]> git.sur5r.net Git - freertos/commitdiff
Update to V4.3.0 as described in http://www.FreeRTOS.org/History.txt
authorrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Tue, 5 Jun 2007 09:53:14 +0000 (09:53 +0000)
committerrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Tue, 5 Jun 2007 09:53:14 +0000 (09:53 +0000)
git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@86 1d2547de-c912-0410-9cb9-b8ca96c0e9e2

352 files changed:
Demo/MCF5235_GCC/demo.c
Demo/MCF5235_GCC/include/arch/mcf523x.h
Demo/MCF5235_GCC/include/arch/mcf523x/mcf523x_can.h
Demo/MCF5235_GCC/include/arch/mcf523x/mcf523x_ccm.h
Demo/MCF5235_GCC/include/arch/mcf523x/mcf523x_cs.h
Demo/MCF5235_GCC/include/arch/mcf523x/mcf523x_eport.h
Demo/MCF5235_GCC/include/arch/mcf523x/mcf523x_etpu.h
Demo/MCF5235_GCC/include/arch/mcf523x/mcf523x_fec.h
Demo/MCF5235_GCC/include/arch/mcf523x/mcf523x_fmpll.h
Demo/MCF5235_GCC/include/arch/mcf523x/mcf523x_gpio.h
Demo/MCF5235_GCC/include/arch/mcf523x/mcf523x_i2c.h
Demo/MCF5235_GCC/include/arch/mcf523x/mcf523x_intc0.h
Demo/MCF5235_GCC/include/arch/mcf523x/mcf523x_intc1.h
Demo/MCF5235_GCC/include/arch/mcf523x/mcf523x_mdha.h
Demo/MCF5235_GCC/include/arch/mcf523x/mcf523x_pit.h
Demo/MCF5235_GCC/include/arch/mcf523x/mcf523x_qspi.h
Demo/MCF5235_GCC/include/arch/mcf523x/mcf523x_rcm.h
Demo/MCF5235_GCC/include/arch/mcf523x/mcf523x_rng.h
Demo/MCF5235_GCC/include/arch/mcf523x/mcf523x_scm.h
Demo/MCF5235_GCC/include/arch/mcf523x/mcf523x_sdramc.h
Demo/MCF5235_GCC/include/arch/mcf523x/mcf523x_skha.h
Demo/MCF5235_GCC/include/arch/mcf523x/mcf523x_sram.h
Demo/MCF5235_GCC/include/arch/mcf523x/mcf523x_timer.h
Demo/MCF5235_GCC/include/arch/mcf523x/mcf523x_uart.h
Demo/MCF5235_GCC/include/arch/mcf523x/mcf523x_wtm.h
Demo/MCF5235_GCC/include/arch/mcf5xxx.h
Demo/MCF5235_GCC/system/init.c
Demo/MCF5235_GCC/system/newlib.c
Demo/MCF5235_GCC/system/serial.c
Demo/MicroBlaze/FreeRTOSConfig.h
Demo/MicroBlaze/ParTest/ParTest.c
Demo/MicroBlaze/main.c
Demo/MicroBlaze/serial/serial.c
Demo/PC/FRConfig.h
Demo/PC/FileIO/fileIO.c
Demo/PC/FreeRTOSConfig.h
Demo/PC/ParTest/ParTest.c
Demo/PC/main.c
Demo/PC/serial/serial.c
Demo/PIC18_MPLAB/FreeRTOSConfig.h
Demo/PIC18_MPLAB/ParTest/ParTest.c
Demo/PIC18_MPLAB/main1.c
Demo/PIC18_MPLAB/main2.c
Demo/PIC18_MPLAB/main3.c
Demo/PIC18_MPLAB/serial/serial.c
Demo/PIC18_WizC/Demo1/FreeRTOSConfig.h
Demo/PIC18_WizC/Demo1/WIZCmake.h
Demo/PIC18_WizC/Demo1/fuses.c
Demo/PIC18_WizC/Demo1/interrupt.c
Demo/PIC18_WizC/Demo1/main.c
Demo/PIC18_WizC/Demo2/FreeRTOSConfig.h
Demo/PIC18_WizC/Demo2/WIZCmake.h
Demo/PIC18_WizC/Demo2/fuses.c
Demo/PIC18_WizC/Demo2/interrupt.c
Demo/PIC18_WizC/Demo2/main.c
Demo/PIC18_WizC/Demo3/FreeRTOSConfig.h
Demo/PIC18_WizC/Demo3/WIZCmake.h
Demo/PIC18_WizC/Demo3/fuses.c
Demo/PIC18_WizC/Demo3/interrupt.c
Demo/PIC18_WizC/Demo3/main.c
Demo/PIC18_WizC/Demo4/FreeRTOSConfig.h
Demo/PIC18_WizC/Demo4/WIZCmake.h
Demo/PIC18_WizC/Demo4/fuses.c
Demo/PIC18_WizC/Demo4/interrupt.c
Demo/PIC18_WizC/Demo4/main.c
Demo/PIC18_WizC/Demo5/FreeRTOSConfig.h
Demo/PIC18_WizC/Demo5/WIZCmake.h
Demo/PIC18_WizC/Demo5/fuses.c
Demo/PIC18_WizC/Demo5/interrupt.c
Demo/PIC18_WizC/Demo5/main.c
Demo/PIC18_WizC/Demo6/FreeRTOSConfig.h
Demo/PIC18_WizC/Demo6/WIZCmake.h
Demo/PIC18_WizC/Demo6/fuses.c
Demo/PIC18_WizC/Demo6/interrupt.c
Demo/PIC18_WizC/Demo6/main.c
Demo/PIC18_WizC/Demo7/FreeRTOSConfig.h
Demo/PIC18_WizC/Demo7/WIZCmake.h
Demo/PIC18_WizC/Demo7/fuses.c
Demo/PIC18_WizC/Demo7/interrupt.c
Demo/PIC18_WizC/Demo7/main.c
Demo/PIC18_WizC/ParTest/ParTest.c
Demo/PIC18_WizC/serial/isrSerialRx.c
Demo/PIC18_WizC/serial/isrSerialTx.c
Demo/PIC18_WizC/serial/serial.c
Demo/PIC24_MPLAB/FreeRTOSConfig.h
Demo/PIC24_MPLAB/ParTest/ParTest.c
Demo/PIC24_MPLAB/RTOSDemo.mcw
Demo/PIC24_MPLAB/RTOSDemo_PIC24.mcp
Demo/PIC24_MPLAB/lcd.c [new file with mode: 0644]
Demo/PIC24_MPLAB/lcd.h [new file with mode: 0644]
Demo/PIC24_MPLAB/main.c
Demo/PIC24_MPLAB/serial/serial.c
Demo/PIC24_MPLAB/timertest.c [new file with mode: 0644]
Demo/PIC24_MPLAB/timertest.h [new file with mode: 0644]
Demo/WizNET_DEMO_GCC_ARM7/FreeRTOSConfig.h
Demo/WizNET_DEMO_GCC_ARM7/HTTP_Serv.c
Demo/WizNET_DEMO_GCC_ARM7/HTTP_Serv.h
Demo/WizNET_DEMO_GCC_ARM7/Makefile
Demo/WizNET_DEMO_GCC_ARM7/TCP.c
Demo/WizNET_DEMO_GCC_ARM7/TCP.h
Demo/WizNET_DEMO_GCC_ARM7/TCPISR.c
Demo/WizNET_DEMO_GCC_ARM7/html_pages.h
Demo/WizNET_DEMO_GCC_ARM7/i2c.c
Demo/WizNET_DEMO_GCC_ARM7/i2c.h
Demo/WizNET_DEMO_GCC_ARM7/i2cISR.c
Demo/WizNET_DEMO_GCC_ARM7/main.c
Demo/WizNET_DEMO_TERN_186/FreeRTOSConfig.h
Demo/WizNET_DEMO_TERN_186/HTTPTask.c
Demo/WizNET_DEMO_TERN_186/HTTPTask.h
Demo/WizNET_DEMO_TERN_186/main.c
Demo/WizNET_DEMO_TERN_186/serial/serial.c
Demo/lwIP_Demo_Rowley_ARM7/BasicWEB.c
Demo/lwIP_Demo_Rowley_ARM7/BasicWEB.h
Demo/lwIP_Demo_Rowley_ARM7/EMAC/SAM7_EMAC.c
Demo/lwIP_Demo_Rowley_ARM7/EMAC/SAM7_EMAC.h
Demo/lwIP_Demo_Rowley_ARM7/EMAC/SAM7_EMAC_ISR.c
Demo/lwIP_Demo_Rowley_ARM7/FreeRTOSConfig.h
Demo/lwIP_Demo_Rowley_ARM7/ParTest/ParTest.c
Demo/lwIP_Demo_Rowley_ARM7/USB/USB-CDC.c
Demo/lwIP_Demo_Rowley_ARM7/USB/USB-CDC.h
Demo/lwIP_Demo_Rowley_ARM7/USB/USBIsr.c
Demo/lwIP_Demo_Rowley_ARM7/USB/descriptors.h
Demo/lwIP_Demo_Rowley_ARM7/USB/usb.h
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/api/api_lib.c
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/api/err.c
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/api/sockets.c
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/api/tcpip.c
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/core/dhcp.c
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/core/inet.c
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/core/inet6.c
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/core/ipv4/ip.c
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/core/ipv4/ip_addr.c
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/core/ipv6/icmp6.c
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/core/ipv6/ip6.c
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/core/ipv6/ip6_addr.c
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/core/mem.c
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/core/memp.c
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/core/netif.c
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/core/stats.c
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/core/sys.c
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/core/tcp_in.c
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/core/udp.c
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/include/ipv4/lwip/icmp.h
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/include/ipv4/lwip/inet.h
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/include/ipv4/lwip/ip.h
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/include/ipv4/lwip/ip_addr.h
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/include/ipv4/lwip/ip_frag.h
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/include/ipv6/lwip/icmp.h
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/include/ipv6/lwip/inet.h
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/include/ipv6/lwip/ip.h
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/include/ipv6/lwip/ip_addr.h
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/include/lwip/api.h
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/include/lwip/api_msg.h
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/include/lwip/arch.h
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/include/lwip/debug.h
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/include/lwip/def.h
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/include/lwip/dhcp.h
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/include/lwip/err.h
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/include/lwip/mem.h
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/include/lwip/memp.h
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/include/lwip/netif.h
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/include/lwip/opt.h
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/include/lwip/pbuf.h
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/include/lwip/raw.h
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/include/lwip/sio.h
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/include/lwip/snmp.h
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/include/lwip/sockets.h
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/include/lwip/stats.h
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/include/lwip/sys.h
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/include/lwip/tcp.h
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/include/lwip/tcpip.h
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/include/lwip/udp.h
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/include/netif/etharp.h
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/include/netif/loopif.h
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/include/netif/slipif.h
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/netif/loopif.c
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/netif/ppp/auth.c
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/netif/ppp/auth.h
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/netif/ppp/chap.c
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/netif/ppp/chap.h
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/netif/ppp/chpms.c
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/netif/ppp/chpms.h
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/netif/ppp/fsm.c
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/netif/ppp/fsm.h
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/netif/ppp/ipcp.c
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/netif/ppp/ipcp.h
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/netif/ppp/lcp.c
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/netif/ppp/lcp.h
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/netif/ppp/magic.c
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/netif/ppp/magic.h
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/netif/ppp/md5.c
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/netif/ppp/md5.h
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/netif/ppp/pap.c
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/netif/ppp/pap.h
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/netif/ppp/ppp.c
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/netif/ppp/ppp.h
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/netif/ppp/pppdebug.h
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/netif/ppp/randm.c
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/netif/ppp/randm.h
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/netif/ppp/vj.c
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/netif/ppp/vj.h
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/netif/ppp/vjbsdhdr.h
Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/netif/slipif.c
Demo/lwIP_Demo_Rowley_ARM7/main.c
Demo/lwIP_Demo_Rowley_ARM7/makefile
Demo/lwIP_MCF5235_GCC/demo.c
Demo/lwIP_MCF5235_GCC/include/arch/mcf523x.h
Demo/lwIP_MCF5235_GCC/include/arch/mcf523x/mcf523x_can.h
Demo/lwIP_MCF5235_GCC/include/arch/mcf523x/mcf523x_ccm.h
Demo/lwIP_MCF5235_GCC/include/arch/mcf523x/mcf523x_cs.h
Demo/lwIP_MCF5235_GCC/include/arch/mcf523x/mcf523x_eport.h
Demo/lwIP_MCF5235_GCC/include/arch/mcf523x/mcf523x_etpu.h
Demo/lwIP_MCF5235_GCC/include/arch/mcf523x/mcf523x_fec.h
Demo/lwIP_MCF5235_GCC/include/arch/mcf523x/mcf523x_fmpll.h
Demo/lwIP_MCF5235_GCC/include/arch/mcf523x/mcf523x_gpio.h
Demo/lwIP_MCF5235_GCC/include/arch/mcf523x/mcf523x_i2c.h
Demo/lwIP_MCF5235_GCC/include/arch/mcf523x/mcf523x_intc0.h
Demo/lwIP_MCF5235_GCC/include/arch/mcf523x/mcf523x_intc1.h
Demo/lwIP_MCF5235_GCC/include/arch/mcf523x/mcf523x_mdha.h
Demo/lwIP_MCF5235_GCC/include/arch/mcf523x/mcf523x_pit.h
Demo/lwIP_MCF5235_GCC/include/arch/mcf523x/mcf523x_qspi.h
Demo/lwIP_MCF5235_GCC/include/arch/mcf523x/mcf523x_rcm.h
Demo/lwIP_MCF5235_GCC/include/arch/mcf523x/mcf523x_rng.h
Demo/lwIP_MCF5235_GCC/include/arch/mcf523x/mcf523x_scm.h
Demo/lwIP_MCF5235_GCC/include/arch/mcf523x/mcf523x_sdramc.h
Demo/lwIP_MCF5235_GCC/include/arch/mcf523x/mcf523x_skha.h
Demo/lwIP_MCF5235_GCC/include/arch/mcf523x/mcf523x_sram.h
Demo/lwIP_MCF5235_GCC/include/arch/mcf523x/mcf523x_timer.h
Demo/lwIP_MCF5235_GCC/include/arch/mcf523x/mcf523x_uart.h
Demo/lwIP_MCF5235_GCC/include/arch/mcf523x/mcf523x_wtm.h
Demo/lwIP_MCF5235_GCC/include/arch/mcf5xxx.h
Demo/lwIP_MCF5235_GCC/lwip/contrib/port/FreeRTOS/MCF5235/arch/cc.h
Demo/lwIP_MCF5235_GCC/lwip/contrib/port/FreeRTOS/MCF5235/arch/cpu.h
Demo/lwIP_MCF5235_GCC/lwip/contrib/port/FreeRTOS/MCF5235/arch/perf.h
Demo/lwIP_MCF5235_GCC/lwip/contrib/port/FreeRTOS/MCF5235/arch/sys_arch.h
Demo/lwIP_MCF5235_GCC/lwip/contrib/port/FreeRTOS/MCF5235/netif/fec.c
Demo/lwIP_MCF5235_GCC/lwip/contrib/port/FreeRTOS/MCF5235/netif/fec.h
Demo/lwIP_MCF5235_GCC/lwip/contrib/port/FreeRTOS/MCF5235/netif/nbuf.c
Demo/lwIP_MCF5235_GCC/lwip/contrib/port/FreeRTOS/MCF5235/netif/nbuf.h
Demo/lwIP_MCF5235_GCC/lwip/contrib/port/FreeRTOS/MCF5235/sys_arch.c
Demo/lwIP_MCF5235_GCC/lwip/src/api/api_lib.c
Demo/lwIP_MCF5235_GCC/lwip/src/api/api_msg.c
Demo/lwIP_MCF5235_GCC/lwip/src/api/err.c
Demo/lwIP_MCF5235_GCC/lwip/src/api/sockets.c
Demo/lwIP_MCF5235_GCC/lwip/src/api/tcpip.c
Demo/lwIP_MCF5235_GCC/lwip/src/core/dhcp.c
Demo/lwIP_MCF5235_GCC/lwip/src/core/inet.c
Demo/lwIP_MCF5235_GCC/lwip/src/core/inet6.c
Demo/lwIP_MCF5235_GCC/lwip/src/core/ipv4/icmp.c
Demo/lwIP_MCF5235_GCC/lwip/src/core/ipv4/ip.c
Demo/lwIP_MCF5235_GCC/lwip/src/core/ipv4/ip_addr.c
Demo/lwIP_MCF5235_GCC/lwip/src/core/ipv4/ip_frag.c
Demo/lwIP_MCF5235_GCC/lwip/src/core/ipv6/icmp6.c
Demo/lwIP_MCF5235_GCC/lwip/src/core/ipv6/ip6.c
Demo/lwIP_MCF5235_GCC/lwip/src/core/ipv6/ip6_addr.c
Demo/lwIP_MCF5235_GCC/lwip/src/core/mem.c
Demo/lwIP_MCF5235_GCC/lwip/src/core/memp.c
Demo/lwIP_MCF5235_GCC/lwip/src/core/netif.c
Demo/lwIP_MCF5235_GCC/lwip/src/core/pbuf.c
Demo/lwIP_MCF5235_GCC/lwip/src/core/raw.c
Demo/lwIP_MCF5235_GCC/lwip/src/core/stats.c
Demo/lwIP_MCF5235_GCC/lwip/src/core/sys.c
Demo/lwIP_MCF5235_GCC/lwip/src/core/tcp.c
Demo/lwIP_MCF5235_GCC/lwip/src/core/tcp_in.c
Demo/lwIP_MCF5235_GCC/lwip/src/core/tcp_out.c
Demo/lwIP_MCF5235_GCC/lwip/src/core/udp.c
Demo/lwIP_MCF5235_GCC/lwip/src/include/ipv4/lwip/icmp.h
Demo/lwIP_MCF5235_GCC/lwip/src/include/ipv4/lwip/inet.h
Demo/lwIP_MCF5235_GCC/lwip/src/include/ipv4/lwip/ip.h
Demo/lwIP_MCF5235_GCC/lwip/src/include/ipv4/lwip/ip_addr.h
Demo/lwIP_MCF5235_GCC/lwip/src/include/ipv4/lwip/ip_frag.h
Demo/lwIP_MCF5235_GCC/lwip/src/include/ipv6/lwip/icmp.h
Demo/lwIP_MCF5235_GCC/lwip/src/include/ipv6/lwip/inet.h
Demo/lwIP_MCF5235_GCC/lwip/src/include/ipv6/lwip/ip.h
Demo/lwIP_MCF5235_GCC/lwip/src/include/ipv6/lwip/ip_addr.h
Demo/lwIP_MCF5235_GCC/lwip/src/include/lwip/api.h
Demo/lwIP_MCF5235_GCC/lwip/src/include/lwip/api_msg.h
Demo/lwIP_MCF5235_GCC/lwip/src/include/lwip/arch.h
Demo/lwIP_MCF5235_GCC/lwip/src/include/lwip/debug.h
Demo/lwIP_MCF5235_GCC/lwip/src/include/lwip/def.h
Demo/lwIP_MCF5235_GCC/lwip/src/include/lwip/dhcp.h
Demo/lwIP_MCF5235_GCC/lwip/src/include/lwip/err.h
Demo/lwIP_MCF5235_GCC/lwip/src/include/lwip/mem.h
Demo/lwIP_MCF5235_GCC/lwip/src/include/lwip/memp.h
Demo/lwIP_MCF5235_GCC/lwip/src/include/lwip/netif.h
Demo/lwIP_MCF5235_GCC/lwip/src/include/lwip/opt.h
Demo/lwIP_MCF5235_GCC/lwip/src/include/lwip/pbuf.h
Demo/lwIP_MCF5235_GCC/lwip/src/include/lwip/raw.h
Demo/lwIP_MCF5235_GCC/lwip/src/include/lwip/sio.h
Demo/lwIP_MCF5235_GCC/lwip/src/include/lwip/snmp.h
Demo/lwIP_MCF5235_GCC/lwip/src/include/lwip/sockets.h
Demo/lwIP_MCF5235_GCC/lwip/src/include/lwip/stats.h
Demo/lwIP_MCF5235_GCC/lwip/src/include/lwip/sys.h
Demo/lwIP_MCF5235_GCC/lwip/src/include/lwip/tcp.h
Demo/lwIP_MCF5235_GCC/lwip/src/include/lwip/tcpip.h
Demo/lwIP_MCF5235_GCC/lwip/src/include/lwip/udp.h
Demo/lwIP_MCF5235_GCC/lwip/src/include/netif/etharp.h
Demo/lwIP_MCF5235_GCC/lwip/src/include/netif/loopif.h
Demo/lwIP_MCF5235_GCC/lwip/src/include/netif/slipif.h
Demo/lwIP_MCF5235_GCC/lwip/src/netif/etharp.c
Demo/lwIP_MCF5235_GCC/lwip/src/netif/ethernetif.c
Demo/lwIP_MCF5235_GCC/lwip/src/netif/loopif.c
Demo/lwIP_MCF5235_GCC/lwip/src/netif/ppp/auth.c
Demo/lwIP_MCF5235_GCC/lwip/src/netif/ppp/auth.h
Demo/lwIP_MCF5235_GCC/lwip/src/netif/ppp/chap.c
Demo/lwIP_MCF5235_GCC/lwip/src/netif/ppp/chap.h
Demo/lwIP_MCF5235_GCC/lwip/src/netif/ppp/chpms.c
Demo/lwIP_MCF5235_GCC/lwip/src/netif/ppp/chpms.h
Demo/lwIP_MCF5235_GCC/lwip/src/netif/ppp/fsm.c
Demo/lwIP_MCF5235_GCC/lwip/src/netif/ppp/fsm.h
Demo/lwIP_MCF5235_GCC/lwip/src/netif/ppp/ipcp.c
Demo/lwIP_MCF5235_GCC/lwip/src/netif/ppp/ipcp.h
Demo/lwIP_MCF5235_GCC/lwip/src/netif/ppp/lcp.c
Demo/lwIP_MCF5235_GCC/lwip/src/netif/ppp/lcp.h
Demo/lwIP_MCF5235_GCC/lwip/src/netif/ppp/magic.c
Demo/lwIP_MCF5235_GCC/lwip/src/netif/ppp/magic.h
Demo/lwIP_MCF5235_GCC/lwip/src/netif/ppp/md5.c
Demo/lwIP_MCF5235_GCC/lwip/src/netif/ppp/md5.h
Demo/lwIP_MCF5235_GCC/lwip/src/netif/ppp/pap.c
Demo/lwIP_MCF5235_GCC/lwip/src/netif/ppp/pap.h
Demo/lwIP_MCF5235_GCC/lwip/src/netif/ppp/ppp.c
Demo/lwIP_MCF5235_GCC/lwip/src/netif/ppp/ppp.h
Demo/lwIP_MCF5235_GCC/lwip/src/netif/ppp/pppdebug.h
Demo/lwIP_MCF5235_GCC/lwip/src/netif/ppp/randm.c
Demo/lwIP_MCF5235_GCC/lwip/src/netif/ppp/randm.h
Demo/lwIP_MCF5235_GCC/lwip/src/netif/ppp/vj.c
Demo/lwIP_MCF5235_GCC/lwip/src/netif/ppp/vj.h
Demo/lwIP_MCF5235_GCC/lwip/src/netif/ppp/vjbsdhdr.h
Demo/lwIP_MCF5235_GCC/lwip/src/netif/slipif.c
Demo/lwIP_MCF5235_GCC/system/init.c
Demo/lwIP_MCF5235_GCC/system/newlib.c
Demo/lwIP_MCF5235_GCC/system/serial.c
Demo/lwIP_MCF5235_GCC/web.c
Demo/lwIP_MCF5235_GCC/web.h
Demo/msp430_CrossWorks/FreeRTOSConfig.h
Demo/msp430_CrossWorks/ParTest/ParTest.c
Demo/msp430_CrossWorks/main.c
Demo/msp430_CrossWorks/serial/serial.c
Demo/msp430_GCC/FreeRTOSConfig.h
Demo/msp430_GCC/ParTest/ParTest.c
Demo/msp430_GCC/main.c
Demo/msp430_GCC/makefile
Demo/msp430_GCC/serial/serial.c
Demo/uIP_Demo_IAR_ARM7/EMAC/EMAClISR.s79
Demo/uIP_Demo_IAR_ARM7/EMAC/SAM7_EMAC.c
Demo/uIP_Demo_IAR_ARM7/FreeRTOSConfig.h
Demo/uIP_Demo_IAR_ARM7/ParTest/ParTest.c
Demo/uIP_Demo_IAR_ARM7/main.c
Demo/uIP_Demo_IAR_ARM7/uip/fsdata.c
Demo/uIP_Demo_IAR_ARM7/uip/uipopt.h
Demo/uIP_Demo_Rowley_ARM7/FreeRTOSConfig.h
Demo/uIP_Demo_Rowley_ARM7/main.c

index 147d18194c5c046c391f5a850aad65d291a91b11..6cc6d53a8bf036de4fed6661d4e1e61802490205 100644 (file)
-/*
-    FreeRTOS V4.1.0 - Copyright (C) 2003-2006 Richard Barry.
-    MCF5235 Port - Copyright (C) 2006 Christian Walter.
-
-    This file is part of the FreeRTOS distribution.
-
-    FreeRTOS is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    FreeRTOS is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with FreeRTOS; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-    A special exception to the GPL can be applied should you wish to distribute
-    a combined work that includes FreeRTOS, without being obliged to provide
-    the source code for any proprietary components.  See the licensing section
-    of http://www.FreeRTOS.org for full details of how and when the exception
-    can be applied.
-
-    ***************************************************************************
-    See http://www.FreeRTOS.org for documentation, latest information, license
-    and contact details.  Please ensure to read the configuration and relevant
+/*\r
+    FreeRTOS V4.1.0 - Copyright (C) 2003-2006 Richard Barry.\r
+    MCF5235 Port - Copyright (C) 2006 Christian Walter.\r
+\r
+    This file is part of the FreeRTOS distribution.\r
+\r
+    FreeRTOS is free software; you can redistribute it and/or modify\r
+    it under the terms of the GNU General Public License as published by\r
+    the Free Software Foundation; either version 2 of the License, or\r
+    (at your option) any later version.\r
+\r
+    FreeRTOS is distributed in the hope that it will be useful,\r
+    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+    GNU General Public License for more details.\r
+\r
+    You should have received a copy of the GNU General Public License\r
+    along with FreeRTOS; if not, write to the Free Software\r
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+\r
+    A special exception to the GPL can be applied should you wish to distribute\r
+    a combined work that includes FreeRTOS, without being obliged to provide\r
+    the source code for any proprietary components.  See the licensing section\r
+    of http://www.FreeRTOS.org for full details of how and when the exception\r
+    can be applied.\r
+\r
+    ***************************************************************************\r
+    See http://www.FreeRTOS.org for documentation, latest information, license\r
+    and contact details.  Please ensure to read the configuration and relevant\r
     port sections of the online documentation.\r
 \r
        Also see http://www.SafeRTOS.com for an IEC 61508 compliant version along\r
-       with commercial development and support options.
-    ***************************************************************************
-*/
-
-/* ------------------------ System includes ------------------------------- */
-#include <stdlib.h>
-#include <string.h>
-
-/* ------------------------ FreeRTOS includes ----------------------------- */
-#include "FreeRTOS.h"
-#include "task.h"
-
-/* ------------------------ Demo application includes --------------------- */
-#include "partest.h"
-#include "flash.h"
-#include "integer.h"
-#include "PollQ.h"
-#include "comtest2.h"
-#include "semtest.h"
-#include "flop.h"
-#include "dynamic.h"
-#include "BlockQ.h"
-#include "serial.h"
-
-/* ------------------------ Defines --------------------------------------- */
-/* Constants for the ComTest tasks. */
-#define mainCOM_TEST_BAUD_RATE  ( ( unsigned portLONG ) 38400 )
-#define mainCOM_TEST_LED        ( -1 )
-
-/* Priorities for the demo application tasks. */
-#define mainLED_TASK_PRIORITY       ( tskIDLE_PRIORITY + 3 )
-#define mainCOM_TEST_PRIORITY       ( tskIDLE_PRIORITY + 2 )
-#define mainQUEUE_POLL_PRIORITY     ( tskIDLE_PRIORITY + 2 )
-#define mainCHECK_TASK_PRIORITY     ( tskIDLE_PRIORITY + 4 )
-#define mainSEM_TEST_PRIORITY       ( tskIDLE_PRIORITY + 1 )
-#define mainBLOCK_Q_PRIORITY        ( tskIDLE_PRIORITY + 2 )
-
-/* Interval in which tasks are checked. */
-#define mainCHECK_PERIOD            ( ( portTickType ) 2000 / portTICK_RATE_MS  )
-
-/* Constants used by the vMemCheckTask() task. */
-#define mainCOUNT_INITIAL_VALUE     ( ( unsigned portLONG ) 0 )
-#define mainNO_TASK                 ( 0 )
-
-/* The size of the memory blocks allocated by the vMemCheckTask() task. */
-#define mainMEM_CHECK_SIZE_1        ( ( size_t ) 51 )
-#define mainMEM_CHECK_SIZE_2        ( ( size_t ) 52 )
-#define mainMEM_CHECK_SIZE_3        ( ( size_t ) 151 )
-
-/* ------------------------ Static variables ------------------------------ */
-xComPortHandle  xSTDComPort = NULL;
-
-/* ------------------------ Static functions ------------------------------ */
-static          portTASK_FUNCTION( vErrorChecks, pvParameters );
-static portLONG prvCheckOtherTasksAreStillRunning( unsigned portLONG
-                                                   ulMemCheckTaskCount );
-static          portTASK_FUNCTION( vMemCheckTask, pvParameters );
-
-/* ------------------------ Implementation -------------------------------- */
-int
-main( int argc, char *argv[] )
-{
-    asm volatile    ( "move.w  #0x2000, %sr\n\t" );
-
-    xSTDComPort = xSerialPortInitMinimal( 38400, 8 );
-
-    /* Start the demo/test application tasks. */
-    vStartIntegerMathTasks( tskIDLE_PRIORITY );
-    vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
-    vStartMathTasks( tskIDLE_PRIORITY );
-    vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
-    vStartDynamicPriorityTasks(  );
-    vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
-
-    /* Start the check task - which is defined in this file. */
-    xTaskCreate( vErrorChecks, ( signed portCHAR * )"Check", 512, NULL,
-                 mainCHECK_TASK_PRIORITY, NULL );
-
-    /* Now all the tasks have been started - start the scheduler. */
-    vTaskStartScheduler(  );
-
-    /* Should never get here! */
-    return 0;
-}
-
-
-
-static
-portTASK_FUNCTION( vErrorChecks, pvParameters )
-{
-    unsigned portLONG ulMemCheckTaskRunningCount;
-    xTaskHandle     xCreatedTask;
-
-    /* The parameters are not used in this function. */
-    ( void )pvParameters;
-
-    xSerialPortInitMinimal( mainCOM_TEST_BAUD_RATE, 8 );
-
-    for( ;; )
-    {
-        ulMemCheckTaskRunningCount = mainCOUNT_INITIAL_VALUE;
-        xCreatedTask = mainNO_TASK;
-
-        if( xTaskCreate
-            ( vMemCheckTask, ( signed portCHAR * )"MEM_CHECK",
-              configMINIMAL_STACK_SIZE, ( void * )&ulMemCheckTaskRunningCount,
-              tskIDLE_PRIORITY, &xCreatedTask ) != pdPASS )
-        {
-            xSerialPutChar( xSTDComPort, 'E', portMAX_DELAY );
-        }
-
-        /* Delay until it is time to execute again. */
-        vTaskDelay( mainCHECK_PERIOD );
-
-        /* Delete the dynamically created task. */
-        if( xCreatedTask != mainNO_TASK )
-        {
-            vTaskDelete( xCreatedTask );
-        }
-
-        if( prvCheckOtherTasksAreStillRunning( ulMemCheckTaskRunningCount ) !=
-            pdPASS )
-        {
-            xSerialPutChar( xSTDComPort, 'E', portMAX_DELAY );
-        }
-        else
-        {
-            xSerialPutChar( xSTDComPort, '.', portMAX_DELAY );
-        }
-    }
-}
-
-static portLONG
-prvCheckOtherTasksAreStillRunning( unsigned portLONG ulMemCheckTaskCount )
-{
-    portLONG        lReturn = ( portLONG ) pdPASS;
-
-    /* Check all the demo tasks (other than the flash tasks) to ensure
-     * that they are all still running, and that none of them have detected
-     * an error.
-     */
-
-    if( xAreIntegerMathsTaskStillRunning(  ) != pdTRUE )
-    {
-        lReturn = ( portLONG ) pdFAIL;
-    }
-
-    if( xArePollingQueuesStillRunning(  ) != pdTRUE )
-    {
-        lReturn = ( portLONG ) pdFAIL;
-    }
-
-    if( xAreMathsTaskStillRunning(  ) != pdTRUE )
-    {
-        lReturn = ( portLONG ) pdFAIL;
-    }
-
-    if( xAreSemaphoreTasksStillRunning(  ) != pdTRUE )
-    {
-        lReturn = ( portLONG ) pdFAIL;
-    }
-
-    if( xAreDynamicPriorityTasksStillRunning(  ) != pdTRUE )
-    {
-        lReturn = ( portLONG ) pdFAIL;
-    }
-
-    if( xAreBlockingQueuesStillRunning(  ) != pdTRUE )
-    {
-        lReturn = ( portLONG ) pdFAIL;
-    }
-    if( ulMemCheckTaskCount == mainCOUNT_INITIAL_VALUE )
-    {
-        // The vMemCheckTask did not increment the counter - it must
-        // have failed.
-        lReturn = ( portLONG ) pdFAIL;
-    }
-    return lReturn;
-}
-
-static void
-vMemCheckTask( void *pvParameters )
-{
-    unsigned portLONG *pulMemCheckTaskRunningCounter;
-    void           *pvMem1, *pvMem2, *pvMem3;
-    static portLONG lErrorOccurred = pdFALSE;
-
-    /* This task is dynamically created then deleted during each cycle of the
-       vErrorChecks task to check the operation of the memory allocator.  Each time
-       the task is created memory is allocated for the stack and TCB.  Each time
-       the task is deleted this memory is returned to the heap.  This task itself
-       exercises the allocator by allocating and freeing blocks.
-
-       The task executes at the idle priority so does not require a delay.
-
-       pulMemCheckTaskRunningCounter is incremented each cycle to indicate to the
-       vErrorChecks() task that this task is still executing without error. */
-
-    pulMemCheckTaskRunningCounter = ( unsigned portLONG * )pvParameters;
-
-    for( ;; )
-    {
-        if( lErrorOccurred == pdFALSE )
-        {
-            /* We have never seen an error so increment the counter. */
-            ( *pulMemCheckTaskRunningCounter )++;
-        }
-
-        /* Allocate some memory - just to give the allocator some extra
-           exercise.  This has to be in a critical section to ensure the
-           task does not get deleted while it has memory allocated. */
-        vTaskSuspendAll(  );
-        {
-            pvMem1 = pvPortMalloc( mainMEM_CHECK_SIZE_1 );
-            if( pvMem1 == NULL )
-            {
-                lErrorOccurred = pdTRUE;
-            }
-            else
-            {
-                memset( pvMem1, 0xaa, mainMEM_CHECK_SIZE_1 );
-                vPortFree( pvMem1 );
-            }
-        }
-        xTaskResumeAll(  );
-
-        /* Again - with a different size block. */
-        vTaskSuspendAll(  );
-        {
-            pvMem2 = pvPortMalloc( mainMEM_CHECK_SIZE_2 );
-            if( pvMem2 == NULL )
-            {
-                lErrorOccurred = pdTRUE;
-            }
-            else
-            {
-                memset( pvMem2, 0xaa, mainMEM_CHECK_SIZE_2 );
-                vPortFree( pvMem2 );
-            }
-        }
-        xTaskResumeAll(  );
-
-        /* Again - with a different size block. */
-        vTaskSuspendAll(  );
-        {
-            pvMem3 = pvPortMalloc( mainMEM_CHECK_SIZE_3 );
-            if( pvMem3 == NULL )
-            {
-                lErrorOccurred = pdTRUE;
-            }
-            else
-            {
-                memset( pvMem3, 0xaa, mainMEM_CHECK_SIZE_3 );
-                vPortFree( pvMem3 );
-            }
-        }
-        xTaskResumeAll(  );
-    }
-}
-
-void
-vParTestSetLED( unsigned portBASE_TYPE uxLED, signed portBASE_TYPE xValue )
-{
-}
-
-void
-vParTestToggleLED( unsigned portBASE_TYPE uxLED )
-{
-}
+       with commercial development and support options.\r
+    ***************************************************************************\r
+*/\r
+\r
+/* ------------------------ System includes ------------------------------- */\r
+#include <stdlib.h>\r
+#include <string.h>\r
+\r
+/* ------------------------ FreeRTOS includes ----------------------------- */\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+\r
+/* ------------------------ Demo application includes --------------------- */\r
+#include "partest.h"\r
+#include "flash.h"\r
+#include "integer.h"\r
+#include "PollQ.h"\r
+#include "comtest2.h"\r
+#include "semtest.h"\r
+#include "flop.h"\r
+#include "dynamic.h"\r
+#include "BlockQ.h"\r
+#include "serial.h"\r
+\r
+/* ------------------------ Defines --------------------------------------- */\r
+/* Constants for the ComTest tasks. */\r
+#define mainCOM_TEST_BAUD_RATE  ( ( unsigned portLONG ) 38400 )\r
+#define mainCOM_TEST_LED        ( -1 )\r
+\r
+/* Priorities for the demo application tasks. */\r
+#define mainLED_TASK_PRIORITY       ( tskIDLE_PRIORITY + 3 )\r
+#define mainCOM_TEST_PRIORITY       ( tskIDLE_PRIORITY + 2 )\r
+#define mainQUEUE_POLL_PRIORITY     ( tskIDLE_PRIORITY + 2 )\r
+#define mainCHECK_TASK_PRIORITY     ( tskIDLE_PRIORITY + 4 )\r
+#define mainSEM_TEST_PRIORITY       ( tskIDLE_PRIORITY + 1 )\r
+#define mainBLOCK_Q_PRIORITY        ( tskIDLE_PRIORITY + 2 )\r
+\r
+/* Interval in which tasks are checked. */\r
+#define mainCHECK_PERIOD            ( ( portTickType ) 2000 / portTICK_RATE_MS  )\r
+\r
+/* Constants used by the vMemCheckTask() task. */\r
+#define mainCOUNT_INITIAL_VALUE     ( ( unsigned portLONG ) 0 )\r
+#define mainNO_TASK                 ( 0 )\r
+\r
+/* The size of the memory blocks allocated by the vMemCheckTask() task. */\r
+#define mainMEM_CHECK_SIZE_1        ( ( size_t ) 51 )\r
+#define mainMEM_CHECK_SIZE_2        ( ( size_t ) 52 )\r
+#define mainMEM_CHECK_SIZE_3        ( ( size_t ) 151 )\r
+\r
+/* ------------------------ Static variables ------------------------------ */\r
+xComPortHandle  xSTDComPort = NULL;\r
+\r
+/* ------------------------ Static functions ------------------------------ */\r
+static          portTASK_FUNCTION( vErrorChecks, pvParameters );\r
+static portLONG prvCheckOtherTasksAreStillRunning( unsigned portLONG\r
+                                                   ulMemCheckTaskCount );\r
+static          portTASK_FUNCTION( vMemCheckTask, pvParameters );\r
+\r
+/* ------------------------ Implementation -------------------------------- */\r
+int\r
+main( int argc, char *argv[] )\r
+{\r
+    asm volatile    ( "move.w  #0x2000, %sr\n\t" );\r
+\r
+    xSTDComPort = xSerialPortInitMinimal( 38400, 8 );\r
+\r
+    /* Start the demo/test application tasks. */\r
+    vStartIntegerMathTasks( tskIDLE_PRIORITY );\r
+    vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );\r
+    vStartMathTasks( tskIDLE_PRIORITY );\r
+    vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );\r
+    vStartDynamicPriorityTasks(  );\r
+    vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );\r
+\r
+    /* Start the check task - which is defined in this file. */\r
+    xTaskCreate( vErrorChecks, ( signed portCHAR * )"Check", 512, NULL,\r
+                 mainCHECK_TASK_PRIORITY, NULL );\r
+\r
+    /* Now all the tasks have been started - start the scheduler. */\r
+    vTaskStartScheduler(  );\r
+\r
+    /* Should never get here! */\r
+    return 0;\r
+}\r
+\r
+\r
+\r
+static\r
+portTASK_FUNCTION( vErrorChecks, pvParameters )\r
+{\r
+    unsigned portLONG ulMemCheckTaskRunningCount;\r
+    xTaskHandle     xCreatedTask;\r
+\r
+    /* The parameters are not used in this function. */\r
+    ( void )pvParameters;\r
+\r
+    xSerialPortInitMinimal( mainCOM_TEST_BAUD_RATE, 8 );\r
+\r
+    for( ;; )\r
+    {\r
+        ulMemCheckTaskRunningCount = mainCOUNT_INITIAL_VALUE;\r
+        xCreatedTask = mainNO_TASK;\r
+\r
+        if( xTaskCreate\r
+            ( vMemCheckTask, ( signed portCHAR * )"MEM_CHECK",\r
+              configMINIMAL_STACK_SIZE, ( void * )&ulMemCheckTaskRunningCount,\r
+              tskIDLE_PRIORITY, &xCreatedTask ) != pdPASS )\r
+        {\r
+            xSerialPutChar( xSTDComPort, 'E', portMAX_DELAY );\r
+        }\r
+\r
+        /* Delay until it is time to execute again. */\r
+        vTaskDelay( mainCHECK_PERIOD );\r
+\r
+        /* Delete the dynamically created task. */\r
+        if( xCreatedTask != mainNO_TASK )\r
+        {\r
+            vTaskDelete( xCreatedTask );\r
+        }\r
+\r
+        if( prvCheckOtherTasksAreStillRunning( ulMemCheckTaskRunningCount ) !=\r
+            pdPASS )\r
+        {\r
+            xSerialPutChar( xSTDComPort, 'E', portMAX_DELAY );\r
+        }\r
+        else\r
+        {\r
+            xSerialPutChar( xSTDComPort, '.', portMAX_DELAY );\r
+        }\r
+    }\r
+}\r
+\r
+static portLONG\r
+prvCheckOtherTasksAreStillRunning( unsigned portLONG ulMemCheckTaskCount )\r
+{\r
+    portLONG        lReturn = ( portLONG ) pdPASS;\r
+\r
+    /* Check all the demo tasks (other than the flash tasks) to ensure\r
+     * that they are all still running, and that none of them have detected\r
+     * an error.\r
+     */\r
+\r
+    if( xAreIntegerMathsTaskStillRunning(  ) != pdTRUE )\r
+    {\r
+        lReturn = ( portLONG ) pdFAIL;\r
+    }\r
+\r
+    if( xArePollingQueuesStillRunning(  ) != pdTRUE )\r
+    {\r
+        lReturn = ( portLONG ) pdFAIL;\r
+    }\r
+\r
+    if( xAreMathsTaskStillRunning(  ) != pdTRUE )\r
+    {\r
+        lReturn = ( portLONG ) pdFAIL;\r
+    }\r
+\r
+    if( xAreSemaphoreTasksStillRunning(  ) != pdTRUE )\r
+    {\r
+        lReturn = ( portLONG ) pdFAIL;\r
+    }\r
+\r
+    if( xAreDynamicPriorityTasksStillRunning(  ) != pdTRUE )\r
+    {\r
+        lReturn = ( portLONG ) pdFAIL;\r
+    }\r
+\r
+    if( xAreBlockingQueuesStillRunning(  ) != pdTRUE )\r
+    {\r
+        lReturn = ( portLONG ) pdFAIL;\r
+    }\r
+    if( ulMemCheckTaskCount == mainCOUNT_INITIAL_VALUE )\r
+    {\r
+        // The vMemCheckTask did not increment the counter - it must\r
+        // have failed.\r
+        lReturn = ( portLONG ) pdFAIL;\r
+    }\r
+    return lReturn;\r
+}\r
+\r
+static void\r
+vMemCheckTask( void *pvParameters )\r
+{\r
+    unsigned portLONG *pulMemCheckTaskRunningCounter;\r
+    void           *pvMem1, *pvMem2, *pvMem3;\r
+    static portLONG lErrorOccurred = pdFALSE;\r
+\r
+    /* This task is dynamically created then deleted during each cycle of the\r
+       vErrorChecks task to check the operation of the memory allocator.  Each time\r
+       the task is created memory is allocated for the stack and TCB.  Each time\r
+       the task is deleted this memory is returned to the heap.  This task itself\r
+       exercises the allocator by allocating and freeing blocks.\r
+\r
+       The task executes at the idle priority so does not require a delay.\r
+\r
+       pulMemCheckTaskRunningCounter is incremented each cycle to indicate to the\r
+       vErrorChecks() task that this task is still executing without error. */\r
+\r
+    pulMemCheckTaskRunningCounter = ( unsigned portLONG * )pvParameters;\r
+\r
+    for( ;; )\r
+    {\r
+        if( lErrorOccurred == pdFALSE )\r
+        {\r
+            /* We have never seen an error so increment the counter. */\r
+            ( *pulMemCheckTaskRunningCounter )++;\r
+        }\r
+\r
+        /* Allocate some memory - just to give the allocator some extra\r
+           exercise.  This has to be in a critical section to ensure the\r
+           task does not get deleted while it has memory allocated. */\r
+        vTaskSuspendAll(  );\r
+        {\r
+            pvMem1 = pvPortMalloc( mainMEM_CHECK_SIZE_1 );\r
+            if( pvMem1 == NULL )\r
+            {\r
+                lErrorOccurred = pdTRUE;\r
+            }\r
+            else\r
+            {\r
+                memset( pvMem1, 0xaa, mainMEM_CHECK_SIZE_1 );\r
+                vPortFree( pvMem1 );\r
+            }\r
+        }\r
+        xTaskResumeAll(  );\r
+\r
+        /* Again - with a different size block. */\r
+        vTaskSuspendAll(  );\r
+        {\r
+            pvMem2 = pvPortMalloc( mainMEM_CHECK_SIZE_2 );\r
+            if( pvMem2 == NULL )\r
+            {\r
+                lErrorOccurred = pdTRUE;\r
+            }\r
+            else\r
+            {\r
+                memset( pvMem2, 0xaa, mainMEM_CHECK_SIZE_2 );\r
+                vPortFree( pvMem2 );\r
+            }\r
+        }\r
+        xTaskResumeAll(  );\r
+\r
+        /* Again - with a different size block. */\r
+        vTaskSuspendAll(  );\r
+        {\r
+            pvMem3 = pvPortMalloc( mainMEM_CHECK_SIZE_3 );\r
+            if( pvMem3 == NULL )\r
+            {\r
+                lErrorOccurred = pdTRUE;\r
+            }\r
+            else\r
+            {\r
+                memset( pvMem3, 0xaa, mainMEM_CHECK_SIZE_3 );\r
+                vPortFree( pvMem3 );\r
+            }\r
+        }\r
+        xTaskResumeAll(  );\r
+    }\r
+}\r
+\r
+void\r
+vParTestSetLED( unsigned portBASE_TYPE uxLED, signed portBASE_TYPE xValue )\r
+{\r
+}\r
+\r
+void\r
+vParTestToggleLED( unsigned portBASE_TYPE uxLED )\r
+{\r
+}\r
index 4b7761fd59c78e3bf3b85fb136304115a9743d2f..ae9dd63f6d2bf01bbf0da2df8cab0adcebe825f0 100644 (file)
@@ -1,46 +1,46 @@
-/*
- * These files are taken from the MCF523X source code example package
- * which is available on the Freescale website. Freescale explicitly 
- * grants the redistribution and modification of these source files.
- * The complete licensing information is available in the file 
- * LICENSE_FREESCALE.TXT.
- *
- * File:       mcf523x.h
- * Purpose:    Register and bit definitions for the MCF523X
- *
- * Notes:      
- *     
- */
-
-#ifndef __MCF523X_H__
-#define __MCF523X_H__
-
-/*********************************************************************/
-
-#include "mcf523x/mcf523x_fec.h"
-#include "mcf523x/mcf523x_rng.h"
-#include "mcf523x/mcf523x_fmpll.h"
-#include "mcf523x/mcf523x_cs.h"
-#include "mcf523x/mcf523x_intc0.h"
-#include "mcf523x/mcf523x_intc1.h"
-#include "mcf523x/mcf523x_sdramc.h"
-#include "mcf523x/mcf523x_sram.h"
-#include "mcf523x/mcf523x_uart.h"
-#include "mcf523x/mcf523x_timer.h"
-#include "mcf523x/mcf523x_qspi.h"
-#include "mcf523x/mcf523x_eport.h"
-#include "mcf523x/mcf523x_i2c.h"
-#include "mcf523x/mcf523x_scm.h"
-#include "mcf523x/mcf523x_pit.h"
-#include "mcf523x/mcf523x_can.h"
-#include "mcf523x/mcf523x_wtm.h"
-#include "mcf523x/mcf523x_gpio.h"
-#include "mcf523x/mcf523x_mdha.h"
-#include "mcf523x/mcf523x_ccm.h"
-#include "mcf523x/mcf523x_rcm.h"
-#include "mcf523x/mcf523x_etpu.h"
-
-
-/********************************************************************/
-
-#endif /* __MCF523X_H__ */
+/*\r
+ * These files are taken from the MCF523X source code example package\r
+ * which is available on the Freescale website. Freescale explicitly \r
+ * grants the redistribution and modification of these source files.\r
+ * The complete licensing information is available in the file \r
+ * LICENSE_FREESCALE.TXT.\r
+ *\r
+ * File:       mcf523x.h\r
+ * Purpose:    Register and bit definitions for the MCF523X\r
+ *\r
+ * Notes:      \r
+ *     \r
+ */\r
+\r
+#ifndef __MCF523X_H__\r
+#define __MCF523X_H__\r
+\r
+/*********************************************************************/\r
+\r
+#include "mcf523x/mcf523x_fec.h"\r
+#include "mcf523x/mcf523x_rng.h"\r
+#include "mcf523x/mcf523x_fmpll.h"\r
+#include "mcf523x/mcf523x_cs.h"\r
+#include "mcf523x/mcf523x_intc0.h"\r
+#include "mcf523x/mcf523x_intc1.h"\r
+#include "mcf523x/mcf523x_sdramc.h"\r
+#include "mcf523x/mcf523x_sram.h"\r
+#include "mcf523x/mcf523x_uart.h"\r
+#include "mcf523x/mcf523x_timer.h"\r
+#include "mcf523x/mcf523x_qspi.h"\r
+#include "mcf523x/mcf523x_eport.h"\r
+#include "mcf523x/mcf523x_i2c.h"\r
+#include "mcf523x/mcf523x_scm.h"\r
+#include "mcf523x/mcf523x_pit.h"\r
+#include "mcf523x/mcf523x_can.h"\r
+#include "mcf523x/mcf523x_wtm.h"\r
+#include "mcf523x/mcf523x_gpio.h"\r
+#include "mcf523x/mcf523x_mdha.h"\r
+#include "mcf523x/mcf523x_ccm.h"\r
+#include "mcf523x/mcf523x_rcm.h"\r
+#include "mcf523x/mcf523x_etpu.h"\r
+\r
+\r
+/********************************************************************/\r
+\r
+#endif /* __MCF523X_H__ */\r
index 7aaa344962c3b0fe81a93f0928878436c75f1758..a193ba6fd0e25f342186824953ebe6abb2d38306 100644 (file)
-/*
- * These files are taken from the MCF523X source code example package
- * which is available on the Freescale website. Freescale explicitly 
- * grants the redistribution and modification of these source files.
- * The complete licensing information is available in the file 
- * LICENSE_FREESCALE.TXT.
- *
- * File:       mcf523x_can.h
- * Purpose:    Register and bit definitions for the MCF523X
- *
- * Notes:      
- *     
- */
-
-#ifndef __MCF523X_CAN_H__
-#define __MCF523X_CAN_H__
-
-/*********************************************************************
-*
-* FlexCAN Module (CAN)
-*
-*********************************************************************/
-
-/* Register read/write macros */
-#define MCF_CAN_CANMCR0        (*(vuint32*)(void*)(&__IPSBAR[0x1C0000]))
-#define MCF_CAN_CANCTRL0       (*(vuint32*)(void*)(&__IPSBAR[0x1C0004]))
-#define MCF_CAN_TIMER0         (*(vuint32*)(void*)(&__IPSBAR[0x1C0008]))
-#define MCF_CAN_RXGMASK0       (*(vuint32*)(void*)(&__IPSBAR[0x1C0010]))
-#define MCF_CAN_RX14MASK0      (*(vuint32*)(void*)(&__IPSBAR[0x1C0014]))
-#define MCF_CAN_RX15MASK0      (*(vuint32*)(void*)(&__IPSBAR[0x1C0018]))
-#define MCF_CAN_ERRCNT0        (*(vuint32*)(void*)(&__IPSBAR[0x1C001C]))
-#define MCF_CAN_ERRSTAT0       (*(vuint32*)(void*)(&__IPSBAR[0x1C0020]))
-#define MCF_CAN_IMASK0         (*(vuint16*)(void*)(&__IPSBAR[0x1C002A]))
-#define MCF_CAN_IFLAG0         (*(vuint16*)(void*)(&__IPSBAR[0x1C0032]))
-#define MCF_CAN_CANMCR1        (*(vuint32*)(void*)(&__IPSBAR[0x1F0000]))
-#define MCF_CAN_CANCTRL1       (*(vuint32*)(void*)(&__IPSBAR[0x1F0004]))
-#define MCF_CAN_TIMER1         (*(vuint32*)(void*)(&__IPSBAR[0x1F0008]))
-#define MCF_CAN_RXGMASK1       (*(vuint32*)(void*)(&__IPSBAR[0x1F0010]))
-#define MCF_CAN_RX14MASK1      (*(vuint32*)(void*)(&__IPSBAR[0x1F0014]))
-#define MCF_CAN_RX15MASK1      (*(vuint32*)(void*)(&__IPSBAR[0x1F0018]))
-#define MCF_CAN_ERRCNT1        (*(vuint32*)(void*)(&__IPSBAR[0x1F001C]))
-#define MCF_CAN_ERRSTAT1       (*(vuint32*)(void*)(&__IPSBAR[0x1F0020]))
-#define MCF_CAN_IMASK1         (*(vuint16*)(void*)(&__IPSBAR[0x1F002A]))
-#define MCF_CAN_IFLAG1         (*(vuint16*)(void*)(&__IPSBAR[0x1F0032]))
-#define MCF_CAN_CANMCR(x)      (*(vuint32*)(void*)(&__IPSBAR[0x1C0000+((x)*0x30000)]))
-#define MCF_CAN_CANCTRL(x)     (*(vuint32*)(void*)(&__IPSBAR[0x1C0004+((x)*0x30000)]))
-#define MCF_CAN_TIMER(x)       (*(vuint32*)(void*)(&__IPSBAR[0x1C0008+((x)*0x30000)]))
-#define MCF_CAN_RXGMASK(x)     (*(vuint32*)(void*)(&__IPSBAR[0x1C0010+((x)*0x30000)]))
-#define MCF_CAN_RX14MASK(x)    (*(vuint32*)(void*)(&__IPSBAR[0x1C0014+((x)*0x30000)]))
-#define MCF_CAN_RX15MASK(x)    (*(vuint32*)(void*)(&__IPSBAR[0x1C0018+((x)*0x30000)]))
-#define MCF_CAN_ERRCNT(x)      (*(vuint32*)(void*)(&__IPSBAR[0x1C001C+((x)*0x30000)]))
-#define MCF_CAN_ERRSTAT(x)     (*(vuint32*)(void*)(&__IPSBAR[0x1C0020+((x)*0x30000)]))
-#define MCF_CAN_IMASK(x)       (*(vuint16*)(void*)(&__IPSBAR[0x1C002A+((x)*0x30000)]))
-#define MCF_CAN_IFLAG(x)       (*(vuint16*)(void*)(&__IPSBAR[0x1C0032+((x)*0x30000)]))
-
-#define MCF_CAN_MBUF0_CTRL(x)          (*(vuint16 *)(void *)(&__IPSBAR[0x1C0080+((x)*0x30000)]))
-#define MCF_CAN_MBUF0_TMSTP(x)         (*(vuint16 *)(void *)(&__IPSBAR[0x1C0082+((x)*0x30000)]))
-#define MCF_CAN_MBUF0_ID(x)        (*(vuint32 *)(void *)(&__IPSBAR[0x1C0084+((x)*0x30000)]))
-#define MCF_CAN_MBUF0_BYTE0(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C0088+((x)*0x30000)]))
-#define MCF_CAN_MBUF0_BYTE1(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C0089+((x)*0x30000)]))
-#define MCF_CAN_MBUF0_BYTE2(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C008A+((x)*0x30000)]))
-#define MCF_CAN_MBUF0_BYTE3(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C008B+((x)*0x30000)]))
-#define MCF_CAN_MBUF0_BYTE4(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C008C+((x)*0x30000)]))
-#define MCF_CAN_MBUF0_BYTE5(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C008D+((x)*0x30000)]))
-#define MCF_CAN_MBUF0_BYTE6(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C008E+((x)*0x30000)]))
-#define MCF_CAN_MBUF0_BYTE7(x)      (*(vuint8  *)(void *)(&__IPSBAR[0x1C008F+((x)*0x30000)]))
-#define MCF_CAN_MBUF1_CTRL(x)          (*(vuint16 *)(void *)(&__IPSBAR[0x1C0090+((x)*0x30000)]))
-#define MCF_CAN_MBUF1_TMSTP(x)         (*(vuint16 *)(void *)(&__IPSBAR[0x1C0092+((x)*0x30000)]))
-#define MCF_CAN_MBUF1_ID(x)                    (*(vuint32 *)(void *)(&__IPSBAR[0x1C0094+((x)*0x30000)]))
-#define MCF_CAN_MBUF1_BYTE0(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C0098+((x)*0x30000)]))
-#define MCF_CAN_MBUF1_BYTE1(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C0099+((x)*0x30000)]))
-#define MCF_CAN_MBUF1_BYTE2(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C009A+((x)*0x30000)]))
-#define MCF_CAN_MBUF1_BYTE3(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C009B+((x)*0x30000)]))
-#define MCF_CAN_MBUF1_BYTE4(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C009C+((x)*0x30000)]))
-#define MCF_CAN_MBUF1_BYTE5(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C009D+((x)*0x30000)]))
-#define MCF_CAN_MBUF1_BYTE6(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C009E+((x)*0x30000)]))
-#define MCF_CAN_MBUF1_BYTE7(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C009F+((x)*0x30000)]))
-#define MCF_CAN_MBUF2_CTRL(x)          (*(vuint16 *)(void *)(&__IPSBAR[0x1C00A0+((x)*0x30000)]))
-#define MCF_CAN_MBUF2_ID(x)        (*(vuint32 *)(void *)(&__IPSBAR[0x1C00A4+((x)*0x30000)]))
-#define MCF_CAN_MBUF2_BYTE0(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00A8+((x)*0x30000)]))
-#define MCF_CAN_MBUF2_BYTE1(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00A9+((x)*0x30000)]))
-#define MCF_CAN_MBUF2_BYTE2(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00AA+((x)*0x30000)]))
-#define MCF_CAN_MBUF2_BYTE3(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00AB+((x)*0x30000)]))
-#define MCF_CAN_MBUF2_BYTE4(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00AC+((x)*0x30000)]))
-#define MCF_CAN_MBUF2_BYTE5(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00AD+((x)*0x30000)]))
-#define MCF_CAN_MBUF2_BYTE6(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00AE+((x)*0x30000)]))
-#define MCF_CAN_MBUF2_BYTE7(x)      (*(vuint8  *)(void *)(&__IPSBAR[0x1C00AF+((x)*0x30000)]))
-#define MCF_CAN_MBUF3_CTRL(x)          (*(vuint16 *)(void *)(&__IPSBAR[0x1C00B0+((x)*0x30000)]))
-#define MCF_CAN_MBUF3_ID(x)                    (*(vuint32 *)(void *)(&__IPSBAR[0x1C00B4+((x)*0x30000)]))
-#define MCF_CAN_MBUF3_BYTE0(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00B8+((x)*0x30000)]))
-#define MCF_CAN_MBUF3_BYTE1(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00B9+((x)*0x30000)]))
-#define MCF_CAN_MBUF3_BYTE2(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00BA+((x)*0x30000)]))
-#define MCF_CAN_MBUF3_BYTE3(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00BB+((x)*0x30000)]))
-#define MCF_CAN_MBUF3_BYTE4(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00BC+((x)*0x30000)]))
-#define MCF_CAN_MBUF3_BYTE5(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00BD+((x)*0x30000)]))
-#define MCF_CAN_MBUF3_BYTE6(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00BE+((x)*0x30000)]))
-#define MCF_CAN_MBUF3_BYTE7(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00BF+((x)*0x30000)]))
-#define MCF_CAN_MBUF4_CTRL(x)          (*(vuint16 *)(void *)(&__IPSBAR[0x1C00C0+((x)*0x30000)]))
-#define MCF_CAN_MBUF4_ID(x)        (*(vuint32 *)(void *)(&__IPSBAR[0x1C00C4+((x)*0x30000)]))
-#define MCF_CAN_MBUF4_BYTE0(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00C8+((x)*0x30000)]))
-#define MCF_CAN_MBUF4_BYTE1(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00C9+((x)*0x30000)]))
-#define MCF_CAN_MBUF4_BYTE2(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00CA+((x)*0x30000)]))
-#define MCF_CAN_MBUF4_BYTE3(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00CB+((x)*0x30000)]))
-#define MCF_CAN_MBUF4_BYTE4(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00CC+((x)*0x30000)]))
-#define MCF_CAN_MBUF4_BYTE5(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00CD+((x)*0x30000)]))
-#define MCF_CAN_MBUF4_BYTE6(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00CE+((x)*0x30000)]))
-#define MCF_CAN_MBUF4_BYTE7(x)      (*(vuint8  *)(void *)(&__IPSBAR[0x1C00CF+((x)*0x30000)]))
-#define MCF_CAN_MBUF5_CTRL(x)          (*(vuint16 *)(void *)(&__IPSBAR[0x1C00D0+((x)*0x30000)]))
-#define MCF_CAN_MBUF5_ID(x)                    (*(vuint32 *)(void *)(&__IPSBAR[0x1C00D4+((x)*0x30000)]))
-#define MCF_CAN_MBUF5_BYTE0(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00D8+((x)*0x30000)]))
-#define MCF_CAN_MBUF5_BYTE1(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00D9+((x)*0x30000)]))
-#define MCF_CAN_MBUF5_BYTE2(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00DA+((x)*0x30000)]))
-#define MCF_CAN_MBUF5_BYTE3(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00DB+((x)*0x30000)]))
-#define MCF_CAN_MBUF5_BYTE4(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00DC+((x)*0x30000)]))
-#define MCF_CAN_MBUF5_BYTE5(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00DD+((x)*0x30000)]))
-#define MCF_CAN_MBUF5_BYTE6(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00DE+((x)*0x30000)]))
-#define MCF_CAN_MBUF5_BYTE7(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00DF+((x)*0x30000)]))
-#define MCF_CAN_MBUF6_CTRL(x)          (*(vuint16 *)(void *)(&__IPSBAR[0x1C00E0+((x)*0x30000)]))
-#define MCF_CAN_MBUF6_ID(x)        (*(vuint32 *)(void *)(&__IPSBAR[0x1C00E4+((x)*0x30000)]))
-#define MCF_CAN_MBUF6_BYTE0(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00E8+((x)*0x30000)]))
-#define MCF_CAN_MBUF6_BYTE1(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00E9+((x)*0x30000)]))
-#define MCF_CAN_MBUF6_BYTE2(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00EA+((x)*0x30000)]))
-#define MCF_CAN_MBUF6_BYTE3(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00EB+((x)*0x30000)]))
-#define MCF_CAN_MBUF6_BYTE4(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00EC+((x)*0x30000)]))
-#define MCF_CAN_MBUF6_BYTE5(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00ED+((x)*0x30000)]))
-#define MCF_CAN_MBUF6_BYTE6(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00EE+((x)*0x30000)]))
-#define MCF_CAN_MBUF6_BYTE7(x)      (*(vuint8  *)(void *)(&__IPSBAR[0x1C00EF+((x)*0x30000)]))
-#define MCF_CAN_MBUF7_CTRL(x)          (*(vuint16 *)(void *)(&__IPSBAR[0x1C00F0+((x)*0x30000)]))
-#define MCF_CAN_MBUF7_ID(x)                    (*(vuint32 *)(void *)(&__IPSBAR[0x1C00F4+((x)*0x30000)]))
-#define MCF_CAN_MBUF7_BYTE0(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00F8+((x)*0x30000)]))
-#define MCF_CAN_MBUF7_BYTE1(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00F9+((x)*0x30000)]))
-#define MCF_CAN_MBUF7_BYTE2(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00FA+((x)*0x30000)]))
-#define MCF_CAN_MBUF7_BYTE3(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00FB+((x)*0x30000)]))
-#define MCF_CAN_MBUF7_BYTE4(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00FC+((x)*0x30000)]))
-#define MCF_CAN_MBUF7_BYTE5(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00FD+((x)*0x30000)]))
-#define MCF_CAN_MBUF7_BYTE6(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00FE+((x)*0x30000)]))
-#define MCF_CAN_MBUF7_BYTE7(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00FF+((x)*0x30000)]))
-#define MCF_CAN_MBUF8_CTRL(x)          (*(vuint16 *)(void *)(&__IPSBAR[0x1C0100+((x)*0x30000)]))
-#define MCF_CAN_MBUF8_ID(x)        (*(vuint32 *)(void *)(&__IPSBAR[0x1C0104+((x)*0x30000)]))
-#define MCF_CAN_MBUF8_BYTE0(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C0108+((x)*0x30000)]))
-#define MCF_CAN_MBUF8_BYTE1(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C0109+((x)*0x30000)]))
-#define MCF_CAN_MBUF8_BYTE2(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C010A+((x)*0x30000)]))
-#define MCF_CAN_MBUF8_BYTE3(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C010B+((x)*0x30000)]))
-#define MCF_CAN_MBUF8_BYTE4(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C010C+((x)*0x30000)]))
-#define MCF_CAN_MBUF8_BYTE5(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C010D+((x)*0x30000)]))
-#define MCF_CAN_MBUF8_BYTE6(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C010E+((x)*0x30000)]))
-#define MCF_CAN_MBUF8_BYTE7(x)      (*(vuint8  *)(void *)(&__IPSBAR[0x1C010F+((x)*0x30000)]))
-#define MCF_CAN_MBUF9_CTRL(x)          (*(vuint16 *)(void *)(&__IPSBAR[0x1C0100+((x)*0x30000)]))
-#define MCF_CAN_MBUF9_ID(x)                    (*(vuint32 *)(void *)(&__IPSBAR[0x1C0114+((x)*0x30000)]))
-#define MCF_CAN_MBUF9_BYTE0(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C0118+((x)*0x30000)]))
-#define MCF_CAN_MBUF9_BYTE1(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C0119+((x)*0x30000)]))
-#define MCF_CAN_MBUF9_BYTE2(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C011A+((x)*0x30000)]))
-#define MCF_CAN_MBUF9_BYTE3(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C011B+((x)*0x30000)]))
-#define MCF_CAN_MBUF9_BYTE4(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C011C+((x)*0x30000)]))
-#define MCF_CAN_MBUF9_BYTE5(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C011D+((x)*0x30000)]))
-#define MCF_CAN_MBUF9_BYTE6(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C011E+((x)*0x30000)]))
-#define MCF_CAN_MBUF9_BYTE7(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C011F+((x)*0x30000)]))
-#define MCF_CAN_MBUF10_CTRL(x)         (*(vuint16 *)(void *)(&__IPSBAR[0x1C0120+((x)*0x30000)]))
-#define MCF_CAN_MBUF10_ID(x)       (*(vuint32 *)(void *)(&__IPSBAR[0x1C0124+((x)*0x30000)]))
-#define MCF_CAN_MBUF10_BYTE0(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C0128+((x)*0x30000)]))
-#define MCF_CAN_MBUF10_BYTE1(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C0129+((x)*0x30000)]))
-#define MCF_CAN_MBUF10_BYTE2(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C012A+((x)*0x30000)]))
-#define MCF_CAN_MBUF10_BYTE3(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C012B+((x)*0x30000)]))
-#define MCF_CAN_MBUF10_BYTE4(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C012C+((x)*0x30000)]))
-#define MCF_CAN_MBUF10_BYTE5(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C012D+((x)*0x30000)]))
-#define MCF_CAN_MBUF10_BYTE6(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C012E+((x)*0x30000)]))
-#define MCF_CAN_MBUF10_BYTE7(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C012F+((x)*0x30000)]))
-#define MCF_CAN_MBUF11_CTRL(x)         (*(vuint16 *)(void *)(&__IPSBAR[0x1C0130+((x)*0x30000)]))
-#define MCF_CAN_MBUF11_ID(x)           (*(vuint32 *)(void *)(&__IPSBAR[0x1C0134+((x)*0x30000)]))
-#define MCF_CAN_MBUF11_BYTE0(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C0138+((x)*0x30000)]))
-#define MCF_CAN_MBUF11_BYTE1(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C0139+((x)*0x30000)]))
-#define MCF_CAN_MBUF11_BYTE2(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C013A+((x)*0x30000)]))
-#define MCF_CAN_MBUF11_BYTE3(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C013B+((x)*0x30000)]))
-#define MCF_CAN_MBUF11_BYTE4(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C013C+((x)*0x30000)]))
-#define MCF_CAN_MBUF11_BYTE5(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C013D+((x)*0x30000)]))
-#define MCF_CAN_MBUF11_BYTE6(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C013E+((x)*0x30000)]))
-#define MCF_CAN_MBUF11_BYTE7(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C013F+((x)*0x30000)]))
-#define MCF_CAN_MBUF12_CTRL(x)         (*(vuint16 *)(void *)(&__IPSBAR[0x1C0140+((x)*0x30000)]))
-#define MCF_CAN_MBUF12_ID(x)       (*(vuint32 *)(void *)(&__IPSBAR[0x1C0144+((x)*0x30000)]))
-#define MCF_CAN_MBUF12_BYTE0(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C0148+((x)*0x30000)]))
-#define MCF_CAN_MBUF12_BYTE1(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C0149+((x)*0x30000)]))
-#define MCF_CAN_MBUF12_BYTE2(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C014A+((x)*0x30000)]))
-#define MCF_CAN_MBUF12_BYTE3(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C014B+((x)*0x30000)]))
-#define MCF_CAN_MBUF12_BYTE4(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C014C+((x)*0x30000)]))
-#define MCF_CAN_MBUF12_BYTE5(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C014D+((x)*0x30000)]))
-#define MCF_CAN_MBUF12_BYTE6(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C014E+((x)*0x30000)]))
-#define MCF_CAN_MBUF12_BYTE7(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C014F+((x)*0x30000)]))
-#define MCF_CAN_MBUF13_CTRL(x)         (*(vuint16 *)(void *)(&__IPSBAR[0x1C0150+((x)*0x30000)]))
-#define MCF_CAN_MBUF13_ID(x)           (*(vuint32 *)(void *)(&__IPSBAR[0x1C0154+((x)*0x30000)]))
-#define MCF_CAN_MBUF13_BYTE0(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C0158+((x)*0x30000)]))
-#define MCF_CAN_MBUF13_BYTE1(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C0159+((x)*0x30000)]))
-#define MCF_CAN_MBUF13_BYTE2(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C015A+((x)*0x30000)]))
-#define MCF_CAN_MBUF13_BYTE3(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C015B+((x)*0x30000)]))
-#define MCF_CAN_MBUF13_BYTE4(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C015C+((x)*0x30000)]))
-#define MCF_CAN_MBUF13_BYTE5(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C015D+((x)*0x30000)]))
-#define MCF_CAN_MBUF13_BYTE6(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C015E+((x)*0x30000)]))
-#define MCF_CAN_MBUF13_BYTE7(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C015F+((x)*0x30000)]))
-#define MCF_CAN_MBUF14_CTRL(x)         (*(vuint16 *)(void *)(&__IPSBAR[0x1C0160+((x)*0x30000)]))
-#define MCF_CAN_MBUF14_ID(x)       (*(vuint32 *)(void *)(&__IPSBAR[0x1C0164+((x)*0x30000)]))
-#define MCF_CAN_MBUF14_BYTE0(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C0168+((x)*0x30000)]))
-#define MCF_CAN_MBUF14_BYTE1(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C0169+((x)*0x30000)]))
-#define MCF_CAN_MBUF14_BYTE2(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C016A+((x)*0x30000)]))
-#define MCF_CAN_MBUF14_BYTE3(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C016B+((x)*0x30000)]))
-#define MCF_CAN_MBUF14_BYTE4(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C016C+((x)*0x30000)]))
-#define MCF_CAN_MBUF14_BYTE5(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C016D+((x)*0x30000)]))
-#define MCF_CAN_MBUF14_BYTE6(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C016E+((x)*0x30000)]))
-#define MCF_CAN_MBUF14_BYTE7(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C016F+((x)*0x30000)]))
-#define MCF_CAN_MBUF15_CTRL(x)         (*(vuint16 *)(void *)(&__IPSBAR[0x1C0170+((x)*0x30000)]))
-#define MCF_CAN_MBUF15_ID(x)           (*(vuint32 *)(void *)(&__IPSBAR[0x1C0174+((x)*0x30000)]))
-#define MCF_CAN_MBUF15_BYTE0(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C0178+((x)*0x30000)]))
-#define MCF_CAN_MBUF15_BYTE1(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C0179+((x)*0x30000)]))
-#define MCF_CAN_MBUF15_BYTE2(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C017A+((x)*0x30000)]))
-#define MCF_CAN_MBUF15_BYTE3(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C017B+((x)*0x30000)]))
-#define MCF_CAN_MBUF15_BYTE4(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C017C+((x)*0x30000)]))
-#define MCF_CAN_MBUF15_BYTE5(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C017D+((x)*0x30000)]))
-#define MCF_CAN_MBUF15_BYTE6(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C017E+((x)*0x30000)]))
-#define MCF_CAN_MBUF15_BYTE7(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C017F+((x)*0x30000)]))
-                                                                                                                                                                 
-                                                                                                                                                                 
-#define MCF_CAN_MBUF0_DATAL(x)     (*(vuint32  *)(void *)(&__IPSBAR[0x1C0088+((x)*0x30000)]))
-#define MCF_CAN_MBUF0_DATAH(x)     (*(vuint32  *)(void *)(&__IPSBAR[0x1C008C+((x)*0x30000)]))
-#define MCF_CAN_MBUF1_DATAL(x)         (*(vuint32  *)(void *)(&__IPSBAR[0x1C0098+((x)*0x30000)]))
-#define MCF_CAN_MBUF1_DATAH(x)         (*(vuint32  *)(void *)(&__IPSBAR[0x1C009C+((x)*0x30000)]))
-#define MCF_CAN_MBUF2_DATAL(x)     (*(vuint32  *)(void *)(&__IPSBAR[0x1C00A8+((x)*0x30000)]))
-#define MCF_CAN_MBUF2_DATAH(x)     (*(vuint32  *)(void *)(&__IPSBAR[0x1C00AC+((x)*0x30000)]))
-                                                                                                                                                                 
-                                                                                                                                                                 
-/* Bit definitions and macros for MCF_CAN_CANMCR */                                                              
-#define MCF_CAN_CANMCR_MAXMB(x)            (((x)&0x0000000F)<<0)                                 
-#define MCF_CAN_CANMCR_SUPV                (0x00800000)                                                          
-#define MCF_CAN_CANMCR_FRZACK              (0x01000000)                                                          
-#define MCF_CAN_CANMCR_SOFTRST             (0x02000000)                                                          
-#define MCF_CAN_CANMCR_HALT                (0x10000000)                                                          
-#define MCF_CAN_CANMCR_FRZ                 (0x40000000)                                                          
-#define MCF_CAN_CANMCR_MDIS                (0x80000000)                                                          
-
-/* Bit definitions and macros for MCF_CAN_CANCTRL */
-#define MCF_CAN_CANCTRL_PROPSEG(x)         (((x)&0x00000007)<<0)
-#define MCF_CAN_CANCTRL_LOM                (0x00000008)
-#define MCF_CAN_CANCTRL_LBUF               (0x00000010)
-#define MCF_CAN_CANCTRL_TSYNC              (0x00000020)
-#define MCF_CAN_CANCTRL_BOFFREC            (0x00000040)
-#define MCF_CAN_CANCTRL_SAMP               (0x00000080)
-#define MCF_CAN_CANCTRL_LPB                (0x00001000)
-#define MCF_CAN_CANCTRL_CLKSRC             (0x00002000)
-#define MCF_CAN_CANCTRL_ERRMSK             (0x00004000)
-#define MCF_CAN_CANCTRL_BOFFMSK            (0x00008000)
-#define MCF_CAN_CANCTRL_PSEG2(x)           (((x)&0x00000007)<<16)
-#define MCF_CAN_CANCTRL_PSEG1(x)           (((x)&0x00000007)<<19)
-#define MCF_CAN_CANCTRL_RJW(x)             (((x)&0x00000003)<<22)
-#define MCF_CAN_CANCTRL_PRESDIV(x)         (((x)&0x000000FF)<<24)
-
-/* Bit definitions and macros for MCF_CAN_TIMER */
-#define MCF_CAN_TIMER_TIMER(x)             (((x)&0x0000FFFF)<<0)
-
-/* Bit definitions and macros for MCF_CAN_RXGMASK */
-#define MCF_CAN_RXGMASK_MI(x)              (((x)&0x1FFFFFFF)<<0)
-
-/* Bit definitions and macros for MCF_CAN_RX14MASK */
-#define MCF_CAN_RX14MASK_MI(x)             (((x)&0x1FFFFFFF)<<0)
-
-/* Bit definitions and macros for MCF_CAN_RX15MASK */
-#define MCF_CAN_RX15MASK_MI(x)             (((x)&0x1FFFFFFF)<<0)
-
-/* Bit definitions and macros for MCF_CAN_ERRCNT */
-#define MCF_CAN_ERRCNT_TXECTR(x)           (((x)&0x000000FF)<<0)
-#define MCF_CAN_ERRCNT_RXECTR(x)           (((x)&0x000000FF)<<8)
-
-/* Bit definitions and macros for MCF_CAN_ERRSTAT */
-#define MCF_CAN_ERRSTAT_WAKINT             (0x00000001)
-#define MCF_CAN_ERRSTAT_ERRINT             (0x00000002)
-#define MCF_CAN_ERRSTAT_BOFFINT            (0x00000004)
-#define MCF_CAN_ERRSTAT_FLTCONF(x)         (((x)&0x00000003)<<4)
-#define MCF_CAN_ERRSTAT_TXRX               (0x00000040)
-#define MCF_CAN_ERRSTAT_IDLE               (0x00000080)
-#define MCF_CAN_ERRSTAT_RXWRN              (0x00000100)
-#define MCF_CAN_ERRSTAT_TXWRN              (0x00000200)
-#define MCF_CAN_ERRSTAT_STFERR             (0x00000400)
-#define MCF_CAN_ERRSTAT_FRMERR             (0x00000800)
-#define MCF_CAN_ERRSTAT_CRCERR             (0x00001000)
-#define MCF_CAN_ERRSTAT_ACKERR             (0x00002000)
-#define MCF_CAN_ERRSTAT_BITERR(x)          (((x)&0x00000003)<<14)
-#define MCF_CAN_ERRSTAT_FLTCONF_ACTIVE     (0x00000000)
-#define MCF_CAN_ERRSTAT_FLTCONF_PASSIVE    (0x00000010)
-#define MCF_CAN_ERRSTAT_FLTCONF_BUSOFF     (0x00000020)
-
-/* Bit definitions and macros for MCF_CAN_IMASK */
-#define MCF_CAN_IMASK_BUF0M                (0x0001)
-#define MCF_CAN_IMASK_BUF1M                (0x0002)
-#define MCF_CAN_IMASK_BUF2M                (0x0004)
-#define MCF_CAN_IMASK_BUF3M                (0x0008)
-#define MCF_CAN_IMASK_BUF4M                (0x0010)
-#define MCF_CAN_IMASK_BUF5M                (0x0020)
-#define MCF_CAN_IMASK_BUF6M                (0x0040)
-#define MCF_CAN_IMASK_BUF7M                (0x0080)
-#define MCF_CAN_IMASK_BUF8M                (0x0100)
-#define MCF_CAN_IMASK_BUF9M                (0x0200)
-#define MCF_CAN_IMASK_BUF10M               (0x0400)
-#define MCF_CAN_IMASK_BUF11M               (0x0800)
-#define MCF_CAN_IMASK_BUF12M               (0x1000)
-#define MCF_CAN_IMASK_BUF13M               (0x2000)
-#define MCF_CAN_IMASK_BUF14M               (0x4000)
-#define MCF_CAN_IMASK_BUF15M               (0x8000)
-
-/* Bit definitions and macros for MCF_CAN_IFLAG */
-#define MCF_CAN_IFLAG_BUF0I                (0x0001)
-#define MCF_CAN_IFLAG_BUF1I                (0x0002)
-#define MCF_CAN_IFLAG_BUF2I                (0x0004)
-#define MCF_CAN_IFLAG_BUF3I                (0x0008)
-#define MCF_CAN_IFLAG_BUF4I                (0x0010)
-#define MCF_CAN_IFLAG_BUF5I                (0x0020)
-#define MCF_CAN_IFLAG_BUF6I                (0x0040)
-#define MCF_CAN_IFLAG_BUF7I                (0x0080)
-#define MCF_CAN_IFLAG_BUF8I                (0x0100)
-#define MCF_CAN_IFLAG_BUF9I                (0x0200)
-#define MCF_CAN_IFLAG_BUF10I               (0x0400)
-#define MCF_CAN_IFLAG_BUF11I               (0x0800)
-#define MCF_CAN_IFLAG_BUF12I               (0x1000)
-#define MCF_CAN_IFLAG_BUF13I               (0x2000)
-#define MCF_CAN_IFLAG_BUF14I               (0x4000)
-#define MCF_CAN_IFLAG_BUF15I               (0x8000)
-
-/********************************************************************/
-
-#endif /* __MCF523X_CAN_H__ */
+/*\r
+ * These files are taken from the MCF523X source code example package\r
+ * which is available on the Freescale website. Freescale explicitly \r
+ * grants the redistribution and modification of these source files.\r
+ * The complete licensing information is available in the file \r
+ * LICENSE_FREESCALE.TXT.\r
+ *\r
+ * File:       mcf523x_can.h\r
+ * Purpose:    Register and bit definitions for the MCF523X\r
+ *\r
+ * Notes:      \r
+ *     \r
+ */\r
+\r
+#ifndef __MCF523X_CAN_H__\r
+#define __MCF523X_CAN_H__\r
+\r
+/*********************************************************************\r
+*\r
+* FlexCAN Module (CAN)\r
+*\r
+*********************************************************************/\r
+\r
+/* Register read/write macros */\r
+#define MCF_CAN_CANMCR0        (*(vuint32*)(void*)(&__IPSBAR[0x1C0000]))\r
+#define MCF_CAN_CANCTRL0       (*(vuint32*)(void*)(&__IPSBAR[0x1C0004]))\r
+#define MCF_CAN_TIMER0         (*(vuint32*)(void*)(&__IPSBAR[0x1C0008]))\r
+#define MCF_CAN_RXGMASK0       (*(vuint32*)(void*)(&__IPSBAR[0x1C0010]))\r
+#define MCF_CAN_RX14MASK0      (*(vuint32*)(void*)(&__IPSBAR[0x1C0014]))\r
+#define MCF_CAN_RX15MASK0      (*(vuint32*)(void*)(&__IPSBAR[0x1C0018]))\r
+#define MCF_CAN_ERRCNT0        (*(vuint32*)(void*)(&__IPSBAR[0x1C001C]))\r
+#define MCF_CAN_ERRSTAT0       (*(vuint32*)(void*)(&__IPSBAR[0x1C0020]))\r
+#define MCF_CAN_IMASK0         (*(vuint16*)(void*)(&__IPSBAR[0x1C002A]))\r
+#define MCF_CAN_IFLAG0         (*(vuint16*)(void*)(&__IPSBAR[0x1C0032]))\r
+#define MCF_CAN_CANMCR1        (*(vuint32*)(void*)(&__IPSBAR[0x1F0000]))\r
+#define MCF_CAN_CANCTRL1       (*(vuint32*)(void*)(&__IPSBAR[0x1F0004]))\r
+#define MCF_CAN_TIMER1         (*(vuint32*)(void*)(&__IPSBAR[0x1F0008]))\r
+#define MCF_CAN_RXGMASK1       (*(vuint32*)(void*)(&__IPSBAR[0x1F0010]))\r
+#define MCF_CAN_RX14MASK1      (*(vuint32*)(void*)(&__IPSBAR[0x1F0014]))\r
+#define MCF_CAN_RX15MASK1      (*(vuint32*)(void*)(&__IPSBAR[0x1F0018]))\r
+#define MCF_CAN_ERRCNT1        (*(vuint32*)(void*)(&__IPSBAR[0x1F001C]))\r
+#define MCF_CAN_ERRSTAT1       (*(vuint32*)(void*)(&__IPSBAR[0x1F0020]))\r
+#define MCF_CAN_IMASK1         (*(vuint16*)(void*)(&__IPSBAR[0x1F002A]))\r
+#define MCF_CAN_IFLAG1         (*(vuint16*)(void*)(&__IPSBAR[0x1F0032]))\r
+#define MCF_CAN_CANMCR(x)      (*(vuint32*)(void*)(&__IPSBAR[0x1C0000+((x)*0x30000)]))\r
+#define MCF_CAN_CANCTRL(x)     (*(vuint32*)(void*)(&__IPSBAR[0x1C0004+((x)*0x30000)]))\r
+#define MCF_CAN_TIMER(x)       (*(vuint32*)(void*)(&__IPSBAR[0x1C0008+((x)*0x30000)]))\r
+#define MCF_CAN_RXGMASK(x)     (*(vuint32*)(void*)(&__IPSBAR[0x1C0010+((x)*0x30000)]))\r
+#define MCF_CAN_RX14MASK(x)    (*(vuint32*)(void*)(&__IPSBAR[0x1C0014+((x)*0x30000)]))\r
+#define MCF_CAN_RX15MASK(x)    (*(vuint32*)(void*)(&__IPSBAR[0x1C0018+((x)*0x30000)]))\r
+#define MCF_CAN_ERRCNT(x)      (*(vuint32*)(void*)(&__IPSBAR[0x1C001C+((x)*0x30000)]))\r
+#define MCF_CAN_ERRSTAT(x)     (*(vuint32*)(void*)(&__IPSBAR[0x1C0020+((x)*0x30000)]))\r
+#define MCF_CAN_IMASK(x)       (*(vuint16*)(void*)(&__IPSBAR[0x1C002A+((x)*0x30000)]))\r
+#define MCF_CAN_IFLAG(x)       (*(vuint16*)(void*)(&__IPSBAR[0x1C0032+((x)*0x30000)]))\r
+\r
+#define MCF_CAN_MBUF0_CTRL(x)          (*(vuint16 *)(void *)(&__IPSBAR[0x1C0080+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF0_TMSTP(x)         (*(vuint16 *)(void *)(&__IPSBAR[0x1C0082+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF0_ID(x)        (*(vuint32 *)(void *)(&__IPSBAR[0x1C0084+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF0_BYTE0(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C0088+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF0_BYTE1(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C0089+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF0_BYTE2(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C008A+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF0_BYTE3(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C008B+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF0_BYTE4(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C008C+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF0_BYTE5(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C008D+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF0_BYTE6(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C008E+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF0_BYTE7(x)      (*(vuint8  *)(void *)(&__IPSBAR[0x1C008F+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF1_CTRL(x)          (*(vuint16 *)(void *)(&__IPSBAR[0x1C0090+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF1_TMSTP(x)         (*(vuint16 *)(void *)(&__IPSBAR[0x1C0092+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF1_ID(x)                    (*(vuint32 *)(void *)(&__IPSBAR[0x1C0094+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF1_BYTE0(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C0098+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF1_BYTE1(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C0099+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF1_BYTE2(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C009A+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF1_BYTE3(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C009B+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF1_BYTE4(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C009C+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF1_BYTE5(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C009D+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF1_BYTE6(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C009E+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF1_BYTE7(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C009F+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF2_CTRL(x)          (*(vuint16 *)(void *)(&__IPSBAR[0x1C00A0+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF2_ID(x)        (*(vuint32 *)(void *)(&__IPSBAR[0x1C00A4+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF2_BYTE0(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00A8+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF2_BYTE1(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00A9+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF2_BYTE2(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00AA+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF2_BYTE3(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00AB+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF2_BYTE4(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00AC+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF2_BYTE5(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00AD+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF2_BYTE6(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00AE+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF2_BYTE7(x)      (*(vuint8  *)(void *)(&__IPSBAR[0x1C00AF+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF3_CTRL(x)          (*(vuint16 *)(void *)(&__IPSBAR[0x1C00B0+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF3_ID(x)                    (*(vuint32 *)(void *)(&__IPSBAR[0x1C00B4+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF3_BYTE0(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00B8+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF3_BYTE1(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00B9+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF3_BYTE2(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00BA+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF3_BYTE3(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00BB+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF3_BYTE4(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00BC+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF3_BYTE5(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00BD+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF3_BYTE6(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00BE+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF3_BYTE7(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00BF+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF4_CTRL(x)          (*(vuint16 *)(void *)(&__IPSBAR[0x1C00C0+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF4_ID(x)        (*(vuint32 *)(void *)(&__IPSBAR[0x1C00C4+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF4_BYTE0(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00C8+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF4_BYTE1(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00C9+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF4_BYTE2(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00CA+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF4_BYTE3(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00CB+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF4_BYTE4(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00CC+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF4_BYTE5(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00CD+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF4_BYTE6(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00CE+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF4_BYTE7(x)      (*(vuint8  *)(void *)(&__IPSBAR[0x1C00CF+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF5_CTRL(x)          (*(vuint16 *)(void *)(&__IPSBAR[0x1C00D0+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF5_ID(x)                    (*(vuint32 *)(void *)(&__IPSBAR[0x1C00D4+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF5_BYTE0(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00D8+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF5_BYTE1(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00D9+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF5_BYTE2(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00DA+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF5_BYTE3(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00DB+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF5_BYTE4(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00DC+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF5_BYTE5(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00DD+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF5_BYTE6(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00DE+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF5_BYTE7(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00DF+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF6_CTRL(x)          (*(vuint16 *)(void *)(&__IPSBAR[0x1C00E0+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF6_ID(x)        (*(vuint32 *)(void *)(&__IPSBAR[0x1C00E4+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF6_BYTE0(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00E8+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF6_BYTE1(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00E9+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF6_BYTE2(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00EA+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF6_BYTE3(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00EB+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF6_BYTE4(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00EC+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF6_BYTE5(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00ED+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF6_BYTE6(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00EE+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF6_BYTE7(x)      (*(vuint8  *)(void *)(&__IPSBAR[0x1C00EF+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF7_CTRL(x)          (*(vuint16 *)(void *)(&__IPSBAR[0x1C00F0+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF7_ID(x)                    (*(vuint32 *)(void *)(&__IPSBAR[0x1C00F4+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF7_BYTE0(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00F8+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF7_BYTE1(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00F9+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF7_BYTE2(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00FA+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF7_BYTE3(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00FB+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF7_BYTE4(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00FC+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF7_BYTE5(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00FD+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF7_BYTE6(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00FE+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF7_BYTE7(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00FF+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF8_CTRL(x)          (*(vuint16 *)(void *)(&__IPSBAR[0x1C0100+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF8_ID(x)        (*(vuint32 *)(void *)(&__IPSBAR[0x1C0104+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF8_BYTE0(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C0108+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF8_BYTE1(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C0109+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF8_BYTE2(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C010A+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF8_BYTE3(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C010B+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF8_BYTE4(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C010C+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF8_BYTE5(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C010D+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF8_BYTE6(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C010E+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF8_BYTE7(x)      (*(vuint8  *)(void *)(&__IPSBAR[0x1C010F+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF9_CTRL(x)          (*(vuint16 *)(void *)(&__IPSBAR[0x1C0100+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF9_ID(x)                    (*(vuint32 *)(void *)(&__IPSBAR[0x1C0114+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF9_BYTE0(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C0118+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF9_BYTE1(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C0119+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF9_BYTE2(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C011A+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF9_BYTE3(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C011B+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF9_BYTE4(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C011C+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF9_BYTE5(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C011D+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF9_BYTE6(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C011E+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF9_BYTE7(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C011F+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF10_CTRL(x)         (*(vuint16 *)(void *)(&__IPSBAR[0x1C0120+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF10_ID(x)       (*(vuint32 *)(void *)(&__IPSBAR[0x1C0124+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF10_BYTE0(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C0128+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF10_BYTE1(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C0129+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF10_BYTE2(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C012A+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF10_BYTE3(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C012B+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF10_BYTE4(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C012C+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF10_BYTE5(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C012D+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF10_BYTE6(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C012E+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF10_BYTE7(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C012F+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF11_CTRL(x)         (*(vuint16 *)(void *)(&__IPSBAR[0x1C0130+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF11_ID(x)           (*(vuint32 *)(void *)(&__IPSBAR[0x1C0134+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF11_BYTE0(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C0138+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF11_BYTE1(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C0139+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF11_BYTE2(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C013A+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF11_BYTE3(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C013B+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF11_BYTE4(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C013C+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF11_BYTE5(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C013D+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF11_BYTE6(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C013E+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF11_BYTE7(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C013F+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF12_CTRL(x)         (*(vuint16 *)(void *)(&__IPSBAR[0x1C0140+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF12_ID(x)       (*(vuint32 *)(void *)(&__IPSBAR[0x1C0144+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF12_BYTE0(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C0148+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF12_BYTE1(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C0149+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF12_BYTE2(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C014A+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF12_BYTE3(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C014B+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF12_BYTE4(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C014C+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF12_BYTE5(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C014D+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF12_BYTE6(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C014E+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF12_BYTE7(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C014F+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF13_CTRL(x)         (*(vuint16 *)(void *)(&__IPSBAR[0x1C0150+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF13_ID(x)           (*(vuint32 *)(void *)(&__IPSBAR[0x1C0154+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF13_BYTE0(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C0158+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF13_BYTE1(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C0159+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF13_BYTE2(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C015A+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF13_BYTE3(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C015B+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF13_BYTE4(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C015C+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF13_BYTE5(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C015D+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF13_BYTE6(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C015E+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF13_BYTE7(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C015F+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF14_CTRL(x)         (*(vuint16 *)(void *)(&__IPSBAR[0x1C0160+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF14_ID(x)       (*(vuint32 *)(void *)(&__IPSBAR[0x1C0164+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF14_BYTE0(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C0168+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF14_BYTE1(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C0169+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF14_BYTE2(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C016A+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF14_BYTE3(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C016B+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF14_BYTE4(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C016C+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF14_BYTE5(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C016D+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF14_BYTE6(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C016E+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF14_BYTE7(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C016F+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF15_CTRL(x)         (*(vuint16 *)(void *)(&__IPSBAR[0x1C0170+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF15_ID(x)           (*(vuint32 *)(void *)(&__IPSBAR[0x1C0174+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF15_BYTE0(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C0178+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF15_BYTE1(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C0179+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF15_BYTE2(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C017A+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF15_BYTE3(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C017B+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF15_BYTE4(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C017C+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF15_BYTE5(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C017D+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF15_BYTE6(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C017E+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF15_BYTE7(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C017F+((x)*0x30000)]))\r
+                                                                                                                                                                 \r
+                                                                                                                                                                 \r
+#define MCF_CAN_MBUF0_DATAL(x)     (*(vuint32  *)(void *)(&__IPSBAR[0x1C0088+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF0_DATAH(x)     (*(vuint32  *)(void *)(&__IPSBAR[0x1C008C+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF1_DATAL(x)         (*(vuint32  *)(void *)(&__IPSBAR[0x1C0098+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF1_DATAH(x)         (*(vuint32  *)(void *)(&__IPSBAR[0x1C009C+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF2_DATAL(x)     (*(vuint32  *)(void *)(&__IPSBAR[0x1C00A8+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF2_DATAH(x)     (*(vuint32  *)(void *)(&__IPSBAR[0x1C00AC+((x)*0x30000)]))\r
+                                                                                                                                                                 \r
+                                                                                                                                                                 \r
+/* Bit definitions and macros for MCF_CAN_CANMCR */                                                              \r
+#define MCF_CAN_CANMCR_MAXMB(x)            (((x)&0x0000000F)<<0)                                 \r
+#define MCF_CAN_CANMCR_SUPV                (0x00800000)                                                          \r
+#define MCF_CAN_CANMCR_FRZACK              (0x01000000)                                                          \r
+#define MCF_CAN_CANMCR_SOFTRST             (0x02000000)                                                          \r
+#define MCF_CAN_CANMCR_HALT                (0x10000000)                                                          \r
+#define MCF_CAN_CANMCR_FRZ                 (0x40000000)                                                          \r
+#define MCF_CAN_CANMCR_MDIS                (0x80000000)                                                          \r
+\r
+/* Bit definitions and macros for MCF_CAN_CANCTRL */\r
+#define MCF_CAN_CANCTRL_PROPSEG(x)         (((x)&0x00000007)<<0)\r
+#define MCF_CAN_CANCTRL_LOM                (0x00000008)\r
+#define MCF_CAN_CANCTRL_LBUF               (0x00000010)\r
+#define MCF_CAN_CANCTRL_TSYNC              (0x00000020)\r
+#define MCF_CAN_CANCTRL_BOFFREC            (0x00000040)\r
+#define MCF_CAN_CANCTRL_SAMP               (0x00000080)\r
+#define MCF_CAN_CANCTRL_LPB                (0x00001000)\r
+#define MCF_CAN_CANCTRL_CLKSRC             (0x00002000)\r
+#define MCF_CAN_CANCTRL_ERRMSK             (0x00004000)\r
+#define MCF_CAN_CANCTRL_BOFFMSK            (0x00008000)\r
+#define MCF_CAN_CANCTRL_PSEG2(x)           (((x)&0x00000007)<<16)\r
+#define MCF_CAN_CANCTRL_PSEG1(x)           (((x)&0x00000007)<<19)\r
+#define MCF_CAN_CANCTRL_RJW(x)             (((x)&0x00000003)<<22)\r
+#define MCF_CAN_CANCTRL_PRESDIV(x)         (((x)&0x000000FF)<<24)\r
+\r
+/* Bit definitions and macros for MCF_CAN_TIMER */\r
+#define MCF_CAN_TIMER_TIMER(x)             (((x)&0x0000FFFF)<<0)\r
+\r
+/* Bit definitions and macros for MCF_CAN_RXGMASK */\r
+#define MCF_CAN_RXGMASK_MI(x)              (((x)&0x1FFFFFFF)<<0)\r
+\r
+/* Bit definitions and macros for MCF_CAN_RX14MASK */\r
+#define MCF_CAN_RX14MASK_MI(x)             (((x)&0x1FFFFFFF)<<0)\r
+\r
+/* Bit definitions and macros for MCF_CAN_RX15MASK */\r
+#define MCF_CAN_RX15MASK_MI(x)             (((x)&0x1FFFFFFF)<<0)\r
+\r
+/* Bit definitions and macros for MCF_CAN_ERRCNT */\r
+#define MCF_CAN_ERRCNT_TXECTR(x)           (((x)&0x000000FF)<<0)\r
+#define MCF_CAN_ERRCNT_RXECTR(x)           (((x)&0x000000FF)<<8)\r
+\r
+/* Bit definitions and macros for MCF_CAN_ERRSTAT */\r
+#define MCF_CAN_ERRSTAT_WAKINT             (0x00000001)\r
+#define MCF_CAN_ERRSTAT_ERRINT             (0x00000002)\r
+#define MCF_CAN_ERRSTAT_BOFFINT            (0x00000004)\r
+#define MCF_CAN_ERRSTAT_FLTCONF(x)         (((x)&0x00000003)<<4)\r
+#define MCF_CAN_ERRSTAT_TXRX               (0x00000040)\r
+#define MCF_CAN_ERRSTAT_IDLE               (0x00000080)\r
+#define MCF_CAN_ERRSTAT_RXWRN              (0x00000100)\r
+#define MCF_CAN_ERRSTAT_TXWRN              (0x00000200)\r
+#define MCF_CAN_ERRSTAT_STFERR             (0x00000400)\r
+#define MCF_CAN_ERRSTAT_FRMERR             (0x00000800)\r
+#define MCF_CAN_ERRSTAT_CRCERR             (0x00001000)\r
+#define MCF_CAN_ERRSTAT_ACKERR             (0x00002000)\r
+#define MCF_CAN_ERRSTAT_BITERR(x)          (((x)&0x00000003)<<14)\r
+#define MCF_CAN_ERRSTAT_FLTCONF_ACTIVE     (0x00000000)\r
+#define MCF_CAN_ERRSTAT_FLTCONF_PASSIVE    (0x00000010)\r
+#define MCF_CAN_ERRSTAT_FLTCONF_BUSOFF     (0x00000020)\r
+\r
+/* Bit definitions and macros for MCF_CAN_IMASK */\r
+#define MCF_CAN_IMASK_BUF0M                (0x0001)\r
+#define MCF_CAN_IMASK_BUF1M                (0x0002)\r
+#define MCF_CAN_IMASK_BUF2M                (0x0004)\r
+#define MCF_CAN_IMASK_BUF3M                (0x0008)\r
+#define MCF_CAN_IMASK_BUF4M                (0x0010)\r
+#define MCF_CAN_IMASK_BUF5M                (0x0020)\r
+#define MCF_CAN_IMASK_BUF6M                (0x0040)\r
+#define MCF_CAN_IMASK_BUF7M                (0x0080)\r
+#define MCF_CAN_IMASK_BUF8M                (0x0100)\r
+#define MCF_CAN_IMASK_BUF9M                (0x0200)\r
+#define MCF_CAN_IMASK_BUF10M               (0x0400)\r
+#define MCF_CAN_IMASK_BUF11M               (0x0800)\r
+#define MCF_CAN_IMASK_BUF12M               (0x1000)\r
+#define MCF_CAN_IMASK_BUF13M               (0x2000)\r
+#define MCF_CAN_IMASK_BUF14M               (0x4000)\r
+#define MCF_CAN_IMASK_BUF15M               (0x8000)\r
+\r
+/* Bit definitions and macros for MCF_CAN_IFLAG */\r
+#define MCF_CAN_IFLAG_BUF0I                (0x0001)\r
+#define MCF_CAN_IFLAG_BUF1I                (0x0002)\r
+#define MCF_CAN_IFLAG_BUF2I                (0x0004)\r
+#define MCF_CAN_IFLAG_BUF3I                (0x0008)\r
+#define MCF_CAN_IFLAG_BUF4I                (0x0010)\r
+#define MCF_CAN_IFLAG_BUF5I                (0x0020)\r
+#define MCF_CAN_IFLAG_BUF6I                (0x0040)\r
+#define MCF_CAN_IFLAG_BUF7I                (0x0080)\r
+#define MCF_CAN_IFLAG_BUF8I                (0x0100)\r
+#define MCF_CAN_IFLAG_BUF9I                (0x0200)\r
+#define MCF_CAN_IFLAG_BUF10I               (0x0400)\r
+#define MCF_CAN_IFLAG_BUF11I               (0x0800)\r
+#define MCF_CAN_IFLAG_BUF12I               (0x1000)\r
+#define MCF_CAN_IFLAG_BUF13I               (0x2000)\r
+#define MCF_CAN_IFLAG_BUF14I               (0x4000)\r
+#define MCF_CAN_IFLAG_BUF15I               (0x8000)\r
+\r
+/********************************************************************/\r
+\r
+#endif /* __MCF523X_CAN_H__ */\r
index da9bdb79e090e5b9cbd13fa70d0a9f592ec91f9d..dd3b71c6492b91374c33e4ba79397887457e1fc4 100644 (file)
@@ -1,56 +1,56 @@
-/*
- * These files are taken from the MCF523X source code example package
- * which is available on the Freescale website. Freescale explicitly 
- * grants the redistribution and modification of these source files.
- * The complete licensing information is available in the file 
- * LICENSE_FREESCALE.TXT.
- *
- * File:       mcf523x_ccm.h
- * Purpose:    Register and bit definitions for the MCF523X
- *
- * Notes:      
- *     
- */
-
-#ifndef __MCF523X_CCM_H__
-#define __MCF523X_CCM_H__
-
-/*********************************************************************
-*
-* Chip Configuration Module (CCM)
-*
-*********************************************************************/
-
-/* Register read/write macros */
-#define MCF_CCM_CCR     (*(vuint16*)(void*)(&__IPSBAR[0x110004]))
-#define MCF_CCM_LPCR    (*(vuint8 *)(void*)(&__IPSBAR[0x110007]))
-#define MCF_CCM_CIR     (*(vuint16*)(void*)(&__IPSBAR[0x11000A]))
-#define MCF_CCM_RCON    (*(vuint16*)(void*)(&__IPSBAR[0x110008]))
-
-/* Bit definitions and macros for MCF_CCM_CCR */
-#define MCF_CCM_CCR_BMT(x)        (((x)&0x0007)<<0)
-#define MCF_CCM_CCR_BME           (0x0008)
-#define MCF_CCM_CCR_SZEN          (0x0040)
-#define MCF_CCM_CCR_MODE(x)       (((x)&0x0007)<<8)
-
-/* Bit definitions and macros for MCF_CCM_LPCR */
-#define MCF_CCM_LPCR_STPMD(x)     (((x)&0x03)<<3)
-#define MCF_CCM_LPCR_LPMD(x)      (((x)&0x03)<<6)
-#define MCF_CCM_LPCR_LPMD_STOP    (0xC0)
-#define MCF_CCM_LPCR_LPMD_WAIT    (0x80)
-#define MCF_CCM_LPCR_LPMD_DOZE    (0x40)
-#define MCF_CCM_LPCR_LPMD_RUN     (0x00)
-
-/* Bit definitions and macros for MCF_CCM_CIR */
-#define MCF_CCM_CIR_PRN(x)        (((x)&0x003F)<<0)
-#define MCF_CCM_CIR_PIN(x)        (((x)&0x03FF)<<6)
-
-/* Bit definitions and macros for MCF_CCM_RCON */
-#define MCF_CCM_RCON_MODE         (0x0001)
-#define MCF_CCM_RCON_BOOTPS(x)    (((x)&0x0003)<<3)
-#define MCF_CCM_RCON_RLOAD        (0x0020)
-#define MCF_CCM_RCON_RCSC(x)      (((x)&0x0003)<<8)
-
-/********************************************************************/
-
-#endif /* __MCF523X_CCM_H__ */
+/*\r
+ * These files are taken from the MCF523X source code example package\r
+ * which is available on the Freescale website. Freescale explicitly \r
+ * grants the redistribution and modification of these source files.\r
+ * The complete licensing information is available in the file \r
+ * LICENSE_FREESCALE.TXT.\r
+ *\r
+ * File:       mcf523x_ccm.h\r
+ * Purpose:    Register and bit definitions for the MCF523X\r
+ *\r
+ * Notes:      \r
+ *     \r
+ */\r
+\r
+#ifndef __MCF523X_CCM_H__\r
+#define __MCF523X_CCM_H__\r
+\r
+/*********************************************************************\r
+*\r
+* Chip Configuration Module (CCM)\r
+*\r
+*********************************************************************/\r
+\r
+/* Register read/write macros */\r
+#define MCF_CCM_CCR     (*(vuint16*)(void*)(&__IPSBAR[0x110004]))\r
+#define MCF_CCM_LPCR    (*(vuint8 *)(void*)(&__IPSBAR[0x110007]))\r
+#define MCF_CCM_CIR     (*(vuint16*)(void*)(&__IPSBAR[0x11000A]))\r
+#define MCF_CCM_RCON    (*(vuint16*)(void*)(&__IPSBAR[0x110008]))\r
+\r
+/* Bit definitions and macros for MCF_CCM_CCR */\r
+#define MCF_CCM_CCR_BMT(x)        (((x)&0x0007)<<0)\r
+#define MCF_CCM_CCR_BME           (0x0008)\r
+#define MCF_CCM_CCR_SZEN          (0x0040)\r
+#define MCF_CCM_CCR_MODE(x)       (((x)&0x0007)<<8)\r
+\r
+/* Bit definitions and macros for MCF_CCM_LPCR */\r
+#define MCF_CCM_LPCR_STPMD(x)     (((x)&0x03)<<3)\r
+#define MCF_CCM_LPCR_LPMD(x)      (((x)&0x03)<<6)\r
+#define MCF_CCM_LPCR_LPMD_STOP    (0xC0)\r
+#define MCF_CCM_LPCR_LPMD_WAIT    (0x80)\r
+#define MCF_CCM_LPCR_LPMD_DOZE    (0x40)\r
+#define MCF_CCM_LPCR_LPMD_RUN     (0x00)\r
+\r
+/* Bit definitions and macros for MCF_CCM_CIR */\r
+#define MCF_CCM_CIR_PRN(x)        (((x)&0x003F)<<0)\r
+#define MCF_CCM_CIR_PIN(x)        (((x)&0x03FF)<<6)\r
+\r
+/* Bit definitions and macros for MCF_CCM_RCON */\r
+#define MCF_CCM_RCON_MODE         (0x0001)\r
+#define MCF_CCM_RCON_BOOTPS(x)    (((x)&0x0003)<<3)\r
+#define MCF_CCM_RCON_RLOAD        (0x0020)\r
+#define MCF_CCM_RCON_RCSC(x)      (((x)&0x0003)<<8)\r
+\r
+/********************************************************************/\r
+\r
+#endif /* __MCF523X_CCM_H__ */\r
index 27251c80a325569c5405c73a8e8957a4d1da5064..240cdf214c10cc3b16a933d019f028c132227a71 100644 (file)
-/*
- * These files are taken from the MCF523X source code example package
- * which is available on the Freescale website. Freescale explicitly 
- * grants the redistribution and modification of these source files.
- * The complete licensing information is available in the file 
- * LICENSE_FREESCALE.TXT.
- *
- * File:       mcf523x_cs.h
- * Purpose:    Register and bit definitions for the MCF523X
- *
- * Notes:      
- *     
- */
-
-#ifndef __MCF523X_CS_H__
-#define __MCF523X_CS_H__
-
-/*********************************************************************
-*
-* Chip Selects (CS)
-*
-*********************************************************************/
-
-/* Register read/write macros */
-#define MCF_CS_CSAR0      (*(vuint16*)(void*)(&__IPSBAR[0x000080]))
-#define MCF_CS_CSMR0      (*(vuint32*)(void*)(&__IPSBAR[0x000084]))
-#define MCF_CS_CSCR0      (*(vuint16*)(void*)(&__IPSBAR[0x00008A]))
-#define MCF_CS_CSAR1      (*(vuint16*)(void*)(&__IPSBAR[0x00008C]))
-#define MCF_CS_CSMR1      (*(vuint32*)(void*)(&__IPSBAR[0x000090]))
-#define MCF_CS_CSCR1      (*(vuint16*)(void*)(&__IPSBAR[0x000096]))
-#define MCF_CS_CSAR2      (*(vuint16*)(void*)(&__IPSBAR[0x000098]))
-#define MCF_CS_CSMR2      (*(vuint32*)(void*)(&__IPSBAR[0x00009C]))
-#define MCF_CS_CSCR2      (*(vuint16*)(void*)(&__IPSBAR[0x0000A2]))
-#define MCF_CS_CSAR3      (*(vuint16*)(void*)(&__IPSBAR[0x0000A4]))
-#define MCF_CS_CSMR3      (*(vuint32*)(void*)(&__IPSBAR[0x0000A8]))
-#define MCF_CS_CSCR3      (*(vuint16*)(void*)(&__IPSBAR[0x0000AE]))
-#define MCF_CS_CSAR4      (*(vuint16*)(void*)(&__IPSBAR[0x0000B0]))
-#define MCF_CS_CSMR4      (*(vuint32*)(void*)(&__IPSBAR[0x0000B4]))
-#define MCF_CS_CSCR4      (*(vuint16*)(void*)(&__IPSBAR[0x0000BA]))
-#define MCF_CS_CSAR5      (*(vuint16*)(void*)(&__IPSBAR[0x0000BC]))
-#define MCF_CS_CSMR5      (*(vuint32*)(void*)(&__IPSBAR[0x0000C0]))
-#define MCF_CS_CSCR5      (*(vuint16*)(void*)(&__IPSBAR[0x0000C6]))
-#define MCF_CS_CSAR6      (*(vuint16*)(void*)(&__IPSBAR[0x0000C8]))
-#define MCF_CS_CSMR6      (*(vuint32*)(void*)(&__IPSBAR[0x0000CC]))
-#define MCF_CS_CSCR6      (*(vuint16*)(void*)(&__IPSBAR[0x0000D2]))
-#define MCF_CS_CSAR7      (*(vuint16*)(void*)(&__IPSBAR[0x0000D4]))
-#define MCF_CS_CSMR7      (*(vuint32*)(void*)(&__IPSBAR[0x0000D8]))
-#define MCF_CS_CSCR7      (*(vuint16*)(void*)(&__IPSBAR[0x0000DE]))
-#define MCF_CS_CSAR(x)    (*(vuint16*)(void*)(&__IPSBAR[0x000080+((x)*0x00C)]))
-#define MCF_CS_CSMR(x)    (*(vuint32*)(void*)(&__IPSBAR[0x000084+((x)*0x00C)]))
-#define MCF_CS_CSCR(x)    (*(vuint16*)(void*)(&__IPSBAR[0x00008A+((x)*0x00C)]))
-
-/* Bit definitions and macros for MCF_CS_CSAR */
-#define MCF_CS_CSAR_BA(x)        ((uint16)(((x)&0xFFFF0000)>>16))
-
-/* Bit definitions and macros for MCF_CS_CSMR */
-#define MCF_CS_CSMR_V            (0x00000001)
-#define MCF_CS_CSMR_UD           (0x00000002)
-#define MCF_CS_CSMR_UC           (0x00000004)
-#define MCF_CS_CSMR_SD           (0x00000008)
-#define MCF_CS_CSMR_SC           (0x00000010)
-#define MCF_CS_CSMR_CI           (0x00000020)
-#define MCF_CS_CSMR_AM           (0x00000040)
-#define MCF_CS_CSMR_WP           (0x00000100)
-#define MCF_CS_CSMR_BAM(x)       (((x)&0x0000FFFF)<<16)
-#define MCF_CS_CSMR_BAM_4G       (0xFFFF0000)
-#define MCF_CS_CSMR_BAM_2G       (0x7FFF0000)
-#define MCF_CS_CSMR_BAM_1G       (0x3FFF0000)
-#define MCF_CS_CSMR_BAM_1024M    (0x3FFF0000)
-#define MCF_CS_CSMR_BAM_512M     (0x1FFF0000)
-#define MCF_CS_CSMR_BAM_256M     (0x0FFF0000)
-#define MCF_CS_CSMR_BAM_128M     (0x07FF0000)
-#define MCF_CS_CSMR_BAM_64M      (0x03FF0000)
-#define MCF_CS_CSMR_BAM_32M      (0x01FF0000)
-#define MCF_CS_CSMR_BAM_16M      (0x00FF0000)
-#define MCF_CS_CSMR_BAM_8M       (0x007F0000)
-#define MCF_CS_CSMR_BAM_4M       (0x003F0000)
-#define MCF_CS_CSMR_BAM_2M       (0x001F0000)
-#define MCF_CS_CSMR_BAM_1M       (0x000F0000)
-#define MCF_CS_CSMR_BAM_1024K    (0x000F0000)
-#define MCF_CS_CSMR_BAM_512K     (0x00070000)
-#define MCF_CS_CSMR_BAM_256K     (0x00030000)
-#define MCF_CS_CSMR_BAM_128K     (0x00010000)
-#define MCF_CS_CSMR_BAM_64K      (0x00000000)
-
-/* Bit definitions and macros for MCF_CS_CSCR */
-#define MCF_CS_CSCR_SWWS(x)      (((x)&0x0007)<<0)
-#define MCF_CS_CSCR_BSTW         (0x0008)
-#define MCF_CS_CSCR_BSTR         (0x0010)
-#define MCF_CS_CSCR_BEM          (0x0020)
-#define MCF_CS_CSCR_PS(x)        (((x)&0x0003)<<6)
-#define MCF_CS_CSCR_AA           (0x0100)
-#define MCF_CS_CSCR_IWS(x)       (((x)&0x000F)<<10)
-#define MCF_CS_CSCR_SRWS(x)      (((x)&0x0003)<<14)
-#define MCF_CS_CSCR_PS_8         (0x0040)
-#define MCF_CS_CSCR_PS_16        (0x0080)
-#define MCF_CS_CSCR_PS_32        (0x0000)
-
-/********************************************************************/
-
-#endif /* __MCF523X_CS_H__ */
+/*\r
+ * These files are taken from the MCF523X source code example package\r
+ * which is available on the Freescale website. Freescale explicitly \r
+ * grants the redistribution and modification of these source files.\r
+ * The complete licensing information is available in the file \r
+ * LICENSE_FREESCALE.TXT.\r
+ *\r
+ * File:       mcf523x_cs.h\r
+ * Purpose:    Register and bit definitions for the MCF523X\r
+ *\r
+ * Notes:      \r
+ *     \r
+ */\r
+\r
+#ifndef __MCF523X_CS_H__\r
+#define __MCF523X_CS_H__\r
+\r
+/*********************************************************************\r
+*\r
+* Chip Selects (CS)\r
+*\r
+*********************************************************************/\r
+\r
+/* Register read/write macros */\r
+#define MCF_CS_CSAR0      (*(vuint16*)(void*)(&__IPSBAR[0x000080]))\r
+#define MCF_CS_CSMR0      (*(vuint32*)(void*)(&__IPSBAR[0x000084]))\r
+#define MCF_CS_CSCR0      (*(vuint16*)(void*)(&__IPSBAR[0x00008A]))\r
+#define MCF_CS_CSAR1      (*(vuint16*)(void*)(&__IPSBAR[0x00008C]))\r
+#define MCF_CS_CSMR1      (*(vuint32*)(void*)(&__IPSBAR[0x000090]))\r
+#define MCF_CS_CSCR1      (*(vuint16*)(void*)(&__IPSBAR[0x000096]))\r
+#define MCF_CS_CSAR2      (*(vuint16*)(void*)(&__IPSBAR[0x000098]))\r
+#define MCF_CS_CSMR2      (*(vuint32*)(void*)(&__IPSBAR[0x00009C]))\r
+#define MCF_CS_CSCR2      (*(vuint16*)(void*)(&__IPSBAR[0x0000A2]))\r
+#define MCF_CS_CSAR3      (*(vuint16*)(void*)(&__IPSBAR[0x0000A4]))\r
+#define MCF_CS_CSMR3      (*(vuint32*)(void*)(&__IPSBAR[0x0000A8]))\r
+#define MCF_CS_CSCR3      (*(vuint16*)(void*)(&__IPSBAR[0x0000AE]))\r
+#define MCF_CS_CSAR4      (*(vuint16*)(void*)(&__IPSBAR[0x0000B0]))\r
+#define MCF_CS_CSMR4      (*(vuint32*)(void*)(&__IPSBAR[0x0000B4]))\r
+#define MCF_CS_CSCR4      (*(vuint16*)(void*)(&__IPSBAR[0x0000BA]))\r
+#define MCF_CS_CSAR5      (*(vuint16*)(void*)(&__IPSBAR[0x0000BC]))\r
+#define MCF_CS_CSMR5      (*(vuint32*)(void*)(&__IPSBAR[0x0000C0]))\r
+#define MCF_CS_CSCR5      (*(vuint16*)(void*)(&__IPSBAR[0x0000C6]))\r
+#define MCF_CS_CSAR6      (*(vuint16*)(void*)(&__IPSBAR[0x0000C8]))\r
+#define MCF_CS_CSMR6      (*(vuint32*)(void*)(&__IPSBAR[0x0000CC]))\r
+#define MCF_CS_CSCR6      (*(vuint16*)(void*)(&__IPSBAR[0x0000D2]))\r
+#define MCF_CS_CSAR7      (*(vuint16*)(void*)(&__IPSBAR[0x0000D4]))\r
+#define MCF_CS_CSMR7      (*(vuint32*)(void*)(&__IPSBAR[0x0000D8]))\r
+#define MCF_CS_CSCR7      (*(vuint16*)(void*)(&__IPSBAR[0x0000DE]))\r
+#define MCF_CS_CSAR(x)    (*(vuint16*)(void*)(&__IPSBAR[0x000080+((x)*0x00C)]))\r
+#define MCF_CS_CSMR(x)    (*(vuint32*)(void*)(&__IPSBAR[0x000084+((x)*0x00C)]))\r
+#define MCF_CS_CSCR(x)    (*(vuint16*)(void*)(&__IPSBAR[0x00008A+((x)*0x00C)]))\r
+\r
+/* Bit definitions and macros for MCF_CS_CSAR */\r
+#define MCF_CS_CSAR_BA(x)        ((uint16)(((x)&0xFFFF0000)>>16))\r
+\r
+/* Bit definitions and macros for MCF_CS_CSMR */\r
+#define MCF_CS_CSMR_V            (0x00000001)\r
+#define MCF_CS_CSMR_UD           (0x00000002)\r
+#define MCF_CS_CSMR_UC           (0x00000004)\r
+#define MCF_CS_CSMR_SD           (0x00000008)\r
+#define MCF_CS_CSMR_SC           (0x00000010)\r
+#define MCF_CS_CSMR_CI           (0x00000020)\r
+#define MCF_CS_CSMR_AM           (0x00000040)\r
+#define MCF_CS_CSMR_WP           (0x00000100)\r
+#define MCF_CS_CSMR_BAM(x)       (((x)&0x0000FFFF)<<16)\r
+#define MCF_CS_CSMR_BAM_4G       (0xFFFF0000)\r
+#define MCF_CS_CSMR_BAM_2G       (0x7FFF0000)\r
+#define MCF_CS_CSMR_BAM_1G       (0x3FFF0000)\r
+#define MCF_CS_CSMR_BAM_1024M    (0x3FFF0000)\r
+#define MCF_CS_CSMR_BAM_512M     (0x1FFF0000)\r
+#define MCF_CS_CSMR_BAM_256M     (0x0FFF0000)\r
+#define MCF_CS_CSMR_BAM_128M     (0x07FF0000)\r
+#define MCF_CS_CSMR_BAM_64M      (0x03FF0000)\r
+#define MCF_CS_CSMR_BAM_32M      (0x01FF0000)\r
+#define MCF_CS_CSMR_BAM_16M      (0x00FF0000)\r
+#define MCF_CS_CSMR_BAM_8M       (0x007F0000)\r
+#define MCF_CS_CSMR_BAM_4M       (0x003F0000)\r
+#define MCF_CS_CSMR_BAM_2M       (0x001F0000)\r
+#define MCF_CS_CSMR_BAM_1M       (0x000F0000)\r
+#define MCF_CS_CSMR_BAM_1024K    (0x000F0000)\r
+#define MCF_CS_CSMR_BAM_512K     (0x00070000)\r
+#define MCF_CS_CSMR_BAM_256K     (0x00030000)\r
+#define MCF_CS_CSMR_BAM_128K     (0x00010000)\r
+#define MCF_CS_CSMR_BAM_64K      (0x00000000)\r
+\r
+/* Bit definitions and macros for MCF_CS_CSCR */\r
+#define MCF_CS_CSCR_SWWS(x)      (((x)&0x0007)<<0)\r
+#define MCF_CS_CSCR_BSTW         (0x0008)\r
+#define MCF_CS_CSCR_BSTR         (0x0010)\r
+#define MCF_CS_CSCR_BEM          (0x0020)\r
+#define MCF_CS_CSCR_PS(x)        (((x)&0x0003)<<6)\r
+#define MCF_CS_CSCR_AA           (0x0100)\r
+#define MCF_CS_CSCR_IWS(x)       (((x)&0x000F)<<10)\r
+#define MCF_CS_CSCR_SRWS(x)      (((x)&0x0003)<<14)\r
+#define MCF_CS_CSCR_PS_8         (0x0040)\r
+#define MCF_CS_CSCR_PS_16        (0x0080)\r
+#define MCF_CS_CSCR_PS_32        (0x0000)\r
+\r
+/********************************************************************/\r
+\r
+#endif /* __MCF523X_CS_H__ */\r
index 5629ebfa47da6e4602da99098c27040a13202feb..9ee8d7c1c1e1c02ecf92e374f7147ae9e588f3e4 100644 (file)
@@ -1,92 +1,92 @@
-/*
- * These files are taken from the MCF523X source code example package
- * which is available on the Freescale website. Freescale explicitly 
- * grants the redistribution and modification of these source files.
- * The complete licensing information is available in the file 
- * LICENSE_FREESCALE.TXT.
- *
- * File:       mcf523x_eport.h
- * Purpose:    Register and bit definitions for the MCF523X
- *
- * Notes:      
- *     
- */
-
-#ifndef __MCF523X_EPORT_H__
-#define __MCF523X_EPORT_H__
-
-/*********************************************************************
-*
-* Edge Port Module (EPORT)
-*
-*********************************************************************/
-
-/* Register read/write macros */
-#define MCF_EPORT_EPPAR    (*(vuint16*)(void*)(&__IPSBAR[0x130000]))
-#define MCF_EPORT_EPDDR    (*(vuint8 *)(void*)(&__IPSBAR[0x130002]))
-#define MCF_EPORT_EPIER    (*(vuint8 *)(void*)(&__IPSBAR[0x130003]))
-#define MCF_EPORT_EPDR     (*(vuint8 *)(void*)(&__IPSBAR[0x130004]))
-#define MCF_EPORT_EPPDR    (*(vuint8 *)(void*)(&__IPSBAR[0x130005]))
-#define MCF_EPORT_EPFR     (*(vuint8 *)(void*)(&__IPSBAR[0x130006]))
-
-/* Bit definitions and macros for MCF_EPORT_EPPAR */
-#define MCF_EPORT_EPPAR_EPPA1(x)         (((x)&0x0003)<<2)
-#define MCF_EPORT_EPPAR_EPPA2(x)         (((x)&0x0003)<<4)
-#define MCF_EPORT_EPPAR_EPPA3(x)         (((x)&0x0003)<<6)
-#define MCF_EPORT_EPPAR_EPPA4(x)         (((x)&0x0003)<<8)
-#define MCF_EPORT_EPPAR_EPPA5(x)         (((x)&0x0003)<<10)
-#define MCF_EPORT_EPPAR_EPPA6(x)         (((x)&0x0003)<<12)
-#define MCF_EPORT_EPPAR_EPPA7(x)         (((x)&0x0003)<<14)
-#define MCF_EPORT_EPPAR_EPPAx_LEVEL      (0)
-#define MCF_EPORT_EPPAR_EPPAx_RISING     (1)
-#define MCF_EPORT_EPPAR_EPPAx_FALLING    (2)
-#define MCF_EPORT_EPPAR_EPPAx_BOTH       (3)
-
-/* Bit definitions and macros for MCF_EPORT_EPDDR */
-#define MCF_EPORT_EPDDR_EPDD1            (0x02)
-#define MCF_EPORT_EPDDR_EPDD2            (0x04)
-#define MCF_EPORT_EPDDR_EPDD3            (0x08)
-#define MCF_EPORT_EPDDR_EPDD4            (0x10)
-#define MCF_EPORT_EPDDR_EPDD5            (0x20)
-#define MCF_EPORT_EPDDR_EPDD6            (0x40)
-#define MCF_EPORT_EPDDR_EPDD7            (0x80)
-
-/* Bit definitions and macros for MCF_EPORT_EPIER */
-#define MCF_EPORT_EPIER_EPIE1            (0x02)
-#define MCF_EPORT_EPIER_EPIE2            (0x04)
-#define MCF_EPORT_EPIER_EPIE3            (0x08)
-#define MCF_EPORT_EPIER_EPIE4            (0x10)
-#define MCF_EPORT_EPIER_EPIE5            (0x20)
-#define MCF_EPORT_EPIER_EPIE6            (0x40)
-#define MCF_EPORT_EPIER_EPIE7            (0x80)
-
-/* Bit definitions and macros for MCF_EPORT_EPDR */
-#define MCF_EPORT_EPDR_EPD1              (0x02)
-#define MCF_EPORT_EPDR_EPD2              (0x04)
-#define MCF_EPORT_EPDR_EPD3              (0x08)
-#define MCF_EPORT_EPDR_EPD4              (0x10)
-#define MCF_EPORT_EPDR_EPD5              (0x20)
-#define MCF_EPORT_EPDR_EPD6              (0x40)
-#define MCF_EPORT_EPDR_EPD7              (0x80)
-
-/* Bit definitions and macros for MCF_EPORT_EPPDR */
-#define MCF_EPORT_EPPDR_EPPD1            (0x02)
-#define MCF_EPORT_EPPDR_EPPD2            (0x04)
-#define MCF_EPORT_EPPDR_EPPD3            (0x08)
-#define MCF_EPORT_EPPDR_EPPD4            (0x10)
-#define MCF_EPORT_EPPDR_EPPD5            (0x20)
-#define MCF_EPORT_EPPDR_EPPD6            (0x40)
-#define MCF_EPORT_EPPDR_EPPD7            (0x80)
-
-/* Bit definitions and macros for MCF_EPORT_EPFR */
-#define MCF_EPORT_EPFR_EPF1              (0x02)
-#define MCF_EPORT_EPFR_EPF2              (0x04)
-#define MCF_EPORT_EPFR_EPF3              (0x08)
-#define MCF_EPORT_EPFR_EPF4              (0x10)
-#define MCF_EPORT_EPFR_EPF5              (0x20)
-#define MCF_EPORT_EPFR_EPF6              (0x40)
-#define MCF_EPORT_EPFR_EPF7              (0x80)
-
-/********************************************************************/
-
-#endif /* __MCF523X_EPORT_H__ */
+/*\r
+ * These files are taken from the MCF523X source code example package\r
+ * which is available on the Freescale website. Freescale explicitly \r
+ * grants the redistribution and modification of these source files.\r
+ * The complete licensing information is available in the file \r
+ * LICENSE_FREESCALE.TXT.\r
+ *\r
+ * File:       mcf523x_eport.h\r
+ * Purpose:    Register and bit definitions for the MCF523X\r
+ *\r
+ * Notes:      \r
+ *     \r
+ */\r
+\r
+#ifndef __MCF523X_EPORT_H__\r
+#define __MCF523X_EPORT_H__\r
+\r
+/*********************************************************************\r
+*\r
+* Edge Port Module (EPORT)\r
+*\r
+*********************************************************************/\r
+\r
+/* Register read/write macros */\r
+#define MCF_EPORT_EPPAR    (*(vuint16*)(void*)(&__IPSBAR[0x130000]))\r
+#define MCF_EPORT_EPDDR    (*(vuint8 *)(void*)(&__IPSBAR[0x130002]))\r
+#define MCF_EPORT_EPIER    (*(vuint8 *)(void*)(&__IPSBAR[0x130003]))\r
+#define MCF_EPORT_EPDR     (*(vuint8 *)(void*)(&__IPSBAR[0x130004]))\r
+#define MCF_EPORT_EPPDR    (*(vuint8 *)(void*)(&__IPSBAR[0x130005]))\r
+#define MCF_EPORT_EPFR     (*(vuint8 *)(void*)(&__IPSBAR[0x130006]))\r
+\r
+/* Bit definitions and macros for MCF_EPORT_EPPAR */\r
+#define MCF_EPORT_EPPAR_EPPA1(x)         (((x)&0x0003)<<2)\r
+#define MCF_EPORT_EPPAR_EPPA2(x)         (((x)&0x0003)<<4)\r
+#define MCF_EPORT_EPPAR_EPPA3(x)         (((x)&0x0003)<<6)\r
+#define MCF_EPORT_EPPAR_EPPA4(x)         (((x)&0x0003)<<8)\r
+#define MCF_EPORT_EPPAR_EPPA5(x)         (((x)&0x0003)<<10)\r
+#define MCF_EPORT_EPPAR_EPPA6(x)         (((x)&0x0003)<<12)\r
+#define MCF_EPORT_EPPAR_EPPA7(x)         (((x)&0x0003)<<14)\r
+#define MCF_EPORT_EPPAR_EPPAx_LEVEL      (0)\r
+#define MCF_EPORT_EPPAR_EPPAx_RISING     (1)\r
+#define MCF_EPORT_EPPAR_EPPAx_FALLING    (2)\r
+#define MCF_EPORT_EPPAR_EPPAx_BOTH       (3)\r
+\r
+/* Bit definitions and macros for MCF_EPORT_EPDDR */\r
+#define MCF_EPORT_EPDDR_EPDD1            (0x02)\r
+#define MCF_EPORT_EPDDR_EPDD2            (0x04)\r
+#define MCF_EPORT_EPDDR_EPDD3            (0x08)\r
+#define MCF_EPORT_EPDDR_EPDD4            (0x10)\r
+#define MCF_EPORT_EPDDR_EPDD5            (0x20)\r
+#define MCF_EPORT_EPDDR_EPDD6            (0x40)\r
+#define MCF_EPORT_EPDDR_EPDD7            (0x80)\r
+\r
+/* Bit definitions and macros for MCF_EPORT_EPIER */\r
+#define MCF_EPORT_EPIER_EPIE1            (0x02)\r
+#define MCF_EPORT_EPIER_EPIE2            (0x04)\r
+#define MCF_EPORT_EPIER_EPIE3            (0x08)\r
+#define MCF_EPORT_EPIER_EPIE4            (0x10)\r
+#define MCF_EPORT_EPIER_EPIE5            (0x20)\r
+#define MCF_EPORT_EPIER_EPIE6            (0x40)\r
+#define MCF_EPORT_EPIER_EPIE7            (0x80)\r
+\r
+/* Bit definitions and macros for MCF_EPORT_EPDR */\r
+#define MCF_EPORT_EPDR_EPD1              (0x02)\r
+#define MCF_EPORT_EPDR_EPD2              (0x04)\r
+#define MCF_EPORT_EPDR_EPD3              (0x08)\r
+#define MCF_EPORT_EPDR_EPD4              (0x10)\r
+#define MCF_EPORT_EPDR_EPD5              (0x20)\r
+#define MCF_EPORT_EPDR_EPD6              (0x40)\r
+#define MCF_EPORT_EPDR_EPD7              (0x80)\r
+\r
+/* Bit definitions and macros for MCF_EPORT_EPPDR */\r
+#define MCF_EPORT_EPPDR_EPPD1            (0x02)\r
+#define MCF_EPORT_EPPDR_EPPD2            (0x04)\r
+#define MCF_EPORT_EPPDR_EPPD3            (0x08)\r
+#define MCF_EPORT_EPPDR_EPPD4            (0x10)\r
+#define MCF_EPORT_EPPDR_EPPD5            (0x20)\r
+#define MCF_EPORT_EPPDR_EPPD6            (0x40)\r
+#define MCF_EPORT_EPPDR_EPPD7            (0x80)\r
+\r
+/* Bit definitions and macros for MCF_EPORT_EPFR */\r
+#define MCF_EPORT_EPFR_EPF1              (0x02)\r
+#define MCF_EPORT_EPFR_EPF2              (0x04)\r
+#define MCF_EPORT_EPFR_EPF3              (0x08)\r
+#define MCF_EPORT_EPFR_EPF4              (0x10)\r
+#define MCF_EPORT_EPFR_EPF5              (0x20)\r
+#define MCF_EPORT_EPFR_EPF6              (0x40)\r
+#define MCF_EPORT_EPFR_EPF7              (0x80)\r
+\r
+/********************************************************************/\r
+\r
+#endif /* __MCF523X_EPORT_H__ */\r
index 91075acf887ff54525d998177f9e6b273bb4c725..5a0d9ca749491507ce4d991fefd7a2f7f34f4329 100644 (file)
-/*
- * These files are taken from the MCF523X source code example package
- * which is available on the Freescale website. Freescale explicitly 
- * grants the redistribution and modification of these source files.
- * The complete licensing information is available in the file 
- * LICENSE_FREESCALE.TXT.
- *
- * File:       mcf523x_etpu.h
- * Purpose:    Register and bit definitions for the MCF523X
- *
- * Notes:      
- *     
- */
-
-#ifndef __MCF523X_ETPU_H__
-#define __MCF523X_ETPU_H__
-
-/*********************************************************************
-*
-* enhanced Time Processor Unit (ETPU)
-*
-*********************************************************************/
-
-/* Register read/write macros */
-#define MCF_ETPU_EMCR          (*(vuint32*)(void*)(&__IPSBAR[0x1D0000]))
-#define MCF_ETPU_ECDCR         (*(vuint32*)(void*)(&__IPSBAR[0x1D0004]))
-#define MCF_ETPU_EMISCCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D000C]))
-#define MCF_ETPU_ESCMODR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0010]))
-#define MCF_ETPU_EECR          (*(vuint32*)(void*)(&__IPSBAR[0x1D0014]))
-#define MCF_ETPU_ETBCR         (*(vuint32*)(void*)(&__IPSBAR[0x1D0020]))
-#define MCF_ETPU_ETB1R         (*(vuint32*)(void*)(&__IPSBAR[0x1D0024]))
-#define MCF_ETPU_ETB2R         (*(vuint32*)(void*)(&__IPSBAR[0x1D0028]))
-#define MCF_ETPU_EREDCR        (*(vuint32*)(void*)(&__IPSBAR[0x1D002C]))
-#define MCF_ETPU_ECISR         (*(vuint32*)(void*)(&__IPSBAR[0x1D0200]))
-#define MCF_ETPU_ECDTRSR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0210]))
-#define MCF_ETPU_ECIOSR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0220]))
-#define MCF_ETPU_ECDTROSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D0230]))
-#define MCF_ETPU_ECIER         (*(vuint32*)(void*)(&__IPSBAR[0x1D0240]))
-#define MCF_ETPU_ECDTRER       (*(vuint32*)(void*)(&__IPSBAR[0x1D0250]))
-#define MCF_ETPU_ECPSSR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0280]))
-#define MCF_ETPU_ECSSR         (*(vuint32*)(void*)(&__IPSBAR[0x1D0290]))
-#define MCF_ETPU_EC0SCR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0404]))
-#define MCF_ETPU_EC1SCR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0414]))
-#define MCF_ETPU_EC2SCR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0424]))
-#define MCF_ETPU_EC3SCR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0434]))
-#define MCF_ETPU_EC4SCR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0444]))
-#define MCF_ETPU_EC5SCR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0454]))
-#define MCF_ETPU_EC6SCR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0464]))
-#define MCF_ETPU_EC7SCR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0474]))
-#define MCF_ETPU_EC8SCR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0484]))
-#define MCF_ETPU_EC9SCR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0494]))
-#define MCF_ETPU_EC10SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D04A4]))
-#define MCF_ETPU_EC11SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D04B4]))
-#define MCF_ETPU_EC12SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D04C4]))
-#define MCF_ETPU_EC13SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D04D4]))
-#define MCF_ETPU_EC14SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D04E4]))
-#define MCF_ETPU_EC15SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D04F4]))
-#define MCF_ETPU_EC16SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0504]))
-#define MCF_ETPU_EC17SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0514]))
-#define MCF_ETPU_EC18SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0524]))
-#define MCF_ETPU_EC19SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0534]))
-#define MCF_ETPU_EC20SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0544]))
-#define MCF_ETPU_EC21SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0554]))
-#define MCF_ETPU_EC22SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0564]))
-#define MCF_ETPU_EC23SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0574]))
-#define MCF_ETPU_EC24SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0584]))
-#define MCF_ETPU_EC25SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0594]))
-#define MCF_ETPU_EC26SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D05A4]))
-#define MCF_ETPU_EC27SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D05B4]))
-#define MCF_ETPU_EC28SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D05C4]))
-#define MCF_ETPU_EC29SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D05D4]))
-#define MCF_ETPU_EC30SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D05E4]))
-#define MCF_ETPU_EC31SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D05F4]))
-#define MCF_ETPU_ECnSCR(x)     (*(vuint32*)(void*)(&__IPSBAR[0x1D0404+((x)*0x010)]))
-#define MCF_ETPU_EC0CR         (*(vuint32*)(void*)(&__IPSBAR[0x1D0400]))
-#define MCF_ETPU_EC1CR         (*(vuint32*)(void*)(&__IPSBAR[0x1D0410]))
-#define MCF_ETPU_EC2CR         (*(vuint32*)(void*)(&__IPSBAR[0x1D0420]))
-#define MCF_ETPU_EC3CR         (*(vuint32*)(void*)(&__IPSBAR[0x1D0430]))
-#define MCF_ETPU_EC4CR         (*(vuint32*)(void*)(&__IPSBAR[0x1D0440]))
-#define MCF_ETPU_EC5CR         (*(vuint32*)(void*)(&__IPSBAR[0x1D0450]))
-#define MCF_ETPU_EC6CR         (*(vuint32*)(void*)(&__IPSBAR[0x1D0460]))
-#define MCF_ETPU_EC7CR         (*(vuint32*)(void*)(&__IPSBAR[0x1D0470]))
-#define MCF_ETPU_EC8CR         (*(vuint32*)(void*)(&__IPSBAR[0x1D0480]))
-#define MCF_ETPU_EC9CR         (*(vuint32*)(void*)(&__IPSBAR[0x1D0490]))
-#define MCF_ETPU_EC10CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D04A0]))
-#define MCF_ETPU_EC11CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D04B0]))
-#define MCF_ETPU_EC12CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D04C0]))
-#define MCF_ETPU_EC13CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D04D0]))
-#define MCF_ETPU_EC14CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D04E0]))
-#define MCF_ETPU_EC15CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D04F0]))
-#define MCF_ETPU_EC16CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0500]))
-#define MCF_ETPU_EC17CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0510]))
-#define MCF_ETPU_EC18CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0520]))
-#define MCF_ETPU_EC19CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0530]))
-#define MCF_ETPU_EC20CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0540]))
-#define MCF_ETPU_EC21CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0550]))
-#define MCF_ETPU_EC22CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0560]))
-#define MCF_ETPU_EC23CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0570]))
-#define MCF_ETPU_EC24CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0580]))
-#define MCF_ETPU_EC25CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0590]))
-#define MCF_ETPU_EC26CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D05A0]))
-#define MCF_ETPU_EC27CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D05B0]))
-#define MCF_ETPU_EC28CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D05C0]))
-#define MCF_ETPU_EC29CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D05D0]))
-#define MCF_ETPU_EC30CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D05E0]))
-#define MCF_ETPU_EC31CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D05F0]))
-#define MCF_ETPU_ECnCR(x)      (*(vuint32*)(void*)(&__IPSBAR[0x1D0400+((x)*0x010)]))
-#define MCF_ETPU_EC0HSSR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0408]))
-#define MCF_ETPU_EC1HSSR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0418]))
-#define MCF_ETPU_EC2HSSR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0428]))
-#define MCF_ETPU_EC3HSSR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0438]))
-#define MCF_ETPU_EC4HSSR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0448]))
-#define MCF_ETPU_EC5HSSR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0458]))
-#define MCF_ETPU_EC6HSSR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0468]))
-#define MCF_ETPU_EC7HSSR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0478]))
-#define MCF_ETPU_EC8HSSR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0488]))
-#define MCF_ETPU_EC9HSSR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0498]))
-#define MCF_ETPU_EC10HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D04A8]))
-#define MCF_ETPU_EC11HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D04B8]))
-#define MCF_ETPU_EC12HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D04C8]))
-#define MCF_ETPU_EC13HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D04D8]))
-#define MCF_ETPU_EC14HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D04E8]))
-#define MCF_ETPU_EC15HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D04F8]))
-#define MCF_ETPU_EC16HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D0508]))
-#define MCF_ETPU_EC17HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D0518]))
-#define MCF_ETPU_EC18HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D0528]))
-#define MCF_ETPU_EC19HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D0538]))
-#define MCF_ETPU_EC20HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D0548]))
-#define MCF_ETPU_EC21HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D0558]))
-#define MCF_ETPU_EC22HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D0568]))
-#define MCF_ETPU_EC23HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D0578]))
-#define MCF_ETPU_EC24HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D0588]))
-#define MCF_ETPU_EC25HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D0598]))
-#define MCF_ETPU_EC26HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D05A8]))
-#define MCF_ETPU_EC27HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D05B8]))
-#define MCF_ETPU_EC28HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D05C8]))
-#define MCF_ETPU_EC29HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D05D8]))
-#define MCF_ETPU_EC30HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D05E8]))
-#define MCF_ETPU_EC31HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D05F8]))
-#define MCF_ETPU_ECnHSSR(x)    (*(vuint32*)(void*)(&__IPSBAR[0x1D0408+((x)*0x010)]))
-
-/* Bit definitions and macros for MCF_ETPU_EMCR */
-#define MCF_ETPU_EMCR_GTBE               (0x00000001)
-#define MCF_ETPU_EMCR_VIS                (0x00000040)
-#define MCF_ETPU_EMCR_SCMMISEN           (0x00000200)
-#define MCF_ETPU_EMCR_SCMMISF            (0x00000400)
-#define MCF_ETPU_EMCR_SCMSIZE(x)         (((x)&0x0000001F)<<16)
-#define MCF_ETPU_EMCR_ILF2               (0x01000000)
-#define MCF_ETPU_EMCR_ILF1               (0x02000000)
-#define MCF_ETPU_EMCR_MGE2               (0x04000000)
-#define MCF_ETPU_EMCR_MGE1               (0x08000000)
-#define MCF_ETPU_EMCR_GEC                (0x80000000)
-
-/* Bit definitions and macros for MCF_ETPU_ECDCR */
-#define MCF_ETPU_ECDCR_PARM1(x)          (((x)&0x0000007F)<<0)
-#define MCF_ETPU_ECDCR_WR                (0x00000080)
-#define MCF_ETPU_ECDCR_PARM0(x)          (((x)&0x0000007F)<<8)
-#define MCF_ETPU_ECDCR_PWIDTH            (0x00008000)
-#define MCF_ETPU_ECDCR_PBASE(x)          (((x)&0x000003FF)<<16)
-#define MCF_ETPU_ECDCR_CTBASE(x)         (((x)&0x0000001F)<<26)
-#define MCF_ETPU_ECDCR_STS               (0x80000000)
-
-/* Bit definitions and macros for MCF_ETPU_EECR */
-#define MCF_ETPU_EECR_ETB(x)             (((x)&0x0000001F)<<0)
-#define MCF_ETPU_EECR_CDFC(x)            (((x)&0x00000003)<<14)
-#define MCF_ETPU_EECR_FPSK(x)            (((x)&0x00000007)<<16)
-#define MCF_ETPU_EECR_HLTF               (0x00800000)
-#define MCF_ETPU_EECR_STF                (0x10000000)
-#define MCF_ETPU_EECR_MDIS               (0x40000000)
-#define MCF_ETPU_EECR_FEND               (0x80000000)
-
-/* Bit definitions and macros for MCF_ETPU_ETBCR */
-#define MCF_ETPU_ETBCR_TCR1P(x)          (((x)&0x000000FF)<<0)
-#define MCF_ETPU_ETBCR_TCR1CTL(x)        (((x)&0x00000003)<<14)
-#define MCF_ETPU_ETBCR_TCR2P(x)          (((x)&0x0000003F)<<16)
-#define MCF_ETPU_ETBCR_AM                (0x02000000)
-#define MCF_ETPU_ETBCR_TCRCF(x)          (((x)&0x00000003)<<27)
-#define MCF_ETPU_ETBCR_TCR2CTL(x)        (((x)&0x00000007)<<29)
-
-/* Bit definitions and macros for MCF_ETPU_ETB1R */
-#define MCF_ETPU_ETB1R_TCR1(x)           (((x)&0x00FFFFFF)<<0)
-
-/* Bit definitions and macros for MCF_ETPU_ETB2R */
-#define MCF_ETPU_ETB2R_TCR2(x)           (((x)&0x00FFFFFF)<<0)
-
-/* Bit definitions and macros for MCF_ETPU_EREDCR */
-#define MCF_ETPU_EREDCR_SRV2(x)          (((x)&0x0000000F)<<0)
-#define MCF_ETPU_EREDCR_SERVER_ID2(x)    (((x)&0x0000000F)<<8)
-#define MCF_ETPU_EREDCR_RSC2             (0x00004000)
-#define MCF_ETPU_EREDCR_REN2             (0x00008000)
-#define MCF_ETPU_EREDCR_SRV1(x)          (((x)&0x0000000F)<<16)
-#define MCF_ETPU_EREDCR_SERVER_ID1(x)    (((x)&0x0000000F)<<24)
-#define MCF_ETPU_EREDCR_RSC1             (0x40000000)
-#define MCF_ETPU_EREDCR_REN1             (0x80000000)
-
-/* Bit definitions and macros for MCF_ETPU_ECISR */
-#define MCF_ETPU_ECISR_CIS0              (0x00000001)
-#define MCF_ETPU_ECISR_CIS1              (0x00000002)
-#define MCF_ETPU_ECISR_CIS2              (0x00000004)
-#define MCF_ETPU_ECISR_CIS3              (0x00000008)
-#define MCF_ETPU_ECISR_CIS4              (0x00000010)
-#define MCF_ETPU_ECISR_CIS5              (0x00000020)
-#define MCF_ETPU_ECISR_CIS6              (0x00000040)
-#define MCF_ETPU_ECISR_CIS7              (0x00000080)
-#define MCF_ETPU_ECISR_CIS8              (0x00000100)
-#define MCF_ETPU_ECISR_CIS9              (0x00000200)
-#define MCF_ETPU_ECISR_CIS10             (0x00000400)
-#define MCF_ETPU_ECISR_CIS11             (0x00000800)
-#define MCF_ETPU_ECISR_CIS12             (0x00001000)
-#define MCF_ETPU_ECISR_CIS13             (0x00002000)
-#define MCF_ETPU_ECISR_CIS14             (0x00004000)
-#define MCF_ETPU_ECISR_CIS15             (0x00008000)
-#define MCF_ETPU_ECISR_CIS16             (0x00010000)
-#define MCF_ETPU_ECISR_CIS17             (0x00020000)
-#define MCF_ETPU_ECISR_CIS18             (0x00040000)
-#define MCF_ETPU_ECISR_CIS19             (0x00080000)
-#define MCF_ETPU_ECISR_CIS20             (0x00100000)
-#define MCF_ETPU_ECISR_CIS21             (0x00200000)
-#define MCF_ETPU_ECISR_CIS22             (0x00400000)
-#define MCF_ETPU_ECISR_CIS23             (0x00800000)
-#define MCF_ETPU_ECISR_CIS24             (0x01000000)
-#define MCF_ETPU_ECISR_CIS25             (0x02000000)
-#define MCF_ETPU_ECISR_CIS26             (0x04000000)
-#define MCF_ETPU_ECISR_CIS27             (0x08000000)
-#define MCF_ETPU_ECISR_CIS28             (0x10000000)
-#define MCF_ETPU_ECISR_CIS29             (0x20000000)
-#define MCF_ETPU_ECISR_CIS30             (0x40000000)
-#define MCF_ETPU_ECISR_CIS31             (0x80000000)
-
-/* Bit definitions and macros for MCF_ETPU_ECDTRSR */
-#define MCF_ETPU_ECDTRSR_DTRS0           (0x00000001)
-#define MCF_ETPU_ECDTRSR_DTRS1           (0x00000002)
-#define MCF_ETPU_ECDTRSR_DTRS2           (0x00000004)
-#define MCF_ETPU_ECDTRSR_DTRS3           (0x00000008)
-#define MCF_ETPU_ECDTRSR_DTRS4           (0x00000010)
-#define MCF_ETPU_ECDTRSR_DTRS5           (0x00000020)
-#define MCF_ETPU_ECDTRSR_DTRS6           (0x00000040)
-#define MCF_ETPU_ECDTRSR_DTRS7           (0x00000080)
-#define MCF_ETPU_ECDTRSR_DTRS8           (0x00000100)
-#define MCF_ETPU_ECDTRSR_DTRS9           (0x00000200)
-#define MCF_ETPU_ECDTRSR_DTRS10          (0x00000400)
-#define MCF_ETPU_ECDTRSR_DTRS11          (0x00000800)
-#define MCF_ETPU_ECDTRSR_DTRS12          (0x00001000)
-#define MCF_ETPU_ECDTRSR_DTRS13          (0x00002000)
-#define MCF_ETPU_ECDTRSR_DTRS14          (0x00004000)
-#define MCF_ETPU_ECDTRSR_DTRS15          (0x00008000)
-#define MCF_ETPU_ECDTRSR_DTRS16          (0x00010000)
-#define MCF_ETPU_ECDTRSR_DTRS17          (0x00020000)
-#define MCF_ETPU_ECDTRSR_DTRS18          (0x00040000)
-#define MCF_ETPU_ECDTRSR_DTRS19          (0x00080000)
-#define MCF_ETPU_ECDTRSR_DTRS20          (0x00100000)
-#define MCF_ETPU_ECDTRSR_DTRS21          (0x00200000)
-#define MCF_ETPU_ECDTRSR_DTRS22          (0x00400000)
-#define MCF_ETPU_ECDTRSR_DTRS23          (0x00800000)
-#define MCF_ETPU_ECDTRSR_DTRS24          (0x01000000)
-#define MCF_ETPU_ECDTRSR_DTRS25          (0x02000000)
-#define MCF_ETPU_ECDTRSR_DTRS26          (0x04000000)
-#define MCF_ETPU_ECDTRSR_DTRS27          (0x08000000)
-#define MCF_ETPU_ECDTRSR_DTRS28          (0x10000000)
-#define MCF_ETPU_ECDTRSR_DTRS29          (0x20000000)
-#define MCF_ETPU_ECDTRSR_DTRS30          (0x40000000)
-#define MCF_ETPU_ECDTRSR_DTRS31          (0x80000000)
-
-/* Bit definitions and macros for MCF_ETPU_ECIOSR */
-#define MCF_ETPU_ECIOSR_CIOS0            (0x00000001)
-#define MCF_ETPU_ECIOSR_CIOS1            (0x00000002)
-#define MCF_ETPU_ECIOSR_CIOS2            (0x00000004)
-#define MCF_ETPU_ECIOSR_CIOS3            (0x00000008)
-#define MCF_ETPU_ECIOSR_CIOS4            (0x00000010)
-#define MCF_ETPU_ECIOSR_CIOS5            (0x00000020)
-#define MCF_ETPU_ECIOSR_CIOS6            (0x00000040)
-#define MCF_ETPU_ECIOSR_CIOS7            (0x00000080)
-#define MCF_ETPU_ECIOSR_CIOS8            (0x00000100)
-#define MCF_ETPU_ECIOSR_CIOS9            (0x00000200)
-#define MCF_ETPU_ECIOSR_CIOS10           (0x00000400)
-#define MCF_ETPU_ECIOSR_CIOS11           (0x00000800)
-#define MCF_ETPU_ECIOSR_CIOS12           (0x00001000)
-#define MCF_ETPU_ECIOSR_CIOS13           (0x00002000)
-#define MCF_ETPU_ECIOSR_CIOS14           (0x00004000)
-#define MCF_ETPU_ECIOSR_CIOS15           (0x00008000)
-#define MCF_ETPU_ECIOSR_CIOS16           (0x00010000)
-#define MCF_ETPU_ECIOSR_CIOS17           (0x00020000)
-#define MCF_ETPU_ECIOSR_CIOS18           (0x00040000)
-#define MCF_ETPU_ECIOSR_CIOS19           (0x00080000)
-#define MCF_ETPU_ECIOSR_CIOS20           (0x00100000)
-#define MCF_ETPU_ECIOSR_CIOS21           (0x00200000)
-#define MCF_ETPU_ECIOSR_CIOS22           (0x00400000)
-#define MCF_ETPU_ECIOSR_CIOS23           (0x00800000)
-#define MCF_ETPU_ECIOSR_CIOS24           (0x01000000)
-#define MCF_ETPU_ECIOSR_CIOS25           (0x02000000)
-#define MCF_ETPU_ECIOSR_CIOS26           (0x04000000)
-#define MCF_ETPU_ECIOSR_CIOS27           (0x08000000)
-#define MCF_ETPU_ECIOSR_CIOS28           (0x10000000)
-#define MCF_ETPU_ECIOSR_CIOS29           (0x20000000)
-#define MCF_ETPU_ECIOSR_CIOS30           (0x40000000)
-#define MCF_ETPU_ECIOSR_CIOS31           (0x80000000)
-
-/* Bit definitions and macros for MCF_ETPU_ECDTROSR */
-#define MCF_ETPU_ECDTROSR_DTROS0         (0x00000001)
-#define MCF_ETPU_ECDTROSR_DTROS1         (0x00000002)
-#define MCF_ETPU_ECDTROSR_DTROS2         (0x00000004)
-#define MCF_ETPU_ECDTROSR_DTROS3         (0x00000008)
-#define MCF_ETPU_ECDTROSR_DTROS4         (0x00000010)
-#define MCF_ETPU_ECDTROSR_DTROS5         (0x00000020)
-#define MCF_ETPU_ECDTROSR_DTROS6         (0x00000040)
-#define MCF_ETPU_ECDTROSR_DTROS7         (0x00000080)
-#define MCF_ETPU_ECDTROSR_DTROS8         (0x00000100)
-#define MCF_ETPU_ECDTROSR_DTROS9         (0x00000200)
-#define MCF_ETPU_ECDTROSR_DTROS10        (0x00000400)
-#define MCF_ETPU_ECDTROSR_DTROS11        (0x00000800)
-#define MCF_ETPU_ECDTROSR_DTROS12        (0x00001000)
-#define MCF_ETPU_ECDTROSR_DTROS13        (0x00002000)
-#define MCF_ETPU_ECDTROSR_DTROS14        (0x00004000)
-#define MCF_ETPU_ECDTROSR_DTROS15        (0x00008000)
-#define MCF_ETPU_ECDTROSR_DTROS16        (0x00010000)
-#define MCF_ETPU_ECDTROSR_DTROS17        (0x00020000)
-#define MCF_ETPU_ECDTROSR_DTROS18        (0x00040000)
-#define MCF_ETPU_ECDTROSR_DTROS19        (0x00080000)
-#define MCF_ETPU_ECDTROSR_DTROS20        (0x00100000)
-#define MCF_ETPU_ECDTROSR_DTROS21        (0x00200000)
-#define MCF_ETPU_ECDTROSR_DTROS22        (0x00400000)
-#define MCF_ETPU_ECDTROSR_DTROS23        (0x00800000)
-#define MCF_ETPU_ECDTROSR_DTROS24        (0x01000000)
-#define MCF_ETPU_ECDTROSR_DTROS25        (0x02000000)
-#define MCF_ETPU_ECDTROSR_DTROS26        (0x04000000)
-#define MCF_ETPU_ECDTROSR_DTROS27        (0x08000000)
-#define MCF_ETPU_ECDTROSR_DTROS28        (0x10000000)
-#define MCF_ETPU_ECDTROSR_DTROS29        (0x20000000)
-#define MCF_ETPU_ECDTROSR_DTROS30        (0x40000000)
-#define MCF_ETPU_ECDTROSR_DTROS31        (0x80000000)
-
-/* Bit definitions and macros for MCF_ETPU_ECIER */
-#define MCF_ETPU_ECIER_CIE0              (0x00000001)
-#define MCF_ETPU_ECIER_CIE1              (0x00000002)
-#define MCF_ETPU_ECIER_CIE2              (0x00000004)
-#define MCF_ETPU_ECIER_CIE3              (0x00000008)
-#define MCF_ETPU_ECIER_CIE4              (0x00000010)
-#define MCF_ETPU_ECIER_CIE5              (0x00000020)
-#define MCF_ETPU_ECIER_CIE6              (0x00000040)
-#define MCF_ETPU_ECIER_CIE7              (0x00000080)
-#define MCF_ETPU_ECIER_CIE8              (0x00000100)
-#define MCF_ETPU_ECIER_CIE9              (0x00000200)
-#define MCF_ETPU_ECIER_CIE10             (0x00000400)
-#define MCF_ETPU_ECIER_CIE11             (0x00000800)
-#define MCF_ETPU_ECIER_CIE12             (0x00001000)
-#define MCF_ETPU_ECIER_CIE13             (0x00002000)
-#define MCF_ETPU_ECIER_CIE14             (0x00004000)
-#define MCF_ETPU_ECIER_CIE15             (0x00008000)
-#define MCF_ETPU_ECIER_CIE16             (0x00010000)
-#define MCF_ETPU_ECIER_CIE17             (0x00020000)
-#define MCF_ETPU_ECIER_CIE18             (0x00040000)
-#define MCF_ETPU_ECIER_CIE19             (0x00080000)
-#define MCF_ETPU_ECIER_CIE20             (0x00100000)
-#define MCF_ETPU_ECIER_CIE21             (0x00200000)
-#define MCF_ETPU_ECIER_CIE22             (0x00400000)
-#define MCF_ETPU_ECIER_CIE23             (0x00800000)
-#define MCF_ETPU_ECIER_CIE24             (0x01000000)
-#define MCF_ETPU_ECIER_CIE25             (0x02000000)
-#define MCF_ETPU_ECIER_CIE26             (0x04000000)
-#define MCF_ETPU_ECIER_CIE27             (0x08000000)
-#define MCF_ETPU_ECIER_CIE28             (0x10000000)
-#define MCF_ETPU_ECIER_CIE29             (0x20000000)
-#define MCF_ETPU_ECIER_CIE30             (0x40000000)
-#define MCF_ETPU_ECIER_CIE31             (0x80000000)
-
-/* Bit definitions and macros for MCF_ETPU_ECDTRER */
-#define MCF_ETPU_ECDTRER_DTRE0           (0x00000001)
-#define MCF_ETPU_ECDTRER_DTRE1           (0x00000002)
-#define MCF_ETPU_ECDTRER_DTRE2           (0x00000004)
-#define MCF_ETPU_ECDTRER_DTRE3           (0x00000008)
-#define MCF_ETPU_ECDTRER_DTRE4           (0x00000010)
-#define MCF_ETPU_ECDTRER_DTRE5           (0x00000020)
-#define MCF_ETPU_ECDTRER_DTRE6           (0x00000040)
-#define MCF_ETPU_ECDTRER_DTRE7           (0x00000080)
-#define MCF_ETPU_ECDTRER_DTRE8           (0x00000100)
-#define MCF_ETPU_ECDTRER_DTRE9           (0x00000200)
-#define MCF_ETPU_ECDTRER_DTRE10          (0x00000400)
-#define MCF_ETPU_ECDTRER_DTRE11          (0x00000800)
-#define MCF_ETPU_ECDTRER_DTRE12          (0x00001000)
-#define MCF_ETPU_ECDTRER_DTRE13          (0x00002000)
-#define MCF_ETPU_ECDTRER_DTRE14          (0x00004000)
-#define MCF_ETPU_ECDTRER_DTRE15          (0x00008000)
-#define MCF_ETPU_ECDTRER_DTRE16          (0x00010000)
-#define MCF_ETPU_ECDTRER_DTRE17          (0x00020000)
-#define MCF_ETPU_ECDTRER_DTRE18          (0x00040000)
-#define MCF_ETPU_ECDTRER_DTRE19          (0x00080000)
-#define MCF_ETPU_ECDTRER_DTRE20          (0x00100000)
-#define MCF_ETPU_ECDTRER_DTRE21          (0x00200000)
-#define MCF_ETPU_ECDTRER_DTRE22          (0x00400000)
-#define MCF_ETPU_ECDTRER_DTRE23          (0x00800000)
-#define MCF_ETPU_ECDTRER_DTRE24          (0x01000000)
-#define MCF_ETPU_ECDTRER_DTRE25          (0x02000000)
-#define MCF_ETPU_ECDTRER_DTRE26          (0x04000000)
-#define MCF_ETPU_ECDTRER_DTRE27          (0x08000000)
-#define MCF_ETPU_ECDTRER_DTRE28          (0x10000000)
-#define MCF_ETPU_ECDTRER_DTRE29          (0x20000000)
-#define MCF_ETPU_ECDTRER_DTRE30          (0x40000000)
-#define MCF_ETPU_ECDTRER_DTRE31          (0x80000000)
-
-/* Bit definitions and macros for MCF_ETPU_ECPSSR */
-#define MCF_ETPU_ECPSSR_SR0              (0x00000001)
-#define MCF_ETPU_ECPSSR_SR1              (0x00000002)
-#define MCF_ETPU_ECPSSR_SR2              (0x00000004)
-#define MCF_ETPU_ECPSSR_SR3              (0x00000008)
-#define MCF_ETPU_ECPSSR_SR4              (0x00000010)
-#define MCF_ETPU_ECPSSR_SR5              (0x00000020)
-#define MCF_ETPU_ECPSSR_SR6              (0x00000040)
-#define MCF_ETPU_ECPSSR_SR7              (0x00000080)
-#define MCF_ETPU_ECPSSR_SR8              (0x00000100)
-#define MCF_ETPU_ECPSSR_SR9              (0x00000200)
-#define MCF_ETPU_ECPSSR_SR10             (0x00000400)
-#define MCF_ETPU_ECPSSR_SR11             (0x00000800)
-#define MCF_ETPU_ECPSSR_SR12             (0x00001000)
-#define MCF_ETPU_ECPSSR_SR13             (0x00002000)
-#define MCF_ETPU_ECPSSR_SR14             (0x00004000)
-#define MCF_ETPU_ECPSSR_SR15             (0x00008000)
-#define MCF_ETPU_ECPSSR_SR16             (0x00010000)
-#define MCF_ETPU_ECPSSR_SR17             (0x00020000)
-#define MCF_ETPU_ECPSSR_SR18             (0x00040000)
-#define MCF_ETPU_ECPSSR_SR19             (0x00080000)
-#define MCF_ETPU_ECPSSR_SR20             (0x00100000)
-#define MCF_ETPU_ECPSSR_SR21             (0x00200000)
-#define MCF_ETPU_ECPSSR_SR22             (0x00400000)
-#define MCF_ETPU_ECPSSR_SR23             (0x00800000)
-#define MCF_ETPU_ECPSSR_SR24             (0x01000000)
-#define MCF_ETPU_ECPSSR_SR25             (0x02000000)
-#define MCF_ETPU_ECPSSR_SR26             (0x04000000)
-#define MCF_ETPU_ECPSSR_SR27             (0x08000000)
-#define MCF_ETPU_ECPSSR_SR28             (0x10000000)
-#define MCF_ETPU_ECPSSR_SR29             (0x20000000)
-#define MCF_ETPU_ECPSSR_SR30             (0x40000000)
-#define MCF_ETPU_ECPSSR_SR31             (0x80000000)
-
-/* Bit definitions and macros for MCF_ETPU_ECSSR */
-#define MCF_ETPU_ECSSR_SS0               (0x00000001)
-#define MCF_ETPU_ECSSR_SS1               (0x00000002)
-#define MCF_ETPU_ECSSR_SS2               (0x00000004)
-#define MCF_ETPU_ECSSR_SS3               (0x00000008)
-#define MCF_ETPU_ECSSR_SS4               (0x00000010)
-#define MCF_ETPU_ECSSR_SS5               (0x00000020)
-#define MCF_ETPU_ECSSR_SS6               (0x00000040)
-#define MCF_ETPU_ECSSR_SS7               (0x00000080)
-#define MCF_ETPU_ECSSR_SS8               (0x00000100)
-#define MCF_ETPU_ECSSR_SS9               (0x00000200)
-#define MCF_ETPU_ECSSR_SS10              (0x00000400)
-#define MCF_ETPU_ECSSR_SS11              (0x00000800)
-#define MCF_ETPU_ECSSR_SS12              (0x00001000)
-#define MCF_ETPU_ECSSR_SS13              (0x00002000)
-#define MCF_ETPU_ECSSR_SS14              (0x00004000)
-#define MCF_ETPU_ECSSR_SS15              (0x00008000)
-#define MCF_ETPU_ECSSR_SS16              (0x00010000)
-#define MCF_ETPU_ECSSR_SS17              (0x00020000)
-#define MCF_ETPU_ECSSR_SS18              (0x00040000)
-#define MCF_ETPU_ECSSR_SS19              (0x00080000)
-#define MCF_ETPU_ECSSR_SS20              (0x00100000)
-#define MCF_ETPU_ECSSR_SS21              (0x00200000)
-#define MCF_ETPU_ECSSR_SS22              (0x00400000)
-#define MCF_ETPU_ECSSR_SS23              (0x00800000)
-#define MCF_ETPU_ECSSR_SS24              (0x01000000)
-#define MCF_ETPU_ECSSR_SS25              (0x02000000)
-#define MCF_ETPU_ECSSR_SS26              (0x04000000)
-#define MCF_ETPU_ECSSR_SS27              (0x08000000)
-#define MCF_ETPU_ECSSR_SS28              (0x10000000)
-#define MCF_ETPU_ECSSR_SS29              (0x20000000)
-#define MCF_ETPU_ECSSR_SS30              (0x40000000)
-#define MCF_ETPU_ECSSR_SS31              (0x80000000)
-
-/* Bit definitions and macros for MCF_ETPU_ECnSCR */
-#define MCF_ETPU_ECnSCR_FM(x)            (((x)&0x00000003)<<0)
-#define MCF_ETPU_ECnSCR_OBE              (0x00002000)
-#define MCF_ETPU_ECnSCR_OPS              (0x00004000)
-#define MCF_ETPU_ECnSCR_IPS              (0x00008000)
-#define MCF_ETPU_ECnSCR_DTROS            (0x00400000)
-#define MCF_ETPU_ECnSCR_DTRS             (0x00800000)
-#define MCF_ETPU_ECnSCR_CIOS             (0x40000000)
-#define MCF_ETPU_ECnSCR_CIS              (0x80000000)
-
-/* Bit definitions and macros for MCF_ETPU_ECnCR */
-#define MCF_ETPU_ECnCR_CPBA(x)           (((x)&0x000007FF)<<0)
-#define MCF_ETPU_ECnCR_OPOL              (0x00004000)
-#define MCF_ETPU_ECnCR_ODIS              (0x00008000)
-#define MCF_ETPU_ECnCR_CFS(x)            (((x)&0x0000001F)<<16)
-#define MCF_ETPU_ECnCR_ETCS              (0x01000000)
-#define MCF_ETPU_ECnCR_CPR(x)            (((x)&0x00000003)<<28)
-#define MCF_ETPU_ECnCR_DTRE              (0x40000000)
-#define MCF_ETPU_ECnCR_CIE               (0x80000000)
-
-/* Bit definitions and macros for MCF_ETPU_ECnHSSR */
-#define MCF_ETPU_ECnHSSR_HSR(x)          (((x)&0x00000007)<<0)
-
-/********************************************************************/
-
-#endif /* __MCF523X_ETPU_H__ */
+/*\r
+ * These files are taken from the MCF523X source code example package\r
+ * which is available on the Freescale website. Freescale explicitly \r
+ * grants the redistribution and modification of these source files.\r
+ * The complete licensing information is available in the file \r
+ * LICENSE_FREESCALE.TXT.\r
+ *\r
+ * File:       mcf523x_etpu.h\r
+ * Purpose:    Register and bit definitions for the MCF523X\r
+ *\r
+ * Notes:      \r
+ *     \r
+ */\r
+\r
+#ifndef __MCF523X_ETPU_H__\r
+#define __MCF523X_ETPU_H__\r
+\r
+/*********************************************************************\r
+*\r
+* enhanced Time Processor Unit (ETPU)\r
+*\r
+*********************************************************************/\r
+\r
+/* Register read/write macros */\r
+#define MCF_ETPU_EMCR          (*(vuint32*)(void*)(&__IPSBAR[0x1D0000]))\r
+#define MCF_ETPU_ECDCR         (*(vuint32*)(void*)(&__IPSBAR[0x1D0004]))\r
+#define MCF_ETPU_EMISCCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D000C]))\r
+#define MCF_ETPU_ESCMODR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0010]))\r
+#define MCF_ETPU_EECR          (*(vuint32*)(void*)(&__IPSBAR[0x1D0014]))\r
+#define MCF_ETPU_ETBCR         (*(vuint32*)(void*)(&__IPSBAR[0x1D0020]))\r
+#define MCF_ETPU_ETB1R         (*(vuint32*)(void*)(&__IPSBAR[0x1D0024]))\r
+#define MCF_ETPU_ETB2R         (*(vuint32*)(void*)(&__IPSBAR[0x1D0028]))\r
+#define MCF_ETPU_EREDCR        (*(vuint32*)(void*)(&__IPSBAR[0x1D002C]))\r
+#define MCF_ETPU_ECISR         (*(vuint32*)(void*)(&__IPSBAR[0x1D0200]))\r
+#define MCF_ETPU_ECDTRSR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0210]))\r
+#define MCF_ETPU_ECIOSR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0220]))\r
+#define MCF_ETPU_ECDTROSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D0230]))\r
+#define MCF_ETPU_ECIER         (*(vuint32*)(void*)(&__IPSBAR[0x1D0240]))\r
+#define MCF_ETPU_ECDTRER       (*(vuint32*)(void*)(&__IPSBAR[0x1D0250]))\r
+#define MCF_ETPU_ECPSSR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0280]))\r
+#define MCF_ETPU_ECSSR         (*(vuint32*)(void*)(&__IPSBAR[0x1D0290]))\r
+#define MCF_ETPU_EC0SCR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0404]))\r
+#define MCF_ETPU_EC1SCR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0414]))\r
+#define MCF_ETPU_EC2SCR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0424]))\r
+#define MCF_ETPU_EC3SCR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0434]))\r
+#define MCF_ETPU_EC4SCR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0444]))\r
+#define MCF_ETPU_EC5SCR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0454]))\r
+#define MCF_ETPU_EC6SCR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0464]))\r
+#define MCF_ETPU_EC7SCR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0474]))\r
+#define MCF_ETPU_EC8SCR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0484]))\r
+#define MCF_ETPU_EC9SCR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0494]))\r
+#define MCF_ETPU_EC10SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D04A4]))\r
+#define MCF_ETPU_EC11SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D04B4]))\r
+#define MCF_ETPU_EC12SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D04C4]))\r
+#define MCF_ETPU_EC13SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D04D4]))\r
+#define MCF_ETPU_EC14SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D04E4]))\r
+#define MCF_ETPU_EC15SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D04F4]))\r
+#define MCF_ETPU_EC16SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0504]))\r
+#define MCF_ETPU_EC17SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0514]))\r
+#define MCF_ETPU_EC18SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0524]))\r
+#define MCF_ETPU_EC19SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0534]))\r
+#define MCF_ETPU_EC20SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0544]))\r
+#define MCF_ETPU_EC21SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0554]))\r
+#define MCF_ETPU_EC22SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0564]))\r
+#define MCF_ETPU_EC23SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0574]))\r
+#define MCF_ETPU_EC24SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0584]))\r
+#define MCF_ETPU_EC25SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0594]))\r
+#define MCF_ETPU_EC26SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D05A4]))\r
+#define MCF_ETPU_EC27SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D05B4]))\r
+#define MCF_ETPU_EC28SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D05C4]))\r
+#define MCF_ETPU_EC29SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D05D4]))\r
+#define MCF_ETPU_EC30SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D05E4]))\r
+#define MCF_ETPU_EC31SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D05F4]))\r
+#define MCF_ETPU_ECnSCR(x)     (*(vuint32*)(void*)(&__IPSBAR[0x1D0404+((x)*0x010)]))\r
+#define MCF_ETPU_EC0CR         (*(vuint32*)(void*)(&__IPSBAR[0x1D0400]))\r
+#define MCF_ETPU_EC1CR         (*(vuint32*)(void*)(&__IPSBAR[0x1D0410]))\r
+#define MCF_ETPU_EC2CR         (*(vuint32*)(void*)(&__IPSBAR[0x1D0420]))\r
+#define MCF_ETPU_EC3CR         (*(vuint32*)(void*)(&__IPSBAR[0x1D0430]))\r
+#define MCF_ETPU_EC4CR         (*(vuint32*)(void*)(&__IPSBAR[0x1D0440]))\r
+#define MCF_ETPU_EC5CR         (*(vuint32*)(void*)(&__IPSBAR[0x1D0450]))\r
+#define MCF_ETPU_EC6CR         (*(vuint32*)(void*)(&__IPSBAR[0x1D0460]))\r
+#define MCF_ETPU_EC7CR         (*(vuint32*)(void*)(&__IPSBAR[0x1D0470]))\r
+#define MCF_ETPU_EC8CR         (*(vuint32*)(void*)(&__IPSBAR[0x1D0480]))\r
+#define MCF_ETPU_EC9CR         (*(vuint32*)(void*)(&__IPSBAR[0x1D0490]))\r
+#define MCF_ETPU_EC10CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D04A0]))\r
+#define MCF_ETPU_EC11CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D04B0]))\r
+#define MCF_ETPU_EC12CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D04C0]))\r
+#define MCF_ETPU_EC13CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D04D0]))\r
+#define MCF_ETPU_EC14CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D04E0]))\r
+#define MCF_ETPU_EC15CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D04F0]))\r
+#define MCF_ETPU_EC16CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0500]))\r
+#define MCF_ETPU_EC17CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0510]))\r
+#define MCF_ETPU_EC18CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0520]))\r
+#define MCF_ETPU_EC19CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0530]))\r
+#define MCF_ETPU_EC20CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0540]))\r
+#define MCF_ETPU_EC21CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0550]))\r
+#define MCF_ETPU_EC22CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0560]))\r
+#define MCF_ETPU_EC23CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0570]))\r
+#define MCF_ETPU_EC24CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0580]))\r
+#define MCF_ETPU_EC25CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0590]))\r
+#define MCF_ETPU_EC26CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D05A0]))\r
+#define MCF_ETPU_EC27CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D05B0]))\r
+#define MCF_ETPU_EC28CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D05C0]))\r
+#define MCF_ETPU_EC29CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D05D0]))\r
+#define MCF_ETPU_EC30CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D05E0]))\r
+#define MCF_ETPU_EC31CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D05F0]))\r
+#define MCF_ETPU_ECnCR(x)      (*(vuint32*)(void*)(&__IPSBAR[0x1D0400+((x)*0x010)]))\r
+#define MCF_ETPU_EC0HSSR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0408]))\r
+#define MCF_ETPU_EC1HSSR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0418]))\r
+#define MCF_ETPU_EC2HSSR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0428]))\r
+#define MCF_ETPU_EC3HSSR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0438]))\r
+#define MCF_ETPU_EC4HSSR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0448]))\r
+#define MCF_ETPU_EC5HSSR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0458]))\r
+#define MCF_ETPU_EC6HSSR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0468]))\r
+#define MCF_ETPU_EC7HSSR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0478]))\r
+#define MCF_ETPU_EC8HSSR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0488]))\r
+#define MCF_ETPU_EC9HSSR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0498]))\r
+#define MCF_ETPU_EC10HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D04A8]))\r
+#define MCF_ETPU_EC11HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D04B8]))\r
+#define MCF_ETPU_EC12HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D04C8]))\r
+#define MCF_ETPU_EC13HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D04D8]))\r
+#define MCF_ETPU_EC14HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D04E8]))\r
+#define MCF_ETPU_EC15HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D04F8]))\r
+#define MCF_ETPU_EC16HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D0508]))\r
+#define MCF_ETPU_EC17HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D0518]))\r
+#define MCF_ETPU_EC18HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D0528]))\r
+#define MCF_ETPU_EC19HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D0538]))\r
+#define MCF_ETPU_EC20HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D0548]))\r
+#define MCF_ETPU_EC21HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D0558]))\r
+#define MCF_ETPU_EC22HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D0568]))\r
+#define MCF_ETPU_EC23HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D0578]))\r
+#define MCF_ETPU_EC24HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D0588]))\r
+#define MCF_ETPU_EC25HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D0598]))\r
+#define MCF_ETPU_EC26HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D05A8]))\r
+#define MCF_ETPU_EC27HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D05B8]))\r
+#define MCF_ETPU_EC28HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D05C8]))\r
+#define MCF_ETPU_EC29HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D05D8]))\r
+#define MCF_ETPU_EC30HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D05E8]))\r
+#define MCF_ETPU_EC31HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D05F8]))\r
+#define MCF_ETPU_ECnHSSR(x)    (*(vuint32*)(void*)(&__IPSBAR[0x1D0408+((x)*0x010)]))\r
+\r
+/* Bit definitions and macros for MCF_ETPU_EMCR */\r
+#define MCF_ETPU_EMCR_GTBE               (0x00000001)\r
+#define MCF_ETPU_EMCR_VIS                (0x00000040)\r
+#define MCF_ETPU_EMCR_SCMMISEN           (0x00000200)\r
+#define MCF_ETPU_EMCR_SCMMISF            (0x00000400)\r
+#define MCF_ETPU_EMCR_SCMSIZE(x)         (((x)&0x0000001F)<<16)\r
+#define MCF_ETPU_EMCR_ILF2               (0x01000000)\r
+#define MCF_ETPU_EMCR_ILF1               (0x02000000)\r
+#define MCF_ETPU_EMCR_MGE2               (0x04000000)\r
+#define MCF_ETPU_EMCR_MGE1               (0x08000000)\r
+#define MCF_ETPU_EMCR_GEC                (0x80000000)\r
+\r
+/* Bit definitions and macros for MCF_ETPU_ECDCR */\r
+#define MCF_ETPU_ECDCR_PARM1(x)          (((x)&0x0000007F)<<0)\r
+#define MCF_ETPU_ECDCR_WR                (0x00000080)\r
+#define MCF_ETPU_ECDCR_PARM0(x)          (((x)&0x0000007F)<<8)\r
+#define MCF_ETPU_ECDCR_PWIDTH            (0x00008000)\r
+#define MCF_ETPU_ECDCR_PBASE(x)          (((x)&0x000003FF)<<16)\r
+#define MCF_ETPU_ECDCR_CTBASE(x)         (((x)&0x0000001F)<<26)\r
+#define MCF_ETPU_ECDCR_STS               (0x80000000)\r
+\r
+/* Bit definitions and macros for MCF_ETPU_EECR */\r
+#define MCF_ETPU_EECR_ETB(x)             (((x)&0x0000001F)<<0)\r
+#define MCF_ETPU_EECR_CDFC(x)            (((x)&0x00000003)<<14)\r
+#define MCF_ETPU_EECR_FPSK(x)            (((x)&0x00000007)<<16)\r
+#define MCF_ETPU_EECR_HLTF               (0x00800000)\r
+#define MCF_ETPU_EECR_STF                (0x10000000)\r
+#define MCF_ETPU_EECR_MDIS               (0x40000000)\r
+#define MCF_ETPU_EECR_FEND               (0x80000000)\r
+\r
+/* Bit definitions and macros for MCF_ETPU_ETBCR */\r
+#define MCF_ETPU_ETBCR_TCR1P(x)          (((x)&0x000000FF)<<0)\r
+#define MCF_ETPU_ETBCR_TCR1CTL(x)        (((x)&0x00000003)<<14)\r
+#define MCF_ETPU_ETBCR_TCR2P(x)          (((x)&0x0000003F)<<16)\r
+#define MCF_ETPU_ETBCR_AM                (0x02000000)\r
+#define MCF_ETPU_ETBCR_TCRCF(x)          (((x)&0x00000003)<<27)\r
+#define MCF_ETPU_ETBCR_TCR2CTL(x)        (((x)&0x00000007)<<29)\r
+\r
+/* Bit definitions and macros for MCF_ETPU_ETB1R */\r
+#define MCF_ETPU_ETB1R_TCR1(x)           (((x)&0x00FFFFFF)<<0)\r
+\r
+/* Bit definitions and macros for MCF_ETPU_ETB2R */\r
+#define MCF_ETPU_ETB2R_TCR2(x)           (((x)&0x00FFFFFF)<<0)\r
+\r
+/* Bit definitions and macros for MCF_ETPU_EREDCR */\r
+#define MCF_ETPU_EREDCR_SRV2(x)          (((x)&0x0000000F)<<0)\r
+#define MCF_ETPU_EREDCR_SERVER_ID2(x)    (((x)&0x0000000F)<<8)\r
+#define MCF_ETPU_EREDCR_RSC2             (0x00004000)\r
+#define MCF_ETPU_EREDCR_REN2             (0x00008000)\r
+#define MCF_ETPU_EREDCR_SRV1(x)          (((x)&0x0000000F)<<16)\r
+#define MCF_ETPU_EREDCR_SERVER_ID1(x)    (((x)&0x0000000F)<<24)\r
+#define MCF_ETPU_EREDCR_RSC1             (0x40000000)\r
+#define MCF_ETPU_EREDCR_REN1             (0x80000000)\r
+\r
+/* Bit definitions and macros for MCF_ETPU_ECISR */\r
+#define MCF_ETPU_ECISR_CIS0              (0x00000001)\r
+#define MCF_ETPU_ECISR_CIS1              (0x00000002)\r
+#define MCF_ETPU_ECISR_CIS2              (0x00000004)\r
+#define MCF_ETPU_ECISR_CIS3              (0x00000008)\r
+#define MCF_ETPU_ECISR_CIS4              (0x00000010)\r
+#define MCF_ETPU_ECISR_CIS5              (0x00000020)\r
+#define MCF_ETPU_ECISR_CIS6              (0x00000040)\r
+#define MCF_ETPU_ECISR_CIS7              (0x00000080)\r
+#define MCF_ETPU_ECISR_CIS8              (0x00000100)\r
+#define MCF_ETPU_ECISR_CIS9              (0x00000200)\r
+#define MCF_ETPU_ECISR_CIS10             (0x00000400)\r
+#define MCF_ETPU_ECISR_CIS11             (0x00000800)\r
+#define MCF_ETPU_ECISR_CIS12             (0x00001000)\r
+#define MCF_ETPU_ECISR_CIS13             (0x00002000)\r
+#define MCF_ETPU_ECISR_CIS14             (0x00004000)\r
+#define MCF_ETPU_ECISR_CIS15             (0x00008000)\r
+#define MCF_ETPU_ECISR_CIS16             (0x00010000)\r
+#define MCF_ETPU_ECISR_CIS17             (0x00020000)\r
+#define MCF_ETPU_ECISR_CIS18             (0x00040000)\r
+#define MCF_ETPU_ECISR_CIS19             (0x00080000)\r
+#define MCF_ETPU_ECISR_CIS20             (0x00100000)\r
+#define MCF_ETPU_ECISR_CIS21             (0x00200000)\r
+#define MCF_ETPU_ECISR_CIS22             (0x00400000)\r
+#define MCF_ETPU_ECISR_CIS23             (0x00800000)\r
+#define MCF_ETPU_ECISR_CIS24             (0x01000000)\r
+#define MCF_ETPU_ECISR_CIS25             (0x02000000)\r
+#define MCF_ETPU_ECISR_CIS26             (0x04000000)\r
+#define MCF_ETPU_ECISR_CIS27             (0x08000000)\r
+#define MCF_ETPU_ECISR_CIS28             (0x10000000)\r
+#define MCF_ETPU_ECISR_CIS29             (0x20000000)\r
+#define MCF_ETPU_ECISR_CIS30             (0x40000000)\r
+#define MCF_ETPU_ECISR_CIS31             (0x80000000)\r
+\r
+/* Bit definitions and macros for MCF_ETPU_ECDTRSR */\r
+#define MCF_ETPU_ECDTRSR_DTRS0           (0x00000001)\r
+#define MCF_ETPU_ECDTRSR_DTRS1           (0x00000002)\r
+#define MCF_ETPU_ECDTRSR_DTRS2           (0x00000004)\r
+#define MCF_ETPU_ECDTRSR_DTRS3           (0x00000008)\r
+#define MCF_ETPU_ECDTRSR_DTRS4           (0x00000010)\r
+#define MCF_ETPU_ECDTRSR_DTRS5           (0x00000020)\r
+#define MCF_ETPU_ECDTRSR_DTRS6           (0x00000040)\r
+#define MCF_ETPU_ECDTRSR_DTRS7           (0x00000080)\r
+#define MCF_ETPU_ECDTRSR_DTRS8           (0x00000100)\r
+#define MCF_ETPU_ECDTRSR_DTRS9           (0x00000200)\r
+#define MCF_ETPU_ECDTRSR_DTRS10          (0x00000400)\r
+#define MCF_ETPU_ECDTRSR_DTRS11          (0x00000800)\r
+#define MCF_ETPU_ECDTRSR_DTRS12          (0x00001000)\r
+#define MCF_ETPU_ECDTRSR_DTRS13          (0x00002000)\r
+#define MCF_ETPU_ECDTRSR_DTRS14          (0x00004000)\r
+#define MCF_ETPU_ECDTRSR_DTRS15          (0x00008000)\r
+#define MCF_ETPU_ECDTRSR_DTRS16          (0x00010000)\r
+#define MCF_ETPU_ECDTRSR_DTRS17          (0x00020000)\r
+#define MCF_ETPU_ECDTRSR_DTRS18          (0x00040000)\r
+#define MCF_ETPU_ECDTRSR_DTRS19          (0x00080000)\r
+#define MCF_ETPU_ECDTRSR_DTRS20          (0x00100000)\r
+#define MCF_ETPU_ECDTRSR_DTRS21          (0x00200000)\r
+#define MCF_ETPU_ECDTRSR_DTRS22          (0x00400000)\r
+#define MCF_ETPU_ECDTRSR_DTRS23          (0x00800000)\r
+#define MCF_ETPU_ECDTRSR_DTRS24          (0x01000000)\r
+#define MCF_ETPU_ECDTRSR_DTRS25          (0x02000000)\r
+#define MCF_ETPU_ECDTRSR_DTRS26          (0x04000000)\r
+#define MCF_ETPU_ECDTRSR_DTRS27          (0x08000000)\r
+#define MCF_ETPU_ECDTRSR_DTRS28          (0x10000000)\r
+#define MCF_ETPU_ECDTRSR_DTRS29          (0x20000000)\r
+#define MCF_ETPU_ECDTRSR_DTRS30          (0x40000000)\r
+#define MCF_ETPU_ECDTRSR_DTRS31          (0x80000000)\r
+\r
+/* Bit definitions and macros for MCF_ETPU_ECIOSR */\r
+#define MCF_ETPU_ECIOSR_CIOS0            (0x00000001)\r
+#define MCF_ETPU_ECIOSR_CIOS1            (0x00000002)\r
+#define MCF_ETPU_ECIOSR_CIOS2            (0x00000004)\r
+#define MCF_ETPU_ECIOSR_CIOS3            (0x00000008)\r
+#define MCF_ETPU_ECIOSR_CIOS4            (0x00000010)\r
+#define MCF_ETPU_ECIOSR_CIOS5            (0x00000020)\r
+#define MCF_ETPU_ECIOSR_CIOS6            (0x00000040)\r
+#define MCF_ETPU_ECIOSR_CIOS7            (0x00000080)\r
+#define MCF_ETPU_ECIOSR_CIOS8            (0x00000100)\r
+#define MCF_ETPU_ECIOSR_CIOS9            (0x00000200)\r
+#define MCF_ETPU_ECIOSR_CIOS10           (0x00000400)\r
+#define MCF_ETPU_ECIOSR_CIOS11           (0x00000800)\r
+#define MCF_ETPU_ECIOSR_CIOS12           (0x00001000)\r
+#define MCF_ETPU_ECIOSR_CIOS13           (0x00002000)\r
+#define MCF_ETPU_ECIOSR_CIOS14           (0x00004000)\r
+#define MCF_ETPU_ECIOSR_CIOS15           (0x00008000)\r
+#define MCF_ETPU_ECIOSR_CIOS16           (0x00010000)\r
+#define MCF_ETPU_ECIOSR_CIOS17           (0x00020000)\r
+#define MCF_ETPU_ECIOSR_CIOS18           (0x00040000)\r
+#define MCF_ETPU_ECIOSR_CIOS19           (0x00080000)\r
+#define MCF_ETPU_ECIOSR_CIOS20           (0x00100000)\r
+#define MCF_ETPU_ECIOSR_CIOS21           (0x00200000)\r
+#define MCF_ETPU_ECIOSR_CIOS22           (0x00400000)\r
+#define MCF_ETPU_ECIOSR_CIOS23           (0x00800000)\r
+#define MCF_ETPU_ECIOSR_CIOS24           (0x01000000)\r
+#define MCF_ETPU_ECIOSR_CIOS25           (0x02000000)\r
+#define MCF_ETPU_ECIOSR_CIOS26           (0x04000000)\r
+#define MCF_ETPU_ECIOSR_CIOS27           (0x08000000)\r
+#define MCF_ETPU_ECIOSR_CIOS28           (0x10000000)\r
+#define MCF_ETPU_ECIOSR_CIOS29           (0x20000000)\r
+#define MCF_ETPU_ECIOSR_CIOS30           (0x40000000)\r
+#define MCF_ETPU_ECIOSR_CIOS31           (0x80000000)\r
+\r
+/* Bit definitions and macros for MCF_ETPU_ECDTROSR */\r
+#define MCF_ETPU_ECDTROSR_DTROS0         (0x00000001)\r
+#define MCF_ETPU_ECDTROSR_DTROS1         (0x00000002)\r
+#define MCF_ETPU_ECDTROSR_DTROS2         (0x00000004)\r
+#define MCF_ETPU_ECDTROSR_DTROS3         (0x00000008)\r
+#define MCF_ETPU_ECDTROSR_DTROS4         (0x00000010)\r
+#define MCF_ETPU_ECDTROSR_DTROS5         (0x00000020)\r
+#define MCF_ETPU_ECDTROSR_DTROS6         (0x00000040)\r
+#define MCF_ETPU_ECDTROSR_DTROS7         (0x00000080)\r
+#define MCF_ETPU_ECDTROSR_DTROS8         (0x00000100)\r
+#define MCF_ETPU_ECDTROSR_DTROS9         (0x00000200)\r
+#define MCF_ETPU_ECDTROSR_DTROS10        (0x00000400)\r
+#define MCF_ETPU_ECDTROSR_DTROS11        (0x00000800)\r
+#define MCF_ETPU_ECDTROSR_DTROS12        (0x00001000)\r
+#define MCF_ETPU_ECDTROSR_DTROS13        (0x00002000)\r
+#define MCF_ETPU_ECDTROSR_DTROS14        (0x00004000)\r
+#define MCF_ETPU_ECDTROSR_DTROS15        (0x00008000)\r
+#define MCF_ETPU_ECDTROSR_DTROS16        (0x00010000)\r
+#define MCF_ETPU_ECDTROSR_DTROS17        (0x00020000)\r
+#define MCF_ETPU_ECDTROSR_DTROS18        (0x00040000)\r
+#define MCF_ETPU_ECDTROSR_DTROS19        (0x00080000)\r
+#define MCF_ETPU_ECDTROSR_DTROS20        (0x00100000)\r
+#define MCF_ETPU_ECDTROSR_DTROS21        (0x00200000)\r
+#define MCF_ETPU_ECDTROSR_DTROS22        (0x00400000)\r
+#define MCF_ETPU_ECDTROSR_DTROS23        (0x00800000)\r
+#define MCF_ETPU_ECDTROSR_DTROS24        (0x01000000)\r
+#define MCF_ETPU_ECDTROSR_DTROS25        (0x02000000)\r
+#define MCF_ETPU_ECDTROSR_DTROS26        (0x04000000)\r
+#define MCF_ETPU_ECDTROSR_DTROS27        (0x08000000)\r
+#define MCF_ETPU_ECDTROSR_DTROS28        (0x10000000)\r
+#define MCF_ETPU_ECDTROSR_DTROS29        (0x20000000)\r
+#define MCF_ETPU_ECDTROSR_DTROS30        (0x40000000)\r
+#define MCF_ETPU_ECDTROSR_DTROS31        (0x80000000)\r
+\r
+/* Bit definitions and macros for MCF_ETPU_ECIER */\r
+#define MCF_ETPU_ECIER_CIE0              (0x00000001)\r
+#define MCF_ETPU_ECIER_CIE1              (0x00000002)\r
+#define MCF_ETPU_ECIER_CIE2              (0x00000004)\r
+#define MCF_ETPU_ECIER_CIE3              (0x00000008)\r
+#define MCF_ETPU_ECIER_CIE4              (0x00000010)\r
+#define MCF_ETPU_ECIER_CIE5              (0x00000020)\r
+#define MCF_ETPU_ECIER_CIE6              (0x00000040)\r
+#define MCF_ETPU_ECIER_CIE7              (0x00000080)\r
+#define MCF_ETPU_ECIER_CIE8              (0x00000100)\r
+#define MCF_ETPU_ECIER_CIE9              (0x00000200)\r
+#define MCF_ETPU_ECIER_CIE10             (0x00000400)\r
+#define MCF_ETPU_ECIER_CIE11             (0x00000800)\r
+#define MCF_ETPU_ECIER_CIE12             (0x00001000)\r
+#define MCF_ETPU_ECIER_CIE13             (0x00002000)\r
+#define MCF_ETPU_ECIER_CIE14             (0x00004000)\r
+#define MCF_ETPU_ECIER_CIE15             (0x00008000)\r
+#define MCF_ETPU_ECIER_CIE16             (0x00010000)\r
+#define MCF_ETPU_ECIER_CIE17             (0x00020000)\r
+#define MCF_ETPU_ECIER_CIE18             (0x00040000)\r
+#define MCF_ETPU_ECIER_CIE19             (0x00080000)\r
+#define MCF_ETPU_ECIER_CIE20             (0x00100000)\r
+#define MCF_ETPU_ECIER_CIE21             (0x00200000)\r
+#define MCF_ETPU_ECIER_CIE22             (0x00400000)\r
+#define MCF_ETPU_ECIER_CIE23             (0x00800000)\r
+#define MCF_ETPU_ECIER_CIE24             (0x01000000)\r
+#define MCF_ETPU_ECIER_CIE25             (0x02000000)\r
+#define MCF_ETPU_ECIER_CIE26             (0x04000000)\r
+#define MCF_ETPU_ECIER_CIE27             (0x08000000)\r
+#define MCF_ETPU_ECIER_CIE28             (0x10000000)\r
+#define MCF_ETPU_ECIER_CIE29             (0x20000000)\r
+#define MCF_ETPU_ECIER_CIE30             (0x40000000)\r
+#define MCF_ETPU_ECIER_CIE31             (0x80000000)\r
+\r
+/* Bit definitions and macros for MCF_ETPU_ECDTRER */\r
+#define MCF_ETPU_ECDTRER_DTRE0           (0x00000001)\r
+#define MCF_ETPU_ECDTRER_DTRE1           (0x00000002)\r
+#define MCF_ETPU_ECDTRER_DTRE2           (0x00000004)\r
+#define MCF_ETPU_ECDTRER_DTRE3           (0x00000008)\r
+#define MCF_ETPU_ECDTRER_DTRE4           (0x00000010)\r
+#define MCF_ETPU_ECDTRER_DTRE5           (0x00000020)\r
+#define MCF_ETPU_ECDTRER_DTRE6           (0x00000040)\r
+#define MCF_ETPU_ECDTRER_DTRE7           (0x00000080)\r
+#define MCF_ETPU_ECDTRER_DTRE8           (0x00000100)\r
+#define MCF_ETPU_ECDTRER_DTRE9           (0x00000200)\r
+#define MCF_ETPU_ECDTRER_DTRE10          (0x00000400)\r
+#define MCF_ETPU_ECDTRER_DTRE11          (0x00000800)\r
+#define MCF_ETPU_ECDTRER_DTRE12          (0x00001000)\r
+#define MCF_ETPU_ECDTRER_DTRE13          (0x00002000)\r
+#define MCF_ETPU_ECDTRER_DTRE14          (0x00004000)\r
+#define MCF_ETPU_ECDTRER_DTRE15          (0x00008000)\r
+#define MCF_ETPU_ECDTRER_DTRE16          (0x00010000)\r
+#define MCF_ETPU_ECDTRER_DTRE17          (0x00020000)\r
+#define MCF_ETPU_ECDTRER_DTRE18          (0x00040000)\r
+#define MCF_ETPU_ECDTRER_DTRE19          (0x00080000)\r
+#define MCF_ETPU_ECDTRER_DTRE20          (0x00100000)\r
+#define MCF_ETPU_ECDTRER_DTRE21          (0x00200000)\r
+#define MCF_ETPU_ECDTRER_DTRE22          (0x00400000)\r
+#define MCF_ETPU_ECDTRER_DTRE23          (0x00800000)\r
+#define MCF_ETPU_ECDTRER_DTRE24          (0x01000000)\r
+#define MCF_ETPU_ECDTRER_DTRE25          (0x02000000)\r
+#define MCF_ETPU_ECDTRER_DTRE26          (0x04000000)\r
+#define MCF_ETPU_ECDTRER_DTRE27          (0x08000000)\r
+#define MCF_ETPU_ECDTRER_DTRE28          (0x10000000)\r
+#define MCF_ETPU_ECDTRER_DTRE29          (0x20000000)\r
+#define MCF_ETPU_ECDTRER_DTRE30          (0x40000000)\r
+#define MCF_ETPU_ECDTRER_DTRE31          (0x80000000)\r
+\r
+/* Bit definitions and macros for MCF_ETPU_ECPSSR */\r
+#define MCF_ETPU_ECPSSR_SR0              (0x00000001)\r
+#define MCF_ETPU_ECPSSR_SR1              (0x00000002)\r
+#define MCF_ETPU_ECPSSR_SR2              (0x00000004)\r
+#define MCF_ETPU_ECPSSR_SR3              (0x00000008)\r
+#define MCF_ETPU_ECPSSR_SR4              (0x00000010)\r
+#define MCF_ETPU_ECPSSR_SR5              (0x00000020)\r
+#define MCF_ETPU_ECPSSR_SR6              (0x00000040)\r
+#define MCF_ETPU_ECPSSR_SR7              (0x00000080)\r
+#define MCF_ETPU_ECPSSR_SR8              (0x00000100)\r
+#define MCF_ETPU_ECPSSR_SR9              (0x00000200)\r
+#define MCF_ETPU_ECPSSR_SR10             (0x00000400)\r
+#define MCF_ETPU_ECPSSR_SR11             (0x00000800)\r
+#define MCF_ETPU_ECPSSR_SR12             (0x00001000)\r
+#define MCF_ETPU_ECPSSR_SR13             (0x00002000)\r
+#define MCF_ETPU_ECPSSR_SR14             (0x00004000)\r
+#define MCF_ETPU_ECPSSR_SR15             (0x00008000)\r
+#define MCF_ETPU_ECPSSR_SR16             (0x00010000)\r
+#define MCF_ETPU_ECPSSR_SR17             (0x00020000)\r
+#define MCF_ETPU_ECPSSR_SR18             (0x00040000)\r
+#define MCF_ETPU_ECPSSR_SR19             (0x00080000)\r
+#define MCF_ETPU_ECPSSR_SR20             (0x00100000)\r
+#define MCF_ETPU_ECPSSR_SR21             (0x00200000)\r
+#define MCF_ETPU_ECPSSR_SR22             (0x00400000)\r
+#define MCF_ETPU_ECPSSR_SR23             (0x00800000)\r
+#define MCF_ETPU_ECPSSR_SR24             (0x01000000)\r
+#define MCF_ETPU_ECPSSR_SR25             (0x02000000)\r
+#define MCF_ETPU_ECPSSR_SR26             (0x04000000)\r
+#define MCF_ETPU_ECPSSR_SR27             (0x08000000)\r
+#define MCF_ETPU_ECPSSR_SR28             (0x10000000)\r
+#define MCF_ETPU_ECPSSR_SR29             (0x20000000)\r
+#define MCF_ETPU_ECPSSR_SR30             (0x40000000)\r
+#define MCF_ETPU_ECPSSR_SR31             (0x80000000)\r
+\r
+/* Bit definitions and macros for MCF_ETPU_ECSSR */\r
+#define MCF_ETPU_ECSSR_SS0               (0x00000001)\r
+#define MCF_ETPU_ECSSR_SS1               (0x00000002)\r
+#define MCF_ETPU_ECSSR_SS2               (0x00000004)\r
+#define MCF_ETPU_ECSSR_SS3               (0x00000008)\r
+#define MCF_ETPU_ECSSR_SS4               (0x00000010)\r
+#define MCF_ETPU_ECSSR_SS5               (0x00000020)\r
+#define MCF_ETPU_ECSSR_SS6               (0x00000040)\r
+#define MCF_ETPU_ECSSR_SS7               (0x00000080)\r
+#define MCF_ETPU_ECSSR_SS8               (0x00000100)\r
+#define MCF_ETPU_ECSSR_SS9               (0x00000200)\r
+#define MCF_ETPU_ECSSR_SS10              (0x00000400)\r
+#define MCF_ETPU_ECSSR_SS11              (0x00000800)\r
+#define MCF_ETPU_ECSSR_SS12              (0x00001000)\r
+#define MCF_ETPU_ECSSR_SS13              (0x00002000)\r
+#define MCF_ETPU_ECSSR_SS14              (0x00004000)\r
+#define MCF_ETPU_ECSSR_SS15              (0x00008000)\r
+#define MCF_ETPU_ECSSR_SS16              (0x00010000)\r
+#define MCF_ETPU_ECSSR_SS17              (0x00020000)\r
+#define MCF_ETPU_ECSSR_SS18              (0x00040000)\r
+#define MCF_ETPU_ECSSR_SS19              (0x00080000)\r
+#define MCF_ETPU_ECSSR_SS20              (0x00100000)\r
+#define MCF_ETPU_ECSSR_SS21              (0x00200000)\r
+#define MCF_ETPU_ECSSR_SS22              (0x00400000)\r
+#define MCF_ETPU_ECSSR_SS23              (0x00800000)\r
+#define MCF_ETPU_ECSSR_SS24              (0x01000000)\r
+#define MCF_ETPU_ECSSR_SS25              (0x02000000)\r
+#define MCF_ETPU_ECSSR_SS26              (0x04000000)\r
+#define MCF_ETPU_ECSSR_SS27              (0x08000000)\r
+#define MCF_ETPU_ECSSR_SS28              (0x10000000)\r
+#define MCF_ETPU_ECSSR_SS29              (0x20000000)\r
+#define MCF_ETPU_ECSSR_SS30              (0x40000000)\r
+#define MCF_ETPU_ECSSR_SS31              (0x80000000)\r
+\r
+/* Bit definitions and macros for MCF_ETPU_ECnSCR */\r
+#define MCF_ETPU_ECnSCR_FM(x)            (((x)&0x00000003)<<0)\r
+#define MCF_ETPU_ECnSCR_OBE              (0x00002000)\r
+#define MCF_ETPU_ECnSCR_OPS              (0x00004000)\r
+#define MCF_ETPU_ECnSCR_IPS              (0x00008000)\r
+#define MCF_ETPU_ECnSCR_DTROS            (0x00400000)\r
+#define MCF_ETPU_ECnSCR_DTRS             (0x00800000)\r
+#define MCF_ETPU_ECnSCR_CIOS             (0x40000000)\r
+#define MCF_ETPU_ECnSCR_CIS              (0x80000000)\r
+\r
+/* Bit definitions and macros for MCF_ETPU_ECnCR */\r
+#define MCF_ETPU_ECnCR_CPBA(x)           (((x)&0x000007FF)<<0)\r
+#define MCF_ETPU_ECnCR_OPOL              (0x00004000)\r
+#define MCF_ETPU_ECnCR_ODIS              (0x00008000)\r
+#define MCF_ETPU_ECnCR_CFS(x)            (((x)&0x0000001F)<<16)\r
+#define MCF_ETPU_ECnCR_ETCS              (0x01000000)\r
+#define MCF_ETPU_ECnCR_CPR(x)            (((x)&0x00000003)<<28)\r
+#define MCF_ETPU_ECnCR_DTRE              (0x40000000)\r
+#define MCF_ETPU_ECnCR_CIE               (0x80000000)\r
+\r
+/* Bit definitions and macros for MCF_ETPU_ECnHSSR */\r
+#define MCF_ETPU_ECnHSSR_HSR(x)          (((x)&0x00000007)<<0)\r
+\r
+/********************************************************************/\r
+\r
+#endif /* __MCF523X_ETPU_H__ */\r
index 2b20a153f14fc0b631f84da6deae0abdc26130ce..a4a209d50199cd00bc970ef4a687575d5c1a5703 100644 (file)
-/*
- * These files are taken from the MCF523X source code example package
- * which is available on the Freescale website. Freescale explicitly 
- * grants the redistribution and modification of these source files.
- * The complete licensing information is available in the file 
- * LICENSE_FREESCALE.TXT.
- *
- * File:       mcf523x_fec.h
- * Purpose:    Register and bit definitions for the MCF523X
- *
- * Notes:      
- *     
- */
-
-#ifndef __MCF523X_FEC_H__
-#define __MCF523X_FEC_H__
-
-/*********************************************************************
-*
-* Fast Ethernet Controller (FEC)
-*
-*********************************************************************/
-
-/* Register read/write macros */
-#define MCF_FEC_EIR                   (*(vuint32*)(void*)(&__IPSBAR[0x001004]))
-#define MCF_FEC_EIMR                  (*(vuint32*)(void*)(&__IPSBAR[0x001008]))
-#define MCF_FEC_RDAR                  (*(vuint32*)(void*)(&__IPSBAR[0x001010]))
-#define MCF_FEC_TDAR                  (*(vuint32*)(void*)(&__IPSBAR[0x001014]))
-#define MCF_FEC_ECR                   (*(vuint32*)(void*)(&__IPSBAR[0x001024]))
-#define MCF_FEC_MMFR                  (*(vuint32*)(void*)(&__IPSBAR[0x001040]))
-#define MCF_FEC_MSCR                  (*(vuint32*)(void*)(&__IPSBAR[0x001044]))
-#define MCF_FEC_MIBC                  (*(vuint32*)(void*)(&__IPSBAR[0x001064]))
-#define MCF_FEC_RCR                   (*(vuint32*)(void*)(&__IPSBAR[0x001084]))
-#define MCF_FEC_TCR                   (*(vuint32*)(void*)(&__IPSBAR[0x0010C4]))
-#define MCF_FEC_PALR                  (*(vuint32*)(void*)(&__IPSBAR[0x0010E4]))
-#define MCF_FEC_PAUR                  (*(vuint32*)(void*)(&__IPSBAR[0x0010E8]))
-#define MCF_FEC_OPD                   (*(vuint32*)(void*)(&__IPSBAR[0x0010EC]))
-#define MCF_FEC_IAUR                  (*(vuint32*)(void*)(&__IPSBAR[0x001118]))
-#define MCF_FEC_IALR                  (*(vuint32*)(void*)(&__IPSBAR[0x00111C]))
-#define MCF_FEC_GAUR                  (*(vuint32*)(void*)(&__IPSBAR[0x001120]))
-#define MCF_FEC_GALR                  (*(vuint32*)(void*)(&__IPSBAR[0x001124]))
-#define MCF_FEC_TFWR                  (*(vuint32*)(void*)(&__IPSBAR[0x001144]))
-#define MCF_FEC_FRBR                  (*(vuint32*)(void*)(&__IPSBAR[0x00114C]))
-#define MCF_FEC_FRSR                  (*(vuint32*)(void*)(&__IPSBAR[0x001150]))
-#define MCF_FEC_ERDSR                 (*(vuint32*)(void*)(&__IPSBAR[0x001180]))
-#define MCF_FEC_ETDSR                 (*(vuint32*)(void*)(&__IPSBAR[0x001184]))
-#define MCF_FEC_EMRBR                 (*(vuint32*)(void*)(&__IPSBAR[0x001188]))
-#define MCF_FEC_RMON_T_DROP           (*(vuint32*)(void*)(&__IPSBAR[0x001200]))
-#define MCF_FEC_RMON_T_PACKETS        (*(vuint32*)(void*)(&__IPSBAR[0x001204]))
-#define MCF_FEC_RMON_T_BC_PKT         (*(vuint32*)(void*)(&__IPSBAR[0x001208]))
-#define MCF_FEC_RMON_T_MC_PKT         (*(vuint32*)(void*)(&__IPSBAR[0x00120C]))
-#define MCF_FEC_RMON_T_CRC_ALIGN      (*(vuint32*)(void*)(&__IPSBAR[0x001210]))
-#define MCF_FEC_RMON_T_UNDERSIZE      (*(vuint32*)(void*)(&__IPSBAR[0x001214]))
-#define MCF_FEC_RMON_T_OVERSIZE       (*(vuint32*)(void*)(&__IPSBAR[0x001218]))
-#define MCF_FEC_RMON_T_FRAG           (*(vuint32*)(void*)(&__IPSBAR[0x00121C]))
-#define MCF_FEC_RMON_T_JAB            (*(vuint32*)(void*)(&__IPSBAR[0x001220]))
-#define MCF_FEC_RMON_T_COL            (*(vuint32*)(void*)(&__IPSBAR[0x001224]))
-#define MCF_FEC_RMON_T_P64            (*(vuint32*)(void*)(&__IPSBAR[0x001228]))
-#define MCF_FEC_RMON_T_P65TO127       (*(vuint32*)(void*)(&__IPSBAR[0x00122C]))
-#define MCF_FEC_RMON_T_P128TO255      (*(vuint32*)(void*)(&__IPSBAR[0x001230]))
-#define MCF_FEC_RMON_T_P256TO511      (*(vuint32*)(void*)(&__IPSBAR[0x001234]))
-#define MCF_FEC_RMON_T_P512TO1023     (*(vuint32*)(void*)(&__IPSBAR[0x001238]))
-#define MCF_FEC_RMON_T_P1024TO2047    (*(vuint32*)(void*)(&__IPSBAR[0x00123C]))
-#define MCF_FEC_RMON_T_P_GTE2048      (*(vuint32*)(void*)(&__IPSBAR[0x001240]))
-#define MCF_FEC_RMON_T_OCTETS         (*(vuint32*)(void*)(&__IPSBAR[0x001244]))
-#define MCF_FEC_IEEE_T_DROP           (*(vuint32*)(void*)(&__IPSBAR[0x001248]))
-#define MCF_FEC_IEEE_T_FRAME_OK       (*(vuint32*)(void*)(&__IPSBAR[0x00124C]))
-#define MCF_FEC_IEEE_T_1COL           (*(vuint32*)(void*)(&__IPSBAR[0x001250]))
-#define MCF_FEC_IEEE_T_MCOL           (*(vuint32*)(void*)(&__IPSBAR[0x001254]))
-#define MCF_FEC_IEEE_T_DEF            (*(vuint32*)(void*)(&__IPSBAR[0x001258]))
-#define MCF_FEC_IEEE_T_LCOL           (*(vuint32*)(void*)(&__IPSBAR[0x00125C]))
-#define MCF_FEC_IEEE_T_EXCOL          (*(vuint32*)(void*)(&__IPSBAR[0x001260]))
-#define MCF_FEC_IEEE_T_MACERR         (*(vuint32*)(void*)(&__IPSBAR[0x001264]))
-#define MCF_FEC_IEEE_T_CSERR          (*(vuint32*)(void*)(&__IPSBAR[0x001268]))
-#define MCF_FEC_IEEE_T_SQE            (*(vuint32*)(void*)(&__IPSBAR[0x00126C]))
-#define MCF_FEC_IEEE_T_FDXFC          (*(vuint32*)(void*)(&__IPSBAR[0x001270]))
-#define MCF_FEC_IEEE_T_OCTETS_OK      (*(vuint32*)(void*)(&__IPSBAR[0x001274]))
-#define MCF_FEC_RMON_R_PACKETS        (*(vuint32*)(void*)(&__IPSBAR[0x001284]))
-#define MCF_FEC_RMON_R_BC_PKT         (*(vuint32*)(void*)(&__IPSBAR[0x001288]))
-#define MCF_FEC_RMON_R_MC_PKT         (*(vuint32*)(void*)(&__IPSBAR[0x00128C]))
-#define MCF_FEC_RMON_R_CRC_ALIGN      (*(vuint32*)(void*)(&__IPSBAR[0x001290]))
-#define MCF_FEC_RMON_R_UNDERSIZE      (*(vuint32*)(void*)(&__IPSBAR[0x001294]))
-#define MCF_FEC_RMON_R_OVERSIZE       (*(vuint32*)(void*)(&__IPSBAR[0x001298]))
-#define MCF_FEC_RMON_R_FRAG           (*(vuint32*)(void*)(&__IPSBAR[0x00129C]))
-#define MCF_FEC_RMON_R_JAB            (*(vuint32*)(void*)(&__IPSBAR[0x0012A0]))
-#define MCF_FEC_RMON_R_RESVD_0        (*(vuint32*)(void*)(&__IPSBAR[0x0012A4]))
-#define MCF_FEC_RMON_R_P64            (*(vuint32*)(void*)(&__IPSBAR[0x0012A8]))
-#define MCF_FEC_RMON_R_P65TO127       (*(vuint32*)(void*)(&__IPSBAR[0x0012AC]))
-#define MCF_FEC_RMON_R_P128TO255      (*(vuint32*)(void*)(&__IPSBAR[0x0012B0]))
-#define MCF_FEC_RMON_R_P256TO511      (*(vuint32*)(void*)(&__IPSBAR[0x0012B4]))
-#define MCF_FEC_RMON_R_512TO1023      (*(vuint32*)(void*)(&__IPSBAR[0x0012B8]))
-#define MCF_FEC_RMON_R_P_GTE2048      (*(vuint32*)(void*)(&__IPSBAR[0x0012C0]))
-#define MCF_FEC_RMON_R_1024TO2047     (*(vuint32*)(void*)(&__IPSBAR[0x0012BC]))
-#define MCF_FEC_RMON_R_OCTETS         (*(vuint32*)(void*)(&__IPSBAR[0x0012C4]))
-#define MCF_FEC_IEEE_R_DROP           (*(vuint32*)(void*)(&__IPSBAR[0x0012C8]))
-#define MCF_FEC_IEEE_R_FRAME_OK       (*(vuint32*)(void*)(&__IPSBAR[0x0012CC]))
-#define MCF_FEC_IEEE_R_CRC            (*(vuint32*)(void*)(&__IPSBAR[0x0012D0]))
-#define MCF_FEC_IEEE_R_ALIGN          (*(vuint32*)(void*)(&__IPSBAR[0x0012D4]))
-#define MCF_FEC_IEEE_R_MACERR         (*(vuint32*)(void*)(&__IPSBAR[0x0012D8]))
-#define MCF_FEC_IEEE_R_FDXFC          (*(vuint32*)(void*)(&__IPSBAR[0x0012DC]))
-#define MCF_FEC_IEEE_R_OCTETS_OK      (*(vuint32*)(void*)(&__IPSBAR[0x0012E0]))
-
-/* Bit definitions and macros for MCF_FEC_EIR */
-#define MCF_FEC_EIR_UN                  (0x00080000)
-#define MCF_FEC_EIR_RL                  (0x00100000)
-#define MCF_FEC_EIR_LC                  (0x00200000)
-#define MCF_FEC_EIR_EBERR               (0x00400000)
-#define MCF_FEC_EIR_MII                 (0x00800000)
-#define MCF_FEC_EIR_RXB                 (0x01000000)
-#define MCF_FEC_EIR_RXF                 (0x02000000)
-#define MCF_FEC_EIR_TXB                 (0x04000000)
-#define MCF_FEC_EIR_TXF                 (0x08000000)
-#define MCF_FEC_EIR_GRA                 (0x10000000)
-#define MCF_FEC_EIR_BABT                (0x20000000)
-#define MCF_FEC_EIR_BABR                (0x40000000)
-#define MCF_FEC_EIR_HBERR               (0x80000000)
-
-/* Bit definitions and macros for MCF_FEC_EIMR */
-#define MCF_FEC_EIMR_UN                 (0x00080000)
-#define MCF_FEC_EIMR_RL                 (0x00100000)
-#define MCF_FEC_EIMR_LC                 (0x00200000)
-#define MCF_FEC_EIMR_EBERR              (0x00400000)
-#define MCF_FEC_EIMR_MII                (0x00800000)
-#define MCF_FEC_EIMR_RXB                (0x01000000)
-#define MCF_FEC_EIMR_RXF                (0x02000000)
-#define MCF_FEC_EIMR_TXB                (0x04000000)
-#define MCF_FEC_EIMR_TXF                (0x08000000)
-#define MCF_FEC_EIMR_GRA                (0x10000000)
-#define MCF_FEC_EIMR_BABT               (0x20000000)
-#define MCF_FEC_EIMR_BABR               (0x40000000)
-#define MCF_FEC_EIMR_HBERR              (0x80000000)
-
-/* Bit definitions and macros for MCF_FEC_RDAR */
-#define MCF_FEC_RDAR_R_DES_ACTIVE       (0x01000000)
-
-/* Bit definitions and macros for MCF_FEC_TDAR */
-#define MCF_FEC_TDAR_X_DES_ACTIVE       (0x01000000)
-
-/* Bit definitions and macros for MCF_FEC_ECR */
-#define MCF_FEC_ECR_RESET               (0x00000001)
-#define MCF_FEC_ECR_ETHER_EN            (0x00000002)
-
-/* Bit definitions and macros for MCF_FEC_MMFR */
-#define MCF_FEC_MMFR_DATA(x)            (((x)&0x0000FFFF)<<0)
-#define MCF_FEC_MMFR_TA(x)              (((x)&0x00000003)<<16)
-#define MCF_FEC_MMFR_RA(x)              (((x)&0x0000001F)<<18)
-#define MCF_FEC_MMFR_PA(x)              (((x)&0x0000001F)<<23)
-#define MCF_FEC_MMFR_OP(x)              (((x)&0x00000003)<<28)
-#define MCF_FEC_MMFR_ST(x)              (((x)&0x00000003)<<30)
-#define MCF_FEC_MMFR_ST_01             (0x40000000)
-#define MCF_FEC_MMFR_OP_READ           (0x20000000)
-#define MCF_FEC_MMFR_OP_WRITE          (0x10000000)
-#define MCF_FEC_MMFR_TA_10             (0x00020000)
-
-
-/* Bit definitions and macros for MCF_FEC_MSCR */
-#define MCF_FEC_MSCR_MII_SPEED(x)       (((x)&0x0000003F)<<1)
-#define MCF_FEC_MSCR_DIS_PREAMBLE       (0x00000080)
-
-/* Bit definitions and macros for MCF_FEC_MIBC */
-#define MCF_FEC_MIBC_MIB_IDLE           (0x40000000)
-#define MCF_FEC_MIBC_MIB_DISABLE        (0x80000000)
-
-/* Bit definitions and macros for MCF_FEC_RCR */
-#define MCF_FEC_RCR_LOOP                (0x00000001)
-#define MCF_FEC_RCR_DRT                 (0x00000002)
-#define MCF_FEC_RCR_MII_MODE            (0x00000004)
-#define MCF_FEC_RCR_PROM                (0x00000008)
-#define MCF_FEC_RCR_BC_REJ              (0x00000010)
-#define MCF_FEC_RCR_FCE                 (0x00000020)
-#define MCF_FEC_RCR_MAX_FL(x)           (((x)&0x000007FF)<<16)
-
-/* Bit definitions and macros for MCF_FEC_TCR */
-#define MCF_FEC_TCR_GTS                 (0x00000001)
-#define MCF_FEC_TCR_HBC                 (0x00000002)
-#define MCF_FEC_TCR_FDEN                (0x00000004)
-#define MCF_FEC_TCR_TFC_PAUSE           (0x00000008)
-#define MCF_FEC_TCR_RFC_PAUSE           (0x00000010)
-
-/* Bit definitions and macros for MCF_FEC_PAUR */
-#define MCF_FEC_PAUR_TYPE(x)            (((x)&0x0000FFFF)<<0)
-#define MCF_FEC_PAUR_PADDR2(x)          (((x)&0x0000FFFF)<<16)
-
-/* Bit definitions and macros for MCF_FEC_OPD */
-#define MCF_FEC_OPD_PAUSE_DUR(x)        (((x)&0x0000FFFF)<<0)
-#define MCF_FEC_OPD_OPCODE(x)           (((x)&0x0000FFFF)<<16)
-
-/* Bit definitions and macros for MCF_FEC_TFWR */
-#define MCF_FEC_TFWR_X_WMRK(x)          (((x)&0x00000003)<<0)
-
-/* Bit definitions and macros for MCF_FEC_FRBR */
-#define MCF_FEC_FRBR_R_BOUND(x)         (((x)&0x000000FF)<<2)
-
-/* Bit definitions and macros for MCF_FEC_FRSR */
-#define MCF_FEC_FRSR_R_FSTART(x)        (((x)&0x000000FF)<<2)
-
-/* Bit definitions and macros for MCF_FEC_ERDSR */
-#define MCF_FEC_ERDSR_R_DES_START(x)    (((x)&0x3FFFFFFF)<<2)
-
-/* Bit definitions and macros for MCF_FEC_ETDSR */
-#define MCF_FEC_ETDSR_X_DES_START(x)    (((x)&0x3FFFFFFF)<<2)
-
-/* Bit definitions and macros for MCF_FEC_EMRBR */
-#define MCF_FEC_EMRBR_R_BUF_SIZE(x)     (((x)&0x0000007F)<<4)
-
-/********************************************************************/
-
-#endif /* __MCF523X_FEC_H__ */
+/*\r
+ * These files are taken from the MCF523X source code example package\r
+ * which is available on the Freescale website. Freescale explicitly \r
+ * grants the redistribution and modification of these source files.\r
+ * The complete licensing information is available in the file \r
+ * LICENSE_FREESCALE.TXT.\r
+ *\r
+ * File:       mcf523x_fec.h\r
+ * Purpose:    Register and bit definitions for the MCF523X\r
+ *\r
+ * Notes:      \r
+ *     \r
+ */\r
+\r
+#ifndef __MCF523X_FEC_H__\r
+#define __MCF523X_FEC_H__\r
+\r
+/*********************************************************************\r
+*\r
+* Fast Ethernet Controller (FEC)\r
+*\r
+*********************************************************************/\r
+\r
+/* Register read/write macros */\r
+#define MCF_FEC_EIR                   (*(vuint32*)(void*)(&__IPSBAR[0x001004]))\r
+#define MCF_FEC_EIMR                  (*(vuint32*)(void*)(&__IPSBAR[0x001008]))\r
+#define MCF_FEC_RDAR                  (*(vuint32*)(void*)(&__IPSBAR[0x001010]))\r
+#define MCF_FEC_TDAR                  (*(vuint32*)(void*)(&__IPSBAR[0x001014]))\r
+#define MCF_FEC_ECR                   (*(vuint32*)(void*)(&__IPSBAR[0x001024]))\r
+#define MCF_FEC_MMFR                  (*(vuint32*)(void*)(&__IPSBAR[0x001040]))\r
+#define MCF_FEC_MSCR                  (*(vuint32*)(void*)(&__IPSBAR[0x001044]))\r
+#define MCF_FEC_MIBC                  (*(vuint32*)(void*)(&__IPSBAR[0x001064]))\r
+#define MCF_FEC_RCR                   (*(vuint32*)(void*)(&__IPSBAR[0x001084]))\r
+#define MCF_FEC_TCR                   (*(vuint32*)(void*)(&__IPSBAR[0x0010C4]))\r
+#define MCF_FEC_PALR                  (*(vuint32*)(void*)(&__IPSBAR[0x0010E4]))\r
+#define MCF_FEC_PAUR                  (*(vuint32*)(void*)(&__IPSBAR[0x0010E8]))\r
+#define MCF_FEC_OPD                   (*(vuint32*)(void*)(&__IPSBAR[0x0010EC]))\r
+#define MCF_FEC_IAUR                  (*(vuint32*)(void*)(&__IPSBAR[0x001118]))\r
+#define MCF_FEC_IALR                  (*(vuint32*)(void*)(&__IPSBAR[0x00111C]))\r
+#define MCF_FEC_GAUR                  (*(vuint32*)(void*)(&__IPSBAR[0x001120]))\r
+#define MCF_FEC_GALR                  (*(vuint32*)(void*)(&__IPSBAR[0x001124]))\r
+#define MCF_FEC_TFWR                  (*(vuint32*)(void*)(&__IPSBAR[0x001144]))\r
+#define MCF_FEC_FRBR                  (*(vuint32*)(void*)(&__IPSBAR[0x00114C]))\r
+#define MCF_FEC_FRSR                  (*(vuint32*)(void*)(&__IPSBAR[0x001150]))\r
+#define MCF_FEC_ERDSR                 (*(vuint32*)(void*)(&__IPSBAR[0x001180]))\r
+#define MCF_FEC_ETDSR                 (*(vuint32*)(void*)(&__IPSBAR[0x001184]))\r
+#define MCF_FEC_EMRBR                 (*(vuint32*)(void*)(&__IPSBAR[0x001188]))\r
+#define MCF_FEC_RMON_T_DROP           (*(vuint32*)(void*)(&__IPSBAR[0x001200]))\r
+#define MCF_FEC_RMON_T_PACKETS        (*(vuint32*)(void*)(&__IPSBAR[0x001204]))\r
+#define MCF_FEC_RMON_T_BC_PKT         (*(vuint32*)(void*)(&__IPSBAR[0x001208]))\r
+#define MCF_FEC_RMON_T_MC_PKT         (*(vuint32*)(void*)(&__IPSBAR[0x00120C]))\r
+#define MCF_FEC_RMON_T_CRC_ALIGN      (*(vuint32*)(void*)(&__IPSBAR[0x001210]))\r
+#define MCF_FEC_RMON_T_UNDERSIZE      (*(vuint32*)(void*)(&__IPSBAR[0x001214]))\r
+#define MCF_FEC_RMON_T_OVERSIZE       (*(vuint32*)(void*)(&__IPSBAR[0x001218]))\r
+#define MCF_FEC_RMON_T_FRAG           (*(vuint32*)(void*)(&__IPSBAR[0x00121C]))\r
+#define MCF_FEC_RMON_T_JAB            (*(vuint32*)(void*)(&__IPSBAR[0x001220]))\r
+#define MCF_FEC_RMON_T_COL            (*(vuint32*)(void*)(&__IPSBAR[0x001224]))\r
+#define MCF_FEC_RMON_T_P64            (*(vuint32*)(void*)(&__IPSBAR[0x001228]))\r
+#define MCF_FEC_RMON_T_P65TO127       (*(vuint32*)(void*)(&__IPSBAR[0x00122C]))\r
+#define MCF_FEC_RMON_T_P128TO255      (*(vuint32*)(void*)(&__IPSBAR[0x001230]))\r
+#define MCF_FEC_RMON_T_P256TO511      (*(vuint32*)(void*)(&__IPSBAR[0x001234]))\r
+#define MCF_FEC_RMON_T_P512TO1023     (*(vuint32*)(void*)(&__IPSBAR[0x001238]))\r
+#define MCF_FEC_RMON_T_P1024TO2047    (*(vuint32*)(void*)(&__IPSBAR[0x00123C]))\r
+#define MCF_FEC_RMON_T_P_GTE2048      (*(vuint32*)(void*)(&__IPSBAR[0x001240]))\r
+#define MCF_FEC_RMON_T_OCTETS         (*(vuint32*)(void*)(&__IPSBAR[0x001244]))\r
+#define MCF_FEC_IEEE_T_DROP           (*(vuint32*)(void*)(&__IPSBAR[0x001248]))\r
+#define MCF_FEC_IEEE_T_FRAME_OK       (*(vuint32*)(void*)(&__IPSBAR[0x00124C]))\r
+#define MCF_FEC_IEEE_T_1COL           (*(vuint32*)(void*)(&__IPSBAR[0x001250]))\r
+#define MCF_FEC_IEEE_T_MCOL           (*(vuint32*)(void*)(&__IPSBAR[0x001254]))\r
+#define MCF_FEC_IEEE_T_DEF            (*(vuint32*)(void*)(&__IPSBAR[0x001258]))\r
+#define MCF_FEC_IEEE_T_LCOL           (*(vuint32*)(void*)(&__IPSBAR[0x00125C]))\r
+#define MCF_FEC_IEEE_T_EXCOL          (*(vuint32*)(void*)(&__IPSBAR[0x001260]))\r
+#define MCF_FEC_IEEE_T_MACERR         (*(vuint32*)(void*)(&__IPSBAR[0x001264]))\r
+#define MCF_FEC_IEEE_T_CSERR          (*(vuint32*)(void*)(&__IPSBAR[0x001268]))\r
+#define MCF_FEC_IEEE_T_SQE            (*(vuint32*)(void*)(&__IPSBAR[0x00126C]))\r
+#define MCF_FEC_IEEE_T_FDXFC          (*(vuint32*)(void*)(&__IPSBAR[0x001270]))\r
+#define MCF_FEC_IEEE_T_OCTETS_OK      (*(vuint32*)(void*)(&__IPSBAR[0x001274]))\r
+#define MCF_FEC_RMON_R_PACKETS        (*(vuint32*)(void*)(&__IPSBAR[0x001284]))\r
+#define MCF_FEC_RMON_R_BC_PKT         (*(vuint32*)(void*)(&__IPSBAR[0x001288]))\r
+#define MCF_FEC_RMON_R_MC_PKT         (*(vuint32*)(void*)(&__IPSBAR[0x00128C]))\r
+#define MCF_FEC_RMON_R_CRC_ALIGN      (*(vuint32*)(void*)(&__IPSBAR[0x001290]))\r
+#define MCF_FEC_RMON_R_UNDERSIZE      (*(vuint32*)(void*)(&__IPSBAR[0x001294]))\r
+#define MCF_FEC_RMON_R_OVERSIZE       (*(vuint32*)(void*)(&__IPSBAR[0x001298]))\r
+#define MCF_FEC_RMON_R_FRAG           (*(vuint32*)(void*)(&__IPSBAR[0x00129C]))\r
+#define MCF_FEC_RMON_R_JAB            (*(vuint32*)(void*)(&__IPSBAR[0x0012A0]))\r
+#define MCF_FEC_RMON_R_RESVD_0        (*(vuint32*)(void*)(&__IPSBAR[0x0012A4]))\r
+#define MCF_FEC_RMON_R_P64            (*(vuint32*)(void*)(&__IPSBAR[0x0012A8]))\r
+#define MCF_FEC_RMON_R_P65TO127       (*(vuint32*)(void*)(&__IPSBAR[0x0012AC]))\r
+#define MCF_FEC_RMON_R_P128TO255      (*(vuint32*)(void*)(&__IPSBAR[0x0012B0]))\r
+#define MCF_FEC_RMON_R_P256TO511      (*(vuint32*)(void*)(&__IPSBAR[0x0012B4]))\r
+#define MCF_FEC_RMON_R_512TO1023      (*(vuint32*)(void*)(&__IPSBAR[0x0012B8]))\r
+#define MCF_FEC_RMON_R_P_GTE2048      (*(vuint32*)(void*)(&__IPSBAR[0x0012C0]))\r
+#define MCF_FEC_RMON_R_1024TO2047     (*(vuint32*)(void*)(&__IPSBAR[0x0012BC]))\r
+#define MCF_FEC_RMON_R_OCTETS         (*(vuint32*)(void*)(&__IPSBAR[0x0012C4]))\r
+#define MCF_FEC_IEEE_R_DROP           (*(vuint32*)(void*)(&__IPSBAR[0x0012C8]))\r
+#define MCF_FEC_IEEE_R_FRAME_OK       (*(vuint32*)(void*)(&__IPSBAR[0x0012CC]))\r
+#define MCF_FEC_IEEE_R_CRC            (*(vuint32*)(void*)(&__IPSBAR[0x0012D0]))\r
+#define MCF_FEC_IEEE_R_ALIGN          (*(vuint32*)(void*)(&__IPSBAR[0x0012D4]))\r
+#define MCF_FEC_IEEE_R_MACERR         (*(vuint32*)(void*)(&__IPSBAR[0x0012D8]))\r
+#define MCF_FEC_IEEE_R_FDXFC          (*(vuint32*)(void*)(&__IPSBAR[0x0012DC]))\r
+#define MCF_FEC_IEEE_R_OCTETS_OK      (*(vuint32*)(void*)(&__IPSBAR[0x0012E0]))\r
+\r
+/* Bit definitions and macros for MCF_FEC_EIR */\r
+#define MCF_FEC_EIR_UN                  (0x00080000)\r
+#define MCF_FEC_EIR_RL                  (0x00100000)\r
+#define MCF_FEC_EIR_LC                  (0x00200000)\r
+#define MCF_FEC_EIR_EBERR               (0x00400000)\r
+#define MCF_FEC_EIR_MII                 (0x00800000)\r
+#define MCF_FEC_EIR_RXB                 (0x01000000)\r
+#define MCF_FEC_EIR_RXF                 (0x02000000)\r
+#define MCF_FEC_EIR_TXB                 (0x04000000)\r
+#define MCF_FEC_EIR_TXF                 (0x08000000)\r
+#define MCF_FEC_EIR_GRA                 (0x10000000)\r
+#define MCF_FEC_EIR_BABT                (0x20000000)\r
+#define MCF_FEC_EIR_BABR                (0x40000000)\r
+#define MCF_FEC_EIR_HBERR               (0x80000000)\r
+\r
+/* Bit definitions and macros for MCF_FEC_EIMR */\r
+#define MCF_FEC_EIMR_UN                 (0x00080000)\r
+#define MCF_FEC_EIMR_RL                 (0x00100000)\r
+#define MCF_FEC_EIMR_LC                 (0x00200000)\r
+#define MCF_FEC_EIMR_EBERR              (0x00400000)\r
+#define MCF_FEC_EIMR_MII                (0x00800000)\r
+#define MCF_FEC_EIMR_RXB                (0x01000000)\r
+#define MCF_FEC_EIMR_RXF                (0x02000000)\r
+#define MCF_FEC_EIMR_TXB                (0x04000000)\r
+#define MCF_FEC_EIMR_TXF                (0x08000000)\r
+#define MCF_FEC_EIMR_GRA                (0x10000000)\r
+#define MCF_FEC_EIMR_BABT               (0x20000000)\r
+#define MCF_FEC_EIMR_BABR               (0x40000000)\r
+#define MCF_FEC_EIMR_HBERR              (0x80000000)\r
+\r
+/* Bit definitions and macros for MCF_FEC_RDAR */\r
+#define MCF_FEC_RDAR_R_DES_ACTIVE       (0x01000000)\r
+\r
+/* Bit definitions and macros for MCF_FEC_TDAR */\r
+#define MCF_FEC_TDAR_X_DES_ACTIVE       (0x01000000)\r
+\r
+/* Bit definitions and macros for MCF_FEC_ECR */\r
+#define MCF_FEC_ECR_RESET               (0x00000001)\r
+#define MCF_FEC_ECR_ETHER_EN            (0x00000002)\r
+\r
+/* Bit definitions and macros for MCF_FEC_MMFR */\r
+#define MCF_FEC_MMFR_DATA(x)            (((x)&0x0000FFFF)<<0)\r
+#define MCF_FEC_MMFR_TA(x)              (((x)&0x00000003)<<16)\r
+#define MCF_FEC_MMFR_RA(x)              (((x)&0x0000001F)<<18)\r
+#define MCF_FEC_MMFR_PA(x)              (((x)&0x0000001F)<<23)\r
+#define MCF_FEC_MMFR_OP(x)              (((x)&0x00000003)<<28)\r
+#define MCF_FEC_MMFR_ST(x)              (((x)&0x00000003)<<30)\r
+#define MCF_FEC_MMFR_ST_01             (0x40000000)\r
+#define MCF_FEC_MMFR_OP_READ           (0x20000000)\r
+#define MCF_FEC_MMFR_OP_WRITE          (0x10000000)\r
+#define MCF_FEC_MMFR_TA_10             (0x00020000)\r
+\r
+\r
+/* Bit definitions and macros for MCF_FEC_MSCR */\r
+#define MCF_FEC_MSCR_MII_SPEED(x)       (((x)&0x0000003F)<<1)\r
+#define MCF_FEC_MSCR_DIS_PREAMBLE       (0x00000080)\r
+\r
+/* Bit definitions and macros for MCF_FEC_MIBC */\r
+#define MCF_FEC_MIBC_MIB_IDLE           (0x40000000)\r
+#define MCF_FEC_MIBC_MIB_DISABLE        (0x80000000)\r
+\r
+/* Bit definitions and macros for MCF_FEC_RCR */\r
+#define MCF_FEC_RCR_LOOP                (0x00000001)\r
+#define MCF_FEC_RCR_DRT                 (0x00000002)\r
+#define MCF_FEC_RCR_MII_MODE            (0x00000004)\r
+#define MCF_FEC_RCR_PROM                (0x00000008)\r
+#define MCF_FEC_RCR_BC_REJ              (0x00000010)\r
+#define MCF_FEC_RCR_FCE                 (0x00000020)\r
+#define MCF_FEC_RCR_MAX_FL(x)           (((x)&0x000007FF)<<16)\r
+\r
+/* Bit definitions and macros for MCF_FEC_TCR */\r
+#define MCF_FEC_TCR_GTS                 (0x00000001)\r
+#define MCF_FEC_TCR_HBC                 (0x00000002)\r
+#define MCF_FEC_TCR_FDEN                (0x00000004)\r
+#define MCF_FEC_TCR_TFC_PAUSE           (0x00000008)\r
+#define MCF_FEC_TCR_RFC_PAUSE           (0x00000010)\r
+\r
+/* Bit definitions and macros for MCF_FEC_PAUR */\r
+#define MCF_FEC_PAUR_TYPE(x)            (((x)&0x0000FFFF)<<0)\r
+#define MCF_FEC_PAUR_PADDR2(x)          (((x)&0x0000FFFF)<<16)\r
+\r
+/* Bit definitions and macros for MCF_FEC_OPD */\r
+#define MCF_FEC_OPD_PAUSE_DUR(x)        (((x)&0x0000FFFF)<<0)\r
+#define MCF_FEC_OPD_OPCODE(x)           (((x)&0x0000FFFF)<<16)\r
+\r
+/* Bit definitions and macros for MCF_FEC_TFWR */\r
+#define MCF_FEC_TFWR_X_WMRK(x)          (((x)&0x00000003)<<0)\r
+\r
+/* Bit definitions and macros for MCF_FEC_FRBR */\r
+#define MCF_FEC_FRBR_R_BOUND(x)         (((x)&0x000000FF)<<2)\r
+\r
+/* Bit definitions and macros for MCF_FEC_FRSR */\r
+#define MCF_FEC_FRSR_R_FSTART(x)        (((x)&0x000000FF)<<2)\r
+\r
+/* Bit definitions and macros for MCF_FEC_ERDSR */\r
+#define MCF_FEC_ERDSR_R_DES_START(x)    (((x)&0x3FFFFFFF)<<2)\r
+\r
+/* Bit definitions and macros for MCF_FEC_ETDSR */\r
+#define MCF_FEC_ETDSR_X_DES_START(x)    (((x)&0x3FFFFFFF)<<2)\r
+\r
+/* Bit definitions and macros for MCF_FEC_EMRBR */\r
+#define MCF_FEC_EMRBR_R_BUF_SIZE(x)     (((x)&0x0000007F)<<4)\r
+\r
+/********************************************************************/\r
+\r
+#endif /* __MCF523X_FEC_H__ */\r
index d9dc941d46401b55dc2b06215cd0bb7ae14f2ef4..3f132e896a56e1e05a41e328cf3043a3d0596d74 100644 (file)
@@ -1,55 +1,55 @@
-/*
- * These files are taken from the MCF523X source code example package
- * which is available on the Freescale website. Freescale explicitly 
- * grants the redistribution and modification of these source files.
- * The complete licensing information is available in the file 
- * LICENSE_FREESCALE.TXT.
- *
- * File:       mcf523x_fmpll.h
- * Purpose:    Register and bit definitions for the MCF523X
- *
- * Notes:      
- *     
- */
-
-#ifndef __MCF523X_FMPLL_H__
-#define __MCF523X_FMPLL_H__
-
-/*********************************************************************
-*
-* Frequency Modulated Phase Locked Loop (FMPLL)
-*
-*********************************************************************/
-
-/* Register read/write macros */
-#define MCF_FMPLL_SYNCR    (*(vuint32*)(void*)(&__IPSBAR[0x120000]))
-#define MCF_FMPLL_SYNSR    (*(vuint32*)(void*)(&__IPSBAR[0x120004]))
-
-/* Bit definitions and macros for MCF_FMPLL_SYNCR */
-#define MCF_FMPLL_SYNCR_EXP(x)       (((x)&0x000003FF)<<0)
-#define MCF_FMPLL_SYNCR_DEPTH(x)     (((x)&0x00000003)<<10)
-#define MCF_FMPLL_SYNCR_RATE         (0x00001000)
-#define MCF_FMPLL_SYNCR_LOCIRQ       (0x00002000)
-#define MCF_FMPLL_SYNCR_LOLIRQ       (0x00004000)
-#define MCF_FMPLL_SYNCR_DISCLK       (0x00008000)
-#define MCF_FMPLL_SYNCR_LOCRE        (0x00010000)
-#define MCF_FMPLL_SYNCR_LOLRE        (0x00020000)
-#define MCF_FMPLL_SYNCR_LOCEN        (0x00040000)
-#define MCF_FMPLL_SYNCR_RFD(x)       (((x)&0x00000007)<<19)
-#define MCF_FMPLL_SYNCR_MFD(x)       (((x)&0x00000007)<<24)
-
-/* Bit definitions and macros for MCF_FMPLL_SYNSR */
-#define MCF_FMPLL_SYNSR_CALPASS      (0x00000001)
-#define MCF_FMPLL_SYNSR_CALDONE      (0x00000002)
-#define MCF_FMPLL_SYNSR_LOCF         (0x00000004)
-#define MCF_FMPLL_SYNSR_LOCK         (0x00000008)
-#define MCF_FMPLL_SYNSR_LOCKS        (0x00000010)
-#define MCF_FMPLL_SYNSR_PLLREF       (0x00000020)
-#define MCF_FMPLL_SYNSR_PLLSEL       (0x00000040)
-#define MCF_FMPLL_SYNSR_MODE         (0x00000080)
-#define MCF_FMPLL_SYNSR_LOC          (0x00000100)
-#define MCF_FMPLL_SYNSR_LOLF         (0x00000200)
-
-/********************************************************************/
-
-#endif /* __MCF523X_FMPLL_H__ */
+/*\r
+ * These files are taken from the MCF523X source code example package\r
+ * which is available on the Freescale website. Freescale explicitly \r
+ * grants the redistribution and modification of these source files.\r
+ * The complete licensing information is available in the file \r
+ * LICENSE_FREESCALE.TXT.\r
+ *\r
+ * File:       mcf523x_fmpll.h\r
+ * Purpose:    Register and bit definitions for the MCF523X\r
+ *\r
+ * Notes:      \r
+ *     \r
+ */\r
+\r
+#ifndef __MCF523X_FMPLL_H__\r
+#define __MCF523X_FMPLL_H__\r
+\r
+/*********************************************************************\r
+*\r
+* Frequency Modulated Phase Locked Loop (FMPLL)\r
+*\r
+*********************************************************************/\r
+\r
+/* Register read/write macros */\r
+#define MCF_FMPLL_SYNCR    (*(vuint32*)(void*)(&__IPSBAR[0x120000]))\r
+#define MCF_FMPLL_SYNSR    (*(vuint32*)(void*)(&__IPSBAR[0x120004]))\r
+\r
+/* Bit definitions and macros for MCF_FMPLL_SYNCR */\r
+#define MCF_FMPLL_SYNCR_EXP(x)       (((x)&0x000003FF)<<0)\r
+#define MCF_FMPLL_SYNCR_DEPTH(x)     (((x)&0x00000003)<<10)\r
+#define MCF_FMPLL_SYNCR_RATE         (0x00001000)\r
+#define MCF_FMPLL_SYNCR_LOCIRQ       (0x00002000)\r
+#define MCF_FMPLL_SYNCR_LOLIRQ       (0x00004000)\r
+#define MCF_FMPLL_SYNCR_DISCLK       (0x00008000)\r
+#define MCF_FMPLL_SYNCR_LOCRE        (0x00010000)\r
+#define MCF_FMPLL_SYNCR_LOLRE        (0x00020000)\r
+#define MCF_FMPLL_SYNCR_LOCEN        (0x00040000)\r
+#define MCF_FMPLL_SYNCR_RFD(x)       (((x)&0x00000007)<<19)\r
+#define MCF_FMPLL_SYNCR_MFD(x)       (((x)&0x00000007)<<24)\r
+\r
+/* Bit definitions and macros for MCF_FMPLL_SYNSR */\r
+#define MCF_FMPLL_SYNSR_CALPASS      (0x00000001)\r
+#define MCF_FMPLL_SYNSR_CALDONE      (0x00000002)\r
+#define MCF_FMPLL_SYNSR_LOCF         (0x00000004)\r
+#define MCF_FMPLL_SYNSR_LOCK         (0x00000008)\r
+#define MCF_FMPLL_SYNSR_LOCKS        (0x00000010)\r
+#define MCF_FMPLL_SYNSR_PLLREF       (0x00000020)\r
+#define MCF_FMPLL_SYNSR_PLLSEL       (0x00000040)\r
+#define MCF_FMPLL_SYNSR_MODE         (0x00000080)\r
+#define MCF_FMPLL_SYNSR_LOC          (0x00000100)\r
+#define MCF_FMPLL_SYNSR_LOLF         (0x00000200)\r
+\r
+/********************************************************************/\r
+\r
+#endif /* __MCF523X_FMPLL_H__ */\r
index 455ac850ddea9c994238ae6157ddb8f2ea96ff0e..df8c366001d481f9b41bc1a595dc035c719e5861 100644 (file)
-/*
- * These files are taken from the MCF523X source code example package
- * which is available on the Freescale website. Freescale explicitly 
- * grants the redistribution and modification of these source files.
- * The complete licensing information is available in the file 
- * LICENSE_FREESCALE.TXT.
- *
- * File:       mcf523x_gpio.h
- * Purpose:    Register and bit definitions for the MCF523X
- *
- * Notes:      
- *     
- */
-
-#ifndef __MCF523X_GPIO_H__
-#define __MCF523X_GPIO_H__
-
-/*********************************************************************
-*
-* General Purpose I/O (GPIO)
-*
-*********************************************************************/
-
-/* Register read/write macros */
-#define MCF_GPIO_PODR_ADDR        (*(vuint8 *)(void*)(&__IPSBAR[0x100000]))
-#define MCF_GPIO_PODR_DATAH       (*(vuint8 *)(void*)(&__IPSBAR[0x100001]))
-#define MCF_GPIO_PODR_DATAL       (*(vuint8 *)(void*)(&__IPSBAR[0x100002]))
-#define MCF_GPIO_PODR_BUSCTL      (*(vuint8 *)(void*)(&__IPSBAR[0x100003]))
-#define MCF_GPIO_PODR_BS          (*(vuint8 *)(void*)(&__IPSBAR[0x100004]))
-#define MCF_GPIO_PODR_CS          (*(vuint8 *)(void*)(&__IPSBAR[0x100005]))
-#define MCF_GPIO_PODR_SDRAM       (*(vuint8 *)(void*)(&__IPSBAR[0x100006]))
-#define MCF_GPIO_PODR_FECI2C      (*(vuint8 *)(void*)(&__IPSBAR[0x100007]))
-#define MCF_GPIO_PODR_UARTH       (*(vuint8 *)(void*)(&__IPSBAR[0x100008]))
-#define MCF_GPIO_PODR_UARTL       (*(vuint8 *)(void*)(&__IPSBAR[0x100009]))
-#define MCF_GPIO_PODR_QSPI        (*(vuint8 *)(void*)(&__IPSBAR[0x10000A]))
-#define MCF_GPIO_PODR_TIMER       (*(vuint8 *)(void*)(&__IPSBAR[0x10000B]))
-#define MCF_GPIO_PODR_ETPU        (*(vuint8 *)(void*)(&__IPSBAR[0x10000C]))
-#define MCF_GPIO_PDDR_APDDR       (*(vuint8 *)(void*)(&__IPSBAR[0x100010]))
-#define MCF_GPIO_PDDR_DATAH       (*(vuint8 *)(void*)(&__IPSBAR[0x100011]))
-#define MCF_GPIO_PDDR_DATAL       (*(vuint8 *)(void*)(&__IPSBAR[0x100012]))
-#define MCF_GPIO_PDDR_BUSCTL      (*(vuint8 *)(void*)(&__IPSBAR[0x100013]))
-#define MCF_GPIO_PDDR_BS          (*(vuint8 *)(void*)(&__IPSBAR[0x100014]))
-#define MCF_GPIO_PDDR_CS          (*(vuint8 *)(void*)(&__IPSBAR[0x100015]))
-#define MCF_GPIO_PDDR_SDRAM       (*(vuint8 *)(void*)(&__IPSBAR[0x100016]))
-#define MCF_GPIO_PDDR_FECI2C      (*(vuint8 *)(void*)(&__IPSBAR[0x100017]))
-#define MCF_GPIO_PDDR_UARTH       (*(vuint8 *)(void*)(&__IPSBAR[0x100018]))
-#define MCF_GPIO_PDDR_UARTL       (*(vuint8 *)(void*)(&__IPSBAR[0x100019]))
-#define MCF_GPIO_PDDR_QSPI        (*(vuint8 *)(void*)(&__IPSBAR[0x10001A]))
-#define MCF_GPIO_PDDR_TIMER       (*(vuint8 *)(void*)(&__IPSBAR[0x10001B]))
-#define MCF_GPIO_PDDR_ETPU        (*(vuint8 *)(void*)(&__IPSBAR[0x10001C]))
-#define MCF_GPIO_PPDSDR_ADDR      (*(vuint8 *)(void*)(&__IPSBAR[0x100020]))
-#define MCF_GPIO_PPDSDR_DATAH     (*(vuint8 *)(void*)(&__IPSBAR[0x100021]))
-#define MCF_GPIO_PPDSDR_DATAL     (*(vuint8 *)(void*)(&__IPSBAR[0x100022]))
-#define MCF_GPIO_PPDSDR_BUSCTL    (*(vuint8 *)(void*)(&__IPSBAR[0x100023]))
-#define MCF_GPIO_PPDSDR_BS        (*(vuint8 *)(void*)(&__IPSBAR[0x100024]))
-#define MCF_GPIO_PPDSDR_FECI2C    (*(vuint8 *)(void*)(&__IPSBAR[0x100027]))
-#define MCF_GPIO_PPDSDR_CS        (*(vuint8 *)(void*)(&__IPSBAR[0x100025]))
-#define MCF_GPIO_PPDSDR_SDRAM     (*(vuint8 *)(void*)(&__IPSBAR[0x100026]))
-#define MCF_GPIO_PPDSDR_UARTH     (*(vuint8 *)(void*)(&__IPSBAR[0x100028]))
-#define MCF_GPIO_PPDSDR_UARTL     (*(vuint8 *)(void*)(&__IPSBAR[0x100029]))
-#define MCF_GPIO_PPDSDR_QSPI      (*(vuint8 *)(void*)(&__IPSBAR[0x10002A]))
-#define MCF_GPIO_PPDSDR_TIMER     (*(vuint8 *)(void*)(&__IPSBAR[0x10002B]))
-#define MCF_GPIO_PPDSDR_ETPU      (*(vuint8 *)(void*)(&__IPSBAR[0x10002C]))
-#define MCF_GPIO_PCLRR_ADDR       (*(vuint8 *)(void*)(&__IPSBAR[0x100030]))
-#define MCF_GPIO_PCLRR_DATAH      (*(vuint8 *)(void*)(&__IPSBAR[0x100031]))
-#define MCF_GPIO_PCLRR_DATAL      (*(vuint8 *)(void*)(&__IPSBAR[0x100032]))
-#define MCF_GPIO_PCLRR_BUSCTL     (*(vuint8 *)(void*)(&__IPSBAR[0x100033]))
-#define MCF_GPIO_PCLRR_BS         (*(vuint8 *)(void*)(&__IPSBAR[0x100034]))
-#define MCF_GPIO_PCLRR_CS         (*(vuint8 *)(void*)(&__IPSBAR[0x100035]))
-#define MCF_GPIO_PCLRR_SDRAM      (*(vuint8 *)(void*)(&__IPSBAR[0x100036]))
-#define MCF_GPIO_PCLRR_FECI2C     (*(vuint8 *)(void*)(&__IPSBAR[0x100037]))
-#define MCF_GPIO_PCLRR_UARTH      (*(vuint8 *)(void*)(&__IPSBAR[0x100038]))
-#define MCF_GPIO_PCLRR_UARTL      (*(vuint8 *)(void*)(&__IPSBAR[0x100039]))
-#define MCF_GPIO_PCLRR_QSPI       (*(vuint8 *)(void*)(&__IPSBAR[0x10003A]))
-#define MCF_GPIO_PCLRR_TIMER      (*(vuint8 *)(void*)(&__IPSBAR[0x10003B]))
-#define MCF_GPIO_PCLRR_ETPU       (*(vuint8 *)(void*)(&__IPSBAR[0x10003C]))
-#define MCF_GPIO_PAR_AD           (*(vuint8 *)(void*)(&__IPSBAR[0x100040]))
-#define MCF_GPIO_PAR_BUSCTL       (*(vuint16*)(void*)(&__IPSBAR[0x100042]))
-#define MCF_GPIO_PAR_BS           (*(vuint8 *)(void*)(&__IPSBAR[0x100044]))
-#define MCF_GPIO_PAR_CS           (*(vuint8 *)(void*)(&__IPSBAR[0x100045]))
-#define MCF_GPIO_PAR_SDRAM        (*(vuint8 *)(void*)(&__IPSBAR[0x100046]))
-#define MCF_GPIO_PAR_FECI2C       (*(vuint8 *)(void*)(&__IPSBAR[0x100047]))
-#define MCF_GPIO_PAR_UART         (*(vuint16*)(void*)(&__IPSBAR[0x100048]))
-#define MCF_GPIO_PAR_QSPI         (*(vuint8 *)(void*)(&__IPSBAR[0x10004A]))
-#define MCF_GPIO_PAR_TIMER        (*(vuint16*)(void*)(&__IPSBAR[0x10004C]))
-#define MCF_GPIO_PAR_ETPU         (*(vuint8 *)(void*)(&__IPSBAR[0x10004E]))
-#define MCF_GPIO_DSCR_EIM         (*(vuint8 *)(void*)(&__IPSBAR[0x100050]))
-#define MCF_GPIO_DSCR_ETPU        (*(vuint8 *)(void*)(&__IPSBAR[0x100051]))
-#define MCF_GPIO_DSCR_FECI2C      (*(vuint8 *)(void*)(&__IPSBAR[0x100052]))
-#define MCF_GPIO_DSCR_UART        (*(vuint8 *)(void*)(&__IPSBAR[0x100053]))
-#define MCF_GPIO_DSCR_QSPI        (*(vuint8 *)(void*)(&__IPSBAR[0x100054]))
-#define MCF_GPIO_DSCR_TIMER       (*(vuint8 *)(void*)(&__IPSBAR[0x100055]))
-
-/* Bit definitions and macros for MCF_GPIO_PODR_ADDR */
-#define MCF_GPIO_PODR_ADDR_PODR_ADDR5            (0x20)
-#define MCF_GPIO_PODR_ADDR_PODR_ADDR6            (0x40)
-#define MCF_GPIO_PODR_ADDR_PODR_ADDR7            (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PODR_DATAH */
-#define MCF_GPIO_PODR_DATAH_PODR_DATAH0          (0x01)
-#define MCF_GPIO_PODR_DATAH_PODR_DATAH1          (0x02)
-#define MCF_GPIO_PODR_DATAH_PODR_DATAH2          (0x04)
-#define MCF_GPIO_PODR_DATAH_PODR_DATAH3          (0x08)
-#define MCF_GPIO_PODR_DATAH_PODR_DATAH4          (0x10)
-#define MCF_GPIO_PODR_DATAH_PODR_DATAH5          (0x20)
-#define MCF_GPIO_PODR_DATAH_PODR_DATAH6          (0x40)
-#define MCF_GPIO_PODR_DATAH_PODR_DATAH7          (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PODR_DATAL */
-#define MCF_GPIO_PODR_DATAL_PODR_DATAL0          (0x01)
-#define MCF_GPIO_PODR_DATAL_PODR_DATAL1          (0x02)
-#define MCF_GPIO_PODR_DATAL_PODR_DATAL2          (0x04)
-#define MCF_GPIO_PODR_DATAL_PODR_DATAL3          (0x08)
-#define MCF_GPIO_PODR_DATAL_PODR_DATAL4          (0x10)
-#define MCF_GPIO_PODR_DATAL_PODR_DATAL5          (0x20)
-#define MCF_GPIO_PODR_DATAL_PODR_DATAL6          (0x40)
-#define MCF_GPIO_PODR_DATAL_PODR_DATAL7          (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PODR_BUSCTL */
-#define MCF_GPIO_PODR_BUSCTL_PODR_BUSCTL0        (0x01)
-#define MCF_GPIO_PODR_BUSCTL_PODR_BUSCTL1        (0x02)
-#define MCF_GPIO_PODR_BUSCTL_PODR_BUSCTL2        (0x04)
-#define MCF_GPIO_PODR_BUSCTL_PODR_BUSCTL3        (0x08)
-#define MCF_GPIO_PODR_BUSCTL_PODR_BUSCTL4        (0x10)
-#define MCF_GPIO_PODR_BUSCTL_PODR_BUSCTL5        (0x20)
-#define MCF_GPIO_PODR_BUSCTL_PODR_BUSCTL6        (0x40)
-#define MCF_GPIO_PODR_BUSCTL_PODR_BUSCTL7        (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PODR_BS */
-#define MCF_GPIO_PODR_BS_PODR_BS0                (0x01)
-#define MCF_GPIO_PODR_BS_PODR_BS1                (0x02)
-#define MCF_GPIO_PODR_BS_PODR_BS2                (0x04)
-#define MCF_GPIO_PODR_BS_PODR_BS3                (0x08)
-
-/* Bit definitions and macros for MCF_GPIO_PODR_CS */
-#define MCF_GPIO_PODR_CS_PODR_CS1                (0x02)
-#define MCF_GPIO_PODR_CS_PODR_CS2                (0x04)
-#define MCF_GPIO_PODR_CS_PODR_CS3                (0x08)
-#define MCF_GPIO_PODR_CS_PODR_CS4                (0x10)
-#define MCF_GPIO_PODR_CS_PODR_CS5                (0x20)
-#define MCF_GPIO_PODR_CS_PODR_CS6                (0x40)
-#define MCF_GPIO_PODR_CS_PODR_CS7                (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PODR_SDRAM */
-#define MCF_GPIO_PODR_SDRAM_PODR_SDRAM0          (0x01)
-#define MCF_GPIO_PODR_SDRAM_PODR_SDRAM1          (0x02)
-#define MCF_GPIO_PODR_SDRAM_PODR_SDRAM2          (0x04)
-#define MCF_GPIO_PODR_SDRAM_PODR_SDRAM3          (0x08)
-#define MCF_GPIO_PODR_SDRAM_PODR_SDRAM4          (0x10)
-#define MCF_GPIO_PODR_SDRAM_PODR_SDRAM5          (0x20)
-
-/* Bit definitions and macros for MCF_GPIO_PODR_FECI2C */
-#define MCF_GPIO_PODR_FECI2C_PODR_FECI2C0        (0x01)
-#define MCF_GPIO_PODR_FECI2C_PODR_FECI2C1        (0x02)
-#define MCF_GPIO_PODR_FECI2C_PODR_FECI2C2        (0x04)
-#define MCF_GPIO_PODR_FECI2C_PODR_FECI2C3        (0x08)
-
-/* Bit definitions and macros for MCF_GPIO_PODR_UARTH */
-#define MCF_GPIO_PODR_UARTH_PODR_UARTH0          (0x01)
-#define MCF_GPIO_PODR_UARTH_PODR_UARTH1          (0x02)
-
-/* Bit definitions and macros for MCF_GPIO_PODR_UARTL */
-#define MCF_GPIO_PODR_UARTL_PODR_UARTL0          (0x01)
-#define MCF_GPIO_PODR_UARTL_PODR_UARTL1          (0x02)
-#define MCF_GPIO_PODR_UARTL_PODR_UARTL2          (0x04)
-#define MCF_GPIO_PODR_UARTL_PODR_UARTL3          (0x08)
-#define MCF_GPIO_PODR_UARTL_PODR_UARTL4          (0x10)
-#define MCF_GPIO_PODR_UARTL_PODR_UARTL5          (0x20)
-#define MCF_GPIO_PODR_UARTL_PODR_UARTL6          (0x40)
-#define MCF_GPIO_PODR_UARTL_PODR_UARTL7          (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PODR_QSPI */
-#define MCF_GPIO_PODR_QSPI_PODR_QSPI0            (0x01)
-#define MCF_GPIO_PODR_QSPI_PODR_QSPI1            (0x02)
-#define MCF_GPIO_PODR_QSPI_PODR_QSPI2            (0x04)
-#define MCF_GPIO_PODR_QSPI_PODR_QSPI3            (0x08)
-#define MCF_GPIO_PODR_QSPI_PODR_QSPI4            (0x10)
-
-/* Bit definitions and macros for MCF_GPIO_PODR_TIMER */
-#define MCF_GPIO_PODR_TIMER_PODR_TIMER0          (0x01)
-#define MCF_GPIO_PODR_TIMER_PODR_TIMER1          (0x02)
-#define MCF_GPIO_PODR_TIMER_PODR_TIMER2          (0x04)
-#define MCF_GPIO_PODR_TIMER_PODR_TIMER3          (0x08)
-#define MCF_GPIO_PODR_TIMER_PODR_TIMER4          (0x10)
-#define MCF_GPIO_PODR_TIMER_PODR_TIMER5          (0x20)
-#define MCF_GPIO_PODR_TIMER_PODR_TIMER6          (0x40)
-#define MCF_GPIO_PODR_TIMER_PODR_TIMER7          (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PODR_ETPU */
-#define MCF_GPIO_PODR_ETPU_PODR_ETPU0            (0x01)
-#define MCF_GPIO_PODR_ETPU_PODR_ETPU1            (0x02)
-#define MCF_GPIO_PODR_ETPU_PODR_ETPU2            (0x04)
-
-/* Bit definitions and macros for MCF_GPIO_PDDR_APDDR */
-#define MCF_GPIO_PDDR_APDDR_PDDR_APDDR5          (0x20)
-#define MCF_GPIO_PDDR_APDDR_PDDR_APDDR6          (0x40)
-#define MCF_GPIO_PDDR_APDDR_PDDR_APDDR7          (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PDDR_DATAH */
-#define MCF_GPIO_PDDR_DATAH_PDDR_DATAH0          (0x01)
-#define MCF_GPIO_PDDR_DATAH_PDDR_DATAH1          (0x02)
-#define MCF_GPIO_PDDR_DATAH_PDDR_DATAH2          (0x04)
-#define MCF_GPIO_PDDR_DATAH_PDDR_DATAH3          (0x08)
-#define MCF_GPIO_PDDR_DATAH_PDDR_DATAH4          (0x10)
-#define MCF_GPIO_PDDR_DATAH_PDDR_DATAH5          (0x20)
-#define MCF_GPIO_PDDR_DATAH_PDDR_DATAH6          (0x40)
-#define MCF_GPIO_PDDR_DATAH_PDDR_DATAH7          (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PDDR_DATAL */
-#define MCF_GPIO_PDDR_DATAL_PDDR_DATAL0          (0x01)
-#define MCF_GPIO_PDDR_DATAL_PDDR_DATAL1          (0x02)
-#define MCF_GPIO_PDDR_DATAL_PDDR_DATAL2          (0x04)
-#define MCF_GPIO_PDDR_DATAL_PDDR_DATAL3          (0x08)
-#define MCF_GPIO_PDDR_DATAL_PDDR_DATAL4          (0x10)
-#define MCF_GPIO_PDDR_DATAL_PDDR_DATAL5          (0x20)
-#define MCF_GPIO_PDDR_DATAL_PDDR_DATAL6          (0x40)
-#define MCF_GPIO_PDDR_DATAL_PDDR_DATAL7          (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PDDR_BUSCTL */
-#define MCF_GPIO_PDDR_BUSCTL_PDDR_BUSCTL0        (0x01)
-#define MCF_GPIO_PDDR_BUSCTL_PDDR_BUSCTL1        (0x02)
-#define MCF_GPIO_PDDR_BUSCTL_PDDR_BUSCTL2        (0x04)
-#define MCF_GPIO_PDDR_BUSCTL_PDDR_BUSCTL3        (0x08)
-#define MCF_GPIO_PDDR_BUSCTL_PDDR_BUSCTL4        (0x10)
-#define MCF_GPIO_PDDR_BUSCTL_PDDR_BUSCTL5        (0x20)
-#define MCF_GPIO_PDDR_BUSCTL_PDDR_BUSCTL6        (0x40)
-#define MCF_GPIO_PDDR_BUSCTL_PDDR_BUSCTL7        (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PDDR_BS */
-#define MCF_GPIO_PDDR_BS_PDDR_BS0                (0x01)
-#define MCF_GPIO_PDDR_BS_PDDR_BS3(x)             (((x)&0x07)<<1)
-
-/* Bit definitions and macros for MCF_GPIO_PDDR_CS */
-#define MCF_GPIO_PDDR_CS_PDDR_CS1                (0x02)
-#define MCF_GPIO_PDDR_CS_PDDR_CS2                (0x04)
-#define MCF_GPIO_PDDR_CS_PDDR_CS3                (0x08)
-#define MCF_GPIO_PDDR_CS_PDDR_CS4                (0x10)
-#define MCF_GPIO_PDDR_CS_PDDR_CS5                (0x20)
-#define MCF_GPIO_PDDR_CS_PDDR_CS6                (0x40)
-#define MCF_GPIO_PDDR_CS_PDDR_CS7                (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PDDR_SDRAM */
-#define MCF_GPIO_PDDR_SDRAM_PDDR_SDRAM0          (0x01)
-#define MCF_GPIO_PDDR_SDRAM_PDDR_SDRAM1          (0x02)
-#define MCF_GPIO_PDDR_SDRAM_PDDR_SDRAM2          (0x04)
-#define MCF_GPIO_PDDR_SDRAM_PDDR_SDRAM3          (0x08)
-#define MCF_GPIO_PDDR_SDRAM_PDDR_SDRAM4          (0x10)
-#define MCF_GPIO_PDDR_SDRAM_PDDR_SDRAM5          (0x20)
-
-/* Bit definitions and macros for MCF_GPIO_PDDR_FECI2C */
-#define MCF_GPIO_PDDR_FECI2C_PDDR_FECI2C0        (0x01)
-#define MCF_GPIO_PDDR_FECI2C_PDDR_FECI2C1        (0x02)
-#define MCF_GPIO_PDDR_FECI2C_PDDR_FECI2C2        (0x04)
-#define MCF_GPIO_PDDR_FECI2C_PDDR_FECI2C3        (0x08)
-
-/* Bit definitions and macros for MCF_GPIO_PDDR_UARTH */
-#define MCF_GPIO_PDDR_UARTH_PDDR_UARTH0          (0x01)
-#define MCF_GPIO_PDDR_UARTH_PDDR_UARTH1          (0x02)
-
-/* Bit definitions and macros for MCF_GPIO_PDDR_UARTL */
-#define MCF_GPIO_PDDR_UARTL_PDDR_UARTL0          (0x01)
-#define MCF_GPIO_PDDR_UARTL_PDDR_UARTL1          (0x02)
-#define MCF_GPIO_PDDR_UARTL_PDDR_UARTL2          (0x04)
-#define MCF_GPIO_PDDR_UARTL_PDDR_UARTL3          (0x08)
-#define MCF_GPIO_PDDR_UARTL_PDDR_UARTL4          (0x10)
-#define MCF_GPIO_PDDR_UARTL_PDDR_UARTL5          (0x20)
-#define MCF_GPIO_PDDR_UARTL_PDDR_UARTL6          (0x40)
-#define MCF_GPIO_PDDR_UARTL_PDDR_UARTL7          (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PDDR_QSPI */
-#define MCF_GPIO_PDDR_QSPI_PDDR_QSPI0            (0x01)
-#define MCF_GPIO_PDDR_QSPI_PDDR_QSPI1            (0x02)
-#define MCF_GPIO_PDDR_QSPI_PDDR_QSPI2            (0x04)
-#define MCF_GPIO_PDDR_QSPI_PDDR_QSPI3            (0x08)
-#define MCF_GPIO_PDDR_QSPI_PDDR_QSPI4            (0x10)
-
-/* Bit definitions and macros for MCF_GPIO_PDDR_TIMER */
-#define MCF_GPIO_PDDR_TIMER_PDDR_TIMER0          (0x01)
-#define MCF_GPIO_PDDR_TIMER_PDDR_TIMER1          (0x02)
-#define MCF_GPIO_PDDR_TIMER_PDDR_TIMER2          (0x04)
-#define MCF_GPIO_PDDR_TIMER_PDDR_TIMER3          (0x08)
-#define MCF_GPIO_PDDR_TIMER_PDDR_TIMER4          (0x10)
-#define MCF_GPIO_PDDR_TIMER_PDDR_TIMER5          (0x20)
-#define MCF_GPIO_PDDR_TIMER_PDDR_TIMER6          (0x40)
-#define MCF_GPIO_PDDR_TIMER_PDDR_TIMER7          (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PDDR_ETPU */
-#define MCF_GPIO_PDDR_ETPU_PDDR_ETPU0            (0x01)
-#define MCF_GPIO_PDDR_ETPU_PDDR_ETPU1            (0x02)
-#define MCF_GPIO_PDDR_ETPU_PDDR_ETPU2            (0x04)
-
-/* Bit definitions and macros for MCF_GPIO_PPDSDR_ADDR */
-#define MCF_GPIO_PPDSDR_ADDR_PPDSDR_ADDR5        (0x20)
-#define MCF_GPIO_PPDSDR_ADDR_PPDSDR_ADDR6        (0x40)
-#define MCF_GPIO_PPDSDR_ADDR_PPDSDR_ADDR7        (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PPDSDR_DATAH */
-#define MCF_GPIO_PPDSDR_DATAH_PPDSDR_DATAH0      (0x01)
-#define MCF_GPIO_PPDSDR_DATAH_PPDSDR_DATAH1      (0x02)
-#define MCF_GPIO_PPDSDR_DATAH_PPDSDR_DATAH2      (0x04)
-#define MCF_GPIO_PPDSDR_DATAH_PPDSDR_DATAH3      (0x08)
-#define MCF_GPIO_PPDSDR_DATAH_PPDSDR_DATAH4      (0x10)
-#define MCF_GPIO_PPDSDR_DATAH_PPDSDR_DATAH5      (0x20)
-#define MCF_GPIO_PPDSDR_DATAH_PPDSDR_DATAH6      (0x40)
-#define MCF_GPIO_PPDSDR_DATAH_PPDSDR_DATAH7      (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PPDSDR_DATAL */
-#define MCF_GPIO_PPDSDR_DATAL_PPDSDR_DATAL0      (0x01)
-#define MCF_GPIO_PPDSDR_DATAL_PPDSDR_DATAL1      (0x02)
-#define MCF_GPIO_PPDSDR_DATAL_PPDSDR_DATAL2      (0x04)
-#define MCF_GPIO_PPDSDR_DATAL_PPDSDR_DATAL3      (0x08)
-#define MCF_GPIO_PPDSDR_DATAL_PPDSDR_DATAL4      (0x10)
-#define MCF_GPIO_PPDSDR_DATAL_PPDSDR_DATAL5      (0x20)
-#define MCF_GPIO_PPDSDR_DATAL_PPDSDR_DATAL6      (0x40)
-#define MCF_GPIO_PPDSDR_DATAL_PPDSDR_DATAL7      (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PPDSDR_BUSCTL */
-#define MCF_GPIO_PPDSDR_BUSCTL_PPDSDR_BUSCTL0    (0x01)
-#define MCF_GPIO_PPDSDR_BUSCTL_PPDSDR_BUSCTL1    (0x02)
-#define MCF_GPIO_PPDSDR_BUSCTL_PPDSDR_BUSCTL2    (0x04)
-#define MCF_GPIO_PPDSDR_BUSCTL_PPDSDR_BUSCTL3    (0x08)
-#define MCF_GPIO_PPDSDR_BUSCTL_PPDSDR_BUSCTL4    (0x10)
-#define MCF_GPIO_PPDSDR_BUSCTL_PPDSDR_BUSCTL5    (0x20)
-#define MCF_GPIO_PPDSDR_BUSCTL_PPDSDR_BUSCTL6    (0x40)
-#define MCF_GPIO_PPDSDR_BUSCTL_PPDSDR_BUSCTL7    (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PPDSDR_BS */
-#define MCF_GPIO_PPDSDR_BS_PPDSDR_BS0            (0x01)
-#define MCF_GPIO_PPDSDR_BS_PPDSDR_BS1            (0x02)
-#define MCF_GPIO_PPDSDR_BS_PPDSDR_BS2            (0x04)
-#define MCF_GPIO_PPDSDR_BS_PPDSDR_BS3            (0x08)
-
-/* Bit definitions and macros for MCF_GPIO_PPDSDR_FECI2C */
-#define MCF_GPIO_PPDSDR_FECI2C_PPDSDR_FECI2C0    (0x01)
-#define MCF_GPIO_PPDSDR_FECI2C_PPDSDR_FECI2C1    (0x02)
-#define MCF_GPIO_PPDSDR_FECI2C_PPDSDR_FECI2C2    (0x04)
-#define MCF_GPIO_PPDSDR_FECI2C_PPDSDR_FECI2C3    (0x08)
-
-/* Bit definitions and macros for MCF_GPIO_PPDSDR_CS */
-#define MCF_GPIO_PPDSDR_CS_PPDSDR_CS1            (0x02)
-#define MCF_GPIO_PPDSDR_CS_PPDSDR_CS2            (0x04)
-#define MCF_GPIO_PPDSDR_CS_PPDSDR_CS3            (0x08)
-#define MCF_GPIO_PPDSDR_CS_PPDSDR_CS4            (0x10)
-#define MCF_GPIO_PPDSDR_CS_PPDSDR_CS5            (0x20)
-#define MCF_GPIO_PPDSDR_CS_PPDSDR_CS6            (0x40)
-#define MCF_GPIO_PPDSDR_CS_PPDSDR_CS7            (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PPDSDR_SDRAM */
-#define MCF_GPIO_PPDSDR_SDRAM_PPDSDR_SDRAM0      (0x01)
-#define MCF_GPIO_PPDSDR_SDRAM_PPDSDR_SDRAM1      (0x02)
-#define MCF_GPIO_PPDSDR_SDRAM_PPDSDR_SDRAM2      (0x04)
-#define MCF_GPIO_PPDSDR_SDRAM_PPDSDR_SDRAM3      (0x08)
-#define MCF_GPIO_PPDSDR_SDRAM_PPDSDR_SDRAM4      (0x10)
-#define MCF_GPIO_PPDSDR_SDRAM_PPDSDR_SDRAM5      (0x20)
-#define MCF_GPIO_PPDSDR_SDRAM_PPDSDR_SDRAM6      (0x40)
-#define MCF_GPIO_PPDSDR_SDRAM_PPDSDR_SDRAM7      (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PPDSDR_UARTH */
-#define MCF_GPIO_PPDSDR_UARTH_PPDSDR_UARTH0      (0x01)
-#define MCF_GPIO_PPDSDR_UARTH_PPDSDR_UARTH1      (0x02)
-
-/* Bit definitions and macros for MCF_GPIO_PPDSDR_UARTL */
-#define MCF_GPIO_PPDSDR_UARTL_PPDSDR_UARTL0      (0x01)
-#define MCF_GPIO_PPDSDR_UARTL_PPDSDR_UARTL1      (0x02)
-#define MCF_GPIO_PPDSDR_UARTL_PPDSDR_UARTL2      (0x04)
-#define MCF_GPIO_PPDSDR_UARTL_PPDSDR_UARTL3      (0x08)
-#define MCF_GPIO_PPDSDR_UARTL_PPDSDR_UARTL4      (0x10)
-#define MCF_GPIO_PPDSDR_UARTL_PPDSDR_UARTL5      (0x20)
-#define MCF_GPIO_PPDSDR_UARTL_PPDSDR_UARTL6      (0x40)
-#define MCF_GPIO_PPDSDR_UARTL_PPDSDR_UARTL7      (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PPDSDR_QSPI */
-#define MCF_GPIO_PPDSDR_QSPI_PPDSDR_QSPI0        (0x01)
-#define MCF_GPIO_PPDSDR_QSPI_PPDSDR_QSPI1        (0x02)
-#define MCF_GPIO_PPDSDR_QSPI_PPDSDR_QSPI2        (0x04)
-#define MCF_GPIO_PPDSDR_QSPI_PPDSDR_QSPI3        (0x08)
-#define MCF_GPIO_PPDSDR_QSPI_PPDSDR_QSPI4        (0x10)
-
-/* Bit definitions and macros for MCF_GPIO_PPDSDR_TIMER */
-#define MCF_GPIO_PPDSDR_TIMER_PPDSDR_TIMER0      (0x01)
-#define MCF_GPIO_PPDSDR_TIMER_PPDSDR_TIMER1      (0x02)
-#define MCF_GPIO_PPDSDR_TIMER_PPDSDR_TIMER2      (0x04)
-#define MCF_GPIO_PPDSDR_TIMER_PPDSDR_TIMER3      (0x08)
-#define MCF_GPIO_PPDSDR_TIMER_PPDSDR_TIMER4      (0x10)
-#define MCF_GPIO_PPDSDR_TIMER_PPDSDR_TIMER5      (0x20)
-#define MCF_GPIO_PPDSDR_TIMER_PPDSDR_TIMER6      (0x40)
-#define MCF_GPIO_PPDSDR_TIMER_PPDSDR_TIMER7      (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PPDSDR_ETPU */
-#define MCF_GPIO_PPDSDR_ETPU_PPDSDR_ETPU0        (0x01)
-#define MCF_GPIO_PPDSDR_ETPU_PPDSDR_ETPU1        (0x02)
-#define MCF_GPIO_PPDSDR_ETPU_PPDSDR_ETPU2        (0x04)
-
-/* Bit definitions and macros for MCF_GPIO_PCLRR_ADDR */
-#define MCF_GPIO_PCLRR_ADDR_PCLRR_ADDR5          (0x20)
-#define MCF_GPIO_PCLRR_ADDR_PCLRR_ADDR6          (0x40)
-#define MCF_GPIO_PCLRR_ADDR_PCLRR_ADDR7          (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PCLRR_DATAH */
-#define MCF_GPIO_PCLRR_DATAH_PCLRR_DATAH0        (0x01)
-#define MCF_GPIO_PCLRR_DATAH_PCLRR_DATAH1        (0x02)
-#define MCF_GPIO_PCLRR_DATAH_PCLRR_DATAH2        (0x04)
-#define MCF_GPIO_PCLRR_DATAH_PCLRR_DATAH3        (0x08)
-#define MCF_GPIO_PCLRR_DATAH_PCLRR_DATAH4        (0x10)
-#define MCF_GPIO_PCLRR_DATAH_PCLRR_DATAH5        (0x20)
-#define MCF_GPIO_PCLRR_DATAH_PCLRR_DATAH6        (0x40)
-#define MCF_GPIO_PCLRR_DATAH_PCLRR_DATAH7        (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PCLRR_DATAL */
-#define MCF_GPIO_PCLRR_DATAL_PCLRR_DATAL0        (0x01)
-#define MCF_GPIO_PCLRR_DATAL_PCLRR_DATAL1        (0x02)
-#define MCF_GPIO_PCLRR_DATAL_PCLRR_DATAL2        (0x04)
-#define MCF_GPIO_PCLRR_DATAL_PCLRR_DATAL3        (0x08)
-#define MCF_GPIO_PCLRR_DATAL_PCLRR_DATAL4        (0x10)
-#define MCF_GPIO_PCLRR_DATAL_PCLRR_DATAL5        (0x20)
-#define MCF_GPIO_PCLRR_DATAL_PCLRR_DATAL6        (0x40)
-#define MCF_GPIO_PCLRR_DATAL_PCLRR_DATAL7        (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PCLRR_BUSCTL */
-#define MCF_GPIO_PCLRR_BUSCTL_PCLRR_BUSCTL0      (0x01)
-#define MCF_GPIO_PCLRR_BUSCTL_PCLRR_BUSCTL1      (0x02)
-#define MCF_GPIO_PCLRR_BUSCTL_PCLRR_BUSCTL2      (0x04)
-#define MCF_GPIO_PCLRR_BUSCTL_PCLRR_BUSCTL3      (0x08)
-#define MCF_GPIO_PCLRR_BUSCTL_PCLRR_BUSCTL4      (0x10)
-#define MCF_GPIO_PCLRR_BUSCTL_PCLRR_BUSCTL5      (0x20)
-#define MCF_GPIO_PCLRR_BUSCTL_PCLRR_BUSCTL6      (0x40)
-#define MCF_GPIO_PCLRR_BUSCTL_PCLRR_BUSCTL7      (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PCLRR_BS */
-#define MCF_GPIO_PCLRR_BS_PCLRR_BS0              (0x01)
-#define MCF_GPIO_PCLRR_BS_PCLRR_BS1              (0x02)
-#define MCF_GPIO_PCLRR_BS_PCLRR_BS2              (0x04)
-#define MCF_GPIO_PCLRR_BS_PCLRR_BS3              (0x08)
-
-/* Bit definitions and macros for MCF_GPIO_PCLRR_CS */
-#define MCF_GPIO_PCLRR_CS_PCLRR_CS1              (0x02)
-#define MCF_GPIO_PCLRR_CS_PCLRR_CS2              (0x04)
-#define MCF_GPIO_PCLRR_CS_PCLRR_CS3              (0x08)
-#define MCF_GPIO_PCLRR_CS_PCLRR_CS4              (0x10)
-#define MCF_GPIO_PCLRR_CS_PCLRR_CS5              (0x20)
-#define MCF_GPIO_PCLRR_CS_PCLRR_CS6              (0x40)
-#define MCF_GPIO_PCLRR_CS_PCLRR_CS7              (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PCLRR_SDRAM */
-#define MCF_GPIO_PCLRR_SDRAM_PCLRR_SDRAM0        (0x01)
-#define MCF_GPIO_PCLRR_SDRAM_PCLRR_SDRAM1        (0x02)
-#define MCF_GPIO_PCLRR_SDRAM_PCLRR_SDRAM2        (0x04)
-#define MCF_GPIO_PCLRR_SDRAM_PCLRR_SDRAM3        (0x08)
-#define MCF_GPIO_PCLRR_SDRAM_PCLRR_SDRAM4        (0x10)
-#define MCF_GPIO_PCLRR_SDRAM_PCLRR_SDRAM5        (0x20)
-
-/* Bit definitions and macros for MCF_GPIO_PCLRR_FECI2C */
-#define MCF_GPIO_PCLRR_FECI2C_PCLRR_FECI2C0      (0x01)
-#define MCF_GPIO_PCLRR_FECI2C_PCLRR_FECI2C1      (0x02)
-#define MCF_GPIO_PCLRR_FECI2C_PCLRR_FECI2C2      (0x04)
-#define MCF_GPIO_PCLRR_FECI2C_PCLRR_FECI2C3      (0x08)
-
-/* Bit definitions and macros for MCF_GPIO_PCLRR_UARTH */
-#define MCF_GPIO_PCLRR_UARTH_PCLRR_UARTH0        (0x01)
-#define MCF_GPIO_PCLRR_UARTH_PCLRR_UARTH1        (0x02)
-
-/* Bit definitions and macros for MCF_GPIO_PCLRR_UARTL */
-#define MCF_GPIO_PCLRR_UARTL_PCLRR_UARTL0        (0x01)
-#define MCF_GPIO_PCLRR_UARTL_PCLRR_UARTL1        (0x02)
-#define MCF_GPIO_PCLRR_UARTL_PCLRR_UARTL2        (0x04)
-#define MCF_GPIO_PCLRR_UARTL_PCLRR_UARTL3        (0x08)
-#define MCF_GPIO_PCLRR_UARTL_PCLRR_UARTL4        (0x10)
-#define MCF_GPIO_PCLRR_UARTL_PCLRR_UARTL5        (0x20)
-#define MCF_GPIO_PCLRR_UARTL_PCLRR_UARTL6        (0x40)
-#define MCF_GPIO_PCLRR_UARTL_PCLRR_UARTL7        (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PCLRR_QSPI */
-#define MCF_GPIO_PCLRR_QSPI_PCLRR_QSPI0          (0x01)
-#define MCF_GPIO_PCLRR_QSPI_PCLRR_QSPI1          (0x02)
-#define MCF_GPIO_PCLRR_QSPI_PCLRR_QSPI2          (0x04)
-#define MCF_GPIO_PCLRR_QSPI_PCLRR_QSPI3          (0x08)
-#define MCF_GPIO_PCLRR_QSPI_PCLRR_QSPI4          (0x10)
-
-/* Bit definitions and macros for MCF_GPIO_PCLRR_TIMER */
-#define MCF_GPIO_PCLRR_TIMER_PCLRR_TIMER0        (0x01)
-#define MCF_GPIO_PCLRR_TIMER_PCLRR_TIMER1        (0x02)
-#define MCF_GPIO_PCLRR_TIMER_PCLRR_TIMER2        (0x04)
-#define MCF_GPIO_PCLRR_TIMER_PCLRR_TIMER3        (0x08)
-#define MCF_GPIO_PCLRR_TIMER_PCLRR_TIMER4        (0x10)
-#define MCF_GPIO_PCLRR_TIMER_PCLRR_TIMER5        (0x20)
-#define MCF_GPIO_PCLRR_TIMER_PCLRR_TIMER6        (0x40)
-#define MCF_GPIO_PCLRR_TIMER_PCLRR_TIMER7        (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PCLRR_ETPU */
-#define MCF_GPIO_PCLRR_ETPU_PCLRR_ETPU0          (0x01)
-#define MCF_GPIO_PCLRR_ETPU_PCLRR_ETPU1          (0x02)
-#define MCF_GPIO_PCLRR_ETPU_PCLRR_ETPU2          (0x04)
-
-/* Bit definitions and macros for MCF_GPIO_PAR_AD */
-#define MCF_GPIO_PAR_AD_PAR_DATAL                (0x01)
-#define MCF_GPIO_PAR_AD_PAR_ADDR21               (0x20)
-#define MCF_GPIO_PAR_AD_PAR_ADDR22               (0x40)
-#define MCF_GPIO_PAR_AD_PAR_ADDR23               (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PAR_BUSCTL */
-#define MCF_GPIO_PAR_BUSCTL_PAR_TIP(x)           (((x)&0x0003)<<0)
-#define MCF_GPIO_PAR_BUSCTL_PAR_TS(x)            (((x)&0x0003)<<2)
-#define MCF_GPIO_PAR_BUSCTL_PAR_TSIZ0            (0x0010)
-#define MCF_GPIO_PAR_BUSCTL_PAR_TSIZ1            (0x0040)
-#define MCF_GPIO_PAR_BUSCTL_PAR_RWB              (0x0100)
-#define MCF_GPIO_PAR_BUSCTL_PAR_TEA(x)           (((x)&0x0003)<<10)
-#define MCF_GPIO_PAR_BUSCTL_PAR_TA               (0x1000)
-#define MCF_GPIO_PAR_BUSCTL_PAR_OE               (0x4000)
-#define MCF_GPIO_PAR_BUSCTL_PAR_TEA_GPIO         (0x0000)
-#define MCF_GPIO_PAR_BUSCTL_PAR_TEA_DMA          (0x0800)
-#define MCF_GPIO_PAR_BUSCTL_PAR_TEA_TEA          (0x0C00)
-#define MCF_GPIO_PAR_BUSCTL_PAR_TS_GPIO          (0x0000)
-#define MCF_GPIO_PAR_BUSCTL_PAR_TS_DMA           (0x0080)
-#define MCF_GPIO_PAR_BUSCTL_PAR_TS_TS            (0x00C0)
-#define MCF_GPIO_PAR_BUSCTL_PAR_TIP_GPIO         (0x0000)
-#define MCF_GPIO_PAR_BUSCTL_PAR_TIP_DMA          (0x0002)
-#define MCF_GPIO_PAR_BUSCTL_PAR_TIP_TEA          (0x0003)
-
-/* Bit definitions and macros for MCF_GPIO_PAR_BS */
-#define MCF_GPIO_PAR_BS_PAR_BS0                  (0x01)
-#define MCF_GPIO_PAR_BS_PAR_BS1                  (0x02)
-#define MCF_GPIO_PAR_BS_PAR_BS2                  (0x04)
-#define MCF_GPIO_PAR_BS_PAR_BS3                  (0x08)
-
-/* Bit definitions and macros for MCF_GPIO_PAR_CS */
-#define MCF_GPIO_PAR_CS_PAR_CS1                  (0x02)
-#define MCF_GPIO_PAR_CS_PAR_CS2                  (0x04)
-#define MCF_GPIO_PAR_CS_PAR_CS3                  (0x08)
-#define MCF_GPIO_PAR_CS_PAR_CS4                  (0x10)
-#define MCF_GPIO_PAR_CS_PAR_CS5                  (0x20)
-#define MCF_GPIO_PAR_CS_PAR_CS6                  (0x40)
-#define MCF_GPIO_PAR_CS_PAR_CS7                  (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PAR_SDRAM */
-#define MCF_GPIO_PAR_SDRAM_PAR_SDCS0             (0x01)
-#define MCF_GPIO_PAR_SDRAM_PAR_SDCS1             (0x02)
-#define MCF_GPIO_PAR_SDRAM_PAR_SCKE              (0x04)
-#define MCF_GPIO_PAR_SDRAM_PAR_SRAS              (0x08)
-#define MCF_GPIO_PAR_SDRAM_PAR_SCAS              (0x10)
-#define MCF_GPIO_PAR_SDRAM_PAR_SDWE              (0x20)
-#define MCF_GPIO_PAR_SDRAM_PAR_CSSDCS(x)         (((x)&0x03)<<6)
-
-/* Bit definitions and macros for MCF_GPIO_PAR_FECI2C */
-#define MCF_GPIO_PAR_FECI2C_PAR_SDA(x)           (((x)&0x03)<<0)
-#define MCF_GPIO_PAR_FECI2C_PAR_SCL(x)           (((x)&0x03)<<2)
-#define MCF_GPIO_PAR_FECI2C_PAR_EMDIO(x)         (((x)&0x03)<<4)
-#define MCF_GPIO_PAR_FECI2C_PAR_EMDC(x)          (((x)&0x03)<<6)
-#define MCF_GPIO_PAR_FECI2C_PAR_EMDC_GPIO        (0x00)
-#define MCF_GPIO_PAR_FECI2C_PAR_EMDC_UART2       (0x40)
-#define MCF_GPIO_PAR_FECI2C_PAR_EMDC_I2C         (0x80)
-#define MCF_GPIO_PAR_FECI2C_PAR_EMDC_FEC         (0xC0)
-#define MCF_GPIO_PAR_FECI2C_PAR_EMDIO_GPIO       (0x00)
-#define MCF_GPIO_PAR_FECI2C_PAR_EMDIO_UART2      (0x10)
-#define MCF_GPIO_PAR_FECI2C_PAR_EMDIO_I2C        (0x20)
-#define MCF_GPIO_PAR_FECI2C_PAR_EMDIO_FEC        (0x30)
-#define MCF_GPIO_PAR_FECI2C_PAR_SCL_GPIO         (0x00)
-#define MCF_GPIO_PAR_FECI2C_PAR_SCL_FLEX         (0x08)
-#define MCF_GPIO_PAR_FECI2C_PAR_SCL_I2C          (0x0C)
-#define MCF_GPIO_PAR_FECI2C_PAR_SDA_GPIO         (0x00)
-#define MCF_GPIO_PAR_FECI2C_PAR_SDA_FLEX         (0x02)
-#define MCF_GPIO_PAR_FECI2C_PAR_SDA_I2C          (0x03)
-
-/* Bit definitions and macros for MCF_GPIO_PAR_UART */
-#define MCF_GPIO_PAR_UART_PAR_U0RTS              (0x0001)
-#define MCF_GPIO_PAR_UART_PAR_U0CTS              (0x0002)
-#define MCF_GPIO_PAR_UART_PAR_U0TXD              (0x0004)
-#define MCF_GPIO_PAR_UART_PAR_U0RXD              (0x0008)
-#define MCF_GPIO_PAR_UART_PAR_U1RTS(x)           (((x)&0x0003)<<4)
-#define MCF_GPIO_PAR_UART_PAR_U1CTS(x)           (((x)&0x0003)<<6)
-#define MCF_GPIO_PAR_UART_PAR_U1TXD(x)           (((x)&0x0003)<<8)
-#define MCF_GPIO_PAR_UART_PAR_U1RXD(x)           (((x)&0x0003)<<10)
-#define MCF_GPIO_PAR_UART_PAR_U2TXD              (0x1000)
-#define MCF_GPIO_PAR_UART_PAR_U2RXD              (0x2000)
-#define MCF_GPIO_PAR_UART_PAR_CAN1EN             (0x4000)
-#define MCF_GPIO_PAR_UART_PAR_DREQ2              (0x8000)
-#define MCF_GPIO_PAR_UART_PAR_U1RXD_GPIO         (0x0000)
-#define MCF_GPIO_PAR_UART_PAR_U1RXD_FLEX         (0x0800)
-#define MCF_GPIO_PAR_UART_PAR_U1RXD_UART1        (0x0C00)
-#define MCF_GPIO_PAR_UART_PAR_U1TXD_GPIO         (0x0000)
-#define MCF_GPIO_PAR_UART_PAR_U1TXD_FLEX         (0x0200)
-#define MCF_GPIO_PAR_UART_PAR_U1TXD_UART1        (0x0300)
-#define MCF_GPIO_PAR_UART_PAR_U1CTS_GPIO         (0x0000)
-#define MCF_GPIO_PAR_UART_PAR_U1CTS_UART2        (0x0080)
-#define MCF_GPIO_PAR_UART_PAR_U1CTS_UART1        (0x00C0)
-#define MCF_GPIO_PAR_UART_PAR_U1RTS_GPIO         (0x0000)
-#define MCF_GPIO_PAR_UART_PAR_U1RTS_UART2        (0x0020)
-#define MCF_GPIO_PAR_UART_PAR_U1RTS_UART1        (0x0030)
-
-/* Bit definitions and macros for MCF_GPIO_PAR_QSPI */
-#define MCF_GPIO_PAR_QSPI_PAR_SCK(x)             (((x)&0x03)<<0)
-#define MCF_GPIO_PAR_QSPI_PAR_DOUT               (0x04)
-#define MCF_GPIO_PAR_QSPI_PAR_DIN(x)             (((x)&0x03)<<3)
-#define MCF_GPIO_PAR_QSPI_PAR_PCS0               (0x20)
-#define MCF_GPIO_PAR_QSPI_PAR_PCS1(x)            (((x)&0x03)<<6)
-#define MCF_GPIO_PAR_QSPI_PAR_PCS1_GPIO          (0x00)
-#define MCF_GPIO_PAR_QSPI_PAR_PCS1_SDRAMC        (0x80)
-#define MCF_GPIO_PAR_QSPI_PAR_PCS1_QSPI          (0xC0)
-#define MCF_GPIO_PAR_QSPI_PAR_DIN_GPIO           (0x00)
-#define MCF_GPIO_PAR_QSPI_PAR_DIN_I2C            (0x10)
-#define MCF_GPIO_PAR_QSPI_PAR_DIN_QSPI           (0x1C)
-#define MCF_GPIO_PAR_QSPI_PAR_SCK_GPIO           (0x00)
-#define MCF_GPIO_PAR_QSPI_PAR_SCK_I2C            (0x02)
-#define MCF_GPIO_PAR_QSPI_PAR_SCK_QSPI           (0x03)
-
-/* Bit definitions and macros for MCF_GPIO_PAR_TIMER */
-#define MCF_GPIO_PAR_TIMER_PAR_T0OUT(x)          (((x)&0x0003)<<0)
-#define MCF_GPIO_PAR_TIMER_PAR_T1OUT(x)          (((x)&0x0003)<<2)
-#define MCF_GPIO_PAR_TIMER_PAR_T2OUT(x)          (((x)&0x0003)<<4)
-#define MCF_GPIO_PAR_TIMER_PAR_T3OUT(x)          (((x)&0x0003)<<6)
-#define MCF_GPIO_PAR_TIMER_PAR_T0IN(x)           (((x)&0x0003)<<8)
-#define MCF_GPIO_PAR_TIMER_PAR_T1IN(x)           (((x)&0x0003)<<10)
-#define MCF_GPIO_PAR_TIMER_PAR_T2IN(x)           (((x)&0x0003)<<12)
-#define MCF_GPIO_PAR_TIMER_PAR_T3IN(x)           (((x)&0x0003)<<14)
-#define MCF_GPIO_PAR_TIMER_PAR_T3IN_GPIO         (0x0000)
-#define MCF_GPIO_PAR_TIMER_PAR_T3IN_QSPI         (0x4000)
-#define MCF_GPIO_PAR_TIMER_PAR_T3IN_UART2        (0x8000)
-#define MCF_GPIO_PAR_TIMER_PAR_T3IN_T3IN         (0xC000)
-#define MCF_GPIO_PAR_TIMER_PAR_T2IN_GPIO         (0x0000)
-#define MCF_GPIO_PAR_TIMER_PAR_T2IN_T2OUT        (0x1000)
-#define MCF_GPIO_PAR_TIMER_PAR_T2IN_DMA          (0x2000)
-#define MCF_GPIO_PAR_TIMER_PAR_T2IN_T2IN         (0x3000)
-#define MCF_GPIO_PAR_TIMER_PAR_T1IN_GPIO         (0x0000)
-#define MCF_GPIO_PAR_TIMER_PAR_T1IN_T1OUT        (0x0400)
-#define MCF_GPIO_PAR_TIMER_PAR_T1IN_DMA          (0x0800)
-#define MCF_GPIO_PAR_TIMER_PAR_T1IN_T1IN         (0x0C00)
-#define MCF_GPIO_PAR_TIMER_PAR_T0IN_GPIO         (0x0000)
-#define MCF_GPIO_PAR_TIMER_PAR_T0IN_DMA          (0x0200)
-#define MCF_GPIO_PAR_TIMER_PAR_T0IN_T0IN         (0x0300)
-#define MCF_GPIO_PAR_TIMER_PAR_T3OUT_GPIO        (0x0000)
-#define MCF_GPIO_PAR_TIMER_PAR_T3OUT_QSPI        (0x0040)
-#define MCF_GPIO_PAR_TIMER_PAR_T3OUT_UART2       (0x0080)
-#define MCF_GPIO_PAR_TIMER_PAR_T3OUT_T3OUT       (0x00C0)
-#define MCF_GPIO_PAR_TIMER_PAR_T2OUT_GPIO        (0x0000)
-#define MCF_GPIO_PAR_TIMER_PAR_T2OUT_DMA         (0x0020)
-#define MCF_GPIO_PAR_TIMER_PAR_T2OUT_T2OUT       (0x0030)
-#define MCF_GPIO_PAR_TIMER_PAR_T1OUT_GPIO        (0x0000)
-#define MCF_GPIO_PAR_TIMER_PAR_T1OUT_DMA         (0x0008)
-#define MCF_GPIO_PAR_TIMER_PAR_T1OUT_T1OUT       (0x000C)
-#define MCF_GPIO_PAR_TIMER_PAR_T0OUT_GPIO        (0x0000)
-#define MCF_GPIO_PAR_TIMER_PAR_T0OUT_DMA         (0x0002)
-#define MCF_GPIO_PAR_TIMER_PAR_T0OUT_T0OUT       (0x0003)
-
-/* Bit definitions and macros for MCF_GPIO_PAR_ETPU */
-#define MCF_GPIO_PAR_ETPU_PAR_LTPU_ODIS          (0x01)
-#define MCF_GPIO_PAR_ETPU_PAR_UTPU_ODIS          (0x02)
-#define MCF_GPIO_PAR_ETPU_PAR_TCRCLK             (0x04)
-
-/* Bit definitions and macros for MCF_GPIO_DSCR_EIM */
-#define MCF_GPIO_DSCR_EIM_DSCR_EIM0              (0x01)
-#define MCF_GPIO_DSCR_EIM_DSCR_EIM1              (0x10)
-
-/* Bit definitions and macros for MCF_GPIO_DSCR_ETPU */
-#define MCF_GPIO_DSCR_ETPU_DSCR_ETPU_7_0         (0x01)
-#define MCF_GPIO_DSCR_ETPU_DSCR_ETPU_15_8        (0x04)
-#define MCF_GPIO_DSCR_ETPU_DSCR_ETPU_23_16       (0x10)
-#define MCF_GPIO_DSCR_ETPU_DSCR_ETPU_31_24       (0x40)
-
-/* Bit definitions and macros for MCF_GPIO_DSCR_FECI2C */
-#define MCF_GPIO_DSCR_FECI2C_DSCR_I2C            (0x01)
-#define MCF_GPIO_DSCR_FECI2C_DSCR_FEC            (0x10)
-
-/* Bit definitions and macros for MCF_GPIO_DSCR_UART */
-#define MCF_GPIO_DSCR_UART_DSCR_UART0            (0x01)
-#define MCF_GPIO_DSCR_UART_DSCR_UART1            (0x04)
-#define MCF_GPIO_DSCR_UART_DSCR_UART2            (0x10)
-#define MCF_GPIO_DSCR_UART_DSCR_IRQ              (0x40)
-
-/* Bit definitions and macros for MCF_GPIO_DSCR_QSPI */
-#define MCF_GPIO_DSCR_QSPI_DSCR_QSPI             (0x01)
-
-/* Bit definitions and macros for MCF_GPIO_DSCR_TIMER */
-#define MCF_GPIO_DSCR_TIMER_DSCR_TIMER           (0x01)
-
-/********************************************************************/
-
-#endif /* __MCF523X_GPIO_H__ */
+/*\r
+ * These files are taken from the MCF523X source code example package\r
+ * which is available on the Freescale website. Freescale explicitly \r
+ * grants the redistribution and modification of these source files.\r
+ * The complete licensing information is available in the file \r
+ * LICENSE_FREESCALE.TXT.\r
+ *\r
+ * File:       mcf523x_gpio.h\r
+ * Purpose:    Register and bit definitions for the MCF523X\r
+ *\r
+ * Notes:      \r
+ *     \r
+ */\r
+\r
+#ifndef __MCF523X_GPIO_H__\r
+#define __MCF523X_GPIO_H__\r
+\r
+/*********************************************************************\r
+*\r
+* General Purpose I/O (GPIO)\r
+*\r
+*********************************************************************/\r
+\r
+/* Register read/write macros */\r
+#define MCF_GPIO_PODR_ADDR        (*(vuint8 *)(void*)(&__IPSBAR[0x100000]))\r
+#define MCF_GPIO_PODR_DATAH       (*(vuint8 *)(void*)(&__IPSBAR[0x100001]))\r
+#define MCF_GPIO_PODR_DATAL       (*(vuint8 *)(void*)(&__IPSBAR[0x100002]))\r
+#define MCF_GPIO_PODR_BUSCTL      (*(vuint8 *)(void*)(&__IPSBAR[0x100003]))\r
+#define MCF_GPIO_PODR_BS          (*(vuint8 *)(void*)(&__IPSBAR[0x100004]))\r
+#define MCF_GPIO_PODR_CS          (*(vuint8 *)(void*)(&__IPSBAR[0x100005]))\r
+#define MCF_GPIO_PODR_SDRAM       (*(vuint8 *)(void*)(&__IPSBAR[0x100006]))\r
+#define MCF_GPIO_PODR_FECI2C      (*(vuint8 *)(void*)(&__IPSBAR[0x100007]))\r
+#define MCF_GPIO_PODR_UARTH       (*(vuint8 *)(void*)(&__IPSBAR[0x100008]))\r
+#define MCF_GPIO_PODR_UARTL       (*(vuint8 *)(void*)(&__IPSBAR[0x100009]))\r
+#define MCF_GPIO_PODR_QSPI        (*(vuint8 *)(void*)(&__IPSBAR[0x10000A]))\r
+#define MCF_GPIO_PODR_TIMER       (*(vuint8 *)(void*)(&__IPSBAR[0x10000B]))\r
+#define MCF_GPIO_PODR_ETPU        (*(vuint8 *)(void*)(&__IPSBAR[0x10000C]))\r
+#define MCF_GPIO_PDDR_APDDR       (*(vuint8 *)(void*)(&__IPSBAR[0x100010]))\r
+#define MCF_GPIO_PDDR_DATAH       (*(vuint8 *)(void*)(&__IPSBAR[0x100011]))\r
+#define MCF_GPIO_PDDR_DATAL       (*(vuint8 *)(void*)(&__IPSBAR[0x100012]))\r
+#define MCF_GPIO_PDDR_BUSCTL      (*(vuint8 *)(void*)(&__IPSBAR[0x100013]))\r
+#define MCF_GPIO_PDDR_BS          (*(vuint8 *)(void*)(&__IPSBAR[0x100014]))\r
+#define MCF_GPIO_PDDR_CS          (*(vuint8 *)(void*)(&__IPSBAR[0x100015]))\r
+#define MCF_GPIO_PDDR_SDRAM       (*(vuint8 *)(void*)(&__IPSBAR[0x100016]))\r
+#define MCF_GPIO_PDDR_FECI2C      (*(vuint8 *)(void*)(&__IPSBAR[0x100017]))\r
+#define MCF_GPIO_PDDR_UARTH       (*(vuint8 *)(void*)(&__IPSBAR[0x100018]))\r
+#define MCF_GPIO_PDDR_UARTL       (*(vuint8 *)(void*)(&__IPSBAR[0x100019]))\r
+#define MCF_GPIO_PDDR_QSPI        (*(vuint8 *)(void*)(&__IPSBAR[0x10001A]))\r
+#define MCF_GPIO_PDDR_TIMER       (*(vuint8 *)(void*)(&__IPSBAR[0x10001B]))\r
+#define MCF_GPIO_PDDR_ETPU        (*(vuint8 *)(void*)(&__IPSBAR[0x10001C]))\r
+#define MCF_GPIO_PPDSDR_ADDR      (*(vuint8 *)(void*)(&__IPSBAR[0x100020]))\r
+#define MCF_GPIO_PPDSDR_DATAH     (*(vuint8 *)(void*)(&__IPSBAR[0x100021]))\r
+#define MCF_GPIO_PPDSDR_DATAL     (*(vuint8 *)(void*)(&__IPSBAR[0x100022]))\r
+#define MCF_GPIO_PPDSDR_BUSCTL    (*(vuint8 *)(void*)(&__IPSBAR[0x100023]))\r
+#define MCF_GPIO_PPDSDR_BS        (*(vuint8 *)(void*)(&__IPSBAR[0x100024]))\r
+#define MCF_GPIO_PPDSDR_FECI2C    (*(vuint8 *)(void*)(&__IPSBAR[0x100027]))\r
+#define MCF_GPIO_PPDSDR_CS        (*(vuint8 *)(void*)(&__IPSBAR[0x100025]))\r
+#define MCF_GPIO_PPDSDR_SDRAM     (*(vuint8 *)(void*)(&__IPSBAR[0x100026]))\r
+#define MCF_GPIO_PPDSDR_UARTH     (*(vuint8 *)(void*)(&__IPSBAR[0x100028]))\r
+#define MCF_GPIO_PPDSDR_UARTL     (*(vuint8 *)(void*)(&__IPSBAR[0x100029]))\r
+#define MCF_GPIO_PPDSDR_QSPI      (*(vuint8 *)(void*)(&__IPSBAR[0x10002A]))\r
+#define MCF_GPIO_PPDSDR_TIMER     (*(vuint8 *)(void*)(&__IPSBAR[0x10002B]))\r
+#define MCF_GPIO_PPDSDR_ETPU      (*(vuint8 *)(void*)(&__IPSBAR[0x10002C]))\r
+#define MCF_GPIO_PCLRR_ADDR       (*(vuint8 *)(void*)(&__IPSBAR[0x100030]))\r
+#define MCF_GPIO_PCLRR_DATAH      (*(vuint8 *)(void*)(&__IPSBAR[0x100031]))\r
+#define MCF_GPIO_PCLRR_DATAL      (*(vuint8 *)(void*)(&__IPSBAR[0x100032]))\r
+#define MCF_GPIO_PCLRR_BUSCTL     (*(vuint8 *)(void*)(&__IPSBAR[0x100033]))\r
+#define MCF_GPIO_PCLRR_BS         (*(vuint8 *)(void*)(&__IPSBAR[0x100034]))\r
+#define MCF_GPIO_PCLRR_CS         (*(vuint8 *)(void*)(&__IPSBAR[0x100035]))\r
+#define MCF_GPIO_PCLRR_SDRAM      (*(vuint8 *)(void*)(&__IPSBAR[0x100036]))\r
+#define MCF_GPIO_PCLRR_FECI2C     (*(vuint8 *)(void*)(&__IPSBAR[0x100037]))\r
+#define MCF_GPIO_PCLRR_UARTH      (*(vuint8 *)(void*)(&__IPSBAR[0x100038]))\r
+#define MCF_GPIO_PCLRR_UARTL      (*(vuint8 *)(void*)(&__IPSBAR[0x100039]))\r
+#define MCF_GPIO_PCLRR_QSPI       (*(vuint8 *)(void*)(&__IPSBAR[0x10003A]))\r
+#define MCF_GPIO_PCLRR_TIMER      (*(vuint8 *)(void*)(&__IPSBAR[0x10003B]))\r
+#define MCF_GPIO_PCLRR_ETPU       (*(vuint8 *)(void*)(&__IPSBAR[0x10003C]))\r
+#define MCF_GPIO_PAR_AD           (*(vuint8 *)(void*)(&__IPSBAR[0x100040]))\r
+#define MCF_GPIO_PAR_BUSCTL       (*(vuint16*)(void*)(&__IPSBAR[0x100042]))\r
+#define MCF_GPIO_PAR_BS           (*(vuint8 *)(void*)(&__IPSBAR[0x100044]))\r
+#define MCF_GPIO_PAR_CS           (*(vuint8 *)(void*)(&__IPSBAR[0x100045]))\r
+#define MCF_GPIO_PAR_SDRAM        (*(vuint8 *)(void*)(&__IPSBAR[0x100046]))\r
+#define MCF_GPIO_PAR_FECI2C       (*(vuint8 *)(void*)(&__IPSBAR[0x100047]))\r
+#define MCF_GPIO_PAR_UART         (*(vuint16*)(void*)(&__IPSBAR[0x100048]))\r
+#define MCF_GPIO_PAR_QSPI         (*(vuint8 *)(void*)(&__IPSBAR[0x10004A]))\r
+#define MCF_GPIO_PAR_TIMER        (*(vuint16*)(void*)(&__IPSBAR[0x10004C]))\r
+#define MCF_GPIO_PAR_ETPU         (*(vuint8 *)(void*)(&__IPSBAR[0x10004E]))\r
+#define MCF_GPIO_DSCR_EIM         (*(vuint8 *)(void*)(&__IPSBAR[0x100050]))\r
+#define MCF_GPIO_DSCR_ETPU        (*(vuint8 *)(void*)(&__IPSBAR[0x100051]))\r
+#define MCF_GPIO_DSCR_FECI2C      (*(vuint8 *)(void*)(&__IPSBAR[0x100052]))\r
+#define MCF_GPIO_DSCR_UART        (*(vuint8 *)(void*)(&__IPSBAR[0x100053]))\r
+#define MCF_GPIO_DSCR_QSPI        (*(vuint8 *)(void*)(&__IPSBAR[0x100054]))\r
+#define MCF_GPIO_DSCR_TIMER       (*(vuint8 *)(void*)(&__IPSBAR[0x100055]))\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PODR_ADDR */\r
+#define MCF_GPIO_PODR_ADDR_PODR_ADDR5            (0x20)\r
+#define MCF_GPIO_PODR_ADDR_PODR_ADDR6            (0x40)\r
+#define MCF_GPIO_PODR_ADDR_PODR_ADDR7            (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PODR_DATAH */\r
+#define MCF_GPIO_PODR_DATAH_PODR_DATAH0          (0x01)\r
+#define MCF_GPIO_PODR_DATAH_PODR_DATAH1          (0x02)\r
+#define MCF_GPIO_PODR_DATAH_PODR_DATAH2          (0x04)\r
+#define MCF_GPIO_PODR_DATAH_PODR_DATAH3          (0x08)\r
+#define MCF_GPIO_PODR_DATAH_PODR_DATAH4          (0x10)\r
+#define MCF_GPIO_PODR_DATAH_PODR_DATAH5          (0x20)\r
+#define MCF_GPIO_PODR_DATAH_PODR_DATAH6          (0x40)\r
+#define MCF_GPIO_PODR_DATAH_PODR_DATAH7          (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PODR_DATAL */\r
+#define MCF_GPIO_PODR_DATAL_PODR_DATAL0          (0x01)\r
+#define MCF_GPIO_PODR_DATAL_PODR_DATAL1          (0x02)\r
+#define MCF_GPIO_PODR_DATAL_PODR_DATAL2          (0x04)\r
+#define MCF_GPIO_PODR_DATAL_PODR_DATAL3          (0x08)\r
+#define MCF_GPIO_PODR_DATAL_PODR_DATAL4          (0x10)\r
+#define MCF_GPIO_PODR_DATAL_PODR_DATAL5          (0x20)\r
+#define MCF_GPIO_PODR_DATAL_PODR_DATAL6          (0x40)\r
+#define MCF_GPIO_PODR_DATAL_PODR_DATAL7          (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PODR_BUSCTL */\r
+#define MCF_GPIO_PODR_BUSCTL_PODR_BUSCTL0        (0x01)\r
+#define MCF_GPIO_PODR_BUSCTL_PODR_BUSCTL1        (0x02)\r
+#define MCF_GPIO_PODR_BUSCTL_PODR_BUSCTL2        (0x04)\r
+#define MCF_GPIO_PODR_BUSCTL_PODR_BUSCTL3        (0x08)\r
+#define MCF_GPIO_PODR_BUSCTL_PODR_BUSCTL4        (0x10)\r
+#define MCF_GPIO_PODR_BUSCTL_PODR_BUSCTL5        (0x20)\r
+#define MCF_GPIO_PODR_BUSCTL_PODR_BUSCTL6        (0x40)\r
+#define MCF_GPIO_PODR_BUSCTL_PODR_BUSCTL7        (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PODR_BS */\r
+#define MCF_GPIO_PODR_BS_PODR_BS0                (0x01)\r
+#define MCF_GPIO_PODR_BS_PODR_BS1                (0x02)\r
+#define MCF_GPIO_PODR_BS_PODR_BS2                (0x04)\r
+#define MCF_GPIO_PODR_BS_PODR_BS3                (0x08)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PODR_CS */\r
+#define MCF_GPIO_PODR_CS_PODR_CS1                (0x02)\r
+#define MCF_GPIO_PODR_CS_PODR_CS2                (0x04)\r
+#define MCF_GPIO_PODR_CS_PODR_CS3                (0x08)\r
+#define MCF_GPIO_PODR_CS_PODR_CS4                (0x10)\r
+#define MCF_GPIO_PODR_CS_PODR_CS5                (0x20)\r
+#define MCF_GPIO_PODR_CS_PODR_CS6                (0x40)\r
+#define MCF_GPIO_PODR_CS_PODR_CS7                (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PODR_SDRAM */\r
+#define MCF_GPIO_PODR_SDRAM_PODR_SDRAM0          (0x01)\r
+#define MCF_GPIO_PODR_SDRAM_PODR_SDRAM1          (0x02)\r
+#define MCF_GPIO_PODR_SDRAM_PODR_SDRAM2          (0x04)\r
+#define MCF_GPIO_PODR_SDRAM_PODR_SDRAM3          (0x08)\r
+#define MCF_GPIO_PODR_SDRAM_PODR_SDRAM4          (0x10)\r
+#define MCF_GPIO_PODR_SDRAM_PODR_SDRAM5          (0x20)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PODR_FECI2C */\r
+#define MCF_GPIO_PODR_FECI2C_PODR_FECI2C0        (0x01)\r
+#define MCF_GPIO_PODR_FECI2C_PODR_FECI2C1        (0x02)\r
+#define MCF_GPIO_PODR_FECI2C_PODR_FECI2C2        (0x04)\r
+#define MCF_GPIO_PODR_FECI2C_PODR_FECI2C3        (0x08)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PODR_UARTH */\r
+#define MCF_GPIO_PODR_UARTH_PODR_UARTH0          (0x01)\r
+#define MCF_GPIO_PODR_UARTH_PODR_UARTH1          (0x02)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PODR_UARTL */\r
+#define MCF_GPIO_PODR_UARTL_PODR_UARTL0          (0x01)\r
+#define MCF_GPIO_PODR_UARTL_PODR_UARTL1          (0x02)\r
+#define MCF_GPIO_PODR_UARTL_PODR_UARTL2          (0x04)\r
+#define MCF_GPIO_PODR_UARTL_PODR_UARTL3          (0x08)\r
+#define MCF_GPIO_PODR_UARTL_PODR_UARTL4          (0x10)\r
+#define MCF_GPIO_PODR_UARTL_PODR_UARTL5          (0x20)\r
+#define MCF_GPIO_PODR_UARTL_PODR_UARTL6          (0x40)\r
+#define MCF_GPIO_PODR_UARTL_PODR_UARTL7          (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PODR_QSPI */\r
+#define MCF_GPIO_PODR_QSPI_PODR_QSPI0            (0x01)\r
+#define MCF_GPIO_PODR_QSPI_PODR_QSPI1            (0x02)\r
+#define MCF_GPIO_PODR_QSPI_PODR_QSPI2            (0x04)\r
+#define MCF_GPIO_PODR_QSPI_PODR_QSPI3            (0x08)\r
+#define MCF_GPIO_PODR_QSPI_PODR_QSPI4            (0x10)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PODR_TIMER */\r
+#define MCF_GPIO_PODR_TIMER_PODR_TIMER0          (0x01)\r
+#define MCF_GPIO_PODR_TIMER_PODR_TIMER1          (0x02)\r
+#define MCF_GPIO_PODR_TIMER_PODR_TIMER2          (0x04)\r
+#define MCF_GPIO_PODR_TIMER_PODR_TIMER3          (0x08)\r
+#define MCF_GPIO_PODR_TIMER_PODR_TIMER4          (0x10)\r
+#define MCF_GPIO_PODR_TIMER_PODR_TIMER5          (0x20)\r
+#define MCF_GPIO_PODR_TIMER_PODR_TIMER6          (0x40)\r
+#define MCF_GPIO_PODR_TIMER_PODR_TIMER7          (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PODR_ETPU */\r
+#define MCF_GPIO_PODR_ETPU_PODR_ETPU0            (0x01)\r
+#define MCF_GPIO_PODR_ETPU_PODR_ETPU1            (0x02)\r
+#define MCF_GPIO_PODR_ETPU_PODR_ETPU2            (0x04)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PDDR_APDDR */\r
+#define MCF_GPIO_PDDR_APDDR_PDDR_APDDR5          (0x20)\r
+#define MCF_GPIO_PDDR_APDDR_PDDR_APDDR6          (0x40)\r
+#define MCF_GPIO_PDDR_APDDR_PDDR_APDDR7          (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PDDR_DATAH */\r
+#define MCF_GPIO_PDDR_DATAH_PDDR_DATAH0          (0x01)\r
+#define MCF_GPIO_PDDR_DATAH_PDDR_DATAH1          (0x02)\r
+#define MCF_GPIO_PDDR_DATAH_PDDR_DATAH2          (0x04)\r
+#define MCF_GPIO_PDDR_DATAH_PDDR_DATAH3          (0x08)\r
+#define MCF_GPIO_PDDR_DATAH_PDDR_DATAH4          (0x10)\r
+#define MCF_GPIO_PDDR_DATAH_PDDR_DATAH5          (0x20)\r
+#define MCF_GPIO_PDDR_DATAH_PDDR_DATAH6          (0x40)\r
+#define MCF_GPIO_PDDR_DATAH_PDDR_DATAH7          (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PDDR_DATAL */\r
+#define MCF_GPIO_PDDR_DATAL_PDDR_DATAL0          (0x01)\r
+#define MCF_GPIO_PDDR_DATAL_PDDR_DATAL1          (0x02)\r
+#define MCF_GPIO_PDDR_DATAL_PDDR_DATAL2          (0x04)\r
+#define MCF_GPIO_PDDR_DATAL_PDDR_DATAL3          (0x08)\r
+#define MCF_GPIO_PDDR_DATAL_PDDR_DATAL4          (0x10)\r
+#define MCF_GPIO_PDDR_DATAL_PDDR_DATAL5          (0x20)\r
+#define MCF_GPIO_PDDR_DATAL_PDDR_DATAL6          (0x40)\r
+#define MCF_GPIO_PDDR_DATAL_PDDR_DATAL7          (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PDDR_BUSCTL */\r
+#define MCF_GPIO_PDDR_BUSCTL_PDDR_BUSCTL0        (0x01)\r
+#define MCF_GPIO_PDDR_BUSCTL_PDDR_BUSCTL1        (0x02)\r
+#define MCF_GPIO_PDDR_BUSCTL_PDDR_BUSCTL2        (0x04)\r
+#define MCF_GPIO_PDDR_BUSCTL_PDDR_BUSCTL3        (0x08)\r
+#define MCF_GPIO_PDDR_BUSCTL_PDDR_BUSCTL4        (0x10)\r
+#define MCF_GPIO_PDDR_BUSCTL_PDDR_BUSCTL5        (0x20)\r
+#define MCF_GPIO_PDDR_BUSCTL_PDDR_BUSCTL6        (0x40)\r
+#define MCF_GPIO_PDDR_BUSCTL_PDDR_BUSCTL7        (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PDDR_BS */\r
+#define MCF_GPIO_PDDR_BS_PDDR_BS0                (0x01)\r
+#define MCF_GPIO_PDDR_BS_PDDR_BS3(x)             (((x)&0x07)<<1)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PDDR_CS */\r
+#define MCF_GPIO_PDDR_CS_PDDR_CS1                (0x02)\r
+#define MCF_GPIO_PDDR_CS_PDDR_CS2                (0x04)\r
+#define MCF_GPIO_PDDR_CS_PDDR_CS3                (0x08)\r
+#define MCF_GPIO_PDDR_CS_PDDR_CS4                (0x10)\r
+#define MCF_GPIO_PDDR_CS_PDDR_CS5                (0x20)\r
+#define MCF_GPIO_PDDR_CS_PDDR_CS6                (0x40)\r
+#define MCF_GPIO_PDDR_CS_PDDR_CS7                (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PDDR_SDRAM */\r
+#define MCF_GPIO_PDDR_SDRAM_PDDR_SDRAM0          (0x01)\r
+#define MCF_GPIO_PDDR_SDRAM_PDDR_SDRAM1          (0x02)\r
+#define MCF_GPIO_PDDR_SDRAM_PDDR_SDRAM2          (0x04)\r
+#define MCF_GPIO_PDDR_SDRAM_PDDR_SDRAM3          (0x08)\r
+#define MCF_GPIO_PDDR_SDRAM_PDDR_SDRAM4          (0x10)\r
+#define MCF_GPIO_PDDR_SDRAM_PDDR_SDRAM5          (0x20)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PDDR_FECI2C */\r
+#define MCF_GPIO_PDDR_FECI2C_PDDR_FECI2C0        (0x01)\r
+#define MCF_GPIO_PDDR_FECI2C_PDDR_FECI2C1        (0x02)\r
+#define MCF_GPIO_PDDR_FECI2C_PDDR_FECI2C2        (0x04)\r
+#define MCF_GPIO_PDDR_FECI2C_PDDR_FECI2C3        (0x08)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PDDR_UARTH */\r
+#define MCF_GPIO_PDDR_UARTH_PDDR_UARTH0          (0x01)\r
+#define MCF_GPIO_PDDR_UARTH_PDDR_UARTH1          (0x02)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PDDR_UARTL */\r
+#define MCF_GPIO_PDDR_UARTL_PDDR_UARTL0          (0x01)\r
+#define MCF_GPIO_PDDR_UARTL_PDDR_UARTL1          (0x02)\r
+#define MCF_GPIO_PDDR_UARTL_PDDR_UARTL2          (0x04)\r
+#define MCF_GPIO_PDDR_UARTL_PDDR_UARTL3          (0x08)\r
+#define MCF_GPIO_PDDR_UARTL_PDDR_UARTL4          (0x10)\r
+#define MCF_GPIO_PDDR_UARTL_PDDR_UARTL5          (0x20)\r
+#define MCF_GPIO_PDDR_UARTL_PDDR_UARTL6          (0x40)\r
+#define MCF_GPIO_PDDR_UARTL_PDDR_UARTL7          (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PDDR_QSPI */\r
+#define MCF_GPIO_PDDR_QSPI_PDDR_QSPI0            (0x01)\r
+#define MCF_GPIO_PDDR_QSPI_PDDR_QSPI1            (0x02)\r
+#define MCF_GPIO_PDDR_QSPI_PDDR_QSPI2            (0x04)\r
+#define MCF_GPIO_PDDR_QSPI_PDDR_QSPI3            (0x08)\r
+#define MCF_GPIO_PDDR_QSPI_PDDR_QSPI4            (0x10)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PDDR_TIMER */\r
+#define MCF_GPIO_PDDR_TIMER_PDDR_TIMER0          (0x01)\r
+#define MCF_GPIO_PDDR_TIMER_PDDR_TIMER1          (0x02)\r
+#define MCF_GPIO_PDDR_TIMER_PDDR_TIMER2          (0x04)\r
+#define MCF_GPIO_PDDR_TIMER_PDDR_TIMER3          (0x08)\r
+#define MCF_GPIO_PDDR_TIMER_PDDR_TIMER4          (0x10)\r
+#define MCF_GPIO_PDDR_TIMER_PDDR_TIMER5          (0x20)\r
+#define MCF_GPIO_PDDR_TIMER_PDDR_TIMER6          (0x40)\r
+#define MCF_GPIO_PDDR_TIMER_PDDR_TIMER7          (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PDDR_ETPU */\r
+#define MCF_GPIO_PDDR_ETPU_PDDR_ETPU0            (0x01)\r
+#define MCF_GPIO_PDDR_ETPU_PDDR_ETPU1            (0x02)\r
+#define MCF_GPIO_PDDR_ETPU_PDDR_ETPU2            (0x04)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PPDSDR_ADDR */\r
+#define MCF_GPIO_PPDSDR_ADDR_PPDSDR_ADDR5        (0x20)\r
+#define MCF_GPIO_PPDSDR_ADDR_PPDSDR_ADDR6        (0x40)\r
+#define MCF_GPIO_PPDSDR_ADDR_PPDSDR_ADDR7        (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PPDSDR_DATAH */\r
+#define MCF_GPIO_PPDSDR_DATAH_PPDSDR_DATAH0      (0x01)\r
+#define MCF_GPIO_PPDSDR_DATAH_PPDSDR_DATAH1      (0x02)\r
+#define MCF_GPIO_PPDSDR_DATAH_PPDSDR_DATAH2      (0x04)\r
+#define MCF_GPIO_PPDSDR_DATAH_PPDSDR_DATAH3      (0x08)\r
+#define MCF_GPIO_PPDSDR_DATAH_PPDSDR_DATAH4      (0x10)\r
+#define MCF_GPIO_PPDSDR_DATAH_PPDSDR_DATAH5      (0x20)\r
+#define MCF_GPIO_PPDSDR_DATAH_PPDSDR_DATAH6      (0x40)\r
+#define MCF_GPIO_PPDSDR_DATAH_PPDSDR_DATAH7      (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PPDSDR_DATAL */\r
+#define MCF_GPIO_PPDSDR_DATAL_PPDSDR_DATAL0      (0x01)\r
+#define MCF_GPIO_PPDSDR_DATAL_PPDSDR_DATAL1      (0x02)\r
+#define MCF_GPIO_PPDSDR_DATAL_PPDSDR_DATAL2      (0x04)\r
+#define MCF_GPIO_PPDSDR_DATAL_PPDSDR_DATAL3      (0x08)\r
+#define MCF_GPIO_PPDSDR_DATAL_PPDSDR_DATAL4      (0x10)\r
+#define MCF_GPIO_PPDSDR_DATAL_PPDSDR_DATAL5      (0x20)\r
+#define MCF_GPIO_PPDSDR_DATAL_PPDSDR_DATAL6      (0x40)\r
+#define MCF_GPIO_PPDSDR_DATAL_PPDSDR_DATAL7      (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PPDSDR_BUSCTL */\r
+#define MCF_GPIO_PPDSDR_BUSCTL_PPDSDR_BUSCTL0    (0x01)\r
+#define MCF_GPIO_PPDSDR_BUSCTL_PPDSDR_BUSCTL1    (0x02)\r
+#define MCF_GPIO_PPDSDR_BUSCTL_PPDSDR_BUSCTL2    (0x04)\r
+#define MCF_GPIO_PPDSDR_BUSCTL_PPDSDR_BUSCTL3    (0x08)\r
+#define MCF_GPIO_PPDSDR_BUSCTL_PPDSDR_BUSCTL4    (0x10)\r
+#define MCF_GPIO_PPDSDR_BUSCTL_PPDSDR_BUSCTL5    (0x20)\r
+#define MCF_GPIO_PPDSDR_BUSCTL_PPDSDR_BUSCTL6    (0x40)\r
+#define MCF_GPIO_PPDSDR_BUSCTL_PPDSDR_BUSCTL7    (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PPDSDR_BS */\r
+#define MCF_GPIO_PPDSDR_BS_PPDSDR_BS0            (0x01)\r
+#define MCF_GPIO_PPDSDR_BS_PPDSDR_BS1            (0x02)\r
+#define MCF_GPIO_PPDSDR_BS_PPDSDR_BS2            (0x04)\r
+#define MCF_GPIO_PPDSDR_BS_PPDSDR_BS3            (0x08)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PPDSDR_FECI2C */\r
+#define MCF_GPIO_PPDSDR_FECI2C_PPDSDR_FECI2C0    (0x01)\r
+#define MCF_GPIO_PPDSDR_FECI2C_PPDSDR_FECI2C1    (0x02)\r
+#define MCF_GPIO_PPDSDR_FECI2C_PPDSDR_FECI2C2    (0x04)\r
+#define MCF_GPIO_PPDSDR_FECI2C_PPDSDR_FECI2C3    (0x08)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PPDSDR_CS */\r
+#define MCF_GPIO_PPDSDR_CS_PPDSDR_CS1            (0x02)\r
+#define MCF_GPIO_PPDSDR_CS_PPDSDR_CS2            (0x04)\r
+#define MCF_GPIO_PPDSDR_CS_PPDSDR_CS3            (0x08)\r
+#define MCF_GPIO_PPDSDR_CS_PPDSDR_CS4            (0x10)\r
+#define MCF_GPIO_PPDSDR_CS_PPDSDR_CS5            (0x20)\r
+#define MCF_GPIO_PPDSDR_CS_PPDSDR_CS6            (0x40)\r
+#define MCF_GPIO_PPDSDR_CS_PPDSDR_CS7            (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PPDSDR_SDRAM */\r
+#define MCF_GPIO_PPDSDR_SDRAM_PPDSDR_SDRAM0      (0x01)\r
+#define MCF_GPIO_PPDSDR_SDRAM_PPDSDR_SDRAM1      (0x02)\r
+#define MCF_GPIO_PPDSDR_SDRAM_PPDSDR_SDRAM2      (0x04)\r
+#define MCF_GPIO_PPDSDR_SDRAM_PPDSDR_SDRAM3      (0x08)\r
+#define MCF_GPIO_PPDSDR_SDRAM_PPDSDR_SDRAM4      (0x10)\r
+#define MCF_GPIO_PPDSDR_SDRAM_PPDSDR_SDRAM5      (0x20)\r
+#define MCF_GPIO_PPDSDR_SDRAM_PPDSDR_SDRAM6      (0x40)\r
+#define MCF_GPIO_PPDSDR_SDRAM_PPDSDR_SDRAM7      (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PPDSDR_UARTH */\r
+#define MCF_GPIO_PPDSDR_UARTH_PPDSDR_UARTH0      (0x01)\r
+#define MCF_GPIO_PPDSDR_UARTH_PPDSDR_UARTH1      (0x02)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PPDSDR_UARTL */\r
+#define MCF_GPIO_PPDSDR_UARTL_PPDSDR_UARTL0      (0x01)\r
+#define MCF_GPIO_PPDSDR_UARTL_PPDSDR_UARTL1      (0x02)\r
+#define MCF_GPIO_PPDSDR_UARTL_PPDSDR_UARTL2      (0x04)\r
+#define MCF_GPIO_PPDSDR_UARTL_PPDSDR_UARTL3      (0x08)\r
+#define MCF_GPIO_PPDSDR_UARTL_PPDSDR_UARTL4      (0x10)\r
+#define MCF_GPIO_PPDSDR_UARTL_PPDSDR_UARTL5      (0x20)\r
+#define MCF_GPIO_PPDSDR_UARTL_PPDSDR_UARTL6      (0x40)\r
+#define MCF_GPIO_PPDSDR_UARTL_PPDSDR_UARTL7      (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PPDSDR_QSPI */\r
+#define MCF_GPIO_PPDSDR_QSPI_PPDSDR_QSPI0        (0x01)\r
+#define MCF_GPIO_PPDSDR_QSPI_PPDSDR_QSPI1        (0x02)\r
+#define MCF_GPIO_PPDSDR_QSPI_PPDSDR_QSPI2        (0x04)\r
+#define MCF_GPIO_PPDSDR_QSPI_PPDSDR_QSPI3        (0x08)\r
+#define MCF_GPIO_PPDSDR_QSPI_PPDSDR_QSPI4        (0x10)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PPDSDR_TIMER */\r
+#define MCF_GPIO_PPDSDR_TIMER_PPDSDR_TIMER0      (0x01)\r
+#define MCF_GPIO_PPDSDR_TIMER_PPDSDR_TIMER1      (0x02)\r
+#define MCF_GPIO_PPDSDR_TIMER_PPDSDR_TIMER2      (0x04)\r
+#define MCF_GPIO_PPDSDR_TIMER_PPDSDR_TIMER3      (0x08)\r
+#define MCF_GPIO_PPDSDR_TIMER_PPDSDR_TIMER4      (0x10)\r
+#define MCF_GPIO_PPDSDR_TIMER_PPDSDR_TIMER5      (0x20)\r
+#define MCF_GPIO_PPDSDR_TIMER_PPDSDR_TIMER6      (0x40)\r
+#define MCF_GPIO_PPDSDR_TIMER_PPDSDR_TIMER7      (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PPDSDR_ETPU */\r
+#define MCF_GPIO_PPDSDR_ETPU_PPDSDR_ETPU0        (0x01)\r
+#define MCF_GPIO_PPDSDR_ETPU_PPDSDR_ETPU1        (0x02)\r
+#define MCF_GPIO_PPDSDR_ETPU_PPDSDR_ETPU2        (0x04)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PCLRR_ADDR */\r
+#define MCF_GPIO_PCLRR_ADDR_PCLRR_ADDR5          (0x20)\r
+#define MCF_GPIO_PCLRR_ADDR_PCLRR_ADDR6          (0x40)\r
+#define MCF_GPIO_PCLRR_ADDR_PCLRR_ADDR7          (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PCLRR_DATAH */\r
+#define MCF_GPIO_PCLRR_DATAH_PCLRR_DATAH0        (0x01)\r
+#define MCF_GPIO_PCLRR_DATAH_PCLRR_DATAH1        (0x02)\r
+#define MCF_GPIO_PCLRR_DATAH_PCLRR_DATAH2        (0x04)\r
+#define MCF_GPIO_PCLRR_DATAH_PCLRR_DATAH3        (0x08)\r
+#define MCF_GPIO_PCLRR_DATAH_PCLRR_DATAH4        (0x10)\r
+#define MCF_GPIO_PCLRR_DATAH_PCLRR_DATAH5        (0x20)\r
+#define MCF_GPIO_PCLRR_DATAH_PCLRR_DATAH6        (0x40)\r
+#define MCF_GPIO_PCLRR_DATAH_PCLRR_DATAH7        (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PCLRR_DATAL */\r
+#define MCF_GPIO_PCLRR_DATAL_PCLRR_DATAL0        (0x01)\r
+#define MCF_GPIO_PCLRR_DATAL_PCLRR_DATAL1        (0x02)\r
+#define MCF_GPIO_PCLRR_DATAL_PCLRR_DATAL2        (0x04)\r
+#define MCF_GPIO_PCLRR_DATAL_PCLRR_DATAL3        (0x08)\r
+#define MCF_GPIO_PCLRR_DATAL_PCLRR_DATAL4        (0x10)\r
+#define MCF_GPIO_PCLRR_DATAL_PCLRR_DATAL5        (0x20)\r
+#define MCF_GPIO_PCLRR_DATAL_PCLRR_DATAL6        (0x40)\r
+#define MCF_GPIO_PCLRR_DATAL_PCLRR_DATAL7        (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PCLRR_BUSCTL */\r
+#define MCF_GPIO_PCLRR_BUSCTL_PCLRR_BUSCTL0      (0x01)\r
+#define MCF_GPIO_PCLRR_BUSCTL_PCLRR_BUSCTL1      (0x02)\r
+#define MCF_GPIO_PCLRR_BUSCTL_PCLRR_BUSCTL2      (0x04)\r
+#define MCF_GPIO_PCLRR_BUSCTL_PCLRR_BUSCTL3      (0x08)\r
+#define MCF_GPIO_PCLRR_BUSCTL_PCLRR_BUSCTL4      (0x10)\r
+#define MCF_GPIO_PCLRR_BUSCTL_PCLRR_BUSCTL5      (0x20)\r
+#define MCF_GPIO_PCLRR_BUSCTL_PCLRR_BUSCTL6      (0x40)\r
+#define MCF_GPIO_PCLRR_BUSCTL_PCLRR_BUSCTL7      (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PCLRR_BS */\r
+#define MCF_GPIO_PCLRR_BS_PCLRR_BS0              (0x01)\r
+#define MCF_GPIO_PCLRR_BS_PCLRR_BS1              (0x02)\r
+#define MCF_GPIO_PCLRR_BS_PCLRR_BS2              (0x04)\r
+#define MCF_GPIO_PCLRR_BS_PCLRR_BS3              (0x08)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PCLRR_CS */\r
+#define MCF_GPIO_PCLRR_CS_PCLRR_CS1              (0x02)\r
+#define MCF_GPIO_PCLRR_CS_PCLRR_CS2              (0x04)\r
+#define MCF_GPIO_PCLRR_CS_PCLRR_CS3              (0x08)\r
+#define MCF_GPIO_PCLRR_CS_PCLRR_CS4              (0x10)\r
+#define MCF_GPIO_PCLRR_CS_PCLRR_CS5              (0x20)\r
+#define MCF_GPIO_PCLRR_CS_PCLRR_CS6              (0x40)\r
+#define MCF_GPIO_PCLRR_CS_PCLRR_CS7              (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PCLRR_SDRAM */\r
+#define MCF_GPIO_PCLRR_SDRAM_PCLRR_SDRAM0        (0x01)\r
+#define MCF_GPIO_PCLRR_SDRAM_PCLRR_SDRAM1        (0x02)\r
+#define MCF_GPIO_PCLRR_SDRAM_PCLRR_SDRAM2        (0x04)\r
+#define MCF_GPIO_PCLRR_SDRAM_PCLRR_SDRAM3        (0x08)\r
+#define MCF_GPIO_PCLRR_SDRAM_PCLRR_SDRAM4        (0x10)\r
+#define MCF_GPIO_PCLRR_SDRAM_PCLRR_SDRAM5        (0x20)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PCLRR_FECI2C */\r
+#define MCF_GPIO_PCLRR_FECI2C_PCLRR_FECI2C0      (0x01)\r
+#define MCF_GPIO_PCLRR_FECI2C_PCLRR_FECI2C1      (0x02)\r
+#define MCF_GPIO_PCLRR_FECI2C_PCLRR_FECI2C2      (0x04)\r
+#define MCF_GPIO_PCLRR_FECI2C_PCLRR_FECI2C3      (0x08)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PCLRR_UARTH */\r
+#define MCF_GPIO_PCLRR_UARTH_PCLRR_UARTH0        (0x01)\r
+#define MCF_GPIO_PCLRR_UARTH_PCLRR_UARTH1        (0x02)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PCLRR_UARTL */\r
+#define MCF_GPIO_PCLRR_UARTL_PCLRR_UARTL0        (0x01)\r
+#define MCF_GPIO_PCLRR_UARTL_PCLRR_UARTL1        (0x02)\r
+#define MCF_GPIO_PCLRR_UARTL_PCLRR_UARTL2        (0x04)\r
+#define MCF_GPIO_PCLRR_UARTL_PCLRR_UARTL3        (0x08)\r
+#define MCF_GPIO_PCLRR_UARTL_PCLRR_UARTL4        (0x10)\r
+#define MCF_GPIO_PCLRR_UARTL_PCLRR_UARTL5        (0x20)\r
+#define MCF_GPIO_PCLRR_UARTL_PCLRR_UARTL6        (0x40)\r
+#define MCF_GPIO_PCLRR_UARTL_PCLRR_UARTL7        (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PCLRR_QSPI */\r
+#define MCF_GPIO_PCLRR_QSPI_PCLRR_QSPI0          (0x01)\r
+#define MCF_GPIO_PCLRR_QSPI_PCLRR_QSPI1          (0x02)\r
+#define MCF_GPIO_PCLRR_QSPI_PCLRR_QSPI2          (0x04)\r
+#define MCF_GPIO_PCLRR_QSPI_PCLRR_QSPI3          (0x08)\r
+#define MCF_GPIO_PCLRR_QSPI_PCLRR_QSPI4          (0x10)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PCLRR_TIMER */\r
+#define MCF_GPIO_PCLRR_TIMER_PCLRR_TIMER0        (0x01)\r
+#define MCF_GPIO_PCLRR_TIMER_PCLRR_TIMER1        (0x02)\r
+#define MCF_GPIO_PCLRR_TIMER_PCLRR_TIMER2        (0x04)\r
+#define MCF_GPIO_PCLRR_TIMER_PCLRR_TIMER3        (0x08)\r
+#define MCF_GPIO_PCLRR_TIMER_PCLRR_TIMER4        (0x10)\r
+#define MCF_GPIO_PCLRR_TIMER_PCLRR_TIMER5        (0x20)\r
+#define MCF_GPIO_PCLRR_TIMER_PCLRR_TIMER6        (0x40)\r
+#define MCF_GPIO_PCLRR_TIMER_PCLRR_TIMER7        (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PCLRR_ETPU */\r
+#define MCF_GPIO_PCLRR_ETPU_PCLRR_ETPU0          (0x01)\r
+#define MCF_GPIO_PCLRR_ETPU_PCLRR_ETPU1          (0x02)\r
+#define MCF_GPIO_PCLRR_ETPU_PCLRR_ETPU2          (0x04)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PAR_AD */\r
+#define MCF_GPIO_PAR_AD_PAR_DATAL                (0x01)\r
+#define MCF_GPIO_PAR_AD_PAR_ADDR21               (0x20)\r
+#define MCF_GPIO_PAR_AD_PAR_ADDR22               (0x40)\r
+#define MCF_GPIO_PAR_AD_PAR_ADDR23               (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PAR_BUSCTL */\r
+#define MCF_GPIO_PAR_BUSCTL_PAR_TIP(x)           (((x)&0x0003)<<0)\r
+#define MCF_GPIO_PAR_BUSCTL_PAR_TS(x)            (((x)&0x0003)<<2)\r
+#define MCF_GPIO_PAR_BUSCTL_PAR_TSIZ0            (0x0010)\r
+#define MCF_GPIO_PAR_BUSCTL_PAR_TSIZ1            (0x0040)\r
+#define MCF_GPIO_PAR_BUSCTL_PAR_RWB              (0x0100)\r
+#define MCF_GPIO_PAR_BUSCTL_PAR_TEA(x)           (((x)&0x0003)<<10)\r
+#define MCF_GPIO_PAR_BUSCTL_PAR_TA               (0x1000)\r
+#define MCF_GPIO_PAR_BUSCTL_PAR_OE               (0x4000)\r
+#define MCF_GPIO_PAR_BUSCTL_PAR_TEA_GPIO         (0x0000)\r
+#define MCF_GPIO_PAR_BUSCTL_PAR_TEA_DMA          (0x0800)\r
+#define MCF_GPIO_PAR_BUSCTL_PAR_TEA_TEA          (0x0C00)\r
+#define MCF_GPIO_PAR_BUSCTL_PAR_TS_GPIO          (0x0000)\r
+#define MCF_GPIO_PAR_BUSCTL_PAR_TS_DMA           (0x0080)\r
+#define MCF_GPIO_PAR_BUSCTL_PAR_TS_TS            (0x00C0)\r
+#define MCF_GPIO_PAR_BUSCTL_PAR_TIP_GPIO         (0x0000)\r
+#define MCF_GPIO_PAR_BUSCTL_PAR_TIP_DMA          (0x0002)\r
+#define MCF_GPIO_PAR_BUSCTL_PAR_TIP_TEA          (0x0003)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PAR_BS */\r
+#define MCF_GPIO_PAR_BS_PAR_BS0                  (0x01)\r
+#define MCF_GPIO_PAR_BS_PAR_BS1                  (0x02)\r
+#define MCF_GPIO_PAR_BS_PAR_BS2                  (0x04)\r
+#define MCF_GPIO_PAR_BS_PAR_BS3                  (0x08)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PAR_CS */\r
+#define MCF_GPIO_PAR_CS_PAR_CS1                  (0x02)\r
+#define MCF_GPIO_PAR_CS_PAR_CS2                  (0x04)\r
+#define MCF_GPIO_PAR_CS_PAR_CS3                  (0x08)\r
+#define MCF_GPIO_PAR_CS_PAR_CS4                  (0x10)\r
+#define MCF_GPIO_PAR_CS_PAR_CS5                  (0x20)\r
+#define MCF_GPIO_PAR_CS_PAR_CS6                  (0x40)\r
+#define MCF_GPIO_PAR_CS_PAR_CS7                  (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PAR_SDRAM */\r
+#define MCF_GPIO_PAR_SDRAM_PAR_SDCS0             (0x01)\r
+#define MCF_GPIO_PAR_SDRAM_PAR_SDCS1             (0x02)\r
+#define MCF_GPIO_PAR_SDRAM_PAR_SCKE              (0x04)\r
+#define MCF_GPIO_PAR_SDRAM_PAR_SRAS              (0x08)\r
+#define MCF_GPIO_PAR_SDRAM_PAR_SCAS              (0x10)\r
+#define MCF_GPIO_PAR_SDRAM_PAR_SDWE              (0x20)\r
+#define MCF_GPIO_PAR_SDRAM_PAR_CSSDCS(x)         (((x)&0x03)<<6)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PAR_FECI2C */\r
+#define MCF_GPIO_PAR_FECI2C_PAR_SDA(x)           (((x)&0x03)<<0)\r
+#define MCF_GPIO_PAR_FECI2C_PAR_SCL(x)           (((x)&0x03)<<2)\r
+#define MCF_GPIO_PAR_FECI2C_PAR_EMDIO(x)         (((x)&0x03)<<4)\r
+#define MCF_GPIO_PAR_FECI2C_PAR_EMDC(x)          (((x)&0x03)<<6)\r
+#define MCF_GPIO_PAR_FECI2C_PAR_EMDC_GPIO        (0x00)\r
+#define MCF_GPIO_PAR_FECI2C_PAR_EMDC_UART2       (0x40)\r
+#define MCF_GPIO_PAR_FECI2C_PAR_EMDC_I2C         (0x80)\r
+#define MCF_GPIO_PAR_FECI2C_PAR_EMDC_FEC         (0xC0)\r
+#define MCF_GPIO_PAR_FECI2C_PAR_EMDIO_GPIO       (0x00)\r
+#define MCF_GPIO_PAR_FECI2C_PAR_EMDIO_UART2      (0x10)\r
+#define MCF_GPIO_PAR_FECI2C_PAR_EMDIO_I2C        (0x20)\r
+#define MCF_GPIO_PAR_FECI2C_PAR_EMDIO_FEC        (0x30)\r
+#define MCF_GPIO_PAR_FECI2C_PAR_SCL_GPIO         (0x00)\r
+#define MCF_GPIO_PAR_FECI2C_PAR_SCL_FLEX         (0x08)\r
+#define MCF_GPIO_PAR_FECI2C_PAR_SCL_I2C          (0x0C)\r
+#define MCF_GPIO_PAR_FECI2C_PAR_SDA_GPIO         (0x00)\r
+#define MCF_GPIO_PAR_FECI2C_PAR_SDA_FLEX         (0x02)\r
+#define MCF_GPIO_PAR_FECI2C_PAR_SDA_I2C          (0x03)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PAR_UART */\r
+#define MCF_GPIO_PAR_UART_PAR_U0RTS              (0x0001)\r
+#define MCF_GPIO_PAR_UART_PAR_U0CTS              (0x0002)\r
+#define MCF_GPIO_PAR_UART_PAR_U0TXD              (0x0004)\r
+#define MCF_GPIO_PAR_UART_PAR_U0RXD              (0x0008)\r
+#define MCF_GPIO_PAR_UART_PAR_U1RTS(x)           (((x)&0x0003)<<4)\r
+#define MCF_GPIO_PAR_UART_PAR_U1CTS(x)           (((x)&0x0003)<<6)\r
+#define MCF_GPIO_PAR_UART_PAR_U1TXD(x)           (((x)&0x0003)<<8)\r
+#define MCF_GPIO_PAR_UART_PAR_U1RXD(x)           (((x)&0x0003)<<10)\r
+#define MCF_GPIO_PAR_UART_PAR_U2TXD              (0x1000)\r
+#define MCF_GPIO_PAR_UART_PAR_U2RXD              (0x2000)\r
+#define MCF_GPIO_PAR_UART_PAR_CAN1EN             (0x4000)\r
+#define MCF_GPIO_PAR_UART_PAR_DREQ2              (0x8000)\r
+#define MCF_GPIO_PAR_UART_PAR_U1RXD_GPIO         (0x0000)\r
+#define MCF_GPIO_PAR_UART_PAR_U1RXD_FLEX         (0x0800)\r
+#define MCF_GPIO_PAR_UART_PAR_U1RXD_UART1        (0x0C00)\r
+#define MCF_GPIO_PAR_UART_PAR_U1TXD_GPIO         (0x0000)\r
+#define MCF_GPIO_PAR_UART_PAR_U1TXD_FLEX         (0x0200)\r
+#define MCF_GPIO_PAR_UART_PAR_U1TXD_UART1        (0x0300)\r
+#define MCF_GPIO_PAR_UART_PAR_U1CTS_GPIO         (0x0000)\r
+#define MCF_GPIO_PAR_UART_PAR_U1CTS_UART2        (0x0080)\r
+#define MCF_GPIO_PAR_UART_PAR_U1CTS_UART1        (0x00C0)\r
+#define MCF_GPIO_PAR_UART_PAR_U1RTS_GPIO         (0x0000)\r
+#define MCF_GPIO_PAR_UART_PAR_U1RTS_UART2        (0x0020)\r
+#define MCF_GPIO_PAR_UART_PAR_U1RTS_UART1        (0x0030)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PAR_QSPI */\r
+#define MCF_GPIO_PAR_QSPI_PAR_SCK(x)             (((x)&0x03)<<0)\r
+#define MCF_GPIO_PAR_QSPI_PAR_DOUT               (0x04)\r
+#define MCF_GPIO_PAR_QSPI_PAR_DIN(x)             (((x)&0x03)<<3)\r
+#define MCF_GPIO_PAR_QSPI_PAR_PCS0               (0x20)\r
+#define MCF_GPIO_PAR_QSPI_PAR_PCS1(x)            (((x)&0x03)<<6)\r
+#define MCF_GPIO_PAR_QSPI_PAR_PCS1_GPIO          (0x00)\r
+#define MCF_GPIO_PAR_QSPI_PAR_PCS1_SDRAMC        (0x80)\r
+#define MCF_GPIO_PAR_QSPI_PAR_PCS1_QSPI          (0xC0)\r
+#define MCF_GPIO_PAR_QSPI_PAR_DIN_GPIO           (0x00)\r
+#define MCF_GPIO_PAR_QSPI_PAR_DIN_I2C            (0x10)\r
+#define MCF_GPIO_PAR_QSPI_PAR_DIN_QSPI           (0x1C)\r
+#define MCF_GPIO_PAR_QSPI_PAR_SCK_GPIO           (0x00)\r
+#define MCF_GPIO_PAR_QSPI_PAR_SCK_I2C            (0x02)\r
+#define MCF_GPIO_PAR_QSPI_PAR_SCK_QSPI           (0x03)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PAR_TIMER */\r
+#define MCF_GPIO_PAR_TIMER_PAR_T0OUT(x)          (((x)&0x0003)<<0)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T1OUT(x)          (((x)&0x0003)<<2)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T2OUT(x)          (((x)&0x0003)<<4)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T3OUT(x)          (((x)&0x0003)<<6)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T0IN(x)           (((x)&0x0003)<<8)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T1IN(x)           (((x)&0x0003)<<10)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T2IN(x)           (((x)&0x0003)<<12)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T3IN(x)           (((x)&0x0003)<<14)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T3IN_GPIO         (0x0000)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T3IN_QSPI         (0x4000)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T3IN_UART2        (0x8000)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T3IN_T3IN         (0xC000)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T2IN_GPIO         (0x0000)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T2IN_T2OUT        (0x1000)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T2IN_DMA          (0x2000)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T2IN_T2IN         (0x3000)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T1IN_GPIO         (0x0000)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T1IN_T1OUT        (0x0400)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T1IN_DMA          (0x0800)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T1IN_T1IN         (0x0C00)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T0IN_GPIO         (0x0000)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T0IN_DMA          (0x0200)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T0IN_T0IN         (0x0300)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T3OUT_GPIO        (0x0000)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T3OUT_QSPI        (0x0040)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T3OUT_UART2       (0x0080)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T3OUT_T3OUT       (0x00C0)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T2OUT_GPIO        (0x0000)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T2OUT_DMA         (0x0020)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T2OUT_T2OUT       (0x0030)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T1OUT_GPIO        (0x0000)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T1OUT_DMA         (0x0008)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T1OUT_T1OUT       (0x000C)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T0OUT_GPIO        (0x0000)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T0OUT_DMA         (0x0002)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T0OUT_T0OUT       (0x0003)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PAR_ETPU */\r
+#define MCF_GPIO_PAR_ETPU_PAR_LTPU_ODIS          (0x01)\r
+#define MCF_GPIO_PAR_ETPU_PAR_UTPU_ODIS          (0x02)\r
+#define MCF_GPIO_PAR_ETPU_PAR_TCRCLK             (0x04)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_DSCR_EIM */\r
+#define MCF_GPIO_DSCR_EIM_DSCR_EIM0              (0x01)\r
+#define MCF_GPIO_DSCR_EIM_DSCR_EIM1              (0x10)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_DSCR_ETPU */\r
+#define MCF_GPIO_DSCR_ETPU_DSCR_ETPU_7_0         (0x01)\r
+#define MCF_GPIO_DSCR_ETPU_DSCR_ETPU_15_8        (0x04)\r
+#define MCF_GPIO_DSCR_ETPU_DSCR_ETPU_23_16       (0x10)\r
+#define MCF_GPIO_DSCR_ETPU_DSCR_ETPU_31_24       (0x40)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_DSCR_FECI2C */\r
+#define MCF_GPIO_DSCR_FECI2C_DSCR_I2C            (0x01)\r
+#define MCF_GPIO_DSCR_FECI2C_DSCR_FEC            (0x10)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_DSCR_UART */\r
+#define MCF_GPIO_DSCR_UART_DSCR_UART0            (0x01)\r
+#define MCF_GPIO_DSCR_UART_DSCR_UART1            (0x04)\r
+#define MCF_GPIO_DSCR_UART_DSCR_UART2            (0x10)\r
+#define MCF_GPIO_DSCR_UART_DSCR_IRQ              (0x40)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_DSCR_QSPI */\r
+#define MCF_GPIO_DSCR_QSPI_DSCR_QSPI             (0x01)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_DSCR_TIMER */\r
+#define MCF_GPIO_DSCR_TIMER_DSCR_TIMER           (0x01)\r
+\r
+/********************************************************************/\r
+\r
+#endif /* __MCF523X_GPIO_H__ */\r
index ee46655070fc79c9d58fc3153cb49ca7cf40d9ed..3bb780b826335a52926c590c78881c66fd3e3b4b 100644 (file)
@@ -1,63 +1,63 @@
-/*
- * These files are taken from the MCF523X source code example package
- * which is available on the Freescale website. Freescale explicitly 
- * grants the redistribution and modification of these source files.
- * The complete licensing information is available in the file 
- * LICENSE_FREESCALE.TXT.
- *
- * File:       mcf523x_i2c.h
- * Purpose:    Register and bit definitions for the MCF523X
- *
- * Notes:      
- *     
- */
-
-#ifndef __MCF523X_I2C_H__
-#define __MCF523X_I2C_H__
-
-/*********************************************************************
-*
-* I2C Module (I2C)
-*
-*********************************************************************/
-
-/* Register read/write macros */
-#define MCF_I2C_I2AR     (*(vuint8 *)(void*)(&__IPSBAR[0x000300]))
-#define MCF_I2C_I2FDR    (*(vuint8 *)(void*)(&__IPSBAR[0x000304]))
-#define MCF_I2C_I2CR     (*(vuint8 *)(void*)(&__IPSBAR[0x000308]))
-#define MCF_I2C_I2SR     (*(vuint8 *)(void*)(&__IPSBAR[0x00030C]))
-#define MCF_I2C_I2DR     (*(vuint8 *)(void*)(&__IPSBAR[0x000310]))
-#define MCF_I2C_I2ICR    (*(vuint8 *)(void*)(&__IPSBAR[0x000320]))
-
-/* Bit definitions and macros for MCF_I2C_I2AR */
-#define MCF_I2C_I2AR_ADR(x)    (((x)&0x7F)<<1)
-
-/* Bit definitions and macros for MCF_I2C_I2FDR */
-#define MCF_I2C_I2FDR_IC(x)    (((x)&0x3F)<<0)
-
-/* Bit definitions and macros for MCF_I2C_I2CR */
-#define MCF_I2C_I2CR_RSTA      (0x04)
-#define MCF_I2C_I2CR_TXAK      (0x08)
-#define MCF_I2C_I2CR_MTX       (0x10)
-#define MCF_I2C_I2CR_MSTA      (0x20)
-#define MCF_I2C_I2CR_IIEN      (0x40)
-#define MCF_I2C_I2CR_IEN       (0x80)
-
-/* Bit definitions and macros for MCF_I2C_I2SR */
-#define MCF_I2C_I2SR_RXAK      (0x01)
-#define MCF_I2C_I2SR_IIF       (0x02)
-#define MCF_I2C_I2SR_SRW       (0x04)
-#define MCF_I2C_I2SR_IAL       (0x10)
-#define MCF_I2C_I2SR_IBB       (0x20)
-#define MCF_I2C_I2SR_IAAS      (0x40)
-#define MCF_I2C_I2SR_ICF       (0x80)
-
-/* Bit definitions and macros for MCF_I2C_I2ICR */
-#define MCF_I2C_I2ICR_IE       (0x01)
-#define MCF_I2C_I2ICR_RE       (0x02)
-#define MCF_I2C_I2ICR_TE       (0x04)
-#define MCF_I2C_I2ICR_BNBE     (0x08)
-
-/********************************************************************/
-
-#endif /* __MCF523X_I2C_H__ */
+/*\r
+ * These files are taken from the MCF523X source code example package\r
+ * which is available on the Freescale website. Freescale explicitly \r
+ * grants the redistribution and modification of these source files.\r
+ * The complete licensing information is available in the file \r
+ * LICENSE_FREESCALE.TXT.\r
+ *\r
+ * File:       mcf523x_i2c.h\r
+ * Purpose:    Register and bit definitions for the MCF523X\r
+ *\r
+ * Notes:      \r
+ *     \r
+ */\r
+\r
+#ifndef __MCF523X_I2C_H__\r
+#define __MCF523X_I2C_H__\r
+\r
+/*********************************************************************\r
+*\r
+* I2C Module (I2C)\r
+*\r
+*********************************************************************/\r
+\r
+/* Register read/write macros */\r
+#define MCF_I2C_I2AR     (*(vuint8 *)(void*)(&__IPSBAR[0x000300]))\r
+#define MCF_I2C_I2FDR    (*(vuint8 *)(void*)(&__IPSBAR[0x000304]))\r
+#define MCF_I2C_I2CR     (*(vuint8 *)(void*)(&__IPSBAR[0x000308]))\r
+#define MCF_I2C_I2SR     (*(vuint8 *)(void*)(&__IPSBAR[0x00030C]))\r
+#define MCF_I2C_I2DR     (*(vuint8 *)(void*)(&__IPSBAR[0x000310]))\r
+#define MCF_I2C_I2ICR    (*(vuint8 *)(void*)(&__IPSBAR[0x000320]))\r
+\r
+/* Bit definitions and macros for MCF_I2C_I2AR */\r
+#define MCF_I2C_I2AR_ADR(x)    (((x)&0x7F)<<1)\r
+\r
+/* Bit definitions and macros for MCF_I2C_I2FDR */\r
+#define MCF_I2C_I2FDR_IC(x)    (((x)&0x3F)<<0)\r
+\r
+/* Bit definitions and macros for MCF_I2C_I2CR */\r
+#define MCF_I2C_I2CR_RSTA      (0x04)\r
+#define MCF_I2C_I2CR_TXAK      (0x08)\r
+#define MCF_I2C_I2CR_MTX       (0x10)\r
+#define MCF_I2C_I2CR_MSTA      (0x20)\r
+#define MCF_I2C_I2CR_IIEN      (0x40)\r
+#define MCF_I2C_I2CR_IEN       (0x80)\r
+\r
+/* Bit definitions and macros for MCF_I2C_I2SR */\r
+#define MCF_I2C_I2SR_RXAK      (0x01)\r
+#define MCF_I2C_I2SR_IIF       (0x02)\r
+#define MCF_I2C_I2SR_SRW       (0x04)\r
+#define MCF_I2C_I2SR_IAL       (0x10)\r
+#define MCF_I2C_I2SR_IBB       (0x20)\r
+#define MCF_I2C_I2SR_IAAS      (0x40)\r
+#define MCF_I2C_I2SR_ICF       (0x80)\r
+\r
+/* Bit definitions and macros for MCF_I2C_I2ICR */\r
+#define MCF_I2C_I2ICR_IE       (0x01)\r
+#define MCF_I2C_I2ICR_RE       (0x02)\r
+#define MCF_I2C_I2ICR_TE       (0x04)\r
+#define MCF_I2C_I2ICR_BNBE     (0x08)\r
+\r
+/********************************************************************/\r
+\r
+#endif /* __MCF523X_I2C_H__ */\r
index 7d19e9863186f5a8d95ccbcdba9b04681fe3a850..2e06524f460f115204b2ea31896649569a575a58 100644 (file)
-/*
- * These files are taken from the MCF523X source code example package
- * which is available on the Freescale website. Freescale explicitly 
- * grants the redistribution and modification of these source files.
- * The complete licensing information is available in the file 
- * LICENSE_FREESCALE.TXT.
- *
- * File:       mcf523x_intc0.h
- * Purpose:    Register and bit definitions for the MCF523X
- *
- * Notes:      
- *     
- */
-
-#ifndef __MCF523X_INTC0_H__
-#define __MCF523X_INTC0_H__
-
-/*********************************************************************
-*
-* Interrupt Controller 0 (INTC0)
-*
-*********************************************************************/
-
-/* Register read/write macros */
-#define MCF_INTC0_IPRH         (*(vuint32*)(void*)(&__IPSBAR[0x000C00]))
-#define MCF_INTC0_IPRL         (*(vuint32*)(void*)(&__IPSBAR[0x000C04]))
-#define MCF_INTC0_IMRH         (*(vuint32*)(void*)(&__IPSBAR[0x000C08]))
-#define MCF_INTC0_IMRL         (*(vuint32*)(void*)(&__IPSBAR[0x000C0C]))
-#define MCF_INTC0_INTFRCH      (*(vuint32*)(void*)(&__IPSBAR[0x000C10]))
-#define MCF_INTC0_INTFRCL      (*(vuint32*)(void*)(&__IPSBAR[0x000C14]))
-#define MCF_INTC0_IRLR         (*(vuint8 *)(void*)(&__IPSBAR[0x000C18]))
-#define MCF_INTC0_IACKLPR      (*(vuint8 *)(void*)(&__IPSBAR[0x000C19]))
-#define MCF_INTC0_ICR0         (*(vuint8 *)(void*)(&__IPSBAR[0x000C40]))
-#define MCF_INTC0_ICR1         (*(vuint8 *)(void*)(&__IPSBAR[0x000C41]))
-#define MCF_INTC0_ICR2         (*(vuint8 *)(void*)(&__IPSBAR[0x000C42]))
-#define MCF_INTC0_ICR3         (*(vuint8 *)(void*)(&__IPSBAR[0x000C43]))
-#define MCF_INTC0_ICR4         (*(vuint8 *)(void*)(&__IPSBAR[0x000C44]))
-#define MCF_INTC0_ICR5         (*(vuint8 *)(void*)(&__IPSBAR[0x000C45]))
-#define MCF_INTC0_ICR6         (*(vuint8 *)(void*)(&__IPSBAR[0x000C46]))
-#define MCF_INTC0_ICR7         (*(vuint8 *)(void*)(&__IPSBAR[0x000C47]))
-#define MCF_INTC0_ICR8         (*(vuint8 *)(void*)(&__IPSBAR[0x000C48]))
-#define MCF_INTC0_ICR9         (*(vuint8 *)(void*)(&__IPSBAR[0x000C49]))
-#define MCF_INTC0_ICR10        (*(vuint8 *)(void*)(&__IPSBAR[0x000C4A]))
-#define MCF_INTC0_ICR11        (*(vuint8 *)(void*)(&__IPSBAR[0x000C4B]))
-#define MCF_INTC0_ICR12        (*(vuint8 *)(void*)(&__IPSBAR[0x000C4C]))
-#define MCF_INTC0_ICR13        (*(vuint8 *)(void*)(&__IPSBAR[0x000C4D]))
-#define MCF_INTC0_ICR14        (*(vuint8 *)(void*)(&__IPSBAR[0x000C4E]))
-#define MCF_INTC0_ICR15        (*(vuint8 *)(void*)(&__IPSBAR[0x000C4F]))
-#define MCF_INTC0_ICR16        (*(vuint8 *)(void*)(&__IPSBAR[0x000C50]))
-#define MCF_INTC0_ICR17        (*(vuint8 *)(void*)(&__IPSBAR[0x000C51]))
-#define MCF_INTC0_ICR18        (*(vuint8 *)(void*)(&__IPSBAR[0x000C52]))
-#define MCF_INTC0_ICR19        (*(vuint8 *)(void*)(&__IPSBAR[0x000C53]))
-#define MCF_INTC0_ICR20        (*(vuint8 *)(void*)(&__IPSBAR[0x000C54]))
-#define MCF_INTC0_ICR21        (*(vuint8 *)(void*)(&__IPSBAR[0x000C55]))
-#define MCF_INTC0_ICR22        (*(vuint8 *)(void*)(&__IPSBAR[0x000C56]))
-#define MCF_INTC0_ICR23        (*(vuint8 *)(void*)(&__IPSBAR[0x000C57]))
-#define MCF_INTC0_ICR24        (*(vuint8 *)(void*)(&__IPSBAR[0x000C58]))
-#define MCF_INTC0_ICR25        (*(vuint8 *)(void*)(&__IPSBAR[0x000C59]))
-#define MCF_INTC0_ICR26        (*(vuint8 *)(void*)(&__IPSBAR[0x000C5A]))
-#define MCF_INTC0_ICR27        (*(vuint8 *)(void*)(&__IPSBAR[0x000C5B]))
-#define MCF_INTC0_ICR28        (*(vuint8 *)(void*)(&__IPSBAR[0x000C5C]))
-#define MCF_INTC0_ICR29        (*(vuint8 *)(void*)(&__IPSBAR[0x000C5D]))
-#define MCF_INTC0_ICR30        (*(vuint8 *)(void*)(&__IPSBAR[0x000C5E]))
-#define MCF_INTC0_ICR31        (*(vuint8 *)(void*)(&__IPSBAR[0x000C5F]))
-#define MCF_INTC0_ICR32        (*(vuint8 *)(void*)(&__IPSBAR[0x000C60]))
-#define MCF_INTC0_ICR33        (*(vuint8 *)(void*)(&__IPSBAR[0x000C61]))
-#define MCF_INTC0_ICR34        (*(vuint8 *)(void*)(&__IPSBAR[0x000C62]))
-#define MCF_INTC0_ICR35        (*(vuint8 *)(void*)(&__IPSBAR[0x000C63]))
-#define MCF_INTC0_ICR36        (*(vuint8 *)(void*)(&__IPSBAR[0x000C64]))
-#define MCF_INTC0_ICR37        (*(vuint8 *)(void*)(&__IPSBAR[0x000C65]))
-#define MCF_INTC0_ICR38        (*(vuint8 *)(void*)(&__IPSBAR[0x000C66]))
-#define MCF_INTC0_ICR39        (*(vuint8 *)(void*)(&__IPSBAR[0x000C67]))
-#define MCF_INTC0_ICR40        (*(vuint8 *)(void*)(&__IPSBAR[0x000C68]))
-#define MCF_INTC0_ICR41        (*(vuint8 *)(void*)(&__IPSBAR[0x000C69]))
-#define MCF_INTC0_ICR42        (*(vuint8 *)(void*)(&__IPSBAR[0x000C6A]))
-#define MCF_INTC0_ICR43        (*(vuint8 *)(void*)(&__IPSBAR[0x000C6B]))
-#define MCF_INTC0_ICR44        (*(vuint8 *)(void*)(&__IPSBAR[0x000C6C]))
-#define MCF_INTC0_ICR45        (*(vuint8 *)(void*)(&__IPSBAR[0x000C6D]))
-#define MCF_INTC0_ICR46        (*(vuint8 *)(void*)(&__IPSBAR[0x000C6E]))
-#define MCF_INTC0_ICR47        (*(vuint8 *)(void*)(&__IPSBAR[0x000C6F]))
-#define MCF_INTC0_ICR48        (*(vuint8 *)(void*)(&__IPSBAR[0x000C70]))
-#define MCF_INTC0_ICR49        (*(vuint8 *)(void*)(&__IPSBAR[0x000C71]))
-#define MCF_INTC0_ICR50        (*(vuint8 *)(void*)(&__IPSBAR[0x000C72]))
-#define MCF_INTC0_ICR51        (*(vuint8 *)(void*)(&__IPSBAR[0x000C73]))
-#define MCF_INTC0_ICR52        (*(vuint8 *)(void*)(&__IPSBAR[0x000C74]))
-#define MCF_INTC0_ICR53        (*(vuint8 *)(void*)(&__IPSBAR[0x000C75]))
-#define MCF_INTC0_ICR54        (*(vuint8 *)(void*)(&__IPSBAR[0x000C76]))
-#define MCF_INTC0_ICR55        (*(vuint8 *)(void*)(&__IPSBAR[0x000C77]))
-#define MCF_INTC0_ICR56        (*(vuint8 *)(void*)(&__IPSBAR[0x000C78]))
-#define MCF_INTC0_ICR57        (*(vuint8 *)(void*)(&__IPSBAR[0x000C79]))
-#define MCF_INTC0_ICR58        (*(vuint8 *)(void*)(&__IPSBAR[0x000C7A]))
-#define MCF_INTC0_ICR59        (*(vuint8 *)(void*)(&__IPSBAR[0x000C7B]))
-#define MCF_INTC0_ICR60        (*(vuint8 *)(void*)(&__IPSBAR[0x000C7C]))
-#define MCF_INTC0_ICR61        (*(vuint8 *)(void*)(&__IPSBAR[0x000C7D]))
-#define MCF_INTC0_ICR62        (*(vuint8 *)(void*)(&__IPSBAR[0x000C7E]))
-#define MCF_INTC0_ICR63        (*(vuint8 *)(void*)(&__IPSBAR[0x000C7F]))
-#define MCF_INTC0_ICRn(x)      (*(vuint8 *)(void*)(&__IPSBAR[0x000C40+((x)*0x001)]))
-#define MCF_INTC0_SWIACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000CE0]))
-#define MCF_INTC0_L1IACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000CE4]))
-#define MCF_INTC0_L2IACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000CE8]))
-#define MCF_INTC0_L3IACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000CEC]))
-#define MCF_INTC0_L4IACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000CF0]))
-#define MCF_INTC0_L5IACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000CF4]))
-#define MCF_INTC0_L6IACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000CF8]))
-#define MCF_INTC0_L7IACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000CFC]))
-#define MCF_INTC0_LnIACK(x)    (*(vuint8 *)(void*)(&__IPSBAR[0x000CE4+((x)*0x004)]))
-
-/* Bit definitions and macros for MCF_INTC0_IPRH */
-#define MCF_INTC0_IPRH_INT32          (0x00000001)
-#define MCF_INTC0_IPRH_INT33          (0x00000002)
-#define MCF_INTC0_IPRH_INT34          (0x00000004)
-#define MCF_INTC0_IPRH_INT35          (0x00000008)
-#define MCF_INTC0_IPRH_INT36          (0x00000010)
-#define MCF_INTC0_IPRH_INT37          (0x00000020)
-#define MCF_INTC0_IPRH_INT38          (0x00000040)
-#define MCF_INTC0_IPRH_INT39          (0x00000080)
-#define MCF_INTC0_IPRH_INT40          (0x00000100)
-#define MCF_INTC0_IPRH_INT41          (0x00000200)
-#define MCF_INTC0_IPRH_INT42          (0x00000400)
-#define MCF_INTC0_IPRH_INT43          (0x00000800)
-#define MCF_INTC0_IPRH_INT44          (0x00001000)
-#define MCF_INTC0_IPRH_INT45          (0x00002000)
-#define MCF_INTC0_IPRH_INT46          (0x00004000)
-#define MCF_INTC0_IPRH_INT47          (0x00008000)
-#define MCF_INTC0_IPRH_INT48          (0x00010000)
-#define MCF_INTC0_IPRH_INT49          (0x00020000)
-#define MCF_INTC0_IPRH_INT50          (0x00040000)
-#define MCF_INTC0_IPRH_INT51          (0x00080000)
-#define MCF_INTC0_IPRH_INT52          (0x00100000)
-#define MCF_INTC0_IPRH_INT53          (0x00200000)
-#define MCF_INTC0_IPRH_INT54          (0x00400000)
-#define MCF_INTC0_IPRH_INT55          (0x00800000)
-#define MCF_INTC0_IPRH_INT56          (0x01000000)
-#define MCF_INTC0_IPRH_INT57          (0x02000000)
-#define MCF_INTC0_IPRH_INT58          (0x04000000)
-#define MCF_INTC0_IPRH_INT59          (0x08000000)
-#define MCF_INTC0_IPRH_INT60          (0x10000000)
-#define MCF_INTC0_IPRH_INT61          (0x20000000)
-#define MCF_INTC0_IPRH_INT62          (0x40000000)
-#define MCF_INTC0_IPRH_INT63          (0x80000000)
-
-/* Bit definitions and macros for MCF_INTC0_IPRL */
-#define MCF_INTC0_IPRL_INT1           (0x00000002)
-#define MCF_INTC0_IPRL_INT2           (0x00000004)
-#define MCF_INTC0_IPRL_INT3           (0x00000008)
-#define MCF_INTC0_IPRL_INT4           (0x00000010)
-#define MCF_INTC0_IPRL_INT5           (0x00000020)
-#define MCF_INTC0_IPRL_INT6           (0x00000040)
-#define MCF_INTC0_IPRL_INT7           (0x00000080)
-#define MCF_INTC0_IPRL_INT8           (0x00000100)
-#define MCF_INTC0_IPRL_INT9           (0x00000200)
-#define MCF_INTC0_IPRL_INT10          (0x00000400)
-#define MCF_INTC0_IPRL_INT11          (0x00000800)
-#define MCF_INTC0_IPRL_INT12          (0x00001000)
-#define MCF_INTC0_IPRL_INT13          (0x00002000)
-#define MCF_INTC0_IPRL_INT14          (0x00004000)
-#define MCF_INTC0_IPRL_INT15          (0x00008000)
-#define MCF_INTC0_IPRL_INT16          (0x00010000)
-#define MCF_INTC0_IPRL_INT17          (0x00020000)
-#define MCF_INTC0_IPRL_INT18          (0x00040000)
-#define MCF_INTC0_IPRL_INT19          (0x00080000)
-#define MCF_INTC0_IPRL_INT20          (0x00100000)
-#define MCF_INTC0_IPRL_INT21          (0x00200000)
-#define MCF_INTC0_IPRL_INT22          (0x00400000)
-#define MCF_INTC0_IPRL_INT23          (0x00800000)
-#define MCF_INTC0_IPRL_INT24          (0x01000000)
-#define MCF_INTC0_IPRL_INT25          (0x02000000)
-#define MCF_INTC0_IPRL_INT26          (0x04000000)
-#define MCF_INTC0_IPRL_INT27          (0x08000000)
-#define MCF_INTC0_IPRL_INT28          (0x10000000)
-#define MCF_INTC0_IPRL_INT29          (0x20000000)
-#define MCF_INTC0_IPRL_INT30          (0x40000000)
-#define MCF_INTC0_IPRL_INT31          (0x80000000)
-
-/* Bit definitions and macros for MCF_INTC0_IMRH */
-#define MCF_INTC0_IMRH_INT_MASK32     (0x00000001)
-#define MCF_INTC0_IMRH_INT_MASK33     (0x00000002)
-#define MCF_INTC0_IMRH_INT_MASK34     (0x00000004)
-#define MCF_INTC0_IMRH_INT_MASK35     (0x00000008)
-#define MCF_INTC0_IMRH_INT_MASK36     (0x00000010)
-#define MCF_INTC0_IMRH_INT_MASK37     (0x00000020)
-#define MCF_INTC0_IMRH_INT_MASK38     (0x00000040)
-#define MCF_INTC0_IMRH_INT_MASK39     (0x00000080)
-#define MCF_INTC0_IMRH_INT_MASK40     (0x00000100)
-#define MCF_INTC0_IMRH_INT_MASK41     (0x00000200)
-#define MCF_INTC0_IMRH_INT_MASK42     (0x00000400)
-#define MCF_INTC0_IMRH_INT_MASK43     (0x00000800)
-#define MCF_INTC0_IMRH_INT_MASK44     (0x00001000)
-#define MCF_INTC0_IMRH_INT_MASK45     (0x00002000)
-#define MCF_INTC0_IMRH_INT_MASK46     (0x00004000)
-#define MCF_INTC0_IMRH_INT_MASK47     (0x00008000)
-#define MCF_INTC0_IMRH_INT_MASK48     (0x00010000)
-#define MCF_INTC0_IMRH_INT_MASK49     (0x00020000)
-#define MCF_INTC0_IMRH_INT_MASK50     (0x00040000)
-#define MCF_INTC0_IMRH_INT_MASK51     (0x00080000)
-#define MCF_INTC0_IMRH_INT_MASK52     (0x00100000)
-#define MCF_INTC0_IMRH_INT_MASK53     (0x00200000)
-#define MCF_INTC0_IMRH_INT_MASK54     (0x00400000)
-#define MCF_INTC0_IMRH_INT_MASK55     (0x00800000)
-#define MCF_INTC0_IMRH_INT_MASK56     (0x01000000)
-#define MCF_INTC0_IMRH_INT_MASK57     (0x02000000)
-#define MCF_INTC0_IMRH_INT_MASK58     (0x04000000)
-#define MCF_INTC0_IMRH_INT_MASK59     (0x08000000)
-#define MCF_INTC0_IMRH_INT_MASK60     (0x10000000)
-#define MCF_INTC0_IMRH_INT_MASK61     (0x20000000)
-#define MCF_INTC0_IMRH_INT_MASK62     (0x40000000)
-#define MCF_INTC0_IMRH_INT_MASK63     (0x80000000)
-
-/* Bit definitions and macros for MCF_INTC0_IMRL */
-#define MCF_INTC0_IMRL_MASKALL        (0x00000001)
-#define MCF_INTC0_IMRL_INT_MASK1      (0x00000002)
-#define MCF_INTC0_IMRL_INT_MASK2      (0x00000004)
-#define MCF_INTC0_IMRL_INT_MASK3      (0x00000008)
-#define MCF_INTC0_IMRL_INT_MASK4      (0x00000010)
-#define MCF_INTC0_IMRL_INT_MASK5      (0x00000020)
-#define MCF_INTC0_IMRL_INT_MASK6      (0x00000040)
-#define MCF_INTC0_IMRL_INT_MASK7      (0x00000080)
-#define MCF_INTC0_IMRL_INT_MASK8      (0x00000100)
-#define MCF_INTC0_IMRL_INT_MASK9      (0x00000200)
-#define MCF_INTC0_IMRL_INT_MASK10     (0x00000400)
-#define MCF_INTC0_IMRL_INT_MASK11     (0x00000800)
-#define MCF_INTC0_IMRL_INT_MASK12     (0x00001000)
-#define MCF_INTC0_IMRL_INT_MASK13     (0x00002000)
-#define MCF_INTC0_IMRL_INT_MASK14     (0x00004000)
-#define MCF_INTC0_IMRL_INT_MASK15     (0x00008000)
-#define MCF_INTC0_IMRL_INT_MASK16     (0x00010000)
-#define MCF_INTC0_IMRL_INT_MASK17     (0x00020000)
-#define MCF_INTC0_IMRL_INT_MASK18     (0x00040000)
-#define MCF_INTC0_IMRL_INT_MASK19     (0x00080000)
-#define MCF_INTC0_IMRL_INT_MASK20     (0x00100000)
-#define MCF_INTC0_IMRL_INT_MASK21     (0x00200000)
-#define MCF_INTC0_IMRL_INT_MASK22     (0x00400000)
-#define MCF_INTC0_IMRL_INT_MASK23     (0x00800000)
-#define MCF_INTC0_IMRL_INT_MASK24     (0x01000000)
-#define MCF_INTC0_IMRL_INT_MASK25     (0x02000000)
-#define MCF_INTC0_IMRL_INT_MASK26     (0x04000000)
-#define MCF_INTC0_IMRL_INT_MASK27     (0x08000000)
-#define MCF_INTC0_IMRL_INT_MASK28     (0x10000000)
-#define MCF_INTC0_IMRL_INT_MASK29     (0x20000000)
-#define MCF_INTC0_IMRL_INT_MASK30     (0x40000000)
-#define MCF_INTC0_IMRL_INT_MASK31     (0x80000000)
-
-/* Bit definitions and macros for MCF_INTC0_INTFRCH */
-#define MCF_INTC0_INTFRCH_INTFRC32    (0x00000001)
-#define MCF_INTC0_INTFRCH_INTFRC33    (0x00000002)
-#define MCF_INTC0_INTFRCH_INTFRC34    (0x00000004)
-#define MCF_INTC0_INTFRCH_INTFRC35    (0x00000008)
-#define MCF_INTC0_INTFRCH_INTFRC36    (0x00000010)
-#define MCF_INTC0_INTFRCH_INTFRC37    (0x00000020)
-#define MCF_INTC0_INTFRCH_INTFRC38    (0x00000040)
-#define MCF_INTC0_INTFRCH_INTFRC39    (0x00000080)
-#define MCF_INTC0_INTFRCH_INTFRC40    (0x00000100)
-#define MCF_INTC0_INTFRCH_INTFRC41    (0x00000200)
-#define MCF_INTC0_INTFRCH_INTFRC42    (0x00000400)
-#define MCF_INTC0_INTFRCH_INTFRC43    (0x00000800)
-#define MCF_INTC0_INTFRCH_INTFRC44    (0x00001000)
-#define MCF_INTC0_INTFRCH_INTFRC45    (0x00002000)
-#define MCF_INTC0_INTFRCH_INTFRC46    (0x00004000)
-#define MCF_INTC0_INTFRCH_INTFRC47    (0x00008000)
-#define MCF_INTC0_INTFRCH_INTFRC48    (0x00010000)
-#define MCF_INTC0_INTFRCH_INTFRC49    (0x00020000)
-#define MCF_INTC0_INTFRCH_INTFRC50    (0x00040000)
-#define MCF_INTC0_INTFRCH_INTFRC51    (0x00080000)
-#define MCF_INTC0_INTFRCH_INTFRC52    (0x00100000)
-#define MCF_INTC0_INTFRCH_INTFRC53    (0x00200000)
-#define MCF_INTC0_INTFRCH_INTFRC54    (0x00400000)
-#define MCF_INTC0_INTFRCH_INTFRC55    (0x00800000)
-#define MCF_INTC0_INTFRCH_INTFRC56    (0x01000000)
-#define MCF_INTC0_INTFRCH_INTFRC57    (0x02000000)
-#define MCF_INTC0_INTFRCH_INTFRC58    (0x04000000)
-#define MCF_INTC0_INTFRCH_INTFRC59    (0x08000000)
-#define MCF_INTC0_INTFRCH_INTFRC60    (0x10000000)
-#define MCF_INTC0_INTFRCH_INTFRC61    (0x20000000)
-#define MCF_INTC0_INTFRCH_INTFRC62    (0x40000000)
-#define MCF_INTC0_INTFRCH_INTFRC63    (0x80000000)
-
-/* Bit definitions and macros for MCF_INTC0_INTFRCL */
-#define MCF_INTC0_INTFRCL_INTFRC1     (0x00000002)
-#define MCF_INTC0_INTFRCL_INTFRC2     (0x00000004)
-#define MCF_INTC0_INTFRCL_INTFRC3     (0x00000008)
-#define MCF_INTC0_INTFRCL_INTFRC4     (0x00000010)
-#define MCF_INTC0_INTFRCL_INTFRC5     (0x00000020)
-#define MCF_INTC0_INTFRCL_INT6        (0x00000040)
-#define MCF_INTC0_INTFRCL_INT7        (0x00000080)
-#define MCF_INTC0_INTFRCL_INT8        (0x00000100)
-#define MCF_INTC0_INTFRCL_INT9        (0x00000200)
-#define MCF_INTC0_INTFRCL_INT10       (0x00000400)
-#define MCF_INTC0_INTFRCL_INTFRC11    (0x00000800)
-#define MCF_INTC0_INTFRCL_INTFRC12    (0x00001000)
-#define MCF_INTC0_INTFRCL_INTFRC13    (0x00002000)
-#define MCF_INTC0_INTFRCL_INTFRC14    (0x00004000)
-#define MCF_INTC0_INTFRCL_INT15       (0x00008000)
-#define MCF_INTC0_INTFRCL_INTFRC16    (0x00010000)
-#define MCF_INTC0_INTFRCL_INTFRC17    (0x00020000)
-#define MCF_INTC0_INTFRCL_INTFRC18    (0x00040000)
-#define MCF_INTC0_INTFRCL_INTFRC19    (0x00080000)
-#define MCF_INTC0_INTFRCL_INTFRC20    (0x00100000)
-#define MCF_INTC0_INTFRCL_INTFRC21    (0x00200000)
-#define MCF_INTC0_INTFRCL_INTFRC22    (0x00400000)
-#define MCF_INTC0_INTFRCL_INTFRC23    (0x00800000)
-#define MCF_INTC0_INTFRCL_INTFRC24    (0x01000000)
-#define MCF_INTC0_INTFRCL_INTFRC25    (0x02000000)
-#define MCF_INTC0_INTFRCL_INTFRC26    (0x04000000)
-#define MCF_INTC0_INTFRCL_INTFRC27    (0x08000000)
-#define MCF_INTC0_INTFRCL_INTFRC28    (0x10000000)
-#define MCF_INTC0_INTFRCL_INTFRC29    (0x20000000)
-#define MCF_INTC0_INTFRCL_INTFRC30    (0x40000000)
-#define MCF_INTC0_INTFRCL_INTFRC31    (0x80000000)
-
-/* Bit definitions and macros for MCF_INTC0_IRLR */
-#define MCF_INTC0_IRLR_IRQ(x)         (((x)&0x7F)<<1)
-
-/* Bit definitions and macros for MCF_INTC0_IACKLPR */
-#define MCF_INTC0_IACKLPR_PRI(x)      (((x)&0x0F)<<0)
-#define MCF_INTC0_IACKLPR_LEVEL(x)    (((x)&0x07)<<4)
-
-/* Bit definitions and macros for MCF_INTC0_ICRn */
-#define MCF_INTC0_ICRn_IP(x)          (((x)&0x07)<<0)
-#define MCF_INTC0_ICRn_IL(x)          (((x)&0x07)<<3)
-
-/********************************************************************/
-
-#endif /* __MCF523X_INTC0_H__ */
+/*\r
+ * These files are taken from the MCF523X source code example package\r
+ * which is available on the Freescale website. Freescale explicitly \r
+ * grants the redistribution and modification of these source files.\r
+ * The complete licensing information is available in the file \r
+ * LICENSE_FREESCALE.TXT.\r
+ *\r
+ * File:       mcf523x_intc0.h\r
+ * Purpose:    Register and bit definitions for the MCF523X\r
+ *\r
+ * Notes:      \r
+ *     \r
+ */\r
+\r
+#ifndef __MCF523X_INTC0_H__\r
+#define __MCF523X_INTC0_H__\r
+\r
+/*********************************************************************\r
+*\r
+* Interrupt Controller 0 (INTC0)\r
+*\r
+*********************************************************************/\r
+\r
+/* Register read/write macros */\r
+#define MCF_INTC0_IPRH         (*(vuint32*)(void*)(&__IPSBAR[0x000C00]))\r
+#define MCF_INTC0_IPRL         (*(vuint32*)(void*)(&__IPSBAR[0x000C04]))\r
+#define MCF_INTC0_IMRH         (*(vuint32*)(void*)(&__IPSBAR[0x000C08]))\r
+#define MCF_INTC0_IMRL         (*(vuint32*)(void*)(&__IPSBAR[0x000C0C]))\r
+#define MCF_INTC0_INTFRCH      (*(vuint32*)(void*)(&__IPSBAR[0x000C10]))\r
+#define MCF_INTC0_INTFRCL      (*(vuint32*)(void*)(&__IPSBAR[0x000C14]))\r
+#define MCF_INTC0_IRLR         (*(vuint8 *)(void*)(&__IPSBAR[0x000C18]))\r
+#define MCF_INTC0_IACKLPR      (*(vuint8 *)(void*)(&__IPSBAR[0x000C19]))\r
+#define MCF_INTC0_ICR0         (*(vuint8 *)(void*)(&__IPSBAR[0x000C40]))\r
+#define MCF_INTC0_ICR1         (*(vuint8 *)(void*)(&__IPSBAR[0x000C41]))\r
+#define MCF_INTC0_ICR2         (*(vuint8 *)(void*)(&__IPSBAR[0x000C42]))\r
+#define MCF_INTC0_ICR3         (*(vuint8 *)(void*)(&__IPSBAR[0x000C43]))\r
+#define MCF_INTC0_ICR4         (*(vuint8 *)(void*)(&__IPSBAR[0x000C44]))\r
+#define MCF_INTC0_ICR5         (*(vuint8 *)(void*)(&__IPSBAR[0x000C45]))\r
+#define MCF_INTC0_ICR6         (*(vuint8 *)(void*)(&__IPSBAR[0x000C46]))\r
+#define MCF_INTC0_ICR7         (*(vuint8 *)(void*)(&__IPSBAR[0x000C47]))\r
+#define MCF_INTC0_ICR8         (*(vuint8 *)(void*)(&__IPSBAR[0x000C48]))\r
+#define MCF_INTC0_ICR9         (*(vuint8 *)(void*)(&__IPSBAR[0x000C49]))\r
+#define MCF_INTC0_ICR10        (*(vuint8 *)(void*)(&__IPSBAR[0x000C4A]))\r
+#define MCF_INTC0_ICR11        (*(vuint8 *)(void*)(&__IPSBAR[0x000C4B]))\r
+#define MCF_INTC0_ICR12        (*(vuint8 *)(void*)(&__IPSBAR[0x000C4C]))\r
+#define MCF_INTC0_ICR13        (*(vuint8 *)(void*)(&__IPSBAR[0x000C4D]))\r
+#define MCF_INTC0_ICR14        (*(vuint8 *)(void*)(&__IPSBAR[0x000C4E]))\r
+#define MCF_INTC0_ICR15        (*(vuint8 *)(void*)(&__IPSBAR[0x000C4F]))\r
+#define MCF_INTC0_ICR16        (*(vuint8 *)(void*)(&__IPSBAR[0x000C50]))\r
+#define MCF_INTC0_ICR17        (*(vuint8 *)(void*)(&__IPSBAR[0x000C51]))\r
+#define MCF_INTC0_ICR18        (*(vuint8 *)(void*)(&__IPSBAR[0x000C52]))\r
+#define MCF_INTC0_ICR19        (*(vuint8 *)(void*)(&__IPSBAR[0x000C53]))\r
+#define MCF_INTC0_ICR20        (*(vuint8 *)(void*)(&__IPSBAR[0x000C54]))\r
+#define MCF_INTC0_ICR21        (*(vuint8 *)(void*)(&__IPSBAR[0x000C55]))\r
+#define MCF_INTC0_ICR22        (*(vuint8 *)(void*)(&__IPSBAR[0x000C56]))\r
+#define MCF_INTC0_ICR23        (*(vuint8 *)(void*)(&__IPSBAR[0x000C57]))\r
+#define MCF_INTC0_ICR24        (*(vuint8 *)(void*)(&__IPSBAR[0x000C58]))\r
+#define MCF_INTC0_ICR25        (*(vuint8 *)(void*)(&__IPSBAR[0x000C59]))\r
+#define MCF_INTC0_ICR26        (*(vuint8 *)(void*)(&__IPSBAR[0x000C5A]))\r
+#define MCF_INTC0_ICR27        (*(vuint8 *)(void*)(&__IPSBAR[0x000C5B]))\r
+#define MCF_INTC0_ICR28        (*(vuint8 *)(void*)(&__IPSBAR[0x000C5C]))\r
+#define MCF_INTC0_ICR29        (*(vuint8 *)(void*)(&__IPSBAR[0x000C5D]))\r
+#define MCF_INTC0_ICR30        (*(vuint8 *)(void*)(&__IPSBAR[0x000C5E]))\r
+#define MCF_INTC0_ICR31        (*(vuint8 *)(void*)(&__IPSBAR[0x000C5F]))\r
+#define MCF_INTC0_ICR32        (*(vuint8 *)(void*)(&__IPSBAR[0x000C60]))\r
+#define MCF_INTC0_ICR33        (*(vuint8 *)(void*)(&__IPSBAR[0x000C61]))\r
+#define MCF_INTC0_ICR34        (*(vuint8 *)(void*)(&__IPSBAR[0x000C62]))\r
+#define MCF_INTC0_ICR35        (*(vuint8 *)(void*)(&__IPSBAR[0x000C63]))\r
+#define MCF_INTC0_ICR36        (*(vuint8 *)(void*)(&__IPSBAR[0x000C64]))\r
+#define MCF_INTC0_ICR37        (*(vuint8 *)(void*)(&__IPSBAR[0x000C65]))\r
+#define MCF_INTC0_ICR38        (*(vuint8 *)(void*)(&__IPSBAR[0x000C66]))\r
+#define MCF_INTC0_ICR39        (*(vuint8 *)(void*)(&__IPSBAR[0x000C67]))\r
+#define MCF_INTC0_ICR40        (*(vuint8 *)(void*)(&__IPSBAR[0x000C68]))\r
+#define MCF_INTC0_ICR41        (*(vuint8 *)(void*)(&__IPSBAR[0x000C69]))\r
+#define MCF_INTC0_ICR42        (*(vuint8 *)(void*)(&__IPSBAR[0x000C6A]))\r
+#define MCF_INTC0_ICR43        (*(vuint8 *)(void*)(&__IPSBAR[0x000C6B]))\r
+#define MCF_INTC0_ICR44        (*(vuint8 *)(void*)(&__IPSBAR[0x000C6C]))\r
+#define MCF_INTC0_ICR45        (*(vuint8 *)(void*)(&__IPSBAR[0x000C6D]))\r
+#define MCF_INTC0_ICR46        (*(vuint8 *)(void*)(&__IPSBAR[0x000C6E]))\r
+#define MCF_INTC0_ICR47        (*(vuint8 *)(void*)(&__IPSBAR[0x000C6F]))\r
+#define MCF_INTC0_ICR48        (*(vuint8 *)(void*)(&__IPSBAR[0x000C70]))\r
+#define MCF_INTC0_ICR49        (*(vuint8 *)(void*)(&__IPSBAR[0x000C71]))\r
+#define MCF_INTC0_ICR50        (*(vuint8 *)(void*)(&__IPSBAR[0x000C72]))\r
+#define MCF_INTC0_ICR51        (*(vuint8 *)(void*)(&__IPSBAR[0x000C73]))\r
+#define MCF_INTC0_ICR52        (*(vuint8 *)(void*)(&__IPSBAR[0x000C74]))\r
+#define MCF_INTC0_ICR53        (*(vuint8 *)(void*)(&__IPSBAR[0x000C75]))\r
+#define MCF_INTC0_ICR54        (*(vuint8 *)(void*)(&__IPSBAR[0x000C76]))\r
+#define MCF_INTC0_ICR55        (*(vuint8 *)(void*)(&__IPSBAR[0x000C77]))\r
+#define MCF_INTC0_ICR56        (*(vuint8 *)(void*)(&__IPSBAR[0x000C78]))\r
+#define MCF_INTC0_ICR57        (*(vuint8 *)(void*)(&__IPSBAR[0x000C79]))\r
+#define MCF_INTC0_ICR58        (*(vuint8 *)(void*)(&__IPSBAR[0x000C7A]))\r
+#define MCF_INTC0_ICR59        (*(vuint8 *)(void*)(&__IPSBAR[0x000C7B]))\r
+#define MCF_INTC0_ICR60        (*(vuint8 *)(void*)(&__IPSBAR[0x000C7C]))\r
+#define MCF_INTC0_ICR61        (*(vuint8 *)(void*)(&__IPSBAR[0x000C7D]))\r
+#define MCF_INTC0_ICR62        (*(vuint8 *)(void*)(&__IPSBAR[0x000C7E]))\r
+#define MCF_INTC0_ICR63        (*(vuint8 *)(void*)(&__IPSBAR[0x000C7F]))\r
+#define MCF_INTC0_ICRn(x)      (*(vuint8 *)(void*)(&__IPSBAR[0x000C40+((x)*0x001)]))\r
+#define MCF_INTC0_SWIACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000CE0]))\r
+#define MCF_INTC0_L1IACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000CE4]))\r
+#define MCF_INTC0_L2IACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000CE8]))\r
+#define MCF_INTC0_L3IACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000CEC]))\r
+#define MCF_INTC0_L4IACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000CF0]))\r
+#define MCF_INTC0_L5IACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000CF4]))\r
+#define MCF_INTC0_L6IACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000CF8]))\r
+#define MCF_INTC0_L7IACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000CFC]))\r
+#define MCF_INTC0_LnIACK(x)    (*(vuint8 *)(void*)(&__IPSBAR[0x000CE4+((x)*0x004)]))\r
+\r
+/* Bit definitions and macros for MCF_INTC0_IPRH */\r
+#define MCF_INTC0_IPRH_INT32          (0x00000001)\r
+#define MCF_INTC0_IPRH_INT33          (0x00000002)\r
+#define MCF_INTC0_IPRH_INT34          (0x00000004)\r
+#define MCF_INTC0_IPRH_INT35          (0x00000008)\r
+#define MCF_INTC0_IPRH_INT36          (0x00000010)\r
+#define MCF_INTC0_IPRH_INT37          (0x00000020)\r
+#define MCF_INTC0_IPRH_INT38          (0x00000040)\r
+#define MCF_INTC0_IPRH_INT39          (0x00000080)\r
+#define MCF_INTC0_IPRH_INT40          (0x00000100)\r
+#define MCF_INTC0_IPRH_INT41          (0x00000200)\r
+#define MCF_INTC0_IPRH_INT42          (0x00000400)\r
+#define MCF_INTC0_IPRH_INT43          (0x00000800)\r
+#define MCF_INTC0_IPRH_INT44          (0x00001000)\r
+#define MCF_INTC0_IPRH_INT45          (0x00002000)\r
+#define MCF_INTC0_IPRH_INT46          (0x00004000)\r
+#define MCF_INTC0_IPRH_INT47          (0x00008000)\r
+#define MCF_INTC0_IPRH_INT48          (0x00010000)\r
+#define MCF_INTC0_IPRH_INT49          (0x00020000)\r
+#define MCF_INTC0_IPRH_INT50          (0x00040000)\r
+#define MCF_INTC0_IPRH_INT51          (0x00080000)\r
+#define MCF_INTC0_IPRH_INT52          (0x00100000)\r
+#define MCF_INTC0_IPRH_INT53          (0x00200000)\r
+#define MCF_INTC0_IPRH_INT54          (0x00400000)\r
+#define MCF_INTC0_IPRH_INT55          (0x00800000)\r
+#define MCF_INTC0_IPRH_INT56          (0x01000000)\r
+#define MCF_INTC0_IPRH_INT57          (0x02000000)\r
+#define MCF_INTC0_IPRH_INT58          (0x04000000)\r
+#define MCF_INTC0_IPRH_INT59          (0x08000000)\r
+#define MCF_INTC0_IPRH_INT60          (0x10000000)\r
+#define MCF_INTC0_IPRH_INT61          (0x20000000)\r
+#define MCF_INTC0_IPRH_INT62          (0x40000000)\r
+#define MCF_INTC0_IPRH_INT63          (0x80000000)\r
+\r
+/* Bit definitions and macros for MCF_INTC0_IPRL */\r
+#define MCF_INTC0_IPRL_INT1           (0x00000002)\r
+#define MCF_INTC0_IPRL_INT2           (0x00000004)\r
+#define MCF_INTC0_IPRL_INT3           (0x00000008)\r
+#define MCF_INTC0_IPRL_INT4           (0x00000010)\r
+#define MCF_INTC0_IPRL_INT5           (0x00000020)\r
+#define MCF_INTC0_IPRL_INT6           (0x00000040)\r
+#define MCF_INTC0_IPRL_INT7           (0x00000080)\r
+#define MCF_INTC0_IPRL_INT8           (0x00000100)\r
+#define MCF_INTC0_IPRL_INT9           (0x00000200)\r
+#define MCF_INTC0_IPRL_INT10          (0x00000400)\r
+#define MCF_INTC0_IPRL_INT11          (0x00000800)\r
+#define MCF_INTC0_IPRL_INT12          (0x00001000)\r
+#define MCF_INTC0_IPRL_INT13          (0x00002000)\r
+#define MCF_INTC0_IPRL_INT14          (0x00004000)\r
+#define MCF_INTC0_IPRL_INT15          (0x00008000)\r
+#define MCF_INTC0_IPRL_INT16          (0x00010000)\r
+#define MCF_INTC0_IPRL_INT17          (0x00020000)\r
+#define MCF_INTC0_IPRL_INT18          (0x00040000)\r
+#define MCF_INTC0_IPRL_INT19          (0x00080000)\r
+#define MCF_INTC0_IPRL_INT20          (0x00100000)\r
+#define MCF_INTC0_IPRL_INT21          (0x00200000)\r
+#define MCF_INTC0_IPRL_INT22          (0x00400000)\r
+#define MCF_INTC0_IPRL_INT23          (0x00800000)\r
+#define MCF_INTC0_IPRL_INT24          (0x01000000)\r
+#define MCF_INTC0_IPRL_INT25          (0x02000000)\r
+#define MCF_INTC0_IPRL_INT26          (0x04000000)\r
+#define MCF_INTC0_IPRL_INT27          (0x08000000)\r
+#define MCF_INTC0_IPRL_INT28          (0x10000000)\r
+#define MCF_INTC0_IPRL_INT29          (0x20000000)\r
+#define MCF_INTC0_IPRL_INT30          (0x40000000)\r
+#define MCF_INTC0_IPRL_INT31          (0x80000000)\r
+\r
+/* Bit definitions and macros for MCF_INTC0_IMRH */\r
+#define MCF_INTC0_IMRH_INT_MASK32     (0x00000001)\r
+#define MCF_INTC0_IMRH_INT_MASK33     (0x00000002)\r
+#define MCF_INTC0_IMRH_INT_MASK34     (0x00000004)\r
+#define MCF_INTC0_IMRH_INT_MASK35     (0x00000008)\r
+#define MCF_INTC0_IMRH_INT_MASK36     (0x00000010)\r
+#define MCF_INTC0_IMRH_INT_MASK37     (0x00000020)\r
+#define MCF_INTC0_IMRH_INT_MASK38     (0x00000040)\r
+#define MCF_INTC0_IMRH_INT_MASK39     (0x00000080)\r
+#define MCF_INTC0_IMRH_INT_MASK40     (0x00000100)\r
+#define MCF_INTC0_IMRH_INT_MASK41     (0x00000200)\r
+#define MCF_INTC0_IMRH_INT_MASK42     (0x00000400)\r
+#define MCF_INTC0_IMRH_INT_MASK43     (0x00000800)\r
+#define MCF_INTC0_IMRH_INT_MASK44     (0x00001000)\r
+#define MCF_INTC0_IMRH_INT_MASK45     (0x00002000)\r
+#define MCF_INTC0_IMRH_INT_MASK46     (0x00004000)\r
+#define MCF_INTC0_IMRH_INT_MASK47     (0x00008000)\r
+#define MCF_INTC0_IMRH_INT_MASK48     (0x00010000)\r
+#define MCF_INTC0_IMRH_INT_MASK49     (0x00020000)\r
+#define MCF_INTC0_IMRH_INT_MASK50     (0x00040000)\r
+#define MCF_INTC0_IMRH_INT_MASK51     (0x00080000)\r
+#define MCF_INTC0_IMRH_INT_MASK52     (0x00100000)\r
+#define MCF_INTC0_IMRH_INT_MASK53     (0x00200000)\r
+#define MCF_INTC0_IMRH_INT_MASK54     (0x00400000)\r
+#define MCF_INTC0_IMRH_INT_MASK55     (0x00800000)\r
+#define MCF_INTC0_IMRH_INT_MASK56     (0x01000000)\r
+#define MCF_INTC0_IMRH_INT_MASK57     (0x02000000)\r
+#define MCF_INTC0_IMRH_INT_MASK58     (0x04000000)\r
+#define MCF_INTC0_IMRH_INT_MASK59     (0x08000000)\r
+#define MCF_INTC0_IMRH_INT_MASK60     (0x10000000)\r
+#define MCF_INTC0_IMRH_INT_MASK61     (0x20000000)\r
+#define MCF_INTC0_IMRH_INT_MASK62     (0x40000000)\r
+#define MCF_INTC0_IMRH_INT_MASK63     (0x80000000)\r
+\r
+/* Bit definitions and macros for MCF_INTC0_IMRL */\r
+#define MCF_INTC0_IMRL_MASKALL        (0x00000001)\r
+#define MCF_INTC0_IMRL_INT_MASK1      (0x00000002)\r
+#define MCF_INTC0_IMRL_INT_MASK2      (0x00000004)\r
+#define MCF_INTC0_IMRL_INT_MASK3      (0x00000008)\r
+#define MCF_INTC0_IMRL_INT_MASK4      (0x00000010)\r
+#define MCF_INTC0_IMRL_INT_MASK5      (0x00000020)\r
+#define MCF_INTC0_IMRL_INT_MASK6      (0x00000040)\r
+#define MCF_INTC0_IMRL_INT_MASK7      (0x00000080)\r
+#define MCF_INTC0_IMRL_INT_MASK8      (0x00000100)\r
+#define MCF_INTC0_IMRL_INT_MASK9      (0x00000200)\r
+#define MCF_INTC0_IMRL_INT_MASK10     (0x00000400)\r
+#define MCF_INTC0_IMRL_INT_MASK11     (0x00000800)\r
+#define MCF_INTC0_IMRL_INT_MASK12     (0x00001000)\r
+#define MCF_INTC0_IMRL_INT_MASK13     (0x00002000)\r
+#define MCF_INTC0_IMRL_INT_MASK14     (0x00004000)\r
+#define MCF_INTC0_IMRL_INT_MASK15     (0x00008000)\r
+#define MCF_INTC0_IMRL_INT_MASK16     (0x00010000)\r
+#define MCF_INTC0_IMRL_INT_MASK17     (0x00020000)\r
+#define MCF_INTC0_IMRL_INT_MASK18     (0x00040000)\r
+#define MCF_INTC0_IMRL_INT_MASK19     (0x00080000)\r
+#define MCF_INTC0_IMRL_INT_MASK20     (0x00100000)\r
+#define MCF_INTC0_IMRL_INT_MASK21     (0x00200000)\r
+#define MCF_INTC0_IMRL_INT_MASK22     (0x00400000)\r
+#define MCF_INTC0_IMRL_INT_MASK23     (0x00800000)\r
+#define MCF_INTC0_IMRL_INT_MASK24     (0x01000000)\r
+#define MCF_INTC0_IMRL_INT_MASK25     (0x02000000)\r
+#define MCF_INTC0_IMRL_INT_MASK26     (0x04000000)\r
+#define MCF_INTC0_IMRL_INT_MASK27     (0x08000000)\r
+#define MCF_INTC0_IMRL_INT_MASK28     (0x10000000)\r
+#define MCF_INTC0_IMRL_INT_MASK29     (0x20000000)\r
+#define MCF_INTC0_IMRL_INT_MASK30     (0x40000000)\r
+#define MCF_INTC0_IMRL_INT_MASK31     (0x80000000)\r
+\r
+/* Bit definitions and macros for MCF_INTC0_INTFRCH */\r
+#define MCF_INTC0_INTFRCH_INTFRC32    (0x00000001)\r
+#define MCF_INTC0_INTFRCH_INTFRC33    (0x00000002)\r
+#define MCF_INTC0_INTFRCH_INTFRC34    (0x00000004)\r
+#define MCF_INTC0_INTFRCH_INTFRC35    (0x00000008)\r
+#define MCF_INTC0_INTFRCH_INTFRC36    (0x00000010)\r
+#define MCF_INTC0_INTFRCH_INTFRC37    (0x00000020)\r
+#define MCF_INTC0_INTFRCH_INTFRC38    (0x00000040)\r
+#define MCF_INTC0_INTFRCH_INTFRC39    (0x00000080)\r
+#define MCF_INTC0_INTFRCH_INTFRC40    (0x00000100)\r
+#define MCF_INTC0_INTFRCH_INTFRC41    (0x00000200)\r
+#define MCF_INTC0_INTFRCH_INTFRC42    (0x00000400)\r
+#define MCF_INTC0_INTFRCH_INTFRC43    (0x00000800)\r
+#define MCF_INTC0_INTFRCH_INTFRC44    (0x00001000)\r
+#define MCF_INTC0_INTFRCH_INTFRC45    (0x00002000)\r
+#define MCF_INTC0_INTFRCH_INTFRC46    (0x00004000)\r
+#define MCF_INTC0_INTFRCH_INTFRC47    (0x00008000)\r
+#define MCF_INTC0_INTFRCH_INTFRC48    (0x00010000)\r
+#define MCF_INTC0_INTFRCH_INTFRC49    (0x00020000)\r
+#define MCF_INTC0_INTFRCH_INTFRC50    (0x00040000)\r
+#define MCF_INTC0_INTFRCH_INTFRC51    (0x00080000)\r
+#define MCF_INTC0_INTFRCH_INTFRC52    (0x00100000)\r
+#define MCF_INTC0_INTFRCH_INTFRC53    (0x00200000)\r
+#define MCF_INTC0_INTFRCH_INTFRC54    (0x00400000)\r
+#define MCF_INTC0_INTFRCH_INTFRC55    (0x00800000)\r
+#define MCF_INTC0_INTFRCH_INTFRC56    (0x01000000)\r
+#define MCF_INTC0_INTFRCH_INTFRC57    (0x02000000)\r
+#define MCF_INTC0_INTFRCH_INTFRC58    (0x04000000)\r
+#define MCF_INTC0_INTFRCH_INTFRC59    (0x08000000)\r
+#define MCF_INTC0_INTFRCH_INTFRC60    (0x10000000)\r
+#define MCF_INTC0_INTFRCH_INTFRC61    (0x20000000)\r
+#define MCF_INTC0_INTFRCH_INTFRC62    (0x40000000)\r
+#define MCF_INTC0_INTFRCH_INTFRC63    (0x80000000)\r
+\r
+/* Bit definitions and macros for MCF_INTC0_INTFRCL */\r
+#define MCF_INTC0_INTFRCL_INTFRC1     (0x00000002)\r
+#define MCF_INTC0_INTFRCL_INTFRC2     (0x00000004)\r
+#define MCF_INTC0_INTFRCL_INTFRC3     (0x00000008)\r
+#define MCF_INTC0_INTFRCL_INTFRC4     (0x00000010)\r
+#define MCF_INTC0_INTFRCL_INTFRC5     (0x00000020)\r
+#define MCF_INTC0_INTFRCL_INT6        (0x00000040)\r
+#define MCF_INTC0_INTFRCL_INT7        (0x00000080)\r
+#define MCF_INTC0_INTFRCL_INT8        (0x00000100)\r
+#define MCF_INTC0_INTFRCL_INT9        (0x00000200)\r
+#define MCF_INTC0_INTFRCL_INT10       (0x00000400)\r
+#define MCF_INTC0_INTFRCL_INTFRC11    (0x00000800)\r
+#define MCF_INTC0_INTFRCL_INTFRC12    (0x00001000)\r
+#define MCF_INTC0_INTFRCL_INTFRC13    (0x00002000)\r
+#define MCF_INTC0_INTFRCL_INTFRC14    (0x00004000)\r
+#define MCF_INTC0_INTFRCL_INT15       (0x00008000)\r
+#define MCF_INTC0_INTFRCL_INTFRC16    (0x00010000)\r
+#define MCF_INTC0_INTFRCL_INTFRC17    (0x00020000)\r
+#define MCF_INTC0_INTFRCL_INTFRC18    (0x00040000)\r
+#define MCF_INTC0_INTFRCL_INTFRC19    (0x00080000)\r
+#define MCF_INTC0_INTFRCL_INTFRC20    (0x00100000)\r
+#define MCF_INTC0_INTFRCL_INTFRC21    (0x00200000)\r
+#define MCF_INTC0_INTFRCL_INTFRC22    (0x00400000)\r
+#define MCF_INTC0_INTFRCL_INTFRC23    (0x00800000)\r
+#define MCF_INTC0_INTFRCL_INTFRC24    (0x01000000)\r
+#define MCF_INTC0_INTFRCL_INTFRC25    (0x02000000)\r
+#define MCF_INTC0_INTFRCL_INTFRC26    (0x04000000)\r
+#define MCF_INTC0_INTFRCL_INTFRC27    (0x08000000)\r
+#define MCF_INTC0_INTFRCL_INTFRC28    (0x10000000)\r
+#define MCF_INTC0_INTFRCL_INTFRC29    (0x20000000)\r
+#define MCF_INTC0_INTFRCL_INTFRC30    (0x40000000)\r
+#define MCF_INTC0_INTFRCL_INTFRC31    (0x80000000)\r
+\r
+/* Bit definitions and macros for MCF_INTC0_IRLR */\r
+#define MCF_INTC0_IRLR_IRQ(x)         (((x)&0x7F)<<1)\r
+\r
+/* Bit definitions and macros for MCF_INTC0_IACKLPR */\r
+#define MCF_INTC0_IACKLPR_PRI(x)      (((x)&0x0F)<<0)\r
+#define MCF_INTC0_IACKLPR_LEVEL(x)    (((x)&0x07)<<4)\r
+\r
+/* Bit definitions and macros for MCF_INTC0_ICRn */\r
+#define MCF_INTC0_ICRn_IP(x)          (((x)&0x07)<<0)\r
+#define MCF_INTC0_ICRn_IL(x)          (((x)&0x07)<<3)\r
+\r
+/********************************************************************/\r
+\r
+#endif /* __MCF523X_INTC0_H__ */\r
index 45613eaaf0aa0577ed9dfc37a6785eac071a6c8f..7e8972c07897e1daeb86a6bf357ac46b443dae23 100644 (file)
-/*
- * These files are taken from the MCF523X source code example package
- * which is available on the Freescale website. Freescale explicitly 
- * grants the redistribution and modification of these source files.
- * The complete licensing information is available in the file 
- * LICENSE_FREESCALE.TXT.
- *
- * File:       mcf523x_intc1.h
- * Purpose:    Register and bit definitions for the MCF523X
- *
- * Notes:      
- *     
- */
-
-#ifndef __MCF523X_INTC1_H__
-#define __MCF523X_INTC1_H__
-
-/*********************************************************************
-*
-* Interrupt Controller 1 (INTC1)
-*
-*********************************************************************/
-
-/* Register read/write macros */
-#define MCF_INTC1_IPRH         (*(vuint32*)(void*)(&__IPSBAR[0x000D00]))
-#define MCF_INTC1_IPRL         (*(vuint32*)(void*)(&__IPSBAR[0x000D04]))
-#define MCF_INTC1_IMRH         (*(vuint32*)(void*)(&__IPSBAR[0x000D08]))
-#define MCF_INTC1_IMRL         (*(vuint32*)(void*)(&__IPSBAR[0x000D0C]))
-#define MCF_INTC1_INTFRCH      (*(vuint32*)(void*)(&__IPSBAR[0x000D10]))
-#define MCF_INTC1_INTFRCL      (*(vuint32*)(void*)(&__IPSBAR[0x000D14]))
-#define MCF_INTC1_IRLR         (*(vuint8 *)(void*)(&__IPSBAR[0x000D18]))
-#define MCF_INTC1_IACKLPR      (*(vuint8 *)(void*)(&__IPSBAR[0x000D19]))
-#define MCF_INTC1_ICR0         (*(vuint8 *)(void*)(&__IPSBAR[0x000D40]))
-#define MCF_INTC1_ICR1         (*(vuint8 *)(void*)(&__IPSBAR[0x000D41]))
-#define MCF_INTC1_ICR2         (*(vuint8 *)(void*)(&__IPSBAR[0x000D42]))
-#define MCF_INTC1_ICR3         (*(vuint8 *)(void*)(&__IPSBAR[0x000D43]))
-#define MCF_INTC1_ICR4         (*(vuint8 *)(void*)(&__IPSBAR[0x000D44]))
-#define MCF_INTC1_ICR5         (*(vuint8 *)(void*)(&__IPSBAR[0x000D45]))
-#define MCF_INTC1_ICR6         (*(vuint8 *)(void*)(&__IPSBAR[0x000D46]))
-#define MCF_INTC1_ICR7         (*(vuint8 *)(void*)(&__IPSBAR[0x000D47]))
-#define MCF_INTC1_ICR8         (*(vuint8 *)(void*)(&__IPSBAR[0x000D48]))
-#define MCF_INTC1_ICR9         (*(vuint8 *)(void*)(&__IPSBAR[0x000D49]))
-#define MCF_INTC1_ICR10        (*(vuint8 *)(void*)(&__IPSBAR[0x000D4A]))
-#define MCF_INTC1_ICR11        (*(vuint8 *)(void*)(&__IPSBAR[0x000D4B]))
-#define MCF_INTC1_ICR12        (*(vuint8 *)(void*)(&__IPSBAR[0x000D4C]))
-#define MCF_INTC1_ICR13        (*(vuint8 *)(void*)(&__IPSBAR[0x000D4D]))
-#define MCF_INTC1_ICR14        (*(vuint8 *)(void*)(&__IPSBAR[0x000D4E]))
-#define MCF_INTC1_ICR15        (*(vuint8 *)(void*)(&__IPSBAR[0x000D4F]))
-#define MCF_INTC1_ICR16        (*(vuint8 *)(void*)(&__IPSBAR[0x000D50]))
-#define MCF_INTC1_ICR17        (*(vuint8 *)(void*)(&__IPSBAR[0x000D51]))
-#define MCF_INTC1_ICR18        (*(vuint8 *)(void*)(&__IPSBAR[0x000D52]))
-#define MCF_INTC1_ICR19        (*(vuint8 *)(void*)(&__IPSBAR[0x000D53]))
-#define MCF_INTC1_ICR20        (*(vuint8 *)(void*)(&__IPSBAR[0x000D54]))
-#define MCF_INTC1_ICR21        (*(vuint8 *)(void*)(&__IPSBAR[0x000D55]))
-#define MCF_INTC1_ICR22        (*(vuint8 *)(void*)(&__IPSBAR[0x000D56]))
-#define MCF_INTC1_ICR23        (*(vuint8 *)(void*)(&__IPSBAR[0x000D57]))
-#define MCF_INTC1_ICR24        (*(vuint8 *)(void*)(&__IPSBAR[0x000D58]))
-#define MCF_INTC1_ICR25        (*(vuint8 *)(void*)(&__IPSBAR[0x000D59]))
-#define MCF_INTC1_ICR26        (*(vuint8 *)(void*)(&__IPSBAR[0x000D5A]))
-#define MCF_INTC1_ICR27        (*(vuint8 *)(void*)(&__IPSBAR[0x000D5B]))
-#define MCF_INTC1_ICR28        (*(vuint8 *)(void*)(&__IPSBAR[0x000D5C]))
-#define MCF_INTC1_ICR29        (*(vuint8 *)(void*)(&__IPSBAR[0x000D5D]))
-#define MCF_INTC1_ICR30        (*(vuint8 *)(void*)(&__IPSBAR[0x000D5E]))
-#define MCF_INTC1_ICR31        (*(vuint8 *)(void*)(&__IPSBAR[0x000D5F]))
-#define MCF_INTC1_ICR32        (*(vuint8 *)(void*)(&__IPSBAR[0x000D60]))
-#define MCF_INTC1_ICR33        (*(vuint8 *)(void*)(&__IPSBAR[0x000D61]))
-#define MCF_INTC1_ICR34        (*(vuint8 *)(void*)(&__IPSBAR[0x000D62]))
-#define MCF_INTC1_ICR35        (*(vuint8 *)(void*)(&__IPSBAR[0x000D63]))
-#define MCF_INTC1_ICR36        (*(vuint8 *)(void*)(&__IPSBAR[0x000D64]))
-#define MCF_INTC1_ICR37        (*(vuint8 *)(void*)(&__IPSBAR[0x000D65]))
-#define MCF_INTC1_ICR38        (*(vuint8 *)(void*)(&__IPSBAR[0x000D66]))
-#define MCF_INTC1_ICR39        (*(vuint8 *)(void*)(&__IPSBAR[0x000D67]))
-#define MCF_INTC1_ICR40        (*(vuint8 *)(void*)(&__IPSBAR[0x000D68]))
-#define MCF_INTC1_ICR41        (*(vuint8 *)(void*)(&__IPSBAR[0x000D69]))
-#define MCF_INTC1_ICR42        (*(vuint8 *)(void*)(&__IPSBAR[0x000D6A]))
-#define MCF_INTC1_ICR43        (*(vuint8 *)(void*)(&__IPSBAR[0x000D6B]))
-#define MCF_INTC1_ICR44        (*(vuint8 *)(void*)(&__IPSBAR[0x000D6C]))
-#define MCF_INTC1_ICR45        (*(vuint8 *)(void*)(&__IPSBAR[0x000D6D]))
-#define MCF_INTC1_ICR46        (*(vuint8 *)(void*)(&__IPSBAR[0x000D6E]))
-#define MCF_INTC1_ICR47        (*(vuint8 *)(void*)(&__IPSBAR[0x000D6F]))
-#define MCF_INTC1_ICR48        (*(vuint8 *)(void*)(&__IPSBAR[0x000D70]))
-#define MCF_INTC1_ICR49        (*(vuint8 *)(void*)(&__IPSBAR[0x000D71]))
-#define MCF_INTC1_ICR50        (*(vuint8 *)(void*)(&__IPSBAR[0x000D72]))
-#define MCF_INTC1_ICR51        (*(vuint8 *)(void*)(&__IPSBAR[0x000D73]))
-#define MCF_INTC1_ICR52        (*(vuint8 *)(void*)(&__IPSBAR[0x000D74]))
-#define MCF_INTC1_ICR53        (*(vuint8 *)(void*)(&__IPSBAR[0x000D75]))
-#define MCF_INTC1_ICR54        (*(vuint8 *)(void*)(&__IPSBAR[0x000D76]))
-#define MCF_INTC1_ICR55        (*(vuint8 *)(void*)(&__IPSBAR[0x000D77]))
-#define MCF_INTC1_ICR56        (*(vuint8 *)(void*)(&__IPSBAR[0x000D78]))
-#define MCF_INTC1_ICR57        (*(vuint8 *)(void*)(&__IPSBAR[0x000D79]))
-#define MCF_INTC1_ICR58        (*(vuint8 *)(void*)(&__IPSBAR[0x000D7A]))
-#define MCF_INTC1_ICR59        (*(vuint8 *)(void*)(&__IPSBAR[0x000D7B]))
-#define MCF_INTC1_ICR60        (*(vuint8 *)(void*)(&__IPSBAR[0x000D7C]))
-#define MCF_INTC1_ICR61        (*(vuint8 *)(void*)(&__IPSBAR[0x000D7D]))
-#define MCF_INTC1_ICR62        (*(vuint8 *)(void*)(&__IPSBAR[0x000D7E]))
-#define MCF_INTC1_ICR63        (*(vuint8 *)(void*)(&__IPSBAR[0x000D7F]))
-#define MCF_INTC1_ICRn(x)      (*(vuint8 *)(void*)(&__IPSBAR[0x000D40+((x)*0x001)]))
-#define MCF_INTC1_SWIACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000DE0]))
-#define MCF_INTC1_L1IACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000DE4]))
-#define MCF_INTC1_L2IACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000DE8]))
-#define MCF_INTC1_L3IACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000DEC]))
-#define MCF_INTC1_L4IACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000DF0]))
-#define MCF_INTC1_L5IACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000DF4]))
-#define MCF_INTC1_L6IACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000DF8]))
-#define MCF_INTC1_L7IACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000DFC]))
-#define MCF_INTC1_LnIACK(x)    (*(vuint8 *)(void*)(&__IPSBAR[0x000DE4+((x)*0x004)]))
-
-/* Bit definitions and macros for MCF_INTC1_IPRH */
-#define MCF_INTC1_IPRH_INT32          (0x00000001)
-#define MCF_INTC1_IPRH_INT33          (0x00000002)
-#define MCF_INTC1_IPRH_INT34          (0x00000004)
-#define MCF_INTC1_IPRH_INT35          (0x00000008)
-#define MCF_INTC1_IPRH_INT36          (0x00000010)
-#define MCF_INTC1_IPRH_INT37          (0x00000020)
-#define MCF_INTC1_IPRH_INT38          (0x00000040)
-#define MCF_INTC1_IPRH_INT39          (0x00000080)
-#define MCF_INTC1_IPRH_INT40          (0x00000100)
-#define MCF_INTC1_IPRH_INT41          (0x00000200)
-#define MCF_INTC1_IPRH_INT42          (0x00000400)
-#define MCF_INTC1_IPRH_INT43          (0x00000800)
-#define MCF_INTC1_IPRH_INT44          (0x00001000)
-#define MCF_INTC1_IPRH_INT45          (0x00002000)
-#define MCF_INTC1_IPRH_INT46          (0x00004000)
-#define MCF_INTC1_IPRH_INT47          (0x00008000)
-#define MCF_INTC1_IPRH_INT48          (0x00010000)
-#define MCF_INTC1_IPRH_INT49          (0x00020000)
-#define MCF_INTC1_IPRH_INT50          (0x00040000)
-#define MCF_INTC1_IPRH_INT51          (0x00080000)
-#define MCF_INTC1_IPRH_INT52          (0x00100000)
-#define MCF_INTC1_IPRH_INT53          (0x00200000)
-#define MCF_INTC1_IPRH_INT54          (0x00400000)
-#define MCF_INTC1_IPRH_INT55          (0x00800000)
-#define MCF_INTC1_IPRH_INT56          (0x01000000)
-#define MCF_INTC1_IPRH_INT57          (0x02000000)
-#define MCF_INTC1_IPRH_INT58          (0x04000000)
-#define MCF_INTC1_IPRH_INT59          (0x08000000)
-#define MCF_INTC1_IPRH_INT60          (0x10000000)
-#define MCF_INTC1_IPRH_INT61          (0x20000000)
-#define MCF_INTC1_IPRH_INT62          (0x40000000)
-#define MCF_INTC1_IPRH_INT63          (0x80000000)
-
-/* Bit definitions and macros for MCF_INTC1_IPRL */
-#define MCF_INTC1_IPRL_INT1           (0x00000002)
-#define MCF_INTC1_IPRL_INT2           (0x00000004)
-#define MCF_INTC1_IPRL_INT3           (0x00000008)
-#define MCF_INTC1_IPRL_INT4           (0x00000010)
-#define MCF_INTC1_IPRL_INT5           (0x00000020)
-#define MCF_INTC1_IPRL_INT6           (0x00000040)
-#define MCF_INTC1_IPRL_INT7           (0x00000080)
-#define MCF_INTC1_IPRL_INT8           (0x00000100)
-#define MCF_INTC1_IPRL_INT9           (0x00000200)
-#define MCF_INTC1_IPRL_INT10          (0x00000400)
-#define MCF_INTC1_IPRL_INT11          (0x00000800)
-#define MCF_INTC1_IPRL_INT12          (0x00001000)
-#define MCF_INTC1_IPRL_INT13          (0x00002000)
-#define MCF_INTC1_IPRL_INT14          (0x00004000)
-#define MCF_INTC1_IPRL_INT15          (0x00008000)
-#define MCF_INTC1_IPRL_INT16          (0x00010000)
-#define MCF_INTC1_IPRL_INT17          (0x00020000)
-#define MCF_INTC1_IPRL_INT18          (0x00040000)
-#define MCF_INTC1_IPRL_INT19          (0x00080000)
-#define MCF_INTC1_IPRL_INT20          (0x00100000)
-#define MCF_INTC1_IPRL_INT21          (0x00200000)
-#define MCF_INTC1_IPRL_INT22          (0x00400000)
-#define MCF_INTC1_IPRL_INT23          (0x00800000)
-#define MCF_INTC1_IPRL_INT24          (0x01000000)
-#define MCF_INTC1_IPRL_INT25          (0x02000000)
-#define MCF_INTC1_IPRL_INT26          (0x04000000)
-#define MCF_INTC1_IPRL_INT27          (0x08000000)
-#define MCF_INTC1_IPRL_INT28          (0x10000000)
-#define MCF_INTC1_IPRL_INT29          (0x20000000)
-#define MCF_INTC1_IPRL_INT30          (0x40000000)
-#define MCF_INTC1_IPRL_INT31          (0x80000000)
-
-/* Bit definitions and macros for MCF_INTC1_IMRH */
-#define MCF_INTC1_IMRH_INT_MASK32     (0x00000001)
-#define MCF_INTC1_IMRH_INT_MASK33     (0x00000002)
-#define MCF_INTC1_IMRH_INT_MASK34     (0x00000004)
-#define MCF_INTC1_IMRH_INT_MASK35     (0x00000008)
-#define MCF_INTC1_IMRH_INT_MASK36     (0x00000010)
-#define MCF_INTC1_IMRH_INT_MASK37     (0x00000020)
-#define MCF_INTC1_IMRH_INT_MASK38     (0x00000040)
-#define MCF_INTC1_IMRH_INT_MASK39     (0x00000080)
-#define MCF_INTC1_IMRH_INT_MASK40     (0x00000100)
-#define MCF_INTC1_IMRH_INT_MASK41     (0x00000200)
-#define MCF_INTC1_IMRH_INT_MASK42     (0x00000400)
-#define MCF_INTC1_IMRH_INT_MASK43     (0x00000800)
-#define MCF_INTC1_IMRH_INT_MASK44     (0x00001000)
-#define MCF_INTC1_IMRH_INT_MASK45     (0x00002000)
-#define MCF_INTC1_IMRH_INT_MASK46     (0x00004000)
-#define MCF_INTC1_IMRH_INT_MASK47     (0x00008000)
-#define MCF_INTC1_IMRH_INT_MASK48     (0x00010000)
-#define MCF_INTC1_IMRH_INT_MASK49     (0x00020000)
-#define MCF_INTC1_IMRH_INT_MASK50     (0x00040000)
-#define MCF_INTC1_IMRH_INT_MASK51     (0x00080000)
-#define MCF_INTC1_IMRH_INT_MASK52     (0x00100000)
-#define MCF_INTC1_IMRH_INT_MASK53     (0x00200000)
-#define MCF_INTC1_IMRH_INT_MASK54     (0x00400000)
-#define MCF_INTC1_IMRH_INT_MASK55     (0x00800000)
-#define MCF_INTC1_IMRH_INT_MASK56     (0x01000000)
-#define MCF_INTC1_IMRH_INT_MASK57     (0x02000000)
-#define MCF_INTC1_IMRH_INT_MASK58     (0x04000000)
-#define MCF_INTC1_IMRH_INT_MASK59     (0x08000000)
-#define MCF_INTC1_IMRH_INT_MASK60     (0x10000000)
-#define MCF_INTC1_IMRH_INT_MASK61     (0x20000000)
-#define MCF_INTC1_IMRH_INT_MASK62     (0x40000000)
-#define MCF_INTC1_IMRH_INT_MASK63     (0x80000000)
-
-/* Bit definitions and macros for MCF_INTC1_IMRL */
-#define MCF_INTC1_IMRL_MASKALL        (0x00000001)
-#define MCF_INTC1_IMRL_INT_MASK1      (0x00000002)
-#define MCF_INTC1_IMRL_INT_MASK2      (0x00000004)
-#define MCF_INTC1_IMRL_INT_MASK3      (0x00000008)
-#define MCF_INTC1_IMRL_INT_MASK4      (0x00000010)
-#define MCF_INTC1_IMRL_INT_MASK5      (0x00000020)
-#define MCF_INTC1_IMRL_INT_MASK6      (0x00000040)
-#define MCF_INTC1_IMRL_INT_MASK7      (0x00000080)
-#define MCF_INTC1_IMRL_INT_MASK8      (0x00000100)
-#define MCF_INTC1_IMRL_INT_MASK9      (0x00000200)
-#define MCF_INTC1_IMRL_INT_MASK10     (0x00000400)
-#define MCF_INTC1_IMRL_INT_MASK11     (0x00000800)
-#define MCF_INTC1_IMRL_INT_MASK12     (0x00001000)
-#define MCF_INTC1_IMRL_INT_MASK13     (0x00002000)
-#define MCF_INTC1_IMRL_INT_MASK14     (0x00004000)
-#define MCF_INTC1_IMRL_INT_MASK15     (0x00008000)
-#define MCF_INTC1_IMRL_INT_MASK16     (0x00010000)
-#define MCF_INTC1_IMRL_INT_MASK17     (0x00020000)
-#define MCF_INTC1_IMRL_INT_MASK18     (0x00040000)
-#define MCF_INTC1_IMRL_INT_MASK19     (0x00080000)
-#define MCF_INTC1_IMRL_INT_MASK20     (0x00100000)
-#define MCF_INTC1_IMRL_INT_MASK21     (0x00200000)
-#define MCF_INTC1_IMRL_INT_MASK22     (0x00400000)
-#define MCF_INTC1_IMRL_INT_MASK23     (0x00800000)
-#define MCF_INTC1_IMRL_INT_MASK24     (0x01000000)
-#define MCF_INTC1_IMRL_INT_MASK25     (0x02000000)
-#define MCF_INTC1_IMRL_INT_MASK26     (0x04000000)
-#define MCF_INTC1_IMRL_INT_MASK27     (0x08000000)
-#define MCF_INTC1_IMRL_INT_MASK28     (0x10000000)
-#define MCF_INTC1_IMRL_INT_MASK29     (0x20000000)
-#define MCF_INTC1_IMRL_INT_MASK30     (0x40000000)
-#define MCF_INTC1_IMRL_INT_MASK31     (0x80000000)
-
-/* Bit definitions and macros for MCF_INTC1_INTFRCH */
-#define MCF_INTC1_INTFRCH_INTFRC32    (0x00000001)
-#define MCF_INTC1_INTFRCH_INTFRC33    (0x00000002)
-#define MCF_INTC1_INTFRCH_INTFRC34    (0x00000004)
-#define MCF_INTC1_INTFRCH_INTFRC35    (0x00000008)
-#define MCF_INTC1_INTFRCH_INTFRC36    (0x00000010)
-#define MCF_INTC1_INTFRCH_INTFRC37    (0x00000020)
-#define MCF_INTC1_INTFRCH_INTFRC38    (0x00000040)
-#define MCF_INTC1_INTFRCH_INTFRC39    (0x00000080)
-#define MCF_INTC1_INTFRCH_INTFRC40    (0x00000100)
-#define MCF_INTC1_INTFRCH_INTFRC41    (0x00000200)
-#define MCF_INTC1_INTFRCH_INTFRC42    (0x00000400)
-#define MCF_INTC1_INTFRCH_INTFRC43    (0x00000800)
-#define MCF_INTC1_INTFRCH_INTFRC44    (0x00001000)
-#define MCF_INTC1_INTFRCH_INTFRC45    (0x00002000)
-#define MCF_INTC1_INTFRCH_INTFRC46    (0x00004000)
-#define MCF_INTC1_INTFRCH_INTFRC47    (0x00008000)
-#define MCF_INTC1_INTFRCH_INTFRC48    (0x00010000)
-#define MCF_INTC1_INTFRCH_INTFRC49    (0x00020000)
-#define MCF_INTC1_INTFRCH_INTFRC50    (0x00040000)
-#define MCF_INTC1_INTFRCH_INTFRC51    (0x00080000)
-#define MCF_INTC1_INTFRCH_INTFRC52    (0x00100000)
-#define MCF_INTC1_INTFRCH_INTFRC53    (0x00200000)
-#define MCF_INTC1_INTFRCH_INTFRC54    (0x00400000)
-#define MCF_INTC1_INTFRCH_INTFRC55    (0x00800000)
-#define MCF_INTC1_INTFRCH_INTFRC56    (0x01000000)
-#define MCF_INTC1_INTFRCH_INTFRC57    (0x02000000)
-#define MCF_INTC1_INTFRCH_INTFRC58    (0x04000000)
-#define MCF_INTC1_INTFRCH_INTFRC59    (0x08000000)
-#define MCF_INTC1_INTFRCH_INTFRC60    (0x10000000)
-#define MCF_INTC1_INTFRCH_INTFRC61    (0x20000000)
-#define MCF_INTC1_INTFRCH_INTFRC62    (0x40000000)
-#define MCF_INTC1_INTFRCH_INTFRC63    (0x80000000)
-
-/* Bit definitions and macros for MCF_INTC1_INTFRCL */
-#define MCF_INTC1_INTFRCL_INTFRC1     (0x00000002)
-#define MCF_INTC1_INTFRCL_INTFRC2     (0x00000004)
-#define MCF_INTC1_INTFRCL_INTFRC3     (0x00000008)
-#define MCF_INTC1_INTFRCL_INTFRC4     (0x00000010)
-#define MCF_INTC1_INTFRCL_INTFRC5     (0x00000020)
-#define MCF_INTC1_INTFRCL_INT6        (0x00000040)
-#define MCF_INTC1_INTFRCL_INT7        (0x00000080)
-#define MCF_INTC1_INTFRCL_INT8        (0x00000100)
-#define MCF_INTC1_INTFRCL_INT9        (0x00000200)
-#define MCF_INTC1_INTFRCL_INT10       (0x00000400)
-#define MCF_INTC1_INTFRCL_INTFRC11    (0x00000800)
-#define MCF_INTC1_INTFRCL_INTFRC12    (0x00001000)
-#define MCF_INTC1_INTFRCL_INTFRC13    (0x00002000)
-#define MCF_INTC1_INTFRCL_INTFRC14    (0x00004000)
-#define MCF_INTC1_INTFRCL_INT15       (0x00008000)
-#define MCF_INTC1_INTFRCL_INTFRC16    (0x00010000)
-#define MCF_INTC1_INTFRCL_INTFRC17    (0x00020000)
-#define MCF_INTC1_INTFRCL_INTFRC18    (0x00040000)
-#define MCF_INTC1_INTFRCL_INTFRC19    (0x00080000)
-#define MCF_INTC1_INTFRCL_INTFRC20    (0x00100000)
-#define MCF_INTC1_INTFRCL_INTFRC21    (0x00200000)
-#define MCF_INTC1_INTFRCL_INTFRC22    (0x00400000)
-#define MCF_INTC1_INTFRCL_INTFRC23    (0x00800000)
-#define MCF_INTC1_INTFRCL_INTFRC24    (0x01000000)
-#define MCF_INTC1_INTFRCL_INTFRC25    (0x02000000)
-#define MCF_INTC1_INTFRCL_INTFRC26    (0x04000000)
-#define MCF_INTC1_INTFRCL_INTFRC27    (0x08000000)
-#define MCF_INTC1_INTFRCL_INTFRC28    (0x10000000)
-#define MCF_INTC1_INTFRCL_INTFRC29    (0x20000000)
-#define MCF_INTC1_INTFRCL_INTFRC30    (0x40000000)
-#define MCF_INTC1_INTFRCL_INTFRC31    (0x80000000)
-
-/* Bit definitions and macros for MCF_INTC1_IRLR */
-#define MCF_INTC1_IRLR_IRQ(x)         (((x)&0x7F)<<1)
-
-/* Bit definitions and macros for MCF_INTC1_IACKLPR */
-#define MCF_INTC1_IACKLPR_PRI(x)      (((x)&0x0F)<<0)
-#define MCF_INTC1_IACKLPR_LEVEL(x)    (((x)&0x07)<<4)
-
-/* Bit definitions and macros for MCF_INTC1_ICRn */
-#define MCF_INTC1_ICRn_IP(x)          (((x)&0x07)<<0)
-#define MCF_INTC1_ICRn_IL(x)          (((x)&0x07)<<3)
-
-/********************************************************************/
-
-#endif /* __MCF523X_INTC1_H__ */
+/*\r
+ * These files are taken from the MCF523X source code example package\r
+ * which is available on the Freescale website. Freescale explicitly \r
+ * grants the redistribution and modification of these source files.\r
+ * The complete licensing information is available in the file \r
+ * LICENSE_FREESCALE.TXT.\r
+ *\r
+ * File:       mcf523x_intc1.h\r
+ * Purpose:    Register and bit definitions for the MCF523X\r
+ *\r
+ * Notes:      \r
+ *     \r
+ */\r
+\r
+#ifndef __MCF523X_INTC1_H__\r
+#define __MCF523X_INTC1_H__\r
+\r
+/*********************************************************************\r
+*\r
+* Interrupt Controller 1 (INTC1)\r
+*\r
+*********************************************************************/\r
+\r
+/* Register read/write macros */\r
+#define MCF_INTC1_IPRH         (*(vuint32*)(void*)(&__IPSBAR[0x000D00]))\r
+#define MCF_INTC1_IPRL         (*(vuint32*)(void*)(&__IPSBAR[0x000D04]))\r
+#define MCF_INTC1_IMRH         (*(vuint32*)(void*)(&__IPSBAR[0x000D08]))\r
+#define MCF_INTC1_IMRL         (*(vuint32*)(void*)(&__IPSBAR[0x000D0C]))\r
+#define MCF_INTC1_INTFRCH      (*(vuint32*)(void*)(&__IPSBAR[0x000D10]))\r
+#define MCF_INTC1_INTFRCL      (*(vuint32*)(void*)(&__IPSBAR[0x000D14]))\r
+#define MCF_INTC1_IRLR         (*(vuint8 *)(void*)(&__IPSBAR[0x000D18]))\r
+#define MCF_INTC1_IACKLPR      (*(vuint8 *)(void*)(&__IPSBAR[0x000D19]))\r
+#define MCF_INTC1_ICR0         (*(vuint8 *)(void*)(&__IPSBAR[0x000D40]))\r
+#define MCF_INTC1_ICR1         (*(vuint8 *)(void*)(&__IPSBAR[0x000D41]))\r
+#define MCF_INTC1_ICR2         (*(vuint8 *)(void*)(&__IPSBAR[0x000D42]))\r
+#define MCF_INTC1_ICR3         (*(vuint8 *)(void*)(&__IPSBAR[0x000D43]))\r
+#define MCF_INTC1_ICR4         (*(vuint8 *)(void*)(&__IPSBAR[0x000D44]))\r
+#define MCF_INTC1_ICR5         (*(vuint8 *)(void*)(&__IPSBAR[0x000D45]))\r
+#define MCF_INTC1_ICR6         (*(vuint8 *)(void*)(&__IPSBAR[0x000D46]))\r
+#define MCF_INTC1_ICR7         (*(vuint8 *)(void*)(&__IPSBAR[0x000D47]))\r
+#define MCF_INTC1_ICR8         (*(vuint8 *)(void*)(&__IPSBAR[0x000D48]))\r
+#define MCF_INTC1_ICR9         (*(vuint8 *)(void*)(&__IPSBAR[0x000D49]))\r
+#define MCF_INTC1_ICR10        (*(vuint8 *)(void*)(&__IPSBAR[0x000D4A]))\r
+#define MCF_INTC1_ICR11        (*(vuint8 *)(void*)(&__IPSBAR[0x000D4B]))\r
+#define MCF_INTC1_ICR12        (*(vuint8 *)(void*)(&__IPSBAR[0x000D4C]))\r
+#define MCF_INTC1_ICR13        (*(vuint8 *)(void*)(&__IPSBAR[0x000D4D]))\r
+#define MCF_INTC1_ICR14        (*(vuint8 *)(void*)(&__IPSBAR[0x000D4E]))\r
+#define MCF_INTC1_ICR15        (*(vuint8 *)(void*)(&__IPSBAR[0x000D4F]))\r
+#define MCF_INTC1_ICR16        (*(vuint8 *)(void*)(&__IPSBAR[0x000D50]))\r
+#define MCF_INTC1_ICR17        (*(vuint8 *)(void*)(&__IPSBAR[0x000D51]))\r
+#define MCF_INTC1_ICR18        (*(vuint8 *)(void*)(&__IPSBAR[0x000D52]))\r
+#define MCF_INTC1_ICR19        (*(vuint8 *)(void*)(&__IPSBAR[0x000D53]))\r
+#define MCF_INTC1_ICR20        (*(vuint8 *)(void*)(&__IPSBAR[0x000D54]))\r
+#define MCF_INTC1_ICR21        (*(vuint8 *)(void*)(&__IPSBAR[0x000D55]))\r
+#define MCF_INTC1_ICR22        (*(vuint8 *)(void*)(&__IPSBAR[0x000D56]))\r
+#define MCF_INTC1_ICR23        (*(vuint8 *)(void*)(&__IPSBAR[0x000D57]))\r
+#define MCF_INTC1_ICR24        (*(vuint8 *)(void*)(&__IPSBAR[0x000D58]))\r
+#define MCF_INTC1_ICR25        (*(vuint8 *)(void*)(&__IPSBAR[0x000D59]))\r
+#define MCF_INTC1_ICR26        (*(vuint8 *)(void*)(&__IPSBAR[0x000D5A]))\r
+#define MCF_INTC1_ICR27        (*(vuint8 *)(void*)(&__IPSBAR[0x000D5B]))\r
+#define MCF_INTC1_ICR28        (*(vuint8 *)(void*)(&__IPSBAR[0x000D5C]))\r
+#define MCF_INTC1_ICR29        (*(vuint8 *)(void*)(&__IPSBAR[0x000D5D]))\r
+#define MCF_INTC1_ICR30        (*(vuint8 *)(void*)(&__IPSBAR[0x000D5E]))\r
+#define MCF_INTC1_ICR31        (*(vuint8 *)(void*)(&__IPSBAR[0x000D5F]))\r
+#define MCF_INTC1_ICR32        (*(vuint8 *)(void*)(&__IPSBAR[0x000D60]))\r
+#define MCF_INTC1_ICR33        (*(vuint8 *)(void*)(&__IPSBAR[0x000D61]))\r
+#define MCF_INTC1_ICR34        (*(vuint8 *)(void*)(&__IPSBAR[0x000D62]))\r
+#define MCF_INTC1_ICR35        (*(vuint8 *)(void*)(&__IPSBAR[0x000D63]))\r
+#define MCF_INTC1_ICR36        (*(vuint8 *)(void*)(&__IPSBAR[0x000D64]))\r
+#define MCF_INTC1_ICR37        (*(vuint8 *)(void*)(&__IPSBAR[0x000D65]))\r
+#define MCF_INTC1_ICR38        (*(vuint8 *)(void*)(&__IPSBAR[0x000D66]))\r
+#define MCF_INTC1_ICR39        (*(vuint8 *)(void*)(&__IPSBAR[0x000D67]))\r
+#define MCF_INTC1_ICR40        (*(vuint8 *)(void*)(&__IPSBAR[0x000D68]))\r
+#define MCF_INTC1_ICR41        (*(vuint8 *)(void*)(&__IPSBAR[0x000D69]))\r
+#define MCF_INTC1_ICR42        (*(vuint8 *)(void*)(&__IPSBAR[0x000D6A]))\r
+#define MCF_INTC1_ICR43        (*(vuint8 *)(void*)(&__IPSBAR[0x000D6B]))\r
+#define MCF_INTC1_ICR44        (*(vuint8 *)(void*)(&__IPSBAR[0x000D6C]))\r
+#define MCF_INTC1_ICR45        (*(vuint8 *)(void*)(&__IPSBAR[0x000D6D]))\r
+#define MCF_INTC1_ICR46        (*(vuint8 *)(void*)(&__IPSBAR[0x000D6E]))\r
+#define MCF_INTC1_ICR47        (*(vuint8 *)(void*)(&__IPSBAR[0x000D6F]))\r
+#define MCF_INTC1_ICR48        (*(vuint8 *)(void*)(&__IPSBAR[0x000D70]))\r
+#define MCF_INTC1_ICR49        (*(vuint8 *)(void*)(&__IPSBAR[0x000D71]))\r
+#define MCF_INTC1_ICR50        (*(vuint8 *)(void*)(&__IPSBAR[0x000D72]))\r
+#define MCF_INTC1_ICR51        (*(vuint8 *)(void*)(&__IPSBAR[0x000D73]))\r
+#define MCF_INTC1_ICR52        (*(vuint8 *)(void*)(&__IPSBAR[0x000D74]))\r
+#define MCF_INTC1_ICR53        (*(vuint8 *)(void*)(&__IPSBAR[0x000D75]))\r
+#define MCF_INTC1_ICR54        (*(vuint8 *)(void*)(&__IPSBAR[0x000D76]))\r
+#define MCF_INTC1_ICR55        (*(vuint8 *)(void*)(&__IPSBAR[0x000D77]))\r
+#define MCF_INTC1_ICR56        (*(vuint8 *)(void*)(&__IPSBAR[0x000D78]))\r
+#define MCF_INTC1_ICR57        (*(vuint8 *)(void*)(&__IPSBAR[0x000D79]))\r
+#define MCF_INTC1_ICR58        (*(vuint8 *)(void*)(&__IPSBAR[0x000D7A]))\r
+#define MCF_INTC1_ICR59        (*(vuint8 *)(void*)(&__IPSBAR[0x000D7B]))\r
+#define MCF_INTC1_ICR60        (*(vuint8 *)(void*)(&__IPSBAR[0x000D7C]))\r
+#define MCF_INTC1_ICR61        (*(vuint8 *)(void*)(&__IPSBAR[0x000D7D]))\r
+#define MCF_INTC1_ICR62        (*(vuint8 *)(void*)(&__IPSBAR[0x000D7E]))\r
+#define MCF_INTC1_ICR63        (*(vuint8 *)(void*)(&__IPSBAR[0x000D7F]))\r
+#define MCF_INTC1_ICRn(x)      (*(vuint8 *)(void*)(&__IPSBAR[0x000D40+((x)*0x001)]))\r
+#define MCF_INTC1_SWIACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000DE0]))\r
+#define MCF_INTC1_L1IACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000DE4]))\r
+#define MCF_INTC1_L2IACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000DE8]))\r
+#define MCF_INTC1_L3IACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000DEC]))\r
+#define MCF_INTC1_L4IACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000DF0]))\r
+#define MCF_INTC1_L5IACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000DF4]))\r
+#define MCF_INTC1_L6IACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000DF8]))\r
+#define MCF_INTC1_L7IACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000DFC]))\r
+#define MCF_INTC1_LnIACK(x)    (*(vuint8 *)(void*)(&__IPSBAR[0x000DE4+((x)*0x004)]))\r
+\r
+/* Bit definitions and macros for MCF_INTC1_IPRH */\r
+#define MCF_INTC1_IPRH_INT32          (0x00000001)\r
+#define MCF_INTC1_IPRH_INT33          (0x00000002)\r
+#define MCF_INTC1_IPRH_INT34          (0x00000004)\r
+#define MCF_INTC1_IPRH_INT35          (0x00000008)\r
+#define MCF_INTC1_IPRH_INT36          (0x00000010)\r
+#define MCF_INTC1_IPRH_INT37          (0x00000020)\r
+#define MCF_INTC1_IPRH_INT38          (0x00000040)\r
+#define MCF_INTC1_IPRH_INT39          (0x00000080)\r
+#define MCF_INTC1_IPRH_INT40          (0x00000100)\r
+#define MCF_INTC1_IPRH_INT41          (0x00000200)\r
+#define MCF_INTC1_IPRH_INT42          (0x00000400)\r
+#define MCF_INTC1_IPRH_INT43          (0x00000800)\r
+#define MCF_INTC1_IPRH_INT44          (0x00001000)\r
+#define MCF_INTC1_IPRH_INT45          (0x00002000)\r
+#define MCF_INTC1_IPRH_INT46          (0x00004000)\r
+#define MCF_INTC1_IPRH_INT47          (0x00008000)\r
+#define MCF_INTC1_IPRH_INT48          (0x00010000)\r
+#define MCF_INTC1_IPRH_INT49          (0x00020000)\r
+#define MCF_INTC1_IPRH_INT50          (0x00040000)\r
+#define MCF_INTC1_IPRH_INT51          (0x00080000)\r
+#define MCF_INTC1_IPRH_INT52          (0x00100000)\r
+#define MCF_INTC1_IPRH_INT53          (0x00200000)\r
+#define MCF_INTC1_IPRH_INT54          (0x00400000)\r
+#define MCF_INTC1_IPRH_INT55          (0x00800000)\r
+#define MCF_INTC1_IPRH_INT56          (0x01000000)\r
+#define MCF_INTC1_IPRH_INT57          (0x02000000)\r
+#define MCF_INTC1_IPRH_INT58          (0x04000000)\r
+#define MCF_INTC1_IPRH_INT59          (0x08000000)\r
+#define MCF_INTC1_IPRH_INT60          (0x10000000)\r
+#define MCF_INTC1_IPRH_INT61          (0x20000000)\r
+#define MCF_INTC1_IPRH_INT62          (0x40000000)\r
+#define MCF_INTC1_IPRH_INT63          (0x80000000)\r
+\r
+/* Bit definitions and macros for MCF_INTC1_IPRL */\r
+#define MCF_INTC1_IPRL_INT1           (0x00000002)\r
+#define MCF_INTC1_IPRL_INT2           (0x00000004)\r
+#define MCF_INTC1_IPRL_INT3           (0x00000008)\r
+#define MCF_INTC1_IPRL_INT4           (0x00000010)\r
+#define MCF_INTC1_IPRL_INT5           (0x00000020)\r
+#define MCF_INTC1_IPRL_INT6           (0x00000040)\r
+#define MCF_INTC1_IPRL_INT7           (0x00000080)\r
+#define MCF_INTC1_IPRL_INT8           (0x00000100)\r
+#define MCF_INTC1_IPRL_INT9           (0x00000200)\r
+#define MCF_INTC1_IPRL_INT10          (0x00000400)\r
+#define MCF_INTC1_IPRL_INT11          (0x00000800)\r
+#define MCF_INTC1_IPRL_INT12          (0x00001000)\r
+#define MCF_INTC1_IPRL_INT13          (0x00002000)\r
+#define MCF_INTC1_IPRL_INT14          (0x00004000)\r
+#define MCF_INTC1_IPRL_INT15          (0x00008000)\r
+#define MCF_INTC1_IPRL_INT16          (0x00010000)\r
+#define MCF_INTC1_IPRL_INT17          (0x00020000)\r
+#define MCF_INTC1_IPRL_INT18          (0x00040000)\r
+#define MCF_INTC1_IPRL_INT19          (0x00080000)\r
+#define MCF_INTC1_IPRL_INT20          (0x00100000)\r
+#define MCF_INTC1_IPRL_INT21          (0x00200000)\r
+#define MCF_INTC1_IPRL_INT22          (0x00400000)\r
+#define MCF_INTC1_IPRL_INT23          (0x00800000)\r
+#define MCF_INTC1_IPRL_INT24          (0x01000000)\r
+#define MCF_INTC1_IPRL_INT25          (0x02000000)\r
+#define MCF_INTC1_IPRL_INT26          (0x04000000)\r
+#define MCF_INTC1_IPRL_INT27          (0x08000000)\r
+#define MCF_INTC1_IPRL_INT28          (0x10000000)\r
+#define MCF_INTC1_IPRL_INT29          (0x20000000)\r
+#define MCF_INTC1_IPRL_INT30          (0x40000000)\r
+#define MCF_INTC1_IPRL_INT31          (0x80000000)\r
+\r
+/* Bit definitions and macros for MCF_INTC1_IMRH */\r
+#define MCF_INTC1_IMRH_INT_MASK32     (0x00000001)\r
+#define MCF_INTC1_IMRH_INT_MASK33     (0x00000002)\r
+#define MCF_INTC1_IMRH_INT_MASK34     (0x00000004)\r
+#define MCF_INTC1_IMRH_INT_MASK35     (0x00000008)\r
+#define MCF_INTC1_IMRH_INT_MASK36     (0x00000010)\r
+#define MCF_INTC1_IMRH_INT_MASK37     (0x00000020)\r
+#define MCF_INTC1_IMRH_INT_MASK38     (0x00000040)\r
+#define MCF_INTC1_IMRH_INT_MASK39     (0x00000080)\r
+#define MCF_INTC1_IMRH_INT_MASK40     (0x00000100)\r
+#define MCF_INTC1_IMRH_INT_MASK41     (0x00000200)\r
+#define MCF_INTC1_IMRH_INT_MASK42     (0x00000400)\r
+#define MCF_INTC1_IMRH_INT_MASK43     (0x00000800)\r
+#define MCF_INTC1_IMRH_INT_MASK44     (0x00001000)\r
+#define MCF_INTC1_IMRH_INT_MASK45     (0x00002000)\r
+#define MCF_INTC1_IMRH_INT_MASK46     (0x00004000)\r
+#define MCF_INTC1_IMRH_INT_MASK47     (0x00008000)\r
+#define MCF_INTC1_IMRH_INT_MASK48     (0x00010000)\r
+#define MCF_INTC1_IMRH_INT_MASK49     (0x00020000)\r
+#define MCF_INTC1_IMRH_INT_MASK50     (0x00040000)\r
+#define MCF_INTC1_IMRH_INT_MASK51     (0x00080000)\r
+#define MCF_INTC1_IMRH_INT_MASK52     (0x00100000)\r
+#define MCF_INTC1_IMRH_INT_MASK53     (0x00200000)\r
+#define MCF_INTC1_IMRH_INT_MASK54     (0x00400000)\r
+#define MCF_INTC1_IMRH_INT_MASK55     (0x00800000)\r
+#define MCF_INTC1_IMRH_INT_MASK56     (0x01000000)\r
+#define MCF_INTC1_IMRH_INT_MASK57     (0x02000000)\r
+#define MCF_INTC1_IMRH_INT_MASK58     (0x04000000)\r
+#define MCF_INTC1_IMRH_INT_MASK59     (0x08000000)\r
+#define MCF_INTC1_IMRH_INT_MASK60     (0x10000000)\r
+#define MCF_INTC1_IMRH_INT_MASK61     (0x20000000)\r
+#define MCF_INTC1_IMRH_INT_MASK62     (0x40000000)\r
+#define MCF_INTC1_IMRH_INT_MASK63     (0x80000000)\r
+\r
+/* Bit definitions and macros for MCF_INTC1_IMRL */\r
+#define MCF_INTC1_IMRL_MASKALL        (0x00000001)\r
+#define MCF_INTC1_IMRL_INT_MASK1      (0x00000002)\r
+#define MCF_INTC1_IMRL_INT_MASK2      (0x00000004)\r
+#define MCF_INTC1_IMRL_INT_MASK3      (0x00000008)\r
+#define MCF_INTC1_IMRL_INT_MASK4      (0x00000010)\r
+#define MCF_INTC1_IMRL_INT_MASK5      (0x00000020)\r
+#define MCF_INTC1_IMRL_INT_MASK6      (0x00000040)\r
+#define MCF_INTC1_IMRL_INT_MASK7      (0x00000080)\r
+#define MCF_INTC1_IMRL_INT_MASK8      (0x00000100)\r
+#define MCF_INTC1_IMRL_INT_MASK9      (0x00000200)\r
+#define MCF_INTC1_IMRL_INT_MASK10     (0x00000400)\r
+#define MCF_INTC1_IMRL_INT_MASK11     (0x00000800)\r
+#define MCF_INTC1_IMRL_INT_MASK12     (0x00001000)\r
+#define MCF_INTC1_IMRL_INT_MASK13     (0x00002000)\r
+#define MCF_INTC1_IMRL_INT_MASK14     (0x00004000)\r
+#define MCF_INTC1_IMRL_INT_MASK15     (0x00008000)\r
+#define MCF_INTC1_IMRL_INT_MASK16     (0x00010000)\r
+#define MCF_INTC1_IMRL_INT_MASK17     (0x00020000)\r
+#define MCF_INTC1_IMRL_INT_MASK18     (0x00040000)\r
+#define MCF_INTC1_IMRL_INT_MASK19     (0x00080000)\r
+#define MCF_INTC1_IMRL_INT_MASK20     (0x00100000)\r
+#define MCF_INTC1_IMRL_INT_MASK21     (0x00200000)\r
+#define MCF_INTC1_IMRL_INT_MASK22     (0x00400000)\r
+#define MCF_INTC1_IMRL_INT_MASK23     (0x00800000)\r
+#define MCF_INTC1_IMRL_INT_MASK24     (0x01000000)\r
+#define MCF_INTC1_IMRL_INT_MASK25     (0x02000000)\r
+#define MCF_INTC1_IMRL_INT_MASK26     (0x04000000)\r
+#define MCF_INTC1_IMRL_INT_MASK27     (0x08000000)\r
+#define MCF_INTC1_IMRL_INT_MASK28     (0x10000000)\r
+#define MCF_INTC1_IMRL_INT_MASK29     (0x20000000)\r
+#define MCF_INTC1_IMRL_INT_MASK30     (0x40000000)\r
+#define MCF_INTC1_IMRL_INT_MASK31     (0x80000000)\r
+\r
+/* Bit definitions and macros for MCF_INTC1_INTFRCH */\r
+#define MCF_INTC1_INTFRCH_INTFRC32    (0x00000001)\r
+#define MCF_INTC1_INTFRCH_INTFRC33    (0x00000002)\r
+#define MCF_INTC1_INTFRCH_INTFRC34    (0x00000004)\r
+#define MCF_INTC1_INTFRCH_INTFRC35    (0x00000008)\r
+#define MCF_INTC1_INTFRCH_INTFRC36    (0x00000010)\r
+#define MCF_INTC1_INTFRCH_INTFRC37    (0x00000020)\r
+#define MCF_INTC1_INTFRCH_INTFRC38    (0x00000040)\r
+#define MCF_INTC1_INTFRCH_INTFRC39    (0x00000080)\r
+#define MCF_INTC1_INTFRCH_INTFRC40    (0x00000100)\r
+#define MCF_INTC1_INTFRCH_INTFRC41    (0x00000200)\r
+#define MCF_INTC1_INTFRCH_INTFRC42    (0x00000400)\r
+#define MCF_INTC1_INTFRCH_INTFRC43    (0x00000800)\r
+#define MCF_INTC1_INTFRCH_INTFRC44    (0x00001000)\r
+#define MCF_INTC1_INTFRCH_INTFRC45    (0x00002000)\r
+#define MCF_INTC1_INTFRCH_INTFRC46    (0x00004000)\r
+#define MCF_INTC1_INTFRCH_INTFRC47    (0x00008000)\r
+#define MCF_INTC1_INTFRCH_INTFRC48    (0x00010000)\r
+#define MCF_INTC1_INTFRCH_INTFRC49    (0x00020000)\r
+#define MCF_INTC1_INTFRCH_INTFRC50    (0x00040000)\r
+#define MCF_INTC1_INTFRCH_INTFRC51    (0x00080000)\r
+#define MCF_INTC1_INTFRCH_INTFRC52    (0x00100000)\r
+#define MCF_INTC1_INTFRCH_INTFRC53    (0x00200000)\r
+#define MCF_INTC1_INTFRCH_INTFRC54    (0x00400000)\r
+#define MCF_INTC1_INTFRCH_INTFRC55    (0x00800000)\r
+#define MCF_INTC1_INTFRCH_INTFRC56    (0x01000000)\r
+#define MCF_INTC1_INTFRCH_INTFRC57    (0x02000000)\r
+#define MCF_INTC1_INTFRCH_INTFRC58    (0x04000000)\r
+#define MCF_INTC1_INTFRCH_INTFRC59    (0x08000000)\r
+#define MCF_INTC1_INTFRCH_INTFRC60    (0x10000000)\r
+#define MCF_INTC1_INTFRCH_INTFRC61    (0x20000000)\r
+#define MCF_INTC1_INTFRCH_INTFRC62    (0x40000000)\r
+#define MCF_INTC1_INTFRCH_INTFRC63    (0x80000000)\r
+\r
+/* Bit definitions and macros for MCF_INTC1_INTFRCL */\r
+#define MCF_INTC1_INTFRCL_INTFRC1     (0x00000002)\r
+#define MCF_INTC1_INTFRCL_INTFRC2     (0x00000004)\r
+#define MCF_INTC1_INTFRCL_INTFRC3     (0x00000008)\r
+#define MCF_INTC1_INTFRCL_INTFRC4     (0x00000010)\r
+#define MCF_INTC1_INTFRCL_INTFRC5     (0x00000020)\r
+#define MCF_INTC1_INTFRCL_INT6        (0x00000040)\r
+#define MCF_INTC1_INTFRCL_INT7        (0x00000080)\r
+#define MCF_INTC1_INTFRCL_INT8        (0x00000100)\r
+#define MCF_INTC1_INTFRCL_INT9        (0x00000200)\r
+#define MCF_INTC1_INTFRCL_INT10       (0x00000400)\r
+#define MCF_INTC1_INTFRCL_INTFRC11    (0x00000800)\r
+#define MCF_INTC1_INTFRCL_INTFRC12    (0x00001000)\r
+#define MCF_INTC1_INTFRCL_INTFRC13    (0x00002000)\r
+#define MCF_INTC1_INTFRCL_INTFRC14    (0x00004000)\r
+#define MCF_INTC1_INTFRCL_INT15       (0x00008000)\r
+#define MCF_INTC1_INTFRCL_INTFRC16    (0x00010000)\r
+#define MCF_INTC1_INTFRCL_INTFRC17    (0x00020000)\r
+#define MCF_INTC1_INTFRCL_INTFRC18    (0x00040000)\r
+#define MCF_INTC1_INTFRCL_INTFRC19    (0x00080000)\r
+#define MCF_INTC1_INTFRCL_INTFRC20    (0x00100000)\r
+#define MCF_INTC1_INTFRCL_INTFRC21    (0x00200000)\r
+#define MCF_INTC1_INTFRCL_INTFRC22    (0x00400000)\r
+#define MCF_INTC1_INTFRCL_INTFRC23    (0x00800000)\r
+#define MCF_INTC1_INTFRCL_INTFRC24    (0x01000000)\r
+#define MCF_INTC1_INTFRCL_INTFRC25    (0x02000000)\r
+#define MCF_INTC1_INTFRCL_INTFRC26    (0x04000000)\r
+#define MCF_INTC1_INTFRCL_INTFRC27    (0x08000000)\r
+#define MCF_INTC1_INTFRCL_INTFRC28    (0x10000000)\r
+#define MCF_INTC1_INTFRCL_INTFRC29    (0x20000000)\r
+#define MCF_INTC1_INTFRCL_INTFRC30    (0x40000000)\r
+#define MCF_INTC1_INTFRCL_INTFRC31    (0x80000000)\r
+\r
+/* Bit definitions and macros for MCF_INTC1_IRLR */\r
+#define MCF_INTC1_IRLR_IRQ(x)         (((x)&0x7F)<<1)\r
+\r
+/* Bit definitions and macros for MCF_INTC1_IACKLPR */\r
+#define MCF_INTC1_IACKLPR_PRI(x)      (((x)&0x0F)<<0)\r
+#define MCF_INTC1_IACKLPR_LEVEL(x)    (((x)&0x07)<<4)\r
+\r
+/* Bit definitions and macros for MCF_INTC1_ICRn */\r
+#define MCF_INTC1_ICRn_IP(x)          (((x)&0x07)<<0)\r
+#define MCF_INTC1_ICRn_IL(x)          (((x)&0x07)<<3)\r
+\r
+/********************************************************************/\r
+\r
+#endif /* __MCF523X_INTC1_H__ */\r
index adc714f6dbb0a685fb2e79631f08a51d6a4e7587..cc2ff27102686e5def607ab60350a8311202c61b 100644 (file)
-/*
- * These files are taken from the MCF523X source code example package
- * which is available on the Freescale website. Freescale explicitly 
- * grants the redistribution and modification of these source files.
- * The complete licensing information is available in the file 
- * LICENSE_FREESCALE.TXT.
- *
- * File:       mcf523x_mdha.h
- * Purpose:    Register and bit definitions for the MCF523X
- *
- * Notes:      
- *     
- */
-
-#ifndef __MCF523X_MDHA_H__
-#define __MCF523X_MDHA_H__
-
-/*********************************************************************
-*
-* Message Digest Hardware Accelerator (MDHA)
-*
-*********************************************************************/
-
-/* Register read/write macros */
-#define MCF_MDHA_MDMR     (*(vuint32*)(void*)(&__IPSBAR[0x190000]))
-#define MCF_MDHA_MDCR     (*(vuint32*)(void*)(&__IPSBAR[0x190004]))
-#define MCF_MDHA_MDCMR    (*(vuint32*)(void*)(&__IPSBAR[0x190008]))
-#define MCF_MDHA_MDSR     (*(vuint32*)(void*)(&__IPSBAR[0x19000C]))
-#define MCF_MDHA_MDISR     (*(vuint32*)(void*)(&__IPSBAR[0x190010]))
-#define MCF_MDHA_MDIMR    (*(vuint32*)(void*)(&__IPSBAR[0x190014]))
-#define MCF_MDHA_MDDSR    (*(vuint32*)(void*)(&__IPSBAR[0x19001C]))
-#define MCF_MDHA_MDIN     (*(vuint32*)(void*)(&__IPSBAR[0x190020]))
-#define MCF_MDHA_MDA0     (*(vuint32*)(void*)(&__IPSBAR[0x190030]))
-#define MCF_MDHA_MDB0     (*(vuint32*)(void*)(&__IPSBAR[0x190034]))
-#define MCF_MDHA_MDC0     (*(vuint32*)(void*)(&__IPSBAR[0x190038]))
-#define MCF_MDHA_MDD0     (*(vuint32*)(void*)(&__IPSBAR[0x19003C]))
-#define MCF_MDHA_MDE0     (*(vuint32*)(void*)(&__IPSBAR[0x190040]))
-#define MCF_MDHA_MDMDS    (*(vuint32*)(void*)(&__IPSBAR[0x190044]))
-#define MCF_MDHA_MDA1     (*(vuint32*)(void*)(&__IPSBAR[0x190070]))
-#define MCF_MDHA_MDB1     (*(vuint32*)(void*)(&__IPSBAR[0x190074]))
-#define MCF_MDHA_MDC1     (*(vuint32*)(void*)(&__IPSBAR[0x190078]))
-#define MCF_MDHA_MDD1     (*(vuint32*)(void*)(&__IPSBAR[0x19007C]))
-#define MCF_MDHA_MDE1     (*(vuint32*)(void*)(&__IPSBAR[0x190080]))
-
-/* Bit definitions and macros for MCF_MDHA_MDMR */
-#define MCF_MDHA_MDMR_ALG             (0x00000001)
-#define MCF_MDHA_MDMR_PDATA           (0x00000004)
-#define MCF_MDHA_MDMR_MAC(x)          (((x)&0x00000003)<<3)
-#define MCF_MDHA_MDMR_INIT            (0x00000020)
-#define MCF_MDHA_MDMR_IPAD            (0x00000040)
-#define MCF_MDHA_MDMR_OPAD            (0x00000080)
-#define MCF_MDHA_MDMR_SWAP            (0x00000100)
-#define MCF_MDHA_MDMR_MACFULL         (0x00000200)
-#define MCF_MDHA_MDMR_SSL             (0x00000400)
-
-/* Bit definitions and macros for MCF_MDHA_MDCR */
-#define MCF_MDHA_MDCR_IE              (0x00000001)
-
-/* Bit definitions and macros for MCF_MDHA_MDCMR */
-#define MCF_MDHA_MDCMR_SWR             (0x00000001)
-#define MCF_MDHA_MDCMR_RI             (0x00000002)
-#define MCF_MDHA_MDCMR_CI             (0x00000004)
-#define MCF_MDHA_MDCMR_GO             (0x00000008)
-
-/* Bit definitions and macros for MCF_MDHA_MDSR */
-#define MCF_MDHA_MDSR_INT             (0x00000001)
-#define MCF_MDHA_MDSR_DONE            (0x00000002)
-#define MCF_MDHA_MDSR_ERR             (0x00000004)
-#define MCF_MDHA_MDSR_RD              (0x00000008)
-#define MCF_MDHA_MDSR_BUSY            (0x00000010)
-#define MCF_MDHA_MDSR_END             (0x00000020)
-#define MCF_MDHA_MDSR_HSH             (0x00000040)
-#define MCF_MDHA_MDSR_GNW             (0x00000080)
-#define MCF_MDHA_MDSR_FS(x)           (((x)&0x00000007)<<8)
-#define MCF_MDHA_MDSR_APD(x)          (((x)&0x00000007)<<13)
-#define MCF_MDHA_MDSR_IFL(x)          (((x)&0x000000FF)<<16)
-
-/* Bit definitions and macros for MCF_MDHA_MDIR */
-#define MCF_MDHA_MDIR_IFO             (0x00000001)
-#define MCF_MDHA_MDIR_NON             (0x00000004)
-#define MCF_MDHA_MDIR_IME             (0x00000010)
-#define MCF_MDHA_MDIR_IDS             (0x00000020)
-#define MCF_MDHA_MDIR_RMDP            (0x00000080)
-#define MCF_MDHA_MDIR_ERE             (0x00000100)
-#define MCF_MDHA_MDIR_GTDS            (0x00000200)
-
-/* Bit definitions and macros for MCF_MDHA_MDIMR */
-#define MCF_MDHA_MDIMR_IFO            (0x00000001)
-#define MCF_MDHA_MDIMR_NON            (0x00000004)
-#define MCF_MDHA_MDIMR_IME            (0x00000010)
-#define MCF_MDHA_MDIMR_IDS            (0x00000020)
-#define MCF_MDHA_MDIMR_RMDP           (0x00000080)
-#define MCF_MDHA_MDIMR_ERE            (0x00000100)
-#define MCF_MDHA_MDIMR_GTDS           (0x00000200)
-
-/* Bit definitions and macros for MCF_MDHA_MDDSR */
-#define MCF_MDHA_MDDSR_DATASIZE(x)    (((x)&0x1FFFFFFF)<<0)
-
-/********************************************************************/
-
-#endif /* __MCF523X_MDHA_H__ */
+/*\r
+ * These files are taken from the MCF523X source code example package\r
+ * which is available on the Freescale website. Freescale explicitly \r
+ * grants the redistribution and modification of these source files.\r
+ * The complete licensing information is available in the file \r
+ * LICENSE_FREESCALE.TXT.\r
+ *\r
+ * File:       mcf523x_mdha.h\r
+ * Purpose:    Register and bit definitions for the MCF523X\r
+ *\r
+ * Notes:      \r
+ *     \r
+ */\r
+\r
+#ifndef __MCF523X_MDHA_H__\r
+#define __MCF523X_MDHA_H__\r
+\r
+/*********************************************************************\r
+*\r
+* Message Digest Hardware Accelerator (MDHA)\r
+*\r
+*********************************************************************/\r
+\r
+/* Register read/write macros */\r
+#define MCF_MDHA_MDMR     (*(vuint32*)(void*)(&__IPSBAR[0x190000]))\r
+#define MCF_MDHA_MDCR     (*(vuint32*)(void*)(&__IPSBAR[0x190004]))\r
+#define MCF_MDHA_MDCMR    (*(vuint32*)(void*)(&__IPSBAR[0x190008]))\r
+#define MCF_MDHA_MDSR     (*(vuint32*)(void*)(&__IPSBAR[0x19000C]))\r
+#define MCF_MDHA_MDISR     (*(vuint32*)(void*)(&__IPSBAR[0x190010]))\r
+#define MCF_MDHA_MDIMR    (*(vuint32*)(void*)(&__IPSBAR[0x190014]))\r
+#define MCF_MDHA_MDDSR    (*(vuint32*)(void*)(&__IPSBAR[0x19001C]))\r
+#define MCF_MDHA_MDIN     (*(vuint32*)(void*)(&__IPSBAR[0x190020]))\r
+#define MCF_MDHA_MDA0     (*(vuint32*)(void*)(&__IPSBAR[0x190030]))\r
+#define MCF_MDHA_MDB0     (*(vuint32*)(void*)(&__IPSBAR[0x190034]))\r
+#define MCF_MDHA_MDC0     (*(vuint32*)(void*)(&__IPSBAR[0x190038]))\r
+#define MCF_MDHA_MDD0     (*(vuint32*)(void*)(&__IPSBAR[0x19003C]))\r
+#define MCF_MDHA_MDE0     (*(vuint32*)(void*)(&__IPSBAR[0x190040]))\r
+#define MCF_MDHA_MDMDS    (*(vuint32*)(void*)(&__IPSBAR[0x190044]))\r
+#define MCF_MDHA_MDA1     (*(vuint32*)(void*)(&__IPSBAR[0x190070]))\r
+#define MCF_MDHA_MDB1     (*(vuint32*)(void*)(&__IPSBAR[0x190074]))\r
+#define MCF_MDHA_MDC1     (*(vuint32*)(void*)(&__IPSBAR[0x190078]))\r
+#define MCF_MDHA_MDD1     (*(vuint32*)(void*)(&__IPSBAR[0x19007C]))\r
+#define MCF_MDHA_MDE1     (*(vuint32*)(void*)(&__IPSBAR[0x190080]))\r
+\r
+/* Bit definitions and macros for MCF_MDHA_MDMR */\r
+#define MCF_MDHA_MDMR_ALG             (0x00000001)\r
+#define MCF_MDHA_MDMR_PDATA           (0x00000004)\r
+#define MCF_MDHA_MDMR_MAC(x)          (((x)&0x00000003)<<3)\r
+#define MCF_MDHA_MDMR_INIT            (0x00000020)\r
+#define MCF_MDHA_MDMR_IPAD            (0x00000040)\r
+#define MCF_MDHA_MDMR_OPAD            (0x00000080)\r
+#define MCF_MDHA_MDMR_SWAP            (0x00000100)\r
+#define MCF_MDHA_MDMR_MACFULL         (0x00000200)\r
+#define MCF_MDHA_MDMR_SSL             (0x00000400)\r
+\r
+/* Bit definitions and macros for MCF_MDHA_MDCR */\r
+#define MCF_MDHA_MDCR_IE              (0x00000001)\r
+\r
+/* Bit definitions and macros for MCF_MDHA_MDCMR */\r
+#define MCF_MDHA_MDCMR_SWR             (0x00000001)\r
+#define MCF_MDHA_MDCMR_RI             (0x00000002)\r
+#define MCF_MDHA_MDCMR_CI             (0x00000004)\r
+#define MCF_MDHA_MDCMR_GO             (0x00000008)\r
+\r
+/* Bit definitions and macros for MCF_MDHA_MDSR */\r
+#define MCF_MDHA_MDSR_INT             (0x00000001)\r
+#define MCF_MDHA_MDSR_DONE            (0x00000002)\r
+#define MCF_MDHA_MDSR_ERR             (0x00000004)\r
+#define MCF_MDHA_MDSR_RD              (0x00000008)\r
+#define MCF_MDHA_MDSR_BUSY            (0x00000010)\r
+#define MCF_MDHA_MDSR_END             (0x00000020)\r
+#define MCF_MDHA_MDSR_HSH             (0x00000040)\r
+#define MCF_MDHA_MDSR_GNW             (0x00000080)\r
+#define MCF_MDHA_MDSR_FS(x)           (((x)&0x00000007)<<8)\r
+#define MCF_MDHA_MDSR_APD(x)          (((x)&0x00000007)<<13)\r
+#define MCF_MDHA_MDSR_IFL(x)          (((x)&0x000000FF)<<16)\r
+\r
+/* Bit definitions and macros for MCF_MDHA_MDIR */\r
+#define MCF_MDHA_MDIR_IFO             (0x00000001)\r
+#define MCF_MDHA_MDIR_NON             (0x00000004)\r
+#define MCF_MDHA_MDIR_IME             (0x00000010)\r
+#define MCF_MDHA_MDIR_IDS             (0x00000020)\r
+#define MCF_MDHA_MDIR_RMDP            (0x00000080)\r
+#define MCF_MDHA_MDIR_ERE             (0x00000100)\r
+#define MCF_MDHA_MDIR_GTDS            (0x00000200)\r
+\r
+/* Bit definitions and macros for MCF_MDHA_MDIMR */\r
+#define MCF_MDHA_MDIMR_IFO            (0x00000001)\r
+#define MCF_MDHA_MDIMR_NON            (0x00000004)\r
+#define MCF_MDHA_MDIMR_IME            (0x00000010)\r
+#define MCF_MDHA_MDIMR_IDS            (0x00000020)\r
+#define MCF_MDHA_MDIMR_RMDP           (0x00000080)\r
+#define MCF_MDHA_MDIMR_ERE            (0x00000100)\r
+#define MCF_MDHA_MDIMR_GTDS           (0x00000200)\r
+\r
+/* Bit definitions and macros for MCF_MDHA_MDDSR */\r
+#define MCF_MDHA_MDDSR_DATASIZE(x)    (((x)&0x1FFFFFFF)<<0)\r
+\r
+/********************************************************************/\r
+\r
+#endif /* __MCF523X_MDHA_H__ */\r
index 0763d20f2e8bac38868c6c4f3185e9e58416c7a1..a3798f070af7f44f377911305701853400cdf345 100644 (file)
@@ -1,89 +1,89 @@
-/*
- * These files are taken from the MCF523X source code example package
- * which is available on the Freescale website. Freescale explicitly 
- * grants the redistribution and modification of these source files.
- * The complete licensing information is available in the file 
- * LICENSE_FREESCALE.TXT.
- *
- * File:       mcf523x_pit.h
- * Purpose:    Register and bit definitions for the MCF523X
- *
- * Notes:      
- *     
- */
-
-#ifndef __MCF523X_PIT_H__
-#define __MCF523X_PIT_H__
-
-/*********************************************************************
-*
-* Programmable Interrupt Timer Modules (PIT)
-*
-*********************************************************************/
-
-/* Register read/write macros */
-#define MCF_PIT_PCSR0       (*(vuint16*)(void*)(&__IPSBAR[0x150000]))
-#define MCF_PIT_PMR0        (*(vuint16*)(void*)(&__IPSBAR[0x150002]))
-#define MCF_PIT_PCNTR0      (*(vuint16*)(void*)(&__IPSBAR[0x150004]))
-#define MCF_PIT_PCSR1       (*(vuint16*)(void*)(&__IPSBAR[0x160000]))
-#define MCF_PIT_PMR1        (*(vuint16*)(void*)(&__IPSBAR[0x160002]))
-#define MCF_PIT_PCNTR1      (*(vuint16*)(void*)(&__IPSBAR[0x160004]))
-#define MCF_PIT_PCSR2       (*(vuint16*)(void*)(&__IPSBAR[0x170000]))
-#define MCF_PIT_PMR2        (*(vuint16*)(void*)(&__IPSBAR[0x170002]))
-#define MCF_PIT_PCNTR2      (*(vuint16*)(void*)(&__IPSBAR[0x170004]))
-#define MCF_PIT_PCSR3       (*(vuint16*)(void*)(&__IPSBAR[0x180000]))
-#define MCF_PIT_PMR3        (*(vuint16*)(void*)(&__IPSBAR[0x180002]))
-#define MCF_PIT_PCNTR3      (*(vuint16*)(void*)(&__IPSBAR[0x180004]))
-#define MCF_PIT_PCSR(x)     (*(vuint16*)(void*)(&__IPSBAR[0x150000+((x)*0x10000)]))
-#define MCF_PIT_PMR(x)      (*(vuint16*)(void*)(&__IPSBAR[0x150002+((x)*0x10000)]))
-#define MCF_PIT_PCNTR(x)    (*(vuint16*)(void*)(&__IPSBAR[0x150004+((x)*0x10000)]))
-
-/* Bit definitions and macros for MCF_PIT_PCSR */
-#define MCF_PIT_PCSR_EN        (0x0001)
-#define MCF_PIT_PCSR_RLD       (0x0002)
-#define MCF_PIT_PCSR_PIF       (0x0004)
-#define MCF_PIT_PCSR_PIE       (0x0008)
-#define MCF_PIT_PCSR_OVW       (0x0010)
-#define MCF_PIT_PCSR_HALTED    (0x0020)
-#define MCF_PIT_PCSR_DOZE      (0x0040)
-#define MCF_PIT_PCSR_PRE(x)    (((x)&0x000F)<<8)
-
-/* Bit definitions and macros for MCF_PIT_PMR */
-#define MCF_PIT_PMR_PM0        (0x0001)
-#define MCF_PIT_PMR_PM1        (0x0002)
-#define MCF_PIT_PMR_PM2        (0x0004)
-#define MCF_PIT_PMR_PM3        (0x0008)
-#define MCF_PIT_PMR_PM4        (0x0010)
-#define MCF_PIT_PMR_PM5        (0x0020)
-#define MCF_PIT_PMR_PM6        (0x0040)
-#define MCF_PIT_PMR_PM7        (0x0080)
-#define MCF_PIT_PMR_PM8        (0x0100)
-#define MCF_PIT_PMR_PM9        (0x0200)
-#define MCF_PIT_PMR_PM10       (0x0400)
-#define MCF_PIT_PMR_PM11       (0x0800)
-#define MCF_PIT_PMR_PM12       (0x1000)
-#define MCF_PIT_PMR_PM13       (0x2000)
-#define MCF_PIT_PMR_PM14       (0x4000)
-#define MCF_PIT_PMR_PM15       (0x8000)
-
-/* Bit definitions and macros for MCF_PIT_PCNTR */
-#define MCF_PIT_PCNTR_PC0      (0x0001)
-#define MCF_PIT_PCNTR_PC1      (0x0002)
-#define MCF_PIT_PCNTR_PC2      (0x0004)
-#define MCF_PIT_PCNTR_PC3      (0x0008)
-#define MCF_PIT_PCNTR_PC4      (0x0010)
-#define MCF_PIT_PCNTR_PC5      (0x0020)
-#define MCF_PIT_PCNTR_PC6      (0x0040)
-#define MCF_PIT_PCNTR_PC7      (0x0080)
-#define MCF_PIT_PCNTR_PC8      (0x0100)
-#define MCF_PIT_PCNTR_PC9      (0x0200)
-#define MCF_PIT_PCNTR_PC10     (0x0400)
-#define MCF_PIT_PCNTR_PC11     (0x0800)
-#define MCF_PIT_PCNTR_PC12     (0x1000)
-#define MCF_PIT_PCNTR_PC13     (0x2000)
-#define MCF_PIT_PCNTR_PC14     (0x4000)
-#define MCF_PIT_PCNTR_PC15     (0x8000)
-
-/********************************************************************/
-
-#endif /* __MCF523X_PIT_H__ */
+/*\r
+ * These files are taken from the MCF523X source code example package\r
+ * which is available on the Freescale website. Freescale explicitly \r
+ * grants the redistribution and modification of these source files.\r
+ * The complete licensing information is available in the file \r
+ * LICENSE_FREESCALE.TXT.\r
+ *\r
+ * File:       mcf523x_pit.h\r
+ * Purpose:    Register and bit definitions for the MCF523X\r
+ *\r
+ * Notes:      \r
+ *     \r
+ */\r
+\r
+#ifndef __MCF523X_PIT_H__\r
+#define __MCF523X_PIT_H__\r
+\r
+/*********************************************************************\r
+*\r
+* Programmable Interrupt Timer Modules (PIT)\r
+*\r
+*********************************************************************/\r
+\r
+/* Register read/write macros */\r
+#define MCF_PIT_PCSR0       (*(vuint16*)(void*)(&__IPSBAR[0x150000]))\r
+#define MCF_PIT_PMR0        (*(vuint16*)(void*)(&__IPSBAR[0x150002]))\r
+#define MCF_PIT_PCNTR0      (*(vuint16*)(void*)(&__IPSBAR[0x150004]))\r
+#define MCF_PIT_PCSR1       (*(vuint16*)(void*)(&__IPSBAR[0x160000]))\r
+#define MCF_PIT_PMR1        (*(vuint16*)(void*)(&__IPSBAR[0x160002]))\r
+#define MCF_PIT_PCNTR1      (*(vuint16*)(void*)(&__IPSBAR[0x160004]))\r
+#define MCF_PIT_PCSR2       (*(vuint16*)(void*)(&__IPSBAR[0x170000]))\r
+#define MCF_PIT_PMR2        (*(vuint16*)(void*)(&__IPSBAR[0x170002]))\r
+#define MCF_PIT_PCNTR2      (*(vuint16*)(void*)(&__IPSBAR[0x170004]))\r
+#define MCF_PIT_PCSR3       (*(vuint16*)(void*)(&__IPSBAR[0x180000]))\r
+#define MCF_PIT_PMR3        (*(vuint16*)(void*)(&__IPSBAR[0x180002]))\r
+#define MCF_PIT_PCNTR3      (*(vuint16*)(void*)(&__IPSBAR[0x180004]))\r
+#define MCF_PIT_PCSR(x)     (*(vuint16*)(void*)(&__IPSBAR[0x150000+((x)*0x10000)]))\r
+#define MCF_PIT_PMR(x)      (*(vuint16*)(void*)(&__IPSBAR[0x150002+((x)*0x10000)]))\r
+#define MCF_PIT_PCNTR(x)    (*(vuint16*)(void*)(&__IPSBAR[0x150004+((x)*0x10000)]))\r
+\r
+/* Bit definitions and macros for MCF_PIT_PCSR */\r
+#define MCF_PIT_PCSR_EN        (0x0001)\r
+#define MCF_PIT_PCSR_RLD       (0x0002)\r
+#define MCF_PIT_PCSR_PIF       (0x0004)\r
+#define MCF_PIT_PCSR_PIE       (0x0008)\r
+#define MCF_PIT_PCSR_OVW       (0x0010)\r
+#define MCF_PIT_PCSR_HALTED    (0x0020)\r
+#define MCF_PIT_PCSR_DOZE      (0x0040)\r
+#define MCF_PIT_PCSR_PRE(x)    (((x)&0x000F)<<8)\r
+\r
+/* Bit definitions and macros for MCF_PIT_PMR */\r
+#define MCF_PIT_PMR_PM0        (0x0001)\r
+#define MCF_PIT_PMR_PM1        (0x0002)\r
+#define MCF_PIT_PMR_PM2        (0x0004)\r
+#define MCF_PIT_PMR_PM3        (0x0008)\r
+#define MCF_PIT_PMR_PM4        (0x0010)\r
+#define MCF_PIT_PMR_PM5        (0x0020)\r
+#define MCF_PIT_PMR_PM6        (0x0040)\r
+#define MCF_PIT_PMR_PM7        (0x0080)\r
+#define MCF_PIT_PMR_PM8        (0x0100)\r
+#define MCF_PIT_PMR_PM9        (0x0200)\r
+#define MCF_PIT_PMR_PM10       (0x0400)\r
+#define MCF_PIT_PMR_PM11       (0x0800)\r
+#define MCF_PIT_PMR_PM12       (0x1000)\r
+#define MCF_PIT_PMR_PM13       (0x2000)\r
+#define MCF_PIT_PMR_PM14       (0x4000)\r
+#define MCF_PIT_PMR_PM15       (0x8000)\r
+\r
+/* Bit definitions and macros for MCF_PIT_PCNTR */\r
+#define MCF_PIT_PCNTR_PC0      (0x0001)\r
+#define MCF_PIT_PCNTR_PC1      (0x0002)\r
+#define MCF_PIT_PCNTR_PC2      (0x0004)\r
+#define MCF_PIT_PCNTR_PC3      (0x0008)\r
+#define MCF_PIT_PCNTR_PC4      (0x0010)\r
+#define MCF_PIT_PCNTR_PC5      (0x0020)\r
+#define MCF_PIT_PCNTR_PC6      (0x0040)\r
+#define MCF_PIT_PCNTR_PC7      (0x0080)\r
+#define MCF_PIT_PCNTR_PC8      (0x0100)\r
+#define MCF_PIT_PCNTR_PC9      (0x0200)\r
+#define MCF_PIT_PCNTR_PC10     (0x0400)\r
+#define MCF_PIT_PCNTR_PC11     (0x0800)\r
+#define MCF_PIT_PCNTR_PC12     (0x1000)\r
+#define MCF_PIT_PCNTR_PC13     (0x2000)\r
+#define MCF_PIT_PCNTR_PC14     (0x4000)\r
+#define MCF_PIT_PCNTR_PC15     (0x8000)\r
+\r
+/********************************************************************/\r
+\r
+#endif /* __MCF523X_PIT_H__ */\r
index ed32d6d40f068009e7b494e49adfa8c6c762cf68..9f05ada6113aaeef70d2e1cec43ae3faa43f6426 100644 (file)
@@ -1,69 +1,69 @@
-/*
- * These files are taken from the MCF523X source code example package
- * which is available on the Freescale website. Freescale explicitly 
- * grants the redistribution and modification of these source files.
- * The complete licensing information is available in the file 
- * LICENSE_FREESCALE.TXT.
- *
- * File:       mcf523x_qspi.h
- * Purpose:    Register and bit definitions for the MCF523X
- *
- * Notes:      
- *     
- */
-
-#ifndef __MCF523X_QSPI_H__
-#define __MCF523X_QSPI_H__
-
-/*********************************************************************
-*
-* Queued Serial Peripheral Interface (QSPI)
-*
-*********************************************************************/
-
-/* Register read/write macros */
-#define MCF_QSPI_QMR      (*(vuint16*)(void*)(&__IPSBAR[0x000340]))
-#define MCF_QSPI_QDLYR    (*(vuint16*)(void*)(&__IPSBAR[0x000344]))
-#define MCF_QSPI_QWR      (*(vuint16*)(void*)(&__IPSBAR[0x000348]))
-#define MCF_QSPI_QIR      (*(vuint16*)(void*)(&__IPSBAR[0x00034C]))
-#define MCF_QSPI_QAR      (*(vuint16*)(void*)(&__IPSBAR[0x000350]))
-#define MCF_QSPI_QDR      (*(vuint16*)(void*)(&__IPSBAR[0x000354]))
-
-/* Bit definitions and macros for MCF_QSPI_QMR */
-#define MCF_QSPI_QMR_BAUD(x)     (((x)&0x00FF)<<0)
-#define MCF_QSPI_QMR_CPHA        (0x0100)
-#define MCF_QSPI_QMR_CPOL        (0x0200)
-#define MCF_QSPI_QMR_BITS(x)     (((x)&0x000F)<<10)
-#define MCF_QSPI_QMR_DOHIE       (0x4000)
-#define MCF_QSPI_QMR_MSTR        (0x8000)
-
-/* Bit definitions and macros for MCF_QSPI_QDLYR */
-#define MCF_QSPI_QDLYR_DTL(x)    (((x)&0x00FF)<<0)
-#define MCF_QSPI_QDLYR_QCD(x)    (((x)&0x007F)<<8)
-#define MCF_QSPI_QDLYR_SPE       (0x8000)
-
-/* Bit definitions and macros for MCF_QSPI_QWR */
-#define MCF_QSPI_QWR_NEWQP(x)    (((x)&0x000F)<<0)
-#define MCF_QSPI_QWR_ENDQP(x)    (((x)&0x000F)<<8)
-#define MCF_QSPI_QWR_CSIV        (0x1000)
-#define MCF_QSPI_QWR_WRTO        (0x2000)
-#define MCF_QSPI_QWR_WREN        (0x4000)
-#define MCF_QSPI_QWR_HALT        (0x8000)
-
-/* Bit definitions and macros for MCF_QSPI_QIR */
-#define MCF_QSPI_QIR_SPIF        (0x0001)
-#define MCF_QSPI_QIR_ABRT        (0x0004)
-#define MCF_QSPI_QIR_WCEF        (0x0008)
-#define MCF_QSPI_QIR_SPIFE       (0x0100)
-#define MCF_QSPI_QIR_ABRTE       (0x0400)
-#define MCF_QSPI_QIR_WCEFE       (0x0800)
-#define MCF_QSPI_QIR_ABRTL       (0x1000)
-#define MCF_QSPI_QIR_ABRTB       (0x4000)
-#define MCF_QSPI_QIR_WCEFB       (0x8000)
-
-/* Bit definitions and macros for MCF_QSPI_QAR */
-#define MCF_QSPI_QAR_ADDR(x)     (((x)&0x003F)<<0)
-
-/********************************************************************/
-
-#endif /* __MCF523X_QSPI_H__ */
+/*\r
+ * These files are taken from the MCF523X source code example package\r
+ * which is available on the Freescale website. Freescale explicitly \r
+ * grants the redistribution and modification of these source files.\r
+ * The complete licensing information is available in the file \r
+ * LICENSE_FREESCALE.TXT.\r
+ *\r
+ * File:       mcf523x_qspi.h\r
+ * Purpose:    Register and bit definitions for the MCF523X\r
+ *\r
+ * Notes:      \r
+ *     \r
+ */\r
+\r
+#ifndef __MCF523X_QSPI_H__\r
+#define __MCF523X_QSPI_H__\r
+\r
+/*********************************************************************\r
+*\r
+* Queued Serial Peripheral Interface (QSPI)\r
+*\r
+*********************************************************************/\r
+\r
+/* Register read/write macros */\r
+#define MCF_QSPI_QMR      (*(vuint16*)(void*)(&__IPSBAR[0x000340]))\r
+#define MCF_QSPI_QDLYR    (*(vuint16*)(void*)(&__IPSBAR[0x000344]))\r
+#define MCF_QSPI_QWR      (*(vuint16*)(void*)(&__IPSBAR[0x000348]))\r
+#define MCF_QSPI_QIR      (*(vuint16*)(void*)(&__IPSBAR[0x00034C]))\r
+#define MCF_QSPI_QAR      (*(vuint16*)(void*)(&__IPSBAR[0x000350]))\r
+#define MCF_QSPI_QDR      (*(vuint16*)(void*)(&__IPSBAR[0x000354]))\r
+\r
+/* Bit definitions and macros for MCF_QSPI_QMR */\r
+#define MCF_QSPI_QMR_BAUD(x)     (((x)&0x00FF)<<0)\r
+#define MCF_QSPI_QMR_CPHA        (0x0100)\r
+#define MCF_QSPI_QMR_CPOL        (0x0200)\r
+#define MCF_QSPI_QMR_BITS(x)     (((x)&0x000F)<<10)\r
+#define MCF_QSPI_QMR_DOHIE       (0x4000)\r
+#define MCF_QSPI_QMR_MSTR        (0x8000)\r
+\r
+/* Bit definitions and macros for MCF_QSPI_QDLYR */\r
+#define MCF_QSPI_QDLYR_DTL(x)    (((x)&0x00FF)<<0)\r
+#define MCF_QSPI_QDLYR_QCD(x)    (((x)&0x007F)<<8)\r
+#define MCF_QSPI_QDLYR_SPE       (0x8000)\r
+\r
+/* Bit definitions and macros for MCF_QSPI_QWR */\r
+#define MCF_QSPI_QWR_NEWQP(x)    (((x)&0x000F)<<0)\r
+#define MCF_QSPI_QWR_ENDQP(x)    (((x)&0x000F)<<8)\r
+#define MCF_QSPI_QWR_CSIV        (0x1000)\r
+#define MCF_QSPI_QWR_WRTO        (0x2000)\r
+#define MCF_QSPI_QWR_WREN        (0x4000)\r
+#define MCF_QSPI_QWR_HALT        (0x8000)\r
+\r
+/* Bit definitions and macros for MCF_QSPI_QIR */\r
+#define MCF_QSPI_QIR_SPIF        (0x0001)\r
+#define MCF_QSPI_QIR_ABRT        (0x0004)\r
+#define MCF_QSPI_QIR_WCEF        (0x0008)\r
+#define MCF_QSPI_QIR_SPIFE       (0x0100)\r
+#define MCF_QSPI_QIR_ABRTE       (0x0400)\r
+#define MCF_QSPI_QIR_WCEFE       (0x0800)\r
+#define MCF_QSPI_QIR_ABRTL       (0x1000)\r
+#define MCF_QSPI_QIR_ABRTB       (0x4000)\r
+#define MCF_QSPI_QIR_WCEFB       (0x8000)\r
+\r
+/* Bit definitions and macros for MCF_QSPI_QAR */\r
+#define MCF_QSPI_QAR_ADDR(x)     (((x)&0x003F)<<0)\r
+\r
+/********************************************************************/\r
+\r
+#endif /* __MCF523X_QSPI_H__ */\r
index 784d0fab0a53bc5db1e5aab3884a3d3d213dff6b..cae92d22b2553ed93a1bd3a2e176c530a7da75f4 100644 (file)
@@ -1,42 +1,42 @@
-/*
- * These files are taken from the MCF523X source code example package
- * which is available on the Freescale website. Freescale explicitly 
- * grants the redistribution and modification of these source files.
- * The complete licensing information is available in the file 
- * LICENSE_FREESCALE.TXT.
- *
- * File:       mcf523x_rcm.h
- * Purpose:    Register and bit definitions for the MCF523X
- *
- * Notes:      
- *     
- */
-
-#ifndef __MCF523X_RCM_H__
-#define __MCF523X_RCM_H__
-
-/*********************************************************************
-*
-* Reset Configuration Module (RCM)
-*
-*********************************************************************/
-
-/* Register read/write macros */
-#define MCF_RCM_RCR    (*(vuint8 *)(void*)(&__IPSBAR[0x110000]))
-#define MCF_RCM_RSR    (*(vuint8 *)(void*)(&__IPSBAR[0x110001]))
-
-/* Bit definitions and macros for MCF_RCM_RCR */
-#define MCF_RCM_RCR_FRCRSTOUT    (0x40)
-#define MCF_RCM_RCR_SOFTRST      (0x80)
-
-/* Bit definitions and macros for MCF_RCM_RSR */
-#define MCF_RCM_RSR_LOL          (0x01)
-#define MCF_RCM_RSR_LOC          (0x02)
-#define MCF_RCM_RSR_EXT          (0x04)
-#define MCF_RCM_RSR_POR          (0x08)
-#define MCF_RCM_RSR_WDR          (0x10)
-#define MCF_RCM_RSR_SOFT         (0x20)
-
-/********************************************************************/
-
-#endif /* __MCF523X_RCM_H__ */
+/*\r
+ * These files are taken from the MCF523X source code example package\r
+ * which is available on the Freescale website. Freescale explicitly \r
+ * grants the redistribution and modification of these source files.\r
+ * The complete licensing information is available in the file \r
+ * LICENSE_FREESCALE.TXT.\r
+ *\r
+ * File:       mcf523x_rcm.h\r
+ * Purpose:    Register and bit definitions for the MCF523X\r
+ *\r
+ * Notes:      \r
+ *     \r
+ */\r
+\r
+#ifndef __MCF523X_RCM_H__\r
+#define __MCF523X_RCM_H__\r
+\r
+/*********************************************************************\r
+*\r
+* Reset Configuration Module (RCM)\r
+*\r
+*********************************************************************/\r
+\r
+/* Register read/write macros */\r
+#define MCF_RCM_RCR    (*(vuint8 *)(void*)(&__IPSBAR[0x110000]))\r
+#define MCF_RCM_RSR    (*(vuint8 *)(void*)(&__IPSBAR[0x110001]))\r
+\r
+/* Bit definitions and macros for MCF_RCM_RCR */\r
+#define MCF_RCM_RCR_FRCRSTOUT    (0x40)\r
+#define MCF_RCM_RCR_SOFTRST      (0x80)\r
+\r
+/* Bit definitions and macros for MCF_RCM_RSR */\r
+#define MCF_RCM_RSR_LOL          (0x01)\r
+#define MCF_RCM_RSR_LOC          (0x02)\r
+#define MCF_RCM_RSR_EXT          (0x04)\r
+#define MCF_RCM_RSR_POR          (0x08)\r
+#define MCF_RCM_RSR_WDR          (0x10)\r
+#define MCF_RCM_RSR_SOFT         (0x20)\r
+\r
+/********************************************************************/\r
+\r
+#endif /* __MCF523X_RCM_H__ */\r
index 744bd0ae351adf87e2f1e4aee0b6a61963b751e5..4bfca3d6cc20f44c584be8b904951a5a65bae934 100644 (file)
@@ -1,46 +1,46 @@
-/*
- * These files are taken from the MCF523X source code example package
- * which is available on the Freescale website. Freescale explicitly 
- * grants the redistribution and modification of these source files.
- * The complete licensing information is available in the file 
- * LICENSE_FREESCALE.TXT.
- *
- * File:       mcf523x_rng.h
- * Purpose:    Register and bit definitions for the MCF523X
- *
- * Notes:      
- *     
- */
-
-#ifndef __MCF523X_RNG_H__
-#define __MCF523X_RNG_H__
-
-/*********************************************************************
-*
-* Random Number Generator (RNG)
-*
-*********************************************************************/
-
-/* Register read/write macros */
-#define MCF_RNG_RNGCR     (*(vuint32*)(void*)(&__IPSBAR[0x1A0000]))
-#define MCF_RNG_RNGSR     (*(vuint32*)(void*)(&__IPSBAR[0x1A0004]))
-#define MCF_RNG_RNGER     (*(vuint32*)(void*)(&__IPSBAR[0x1A0008]))
-#define MCF_RNG_RNGOUT    (*(vuint32*)(void*)(&__IPSBAR[0x1A000C]))
-
-/* Bit definitions and macros for MCF_RNG_RNGCR */
-#define MCF_RNG_RNGCR_GO        (0x00000001)
-#define MCF_RNG_RNGCR_HA        (0x00000002)
-#define MCF_RNG_RNGCR_IM        (0x00000004)
-#define MCF_RNG_RNGCR_CI        (0x00000008)
-
-/* Bit definitions and macros for MCF_RNG_RNGSR */
-#define MCF_RNG_RNGSR_SV        (0x00000001)
-#define MCF_RNG_RNGSR_LRS       (0x00000002)
-#define MCF_RNG_RNGSR_FUF       (0x00000004)
-#define MCF_RNG_RNGSR_EI        (0x00000008)
-#define MCF_RNG_RNGSR_OFL(x)    (((x)&0x000000FF)<<8)
-#define MCF_RNG_RNGSR_OFS(x)    (((x)&0x000000FF)<<16)
-
-/********************************************************************/
-
-#endif /* __MCF523X_RNG_H__ */
+/*\r
+ * These files are taken from the MCF523X source code example package\r
+ * which is available on the Freescale website. Freescale explicitly \r
+ * grants the redistribution and modification of these source files.\r
+ * The complete licensing information is available in the file \r
+ * LICENSE_FREESCALE.TXT.\r
+ *\r
+ * File:       mcf523x_rng.h\r
+ * Purpose:    Register and bit definitions for the MCF523X\r
+ *\r
+ * Notes:      \r
+ *     \r
+ */\r
+\r
+#ifndef __MCF523X_RNG_H__\r
+#define __MCF523X_RNG_H__\r
+\r
+/*********************************************************************\r
+*\r
+* Random Number Generator (RNG)\r
+*\r
+*********************************************************************/\r
+\r
+/* Register read/write macros */\r
+#define MCF_RNG_RNGCR     (*(vuint32*)(void*)(&__IPSBAR[0x1A0000]))\r
+#define MCF_RNG_RNGSR     (*(vuint32*)(void*)(&__IPSBAR[0x1A0004]))\r
+#define MCF_RNG_RNGER     (*(vuint32*)(void*)(&__IPSBAR[0x1A0008]))\r
+#define MCF_RNG_RNGOUT    (*(vuint32*)(void*)(&__IPSBAR[0x1A000C]))\r
+\r
+/* Bit definitions and macros for MCF_RNG_RNGCR */\r
+#define MCF_RNG_RNGCR_GO        (0x00000001)\r
+#define MCF_RNG_RNGCR_HA        (0x00000002)\r
+#define MCF_RNG_RNGCR_IM        (0x00000004)\r
+#define MCF_RNG_RNGCR_CI        (0x00000008)\r
+\r
+/* Bit definitions and macros for MCF_RNG_RNGSR */\r
+#define MCF_RNG_RNGSR_SV        (0x00000001)\r
+#define MCF_RNG_RNGSR_LRS       (0x00000002)\r
+#define MCF_RNG_RNGSR_FUF       (0x00000004)\r
+#define MCF_RNG_RNGSR_EI        (0x00000008)\r
+#define MCF_RNG_RNGSR_OFL(x)    (((x)&0x000000FF)<<8)\r
+#define MCF_RNG_RNGSR_OFS(x)    (((x)&0x000000FF)<<16)\r
+\r
+/********************************************************************/\r
+\r
+#endif /* __MCF523X_RNG_H__ */\r
index d9ef0f0eb4f518b71a287786434bf722519686d2..e330ee990f3b7b37afda14069a4e0573335d6a78 100644 (file)
-/*
- * These files are taken from the MCF523X source code example package
- * which is available on the Freescale website. Freescale explicitly 
- * grants the redistribution and modification of these source files.
- * The complete licensing information is available in the file 
- * LICENSE_FREESCALE.TXT.
- *
- * File:       mcf523x_scm.h
- * Purpose:    Register and bit definitions for the MCF523X
- *
- * Notes:      
- *     
- */
-
-#ifndef __MCF523X_SCM_H__
-#define __MCF523X_SCM_H__
-
-/*********************************************************************
-*
-* System Control Module (SCM)
-*
-*********************************************************************/
-
-/* Register read/write macros */
-#define MCF_SCM_IPSBAR     (*(vuint32*)(void*)(&__IPSBAR[0x000000]))
-#define MCF_SCM_RAMBAR     (*(vuint32*)(void*)(&__IPSBAR[0x000008]))
-#define MCF_SCM_CRSR       (*(vuint8 *)(void*)(&__IPSBAR[0x000010]))
-#define MCF_SCM_CWCR       (*(vuint8 *)(void*)(&__IPSBAR[0x000011]))
-#define MCF_SCM_LPICR      (*(vuint8 *)(void*)(&__IPSBAR[0x000012]))
-#define MCF_SCM_CWSR       (*(vuint8 *)(void*)(&__IPSBAR[0x000013]))
-#define MCF_SCM_DMAREQC    (*(vuint32*)(void*)(&__IPSBAR[0x000014]))
-#define MCF_SCM_MPARK      (*(vuint32*)(void*)(&__IPSBAR[0x00001C]))
-#define MCF_SCM_MPR        (*(vuint8 *)(void*)(&__IPSBAR[0x000020]))
-#define MCF_SCM_PACR0      (*(vuint8 *)(void*)(&__IPSBAR[0x000024]))
-#define MCF_SCM_PACR1      (*(vuint8 *)(void*)(&__IPSBAR[0x000025]))
-#define MCF_SCM_PACR2      (*(vuint8 *)(void*)(&__IPSBAR[0x000026]))
-#define MCF_SCM_PACR3      (*(vuint8 *)(void*)(&__IPSBAR[0x000027]))
-#define MCF_SCM_PACR4      (*(vuint8 *)(void*)(&__IPSBAR[0x000028]))
-#define MCF_SCM_PACR5      (*(vuint8 *)(void*)(&__IPSBAR[0x00002A]))
-#define MCF_SCM_PACR6      (*(vuint8 *)(void*)(&__IPSBAR[0x00002B]))
-#define MCF_SCM_PACR7      (*(vuint8 *)(void*)(&__IPSBAR[0x00002C]))
-#define MCF_SCM_PACR8      (*(vuint8 *)(void*)(&__IPSBAR[0x00002E]))
-#define MCF_SCM_GPACR0     (*(vuint8 *)(void*)(&__IPSBAR[0x000030]))
-
-/* Bit definitions and macros for MCF_SCM_IPSBAR */
-#define MCF_SCM_IPSBAR_V                 (0x00000001)
-#define MCF_SCM_IPSBAR_BA(x)             (((x)&0x00000003)<<30)
-
-/* Bit definitions and macros for MCF_SCM_RAMBAR */
-#define MCF_SCM_RAMBAR_BDE               (0x00000200)
-#define MCF_SCM_RAMBAR_BA(x)             (((x)&0x0000FFFF)<<16)
-
-/* Bit definitions and macros for MCF_SCM_CRSR */
-#define MCF_SCM_CRSR_CWDR                (0x20)
-#define MCF_SCM_CRSR_EXT                 (0x80)
-
-/* Bit definitions and macros for MCF_SCM_CWCR */
-#define MCF_SCM_CWCR_CWTIC               (0x01)
-#define MCF_SCM_CWCR_CWTAVAL             (0x02)
-#define MCF_SCM_CWCR_CWTA                (0x04)
-#define MCF_SCM_CWCR_CWT(x)              (((x)&0x07)<<3)
-#define MCF_SCM_CWCR_CWRI                (0x40)
-#define MCF_SCM_CWCR_CWE                 (0x80)
-
-/* Bit definitions and macros for MCF_SCM_LPICR */
-#define MCF_SCM_LPICR_XLPM_IPL(x)        (((x)&0x07)<<4)
-#define MCF_SCM_LPICR_ENBSTOP            (0x80)
-
-/* Bit definitions and macros for MCF_SCM_DMAREQC */
-#define MCF_SCM_DMAREQC_DMAC0(x)         (((x)&0x0000000F)<<0)
-#define MCF_SCM_DMAREQC_DMAC1(x)         (((x)&0x0000000F)<<4)
-#define MCF_SCM_DMAREQC_DMAC2(x)         (((x)&0x0000000F)<<8)
-#define MCF_SCM_DMAREQC_DMAC3(x)         (((x)&0x0000000F)<<12)
-
-/* Bit definitions and macros for MCF_SCM_MPARK */
-#define MCF_SCM_MPARK_LCKOUT_TIME(x)     (((x)&0x0000000F)<<8)
-#define MCF_SCM_MPARK_PRKLAST            (0x00001000)
-#define MCF_SCM_MPARK_TIMEOUT            (0x00002000)
-#define MCF_SCM_MPARK_FIXED              (0x00004000)
-#define MCF_SCM_MPARK_M1_PRTY(x)         (((x)&0x00000003)<<16)
-#define MCF_SCM_MPARK_M0_PRTY(x)         (((x)&0x00000003)<<18)
-#define MCF_SCM_MPARK_M2_PRTY(x)         (((x)&0x00000003)<<20)
-#define MCF_SCM_MPARK_M3_PRTY(x)         (((x)&0x00000003)<<22)
-#define MCF_SCM_MPARK_BCR24BIT           (0x01000000)
-#define MCF_SCM_MPARK_M2_P_EN            (0x02000000)
-
-/* Bit definitions and macros for MCF_SCM_MPR */
-#define MCF_SCM_MPR_MPR(x)               (((x)&0x0F)<<0)
-
-/* Bit definitions and macros for MCF_SCM_PACR0 */
-#define MCF_SCM_PACR0_ACCESS_CTRL0(x)    (((x)&0x07)<<0)
-#define MCF_SCM_PACR0_LOCK0              (0x08)
-#define MCF_SCM_PACR0_ACCESS_CTRL1(x)    (((x)&0x07)<<4)
-#define MCF_SCM_PACR0_LOCK1              (0x80)
-
-/* Bit definitions and macros for MCF_SCM_PACR1 */
-#define MCF_SCM_PACR1_ACCESS_CTRL0(x)    (((x)&0x07)<<0)
-#define MCF_SCM_PACR1_LOCK0              (0x08)
-#define MCF_SCM_PACR1_ACCESS_CTRL1(x)    (((x)&0x07)<<4)
-#define MCF_SCM_PACR1_LOCK1              (0x80)
-
-/* Bit definitions and macros for MCF_SCM_PACR2 */
-#define MCF_SCM_PACR2_ACCESS_CTRL0(x)    (((x)&0x07)<<0)
-#define MCF_SCM_PACR2_LOCK0              (0x08)
-#define MCF_SCM_PACR2_ACCESS_CTRL1(x)    (((x)&0x07)<<4)
-#define MCF_SCM_PACR2_LOCK1              (0x80)
-
-/* Bit definitions and macros for MCF_SCM_PACR3 */
-#define MCF_SCM_PACR3_ACCESS_CTRL0(x)    (((x)&0x07)<<0)
-#define MCF_SCM_PACR3_LOCK0              (0x08)
-#define MCF_SCM_PACR3_ACCESS_CTRL1(x)    (((x)&0x07)<<4)
-#define MCF_SCM_PACR3_LOCK1              (0x80)
-
-/* Bit definitions and macros for MCF_SCM_PACR4 */
-#define MCF_SCM_PACR4_ACCESS_CTRL0(x)    (((x)&0x07)<<0)
-#define MCF_SCM_PACR4_LOCK0              (0x08)
-#define MCF_SCM_PACR4_ACCESS_CTRL1(x)    (((x)&0x07)<<4)
-#define MCF_SCM_PACR4_LOCK1              (0x80)
-
-/* Bit definitions and macros for MCF_SCM_PACR5 */
-#define MCF_SCM_PACR5_ACCESS_CTRL0(x)    (((x)&0x07)<<0)
-#define MCF_SCM_PACR5_LOCK0              (0x08)
-#define MCF_SCM_PACR5_ACCESS_CTRL1(x)    (((x)&0x07)<<4)
-#define MCF_SCM_PACR5_LOCK1              (0x80)
-
-/* Bit definitions and macros for MCF_SCM_PACR6 */
-#define MCF_SCM_PACR6_ACCESS_CTRL0(x)    (((x)&0x07)<<0)
-#define MCF_SCM_PACR6_LOCK0              (0x08)
-#define MCF_SCM_PACR6_ACCESS_CTRL1(x)    (((x)&0x07)<<4)
-#define MCF_SCM_PACR6_LOCK1              (0x80)
-
-/* Bit definitions and macros for MCF_SCM_PACR7 */
-#define MCF_SCM_PACR7_ACCESS_CTRL0(x)    (((x)&0x07)<<0)
-#define MCF_SCM_PACR7_LOCK0              (0x08)
-#define MCF_SCM_PACR7_ACCESS_CTRL1(x)    (((x)&0x07)<<4)
-#define MCF_SCM_PACR7_LOCK1              (0x80)
-
-/* Bit definitions and macros for MCF_SCM_PACR8 */
-#define MCF_SCM_PACR8_ACCESS_CTRL0(x)    (((x)&0x07)<<0)
-#define MCF_SCM_PACR8_LOCK0              (0x08)
-#define MCF_SCM_PACR8_ACCESS_CTRL1(x)    (((x)&0x07)<<4)
-#define MCF_SCM_PACR8_LOCK1              (0x80)
-
-/* Bit definitions and macros for MCF_SCM_GPACR0 */
-#define MCF_SCM_GPACR0_ACCESS_CTRL(x)    (((x)&0x0F)<<0)
-#define MCF_SCM_GPACR0_LOCK              (0x80)
-
-/********************************************************************/
-
-#endif /* __MCF523X_SCM_H__ */
+/*\r
+ * These files are taken from the MCF523X source code example package\r
+ * which is available on the Freescale website. Freescale explicitly \r
+ * grants the redistribution and modification of these source files.\r
+ * The complete licensing information is available in the file \r
+ * LICENSE_FREESCALE.TXT.\r
+ *\r
+ * File:       mcf523x_scm.h\r
+ * Purpose:    Register and bit definitions for the MCF523X\r
+ *\r
+ * Notes:      \r
+ *     \r
+ */\r
+\r
+#ifndef __MCF523X_SCM_H__\r
+#define __MCF523X_SCM_H__\r
+\r
+/*********************************************************************\r
+*\r
+* System Control Module (SCM)\r
+*\r
+*********************************************************************/\r
+\r
+/* Register read/write macros */\r
+#define MCF_SCM_IPSBAR     (*(vuint32*)(void*)(&__IPSBAR[0x000000]))\r
+#define MCF_SCM_RAMBAR     (*(vuint32*)(void*)(&__IPSBAR[0x000008]))\r
+#define MCF_SCM_CRSR       (*(vuint8 *)(void*)(&__IPSBAR[0x000010]))\r
+#define MCF_SCM_CWCR       (*(vuint8 *)(void*)(&__IPSBAR[0x000011]))\r
+#define MCF_SCM_LPICR      (*(vuint8 *)(void*)(&__IPSBAR[0x000012]))\r
+#define MCF_SCM_CWSR       (*(vuint8 *)(void*)(&__IPSBAR[0x000013]))\r
+#define MCF_SCM_DMAREQC    (*(vuint32*)(void*)(&__IPSBAR[0x000014]))\r
+#define MCF_SCM_MPARK      (*(vuint32*)(void*)(&__IPSBAR[0x00001C]))\r
+#define MCF_SCM_MPR        (*(vuint8 *)(void*)(&__IPSBAR[0x000020]))\r
+#define MCF_SCM_PACR0      (*(vuint8 *)(void*)(&__IPSBAR[0x000024]))\r
+#define MCF_SCM_PACR1      (*(vuint8 *)(void*)(&__IPSBAR[0x000025]))\r
+#define MCF_SCM_PACR2      (*(vuint8 *)(void*)(&__IPSBAR[0x000026]))\r
+#define MCF_SCM_PACR3      (*(vuint8 *)(void*)(&__IPSBAR[0x000027]))\r
+#define MCF_SCM_PACR4      (*(vuint8 *)(void*)(&__IPSBAR[0x000028]))\r
+#define MCF_SCM_PACR5      (*(vuint8 *)(void*)(&__IPSBAR[0x00002A]))\r
+#define MCF_SCM_PACR6      (*(vuint8 *)(void*)(&__IPSBAR[0x00002B]))\r
+#define MCF_SCM_PACR7      (*(vuint8 *)(void*)(&__IPSBAR[0x00002C]))\r
+#define MCF_SCM_PACR8      (*(vuint8 *)(void*)(&__IPSBAR[0x00002E]))\r
+#define MCF_SCM_GPACR0     (*(vuint8 *)(void*)(&__IPSBAR[0x000030]))\r
+\r
+/* Bit definitions and macros for MCF_SCM_IPSBAR */\r
+#define MCF_SCM_IPSBAR_V                 (0x00000001)\r
+#define MCF_SCM_IPSBAR_BA(x)             (((x)&0x00000003)<<30)\r
+\r
+/* Bit definitions and macros for MCF_SCM_RAMBAR */\r
+#define MCF_SCM_RAMBAR_BDE               (0x00000200)\r
+#define MCF_SCM_RAMBAR_BA(x)             (((x)&0x0000FFFF)<<16)\r
+\r
+/* Bit definitions and macros for MCF_SCM_CRSR */\r
+#define MCF_SCM_CRSR_CWDR                (0x20)\r
+#define MCF_SCM_CRSR_EXT                 (0x80)\r
+\r
+/* Bit definitions and macros for MCF_SCM_CWCR */\r
+#define MCF_SCM_CWCR_CWTIC               (0x01)\r
+#define MCF_SCM_CWCR_CWTAVAL             (0x02)\r
+#define MCF_SCM_CWCR_CWTA                (0x04)\r
+#define MCF_SCM_CWCR_CWT(x)              (((x)&0x07)<<3)\r
+#define MCF_SCM_CWCR_CWRI                (0x40)\r
+#define MCF_SCM_CWCR_CWE                 (0x80)\r
+\r
+/* Bit definitions and macros for MCF_SCM_LPICR */\r
+#define MCF_SCM_LPICR_XLPM_IPL(x)        (((x)&0x07)<<4)\r
+#define MCF_SCM_LPICR_ENBSTOP            (0x80)\r
+\r
+/* Bit definitions and macros for MCF_SCM_DMAREQC */\r
+#define MCF_SCM_DMAREQC_DMAC0(x)         (((x)&0x0000000F)<<0)\r
+#define MCF_SCM_DMAREQC_DMAC1(x)         (((x)&0x0000000F)<<4)\r
+#define MCF_SCM_DMAREQC_DMAC2(x)         (((x)&0x0000000F)<<8)\r
+#define MCF_SCM_DMAREQC_DMAC3(x)         (((x)&0x0000000F)<<12)\r
+\r
+/* Bit definitions and macros for MCF_SCM_MPARK */\r
+#define MCF_SCM_MPARK_LCKOUT_TIME(x)     (((x)&0x0000000F)<<8)\r
+#define MCF_SCM_MPARK_PRKLAST            (0x00001000)\r
+#define MCF_SCM_MPARK_TIMEOUT            (0x00002000)\r
+#define MCF_SCM_MPARK_FIXED              (0x00004000)\r
+#define MCF_SCM_MPARK_M1_PRTY(x)         (((x)&0x00000003)<<16)\r
+#define MCF_SCM_MPARK_M0_PRTY(x)         (((x)&0x00000003)<<18)\r
+#define MCF_SCM_MPARK_M2_PRTY(x)         (((x)&0x00000003)<<20)\r
+#define MCF_SCM_MPARK_M3_PRTY(x)         (((x)&0x00000003)<<22)\r
+#define MCF_SCM_MPARK_BCR24BIT           (0x01000000)\r
+#define MCF_SCM_MPARK_M2_P_EN            (0x02000000)\r
+\r
+/* Bit definitions and macros for MCF_SCM_MPR */\r
+#define MCF_SCM_MPR_MPR(x)               (((x)&0x0F)<<0)\r
+\r
+/* Bit definitions and macros for MCF_SCM_PACR0 */\r
+#define MCF_SCM_PACR0_ACCESS_CTRL0(x)    (((x)&0x07)<<0)\r
+#define MCF_SCM_PACR0_LOCK0              (0x08)\r
+#define MCF_SCM_PACR0_ACCESS_CTRL1(x)    (((x)&0x07)<<4)\r
+#define MCF_SCM_PACR0_LOCK1              (0x80)\r
+\r
+/* Bit definitions and macros for MCF_SCM_PACR1 */\r
+#define MCF_SCM_PACR1_ACCESS_CTRL0(x)    (((x)&0x07)<<0)\r
+#define MCF_SCM_PACR1_LOCK0              (0x08)\r
+#define MCF_SCM_PACR1_ACCESS_CTRL1(x)    (((x)&0x07)<<4)\r
+#define MCF_SCM_PACR1_LOCK1              (0x80)\r
+\r
+/* Bit definitions and macros for MCF_SCM_PACR2 */\r
+#define MCF_SCM_PACR2_ACCESS_CTRL0(x)    (((x)&0x07)<<0)\r
+#define MCF_SCM_PACR2_LOCK0              (0x08)\r
+#define MCF_SCM_PACR2_ACCESS_CTRL1(x)    (((x)&0x07)<<4)\r
+#define MCF_SCM_PACR2_LOCK1              (0x80)\r
+\r
+/* Bit definitions and macros for MCF_SCM_PACR3 */\r
+#define MCF_SCM_PACR3_ACCESS_CTRL0(x)    (((x)&0x07)<<0)\r
+#define MCF_SCM_PACR3_LOCK0              (0x08)\r
+#define MCF_SCM_PACR3_ACCESS_CTRL1(x)    (((x)&0x07)<<4)\r
+#define MCF_SCM_PACR3_LOCK1              (0x80)\r
+\r
+/* Bit definitions and macros for MCF_SCM_PACR4 */\r
+#define MCF_SCM_PACR4_ACCESS_CTRL0(x)    (((x)&0x07)<<0)\r
+#define MCF_SCM_PACR4_LOCK0              (0x08)\r
+#define MCF_SCM_PACR4_ACCESS_CTRL1(x)    (((x)&0x07)<<4)\r
+#define MCF_SCM_PACR4_LOCK1              (0x80)\r
+\r
+/* Bit definitions and macros for MCF_SCM_PACR5 */\r
+#define MCF_SCM_PACR5_ACCESS_CTRL0(x)    (((x)&0x07)<<0)\r
+#define MCF_SCM_PACR5_LOCK0              (0x08)\r
+#define MCF_SCM_PACR5_ACCESS_CTRL1(x)    (((x)&0x07)<<4)\r
+#define MCF_SCM_PACR5_LOCK1              (0x80)\r
+\r
+/* Bit definitions and macros for MCF_SCM_PACR6 */\r
+#define MCF_SCM_PACR6_ACCESS_CTRL0(x)    (((x)&0x07)<<0)\r
+#define MCF_SCM_PACR6_LOCK0              (0x08)\r
+#define MCF_SCM_PACR6_ACCESS_CTRL1(x)    (((x)&0x07)<<4)\r
+#define MCF_SCM_PACR6_LOCK1              (0x80)\r
+\r
+/* Bit definitions and macros for MCF_SCM_PACR7 */\r
+#define MCF_SCM_PACR7_ACCESS_CTRL0(x)    (((x)&0x07)<<0)\r
+#define MCF_SCM_PACR7_LOCK0              (0x08)\r
+#define MCF_SCM_PACR7_ACCESS_CTRL1(x)    (((x)&0x07)<<4)\r
+#define MCF_SCM_PACR7_LOCK1              (0x80)\r
+\r
+/* Bit definitions and macros for MCF_SCM_PACR8 */\r
+#define MCF_SCM_PACR8_ACCESS_CTRL0(x)    (((x)&0x07)<<0)\r
+#define MCF_SCM_PACR8_LOCK0              (0x08)\r
+#define MCF_SCM_PACR8_ACCESS_CTRL1(x)    (((x)&0x07)<<4)\r
+#define MCF_SCM_PACR8_LOCK1              (0x80)\r
+\r
+/* Bit definitions and macros for MCF_SCM_GPACR0 */\r
+#define MCF_SCM_GPACR0_ACCESS_CTRL(x)    (((x)&0x0F)<<0)\r
+#define MCF_SCM_GPACR0_LOCK              (0x80)\r
+\r
+/********************************************************************/\r
+\r
+#endif /* __MCF523X_SCM_H__ */\r
index dbf38f8b609804bbbeb4d3e4ba183d40f1e35e12..87eb0acef618b335a64483115b404b4e5091e298 100644 (file)
@@ -1,94 +1,94 @@
-/*
- * These files are taken from the MCF523X source code example package
- * which is available on the Freescale website. Freescale explicitly 
- * grants the redistribution and modification of these source files.
- * The complete licensing information is available in the file 
- * LICENSE_FREESCALE.TXT.
- *
- * File:       mcf523x_sdramc.h
- * Purpose:    Register and bit definitions for the MCF523X
- *
- * Notes:      
- *     
- */
-
-#ifndef __MCF523X_SDRAMC_H__
-#define __MCF523X_SDRAMC_H__
-
-/*********************************************************************
-*
-* SDRAM Controller (SDRAMC)
-*
-*********************************************************************/
-
-/* Register read/write macros */
-#define MCF_SDRAMC_DCR      (*(vuint16*)(void*)(&__IPSBAR[0x000040]))
-#define MCF_SDRAMC_DACR0    (*(vuint32*)(void*)(&__IPSBAR[0x000048]))
-#define MCF_SDRAMC_DMR0     (*(vuint32*)(void*)(&__IPSBAR[0x00004C]))
-#define MCF_SDRAMC_DACR1    (*(vuint32*)(void*)(&__IPSBAR[0x000050]))
-#define MCF_SDRAMC_DMR1     (*(vuint32*)(void*)(&__IPSBAR[0x000054]))
-
-/* Bit definitions and macros for MCF_SDRAMC_DCR */
-#define MCF_SDRAMC_DCR_RC(x)        (((x)&0x01FF)<<0)
-#define MCF_SDRAMC_DCR_RTIM(x)      (((x)&0x0003)<<9)
-#define MCF_SDRAMC_DCR_IS           (0x0800)
-#define MCF_SDRAMC_DCR_COC          (0x1000)
-#define MCF_SDRAMC_DCR_NAM          (0x2000)
-
-/* Bit definitions and macros for MCF_SDRAMC_DACR0 */
-#define MCF_SDRAMC_DACR0_IP         (0x00000008)
-#define MCF_SDRAMC_DACR0_PS(x)      (((x)&0x00000003)<<4)
-#define MCF_SDRAMC_DACR0_MRS        (0x00000040)
-#define MCF_SDRAMC_DACR0_CBM(x)     (((x)&0x00000007)<<8)
-#define MCF_SDRAMC_DACR0_CASL(x)    (((x)&0x00000003)<<12)
-#define MCF_SDRAMC_DACR0_RE         (0x00008000)
-#define MCF_SDRAMC_DACR0_BA(x)      (((x)&0x00003FFF)<<18)
-
-/* Bit definitions and macros for MCF_SDRAMC_DMR0 */
-#define MCF_SDRAMC_DMR0_V           (0x00000001)
-#define MCF_SDRAMC_DMR0_WP          (0x00000100)
-#define MCF_SDRAMC_DMR0_BAM(x)      (((x)&0x00003FFF)<<18)
-
-/* Bit definitions and macros for MCF_SDRAMC_DACR1 */
-#define MCF_SDRAMC_DACR1_IP         (0x00000008)
-#define MCF_SDRAMC_DACR1_PS(x)      (((x)&0x00000003)<<4)
-#define MCF_SDRAMC_DACR1_MRS        (0x00000040)
-#define MCF_SDRAMC_DACR1_CBM(x)     (((x)&0x00000007)<<8)
-#define MCF_SDRAMC_DACR1_CASL(x)    (((x)&0x00000003)<<12)
-#define MCF_SDRAMC_DACR1_RE         (0x00008000)
-#define MCF_SDRAMC_DACR1_BA(x)      (((x)&0x00003FFF)<<18)
-
-/* Bit definitions and macros for MCF_SDRAMC_DMR1 */
-#define MCF_SDRAMC_DMR1_V           (0x00000001)
-#define MCF_SDRAMC_DMR1_WP          (0x00000100)
-#define MCF_SDRAMC_DMR1_BAM(x)      (((x)&0x00003FFF)<<18)
-
-/********************************************************************/
-
-#define MCF_SDRAMC_DMR_BAM_4G                  (0xFFFC0000)
-#define MCF_SDRAMC_DMR_BAM_2G                  (0x7FFC0000)
-#define MCF_SDRAMC_DMR_BAM_1G                  (0x3FFC0000)
-#define MCF_SDRAMC_DMR_BAM_1024M               (0x3FFC0000)
-#define MCF_SDRAMC_DMR_BAM_512M                        (0x1FFC0000)
-#define MCF_SDRAMC_DMR_BAM_256M                        (0x0FFC0000)
-#define MCF_SDRAMC_DMR_BAM_128M                        (0x07FC0000)
-#define MCF_SDRAMC_DMR_BAM_64M                 (0x03FC0000)
-#define MCF_SDRAMC_DMR_BAM_32M                 (0x01FC0000)
-#define MCF_SDRAMC_DMR_BAM_16M                 (0x00FC0000)
-#define MCF_SDRAMC_DMR_BAM_8M                  (0x007C0000)
-#define MCF_SDRAMC_DMR_BAM_4M                  (0x003C0000)
-#define MCF_SDRAMC_DMR_BAM_2M                  (0x001C0000)
-#define MCF_SDRAMC_DMR_BAM_1M                  (0x000C0000)
-#define MCF_SDRAMC_DMR_BAM_1024K               (0x000C0000)
-#define MCF_SDRAMC_DMR_BAM_512K                        (0x00040000)
-#define MCF_SDRAMC_DMR_BAM_256K                        (0x00000000)
-#define MCF_SDRAMC_DMR_WP                              (0x00000100)
-#define MCF_SDRAMC_DMR_CI                              (0x00000040)
-#define MCF_SDRAMC_DMR_AM                              (0x00000020)
-#define MCF_SDRAMC_DMR_SC                              (0x00000010)
-#define MCF_SDRAMC_DMR_SD                              (0x00000008)
-#define MCF_SDRAMC_DMR_UC                              (0x00000004)
-#define MCF_SDRAMC_DMR_UD                              (0x00000002)
-#define MCF_SDRAMC_DMR_V                               (0x00000001)
-
-#endif /* __MCF523X_SDRAMC_H__ */
+/*\r
+ * These files are taken from the MCF523X source code example package\r
+ * which is available on the Freescale website. Freescale explicitly \r
+ * grants the redistribution and modification of these source files.\r
+ * The complete licensing information is available in the file \r
+ * LICENSE_FREESCALE.TXT.\r
+ *\r
+ * File:       mcf523x_sdramc.h\r
+ * Purpose:    Register and bit definitions for the MCF523X\r
+ *\r
+ * Notes:      \r
+ *     \r
+ */\r
+\r
+#ifndef __MCF523X_SDRAMC_H__\r
+#define __MCF523X_SDRAMC_H__\r
+\r
+/*********************************************************************\r
+*\r
+* SDRAM Controller (SDRAMC)\r
+*\r
+*********************************************************************/\r
+\r
+/* Register read/write macros */\r
+#define MCF_SDRAMC_DCR      (*(vuint16*)(void*)(&__IPSBAR[0x000040]))\r
+#define MCF_SDRAMC_DACR0    (*(vuint32*)(void*)(&__IPSBAR[0x000048]))\r
+#define MCF_SDRAMC_DMR0     (*(vuint32*)(void*)(&__IPSBAR[0x00004C]))\r
+#define MCF_SDRAMC_DACR1    (*(vuint32*)(void*)(&__IPSBAR[0x000050]))\r
+#define MCF_SDRAMC_DMR1     (*(vuint32*)(void*)(&__IPSBAR[0x000054]))\r
+\r
+/* Bit definitions and macros for MCF_SDRAMC_DCR */\r
+#define MCF_SDRAMC_DCR_RC(x)        (((x)&0x01FF)<<0)\r
+#define MCF_SDRAMC_DCR_RTIM(x)      (((x)&0x0003)<<9)\r
+#define MCF_SDRAMC_DCR_IS           (0x0800)\r
+#define MCF_SDRAMC_DCR_COC          (0x1000)\r
+#define MCF_SDRAMC_DCR_NAM          (0x2000)\r
+\r
+/* Bit definitions and macros for MCF_SDRAMC_DACR0 */\r
+#define MCF_SDRAMC_DACR0_IP         (0x00000008)\r
+#define MCF_SDRAMC_DACR0_PS(x)      (((x)&0x00000003)<<4)\r
+#define MCF_SDRAMC_DACR0_MRS        (0x00000040)\r
+#define MCF_SDRAMC_DACR0_CBM(x)     (((x)&0x00000007)<<8)\r
+#define MCF_SDRAMC_DACR0_CASL(x)    (((x)&0x00000003)<<12)\r
+#define MCF_SDRAMC_DACR0_RE         (0x00008000)\r
+#define MCF_SDRAMC_DACR0_BA(x)      (((x)&0x00003FFF)<<18)\r
+\r
+/* Bit definitions and macros for MCF_SDRAMC_DMR0 */\r
+#define MCF_SDRAMC_DMR0_V           (0x00000001)\r
+#define MCF_SDRAMC_DMR0_WP          (0x00000100)\r
+#define MCF_SDRAMC_DMR0_BAM(x)      (((x)&0x00003FFF)<<18)\r
+\r
+/* Bit definitions and macros for MCF_SDRAMC_DACR1 */\r
+#define MCF_SDRAMC_DACR1_IP         (0x00000008)\r
+#define MCF_SDRAMC_DACR1_PS(x)      (((x)&0x00000003)<<4)\r
+#define MCF_SDRAMC_DACR1_MRS        (0x00000040)\r
+#define MCF_SDRAMC_DACR1_CBM(x)     (((x)&0x00000007)<<8)\r
+#define MCF_SDRAMC_DACR1_CASL(x)    (((x)&0x00000003)<<12)\r
+#define MCF_SDRAMC_DACR1_RE         (0x00008000)\r
+#define MCF_SDRAMC_DACR1_BA(x)      (((x)&0x00003FFF)<<18)\r
+\r
+/* Bit definitions and macros for MCF_SDRAMC_DMR1 */\r
+#define MCF_SDRAMC_DMR1_V           (0x00000001)\r
+#define MCF_SDRAMC_DMR1_WP          (0x00000100)\r
+#define MCF_SDRAMC_DMR1_BAM(x)      (((x)&0x00003FFF)<<18)\r
+\r
+/********************************************************************/\r
+\r
+#define MCF_SDRAMC_DMR_BAM_4G                  (0xFFFC0000)\r
+#define MCF_SDRAMC_DMR_BAM_2G                  (0x7FFC0000)\r
+#define MCF_SDRAMC_DMR_BAM_1G                  (0x3FFC0000)\r
+#define MCF_SDRAMC_DMR_BAM_1024M               (0x3FFC0000)\r
+#define MCF_SDRAMC_DMR_BAM_512M                        (0x1FFC0000)\r
+#define MCF_SDRAMC_DMR_BAM_256M                        (0x0FFC0000)\r
+#define MCF_SDRAMC_DMR_BAM_128M                        (0x07FC0000)\r
+#define MCF_SDRAMC_DMR_BAM_64M                 (0x03FC0000)\r
+#define MCF_SDRAMC_DMR_BAM_32M                 (0x01FC0000)\r
+#define MCF_SDRAMC_DMR_BAM_16M                 (0x00FC0000)\r
+#define MCF_SDRAMC_DMR_BAM_8M                  (0x007C0000)\r
+#define MCF_SDRAMC_DMR_BAM_4M                  (0x003C0000)\r
+#define MCF_SDRAMC_DMR_BAM_2M                  (0x001C0000)\r
+#define MCF_SDRAMC_DMR_BAM_1M                  (0x000C0000)\r
+#define MCF_SDRAMC_DMR_BAM_1024K               (0x000C0000)\r
+#define MCF_SDRAMC_DMR_BAM_512K                        (0x00040000)\r
+#define MCF_SDRAMC_DMR_BAM_256K                        (0x00000000)\r
+#define MCF_SDRAMC_DMR_WP                              (0x00000100)\r
+#define MCF_SDRAMC_DMR_CI                              (0x00000040)\r
+#define MCF_SDRAMC_DMR_AM                              (0x00000020)\r
+#define MCF_SDRAMC_DMR_SC                              (0x00000010)\r
+#define MCF_SDRAMC_DMR_SD                              (0x00000008)\r
+#define MCF_SDRAMC_DMR_UC                              (0x00000004)\r
+#define MCF_SDRAMC_DMR_UD                              (0x00000002)\r
+#define MCF_SDRAMC_DMR_V                               (0x00000001)\r
+\r
+#endif /* __MCF523X_SDRAMC_H__ */\r
index e03d2e05c7b840a67b411fce62c2cb9a058d5807..ae4dc57abb98aa82e01a2bb600b835296d09e618 100644 (file)
-/*
- * These files are taken from the MCF523X source code example package
- * which is available on the Freescale website. Freescale explicitly 
- * grants the redistribution and modification of these source files.
- * The complete licensing information is available in the file 
- * LICENSE_FREESCALE.TXT.
- *
- * File:       mcf523x_skha.h
- * Purpose:    Register and bit definitions for the MCF523X
- *
- * Notes:      
- *     
- */
-
-#ifndef __MCF523X_SKHA_H__
-#define __MCF523X_SKHA_H__
-
-/*********************************************************************
-*
-* Symmetric Key Hardware Accelerator (SKHA)
-*
-*********************************************************************/
-
-/* Register read/write macros */
-#define MCF_SKHA_SKMR         (*(vuint32*)(void*)(&__IPSBAR[0x1B0000]))
-#define MCF_SKHA_SKCR         (*(vuint32*)(void*)(&__IPSBAR[0x1B0004]))
-#define MCF_SKHA_SKCMR        (*(vuint32*)(void*)(&__IPSBAR[0x1B0008]))
-#define MCF_SKHA_SKSR         (*(vuint32*)(void*)(&__IPSBAR[0x1B000C]))
-#define MCF_SKHA_SKIR         (*(vuint32*)(void*)(&__IPSBAR[0x1B0010]))
-#define MCF_SKHA_SKIMR        (*(vuint32*)(void*)(&__IPSBAR[0x1B0014]))
-#define MCF_SKHA_SKKSR        (*(vuint32*)(void*)(&__IPSBAR[0x1B0018]))
-#define MCF_SKHA_SKDSR        (*(vuint32*)(void*)(&__IPSBAR[0x1B001C]))
-#define MCF_SKHA_SKIN         (*(vuint32*)(void*)(&__IPSBAR[0x1B0020]))
-#define MCF_SKHA_SKOUT        (*(vuint32*)(void*)(&__IPSBAR[0x1B0024]))
-#define MCF_SKHA_SKKDR0       (*(vuint32*)(void*)(&__IPSBAR[0x1B0030]))
-#define MCF_SKHA_SKKDR1       (*(vuint32*)(void*)(&__IPSBAR[0x1B0034]))
-#define MCF_SKHA_SKKDR2       (*(vuint32*)(void*)(&__IPSBAR[0x1B0038]))
-#define MCF_SKHA_SKKDR3       (*(vuint32*)(void*)(&__IPSBAR[0x1B003C]))
-#define MCF_SKHA_SKKDR4       (*(vuint32*)(void*)(&__IPSBAR[0x1B0040]))
-#define MCF_SKHA_SKKDR5       (*(vuint32*)(void*)(&__IPSBAR[0x1B0044]))
-#define MCF_SKHA_SKKDRn(x)    (*(vuint32*)(void*)(&__IPSBAR[0x1B0030+((x)*0x004)]))
-#define MCF_SKHA_SKCR0        (*(vuint32*)(void*)(&__IPSBAR[0x1B0070]))
-#define MCF_SKHA_SKCR1        (*(vuint32*)(void*)(&__IPSBAR[0x1B0074]))
-#define MCF_SKHA_SKCR2        (*(vuint32*)(void*)(&__IPSBAR[0x1B0078]))
-#define MCF_SKHA_SKCR3        (*(vuint32*)(void*)(&__IPSBAR[0x1B007C]))
-#define MCF_SKHA_SKCR4        (*(vuint32*)(void*)(&__IPSBAR[0x1B0080]))
-#define MCF_SKHA_SKCR5        (*(vuint32*)(void*)(&__IPSBAR[0x1B0084]))
-#define MCF_SKHA_SKCR6        (*(vuint32*)(void*)(&__IPSBAR[0x1B0088]))
-#define MCF_SKHA_SKCR7        (*(vuint32*)(void*)(&__IPSBAR[0x1B008C]))
-#define MCF_SKHA_SKCR8        (*(vuint32*)(void*)(&__IPSBAR[0x1B0090]))
-#define MCF_SKHA_SKCR9        (*(vuint32*)(void*)(&__IPSBAR[0x1B0094]))
-#define MCF_SKHA_SKCR10       (*(vuint32*)(void*)(&__IPSBAR[0x1B0098]))
-#define MCF_SKHA_SKCR11       (*(vuint32*)(void*)(&__IPSBAR[0x1B009C]))
-#define MCF_SKHA_SKCRn(x)     (*(vuint32*)(void*)(&__IPSBAR[0x1B0070+((x)*0x004)]))
-
-/* Bit definitions and macros for MCF_SKHA_SKMR */
-#define MCF_SKHA_SKMR_ALG(x)         (((x)&0x00000003)<<0)
-#define MCF_SKHA_SKMR_DIR            (0x00000004)
-#define MCF_SKHA_SKMR_CM(x)          (((x)&0x00000003)<<3)
-#define MCF_SKHA_SKMR_DKP            (0x00000100)
-#define MCF_SKHA_SKMR_CTRM(x)        (((x)&0x0000000F)<<9)
-#define MCF_SKHA_SKMR_CM_ECB         (0x00000000)
-#define MCF_SKHA_SKMR_CM_CBC         (0x00000008)
-#define MCF_SKHA_SKMR_CM_CTR         (0x00000018)
-#define MCF_SKHA_SKMR_DIR_DEC        (0x00000000)
-#define MCF_SKHA_SKMR_DIR_ENC        (0x00000004)
-#define MCF_SKHA_SKMR_ALG_AES        (0x00000000)
-#define MCF_SKHA_SKMR_ALG_DES        (0x00000001)
-#define MCF_SKHA_SKMR_ALG_TDES       (0x00000002)
-
-/* Bit definitions and macros for MCF_SKHA_SKCR */
-#define MCF_SKHA_SKCR_IE             (0x00000001)
-
-/* Bit definitions and macros for MCF_SKHA_SKCMR */
-#define MCF_SKHA_SKCMR_SWR           (0x00000001)
-#define MCF_SKHA_SKCMR_RI            (0x00000002)
-#define MCF_SKHA_SKCMR_CI            (0x00000004)
-#define MCF_SKHA_SKCMR_GO            (0x00000008)
-
-/* Bit definitions and macros for MCF_SKHA_SKSR */
-#define MCF_SKHA_SKSR_INT            (0x00000001)
-#define MCF_SKHA_SKSR_DONE           (0x00000002)
-#define MCF_SKHA_SKSR_ERR            (0x00000004)
-#define MCF_SKHA_SKSR_RD             (0x00000008)
-#define MCF_SKHA_SKSR_BUSY           (0x00000010)
-#define MCF_SKHA_SKSR_IFL(x)         (((x)&0x000000FF)<<16)
-#define MCF_SKHA_SKSR_OFL(x)         (((x)&0x000000FF)<<24)
-
-/* Bit definitions and macros for MCF_SKHA_SKIR */
-#define MCF_SKHA_SKIR_IFO            (0x00000001)
-#define MCF_SKHA_SKIR_OFU            (0x00000002)
-#define MCF_SKHA_SKIR_NEIF           (0x00000004)
-#define MCF_SKHA_SKIR_NEOF           (0x00000008)
-#define MCF_SKHA_SKIR_IME            (0x00000010)
-#define MCF_SKHA_SKIR_DSE            (0x00000020)
-#define MCF_SKHA_SKIR_KSE            (0x00000040)
-#define MCF_SKHA_SKIR_RMDP           (0x00000080)
-#define MCF_SKHA_SKIR_ERE            (0x00000100)
-#define MCF_SKHA_SKIR_KPE            (0x00000200)
-#define MCF_SKHA_SKIR_KRE            (0x00000400)
-
-/* Bit definitions and macros for MCF_SKHA_SKIMR */
-#define MCF_SKHA_SKIMR_IFO           (0x00000001)
-#define MCF_SKHA_SKIMR_OFU           (0x00000002)
-#define MCF_SKHA_SKIMR_NEIF          (0x00000004)
-#define MCF_SKHA_SKIMR_NEOF          (0x00000008)
-#define MCF_SKHA_SKIMR_IME           (0x00000010)
-#define MCF_SKHA_SKIMR_DSE           (0x00000020)
-#define MCF_SKHA_SKIMR_KSE           (0x00000040)
-#define MCF_SKHA_SKIMR_RMDP          (0x00000080)
-#define MCF_SKHA_SKIMR_ERE           (0x00000100)
-#define MCF_SKHA_SKIMR_KPE           (0x00000200)
-#define MCF_SKHA_SKIMR_KRE           (0x00000400)
-
-/* Bit definitions and macros for MCF_SKHA_SKKSR */
-#define MCF_SKHA_SKKSR_KEYSIZE(x)    (((x)&0x0000003F)<<0)
-
-/********************************************************************/
-
-#endif /* __MCF523X_SKHA_H__ */
+/*\r
+ * These files are taken from the MCF523X source code example package\r
+ * which is available on the Freescale website. Freescale explicitly \r
+ * grants the redistribution and modification of these source files.\r
+ * The complete licensing information is available in the file \r
+ * LICENSE_FREESCALE.TXT.\r
+ *\r
+ * File:       mcf523x_skha.h\r
+ * Purpose:    Register and bit definitions for the MCF523X\r
+ *\r
+ * Notes:      \r
+ *     \r
+ */\r
+\r
+#ifndef __MCF523X_SKHA_H__\r
+#define __MCF523X_SKHA_H__\r
+\r
+/*********************************************************************\r
+*\r
+* Symmetric Key Hardware Accelerator (SKHA)\r
+*\r
+*********************************************************************/\r
+\r
+/* Register read/write macros */\r
+#define MCF_SKHA_SKMR         (*(vuint32*)(void*)(&__IPSBAR[0x1B0000]))\r
+#define MCF_SKHA_SKCR         (*(vuint32*)(void*)(&__IPSBAR[0x1B0004]))\r
+#define MCF_SKHA_SKCMR        (*(vuint32*)(void*)(&__IPSBAR[0x1B0008]))\r
+#define MCF_SKHA_SKSR         (*(vuint32*)(void*)(&__IPSBAR[0x1B000C]))\r
+#define MCF_SKHA_SKIR         (*(vuint32*)(void*)(&__IPSBAR[0x1B0010]))\r
+#define MCF_SKHA_SKIMR        (*(vuint32*)(void*)(&__IPSBAR[0x1B0014]))\r
+#define MCF_SKHA_SKKSR        (*(vuint32*)(void*)(&__IPSBAR[0x1B0018]))\r
+#define MCF_SKHA_SKDSR        (*(vuint32*)(void*)(&__IPSBAR[0x1B001C]))\r
+#define MCF_SKHA_SKIN         (*(vuint32*)(void*)(&__IPSBAR[0x1B0020]))\r
+#define MCF_SKHA_SKOUT        (*(vuint32*)(void*)(&__IPSBAR[0x1B0024]))\r
+#define MCF_SKHA_SKKDR0       (*(vuint32*)(void*)(&__IPSBAR[0x1B0030]))\r
+#define MCF_SKHA_SKKDR1       (*(vuint32*)(void*)(&__IPSBAR[0x1B0034]))\r
+#define MCF_SKHA_SKKDR2       (*(vuint32*)(void*)(&__IPSBAR[0x1B0038]))\r
+#define MCF_SKHA_SKKDR3       (*(vuint32*)(void*)(&__IPSBAR[0x1B003C]))\r
+#define MCF_SKHA_SKKDR4       (*(vuint32*)(void*)(&__IPSBAR[0x1B0040]))\r
+#define MCF_SKHA_SKKDR5       (*(vuint32*)(void*)(&__IPSBAR[0x1B0044]))\r
+#define MCF_SKHA_SKKDRn(x)    (*(vuint32*)(void*)(&__IPSBAR[0x1B0030+((x)*0x004)]))\r
+#define MCF_SKHA_SKCR0        (*(vuint32*)(void*)(&__IPSBAR[0x1B0070]))\r
+#define MCF_SKHA_SKCR1        (*(vuint32*)(void*)(&__IPSBAR[0x1B0074]))\r
+#define MCF_SKHA_SKCR2        (*(vuint32*)(void*)(&__IPSBAR[0x1B0078]))\r
+#define MCF_SKHA_SKCR3        (*(vuint32*)(void*)(&__IPSBAR[0x1B007C]))\r
+#define MCF_SKHA_SKCR4        (*(vuint32*)(void*)(&__IPSBAR[0x1B0080]))\r
+#define MCF_SKHA_SKCR5        (*(vuint32*)(void*)(&__IPSBAR[0x1B0084]))\r
+#define MCF_SKHA_SKCR6        (*(vuint32*)(void*)(&__IPSBAR[0x1B0088]))\r
+#define MCF_SKHA_SKCR7        (*(vuint32*)(void*)(&__IPSBAR[0x1B008C]))\r
+#define MCF_SKHA_SKCR8        (*(vuint32*)(void*)(&__IPSBAR[0x1B0090]))\r
+#define MCF_SKHA_SKCR9        (*(vuint32*)(void*)(&__IPSBAR[0x1B0094]))\r
+#define MCF_SKHA_SKCR10       (*(vuint32*)(void*)(&__IPSBAR[0x1B0098]))\r
+#define MCF_SKHA_SKCR11       (*(vuint32*)(void*)(&__IPSBAR[0x1B009C]))\r
+#define MCF_SKHA_SKCRn(x)     (*(vuint32*)(void*)(&__IPSBAR[0x1B0070+((x)*0x004)]))\r
+\r
+/* Bit definitions and macros for MCF_SKHA_SKMR */\r
+#define MCF_SKHA_SKMR_ALG(x)         (((x)&0x00000003)<<0)\r
+#define MCF_SKHA_SKMR_DIR            (0x00000004)\r
+#define MCF_SKHA_SKMR_CM(x)          (((x)&0x00000003)<<3)\r
+#define MCF_SKHA_SKMR_DKP            (0x00000100)\r
+#define MCF_SKHA_SKMR_CTRM(x)        (((x)&0x0000000F)<<9)\r
+#define MCF_SKHA_SKMR_CM_ECB         (0x00000000)\r
+#define MCF_SKHA_SKMR_CM_CBC         (0x00000008)\r
+#define MCF_SKHA_SKMR_CM_CTR         (0x00000018)\r
+#define MCF_SKHA_SKMR_DIR_DEC        (0x00000000)\r
+#define MCF_SKHA_SKMR_DIR_ENC        (0x00000004)\r
+#define MCF_SKHA_SKMR_ALG_AES        (0x00000000)\r
+#define MCF_SKHA_SKMR_ALG_DES        (0x00000001)\r
+#define MCF_SKHA_SKMR_ALG_TDES       (0x00000002)\r
+\r
+/* Bit definitions and macros for MCF_SKHA_SKCR */\r
+#define MCF_SKHA_SKCR_IE             (0x00000001)\r
+\r
+/* Bit definitions and macros for MCF_SKHA_SKCMR */\r
+#define MCF_SKHA_SKCMR_SWR           (0x00000001)\r
+#define MCF_SKHA_SKCMR_RI            (0x00000002)\r
+#define MCF_SKHA_SKCMR_CI            (0x00000004)\r
+#define MCF_SKHA_SKCMR_GO            (0x00000008)\r
+\r
+/* Bit definitions and macros for MCF_SKHA_SKSR */\r
+#define MCF_SKHA_SKSR_INT            (0x00000001)\r
+#define MCF_SKHA_SKSR_DONE           (0x00000002)\r
+#define MCF_SKHA_SKSR_ERR            (0x00000004)\r
+#define MCF_SKHA_SKSR_RD             (0x00000008)\r
+#define MCF_SKHA_SKSR_BUSY           (0x00000010)\r
+#define MCF_SKHA_SKSR_IFL(x)         (((x)&0x000000FF)<<16)\r
+#define MCF_SKHA_SKSR_OFL(x)         (((x)&0x000000FF)<<24)\r
+\r
+/* Bit definitions and macros for MCF_SKHA_SKIR */\r
+#define MCF_SKHA_SKIR_IFO            (0x00000001)\r
+#define MCF_SKHA_SKIR_OFU            (0x00000002)\r
+#define MCF_SKHA_SKIR_NEIF           (0x00000004)\r
+#define MCF_SKHA_SKIR_NEOF           (0x00000008)\r
+#define MCF_SKHA_SKIR_IME            (0x00000010)\r
+#define MCF_SKHA_SKIR_DSE            (0x00000020)\r
+#define MCF_SKHA_SKIR_KSE            (0x00000040)\r
+#define MCF_SKHA_SKIR_RMDP           (0x00000080)\r
+#define MCF_SKHA_SKIR_ERE            (0x00000100)\r
+#define MCF_SKHA_SKIR_KPE            (0x00000200)\r
+#define MCF_SKHA_SKIR_KRE            (0x00000400)\r
+\r
+/* Bit definitions and macros for MCF_SKHA_SKIMR */\r
+#define MCF_SKHA_SKIMR_IFO           (0x00000001)\r
+#define MCF_SKHA_SKIMR_OFU           (0x00000002)\r
+#define MCF_SKHA_SKIMR_NEIF          (0x00000004)\r
+#define MCF_SKHA_SKIMR_NEOF          (0x00000008)\r
+#define MCF_SKHA_SKIMR_IME           (0x00000010)\r
+#define MCF_SKHA_SKIMR_DSE           (0x00000020)\r
+#define MCF_SKHA_SKIMR_KSE           (0x00000040)\r
+#define MCF_SKHA_SKIMR_RMDP          (0x00000080)\r
+#define MCF_SKHA_SKIMR_ERE           (0x00000100)\r
+#define MCF_SKHA_SKIMR_KPE           (0x00000200)\r
+#define MCF_SKHA_SKIMR_KRE           (0x00000400)\r
+\r
+/* Bit definitions and macros for MCF_SKHA_SKKSR */\r
+#define MCF_SKHA_SKKSR_KEYSIZE(x)    (((x)&0x0000003F)<<0)\r
+\r
+/********************************************************************/\r
+\r
+#endif /* __MCF523X_SKHA_H__ */\r
index b40dda0e6a3d3b16b24734da202967d611ce6200..74626c2be45a4514dd49aa769e9112ad1a98ed67 100644 (file)
@@ -1,42 +1,42 @@
-/*
- * These files are taken from the MCF523X source code example package
- * which is available on the Freescale website. Freescale explicitly 
- * grants the redistribution and modification of these source files.
- * The complete licensing information is available in the file 
- * LICENSE_FREESCALE.TXT.
- *
- * File:       mcf523x_sram.h
- * Purpose:    Register and bit definitions for the MCF523X
- *
- * Notes:      
- *     
- */
-
-#ifndef __MCF523X_SRAM_H__
-#define __MCF523X_SRAM_H__
-
-/*********************************************************************
-*
-* 64KByte System SRAM (SRAM)
-*
-*********************************************************************/
-
-/* Register read/write macros */
-#define MCF_SRAM_RAMBAR    (*(vuint32*)(void*)(&__IPSBAR[0x20000000]))
-
-/* Bit definitions and macros for MCF_SRAM_RAMBAR */
-#define MCF_SRAM_RAMBAR_V        (0x00000001)
-#define MCF_SRAM_RAMBAR_UD       (0x00000002)
-#define MCF_SRAM_RAMBAR_UC       (0x00000004)
-#define MCF_SRAM_RAMBAR_SD       (0x00000008)
-#define MCF_SRAM_RAMBAR_SC       (0x00000010)
-#define MCF_SRAM_RAMBAR_CI       (0x00000020)
-#define MCF_SRAM_RAMBAR_WP       (0x00000100)
-#define MCF_SRAM_RAMBAR_SPV      (0x00000200)
-#define MCF_SRAM_RAMBAR_PRI2     (0x00000400)
-#define MCF_SRAM_RAMBAR_PRI1     (0x00000800)
-#define MCF_SRAM_RAMBAR_BA(x)    (((x)&0x0000FFFF)<<16)
-
-/********************************************************************/
-
-#endif /* __MCF523X_SRAM_H__ */
+/*\r
+ * These files are taken from the MCF523X source code example package\r
+ * which is available on the Freescale website. Freescale explicitly \r
+ * grants the redistribution and modification of these source files.\r
+ * The complete licensing information is available in the file \r
+ * LICENSE_FREESCALE.TXT.\r
+ *\r
+ * File:       mcf523x_sram.h\r
+ * Purpose:    Register and bit definitions for the MCF523X\r
+ *\r
+ * Notes:      \r
+ *     \r
+ */\r
+\r
+#ifndef __MCF523X_SRAM_H__\r
+#define __MCF523X_SRAM_H__\r
+\r
+/*********************************************************************\r
+*\r
+* 64KByte System SRAM (SRAM)\r
+*\r
+*********************************************************************/\r
+\r
+/* Register read/write macros */\r
+#define MCF_SRAM_RAMBAR    (*(vuint32*)(void*)(&__IPSBAR[0x20000000]))\r
+\r
+/* Bit definitions and macros for MCF_SRAM_RAMBAR */\r
+#define MCF_SRAM_RAMBAR_V        (0x00000001)\r
+#define MCF_SRAM_RAMBAR_UD       (0x00000002)\r
+#define MCF_SRAM_RAMBAR_UC       (0x00000004)\r
+#define MCF_SRAM_RAMBAR_SD       (0x00000008)\r
+#define MCF_SRAM_RAMBAR_SC       (0x00000010)\r
+#define MCF_SRAM_RAMBAR_CI       (0x00000020)\r
+#define MCF_SRAM_RAMBAR_WP       (0x00000100)\r
+#define MCF_SRAM_RAMBAR_SPV      (0x00000200)\r
+#define MCF_SRAM_RAMBAR_PRI2     (0x00000400)\r
+#define MCF_SRAM_RAMBAR_PRI1     (0x00000800)\r
+#define MCF_SRAM_RAMBAR_BA(x)    (((x)&0x0000FFFF)<<16)\r
+\r
+/********************************************************************/\r
+\r
+#endif /* __MCF523X_SRAM_H__ */\r
index e9db74c27236efe6c6bc71022cf697653242b0c0..359e895f7ac16395455d1a9355220f6ceef57d30 100644 (file)
@@ -1,83 +1,83 @@
-/*
- * These files are taken from the MCF523X source code example package
- * which is available on the Freescale website. Freescale explicitly 
- * grants the redistribution and modification of these source files.
- * The complete licensing information is available in the file 
- * LICENSE_FREESCALE.TXT.
- *
- * File:       mcf523x_timer.h
- * Purpose:    Register and bit definitions for the MCF523X
- *
- * Notes:      
- *     
- */
-
-#ifndef __MCF523X_TIMER_H__
-#define __MCF523X_TIMER_H__
-
-/*********************************************************************
-*
-* DMA Timers (TIMER)
-*
-*********************************************************************/
-
-/* Register read/write macros */
-#define MCF_TIMER_DTMR0       (*(vuint16*)(void*)(&__IPSBAR[0x000400]))
-#define MCF_TIMER_DTXMR0      (*(vuint8 *)(void*)(&__IPSBAR[0x000402]))
-#define MCF_TIMER_DTER0       (*(vuint8 *)(void*)(&__IPSBAR[0x000403]))
-#define MCF_TIMER_DTRR0       (*(vuint32*)(void*)(&__IPSBAR[0x000404]))
-#define MCF_TIMER_DTCR0       (*(vuint32*)(void*)(&__IPSBAR[0x000408]))
-#define MCF_TIMER_DTCN0       (*(vuint32*)(void*)(&__IPSBAR[0x00040C]))
-#define MCF_TIMER_DTMR1       (*(vuint16*)(void*)(&__IPSBAR[0x000440]))
-#define MCF_TIMER_DTXMR1      (*(vuint8 *)(void*)(&__IPSBAR[0x000442]))
-#define MCF_TIMER_DTER1       (*(vuint8 *)(void*)(&__IPSBAR[0x000443]))
-#define MCF_TIMER_DTRR1       (*(vuint32*)(void*)(&__IPSBAR[0x000444]))
-#define MCF_TIMER_DTCR1       (*(vuint32*)(void*)(&__IPSBAR[0x000448]))
-#define MCF_TIMER_DTCN1       (*(vuint32*)(void*)(&__IPSBAR[0x00044C]))
-#define MCF_TIMER_DTMR2       (*(vuint16*)(void*)(&__IPSBAR[0x000480]))
-#define MCF_TIMER_DTXMR2      (*(vuint8 *)(void*)(&__IPSBAR[0x000482]))
-#define MCF_TIMER_DTER2       (*(vuint8 *)(void*)(&__IPSBAR[0x000483]))
-#define MCF_TIMER_DTRR2       (*(vuint32*)(void*)(&__IPSBAR[0x000484]))
-#define MCF_TIMER_DTCR2       (*(vuint32*)(void*)(&__IPSBAR[0x000488]))
-#define MCF_TIMER_DTCN2       (*(vuint32*)(void*)(&__IPSBAR[0x00048C]))
-#define MCF_TIMER_DTMR3       (*(vuint16*)(void*)(&__IPSBAR[0x0004C0]))
-#define MCF_TIMER_DTXMR3      (*(vuint8 *)(void*)(&__IPSBAR[0x0004C2]))
-#define MCF_TIMER_DTER3       (*(vuint8 *)(void*)(&__IPSBAR[0x0004C3]))
-#define MCF_TIMER_DTRR3       (*(vuint32*)(void*)(&__IPSBAR[0x0004C4]))
-#define MCF_TIMER_DTCR3       (*(vuint32*)(void*)(&__IPSBAR[0x0004C8]))
-#define MCF_TIMER_DTCN3       (*(vuint32*)(void*)(&__IPSBAR[0x0004CC]))
-#define MCF_TIMER_DTMR(x)     (*(vuint16*)(void*)(&__IPSBAR[0x000400+((x)*0x040)]))
-#define MCF_TIMER_DTXMR(x)    (*(vuint8 *)(void*)(&__IPSBAR[0x000402+((x)*0x040)]))
-#define MCF_TIMER_DTER(x)     (*(vuint8 *)(void*)(&__IPSBAR[0x000403+((x)*0x040)]))
-#define MCF_TIMER_DTRR(x)     (*(vuint32*)(void*)(&__IPSBAR[0x000404+((x)*0x040)]))
-#define MCF_TIMER_DTCR(x)     (*(vuint32*)(void*)(&__IPSBAR[0x000408+((x)*0x040)]))
-#define MCF_TIMER_DTCN(x)     (*(vuint32*)(void*)(&__IPSBAR[0x00040C+((x)*0x040)]))
-
-/* Bit definitions and macros for MCF_TIMER_DTMR */
-#define MCF_TIMER_DTMR_RST          (0x0001)
-#define MCF_TIMER_DTMR_CLK(x)       (((x)&0x0003)<<1)
-#define MCF_TIMER_DTMR_FRR          (0x0008)
-#define MCF_TIMER_DTMR_ORRI         (0x0010)
-#define MCF_TIMER_DTMR_OM           (0x0020)
-#define MCF_TIMER_DTMR_CE(x)        (((x)&0x0003)<<6)
-#define MCF_TIMER_DTMR_PS(x)        (((x)&0x00FF)<<8)
-#define MCF_TIMER_DTMR_CE_ANY       (0x00C0)
-#define MCF_TIMER_DTMR_CE_FALL      (0x0080)
-#define MCF_TIMER_DTMR_CE_RISE      (0x0040)
-#define MCF_TIMER_DTMR_CE_NONE      (0x0000)
-#define MCF_TIMER_DTMR_CLK_DTIN     (0x0006)
-#define MCF_TIMER_DTMR_CLK_DIV16    (0x0004)
-#define MCF_TIMER_DTMR_CLK_DIV1     (0x0002)
-#define MCF_TIMER_DTMR_CLK_STOP     (0x0000)
-
-/* Bit definitions and macros for MCF_TIMER_DTXMR */
-#define MCF_TIMER_DTXMR_MODE16      (0x01)
-#define MCF_TIMER_DTXMR_DMAEN       (0x80)
-
-/* Bit definitions and macros for MCF_TIMER_DTER */
-#define MCF_TIMER_DTER_CAP          (0x01)
-#define MCF_TIMER_DTER_REF          (0x02)
-
-/********************************************************************/
-
-#endif /* __MCF523X_TIMER_H__ */
+/*\r
+ * These files are taken from the MCF523X source code example package\r
+ * which is available on the Freescale website. Freescale explicitly \r
+ * grants the redistribution and modification of these source files.\r
+ * The complete licensing information is available in the file \r
+ * LICENSE_FREESCALE.TXT.\r
+ *\r
+ * File:       mcf523x_timer.h\r
+ * Purpose:    Register and bit definitions for the MCF523X\r
+ *\r
+ * Notes:      \r
+ *     \r
+ */\r
+\r
+#ifndef __MCF523X_TIMER_H__\r
+#define __MCF523X_TIMER_H__\r
+\r
+/*********************************************************************\r
+*\r
+* DMA Timers (TIMER)\r
+*\r
+*********************************************************************/\r
+\r
+/* Register read/write macros */\r
+#define MCF_TIMER_DTMR0       (*(vuint16*)(void*)(&__IPSBAR[0x000400]))\r
+#define MCF_TIMER_DTXMR0      (*(vuint8 *)(void*)(&__IPSBAR[0x000402]))\r
+#define MCF_TIMER_DTER0       (*(vuint8 *)(void*)(&__IPSBAR[0x000403]))\r
+#define MCF_TIMER_DTRR0       (*(vuint32*)(void*)(&__IPSBAR[0x000404]))\r
+#define MCF_TIMER_DTCR0       (*(vuint32*)(void*)(&__IPSBAR[0x000408]))\r
+#define MCF_TIMER_DTCN0       (*(vuint32*)(void*)(&__IPSBAR[0x00040C]))\r
+#define MCF_TIMER_DTMR1       (*(vuint16*)(void*)(&__IPSBAR[0x000440]))\r
+#define MCF_TIMER_DTXMR1      (*(vuint8 *)(void*)(&__IPSBAR[0x000442]))\r
+#define MCF_TIMER_DTER1       (*(vuint8 *)(void*)(&__IPSBAR[0x000443]))\r
+#define MCF_TIMER_DTRR1       (*(vuint32*)(void*)(&__IPSBAR[0x000444]))\r
+#define MCF_TIMER_DTCR1       (*(vuint32*)(void*)(&__IPSBAR[0x000448]))\r
+#define MCF_TIMER_DTCN1       (*(vuint32*)(void*)(&__IPSBAR[0x00044C]))\r
+#define MCF_TIMER_DTMR2       (*(vuint16*)(void*)(&__IPSBAR[0x000480]))\r
+#define MCF_TIMER_DTXMR2      (*(vuint8 *)(void*)(&__IPSBAR[0x000482]))\r
+#define MCF_TIMER_DTER2       (*(vuint8 *)(void*)(&__IPSBAR[0x000483]))\r
+#define MCF_TIMER_DTRR2       (*(vuint32*)(void*)(&__IPSBAR[0x000484]))\r
+#define MCF_TIMER_DTCR2       (*(vuint32*)(void*)(&__IPSBAR[0x000488]))\r
+#define MCF_TIMER_DTCN2       (*(vuint32*)(void*)(&__IPSBAR[0x00048C]))\r
+#define MCF_TIMER_DTMR3       (*(vuint16*)(void*)(&__IPSBAR[0x0004C0]))\r
+#define MCF_TIMER_DTXMR3      (*(vuint8 *)(void*)(&__IPSBAR[0x0004C2]))\r
+#define MCF_TIMER_DTER3       (*(vuint8 *)(void*)(&__IPSBAR[0x0004C3]))\r
+#define MCF_TIMER_DTRR3       (*(vuint32*)(void*)(&__IPSBAR[0x0004C4]))\r
+#define MCF_TIMER_DTCR3       (*(vuint32*)(void*)(&__IPSBAR[0x0004C8]))\r
+#define MCF_TIMER_DTCN3       (*(vuint32*)(void*)(&__IPSBAR[0x0004CC]))\r
+#define MCF_TIMER_DTMR(x)     (*(vuint16*)(void*)(&__IPSBAR[0x000400+((x)*0x040)]))\r
+#define MCF_TIMER_DTXMR(x)    (*(vuint8 *)(void*)(&__IPSBAR[0x000402+((x)*0x040)]))\r
+#define MCF_TIMER_DTER(x)     (*(vuint8 *)(void*)(&__IPSBAR[0x000403+((x)*0x040)]))\r
+#define MCF_TIMER_DTRR(x)     (*(vuint32*)(void*)(&__IPSBAR[0x000404+((x)*0x040)]))\r
+#define MCF_TIMER_DTCR(x)     (*(vuint32*)(void*)(&__IPSBAR[0x000408+((x)*0x040)]))\r
+#define MCF_TIMER_DTCN(x)     (*(vuint32*)(void*)(&__IPSBAR[0x00040C+((x)*0x040)]))\r
+\r
+/* Bit definitions and macros for MCF_TIMER_DTMR */\r
+#define MCF_TIMER_DTMR_RST          (0x0001)\r
+#define MCF_TIMER_DTMR_CLK(x)       (((x)&0x0003)<<1)\r
+#define MCF_TIMER_DTMR_FRR          (0x0008)\r
+#define MCF_TIMER_DTMR_ORRI         (0x0010)\r
+#define MCF_TIMER_DTMR_OM           (0x0020)\r
+#define MCF_TIMER_DTMR_CE(x)        (((x)&0x0003)<<6)\r
+#define MCF_TIMER_DTMR_PS(x)        (((x)&0x00FF)<<8)\r
+#define MCF_TIMER_DTMR_CE_ANY       (0x00C0)\r
+#define MCF_TIMER_DTMR_CE_FALL      (0x0080)\r
+#define MCF_TIMER_DTMR_CE_RISE      (0x0040)\r
+#define MCF_TIMER_DTMR_CE_NONE      (0x0000)\r
+#define MCF_TIMER_DTMR_CLK_DTIN     (0x0006)\r
+#define MCF_TIMER_DTMR_CLK_DIV16    (0x0004)\r
+#define MCF_TIMER_DTMR_CLK_DIV1     (0x0002)\r
+#define MCF_TIMER_DTMR_CLK_STOP     (0x0000)\r
+\r
+/* Bit definitions and macros for MCF_TIMER_DTXMR */\r
+#define MCF_TIMER_DTXMR_MODE16      (0x01)\r
+#define MCF_TIMER_DTXMR_DMAEN       (0x80)\r
+\r
+/* Bit definitions and macros for MCF_TIMER_DTER */\r
+#define MCF_TIMER_DTER_CAP          (0x01)\r
+#define MCF_TIMER_DTER_REF          (0x02)\r
+\r
+/********************************************************************/\r
+\r
+#endif /* __MCF523X_TIMER_H__ */\r
index 43a44a67fb9bdf303c867e7a32569f6cf7b106bf..f70a71c4e11b6cd3a7043bb581f15de593822737 100644 (file)
-/*
- * These files are taken from the MCF523X source code example package
- * which is available on the Freescale website. Freescale explicitly 
- * grants the redistribution and modification of these source files.
- * The complete licensing information is available in the file 
- * LICENSE_FREESCALE.TXT.
- *
- * File:       mcf523x_uart.h
- * Purpose:    Register and bit definitions for the MCF523X
- *
- * Notes:      
- *     
- */
-
-#ifndef __MCF523X_UART_H__
-#define __MCF523X_UART_H__
-
-/*********************************************************************
-*
-* Universal Asynchronous Receiver Transmitter (UART)
-*
-*********************************************************************/
-
-/* Register read/write macros */
-#define MCF_UART_UMR0        (*(vuint8 *)(void*)(&__IPSBAR[0x000200]))
-#define MCF_UART_USR0        (*(vuint8 *)(void*)(&__IPSBAR[0x000204]))
-#define MCF_UART_UCSR0       (*(vuint8 *)(void*)(&__IPSBAR[0x000204]))
-#define MCF_UART_UCR0        (*(vuint8 *)(void*)(&__IPSBAR[0x000208]))
-#define MCF_UART_URB0        (*(vuint8 *)(void*)(&__IPSBAR[0x00020C]))
-#define MCF_UART_UTB0        (*(vuint8 *)(void*)(&__IPSBAR[0x00020C]))
-#define MCF_UART_UIPCR0      (*(vuint8 *)(void*)(&__IPSBAR[0x000210]))
-#define MCF_UART_UACR0       (*(vuint8 *)(void*)(&__IPSBAR[0x000210]))
-#define MCF_UART_UISR0       (*(vuint8 *)(void*)(&__IPSBAR[0x000214]))
-#define MCF_UART_UIMR0       (*(vuint8 *)(void*)(&__IPSBAR[0x000214]))
-#define MCF_UART_UBG10       (*(vuint8 *)(void*)(&__IPSBAR[0x000218]))
-#define MCF_UART_UBG20       (*(vuint8 *)(void*)(&__IPSBAR[0x00021C]))
-#define MCF_UART_UIP0        (*(vuint8 *)(void*)(&__IPSBAR[0x000234]))
-#define MCF_UART_UOP10       (*(vuint8 *)(void*)(&__IPSBAR[0x000238]))
-#define MCF_UART_UOP00       (*(vuint8 *)(void*)(&__IPSBAR[0x00023C]))
-#define MCF_UART_UMR1        (*(vuint8 *)(void*)(&__IPSBAR[0x000240]))
-#define MCF_UART_USR1        (*(vuint8 *)(void*)(&__IPSBAR[0x000244]))
-#define MCF_UART_UCSR1       (*(vuint8 *)(void*)(&__IPSBAR[0x000244]))
-#define MCF_UART_UCR1        (*(vuint8 *)(void*)(&__IPSBAR[0x000248]))
-#define MCF_UART_URB1        (*(vuint8 *)(void*)(&__IPSBAR[0x00024C]))
-#define MCF_UART_UTB1        (*(vuint8 *)(void*)(&__IPSBAR[0x00024C]))
-#define MCF_UART_UIPCR1      (*(vuint8 *)(void*)(&__IPSBAR[0x000250]))
-#define MCF_UART_UACR1       (*(vuint8 *)(void*)(&__IPSBAR[0x000250]))
-#define MCF_UART_UISR1       (*(vuint8 *)(void*)(&__IPSBAR[0x000254]))
-#define MCF_UART_UIMR1       (*(vuint8 *)(void*)(&__IPSBAR[0x000254]))
-#define MCF_UART_UBG11       (*(vuint8 *)(void*)(&__IPSBAR[0x000258]))
-#define MCF_UART_UBG21       (*(vuint8 *)(void*)(&__IPSBAR[0x00025C]))
-#define MCF_UART_UIP1        (*(vuint8 *)(void*)(&__IPSBAR[0x000274]))
-#define MCF_UART_UOP11       (*(vuint8 *)(void*)(&__IPSBAR[0x000278]))
-#define MCF_UART_UOP01       (*(vuint8 *)(void*)(&__IPSBAR[0x00027C]))
-#define MCF_UART_UMR2        (*(vuint8 *)(void*)(&__IPSBAR[0x000280]))
-#define MCF_UART_USR2        (*(vuint8 *)(void*)(&__IPSBAR[0x000284]))
-#define MCF_UART_UCSR2       (*(vuint8 *)(void*)(&__IPSBAR[0x000284]))
-#define MCF_UART_UCR2        (*(vuint8 *)(void*)(&__IPSBAR[0x000288]))
-#define MCF_UART_URB2        (*(vuint8 *)(void*)(&__IPSBAR[0x00028C]))
-#define MCF_UART_UTB2        (*(vuint8 *)(void*)(&__IPSBAR[0x00028C]))
-#define MCF_UART_UIPCR2      (*(vuint8 *)(void*)(&__IPSBAR[0x000290]))
-#define MCF_UART_UACR2       (*(vuint8 *)(void*)(&__IPSBAR[0x000290]))
-#define MCF_UART_UISR2       (*(vuint8 *)(void*)(&__IPSBAR[0x000294]))
-#define MCF_UART_UIMR2       (*(vuint8 *)(void*)(&__IPSBAR[0x000294]))
-#define MCF_UART_UBG12       (*(vuint8 *)(void*)(&__IPSBAR[0x000298]))
-#define MCF_UART_UBG22       (*(vuint8 *)(void*)(&__IPSBAR[0x00029C]))
-#define MCF_UART_UIP2        (*(vuint8 *)(void*)(&__IPSBAR[0x0002B4]))
-#define MCF_UART_UOP12       (*(vuint8 *)(void*)(&__IPSBAR[0x0002B8]))
-#define MCF_UART_UOP02       (*(vuint8 *)(void*)(&__IPSBAR[0x0002BC]))
-#define MCF_UART_UMR(x)      (*(vuint8 *)(void*)(&__IPSBAR[0x000200+((x)*0x040)]))
-#define MCF_UART_USR(x)      (*(vuint8 *)(void*)(&__IPSBAR[0x000204+((x)*0x040)]))
-#define MCF_UART_UCSR(x)     (*(vuint8 *)(void*)(&__IPSBAR[0x000204+((x)*0x040)]))
-#define MCF_UART_UCR(x)      (*(vuint8 *)(void*)(&__IPSBAR[0x000208+((x)*0x040)]))
-#define MCF_UART_URB(x)      (*(vuint8 *)(void*)(&__IPSBAR[0x00020C+((x)*0x040)]))
-#define MCF_UART_UTB(x)      (*(vuint8 *)(void*)(&__IPSBAR[0x00020C+((x)*0x040)]))
-#define MCF_UART_UIPCR(x)    (*(vuint8 *)(void*)(&__IPSBAR[0x000210+((x)*0x040)]))
-#define MCF_UART_UACR(x)     (*(vuint8 *)(void*)(&__IPSBAR[0x000210+((x)*0x040)]))
-#define MCF_UART_UISR(x)     (*(vuint8 *)(void*)(&__IPSBAR[0x000214+((x)*0x040)]))
-#define MCF_UART_UIMR(x)     (*(vuint8 *)(void*)(&__IPSBAR[0x000214+((x)*0x040)]))
-#define MCF_UART_UBG1(x)     (*(vuint8 *)(void*)(&__IPSBAR[0x000218+((x)*0x040)]))
-#define MCF_UART_UBG2(x)     (*(vuint8 *)(void*)(&__IPSBAR[0x00021C+((x)*0x040)]))
-#define MCF_UART_UIP(x)      (*(vuint8 *)(void*)(&__IPSBAR[0x000234+((x)*0x040)]))
-#define MCF_UART_UOP1(x)     (*(vuint8 *)(void*)(&__IPSBAR[0x000238+((x)*0x040)]))
-#define MCF_UART_UOP0(x)     (*(vuint8 *)(void*)(&__IPSBAR[0x00023C+((x)*0x040)]))
-
-/* Bit definitions and macros for MCF_UART_UMR */
-#define MCF_UART_UMR_BC(x)              (((x)&0x03)<<0)
-#define MCF_UART_UMR_PT                 (0x04)
-#define MCF_UART_UMR_PM(x)              (((x)&0x03)<<3)
-#define MCF_UART_UMR_ERR                (0x20)
-#define MCF_UART_UMR_RXIRQ              (0x40)
-#define MCF_UART_UMR_RXRTS              (0x80)
-#define MCF_UART_UMR_SB(x)              (((x)&0x0F)<<0)
-#define MCF_UART_UMR_TXCTS              (0x10)
-#define MCF_UART_UMR_TXRTS              (0x20)
-#define MCF_UART_UMR_CM(x)              (((x)&0x03)<<6)
-#define MCF_UART_UMR_PM_MULTI_ADDR      (0x1C)
-#define MCF_UART_UMR_PM_MULTI_DATA      (0x18)
-#define MCF_UART_UMR_PM_NONE            (0x10)
-#define MCF_UART_UMR_PM_FORCE_HI        (0x0C)
-#define MCF_UART_UMR_PM_FORCE_LO        (0x08)
-#define MCF_UART_UMR_PM_ODD             (0x04)
-#define MCF_UART_UMR_PM_EVEN            (0x00)
-#define MCF_UART_UMR_BC_5               (0x00)
-#define MCF_UART_UMR_BC_6               (0x01)
-#define MCF_UART_UMR_BC_7               (0x02)
-#define MCF_UART_UMR_BC_8               (0x03)
-#define MCF_UART_UMR_CM_NORMAL          (0x00)
-#define MCF_UART_UMR_CM_ECHO            (0x40)
-#define MCF_UART_UMR_CM_LOCAL_LOOP      (0x80)
-#define MCF_UART_UMR_CM_REMOTE_LOOP     (0xC0)
-#define MCF_UART_UMR_SB_STOP_BITS_1     (0x07)
-#define MCF_UART_UMR_SB_STOP_BITS_15    (0x08)
-#define MCF_UART_UMR_SB_STOP_BITS_2     (0x0F)
-
-/* Bit definitions and macros for MCF_UART_USR */
-#define MCF_UART_USR_RXRDY              (0x01)
-#define MCF_UART_USR_FFULL              (0x02)
-#define MCF_UART_USR_TXRDY              (0x04)
-#define MCF_UART_USR_TXEMP              (0x08)
-#define MCF_UART_USR_OE                 (0x10)
-#define MCF_UART_USR_PE                 (0x20)
-#define MCF_UART_USR_FE                 (0x40)
-#define MCF_UART_USR_RB                 (0x80)
-
-/* Bit definitions and macros for MCF_UART_UCSR */
-#define MCF_UART_UCSR_TCS(x)            (((x)&0x0F)<<0)
-#define MCF_UART_UCSR_RCS(x)            (((x)&0x0F)<<4)
-#define MCF_UART_UCSR_RCS_SYS_CLK       (0xD0)
-#define MCF_UART_UCSR_RCS_CTM16         (0xE0)
-#define MCF_UART_UCSR_RCS_CTM           (0xF0)
-#define MCF_UART_UCSR_TCS_SYS_CLK       (0x0D)
-#define MCF_UART_UCSR_TCS_CTM16         (0x0E)
-#define MCF_UART_UCSR_TCS_CTM           (0x0F)
-
-/* Bit definitions and macros for MCF_UART_UCR */
-#define MCF_UART_UCR_RXC(x)             (((x)&0x03)<<0)
-#define MCF_UART_UCR_TXC(x)             (((x)&0x03)<<2)
-#define MCF_UART_UCR_MISC(x)            (((x)&0x07)<<4)
-#define MCF_UART_UCR_NONE               (0x00)
-#define MCF_UART_UCR_STOP_BREAK         (0x70)
-#define MCF_UART_UCR_START_BREAK        (0x60)
-#define MCF_UART_UCR_BKCHGINT           (0x50)
-#define MCF_UART_UCR_RESET_ERROR        (0x40)
-#define MCF_UART_UCR_RESET_TX           (0x30)
-#define MCF_UART_UCR_RESET_RX           (0x20)
-#define MCF_UART_UCR_RESET_MR           (0x10)
-#define MCF_UART_UCR_TX_DISABLED        (0x08)
-#define MCF_UART_UCR_TX_ENABLED         (0x04)
-#define MCF_UART_UCR_RX_DISABLED        (0x02)
-#define MCF_UART_UCR_RX_ENABLED         (0x01)
-
-/* Bit definitions and macros for MCF_UART_UIPCR */
-#define MCF_UART_UIPCR_CTS              (0x01)
-#define MCF_UART_UIPCR_COS              (0x10)
-
-/* Bit definitions and macros for MCF_UART_UACR */
-#define MCF_UART_UACR_IEC               (0x01)
-
-/* Bit definitions and macros for MCF_UART_UISR */
-#define MCF_UART_UISR_TXRDY             (0x01)
-#define MCF_UART_UISR_RXRDY_FU          (0x02)
-#define MCF_UART_UISR_DB                (0x04)
-#define MCF_UART_UISR_RXFTO             (0x08)
-#define MCF_UART_UISR_TXFIFO            (0x10)
-#define MCF_UART_UISR_RXFIFO            (0x20)
-#define MCF_UART_UISR_COS               (0x80)
-
-/* Bit definitions and macros for MCF_UART_UIMR */
-#define MCF_UART_UIMR_TXRDY             (0x01)
-#define MCF_UART_UIMR_RXRDY_FU          (0x02)
-#define MCF_UART_UIMR_DB                (0x04)
-#define MCF_UART_UIMR_COS               (0x80)
-
-/* Bit definitions and macros for MCF_UART_UIP */
-#define MCF_UART_UIP_CTS                (0x01)
-
-/* Bit definitions and macros for MCF_UART_UOP1 */
-#define MCF_UART_UOP1_RTS               (0x01)
-
-/* Bit definitions and macros for MCF_UART_UOP0 */
-#define MCF_UART_UOP0_RTS               (0x01)
-
-/********************************************************************/
-
-#endif /* __MCF523X_UART_H__ */
+/*\r
+ * These files are taken from the MCF523X source code example package\r
+ * which is available on the Freescale website. Freescale explicitly \r
+ * grants the redistribution and modification of these source files.\r
+ * The complete licensing information is available in the file \r
+ * LICENSE_FREESCALE.TXT.\r
+ *\r
+ * File:       mcf523x_uart.h\r
+ * Purpose:    Register and bit definitions for the MCF523X\r
+ *\r
+ * Notes:      \r
+ *     \r
+ */\r
+\r
+#ifndef __MCF523X_UART_H__\r
+#define __MCF523X_UART_H__\r
+\r
+/*********************************************************************\r
+*\r
+* Universal Asynchronous Receiver Transmitter (UART)\r
+*\r
+*********************************************************************/\r
+\r
+/* Register read/write macros */\r
+#define MCF_UART_UMR0        (*(vuint8 *)(void*)(&__IPSBAR[0x000200]))\r
+#define MCF_UART_USR0        (*(vuint8 *)(void*)(&__IPSBAR[0x000204]))\r
+#define MCF_UART_UCSR0       (*(vuint8 *)(void*)(&__IPSBAR[0x000204]))\r
+#define MCF_UART_UCR0        (*(vuint8 *)(void*)(&__IPSBAR[0x000208]))\r
+#define MCF_UART_URB0        (*(vuint8 *)(void*)(&__IPSBAR[0x00020C]))\r
+#define MCF_UART_UTB0        (*(vuint8 *)(void*)(&__IPSBAR[0x00020C]))\r
+#define MCF_UART_UIPCR0      (*(vuint8 *)(void*)(&__IPSBAR[0x000210]))\r
+#define MCF_UART_UACR0       (*(vuint8 *)(void*)(&__IPSBAR[0x000210]))\r
+#define MCF_UART_UISR0       (*(vuint8 *)(void*)(&__IPSBAR[0x000214]))\r
+#define MCF_UART_UIMR0       (*(vuint8 *)(void*)(&__IPSBAR[0x000214]))\r
+#define MCF_UART_UBG10       (*(vuint8 *)(void*)(&__IPSBAR[0x000218]))\r
+#define MCF_UART_UBG20       (*(vuint8 *)(void*)(&__IPSBAR[0x00021C]))\r
+#define MCF_UART_UIP0        (*(vuint8 *)(void*)(&__IPSBAR[0x000234]))\r
+#define MCF_UART_UOP10       (*(vuint8 *)(void*)(&__IPSBAR[0x000238]))\r
+#define MCF_UART_UOP00       (*(vuint8 *)(void*)(&__IPSBAR[0x00023C]))\r
+#define MCF_UART_UMR1        (*(vuint8 *)(void*)(&__IPSBAR[0x000240]))\r
+#define MCF_UART_USR1        (*(vuint8 *)(void*)(&__IPSBAR[0x000244]))\r
+#define MCF_UART_UCSR1       (*(vuint8 *)(void*)(&__IPSBAR[0x000244]))\r
+#define MCF_UART_UCR1        (*(vuint8 *)(void*)(&__IPSBAR[0x000248]))\r
+#define MCF_UART_URB1        (*(vuint8 *)(void*)(&__IPSBAR[0x00024C]))\r
+#define MCF_UART_UTB1        (*(vuint8 *)(void*)(&__IPSBAR[0x00024C]))\r
+#define MCF_UART_UIPCR1      (*(vuint8 *)(void*)(&__IPSBAR[0x000250]))\r
+#define MCF_UART_UACR1       (*(vuint8 *)(void*)(&__IPSBAR[0x000250]))\r
+#define MCF_UART_UISR1       (*(vuint8 *)(void*)(&__IPSBAR[0x000254]))\r
+#define MCF_UART_UIMR1       (*(vuint8 *)(void*)(&__IPSBAR[0x000254]))\r
+#define MCF_UART_UBG11       (*(vuint8 *)(void*)(&__IPSBAR[0x000258]))\r
+#define MCF_UART_UBG21       (*(vuint8 *)(void*)(&__IPSBAR[0x00025C]))\r
+#define MCF_UART_UIP1        (*(vuint8 *)(void*)(&__IPSBAR[0x000274]))\r
+#define MCF_UART_UOP11       (*(vuint8 *)(void*)(&__IPSBAR[0x000278]))\r
+#define MCF_UART_UOP01       (*(vuint8 *)(void*)(&__IPSBAR[0x00027C]))\r
+#define MCF_UART_UMR2        (*(vuint8 *)(void*)(&__IPSBAR[0x000280]))\r
+#define MCF_UART_USR2        (*(vuint8 *)(void*)(&__IPSBAR[0x000284]))\r
+#define MCF_UART_UCSR2       (*(vuint8 *)(void*)(&__IPSBAR[0x000284]))\r
+#define MCF_UART_UCR2        (*(vuint8 *)(void*)(&__IPSBAR[0x000288]))\r
+#define MCF_UART_URB2        (*(vuint8 *)(void*)(&__IPSBAR[0x00028C]))\r
+#define MCF_UART_UTB2        (*(vuint8 *)(void*)(&__IPSBAR[0x00028C]))\r
+#define MCF_UART_UIPCR2      (*(vuint8 *)(void*)(&__IPSBAR[0x000290]))\r
+#define MCF_UART_UACR2       (*(vuint8 *)(void*)(&__IPSBAR[0x000290]))\r
+#define MCF_UART_UISR2       (*(vuint8 *)(void*)(&__IPSBAR[0x000294]))\r
+#define MCF_UART_UIMR2       (*(vuint8 *)(void*)(&__IPSBAR[0x000294]))\r
+#define MCF_UART_UBG12       (*(vuint8 *)(void*)(&__IPSBAR[0x000298]))\r
+#define MCF_UART_UBG22       (*(vuint8 *)(void*)(&__IPSBAR[0x00029C]))\r
+#define MCF_UART_UIP2        (*(vuint8 *)(void*)(&__IPSBAR[0x0002B4]))\r
+#define MCF_UART_UOP12       (*(vuint8 *)(void*)(&__IPSBAR[0x0002B8]))\r
+#define MCF_UART_UOP02       (*(vuint8 *)(void*)(&__IPSBAR[0x0002BC]))\r
+#define MCF_UART_UMR(x)      (*(vuint8 *)(void*)(&__IPSBAR[0x000200+((x)*0x040)]))\r
+#define MCF_UART_USR(x)      (*(vuint8 *)(void*)(&__IPSBAR[0x000204+((x)*0x040)]))\r
+#define MCF_UART_UCSR(x)     (*(vuint8 *)(void*)(&__IPSBAR[0x000204+((x)*0x040)]))\r
+#define MCF_UART_UCR(x)      (*(vuint8 *)(void*)(&__IPSBAR[0x000208+((x)*0x040)]))\r
+#define MCF_UART_URB(x)      (*(vuint8 *)(void*)(&__IPSBAR[0x00020C+((x)*0x040)]))\r
+#define MCF_UART_UTB(x)      (*(vuint8 *)(void*)(&__IPSBAR[0x00020C+((x)*0x040)]))\r
+#define MCF_UART_UIPCR(x)    (*(vuint8 *)(void*)(&__IPSBAR[0x000210+((x)*0x040)]))\r
+#define MCF_UART_UACR(x)     (*(vuint8 *)(void*)(&__IPSBAR[0x000210+((x)*0x040)]))\r
+#define MCF_UART_UISR(x)     (*(vuint8 *)(void*)(&__IPSBAR[0x000214+((x)*0x040)]))\r
+#define MCF_UART_UIMR(x)     (*(vuint8 *)(void*)(&__IPSBAR[0x000214+((x)*0x040)]))\r
+#define MCF_UART_UBG1(x)     (*(vuint8 *)(void*)(&__IPSBAR[0x000218+((x)*0x040)]))\r
+#define MCF_UART_UBG2(x)     (*(vuint8 *)(void*)(&__IPSBAR[0x00021C+((x)*0x040)]))\r
+#define MCF_UART_UIP(x)      (*(vuint8 *)(void*)(&__IPSBAR[0x000234+((x)*0x040)]))\r
+#define MCF_UART_UOP1(x)     (*(vuint8 *)(void*)(&__IPSBAR[0x000238+((x)*0x040)]))\r
+#define MCF_UART_UOP0(x)     (*(vuint8 *)(void*)(&__IPSBAR[0x00023C+((x)*0x040)]))\r
+\r
+/* Bit definitions and macros for MCF_UART_UMR */\r
+#define MCF_UART_UMR_BC(x)              (((x)&0x03)<<0)\r
+#define MCF_UART_UMR_PT                 (0x04)\r
+#define MCF_UART_UMR_PM(x)              (((x)&0x03)<<3)\r
+#define MCF_UART_UMR_ERR                (0x20)\r
+#define MCF_UART_UMR_RXIRQ              (0x40)\r
+#define MCF_UART_UMR_RXRTS              (0x80)\r
+#define MCF_UART_UMR_SB(x)              (((x)&0x0F)<<0)\r
+#define MCF_UART_UMR_TXCTS              (0x10)\r
+#define MCF_UART_UMR_TXRTS              (0x20)\r
+#define MCF_UART_UMR_CM(x)              (((x)&0x03)<<6)\r
+#define MCF_UART_UMR_PM_MULTI_ADDR      (0x1C)\r
+#define MCF_UART_UMR_PM_MULTI_DATA      (0x18)\r
+#define MCF_UART_UMR_PM_NONE            (0x10)\r
+#define MCF_UART_UMR_PM_FORCE_HI        (0x0C)\r
+#define MCF_UART_UMR_PM_FORCE_LO        (0x08)\r
+#define MCF_UART_UMR_PM_ODD             (0x04)\r
+#define MCF_UART_UMR_PM_EVEN            (0x00)\r
+#define MCF_UART_UMR_BC_5               (0x00)\r
+#define MCF_UART_UMR_BC_6               (0x01)\r
+#define MCF_UART_UMR_BC_7               (0x02)\r
+#define MCF_UART_UMR_BC_8               (0x03)\r
+#define MCF_UART_UMR_CM_NORMAL          (0x00)\r
+#define MCF_UART_UMR_CM_ECHO            (0x40)\r
+#define MCF_UART_UMR_CM_LOCAL_LOOP      (0x80)\r
+#define MCF_UART_UMR_CM_REMOTE_LOOP     (0xC0)\r
+#define MCF_UART_UMR_SB_STOP_BITS_1     (0x07)\r
+#define MCF_UART_UMR_SB_STOP_BITS_15    (0x08)\r
+#define MCF_UART_UMR_SB_STOP_BITS_2     (0x0F)\r
+\r
+/* Bit definitions and macros for MCF_UART_USR */\r
+#define MCF_UART_USR_RXRDY              (0x01)\r
+#define MCF_UART_USR_FFULL              (0x02)\r
+#define MCF_UART_USR_TXRDY              (0x04)\r
+#define MCF_UART_USR_TXEMP              (0x08)\r
+#define MCF_UART_USR_OE                 (0x10)\r
+#define MCF_UART_USR_PE                 (0x20)\r
+#define MCF_UART_USR_FE                 (0x40)\r
+#define MCF_UART_USR_RB                 (0x80)\r
+\r
+/* Bit definitions and macros for MCF_UART_UCSR */\r
+#define MCF_UART_UCSR_TCS(x)            (((x)&0x0F)<<0)\r
+#define MCF_UART_UCSR_RCS(x)            (((x)&0x0F)<<4)\r
+#define MCF_UART_UCSR_RCS_SYS_CLK       (0xD0)\r
+#define MCF_UART_UCSR_RCS_CTM16         (0xE0)\r
+#define MCF_UART_UCSR_RCS_CTM           (0xF0)\r
+#define MCF_UART_UCSR_TCS_SYS_CLK       (0x0D)\r
+#define MCF_UART_UCSR_TCS_CTM16         (0x0E)\r
+#define MCF_UART_UCSR_TCS_CTM           (0x0F)\r
+\r
+/* Bit definitions and macros for MCF_UART_UCR */\r
+#define MCF_UART_UCR_RXC(x)             (((x)&0x03)<<0)\r
+#define MCF_UART_UCR_TXC(x)             (((x)&0x03)<<2)\r
+#define MCF_UART_UCR_MISC(x)            (((x)&0x07)<<4)\r
+#define MCF_UART_UCR_NONE               (0x00)\r
+#define MCF_UART_UCR_STOP_BREAK         (0x70)\r
+#define MCF_UART_UCR_START_BREAK        (0x60)\r
+#define MCF_UART_UCR_BKCHGINT           (0x50)\r
+#define MCF_UART_UCR_RESET_ERROR        (0x40)\r
+#define MCF_UART_UCR_RESET_TX           (0x30)\r
+#define MCF_UART_UCR_RESET_RX           (0x20)\r
+#define MCF_UART_UCR_RESET_MR           (0x10)\r
+#define MCF_UART_UCR_TX_DISABLED        (0x08)\r
+#define MCF_UART_UCR_TX_ENABLED         (0x04)\r
+#define MCF_UART_UCR_RX_DISABLED        (0x02)\r
+#define MCF_UART_UCR_RX_ENABLED         (0x01)\r
+\r
+/* Bit definitions and macros for MCF_UART_UIPCR */\r
+#define MCF_UART_UIPCR_CTS              (0x01)\r
+#define MCF_UART_UIPCR_COS              (0x10)\r
+\r
+/* Bit definitions and macros for MCF_UART_UACR */\r
+#define MCF_UART_UACR_IEC               (0x01)\r
+\r
+/* Bit definitions and macros for MCF_UART_UISR */\r
+#define MCF_UART_UISR_TXRDY             (0x01)\r
+#define MCF_UART_UISR_RXRDY_FU          (0x02)\r
+#define MCF_UART_UISR_DB                (0x04)\r
+#define MCF_UART_UISR_RXFTO             (0x08)\r
+#define MCF_UART_UISR_TXFIFO            (0x10)\r
+#define MCF_UART_UISR_RXFIFO            (0x20)\r
+#define MCF_UART_UISR_COS               (0x80)\r
+\r
+/* Bit definitions and macros for MCF_UART_UIMR */\r
+#define MCF_UART_UIMR_TXRDY             (0x01)\r
+#define MCF_UART_UIMR_RXRDY_FU          (0x02)\r
+#define MCF_UART_UIMR_DB                (0x04)\r
+#define MCF_UART_UIMR_COS               (0x80)\r
+\r
+/* Bit definitions and macros for MCF_UART_UIP */\r
+#define MCF_UART_UIP_CTS                (0x01)\r
+\r
+/* Bit definitions and macros for MCF_UART_UOP1 */\r
+#define MCF_UART_UOP1_RTS               (0x01)\r
+\r
+/* Bit definitions and macros for MCF_UART_UOP0 */\r
+#define MCF_UART_UOP0_RTS               (0x01)\r
+\r
+/********************************************************************/\r
+\r
+#endif /* __MCF523X_UART_H__ */\r
index 4894867917953525d96b9a7e248efafeabbe1f4f..1e5f9f97fe57334a9d6d9f8e8e38d4940c78f224 100644 (file)
@@ -1,92 +1,92 @@
-/*
- * These files are taken from the MCF523X source code example package
- * which is available on the Freescale website. Freescale explicitly 
- * grants the redistribution and modification of these source files.
- * The complete licensing information is available in the file 
- * LICENSE_FREESCALE.TXT.
- *
- * File:       mcf523x_wtm.h
- * Purpose:    Register and bit definitions for the MCF523X
- *
- * Notes:      
- *     
- */
-
-#ifndef __MCF523X_WTM_H__
-#define __MCF523X_WTM_H__
-
-/*********************************************************************
-*
-* Watchdog Timer Modules (WTM)
-*
-*********************************************************************/
-
-/* Register read/write macros */
-#define MCF_WTM_WCR      (*(vuint16*)(void*)(&__IPSBAR[0x140000]))
-#define MCF_WTM_WMR      (*(vuint16*)(void*)(&__IPSBAR[0x140002]))
-#define MCF_WTM_WCNTR    (*(vuint16*)(void*)(&__IPSBAR[0x140004]))
-#define MCF_WTM_WSR      (*(vuint16*)(void*)(&__IPSBAR[0x140006]))
-
-/* Bit definitions and macros for MCF_WTM_WCR */
-#define MCF_WTM_WCR_EN        (0x0001)
-#define MCF_WTM_WCR_HALTED    (0x0002)
-#define MCF_WTM_WCR_DOZE      (0x0004)
-#define MCF_WTM_WCR_WAIT      (0x0008)
-
-/* Bit definitions and macros for MCF_WTM_WMR */
-#define MCF_WTM_WMR_WM0       (0x0001)
-#define MCF_WTM_WMR_WM1       (0x0002)
-#define MCF_WTM_WMR_WM2       (0x0004)
-#define MCF_WTM_WMR_WM3       (0x0008)
-#define MCF_WTM_WMR_WM4       (0x0010)
-#define MCF_WTM_WMR_WM5       (0x0020)
-#define MCF_WTM_WMR_WM6       (0x0040)
-#define MCF_WTM_WMR_WM7       (0x0080)
-#define MCF_WTM_WMR_WM8       (0x0100)
-#define MCF_WTM_WMR_WM9       (0x0200)
-#define MCF_WTM_WMR_WM10      (0x0400)
-#define MCF_WTM_WMR_WM11      (0x0800)
-#define MCF_WTM_WMR_WM12      (0x1000)
-#define MCF_WTM_WMR_WM13      (0x2000)
-#define MCF_WTM_WMR_WM14      (0x4000)
-#define MCF_WTM_WMR_WM15      (0x8000)
-
-/* Bit definitions and macros for MCF_WTM_WCNTR */
-#define MCF_WTM_WCNTR_WC0     (0x0001)
-#define MCF_WTM_WCNTR_WC1     (0x0002)
-#define MCF_WTM_WCNTR_WC2     (0x0004)
-#define MCF_WTM_WCNTR_WC3     (0x0008)
-#define MCF_WTM_WCNTR_WC4     (0x0010)
-#define MCF_WTM_WCNTR_WC5     (0x0020)
-#define MCF_WTM_WCNTR_WC6     (0x0040)
-#define MCF_WTM_WCNTR_WC7     (0x0080)
-#define MCF_WTM_WCNTR_WC8     (0x0100)
-#define MCF_WTM_WCNTR_WC9     (0x0200)
-#define MCF_WTM_WCNTR_WC10    (0x0400)
-#define MCF_WTM_WCNTR_WC11    (0x0800)
-#define MCF_WTM_WCNTR_WC12    (0x1000)
-#define MCF_WTM_WCNTR_WC13    (0x2000)
-#define MCF_WTM_WCNTR_WC14    (0x4000)
-#define MCF_WTM_WCNTR_WC15    (0x8000)
-
-/* Bit definitions and macros for MCF_WTM_WSR */
-#define MCF_WTM_WSR_WS0       (0x0001)
-#define MCF_WTM_WSR_WS1       (0x0002)
-#define MCF_WTM_WSR_WS2       (0x0004)
-#define MCF_WTM_WSR_WS3       (0x0008)
-#define MCF_WTM_WSR_WS4       (0x0010)
-#define MCF_WTM_WSR_WS5       (0x0020)
-#define MCF_WTM_WSR_WS6       (0x0040)
-#define MCF_WTM_WSR_WS7       (0x0080)
-#define MCF_WTM_WSR_WS8       (0x0100)
-#define MCF_WTM_WSR_WS9       (0x0200)
-#define MCF_WTM_WSR_WS10      (0x0400)
-#define MCF_WTM_WSR_WS11      (0x0800)
-#define MCF_WTM_WSR_WS12      (0x1000)
-#define MCF_WTM_WSR_WS13      (0x2000)
-#define MCF_WTM_WSR_WS14      (0x4000)
-#define MCF_WTM_WSR_WS15      (0x8000)
-
-/********************************************************************/
-
-#endif /* __MCF523X_WTM_H__ */
+/*\r
+ * These files are taken from the MCF523X source code example package\r
+ * which is available on the Freescale website. Freescale explicitly \r
+ * grants the redistribution and modification of these source files.\r
+ * The complete licensing information is available in the file \r
+ * LICENSE_FREESCALE.TXT.\r
+ *\r
+ * File:       mcf523x_wtm.h\r
+ * Purpose:    Register and bit definitions for the MCF523X\r
+ *\r
+ * Notes:      \r
+ *     \r
+ */\r
+\r
+#ifndef __MCF523X_WTM_H__\r
+#define __MCF523X_WTM_H__\r
+\r
+/*********************************************************************\r
+*\r
+* Watchdog Timer Modules (WTM)\r
+*\r
+*********************************************************************/\r
+\r
+/* Register read/write macros */\r
+#define MCF_WTM_WCR      (*(vuint16*)(void*)(&__IPSBAR[0x140000]))\r
+#define MCF_WTM_WMR      (*(vuint16*)(void*)(&__IPSBAR[0x140002]))\r
+#define MCF_WTM_WCNTR    (*(vuint16*)(void*)(&__IPSBAR[0x140004]))\r
+#define MCF_WTM_WSR      (*(vuint16*)(void*)(&__IPSBAR[0x140006]))\r
+\r
+/* Bit definitions and macros for MCF_WTM_WCR */\r
+#define MCF_WTM_WCR_EN        (0x0001)\r
+#define MCF_WTM_WCR_HALTED    (0x0002)\r
+#define MCF_WTM_WCR_DOZE      (0x0004)\r
+#define MCF_WTM_WCR_WAIT      (0x0008)\r
+\r
+/* Bit definitions and macros for MCF_WTM_WMR */\r
+#define MCF_WTM_WMR_WM0       (0x0001)\r
+#define MCF_WTM_WMR_WM1       (0x0002)\r
+#define MCF_WTM_WMR_WM2       (0x0004)\r
+#define MCF_WTM_WMR_WM3       (0x0008)\r
+#define MCF_WTM_WMR_WM4       (0x0010)\r
+#define MCF_WTM_WMR_WM5       (0x0020)\r
+#define MCF_WTM_WMR_WM6       (0x0040)\r
+#define MCF_WTM_WMR_WM7       (0x0080)\r
+#define MCF_WTM_WMR_WM8       (0x0100)\r
+#define MCF_WTM_WMR_WM9       (0x0200)\r
+#define MCF_WTM_WMR_WM10      (0x0400)\r
+#define MCF_WTM_WMR_WM11      (0x0800)\r
+#define MCF_WTM_WMR_WM12      (0x1000)\r
+#define MCF_WTM_WMR_WM13      (0x2000)\r
+#define MCF_WTM_WMR_WM14      (0x4000)\r
+#define MCF_WTM_WMR_WM15      (0x8000)\r
+\r
+/* Bit definitions and macros for MCF_WTM_WCNTR */\r
+#define MCF_WTM_WCNTR_WC0     (0x0001)\r
+#define MCF_WTM_WCNTR_WC1     (0x0002)\r
+#define MCF_WTM_WCNTR_WC2     (0x0004)\r
+#define MCF_WTM_WCNTR_WC3     (0x0008)\r
+#define MCF_WTM_WCNTR_WC4     (0x0010)\r
+#define MCF_WTM_WCNTR_WC5     (0x0020)\r
+#define MCF_WTM_WCNTR_WC6     (0x0040)\r
+#define MCF_WTM_WCNTR_WC7     (0x0080)\r
+#define MCF_WTM_WCNTR_WC8     (0x0100)\r
+#define MCF_WTM_WCNTR_WC9     (0x0200)\r
+#define MCF_WTM_WCNTR_WC10    (0x0400)\r
+#define MCF_WTM_WCNTR_WC11    (0x0800)\r
+#define MCF_WTM_WCNTR_WC12    (0x1000)\r
+#define MCF_WTM_WCNTR_WC13    (0x2000)\r
+#define MCF_WTM_WCNTR_WC14    (0x4000)\r
+#define MCF_WTM_WCNTR_WC15    (0x8000)\r
+\r
+/* Bit definitions and macros for MCF_WTM_WSR */\r
+#define MCF_WTM_WSR_WS0       (0x0001)\r
+#define MCF_WTM_WSR_WS1       (0x0002)\r
+#define MCF_WTM_WSR_WS2       (0x0004)\r
+#define MCF_WTM_WSR_WS3       (0x0008)\r
+#define MCF_WTM_WSR_WS4       (0x0010)\r
+#define MCF_WTM_WSR_WS5       (0x0020)\r
+#define MCF_WTM_WSR_WS6       (0x0040)\r
+#define MCF_WTM_WSR_WS7       (0x0080)\r
+#define MCF_WTM_WSR_WS8       (0x0100)\r
+#define MCF_WTM_WSR_WS9       (0x0200)\r
+#define MCF_WTM_WSR_WS10      (0x0400)\r
+#define MCF_WTM_WSR_WS11      (0x0800)\r
+#define MCF_WTM_WSR_WS12      (0x1000)\r
+#define MCF_WTM_WSR_WS13      (0x2000)\r
+#define MCF_WTM_WSR_WS14      (0x4000)\r
+#define MCF_WTM_WSR_WS15      (0x8000)\r
+\r
+/********************************************************************/\r
+\r
+#endif /* __MCF523X_WTM_H__ */\r
index 692d690e149e40561ae9af4bf2978da81e280f33..01153e4090c70e5ecd8d256085d6e0176e595dcf 100644 (file)
-/*
- * These files are taken from the MCF523X source code example package
- * which is available on the Freescale website. Freescale explicitly 
- * grants the redistribution and modification of these source files.
- * The complete licensing information is available in the file 
- * LICENSE_FREESCALE.TXT.
- *
- * File:               mcf5xxx.h
- * Purpose:            Definitions common to all ColdFire processors
- *
- * Notes:
- */
-
-#ifndef _CPU_MCF5XXX_H
-#define _CPU_MCF5XXX_H
-
-/***********************************************************************/
-/*
- * Misc. Defines
- */
-
-#ifdef FALSE
-#undef FALSE
-#endif
-#define FALSE  (0)
-
-#ifdef TRUE
-#undef TRUE
-#endif
-#define        TRUE    (1)
-
-#ifdef NULL
-#undef NULL
-#endif
-#define NULL   (0)
-
-/***********************************************************************/
-/*
- * The basic data types
- */
-
-typedef unsigned char          uint8;  /*  8 bits */
-typedef unsigned short int     uint16; /* 16 bits */
-typedef unsigned long int      uint32; /* 32 bits */
-
-typedef signed char                    int8;   /*  8 bits */
-typedef signed short int       int16;  /* 16 bits */
-typedef signed long int                int32;  /* 32 bits */
-
-typedef volatile uint8         vuint8;  /*  8 bits */
-typedef volatile uint16                vuint16; /* 16 bits */
-typedef volatile uint32                vuint32; /* 32 bits */
-
-/***********************************************************************/
-/*
- * Common M68K & ColdFire definitions
- */
-
-#define ADDRESS                        uint32
-#define INSTRUCTION            uint16
-#define ILLEGAL                        0x4AFC
-#define CPU_WORD_SIZE  16
-
-#define MCF5XXX_SR_T           (0x8000)
-#define MCF5XXX_SR_S           (0x2000)
-#define MCF5XXX_SR_M           (0x1000)
-#define MCF5XXX_SR_IPL         (0x0700)
-#define MCF5XXX_SR_IPL_0       (0x0000)
-#define MCF5XXX_SR_IPL_1       (0x0100)
-#define MCF5XXX_SR_IPL_2       (0x0200)
-#define MCF5XXX_SR_IPL_3       (0x0300)
-#define MCF5XXX_SR_IPL_4       (0x0400)
-#define MCF5XXX_SR_IPL_5       (0x0500)
-#define MCF5XXX_SR_IPL_6       (0x0600)
-#define MCF5XXX_SR_IPL_7       (0x0700)
-#define MCF5XXX_SR_X           (0x0010)
-#define MCF5XXX_SR_N           (0x0008)
-#define MCF5XXX_SR_Z           (0x0004)
-#define MCF5XXX_SR_V           (0x0002)
-#define MCF5XXX_SR_C           (0x0001)
-
-#define MCF5XXX_CACR_CENB              (0x80000000)
-#define MCF5XXX_CACR_CPDI              (0x10000000)
-#define MCF5XXX_CACR_CPD               (0x10000000)
-#define MCF5XXX_CACR_CFRZ              (0x08000000)
-#define MCF5XXX_CACR_CINV              (0x01000000)
-#define MCF5XXX_CACR_DIDI              (0x00800000)
-#define MCF5XXX_CACR_DISD              (0x00400000)
-#define MCF5XXX_CACR_INVI              (0x00200000)
-#define MCF5XXX_CACR_INVD              (0x00100000)
-#define MCF5XXX_CACR_CEIB              (0x00000400)
-#define MCF5XXX_CACR_DCM_WR            (0x00000000)
-#define MCF5XXX_CACR_DCM_CB            (0x00000100)
-#define MCF5XXX_CACR_DCM_IP            (0x00000200)
-#define MCF5XXX_CACR_DCM               (0x00000200)
-#define MCF5XXX_CACR_DCM_II            (0x00000300)
-#define MCF5XXX_CACR_DBWE              (0x00000100)
-#define MCF5XXX_CACR_DWP               (0x00000020)
-#define MCF5XXX_CACR_EUST              (0x00000010)
-#define MCF5XXX_CACR_CLNF_00   (0x00000000)
-#define MCF5XXX_CACR_CLNF_01   (0x00000002)
-#define MCF5XXX_CACR_CLNF_10   (0x00000004)
-#define MCF5XXX_CACR_CLNF_11   (0x00000006)
-
-#define MCF5XXX_ACR_AB(a)              ((a)&0xFF000000)
-#define MCF5XXX_ACR_AM(a)              (((a)&0xFF000000) >> 8)
-#define MCF5XXX_ACR_EN                 (0x00008000)
-#define MCF5XXX_ACR_SM_USER            (0x00000000)
-#define MCF5XXX_ACR_SM_SUPER   (0x00002000)
-#define MCF5XXX_ACR_SM_IGNORE  (0x00006000)
-#define MCF5XXX_ACR_ENIB               (0x00000080)
-#define MCF5XXX_ACR_CM                 (0x00000040)
-#define MCF5XXX_ACR_DCM_WR             (0x00000000)
-#define MCF5XXX_ACR_DCM_CB             (0x00000020)
-#define MCF5XXX_ACR_DCM_IP             (0x00000040)
-#define MCF5XXX_ACR_DCM_II             (0x00000060)
-#define MCF5XXX_ACR_CM                 (0x00000040)
-#define MCF5XXX_ACR_BWE                        (0x00000020)
-#define MCF5XXX_ACR_WP                 (0x00000004)
-
-#define MCF5XXX_RAMBAR_BA(a)   ((a)&0xFFFFC000)
-#define MCF5XXX_RAMBAR_PRI_00  (0x00000000)
-#define MCF5XXX_RAMBAR_PRI_01  (0x00004000)
-#define MCF5XXX_RAMBAR_PRI_10  (0x00008000)
-#define MCF5XXX_RAMBAR_PRI_11  (0x0000C000)
-#define MCF5XXX_RAMBAR_WP              (0x00000100)
-#define MCF5XXX_RAMBAR_CI              (0x00000020)
-#define MCF5XXX_RAMBAR_SC              (0x00000010)
-#define MCF5XXX_RAMBAR_SD              (0x00000008)
-#define MCF5XXX_RAMBAR_UC              (0x00000004)
-#define MCF5XXX_RAMBAR_UD              (0x00000002)
-#define MCF5XXX_RAMBAR_V               (0x00000001)
-
-/***********************************************************************/
-/*
- * The ColdFire family of processors has a simplified exception stack
- * frame that looks like the following:
- *
- *              3322222222221111 111111
- *              1098765432109876 5432109876543210
- *           8 +----------------+----------------+
- *             |         Program Counter         |
- *           4 +----------------+----------------+
- *             |FS/Fmt/Vector/FS|      SR        |
- *   SP -->  0 +----------------+----------------+
- *
- * The stack self-aligns to a 4-byte boundary at an exception, with
- * the FS/Fmt/Vector/FS field indicating the size of the adjustment
- * (SP += 0,1,2,3 bytes).
- */
-
-#define MCF5XXX_RD_SF_FORMAT(PTR)      \
-       ((*((uint16 *)(PTR)) >> 12) & 0x00FF)
-
-#define MCF5XXX_RD_SF_VECTOR(PTR)      \
-       ((*((uint16 *)(PTR)) >>  2) & 0x00FF)
-
-#define MCF5XXX_RD_SF_FS(PTR)          \
-       ( ((*((uint16 *)(PTR)) & 0x0C00) >> 8) | (*((uint16 *)(PTR)) & 0x0003) )
-
-#define MCF5XXX_SF_SR(PTR)     *((uint16 *)(PTR)+1)
-#define MCF5XXX_SF_PC(PTR)     *((uint32 *)(PTR)+1)
-
-/********************************************************************/
-/*
- * Functions provided by mcf5xxx.s
- */
-int    asm_set_ipl (uint32);
-void   mcf5xxx_wr_cacr (uint32);
-void   mcf5xxx_wr_acr0 (uint32);
-void   mcf5xxx_wr_acr1 (uint32);
-void   mcf5xxx_wr_acr2 (uint32);
-void   mcf5xxx_wr_acr3 (uint32);
-void   mcf5xxx_wr_other_a7 (uint32);
-void   mcf5xxx_wr_other_sp (uint32);
-void   mcf5xxx_wr_vbr (uint32);
-void   mcf5xxx_wr_macsr (uint32);
-void   mcf5xxx_wr_mask (uint32);
-void   mcf5xxx_wr_acc0 (uint32);
-void   mcf5xxx_wr_accext01 (uint32);
-void   mcf5xxx_wr_accext23 (uint32);
-void   mcf5xxx_wr_acc1 (uint32);
-void   mcf5xxx_wr_acc2 (uint32);
-void   mcf5xxx_wr_acc3 (uint32);
-void   mcf5xxx_wr_sr (uint32);
-void   mcf5xxx_wr_rambar0 (uint32);
-void   mcf5xxx_wr_rambar1 (uint32);
-void   mcf5xxx_wr_mbar (uint32);
-void   mcf5xxx_wr_mbar0 (uint32);
-void   mcf5xxx_wr_mbar1 (uint32);
-
-/********************************************************************/
-
-#endif /* _CPU_MCF5XXX_H */
-
+/*\r
+ * These files are taken from the MCF523X source code example package\r
+ * which is available on the Freescale website. Freescale explicitly \r
+ * grants the redistribution and modification of these source files.\r
+ * The complete licensing information is available in the file \r
+ * LICENSE_FREESCALE.TXT.\r
+ *\r
+ * File:               mcf5xxx.h\r
+ * Purpose:            Definitions common to all ColdFire processors\r
+ *\r
+ * Notes:\r
+ */\r
+\r
+#ifndef _CPU_MCF5XXX_H\r
+#define _CPU_MCF5XXX_H\r
+\r
+/***********************************************************************/\r
+/*\r
+ * Misc. Defines\r
+ */\r
+\r
+#ifdef FALSE\r
+#undef FALSE\r
+#endif\r
+#define FALSE  (0)\r
+\r
+#ifdef TRUE\r
+#undef TRUE\r
+#endif\r
+#define        TRUE    (1)\r
+\r
+#ifdef NULL\r
+#undef NULL\r
+#endif\r
+#define NULL   (0)\r
+\r
+/***********************************************************************/\r
+/*\r
+ * The basic data types\r
+ */\r
+\r
+typedef unsigned char          uint8;  /*  8 bits */\r
+typedef unsigned short int     uint16; /* 16 bits */\r
+typedef unsigned long int      uint32; /* 32 bits */\r
+\r
+typedef signed char                    int8;   /*  8 bits */\r
+typedef signed short int       int16;  /* 16 bits */\r
+typedef signed long int                int32;  /* 32 bits */\r
+\r
+typedef volatile uint8         vuint8;  /*  8 bits */\r
+typedef volatile uint16                vuint16; /* 16 bits */\r
+typedef volatile uint32                vuint32; /* 32 bits */\r
+\r
+/***********************************************************************/\r
+/*\r
+ * Common M68K & ColdFire definitions\r
+ */\r
+\r
+#define ADDRESS                        uint32\r
+#define INSTRUCTION            uint16\r
+#define ILLEGAL                        0x4AFC\r
+#define CPU_WORD_SIZE  16\r
+\r
+#define MCF5XXX_SR_T           (0x8000)\r
+#define MCF5XXX_SR_S           (0x2000)\r
+#define MCF5XXX_SR_M           (0x1000)\r
+#define MCF5XXX_SR_IPL         (0x0700)\r
+#define MCF5XXX_SR_IPL_0       (0x0000)\r
+#define MCF5XXX_SR_IPL_1       (0x0100)\r
+#define MCF5XXX_SR_IPL_2       (0x0200)\r
+#define MCF5XXX_SR_IPL_3       (0x0300)\r
+#define MCF5XXX_SR_IPL_4       (0x0400)\r
+#define MCF5XXX_SR_IPL_5       (0x0500)\r
+#define MCF5XXX_SR_IPL_6       (0x0600)\r
+#define MCF5XXX_SR_IPL_7       (0x0700)\r
+#define MCF5XXX_SR_X           (0x0010)\r
+#define MCF5XXX_SR_N           (0x0008)\r
+#define MCF5XXX_SR_Z           (0x0004)\r
+#define MCF5XXX_SR_V           (0x0002)\r
+#define MCF5XXX_SR_C           (0x0001)\r
+\r
+#define MCF5XXX_CACR_CENB              (0x80000000)\r
+#define MCF5XXX_CACR_CPDI              (0x10000000)\r
+#define MCF5XXX_CACR_CPD               (0x10000000)\r
+#define MCF5XXX_CACR_CFRZ              (0x08000000)\r
+#define MCF5XXX_CACR_CINV              (0x01000000)\r
+#define MCF5XXX_CACR_DIDI              (0x00800000)\r
+#define MCF5XXX_CACR_DISD              (0x00400000)\r
+#define MCF5XXX_CACR_INVI              (0x00200000)\r
+#define MCF5XXX_CACR_INVD              (0x00100000)\r
+#define MCF5XXX_CACR_CEIB              (0x00000400)\r
+#define MCF5XXX_CACR_DCM_WR            (0x00000000)\r
+#define MCF5XXX_CACR_DCM_CB            (0x00000100)\r
+#define MCF5XXX_CACR_DCM_IP            (0x00000200)\r
+#define MCF5XXX_CACR_DCM               (0x00000200)\r
+#define MCF5XXX_CACR_DCM_II            (0x00000300)\r
+#define MCF5XXX_CACR_DBWE              (0x00000100)\r
+#define MCF5XXX_CACR_DWP               (0x00000020)\r
+#define MCF5XXX_CACR_EUST              (0x00000010)\r
+#define MCF5XXX_CACR_CLNF_00   (0x00000000)\r
+#define MCF5XXX_CACR_CLNF_01   (0x00000002)\r
+#define MCF5XXX_CACR_CLNF_10   (0x00000004)\r
+#define MCF5XXX_CACR_CLNF_11   (0x00000006)\r
+\r
+#define MCF5XXX_ACR_AB(a)              ((a)&0xFF000000)\r
+#define MCF5XXX_ACR_AM(a)              (((a)&0xFF000000) >> 8)\r
+#define MCF5XXX_ACR_EN                 (0x00008000)\r
+#define MCF5XXX_ACR_SM_USER            (0x00000000)\r
+#define MCF5XXX_ACR_SM_SUPER   (0x00002000)\r
+#define MCF5XXX_ACR_SM_IGNORE  (0x00006000)\r
+#define MCF5XXX_ACR_ENIB               (0x00000080)\r
+#define MCF5XXX_ACR_CM                 (0x00000040)\r
+#define MCF5XXX_ACR_DCM_WR             (0x00000000)\r
+#define MCF5XXX_ACR_DCM_CB             (0x00000020)\r
+#define MCF5XXX_ACR_DCM_IP             (0x00000040)\r
+#define MCF5XXX_ACR_DCM_II             (0x00000060)\r
+#define MCF5XXX_ACR_CM                 (0x00000040)\r
+#define MCF5XXX_ACR_BWE                        (0x00000020)\r
+#define MCF5XXX_ACR_WP                 (0x00000004)\r
+\r
+#define MCF5XXX_RAMBAR_BA(a)   ((a)&0xFFFFC000)\r
+#define MCF5XXX_RAMBAR_PRI_00  (0x00000000)\r
+#define MCF5XXX_RAMBAR_PRI_01  (0x00004000)\r
+#define MCF5XXX_RAMBAR_PRI_10  (0x00008000)\r
+#define MCF5XXX_RAMBAR_PRI_11  (0x0000C000)\r
+#define MCF5XXX_RAMBAR_WP              (0x00000100)\r
+#define MCF5XXX_RAMBAR_CI              (0x00000020)\r
+#define MCF5XXX_RAMBAR_SC              (0x00000010)\r
+#define MCF5XXX_RAMBAR_SD              (0x00000008)\r
+#define MCF5XXX_RAMBAR_UC              (0x00000004)\r
+#define MCF5XXX_RAMBAR_UD              (0x00000002)\r
+#define MCF5XXX_RAMBAR_V               (0x00000001)\r
+\r
+/***********************************************************************/\r
+/*\r
+ * The ColdFire family of processors has a simplified exception stack\r
+ * frame that looks like the following:\r
+ *\r
+ *              3322222222221111 111111\r
+ *              1098765432109876 5432109876543210\r
+ *           8 +----------------+----------------+\r
+ *             |         Program Counter         |\r
+ *           4 +----------------+----------------+\r
+ *             |FS/Fmt/Vector/FS|      SR        |\r
+ *   SP -->  0 +----------------+----------------+\r
+ *\r
+ * The stack self-aligns to a 4-byte boundary at an exception, with\r
+ * the FS/Fmt/Vector/FS field indicating the size of the adjustment\r
+ * (SP += 0,1,2,3 bytes).\r
+ */\r
+\r
+#define MCF5XXX_RD_SF_FORMAT(PTR)      \\r
+       ((*((uint16 *)(PTR)) >> 12) & 0x00FF)\r
+\r
+#define MCF5XXX_RD_SF_VECTOR(PTR)      \\r
+       ((*((uint16 *)(PTR)) >>  2) & 0x00FF)\r
+\r
+#define MCF5XXX_RD_SF_FS(PTR)          \\r
+       ( ((*((uint16 *)(PTR)) & 0x0C00) >> 8) | (*((uint16 *)(PTR)) & 0x0003) )\r
+\r
+#define MCF5XXX_SF_SR(PTR)     *((uint16 *)(PTR)+1)\r
+#define MCF5XXX_SF_PC(PTR)     *((uint32 *)(PTR)+1)\r
+\r
+/********************************************************************/\r
+/*\r
+ * Functions provided by mcf5xxx.s\r
+ */\r
\r
+int    asm_set_ipl (uint32);\r
+void   mcf5xxx_wr_cacr (uint32);\r
+void   mcf5xxx_wr_acr0 (uint32);\r
+void   mcf5xxx_wr_acr1 (uint32);\r
+void   mcf5xxx_wr_acr2 (uint32);\r
+void   mcf5xxx_wr_acr3 (uint32);\r
+void   mcf5xxx_wr_other_a7 (uint32);\r
+void   mcf5xxx_wr_other_sp (uint32);\r
+void   mcf5xxx_wr_vbr (uint32);\r
+void   mcf5xxx_wr_macsr (uint32);\r
+void   mcf5xxx_wr_mask (uint32);\r
+void   mcf5xxx_wr_acc0 (uint32);\r
+void   mcf5xxx_wr_accext01 (uint32);\r
+void   mcf5xxx_wr_accext23 (uint32);\r
+void   mcf5xxx_wr_acc1 (uint32);\r
+void   mcf5xxx_wr_acc2 (uint32);\r
+void   mcf5xxx_wr_acc3 (uint32);\r
+void   mcf5xxx_wr_sr (uint32);\r
+void   mcf5xxx_wr_rambar0 (uint32);\r
+void   mcf5xxx_wr_rambar1 (uint32);\r
+void   mcf5xxx_wr_mbar (uint32);\r
+void   mcf5xxx_wr_mbar0 (uint32);\r
+void   mcf5xxx_wr_mbar1 (uint32);\r
+\r
+/********************************************************************/\r
+\r
+#endif /* _CPU_MCF5XXX_H */\r
+\r
index 8ebf30a5d004f86bec570ef228e701e46e0486c1..f923c982cad69457545bfdf6742c10f17208fae5 100644 (file)
-/*
-    FreeRTOS MCF5235 port - Copyright (C) 2006 Christian Walter.
-
-    This file is part of the FreeRTOS distribution.
-
-    FreeRTOS is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    FreeRTOS is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with FreeRTOS; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-    A special exception to the GPL can be applied should you wish to distribute
-    a combined work that includes FreeRTOS, without being obliged to provide
-    the source code for any proprietary components.  See the licensing section
-    of http://www.FreeRTOS.org for full details of how and when the exception
-    can be applied.
-
-    ***************************************************************************
-    See http://www.FreeRTOS.org for documentation, latest information, license
-    and contact details.  Please ensure to read the configuration and relevant
+/*\r
+    FreeRTOS MCF5235 port - Copyright (C) 2006 Christian Walter.\r
+\r
+    This file is part of the FreeRTOS distribution.\r
+\r
+    FreeRTOS is free software; you can redistribute it and/or modify\r
+    it under the terms of the GNU General Public License as published by\r
+    the Free Software Foundation; either version 2 of the License, or\r
+    (at your option) any later version.\r
+\r
+    FreeRTOS is distributed in the hope that it will be useful,\r
+    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+    GNU General Public License for more details.\r
+\r
+    You should have received a copy of the GNU General Public License\r
+    along with FreeRTOS; if not, write to the Free Software\r
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+\r
+    A special exception to the GPL can be applied should you wish to distribute\r
+    a combined work that includes FreeRTOS, without being obliged to provide\r
+    the source code for any proprietary components.  See the licensing section\r
+    of http://www.FreeRTOS.org for full details of how and when the exception\r
+    can be applied.\r
+\r
+    ***************************************************************************\r
+    See http://www.FreeRTOS.org for documentation, latest information, license\r
+    and contact details.  Please ensure to read the configuration and relevant\r
     port sections of the online documentation.\r
 \r
        Also see http://www.SafeRTOS.com for an IEC 61508 compliant version along\r
-       with commercial development and support options.
-    ***************************************************************************
-*/
-
-#include "mcf5xxx.h"
-#include "mcf523x.h"
-
-/* Function prototypes */
-void            init_main( void );
-static void     disable_interrupts( void );
-static void     disable_watchdog_timer( void );
-static void     disable_cache( void );
-static void     init_ipsbar( void );
-static void     init_basics( void );
-static void     init_clock_config( void );
-static void     init_chip_selects( void );
-static void     init_bus_config( void );
-static void     init_cache( void );
-static void     init_eport( void );
-static void     init_flexcan( void );
-static void     init_power_management( void );
-static void     init_dma_timers( void );
-static void     init_interrupt_timers( void );
-static void     init_watchdog_timers( void );
-static void     init_pin_assignments( void );
-static void     init_sdram_controller( void );
-static void     init_interrupt_controller( void );
-
-
-/*********************************************************************
-* init_main - Main entry point for initialisation code               *
-**********************************************************************/
-void
-init_main( void )
-{
-
-    /* Initialise base address of peripherals, VBR, etc */
-    init_ipsbar(  );
-    init_basics(  );
-    init_clock_config(  );
-
-    /* Disable interrupts, watchdog timer, cache */
-    disable_interrupts(  );
-    disable_watchdog_timer(  );
-    disable_cache(  );
-
-    /* Initialise individual modules */
-    init_chip_selects(  );
-    init_bus_config(  );
-    init_cache(  );
-    init_eport(  );
-    init_flexcan(  );
-    init_power_management(  );
-    init_dma_timers(  );
-    init_interrupt_timers(  );
-    init_watchdog_timers(  );
-    init_pin_assignments(  );
-    init_sdram_controller(  );
-
-    /* Initialise interrupt controller */
-    init_interrupt_controller(  );
-}
-
-/*********************************************************************
-* disable_interrupts - Disable all interrupt sources                 *
-**********************************************************************/
-static void
-disable_interrupts( void )
-{
-    vuint8         *p;
-    int             i;
-
-
-    /* Set ICR008-ICR063 to 0x0 */
-    p = ( vuint8 * ) & MCF_INTC0_ICR8;
-    for( i = 8; i <= 63; i++ )
-        *p++ = 0x0;
-
-    /* Set ICR108-ICR163 to 0x0 */
-    p = ( vuint8 * ) & MCF_INTC1_ICR8;
-    for( i = 108; i <= 163; i++ )
-        *p++ = 0x0;
-}
-
-
-/*********************************************************************
-* disable_watchdog_timer - Disable system watchdog timer             *
-**********************************************************************/
-static void
-disable_watchdog_timer( void )
-{
-
-    /* Disable Core Watchdog Timer */
-    MCF_SCM_CWCR = 0;
-}
-
-/*********************************************************************
-* disable_cache - Disable and invalidate cache                       *
-**********************************************************************/
-static void
-disable_cache( void )
-{
-    asm ( "move.l   #0x01000000, %d0" );
-    asm ( "movec    %d0, %CACR" );
-}
-
-/*********************************************************************
-* init_basics - Configuration Information & VBR                      *
-**********************************************************************/
-static void
-init_basics( void )
-{
-    int             i;
-    extern uint32   __RAMVEC[];
-    extern uint32   __ROMVEC[];
-
-    /* Transfer size not driven on SIZ[1:0] pins during external cycles
-       Processor Status (PST) and Debug Data (DDATA) functions disabled
-       Bus monitor disabled
-       Output pads configured for full strength
-     */
-    MCF_CCM_CCR = ( 0x1 << 15 ) | MCF_CCM_CCR_BME;
-
-    /* Set up RAM vectors */
-    for( i = 0; i < 256; i++ )
-
-    {
-        __RAMVEC[i] = __ROMVEC[i];
-    }
-    asm( "move.l   %0,%%d0": :"i"( __RAMVEC ) );
-    asm( "movec    %d0,%vbr" );
-}
-
-
-/*********************************************************************
-* init_clock_config - Clock Module                                   *
-**********************************************************************/
-static void
-init_clock_config( void )
-{
-    /* Clock module uses normal PLL mode with 25.0000 MHz external reference (Fref)
-       MFD = 0, RFD = 1
-       Bus clock frequency = 25.00 MHz
-       Processor clock frequency = 2 x bus clock = 50.00 MHz
-       Frequency Modulation disabled
-       Loss of clock detection disabled
-       Reset/Interrupt on loss of lock disabled
-     */
-    MCF_FMPLL_SYNCR = 0x00100000;       /* Set RFD=RFD+1 to avoid frequency overshoot */
-    while( ( MCF_FMPLL_SYNSR & 0x08 ) == 0 )    /* Wait for PLL to lock */
-        ;
-    MCF_FMPLL_SYNCR = 0x00080000;       /* Set desired RFD */
-    while( ( MCF_FMPLL_SYNSR & 0x08 ) == 0 )    /* Wait for PLL to lock */
-        ;
-}
-
-
-/*********************************************************************
-* init_ipsbar - Internal Peripheral System Base Address (IPSBAR)     *
-**********************************************************************/
-static void
-init_ipsbar( void )
-{
-    extern int  __SRAM;
-
-    /* Base address of internal peripherals (IPSBAR) = 0x40000000
-
-       Note: Processor powers up with IPS base address = 0x40000000
-       Write to IPS base + 0x00000000 to set new value
-     */
-    *( vuint32 * ) 0x40000000 = ( vuint32 ) __IPSBAR + 1;
-
-    /* Configure RAMBAR in SCM module and allow dual-ported access. */
-    MCF_SCM_RAMBAR = ( uint32 ) &__SRAM | MCF_SCM_RAMBAR_BDE;
-}
-
-/*********************************************************************
-* init_chip_selects - Chip Select Module                             *
-**********************************************************************/
-static void
-init_chip_selects( void )
-{
-    extern void __FLASH;
-    uint32 FLASH_ADDR = (uint32)&__FLASH;
-
-    /* Chip Select 0 - External Flash */
-    MCF_CS_CSAR0 = MCF_CS_CSAR_BA( FLASH_ADDR );
-    MCF_CS_CSCR0 = ( 0
-                     | MCF_CS_CSCR_IWS( 6 )
-                     | MCF_CS_CSCR_AA | MCF_CS_CSCR_PS_16 );
-    MCF_CS_CSMR0 = MCF_CS_CSMR_BAM_2M | MCF_CS_CSMR_V;
-
-    /* Chip Select 1 disabled (CSMR1[V] = 0) */
-    MCF_CS_CSAR1 = 0;
-    MCF_CS_CSMR1 = 0;
-    MCF_CS_CSCR1 = 0;
-
-    /* Chip Select 2 disabled (CSMR2[V] = 0) */
-    MCF_CS_CSAR2 = 0;
-    MCF_CS_CSMR2 = 0;
-    MCF_CS_CSCR2 = 0;
-
-    /* Chip Select 3 disabled (CSMR3[V] = 0) */
-    MCF_CS_CSAR3 = 0;
-    MCF_CS_CSMR3 = 0;
-    MCF_CS_CSCR3 = 0;
-
-    /* Chip Select 4 disabled (CSMR4[V] = 0) */
-    MCF_CS_CSAR4 = 0;
-    MCF_CS_CSMR4 = 0;
-    MCF_CS_CSCR4 = 0;
-
-    /* Chip Select 5 disabled (CSMR5[V] = 0) */
-    MCF_CS_CSAR5 = 0;
-    MCF_CS_CSMR5 = 0;
-    MCF_CS_CSCR5 = 0;
-
-    /* Chip Select 6 disabled (CSMR6[V] = 0) */
-    MCF_CS_CSAR6 = 0;
-    MCF_CS_CSMR6 = 0;
-    MCF_CS_CSCR6 = 0;
-
-    /* Chip Select 7 disabled (CSMR7[V] = 0) */
-    MCF_CS_CSAR7 = 0;
-    MCF_CS_CSMR7 = 0;
-    MCF_CS_CSCR7 = 0;
-}
-
-/*********************************************************************
-* init_bus_config - Internal Bus Arbitration                         *
-**********************************************************************/
-static void
-init_bus_config( void )
-{
-
-    /* Use round robin arbitration scheme
-       Assigned priorities (highest first):
-       Ethernet
-       DMA Controller
-       ColdFire Core
-       DMA bandwidth control disabled
-       Park on last active bus master
-     */
-    MCF_SCM_MPARK =
-        MCF_SCM_MPARK_M3_PRTY( 0x3 ) | MCF_SCM_MPARK_M2_PRTY( 0x2 ) |
-        MCF_SCM_MPARK_M1_PRTY( 0x1 );
-}
-
-/*********************************************************************
-* init_cache - Instruction/Data Cache                                *
-**********************************************************************/
-static void
-init_cache( void )
-{
-    /* Configured as split cache: 4 KByte instruction cache and 4 Kbyte data cache
-       ACR0: Don't cache accesses to 16 MB memory region at address $20000000
-       ACR1: Don't cache accesses to 1 GB memory region at address $40000000
-       CACR: Cache accesses to the rest of memory
-    */
-    asm("move.l   #0x80000000,%d0");
-    asm("movec    %d0,%CACR");
-    asm("move.l   #0x2000c040,%d0");
-    asm("movec    %d0,%ACR0");
-    asm("move.l   #0x403fc040,%d0");
-    asm("movec    %d0,%ACR1");
-
-    /* Instruction/Data cache disabled. */
-    //asm( "move.l   #0x00000000, %d0" );
-    //asm( "movec    %d0,%cacr" );
-}
-
-/*********************************************************************
-* init_eport - Edge Port Module (EPORT)                              *
-**********************************************************************/
-static void
-init_eport( void )
-{
-
-    /* Pins 1-7 configured as GPIO inputs */
-    MCF_EPORT_EPPAR = 0;
-    MCF_EPORT_EPDDR = 0;
-    MCF_EPORT_EPIER = 0;
-}
-
-/*********************************************************************
-* init_flexcan - FlexCAN Module                                      *
-**********************************************************************/
-static void
-init_flexcan( void )
-{
-
-    /* FlexCAN controller 0 disabled (CANMCR0[MDIS]=1) */
-    MCF_CAN_IMASK0 = 0;
-    MCF_CAN_RXGMASK0 = MCF_CAN_RXGMASK_MI( 0x1fffffff );
-    MCF_CAN_RX14MASK0 = MCF_CAN_RX14MASK_MI( 0x1fffffff );
-    MCF_CAN_RX15MASK0 = MCF_CAN_RX15MASK_MI( 0x1fffffff );
-    MCF_CAN_CANCTRL0 = 0;
-    MCF_CAN_CANMCR0 =
-        MCF_CAN_CANMCR_MDIS | MCF_CAN_CANMCR_FRZ | MCF_CAN_CANMCR_HALT |
-        MCF_CAN_CANMCR_SUPV | MCF_CAN_CANMCR_MAXMB( 0xf );
-
-    /* FlexCAN controller 1 disabled (CANMCR1[MDIS]=1) */
-    MCF_CAN_IMASK1 = 0;
-    MCF_CAN_RXGMASK1 = MCF_CAN_RXGMASK_MI( 0x1fffffff );
-    MCF_CAN_RX14MASK1 = MCF_CAN_RX14MASK_MI( 0x1fffffff );
-    MCF_CAN_RX15MASK1 = MCF_CAN_RX15MASK_MI( 0x1fffffff );
-    MCF_CAN_CANCTRL1 = 0;
-    MCF_CAN_CANMCR1 =
-        MCF_CAN_CANMCR_MDIS | MCF_CAN_CANMCR_FRZ | MCF_CAN_CANMCR_HALT |
-        MCF_CAN_CANMCR_SUPV | MCF_CAN_CANMCR_MAXMB( 0xf );
-}
-
-/*********************************************************************
-* init_power_management - Power Management                           *
-**********************************************************************/
-static void
-init_power_management( void )
-{
-
-    /* On executing STOP instruction, processor enters RUN mode
-       Mode is exited when an interrupt of level 1 or higher is received
-     */
-    MCF_SCM_LPICR = MCF_SCM_LPICR_ENBSTOP;
-    MCF_CCM_LPCR = 0;
-}
-
-/*********************************************************************
-* init_sdram_controller - SDRAM Controller                           *
-**********************************************************************/
-static void
-init_sdram_controller( void )
-{
-    extern void __SDRAM;
-    uint32 SDRAM_ADDR = (uint32)&__SDRAM;
-    int             i;
-
-
-    /*
-     * Check to see if the SDRAM has already been initialized
-     * by a run control tool
-     */
-    if( !( MCF_SDRAMC_DACR0 & MCF_SDRAMC_DACR0_RE ) )
-    {
-        /* Initialize DRAM Control Register: DCR */
-        MCF_SDRAMC_DCR = ( MCF_SDRAMC_DCR_RTIM( 1 ) |
-                           MCF_SDRAMC_DCR_RC( ( 15 * FSYS_2 ) >> 4 ) );
-
-        /* Initialize DACR0 */
-        MCF_SDRAMC_DACR0 = ( MCF_SDRAMC_DACR0_BA( SDRAM_ADDR >> 18UL ) |
-                             MCF_SDRAMC_DACR0_CASL( 1 ) |
-                             MCF_SDRAMC_DACR0_CBM( 3 ) |
-                             MCF_SDRAMC_DACR0_PS( 0 ) );
-
-        /* Initialize DMR0 */
-        MCF_SDRAMC_DMR0 = ( MCF_SDRAMC_DMR_BAM_16M | MCF_SDRAMC_DMR0_V );
-
-        /* Set IP (bit 3) in DACR */
-        MCF_SDRAMC_DACR0 |= MCF_SDRAMC_DACR0_IP;
-
-        /* Wait 30ns to allow banks to precharge */
-        for( i = 0; i < 5; i++ )
-        {
-            asm volatile    ( " nop" );
-        }
-        /* Write to this block to initiate precharge */
-        *( uint32 * ) ( SDRAM_ADDR ) = 0xA5A59696;
-
-        /* Set RE (bit 15) in DACR */
-        MCF_SDRAMC_DACR0 |= MCF_SDRAMC_DACR0_RE;
-
-        /* Wait for at least 8 auto refresh cycles to occur */
-        for( i = 0; i < 2000; i++ )
-        {
-            asm volatile    ( "nop" );
-        }
-        /* Finish the configuration by issuing the IMRS. */
-        MCF_SDRAMC_DACR0 |= MCF_SDRAMC_DACR0_MRS;
-
-        /* Write to the SDRAM Mode Register */
-        *( uint32 * ) ( SDRAM_ADDR + 0x400 ) = 0xA5A59696;
-    }
-}
-
-/*********************************************************************
-* init_dma_timers - DMA Timer Modules                                *
-**********************************************************************/
-static void
-init_dma_timers( void )
-{
-
-    /* DMA Timer 0 disabled (DTMR0[RST] = 0) */
-    MCF_TIMER_DTMR0 = 0;
-    MCF_TIMER_DTXMR0 = 0;
-    MCF_TIMER_DTRR0 = 0xffffffff;
-
-    /* DMA Timer 1 disabled (DTMR1[RST] = 0) */
-    MCF_TIMER_DTMR1 = 0;
-    MCF_TIMER_DTXMR1 = 0;
-    MCF_TIMER_DTRR1 = 0xffffffff;
-
-    /* DMA Timer 2 disabled (DTMR2[RST] = 0) */
-    MCF_TIMER_DTMR2 = 0;
-    MCF_TIMER_DTXMR2 = 0;
-    MCF_TIMER_DTRR2 = 0xffffffff;
-
-    /* DMA Timer 3 disabled (DTMR3[RST] = 0) */
-    MCF_TIMER_DTMR3 = 0;
-    MCF_TIMER_DTXMR3 = 0;
-    MCF_TIMER_DTRR3 = 0xffffffff;
-}
-
-/**********************************************************************
-* init_interrupt_timers - Programmable Interrupt Timer (PIT) Modules  *
-***********************************************************************/
-static void
-init_interrupt_timers( void )
-{
-
-    /* PIT0 disabled (PCSR0[EN]=0) */
-    MCF_PIT_PCSR0 = 0;
-
-    /* PIT1 disabled (PCSR1[EN]=0) */
-    MCF_PIT_PCSR1 = 0;
-
-    /* PIT2 disabled (PCSR2[EN]=0) */
-    MCF_PIT_PCSR2 = 0;
-
-    /* PIT3 disabled (PCSR3[EN]=0) */
-    MCF_PIT_PCSR3 = 0;
-}
-
-/*********************************************************************
-* init_watchdog_timers - Watchdog Timer Modules                      *
-**********************************************************************/
-static void
-init_watchdog_timers( void )
-{
-
-    /* Watchdog Timer disabled (WCR[EN]=0)
-       NOTE: WCR and WMR cannot be written again until after the
-       processor is reset.
-     */
-    MCF_WTM_WCR = MCF_WTM_WCR_WAIT | MCF_WTM_WCR_DOZE | MCF_WTM_WCR_HALTED;
-    MCF_WTM_WMR = 0xffff;
-
-    /* Core Watchdog Timer disabled (CWCR[CWE]=0) */
-    MCF_SCM_CWCR = 0;
-}
-
-/*********************************************************************
-* init_interrupt_controller - Interrupt Controller                   *
-**********************************************************************/
-static void
-init_interrupt_controller( void )
-{
-
-    /* Configured interrupt sources in order of priority...
-       Level 7:  External interrupt /IRQ7, (initially masked)
-       Level 6:  External interrupt /IRQ6, (initially masked)
-       Level 5:  External interrupt /IRQ5, (initially masked)
-       Level 4:  External interrupt /IRQ4, (initially masked)
-       Level 3:  External interrupt /IRQ3, (initially masked)
-       Level 2:  External interrupt /IRQ2, (initially masked)
-       Level 1:  External interrupt /IRQ1, (initially masked)
-     */
-    MCF_INTC0_ICR1 = 0;
-    MCF_INTC0_ICR2 = 0;
-    MCF_INTC0_ICR3 = 0;
-    MCF_INTC0_ICR4 = 0;
-    MCF_INTC0_ICR5 = 0;
-    MCF_INTC0_ICR6 = 0;
-    MCF_INTC0_ICR7 = 0;
-    MCF_INTC0_ICR8 = 0;
-    MCF_INTC0_ICR9 = 0;
-    MCF_INTC0_ICR10 = 0;
-    MCF_INTC0_ICR11 = 0;
-    MCF_INTC0_ICR12 = 0;
-    MCF_INTC0_ICR13 = 0;
-    MCF_INTC0_ICR14 = 0;
-    MCF_INTC0_ICR15 = 0;
-    MCF_INTC0_ICR17 = 0;
-    MCF_INTC0_ICR18 = 0;
-    MCF_INTC0_ICR19 = 0;
-    MCF_INTC0_ICR20 = 0;
-    MCF_INTC0_ICR21 = 0;
-    MCF_INTC0_ICR22 = 0;
-    MCF_INTC0_ICR23 = 0;
-    MCF_INTC0_ICR24 = 0;
-    MCF_INTC0_ICR25 = 0;
-    MCF_INTC0_ICR26 = 0;
-    MCF_INTC0_ICR27 = 0;
-    MCF_INTC0_ICR28 = 0;
-    MCF_INTC0_ICR29 = 0;
-    MCF_INTC0_ICR30 = 0;
-    MCF_INTC0_ICR31 = 0;
-    MCF_INTC0_ICR32 = 0;
-    MCF_INTC0_ICR33 = 0;
-    MCF_INTC0_ICR34 = 0;
-    MCF_INTC0_ICR35 = 0;
-    MCF_INTC0_ICR36 = 0;
-    MCF_INTC0_ICR37 = 0;
-    MCF_INTC0_ICR38 = 0;
-    MCF_INTC0_ICR39 = 0;
-    MCF_INTC0_ICR40 = 0;
-    MCF_INTC0_ICR41 = 0;
-    MCF_INTC0_ICR42 = 0;
-    MCF_INTC0_ICR43 = 0;
-    MCF_INTC0_ICR44 = 0;
-    MCF_INTC0_ICR45 = 0;
-    MCF_INTC0_ICR46 = 0;
-    MCF_INTC0_ICR47 = 0;
-    MCF_INTC0_ICR48 = 0;
-    MCF_INTC0_ICR49 = 0;
-    MCF_INTC0_ICR50 = 0;
-    MCF_INTC0_ICR51 = 0;
-    MCF_INTC0_ICR52 = 0;
-    MCF_INTC0_ICR53 = 0;
-    MCF_INTC0_ICR54 = 0;
-    MCF_INTC0_ICR55 = 0;
-    MCF_INTC0_ICR56 = 0;
-    MCF_INTC0_ICR57 = 0;
-    MCF_INTC0_ICR58 = 0;
-    MCF_INTC0_ICR59 = 0;
-    MCF_INTC0_ICR60 = 0;
-    MCF_INTC1_ICR8 = 0;
-    MCF_INTC1_ICR9 = 0;
-    MCF_INTC1_ICR10 = 0;
-    MCF_INTC1_ICR11 = 0;
-    MCF_INTC1_ICR12 = 0;
-    MCF_INTC1_ICR13 = 0;
-    MCF_INTC1_ICR14 = 0;
-    MCF_INTC1_ICR15 = 0;
-    MCF_INTC1_ICR16 = 0;
-    MCF_INTC1_ICR17 = 0;
-    MCF_INTC1_ICR18 = 0;
-    MCF_INTC1_ICR19 = 0;
-    MCF_INTC1_ICR20 = 0;
-    MCF_INTC1_ICR21 = 0;
-    MCF_INTC1_ICR22 = 0;
-    MCF_INTC1_ICR23 = 0;
-    MCF_INTC1_ICR24 = 0;
-    MCF_INTC1_ICR25 = 0;
-    MCF_INTC1_ICR27 = 0;
-    MCF_INTC1_ICR28 = 0;
-    MCF_INTC1_ICR29 = 0;
-    MCF_INTC1_ICR30 = 0;
-    MCF_INTC1_ICR31 = 0;
-    MCF_INTC1_ICR32 = 0;
-    MCF_INTC1_ICR33 = 0;
-    MCF_INTC1_ICR34 = 0;
-    MCF_INTC1_ICR35 = 0;
-    MCF_INTC1_ICR36 = 0;
-    MCF_INTC1_ICR37 = 0;
-    MCF_INTC1_ICR38 = 0;
-    MCF_INTC1_ICR39 = 0;
-    MCF_INTC1_ICR40 = 0;
-    MCF_INTC1_ICR41 = 0;
-    MCF_INTC1_ICR42 = 0;
-    MCF_INTC1_ICR59 = 0;
-    MCF_INTC0_IMRH = 0xffffffff;
-    MCF_INTC0_IMRL =
-        MCF_INTC0_IMRL_INT_MASK31 | MCF_INTC0_IMRL_INT_MASK30 |
-        MCF_INTC0_IMRL_INT_MASK29 | MCF_INTC0_IMRL_INT_MASK28 |
-        MCF_INTC0_IMRL_INT_MASK27 | MCF_INTC0_IMRL_INT_MASK26 |
-        MCF_INTC0_IMRL_INT_MASK25 | MCF_INTC0_IMRL_INT_MASK24 |
-        MCF_INTC0_IMRL_INT_MASK23 | MCF_INTC0_IMRL_INT_MASK22 |
-        MCF_INTC0_IMRL_INT_MASK21 | MCF_INTC0_IMRL_INT_MASK20 |
-        MCF_INTC0_IMRL_INT_MASK19 | MCF_INTC0_IMRL_INT_MASK18 |
-        MCF_INTC0_IMRL_INT_MASK17 | MCF_INTC0_IMRL_INT_MASK16 |
-        MCF_INTC0_IMRL_INT_MASK15 | MCF_INTC0_IMRL_INT_MASK14 |
-        MCF_INTC0_IMRL_INT_MASK13 | MCF_INTC0_IMRL_INT_MASK12 |
-        MCF_INTC0_IMRL_INT_MASK11 | MCF_INTC0_IMRL_INT_MASK10 |
-        MCF_INTC0_IMRL_INT_MASK9 | MCF_INTC0_IMRL_INT_MASK8 |
-        MCF_INTC0_IMRL_INT_MASK7 | MCF_INTC0_IMRL_INT_MASK6 |
-        MCF_INTC0_IMRL_INT_MASK5 | MCF_INTC0_IMRL_INT_MASK4 |
-        MCF_INTC0_IMRL_INT_MASK3 | MCF_INTC0_IMRL_INT_MASK2 |
-        MCF_INTC0_IMRL_INT_MASK1;
-    MCF_INTC1_IMRH = 0xffffffff;
-    MCF_INTC1_IMRL =
-        MCF_INTC1_IMRL_INT_MASK31 | MCF_INTC1_IMRL_INT_MASK30 |
-        MCF_INTC1_IMRL_INT_MASK29 | MCF_INTC1_IMRL_INT_MASK28 |
-        MCF_INTC1_IMRL_INT_MASK27 | MCF_INTC1_IMRL_INT_MASK26 |
-        MCF_INTC1_IMRL_INT_MASK25 | MCF_INTC1_IMRL_INT_MASK24 |
-        MCF_INTC1_IMRL_INT_MASK23 | MCF_INTC1_IMRL_INT_MASK22 |
-        MCF_INTC1_IMRL_INT_MASK21 | MCF_INTC1_IMRL_INT_MASK20 |
-        MCF_INTC1_IMRL_INT_MASK19 | MCF_INTC1_IMRL_INT_MASK18 |
-        MCF_INTC1_IMRL_INT_MASK17 | MCF_INTC1_IMRL_INT_MASK16 |
-        MCF_INTC1_IMRL_INT_MASK15 | MCF_INTC1_IMRL_INT_MASK14 |
-        MCF_INTC1_IMRL_INT_MASK13 | MCF_INTC1_IMRL_INT_MASK12 |
-        MCF_INTC1_IMRL_INT_MASK11 | MCF_INTC1_IMRL_INT_MASK10 |
-        MCF_INTC1_IMRL_INT_MASK9 | MCF_INTC1_IMRL_INT_MASK8 |
-        MCF_INTC1_IMRL_INT_MASK7 | MCF_INTC1_IMRL_INT_MASK6 |
-        MCF_INTC1_IMRL_INT_MASK5 | MCF_INTC1_IMRL_INT_MASK4 |
-        MCF_INTC1_IMRL_INT_MASK3 | MCF_INTC1_IMRL_INT_MASK2 |
-        MCF_INTC1_IMRL_INT_MASK1;
-}
-
-/*********************************************************************
-* init_pin_assignments - Pin Assignment and General Purpose I/O      *
-**********************************************************************/
-static void
-init_pin_assignments( void )
-{
-
-    /* Pin assignments for port ADDR
-       Pins are all GPIO inputs
-     */
-    MCF_GPIO_PDDR_APDDR = 0;
-    MCF_GPIO_PAR_AD = MCF_GPIO_PAR_AD_PAR_ADDR23
-        | MCF_GPIO_PAR_AD_PAR_ADDR22
-        | MCF_GPIO_PAR_AD_PAR_ADDR21 | MCF_GPIO_PAR_AD_PAR_DATAL;
-
-    /* Pin assignments for ports DATAH and DATAL
-       Pins are all GPIO inputs
-     */
-    MCF_GPIO_PDDR_DATAH = 0;
-    MCF_GPIO_PDDR_DATAL = 0;
-
-    /* Pin assignments for port BUSCTL
-       Pin /OE        : External bus output enable, /OE
-       Pin /TA        : External bus transfer acknowledge, /TA
-       Pin /TEA       : External bus transfer error acknowledge, /TEA
-       Pin R/W        : External bus read/write indication, R/W
-       Pin TSIZ1      : External bus transfer size TSIZ1 or DMA acknowledge /DACK1
-       Pin TSIZ0      : External bus transfer size TSIZ0 or DMA acknowledge /DACK0
-       Pin /TS        : External bus transfer start, /TS
-       Pin /TIP       : External bus transfer in progess, /TIP
-     */
-    MCF_GPIO_PDDR_BUSCTL = 0;
-    MCF_GPIO_PAR_BUSCTL =
-        MCF_GPIO_PAR_BUSCTL_PAR_OE | MCF_GPIO_PAR_BUSCTL_PAR_TA |
-        MCF_GPIO_PAR_BUSCTL_PAR_TEA( 0x3 ) | MCF_GPIO_PAR_BUSCTL_PAR_RWB |
-        MCF_GPIO_PAR_BUSCTL_PAR_TSIZ1 | MCF_GPIO_PAR_BUSCTL_PAR_TSIZ0 |
-        MCF_GPIO_PAR_BUSCTL_PAR_TS( 0x3 ) |
-        MCF_GPIO_PAR_BUSCTL_PAR_TIP( 0x3 );
-
-    /* Pin assignments for port BS
-       Pin /BS3       : External byte strobe /BS3
-       Pin /BS2       : External byte strobe /BS2
-       Pin /BS1       : External byte strobe /BS1
-       Pin /BS0       : External byte strobe /BS0
-     */
-    MCF_GPIO_PDDR_BS = 0;
-    MCF_GPIO_PAR_BS =
-        MCF_GPIO_PAR_BS_PAR_BS3 | MCF_GPIO_PAR_BS_PAR_BS2 |
-        MCF_GPIO_PAR_BS_PAR_BS1 | MCF_GPIO_PAR_BS_PAR_BS0;
-
-    /* Pin assignments for port CS
-       Pin /CS7       : Chip select /CS7
-       Pin /CS6       : Chip select /CS6
-       Pin /CS5       : Chip select /CS5
-       Pin /CS4       : Chip select /CS4
-       Pin /CS3       : Chip select /CS3
-       Pin /CS2       : Chip select /CS2
-       Pin /CS1       : Chip select /CS1
-     */
-    MCF_GPIO_PDDR_CS = 0;
-    MCF_GPIO_PAR_CS =
-        MCF_GPIO_PAR_CS_PAR_CS7 | MCF_GPIO_PAR_CS_PAR_CS6 |
-        MCF_GPIO_PAR_CS_PAR_CS5 | MCF_GPIO_PAR_CS_PAR_CS4 |
-        MCF_GPIO_PAR_CS_PAR_CS3 | MCF_GPIO_PAR_CS_PAR_CS2 |
-        MCF_GPIO_PAR_CS_PAR_CS1;
-
-    /* Pin assignments for port SDRAM
-       Pin /SD_WE     : SDRAM controller /SD_WE
-       Pin /SD_SCAS   : SDRAM controller /SD_SCAS
-       Pin /SD_SRAS   : SDRAM controller /SD_SRAS
-       Pin /SD_SCKE   : SDRAM controller /SD_SCKE
-       Pin /SD_CS1    : SDRAM controller /SD_CS1
-       Pin /SD_CS0    : SDRAM controller /SD_CS0
-     */
-    MCF_GPIO_PDDR_SDRAM = 0;
-    MCF_GPIO_PAR_SDRAM =
-        MCF_GPIO_PAR_SDRAM_PAR_SDWE | MCF_GPIO_PAR_SDRAM_PAR_SCAS |
-        MCF_GPIO_PAR_SDRAM_PAR_SRAS | MCF_GPIO_PAR_SDRAM_PAR_SCKE |
-        MCF_GPIO_PAR_SDRAM_PAR_SDCS1 | MCF_GPIO_PAR_SDRAM_PAR_SDCS0;
-
-    /* Pin assignments for port FECI2C
-       Pins are all GPIO inputs
-     */
-    MCF_GPIO_PDDR_FECI2C = 0;
-    MCF_GPIO_PAR_FECI2C =
-        MCF_GPIO_PAR_FECI2C_PAR_EMDC_FEC | MCF_GPIO_PAR_FECI2C_PAR_EMDIO_FEC;
-
-    /* Pin assignments for port UARTL
-       Pins are all GPIO inputs
-     */
-    MCF_GPIO_PDDR_UARTL = 0;
-    MCF_GPIO_PAR_UART = 0;
-
-    /* Pin assignments for port UARTH
-       Pin U2TXD      : GPIO input
-       Pin U2RXD      : GPIO input
-       Pin /IRQ2      : Interrupt request /IRQ2 or GPIO
-     */
-    MCF_GPIO_PDDR_UARTH = 0;
-
-    /* Pin assignments for port QSPI
-       Pins are all GPIO inputs
-     */
-    MCF_GPIO_PDDR_QSPI = 0;
-    MCF_GPIO_PAR_QSPI = 0;
-
-    /* Pin assignments for port TIMER
-       Pins are all GPIO inputs
-     */
-    MCF_GPIO_PDDR_TIMER = 0;
-    MCF_GPIO_PAR_TIMER = 0;
-
-    /* Pin assignments for port ETPU
-       Pins are all GPIO inputs
-     */
-    MCF_GPIO_PDDR_ETPU = 0;
-    MCF_GPIO_PAR_ETPU = 0;
-}
+       with commercial development and support options.\r
+    ***************************************************************************\r
+*/\r
+\r
+#include "mcf5xxx.h"\r
+#include "mcf523x.h"\r
+\r
+/* Function prototypes */\r
+void            init_main( void );\r
+static void     disable_interrupts( void );\r
+static void     disable_watchdog_timer( void );\r
+static void     disable_cache( void );\r
+static void     init_ipsbar( void );\r
+static void     init_basics( void );\r
+static void     init_clock_config( void );\r
+static void     init_chip_selects( void );\r
+static void     init_bus_config( void );\r
+static void     init_cache( void );\r
+static void     init_eport( void );\r
+static void     init_flexcan( void );\r
+static void     init_power_management( void );\r
+static void     init_dma_timers( void );\r
+static void     init_interrupt_timers( void );\r
+static void     init_watchdog_timers( void );\r
+static void     init_pin_assignments( void );\r
+static void     init_sdram_controller( void );\r
+static void     init_interrupt_controller( void );\r
+\r
+\r
+/*********************************************************************\r
+* init_main - Main entry point for initialisation code               *\r
+**********************************************************************/\r
+void\r
+init_main( void )\r
+{\r
+\r
+    /* Initialise base address of peripherals, VBR, etc */\r
+    init_ipsbar(  );\r
+    init_basics(  );\r
+    init_clock_config(  );\r
+\r
+    /* Disable interrupts, watchdog timer, cache */\r
+    disable_interrupts(  );\r
+    disable_watchdog_timer(  );\r
+    disable_cache(  );\r
+\r
+    /* Initialise individual modules */\r
+    init_chip_selects(  );\r
+    init_bus_config(  );\r
+    init_cache(  );\r
+    init_eport(  );\r
+    init_flexcan(  );\r
+    init_power_management(  );\r
+    init_dma_timers(  );\r
+    init_interrupt_timers(  );\r
+    init_watchdog_timers(  );\r
+    init_pin_assignments(  );\r
+    init_sdram_controller(  );\r
+\r
+    /* Initialise interrupt controller */\r
+    init_interrupt_controller(  );\r
+}\r
+\r
+/*********************************************************************\r
+* disable_interrupts - Disable all interrupt sources                 *\r
+**********************************************************************/\r
+static void\r
+disable_interrupts( void )\r
+{\r
+    vuint8         *p;\r
+    int             i;\r
+\r
+\r
+    /* Set ICR008-ICR063 to 0x0 */\r
+    p = ( vuint8 * ) & MCF_INTC0_ICR8;\r
+    for( i = 8; i <= 63; i++ )\r
+        *p++ = 0x0;\r
+\r
+    /* Set ICR108-ICR163 to 0x0 */\r
+    p = ( vuint8 * ) & MCF_INTC1_ICR8;\r
+    for( i = 108; i <= 163; i++ )\r
+        *p++ = 0x0;\r
+}\r
+\r
+\r
+/*********************************************************************\r
+* disable_watchdog_timer - Disable system watchdog timer             *\r
+**********************************************************************/\r
+static void\r
+disable_watchdog_timer( void )\r
+{\r
+\r
+    /* Disable Core Watchdog Timer */\r
+    MCF_SCM_CWCR = 0;\r
+}\r
+\r
+/*********************************************************************\r
+* disable_cache - Disable and invalidate cache                       *\r
+**********************************************************************/\r
+static void\r
+disable_cache( void )\r
+{\r
+    asm ( "move.l   #0x01000000, %d0" );\r
+    asm ( "movec    %d0, %CACR" );\r
+}\r
+\r
+/*********************************************************************\r
+* init_basics - Configuration Information & VBR                      *\r
+**********************************************************************/\r
+static void\r
+init_basics( void )\r
+{\r
+    int             i;\r
+    extern uint32   __RAMVEC[];\r
+    extern uint32   __ROMVEC[];\r
+\r
+    /* Transfer size not driven on SIZ[1:0] pins during external cycles\r
+       Processor Status (PST) and Debug Data (DDATA) functions disabled\r
+       Bus monitor disabled\r
+       Output pads configured for full strength\r
+     */\r
+    MCF_CCM_CCR = ( 0x1 << 15 ) | MCF_CCM_CCR_BME;\r
+\r
+    /* Set up RAM vectors */\r
+    for( i = 0; i < 256; i++ )\r
+\r
+    {\r
+        __RAMVEC[i] = __ROMVEC[i];\r
+    }\r
+    asm( "move.l   %0,%%d0": :"i"( __RAMVEC ) );\r
+    asm( "movec    %d0,%vbr" );\r
+}\r
+\r
+\r
+/*********************************************************************\r
+* init_clock_config - Clock Module                                   *\r
+**********************************************************************/\r
+static void\r
+init_clock_config( void )\r
+{\r
+    /* Clock module uses normal PLL mode with 25.0000 MHz external reference (Fref)\r
+       MFD = 0, RFD = 1\r
+       Bus clock frequency = 25.00 MHz\r
+       Processor clock frequency = 2 x bus clock = 50.00 MHz\r
+       Frequency Modulation disabled\r
+       Loss of clock detection disabled\r
+       Reset/Interrupt on loss of lock disabled\r
+     */\r
+    MCF_FMPLL_SYNCR = 0x00100000;       /* Set RFD=RFD+1 to avoid frequency overshoot */\r
+    while( ( MCF_FMPLL_SYNSR & 0x08 ) == 0 )    /* Wait for PLL to lock */\r
+        ;\r
+    MCF_FMPLL_SYNCR = 0x00080000;       /* Set desired RFD */\r
+    while( ( MCF_FMPLL_SYNSR & 0x08 ) == 0 )    /* Wait for PLL to lock */\r
+        ;\r
+}\r
+\r
+\r
+/*********************************************************************\r
+* init_ipsbar - Internal Peripheral System Base Address (IPSBAR)     *\r
+**********************************************************************/\r
+static void\r
+init_ipsbar( void )\r
+{\r
+    extern int  __SRAM;\r
+\r
+    /* Base address of internal peripherals (IPSBAR) = 0x40000000\r
+\r
+       Note: Processor powers up with IPS base address = 0x40000000\r
+       Write to IPS base + 0x00000000 to set new value\r
+     */\r
+    *( vuint32 * ) 0x40000000 = ( vuint32 ) __IPSBAR + 1;\r
+\r
+    /* Configure RAMBAR in SCM module and allow dual-ported access. */\r
+    MCF_SCM_RAMBAR = ( uint32 ) &__SRAM | MCF_SCM_RAMBAR_BDE;\r
+}\r
+\r
+/*********************************************************************\r
+* init_chip_selects - Chip Select Module                             *\r
+**********************************************************************/\r
+static void\r
+init_chip_selects( void )\r
+{\r
+    extern void __FLASH;\r
+    uint32 FLASH_ADDR = (uint32)&__FLASH;\r
+\r
+    /* Chip Select 0 - External Flash */\r
+    MCF_CS_CSAR0 = MCF_CS_CSAR_BA( FLASH_ADDR );\r
+    MCF_CS_CSCR0 = ( 0\r
+                     | MCF_CS_CSCR_IWS( 6 )\r
+                     | MCF_CS_CSCR_AA | MCF_CS_CSCR_PS_16 );\r
+    MCF_CS_CSMR0 = MCF_CS_CSMR_BAM_2M | MCF_CS_CSMR_V;\r
+\r
+    /* Chip Select 1 disabled (CSMR1[V] = 0) */\r
+    MCF_CS_CSAR1 = 0;\r
+    MCF_CS_CSMR1 = 0;\r
+    MCF_CS_CSCR1 = 0;\r
+\r
+    /* Chip Select 2 disabled (CSMR2[V] = 0) */\r
+    MCF_CS_CSAR2 = 0;\r
+    MCF_CS_CSMR2 = 0;\r
+    MCF_CS_CSCR2 = 0;\r
+\r
+    /* Chip Select 3 disabled (CSMR3[V] = 0) */\r
+    MCF_CS_CSAR3 = 0;\r
+    MCF_CS_CSMR3 = 0;\r
+    MCF_CS_CSCR3 = 0;\r
+\r
+    /* Chip Select 4 disabled (CSMR4[V] = 0) */\r
+    MCF_CS_CSAR4 = 0;\r
+    MCF_CS_CSMR4 = 0;\r
+    MCF_CS_CSCR4 = 0;\r
+\r
+    /* Chip Select 5 disabled (CSMR5[V] = 0) */\r
+    MCF_CS_CSAR5 = 0;\r
+    MCF_CS_CSMR5 = 0;\r
+    MCF_CS_CSCR5 = 0;\r
+\r
+    /* Chip Select 6 disabled (CSMR6[V] = 0) */\r
+    MCF_CS_CSAR6 = 0;\r
+    MCF_CS_CSMR6 = 0;\r
+    MCF_CS_CSCR6 = 0;\r
+\r
+    /* Chip Select 7 disabled (CSMR7[V] = 0) */\r
+    MCF_CS_CSAR7 = 0;\r
+    MCF_CS_CSMR7 = 0;\r
+    MCF_CS_CSCR7 = 0;\r
+}\r
+\r
+/*********************************************************************\r
+* init_bus_config - Internal Bus Arbitration                         *\r
+**********************************************************************/\r
+static void\r
+init_bus_config( void )\r
+{\r
+\r
+    /* Use round robin arbitration scheme\r
+       Assigned priorities (highest first):\r
+       Ethernet\r
+       DMA Controller\r
+       ColdFire Core\r
+       DMA bandwidth control disabled\r
+       Park on last active bus master\r
+     */\r
+    MCF_SCM_MPARK =\r
+        MCF_SCM_MPARK_M3_PRTY( 0x3 ) | MCF_SCM_MPARK_M2_PRTY( 0x2 ) |\r
+        MCF_SCM_MPARK_M1_PRTY( 0x1 );\r
+}\r
+\r
+/*********************************************************************\r
+* init_cache - Instruction/Data Cache                                *\r
+**********************************************************************/\r
+static void\r
+init_cache( void )\r
+{\r
+    /* Configured as split cache: 4 KByte instruction cache and 4 Kbyte data cache\r
+       ACR0: Don't cache accesses to 16 MB memory region at address $20000000\r
+       ACR1: Don't cache accesses to 1 GB memory region at address $40000000\r
+       CACR: Cache accesses to the rest of memory\r
+    */\r
+    asm("move.l   #0x80000000,%d0");\r
+    asm("movec    %d0,%CACR");\r
+    asm("move.l   #0x2000c040,%d0");\r
+    asm("movec    %d0,%ACR0");\r
+    asm("move.l   #0x403fc040,%d0");\r
+    asm("movec    %d0,%ACR1");\r
+\r
+    /* Instruction/Data cache disabled. */\r
+    //asm( "move.l   #0x00000000, %d0" );\r
+    //asm( "movec    %d0,%cacr" );\r
+}\r
+\r
+/*********************************************************************\r
+* init_eport - Edge Port Module (EPORT)                              *\r
+**********************************************************************/\r
+static void\r
+init_eport( void )\r
+{\r
+\r
+    /* Pins 1-7 configured as GPIO inputs */\r
+    MCF_EPORT_EPPAR = 0;\r
+    MCF_EPORT_EPDDR = 0;\r
+    MCF_EPORT_EPIER = 0;\r
+}\r
+\r
+/*********************************************************************\r
+* init_flexcan - FlexCAN Module                                      *\r
+**********************************************************************/\r
+static void\r
+init_flexcan( void )\r
+{\r
+\r
+    /* FlexCAN controller 0 disabled (CANMCR0[MDIS]=1) */\r
+    MCF_CAN_IMASK0 = 0;\r
+    MCF_CAN_RXGMASK0 = MCF_CAN_RXGMASK_MI( 0x1fffffff );\r
+    MCF_CAN_RX14MASK0 = MCF_CAN_RX14MASK_MI( 0x1fffffff );\r
+    MCF_CAN_RX15MASK0 = MCF_CAN_RX15MASK_MI( 0x1fffffff );\r
+    MCF_CAN_CANCTRL0 = 0;\r
+    MCF_CAN_CANMCR0 =\r
+        MCF_CAN_CANMCR_MDIS | MCF_CAN_CANMCR_FRZ | MCF_CAN_CANMCR_HALT |\r
+        MCF_CAN_CANMCR_SUPV | MCF_CAN_CANMCR_MAXMB( 0xf );\r
+\r
+    /* FlexCAN controller 1 disabled (CANMCR1[MDIS]=1) */\r
+    MCF_CAN_IMASK1 = 0;\r
+    MCF_CAN_RXGMASK1 = MCF_CAN_RXGMASK_MI( 0x1fffffff );\r
+    MCF_CAN_RX14MASK1 = MCF_CAN_RX14MASK_MI( 0x1fffffff );\r
+    MCF_CAN_RX15MASK1 = MCF_CAN_RX15MASK_MI( 0x1fffffff );\r
+    MCF_CAN_CANCTRL1 = 0;\r
+    MCF_CAN_CANMCR1 =\r
+        MCF_CAN_CANMCR_MDIS | MCF_CAN_CANMCR_FRZ | MCF_CAN_CANMCR_HALT |\r
+        MCF_CAN_CANMCR_SUPV | MCF_CAN_CANMCR_MAXMB( 0xf );\r
+}\r
+\r
+/*********************************************************************\r
+* init_power_management - Power Management                           *\r
+**********************************************************************/\r
+static void\r
+init_power_management( void )\r
+{\r
+\r
+    /* On executing STOP instruction, processor enters RUN mode\r
+       Mode is exited when an interrupt of level 1 or higher is received\r
+     */\r
+    MCF_SCM_LPICR = MCF_SCM_LPICR_ENBSTOP;\r
+    MCF_CCM_LPCR = 0;\r
+}\r
+\r
+/*********************************************************************\r
+* init_sdram_controller - SDRAM Controller                           *\r
+**********************************************************************/\r
+static void\r
+init_sdram_controller( void )\r
+{\r
+    extern void __SDRAM;\r
+    uint32 SDRAM_ADDR = (uint32)&__SDRAM;\r
+    int             i;\r
+\r
+\r
+    /*\r
+     * Check to see if the SDRAM has already been initialized\r
+     * by a run control tool\r
+     */\r
+    if( !( MCF_SDRAMC_DACR0 & MCF_SDRAMC_DACR0_RE ) )\r
+    {\r
+        /* Initialize DRAM Control Register: DCR */\r
+        MCF_SDRAMC_DCR = ( MCF_SDRAMC_DCR_RTIM( 1 ) |\r
+                           MCF_SDRAMC_DCR_RC( ( 15 * FSYS_2 ) >> 4 ) );\r
+\r
+        /* Initialize DACR0 */\r
+        MCF_SDRAMC_DACR0 = ( MCF_SDRAMC_DACR0_BA( SDRAM_ADDR >> 18UL ) |\r
+                             MCF_SDRAMC_DACR0_CASL( 1 ) |\r
+                             MCF_SDRAMC_DACR0_CBM( 3 ) |\r
+                             MCF_SDRAMC_DACR0_PS( 0 ) );\r
+\r
+        /* Initialize DMR0 */\r
+        MCF_SDRAMC_DMR0 = ( MCF_SDRAMC_DMR_BAM_16M | MCF_SDRAMC_DMR0_V );\r
+\r
+        /* Set IP (bit 3) in DACR */\r
+        MCF_SDRAMC_DACR0 |= MCF_SDRAMC_DACR0_IP;\r
+\r
+        /* Wait 30ns to allow banks to precharge */\r
+        for( i = 0; i < 5; i++ )\r
+        {\r
+            asm volatile    ( " nop" );\r
+        }\r
+        /* Write to this block to initiate precharge */\r
+        *( uint32 * ) ( SDRAM_ADDR ) = 0xA5A59696;\r
+\r
+        /* Set RE (bit 15) in DACR */\r
+        MCF_SDRAMC_DACR0 |= MCF_SDRAMC_DACR0_RE;\r
+\r
+        /* Wait for at least 8 auto refresh cycles to occur */\r
+        for( i = 0; i < 2000; i++ )\r
+        {\r
+            asm volatile    ( "nop" );\r
+        }\r
+        /* Finish the configuration by issuing the IMRS. */\r
+        MCF_SDRAMC_DACR0 |= MCF_SDRAMC_DACR0_MRS;\r
+\r
+        /* Write to the SDRAM Mode Register */\r
+        *( uint32 * ) ( SDRAM_ADDR + 0x400 ) = 0xA5A59696;\r
+    }\r
+}\r
+\r
+/*********************************************************************\r
+* init_dma_timers - DMA Timer Modules                                *\r
+**********************************************************************/\r
+static void\r
+init_dma_timers( void )\r
+{\r
+\r
+    /* DMA Timer 0 disabled (DTMR0[RST] = 0) */\r
+    MCF_TIMER_DTMR0 = 0;\r
+    MCF_TIMER_DTXMR0 = 0;\r
+    MCF_TIMER_DTRR0 = 0xffffffff;\r
+\r
+    /* DMA Timer 1 disabled (DTMR1[RST] = 0) */\r
+    MCF_TIMER_DTMR1 = 0;\r
+    MCF_TIMER_DTXMR1 = 0;\r
+    MCF_TIMER_DTRR1 = 0xffffffff;\r
+\r
+    /* DMA Timer 2 disabled (DTMR2[RST] = 0) */\r
+    MCF_TIMER_DTMR2 = 0;\r
+    MCF_TIMER_DTXMR2 = 0;\r
+    MCF_TIMER_DTRR2 = 0xffffffff;\r
+\r
+    /* DMA Timer 3 disabled (DTMR3[RST] = 0) */\r
+    MCF_TIMER_DTMR3 = 0;\r
+    MCF_TIMER_DTXMR3 = 0;\r
+    MCF_TIMER_DTRR3 = 0xffffffff;\r
+}\r
+\r
+/**********************************************************************\r
+* init_interrupt_timers - Programmable Interrupt Timer (PIT) Modules  *\r
+***********************************************************************/\r
+static void\r
+init_interrupt_timers( void )\r
+{\r
+\r
+    /* PIT0 disabled (PCSR0[EN]=0) */\r
+    MCF_PIT_PCSR0 = 0;\r
+\r
+    /* PIT1 disabled (PCSR1[EN]=0) */\r
+    MCF_PIT_PCSR1 = 0;\r
+\r
+    /* PIT2 disabled (PCSR2[EN]=0) */\r
+    MCF_PIT_PCSR2 = 0;\r
+\r
+    /* PIT3 disabled (PCSR3[EN]=0) */\r
+    MCF_PIT_PCSR3 = 0;\r
+}\r
+\r
+/*********************************************************************\r
+* init_watchdog_timers - Watchdog Timer Modules                      *\r
+**********************************************************************/\r
+static void\r
+init_watchdog_timers( void )\r
+{\r
+\r
+    /* Watchdog Timer disabled (WCR[EN]=0)\r
+       NOTE: WCR and WMR cannot be written again until after the\r
+       processor is reset.\r
+     */\r
+    MCF_WTM_WCR = MCF_WTM_WCR_WAIT | MCF_WTM_WCR_DOZE | MCF_WTM_WCR_HALTED;\r
+    MCF_WTM_WMR = 0xffff;\r
+\r
+    /* Core Watchdog Timer disabled (CWCR[CWE]=0) */\r
+    MCF_SCM_CWCR = 0;\r
+}\r
+\r
+/*********************************************************************\r
+* init_interrupt_controller - Interrupt Controller                   *\r
+**********************************************************************/\r
+static void\r
+init_interrupt_controller( void )\r
+{\r
+\r
+    /* Configured interrupt sources in order of priority...\r
+       Level 7:  External interrupt /IRQ7, (initially masked)\r
+       Level 6:  External interrupt /IRQ6, (initially masked)\r
+       Level 5:  External interrupt /IRQ5, (initially masked)\r
+       Level 4:  External interrupt /IRQ4, (initially masked)\r
+       Level 3:  External interrupt /IRQ3, (initially masked)\r
+       Level 2:  External interrupt /IRQ2, (initially masked)\r
+       Level 1:  External interrupt /IRQ1, (initially masked)\r
+     */\r
+    MCF_INTC0_ICR1 = 0;\r
+    MCF_INTC0_ICR2 = 0;\r
+    MCF_INTC0_ICR3 = 0;\r
+    MCF_INTC0_ICR4 = 0;\r
+    MCF_INTC0_ICR5 = 0;\r
+    MCF_INTC0_ICR6 = 0;\r
+    MCF_INTC0_ICR7 = 0;\r
+    MCF_INTC0_ICR8 = 0;\r
+    MCF_INTC0_ICR9 = 0;\r
+    MCF_INTC0_ICR10 = 0;\r
+    MCF_INTC0_ICR11 = 0;\r
+    MCF_INTC0_ICR12 = 0;\r
+    MCF_INTC0_ICR13 = 0;\r
+    MCF_INTC0_ICR14 = 0;\r
+    MCF_INTC0_ICR15 = 0;\r
+    MCF_INTC0_ICR17 = 0;\r
+    MCF_INTC0_ICR18 = 0;\r
+    MCF_INTC0_ICR19 = 0;\r
+    MCF_INTC0_ICR20 = 0;\r
+    MCF_INTC0_ICR21 = 0;\r
+    MCF_INTC0_ICR22 = 0;\r
+    MCF_INTC0_ICR23 = 0;\r
+    MCF_INTC0_ICR24 = 0;\r
+    MCF_INTC0_ICR25 = 0;\r
+    MCF_INTC0_ICR26 = 0;\r
+    MCF_INTC0_ICR27 = 0;\r
+    MCF_INTC0_ICR28 = 0;\r
+    MCF_INTC0_ICR29 = 0;\r
+    MCF_INTC0_ICR30 = 0;\r
+    MCF_INTC0_ICR31 = 0;\r
+    MCF_INTC0_ICR32 = 0;\r
+    MCF_INTC0_ICR33 = 0;\r
+    MCF_INTC0_ICR34 = 0;\r
+    MCF_INTC0_ICR35 = 0;\r
+    MCF_INTC0_ICR36 = 0;\r
+    MCF_INTC0_ICR37 = 0;\r
+    MCF_INTC0_ICR38 = 0;\r
+    MCF_INTC0_ICR39 = 0;\r
+    MCF_INTC0_ICR40 = 0;\r
+    MCF_INTC0_ICR41 = 0;\r
+    MCF_INTC0_ICR42 = 0;\r
+    MCF_INTC0_ICR43 = 0;\r
+    MCF_INTC0_ICR44 = 0;\r
+    MCF_INTC0_ICR45 = 0;\r
+    MCF_INTC0_ICR46 = 0;\r
+    MCF_INTC0_ICR47 = 0;\r
+    MCF_INTC0_ICR48 = 0;\r
+    MCF_INTC0_ICR49 = 0;\r
+    MCF_INTC0_ICR50 = 0;\r
+    MCF_INTC0_ICR51 = 0;\r
+    MCF_INTC0_ICR52 = 0;\r
+    MCF_INTC0_ICR53 = 0;\r
+    MCF_INTC0_ICR54 = 0;\r
+    MCF_INTC0_ICR55 = 0;\r
+    MCF_INTC0_ICR56 = 0;\r
+    MCF_INTC0_ICR57 = 0;\r
+    MCF_INTC0_ICR58 = 0;\r
+    MCF_INTC0_ICR59 = 0;\r
+    MCF_INTC0_ICR60 = 0;\r
+    MCF_INTC1_ICR8 = 0;\r
+    MCF_INTC1_ICR9 = 0;\r
+    MCF_INTC1_ICR10 = 0;\r
+    MCF_INTC1_ICR11 = 0;\r
+    MCF_INTC1_ICR12 = 0;\r
+    MCF_INTC1_ICR13 = 0;\r
+    MCF_INTC1_ICR14 = 0;\r
+    MCF_INTC1_ICR15 = 0;\r
+    MCF_INTC1_ICR16 = 0;\r
+    MCF_INTC1_ICR17 = 0;\r
+    MCF_INTC1_ICR18 = 0;\r
+    MCF_INTC1_ICR19 = 0;\r
+    MCF_INTC1_ICR20 = 0;\r
+    MCF_INTC1_ICR21 = 0;\r
+    MCF_INTC1_ICR22 = 0;\r
+    MCF_INTC1_ICR23 = 0;\r
+    MCF_INTC1_ICR24 = 0;\r
+    MCF_INTC1_ICR25 = 0;\r
+    MCF_INTC1_ICR27 = 0;\r
+    MCF_INTC1_ICR28 = 0;\r
+    MCF_INTC1_ICR29 = 0;\r
+    MCF_INTC1_ICR30 = 0;\r
+    MCF_INTC1_ICR31 = 0;\r
+    MCF_INTC1_ICR32 = 0;\r
+    MCF_INTC1_ICR33 = 0;\r
+    MCF_INTC1_ICR34 = 0;\r
+    MCF_INTC1_ICR35 = 0;\r
+    MCF_INTC1_ICR36 = 0;\r
+    MCF_INTC1_ICR37 = 0;\r
+    MCF_INTC1_ICR38 = 0;\r
+    MCF_INTC1_ICR39 = 0;\r
+    MCF_INTC1_ICR40 = 0;\r
+    MCF_INTC1_ICR41 = 0;\r
+    MCF_INTC1_ICR42 = 0;\r
+    MCF_INTC1_ICR59 = 0;\r
+    MCF_INTC0_IMRH = 0xffffffff;\r
+    MCF_INTC0_IMRL =\r
+        MCF_INTC0_IMRL_INT_MASK31 | MCF_INTC0_IMRL_INT_MASK30 |\r
+        MCF_INTC0_IMRL_INT_MASK29 | MCF_INTC0_IMRL_INT_MASK28 |\r
+        MCF_INTC0_IMRL_INT_MASK27 | MCF_INTC0_IMRL_INT_MASK26 |\r
+        MCF_INTC0_IMRL_INT_MASK25 | MCF_INTC0_IMRL_INT_MASK24 |\r
+        MCF_INTC0_IMRL_INT_MASK23 | MCF_INTC0_IMRL_INT_MASK22 |\r
+        MCF_INTC0_IMRL_INT_MASK21 | MCF_INTC0_IMRL_INT_MASK20 |\r
+        MCF_INTC0_IMRL_INT_MASK19 | MCF_INTC0_IMRL_INT_MASK18 |\r
+        MCF_INTC0_IMRL_INT_MASK17 | MCF_INTC0_IMRL_INT_MASK16 |\r
+        MCF_INTC0_IMRL_INT_MASK15 | MCF_INTC0_IMRL_INT_MASK14 |\r
+        MCF_INTC0_IMRL_INT_MASK13 | MCF_INTC0_IMRL_INT_MASK12 |\r
+        MCF_INTC0_IMRL_INT_MASK11 | MCF_INTC0_IMRL_INT_MASK10 |\r
+        MCF_INTC0_IMRL_INT_MASK9 | MCF_INTC0_IMRL_INT_MASK8 |\r
+        MCF_INTC0_IMRL_INT_MASK7 | MCF_INTC0_IMRL_INT_MASK6 |\r
+        MCF_INTC0_IMRL_INT_MASK5 | MCF_INTC0_IMRL_INT_MASK4 |\r
+        MCF_INTC0_IMRL_INT_MASK3 | MCF_INTC0_IMRL_INT_MASK2 |\r
+        MCF_INTC0_IMRL_INT_MASK1;\r
+    MCF_INTC1_IMRH = 0xffffffff;\r
+    MCF_INTC1_IMRL =\r
+        MCF_INTC1_IMRL_INT_MASK31 | MCF_INTC1_IMRL_INT_MASK30 |\r
+        MCF_INTC1_IMRL_INT_MASK29 | MCF_INTC1_IMRL_INT_MASK28 |\r
+        MCF_INTC1_IMRL_INT_MASK27 | MCF_INTC1_IMRL_INT_MASK26 |\r
+        MCF_INTC1_IMRL_INT_MASK25 | MCF_INTC1_IMRL_INT_MASK24 |\r
+        MCF_INTC1_IMRL_INT_MASK23 | MCF_INTC1_IMRL_INT_MASK22 |\r
+        MCF_INTC1_IMRL_INT_MASK21 | MCF_INTC1_IMRL_INT_MASK20 |\r
+        MCF_INTC1_IMRL_INT_MASK19 | MCF_INTC1_IMRL_INT_MASK18 |\r
+        MCF_INTC1_IMRL_INT_MASK17 | MCF_INTC1_IMRL_INT_MASK16 |\r
+        MCF_INTC1_IMRL_INT_MASK15 | MCF_INTC1_IMRL_INT_MASK14 |\r
+        MCF_INTC1_IMRL_INT_MASK13 | MCF_INTC1_IMRL_INT_MASK12 |\r
+        MCF_INTC1_IMRL_INT_MASK11 | MCF_INTC1_IMRL_INT_MASK10 |\r
+        MCF_INTC1_IMRL_INT_MASK9 | MCF_INTC1_IMRL_INT_MASK8 |\r
+        MCF_INTC1_IMRL_INT_MASK7 | MCF_INTC1_IMRL_INT_MASK6 |\r
+        MCF_INTC1_IMRL_INT_MASK5 | MCF_INTC1_IMRL_INT_MASK4 |\r
+        MCF_INTC1_IMRL_INT_MASK3 | MCF_INTC1_IMRL_INT_MASK2 |\r
+        MCF_INTC1_IMRL_INT_MASK1;\r
+}\r
+\r
+/*********************************************************************\r
+* init_pin_assignments - Pin Assignment and General Purpose I/O      *\r
+**********************************************************************/\r
+static void\r
+init_pin_assignments( void )\r
+{\r
+\r
+    /* Pin assignments for port ADDR\r
+       Pins are all GPIO inputs\r
+     */\r
+    MCF_GPIO_PDDR_APDDR = 0;\r
+    MCF_GPIO_PAR_AD = MCF_GPIO_PAR_AD_PAR_ADDR23\r
+        | MCF_GPIO_PAR_AD_PAR_ADDR22\r
+        | MCF_GPIO_PAR_AD_PAR_ADDR21 | MCF_GPIO_PAR_AD_PAR_DATAL;\r
+\r
+    /* Pin assignments for ports DATAH and DATAL\r
+       Pins are all GPIO inputs\r
+     */\r
+    MCF_GPIO_PDDR_DATAH = 0;\r
+    MCF_GPIO_PDDR_DATAL = 0;\r
+\r
+    /* Pin assignments for port BUSCTL\r
+       Pin /OE        : External bus output enable, /OE\r
+       Pin /TA        : External bus transfer acknowledge, /TA\r
+       Pin /TEA       : External bus transfer error acknowledge, /TEA\r
+       Pin R/W        : External bus read/write indication, R/W\r
+       Pin TSIZ1      : External bus transfer size TSIZ1 or DMA acknowledge /DACK1\r
+       Pin TSIZ0      : External bus transfer size TSIZ0 or DMA acknowledge /DACK0\r
+       Pin /TS        : External bus transfer start, /TS\r
+       Pin /TIP       : External bus transfer in progess, /TIP\r
+     */\r
+    MCF_GPIO_PDDR_BUSCTL = 0;\r
+    MCF_GPIO_PAR_BUSCTL =\r
+        MCF_GPIO_PAR_BUSCTL_PAR_OE | MCF_GPIO_PAR_BUSCTL_PAR_TA |\r
+        MCF_GPIO_PAR_BUSCTL_PAR_TEA( 0x3 ) | MCF_GPIO_PAR_BUSCTL_PAR_RWB |\r
+        MCF_GPIO_PAR_BUSCTL_PAR_TSIZ1 | MCF_GPIO_PAR_BUSCTL_PAR_TSIZ0 |\r
+        MCF_GPIO_PAR_BUSCTL_PAR_TS( 0x3 ) |\r
+        MCF_GPIO_PAR_BUSCTL_PAR_TIP( 0x3 );\r
+\r
+    /* Pin assignments for port BS\r
+       Pin /BS3       : External byte strobe /BS3\r
+       Pin /BS2       : External byte strobe /BS2\r
+       Pin /BS1       : External byte strobe /BS1\r
+       Pin /BS0       : External byte strobe /BS0\r
+     */\r
+    MCF_GPIO_PDDR_BS = 0;\r
+    MCF_GPIO_PAR_BS =\r
+        MCF_GPIO_PAR_BS_PAR_BS3 | MCF_GPIO_PAR_BS_PAR_BS2 |\r
+        MCF_GPIO_PAR_BS_PAR_BS1 | MCF_GPIO_PAR_BS_PAR_BS0;\r
+\r
+    /* Pin assignments for port CS\r
+       Pin /CS7       : Chip select /CS7\r
+       Pin /CS6       : Chip select /CS6\r
+       Pin /CS5       : Chip select /CS5\r
+       Pin /CS4       : Chip select /CS4\r
+       Pin /CS3       : Chip select /CS3\r
+       Pin /CS2       : Chip select /CS2\r
+       Pin /CS1       : Chip select /CS1\r
+     */\r
+    MCF_GPIO_PDDR_CS = 0;\r
+    MCF_GPIO_PAR_CS =\r
+        MCF_GPIO_PAR_CS_PAR_CS7 | MCF_GPIO_PAR_CS_PAR_CS6 |\r
+        MCF_GPIO_PAR_CS_PAR_CS5 | MCF_GPIO_PAR_CS_PAR_CS4 |\r
+        MCF_GPIO_PAR_CS_PAR_CS3 | MCF_GPIO_PAR_CS_PAR_CS2 |\r
+        MCF_GPIO_PAR_CS_PAR_CS1;\r
+\r
+    /* Pin assignments for port SDRAM\r
+       Pin /SD_WE     : SDRAM controller /SD_WE\r
+       Pin /SD_SCAS   : SDRAM controller /SD_SCAS\r
+       Pin /SD_SRAS   : SDRAM controller /SD_SRAS\r
+       Pin /SD_SCKE   : SDRAM controller /SD_SCKE\r
+       Pin /SD_CS1    : SDRAM controller /SD_CS1\r
+       Pin /SD_CS0    : SDRAM controller /SD_CS0\r
+     */\r
+    MCF_GPIO_PDDR_SDRAM = 0;\r
+    MCF_GPIO_PAR_SDRAM =\r
+        MCF_GPIO_PAR_SDRAM_PAR_SDWE | MCF_GPIO_PAR_SDRAM_PAR_SCAS |\r
+        MCF_GPIO_PAR_SDRAM_PAR_SRAS | MCF_GPIO_PAR_SDRAM_PAR_SCKE |\r
+        MCF_GPIO_PAR_SDRAM_PAR_SDCS1 | MCF_GPIO_PAR_SDRAM_PAR_SDCS0;\r
+\r
+    /* Pin assignments for port FECI2C\r
+       Pins are all GPIO inputs\r
+     */\r
+    MCF_GPIO_PDDR_FECI2C = 0;\r
+    MCF_GPIO_PAR_FECI2C =\r
+        MCF_GPIO_PAR_FECI2C_PAR_EMDC_FEC | MCF_GPIO_PAR_FECI2C_PAR_EMDIO_FEC;\r
+\r
+    /* Pin assignments for port UARTL\r
+       Pins are all GPIO inputs\r
+     */\r
+    MCF_GPIO_PDDR_UARTL = 0;\r
+    MCF_GPIO_PAR_UART = 0;\r
+\r
+    /* Pin assignments for port UARTH\r
+       Pin U2TXD      : GPIO input\r
+       Pin U2RXD      : GPIO input\r
+       Pin /IRQ2      : Interrupt request /IRQ2 or GPIO\r
+     */\r
+    MCF_GPIO_PDDR_UARTH = 0;\r
+\r
+    /* Pin assignments for port QSPI\r
+       Pins are all GPIO inputs\r
+     */\r
+    MCF_GPIO_PDDR_QSPI = 0;\r
+    MCF_GPIO_PAR_QSPI = 0;\r
+\r
+    /* Pin assignments for port TIMER\r
+       Pins are all GPIO inputs\r
+     */\r
+    MCF_GPIO_PDDR_TIMER = 0;\r
+    MCF_GPIO_PAR_TIMER = 0;\r
+\r
+    /* Pin assignments for port ETPU\r
+       Pins are all GPIO inputs\r
+     */\r
+    MCF_GPIO_PDDR_ETPU = 0;\r
+    MCF_GPIO_PAR_ETPU = 0;\r
+}\r
index a31e8c918bf2c7a735a7f923a762e550063c6159..1626a9d600b7578da9a2b06f8a5c7989f85cf6e2 100644 (file)
-/*
-    FreeRTOS MCF5235 port - Copyright (C) 2006 Christian Walter.
-
-    This file is part of the FreeRTOS distribution.
-
-    FreeRTOS is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    FreeRTOS is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with FreeRTOS; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-    A special exception to the GPL can be applied should you wish to distribute
-    a combined work that includes FreeRTOS, without being obliged to provide
-    the source code for any proprietary components.  See the licensing section
-    of http://www.FreeRTOS.org for full details of how and when the exception
-    can be applied.
-
-    ***************************************************************************
-    See http://www.FreeRTOS.org for documentation, latest information, license
-    and contact details.  Please ensure to read the configuration and relevant
+/*\r
+    FreeRTOS MCF5235 port - Copyright (C) 2006 Christian Walter.\r
+\r
+    This file is part of the FreeRTOS distribution.\r
+\r
+    FreeRTOS is free software; you can redistribute it and/or modify\r
+    it under the terms of the GNU General Public License as published by\r
+    the Free Software Foundation; either version 2 of the License, or\r
+    (at your option) any later version.\r
+\r
+    FreeRTOS is distributed in the hope that it will be useful,\r
+    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+    GNU General Public License for more details.\r
+\r
+    You should have received a copy of the GNU General Public License\r
+    along with FreeRTOS; if not, write to the Free Software\r
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+\r
+    A special exception to the GPL can be applied should you wish to distribute\r
+    a combined work that includes FreeRTOS, without being obliged to provide\r
+    the source code for any proprietary components.  See the licensing section\r
+    of http://www.FreeRTOS.org for full details of how and when the exception\r
+    can be applied.\r
+\r
+    ***************************************************************************\r
+    See http://www.FreeRTOS.org for documentation, latest information, license\r
+    and contact details.  Please ensure to read the configuration and relevant\r
     port sections of the online documentation.\r
 \r
        Also see http://www.SafeRTOS.com for an IEC 61508 compliant version along\r
-       with commercial development and support options.
-    ***************************************************************************
-*/
-
-/* ------------------------ System includes ------------------------------- */
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <errno.h>
-
-/* ------------------------ FreeRTOS includes ----------------------------- */
-#include <FreeRTOS.h>
-#include <serial.h>
-
-/* ------------------------ Prototypes ------------------------------------ */
-void vSerialPutStringNOISR( xComPortHandle pxPort,
-                            const signed portCHAR * const pcString,
-                            unsigned portSHORT usStringLength );
-
-/* ------------------------ Start implementation -------------------------- */
-void
-_exit( int status )
-{
-    asm volatile    ( "halt" );
-
-    for( ;; );
-}
-
-pid_t
-getpid( void )
-{
-    return 0;
-}
-
-int
-kill( pid_t pid, int sig )
-{
-    _exit( 0 );
-}
-
-int
-close( int fd )
-{
-    return 0;
-}
-
-int
-fstat( int fd, struct stat *buf )
-{
-    buf->st_mode = S_IFCHR;
-    buf->st_blksize = 0;
-    return 0;
-}
-
-ssize_t
-write( int fd, const void *buf, size_t nbytes )
-{
-    ssize_t res = nbytes;
-    extern xComPortHandle xSTDComPort;
-    switch ( fd )
-    {
-        case STDERR_FILENO:
-            vSerialPutStringNOISR( xSTDComPort,
-                                   ( const signed portCHAR * const )buf,
-                                   ( unsigned portSHORT )nbytes );
-            break;
-        case STDOUT_FILENO:
-            vSerialPutString( xSTDComPort,
-                              ( const signed portCHAR * const)buf,
-                              ( unsigned portSHORT )nbytes );
-            break;
-        default:
-            errno = EIO;
-            res = -1;
-            break;
-    }
-    return res;
-}
-
-int
-read( int fd, void *buf, size_t nbytes )
-{
-    switch ( fd )
-    {
-        default:
-            errno = EIO;
-            return -1;
-    }
-}
-
-int
-isatty( int fd )
-{
-    return 0;
-}
-
-off_t
-lseek( int fd, off_t offset, int whence )
-{
-    errno = EIO;
-    return ( off_t ) - 1;
-}
-
-extern char     _end[];
-char           *heap_ptr;
-
-void           *
-sbrk( ptrdiff_t nbytes )
-{
-    char           *base;
-
-    if( !heap_ptr )
-        heap_ptr = ( char * )&_end;
-    base = heap_ptr;
-    heap_ptr += nbytes;
-
-    return base;
-}
+       with commercial development and support options.\r
+    ***************************************************************************\r
+*/\r
+\r
+/* ------------------------ System includes ------------------------------- */\r
+#include <sys/types.h>\r
+#include <sys/stat.h>\r
+#include <unistd.h>\r
+#include <errno.h>\r
+\r
+/* ------------------------ FreeRTOS includes ----------------------------- */\r
+#include <FreeRTOS.h>\r
+#include <serial.h>\r
+\r
+/* ------------------------ Prototypes ------------------------------------ */\r
+void vSerialPutStringNOISR( xComPortHandle pxPort,\r
+                            const signed portCHAR * const pcString,\r
+                            unsigned portSHORT usStringLength );\r
+\r
+/* ------------------------ Start implementation -------------------------- */\r
+void\r
+_exit( int status )\r
+{\r
+    asm volatile    ( "halt" );\r
+\r
+    for( ;; );\r
+}\r
+\r
+pid_t\r
+getpid( void )\r
+{\r
+    return 0;\r
+}\r
+\r
+int\r
+kill( pid_t pid, int sig )\r
+{\r
+    _exit( 0 );\r
+}\r
+\r
+int\r
+close( int fd )\r
+{\r
+    return 0;\r
+}\r
+\r
+int\r
+fstat( int fd, struct stat *buf )\r
+{\r
+    buf->st_mode = S_IFCHR;\r
+    buf->st_blksize = 0;\r
+    return 0;\r
+}\r
+\r
+ssize_t\r
+write( int fd, const void *buf, size_t nbytes )\r
+{\r
+    ssize_t res = nbytes;\r
+    extern xComPortHandle xSTDComPort;\r
+    switch ( fd )\r
+    {\r
+        case STDERR_FILENO:\r
+            vSerialPutStringNOISR( xSTDComPort,\r
+                                   ( const signed portCHAR * const )buf,\r
+                                   ( unsigned portSHORT )nbytes );\r
+            break;\r
+        case STDOUT_FILENO:\r
+            vSerialPutString( xSTDComPort,\r
+                              ( const signed portCHAR * const)buf,\r
+                              ( unsigned portSHORT )nbytes );\r
+            break;\r
+        default:\r
+            errno = EIO;\r
+            res = -1;\r
+            break;\r
+    }\r
+    return res;\r
+}\r
+\r
+int\r
+read( int fd, void *buf, size_t nbytes )\r
+{\r
+    switch ( fd )\r
+    {\r
+        default:\r
+            errno = EIO;\r
+            return -1;\r
+    }\r
+}\r
+\r
+int\r
+isatty( int fd )\r
+{\r
+    return 0;\r
+}\r
+\r
+off_t\r
+lseek( int fd, off_t offset, int whence )\r
+{\r
+    errno = EIO;\r
+    return ( off_t ) - 1;\r
+}\r
+\r
+extern char     _end[];\r
+char           *heap_ptr;\r
+\r
+void           *\r
+sbrk( ptrdiff_t nbytes )\r
+{\r
+    char           *base;\r
+\r
+    if( !heap_ptr )\r
+        heap_ptr = ( char * )&_end;\r
+    base = heap_ptr;\r
+    heap_ptr += nbytes;\r
+\r
+    return base;\r
+}\r
index de74f81efd19893901cdd98b435c1e5ff76ff27d..ef10d7aa90f2dfc3eef5597795839153662582f5 100644 (file)
-/*
-    FreeRTOS MCF5235 port - Copyright (C) 2006 Christian Walter.
-
-    This file is part of the FreeRTOS distribution.
-
-    FreeRTOS is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    FreeRTOS is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with FreeRTOS; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-    A special exception to the GPL can be applied should you wish to distribute
-    a combined work that includes FreeRTOS, without being obliged to provide
-    the source code for any proprietary components.  See the licensing section
-    of http://www.FreeRTOS.org for full details of how and when the exception
-    can be applied.
-
-    ***************************************************************************
-    See http://www.FreeRTOS.org for documentation, latest information, license
-    and contact details.  Please ensure to read the configuration and relevant
+/*\r
+    FreeRTOS MCF5235 port - Copyright (C) 2006 Christian Walter.\r
+\r
+    This file is part of the FreeRTOS distribution.\r
+\r
+    FreeRTOS is free software; you can redistribute it and/or modify\r
+    it under the terms of the GNU General Public License as published by\r
+    the Free Software Foundation; either version 2 of the License, or\r
+    (at your option) any later version.\r
+\r
+    FreeRTOS is distributed in the hope that it will be useful,\r
+    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+    GNU General Public License for more details.\r
+\r
+    You should have received a copy of the GNU General Public License\r
+    along with FreeRTOS; if not, write to the Free Software\r
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+\r
+    A special exception to the GPL can be applied should you wish to distribute\r
+    a combined work that includes FreeRTOS, without being obliged to provide\r
+    the source code for any proprietary components.  See the licensing section\r
+    of http://www.FreeRTOS.org for full details of how and when the exception\r
+    can be applied.\r
+\r
+    ***************************************************************************\r
+    See http://www.FreeRTOS.org for documentation, latest information, license\r
+    and contact details.  Please ensure to read the configuration and relevant\r
     port sections of the online documentation.\r
 \r
        Also see http://www.SafeRTOS.com for an IEC 61508 compliant version along\r
-       with commercial development and support options.
-    ***************************************************************************
-*/
-
-/* ------------------------ MCF523x includes ------------------------------ */
-#include "mcf5xxx.h"
-#include "mcf523x.h"
-
-/* ------------------------ FreeRTOS includes ----------------------------- */
-#include "FreeRTOS.h"
-#include "queue.h"
-#include "task.h"
-
-#include "serial.h"
-
-/* ----------------------- Defines ----------------------------------------- */
-#define BAUDRATE_VALUE(fsys, baud)      ( ( fsys )/(32UL * baud) )
-#define MCF_UART_VECTOR                 ( 64 + 13 )
-#define COM_NIFACE                      1
-#define COM_BLOCK_RETRYTIME             10
-
-/* ------------------------ Static functions ------------------------------ */
-static void     prvSerialISR( void );
-
-/* ------------------------ Static variables ------------------------------ */
-typedef struct
-{
-    portBASE_TYPE xInitialized;
-    xQueueHandle xRXChars;
-    xQueueHandle xTXChars;
-} xComPortIF_t;
-
-static xComPortIF_t xComPortIF[ COM_NIFACE ];
-
-/* ------------------------ Begin implementation -------------------------- */
-xComPortHandle
-xSerialPortInitMinimal( unsigned portLONG ulWantedBaud,
-                        unsigned portBASE_TYPE uxQueueLength )
-{
-    extern void     ( *__RAMVEC[] ) (  );
-    xComPortHandle xReturn;
-    portBASE_TYPE xOldIPL;
-
-    /* Create the queues used to hold Rx and Tx characters. */
-    xComPortIF[ 0 ].xRXChars =
-        xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE )sizeof( signed portCHAR ) );
-    xComPortIF[ 0 ].xTXChars =
-        xQueueCreate( uxQueueLength + 1, ( unsigned portBASE_TYPE )sizeof( signed portCHAR ) );
-
-    /* If the queues were created correctly then setup the serial port hardware. */
-    if( ( xComPortIF[ 0 ].xRXChars != 0 ) && ( xComPortIF[ 0 ].xTXChars != 0 ) )
-    {
-        xOldIPL = portSET_IPL( portIPL_MAX );
-
-        /* UART 0: Reset transmitter, receiver and mode register pointer */
-        MCF_UART_UCR0 = MCF_UART_UCR_MISC( 0x3 );
-        MCF_UART_UCR0 = MCF_UART_UCR_MISC( 0x2 );
-        MCF_UART_UCR0 = MCF_UART_UCR_MISC( 0x1 );
-
-        /* Enable receive interrupts. */
-        MCF_UART_UIMR0 = MCF_UART_UIMR_RXRDY_FU;
-
-        /* 8 Databits, 1 Stopbit and no parity */
-        MCF_UART_UMR0 = MCF_UART_UMR_PM( 0x3 ) | MCF_UART_UMR_SB( 0x7 ) | MCF_UART_UMR_BC( 0x3 );
-
-        /* UART 0 Clocking */
-        MCF_UART_UCSR0 = MCF_UART_UCSR_RCS( 0xd ) | MCF_UART_UCSR_TCS( 0xd );
-        MCF_UART_UBG10 = BAUDRATE_VALUE( FSYS_2, ulWantedBaud ) >> 8U;
-        MCF_UART_UBG20 = BAUDRATE_VALUE( FSYS_2, ulWantedBaud ) & 0xFFU;
-
-        /* UART 0: Enable interrupts */
-        __RAMVEC[MCF_UART_VECTOR] = prvSerialISR;
-        MCF_INTC0_ICR13 = MCF_INTC0_ICRn_IL( 0x2 ) | MCF_INTC0_ICRn_IP( 0x1 );
-        MCF_INTC0_IMRL &= ~MCF_INTC0_IMRL_INT_MASK13;
-
-        /* UART 0 Miscellaneous */
-        MCF_UART_UACR0 = 0;
-
-        /* UART 0: Enable pins */
-        MCF_GPIO_PAR_UART = MCF_GPIO_PAR_UART_PAR_U0RXD | MCF_GPIO_PAR_UART_PAR_U0TXD;
-
-        /* Enable the UART. */
-        MCF_UART_UCR0 = MCF_UART_UCR_RXC( 0x1 ) | MCF_UART_UCR_TXC( 0x1 );
-
-        xComPortIF[ 0 ].xInitialized = TRUE;
-        xReturn = ( xComPortHandle ) &xComPortIF[ 0 ];
-
-        ( void )portSET_IPL( xOldIPL );
-    }
-    else
-    {
-        xReturn = ( xComPortHandle ) 0;
-    }
-
-    return xReturn;
-}
-
-signed          portBASE_TYPE
-xSerialGetChar( xComPortHandle pxPort, signed portCHAR * pcRxedChar,
-                portTickType xBlockTime )
-{
-    int i;
-    portBASE_TYPE xResult = pdFALSE;
-    /* Lookup the correct interface. */
-    for( i = 0; i < COM_NIFACE; i++ )
-    {
-        if( pxPort == ( xComPortHandle ) &xComPortIF[ i ] )
-        {
-            break;
-        }
-    }
-    /* This COM port is available. */
-    if( ( i != COM_NIFACE ) && xComPortIF[ i ].xInitialized )
-    {
-        /* Get the next character from the buffer.  Return false if no characters
-         * are available, or arrive before xBlockTime expires.
-         */
-        if( xQueueReceive( xComPortIF[ i ].xRXChars, pcRxedChar, xBlockTime ) )
-        {
-            xResult = pdTRUE;
-        }
-    }
-    return xResult;
-}
-
-void
-vSerialPutString( xComPortHandle pxPort, const signed portCHAR *
-                  const pcString, unsigned portSHORT usStringLength )
-{
-    int i;
-    signed portCHAR *pChNext;
-
-    /* Send each character in the string, one at a time. */
-    pChNext = ( signed portCHAR * )pcString;
-    for( i = 0; i < usStringLength; i++ )
-    {
-        /* Block until character has been transmitted. */
-        while( xSerialPutChar( pxPort, *pChNext, COM_BLOCK_RETRYTIME ) != pdTRUE ); pChNext++;
-    }
-}
-
-signed          portBASE_TYPE
-xSerialPutChar( xComPortHandle pxPort, signed portCHAR cOutChar,
-                portTickType xBlockTime )
-{
-    int i;
-    portBASE_TYPE xResult = pdFALSE;
-    portBASE_TYPE xOldIPL;
-    /* Lookup the correct interface. */
-    for( i = 0; i < COM_NIFACE; i++ )
-    {
-        if( pxPort == ( xComPortHandle ) &xComPortIF[ i ] )
-        {
-            break;
-        }
-    }
-    /* This COM port is available. */
-    if( ( i != COM_NIFACE ) && xComPortIF[ i ].xInitialized )
-    {
-        /* Place the character in the queue of characters to be transmitted. */
-        if( xQueueSend( xComPortIF[ i ].xTXChars, &cOutChar, xBlockTime ) == pdPASS )
-        {
-            /* Turn on the Tx interrupt so the ISR will remove the character from the
-             * queue and send it. */
-            MCF_UART_UIMR0 = MCF_UART_UIMR_TXRDY | MCF_UART_UIMR_RXRDY_FU;
-            xResult = pdTRUE;
-        }
-    }
-    return xResult;
-}
-
-signed          portBASE_TYPE
-xSerialPutCharNOISR( xComPortHandle pxPort, signed portCHAR cOutChar )
-{
-    int i;
-    portBASE_TYPE xResult = pdFALSE;
-    portBASE_TYPE xOldIPL = portSET_IPL( portIPL_MAX );
-    /* Lookup the correct interface. */
-    for( i = 0; i < COM_NIFACE; i++ )
-    {
-        if( pxPort == ( xComPortHandle ) &xComPortIF[ i ] )
-        {
-            break;
-        }
-    }
-    /* This COM port is available. Support for this only available for COM1 right now. */
-    if( ( i != COM_NIFACE ) && ( i == 0 ) )
-    {
-        /* Wait until the transmit buffer is ready. */
-        while( !( MCF_UART_USR0 & MCF_UART_USR_TXRDY ) );
-        /* Place the character in the transmit buffer. */
-        MCF_UART_UTB0 = cOutChar;
-        xResult = pdTRUE;
-    }
-    ( void )portSET_IPL( xOldIPL );
-    return xResult;
-}
-
-void
-vSerialPutStringNOISR( xComPortHandle pxPort, const signed portCHAR *
-                       const pcString, unsigned portSHORT usStringLength )
-{
-    int i;
-    signed portCHAR *pChNext;
-    portBASE_TYPE xOldIPL = portSET_IPL( portIPL_MAX );
-
-    /* Send each character in the string, one at a time. */
-    pChNext = ( signed portCHAR * )pcString;
-    for( i = 0; i < usStringLength; i++ )
-    {
-        /* Block until character has been transmitted. */
-        while( xSerialPutCharNOISR( pxPort, *pChNext ) != pdTRUE );
-        pChNext++;
-    }
-    ( void )portSET_IPL( xOldIPL );
-}
-
-void
-vSerialClose( xComPortHandle xPort )
-{
-    /* Not supported as not required by the demo application. */
-}
-
-void
-prvSerialISR( void )
-{
-    static signed portCHAR cChar;
-    static portBASE_TYPE xTaskWokenByTx = pdFALSE, xTaskWokenByRx = pdFALSE;
-
-    /* We have to remvoe the effect of the GCC. Please note that the
-     * __attribute__ ((interrupt_handler)) does not work here because we
-     * have to do the storing of the registers ourself. Another problem
-     * is the usage of a frame pointer which is unlinked on entry.
-     */
-#if _GCC_USES_FP == 1
-    asm volatile ( "unlk %fp\n\t" );
-#endif
-    /* This ISR can cause a context switch, so the first statement must be
-     * a call to the portENTER_SWITCHING_ISR() macro. This must be BEFORE any
-     * variable declarations.
-     */
-    portENTER_SWITCHING_ISR();
-
-    /* Ready to send a character from the buffer. */
-    if( MCF_UART_USR0 & MCF_UART_USR_TXRDY )
-    {
-        /* Transmit buffer is ready. Test if there are characters available. */
-        if( xQueueReceiveFromISR( xComPortIF[ 0 ].xTXChars, &cChar, &xTaskWokenByTx ) ==
-            pdTRUE )
-        {
-            /* A character was retrieved from the queue so can be sent. */
-            MCF_UART_UTB0 = cChar;
-        }
-        else
-        {
-            /* Leave only receiver enabled. */
-            MCF_UART_UIMR0 = MCF_UART_UIMR_RXRDY_FU;
-        }
-    }
-    if( MCF_UART_USR0 & MCF_UART_USR_RXRDY )
-    {
-        cChar = MCF_UART_URB0;
-        xTaskWokenByRx =
-            xQueueSendFromISR( xComPortIF[ 0].xRXChars, &cChar, xTaskWokenByRx );
-    }
-    /* Exit the ISR.  If a task was woken by either a character being
-     * or transmitted then a context switch will occur.
-     */
-    portEXIT_SWITCHING_ISR( ( xTaskWokenByTx || xTaskWokenByRx ) );
-}
+       with commercial development and support options.\r
+    ***************************************************************************\r
+*/\r
+\r
+/* ------------------------ MCF523x includes ------------------------------ */\r
+#include "mcf5xxx.h"\r
+#include "mcf523x.h"\r
+\r
+/* ------------------------ FreeRTOS includes ----------------------------- */\r
+#include "FreeRTOS.h"\r
+#include "queue.h"\r
+#include "task.h"\r
+\r
+#include "serial.h"\r
+\r
+/* ----------------------- Defines ----------------------------------------- */\r
+#define BAUDRATE_VALUE(fsys, baud)      ( ( fsys )/(32UL * baud) )\r
+#define MCF_UART_VECTOR                 ( 64 + 13 )\r
+#define COM_NIFACE                      1\r
+#define COM_BLOCK_RETRYTIME             10\r
+\r
+/* ------------------------ Static functions ------------------------------ */\r
+static void     prvSerialISR( void );\r
+\r
+/* ------------------------ Static variables ------------------------------ */\r
+typedef struct\r
+{\r
+    portBASE_TYPE xInitialized;\r
+    xQueueHandle xRXChars;\r
+    xQueueHandle xTXChars;\r
+} xComPortIF_t;\r
+\r
+static xComPortIF_t xComPortIF[ COM_NIFACE ];\r
+\r
+/* ------------------------ Begin implementation -------------------------- */\r
+xComPortHandle\r
+xSerialPortInitMinimal( unsigned portLONG ulWantedBaud,\r
+                        unsigned portBASE_TYPE uxQueueLength )\r
+{\r
+    extern void     ( *__RAMVEC[] ) (  );\r
+    xComPortHandle xReturn;\r
+    portBASE_TYPE xOldIPL;\r
+\r
+    /* Create the queues used to hold Rx and Tx characters. */\r
+    xComPortIF[ 0 ].xRXChars =\r
+        xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE )sizeof( signed portCHAR ) );\r
+    xComPortIF[ 0 ].xTXChars =\r
+        xQueueCreate( uxQueueLength + 1, ( unsigned portBASE_TYPE )sizeof( signed portCHAR ) );\r
+\r
+    /* If the queues were created correctly then setup the serial port hardware. */\r
+    if( ( xComPortIF[ 0 ].xRXChars != 0 ) && ( xComPortIF[ 0 ].xTXChars != 0 ) )\r
+    {\r
+        xOldIPL = portSET_IPL( portIPL_MAX );\r
+\r
+        /* UART 0: Reset transmitter, receiver and mode register pointer */\r
+        MCF_UART_UCR0 = MCF_UART_UCR_MISC( 0x3 );\r
+        MCF_UART_UCR0 = MCF_UART_UCR_MISC( 0x2 );\r
+        MCF_UART_UCR0 = MCF_UART_UCR_MISC( 0x1 );\r
+\r
+        /* Enable receive interrupts. */\r
+        MCF_UART_UIMR0 = MCF_UART_UIMR_RXRDY_FU;\r
+\r
+        /* 8 Databits, 1 Stopbit and no parity */\r
+        MCF_UART_UMR0 = MCF_UART_UMR_PM( 0x3 ) | MCF_UART_UMR_SB( 0x7 ) | MCF_UART_UMR_BC( 0x3 );\r
+\r
+        /* UART 0 Clocking */\r
+        MCF_UART_UCSR0 = MCF_UART_UCSR_RCS( 0xd ) | MCF_UART_UCSR_TCS( 0xd );\r
+        MCF_UART_UBG10 = BAUDRATE_VALUE( FSYS_2, ulWantedBaud ) >> 8U;\r
+        MCF_UART_UBG20 = BAUDRATE_VALUE( FSYS_2, ulWantedBaud ) & 0xFFU;\r
+\r
+        /* UART 0: Enable interrupts */\r
+        __RAMVEC[MCF_UART_VECTOR] = prvSerialISR;\r
+        MCF_INTC0_ICR13 = MCF_INTC0_ICRn_IL( 0x2 ) | MCF_INTC0_ICRn_IP( 0x1 );\r
+        MCF_INTC0_IMRL &= ~MCF_INTC0_IMRL_INT_MASK13;\r
+\r
+        /* UART 0 Miscellaneous */\r
+        MCF_UART_UACR0 = 0;\r
+\r
+        /* UART 0: Enable pins */\r
+        MCF_GPIO_PAR_UART = MCF_GPIO_PAR_UART_PAR_U0RXD | MCF_GPIO_PAR_UART_PAR_U0TXD;\r
+\r
+        /* Enable the UART. */\r
+        MCF_UART_UCR0 = MCF_UART_UCR_RXC( 0x1 ) | MCF_UART_UCR_TXC( 0x1 );\r
+\r
+        xComPortIF[ 0 ].xInitialized = TRUE;\r
+        xReturn = ( xComPortHandle ) &xComPortIF[ 0 ];\r
+\r
+        ( void )portSET_IPL( xOldIPL );\r
+    }\r
+    else\r
+    {\r
+        xReturn = ( xComPortHandle ) 0;\r
+    }\r
+\r
+    return xReturn;\r
+}\r
+\r
+signed          portBASE_TYPE\r
+xSerialGetChar( xComPortHandle pxPort, signed portCHAR * pcRxedChar,\r
+                portTickType xBlockTime )\r
+{\r
+    int i;\r
+    portBASE_TYPE xResult = pdFALSE;\r
+    /* Lookup the correct interface. */\r
+    for( i = 0; i < COM_NIFACE; i++ )\r
+    {\r
+        if( pxPort == ( xComPortHandle ) &xComPortIF[ i ] )\r
+        {\r
+            break;\r
+        }\r
+    }\r
+    /* This COM port is available. */\r
+    if( ( i != COM_NIFACE ) && xComPortIF[ i ].xInitialized )\r
+    {\r
+        /* Get the next character from the buffer.  Return false if no characters\r
+         * are available, or arrive before xBlockTime expires.\r
+         */\r
+        if( xQueueReceive( xComPortIF[ i ].xRXChars, pcRxedChar, xBlockTime ) )\r
+        {\r
+            xResult = pdTRUE;\r
+        }\r
+    }\r
+    return xResult;\r
+}\r
+\r
+void\r
+vSerialPutString( xComPortHandle pxPort, const signed portCHAR *\r
+                  const pcString, unsigned portSHORT usStringLength )\r
+{\r
+    int i;\r
+    signed portCHAR *pChNext;\r
+\r
+    /* Send each character in the string, one at a time. */\r
+    pChNext = ( signed portCHAR * )pcString;\r
+    for( i = 0; i < usStringLength; i++ )\r
+    {\r
+        /* Block until character has been transmitted. */\r
+        while( xSerialPutChar( pxPort, *pChNext, COM_BLOCK_RETRYTIME ) != pdTRUE ); pChNext++;\r
+    }\r
+}\r
+\r
+signed          portBASE_TYPE\r
+xSerialPutChar( xComPortHandle pxPort, signed portCHAR cOutChar,\r
+                portTickType xBlockTime )\r
+{\r
+    int i;\r
+    portBASE_TYPE xResult = pdFALSE;\r
+    portBASE_TYPE xOldIPL;\r
+    /* Lookup the correct interface. */\r
+    for( i = 0; i < COM_NIFACE; i++ )\r
+    {\r
+        if( pxPort == ( xComPortHandle ) &xComPortIF[ i ] )\r
+        {\r
+            break;\r
+        }\r
+    }\r
+    /* This COM port is available. */\r
+    if( ( i != COM_NIFACE ) && xComPortIF[ i ].xInitialized )\r
+    {\r
+        /* Place the character in the queue of characters to be transmitted. */\r
+        if( xQueueSend( xComPortIF[ i ].xTXChars, &cOutChar, xBlockTime ) == pdPASS )\r
+        {\r
+            /* Turn on the Tx interrupt so the ISR will remove the character from the\r
+             * queue and send it. */\r
+            MCF_UART_UIMR0 = MCF_UART_UIMR_TXRDY | MCF_UART_UIMR_RXRDY_FU;\r
+            xResult = pdTRUE;\r
+        }\r
+    }\r
+    return xResult;\r
+}\r
+\r
+signed          portBASE_TYPE\r
+xSerialPutCharNOISR( xComPortHandle pxPort, signed portCHAR cOutChar )\r
+{\r
+    int i;\r
+    portBASE_TYPE xResult = pdFALSE;\r
+    portBASE_TYPE xOldIPL = portSET_IPL( portIPL_MAX );\r
+    /* Lookup the correct interface. */\r
+    for( i = 0; i < COM_NIFACE; i++ )\r
+    {\r
+        if( pxPort == ( xComPortHandle ) &xComPortIF[ i ] )\r
+        {\r
+            break;\r
+        }\r
+    }\r
+    /* This COM port is available. Support for this only available for COM1 right now. */\r
+    if( ( i != COM_NIFACE ) && ( i == 0 ) )\r
+    {\r
+        /* Wait until the transmit buffer is ready. */\r
+        while( !( MCF_UART_USR0 & MCF_UART_USR_TXRDY ) );\r
+        /* Place the character in the transmit buffer. */\r
+        MCF_UART_UTB0 = cOutChar;\r
+        xResult = pdTRUE;\r
+    }\r
+    ( void )portSET_IPL( xOldIPL );\r
+    return xResult;\r
+}\r
+\r
+void\r
+vSerialPutStringNOISR( xComPortHandle pxPort, const signed portCHAR *\r
+                       const pcString, unsigned portSHORT usStringLength )\r
+{\r
+    int i;\r
+    signed portCHAR *pChNext;\r
+    portBASE_TYPE xOldIPL = portSET_IPL( portIPL_MAX );\r
+\r
+    /* Send each character in the string, one at a time. */\r
+    pChNext = ( signed portCHAR * )pcString;\r
+    for( i = 0; i < usStringLength; i++ )\r
+    {\r
+        /* Block until character has been transmitted. */\r
+        while( xSerialPutCharNOISR( pxPort, *pChNext ) != pdTRUE );\r
+        pChNext++;\r
+    }\r
+    ( void )portSET_IPL( xOldIPL );\r
+}\r
+\r
+void\r
+vSerialClose( xComPortHandle xPort )\r
+{\r
+    /* Not supported as not required by the demo application. */\r
+}\r
+\r
+void\r
+prvSerialISR( void )\r
+{\r
+    static signed portCHAR cChar;\r
+    static portBASE_TYPE xTaskWokenByTx = pdFALSE, xTaskWokenByRx = pdFALSE;\r
+\r
+    /* We have to remvoe the effect of the GCC. Please note that the\r
+     * __attribute__ ((interrupt_handler)) does not work here because we\r
+     * have to do the storing of the registers ourself. Another problem\r
+     * is the usage of a frame pointer which is unlinked on entry.\r
+     */\r
+#if _GCC_USES_FP == 1\r
+    asm volatile ( "unlk %fp\n\t" );\r
+#endif\r
+    /* This ISR can cause a context switch, so the first statement must be\r
+     * a call to the portENTER_SWITCHING_ISR() macro. This must be BEFORE any\r
+     * variable declarations.\r
+     */\r
+    portENTER_SWITCHING_ISR();\r
+\r
+    /* Ready to send a character from the buffer. */\r
+    if( MCF_UART_USR0 & MCF_UART_USR_TXRDY )\r
+    {\r
+        /* Transmit buffer is ready. Test if there are characters available. */\r
+        if( xQueueReceiveFromISR( xComPortIF[ 0 ].xTXChars, &cChar, &xTaskWokenByTx ) ==\r
+            pdTRUE )\r
+        {\r
+            /* A character was retrieved from the queue so can be sent. */\r
+            MCF_UART_UTB0 = cChar;\r
+        }\r
+        else\r
+        {\r
+            /* Leave only receiver enabled. */\r
+            MCF_UART_UIMR0 = MCF_UART_UIMR_RXRDY_FU;\r
+        }\r
+    }\r
+    if( MCF_UART_USR0 & MCF_UART_USR_RXRDY )\r
+    {\r
+        cChar = MCF_UART_URB0;\r
+        xTaskWokenByRx =\r
+            xQueueSendFromISR( xComPortIF[ 0].xRXChars, &cChar, xTaskWokenByRx );\r
+    }\r
+    /* Exit the ISR.  If a task was woken by either a character being\r
+     * or transmitted then a context switch will occur.\r
+     */\r
+    portEXIT_SWITCHING_ISR( ( xTaskWokenByTx || xTaskWokenByRx ) );\r
+}\r
index d5bbafbe98e7739c75eff3303cfa7a7a849f7ef3..9021da378bf84190ed740af2a473cb846db3884f 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index b6b8717d867f7bfc6d12ccda9fbc51847ea9e938..f2b1802a64bfa2ee0ce1c0f83f4375c19f4e46e1 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index b981a92b461d01f43355bc17c0476fb4a3e34a87..4e62c121a8fd9b5a859ffad1d1b74e2ebfe203cf 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
@@ -63,7 +63,7 @@
 #include "FreeRTOS.h"\r
 #include "task.h"\r
 \r
-/* Demo application includes. */
+/* Demo application includes. */\r
 #include "ParTest.h"\r
 #include "flash.h"\r
 #include "comtest2.h"\r
@@ -173,7 +173,7 @@ int main (void)
        /* Should not get here as the processor is now under control of the \r
        scheduler! */\r
 \r
-       return 0;
+       return 0;\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
index d8d7d11cf4ba39b3240e6c73351c24e0d9fcc537..94020cada7a3d3682a5f7ca598748753b69b429a 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index 3eeceac648a2c9b53bd723106e5fa90e99e69acb..0950fe6dbbedd32bd5c2a5a84da5c95909982255 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index e76a518eb7e9034c26dbd7b4c9e9531d066cda51..e3eaa3ca0d027ec99c588c5f746b1140bd9d421c 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index 5a7fbf085a4d62129ffa4edeb58a1d0d0d9fcda4..ee87540469a090c72729a9ef073cd62b96453496 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index a4ecf23b83699e2bdfb6961bc79dc5ed2b5fa849..228944a64edce125581fe178c9f35fdf547f94df 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index 93c400e87422c1f67af916ae8ca201af73473691..c40cc320d0832309b913df2f84ff1346570f1540 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index a2dd0aa0bfefb011c46b58f0483bcfe16d75f747..e46be9761059a400626c7b549b329a69283a0075 100644 (file)
@@ -5,7 +5,7 @@
        http://dzcomm.sourceforge.net\r
 \r
 \r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index c939d61f81ae1ba34960327c492953b0a0544ce3..c9d163cf7f7f679f2a681316314d07de061a6095 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index b61badc52dc8ba3d874c2442c51c9df9df836c33..7458d5dbd118ca98e6a86a25fd5a8a712990ccd7 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index 23caf44aad8345db07f668ca01359fa0039cd9c3..d90ccc75437a96c8be36704661f72f121209c210 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index 3b51dd683cd881ae12a368f274343e0ef8f67d40..17b8c562df363d5528ce61381e25cb73cc82518e 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index f6aade2436707e687868f6724d45c3297829c16b..2c06de0184d53bb9ce0bab30d4cd5e51bf64d5d7 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index 36c0c4ae8eedff03926d9f4a87057e1249eeec21..3ff4513c11389640fdb7ebfdcd13b9bc9b4badfd 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index 50c05659d329cbebaa95a6a2f8b61f7db1b729b9..d3a63c4e36ec5421163fa2cc7d270c96573d8769 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index 1d6e3d19da19179816ac5daaeda846e368a87e01..60266cdbdcc9d1c195532324f889aab5534c314c 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index e3e79d0bdf5d844b0ca94b9906be064282528787..9c5671e9725052e3c95fb3d7f264a6a026b6302f 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index f4b176fa2a7bad873701f54c1ef5c6959b90a56b..3b255425f56adbe47ea416b4d0b3b4829a4f3c39 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index cb5ddef5af4dee448cf8dcbdde756f3d3115af71..3c0f34d2befabfdb3dbed8c4a1d64d1194235c59 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index c940070acad78172513a1b7b6f45afa199ee939d..b8d18d209b02efe0c61075f63456ac1273424085 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index 78e599a1d7fc23c6b1683ead6e124685b0072d3a..0603ce5036a1fe3d06e6a25e529d933621cb242e 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index e3e79d0bdf5d844b0ca94b9906be064282528787..9c5671e9725052e3c95fb3d7f264a6a026b6302f 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index b91305b037ceaac32aa45f7e3cd0592bd519d446..02662014e023aadf8858424d0d74385f57409297 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index a63823f8cadd59ed9c32560e23dfede9c4a6bf2c..3a1564619f6bf81c41f3e1c4422e3e72fb7553d0 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index 0fe4afe266cbdae674f718c25104dd686a9b0d32..cdc40de513f29634b0a3800caa44a2464e7d5135 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index 78e599a1d7fc23c6b1683ead6e124685b0072d3a..0603ce5036a1fe3d06e6a25e529d933621cb242e 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index e3e79d0bdf5d844b0ca94b9906be064282528787..9c5671e9725052e3c95fb3d7f264a6a026b6302f 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index b91305b037ceaac32aa45f7e3cd0592bd519d446..02662014e023aadf8858424d0d74385f57409297 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index 6147bc9432c276a05f5ded84c03c68c43a9ff01a..5da1a014ef20c1dbe4a7ec0ab4348751dfb0a3b7 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index 6b4c66b9efa7cef9a27658133dd98e2ae6f4414b..facce0381d75603c51e7c888e3c5ea69088cc256 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index 78e599a1d7fc23c6b1683ead6e124685b0072d3a..0603ce5036a1fe3d06e6a25e529d933621cb242e 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index e3e79d0bdf5d844b0ca94b9906be064282528787..9c5671e9725052e3c95fb3d7f264a6a026b6302f 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index b91305b037ceaac32aa45f7e3cd0592bd519d446..02662014e023aadf8858424d0d74385f57409297 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index bc1062927c39d4d14f02dcc3b73ce3966d297f4a..0f7ae7957f546414808bf944772b4ba17692ea1f 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index 1bd8649bd563da788a97cdab3a0dd27933cefe31..c3810fca0db6dc336b751b46464005494c8d01b4 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index 78e599a1d7fc23c6b1683ead6e124685b0072d3a..0603ce5036a1fe3d06e6a25e529d933621cb242e 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index e3e79d0bdf5d844b0ca94b9906be064282528787..9c5671e9725052e3c95fb3d7f264a6a026b6302f 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index b91305b037ceaac32aa45f7e3cd0592bd519d446..02662014e023aadf8858424d0d74385f57409297 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index 21d937d90aed63666e932a36028fde77fcd19e57..33c014c059f1f2fb424729c7c33164e5a5c81954 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index 815761e2e2ed2c03dd3d2657c4ad5efedfe82378..4302ebb998f2f5a3181cb7f5e1ed0fb3ef4f775c 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index 78e599a1d7fc23c6b1683ead6e124685b0072d3a..0603ce5036a1fe3d06e6a25e529d933621cb242e 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index e3e79d0bdf5d844b0ca94b9906be064282528787..9c5671e9725052e3c95fb3d7f264a6a026b6302f 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index b91305b037ceaac32aa45f7e3cd0592bd519d446..02662014e023aadf8858424d0d74385f57409297 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index 44c0fdbda3c30a872c78e5146ebe35366c7c42aa..c09a52bc30ac2a69e6c7e21916f1408fed1ab8d9 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index 833df17f61859ae8777e2db8568703c25e5010c0..f974ecf299d4c5debc02f6487a123970c1879461 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index 78e599a1d7fc23c6b1683ead6e124685b0072d3a..0603ce5036a1fe3d06e6a25e529d933621cb242e 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index e3e79d0bdf5d844b0ca94b9906be064282528787..9c5671e9725052e3c95fb3d7f264a6a026b6302f 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index b91305b037ceaac32aa45f7e3cd0592bd519d446..02662014e023aadf8858424d0d74385f57409297 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index 9eab48c7f1aaee48244578b5c6fe76aa99dcdba5..1c902ef47be2b59d24f61e5951de30fe7b83c1a4 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index 51c77a4f4b7cc51b34691527410beb7efda8cd52..e43b53bbd354507478c005a5cfe102518f534fb6 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index 2cada7c5438ff69041b9fef7ef50bb1ada8432b8..86b6122f8b421954415167ff43f577e9b67fcd73 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index d5b2b0a033db5ebec6223a46a9eb1f0718145f98..6e4ecdc784a886b50fca6e41296d955d89d302dd 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index b15f8e34e3519abc1c9b7e6ab6fd3476a20e4c9a..871885f80b669a4e18610190d71a5eac16e5c2ac 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index 039217231a0cb8c223905abfaeea2cfc214f7e45..150061ae32c0cbfec8cb7deab8ff4eae2dea2a8b 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
@@ -77,4 +77,6 @@ to exclude the API function. */
 #define INCLUDE_vTaskDelay                             1\r
 \r
 \r
+#define configKERNEL_INTERRUPT_PRIORITY        0x01\r
+\r
 #endif /* FREERTOS_CONFIG_H */\r
index 54420791eda46c1947449d03d3862f6fd06f68dc..196f925afdcc26c82de6a90acb2cf0655ff9c195 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index acf1e014d8179d415a3b229a0dc20e2ed3e1b03a..61dc2e940e5bdfad3faa94c8b4487bdb46a5ac43 100644 (file)
Binary files a/Demo/PIC24_MPLAB/RTOSDemo.mcw and b/Demo/PIC24_MPLAB/RTOSDemo.mcw differ
index e42a7e8d8049a0bd987b6c3fe70d5d475f297350..882052bb7b3cb17f6424ad86d41810c670e3370c 100644 (file)
@@ -36,6 +36,8 @@ file_016=no
 file_017=no\r
 file_018=no\r
 file_019=no\r
+file_020=no\r
+file_021=no\r
 [FILE_INFO]\r
 file_000=main.c\r
 file_001=..\..\source\list.c\r
@@ -51,12 +53,14 @@ file_010=..\Common\Minimal\blocktim.c
 file_011=..\Common\Minimal\integer.c\r
 file_012=..\Common\Minimal\comtest.c\r
 file_013=serial\serial.c\r
-file_014=..\..\source\include\semphr.h\r
-file_015=..\..\source\include\task.h\r
-file_016=..\..\source\include\croutine.h\r
-file_017=..\..\source\include\queue.h\r
-file_018=FreeRTOSConfig.h\r
-file_019=p24FJ128GA010.gld\r
+file_014=timertest.c\r
+file_015=lcd.c\r
+file_016=..\..\source\include\semphr.h\r
+file_017=..\..\source\include\task.h\r
+file_018=..\..\source\include\croutine.h\r
+file_019=..\..\source\include\queue.h\r
+file_020=FreeRTOSConfig.h\r
+file_021=p24FJ128GA010.gld\r
 [SUITE_INFO]\r
 suite_guid={479DDE59-4D56-455E-855E-FFF59A3DB57E}\r
 suite_state=\r
@@ -65,3 +69,7 @@ TS{7D9C6ECE-785D-44CB-BA22-17BF2E119622}=-g
 TS{25AC22BD-2378-4FDB-BFB6-7345A15512D3}=-g -Wall -DMPLAB_PIC24_PORT -mlarge-code -fomit-frame-pointer -fno-schedule-insns -fno-schedule-insns2\r
 TS{7DAC9A1D-4C45-45D6-B25A-D117C74E8F5A}=--defsym=__ICD2RAM=1 -Map="$(TARGETBASE).map" -o"$(TARGETBASE).$(TARGETSUFFIX)"\r
 TS{509E5861-1E2A-483B-8B6B-CA8DB7F2DD78}=\r
+[INSTRUMENTED_TRACE]\r
+enable=0\r
+transport=0\r
+format=0\r
diff --git a/Demo/PIC24_MPLAB/lcd.c b/Demo/PIC24_MPLAB/lcd.c
new file mode 100644 (file)
index 0000000..b9a758a
--- /dev/null
@@ -0,0 +1,210 @@
+/*\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
+\r
+       This file is part of the FreeRTOS.org distribution.\r
+\r
+       FreeRTOS.org is free software; you can redistribute it and/or modify\r
+       it under the terms of the GNU General Public License as published by\r
+       the Free Software Foundation; either version 2 of the License, or\r
+       (at your option) any later version.\r
+\r
+       FreeRTOS.org is distributed in the hope that it will be useful,\r
+       but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+       GNU General Public License for more details.\r
+\r
+       You should have received a copy of the GNU General Public License\r
+       along with FreeRTOS.org; if not, write to the Free Software\r
+       Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+\r
+       A special exception to the GPL can be applied should you wish to distribute\r
+       a combined work that includes FreeRTOS.org, without being obliged to provide\r
+       the source code for any proprietary components.  See the licensing section \r
+       of http://www.FreeRTOS.org for full details of how and when the exception\r
+       can be applied.\r
+\r
+       ***************************************************************************\r
+       See http://www.FreeRTOS.org for documentation, latest information, license \r
+       and contact details.  Please ensure to read the configuration and relevant \r
+       port sections of the online documentation.\r
+\r
+       Also see http://www.SafeRTOS.com for an IEC 61508 compliant version along\r
+       with commercial development and support options.\r
+       ***************************************************************************\r
+*/\r
+\r
+/* Scheduler includes. */\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+#include "queue.h"\r
+\r
+/* Demo includes. */\r
+#include "lcd.h"\r
+\r
+/*\r
+ * The LCD is written to by more than one task so is controlled by this\r
+ * 'gatekeeper' task.  This is the only task that is actually permitted to\r
+ * access the LCD directly.  Other tasks wanting to display a message send\r
+ * the message to the gatekeeper.\r
+ */\r
+static void vLCDTask( void *pvParameters );\r
+\r
+/*\r
+ * Setup the peripherals required to communicate with the LCD.\r
+ */\r
+static void prvSetupLCD( void );\r
+\r
+/* \r
+ * Move to the first (0) or second (1) row of the LCD. \r
+ */\r
+static void prvLCDGotoRow( unsigned portSHORT usRow );\r
+\r
+/* \r
+ * Write a string of text to the LCD. \r
+ */\r
+static void prvLCDPutString( portCHAR *pcString );\r
+\r
+/* \r
+ * Clear the LCD. \r
+ */\r
+static void prvLCDClear( void );\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/* Brief delay to permit the LCD to catch up with commands. */\r
+#define lcdSHORT_DELAY         3\r
+\r
+/* SFR that seems to be missing from the standard header files. */\r
+#define PMAEN                          *( ( unsigned short * ) 0x60c )\r
+\r
+/* LCD commands. */\r
+#define lcdDEFAULT_FUNCTION    0x3c\r
+#define lcdDISPLAY_CONTROL     0x0c\r
+#define lcdCLEAR_DISPLAY       0x01\r
+#define lcdENTRY_MODE          0x06\r
+\r
+/* The length of the queue used to send messages to the LCD gatekeeper task. */\r
+#define lcdQUEUE_SIZE          3\r
+/*-----------------------------------------------------------*/\r
+\r
+/* The queue used to send messages to the LCD task. */\r
+xQueueHandle xLCDQueue;\r
+\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+xQueueHandle xStartLCDTask( void )\r
+{\r
+       /* Create the queue used by the LCD task.  Messages for display on the LCD\r
+       are received via this queue. */\r
+       xLCDQueue = xQueueCreate( lcdQUEUE_SIZE, sizeof( xLCDMessage ) );\r
+\r
+       /* Start the task that will write to the LCD.  The LCD hardware is\r
+       initialised from within the task itself so delays can be used. */\r
+       xTaskCreate( vLCDTask, ( signed portCHAR * ) "LCD", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, NULL );\r
+\r
+       return xLCDQueue;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvLCDGotoRow( unsigned portSHORT usRow )\r
+{\r
+       if( usRow == 0 )\r
+       {\r
+               PMADDR = 0x0000;\r
+               PMDIN1 = 0x02;\r
+       }\r
+       else\r
+       {\r
+               PMADDR = 0x0000;\r
+               PMDIN1 = 0xc0;\r
+       }\r
+\r
+       vTaskDelay( lcdSHORT_DELAY );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvLCDPutString( portCHAR *pcString )\r
+{\r
+       /* Write out each character with appropriate delay between each. */\r
+       while( *pcString )\r
+       {\r
+               PMADDR = 0x0001;\r
+               PMDIN1 = *pcString;\r
+               pcString++;\r
+               vTaskDelay( lcdSHORT_DELAY );\r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvLCDClear( void )\r
+{\r
+       /* Clear the display. */\r
+       PMADDR = 0x0000;\r
+       PMDIN1 = lcdCLEAR_DISPLAY;\r
+       vTaskDelay( lcdSHORT_DELAY );   \r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvSetupLCD( void )\r
+{\r
+       /* Setup the PMP. */\r
+       PMCON = 0x83BF;\r
+       PMMODE = 0x3FF;\r
+       PMAEN = 1;\r
+       PMADDR = 0x0000;\r
+       vTaskDelay( lcdSHORT_DELAY );\r
+\r
+       /* Set the default function. */\r
+       PMDIN1 = lcdDEFAULT_FUNCTION;\r
+       vTaskDelay( lcdSHORT_DELAY );\r
+\r
+       /* Set the display control. */\r
+       PMDIN1 = lcdDISPLAY_CONTROL;\r
+       vTaskDelay( lcdSHORT_DELAY );\r
+\r
+       /* Clear the display. */\r
+       PMDIN1 = lcdCLEAR_DISPLAY;\r
+       vTaskDelay( lcdSHORT_DELAY );\r
+\r
+       /* Set the entry mode. */\r
+       PMDIN1 = lcdENTRY_MODE;\r
+       vTaskDelay( lcdSHORT_DELAY );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void vLCDTask( void *pvParameters )\r
+{\r
+xLCDMessage xMessage;\r
+unsigned portSHORT usRow = 0;\r
+\r
+       /* Initialise the hardware.  This uses delays so must not be called prior\r
+       to the scheduler being started. */\r
+       prvSetupLCD();\r
+\r
+       /* Welcome message. */\r
+       prvLCDPutString( "www.FreeRTOS.org" );\r
+\r
+       for( ;; )\r
+       {\r
+               /* Wait for a message to arrive that requires displaying. */\r
+               while( xQueueReceive( xLCDQueue, &xMessage, portMAX_DELAY ) != pdPASS );\r
+\r
+               /* Clear the current display value. */\r
+               prvLCDClear();\r
+\r
+               /* Switch rows each time so we can see that the display is still being\r
+               updated. */\r
+               prvLCDGotoRow( usRow & 0x01 );\r
+               usRow++;\r
+               prvLCDPutString( xMessage.pcMessage );\r
+\r
+               /* Delay the requested amount of time to ensure the text just written \r
+               to the LCD is not overwritten. */\r
+               vTaskDelay( xMessage.xMinDisplayTime );         \r
+       }\r
+}\r
+\r
+\r
+\r
+\r
diff --git a/Demo/PIC24_MPLAB/lcd.h b/Demo/PIC24_MPLAB/lcd.h
new file mode 100644 (file)
index 0000000..e11c583
--- /dev/null
@@ -0,0 +1,57 @@
+/*\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
+\r
+       This file is part of the FreeRTOS.org distribution.\r
+\r
+       FreeRTOS.org is free software; you can redistribute it and/or modify\r
+       it under the terms of the GNU General Public License as published by\r
+       the Free Software Foundation; either version 2 of the License, or\r
+       (at your option) any later version.\r
+\r
+       FreeRTOS.org is distributed in the hope that it will be useful,\r
+       but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+       GNU General Public License for more details.\r
+\r
+       You should have received a copy of the GNU General Public License\r
+       along with FreeRTOS.org; if not, write to the Free Software\r
+       Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+\r
+       A special exception to the GPL can be applied should you wish to distribute\r
+       a combined work that includes FreeRTOS.org, without being obliged to provide\r
+       the source code for any proprietary components.  See the licensing section \r
+       of http://www.FreeRTOS.org for full details of how and when the exception\r
+       can be applied.\r
+\r
+       ***************************************************************************\r
+       See http://www.FreeRTOS.org for documentation, latest information, license \r
+       and contact details.  Please ensure to read the configuration and relevant \r
+       port sections of the online documentation.\r
+\r
+       Also see http://www.SafeRTOS.com for an IEC 61508 compliant version along\r
+       with commercial development and support options.\r
+       ***************************************************************************\r
+*/\r
+\r
+#ifndef LCD_INC_H\r
+#define LCD_INC_H\r
+\r
+/* Create the task that will control the LCD.  Returned is a handle to the queue\r
+on which messages to get written to the LCD should be written. */\r
+xQueueHandle xStartLCDTask( void );\r
+\r
+typedef struct\r
+{\r
+       /* The minimum amount of time the message should remain on the LCD without\r
+       being overwritten. */\r
+       portTickType xMinDisplayTime;\r
+\r
+       /* A pointer to the string to be displayed. */\r
+       portCHAR *pcMessage;\r
+\r
+} xLCDMessage;\r
+\r
+\r
+#endif /* LCD_INC_H */\r
+\r
+\r
index f1dfab1364bb26108f3927ac545df3ce017655a4..c130cf182d54689677de3a760e77ee84090d7448 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
 /*\r
  * Creates all the demo application tasks, then starts the scheduler.  The WEB\r
  * documentation provides more details of the standard demo application tasks.\r
- * In addition to the standard demo tasks, the following tasks are defined\r
- * within this file:\r
- * \r
- * "Register test" tasks - These tasks first set all the general purpose \r
- * registers to a known value (with each register containing a different value)\r
- * then test each general purpose register to ensure it still contains the\r
- * set value.  There are two register test tasks, with different values being\r
- * used by each.  The register test tasks will be preempted frequently due to\r
- * their low priority.  Setting then testing the value of each register in this\r
- * manner ensures the context of the tasks is being correctly saved and then\r
- * restored as the preemptive context switches occur.  An error is flagged\r
- * should any register be found to contain an unexpected value.  In addition\r
- * the register test tasks maintain a count of the number of times they cycle, \r
- * so an error can also be flagged should the cycle count not increment as\r
- * expected (indicating the the tasks are not executing at all).\r
+ * In addition to the standard demo tasks, the following tasks and tests are\r
+ * defined and/or created within this file:\r
+ *\r
+ * "Fast Interrupt Test" - A high frequency periodic interrupt is generated\r
+ * using a free running timer to demonstrate the use of the \r
+ * configKERNEL_INTERRUPT_PRIORITY configuration constant.  The interrupt \r
+ * service routine measures the number of processor clocks that occur between\r
+ * each interrupt - and in so doing measures the jitter in the interrupt \r
+ * timing.  The maximum measured jitter time is latched in the usMaxJitter \r
+ * variable, and displayed on the LCD by the 'Check' as described below.  \r
+ * The fast interrupt is configured and handled in the timer_test.c source \r
+ * file.\r
  *\r
+ * "LCD" task - the LCD task is a 'gatekeeper' task.  It is the only task that\r
+ * is permitted to access the LCD directly.  Other tasks wishing to write a\r
+ * message to the LCD send the message on a queue to the LCD task instead of \r
+ * accessing the LCD themselves.  The LCD task just blocks on the queue waiting \r
+ * for messages - waking and displaying the messages as they arrive.  The LCD\r
+ * task is defined in lcd.c.  \r
+ * \r
  * "Check" task -  This only executes every three seconds but has the highest \r
  * priority so is guaranteed to get processor time.  Its main function is to \r
- * check that all the other tasks are still operational.  Each task maintains a \r
- * unique count that is incremented each time the task successfully completes \r
- * its function.  Should any error occur within such a task the count is \r
- * permanently halted.  The check task inspects the count of each task to \r
- * ensure it has changed since the last time the check task executed.  If all \r
- * the count variables have changed all the tasks are still executing error \r
- * free, and the check task toggles the onboard LED.  Should any task contain \r
- * an error at any time check task cycle frequency is increased to 500ms, \r
- * causing the LED toggle rate to increase from 3 seconds to 500ms and in so\r
- * doing providing visual feedback that an error has occurred.\r
- *\r
+ * check that all the standard demo tasks are still operational.  Should any\r
+ * unexpected behaviour within a demo task be discovered the 'check' task will\r
+ * write "FAIL #n" to the LCD (via the LCD task).  If all the demo tasks are \r
+ * executing with their expected behaviour then the check task writes the max\r
+ * jitter time to the LCD (again via the LCD task), as described above.\r
  */\r
 \r
+/* Standard includes. */\r
+#include <stdio.h>\r
+\r
 /* Scheduler includes. */\r
 #include "FreeRTOS.h"\r
 #include "task.h"\r
+#include "queue.h"\r
 #include "croutine.h"\r
 \r
 /* Demo application includes. */\r
 #include "integer.h"\r
 #include "comtest2.h"\r
 #include "partest.h"\r
+#include "lcd.h"\r
+#include "timertest.h"\r
 \r
 /* Demo task priorities. */\r
 #define mainBLOCK_Q_PRIORITY                           ( tskIDLE_PRIORITY + 2 )\r
 #define mainCHECK_TASK_PRIORITY                                ( tskIDLE_PRIORITY + 3 )\r
 #define mainCOM_TEST_PRIORITY                          ( 2 )\r
 \r
-/* Delay between check task cycles when an error has/has not been detected. */\r
-#define mainNO_ERROR_DELAY                                     ( ( portTickType ) 3000 / portTICK_RATE_MS )\r
-#define mainERROR_DELAY                                                ( ( portTickType ) 500 / portTICK_RATE_MS )\r
+/* The check task may require a bit more stack as it calls sprintf(). */\r
+#define mainCHECK_TAKS_STACK_SIZE                      ( configMINIMAL_STACK_SIZE * 2 )\r
+\r
+/* The execution period of the check task. */\r
+#define mainCHECK_TASK_PERIOD                          ( ( portTickType ) 3000 / portTICK_RATE_MS )\r
 \r
 /* The number of flash co-routines to create. */\r
-#define mainNUM_FLASH_COROUTINES                       ( 3 )\r
+#define mainNUM_FLASH_COROUTINES                       ( 5 )\r
 \r
 /* Baud rate used by the comtest tasks. */\r
 #define mainCOM_TEST_BAUD_RATE                         ( 19200 )\r
 \r
 /* The LED used by the comtest tasks.  mainCOM_TEST_LED + 1 is also used.\r
 See the comtest.c file for more information. */\r
-#define mainCOM_TEST_LED                                       ( 4 )\r
+#define mainCOM_TEST_LED                                       ( 6 )\r
 \r
-/* The LED used by the check task. */\r
-#define mainCHECK_LED                                          ( 7 )\r
+/* The frequency at which the "fast interrupt test" interrupt will occur. */\r
+#define mainTEST_INTERRUPT_FREQUENCY           ( 20000 )\r
 \r
-/*-----------------------------------------------------------*/\r
+/* The number of processor clocks we expect to occur between each "fast\r
+interrupt test" interrupt. */\r
+#define mainEXPECTED_CLOCKS_BETWEEN_INTERRUPTS ( configCPU_CLOCK_HZ / mainTEST_INTERRUPT_FREQUENCY )\r
 \r
-/*\r
- * The register test tasks as described at the top of this file. \r
- */ \r
-void xRegisterTest1( void *pvParameters );\r
-void xRegisterTest2( void *pvParameters );\r
+/* The number of nano seconds between each processor clock. */\r
+#define mainNS_PER_CLOCK ( ( unsigned portSHORT ) ( ( 1.0 / ( double ) configCPU_CLOCK_HZ ) * 1000000000.0 ) )\r
+\r
+/* Dimension the buffer used to hold the value of the maximum jitter time when\r
+it is converted to a string. */\r
+#define mainMAX_STRING_LENGTH                          ( 20 )\r
+\r
+/*-----------------------------------------------------------*/\r
 \r
 /*\r
  * The check task as described at the top of this file.\r
@@ -122,13 +133,8 @@ static void prvSetupHardware( void );
 \r
 /*-----------------------------------------------------------*/\r
 \r
-/* Variables used to detect errors within the register test tasks. */\r
-static volatile unsigned portSHORT usTest1CycleCounter = 0, usTest2CycleCounter = 0;\r
-static unsigned portSHORT usPreviousTest1Count = 0, usPreviousTest2Count = 0;\r
-\r
-/* Set to pdTRUE should an error be detected in any of the standard demo tasks\r
-or tasks defined within this file. */\r
-static unsigned portSHORT usErrorDetected = pdFALSE;\r
+/* The queue used to send messages to the LCD task. */\r
+static xQueueHandle xLCDQueue;\r
 \r
 /*-----------------------------------------------------------*/\r
 \r
@@ -148,9 +154,14 @@ int main( void )
        vCreateBlockTimeTasks();\r
 \r
        /* Create the test tasks defined within this file. */\r
-       xTaskCreate( xRegisterTest1, "Reg1", configMINIMAL_STACK_SIZE, ( void * ) &usTest1CycleCounter, tskIDLE_PRIORITY, NULL );\r
-       xTaskCreate( xRegisterTest2, "Reg2", configMINIMAL_STACK_SIZE, ( void * ) &usTest2CycleCounter, tskIDLE_PRIORITY, NULL );\r
-       xTaskCreate( vCheckTask, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );\r
+       xTaskCreate( vCheckTask, ( signed portCHAR * ) "Check", mainCHECK_TAKS_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );\r
+\r
+       /* Start the task that will control the LCD.  This returns the handle\r
+       to the queue used to write text out to the task. */\r
+       xLCDQueue = xStartLCDTask();\r
+\r
+       /* Start the high frequency interrupt test. */\r
+       vSetupTimerTest( mainTEST_INTERRUPT_FREQUENCY );\r
 \r
        /* Finally start the scheduler. */\r
        vTaskStartScheduler();\r
@@ -169,11 +180,23 @@ static void prvSetupHardware( void )
 \r
 static void vCheckTask( void *pvParameters )\r
 {\r
-portTickType xLastExecutionTime;\r
+/* Used to wake the task at the correct frequency. */\r
+portTickType xLastExecutionTime; \r
+\r
+/* The maximum jitter time measured by the fast interrupt test. */\r
+extern unsigned portSHORT usMaxJitter ;\r
 \r
-/* Start with the no error delay.  The long delay will cause the LED to flash\r
-slowly. */\r
-portTickType xDelay = mainNO_ERROR_DELAY;\r
+/* Buffer into which the maximum jitter time is written as a string. */\r
+static portCHAR cStringBuffer[ mainMAX_STRING_LENGTH ];\r
+\r
+/* The message that is sent on the queue to the LCD task.  The first\r
+parameter is the minimum time (in ticks) that the message should be\r
+left on the LCD without being overwritten.  The second parameter is a pointer\r
+to the message to display itself. */\r
+xLCDMessage xMessage = { 0, cStringBuffer };\r
+\r
+/* Set to pdTRUE should an error be detected in any of the standard demo tasks. */\r
+unsigned portSHORT usErrorDetected = pdFALSE;\r
 \r
        /* Initialise xLastExecutionTime so the first call to vTaskDelayUntil()\r
        works correctly. */\r
@@ -182,235 +205,43 @@ portTickType xDelay = mainNO_ERROR_DELAY;
        for( ;; )\r
        {\r
                /* Wait until it is time for the next cycle. */\r
-               vTaskDelayUntil( &xLastExecutionTime, xDelay );\r
+               vTaskDelayUntil( &xLastExecutionTime, mainCHECK_TASK_PERIOD );\r
 \r
                /* Has an error been found in any of the standard demo tasks? */\r
 \r
                if( xAreIntegerMathsTaskStillRunning() != pdTRUE )\r
                {\r
                        usErrorDetected = pdTRUE;\r
+                       sprintf( cStringBuffer, "FAIL #1" );\r
                }\r
        \r
                if( xAreComTestTasksStillRunning() != pdTRUE )\r
                {\r
                        usErrorDetected = pdTRUE;\r
+                       sprintf( cStringBuffer, "FAIL #2" );\r
                }\r
 \r
                if( xAreBlockTimeTestTasksStillRunning() != pdTRUE )\r
                {\r
                        usErrorDetected = pdTRUE;\r
+                       sprintf( cStringBuffer, "FAIL #3" );\r
                }\r
 \r
                if( xAreBlockingQueuesStillRunning() != pdTRUE )\r
                {\r
                        usErrorDetected = pdTRUE;\r
+                       sprintf( cStringBuffer, "FAIL #4" );\r
                }\r
 \r
-\r
-               /* Are the register test tasks still cycling? */\r
-\r
-               if( usTest1CycleCounter == usPreviousTest1Count )\r
-               {\r
-                       usErrorDetected = pdTRUE;\r
-               }\r
-\r
-               if( usTest2CycleCounter == usPreviousTest2Count )\r
+               if( usErrorDetected == pdFALSE )\r
                {\r
-                       usErrorDetected = pdTRUE;\r
-               }\r
-\r
-               usPreviousTest2Count = usTest2CycleCounter;\r
-               usPreviousTest1Count = usTest1CycleCounter;\r
-\r
-               \r
-               /* If an error has been detected in any task then the delay will be\r
-               reduced to increase the cycle rate of this task.  This has the effect\r
-               of causing the LED to flash much faster giving a visual indication of\r
-               the error condition. */\r
-               if( usErrorDetected != pdFALSE )\r
-               {\r
-                       xDelay = mainERROR_DELAY;\r
+                       /* No errors have been discovered, so display the maximum jitter\r
+                       timer discovered by the "fast interrupt test". */\r
+                       sprintf( cStringBuffer, "%dns max jitter", ( portSHORT ) ( usMaxJitter - mainEXPECTED_CLOCKS_BETWEEN_INTERRUPTS ) * mainNS_PER_CLOCK );\r
                }\r
 \r
-               /* Finally, toggle the LED before returning to delay to wait for the\r
-               next cycle. */\r
-               vParTestToggleLED( mainCHECK_LED );\r
-       }\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-void xRegisterTest1( void *pvParameters )\r
-{\r
-/* This static so as not to use the frame pointer.   They are volatile\r
-also to avoid it being stored in a register that we clobber during the test. */\r
-static unsigned portSHORT * volatile pusParameter;\r
-\r
-       /* The variable incremented by this task is passed in as the parameter\r
-       even though it is defined within this file.  This is just to test the\r
-       parameter passing mechanism. */\r
-       pusParameter = pvParameters;\r
-\r
-       for( ;; )\r
-       {\r
-               /* Increment the variable to show this task is still cycling. */\r
-               ( *pusParameter )++;\r
-\r
-               /* Set the w registers to known values, then check that each register\r
-               contains the expected value.  See the explanation at the top of this\r
-               file for more information. */\r
-               asm volatile(   "mov.w  #0x0101, W0             \n"             \\r
-                                               "mov.w  #0x0102, W1             \n"             \\r
-                                               "mov.w  #0x0103, W2             \n"             \\r
-                                               "mov.w  #0x0104, W3             \n"             \\r
-                                               "mov.w  #0x0105, W4             \n"             \\r
-                                               "mov.w  #0x0106, W5             \n"             \\r
-                                               "mov.w  #0x0107, W6             \n"             \\r
-                                               "mov.w  #0x0108, W7             \n"             \\r
-                                               "mov.w  #0x0109, W8             \n"             \\r
-                                               "mov.w  #0x010a, W9             \n"             \\r
-                                               "mov.w  #0x010b, W10    \n"             \\r
-                                               "mov.w  #0x010c, W11    \n"             \\r
-                                               "mov.w  #0x010d, W12    \n"             \\r
-                                               "mov.w  #0x010e, W13    \n"             \\r
-                                               "mov.w  #0x010f, W14    \n"             \\r
-                                               "sub    #0x0101, W0             \n"             \\r
-                                               "cp0.w  W0                              \n"     \\r
-                                               "bra    NZ, ERROR_TEST1 \n"             \\r
-                                               "sub    #0x0102, W1             \n"             \\r
-                                               "cp0.w  W1                              \n"     \\r
-                                               "bra    NZ, ERROR_TEST1 \n"             \\r
-                                               "sub    #0x0103, W2             \n"             \\r
-                                               "cp0.w  W2                              \n"     \\r
-                                               "bra    NZ, ERROR_TEST1 \n"             \\r
-                                               "sub    #0x0104, W3             \n"             \\r
-                                               "cp0.w  W3                              \n"     \\r
-                                               "bra    NZ, ERROR_TEST1 \n"             \\r
-                                               "sub    #0x0105, W4             \n"             \\r
-                                               "cp0.w  W4                              \n"     \\r
-                                               "bra    NZ, ERROR_TEST1 \n"             \\r
-                                               "sub    #0x0106, W5             \n"             \\r
-                                               "cp0.w  W5                              \n"     \\r
-                                               "bra    NZ, ERROR_TEST1 \n"             \\r
-                                               "sub    #0x0107, W6             \n"             \\r
-                                               "cp0.w  W6                              \n"     \\r
-                                               "bra    NZ, ERROR_TEST1 \n"             \\r
-                                               "sub    #0x0108, W7             \n"             \\r
-                                               "cp0.w  W7                              \n"     \\r
-                                               "bra    NZ, ERROR_TEST1 \n"             \\r
-                                               "sub    #0x0109, W8             \n"             \\r
-                                               "cp0.w  W8                              \n"     \\r
-                                               "bra    NZ, ERROR_TEST1 \n"             \\r
-                                               "sub    #0x010a, W9             \n"             \\r
-                                               "cp0.w  W9                              \n"     \\r
-                                               "bra    NZ, ERROR_TEST1 \n"             \\r
-                                               "sub    #0x010b, W10    \n"             \\r
-                                               "cp0.w  W10                             \n"     \\r
-                                               "bra    NZ, ERROR_TEST1 \n"             \\r
-                                               "sub    #0x010c, W11    \n"             \\r
-                                               "cp0.w  W11                             \n"     \\r
-                                               "bra    NZ, ERROR_TEST1 \n"             \\r
-                                               "sub    #0x010d, W12    \n"             \\r
-                                               "cp0.w  W12                             \n"     \\r
-                                               "bra    NZ, ERROR_TEST1 \n"             \\r
-                                               "sub    #0x010e, W13    \n"             \\r
-                                               "cp0.w  W13                             \n"     \\r
-                                               "bra    NZ, ERROR_TEST1 \n"             \\r
-                                               "sub    #0x010f, W14    \n"             \\r
-                                               "cp0.w  W14                             \n"     \\r
-                                               "bra    NZ, ERROR_TEST1 \n"             \\r
-                                               "bra    NO_ERROR1               \n"     \\r
-                                               "ERROR_TEST1:                   \n"             \\r
-                                               "mov.w  #1, W0                  \n"             \\r
-                                               "mov.w  W0, _usErrorDetected\n" \\r
-                                               "NO_ERROR1:                             \n" );\r
-       }\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-void xRegisterTest2( void *pvParameters )\r
-{\r
-/* This static so as not to use the frame pointer.   They are volatile\r
-also to avoid it being stored in a register that we clobber during the test. */\r
-static unsigned portSHORT * volatile pusParameter;\r
-\r
-       /* The variable incremented by this task is passed in as the parameter\r
-       even though it is defined within this file.  This is just to test the\r
-       parameter passing mechanism. */\r
-       pusParameter = pvParameters;\r
-\r
-       for( ;; )\r
-       {\r
-               /* Increment the variable to show this task is still cycling. */\r
-               ( *pusParameter )++;\r
-\r
-               /* Set the w registers to known values, then check that each register\r
-               contains the expected value.  See the explanation at the top of this\r
-               file for more information. */\r
-               asm volatile(   "mov.w  #0x0100, W0             \n"             \\r
-                                               "mov.w  #0x0101, W1             \n"             \\r
-                                               "mov.w  #0x0102, W2             \n"             \\r
-                                               "mov.w  #0x0103, W3             \n"             \\r
-                                               "mov.w  #0x0104, W4             \n"             \\r
-                                               "mov.w  #0x0105, W5             \n"             \\r
-                                               "mov.w  #0x0106, W6             \n"             \\r
-                                               "mov.w  #0x0107, W7             \n"             \\r
-                                               "mov.w  #0x0108, W8             \n"             \\r
-                                               "mov.w  #0x0109, W9             \n"             \\r
-                                               "mov.w  #0x010a, W10    \n"             \\r
-                                               "mov.w  #0x010b, W11    \n"             \\r
-                                               "mov.w  #0x010c, W12    \n"             \\r
-                                               "mov.w  #0x010d, W13    \n"             \\r
-                                               "mov.w  #0x010e, W14    \n"             \\r
-                                               "sub    #0x0100, W0             \n"             \\r
-                                               "cp0.w  W0                              \n"     \\r
-                                               "bra    NZ, ERROR_TEST2 \n"             \\r
-                                               "sub    #0x0101, W1             \n"             \\r
-                                               "cp0.w  W1                              \n"     \\r
-                                               "bra    NZ, ERROR_TEST2 \n"             \\r
-                                               "sub    #0x0102, W2             \n"             \\r
-                                               "cp0.w  W2                              \n"     \\r
-                                               "bra    NZ, ERROR_TEST2 \n"             \\r
-                                               "sub    #0x0103, W3             \n"             \\r
-                                               "cp0.w  W3                              \n"     \\r
-                                               "bra    NZ, ERROR_TEST2 \n"             \\r
-                                               "sub    #0x0104, W4             \n"             \\r
-                                               "cp0.w  W4                              \n"     \\r
-                                               "bra    NZ, ERROR_TEST2 \n"             \\r
-                                               "sub    #0x0105, W5             \n"             \\r
-                                               "cp0.w  W5                              \n"     \\r
-                                               "bra    NZ, ERROR_TEST2 \n"             \\r
-                                               "sub    #0x0106, W6             \n"             \\r
-                                               "cp0.w  W6                              \n"     \\r
-                                               "bra    NZ, ERROR_TEST2 \n"             \\r
-                                               "sub    #0x0107, W7             \n"             \\r
-                                               "cp0.w  W7                              \n"     \\r
-                                               "bra    NZ, ERROR_TEST2 \n"             \\r
-                                               "sub    #0x0108, W8             \n"             \\r
-                                               "cp0.w  W8                              \n"     \\r
-                                               "bra    NZ, ERROR_TEST2 \n"             \\r
-                                               "sub    #0x0109, W9             \n"             \\r
-                                               "cp0.w  W9                              \n"     \\r
-                                               "bra    NZ, ERROR_TEST2 \n"             \\r
-                                               "sub    #0x010a, W10    \n"             \\r
-                                               "cp0.w  W10                             \n"     \\r
-                                               "bra    NZ, ERROR_TEST2 \n"             \\r
-                                               "sub    #0x010b, W11    \n"             \\r
-                                               "cp0.w  W11                             \n"     \\r
-                                               "bra    NZ, ERROR_TEST2 \n"             \\r
-                                               "sub    #0x010c, W12    \n"             \\r
-                                               "cp0.w  W12                             \n"     \\r
-                                               "bra    NZ, ERROR_TEST2 \n"             \\r
-                                               "sub    #0x010d, W13    \n"             \\r
-                                               "cp0.w  W13                             \n"     \\r
-                                               "bra    NZ, ERROR_TEST2 \n"             \\r
-                                               "sub    #0x010e, W14    \n"             \\r
-                                               "cp0.w  W14                             \n"     \\r
-                                               "bra    NZ, ERROR_TEST2 \n"             \\r
-                                               "bra    NO_ERROR2               \n"     \\r
-                                               "ERROR_TEST2:                   \n"             \\r
-                                               "mov.w  #1, W0                  \n"             \\r
-                                               "mov.w  W0, _usErrorDetected\n" \\r
-                                               "NO_ERROR2:                             \n" );\r
+               /* Send the message to the LCD gatekeeper for display. */\r
+               xQueueSend( xLCDQueue, &xMessage, portMAX_DELAY );\r
        }\r
 }\r
 /*-----------------------------------------------------------*/\r
index 88a09887bdd4020bbf1059551606873f1bffd435..dcfb16ddbe049a9dc0d07945501af8e4bcaa7f3e 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
@@ -117,8 +117,8 @@ portCHAR cChar;
 \r
        IFS1bits.U2RXIF = serCLEAR_FLAG;\r
        IFS1bits.U2TXIF = serCLEAR_FLAG;\r
-       IPC7bits.U2RXIP = portKERNEL_INTERRUPT_PRIORITY;\r
-       IPC7bits.U2TXIP = portKERNEL_INTERRUPT_PRIORITY;\r
+       IPC7bits.U2RXIP = configKERNEL_INTERRUPT_PRIORITY;\r
+       IPC7bits.U2TXIP = configKERNEL_INTERRUPT_PRIORITY;\r
        IEC1bits.U2TXIE = serINTERRUPT_ENABLE;\r
        IEC1bits.U2RXIE = serINTERRUPT_ENABLE;\r
 \r
@@ -180,10 +180,7 @@ void vSerialClose( xComPortHandle xPort )
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-volatile short s = 0;\r
-char c[80] = {0};\r
-\r
-void __attribute__((__interrupt__)) _U2RXInterrupt( void )\r
+void __attribute__((__interrupt__, auto_psv)) _U2RXInterrupt( void )\r
 {\r
 portCHAR cChar;\r
 portBASE_TYPE xYieldRequired = pdFALSE;\r
@@ -205,7 +202,7 @@ portBASE_TYPE xYieldRequired = pdFALSE;
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-void __attribute__((__interrupt__)) _U2TXInterrupt( void )\r
+void __attribute__((__interrupt__, auto_psv)) _U2TXInterrupt( void )\r
 {\r
 signed portCHAR cChar;\r
 portBASE_TYPE xTaskWoken = pdFALSE;\r
diff --git a/Demo/PIC24_MPLAB/timertest.c b/Demo/PIC24_MPLAB/timertest.c
new file mode 100644 (file)
index 0000000..633c2d2
--- /dev/null
@@ -0,0 +1,144 @@
+/*\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
+\r
+       This file is part of the FreeRTOS.org distribution.\r
+\r
+       FreeRTOS.org is free software; you can redistribute it and/or modify\r
+       it under the terms of the GNU General Public License as published by\r
+       the Free Software Foundation; either version 2 of the License, or\r
+       (at your option) any later version.\r
+\r
+       FreeRTOS.org is distributed in the hope that it will be useful,\r
+       but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+       GNU General Public License for more details.\r
+\r
+       You should have received a copy of the GNU General Public License\r
+       along with FreeRTOS.org; if not, write to the Free Software\r
+       Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+\r
+       A special exception to the GPL can be applied should you wish to distribute\r
+       a combined work that includes FreeRTOS.org, without being obliged to provide\r
+       the source code for any proprietary components.  See the licensing section \r
+       of http://www.FreeRTOS.org for full details of how and when the exception\r
+       can be applied.\r
+\r
+       ***************************************************************************\r
+       See http://www.FreeRTOS.org for documentation, latest information, license \r
+       and contact details.  Please ensure to read the configuration and relevant \r
+       port sections of the online documentation.\r
+\r
+       Also see http://www.SafeRTOS.com for an IEC 61508 compliant version along\r
+       with commercial development and support options.\r
+       ***************************************************************************\r
+*/\r
+\r
+/* High speed timer test as described in main.c. */\r
+\r
+\r
+/* Scheduler includes. */\r
+#include "FreeRTOS.h"\r
+\r
+/* Demo includes. */\r
+#include "partest.h"\r
+\r
+/* The number of interrupts to pass before we start looking at the jitter. */\r
+#define timerSETTLE_TIME                       5\r
+\r
+/* The maximum value the 16bit timer can contain. */\r
+#define timerMAX_COUNT                         0xffff\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * Measure the time between this interrupt and the previous interrupt to \r
+ * calculate the timing jitter.  Remember the maximum value the jitter has\r
+ * ever been calculated to be.\r
+ */\r
+static void prvCalculateAndStoreJitter( void );\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/* The maximum time (in processor clocks) between two consecutive timer\r
+interrupts so far. */\r
+unsigned portSHORT usMaxJitter = 0;\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void vSetupTimerTest( unsigned portSHORT usFrequencyHz )\r
+{\r
+       /* T2 is used to generate interrupts.  T4 is used to provide an accurate\r
+       time measurement. */\r
+       T2CON = 0;\r
+       T4CON = 0;\r
+       TMR2 = 0;\r
+       TMR4 = 0;\r
+\r
+       /* Timer 2 is going to interrupt at usFrequencyHz Hz. */\r
+       PR2 = ( unsigned portSHORT ) ( configCPU_CLOCK_HZ / ( unsigned portLONG ) usFrequencyHz );\r
+\r
+       /* Timer 4 is going to free run from minimum to maximum value. */\r
+       PR4 = ( unsigned portSHORT ) timerMAX_COUNT;\r
+\r
+       /* Setup timer 2 interrupt priority to be above the kernel priority so \r
+       the timer jitter is not effected by the kernel activity. */\r
+       IPC1bits.T2IP = configKERNEL_INTERRUPT_PRIORITY + 1;\r
+\r
+       /* Clear the interrupt as a starting condition. */\r
+       IFS0bits.T2IF = 0;\r
+\r
+       /* Enable the interrupt. */\r
+       IEC0bits.T2IE = 1;\r
+\r
+       /* Start both timers. */\r
+       T2CONbits.TON = 1;\r
+       T4CONbits.TON = 1;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvCalculateAndStoreJitter( void )\r
+{\r
+static unsigned portSHORT usLastCount = 0, usSettleCount = 0;\r
+unsigned portSHORT usThisCount, usDifference;\r
+\r
+       /* Capture the timer value as we enter the interrupt. */\r
+       usThisCount = TMR4;\r
+\r
+       if( usSettleCount >= timerSETTLE_TIME )\r
+       {\r
+               /* What is the difference between the timer value in this interrupt\r
+               and the value from the last interrupt. */\r
+               usDifference = usThisCount - usLastCount;\r
+\r
+               /* Store the difference in the timer values if it is larger than the\r
+               currently stored largest value.  The difference over and above the \r
+               expected difference will give the 'jitter' in the processing of these\r
+               interrupts. */\r
+               if( usDifference > usMaxJitter )\r
+               {\r
+                       usMaxJitter = usDifference;\r
+               }\r
+       }\r
+       else\r
+       {\r
+               /* Don't bother storing any values for the first couple of \r
+               interrupts. */\r
+               usSettleCount++;\r
+       }\r
+\r
+       /* Remember what the timer value was this time through, so we can calculate\r
+       the difference the next time through. */\r
+       usLastCount = usThisCount;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void __attribute__((__interrupt__, auto_psv)) _T2Interrupt( void )\r
+{\r
+       /* Work out the time between this and the previous interrupt. */\r
+       prvCalculateAndStoreJitter();\r
+\r
+       /* Clear the timer interrupt. */\r
+       IFS0bits.T2IF = 0;\r
+}\r
+\r
+\r
diff --git a/Demo/PIC24_MPLAB/timertest.h b/Demo/PIC24_MPLAB/timertest.h
new file mode 100644 (file)
index 0000000..a4b0aea
--- /dev/null
@@ -0,0 +1,45 @@
+/*\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
+\r
+       This file is part of the FreeRTOS.org distribution.\r
+\r
+       FreeRTOS.org is free software; you can redistribute it and/or modify\r
+       it under the terms of the GNU General Public License as published by\r
+       the Free Software Foundation; either version 2 of the License, or\r
+       (at your option) any later version.\r
+\r
+       FreeRTOS.org is distributed in the hope that it will be useful,\r
+       but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+       GNU General Public License for more details.\r
+\r
+       You should have received a copy of the GNU General Public License\r
+       along with FreeRTOS.org; if not, write to the Free Software\r
+       Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+\r
+       A special exception to the GPL can be applied should you wish to distribute\r
+       a combined work that includes FreeRTOS.org, without being obliged to provide\r
+       the source code for any proprietary components.  See the licensing section \r
+       of http://www.FreeRTOS.org for full details of how and when the exception\r
+       can be applied.\r
+\r
+       ***************************************************************************\r
+       See http://www.FreeRTOS.org for documentation, latest information, license \r
+       and contact details.  Please ensure to read the configuration and relevant \r
+       port sections of the online documentation.\r
+\r
+       Also see http://www.SafeRTOS.com for an IEC 61508 compliant version along\r
+       with commercial development and support options.\r
+       ***************************************************************************\r
+*/\r
+\r
+#ifndef TIMER_TEST_H\r
+#define TIMER_TEST_H\r
+\r
+/* Setup the high frequency timer interrupt. */\r
+void vSetupTimerTest( unsigned portSHORT usFrequencyHz );\r
+\r
+#endif /* TIMER_TEST_H */\r
+\r
+\r
+\r
index 3afa1ec2b769b46847993dc0a90637f09034b816..ca1809c7c704c98691e3e2b79f32f204cb8af067 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index 6bc4ed0a54faf2da87d244bad9a7e2c9cdbd80b4..cb11969fe9d325a6e39b8c17f17ab3d96f42aa39 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index 038ac2a8d577a5414d0d06014bd5120ec1570e6c..26d18081eb49ee228e8b620848575e78462e9a83 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index 31d34b6feab5d0c109647b59f47de9d967e32f17..8614ee505c64dbead37ab784189174c790b0da7d 100644 (file)
@@ -1,4 +1,4 @@
-#      FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+#      FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 #\r
 #      This file is part of the FreeRTOS.org distribution.\r
 #\r
index 0420602d947bfa47260d9eecd08404a3f7a9ad6e..c54e5bfd94a2798939052ae6d0cc0700c3d7e41f 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index e64cdd778e7375c2050a05e52254a71f63cdbede..d60bd2dd6cbd5754b1b2ad4e048c2da2a7862701 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index e09af3de8c4756b9a76be7a95b1e1edb60499590..b4290c02c212108754f755e9b9ac758948a6cad6 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index 8f5ebe8cb5ab31ed4dc42c168fc0de3ed73fea34..14117e37bc512cf29b76c3117f213a9208e3c0cf 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index ffb6d10daa9ce493cb83eb0a0d2968b29176e2d9..36b4ddc81fac1f477e46bd3970f6978a2d29a2a2 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index 8c765b4256ba39d6e3f0c24fe7dd76444309793e..e720a992c080a08b1ba6acbc97b2a9bb00625e6e 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index e171f0eeb702cb641e0ea245a997147ef7c70d84..7cd97e624b472a75e259c71428651a546022bd61 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index 980729898488c3e8e829b8e5ca54a7dae20cb9af..42887e96922a02f2d8246bd85920828004acc348 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index a945082bca9fce3130657cd5d2faec69b318daef..1486de8b93c1e8b9f3343aa3e2e199634b5ce2bb 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index 6dd10c68d4edd536742980a26d3eca9fe59e8ed6..156eab81b4e59d4252d127316fb0e9b494a9530e 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index 59b84fecfbfc319fe23370e379dc29c568d7034e..4e807fa06e649ee7a691e57be5ba66687976323f 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index a1dc90703805a31c08e473169b52a338ca11220d..9a30596ab97292f74c7cac85dbb5e009462d96b0 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index b412a18dc71a12eb2bf92153c623c3a5fe5205a2..3ca59cf9ed0c89c1f4598df689d9ede3a9e12dec 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index d8dbad01273b2c8ac826e9ace0e4b4ecd489ac25..f1a3680c19fc3f861112734280dd032290ddf194 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index 910058d1388b9f3308edc69f09d9957d8c436bc0..4cb28e7de77450432185bf92d699aa55cb21fe56 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index dfbf4d5ab4430493efa49c9a94691ae701e7aeac..deb65fc2f01a5619b70f4311bb7ec8db1ba8fbe7 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index e019ec08c89a4a7f459945fa3fe18dbf803f50e8..a13fb1a0278afc27bb4d4608708912813156a433 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index 7d2444f7cf6d7a24b9ab53cbdef48b261f91f47b..7fcd9f92dc565a7ca45f3e67e69b0d4daff53c0e 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index 196b611dbde4c85561126e6ae7e477dd91795c7a..312836b9028ebfd11409b478c04f87ae0d3f5f31 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index 8404e0f5668f829c68ed61aa5098ddb60bc3d18b..addd18ca18cfabb6a0d4e887049b643e12e363d7 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index 8f01de3c83b55a54eced9af7d11c5c81d48b75b9..86e5d6ddabdbba3ea3985fa096d5da8a2a867970 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index a654bdafe22f4c8833c7f6f7e7901728f7f4e9f3..7e9046cc5f4ef42cf92246d8ddba7ead40543337 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index de25fd9a19bdeeada36b05e320312901dc5b4cfc..25a5ac60896d876b38ab9cef254c2706000d7c5f 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-  FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+  FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
   This file is part of the FreeRTOS.org distribution.\r
 \r
index cee93fcd944f5527255b6967db5e0bde666c69bd..4c3858bc329226ffc7b901d8638d4afe8a7a4de0 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index edccee2c65dd4f342c5e2a513abd67e2ff097821..63aa74215391800f9905f2d35acce91dccf8f487 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index 48d0a384bc8224d73f659004ad8f0ce9b8b6eb06..43b210e64133e6c1a780fc67608ac27c9e38f960 100644 (file)
-/*
- * 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 <adam@sics.se>
- *
- */
-
-/* This is the part of the API that is linked with
-   the application */
-
-#include "lwip/opt.h"
-#include "lwip/api.h"
-#include "lwip/api_msg.h"
-#include "lwip/memp.h"
-
-
-struct
-netbuf *netbuf_new(void)
-{
-  struct netbuf *buf;
-
-  buf = memp_malloc(MEMP_NETBUF);
-  if (buf != NULL) {
-    buf->p = NULL;
-    buf->ptr = NULL;
-    return buf;
-  } else {
-    return NULL;
-  }
-}
-
-void
-netbuf_delete(struct netbuf *buf)
-{
-  if (buf != NULL) {
-    if (buf->p != NULL) {
-      pbuf_free(buf->p);
-      buf->p = buf->ptr = NULL;
-    }
-    memp_free(MEMP_NETBUF, buf);
-  }
-}
-
-void *
-netbuf_alloc(struct netbuf *buf, u16_t size)
-{
-  /* Deallocate any previously allocated memory. */
-  if (buf->p != NULL) {
-    pbuf_free(buf->p);
-  }
-  buf->p = pbuf_alloc(PBUF_TRANSPORT, size, PBUF_RAM);
-  if (buf->p == NULL) {
-     return NULL;
-  }
-  buf->ptr = buf->p;
-  return buf->p->payload;
-}
-
-void
-netbuf_free(struct netbuf *buf)
-{
-  if (buf->p != NULL) {
-    pbuf_free(buf->p);
-  }
-  buf->p = buf->ptr = NULL;
-}
-
-void
-netbuf_ref(struct netbuf *buf, void *dataptr, u16_t size)
-{
-  if (buf->p != NULL) {
-    pbuf_free(buf->p);
-  }
-  buf->p = pbuf_alloc(PBUF_TRANSPORT, 0, PBUF_REF);
-  buf->p->payload = dataptr;
-  buf->p->len = buf->p->tot_len = size;
-  buf->ptr = buf->p;
-}
-
-void
-netbuf_chain(struct netbuf *head, struct netbuf *tail)
-{
-  pbuf_chain(head->p, tail->p);
-  head->ptr = head->p;
-  memp_free(MEMP_NETBUF, tail);
-}
-
-u16_t
-netbuf_len(struct netbuf *buf)
-{
-  return buf->p->tot_len;
-}
-
-err_t
-netbuf_data(struct netbuf *buf, void **dataptr, u16_t *len)
-{
-  if (buf->ptr == NULL) {
-    return ERR_BUF;
-  }
-  *dataptr = buf->ptr->payload;
-  *len = buf->ptr->len;
-  return ERR_OK;
-}
-
-s8_t
-netbuf_next(struct netbuf *buf)
-{
-  if (buf->ptr->next == NULL) {
-    return -1;
-  }
-  buf->ptr = buf->ptr->next;
-  if (buf->ptr->next == NULL) {
-    return 1;
-  }
-  return 0;
-}
-
-void
-netbuf_first(struct netbuf *buf)
-{
-  buf->ptr = buf->p;
-}
-
-void
-netbuf_copy_partial(struct netbuf *buf, void *dataptr, u16_t len, u16_t offset)
-{
-  struct pbuf *p;
-  u16_t i, left;
-
-  left = 0;
-
-  if(buf == NULL || dataptr == NULL) {
-    return;
-  }
-  
-  /* This implementation is bad. It should use bcopy
-     instead. */
-  for(p = buf->p; left < len && p != NULL; p = p->next) {
-    if (offset != 0 && offset >= p->len) {
-      offset -= p->len;
-    } else {    
-      for(i = offset; i < p->len; ++i) {
-  ((char *)dataptr)[left] = ((char *)p->payload)[i];
-  if (++left >= len) {
-    return;
-  }
-      }
-      offset = 0;
-    }
-  }
-}
-
-void
-netbuf_copy(struct netbuf *buf, void *dataptr, u16_t len)
-{
-  netbuf_copy_partial(buf, dataptr, len, 0);
-}
-
-struct ip_addr *
-netbuf_fromaddr(struct netbuf *buf)
-{
-  return buf->fromaddr;
-}
-
-u16_t
-netbuf_fromport(struct netbuf *buf)
-{
-  return buf->fromport;
-}
-
-struct
-netconn *netconn_new_with_proto_and_callback(enum netconn_type t, u16_t proto,
-                                   void (*callback)(struct netconn *, enum netconn_evt, u16_t len))
-{
-  struct netconn *conn;
-  struct api_msg *msg;
-
-  conn = memp_malloc(MEMP_NETCONN);
-  if (conn == NULL) {
-    return NULL;
-  }
-  
-  conn->err = ERR_OK;
-  conn->type = t;
-  conn->pcb.tcp = NULL;
-
-  if ((conn->mbox = sys_mbox_new()) == SYS_MBOX_NULL) {
-    memp_free(MEMP_NETCONN, conn);
-    return NULL;
-  }
-  conn->recvmbox = SYS_MBOX_NULL;
-  conn->acceptmbox = SYS_MBOX_NULL;
-  conn->sem = SYS_SEM_NULL;
-  conn->state = NETCONN_NONE;
-  conn->socket = 0;
-  conn->callback = callback;
-  conn->recv_avail = 0;
-
-  if((msg = memp_malloc(MEMP_API_MSG)) == NULL) {
-    memp_free(MEMP_NETCONN, conn);
-    return NULL;
-  }
-  
-  msg->type = API_MSG_NEWCONN;
-  msg->msg.msg.bc.port = proto; /* misusing the port field */
-  msg->msg.conn = conn;
-  api_msg_post(msg);  
-  sys_mbox_fetch(conn->mbox, NULL);
-  memp_free(MEMP_API_MSG, msg);
-
-  if ( conn->err != ERR_OK ) {
-    memp_free(MEMP_NETCONN, conn);
-    return NULL;
-  }
-
-  return conn;
-}
-
-
-struct
-netconn *netconn_new(enum netconn_type t)
-{
-  return netconn_new_with_proto_and_callback(t,0,NULL);
-}
-
-struct
-netconn *netconn_new_with_callback(enum netconn_type t,
-                                   void (*callback)(struct netconn *, enum netconn_evt, u16_t len))
-{
-  return netconn_new_with_proto_and_callback(t,0,callback);
-}
-
-
-err_t
-netconn_delete(struct netconn *conn)
-{
-  struct api_msg *msg;
-  void *mem;
-  
-  if (conn == NULL) {
-    return ERR_OK;
-  }
-  
-  if ((msg = memp_malloc(MEMP_API_MSG)) == NULL) {
-    return ERR_MEM;
-  }
-  
-  msg->type = API_MSG_DELCONN;
-  msg->msg.conn = conn;
-  api_msg_post(msg);  
-  sys_mbox_fetch(conn->mbox, NULL);
-  memp_free(MEMP_API_MSG, msg);
-
-  /* Drain the recvmbox. */
-  if (conn->recvmbox != SYS_MBOX_NULL) {
-    while (sys_arch_mbox_fetch(conn->recvmbox, &mem, 1) != SYS_ARCH_TIMEOUT) {
-      if (conn->type == NETCONN_TCP) {
-        if(mem != NULL)
-          pbuf_free((struct pbuf *)mem);
-      } else {
-        netbuf_delete((struct netbuf *)mem);
-      }
-    }
-    sys_mbox_free(conn->recvmbox);
-    conn->recvmbox = SYS_MBOX_NULL;
-  }
-
-  /* Drain the acceptmbox. */
-  if (conn->acceptmbox != SYS_MBOX_NULL) {
-    while (sys_arch_mbox_fetch(conn->acceptmbox, &mem, 1) != SYS_ARCH_TIMEOUT) {
-      netconn_delete((struct netconn *)mem);
-    }
-    
-    sys_mbox_free(conn->acceptmbox);
-    conn->acceptmbox = SYS_MBOX_NULL;
-  }
-
-  sys_mbox_free(conn->mbox);
-  conn->mbox = SYS_MBOX_NULL;
-  if (conn->sem != SYS_SEM_NULL) {
-    sys_sem_free(conn->sem);
-  }
-  /*  conn->sem = SYS_SEM_NULL;*/
-  memp_free(MEMP_NETCONN, conn);
-  return ERR_OK;
-}
-
-enum netconn_type
-netconn_type(struct netconn *conn)
-{
-  return conn->type;
-}
-
-err_t
-netconn_peer(struct netconn *conn, struct ip_addr *addr,
-       u16_t *port)
-{
-  switch (conn->type) {
-  case NETCONN_RAW:
-    /* return an error as connecting is only a helper for upper layers */
-    return ERR_CONN;
-  case NETCONN_UDPLITE:
-  case NETCONN_UDPNOCHKSUM:
-  case NETCONN_UDP:
-    if (conn->pcb.udp == NULL ||
-  ((conn->pcb.udp->flags & UDP_FLAGS_CONNECTED) == 0))
-     return ERR_CONN;
-    *addr = (conn->pcb.udp->remote_ip);
-    *port = conn->pcb.udp->remote_port;
-    break;
-  case NETCONN_TCP:
-    if (conn->pcb.tcp == NULL)
-      return ERR_CONN;
-    *addr = (conn->pcb.tcp->remote_ip);
-    *port = conn->pcb.tcp->remote_port;
-    break;
-  }
-  return (conn->err = ERR_OK);
-}
-
-err_t
-netconn_addr(struct netconn *conn, struct ip_addr **addr,
-       u16_t *port)
-{
-  switch (conn->type) {
-  case NETCONN_RAW:
-    *addr = &(conn->pcb.raw->local_ip);
-    *port = conn->pcb.raw->protocol;
-    break;
-  case NETCONN_UDPLITE:
-  case NETCONN_UDPNOCHKSUM:
-  case NETCONN_UDP:
-    *addr = &(conn->pcb.udp->local_ip);
-    *port = conn->pcb.udp->local_port;
-    break;
-  case NETCONN_TCP:
-    *addr = &(conn->pcb.tcp->local_ip);
-    *port = conn->pcb.tcp->local_port;
-    break;
-  }
-  return (conn->err = ERR_OK);
-}
-
-err_t
-netconn_bind(struct netconn *conn, struct ip_addr *addr,
-      u16_t port)
-{
-  struct api_msg *msg;
-
-  if (conn == NULL) {
-    return ERR_VAL;
-  }
-
-  if (conn->type != NETCONN_TCP &&
-     conn->recvmbox == SYS_MBOX_NULL) {
-    if ((conn->recvmbox = sys_mbox_new()) == SYS_MBOX_NULL) {
-      return ERR_MEM;
-    }
-  }
-  
-  if ((msg = memp_malloc(MEMP_API_MSG)) == NULL) {
-    return (conn->err = ERR_MEM);
-  }
-  msg->type = API_MSG_BIND;
-  msg->msg.conn = conn;
-  msg->msg.msg.bc.ipaddr = addr;
-  msg->msg.msg.bc.port = port;
-  api_msg_post(msg);
-  sys_mbox_fetch(conn->mbox, NULL);
-  memp_free(MEMP_API_MSG, msg);
-  return conn->err;
-}
-
-
-err_t
-netconn_connect(struct netconn *conn, struct ip_addr *addr,
-       u16_t port)
-{
-  struct api_msg *msg;
-  
-  if (conn == NULL) {
-    return ERR_VAL;
-  }
-
-
-  if (conn->recvmbox == SYS_MBOX_NULL) {
-    if ((conn->recvmbox = sys_mbox_new()) == SYS_MBOX_NULL) {
-      return ERR_MEM;
-    }
-  }
-  
-  if ((msg = memp_malloc(MEMP_API_MSG)) == NULL) {
-    return ERR_MEM;
-  }
-  msg->type = API_MSG_CONNECT;
-  msg->msg.conn = conn;  
-  msg->msg.msg.bc.ipaddr = addr;
-  msg->msg.msg.bc.port = port;
-  api_msg_post(msg);
-  sys_mbox_fetch(conn->mbox, NULL);
-  memp_free(MEMP_API_MSG, msg);
-  return conn->err;
-}
-
-err_t
-netconn_disconnect(struct netconn *conn)
-{
-  struct api_msg *msg;
-  
-  if (conn == NULL) {
-    return ERR_VAL;
-  }
-
-  if ((msg = memp_malloc(MEMP_API_MSG)) == NULL) {
-    return ERR_MEM;
-  }
-  msg->type = API_MSG_DISCONNECT;
-  msg->msg.conn = conn;  
-  api_msg_post(msg);
-  sys_mbox_fetch(conn->mbox, NULL);
-  memp_free(MEMP_API_MSG, msg);
-  return conn->err;
-
-}
-
-err_t
-netconn_listen(struct netconn *conn)
-{
-  struct api_msg *msg;
-
-  if (conn == NULL) {
-    return ERR_VAL;
-  }
-
-  if (conn->acceptmbox == SYS_MBOX_NULL) {
-    conn->acceptmbox = sys_mbox_new();
-    if (conn->acceptmbox == SYS_MBOX_NULL) {
-      return ERR_MEM;
-    }
-  }
-  
-  if ((msg = memp_malloc(MEMP_API_MSG)) == NULL) {
-    return (conn->err = ERR_MEM);
-  }
-  msg->type = API_MSG_LISTEN;
-  msg->msg.conn = conn;
-  api_msg_post(msg);
-  sys_mbox_fetch(conn->mbox, NULL);
-  memp_free(MEMP_API_MSG, msg);
-  return conn->err;
-}
-
-struct netconn *
-netconn_accept(struct netconn *conn)
-{
-  struct netconn *newconn;
-  
-  if (conn == NULL) {
-    return NULL;
-  }
-  
-  sys_mbox_fetch(conn->acceptmbox, (void **)&newconn);
-  /* Register event with callback */
-  if (conn->callback)
-      (*conn->callback)(conn, NETCONN_EVT_RCVMINUS, 0);
-  
-  return newconn;
-}
-
-struct netbuf *
-netconn_recv(struct netconn *conn)
-{
-  struct api_msg *msg;
-  struct netbuf *buf;
-  struct pbuf *p;
-  u16_t len;
-    
-  if (conn == NULL) {
-    return NULL;
-  }
-  
-  if (conn->recvmbox == SYS_MBOX_NULL) {
-    conn->err = ERR_CONN;
-    return NULL;
-  }
-
-  if (conn->err != ERR_OK) {
-    return NULL;
-  }
-
-  if (conn->type == NETCONN_TCP) {
-    if (conn->pcb.tcp->state == LISTEN) {
-      conn->err = ERR_CONN;
-      return NULL;
-    }
-
-
-    buf = memp_malloc(MEMP_NETBUF);
-
-    if (buf == NULL) {
-      conn->err = ERR_MEM;
-      return NULL;
-    }
-    
-    sys_mbox_fetch(conn->recvmbox, (void **)&p);
-
-    if (p != NULL)
-    {
-        len = p->tot_len;
-        conn->recv_avail -= len;
-    }
-    else
-        len = 0;
-    
-    /* Register event with callback */
-      if (conn->callback)
-        (*conn->callback)(conn, NETCONN_EVT_RCVMINUS, len);
-
-    /* If we are closed, we indicate that we no longer wish to receive
-       data by setting conn->recvmbox to SYS_MBOX_NULL. */
-    if (p == NULL) {
-      memp_free(MEMP_NETBUF, buf);
-      sys_mbox_free(conn->recvmbox);
-      conn->recvmbox = SYS_MBOX_NULL;
-      return NULL;
-    }
-
-    buf->p = p;
-    buf->ptr = p;
-    buf->fromport = 0;
-    buf->fromaddr = NULL;
-
-    /* Let the stack know that we have taken the data. */
-    if ((msg = memp_malloc(MEMP_API_MSG)) == NULL) {
-      conn->err = ERR_MEM;
-      return buf;
-    }
-    msg->type = API_MSG_RECV;
-    msg->msg.conn = conn;
-    if (buf != NULL) {
-      msg->msg.msg.len = buf->p->tot_len;
-    } else {
-      msg->msg.msg.len = 1;
-    }
-    api_msg_post(msg);
-
-    sys_mbox_fetch(conn->mbox, NULL);
-    memp_free(MEMP_API_MSG, msg);
-  } else {
-    sys_mbox_fetch(conn->recvmbox, (void **)&buf);
-  conn->recv_avail -= buf->p->tot_len;
-    /* Register event with callback */
-    if (conn->callback)
-        (*conn->callback)(conn, NETCONN_EVT_RCVMINUS, buf->p->tot_len);
-  }
-
-  
-
-    
-  LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_recv: received %p (err %d)\n", (void *)buf, conn->err));
-
-
-  return buf;
-}
-
-err_t
-netconn_send(struct netconn *conn, struct netbuf *buf)
-{
-  struct api_msg *msg;
-
-  if (conn == NULL) {
-    return ERR_VAL;
-  }
-
-  if (conn->err != ERR_OK) {
-    return conn->err;
-  }
-
-  if ((msg = memp_malloc(MEMP_API_MSG)) == NULL) {
-    return (conn->err = ERR_MEM);
-  }
-
-  LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_send: sending %d bytes\n", buf->p->tot_len));
-  msg->type = API_MSG_SEND;
-  msg->msg.conn = conn;
-  msg->msg.msg.p = buf->p;
-  api_msg_post(msg);
-
-  sys_mbox_fetch(conn->mbox, NULL);
-  memp_free(MEMP_API_MSG, msg);
-  return conn->err;
-}
-
-err_t
-netconn_write(struct netconn *conn, void *dataptr, u16_t size, u8_t copy)
-{
-  struct api_msg *msg;
-  u16_t len;
-  
-  if (conn == NULL) {
-    return ERR_VAL;
-  }
-
-  if (conn->err != ERR_OK) {
-    return conn->err;
-  }
-  
-  if (conn->sem == SYS_SEM_NULL) {
-    conn->sem = sys_sem_new(0);
-    if (conn->sem == SYS_SEM_NULL) {
-      return ERR_MEM;
-    }
-  }
-
-  if ((msg = memp_malloc(MEMP_API_MSG)) == NULL) {
-    return (conn->err = ERR_MEM);
-  }
-  msg->type = API_MSG_WRITE;
-  msg->msg.conn = conn;
-        
-
-  conn->state = NETCONN_WRITE;
-  while (conn->err == ERR_OK && size > 0) {
-    msg->msg.msg.w.dataptr = dataptr;
-    msg->msg.msg.w.copy = copy;
-    
-    if (conn->type == NETCONN_TCP) {
-      if (tcp_sndbuf(conn->pcb.tcp) == 0) {
-  sys_sem_wait(conn->sem);
-  if (conn->err != ERR_OK) {
-    goto ret;
-  }
-      }
-      if (size > tcp_sndbuf(conn->pcb.tcp)) {
-  /* We cannot send more than one send buffer's worth of data at a
-     time. */
-  len = tcp_sndbuf(conn->pcb.tcp);
-      } else {
-  len = size;
-      }
-    } else {
-      len = size;
-    }
-    
-    LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_write: writing %d bytes (%d)\n", len, copy));
-    msg->msg.msg.w.len = len;
-    api_msg_post(msg);
-    sys_mbox_fetch(conn->mbox, NULL);    
-    if (conn->err == ERR_OK) {
-      dataptr = (void *)((char *)dataptr + len);
-      size -= len;
-    } else if (conn->err == ERR_MEM) {
-      conn->err = ERR_OK;
-      sys_sem_wait(conn->sem);
-    } else {
-      goto ret;
-    }
-  }
- ret:
-  memp_free(MEMP_API_MSG, msg);
-  conn->state = NETCONN_NONE;
-  if (conn->sem != SYS_SEM_NULL) {
-    sys_sem_free(conn->sem);
-    conn->sem = SYS_SEM_NULL;
-  }
-  
-  return conn->err;
-}
-
-err_t
-netconn_close(struct netconn *conn)
-{
-  struct api_msg *msg;
-
-  if (conn == NULL) {
-    return ERR_VAL;
-  }
-  if ((msg = memp_malloc(MEMP_API_MSG)) == NULL) {
-    return (conn->err = ERR_MEM);
-  }
-
-  conn->state = NETCONN_CLOSE;
- again:
-  msg->type = API_MSG_CLOSE;
-  msg->msg.conn = conn;
-  api_msg_post(msg);
-  sys_mbox_fetch(conn->mbox, NULL);
-  if (conn->err == ERR_MEM &&
-     conn->sem != SYS_SEM_NULL) {
-    sys_sem_wait(conn->sem);
-    goto again;
-  }
-  conn->state = NETCONN_NONE;
-  memp_free(MEMP_API_MSG, msg);
-  return conn->err;
-}
-
-err_t
-netconn_err(struct netconn *conn)
-{
-  return conn->err;
-}
-
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+\r
+/* This is the part of the API that is linked with\r
+   the application */\r
+\r
+#include "lwip/opt.h"\r
+#include "lwip/api.h"\r
+#include "lwip/api_msg.h"\r
+#include "lwip/memp.h"\r
+\r
+\r
+struct\r
+netbuf *netbuf_new(void)\r
+{\r
+  struct netbuf *buf;\r
+\r
+  buf = memp_malloc(MEMP_NETBUF);\r
+  if (buf != NULL) {\r
+    buf->p = NULL;\r
+    buf->ptr = NULL;\r
+    return buf;\r
+  } else {\r
+    return NULL;\r
+  }\r
+}\r
+\r
+void\r
+netbuf_delete(struct netbuf *buf)\r
+{\r
+  if (buf != NULL) {\r
+    if (buf->p != NULL) {\r
+      pbuf_free(buf->p);\r
+      buf->p = buf->ptr = NULL;\r
+    }\r
+    memp_free(MEMP_NETBUF, buf);\r
+  }\r
+}\r
+\r
+void *\r
+netbuf_alloc(struct netbuf *buf, u16_t size)\r
+{\r
+  /* Deallocate any previously allocated memory. */\r
+  if (buf->p != NULL) {\r
+    pbuf_free(buf->p);\r
+  }\r
+  buf->p = pbuf_alloc(PBUF_TRANSPORT, size, PBUF_RAM);\r
+  if (buf->p == NULL) {\r
+     return NULL;\r
+  }\r
+  buf->ptr = buf->p;\r
+  return buf->p->payload;\r
+}\r
+\r
+void\r
+netbuf_free(struct netbuf *buf)\r
+{\r
+  if (buf->p != NULL) {\r
+    pbuf_free(buf->p);\r
+  }\r
+  buf->p = buf->ptr = NULL;\r
+}\r
+\r
+void\r
+netbuf_ref(struct netbuf *buf, void *dataptr, u16_t size)\r
+{\r
+  if (buf->p != NULL) {\r
+    pbuf_free(buf->p);\r
+  }\r
+  buf->p = pbuf_alloc(PBUF_TRANSPORT, 0, PBUF_REF);\r
+  buf->p->payload = dataptr;\r
+  buf->p->len = buf->p->tot_len = size;\r
+  buf->ptr = buf->p;\r
+}\r
+\r
+void\r
+netbuf_chain(struct netbuf *head, struct netbuf *tail)\r
+{\r
+  pbuf_chain(head->p, tail->p);\r
+  head->ptr = head->p;\r
+  memp_free(MEMP_NETBUF, tail);\r
+}\r
+\r
+u16_t\r
+netbuf_len(struct netbuf *buf)\r
+{\r
+  return buf->p->tot_len;\r
+}\r
+\r
+err_t\r
+netbuf_data(struct netbuf *buf, void **dataptr, u16_t *len)\r
+{\r
+  if (buf->ptr == NULL) {\r
+    return ERR_BUF;\r
+  }\r
+  *dataptr = buf->ptr->payload;\r
+  *len = buf->ptr->len;\r
+  return ERR_OK;\r
+}\r
+\r
+s8_t\r
+netbuf_next(struct netbuf *buf)\r
+{\r
+  if (buf->ptr->next == NULL) {\r
+    return -1;\r
+  }\r
+  buf->ptr = buf->ptr->next;\r
+  if (buf->ptr->next == NULL) {\r
+    return 1;\r
+  }\r
+  return 0;\r
+}\r
+\r
+void\r
+netbuf_first(struct netbuf *buf)\r
+{\r
+  buf->ptr = buf->p;\r
+}\r
+\r
+void\r
+netbuf_copy_partial(struct netbuf *buf, void *dataptr, u16_t len, u16_t offset)\r
+{\r
+  struct pbuf *p;\r
+  u16_t i, left;\r
+\r
+  left = 0;\r
+\r
+  if(buf == NULL || dataptr == NULL) {\r
+    return;\r
+  }\r
+  \r
+  /* This implementation is bad. It should use bcopy\r
+     instead. */\r
+  for(p = buf->p; left < len && p != NULL; p = p->next) {\r
+    if (offset != 0 && offset >= p->len) {\r
+      offset -= p->len;\r
+    } else {    \r
+      for(i = offset; i < p->len; ++i) {\r
+  ((char *)dataptr)[left] = ((char *)p->payload)[i];\r
+  if (++left >= len) {\r
+    return;\r
+  }\r
+      }\r
+      offset = 0;\r
+    }\r
+  }\r
+}\r
+\r
+void\r
+netbuf_copy(struct netbuf *buf, void *dataptr, u16_t len)\r
+{\r
+  netbuf_copy_partial(buf, dataptr, len, 0);\r
+}\r
+\r
+struct ip_addr *\r
+netbuf_fromaddr(struct netbuf *buf)\r
+{\r
+  return buf->fromaddr;\r
+}\r
+\r
+u16_t\r
+netbuf_fromport(struct netbuf *buf)\r
+{\r
+  return buf->fromport;\r
+}\r
+\r
+struct\r
+netconn *netconn_new_with_proto_and_callback(enum netconn_type t, u16_t proto,\r
+                                   void (*callback)(struct netconn *, enum netconn_evt, u16_t len))\r
+{\r
+  struct netconn *conn;\r
+  struct api_msg *msg;\r
+\r
+  conn = memp_malloc(MEMP_NETCONN);\r
+  if (conn == NULL) {\r
+    return NULL;\r
+  }\r
+  \r
+  conn->err = ERR_OK;\r
+  conn->type = t;\r
+  conn->pcb.tcp = NULL;\r
+\r
+  if ((conn->mbox = sys_mbox_new()) == SYS_MBOX_NULL) {\r
+    memp_free(MEMP_NETCONN, conn);\r
+    return NULL;\r
+  }\r
+  conn->recvmbox = SYS_MBOX_NULL;\r
+  conn->acceptmbox = SYS_MBOX_NULL;\r
+  conn->sem = SYS_SEM_NULL;\r
+  conn->state = NETCONN_NONE;\r
+  conn->socket = 0;\r
+  conn->callback = callback;\r
+  conn->recv_avail = 0;\r
+\r
+  if((msg = memp_malloc(MEMP_API_MSG)) == NULL) {\r
+    memp_free(MEMP_NETCONN, conn);\r
+    return NULL;\r
+  }\r
+  \r
+  msg->type = API_MSG_NEWCONN;\r
+  msg->msg.msg.bc.port = proto; /* misusing the port field */\r
+  msg->msg.conn = conn;\r
+  api_msg_post(msg);  \r
+  sys_mbox_fetch(conn->mbox, NULL);\r
+  memp_free(MEMP_API_MSG, msg);\r
+\r
+  if ( conn->err != ERR_OK ) {\r
+    memp_free(MEMP_NETCONN, conn);\r
+    return NULL;\r
+  }\r
+\r
+  return conn;\r
+}\r
+\r
+\r
+struct\r
+netconn *netconn_new(enum netconn_type t)\r
+{\r
+  return netconn_new_with_proto_and_callback(t,0,NULL);\r
+}\r
+\r
+struct\r
+netconn *netconn_new_with_callback(enum netconn_type t,\r
+                                   void (*callback)(struct netconn *, enum netconn_evt, u16_t len))\r
+{\r
+  return netconn_new_with_proto_and_callback(t,0,callback);\r
+}\r
+\r
+\r
+err_t\r
+netconn_delete(struct netconn *conn)\r
+{\r
+  struct api_msg *msg;\r
+  void *mem;\r
+  \r
+  if (conn == NULL) {\r
+    return ERR_OK;\r
+  }\r
+  \r
+  if ((msg = memp_malloc(MEMP_API_MSG)) == NULL) {\r
+    return ERR_MEM;\r
+  }\r
+  \r
+  msg->type = API_MSG_DELCONN;\r
+  msg->msg.conn = conn;\r
+  api_msg_post(msg);  \r
+  sys_mbox_fetch(conn->mbox, NULL);\r
+  memp_free(MEMP_API_MSG, msg);\r
+\r
+  /* Drain the recvmbox. */\r
+  if (conn->recvmbox != SYS_MBOX_NULL) {\r
+    while (sys_arch_mbox_fetch(conn->recvmbox, &mem, 1) != SYS_ARCH_TIMEOUT) {\r
+      if (conn->type == NETCONN_TCP) {\r
+        if(mem != NULL)\r
+          pbuf_free((struct pbuf *)mem);\r
+      } else {\r
+        netbuf_delete((struct netbuf *)mem);\r
+      }\r
+    }\r
+    sys_mbox_free(conn->recvmbox);\r
+    conn->recvmbox = SYS_MBOX_NULL;\r
+  }\r
\r
+\r
+  /* Drain the acceptmbox. */\r
+  if (conn->acceptmbox != SYS_MBOX_NULL) {\r
+    while (sys_arch_mbox_fetch(conn->acceptmbox, &mem, 1) != SYS_ARCH_TIMEOUT) {\r
+      netconn_delete((struct netconn *)mem);\r
+    }\r
+    \r
+    sys_mbox_free(conn->acceptmbox);\r
+    conn->acceptmbox = SYS_MBOX_NULL;\r
+  }\r
+\r
+  sys_mbox_free(conn->mbox);\r
+  conn->mbox = SYS_MBOX_NULL;\r
+  if (conn->sem != SYS_SEM_NULL) {\r
+    sys_sem_free(conn->sem);\r
+  }\r
+  /*  conn->sem = SYS_SEM_NULL;*/\r
+  memp_free(MEMP_NETCONN, conn);\r
+  return ERR_OK;\r
+}\r
+\r
+enum netconn_type\r
+netconn_type(struct netconn *conn)\r
+{\r
+  return conn->type;\r
+}\r
+\r
+err_t\r
+netconn_peer(struct netconn *conn, struct ip_addr *addr,\r
+       u16_t *port)\r
+{\r
+  switch (conn->type) {\r
+  case NETCONN_RAW:\r
+    /* return an error as connecting is only a helper for upper layers */\r
+    return ERR_CONN;\r
+  case NETCONN_UDPLITE:\r
+  case NETCONN_UDPNOCHKSUM:\r
+  case NETCONN_UDP:\r
+    if (conn->pcb.udp == NULL ||\r
+  ((conn->pcb.udp->flags & UDP_FLAGS_CONNECTED) == 0))\r
+     return ERR_CONN;\r
+    *addr = (conn->pcb.udp->remote_ip);\r
+    *port = conn->pcb.udp->remote_port;\r
+    break;\r
+  case NETCONN_TCP:\r
+    if (conn->pcb.tcp == NULL)\r
+      return ERR_CONN;\r
+    *addr = (conn->pcb.tcp->remote_ip);\r
+    *port = conn->pcb.tcp->remote_port;\r
+    break;\r
+  }\r
+  return (conn->err = ERR_OK);\r
+}\r
+\r
+err_t\r
+netconn_addr(struct netconn *conn, struct ip_addr **addr,\r
+       u16_t *port)\r
+{\r
+  switch (conn->type) {\r
+  case NETCONN_RAW:\r
+    *addr = &(conn->pcb.raw->local_ip);\r
+    *port = conn->pcb.raw->protocol;\r
+    break;\r
+  case NETCONN_UDPLITE:\r
+  case NETCONN_UDPNOCHKSUM:\r
+  case NETCONN_UDP:\r
+    *addr = &(conn->pcb.udp->local_ip);\r
+    *port = conn->pcb.udp->local_port;\r
+    break;\r
+  case NETCONN_TCP:\r
+    *addr = &(conn->pcb.tcp->local_ip);\r
+    *port = conn->pcb.tcp->local_port;\r
+    break;\r
+  }\r
+  return (conn->err = ERR_OK);\r
+}\r
+\r
+err_t\r
+netconn_bind(struct netconn *conn, struct ip_addr *addr,\r
+      u16_t port)\r
+{\r
+  struct api_msg *msg;\r
+\r
+  if (conn == NULL) {\r
+    return ERR_VAL;\r
+  }\r
+\r
+  if (conn->type != NETCONN_TCP &&\r
+     conn->recvmbox == SYS_MBOX_NULL) {\r
+    if ((conn->recvmbox = sys_mbox_new()) == SYS_MBOX_NULL) {\r
+      return ERR_MEM;\r
+    }\r
+  }\r
+  \r
+  if ((msg = memp_malloc(MEMP_API_MSG)) == NULL) {\r
+    return (conn->err = ERR_MEM);\r
+  }\r
+  msg->type = API_MSG_BIND;\r
+  msg->msg.conn = conn;\r
+  msg->msg.msg.bc.ipaddr = addr;\r
+  msg->msg.msg.bc.port = port;\r
+  api_msg_post(msg);\r
+  sys_mbox_fetch(conn->mbox, NULL);\r
+  memp_free(MEMP_API_MSG, msg);\r
+  return conn->err;\r
+}\r
+\r
+\r
+err_t\r
+netconn_connect(struct netconn *conn, struct ip_addr *addr,\r
+       u16_t port)\r
+{\r
+  struct api_msg *msg;\r
+  \r
+  if (conn == NULL) {\r
+    return ERR_VAL;\r
+  }\r
+\r
+\r
+  if (conn->recvmbox == SYS_MBOX_NULL) {\r
+    if ((conn->recvmbox = sys_mbox_new()) == SYS_MBOX_NULL) {\r
+      return ERR_MEM;\r
+    }\r
+  }\r
+  \r
+  if ((msg = memp_malloc(MEMP_API_MSG)) == NULL) {\r
+    return ERR_MEM;\r
+  }\r
+  msg->type = API_MSG_CONNECT;\r
+  msg->msg.conn = conn;  \r
+  msg->msg.msg.bc.ipaddr = addr;\r
+  msg->msg.msg.bc.port = port;\r
+  api_msg_post(msg);\r
+  sys_mbox_fetch(conn->mbox, NULL);\r
+  memp_free(MEMP_API_MSG, msg);\r
+  return conn->err;\r
+}\r
+\r
+err_t\r
+netconn_disconnect(struct netconn *conn)\r
+{\r
+  struct api_msg *msg;\r
+  \r
+  if (conn == NULL) {\r
+    return ERR_VAL;\r
+  }\r
+\r
+  if ((msg = memp_malloc(MEMP_API_MSG)) == NULL) {\r
+    return ERR_MEM;\r
+  }\r
+  msg->type = API_MSG_DISCONNECT;\r
+  msg->msg.conn = conn;  \r
+  api_msg_post(msg);\r
+  sys_mbox_fetch(conn->mbox, NULL);\r
+  memp_free(MEMP_API_MSG, msg);\r
+  return conn->err;\r
+\r
+}\r
+\r
+err_t\r
+netconn_listen(struct netconn *conn)\r
+{\r
+  struct api_msg *msg;\r
+\r
+  if (conn == NULL) {\r
+    return ERR_VAL;\r
+  }\r
+\r
+  if (conn->acceptmbox == SYS_MBOX_NULL) {\r
+    conn->acceptmbox = sys_mbox_new();\r
+    if (conn->acceptmbox == SYS_MBOX_NULL) {\r
+      return ERR_MEM;\r
+    }\r
+  }\r
+  \r
+  if ((msg = memp_malloc(MEMP_API_MSG)) == NULL) {\r
+    return (conn->err = ERR_MEM);\r
+  }\r
+  msg->type = API_MSG_LISTEN;\r
+  msg->msg.conn = conn;\r
+  api_msg_post(msg);\r
+  sys_mbox_fetch(conn->mbox, NULL);\r
+  memp_free(MEMP_API_MSG, msg);\r
+  return conn->err;\r
+}\r
+\r
+struct netconn *\r
+netconn_accept(struct netconn *conn)\r
+{\r
+  struct netconn *newconn;\r
+  \r
+  if (conn == NULL) {\r
+    return NULL;\r
+  }\r
+  \r
+  sys_mbox_fetch(conn->acceptmbox, (void **)&newconn);\r
+  /* Register event with callback */\r
+  if (conn->callback)\r
+      (*conn->callback)(conn, NETCONN_EVT_RCVMINUS, 0);\r
+  \r
+  return newconn;\r
+}\r
+\r
+struct netbuf *\r
+netconn_recv(struct netconn *conn)\r
+{\r
+  struct api_msg *msg;\r
+  struct netbuf *buf;\r
+  struct pbuf *p;\r
+  u16_t len;\r
+    \r
+  if (conn == NULL) {\r
+    return NULL;\r
+  }\r
+  \r
+  if (conn->recvmbox == SYS_MBOX_NULL) {\r
+    conn->err = ERR_CONN;\r
+    return NULL;\r
+  }\r
+\r
+  if (conn->err != ERR_OK) {\r
+    return NULL;\r
+  }\r
+\r
+  if (conn->type == NETCONN_TCP) {\r
+    if (conn->pcb.tcp->state == LISTEN) {\r
+      conn->err = ERR_CONN;\r
+      return NULL;\r
+    }\r
+\r
+\r
+    buf = memp_malloc(MEMP_NETBUF);\r
+\r
+    if (buf == NULL) {\r
+      conn->err = ERR_MEM;\r
+      return NULL;\r
+    }\r
+    \r
+    sys_mbox_fetch(conn->recvmbox, (void **)&p);\r
+\r
+    if (p != NULL)\r
+    {\r
+        len = p->tot_len;\r
+        conn->recv_avail -= len;\r
+    }\r
+    else\r
+        len = 0;\r
+    \r
+    /* Register event with callback */\r
+      if (conn->callback)\r
+        (*conn->callback)(conn, NETCONN_EVT_RCVMINUS, len);\r
+\r
+    /* If we are closed, we indicate that we no longer wish to receive\r
+       data by setting conn->recvmbox to SYS_MBOX_NULL. */\r
+    if (p == NULL) {\r
+      memp_free(MEMP_NETBUF, buf);\r
+      sys_mbox_free(conn->recvmbox);\r
+      conn->recvmbox = SYS_MBOX_NULL;\r
+      return NULL;\r
+    }\r
+\r
+    buf->p = p;\r
+    buf->ptr = p;\r
+    buf->fromport = 0;\r
+    buf->fromaddr = NULL;\r
+\r
+    /* Let the stack know that we have taken the data. */\r
+    if ((msg = memp_malloc(MEMP_API_MSG)) == NULL) {\r
+      conn->err = ERR_MEM;\r
+      return buf;\r
+    }\r
+    msg->type = API_MSG_RECV;\r
+    msg->msg.conn = conn;\r
+    if (buf != NULL) {\r
+      msg->msg.msg.len = buf->p->tot_len;\r
+    } else {\r
+      msg->msg.msg.len = 1;\r
+    }\r
+    api_msg_post(msg);\r
+\r
+    sys_mbox_fetch(conn->mbox, NULL);\r
+    memp_free(MEMP_API_MSG, msg);\r
+  } else {\r
+    sys_mbox_fetch(conn->recvmbox, (void **)&buf);\r
+  conn->recv_avail -= buf->p->tot_len;\r
+    /* Register event with callback */\r
+    if (conn->callback)\r
+        (*conn->callback)(conn, NETCONN_EVT_RCVMINUS, buf->p->tot_len);\r
+  }\r
+\r
+  \r
+\r
+    \r
+  LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_recv: received %p (err %d)\n", (void *)buf, conn->err));\r
+\r
+\r
+  return buf;\r
+}\r
+\r
+err_t\r
+netconn_send(struct netconn *conn, struct netbuf *buf)\r
+{\r
+  struct api_msg *msg;\r
+\r
+  if (conn == NULL) {\r
+    return ERR_VAL;\r
+  }\r
+\r
+  if (conn->err != ERR_OK) {\r
+    return conn->err;\r
+  }\r
+\r
+  if ((msg = memp_malloc(MEMP_API_MSG)) == NULL) {\r
+    return (conn->err = ERR_MEM);\r
+  }\r
+\r
+  LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_send: sending %d bytes\n", buf->p->tot_len));\r
+  msg->type = API_MSG_SEND;\r
+  msg->msg.conn = conn;\r
+  msg->msg.msg.p = buf->p;\r
+  api_msg_post(msg);\r
+\r
+  sys_mbox_fetch(conn->mbox, NULL);\r
+  memp_free(MEMP_API_MSG, msg);\r
+  return conn->err;\r
+}\r
+\r
+err_t\r
+netconn_write(struct netconn *conn, void *dataptr, u16_t size, u8_t copy)\r
+{\r
+  struct api_msg *msg;\r
+  u16_t len;\r
+  \r
+  if (conn == NULL) {\r
+    return ERR_VAL;\r
+  }\r
+\r
+  if (conn->err != ERR_OK) {\r
+    return conn->err;\r
+  }\r
+  \r
+  if (conn->sem == SYS_SEM_NULL) {\r
+    conn->sem = sys_sem_new(0);\r
+    if (conn->sem == SYS_SEM_NULL) {\r
+      return ERR_MEM;\r
+    }\r
+  }\r
+\r
+  if ((msg = memp_malloc(MEMP_API_MSG)) == NULL) {\r
+    return (conn->err = ERR_MEM);\r
+  }\r
+  msg->type = API_MSG_WRITE;\r
+  msg->msg.conn = conn;\r
+        \r
+\r
+  conn->state = NETCONN_WRITE;\r
+  while (conn->err == ERR_OK && size > 0) {\r
+    msg->msg.msg.w.dataptr = dataptr;\r
+    msg->msg.msg.w.copy = copy;\r
+    \r
+    if (conn->type == NETCONN_TCP) {\r
+      if (tcp_sndbuf(conn->pcb.tcp) == 0) {\r
+  sys_sem_wait(conn->sem);\r
+  if (conn->err != ERR_OK) {\r
+    goto ret;\r
+  }\r
+      }\r
+      if (size > tcp_sndbuf(conn->pcb.tcp)) {\r
+  /* We cannot send more than one send buffer's worth of data at a\r
+     time. */\r
+  len = tcp_sndbuf(conn->pcb.tcp);\r
+      } else {\r
+  len = size;\r
+      }\r
+    } else {\r
+      len = size;\r
+    }\r
+    \r
+    LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_write: writing %d bytes (%d)\n", len, copy));\r
+    msg->msg.msg.w.len = len;\r
+    api_msg_post(msg);\r
+    sys_mbox_fetch(conn->mbox, NULL);    \r
+    if (conn->err == ERR_OK) {\r
+      dataptr = (void *)((char *)dataptr + len);\r
+      size -= len;\r
+    } else if (conn->err == ERR_MEM) {\r
+      conn->err = ERR_OK;\r
+      sys_sem_wait(conn->sem);\r
+    } else {\r
+      goto ret;\r
+    }\r
+  }\r
+ ret:\r
+  memp_free(MEMP_API_MSG, msg);\r
+  conn->state = NETCONN_NONE;\r
+  if (conn->sem != SYS_SEM_NULL) {\r
+    sys_sem_free(conn->sem);\r
+    conn->sem = SYS_SEM_NULL;\r
+  }\r
+  \r
+  return conn->err;\r
+}\r
+\r
+err_t\r
+netconn_close(struct netconn *conn)\r
+{\r
+  struct api_msg *msg;\r
+\r
+  if (conn == NULL) {\r
+    return ERR_VAL;\r
+  }\r
+  if ((msg = memp_malloc(MEMP_API_MSG)) == NULL) {\r
+    return (conn->err = ERR_MEM);\r
+  }\r
+\r
+  conn->state = NETCONN_CLOSE;\r
+ again:\r
+  msg->type = API_MSG_CLOSE;\r
+  msg->msg.conn = conn;\r
+  api_msg_post(msg);\r
+  sys_mbox_fetch(conn->mbox, NULL);\r
+  if (conn->err == ERR_MEM &&\r
+     conn->sem != SYS_SEM_NULL) {\r
+    sys_sem_wait(conn->sem);\r
+    goto again;\r
+  }\r
+  conn->state = NETCONN_NONE;\r
+  memp_free(MEMP_API_MSG, msg);\r
+  return conn->err;\r
+}\r
+\r
+err_t\r
+netconn_err(struct netconn *conn)\r
+{\r
+  return conn->err;\r
+}\r
+\r
index b582d88a2b4f6943bbdaa9fa7fca6bb91a60bb27..cc6367814734a1ebbfab543822da22dcb4006e9e 100644 (file)
@@ -1,59 +1,59 @@
-/*
- * 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 <adam@sics.se>
- *
- */
-
-#include "lwip/err.h"
-
-#ifdef LWIP_DEBUG
-
-static char *err_strerr[] = {"Ok.",
-           "Out of memory error.",
-           "Buffer error.",
-           "Connection aborted.",
-           "Connection reset.",
-           "Connection closed.",
-           "Not connected.",
-           "Illegal value.",
-           "Illegal argument.",
-           "Routing problem.",
-           "Address in use."
-};
-
-
-char *
-lwip_strerr(err_t err)
-{
-  return err_strerr[-err];
-
-}
-
-
-#endif /* LWIP_DEBUG */
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+\r
+#include "lwip/err.h"\r
+\r
+#ifdef LWIP_DEBUG\r
+\r
+static char *err_strerr[] = {"Ok.",\r
+           "Out of memory error.",\r
+           "Buffer error.",\r
+           "Connection aborted.",\r
+           "Connection reset.",\r
+           "Connection closed.",\r
+           "Not connected.",\r
+           "Illegal value.",\r
+           "Illegal argument.",\r
+           "Routing problem.",\r
+           "Address in use."\r
+};\r
+\r
+\r
+char *\r
+lwip_strerr(err_t err)\r
+{\r
+  return err_strerr[-err];\r
+\r
+}\r
+\r
+\r
+#endif /* LWIP_DEBUG */\r
index 0528ac44f09e59b93833ad9a52a8d43215c3389d..af96db436d0a920200fda892036b937d42ad830a 100644 (file)
-/*
- * 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 <adam@sics.se>
- *
- * Improved by Marc Boucher <marc@mbsi.ca> and David Haas <dhaas@alum.rpi.edu>
- *
- */
-
-#include <string.h>
-#include <errno.h>
-
-#include "lwip/opt.h"
-#include "lwip/api.h"
-#include "lwip/arch.h"
-#include "lwip/sys.h"
-
-#include "lwip/sockets.h"
-
-#define NUM_SOCKETS MEMP_NUM_NETCONN
-
-struct lwip_socket {
-  struct netconn *conn;
-  struct netbuf *lastdata;
-  u16_t lastoffset;
-  u16_t rcvevent;
-  u16_t sendevent;
-  u16_t  flags;
-  int err;
-};
-
-struct lwip_select_cb
-{
-    struct lwip_select_cb *next;
-    fd_set *readset;
-    fd_set *writeset;
-    fd_set *exceptset;
-    int sem_signalled;
-    sys_sem_t sem;
-};
-
-static struct lwip_socket sockets[NUM_SOCKETS];
-static struct lwip_select_cb *select_cb_list = 0;
-
-static sys_sem_t socksem = 0;
-static sys_sem_t selectsem = 0;
-
-static void
-event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len);
-
-static int err_to_errno_table[11] = {
-    0,      /* ERR_OK    0      No error, everything OK. */
-    ENOMEM,    /* ERR_MEM  -1      Out of memory error.     */
-    ENOBUFS,    /* ERR_BUF  -2      Buffer error.            */
-    ECONNABORTED,  /* ERR_ABRT -3      Connection aborted.      */
-    ECONNRESET,    /* ERR_RST  -4      Connection reset.        */
-    ESHUTDOWN,    /* ERR_CLSD -5      Connection closed.       */
-    ENOTCONN,    /* ERR_CONN -6      Not connected.           */
-    EINVAL,    /* ERR_VAL  -7      Illegal value.           */
-    EIO,    /* ERR_ARG  -8      Illegal argument.        */
-    EHOSTUNREACH,  /* ERR_RTE  -9      Routing problem.         */
-    EADDRINUSE    /* ERR_USE  -10     Address in use.          */
-};
-
-#define err_to_errno(err) \
-  ((err) < (sizeof(err_to_errno_table)/sizeof(int))) ? \
-    err_to_errno_table[-(err)] : EIO
-
-#ifdef ERRNO
-#define set_errno(err) errno = (err)
-#else
-#define set_errno(err)
-#endif
-
-#define sock_set_errno(sk, e) do { \
-      sk->err = (e); \
-      set_errno(sk->err); \
-} while (0)
-
-
-static struct lwip_socket *
-get_socket(int s)
-{
-  struct lwip_socket *sock;
-
-  if ((s < 0) || (s > NUM_SOCKETS)) {
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("get_socket(%d): invalid\n", s));
-    set_errno(EBADF);
-    return NULL;
-  }
-
-  sock = &sockets[s];
-
-  if (!sock->conn) {
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("get_socket(%d): not active\n", s));
-    set_errno(EBADF);
-    return NULL;
-  }
-
-  return sock;
-}
-
-static int
-alloc_socket(struct netconn *newconn)
-{
-  int i;
-
-  if (!socksem)
-      socksem = sys_sem_new(1);
-
-  /* Protect socket array */
-  sys_sem_wait(socksem);
-
-  /* allocate a new socket identifier */
-  for(i = 0; i < NUM_SOCKETS; ++i) {
-    if (!sockets[i].conn) {
-      sockets[i].conn = newconn;
-      sockets[i].lastdata = NULL;
-      sockets[i].lastoffset = 0;
-      sockets[i].rcvevent = 0;
-      sockets[i].sendevent = 1; /* TCP send buf is empty */
-      sockets[i].flags = 0;
-      sockets[i].err = 0;
-      sys_sem_signal(socksem);
-      return i;
-    }
-  }
-  sys_sem_signal(socksem);
-  return -1;
-}
-
-int
-lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
-{
-  struct lwip_socket *sock;
-  struct netconn *newconn;
-  struct ip_addr naddr;
-  u16_t port;
-  int newsock;
-  struct sockaddr_in sin;
-
-  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d)...\n", s));
-  sock = get_socket(s);
-  if (!sock) {
-    set_errno(EBADF);
-    return -1;
-  }
-
-  newconn = netconn_accept(sock->conn);
-
-  /* get the IP address and port of the remote host */
-  netconn_peer(newconn, &naddr, &port);
-
-  memset(&sin, 0, sizeof(sin));
-  sin.sin_len = sizeof(sin);
-  sin.sin_family = AF_INET;
-  sin.sin_port = htons(port);
-  sin.sin_addr.s_addr = naddr.addr;
-
-  if (*addrlen > sizeof(sin))
-      *addrlen = sizeof(sin);
-
-  memcpy(addr, &sin, *addrlen);
-
-  newsock = alloc_socket(newconn);
-  if (newsock == -1) {
-    netconn_delete(newconn);
-  sock_set_errno(sock, ENOBUFS);
-  return -1;
-  }
-  newconn->callback = event_callback;
-  sock = get_socket(newsock);
-
-  sys_sem_wait(socksem);
-  sock->rcvevent += -1 - newconn->socket;
-  newconn->socket = newsock;
-  sys_sem_signal(socksem);
-
-  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d) returning new sock=%d addr=", s, newsock));
-  ip_addr_debug_print(SOCKETS_DEBUG, &naddr);
-  LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u\n", port));
-
-  sock_set_errno(sock, 0);
-  return newsock;
-}
-
-int
-lwip_bind(int s, struct sockaddr *name, socklen_t namelen)
-{
-  struct lwip_socket *sock;
-  struct ip_addr local_addr;
-  u16_t local_port;
-  err_t err;
-
-  sock = get_socket(s);
-  if (!sock) {
-    set_errno(EBADF);
-    return -1;
-  }
-
-  local_addr.addr = ((struct sockaddr_in *)name)->sin_addr.s_addr;
-  local_port = ((struct sockaddr_in *)name)->sin_port;
-
-  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d, addr=", s));
-  ip_addr_debug_print(SOCKETS_DEBUG, &local_addr);
-  LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u)\n", ntohs(local_port)));
-
-  err = netconn_bind(sock->conn, &local_addr, ntohs(local_port));
-
-  if (err != ERR_OK) {
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d) failed, err=%d\n", s, err));
-    sock_set_errno(sock, err_to_errno(err));
-    return -1;
-  }
-
-  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d) succeeded\n", s));
-  sock_set_errno(sock, 0);
-  return 0;
-}
-
-int
-lwip_close(int s)
-{
-  struct lwip_socket *sock;
-
-  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_close(%d)\n", s));
-  if (!socksem)
-      socksem = sys_sem_new(1);
-
-  /* We cannot allow multiple closes of the same socket. */
-  sys_sem_wait(socksem);
-
-  sock = get_socket(s);
-  if (!sock) {
-      sys_sem_signal(socksem);
-      set_errno(EBADF);
-      return -1;
-  }
-
-  netconn_delete(sock->conn);
-  if (sock->lastdata) {
-    netbuf_delete(sock->lastdata);
-  }
-  sock->lastdata = NULL;
-  sock->lastoffset = 0;
-  sock->conn = NULL;
-  sys_sem_signal(socksem);
-  sock_set_errno(sock, 0);
-  return 0;
-}
-
-int
-lwip_connect(int s, struct sockaddr *name, socklen_t namelen)
-{
-  struct lwip_socket *sock;
-  err_t err;
-
-  sock = get_socket(s);
-  if (!sock) {
-    set_errno(EBADF);
-    return -1;
-  }
-
-  if (((struct sockaddr_in *)name)->sin_family == AF_UNSPEC) {
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, AF_UNSPEC)\n", s));
-    err = netconn_disconnect(sock->conn);
-  } else {
-    struct ip_addr remote_addr;
-    u16_t remote_port;
-
-    remote_addr.addr = ((struct sockaddr_in *)name)->sin_addr.s_addr;
-    remote_port = ((struct sockaddr_in *)name)->sin_port;
-
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, addr=", s));
-    ip_addr_debug_print(SOCKETS_DEBUG, &remote_addr);
-    LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u)\n", ntohs(remote_port)));
-
-    err = netconn_connect(sock->conn, &remote_addr, ntohs(remote_port));
-   }
-
-  if (err != ERR_OK) {
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d) failed, err=%d\n", s, err));
-    sock_set_errno(sock, err_to_errno(err));
-    return -1;
-  }
-
-  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d) succeeded\n", s));
-  sock_set_errno(sock, 0);
-  return 0;
-}
-
-int
-lwip_listen(int s, int backlog)
-{
-  struct lwip_socket *sock;
-  err_t err;
-
-  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_listen(%d, backlog=%d)\n", s, backlog));
-  sock = get_socket(s);
-  if (!sock) {
-    set_errno(EBADF);
-    return -1;
-  }
-
-  err = netconn_listen(sock->conn);
-
-  if (err != ERR_OK) {
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_listen(%d) failed, err=%d\n", s, err));
-    sock_set_errno(sock, err_to_errno(err));
-    return -1;
-  }
-
-  sock_set_errno(sock, 0);
-  return 0;
-}
-
-int
-lwip_recvfrom(int s, void *mem, int len, unsigned int flags,
-        struct sockaddr *from, socklen_t *fromlen)
-{
-  struct lwip_socket *sock;
-  struct netbuf *buf;
-  u16_t buflen, copylen;
-  struct ip_addr *addr;
-  u16_t port;
-
-
-  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d, %p, %d, 0x%x, ..)\n", s, mem, len, flags));
-  sock = get_socket(s);
-  if (!sock) {
-    set_errno(EBADF);
-    return -1;
-  }
-
-  /* Check if there is data left from the last recv operation. */
-  if (sock->lastdata) {
-    buf = sock->lastdata;
-  } else {
-    /* If this is non-blocking call, then check first */
-    if (((flags & MSG_DONTWAIT) || (sock->flags & O_NONBLOCK))
-  && !sock->rcvevent)
-    {
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): returning EWOULDBLOCK\n", s));
-      sock_set_errno(sock, EWOULDBLOCK);
-      return -1;
-    }
-
-    /* No data was left from the previous operation, so we try to get
-       some from the network. */
-    buf = netconn_recv(sock->conn);
-
-    if (!buf) {
-      /* We should really do some error checking here. */
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): buf == NULL!\n", s));
-      sock_set_errno(sock, 0);
-      return 0;
-    }
-  }
-
-  buflen = netbuf_len(buf);
-
-  buflen -= sock->lastoffset;
-
-  if (len > buflen) {
-    copylen = buflen;
-  } else {
-    copylen = len;
-  }
-
-  /* copy the contents of the received buffer into
-     the supplied memory pointer mem */
-  netbuf_copy_partial(buf, mem, copylen, sock->lastoffset);
-
-  /* Check to see from where the data was. */
-  if (from && fromlen) {
-    struct sockaddr_in sin;
-
-    addr = netbuf_fromaddr(buf);
-    port = netbuf_fromport(buf);
-
-    memset(&sin, 0, sizeof(sin));
-    sin.sin_len = sizeof(sin);
-    sin.sin_family = AF_INET;
-    sin.sin_port = htons(port);
-    sin.sin_addr.s_addr = addr->addr;
-
-    if (*fromlen > sizeof(sin))
-      *fromlen = sizeof(sin);
-
-    memcpy(from, &sin, *fromlen);
-
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): addr=", s));
-    ip_addr_debug_print(SOCKETS_DEBUG, addr);
-    LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u len=%u\n", port, copylen));
-  } else {
-#if SOCKETS_DEBUG
-    addr = netbuf_fromaddr(buf);
-    port = netbuf_fromport(buf);
-
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): addr=", s));
-    ip_addr_debug_print(SOCKETS_DEBUG, addr);
-    LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u len=%u\n", port, copylen));
-#endif
-
-  }
-
-  /* If this is a TCP socket, check if there is data left in the
-     buffer. If so, it should be saved in the sock structure for next
-     time around. */
-  if (netconn_type(sock->conn) == NETCONN_TCP && buflen - copylen > 0) {
-    sock->lastdata = buf;
-    sock->lastoffset += copylen;
-  } else {
-    sock->lastdata = NULL;
-    sock->lastoffset = 0;
-    netbuf_delete(buf);
-  }
-
-
-  sock_set_errno(sock, 0);
-  return copylen;
-}
-
-int
-lwip_read(int s, void *mem, int len)
-{
-  return lwip_recvfrom(s, mem, len, 0, NULL, NULL);
-}
-
-int
-lwip_recv(int s, void *mem, int len, unsigned int flags)
-{
-  return lwip_recvfrom(s, mem, len, flags, NULL, NULL);
-}
-
-int
-lwip_send(int s, void *data, int size, unsigned int flags)
-{
-  struct lwip_socket *sock;
-  struct netbuf *buf;
-  err_t err;
-
-  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d, data=%p, size=%d, flags=0x%x)\n", s, data, size, flags));
-
-  sock = get_socket(s);
-  if (!sock) {
-    set_errno(EBADF);
-    return -1;
-  }
-
-  switch (netconn_type(sock->conn)) {
-  case NETCONN_RAW:
-  case NETCONN_UDP:
-  case NETCONN_UDPLITE:
-  case NETCONN_UDPNOCHKSUM:
-    /* create a buffer */
-    buf = netbuf_new();
-
-    if (!buf) {
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) ENOBUFS\n", s));
-      sock_set_errno(sock, ENOBUFS);
-      return -1;
-    }
-
-    /* make the buffer point to the data that should
-       be sent */
-    netbuf_ref(buf, data, size);
-
-    /* send the data */
-    err = netconn_send(sock->conn, buf);
-
-    /* deallocated the buffer */
-    netbuf_delete(buf);
-    break;
-  case NETCONN_TCP:
-    err = netconn_write(sock->conn, data, size, NETCONN_COPY);
-    break;
-  default:
-    err = ERR_ARG;
-    break;
-  }
-  if (err != ERR_OK) {
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) err=%d\n", s, err));
-    sock_set_errno(sock, err_to_errno(err));
-    return -1;
-  }
-
-  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) ok size=%d\n", s, size));
-  sock_set_errno(sock, 0);
-  return size;
-}
-
-int
-lwip_sendto(int s, void *data, int size, unsigned int flags,
-       struct sockaddr *to, socklen_t tolen)
-{
-  struct lwip_socket *sock;
-  struct ip_addr remote_addr, addr;
-  u16_t remote_port, port;
-  int ret,connected;
-
-  sock = get_socket(s);
-  if (!sock) {
-    set_errno(EBADF);
-    return -1;
-  }
-
-  /* get the peer if currently connected */
-  connected = (netconn_peer(sock->conn, &addr, &port) == ERR_OK);
-
-  remote_addr.addr = ((struct sockaddr_in *)to)->sin_addr.s_addr;
-  remote_port = ((struct sockaddr_in *)to)->sin_port;
-
-  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_sendto(%d, data=%p, size=%d, flags=0x%x to=", s, data, size, flags));
-  ip_addr_debug_print(SOCKETS_DEBUG, &remote_addr);
-  LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u\n", ntohs(remote_port)));
-
-  netconn_connect(sock->conn, &remote_addr, ntohs(remote_port));
-
-  ret = lwip_send(s, data, size, flags);
-
-  /* reset the remote address and port number
-     of the connection */
-  if (connected)
-    netconn_connect(sock->conn, &addr, port);
-  else
-  netconn_disconnect(sock->conn);
-  return ret;
-}
-
-int
-lwip_socket(int domain, int type, int protocol)
-{
-  struct netconn *conn;
-  int i;
-
-  /* create a netconn */
-  switch (type) {
-  case SOCK_RAW:
-    conn = netconn_new_with_proto_and_callback(NETCONN_RAW, protocol, event_callback);
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_RAW, %d) = ", domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol));
-    break;
-  case SOCK_DGRAM:
-    conn = netconn_new_with_callback(NETCONN_UDP, event_callback);
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_DGRAM, %d) = ", domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol));
-    break;
-  case SOCK_STREAM:
-    conn = netconn_new_with_callback(NETCONN_TCP, event_callback);
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_STREAM, %d) = ", domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol));
-    break;
-  default:
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%d, %d/UNKNOWN, %d) = -1\n", domain, type, protocol));
-    set_errno(EINVAL);
-    return -1;
-  }
-
-  if (!conn) {
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("-1 / ENOBUFS (could not create netconn)\n"));
-    set_errno(ENOBUFS);
-    return -1;
-  }
-
-  i = alloc_socket(conn);
-
-  if (i == -1) {
-    netconn_delete(conn);
-  set_errno(ENOBUFS);
-  return -1;
-  }
-  conn->socket = i;
-  LWIP_DEBUGF(SOCKETS_DEBUG, ("%d\n", i));
-  set_errno(0);
-  return i;
-}
-
-int
-lwip_write(int s, void *data, int size)
-{
-   return lwip_send(s, data, size, 0);
-}
-
-
-static int
-lwip_selscan(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset)
-{
-    int i, nready = 0;
-    fd_set lreadset, lwriteset, lexceptset;
-    struct lwip_socket *p_sock;
-
-    FD_ZERO(&lreadset);
-    FD_ZERO(&lwriteset);
-    FD_ZERO(&lexceptset);
-
-    /* Go through each socket in each list to count number of sockets which
-       currently match */
-    for(i = 0; i < maxfdp1; i++)
-    {
-        if (FD_ISSET(i, readset))
-        {
-            /* See if netconn of this socket is ready for read */
-            p_sock = get_socket(i);
-            if (p_sock && (p_sock->lastdata || p_sock->rcvevent))
-            {
-                FD_SET(i, &lreadset);
-               LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for reading\n", i));
-                nready++;
-            }
-        }
-        if (FD_ISSET(i, writeset))
-        {
-            /* See if netconn of this socket is ready for write */
-            p_sock = get_socket(i);
-            if (p_sock && p_sock->sendevent)
-            {
-                FD_SET(i, &lwriteset);
-               LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for writing\n", i));
-                nready++;
-            }
-        }
-    }
-    *readset = lreadset;
-    *writeset = lwriteset;
-    FD_ZERO(exceptset);
-
-    return nready;
-}
-
-
-
-int
-lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
-               struct timeval *timeout)
-{
-    int i;
-    int nready;
-    fd_set lreadset, lwriteset, lexceptset;
-    u32_t msectimeout;
-    struct lwip_select_cb select_cb;
-    struct lwip_select_cb *p_selcb;
-
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select(%d, %p, %p, %p, tvsec=%ld tvusec=%ld)\n", maxfdp1, (void *)readset, (void *) writeset, (void *) exceptset, timeout ? timeout->tv_sec : -1L, timeout ? timeout->tv_usec : -1L));
-
-    select_cb.next = 0;
-    select_cb.readset = readset;
-    select_cb.writeset = writeset;
-    select_cb.exceptset = exceptset;
-    select_cb.sem_signalled = 0;
-
-    /* Protect ourselves searching through the list */
-    if (!selectsem)
-        selectsem = sys_sem_new(1);
-    sys_sem_wait(selectsem);
-
-    if (readset)
-        lreadset = *readset;
-    else
-        FD_ZERO(&lreadset);
-    if (writeset)
-        lwriteset = *writeset;
-    else
-        FD_ZERO(&lwriteset);
-    if (exceptset)
-        lexceptset = *exceptset;
-    else
-        FD_ZERO(&lexceptset);
-
-    /* Go through each socket in each list to count number of sockets which
-       currently match */
-    nready = lwip_selscan(maxfdp1, &lreadset, &lwriteset, &lexceptset);
-
-    /* If we don't have any current events, then suspend if we are supposed to */
-    if (!nready)
-    {
-        if (timeout && timeout->tv_sec == 0 && timeout->tv_usec == 0)
-        {
-            sys_sem_signal(selectsem);
-            if (readset)
-                FD_ZERO(readset);
-            if (writeset)
-                FD_ZERO(writeset);
-            if (exceptset)
-                FD_ZERO(exceptset);
-
-           LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: no timeout, returning 0\n"));
-           set_errno(0);
-
-            return 0;
-        }
-
-        /* add our semaphore to list */
-        /* We don't actually need any dynamic memory. Our entry on the
-         * list is only valid while we are in this function, so it's ok
-         * to use local variables */
-
-        select_cb.sem = sys_sem_new(0);
-        /* Note that we are still protected */
-        /* Put this select_cb on top of list */
-        select_cb.next = select_cb_list;
-        select_cb_list = &select_cb;
-
-        /* Now we can safely unprotect */
-        sys_sem_signal(selectsem);
-
-        /* Now just wait to be woken */
-        if (timeout == 0)
-            /* Wait forever */
-            msectimeout = 0;
-        else
-            msectimeout =  ((timeout->tv_sec * 1000) + ((timeout->tv_usec + 500)/1000));
-
-        i = sys_sem_wait_timeout(select_cb.sem, msectimeout);
-
-        /* Take us off the list */
-        sys_sem_wait(selectsem);
-        if (select_cb_list == &select_cb)
-            select_cb_list = select_cb.next;
-        else
-            for (p_selcb = select_cb_list; p_selcb; p_selcb = p_selcb->next)
-                if (p_selcb->next == &select_cb)
-                {
-                    p_selcb->next = select_cb.next;
-                    break;
-                }
-
-        sys_sem_signal(selectsem);
-
-        sys_sem_free(select_cb.sem);
-        if (i == 0)             /* Timeout */
-        {
-            if (readset)
-                FD_ZERO(readset);
-            if (writeset)
-                FD_ZERO(writeset);
-            if (exceptset)
-                FD_ZERO(exceptset);
-
-           LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: timeout expired\n"));
-           set_errno(0);
-
-            return 0;
-        }
-
-        if (readset)
-            lreadset = *readset;
-        else
-            FD_ZERO(&lreadset);
-        if (writeset)
-            lwriteset = *writeset;
-        else
-            FD_ZERO(&lwriteset);
-        if (exceptset)
-            lexceptset = *exceptset;
-        else
-            FD_ZERO(&lexceptset);
-
-        /* See what's set */
-        nready = lwip_selscan(maxfdp1, &lreadset, &lwriteset, &lexceptset);
-    }
-    else
-        sys_sem_signal(selectsem);
-
-    if (readset)
-        *readset = lreadset;
-    if (writeset)
-        *writeset = lwriteset;
-    if (exceptset)
-        *exceptset = lexceptset;
-
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: nready=%d\n", nready));
-    set_errno(0);
-
-    return nready;
-}
-
-
-static void
-event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len)
-{
-    int s;
-    struct lwip_socket *sock;
-    struct lwip_select_cb *scb;
-
-    /* Get socket */
-    if (conn)
-    {
-        s = conn->socket;
-        if (s < 0)
-        {
-            /* Data comes in right away after an accept, even though
-             * the server task might not have created a new socket yet.
-             * Just count down (or up) if that's the case and we
-             * will use the data later. Note that only receive events
-             * can happen before the new socket is set up. */
-            if (evt == NETCONN_EVT_RCVPLUS)
-                conn->socket--;
-            return;
-        }
-
-        sock = get_socket(s);
-        if (!sock)
-            return;
-    }
-    else
-        return;
-
-    if (!selectsem)
-        selectsem = sys_sem_new(1);
-
-    sys_sem_wait(selectsem);
-    /* Set event as required */
-    switch (evt)
-    {
-      case NETCONN_EVT_RCVPLUS:
-        sock->rcvevent++;
-        break;
-      case NETCONN_EVT_RCVMINUS:
-        sock->rcvevent--;
-        break;
-      case NETCONN_EVT_SENDPLUS:
-        sock->sendevent = 1;
-        break;
-      case NETCONN_EVT_SENDMINUS:
-        sock->sendevent = 0;
-        break;
-    }
-    sys_sem_signal(selectsem);
-
-    /* Now decide if anyone is waiting for this socket */
-    /* NOTE: This code is written this way to protect the select link list
-       but to avoid a deadlock situation by releasing socksem before
-       signalling for the select. This means we need to go through the list
-       multiple times ONLY IF a select was actually waiting. We go through
-       the list the number of waiting select calls + 1. This list is
-       expected to be small. */
-    while (1)
-    {
-        sys_sem_wait(selectsem);
-        for (scb = select_cb_list; scb; scb = scb->next)
-        {
-            if (scb->sem_signalled == 0)
-            {
-                /* Test this select call for our socket */
-                if (scb->readset && FD_ISSET(s, scb->readset))
-                    if (sock->rcvevent)
-                        break;
-                if (scb->writeset && FD_ISSET(s, scb->writeset))
-                    if (sock->sendevent)
-                        break;
-            }
-        }
-        if (scb)
-        {
-            scb->sem_signalled = 1;
-            sys_sem_signal(selectsem);
-            sys_sem_signal(scb->sem);
-        } else {
-            sys_sem_signal(selectsem);
-            break;
-        }
-    }
-
-}
-
-
-
-
-int lwip_shutdown(int s, int how)
-{
-  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_shutdown(%d, how=%d)\n", s, how));
-  return lwip_close(s); /* XXX temporary hack until proper implementation */
-}
-
-int lwip_getpeername (int s, struct sockaddr *name, socklen_t *namelen)
-{
-  struct lwip_socket *sock;
-  struct sockaddr_in sin;
-  struct ip_addr naddr;
-
-  sock = get_socket(s);
-  if (!sock) {
-    set_errno(EBADF);
-    return -1;
-  }
-
-  memset(&sin, 0, sizeof(sin));
-  sin.sin_len = sizeof(sin);
-  sin.sin_family = AF_INET;
-
-  /* get the IP address and port of the remote host */
-  netconn_peer(sock->conn, &naddr, &sin.sin_port);
-
-  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getpeername(%d, addr=", s));
-  ip_addr_debug_print(SOCKETS_DEBUG, &naddr);
-  LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%d)\n", sin.sin_port));
-
-  sin.sin_port = htons(sin.sin_port);
-  sin.sin_addr.s_addr = naddr.addr;
-
-  if (*namelen > sizeof(sin))
-      *namelen = sizeof(sin);
-
-  memcpy(name, &sin, *namelen);
-  sock_set_errno(sock, 0);
-  return 0;
-}
-
-int lwip_getsockname (int s, struct sockaddr *name, socklen_t *namelen)
-{
-  struct lwip_socket *sock;
-  struct sockaddr_in sin;
-  struct ip_addr *naddr;
-
-  sock = get_socket(s);
-  if (!sock) {
-    set_errno(EBADF);
-    return -1;
-  }
-
-  memset(&sin, 0, sizeof(sin));
-  sin.sin_len = sizeof(sin);
-  sin.sin_family = AF_INET;
-
-  /* get the IP address and port of the remote host */
-  netconn_addr(sock->conn, &naddr, &sin.sin_port);
-
-  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockname(%d, addr=", s));
-  ip_addr_debug_print(SOCKETS_DEBUG, naddr);
-  LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%d)\n", sin.sin_port));
-
-  sin.sin_port = htons(sin.sin_port);
-  sin.sin_addr.s_addr = naddr->addr;
-
-  if (*namelen > sizeof(sin))
-      *namelen = sizeof(sin);
-
-  memcpy(name, &sin, *namelen);
-  sock_set_errno(sock, 0);
-  return 0;
-}
-
-int lwip_getsockopt (int s, int level, int optname, void *optval, socklen_t *optlen)
-{
-  int err = 0;
-  struct lwip_socket *sock = get_socket(s);
-
-  if(!sock) {
-       set_errno(EBADF);
-    return -1;
-  }
-
-  if( NULL == optval || NULL == optlen ) {
-    sock_set_errno( sock, EFAULT );
-    return -1;
-  }
-
-  /* Do length and type checks for the various options first, to keep it readable. */
-  switch( level ) {
-   
-/* Level: SOL_SOCKET */
-  case SOL_SOCKET:
-      switch(optname) {
-         
-      case SO_ACCEPTCONN:
-      case SO_BROADCAST:
-      /* UNIMPL case SO_DEBUG: */
-      /* UNIMPL case SO_DONTROUTE: */
-      case SO_ERROR:
-      case SO_KEEPALIVE:
-      /* UNIMPL case SO_OOBINLINE: */
-      /* UNIMPL case SO_RCVBUF: */
-      /* UNIMPL case SO_SNDBUF: */
-      /* UNIMPL case SO_RCVLOWAT: */
-      /* UNIMPL case SO_SNDLOWAT: */
-#if SO_REUSE
-      case SO_REUSEADDR:
-      case SO_REUSEPORT:
-#endif /* SO_REUSE */
-      case SO_TYPE:
-      /* UNIMPL case SO_USELOOPBACK: */
-        if( *optlen < sizeof(int) ) {
-          err = EINVAL;
-        }
-          break;
-
-      default:
-        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, UNIMPL: optname=0x%x, ..)\n", s, optname));
-        err = ENOPROTOOPT;
-      }  /* switch */
-      break;
-                     
-/* Level: IPPROTO_IP */
-  case IPPROTO_IP:
-      switch(optname) {
-      /* UNIMPL case IP_HDRINCL: */
-      /* UNIMPL case IP_RCVDSTADDR: */
-      /* UNIMPL case IP_RCVIF: */
-      case IP_TTL:
-      case IP_TOS:
-        if( *optlen < sizeof(int) ) {
-          err = EINVAL;
-        }
-        break;
-
-      default:
-        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, UNIMPL: optname=0x%x, ..)\n", s, optname));
-        err = ENOPROTOOPT;
-      }  /* switch */
-      break;
-         
-/* Level: IPPROTO_TCP */
-  case IPPROTO_TCP:
-      if( *optlen < sizeof(int) ) {
-        err = EINVAL;
-        break;
-    }
-      
-      /* If this is no TCP socket, ignore any options. */
-      if ( sock->conn->type != NETCONN_TCP ) return 0;
-
-      switch( optname ) {
-      case TCP_NODELAY:
-      case TCP_KEEPALIVE:
-        break;
-         
-      default:
-        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, UNIMPL: optname=0x%x, ..)\n", s, optname));
-        err = ENOPROTOOPT;
-      }  /* switch */
-      break;
-
-/* UNDEFINED LEVEL */
-  default:
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, level=0x%x, UNIMPL: optname=0x%x, ..)\n", s, level, optname));
-      err = ENOPROTOOPT;
-  }  /* switch */
-
-   
-  if( 0 != err ) {
-    sock_set_errno(sock, err);
-    return -1;
-  }
-   
-
-
-  /* Now do the actual option processing */
-
-  switch(level) {
-   
-/* Level: SOL_SOCKET */
-  case SOL_SOCKET:
-    switch( optname ) {
-
-    /* The option flags */
-    case SO_ACCEPTCONN:
-    case SO_BROADCAST:
-    /* UNIMPL case SO_DEBUG: */
-    /* UNIMPL case SO_DONTROUTE: */
-    case SO_KEEPALIVE:
-    /* UNIMPL case SO_OOBINCLUDE: */
-#if SO_REUSE
-    case SO_REUSEADDR:
-    case SO_REUSEPORT:
-#endif /* SO_REUSE */
-    /*case SO_USELOOPBACK: UNIMPL */
-      *(int*)optval = sock->conn->pcb.tcp->so_options & optname;
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, optname=0x%x, ..) = %s\n", s, optname, (*(int*)optval?"on":"off")));
-      break;
-
-    case SO_TYPE:
-      switch (sock->conn->type) {
-      case NETCONN_RAW:
-        *(int*)optval = SOCK_RAW;
-        break;
-      case NETCONN_TCP:
-        *(int*)optval = SOCK_STREAM;
-        break;
-      case NETCONN_UDP:
-      case NETCONN_UDPLITE:
-      case NETCONN_UDPNOCHKSUM:
-        *(int*)optval = SOCK_DGRAM;
-        break;
-      default: /* unrecognized socket type */
-        *(int*)optval = sock->conn->type;
-        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, SO_TYPE): unrecognized socket type %d\n", s, *(int *)optval));
-      }  /* switch */
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, SO_TYPE) = %d\n", s, *(int *)optval));
-      break;
-
-    case SO_ERROR:
-      *(int *)optval = sock->err;
-      sock->err = 0;
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, SO_ERROR) = %d\n", s, *(int *)optval));
-      break;
-    }  /* switch */
-    break;
-
-/* Level: IPPROTO_IP */
-  case IPPROTO_IP:
-    switch( optname ) {
-    case IP_TTL:
-      *(int*)optval = sock->conn->pcb.tcp->ttl;
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_TTL) = %d\n", s, *(int *)optval));
-      break;
-    case IP_TOS:
-      *(int*)optval = sock->conn->pcb.tcp->tos;
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_TOS) = %d\n", s, *(int *)optval));
-      break;
-    }  /* switch */
-    break;
-
-/* Level: IPPROTO_TCP */
-  case IPPROTO_TCP:
-    switch( optname ) {
-    case TCP_NODELAY:
-      *(int*)optval = (sock->conn->pcb.tcp->flags & TF_NODELAY);
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, TCP_NODELAY) = %s\n", s, (*(int*)optval)?"on":"off") );
-      break;
-    case TCP_KEEPALIVE:
-      *(int*)optval = (int)sock->conn->pcb.tcp->keepalive;
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, TCP_KEEPALIVE) = %d\n", s, *(int *)optval));
-      break;
-    }  /* switch */
-    break;
-  }
-
-
-  sock_set_errno(sock, err);
-  return err ? -1 : 0;
-}
-
-int lwip_setsockopt (int s, int level, int optname, const void *optval, socklen_t optlen)
-{
-  struct lwip_socket *sock = get_socket(s);
-  int err = 0;
-
-  if(!sock) {
-       set_errno(EBADF);
-    return -1;
-  }
-
-  if( NULL == optval ) {
-    sock_set_errno( sock, EFAULT );
-    return -1;
-  }
-
-
-  /* Do length and type checks for the various options first, to keep it readable. */
-  switch( level ) {
-
-/* Level: SOL_SOCKET */
-  case SOL_SOCKET:
-    switch(optname) {
-
-    case SO_BROADCAST:
-    /* UNIMPL case SO_DEBUG: */
-    /* UNIMPL case SO_DONTROUTE: */
-    case SO_KEEPALIVE:
-    /* UNIMPL case SO_OOBINLINE: */
-    /* UNIMPL case SO_RCVBUF: */
-    /* UNIMPL case SO_SNDBUF: */
-    /* UNIMPL case SO_RCVLOWAT: */
-    /* UNIMPL case SO_SNDLOWAT: */
-#if SO_REUSE
-    case SO_REUSEADDR:
-    case SO_REUSEPORT:
-#endif /* SO_REUSE */
-    /* UNIMPL case SO_USELOOPBACK: */
-      if( optlen < sizeof(int) ) {
-        err = EINVAL;
-      }
-      break;
-    default:
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, SOL_SOCKET, UNIMPL: optname=0x%x, ..)\n", s, optname));
-      err = ENOPROTOOPT;
-    }  /* switch */
-    break;
-
-/* Level: IPPROTO_IP */
-  case IPPROTO_IP:
-    switch(optname) {
-    /* UNIMPL case IP_HDRINCL: */
-    /* UNIMPL case IP_RCVDSTADDR: */
-    /* UNIMPL case IP_RCVIF: */
-    case IP_TTL:
-    case IP_TOS:
-      if( optlen < sizeof(int) ) {
-        err = EINVAL;
-      }
-        break;
-      default:
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, UNIMPL: optname=0x%x, ..)\n", s, optname));
-      err = ENOPROTOOPT;
-    }  /* switch */
-    break;
-
-/* Level: IPPROTO_TCP */
-  case IPPROTO_TCP:
-    if( optlen < sizeof(int) ) {
-      err = EINVAL;
-        break;
-    }
-
-    /* If this is no TCP socket, ignore any options. */
-    if ( sock->conn->type != NETCONN_TCP ) return 0;
-
-    switch( optname ) {
-    case TCP_NODELAY:
-    case TCP_KEEPALIVE:
-      break;
-
-    default:
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, UNIMPL: optname=0x%x, ..)\n", s, optname));
-      err = ENOPROTOOPT;
-    }  /* switch */
-    break;
-
-/* UNDEFINED LEVEL */      
-  default:
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, level=0x%x, UNIMPL: optname=0x%x, ..)\n", s, level, optname));
-    err = ENOPROTOOPT;
-  }  /* switch */
-
-
-  if( 0 != err ) {
-    sock_set_errno(sock, err);
-    return -1;
-  }
-
-
-
-  /* Now do the actual option processing */
-
-  switch(level) {
-
-/* Level: SOL_SOCKET */
-  case SOL_SOCKET:
-    switch(optname) {
-
-    /* The option flags */
-    case SO_BROADCAST:
-    /* UNIMPL case SO_DEBUG: */
-    /* UNIMPL case SO_DONTROUTE: */
-    case SO_KEEPALIVE:
-    /* UNIMPL case SO_OOBINCLUDE: */
-#if SO_REUSE
-    case SO_REUSEADDR:
-    case SO_REUSEPORT:
-#endif /* SO_REUSE */
-    /* UNIMPL case SO_USELOOPBACK: */
-      if ( *(int*)optval ) {
-        sock->conn->pcb.tcp->so_options |= optname;
-      } else {
-        sock->conn->pcb.tcp->so_options &= ~optname;
-      }
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, SOL_SOCKET, optname=0x%x, ..) -> %s\n", s, optname, (*(int*)optval?"on":"off")));
-      break;
-    }  /* switch */
-    break;
-
-/* Level: IPPROTO_IP */
-  case IPPROTO_IP:
-    switch( optname ) {
-    case IP_TTL:
-      sock->conn->pcb.tcp->ttl = (u8_t)(*(int*)optval);
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, IP_TTL, ..) -> %u\n", s, sock->conn->pcb.tcp->ttl));
-      break;
-    case IP_TOS:
-      sock->conn->pcb.tcp->tos = (u8_t)(*(int*)optval);
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, IP_TOS, ..)-> %u\n", s, sock->conn->pcb.tcp->tos));
-      break;
-    }  /* switch */
-    break;
-
-/* Level: IPPROTO_TCP */
-  case IPPROTO_TCP:
-    switch( optname ) {
-    case TCP_NODELAY:
-      if ( *(int*)optval ) {
-        sock->conn->pcb.tcp->flags |= TF_NODELAY;
-      } else {
-        sock->conn->pcb.tcp->flags &= ~TF_NODELAY;
-      }
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_NODELAY) -> %s\n", s, (*(int *)optval)?"on":"off") );
-      break;
-    case TCP_KEEPALIVE:
-      sock->conn->pcb.tcp->keepalive = (u32_t)(*(int*)optval);
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPALIVE) -> %lu\n", s, sock->conn->pcb.tcp->keepalive));
-      break;
-    }  /* switch */
-    break;
-  }  /* switch */
-
-  sock_set_errno(sock, err);
-  return err ? -1 : 0;
-}
-
-int lwip_ioctl(int s, long cmd, void *argp)
-{
-  struct lwip_socket *sock = get_socket(s);
-
-  if(!sock) {
-       set_errno(EBADF);
-    return -1;
-  }
-
-  switch (cmd) {
-  case FIONREAD:
-    if (!argp) {
-      sock_set_errno(sock, EINVAL);
-      return -1;
-    }
-
-    *((u16_t*)argp) = sock->conn->recv_avail;
-
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, FIONREAD, %p) = %u\n", s, argp, *((u16_t*)argp)));
-    sock_set_errno(sock, 0);
-    return 0;
-
-  case FIONBIO:
-    if (argp && *(u32_t*)argp)
-      sock->flags |= O_NONBLOCK;
-    else
-      sock->flags &= ~O_NONBLOCK;
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, FIONBIO, %d)\n", s, !!(sock->flags & O_NONBLOCK)));
-    sock_set_errno(sock, 0);
-    return 0;
-
-  default:
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, UNIMPL: 0x%lx, %p)\n", s, cmd, argp));
-    sock_set_errno(sock, ENOSYS); /* not yet implemented */
-    return -1;
-  }
-}
-
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without modification,\r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED\r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT\r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY\r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ *\r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ * Improved by Marc Boucher <marc@mbsi.ca> and David Haas <dhaas@alum.rpi.edu>\r
+ *\r
+ */\r
+\r
+#include <string.h>\r
+#include <errno.h>\r
+\r
+#include "lwip/opt.h"\r
+#include "lwip/api.h"\r
+#include "lwip/arch.h"\r
+#include "lwip/sys.h"\r
+\r
+#include "lwip/sockets.h"\r
+\r
+#define NUM_SOCKETS MEMP_NUM_NETCONN\r
+\r
+struct lwip_socket {\r
+  struct netconn *conn;\r
+  struct netbuf *lastdata;\r
+  u16_t lastoffset;\r
+  u16_t rcvevent;\r
+  u16_t sendevent;\r
+  u16_t  flags;\r
+  int err;\r
+};\r
+\r
+struct lwip_select_cb\r
+{\r
+    struct lwip_select_cb *next;\r
+    fd_set *readset;\r
+    fd_set *writeset;\r
+    fd_set *exceptset;\r
+    int sem_signalled;\r
+    sys_sem_t sem;\r
+};\r
+\r
+static struct lwip_socket sockets[NUM_SOCKETS];\r
+static struct lwip_select_cb *select_cb_list = 0;\r
+\r
+static sys_sem_t socksem = 0;\r
+static sys_sem_t selectsem = 0;\r
+\r
+static void\r
+event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len);\r
+\r
+static int err_to_errno_table[11] = {\r
+    0,      /* ERR_OK    0      No error, everything OK. */\r
+    ENOMEM,    /* ERR_MEM  -1      Out of memory error.     */\r
+    ENOBUFS,    /* ERR_BUF  -2      Buffer error.            */\r
+    ECONNABORTED,  /* ERR_ABRT -3      Connection aborted.      */\r
+    ECONNRESET,    /* ERR_RST  -4      Connection reset.        */\r
+    ESHUTDOWN,    /* ERR_CLSD -5      Connection closed.       */\r
+    ENOTCONN,    /* ERR_CONN -6      Not connected.           */\r
+    EINVAL,    /* ERR_VAL  -7      Illegal value.           */\r
+    EIO,    /* ERR_ARG  -8      Illegal argument.        */\r
+    EHOSTUNREACH,  /* ERR_RTE  -9      Routing problem.         */\r
+    EADDRINUSE    /* ERR_USE  -10     Address in use.          */\r
+};\r
+\r
+#define err_to_errno(err) \\r
+  ((err) < (sizeof(err_to_errno_table)/sizeof(int))) ? \\r
+    err_to_errno_table[-(err)] : EIO\r
+\r
+#ifdef ERRNO\r
+#define set_errno(err) errno = (err)\r
+#else\r
+#define set_errno(err)\r
+#endif\r
+\r
+#define sock_set_errno(sk, e) do { \\r
+      sk->err = (e); \\r
+      set_errno(sk->err); \\r
+} while (0)\r
+\r
+\r
+static struct lwip_socket *\r
+get_socket(int s)\r
+{\r
+  struct lwip_socket *sock;\r
+\r
+  if ((s < 0) || (s > NUM_SOCKETS)) {\r
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("get_socket(%d): invalid\n", s));\r
+    set_errno(EBADF);\r
+    return NULL;\r
+  }\r
+\r
+  sock = &sockets[s];\r
+\r
+  if (!sock->conn) {\r
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("get_socket(%d): not active\n", s));\r
+    set_errno(EBADF);\r
+    return NULL;\r
+  }\r
+\r
+  return sock;\r
+}\r
+\r
+static int\r
+alloc_socket(struct netconn *newconn)\r
+{\r
+  int i;\r
+\r
+  if (!socksem)\r
+      socksem = sys_sem_new(1);\r
+\r
+  /* Protect socket array */\r
+  sys_sem_wait(socksem);\r
+\r
+  /* allocate a new socket identifier */\r
+  for(i = 0; i < NUM_SOCKETS; ++i) {\r
+    if (!sockets[i].conn) {\r
+      sockets[i].conn = newconn;\r
+      sockets[i].lastdata = NULL;\r
+      sockets[i].lastoffset = 0;\r
+      sockets[i].rcvevent = 0;\r
+      sockets[i].sendevent = 1; /* TCP send buf is empty */\r
+      sockets[i].flags = 0;\r
+      sockets[i].err = 0;\r
+      sys_sem_signal(socksem);\r
+      return i;\r
+    }\r
+  }\r
+  sys_sem_signal(socksem);\r
+  return -1;\r
+}\r
+\r
+int\r
+lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen)\r
+{\r
+  struct lwip_socket *sock;\r
+  struct netconn *newconn;\r
+  struct ip_addr naddr;\r
+  u16_t port;\r
+  int newsock;\r
+  struct sockaddr_in sin;\r
+\r
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d)...\n", s));\r
+  sock = get_socket(s);\r
+  if (!sock) {\r
+    set_errno(EBADF);\r
+    return -1;\r
+  }\r
+\r
+  newconn = netconn_accept(sock->conn);\r
+\r
+  /* get the IP address and port of the remote host */\r
+  netconn_peer(newconn, &naddr, &port);\r
+\r
+  memset(&sin, 0, sizeof(sin));\r
+  sin.sin_len = sizeof(sin);\r
+  sin.sin_family = AF_INET;\r
+  sin.sin_port = htons(port);\r
+  sin.sin_addr.s_addr = naddr.addr;\r
+\r
+  if (*addrlen > sizeof(sin))\r
+      *addrlen = sizeof(sin);\r
+\r
+  memcpy(addr, &sin, *addrlen);\r
+\r
+  newsock = alloc_socket(newconn);\r
+  if (newsock == -1) {\r
+    netconn_delete(newconn);\r
+  sock_set_errno(sock, ENOBUFS);\r
+  return -1;\r
+  }\r
+  newconn->callback = event_callback;\r
+  sock = get_socket(newsock);\r
+\r
+  sys_sem_wait(socksem);\r
+  sock->rcvevent += -1 - newconn->socket;\r
+  newconn->socket = newsock;\r
+  sys_sem_signal(socksem);\r
+\r
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d) returning new sock=%d addr=", s, newsock));\r
+  ip_addr_debug_print(SOCKETS_DEBUG, &naddr);\r
+  LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u\n", port));\r
+\r
+  sock_set_errno(sock, 0);\r
+  return newsock;\r
+}\r
+\r
+int\r
+lwip_bind(int s, struct sockaddr *name, socklen_t namelen)\r
+{\r
+  struct lwip_socket *sock;\r
+  struct ip_addr local_addr;\r
+  u16_t local_port;\r
+  err_t err;\r
+\r
+  sock = get_socket(s);\r
+  if (!sock) {\r
+    set_errno(EBADF);\r
+    return -1;\r
+  }\r
+\r
+  local_addr.addr = ((struct sockaddr_in *)name)->sin_addr.s_addr;\r
+  local_port = ((struct sockaddr_in *)name)->sin_port;\r
+\r
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d, addr=", s));\r
+  ip_addr_debug_print(SOCKETS_DEBUG, &local_addr);\r
+  LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u)\n", ntohs(local_port)));\r
+\r
+  err = netconn_bind(sock->conn, &local_addr, ntohs(local_port));\r
+\r
+  if (err != ERR_OK) {\r
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d) failed, err=%d\n", s, err));\r
+    sock_set_errno(sock, err_to_errno(err));\r
+    return -1;\r
+  }\r
+\r
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d) succeeded\n", s));\r
+  sock_set_errno(sock, 0);\r
+  return 0;\r
+}\r
+\r
+int\r
+lwip_close(int s)\r
+{\r
+  struct lwip_socket *sock;\r
+\r
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_close(%d)\n", s));\r
+  if (!socksem)\r
+      socksem = sys_sem_new(1);\r
+\r
+  /* We cannot allow multiple closes of the same socket. */\r
+  sys_sem_wait(socksem);\r
+\r
+  sock = get_socket(s);\r
+  if (!sock) {\r
+      sys_sem_signal(socksem);\r
+      set_errno(EBADF);\r
+      return -1;\r
+  }\r
+\r
+  netconn_delete(sock->conn);\r
+  if (sock->lastdata) {\r
+    netbuf_delete(sock->lastdata);\r
+  }\r
+  sock->lastdata = NULL;\r
+  sock->lastoffset = 0;\r
+  sock->conn = NULL;\r
+  sys_sem_signal(socksem);\r
+  sock_set_errno(sock, 0);\r
+  return 0;\r
+}\r
+\r
+int\r
+lwip_connect(int s, struct sockaddr *name, socklen_t namelen)\r
+{\r
+  struct lwip_socket *sock;\r
+  err_t err;\r
+\r
+  sock = get_socket(s);\r
+  if (!sock) {\r
+    set_errno(EBADF);\r
+    return -1;\r
+  }\r
+\r
+  if (((struct sockaddr_in *)name)->sin_family == AF_UNSPEC) {\r
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, AF_UNSPEC)\n", s));\r
+    err = netconn_disconnect(sock->conn);\r
+  } else {\r
+    struct ip_addr remote_addr;\r
+    u16_t remote_port;\r
+\r
+    remote_addr.addr = ((struct sockaddr_in *)name)->sin_addr.s_addr;\r
+    remote_port = ((struct sockaddr_in *)name)->sin_port;\r
+\r
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, addr=", s));\r
+    ip_addr_debug_print(SOCKETS_DEBUG, &remote_addr);\r
+    LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u)\n", ntohs(remote_port)));\r
+\r
+    err = netconn_connect(sock->conn, &remote_addr, ntohs(remote_port));\r
+   }\r
+\r
+  if (err != ERR_OK) {\r
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d) failed, err=%d\n", s, err));\r
+    sock_set_errno(sock, err_to_errno(err));\r
+    return -1;\r
+  }\r
+\r
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d) succeeded\n", s));\r
+  sock_set_errno(sock, 0);\r
+  return 0;\r
+}\r
+\r
+int\r
+lwip_listen(int s, int backlog)\r
+{\r
+  struct lwip_socket *sock;\r
+  err_t err;\r
+\r
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_listen(%d, backlog=%d)\n", s, backlog));\r
+  sock = get_socket(s);\r
+  if (!sock) {\r
+    set_errno(EBADF);\r
+    return -1;\r
+  }\r
+\r
+  err = netconn_listen(sock->conn);\r
+\r
+  if (err != ERR_OK) {\r
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_listen(%d) failed, err=%d\n", s, err));\r
+    sock_set_errno(sock, err_to_errno(err));\r
+    return -1;\r
+  }\r
+\r
+  sock_set_errno(sock, 0);\r
+  return 0;\r
+}\r
+\r
+int\r
+lwip_recvfrom(int s, void *mem, int len, unsigned int flags,\r
+        struct sockaddr *from, socklen_t *fromlen)\r
+{\r
+  struct lwip_socket *sock;\r
+  struct netbuf *buf;\r
+  u16_t buflen, copylen;\r
+  struct ip_addr *addr;\r
+  u16_t port;\r
+\r
+\r
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d, %p, %d, 0x%x, ..)\n", s, mem, len, flags));\r
+  sock = get_socket(s);\r
+  if (!sock) {\r
+    set_errno(EBADF);\r
+    return -1;\r
+  }\r
+\r
+  /* Check if there is data left from the last recv operation. */\r
+  if (sock->lastdata) {\r
+    buf = sock->lastdata;\r
+  } else {\r
+    /* If this is non-blocking call, then check first */\r
+    if (((flags & MSG_DONTWAIT) || (sock->flags & O_NONBLOCK))\r
+  && !sock->rcvevent)\r
+    {\r
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): returning EWOULDBLOCK\n", s));\r
+      sock_set_errno(sock, EWOULDBLOCK);\r
+      return -1;\r
+    }\r
+\r
+    /* No data was left from the previous operation, so we try to get\r
+       some from the network. */\r
+    buf = netconn_recv(sock->conn);\r
+\r
+    if (!buf) {\r
+      /* We should really do some error checking here. */\r
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): buf == NULL!\n", s));\r
+      sock_set_errno(sock, 0);\r
+      return 0;\r
+    }\r
+  }\r
+\r
+  buflen = netbuf_len(buf);\r
+\r
+  buflen -= sock->lastoffset;\r
+\r
+  if (len > buflen) {\r
+    copylen = buflen;\r
+  } else {\r
+    copylen = len;\r
+  }\r
+\r
+  /* copy the contents of the received buffer into\r
+     the supplied memory pointer mem */\r
+  netbuf_copy_partial(buf, mem, copylen, sock->lastoffset);\r
+\r
+  /* Check to see from where the data was. */\r
+  if (from && fromlen) {\r
+    struct sockaddr_in sin;\r
+\r
+    addr = netbuf_fromaddr(buf);\r
+    port = netbuf_fromport(buf);\r
+\r
+    memset(&sin, 0, sizeof(sin));\r
+    sin.sin_len = sizeof(sin);\r
+    sin.sin_family = AF_INET;\r
+    sin.sin_port = htons(port);\r
+    sin.sin_addr.s_addr = addr->addr;\r
+\r
+    if (*fromlen > sizeof(sin))\r
+      *fromlen = sizeof(sin);\r
+\r
+    memcpy(from, &sin, *fromlen);\r
+\r
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): addr=", s));\r
+    ip_addr_debug_print(SOCKETS_DEBUG, addr);\r
+    LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u len=%u\n", port, copylen));\r
+  } else {\r
+#if SOCKETS_DEBUG\r
+    addr = netbuf_fromaddr(buf);\r
+    port = netbuf_fromport(buf);\r
+\r
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): addr=", s));\r
+    ip_addr_debug_print(SOCKETS_DEBUG, addr);\r
+    LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u len=%u\n", port, copylen));\r
+#endif\r
+\r
+  }\r
+\r
+  /* If this is a TCP socket, check if there is data left in the\r
+     buffer. If so, it should be saved in the sock structure for next\r
+     time around. */\r
+  if (netconn_type(sock->conn) == NETCONN_TCP && buflen - copylen > 0) {\r
+    sock->lastdata = buf;\r
+    sock->lastoffset += copylen;\r
+  } else {\r
+    sock->lastdata = NULL;\r
+    sock->lastoffset = 0;\r
+    netbuf_delete(buf);\r
+  }\r
+\r
+\r
+  sock_set_errno(sock, 0);\r
+  return copylen;\r
+}\r
+\r
+int\r
+lwip_read(int s, void *mem, int len)\r
+{\r
+  return lwip_recvfrom(s, mem, len, 0, NULL, NULL);\r
+}\r
+\r
+int\r
+lwip_recv(int s, void *mem, int len, unsigned int flags)\r
+{\r
+  return lwip_recvfrom(s, mem, len, flags, NULL, NULL);\r
+}\r
+\r
+int\r
+lwip_send(int s, void *data, int size, unsigned int flags)\r
+{\r
+  struct lwip_socket *sock;\r
+  struct netbuf *buf;\r
+  err_t err;\r
+\r
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d, data=%p, size=%d, flags=0x%x)\n", s, data, size, flags));\r
+\r
+  sock = get_socket(s);\r
+  if (!sock) {\r
+    set_errno(EBADF);\r
+    return -1;\r
+  }\r
+\r
+  switch (netconn_type(sock->conn)) {\r
+  case NETCONN_RAW:\r
+  case NETCONN_UDP:\r
+  case NETCONN_UDPLITE:\r
+  case NETCONN_UDPNOCHKSUM:\r
+    /* create a buffer */\r
+    buf = netbuf_new();\r
+\r
+    if (!buf) {\r
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) ENOBUFS\n", s));\r
+      sock_set_errno(sock, ENOBUFS);\r
+      return -1;\r
+    }\r
+\r
+    /* make the buffer point to the data that should\r
+       be sent */\r
+    netbuf_ref(buf, data, size);\r
+\r
+    /* send the data */\r
+    err = netconn_send(sock->conn, buf);\r
+\r
+    /* deallocated the buffer */\r
+    netbuf_delete(buf);\r
+    break;\r
+  case NETCONN_TCP:\r
+    err = netconn_write(sock->conn, data, size, NETCONN_COPY);\r
+    break;\r
+  default:\r
+    err = ERR_ARG;\r
+    break;\r
+  }\r
+  if (err != ERR_OK) {\r
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) err=%d\n", s, err));\r
+    sock_set_errno(sock, err_to_errno(err));\r
+    return -1;\r
+  }\r
+\r
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) ok size=%d\n", s, size));\r
+  sock_set_errno(sock, 0);\r
+  return size;\r
+}\r
+\r
+int\r
+lwip_sendto(int s, void *data, int size, unsigned int flags,\r
+       struct sockaddr *to, socklen_t tolen)\r
+{\r
+  struct lwip_socket *sock;\r
+  struct ip_addr remote_addr, addr;\r
+  u16_t remote_port, port;\r
+  int ret,connected;\r
+\r
+  sock = get_socket(s);\r
+  if (!sock) {\r
+    set_errno(EBADF);\r
+    return -1;\r
+  }\r
+\r
+  /* get the peer if currently connected */\r
+  connected = (netconn_peer(sock->conn, &addr, &port) == ERR_OK);\r
+\r
+  remote_addr.addr = ((struct sockaddr_in *)to)->sin_addr.s_addr;\r
+  remote_port = ((struct sockaddr_in *)to)->sin_port;\r
+\r
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_sendto(%d, data=%p, size=%d, flags=0x%x to=", s, data, size, flags));\r
+  ip_addr_debug_print(SOCKETS_DEBUG, &remote_addr);\r
+  LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u\n", ntohs(remote_port)));\r
+\r
+  netconn_connect(sock->conn, &remote_addr, ntohs(remote_port));\r
+\r
+  ret = lwip_send(s, data, size, flags);\r
+\r
+  /* reset the remote address and port number\r
+     of the connection */\r
+  if (connected)\r
+    netconn_connect(sock->conn, &addr, port);\r
+  else\r
+  netconn_disconnect(sock->conn);\r
+  return ret;\r
+}\r
+\r
+int\r
+lwip_socket(int domain, int type, int protocol)\r
+{\r
+  struct netconn *conn;\r
+  int i;\r
+\r
+  /* create a netconn */\r
+  switch (type) {\r
+  case SOCK_RAW:\r
+    conn = netconn_new_with_proto_and_callback(NETCONN_RAW, protocol, event_callback);\r
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_RAW, %d) = ", domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol));\r
+    break;\r
+  case SOCK_DGRAM:\r
+    conn = netconn_new_with_callback(NETCONN_UDP, event_callback);\r
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_DGRAM, %d) = ", domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol));\r
+    break;\r
+  case SOCK_STREAM:\r
+    conn = netconn_new_with_callback(NETCONN_TCP, event_callback);\r
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_STREAM, %d) = ", domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol));\r
+    break;\r
+  default:\r
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%d, %d/UNKNOWN, %d) = -1\n", domain, type, protocol));\r
+    set_errno(EINVAL);\r
+    return -1;\r
+  }\r
+\r
+  if (!conn) {\r
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("-1 / ENOBUFS (could not create netconn)\n"));\r
+    set_errno(ENOBUFS);\r
+    return -1;\r
+  }\r
+\r
+  i = alloc_socket(conn);\r
+\r
+  if (i == -1) {\r
+    netconn_delete(conn);\r
+  set_errno(ENOBUFS);\r
+  return -1;\r
+  }\r
+  conn->socket = i;\r
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("%d\n", i));\r
+  set_errno(0);\r
+  return i;\r
+}\r
+\r
+int\r
+lwip_write(int s, void *data, int size)\r
+{\r
+   return lwip_send(s, data, size, 0);\r
+}\r
+\r
+\r
+static int\r
+lwip_selscan(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset)\r
+{\r
+    int i, nready = 0;\r
+    fd_set lreadset, lwriteset, lexceptset;\r
+    struct lwip_socket *p_sock;\r
+\r
+    FD_ZERO(&lreadset);\r
+    FD_ZERO(&lwriteset);\r
+    FD_ZERO(&lexceptset);\r
+\r
+    /* Go through each socket in each list to count number of sockets which\r
+       currently match */\r
+    for(i = 0; i < maxfdp1; i++)\r
+    {\r
+        if (FD_ISSET(i, readset))\r
+        {\r
+            /* See if netconn of this socket is ready for read */\r
+            p_sock = get_socket(i);\r
+            if (p_sock && (p_sock->lastdata || p_sock->rcvevent))\r
+            {\r
+                FD_SET(i, &lreadset);\r
+               LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for reading\n", i));\r
+                nready++;\r
+            }\r
+        }\r
+        if (FD_ISSET(i, writeset))\r
+        {\r
+            /* See if netconn of this socket is ready for write */\r
+            p_sock = get_socket(i);\r
+            if (p_sock && p_sock->sendevent)\r
+            {\r
+                FD_SET(i, &lwriteset);\r
+               LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for writing\n", i));\r
+                nready++;\r
+            }\r
+        }\r
+    }\r
+    *readset = lreadset;\r
+    *writeset = lwriteset;\r
+    FD_ZERO(exceptset);\r
+\r
+    return nready;\r
+}\r
+\r
+\r
+\r
+int\r
+lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,\r
+               struct timeval *timeout)\r
+{\r
+    int i;\r
+    int nready;\r
+    fd_set lreadset, lwriteset, lexceptset;\r
+    u32_t msectimeout;\r
+    struct lwip_select_cb select_cb;\r
+    struct lwip_select_cb *p_selcb;\r
+\r
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select(%d, %p, %p, %p, tvsec=%ld tvusec=%ld)\n", maxfdp1, (void *)readset, (void *) writeset, (void *) exceptset, timeout ? timeout->tv_sec : -1L, timeout ? timeout->tv_usec : -1L));\r
+\r
+    select_cb.next = 0;\r
+    select_cb.readset = readset;\r
+    select_cb.writeset = writeset;\r
+    select_cb.exceptset = exceptset;\r
+    select_cb.sem_signalled = 0;\r
+\r
+    /* Protect ourselves searching through the list */\r
+    if (!selectsem)\r
+        selectsem = sys_sem_new(1);\r
+    sys_sem_wait(selectsem);\r
+\r
+    if (readset)\r
+        lreadset = *readset;\r
+    else\r
+        FD_ZERO(&lreadset);\r
+    if (writeset)\r
+        lwriteset = *writeset;\r
+    else\r
+        FD_ZERO(&lwriteset);\r
+    if (exceptset)\r
+        lexceptset = *exceptset;\r
+    else\r
+        FD_ZERO(&lexceptset);\r
+\r
+    /* Go through each socket in each list to count number of sockets which\r
+       currently match */\r
+    nready = lwip_selscan(maxfdp1, &lreadset, &lwriteset, &lexceptset);\r
+\r
+    /* If we don't have any current events, then suspend if we are supposed to */\r
+    if (!nready)\r
+    {\r
+        if (timeout && timeout->tv_sec == 0 && timeout->tv_usec == 0)\r
+        {\r
+            sys_sem_signal(selectsem);\r
+            if (readset)\r
+                FD_ZERO(readset);\r
+            if (writeset)\r
+                FD_ZERO(writeset);\r
+            if (exceptset)\r
+                FD_ZERO(exceptset);\r
+\r
+           LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: no timeout, returning 0\n"));\r
+           set_errno(0);\r
+\r
+            return 0;\r
+        }\r
+\r
+        /* add our semaphore to list */\r
+        /* We don't actually need any dynamic memory. Our entry on the\r
+         * list is only valid while we are in this function, so it's ok\r
+         * to use local variables */\r
+\r
+        select_cb.sem = sys_sem_new(0);\r
+        /* Note that we are still protected */\r
+        /* Put this select_cb on top of list */\r
+        select_cb.next = select_cb_list;\r
+        select_cb_list = &select_cb;\r
+\r
+        /* Now we can safely unprotect */\r
+        sys_sem_signal(selectsem);\r
+\r
+        /* Now just wait to be woken */\r
+        if (timeout == 0)\r
+            /* Wait forever */\r
+            msectimeout = 0;\r
+        else\r
+            msectimeout =  ((timeout->tv_sec * 1000) + ((timeout->tv_usec + 500)/1000));\r
+\r
+        i = sys_sem_wait_timeout(select_cb.sem, msectimeout);\r
+\r
+        /* Take us off the list */\r
+        sys_sem_wait(selectsem);\r
+        if (select_cb_list == &select_cb)\r
+            select_cb_list = select_cb.next;\r
+        else\r
+            for (p_selcb = select_cb_list; p_selcb; p_selcb = p_selcb->next)\r
+                if (p_selcb->next == &select_cb)\r
+                {\r
+                    p_selcb->next = select_cb.next;\r
+                    break;\r
+                }\r
+\r
+        sys_sem_signal(selectsem);\r
+\r
+        sys_sem_free(select_cb.sem);\r
+        if (i == 0)             /* Timeout */\r
+        {\r
+            if (readset)\r
+                FD_ZERO(readset);\r
+            if (writeset)\r
+                FD_ZERO(writeset);\r
+            if (exceptset)\r
+                FD_ZERO(exceptset);\r
+\r
+           LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: timeout expired\n"));\r
+           set_errno(0);\r
+\r
+            return 0;\r
+        }\r
+\r
+        if (readset)\r
+            lreadset = *readset;\r
+        else\r
+            FD_ZERO(&lreadset);\r
+        if (writeset)\r
+            lwriteset = *writeset;\r
+        else\r
+            FD_ZERO(&lwriteset);\r
+        if (exceptset)\r
+            lexceptset = *exceptset;\r
+        else\r
+            FD_ZERO(&lexceptset);\r
+\r
+        /* See what's set */\r
+        nready = lwip_selscan(maxfdp1, &lreadset, &lwriteset, &lexceptset);\r
+    }\r
+    else\r
+        sys_sem_signal(selectsem);\r
+\r
+    if (readset)\r
+        *readset = lreadset;\r
+    if (writeset)\r
+        *writeset = lwriteset;\r
+    if (exceptset)\r
+        *exceptset = lexceptset;\r
+\r
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: nready=%d\n", nready));\r
+    set_errno(0);\r
+\r
+    return nready;\r
+}\r
+\r
+\r
+static void\r
+event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len)\r
+{\r
+    int s;\r
+    struct lwip_socket *sock;\r
+    struct lwip_select_cb *scb;\r
+\r
+    /* Get socket */\r
+    if (conn)\r
+    {\r
+        s = conn->socket;\r
+        if (s < 0)\r
+        {\r
+            /* Data comes in right away after an accept, even though\r
+             * the server task might not have created a new socket yet.\r
+             * Just count down (or up) if that's the case and we\r
+             * will use the data later. Note that only receive events\r
+             * can happen before the new socket is set up. */\r
+            if (evt == NETCONN_EVT_RCVPLUS)\r
+                conn->socket--;\r
+            return;\r
+        }\r
+\r
+        sock = get_socket(s);\r
+        if (!sock)\r
+            return;\r
+    }\r
+    else\r
+        return;\r
+\r
+    if (!selectsem)\r
+        selectsem = sys_sem_new(1);\r
+\r
+    sys_sem_wait(selectsem);\r
+    /* Set event as required */\r
+    switch (evt)\r
+    {\r
+      case NETCONN_EVT_RCVPLUS:\r
+        sock->rcvevent++;\r
+        break;\r
+      case NETCONN_EVT_RCVMINUS:\r
+        sock->rcvevent--;\r
+        break;\r
+      case NETCONN_EVT_SENDPLUS:\r
+        sock->sendevent = 1;\r
+        break;\r
+      case NETCONN_EVT_SENDMINUS:\r
+        sock->sendevent = 0;\r
+        break;\r
+    }\r
+    sys_sem_signal(selectsem);\r
+\r
+    /* Now decide if anyone is waiting for this socket */\r
+    /* NOTE: This code is written this way to protect the select link list\r
+       but to avoid a deadlock situation by releasing socksem before\r
+       signalling for the select. This means we need to go through the list\r
+       multiple times ONLY IF a select was actually waiting. We go through\r
+       the list the number of waiting select calls + 1. This list is\r
+       expected to be small. */\r
+    while (1)\r
+    {\r
+        sys_sem_wait(selectsem);\r
+        for (scb = select_cb_list; scb; scb = scb->next)\r
+        {\r
+            if (scb->sem_signalled == 0)\r
+            {\r
+                /* Test this select call for our socket */\r
+                if (scb->readset && FD_ISSET(s, scb->readset))\r
+                    if (sock->rcvevent)\r
+                        break;\r
+                if (scb->writeset && FD_ISSET(s, scb->writeset))\r
+                    if (sock->sendevent)\r
+                        break;\r
+            }\r
+        }\r
+        if (scb)\r
+        {\r
+            scb->sem_signalled = 1;\r
+            sys_sem_signal(selectsem);\r
+            sys_sem_signal(scb->sem);\r
+        } else {\r
+            sys_sem_signal(selectsem);\r
+            break;\r
+        }\r
+    }\r
+\r
+}\r
+\r
+\r
+\r
+\r
+int lwip_shutdown(int s, int how)\r
+{\r
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_shutdown(%d, how=%d)\n", s, how));\r
+  return lwip_close(s); /* XXX temporary hack until proper implementation */\r
+}\r
+\r
+int lwip_getpeername (int s, struct sockaddr *name, socklen_t *namelen)\r
+{\r
+  struct lwip_socket *sock;\r
+  struct sockaddr_in sin;\r
+  struct ip_addr naddr;\r
+\r
+  sock = get_socket(s);\r
+  if (!sock) {\r
+    set_errno(EBADF);\r
+    return -1;\r
+  }\r
+\r
+  memset(&sin, 0, sizeof(sin));\r
+  sin.sin_len = sizeof(sin);\r
+  sin.sin_family = AF_INET;\r
+\r
+  /* get the IP address and port of the remote host */\r
+  netconn_peer(sock->conn, &naddr, &sin.sin_port);\r
+\r
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getpeername(%d, addr=", s));\r
+  ip_addr_debug_print(SOCKETS_DEBUG, &naddr);\r
+  LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%d)\n", sin.sin_port));\r
+\r
+  sin.sin_port = htons(sin.sin_port);\r
+  sin.sin_addr.s_addr = naddr.addr;\r
+\r
+  if (*namelen > sizeof(sin))\r
+      *namelen = sizeof(sin);\r
+\r
+  memcpy(name, &sin, *namelen);\r
+  sock_set_errno(sock, 0);\r
+  return 0;\r
+}\r
+\r
+int lwip_getsockname (int s, struct sockaddr *name, socklen_t *namelen)\r
+{\r
+  struct lwip_socket *sock;\r
+  struct sockaddr_in sin;\r
+  struct ip_addr *naddr;\r
+\r
+  sock = get_socket(s);\r
+  if (!sock) {\r
+    set_errno(EBADF);\r
+    return -1;\r
+  }\r
+\r
+  memset(&sin, 0, sizeof(sin));\r
+  sin.sin_len = sizeof(sin);\r
+  sin.sin_family = AF_INET;\r
+\r
+  /* get the IP address and port of the remote host */\r
+  netconn_addr(sock->conn, &naddr, &sin.sin_port);\r
+\r
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockname(%d, addr=", s));\r
+  ip_addr_debug_print(SOCKETS_DEBUG, naddr);\r
+  LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%d)\n", sin.sin_port));\r
+\r
+  sin.sin_port = htons(sin.sin_port);\r
+  sin.sin_addr.s_addr = naddr->addr;\r
+\r
+  if (*namelen > sizeof(sin))\r
+      *namelen = sizeof(sin);\r
+\r
+  memcpy(name, &sin, *namelen);\r
+  sock_set_errno(sock, 0);\r
+  return 0;\r
+}\r
+\r
+int lwip_getsockopt (int s, int level, int optname, void *optval, socklen_t *optlen)\r
+{\r
+  int err = 0;\r
+  struct lwip_socket *sock = get_socket(s);\r
+\r
+  if(!sock) {\r
+       set_errno(EBADF);\r
+    return -1;\r
+  }\r
+\r
+  if( NULL == optval || NULL == optlen ) {\r
+    sock_set_errno( sock, EFAULT );\r
+    return -1;\r
+  }\r
+\r
+  /* Do length and type checks for the various options first, to keep it readable. */\r
+  switch( level ) {\r
+   \r
+/* Level: SOL_SOCKET */\r
+  case SOL_SOCKET:\r
+      switch(optname) {\r
+         \r
+      case SO_ACCEPTCONN:\r
+      case SO_BROADCAST:\r
+      /* UNIMPL case SO_DEBUG: */\r
+      /* UNIMPL case SO_DONTROUTE: */\r
+      case SO_ERROR:\r
+      case SO_KEEPALIVE:\r
+      /* UNIMPL case SO_OOBINLINE: */\r
+      /* UNIMPL case SO_RCVBUF: */\r
+      /* UNIMPL case SO_SNDBUF: */\r
+      /* UNIMPL case SO_RCVLOWAT: */\r
+      /* UNIMPL case SO_SNDLOWAT: */\r
+#if SO_REUSE\r
+      case SO_REUSEADDR:\r
+      case SO_REUSEPORT:\r
+#endif /* SO_REUSE */\r
+      case SO_TYPE:\r
+      /* UNIMPL case SO_USELOOPBACK: */\r
+        if( *optlen < sizeof(int) ) {\r
+          err = EINVAL;\r
+        }\r
+          break;\r
+\r
+      default:\r
+        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, UNIMPL: optname=0x%x, ..)\n", s, optname));\r
+        err = ENOPROTOOPT;\r
+      }  /* switch */\r
+      break;\r
+                     \r
+/* Level: IPPROTO_IP */\r
+  case IPPROTO_IP:\r
+      switch(optname) {\r
+      /* UNIMPL case IP_HDRINCL: */\r
+      /* UNIMPL case IP_RCVDSTADDR: */\r
+      /* UNIMPL case IP_RCVIF: */\r
+      case IP_TTL:\r
+      case IP_TOS:\r
+        if( *optlen < sizeof(int) ) {\r
+          err = EINVAL;\r
+        }\r
+        break;\r
+\r
+      default:\r
+        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, UNIMPL: optname=0x%x, ..)\n", s, optname));\r
+        err = ENOPROTOOPT;\r
+      }  /* switch */\r
+      break;\r
+         \r
+/* Level: IPPROTO_TCP */\r
+  case IPPROTO_TCP:\r
+      if( *optlen < sizeof(int) ) {\r
+        err = EINVAL;\r
+        break;\r
+    }\r
+      \r
+      /* If this is no TCP socket, ignore any options. */\r
+      if ( sock->conn->type != NETCONN_TCP ) return 0;\r
+\r
+      switch( optname ) {\r
+      case TCP_NODELAY:\r
+      case TCP_KEEPALIVE:\r
+        break;\r
+         \r
+      default:\r
+        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, UNIMPL: optname=0x%x, ..)\n", s, optname));\r
+        err = ENOPROTOOPT;\r
+      }  /* switch */\r
+      break;\r
+\r
+/* UNDEFINED LEVEL */\r
+  default:\r
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, level=0x%x, UNIMPL: optname=0x%x, ..)\n", s, level, optname));\r
+      err = ENOPROTOOPT;\r
+  }  /* switch */\r
+\r
+   \r
+  if( 0 != err ) {\r
+    sock_set_errno(sock, err);\r
+    return -1;\r
+  }\r
+   \r
+\r
+\r
+  /* Now do the actual option processing */\r
+\r
+  switch(level) {\r
+   \r
+/* Level: SOL_SOCKET */\r
+  case SOL_SOCKET:\r
+    switch( optname ) {\r
+\r
+    /* The option flags */\r
+    case SO_ACCEPTCONN:\r
+    case SO_BROADCAST:\r
+    /* UNIMPL case SO_DEBUG: */\r
+    /* UNIMPL case SO_DONTROUTE: */\r
+    case SO_KEEPALIVE:\r
+    /* UNIMPL case SO_OOBINCLUDE: */\r
+#if SO_REUSE\r
+    case SO_REUSEADDR:\r
+    case SO_REUSEPORT:\r
+#endif /* SO_REUSE */\r
+    /*case SO_USELOOPBACK: UNIMPL */\r
+      *(int*)optval = sock->conn->pcb.tcp->so_options & optname;\r
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, optname=0x%x, ..) = %s\n", s, optname, (*(int*)optval?"on":"off")));\r
+      break;\r
+\r
+    case SO_TYPE:\r
+      switch (sock->conn->type) {\r
+      case NETCONN_RAW:\r
+        *(int*)optval = SOCK_RAW;\r
+        break;\r
+      case NETCONN_TCP:\r
+        *(int*)optval = SOCK_STREAM;\r
+        break;\r
+      case NETCONN_UDP:\r
+      case NETCONN_UDPLITE:\r
+      case NETCONN_UDPNOCHKSUM:\r
+        *(int*)optval = SOCK_DGRAM;\r
+        break;\r
+      default: /* unrecognized socket type */\r
+        *(int*)optval = sock->conn->type;\r
+        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, SO_TYPE): unrecognized socket type %d\n", s, *(int *)optval));\r
+      }  /* switch */\r
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, SO_TYPE) = %d\n", s, *(int *)optval));\r
+      break;\r
+\r
+    case SO_ERROR:\r
+      *(int *)optval = sock->err;\r
+      sock->err = 0;\r
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, SO_ERROR) = %d\n", s, *(int *)optval));\r
+      break;\r
+    }  /* switch */\r
+    break;\r
+\r
+/* Level: IPPROTO_IP */\r
+  case IPPROTO_IP:\r
+    switch( optname ) {\r
+    case IP_TTL:\r
+      *(int*)optval = sock->conn->pcb.tcp->ttl;\r
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_TTL) = %d\n", s, *(int *)optval));\r
+      break;\r
+    case IP_TOS:\r
+      *(int*)optval = sock->conn->pcb.tcp->tos;\r
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_TOS) = %d\n", s, *(int *)optval));\r
+      break;\r
+    }  /* switch */\r
+    break;\r
+\r
+/* Level: IPPROTO_TCP */\r
+  case IPPROTO_TCP:\r
+    switch( optname ) {\r
+    case TCP_NODELAY:\r
+      *(int*)optval = (sock->conn->pcb.tcp->flags & TF_NODELAY);\r
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, TCP_NODELAY) = %s\n", s, (*(int*)optval)?"on":"off") );\r
+      break;\r
+    case TCP_KEEPALIVE:\r
+      *(int*)optval = (int)sock->conn->pcb.tcp->keepalive;\r
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, TCP_KEEPALIVE) = %d\n", s, *(int *)optval));\r
+      break;\r
+    }  /* switch */\r
+    break;\r
+  }\r
+\r
+\r
+  sock_set_errno(sock, err);\r
+  return err ? -1 : 0;\r
+}\r
+\r
+int lwip_setsockopt (int s, int level, int optname, const void *optval, socklen_t optlen)\r
+{\r
+  struct lwip_socket *sock = get_socket(s);\r
+  int err = 0;\r
+\r
+  if(!sock) {\r
+       set_errno(EBADF);\r
+    return -1;\r
+  }\r
+\r
+  if( NULL == optval ) {\r
+    sock_set_errno( sock, EFAULT );\r
+    return -1;\r
+  }\r
+\r
+\r
+  /* Do length and type checks for the various options first, to keep it readable. */\r
+  switch( level ) {\r
+\r
+/* Level: SOL_SOCKET */\r
+  case SOL_SOCKET:\r
+    switch(optname) {\r
+\r
+    case SO_BROADCAST:\r
+    /* UNIMPL case SO_DEBUG: */\r
+    /* UNIMPL case SO_DONTROUTE: */\r
+    case SO_KEEPALIVE:\r
+    /* UNIMPL case SO_OOBINLINE: */\r
+    /* UNIMPL case SO_RCVBUF: */\r
+    /* UNIMPL case SO_SNDBUF: */\r
+    /* UNIMPL case SO_RCVLOWAT: */\r
+    /* UNIMPL case SO_SNDLOWAT: */\r
+#if SO_REUSE\r
+    case SO_REUSEADDR:\r
+    case SO_REUSEPORT:\r
+#endif /* SO_REUSE */\r
+    /* UNIMPL case SO_USELOOPBACK: */\r
+      if( optlen < sizeof(int) ) {\r
+        err = EINVAL;\r
+      }\r
+      break;\r
+    default:\r
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, SOL_SOCKET, UNIMPL: optname=0x%x, ..)\n", s, optname));\r
+      err = ENOPROTOOPT;\r
+    }  /* switch */\r
+    break;\r
+\r
+/* Level: IPPROTO_IP */\r
+  case IPPROTO_IP:\r
+    switch(optname) {\r
+    /* UNIMPL case IP_HDRINCL: */\r
+    /* UNIMPL case IP_RCVDSTADDR: */\r
+    /* UNIMPL case IP_RCVIF: */\r
+    case IP_TTL:\r
+    case IP_TOS:\r
+      if( optlen < sizeof(int) ) {\r
+        err = EINVAL;\r
+      }\r
+        break;\r
+      default:\r
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, UNIMPL: optname=0x%x, ..)\n", s, optname));\r
+      err = ENOPROTOOPT;\r
+    }  /* switch */\r
+    break;\r
+\r
+/* Level: IPPROTO_TCP */\r
+  case IPPROTO_TCP:\r
+    if( optlen < sizeof(int) ) {\r
+      err = EINVAL;\r
+        break;\r
+    }\r
+\r
+    /* If this is no TCP socket, ignore any options. */\r
+    if ( sock->conn->type != NETCONN_TCP ) return 0;\r
+\r
+    switch( optname ) {\r
+    case TCP_NODELAY:\r
+    case TCP_KEEPALIVE:\r
+      break;\r
+\r
+    default:\r
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, UNIMPL: optname=0x%x, ..)\n", s, optname));\r
+      err = ENOPROTOOPT;\r
+    }  /* switch */\r
+    break;\r
+\r
+/* UNDEFINED LEVEL */      \r
+  default:\r
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, level=0x%x, UNIMPL: optname=0x%x, ..)\n", s, level, optname));\r
+    err = ENOPROTOOPT;\r
+  }  /* switch */\r
+\r
+\r
+  if( 0 != err ) {\r
+    sock_set_errno(sock, err);\r
+    return -1;\r
+  }\r
+\r
+\r
+\r
+  /* Now do the actual option processing */\r
+\r
+  switch(level) {\r
+\r
+/* Level: SOL_SOCKET */\r
+  case SOL_SOCKET:\r
+    switch(optname) {\r
+\r
+    /* The option flags */\r
+    case SO_BROADCAST:\r
+    /* UNIMPL case SO_DEBUG: */\r
+    /* UNIMPL case SO_DONTROUTE: */\r
+    case SO_KEEPALIVE:\r
+    /* UNIMPL case SO_OOBINCLUDE: */\r
+#if SO_REUSE\r
+    case SO_REUSEADDR:\r
+    case SO_REUSEPORT:\r
+#endif /* SO_REUSE */\r
+    /* UNIMPL case SO_USELOOPBACK: */\r
+      if ( *(int*)optval ) {\r
+        sock->conn->pcb.tcp->so_options |= optname;\r
+      } else {\r
+        sock->conn->pcb.tcp->so_options &= ~optname;\r
+      }\r
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, SOL_SOCKET, optname=0x%x, ..) -> %s\n", s, optname, (*(int*)optval?"on":"off")));\r
+      break;\r
+    }  /* switch */\r
+    break;\r
+\r
+/* Level: IPPROTO_IP */\r
+  case IPPROTO_IP:\r
+    switch( optname ) {\r
+    case IP_TTL:\r
+      sock->conn->pcb.tcp->ttl = (u8_t)(*(int*)optval);\r
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, IP_TTL, ..) -> %u\n", s, sock->conn->pcb.tcp->ttl));\r
+      break;\r
+    case IP_TOS:\r
+      sock->conn->pcb.tcp->tos = (u8_t)(*(int*)optval);\r
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, IP_TOS, ..)-> %u\n", s, sock->conn->pcb.tcp->tos));\r
+      break;\r
+    }  /* switch */\r
+    break;\r
+\r
+/* Level: IPPROTO_TCP */\r
+  case IPPROTO_TCP:\r
+    switch( optname ) {\r
+    case TCP_NODELAY:\r
+      if ( *(int*)optval ) {\r
+        sock->conn->pcb.tcp->flags |= TF_NODELAY;\r
+      } else {\r
+        sock->conn->pcb.tcp->flags &= ~TF_NODELAY;\r
+      }\r
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_NODELAY) -> %s\n", s, (*(int *)optval)?"on":"off") );\r
+      break;\r
+    case TCP_KEEPALIVE:\r
+      sock->conn->pcb.tcp->keepalive = (u32_t)(*(int*)optval);\r
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPALIVE) -> %lu\n", s, sock->conn->pcb.tcp->keepalive));\r
+      break;\r
+    }  /* switch */\r
+    break;\r
+  }  /* switch */\r
+\r
+  sock_set_errno(sock, err);\r
+  return err ? -1 : 0;\r
+}\r
+\r
+int lwip_ioctl(int s, long cmd, void *argp)\r
+{\r
+  struct lwip_socket *sock = get_socket(s);\r
+\r
+  if(!sock) {\r
+       set_errno(EBADF);\r
+    return -1;\r
+  }\r
+\r
+  switch (cmd) {\r
+  case FIONREAD:\r
+    if (!argp) {\r
+      sock_set_errno(sock, EINVAL);\r
+      return -1;\r
+    }\r
+\r
+    *((u16_t*)argp) = sock->conn->recv_avail;\r
+\r
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, FIONREAD, %p) = %u\n", s, argp, *((u16_t*)argp)));\r
+    sock_set_errno(sock, 0);\r
+    return 0;\r
+\r
+  case FIONBIO:\r
+    if (argp && *(u32_t*)argp)\r
+      sock->flags |= O_NONBLOCK;\r
+    else\r
+      sock->flags &= ~O_NONBLOCK;\r
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, FIONBIO, %d)\n", s, !!(sock->flags & O_NONBLOCK)));\r
+    sock_set_errno(sock, 0);\r
+    return 0;\r
+\r
+  default:\r
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, UNIMPL: 0x%lx, %p)\n", s, cmd, argp));\r
+    sock_set_errno(sock, ENOSYS); /* not yet implemented */\r
+    return -1;\r
+  }\r
+}\r
+\r
index b9e11f8e71671da9110282d7e1953226ce521067..c580bddf92eb32a1d7510ab5777efd4b673bb0a8 100644 (file)
-/*
- * 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 <adam@sics.se>
- *
- */
-
-#include "lwip/opt.h"
-
-#include "lwip/sys.h"
-
-#include "lwip/memp.h"
-#include "lwip/pbuf.h"
-
-#include "lwip/ip.h"
-#include "lwip/udp.h"
-#include "lwip/tcp.h"
-
-#include "lwip/tcpip.h"
-
-static void (* tcpip_init_done)(void *arg) = NULL;
-static void *tcpip_init_done_arg;
-static sys_mbox_t mbox;
-
-#if LWIP_TCP
-static int tcpip_tcp_timer_active = 0;
-
-static void
-tcpip_tcp_timer(void *arg)
-{
-  (void)arg;
-
-  /* call TCP timer handler */
-  tcp_tmr();
-  /* timer still needed? */
-  if (tcp_active_pcbs || tcp_tw_pcbs) {
-    /* restart timer */
-    sys_timeout(TCP_TMR_INTERVAL, tcpip_tcp_timer, NULL);
-  } else {
-    /* disable timer */
-    tcpip_tcp_timer_active = 0;
-  }
-}
-
-#if !NO_SYS
-void
-tcp_timer_needed(void)
-{
-  /* timer is off but needed again? */
-  if (!tcpip_tcp_timer_active && (tcp_active_pcbs || tcp_tw_pcbs)) {
-    /* enable and start timer */
-    tcpip_tcp_timer_active = 1;
-    sys_timeout(TCP_TMR_INTERVAL, tcpip_tcp_timer, NULL);
-  }
-}
-#endif /* !NO_SYS */
-#endif /* LWIP_TCP */
-
-static void
-tcpip_thread(void *arg)
-{
-  struct tcpip_msg *msg;
-
-  (void)arg;
-
-  ip_init();
-#if LWIP_UDP  
-  udp_init();
-#endif
-#if LWIP_TCP
-  tcp_init();
-#endif
-  if (tcpip_init_done != NULL) {
-    tcpip_init_done(tcpip_init_done_arg);
-  }
-
-  while (1) {                          /* MAIN Loop */
-    sys_mbox_fetch(mbox, (void *)&msg);
-    switch (msg->type) {
-    case TCPIP_MSG_API:
-      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: API message %p\n", (void *)msg));
-      api_msg_input(msg->msg.apimsg);
-      break;
-    case TCPIP_MSG_INPUT:
-      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: IP packet %p\n", (void *)msg));
-      ip_input(msg->msg.inp.p, msg->msg.inp.netif);
-      break;
-    case TCPIP_MSG_CALLBACK:
-      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK %p\n", (void *)msg));
-      msg->msg.cb.f(msg->msg.cb.ctx);
-      break;
-    default:
-      break;
-    }
-    memp_free(MEMP_TCPIP_MSG, msg);
-  }
-}
-
-err_t
-tcpip_input(struct pbuf *p, struct netif *inp)
-{
-  struct tcpip_msg *msg;
-  
-  msg = memp_malloc(MEMP_TCPIP_MSG);
-  if (msg == NULL) {
-    pbuf_free(p);    
-    return ERR_MEM;  
-  }
-  
-  msg->type = TCPIP_MSG_INPUT;
-  msg->msg.inp.p = p;
-  msg->msg.inp.netif = inp;
-  sys_mbox_post(mbox, msg);
-  return ERR_OK;
-}
-
-err_t
-tcpip_callback(void (*f)(void *ctx), void *ctx)
-{
-  struct tcpip_msg *msg;
-  
-  msg = memp_malloc(MEMP_TCPIP_MSG);
-  if (msg == NULL) {
-    return ERR_MEM;  
-  }
-  
-  msg->type = TCPIP_MSG_CALLBACK;
-  msg->msg.cb.f = f;
-  msg->msg.cb.ctx = ctx;
-  sys_mbox_post(mbox, msg);
-  return ERR_OK;
-}
-
-void
-tcpip_apimsg(struct api_msg *apimsg)
-{
-  struct tcpip_msg *msg;
-  msg = memp_malloc(MEMP_TCPIP_MSG);
-  if (msg == NULL) {
-    memp_free(MEMP_API_MSG, apimsg);
-    return;
-  }
-  msg->type = TCPIP_MSG_API;
-  msg->msg.apimsg = apimsg;
-  sys_mbox_post(mbox, msg);
-}
-
-void
-tcpip_init(void (* initfunc)(void *), void *arg)
-{
-  tcpip_init_done = initfunc;
-  tcpip_init_done_arg = arg;
-  mbox = sys_mbox_new();
-  sys_thread_new(tcpip_thread, NULL, TCPIP_THREAD_PRIO);
-}
-
-
-
-
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+\r
+#include "lwip/opt.h"\r
+\r
+#include "lwip/sys.h"\r
+\r
+#include "lwip/memp.h"\r
+#include "lwip/pbuf.h"\r
+\r
+#include "lwip/ip.h"\r
+#include "lwip/udp.h"\r
+#include "lwip/tcp.h"\r
+\r
+#include "lwip/tcpip.h"\r
+\r
+static void (* tcpip_init_done)(void *arg) = NULL;\r
+static void *tcpip_init_done_arg;\r
+static sys_mbox_t mbox;\r
+\r
+#if LWIP_TCP\r
+static int tcpip_tcp_timer_active = 0;\r
+\r
+static void\r
+tcpip_tcp_timer(void *arg)\r
+{\r
+  (void)arg;\r
+\r
+  /* call TCP timer handler */\r
+  tcp_tmr();\r
+  /* timer still needed? */\r
+  if (tcp_active_pcbs || tcp_tw_pcbs) {\r
+    /* restart timer */\r
+    sys_timeout(TCP_TMR_INTERVAL, tcpip_tcp_timer, NULL);\r
+  } else {\r
+    /* disable timer */\r
+    tcpip_tcp_timer_active = 0;\r
+  }\r
+}\r
+\r
+#if !NO_SYS\r
+void\r
+tcp_timer_needed(void)\r
+{\r
+  /* timer is off but needed again? */\r
+  if (!tcpip_tcp_timer_active && (tcp_active_pcbs || tcp_tw_pcbs)) {\r
+    /* enable and start timer */\r
+    tcpip_tcp_timer_active = 1;\r
+    sys_timeout(TCP_TMR_INTERVAL, tcpip_tcp_timer, NULL);\r
+  }\r
+}\r
+#endif /* !NO_SYS */\r
+#endif /* LWIP_TCP */\r
+\r
+static void\r
+tcpip_thread(void *arg)\r
+{\r
+  struct tcpip_msg *msg;\r
+\r
+  (void)arg;\r
+\r
+  ip_init();\r
+#if LWIP_UDP  \r
+  udp_init();\r
+#endif\r
+#if LWIP_TCP\r
+  tcp_init();\r
+#endif\r
+  if (tcpip_init_done != NULL) {\r
+    tcpip_init_done(tcpip_init_done_arg);\r
+  }\r
+\r
+  while (1) {                          /* MAIN Loop */\r
+    sys_mbox_fetch(mbox, (void *)&msg);\r
+    switch (msg->type) {\r
+    case TCPIP_MSG_API:\r
+      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: API message %p\n", (void *)msg));\r
+      api_msg_input(msg->msg.apimsg);\r
+      break;\r
+    case TCPIP_MSG_INPUT:\r
+      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: IP packet %p\n", (void *)msg));\r
+      ip_input(msg->msg.inp.p, msg->msg.inp.netif);\r
+      break;\r
+    case TCPIP_MSG_CALLBACK:\r
+      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK %p\n", (void *)msg));\r
+      msg->msg.cb.f(msg->msg.cb.ctx);\r
+      break;\r
+    default:\r
+      break;\r
+    }\r
+    memp_free(MEMP_TCPIP_MSG, msg);\r
+  }\r
+}\r
+\r
+err_t\r
+tcpip_input(struct pbuf *p, struct netif *inp)\r
+{\r
+  struct tcpip_msg *msg;\r
+  \r
+  msg = memp_malloc(MEMP_TCPIP_MSG);\r
+  if (msg == NULL) {\r
+    pbuf_free(p);    \r
+    return ERR_MEM;  \r
+  }\r
+  \r
+  msg->type = TCPIP_MSG_INPUT;\r
+  msg->msg.inp.p = p;\r
+  msg->msg.inp.netif = inp;\r
+  sys_mbox_post(mbox, msg);\r
+  return ERR_OK;\r
+}\r
+\r
+err_t\r
+tcpip_callback(void (*f)(void *ctx), void *ctx)\r
+{\r
+  struct tcpip_msg *msg;\r
+  \r
+  msg = memp_malloc(MEMP_TCPIP_MSG);\r
+  if (msg == NULL) {\r
+    return ERR_MEM;  \r
+  }\r
+  \r
+  msg->type = TCPIP_MSG_CALLBACK;\r
+  msg->msg.cb.f = f;\r
+  msg->msg.cb.ctx = ctx;\r
+  sys_mbox_post(mbox, msg);\r
+  return ERR_OK;\r
+}\r
+\r
+void\r
+tcpip_apimsg(struct api_msg *apimsg)\r
+{\r
+  struct tcpip_msg *msg;\r
+  msg = memp_malloc(MEMP_TCPIP_MSG);\r
+  if (msg == NULL) {\r
+    memp_free(MEMP_API_MSG, apimsg);\r
+    return;\r
+  }\r
+  msg->type = TCPIP_MSG_API;\r
+  msg->msg.apimsg = apimsg;\r
+  sys_mbox_post(mbox, msg);\r
+}\r
+\r
+void\r
+tcpip_init(void (* initfunc)(void *), void *arg)\r
+{\r
+  tcpip_init_done = initfunc;\r
+  tcpip_init_done_arg = arg;\r
+  mbox = sys_mbox_new();\r
+  sys_thread_new(tcpip_thread, NULL, TCPIP_THREAD_PRIO);\r
+}\r
+\r
+\r
+\r
+\r
index 2a9c1887d8d331c1d028244a189c5b05a050f3bf..0caf7d0de885761568fc8cf8a929c3f69c0d4cb4 100644 (file)
-/**
- * @file
- *
- * Dynamic Host Configuration Protocol client
- */
-
-/*
- *
- * Copyright (c) 2001-2004 Leon Woestenberg <leon.woestenberg@gmx.net>
- * Copyright (c) 2001-2004 Axon Digital Design B.V., The Netherlands.
- * 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 a contribution to the lwIP TCP/IP stack.
- * The Swedish Institute of Computer Science and Adam Dunkels
- * are specifically granted permission to redistribute this
- * source code.
- *
- * Author: Leon Woestenberg <leon.woestenberg@gmx.net>
- *
- * This is a DHCP client for the lwIP TCP/IP stack. It aims to conform
- * with RFC 2131 and RFC 2132.
- *
- * TODO:
- * - Proper parsing of DHCP messages exploiting file/sname field overloading.
- * - Add JavaDoc style documentation (API, internals).
- * - Support for interfaces other than Ethernet (SLIP, PPP, ...)
- *
- * Please coordinate changes and requests with Leon Woestenberg
- * <leon.woestenberg@gmx.net>
- *
- * Integration with your code:
- *
- * In lwip/dhcp.h
- * #define DHCP_COARSE_TIMER_SECS (recommended 60 which is a minute)
- * #define DHCP_FINE_TIMER_MSECS (recommended 500 which equals TCP coarse timer)
- *
- * Then have your application call dhcp_coarse_tmr() and
- * dhcp_fine_tmr() on the defined intervals.
- *
- * dhcp_start(struct netif *netif);
- * starts a DHCP client instance which configures the interface by
- * obtaining an IP address lease and maintaining it.
- *
- * Use dhcp_release(netif) to end the lease and use dhcp_stop(netif)
- * to remove the DHCP client.
- *
- */
-#include <string.h>
-#include "lwip/stats.h"
-#include "lwip/mem.h"
-#include "lwip/udp.h"
-#include "lwip/ip_addr.h"
-#include "lwip/netif.h"
-#include "lwip/inet.h"
-#include "netif/etharp.h"
-
-#include "lwip/sys.h"
-#include "lwip/opt.h"
-#include "lwip/dhcp.h"
-
-#if LWIP_DHCP /* don't build if not configured for use in lwipopt.h */
-
-/** global transaction identifier, must be
- *  unique for each DHCP request. We simply increment, starting
- *  with this value (easy to match with a packet analyzer) */
-static u32_t xid = 0xABCD0000;
-
-/** DHCP client state machine functions */
-static void dhcp_handle_ack(struct netif *netif);
-static void dhcp_handle_nak(struct netif *netif);
-static void dhcp_handle_offer(struct netif *netif);
-
-static err_t dhcp_discover(struct netif *netif);
-static err_t dhcp_select(struct netif *netif);
-static void dhcp_check(struct netif *netif);
-static void dhcp_bind(struct netif *netif);
-static err_t dhcp_decline(struct netif *netif);
-static err_t dhcp_rebind(struct netif *netif);
-static void dhcp_set_state(struct dhcp *dhcp, unsigned char new_state);
-
-/** receive, unfold, parse and free incoming messages */
-static void dhcp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u16_t port);
-static err_t dhcp_unfold_reply(struct dhcp *dhcp);
-static u8_t *dhcp_get_option_ptr(struct dhcp *dhcp, u8_t option_type);
-static u8_t dhcp_get_option_byte(u8_t *ptr);
-static u16_t dhcp_get_option_short(u8_t *ptr);
-static u32_t dhcp_get_option_long(u8_t *ptr);
-static void dhcp_free_reply(struct dhcp *dhcp);
-
-/** set the DHCP timers */
-static void dhcp_timeout(struct netif *netif);
-static void dhcp_t1_timeout(struct netif *netif);
-static void dhcp_t2_timeout(struct netif *netif);
-
-/** build outgoing messages */
-/** create a DHCP request, fill in common headers */
-static err_t dhcp_create_request(struct netif *netif);
-/** free a DHCP request */
-static void dhcp_delete_request(struct netif *netif);
-/** add a DHCP option (type, then length in bytes) */
-static void dhcp_option(struct dhcp *dhcp, u8_t option_type, u8_t option_len);
-/** add option values */
-static void dhcp_option_byte(struct dhcp *dhcp, u8_t value);
-static void dhcp_option_short(struct dhcp *dhcp, u16_t value);
-static void dhcp_option_long(struct dhcp *dhcp, u32_t value);
-/** always add the DHCP options trailer to end and pad */
-static void dhcp_option_trailer(struct dhcp *dhcp);
-
-/**
- * Back-off the DHCP client (because of a received NAK response).
- *
- * Back-off the DHCP client because of a received NAK. Receiving a
- * NAK means the client asked for something non-sensible, for
- * example when it tries to renew a lease obtained on another network.
- *
- * We back-off and will end up restarting a fresh DHCP negotiation later.
- *
- * @param state pointer to DHCP state structure
- */
-static void dhcp_handle_nak(struct netif *netif) {
-  struct dhcp *dhcp = netif->dhcp;
-  u16_t msecs = 10 * 1000;
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_handle_nak(netif=%p) %c%c%u\n", netif,
-    netif->name[0], netif->name[1], (unsigned int)netif->num));
-  dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_handle_nak(): set request timeout %u msecs\n", msecs));
-  dhcp_set_state(dhcp, DHCP_BACKING_OFF);
-}
-
-/**
- * Checks if the offered IP address is already in use.
- *
- * It does so by sending an ARP request for the offered address and
- * entering CHECKING state. If no ARP reply is received within a small
- * interval, the address is assumed to be free for use by us.
- */
-static void dhcp_check(struct netif *netif)
-{
-  struct dhcp *dhcp = netif->dhcp;
-  err_t result;
-  u16_t msecs;
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_check(netif=%p) %c%c\n", (void *)netif, (unsigned int)netif->name[0],
-    (unsigned int)netif->name[1]));
-  /* create an ARP query for the offered IP address, expecting that no host
-     responds, as the IP address should not be in use. */
-  result = etharp_query(netif, &dhcp->offered_ip_addr, NULL);
-  if (result != ERR_OK) {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_check: could not perform ARP query\n"));
-  }
-  dhcp->tries++;
-  msecs = 500;
-  dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_check(): set request timeout %u msecs\n", msecs));
-  dhcp_set_state(dhcp, DHCP_CHECKING);
-}
-
-/**
- * Remember the configuration offered by a DHCP server.
- *
- * @param state pointer to DHCP state structure
- */
-static void dhcp_handle_offer(struct netif *netif)
-{
-  struct dhcp *dhcp = netif->dhcp;
-  /* obtain the server address */
-  u8_t *option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_SERVER_ID);
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_handle_offer(netif=%p) %c%c%u\n", netif,
-    netif->name[0], netif->name[1], netif->num));
-  if (option_ptr != NULL)
-  {
-    dhcp->server_ip_addr.addr = htonl(dhcp_get_option_long(&option_ptr[2]));
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_STATE, ("dhcp_handle_offer(): server 0x%08lx\n", dhcp->server_ip_addr.addr));
-    /* remember offered address */
-    ip_addr_set(&dhcp->offered_ip_addr, (struct ip_addr *)&dhcp->msg_in->yiaddr);
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_STATE, ("dhcp_handle_offer(): offer for 0x%08lx\n", dhcp->offered_ip_addr.addr));
-
-    dhcp_select(netif);
-  }
-}
-
-/**
- * Select a DHCP server offer out of all offers.
- *
- * Simply select the first offer received.
- *
- * @param netif the netif under DHCP control
- * @return lwIP specific error (see error.h)
- */
-static err_t dhcp_select(struct netif *netif)
-{
-  struct dhcp *dhcp = netif->dhcp;
-  err_t result;
-  u32_t msecs;
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_select(netif=%p) %c%c%u\n", netif, netif->name[0], netif->name[1], netif->num));
-
-  /* create and initialize the DHCP message header */
-  result = dhcp_create_request(netif);
-  if (result == ERR_OK)
-  {
-    dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN);
-    dhcp_option_byte(dhcp, DHCP_REQUEST);
-
-    dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
-    dhcp_option_short(dhcp, 576);
-
-    /* MUST request the offered IP address */
-    dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4);
-    dhcp_option_long(dhcp, ntohl(dhcp->offered_ip_addr.addr));
-
-    dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4);
-    dhcp_option_long(dhcp, ntohl(dhcp->server_ip_addr.addr));
-
-    dhcp_option(dhcp, DHCP_OPTION_PARAMETER_REQUEST_LIST, 4/*num options*/);
-    dhcp_option_byte(dhcp, DHCP_OPTION_SUBNET_MASK);
-    dhcp_option_byte(dhcp, DHCP_OPTION_ROUTER);
-    dhcp_option_byte(dhcp, DHCP_OPTION_BROADCAST);
-    dhcp_option_byte(dhcp, DHCP_OPTION_DNS_SERVER);
-
-    dhcp_option_trailer(dhcp);
-    /* shrink the pbuf to the actual content length */
-    pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
-
-    /* TODO: we really should bind to a specific local interface here
-       but we cannot specify an unconfigured netif as it is addressless */
-    udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);
-    /* send broadcast to any DHCP server */
-    udp_connect(dhcp->pcb, IP_ADDR_BROADCAST, DHCP_SERVER_PORT);
-    udp_send(dhcp->pcb, dhcp->p_out);
-    /* reconnect to any (or to server here?!) */
-    udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT);
-    dhcp_delete_request(netif);
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_select: REQUESTING\n"));
-    dhcp_set_state(dhcp, DHCP_REQUESTING);
-  } else {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_select: could not allocate DHCP request\n"));
-  }
-  dhcp->tries++;
-  msecs = dhcp->tries < 4 ? dhcp->tries * 1000 : 4 * 1000;
-  dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_STATE, ("dhcp_select(): set request timeout %u msecs\n", msecs));
-  return result;
-}
-
-/**
- * The DHCP timer that checks for lease renewal/rebind timeouts.
- *
- */
-void dhcp_coarse_tmr()
-{
-  struct netif *netif = netif_list;
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_coarse_tmr()\n"));
-  /* iterate through all network interfaces */
-  while (netif != NULL) {
-    /* only act on DHCP configured interfaces */
-    if (netif->dhcp != NULL) {
-      /* timer is active (non zero), and triggers (zeroes) now? */
-      if (netif->dhcp->t2_timeout-- == 1) {
-        LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_coarse_tmr(): t2 timeout\n"));
-        /* this clients' rebind timeout triggered */
-        dhcp_t2_timeout(netif);
-      /* timer is active (non zero), and triggers (zeroes) now */
-      } else if (netif->dhcp->t1_timeout-- == 1) {
-        LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_coarse_tmr(): t1 timeout\n"));
-        /* this clients' renewal timeout triggered */
-        dhcp_t1_timeout(netif);
-      }
-    }
-    /* proceed to next netif */
-    netif = netif->next;
-  }
-}
-
-/**
- * DHCP transaction timeout handling
- *
- * A DHCP server is expected to respond within a short period of time.
- * This timer checks whether an outstanding DHCP request is timed out.
- * 
- */
-void dhcp_fine_tmr()
-{
-  struct netif *netif = netif_list;
-  /* loop through netif's */
-  while (netif != NULL) {
-    /* only act on DHCP configured interfaces */
-    if (netif->dhcp != NULL) {
-      /* timer is active (non zero), and is about to trigger now */
-      if (netif->dhcp->request_timeout-- == 1) {
-        /* { netif->dhcp->request_timeout == 0 } */
-        LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_fine_tmr(): request timeout\n"));
-        /* this clients' request timeout triggered */
-        dhcp_timeout(netif);
-      }
-    }
-    /* proceed to next network interface */
-    netif = netif->next;
-  }
-}
-
-/**
- * A DHCP negotiation transaction, or ARP request, has timed out.
- *
- * The timer that was started with the DHCP or ARP request has
- * timed out, indicating no response was received in time.
- *
- * @param netif the netif under DHCP control
- *
- */
-static void dhcp_timeout(struct netif *netif)
-{
-  struct dhcp *dhcp = netif->dhcp;
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_timeout()\n"));
-  /* back-off period has passed, or server selection timed out */
-  if ((dhcp->state == DHCP_BACKING_OFF) || (dhcp->state == DHCP_SELECTING)) {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_timeout(): restarting discovery\n"));
-    dhcp_discover(netif);
-  /* receiving the requested lease timed out */
-  } else if (dhcp->state == DHCP_REQUESTING) {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_timeout(): REQUESTING, DHCP request timed out\n"));
-    if (dhcp->tries <= 5) {
-      dhcp_select(netif);
-    } else {
-      LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_timeout(): REQUESTING, releasing, restarting\n"));
-      dhcp_release(netif);
-      dhcp_discover(netif);
-    }
-  /* received no ARP reply for the offered address (which is good) */
-  } else if (dhcp->state == DHCP_CHECKING) {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_timeout(): CHECKING, ARP request timed out\n"));
-    if (dhcp->tries <= 1) {
-      dhcp_check(netif);
-    /* no ARP replies on the offered address,
-       looks like the IP address is indeed free */
-    } else {
-      /* bind the interface to the offered address */
-      dhcp_bind(netif);
-    }
-  }
-  /* did not get response to renew request? */
-  else if (dhcp->state == DHCP_RENEWING) {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_timeout(): RENEWING, DHCP request timed out\n"));
-    /* just retry renewal */
-    /* note that the rebind timer will eventually time-out if renew does not work */
-    dhcp_renew(netif);
-  /* did not get response to rebind request? */
-  } else if (dhcp->state == DHCP_REBINDING) {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_timeout(): REBINDING, DHCP request timed out\n"));
-    if (dhcp->tries <= 8) {
-      dhcp_rebind(netif);
-    } else {
-      LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_timeout(): RELEASING, DISCOVERING\n"));
-      dhcp_release(netif);
-      dhcp_discover(netif);
-    }
-  }
-}
-
-/**
- * The renewal period has timed out.
- *
- * @param netif the netif under DHCP control
- */
-static void dhcp_t1_timeout(struct netif *netif)
-{
-  struct dhcp *dhcp = netif->dhcp;
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_STATE, ("dhcp_t1_timeout()\n"));
-  if ((dhcp->state == DHCP_REQUESTING) || (dhcp->state == DHCP_BOUND) || (dhcp->state == DHCP_RENEWING)) {
-    /* just retry to renew - note that the rebind timer (t2) will
-     * eventually time-out if renew tries fail. */
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_t1_timeout(): must renew\n"));
-    dhcp_renew(netif);
-  }
-}
-
-/**
- * The rebind period has timed out.
- *
- */
-static void dhcp_t2_timeout(struct netif *netif)
-{
-  struct dhcp *dhcp = netif->dhcp;
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_t2_timeout()\n"));
-  if ((dhcp->state == DHCP_REQUESTING) || (dhcp->state == DHCP_BOUND) || (dhcp->state == DHCP_RENEWING)) {
-    /* just retry to rebind */
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_t2_timeout(): must rebind\n"));
-    dhcp_rebind(netif);
-  }
-}
-
-/**
- *
- * @param netif the netif under DHCP control
- */
-static void dhcp_handle_ack(struct netif *netif)
-{
-  struct dhcp *dhcp = netif->dhcp;
-  u8_t *option_ptr;
-  /* clear options we might not get from the ACK */
-  dhcp->offered_sn_mask.addr = 0;
-  dhcp->offered_gw_addr.addr = 0;
-  dhcp->offered_bc_addr.addr = 0;
-
-  /* lease time given? */
-  option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_LEASE_TIME);
-  if (option_ptr != NULL) {
-    /* remember offered lease time */
-    dhcp->offered_t0_lease = dhcp_get_option_long(option_ptr + 2);
-  }
-  /* renewal period given? */
-  option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_T1);
-  if (option_ptr != NULL) {
-    /* remember given renewal period */
-    dhcp->offered_t1_renew = dhcp_get_option_long(option_ptr + 2);
-  } else {
-    /* calculate safe periods for renewal */
-    dhcp->offered_t1_renew = dhcp->offered_t0_lease / 2;
-  }
-
-  /* renewal period given? */
-  option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_T2);
-  if (option_ptr != NULL) {
-    /* remember given rebind period */
-    dhcp->offered_t2_rebind = dhcp_get_option_long(option_ptr + 2);
-  } else {
-    /* calculate safe periods for rebinding */
-    dhcp->offered_t2_rebind = dhcp->offered_t0_lease;
-  }
-
-  /* (y)our internet address */
-  ip_addr_set(&dhcp->offered_ip_addr, &dhcp->msg_in->yiaddr);
-
-/**
- * Patch #1308
- * TODO: we must check if the file field is not overloaded by DHCP options!
- */
-#if 0
-  /* boot server address */
-  ip_addr_set(&dhcp->offered_si_addr, &dhcp->msg_in->siaddr);
-  /* boot file name */
-  if (dhcp->msg_in->file[0]) {
-    dhcp->boot_file_name = mem_malloc(strlen(dhcp->msg_in->file) + 1);
-    strcpy(dhcp->boot_file_name, dhcp->msg_in->file);
-  }
-#endif
-
-  /* subnet mask */
-  option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_SUBNET_MASK);
-  /* subnet mask given? */
-  if (option_ptr != NULL) {
-    dhcp->offered_sn_mask.addr = htonl(dhcp_get_option_long(&option_ptr[2]));
-  }
-
-  /* gateway router */
-  option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_ROUTER);
-  if (option_ptr != NULL) {
-    dhcp->offered_gw_addr.addr = htonl(dhcp_get_option_long(&option_ptr[2]));
-  }
-
-  /* broadcast address */
-  option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_BROADCAST);
-  if (option_ptr != NULL) {
-    dhcp->offered_bc_addr.addr = htonl(dhcp_get_option_long(&option_ptr[2]));
-  }
-  
-  /* DNS servers */
-  option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_DNS_SERVER);
-  if (option_ptr != NULL) {
-    u8_t n;
-    dhcp->dns_count = dhcp_get_option_byte(&option_ptr[1]);
-    /* limit to at most DHCP_MAX_DNS DNS servers */
-    if (dhcp->dns_count > DHCP_MAX_DNS) dhcp->dns_count = DHCP_MAX_DNS;
-    for (n = 0; n < dhcp->dns_count; n++)
-    {
-      dhcp->offered_dns_addr[n].addr = htonl(dhcp_get_option_long(&option_ptr[2+(n<<2)]));
-    }
-  }
-}
-
-/**
- * Start DHCP negotiation for a network interface.
- *
- * If no DHCP client instance was attached to this interface,
- * a new client is created first. If a DHCP client instance
- * was already present, it restarts negotiation.
- *
- * @param netif The lwIP network interface
- * @return lwIP error code
- * - ERR_OK - No error
- * - ERR_MEM - Out of memory
- *
- */
-err_t dhcp_start(struct netif *netif)
-{
-  struct dhcp *dhcp = netif->dhcp;
-  err_t result = ERR_OK;
-
-  LWIP_ASSERT("netif != NULL", netif != NULL);
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_start(netif=%p) %c%c%u\n", netif, netif->name[0], netif->name[1], netif->num));
-  netif->flags &= ~NETIF_FLAG_DHCP;
-
-  /* no DHCP client attached yet? */
-  if (dhcp == NULL) {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_start(): starting new DHCP client\n"));
-    dhcp = mem_malloc(sizeof(struct dhcp));
-    if (dhcp == NULL) {
-      LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_start(): could not allocate dhcp\n"));
-      return ERR_MEM;
-    }
-    /* store this dhcp client in the netif */
-    netif->dhcp = dhcp;
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_start(): allocated dhcp"));
-  /* already has DHCP client attached */
-  } else {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE | 3, ("dhcp_start(): restarting DHCP configuration\n"));
-  }
-       
-       /* clear data structure */
-       memset(dhcp, 0, sizeof(struct dhcp));
-  /* allocate UDP PCB */
-       dhcp->pcb = udp_new();
-       if (dhcp->pcb == NULL) {
-         LWIP_DEBUGF(DHCP_DEBUG  | DBG_TRACE, ("dhcp_start(): could not obtain pcb\n"));
-         mem_free((void *)dhcp);
-         netif->dhcp = dhcp = NULL;
-         return ERR_MEM;
-       }
-       LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_start(): starting DHCP configuration\n"));
-  /* (re)start the DHCP negotiation */
-  result = dhcp_discover(netif);
-  if (result != ERR_OK) {
-    /* free resources allocated above */
-    dhcp_stop(netif);
-    return ERR_MEM;
-  }
-  netif->flags |= NETIF_FLAG_DHCP;
-  return result;
-}
-
-/**
- * Inform a DHCP server of our manual configuration.
- *
- * This informs DHCP servers of our fixed IP address configuration
- * by sending an INFORM message. It does not involve DHCP address
- * configuration, it is just here to be nice to the network.
- *
- * @param netif The lwIP network interface
- *
- */
-void dhcp_inform(struct netif *netif)
-{
-  struct dhcp *dhcp;
-  err_t result = ERR_OK;
-  dhcp = mem_malloc(sizeof(struct dhcp));
-  if (dhcp == NULL) {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_inform(): could not allocate dhcp\n"));
-    return;
-  }
-  netif->dhcp = dhcp;
-  memset(dhcp, 0, sizeof(struct dhcp));
-
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_inform(): allocated dhcp\n"));
-  dhcp->pcb = udp_new();
-  if (dhcp->pcb == NULL) {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_inform(): could not obtain pcb"));
-    mem_free((void *)dhcp);
-    return;
-  }
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_inform(): created new udp pcb\n"));
-  /* create and initialize the DHCP message header */
-  result = dhcp_create_request(netif);
-  if (result == ERR_OK) {
-
-    dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN);
-    dhcp_option_byte(dhcp, DHCP_INFORM);
-
-    dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
-    /* TODO: use netif->mtu ?! */
-    dhcp_option_short(dhcp, 576);
-
-    dhcp_option_trailer(dhcp);
-
-    pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
-
-    udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);
-    udp_connect(dhcp->pcb, IP_ADDR_BROADCAST, DHCP_SERVER_PORT);
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_inform: INFORMING\n"));
-    udp_send(dhcp->pcb, dhcp->p_out);
-    udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT);
-    dhcp_delete_request(netif);
-  } else {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_inform: could not allocate DHCP request\n"));
-  }
-
-  if (dhcp != NULL)
-  {
-    if (dhcp->pcb != NULL) udp_remove(dhcp->pcb);
-    dhcp->pcb = NULL;
-    mem_free((void *)dhcp);
-    netif->dhcp = NULL;
-  }
-}
-
-#if DHCP_DOES_ARP_CHECK
-/**
- * Match an ARP reply with the offered IP address.
- *
- * @param addr The IP address we received a reply from
- *
- */
-void dhcp_arp_reply(struct netif *netif, struct ip_addr *addr)
-{
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_arp_reply()\n"));
-  /* is this DHCP client doing an ARP check? */
-  if ((netif->dhcp != NULL) && (netif->dhcp->state == DHCP_CHECKING)) {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_arp_reply(): CHECKING, arp reply for 0x%08lx\n", addr->addr));
-    /* did a host respond with the address we
-       were offered by the DHCP server? */
-    if (ip_addr_cmp(addr, &netif->dhcp->offered_ip_addr)) {
-      /* we will not accept the offered address */
-      LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE | 1, ("dhcp_arp_reply(): arp reply matched with offered address, declining\n"));
-      dhcp_decline(netif);
-    }
-  }
-}
-
-/**
- * Decline an offered lease.
- *
- * Tell the DHCP server we do not accept the offered address.
- * One reason to decline the lease is when we find out the address
- * is already in use by another host (through ARP).
- */
-static err_t dhcp_decline(struct netif *netif)
-{
-  struct dhcp *dhcp = netif->dhcp;
-  err_t result = ERR_OK;
-  u16_t msecs;
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_decline()\n"));
-  dhcp_set_state(dhcp, DHCP_BACKING_OFF);
-  /* create and initialize the DHCP message header */
-  result = dhcp_create_request(netif);
-  if (result == ERR_OK)
-  {
-    dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN);
-    dhcp_option_byte(dhcp, DHCP_DECLINE);
-
-    dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
-    dhcp_option_short(dhcp, 576);
-
-    dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4);
-    dhcp_option_long(dhcp, ntohl(dhcp->offered_ip_addr.addr));
-
-    dhcp_option_trailer(dhcp);
-    /* resize pbuf to reflect true size of options */
-    pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
-
-    udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);
-    /* @todo: should we really connect here? we are performing sendto() */
-    udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT);
-    /* per section 4.4.4, broadcast DECLINE messages */
-    udp_sendto(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT);
-    dhcp_delete_request(netif);
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_decline: BACKING OFF\n"));
-  } else {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_decline: could not allocate DHCP request\n"));
-  }
-  dhcp->tries++;
-  msecs = 10*1000;
-  dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
-   LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_decline(): set request timeout %u msecs\n", msecs));
-  return result;
-}
-#endif
-
-
-/**
- * Start the DHCP process, discover a DHCP server.
- *
- */
-static err_t dhcp_discover(struct netif *netif)
-{
-  struct dhcp *dhcp = netif->dhcp;
-  err_t result = ERR_OK;
-  u16_t msecs;
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_discover()\n"));
-  ip_addr_set(&dhcp->offered_ip_addr, IP_ADDR_ANY);
-  /* create and initialize the DHCP message header */
-  result = dhcp_create_request(netif);
-  if (result == ERR_OK)
-  {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_discover: making request\n"));
-    dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN);
-    dhcp_option_byte(dhcp, DHCP_DISCOVER);
-
-    dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
-    dhcp_option_short(dhcp, 576);
-
-    dhcp_option(dhcp, DHCP_OPTION_PARAMETER_REQUEST_LIST, 4/*num options*/);
-    dhcp_option_byte(dhcp, DHCP_OPTION_SUBNET_MASK);
-    dhcp_option_byte(dhcp, DHCP_OPTION_ROUTER);
-    dhcp_option_byte(dhcp, DHCP_OPTION_BROADCAST);
-    dhcp_option_byte(dhcp, DHCP_OPTION_DNS_SERVER);
-
-    dhcp_option_trailer(dhcp);
-
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_discover: realloc()ing\n"));
-    pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
-
-    /* set receive callback function with netif as user data */
-    udp_recv(dhcp->pcb, dhcp_recv, netif);
-    udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);
-    udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT);
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_discover: sendto(DISCOVER, IP_ADDR_BROADCAST, DHCP_SERVER_PORT)\n"));
-    udp_sendto(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT);
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_discover: deleting()ing\n"));
-    dhcp_delete_request(netif);
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_discover: SELECTING\n"));
-    dhcp_set_state(dhcp, DHCP_SELECTING);
-  } else {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_discover: could not allocate DHCP request\n"));
-  }
-  dhcp->tries++;
-  msecs = dhcp->tries < 4 ? (dhcp->tries + 1) * 1000 : 10 * 1000;
-  dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_discover(): set request timeout %u msecs\n", msecs));
-  return result;
-}
-
-
-/**
- * Bind the interface to the offered IP address.
- *
- * @param netif network interface to bind to the offered address
- */
-static void dhcp_bind(struct netif *netif)
-{
-  struct dhcp *dhcp = netif->dhcp;
-  struct ip_addr sn_mask, gw_addr;
-  LWIP_ASSERT("dhcp_bind: netif != NULL", netif != NULL);
-  LWIP_ASSERT("dhcp_bind: dhcp != NULL", dhcp != NULL);
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_bind(netif=%p) %c%c%u\n", netif, netif->name[0], netif->name[1], netif->num));
-
-  /* temporary DHCP lease? */
-  if (dhcp->offered_t1_renew != 0xffffffffUL) {
-    /* set renewal period timer */
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_bind(): t1 renewal timer %lu secs\n", dhcp->offered_t1_renew));
-    dhcp->t1_timeout = (dhcp->offered_t1_renew + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS;
-    if (dhcp->t1_timeout == 0) dhcp->t1_timeout = 1;
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_bind(): set request timeout %u msecs\n", dhcp->offered_t1_renew*1000));
-  }
-  /* set renewal period timer */
-  if (dhcp->offered_t2_rebind != 0xffffffffUL) {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_bind(): t2 rebind timer %lu secs\n", dhcp->offered_t2_rebind));
-    dhcp->t2_timeout = (dhcp->offered_t2_rebind + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS;
-    if (dhcp->t2_timeout == 0) dhcp->t2_timeout = 1;
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_bind(): set request timeout %u msecs\n", dhcp->offered_t2_rebind*1000));
-  }
-  /* copy offered network mask */
-  ip_addr_set(&sn_mask, &dhcp->offered_sn_mask);
-
-  /* subnet mask not given? */
-  /* TODO: this is not a valid check. what if the network mask is 0? */
-  if (sn_mask.addr == 0) {
-    /* choose a safe subnet mask given the network class */
-    u8_t first_octet = ip4_addr1(&sn_mask);
-    if (first_octet <= 127) sn_mask.addr = htonl(0xff000000);
-    else if (first_octet >= 192) sn_mask.addr = htonl(0xffffff00);
-    else sn_mask.addr = htonl(0xffff0000);
-  }
-
-  ip_addr_set(&gw_addr, &dhcp->offered_gw_addr);
-  /* gateway address not given? */
-  if (gw_addr.addr == 0) {
-    /* copy network address */
-    gw_addr.addr = (dhcp->offered_ip_addr.addr & sn_mask.addr);
-    /* use first host address on network as gateway */
-    gw_addr.addr |= htonl(0x00000001);
-  }
-
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_STATE, ("dhcp_bind(): IP: 0x%08lx\n", dhcp->offered_ip_addr.addr));
-  netif_set_ipaddr(netif, &dhcp->offered_ip_addr);
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_STATE, ("dhcp_bind(): SN: 0x%08lx\n", sn_mask.addr));
-  netif_set_netmask(netif, &sn_mask);
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_STATE, ("dhcp_bind(): GW: 0x%08lx\n", gw_addr.addr));
-  netif_set_gw(netif, &gw_addr);
-  /* bring the interface up */
-  netif_set_up(netif);
-  /* netif is now bound to DHCP leased address */
-  dhcp_set_state(dhcp, DHCP_BOUND);
-}
-
-/**
- * Renew an existing DHCP lease at the involved DHCP server.
- *
- * @param netif network interface which must renew its lease
- */
-err_t dhcp_renew(struct netif *netif)
-{
-  struct dhcp *dhcp = netif->dhcp;
-  err_t result;
-  u16_t msecs;
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_renew()\n"));
-  dhcp_set_state(dhcp, DHCP_RENEWING);
-
-  /* create and initialize the DHCP message header */
-  result = dhcp_create_request(netif);
-  if (result == ERR_OK) {
-
-    dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN);
-    dhcp_option_byte(dhcp, DHCP_REQUEST);
-
-    dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
-    /* TODO: use netif->mtu in some way */
-    dhcp_option_short(dhcp, 576);
-
-#if 0
-    dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4);
-    dhcp_option_long(dhcp, ntohl(dhcp->offered_ip_addr.addr));
-#endif
-
-#if 0
-    dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4);
-    dhcp_option_long(dhcp, ntohl(dhcp->server_ip_addr.addr));
-#endif
-    /* append DHCP message trailer */
-    dhcp_option_trailer(dhcp);
-
-    pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
-
-    udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);
-    udp_connect(dhcp->pcb, &dhcp->server_ip_addr, DHCP_SERVER_PORT);
-    udp_send(dhcp->pcb, dhcp->p_out);
-    dhcp_delete_request(netif);
-
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_renew: RENEWING\n"));
-  } else {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_renew: could not allocate DHCP request\n"));
-  }
-  dhcp->tries++;
-  /* back-off on retries, but to a maximum of 20 seconds */
-  msecs = dhcp->tries < 10 ? dhcp->tries * 2000 : 20 * 1000;
-  dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
-   LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_renew(): set request timeout %u msecs\n", msecs));
-  return result;
-}
-
-/**
- * Rebind with a DHCP server for an existing DHCP lease.
- *
- * @param netif network interface which must rebind with a DHCP server
- */
-static err_t dhcp_rebind(struct netif *netif)
-{
-  struct dhcp *dhcp = netif->dhcp;
-  err_t result;
-  u16_t msecs;
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_rebind()\n"));
-  dhcp_set_state(dhcp, DHCP_REBINDING);
-
-  /* create and initialize the DHCP message header */
-  result = dhcp_create_request(netif);
-  if (result == ERR_OK)
-  {
-
-    dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN);
-    dhcp_option_byte(dhcp, DHCP_REQUEST);
-
-    dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
-    dhcp_option_short(dhcp, 576);
-
-#if 0
-    dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4);
-    dhcp_option_long(dhcp, ntohl(dhcp->offered_ip_addr.addr));
-
-    dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4);
-    dhcp_option_long(dhcp, ntohl(dhcp->server_ip_addr.addr));
-#endif
-
-    dhcp_option_trailer(dhcp);
-
-    pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
-
-    /* set remote IP association to any DHCP server */
-    udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);
-    udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT);
-    /* broadcast to server */
-    udp_sendto(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT);
-    dhcp_delete_request(netif);
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_rebind: REBINDING\n"));
-  } else {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_rebind: could not allocate DHCP request\n"));
-  }
-  dhcp->tries++;
-  msecs = dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000;
-  dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
-   LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_rebind(): set request timeout %u msecs\n", msecs));
-  return result;
-}
-
-/**
- * Release a DHCP lease.
- *
- * @param netif network interface which must release its lease
- */
-err_t dhcp_release(struct netif *netif)
-{
-  struct dhcp *dhcp = netif->dhcp;
-  err_t result;
-  u16_t msecs;
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_release()\n"));
-
-  /* idle DHCP client */
-  dhcp_set_state(dhcp, DHCP_OFF);
-  /* clean old DHCP offer */
-  dhcp->server_ip_addr.addr = 0;
-  dhcp->offered_ip_addr.addr = dhcp->offered_sn_mask.addr = 0;
-  dhcp->offered_gw_addr.addr = dhcp->offered_bc_addr.addr = 0;
-  dhcp->offered_t0_lease = dhcp->offered_t1_renew = dhcp->offered_t2_rebind = 0;
-  dhcp->dns_count = 0;
-  
-  /* create and initialize the DHCP message header */
-  result = dhcp_create_request(netif);
-  if (result == ERR_OK) {
-    dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN);
-    dhcp_option_byte(dhcp, DHCP_RELEASE);
-
-    dhcp_option_trailer(dhcp);
-
-    pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
-
-    udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);
-    udp_connect(dhcp->pcb, &dhcp->server_ip_addr, DHCP_SERVER_PORT);
-    udp_send(dhcp->pcb, dhcp->p_out);
-    dhcp_delete_request(netif);
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_release: RELEASED, DHCP_OFF\n"));
-  } else {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_release: could not allocate DHCP request\n"));
-  }
-  dhcp->tries++;
-  msecs = dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000;
-  dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_release(): set request timeout %u msecs\n", msecs));
-  /* bring the interface down */
-  netif_set_down(netif);
-  /* remove IP address from interface */
-  netif_set_ipaddr(netif, IP_ADDR_ANY);
-  netif_set_gw(netif, IP_ADDR_ANY);
-  netif_set_netmask(netif, IP_ADDR_ANY);
-  
-  /* TODO: netif_down(netif); */
-  return result;
-}
-/**
- * Remove the DHCP client from the interface.
- *
- * @param netif The network interface to stop DHCP on
- */
-void dhcp_stop(struct netif *netif)
-{
-  struct dhcp *dhcp = netif->dhcp;
-  LWIP_ASSERT("dhcp_stop: netif != NULL", netif != NULL);
-
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_stop()\n"));
-  /* netif is DHCP configured? */
-  if (dhcp != NULL)
-  {
-    if (dhcp->pcb != NULL)
-    {
-      udp_remove(dhcp->pcb);
-      dhcp->pcb = NULL;
-    }
-    if (dhcp->p != NULL)
-    {
-      pbuf_free(dhcp->p);
-      dhcp->p = NULL;
-    }
-    /* free unfolded reply */
-    dhcp_free_reply(dhcp);
-    mem_free((void *)dhcp);
-    netif->dhcp = NULL;
-  }
-}
-
-/*
- * Set the DHCP state of a DHCP client.
- *
- * If the state changed, reset the number of tries.
- *
- * TODO: we might also want to reset the timeout here?
- */
-static void dhcp_set_state(struct dhcp *dhcp, unsigned char new_state)
-{
-  if (new_state != dhcp->state)
-  {
-    dhcp->state = new_state;
-    dhcp->tries = 0;
-  }
-}
-
-/*
- * Concatenate an option type and length field to the outgoing
- * DHCP message.
- *
- */
-static void dhcp_option(struct dhcp *dhcp, u8_t option_type, u8_t option_len)
-{
-  LWIP_ASSERT("dhcp_option_short: dhcp->options_out_len + 2 + option_len <= DHCP_OPTIONS_LEN", dhcp->options_out_len + 2 + option_len <= DHCP_OPTIONS_LEN);
-  dhcp->msg_out->options[dhcp->options_out_len++] = option_type;
-  dhcp->msg_out->options[dhcp->options_out_len++] = option_len;
-}
-/*
- * Concatenate a single byte to the outgoing DHCP message.
- *
- */
-static void dhcp_option_byte(struct dhcp *dhcp, u8_t value)
-{
-  LWIP_ASSERT("dhcp_option_short: dhcp->options_out_len < DHCP_OPTIONS_LEN", dhcp->options_out_len < DHCP_OPTIONS_LEN);
-  dhcp->msg_out->options[dhcp->options_out_len++] = value;
-}
-static void dhcp_option_short(struct dhcp *dhcp, u16_t value)
-{
-  LWIP_ASSERT("dhcp_option_short: dhcp->options_out_len + 2 <= DHCP_OPTIONS_LEN", dhcp->options_out_len + 2 <= DHCP_OPTIONS_LEN);
-  dhcp->msg_out->options[dhcp->options_out_len++] = (value & 0xff00U) >> 8;
-  dhcp->msg_out->options[dhcp->options_out_len++] =  value & 0x00ffU;
-}
-static void dhcp_option_long(struct dhcp *dhcp, u32_t value)
-{
-  LWIP_ASSERT("dhcp_option_long: dhcp->options_out_len + 4 <= DHCP_OPTIONS_LEN", dhcp->options_out_len + 4 <= DHCP_OPTIONS_LEN);
-  dhcp->msg_out->options[dhcp->options_out_len++] = (value & 0xff000000UL) >> 24;
-  dhcp->msg_out->options[dhcp->options_out_len++] = (value & 0x00ff0000UL) >> 16;
-  dhcp->msg_out->options[dhcp->options_out_len++] = (value & 0x0000ff00UL) >> 8;
-  dhcp->msg_out->options[dhcp->options_out_len++] = (value & 0x000000ffUL);
-}
-
-/**
- * Extract the DHCP message and the DHCP options.
- *
- * Extract the DHCP message and the DHCP options, each into a contiguous
- * piece of memory. As a DHCP message is variable sized by its options,
- * and also allows overriding some fields for options, the easy approach
- * is to first unfold the options into a conitguous piece of memory, and
- * use that further on.
- *
- */
-static err_t dhcp_unfold_reply(struct dhcp *dhcp)
-{
-  struct pbuf *p = dhcp->p;
-  u8_t *ptr;
-  u16_t i;
-  u16_t j = 0;
-  LWIP_ASSERT("dhcp->p != NULL", dhcp->p != NULL);
-  /* free any left-overs from previous unfolds */
-  dhcp_free_reply(dhcp);
-  /* options present? */
-  if (dhcp->p->tot_len > (sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN))
-  {
-    dhcp->options_in_len = dhcp->p->tot_len - (sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN);
-    dhcp->options_in = mem_malloc(dhcp->options_in_len);
-    if (dhcp->options_in == NULL)
-    {
-      LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_unfold_reply(): could not allocate dhcp->options\n"));
-      return ERR_MEM;
-    }
-  }
-  dhcp->msg_in = mem_malloc(sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN);
-  if (dhcp->msg_in == NULL)
-  {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_unfold_reply(): could not allocate dhcp->msg_in\n"));
-    mem_free((void *)dhcp->options_in);
-    dhcp->options_in = NULL;
-    return ERR_MEM;
-  }
-
-  ptr = (u8_t *)dhcp->msg_in;
-  /* proceed through struct dhcp_msg */
-  for (i = 0; i < sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN; i++)
-  {
-    *ptr++ = ((u8_t *)p->payload)[j++];
-    /* reached end of pbuf? */
-    if (j == p->len)
-    {
-      /* proceed to next pbuf in chain */
-      p = p->next;
-      j = 0;
-    }
-  }
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_unfold_reply(): copied %u bytes into dhcp->msg_in[]\n", i));
-  if (dhcp->options_in != NULL) {
-    ptr = (u8_t *)dhcp->options_in;
-    /* proceed through options */
-    for (i = 0; i < dhcp->options_in_len; i++) {
-      *ptr++ = ((u8_t *)p->payload)[j++];
-      /* reached end of pbuf? */
-      if (j == p->len) {
-        /* proceed to next pbuf in chain */
-        p = p->next;
-        j = 0;
-      }
-    }
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_unfold_reply(): copied %u bytes to dhcp->options_in[]\n", i));
-  }
-  return ERR_OK;
-}
-
-/**
- * Free the incoming DHCP message including contiguous copy of
- * its DHCP options.
- *
- */
-static void dhcp_free_reply(struct dhcp *dhcp)
-{
-  if (dhcp->msg_in != NULL) {
-    mem_free((void *)dhcp->msg_in);
-    dhcp->msg_in = NULL;
-  }
-  if (dhcp->options_in) {
-    mem_free((void *)dhcp->options_in);
-    dhcp->options_in = NULL;
-    dhcp->options_in_len = 0;
-  }
-  LWIP_DEBUGF(DHCP_DEBUG, ("dhcp_free_reply(): free'd\n"));
-}
-
-
-/**
- * If an incoming DHCP message is in response to us, then trigger the state machine
- */
-static void dhcp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u16_t port)
-{
-  struct netif *netif = (struct netif *)arg;
-  struct dhcp *dhcp = netif->dhcp;
-  struct dhcp_msg *reply_msg = (struct dhcp_msg *)p->payload;
-  u8_t *options_ptr;
-  u8_t msg_type;
-  u8_t i;
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_recv(pbuf = %p) from DHCP server %u.%u.%u.%u port %u\n", p,
-    (unsigned int)(ntohl(addr->addr) >> 24 & 0xff), (unsigned int)(ntohl(addr->addr) >> 16 & 0xff),
-    (unsigned int)(ntohl(addr->addr) >>  8 & 0xff), (unsigned int)(ntohl(addr->addr) & 0xff), port));
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("pbuf->len = %u\n", p->len));
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("pbuf->tot_len = %u\n", p->tot_len));
-  /* prevent warnings about unused arguments */
-  (void)pcb; (void)addr; (void)port;
-  dhcp->p = p;
-  /* TODO: check packet length before reading them */
-  if (reply_msg->op != DHCP_BOOTREPLY) {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 1, ("not a DHCP reply message, but type %u\n", reply_msg->op));
-    pbuf_free(p);
-    dhcp->p = NULL;
-    return;
-  }
-  /* iterate through hardware address and match against DHCP message */
-  for (i = 0; i < netif->hwaddr_len; i++) {
-    if (netif->hwaddr[i] != reply_msg->chaddr[i]) {
-      LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("netif->hwaddr[%u]==%02x != reply_msg->chaddr[%u]==%02x\n",
-        i, netif->hwaddr[i], i, reply_msg->chaddr[i]));
-      pbuf_free(p);
-      dhcp->p = NULL;
-      return;
-    }
-  }
-  /* match transaction ID against what we expected */
-  if (ntohl(reply_msg->xid) != dhcp->xid) {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("transaction id mismatch\n"));
-    pbuf_free(p);
-    dhcp->p = NULL;
-    return;
-  }
-  /* option fields could be unfold? */
-  if (dhcp_unfold_reply(dhcp) != ERR_OK) {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("problem unfolding DHCP message - too short on memory?\n"));
-    pbuf_free(p);
-    dhcp->p = NULL;
-    return;
-  }
-
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("searching DHCP_OPTION_MESSAGE_TYPE\n"));
-  /* obtain pointer to DHCP message type */
-  options_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_MESSAGE_TYPE);
-  if (options_ptr == NULL) {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 1, ("DHCP_OPTION_MESSAGE_TYPE option not found\n"));
-    pbuf_free(p);
-    dhcp->p = NULL;
-    return;
-  }
-
-  /* read DHCP message type */
-  msg_type = dhcp_get_option_byte(options_ptr + 2);
-  /* message type is DHCP ACK? */
-  if (msg_type == DHCP_ACK) {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 1, ("DHCP_ACK received\n"));
-    /* in requesting state? */
-    if (dhcp->state == DHCP_REQUESTING) {
-      dhcp_handle_ack(netif);
-      dhcp->request_timeout = 0;
-#if DHCP_DOES_ARP_CHECK
-      /* check if the acknowledged lease address is already in use */
-      dhcp_check(netif);
-#else
-      /* bind interface to the acknowledged lease address */
-      dhcp_bind(netif);
-#endif
-    }
-    /* already bound to the given lease address? */
-    else if ((dhcp->state == DHCP_REBOOTING) || (dhcp->state == DHCP_REBINDING) || (dhcp->state == DHCP_RENEWING)) {
-      dhcp->request_timeout = 0;
-      dhcp_bind(netif);
-    }
-  }
-  /* received a DHCP_NAK in appropriate state? */
-  else if ((msg_type == DHCP_NAK) &&
-    ((dhcp->state == DHCP_REBOOTING) || (dhcp->state == DHCP_REQUESTING) ||
-     (dhcp->state == DHCP_REBINDING) || (dhcp->state == DHCP_RENEWING  ))) {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 1, ("DHCP_NAK received\n"));
-    dhcp->request_timeout = 0;
-    dhcp_handle_nak(netif);
-  }
-  /* received a DHCP_OFFER in DHCP_SELECTING state? */
-  else if ((msg_type == DHCP_OFFER) && (dhcp->state == DHCP_SELECTING)) {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 1, ("DHCP_OFFER received in DHCP_SELECTING state\n"));
-    dhcp->request_timeout = 0;
-    /* remember offered lease */
-    dhcp_handle_offer(netif);
-  }
-  pbuf_free(p);
-  dhcp->p = NULL;
-}
-
-
-static err_t dhcp_create_request(struct netif *netif)
-{
-  struct dhcp *dhcp = netif->dhcp;
-  u16_t i;
-  LWIP_ASSERT("dhcp_create_request: dhcp->p_out == NULL", dhcp->p_out == NULL);
-  LWIP_ASSERT("dhcp_create_request: dhcp->msg_out == NULL", dhcp->msg_out == NULL);
-  dhcp->p_out = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct dhcp_msg), PBUF_RAM);
-  if (dhcp->p_out == NULL) {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_create_request(): could not allocate pbuf\n"));
-    return ERR_MEM;
-  }
-  /* give unique transaction identifier to this request */
-  dhcp->xid = xid++;
-
-  dhcp->msg_out = (struct dhcp_msg *)dhcp->p_out->payload;
-
-  dhcp->msg_out->op = DHCP_BOOTREQUEST;
-  /* TODO: make link layer independent */
-  dhcp->msg_out->htype = DHCP_HTYPE_ETH;
-  /* TODO: make link layer independent */
-  dhcp->msg_out->hlen = DHCP_HLEN_ETH;
-  dhcp->msg_out->hops = 0;
-  dhcp->msg_out->xid = htonl(dhcp->xid);
-  dhcp->msg_out->secs = 0;
-  dhcp->msg_out->flags = 0;
-  dhcp->msg_out->ciaddr.addr = netif->ip_addr.addr;
-  dhcp->msg_out->yiaddr.addr = 0;
-  dhcp->msg_out->siaddr.addr = 0;
-  dhcp->msg_out->giaddr.addr = 0;
-  for (i = 0; i < DHCP_CHADDR_LEN; i++) {
-    /* copy netif hardware address, pad with zeroes */
-    dhcp->msg_out->chaddr[i] = (i < netif->hwaddr_len) ? netif->hwaddr[i] : 0/* pad byte*/;
-  }
-  for (i = 0; i < DHCP_SNAME_LEN; i++) dhcp->msg_out->sname[i] = 0;
-  for (i = 0; i < DHCP_FILE_LEN; i++) dhcp->msg_out->file[i] = 0;
-  dhcp->msg_out->cookie = htonl(0x63825363UL);
-  dhcp->options_out_len = 0;
-  /* fill options field with an incrementing array (for debugging purposes) */
-  for (i = 0; i < DHCP_OPTIONS_LEN; i++) dhcp->msg_out->options[i] = i;
-  return ERR_OK;
-}
-
-static void dhcp_delete_request(struct netif *netif)
-{
-  struct dhcp *dhcp = netif->dhcp;
-  LWIP_ASSERT("dhcp_free_msg: dhcp->p_out != NULL", dhcp->p_out != NULL);
-  LWIP_ASSERT("dhcp_free_msg: dhcp->msg_out != NULL", dhcp->msg_out != NULL);
-  pbuf_free(dhcp->p_out);
-  dhcp->p_out = NULL;
-  dhcp->msg_out = NULL;
-}
-
-/**
- * Add a DHCP message trailer
- *
- * Adds the END option to the DHCP message, and if
- * necessary, up to three padding bytes.
- */
-
-static void dhcp_option_trailer(struct dhcp *dhcp)
-{
-  LWIP_ASSERT("dhcp_option_trailer: dhcp->msg_out != NULL\n", dhcp->msg_out != NULL);
-  LWIP_ASSERT("dhcp_option_trailer: dhcp->options_out_len < DHCP_OPTIONS_LEN\n", dhcp->options_out_len < DHCP_OPTIONS_LEN);
-  dhcp->msg_out->options[dhcp->options_out_len++] = DHCP_OPTION_END;
-  /* packet is too small, or not 4 byte aligned? */
-  while ((dhcp->options_out_len < DHCP_MIN_OPTIONS_LEN) || (dhcp->options_out_len & 3)) {
-    /* LWIP_DEBUGF(DHCP_DEBUG, ("dhcp_option_trailer: dhcp->options_out_len=%u, DHCP_OPTIONS_LEN=%u", dhcp->options_out_len, DHCP_OPTIONS_LEN)); */
-    LWIP_ASSERT("dhcp_option_trailer: dhcp->options_out_len < DHCP_OPTIONS_LEN\n", dhcp->options_out_len < DHCP_OPTIONS_LEN);
-    /* add a fill/padding byte */
-    dhcp->msg_out->options[dhcp->options_out_len++] = 0;
-  }
-}
-
-/**
- * Find the offset of a DHCP option inside the DHCP message.
- *
- * @param client DHCP client
- * @param option_type
- *
- * @return a byte offset into the UDP message where the option was found, or
- * zero if the given option was not found.
- */
-static u8_t *dhcp_get_option_ptr(struct dhcp *dhcp, u8_t option_type)
-{
-  u8_t overload = DHCP_OVERLOAD_NONE;
-
-  /* options available? */
-  if ((dhcp->options_in != NULL) && (dhcp->options_in_len > 0)) {
-    /* start with options field */
-    u8_t *options = (u8_t *)dhcp->options_in;
-    u16_t offset = 0;
-    /* at least 1 byte to read and no end marker, then at least 3 bytes to read? */
-    while ((offset < dhcp->options_in_len) && (options[offset] != DHCP_OPTION_END)) {
-      /* LWIP_DEBUGF(DHCP_DEBUG, ("msg_offset=%u, q->len=%u", msg_offset, q->len)); */
-      /* are the sname and/or file field overloaded with options? */
-      if (options[offset] == DHCP_OPTION_OVERLOAD) {
-        LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("overloaded message detected\n"));
-        /* skip option type and length */
-        offset += 2;
-        overload = options[offset++];
-      }
-      /* requested option found */
-      else if (options[offset] == option_type) {
-        LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("option found at offset %u in options\n", offset));
-        return &options[offset];
-      /* skip option */
-      } else {
-         LWIP_DEBUGF(DHCP_DEBUG, ("skipping option %u in options\n", options[offset]));
-        /* skip option type */
-        offset++;
-        /* skip option length, and then length bytes */
-        offset += 1 + options[offset];
-      }
-    }
-    /* is this an overloaded message? */
-    if (overload != DHCP_OVERLOAD_NONE) {
-      u16_t field_len;
-      if (overload == DHCP_OVERLOAD_FILE) {
-        LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 1, ("overloaded file field\n"));
-        options = (u8_t *)&dhcp->msg_in->file;
-        field_len = DHCP_FILE_LEN;
-      } else if (overload == DHCP_OVERLOAD_SNAME) {
-        LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 1, ("overloaded sname field\n"));
-        options = (u8_t *)&dhcp->msg_in->sname;
-        field_len = DHCP_SNAME_LEN;
-      /* TODO: check if else if () is necessary */
-      } else {
-        LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 1, ("overloaded sname and file field\n"));
-        options = (u8_t *)&dhcp->msg_in->sname;
-        field_len = DHCP_FILE_LEN + DHCP_SNAME_LEN;
-      }
-      offset = 0;
-
-      /* at least 1 byte to read and no end marker */
-      while ((offset < field_len) && (options[offset] != DHCP_OPTION_END)) {
-        if (options[offset] == option_type) {
-           LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("option found at offset=%u\n", offset));
-          return &options[offset];
-        /* skip option */
-        } else {
-          LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("skipping option %u\n", options[offset]));
-          /* skip option type */
-          offset++;
-          offset += 1 + options[offset];
-        }
-      }
-    }
-  }
-  return 0;
-}
-
-/**
- * Return the byte of DHCP option data.
- *
- * @param client DHCP client.
- * @param ptr pointer obtained by dhcp_get_option_ptr().
- *
- * @return byte value at the given address.
- */
-static u8_t dhcp_get_option_byte(u8_t *ptr)
-{
-  LWIP_DEBUGF(DHCP_DEBUG, ("option byte value=%u\n", *ptr));
-  return *ptr;
-}
-
-/**
- * Return the 16-bit value of DHCP option data.
- *
- * @param client DHCP client.
- * @param ptr pointer obtained by dhcp_get_option_ptr().
- *
- * @return byte value at the given address.
- */
-static u16_t dhcp_get_option_short(u8_t *ptr)
-{
-  u16_t value;
-  value = *ptr++ << 8;
-  value |= *ptr;
-  LWIP_DEBUGF(DHCP_DEBUG, ("option short value=%u\n", value));
-  return value;
-}
-
-/**
- * Return the 32-bit value of DHCP option data.
- *
- * @param client DHCP client.
- * @param ptr pointer obtained by dhcp_get_option_ptr().
- *
- * @return byte value at the given address.
- */
-static u32_t dhcp_get_option_long(u8_t *ptr)
-{
-  u32_t value;
-  value = (u32_t)(*ptr++) << 24;
-  value |= (u32_t)(*ptr++) << 16;
-  value |= (u32_t)(*ptr++) << 8;
-  value |= (u32_t)(*ptr++);
-  LWIP_DEBUGF(DHCP_DEBUG, ("option long value=%lu\n", value));
-  return value;
-}
-
-#endif /* LWIP_DHCP */
+/**\r
+ * @file\r
+ *\r
+ * Dynamic Host Configuration Protocol client\r
+ */\r
+\r
+/*\r
+ *\r
+ * Copyright (c) 2001-2004 Leon Woestenberg <leon.woestenberg@gmx.net>\r
+ * Copyright (c) 2001-2004 Axon Digital Design B.V., The Netherlands.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without modification,\r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED\r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT\r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY\r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is a contribution to the lwIP TCP/IP stack.\r
+ * The Swedish Institute of Computer Science and Adam Dunkels\r
+ * are specifically granted permission to redistribute this\r
+ * source code.\r
+ *\r
+ * Author: Leon Woestenberg <leon.woestenberg@gmx.net>\r
+ *\r
+ * This is a DHCP client for the lwIP TCP/IP stack. It aims to conform\r
+ * with RFC 2131 and RFC 2132.\r
+ *\r
+ * TODO:\r
+ * - Proper parsing of DHCP messages exploiting file/sname field overloading.\r
+ * - Add JavaDoc style documentation (API, internals).\r
+ * - Support for interfaces other than Ethernet (SLIP, PPP, ...)\r
+ *\r
+ * Please coordinate changes and requests with Leon Woestenberg\r
+ * <leon.woestenberg@gmx.net>\r
+ *\r
+ * Integration with your code:\r
+ *\r
+ * In lwip/dhcp.h\r
+ * #define DHCP_COARSE_TIMER_SECS (recommended 60 which is a minute)\r
+ * #define DHCP_FINE_TIMER_MSECS (recommended 500 which equals TCP coarse timer)\r
+ *\r
+ * Then have your application call dhcp_coarse_tmr() and\r
+ * dhcp_fine_tmr() on the defined intervals.\r
+ *\r
+ * dhcp_start(struct netif *netif);\r
+ * starts a DHCP client instance which configures the interface by\r
+ * obtaining an IP address lease and maintaining it.\r
+ *\r
+ * Use dhcp_release(netif) to end the lease and use dhcp_stop(netif)\r
+ * to remove the DHCP client.\r
+ *\r
+ */\r
\r
+#include <string.h>\r
\r
+#include "lwip/stats.h"\r
+#include "lwip/mem.h"\r
+#include "lwip/udp.h"\r
+#include "lwip/ip_addr.h"\r
+#include "lwip/netif.h"\r
+#include "lwip/inet.h"\r
+#include "netif/etharp.h"\r
+\r
+#include "lwip/sys.h"\r
+#include "lwip/opt.h"\r
+#include "lwip/dhcp.h"\r
+\r
+#if LWIP_DHCP /* don't build if not configured for use in lwipopt.h */\r
+\r
+/** global transaction identifier, must be\r
+ *  unique for each DHCP request. We simply increment, starting\r
+ *  with this value (easy to match with a packet analyzer) */\r
+static u32_t xid = 0xABCD0000;\r
+\r
+/** DHCP client state machine functions */\r
+static void dhcp_handle_ack(struct netif *netif);\r
+static void dhcp_handle_nak(struct netif *netif);\r
+static void dhcp_handle_offer(struct netif *netif);\r
+\r
+static err_t dhcp_discover(struct netif *netif);\r
+static err_t dhcp_select(struct netif *netif);\r
+static void dhcp_check(struct netif *netif);\r
+static void dhcp_bind(struct netif *netif);\r
+static err_t dhcp_decline(struct netif *netif);\r
+static err_t dhcp_rebind(struct netif *netif);\r
+static void dhcp_set_state(struct dhcp *dhcp, unsigned char new_state);\r
+\r
+/** receive, unfold, parse and free incoming messages */\r
+static void dhcp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u16_t port);\r
+static err_t dhcp_unfold_reply(struct dhcp *dhcp);\r
+static u8_t *dhcp_get_option_ptr(struct dhcp *dhcp, u8_t option_type);\r
+static u8_t dhcp_get_option_byte(u8_t *ptr);\r
+static u16_t dhcp_get_option_short(u8_t *ptr);\r
+static u32_t dhcp_get_option_long(u8_t *ptr);\r
+static void dhcp_free_reply(struct dhcp *dhcp);\r
+\r
+/** set the DHCP timers */\r
+static void dhcp_timeout(struct netif *netif);\r
+static void dhcp_t1_timeout(struct netif *netif);\r
+static void dhcp_t2_timeout(struct netif *netif);\r
+\r
+/** build outgoing messages */\r
+/** create a DHCP request, fill in common headers */\r
+static err_t dhcp_create_request(struct netif *netif);\r
+/** free a DHCP request */\r
+static void dhcp_delete_request(struct netif *netif);\r
+/** add a DHCP option (type, then length in bytes) */\r
+static void dhcp_option(struct dhcp *dhcp, u8_t option_type, u8_t option_len);\r
+/** add option values */\r
+static void dhcp_option_byte(struct dhcp *dhcp, u8_t value);\r
+static void dhcp_option_short(struct dhcp *dhcp, u16_t value);\r
+static void dhcp_option_long(struct dhcp *dhcp, u32_t value);\r
+/** always add the DHCP options trailer to end and pad */\r
+static void dhcp_option_trailer(struct dhcp *dhcp);\r
+\r
+/**\r
+ * Back-off the DHCP client (because of a received NAK response).\r
+ *\r
+ * Back-off the DHCP client because of a received NAK. Receiving a\r
+ * NAK means the client asked for something non-sensible, for\r
+ * example when it tries to renew a lease obtained on another network.\r
+ *\r
+ * We back-off and will end up restarting a fresh DHCP negotiation later.\r
+ *\r
+ * @param state pointer to DHCP state structure\r
+ */\r
+static void dhcp_handle_nak(struct netif *netif) {\r
+  struct dhcp *dhcp = netif->dhcp;\r
+  u16_t msecs = 10 * 1000;\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_handle_nak(netif=%p) %c%c%u\n", netif,\r
+    netif->name[0], netif->name[1], (unsigned int)netif->num));\r
+  dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_handle_nak(): set request timeout %u msecs\n", msecs));\r
+  dhcp_set_state(dhcp, DHCP_BACKING_OFF);\r
+}\r
+\r
+/**\r
+ * Checks if the offered IP address is already in use.\r
+ *\r
+ * It does so by sending an ARP request for the offered address and\r
+ * entering CHECKING state. If no ARP reply is received within a small\r
+ * interval, the address is assumed to be free for use by us.\r
+ */\r
+static void dhcp_check(struct netif *netif)\r
+{\r
+  struct dhcp *dhcp = netif->dhcp;\r
+  err_t result;\r
+  u16_t msecs;\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_check(netif=%p) %c%c\n", (void *)netif, (unsigned int)netif->name[0],\r
+    (unsigned int)netif->name[1]));\r
+  /* create an ARP query for the offered IP address, expecting that no host\r
+     responds, as the IP address should not be in use. */\r
+  result = etharp_query(netif, &dhcp->offered_ip_addr, NULL);\r
+  if (result != ERR_OK) {\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_check: could not perform ARP query\n"));\r
+  }\r
+  dhcp->tries++;\r
+  msecs = 500;\r
+  dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_check(): set request timeout %u msecs\n", msecs));\r
+  dhcp_set_state(dhcp, DHCP_CHECKING);\r
+}\r
+\r
+/**\r
+ * Remember the configuration offered by a DHCP server.\r
+ *\r
+ * @param state pointer to DHCP state structure\r
+ */\r
+static void dhcp_handle_offer(struct netif *netif)\r
+{\r
+  struct dhcp *dhcp = netif->dhcp;\r
+  /* obtain the server address */\r
+  u8_t *option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_SERVER_ID);\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_handle_offer(netif=%p) %c%c%u\n", netif,\r
+    netif->name[0], netif->name[1], netif->num));\r
+  if (option_ptr != NULL)\r
+  {\r
+    dhcp->server_ip_addr.addr = htonl(dhcp_get_option_long(&option_ptr[2]));\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_STATE, ("dhcp_handle_offer(): server 0x%08lx\n", dhcp->server_ip_addr.addr));\r
+    /* remember offered address */\r
+    ip_addr_set(&dhcp->offered_ip_addr, (struct ip_addr *)&dhcp->msg_in->yiaddr);\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_STATE, ("dhcp_handle_offer(): offer for 0x%08lx\n", dhcp->offered_ip_addr.addr));\r
+\r
+    dhcp_select(netif);\r
+  }\r
+}\r
+\r
+/**\r
+ * Select a DHCP server offer out of all offers.\r
+ *\r
+ * Simply select the first offer received.\r
+ *\r
+ * @param netif the netif under DHCP control\r
+ * @return lwIP specific error (see error.h)\r
+ */\r
+static err_t dhcp_select(struct netif *netif)\r
+{\r
+  struct dhcp *dhcp = netif->dhcp;\r
+  err_t result;\r
+  u32_t msecs;\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_select(netif=%p) %c%c%u\n", netif, netif->name[0], netif->name[1], netif->num));\r
+\r
+  /* create and initialize the DHCP message header */\r
+  result = dhcp_create_request(netif);\r
+  if (result == ERR_OK)\r
+  {\r
+    dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN);\r
+    dhcp_option_byte(dhcp, DHCP_REQUEST);\r
+\r
+    dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);\r
+    dhcp_option_short(dhcp, 576);\r
+\r
+    /* MUST request the offered IP address */\r
+    dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4);\r
+    dhcp_option_long(dhcp, ntohl(dhcp->offered_ip_addr.addr));\r
+\r
+    dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4);\r
+    dhcp_option_long(dhcp, ntohl(dhcp->server_ip_addr.addr));\r
+\r
+    dhcp_option(dhcp, DHCP_OPTION_PARAMETER_REQUEST_LIST, 4/*num options*/);\r
+    dhcp_option_byte(dhcp, DHCP_OPTION_SUBNET_MASK);\r
+    dhcp_option_byte(dhcp, DHCP_OPTION_ROUTER);\r
+    dhcp_option_byte(dhcp, DHCP_OPTION_BROADCAST);\r
+    dhcp_option_byte(dhcp, DHCP_OPTION_DNS_SERVER);\r
+\r
+    dhcp_option_trailer(dhcp);\r
+    /* shrink the pbuf to the actual content length */\r
+    pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);\r
+\r
+    /* TODO: we really should bind to a specific local interface here\r
+       but we cannot specify an unconfigured netif as it is addressless */\r
+    udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);\r
+    /* send broadcast to any DHCP server */\r
+    udp_connect(dhcp->pcb, IP_ADDR_BROADCAST, DHCP_SERVER_PORT);\r
+    udp_send(dhcp->pcb, dhcp->p_out);\r
+    /* reconnect to any (or to server here?!) */\r
+    udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT);\r
+    dhcp_delete_request(netif);\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_select: REQUESTING\n"));\r
+    dhcp_set_state(dhcp, DHCP_REQUESTING);\r
+  } else {\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_select: could not allocate DHCP request\n"));\r
+  }\r
+  dhcp->tries++;\r
+  msecs = dhcp->tries < 4 ? dhcp->tries * 1000 : 4 * 1000;\r
+  dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_STATE, ("dhcp_select(): set request timeout %u msecs\n", msecs));\r
+  return result;\r
+}\r
+\r
+/**\r
+ * The DHCP timer that checks for lease renewal/rebind timeouts.\r
+ *\r
+ */\r
+void dhcp_coarse_tmr()\r
+{\r
+  struct netif *netif = netif_list;\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_coarse_tmr()\n"));\r
+  /* iterate through all network interfaces */\r
+  while (netif != NULL) {\r
+    /* only act on DHCP configured interfaces */\r
+    if (netif->dhcp != NULL) {\r
+      /* timer is active (non zero), and triggers (zeroes) now? */\r
+      if (netif->dhcp->t2_timeout-- == 1) {\r
+        LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_coarse_tmr(): t2 timeout\n"));\r
+        /* this clients' rebind timeout triggered */\r
+        dhcp_t2_timeout(netif);\r
+      /* timer is active (non zero), and triggers (zeroes) now */\r
+      } else if (netif->dhcp->t1_timeout-- == 1) {\r
+        LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_coarse_tmr(): t1 timeout\n"));\r
+        /* this clients' renewal timeout triggered */\r
+        dhcp_t1_timeout(netif);\r
+      }\r
+    }\r
+    /* proceed to next netif */\r
+    netif = netif->next;\r
+  }\r
+}\r
+\r
+/**\r
+ * DHCP transaction timeout handling\r
+ *\r
+ * A DHCP server is expected to respond within a short period of time.\r
+ * This timer checks whether an outstanding DHCP request is timed out.\r
+ * \r
+ */\r
+void dhcp_fine_tmr()\r
+{\r
+  struct netif *netif = netif_list;\r
+  /* loop through netif's */\r
+  while (netif != NULL) {\r
+    /* only act on DHCP configured interfaces */\r
+    if (netif->dhcp != NULL) {\r
+      /* timer is active (non zero), and is about to trigger now */\r
+      if (netif->dhcp->request_timeout-- == 1) {\r
+        /* { netif->dhcp->request_timeout == 0 } */\r
+        LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_fine_tmr(): request timeout\n"));\r
+        /* this clients' request timeout triggered */\r
+        dhcp_timeout(netif);\r
+      }\r
+    }\r
+    /* proceed to next network interface */\r
+    netif = netif->next;\r
+  }\r
+}\r
+\r
+/**\r
+ * A DHCP negotiation transaction, or ARP request, has timed out.\r
+ *\r
+ * The timer that was started with the DHCP or ARP request has\r
+ * timed out, indicating no response was received in time.\r
+ *\r
+ * @param netif the netif under DHCP control\r
+ *\r
+ */\r
+static void dhcp_timeout(struct netif *netif)\r
+{\r
+  struct dhcp *dhcp = netif->dhcp;\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_timeout()\n"));\r
+  /* back-off period has passed, or server selection timed out */\r
+  if ((dhcp->state == DHCP_BACKING_OFF) || (dhcp->state == DHCP_SELECTING)) {\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_timeout(): restarting discovery\n"));\r
+    dhcp_discover(netif);\r
+  /* receiving the requested lease timed out */\r
+  } else if (dhcp->state == DHCP_REQUESTING) {\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_timeout(): REQUESTING, DHCP request timed out\n"));\r
+    if (dhcp->tries <= 5) {\r
+      dhcp_select(netif);\r
+    } else {\r
+      LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_timeout(): REQUESTING, releasing, restarting\n"));\r
+      dhcp_release(netif);\r
+      dhcp_discover(netif);\r
+    }\r
+  /* received no ARP reply for the offered address (which is good) */\r
+  } else if (dhcp->state == DHCP_CHECKING) {\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_timeout(): CHECKING, ARP request timed out\n"));\r
+    if (dhcp->tries <= 1) {\r
+      dhcp_check(netif);\r
+    /* no ARP replies on the offered address,\r
+       looks like the IP address is indeed free */\r
+    } else {\r
+      /* bind the interface to the offered address */\r
+      dhcp_bind(netif);\r
+    }\r
+  }\r
+  /* did not get response to renew request? */\r
+  else if (dhcp->state == DHCP_RENEWING) {\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_timeout(): RENEWING, DHCP request timed out\n"));\r
+    /* just retry renewal */\r
+    /* note that the rebind timer will eventually time-out if renew does not work */\r
+    dhcp_renew(netif);\r
+  /* did not get response to rebind request? */\r
+  } else if (dhcp->state == DHCP_REBINDING) {\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_timeout(): REBINDING, DHCP request timed out\n"));\r
+    if (dhcp->tries <= 8) {\r
+      dhcp_rebind(netif);\r
+    } else {\r
+      LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_timeout(): RELEASING, DISCOVERING\n"));\r
+      dhcp_release(netif);\r
+      dhcp_discover(netif);\r
+    }\r
+  }\r
+}\r
+\r
+/**\r
+ * The renewal period has timed out.\r
+ *\r
+ * @param netif the netif under DHCP control\r
+ */\r
+static void dhcp_t1_timeout(struct netif *netif)\r
+{\r
+  struct dhcp *dhcp = netif->dhcp;\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_STATE, ("dhcp_t1_timeout()\n"));\r
+  if ((dhcp->state == DHCP_REQUESTING) || (dhcp->state == DHCP_BOUND) || (dhcp->state == DHCP_RENEWING)) {\r
+    /* just retry to renew - note that the rebind timer (t2) will\r
+     * eventually time-out if renew tries fail. */\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_t1_timeout(): must renew\n"));\r
+    dhcp_renew(netif);\r
+  }\r
+}\r
+\r
+/**\r
+ * The rebind period has timed out.\r
+ *\r
+ */\r
+static void dhcp_t2_timeout(struct netif *netif)\r
+{\r
+  struct dhcp *dhcp = netif->dhcp;\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_t2_timeout()\n"));\r
+  if ((dhcp->state == DHCP_REQUESTING) || (dhcp->state == DHCP_BOUND) || (dhcp->state == DHCP_RENEWING)) {\r
+    /* just retry to rebind */\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_t2_timeout(): must rebind\n"));\r
+    dhcp_rebind(netif);\r
+  }\r
+}\r
+\r
+/**\r
+ *\r
+ * @param netif the netif under DHCP control\r
+ */\r
+static void dhcp_handle_ack(struct netif *netif)\r
+{\r
+  struct dhcp *dhcp = netif->dhcp;\r
+  u8_t *option_ptr;\r
+  /* clear options we might not get from the ACK */\r
+  dhcp->offered_sn_mask.addr = 0;\r
+  dhcp->offered_gw_addr.addr = 0;\r
+  dhcp->offered_bc_addr.addr = 0;\r
+\r
+  /* lease time given? */\r
+  option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_LEASE_TIME);\r
+  if (option_ptr != NULL) {\r
+    /* remember offered lease time */\r
+    dhcp->offered_t0_lease = dhcp_get_option_long(option_ptr + 2);\r
+  }\r
+  /* renewal period given? */\r
+  option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_T1);\r
+  if (option_ptr != NULL) {\r
+    /* remember given renewal period */\r
+    dhcp->offered_t1_renew = dhcp_get_option_long(option_ptr + 2);\r
+  } else {\r
+    /* calculate safe periods for renewal */\r
+    dhcp->offered_t1_renew = dhcp->offered_t0_lease / 2;\r
+  }\r
+\r
+  /* renewal period given? */\r
+  option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_T2);\r
+  if (option_ptr != NULL) {\r
+    /* remember given rebind period */\r
+    dhcp->offered_t2_rebind = dhcp_get_option_long(option_ptr + 2);\r
+  } else {\r
+    /* calculate safe periods for rebinding */\r
+    dhcp->offered_t2_rebind = dhcp->offered_t0_lease;\r
+  }\r
+\r
+  /* (y)our internet address */\r
+  ip_addr_set(&dhcp->offered_ip_addr, &dhcp->msg_in->yiaddr);\r
+\r
+/**\r
+ * Patch #1308\r
+ * TODO: we must check if the file field is not overloaded by DHCP options!\r
+ */\r
+#if 0\r
+  /* boot server address */\r
+  ip_addr_set(&dhcp->offered_si_addr, &dhcp->msg_in->siaddr);\r
+  /* boot file name */\r
+  if (dhcp->msg_in->file[0]) {\r
+    dhcp->boot_file_name = mem_malloc(strlen(dhcp->msg_in->file) + 1);\r
+    strcpy(dhcp->boot_file_name, dhcp->msg_in->file);\r
+  }\r
+#endif\r
+\r
+  /* subnet mask */\r
+  option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_SUBNET_MASK);\r
+  /* subnet mask given? */\r
+  if (option_ptr != NULL) {\r
+    dhcp->offered_sn_mask.addr = htonl(dhcp_get_option_long(&option_ptr[2]));\r
+  }\r
+\r
+  /* gateway router */\r
+  option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_ROUTER);\r
+  if (option_ptr != NULL) {\r
+    dhcp->offered_gw_addr.addr = htonl(dhcp_get_option_long(&option_ptr[2]));\r
+  }\r
+\r
+  /* broadcast address */\r
+  option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_BROADCAST);\r
+  if (option_ptr != NULL) {\r
+    dhcp->offered_bc_addr.addr = htonl(dhcp_get_option_long(&option_ptr[2]));\r
+  }\r
+  \r
+  /* DNS servers */\r
+  option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_DNS_SERVER);\r
+  if (option_ptr != NULL) {\r
+    u8_t n;\r
+    dhcp->dns_count = dhcp_get_option_byte(&option_ptr[1]);\r
+    /* limit to at most DHCP_MAX_DNS DNS servers */\r
+    if (dhcp->dns_count > DHCP_MAX_DNS) dhcp->dns_count = DHCP_MAX_DNS;\r
+    for (n = 0; n < dhcp->dns_count; n++)\r
+    {\r
+      dhcp->offered_dns_addr[n].addr = htonl(dhcp_get_option_long(&option_ptr[2+(n<<2)]));\r
+    }\r
+  }\r
+}\r
+\r
+/**\r
+ * Start DHCP negotiation for a network interface.\r
+ *\r
+ * If no DHCP client instance was attached to this interface,\r
+ * a new client is created first. If a DHCP client instance\r
+ * was already present, it restarts negotiation.\r
+ *\r
+ * @param netif The lwIP network interface\r
+ * @return lwIP error code\r
+ * - ERR_OK - No error\r
+ * - ERR_MEM - Out of memory\r
+ *\r
+ */\r
+err_t dhcp_start(struct netif *netif)\r
+{\r
+  struct dhcp *dhcp = netif->dhcp;\r
+  err_t result = ERR_OK;\r
+\r
+  LWIP_ASSERT("netif != NULL", netif != NULL);\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_start(netif=%p) %c%c%u\n", netif, netif->name[0], netif->name[1], netif->num));\r
+  netif->flags &= ~NETIF_FLAG_DHCP;\r
+\r
+  /* no DHCP client attached yet? */\r
+  if (dhcp == NULL) {\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_start(): starting new DHCP client\n"));\r
+    dhcp = mem_malloc(sizeof(struct dhcp));\r
+    if (dhcp == NULL) {\r
+      LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_start(): could not allocate dhcp\n"));\r
+      return ERR_MEM;\r
+    }\r
+    /* store this dhcp client in the netif */\r
+    netif->dhcp = dhcp;\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_start(): allocated dhcp"));\r
+  /* already has DHCP client attached */\r
+  } else {\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE | 3, ("dhcp_start(): restarting DHCP configuration\n"));\r
+  }\r
+       \r
+       /* clear data structure */\r
+       memset(dhcp, 0, sizeof(struct dhcp));\r
+  /* allocate UDP PCB */\r
+       dhcp->pcb = udp_new();\r
+       if (dhcp->pcb == NULL) {\r
+         LWIP_DEBUGF(DHCP_DEBUG  | DBG_TRACE, ("dhcp_start(): could not obtain pcb\n"));\r
+         mem_free((void *)dhcp);\r
+         netif->dhcp = dhcp = NULL;\r
+         return ERR_MEM;\r
+       }\r
+       LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_start(): starting DHCP configuration\n"));\r
+  /* (re)start the DHCP negotiation */\r
+  result = dhcp_discover(netif);\r
+  if (result != ERR_OK) {\r
+    /* free resources allocated above */\r
+    dhcp_stop(netif);\r
+    return ERR_MEM;\r
+  }\r
+  netif->flags |= NETIF_FLAG_DHCP;\r
+  return result;\r
+}\r
+\r
+/**\r
+ * Inform a DHCP server of our manual configuration.\r
+ *\r
+ * This informs DHCP servers of our fixed IP address configuration\r
+ * by sending an INFORM message. It does not involve DHCP address\r
+ * configuration, it is just here to be nice to the network.\r
+ *\r
+ * @param netif The lwIP network interface\r
+ *\r
+ */\r
+void dhcp_inform(struct netif *netif)\r
+{\r
+  struct dhcp *dhcp;\r
+  err_t result = ERR_OK;\r
+  dhcp = mem_malloc(sizeof(struct dhcp));\r
+  if (dhcp == NULL) {\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_inform(): could not allocate dhcp\n"));\r
+    return;\r
+  }\r
+  netif->dhcp = dhcp;\r
+  memset(dhcp, 0, sizeof(struct dhcp));\r
+\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_inform(): allocated dhcp\n"));\r
+  dhcp->pcb = udp_new();\r
+  if (dhcp->pcb == NULL) {\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_inform(): could not obtain pcb"));\r
+    mem_free((void *)dhcp);\r
+    return;\r
+  }\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_inform(): created new udp pcb\n"));\r
+  /* create and initialize the DHCP message header */\r
+  result = dhcp_create_request(netif);\r
+  if (result == ERR_OK) {\r
+\r
+    dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN);\r
+    dhcp_option_byte(dhcp, DHCP_INFORM);\r
+\r
+    dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);\r
+    /* TODO: use netif->mtu ?! */\r
+    dhcp_option_short(dhcp, 576);\r
+\r
+    dhcp_option_trailer(dhcp);\r
+\r
+    pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);\r
+\r
+    udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);\r
+    udp_connect(dhcp->pcb, IP_ADDR_BROADCAST, DHCP_SERVER_PORT);\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_inform: INFORMING\n"));\r
+    udp_send(dhcp->pcb, dhcp->p_out);\r
+    udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT);\r
+    dhcp_delete_request(netif);\r
+  } else {\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_inform: could not allocate DHCP request\n"));\r
+  }\r
+\r
+  if (dhcp != NULL)\r
+  {\r
+    if (dhcp->pcb != NULL) udp_remove(dhcp->pcb);\r
+    dhcp->pcb = NULL;\r
+    mem_free((void *)dhcp);\r
+    netif->dhcp = NULL;\r
+  }\r
+}\r
+\r
+#if DHCP_DOES_ARP_CHECK\r
+/**\r
+ * Match an ARP reply with the offered IP address.\r
+ *\r
+ * @param addr The IP address we received a reply from\r
+ *\r
+ */\r
+void dhcp_arp_reply(struct netif *netif, struct ip_addr *addr)\r
+{\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_arp_reply()\n"));\r
+  /* is this DHCP client doing an ARP check? */\r
+  if ((netif->dhcp != NULL) && (netif->dhcp->state == DHCP_CHECKING)) {\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_arp_reply(): CHECKING, arp reply for 0x%08lx\n", addr->addr));\r
+    /* did a host respond with the address we\r
+       were offered by the DHCP server? */\r
+    if (ip_addr_cmp(addr, &netif->dhcp->offered_ip_addr)) {\r
+      /* we will not accept the offered address */\r
+      LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE | 1, ("dhcp_arp_reply(): arp reply matched with offered address, declining\n"));\r
+      dhcp_decline(netif);\r
+    }\r
+  }\r
+}\r
+\r
+/**\r
+ * Decline an offered lease.\r
+ *\r
+ * Tell the DHCP server we do not accept the offered address.\r
+ * One reason to decline the lease is when we find out the address\r
+ * is already in use by another host (through ARP).\r
+ */\r
+static err_t dhcp_decline(struct netif *netif)\r
+{\r
+  struct dhcp *dhcp = netif->dhcp;\r
+  err_t result = ERR_OK;\r
+  u16_t msecs;\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_decline()\n"));\r
+  dhcp_set_state(dhcp, DHCP_BACKING_OFF);\r
+  /* create and initialize the DHCP message header */\r
+  result = dhcp_create_request(netif);\r
+  if (result == ERR_OK)\r
+  {\r
+    dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN);\r
+    dhcp_option_byte(dhcp, DHCP_DECLINE);\r
+\r
+    dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);\r
+    dhcp_option_short(dhcp, 576);\r
+\r
+    dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4);\r
+    dhcp_option_long(dhcp, ntohl(dhcp->offered_ip_addr.addr));\r
+\r
+    dhcp_option_trailer(dhcp);\r
+    /* resize pbuf to reflect true size of options */\r
+    pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);\r
+\r
+    udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);\r
+    /* @todo: should we really connect here? we are performing sendto() */\r
+    udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT);\r
+    /* per section 4.4.4, broadcast DECLINE messages */\r
+    udp_sendto(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT);\r
+    dhcp_delete_request(netif);\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_decline: BACKING OFF\n"));\r
+  } else {\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_decline: could not allocate DHCP request\n"));\r
+  }\r
+  dhcp->tries++;\r
+  msecs = 10*1000;\r
+  dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;\r
+   LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_decline(): set request timeout %u msecs\n", msecs));\r
+  return result;\r
+}\r
+#endif\r
+\r
+\r
+/**\r
+ * Start the DHCP process, discover a DHCP server.\r
+ *\r
+ */\r
+static err_t dhcp_discover(struct netif *netif)\r
+{\r
+  struct dhcp *dhcp = netif->dhcp;\r
+  err_t result = ERR_OK;\r
+  u16_t msecs;\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_discover()\n"));\r
+  ip_addr_set(&dhcp->offered_ip_addr, IP_ADDR_ANY);\r
+  /* create and initialize the DHCP message header */\r
+  result = dhcp_create_request(netif);\r
+  if (result == ERR_OK)\r
+  {\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_discover: making request\n"));\r
+    dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN);\r
+    dhcp_option_byte(dhcp, DHCP_DISCOVER);\r
+\r
+    dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);\r
+    dhcp_option_short(dhcp, 576);\r
+\r
+    dhcp_option(dhcp, DHCP_OPTION_PARAMETER_REQUEST_LIST, 4/*num options*/);\r
+    dhcp_option_byte(dhcp, DHCP_OPTION_SUBNET_MASK);\r
+    dhcp_option_byte(dhcp, DHCP_OPTION_ROUTER);\r
+    dhcp_option_byte(dhcp, DHCP_OPTION_BROADCAST);\r
+    dhcp_option_byte(dhcp, DHCP_OPTION_DNS_SERVER);\r
+\r
+    dhcp_option_trailer(dhcp);\r
+\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_discover: realloc()ing\n"));\r
+    pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);\r
+\r
+    /* set receive callback function with netif as user data */\r
+    udp_recv(dhcp->pcb, dhcp_recv, netif);\r
+    udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);\r
+    udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT);\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_discover: sendto(DISCOVER, IP_ADDR_BROADCAST, DHCP_SERVER_PORT)\n"));\r
+    udp_sendto(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT);\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_discover: deleting()ing\n"));\r
+    dhcp_delete_request(netif);\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_discover: SELECTING\n"));\r
+    dhcp_set_state(dhcp, DHCP_SELECTING);\r
+  } else {\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_discover: could not allocate DHCP request\n"));\r
+  }\r
+  dhcp->tries++;\r
+  msecs = dhcp->tries < 4 ? (dhcp->tries + 1) * 1000 : 10 * 1000;\r
+  dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_discover(): set request timeout %u msecs\n", msecs));\r
+  return result;\r
+}\r
+\r
+\r
+/**\r
+ * Bind the interface to the offered IP address.\r
+ *\r
+ * @param netif network interface to bind to the offered address\r
+ */\r
+static void dhcp_bind(struct netif *netif)\r
+{\r
+  struct dhcp *dhcp = netif->dhcp;\r
+  struct ip_addr sn_mask, gw_addr;\r
+  LWIP_ASSERT("dhcp_bind: netif != NULL", netif != NULL);\r
+  LWIP_ASSERT("dhcp_bind: dhcp != NULL", dhcp != NULL);\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_bind(netif=%p) %c%c%u\n", netif, netif->name[0], netif->name[1], netif->num));\r
+\r
+  /* temporary DHCP lease? */\r
+  if (dhcp->offered_t1_renew != 0xffffffffUL) {\r
+    /* set renewal period timer */\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_bind(): t1 renewal timer %lu secs\n", dhcp->offered_t1_renew));\r
+    dhcp->t1_timeout = (dhcp->offered_t1_renew + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS;\r
+    if (dhcp->t1_timeout == 0) dhcp->t1_timeout = 1;\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_bind(): set request timeout %u msecs\n", dhcp->offered_t1_renew*1000));\r
+  }\r
+  /* set renewal period timer */\r
+  if (dhcp->offered_t2_rebind != 0xffffffffUL) {\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_bind(): t2 rebind timer %lu secs\n", dhcp->offered_t2_rebind));\r
+    dhcp->t2_timeout = (dhcp->offered_t2_rebind + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS;\r
+    if (dhcp->t2_timeout == 0) dhcp->t2_timeout = 1;\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_bind(): set request timeout %u msecs\n", dhcp->offered_t2_rebind*1000));\r
+  }\r
+  /* copy offered network mask */\r
+  ip_addr_set(&sn_mask, &dhcp->offered_sn_mask);\r
+\r
+  /* subnet mask not given? */\r
+  /* TODO: this is not a valid check. what if the network mask is 0? */\r
+  if (sn_mask.addr == 0) {\r
+    /* choose a safe subnet mask given the network class */\r
+    u8_t first_octet = ip4_addr1(&sn_mask);\r
+    if (first_octet <= 127) sn_mask.addr = htonl(0xff000000);\r
+    else if (first_octet >= 192) sn_mask.addr = htonl(0xffffff00);\r
+    else sn_mask.addr = htonl(0xffff0000);\r
+  }\r
+\r
+  ip_addr_set(&gw_addr, &dhcp->offered_gw_addr);\r
+  /* gateway address not given? */\r
+  if (gw_addr.addr == 0) {\r
+    /* copy network address */\r
+    gw_addr.addr = (dhcp->offered_ip_addr.addr & sn_mask.addr);\r
+    /* use first host address on network as gateway */\r
+    gw_addr.addr |= htonl(0x00000001);\r
+  }\r
+\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_STATE, ("dhcp_bind(): IP: 0x%08lx\n", dhcp->offered_ip_addr.addr));\r
+  netif_set_ipaddr(netif, &dhcp->offered_ip_addr);\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_STATE, ("dhcp_bind(): SN: 0x%08lx\n", sn_mask.addr));\r
+  netif_set_netmask(netif, &sn_mask);\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_STATE, ("dhcp_bind(): GW: 0x%08lx\n", gw_addr.addr));\r
+  netif_set_gw(netif, &gw_addr);\r
+  /* bring the interface up */\r
+  netif_set_up(netif);\r
+  /* netif is now bound to DHCP leased address */\r
+  dhcp_set_state(dhcp, DHCP_BOUND);\r
+}\r
+\r
+/**\r
+ * Renew an existing DHCP lease at the involved DHCP server.\r
+ *\r
+ * @param netif network interface which must renew its lease\r
+ */\r
+err_t dhcp_renew(struct netif *netif)\r
+{\r
+  struct dhcp *dhcp = netif->dhcp;\r
+  err_t result;\r
+  u16_t msecs;\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_renew()\n"));\r
+  dhcp_set_state(dhcp, DHCP_RENEWING);\r
+\r
+  /* create and initialize the DHCP message header */\r
+  result = dhcp_create_request(netif);\r
+  if (result == ERR_OK) {\r
+\r
+    dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN);\r
+    dhcp_option_byte(dhcp, DHCP_REQUEST);\r
+\r
+    dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);\r
+    /* TODO: use netif->mtu in some way */\r
+    dhcp_option_short(dhcp, 576);\r
+\r
+#if 0\r
+    dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4);\r
+    dhcp_option_long(dhcp, ntohl(dhcp->offered_ip_addr.addr));\r
+#endif\r
+\r
+#if 0\r
+    dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4);\r
+    dhcp_option_long(dhcp, ntohl(dhcp->server_ip_addr.addr));\r
+#endif\r
+    /* append DHCP message trailer */\r
+    dhcp_option_trailer(dhcp);\r
+\r
+    pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);\r
+\r
+    udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);\r
+    udp_connect(dhcp->pcb, &dhcp->server_ip_addr, DHCP_SERVER_PORT);\r
+    udp_send(dhcp->pcb, dhcp->p_out);\r
+    dhcp_delete_request(netif);\r
+\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_renew: RENEWING\n"));\r
+  } else {\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_renew: could not allocate DHCP request\n"));\r
+  }\r
+  dhcp->tries++;\r
+  /* back-off on retries, but to a maximum of 20 seconds */\r
+  msecs = dhcp->tries < 10 ? dhcp->tries * 2000 : 20 * 1000;\r
+  dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;\r
+   LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_renew(): set request timeout %u msecs\n", msecs));\r
+  return result;\r
+}\r
+\r
+/**\r
+ * Rebind with a DHCP server for an existing DHCP lease.\r
+ *\r
+ * @param netif network interface which must rebind with a DHCP server\r
+ */\r
+static err_t dhcp_rebind(struct netif *netif)\r
+{\r
+  struct dhcp *dhcp = netif->dhcp;\r
+  err_t result;\r
+  u16_t msecs;\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_rebind()\n"));\r
+  dhcp_set_state(dhcp, DHCP_REBINDING);\r
+\r
+  /* create and initialize the DHCP message header */\r
+  result = dhcp_create_request(netif);\r
+  if (result == ERR_OK)\r
+  {\r
+\r
+    dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN);\r
+    dhcp_option_byte(dhcp, DHCP_REQUEST);\r
+\r
+    dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);\r
+    dhcp_option_short(dhcp, 576);\r
+\r
+#if 0\r
+    dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4);\r
+    dhcp_option_long(dhcp, ntohl(dhcp->offered_ip_addr.addr));\r
+\r
+    dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4);\r
+    dhcp_option_long(dhcp, ntohl(dhcp->server_ip_addr.addr));\r
+#endif\r
+\r
+    dhcp_option_trailer(dhcp);\r
+\r
+    pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);\r
+\r
+    /* set remote IP association to any DHCP server */\r
+    udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);\r
+    udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT);\r
+    /* broadcast to server */\r
+    udp_sendto(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT);\r
+    dhcp_delete_request(netif);\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_rebind: REBINDING\n"));\r
+  } else {\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_rebind: could not allocate DHCP request\n"));\r
+  }\r
+  dhcp->tries++;\r
+  msecs = dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000;\r
+  dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;\r
+   LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_rebind(): set request timeout %u msecs\n", msecs));\r
+  return result;\r
+}\r
+\r
+/**\r
+ * Release a DHCP lease.\r
+ *\r
+ * @param netif network interface which must release its lease\r
+ */\r
+err_t dhcp_release(struct netif *netif)\r
+{\r
+  struct dhcp *dhcp = netif->dhcp;\r
+  err_t result;\r
+  u16_t msecs;\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_release()\n"));\r
+\r
+  /* idle DHCP client */\r
+  dhcp_set_state(dhcp, DHCP_OFF);\r
+  /* clean old DHCP offer */\r
+  dhcp->server_ip_addr.addr = 0;\r
+  dhcp->offered_ip_addr.addr = dhcp->offered_sn_mask.addr = 0;\r
+  dhcp->offered_gw_addr.addr = dhcp->offered_bc_addr.addr = 0;\r
+  dhcp->offered_t0_lease = dhcp->offered_t1_renew = dhcp->offered_t2_rebind = 0;\r
+  dhcp->dns_count = 0;\r
+  \r
+  /* create and initialize the DHCP message header */\r
+  result = dhcp_create_request(netif);\r
+  if (result == ERR_OK) {\r
+    dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN);\r
+    dhcp_option_byte(dhcp, DHCP_RELEASE);\r
+\r
+    dhcp_option_trailer(dhcp);\r
+\r
+    pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);\r
+\r
+    udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);\r
+    udp_connect(dhcp->pcb, &dhcp->server_ip_addr, DHCP_SERVER_PORT);\r
+    udp_send(dhcp->pcb, dhcp->p_out);\r
+    dhcp_delete_request(netif);\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_release: RELEASED, DHCP_OFF\n"));\r
+  } else {\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_release: could not allocate DHCP request\n"));\r
+  }\r
+  dhcp->tries++;\r
+  msecs = dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000;\r
+  dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_release(): set request timeout %u msecs\n", msecs));\r
+  /* bring the interface down */\r
+  netif_set_down(netif);\r
+  /* remove IP address from interface */\r
+  netif_set_ipaddr(netif, IP_ADDR_ANY);\r
+  netif_set_gw(netif, IP_ADDR_ANY);\r
+  netif_set_netmask(netif, IP_ADDR_ANY);\r
+  \r
+  /* TODO: netif_down(netif); */\r
+  return result;\r
+}\r
+/**\r
+ * Remove the DHCP client from the interface.\r
+ *\r
+ * @param netif The network interface to stop DHCP on\r
+ */\r
+void dhcp_stop(struct netif *netif)\r
+{\r
+  struct dhcp *dhcp = netif->dhcp;\r
+  LWIP_ASSERT("dhcp_stop: netif != NULL", netif != NULL);\r
+\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_stop()\n"));\r
+  /* netif is DHCP configured? */\r
+  if (dhcp != NULL)\r
+  {\r
+    if (dhcp->pcb != NULL)\r
+    {\r
+      udp_remove(dhcp->pcb);\r
+      dhcp->pcb = NULL;\r
+    }\r
+    if (dhcp->p != NULL)\r
+    {\r
+      pbuf_free(dhcp->p);\r
+      dhcp->p = NULL;\r
+    }\r
+    /* free unfolded reply */\r
+    dhcp_free_reply(dhcp);\r
+    mem_free((void *)dhcp);\r
+    netif->dhcp = NULL;\r
+  }\r
+}\r
+\r
+/*\r
+ * Set the DHCP state of a DHCP client.\r
+ *\r
+ * If the state changed, reset the number of tries.\r
+ *\r
+ * TODO: we might also want to reset the timeout here?\r
+ */\r
+static void dhcp_set_state(struct dhcp *dhcp, unsigned char new_state)\r
+{\r
+  if (new_state != dhcp->state)\r
+  {\r
+    dhcp->state = new_state;\r
+    dhcp->tries = 0;\r
+  }\r
+}\r
+\r
+/*\r
+ * Concatenate an option type and length field to the outgoing\r
+ * DHCP message.\r
+ *\r
+ */\r
+static void dhcp_option(struct dhcp *dhcp, u8_t option_type, u8_t option_len)\r
+{\r
+  LWIP_ASSERT("dhcp_option_short: dhcp->options_out_len + 2 + option_len <= DHCP_OPTIONS_LEN", dhcp->options_out_len + 2 + option_len <= DHCP_OPTIONS_LEN);\r
+  dhcp->msg_out->options[dhcp->options_out_len++] = option_type;\r
+  dhcp->msg_out->options[dhcp->options_out_len++] = option_len;\r
+}\r
+/*\r
+ * Concatenate a single byte to the outgoing DHCP message.\r
+ *\r
+ */\r
+static void dhcp_option_byte(struct dhcp *dhcp, u8_t value)\r
+{\r
+  LWIP_ASSERT("dhcp_option_short: dhcp->options_out_len < DHCP_OPTIONS_LEN", dhcp->options_out_len < DHCP_OPTIONS_LEN);\r
+  dhcp->msg_out->options[dhcp->options_out_len++] = value;\r
+}\r
+static void dhcp_option_short(struct dhcp *dhcp, u16_t value)\r
+{\r
+  LWIP_ASSERT("dhcp_option_short: dhcp->options_out_len + 2 <= DHCP_OPTIONS_LEN", dhcp->options_out_len + 2 <= DHCP_OPTIONS_LEN);\r
+  dhcp->msg_out->options[dhcp->options_out_len++] = (value & 0xff00U) >> 8;\r
+  dhcp->msg_out->options[dhcp->options_out_len++] =  value & 0x00ffU;\r
+}\r
+static void dhcp_option_long(struct dhcp *dhcp, u32_t value)\r
+{\r
+  LWIP_ASSERT("dhcp_option_long: dhcp->options_out_len + 4 <= DHCP_OPTIONS_LEN", dhcp->options_out_len + 4 <= DHCP_OPTIONS_LEN);\r
+  dhcp->msg_out->options[dhcp->options_out_len++] = (value & 0xff000000UL) >> 24;\r
+  dhcp->msg_out->options[dhcp->options_out_len++] = (value & 0x00ff0000UL) >> 16;\r
+  dhcp->msg_out->options[dhcp->options_out_len++] = (value & 0x0000ff00UL) >> 8;\r
+  dhcp->msg_out->options[dhcp->options_out_len++] = (value & 0x000000ffUL);\r
+}\r
+\r
+/**\r
+ * Extract the DHCP message and the DHCP options.\r
+ *\r
+ * Extract the DHCP message and the DHCP options, each into a contiguous\r
+ * piece of memory. As a DHCP message is variable sized by its options,\r
+ * and also allows overriding some fields for options, the easy approach\r
+ * is to first unfold the options into a conitguous piece of memory, and\r
+ * use that further on.\r
+ *\r
+ */\r
+static err_t dhcp_unfold_reply(struct dhcp *dhcp)\r
+{\r
+  struct pbuf *p = dhcp->p;\r
+  u8_t *ptr;\r
+  u16_t i;\r
+  u16_t j = 0;\r
+  LWIP_ASSERT("dhcp->p != NULL", dhcp->p != NULL);\r
+  /* free any left-overs from previous unfolds */\r
+  dhcp_free_reply(dhcp);\r
+  /* options present? */\r
+  if (dhcp->p->tot_len > (sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN))\r
+  {\r
+    dhcp->options_in_len = dhcp->p->tot_len - (sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN);\r
+    dhcp->options_in = mem_malloc(dhcp->options_in_len);\r
+    if (dhcp->options_in == NULL)\r
+    {\r
+      LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_unfold_reply(): could not allocate dhcp->options\n"));\r
+      return ERR_MEM;\r
+    }\r
+  }\r
+  dhcp->msg_in = mem_malloc(sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN);\r
+  if (dhcp->msg_in == NULL)\r
+  {\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_unfold_reply(): could not allocate dhcp->msg_in\n"));\r
+    mem_free((void *)dhcp->options_in);\r
+    dhcp->options_in = NULL;\r
+    return ERR_MEM;\r
+  }\r
+\r
+  ptr = (u8_t *)dhcp->msg_in;\r
+  /* proceed through struct dhcp_msg */\r
+  for (i = 0; i < sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN; i++)\r
+  {\r
+    *ptr++ = ((u8_t *)p->payload)[j++];\r
+    /* reached end of pbuf? */\r
+    if (j == p->len)\r
+    {\r
+      /* proceed to next pbuf in chain */\r
+      p = p->next;\r
+      j = 0;\r
+    }\r
+  }\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_unfold_reply(): copied %u bytes into dhcp->msg_in[]\n", i));\r
+  if (dhcp->options_in != NULL) {\r
+    ptr = (u8_t *)dhcp->options_in;\r
+    /* proceed through options */\r
+    for (i = 0; i < dhcp->options_in_len; i++) {\r
+      *ptr++ = ((u8_t *)p->payload)[j++];\r
+      /* reached end of pbuf? */\r
+      if (j == p->len) {\r
+        /* proceed to next pbuf in chain */\r
+        p = p->next;\r
+        j = 0;\r
+      }\r
+    }\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_unfold_reply(): copied %u bytes to dhcp->options_in[]\n", i));\r
+  }\r
+  return ERR_OK;\r
+}\r
+\r
+/**\r
+ * Free the incoming DHCP message including contiguous copy of\r
+ * its DHCP options.\r
+ *\r
+ */\r
+static void dhcp_free_reply(struct dhcp *dhcp)\r
+{\r
+  if (dhcp->msg_in != NULL) {\r
+    mem_free((void *)dhcp->msg_in);\r
+    dhcp->msg_in = NULL;\r
+  }\r
+  if (dhcp->options_in) {\r
+    mem_free((void *)dhcp->options_in);\r
+    dhcp->options_in = NULL;\r
+    dhcp->options_in_len = 0;\r
+  }\r
+  LWIP_DEBUGF(DHCP_DEBUG, ("dhcp_free_reply(): free'd\n"));\r
+}\r
+\r
+\r
+/**\r
+ * If an incoming DHCP message is in response to us, then trigger the state machine\r
+ */\r
+static void dhcp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u16_t port)\r
+{\r
+  struct netif *netif = (struct netif *)arg;\r
+  struct dhcp *dhcp = netif->dhcp;\r
+  struct dhcp_msg *reply_msg = (struct dhcp_msg *)p->payload;\r
+  u8_t *options_ptr;\r
+  u8_t msg_type;\r
+  u8_t i;\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_recv(pbuf = %p) from DHCP server %u.%u.%u.%u port %u\n", p,\r
+    (unsigned int)(ntohl(addr->addr) >> 24 & 0xff), (unsigned int)(ntohl(addr->addr) >> 16 & 0xff),\r
+    (unsigned int)(ntohl(addr->addr) >>  8 & 0xff), (unsigned int)(ntohl(addr->addr) & 0xff), port));\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("pbuf->len = %u\n", p->len));\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("pbuf->tot_len = %u\n", p->tot_len));\r
+  /* prevent warnings about unused arguments */\r
+  (void)pcb; (void)addr; (void)port;\r
+  dhcp->p = p;\r
+  /* TODO: check packet length before reading them */\r
+  if (reply_msg->op != DHCP_BOOTREPLY) {\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 1, ("not a DHCP reply message, but type %u\n", reply_msg->op));\r
+    pbuf_free(p);\r
+    dhcp->p = NULL;\r
+    return;\r
+  }\r
+  /* iterate through hardware address and match against DHCP message */\r
+  for (i = 0; i < netif->hwaddr_len; i++) {\r
+    if (netif->hwaddr[i] != reply_msg->chaddr[i]) {\r
+      LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("netif->hwaddr[%u]==%02x != reply_msg->chaddr[%u]==%02x\n",\r
+        i, netif->hwaddr[i], i, reply_msg->chaddr[i]));\r
+      pbuf_free(p);\r
+      dhcp->p = NULL;\r
+      return;\r
+    }\r
+  }\r
+  /* match transaction ID against what we expected */\r
+  if (ntohl(reply_msg->xid) != dhcp->xid) {\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("transaction id mismatch\n"));\r
+    pbuf_free(p);\r
+    dhcp->p = NULL;\r
+    return;\r
+  }\r
+  /* option fields could be unfold? */\r
+  if (dhcp_unfold_reply(dhcp) != ERR_OK) {\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("problem unfolding DHCP message - too short on memory?\n"));\r
+    pbuf_free(p);\r
+    dhcp->p = NULL;\r
+    return;\r
+  }\r
+\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("searching DHCP_OPTION_MESSAGE_TYPE\n"));\r
+  /* obtain pointer to DHCP message type */\r
+  options_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_MESSAGE_TYPE);\r
+  if (options_ptr == NULL) {\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 1, ("DHCP_OPTION_MESSAGE_TYPE option not found\n"));\r
+    pbuf_free(p);\r
+    dhcp->p = NULL;\r
+    return;\r
+  }\r
+\r
+  /* read DHCP message type */\r
+  msg_type = dhcp_get_option_byte(options_ptr + 2);\r
+  /* message type is DHCP ACK? */\r
+  if (msg_type == DHCP_ACK) {\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 1, ("DHCP_ACK received\n"));\r
+    /* in requesting state? */\r
+    if (dhcp->state == DHCP_REQUESTING) {\r
+      dhcp_handle_ack(netif);\r
+      dhcp->request_timeout = 0;\r
+#if DHCP_DOES_ARP_CHECK\r
+      /* check if the acknowledged lease address is already in use */\r
+      dhcp_check(netif);\r
+#else\r
+      /* bind interface to the acknowledged lease address */\r
+      dhcp_bind(netif);\r
+#endif\r
+    }\r
+    /* already bound to the given lease address? */\r
+    else if ((dhcp->state == DHCP_REBOOTING) || (dhcp->state == DHCP_REBINDING) || (dhcp->state == DHCP_RENEWING)) {\r
+      dhcp->request_timeout = 0;\r
+      dhcp_bind(netif);\r
+    }\r
+  }\r
+  /* received a DHCP_NAK in appropriate state? */\r
+  else if ((msg_type == DHCP_NAK) &&\r
+    ((dhcp->state == DHCP_REBOOTING) || (dhcp->state == DHCP_REQUESTING) ||\r
+     (dhcp->state == DHCP_REBINDING) || (dhcp->state == DHCP_RENEWING  ))) {\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 1, ("DHCP_NAK received\n"));\r
+    dhcp->request_timeout = 0;\r
+    dhcp_handle_nak(netif);\r
+  }\r
+  /* received a DHCP_OFFER in DHCP_SELECTING state? */\r
+  else if ((msg_type == DHCP_OFFER) && (dhcp->state == DHCP_SELECTING)) {\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 1, ("DHCP_OFFER received in DHCP_SELECTING state\n"));\r
+    dhcp->request_timeout = 0;\r
+    /* remember offered lease */\r
+    dhcp_handle_offer(netif);\r
+  }\r
+  pbuf_free(p);\r
+  dhcp->p = NULL;\r
+}\r
+\r
+\r
+static err_t dhcp_create_request(struct netif *netif)\r
+{\r
+  struct dhcp *dhcp = netif->dhcp;\r
+  u16_t i;\r
+  LWIP_ASSERT("dhcp_create_request: dhcp->p_out == NULL", dhcp->p_out == NULL);\r
+  LWIP_ASSERT("dhcp_create_request: dhcp->msg_out == NULL", dhcp->msg_out == NULL);\r
+  dhcp->p_out = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct dhcp_msg), PBUF_RAM);\r
+  if (dhcp->p_out == NULL) {\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_create_request(): could not allocate pbuf\n"));\r
+    return ERR_MEM;\r
+  }\r
+  /* give unique transaction identifier to this request */\r
+  dhcp->xid = xid++;\r
+\r
+  dhcp->msg_out = (struct dhcp_msg *)dhcp->p_out->payload;\r
+\r
+  dhcp->msg_out->op = DHCP_BOOTREQUEST;\r
+  /* TODO: make link layer independent */\r
+  dhcp->msg_out->htype = DHCP_HTYPE_ETH;\r
+  /* TODO: make link layer independent */\r
+  dhcp->msg_out->hlen = DHCP_HLEN_ETH;\r
+  dhcp->msg_out->hops = 0;\r
+  dhcp->msg_out->xid = htonl(dhcp->xid);\r
+  dhcp->msg_out->secs = 0;\r
+  dhcp->msg_out->flags = 0;\r
+  dhcp->msg_out->ciaddr.addr = netif->ip_addr.addr;\r
+  dhcp->msg_out->yiaddr.addr = 0;\r
+  dhcp->msg_out->siaddr.addr = 0;\r
+  dhcp->msg_out->giaddr.addr = 0;\r
+  for (i = 0; i < DHCP_CHADDR_LEN; i++) {\r
+    /* copy netif hardware address, pad with zeroes */\r
+    dhcp->msg_out->chaddr[i] = (i < netif->hwaddr_len) ? netif->hwaddr[i] : 0/* pad byte*/;\r
+  }\r
+  for (i = 0; i < DHCP_SNAME_LEN; i++) dhcp->msg_out->sname[i] = 0;\r
+  for (i = 0; i < DHCP_FILE_LEN; i++) dhcp->msg_out->file[i] = 0;\r
+  dhcp->msg_out->cookie = htonl(0x63825363UL);\r
+  dhcp->options_out_len = 0;\r
+  /* fill options field with an incrementing array (for debugging purposes) */\r
+  for (i = 0; i < DHCP_OPTIONS_LEN; i++) dhcp->msg_out->options[i] = i;\r
+  return ERR_OK;\r
+}\r
+\r
+static void dhcp_delete_request(struct netif *netif)\r
+{\r
+  struct dhcp *dhcp = netif->dhcp;\r
+  LWIP_ASSERT("dhcp_free_msg: dhcp->p_out != NULL", dhcp->p_out != NULL);\r
+  LWIP_ASSERT("dhcp_free_msg: dhcp->msg_out != NULL", dhcp->msg_out != NULL);\r
+  pbuf_free(dhcp->p_out);\r
+  dhcp->p_out = NULL;\r
+  dhcp->msg_out = NULL;\r
+}\r
+\r
+/**\r
+ * Add a DHCP message trailer\r
+ *\r
+ * Adds the END option to the DHCP message, and if\r
+ * necessary, up to three padding bytes.\r
+ */\r
+\r
+static void dhcp_option_trailer(struct dhcp *dhcp)\r
+{\r
+  LWIP_ASSERT("dhcp_option_trailer: dhcp->msg_out != NULL\n", dhcp->msg_out != NULL);\r
+  LWIP_ASSERT("dhcp_option_trailer: dhcp->options_out_len < DHCP_OPTIONS_LEN\n", dhcp->options_out_len < DHCP_OPTIONS_LEN);\r
+  dhcp->msg_out->options[dhcp->options_out_len++] = DHCP_OPTION_END;\r
+  /* packet is too small, or not 4 byte aligned? */\r
+  while ((dhcp->options_out_len < DHCP_MIN_OPTIONS_LEN) || (dhcp->options_out_len & 3)) {\r
+    /* LWIP_DEBUGF(DHCP_DEBUG, ("dhcp_option_trailer: dhcp->options_out_len=%u, DHCP_OPTIONS_LEN=%u", dhcp->options_out_len, DHCP_OPTIONS_LEN)); */\r
+    LWIP_ASSERT("dhcp_option_trailer: dhcp->options_out_len < DHCP_OPTIONS_LEN\n", dhcp->options_out_len < DHCP_OPTIONS_LEN);\r
+    /* add a fill/padding byte */\r
+    dhcp->msg_out->options[dhcp->options_out_len++] = 0;\r
+  }\r
+}\r
+\r
+/**\r
+ * Find the offset of a DHCP option inside the DHCP message.\r
+ *\r
+ * @param client DHCP client\r
+ * @param option_type\r
+ *\r
+ * @return a byte offset into the UDP message where the option was found, or\r
+ * zero if the given option was not found.\r
+ */\r
+static u8_t *dhcp_get_option_ptr(struct dhcp *dhcp, u8_t option_type)\r
+{\r
+  u8_t overload = DHCP_OVERLOAD_NONE;\r
+\r
+  /* options available? */\r
+  if ((dhcp->options_in != NULL) && (dhcp->options_in_len > 0)) {\r
+    /* start with options field */\r
+    u8_t *options = (u8_t *)dhcp->options_in;\r
+    u16_t offset = 0;\r
+    /* at least 1 byte to read and no end marker, then at least 3 bytes to read? */\r
+    while ((offset < dhcp->options_in_len) && (options[offset] != DHCP_OPTION_END)) {\r
+      /* LWIP_DEBUGF(DHCP_DEBUG, ("msg_offset=%u, q->len=%u", msg_offset, q->len)); */\r
+      /* are the sname and/or file field overloaded with options? */\r
+      if (options[offset] == DHCP_OPTION_OVERLOAD) {\r
+        LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("overloaded message detected\n"));\r
+        /* skip option type and length */\r
+        offset += 2;\r
+        overload = options[offset++];\r
+      }\r
+      /* requested option found */\r
+      else if (options[offset] == option_type) {\r
+        LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("option found at offset %u in options\n", offset));\r
+        return &options[offset];\r
+      /* skip option */\r
+      } else {\r
+         LWIP_DEBUGF(DHCP_DEBUG, ("skipping option %u in options\n", options[offset]));\r
+        /* skip option type */\r
+        offset++;\r
+        /* skip option length, and then length bytes */\r
+        offset += 1 + options[offset];\r
+      }\r
+    }\r
+    /* is this an overloaded message? */\r
+    if (overload != DHCP_OVERLOAD_NONE) {\r
+      u16_t field_len;\r
+      if (overload == DHCP_OVERLOAD_FILE) {\r
+        LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 1, ("overloaded file field\n"));\r
+        options = (u8_t *)&dhcp->msg_in->file;\r
+        field_len = DHCP_FILE_LEN;\r
+      } else if (overload == DHCP_OVERLOAD_SNAME) {\r
+        LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 1, ("overloaded sname field\n"));\r
+        options = (u8_t *)&dhcp->msg_in->sname;\r
+        field_len = DHCP_SNAME_LEN;\r
+      /* TODO: check if else if () is necessary */\r
+      } else {\r
+        LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 1, ("overloaded sname and file field\n"));\r
+        options = (u8_t *)&dhcp->msg_in->sname;\r
+        field_len = DHCP_FILE_LEN + DHCP_SNAME_LEN;\r
+      }\r
+      offset = 0;\r
+\r
+      /* at least 1 byte to read and no end marker */\r
+      while ((offset < field_len) && (options[offset] != DHCP_OPTION_END)) {\r
+        if (options[offset] == option_type) {\r
+           LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("option found at offset=%u\n", offset));\r
+          return &options[offset];\r
+        /* skip option */\r
+        } else {\r
+          LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("skipping option %u\n", options[offset]));\r
+          /* skip option type */\r
+          offset++;\r
+          offset += 1 + options[offset];\r
+        }\r
+      }\r
+    }\r
+  }\r
+  return 0;\r
+}\r
+\r
+/**\r
+ * Return the byte of DHCP option data.\r
+ *\r
+ * @param client DHCP client.\r
+ * @param ptr pointer obtained by dhcp_get_option_ptr().\r
+ *\r
+ * @return byte value at the given address.\r
+ */\r
+static u8_t dhcp_get_option_byte(u8_t *ptr)\r
+{\r
+  LWIP_DEBUGF(DHCP_DEBUG, ("option byte value=%u\n", *ptr));\r
+  return *ptr;\r
+}\r
+\r
+/**\r
+ * Return the 16-bit value of DHCP option data.\r
+ *\r
+ * @param client DHCP client.\r
+ * @param ptr pointer obtained by dhcp_get_option_ptr().\r
+ *\r
+ * @return byte value at the given address.\r
+ */\r
+static u16_t dhcp_get_option_short(u8_t *ptr)\r
+{\r
+  u16_t value;\r
+  value = *ptr++ << 8;\r
+  value |= *ptr;\r
+  LWIP_DEBUGF(DHCP_DEBUG, ("option short value=%u\n", value));\r
+  return value;\r
+}\r
+\r
+/**\r
+ * Return the 32-bit value of DHCP option data.\r
+ *\r
+ * @param client DHCP client.\r
+ * @param ptr pointer obtained by dhcp_get_option_ptr().\r
+ *\r
+ * @return byte value at the given address.\r
+ */\r
+static u32_t dhcp_get_option_long(u8_t *ptr)\r
+{\r
+  u32_t value;\r
+  value = (u32_t)(*ptr++) << 24;\r
+  value |= (u32_t)(*ptr++) << 16;\r
+  value |= (u32_t)(*ptr++) << 8;\r
+  value |= (u32_t)(*ptr++);\r
+  LWIP_DEBUGF(DHCP_DEBUG, ("option long value=%lu\n", value));\r
+  return value;\r
+}\r
+\r
+#endif /* LWIP_DHCP */\r
index 59c80ea48c4ceb7f6fcace5882ee70b68494b56a..8b02cada3509e071d142430f66e2e9ec829edc97 100644 (file)
-/*
- * 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 <adam@sics.se>
- *
- */
-
-
-/* inet.c
- *
- * Functions common to all TCP/IP modules, such as the Internet checksum and the
- * byte order functions.
- *
- */
-
-
-#include "lwip/opt.h"
-
-#include "lwip/arch.h"
-
-#include "lwip/def.h"
-#include "lwip/inet.h"
-
-#include "lwip/sys.h"
-
-/* This is a reference implementation of the checksum algorithm
-
- - it may not work on all architectures, and all processors, particularly
-   if they have issues with alignment and 16 bit access.
-
- - in this case you will need to port it to your architecture and 
-   #define LWIP_CHKSUM <your_checksum_routine> 
-   in your sys_arch.h
-*/
-#ifndef LWIP_CHKSUM
-#define LWIP_CHKSUM lwip_standard_chksum
-static u16_t
-lwip_standard_chksum(void *dataptr, int len)
-{
-  u32_t acc;
-
-  LWIP_DEBUGF(INET_DEBUG, ("lwip_chksum(%p, %d)\n", (void *)dataptr, len));
-  for(acc = 0; len > 1; len -= 2) {
-      /*    acc = acc + *((u16_t *)dataptr)++;*/
-    acc += *(u16_t *)dataptr;
-    dataptr = (void *)((u16_t *)dataptr + 1);
-  }
-
-  /* add up any odd byte */
-  if (len == 1) {
-    acc += htons((u16_t)((*(u8_t *)dataptr) & 0xff) << 8);
-    LWIP_DEBUGF(INET_DEBUG, ("inet: chksum: odd byte %d\n", (unsigned int)(*(u8_t *)dataptr)));
-  } else {
-    LWIP_DEBUGF(INET_DEBUG, ("inet: chksum: no odd byte\n"));
-  }
-  acc = (acc >> 16) + (acc & 0xffffUL);
-
-  if ((acc & 0xffff0000) != 0) {
-    acc = (acc >> 16) + (acc & 0xffffUL);
-  }
-
-  return (u16_t)acc;
-}
-#endif
-
-/* inet_chksum_pseudo:
- *
- * Calculates the pseudo Internet checksum used by TCP and UDP for a pbuf chain.
- */
-
-u16_t
-inet_chksum_pseudo(struct pbuf *p,
-       struct ip_addr *src, struct ip_addr *dest,
-       u8_t proto, u16_t proto_len)
-{
-  u32_t acc;
-  struct pbuf *q;
-  u8_t swapped;
-
-  acc = 0;
-  swapped = 0;
-  /* iterate through all pbuf in chain */
-  for(q = p; q != NULL; q = q->next) {
-    LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): checksumming pbuf %p (has next %p) \n",
-      (void *)q, (void *)q->next));
-    acc += LWIP_CHKSUM(q->payload, q->len);
-    /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): unwrapped lwip_chksum()=%lx \n", acc));*/
-    while (acc >> 16) {
-      acc = (acc & 0xffffUL) + (acc >> 16);
-    }
-    if (q->len % 2 != 0) {
-      swapped = 1 - swapped;
-      acc = ((acc & 0xff) << 8) | ((acc & 0xff00UL) >> 8);
-    }
-    /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): wrapped lwip_chksum()=%lx \n", acc));*/
-  }
-
-  if (swapped) {
-    acc = ((acc & 0xff) << 8) | ((acc & 0xff00UL) >> 8);
-  }
-  acc += (src->addr & 0xffffUL);
-  acc += ((src->addr >> 16) & 0xffffUL);
-  acc += (dest->addr & 0xffffUL);
-  acc += ((dest->addr >> 16) & 0xffffUL);
-  acc += (u32_t)htons((u16_t)proto);
-  acc += (u32_t)htons(proto_len);
-
-  while (acc >> 16) {
-    acc = (acc & 0xffffUL) + (acc >> 16);
-  }
-  LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): pbuf chain lwip_chksum()=%lx\n", acc));
-  return (u16_t)~(acc & 0xffffUL);
-}
-
-/* inet_chksum:
- *
- * Calculates the Internet checksum over a portion of memory. Used primarely for IP
- * and ICMP.
- */
-
-u16_t
-inet_chksum(void *dataptr, u16_t len)
-{
-  u32_t acc;
-
-  acc = LWIP_CHKSUM(dataptr, len);
-  while (acc >> 16) {
-    acc = (acc & 0xffff) + (acc >> 16);
-  }
-  return (u16_t)~(acc & 0xffff);
-}
-
-u16_t
-inet_chksum_pbuf(struct pbuf *p)
-{
-  u32_t acc;
-  struct pbuf *q;
-  u8_t swapped;
-
-  acc = 0;
-  swapped = 0;
-  for(q = p; q != NULL; q = q->next) {
-    acc += LWIP_CHKSUM(q->payload, q->len);
-    while (acc >> 16) {
-      acc = (acc & 0xffffUL) + (acc >> 16);
-    }
-    if (q->len % 2 != 0) {
-      swapped = 1 - swapped;
-      acc = (acc & 0x00ffUL << 8) | (acc & 0xff00UL >> 8);
-    }
-  }
-
-  if (swapped) {
-    acc = ((acc & 0x00ffUL) << 8) | ((acc & 0xff00UL) >> 8);
-  }
-  return (u16_t)~(acc & 0xffffUL);
-}
-
-/* Here for now until needed in other places in lwIP */
-#ifndef isascii
-#define in_range(c, lo, up)  ((u8_t)c >= lo && (u8_t)c <= up)
-#define isascii(c)           in_range(c, 0x20, 0x7f)
-#define isdigit(c)           in_range(c, '0', '9')
-#define isxdigit(c)          (isdigit(c) || in_range(c, 'a', 'f') || in_range(c, 'A', 'F'))
-#define islower(c)           in_range(c, 'a', 'z')
-#define isspace(c)           (c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v')
-#endif         
-               
-
- /*
-  * Ascii internet address interpretation routine.
-  * The value returned is in network order.
-  */
-
- /*  */
- /* inet_addr */
- u32_t inet_addr(const char *cp)
- {
-     struct in_addr val;
-
-     if (inet_aton(cp, &val)) {
-         return (val.s_addr);
-     }
-     return (INADDR_NONE);
- }
-
- /*
-  * Check whether "cp" is a valid ascii representation
-  * of an Internet address and convert to a binary address.
-  * Returns 1 if the address is valid, 0 if not.
-  * This replaces inet_addr, the return value from which
-  * cannot distinguish between failure and a local broadcast address.
-  */
- /*  */
- /* inet_aton */
- int inet_aton(const char *cp, struct in_addr *addr)
- {
-     u32_t val;
-     int base, n;
-     char c;
-     u32_t parts[4];
-     u32_t* pp = parts;
-
-     c = *cp;
-     for (;;) {
-         /*
-          * Collect number up to ``.''.
-          * Values are specified as for C:
-          * 0x=hex, 0=octal, isdigit=decimal.
-          */
-         if (!isdigit(c))
-             return (0);
-         val = 0; base = 10;
-         if (c == '0') {
-             c = *++cp;
-             if (c == 'x' || c == 'X')
-                 base = 16, c = *++cp;
-             else
-                 base = 8;
-         }
-         for (;;) {
-             if (isdigit(c)) {
-                 val = (val * base) + (int)(c - '0');
-                 c = *++cp;
-             } else if (base == 16 && isxdigit(c)) {
-                 val = (val << 4) |
-                     (int)(c + 10 - (islower(c) ? 'a' : 'A'));
-                 c = *++cp;
-             } else
-             break;
-         }
-         if (c == '.') {
-             /*
-              * Internet format:
-              *  a.b.c.d
-              *  a.b.c   (with c treated as 16 bits)
-              *  a.b (with b treated as 24 bits)
-              */
-             if (pp >= parts + 3)
-                 return (0);
-             *pp++ = val;
-             c = *++cp;
-         } else
-             break;
-     }
-     /*
-      * Check for trailing characters.
-      */
-     if (c != '\0' && (!isascii(c) || !isspace(c)))
-         return (0);
-     /*
-      * Concoct the address according to
-      * the number of parts specified.
-      */
-     n = pp - parts + 1;
-     switch (n) {
-
-     case 0:
-         return (0);     /* initial nondigit */
-
-     case 1:             /* a -- 32 bits */
-         break;
-
-     case 2:             /* a.b -- 8.24 bits */
-         if (val > 0xffffff)
-             return (0);
-         val |= parts[0] << 24;
-         break;
-
-     case 3:             /* a.b.c -- 8.8.16 bits */
-         if (val > 0xffff)
-             return (0);
-         val |= (parts[0] << 24) | (parts[1] << 16);
-         break;
-
-     case 4:             /* a.b.c.d -- 8.8.8.8 bits */
-         if (val > 0xff)
-             return (0);
-         val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
-         break;
-     }
-     if (addr)
-         addr->s_addr = htonl(val);
-     return (1);
- }
-
-/* Convert numeric IP address into decimal dotted ASCII representation.
- * returns ptr to static buffer; not reentrant!
- */
-char *inet_ntoa(struct in_addr addr)
-{
-  static char str[16];
-  u32_t s_addr = addr.s_addr;
-  char inv[3];
-  char *rp;
-  u8_t *ap;
-  u8_t rem;
-  u8_t n;
-  u8_t i;
-
-  rp = str;
-  ap = (u8_t *)&s_addr;
-  for(n = 0; n < 4; n++) {
-    i = 0;
-    do {
-      rem = *ap % (u8_t)10;
-      *ap /= (u8_t)10;
-      inv[i++] = '0' + rem;
-    } while(*ap);
-    while(i--)
-      *rp++ = inv[i];
-    *rp++ = '.';
-    ap++;
-  }
-  *--rp = 0;
-  return str;
-}
-
-
-#ifndef BYTE_ORDER
-#error BYTE_ORDER is not defined
-#endif
-#if BYTE_ORDER == LITTLE_ENDIAN
-
-u16_t
-htons(u16_t n)
-{
-  return ((n & 0xff) << 8) | ((n & 0xff00) >> 8);
-}
-
-u16_t
-ntohs(u16_t n)
-{
-  return htons(n);
-}
-
-u32_t
-htonl(u32_t n)
-{
-  return ((n & 0xff) << 24) |
-    ((n & 0xff00) << 8) |
-    ((n & 0xff0000) >> 8) |
-    ((n & 0xff000000) >> 24);
-}
-
-u32_t
-ntohl(u32_t n)
-{
-  return htonl(n);
-}
-
-#endif /* BYTE_ORDER == LITTLE_ENDIAN */
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without modification,\r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED\r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT\r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY\r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ *\r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+\r
+\r
+/* inet.c\r
+ *\r
+ * Functions common to all TCP/IP modules, such as the Internet checksum and the\r
+ * byte order functions.\r
+ *\r
+ */\r
+\r
+\r
+#include "lwip/opt.h"\r
+\r
+#include "lwip/arch.h"\r
+\r
+#include "lwip/def.h"\r
+#include "lwip/inet.h"\r
+\r
+#include "lwip/sys.h"\r
+\r
+/* This is a reference implementation of the checksum algorithm\r
+\r
+ - it may not work on all architectures, and all processors, particularly\r
+   if they have issues with alignment and 16 bit access.\r
+\r
+ - in this case you will need to port it to your architecture and \r
+   #define LWIP_CHKSUM <your_checksum_routine> \r
+   in your sys_arch.h\r
+*/\r
+#ifndef LWIP_CHKSUM\r
+#define LWIP_CHKSUM lwip_standard_chksum\r
+static u16_t\r
+lwip_standard_chksum(void *dataptr, int len)\r
+{\r
+  u32_t acc;\r
+\r
+  LWIP_DEBUGF(INET_DEBUG, ("lwip_chksum(%p, %d)\n", (void *)dataptr, len));\r
+  for(acc = 0; len > 1; len -= 2) {\r
+      /*    acc = acc + *((u16_t *)dataptr)++;*/\r
+    acc += *(u16_t *)dataptr;\r
+    dataptr = (void *)((u16_t *)dataptr + 1);\r
+  }\r
+\r
+  /* add up any odd byte */\r
+  if (len == 1) {\r
+    acc += htons((u16_t)((*(u8_t *)dataptr) & 0xff) << 8);\r
+    LWIP_DEBUGF(INET_DEBUG, ("inet: chksum: odd byte %d\n", (unsigned int)(*(u8_t *)dataptr)));\r
+  } else {\r
+    LWIP_DEBUGF(INET_DEBUG, ("inet: chksum: no odd byte\n"));\r
+  }\r
+  acc = (acc >> 16) + (acc & 0xffffUL);\r
+\r
+  if ((acc & 0xffff0000) != 0) {\r
+    acc = (acc >> 16) + (acc & 0xffffUL);\r
+  }\r
+\r
+  return (u16_t)acc;\r
+}\r
+#endif\r
+\r
+/* inet_chksum_pseudo:\r
+ *\r
+ * Calculates the pseudo Internet checksum used by TCP and UDP for a pbuf chain.\r
+ */\r
+\r
+u16_t\r
+inet_chksum_pseudo(struct pbuf *p,\r
+       struct ip_addr *src, struct ip_addr *dest,\r
+       u8_t proto, u16_t proto_len)\r
+{\r
+  u32_t acc;\r
+  struct pbuf *q;\r
+  u8_t swapped;\r
+\r
+  acc = 0;\r
+  swapped = 0;\r
+  /* iterate through all pbuf in chain */\r
+  for(q = p; q != NULL; q = q->next) {\r
+    LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): checksumming pbuf %p (has next %p) \n",\r
+      (void *)q, (void *)q->next));\r
+    acc += LWIP_CHKSUM(q->payload, q->len);\r
+    /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): unwrapped lwip_chksum()=%lx \n", acc));*/\r
+    while (acc >> 16) {\r
+      acc = (acc & 0xffffUL) + (acc >> 16);\r
+    }\r
+    if (q->len % 2 != 0) {\r
+      swapped = 1 - swapped;\r
+      acc = ((acc & 0xff) << 8) | ((acc & 0xff00UL) >> 8);\r
+    }\r
+    /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): wrapped lwip_chksum()=%lx \n", acc));*/\r
+  }\r
+\r
+  if (swapped) {\r
+    acc = ((acc & 0xff) << 8) | ((acc & 0xff00UL) >> 8);\r
+  }\r
+  acc += (src->addr & 0xffffUL);\r
+  acc += ((src->addr >> 16) & 0xffffUL);\r
+  acc += (dest->addr & 0xffffUL);\r
+  acc += ((dest->addr >> 16) & 0xffffUL);\r
+  acc += (u32_t)htons((u16_t)proto);\r
+  acc += (u32_t)htons(proto_len);\r
+\r
+  while (acc >> 16) {\r
+    acc = (acc & 0xffffUL) + (acc >> 16);\r
+  }\r
+  LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): pbuf chain lwip_chksum()=%lx\n", acc));\r
+  return (u16_t)~(acc & 0xffffUL);\r
+}\r
+\r
+/* inet_chksum:\r
+ *\r
+ * Calculates the Internet checksum over a portion of memory. Used primarely for IP\r
+ * and ICMP.\r
+ */\r
+\r
+u16_t\r
+inet_chksum(void *dataptr, u16_t len)\r
+{\r
+  u32_t acc;\r
+\r
+  acc = LWIP_CHKSUM(dataptr, len);\r
+  while (acc >> 16) {\r
+    acc = (acc & 0xffff) + (acc >> 16);\r
+  }\r
+  return (u16_t)~(acc & 0xffff);\r
+}\r
+\r
+u16_t\r
+inet_chksum_pbuf(struct pbuf *p)\r
+{\r
+  u32_t acc;\r
+  struct pbuf *q;\r
+  u8_t swapped;\r
+\r
+  acc = 0;\r
+  swapped = 0;\r
+  for(q = p; q != NULL; q = q->next) {\r
+    acc += LWIP_CHKSUM(q->payload, q->len);\r
+    while (acc >> 16) {\r
+      acc = (acc & 0xffffUL) + (acc >> 16);\r
+    }\r
+    if (q->len % 2 != 0) {\r
+      swapped = 1 - swapped;\r
+      acc = (acc & 0x00ffUL << 8) | (acc & 0xff00UL >> 8);\r
+    }\r
+  }\r
+\r
+  if (swapped) {\r
+    acc = ((acc & 0x00ffUL) << 8) | ((acc & 0xff00UL) >> 8);\r
+  }\r
+  return (u16_t)~(acc & 0xffffUL);\r
+}\r
+\r
+/* Here for now until needed in other places in lwIP */\r
+#ifndef isascii\r
+#define in_range(c, lo, up)  ((u8_t)c >= lo && (u8_t)c <= up)\r
+#define isascii(c)           in_range(c, 0x20, 0x7f)\r
+#define isdigit(c)           in_range(c, '0', '9')\r
+#define isxdigit(c)          (isdigit(c) || in_range(c, 'a', 'f') || in_range(c, 'A', 'F'))\r
+#define islower(c)           in_range(c, 'a', 'z')\r
+#define isspace(c)           (c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v')\r
+#endif         \r
+               \r
+\r
+ /*\r
+  * Ascii internet address interpretation routine.\r
+  * The value returned is in network order.\r
+  */\r
+\r
+ /*  */\r
+ /* inet_addr */\r
+ u32_t inet_addr(const char *cp)\r
+ {\r
+     struct in_addr val;\r
+\r
+     if (inet_aton(cp, &val)) {\r
+         return (val.s_addr);\r
+     }\r
+     return (INADDR_NONE);\r
+ }\r
+\r
+ /*\r
+  * Check whether "cp" is a valid ascii representation\r
+  * of an Internet address and convert to a binary address.\r
+  * Returns 1 if the address is valid, 0 if not.\r
+  * This replaces inet_addr, the return value from which\r
+  * cannot distinguish between failure and a local broadcast address.\r
+  */\r
+ /*  */\r
+ /* inet_aton */\r
+ int inet_aton(const char *cp, struct in_addr *addr)\r
+ {\r
+     u32_t val;\r
+     int base, n;\r
+     char c;\r
+     u32_t parts[4];\r
+     u32_t* pp = parts;\r
+\r
+     c = *cp;\r
+     for (;;) {\r
+         /*\r
+          * Collect number up to ``.''.\r
+          * Values are specified as for C:\r
+          * 0x=hex, 0=octal, isdigit=decimal.\r
+          */\r
+         if (!isdigit(c))\r
+             return (0);\r
+         val = 0; base = 10;\r
+         if (c == '0') {\r
+             c = *++cp;\r
+             if (c == 'x' || c == 'X')\r
+                 base = 16, c = *++cp;\r
+             else\r
+                 base = 8;\r
+         }\r
+         for (;;) {\r
+             if (isdigit(c)) {\r
+                 val = (val * base) + (int)(c - '0');\r
+                 c = *++cp;\r
+             } else if (base == 16 && isxdigit(c)) {\r
+                 val = (val << 4) |\r
+                     (int)(c + 10 - (islower(c) ? 'a' : 'A'));\r
+                 c = *++cp;\r
+             } else\r
+             break;\r
+         }\r
+         if (c == '.') {\r
+             /*\r
+              * Internet format:\r
+              *  a.b.c.d\r
+              *  a.b.c   (with c treated as 16 bits)\r
+              *  a.b (with b treated as 24 bits)\r
+              */\r
+             if (pp >= parts + 3)\r
+                 return (0);\r
+             *pp++ = val;\r
+             c = *++cp;\r
+         } else\r
+             break;\r
+     }\r
+     /*\r
+      * Check for trailing characters.\r
+      */\r
+     if (c != '\0' && (!isascii(c) || !isspace(c)))\r
+         return (0);\r
+     /*\r
+      * Concoct the address according to\r
+      * the number of parts specified.\r
+      */\r
+     n = pp - parts + 1;\r
+     switch (n) {\r
+\r
+     case 0:\r
+         return (0);     /* initial nondigit */\r
+\r
+     case 1:             /* a -- 32 bits */\r
+         break;\r
+\r
+     case 2:             /* a.b -- 8.24 bits */\r
+         if (val > 0xffffff)\r
+             return (0);\r
+         val |= parts[0] << 24;\r
+         break;\r
+\r
+     case 3:             /* a.b.c -- 8.8.16 bits */\r
+         if (val > 0xffff)\r
+             return (0);\r
+         val |= (parts[0] << 24) | (parts[1] << 16);\r
+         break;\r
+\r
+     case 4:             /* a.b.c.d -- 8.8.8.8 bits */\r
+         if (val > 0xff)\r
+             return (0);\r
+         val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);\r
+         break;\r
+     }\r
+     if (addr)\r
+         addr->s_addr = htonl(val);\r
+     return (1);\r
+ }\r
+\r
+/* Convert numeric IP address into decimal dotted ASCII representation.\r
+ * returns ptr to static buffer; not reentrant!\r
+ */\r
+char *inet_ntoa(struct in_addr addr)\r
+{\r
+  static char str[16];\r
+  u32_t s_addr = addr.s_addr;\r
+  char inv[3];\r
+  char *rp;\r
+  u8_t *ap;\r
+  u8_t rem;\r
+  u8_t n;\r
+  u8_t i;\r
+\r
+  rp = str;\r
+  ap = (u8_t *)&s_addr;\r
+  for(n = 0; n < 4; n++) {\r
+    i = 0;\r
+    do {\r
+      rem = *ap % (u8_t)10;\r
+      *ap /= (u8_t)10;\r
+      inv[i++] = '0' + rem;\r
+    } while(*ap);\r
+    while(i--)\r
+      *rp++ = inv[i];\r
+    *rp++ = '.';\r
+    ap++;\r
+  }\r
+  *--rp = 0;\r
+  return str;\r
+}\r
+\r
+\r
+#ifndef BYTE_ORDER\r
+#error BYTE_ORDER is not defined\r
+#endif\r
+#if BYTE_ORDER == LITTLE_ENDIAN\r
+\r
+u16_t\r
+htons(u16_t n)\r
+{\r
+  return ((n & 0xff) << 8) | ((n & 0xff00) >> 8);\r
+}\r
+\r
+u16_t\r
+ntohs(u16_t n)\r
+{\r
+  return htons(n);\r
+}\r
+\r
+u32_t\r
+htonl(u32_t n)\r
+{\r
+  return ((n & 0xff) << 24) |\r
+    ((n & 0xff00) << 8) |\r
+    ((n & 0xff0000) >> 8) |\r
+    ((n & 0xff000000) >> 24);\r
+}\r
+\r
+u32_t\r
+ntohl(u32_t n)\r
+{\r
+  return htonl(n);\r
+}\r
+\r
+#endif /* BYTE_ORDER == LITTLE_ENDIAN */\r
index c04915b73d009a6e9be6050231fb60b2b984e5d3..aebc6f381e670a728968465889df3f363d70af12 100644 (file)
-/*
- * 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 <adam@sics.se>
- *
- */
-
-
-/* inet6.c
- *
- * Functions common to all TCP/IP modules, such as the Internet checksum and the
- * byte order functions.
- *
- */
-
-
-#include "lwip/opt.h"
-
-#include "lwip/def.h"
-#include "lwip/inet.h"
-
-
-
-/* chksum:
- *
- * Sums up all 16 bit words in a memory portion. Also includes any odd byte.
- * This function is used by the other checksum functions.
- *
- * For now, this is not optimized. Must be optimized for the particular processor
- * arcitecture on which it is to run. Preferebly coded in assembler.
- */
-
-static u32_t
-chksum(void *dataptr, u16_t len)
-{
-  u16_t *sdataptr = dataptr;
-  u32_t acc;
-  
-  
-  for(acc = 0; len > 1; len -= 2) {
-    acc += *sdataptr++;
-  }
-
-  /* add up any odd byte */
-  if (len == 1) {
-    acc += htons((u16_t)(*(u8_t *)dataptr) << 8);
-  }
-
-  return acc;
-
-}
-
-/* inet_chksum_pseudo:
- *
- * Calculates the pseudo Internet checksum used by TCP and UDP for a pbuf chain.
- */
-
-u16_t
-inet_chksum_pseudo(struct pbuf *p,
-       struct ip_addr *src, struct ip_addr *dest,
-       u8_t proto, u32_t proto_len)
-{
-  u32_t acc;
-  struct pbuf *q;
-  u8_t swapped, i;
-
-  acc = 0;
-  swapped = 0;
-  for(q = p; q != NULL; q = q->next) {    
-    acc += chksum(q->payload, q->len);
-    while (acc >> 16) {
-      acc = (acc & 0xffff) + (acc >> 16);
-    }
-    if (q->len % 2 != 0) {
-      swapped = 1 - swapped;
-      acc = ((acc & 0xff) << 8) | ((acc & 0xff00) >> 8);
-    }
-  }
-
-  if (swapped) {
-    acc = ((acc & 0xff) << 8) | ((acc & 0xff00) >> 8);
-  }
-  
-  for(i = 0; i < 8; i++) {
-    acc += ((u16_t *)src->addr)[i] & 0xffff;
-    acc += ((u16_t *)dest->addr)[i] & 0xffff;
-    while (acc >> 16) {
-      acc = (acc & 0xffff) + (acc >> 16);
-    }
-  }
-  acc += (u16_t)htons((u16_t)proto);
-  acc += ((u16_t *)&proto_len)[0] & 0xffff;
-  acc += ((u16_t *)&proto_len)[1] & 0xffff;
-
-  while (acc >> 16) {
-    acc = (acc & 0xffff) + (acc >> 16);
-  }
-  return ~(acc & 0xffff);
-}
-
-/* inet_chksum:
- *
- * Calculates the Internet checksum over a portion of memory. Used primarely for IP
- * and ICMP.
- */
-
-u16_t
-inet_chksum(void *dataptr, u16_t len)
-{
-  u32_t acc, sum;
-
-  acc = chksum(dataptr, len);
-  sum = (acc & 0xffff) + (acc >> 16);
-  sum += (sum >> 16);
-  return ~(sum & 0xffff);
-}
-
-u16_t
-inet_chksum_pbuf(struct pbuf *p)
-{
-  u32_t acc;
-  struct pbuf *q;
-  u8_t swapped;
-  
-  acc = 0;
-  swapped = 0;
-  for(q = p; q != NULL; q = q->next) {
-    acc += chksum(q->payload, q->len);
-    while (acc >> 16) {
-      acc = (acc & 0xffff) + (acc >> 16);
-    }    
-    if (q->len % 2 != 0) {
-      swapped = 1 - swapped;
-      acc = (acc & 0xff << 8) | (acc & 0xff00 >> 8);
-    }
-  }
-  if (swapped) {
-    acc = ((acc & 0xff) << 8) | ((acc & 0xff00) >> 8);
-  }
-  return ~(acc & 0xffff);
-}
-
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+\r
+\r
+/* inet6.c\r
+ *\r
+ * Functions common to all TCP/IP modules, such as the Internet checksum and the\r
+ * byte order functions.\r
+ *\r
+ */\r
+\r
+\r
+#include "lwip/opt.h"\r
+\r
+#include "lwip/def.h"\r
+#include "lwip/inet.h"\r
+\r
+\r
+\r
+/* chksum:\r
+ *\r
+ * Sums up all 16 bit words in a memory portion. Also includes any odd byte.\r
+ * This function is used by the other checksum functions.\r
+ *\r
+ * For now, this is not optimized. Must be optimized for the particular processor\r
+ * arcitecture on which it is to run. Preferebly coded in assembler.\r
+ */\r
+\r
+static u32_t\r
+chksum(void *dataptr, u16_t len)\r
+{\r
+  u16_t *sdataptr = dataptr;\r
+  u32_t acc;\r
+  \r
+  \r
+  for(acc = 0; len > 1; len -= 2) {\r
+    acc += *sdataptr++;\r
+  }\r
+\r
+  /* add up any odd byte */\r
+  if (len == 1) {\r
+    acc += htons((u16_t)(*(u8_t *)dataptr) << 8);\r
+  }\r
+\r
+  return acc;\r
+\r
+}\r
+\r
+/* inet_chksum_pseudo:\r
+ *\r
+ * Calculates the pseudo Internet checksum used by TCP and UDP for a pbuf chain.\r
+ */\r
+\r
+u16_t\r
+inet_chksum_pseudo(struct pbuf *p,\r
+       struct ip_addr *src, struct ip_addr *dest,\r
+       u8_t proto, u32_t proto_len)\r
+{\r
+  u32_t acc;\r
+  struct pbuf *q;\r
+  u8_t swapped, i;\r
+\r
+  acc = 0;\r
+  swapped = 0;\r
+  for(q = p; q != NULL; q = q->next) {    \r
+    acc += chksum(q->payload, q->len);\r
+    while (acc >> 16) {\r
+      acc = (acc & 0xffff) + (acc >> 16);\r
+    }\r
+    if (q->len % 2 != 0) {\r
+      swapped = 1 - swapped;\r
+      acc = ((acc & 0xff) << 8) | ((acc & 0xff00) >> 8);\r
+    }\r
+  }\r
+\r
+  if (swapped) {\r
+    acc = ((acc & 0xff) << 8) | ((acc & 0xff00) >> 8);\r
+  }\r
+  \r
+  for(i = 0; i < 8; i++) {\r
+    acc += ((u16_t *)src->addr)[i] & 0xffff;\r
+    acc += ((u16_t *)dest->addr)[i] & 0xffff;\r
+    while (acc >> 16) {\r
+      acc = (acc & 0xffff) + (acc >> 16);\r
+    }\r
+  }\r
+  acc += (u16_t)htons((u16_t)proto);\r
+  acc += ((u16_t *)&proto_len)[0] & 0xffff;\r
+  acc += ((u16_t *)&proto_len)[1] & 0xffff;\r
+\r
+  while (acc >> 16) {\r
+    acc = (acc & 0xffff) + (acc >> 16);\r
+  }\r
+  return ~(acc & 0xffff);\r
+}\r
+\r
+/* inet_chksum:\r
+ *\r
+ * Calculates the Internet checksum over a portion of memory. Used primarely for IP\r
+ * and ICMP.\r
+ */\r
+\r
+u16_t\r
+inet_chksum(void *dataptr, u16_t len)\r
+{\r
+  u32_t acc, sum;\r
+\r
+  acc = chksum(dataptr, len);\r
+  sum = (acc & 0xffff) + (acc >> 16);\r
+  sum += (sum >> 16);\r
+  return ~(sum & 0xffff);\r
+}\r
+\r
+u16_t\r
+inet_chksum_pbuf(struct pbuf *p)\r
+{\r
+  u32_t acc;\r
+  struct pbuf *q;\r
+  u8_t swapped;\r
+  \r
+  acc = 0;\r
+  swapped = 0;\r
+  for(q = p; q != NULL; q = q->next) {\r
+    acc += chksum(q->payload, q->len);\r
+    while (acc >> 16) {\r
+      acc = (acc & 0xffff) + (acc >> 16);\r
+    }    \r
+    if (q->len % 2 != 0) {\r
+      swapped = 1 - swapped;\r
+      acc = (acc & 0xff << 8) | (acc & 0xff00 >> 8);\r
+    }\r
+  }\r
\r
+  if (swapped) {\r
+    acc = ((acc & 0xff) << 8) | ((acc & 0xff00) >> 8);\r
+  }\r
+  return ~(acc & 0xffff);\r
+}\r
+\r
index 368d97763c04b281cff9e5ce822db828be466991..3d419c958ea453362aab66632527f532a29bf315 100644 (file)
-/* @file
- *
- * This is the IP layer implementation for incoming and outgoing IP traffic.
- * 
- * @see ip_frag.c
- *
- */
-/*
- * 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 <adam@sics.se>
- *
- */
-
-#include "lwip/opt.h"
-
-#include "lwip/def.h"
-#include "lwip/mem.h"
-#include "lwip/ip.h"
-#include "lwip/ip_frag.h"
-#include "lwip/inet.h"
-#include "lwip/netif.h"
-#include "lwip/icmp.h"
-#include "lwip/raw.h"
-#include "lwip/udp.h"
-#include "lwip/tcp.h"
-
-#include "lwip/stats.h"
-
-#include "arch/perf.h"
-
-#include "lwip/snmp.h"
-#if LWIP_DHCP
-#  include "lwip/dhcp.h"
-#endif /* LWIP_DHCP */
-
-
-/**
- * Initializes the IP layer.
- */
-
-void
-ip_init(void)
-{
-  /* no initializations as of yet */
-}
-
-/**
- * Finds the appropriate network interface for a given IP address. It
- * searches the list of network interfaces linearly. A match is found
- * if the masked IP address of the network interface equals the masked
- * IP address given to the function.
- */
-
-struct netif *
-ip_route(struct ip_addr *dest)
-{
-  struct netif *netif;
-
-  /* iterate through netifs */
-  for(netif = netif_list; netif != NULL; netif = netif->next) {
-    /* network mask matches? */
-    if (ip_addr_netcmp(dest, &(netif->ip_addr), &(netif->netmask))) {
-      /* return netif on which to forward IP packet */
-      return netif;
-    }
-  }
-  /* no matching netif found, use default netif */
-  return netif_default;
-}
-#if IP_FORWARD
-
-/**
- * Forwards an IP packet. It finds an appropriate route for the
- * packet, decrements the TTL value of the packet, adjusts the
- * checksum and outputs the packet on the appropriate interface.
- */
-
-static struct netif *
-ip_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp)
-{
-  struct netif *netif;
-
-  PERF_START;
-  /* Find network interface where to forward this IP packet to. */
-  netif = ip_route((struct ip_addr *)&(iphdr->dest));
-  if (netif == NULL) {
-    LWIP_DEBUGF(IP_DEBUG, ("ip_forward: no forwarding route for 0x%lx found\n",
-                      iphdr->dest.addr));
-    snmp_inc_ipnoroutes();
-    return (struct netif *)NULL;
-  }
-  /* Do not forward packets onto the same network interface on which
-   * they arrived. */
-  if (netif == inp) {
-    LWIP_DEBUGF(IP_DEBUG, ("ip_forward: not bouncing packets back on incoming interface.\n"));
-    snmp_inc_ipnoroutes();
-    return (struct netif *)NULL;
-  }
-
-  /* decrement TTL */
-  IPH_TTL_SET(iphdr, IPH_TTL(iphdr) - 1);
-  /* send ICMP if TTL == 0 */
-  if (IPH_TTL(iphdr) == 0) {
-    /* Don't send ICMP messages in response to ICMP messages */
-    if (IPH_PROTO(iphdr) != IP_PROTO_ICMP) {
-      icmp_time_exceeded(p, ICMP_TE_TTL);
-      snmp_inc_icmpouttimeexcds();
-    }
-    return (struct netif *)NULL;
-  }
-
-  /* Incrementally update the IP checksum. */
-  if (IPH_CHKSUM(iphdr) >= htons(0xffff - 0x100)) {
-    IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + htons(0x100) + 1);
-  } else {
-    IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + htons(0x100));
-  }
-
-  LWIP_DEBUGF(IP_DEBUG, ("ip_forward: forwarding packet to 0x%lx\n",
-                    iphdr->dest.addr));
-
-  IP_STATS_INC(ip.fw);
-  IP_STATS_INC(ip.xmit);
-    snmp_inc_ipforwdatagrams();
-
-  PERF_STOP("ip_forward");
-  /* transmit pbuf on chosen interface */
-  netif->output(netif, p, (struct ip_addr *)&(iphdr->dest));
-  return netif;
-}
-#endif /* IP_FORWARD */
-
-/**
- * This function is called by the network interface device driver when
- * an IP packet is received. The function does the basic checks of the
- * IP header such as packet size being at least larger than the header
- * size etc. If the packet was not destined for us, the packet is
- * forwarded (using ip_forward). The IP checksum is always checked.
- *
- * Finally, the packet is sent to the upper layer protocol input function.
- * 
- * 
- * 
- */
-
-err_t
-ip_input(struct pbuf *p, struct netif *inp) {
-  struct ip_hdr *iphdr;
-  struct netif *netif;
-  u16_t iphdrlen;
-
-  IP_STATS_INC(ip.recv);
-  snmp_inc_ipinreceives();
-
-  /* identify the IP header */
-  iphdr = p->payload;
-  if (IPH_V(iphdr) != 4) {
-    LWIP_DEBUGF(IP_DEBUG | 1, ("IP packet dropped due to bad version number %u\n", IPH_V(iphdr)));
-    ip_debug_print(p);
-    pbuf_free(p);
-    IP_STATS_INC(ip.err);
-    IP_STATS_INC(ip.drop);
-    snmp_inc_ipunknownprotos();
-    return ERR_OK;
-  }
-  /* obtain IP header length in number of 32-bit words */
-  iphdrlen = IPH_HL(iphdr);
-  /* calculate IP header length in bytes */
-  iphdrlen *= 4;
-
-  /* header length exceeds first pbuf length? */
-  if (iphdrlen > p->len) {
-    LWIP_DEBUGF(IP_DEBUG | 2, ("IP header (len %u) does not fit in first pbuf (len %u), IP packet droppped.\n",
-      iphdrlen, p->len));
-    /* free (drop) packet pbufs */
-    pbuf_free(p);
-    IP_STATS_INC(ip.lenerr);
-    IP_STATS_INC(ip.drop);
-    snmp_inc_ipindiscards();
-    return ERR_OK;
-  }
-
-  /* verify checksum */
-#if CHECKSUM_CHECK_IP
-  if (inet_chksum(iphdr, iphdrlen) != 0) {
-
-    LWIP_DEBUGF(IP_DEBUG | 2, ("Checksum (0x%x) failed, IP packet dropped.\n", inet_chksum(iphdr, iphdrlen)));
-    ip_debug_print(p);
-    pbuf_free(p);
-    IP_STATS_INC(ip.chkerr);
-    IP_STATS_INC(ip.drop);
-    snmp_inc_ipindiscards();
-    return ERR_OK;
-  }
-#endif
-
-  /* Trim pbuf. This should have been done at the netif layer,
-   * but we'll do it anyway just to be sure that its done. */
-  pbuf_realloc(p, ntohs(IPH_LEN(iphdr)));
-
-  /* match packet against an interface, i.e. is this packet for us? */
-  for (netif = netif_list; netif != NULL; netif = netif->next) {
-
-    LWIP_DEBUGF(IP_DEBUG, ("ip_input: iphdr->dest 0x%lx netif->ip_addr 0x%lx (0x%lx, 0x%lx, 0x%lx)\n",
-      iphdr->dest.addr, netif->ip_addr.addr,
-      iphdr->dest.addr & netif->netmask.addr,
-      netif->ip_addr.addr & netif->netmask.addr,
-      iphdr->dest.addr & ~(netif->netmask.addr)));
-
-    /* interface is up and configured? */
-    if ((netif_is_up(netif)) && (!ip_addr_isany(&(netif->ip_addr))))
-    {
-      /* unicast to this interface address? */
-      if (ip_addr_cmp(&(iphdr->dest), &(netif->ip_addr)) ||
-         /* or broadcast on this interface network address? */
-         ip_addr_isbroadcast(&(iphdr->dest), netif)) {
-        LWIP_DEBUGF(IP_DEBUG, ("ip_input: packet accepted on interface %c%c\n",
-          netif->name[0], netif->name[1]));
-        /* break out of for loop */
-        break;
-      }
-    }
-  }
-#if LWIP_DHCP
-  /* Pass DHCP messages regardless of destination address. DHCP traffic is addressed
-   * using link layer addressing (such as Ethernet MAC) so we must not filter on IP.
-   * According to RFC 1542 section 3.1.1, referred by RFC 2131).
-   */
-  if (netif == NULL) {
-    /* remote port is DHCP server? */
-    if (IPH_PROTO(iphdr) == IP_PROTO_UDP) {
-      LWIP_DEBUGF(IP_DEBUG | DBG_TRACE | 1, ("ip_input: UDP packet to DHCP client port %u\n",
-        ntohs(((struct udp_hdr *)((u8_t *)iphdr + iphdrlen))->dest)));
-      if (ntohs(((struct udp_hdr *)((u8_t *)iphdr + iphdrlen))->dest) == DHCP_CLIENT_PORT) {
-        LWIP_DEBUGF(IP_DEBUG | DBG_TRACE | 1, ("ip_input: DHCP packet accepted.\n"));
-        netif = inp;
-      }
-    }
-  }
-#endif /* LWIP_DHCP */
-  /* packet not for us? */
-  if (netif == NULL) {
-    /* packet not for us, route or discard */
-    LWIP_DEBUGF(IP_DEBUG | DBG_TRACE | 1, ("ip_input: packet not for us.\n"));
-#if IP_FORWARD
-    /* non-broadcast packet? */
-    if (!ip_addr_isbroadcast(&(iphdr->dest), inp)) {
-      /* try to forward IP packet on (other) interfaces */
-      ip_forward(p, iphdr, inp);
-    }
-    else
-#endif /* IP_FORWARD */
-    {
-      snmp_inc_ipindiscards();
-    }
-    pbuf_free(p);
-    return ERR_OK;
-  }
-  /* packet consists of multiple fragments? */
-  if ((IPH_OFFSET(iphdr) & htons(IP_OFFMASK | IP_MF)) != 0) {
-#if IP_REASSEMBLY /* packet fragment reassembly code present? */
-    LWIP_DEBUGF(IP_DEBUG, ("IP packet is a fragment (id=0x%04x tot_len=%u len=%u MF=%u offset=%u), calling ip_reass()\n",
-      ntohs(IPH_ID(iphdr)), p->tot_len, ntohs(IPH_LEN(iphdr)), !!(IPH_OFFSET(iphdr) & htons(IP_MF)), (ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK)*8));
-    /* reassemble the packet*/
-    p = ip_reass(p);
-    /* packet not fully reassembled yet? */
-    if (p == NULL) {
-      return ERR_OK;
-    }
-    iphdr = p->payload;
-#else /* IP_REASSEMBLY == 0, no packet fragment reassembly code present */
-    pbuf_free(p);
-    LWIP_DEBUGF(IP_DEBUG | 2, ("IP packet dropped since it was fragmented (0x%x) (while IP_REASSEMBLY == 0).\n",
-      ntohs(IPH_OFFSET(iphdr))));
-    IP_STATS_INC(ip.opterr);
-    IP_STATS_INC(ip.drop);
-    snmp_inc_ipunknownprotos();
-    return ERR_OK;
-#endif /* IP_REASSEMBLY */
-  }
-
-#if IP_OPTIONS == 0 /* no support for IP options in the IP header? */
-  if (iphdrlen > IP_HLEN) {
-    LWIP_DEBUGF(IP_DEBUG | 2, ("IP packet dropped since there were IP options (while IP_OPTIONS == 0).\n"));
-    pbuf_free(p);
-    IP_STATS_INC(ip.opterr);
-    IP_STATS_INC(ip.drop);
-    snmp_inc_ipunknownprotos();
-    return ERR_OK;
-  }
-#endif /* IP_OPTIONS == 0 */
-
-  /* send to upper layers */
-  LWIP_DEBUGF(IP_DEBUG, ("ip_input: \n"));
-  ip_debug_print(p);
-  LWIP_DEBUGF(IP_DEBUG, ("ip_input: p->len %d p->tot_len %d\n", p->len, p->tot_len));
-
-#if LWIP_RAW
-  /* raw input did not eat the packet? */
-  if (raw_input(p, inp) == 0) {
-#endif /* LWIP_RAW */
-
-  switch (IPH_PROTO(iphdr)) {
-#if LWIP_UDP
-  case IP_PROTO_UDP:
-  case IP_PROTO_UDPLITE:
-    snmp_inc_ipindelivers();
-    udp_input(p, inp);
-    break;
-#endif /* LWIP_UDP */
-#if LWIP_TCP
-  case IP_PROTO_TCP:
-    snmp_inc_ipindelivers();
-    tcp_input(p, inp);
-    break;
-#endif /* LWIP_TCP */
-  case IP_PROTO_ICMP:
-    snmp_inc_ipindelivers();
-    icmp_input(p, inp);
-    break;
-  default:
-    /* send ICMP destination protocol unreachable unless is was a broadcast */
-    if (!ip_addr_isbroadcast(&(iphdr->dest), inp) &&
-        !ip_addr_ismulticast(&(iphdr->dest))) {
-      p->payload = iphdr;
-      icmp_dest_unreach(p, ICMP_DUR_PROTO);
-    }
-    pbuf_free(p);
-
-    LWIP_DEBUGF(IP_DEBUG | 2, ("Unsupported transport protocol %d\n", IPH_PROTO(iphdr)));
-
-    IP_STATS_INC(ip.proterr);
-    IP_STATS_INC(ip.drop);
-    snmp_inc_ipunknownprotos();
-  }
-#if LWIP_RAW
-  } /* LWIP_RAW */
-#endif
-  return ERR_OK;
-}
-
-/**
- * Sends an IP packet on a network interface. This function constructs
- * the IP header and calculates the IP header checksum. If the source
- * IP address is NULL, the IP address of the outgoing network
- * interface is filled in as source address.
- */
-
-err_t
-ip_output_if(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
-             u8_t ttl, u8_t tos,
-             u8_t proto, struct netif *netif)
-{
-  struct ip_hdr *iphdr;
-  u16_t ip_id = 0;
-
-  snmp_inc_ipoutrequests();
-
-  if (dest != IP_HDRINCL) {
-    if (pbuf_header(p, IP_HLEN)) {
-      LWIP_DEBUGF(IP_DEBUG | 2, ("ip_output: not enough room for IP header in pbuf\n"));
-
-      IP_STATS_INC(ip.err);
-      snmp_inc_ipoutdiscards();
-      return ERR_BUF;
-    }
-
-    iphdr = p->payload;
-
-    IPH_TTL_SET(iphdr, ttl);
-    IPH_PROTO_SET(iphdr, proto);
-
-    ip_addr_set(&(iphdr->dest), dest);
-
-    IPH_VHLTOS_SET(iphdr, 4, IP_HLEN / 4, tos);
-    IPH_LEN_SET(iphdr, htons(p->tot_len));
-    IPH_OFFSET_SET(iphdr, htons(IP_DF));
-    IPH_ID_SET(iphdr, htons(ip_id));
-    ++ip_id;
-
-    if (ip_addr_isany(src)) {
-      ip_addr_set(&(iphdr->src), &(netif->ip_addr));
-    } else {
-      ip_addr_set(&(iphdr->src), src);
-    }
-
-    IPH_CHKSUM_SET(iphdr, 0);
-#if CHECKSUM_GEN_IP
-    IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN));
-#endif
-  } else {
-    iphdr = p->payload;
-    dest = &(iphdr->dest);
-  }
-
-#if IP_FRAG
-  /* don't fragment if interface has mtu set to 0 [loopif] */
-  if (netif->mtu && (p->tot_len > netif->mtu))
-    return ip_frag(p,netif,dest);
-#endif
-
-  IP_STATS_INC(ip.xmit);
-
-  LWIP_DEBUGF(IP_DEBUG, ("ip_output_if: %c%c%u\n", netif->name[0], netif->name[1], netif->num));
-  ip_debug_print(p);
-
-  LWIP_DEBUGF(IP_DEBUG, ("netif->output()"));
-
-  return netif->output(netif, p, dest);
-}
-
-/**
- * Simple interface to ip_output_if. It finds the outgoing network
- * interface and calls upon ip_output_if to do the actual work.
- */
-
-err_t
-ip_output(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
-          u8_t ttl, u8_t tos, u8_t proto)
-{
-  struct netif *netif;
-
-  if ((netif = ip_route(dest)) == NULL) {
-    LWIP_DEBUGF(IP_DEBUG | 2, ("ip_output: No route to 0x%lx\n", dest->addr));
-
-    IP_STATS_INC(ip.rterr);
-    snmp_inc_ipoutdiscards();
-    return ERR_RTE;
-  }
-
-  return ip_output_if(p, src, dest, ttl, tos, proto, netif);
-}
-
-#if IP_DEBUG
-void
-ip_debug_print(struct pbuf *p)
-{
-  struct ip_hdr *iphdr = p->payload;
-  u8_t *payload;
-
-  payload = (u8_t *)iphdr + IP_HLEN;
-
-  LWIP_DEBUGF(IP_DEBUG, ("IP header:\n"));
-  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
-  LWIP_DEBUGF(IP_DEBUG, ("|%2d |%2d |  0x%02x |     %5u     | (v, hl, tos, len)\n",
-                    IPH_V(iphdr),
-                    IPH_HL(iphdr),
-                    IPH_TOS(iphdr),
-                    ntohs(IPH_LEN(iphdr))));
-  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
-  LWIP_DEBUGF(IP_DEBUG, ("|    %5u      |%u%u%u|    %4u   | (id, flags, offset)\n",
-                    ntohs(IPH_ID(iphdr)),
-                    ntohs(IPH_OFFSET(iphdr)) >> 15 & 1,
-                    ntohs(IPH_OFFSET(iphdr)) >> 14 & 1,
-                    ntohs(IPH_OFFSET(iphdr)) >> 13 & 1,
-                    ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK));
-  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
-  LWIP_DEBUGF(IP_DEBUG, ("|  %3u  |  %3u  |    0x%04x     | (ttl, proto, chksum)\n",
-                    IPH_TTL(iphdr),
-                    IPH_PROTO(iphdr),
-                    ntohs(IPH_CHKSUM(iphdr))));
-  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
-  LWIP_DEBUGF(IP_DEBUG, ("|  %3u  |  %3u  |  %3u  |  %3u  | (src)\n",
-                    ip4_addr1(&iphdr->src),
-                    ip4_addr2(&iphdr->src),
-                    ip4_addr3(&iphdr->src),
-                    ip4_addr4(&iphdr->src)));
-  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
-  LWIP_DEBUGF(IP_DEBUG, ("|  %3u  |  %3u  |  %3u  |  %3u  | (dest)\n",
-                    ip4_addr1(&iphdr->dest),
-                    ip4_addr2(&iphdr->dest),
-                    ip4_addr3(&iphdr->dest),
-                    ip4_addr4(&iphdr->dest)));
-  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
-}
-#endif /* IP_DEBUG */
-
-
-
-
-
-
+/* @file\r
+ *\r
+ * This is the IP layer implementation for incoming and outgoing IP traffic.\r
+ * \r
+ * @see ip_frag.c\r
+ *\r
+ */\r
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without modification,\r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED\r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT\r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY\r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ *\r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+\r
+#include "lwip/opt.h"\r
+\r
+#include "lwip/def.h"\r
+#include "lwip/mem.h"\r
+#include "lwip/ip.h"\r
+#include "lwip/ip_frag.h"\r
+#include "lwip/inet.h"\r
+#include "lwip/netif.h"\r
+#include "lwip/icmp.h"\r
+#include "lwip/raw.h"\r
+#include "lwip/udp.h"\r
+#include "lwip/tcp.h"\r
+\r
+#include "lwip/stats.h"\r
+\r
+#include "arch/perf.h"\r
+\r
+#include "lwip/snmp.h"\r
+#if LWIP_DHCP\r
+#  include "lwip/dhcp.h"\r
+#endif /* LWIP_DHCP */\r
+\r
+\r
+/**\r
+ * Initializes the IP layer.\r
+ */\r
+\r
+void\r
+ip_init(void)\r
+{\r
+  /* no initializations as of yet */\r
+}\r
+\r
+/**\r
+ * Finds the appropriate network interface for a given IP address. It\r
+ * searches the list of network interfaces linearly. A match is found\r
+ * if the masked IP address of the network interface equals the masked\r
+ * IP address given to the function.\r
+ */\r
+\r
+struct netif *\r
+ip_route(struct ip_addr *dest)\r
+{\r
+  struct netif *netif;\r
+\r
+  /* iterate through netifs */\r
+  for(netif = netif_list; netif != NULL; netif = netif->next) {\r
+    /* network mask matches? */\r
+    if (ip_addr_netcmp(dest, &(netif->ip_addr), &(netif->netmask))) {\r
+      /* return netif on which to forward IP packet */\r
+      return netif;\r
+    }\r
+  }\r
+  /* no matching netif found, use default netif */\r
+  return netif_default;\r
+}\r
+#if IP_FORWARD\r
+\r
+/**\r
+ * Forwards an IP packet. It finds an appropriate route for the\r
+ * packet, decrements the TTL value of the packet, adjusts the\r
+ * checksum and outputs the packet on the appropriate interface.\r
+ */\r
+\r
+static struct netif *\r
+ip_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp)\r
+{\r
+  struct netif *netif;\r
+\r
+  PERF_START;\r
+  /* Find network interface where to forward this IP packet to. */\r
+  netif = ip_route((struct ip_addr *)&(iphdr->dest));\r
+  if (netif == NULL) {\r
+    LWIP_DEBUGF(IP_DEBUG, ("ip_forward: no forwarding route for 0x%lx found\n",\r
+                      iphdr->dest.addr));\r
+    snmp_inc_ipnoroutes();\r
+    return (struct netif *)NULL;\r
+  }\r
+  /* Do not forward packets onto the same network interface on which\r
+   * they arrived. */\r
+  if (netif == inp) {\r
+    LWIP_DEBUGF(IP_DEBUG, ("ip_forward: not bouncing packets back on incoming interface.\n"));\r
+    snmp_inc_ipnoroutes();\r
+    return (struct netif *)NULL;\r
+  }\r
+\r
+  /* decrement TTL */\r
+  IPH_TTL_SET(iphdr, IPH_TTL(iphdr) - 1);\r
+  /* send ICMP if TTL == 0 */\r
+  if (IPH_TTL(iphdr) == 0) {\r
+    /* Don't send ICMP messages in response to ICMP messages */\r
+    if (IPH_PROTO(iphdr) != IP_PROTO_ICMP) {\r
+      icmp_time_exceeded(p, ICMP_TE_TTL);\r
+      snmp_inc_icmpouttimeexcds();\r
+    }\r
+    return (struct netif *)NULL;\r
+  }\r
+\r
+  /* Incrementally update the IP checksum. */\r
+  if (IPH_CHKSUM(iphdr) >= htons(0xffff - 0x100)) {\r
+    IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + htons(0x100) + 1);\r
+  } else {\r
+    IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + htons(0x100));\r
+  }\r
+\r
+  LWIP_DEBUGF(IP_DEBUG, ("ip_forward: forwarding packet to 0x%lx\n",\r
+                    iphdr->dest.addr));\r
+\r
+  IP_STATS_INC(ip.fw);\r
+  IP_STATS_INC(ip.xmit);\r
+    snmp_inc_ipforwdatagrams();\r
+\r
+  PERF_STOP("ip_forward");\r
+  /* transmit pbuf on chosen interface */\r
+  netif->output(netif, p, (struct ip_addr *)&(iphdr->dest));\r
+  return netif;\r
+}\r
+#endif /* IP_FORWARD */\r
+\r
+/**\r
+ * This function is called by the network interface device driver when\r
+ * an IP packet is received. The function does the basic checks of the\r
+ * IP header such as packet size being at least larger than the header\r
+ * size etc. If the packet was not destined for us, the packet is\r
+ * forwarded (using ip_forward). The IP checksum is always checked.\r
+ *\r
+ * Finally, the packet is sent to the upper layer protocol input function.\r
+ * \r
+ * \r
+ * \r
+ */\r
+\r
+err_t\r
+ip_input(struct pbuf *p, struct netif *inp) {\r
+  struct ip_hdr *iphdr;\r
+  struct netif *netif;\r
+  u16_t iphdrlen;\r
+\r
+  IP_STATS_INC(ip.recv);\r
+  snmp_inc_ipinreceives();\r
+\r
+  /* identify the IP header */\r
+  iphdr = p->payload;\r
+  if (IPH_V(iphdr) != 4) {\r
+    LWIP_DEBUGF(IP_DEBUG | 1, ("IP packet dropped due to bad version number %u\n", IPH_V(iphdr)));\r
+    ip_debug_print(p);\r
+    pbuf_free(p);\r
+    IP_STATS_INC(ip.err);\r
+    IP_STATS_INC(ip.drop);\r
+    snmp_inc_ipunknownprotos();\r
+    return ERR_OK;\r
+  }\r
+  /* obtain IP header length in number of 32-bit words */\r
+  iphdrlen = IPH_HL(iphdr);\r
+  /* calculate IP header length in bytes */\r
+  iphdrlen *= 4;\r
+\r
+  /* header length exceeds first pbuf length? */\r
+  if (iphdrlen > p->len) {\r
+    LWIP_DEBUGF(IP_DEBUG | 2, ("IP header (len %u) does not fit in first pbuf (len %u), IP packet droppped.\n",\r
+      iphdrlen, p->len));\r
+    /* free (drop) packet pbufs */\r
+    pbuf_free(p);\r
+    IP_STATS_INC(ip.lenerr);\r
+    IP_STATS_INC(ip.drop);\r
+    snmp_inc_ipindiscards();\r
+    return ERR_OK;\r
+  }\r
+\r
+  /* verify checksum */\r
+#if CHECKSUM_CHECK_IP\r
+  if (inet_chksum(iphdr, iphdrlen) != 0) {\r
+\r
+    LWIP_DEBUGF(IP_DEBUG | 2, ("Checksum (0x%x) failed, IP packet dropped.\n", inet_chksum(iphdr, iphdrlen)));\r
+    ip_debug_print(p);\r
+    pbuf_free(p);\r
+    IP_STATS_INC(ip.chkerr);\r
+    IP_STATS_INC(ip.drop);\r
+    snmp_inc_ipindiscards();\r
+    return ERR_OK;\r
+  }\r
+#endif\r
+\r
+  /* Trim pbuf. This should have been done at the netif layer,\r
+   * but we'll do it anyway just to be sure that its done. */\r
+  pbuf_realloc(p, ntohs(IPH_LEN(iphdr)));\r
+\r
+  /* match packet against an interface, i.e. is this packet for us? */\r
+  for (netif = netif_list; netif != NULL; netif = netif->next) {\r
+\r
+    LWIP_DEBUGF(IP_DEBUG, ("ip_input: iphdr->dest 0x%lx netif->ip_addr 0x%lx (0x%lx, 0x%lx, 0x%lx)\n",\r
+      iphdr->dest.addr, netif->ip_addr.addr,\r
+      iphdr->dest.addr & netif->netmask.addr,\r
+      netif->ip_addr.addr & netif->netmask.addr,\r
+      iphdr->dest.addr & ~(netif->netmask.addr)));\r
+\r
+    /* interface is up and configured? */\r
+    if ((netif_is_up(netif)) && (!ip_addr_isany(&(netif->ip_addr))))\r
+    {\r
+      /* unicast to this interface address? */\r
+      if (ip_addr_cmp(&(iphdr->dest), &(netif->ip_addr)) ||\r
+         /* or broadcast on this interface network address? */\r
+         ip_addr_isbroadcast(&(iphdr->dest), netif)) {\r
+        LWIP_DEBUGF(IP_DEBUG, ("ip_input: packet accepted on interface %c%c\n",\r
+          netif->name[0], netif->name[1]));\r
+        /* break out of for loop */\r
+        break;\r
+      }\r
+    }\r
+  }\r
+#if LWIP_DHCP\r
+  /* Pass DHCP messages regardless of destination address. DHCP traffic is addressed\r
+   * using link layer addressing (such as Ethernet MAC) so we must not filter on IP.\r
+   * According to RFC 1542 section 3.1.1, referred by RFC 2131).\r
+   */\r
+  if (netif == NULL) {\r
+    /* remote port is DHCP server? */\r
+    if (IPH_PROTO(iphdr) == IP_PROTO_UDP) {\r
+      LWIP_DEBUGF(IP_DEBUG | DBG_TRACE | 1, ("ip_input: UDP packet to DHCP client port %u\n",\r
+        ntohs(((struct udp_hdr *)((u8_t *)iphdr + iphdrlen))->dest)));\r
+      if (ntohs(((struct udp_hdr *)((u8_t *)iphdr + iphdrlen))->dest) == DHCP_CLIENT_PORT) {\r
+        LWIP_DEBUGF(IP_DEBUG | DBG_TRACE | 1, ("ip_input: DHCP packet accepted.\n"));\r
+        netif = inp;\r
+      }\r
+    }\r
+  }\r
+#endif /* LWIP_DHCP */\r
+  /* packet not for us? */\r
+  if (netif == NULL) {\r
+    /* packet not for us, route or discard */\r
+    LWIP_DEBUGF(IP_DEBUG | DBG_TRACE | 1, ("ip_input: packet not for us.\n"));\r
+#if IP_FORWARD\r
+    /* non-broadcast packet? */\r
+    if (!ip_addr_isbroadcast(&(iphdr->dest), inp)) {\r
+      /* try to forward IP packet on (other) interfaces */\r
+      ip_forward(p, iphdr, inp);\r
+    }\r
+    else\r
+#endif /* IP_FORWARD */\r
+    {\r
+      snmp_inc_ipindiscards();\r
+    }\r
+    pbuf_free(p);\r
+    return ERR_OK;\r
+  }\r
+  /* packet consists of multiple fragments? */\r
+  if ((IPH_OFFSET(iphdr) & htons(IP_OFFMASK | IP_MF)) != 0) {\r
+#if IP_REASSEMBLY /* packet fragment reassembly code present? */\r
+    LWIP_DEBUGF(IP_DEBUG, ("IP packet is a fragment (id=0x%04x tot_len=%u len=%u MF=%u offset=%u), calling ip_reass()\n",\r
+      ntohs(IPH_ID(iphdr)), p->tot_len, ntohs(IPH_LEN(iphdr)), !!(IPH_OFFSET(iphdr) & htons(IP_MF)), (ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK)*8));\r
+    /* reassemble the packet*/\r
+    p = ip_reass(p);\r
+    /* packet not fully reassembled yet? */\r
+    if (p == NULL) {\r
+      return ERR_OK;\r
+    }\r
+    iphdr = p->payload;\r
+#else /* IP_REASSEMBLY == 0, no packet fragment reassembly code present */\r
+    pbuf_free(p);\r
+    LWIP_DEBUGF(IP_DEBUG | 2, ("IP packet dropped since it was fragmented (0x%x) (while IP_REASSEMBLY == 0).\n",\r
+      ntohs(IPH_OFFSET(iphdr))));\r
+    IP_STATS_INC(ip.opterr);\r
+    IP_STATS_INC(ip.drop);\r
+    snmp_inc_ipunknownprotos();\r
+    return ERR_OK;\r
+#endif /* IP_REASSEMBLY */\r
+  }\r
+\r
+#if IP_OPTIONS == 0 /* no support for IP options in the IP header? */\r
+  if (iphdrlen > IP_HLEN) {\r
+    LWIP_DEBUGF(IP_DEBUG | 2, ("IP packet dropped since there were IP options (while IP_OPTIONS == 0).\n"));\r
+    pbuf_free(p);\r
+    IP_STATS_INC(ip.opterr);\r
+    IP_STATS_INC(ip.drop);\r
+    snmp_inc_ipunknownprotos();\r
+    return ERR_OK;\r
+  }\r
+#endif /* IP_OPTIONS == 0 */\r
+\r
+  /* send to upper layers */\r
+  LWIP_DEBUGF(IP_DEBUG, ("ip_input: \n"));\r
+  ip_debug_print(p);\r
+  LWIP_DEBUGF(IP_DEBUG, ("ip_input: p->len %d p->tot_len %d\n", p->len, p->tot_len));\r
+\r
+#if LWIP_RAW\r
+  /* raw input did not eat the packet? */\r
+  if (raw_input(p, inp) == 0) {\r
+#endif /* LWIP_RAW */\r
+\r
+  switch (IPH_PROTO(iphdr)) {\r
+#if LWIP_UDP\r
+  case IP_PROTO_UDP:\r
+  case IP_PROTO_UDPLITE:\r
+    snmp_inc_ipindelivers();\r
+    udp_input(p, inp);\r
+    break;\r
+#endif /* LWIP_UDP */\r
+#if LWIP_TCP\r
+  case IP_PROTO_TCP:\r
+    snmp_inc_ipindelivers();\r
+    tcp_input(p, inp);\r
+    break;\r
+#endif /* LWIP_TCP */\r
+  case IP_PROTO_ICMP:\r
+    snmp_inc_ipindelivers();\r
+    icmp_input(p, inp);\r
+    break;\r
+  default:\r
+    /* send ICMP destination protocol unreachable unless is was a broadcast */\r
+    if (!ip_addr_isbroadcast(&(iphdr->dest), inp) &&\r
+        !ip_addr_ismulticast(&(iphdr->dest))) {\r
+      p->payload = iphdr;\r
+      icmp_dest_unreach(p, ICMP_DUR_PROTO);\r
+    }\r
+    pbuf_free(p);\r
+\r
+    LWIP_DEBUGF(IP_DEBUG | 2, ("Unsupported transport protocol %d\n", IPH_PROTO(iphdr)));\r
+\r
+    IP_STATS_INC(ip.proterr);\r
+    IP_STATS_INC(ip.drop);\r
+    snmp_inc_ipunknownprotos();\r
+  }\r
+#if LWIP_RAW\r
+  } /* LWIP_RAW */\r
+#endif\r
+  return ERR_OK;\r
+}\r
+\r
+/**\r
+ * Sends an IP packet on a network interface. This function constructs\r
+ * the IP header and calculates the IP header checksum. If the source\r
+ * IP address is NULL, the IP address of the outgoing network\r
+ * interface is filled in as source address.\r
+ */\r
+\r
+err_t\r
+ip_output_if(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,\r
+             u8_t ttl, u8_t tos,\r
+             u8_t proto, struct netif *netif)\r
+{\r
+  struct ip_hdr *iphdr;\r
+  u16_t ip_id = 0;\r
+\r
+  snmp_inc_ipoutrequests();\r
+\r
+  if (dest != IP_HDRINCL) {\r
+    if (pbuf_header(p, IP_HLEN)) {\r
+      LWIP_DEBUGF(IP_DEBUG | 2, ("ip_output: not enough room for IP header in pbuf\n"));\r
+\r
+      IP_STATS_INC(ip.err);\r
+      snmp_inc_ipoutdiscards();\r
+      return ERR_BUF;\r
+    }\r
+\r
+    iphdr = p->payload;\r
+\r
+    IPH_TTL_SET(iphdr, ttl);\r
+    IPH_PROTO_SET(iphdr, proto);\r
+\r
+    ip_addr_set(&(iphdr->dest), dest);\r
+\r
+    IPH_VHLTOS_SET(iphdr, 4, IP_HLEN / 4, tos);\r
+    IPH_LEN_SET(iphdr, htons(p->tot_len));\r
+    IPH_OFFSET_SET(iphdr, htons(IP_DF));\r
+    IPH_ID_SET(iphdr, htons(ip_id));\r
+    ++ip_id;\r
+\r
+    if (ip_addr_isany(src)) {\r
+      ip_addr_set(&(iphdr->src), &(netif->ip_addr));\r
+    } else {\r
+      ip_addr_set(&(iphdr->src), src);\r
+    }\r
+\r
+    IPH_CHKSUM_SET(iphdr, 0);\r
+#if CHECKSUM_GEN_IP\r
+    IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN));\r
+#endif\r
+  } else {\r
+    iphdr = p->payload;\r
+    dest = &(iphdr->dest);\r
+  }\r
+\r
+#if IP_FRAG\r
+  /* don't fragment if interface has mtu set to 0 [loopif] */\r
+  if (netif->mtu && (p->tot_len > netif->mtu))\r
+    return ip_frag(p,netif,dest);\r
+#endif\r
+\r
+  IP_STATS_INC(ip.xmit);\r
+\r
+  LWIP_DEBUGF(IP_DEBUG, ("ip_output_if: %c%c%u\n", netif->name[0], netif->name[1], netif->num));\r
+  ip_debug_print(p);\r
+\r
+  LWIP_DEBUGF(IP_DEBUG, ("netif->output()"));\r
+\r
+  return netif->output(netif, p, dest);\r
+}\r
+\r
+/**\r
+ * Simple interface to ip_output_if. It finds the outgoing network\r
+ * interface and calls upon ip_output_if to do the actual work.\r
+ */\r
+\r
+err_t\r
+ip_output(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,\r
+          u8_t ttl, u8_t tos, u8_t proto)\r
+{\r
+  struct netif *netif;\r
+\r
+  if ((netif = ip_route(dest)) == NULL) {\r
+    LWIP_DEBUGF(IP_DEBUG | 2, ("ip_output: No route to 0x%lx\n", dest->addr));\r
+\r
+    IP_STATS_INC(ip.rterr);\r
+    snmp_inc_ipoutdiscards();\r
+    return ERR_RTE;\r
+  }\r
+\r
+  return ip_output_if(p, src, dest, ttl, tos, proto, netif);\r
+}\r
+\r
+#if IP_DEBUG\r
+void\r
+ip_debug_print(struct pbuf *p)\r
+{\r
+  struct ip_hdr *iphdr = p->payload;\r
+  u8_t *payload;\r
+\r
+  payload = (u8_t *)iphdr + IP_HLEN;\r
+\r
+  LWIP_DEBUGF(IP_DEBUG, ("IP header:\n"));\r
+  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));\r
+  LWIP_DEBUGF(IP_DEBUG, ("|%2d |%2d |  0x%02x |     %5u     | (v, hl, tos, len)\n",\r
+                    IPH_V(iphdr),\r
+                    IPH_HL(iphdr),\r
+                    IPH_TOS(iphdr),\r
+                    ntohs(IPH_LEN(iphdr))));\r
+  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));\r
+  LWIP_DEBUGF(IP_DEBUG, ("|    %5u      |%u%u%u|    %4u   | (id, flags, offset)\n",\r
+                    ntohs(IPH_ID(iphdr)),\r
+                    ntohs(IPH_OFFSET(iphdr)) >> 15 & 1,\r
+                    ntohs(IPH_OFFSET(iphdr)) >> 14 & 1,\r
+                    ntohs(IPH_OFFSET(iphdr)) >> 13 & 1,\r
+                    ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK));\r
+  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));\r
+  LWIP_DEBUGF(IP_DEBUG, ("|  %3u  |  %3u  |    0x%04x     | (ttl, proto, chksum)\n",\r
+                    IPH_TTL(iphdr),\r
+                    IPH_PROTO(iphdr),\r
+                    ntohs(IPH_CHKSUM(iphdr))));\r
+  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));\r
+  LWIP_DEBUGF(IP_DEBUG, ("|  %3u  |  %3u  |  %3u  |  %3u  | (src)\n",\r
+                    ip4_addr1(&iphdr->src),\r
+                    ip4_addr2(&iphdr->src),\r
+                    ip4_addr3(&iphdr->src),\r
+                    ip4_addr4(&iphdr->src)));\r
+  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));\r
+  LWIP_DEBUGF(IP_DEBUG, ("|  %3u  |  %3u  |  %3u  |  %3u  | (dest)\n",\r
+                    ip4_addr1(&iphdr->dest),\r
+                    ip4_addr2(&iphdr->dest),\r
+                    ip4_addr3(&iphdr->dest),\r
+                    ip4_addr4(&iphdr->dest)));\r
+  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));\r
+}\r
+#endif /* IP_DEBUG */\r
+\r
+\r
+\r
+\r
+\r
+\r
index 2af526e9f3e62ad5f889d824aa82f6200445a647..cb465eef23dd3fb886d00aa07cea2717392d861f 100644 (file)
@@ -1,72 +1,72 @@
-/*
- * 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 <adam@sics.se>
- *
- */
-
-#include "lwip/ip_addr.h"
-#include "lwip/inet.h"
-#include "lwip/netif.h"
-
-/* used by IP_ADDR_ANY and IP_ADDR_BROADCAST in ip_addr.h */
-const struct ip_addr ip_addr_any = { 0x00000000UL };
-const struct ip_addr ip_addr_broadcast = { 0xffffffffUL };
-
-/* Determine if an address is a broadcast address on a network interface 
- * 
- * @param addr address to be checked
- * @param netif the network interface against which the address is checked
- * @return returns non-zero if the address is a broadcast address
- *
- */
-
-u8_t ip_addr_isbroadcast(struct ip_addr *addr, struct netif *netif)
-{
-  /* all ones (broadcast) or all zeroes (old skool broadcast) */
-  if ((addr->addr == ip_addr_broadcast.addr) ||
-      (addr->addr == ip_addr_any.addr))
-    return 1;
-  /* no broadcast support on this network interface? */
-  else if ((netif->flags & NETIF_FLAG_BROADCAST) == 0)
-    /* the given address cannot be a broadcast address
-     * nor can we check against any broadcast addresses */
-    return 0;
-  /* address matches network interface address exactly? => no broadcast */
-  else if (addr->addr == netif->ip_addr.addr)
-    return 0;
-  /*  on the same (sub) network... */
-  else if (ip_addr_netcmp(addr, &(netif->ip_addr), &(netif->netmask))
-         /* ...and host identifier bits are all ones? =>... */
-          && ((addr->addr & ~netif->netmask.addr) ==
-           (ip_addr_broadcast.addr & ~netif->netmask.addr)))
-    /* => network broadcast address */
-    return 1;
-  else
-    return 0;
-}
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+\r
+#include "lwip/ip_addr.h"\r
+#include "lwip/inet.h"\r
+#include "lwip/netif.h"\r
+\r
+/* used by IP_ADDR_ANY and IP_ADDR_BROADCAST in ip_addr.h */\r
+const struct ip_addr ip_addr_any = { 0x00000000UL };\r
+const struct ip_addr ip_addr_broadcast = { 0xffffffffUL };\r
+\r
+/* Determine if an address is a broadcast address on a network interface \r
+ * \r
+ * @param addr address to be checked\r
+ * @param netif the network interface against which the address is checked\r
+ * @return returns non-zero if the address is a broadcast address\r
+ *\r
+ */\r
+\r
+u8_t ip_addr_isbroadcast(struct ip_addr *addr, struct netif *netif)\r
+{\r
+  /* all ones (broadcast) or all zeroes (old skool broadcast) */\r
+  if ((addr->addr == ip_addr_broadcast.addr) ||\r
+      (addr->addr == ip_addr_any.addr))\r
+    return 1;\r
+  /* no broadcast support on this network interface? */\r
+  else if ((netif->flags & NETIF_FLAG_BROADCAST) == 0)\r
+    /* the given address cannot be a broadcast address\r
+     * nor can we check against any broadcast addresses */\r
+    return 0;\r
+  /* address matches network interface address exactly? => no broadcast */\r
+  else if (addr->addr == netif->ip_addr.addr)\r
+    return 0;\r
+  /*  on the same (sub) network... */\r
+  else if (ip_addr_netcmp(addr, &(netif->ip_addr), &(netif->netmask))\r
+         /* ...and host identifier bits are all ones? =>... */\r
+          && ((addr->addr & ~netif->netmask.addr) ==\r
+           (ip_addr_broadcast.addr & ~netif->netmask.addr)))\r
+    /* => network broadcast address */\r
+    return 1;\r
+  else\r
+    return 0;\r
+}\r
index a162758aaefe762886beb5986bafc3c03d7e1b5c..76d13ca17ea28a7e9f27c9d1c1960fb32b4f9eb7 100644 (file)
-/*
- * 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 <adam@sics.se>
- *
- */
-
-/* Some ICMP messages should be passed to the transport protocols. This
-   is not implemented. */
-
-#include "lwip/opt.h"
-
-#include "lwip/icmp.h"
-#include "lwip/inet.h"
-#include "lwip/ip.h"
-#include "lwip/def.h"
-
-#include "lwip/stats.h"
-
-
-void
-icmp_input(struct pbuf *p, struct netif *inp)
-{
-  unsigned char type;
-  struct icmp_echo_hdr *iecho;
-  struct ip_hdr *iphdr;
-  struct ip_addr tmpaddr;
-
-#ifdef ICMP_STATS
-  ++lwip_stats.icmp.recv;
-#endif /* ICMP_STATS */
-
-  /* TODO: check length before accessing payload! */
-
-  type = ((char *)p->payload)[0];
-
-  switch (type) {
-  case ICMP6_ECHO:
-    LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ping\n"));
-
-    if (p->tot_len < sizeof(struct icmp_echo_hdr)) {
-      LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: bad ICMP echo received\n"));
-
-      pbuf_free(p);
-#ifdef ICMP_STATS
-      ++lwip_stats.icmp.lenerr;
-#endif /* ICMP_STATS */
-
-      return;
-    }
-    iecho = p->payload;
-    iphdr = (struct ip_hdr *)((char *)p->payload - IP_HLEN);
-    if (inet_chksum_pbuf(p) != 0) {
-      LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: checksum failed for received ICMP echo (%x)\n", inet_chksum_pseudo(p, &(iphdr->src), &(iphdr->dest), IP_PROTO_ICMP, p->tot_len)));
-
-#ifdef ICMP_STATS
-      ++lwip_stats.icmp.chkerr;
-#endif /* ICMP_STATS */
-    /*      return;*/
-    }
-    LWIP_DEBUGF(ICMP_DEBUG, ("icmp: p->len %d p->tot_len %d\n", p->len, p->tot_len));
-    ip_addr_set(&tmpaddr, &(iphdr->src));
-    ip_addr_set(&(iphdr->src), &(iphdr->dest));
-    ip_addr_set(&(iphdr->dest), &tmpaddr);
-    iecho->type = ICMP6_ER;
-    /* adjust the checksum */
-    if (iecho->chksum >= htons(0xffff - (ICMP6_ECHO << 8))) {
-      iecho->chksum += htons(ICMP6_ECHO << 8) + 1;
-    } else {
-      iecho->chksum += htons(ICMP6_ECHO << 8);
-    }
-    LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: checksum failed for received ICMP echo (%x)\n", inet_chksum_pseudo(p, &(iphdr->src), &(iphdr->dest), IP_PROTO_ICMP, p->tot_len)));
-#ifdef ICMP_STATS
-    ++lwip_stats.icmp.xmit;
-#endif /* ICMP_STATS */
-
-    /*    LWIP_DEBUGF("icmp: p->len %u p->tot_len %u\n", p->len, p->tot_len);*/
-    ip_output_if (p, &(iphdr->src), IP_HDRINCL,
-     iphdr->hoplim, IP_PROTO_ICMP, inp);
-    break;
-  default:
-    LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ICMP type %d not supported.\n", (int)type));
-#ifdef ICMP_STATS
-    ++lwip_stats.icmp.proterr;
-    ++lwip_stats.icmp.drop;
-#endif /* ICMP_STATS */
-  }
-
-  pbuf_free(p);
-}
-
-void
-icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t)
-{
-  struct pbuf *q;
-  struct ip_hdr *iphdr;
-  struct icmp_dur_hdr *idur;
-
-  q = pbuf_alloc(PBUF_IP, 8 + IP_HLEN + 8, PBUF_RAM);
-  /* ICMP header + IP header + 8 bytes of data */
-
-  iphdr = p->payload;
-
-  idur = q->payload;
-  idur->type = (char)ICMP6_DUR;
-  idur->icode = (char)t;
-
-  memcpy((char *)q->payload + 8, p->payload, IP_HLEN + 8);
-
-  /* calculate checksum */
-  idur->chksum = 0;
-  idur->chksum = inet_chksum(idur, q->len);
-#ifdef ICMP_STATS
-  ++lwip_stats.icmp.xmit;
-#endif /* ICMP_STATS */
-
-  ip_output(q, NULL,
-      (struct ip_addr *)&(iphdr->src), ICMP_TTL, IP_PROTO_ICMP);
-  pbuf_free(q);
-}
-
-void
-icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t)
-{
-  struct pbuf *q;
-  struct ip_hdr *iphdr;
-  struct icmp_te_hdr *tehdr;
-
-  LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded\n"));
-
-  q = pbuf_alloc(PBUF_IP, 8 + IP_HLEN + 8, PBUF_RAM);
-
-  iphdr = p->payload;
-
-  tehdr = q->payload;
-  tehdr->type = (char)ICMP6_TE;
-  tehdr->icode = (char)t;
-
-  /* copy fields from original packet */
-  memcpy((char *)q->payload + 8, (char *)p->payload, IP_HLEN + 8);
-
-  /* calculate checksum */
-  tehdr->chksum = 0;
-  tehdr->chksum = inet_chksum(tehdr, q->len);
-#ifdef ICMP_STATS
-  ++lwip_stats.icmp.xmit;
-#endif /* ICMP_STATS */
-  ip_output(q, NULL,
-      (struct ip_addr *)&(iphdr->src), ICMP_TTL, IP_PROTO_ICMP);
-  pbuf_free(q);
-}
-
-
-
-
-
-
-
-
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without modification,\r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED\r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT\r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY\r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ *\r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+\r
+/* Some ICMP messages should be passed to the transport protocols. This\r
+   is not implemented. */\r
+\r
+#include "lwip/opt.h"\r
+\r
+#include "lwip/icmp.h"\r
+#include "lwip/inet.h"\r
+#include "lwip/ip.h"\r
+#include "lwip/def.h"\r
+\r
+#include "lwip/stats.h"\r
+\r
+\r
+void\r
+icmp_input(struct pbuf *p, struct netif *inp)\r
+{\r
+  unsigned char type;\r
+  struct icmp_echo_hdr *iecho;\r
+  struct ip_hdr *iphdr;\r
+  struct ip_addr tmpaddr;\r
+\r
+#ifdef ICMP_STATS\r
+  ++lwip_stats.icmp.recv;\r
+#endif /* ICMP_STATS */\r
+\r
+  /* TODO: check length before accessing payload! */\r
+\r
+  type = ((char *)p->payload)[0];\r
+\r
+  switch (type) {\r
+  case ICMP6_ECHO:\r
+    LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ping\n"));\r
+\r
+    if (p->tot_len < sizeof(struct icmp_echo_hdr)) {\r
+      LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: bad ICMP echo received\n"));\r
+\r
+      pbuf_free(p);\r
+#ifdef ICMP_STATS\r
+      ++lwip_stats.icmp.lenerr;\r
+#endif /* ICMP_STATS */\r
+\r
+      return;\r
+    }\r
+    iecho = p->payload;\r
+    iphdr = (struct ip_hdr *)((char *)p->payload - IP_HLEN);\r
+    if (inet_chksum_pbuf(p) != 0) {\r
+      LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: checksum failed for received ICMP echo (%x)\n", inet_chksum_pseudo(p, &(iphdr->src), &(iphdr->dest), IP_PROTO_ICMP, p->tot_len)));\r
+\r
+#ifdef ICMP_STATS\r
+      ++lwip_stats.icmp.chkerr;\r
+#endif /* ICMP_STATS */\r
+    /*      return;*/\r
+    }\r
+    LWIP_DEBUGF(ICMP_DEBUG, ("icmp: p->len %d p->tot_len %d\n", p->len, p->tot_len));\r
+    ip_addr_set(&tmpaddr, &(iphdr->src));\r
+    ip_addr_set(&(iphdr->src), &(iphdr->dest));\r
+    ip_addr_set(&(iphdr->dest), &tmpaddr);\r
+    iecho->type = ICMP6_ER;\r
+    /* adjust the checksum */\r
+    if (iecho->chksum >= htons(0xffff - (ICMP6_ECHO << 8))) {\r
+      iecho->chksum += htons(ICMP6_ECHO << 8) + 1;\r
+    } else {\r
+      iecho->chksum += htons(ICMP6_ECHO << 8);\r
+    }\r
+    LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: checksum failed for received ICMP echo (%x)\n", inet_chksum_pseudo(p, &(iphdr->src), &(iphdr->dest), IP_PROTO_ICMP, p->tot_len)));\r
+#ifdef ICMP_STATS\r
+    ++lwip_stats.icmp.xmit;\r
+#endif /* ICMP_STATS */\r
+\r
+    /*    LWIP_DEBUGF("icmp: p->len %u p->tot_len %u\n", p->len, p->tot_len);*/\r
+    ip_output_if (p, &(iphdr->src), IP_HDRINCL,\r
+     iphdr->hoplim, IP_PROTO_ICMP, inp);\r
+    break;\r
+  default:\r
+    LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ICMP type %d not supported.\n", (int)type));\r
+#ifdef ICMP_STATS\r
+    ++lwip_stats.icmp.proterr;\r
+    ++lwip_stats.icmp.drop;\r
+#endif /* ICMP_STATS */\r
+  }\r
+\r
+  pbuf_free(p);\r
+}\r
+\r
+void\r
+icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t)\r
+{\r
+  struct pbuf *q;\r
+  struct ip_hdr *iphdr;\r
+  struct icmp_dur_hdr *idur;\r
+\r
+  q = pbuf_alloc(PBUF_IP, 8 + IP_HLEN + 8, PBUF_RAM);\r
+  /* ICMP header + IP header + 8 bytes of data */\r
+\r
+  iphdr = p->payload;\r
+\r
+  idur = q->payload;\r
+  idur->type = (char)ICMP6_DUR;\r
+  idur->icode = (char)t;\r
+\r
+  memcpy((char *)q->payload + 8, p->payload, IP_HLEN + 8);\r
+\r
+  /* calculate checksum */\r
+  idur->chksum = 0;\r
+  idur->chksum = inet_chksum(idur, q->len);\r
+#ifdef ICMP_STATS\r
+  ++lwip_stats.icmp.xmit;\r
+#endif /* ICMP_STATS */\r
+\r
+  ip_output(q, NULL,\r
+      (struct ip_addr *)&(iphdr->src), ICMP_TTL, IP_PROTO_ICMP);\r
+  pbuf_free(q);\r
+}\r
+\r
+void\r
+icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t)\r
+{\r
+  struct pbuf *q;\r
+  struct ip_hdr *iphdr;\r
+  struct icmp_te_hdr *tehdr;\r
+\r
+  LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded\n"));\r
+\r
+  q = pbuf_alloc(PBUF_IP, 8 + IP_HLEN + 8, PBUF_RAM);\r
+\r
+  iphdr = p->payload;\r
+\r
+  tehdr = q->payload;\r
+  tehdr->type = (char)ICMP6_TE;\r
+  tehdr->icode = (char)t;\r
+\r
+  /* copy fields from original packet */\r
+  memcpy((char *)q->payload + 8, (char *)p->payload, IP_HLEN + 8);\r
+\r
+  /* calculate checksum */\r
+  tehdr->chksum = 0;\r
+  tehdr->chksum = inet_chksum(tehdr, q->len);\r
+#ifdef ICMP_STATS\r
+  ++lwip_stats.icmp.xmit;\r
+#endif /* ICMP_STATS */\r
+  ip_output(q, NULL,\r
+      (struct ip_addr *)&(iphdr->src), ICMP_TTL, IP_PROTO_ICMP);\r
+  pbuf_free(q);\r
+}\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
index abce830cf1088bc924d5e64538c7cfce441540ff..1a7f74ac8152500ce8dd68944f6509068c20b6ca 100644 (file)
-/*
- * 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 <adam@sics.se>
- *
- */
-
-
-
-/* ip.c
- *
- * This is the code for the IP layer for IPv6.
- *
- */
-
-
-#include "lwip/opt.h"
-
-#include "lwip/def.h"
-#include "lwip/mem.h"
-#include "lwip/ip.h"
-#include "lwip/inet.h"
-#include "lwip/netif.h"
-#include "lwip/icmp.h"
-#include "lwip/udp.h"
-#include "lwip/tcp.h"
-
-#include "lwip/stats.h"
-
-#include "arch/perf.h"
-
-/* ip_init:
- *
- * Initializes the IP layer.
- */
-
-void
-ip_init(void)
-{
-}
-
-/* ip_route:
- *
- * Finds the appropriate network interface for a given IP address. It searches the
- * list of network interfaces linearly. A match is found if the masked IP address of
- * the network interface equals the masked IP address given to the function.
- */
-
-struct netif *
-ip_route(struct ip_addr *dest)
-{
-  struct netif *netif;
-
-  for(netif = netif_list; netif != NULL; netif = netif->next) {
-    if (ip_addr_netcmp(dest, &(netif->ip_addr), &(netif->netmask))) {
-      return netif;
-    }
-  }
-
-  return netif_default;
-}
-
-/* ip_forward:
- *
- * Forwards an IP packet. It finds an appropriate route for the packet, decrements
- * the TTL value of the packet, adjusts the checksum and outputs the packet on the
- * appropriate interface.
- */
-
-static void
-ip_forward(struct pbuf *p, struct ip_hdr *iphdr)
-{
-  struct netif *netif;
-
-  PERF_START;
-
-  if ((netif = ip_route((struct ip_addr *)&(iphdr->dest))) == NULL) {
-
-    LWIP_DEBUGF(IP_DEBUG, ("ip_input: no forwarding route found for "));
-#if IP_DEBUG
-    ip_addr_debug_print(IP_DEBUG, &(iphdr->dest));
-#endif /* IP_DEBUG */
-    LWIP_DEBUGF(IP_DEBUG, ("\n"));
-    pbuf_free(p);
-    return;
-  }
-  /* Decrement TTL and send ICMP if ttl == 0. */
-  if (--iphdr->hoplim == 0) {
-    /* Don't send ICMP messages in response to ICMP messages */
-    if (iphdr->nexthdr != IP_PROTO_ICMP) {
-      icmp_time_exceeded(p, ICMP_TE_TTL);
-    }
-    pbuf_free(p);
-    return;
-  }
-
-  /* Incremental update of the IP checksum. */
-  /*  if (iphdr->chksum >= htons(0xffff - 0x100)) {
-    iphdr->chksum += htons(0x100) + 1;
-  } else {
-    iphdr->chksum += htons(0x100);
-    }*/
-
-
-  LWIP_DEBUGF(IP_DEBUG, ("ip_forward: forwarding packet to "));
-#if IP_DEBUG
-  ip_addr_debug_print(IP_DEBUG, &(iphdr->dest));
-#endif /* IP_DEBUG */
-  LWIP_DEBUGF(IP_DEBUG, ("\n"));
-
-#ifdef IP_STATS
-  ++lwip_stats.ip.fw;
-  ++lwip_stats.ip.xmit;
-#endif /* IP_STATS */
-
-  PERF_STOP("ip_forward");
-
-  netif->output(netif, p, (struct ip_addr *)&(iphdr->dest));
-}
-
-/* ip_input:
- *
- * This function is called by the network interface device driver when an IP packet is
- * received. The function does the basic checks of the IP header such as packet size
- * being at least larger than the header size etc. If the packet was not destined for
- * us, the packet is forwarded (using ip_forward). The IP checksum is always checked.
- *
- * Finally, the packet is sent to the upper layer protocol input function.
- */
-
-void
-ip_input(struct pbuf *p, struct netif *inp) {
-  struct ip_hdr *iphdr;
-  struct netif *netif;
-
-
-  PERF_START;
-
-#if IP_DEBUG
-  ip_debug_print(p);
-#endif /* IP_DEBUG */
-
-
-#ifdef IP_STATS
-  ++lwip_stats.ip.recv;
-#endif /* IP_STATS */
-
-  /* identify the IP header */
-  iphdr = p->payload;
-
-
-  if (iphdr->v != 6) {
-    LWIP_DEBUGF(IP_DEBUG, ("IP packet dropped due to bad version number\n"));
-#if IP_DEBUG
-    ip_debug_print(p);
-#endif /* IP_DEBUG */
-    pbuf_free(p);
-#ifdef IP_STATS
-    ++lwip_stats.ip.err;
-    ++lwip_stats.ip.drop;
-#endif /* IP_STATS */
-    return;
-  }
-
-  /* is this packet for us? */
-  for(netif = netif_list; netif != NULL; netif = netif->next) {
-#if IP_DEBUG
-    LWIP_DEBUGF(IP_DEBUG, ("ip_input: iphdr->dest "));
-    ip_addr_debug_print(IP_DEBUG, &(iphdr->dest));
-    LWIP_DEBUGF(IP_DEBUG, ("netif->ip_addr "));
-    ip_addr_debug_print(IP_DEBUG, &(netif->ip_addr));
-    LWIP_DEBUGF(IP_DEBUG, ("\n"));
-#endif /* IP_DEBUG */
-    if (ip_addr_cmp(&(iphdr->dest), &(netif->ip_addr))) {
-      break;
-    }
-  }
-
-
-  if (netif == NULL) {
-    /* packet not for us, route or discard */
-#ifdef IP_FORWARD
-    ip_forward(p, iphdr);
-#endif
-    pbuf_free(p);
-    return;
-  }
-
-  pbuf_realloc(p, IP_HLEN + ntohs(iphdr->len));
-
-  /* send to upper layers */
-#if IP_DEBUG
-  /*  LWIP_DEBUGF("ip_input: \n");
-  ip_debug_print(p);
-  LWIP_DEBUGF("ip_input: p->len %u p->tot_len %u\n", p->len, p->tot_len);*/
-#endif /* IP_DEBUG */
-
-
-  pbuf_header(p, -IP_HLEN);
-
-  switch (iphdr->nexthdr) {
-  case IP_PROTO_UDP:
-    udp_input(p);
-    break;
-  case IP_PROTO_TCP:
-    tcp_input(p);
-    break;
-  case IP_PROTO_ICMP:
-    icmp_input(p, inp);
-    break;
-  default:
-    /* send ICMP destination protocol unreachable */
-    icmp_dest_unreach(p, ICMP_DUR_PROTO);
-    pbuf_free(p);
-    LWIP_DEBUGF(IP_DEBUG, ("Unsupported transport protocol %u\n",
-          iphdr->nexthdr));
-
-#ifdef IP_STATS
-    ++lwip_stats.ip.proterr;
-    ++lwip_stats.ip.drop;
-#endif /* IP_STATS */
-
-  }
-  PERF_STOP("ip_input");
-}
-
-
-/* ip_output_if:
- *
- * Sends an IP packet on a network interface. This function constructs the IP header
- * and calculates the IP header checksum. If the source IP address is NULL,
- * the IP address of the outgoing network interface is filled in as source address.
- */
-
-err_t
-ip_output_if (struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
-       u8_t ttl,
-       u8_t proto, struct netif *netif)
-{
-  struct ip_hdr *iphdr;
-
-  PERF_START;
-
-  printf("len %u tot_len %u\n", p->len, p->tot_len);
-  if (pbuf_header(p, IP_HLEN)) {
-    LWIP_DEBUGF(IP_DEBUG, ("ip_output: not enough room for IP header in pbuf\n"));
-#ifdef IP_STATS
-    ++lwip_stats.ip.err;
-#endif /* IP_STATS */
-
-    return ERR_BUF;
-  }
-  printf("len %u tot_len %u\n", p->len, p->tot_len);
-
-  iphdr = p->payload;
-
-
-  if (dest != IP_HDRINCL) {
-    printf("!IP_HDRLINCL\n");
-    iphdr->hoplim = ttl;
-    iphdr->nexthdr = proto;
-    iphdr->len = htons(p->tot_len - IP_HLEN);
-    ip_addr_set(&(iphdr->dest), dest);
-
-    iphdr->v = 6;
-
-    if (ip_addr_isany(src)) {
-      ip_addr_set(&(iphdr->src), &(netif->ip_addr));
-    } else {
-      ip_addr_set(&(iphdr->src), src);
-    }
-
-  } else {
-    dest = &(iphdr->dest);
-  }
-
-#ifdef IP_STATS
-  ++lwip_stats.ip.xmit;
-#endif /* IP_STATS */
-
-  LWIP_DEBUGF(IP_DEBUG, ("ip_output_if: %c%c (len %u)\n", netif->name[0], netif->name[1], p->tot_len));
-#if IP_DEBUG
-  ip_debug_print(p);
-#endif /* IP_DEBUG */
-
-  PERF_STOP("ip_output_if");
-  return netif->output(netif, p, dest);
-}
-
-/* ip_output:
- *
- * Simple interface to ip_output_if. It finds the outgoing network interface and
- * calls upon ip_output_if to do the actual work.
- */
-
-err_t
-ip_output(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
-    u8_t ttl, u8_t proto)
-{
-  struct netif *netif;
-  if ((netif = ip_route(dest)) == NULL) {
-    LWIP_DEBUGF(IP_DEBUG, ("ip_output: No route to 0x%lx\n", dest->addr));
-#ifdef IP_STATS
-    ++lwip_stats.ip.rterr;
-#endif /* IP_STATS */
-    return ERR_RTE;
-  }
-
-  return ip_output_if (p, src, dest, ttl, proto, netif);
-}
-
-#if IP_DEBUG
-void
-ip_debug_print(struct pbuf *p)
-{
-  struct ip_hdr *iphdr = p->payload;
-  char *payload;
-
-  payload = (char *)iphdr + IP_HLEN;
-
-  LWIP_DEBUGF(IP_DEBUG, ("IP header:\n"));
-  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
-  LWIP_DEBUGF(IP_DEBUG, ("|%2d |  %x%x  |      %x%x           | (v, traffic class, flow label)\n",
-        iphdr->v,
-        iphdr->tclass1, iphdr->tclass2,
-        iphdr->flow1, iphdr->flow2));
-  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
-  LWIP_DEBUGF(IP_DEBUG, ("|    %5u      | %2u  |  %2u   | (len, nexthdr, hoplim)\n",
-        ntohs(iphdr->len),
-        iphdr->nexthdr,
-        iphdr->hoplim));
-  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
-  LWIP_DEBUGF(IP_DEBUG, ("|       %4lx      |       %4lx     | (src)\n",
-        ntohl(iphdr->src.addr[0]) >> 16 & 0xffff,
-        ntohl(iphdr->src.addr[0]) & 0xffff));
-  LWIP_DEBUGF(IP_DEBUG, ("|       %4lx      |       %4lx     | (src)\n",
-        ntohl(iphdr->src.addr[1]) >> 16 & 0xffff,
-        ntohl(iphdr->src.addr[1]) & 0xffff));
-  LWIP_DEBUGF(IP_DEBUG, ("|       %4lx      |       %4lx     | (src)\n",
-        ntohl(iphdr->src.addr[2]) >> 16 & 0xffff,
-        ntohl(iphdr->src.addr[2]) & 0xffff));
-  LWIP_DEBUGF(IP_DEBUG, ("|       %4lx      |       %4lx     | (src)\n",
-        ntohl(iphdr->src.addr[3]) >> 16 & 0xffff,
-        ntohl(iphdr->src.addr[3]) & 0xffff));
-  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
-  LWIP_DEBUGF(IP_DEBUG, ("|       %4lx      |       %4lx     | (dest)\n",
-        ntohl(iphdr->dest.addr[0]) >> 16 & 0xffff,
-        ntohl(iphdr->dest.addr[0]) & 0xffff));
-  LWIP_DEBUGF(IP_DEBUG, ("|       %4lx      |       %4lx     | (dest)\n",
-        ntohl(iphdr->dest.addr[1]) >> 16 & 0xffff,
-        ntohl(iphdr->dest.addr[1]) & 0xffff));
-  LWIP_DEBUGF(IP_DEBUG, ("|       %4lx      |       %4lx     | (dest)\n",
-        ntohl(iphdr->dest.addr[2]) >> 16 & 0xffff,
-        ntohl(iphdr->dest.addr[2]) & 0xffff));
-  LWIP_DEBUGF(IP_DEBUG, ("|       %4lx      |       %4lx     | (dest)\n",
-        ntohl(iphdr->dest.addr[3]) >> 16 & 0xffff,
-        ntohl(iphdr->dest.addr[3]) & 0xffff));
-  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
-}
-#endif /* IP_DEBUG */
-
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without modification,\r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED\r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT\r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY\r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ *\r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+\r
+\r
+\r
+/* ip.c\r
+ *\r
+ * This is the code for the IP layer for IPv6.\r
+ *\r
+ */\r
+\r
+\r
+#include "lwip/opt.h"\r
+\r
+#include "lwip/def.h"\r
+#include "lwip/mem.h"\r
+#include "lwip/ip.h"\r
+#include "lwip/inet.h"\r
+#include "lwip/netif.h"\r
+#include "lwip/icmp.h"\r
+#include "lwip/udp.h"\r
+#include "lwip/tcp.h"\r
+\r
+#include "lwip/stats.h"\r
+\r
+#include "arch/perf.h"\r
+\r
+/* ip_init:\r
+ *\r
+ * Initializes the IP layer.\r
+ */\r
+\r
+void\r
+ip_init(void)\r
+{\r
+}\r
+\r
+/* ip_route:\r
+ *\r
+ * Finds the appropriate network interface for a given IP address. It searches the\r
+ * list of network interfaces linearly. A match is found if the masked IP address of\r
+ * the network interface equals the masked IP address given to the function.\r
+ */\r
+\r
+struct netif *\r
+ip_route(struct ip_addr *dest)\r
+{\r
+  struct netif *netif;\r
+\r
+  for(netif = netif_list; netif != NULL; netif = netif->next) {\r
+    if (ip_addr_netcmp(dest, &(netif->ip_addr), &(netif->netmask))) {\r
+      return netif;\r
+    }\r
+  }\r
+\r
+  return netif_default;\r
+}\r
+\r
+/* ip_forward:\r
+ *\r
+ * Forwards an IP packet. It finds an appropriate route for the packet, decrements\r
+ * the TTL value of the packet, adjusts the checksum and outputs the packet on the\r
+ * appropriate interface.\r
+ */\r
+\r
+static void\r
+ip_forward(struct pbuf *p, struct ip_hdr *iphdr)\r
+{\r
+  struct netif *netif;\r
+\r
+  PERF_START;\r
+\r
+  if ((netif = ip_route((struct ip_addr *)&(iphdr->dest))) == NULL) {\r
+\r
+    LWIP_DEBUGF(IP_DEBUG, ("ip_input: no forwarding route found for "));\r
+#if IP_DEBUG\r
+    ip_addr_debug_print(IP_DEBUG, &(iphdr->dest));\r
+#endif /* IP_DEBUG */\r
+    LWIP_DEBUGF(IP_DEBUG, ("\n"));\r
+    pbuf_free(p);\r
+    return;\r
+  }\r
+  /* Decrement TTL and send ICMP if ttl == 0. */\r
+  if (--iphdr->hoplim == 0) {\r
+    /* Don't send ICMP messages in response to ICMP messages */\r
+    if (iphdr->nexthdr != IP_PROTO_ICMP) {\r
+      icmp_time_exceeded(p, ICMP_TE_TTL);\r
+    }\r
+    pbuf_free(p);\r
+    return;\r
+  }\r
+\r
+  /* Incremental update of the IP checksum. */\r
+  /*  if (iphdr->chksum >= htons(0xffff - 0x100)) {\r
+    iphdr->chksum += htons(0x100) + 1;\r
+  } else {\r
+    iphdr->chksum += htons(0x100);\r
+    }*/\r
+\r
+\r
+  LWIP_DEBUGF(IP_DEBUG, ("ip_forward: forwarding packet to "));\r
+#if IP_DEBUG\r
+  ip_addr_debug_print(IP_DEBUG, &(iphdr->dest));\r
+#endif /* IP_DEBUG */\r
+  LWIP_DEBUGF(IP_DEBUG, ("\n"));\r
+\r
+#ifdef IP_STATS\r
+  ++lwip_stats.ip.fw;\r
+  ++lwip_stats.ip.xmit;\r
+#endif /* IP_STATS */\r
+\r
+  PERF_STOP("ip_forward");\r
+\r
+  netif->output(netif, p, (struct ip_addr *)&(iphdr->dest));\r
+}\r
+\r
+/* ip_input:\r
+ *\r
+ * This function is called by the network interface device driver when an IP packet is\r
+ * received. The function does the basic checks of the IP header such as packet size\r
+ * being at least larger than the header size etc. If the packet was not destined for\r
+ * us, the packet is forwarded (using ip_forward). The IP checksum is always checked.\r
+ *\r
+ * Finally, the packet is sent to the upper layer protocol input function.\r
+ */\r
+\r
+void\r
+ip_input(struct pbuf *p, struct netif *inp) {\r
+  struct ip_hdr *iphdr;\r
+  struct netif *netif;\r
+\r
+\r
+  PERF_START;\r
+\r
+#if IP_DEBUG\r
+  ip_debug_print(p);\r
+#endif /* IP_DEBUG */\r
+\r
+\r
+#ifdef IP_STATS\r
+  ++lwip_stats.ip.recv;\r
+#endif /* IP_STATS */\r
+\r
+  /* identify the IP header */\r
+  iphdr = p->payload;\r
+\r
+\r
+  if (iphdr->v != 6) {\r
+    LWIP_DEBUGF(IP_DEBUG, ("IP packet dropped due to bad version number\n"));\r
+#if IP_DEBUG\r
+    ip_debug_print(p);\r
+#endif /* IP_DEBUG */\r
+    pbuf_free(p);\r
+#ifdef IP_STATS\r
+    ++lwip_stats.ip.err;\r
+    ++lwip_stats.ip.drop;\r
+#endif /* IP_STATS */\r
+    return;\r
+  }\r
+\r
+  /* is this packet for us? */\r
+  for(netif = netif_list; netif != NULL; netif = netif->next) {\r
+#if IP_DEBUG\r
+    LWIP_DEBUGF(IP_DEBUG, ("ip_input: iphdr->dest "));\r
+    ip_addr_debug_print(IP_DEBUG, &(iphdr->dest));\r
+    LWIP_DEBUGF(IP_DEBUG, ("netif->ip_addr "));\r
+    ip_addr_debug_print(IP_DEBUG, &(netif->ip_addr));\r
+    LWIP_DEBUGF(IP_DEBUG, ("\n"));\r
+#endif /* IP_DEBUG */\r
+    if (ip_addr_cmp(&(iphdr->dest), &(netif->ip_addr))) {\r
+      break;\r
+    }\r
+  }\r
+\r
+\r
+  if (netif == NULL) {\r
+    /* packet not for us, route or discard */\r
+#ifdef IP_FORWARD\r
+    ip_forward(p, iphdr);\r
+#endif\r
+    pbuf_free(p);\r
+    return;\r
+  }\r
+\r
+  pbuf_realloc(p, IP_HLEN + ntohs(iphdr->len));\r
+\r
+  /* send to upper layers */\r
+#if IP_DEBUG\r
+  /*  LWIP_DEBUGF("ip_input: \n");\r
+  ip_debug_print(p);\r
+  LWIP_DEBUGF("ip_input: p->len %u p->tot_len %u\n", p->len, p->tot_len);*/\r
+#endif /* IP_DEBUG */\r
+\r
+\r
+  pbuf_header(p, -IP_HLEN);\r
+\r
+  switch (iphdr->nexthdr) {\r
+  case IP_PROTO_UDP:\r
+    udp_input(p);\r
+    break;\r
+  case IP_PROTO_TCP:\r
+    tcp_input(p);\r
+    break;\r
+  case IP_PROTO_ICMP:\r
+    icmp_input(p, inp);\r
+    break;\r
+  default:\r
+    /* send ICMP destination protocol unreachable */\r
+    icmp_dest_unreach(p, ICMP_DUR_PROTO);\r
+    pbuf_free(p);\r
+    LWIP_DEBUGF(IP_DEBUG, ("Unsupported transport protocol %u\n",\r
+          iphdr->nexthdr));\r
+\r
+#ifdef IP_STATS\r
+    ++lwip_stats.ip.proterr;\r
+    ++lwip_stats.ip.drop;\r
+#endif /* IP_STATS */\r
+\r
+  }\r
+  PERF_STOP("ip_input");\r
+}\r
+\r
+\r
+/* ip_output_if:\r
+ *\r
+ * Sends an IP packet on a network interface. This function constructs the IP header\r
+ * and calculates the IP header checksum. If the source IP address is NULL,\r
+ * the IP address of the outgoing network interface is filled in as source address.\r
+ */\r
+\r
+err_t\r
+ip_output_if (struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,\r
+       u8_t ttl,\r
+       u8_t proto, struct netif *netif)\r
+{\r
+  struct ip_hdr *iphdr;\r
+\r
+  PERF_START;\r
+\r
+  printf("len %u tot_len %u\n", p->len, p->tot_len);\r
+  if (pbuf_header(p, IP_HLEN)) {\r
+    LWIP_DEBUGF(IP_DEBUG, ("ip_output: not enough room for IP header in pbuf\n"));\r
+#ifdef IP_STATS\r
+    ++lwip_stats.ip.err;\r
+#endif /* IP_STATS */\r
+\r
+    return ERR_BUF;\r
+  }\r
+  printf("len %u tot_len %u\n", p->len, p->tot_len);\r
+\r
+  iphdr = p->payload;\r
+\r
+\r
+  if (dest != IP_HDRINCL) {\r
+    printf("!IP_HDRLINCL\n");\r
+    iphdr->hoplim = ttl;\r
+    iphdr->nexthdr = proto;\r
+    iphdr->len = htons(p->tot_len - IP_HLEN);\r
+    ip_addr_set(&(iphdr->dest), dest);\r
+\r
+    iphdr->v = 6;\r
+\r
+    if (ip_addr_isany(src)) {\r
+      ip_addr_set(&(iphdr->src), &(netif->ip_addr));\r
+    } else {\r
+      ip_addr_set(&(iphdr->src), src);\r
+    }\r
+\r
+  } else {\r
+    dest = &(iphdr->dest);\r
+  }\r
+\r
+#ifdef IP_STATS\r
+  ++lwip_stats.ip.xmit;\r
+#endif /* IP_STATS */\r
+\r
+  LWIP_DEBUGF(IP_DEBUG, ("ip_output_if: %c%c (len %u)\n", netif->name[0], netif->name[1], p->tot_len));\r
+#if IP_DEBUG\r
+  ip_debug_print(p);\r
+#endif /* IP_DEBUG */\r
+\r
+  PERF_STOP("ip_output_if");\r
+  return netif->output(netif, p, dest);\r
+}\r
+\r
+/* ip_output:\r
+ *\r
+ * Simple interface to ip_output_if. It finds the outgoing network interface and\r
+ * calls upon ip_output_if to do the actual work.\r
+ */\r
+\r
+err_t\r
+ip_output(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,\r
+    u8_t ttl, u8_t proto)\r
+{\r
+  struct netif *netif;\r
+  if ((netif = ip_route(dest)) == NULL) {\r
+    LWIP_DEBUGF(IP_DEBUG, ("ip_output: No route to 0x%lx\n", dest->addr));\r
+#ifdef IP_STATS\r
+    ++lwip_stats.ip.rterr;\r
+#endif /* IP_STATS */\r
+    return ERR_RTE;\r
+  }\r
+\r
+  return ip_output_if (p, src, dest, ttl, proto, netif);\r
+}\r
+\r
+#if IP_DEBUG\r
+void\r
+ip_debug_print(struct pbuf *p)\r
+{\r
+  struct ip_hdr *iphdr = p->payload;\r
+  char *payload;\r
+\r
+  payload = (char *)iphdr + IP_HLEN;\r
+\r
+  LWIP_DEBUGF(IP_DEBUG, ("IP header:\n"));\r
+  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));\r
+  LWIP_DEBUGF(IP_DEBUG, ("|%2d |  %x%x  |      %x%x           | (v, traffic class, flow label)\n",\r
+        iphdr->v,\r
+        iphdr->tclass1, iphdr->tclass2,\r
+        iphdr->flow1, iphdr->flow2));\r
+  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));\r
+  LWIP_DEBUGF(IP_DEBUG, ("|    %5u      | %2u  |  %2u   | (len, nexthdr, hoplim)\n",\r
+        ntohs(iphdr->len),\r
+        iphdr->nexthdr,\r
+        iphdr->hoplim));\r
+  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));\r
+  LWIP_DEBUGF(IP_DEBUG, ("|       %4lx      |       %4lx     | (src)\n",\r
+        ntohl(iphdr->src.addr[0]) >> 16 & 0xffff,\r
+        ntohl(iphdr->src.addr[0]) & 0xffff));\r
+  LWIP_DEBUGF(IP_DEBUG, ("|       %4lx      |       %4lx     | (src)\n",\r
+        ntohl(iphdr->src.addr[1]) >> 16 & 0xffff,\r
+        ntohl(iphdr->src.addr[1]) & 0xffff));\r
+  LWIP_DEBUGF(IP_DEBUG, ("|       %4lx      |       %4lx     | (src)\n",\r
+        ntohl(iphdr->src.addr[2]) >> 16 & 0xffff,\r
+        ntohl(iphdr->src.addr[2]) & 0xffff));\r
+  LWIP_DEBUGF(IP_DEBUG, ("|       %4lx      |       %4lx     | (src)\n",\r
+        ntohl(iphdr->src.addr[3]) >> 16 & 0xffff,\r
+        ntohl(iphdr->src.addr[3]) & 0xffff));\r
+  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));\r
+  LWIP_DEBUGF(IP_DEBUG, ("|       %4lx      |       %4lx     | (dest)\n",\r
+        ntohl(iphdr->dest.addr[0]) >> 16 & 0xffff,\r
+        ntohl(iphdr->dest.addr[0]) & 0xffff));\r
+  LWIP_DEBUGF(IP_DEBUG, ("|       %4lx      |       %4lx     | (dest)\n",\r
+        ntohl(iphdr->dest.addr[1]) >> 16 & 0xffff,\r
+        ntohl(iphdr->dest.addr[1]) & 0xffff));\r
+  LWIP_DEBUGF(IP_DEBUG, ("|       %4lx      |       %4lx     | (dest)\n",\r
+        ntohl(iphdr->dest.addr[2]) >> 16 & 0xffff,\r
+        ntohl(iphdr->dest.addr[2]) & 0xffff));\r
+  LWIP_DEBUGF(IP_DEBUG, ("|       %4lx      |       %4lx     | (dest)\n",\r
+        ntohl(iphdr->dest.addr[3]) >> 16 & 0xffff,\r
+        ntohl(iphdr->dest.addr[3]) & 0xffff));\r
+  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));\r
+}\r
+#endif /* IP_DEBUG */\r
+\r
index d1bc358a691564d8a6a12a37565c967c32f858c4..fbc03aa99d09e47e845af80bc49077a297f62500 100644 (file)
@@ -1,90 +1,90 @@
-/*
- * 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 <adam@sics.se>
- *
- */
-
-#include "lwip/ip_addr.h"
-#include "lwip/inet.h"
-
-
-int
-ip_addr_netcmp(struct ip_addr *addr1, struct ip_addr *addr2,
-                struct ip_addr *mask)
-{
-  return((addr1->addr[0] & mask->addr[0]) == (addr2->addr[0] & mask->addr[0]) &&
-         (addr1->addr[1] & mask->addr[1]) == (addr2->addr[1] & mask->addr[1]) &&
-         (addr1->addr[2] & mask->addr[2]) == (addr2->addr[2] & mask->addr[2]) &&
-         (addr1->addr[3] & mask->addr[3]) == (addr2->addr[3] & mask->addr[3]));
-        
-}
-
-int
-ip_addr_cmp(struct ip_addr *addr1, struct ip_addr *addr2)
-{
-  return(addr1->addr[0] == addr2->addr[0] &&
-         addr1->addr[1] == addr2->addr[1] &&
-         addr1->addr[2] == addr2->addr[2] &&
-         addr1->addr[3] == addr2->addr[3]);
-}
-
-void
-ip_addr_set(struct ip_addr *dest, struct ip_addr *src)
-{
-  memcpy(dest, src, sizeof(struct ip_addr));
-  /*  dest->addr[0] = src->addr[0];
-  dest->addr[1] = src->addr[1];
-  dest->addr[2] = src->addr[2];
-  dest->addr[3] = src->addr[3];*/
-}
-
-int
-ip_addr_isany(struct ip_addr *addr)
-{
-  if (addr == NULL) return 1;
-  return((addr->addr[0] | addr->addr[1] | addr->addr[2] | addr->addr[3]) == 0);
-}
-
-
-/*#if IP_DEBUG*/
-void
-ip_addr_debug_print(struct ip_addr *addr)
-{
-  printf("%lx:%lx:%lx:%lx:%lx:%lx:%lx:%lx",
-         ntohl(addr->addr[0]) >> 16 & 0xffff,
-         ntohl(addr->addr[0]) & 0xffff,
-         ntohl(addr->addr[1]) >> 16 & 0xffff,
-         ntohl(addr->addr[1]) & 0xffff,
-         ntohl(addr->addr[2]) >> 16 & 0xffff,
-         ntohl(addr->addr[2]) & 0xffff,
-         ntohl(addr->addr[3]) >> 16 & 0xffff,
-         ntohl(addr->addr[3]) & 0xffff);
-}
-/*#endif*/ /* IP_DEBUG */
-
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+\r
+#include "lwip/ip_addr.h"\r
+#include "lwip/inet.h"\r
+\r
+\r
+int\r
+ip_addr_netcmp(struct ip_addr *addr1, struct ip_addr *addr2,\r
+                struct ip_addr *mask)\r
+{\r
+  return((addr1->addr[0] & mask->addr[0]) == (addr2->addr[0] & mask->addr[0]) &&\r
+         (addr1->addr[1] & mask->addr[1]) == (addr2->addr[1] & mask->addr[1]) &&\r
+         (addr1->addr[2] & mask->addr[2]) == (addr2->addr[2] & mask->addr[2]) &&\r
+         (addr1->addr[3] & mask->addr[3]) == (addr2->addr[3] & mask->addr[3]));\r
+        \r
+}\r
+\r
+int\r
+ip_addr_cmp(struct ip_addr *addr1, struct ip_addr *addr2)\r
+{\r
+  return(addr1->addr[0] == addr2->addr[0] &&\r
+         addr1->addr[1] == addr2->addr[1] &&\r
+         addr1->addr[2] == addr2->addr[2] &&\r
+         addr1->addr[3] == addr2->addr[3]);\r
+}\r
+\r
+void\r
+ip_addr_set(struct ip_addr *dest, struct ip_addr *src)\r
+{\r
+  memcpy(dest, src, sizeof(struct ip_addr));\r
+  /*  dest->addr[0] = src->addr[0];\r
+  dest->addr[1] = src->addr[1];\r
+  dest->addr[2] = src->addr[2];\r
+  dest->addr[3] = src->addr[3];*/\r
+}\r
+\r
+int\r
+ip_addr_isany(struct ip_addr *addr)\r
+{\r
+  if (addr == NULL) return 1;\r
+  return((addr->addr[0] | addr->addr[1] | addr->addr[2] | addr->addr[3]) == 0);\r
+}\r
+\r
+\r
+/*#if IP_DEBUG*/\r
+void\r
+ip_addr_debug_print(struct ip_addr *addr)\r
+{\r
+  printf("%lx:%lx:%lx:%lx:%lx:%lx:%lx:%lx",\r
+         ntohl(addr->addr[0]) >> 16 & 0xffff,\r
+         ntohl(addr->addr[0]) & 0xffff,\r
+         ntohl(addr->addr[1]) >> 16 & 0xffff,\r
+         ntohl(addr->addr[1]) & 0xffff,\r
+         ntohl(addr->addr[2]) >> 16 & 0xffff,\r
+         ntohl(addr->addr[2]) & 0xffff,\r
+         ntohl(addr->addr[3]) >> 16 & 0xffff,\r
+         ntohl(addr->addr[3]) & 0xffff);\r
+}\r
+/*#endif*/ /* IP_DEBUG */\r
+\r
index aea62963bc044a1cb53a4bc0e9e0e71aaf57f486..6e061684aef8e20ae102c45abc73033b474b35d9 100644 (file)
-/** @file
- *
- * Dynamic memory manager
- *
- */
-
-/* 
- * 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 <adam@sics.se>
- *
- */
-
-#include <string.h>
-
-#include "lwip/arch.h"
-#include "lwip/opt.h"
-#include "lwip/def.h"
-#include "lwip/mem.h"
-
-#include "lwip/sys.h"
-
-#include "lwip/stats.h"
-
-struct mem {
-  mem_size_t next, prev;
-#if MEM_ALIGNMENT == 1
-  u8_t used;
-#elif MEM_ALIGNMENT == 2
-  u16_t used;
-#elif MEM_ALIGNMENT == 4
-  u32_t used;
-#elif MEM_ALIGNMENT == 8
-  u64_t used;
-#else
-#error "unhandled MEM_ALIGNMENT size"
-#endif /* MEM_ALIGNMENT */
-}; 
-
-static struct mem *ram_end;
-static u8_t ram[MEM_SIZE + sizeof(struct mem) + MEM_ALIGNMENT];
-
-#define MIN_SIZE 12
-#if 0 /* this one does not align correctly for some, resulting in crashes */
-#define SIZEOF_STRUCT_MEM (unsigned int)MEM_ALIGN_SIZE(sizeof(struct mem))
-#else
-#define SIZEOF_STRUCT_MEM (sizeof(struct mem) + \
-                          (((sizeof(struct mem) % MEM_ALIGNMENT) == 0)? 0 : \
-                          (4 - (sizeof(struct mem) % MEM_ALIGNMENT))))
-#endif
-
-static struct mem *lfree;   /* pointer to the lowest free block */
-
-static sys_sem_t mem_sem;
-
-static void
-plug_holes(struct mem *mem)
-{
-  struct mem *nmem;
-  struct mem *pmem;
-
-  LWIP_ASSERT("plug_holes: mem >= ram", (u8_t *)mem >= ram);
-  LWIP_ASSERT("plug_holes: mem < ram_end", (u8_t *)mem < (u8_t *)ram_end);
-  LWIP_ASSERT("plug_holes: mem->used == 0", mem->used == 0);
-  
-  /* plug hole forward */
-  LWIP_ASSERT("plug_holes: mem->next <= MEM_SIZE", mem->next <= MEM_SIZE);
-  
-  nmem = (struct mem *)&ram[mem->next];
-  if (mem != nmem && nmem->used == 0 && (u8_t *)nmem != (u8_t *)ram_end) {
-    if (lfree == nmem) {
-      lfree = mem;
-    }
-    mem->next = nmem->next;
-    ((struct mem *)&ram[nmem->next])->prev = (u8_t *)mem - ram;
-  }
-
-  /* plug hole backward */
-  pmem = (struct mem *)&ram[mem->prev];
-  if (pmem != mem && pmem->used == 0) {
-    if (lfree == mem) {
-      lfree = pmem;
-    }
-    pmem->next = mem->next;
-    ((struct mem *)&ram[mem->next])->prev = (u8_t *)pmem - ram;
-  }
-
-}
-void
-mem_init(void)
-{
-  struct mem *mem;
-
-  memset(ram, 0, MEM_SIZE);
-  mem = (struct mem *)ram;
-  mem->next = MEM_SIZE;
-  mem->prev = 0;
-  mem->used = 0;
-  ram_end = (struct mem *)&ram[MEM_SIZE];
-  ram_end->used = 1;
-  ram_end->next = MEM_SIZE;
-  ram_end->prev = MEM_SIZE;
-
-  mem_sem = sys_sem_new(1);
-
-  lfree = (struct mem *)ram;
-
-#if MEM_STATS
-  lwip_stats.mem.avail = MEM_SIZE;
-#endif /* MEM_STATS */
-}
-void
-mem_free(void *rmem)
-{
-  struct mem *mem;
-
-  if (rmem == NULL) {
-    LWIP_DEBUGF(MEM_DEBUG | DBG_TRACE | 2, ("mem_free(p == NULL) was called.\n"));
-    return;
-  }
-  
-  sys_sem_wait(mem_sem);
-
-  LWIP_ASSERT("mem_free: legal memory", (u8_t *)rmem >= (u8_t *)ram &&
-    (u8_t *)rmem < (u8_t *)ram_end);
-  
-  if ((u8_t *)rmem < (u8_t *)ram || (u8_t *)rmem >= (u8_t *)ram_end) {
-    LWIP_DEBUGF(MEM_DEBUG | 3, ("mem_free: illegal memory\n"));
-#if MEM_STATS
-    ++lwip_stats.mem.err;
-#endif /* MEM_STATS */
-    sys_sem_signal(mem_sem);
-    return;
-  }
-  mem = (struct mem *)((u8_t *)rmem - SIZEOF_STRUCT_MEM);
-
-  LWIP_ASSERT("mem_free: mem->used", mem->used);
-  
-  mem->used = 0;
-
-  if (mem < lfree) {
-    lfree = mem;
-  }
-  
-#if MEM_STATS
-  lwip_stats.mem.used -= mem->next - ((u8_t *)mem - ram);
-  
-#endif /* MEM_STATS */
-  plug_holes(mem);
-  sys_sem_signal(mem_sem);
-}
-void *
-mem_reallocm(void *rmem, mem_size_t newsize)
-{
-  void *nmem;
-  nmem = mem_malloc(newsize);
-  if (nmem == NULL) {
-    return mem_realloc(rmem, newsize);
-  }
-  memcpy(nmem, rmem, newsize);
-  mem_free(rmem);
-  return nmem;
-}
-
-void *
-mem_realloc(void *rmem, mem_size_t newsize)
-{
-  mem_size_t size;
-  mem_size_t ptr, ptr2;
-  struct mem *mem, *mem2;
-
-  /* Expand the size of the allocated memory region so that we can
-     adjust for alignment. */
-  if ((newsize % MEM_ALIGNMENT) != 0) {
-   newsize += MEM_ALIGNMENT - ((newsize + SIZEOF_STRUCT_MEM) % MEM_ALIGNMENT);
-  }
-  
-  if (newsize > MEM_SIZE) {
-    return NULL;
-  }
-  
-  sys_sem_wait(mem_sem);
-  
-  LWIP_ASSERT("mem_realloc: legal memory", (u8_t *)rmem >= (u8_t *)ram &&
-   (u8_t *)rmem < (u8_t *)ram_end);
-  
-  if ((u8_t *)rmem < (u8_t *)ram || (u8_t *)rmem >= (u8_t *)ram_end) {
-    LWIP_DEBUGF(MEM_DEBUG | 3, ("mem_realloc: illegal memory\n"));
-    return rmem;
-  }
-  mem = (struct mem *)((u8_t *)rmem - SIZEOF_STRUCT_MEM);
-
-  ptr = (u8_t *)mem - ram;
-
-  size = mem->next - ptr - SIZEOF_STRUCT_MEM;
-#if MEM_STATS
-  lwip_stats.mem.used -= (size - newsize);
-#endif /* MEM_STATS */
-  
-  if (newsize + SIZEOF_STRUCT_MEM + MIN_SIZE < size) {
-    ptr2 = ptr + SIZEOF_STRUCT_MEM + newsize;
-    mem2 = (struct mem *)&ram[ptr2];
-    mem2->used = 0;
-    mem2->next = mem->next;
-    mem2->prev = ptr;
-    mem->next = ptr2;
-    if (mem2->next != MEM_SIZE) {
-      ((struct mem *)&ram[mem2->next])->prev = ptr2;
-    }
-
-    plug_holes(mem2);
-  }
-  sys_sem_signal(mem_sem);  
-  return rmem;
-}
-void *
-mem_malloc(mem_size_t size)
-{
-  mem_size_t ptr, ptr2;
-  struct mem *mem, *mem2;
-
-  if (size == 0) {
-    return NULL;
-  }
-
-  /* Expand the size of the allocated memory region so that we can
-     adjust for alignment. */
-  if ((size % MEM_ALIGNMENT) != 0) {
-    size += MEM_ALIGNMENT - ((size + SIZEOF_STRUCT_MEM) % MEM_ALIGNMENT);
-  }
-  
-  if (size > MEM_SIZE) {
-    return NULL;
-  }
-  
-  sys_sem_wait(mem_sem);
-
-  for (ptr = (u8_t *)lfree - ram; ptr < MEM_SIZE; ptr = ((struct mem *)&ram[ptr])->next) {
-    mem = (struct mem *)&ram[ptr];
-    if (!mem->used &&
-       mem->next - (ptr + SIZEOF_STRUCT_MEM) >= size + SIZEOF_STRUCT_MEM) {
-      ptr2 = ptr + SIZEOF_STRUCT_MEM + size;
-      mem2 = (struct mem *)&ram[ptr2];
-
-      mem2->prev = ptr;      
-      mem2->next = mem->next;
-      mem->next = ptr2;      
-      if (mem2->next != MEM_SIZE) {
-        ((struct mem *)&ram[mem2->next])->prev = ptr2;
-      }
-      
-      mem2->used = 0;      
-      mem->used = 1;
-#if MEM_STATS
-      lwip_stats.mem.used += (size + SIZEOF_STRUCT_MEM);
-      /*      if (lwip_stats.mem.max < lwip_stats.mem.used) {
-        lwip_stats.mem.max = lwip_stats.mem.used;
-  } */
-      if (lwip_stats.mem.max < ptr2) {
-        lwip_stats.mem.max = ptr2;
-      }      
-#endif /* MEM_STATS */
-
-      if (mem == lfree) {
-  /* Find next free block after mem */
-        while (lfree->used && lfree != ram_end) {
-    lfree = (struct mem *)&ram[lfree->next];
-        }
-        LWIP_ASSERT("mem_malloc: !lfree->used", !lfree->used);
-      }
-      sys_sem_signal(mem_sem);
-      LWIP_ASSERT("mem_malloc: allocated memory not above ram_end.",
-       (mem_ptr_t)mem + SIZEOF_STRUCT_MEM + size <= (mem_ptr_t)ram_end);
-      LWIP_ASSERT("mem_malloc: allocated memory properly aligned.",
-       (unsigned long)((u8_t *)mem + SIZEOF_STRUCT_MEM) % MEM_ALIGNMENT == 0);
-      return (u8_t *)mem + SIZEOF_STRUCT_MEM;
-    }    
-  }
-  LWIP_DEBUGF(MEM_DEBUG | 2, ("mem_malloc: could not allocate %d bytes\n", (int)size));
-#if MEM_STATS
-  ++lwip_stats.mem.err;
-#endif /* MEM_STATS */  
-  sys_sem_signal(mem_sem);
-  return NULL;
-}
+/** @file\r
+ *\r
+ * Dynamic memory manager\r
+ *\r
+ */\r
+\r
+/* \r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+\r
+#include <string.h>\r
+\r
+#include "lwip/arch.h"\r
+#include "lwip/opt.h"\r
+#include "lwip/def.h"\r
+#include "lwip/mem.h"\r
+\r
+#include "lwip/sys.h"\r
+\r
+#include "lwip/stats.h"\r
+\r
+struct mem {\r
+  mem_size_t next, prev;\r
+#if MEM_ALIGNMENT == 1\r
+  u8_t used;\r
+#elif MEM_ALIGNMENT == 2\r
+  u16_t used;\r
+#elif MEM_ALIGNMENT == 4\r
+  u32_t used;\r
+#elif MEM_ALIGNMENT == 8\r
+  u64_t used;\r
+#else\r
+#error "unhandled MEM_ALIGNMENT size"\r
+#endif /* MEM_ALIGNMENT */\r
+}; \r
+\r
+static struct mem *ram_end;\r
+static u8_t ram[MEM_SIZE + sizeof(struct mem) + MEM_ALIGNMENT];\r
+\r
+#define MIN_SIZE 12\r
+#if 0 /* this one does not align correctly for some, resulting in crashes */\r
+#define SIZEOF_STRUCT_MEM (unsigned int)MEM_ALIGN_SIZE(sizeof(struct mem))\r
+#else\r
+#define SIZEOF_STRUCT_MEM (sizeof(struct mem) + \\r
+                          (((sizeof(struct mem) % MEM_ALIGNMENT) == 0)? 0 : \\r
+                          (4 - (sizeof(struct mem) % MEM_ALIGNMENT))))\r
+#endif\r
+\r
+static struct mem *lfree;   /* pointer to the lowest free block */\r
+\r
+static sys_sem_t mem_sem;\r
+\r
+static void\r
+plug_holes(struct mem *mem)\r
+{\r
+  struct mem *nmem;\r
+  struct mem *pmem;\r
+\r
+  LWIP_ASSERT("plug_holes: mem >= ram", (u8_t *)mem >= ram);\r
+  LWIP_ASSERT("plug_holes: mem < ram_end", (u8_t *)mem < (u8_t *)ram_end);\r
+  LWIP_ASSERT("plug_holes: mem->used == 0", mem->used == 0);\r
+  \r
+  /* plug hole forward */\r
+  LWIP_ASSERT("plug_holes: mem->next <= MEM_SIZE", mem->next <= MEM_SIZE);\r
+  \r
+  nmem = (struct mem *)&ram[mem->next];\r
+  if (mem != nmem && nmem->used == 0 && (u8_t *)nmem != (u8_t *)ram_end) {\r
+    if (lfree == nmem) {\r
+      lfree = mem;\r
+    }\r
+    mem->next = nmem->next;\r
+    ((struct mem *)&ram[nmem->next])->prev = (u8_t *)mem - ram;\r
+  }\r
+\r
+  /* plug hole backward */\r
+  pmem = (struct mem *)&ram[mem->prev];\r
+  if (pmem != mem && pmem->used == 0) {\r
+    if (lfree == mem) {\r
+      lfree = pmem;\r
+    }\r
+    pmem->next = mem->next;\r
+    ((struct mem *)&ram[mem->next])->prev = (u8_t *)pmem - ram;\r
+  }\r
+\r
+}\r
+void\r
+mem_init(void)\r
+{\r
+  struct mem *mem;\r
+\r
+  memset(ram, 0, MEM_SIZE);\r
+  mem = (struct mem *)ram;\r
+  mem->next = MEM_SIZE;\r
+  mem->prev = 0;\r
+  mem->used = 0;\r
+  ram_end = (struct mem *)&ram[MEM_SIZE];\r
+  ram_end->used = 1;\r
+  ram_end->next = MEM_SIZE;\r
+  ram_end->prev = MEM_SIZE;\r
+\r
+  mem_sem = sys_sem_new(1);\r
+\r
+  lfree = (struct mem *)ram;\r
+\r
+#if MEM_STATS\r
+  lwip_stats.mem.avail = MEM_SIZE;\r
+#endif /* MEM_STATS */\r
+}\r
+void\r
+mem_free(void *rmem)\r
+{\r
+  struct mem *mem;\r
+\r
+  if (rmem == NULL) {\r
+    LWIP_DEBUGF(MEM_DEBUG | DBG_TRACE | 2, ("mem_free(p == NULL) was called.\n"));\r
+    return;\r
+  }\r
+  \r
+  sys_sem_wait(mem_sem);\r
+\r
+  LWIP_ASSERT("mem_free: legal memory", (u8_t *)rmem >= (u8_t *)ram &&\r
+    (u8_t *)rmem < (u8_t *)ram_end);\r
+  \r
+  if ((u8_t *)rmem < (u8_t *)ram || (u8_t *)rmem >= (u8_t *)ram_end) {\r
+    LWIP_DEBUGF(MEM_DEBUG | 3, ("mem_free: illegal memory\n"));\r
+#if MEM_STATS\r
+    ++lwip_stats.mem.err;\r
+#endif /* MEM_STATS */\r
+    sys_sem_signal(mem_sem);\r
+    return;\r
+  }\r
+  mem = (struct mem *)((u8_t *)rmem - SIZEOF_STRUCT_MEM);\r
+\r
+  LWIP_ASSERT("mem_free: mem->used", mem->used);\r
+  \r
+  mem->used = 0;\r
+\r
+  if (mem < lfree) {\r
+    lfree = mem;\r
+  }\r
+  \r
+#if MEM_STATS\r
+  lwip_stats.mem.used -= mem->next - ((u8_t *)mem - ram);\r
+  \r
+#endif /* MEM_STATS */\r
+  plug_holes(mem);\r
+  sys_sem_signal(mem_sem);\r
+}\r
+void *\r
+mem_reallocm(void *rmem, mem_size_t newsize)\r
+{\r
+  void *nmem;\r
+  nmem = mem_malloc(newsize);\r
+  if (nmem == NULL) {\r
+    return mem_realloc(rmem, newsize);\r
+  }\r
+  memcpy(nmem, rmem, newsize);\r
+  mem_free(rmem);\r
+  return nmem;\r
+}\r
+\r
+void *\r
+mem_realloc(void *rmem, mem_size_t newsize)\r
+{\r
+  mem_size_t size;\r
+  mem_size_t ptr, ptr2;\r
+  struct mem *mem, *mem2;\r
+\r
+  /* Expand the size of the allocated memory region so that we can\r
+     adjust for alignment. */\r
+  if ((newsize % MEM_ALIGNMENT) != 0) {\r
+   newsize += MEM_ALIGNMENT - ((newsize + SIZEOF_STRUCT_MEM) % MEM_ALIGNMENT);\r
+  }\r
+  \r
+  if (newsize > MEM_SIZE) {\r
+    return NULL;\r
+  }\r
+  \r
+  sys_sem_wait(mem_sem);\r
+  \r
+  LWIP_ASSERT("mem_realloc: legal memory", (u8_t *)rmem >= (u8_t *)ram &&\r
+   (u8_t *)rmem < (u8_t *)ram_end);\r
+  \r
+  if ((u8_t *)rmem < (u8_t *)ram || (u8_t *)rmem >= (u8_t *)ram_end) {\r
+    LWIP_DEBUGF(MEM_DEBUG | 3, ("mem_realloc: illegal memory\n"));\r
+    return rmem;\r
+  }\r
+  mem = (struct mem *)((u8_t *)rmem - SIZEOF_STRUCT_MEM);\r
+\r
+  ptr = (u8_t *)mem - ram;\r
+\r
+  size = mem->next - ptr - SIZEOF_STRUCT_MEM;\r
+#if MEM_STATS\r
+  lwip_stats.mem.used -= (size - newsize);\r
+#endif /* MEM_STATS */\r
+  \r
+  if (newsize + SIZEOF_STRUCT_MEM + MIN_SIZE < size) {\r
+    ptr2 = ptr + SIZEOF_STRUCT_MEM + newsize;\r
+    mem2 = (struct mem *)&ram[ptr2];\r
+    mem2->used = 0;\r
+    mem2->next = mem->next;\r
+    mem2->prev = ptr;\r
+    mem->next = ptr2;\r
+    if (mem2->next != MEM_SIZE) {\r
+      ((struct mem *)&ram[mem2->next])->prev = ptr2;\r
+    }\r
+\r
+    plug_holes(mem2);\r
+  }\r
+  sys_sem_signal(mem_sem);  \r
+  return rmem;\r
+}\r
+void *\r
+mem_malloc(mem_size_t size)\r
+{\r
+  mem_size_t ptr, ptr2;\r
+  struct mem *mem, *mem2;\r
+\r
+  if (size == 0) {\r
+    return NULL;\r
+  }\r
+\r
+  /* Expand the size of the allocated memory region so that we can\r
+     adjust for alignment. */\r
+  if ((size % MEM_ALIGNMENT) != 0) {\r
+    size += MEM_ALIGNMENT - ((size + SIZEOF_STRUCT_MEM) % MEM_ALIGNMENT);\r
+  }\r
+  \r
+  if (size > MEM_SIZE) {\r
+    return NULL;\r
+  }\r
+  \r
+  sys_sem_wait(mem_sem);\r
+\r
+  for (ptr = (u8_t *)lfree - ram; ptr < MEM_SIZE; ptr = ((struct mem *)&ram[ptr])->next) {\r
+    mem = (struct mem *)&ram[ptr];\r
+    if (!mem->used &&\r
+       mem->next - (ptr + SIZEOF_STRUCT_MEM) >= size + SIZEOF_STRUCT_MEM) {\r
+      ptr2 = ptr + SIZEOF_STRUCT_MEM + size;\r
+      mem2 = (struct mem *)&ram[ptr2];\r
+\r
+      mem2->prev = ptr;      \r
+      mem2->next = mem->next;\r
+      mem->next = ptr2;      \r
+      if (mem2->next != MEM_SIZE) {\r
+        ((struct mem *)&ram[mem2->next])->prev = ptr2;\r
+      }\r
+      \r
+      mem2->used = 0;      \r
+      mem->used = 1;\r
+#if MEM_STATS\r
+      lwip_stats.mem.used += (size + SIZEOF_STRUCT_MEM);\r
+      /*      if (lwip_stats.mem.max < lwip_stats.mem.used) {\r
+        lwip_stats.mem.max = lwip_stats.mem.used;\r
+  } */\r
+      if (lwip_stats.mem.max < ptr2) {\r
+        lwip_stats.mem.max = ptr2;\r
+      }      \r
+#endif /* MEM_STATS */\r
+\r
+      if (mem == lfree) {\r
+  /* Find next free block after mem */\r
+        while (lfree->used && lfree != ram_end) {\r
+    lfree = (struct mem *)&ram[lfree->next];\r
+        }\r
+        LWIP_ASSERT("mem_malloc: !lfree->used", !lfree->used);\r
+      }\r
+      sys_sem_signal(mem_sem);\r
+      LWIP_ASSERT("mem_malloc: allocated memory not above ram_end.",\r
+       (mem_ptr_t)mem + SIZEOF_STRUCT_MEM + size <= (mem_ptr_t)ram_end);\r
+      LWIP_ASSERT("mem_malloc: allocated memory properly aligned.",\r
+       (unsigned long)((u8_t *)mem + SIZEOF_STRUCT_MEM) % MEM_ALIGNMENT == 0);\r
+      return (u8_t *)mem + SIZEOF_STRUCT_MEM;\r
+    }    \r
+  }\r
+  LWIP_DEBUGF(MEM_DEBUG | 2, ("mem_malloc: could not allocate %d bytes\n", (int)size));\r
+#if MEM_STATS\r
+  ++lwip_stats.mem.err;\r
+#endif /* MEM_STATS */  \r
+  sys_sem_signal(mem_sem);\r
+  return NULL;\r
+}\r
index c570b7e10250b9e3abd6457512288d627f1c1552..731c8cade36e69c4d6333d181f7ca93cbe1353a3 100644 (file)
-/*
- * 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 <adam@sics.se>
- *
- */
-
-#include "lwip/opt.h"
-
-#include "lwip/memp.h"
-
-#include "lwip/pbuf.h"
-#include "lwip/udp.h"
-#include "lwip/raw.h"
-#include "lwip/tcp.h"
-#include "lwip/api.h"
-#include "lwip/api_msg.h"
-#include "lwip/tcpip.h"
-
-#include "lwip/sys.h"
-#include "lwip/stats.h"
-
-struct memp {
-  struct memp *next;
-};
-
-
-
-static struct memp *memp_tab[MEMP_MAX];
-
-static const u16_t memp_sizes[MEMP_MAX] = {
-  sizeof(struct pbuf),
-  sizeof(struct raw_pcb),
-  sizeof(struct udp_pcb),
-  sizeof(struct tcp_pcb),
-  sizeof(struct tcp_pcb_listen),
-  sizeof(struct tcp_seg),
-  sizeof(struct netbuf),
-  sizeof(struct netconn),
-  sizeof(struct api_msg),
-  sizeof(struct tcpip_msg),
-  sizeof(struct sys_timeout)
-};
-
-static const u16_t memp_num[MEMP_MAX] = {
-  MEMP_NUM_PBUF,
-  MEMP_NUM_RAW_PCB,
-  MEMP_NUM_UDP_PCB,
-  MEMP_NUM_TCP_PCB,
-  MEMP_NUM_TCP_PCB_LISTEN,
-  MEMP_NUM_TCP_SEG,
-  MEMP_NUM_NETBUF,
-  MEMP_NUM_NETCONN,
-  MEMP_NUM_API_MSG,
-  MEMP_NUM_TCPIP_MSG,
-  MEMP_NUM_SYS_TIMEOUT
-};
-
-static u8_t memp_memory[(MEMP_NUM_PBUF *
-       MEM_ALIGN_SIZE(sizeof(struct pbuf) +
-          sizeof(struct memp)) +
-      MEMP_NUM_RAW_PCB *
-       MEM_ALIGN_SIZE(sizeof(struct raw_pcb) +
-          sizeof(struct memp)) +
-      MEMP_NUM_UDP_PCB *
-       MEM_ALIGN_SIZE(sizeof(struct udp_pcb) +
-          sizeof(struct memp)) +
-      MEMP_NUM_TCP_PCB *
-       MEM_ALIGN_SIZE(sizeof(struct tcp_pcb) +
-          sizeof(struct memp)) +
-      MEMP_NUM_TCP_PCB_LISTEN *
-       MEM_ALIGN_SIZE(sizeof(struct tcp_pcb_listen) +
-          sizeof(struct memp)) +
-      MEMP_NUM_TCP_SEG *
-       MEM_ALIGN_SIZE(sizeof(struct tcp_seg) +
-          sizeof(struct memp)) +
-      MEMP_NUM_NETBUF *
-       MEM_ALIGN_SIZE(sizeof(struct netbuf) +
-          sizeof(struct memp)) +
-      MEMP_NUM_NETCONN *
-       MEM_ALIGN_SIZE(sizeof(struct netconn) +
-          sizeof(struct memp)) +
-      MEMP_NUM_API_MSG *
-       MEM_ALIGN_SIZE(sizeof(struct api_msg) +
-          sizeof(struct memp)) +
-      MEMP_NUM_TCPIP_MSG *
-       MEM_ALIGN_SIZE(sizeof(struct tcpip_msg) +
-          sizeof(struct memp)) +
-      MEMP_NUM_SYS_TIMEOUT *
-       MEM_ALIGN_SIZE(sizeof(struct sys_timeout) +
-          sizeof(struct memp)))];
-
-
-#if !SYS_LIGHTWEIGHT_PROT
-static sys_sem_t mutex;
-#endif
-
-#if MEMP_SANITY_CHECK
-static int
-memp_sanity(void)
-{
-  int i, c;
-  struct memp *m, *n;
-
-  for(i = 0; i < MEMP_MAX; i++) {
-    for(m = memp_tab[i]; m != NULL; m = m->next) {
-      c = 1;
-      for(n = memp_tab[i]; n != NULL; n = n->next) {
-         if (n == m) {
-          --c;
-        }
-        if (c < 0) return 0; /* LW was: abort(); */
-      }
-    }
-  }
-  return 1;
-}
-#endif /* MEMP_SANITY_CHECK*/
-
-void
-memp_init(void)
-{
-  struct memp *m, *memp;
-  u16_t i, j;
-  u16_t size;
-      
-#if MEMP_STATS
-  for(i = 0; i < MEMP_MAX; ++i) {
-    lwip_stats.memp[i].used = lwip_stats.memp[i].max =
-      lwip_stats.memp[i].err = 0;
-    lwip_stats.memp[i].avail = memp_num[i];
-  }
-#endif /* MEMP_STATS */
-
-  memp = (struct memp *)&memp_memory[0];
-  for(i = 0; i < MEMP_MAX; ++i) {
-    size = MEM_ALIGN_SIZE(memp_sizes[i] + sizeof(struct memp));
-    if (memp_num[i] > 0) {
-      memp_tab[i] = memp;
-      m = memp;
-      
-      for(j = 0; j < memp_num[i]; ++j) {
-  m->next = (struct memp *)MEM_ALIGN((u8_t *)m + size);
-  memp = m;
-  m = m->next;
-      }
-      memp->next = NULL;
-      memp = m;
-    } else {
-      memp_tab[i] = NULL;
-    }
-  }
-
-#if !SYS_LIGHTWEIGHT_PROT
-  mutex = sys_sem_new(1);
-#endif
-
-  
-}
-
-void *
-memp_malloc(memp_t type)
-{
-  struct memp *memp;
-  void *mem;
-#if SYS_LIGHTWEIGHT_PROT
-  SYS_ARCH_DECL_PROTECT(old_level);
-#endif
-  LWIP_ASSERT("memp_malloc: type < MEMP_MAX", type < MEMP_MAX);
-
-#if SYS_LIGHTWEIGHT_PROT
-  SYS_ARCH_PROTECT(old_level);
-#else /* SYS_LIGHTWEIGHT_PROT */  
-  sys_sem_wait(mutex);
-#endif /* SYS_LIGHTWEIGHT_PROT */  
-
-  memp = memp_tab[type];
-  
-  if (memp != NULL) {    
-    memp_tab[type] = memp->next;    
-    memp->next = NULL;
-#if MEMP_STATS
-    ++lwip_stats.memp[type].used;
-    if (lwip_stats.memp[type].used > lwip_stats.memp[type].max) {
-      lwip_stats.memp[type].max = lwip_stats.memp[type].used;
-    }
-#endif /* MEMP_STATS */
-#if SYS_LIGHTWEIGHT_PROT
-    SYS_ARCH_UNPROTECT(old_level);
-#else /* SYS_LIGHTWEIGHT_PROT */
-    sys_sem_signal(mutex);
-#endif /* SYS_LIGHTWEIGHT_PROT */  
-    LWIP_ASSERT("memp_malloc: memp properly aligned",
-     ((mem_ptr_t)MEM_ALIGN((u8_t *)memp + sizeof(struct memp)) % MEM_ALIGNMENT) == 0);
-
-    mem = MEM_ALIGN((u8_t *)memp + sizeof(struct memp));
-    return mem;
-  } else {
-    LWIP_DEBUGF(MEMP_DEBUG | 2, ("memp_malloc: out of memory in pool %d\n", type));
-#if MEMP_STATS
-    ++lwip_stats.memp[type].err;
-#endif /* MEMP_STATS */
-#if SYS_LIGHTWEIGHT_PROT
-  SYS_ARCH_UNPROTECT(old_level);
-#else /* SYS_LIGHTWEIGHT_PROT */
-  sys_sem_signal(mutex);
-#endif /* SYS_LIGHTWEIGHT_PROT */  
-    return NULL;
-  }
-}
-
-void
-memp_free(memp_t type, void *mem)
-{
-  struct memp *memp;
-#if SYS_LIGHTWEIGHT_PROT
-  SYS_ARCH_DECL_PROTECT(old_level);
-#endif /* SYS_LIGHTWEIGHT_PROT */  
-
-  if (mem == NULL) {
-    return;
-  }
-  memp = (struct memp *)((u8_t *)mem - sizeof(struct memp));
-
-#if SYS_LIGHTWEIGHT_PROT
-    SYS_ARCH_PROTECT(old_level);
-#else /* SYS_LIGHTWEIGHT_PROT */  
-  sys_sem_wait(mutex);
-#endif /* SYS_LIGHTWEIGHT_PROT */  
-
-#if MEMP_STATS
-  lwip_stats.memp[type].used--; 
-#endif /* MEMP_STATS */
-  
-  memp->next = memp_tab[type]; 
-  memp_tab[type] = memp;
-
-#if MEMP_SANITY_CHECK
-  LWIP_ASSERT("memp sanity", memp_sanity());
-#endif  
-
-#if SYS_LIGHTWEIGHT_PROT
-  SYS_ARCH_UNPROTECT(old_level);
-#else /* SYS_LIGHTWEIGHT_PROT */
-  sys_sem_signal(mutex);
-#endif /* SYS_LIGHTWEIGHT_PROT */  
-}
-
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+\r
+#include "lwip/opt.h"\r
+\r
+#include "lwip/memp.h"\r
+\r
+#include "lwip/pbuf.h"\r
+#include "lwip/udp.h"\r
+#include "lwip/raw.h"\r
+#include "lwip/tcp.h"\r
+#include "lwip/api.h"\r
+#include "lwip/api_msg.h"\r
+#include "lwip/tcpip.h"\r
+\r
+#include "lwip/sys.h"\r
+#include "lwip/stats.h"\r
+\r
+struct memp {\r
+  struct memp *next;\r
+};\r
+\r
+\r
+\r
+static struct memp *memp_tab[MEMP_MAX];\r
+\r
+static const u16_t memp_sizes[MEMP_MAX] = {\r
+  sizeof(struct pbuf),\r
+  sizeof(struct raw_pcb),\r
+  sizeof(struct udp_pcb),\r
+  sizeof(struct tcp_pcb),\r
+  sizeof(struct tcp_pcb_listen),\r
+  sizeof(struct tcp_seg),\r
+  sizeof(struct netbuf),\r
+  sizeof(struct netconn),\r
+  sizeof(struct api_msg),\r
+  sizeof(struct tcpip_msg),\r
+  sizeof(struct sys_timeout)\r
+};\r
+\r
+static const u16_t memp_num[MEMP_MAX] = {\r
+  MEMP_NUM_PBUF,\r
+  MEMP_NUM_RAW_PCB,\r
+  MEMP_NUM_UDP_PCB,\r
+  MEMP_NUM_TCP_PCB,\r
+  MEMP_NUM_TCP_PCB_LISTEN,\r
+  MEMP_NUM_TCP_SEG,\r
+  MEMP_NUM_NETBUF,\r
+  MEMP_NUM_NETCONN,\r
+  MEMP_NUM_API_MSG,\r
+  MEMP_NUM_TCPIP_MSG,\r
+  MEMP_NUM_SYS_TIMEOUT\r
+};\r
+\r
+static u8_t memp_memory[(MEMP_NUM_PBUF *\r
+       MEM_ALIGN_SIZE(sizeof(struct pbuf) +\r
+          sizeof(struct memp)) +\r
+      MEMP_NUM_RAW_PCB *\r
+       MEM_ALIGN_SIZE(sizeof(struct raw_pcb) +\r
+          sizeof(struct memp)) +\r
+      MEMP_NUM_UDP_PCB *\r
+       MEM_ALIGN_SIZE(sizeof(struct udp_pcb) +\r
+          sizeof(struct memp)) +\r
+      MEMP_NUM_TCP_PCB *\r
+       MEM_ALIGN_SIZE(sizeof(struct tcp_pcb) +\r
+          sizeof(struct memp)) +\r
+      MEMP_NUM_TCP_PCB_LISTEN *\r
+       MEM_ALIGN_SIZE(sizeof(struct tcp_pcb_listen) +\r
+          sizeof(struct memp)) +\r
+      MEMP_NUM_TCP_SEG *\r
+       MEM_ALIGN_SIZE(sizeof(struct tcp_seg) +\r
+          sizeof(struct memp)) +\r
+      MEMP_NUM_NETBUF *\r
+       MEM_ALIGN_SIZE(sizeof(struct netbuf) +\r
+          sizeof(struct memp)) +\r
+      MEMP_NUM_NETCONN *\r
+       MEM_ALIGN_SIZE(sizeof(struct netconn) +\r
+          sizeof(struct memp)) +\r
+      MEMP_NUM_API_MSG *\r
+       MEM_ALIGN_SIZE(sizeof(struct api_msg) +\r
+          sizeof(struct memp)) +\r
+      MEMP_NUM_TCPIP_MSG *\r
+       MEM_ALIGN_SIZE(sizeof(struct tcpip_msg) +\r
+          sizeof(struct memp)) +\r
+      MEMP_NUM_SYS_TIMEOUT *\r
+       MEM_ALIGN_SIZE(sizeof(struct sys_timeout) +\r
+          sizeof(struct memp)))];\r
+\r
+\r
+#if !SYS_LIGHTWEIGHT_PROT\r
+static sys_sem_t mutex;\r
+#endif\r
+\r
+#if MEMP_SANITY_CHECK\r
+static int\r
+memp_sanity(void)\r
+{\r
+  int i, c;\r
+  struct memp *m, *n;\r
+\r
+  for(i = 0; i < MEMP_MAX; i++) {\r
+    for(m = memp_tab[i]; m != NULL; m = m->next) {\r
+      c = 1;\r
+      for(n = memp_tab[i]; n != NULL; n = n->next) {\r
+         if (n == m) {\r
+          --c;\r
+        }\r
+        if (c < 0) return 0; /* LW was: abort(); */\r
+      }\r
+    }\r
+  }\r
+  return 1;\r
+}\r
+#endif /* MEMP_SANITY_CHECK*/\r
+\r
+void\r
+memp_init(void)\r
+{\r
+  struct memp *m, *memp;\r
+  u16_t i, j;\r
+  u16_t size;\r
+      \r
+#if MEMP_STATS\r
+  for(i = 0; i < MEMP_MAX; ++i) {\r
+    lwip_stats.memp[i].used = lwip_stats.memp[i].max =\r
+      lwip_stats.memp[i].err = 0;\r
+    lwip_stats.memp[i].avail = memp_num[i];\r
+  }\r
+#endif /* MEMP_STATS */\r
+\r
+  memp = (struct memp *)&memp_memory[0];\r
+  for(i = 0; i < MEMP_MAX; ++i) {\r
+    size = MEM_ALIGN_SIZE(memp_sizes[i] + sizeof(struct memp));\r
+    if (memp_num[i] > 0) {\r
+      memp_tab[i] = memp;\r
+      m = memp;\r
+      \r
+      for(j = 0; j < memp_num[i]; ++j) {\r
+  m->next = (struct memp *)MEM_ALIGN((u8_t *)m + size);\r
+  memp = m;\r
+  m = m->next;\r
+      }\r
+      memp->next = NULL;\r
+      memp = m;\r
+    } else {\r
+      memp_tab[i] = NULL;\r
+    }\r
+  }\r
+\r
+#if !SYS_LIGHTWEIGHT_PROT\r
+  mutex = sys_sem_new(1);\r
+#endif\r
+\r
+  \r
+}\r
+\r
+void *\r
+memp_malloc(memp_t type)\r
+{\r
+  struct memp *memp;\r
+  void *mem;\r
+#if SYS_LIGHTWEIGHT_PROT\r
+  SYS_ARCH_DECL_PROTECT(old_level);\r
+#endif\r
\r
+  LWIP_ASSERT("memp_malloc: type < MEMP_MAX", type < MEMP_MAX);\r
+\r
+#if SYS_LIGHTWEIGHT_PROT\r
+  SYS_ARCH_PROTECT(old_level);\r
+#else /* SYS_LIGHTWEIGHT_PROT */  \r
+  sys_sem_wait(mutex);\r
+#endif /* SYS_LIGHTWEIGHT_PROT */  \r
+\r
+  memp = memp_tab[type];\r
+  \r
+  if (memp != NULL) {    \r
+    memp_tab[type] = memp->next;    \r
+    memp->next = NULL;\r
+#if MEMP_STATS\r
+    ++lwip_stats.memp[type].used;\r
+    if (lwip_stats.memp[type].used > lwip_stats.memp[type].max) {\r
+      lwip_stats.memp[type].max = lwip_stats.memp[type].used;\r
+    }\r
+#endif /* MEMP_STATS */\r
+#if SYS_LIGHTWEIGHT_PROT\r
+    SYS_ARCH_UNPROTECT(old_level);\r
+#else /* SYS_LIGHTWEIGHT_PROT */\r
+    sys_sem_signal(mutex);\r
+#endif /* SYS_LIGHTWEIGHT_PROT */  \r
+    LWIP_ASSERT("memp_malloc: memp properly aligned",\r
+     ((mem_ptr_t)MEM_ALIGN((u8_t *)memp + sizeof(struct memp)) % MEM_ALIGNMENT) == 0);\r
+\r
+    mem = MEM_ALIGN((u8_t *)memp + sizeof(struct memp));\r
+    return mem;\r
+  } else {\r
+    LWIP_DEBUGF(MEMP_DEBUG | 2, ("memp_malloc: out of memory in pool %d\n", type));\r
+#if MEMP_STATS\r
+    ++lwip_stats.memp[type].err;\r
+#endif /* MEMP_STATS */\r
+#if SYS_LIGHTWEIGHT_PROT\r
+  SYS_ARCH_UNPROTECT(old_level);\r
+#else /* SYS_LIGHTWEIGHT_PROT */\r
+  sys_sem_signal(mutex);\r
+#endif /* SYS_LIGHTWEIGHT_PROT */  \r
+    return NULL;\r
+  }\r
+}\r
+\r
+void\r
+memp_free(memp_t type, void *mem)\r
+{\r
+  struct memp *memp;\r
+#if SYS_LIGHTWEIGHT_PROT\r
+  SYS_ARCH_DECL_PROTECT(old_level);\r
+#endif /* SYS_LIGHTWEIGHT_PROT */  \r
+\r
+  if (mem == NULL) {\r
+    return;\r
+  }\r
+  memp = (struct memp *)((u8_t *)mem - sizeof(struct memp));\r
+\r
+#if SYS_LIGHTWEIGHT_PROT\r
+    SYS_ARCH_PROTECT(old_level);\r
+#else /* SYS_LIGHTWEIGHT_PROT */  \r
+  sys_sem_wait(mutex);\r
+#endif /* SYS_LIGHTWEIGHT_PROT */  \r
+\r
+#if MEMP_STATS\r
+  lwip_stats.memp[type].used--; \r
+#endif /* MEMP_STATS */\r
+  \r
+  memp->next = memp_tab[type]; \r
+  memp_tab[type] = memp;\r
+\r
+#if MEMP_SANITY_CHECK\r
+  LWIP_ASSERT("memp sanity", memp_sanity());\r
+#endif  \r
+\r
+#if SYS_LIGHTWEIGHT_PROT\r
+  SYS_ARCH_UNPROTECT(old_level);\r
+#else /* SYS_LIGHTWEIGHT_PROT */\r
+  sys_sem_signal(mutex);\r
+#endif /* SYS_LIGHTWEIGHT_PROT */  \r
+}\r
+\r
index 32deb8d9d986ef3f2bddcc5eb863c3cc9bb3467c..e8cabc99dc377f7dcd683da2e2d92a21f4c05204 100644 (file)
-/**
- * @file
- *
- * lwIP network interface 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 <adam@sics.se>
- *
- */
-
-#include "lwip/opt.h"
-
-#include "lwip/def.h"
-#include "lwip/ip_addr.h"
-#include "lwip/netif.h"
-#include "lwip/tcp.h"
-
-struct netif *netif_list = NULL;
-struct netif *netif_default = NULL;
-
-/**
- * Add a network interface to the list of lwIP netifs.
- *
- * @param netif a pre-allocated netif structure
- * @param ipaddr IP address for the new netif
- * @param netmask network mask for the new netif
- * @param gw default gateway IP address for the new netif
- * @param state opaque data passed to the new netif
- * @param init callback function that initializes the interface
- * @param input callback function that is called to pass
- * ingress packets up in the protocol layer stack.
- *
- * @return netif, or NULL if failed.
- */
-struct netif *
-netif_add(struct netif *netif, struct ip_addr *ipaddr, struct ip_addr *netmask,
-  struct ip_addr *gw,
-  void *state,
-  err_t (* init)(struct netif *netif),
-  err_t (* input)(struct pbuf *p, struct netif *netif))
-{
-  static int netifnum = 0;
-  
-#if LWIP_DHCP
-  /* netif not under DHCP control by default */
-  netif->dhcp = NULL;
-#endif
-  /* remember netif specific state information data */
-  netif->state = state;
-  netif->num = netifnum++;
-  netif->input = input;
-
-  netif_set_addr(netif, ipaddr, netmask, gw);
-
-  /* call user specified initialization function for netif */
-  if (init(netif) != ERR_OK) {
-    return NULL;
-  }
-
-  /* add this netif to the list */
-  netif->next = netif_list;
-  netif_list = netif;
-  LWIP_DEBUGF(NETIF_DEBUG, ("netif: added interface %c%c IP addr ",
-    netif->name[0], netif->name[1]));
-  ip_addr_debug_print(NETIF_DEBUG, ipaddr);
-  LWIP_DEBUGF(NETIF_DEBUG, (" netmask "));
-  ip_addr_debug_print(NETIF_DEBUG, netmask);
-  LWIP_DEBUGF(NETIF_DEBUG, (" gw "));
-  ip_addr_debug_print(NETIF_DEBUG, gw);
-  LWIP_DEBUGF(NETIF_DEBUG, ("\n"));
-  return netif;
-}
-
-void
-netif_set_addr(struct netif *netif,struct ip_addr *ipaddr, struct ip_addr *netmask,
-    struct ip_addr *gw)
-{
-  netif_set_ipaddr(netif, ipaddr);
-  netif_set_netmask(netif, netmask);
-  netif_set_gw(netif, gw);
-}
-
-void netif_remove(struct netif * netif)
-{
-  if ( netif == NULL ) return;
-
-  /*  is it the first netif? */
-  if (netif_list == netif) {
-    netif_list = netif->next;
-  }
-  else {
-    /*  look for netif further down the list */
-    struct netif * tmpNetif;
-    for (tmpNetif = netif_list; tmpNetif != NULL; tmpNetif = tmpNetif->next) {
-      if (tmpNetif->next == netif) {
-        tmpNetif->next = netif->next;
-        break;
-        }
-    }
-    if (tmpNetif == NULL)
-      return; /*  we didn't find any netif today */
-  }
-  /* this netif is default? */
-  if (netif_default == netif)
-    /* reset default netif */
-    netif_default = NULL;
-  LWIP_DEBUGF( NETIF_DEBUG, ("netif_remove: removed netif\n") );
-}
-
-struct netif *
-netif_find(char *name)
-{
-  struct netif *netif;
-  u8_t num;
-
-  if (name == NULL) {
-    return NULL;
-  }
-
-  num = name[2] - '0';
-
-  for(netif = netif_list; netif != NULL; netif = netif->next) {
-    if (num == netif->num &&
-       name[0] == netif->name[0] &&
-       name[1] == netif->name[1]) {
-      LWIP_DEBUGF(NETIF_DEBUG, ("netif_find: found %c%c\n", name[0], name[1]));
-      return netif;
-    }
-  }
-  LWIP_DEBUGF(NETIF_DEBUG, ("netif_find: didn't find %c%c\n", name[0], name[1]));
-  return NULL;
-}
-
-void
-netif_set_ipaddr(struct netif *netif, struct ip_addr *ipaddr)
-{
-  /* TODO: Handling of obsolete pcbs */
-  /* See:  http://mail.gnu.org/archive/html/lwip-users/2003-03/msg00118.html */
-#if LWIP_TCP
-  struct tcp_pcb *pcb;
-  struct tcp_pcb_listen *lpcb;
-
-  /* address is actually being changed? */
-  if ((ip_addr_cmp(ipaddr, &(netif->ip_addr))) == 0)
-  {
-    /* extern struct tcp_pcb *tcp_active_pcbs; defined by tcp.h */
-    LWIP_DEBUGF(NETIF_DEBUG | 1, ("netif_set_ipaddr: netif address being changed\n"));
-    pcb = tcp_active_pcbs;
-    while (pcb != NULL) {
-      /* PCB bound to current local interface address? */
-      if (ip_addr_cmp(&(pcb->local_ip), &(netif->ip_addr))) {
-        /* this connection must be aborted */
-        struct tcp_pcb *next = pcb->next;
-        LWIP_DEBUGF(NETIF_DEBUG | 1, ("netif_set_ipaddr: aborting TCP pcb %p\n", (void *)pcb));
-        tcp_abort(pcb);
-        pcb = next;
-      } else {
-        pcb = pcb->next;
-      }
-    }
-    for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
-      /* PCB bound to current local interface address? */
-      if (ip_addr_cmp(&(lpcb->local_ip), &(netif->ip_addr))) {
-        /* The PCB is listening to the old ipaddr and
-         * is set to listen to the new one instead */
-        ip_addr_set(&(lpcb->local_ip), ipaddr);
-      }
-    }
-  }
-#endif
-  ip_addr_set(&(netif->ip_addr), ipaddr);
-#if 0 /* only allowed for Ethernet interfaces TODO: how can we check? */
-  /** For Ethernet network interfaces, we would like to send a
-   *  "gratuitous ARP"; this is an ARP packet sent by a node in order
-   *  to spontaneously cause other nodes to update an entry in their
-   *  ARP cache. From RFC 3220 "IP Mobility Support for IPv4" section 4.6.
-   */ 
-  etharp_query(netif, ipaddr, NULL);
-#endif
-  LWIP_DEBUGF(NETIF_DEBUG | DBG_TRACE | DBG_STATE | 3, ("netif: IP address of interface %c%c set to %u.%u.%u.%u\n",
-    netif->name[0], netif->name[1],
-    ip4_addr1(&netif->ip_addr),
-    ip4_addr2(&netif->ip_addr),
-    ip4_addr3(&netif->ip_addr),
-    ip4_addr4(&netif->ip_addr)));
-}
-
-void
-netif_set_gw(struct netif *netif, struct ip_addr *gw)
-{
-  ip_addr_set(&(netif->gw), gw);
-  LWIP_DEBUGF(NETIF_DEBUG | DBG_TRACE | DBG_STATE | 3, ("netif: GW address of interface %c%c set to %u.%u.%u.%u\n",
-    netif->name[0], netif->name[1],
-    ip4_addr1(&netif->gw),
-    ip4_addr2(&netif->gw),
-    ip4_addr3(&netif->gw),
-    ip4_addr4(&netif->gw)));
-}
-
-void
-netif_set_netmask(struct netif *netif, struct ip_addr *netmask)
-{
-  ip_addr_set(&(netif->netmask), netmask);
-  LWIP_DEBUGF(NETIF_DEBUG | DBG_TRACE | DBG_STATE | 3, ("netif: netmask of interface %c%c set to %u.%u.%u.%u\n",
-    netif->name[0], netif->name[1],
-    ip4_addr1(&netif->netmask),
-    ip4_addr2(&netif->netmask),
-    ip4_addr3(&netif->netmask),
-    ip4_addr4(&netif->netmask)));
-}
-
-void
-netif_set_default(struct netif *netif)
-{
-  netif_default = netif;
-  LWIP_DEBUGF(NETIF_DEBUG, ("netif: setting default interface %c%c\n",
-           netif ? netif->name[0] : '\'', netif ? netif->name[1] : '\''));
-}
-
-/**
- * Bring an interface up, available for processing
- * traffic.
- * 
- * @note: Enabling DHCP on a down interface will make it come
- * up once configured.
- * 
- * @see dhcp_start()
- */ 
-void netif_set_up(struct netif *netif)
-{
-  netif->flags |= NETIF_FLAG_UP;
-}
-
-/**
- * Ask if an interface is up
- */ 
-u8_t netif_is_up(struct netif *netif)
-{
-  return (netif->flags & NETIF_FLAG_UP)?1:0;
-}
-
-/**
- * Bring an interface down, disabling any traffic processing.
- *
- * @note: Enabling DHCP on a down interface will make it come
- * up once configured.
- * 
- * @see dhcp_start()
- */ 
-void netif_set_down(struct netif *netif)
-{
-  netif->flags &= ~NETIF_FLAG_UP;
-}
-
-void
-netif_init(void)
-{
-  netif_list = netif_default = NULL;
-}
-
+/**\r
+ * @file\r
+ *\r
+ * lwIP network interface abstraction\r
+ */\r
+\r
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without modification,\r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED\r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT\r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY\r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ *\r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+\r
+#include "lwip/opt.h"\r
+\r
+#include "lwip/def.h"\r
+#include "lwip/ip_addr.h"\r
+#include "lwip/netif.h"\r
+#include "lwip/tcp.h"\r
+\r
+struct netif *netif_list = NULL;\r
+struct netif *netif_default = NULL;\r
+\r
+/**\r
+ * Add a network interface to the list of lwIP netifs.\r
+ *\r
+ * @param netif a pre-allocated netif structure\r
+ * @param ipaddr IP address for the new netif\r
+ * @param netmask network mask for the new netif\r
+ * @param gw default gateway IP address for the new netif\r
+ * @param state opaque data passed to the new netif\r
+ * @param init callback function that initializes the interface\r
+ * @param input callback function that is called to pass\r
+ * ingress packets up in the protocol layer stack.\r
+ *\r
+ * @return netif, or NULL if failed.\r
+ */\r
+struct netif *\r
+netif_add(struct netif *netif, struct ip_addr *ipaddr, struct ip_addr *netmask,\r
+  struct ip_addr *gw,\r
+  void *state,\r
+  err_t (* init)(struct netif *netif),\r
+  err_t (* input)(struct pbuf *p, struct netif *netif))\r
+{\r
+  static int netifnum = 0;\r
+  \r
+#if LWIP_DHCP\r
+  /* netif not under DHCP control by default */\r
+  netif->dhcp = NULL;\r
+#endif\r
+  /* remember netif specific state information data */\r
+  netif->state = state;\r
+  netif->num = netifnum++;\r
+  netif->input = input;\r
+\r
+  netif_set_addr(netif, ipaddr, netmask, gw);\r
+\r
+  /* call user specified initialization function for netif */\r
+  if (init(netif) != ERR_OK) {\r
+    return NULL;\r
+  }\r
+\r
+  /* add this netif to the list */\r
+  netif->next = netif_list;\r
+  netif_list = netif;\r
+  LWIP_DEBUGF(NETIF_DEBUG, ("netif: added interface %c%c IP addr ",\r
+    netif->name[0], netif->name[1]));\r
+  ip_addr_debug_print(NETIF_DEBUG, ipaddr);\r
+  LWIP_DEBUGF(NETIF_DEBUG, (" netmask "));\r
+  ip_addr_debug_print(NETIF_DEBUG, netmask);\r
+  LWIP_DEBUGF(NETIF_DEBUG, (" gw "));\r
+  ip_addr_debug_print(NETIF_DEBUG, gw);\r
+  LWIP_DEBUGF(NETIF_DEBUG, ("\n"));\r
+  return netif;\r
+}\r
+\r
+void\r
+netif_set_addr(struct netif *netif,struct ip_addr *ipaddr, struct ip_addr *netmask,\r
+    struct ip_addr *gw)\r
+{\r
+  netif_set_ipaddr(netif, ipaddr);\r
+  netif_set_netmask(netif, netmask);\r
+  netif_set_gw(netif, gw);\r
+}\r
+\r
+void netif_remove(struct netif * netif)\r
+{\r
+  if ( netif == NULL ) return;\r
+\r
+  /*  is it the first netif? */\r
+  if (netif_list == netif) {\r
+    netif_list = netif->next;\r
+  }\r
+  else {\r
+    /*  look for netif further down the list */\r
+    struct netif * tmpNetif;\r
+    for (tmpNetif = netif_list; tmpNetif != NULL; tmpNetif = tmpNetif->next) {\r
+      if (tmpNetif->next == netif) {\r
+        tmpNetif->next = netif->next;\r
+        break;\r
+        }\r
+    }\r
+    if (tmpNetif == NULL)\r
+      return; /*  we didn't find any netif today */\r
+  }\r
+  /* this netif is default? */\r
+  if (netif_default == netif)\r
+    /* reset default netif */\r
+    netif_default = NULL;\r
+  LWIP_DEBUGF( NETIF_DEBUG, ("netif_remove: removed netif\n") );\r
+}\r
+\r
+struct netif *\r
+netif_find(char *name)\r
+{\r
+  struct netif *netif;\r
+  u8_t num;\r
+\r
+  if (name == NULL) {\r
+    return NULL;\r
+  }\r
+\r
+  num = name[2] - '0';\r
+\r
+  for(netif = netif_list; netif != NULL; netif = netif->next) {\r
+    if (num == netif->num &&\r
+       name[0] == netif->name[0] &&\r
+       name[1] == netif->name[1]) {\r
+      LWIP_DEBUGF(NETIF_DEBUG, ("netif_find: found %c%c\n", name[0], name[1]));\r
+      return netif;\r
+    }\r
+  }\r
+  LWIP_DEBUGF(NETIF_DEBUG, ("netif_find: didn't find %c%c\n", name[0], name[1]));\r
+  return NULL;\r
+}\r
+\r
+void\r
+netif_set_ipaddr(struct netif *netif, struct ip_addr *ipaddr)\r
+{\r
+  /* TODO: Handling of obsolete pcbs */\r
+  /* See:  http://mail.gnu.org/archive/html/lwip-users/2003-03/msg00118.html */\r
+#if LWIP_TCP\r
+  struct tcp_pcb *pcb;\r
+  struct tcp_pcb_listen *lpcb;\r
+\r
+  /* address is actually being changed? */\r
+  if ((ip_addr_cmp(ipaddr, &(netif->ip_addr))) == 0)\r
+  {\r
+    /* extern struct tcp_pcb *tcp_active_pcbs; defined by tcp.h */\r
+    LWIP_DEBUGF(NETIF_DEBUG | 1, ("netif_set_ipaddr: netif address being changed\n"));\r
+    pcb = tcp_active_pcbs;\r
+    while (pcb != NULL) {\r
+      /* PCB bound to current local interface address? */\r
+      if (ip_addr_cmp(&(pcb->local_ip), &(netif->ip_addr))) {\r
+        /* this connection must be aborted */\r
+        struct tcp_pcb *next = pcb->next;\r
+        LWIP_DEBUGF(NETIF_DEBUG | 1, ("netif_set_ipaddr: aborting TCP pcb %p\n", (void *)pcb));\r
+        tcp_abort(pcb);\r
+        pcb = next;\r
+      } else {\r
+        pcb = pcb->next;\r
+      }\r
+    }\r
+    for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {\r
+      /* PCB bound to current local interface address? */\r
+      if (ip_addr_cmp(&(lpcb->local_ip), &(netif->ip_addr))) {\r
+        /* The PCB is listening to the old ipaddr and\r
+         * is set to listen to the new one instead */\r
+        ip_addr_set(&(lpcb->local_ip), ipaddr);\r
+      }\r
+    }\r
+  }\r
+#endif\r
+  ip_addr_set(&(netif->ip_addr), ipaddr);\r
+#if 0 /* only allowed for Ethernet interfaces TODO: how can we check? */\r
+  /** For Ethernet network interfaces, we would like to send a\r
+   *  "gratuitous ARP"; this is an ARP packet sent by a node in order\r
+   *  to spontaneously cause other nodes to update an entry in their\r
+   *  ARP cache. From RFC 3220 "IP Mobility Support for IPv4" section 4.6.\r
+   */ \r
+  etharp_query(netif, ipaddr, NULL);\r
+#endif\r
+  LWIP_DEBUGF(NETIF_DEBUG | DBG_TRACE | DBG_STATE | 3, ("netif: IP address of interface %c%c set to %u.%u.%u.%u\n",\r
+    netif->name[0], netif->name[1],\r
+    ip4_addr1(&netif->ip_addr),\r
+    ip4_addr2(&netif->ip_addr),\r
+    ip4_addr3(&netif->ip_addr),\r
+    ip4_addr4(&netif->ip_addr)));\r
+}\r
+\r
+void\r
+netif_set_gw(struct netif *netif, struct ip_addr *gw)\r
+{\r
+  ip_addr_set(&(netif->gw), gw);\r
+  LWIP_DEBUGF(NETIF_DEBUG | DBG_TRACE | DBG_STATE | 3, ("netif: GW address of interface %c%c set to %u.%u.%u.%u\n",\r
+    netif->name[0], netif->name[1],\r
+    ip4_addr1(&netif->gw),\r
+    ip4_addr2(&netif->gw),\r
+    ip4_addr3(&netif->gw),\r
+    ip4_addr4(&netif->gw)));\r
+}\r
+\r
+void\r
+netif_set_netmask(struct netif *netif, struct ip_addr *netmask)\r
+{\r
+  ip_addr_set(&(netif->netmask), netmask);\r
+  LWIP_DEBUGF(NETIF_DEBUG | DBG_TRACE | DBG_STATE | 3, ("netif: netmask of interface %c%c set to %u.%u.%u.%u\n",\r
+    netif->name[0], netif->name[1],\r
+    ip4_addr1(&netif->netmask),\r
+    ip4_addr2(&netif->netmask),\r
+    ip4_addr3(&netif->netmask),\r
+    ip4_addr4(&netif->netmask)));\r
+}\r
+\r
+void\r
+netif_set_default(struct netif *netif)\r
+{\r
+  netif_default = netif;\r
+  LWIP_DEBUGF(NETIF_DEBUG, ("netif: setting default interface %c%c\n",\r
+           netif ? netif->name[0] : '\'', netif ? netif->name[1] : '\''));\r
+}\r
+\r
+/**\r
+ * Bring an interface up, available for processing\r
+ * traffic.\r
+ * \r
+ * @note: Enabling DHCP on a down interface will make it come\r
+ * up once configured.\r
+ * \r
+ * @see dhcp_start()\r
+ */ \r
+void netif_set_up(struct netif *netif)\r
+{\r
+  netif->flags |= NETIF_FLAG_UP;\r
+}\r
+\r
+/**\r
+ * Ask if an interface is up\r
+ */ \r
+u8_t netif_is_up(struct netif *netif)\r
+{\r
+  return (netif->flags & NETIF_FLAG_UP)?1:0;\r
+}\r
+\r
+/**\r
+ * Bring an interface down, disabling any traffic processing.\r
+ *\r
+ * @note: Enabling DHCP on a down interface will make it come\r
+ * up once configured.\r
+ * \r
+ * @see dhcp_start()\r
+ */ \r
+void netif_set_down(struct netif *netif)\r
+{\r
+  netif->flags &= ~NETIF_FLAG_UP;\r
+}\r
+\r
+void\r
+netif_init(void)\r
+{\r
+  netif_list = netif_default = NULL;\r
+}\r
+\r
index 56768896b2b3e4564b04f2e2405931a2693254e4..5f96892581e37a520e46d186a6e7cf96dab6261f 100644 (file)
-/*
- * 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 <adam@sics.se>
- *
- */
-
-#include <string.h>
-
-#include "lwip/opt.h"
-
-#include "lwip/def.h"
-
-#include "lwip/stats.h"
-#include "lwip/mem.h"
-
-
-#if LWIP_STATS
-struct stats_ lwip_stats;
-
-void
-stats_init(void)
-{
-  memset(&lwip_stats, 0, sizeof(struct stats_));
-}
-#if LWIP_STATS_DISPLAY
-void
-stats_display_proto(struct stats_proto *proto, char *name)
-{
-  LWIP_PLATFORM_DIAG(("\n%s\n\t", name));
-  LWIP_PLATFORM_DIAG(("xmit: %d\n\t", proto->xmit)); 
-  LWIP_PLATFORM_DIAG(("rexmit: %d\n\t", proto->rexmit)); 
-  LWIP_PLATFORM_DIAG(("recv: %d\n\t", proto->recv)); 
-  LWIP_PLATFORM_DIAG(("fw: %d\n\t", proto->fw)); 
-  LWIP_PLATFORM_DIAG(("drop: %d\n\t", proto->drop)); 
-  LWIP_PLATFORM_DIAG(("chkerr: %d\n\t", proto->chkerr)); 
-  LWIP_PLATFORM_DIAG(("lenerr: %d\n\t", proto->lenerr)); 
-  LWIP_PLATFORM_DIAG(("memerr: %d\n\t", proto->memerr)); 
-  LWIP_PLATFORM_DIAG(("rterr: %d\n\t", proto->rterr)); 
-  LWIP_PLATFORM_DIAG(("proterr: %d\n\t", proto->proterr)); 
-  LWIP_PLATFORM_DIAG(("opterr: %d\n\t", proto->opterr)); 
-  LWIP_PLATFORM_DIAG(("err: %d\n\t", proto->err)); 
-  LWIP_PLATFORM_DIAG(("cachehit: %d\n", proto->cachehit)); 
-}
-
-void
-stats_display_pbuf(struct stats_pbuf *pbuf)
-{
-  LWIP_PLATFORM_DIAG(("\nPBUF\n\t"));
-  LWIP_PLATFORM_DIAG(("avail: %d\n\t", pbuf->avail)); 
-  LWIP_PLATFORM_DIAG(("used: %d\n\t", pbuf->used)); 
-  LWIP_PLATFORM_DIAG(("max: %d\n\t", pbuf->max)); 
-  LWIP_PLATFORM_DIAG(("err: %d\n\t", pbuf->err)); 
-  LWIP_PLATFORM_DIAG(("alloc_locked: %d\n\t", pbuf->alloc_locked)); 
-  LWIP_PLATFORM_DIAG(("refresh_locked: %d\n", pbuf->refresh_locked)); 
-}
-
-void
-stats_display_mem(struct stats_mem *mem, char *name)
-{
-  LWIP_PLATFORM_DIAG(("\n MEM %s\n\t", name));
-  LWIP_PLATFORM_DIAG(("avail: %d\n\t", mem->avail)); 
-  LWIP_PLATFORM_DIAG(("used: %d\n\t", mem->used)); 
-  LWIP_PLATFORM_DIAG(("max: %d\n\t", mem->max)); 
-  LWIP_PLATFORM_DIAG(("err: %d\n", mem->err));
-  
-}
-
-void
-stats_display(void)
-{
-  int i;
-  char * memp_names[] = {"PBUF", "RAW_PCB", "UDP_PCB", "TCP_PCB", "TCP_PCB_LISTEN",
-                       "TCP_SEG", "NETBUF", "NETCONN", "API_MSG", "TCP_MSG", "TIMEOUT"};
-  stats_display_proto(&lwip_stats.link, "LINK");
-  stats_display_proto(&lwip_stats.ip_frag, "IP_FRAG");
-  stats_display_proto(&lwip_stats.ip, "IP");
-  stats_display_proto(&lwip_stats.icmp, "ICMP");
-  stats_display_proto(&lwip_stats.udp, "UDP");
-  stats_display_proto(&lwip_stats.tcp, "TCP");
-  stats_display_pbuf(&lwip_stats.pbuf);
-  stats_display_mem(&lwip_stats.mem, "HEAP");
-  for (i = 0; i < MEMP_MAX; i++) {
-    stats_display_mem(&lwip_stats.memp[i], memp_names[i]);
-  }
-       
-}
-#endif /* LWIP_STATS_DISPLAY */
-#endif /* LWIP_STATS */
-
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+\r
+#include <string.h>\r
+\r
+#include "lwip/opt.h"\r
+\r
+#include "lwip/def.h"\r
+\r
+#include "lwip/stats.h"\r
+#include "lwip/mem.h"\r
+\r
+\r
+#if LWIP_STATS\r
+struct stats_ lwip_stats;\r
+\r
+void\r
+stats_init(void)\r
+{\r
+  memset(&lwip_stats, 0, sizeof(struct stats_));\r
+}\r
+#if LWIP_STATS_DISPLAY\r
+void\r
+stats_display_proto(struct stats_proto *proto, char *name)\r
+{\r
+  LWIP_PLATFORM_DIAG(("\n%s\n\t", name));\r
+  LWIP_PLATFORM_DIAG(("xmit: %d\n\t", proto->xmit)); \r
+  LWIP_PLATFORM_DIAG(("rexmit: %d\n\t", proto->rexmit)); \r
+  LWIP_PLATFORM_DIAG(("recv: %d\n\t", proto->recv)); \r
+  LWIP_PLATFORM_DIAG(("fw: %d\n\t", proto->fw)); \r
+  LWIP_PLATFORM_DIAG(("drop: %d\n\t", proto->drop)); \r
+  LWIP_PLATFORM_DIAG(("chkerr: %d\n\t", proto->chkerr)); \r
+  LWIP_PLATFORM_DIAG(("lenerr: %d\n\t", proto->lenerr)); \r
+  LWIP_PLATFORM_DIAG(("memerr: %d\n\t", proto->memerr)); \r
+  LWIP_PLATFORM_DIAG(("rterr: %d\n\t", proto->rterr)); \r
+  LWIP_PLATFORM_DIAG(("proterr: %d\n\t", proto->proterr)); \r
+  LWIP_PLATFORM_DIAG(("opterr: %d\n\t", proto->opterr)); \r
+  LWIP_PLATFORM_DIAG(("err: %d\n\t", proto->err)); \r
+  LWIP_PLATFORM_DIAG(("cachehit: %d\n", proto->cachehit)); \r
+}\r
+\r
+void\r
+stats_display_pbuf(struct stats_pbuf *pbuf)\r
+{\r
+  LWIP_PLATFORM_DIAG(("\nPBUF\n\t"));\r
+  LWIP_PLATFORM_DIAG(("avail: %d\n\t", pbuf->avail)); \r
+  LWIP_PLATFORM_DIAG(("used: %d\n\t", pbuf->used)); \r
+  LWIP_PLATFORM_DIAG(("max: %d\n\t", pbuf->max)); \r
+  LWIP_PLATFORM_DIAG(("err: %d\n\t", pbuf->err)); \r
+  LWIP_PLATFORM_DIAG(("alloc_locked: %d\n\t", pbuf->alloc_locked)); \r
+  LWIP_PLATFORM_DIAG(("refresh_locked: %d\n", pbuf->refresh_locked)); \r
+}\r
+\r
+void\r
+stats_display_mem(struct stats_mem *mem, char *name)\r
+{\r
+  LWIP_PLATFORM_DIAG(("\n MEM %s\n\t", name));\r
+  LWIP_PLATFORM_DIAG(("avail: %d\n\t", mem->avail)); \r
+  LWIP_PLATFORM_DIAG(("used: %d\n\t", mem->used)); \r
+  LWIP_PLATFORM_DIAG(("max: %d\n\t", mem->max)); \r
+  LWIP_PLATFORM_DIAG(("err: %d\n", mem->err));\r
+  \r
+}\r
+\r
+void\r
+stats_display(void)\r
+{\r
+  int i;\r
+  char * memp_names[] = {"PBUF", "RAW_PCB", "UDP_PCB", "TCP_PCB", "TCP_PCB_LISTEN",\r
+                       "TCP_SEG", "NETBUF", "NETCONN", "API_MSG", "TCP_MSG", "TIMEOUT"};\r
+  stats_display_proto(&lwip_stats.link, "LINK");\r
+  stats_display_proto(&lwip_stats.ip_frag, "IP_FRAG");\r
+  stats_display_proto(&lwip_stats.ip, "IP");\r
+  stats_display_proto(&lwip_stats.icmp, "ICMP");\r
+  stats_display_proto(&lwip_stats.udp, "UDP");\r
+  stats_display_proto(&lwip_stats.tcp, "TCP");\r
+  stats_display_pbuf(&lwip_stats.pbuf);\r
+  stats_display_mem(&lwip_stats.mem, "HEAP");\r
+  for (i = 0; i < MEMP_MAX; i++) {\r
+    stats_display_mem(&lwip_stats.memp[i], memp_names[i]);\r
+  }\r
+       \r
+}\r
+#endif /* LWIP_STATS_DISPLAY */\r
+#endif /* LWIP_STATS */\r
+\r
index a07a839a6bddad830c5d12d9317c8d0ce64f9561..8134566eaba1b45d63c60f6a6913e58885278419 100644 (file)
-/*
- * 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 <adam@sics.se>
- *
- */
-
-#include "lwip/sys.h"
-#include "lwip/opt.h"
-#include "lwip/def.h"
-#include "lwip/memp.h"
-
-#if (NO_SYS == 0)
-
-struct sswt_cb
-{
-    int timeflag;
-    sys_sem_t *psem;
-};
-
-
-
-void
-sys_mbox_fetch(sys_mbox_t mbox, void **msg)
-{
-  u32_t time;
-  struct sys_timeouts *timeouts;
-  struct sys_timeout *tmptimeout;
-  sys_timeout_handler h;
-  void *arg;
-
-
- again:
-  timeouts = sys_arch_timeouts();
-
-  if (!timeouts || !timeouts->next) {
-    sys_arch_mbox_fetch(mbox, msg, 0);
-  } else {
-    if (timeouts->next->time > 0) {
-      time = sys_arch_mbox_fetch(mbox, msg, timeouts->next->time);
-    } else {
-      time = SYS_ARCH_TIMEOUT;
-    }
-
-    if (time == SYS_ARCH_TIMEOUT) {
-      /* If time == SYS_ARCH_TIMEOUT, a timeout occured before a message
-   could be fetched. We should now call the timeout handler and
-   deallocate the memory allocated for the timeout. */
-      tmptimeout = timeouts->next;
-      timeouts->next = tmptimeout->next;
-      h = tmptimeout->h;
-      arg = tmptimeout->arg;
-      memp_free(MEMP_SYS_TIMEOUT, tmptimeout);
-      if (h != NULL) {
-        LWIP_DEBUGF(SYS_DEBUG, ("smf calling h=%p(%p)\n", (void *)h, (void *)arg));
-       h(arg);
-      }
-
-      /* We try again to fetch a message from the mbox. */
-      goto again;
-    } else {
-      /* If time != SYS_ARCH_TIMEOUT, a message was received before the timeout
-   occured. The time variable is set to the number of
-   milliseconds we waited for the message. */
-      if (time <= timeouts->next->time) {
-  timeouts->next->time -= time;
-      } else {
-  timeouts->next->time = 0;
-      }
-    }
-
-  }
-}
-
-void
-sys_sem_wait(sys_sem_t sem)
-{
-  u32_t time;
-  struct sys_timeouts *timeouts;
-  struct sys_timeout *tmptimeout;
-  sys_timeout_handler h;
-  void *arg;
-
-  /*  while (sys_arch_sem_wait(sem, 1000) == 0);
-      return;*/
-
- again:
-
-  timeouts = sys_arch_timeouts();
-
-  if (!timeouts || !timeouts->next) {
-    sys_arch_sem_wait(sem, 0);
-  } else {
-    if (timeouts->next->time > 0) {
-      time = sys_arch_sem_wait(sem, timeouts->next->time);
-    } else {
-      time = SYS_ARCH_TIMEOUT;
-    }
-
-    if (time == SYS_ARCH_TIMEOUT) {
-      /* If time == SYS_ARCH_TIMEOUT, a timeout occured before a message
-   could be fetched. We should now call the timeout handler and
-   deallocate the memory allocated for the timeout. */
-      tmptimeout = timeouts->next;
-      timeouts->next = tmptimeout->next;
-      h = tmptimeout->h;
-      arg = tmptimeout->arg;
-      memp_free(MEMP_SYS_TIMEOUT, tmptimeout);
-      if (h != NULL) {
-        LWIP_DEBUGF(SYS_DEBUG, ("ssw h=%p(%p)\n", (void *)h, (void *)arg));
-        h(arg);
-      }
-
-
-      /* We try again to fetch a message from the mbox. */
-      goto again;
-    } else {
-      /* If time != SYS_ARCH_TIMEOUT, a message was received before the timeout
-   occured. The time variable is set to the number of
-   milliseconds we waited for the message. */
-      if (time <= timeouts->next->time) {
-  timeouts->next->time -= time;
-      } else {
-  timeouts->next->time = 0;
-      }
-    }
-
-  }
-}
-
-void
-sys_timeout(u32_t msecs, sys_timeout_handler h, void *arg)
-{
-  struct sys_timeouts *timeouts;
-  struct sys_timeout *timeout, *t;
-
-  timeout = memp_malloc(MEMP_SYS_TIMEOUT);
-  if (timeout == NULL) {
-    return;
-  }
-  timeout->next = NULL;
-  timeout->h = h;
-  timeout->arg = arg;
-  timeout->time = msecs;
-
-  timeouts = sys_arch_timeouts();
-
-  LWIP_DEBUGF(SYS_DEBUG, ("sys_timeout: %p msecs=%lu h=%p arg=%p\n",
-    (void *)timeout, msecs, (void *)h, (void *)arg));
-
-  LWIP_ASSERT("sys_timeout: timeouts != NULL", timeouts != NULL);
-
-  if (timeouts->next == NULL) {
-    timeouts->next = timeout;
-    return;
-  }
-
-  if (timeouts->next->time > msecs) {
-    timeouts->next->time -= msecs;
-    timeout->next = timeouts->next;
-    timeouts->next = timeout;
-  } else {
-    for(t = timeouts->next; t != NULL; t = t->next) {
-      timeout->time -= t->time;
-      if (t->next == NULL || t->next->time > timeout->time) {
-        if (t->next != NULL) {
-          t->next->time -= timeout->time;
-        }
-        timeout->next = t->next;
-        t->next = timeout;
-        break;
-      }
-    }
-  }
-
-}
-
-/* Go through timeout list (for this task only) and remove the first matching entry,
-   even though the timeout has not triggered yet.
-*/
-
-void
-sys_untimeout(sys_timeout_handler h, void *arg)
-{
-    struct sys_timeouts *timeouts;
-    struct sys_timeout *prev_t, *t;
-
-    timeouts = sys_arch_timeouts();
-
-    if (timeouts->next == NULL)
-        return;
-
-    for (t = timeouts->next, prev_t = NULL; t != NULL; prev_t = t, t = t->next)
-    {
-        if ((t->h == h) && (t->arg == arg))
-        {
-            /* We have a match */
-            /* Unlink from previous in list */
-            if (prev_t == NULL)
-                timeouts->next = t->next;
-            else
-                prev_t->next = t->next;
-            /* If not the last one, add time of this one back to next */
-            if (t->next != NULL)
-                t->next->time += t->time;
-            memp_free(MEMP_SYS_TIMEOUT, t);
-            return;
-        }
-    }
-    return;
-}
-
-
-
-
-
-static void
-sswt_handler(void *arg)
-{
-    struct sswt_cb *sswt_cb = (struct sswt_cb *) arg;
-
-    /* Timeout. Set flag to TRUE and signal semaphore */
-    sswt_cb->timeflag = 1;
-    sys_sem_signal(*(sswt_cb->psem));
-}
-
-/* Wait for a semaphore with timeout (specified in ms) */
-/* timeout = 0: wait forever */
-/* Returns 0 on timeout. 1 otherwise */
-
-int
-sys_sem_wait_timeout(sys_sem_t sem, u32_t timeout)
-{
-    struct sswt_cb sswt_cb;
-
-    sswt_cb.psem = &sem;
-    sswt_cb.timeflag = 0;
-
-    /* If timeout is zero, then just wait forever */
-    if (timeout > 0)
-        /* Create a timer and pass it the address of our flag */
-        sys_timeout(timeout, sswt_handler, &sswt_cb);
-    sys_sem_wait(sem);
-    /* Was it a timeout? */
-    if (sswt_cb.timeflag)
-    {
-        /* timeout */
-        return 0;
-    } else {
-        /* Not a timeout. Remove timeout entry */
-        sys_untimeout(sswt_handler, &sswt_cb);
-        return 1;
-    }
-
-}
-
-
-void
-sys_msleep(u32_t ms)
-{
-  sys_sem_t delaysem = sys_sem_new(0);
-
-  sys_sem_wait_timeout(delaysem, ms);
-
-  sys_sem_free(delaysem);
-}
-
-
-#endif /* NO_SYS */
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without modification,\r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED\r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT\r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY\r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ *\r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+\r
+#include "lwip/sys.h"\r
+#include "lwip/opt.h"\r
+#include "lwip/def.h"\r
+#include "lwip/memp.h"\r
+\r
+#if (NO_SYS == 0)\r
+\r
+struct sswt_cb\r
+{\r
+    int timeflag;\r
+    sys_sem_t *psem;\r
+};\r
+\r
+\r
+\r
+void\r
+sys_mbox_fetch(sys_mbox_t mbox, void **msg)\r
+{\r
+  u32_t time;\r
+  struct sys_timeouts *timeouts;\r
+  struct sys_timeout *tmptimeout;\r
+  sys_timeout_handler h;\r
+  void *arg;\r
+\r
+\r
+ again:\r
+  timeouts = sys_arch_timeouts();\r
+\r
+  if (!timeouts || !timeouts->next) {\r
+    sys_arch_mbox_fetch(mbox, msg, 0);\r
+  } else {\r
+    if (timeouts->next->time > 0) {\r
+      time = sys_arch_mbox_fetch(mbox, msg, timeouts->next->time);\r
+    } else {\r
+      time = SYS_ARCH_TIMEOUT;\r
+    }\r
+\r
+    if (time == SYS_ARCH_TIMEOUT) {\r
+      /* If time == SYS_ARCH_TIMEOUT, a timeout occured before a message\r
+   could be fetched. We should now call the timeout handler and\r
+   deallocate the memory allocated for the timeout. */\r
+      tmptimeout = timeouts->next;\r
+      timeouts->next = tmptimeout->next;\r
+      h = tmptimeout->h;\r
+      arg = tmptimeout->arg;\r
+      memp_free(MEMP_SYS_TIMEOUT, tmptimeout);\r
+      if (h != NULL) {\r
+        LWIP_DEBUGF(SYS_DEBUG, ("smf calling h=%p(%p)\n", (void *)h, (void *)arg));\r
+       h(arg);\r
+      }\r
+\r
+      /* We try again to fetch a message from the mbox. */\r
+      goto again;\r
+    } else {\r
+      /* If time != SYS_ARCH_TIMEOUT, a message was received before the timeout\r
+   occured. The time variable is set to the number of\r
+   milliseconds we waited for the message. */\r
+      if (time <= timeouts->next->time) {\r
+  timeouts->next->time -= time;\r
+      } else {\r
+  timeouts->next->time = 0;\r
+      }\r
+    }\r
+\r
+  }\r
+}\r
+\r
+void\r
+sys_sem_wait(sys_sem_t sem)\r
+{\r
+  u32_t time;\r
+  struct sys_timeouts *timeouts;\r
+  struct sys_timeout *tmptimeout;\r
+  sys_timeout_handler h;\r
+  void *arg;\r
+\r
+  /*  while (sys_arch_sem_wait(sem, 1000) == 0);\r
+      return;*/\r
+\r
+ again:\r
+\r
+  timeouts = sys_arch_timeouts();\r
+\r
+  if (!timeouts || !timeouts->next) {\r
+    sys_arch_sem_wait(sem, 0);\r
+  } else {\r
+    if (timeouts->next->time > 0) {\r
+      time = sys_arch_sem_wait(sem, timeouts->next->time);\r
+    } else {\r
+      time = SYS_ARCH_TIMEOUT;\r
+    }\r
+\r
+    if (time == SYS_ARCH_TIMEOUT) {\r
+      /* If time == SYS_ARCH_TIMEOUT, a timeout occured before a message\r
+   could be fetched. We should now call the timeout handler and\r
+   deallocate the memory allocated for the timeout. */\r
+      tmptimeout = timeouts->next;\r
+      timeouts->next = tmptimeout->next;\r
+      h = tmptimeout->h;\r
+      arg = tmptimeout->arg;\r
+      memp_free(MEMP_SYS_TIMEOUT, tmptimeout);\r
+      if (h != NULL) {\r
+        LWIP_DEBUGF(SYS_DEBUG, ("ssw h=%p(%p)\n", (void *)h, (void *)arg));\r
+        h(arg);\r
+      }\r
+\r
+\r
+      /* We try again to fetch a message from the mbox. */\r
+      goto again;\r
+    } else {\r
+      /* If time != SYS_ARCH_TIMEOUT, a message was received before the timeout\r
+   occured. The time variable is set to the number of\r
+   milliseconds we waited for the message. */\r
+      if (time <= timeouts->next->time) {\r
+  timeouts->next->time -= time;\r
+      } else {\r
+  timeouts->next->time = 0;\r
+      }\r
+    }\r
+\r
+  }\r
+}\r
+\r
+void\r
+sys_timeout(u32_t msecs, sys_timeout_handler h, void *arg)\r
+{\r
+  struct sys_timeouts *timeouts;\r
+  struct sys_timeout *timeout, *t;\r
+\r
+  timeout = memp_malloc(MEMP_SYS_TIMEOUT);\r
+  if (timeout == NULL) {\r
+    return;\r
+  }\r
+  timeout->next = NULL;\r
+  timeout->h = h;\r
+  timeout->arg = arg;\r
+  timeout->time = msecs;\r
+\r
+  timeouts = sys_arch_timeouts();\r
+\r
+  LWIP_DEBUGF(SYS_DEBUG, ("sys_timeout: %p msecs=%lu h=%p arg=%p\n",\r
+    (void *)timeout, msecs, (void *)h, (void *)arg));\r
+\r
+  LWIP_ASSERT("sys_timeout: timeouts != NULL", timeouts != NULL);\r
+\r
+  if (timeouts->next == NULL) {\r
+    timeouts->next = timeout;\r
+    return;\r
+  }\r
+\r
+  if (timeouts->next->time > msecs) {\r
+    timeouts->next->time -= msecs;\r
+    timeout->next = timeouts->next;\r
+    timeouts->next = timeout;\r
+  } else {\r
+    for(t = timeouts->next; t != NULL; t = t->next) {\r
+      timeout->time -= t->time;\r
+      if (t->next == NULL || t->next->time > timeout->time) {\r
+        if (t->next != NULL) {\r
+          t->next->time -= timeout->time;\r
+        }\r
+        timeout->next = t->next;\r
+        t->next = timeout;\r
+        break;\r
+      }\r
+    }\r
+  }\r
+\r
+}\r
+\r
+/* Go through timeout list (for this task only) and remove the first matching entry,\r
+   even though the timeout has not triggered yet.\r
+*/\r
+\r
+void\r
+sys_untimeout(sys_timeout_handler h, void *arg)\r
+{\r
+    struct sys_timeouts *timeouts;\r
+    struct sys_timeout *prev_t, *t;\r
+\r
+    timeouts = sys_arch_timeouts();\r
+\r
+    if (timeouts->next == NULL)\r
+        return;\r
+\r
+    for (t = timeouts->next, prev_t = NULL; t != NULL; prev_t = t, t = t->next)\r
+    {\r
+        if ((t->h == h) && (t->arg == arg))\r
+        {\r
+            /* We have a match */\r
+            /* Unlink from previous in list */\r
+            if (prev_t == NULL)\r
+                timeouts->next = t->next;\r
+            else\r
+                prev_t->next = t->next;\r
+            /* If not the last one, add time of this one back to next */\r
+            if (t->next != NULL)\r
+                t->next->time += t->time;\r
+            memp_free(MEMP_SYS_TIMEOUT, t);\r
+            return;\r
+        }\r
+    }\r
+    return;\r
+}\r
+\r
+\r
+\r
+\r
+\r
+static void\r
+sswt_handler(void *arg)\r
+{\r
+    struct sswt_cb *sswt_cb = (struct sswt_cb *) arg;\r
+\r
+    /* Timeout. Set flag to TRUE and signal semaphore */\r
+    sswt_cb->timeflag = 1;\r
+    sys_sem_signal(*(sswt_cb->psem));\r
+}\r
+\r
+/* Wait for a semaphore with timeout (specified in ms) */\r
+/* timeout = 0: wait forever */\r
+/* Returns 0 on timeout. 1 otherwise */\r
+\r
+int\r
+sys_sem_wait_timeout(sys_sem_t sem, u32_t timeout)\r
+{\r
+    struct sswt_cb sswt_cb;\r
+\r
+    sswt_cb.psem = &sem;\r
+    sswt_cb.timeflag = 0;\r
+\r
+    /* If timeout is zero, then just wait forever */\r
+    if (timeout > 0)\r
+        /* Create a timer and pass it the address of our flag */\r
+        sys_timeout(timeout, sswt_handler, &sswt_cb);\r
+    sys_sem_wait(sem);\r
+    /* Was it a timeout? */\r
+    if (sswt_cb.timeflag)\r
+    {\r
+        /* timeout */\r
+        return 0;\r
+    } else {\r
+        /* Not a timeout. Remove timeout entry */\r
+        sys_untimeout(sswt_handler, &sswt_cb);\r
+        return 1;\r
+    }\r
+\r
+}\r
+\r
+\r
+void\r
+sys_msleep(u32_t ms)\r
+{\r
+  sys_sem_t delaysem = sys_sem_new(0);\r
+\r
+  sys_sem_wait_timeout(delaysem, ms);\r
+\r
+  sys_sem_free(delaysem);\r
+}\r
+\r
+\r
+#endif /* NO_SYS */\r
index c050a05aec9fc53377782b6cf0963fa9ec1f2f05..0571661f4d2767f03e3dfcda42ef7f142c01c15d 100644 (file)
-/**
- * @file
- *
- * Transmission Control Protocol, incoming traffic
- *
- * The input processing functions of TCP.
- *
- * 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 <adam@sics.se>
- *
- */
-
-#include "lwip/def.h"
-#include "lwip/opt.h"
-
-#include "lwip/ip_addr.h"
-#include "lwip/netif.h"
-#include "lwip/mem.h"
-#include "lwip/memp.h"
-
-#include "lwip/inet.h"
-#include "lwip/tcp.h"
-
-#include "lwip/stats.h"
-
-#include "arch/perf.h"
-#if LWIP_TCP
-/* 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);
-
-
-/* tcp_input:
- *
- * 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()).
- */
-
-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;
-
-#if SO_REUSE
-  struct tcp_pcb *pcb_temp;
-  int reuse = 0;
-  int reuse_port = 0;
-#endif /* SO_REUSE */
-
-  PERF_START;
-
-  TCP_STATS_INC(tcp.recv);
-
-  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 (%u bytes) discarded\n", p->tot_len));
-    TCP_STATS_INC(tcp.lenerr);
-    TCP_STATS_INC(tcp.drop);
-    pbuf_free(p);
-    return;
-  }
-
-  /* Don't even process incoming broadcasts/multicasts. */
-  if (ip_addr_isbroadcast(&(iphdr->dest), inp) ||
-      ip_addr_ismulticast(&(iphdr->dest))) {
-    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%04x\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);
-
-    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);
-  pbuf_header(p, -(hdrlen * 4));
-
-  /* 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) & TCP_FLAGS;
-  tcplen = p->tot_len + ((flags & TCP_FIN || flags & TCP_SYN)? 1: 0);
-
-  /* Demultiplex an incoming segment. First, we check if it is destined
-     for an active connection. */
-  prev = NULL;
-
-#if SO_REUSE
-  pcb_temp = tcp_active_pcbs;
-  
- again_1:
-  
-  /* Iterate through the TCP pcb list for a fully matching pcb */
-  for(pcb = pcb_temp; pcb != NULL; pcb = pcb->next) {
-#else  /* SO_REUSE */
-  for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
-#endif  /* SO_REUSE */
-    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))) {
-
-#if SO_REUSE
-      if(pcb->so_options & SOF_REUSEPORT) {
-        if(reuse) {
-          /* We processed one PCB already */
-          LWIP_DEBUGF(TCP_INPUT_DEBUG,("tcp_input: second or later PCB and SOF_REUSEPORT set.\n"));
-        } else {
-          /* First PCB with this address */
-          LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: first PCB and SOF_REUSEPORT set.\n"));
-          reuse = 1;
-        }
-        
-        reuse_port = 1; 
-        p->ref++;
-        
-        /* We want to search on next socket after receiving */
-        pcb_temp = pcb->next;
-        
-        LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: reference counter on PBUF set to %i\n", p->ref));
-      } else  {
-        if(reuse) {
-          /* We processed one PCB already */
-          LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: second or later PCB but SOF_REUSEPORT not set !\n"));
-        }
-      }
-#endif /* SO_REUSE */
-
-      /* 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;
-
-    tcp_input_pcb = pcb;
-    err = tcp_process(pcb);
-    tcp_input_pcb = NULL;
-    /* 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) {
-    /* Notify application that data has been received. */
-    TCP_EVENT_RECV(pcb, recv_data, ERR_OK, err);
-  }
-
-  /* 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);
-  }
-  /* If there were no errors, we try to send something out. */
-  if (err == ERR_OK) {
-    tcp_output(pcb);
-  }
-      }
-    }
-
-
-    /* We deallocate the incoming pbuf. If it was buffered by the
-       application, the application should have called pbuf_ref() to
-       increase the reference counter in the pbuf. If so, the buffer
-       isn't actually deallocated by the call to pbuf_free(), only the
-       reference count is decreased. */
-    if (inseg.p != NULL) pbuf_free(inseg.p);
-#if TCP_INPUT_DEBUG
-#if TCP_DEBUG
-    tcp_debug_print_state(pcb->state);
-#endif /* TCP_DEBUG */
-#endif /* TCP_INPUT_DEBUG */
-#if SO_REUSE
-    /* First socket should receive now */
-    if(reuse_port) {
-      LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: searching next PCB.\n"));
-      reuse_port = 0;
-      
-      /* We are searching connected sockets */
-      goto again_1;
-    }
-#endif /* SO_REUSE */
-
-  } else {
-#if SO_REUSE
-    if(reuse) {
-      LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: freeing PBUF with reference counter set to %i\n", p->ref));
-      pbuf_free(p);
-      goto end;
-    }
-#endif /* SO_REUSE */
-    /* 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);
-  }
-#if SO_REUSE
- end:
-#endif /* SO_REUSE */
-  LWIP_ASSERT("tcp_input: tcp_pcbs_sane()", tcp_pcbs_sane());
-  PERF_STOP("tcp_input");
-}
-
-/* tcp_listen_input():
- *
- * Called by tcp_input() when a segment arrives for a listening
- * connection.
- */
-
-static err_t
-tcp_listen_input(struct tcp_pcb_listen *pcb)
-{
-  struct tcp_pcb *npcb;
-  u32_t optdata;
-
-  /* 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 %u -> %u.\n", tcphdr->src, tcphdr->dest));
-    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;
-    }
-    /* 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->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);
-
-    /* Build an MSS option. */
-    optdata = htonl(((u32_t)2 << 24) |
-        ((u32_t)4 << 16) |
-        (((u32_t)npcb->mss / 256) << 8) |
-        (npcb->mss & 255));
-    /* Send a SYN|ACK together with the MSS option. */
-    tcp_enqueue(npcb, NULL, 0, TCP_SYN | TCP_ACK, 0, (u8_t *)&optdata, 4);
-    return tcp_output(npcb);
-  }
-  return ERR_OK;
-}
-
-/* tcp_timewait_input():
- *
- * Called by tcp_input() when a segment arrives for a connection in
- * TIME_WAIT.
- */
-
-static err_t
-tcp_timewait_input(struct tcp_pcb *pcb)
-{
-  if (TCP_SEQ_GT(seqno + tcplen, pcb->rcv_nxt)) {
-    pcb->rcv_nxt = seqno + tcplen;
-  }
-  if (tcplen > 0) {
-    tcp_ack_now(pcb);
-  }
-  return tcp_output(pcb);
-}
-
-/* tcp_process
- *
- * 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.
- */
-
-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_GEQ(seqno, pcb->rcv_nxt) &&
-          TCP_SEQ_LEQ(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {
-      */
-      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 %lu rcv_nxt %lu\n",
-       seqno, pcb->rcv_nxt));
-      LWIP_DEBUGF(TCP_DEBUG, ("tcp_process: unacceptable reset seqno %lu rcv_nxt %lu\n",
-       seqno, pcb->rcv_nxt));
-      return ERR_OK;
-    }
-  }
-
-  /* Update the PCB (in)activity timer. */
-  pcb->tmr = tcp_ticks;
-  pcb->keep_cnt = 0;
-
-  /* Do different things depending on the TCP state. */
-  switch (pcb->state) {
-  case SYN_SENT:
-    LWIP_DEBUGF(TCP_INPUT_DEBUG, ("SYN-SENT: ackno %lu pcb->snd_nxt %lu unacked %lu\n", ackno,
-     pcb->snd_nxt, ntohl(pcb->unacked->tcphdr->seqno)));
-    if ((flags & TCP_ACK) && (flags & TCP_SYN)
-        && ackno == ntohl(pcb->unacked->tcphdr->seqno) + 1) {
-      pcb->snd_buf ++;
-      pcb->rcv_nxt = seqno + 1;
-      pcb->lastack = ackno;
-      pcb->snd_wnd = tcphdr->wnd;
-      pcb->snd_wl1 = seqno - 1; /* initialise to seqno - 1 to force window update */
-      pcb->state = ESTABLISHED;
-      pcb->cwnd = pcb->mss;
-      --pcb->snd_queuelen;
-      LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_process: SYN-SENT --queuelen %u\n", (unsigned int)pcb->snd_queuelen));
-      rseg = pcb->unacked;
-      pcb->unacked = rseg->next;
-      tcp_seg_free(rseg);
-
-      /* Parse any options in the SYNACK. */
-      tcp_parseopt(pcb);
-
-      /* Call the user specified function to call when sucessfully
-       * connected. */
-      TCP_EVENT_CONNECTED(pcb, ERR_OK, err);
-      tcp_ack(pcb);
-    }
-    break;
-  case SYN_RCVD:
-    if (flags & TCP_ACK &&
-       !(flags & TCP_RST)) {
-      /*if (TCP_SEQ_LT(pcb->lastack, ackno) &&
-        TCP_SEQ_LEQ(ackno, pcb->snd_nxt)) { */
-      if(TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)){
-        pcb->state = ESTABLISHED;
-        LWIP_DEBUGF(TCP_DEBUG, ("TCP connection established %u -> %u.\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;
-        }
-        /* If there was any data contained within this ACK,
-         * we'd better pass it on to the application as well. */
-        tcp_receive(pcb);
-        pcb->cwnd = pcb->mss;
-      }
-    }
-    break;
-  case CLOSE_WAIT:
-    /* FALLTHROUGH */
-  case ESTABLISHED:
-    tcp_receive(pcb);
-    if (flags & TCP_FIN) {
-      tcp_ack_now(pcb);
-      pcb->state = CLOSE_WAIT;
-    }
-    break;
-  case FIN_WAIT_1:
-    tcp_receive(pcb);
-    if (flags & TCP_FIN) {
-      if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
-        LWIP_DEBUGF(TCP_DEBUG,
-         ("TCP connection closed %d -> %d.\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 (flags & TCP_FIN) {
-      LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed %u -> %u.\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 %u -> %u.\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 LAST_ACK:
-    tcp_receive(pcb);
-    if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
-      LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed %u -> %u.\n", inseg.tcphdr->src, inseg.tcphdr->dest));
-      pcb->state = CLOSED;
-      recv_flags = TF_CLOSED;
-    }
-    break;
-  default:
-    break;
-  }
-
-  return ERR_OK;
-}
-
-/* tcp_receive:
- *
- * 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.
- */
-
-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;
-  int m;
-  u32_t right_wnd_edge;
-  u16_t new_tot_len;
-
-
-  if (flags & TCP_ACK) {
-    right_wnd_edge = pcb->snd_wnd + pcb->snd_wl1;
-
-    /* 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;
-      LWIP_DEBUGF(TCP_WND_DEBUG, ("tcp_receive: window update %lu\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 %lu snd_max %lu ackno %lu wl1 %lu seqno %lu wl2 %lu\n",
-                               pcb->lastack, pcb->snd_max, ackno, pcb->snd_wl1, seqno, pcb->snd_wl2));
-      }
-#endif /* TCP_WND_DEBUG */
-    }
-
-
-    if (pcb->lastack == ackno) {
-      pcb->acked = 0;
-
-      if (pcb->snd_wl1 + pcb->snd_wnd == right_wnd_edge){
-        ++pcb->dupacks;
-        if (pcb->dupacks >= 3 && pcb->unacked != NULL) {
-          if (!(pcb->flags & TF_INFR)) {
-            /* This is fast retransmit. Retransmit the first unacked segment. */
-            LWIP_DEBUGF(TCP_FR_DEBUG, ("tcp_receive: dupacks %u (%lu), fast retransmit %lu\n",
-                                       (unsigned int)pcb->dupacks, pcb->lastack,
-                                       ntohl(pcb->unacked->tcphdr->seqno)));
-            tcp_rexmit(pcb);
-            /* Set ssthresh to max (FlightSize / 2, 2*SMSS) */
-            /*pcb->ssthresh = LWIP_MAX((pcb->snd_max -
-                                      pcb->lastack) / 2,
-                                      2 * pcb->mss);*/
-            /* Set ssthresh to half of the minimum of the currenct cwnd and the advertised window */
-            if(pcb->cwnd > pcb->snd_wnd)
-              pcb->ssthresh = pcb->snd_wnd / 2;
-            else
-              pcb->ssthresh = pcb->cwnd / 2;
-
-            pcb->cwnd = pcb->ssthresh + 3 * pcb->mss;
-            pcb->flags |= TF_INFR;
-          } else {
-            /* 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 {
-        LWIP_DEBUGF(TCP_FR_DEBUG, ("tcp_receive: dupack averted %lu %lu\n",
-                                   pcb->snd_wl1 + pcb->snd_wnd, right_wnd_edge));
-      }
-    } else
-      /*if (TCP_SEQ_LT(pcb->lastack, ackno) &&
-        TCP_SEQ_LEQ(ackno, pcb->snd_max)) { */
-      if(TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_max)){
-      /* 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. */
-      pcb->acked = 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 %u\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 %u\n", pcb->cwnd));
-        }
-      }
-      LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: ACK for %lu, unacked->seqno %lu:%lu\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 %lu:%lu 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 %u ... ", (unsigned int)pcb->snd_queuelen));
-        pcb->snd_queuelen -= pbuf_clen(next->p);
-        tcp_seg_free(next);
-
-        LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%u (after freeing unacked)\n", (unsigned int)pcb->snd_queuelen));
-        if (pcb->snd_queuelen != 0) {
-          LWIP_ASSERT("tcp_receive: valid queue length", pcb->unacked != NULL ||
-                      pcb->unsent != NULL);
-        }
-      }
-      pcb->polltmr = 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_LEQ(ntohl(pcb->unsent->tcphdr->seqno) + TCP_TCPLEN(pcb->unsent), ackno) &&
-             TCP_SEQ_LEQ(ackno, pcb->snd_max)*/
-           TCP_SEQ_BETWEEN(ackno, ntohl(pcb->unsent->tcphdr->seqno) + TCP_TCPLEN(pcb->unsent), pcb->snd_max)
-           ) {
-      LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %lu:%lu 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 %u ... ", (unsigned int)pcb->snd_queuelen));
-      pcb->snd_queuelen -= pbuf_clen(next->p);
-      tcp_seg_free(next);
-      LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%u (after freeing unsent)\n", (unsigned int)pcb->snd_queuelen));
-      if (pcb->snd_queuelen != 0) {
-        LWIP_ASSERT("tcp_receive: valid queue length",
-          pcb->unacked != NULL || pcb->unsent != NULL);
-      }
-
-      if (pcb->unsent != NULL) {
-        pcb->snd_nxt = htonl(pcb->unsent->tcphdr->seqno);
-      }
-    }
-    /* End of ACK for new data processing. */
-
-    LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: pcb->rttest %u rtseq %lu ackno %lu\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)) {
-      m = tcp_ticks - pcb->rttest;
-
-      LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: experienced rtt %u ticks (%u 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 %u (%u miliseconds)\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;
-      if (inseg.p->len < off) {
-        new_tot_len = 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;
-        }
-        pbuf_header(p, -off);
-      } else {
-        pbuf_header(inseg.p, -off);
-      }
-      /* KJM following line changed to use p->payload rather than inseg->p->payload
-         to fix bug #9076 */
-      inseg.dataptr = p->payload;
-      inseg.len -= 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 %lu\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_GEQ(seqno, pcb->rcv_nxt) &&
-      TCP_SEQ_LT(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {*/
-    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. */
-#if TCP_QUEUE_OOSEQ
-        if (pcb->ooseq != NULL &&
-            TCP_SEQ_LEQ(pcb->ooseq->tcphdr->seqno, seqno + inseg.len)) {
-          /* We have to trim the second edge of the incoming
-             segment. */
-          inseg.len = pcb->ooseq->tcphdr->seqno - seqno;
-          pbuf_realloc(inseg.p, inseg.len);
-        }
-#endif /* TCP_QUEUE_OOSEQ */
-
-        tcplen = TCP_TCPLEN(&inseg);
-
-        pcb->rcv_nxt += tcplen;
-
-        /* Update the receiver's (our) window. */
-        if (pcb->rcv_wnd < tcplen) {
-          pcb->rcv_wnd = 0;
-        } else {
-          pcb->rcv_wnd -= tcplen;
-        }
-
-        /* 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);
-          if (pcb->rcv_wnd < TCP_TCPLEN(cseg)) {
-            pcb->rcv_wnd = 0;
-          } else {
-            pcb->rcv_wnd -= TCP_TCPLEN(cseg);
-          }
-          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;
-          }
-
-
-          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_ack_now(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 the old segment with the new
-                   one. */
-                cseg = tcp_seg_copy(&inseg);
-                if (cseg != NULL) {
-                  cseg->next = next->next;
-                  if (prev != NULL) {
-                    prev->next = cseg;
-                  } else {
-                    pcb->ooseq = cseg;
-                  }
-                }
-                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. */
-
-                  if (TCP_SEQ_GT(seqno + inseg.len, next->tcphdr->seqno)) {
-                    /* We need to trim the incoming segment. */
-                    inseg.len = next->tcphdr->seqno - seqno;
-                    pbuf_realloc(inseg.p, inseg.len);
-                  }
-                  cseg = tcp_seg_copy(&inseg);
-                  if (cseg != NULL) {
-                    cseg->next = next;
-                    pcb->ooseq = cseg;
-                  }
-                  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 and insert the
-                   incoming segment and trim the previous segment, if
-                   needed. */
-                if (TCP_SEQ_GT(seqno + inseg.len, next->tcphdr->seqno)) {
-                  /* We need to trim the incoming segment. */
-                  inseg.len = next->tcphdr->seqno - seqno;
-                  pbuf_realloc(inseg.p, inseg.len);
-                }
-
-                cseg = tcp_seg_copy(&inseg);
-                if (cseg != NULL) {
-                  cseg->next = next;
-                  prev->next = cseg;
-                  if (TCP_SEQ_GT(prev->tcphdr->seqno + prev->len, seqno)) {
-                    /* We need to trim the prev segment. */
-                    prev->len = seqno - prev->tcphdr->seqno;
-                    pbuf_realloc(prev->p, prev->len);
-                  }
-                }
-                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)) {
-                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 = seqno - next->tcphdr->seqno;
-                    pbuf_realloc(next->p, next->len);
-                  }
-                }
-                break;
-              }
-            }
-            prev = next;
-          }
-        }
-#endif /* TCP_QUEUE_OOSEQ */
-
-      }
-    } else {
-      /*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);
-      }
-    }
-  } 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);
-    }
-  }
-}
-
-/*
- * tcp_parseopt:
- *
- * Parses the options contained in the incoming segment. (Code taken
- * from uIP with only small changes.)
- *
- */
-
-static void
-tcp_parseopt(struct tcp_pcb *pcb)
-{
-  u8_t c;
-  u8_t *opts, opt;
-  u16_t mss;
-
-  opts = (u8_t *)tcphdr + TCP_HLEN;
-
-  /* Parse the TCP MSS option, if present. */
-  if(TCPH_HDRLEN(tcphdr) > 0x5) {
-    for(c = 0; c < (TCPH_HDRLEN(tcphdr) - 5) << 2 ;) {
-      opt = opts[c];
-      if (opt == 0x00) {
-        /* End of options. */
-  break;
-      } else if (opt == 0x01) {
-        ++c;
-        /* NOP option. */
-      } else if (opt == 0x02 &&
-        opts[c + 1] == 0x04) {
-        /* An MSS option with the right option length. */
-        mss = (opts[c + 2] << 8) | opts[c + 3];
-        pcb->mss = mss > TCP_MSS? TCP_MSS: mss;
-
-        /* And we are done processing options. */
-        break;
-      } else {
-  if (opts[c + 1] == 0) {
-          /* If the length field is zero, the options are malformed
-             and we don't process them further. */
-          break;
-        }
-        /* All other options have a length field, so that we easily
-           can skip past them. */
-        c += opts[c + 1];
-      }
-    }
-  }
-}
-#endif /* LWIP_TCP */
-
-
+/**\r
+ * @file\r
+ *\r
+ * Transmission Control Protocol, incoming traffic\r
+ *\r
+ * The input processing functions of TCP.\r
+ *\r
+ * These functions are generally called in the order (ip_input() ->) tcp_input() ->\r
+ * tcp_process() -> tcp_receive() (-> application).\r
+ * \r
+ */\r
+\r
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without modification,\r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED\r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT\r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY\r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ *\r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+\r
+#include "lwip/def.h"\r
+#include "lwip/opt.h"\r
+\r
+#include "lwip/ip_addr.h"\r
+#include "lwip/netif.h"\r
+#include "lwip/mem.h"\r
+#include "lwip/memp.h"\r
+\r
+#include "lwip/inet.h"\r
+#include "lwip/tcp.h"\r
+\r
+#include "lwip/stats.h"\r
+\r
+#include "arch/perf.h"\r
+#if LWIP_TCP\r
+/* These variables are global to all functions involved in the input\r
+   processing of TCP segments. They are set by the tcp_input()\r
+   function. */\r
+static struct tcp_seg inseg;\r
+static struct tcp_hdr *tcphdr;\r
+static struct ip_hdr *iphdr;\r
+static u32_t seqno, ackno;\r
+static u8_t flags;\r
+static u16_t tcplen;\r
+\r
+static u8_t recv_flags;\r
+static struct pbuf *recv_data;\r
+\r
+struct tcp_pcb *tcp_input_pcb;\r
+\r
+/* Forward declarations. */\r
+static err_t tcp_process(struct tcp_pcb *pcb);\r
+static void tcp_receive(struct tcp_pcb *pcb);\r
+static void tcp_parseopt(struct tcp_pcb *pcb);\r
+\r
+static err_t tcp_listen_input(struct tcp_pcb_listen *pcb);\r
+static err_t tcp_timewait_input(struct tcp_pcb *pcb);\r
+\r
+\r
+/* tcp_input:\r
+ *\r
+ * The initial input processing of TCP. It verifies the TCP header, demultiplexes\r
+ * the segment between the PCBs and passes it on to tcp_process(), which implements\r
+ * the TCP finite state machine. This function is called by the IP layer (in\r
+ * ip_input()).\r
+ */\r
+\r
+void\r
+tcp_input(struct pbuf *p, struct netif *inp)\r
+{\r
+  struct tcp_pcb *pcb, *prev;\r
+  struct tcp_pcb_listen *lpcb;\r
+  u8_t hdrlen;\r
+  err_t err;\r
+\r
+#if SO_REUSE\r
+  struct tcp_pcb *pcb_temp;\r
+  int reuse = 0;\r
+  int reuse_port = 0;\r
+#endif /* SO_REUSE */\r
+\r
+  PERF_START;\r
+\r
+  TCP_STATS_INC(tcp.recv);\r
+\r
+  iphdr = p->payload;\r
+  tcphdr = (struct tcp_hdr *)((u8_t *)p->payload + IPH_HL(iphdr) * 4);\r
+\r
+#if TCP_INPUT_DEBUG\r
+  tcp_debug_print(tcphdr);\r
+#endif\r
+\r
+  /* remove header from payload */\r
+  if (pbuf_header(p, -((s16_t)(IPH_HL(iphdr) * 4))) || (p->tot_len < sizeof(struct tcp_hdr))) {\r
+    /* drop short packets */\r
+    LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: short packet (%u bytes) discarded\n", p->tot_len));\r
+    TCP_STATS_INC(tcp.lenerr);\r
+    TCP_STATS_INC(tcp.drop);\r
+    pbuf_free(p);\r
+    return;\r
+  }\r
+\r
+  /* Don't even process incoming broadcasts/multicasts. */\r
+  if (ip_addr_isbroadcast(&(iphdr->dest), inp) ||\r
+      ip_addr_ismulticast(&(iphdr->dest))) {\r
+    pbuf_free(p);\r
+    return;\r
+  }\r
+\r
+#if CHECKSUM_CHECK_TCP\r
+  /* Verify TCP checksum. */\r
+  if (inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src),\r
+      (struct ip_addr *)&(iphdr->dest),\r
+      IP_PROTO_TCP, p->tot_len) != 0) {\r
+      LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packet discarded due to failing checksum 0x%04x\n",\r
+        inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src), (struct ip_addr *)&(iphdr->dest),\r
+      IP_PROTO_TCP, p->tot_len)));\r
+#if TCP_DEBUG\r
+    tcp_debug_print(tcphdr);\r
+#endif /* TCP_DEBUG */\r
+    TCP_STATS_INC(tcp.chkerr);\r
+    TCP_STATS_INC(tcp.drop);\r
+\r
+    pbuf_free(p);\r
+    return;\r
+  }\r
+#endif\r
+\r
+  /* Move the payload pointer in the pbuf so that it points to the\r
+     TCP data instead of the TCP header. */\r
+  hdrlen = TCPH_HDRLEN(tcphdr);\r
+  pbuf_header(p, -(hdrlen * 4));\r
+\r
+  /* Convert fields in TCP header to host byte order. */\r
+  tcphdr->src = ntohs(tcphdr->src);\r
+  tcphdr->dest = ntohs(tcphdr->dest);\r
+  seqno = tcphdr->seqno = ntohl(tcphdr->seqno);\r
+  ackno = tcphdr->ackno = ntohl(tcphdr->ackno);\r
+  tcphdr->wnd = ntohs(tcphdr->wnd);\r
+\r
+  flags = TCPH_FLAGS(tcphdr) & TCP_FLAGS;\r
+  tcplen = p->tot_len + ((flags & TCP_FIN || flags & TCP_SYN)? 1: 0);\r
+\r
+  /* Demultiplex an incoming segment. First, we check if it is destined\r
+     for an active connection. */\r
+  prev = NULL;\r
+\r
+#if SO_REUSE\r
+  pcb_temp = tcp_active_pcbs;\r
+  \r
+ again_1:\r
+  \r
+  /* Iterate through the TCP pcb list for a fully matching pcb */\r
+  for(pcb = pcb_temp; pcb != NULL; pcb = pcb->next) {\r
+#else  /* SO_REUSE */\r
+  for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {\r
+#endif  /* SO_REUSE */\r
+    LWIP_ASSERT("tcp_input: active pcb->state != CLOSED", pcb->state != CLOSED);\r
+    LWIP_ASSERT("tcp_input: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT);\r
+    LWIP_ASSERT("tcp_input: active pcb->state != LISTEN", pcb->state != LISTEN);\r
+    if (pcb->remote_port == tcphdr->src &&\r
+       pcb->local_port == tcphdr->dest &&\r
+       ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src)) &&\r
+       ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest))) {\r
+\r
+#if SO_REUSE\r
+      if(pcb->so_options & SOF_REUSEPORT) {\r
+        if(reuse) {\r
+          /* We processed one PCB already */\r
+          LWIP_DEBUGF(TCP_INPUT_DEBUG,("tcp_input: second or later PCB and SOF_REUSEPORT set.\n"));\r
+        } else {\r
+          /* First PCB with this address */\r
+          LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: first PCB and SOF_REUSEPORT set.\n"));\r
+          reuse = 1;\r
+        }\r
+        \r
+        reuse_port = 1; \r
+        p->ref++;\r
+        \r
+        /* We want to search on next socket after receiving */\r
+        pcb_temp = pcb->next;\r
+        \r
+        LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: reference counter on PBUF set to %i\n", p->ref));\r
+      } else  {\r
+        if(reuse) {\r
+          /* We processed one PCB already */\r
+          LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: second or later PCB but SOF_REUSEPORT not set !\n"));\r
+        }\r
+      }\r
+#endif /* SO_REUSE */\r
+\r
+      /* Move this PCB to the front of the list so that subsequent\r
+   lookups will be faster (we exploit locality in TCP segment\r
+   arrivals). */\r
+      LWIP_ASSERT("tcp_input: pcb->next != pcb (before cache)", pcb->next != pcb);\r
+      if (prev != NULL) {\r
+  prev->next = pcb->next;\r
+  pcb->next = tcp_active_pcbs;\r
+  tcp_active_pcbs = pcb;\r
+      }\r
+      LWIP_ASSERT("tcp_input: pcb->next != pcb (after cache)", pcb->next != pcb);\r
+      break;\r
+    }\r
+    prev = pcb;\r
+  }\r
+\r
+  if (pcb == NULL) {\r
+    /* If it did not go to an active connection, we check the connections\r
+       in the TIME-WAIT state. */\r
+\r
+    for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {\r
+      LWIP_ASSERT("tcp_input: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT);\r
+      if (pcb->remote_port == tcphdr->src &&\r
+   pcb->local_port == tcphdr->dest &&\r
+   ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src)) &&\r
+         ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest))) {\r
+  /* We don't really care enough to move this PCB to the front\r
+     of the list since we are not very likely to receive that\r
+     many segments for connections in TIME-WAIT. */\r
+  LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for TIME_WAITing connection.\n"));\r
+  tcp_timewait_input(pcb);\r
+  pbuf_free(p);\r
+  return;\r
+      }\r
+    }\r
+\r
+  /* Finally, if we still did not get a match, we check all PCBs that\r
+     are LISTENing for incoming connections. */\r
+    prev = NULL;\r
+    for(lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {\r
+      if ((ip_addr_isany(&(lpcb->local_ip)) ||\r
+    ip_addr_cmp(&(lpcb->local_ip), &(iphdr->dest))) &&\r
+   lpcb->local_port == tcphdr->dest) {\r
+  /* Move this PCB to the front of the list so that subsequent\r
+     lookups will be faster (we exploit locality in TCP segment\r
+     arrivals). */\r
+  if (prev != NULL) {\r
+    ((struct tcp_pcb_listen *)prev)->next = lpcb->next;\r
+          /* our successor is the remainder of the listening list */\r
+    lpcb->next = tcp_listen_pcbs.listen_pcbs;\r
+          /* put this listening pcb at the head of the listening list */\r
+    tcp_listen_pcbs.listen_pcbs = lpcb;\r
+  }\r
+\r
+  LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for LISTENing connection.\n"));\r
+  tcp_listen_input(lpcb);\r
+  pbuf_free(p);\r
+  return;\r
+      }\r
+      prev = (struct tcp_pcb *)lpcb;\r
+    }\r
+  }\r
+\r
+#if TCP_INPUT_DEBUG\r
+  LWIP_DEBUGF(TCP_INPUT_DEBUG, ("+-+-+-+-+-+-+-+-+-+-+-+-+-+- tcp_input: flags "));\r
+  tcp_debug_print_flags(TCPH_FLAGS(tcphdr));\r
+  LWIP_DEBUGF(TCP_INPUT_DEBUG, ("-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n"));\r
+#endif /* TCP_INPUT_DEBUG */\r
+\r
+\r
+  if (pcb != NULL) {\r
+    /* The incoming segment belongs to a connection. */\r
+#if TCP_INPUT_DEBUG\r
+#if TCP_DEBUG\r
+    tcp_debug_print_state(pcb->state);\r
+#endif /* TCP_DEBUG */\r
+#endif /* TCP_INPUT_DEBUG */\r
+\r
+    /* Set up a tcp_seg structure. */\r
+    inseg.next = NULL;\r
+    inseg.len = p->tot_len;\r
+    inseg.dataptr = p->payload;\r
+    inseg.p = p;\r
+    inseg.tcphdr = tcphdr;\r
+\r
+    recv_data = NULL;\r
+    recv_flags = 0;\r
+\r
+    tcp_input_pcb = pcb;\r
+    err = tcp_process(pcb);\r
+    tcp_input_pcb = NULL;\r
+    /* A return value of ERR_ABRT means that tcp_abort() was called\r
+       and that the pcb has been freed. If so, we don't do anything. */\r
+    if (err != ERR_ABRT) {\r
+      if (recv_flags & TF_RESET) {\r
+  /* TF_RESET means that the connection was reset by the other\r
+     end. We then call the error callback to inform the\r
+     application that the connection is dead before we\r
+     deallocate the PCB. */\r
+  TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_RST);\r
+  tcp_pcb_remove(&tcp_active_pcbs, pcb);\r
+  memp_free(MEMP_TCP_PCB, pcb);\r
+      } else if (recv_flags & TF_CLOSED) {\r
+  /* The connection has been closed and we will deallocate the\r
+     PCB. */\r
+  tcp_pcb_remove(&tcp_active_pcbs, pcb);\r
+  memp_free(MEMP_TCP_PCB, pcb);\r
+      } else {\r
+  err = ERR_OK;\r
+  /* If the application has registered a "sent" function to be\r
+     called when new send buffer space is available, we call it\r
+     now. */\r
+  if (pcb->acked > 0) {\r
+    TCP_EVENT_SENT(pcb, pcb->acked, err);\r
+  }\r
+\r
+  if (recv_data != NULL) {\r
+    /* Notify application that data has been received. */\r
+    TCP_EVENT_RECV(pcb, recv_data, ERR_OK, err);\r
+  }\r
+\r
+  /* If a FIN segment was received, we call the callback\r
+     function with a NULL buffer to indicate EOF. */\r
+  if (recv_flags & TF_GOT_FIN) {\r
+    TCP_EVENT_RECV(pcb, NULL, ERR_OK, err);\r
+  }\r
+  /* If there were no errors, we try to send something out. */\r
+  if (err == ERR_OK) {\r
+    tcp_output(pcb);\r
+  }\r
+      }\r
+    }\r
+\r
+\r
+    /* We deallocate the incoming pbuf. If it was buffered by the\r
+       application, the application should have called pbuf_ref() to\r
+       increase the reference counter in the pbuf. If so, the buffer\r
+       isn't actually deallocated by the call to pbuf_free(), only the\r
+       reference count is decreased. */\r
+    if (inseg.p != NULL) pbuf_free(inseg.p);\r
+#if TCP_INPUT_DEBUG\r
+#if TCP_DEBUG\r
+    tcp_debug_print_state(pcb->state);\r
+#endif /* TCP_DEBUG */\r
+#endif /* TCP_INPUT_DEBUG */\r
+#if SO_REUSE\r
+    /* First socket should receive now */\r
+    if(reuse_port) {\r
+      LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: searching next PCB.\n"));\r
+      reuse_port = 0;\r
+      \r
+      /* We are searching connected sockets */\r
+      goto again_1;\r
+    }\r
+#endif /* SO_REUSE */\r
+\r
+  } else {\r
+#if SO_REUSE\r
+    if(reuse) {\r
+      LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: freeing PBUF with reference counter set to %i\n", p->ref));\r
+      pbuf_free(p);\r
+      goto end;\r
+    }\r
+#endif /* SO_REUSE */\r
+    /* If no matching PCB was found, send a TCP RST (reset) to the\r
+       sender. */\r
+    LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_input: no PCB match found, resetting.\n"));\r
+    if (!(TCPH_FLAGS(tcphdr) & TCP_RST)) {\r
+      TCP_STATS_INC(tcp.proterr);\r
+      TCP_STATS_INC(tcp.drop);\r
+      tcp_rst(ackno, seqno + tcplen,\r
+        &(iphdr->dest), &(iphdr->src),\r
+        tcphdr->dest, tcphdr->src);\r
+    }\r
+    pbuf_free(p);\r
+  }\r
+#if SO_REUSE\r
+ end:\r
+#endif /* SO_REUSE */\r
+  LWIP_ASSERT("tcp_input: tcp_pcbs_sane()", tcp_pcbs_sane());\r
+  PERF_STOP("tcp_input");\r
+}\r
+\r
+/* tcp_listen_input():\r
+ *\r
+ * Called by tcp_input() when a segment arrives for a listening\r
+ * connection.\r
+ */\r
+\r
+static err_t\r
+tcp_listen_input(struct tcp_pcb_listen *pcb)\r
+{\r
+  struct tcp_pcb *npcb;\r
+  u32_t optdata;\r
+\r
+  /* In the LISTEN state, we check for incoming SYN segments,\r
+     creates a new PCB, and responds with a SYN|ACK. */\r
+  if (flags & TCP_ACK) {\r
+    /* For incoming segments with the ACK flag set, respond with a\r
+       RST. */\r
+    LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_listen_input: ACK in LISTEN, sending reset\n"));\r
+    tcp_rst(ackno + 1, seqno + tcplen,\r
+      &(iphdr->dest), &(iphdr->src),\r
+      tcphdr->dest, tcphdr->src);\r
+  } else if (flags & TCP_SYN) {\r
+    LWIP_DEBUGF(TCP_DEBUG, ("TCP connection request %u -> %u.\n", tcphdr->src, tcphdr->dest));\r
+    npcb = tcp_alloc(pcb->prio);\r
+    /* If a new PCB could not be created (probably due to lack of memory),\r
+       we don't do anything, but rely on the sender will retransmit the\r
+       SYN at a time when we have more memory available. */\r
+    if (npcb == NULL) {\r
+      LWIP_DEBUGF(TCP_DEBUG, ("tcp_listen_input: could not allocate PCB\n"));\r
+      TCP_STATS_INC(tcp.memerr);\r
+      return ERR_MEM;\r
+    }\r
+    /* Set up the new PCB. */\r
+    ip_addr_set(&(npcb->local_ip), &(iphdr->dest));\r
+    npcb->local_port = pcb->local_port;\r
+    ip_addr_set(&(npcb->remote_ip), &(iphdr->src));\r
+    npcb->remote_port = tcphdr->src;\r
+    npcb->state = SYN_RCVD;\r
+    npcb->rcv_nxt = seqno + 1;\r
+    npcb->snd_wnd = tcphdr->wnd;\r
+    npcb->ssthresh = npcb->snd_wnd;\r
+    npcb->snd_wl1 = seqno - 1;/* initialise to seqno-1 to force window update */\r
+    npcb->callback_arg = pcb->callback_arg;\r
+#if LWIP_CALLBACK_API\r
+    npcb->accept = pcb->accept;\r
+#endif /* LWIP_CALLBACK_API */\r
+    /* inherit socket options */\r
+    npcb->so_options = pcb->so_options & (SOF_DEBUG|SOF_DONTROUTE|SOF_KEEPALIVE|SOF_OOBINLINE|SOF_LINGER);\r
+    /* Register the new PCB so that we can begin receiving segments\r
+       for it. */\r
+    TCP_REG(&tcp_active_pcbs, npcb);\r
+\r
+    /* Parse any options in the SYN. */\r
+    tcp_parseopt(npcb);\r
+\r
+    /* Build an MSS option. */\r
+    optdata = htonl(((u32_t)2 << 24) |\r
+        ((u32_t)4 << 16) |\r
+        (((u32_t)npcb->mss / 256) << 8) |\r
+        (npcb->mss & 255));\r
+    /* Send a SYN|ACK together with the MSS option. */\r
+    tcp_enqueue(npcb, NULL, 0, TCP_SYN | TCP_ACK, 0, (u8_t *)&optdata, 4);\r
+    return tcp_output(npcb);\r
+  }\r
+  return ERR_OK;\r
+}\r
+\r
+/* tcp_timewait_input():\r
+ *\r
+ * Called by tcp_input() when a segment arrives for a connection in\r
+ * TIME_WAIT.\r
+ */\r
+\r
+static err_t\r
+tcp_timewait_input(struct tcp_pcb *pcb)\r
+{\r
+  if (TCP_SEQ_GT(seqno + tcplen, pcb->rcv_nxt)) {\r
+    pcb->rcv_nxt = seqno + tcplen;\r
+  }\r
+  if (tcplen > 0) {\r
+    tcp_ack_now(pcb);\r
+  }\r
+  return tcp_output(pcb);\r
+}\r
+\r
+/* tcp_process\r
+ *\r
+ * Implements the TCP state machine. Called by tcp_input. In some\r
+ * states tcp_receive() is called to receive data. The tcp_seg\r
+ * argument will be freed by the caller (tcp_input()) unless the\r
+ * recv_data pointer in the pcb is set.\r
+ */\r
+\r
+static err_t\r
+tcp_process(struct tcp_pcb *pcb)\r
+{\r
+  struct tcp_seg *rseg;\r
+  u8_t acceptable = 0;\r
+  err_t err;\r
+\r
+\r
+  err = ERR_OK;\r
+\r
+  /* Process incoming RST segments. */\r
+  if (flags & TCP_RST) {\r
+    /* First, determine if the reset is acceptable. */\r
+    if (pcb->state == SYN_SENT) {\r
+      if (ackno == pcb->snd_nxt) {\r
+        acceptable = 1;\r
+      }\r
+    } else {\r
+      /*if (TCP_SEQ_GEQ(seqno, pcb->rcv_nxt) &&\r
+          TCP_SEQ_LEQ(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {\r
+      */\r
+      if(TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt+pcb->rcv_wnd)){\r
+        acceptable = 1;\r
+      }\r
+    }\r
+\r
+    if (acceptable) {\r
+      LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: Connection RESET\n"));\r
+      LWIP_ASSERT("tcp_input: pcb->state != CLOSED", pcb->state != CLOSED);\r
+      recv_flags = TF_RESET;\r
+      pcb->flags &= ~TF_ACK_DELAY;\r
+      return ERR_RST;\r
+    } else {\r
+      LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: unacceptable reset seqno %lu rcv_nxt %lu\n",\r
+       seqno, pcb->rcv_nxt));\r
+      LWIP_DEBUGF(TCP_DEBUG, ("tcp_process: unacceptable reset seqno %lu rcv_nxt %lu\n",\r
+       seqno, pcb->rcv_nxt));\r
+      return ERR_OK;\r
+    }\r
+  }\r
+\r
+  /* Update the PCB (in)activity timer. */\r
+  pcb->tmr = tcp_ticks;\r
+  pcb->keep_cnt = 0;\r
+\r
+  /* Do different things depending on the TCP state. */\r
+  switch (pcb->state) {\r
+  case SYN_SENT:\r
+    LWIP_DEBUGF(TCP_INPUT_DEBUG, ("SYN-SENT: ackno %lu pcb->snd_nxt %lu unacked %lu\n", ackno,\r
+     pcb->snd_nxt, ntohl(pcb->unacked->tcphdr->seqno)));\r
+    if ((flags & TCP_ACK) && (flags & TCP_SYN)\r
+        && ackno == ntohl(pcb->unacked->tcphdr->seqno) + 1) {\r
+      pcb->snd_buf ++;\r
+      pcb->rcv_nxt = seqno + 1;\r
+      pcb->lastack = ackno;\r
+      pcb->snd_wnd = tcphdr->wnd;\r
+      pcb->snd_wl1 = seqno - 1; /* initialise to seqno - 1 to force window update */\r
+      pcb->state = ESTABLISHED;\r
+      pcb->cwnd = pcb->mss;\r
+      --pcb->snd_queuelen;\r
+      LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_process: SYN-SENT --queuelen %u\n", (unsigned int)pcb->snd_queuelen));\r
+      rseg = pcb->unacked;\r
+      pcb->unacked = rseg->next;\r
+      tcp_seg_free(rseg);\r
+\r
+      /* Parse any options in the SYNACK. */\r
+      tcp_parseopt(pcb);\r
+\r
+      /* Call the user specified function to call when sucessfully\r
+       * connected. */\r
+      TCP_EVENT_CONNECTED(pcb, ERR_OK, err);\r
+      tcp_ack(pcb);\r
+    }\r
+    break;\r
+  case SYN_RCVD:\r
+    if (flags & TCP_ACK &&\r
+       !(flags & TCP_RST)) {\r
+      /*if (TCP_SEQ_LT(pcb->lastack, ackno) &&\r
+        TCP_SEQ_LEQ(ackno, pcb->snd_nxt)) { */\r
+      if(TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)){\r
+        pcb->state = ESTABLISHED;\r
+        LWIP_DEBUGF(TCP_DEBUG, ("TCP connection established %u -> %u.\n", inseg.tcphdr->src, inseg.tcphdr->dest));\r
+#if LWIP_CALLBACK_API\r
+        LWIP_ASSERT("pcb->accept != NULL", pcb->accept != NULL);\r
+#endif\r
+        /* Call the accept function. */\r
+        TCP_EVENT_ACCEPT(pcb, ERR_OK, err);\r
+        if (err != ERR_OK) {\r
+          /* If the accept function returns with an error, we abort\r
+           * the connection. */\r
+          tcp_abort(pcb);\r
+          return ERR_ABRT;\r
+        }\r
+        /* If there was any data contained within this ACK,\r
+         * we'd better pass it on to the application as well. */\r
+        tcp_receive(pcb);\r
+        pcb->cwnd = pcb->mss;\r
+      }\r
+    }\r
+    break;\r
+  case CLOSE_WAIT:\r
+    /* FALLTHROUGH */\r
+  case ESTABLISHED:\r
+    tcp_receive(pcb);\r
+    if (flags & TCP_FIN) {\r
+      tcp_ack_now(pcb);\r
+      pcb->state = CLOSE_WAIT;\r
+    }\r
+    break;\r
+  case FIN_WAIT_1:\r
+    tcp_receive(pcb);\r
+    if (flags & TCP_FIN) {\r
+      if (flags & TCP_ACK && ackno == pcb->snd_nxt) {\r
+        LWIP_DEBUGF(TCP_DEBUG,\r
+         ("TCP connection closed %d -> %d.\n", inseg.tcphdr->src, inseg.tcphdr->dest));\r
+  tcp_ack_now(pcb);\r
+  tcp_pcb_purge(pcb);\r
+  TCP_RMV(&tcp_active_pcbs, pcb);\r
+  pcb->state = TIME_WAIT;\r
+  TCP_REG(&tcp_tw_pcbs, pcb);\r
+      } else {\r
+  tcp_ack_now(pcb);\r
+  pcb->state = CLOSING;\r
+      }\r
+    } else if (flags & TCP_ACK && ackno == pcb->snd_nxt) {\r
+      pcb->state = FIN_WAIT_2;\r
+    }\r
+    break;\r
+  case FIN_WAIT_2:\r
+    tcp_receive(pcb);\r
+    if (flags & TCP_FIN) {\r
+      LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed %u -> %u.\n", inseg.tcphdr->src, inseg.tcphdr->dest));\r
+      tcp_ack_now(pcb);\r
+      tcp_pcb_purge(pcb);\r
+      TCP_RMV(&tcp_active_pcbs, pcb);\r
+      pcb->state = TIME_WAIT;\r
+      TCP_REG(&tcp_tw_pcbs, pcb);\r
+    }\r
+    break;\r
+  case CLOSING:\r
+    tcp_receive(pcb);\r
+    if (flags & TCP_ACK && ackno == pcb->snd_nxt) {\r
+      LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed %u -> %u.\n", inseg.tcphdr->src, inseg.tcphdr->dest));\r
+      tcp_ack_now(pcb);\r
+      tcp_pcb_purge(pcb);\r
+      TCP_RMV(&tcp_active_pcbs, pcb);\r
+      pcb->state = TIME_WAIT;\r
+      TCP_REG(&tcp_tw_pcbs, pcb);\r
+    }\r
+    break;\r
+  case LAST_ACK:\r
+    tcp_receive(pcb);\r
+    if (flags & TCP_ACK && ackno == pcb->snd_nxt) {\r
+      LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed %u -> %u.\n", inseg.tcphdr->src, inseg.tcphdr->dest));\r
+      pcb->state = CLOSED;\r
+      recv_flags = TF_CLOSED;\r
+    }\r
+    break;\r
+  default:\r
+    break;\r
+  }\r
+\r
+  return ERR_OK;\r
+}\r
+\r
+/* tcp_receive:\r
+ *\r
+ * Called by tcp_process. Checks if the given segment is an ACK for outstanding\r
+ * data, and if so frees the memory of the buffered data. Next, is places the\r
+ * segment on any of the receive queues (pcb->recved or pcb->ooseq). If the segment\r
+ * is buffered, the pbuf is referenced by pbuf_ref so that it will not be freed until\r
+ * i it has been removed from the buffer.\r
+ *\r
+ * If the incoming segment constitutes an ACK for a segment that was used for RTT\r
+ * estimation, the RTT is estimated here as well.\r
+ */\r
+\r
+static void\r
+tcp_receive(struct tcp_pcb *pcb)\r
+{\r
+  struct tcp_seg *next;\r
+#if TCP_QUEUE_OOSEQ\r
+  struct tcp_seg *prev, *cseg;\r
+#endif\r
+  struct pbuf *p;\r
+  s32_t off;\r
+  int m;\r
+  u32_t right_wnd_edge;\r
+  u16_t new_tot_len;\r
+\r
+\r
+  if (flags & TCP_ACK) {\r
+    right_wnd_edge = pcb->snd_wnd + pcb->snd_wl1;\r
+\r
+    /* Update window. */\r
+    if (TCP_SEQ_LT(pcb->snd_wl1, seqno) ||\r
+       (pcb->snd_wl1 == seqno && TCP_SEQ_LT(pcb->snd_wl2, ackno)) ||\r
+       (pcb->snd_wl2 == ackno && tcphdr->wnd > pcb->snd_wnd)) {\r
+      pcb->snd_wnd = tcphdr->wnd;\r
+      pcb->snd_wl1 = seqno;\r
+      pcb->snd_wl2 = ackno;\r
+      LWIP_DEBUGF(TCP_WND_DEBUG, ("tcp_receive: window update %lu\n", pcb->snd_wnd));\r
+#if TCP_WND_DEBUG\r
+    } else {\r
+      if (pcb->snd_wnd != tcphdr->wnd) {\r
+        LWIP_DEBUGF(TCP_WND_DEBUG, ("tcp_receive: no window update lastack %lu snd_max %lu ackno %lu wl1 %lu seqno %lu wl2 %lu\n",\r
+                               pcb->lastack, pcb->snd_max, ackno, pcb->snd_wl1, seqno, pcb->snd_wl2));\r
+      }\r
+#endif /* TCP_WND_DEBUG */\r
+    }\r
+\r
+\r
+    if (pcb->lastack == ackno) {\r
+      pcb->acked = 0;\r
+\r
+      if (pcb->snd_wl1 + pcb->snd_wnd == right_wnd_edge){\r
+        ++pcb->dupacks;\r
+        if (pcb->dupacks >= 3 && pcb->unacked != NULL) {\r
+          if (!(pcb->flags & TF_INFR)) {\r
+            /* This is fast retransmit. Retransmit the first unacked segment. */\r
+            LWIP_DEBUGF(TCP_FR_DEBUG, ("tcp_receive: dupacks %u (%lu), fast retransmit %lu\n",\r
+                                       (unsigned int)pcb->dupacks, pcb->lastack,\r
+                                       ntohl(pcb->unacked->tcphdr->seqno)));\r
+            tcp_rexmit(pcb);\r
+            /* Set ssthresh to max (FlightSize / 2, 2*SMSS) */\r
+            /*pcb->ssthresh = LWIP_MAX((pcb->snd_max -\r
+                                      pcb->lastack) / 2,\r
+                                      2 * pcb->mss);*/\r
+            /* Set ssthresh to half of the minimum of the currenct cwnd and the advertised window */\r
+            if(pcb->cwnd > pcb->snd_wnd)\r
+              pcb->ssthresh = pcb->snd_wnd / 2;\r
+            else\r
+              pcb->ssthresh = pcb->cwnd / 2;\r
+\r
+            pcb->cwnd = pcb->ssthresh + 3 * pcb->mss;\r
+            pcb->flags |= TF_INFR;\r
+          } else {\r
+            /* Inflate the congestion window, but not if it means that\r
+               the value overflows. */\r
+            if ((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) {\r
+              pcb->cwnd += pcb->mss;\r
+            }\r
+          }\r
+        }\r
+      } else {\r
+        LWIP_DEBUGF(TCP_FR_DEBUG, ("tcp_receive: dupack averted %lu %lu\n",\r
+                                   pcb->snd_wl1 + pcb->snd_wnd, right_wnd_edge));\r
+      }\r
+    } else\r
+      /*if (TCP_SEQ_LT(pcb->lastack, ackno) &&\r
+        TCP_SEQ_LEQ(ackno, pcb->snd_max)) { */\r
+      if(TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_max)){\r
+      /* We come here when the ACK acknowledges new data. */\r
+      \r
+      /* Reset the "IN Fast Retransmit" flag, since we are no longer\r
+         in fast retransmit. Also reset the congestion window to the\r
+         slow start threshold. */\r
+      if (pcb->flags & TF_INFR) {\r
+        pcb->flags &= ~TF_INFR;\r
+        pcb->cwnd = pcb->ssthresh;\r
+      }\r
+\r
+      /* Reset the number of retransmissions. */\r
+      pcb->nrtx = 0;\r
+\r
+      /* Reset the retransmission time-out. */\r
+      pcb->rto = (pcb->sa >> 3) + pcb->sv;\r
+\r
+      /* Update the send buffer space. */\r
+      pcb->acked = ackno - pcb->lastack;\r
+      pcb->snd_buf += pcb->acked;\r
+\r
+      /* Reset the fast retransmit variables. */\r
+      pcb->dupacks = 0;\r
+      pcb->lastack = ackno;\r
+\r
+      /* Update the congestion control variables (cwnd and\r
+         ssthresh). */\r
+      if (pcb->state >= ESTABLISHED) {\r
+        if (pcb->cwnd < pcb->ssthresh) {\r
+          if ((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) {\r
+            pcb->cwnd += pcb->mss;\r
+          }\r
+          LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: slow start cwnd %u\n", pcb->cwnd));\r
+        } else {\r
+          u16_t new_cwnd = (pcb->cwnd + pcb->mss * pcb->mss / pcb->cwnd);\r
+          if (new_cwnd > pcb->cwnd) {\r
+            pcb->cwnd = new_cwnd;\r
+          }\r
+          LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: congestion avoidance cwnd %u\n", pcb->cwnd));\r
+        }\r
+      }\r
+      LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: ACK for %lu, unacked->seqno %lu:%lu\n",\r
+                                    ackno,\r
+                                    pcb->unacked != NULL?\r
+                                    ntohl(pcb->unacked->tcphdr->seqno): 0,\r
+                                    pcb->unacked != NULL?\r
+                                    ntohl(pcb->unacked->tcphdr->seqno) + TCP_TCPLEN(pcb->unacked): 0));\r
+\r
+      /* Remove segment from the unacknowledged list if the incoming\r
+         ACK acknowlegdes them. */\r
+      while (pcb->unacked != NULL &&\r
+             TCP_SEQ_LEQ(ntohl(pcb->unacked->tcphdr->seqno) +\r
+                         TCP_TCPLEN(pcb->unacked), ackno)) {\r
+        LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %lu:%lu from pcb->unacked\n",\r
+                                      ntohl(pcb->unacked->tcphdr->seqno),\r
+                                      ntohl(pcb->unacked->tcphdr->seqno) +\r
+                                      TCP_TCPLEN(pcb->unacked)));\r
+\r
+        next = pcb->unacked;\r
+        pcb->unacked = pcb->unacked->next;\r
+\r
+        LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %u ... ", (unsigned int)pcb->snd_queuelen));\r
+        pcb->snd_queuelen -= pbuf_clen(next->p);\r
+        tcp_seg_free(next);\r
+\r
+        LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%u (after freeing unacked)\n", (unsigned int)pcb->snd_queuelen));\r
+        if (pcb->snd_queuelen != 0) {\r
+          LWIP_ASSERT("tcp_receive: valid queue length", pcb->unacked != NULL ||\r
+                      pcb->unsent != NULL);\r
+        }\r
+      }\r
+      pcb->polltmr = 0;\r
+    }\r
+\r
+    /* We go through the ->unsent list to see if any of the segments\r
+       on the list are acknowledged by the ACK. This may seem\r
+       strange since an "unsent" segment shouldn't be acked. The\r
+       rationale is that lwIP puts all outstanding segments on the\r
+       ->unsent list after a retransmission, so these segments may\r
+       in fact have been sent once. */\r
+    while (pcb->unsent != NULL &&\r
+           /*TCP_SEQ_LEQ(ntohl(pcb->unsent->tcphdr->seqno) + TCP_TCPLEN(pcb->unsent), ackno) &&\r
+             TCP_SEQ_LEQ(ackno, pcb->snd_max)*/\r
+           TCP_SEQ_BETWEEN(ackno, ntohl(pcb->unsent->tcphdr->seqno) + TCP_TCPLEN(pcb->unsent), pcb->snd_max)\r
+           ) {\r
+      LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %lu:%lu from pcb->unsent\n",\r
+                                    ntohl(pcb->unsent->tcphdr->seqno), ntohl(pcb->unsent->tcphdr->seqno) +\r
+                                    TCP_TCPLEN(pcb->unsent)));\r
+\r
+      next = pcb->unsent;\r
+      pcb->unsent = pcb->unsent->next;\r
+      LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %u ... ", (unsigned int)pcb->snd_queuelen));\r
+      pcb->snd_queuelen -= pbuf_clen(next->p);\r
+      tcp_seg_free(next);\r
+      LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%u (after freeing unsent)\n", (unsigned int)pcb->snd_queuelen));\r
+      if (pcb->snd_queuelen != 0) {\r
+        LWIP_ASSERT("tcp_receive: valid queue length",\r
+          pcb->unacked != NULL || pcb->unsent != NULL);\r
+      }\r
+\r
+      if (pcb->unsent != NULL) {\r
+        pcb->snd_nxt = htonl(pcb->unsent->tcphdr->seqno);\r
+      }\r
+    }\r
+    /* End of ACK for new data processing. */\r
+\r
+    LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: pcb->rttest %u rtseq %lu ackno %lu\n",\r
+                                pcb->rttest, pcb->rtseq, ackno));\r
+\r
+    /* RTT estimation calculations. This is done by checking if the\r
+       incoming segment acknowledges the segment we use to take a\r
+       round-trip time measurement. */\r
+    if (pcb->rttest && TCP_SEQ_LT(pcb->rtseq, ackno)) {\r
+      m = tcp_ticks - pcb->rttest;\r
+\r
+      LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: experienced rtt %u ticks (%u msec).\n",\r
+                                  m, m * TCP_SLOW_INTERVAL));\r
+\r
+      /* This is taken directly from VJs original code in his paper */\r
+      m = m - (pcb->sa >> 3);\r
+      pcb->sa += m;\r
+      if (m < 0) {\r
+        m = -m;\r
+      }\r
+      m = m - (pcb->sv >> 2);\r
+      pcb->sv += m;\r
+      pcb->rto = (pcb->sa >> 3) + pcb->sv;\r
+\r
+      LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: RTO %u (%u miliseconds)\n",\r
+                                  pcb->rto, pcb->rto * TCP_SLOW_INTERVAL));\r
+\r
+      pcb->rttest = 0;\r
+    }\r
+  }\r
+\r
+  /* If the incoming segment contains data, we must process it\r
+     further. */\r
+  if (tcplen > 0) {\r
+    /* This code basically does three things:\r
+\r
+    +) If the incoming segment contains data that is the next\r
+    in-sequence data, this data is passed to the application. This\r
+    might involve trimming the first edge of the data. The rcv_nxt\r
+    variable and the advertised window are adjusted.\r
+\r
+    +) If the incoming segment has data that is above the next\r
+    sequence number expected (->rcv_nxt), the segment is placed on\r
+    the ->ooseq queue. This is done by finding the appropriate\r
+    place in the ->ooseq queue (which is ordered by sequence\r
+    number) and trim the segment in both ends if needed. An\r
+    immediate ACK is sent to indicate that we received an\r
+    out-of-sequence segment.\r
+\r
+    +) Finally, we check if the first segment on the ->ooseq queue\r
+    now is in sequence (i.e., if rcv_nxt >= ooseq->seqno). If\r
+    rcv_nxt > ooseq->seqno, we must trim the first edge of the\r
+    segment on ->ooseq before we adjust rcv_nxt. The data in the\r
+    segments that are now on sequence are chained onto the\r
+    incoming segment so that we only need to call the application\r
+    once.\r
+    */\r
+\r
+    /* First, we check if we must trim the first edge. We have to do\r
+       this if the sequence number of the incoming segment is less\r
+       than rcv_nxt, and the sequence number plus the length of the\r
+       segment is larger than rcv_nxt. */\r
+    /*    if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)){\r
+          if (TCP_SEQ_LT(pcb->rcv_nxt, seqno + tcplen)) {*/\r
+    if(TCP_SEQ_BETWEEN(pcb->rcv_nxt, seqno+1, seqno+tcplen-1)){\r
+      /* Trimming the first edge is done by pushing the payload\r
+         pointer in the pbuf downwards. This is somewhat tricky since\r
+         we do not want to discard the full contents of the pbuf up to\r
+         the new starting point of the data since we have to keep the\r
+         TCP header which is present in the first pbuf in the chain.\r
+         \r
+         What is done is really quite a nasty hack: the first pbuf in\r
+         the pbuf chain is pointed to by inseg.p. Since we need to be\r
+         able to deallocate the whole pbuf, we cannot change this\r
+         inseg.p pointer to point to any of the later pbufs in the\r
+         chain. Instead, we point the ->payload pointer in the first\r
+         pbuf to data in one of the later pbufs. We also set the\r
+         inseg.data pointer to point to the right place. This way, the\r
+         ->p pointer will still point to the first pbuf, but the\r
+         ->p->payload pointer will point to data in another pbuf.\r
+         \r
+         After we are done with adjusting the pbuf pointers we must\r
+         adjust the ->data pointer in the seg and the segment\r
+         length.*/\r
+      \r
+      off = pcb->rcv_nxt - seqno;\r
+      p = inseg.p;\r
+      if (inseg.p->len < off) {\r
+        new_tot_len = inseg.p->tot_len - off;\r
+        while (p->len < off) {\r
+          off -= p->len;\r
+          /* KJM following line changed (with addition of new_tot_len var)\r
+             to fix bug #9076\r
+             inseg.p->tot_len -= p->len; */\r
+          p->tot_len = new_tot_len;\r
+          p->len = 0;\r
+          p = p->next;\r
+        }\r
+        pbuf_header(p, -off);\r
+      } else {\r
+        pbuf_header(inseg.p, -off);\r
+      }\r
+      /* KJM following line changed to use p->payload rather than inseg->p->payload\r
+         to fix bug #9076 */\r
+      inseg.dataptr = p->payload;\r
+      inseg.len -= pcb->rcv_nxt - seqno;\r
+      inseg.tcphdr->seqno = seqno = pcb->rcv_nxt;\r
+    }\r
+    else{\r
+      if(TCP_SEQ_LT(seqno, pcb->rcv_nxt)){\r
+        /* the whole segment is < rcv_nxt */\r
+        /* must be a duplicate of a packet that has already been correctly handled */\r
+        \r
+        LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: duplicate seqno %lu\n", seqno));\r
+        tcp_ack_now(pcb);\r
+      }\r
+    }\r
+\r
+    /* The sequence number must be within the window (above rcv_nxt\r
+       and below rcv_nxt + rcv_wnd) in order to be further\r
+       processed. */\r
+    /*if (TCP_SEQ_GEQ(seqno, pcb->rcv_nxt) &&\r
+      TCP_SEQ_LT(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {*/\r
+    if(TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt + pcb->rcv_wnd - 1)){\r
+      if (pcb->rcv_nxt == seqno) {\r
+        /* The incoming segment is the next in sequence. We check if\r
+           we have to trim the end of the segment and update rcv_nxt\r
+           and pass the data to the application. */\r
+#if TCP_QUEUE_OOSEQ\r
+        if (pcb->ooseq != NULL &&\r
+            TCP_SEQ_LEQ(pcb->ooseq->tcphdr->seqno, seqno + inseg.len)) {\r
+          /* We have to trim the second edge of the incoming\r
+             segment. */\r
+          inseg.len = pcb->ooseq->tcphdr->seqno - seqno;\r
+          pbuf_realloc(inseg.p, inseg.len);\r
+        }\r
+#endif /* TCP_QUEUE_OOSEQ */\r
+\r
+        tcplen = TCP_TCPLEN(&inseg);\r
+\r
+        pcb->rcv_nxt += tcplen;\r
+\r
+        /* Update the receiver's (our) window. */\r
+        if (pcb->rcv_wnd < tcplen) {\r
+          pcb->rcv_wnd = 0;\r
+        } else {\r
+          pcb->rcv_wnd -= tcplen;\r
+        }\r
+\r
+        /* If there is data in the segment, we make preparations to\r
+           pass this up to the application. The ->recv_data variable\r
+           is used for holding the pbuf that goes to the\r
+           application. The code for reassembling out-of-sequence data\r
+           chains its data on this pbuf as well.\r
+\r
+           If the segment was a FIN, we set the TF_GOT_FIN flag that will\r
+           be used to indicate to the application that the remote side has\r
+           closed its end of the connection. */\r
+        if (inseg.p->tot_len > 0) {\r
+          recv_data = inseg.p;\r
+          /* Since this pbuf now is the responsibility of the\r
+             application, we delete our reference to it so that we won't\r
+             (mistakingly) deallocate it. */\r
+          inseg.p = NULL;\r
+        }\r
+        if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) {\r
+          LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: received FIN.\n"));\r
+          recv_flags = TF_GOT_FIN;\r
+        }\r
+\r
+#if TCP_QUEUE_OOSEQ\r
+        /* We now check if we have segments on the ->ooseq queue that\r
+           is now in sequence. */\r
+        while (pcb->ooseq != NULL &&\r
+               pcb->ooseq->tcphdr->seqno == pcb->rcv_nxt) {\r
+\r
+          cseg = pcb->ooseq;\r
+          seqno = pcb->ooseq->tcphdr->seqno;\r
+\r
+          pcb->rcv_nxt += TCP_TCPLEN(cseg);\r
+          if (pcb->rcv_wnd < TCP_TCPLEN(cseg)) {\r
+            pcb->rcv_wnd = 0;\r
+          } else {\r
+            pcb->rcv_wnd -= TCP_TCPLEN(cseg);\r
+          }\r
+          if (cseg->p->tot_len > 0) {\r
+            /* Chain this pbuf onto the pbuf that we will pass to\r
+               the application. */\r
+            if (recv_data) {\r
+              pbuf_cat(recv_data, cseg->p);\r
+            } else {\r
+              recv_data = cseg->p;\r
+            }\r
+            cseg->p = NULL;\r
+          }\r
+          if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) {\r
+            LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: dequeued FIN.\n"));\r
+            recv_flags = TF_GOT_FIN;\r
+          }\r
+\r
+\r
+          pcb->ooseq = cseg->next;\r
+          tcp_seg_free(cseg);\r
+        }\r
+#endif /* TCP_QUEUE_OOSEQ */\r
+\r
+\r
+        /* Acknowledge the segment(s). */\r
+        tcp_ack(pcb);\r
+\r
+      } else {\r
+        /* We get here if the incoming segment is out-of-sequence. */\r
+        tcp_ack_now(pcb);\r
+#if TCP_QUEUE_OOSEQ\r
+        /* We queue the segment on the ->ooseq queue. */\r
+        if (pcb->ooseq == NULL) {\r
+          pcb->ooseq = tcp_seg_copy(&inseg);\r
+        } else {\r
+          /* If the queue is not empty, we walk through the queue and\r
+             try to find a place where the sequence number of the\r
+             incoming segment is between the sequence numbers of the\r
+             previous and the next segment on the ->ooseq queue. That is\r
+             the place where we put the incoming segment. If needed, we\r
+             trim the second edges of the previous and the incoming\r
+             segment so that it will fit into the sequence.\r
+\r
+             If the incoming segment has the same sequence number as a\r
+             segment on the ->ooseq queue, we discard the segment that\r
+             contains less data. */\r
+\r
+          prev = NULL;\r
+          for(next = pcb->ooseq; next != NULL; next = next->next) {\r
+            if (seqno == next->tcphdr->seqno) {\r
+              /* The sequence number of the incoming segment is the\r
+                 same as the sequence number of the segment on\r
+                 ->ooseq. We check the lengths to see which one to\r
+                 discard. */\r
+              if (inseg.len > next->len) {\r
+                /* The incoming segment is larger than the old\r
+                   segment. We replace the old segment with the new\r
+                   one. */\r
+                cseg = tcp_seg_copy(&inseg);\r
+                if (cseg != NULL) {\r
+                  cseg->next = next->next;\r
+                  if (prev != NULL) {\r
+                    prev->next = cseg;\r
+                  } else {\r
+                    pcb->ooseq = cseg;\r
+                  }\r
+                }\r
+                break;\r
+              } else {\r
+                /* Either the lenghts are the same or the incoming\r
+                   segment was smaller than the old one; in either\r
+                   case, we ditch the incoming segment. */\r
+                break;\r
+              }\r
+            } else {\r
+              if (prev == NULL) {\r
+                if (TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {\r
+                  /* The sequence number of the incoming segment is lower\r
+                     than the sequence number of the first segment on the\r
+                     queue. We put the incoming segment first on the\r
+                     queue. */\r
+\r
+                  if (TCP_SEQ_GT(seqno + inseg.len, next->tcphdr->seqno)) {\r
+                    /* We need to trim the incoming segment. */\r
+                    inseg.len = next->tcphdr->seqno - seqno;\r
+                    pbuf_realloc(inseg.p, inseg.len);\r
+                  }\r
+                  cseg = tcp_seg_copy(&inseg);\r
+                  if (cseg != NULL) {\r
+                    cseg->next = next;\r
+                    pcb->ooseq = cseg;\r
+                  }\r
+                  break;\r
+                }\r
+              } else \r
+                /*if (TCP_SEQ_LT(prev->tcphdr->seqno, seqno) &&\r
+                  TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {*/\r
+                if(TCP_SEQ_BETWEEN(seqno, prev->tcphdr->seqno+1, next->tcphdr->seqno-1)){\r
+                /* The sequence number of the incoming segment is in\r
+                   between the sequence numbers of the previous and\r
+                   the next segment on ->ooseq. We trim and insert the\r
+                   incoming segment and trim the previous segment, if\r
+                   needed. */\r
+                if (TCP_SEQ_GT(seqno + inseg.len, next->tcphdr->seqno)) {\r
+                  /* We need to trim the incoming segment. */\r
+                  inseg.len = next->tcphdr->seqno - seqno;\r
+                  pbuf_realloc(inseg.p, inseg.len);\r
+                }\r
+\r
+                cseg = tcp_seg_copy(&inseg);\r
+                if (cseg != NULL) {\r
+                  cseg->next = next;\r
+                  prev->next = cseg;\r
+                  if (TCP_SEQ_GT(prev->tcphdr->seqno + prev->len, seqno)) {\r
+                    /* We need to trim the prev segment. */\r
+                    prev->len = seqno - prev->tcphdr->seqno;\r
+                    pbuf_realloc(prev->p, prev->len);\r
+                  }\r
+                }\r
+                break;\r
+              }\r
+              /* If the "next" segment is the last segment on the\r
+                 ooseq queue, we add the incoming segment to the end\r
+                 of the list. */\r
+              if (next->next == NULL &&\r
+                  TCP_SEQ_GT(seqno, next->tcphdr->seqno)) {\r
+                next->next = tcp_seg_copy(&inseg);\r
+                if (next->next != NULL) {\r
+                  if (TCP_SEQ_GT(next->tcphdr->seqno + next->len, seqno)) {\r
+                    /* We need to trim the last segment. */\r
+                    next->len = seqno - next->tcphdr->seqno;\r
+                    pbuf_realloc(next->p, next->len);\r
+                  }\r
+                }\r
+                break;\r
+              }\r
+            }\r
+            prev = next;\r
+          }\r
+        }\r
+#endif /* TCP_QUEUE_OOSEQ */\r
+\r
+      }\r
+    } else {\r
+      /*if (TCP_SEQ_GT(pcb->rcv_nxt, seqno) ||\r
+        TCP_SEQ_GEQ(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {*/\r
+      if(!TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt + pcb->rcv_wnd-1)){\r
+        tcp_ack_now(pcb);\r
+      }\r
+    }\r
+  } else {\r
+    /* Segments with length 0 is taken care of here. Segments that\r
+       fall out of the window are ACKed. */\r
+    /*if (TCP_SEQ_GT(pcb->rcv_nxt, seqno) ||\r
+      TCP_SEQ_GEQ(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {*/\r
+    if(!TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt + pcb->rcv_wnd-1)){\r
+      tcp_ack_now(pcb);\r
+    }\r
+  }\r
+}\r
+\r
+/*\r
+ * tcp_parseopt:\r
+ *\r
+ * Parses the options contained in the incoming segment. (Code taken\r
+ * from uIP with only small changes.)\r
+ *\r
+ */\r
+\r
+static void\r
+tcp_parseopt(struct tcp_pcb *pcb)\r
+{\r
+  u8_t c;\r
+  u8_t *opts, opt;\r
+  u16_t mss;\r
+\r
+  opts = (u8_t *)tcphdr + TCP_HLEN;\r
+\r
+  /* Parse the TCP MSS option, if present. */\r
+  if(TCPH_HDRLEN(tcphdr) > 0x5) {\r
+    for(c = 0; c < (TCPH_HDRLEN(tcphdr) - 5) << 2 ;) {\r
+      opt = opts[c];\r
+      if (opt == 0x00) {\r
+        /* End of options. */\r
+  break;\r
+      } else if (opt == 0x01) {\r
+        ++c;\r
+        /* NOP option. */\r
+      } else if (opt == 0x02 &&\r
+        opts[c + 1] == 0x04) {\r
+        /* An MSS option with the right option length. */\r
+        mss = (opts[c + 2] << 8) | opts[c + 3];\r
+        pcb->mss = mss > TCP_MSS? TCP_MSS: mss;\r
+\r
+        /* And we are done processing options. */\r
+        break;\r
+      } else {\r
+  if (opts[c + 1] == 0) {\r
+          /* If the length field is zero, the options are malformed\r
+             and we don't process them further. */\r
+          break;\r
+        }\r
+        /* All other options have a length field, so that we easily\r
+           can skip past them. */\r
+        c += opts[c + 1];\r
+      }\r
+    }\r
+  }\r
+}\r
+#endif /* LWIP_TCP */\r
+\r
+\r
index 8343d34dcc196534f4e3e29da19be8e46ae09487..8bea4ed5eaf0f2b14eceefabc8b5b666fe81160a 100644 (file)
-/**
- * @file
- * User Datagram Protocol module
- *
- */
-/*
- * 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 <adam@sics.se>
- *
- */
-
-
-/* udp.c
- *
- * The code for the User Datagram Protocol UDP.
- *
- */
-
-#include <string.h>
-
-#include "lwip/opt.h"
-
-#include "lwip/def.h"
-#include "lwip/memp.h"
-#include "lwip/inet.h"
-#include "lwip/ip_addr.h"
-#include "lwip/netif.h"
-#include "lwip/udp.h"
-#include "lwip/icmp.h"
-
-#include "lwip/stats.h"
-
-#include "arch/perf.h"
-#include "lwip/snmp.h"
-
-/* The list of UDP PCBs */
-#if LWIP_UDP
-/* was static, but we may want to access this from a socket layer */
-struct udp_pcb *udp_pcbs = NULL;
-
-static struct udp_pcb *pcb_cache = NULL;
-
-
-void
-udp_init(void)
-{
-  udp_pcbs = pcb_cache = NULL;
-}
-
-/**
- * Process an incoming UDP datagram.
- *
- * Given an incoming UDP datagram (as a chain of pbufs) this function
- * finds a corresponding UDP PCB and
- *
- * @param pbuf pbuf to be demultiplexed to a UDP PCB.
- * @param netif network interface on which the datagram was received.
- *
- */
-void
-udp_input(struct pbuf *p, struct netif *inp)
-{
-  struct udp_hdr *udphdr;
-  struct udp_pcb *pcb;
-  struct ip_hdr *iphdr;
-  u16_t src, dest;
-
-#if SO_REUSE
-  struct udp_pcb *pcb_temp;
-  int reuse = 0;
-  int reuse_port_1 = 0;
-  int reuse_port_2 = 0;
-#endif /* SO_REUSE */
-  
-  PERF_START;
-
-  UDP_STATS_INC(udp.recv);
-
-  iphdr = p->payload;
-
-  if (pbuf_header(p, -((s16_t)(UDP_HLEN + IPH_HL(iphdr) * 4)))) {
-    /* drop short packets */
-    LWIP_DEBUGF(UDP_DEBUG, ("udp_input: short UDP datagram (%u bytes) discarded\n", p->tot_len));
-    UDP_STATS_INC(udp.lenerr);
-    UDP_STATS_INC(udp.drop);
-    snmp_inc_udpinerrors();
-    pbuf_free(p);
-    goto end;
-  }
-
-  udphdr = (struct udp_hdr *)((u8_t *)p->payload - UDP_HLEN);
-
-  LWIP_DEBUGF(UDP_DEBUG, ("udp_input: received datagram of length %u\n", p->tot_len));
-
-  src = ntohs(udphdr->src);
-  dest = ntohs(udphdr->dest);
-
-  udp_debug_print(udphdr);
-
-  /* print the UDP source and destination */
-  LWIP_DEBUGF(UDP_DEBUG, ("udp (%u.%u.%u.%u, %u) <-- (%u.%u.%u.%u, %u)\n",
-    ip4_addr1(&iphdr->dest), ip4_addr2(&iphdr->dest),
-    ip4_addr3(&iphdr->dest), ip4_addr4(&iphdr->dest), ntohs(udphdr->dest),
-    ip4_addr1(&iphdr->src), ip4_addr2(&iphdr->src),
-    ip4_addr3(&iphdr->src), ip4_addr4(&iphdr->src), ntohs(udphdr->src)));
-
-#if SO_REUSE
-  pcb_temp = udp_pcbs;
-  
- again_1:
-  
-  /* Iterate through the UDP pcb list for a fully matching pcb */
-  for (pcb = pcb_temp; pcb != NULL; pcb = pcb->next) {
-#else  /* SO_REUSE */ 
-  /* Iterate through the UDP pcb list for a fully matching pcb */
-  for (pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) {
-#endif  /* SO_REUSE */ 
-    /* print the PCB local and remote address */
-    LWIP_DEBUGF(UDP_DEBUG, ("pcb (%u.%u.%u.%u, %u) --- (%u.%u.%u.%u, %u)\n",
-      ip4_addr1(&pcb->local_ip), ip4_addr2(&pcb->local_ip),
-      ip4_addr3(&pcb->local_ip), ip4_addr4(&pcb->local_ip), pcb->local_port,
-      ip4_addr1(&pcb->remote_ip), ip4_addr2(&pcb->remote_ip),
-      ip4_addr3(&pcb->remote_ip), ip4_addr4(&pcb->remote_ip), pcb->remote_port));
-
-       /* PCB remote port matches UDP source port? */
-    if ((pcb->remote_port == src) &&
-       /* PCB local port matches UDP destination port? */
-       (pcb->local_port == dest) &&
-       /* accepting from any remote (source) IP address? or... */
-       (ip_addr_isany(&pcb->remote_ip) ||
-       /* PCB remote IP address matches UDP source IP address? */
-        ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src))) &&
-       /* accepting on any local (netif) IP address? or... */
-       (ip_addr_isany(&pcb->local_ip) ||
-       /* PCB local IP address matches UDP destination IP address? */
-        ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest)))) {
-#if SO_REUSE
-      if (pcb->so_options & SOF_REUSEPORT) {
-        if(reuse) {
-          /* We processed one PCB already */
-          LWIP_DEBUGF(UDP_DEBUG, ("udp_input: second or later PCB and SOF_REUSEPORT set.\n"));
-        } else {
-          /* First PCB with this address */
-          LWIP_DEBUGF(UDP_DEBUG, ("udp_input: first PCB and SOF_REUSEPORT set.\n"));
-          reuse = 1;
-        }
-        
-        reuse_port_1 = 1; 
-        p->ref++;
-        LWIP_DEBUGF(UDP_DEBUG, ("udp_input: reference counter on PBUF set to %i\n", p->ref));
-      } else {
-        if (reuse) {
-          /* We processed one PCB already */
-          LWIP_DEBUGF(UDP_DEBUG, ("udp_input: second or later PCB but SOF_REUSEPORT not set !\n"));
-        }
-      }
-#endif /* SO_REUSE */
-      break;
-    }
-  }
-  /* no fully matching pcb found? then look for an unconnected pcb */
-  if (pcb == NULL) {
-    /* Iterate through the UDP PCB list for a pcb that matches
-       the local address. */
-
-#if SO_REUSE
-    pcb_temp = udp_pcbs;
-    
-  again_2:
-
-    for (pcb = pcb_temp; pcb != NULL; pcb = pcb->next) {
-#else  /* SO_REUSE */ 
-    for (pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) {
-#endif  /* SO_REUSE */ 
-      LWIP_DEBUGF(UDP_DEBUG, ("pcb (%u.%u.%u.%u, %u) --- (%u.%u.%u.%u, %u)\n",
-        ip4_addr1(&pcb->local_ip), ip4_addr2(&pcb->local_ip),
-        ip4_addr3(&pcb->local_ip), ip4_addr4(&pcb->local_ip), pcb->local_port,
-        ip4_addr1(&pcb->remote_ip), ip4_addr2(&pcb->remote_ip),
-        ip4_addr3(&pcb->remote_ip), ip4_addr4(&pcb->remote_ip), pcb->remote_port));
-      /* unconnected? */
-      if (((pcb->flags & UDP_FLAGS_CONNECTED) == 0) &&
-         /* destination port matches? */
-        (pcb->local_port == dest) &&
-        /* not bound to a specific (local) interface address? or... */
-        (ip_addr_isany(&pcb->local_ip) ||
-        /* ...matching interface address? */
-        ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest)))) {
-#if SO_REUSE
-        if (pcb->so_options & SOF_REUSEPORT) {
-          if (reuse) {
-            /* We processed one PCB already */
-            LWIP_DEBUGF(UDP_DEBUG, ("udp_input: second or later PCB and SOF_REUSEPORT set.\n"));
-          } else {
-            /* First PCB with this address */
-            LWIP_DEBUGF(UDP_DEBUG, ("udp_input: first PCB and SOF_REUSEPORT set.\n"));
-            reuse = 1;
-          }
-          
-          reuse_port_2 = 1; 
-          p->ref++;
-          LWIP_DEBUGF(UDP_DEBUG, ("udp_input: reference counter on PBUF set to %i\n", p->ref));
-        } else {
-          if (reuse) {
-            /* We processed one PCB already */
-            LWIP_DEBUGF(UDP_DEBUG, ("udp_input: second or later PCB but SOF_REUSEPORT not set !\n"));
-          }
-        }
-#endif /* SO_REUSE */
-        break;
-      }
-    }
-  }
-
-  /* Check checksum if this is a match or if it was directed at us. */
-  if (pcb != NULL  || ip_addr_cmp(&inp->ip_addr, &iphdr->dest))
-    {
-    LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE, ("udp_input: calculating checksum\n"));
-    pbuf_header(p, UDP_HLEN);
-#ifdef IPv6
-    if (iphdr->nexthdr == IP_PROTO_UDPLITE) {
-#else
-    if (IPH_PROTO(iphdr) == IP_PROTO_UDPLITE) {
-#endif /* IPv4 */
-      /* Do the UDP Lite checksum */
-#if CHECKSUM_CHECK_UDP
-      if (inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src),
-         (struct ip_addr *)&(iphdr->dest),
-         IP_PROTO_UDPLITE, ntohs(udphdr->len)) != 0) {
-  LWIP_DEBUGF(UDP_DEBUG | 2, ("udp_input: UDP Lite datagram discarded due to failing checksum\n"));
-  UDP_STATS_INC(udp.chkerr);
-  UDP_STATS_INC(udp.drop);
-  snmp_inc_udpinerrors();
-  pbuf_free(p);
-  goto end;
-      }
-#endif
-    } else {
-#if CHECKSUM_CHECK_UDP
-      if (udphdr->chksum != 0) {
-  if (inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src),
-       (struct ip_addr *)&(iphdr->dest),
-        IP_PROTO_UDP, p->tot_len) != 0) {
-    LWIP_DEBUGF(UDP_DEBUG | 2, ("udp_input: UDP datagram discarded due to failing checksum\n"));
-
-    UDP_STATS_INC(udp.chkerr);
-    UDP_STATS_INC(udp.drop);
-    snmp_inc_udpinerrors();
-    pbuf_free(p);
-    goto end;
-  }
-      }
-#endif
-    }
-    pbuf_header(p, -UDP_HLEN);
-    if (pcb != NULL) {
-      snmp_inc_udpindatagrams();
-      pcb->recv(pcb->recv_arg, pcb, p, &(iphdr->src), src);
-#if SO_REUSE
-      /* First socket should receive now */
-      if(reuse_port_1 || reuse_port_2) {
-        /* We want to search on next socket after receiving */
-        pcb_temp = pcb->next;
-        
-        if(reuse_port_1) {
-          /* We are searching connected sockets */
-          reuse_port_1 = 0;
-          reuse_port_2 = 0;
-          goto again_1;
-        } else {
-          /* We are searching unconnected sockets */
-          reuse_port_1 = 0;
-          reuse_port_2 = 0;
-          goto again_2;
-        }
-      }
-#endif /* SO_REUSE */ 
-    } else {
-#if SO_REUSE
-      if(reuse) {
-        LWIP_DEBUGF(UDP_DEBUG, ("udp_input: freeing PBUF with reference counter set to %i\n", p->ref));
-        pbuf_free(p);
-        goto end;
-      }
-#endif /* SO_REUSE */
-      LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE, ("udp_input: not for us.\n"));
-
-      /* No match was found, send ICMP destination port unreachable unless
-      destination address was broadcast/multicast. */
-
-      if (!ip_addr_isbroadcast(&iphdr->dest, inp) &&
-          !ip_addr_ismulticast(&iphdr->dest)) {
-
-  /* adjust pbuf pointer */
-  p->payload = iphdr;
-  icmp_dest_unreach(p, ICMP_DUR_PORT);
-      }
-      UDP_STATS_INC(udp.proterr);
-      UDP_STATS_INC(udp.drop);
-    snmp_inc_udpnoports();
-      pbuf_free(p);
-    }
-  } else {
-    pbuf_free(p);
-  }
-  end:
-
-  PERF_STOP("udp_input");
-}
-
-/**
- * Send data to a specified address using UDP.
- *
- * @param pcb UDP PCB used to send the data.
- * @param pbuf chain of pbuf's to be sent.
- * @param dst_ip Destination IP address.
- * @param dst_port Destination UDP port.
- *
- * If the PCB already has a remote address association, it will
- * be restored after the data is sent.
- * 
- * @return lwIP error code.
- * - ERR_OK. Successful. No error occured.
- * - ERR_MEM. Out of memory.
- * - ERR_RTE. Could not find route to destination address.
- *
- * @see udp_disconnect() udp_send()
- */
-err_t
-udp_sendto(struct udp_pcb *pcb, struct pbuf *p,
-  struct ip_addr *dst_ip, u16_t dst_port)
-{
-  err_t err;
-  /* temporary space for current PCB remote address */
-  struct ip_addr pcb_remote_ip;
-  u16_t pcb_remote_port;
-  /* remember current remote peer address of PCB */
-  pcb_remote_ip.addr = pcb->remote_ip.addr;
-  pcb_remote_port = pcb->remote_port;
-  /* copy packet destination address to PCB remote peer address */
-  pcb->remote_ip.addr = dst_ip->addr;
-  pcb->remote_port = dst_port;
-  /* send to the packet destination address */
-  err = udp_send(pcb, p);
-  /* restore PCB remote peer address */
-  pcb->remote_ip.addr = pcb_remote_ip.addr;
-  pcb->remote_port = pcb_remote_port;
-  return err;
-}
-
-/**
- * Send data using UDP.
- *
- * @param pcb UDP PCB used to send the data.
- * @param pbuf chain of pbuf's to be sent.
- *
- * @return lwIP error code.
- * - ERR_OK. Successful. No error occured.
- * - ERR_MEM. Out of memory.
- * - ERR_RTE. Could not find route to destination address.
- *
- * @see udp_disconnect() udp_sendto()
- */
-err_t
-udp_send(struct udp_pcb *pcb, struct pbuf *p)
-{
-  struct udp_hdr *udphdr;
-  struct netif *netif;
-  struct ip_addr *src_ip;
-  err_t err;
-  struct pbuf *q; /* q will be sent down the stack */
-
-  LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | 3, ("udp_send\n"));
-
-  /* if the PCB is not yet bound to a port, bind it here */
-  if (pcb->local_port == 0) {
-    LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | 2, ("udp_send: not yet bound to a port, binding now\n"));
-    err = udp_bind(pcb, &pcb->local_ip, pcb->local_port);
-    if (err != ERR_OK) {
-      LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | 2, ("udp_send: forced port bind failed\n"));
-      return err;
-    }
-  }
-
-  /* not enough space to add an UDP header to first pbuf in given p chain? */
-  if (pbuf_header(p, UDP_HLEN)) {
-    /* allocate header in a seperate new pbuf */
-    q = pbuf_alloc(PBUF_IP, UDP_HLEN, PBUF_RAM);
-    /* new header pbuf could not be allocated? */
-    if (q == NULL) {
-      LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | 2, ("udp_send: could not allocate header\n"));
-      return ERR_MEM;
-    }
-    /* chain header q in front of given pbuf p */
-    pbuf_chain(q, p);
-    /* { first pbuf q points to header pbuf } */
-    LWIP_DEBUGF(UDP_DEBUG, ("udp_send: added header pbuf %p before given pbuf %p\n", (void *)q, (void *)p));
-  /* adding a header within p succeeded */
-  } else {
-    /* first pbuf q equals given pbuf */
-    q = p;
-    LWIP_DEBUGF(UDP_DEBUG, ("udp_send: added header in given pbuf %p\n", (void *)p));
-  }
-  /* { q now represents the packet to be sent } */
-  udphdr = q->payload;
-  udphdr->src = htons(pcb->local_port);
-  udphdr->dest = htons(pcb->remote_port);
-  /* in UDP, 0 checksum means 'no checksum' */
-  udphdr->chksum = 0x0000; 
-
-  /* find the outgoing network interface for this packet */
-  netif = ip_route(&(pcb->remote_ip));
-  /* no outgoing network interface could be found? */
-  if (netif == NULL) {
-    LWIP_DEBUGF(UDP_DEBUG | 1, ("udp_send: No route to 0x%lx\n", pcb->remote_ip.addr));
-    UDP_STATS_INC(udp.rterr);
-    return ERR_RTE;
-  }
-  /* PCB local address is IP_ANY_ADDR? */
-  if (ip_addr_isany(&pcb->local_ip)) {
-    /* use outgoing network interface IP address as source address */
-    src_ip = &(netif->ip_addr);
-  } else {
-    /* use UDP PCB local IP address as source address */
-    src_ip = &(pcb->local_ip);
-  }
-
-  LWIP_DEBUGF(UDP_DEBUG, ("udp_send: sending datagram of length %u\n", q->tot_len));
-
-  /* UDP Lite protocol? */
-  if (pcb->flags & UDP_FLAGS_UDPLITE) {
-    LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP LITE packet length %u\n", q->tot_len));
-    /* set UDP message length in UDP header */
-    udphdr->len = htons(pcb->chksum_len);
-    /* calculate checksum */
-#if CHECKSUM_GEN_UDP
-    udphdr->chksum = inet_chksum_pseudo(q, src_ip, &(pcb->remote_ip),
-          IP_PROTO_UDP, pcb->chksum_len);
-    /* chksum zero must become 0xffff, as zero means 'no checksum' */
-    if (udphdr->chksum == 0x0000) udphdr->chksum = 0xffff;
-#else
-    udphdr->chksum = 0x0000;
-#endif
-    /* output to IP */
-    LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,IP_PROTO_UDPLITE,)\n"));
-    err = ip_output_if (q, src_ip, &pcb->remote_ip, pcb->ttl, pcb->tos, IP_PROTO_UDPLITE, netif);    
-  /* UDP */
-  } else {
-    LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP packet length %u\n", q->tot_len));
-    udphdr->len = htons(q->tot_len);
-    /* calculate checksum */
-#if CHECKSUM_GEN_UDP
-    if ((pcb->flags & UDP_FLAGS_NOCHKSUM) == 0) {
-      udphdr->chksum = inet_chksum_pseudo(q, src_ip, &pcb->remote_ip, IP_PROTO_UDP, q->tot_len);
-      /* chksum zero must become 0xffff, as zero means 'no checksum' */
-      if (udphdr->chksum == 0x0000) udphdr->chksum = 0xffff;
-    }
-#else
-    udphdr->chksum = 0x0000;
-#endif
-    LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP checksum 0x%04x\n", udphdr->chksum));
-    LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,IP_PROTO_UDP,)\n"));
-    /* output to IP */
-    err = ip_output_if(q, src_ip, &pcb->remote_ip, pcb->ttl, pcb->tos, IP_PROTO_UDP, netif);    
-  }
-  /* TODO: must this be increased even if error occured? */
-  snmp_inc_udpoutdatagrams();
-
-  /* did we chain a seperate header pbuf earlier? */
-  if (q != p) {
-    /* free the header pbuf */
-    pbuf_free(q); q = NULL;
-    /* { p is still referenced by the caller, and will live on } */
-  }
-
-  UDP_STATS_INC(udp.xmit);
-  return err;
-}
-
-/**
- * Bind an UDP PCB.
- *
- * @param pcb UDP PCB to be bound with a local address ipaddr and port.
- * @param ipaddr local IP address to bind with. Use IP_ADDR_ANY to
- * bind to all local interfaces.
- * @param port local UDP port to bind with.
- *
- * @return lwIP error code.
- * - ERR_OK. Successful. No error occured.
- * - ERR_USE. The specified ipaddr and port are already bound to by
- * another UDP PCB.
- *
- * @see udp_disconnect()
- */
-err_t
-udp_bind(struct udp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
-{
-  struct udp_pcb *ipcb;
-  u8_t rebind;
-#if SO_REUSE
-  int reuse_port_all_set = 1;
-#endif /* SO_REUSE */
-  LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | 3, ("udp_bind(ipaddr = "));
-  ip_addr_debug_print(UDP_DEBUG, ipaddr);
-  LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | 3, (", port = %u)\n", port));
-
-  rebind = 0;
-  /* Check for double bind and rebind of the same pcb */
-  for (ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) {
-    /* is this UDP PCB already on active list? */
-    if (pcb == ipcb) {
-      /* pcb may occur at most once in active list */
-      LWIP_ASSERT("rebind == 0", rebind == 0);
-      /* pcb already in list, just rebind */
-      rebind = 1;
-    }
-
-#if SO_REUSE == 0
-/* this code does not allow upper layer to share a UDP port for
-   listening to broadcast or multicast traffic (See SO_REUSE_ADDR and
-   SO_REUSE_PORT under *BSD). TODO: See where it fits instead, OR
-   combine with implementation of UDP PCB flags. Leon Woestenberg. */
-#ifdef LWIP_UDP_TODO
-    /* port matches that of PCB in list? */
-    else if ((ipcb->local_port == port) &&
-       /* IP address matches, or one is IP_ADDR_ANY? */
-       (ip_addr_isany(&(ipcb->local_ip)) ||
-       ip_addr_isany(ipaddr) ||
-       ip_addr_cmp(&(ipcb->local_ip), ipaddr))) {
-      /* other PCB already binds to this local IP and port */
-      LWIP_DEBUGF(UDP_DEBUG, ("udp_bind: local port %u already bound by another pcb\n", port));
-      return ERR_USE;
-    }
-#endif
-
-#else /* SO_REUSE */
-      /* Search through list of PCB's. 
-         
-      If there is a PCB bound to specified port and IP_ADDR_ANY another PCB can be bound to the interface IP
-      or to the loopback address on the same port if SOF_REUSEADDR is set. Any combination of PCB's bound to 
-      the same local port, but to one address out of {IP_ADDR_ANY, 127.0.0.1, interface IP} at a time is valid.
-      But no two PCB's bound to same local port and same local address is valid.
-      
-      If SOF_REUSEPORT is set several PCB's can be bound to same local port and same local address also. But then 
-      all PCB's must have the SOF_REUSEPORT option set.
-      
-      When the two options aren't set and specified port is already bound, ERR_USE is returned saying that 
-      address is already in use. */
-    else if (ipcb->local_port == port) {
-      if(ip_addr_cmp(&(ipcb->local_ip), ipaddr)) {
-        if(pcb->so_options & SOF_REUSEPORT) {
-          LWIP_DEBUGF(UDP_DEBUG, ("udp_bind: in UDP PCB's SO_REUSEPORT set and same address.\n"));
-          reuse_port_all_set = (reuse_port_all_set && (ipcb->so_options & SOF_REUSEPORT));
-        }
-        else {
-          LWIP_DEBUGF(UDP_DEBUG, ("udp_bind: in UDP PCB's SO_REUSEPORT not set and same address.\n"));
-          return ERR_USE;
-        }
-      }
-      else if((ip_addr_isany(ipaddr) && !ip_addr_isany(&(ipcb->local_ip))) ||
-              (!ip_addr_isany(ipaddr) && ip_addr_isany(&(ipcb->local_ip)))) {
-        if(!(pcb->so_options & SOF_REUSEADDR) && !(pcb->so_options & SOF_REUSEPORT)) {
-          LWIP_DEBUGF(UDP_DEBUG, ("udp_bind: in UDP PCB's SO_REUSEPORT or SO_REUSEADDR not set and not the same address.\n"));
-          return ERR_USE;
-        }           
-      }
-    }
-#endif /* SO_REUSE */
-
-  }
-
-#if SO_REUSE
-  /* If SOF_REUSEPORT isn't set in all PCB's bound to specified port and local address specified then 
-     {IP, port} can't be reused. */
-  if(!reuse_port_all_set) {
-    LWIP_DEBUGF(UDP_DEBUG, ("udp_bind: not all sockets have SO_REUSEPORT set.\n"));
-    return ERR_USE;
-  }
-#endif /* SO_REUSE */
-
-  ip_addr_set(&pcb->local_ip, ipaddr);
-  /* 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
-#endif
-    port = UDP_LOCAL_PORT_RANGE_START;
-    ipcb = udp_pcbs;
-    while ((ipcb != NULL) && (port != UDP_LOCAL_PORT_RANGE_END)) {
-      if (ipcb->local_port == port) {
-        port++;
-        ipcb = udp_pcbs;
-      } else
-        ipcb = ipcb->next;
-    }
-    if (ipcb != NULL) {
-      /* no more ports available in local range */
-      LWIP_DEBUGF(UDP_DEBUG, ("udp_bind: out of free UDP ports\n"));
-      return ERR_USE;
-    }
-  }
-  pcb->local_port = port;
-  /* pcb not active yet? */
-  if (rebind == 0) {
-    /* place the PCB on the active list if not already there */
-    pcb->next = udp_pcbs;
-    udp_pcbs = pcb;
-  }
-  LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | DBG_STATE, ("udp_bind: bound to %u.%u.%u.%u, port %u\n",
-   (unsigned int)(ntohl(pcb->local_ip.addr) >> 24 & 0xff),
-   (unsigned int)(ntohl(pcb->local_ip.addr) >> 16 & 0xff),
-   (unsigned int)(ntohl(pcb->local_ip.addr) >> 8 & 0xff),
-   (unsigned int)(ntohl(pcb->local_ip.addr) & 0xff), pcb->local_port));
-  return ERR_OK;
-}
-/**
- * Connect an UDP PCB.
- *
- * This will associate the UDP PCB with the remote address.
- *
- * @param pcb UDP PCB to be connected with remote address ipaddr and port.
- * @param ipaddr remote IP address to connect with.
- * @param port remote UDP port to connect with.
- *
- * @return lwIP error code
- *
- * @see udp_disconnect()
- */
-err_t
-udp_connect(struct udp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
-{
-  struct udp_pcb *ipcb;
-
-  if (pcb->local_port == 0) {
-    err_t err = udp_bind(pcb, &pcb->local_ip, pcb->local_port);
-    if (err != ERR_OK)
-      return err;
-  }
-
-  ip_addr_set(&pcb->remote_ip, ipaddr);
-  pcb->remote_port = port;
-  pcb->flags |= UDP_FLAGS_CONNECTED;
-/** TODO: this functionality belongs in upper layers */
-#ifdef LWIP_UDP_TODO
-  /* Nail down local IP for netconn_addr()/getsockname() */
-  if (ip_addr_isany(&pcb->local_ip) && !ip_addr_isany(&pcb->remote_ip)) {
-    struct netif *netif;
-
-    if ((netif = ip_route(&(pcb->remote_ip))) == NULL) {
-      LWIP_DEBUGF(UDP_DEBUG, ("udp_connect: No route to 0x%lx\n", pcb->remote_ip.addr));
-        UDP_STATS_INC(udp.rterr);
-      return ERR_RTE;
-    }
-    /** TODO: this will bind the udp pcb locally, to the interface which
-        is used to route output packets to the remote address. However, we
-        might want to accept incoming packets on any interface! */
-    pcb->local_ip = netif->ip_addr;
-  } else if (ip_addr_isany(&pcb->remote_ip)) {
-    pcb->local_ip.addr = 0;
-  }
-#endif
-  LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | DBG_STATE, ("udp_connect: connected to %u.%u.%u.%u, port %u\n",
-   (unsigned int)(ntohl(pcb->remote_ip.addr) >> 24 & 0xff),
-   (unsigned int)(ntohl(pcb->remote_ip.addr) >> 16 & 0xff),
-   (unsigned int)(ntohl(pcb->remote_ip.addr) >> 8 & 0xff),
-   (unsigned int)(ntohl(pcb->remote_ip.addr) & 0xff), pcb->remote_port));
-
-  /* Insert UDP PCB into the list of active UDP PCBs. */
-  for(ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) {
-    if (pcb == ipcb) {
-      /* already on the list, just return */
-      return ERR_OK;
-    }
-  }
-  /* PCB not yet on the list, add PCB now */
-  pcb->next = udp_pcbs;
-  udp_pcbs = pcb;
-  return ERR_OK;
-}
-
-void
-udp_disconnect(struct udp_pcb *pcb)
-{
-  /* reset remote address association */
-  ip_addr_set(&pcb->remote_ip, IP_ADDR_ANY);
-  pcb->remote_port = 0;
-  /* mark PCB as unconnected */
-  pcb->flags &= ~UDP_FLAGS_CONNECTED;
-}
-
-void
-udp_recv(struct udp_pcb *pcb,
-   void (* recv)(void *arg, struct udp_pcb *upcb, struct pbuf *p,
-           struct ip_addr *addr, u16_t port),
-   void *recv_arg)
-{
-  /* remember recv() callback and user data */
-  pcb->recv = recv;
-  pcb->recv_arg = recv_arg;
-}
-/**
- * Remove an UDP PCB.
- *
- * @param pcb UDP PCB to be removed. The PCB is removed from the list of
- * UDP PCB's and the data structure is freed from memory.
- *
- * @see udp_new()
- */
-void
-udp_remove(struct udp_pcb *pcb)
-{
-  struct udp_pcb *pcb2;
-  /* pcb to be removed is first in list? */
-  if (udp_pcbs == pcb) {
-    /* make list start at 2nd pcb */
-    udp_pcbs = udp_pcbs->next;
-  /* pcb not 1st in list */
-  } else for(pcb2 = udp_pcbs; pcb2 != NULL; pcb2 = pcb2->next) {
-    /* find pcb in udp_pcbs list */
-    if (pcb2->next != NULL && pcb2->next == pcb) {
-      /* remove pcb from list */
-      pcb2->next = pcb->next;
-    }
-  }
-  memp_free(MEMP_UDP_PCB, pcb);
-}
-/**
- * Create a UDP PCB.
- *
- * @return The UDP PCB which was created. NULL if the PCB data structure
- * could not be allocated.
- *
- * @see udp_remove()
- */
-struct udp_pcb *
-udp_new(void) {
-  struct udp_pcb *pcb;
-  pcb = memp_malloc(MEMP_UDP_PCB);
-  /* could allocate UDP PCB? */
-  if (pcb != NULL) {
-    /* initialize PCB to all zeroes */
-    memset(pcb, 0, sizeof(struct udp_pcb));
-    pcb->ttl = UDP_TTL;
-  }
-  
-  
-  return pcb;
-}
-
-#if UDP_DEBUG
-int
-udp_debug_print(struct udp_hdr *udphdr)
-{
-  LWIP_DEBUGF(UDP_DEBUG, ("UDP header:\n"));
-  LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n"));
-  LWIP_DEBUGF(UDP_DEBUG, ("|     %5u     |     %5u     | (src port, dest port)\n",
-         ntohs(udphdr->src), ntohs(udphdr->dest)));
-  LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n"));
-  LWIP_DEBUGF(UDP_DEBUG, ("|     %5u     |     0x%04x    | (len, chksum)\n",
-         ntohs(udphdr->len), ntohs(udphdr->chksum)));
-  LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n"));
-  return 0;
-}
-#endif /* UDP_DEBUG */
-
-#endif /* LWIP_UDP */
-
-
-
-
-
-
-
-
-
+/**\r
+ * @file\r
+ * User Datagram Protocol module\r
+ *\r
+ */\r
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without modification,\r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED\r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT\r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY\r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ *\r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+\r
+\r
+/* udp.c\r
+ *\r
+ * The code for the User Datagram Protocol UDP.\r
+ *\r
+ */\r
+\r
+#include <string.h>\r
+\r
+#include "lwip/opt.h"\r
+\r
+#include "lwip/def.h"\r
+#include "lwip/memp.h"\r
+#include "lwip/inet.h"\r
+#include "lwip/ip_addr.h"\r
+#include "lwip/netif.h"\r
+#include "lwip/udp.h"\r
+#include "lwip/icmp.h"\r
+\r
+#include "lwip/stats.h"\r
+\r
+#include "arch/perf.h"\r
+#include "lwip/snmp.h"\r
+\r
+/* The list of UDP PCBs */\r
+#if LWIP_UDP\r
+/* was static, but we may want to access this from a socket layer */\r
+struct udp_pcb *udp_pcbs = NULL;\r
+\r
+static struct udp_pcb *pcb_cache = NULL;\r
+\r
+\r
+void\r
+udp_init(void)\r
+{\r
+  udp_pcbs = pcb_cache = NULL;\r
+}\r
+\r
+/**\r
+ * Process an incoming UDP datagram.\r
+ *\r
+ * Given an incoming UDP datagram (as a chain of pbufs) this function\r
+ * finds a corresponding UDP PCB and\r
+ *\r
+ * @param pbuf pbuf to be demultiplexed to a UDP PCB.\r
+ * @param netif network interface on which the datagram was received.\r
+ *\r
+ */\r
+void\r
+udp_input(struct pbuf *p, struct netif *inp)\r
+{\r
+  struct udp_hdr *udphdr;\r
+  struct udp_pcb *pcb;\r
+  struct ip_hdr *iphdr;\r
+  u16_t src, dest;\r
+\r
+#if SO_REUSE\r
+  struct udp_pcb *pcb_temp;\r
+  int reuse = 0;\r
+  int reuse_port_1 = 0;\r
+  int reuse_port_2 = 0;\r
+#endif /* SO_REUSE */\r
+  \r
+  PERF_START;\r
+\r
+  UDP_STATS_INC(udp.recv);\r
+\r
+  iphdr = p->payload;\r
+\r
+  if (pbuf_header(p, -((s16_t)(UDP_HLEN + IPH_HL(iphdr) * 4)))) {\r
+    /* drop short packets */\r
+    LWIP_DEBUGF(UDP_DEBUG, ("udp_input: short UDP datagram (%u bytes) discarded\n", p->tot_len));\r
+    UDP_STATS_INC(udp.lenerr);\r
+    UDP_STATS_INC(udp.drop);\r
+    snmp_inc_udpinerrors();\r
+    pbuf_free(p);\r
+    goto end;\r
+  }\r
+\r
+  udphdr = (struct udp_hdr *)((u8_t *)p->payload - UDP_HLEN);\r
+\r
+  LWIP_DEBUGF(UDP_DEBUG, ("udp_input: received datagram of length %u\n", p->tot_len));\r
+\r
+  src = ntohs(udphdr->src);\r
+  dest = ntohs(udphdr->dest);\r
+\r
+  udp_debug_print(udphdr);\r
+\r
+  /* print the UDP source and destination */\r
+  LWIP_DEBUGF(UDP_DEBUG, ("udp (%u.%u.%u.%u, %u) <-- (%u.%u.%u.%u, %u)\n",\r
+    ip4_addr1(&iphdr->dest), ip4_addr2(&iphdr->dest),\r
+    ip4_addr3(&iphdr->dest), ip4_addr4(&iphdr->dest), ntohs(udphdr->dest),\r
+    ip4_addr1(&iphdr->src), ip4_addr2(&iphdr->src),\r
+    ip4_addr3(&iphdr->src), ip4_addr4(&iphdr->src), ntohs(udphdr->src)));\r
+\r
+#if SO_REUSE\r
+  pcb_temp = udp_pcbs;\r
+  \r
+ again_1:\r
+  \r
+  /* Iterate through the UDP pcb list for a fully matching pcb */\r
+  for (pcb = pcb_temp; pcb != NULL; pcb = pcb->next) {\r
+#else  /* SO_REUSE */ \r
+  /* Iterate through the UDP pcb list for a fully matching pcb */\r
+  for (pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) {\r
+#endif  /* SO_REUSE */ \r
+    /* print the PCB local and remote address */\r
+    LWIP_DEBUGF(UDP_DEBUG, ("pcb (%u.%u.%u.%u, %u) --- (%u.%u.%u.%u, %u)\n",\r
+      ip4_addr1(&pcb->local_ip), ip4_addr2(&pcb->local_ip),\r
+      ip4_addr3(&pcb->local_ip), ip4_addr4(&pcb->local_ip), pcb->local_port,\r
+      ip4_addr1(&pcb->remote_ip), ip4_addr2(&pcb->remote_ip),\r
+      ip4_addr3(&pcb->remote_ip), ip4_addr4(&pcb->remote_ip), pcb->remote_port));\r
+\r
+       /* PCB remote port matches UDP source port? */\r
+    if ((pcb->remote_port == src) &&\r
+       /* PCB local port matches UDP destination port? */\r
+       (pcb->local_port == dest) &&\r
+       /* accepting from any remote (source) IP address? or... */\r
+       (ip_addr_isany(&pcb->remote_ip) ||\r
+       /* PCB remote IP address matches UDP source IP address? */\r
+        ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src))) &&\r
+       /* accepting on any local (netif) IP address? or... */\r
+       (ip_addr_isany(&pcb->local_ip) ||\r
+       /* PCB local IP address matches UDP destination IP address? */\r
+        ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest)))) {\r
+#if SO_REUSE\r
+      if (pcb->so_options & SOF_REUSEPORT) {\r
+        if(reuse) {\r
+          /* We processed one PCB already */\r
+          LWIP_DEBUGF(UDP_DEBUG, ("udp_input: second or later PCB and SOF_REUSEPORT set.\n"));\r
+        } else {\r
+          /* First PCB with this address */\r
+          LWIP_DEBUGF(UDP_DEBUG, ("udp_input: first PCB and SOF_REUSEPORT set.\n"));\r
+          reuse = 1;\r
+        }\r
+        \r
+        reuse_port_1 = 1; \r
+        p->ref++;\r
+        LWIP_DEBUGF(UDP_DEBUG, ("udp_input: reference counter on PBUF set to %i\n", p->ref));\r
+      } else {\r
+        if (reuse) {\r
+          /* We processed one PCB already */\r
+          LWIP_DEBUGF(UDP_DEBUG, ("udp_input: second or later PCB but SOF_REUSEPORT not set !\n"));\r
+        }\r
+      }\r
+#endif /* SO_REUSE */\r
+      break;\r
+    }\r
+  }\r
+  /* no fully matching pcb found? then look for an unconnected pcb */\r
+  if (pcb == NULL) {\r
+    /* Iterate through the UDP PCB list for a pcb that matches\r
+       the local address. */\r
+\r
+#if SO_REUSE\r
+    pcb_temp = udp_pcbs;\r
+    \r
+  again_2:\r
+\r
+    for (pcb = pcb_temp; pcb != NULL; pcb = pcb->next) {\r
+#else  /* SO_REUSE */ \r
+    for (pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) {\r
+#endif  /* SO_REUSE */ \r
+      LWIP_DEBUGF(UDP_DEBUG, ("pcb (%u.%u.%u.%u, %u) --- (%u.%u.%u.%u, %u)\n",\r
+        ip4_addr1(&pcb->local_ip), ip4_addr2(&pcb->local_ip),\r
+        ip4_addr3(&pcb->local_ip), ip4_addr4(&pcb->local_ip), pcb->local_port,\r
+        ip4_addr1(&pcb->remote_ip), ip4_addr2(&pcb->remote_ip),\r
+        ip4_addr3(&pcb->remote_ip), ip4_addr4(&pcb->remote_ip), pcb->remote_port));\r
+      /* unconnected? */\r
+      if (((pcb->flags & UDP_FLAGS_CONNECTED) == 0) &&\r
+         /* destination port matches? */\r
+        (pcb->local_port == dest) &&\r
+        /* not bound to a specific (local) interface address? or... */\r
+        (ip_addr_isany(&pcb->local_ip) ||\r
+        /* ...matching interface address? */\r
+        ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest)))) {\r
+#if SO_REUSE\r
+        if (pcb->so_options & SOF_REUSEPORT) {\r
+          if (reuse) {\r
+            /* We processed one PCB already */\r
+            LWIP_DEBUGF(UDP_DEBUG, ("udp_input: second or later PCB and SOF_REUSEPORT set.\n"));\r
+          } else {\r
+            /* First PCB with this address */\r
+            LWIP_DEBUGF(UDP_DEBUG, ("udp_input: first PCB and SOF_REUSEPORT set.\n"));\r
+            reuse = 1;\r
+          }\r
+          \r
+          reuse_port_2 = 1; \r
+          p->ref++;\r
+          LWIP_DEBUGF(UDP_DEBUG, ("udp_input: reference counter on PBUF set to %i\n", p->ref));\r
+        } else {\r
+          if (reuse) {\r
+            /* We processed one PCB already */\r
+            LWIP_DEBUGF(UDP_DEBUG, ("udp_input: second or later PCB but SOF_REUSEPORT not set !\n"));\r
+          }\r
+        }\r
+#endif /* SO_REUSE */\r
+        break;\r
+      }\r
+    }\r
+  }\r
+\r
+  /* Check checksum if this is a match or if it was directed at us. */\r
+  if (pcb != NULL  || ip_addr_cmp(&inp->ip_addr, &iphdr->dest))\r
+    {\r
+    LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE, ("udp_input: calculating checksum\n"));\r
+    pbuf_header(p, UDP_HLEN);\r
+#ifdef IPv6\r
+    if (iphdr->nexthdr == IP_PROTO_UDPLITE) {\r
+#else\r
+    if (IPH_PROTO(iphdr) == IP_PROTO_UDPLITE) {\r
+#endif /* IPv4 */\r
+      /* Do the UDP Lite checksum */\r
+#if CHECKSUM_CHECK_UDP\r
+      if (inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src),\r
+         (struct ip_addr *)&(iphdr->dest),\r
+         IP_PROTO_UDPLITE, ntohs(udphdr->len)) != 0) {\r
+  LWIP_DEBUGF(UDP_DEBUG | 2, ("udp_input: UDP Lite datagram discarded due to failing checksum\n"));\r
+  UDP_STATS_INC(udp.chkerr);\r
+  UDP_STATS_INC(udp.drop);\r
+  snmp_inc_udpinerrors();\r
+  pbuf_free(p);\r
+  goto end;\r
+      }\r
+#endif\r
+    } else {\r
+#if CHECKSUM_CHECK_UDP\r
+      if (udphdr->chksum != 0) {\r
+  if (inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src),\r
+       (struct ip_addr *)&(iphdr->dest),\r
+        IP_PROTO_UDP, p->tot_len) != 0) {\r
+    LWIP_DEBUGF(UDP_DEBUG | 2, ("udp_input: UDP datagram discarded due to failing checksum\n"));\r
+\r
+    UDP_STATS_INC(udp.chkerr);\r
+    UDP_STATS_INC(udp.drop);\r
+    snmp_inc_udpinerrors();\r
+    pbuf_free(p);\r
+    goto end;\r
+  }\r
+      }\r
+#endif\r
+    }\r
+    pbuf_header(p, -UDP_HLEN);\r
+    if (pcb != NULL) {\r
+      snmp_inc_udpindatagrams();\r
+      pcb->recv(pcb->recv_arg, pcb, p, &(iphdr->src), src);\r
+#if SO_REUSE\r
+      /* First socket should receive now */\r
+      if(reuse_port_1 || reuse_port_2) {\r
+        /* We want to search on next socket after receiving */\r
+        pcb_temp = pcb->next;\r
+        \r
+        if(reuse_port_1) {\r
+          /* We are searching connected sockets */\r
+          reuse_port_1 = 0;\r
+          reuse_port_2 = 0;\r
+          goto again_1;\r
+        } else {\r
+          /* We are searching unconnected sockets */\r
+          reuse_port_1 = 0;\r
+          reuse_port_2 = 0;\r
+          goto again_2;\r
+        }\r
+      }\r
+#endif /* SO_REUSE */ \r
+    } else {\r
+#if SO_REUSE\r
+      if(reuse) {\r
+        LWIP_DEBUGF(UDP_DEBUG, ("udp_input: freeing PBUF with reference counter set to %i\n", p->ref));\r
+        pbuf_free(p);\r
+        goto end;\r
+      }\r
+#endif /* SO_REUSE */\r
+      LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE, ("udp_input: not for us.\n"));\r
+\r
+      /* No match was found, send ICMP destination port unreachable unless\r
+      destination address was broadcast/multicast. */\r
+\r
+      if (!ip_addr_isbroadcast(&iphdr->dest, inp) &&\r
+          !ip_addr_ismulticast(&iphdr->dest)) {\r
+\r
+  /* adjust pbuf pointer */\r
+  p->payload = iphdr;\r
+  icmp_dest_unreach(p, ICMP_DUR_PORT);\r
+      }\r
+      UDP_STATS_INC(udp.proterr);\r
+      UDP_STATS_INC(udp.drop);\r
+    snmp_inc_udpnoports();\r
+      pbuf_free(p);\r
+    }\r
+  } else {\r
+    pbuf_free(p);\r
+  }\r
+  end:\r
+\r
+  PERF_STOP("udp_input");\r
+}\r
+\r
+/**\r
+ * Send data to a specified address using UDP.\r
+ *\r
+ * @param pcb UDP PCB used to send the data.\r
+ * @param pbuf chain of pbuf's to be sent.\r
+ * @param dst_ip Destination IP address.\r
+ * @param dst_port Destination UDP port.\r
+ *\r
+ * If the PCB already has a remote address association, it will\r
+ * be restored after the data is sent.\r
+ * \r
+ * @return lwIP error code.\r
+ * - ERR_OK. Successful. No error occured.\r
+ * - ERR_MEM. Out of memory.\r
+ * - ERR_RTE. Could not find route to destination address.\r
+ *\r
+ * @see udp_disconnect() udp_send()\r
+ */\r
+err_t\r
+udp_sendto(struct udp_pcb *pcb, struct pbuf *p,\r
+  struct ip_addr *dst_ip, u16_t dst_port)\r
+{\r
+  err_t err;\r
+  /* temporary space for current PCB remote address */\r
+  struct ip_addr pcb_remote_ip;\r
+  u16_t pcb_remote_port;\r
+  /* remember current remote peer address of PCB */\r
+  pcb_remote_ip.addr = pcb->remote_ip.addr;\r
+  pcb_remote_port = pcb->remote_port;\r
+  /* copy packet destination address to PCB remote peer address */\r
+  pcb->remote_ip.addr = dst_ip->addr;\r
+  pcb->remote_port = dst_port;\r
+  /* send to the packet destination address */\r
+  err = udp_send(pcb, p);\r
+  /* restore PCB remote peer address */\r
+  pcb->remote_ip.addr = pcb_remote_ip.addr;\r
+  pcb->remote_port = pcb_remote_port;\r
+  return err;\r
+}\r
+\r
+/**\r
+ * Send data using UDP.\r
+ *\r
+ * @param pcb UDP PCB used to send the data.\r
+ * @param pbuf chain of pbuf's to be sent.\r
+ *\r
+ * @return lwIP error code.\r
+ * - ERR_OK. Successful. No error occured.\r
+ * - ERR_MEM. Out of memory.\r
+ * - ERR_RTE. Could not find route to destination address.\r
+ *\r
+ * @see udp_disconnect() udp_sendto()\r
+ */\r
+err_t\r
+udp_send(struct udp_pcb *pcb, struct pbuf *p)\r
+{\r
+  struct udp_hdr *udphdr;\r
+  struct netif *netif;\r
+  struct ip_addr *src_ip;\r
+  err_t err;\r
+  struct pbuf *q; /* q will be sent down the stack */\r
+\r
+  LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | 3, ("udp_send\n"));\r
+\r
+  /* if the PCB is not yet bound to a port, bind it here */\r
+  if (pcb->local_port == 0) {\r
+    LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | 2, ("udp_send: not yet bound to a port, binding now\n"));\r
+    err = udp_bind(pcb, &pcb->local_ip, pcb->local_port);\r
+    if (err != ERR_OK) {\r
+      LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | 2, ("udp_send: forced port bind failed\n"));\r
+      return err;\r
+    }\r
+  }\r
+\r
+  /* not enough space to add an UDP header to first pbuf in given p chain? */\r
+  if (pbuf_header(p, UDP_HLEN)) {\r
+    /* allocate header in a seperate new pbuf */\r
+    q = pbuf_alloc(PBUF_IP, UDP_HLEN, PBUF_RAM);\r
+    /* new header pbuf could not be allocated? */\r
+    if (q == NULL) {\r
+      LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | 2, ("udp_send: could not allocate header\n"));\r
+      return ERR_MEM;\r
+    }\r
+    /* chain header q in front of given pbuf p */\r
+    pbuf_chain(q, p);\r
+    /* { first pbuf q points to header pbuf } */\r
+    LWIP_DEBUGF(UDP_DEBUG, ("udp_send: added header pbuf %p before given pbuf %p\n", (void *)q, (void *)p));\r
+  /* adding a header within p succeeded */\r
+  } else {\r
+    /* first pbuf q equals given pbuf */\r
+    q = p;\r
+    LWIP_DEBUGF(UDP_DEBUG, ("udp_send: added header in given pbuf %p\n", (void *)p));\r
+  }\r
+  /* { q now represents the packet to be sent } */\r
+  udphdr = q->payload;\r
+  udphdr->src = htons(pcb->local_port);\r
+  udphdr->dest = htons(pcb->remote_port);\r
+  /* in UDP, 0 checksum means 'no checksum' */\r
+  udphdr->chksum = 0x0000; \r
+\r
+  /* find the outgoing network interface for this packet */\r
+  netif = ip_route(&(pcb->remote_ip));\r
+  /* no outgoing network interface could be found? */\r
+  if (netif == NULL) {\r
+    LWIP_DEBUGF(UDP_DEBUG | 1, ("udp_send: No route to 0x%lx\n", pcb->remote_ip.addr));\r
+    UDP_STATS_INC(udp.rterr);\r
+    return ERR_RTE;\r
+  }\r
+  /* PCB local address is IP_ANY_ADDR? */\r
+  if (ip_addr_isany(&pcb->local_ip)) {\r
+    /* use outgoing network interface IP address as source address */\r
+    src_ip = &(netif->ip_addr);\r
+  } else {\r
+    /* use UDP PCB local IP address as source address */\r
+    src_ip = &(pcb->local_ip);\r
+  }\r
+\r
+  LWIP_DEBUGF(UDP_DEBUG, ("udp_send: sending datagram of length %u\n", q->tot_len));\r
+\r
+  /* UDP Lite protocol? */\r
+  if (pcb->flags & UDP_FLAGS_UDPLITE) {\r
+    LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP LITE packet length %u\n", q->tot_len));\r
+    /* set UDP message length in UDP header */\r
+    udphdr->len = htons(pcb->chksum_len);\r
+    /* calculate checksum */\r
+#if CHECKSUM_GEN_UDP\r
+    udphdr->chksum = inet_chksum_pseudo(q, src_ip, &(pcb->remote_ip),\r
+          IP_PROTO_UDP, pcb->chksum_len);\r
+    /* chksum zero must become 0xffff, as zero means 'no checksum' */\r
+    if (udphdr->chksum == 0x0000) udphdr->chksum = 0xffff;\r
+#else\r
+    udphdr->chksum = 0x0000;\r
+#endif\r
+    /* output to IP */\r
+    LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,IP_PROTO_UDPLITE,)\n"));\r
+    err = ip_output_if (q, src_ip, &pcb->remote_ip, pcb->ttl, pcb->tos, IP_PROTO_UDPLITE, netif);    \r
+  /* UDP */\r
+  } else {\r
+    LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP packet length %u\n", q->tot_len));\r
+    udphdr->len = htons(q->tot_len);\r
+    /* calculate checksum */\r
+#if CHECKSUM_GEN_UDP\r
+    if ((pcb->flags & UDP_FLAGS_NOCHKSUM) == 0) {\r
+      udphdr->chksum = inet_chksum_pseudo(q, src_ip, &pcb->remote_ip, IP_PROTO_UDP, q->tot_len);\r
+      /* chksum zero must become 0xffff, as zero means 'no checksum' */\r
+      if (udphdr->chksum == 0x0000) udphdr->chksum = 0xffff;\r
+    }\r
+#else\r
+    udphdr->chksum = 0x0000;\r
+#endif\r
+    LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP checksum 0x%04x\n", udphdr->chksum));\r
+    LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,IP_PROTO_UDP,)\n"));\r
+    /* output to IP */\r
+    err = ip_output_if(q, src_ip, &pcb->remote_ip, pcb->ttl, pcb->tos, IP_PROTO_UDP, netif);    \r
+  }\r
+  /* TODO: must this be increased even if error occured? */\r
+  snmp_inc_udpoutdatagrams();\r
+\r
+  /* did we chain a seperate header pbuf earlier? */\r
+  if (q != p) {\r
+    /* free the header pbuf */\r
+    pbuf_free(q); q = NULL;\r
+    /* { p is still referenced by the caller, and will live on } */\r
+  }\r
+\r
+  UDP_STATS_INC(udp.xmit);\r
+  return err;\r
+}\r
+\r
+/**\r
+ * Bind an UDP PCB.\r
+ *\r
+ * @param pcb UDP PCB to be bound with a local address ipaddr and port.\r
+ * @param ipaddr local IP address to bind with. Use IP_ADDR_ANY to\r
+ * bind to all local interfaces.\r
+ * @param port local UDP port to bind with.\r
+ *\r
+ * @return lwIP error code.\r
+ * - ERR_OK. Successful. No error occured.\r
+ * - ERR_USE. The specified ipaddr and port are already bound to by\r
+ * another UDP PCB.\r
+ *\r
+ * @see udp_disconnect()\r
+ */\r
+err_t\r
+udp_bind(struct udp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)\r
+{\r
+  struct udp_pcb *ipcb;\r
+  u8_t rebind;\r
+#if SO_REUSE\r
+  int reuse_port_all_set = 1;\r
+#endif /* SO_REUSE */\r
+  LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | 3, ("udp_bind(ipaddr = "));\r
+  ip_addr_debug_print(UDP_DEBUG, ipaddr);\r
+  LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | 3, (", port = %u)\n", port));\r
+\r
+  rebind = 0;\r
+  /* Check for double bind and rebind of the same pcb */\r
+  for (ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) {\r
+    /* is this UDP PCB already on active list? */\r
+    if (pcb == ipcb) {\r
+      /* pcb may occur at most once in active list */\r
+      LWIP_ASSERT("rebind == 0", rebind == 0);\r
+      /* pcb already in list, just rebind */\r
+      rebind = 1;\r
+    }\r
+\r
+#if SO_REUSE == 0\r
+/* this code does not allow upper layer to share a UDP port for\r
+   listening to broadcast or multicast traffic (See SO_REUSE_ADDR and\r
+   SO_REUSE_PORT under *BSD). TODO: See where it fits instead, OR\r
+   combine with implementation of UDP PCB flags. Leon Woestenberg. */\r
+#ifdef LWIP_UDP_TODO\r
+    /* port matches that of PCB in list? */\r
+    else if ((ipcb->local_port == port) &&\r
+       /* IP address matches, or one is IP_ADDR_ANY? */\r
+       (ip_addr_isany(&(ipcb->local_ip)) ||\r
+       ip_addr_isany(ipaddr) ||\r
+       ip_addr_cmp(&(ipcb->local_ip), ipaddr))) {\r
+      /* other PCB already binds to this local IP and port */\r
+      LWIP_DEBUGF(UDP_DEBUG, ("udp_bind: local port %u already bound by another pcb\n", port));\r
+      return ERR_USE;\r
+    }\r
+#endif\r
+\r
+#else /* SO_REUSE */\r
+      /* Search through list of PCB's. \r
+         \r
+      If there is a PCB bound to specified port and IP_ADDR_ANY another PCB can be bound to the interface IP\r
+      or to the loopback address on the same port if SOF_REUSEADDR is set. Any combination of PCB's bound to \r
+      the same local port, but to one address out of {IP_ADDR_ANY, 127.0.0.1, interface IP} at a time is valid.\r
+      But no two PCB's bound to same local port and same local address is valid.\r
+      \r
+      If SOF_REUSEPORT is set several PCB's can be bound to same local port and same local address also. But then \r
+      all PCB's must have the SOF_REUSEPORT option set.\r
+      \r
+      When the two options aren't set and specified port is already bound, ERR_USE is returned saying that \r
+      address is already in use. */\r
+    else if (ipcb->local_port == port) {\r
+      if(ip_addr_cmp(&(ipcb->local_ip), ipaddr)) {\r
+        if(pcb->so_options & SOF_REUSEPORT) {\r
+          LWIP_DEBUGF(UDP_DEBUG, ("udp_bind: in UDP PCB's SO_REUSEPORT set and same address.\n"));\r
+          reuse_port_all_set = (reuse_port_all_set && (ipcb->so_options & SOF_REUSEPORT));\r
+        }\r
+        else {\r
+          LWIP_DEBUGF(UDP_DEBUG, ("udp_bind: in UDP PCB's SO_REUSEPORT not set and same address.\n"));\r
+          return ERR_USE;\r
+        }\r
+      }\r
+      else if((ip_addr_isany(ipaddr) && !ip_addr_isany(&(ipcb->local_ip))) ||\r
+              (!ip_addr_isany(ipaddr) && ip_addr_isany(&(ipcb->local_ip)))) {\r
+        if(!(pcb->so_options & SOF_REUSEADDR) && !(pcb->so_options & SOF_REUSEPORT)) {\r
+          LWIP_DEBUGF(UDP_DEBUG, ("udp_bind: in UDP PCB's SO_REUSEPORT or SO_REUSEADDR not set and not the same address.\n"));\r
+          return ERR_USE;\r
+        }           \r
+      }\r
+    }\r
+#endif /* SO_REUSE */\r
+\r
+  }\r
+\r
+#if SO_REUSE\r
+  /* If SOF_REUSEPORT isn't set in all PCB's bound to specified port and local address specified then \r
+     {IP, port} can't be reused. */\r
+  if(!reuse_port_all_set) {\r
+    LWIP_DEBUGF(UDP_DEBUG, ("udp_bind: not all sockets have SO_REUSEPORT set.\n"));\r
+    return ERR_USE;\r
+  }\r
+#endif /* SO_REUSE */\r
+\r
+  ip_addr_set(&pcb->local_ip, ipaddr);\r
+  /* no port specified? */\r
+  if (port == 0) {\r
+#ifndef UDP_LOCAL_PORT_RANGE_START\r
+#define UDP_LOCAL_PORT_RANGE_START 4096\r
+#define UDP_LOCAL_PORT_RANGE_END   0x7fff\r
+#endif\r
+    port = UDP_LOCAL_PORT_RANGE_START;\r
+    ipcb = udp_pcbs;\r
+    while ((ipcb != NULL) && (port != UDP_LOCAL_PORT_RANGE_END)) {\r
+      if (ipcb->local_port == port) {\r
+        port++;\r
+        ipcb = udp_pcbs;\r
+      } else\r
+        ipcb = ipcb->next;\r
+    }\r
+    if (ipcb != NULL) {\r
+      /* no more ports available in local range */\r
+      LWIP_DEBUGF(UDP_DEBUG, ("udp_bind: out of free UDP ports\n"));\r
+      return ERR_USE;\r
+    }\r
+  }\r
+  pcb->local_port = port;\r
+  /* pcb not active yet? */\r
+  if (rebind == 0) {\r
+    /* place the PCB on the active list if not already there */\r
+    pcb->next = udp_pcbs;\r
+    udp_pcbs = pcb;\r
+  }\r
+  LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | DBG_STATE, ("udp_bind: bound to %u.%u.%u.%u, port %u\n",\r
+   (unsigned int)(ntohl(pcb->local_ip.addr) >> 24 & 0xff),\r
+   (unsigned int)(ntohl(pcb->local_ip.addr) >> 16 & 0xff),\r
+   (unsigned int)(ntohl(pcb->local_ip.addr) >> 8 & 0xff),\r
+   (unsigned int)(ntohl(pcb->local_ip.addr) & 0xff), pcb->local_port));\r
+  return ERR_OK;\r
+}\r
+/**\r
+ * Connect an UDP PCB.\r
+ *\r
+ * This will associate the UDP PCB with the remote address.\r
+ *\r
+ * @param pcb UDP PCB to be connected with remote address ipaddr and port.\r
+ * @param ipaddr remote IP address to connect with.\r
+ * @param port remote UDP port to connect with.\r
+ *\r
+ * @return lwIP error code\r
+ *\r
+ * @see udp_disconnect()\r
+ */\r
+err_t\r
+udp_connect(struct udp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)\r
+{\r
+  struct udp_pcb *ipcb;\r
+\r
+  if (pcb->local_port == 0) {\r
+    err_t err = udp_bind(pcb, &pcb->local_ip, pcb->local_port);\r
+    if (err != ERR_OK)\r
+      return err;\r
+  }\r
+\r
+  ip_addr_set(&pcb->remote_ip, ipaddr);\r
+  pcb->remote_port = port;\r
+  pcb->flags |= UDP_FLAGS_CONNECTED;\r
+/** TODO: this functionality belongs in upper layers */\r
+#ifdef LWIP_UDP_TODO\r
+  /* Nail down local IP for netconn_addr()/getsockname() */\r
+  if (ip_addr_isany(&pcb->local_ip) && !ip_addr_isany(&pcb->remote_ip)) {\r
+    struct netif *netif;\r
+\r
+    if ((netif = ip_route(&(pcb->remote_ip))) == NULL) {\r
+      LWIP_DEBUGF(UDP_DEBUG, ("udp_connect: No route to 0x%lx\n", pcb->remote_ip.addr));\r
+        UDP_STATS_INC(udp.rterr);\r
+      return ERR_RTE;\r
+    }\r
+    /** TODO: this will bind the udp pcb locally, to the interface which\r
+        is used to route output packets to the remote address. However, we\r
+        might want to accept incoming packets on any interface! */\r
+    pcb->local_ip = netif->ip_addr;\r
+  } else if (ip_addr_isany(&pcb->remote_ip)) {\r
+    pcb->local_ip.addr = 0;\r
+  }\r
+#endif\r
+  LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | DBG_STATE, ("udp_connect: connected to %u.%u.%u.%u, port %u\n",\r
+   (unsigned int)(ntohl(pcb->remote_ip.addr) >> 24 & 0xff),\r
+   (unsigned int)(ntohl(pcb->remote_ip.addr) >> 16 & 0xff),\r
+   (unsigned int)(ntohl(pcb->remote_ip.addr) >> 8 & 0xff),\r
+   (unsigned int)(ntohl(pcb->remote_ip.addr) & 0xff), pcb->remote_port));\r
+\r
+  /* Insert UDP PCB into the list of active UDP PCBs. */\r
+  for(ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) {\r
+    if (pcb == ipcb) {\r
+      /* already on the list, just return */\r
+      return ERR_OK;\r
+    }\r
+  }\r
+  /* PCB not yet on the list, add PCB now */\r
+  pcb->next = udp_pcbs;\r
+  udp_pcbs = pcb;\r
+  return ERR_OK;\r
+}\r
+\r
+void\r
+udp_disconnect(struct udp_pcb *pcb)\r
+{\r
+  /* reset remote address association */\r
+  ip_addr_set(&pcb->remote_ip, IP_ADDR_ANY);\r
+  pcb->remote_port = 0;\r
+  /* mark PCB as unconnected */\r
+  pcb->flags &= ~UDP_FLAGS_CONNECTED;\r
+}\r
+\r
+void\r
+udp_recv(struct udp_pcb *pcb,\r
+   void (* recv)(void *arg, struct udp_pcb *upcb, struct pbuf *p,\r
+           struct ip_addr *addr, u16_t port),\r
+   void *recv_arg)\r
+{\r
+  /* remember recv() callback and user data */\r
+  pcb->recv = recv;\r
+  pcb->recv_arg = recv_arg;\r
+}\r
+/**\r
+ * Remove an UDP PCB.\r
+ *\r
+ * @param pcb UDP PCB to be removed. The PCB is removed from the list of\r
+ * UDP PCB's and the data structure is freed from memory.\r
+ *\r
+ * @see udp_new()\r
+ */\r
+void\r
+udp_remove(struct udp_pcb *pcb)\r
+{\r
+  struct udp_pcb *pcb2;\r
+  /* pcb to be removed is first in list? */\r
+  if (udp_pcbs == pcb) {\r
+    /* make list start at 2nd pcb */\r
+    udp_pcbs = udp_pcbs->next;\r
+  /* pcb not 1st in list */\r
+  } else for(pcb2 = udp_pcbs; pcb2 != NULL; pcb2 = pcb2->next) {\r
+    /* find pcb in udp_pcbs list */\r
+    if (pcb2->next != NULL && pcb2->next == pcb) {\r
+      /* remove pcb from list */\r
+      pcb2->next = pcb->next;\r
+    }\r
+  }\r
+  memp_free(MEMP_UDP_PCB, pcb);\r
+}\r
+/**\r
+ * Create a UDP PCB.\r
+ *\r
+ * @return The UDP PCB which was created. NULL if the PCB data structure\r
+ * could not be allocated.\r
+ *\r
+ * @see udp_remove()\r
+ */\r
+struct udp_pcb *\r
+udp_new(void) {\r
+  struct udp_pcb *pcb;\r
+  pcb = memp_malloc(MEMP_UDP_PCB);\r
+  /* could allocate UDP PCB? */\r
+  if (pcb != NULL) {\r
+    /* initialize PCB to all zeroes */\r
+    memset(pcb, 0, sizeof(struct udp_pcb));\r
+    pcb->ttl = UDP_TTL;\r
+  }\r
+  \r
+  \r
+  return pcb;\r
+}\r
+\r
+#if UDP_DEBUG\r
+int\r
+udp_debug_print(struct udp_hdr *udphdr)\r
+{\r
+  LWIP_DEBUGF(UDP_DEBUG, ("UDP header:\n"));\r
+  LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n"));\r
+  LWIP_DEBUGF(UDP_DEBUG, ("|     %5u     |     %5u     | (src port, dest port)\n",\r
+         ntohs(udphdr->src), ntohs(udphdr->dest)));\r
+  LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n"));\r
+  LWIP_DEBUGF(UDP_DEBUG, ("|     %5u     |     0x%04x    | (len, chksum)\n",\r
+         ntohs(udphdr->len), ntohs(udphdr->chksum)));\r
+  LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n"));\r
+  return 0;\r
+}\r
+#endif /* UDP_DEBUG */\r
+\r
+#endif /* LWIP_UDP */\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
index 634405b714f1f6465a4991386bf2344af12adddd..04307e7432baffa337e9ae6b0741ae1145a8c084 100644 (file)
-/*
- * 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 <adam@sics.se>
- *
- */
-#ifndef __LWIP_ICMP_H__
-#define __LWIP_ICMP_H__
-
-#include "lwip/arch.h"
-
-#include "lwip/opt.h"
-#include "lwip/pbuf.h"
-
-#include "lwip/ip_addr.h"
-#include "lwip/netif.h"
-
-#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_TSR 14    /* timestamp reply */
-#define ICMP_IRQ 15    /* information request */
-#define ICMP_IR 16     /* information reply */
-
-enum icmp_dur_type {
-  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 */
-};
-
-enum icmp_te_type {
-  ICMP_TE_TTL = 0,     /* time to live exceeded in transit */
-  ICMP_TE_FRAG = 1     /* fragment reassembly time exceeded */
-};
-
-void icmp_input(struct pbuf *p, struct netif *inp);
-
-void icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t);
-void icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t);
-
-#ifdef PACK_STRUCT_USE_INCLUDES
-#  include "arch/bpstruct.h"
-#endif
-PACK_STRUCT_BEGIN
-struct icmp_echo_hdr {
-  PACK_STRUCT_FIELD(u16_t _type_code);
-  PACK_STRUCT_FIELD(u16_t chksum);
-  PACK_STRUCT_FIELD(u16_t id);
-  PACK_STRUCT_FIELD(u16_t seqno);
-} PACK_STRUCT_STRUCT;
-PACK_STRUCT_END
-
-PACK_STRUCT_BEGIN
-struct icmp_dur_hdr {
-  PACK_STRUCT_FIELD(u16_t _type_code);
-  PACK_STRUCT_FIELD(u16_t chksum);
-  PACK_STRUCT_FIELD(u32_t unused);
-} PACK_STRUCT_STRUCT;
-PACK_STRUCT_END
-
-PACK_STRUCT_BEGIN
-struct icmp_te_hdr {
-  PACK_STRUCT_FIELD(u16_t _type_code);
-  PACK_STRUCT_FIELD(u16_t chksum);
-  PACK_STRUCT_FIELD(u32_t unused);
-} PACK_STRUCT_STRUCT;
-PACK_STRUCT_END
-#ifdef PACK_STRUCT_USE_INCLUDES
-#  include "arch/epstruct.h"
-#endif
-
-#define ICMPH_TYPE(hdr) (ntohs((hdr)->_type_code) >> 8)
-#define ICMPH_CODE(hdr) (ntohs((hdr)->_type_code) & 0xff)
-
-#define ICMPH_TYPE_SET(hdr, type) ((hdr)->_type_code = htons(ICMPH_CODE(hdr) | ((type) << 8)))
-#define ICMPH_CODE_SET(hdr, code) ((hdr)->_type_code = htons((code) | (ICMPH_TYPE(hdr) << 8)))
-
-#endif /* __LWIP_ICMP_H__ */
-    
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+#ifndef __LWIP_ICMP_H__\r
+#define __LWIP_ICMP_H__\r
+\r
+#include "lwip/arch.h"\r
+\r
+#include "lwip/opt.h"\r
+#include "lwip/pbuf.h"\r
+\r
+#include "lwip/ip_addr.h"\r
+#include "lwip/netif.h"\r
+\r
+#define ICMP_ER 0      /* echo reply */\r
+#define ICMP_DUR 3     /* destination unreachable */\r
+#define ICMP_SQ 4      /* source quench */\r
+#define ICMP_RD 5      /* redirect */\r
+#define ICMP_ECHO 8    /* echo */\r
+#define ICMP_TE 11     /* time exceeded */\r
+#define ICMP_PP 12     /* parameter problem */\r
+#define ICMP_TS 13     /* timestamp */\r
+#define ICMP_TSR 14    /* timestamp reply */\r
+#define ICMP_IRQ 15    /* information request */\r
+#define ICMP_IR 16     /* information reply */\r
+\r
+enum icmp_dur_type {\r
+  ICMP_DUR_NET = 0,    /* net unreachable */\r
+  ICMP_DUR_HOST = 1,   /* host unreachable */\r
+  ICMP_DUR_PROTO = 2,  /* protocol unreachable */\r
+  ICMP_DUR_PORT = 3,   /* port unreachable */\r
+  ICMP_DUR_FRAG = 4,   /* fragmentation needed and DF set */\r
+  ICMP_DUR_SR = 5      /* source route failed */\r
+};\r
+\r
+enum icmp_te_type {\r
+  ICMP_TE_TTL = 0,     /* time to live exceeded in transit */\r
+  ICMP_TE_FRAG = 1     /* fragment reassembly time exceeded */\r
+};\r
+\r
+void icmp_input(struct pbuf *p, struct netif *inp);\r
+\r
+void icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t);\r
+void icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t);\r
+\r
+#ifdef PACK_STRUCT_USE_INCLUDES\r
+#  include "arch/bpstruct.h"\r
+#endif\r
+PACK_STRUCT_BEGIN\r
+struct icmp_echo_hdr {\r
+  PACK_STRUCT_FIELD(u16_t _type_code);\r
+  PACK_STRUCT_FIELD(u16_t chksum);\r
+  PACK_STRUCT_FIELD(u16_t id);\r
+  PACK_STRUCT_FIELD(u16_t seqno);\r
+} PACK_STRUCT_STRUCT;\r
+PACK_STRUCT_END\r
+\r
+PACK_STRUCT_BEGIN\r
+struct icmp_dur_hdr {\r
+  PACK_STRUCT_FIELD(u16_t _type_code);\r
+  PACK_STRUCT_FIELD(u16_t chksum);\r
+  PACK_STRUCT_FIELD(u32_t unused);\r
+} PACK_STRUCT_STRUCT;\r
+PACK_STRUCT_END\r
+\r
+PACK_STRUCT_BEGIN\r
+struct icmp_te_hdr {\r
+  PACK_STRUCT_FIELD(u16_t _type_code);\r
+  PACK_STRUCT_FIELD(u16_t chksum);\r
+  PACK_STRUCT_FIELD(u32_t unused);\r
+} PACK_STRUCT_STRUCT;\r
+PACK_STRUCT_END\r
+#ifdef PACK_STRUCT_USE_INCLUDES\r
+#  include "arch/epstruct.h"\r
+#endif\r
+\r
+#define ICMPH_TYPE(hdr) (ntohs((hdr)->_type_code) >> 8)\r
+#define ICMPH_CODE(hdr) (ntohs((hdr)->_type_code) & 0xff)\r
+\r
+#define ICMPH_TYPE_SET(hdr, type) ((hdr)->_type_code = htons(ICMPH_CODE(hdr) | ((type) << 8)))\r
+#define ICMPH_CODE_SET(hdr, code) ((hdr)->_type_code = htons((code) | (ICMPH_TYPE(hdr) << 8)))\r
+\r
+#endif /* __LWIP_ICMP_H__ */\r
+    \r
index beab85183a7dca9442c75c5702edd92cc2ae1290..21463accf7c102cfbcd3b7034f5f4fc7b8944e09 100644 (file)
@@ -1,84 +1,84 @@
-/*
- * 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 <adam@sics.se>
- *
- */
-#ifndef __LWIP_INET_H__
-#define __LWIP_INET_H__
-
-#include "lwip/arch.h"
-
-#include "lwip/opt.h"
-#include "lwip/pbuf.h"
-#include "lwip/ip_addr.h"
-
-u16_t inet_chksum(void *dataptr, u16_t len);
-u16_t inet_chksum_pbuf(struct pbuf *p);
-u16_t inet_chksum_pseudo(struct pbuf *p,
-       struct ip_addr *src, struct ip_addr *dest,
-       u8_t proto, u16_t proto_len);
-
-u32_t inet_addr(const char *cp);
-int inet_aton(const char *cp, struct in_addr *addr);
-char *inet_ntoa(struct in_addr addr); /* returns ptr to static buffer; not reentrant! */
-
-#ifdef htons
-#undef htons
-#endif /* htons */
-#ifdef htonl
-#undef htonl
-#endif /* htonl */
-#ifdef ntohs
-#undef ntohs
-#endif /* ntohs */
-#ifdef ntohl
-#undef ntohl
-#endif /* ntohl */
-
-#if BYTE_ORDER == BIG_ENDIAN
-#define htons(x) (x)
-#define ntohs(x) (x)
-#define htonl(x) (x)
-#define ntohl(x) (x)
-#else
-#ifdef LWIP_PREFIX_BYTEORDER_FUNCS
-/* workaround for naming collisions on some platforms */
-#define htons lwip_htons
-#define ntohs lwip_ntohs
-#define htonl lwip_htonl
-#define ntohl lwip_ntohl
-#endif
-u16_t htons(u16_t x);
-u16_t ntohs(u16_t x);
-u32_t htonl(u32_t x);
-u32_t ntohl(u32_t x);
-#endif
-
-#endif /* __LWIP_INET_H__ */
-
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+#ifndef __LWIP_INET_H__\r
+#define __LWIP_INET_H__\r
+\r
+#include "lwip/arch.h"\r
+\r
+#include "lwip/opt.h"\r
+#include "lwip/pbuf.h"\r
+#include "lwip/ip_addr.h"\r
+\r
+u16_t inet_chksum(void *dataptr, u16_t len);\r
+u16_t inet_chksum_pbuf(struct pbuf *p);\r
+u16_t inet_chksum_pseudo(struct pbuf *p,\r
+       struct ip_addr *src, struct ip_addr *dest,\r
+       u8_t proto, u16_t proto_len);\r
+\r
+u32_t inet_addr(const char *cp);\r
+int inet_aton(const char *cp, struct in_addr *addr);\r
+char *inet_ntoa(struct in_addr addr); /* returns ptr to static buffer; not reentrant! */\r
+\r
+#ifdef htons\r
+#undef htons\r
+#endif /* htons */\r
+#ifdef htonl\r
+#undef htonl\r
+#endif /* htonl */\r
+#ifdef ntohs\r
+#undef ntohs\r
+#endif /* ntohs */\r
+#ifdef ntohl\r
+#undef ntohl\r
+#endif /* ntohl */\r
+\r
+#if BYTE_ORDER == BIG_ENDIAN\r
+#define htons(x) (x)\r
+#define ntohs(x) (x)\r
+#define htonl(x) (x)\r
+#define ntohl(x) (x)\r
+#else\r
+#ifdef LWIP_PREFIX_BYTEORDER_FUNCS\r
+/* workaround for naming collisions on some platforms */\r
+#define htons lwip_htons\r
+#define ntohs lwip_ntohs\r
+#define htonl lwip_htonl\r
+#define ntohl lwip_ntohl\r
+#endif\r
+u16_t htons(u16_t x);\r
+u16_t ntohs(u16_t x);\r
+u32_t htonl(u32_t x);\r
+u32_t ntohl(u32_t x);\r
+#endif\r
+\r
+#endif /* __LWIP_INET_H__ */\r
+\r
index 4c15e1a0ea1eeac4cce3bccca5036fe82b12cfac..34ca7a8fc3a98bc76c68e01d0addffc741023063 100644 (file)
-/*
- * 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 <adam@sics.se>
- *
- */
-#ifndef __LWIP_IP_H__
-#define __LWIP_IP_H__
-
-#include "lwip/arch.h"
-
-#include "lwip/def.h"
-#include "lwip/pbuf.h"
-#include "lwip/ip_addr.h"
-
-#include "lwip/err.h"
-
-
-void ip_init(void);
-struct netif *ip_route(struct ip_addr *dest);
-err_t ip_input(struct pbuf *p, struct netif *inp);
-err_t ip_output(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
-               u8_t ttl, u8_t tos, u8_t proto);
-err_t ip_output_if(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
-                  u8_t ttl, u8_t tos, u8_t proto,
-       struct netif *netif);
-
-#define IP_HLEN 20
-
-#define IP_PROTO_ICMP 1
-#define IP_PROTO_UDP 17
-#define IP_PROTO_UDPLITE 170
-#define IP_PROTO_TCP 6
-
-/* This is passed as the destination address to ip_output_if (not
-   to ip_output), meaning that an IP header already is constructed
-   in the pbuf. This is used when TCP retransmits. */
-#ifdef IP_HDRINCL
-#undef IP_HDRINCL
-#endif /* IP_HDRINCL */
-#define IP_HDRINCL  NULL
-
-
-/* This is the common part of all PCB types. It needs to be at the
-   beginning of a PCB type definition. It is located here so that
-   changes to this common part are made in one location instead of
-   having to change all PCB structs. */
-#define IP_PCB struct ip_addr local_ip; \
-  struct ip_addr remote_ip; \
-   /* Socket options */  \
-  u16_t so_options;      \
-   /* Type Of Service */ \
-  u8_t tos;              \
-  /* Time To Live */     \
-  u8_t ttl
-
-/*
- * Option flags per-socket. These are the same like SO_XXX.
- */
-#define        SOF_DEBUG           (u16_t)0x0001U              /* turn on debugging info recording */
-#define        SOF_ACCEPTCONN  (u16_t)0x0002U          /* socket has had listen() */
-#define        SOF_REUSEADDR   (u16_t)0x0004U          /* allow local address reuse */
-#define        SOF_KEEPALIVE   (u16_t)0x0008U          /* keep connections alive */
-#define        SOF_DONTROUTE   (u16_t)0x0010U          /* just use interface addresses */
-#define        SOF_BROADCAST   (u16_t)0x0020U          /* permit sending of broadcast msgs */
-#define        SOF_USELOOPBACK (u16_t)0x0040U          /* bypass hardware when possible */
-#define        SOF_LINGER          (u16_t)0x0080U              /* linger on close if data present */
-#define        SOF_OOBINLINE   (u16_t)0x0100U          /* leave received OOB data in line */
-#define        SOF_REUSEPORT   (u16_t)0x0200U          /* allow local address & port reuse */
-
-
-
-#ifdef PACK_STRUCT_USE_INCLUDES
-#  include "arch/bpstruct.h"
-#endif
-PACK_STRUCT_BEGIN
-struct ip_hdr {
-  /* version / header length / type of service */
-  PACK_STRUCT_FIELD(u16_t _v_hl_tos);
-  /* total length */
-  PACK_STRUCT_FIELD(u16_t _len);
-  /* identification */
-  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 */
-  /* time to live / protocol*/
-  PACK_STRUCT_FIELD(u16_t _ttl_proto);
-  /* checksum */
-  PACK_STRUCT_FIELD(u16_t _chksum);
-  /* source and destination IP addresses */
-  PACK_STRUCT_FIELD(struct ip_addr src);
-  PACK_STRUCT_FIELD(struct ip_addr dest); 
-} PACK_STRUCT_STRUCT;
-PACK_STRUCT_END
-#ifdef PACK_STRUCT_USE_INCLUDES
-#  include "arch/epstruct.h"
-#endif
-
-#define IPH_V(hdr)  (ntohs((hdr)->_v_hl_tos) >> 12)
-#define IPH_HL(hdr) ((ntohs((hdr)->_v_hl_tos) >> 8) & 0x0f)
-#define IPH_TOS(hdr) (ntohs((hdr)->_v_hl_tos) & 0xff)
-#define IPH_LEN(hdr) ((hdr)->_len)
-#define IPH_ID(hdr) ((hdr)->_id)
-#define IPH_OFFSET(hdr) ((hdr)->_offset)
-#define IPH_TTL(hdr) (ntohs((hdr)->_ttl_proto) >> 8)
-#define IPH_PROTO(hdr) (ntohs((hdr)->_ttl_proto) & 0xff)
-#define IPH_CHKSUM(hdr) ((hdr)->_chksum)
-
-#define IPH_VHLTOS_SET(hdr, v, hl, tos) (hdr)->_v_hl_tos = (htons(((v) << 12) | ((hl) << 8) | (tos)))
-#define IPH_LEN_SET(hdr, len) (hdr)->_len = (len)
-#define IPH_ID_SET(hdr, id) (hdr)->_id = (id)
-#define IPH_OFFSET_SET(hdr, off) (hdr)->_offset = (off)
-#define IPH_TTL_SET(hdr, ttl) (hdr)->_ttl_proto = (htons(IPH_PROTO(hdr) | ((ttl) << 8)))
-#define IPH_PROTO_SET(hdr, proto) (hdr)->_ttl_proto = (htons((proto) | (IPH_TTL(hdr) << 8)))
-#define IPH_CHKSUM_SET(hdr, chksum) (hdr)->_chksum = (chksum)
-
-#if IP_DEBUG
-void ip_debug_print(struct pbuf *p);
-#else
-#define ip_debug_print(p)
-#endif /* IP_DEBUG */
-
-#endif /* __LWIP_IP_H__ */
-
-
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+#ifndef __LWIP_IP_H__\r
+#define __LWIP_IP_H__\r
+\r
+#include "lwip/arch.h"\r
+\r
+#include "lwip/def.h"\r
+#include "lwip/pbuf.h"\r
+#include "lwip/ip_addr.h"\r
+\r
+#include "lwip/err.h"\r
+\r
+\r
+void ip_init(void);\r
+struct netif *ip_route(struct ip_addr *dest);\r
+err_t ip_input(struct pbuf *p, struct netif *inp);\r
+err_t ip_output(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,\r
+               u8_t ttl, u8_t tos, u8_t proto);\r
+err_t ip_output_if(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,\r
+                  u8_t ttl, u8_t tos, u8_t proto,\r
+       struct netif *netif);\r
+\r
+#define IP_HLEN 20\r
+\r
+#define IP_PROTO_ICMP 1\r
+#define IP_PROTO_UDP 17\r
+#define IP_PROTO_UDPLITE 170\r
+#define IP_PROTO_TCP 6\r
+\r
+/* This is passed as the destination address to ip_output_if (not\r
+   to ip_output), meaning that an IP header already is constructed\r
+   in the pbuf. This is used when TCP retransmits. */\r
+#ifdef IP_HDRINCL\r
+#undef IP_HDRINCL\r
+#endif /* IP_HDRINCL */\r
+#define IP_HDRINCL  NULL\r
+\r
+\r
+/* This is the common part of all PCB types. It needs to be at the\r
+   beginning of a PCB type definition. It is located here so that\r
+   changes to this common part are made in one location instead of\r
+   having to change all PCB structs. */\r
+#define IP_PCB struct ip_addr local_ip; \\r
+  struct ip_addr remote_ip; \\r
+   /* Socket options */  \\r
+  u16_t so_options;      \\r
+   /* Type Of Service */ \\r
+  u8_t tos;              \\r
+  /* Time To Live */     \\r
+  u8_t ttl\r
+\r
+/*\r
+ * Option flags per-socket. These are the same like SO_XXX.\r
+ */\r
+#define        SOF_DEBUG           (u16_t)0x0001U              /* turn on debugging info recording */\r
+#define        SOF_ACCEPTCONN  (u16_t)0x0002U          /* socket has had listen() */\r
+#define        SOF_REUSEADDR   (u16_t)0x0004U          /* allow local address reuse */\r
+#define        SOF_KEEPALIVE   (u16_t)0x0008U          /* keep connections alive */\r
+#define        SOF_DONTROUTE   (u16_t)0x0010U          /* just use interface addresses */\r
+#define        SOF_BROADCAST   (u16_t)0x0020U          /* permit sending of broadcast msgs */\r
+#define        SOF_USELOOPBACK (u16_t)0x0040U          /* bypass hardware when possible */\r
+#define        SOF_LINGER          (u16_t)0x0080U              /* linger on close if data present */\r
+#define        SOF_OOBINLINE   (u16_t)0x0100U          /* leave received OOB data in line */\r
+#define        SOF_REUSEPORT   (u16_t)0x0200U          /* allow local address & port reuse */\r
+\r
+\r
+\r
+#ifdef PACK_STRUCT_USE_INCLUDES\r
+#  include "arch/bpstruct.h"\r
+#endif\r
+PACK_STRUCT_BEGIN\r
+struct ip_hdr {\r
+  /* version / header length / type of service */\r
+  PACK_STRUCT_FIELD(u16_t _v_hl_tos);\r
+  /* total length */\r
+  PACK_STRUCT_FIELD(u16_t _len);\r
+  /* identification */\r
+  PACK_STRUCT_FIELD(u16_t _id);\r
+  /* fragment offset field */\r
+  PACK_STRUCT_FIELD(u16_t _offset);\r
+#define IP_RF 0x8000        /* reserved fragment flag */\r
+#define IP_DF 0x4000        /* dont fragment flag */\r
+#define IP_MF 0x2000        /* more fragments flag */\r
+#define IP_OFFMASK 0x1fff   /* mask for fragmenting bits */\r
+  /* time to live / protocol*/\r
+  PACK_STRUCT_FIELD(u16_t _ttl_proto);\r
+  /* checksum */\r
+  PACK_STRUCT_FIELD(u16_t _chksum);\r
+  /* source and destination IP addresses */\r
+  PACK_STRUCT_FIELD(struct ip_addr src);\r
+  PACK_STRUCT_FIELD(struct ip_addr dest); \r
+} PACK_STRUCT_STRUCT;\r
+PACK_STRUCT_END\r
+#ifdef PACK_STRUCT_USE_INCLUDES\r
+#  include "arch/epstruct.h"\r
+#endif\r
+\r
+#define IPH_V(hdr)  (ntohs((hdr)->_v_hl_tos) >> 12)\r
+#define IPH_HL(hdr) ((ntohs((hdr)->_v_hl_tos) >> 8) & 0x0f)\r
+#define IPH_TOS(hdr) (ntohs((hdr)->_v_hl_tos) & 0xff)\r
+#define IPH_LEN(hdr) ((hdr)->_len)\r
+#define IPH_ID(hdr) ((hdr)->_id)\r
+#define IPH_OFFSET(hdr) ((hdr)->_offset)\r
+#define IPH_TTL(hdr) (ntohs((hdr)->_ttl_proto) >> 8)\r
+#define IPH_PROTO(hdr) (ntohs((hdr)->_ttl_proto) & 0xff)\r
+#define IPH_CHKSUM(hdr) ((hdr)->_chksum)\r
+\r
+#define IPH_VHLTOS_SET(hdr, v, hl, tos) (hdr)->_v_hl_tos = (htons(((v) << 12) | ((hl) << 8) | (tos)))\r
+#define IPH_LEN_SET(hdr, len) (hdr)->_len = (len)\r
+#define IPH_ID_SET(hdr, id) (hdr)->_id = (id)\r
+#define IPH_OFFSET_SET(hdr, off) (hdr)->_offset = (off)\r
+#define IPH_TTL_SET(hdr, ttl) (hdr)->_ttl_proto = (htons(IPH_PROTO(hdr) | ((ttl) << 8)))\r
+#define IPH_PROTO_SET(hdr, proto) (hdr)->_ttl_proto = (htons((proto) | (IPH_TTL(hdr) << 8)))\r
+#define IPH_CHKSUM_SET(hdr, chksum) (hdr)->_chksum = (chksum)\r
+\r
+#if IP_DEBUG\r
+void ip_debug_print(struct pbuf *p);\r
+#else\r
+#define ip_debug_print(p)\r
+#endif /* IP_DEBUG */\r
+\r
+#endif /* __LWIP_IP_H__ */\r
+\r
+\r
index 0ef99937b39a878b640bff6f10d5fcff0af1f8c7..2fe12f7d86b276bb840a7490f9691e30f7fc9107 100644 (file)
-/*
- * 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 <adam@sics.se>
- *
- */
-#ifndef __LWIP_IP_ADDR_H__
-#define __LWIP_IP_ADDR_H__
-
-#include "lwip/arch.h"
-
-#ifdef PACK_STRUCT_USE_INCLUDES
-#  include "arch/bpstruct.h"
-#endif
-PACK_STRUCT_BEGIN
-struct ip_addr {
-  PACK_STRUCT_FIELD(u32_t addr);
-} PACK_STRUCT_STRUCT;
-PACK_STRUCT_END
-#ifdef PACK_STRUCT_USE_INCLUDES
-#  include "arch/epstruct.h"
-#endif
-
-#ifdef PACK_STRUCT_USE_INCLUDES
-#  include "arch/bpstruct.h"
-#endif
-PACK_STRUCT_BEGIN
-struct ip_addr2 {
-  PACK_STRUCT_FIELD(u16_t addrw[2]);
-} PACK_STRUCT_STRUCT;
-PACK_STRUCT_END
-#ifdef PACK_STRUCT_USE_INCLUDES
-#  include "arch/epstruct.h"
-#endif
-
-/* For compatibility with BSD code */
-struct in_addr {
-  u32_t s_addr;
-};
-
-struct netif;
-
-extern const struct ip_addr ip_addr_any;
-extern const struct ip_addr ip_addr_broadcast;
-
-/** IP_ADDR_ can be used as a fixed IP address
- *  for the wildcard and the broadcast address
- */
-#define IP_ADDR_ANY ((struct ip_addr *)&ip_addr_any)
-#define IP_ADDR_BROADCAST ((struct ip_addr *)&ip_addr_broadcast)
-
-#define INADDR_NONE    ((u32_t) 0xffffffff)  /* 255.255.255.255 */
-#define INADDR_LOOPBACK    ((u32_t) 0x7f000001)  /* 127.0.0.1 */
-
-/* Definitions of the bits in an Internet address integer.
-
-   On subnets, host and network parts are found according to
-   the subnet mask, not these masks.  */
-
-#define  IN_CLASSA(a)    ((((u32_t)(a)) & 0x80000000) == 0)
-#define  IN_CLASSA_NET    0xff000000
-#define  IN_CLASSA_NSHIFT  24
-#define  IN_CLASSA_HOST    (0xffffffff & ~IN_CLASSA_NET)
-#define  IN_CLASSA_MAX    128
-
-#define  IN_CLASSB(a)    ((((u32_t)(a)) & 0xc0000000) == 0x80000000)
-#define  IN_CLASSB_NET    0xffff0000
-#define  IN_CLASSB_NSHIFT  16
-#define  IN_CLASSB_HOST    (0xffffffff & ~IN_CLASSB_NET)
-#define  IN_CLASSB_MAX    65536
-
-#define  IN_CLASSC(a)    ((((u32_t)(a)) & 0xe0000000) == 0xc0000000)
-#define  IN_CLASSC_NET    0xffffff00
-#define  IN_CLASSC_NSHIFT  8
-#define  IN_CLASSC_HOST    (0xffffffff & ~IN_CLASSC_NET)
-
-#define IN_CLASSD(a)        (((u32_t)(a) & 0xf0000000) == 0xe0000000)
-#define IN_CLASSD_NET       0xf0000000  /* These ones aren't really */
-#define IN_CLASSD_NSHIFT    28      /* net and host fields, but */
-#define IN_CLASSD_HOST      0x0fffffff  /* routing needn't know.    */
-#define IN_MULTICAST(a)     IN_CLASSD(a)
-
-#define IN_EXPERIMENTAL(a)  (((u32_t)(a) & 0xf0000000) == 0xf0000000)
-#define IN_BADCLASS(a)      (((u32_t)(a) & 0xf0000000) == 0xf0000000)
-
-#define IN_LOOPBACKNET      127         /* official! */
-
-
-#define IP4_ADDR(ipaddr, a,b,c,d) (ipaddr)->addr = htonl(((u32_t)(a & 0xff) << 24) | ((u32_t)(b & 0xff) << 16) | \
-                                                         ((u32_t)(c & 0xff) << 8) | (u32_t)(d & 0xff))
-
-#define ip_addr_set(dest, src) (dest)->addr = \
-                               ((src) == NULL? 0:\
-                               (src)->addr)
-/**
- * Determine if two address are on the same network.
- *
- * @arg addr1 IP address 1
- * @arg addr2 IP address 2
- * @arg mask network identifier mask
- * @return !0 if the network identifiers of both address match
- */
-#define ip_addr_netcmp(addr1, addr2, mask) (((addr1)->addr & \
-                                              (mask)->addr) == \
-                                             ((addr2)->addr & \
-                                              (mask)->addr))
-#define ip_addr_cmp(addr1, addr2) ((addr1)->addr == (addr2)->addr)
-
-#define ip_addr_isany(addr1) ((addr1) == NULL || (addr1)->addr == 0)
-
-u8_t ip_addr_isbroadcast(struct ip_addr *, struct netif *);
-
-#define ip_addr_ismulticast(addr1) (((addr1)->addr & ntohl(0xf0000000)) == ntohl(0xe0000000))
-
-
-#define ip_addr_debug_print(debug, ipaddr) LWIP_DEBUGF(debug, ("%u.%u.%u.%u", \
-        ipaddr?(unsigned int)(ntohl((ipaddr)->addr) >> 24) & 0xff:0, \
-        ipaddr?(unsigned int)(ntohl((ipaddr)->addr) >> 16) & 0xff:0, \
-        ipaddr?(unsigned int)(ntohl((ipaddr)->addr) >> 8) & 0xff:0, \
-        ipaddr?(unsigned int)ntohl((ipaddr)->addr) & 0xff:0U))
-
-/* cast to unsigned int, as it is used as argument to printf functions
- * which expect integer arguments */
-#define ip4_addr1(ipaddr) ((unsigned int)(ntohl((ipaddr)->addr) >> 24) & 0xff)
-#define ip4_addr2(ipaddr) ((unsigned int)(ntohl((ipaddr)->addr) >> 16) & 0xff)
-#define ip4_addr3(ipaddr) ((unsigned int)(ntohl((ipaddr)->addr) >> 8) & 0xff)
-#define ip4_addr4(ipaddr) ((unsigned int)(ntohl((ipaddr)->addr)) & 0xff)
-#endif /* __LWIP_IP_ADDR_H__ */
-
-
-
-
-
-
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without modification,\r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED\r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT\r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY\r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ *\r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+#ifndef __LWIP_IP_ADDR_H__\r
+#define __LWIP_IP_ADDR_H__\r
+\r
+#include "lwip/arch.h"\r
+\r
+#ifdef PACK_STRUCT_USE_INCLUDES\r
+#  include "arch/bpstruct.h"\r
+#endif\r
+PACK_STRUCT_BEGIN\r
+struct ip_addr {\r
+  PACK_STRUCT_FIELD(u32_t addr);\r
+} PACK_STRUCT_STRUCT;\r
+PACK_STRUCT_END\r
+#ifdef PACK_STRUCT_USE_INCLUDES\r
+#  include "arch/epstruct.h"\r
+#endif\r
+\r
+#ifdef PACK_STRUCT_USE_INCLUDES\r
+#  include "arch/bpstruct.h"\r
+#endif\r
+PACK_STRUCT_BEGIN\r
+struct ip_addr2 {\r
+  PACK_STRUCT_FIELD(u16_t addrw[2]);\r
+} PACK_STRUCT_STRUCT;\r
+PACK_STRUCT_END\r
+#ifdef PACK_STRUCT_USE_INCLUDES\r
+#  include "arch/epstruct.h"\r
+#endif\r
+\r
+/* For compatibility with BSD code */\r
+struct in_addr {\r
+  u32_t s_addr;\r
+};\r
+\r
+struct netif;\r
+\r
+extern const struct ip_addr ip_addr_any;\r
+extern const struct ip_addr ip_addr_broadcast;\r
+\r
+/** IP_ADDR_ can be used as a fixed IP address\r
+ *  for the wildcard and the broadcast address\r
+ */\r
+#define IP_ADDR_ANY ((struct ip_addr *)&ip_addr_any)\r
+#define IP_ADDR_BROADCAST ((struct ip_addr *)&ip_addr_broadcast)\r
+\r
+#define INADDR_NONE    ((u32_t) 0xffffffff)  /* 255.255.255.255 */\r
+#define INADDR_LOOPBACK    ((u32_t) 0x7f000001)  /* 127.0.0.1 */\r
+\r
+/* Definitions of the bits in an Internet address integer.\r
+\r
+   On subnets, host and network parts are found according to\r
+   the subnet mask, not these masks.  */\r
+\r
+#define  IN_CLASSA(a)    ((((u32_t)(a)) & 0x80000000) == 0)\r
+#define  IN_CLASSA_NET    0xff000000\r
+#define  IN_CLASSA_NSHIFT  24\r
+#define  IN_CLASSA_HOST    (0xffffffff & ~IN_CLASSA_NET)\r
+#define  IN_CLASSA_MAX    128\r
+\r
+#define  IN_CLASSB(a)    ((((u32_t)(a)) & 0xc0000000) == 0x80000000)\r
+#define  IN_CLASSB_NET    0xffff0000\r
+#define  IN_CLASSB_NSHIFT  16\r
+#define  IN_CLASSB_HOST    (0xffffffff & ~IN_CLASSB_NET)\r
+#define  IN_CLASSB_MAX    65536\r
+\r
+#define  IN_CLASSC(a)    ((((u32_t)(a)) & 0xe0000000) == 0xc0000000)\r
+#define  IN_CLASSC_NET    0xffffff00\r
+#define  IN_CLASSC_NSHIFT  8\r
+#define  IN_CLASSC_HOST    (0xffffffff & ~IN_CLASSC_NET)\r
+\r
+#define IN_CLASSD(a)        (((u32_t)(a) & 0xf0000000) == 0xe0000000)\r
+#define IN_CLASSD_NET       0xf0000000  /* These ones aren't really */\r
+#define IN_CLASSD_NSHIFT    28      /* net and host fields, but */\r
+#define IN_CLASSD_HOST      0x0fffffff  /* routing needn't know.    */\r
+#define IN_MULTICAST(a)     IN_CLASSD(a)\r
+\r
+#define IN_EXPERIMENTAL(a)  (((u32_t)(a) & 0xf0000000) == 0xf0000000)\r
+#define IN_BADCLASS(a)      (((u32_t)(a) & 0xf0000000) == 0xf0000000)\r
+\r
+#define IN_LOOPBACKNET      127         /* official! */\r
+\r
+\r
+#define IP4_ADDR(ipaddr, a,b,c,d) (ipaddr)->addr = htonl(((u32_t)(a & 0xff) << 24) | ((u32_t)(b & 0xff) << 16) | \\r
+                                                         ((u32_t)(c & 0xff) << 8) | (u32_t)(d & 0xff))\r
+\r
+#define ip_addr_set(dest, src) (dest)->addr = \\r
+                               ((src) == NULL? 0:\\r
+                               (src)->addr)\r
+/**\r
+ * Determine if two address are on the same network.\r
+ *\r
+ * @arg addr1 IP address 1\r
+ * @arg addr2 IP address 2\r
+ * @arg mask network identifier mask\r
+ * @return !0 if the network identifiers of both address match\r
+ */\r
+#define ip_addr_netcmp(addr1, addr2, mask) (((addr1)->addr & \\r
+                                              (mask)->addr) == \\r
+                                             ((addr2)->addr & \\r
+                                              (mask)->addr))\r
+#define ip_addr_cmp(addr1, addr2) ((addr1)->addr == (addr2)->addr)\r
+\r
+#define ip_addr_isany(addr1) ((addr1) == NULL || (addr1)->addr == 0)\r
+\r
+u8_t ip_addr_isbroadcast(struct ip_addr *, struct netif *);\r
+\r
+#define ip_addr_ismulticast(addr1) (((addr1)->addr & ntohl(0xf0000000)) == ntohl(0xe0000000))\r
+\r
+\r
+#define ip_addr_debug_print(debug, ipaddr) LWIP_DEBUGF(debug, ("%u.%u.%u.%u", \\r
+        ipaddr?(unsigned int)(ntohl((ipaddr)->addr) >> 24) & 0xff:0, \\r
+        ipaddr?(unsigned int)(ntohl((ipaddr)->addr) >> 16) & 0xff:0, \\r
+        ipaddr?(unsigned int)(ntohl((ipaddr)->addr) >> 8) & 0xff:0, \\r
+        ipaddr?(unsigned int)ntohl((ipaddr)->addr) & 0xff:0U))\r
+\r
+/* cast to unsigned int, as it is used as argument to printf functions\r
+ * which expect integer arguments */\r
+#define ip4_addr1(ipaddr) ((unsigned int)(ntohl((ipaddr)->addr) >> 24) & 0xff)\r
+#define ip4_addr2(ipaddr) ((unsigned int)(ntohl((ipaddr)->addr) >> 16) & 0xff)\r
+#define ip4_addr3(ipaddr) ((unsigned int)(ntohl((ipaddr)->addr) >> 8) & 0xff)\r
+#define ip4_addr4(ipaddr) ((unsigned int)(ntohl((ipaddr)->addr)) & 0xff)\r
+#endif /* __LWIP_IP_ADDR_H__ */\r
+\r
+\r
+\r
+\r
+\r
+\r
index 654b4d7f8aa1ee4bc3c2f3538dd04bd80abc6ff1..ea4d2c4970d9f6ebfa93831bb9d3eebe230a7c31 100644 (file)
@@ -1,46 +1,46 @@
-/*
- * 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: Jani Monoses <jani@iv.ro>
- *
- */
-
-#ifndef __LWIP_IP_FRAG_H__
-#define __LWIP_IP_FRAG_H__
-
-#include "lwip/err.h"
-#include "lwip/pbuf.h"
-#include "lwip/netif.h"
-#include "lwip/ip_addr.h"
-
-struct pbuf * ip_reass(struct pbuf *);
-err_t ip_frag(struct pbuf *, struct netif *, struct ip_addr *);
-
-#endif /* __LWIP_IP_FRAG_H__ */
-
-
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Jani Monoses <jani@iv.ro>\r
+ *\r
+ */\r
+\r
+#ifndef __LWIP_IP_FRAG_H__\r
+#define __LWIP_IP_FRAG_H__\r
+\r
+#include "lwip/err.h"\r
+#include "lwip/pbuf.h"\r
+#include "lwip/netif.h"\r
+#include "lwip/ip_addr.h"\r
+\r
+struct pbuf * ip_reass(struct pbuf *);\r
+err_t ip_frag(struct pbuf *, struct netif *, struct ip_addr *);\r
+\r
+#endif /* __LWIP_IP_FRAG_H__ */\r
+\r
+\r
index 2b6adb1222a9a8fd78b6f1d42b4608b2abcf4335..9c63a3f45ae980b1dfbd0f40234dc7ecc9919b43 100644 (file)
@@ -1,90 +1,90 @@
-/*
- * 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 <adam@sics.se>
- *
- */
-#ifndef __LWIP_ICMP_H__
-#define __LWIP_ICMP_H__
-
-#include "lwip/arch.h"
-
-#include "lwip/opt.h"
-#include "lwip/pbuf.h"
-
-#include "lwip/netif.h"
-
-#define ICMP6_DUR  1
-#define ICMP6_TE   3
-#define ICMP6_ECHO 128    /* echo */
-#define ICMP6_ER   129      /* echo reply */
-
-
-enum icmp_dur_type {
-  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 */
-};
-
-enum icmp_te_type {
-  ICMP_TE_TTL = 0,     /* time to live exceeded in transit */
-  ICMP_TE_FRAG = 1     /* fragment reassembly time exceeded */
-};
-
-void icmp_input(struct pbuf *p, struct netif *inp);
-
-void icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t);
-void icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t);
-
-struct icmp_echo_hdr {
-  u8_t type;
-  u8_t icode;
-  u16_t chksum;
-  u16_t id;
-  u16_t seqno;
-};
-
-struct icmp_dur_hdr {
-  u8_t type;
-  u8_t icode;
-  u16_t chksum;
-  u32_t unused;
-};
-
-struct icmp_te_hdr {
-  u8_t type;
-  u8_t icode;
-  u16_t chksum;
-  u32_t unused;
-};
-
-#endif /* __LWIP_ICMP_H__ */
-    
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+#ifndef __LWIP_ICMP_H__\r
+#define __LWIP_ICMP_H__\r
+\r
+#include "lwip/arch.h"\r
+\r
+#include "lwip/opt.h"\r
+#include "lwip/pbuf.h"\r
+\r
+#include "lwip/netif.h"\r
+\r
+#define ICMP6_DUR  1\r
+#define ICMP6_TE   3\r
+#define ICMP6_ECHO 128    /* echo */\r
+#define ICMP6_ER   129      /* echo reply */\r
+\r
+\r
+enum icmp_dur_type {\r
+  ICMP_DUR_NET = 0,    /* net unreachable */\r
+  ICMP_DUR_HOST = 1,   /* host unreachable */\r
+  ICMP_DUR_PROTO = 2,  /* protocol unreachable */\r
+  ICMP_DUR_PORT = 3,   /* port unreachable */\r
+  ICMP_DUR_FRAG = 4,   /* fragmentation needed and DF set */\r
+  ICMP_DUR_SR = 5      /* source route failed */\r
+};\r
+\r
+enum icmp_te_type {\r
+  ICMP_TE_TTL = 0,     /* time to live exceeded in transit */\r
+  ICMP_TE_FRAG = 1     /* fragment reassembly time exceeded */\r
+};\r
+\r
+void icmp_input(struct pbuf *p, struct netif *inp);\r
+\r
+void icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t);\r
+void icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t);\r
+\r
+struct icmp_echo_hdr {\r
+  u8_t type;\r
+  u8_t icode;\r
+  u16_t chksum;\r
+  u16_t id;\r
+  u16_t seqno;\r
+};\r
+\r
+struct icmp_dur_hdr {\r
+  u8_t type;\r
+  u8_t icode;\r
+  u16_t chksum;\r
+  u32_t unused;\r
+};\r
+\r
+struct icmp_te_hdr {\r
+  u8_t type;\r
+  u8_t icode;\r
+  u16_t chksum;\r
+  u32_t unused;\r
+};\r
+\r
+#endif /* __LWIP_ICMP_H__ */\r
+    \r
index 3cdd7407a62410867c180cfcd27813d40234994b..b13ce57b7713c6395fd64e49af86bdcf28e79466 100644 (file)
@@ -1,62 +1,62 @@
-/*
- * 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 <adam@sics.se>
- *
- */
-#ifndef __LWIP_INET_H__
-#define __LWIP_INET_H__
-
-#include "lwip/arch.h"
-
-#include "lwip/opt.h"
-#include "lwip/pbuf.h"
-#include "lwip/ip_addr.h"
-
-u16_t inet_chksum(void *data, u16_t len);
-u16_t inet_chksum_pbuf(struct pbuf *p);
-u16_t inet_chksum_pseudo(struct pbuf *p,
-       struct ip_addr *src, struct ip_addr *dest,
-       u8_t proto, u32_t proto_len);
-
-u32_t inet_addr(const char *cp);
-int inet_aton(const char *cp, struct in_addr *addr);
-
-#ifndef _MACHINE_ENDIAN_H_
-#ifndef _NETINET_IN_H
-#ifndef _LINUX_BYTEORDER_GENERIC_H
-u16_t htons(u16_t n);
-u16_t ntohs(u16_t n);
-u32_t htonl(u32_t n);
-u32_t ntohl(u32_t n);
-#endif /* _LINUX_BYTEORDER_GENERIC_H */
-#endif /* _NETINET_IN_H */
-#endif /* _MACHINE_ENDIAN_H_ */
-
-#endif /* __LWIP_INET_H__ */
-
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+#ifndef __LWIP_INET_H__\r
+#define __LWIP_INET_H__\r
+\r
+#include "lwip/arch.h"\r
+\r
+#include "lwip/opt.h"\r
+#include "lwip/pbuf.h"\r
+#include "lwip/ip_addr.h"\r
+\r
+u16_t inet_chksum(void *data, u16_t len);\r
+u16_t inet_chksum_pbuf(struct pbuf *p);\r
+u16_t inet_chksum_pseudo(struct pbuf *p,\r
+       struct ip_addr *src, struct ip_addr *dest,\r
+       u8_t proto, u32_t proto_len);\r
+\r
+u32_t inet_addr(const char *cp);\r
+int inet_aton(const char *cp, struct in_addr *addr);\r
+\r
+#ifndef _MACHINE_ENDIAN_H_\r
+#ifndef _NETINET_IN_H\r
+#ifndef _LINUX_BYTEORDER_GENERIC_H\r
+u16_t htons(u16_t n);\r
+u16_t ntohs(u16_t n);\r
+u32_t htonl(u32_t n);\r
+u32_t ntohl(u32_t n);\r
+#endif /* _LINUX_BYTEORDER_GENERIC_H */\r
+#endif /* _NETINET_IN_H */\r
+#endif /* _MACHINE_ENDIAN_H_ */\r
+\r
+#endif /* __LWIP_INET_H__ */\r
+\r
index 432ca36e05f3c94084655d06203d27c3aaa75847..6c4c50960c2be9bfa7c84974ed0b39ec66ea4718 100644 (file)
@@ -1,96 +1,96 @@
-/*
- * 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 <adam@sics.se>
- *
- */
-#ifndef __LWIP_IP_H__
-#define __LWIP_IP_H__
-
-#include "lwip/opt.h"
-#include "lwip/def.h"
-#include "lwip/pbuf.h"
-#include "lwip/ip_addr.h"
-
-#include "lwip/err.h"
-
-#define IP_HLEN 40
-
-#define IP_PROTO_ICMP 58
-#define IP_PROTO_UDP 17
-#define IP_PROTO_UDPLITE 170
-#define IP_PROTO_TCP 6
-
-/* This is passed as the destination address to ip_output_if (not
-   to ip_output), meaning that an IP header already is constructed
-   in the pbuf. This is used when TCP retransmits. */
-#ifdef IP_HDRINCL
-#undef IP_HDRINCL
-#endif /* IP_HDRINCL */
-#define IP_HDRINCL  NULL
-
-
-/* The IPv6 header. */
-struct ip_hdr {
-#if BYTE_ORDER == LITTLE_ENDIAN
-  u8_t tclass1:4, v:4;
-  u8_t flow1:4, tclass2:4;  
-#else
-  u8_t v:4, tclass1:4;
-  u8_t tclass2:8, flow1:4;
-#endif
-  u16_t flow2;
-  u16_t len;                /* payload length */
-  u8_t nexthdr;             /* next header */
-  u8_t hoplim;              /* hop limit (TTL) */
-  struct ip_addr src, dest;          /* source and destination IP addresses */
-};
-
-void ip_init(void);
-
-#include "lwip/netif.h"
-
-struct netif *ip_route(struct ip_addr *dest);
-
-void ip_input(struct pbuf *p, struct netif *inp);
-
-/* source and destination addresses in network byte order, please */
-err_t ip_output(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
-         unsigned char ttl, unsigned char proto);
-
-err_t ip_output_if(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
-      unsigned char ttl, unsigned char proto,
-      struct netif *netif);
-
-#if IP_DEBUG
-void ip_debug_print(struct pbuf *p);
-#endif /* IP_DEBUG */
-
-#endif /* __LWIP_IP_H__ */
-
-
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+#ifndef __LWIP_IP_H__\r
+#define __LWIP_IP_H__\r
+\r
+#include "lwip/opt.h"\r
+#include "lwip/def.h"\r
+#include "lwip/pbuf.h"\r
+#include "lwip/ip_addr.h"\r
+\r
+#include "lwip/err.h"\r
+\r
+#define IP_HLEN 40\r
+\r
+#define IP_PROTO_ICMP 58\r
+#define IP_PROTO_UDP 17\r
+#define IP_PROTO_UDPLITE 170\r
+#define IP_PROTO_TCP 6\r
+\r
+/* This is passed as the destination address to ip_output_if (not\r
+   to ip_output), meaning that an IP header already is constructed\r
+   in the pbuf. This is used when TCP retransmits. */\r
+#ifdef IP_HDRINCL\r
+#undef IP_HDRINCL\r
+#endif /* IP_HDRINCL */\r
+#define IP_HDRINCL  NULL\r
+\r
+\r
+/* The IPv6 header. */\r
+struct ip_hdr {\r
+#if BYTE_ORDER == LITTLE_ENDIAN\r
+  u8_t tclass1:4, v:4;\r
+  u8_t flow1:4, tclass2:4;  \r
+#else\r
+  u8_t v:4, tclass1:4;\r
+  u8_t tclass2:8, flow1:4;\r
+#endif\r
+  u16_t flow2;\r
+  u16_t len;                /* payload length */\r
+  u8_t nexthdr;             /* next header */\r
+  u8_t hoplim;              /* hop limit (TTL) */\r
+  struct ip_addr src, dest;          /* source and destination IP addresses */\r
+};\r
+\r
+void ip_init(void);\r
+\r
+#include "lwip/netif.h"\r
+\r
+struct netif *ip_route(struct ip_addr *dest);\r
+\r
+void ip_input(struct pbuf *p, struct netif *inp);\r
+\r
+/* source and destination addresses in network byte order, please */\r
+err_t ip_output(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,\r
+         unsigned char ttl, unsigned char proto);\r
+\r
+err_t ip_output_if(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,\r
+      unsigned char ttl, unsigned char proto,\r
+      struct netif *netif);\r
+\r
+#if IP_DEBUG\r
+void ip_debug_print(struct pbuf *p);\r
+#endif /* IP_DEBUG */\r
+\r
+#endif /* __LWIP_IP_H__ */\r
+\r
+\r
index 08e962ddd37eb00cfe4649a475125bc292997a23..d3937d36af29058921cde74500bcb44cc04ff3ce 100644 (file)
@@ -1,59 +1,59 @@
-/*
- * 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 <adam@sics.se>
- *
- */
-#ifndef __LWIP_IP_ADDR_H__
-#define __LWIP_IP_ADDR_H__
-
-#include "lwip/arch.h"
-
-#define IP_ADDR_ANY 0
-
-struct ip_addr {
-  u32_t addr[4];
-};
-
-#define IP6_ADDR(ipaddr, a,b,c,d,e,f,g,h) do { (ipaddr)->addr[0] = htonl((u32_t)((a & 0xffff) << 16) | (b & 0xffff)); \
-                                               (ipaddr)->addr[1] = htonl(((c & 0xffff) << 16) | (d & 0xffff)); \
-                                               (ipaddr)->addr[2] = htonl(((e & 0xffff) << 16) | (f & 0xffff)); \
-                                               (ipaddr)->addr[3] = htonl(((g & 0xffff) << 16) | (h & 0xffff)); } while(0)
-
-int ip_addr_netcmp(struct ip_addr *addr1, struct ip_addr *addr2,
-        struct ip_addr *mask);
-int ip_addr_cmp(struct ip_addr *addr1, struct ip_addr *addr2);
-void ip_addr_set(struct ip_addr *dest, struct ip_addr *src);
-int ip_addr_isany(struct ip_addr *addr);
-
-
-#if IP_DEBUG
-void ip_addr_debug_print(struct ip_addr *addr);
-#endif /* IP_DEBUG */
-
-#endif /* __LWIP_IP_ADDR_H__ */
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+#ifndef __LWIP_IP_ADDR_H__\r
+#define __LWIP_IP_ADDR_H__\r
+\r
+#include "lwip/arch.h"\r
+\r
+#define IP_ADDR_ANY 0\r
+\r
+struct ip_addr {\r
+  u32_t addr[4];\r
+};\r
+\r
+#define IP6_ADDR(ipaddr, a,b,c,d,e,f,g,h) do { (ipaddr)->addr[0] = htonl((u32_t)((a & 0xffff) << 16) | (b & 0xffff)); \\r
+                                               (ipaddr)->addr[1] = htonl(((c & 0xffff) << 16) | (d & 0xffff)); \\r
+                                               (ipaddr)->addr[2] = htonl(((e & 0xffff) << 16) | (f & 0xffff)); \\r
+                                               (ipaddr)->addr[3] = htonl(((g & 0xffff) << 16) | (h & 0xffff)); } while(0)\r
+\r
+int ip_addr_netcmp(struct ip_addr *addr1, struct ip_addr *addr2,\r
+        struct ip_addr *mask);\r
+int ip_addr_cmp(struct ip_addr *addr1, struct ip_addr *addr2);\r
+void ip_addr_set(struct ip_addr *dest, struct ip_addr *src);\r
+int ip_addr_isany(struct ip_addr *addr);\r
+\r
+\r
+#if IP_DEBUG\r
+void ip_addr_debug_print(struct ip_addr *addr);\r
+#endif /* IP_DEBUG */\r
+\r
+#endif /* __LWIP_IP_ADDR_H__ */\r
index 7f0ad596666dda1c26b722d7bbcab568258620d1..1059eca2e3699280c23e26b8a52bf5772dc29957 100644 (file)
-/*
- * 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 <adam@sics.se>
- *
- */
-#ifndef __LWIP_API_H__
-#define __LWIP_API_H__
-
-#include "lwip/opt.h"
-#include "lwip/pbuf.h"
-#include "lwip/sys.h"
-
-#include "lwip/ip.h"
-
-#include "lwip/raw.h"
-#include "lwip/udp.h"
-#include "lwip/tcp.h"
-
-#include "lwip/err.h"
-
-#define NETCONN_NOCOPY 0x00
-#define NETCONN_COPY   0x01
-
-enum netconn_type {
-  NETCONN_TCP,
-  NETCONN_UDP,
-  NETCONN_UDPLITE,
-  NETCONN_UDPNOCHKSUM,
-  NETCONN_RAW
-};
-
-enum netconn_state {
-  NETCONN_NONE,
-  NETCONN_WRITE,
-  NETCONN_ACCEPT,
-  NETCONN_RECV,
-  NETCONN_CONNECT,
-  NETCONN_CLOSE
-};
-
-enum netconn_evt {
-  NETCONN_EVT_RCVPLUS,
-  NETCONN_EVT_RCVMINUS,
-  NETCONN_EVT_SENDPLUS,
-  NETCONN_EVT_SENDMINUS
-};
-
-struct netbuf {
-  struct pbuf *p, *ptr;
-  struct ip_addr *fromaddr;
-  u16_t fromport;
-  err_t err;
-};
-
-struct netconn {
-  enum netconn_type type;
-  enum netconn_state state;
-  union {
-    struct tcp_pcb *tcp;
-    struct udp_pcb *udp;
-    struct raw_pcb *raw;
-  } pcb;
-  err_t err;
-  sys_mbox_t mbox;
-  sys_mbox_t recvmbox;
-  sys_mbox_t acceptmbox;
-  sys_sem_t sem;
-  int socket;
-  u16_t recv_avail;
-  void (* callback)(struct netconn *, enum netconn_evt, u16_t len);
-};
-
-/* Network buffer functions: */
-struct netbuf *   netbuf_new      (void);
-void              netbuf_delete   (struct netbuf *buf);
-void *            netbuf_alloc    (struct netbuf *buf, u16_t size);
-void              netbuf_free     (struct netbuf *buf);
-void              netbuf_ref      (struct netbuf *buf,
-           void *dataptr, u16_t size);
-void              netbuf_chain    (struct netbuf *head,
-           struct netbuf *tail);
-
-u16_t             netbuf_len      (struct netbuf *buf);
-err_t             netbuf_data     (struct netbuf *buf,
-           void **dataptr, u16_t *len);
-s8_t              netbuf_next     (struct netbuf *buf);
-void              netbuf_first    (struct netbuf *buf);
-
-void              netbuf_copy     (struct netbuf *buf,
-           void *dataptr, u16_t len);
-void              netbuf_copy_partial(struct netbuf *buf, void *dataptr, 
-              u16_t len, u16_t offset);
-struct ip_addr *  netbuf_fromaddr (struct netbuf *buf);
-u16_t             netbuf_fromport (struct netbuf *buf);
-
-/* Network connection functions: */
-struct netconn *  netconn_new     (enum netconn_type type);
-struct
-netconn *netconn_new_with_callback(enum netconn_type t,
-                                   void (*callback)(struct netconn *, enum netconn_evt, u16_t len));
-struct
-netconn *netconn_new_with_proto_and_callback(enum netconn_type t, u16_t proto,
-                                   void (*callback)(struct netconn *, enum netconn_evt, u16_t len));
-err_t             netconn_delete  (struct netconn *conn);
-enum netconn_type netconn_type    (struct netconn *conn);
-err_t             netconn_peer    (struct netconn *conn,
-           struct ip_addr *addr,
-           u16_t *port);
-err_t             netconn_addr    (struct netconn *conn,
-           struct ip_addr **addr,
-           u16_t *port);
-err_t             netconn_bind    (struct netconn *conn,
-           struct ip_addr *addr,
-           u16_t port);
-err_t             netconn_connect (struct netconn *conn,
-           struct ip_addr *addr,
-           u16_t port);
-err_t             netconn_disconnect (struct netconn *conn);
-err_t             netconn_listen  (struct netconn *conn);
-struct netconn *  netconn_accept  (struct netconn *conn);
-struct netbuf *   netconn_recv    (struct netconn *conn);
-err_t             netconn_send    (struct netconn *conn,
-           struct netbuf *buf);
-err_t             netconn_write   (struct netconn *conn,
-           void *dataptr, u16_t size,
-           u8_t copy);
-err_t             netconn_close   (struct netconn *conn);
-
-err_t             netconn_err     (struct netconn *conn);
-
-#endif /* __LWIP_API_H__ */
-
-
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+#ifndef __LWIP_API_H__\r
+#define __LWIP_API_H__\r
+\r
+#include "lwip/opt.h"\r
+#include "lwip/pbuf.h"\r
+#include "lwip/sys.h"\r
+\r
+#include "lwip/ip.h"\r
+\r
+#include "lwip/raw.h"\r
+#include "lwip/udp.h"\r
+#include "lwip/tcp.h"\r
+\r
+#include "lwip/err.h"\r
+\r
+#define NETCONN_NOCOPY 0x00\r
+#define NETCONN_COPY   0x01\r
+\r
+enum netconn_type {\r
+  NETCONN_TCP,\r
+  NETCONN_UDP,\r
+  NETCONN_UDPLITE,\r
+  NETCONN_UDPNOCHKSUM,\r
+  NETCONN_RAW\r
+};\r
+\r
+enum netconn_state {\r
+  NETCONN_NONE,\r
+  NETCONN_WRITE,\r
+  NETCONN_ACCEPT,\r
+  NETCONN_RECV,\r
+  NETCONN_CONNECT,\r
+  NETCONN_CLOSE\r
+};\r
+\r
+enum netconn_evt {\r
+  NETCONN_EVT_RCVPLUS,\r
+  NETCONN_EVT_RCVMINUS,\r
+  NETCONN_EVT_SENDPLUS,\r
+  NETCONN_EVT_SENDMINUS\r
+};\r
+\r
+struct netbuf {\r
+  struct pbuf *p, *ptr;\r
+  struct ip_addr *fromaddr;\r
+  u16_t fromport;\r
+  err_t err;\r
+};\r
+\r
+struct netconn {\r
+  enum netconn_type type;\r
+  enum netconn_state state;\r
+  union {\r
+    struct tcp_pcb *tcp;\r
+    struct udp_pcb *udp;\r
+    struct raw_pcb *raw;\r
+  } pcb;\r
+  err_t err;\r
+  sys_mbox_t mbox;\r
+  sys_mbox_t recvmbox;\r
+  sys_mbox_t acceptmbox;\r
+  sys_sem_t sem;\r
+  int socket;\r
+  u16_t recv_avail;\r
+  void (* callback)(struct netconn *, enum netconn_evt, u16_t len);\r
+};\r
+\r
+/* Network buffer functions: */\r
+struct netbuf *   netbuf_new      (void);\r
+void              netbuf_delete   (struct netbuf *buf);\r
+void *            netbuf_alloc    (struct netbuf *buf, u16_t size);\r
+void              netbuf_free     (struct netbuf *buf);\r
+void              netbuf_ref      (struct netbuf *buf,\r
+           void *dataptr, u16_t size);\r
+void              netbuf_chain    (struct netbuf *head,\r
+           struct netbuf *tail);\r
+\r
+u16_t             netbuf_len      (struct netbuf *buf);\r
+err_t             netbuf_data     (struct netbuf *buf,\r
+           void **dataptr, u16_t *len);\r
+s8_t              netbuf_next     (struct netbuf *buf);\r
+void              netbuf_first    (struct netbuf *buf);\r
+\r
+void              netbuf_copy     (struct netbuf *buf,\r
+           void *dataptr, u16_t len);\r
+void              netbuf_copy_partial(struct netbuf *buf, void *dataptr, \r
+              u16_t len, u16_t offset);\r
+struct ip_addr *  netbuf_fromaddr (struct netbuf *buf);\r
+u16_t             netbuf_fromport (struct netbuf *buf);\r
+\r
+/* Network connection functions: */\r
+struct netconn *  netconn_new     (enum netconn_type type);\r
+struct\r
+netconn *netconn_new_with_callback(enum netconn_type t,\r
+                                   void (*callback)(struct netconn *, enum netconn_evt, u16_t len));\r
+struct\r
+netconn *netconn_new_with_proto_and_callback(enum netconn_type t, u16_t proto,\r
+                                   void (*callback)(struct netconn *, enum netconn_evt, u16_t len));\r
+err_t             netconn_delete  (struct netconn *conn);\r
+enum netconn_type netconn_type    (struct netconn *conn);\r
+err_t             netconn_peer    (struct netconn *conn,\r
+           struct ip_addr *addr,\r
+           u16_t *port);\r
+err_t             netconn_addr    (struct netconn *conn,\r
+           struct ip_addr **addr,\r
+           u16_t *port);\r
+err_t             netconn_bind    (struct netconn *conn,\r
+           struct ip_addr *addr,\r
+           u16_t port);\r
+err_t             netconn_connect (struct netconn *conn,\r
+           struct ip_addr *addr,\r
+           u16_t port);\r
+err_t             netconn_disconnect (struct netconn *conn);\r
+err_t             netconn_listen  (struct netconn *conn);\r
+struct netconn *  netconn_accept  (struct netconn *conn);\r
+struct netbuf *   netconn_recv    (struct netconn *conn);\r
+err_t             netconn_send    (struct netconn *conn,\r
+           struct netbuf *buf);\r
+err_t             netconn_write   (struct netconn *conn,\r
+           void *dataptr, u16_t size,\r
+           u8_t copy);\r
+err_t             netconn_close   (struct netconn *conn);\r
+\r
+err_t             netconn_err     (struct netconn *conn);\r
+\r
+#endif /* __LWIP_API_H__ */\r
+\r
+\r
index 1957abc5edb50412231860230847e717e016a555..3ed585c447279157c029743df64b3341ecdaed38 100644 (file)
@@ -1,94 +1,94 @@
-/*
- * 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 <adam@sics.se>
- *
- */
-#ifndef __LWIP_API_MSG_H__
-#define __LWIP_API_MSG_H__
-
-#include "lwip/opt.h"
-#include "lwip/pbuf.h"
-#include "lwip/sys.h"
-
-#include "lwip/ip.h"
-
-#include "lwip/udp.h"
-#include "lwip/tcp.h"
-
-#include "lwip/api.h"
-
-enum api_msg_type {
-  API_MSG_NEWCONN,
-  API_MSG_DELCONN,
-  
-  API_MSG_BIND,
-  API_MSG_CONNECT,
-  API_MSG_DISCONNECT,
-
-  API_MSG_LISTEN,
-  API_MSG_ACCEPT,
-
-  API_MSG_SEND,
-  API_MSG_RECV,
-  API_MSG_WRITE,
-
-  API_MSG_CLOSE,
-  
-  API_MSG_MAX
-};
-
-struct api_msg_msg {
-  struct netconn *conn;
-  enum netconn_type conntype;
-  union {
-    struct pbuf *p;   
-    struct  {
-      struct ip_addr *ipaddr;
-      u16_t port;
-    } bc;
-    struct {
-      void *dataptr;
-      u16_t len;
-      unsigned char copy;
-    } w;    
-    sys_mbox_t mbox;
-    u16_t len;
-  } msg;
-};
-
-struct api_msg {
-  enum api_msg_type type;
-  struct api_msg_msg msg;
-};
-
-void api_msg_input(struct api_msg *msg);
-void api_msg_post(struct api_msg *msg);
-
-#endif /* __LWIP_API_MSG_H__ */
-
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+#ifndef __LWIP_API_MSG_H__\r
+#define __LWIP_API_MSG_H__\r
+\r
+#include "lwip/opt.h"\r
+#include "lwip/pbuf.h"\r
+#include "lwip/sys.h"\r
+\r
+#include "lwip/ip.h"\r
+\r
+#include "lwip/udp.h"\r
+#include "lwip/tcp.h"\r
+\r
+#include "lwip/api.h"\r
+\r
+enum api_msg_type {\r
+  API_MSG_NEWCONN,\r
+  API_MSG_DELCONN,\r
+  \r
+  API_MSG_BIND,\r
+  API_MSG_CONNECT,\r
+  API_MSG_DISCONNECT,\r
+\r
+  API_MSG_LISTEN,\r
+  API_MSG_ACCEPT,\r
+\r
+  API_MSG_SEND,\r
+  API_MSG_RECV,\r
+  API_MSG_WRITE,\r
+\r
+  API_MSG_CLOSE,\r
+  \r
+  API_MSG_MAX\r
+};\r
+\r
+struct api_msg_msg {\r
+  struct netconn *conn;\r
+  enum netconn_type conntype;\r
+  union {\r
+    struct pbuf *p;   \r
+    struct  {\r
+      struct ip_addr *ipaddr;\r
+      u16_t port;\r
+    } bc;\r
+    struct {\r
+      void *dataptr;\r
+      u16_t len;\r
+      unsigned char copy;\r
+    } w;    \r
+    sys_mbox_t mbox;\r
+    u16_t len;\r
+  } msg;\r
+};\r
+\r
+struct api_msg {\r
+  enum api_msg_type type;\r
+  struct api_msg_msg msg;\r
+};\r
+\r
+void api_msg_input(struct api_msg *msg);\r
+void api_msg_post(struct api_msg *msg);\r
+\r
+#endif /* __LWIP_API_MSG_H__ */\r
+\r
index e0d622a4b2b0442e57a174548c34d81c5ea5a63b..f5e10513fb44f5ebbd9d1469403e311981b19b0c 100644 (file)
-/*
- * 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 <adam@sics.se>
- *
- */
-#ifndef __LWIP_ARCH_H__
-#define __LWIP_ARCH_H__
-
-#ifndef LITTLE_ENDIAN
-#define LITTLE_ENDIAN 1234
-#endif
-
-#ifndef BIG_ENDIAN
-#define BIG_ENDIAN 4321
-#endif
-
-#include "arch/cc.h"
-
-#ifndef PACK_STRUCT_BEGIN
-#define PACK_STRUCT_BEGIN
-#endif /* PACK_STRUCT_BEGIN */
-
-#ifndef PACK_STRUCT_END
-#define PACK_STRUCT_END
-#endif /* PACK_STRUCT_END */
-
-#ifndef PACK_STRUCT_FIELD
-#define PACK_STRUCT_FIELD(x) x
-#endif /* PACK_STRUCT_FIELD */
-
-
-
-#ifdef LWIP_PROVIDE_ERRNO
-
-#define  EPERM     1  /* Operation not permitted */
-#define  ENOENT     2  /* No such file or directory */
-#define  ESRCH     3  /* No such process */
-#define  EINTR     4  /* Interrupted system call */
-#define  EIO     5  /* I/O error */
-#define  ENXIO     6  /* No such device or address */
-#define  E2BIG     7  /* Arg list too long */
-#define  ENOEXEC     8  /* Exec format error */
-#define  EBADF     9  /* Bad file number */
-#define  ECHILD    10  /* No child processes */
-#define  EAGAIN    11  /* Try again */
-#define  ENOMEM    12  /* Out of memory */
-#define  EACCES    13  /* Permission denied */
-#define  EFAULT    14  /* Bad address */
-#define  ENOTBLK    15  /* Block device required */
-#define  EBUSY    16  /* Device or resource busy */
-#define  EEXIST    17  /* File exists */
-#define  EXDEV    18  /* Cross-device link */
-#define  ENODEV    19  /* No such device */
-#define  ENOTDIR    20  /* Not a directory */
-#define  EISDIR    21  /* Is a directory */
-#define  EINVAL    22  /* Invalid argument */
-#define  ENFILE    23  /* File table overflow */
-#define  EMFILE    24  /* Too many open files */
-#define  ENOTTY    25  /* Not a typewriter */
-#define  ETXTBSY    26  /* Text file busy */
-#define  EFBIG    27  /* File too large */
-#define  ENOSPC    28  /* No space left on device */
-#define  ESPIPE    29  /* Illegal seek */
-#define  EROFS    30  /* Read-only file system */
-#define  EMLINK    31  /* Too many links */
-#define  EPIPE    32  /* Broken pipe */
-#define  EDOM    33  /* Math argument out of domain of func */
-#define  ERANGE    34  /* Math result not representable */
-#define  EDEADLK    35  /* Resource deadlock would occur */
-#define  ENAMETOOLONG  36  /* File name too long */
-#define  ENOLCK    37  /* No record locks available */
-#define  ENOSYS    38  /* Function not implemented */
-#define  ENOTEMPTY  39  /* Directory not empty */
-#define  ELOOP    40  /* Too many symbolic links encountered */
-#define  EWOULDBLOCK  EAGAIN  /* Operation would block */
-#define  ENOMSG    42  /* No message of desired type */
-#define  EIDRM    43  /* Identifier removed */
-#define  ECHRNG    44  /* Channel number out of range */
-#define  EL2NSYNC  45  /* Level 2 not synchronized */
-#define  EL3HLT    46  /* Level 3 halted */
-#define  EL3RST    47  /* Level 3 reset */
-#define  ELNRNG    48  /* Link number out of range */
-#define  EUNATCH    49  /* Protocol driver not attached */
-#define  ENOCSI    50  /* No CSI structure available */
-#define  EL2HLT    51  /* Level 2 halted */
-#define  EBADE    52  /* Invalid exchange */
-#define  EBADR    53  /* Invalid request descriptor */
-#define  EXFULL    54  /* Exchange full */
-#define  ENOANO    55  /* No anode */
-#define  EBADRQC    56  /* Invalid request code */
-#define  EBADSLT    57  /* Invalid slot */
-
-#define  EDEADLOCK  EDEADLK
-
-#define  EBFONT    59  /* Bad font file format */
-#define  ENOSTR    60  /* Device not a stream */
-#define  ENODATA    61  /* No data available */
-#define  ETIME    62  /* Timer expired */
-#define  ENOSR    63  /* Out of streams resources */
-#define  ENONET    64  /* Machine is not on the network */
-#define  ENOPKG    65  /* Package not installed */
-#define  EREMOTE    66  /* Object is remote */
-#define  ENOLINK    67  /* Link has been severed */
-#define  EADV    68  /* Advertise error */
-#define  ESRMNT    69  /* Srmount error */
-#define  ECOMM    70  /* Communication error on send */
-#define  EPROTO    71  /* Protocol error */
-#define  EMULTIHOP  72  /* Multihop attempted */
-#define  EDOTDOT    73  /* RFS specific error */
-#define  EBADMSG    74  /* Not a data message */
-#define  EOVERFLOW  75  /* Value too large for defined data type */
-#define  ENOTUNIQ  76  /* Name not unique on network */
-#define  EBADFD    77  /* File descriptor in bad state */
-#define  EREMCHG    78  /* Remote address changed */
-#define  ELIBACC    79  /* Can not access a needed shared library */
-#define  ELIBBAD    80  /* Accessing a corrupted shared library */
-#define  ELIBSCN    81  /* .lib section in a.out corrupted */
-#define  ELIBMAX    82  /* Attempting to link in too many shared libraries */
-#define  ELIBEXEC  83  /* Cannot exec a shared library directly */
-#define  EILSEQ    84  /* Illegal byte sequence */
-#define  ERESTART  85  /* Interrupted system call should be restarted */
-#define  ESTRPIPE  86  /* Streams pipe error */
-#define  EUSERS    87  /* Too many users */
-#define  ENOTSOCK  88  /* Socket operation on non-socket */
-#define  EDESTADDRREQ  89  /* Destination address required */
-#define  EMSGSIZE  90  /* Message too long */
-#define  EPROTOTYPE  91  /* Protocol wrong type for socket */
-#define  ENOPROTOOPT  92  /* Protocol not available */
-#define  EPROTONOSUPPORT  93  /* Protocol not supported */
-#define  ESOCKTNOSUPPORT  94  /* Socket type not supported */
-#define  EOPNOTSUPP  95  /* Operation not supported on transport endpoint */
-#define  EPFNOSUPPORT  96  /* Protocol family not supported */
-#define  EAFNOSUPPORT  97  /* Address family not supported by protocol */
-#define  EADDRINUSE  98  /* Address already in use */
-#define  EADDRNOTAVAIL  99  /* Cannot assign requested address */
-#define  ENETDOWN  100  /* Network is down */
-#define  ENETUNREACH  101  /* Network is unreachable */
-#define  ENETRESET  102  /* Network dropped connection because of reset */
-#define  ECONNABORTED  103  /* Software caused connection abort */
-#define  ECONNRESET  104  /* Connection reset by peer */
-#define  ENOBUFS    105  /* No buffer space available */
-#define  EISCONN    106  /* Transport endpoint is already connected */
-#define  ENOTCONN  107  /* Transport endpoint is not connected */
-#define  ESHUTDOWN  108  /* Cannot send after transport endpoint shutdown */
-#define  ETOOMANYREFS  109  /* Too many references: cannot splice */
-#define  ETIMEDOUT  110  /* Connection timed out */
-#define  ECONNREFUSED  111  /* Connection refused */
-#define  EHOSTDOWN  112  /* Host is down */
-#define  EHOSTUNREACH  113  /* No route to host */
-#define  EALREADY  114  /* Operation already in progress */
-#define  EINPROGRESS  115  /* Operation now in progress */
-#define  ESTALE    116  /* Stale NFS file handle */
-#define  EUCLEAN    117  /* Structure needs cleaning */
-#define  ENOTNAM    118  /* Not a XENIX named type file */
-#define  ENAVAIL    119  /* No XENIX semaphores available */
-#define  EISNAM    120  /* Is a named type file */
-#define  EREMOTEIO  121  /* Remote I/O error */
-#define  EDQUOT    122  /* Quota exceeded */
-
-#define  ENOMEDIUM  123  /* No medium found */
-#define  EMEDIUMTYPE  124  /* Wrong medium type */
-
-
-#define        ENSROK          0       /* DNS server returned answer with no data */
-#define        ENSRNODATA      160     /* DNS server returned answer with no data */
-#define        ENSRFORMERR     161     /* DNS server claims query was misformatted */
-#define        ENSRSERVFAIL 162        /* DNS server returned general failure */
-#define        ENSRNOTFOUND 163        /* Domain name not found */
-#define        ENSRNOTIMP      164     /* DNS server does not implement requested operation */
-#define        ENSRREFUSED     165     /* DNS server refused query */
-#define        ENSRBADQUERY 166        /* Misformatted DNS query */
-#define        ENSRBADNAME     167     /* Misformatted domain name */
-#define        ENSRBADFAMILY 168       /* Unsupported address family */
-#define        ENSRBADRESP     169     /* Misformatted DNS reply */
-#define        ENSRCONNREFUSED 170     /* Could not contact DNS servers */
-#define        ENSRTIMEOUT     171     /* Timeout while contacting DNS servers */
-#define        ENSROF          172     /* End of file */
-#define        ENSRFILE        173     /* Error reading file */
-#define        ENSRNOMEM       174     /* Out of memory */
-#define        ENSRDESTRUCTION 175     /* Application terminated lookup */
-#define        ENSRQUERYDOMAINTOOLONG  176     /* Domain name is too long */
-#define        ENSRCNAMELOOP   177     /* Domain name is too long */
-
-#ifndef errno
-extern int errno;
-#endif
-
-#endif /* LWIP_PROVIDE_ERRNO */
-
-#endif /* __LWIP_ARCH_H__ */
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+#ifndef __LWIP_ARCH_H__\r
+#define __LWIP_ARCH_H__\r
+\r
+#ifndef LITTLE_ENDIAN\r
+#define LITTLE_ENDIAN 1234\r
+#endif\r
+\r
+#ifndef BIG_ENDIAN\r
+#define BIG_ENDIAN 4321\r
+#endif\r
+\r
+#include "arch/cc.h"\r
+\r
+#ifndef PACK_STRUCT_BEGIN\r
+#define PACK_STRUCT_BEGIN\r
+#endif /* PACK_STRUCT_BEGIN */\r
+\r
+#ifndef PACK_STRUCT_END\r
+#define PACK_STRUCT_END\r
+#endif /* PACK_STRUCT_END */\r
+\r
+#ifndef PACK_STRUCT_FIELD\r
+#define PACK_STRUCT_FIELD(x) x\r
+#endif /* PACK_STRUCT_FIELD */\r
+\r
+\r
+\r
+#ifdef LWIP_PROVIDE_ERRNO\r
+\r
+#define  EPERM     1  /* Operation not permitted */\r
+#define  ENOENT     2  /* No such file or directory */\r
+#define  ESRCH     3  /* No such process */\r
+#define  EINTR     4  /* Interrupted system call */\r
+#define  EIO     5  /* I/O error */\r
+#define  ENXIO     6  /* No such device or address */\r
+#define  E2BIG     7  /* Arg list too long */\r
+#define  ENOEXEC     8  /* Exec format error */\r
+#define  EBADF     9  /* Bad file number */\r
+#define  ECHILD    10  /* No child processes */\r
+#define  EAGAIN    11  /* Try again */\r
+#define  ENOMEM    12  /* Out of memory */\r
+#define  EACCES    13  /* Permission denied */\r
+#define  EFAULT    14  /* Bad address */\r
+#define  ENOTBLK    15  /* Block device required */\r
+#define  EBUSY    16  /* Device or resource busy */\r
+#define  EEXIST    17  /* File exists */\r
+#define  EXDEV    18  /* Cross-device link */\r
+#define  ENODEV    19  /* No such device */\r
+#define  ENOTDIR    20  /* Not a directory */\r
+#define  EISDIR    21  /* Is a directory */\r
+#define  EINVAL    22  /* Invalid argument */\r
+#define  ENFILE    23  /* File table overflow */\r
+#define  EMFILE    24  /* Too many open files */\r
+#define  ENOTTY    25  /* Not a typewriter */\r
+#define  ETXTBSY    26  /* Text file busy */\r
+#define  EFBIG    27  /* File too large */\r
+#define  ENOSPC    28  /* No space left on device */\r
+#define  ESPIPE    29  /* Illegal seek */\r
+#define  EROFS    30  /* Read-only file system */\r
+#define  EMLINK    31  /* Too many links */\r
+#define  EPIPE    32  /* Broken pipe */\r
+#define  EDOM    33  /* Math argument out of domain of func */\r
+#define  ERANGE    34  /* Math result not representable */\r
+#define  EDEADLK    35  /* Resource deadlock would occur */\r
+#define  ENAMETOOLONG  36  /* File name too long */\r
+#define  ENOLCK    37  /* No record locks available */\r
+#define  ENOSYS    38  /* Function not implemented */\r
+#define  ENOTEMPTY  39  /* Directory not empty */\r
+#define  ELOOP    40  /* Too many symbolic links encountered */\r
+#define  EWOULDBLOCK  EAGAIN  /* Operation would block */\r
+#define  ENOMSG    42  /* No message of desired type */\r
+#define  EIDRM    43  /* Identifier removed */\r
+#define  ECHRNG    44  /* Channel number out of range */\r
+#define  EL2NSYNC  45  /* Level 2 not synchronized */\r
+#define  EL3HLT    46  /* Level 3 halted */\r
+#define  EL3RST    47  /* Level 3 reset */\r
+#define  ELNRNG    48  /* Link number out of range */\r
+#define  EUNATCH    49  /* Protocol driver not attached */\r
+#define  ENOCSI    50  /* No CSI structure available */\r
+#define  EL2HLT    51  /* Level 2 halted */\r
+#define  EBADE    52  /* Invalid exchange */\r
+#define  EBADR    53  /* Invalid request descriptor */\r
+#define  EXFULL    54  /* Exchange full */\r
+#define  ENOANO    55  /* No anode */\r
+#define  EBADRQC    56  /* Invalid request code */\r
+#define  EBADSLT    57  /* Invalid slot */\r
+\r
+#define  EDEADLOCK  EDEADLK\r
+\r
+#define  EBFONT    59  /* Bad font file format */\r
+#define  ENOSTR    60  /* Device not a stream */\r
+#define  ENODATA    61  /* No data available */\r
+#define  ETIME    62  /* Timer expired */\r
+#define  ENOSR    63  /* Out of streams resources */\r
+#define  ENONET    64  /* Machine is not on the network */\r
+#define  ENOPKG    65  /* Package not installed */\r
+#define  EREMOTE    66  /* Object is remote */\r
+#define  ENOLINK    67  /* Link has been severed */\r
+#define  EADV    68  /* Advertise error */\r
+#define  ESRMNT    69  /* Srmount error */\r
+#define  ECOMM    70  /* Communication error on send */\r
+#define  EPROTO    71  /* Protocol error */\r
+#define  EMULTIHOP  72  /* Multihop attempted */\r
+#define  EDOTDOT    73  /* RFS specific error */\r
+#define  EBADMSG    74  /* Not a data message */\r
+#define  EOVERFLOW  75  /* Value too large for defined data type */\r
+#define  ENOTUNIQ  76  /* Name not unique on network */\r
+#define  EBADFD    77  /* File descriptor in bad state */\r
+#define  EREMCHG    78  /* Remote address changed */\r
+#define  ELIBACC    79  /* Can not access a needed shared library */\r
+#define  ELIBBAD    80  /* Accessing a corrupted shared library */\r
+#define  ELIBSCN    81  /* .lib section in a.out corrupted */\r
+#define  ELIBMAX    82  /* Attempting to link in too many shared libraries */\r
+#define  ELIBEXEC  83  /* Cannot exec a shared library directly */\r
+#define  EILSEQ    84  /* Illegal byte sequence */\r
+#define  ERESTART  85  /* Interrupted system call should be restarted */\r
+#define  ESTRPIPE  86  /* Streams pipe error */\r
+#define  EUSERS    87  /* Too many users */\r
+#define  ENOTSOCK  88  /* Socket operation on non-socket */\r
+#define  EDESTADDRREQ  89  /* Destination address required */\r
+#define  EMSGSIZE  90  /* Message too long */\r
+#define  EPROTOTYPE  91  /* Protocol wrong type for socket */\r
+#define  ENOPROTOOPT  92  /* Protocol not available */\r
+#define  EPROTONOSUPPORT  93  /* Protocol not supported */\r
+#define  ESOCKTNOSUPPORT  94  /* Socket type not supported */\r
+#define  EOPNOTSUPP  95  /* Operation not supported on transport endpoint */\r
+#define  EPFNOSUPPORT  96  /* Protocol family not supported */\r
+#define  EAFNOSUPPORT  97  /* Address family not supported by protocol */\r
+#define  EADDRINUSE  98  /* Address already in use */\r
+#define  EADDRNOTAVAIL  99  /* Cannot assign requested address */\r
+#define  ENETDOWN  100  /* Network is down */\r
+#define  ENETUNREACH  101  /* Network is unreachable */\r
+#define  ENETRESET  102  /* Network dropped connection because of reset */\r
+#define  ECONNABORTED  103  /* Software caused connection abort */\r
+#define  ECONNRESET  104  /* Connection reset by peer */\r
+#define  ENOBUFS    105  /* No buffer space available */\r
+#define  EISCONN    106  /* Transport endpoint is already connected */\r
+#define  ENOTCONN  107  /* Transport endpoint is not connected */\r
+#define  ESHUTDOWN  108  /* Cannot send after transport endpoint shutdown */\r
+#define  ETOOMANYREFS  109  /* Too many references: cannot splice */\r
+#define  ETIMEDOUT  110  /* Connection timed out */\r
+#define  ECONNREFUSED  111  /* Connection refused */\r
+#define  EHOSTDOWN  112  /* Host is down */\r
+#define  EHOSTUNREACH  113  /* No route to host */\r
+#define  EALREADY  114  /* Operation already in progress */\r
+#define  EINPROGRESS  115  /* Operation now in progress */\r
+#define  ESTALE    116  /* Stale NFS file handle */\r
+#define  EUCLEAN    117  /* Structure needs cleaning */\r
+#define  ENOTNAM    118  /* Not a XENIX named type file */\r
+#define  ENAVAIL    119  /* No XENIX semaphores available */\r
+#define  EISNAM    120  /* Is a named type file */\r
+#define  EREMOTEIO  121  /* Remote I/O error */\r
+#define  EDQUOT    122  /* Quota exceeded */\r
+\r
+#define  ENOMEDIUM  123  /* No medium found */\r
+#define  EMEDIUMTYPE  124  /* Wrong medium type */\r
+\r
+\r
+#define        ENSROK          0       /* DNS server returned answer with no data */\r
+#define        ENSRNODATA      160     /* DNS server returned answer with no data */\r
+#define        ENSRFORMERR     161     /* DNS server claims query was misformatted */\r
+#define        ENSRSERVFAIL 162        /* DNS server returned general failure */\r
+#define        ENSRNOTFOUND 163        /* Domain name not found */\r
+#define        ENSRNOTIMP      164     /* DNS server does not implement requested operation */\r
+#define        ENSRREFUSED     165     /* DNS server refused query */\r
+#define        ENSRBADQUERY 166        /* Misformatted DNS query */\r
+#define        ENSRBADNAME     167     /* Misformatted domain name */\r
+#define        ENSRBADFAMILY 168       /* Unsupported address family */\r
+#define        ENSRBADRESP     169     /* Misformatted DNS reply */\r
+#define        ENSRCONNREFUSED 170     /* Could not contact DNS servers */\r
+#define        ENSRTIMEOUT     171     /* Timeout while contacting DNS servers */\r
+#define        ENSROF          172     /* End of file */\r
+#define        ENSRFILE        173     /* Error reading file */\r
+#define        ENSRNOMEM       174     /* Out of memory */\r
+#define        ENSRDESTRUCTION 175     /* Application terminated lookup */\r
+#define        ENSRQUERYDOMAINTOOLONG  176     /* Domain name is too long */\r
+#define        ENSRCNAMELOOP   177     /* Domain name is too long */\r
+\r
+#ifndef errno\r
+extern int errno;\r
+#endif\r
+\r
+#endif /* LWIP_PROVIDE_ERRNO */\r
+\r
+#endif /* __LWIP_ARCH_H__ */\r
index 4d3425c070cebc72cacd125613b495d3160c9389..eb9eda7feab1e8bbfd90bd267253726bbc2654a8 100644 (file)
@@ -1,87 +1,87 @@
-/*
- * 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 <adam@sics.se>
- *
- */
-#ifndef __LWIP_DEBUG_H__
-#define __LWIP_DEBUG_H__
-
-#include "arch/cc.h"
-
-/** lower two bits indicate debug level
- * - 0 off
- * - 1 warning
- * - 2 serious
- * - 3 severe
- */
-
-#define DBG_LEVEL_OFF     0
-#define DBG_LEVEL_WARNING 1  /* bad checksums, dropped packets, ... */
-#define DBG_LEVEL_SERIOUS 2  /* memory allocation failures, ... */
-#define DBG_LEVEL_SEVERE  3  /* */ 
-#define DBG_MASK_LEVEL    3
-
-/** flag for LWIP_DEBUGF to enable that debug message */
-#define DBG_ON  0x80U
-/** flag for LWIP_DEBUGF to disable that debug message */
-#define DBG_OFF 0x00U
-
-/** flag for LWIP_DEBUGF indicating a tracing message (to follow program flow) */
-#define DBG_TRACE   0x40U
-/** flag for LWIP_DEBUGF indicating a state debug message (to follow module states) */
-#define DBG_STATE   0x20U
-/** flag for LWIP_DEBUGF indicating newly added code, not thoroughly tested yet */
-#define DBG_FRESH   0x10U
-/** flag for LWIP_DEBUGF to halt after printing this debug message */
-#define DBG_HALT    0x08U
-
-#ifndef LWIP_NOASSERT
-#  define LWIP_ASSERT(x,y) do { if(!(y)) LWIP_PLATFORM_ASSERT(x); } while(0)
-#else
-#  define LWIP_ASSERT(x,y) 
-#endif
-
-#ifdef LWIP_DEBUG
-/** print debug message only if debug message type is enabled...
- *  AND is of correct type AND is at least DBG_LEVEL
- */
-#  define LWIP_DEBUGF(debug,x) do { if (((debug) & DBG_ON) && ((debug) & DBG_TYPES_ON) && ((int)((debug) & DBG_MASK_LEVEL) >= DBG_MIN_LEVEL)) { LWIP_PLATFORM_DIAG(x); if ((debug) & DBG_HALT) while(1); } } while(0)
-#  define LWIP_ERROR(x)   do { LWIP_PLATFORM_DIAG(x); } while(0)  
-#else /* LWIP_DEBUG */
-#  define LWIP_DEBUGF(debug,x) 
-#  define LWIP_ERROR(x)  
-#endif /* LWIP_DEBUG */
-
-#endif /* __LWIP_DEBUG_H__ */
-
-
-
-
-
-
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+#ifndef __LWIP_DEBUG_H__\r
+#define __LWIP_DEBUG_H__\r
+\r
+#include "arch/cc.h"\r
+\r
+/** lower two bits indicate debug level\r
+ * - 0 off\r
+ * - 1 warning\r
+ * - 2 serious\r
+ * - 3 severe\r
+ */\r
+\r
+#define DBG_LEVEL_OFF     0\r
+#define DBG_LEVEL_WARNING 1  /* bad checksums, dropped packets, ... */\r
+#define DBG_LEVEL_SERIOUS 2  /* memory allocation failures, ... */\r
+#define DBG_LEVEL_SEVERE  3  /* */ \r
+#define DBG_MASK_LEVEL    3\r
+\r
+/** flag for LWIP_DEBUGF to enable that debug message */\r
+#define DBG_ON  0x80U\r
+/** flag for LWIP_DEBUGF to disable that debug message */\r
+#define DBG_OFF 0x00U\r
+\r
+/** flag for LWIP_DEBUGF indicating a tracing message (to follow program flow) */\r
+#define DBG_TRACE   0x40U\r
+/** flag for LWIP_DEBUGF indicating a state debug message (to follow module states) */\r
+#define DBG_STATE   0x20U\r
+/** flag for LWIP_DEBUGF indicating newly added code, not thoroughly tested yet */\r
+#define DBG_FRESH   0x10U\r
+/** flag for LWIP_DEBUGF to halt after printing this debug message */\r
+#define DBG_HALT    0x08U\r
+\r
+#ifndef LWIP_NOASSERT\r
+#  define LWIP_ASSERT(x,y) do { if(!(y)) LWIP_PLATFORM_ASSERT(x); } while(0)\r
+#else\r
+#  define LWIP_ASSERT(x,y) \r
+#endif\r
+\r
+#ifdef LWIP_DEBUG\r
+/** print debug message only if debug message type is enabled...\r
+ *  AND is of correct type AND is at least DBG_LEVEL\r
+ */\r
+#  define LWIP_DEBUGF(debug,x) do { if (((debug) & DBG_ON) && ((debug) & DBG_TYPES_ON) && ((int)((debug) & DBG_MASK_LEVEL) >= DBG_MIN_LEVEL)) { LWIP_PLATFORM_DIAG(x); if ((debug) & DBG_HALT) while(1); } } while(0)\r
+#  define LWIP_ERROR(x)   do { LWIP_PLATFORM_DIAG(x); } while(0)  \r
+#else /* LWIP_DEBUG */\r
+#  define LWIP_DEBUGF(debug,x) \r
+#  define LWIP_ERROR(x)  \r
+#endif /* LWIP_DEBUG */\r
+\r
+#endif /* __LWIP_DEBUG_H__ */\r
+\r
+\r
+\r
+\r
+\r
+\r
index eba9b8774dbbb8ed834f113bb9d42a6365de63a5..f26bdd0406f74b773e1f19e20d3ddafb5a40c875 100644 (file)
@@ -1,47 +1,47 @@
-/*
- * 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 <adam@sics.se>
- *
- */
-#ifndef __LWIP_DEF_H__
-#define __LWIP_DEF_H__
-
-/* this might define NULL already */
-#include "arch/cc.h"
-
-#define LWIP_MAX(x , y)  (x) > (y) ? (x) : (y)
-#define LWIP_MIN(x , y)  (x) < (y) ? (x) : (y)
-
-#ifndef NULL
-#define NULL ((void *)0)
-#endif
-
-
-#endif /* __LWIP_DEF_H__ */
-
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+#ifndef __LWIP_DEF_H__\r
+#define __LWIP_DEF_H__\r
+\r
+/* this might define NULL already */\r
+#include "arch/cc.h"\r
+\r
+#define LWIP_MAX(x , y)  (x) > (y) ? (x) : (y)\r
+#define LWIP_MIN(x , y)  (x) < (y) ? (x) : (y)\r
+\r
+#ifndef NULL\r
+#define NULL ((void *)0)\r
+#endif\r
+\r
+\r
+#endif /* __LWIP_DEF_H__ */\r
+\r
index bfe753f26a8bd2bdb7c9abe6dd6d349ff57aeddd..df51bdc96e5cf64ee6f2b098a63419ac0b2bf9e9 100644 (file)
-/** @file
- */
-
-#ifndef __LWIP_DHCP_H__
-#define __LWIP_DHCP_H__
-
-#include "lwip/opt.h"
-#include "lwip/netif.h"
-#include "lwip/udp.h"
-
-/** period (in seconds) of the application calling dhcp_coarse_tmr() */
-#define DHCP_COARSE_TIMER_SECS 60 
-/** period (in milliseconds) of the application calling dhcp_fine_tmr() */
-#define DHCP_FINE_TIMER_MSECS 500 
-
-struct dhcp
-{
-  /** current DHCP state machine state */
-  u8_t state;
-  /** retries of current request */
-  u8_t tries;
-  /** transaction identifier of last sent request */ 
-  u32_t xid;
-  /** our connection to the DHCP server */ 
-  struct udp_pcb *pcb;
-  /** (first) pbuf of incoming msg */
-  struct pbuf *p;
-  /** incoming msg */
-  struct dhcp_msg *msg_in;
-  /** incoming msg options */
-  struct dhcp_msg *options_in; 
-  /** ingoing msg options length */
-  u16_t options_in_len;
-
-  struct pbuf *p_out; /* pbuf of outcoming msg */
-  struct dhcp_msg *msg_out; /* outgoing msg */
-  u16_t options_out_len; /* outgoing msg options length */
-  u16_t request_timeout; /* #ticks with period DHCP_FINE_TIMER_SECS for request timeout */
-  u16_t t1_timeout;  /* #ticks with period DHCP_COARSE_TIMER_SECS for renewal time */
-  u16_t t2_timeout;  /* #ticks with period DHCP_COARSE_TIMER_SECS for rebind time */
-  struct ip_addr server_ip_addr; /* dhcp server address that offered this lease */
-  struct ip_addr offered_ip_addr;
-  struct ip_addr offered_sn_mask;
-  struct ip_addr offered_gw_addr;
-  struct ip_addr offered_bc_addr;
-#define DHCP_MAX_DNS 2
-  u32_t dns_count; /* actual number of DNS servers obtained */
-  struct ip_addr offered_dns_addr[DHCP_MAX_DNS]; /* DNS server addresses */
-  u32_t offered_t0_lease; /* lease period (in seconds) */
-  u32_t offered_t1_renew; /* recommended renew time (usually 50% of lease period) */
-  u32_t offered_t2_rebind; /* recommended rebind time (usually 66% of lease period)  */
-/** Patch #1308
- *  TODO: See dhcp.c "TODO"s
- */
-#if 0
-  struct ip_addr offered_si_addr;
-  u8_t *boot_file_name;
-#endif
-};
-
-/* MUST be compiled with "pack structs" or equivalent! */
-#ifdef PACK_STRUCT_USE_INCLUDES
-#  include "arch/bpstruct.h"
-#endif
-PACK_STRUCT_BEGIN
-/** minimum set of fields of any DHCP message */
-struct dhcp_msg
-{
-  PACK_STRUCT_FIELD(u8_t op);
-  PACK_STRUCT_FIELD(u8_t htype);
-  PACK_STRUCT_FIELD(u8_t hlen);
-  PACK_STRUCT_FIELD(u8_t hops);
-  PACK_STRUCT_FIELD(u32_t xid);
-  PACK_STRUCT_FIELD(u16_t secs);
-  PACK_STRUCT_FIELD(u16_t flags);
-  PACK_STRUCT_FIELD(struct ip_addr ciaddr);
-  PACK_STRUCT_FIELD(struct ip_addr yiaddr);
-  PACK_STRUCT_FIELD(struct ip_addr siaddr);
-  PACK_STRUCT_FIELD(struct ip_addr giaddr);
-#define DHCP_CHADDR_LEN 16U
-  PACK_STRUCT_FIELD(u8_t chaddr[DHCP_CHADDR_LEN]);
-#define DHCP_SNAME_LEN 64U
-  PACK_STRUCT_FIELD(u8_t sname[DHCP_SNAME_LEN]);
-#define DHCP_FILE_LEN 128U
-  PACK_STRUCT_FIELD(u8_t file[DHCP_FILE_LEN]);
-  PACK_STRUCT_FIELD(u32_t cookie);
-#define DHCP_MIN_OPTIONS_LEN 68U
-/** make sure user does not configure this too small */
-#if ((defined(DHCP_OPTIONS_LEN)) && (DHCP_OPTIONS_LEN < DHCP_MIN_OPTIONS_LEN))
-#  undef DHCP_OPTIONS_LEN
-#endif
-/** allow this to be configured in lwipopts.h, but not too small */
-#if (!defined(DHCP_OPTIONS_LEN))
-/** set this to be sufficient for your options in outgoing DHCP msgs */
-#  define DHCP_OPTIONS_LEN DHCP_MIN_OPTIONS_LEN
-#endif
-  PACK_STRUCT_FIELD(u8_t options[DHCP_OPTIONS_LEN]);
-} PACK_STRUCT_STRUCT;
-PACK_STRUCT_END
-#ifdef PACK_STRUCT_USE_INCLUDES
-#  include "arch/epstruct.h"
-#endif
-
-/** start DHCP configuration */
-err_t dhcp_start(struct netif *netif);
-/** enforce early lease renewal (not needed normally)*/
-err_t dhcp_renew(struct netif *netif);
-/** release the DHCP lease, usually called before dhcp_stop()*/
-err_t dhcp_release(struct netif *netif);
-/** stop DHCP configuration */
-void dhcp_stop(struct netif *netif);
-/** inform server of our manual IP address */
-void dhcp_inform(struct netif *netif);
-
-/** if enabled, check whether the offered IP address is not in use, using ARP */
-#if DHCP_DOES_ARP_CHECK
-void dhcp_arp_reply(struct netif *netif, struct ip_addr *addr);
-#endif
-
-/** to be called every minute */
-void dhcp_coarse_tmr(void);
-/** to be called every half second */
-void dhcp_fine_tmr(void);
-/** DHCP message item offsets and length */
-#define DHCP_MSG_OFS (UDP_DATA_OFS)  
-  #define DHCP_OP_OFS (DHCP_MSG_OFS + 0)
-  #define DHCP_HTYPE_OFS (DHCP_MSG_OFS + 1)
-  #define DHCP_HLEN_OFS (DHCP_MSG_OFS + 2)
-  #define DHCP_HOPS_OFS (DHCP_MSG_OFS + 3)
-  #define DHCP_XID_OFS (DHCP_MSG_OFS + 4)
-  #define DHCP_SECS_OFS (DHCP_MSG_OFS + 8)
-  #define DHCP_FLAGS_OFS (DHCP_MSG_OFS + 10)
-  #define DHCP_CIADDR_OFS (DHCP_MSG_OFS + 12)
-  #define DHCP_YIADDR_OFS (DHCP_MSG_OFS + 16)
-  #define DHCP_SIADDR_OFS (DHCP_MSG_OFS + 20)
-  #define DHCP_GIADDR_OFS (DHCP_MSG_OFS + 24)
-  #define DHCP_CHADDR_OFS (DHCP_MSG_OFS + 28)
-  #define DHCP_SNAME_OFS (DHCP_MSG_OFS + 44)
-  #define DHCP_FILE_OFS (DHCP_MSG_OFS + 108)
-#define DHCP_MSG_LEN 236
-
-#define DHCP_COOKIE_OFS (DHCP_MSG_OFS + DHCP_MSG_LEN)
-#define DHCP_OPTIONS_OFS (DHCP_MSG_OFS + DHCP_MSG_LEN + 4)
-
-#define DHCP_CLIENT_PORT 68  
-#define DHCP_SERVER_PORT 67
-
-/** DHCP client states */
-#define DHCP_REQUESTING 1
-#define DHCP_INIT 2
-#define DHCP_REBOOTING 3
-#define DHCP_REBINDING 4
-#define DHCP_RENEWING 5
-#define DHCP_SELECTING 6
-#define DHCP_INFORMING 7
-#define DHCP_CHECKING 8
-#define DHCP_PERMANENT 9
-#define DHCP_BOUND 10
-/** not yet implemented #define DHCP_RELEASING 11 */
-#define DHCP_BACKING_OFF 12
-#define DHCP_OFF 13
-#define DHCP_BOOTREQUEST 1
-#define DHCP_BOOTREPLY 2
-
-#define DHCP_DISCOVER 1
-#define DHCP_OFFER 2
-#define DHCP_REQUEST 3
-#define DHCP_DECLINE 4
-#define DHCP_ACK 5
-#define DHCP_NAK 6
-#define DHCP_RELEASE 7
-#define DHCP_INFORM 8
-
-#define DHCP_HTYPE_ETH 1
-
-#define DHCP_HLEN_ETH 6
-
-#define DHCP_BROADCAST_FLAG 15
-#define DHCP_BROADCAST_MASK (1 << DHCP_FLAG_BROADCAST)
-
-/** BootP options */
-#define DHCP_OPTION_PAD 0
-#define DHCP_OPTION_SUBNET_MASK 1 /* RFC 2132 3.3 */
-#define DHCP_OPTION_ROUTER 3
-#define DHCP_OPTION_DNS_SERVER 6 
-#define DHCP_OPTION_HOSTNAME 12
-#define DHCP_OPTION_IP_TTL 23
-#define DHCP_OPTION_MTU 26
-#define DHCP_OPTION_BROADCAST 28
-#define DHCP_OPTION_TCP_TTL 37
-#define DHCP_OPTION_END 255
-
-/** DHCP options */
-#define DHCP_OPTION_REQUESTED_IP 50 /* RFC 2132 9.1, requested IP address */
-#define DHCP_OPTION_LEASE_TIME 51 /* RFC 2132 9.2, time in seconds, in 4 bytes */
-#define DHCP_OPTION_OVERLOAD 52 /* RFC2132 9.3, use file and/or sname field for options */
-
-#define DHCP_OPTION_MESSAGE_TYPE 53 /* RFC 2132 9.6, important for DHCP */
-#define DHCP_OPTION_MESSAGE_TYPE_LEN 1
-
-
-#define DHCP_OPTION_SERVER_ID 54 /* RFC 2132 9.7, server IP address */
-#define DHCP_OPTION_PARAMETER_REQUEST_LIST 55 /* RFC 2132 9.8, requested option types */
-
-#define DHCP_OPTION_MAX_MSG_SIZE 57 /* RFC 2132 9.10, message size accepted >= 576 */
-#define DHCP_OPTION_MAX_MSG_SIZE_LEN 2
-
-#define DHCP_OPTION_T1 58 /* T1 renewal time */
-#define DHCP_OPTION_T2 59 /* T2 rebinding time */
-#define DHCP_OPTION_CLIENT_ID 61
-#define DHCP_OPTION_TFTP_SERVERNAME 66
-#define DHCP_OPTION_BOOTFILE 67
-
-/** possible combinations of overloading the file and sname fields with options */
-#define DHCP_OVERLOAD_NONE 0
-#define DHCP_OVERLOAD_FILE 1
-#define DHCP_OVERLOAD_SNAME  2
-#define DHCP_OVERLOAD_SNAME_FILE 3
-
-#endif /*__LWIP_DHCP_H__*/
+/** @file\r
+ */\r
+\r
+#ifndef __LWIP_DHCP_H__\r
+#define __LWIP_DHCP_H__\r
+\r
+#include "lwip/opt.h"\r
+#include "lwip/netif.h"\r
+#include "lwip/udp.h"\r
+\r
+/** period (in seconds) of the application calling dhcp_coarse_tmr() */\r
+#define DHCP_COARSE_TIMER_SECS 60 \r
+/** period (in milliseconds) of the application calling dhcp_fine_tmr() */\r
+#define DHCP_FINE_TIMER_MSECS 500 \r
+\r
+struct dhcp\r
+{\r
+  /** current DHCP state machine state */\r
+  u8_t state;\r
+  /** retries of current request */\r
+  u8_t tries;\r
+  /** transaction identifier of last sent request */ \r
+  u32_t xid;\r
+  /** our connection to the DHCP server */ \r
+  struct udp_pcb *pcb;\r
+  /** (first) pbuf of incoming msg */\r
+  struct pbuf *p;\r
+  /** incoming msg */\r
+  struct dhcp_msg *msg_in;\r
+  /** incoming msg options */\r
+  struct dhcp_msg *options_in; \r
+  /** ingoing msg options length */\r
+  u16_t options_in_len;\r
+\r
+  struct pbuf *p_out; /* pbuf of outcoming msg */\r
+  struct dhcp_msg *msg_out; /* outgoing msg */\r
+  u16_t options_out_len; /* outgoing msg options length */\r
+  u16_t request_timeout; /* #ticks with period DHCP_FINE_TIMER_SECS for request timeout */\r
+  u16_t t1_timeout;  /* #ticks with period DHCP_COARSE_TIMER_SECS for renewal time */\r
+  u16_t t2_timeout;  /* #ticks with period DHCP_COARSE_TIMER_SECS for rebind time */\r
+  struct ip_addr server_ip_addr; /* dhcp server address that offered this lease */\r
+  struct ip_addr offered_ip_addr;\r
+  struct ip_addr offered_sn_mask;\r
+  struct ip_addr offered_gw_addr;\r
+  struct ip_addr offered_bc_addr;\r
+#define DHCP_MAX_DNS 2\r
+  u32_t dns_count; /* actual number of DNS servers obtained */\r
+  struct ip_addr offered_dns_addr[DHCP_MAX_DNS]; /* DNS server addresses */\r
\r
+  u32_t offered_t0_lease; /* lease period (in seconds) */\r
+  u32_t offered_t1_renew; /* recommended renew time (usually 50% of lease period) */\r
+  u32_t offered_t2_rebind; /* recommended rebind time (usually 66% of lease period)  */\r
+/** Patch #1308\r
+ *  TODO: See dhcp.c "TODO"s\r
+ */\r
+#if 0\r
+  struct ip_addr offered_si_addr;\r
+  u8_t *boot_file_name;\r
+#endif\r
+};\r
+\r
+/* MUST be compiled with "pack structs" or equivalent! */\r
+#ifdef PACK_STRUCT_USE_INCLUDES\r
+#  include "arch/bpstruct.h"\r
+#endif\r
+PACK_STRUCT_BEGIN\r
+/** minimum set of fields of any DHCP message */\r
+struct dhcp_msg\r
+{\r
+  PACK_STRUCT_FIELD(u8_t op);\r
+  PACK_STRUCT_FIELD(u8_t htype);\r
+  PACK_STRUCT_FIELD(u8_t hlen);\r
+  PACK_STRUCT_FIELD(u8_t hops);\r
+  PACK_STRUCT_FIELD(u32_t xid);\r
+  PACK_STRUCT_FIELD(u16_t secs);\r
+  PACK_STRUCT_FIELD(u16_t flags);\r
+  PACK_STRUCT_FIELD(struct ip_addr ciaddr);\r
+  PACK_STRUCT_FIELD(struct ip_addr yiaddr);\r
+  PACK_STRUCT_FIELD(struct ip_addr siaddr);\r
+  PACK_STRUCT_FIELD(struct ip_addr giaddr);\r
+#define DHCP_CHADDR_LEN 16U\r
+  PACK_STRUCT_FIELD(u8_t chaddr[DHCP_CHADDR_LEN]);\r
+#define DHCP_SNAME_LEN 64U\r
+  PACK_STRUCT_FIELD(u8_t sname[DHCP_SNAME_LEN]);\r
+#define DHCP_FILE_LEN 128U\r
+  PACK_STRUCT_FIELD(u8_t file[DHCP_FILE_LEN]);\r
+  PACK_STRUCT_FIELD(u32_t cookie);\r
+#define DHCP_MIN_OPTIONS_LEN 68U\r
+/** make sure user does not configure this too small */\r
+#if ((defined(DHCP_OPTIONS_LEN)) && (DHCP_OPTIONS_LEN < DHCP_MIN_OPTIONS_LEN))\r
+#  undef DHCP_OPTIONS_LEN\r
+#endif\r
+/** allow this to be configured in lwipopts.h, but not too small */\r
+#if (!defined(DHCP_OPTIONS_LEN))\r
+/** set this to be sufficient for your options in outgoing DHCP msgs */\r
+#  define DHCP_OPTIONS_LEN DHCP_MIN_OPTIONS_LEN\r
+#endif\r
+  PACK_STRUCT_FIELD(u8_t options[DHCP_OPTIONS_LEN]);\r
+} PACK_STRUCT_STRUCT;\r
+PACK_STRUCT_END\r
+#ifdef PACK_STRUCT_USE_INCLUDES\r
+#  include "arch/epstruct.h"\r
+#endif\r
+\r
+/** start DHCP configuration */\r
+err_t dhcp_start(struct netif *netif);\r
+/** enforce early lease renewal (not needed normally)*/\r
+err_t dhcp_renew(struct netif *netif);\r
+/** release the DHCP lease, usually called before dhcp_stop()*/\r
+err_t dhcp_release(struct netif *netif);\r
+/** stop DHCP configuration */\r
+void dhcp_stop(struct netif *netif);\r
+/** inform server of our manual IP address */\r
+void dhcp_inform(struct netif *netif);\r
+\r
+/** if enabled, check whether the offered IP address is not in use, using ARP */\r
+#if DHCP_DOES_ARP_CHECK\r
+void dhcp_arp_reply(struct netif *netif, struct ip_addr *addr);\r
+#endif\r
+\r
+/** to be called every minute */\r
+void dhcp_coarse_tmr(void);\r
+/** to be called every half second */\r
+void dhcp_fine_tmr(void);\r
\r
+/** DHCP message item offsets and length */\r
+#define DHCP_MSG_OFS (UDP_DATA_OFS)  \r
+  #define DHCP_OP_OFS (DHCP_MSG_OFS + 0)\r
+  #define DHCP_HTYPE_OFS (DHCP_MSG_OFS + 1)\r
+  #define DHCP_HLEN_OFS (DHCP_MSG_OFS + 2)\r
+  #define DHCP_HOPS_OFS (DHCP_MSG_OFS + 3)\r
+  #define DHCP_XID_OFS (DHCP_MSG_OFS + 4)\r
+  #define DHCP_SECS_OFS (DHCP_MSG_OFS + 8)\r
+  #define DHCP_FLAGS_OFS (DHCP_MSG_OFS + 10)\r
+  #define DHCP_CIADDR_OFS (DHCP_MSG_OFS + 12)\r
+  #define DHCP_YIADDR_OFS (DHCP_MSG_OFS + 16)\r
+  #define DHCP_SIADDR_OFS (DHCP_MSG_OFS + 20)\r
+  #define DHCP_GIADDR_OFS (DHCP_MSG_OFS + 24)\r
+  #define DHCP_CHADDR_OFS (DHCP_MSG_OFS + 28)\r
+  #define DHCP_SNAME_OFS (DHCP_MSG_OFS + 44)\r
+  #define DHCP_FILE_OFS (DHCP_MSG_OFS + 108)\r
+#define DHCP_MSG_LEN 236\r
+\r
+#define DHCP_COOKIE_OFS (DHCP_MSG_OFS + DHCP_MSG_LEN)\r
+#define DHCP_OPTIONS_OFS (DHCP_MSG_OFS + DHCP_MSG_LEN + 4)\r
+\r
+#define DHCP_CLIENT_PORT 68  \r
+#define DHCP_SERVER_PORT 67\r
+\r
+/** DHCP client states */\r
+#define DHCP_REQUESTING 1\r
+#define DHCP_INIT 2\r
+#define DHCP_REBOOTING 3\r
+#define DHCP_REBINDING 4\r
+#define DHCP_RENEWING 5\r
+#define DHCP_SELECTING 6\r
+#define DHCP_INFORMING 7\r
+#define DHCP_CHECKING 8\r
+#define DHCP_PERMANENT 9\r
+#define DHCP_BOUND 10\r
+/** not yet implemented #define DHCP_RELEASING 11 */\r
+#define DHCP_BACKING_OFF 12\r
+#define DHCP_OFF 13\r
\r
+#define DHCP_BOOTREQUEST 1\r
+#define DHCP_BOOTREPLY 2\r
+\r
+#define DHCP_DISCOVER 1\r
+#define DHCP_OFFER 2\r
+#define DHCP_REQUEST 3\r
+#define DHCP_DECLINE 4\r
+#define DHCP_ACK 5\r
+#define DHCP_NAK 6\r
+#define DHCP_RELEASE 7\r
+#define DHCP_INFORM 8\r
+\r
+#define DHCP_HTYPE_ETH 1\r
+\r
+#define DHCP_HLEN_ETH 6\r
+\r
+#define DHCP_BROADCAST_FLAG 15\r
+#define DHCP_BROADCAST_MASK (1 << DHCP_FLAG_BROADCAST)\r
+\r
+/** BootP options */\r
+#define DHCP_OPTION_PAD 0\r
+#define DHCP_OPTION_SUBNET_MASK 1 /* RFC 2132 3.3 */\r
+#define DHCP_OPTION_ROUTER 3\r
+#define DHCP_OPTION_DNS_SERVER 6 \r
+#define DHCP_OPTION_HOSTNAME 12\r
+#define DHCP_OPTION_IP_TTL 23\r
+#define DHCP_OPTION_MTU 26\r
+#define DHCP_OPTION_BROADCAST 28\r
+#define DHCP_OPTION_TCP_TTL 37\r
+#define DHCP_OPTION_END 255\r
+\r
+/** DHCP options */\r
+#define DHCP_OPTION_REQUESTED_IP 50 /* RFC 2132 9.1, requested IP address */\r
+#define DHCP_OPTION_LEASE_TIME 51 /* RFC 2132 9.2, time in seconds, in 4 bytes */\r
+#define DHCP_OPTION_OVERLOAD 52 /* RFC2132 9.3, use file and/or sname field for options */\r
+\r
+#define DHCP_OPTION_MESSAGE_TYPE 53 /* RFC 2132 9.6, important for DHCP */\r
+#define DHCP_OPTION_MESSAGE_TYPE_LEN 1\r
+\r
+\r
+#define DHCP_OPTION_SERVER_ID 54 /* RFC 2132 9.7, server IP address */\r
+#define DHCP_OPTION_PARAMETER_REQUEST_LIST 55 /* RFC 2132 9.8, requested option types */\r
+\r
+#define DHCP_OPTION_MAX_MSG_SIZE 57 /* RFC 2132 9.10, message size accepted >= 576 */\r
+#define DHCP_OPTION_MAX_MSG_SIZE_LEN 2\r
+\r
+#define DHCP_OPTION_T1 58 /* T1 renewal time */\r
+#define DHCP_OPTION_T2 59 /* T2 rebinding time */\r
+#define DHCP_OPTION_CLIENT_ID 61\r
+#define DHCP_OPTION_TFTP_SERVERNAME 66\r
+#define DHCP_OPTION_BOOTFILE 67\r
+\r
+/** possible combinations of overloading the file and sname fields with options */\r
+#define DHCP_OVERLOAD_NONE 0\r
+#define DHCP_OVERLOAD_FILE 1\r
+#define DHCP_OVERLOAD_SNAME  2\r
+#define DHCP_OVERLOAD_SNAME_FILE 3\r
+\r
+#endif /*__LWIP_DHCP_H__*/\r
index c92cb26d7693e422706442c74715fbdc939e1417..fc90f2eabadb9418db10aa6ff8c6d9437c096736 100644 (file)
@@ -1,70 +1,70 @@
-/*
- * 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 <adam@sics.se>
- *
- */
-#ifndef __LWIP_ERR_H__
-#define __LWIP_ERR_H__
-
-#include "lwip/opt.h"
-
-#include "arch/cc.h"
-
-typedef s8_t err_t;
-
-/* Definitions for error constants. */
-
-#define ERR_OK    0      /* No error, everything OK. */
-#define ERR_MEM  -1      /* Out of memory error.     */
-#define ERR_BUF  -2      /* Buffer error.            */
-
-
-#define ERR_ABRT -3      /* Connection aborted.      */
-#define ERR_RST  -4      /* Connection reset.        */
-#define ERR_CLSD -5      /* Connection closed.       */
-#define ERR_CONN -6      /* Not connected.           */
-
-#define ERR_VAL  -7      /* Illegal value.           */
-
-#define ERR_ARG  -8      /* Illegal argument.        */
-
-#define ERR_RTE  -9      /* Routing problem.         */
-
-#define ERR_USE  -10     /* Address in use.          */
-
-#define ERR_IF   -11     /* Low-level netif error    */
-#define ERR_ISCONN -12   /* Already connected.       */
-
-
-#ifdef LWIP_DEBUG
-extern char *lwip_strerr(err_t err);
-#else
-#define lwip_strerr(x) ""
-#endif /* LWIP_DEBUG */
-#endif /* __LWIP_ERR_H__ */
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+#ifndef __LWIP_ERR_H__\r
+#define __LWIP_ERR_H__\r
+\r
+#include "lwip/opt.h"\r
+\r
+#include "arch/cc.h"\r
+\r
+typedef s8_t err_t;\r
+\r
+/* Definitions for error constants. */\r
+\r
+#define ERR_OK    0      /* No error, everything OK. */\r
+#define ERR_MEM  -1      /* Out of memory error.     */\r
+#define ERR_BUF  -2      /* Buffer error.            */\r
+\r
+\r
+#define ERR_ABRT -3      /* Connection aborted.      */\r
+#define ERR_RST  -4      /* Connection reset.        */\r
+#define ERR_CLSD -5      /* Connection closed.       */\r
+#define ERR_CONN -6      /* Not connected.           */\r
+\r
+#define ERR_VAL  -7      /* Illegal value.           */\r
+\r
+#define ERR_ARG  -8      /* Illegal argument.        */\r
+\r
+#define ERR_RTE  -9      /* Routing problem.         */\r
+\r
+#define ERR_USE  -10     /* Address in use.          */\r
+\r
+#define ERR_IF   -11     /* Low-level netif error    */\r
+#define ERR_ISCONN -12   /* Already connected.       */\r
+\r
+\r
+#ifdef LWIP_DEBUG\r
+extern char *lwip_strerr(err_t err);\r
+#else\r
+#define lwip_strerr(x) ""\r
+#endif /* LWIP_DEBUG */\r
+#endif /* __LWIP_ERR_H__ */\r
index ee6fea7d8ceb7bf3dd1def96944501e9f83265be..b88ea9c8d1689b9a2c670dd0dc31d53701d687c9 100644 (file)
@@ -1,61 +1,61 @@
-/*
- * 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 <adam@sics.se>
- *
- */
-#ifndef __LWIP_MEM_H__
-#define __LWIP_MEM_H__
-
-#include "lwip/opt.h"
-#include "lwip/arch.h"
-
-#if MEM_SIZE > 64000l
-typedef u32_t mem_size_t;
-#else
-typedef u16_t mem_size_t;
-#endif /* MEM_SIZE > 64000 */
-
-
-void mem_init(void);
-
-void *mem_malloc(mem_size_t size);
-void mem_free(void *mem);
-void *mem_realloc(void *mem, mem_size_t size);
-void *mem_reallocm(void *mem, mem_size_t size);
-
-#ifndef MEM_ALIGN_SIZE
-#define MEM_ALIGN_SIZE(size) (((size) + MEM_ALIGNMENT - 1) & ~(MEM_ALIGNMENT-1))
-#endif
-
-#ifndef MEM_ALIGN
-#define MEM_ALIGN(addr) ((void *)(((mem_ptr_t)(addr) + MEM_ALIGNMENT - 1) & ~(mem_ptr_t)(MEM_ALIGNMENT-1)))
-#endif
-
-#endif /* __LWIP_MEM_H__ */
-
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+#ifndef __LWIP_MEM_H__\r
+#define __LWIP_MEM_H__\r
+\r
+#include "lwip/opt.h"\r
+#include "lwip/arch.h"\r
+\r
+#if MEM_SIZE > 64000l\r
+typedef u32_t mem_size_t;\r
+#else\r
+typedef u16_t mem_size_t;\r
+#endif /* MEM_SIZE > 64000 */\r
+\r
+\r
+void mem_init(void);\r
+\r
+void *mem_malloc(mem_size_t size);\r
+void mem_free(void *mem);\r
+void *mem_realloc(void *mem, mem_size_t size);\r
+void *mem_reallocm(void *mem, mem_size_t size);\r
+\r
+#ifndef MEM_ALIGN_SIZE\r
+#define MEM_ALIGN_SIZE(size) (((size) + MEM_ALIGNMENT - 1) & ~(MEM_ALIGNMENT-1))\r
+#endif\r
+\r
+#ifndef MEM_ALIGN\r
+#define MEM_ALIGN(addr) ((void *)(((mem_ptr_t)(addr) + MEM_ALIGNMENT - 1) & ~(mem_ptr_t)(MEM_ALIGNMENT-1)))\r
+#endif\r
+\r
+#endif /* __LWIP_MEM_H__ */\r
+\r
index 1cd46fa3fe378de2a896ed0624a2e2ca8610d6ba..6da033f27d3ea5b3612d98db2d4bb2a81faad605 100644 (file)
@@ -1,63 +1,63 @@
-/*
- * 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 <adam@sics.se>
- *
- */
-
-#ifndef __LWIP_MEMP_H__
-#define __LWIP_MEMP_H__
-
-#include "lwip/opt.h"
-
-typedef enum {
-  MEMP_PBUF,
-  MEMP_RAW_PCB,
-  MEMP_UDP_PCB,
-  MEMP_TCP_PCB,
-  MEMP_TCP_PCB_LISTEN,
-  MEMP_TCP_SEG,
-
-  MEMP_NETBUF,
-  MEMP_NETCONN,
-  MEMP_API_MSG,
-  MEMP_TCPIP_MSG,
-
-  MEMP_SYS_TIMEOUT,
-  
-  MEMP_MAX
-} memp_t;
-
-void memp_init(void);
-
-void *memp_malloc(memp_t type);
-void *memp_realloc(memp_t fromtype, memp_t totype, void *mem);
-void memp_free(memp_t type, void *mem);
-
-#endif /* __LWIP_MEMP_H__  */
-    
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+\r
+#ifndef __LWIP_MEMP_H__\r
+#define __LWIP_MEMP_H__\r
+\r
+#include "lwip/opt.h"\r
+\r
+typedef enum {\r
+  MEMP_PBUF,\r
+  MEMP_RAW_PCB,\r
+  MEMP_UDP_PCB,\r
+  MEMP_TCP_PCB,\r
+  MEMP_TCP_PCB_LISTEN,\r
+  MEMP_TCP_SEG,\r
+\r
+  MEMP_NETBUF,\r
+  MEMP_NETCONN,\r
+  MEMP_API_MSG,\r
+  MEMP_TCPIP_MSG,\r
+\r
+  MEMP_SYS_TIMEOUT,\r
+  \r
+  MEMP_MAX\r
+} memp_t;\r
+\r
+void memp_init(void);\r
+\r
+void *memp_malloc(memp_t type);\r
+void *memp_realloc(memp_t fromtype, memp_t totype, void *mem);\r
+void memp_free(memp_t type, void *mem);\r
+\r
+#endif /* __LWIP_MEMP_H__  */\r
+    \r
index d0bda2df93f4b15eee5b24ccd7c0c3ecbcaa41c4..d4a18ffbe185ed22a586415fdc3de5038cf75895 100644 (file)
-/*
- * 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 <adam@sics.se>
- *
- */
-#ifndef __LWIP_NETIF_H__
-#define __LWIP_NETIF_H__
-
-#include "lwip/opt.h"
-
-#include "lwip/err.h"
-
-#include "lwip/ip_addr.h"
-
-#include "lwip/inet.h"
-#include "lwip/pbuf.h"
-#if LWIP_DHCP
-#  include "lwip/dhcp.h"
-#endif
-
-/** must be the maximum of all used hardware address lengths
-    across all types of interfaces in use */
-#define NETIF_MAX_HWADDR_LEN 6U
-
-/** TODO: define the use (where, when, whom) of netif flags */
-
-/** whether the network interface is 'up'. this is
- * a software flag used to control whether this network
- * interface is enabled and processes traffic.
- */
-#define NETIF_FLAG_UP 0x1U
-/** if set, the netif has broadcast capability */
-#define NETIF_FLAG_BROADCAST 0x2U
-/** if set, the netif is one end of a point-to-point connection */
-#define NETIF_FLAG_POINTTOPOINT 0x4U
-/** if set, the interface is configured using DHCP */
-#define NETIF_FLAG_DHCP 0x08U
-/** if set, the interface has an active link
- *  (set by the network interface driver) */
-#define NETIF_FLAG_LINK_UP 0x10U
-
-/** Generic data structure used for all lwIP network interfaces.
- *  The following fields should be filled in by the initialization
- *  function for the device driver: hwaddr_len, hwaddr[], mtu, flags */
-
-struct netif {
-  /** pointer to next in linked list */
-  struct netif *next;
-
-  /** IP address configuration in network byte order */
-  struct ip_addr ip_addr;
-  struct ip_addr netmask;
-  struct ip_addr gw;
-
-  /** This function is called by the network device driver
-   *  to pass a packet up the TCP/IP stack. */
-  err_t (* input)(struct pbuf *p, struct netif *inp);
-  /** This function is called by the IP module when it wants
-   *  to send a packet on the interface. This function typically
-   *  first resolves the hardware address, then sends the packet. */
-  err_t (* output)(struct netif *netif, struct pbuf *p,
-       struct ip_addr *ipaddr);
-  /** This function is called by the ARP module when it wants
-   *  to send a packet on the interface. This function outputs
-   *  the pbuf as-is on the link medium. */
-  err_t (* linkoutput)(struct netif *netif, struct pbuf *p);
-  /** This field can be set by the device driver and could point
-   *  to state information for the device. */
-  void *state;
-#if LWIP_DHCP
-  /** the DHCP client state information for this netif */
-  struct dhcp *dhcp;
-#endif
-  /** number of bytes used in hwaddr */
-  unsigned char hwaddr_len;
-  /** link level hardware address of this interface */
-  unsigned char hwaddr[NETIF_MAX_HWADDR_LEN];
-  /** maximum transfer unit (in bytes) */
-  u16_t mtu;
-  /** flags (see NETIF_FLAG_ above) */
-  u8_t flags;
-  /** link type */
-  u8_t link_type;
-  /** descriptive abbreviation */
-  char name[2];
-  /** number of this interface */
-  u8_t num;
-};
-
-/** The list of network interfaces. */
-extern struct netif *netif_list;
-/** The default network interface. */
-extern struct netif *netif_default;
-
-/* netif_init() must be called first. */
-void netif_init(void);
-
-struct netif *netif_add(struct netif *netif, struct ip_addr *ipaddr, struct ip_addr *netmask,
-      struct ip_addr *gw,
-      void *state,
-      err_t (* init)(struct netif *netif),
-      err_t (* input)(struct pbuf *p, struct netif *netif));
-
-void
-netif_set_addr(struct netif *netif,struct ip_addr *ipaddr, struct ip_addr *netmask,
-    struct ip_addr *gw);
-void netif_remove(struct netif * netif);
-
-/* Returns a network interface given its name. The name is of the form
-   "et0", where the first two letters are the "name" field in the
-   netif structure, and the digit is in the num field in the same
-   structure. */
-struct netif *netif_find(char *name);
-
-void netif_set_default(struct netif *netif);
-
-void netif_set_ipaddr(struct netif *netif, struct ip_addr *ipaddr);
-void netif_set_netmask(struct netif *netif, struct ip_addr *netmast);
-void netif_set_gw(struct netif *netif, struct ip_addr *gw);
-void netif_set_up(struct netif *netif);
-void netif_set_down(struct netif *netif);
-u8_t netif_is_up(struct netif *netif);
-
-#endif /* __LWIP_NETIF_H__ */
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+#ifndef __LWIP_NETIF_H__\r
+#define __LWIP_NETIF_H__\r
+\r
+#include "lwip/opt.h"\r
+\r
+#include "lwip/err.h"\r
+\r
+#include "lwip/ip_addr.h"\r
+\r
+#include "lwip/inet.h"\r
+#include "lwip/pbuf.h"\r
+#if LWIP_DHCP\r
+#  include "lwip/dhcp.h"\r
+#endif\r
+\r
+/** must be the maximum of all used hardware address lengths\r
+    across all types of interfaces in use */\r
+#define NETIF_MAX_HWADDR_LEN 6U\r
+\r
+/** TODO: define the use (where, when, whom) of netif flags */\r
+\r
+/** whether the network interface is 'up'. this is\r
+ * a software flag used to control whether this network\r
+ * interface is enabled and processes traffic.\r
+ */\r
+#define NETIF_FLAG_UP 0x1U\r
+/** if set, the netif has broadcast capability */\r
+#define NETIF_FLAG_BROADCAST 0x2U\r
+/** if set, the netif is one end of a point-to-point connection */\r
+#define NETIF_FLAG_POINTTOPOINT 0x4U\r
+/** if set, the interface is configured using DHCP */\r
+#define NETIF_FLAG_DHCP 0x08U\r
+/** if set, the interface has an active link\r
+ *  (set by the network interface driver) */\r
+#define NETIF_FLAG_LINK_UP 0x10U\r
+\r
+/** Generic data structure used for all lwIP network interfaces.\r
+ *  The following fields should be filled in by the initialization\r
+ *  function for the device driver: hwaddr_len, hwaddr[], mtu, flags */\r
+\r
+struct netif {\r
+  /** pointer to next in linked list */\r
+  struct netif *next;\r
+\r
+  /** IP address configuration in network byte order */\r
+  struct ip_addr ip_addr;\r
+  struct ip_addr netmask;\r
+  struct ip_addr gw;\r
+\r
+  /** This function is called by the network device driver\r
+   *  to pass a packet up the TCP/IP stack. */\r
+  err_t (* input)(struct pbuf *p, struct netif *inp);\r
+  /** This function is called by the IP module when it wants\r
+   *  to send a packet on the interface. This function typically\r
+   *  first resolves the hardware address, then sends the packet. */\r
+  err_t (* output)(struct netif *netif, struct pbuf *p,\r
+       struct ip_addr *ipaddr);\r
+  /** This function is called by the ARP module when it wants\r
+   *  to send a packet on the interface. This function outputs\r
+   *  the pbuf as-is on the link medium. */\r
+  err_t (* linkoutput)(struct netif *netif, struct pbuf *p);\r
+  /** This field can be set by the device driver and could point\r
+   *  to state information for the device. */\r
+  void *state;\r
+#if LWIP_DHCP\r
+  /** the DHCP client state information for this netif */\r
+  struct dhcp *dhcp;\r
+#endif\r
+  /** number of bytes used in hwaddr */\r
+  unsigned char hwaddr_len;\r
+  /** link level hardware address of this interface */\r
+  unsigned char hwaddr[NETIF_MAX_HWADDR_LEN];\r
+  /** maximum transfer unit (in bytes) */\r
+  u16_t mtu;\r
+  /** flags (see NETIF_FLAG_ above) */\r
+  u8_t flags;\r
+  /** link type */\r
+  u8_t link_type;\r
+  /** descriptive abbreviation */\r
+  char name[2];\r
+  /** number of this interface */\r
+  u8_t num;\r
+};\r
+\r
+/** The list of network interfaces. */\r
+extern struct netif *netif_list;\r
+/** The default network interface. */\r
+extern struct netif *netif_default;\r
+\r
+/* netif_init() must be called first. */\r
+void netif_init(void);\r
+\r
+struct netif *netif_add(struct netif *netif, struct ip_addr *ipaddr, struct ip_addr *netmask,\r
+      struct ip_addr *gw,\r
+      void *state,\r
+      err_t (* init)(struct netif *netif),\r
+      err_t (* input)(struct pbuf *p, struct netif *netif));\r
+\r
+void\r
+netif_set_addr(struct netif *netif,struct ip_addr *ipaddr, struct ip_addr *netmask,\r
+    struct ip_addr *gw);\r
+void netif_remove(struct netif * netif);\r
+\r
+/* Returns a network interface given its name. The name is of the form\r
+   "et0", where the first two letters are the "name" field in the\r
+   netif structure, and the digit is in the num field in the same\r
+   structure. */\r
+struct netif *netif_find(char *name);\r
+\r
+void netif_set_default(struct netif *netif);\r
+\r
+void netif_set_ipaddr(struct netif *netif, struct ip_addr *ipaddr);\r
+void netif_set_netmask(struct netif *netif, struct ip_addr *netmast);\r
+void netif_set_gw(struct netif *netif, struct ip_addr *gw);\r
+void netif_set_up(struct netif *netif);\r
+void netif_set_down(struct netif *netif);\r
+u8_t netif_is_up(struct netif *netif);\r
+\r
+#endif /* __LWIP_NETIF_H__ */\r
index 8e3910d52bf3a1b2f2b1f4455aa67de9bf5e7097..f8c18221e2dfc2b779d750f903de8fbcf534783c 100644 (file)
-/*
- * 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 <adam@sics.se>
- *
- */
-#ifndef __LWIP_OPT_H__
-#define __LWIP_OPT_H__
-
-/* Include user defined options first */
-#include "lwipopts.h"
-#include "lwip/debug.h"
-
-/* Define default values for unconfigured parameters. */
-
-/* Platform specific locking */
-
-/*
- * enable SYS_LIGHTWEIGHT_PROT in lwipopts.h if you want inter-task protection
- * for certain critical regions during buffer allocation, deallocation and memory
- * allocation and deallocation.
- */
-#ifndef SYS_LIGHTWEIGHT_PROT
-#define SYS_LIGHTWEIGHT_PROT            0
-#endif
-
-#ifndef NO_SYS
-#define NO_SYS                          0
-#endif
-/* ---------- Memory options ---------- */
-/* MEM_ALIGNMENT: should be set to the alignment of the CPU for which
-   lwIP is compiled. 4 byte alignment -> define MEM_ALIGNMENT to 4, 2
-   byte alignment -> define MEM_ALIGNMENT to 2. */
-
-#ifndef MEM_ALIGNMENT
-#define MEM_ALIGNMENT                   1
-#endif
-
-/* MEM_SIZE: the size of the heap memory. If the application will send
-a lot of data that needs to be copied, this should be set high. */
-#ifndef MEM_SIZE
-#define MEM_SIZE                        1600
-#endif
-
-#ifndef MEMP_SANITY_CHECK
-#define MEMP_SANITY_CHECK              0
-#endif
-
-/* MEMP_NUM_PBUF: the number of memp struct pbufs. If the application
-   sends a lot of data out of ROM (or other static memory), this
-   should be set high. */
-#ifndef MEMP_NUM_PBUF
-#define MEMP_NUM_PBUF                   16
-#endif
-
-/* Number of raw connection PCBs */
-#ifndef MEMP_NUM_RAW_PCB
-#define MEMP_NUM_RAW_PCB                4
-#endif
-
-/* MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One
-   per active UDP "connection". */
-#ifndef MEMP_NUM_UDP_PCB
-#define MEMP_NUM_UDP_PCB                4
-#endif
-/* MEMP_NUM_TCP_PCB: the number of simulatenously active TCP
-   connections. */
-#ifndef MEMP_NUM_TCP_PCB
-#define MEMP_NUM_TCP_PCB                5
-#endif
-/* MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP
-   connections. */
-#ifndef MEMP_NUM_TCP_PCB_LISTEN
-#define MEMP_NUM_TCP_PCB_LISTEN         8
-#endif
-/* MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP
-   segments. */
-#ifndef MEMP_NUM_TCP_SEG
-#define MEMP_NUM_TCP_SEG                16
-#endif
-/* MEMP_NUM_SYS_TIMEOUT: the number of simulateously active
-   timeouts. */
-#ifndef MEMP_NUM_SYS_TIMEOUT
-#define MEMP_NUM_SYS_TIMEOUT            3
-#endif
-
-/* The following four are used only with the sequential API and can be
-   set to 0 if the application only will use the raw API. */
-/* MEMP_NUM_NETBUF: the number of struct netbufs. */
-#ifndef MEMP_NUM_NETBUF
-#define MEMP_NUM_NETBUF                 2
-#endif
-/* MEMP_NUM_NETCONN: the number of struct netconns. */
-#ifndef MEMP_NUM_NETCONN
-#define MEMP_NUM_NETCONN                4
-#endif
-/* MEMP_NUM_APIMSG: the number of struct api_msg, used for
-   communication between the TCP/IP stack and the sequential
-   programs. */
-#ifndef MEMP_NUM_API_MSG
-#define MEMP_NUM_API_MSG                8
-#endif
-/* MEMP_NUM_TCPIPMSG: the number of struct tcpip_msg, which is used
-   for sequential API communication and incoming packets. Used in
-   src/api/tcpip.c. */
-#ifndef MEMP_NUM_TCPIP_MSG
-#define MEMP_NUM_TCPIP_MSG              8
-#endif
-
-/* ---------- Pbuf options ---------- */
-/* PBUF_POOL_SIZE: the number of buffers in the pbuf pool. */
-
-#ifndef PBUF_POOL_SIZE
-#define PBUF_POOL_SIZE                  16
-#endif
-
-/* PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. */
-
-#ifndef PBUF_POOL_BUFSIZE
-#define PBUF_POOL_BUFSIZE               128
-#endif
-
-/* PBUF_LINK_HLEN: the number of bytes that should be allocated for a
-   link level header. Defaults to 14 for Ethernet. */
-
-#ifndef PBUF_LINK_HLEN
-#define PBUF_LINK_HLEN                  14
-#endif
-
-
-
-/* ---------- ARP options ---------- */
-
-/** Number of active hardware address, IP address pairs cached */
-#ifndef ARP_TABLE_SIZE
-#define ARP_TABLE_SIZE                  10
-#endif
-
-/**
- * If enabled, outgoing packets are queued during hardware address
- * resolution.
- *
- * This feature has not stabilized yet. Single-packet queueing is
- * believed to be stable, multi-packet queueing is believed to
- * clash with the TCP segment queueing.
- * 
- * As multi-packet-queueing is currently disabled, enabling this
- * _should_ work, but we need your testing feedback on lwip-users.
- *
- */
-#ifndef ARP_QUEUEING
-#define ARP_QUEUEING                    1
-#endif
-
-/* This option is deprecated */
-#ifdef ETHARP_QUEUE_FIRST
-#error ETHARP_QUEUE_FIRST option is deprecated. Remove it from your lwipopts.h.
-#endif
-
-/* This option is removed to comply with the ARP standard */
-#ifdef ETHARP_ALWAYS_INSERT
-#error ETHARP_ALWAYS_INSERT option is deprecated. Remove it from your lwipopts.h.
-#endif
-
-/* ---------- IP options ---------- */
-/* Define IP_FORWARD to 1 if you wish to have the ability to forward
-   IP packets across network interfaces. If you are going to run lwIP
-   on a device with only one network interface, define this to 0. */
-#ifndef IP_FORWARD
-#define IP_FORWARD                      0
-#endif
-
-/* If defined to 1, IP options are allowed (but not parsed). If
-   defined to 0, all packets with IP options are dropped. */
-#ifndef IP_OPTIONS
-#define IP_OPTIONS                      1
-#endif
-
-/** IP reassembly and segmentation. Even if they both deal with IP
- *  fragments, note that these are orthogonal, one dealing with incoming
- *  packets, the other with outgoing packets
- */
-
-/** Reassemble incoming fragmented IP packets */
-#ifndef IP_REASSEMBLY
-#define IP_REASSEMBLY                   1
-#endif
-
-/** Fragment outgoing IP packets if their size exceeds MTU */
-#ifndef IP_FRAG
-#define IP_FRAG                         1
-#endif
-
-/* ---------- ICMP options ---------- */
-
-#ifndef ICMP_TTL
-#define ICMP_TTL                        255
-#endif
-
-/* ---------- RAW options ---------- */
-
-#ifndef LWIP_RAW
-#define LWIP_RAW                        1
-#endif
-
-#ifndef RAW_TTL
-#define RAW_TTL                        255
-#endif
-
-/* ---------- DHCP options ---------- */
-
-#ifndef LWIP_DHCP
-#define LWIP_DHCP                       0
-#endif
-
-/* 1 if you want to do an ARP check on the offered address
-   (recommended). */
-#ifndef DHCP_DOES_ARP_CHECK
-#define DHCP_DOES_ARP_CHECK             1
-#endif
-
-/* ---------- UDP options ---------- */
-#ifndef LWIP_UDP
-#define LWIP_UDP                        1
-#endif
-
-#ifndef UDP_TTL
-#define UDP_TTL                         255
-#endif
-
-/* ---------- TCP options ---------- */
-#ifndef LWIP_TCP
-#define LWIP_TCP                        1
-#endif
-
-#ifndef TCP_TTL
-#define TCP_TTL                         255
-#endif
-
-#ifndef TCP_WND
-#define TCP_WND                         2048
-#endif 
-
-#ifndef TCP_MAXRTX
-#define TCP_MAXRTX                      12
-#endif
-
-#ifndef TCP_SYNMAXRTX
-#define TCP_SYNMAXRTX                   6
-#endif
-
-
-/* Controls if TCP should queue segments that arrive out of
-   order. Define to 0 if your device is low on memory. */
-#ifndef TCP_QUEUE_OOSEQ
-#define TCP_QUEUE_OOSEQ                 1
-#endif
-
-/* TCP Maximum segment size. */
-#ifndef TCP_MSS
-#define TCP_MSS                         128 /* A *very* conservative default. */
-#endif
-
-/* TCP sender buffer space (bytes). */
-#ifndef TCP_SND_BUF
-#define TCP_SND_BUF                     256
-#endif
-
-/* TCP sender buffer space (pbufs). This must be at least = 2 *
-   TCP_SND_BUF/TCP_MSS for things to work. */
-#ifndef TCP_SND_QUEUELEN
-#define TCP_SND_QUEUELEN                4 * TCP_SND_BUF/TCP_MSS
-#endif
-
-
-/* Maximum number of retransmissions of data segments. */
-
-/* Maximum number of retransmissions of SYN segments. */
-
-/* TCP writable space (bytes). This must be less than or equal
-   to TCP_SND_BUF. It is the amount of space which must be
-   available in the tcp snd_buf for select to return writable */
-#ifndef TCP_SNDLOWAT
-#define TCP_SNDLOWAT                    TCP_SND_BUF/2
-#endif
-
-/* Support loop interface (127.0.0.1) */
-#ifndef LWIP_HAVE_LOOPIF
-#define LWIP_HAVE_LOOPIF               1
-#endif
-
-#ifndef LWIP_EVENT_API
-#define LWIP_EVENT_API                  0
-#define LWIP_CALLBACK_API               1
-#else 
-#define LWIP_EVENT_API                  1
-#define LWIP_CALLBACK_API               0
-#endif 
-
-#ifndef LWIP_COMPAT_SOCKETS
-#define LWIP_COMPAT_SOCKETS             1
-#endif
-
-
-#ifndef TCPIP_THREAD_PRIO
-#define TCPIP_THREAD_PRIO               1
-#endif
-
-#ifndef SLIPIF_THREAD_PRIO
-#define SLIPIF_THREAD_PRIO              1
-#endif
-
-#ifndef PPP_THREAD_PRIO
-#define PPP_THREAD_PRIO                 1
-#endif
-
-#ifndef DEFAULT_THREAD_PRIO
-#define DEFAULT_THREAD_PRIO             1
-#endif
-
-
-/* ---------- Socket Options ---------- */
-/* Enable SO_REUSEADDR and SO_REUSEPORT options */ 
-#ifndef SO_REUSE
-# define SO_REUSE 0
-#endif                                                                        
-
-
-/* ---------- Statistics options ---------- */
-#ifndef LWIP_STATS
-#define LWIP_STATS                      1
-#endif
-
-#if LWIP_STATS
-
-#ifndef LWIP_STATS_DISPLAY
-#define LWIP_STATS_DISPLAY 0
-#endif
-
-#ifndef LINK_STATS
-#define LINK_STATS     1
-#endif
-
-#ifndef IP_STATS
-#define IP_STATS       1
-#endif
-
-#ifndef IPFRAG_STATS
-#define IPFRAG_STATS   1
-#endif
-
-#ifndef ICMP_STATS
-#define ICMP_STATS     1
-#endif
-
-#ifndef UDP_STATS
-#define UDP_STATS      1
-#endif
-
-#ifndef TCP_STATS
-#define TCP_STATS      1
-#endif
-
-#ifndef MEM_STATS
-#define MEM_STATS      1
-#endif
-
-#ifndef MEMP_STATS
-#define MEMP_STATS     1
-#endif
-
-#ifndef PBUF_STATS
-#define PBUF_STATS     1
-#endif
-
-#ifndef SYS_STATS
-#define SYS_STATS      1
-#endif
-
-#ifndef RAW_STATS
-#define RAW_STATS      0
-#endif
-
-#else
-
-#define LINK_STATS     0
-#define IP_STATS       0
-#define IPFRAG_STATS   0
-#define ICMP_STATS     0
-#define UDP_STATS      0
-#define TCP_STATS      0
-#define MEM_STATS      0
-#define MEMP_STATS     0
-#define PBUF_STATS     0
-#define SYS_STATS      0
-#define RAW_STATS      0
-#define LWIP_STATS_DISPLAY     0
-
-#endif /* LWIP_STATS */
-
-/* ---------- PPP options ---------- */
-
-#ifndef PPP_SUPPORT
-#define PPP_SUPPORT                     0      /* Set for PPP */
-#endif
-
-#if PPP_SUPPORT 
-
-#define NUM_PPP                         1      /* Max PPP sessions. */
-
-
-
-#ifndef PAP_SUPPORT
-#define PAP_SUPPORT                     0      /* Set for PAP. */
-#endif
-
-#ifndef CHAP_SUPPORT
-#define CHAP_SUPPORT                    0      /* Set for CHAP. */
-#endif
-
-#define MSCHAP_SUPPORT                  0      /* Set for MSCHAP (NOT FUNCTIONAL!) */
-#define CBCP_SUPPORT                    0      /* Set for CBCP (NOT FUNCTIONAL!) */
-#define CCP_SUPPORT                     0      /* Set for CCP (NOT FUNCTIONAL!) */
-
-#ifndef VJ_SUPPORT
-#define VJ_SUPPORT                      0      /* Set for VJ header compression. */
-#endif
-
-#ifndef MD5_SUPPORT
-#define MD5_SUPPORT                     0      /* Set for MD5 (see also CHAP) */
-#endif
-
-
-/*
- * Timeouts.
- */
-#define FSM_DEFTIMEOUT                  6       /* Timeout time in seconds */
-#define FSM_DEFMAXTERMREQS              2       /* Maximum Terminate-Request transmissions */
-#define FSM_DEFMAXCONFREQS              10      /* Maximum Configure-Request transmissions */
-#define FSM_DEFMAXNAKLOOPS              5       /* Maximum number of nak loops */
-
-#define UPAP_DEFTIMEOUT                 6       /* Timeout (seconds) for retransmitting req */
-#define UPAP_DEFREQTIME                 30      /* Time to wait for auth-req from peer */
-
-#define CHAP_DEFTIMEOUT                 6       /* Timeout time in seconds */
-#define CHAP_DEFTRANSMITS               10      /* max # times to send challenge */
-
-
-/* Interval in seconds between keepalive echo requests, 0 to disable. */
-#if 1
-#define LCP_ECHOINTERVAL                0
-#else
-#define LCP_ECHOINTERVAL                10
-#endif
-
-/* Number of unanswered echo requests before failure. */
-#define LCP_MAXECHOFAILS                3
-
-/* Max Xmit idle time (in jiffies) before resend flag char. */
-#define PPP_MAXIDLEFLAG                 100
-
-/*
- * Packet sizes
- *
- * Note - lcp shouldn't be allowed to negotiate stuff outside these
- *    limits.  See lcp.h in the pppd directory.
- * (XXX - these constants should simply be shared by lcp.c instead
- *    of living in lcp.h)
- */
-#define PPP_MTU                         1500     /* Default MTU (size of Info field) */
-#if 0
-#define PPP_MAXMTU  65535 - (PPP_HDRLEN + PPP_FCSLEN)
-#else
-#define PPP_MAXMTU                      1500 /* Largest MTU we allow */
-#endif
-#define PPP_MINMTU                      64
-#define PPP_MRU                         1500     /* default MRU = max length of info field */
-#define PPP_MAXMRU                      1500     /* Largest MRU we allow */
-#define PPP_DEFMRU                      296             /* Try for this */
-#define PPP_MINMRU                      128             /* No MRUs below this */
-
-
-#define MAXNAMELEN                      256     /* max length of hostname or name for auth */
-#define MAXSECRETLEN                    256     /* max length of password or secret */
-
-#endif /* PPP_SUPPORT */
-
-/* checksum options - set to zero for hardware checksum support */
-
-#ifndef CHECKSUM_GEN_IP
-#define CHECKSUM_GEN_IP                 1
-#endif
-#ifndef CHECKSUM_GEN_UDP
-#define CHECKSUM_GEN_UDP                1
-#endif
-#ifndef CHECKSUM_GEN_TCP
-#define CHECKSUM_GEN_TCP                1
-#endif
-#ifndef CHECKSUM_CHECK_IP
-#define CHECKSUM_CHECK_IP               1
-#endif
-#ifndef CHECKSUM_CHECK_UDP
-#define CHECKSUM_CHECK_UDP              1
-#endif
-
-#ifndef CHECKSUM_CHECK_TCP
-#define CHECKSUM_CHECK_TCP              1
-#endif
-
-/* Debugging options all default to off */
-
-#ifndef DBG_TYPES_ON
-#define DBG_TYPES_ON                    0
-#endif
-
-#ifndef ETHARP_DEBUG
-#define ETHARP_DEBUG                    DBG_OFF
-#endif
-
-#ifndef NETIF_DEBUG
-#define NETIF_DEBUG                     DBG_OFF
-#endif
-
-#ifndef PBUF_DEBUG
-#define PBUF_DEBUG                      DBG_OFF
-#endif
-
-#ifndef API_LIB_DEBUG
-#define API_LIB_DEBUG                   DBG_OFF
-#endif
-
-#ifndef API_MSG_DEBUG
-#define API_MSG_DEBUG                   DBG_OFF
-#endif
-
-#ifndef SOCKETS_DEBUG
-#define SOCKETS_DEBUG                   DBG_OFF
-#endif
-
-#ifndef ICMP_DEBUG
-#define ICMP_DEBUG                      DBG_OFF
-#endif
-
-#ifndef INET_DEBUG
-#define INET_DEBUG                      DBG_OFF
-#endif
-
-#ifndef IP_DEBUG
-#define IP_DEBUG                        DBG_OFF
-#endif
-
-#ifndef IP_REASS_DEBUG
-#define IP_REASS_DEBUG                  DBG_OFF
-#endif
-
-#ifndef RAW_DEBUG
-#define RAW_DEBUG                       DBG_OFF
-#endif
-
-#ifndef MEM_DEBUG
-#define MEM_DEBUG                       DBG_OFF
-#endif
-
-#ifndef MEMP_DEBUG
-#define MEMP_DEBUG                      DBG_OFF
-#endif
-
-#ifndef SYS_DEBUG
-#define SYS_DEBUG                       DBG_OFF
-#endif
-
-#ifndef TCP_DEBUG
-#define TCP_DEBUG                       DBG_OFF
-#endif
-
-#ifndef TCP_INPUT_DEBUG
-#define TCP_INPUT_DEBUG                 DBG_OFF
-#endif
-
-#ifndef TCP_FR_DEBUG
-#define TCP_FR_DEBUG                    DBG_OFF
-#endif
-
-#ifndef TCP_RTO_DEBUG
-#define TCP_RTO_DEBUG                   DBG_OFF
-#endif
-
-#ifndef TCP_REXMIT_DEBUG
-#define TCP_REXMIT_DEBUG                DBG_OFF
-#endif
-
-#ifndef TCP_CWND_DEBUG
-#define TCP_CWND_DEBUG                  DBG_OFF
-#endif
-
-#ifndef TCP_WND_DEBUG
-#define TCP_WND_DEBUG                   DBG_OFF
-#endif
-
-#ifndef TCP_OUTPUT_DEBUG
-#define TCP_OUTPUT_DEBUG                DBG_OFF
-#endif
-
-#ifndef TCP_RST_DEBUG
-#define TCP_RST_DEBUG                   DBG_OFF
-#endif
-
-#ifndef TCP_QLEN_DEBUG
-#define TCP_QLEN_DEBUG                  DBG_OFF
-#endif
-
-#ifndef UDP_DEBUG
-#define UDP_DEBUG                       DBG_OFF
-#endif
-
-#ifndef TCPIP_DEBUG
-#define TCPIP_DEBUG                     DBG_OFF
-#endif
-
-#ifndef PPP_DEBUG 
-#define PPP_DEBUG                       DBG_OFF
-#endif
-
-#ifndef SLIP_DEBUG 
-#define SLIP_DEBUG                      DBG_OFF
-#endif
-
-#ifndef DHCP_DEBUG 
-#define DHCP_DEBUG                      DBG_OFF
-#endif
-
-
-#ifndef DBG_MIN_LEVEL
-#define DBG_MIN_LEVEL                   DBG_LEVEL_OFF
-#endif
-
-#endif /* __LWIP_OPT_H__ */
-
-
-
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+#ifndef __LWIP_OPT_H__\r
+#define __LWIP_OPT_H__\r
+\r
+/* Include user defined options first */\r
+#include "lwipopts.h"\r
+#include "lwip/debug.h"\r
+\r
+/* Define default values for unconfigured parameters. */\r
+\r
+/* Platform specific locking */\r
+\r
+/*\r
+ * enable SYS_LIGHTWEIGHT_PROT in lwipopts.h if you want inter-task protection\r
+ * for certain critical regions during buffer allocation, deallocation and memory\r
+ * allocation and deallocation.\r
+ */\r
+#ifndef SYS_LIGHTWEIGHT_PROT\r
+#define SYS_LIGHTWEIGHT_PROT            0\r
+#endif\r
+\r
+#ifndef NO_SYS\r
+#define NO_SYS                          0\r
+#endif\r
+/* ---------- Memory options ---------- */\r
+/* MEM_ALIGNMENT: should be set to the alignment of the CPU for which\r
+   lwIP is compiled. 4 byte alignment -> define MEM_ALIGNMENT to 4, 2\r
+   byte alignment -> define MEM_ALIGNMENT to 2. */\r
+\r
+#ifndef MEM_ALIGNMENT\r
+#define MEM_ALIGNMENT                   1\r
+#endif\r
+\r
+/* MEM_SIZE: the size of the heap memory. If the application will send\r
+a lot of data that needs to be copied, this should be set high. */\r
+#ifndef MEM_SIZE\r
+#define MEM_SIZE                        1600\r
+#endif\r
+\r
+#ifndef MEMP_SANITY_CHECK\r
+#define MEMP_SANITY_CHECK              0\r
+#endif\r
+\r
+/* MEMP_NUM_PBUF: the number of memp struct pbufs. If the application\r
+   sends a lot of data out of ROM (or other static memory), this\r
+   should be set high. */\r
+#ifndef MEMP_NUM_PBUF\r
+#define MEMP_NUM_PBUF                   16\r
+#endif\r
+\r
+/* Number of raw connection PCBs */\r
+#ifndef MEMP_NUM_RAW_PCB\r
+#define MEMP_NUM_RAW_PCB                4\r
+#endif\r
+\r
+/* MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One\r
+   per active UDP "connection". */\r
+#ifndef MEMP_NUM_UDP_PCB\r
+#define MEMP_NUM_UDP_PCB                4\r
+#endif\r
+/* MEMP_NUM_TCP_PCB: the number of simulatenously active TCP\r
+   connections. */\r
+#ifndef MEMP_NUM_TCP_PCB\r
+#define MEMP_NUM_TCP_PCB                5\r
+#endif\r
+/* MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP\r
+   connections. */\r
+#ifndef MEMP_NUM_TCP_PCB_LISTEN\r
+#define MEMP_NUM_TCP_PCB_LISTEN         8\r
+#endif\r
+/* MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP\r
+   segments. */\r
+#ifndef MEMP_NUM_TCP_SEG\r
+#define MEMP_NUM_TCP_SEG                16\r
+#endif\r
+/* MEMP_NUM_SYS_TIMEOUT: the number of simulateously active\r
+   timeouts. */\r
+#ifndef MEMP_NUM_SYS_TIMEOUT\r
+#define MEMP_NUM_SYS_TIMEOUT            3\r
+#endif\r
+\r
+/* The following four are used only with the sequential API and can be\r
+   set to 0 if the application only will use the raw API. */\r
+/* MEMP_NUM_NETBUF: the number of struct netbufs. */\r
+#ifndef MEMP_NUM_NETBUF\r
+#define MEMP_NUM_NETBUF                 2\r
+#endif\r
+/* MEMP_NUM_NETCONN: the number of struct netconns. */\r
+#ifndef MEMP_NUM_NETCONN\r
+#define MEMP_NUM_NETCONN                4\r
+#endif\r
+/* MEMP_NUM_APIMSG: the number of struct api_msg, used for\r
+   communication between the TCP/IP stack and the sequential\r
+   programs. */\r
+#ifndef MEMP_NUM_API_MSG\r
+#define MEMP_NUM_API_MSG                8\r
+#endif\r
+/* MEMP_NUM_TCPIPMSG: the number of struct tcpip_msg, which is used\r
+   for sequential API communication and incoming packets. Used in\r
+   src/api/tcpip.c. */\r
+#ifndef MEMP_NUM_TCPIP_MSG\r
+#define MEMP_NUM_TCPIP_MSG              8\r
+#endif\r
+\r
+/* ---------- Pbuf options ---------- */\r
+/* PBUF_POOL_SIZE: the number of buffers in the pbuf pool. */\r
+\r
+#ifndef PBUF_POOL_SIZE\r
+#define PBUF_POOL_SIZE                  16\r
+#endif\r
+\r
+/* PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. */\r
+\r
+#ifndef PBUF_POOL_BUFSIZE\r
+#define PBUF_POOL_BUFSIZE               128\r
+#endif\r
+\r
+/* PBUF_LINK_HLEN: the number of bytes that should be allocated for a\r
+   link level header. Defaults to 14 for Ethernet. */\r
+\r
+#ifndef PBUF_LINK_HLEN\r
+#define PBUF_LINK_HLEN                  14\r
+#endif\r
+\r
+\r
+\r
+/* ---------- ARP options ---------- */\r
+\r
+/** Number of active hardware address, IP address pairs cached */\r
+#ifndef ARP_TABLE_SIZE\r
+#define ARP_TABLE_SIZE                  10\r
+#endif\r
+\r
+/**\r
+ * If enabled, outgoing packets are queued during hardware address\r
+ * resolution.\r
+ *\r
+ * This feature has not stabilized yet. Single-packet queueing is\r
+ * believed to be stable, multi-packet queueing is believed to\r
+ * clash with the TCP segment queueing.\r
+ * \r
+ * As multi-packet-queueing is currently disabled, enabling this\r
+ * _should_ work, but we need your testing feedback on lwip-users.\r
+ *\r
+ */\r
+#ifndef ARP_QUEUEING\r
+#define ARP_QUEUEING                    1\r
+#endif\r
+\r
+/* This option is deprecated */\r
+#ifdef ETHARP_QUEUE_FIRST\r
+#error ETHARP_QUEUE_FIRST option is deprecated. Remove it from your lwipopts.h.\r
+#endif\r
+\r
+/* This option is removed to comply with the ARP standard */\r
+#ifdef ETHARP_ALWAYS_INSERT\r
+#error ETHARP_ALWAYS_INSERT option is deprecated. Remove it from your lwipopts.h.\r
+#endif\r
+\r
+/* ---------- IP options ---------- */\r
+/* Define IP_FORWARD to 1 if you wish to have the ability to forward\r
+   IP packets across network interfaces. If you are going to run lwIP\r
+   on a device with only one network interface, define this to 0. */\r
+#ifndef IP_FORWARD\r
+#define IP_FORWARD                      0\r
+#endif\r
+\r
+/* If defined to 1, IP options are allowed (but not parsed). If\r
+   defined to 0, all packets with IP options are dropped. */\r
+#ifndef IP_OPTIONS\r
+#define IP_OPTIONS                      1\r
+#endif\r
+\r
+/** IP reassembly and segmentation. Even if they both deal with IP\r
+ *  fragments, note that these are orthogonal, one dealing with incoming\r
+ *  packets, the other with outgoing packets\r
+ */\r
+\r
+/** Reassemble incoming fragmented IP packets */\r
+#ifndef IP_REASSEMBLY\r
+#define IP_REASSEMBLY                   1\r
+#endif\r
+\r
+/** Fragment outgoing IP packets if their size exceeds MTU */\r
+#ifndef IP_FRAG\r
+#define IP_FRAG                         1\r
+#endif\r
+\r
+/* ---------- ICMP options ---------- */\r
+\r
+#ifndef ICMP_TTL\r
+#define ICMP_TTL                        255\r
+#endif\r
+\r
+/* ---------- RAW options ---------- */\r
+\r
+#ifndef LWIP_RAW\r
+#define LWIP_RAW                        1\r
+#endif\r
+\r
+#ifndef RAW_TTL\r
+#define RAW_TTL                        255\r
+#endif\r
+\r
+/* ---------- DHCP options ---------- */\r
+\r
+#ifndef LWIP_DHCP\r
+#define LWIP_DHCP                       0\r
+#endif\r
+\r
+/* 1 if you want to do an ARP check on the offered address\r
+   (recommended). */\r
+#ifndef DHCP_DOES_ARP_CHECK\r
+#define DHCP_DOES_ARP_CHECK             1\r
+#endif\r
+\r
+/* ---------- UDP options ---------- */\r
+#ifndef LWIP_UDP\r
+#define LWIP_UDP                        1\r
+#endif\r
+\r
+#ifndef UDP_TTL\r
+#define UDP_TTL                         255\r
+#endif\r
+\r
+/* ---------- TCP options ---------- */\r
+#ifndef LWIP_TCP\r
+#define LWIP_TCP                        1\r
+#endif\r
+\r
+#ifndef TCP_TTL\r
+#define TCP_TTL                         255\r
+#endif\r
+\r
+#ifndef TCP_WND\r
+#define TCP_WND                         2048\r
+#endif \r
+\r
+#ifndef TCP_MAXRTX\r
+#define TCP_MAXRTX                      12\r
+#endif\r
+\r
+#ifndef TCP_SYNMAXRTX\r
+#define TCP_SYNMAXRTX                   6\r
+#endif\r
+\r
+\r
+/* Controls if TCP should queue segments that arrive out of\r
+   order. Define to 0 if your device is low on memory. */\r
+#ifndef TCP_QUEUE_OOSEQ\r
+#define TCP_QUEUE_OOSEQ                 1\r
+#endif\r
+\r
+/* TCP Maximum segment size. */\r
+#ifndef TCP_MSS\r
+#define TCP_MSS                         128 /* A *very* conservative default. */\r
+#endif\r
+\r
+/* TCP sender buffer space (bytes). */\r
+#ifndef TCP_SND_BUF\r
+#define TCP_SND_BUF                     256\r
+#endif\r
+\r
+/* TCP sender buffer space (pbufs). This must be at least = 2 *\r
+   TCP_SND_BUF/TCP_MSS for things to work. */\r
+#ifndef TCP_SND_QUEUELEN\r
+#define TCP_SND_QUEUELEN                4 * TCP_SND_BUF/TCP_MSS\r
+#endif\r
+\r
+\r
+/* Maximum number of retransmissions of data segments. */\r
+\r
+/* Maximum number of retransmissions of SYN segments. */\r
+\r
+/* TCP writable space (bytes). This must be less than or equal\r
+   to TCP_SND_BUF. It is the amount of space which must be\r
+   available in the tcp snd_buf for select to return writable */\r
+#ifndef TCP_SNDLOWAT\r
+#define TCP_SNDLOWAT                    TCP_SND_BUF/2\r
+#endif\r
+\r
+/* Support loop interface (127.0.0.1) */\r
+#ifndef LWIP_HAVE_LOOPIF\r
+#define LWIP_HAVE_LOOPIF               1\r
+#endif\r
+\r
+#ifndef LWIP_EVENT_API\r
+#define LWIP_EVENT_API                  0\r
+#define LWIP_CALLBACK_API               1\r
+#else \r
+#define LWIP_EVENT_API                  1\r
+#define LWIP_CALLBACK_API               0\r
+#endif \r
+\r
+#ifndef LWIP_COMPAT_SOCKETS\r
+#define LWIP_COMPAT_SOCKETS             1\r
+#endif\r
+\r
+\r
+#ifndef TCPIP_THREAD_PRIO\r
+#define TCPIP_THREAD_PRIO               1\r
+#endif\r
+\r
+#ifndef SLIPIF_THREAD_PRIO\r
+#define SLIPIF_THREAD_PRIO              1\r
+#endif\r
+\r
+#ifndef PPP_THREAD_PRIO\r
+#define PPP_THREAD_PRIO                 1\r
+#endif\r
+\r
+#ifndef DEFAULT_THREAD_PRIO\r
+#define DEFAULT_THREAD_PRIO             1\r
+#endif\r
+\r
+\r
+/* ---------- Socket Options ---------- */\r
+/* Enable SO_REUSEADDR and SO_REUSEPORT options */ \r
+#ifndef SO_REUSE\r
+# define SO_REUSE 0\r
+#endif                                                                        \r
+\r
+\r
+/* ---------- Statistics options ---------- */\r
+#ifndef LWIP_STATS\r
+#define LWIP_STATS                      1\r
+#endif\r
+\r
+#if LWIP_STATS\r
+\r
+#ifndef LWIP_STATS_DISPLAY\r
+#define LWIP_STATS_DISPLAY 0\r
+#endif\r
+\r
+#ifndef LINK_STATS\r
+#define LINK_STATS     1\r
+#endif\r
+\r
+#ifndef IP_STATS\r
+#define IP_STATS       1\r
+#endif\r
+\r
+#ifndef IPFRAG_STATS\r
+#define IPFRAG_STATS   1\r
+#endif\r
+\r
+#ifndef ICMP_STATS\r
+#define ICMP_STATS     1\r
+#endif\r
+\r
+#ifndef UDP_STATS\r
+#define UDP_STATS      1\r
+#endif\r
+\r
+#ifndef TCP_STATS\r
+#define TCP_STATS      1\r
+#endif\r
+\r
+#ifndef MEM_STATS\r
+#define MEM_STATS      1\r
+#endif\r
+\r
+#ifndef MEMP_STATS\r
+#define MEMP_STATS     1\r
+#endif\r
+\r
+#ifndef PBUF_STATS\r
+#define PBUF_STATS     1\r
+#endif\r
+\r
+#ifndef SYS_STATS\r
+#define SYS_STATS      1\r
+#endif\r
+\r
+#ifndef RAW_STATS\r
+#define RAW_STATS      0\r
+#endif\r
+\r
+#else\r
+\r
+#define LINK_STATS     0\r
+#define IP_STATS       0\r
+#define IPFRAG_STATS   0\r
+#define ICMP_STATS     0\r
+#define UDP_STATS      0\r
+#define TCP_STATS      0\r
+#define MEM_STATS      0\r
+#define MEMP_STATS     0\r
+#define PBUF_STATS     0\r
+#define SYS_STATS      0\r
+#define RAW_STATS      0\r
+#define LWIP_STATS_DISPLAY     0\r
+\r
+#endif /* LWIP_STATS */\r
+\r
+/* ---------- PPP options ---------- */\r
+\r
+#ifndef PPP_SUPPORT\r
+#define PPP_SUPPORT                     0      /* Set for PPP */\r
+#endif\r
+\r
+#if PPP_SUPPORT \r
+\r
+#define NUM_PPP                         1      /* Max PPP sessions. */\r
+\r
+\r
+\r
+#ifndef PAP_SUPPORT\r
+#define PAP_SUPPORT                     0      /* Set for PAP. */\r
+#endif\r
+\r
+#ifndef CHAP_SUPPORT\r
+#define CHAP_SUPPORT                    0      /* Set for CHAP. */\r
+#endif\r
+\r
+#define MSCHAP_SUPPORT                  0      /* Set for MSCHAP (NOT FUNCTIONAL!) */\r
+#define CBCP_SUPPORT                    0      /* Set for CBCP (NOT FUNCTIONAL!) */\r
+#define CCP_SUPPORT                     0      /* Set for CCP (NOT FUNCTIONAL!) */\r
+\r
+#ifndef VJ_SUPPORT\r
+#define VJ_SUPPORT                      0      /* Set for VJ header compression. */\r
+#endif\r
+\r
+#ifndef MD5_SUPPORT\r
+#define MD5_SUPPORT                     0      /* Set for MD5 (see also CHAP) */\r
+#endif\r
+\r
+\r
+/*\r
+ * Timeouts.\r
+ */\r
+#define FSM_DEFTIMEOUT                  6       /* Timeout time in seconds */\r
+#define FSM_DEFMAXTERMREQS              2       /* Maximum Terminate-Request transmissions */\r
+#define FSM_DEFMAXCONFREQS              10      /* Maximum Configure-Request transmissions */\r
+#define FSM_DEFMAXNAKLOOPS              5       /* Maximum number of nak loops */\r
+\r
+#define UPAP_DEFTIMEOUT                 6       /* Timeout (seconds) for retransmitting req */\r
+#define UPAP_DEFREQTIME                 30      /* Time to wait for auth-req from peer */\r
+\r
+#define CHAP_DEFTIMEOUT                 6       /* Timeout time in seconds */\r
+#define CHAP_DEFTRANSMITS               10      /* max # times to send challenge */\r
+\r
+\r
+/* Interval in seconds between keepalive echo requests, 0 to disable. */\r
+#if 1\r
+#define LCP_ECHOINTERVAL                0\r
+#else\r
+#define LCP_ECHOINTERVAL                10\r
+#endif\r
+\r
+/* Number of unanswered echo requests before failure. */\r
+#define LCP_MAXECHOFAILS                3\r
+\r
+/* Max Xmit idle time (in jiffies) before resend flag char. */\r
+#define PPP_MAXIDLEFLAG                 100\r
+\r
+/*\r
+ * Packet sizes\r
+ *\r
+ * Note - lcp shouldn't be allowed to negotiate stuff outside these\r
+ *    limits.  See lcp.h in the pppd directory.\r
+ * (XXX - these constants should simply be shared by lcp.c instead\r
+ *    of living in lcp.h)\r
+ */\r
+#define PPP_MTU                         1500     /* Default MTU (size of Info field) */\r
+#if 0\r
+#define PPP_MAXMTU  65535 - (PPP_HDRLEN + PPP_FCSLEN)\r
+#else\r
+#define PPP_MAXMTU                      1500 /* Largest MTU we allow */\r
+#endif\r
+#define PPP_MINMTU                      64\r
+#define PPP_MRU                         1500     /* default MRU = max length of info field */\r
+#define PPP_MAXMRU                      1500     /* Largest MRU we allow */\r
+#define PPP_DEFMRU                      296             /* Try for this */\r
+#define PPP_MINMRU                      128             /* No MRUs below this */\r
+\r
+\r
+#define MAXNAMELEN                      256     /* max length of hostname or name for auth */\r
+#define MAXSECRETLEN                    256     /* max length of password or secret */\r
+\r
+#endif /* PPP_SUPPORT */\r
+\r
+/* checksum options - set to zero for hardware checksum support */\r
+\r
+#ifndef CHECKSUM_GEN_IP\r
+#define CHECKSUM_GEN_IP                 1\r
+#endif\r
\r
+#ifndef CHECKSUM_GEN_UDP\r
+#define CHECKSUM_GEN_UDP                1\r
+#endif\r
\r
+#ifndef CHECKSUM_GEN_TCP\r
+#define CHECKSUM_GEN_TCP                1\r
+#endif\r
\r
+#ifndef CHECKSUM_CHECK_IP\r
+#define CHECKSUM_CHECK_IP               1\r
+#endif\r
\r
+#ifndef CHECKSUM_CHECK_UDP\r
+#define CHECKSUM_CHECK_UDP              1\r
+#endif\r
+\r
+#ifndef CHECKSUM_CHECK_TCP\r
+#define CHECKSUM_CHECK_TCP              1\r
+#endif\r
+\r
+/* Debugging options all default to off */\r
+\r
+#ifndef DBG_TYPES_ON\r
+#define DBG_TYPES_ON                    0\r
+#endif\r
+\r
+#ifndef ETHARP_DEBUG\r
+#define ETHARP_DEBUG                    DBG_OFF\r
+#endif\r
+\r
+#ifndef NETIF_DEBUG\r
+#define NETIF_DEBUG                     DBG_OFF\r
+#endif\r
+\r
+#ifndef PBUF_DEBUG\r
+#define PBUF_DEBUG                      DBG_OFF\r
+#endif\r
+\r
+#ifndef API_LIB_DEBUG\r
+#define API_LIB_DEBUG                   DBG_OFF\r
+#endif\r
+\r
+#ifndef API_MSG_DEBUG\r
+#define API_MSG_DEBUG                   DBG_OFF\r
+#endif\r
+\r
+#ifndef SOCKETS_DEBUG\r
+#define SOCKETS_DEBUG                   DBG_OFF\r
+#endif\r
+\r
+#ifndef ICMP_DEBUG\r
+#define ICMP_DEBUG                      DBG_OFF\r
+#endif\r
+\r
+#ifndef INET_DEBUG\r
+#define INET_DEBUG                      DBG_OFF\r
+#endif\r
+\r
+#ifndef IP_DEBUG\r
+#define IP_DEBUG                        DBG_OFF\r
+#endif\r
+\r
+#ifndef IP_REASS_DEBUG\r
+#define IP_REASS_DEBUG                  DBG_OFF\r
+#endif\r
+\r
+#ifndef RAW_DEBUG\r
+#define RAW_DEBUG                       DBG_OFF\r
+#endif\r
+\r
+#ifndef MEM_DEBUG\r
+#define MEM_DEBUG                       DBG_OFF\r
+#endif\r
+\r
+#ifndef MEMP_DEBUG\r
+#define MEMP_DEBUG                      DBG_OFF\r
+#endif\r
+\r
+#ifndef SYS_DEBUG\r
+#define SYS_DEBUG                       DBG_OFF\r
+#endif\r
+\r
+#ifndef TCP_DEBUG\r
+#define TCP_DEBUG                       DBG_OFF\r
+#endif\r
+\r
+#ifndef TCP_INPUT_DEBUG\r
+#define TCP_INPUT_DEBUG                 DBG_OFF\r
+#endif\r
+\r
+#ifndef TCP_FR_DEBUG\r
+#define TCP_FR_DEBUG                    DBG_OFF\r
+#endif\r
+\r
+#ifndef TCP_RTO_DEBUG\r
+#define TCP_RTO_DEBUG                   DBG_OFF\r
+#endif\r
+\r
+#ifndef TCP_REXMIT_DEBUG\r
+#define TCP_REXMIT_DEBUG                DBG_OFF\r
+#endif\r
+\r
+#ifndef TCP_CWND_DEBUG\r
+#define TCP_CWND_DEBUG                  DBG_OFF\r
+#endif\r
+\r
+#ifndef TCP_WND_DEBUG\r
+#define TCP_WND_DEBUG                   DBG_OFF\r
+#endif\r
+\r
+#ifndef TCP_OUTPUT_DEBUG\r
+#define TCP_OUTPUT_DEBUG                DBG_OFF\r
+#endif\r
+\r
+#ifndef TCP_RST_DEBUG\r
+#define TCP_RST_DEBUG                   DBG_OFF\r
+#endif\r
+\r
+#ifndef TCP_QLEN_DEBUG\r
+#define TCP_QLEN_DEBUG                  DBG_OFF\r
+#endif\r
+\r
+#ifndef UDP_DEBUG\r
+#define UDP_DEBUG                       DBG_OFF\r
+#endif\r
+\r
+#ifndef TCPIP_DEBUG\r
+#define TCPIP_DEBUG                     DBG_OFF\r
+#endif\r
+\r
+#ifndef PPP_DEBUG \r
+#define PPP_DEBUG                       DBG_OFF\r
+#endif\r
+\r
+#ifndef SLIP_DEBUG \r
+#define SLIP_DEBUG                      DBG_OFF\r
+#endif\r
+\r
+#ifndef DHCP_DEBUG \r
+#define DHCP_DEBUG                      DBG_OFF\r
+#endif\r
+\r
+\r
+#ifndef DBG_MIN_LEVEL\r
+#define DBG_MIN_LEVEL                   DBG_LEVEL_OFF\r
+#endif\r
+\r
+#endif /* __LWIP_OPT_H__ */\r
+\r
+\r
+\r
index 546aa30357cefb90564f38c547081c6402f4ff81..0b187e1215f66f63b766c10407363b6ff7a16ea7 100644 (file)
-/*
- * 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 <adam@sics.se>
- *
- */
-
-#ifndef __LWIP_PBUF_H__
-#define __LWIP_PBUF_H__
-
-#include "arch/cc.h"
-
-
-#define PBUF_TRANSPORT_HLEN 20
-#define PBUF_IP_HLEN        20
-
-typedef enum {
-  PBUF_TRANSPORT,
-  PBUF_IP,
-  PBUF_LINK,
-  PBUF_RAW
-} pbuf_layer;
-
-typedef enum {
-  PBUF_RAM,
-  PBUF_ROM,
-  PBUF_REF,
-  PBUF_POOL
-} pbuf_flag;
-
-/* Definitions for the pbuf flag field. These are NOT the flags that
- * are passed to pbuf_alloc(). */
-#define PBUF_FLAG_RAM   0x00U    /* Flags that pbuf data is stored in RAM */
-#define PBUF_FLAG_ROM   0x01U    /* Flags that pbuf data is stored in ROM */
-#define PBUF_FLAG_POOL  0x02U    /* Flags that the pbuf comes from the pbuf pool */
-#define PBUF_FLAG_REF   0x04U    /* Flags thet the pbuf payload refers to RAM */
-
-/** indicates this packet was broadcast on the link */
-#define PBUF_FLAG_LINK_BROADCAST 0x80U
-
-struct pbuf {
-  /** next pbuf in singly linked pbuf chain */
-  struct pbuf *next;
-
-  /** pointer to the actual data in the buffer */
-  void *payload;
-  
-  /**
-   * total length of this buffer and all next buffers in chain
-   * belonging to the same packet.
-   *
-   * For non-queue packet chains this is the invariant:
-   * p->tot_len == p->len + (p->next? p->next->tot_len: 0)
-   */
-  u16_t tot_len;
-  
-  /** length of this buffer */
-  u16_t len;  
-
-  /** flags telling the type of pbuf, see PBUF_FLAG_ */
-  u16_t flags;
-  
-  /**
-   * the reference count always equals the number of pointers
-   * that refer to this pbuf. This can be pointers from an application,
-   * the stack itself, or pbuf->next pointers from a chain.
-   */
-  u16_t ref;
-  
-};
-
-void pbuf_init(void);
-
-struct pbuf *pbuf_alloc(pbuf_layer l, u16_t size, pbuf_flag flag);
-void pbuf_realloc(struct pbuf *p, u16_t size); 
-u8_t pbuf_header(struct pbuf *p, s16_t header_size);
-void pbuf_ref(struct pbuf *p);
-void pbuf_ref_chain(struct pbuf *p);
-u8_t pbuf_free(struct pbuf *p);
-u8_t pbuf_clen(struct pbuf *p);  
-void pbuf_cat(struct pbuf *h, struct pbuf *t);
-void pbuf_chain(struct pbuf *h, struct pbuf *t);
-struct pbuf *pbuf_take(struct pbuf *f);
-struct pbuf *pbuf_dechain(struct pbuf *p);
-void pbuf_queue(struct pbuf *p, struct pbuf *n);
-struct pbuf * pbuf_dequeue(struct pbuf *p);
-
-#endif /* __LWIP_PBUF_H__ */
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+\r
+#ifndef __LWIP_PBUF_H__\r
+#define __LWIP_PBUF_H__\r
+\r
+#include "arch/cc.h"\r
+\r
+\r
+#define PBUF_TRANSPORT_HLEN 20\r
+#define PBUF_IP_HLEN        20\r
+\r
+typedef enum {\r
+  PBUF_TRANSPORT,\r
+  PBUF_IP,\r
+  PBUF_LINK,\r
+  PBUF_RAW\r
+} pbuf_layer;\r
+\r
+typedef enum {\r
+  PBUF_RAM,\r
+  PBUF_ROM,\r
+  PBUF_REF,\r
+  PBUF_POOL\r
+} pbuf_flag;\r
+\r
+/* Definitions for the pbuf flag field. These are NOT the flags that\r
+ * are passed to pbuf_alloc(). */\r
+#define PBUF_FLAG_RAM   0x00U    /* Flags that pbuf data is stored in RAM */\r
+#define PBUF_FLAG_ROM   0x01U    /* Flags that pbuf data is stored in ROM */\r
+#define PBUF_FLAG_POOL  0x02U    /* Flags that the pbuf comes from the pbuf pool */\r
+#define PBUF_FLAG_REF   0x04U    /* Flags thet the pbuf payload refers to RAM */\r
+\r
+/** indicates this packet was broadcast on the link */\r
+#define PBUF_FLAG_LINK_BROADCAST 0x80U\r
+\r
+struct pbuf {\r
+  /** next pbuf in singly linked pbuf chain */\r
+  struct pbuf *next;\r
+\r
+  /** pointer to the actual data in the buffer */\r
+  void *payload;\r
+  \r
+  /**\r
+   * total length of this buffer and all next buffers in chain\r
+   * belonging to the same packet.\r
+   *\r
+   * For non-queue packet chains this is the invariant:\r
+   * p->tot_len == p->len + (p->next? p->next->tot_len: 0)\r
+   */\r
+  u16_t tot_len;\r
+  \r
+  /** length of this buffer */\r
+  u16_t len;  \r
+\r
+  /** flags telling the type of pbuf, see PBUF_FLAG_ */\r
+  u16_t flags;\r
+  \r
+  /**\r
+   * the reference count always equals the number of pointers\r
+   * that refer to this pbuf. This can be pointers from an application,\r
+   * the stack itself, or pbuf->next pointers from a chain.\r
+   */\r
+  u16_t ref;\r
+  \r
+};\r
+\r
+void pbuf_init(void);\r
+\r
+struct pbuf *pbuf_alloc(pbuf_layer l, u16_t size, pbuf_flag flag);\r
+void pbuf_realloc(struct pbuf *p, u16_t size); \r
+u8_t pbuf_header(struct pbuf *p, s16_t header_size);\r
+void pbuf_ref(struct pbuf *p);\r
+void pbuf_ref_chain(struct pbuf *p);\r
+u8_t pbuf_free(struct pbuf *p);\r
+u8_t pbuf_clen(struct pbuf *p);  \r
+void pbuf_cat(struct pbuf *h, struct pbuf *t);\r
+void pbuf_chain(struct pbuf *h, struct pbuf *t);\r
+struct pbuf *pbuf_take(struct pbuf *f);\r
+struct pbuf *pbuf_dechain(struct pbuf *p);\r
+void pbuf_queue(struct pbuf *p, struct pbuf *n);\r
+struct pbuf * pbuf_dequeue(struct pbuf *p);\r
+\r
+#endif /* __LWIP_PBUF_H__ */\r
index 6f7a98717f0523ae957a73c8b118e259a974d893..83b32da9d67272cd85fa483d4249e7e1d8556a05 100644 (file)
@@ -1,74 +1,74 @@
-/*
- * 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 <adam@sics.se>
- *
- */
-#ifndef __LWIP_RAW_H__
-#define __LWIP_RAW_H__
-
-#include "lwip/arch.h"
-
-#include "lwip/pbuf.h"
-#include "lwip/inet.h"
-#include "lwip/ip.h"
-
-struct raw_pcb {
-/* Common members of all PCB types */
-  IP_PCB;
-
-  struct raw_pcb *next;
-
-  u16_t protocol;
-
-  u8_t (* recv)(void *arg, struct raw_pcb *pcb, struct pbuf *p,
-    struct ip_addr *addr);
-  void *recv_arg;
-};
-
-/* The following functions is the application layer interface to the
-   RAW code. */
-struct raw_pcb * raw_new        (u16_t proto);
-void             raw_remove     (struct raw_pcb *pcb);
-err_t            raw_bind       (struct raw_pcb *pcb, struct ip_addr *ipaddr);
-err_t            raw_connect    (struct raw_pcb *pcb, struct ip_addr *ipaddr);
-
-void             raw_recv       (struct raw_pcb *pcb,
-                                 u8_t (* recv)(void *arg, struct raw_pcb *pcb,
-                                              struct pbuf *p,
-                                              struct ip_addr *addr),
-                                 void *recv_arg);
-err_t            raw_sendto    (struct raw_pcb *pcb, struct pbuf *p, struct ip_addr *ipaddr);
-err_t            raw_send       (struct raw_pcb *pcb, struct pbuf *p);
-
-/* The following functions are the lower layer interface to RAW. */
-u8_t              raw_input      (struct pbuf *p, struct netif *inp);
-void             raw_init       (void);
-
-
-#endif /* __LWIP_RAW_H__ */
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without modification,\r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED\r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT\r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY\r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ *\r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+#ifndef __LWIP_RAW_H__\r
+#define __LWIP_RAW_H__\r
+\r
+#include "lwip/arch.h"\r
+\r
+#include "lwip/pbuf.h"\r
+#include "lwip/inet.h"\r
+#include "lwip/ip.h"\r
+\r
+struct raw_pcb {\r
+/* Common members of all PCB types */\r
+  IP_PCB;\r
+\r
+  struct raw_pcb *next;\r
+\r
+  u16_t protocol;\r
+\r
+  u8_t (* recv)(void *arg, struct raw_pcb *pcb, struct pbuf *p,\r
+    struct ip_addr *addr);\r
+  void *recv_arg;\r
+};\r
+\r
+/* The following functions is the application layer interface to the\r
+   RAW code. */\r
+struct raw_pcb * raw_new        (u16_t proto);\r
+void             raw_remove     (struct raw_pcb *pcb);\r
+err_t            raw_bind       (struct raw_pcb *pcb, struct ip_addr *ipaddr);\r
+err_t            raw_connect    (struct raw_pcb *pcb, struct ip_addr *ipaddr);\r
+\r
+void             raw_recv       (struct raw_pcb *pcb,\r
+                                 u8_t (* recv)(void *arg, struct raw_pcb *pcb,\r
+                                              struct pbuf *p,\r
+                                              struct ip_addr *addr),\r
+                                 void *recv_arg);\r
+err_t            raw_sendto    (struct raw_pcb *pcb, struct pbuf *p, struct ip_addr *ipaddr);\r
+err_t            raw_send       (struct raw_pcb *pcb, struct pbuf *p);\r
+\r
+/* The following functions are the lower layer interface to RAW. */\r
+u8_t              raw_input      (struct pbuf *p, struct netif *inp);\r
+void             raw_init       (void);\r
+\r
+\r
+#endif /* __LWIP_RAW_H__ */\r
index 8a37aa35ab3eff4bc4f3d73e29d0c47c0f27dedf..5fc28a4d6d618748a4916c6228773bba642bc212 100644 (file)
@@ -1,63 +1,63 @@
-/*
- * 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.
- */
-
-/*
- * This is the interface to the platform specific serial IO module
- * It needs to be implemented by those platforms which need SLIP or PPP
- */
-
-#include "arch/cc.h"
-
-#ifndef __sio_fd_t_defined
-typedef void * sio_fd_t;
-#endif
-
-#ifndef sio_open
-sio_fd_t sio_open(u8_t);
-#endif
-
-#ifndef sio_send
-void sio_send(u8_t, sio_fd_t);
-#endif
-
-#ifndef sio_recv
-u8_t sio_recv(sio_fd_t);
-#endif
-
-#ifndef sio_read
-u32_t sio_read(sio_fd_t, u8_t *, u32_t);
-#endif
-
-#ifndef sio_write
-u32_t sio_write(sio_fd_t, u8_t *, u32_t);
-#endif
-
-#ifndef sio_read_abort
-void sio_read_abort(sio_fd_t);
-#endif
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ */\r
+\r
+/*\r
+ * This is the interface to the platform specific serial IO module\r
+ * It needs to be implemented by those platforms which need SLIP or PPP\r
+ */\r
+\r
+#include "arch/cc.h"\r
+\r
+#ifndef __sio_fd_t_defined\r
+typedef void * sio_fd_t;\r
+#endif\r
+\r
+#ifndef sio_open\r
+sio_fd_t sio_open(u8_t);\r
+#endif\r
+\r
+#ifndef sio_send\r
+void sio_send(u8_t, sio_fd_t);\r
+#endif\r
+\r
+#ifndef sio_recv\r
+u8_t sio_recv(sio_fd_t);\r
+#endif\r
+\r
+#ifndef sio_read\r
+u32_t sio_read(sio_fd_t, u8_t *, u32_t);\r
+#endif\r
+\r
+#ifndef sio_write\r
+u32_t sio_write(sio_fd_t, u8_t *, u32_t);\r
+#endif\r
+\r
+#ifndef sio_read_abort\r
+void sio_read_abort(sio_fd_t);\r
+#endif\r
index 7d160aaa440369f9889145e0bb18e5f6c40634dc..4e806914b4030d7b60b9a1709600fe924d07ea82 100644 (file)
-/*
- * Copyright (c) 2001, 2002 Leon Woestenberg <leon.woestenberg@axon.tv>
- * Copyright (c) 2001, 2002 Axon Digital Design B.V., The Netherlands.
- * 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: Leon Woestenberg <leon.woestenberg@axon.tv>
- *
- */
-#ifndef __LWIP_SNMP_H__
-#define __LWIP_SNMP_H__
-
-#include "lwip/opt.h"
-
-/* SNMP support available? */
-#if defined(LWIP_SNMP) && (LWIP_SNMP > 0)
-
-/* network interface */
-void snmp_add_ifinoctets(unsigned long value); 
-void snmp_inc_ifinucastpkts(void);
-void snmp_inc_ifinnucastpkts(void);
-void snmp_inc_ifindiscards(void);
-void snmp_add_ifoutoctets(unsigned long value);
-void snmp_inc_ifoutucastpkts(void);
-void snmp_inc_ifoutnucastpkts(void);
-void snmp_inc_ifoutdiscards(void);
-
-/* IP */
-void snmp_inc_ipinreceives(void);
-void snmp_inc_ipindelivers(void);
-void snmp_inc_ipindiscards(void);
-void snmp_inc_ipoutdiscards(void);
-void snmp_inc_ipoutrequests(void);
-void snmp_inc_ipunknownprotos(void);
-void snmp_inc_ipnoroutes(void);
-void snmp_inc_ipforwdatagrams(void);
-
-/* ICMP */
-void snmp_inc_icmpinmsgs(void);
-void snmp_inc_icmpinerrors(void);
-void snmp_inc_icmpindestunreachs(void);
-void snmp_inc_icmpintimeexcds(void);
-void snmp_inc_icmpinparmprobs(void);
-void snmp_inc_icmpinsrcquenchs(void);
-void snmp_inc_icmpinredirects(void);
-void snmp_inc_icmpinechos(void);
-void snmp_inc_icmpinechoreps(void);
-void snmp_inc_icmpintimestamps(void);
-void snmp_inc_icmpintimestampreps(void);
-void snmp_inc_icmpinaddrmasks(void);
-void snmp_inc_icmpinaddrmaskreps(void);
-void snmp_inc_icmpoutmsgs(void);
-void snmp_inc_icmpouterrors(void);
-void snmp_inc_icmpoutdestunreachs(void);
-void snmp_inc_icmpouttimeexcds(void);
-void snmp_inc_icmpoutparmprobs(void);
-void snmp_inc_icmpoutsrcquenchs(void);
-void snmp_inc_icmpoutredirects(void); 
-void snmp_inc_icmpoutechos(void);
-void snmp_inc_icmpoutechoreps(void);
-void snmp_inc_icmpouttimestamps(void);
-void snmp_inc_icmpouttimestampreps(void);
-void snmp_inc_icmpoutaddrmasks(void);
-void snmp_inc_icmpoutaddrmaskreps(void);
-
-/* TCP */
-void snmp_inc_tcpactiveopens(void);
-void snmp_inc_tcppassiveopens(void);
-void snmp_inc_tcpattemptfails(void);
-void snmp_inc_tcpestabresets(void);
-void snmp_inc_tcpcurrestab(void);
-void snmp_inc_tcpinsegs(void);
-void snmp_inc_tcpoutsegs(void);
-void snmp_inc_tcpretranssegs(void);
-void snmp_inc_tcpinerrs(void);
-void snmp_inc_tcpoutrsts(void);
-
-/* UDP */
-void snmp_inc_udpindatagrams(void);
-void snmp_inc_udpnoports(void);
-void snmp_inc_udpinerrors(void);
-void snmp_inc_udpoutdatagrams(void);
-
-/* LWIP_SNMP support not available */
-/* define everything to be empty */
-#else
-
-/* network interface */
-#define snmp_add_ifinoctets(value) 
-#define snmp_inc_ifinucastpkts()
-#define snmp_inc_ifinnucastpkts()
-#define snmp_inc_ifindiscards()
-#define snmp_add_ifoutoctets(value)
-#define snmp_inc_ifoutucastpkts()
-#define snmp_inc_ifoutnucastpkts()
-#define snmp_inc_ifoutdiscards()
-
-/* IP */
-#define snmp_inc_ipinreceives()
-#define snmp_inc_ipindelivers()
-#define snmp_inc_ipindiscards()
-#define snmp_inc_ipoutdiscards()
-#define snmp_inc_ipoutrequests()
-#define snmp_inc_ipunknownprotos()
-#define snmp_inc_ipnoroutes()
-#define snmp_inc_ipforwdatagrams()
-
-/* ICMP */
-#define snmp_inc_icmpinmsgs()
-#define snmp_inc_icmpinerrors() 
-#define snmp_inc_icmpindestunreachs() 
-#define snmp_inc_icmpintimeexcds()
-#define snmp_inc_icmpinparmprobs() 
-#define snmp_inc_icmpinsrcquenchs() 
-#define snmp_inc_icmpinredirects() 
-#define snmp_inc_icmpinechos() 
-#define snmp_inc_icmpinechoreps()
-#define snmp_inc_icmpintimestamps() 
-#define snmp_inc_icmpintimestampreps()
-#define snmp_inc_icmpinaddrmasks()
-#define snmp_inc_icmpinaddrmaskreps()
-#define snmp_inc_icmpoutmsgs()
-#define snmp_inc_icmpouterrors()
-#define snmp_inc_icmpoutdestunreachs() 
-#define snmp_inc_icmpouttimeexcds() 
-#define snmp_inc_icmpoutparmprobs()
-#define snmp_inc_icmpoutsrcquenchs()
-#define snmp_inc_icmpoutredirects() 
-#define snmp_inc_icmpoutechos() 
-#define snmp_inc_icmpoutechoreps()
-#define snmp_inc_icmpouttimestamps()
-#define snmp_inc_icmpouttimestampreps()
-#define snmp_inc_icmpoutaddrmasks()
-#define snmp_inc_icmpoutaddrmaskreps()
-/* TCP */
-#define snmp_inc_tcpactiveopens()
-#define snmp_inc_tcppassiveopens()
-#define snmp_inc_tcpattemptfails()
-#define snmp_inc_tcpestabresets()
-#define snmp_inc_tcpcurrestab()
-#define snmp_inc_tcpinsegs()
-#define snmp_inc_tcpoutsegs()
-#define snmp_inc_tcpretranssegs()
-#define snmp_inc_tcpinerrs()
-#define snmp_inc_tcpoutrsts()
-
-/* UDP */
-#define snmp_inc_udpindatagrams()
-#define snmp_inc_udpnoports()
-#define snmp_inc_udpinerrors()
-#define snmp_inc_udpoutdatagrams()
-
-#endif
-
-#endif /* __LWIP_SNMP_H__ */
+/*\r
+ * Copyright (c) 2001, 2002 Leon Woestenberg <leon.woestenberg@axon.tv>\r
+ * Copyright (c) 2001, 2002 Axon Digital Design B.V., The Netherlands.\r
+ * All rights reserved.\r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Leon Woestenberg <leon.woestenberg@axon.tv>\r
+ *\r
+ */\r
+#ifndef __LWIP_SNMP_H__\r
+#define __LWIP_SNMP_H__\r
+\r
+#include "lwip/opt.h"\r
+\r
+/* SNMP support available? */\r
+#if defined(LWIP_SNMP) && (LWIP_SNMP > 0)\r
+\r
+/* network interface */\r
+void snmp_add_ifinoctets(unsigned long value); \r
+void snmp_inc_ifinucastpkts(void);\r
+void snmp_inc_ifinnucastpkts(void);\r
+void snmp_inc_ifindiscards(void);\r
+void snmp_add_ifoutoctets(unsigned long value);\r
+void snmp_inc_ifoutucastpkts(void);\r
+void snmp_inc_ifoutnucastpkts(void);\r
+void snmp_inc_ifoutdiscards(void);\r
+\r
+/* IP */\r
+void snmp_inc_ipinreceives(void);\r
+void snmp_inc_ipindelivers(void);\r
+void snmp_inc_ipindiscards(void);\r
+void snmp_inc_ipoutdiscards(void);\r
+void snmp_inc_ipoutrequests(void);\r
+void snmp_inc_ipunknownprotos(void);\r
+void snmp_inc_ipnoroutes(void);\r
+void snmp_inc_ipforwdatagrams(void);\r
+\r
+/* ICMP */\r
+void snmp_inc_icmpinmsgs(void);\r
+void snmp_inc_icmpinerrors(void);\r
+void snmp_inc_icmpindestunreachs(void);\r
+void snmp_inc_icmpintimeexcds(void);\r
+void snmp_inc_icmpinparmprobs(void);\r
+void snmp_inc_icmpinsrcquenchs(void);\r
+void snmp_inc_icmpinredirects(void);\r
+void snmp_inc_icmpinechos(void);\r
+void snmp_inc_icmpinechoreps(void);\r
+void snmp_inc_icmpintimestamps(void);\r
+void snmp_inc_icmpintimestampreps(void);\r
+void snmp_inc_icmpinaddrmasks(void);\r
+void snmp_inc_icmpinaddrmaskreps(void);\r
+void snmp_inc_icmpoutmsgs(void);\r
+void snmp_inc_icmpouterrors(void);\r
+void snmp_inc_icmpoutdestunreachs(void);\r
+void snmp_inc_icmpouttimeexcds(void);\r
+void snmp_inc_icmpoutparmprobs(void);\r
+void snmp_inc_icmpoutsrcquenchs(void);\r
+void snmp_inc_icmpoutredirects(void); \r
+void snmp_inc_icmpoutechos(void);\r
+void snmp_inc_icmpoutechoreps(void);\r
+void snmp_inc_icmpouttimestamps(void);\r
+void snmp_inc_icmpouttimestampreps(void);\r
+void snmp_inc_icmpoutaddrmasks(void);\r
+void snmp_inc_icmpoutaddrmaskreps(void);\r
+\r
+/* TCP */\r
+void snmp_inc_tcpactiveopens(void);\r
+void snmp_inc_tcppassiveopens(void);\r
+void snmp_inc_tcpattemptfails(void);\r
+void snmp_inc_tcpestabresets(void);\r
+void snmp_inc_tcpcurrestab(void);\r
+void snmp_inc_tcpinsegs(void);\r
+void snmp_inc_tcpoutsegs(void);\r
+void snmp_inc_tcpretranssegs(void);\r
+void snmp_inc_tcpinerrs(void);\r
+void snmp_inc_tcpoutrsts(void);\r
+\r
+/* UDP */\r
+void snmp_inc_udpindatagrams(void);\r
+void snmp_inc_udpnoports(void);\r
+void snmp_inc_udpinerrors(void);\r
+void snmp_inc_udpoutdatagrams(void);\r
+\r
+/* LWIP_SNMP support not available */\r
+/* define everything to be empty */\r
+#else\r
+\r
+/* network interface */\r
+#define snmp_add_ifinoctets(value) \r
+#define snmp_inc_ifinucastpkts()\r
+#define snmp_inc_ifinnucastpkts()\r
+#define snmp_inc_ifindiscards()\r
+#define snmp_add_ifoutoctets(value)\r
+#define snmp_inc_ifoutucastpkts()\r
+#define snmp_inc_ifoutnucastpkts()\r
+#define snmp_inc_ifoutdiscards()\r
+\r
+/* IP */\r
+#define snmp_inc_ipinreceives()\r
+#define snmp_inc_ipindelivers()\r
+#define snmp_inc_ipindiscards()\r
+#define snmp_inc_ipoutdiscards()\r
+#define snmp_inc_ipoutrequests()\r
+#define snmp_inc_ipunknownprotos()\r
+#define snmp_inc_ipnoroutes()\r
+#define snmp_inc_ipforwdatagrams()\r
+\r
+/* ICMP */\r
+#define snmp_inc_icmpinmsgs()\r
+#define snmp_inc_icmpinerrors() \r
+#define snmp_inc_icmpindestunreachs() \r
+#define snmp_inc_icmpintimeexcds()\r
+#define snmp_inc_icmpinparmprobs() \r
+#define snmp_inc_icmpinsrcquenchs() \r
+#define snmp_inc_icmpinredirects() \r
+#define snmp_inc_icmpinechos() \r
+#define snmp_inc_icmpinechoreps()\r
+#define snmp_inc_icmpintimestamps() \r
+#define snmp_inc_icmpintimestampreps()\r
+#define snmp_inc_icmpinaddrmasks()\r
+#define snmp_inc_icmpinaddrmaskreps()\r
+#define snmp_inc_icmpoutmsgs()\r
+#define snmp_inc_icmpouterrors()\r
+#define snmp_inc_icmpoutdestunreachs() \r
+#define snmp_inc_icmpouttimeexcds() \r
+#define snmp_inc_icmpoutparmprobs()\r
+#define snmp_inc_icmpoutsrcquenchs()\r
+#define snmp_inc_icmpoutredirects() \r
+#define snmp_inc_icmpoutechos() \r
+#define snmp_inc_icmpoutechoreps()\r
+#define snmp_inc_icmpouttimestamps()\r
+#define snmp_inc_icmpouttimestampreps()\r
+#define snmp_inc_icmpoutaddrmasks()\r
+#define snmp_inc_icmpoutaddrmaskreps()\r
+/* TCP */\r
+#define snmp_inc_tcpactiveopens()\r
+#define snmp_inc_tcppassiveopens()\r
+#define snmp_inc_tcpattemptfails()\r
+#define snmp_inc_tcpestabresets()\r
+#define snmp_inc_tcpcurrestab()\r
+#define snmp_inc_tcpinsegs()\r
+#define snmp_inc_tcpoutsegs()\r
+#define snmp_inc_tcpretranssegs()\r
+#define snmp_inc_tcpinerrs()\r
+#define snmp_inc_tcpoutrsts()\r
+\r
+/* UDP */\r
+#define snmp_inc_udpindatagrams()\r
+#define snmp_inc_udpnoports()\r
+#define snmp_inc_udpinerrors()\r
+#define snmp_inc_udpoutdatagrams()\r
+\r
+#endif\r
+\r
+#endif /* __LWIP_SNMP_H__ */\r
index d5f8ccf74aa793629cb0fb081e347101f434e326..9c25035ad495dd9ef6650debfc4ae71638af74f1 100644 (file)
-/*
- * 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 <adam@sics.se>
- *
- */
-
-
-#ifndef __LWIP_SOCKETS_H__
-#define __LWIP_SOCKETS_H__
-#include "lwip/ip_addr.h"
-
-struct sockaddr_in {
-  u8_t sin_len;
-  u8_t sin_family;
-  u16_t sin_port;
-  struct in_addr sin_addr;
-  char sin_zero[8];
-};
-
-struct sockaddr {
-  u8_t sa_len;
-  u8_t sa_family;
-  char sa_data[14];
-};
-
-#ifndef socklen_t
-#  define socklen_t int
-#endif
-
-
-#define SOCK_STREAM     1
-#define SOCK_DGRAM      2
-#define SOCK_RAW        3
-
-/*
- * Option flags per-socket.
- */
-#define  SO_DEBUG  0x0001    /* turn on debugging info recording */
-#define  SO_ACCEPTCONN  0x0002    /* socket has had listen() */
-#define  SO_REUSEADDR  0x0004    /* allow local address reuse */
-#define  SO_KEEPALIVE  0x0008    /* keep connections alive */
-#define  SO_DONTROUTE  0x0010    /* just use interface addresses */
-#define  SO_BROADCAST  0x0020    /* permit sending of broadcast msgs */
-#define  SO_USELOOPBACK  0x0040    /* bypass hardware when possible */
-#define  SO_LINGER  0x0080    /* linger on close if data present */
-#define  SO_OOBINLINE  0x0100    /* leave received OOB data in line */
-#define         SO_REUSEPORT   0x0200          /* allow local address & port reuse */
-
-#define SO_DONTLINGER   (int)(~SO_LINGER)
-
-/*
- * Additional options, not kept in so_options.
- */
-#define SO_SNDBUF  0x1001    /* send buffer size */
-#define SO_RCVBUF  0x1002    /* receive buffer size */
-#define SO_SNDLOWAT  0x1003    /* send low-water mark */
-#define SO_RCVLOWAT  0x1004    /* receive low-water mark */
-#define SO_SNDTIMEO  0x1005    /* send timeout */
-#define SO_RCVTIMEO  0x1006    /* receive timeout */
-#define  SO_ERROR  0x1007    /* get error status and clear */
-#define  SO_TYPE    0x1008    /* get socket type */
-
-
-
-/*
- * Structure used for manipulating linger option.
- */
-struct linger {
-       int l_onoff;                /* option on/off */
-       int l_linger;               /* linger time */
-};
-
-/*
- * Level number for (get/set)sockopt() to apply to socket itself.
- */
-#define  SOL_SOCKET  0xfff    /* options for socket level */
-
-
-#define AF_UNSPEC       0
-#define AF_INET         2
-#define PF_INET         AF_INET
-#define PF_UNSPEC       AF_UNSPEC
-
-#define IPPROTO_IP      0
-#define IPPROTO_TCP     6
-#define IPPROTO_UDP     17
-
-#define INADDR_ANY      0
-#define INADDR_BROADCAST 0xffffffff
-
-/* Flags we can use with send and recv. */
-#define MSG_DONTWAIT    0x40            /* Nonblocking i/o for this operation only */
-
-
-/*
- * Options for level IPPROTO_IP
- */
-#define IP_TOS       1
-#define IP_TTL       2
-
-
-#define IPTOS_TOS_MASK          0x1E
-#define IPTOS_TOS(tos)          ((tos) & IPTOS_TOS_MASK)
-#define IPTOS_LOWDELAY          0x10
-#define IPTOS_THROUGHPUT        0x08
-#define IPTOS_RELIABILITY       0x04
-#define IPTOS_LOWCOST           0x02
-#define IPTOS_MINCOST           IPTOS_LOWCOST
-
-/*
- * Definitions for IP precedence (also in ip_tos) (hopefully unused)
- */
-#define IPTOS_PREC_MASK                 0xe0
-#define IPTOS_PREC(tos)                ((tos) & IPTOS_PREC_MASK)
-#define IPTOS_PREC_NETCONTROL           0xe0
-#define IPTOS_PREC_INTERNETCONTROL      0xc0
-#define IPTOS_PREC_CRITIC_ECP           0xa0
-#define IPTOS_PREC_FLASHOVERRIDE        0x80
-#define IPTOS_PREC_FLASH                0x60
-#define IPTOS_PREC_IMMEDIATE            0x40
-#define IPTOS_PREC_PRIORITY             0x20
-#define IPTOS_PREC_ROUTINE              0x00
-
-
-/*
- * Commands for ioctlsocket(),  taken from the BSD file fcntl.h.
- *
- *
- * Ioctl's have the command encoded in the lower word,
- * and the size of any in or out parameters in the upper
- * word.  The high 2 bits of the upper word are used
- * to encode the in/out status of the parameter; for now
- * we restrict parameters to at most 128 bytes.
- */
-#if !defined(FIONREAD) || !defined(FIONBIO)
-#define IOCPARM_MASK    0x7f            /* parameters must be < 128 bytes */
-#define IOC_VOID        0x20000000      /* no parameters */
-#define IOC_OUT         0x40000000      /* copy out parameters */
-#define IOC_IN          0x80000000      /* copy in parameters */
-#define IOC_INOUT       (IOC_IN|IOC_OUT)
-                                        /* 0x20000000 distinguishes new &
-                                           old ioctl's */
-#define _IO(x,y)        (IOC_VOID|((x)<<8)|(y))
-
-#define _IOR(x,y,t)     (IOC_OUT|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y))
-
-#define _IOW(x,y,t)     (IOC_IN|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y))
-#endif
-
-#ifndef FIONREAD
-#define FIONREAD    _IOR('f', 127, unsigned long) /* get # bytes to read */
-#endif
-#ifndef FIONBIO
-#define FIONBIO     _IOW('f', 126, unsigned long) /* set/clear non-blocking i/o */
-#endif
-
-/* Socket I/O Controls */
-#ifndef SIOCSHIWAT
-#define SIOCSHIWAT  _IOW('s',  0, unsigned long)  /* set high watermark */
-#define SIOCGHIWAT  _IOR('s',  1, unsigned long)  /* get high watermark */
-#define SIOCSLOWAT  _IOW('s',  2, unsigned long)  /* set low watermark */
-#define SIOCGLOWAT  _IOR('s',  3, unsigned long)  /* get low watermark */
-#define SIOCATMARK  _IOR('s',  7, unsigned long)  /* at oob mark? */
-#endif
-
-#ifndef O_NONBLOCK
-#define O_NONBLOCK    04000U
-#endif
-
-#ifndef FD_SET
-  #undef  FD_SETSIZE
-  #define FD_SETSIZE    16
-  #define FD_SET(n, p)  ((p)->fd_bits[(n)/8] |=  (1 << ((n) & 7)))
-  #define FD_CLR(n, p)  ((p)->fd_bits[(n)/8] &= ~(1 << ((n) & 7)))
-  #define FD_ISSET(n,p) ((p)->fd_bits[(n)/8] &   (1 << ((n) & 7)))
-  #define FD_ZERO(p)    memset((void*)(p),0,sizeof(*(p)))
-
-  typedef struct fd_set {
-          unsigned char fd_bits [(FD_SETSIZE+7)/8];
-        } fd_set;
-
-/* 
- * only define this in sockets.c so it does not interfere
- * with other projects namespaces where timeval is present
- */ 
-#ifndef LWIP_TIMEVAL_PRIVATE
-#define LWIP_TIMEVAL_PRIVATE 1
-#endif
-
-#if LWIP_TIMEVAL_PRIVATE
-  struct timeval {
-    long    tv_sec;         /* seconds */
-    long    tv_usec;        /* and microseconds */
-  };
-#endif
-
-#endif
-
-int lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen);
-int lwip_bind(int s, struct sockaddr *name, socklen_t namelen);
-int lwip_shutdown(int s, int how);
-int lwip_getpeername (int s, struct sockaddr *name, socklen_t *namelen);
-int lwip_getsockname (int s, struct sockaddr *name, socklen_t *namelen);
-int lwip_getsockopt (int s, int level, int optname, void *optval, socklen_t *optlen);
-int lwip_setsockopt (int s, int level, int optname, const void *optval, socklen_t optlen);
-int lwip_close(int s);
-int lwip_connect(int s, struct sockaddr *name, socklen_t namelen);
-int lwip_listen(int s, int backlog);
-int lwip_recv(int s, void *mem, int len, unsigned int flags);
-int lwip_read(int s, void *mem, int len);
-int lwip_recvfrom(int s, void *mem, int len, unsigned int flags,
-      struct sockaddr *from, socklen_t *fromlen);
-int lwip_send(int s, void *dataptr, int size, unsigned int flags);
-int lwip_sendto(int s, void *dataptr, int size, unsigned int flags,
-    struct sockaddr *to, socklen_t tolen);
-int lwip_socket(int domain, int type, int protocol);
-int lwip_write(int s, void *dataptr, int size);
-int lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
-                struct timeval *timeout);
-int lwip_ioctl(int s, long cmd, void *argp);
-
-#if LWIP_COMPAT_SOCKETS
-#define accept(a,b,c)         lwip_accept(a,b,c)
-#define bind(a,b,c)           lwip_bind(a,b,c)
-#define shutdown(a,b)         lwip_shutdown(a,b)
-#define close(s)              lwip_close(s)
-#define connect(a,b,c)        lwip_connect(a,b,c)
-#define getsockname(a,b,c)    lwip_getsockname(a,b,c)
-#define getpeername(a,b,c)    lwip_getpeername(a,b,c)
-#define setsockopt(a,b,c,d,e) lwip_setsockopt(a,b,c,d,e)
-#define getsockopt(a,b,c,d,e) lwip_getsockopt(a,b,c,d,e)
-#define listen(a,b)           lwip_listen(a,b)
-#define recv(a,b,c,d)         lwip_recv(a,b,c,d)
-#define read(a,b,c)           lwip_read(a,b,c)
-#define recvfrom(a,b,c,d,e,f) lwip_recvfrom(a,b,c,d,e,f)
-#define send(a,b,c,d)         lwip_send(a,b,c,d)
-#define sendto(a,b,c,d,e,f)   lwip_sendto(a,b,c,d,e,f)
-#define socket(a,b,c)         lwip_socket(a,b,c)
-#define write(a,b,c)          lwip_write(a,b,c)
-#define select(a,b,c,d,e)     lwip_select(a,b,c,d,e)
-#define ioctlsocket(a,b,c)    lwip_ioctl(a,b,c)
-#endif /* LWIP_COMPAT_SOCKETS */
-
-#endif /* __LWIP_SOCKETS_H__ */
-
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+\r
+\r
+#ifndef __LWIP_SOCKETS_H__\r
+#define __LWIP_SOCKETS_H__\r
+#include "lwip/ip_addr.h"\r
+\r
+struct sockaddr_in {\r
+  u8_t sin_len;\r
+  u8_t sin_family;\r
+  u16_t sin_port;\r
+  struct in_addr sin_addr;\r
+  char sin_zero[8];\r
+};\r
+\r
+struct sockaddr {\r
+  u8_t sa_len;\r
+  u8_t sa_family;\r
+  char sa_data[14];\r
+};\r
+\r
+#ifndef socklen_t\r
+#  define socklen_t int\r
+#endif\r
+\r
+\r
+#define SOCK_STREAM     1\r
+#define SOCK_DGRAM      2\r
+#define SOCK_RAW        3\r
+\r
+/*\r
+ * Option flags per-socket.\r
+ */\r
+#define  SO_DEBUG  0x0001    /* turn on debugging info recording */\r
+#define  SO_ACCEPTCONN  0x0002    /* socket has had listen() */\r
+#define  SO_REUSEADDR  0x0004    /* allow local address reuse */\r
+#define  SO_KEEPALIVE  0x0008    /* keep connections alive */\r
+#define  SO_DONTROUTE  0x0010    /* just use interface addresses */\r
+#define  SO_BROADCAST  0x0020    /* permit sending of broadcast msgs */\r
+#define  SO_USELOOPBACK  0x0040    /* bypass hardware when possible */\r
+#define  SO_LINGER  0x0080    /* linger on close if data present */\r
+#define  SO_OOBINLINE  0x0100    /* leave received OOB data in line */\r
+#define         SO_REUSEPORT   0x0200          /* allow local address & port reuse */\r
+\r
+#define SO_DONTLINGER   (int)(~SO_LINGER)\r
+\r
+/*\r
+ * Additional options, not kept in so_options.\r
+ */\r
+#define SO_SNDBUF  0x1001    /* send buffer size */\r
+#define SO_RCVBUF  0x1002    /* receive buffer size */\r
+#define SO_SNDLOWAT  0x1003    /* send low-water mark */\r
+#define SO_RCVLOWAT  0x1004    /* receive low-water mark */\r
+#define SO_SNDTIMEO  0x1005    /* send timeout */\r
+#define SO_RCVTIMEO  0x1006    /* receive timeout */\r
+#define  SO_ERROR  0x1007    /* get error status and clear */\r
+#define  SO_TYPE    0x1008    /* get socket type */\r
+\r
+\r
+\r
+/*\r
+ * Structure used for manipulating linger option.\r
+ */\r
+struct linger {\r
+       int l_onoff;                /* option on/off */\r
+       int l_linger;               /* linger time */\r
+};\r
+\r
+/*\r
+ * Level number for (get/set)sockopt() to apply to socket itself.\r
+ */\r
+#define  SOL_SOCKET  0xfff    /* options for socket level */\r
+\r
+\r
+#define AF_UNSPEC       0\r
+#define AF_INET         2\r
+#define PF_INET         AF_INET\r
+#define PF_UNSPEC       AF_UNSPEC\r
+\r
+#define IPPROTO_IP      0\r
+#define IPPROTO_TCP     6\r
+#define IPPROTO_UDP     17\r
+\r
+#define INADDR_ANY      0\r
+#define INADDR_BROADCAST 0xffffffff\r
+\r
+/* Flags we can use with send and recv. */\r
+#define MSG_DONTWAIT    0x40            /* Nonblocking i/o for this operation only */\r
+\r
+\r
+/*\r
+ * Options for level IPPROTO_IP\r
+ */\r
+#define IP_TOS       1\r
+#define IP_TTL       2\r
+\r
+\r
+#define IPTOS_TOS_MASK          0x1E\r
+#define IPTOS_TOS(tos)          ((tos) & IPTOS_TOS_MASK)\r
+#define IPTOS_LOWDELAY          0x10\r
+#define IPTOS_THROUGHPUT        0x08\r
+#define IPTOS_RELIABILITY       0x04\r
+#define IPTOS_LOWCOST           0x02\r
+#define IPTOS_MINCOST           IPTOS_LOWCOST\r
+\r
+/*\r
+ * Definitions for IP precedence (also in ip_tos) (hopefully unused)\r
+ */\r
+#define IPTOS_PREC_MASK                 0xe0\r
+#define IPTOS_PREC(tos)                ((tos) & IPTOS_PREC_MASK)\r
+#define IPTOS_PREC_NETCONTROL           0xe0\r
+#define IPTOS_PREC_INTERNETCONTROL      0xc0\r
+#define IPTOS_PREC_CRITIC_ECP           0xa0\r
+#define IPTOS_PREC_FLASHOVERRIDE        0x80\r
+#define IPTOS_PREC_FLASH                0x60\r
+#define IPTOS_PREC_IMMEDIATE            0x40\r
+#define IPTOS_PREC_PRIORITY             0x20\r
+#define IPTOS_PREC_ROUTINE              0x00\r
+\r
+\r
+/*\r
+ * Commands for ioctlsocket(),  taken from the BSD file fcntl.h.\r
+ *\r
+ *\r
+ * Ioctl's have the command encoded in the lower word,\r
+ * and the size of any in or out parameters in the upper\r
+ * word.  The high 2 bits of the upper word are used\r
+ * to encode the in/out status of the parameter; for now\r
+ * we restrict parameters to at most 128 bytes.\r
+ */\r
+#if !defined(FIONREAD) || !defined(FIONBIO)\r
+#define IOCPARM_MASK    0x7f            /* parameters must be < 128 bytes */\r
+#define IOC_VOID        0x20000000      /* no parameters */\r
+#define IOC_OUT         0x40000000      /* copy out parameters */\r
+#define IOC_IN          0x80000000      /* copy in parameters */\r
+#define IOC_INOUT       (IOC_IN|IOC_OUT)\r
+                                        /* 0x20000000 distinguishes new &\r
+                                           old ioctl's */\r
+#define _IO(x,y)        (IOC_VOID|((x)<<8)|(y))\r
+\r
+#define _IOR(x,y,t)     (IOC_OUT|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y))\r
+\r
+#define _IOW(x,y,t)     (IOC_IN|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y))\r
+#endif\r
+\r
+#ifndef FIONREAD\r
+#define FIONREAD    _IOR('f', 127, unsigned long) /* get # bytes to read */\r
+#endif\r
+#ifndef FIONBIO\r
+#define FIONBIO     _IOW('f', 126, unsigned long) /* set/clear non-blocking i/o */\r
+#endif\r
+\r
+/* Socket I/O Controls */\r
+#ifndef SIOCSHIWAT\r
+#define SIOCSHIWAT  _IOW('s',  0, unsigned long)  /* set high watermark */\r
+#define SIOCGHIWAT  _IOR('s',  1, unsigned long)  /* get high watermark */\r
+#define SIOCSLOWAT  _IOW('s',  2, unsigned long)  /* set low watermark */\r
+#define SIOCGLOWAT  _IOR('s',  3, unsigned long)  /* get low watermark */\r
+#define SIOCATMARK  _IOR('s',  7, unsigned long)  /* at oob mark? */\r
+#endif\r
+\r
+#ifndef O_NONBLOCK\r
+#define O_NONBLOCK    04000U\r
+#endif\r
+\r
+#ifndef FD_SET\r
+  #undef  FD_SETSIZE\r
+  #define FD_SETSIZE    16\r
+  #define FD_SET(n, p)  ((p)->fd_bits[(n)/8] |=  (1 << ((n) & 7)))\r
+  #define FD_CLR(n, p)  ((p)->fd_bits[(n)/8] &= ~(1 << ((n) & 7)))\r
+  #define FD_ISSET(n,p) ((p)->fd_bits[(n)/8] &   (1 << ((n) & 7)))\r
+  #define FD_ZERO(p)    memset((void*)(p),0,sizeof(*(p)))\r
+\r
+  typedef struct fd_set {\r
+          unsigned char fd_bits [(FD_SETSIZE+7)/8];\r
+        } fd_set;\r
+\r
+/* \r
+ * only define this in sockets.c so it does not interfere\r
+ * with other projects namespaces where timeval is present\r
+ */ \r
+#ifndef LWIP_TIMEVAL_PRIVATE\r
+#define LWIP_TIMEVAL_PRIVATE 1\r
+#endif\r
+\r
+#if LWIP_TIMEVAL_PRIVATE\r
+  struct timeval {\r
+    long    tv_sec;         /* seconds */\r
+    long    tv_usec;        /* and microseconds */\r
+  };\r
+#endif\r
+\r
+#endif\r
+\r
+int lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen);\r
+int lwip_bind(int s, struct sockaddr *name, socklen_t namelen);\r
+int lwip_shutdown(int s, int how);\r
+int lwip_getpeername (int s, struct sockaddr *name, socklen_t *namelen);\r
+int lwip_getsockname (int s, struct sockaddr *name, socklen_t *namelen);\r
+int lwip_getsockopt (int s, int level, int optname, void *optval, socklen_t *optlen);\r
+int lwip_setsockopt (int s, int level, int optname, const void *optval, socklen_t optlen);\r
+int lwip_close(int s);\r
+int lwip_connect(int s, struct sockaddr *name, socklen_t namelen);\r
+int lwip_listen(int s, int backlog);\r
+int lwip_recv(int s, void *mem, int len, unsigned int flags);\r
+int lwip_read(int s, void *mem, int len);\r
+int lwip_recvfrom(int s, void *mem, int len, unsigned int flags,\r
+      struct sockaddr *from, socklen_t *fromlen);\r
+int lwip_send(int s, void *dataptr, int size, unsigned int flags);\r
+int lwip_sendto(int s, void *dataptr, int size, unsigned int flags,\r
+    struct sockaddr *to, socklen_t tolen);\r
+int lwip_socket(int domain, int type, int protocol);\r
+int lwip_write(int s, void *dataptr, int size);\r
+int lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,\r
+                struct timeval *timeout);\r
+int lwip_ioctl(int s, long cmd, void *argp);\r
+\r
+#if LWIP_COMPAT_SOCKETS\r
+#define accept(a,b,c)         lwip_accept(a,b,c)\r
+#define bind(a,b,c)           lwip_bind(a,b,c)\r
+#define shutdown(a,b)         lwip_shutdown(a,b)\r
+#define close(s)              lwip_close(s)\r
+#define connect(a,b,c)        lwip_connect(a,b,c)\r
+#define getsockname(a,b,c)    lwip_getsockname(a,b,c)\r
+#define getpeername(a,b,c)    lwip_getpeername(a,b,c)\r
+#define setsockopt(a,b,c,d,e) lwip_setsockopt(a,b,c,d,e)\r
+#define getsockopt(a,b,c,d,e) lwip_getsockopt(a,b,c,d,e)\r
+#define listen(a,b)           lwip_listen(a,b)\r
+#define recv(a,b,c,d)         lwip_recv(a,b,c,d)\r
+#define read(a,b,c)           lwip_read(a,b,c)\r
+#define recvfrom(a,b,c,d,e,f) lwip_recvfrom(a,b,c,d,e,f)\r
+#define send(a,b,c,d)         lwip_send(a,b,c,d)\r
+#define sendto(a,b,c,d,e,f)   lwip_sendto(a,b,c,d,e,f)\r
+#define socket(a,b,c)         lwip_socket(a,b,c)\r
+#define write(a,b,c)          lwip_write(a,b,c)\r
+#define select(a,b,c,d,e)     lwip_select(a,b,c,d,e)\r
+#define ioctlsocket(a,b,c)    lwip_ioctl(a,b,c)\r
+#endif /* LWIP_COMPAT_SOCKETS */\r
+\r
+#endif /* __LWIP_SOCKETS_H__ */\r
+\r
index 71acfd068f3730beedf233d4089d6edeb5fedab4..29dfd5731e13b9ebec3eb506a8e3333f0cfa7a9b 100644 (file)
-/*
- * 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 <adam@sics.se>
- *
- */
-#ifndef __LWIP_STATS_H__
-#define __LWIP_STATS_H__
-
-#include "lwip/opt.h"
-#include "arch/cc.h"
-
-#include "lwip/mem.h"
-#include "lwip/memp.h"
-
-#if LWIP_STATS
-
-struct stats_proto {
-  u16_t xmit;    /* Transmitted packets. */
-  u16_t rexmit;  /* Retransmitted packets. */
-  u16_t recv;    /* Received packets. */
-  u16_t fw;      /* Forwarded packets. */
-  u16_t drop;    /* Dropped packets. */
-  u16_t chkerr;  /* Checksum error. */
-  u16_t lenerr;  /* Invalid length error. */
-  u16_t memerr;  /* Out of memory error. */
-  u16_t rterr;   /* Routing error. */
-  u16_t proterr; /* Protocol error. */
-  u16_t opterr;  /* Error in options. */
-  u16_t err;     /* Misc error. */
-  u16_t cachehit;
-};
-
-struct stats_mem {
-  mem_size_t avail;
-  mem_size_t used;
-  mem_size_t max;  
-  mem_size_t err;
-};
-
-struct stats_pbuf {
-  u16_t avail;
-  u16_t used;
-  u16_t max;  
-  u16_t err;
-
-  u16_t alloc_locked;
-  u16_t refresh_locked;
-};
-
-struct stats_syselem {
-  u16_t used;
-  u16_t max;
-  u16_t err;
-};
-
-struct stats_sys {
-  struct stats_syselem sem;
-  struct stats_syselem mbox;
-};
-
-struct stats_ {
-  struct stats_proto link;
-  struct stats_proto ip_frag;
-  struct stats_proto ip;
-  struct stats_proto icmp;
-  struct stats_proto udp;
-  struct stats_proto tcp;
-  struct stats_pbuf pbuf;
-  struct stats_mem mem;
-  struct stats_mem memp[MEMP_MAX];
-  struct stats_sys sys;
-};
-
-extern struct stats_ lwip_stats;
-
-
-void stats_init(void);
-
-#define STATS_INC(x) ++lwip_stats.x
-#else
-#define stats_init()
-#define STATS_INC(x)
-#endif /* LWIP_STATS */
-
-#if TCP_STATS
-#define TCP_STATS_INC(x) STATS_INC(x)
-#else
-#define TCP_STATS_INC(x)
-#endif
-
-#if UDP_STATS
-#define UDP_STATS_INC(x) STATS_INC(x)
-#else
-#define UDP_STATS_INC(x)
-#endif
-
-#if ICMP_STATS
-#define ICMP_STATS_INC(x) STATS_INC(x)
-#else
-#define ICMP_STATS_INC(x)
-#endif
-
-#if IP_STATS
-#define IP_STATS_INC(x) STATS_INC(x)
-#else
-#define IP_STATS_INC(x)
-#endif
-
-#if IPFRAG_STATS
-#define IPFRAG_STATS_INC(x) STATS_INC(x)
-#else
-#define IPFRAG_STATS_INC(x)
-#endif
-
-#if LINK_STATS
-#define LINK_STATS_INC(x) STATS_INC(x)
-#else
-#define LINK_STATS_INC(x)
-#endif
-
-/* Display of statistics */
-#if LWIP_STATS_DISPLAY
-void stats_display(void);
-#else
-#define stats_display()
-#endif
-
-#endif /* __LWIP_STATS_H__ */
-
-
-
-
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+#ifndef __LWIP_STATS_H__\r
+#define __LWIP_STATS_H__\r
+\r
+#include "lwip/opt.h"\r
+#include "arch/cc.h"\r
+\r
+#include "lwip/mem.h"\r
+#include "lwip/memp.h"\r
+\r
+#if LWIP_STATS\r
+\r
+struct stats_proto {\r
+  u16_t xmit;    /* Transmitted packets. */\r
+  u16_t rexmit;  /* Retransmitted packets. */\r
+  u16_t recv;    /* Received packets. */\r
+  u16_t fw;      /* Forwarded packets. */\r
+  u16_t drop;    /* Dropped packets. */\r
+  u16_t chkerr;  /* Checksum error. */\r
+  u16_t lenerr;  /* Invalid length error. */\r
+  u16_t memerr;  /* Out of memory error. */\r
+  u16_t rterr;   /* Routing error. */\r
+  u16_t proterr; /* Protocol error. */\r
+  u16_t opterr;  /* Error in options. */\r
+  u16_t err;     /* Misc error. */\r
+  u16_t cachehit;\r
+};\r
+\r
+struct stats_mem {\r
+  mem_size_t avail;\r
+  mem_size_t used;\r
+  mem_size_t max;  \r
+  mem_size_t err;\r
+};\r
+\r
+struct stats_pbuf {\r
+  u16_t avail;\r
+  u16_t used;\r
+  u16_t max;  \r
+  u16_t err;\r
+\r
+  u16_t alloc_locked;\r
+  u16_t refresh_locked;\r
+};\r
+\r
+struct stats_syselem {\r
+  u16_t used;\r
+  u16_t max;\r
+  u16_t err;\r
+};\r
+\r
+struct stats_sys {\r
+  struct stats_syselem sem;\r
+  struct stats_syselem mbox;\r
+};\r
+\r
+struct stats_ {\r
+  struct stats_proto link;\r
+  struct stats_proto ip_frag;\r
+  struct stats_proto ip;\r
+  struct stats_proto icmp;\r
+  struct stats_proto udp;\r
+  struct stats_proto tcp;\r
+  struct stats_pbuf pbuf;\r
+  struct stats_mem mem;\r
+  struct stats_mem memp[MEMP_MAX];\r
+  struct stats_sys sys;\r
+};\r
+\r
+extern struct stats_ lwip_stats;\r
+\r
+\r
+void stats_init(void);\r
+\r
+#define STATS_INC(x) ++lwip_stats.x\r
+#else\r
+#define stats_init()\r
+#define STATS_INC(x)\r
+#endif /* LWIP_STATS */\r
+\r
+#if TCP_STATS\r
+#define TCP_STATS_INC(x) STATS_INC(x)\r
+#else\r
+#define TCP_STATS_INC(x)\r
+#endif\r
+\r
+#if UDP_STATS\r
+#define UDP_STATS_INC(x) STATS_INC(x)\r
+#else\r
+#define UDP_STATS_INC(x)\r
+#endif\r
+\r
+#if ICMP_STATS\r
+#define ICMP_STATS_INC(x) STATS_INC(x)\r
+#else\r
+#define ICMP_STATS_INC(x)\r
+#endif\r
+\r
+#if IP_STATS\r
+#define IP_STATS_INC(x) STATS_INC(x)\r
+#else\r
+#define IP_STATS_INC(x)\r
+#endif\r
+\r
+#if IPFRAG_STATS\r
+#define IPFRAG_STATS_INC(x) STATS_INC(x)\r
+#else\r
+#define IPFRAG_STATS_INC(x)\r
+#endif\r
+\r
+#if LINK_STATS\r
+#define LINK_STATS_INC(x) STATS_INC(x)\r
+#else\r
+#define LINK_STATS_INC(x)\r
+#endif\r
+\r
+/* Display of statistics */\r
+#if LWIP_STATS_DISPLAY\r
+void stats_display(void);\r
+#else\r
+#define stats_display()\r
+#endif\r
+\r
+#endif /* __LWIP_STATS_H__ */\r
+\r
+\r
+\r
+\r
index 68926e95420ea3bb6419808a8d468e147568744c..d2328c4622f2629265f9121cb45c5abadc9fc702 100644 (file)
-/*
- * 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 <adam@sics.se>
- *
- */
-#ifndef __LWIP_SYS_H__
-#define __LWIP_SYS_H__
-
-#include "arch/cc.h"
-
-#include "lwip/opt.h"
-
-
-#if NO_SYS
-
-/* For a totally minimal and standalone system, we provide null
-   definitions of the sys_ functions. */
-typedef u8_t sys_sem_t;
-typedef u8_t sys_mbox_t;
-struct sys_timeout {u8_t dummy;};
-
-#define sys_init()
-#define sys_timeout(m,h,a)
-#define sys_untimeout(m,a)
-#define sys_sem_new(c) c
-#define sys_sem_signal(s)
-#define sys_sem_wait(s)
-#define sys_sem_free(s)
-#define sys_mbox_new() 0
-#define sys_mbox_fetch(m,d)
-#define sys_mbox_post(m,d)
-#define sys_mbox_free(m)
-
-#define sys_thread_new(t,a,p)
-
-#else /* NO_SYS */
-
-#include "arch/sys_arch.h"
-
-/** Return code for timeouts from sys_arch_mbox_fetch and sys_arch_sem_wait */
-#define SYS_ARCH_TIMEOUT 0xffffffff
-
-typedef void (* sys_timeout_handler)(void *arg);
-
-struct sys_timeout {
-  struct sys_timeout *next;
-  u32_t time;
-  sys_timeout_handler h;
-  void *arg;
-};
-
-struct sys_timeouts {
-  struct sys_timeout *next;
-};
-
-/* sys_init() must be called before anthing else. */
-void sys_init(void);
-
-/*
- * sys_timeout():
- *
- * Schedule a timeout a specified amount of milliseconds in the
- * future. When the timeout occurs, the specified timeout handler will
- * be called. The handler will be passed the "arg" argument when
- * called.
- *
- */
-void sys_timeout(u32_t msecs, sys_timeout_handler h, void *arg);
-void sys_untimeout(sys_timeout_handler h, void *arg);
-struct sys_timeouts *sys_arch_timeouts(void);
-
-/* Semaphore functions. */
-sys_sem_t sys_sem_new(u8_t count);
-void sys_sem_signal(sys_sem_t sem);
-u32_t sys_arch_sem_wait(sys_sem_t sem, u32_t timeout);
-void sys_sem_free(sys_sem_t sem);
-void sys_sem_wait(sys_sem_t sem);
-int sys_sem_wait_timeout(sys_sem_t sem, u32_t timeout);
-
-/* Time functions. */
-#ifndef sys_msleep
-void sys_msleep(u32_t ms); /* only has a (close to) 1 jiffy resolution. */
-#endif
-#ifndef sys_jiffies
-u32_t sys_jiffies(void); /* since power up. */
-#endif
-
-/* Mailbox functions. */
-sys_mbox_t sys_mbox_new(void);
-void sys_mbox_post(sys_mbox_t mbox, void *msg);
-u32_t sys_arch_mbox_fetch(sys_mbox_t mbox, void **msg, u32_t timeout);
-void sys_mbox_free(sys_mbox_t mbox);
-void sys_mbox_fetch(sys_mbox_t mbox, void **msg);
-
-
-/* Thread functions. */
-sys_thread_t sys_thread_new(void (* thread)(void *arg), void *arg, int prio);
-
-/* The following functions are used only in Unix code, and
-   can be omitted when porting the stack. */
-/* Returns the current time in microseconds. */
-unsigned long sys_now(void);
-
-#endif /* NO_SYS */
-
-/* Critical Region Protection */
-/* These functions must be implemented in the sys_arch.c file.
-   In some implementations they can provide a more light-weight protection
-   mechanism than using semaphores. Otherwise semaphores can be used for
-   implementation */
-#ifndef SYS_ARCH_PROTECT
-/** SYS_LIGHTWEIGHT_PROT
- * define SYS_LIGHTWEIGHT_PROT in lwipopts.h if you want inter-task protection
- * for certain critical regions during buffer allocation, deallocation and memory
- * allocation and deallocation.
- */
-#if SYS_LIGHTWEIGHT_PROT
-
-/** SYS_ARCH_DECL_PROTECT
- * declare a protection variable. This macro will default to defining a variable of
- * type sys_prot_t. If a particular port needs a different implementation, then
- * this macro may be defined in sys_arch.h.
- */
-#define SYS_ARCH_DECL_PROTECT(lev) sys_prot_t lev
-/** SYS_ARCH_PROTECT
- * Perform a "fast" protect. This could be implemented by
- * disabling interrupts for an embedded system or by using a semaphore or
- * mutex. The implementation should allow calling SYS_ARCH_PROTECT when
- * already protected. The old protection level is returned in the variable
- * "lev". This macro will default to calling the sys_arch_protect() function
- * which should be implemented in sys_arch.c. If a particular port needs a
- * different implementation, then this macro may be defined in sys_arch.h
- */
-#define SYS_ARCH_PROTECT(lev) lev = sys_arch_protect()
-/** SYS_ARCH_UNPROTECT
- * Perform a "fast" set of the protection level to "lev". This could be
- * implemented by setting the interrupt level to "lev" within the MACRO or by
- * using a semaphore or mutex.  This macro will default to calling the
- * sys_arch_unprotect() function which should be implemented in
- * sys_arch.c. If a particular port needs a different implementation, then
- * this macro may be defined in sys_arch.h
- */
-#define SYS_ARCH_UNPROTECT(lev) sys_arch_unprotect(lev)
-sys_prot_t sys_arch_protect(void);
-void sys_arch_unprotect(sys_prot_t pval);
-
-#else
-
-#define SYS_ARCH_DECL_PROTECT(lev)
-#define SYS_ARCH_PROTECT(lev)
-#define SYS_ARCH_UNPROTECT(lev)
-
-#endif /* SYS_LIGHTWEIGHT_PROT */
-
-#endif /* SYS_ARCH_PROTECT */
-
-#endif /* __LWIP_SYS_H__ */
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+#ifndef __LWIP_SYS_H__\r
+#define __LWIP_SYS_H__\r
+\r
+#include "arch/cc.h"\r
+\r
+#include "lwip/opt.h"\r
+\r
+\r
+#if NO_SYS\r
+\r
+/* For a totally minimal and standalone system, we provide null\r
+   definitions of the sys_ functions. */\r
+typedef u8_t sys_sem_t;\r
+typedef u8_t sys_mbox_t;\r
+struct sys_timeout {u8_t dummy;};\r
+\r
+#define sys_init()\r
+#define sys_timeout(m,h,a)\r
+#define sys_untimeout(m,a)\r
+#define sys_sem_new(c) c\r
+#define sys_sem_signal(s)\r
+#define sys_sem_wait(s)\r
+#define sys_sem_free(s)\r
+#define sys_mbox_new() 0\r
+#define sys_mbox_fetch(m,d)\r
+#define sys_mbox_post(m,d)\r
+#define sys_mbox_free(m)\r
+\r
+#define sys_thread_new(t,a,p)\r
+\r
+#else /* NO_SYS */\r
+\r
+#include "arch/sys_arch.h"\r
+\r
+/** Return code for timeouts from sys_arch_mbox_fetch and sys_arch_sem_wait */\r
+#define SYS_ARCH_TIMEOUT 0xffffffff\r
+\r
+typedef void (* sys_timeout_handler)(void *arg);\r
+\r
+struct sys_timeout {\r
+  struct sys_timeout *next;\r
+  u32_t time;\r
+  sys_timeout_handler h;\r
+  void *arg;\r
+};\r
+\r
+struct sys_timeouts {\r
+  struct sys_timeout *next;\r
+};\r
+\r
+/* sys_init() must be called before anthing else. */\r
+void sys_init(void);\r
+\r
+/*\r
+ * sys_timeout():\r
+ *\r
+ * Schedule a timeout a specified amount of milliseconds in the\r
+ * future. When the timeout occurs, the specified timeout handler will\r
+ * be called. The handler will be passed the "arg" argument when\r
+ * called.\r
+ *\r
+ */\r
+void sys_timeout(u32_t msecs, sys_timeout_handler h, void *arg);\r
+void sys_untimeout(sys_timeout_handler h, void *arg);\r
+struct sys_timeouts *sys_arch_timeouts(void);\r
+\r
+/* Semaphore functions. */\r
+sys_sem_t sys_sem_new(u8_t count);\r
+void sys_sem_signal(sys_sem_t sem);\r
+u32_t sys_arch_sem_wait(sys_sem_t sem, u32_t timeout);\r
+void sys_sem_free(sys_sem_t sem);\r
+void sys_sem_wait(sys_sem_t sem);\r
+int sys_sem_wait_timeout(sys_sem_t sem, u32_t timeout);\r
+\r
+/* Time functions. */\r
+#ifndef sys_msleep\r
+void sys_msleep(u32_t ms); /* only has a (close to) 1 jiffy resolution. */\r
+#endif\r
+#ifndef sys_jiffies\r
+u32_t sys_jiffies(void); /* since power up. */\r
+#endif\r
+\r
+/* Mailbox functions. */\r
+sys_mbox_t sys_mbox_new(void);\r
+void sys_mbox_post(sys_mbox_t mbox, void *msg);\r
+u32_t sys_arch_mbox_fetch(sys_mbox_t mbox, void **msg, u32_t timeout);\r
+void sys_mbox_free(sys_mbox_t mbox);\r
+void sys_mbox_fetch(sys_mbox_t mbox, void **msg);\r
+\r
+\r
+/* Thread functions. */\r
+sys_thread_t sys_thread_new(void (* thread)(void *arg), void *arg, int prio);\r
+\r
+/* The following functions are used only in Unix code, and\r
+   can be omitted when porting the stack. */\r
+/* Returns the current time in microseconds. */\r
+unsigned long sys_now(void);\r
+\r
+#endif /* NO_SYS */\r
+\r
+/* Critical Region Protection */\r
+/* These functions must be implemented in the sys_arch.c file.\r
+   In some implementations they can provide a more light-weight protection\r
+   mechanism than using semaphores. Otherwise semaphores can be used for\r
+   implementation */\r
+#ifndef SYS_ARCH_PROTECT\r
+/** SYS_LIGHTWEIGHT_PROT\r
+ * define SYS_LIGHTWEIGHT_PROT in lwipopts.h if you want inter-task protection\r
+ * for certain critical regions during buffer allocation, deallocation and memory\r
+ * allocation and deallocation.\r
+ */\r
+#if SYS_LIGHTWEIGHT_PROT\r
+\r
+/** SYS_ARCH_DECL_PROTECT\r
+ * declare a protection variable. This macro will default to defining a variable of\r
+ * type sys_prot_t. If a particular port needs a different implementation, then\r
+ * this macro may be defined in sys_arch.h.\r
+ */\r
+#define SYS_ARCH_DECL_PROTECT(lev) sys_prot_t lev\r
+/** SYS_ARCH_PROTECT\r
+ * Perform a "fast" protect. This could be implemented by\r
+ * disabling interrupts for an embedded system or by using a semaphore or\r
+ * mutex. The implementation should allow calling SYS_ARCH_PROTECT when\r
+ * already protected. The old protection level is returned in the variable\r
+ * "lev". This macro will default to calling the sys_arch_protect() function\r
+ * which should be implemented in sys_arch.c. If a particular port needs a\r
+ * different implementation, then this macro may be defined in sys_arch.h\r
+ */\r
+#define SYS_ARCH_PROTECT(lev) lev = sys_arch_protect()\r
+/** SYS_ARCH_UNPROTECT\r
+ * Perform a "fast" set of the protection level to "lev". This could be\r
+ * implemented by setting the interrupt level to "lev" within the MACRO or by\r
+ * using a semaphore or mutex.  This macro will default to calling the\r
+ * sys_arch_unprotect() function which should be implemented in\r
+ * sys_arch.c. If a particular port needs a different implementation, then\r
+ * this macro may be defined in sys_arch.h\r
+ */\r
+#define SYS_ARCH_UNPROTECT(lev) sys_arch_unprotect(lev)\r
+sys_prot_t sys_arch_protect(void);\r
+void sys_arch_unprotect(sys_prot_t pval);\r
+\r
+#else\r
+\r
+#define SYS_ARCH_DECL_PROTECT(lev)\r
+#define SYS_ARCH_PROTECT(lev)\r
+#define SYS_ARCH_UNPROTECT(lev)\r
+\r
+#endif /* SYS_LIGHTWEIGHT_PROT */\r
+\r
+#endif /* SYS_ARCH_PROTECT */\r
+\r
+#endif /* __LWIP_SYS_H__ */\r
index 301a3f0235592c1bed5129b8c7757c3e2e68c70a..81eb51e08a8e08f2c75effd80b525746f4cc1794 100644 (file)
-/*
- * 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 <adam@sics.se>
- *
- */
-#ifndef __LWIP_TCP_H__
-#define __LWIP_TCP_H__
-
-#include "lwip/sys.h"
-#include "lwip/mem.h"
-
-#include "lwip/pbuf.h"
-#include "lwip/opt.h"
-#include "lwip/ip.h"
-#include "lwip/icmp.h"
-
-#include "lwip/err.h"
-
-struct tcp_pcb;
-
-/* Functions for interfacing with TCP: */
-
-/* Lower layer interface to TCP: */
-void             tcp_init    (void);  /* Must be called first to
-           initialize TCP. */
-void             tcp_tmr     (void);  /* Must be called every
-           TCP_TMR_INTERVAL
-           ms. (Typically 250 ms). */
-/* Application program's interface: */
-struct tcp_pcb * tcp_new     (void);
-struct tcp_pcb * tcp_alloc   (u8_t prio);
-
-void             tcp_arg     (struct tcp_pcb *pcb, void *arg);
-void             tcp_accept  (struct tcp_pcb *pcb,
-            err_t (* accept)(void *arg, struct tcp_pcb *newpcb,
-                 err_t err));
-void             tcp_recv    (struct tcp_pcb *pcb,
-            err_t (* recv)(void *arg, struct tcp_pcb *tpcb,
-          struct pbuf *p, err_t err));
-void             tcp_sent    (struct tcp_pcb *pcb,
-            err_t (* sent)(void *arg, struct tcp_pcb *tpcb,
-               u16_t len));
-void             tcp_poll    (struct tcp_pcb *pcb,
-            err_t (* poll)(void *arg, struct tcp_pcb *tpcb),
-            u8_t interval);
-void             tcp_err     (struct tcp_pcb *pcb,
-            void (* err)(void *arg, err_t err));
-
-#define          tcp_mss(pcb)      ((pcb)->mss)
-#define          tcp_sndbuf(pcb)   ((pcb)->snd_buf)
-
-void             tcp_recved  (struct tcp_pcb *pcb, u16_t len);
-err_t            tcp_bind    (struct tcp_pcb *pcb, struct ip_addr *ipaddr,
-            u16_t port);
-err_t            tcp_connect (struct tcp_pcb *pcb, struct ip_addr *ipaddr,
-            u16_t port, err_t (* connected)(void *arg,
-                    struct tcp_pcb *tpcb,
-                    err_t err));
-struct tcp_pcb * tcp_listen  (struct tcp_pcb *pcb);
-void             tcp_abort   (struct tcp_pcb *pcb);
-err_t            tcp_close   (struct tcp_pcb *pcb);
-err_t            tcp_write   (struct tcp_pcb *pcb, const void *dataptr, u16_t len,
-            u8_t copy);
-
-void             tcp_setprio (struct tcp_pcb *pcb, u8_t prio);
-
-#define TCP_PRIO_MIN    1
-#define TCP_PRIO_NORMAL 64
-#define TCP_PRIO_MAX    127
-
-/* It is also possible to call these two functions at the right
-   intervals (instead of calling tcp_tmr()). */
-void             tcp_slowtmr (void);
-void             tcp_fasttmr (void);
-
-
-/* Only used by IP to pass a TCP segment to TCP: */
-void             tcp_input   (struct pbuf *p, struct netif *inp);
-/* Used within the TCP code only: */
-err_t            tcp_output  (struct tcp_pcb *pcb);
-void             tcp_rexmit  (struct tcp_pcb *pcb);
-void             tcp_rexmit_rto  (struct tcp_pcb *pcb);
-
-
-
-#define TCP_SEQ_LT(a,b)     ((s32_t)((a)-(b)) < 0)
-#define TCP_SEQ_LEQ(a,b)    ((s32_t)((a)-(b)) <= 0)
-#define TCP_SEQ_GT(a,b)     ((s32_t)((a)-(b)) > 0)
-#define TCP_SEQ_GEQ(a,b)    ((s32_t)((a)-(b)) >= 0)
-/* is b<=a<=c? */
-#if 0 /* see bug #10548 */
-#define TCP_SEQ_BETWEEN(a,b,c) ((c)-(b) >= (a)-(b))
-#endif
-#define TCP_SEQ_BETWEEN(a,b,c) (TCP_SEQ_GEQ(a,b) && TCP_SEQ_LEQ(a,c))
-#define TCP_FIN 0x01U
-#define TCP_SYN 0x02U
-#define TCP_RST 0x04U
-#define TCP_PSH 0x08U
-#define TCP_ACK 0x10U
-#define TCP_URG 0x20U
-#define TCP_ECE 0x40U
-#define TCP_CWR 0x80U
-
-#define TCP_FLAGS 0x3fU
-
-/* Length of the TCP header, excluding options. */
-#define TCP_HLEN 20
-
-#ifndef TCP_TMR_INTERVAL
-#define TCP_TMR_INTERVAL       250  /* The TCP timer interval in
-                                       milliseconds. */
-#endif /* TCP_TMR_INTERVAL */
-
-#ifndef TCP_FAST_INTERVAL
-#define TCP_FAST_INTERVAL      TCP_TMR_INTERVAL /* the fine grained timeout in
-                                       milliseconds */
-#endif /* TCP_FAST_INTERVAL */
-
-#ifndef TCP_SLOW_INTERVAL
-#define TCP_SLOW_INTERVAL      (2*TCP_TMR_INTERVAL)  /* the coarse grained timeout in
-                                       milliseconds */
-#endif /* TCP_SLOW_INTERVAL */
-
-#define TCP_FIN_WAIT_TIMEOUT 20000 /* milliseconds */
-#define TCP_SYN_RCVD_TIMEOUT 20000 /* milliseconds */
-
-#define TCP_OOSEQ_TIMEOUT        6 /* x RTO */
-
-#define TCP_MSL 60000  /* The maximum segment lifetime in microseconds */
-
-/*
- * User-settable options (used with setsockopt).
- */
-#define        TCP_NODELAY        0x01    /* don't delay send to coalesce packets */
-#define TCP_KEEPALIVE  0x02    /* send KEEPALIVE probes when idle for pcb->keepalive miliseconds */
-
-/* Keepalive values */
-#define  TCP_KEEPDEFAULT   7200000                       /* KEEPALIVE timer in miliseconds */
-#define  TCP_KEEPINTVL     75000                         /* Time between KEEPALIVE probes in miliseconds */
-#define  TCP_KEEPCNT       9                             /* Counter for KEEPALIVE probes */
-#define  TCP_MAXIDLE       TCP_KEEPCNT * TCP_KEEPINTVL   /* Maximum KEEPALIVE probe time */
-
-
-#ifdef PACK_STRUCT_USE_INCLUDES
-#  include "arch/bpstruct.h"
-#endif
-PACK_STRUCT_BEGIN
-struct tcp_hdr {
-  PACK_STRUCT_FIELD(u16_t src);
-  PACK_STRUCT_FIELD(u16_t dest);
-  PACK_STRUCT_FIELD(u32_t seqno);
-  PACK_STRUCT_FIELD(u32_t ackno);
-  PACK_STRUCT_FIELD(u16_t _hdrlen_rsvd_flags);
-  PACK_STRUCT_FIELD(u16_t wnd);
-  PACK_STRUCT_FIELD(u16_t chksum);
-  PACK_STRUCT_FIELD(u16_t urgp);
-} PACK_STRUCT_STRUCT;
-PACK_STRUCT_END
-#ifdef PACK_STRUCT_USE_INCLUDES
-#  include "arch/epstruct.h"
-#endif
-
-#define TCPH_OFFSET(phdr) (ntohs((phdr)->_hdrlen_rsvd_flags) >> 8)
-#define TCPH_HDRLEN(phdr) (ntohs((phdr)->_hdrlen_rsvd_flags) >> 12)
-#define TCPH_FLAGS(phdr)  (ntohs((phdr)->_hdrlen_rsvd_flags) & TCP_FLAGS)
-
-#define TCPH_OFFSET_SET(phdr, offset) (phdr)->_hdrlen_rsvd_flags = htons(((offset) << 8) | TCPH_FLAGS(phdr))
-#define TCPH_HDRLEN_SET(phdr, len) (phdr)->_hdrlen_rsvd_flags = htons(((len) << 12) | TCPH_FLAGS(phdr))
-#define TCPH_FLAGS_SET(phdr, flags) (phdr)->_hdrlen_rsvd_flags = htons((ntohs((phdr)->_hdrlen_rsvd_flags) & ~TCP_FLAGS) | (flags))
-#define TCPH_SET_FLAG(phdr, flags ) (phdr)->_hdrlen_rsvd_flags = htons(ntohs((phdr)->_hdrlen_rsvd_flags) | (flags))
-#define TCPH_UNSET_FLAG(phdr, flags) (phdr)->_hdrlen_rsvd_flags = htons(ntohs((phdr)->_hdrlen_rsvd_flags) | (TCPH_FLAGS(phdr) & ~(flags)) )
-
-#define TCP_TCPLEN(seg) ((seg)->len + ((TCPH_FLAGS((seg)->tcphdr) & TCP_FIN || \
-          TCPH_FLAGS((seg)->tcphdr) & TCP_SYN)? 1: 0))
-
-enum tcp_state {
-  CLOSED      = 0,
-  LISTEN      = 1,
-  SYN_SENT    = 2,
-  SYN_RCVD    = 3,
-  ESTABLISHED = 4,
-  FIN_WAIT_1  = 5,
-  FIN_WAIT_2  = 6,
-  CLOSE_WAIT  = 7,
-  CLOSING     = 8,
-  LAST_ACK    = 9,
-  TIME_WAIT   = 10
-};
-
-/* the TCP protocol control block */
-struct tcp_pcb {
-/** common PCB members */
-  IP_PCB;
-/** protocol specific PCB members */
-  struct tcp_pcb *next; /* for the linked list */
-  enum tcp_state state; /* TCP state */
-  u8_t prio;
-  void *callback_arg;
-
-  u16_t local_port;
-  u16_t remote_port;
-  
-  u8_t flags;
-#define TF_ACK_DELAY (u8_t)0x01U   /* Delayed ACK. */
-#define TF_ACK_NOW   (u8_t)0x02U   /* Immediate ACK. */
-#define TF_INFR      (u8_t)0x04U   /* In fast recovery. */
-#define TF_RESET     (u8_t)0x08U   /* Connection was reset. */
-#define TF_CLOSED    (u8_t)0x10U   /* Connection was sucessfully closed. */
-#define TF_GOT_FIN   (u8_t)0x20U   /* Connection was closed by the remote end. */
-#define TF_NODELAY   (u8_t)0x40U   /* Disable Nagle algorithm */
-
-  /* receiver variables */
-  u32_t rcv_nxt;   /* next seqno expected */
-  u16_t rcv_wnd;   /* receiver window */
-  
-  /* Timers */
-  u32_t tmr;
-  u8_t polltmr, pollinterval;
-  
-  /* Retransmission timer. */
-  u16_t rtime;
-  
-  u16_t mss;   /* maximum segment size */
-  
-  /* RTT (round trip time) estimation variables */
-  u32_t rttest; /* RTT estimate in 500ms ticks */
-  u32_t rtseq;  /* sequence number being timed */
-  s16_t sa, sv; /* @todo document this */
-
-  u16_t rto;    /* retransmission time-out */
-  u8_t nrtx;    /* number of retransmissions */
-
-  /* fast retransmit/recovery */
-  u32_t lastack; /* Highest acknowledged seqno. */
-  u8_t dupacks;
-  
-  /* congestion avoidance/control variables */
-  u16_t cwnd;  
-  u16_t ssthresh;
-
-  /* sender variables */
-  u32_t snd_nxt,       /* next seqno to be sent */
-    snd_max,       /* Highest seqno sent. */
-    snd_wnd,       /* sender window */
-    snd_wl1, snd_wl2, /* Sequence and acknowledgement numbers of last
-       window update. */
-    snd_lbb;       /* Sequence number of next byte to be buffered. */
-
-  u16_t acked;
-  
-  u16_t snd_buf;   /* Available buffer space for sending (in bytes). */
-  u8_t snd_queuelen; /* Available buffer space for sending (in tcp_segs). */
-  
-  
-  /* These are ordered by sequence number: */
-  struct tcp_seg *unsent;   /* Unsent (queued) segments. */
-  struct tcp_seg *unacked;  /* Sent but unacknowledged segments. */
-#if TCP_QUEUE_OOSEQ  
-  struct tcp_seg *ooseq;    /* Received out of sequence segments. */
-#endif /* TCP_QUEUE_OOSEQ */
-
-#if LWIP_CALLBACK_API
-  /* Function to be called when more send buffer space is available. */
-  err_t (* sent)(void *arg, struct tcp_pcb *pcb, u16_t space);
-  
-  /* Function to be called when (in-sequence) data has arrived. */
-  err_t (* recv)(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err);
-
-  /* Function to be called when a connection has been set up. */
-  err_t (* connected)(void *arg, struct tcp_pcb *pcb, err_t err);
-
-  /* Function to call when a listener has been connected. */
-  err_t (* accept)(void *arg, struct tcp_pcb *newpcb, err_t err);
-
-  /* Function which is called periodically. */
-  err_t (* poll)(void *arg, struct tcp_pcb *pcb);
-
-  /* Function to be called whenever a fatal error occurs. */
-  void (* errf)(void *arg, err_t err);
-#endif /* LWIP_CALLBACK_API */
-
-  /* idle time before KEEPALIVE is sent */
-  u32_t keepalive;
-  
-  /* KEEPALIVE counter */
-  u8_t keep_cnt;
-};
-
-struct tcp_pcb_listen {  
-/* Common members of all PCB types */
-  IP_PCB;
-
-/* Protocol specific PCB members */
-  struct tcp_pcb_listen *next;   /* for the linked list */
-  
-  /* Even if state is obviously LISTEN this is here for
-   * field compatibility with tpc_pcb to which it is cast sometimes
-   * Until a cleaner solution emerges this is here.FIXME
-   */ 
-  enum tcp_state state;   /* TCP state */
-
-  u8_t prio;
-  void *callback_arg;
-  
-  u16_t local_port; 
-
-#if LWIP_CALLBACK_API
-  /* Function to call when a listener has been connected. */
-  err_t (* accept)(void *arg, struct tcp_pcb *newpcb, err_t err);
-#endif /* LWIP_CALLBACK_API */
-};
-
-#if LWIP_EVENT_API
-
-enum lwip_event {
-  LWIP_EVENT_ACCEPT,
-  LWIP_EVENT_SENT,
-  LWIP_EVENT_RECV,
-  LWIP_EVENT_CONNECTED,
-  LWIP_EVENT_POLL,
-  LWIP_EVENT_ERR
-};
-
-err_t lwip_tcp_event(void *arg, struct tcp_pcb *pcb,
-         enum lwip_event,
-         struct pbuf *p,
-         u16_t size,
-         err_t err);
-
-#define TCP_EVENT_ACCEPT(pcb,err,ret)    ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\
-                LWIP_EVENT_ACCEPT, NULL, 0, err)
-#define TCP_EVENT_SENT(pcb,space,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\
-                   LWIP_EVENT_SENT, NULL, space, ERR_OK)
-#define TCP_EVENT_RECV(pcb,p,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\
-                LWIP_EVENT_RECV, (p), 0, (err))
-#define TCP_EVENT_CONNECTED(pcb,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\
-                LWIP_EVENT_CONNECTED, NULL, 0, (err))
-#define TCP_EVENT_POLL(pcb,ret)       ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\
-                LWIP_EVENT_POLL, NULL, 0, ERR_OK)
-#define TCP_EVENT_ERR(errf,arg,err)  lwip_tcp_event((arg), NULL, \
-                LWIP_EVENT_ERR, NULL, 0, (err))
-#else /* LWIP_EVENT_API */
-#define TCP_EVENT_ACCEPT(pcb,err,ret)     \
-                        if((pcb)->accept != NULL) \
-                        (ret = (pcb)->accept((pcb)->callback_arg,(pcb),(err)))
-#define TCP_EVENT_SENT(pcb,space,ret) \
-                        if((pcb)->sent != NULL) \
-                        (ret = (pcb)->sent((pcb)->callback_arg,(pcb),(space)))
-#define TCP_EVENT_RECV(pcb,p,err,ret) \
-                        if((pcb)->recv != NULL) \
-                        { ret = (pcb)->recv((pcb)->callback_arg,(pcb),(p),(err)); } else { \
-                          if (p) pbuf_free(p); }
-#define TCP_EVENT_CONNECTED(pcb,err,ret) \
-                        if((pcb)->connected != NULL) \
-                        (ret = (pcb)->connected((pcb)->callback_arg,(pcb),(err)))
-#define TCP_EVENT_POLL(pcb,ret) \
-                        if((pcb)->poll != NULL) \
-                        (ret = (pcb)->poll((pcb)->callback_arg,(pcb)))
-#define TCP_EVENT_ERR(errf,arg,err) \
-                        if((errf) != NULL) \
-                        (errf)((arg),(err))
-#endif /* LWIP_EVENT_API */
-
-/* This structure represents a TCP segment on the unsent and unacked queues */
-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 */
-  struct tcp_hdr *tcphdr;  /* the TCP header */
-};
-
-/* Internal functions and global variables: */
-struct tcp_pcb *tcp_pcb_copy(struct tcp_pcb *pcb);
-void tcp_pcb_purge(struct tcp_pcb *pcb);
-void tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb);
-
-u8_t tcp_segs_free(struct tcp_seg *seg);
-u8_t tcp_seg_free(struct tcp_seg *seg);
-struct tcp_seg *tcp_seg_copy(struct tcp_seg *seg);
-
-#define tcp_ack(pcb)     if((pcb)->flags & TF_ACK_DELAY) { \
-                            (pcb)->flags &= ~TF_ACK_DELAY; \
-                            (pcb)->flags |= TF_ACK_NOW; \
-                            tcp_output(pcb); \
-                         } else { \
-                            (pcb)->flags |= TF_ACK_DELAY; \
-                         }
-
-#define tcp_ack_now(pcb) (pcb)->flags |= TF_ACK_NOW; \
-                         tcp_output(pcb)
-
-err_t tcp_send_ctrl(struct tcp_pcb *pcb, u8_t flags);
-err_t tcp_enqueue(struct tcp_pcb *pcb, void *dataptr, u16_t len,
-    u8_t flags, u8_t copy,
-                u8_t *optdata, u8_t optlen);
-
-void tcp_rexmit_seg(struct tcp_pcb *pcb, struct tcp_seg *seg);
-
-void tcp_rst(u32_t seqno, u32_t ackno,
-       struct ip_addr *local_ip, struct ip_addr *remote_ip,
-       u16_t local_port, u16_t remote_port);
-
-u32_t tcp_next_iss(void);
-
-void tcp_keepalive(struct tcp_pcb *pcb);
-
-extern struct tcp_pcb *tcp_input_pcb;
-extern u32_t tcp_ticks;
-
-#if TCP_DEBUG || TCP_INPUT_DEBUG || TCP_OUTPUT_DEBUG
-void tcp_debug_print(struct tcp_hdr *tcphdr);
-void tcp_debug_print_flags(u8_t flags);
-void tcp_debug_print_state(enum tcp_state s);
-void tcp_debug_print_pcbs(void);
-int tcp_pcbs_sane(void);
-#else
-#  define tcp_debug_print(tcphdr)
-#  define tcp_debug_print_flags(flags)
-#  define tcp_debug_print_state(s)
-#  define tcp_debug_print_pcbs()
-#  define tcp_pcbs_sane() 1
-#endif /* TCP_DEBUG */
-
-#if NO_SYS
-#define tcp_timer_needed()
-#else
-void tcp_timer_needed(void);
-#endif
-
-/* The TCP PCB lists. */
-union tcp_listen_pcbs_t { /* List of all TCP PCBs in LISTEN state. */
-       struct tcp_pcb_listen *listen_pcbs; 
-       struct tcp_pcb *pcbs;
-};
-extern union tcp_listen_pcbs_t tcp_listen_pcbs;
-extern struct tcp_pcb *tcp_active_pcbs;  /* List of all TCP PCBs that are in a
-              state in which they accept or send
-              data. */
-extern struct tcp_pcb *tcp_tw_pcbs;      /* List of all TCP PCBs in TIME-WAIT. */
-
-extern struct tcp_pcb *tcp_tmp_pcb;      /* Only used for temporary storage. */
-
-/* Axioms about the above lists:   
-   1) Every TCP PCB that is not CLOSED is in one of the lists.
-   2) A PCB is only in one of the lists.
-   3) All PCBs in the tcp_listen_pcbs list is in LISTEN state.
-   4) All PCBs in the tcp_tw_pcbs list is in TIME-WAIT state.
-*/
-
-/* Define two macros, TCP_REG and TCP_RMV that registers a TCP PCB
-   with a PCB list or removes a PCB from a list, respectively. */
-#if 0
-#define TCP_REG(pcbs, npcb) do {\
-                            LWIP_DEBUGF(TCP_DEBUG, ("TCP_REG %p local port %d\n", npcb, npcb->local_port)); \
-                            for(tcp_tmp_pcb = *pcbs; \
-          tcp_tmp_pcb != NULL; \
-        tcp_tmp_pcb = tcp_tmp_pcb->next) { \
-                                LWIP_ASSERT("TCP_REG: already registered\n", tcp_tmp_pcb != npcb); \
-                            } \
-                            LWIP_ASSERT("TCP_REG: pcb->state != CLOSED", npcb->state != CLOSED); \
-                            npcb->next = *pcbs; \
-                            LWIP_ASSERT("TCP_REG: npcb->next != npcb", npcb->next != npcb); \
-                            *(pcbs) = npcb; \
-                            LWIP_ASSERT("TCP_RMV: tcp_pcbs sane", tcp_pcbs_sane()); \
-              tcp_timer_needed(); \
-                            } while(0)
-#define TCP_RMV(pcbs, npcb) do { \
-                            LWIP_ASSERT("TCP_RMV: pcbs != NULL", *pcbs != NULL); \
-                            LWIP_DEBUGF(TCP_DEBUG, ("TCP_RMV: removing %p from %p\n", npcb, *pcbs)); \
-                            if(*pcbs == npcb) { \
-                               *pcbs = (*pcbs)->next; \
-                            } else for(tcp_tmp_pcb = *pcbs; tcp_tmp_pcb != NULL; tcp_tmp_pcb = tcp_tmp_pcb->next) { \
-                               if(tcp_tmp_pcb->next != NULL && tcp_tmp_pcb->next == npcb) { \
-                                  tcp_tmp_pcb->next = npcb->next; \
-                                  break; \
-                               } \
-                            } \
-                            npcb->next = NULL; \
-                            LWIP_ASSERT("TCP_RMV: tcp_pcbs sane", tcp_pcbs_sane()); \
-                            LWIP_DEBUGF(TCP_DEBUG, ("TCP_RMV: removed %p from %p\n", npcb, *pcbs)); \
-                            } while(0)
-
-#else /* LWIP_DEBUG */
-#define TCP_REG(pcbs, npcb) do { \
-                            npcb->next = *pcbs; \
-                            *(pcbs) = npcb; \
-              tcp_timer_needed(); \
-                            } while(0)
-#define TCP_RMV(pcbs, npcb) do { \
-                            if(*(pcbs) == npcb) { \
-                               (*(pcbs)) = (*pcbs)->next; \
-                            } else for(tcp_tmp_pcb = *pcbs; tcp_tmp_pcb != NULL; tcp_tmp_pcb = tcp_tmp_pcb->next) { \
-                               if(tcp_tmp_pcb->next != NULL && tcp_tmp_pcb->next == npcb) { \
-                                  tcp_tmp_pcb->next = npcb->next; \
-                                  break; \
-                               } \
-                            } \
-                            npcb->next = NULL; \
-                            } while(0)
-#endif /* LWIP_DEBUG */
-#endif /* __LWIP_TCP_H__ */
-
-
-
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+#ifndef __LWIP_TCP_H__\r
+#define __LWIP_TCP_H__\r
+\r
+#include "lwip/sys.h"\r
+#include "lwip/mem.h"\r
+\r
+#include "lwip/pbuf.h"\r
+#include "lwip/opt.h"\r
+#include "lwip/ip.h"\r
+#include "lwip/icmp.h"\r
+\r
+#include "lwip/err.h"\r
+\r
+struct tcp_pcb;\r
+\r
+/* Functions for interfacing with TCP: */\r
+\r
+/* Lower layer interface to TCP: */\r
+void             tcp_init    (void);  /* Must be called first to\r
+           initialize TCP. */\r
+void             tcp_tmr     (void);  /* Must be called every\r
+           TCP_TMR_INTERVAL\r
+           ms. (Typically 250 ms). */\r
+/* Application program's interface: */\r
+struct tcp_pcb * tcp_new     (void);\r
+struct tcp_pcb * tcp_alloc   (u8_t prio);\r
+\r
+void             tcp_arg     (struct tcp_pcb *pcb, void *arg);\r
+void             tcp_accept  (struct tcp_pcb *pcb,\r
+            err_t (* accept)(void *arg, struct tcp_pcb *newpcb,\r
+                 err_t err));\r
+void             tcp_recv    (struct tcp_pcb *pcb,\r
+            err_t (* recv)(void *arg, struct tcp_pcb *tpcb,\r
+          struct pbuf *p, err_t err));\r
+void             tcp_sent    (struct tcp_pcb *pcb,\r
+            err_t (* sent)(void *arg, struct tcp_pcb *tpcb,\r
+               u16_t len));\r
+void             tcp_poll    (struct tcp_pcb *pcb,\r
+            err_t (* poll)(void *arg, struct tcp_pcb *tpcb),\r
+            u8_t interval);\r
+void             tcp_err     (struct tcp_pcb *pcb,\r
+            void (* err)(void *arg, err_t err));\r
+\r
+#define          tcp_mss(pcb)      ((pcb)->mss)\r
+#define          tcp_sndbuf(pcb)   ((pcb)->snd_buf)\r
+\r
+void             tcp_recved  (struct tcp_pcb *pcb, u16_t len);\r
+err_t            tcp_bind    (struct tcp_pcb *pcb, struct ip_addr *ipaddr,\r
+            u16_t port);\r
+err_t            tcp_connect (struct tcp_pcb *pcb, struct ip_addr *ipaddr,\r
+            u16_t port, err_t (* connected)(void *arg,\r
+                    struct tcp_pcb *tpcb,\r
+                    err_t err));\r
+struct tcp_pcb * tcp_listen  (struct tcp_pcb *pcb);\r
+void             tcp_abort   (struct tcp_pcb *pcb);\r
+err_t            tcp_close   (struct tcp_pcb *pcb);\r
+err_t            tcp_write   (struct tcp_pcb *pcb, const void *dataptr, u16_t len,\r
+            u8_t copy);\r
+\r
+void             tcp_setprio (struct tcp_pcb *pcb, u8_t prio);\r
+\r
+#define TCP_PRIO_MIN    1\r
+#define TCP_PRIO_NORMAL 64\r
+#define TCP_PRIO_MAX    127\r
+\r
+/* It is also possible to call these two functions at the right\r
+   intervals (instead of calling tcp_tmr()). */\r
+void             tcp_slowtmr (void);\r
+void             tcp_fasttmr (void);\r
+\r
+\r
+/* Only used by IP to pass a TCP segment to TCP: */\r
+void             tcp_input   (struct pbuf *p, struct netif *inp);\r
+/* Used within the TCP code only: */\r
+err_t            tcp_output  (struct tcp_pcb *pcb);\r
+void             tcp_rexmit  (struct tcp_pcb *pcb);\r
+void             tcp_rexmit_rto  (struct tcp_pcb *pcb);\r
+\r
+\r
+\r
+#define TCP_SEQ_LT(a,b)     ((s32_t)((a)-(b)) < 0)\r
+#define TCP_SEQ_LEQ(a,b)    ((s32_t)((a)-(b)) <= 0)\r
+#define TCP_SEQ_GT(a,b)     ((s32_t)((a)-(b)) > 0)\r
+#define TCP_SEQ_GEQ(a,b)    ((s32_t)((a)-(b)) >= 0)\r
+/* is b<=a<=c? */\r
+#if 0 /* see bug #10548 */\r
+#define TCP_SEQ_BETWEEN(a,b,c) ((c)-(b) >= (a)-(b))\r
+#endif\r
+#define TCP_SEQ_BETWEEN(a,b,c) (TCP_SEQ_GEQ(a,b) && TCP_SEQ_LEQ(a,c))\r
+#define TCP_FIN 0x01U\r
+#define TCP_SYN 0x02U\r
+#define TCP_RST 0x04U\r
+#define TCP_PSH 0x08U\r
+#define TCP_ACK 0x10U\r
+#define TCP_URG 0x20U\r
+#define TCP_ECE 0x40U\r
+#define TCP_CWR 0x80U\r
+\r
+#define TCP_FLAGS 0x3fU\r
+\r
+/* Length of the TCP header, excluding options. */\r
+#define TCP_HLEN 20\r
+\r
+#ifndef TCP_TMR_INTERVAL\r
+#define TCP_TMR_INTERVAL       250  /* The TCP timer interval in\r
+                                       milliseconds. */\r
+#endif /* TCP_TMR_INTERVAL */\r
+\r
+#ifndef TCP_FAST_INTERVAL\r
+#define TCP_FAST_INTERVAL      TCP_TMR_INTERVAL /* the fine grained timeout in\r
+                                       milliseconds */\r
+#endif /* TCP_FAST_INTERVAL */\r
+\r
+#ifndef TCP_SLOW_INTERVAL\r
+#define TCP_SLOW_INTERVAL      (2*TCP_TMR_INTERVAL)  /* the coarse grained timeout in\r
+                                       milliseconds */\r
+#endif /* TCP_SLOW_INTERVAL */\r
+\r
+#define TCP_FIN_WAIT_TIMEOUT 20000 /* milliseconds */\r
+#define TCP_SYN_RCVD_TIMEOUT 20000 /* milliseconds */\r
+\r
+#define TCP_OOSEQ_TIMEOUT        6 /* x RTO */\r
+\r
+#define TCP_MSL 60000  /* The maximum segment lifetime in microseconds */\r
+\r
+/*\r
+ * User-settable options (used with setsockopt).\r
+ */\r
+#define        TCP_NODELAY        0x01    /* don't delay send to coalesce packets */\r
+#define TCP_KEEPALIVE  0x02    /* send KEEPALIVE probes when idle for pcb->keepalive miliseconds */\r
+\r
+/* Keepalive values */\r
+#define  TCP_KEEPDEFAULT   7200000                       /* KEEPALIVE timer in miliseconds */\r
+#define  TCP_KEEPINTVL     75000                         /* Time between KEEPALIVE probes in miliseconds */\r
+#define  TCP_KEEPCNT       9                             /* Counter for KEEPALIVE probes */\r
+#define  TCP_MAXIDLE       TCP_KEEPCNT * TCP_KEEPINTVL   /* Maximum KEEPALIVE probe time */\r
+\r
+\r
+#ifdef PACK_STRUCT_USE_INCLUDES\r
+#  include "arch/bpstruct.h"\r
+#endif\r
+PACK_STRUCT_BEGIN\r
+struct tcp_hdr {\r
+  PACK_STRUCT_FIELD(u16_t src);\r
+  PACK_STRUCT_FIELD(u16_t dest);\r
+  PACK_STRUCT_FIELD(u32_t seqno);\r
+  PACK_STRUCT_FIELD(u32_t ackno);\r
+  PACK_STRUCT_FIELD(u16_t _hdrlen_rsvd_flags);\r
+  PACK_STRUCT_FIELD(u16_t wnd);\r
+  PACK_STRUCT_FIELD(u16_t chksum);\r
+  PACK_STRUCT_FIELD(u16_t urgp);\r
+} PACK_STRUCT_STRUCT;\r
+PACK_STRUCT_END\r
+#ifdef PACK_STRUCT_USE_INCLUDES\r
+#  include "arch/epstruct.h"\r
+#endif\r
+\r
+#define TCPH_OFFSET(phdr) (ntohs((phdr)->_hdrlen_rsvd_flags) >> 8)\r
+#define TCPH_HDRLEN(phdr) (ntohs((phdr)->_hdrlen_rsvd_flags) >> 12)\r
+#define TCPH_FLAGS(phdr)  (ntohs((phdr)->_hdrlen_rsvd_flags) & TCP_FLAGS)\r
+\r
+#define TCPH_OFFSET_SET(phdr, offset) (phdr)->_hdrlen_rsvd_flags = htons(((offset) << 8) | TCPH_FLAGS(phdr))\r
+#define TCPH_HDRLEN_SET(phdr, len) (phdr)->_hdrlen_rsvd_flags = htons(((len) << 12) | TCPH_FLAGS(phdr))\r
+#define TCPH_FLAGS_SET(phdr, flags) (phdr)->_hdrlen_rsvd_flags = htons((ntohs((phdr)->_hdrlen_rsvd_flags) & ~TCP_FLAGS) | (flags))\r
+#define TCPH_SET_FLAG(phdr, flags ) (phdr)->_hdrlen_rsvd_flags = htons(ntohs((phdr)->_hdrlen_rsvd_flags) | (flags))\r
+#define TCPH_UNSET_FLAG(phdr, flags) (phdr)->_hdrlen_rsvd_flags = htons(ntohs((phdr)->_hdrlen_rsvd_flags) | (TCPH_FLAGS(phdr) & ~(flags)) )\r
+\r
+#define TCP_TCPLEN(seg) ((seg)->len + ((TCPH_FLAGS((seg)->tcphdr) & TCP_FIN || \\r
+          TCPH_FLAGS((seg)->tcphdr) & TCP_SYN)? 1: 0))\r
+\r
+enum tcp_state {\r
+  CLOSED      = 0,\r
+  LISTEN      = 1,\r
+  SYN_SENT    = 2,\r
+  SYN_RCVD    = 3,\r
+  ESTABLISHED = 4,\r
+  FIN_WAIT_1  = 5,\r
+  FIN_WAIT_2  = 6,\r
+  CLOSE_WAIT  = 7,\r
+  CLOSING     = 8,\r
+  LAST_ACK    = 9,\r
+  TIME_WAIT   = 10\r
+};\r
+\r
+/* the TCP protocol control block */\r
+struct tcp_pcb {\r
+/** common PCB members */\r
+  IP_PCB;\r
+/** protocol specific PCB members */\r
+  struct tcp_pcb *next; /* for the linked list */\r
+  enum tcp_state state; /* TCP state */\r
+  u8_t prio;\r
+  void *callback_arg;\r
+\r
+  u16_t local_port;\r
+  u16_t remote_port;\r
+  \r
+  u8_t flags;\r
+#define TF_ACK_DELAY (u8_t)0x01U   /* Delayed ACK. */\r
+#define TF_ACK_NOW   (u8_t)0x02U   /* Immediate ACK. */\r
+#define TF_INFR      (u8_t)0x04U   /* In fast recovery. */\r
+#define TF_RESET     (u8_t)0x08U   /* Connection was reset. */\r
+#define TF_CLOSED    (u8_t)0x10U   /* Connection was sucessfully closed. */\r
+#define TF_GOT_FIN   (u8_t)0x20U   /* Connection was closed by the remote end. */\r
+#define TF_NODELAY   (u8_t)0x40U   /* Disable Nagle algorithm */\r
+\r
+  /* receiver variables */\r
+  u32_t rcv_nxt;   /* next seqno expected */\r
+  u16_t rcv_wnd;   /* receiver window */\r
+  \r
+  /* Timers */\r
+  u32_t tmr;\r
+  u8_t polltmr, pollinterval;\r
+  \r
+  /* Retransmission timer. */\r
+  u16_t rtime;\r
+  \r
+  u16_t mss;   /* maximum segment size */\r
+  \r
+  /* RTT (round trip time) estimation variables */\r
+  u32_t rttest; /* RTT estimate in 500ms ticks */\r
+  u32_t rtseq;  /* sequence number being timed */\r
+  s16_t sa, sv; /* @todo document this */\r
+\r
+  u16_t rto;    /* retransmission time-out */\r
+  u8_t nrtx;    /* number of retransmissions */\r
+\r
+  /* fast retransmit/recovery */\r
+  u32_t lastack; /* Highest acknowledged seqno. */\r
+  u8_t dupacks;\r
+  \r
+  /* congestion avoidance/control variables */\r
+  u16_t cwnd;  \r
+  u16_t ssthresh;\r
+\r
+  /* sender variables */\r
+  u32_t snd_nxt,       /* next seqno to be sent */\r
+    snd_max,       /* Highest seqno sent. */\r
+    snd_wnd,       /* sender window */\r
+    snd_wl1, snd_wl2, /* Sequence and acknowledgement numbers of last\r
+       window update. */\r
+    snd_lbb;       /* Sequence number of next byte to be buffered. */\r
+\r
+  u16_t acked;\r
+  \r
+  u16_t snd_buf;   /* Available buffer space for sending (in bytes). */\r
+  u8_t snd_queuelen; /* Available buffer space for sending (in tcp_segs). */\r
+  \r
+  \r
+  /* These are ordered by sequence number: */\r
+  struct tcp_seg *unsent;   /* Unsent (queued) segments. */\r
+  struct tcp_seg *unacked;  /* Sent but unacknowledged segments. */\r
+#if TCP_QUEUE_OOSEQ  \r
+  struct tcp_seg *ooseq;    /* Received out of sequence segments. */\r
+#endif /* TCP_QUEUE_OOSEQ */\r
+\r
+#if LWIP_CALLBACK_API\r
+  /* Function to be called when more send buffer space is available. */\r
+  err_t (* sent)(void *arg, struct tcp_pcb *pcb, u16_t space);\r
+  \r
+  /* Function to be called when (in-sequence) data has arrived. */\r
+  err_t (* recv)(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err);\r
+\r
+  /* Function to be called when a connection has been set up. */\r
+  err_t (* connected)(void *arg, struct tcp_pcb *pcb, err_t err);\r
+\r
+  /* Function to call when a listener has been connected. */\r
+  err_t (* accept)(void *arg, struct tcp_pcb *newpcb, err_t err);\r
+\r
+  /* Function which is called periodically. */\r
+  err_t (* poll)(void *arg, struct tcp_pcb *pcb);\r
+\r
+  /* Function to be called whenever a fatal error occurs. */\r
+  void (* errf)(void *arg, err_t err);\r
+#endif /* LWIP_CALLBACK_API */\r
+\r
+  /* idle time before KEEPALIVE is sent */\r
+  u32_t keepalive;\r
+  \r
+  /* KEEPALIVE counter */\r
+  u8_t keep_cnt;\r
+};\r
+\r
+struct tcp_pcb_listen {  \r
+/* Common members of all PCB types */\r
+  IP_PCB;\r
+\r
+/* Protocol specific PCB members */\r
+  struct tcp_pcb_listen *next;   /* for the linked list */\r
+  \r
+  /* Even if state is obviously LISTEN this is here for\r
+   * field compatibility with tpc_pcb to which it is cast sometimes\r
+   * Until a cleaner solution emerges this is here.FIXME\r
+   */ \r
+  enum tcp_state state;   /* TCP state */\r
+\r
+  u8_t prio;\r
+  void *callback_arg;\r
+  \r
+  u16_t local_port; \r
+\r
+#if LWIP_CALLBACK_API\r
+  /* Function to call when a listener has been connected. */\r
+  err_t (* accept)(void *arg, struct tcp_pcb *newpcb, err_t err);\r
+#endif /* LWIP_CALLBACK_API */\r
+};\r
+\r
+#if LWIP_EVENT_API\r
+\r
+enum lwip_event {\r
+  LWIP_EVENT_ACCEPT,\r
+  LWIP_EVENT_SENT,\r
+  LWIP_EVENT_RECV,\r
+  LWIP_EVENT_CONNECTED,\r
+  LWIP_EVENT_POLL,\r
+  LWIP_EVENT_ERR\r
+};\r
+\r
+err_t lwip_tcp_event(void *arg, struct tcp_pcb *pcb,\r
+         enum lwip_event,\r
+         struct pbuf *p,\r
+         u16_t size,\r
+         err_t err);\r
+\r
+#define TCP_EVENT_ACCEPT(pcb,err,ret)    ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\\r
+                LWIP_EVENT_ACCEPT, NULL, 0, err)\r
+#define TCP_EVENT_SENT(pcb,space,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\\r
+                   LWIP_EVENT_SENT, NULL, space, ERR_OK)\r
+#define TCP_EVENT_RECV(pcb,p,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\\r
+                LWIP_EVENT_RECV, (p), 0, (err))\r
+#define TCP_EVENT_CONNECTED(pcb,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\\r
+                LWIP_EVENT_CONNECTED, NULL, 0, (err))\r
+#define TCP_EVENT_POLL(pcb,ret)       ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\\r
+                LWIP_EVENT_POLL, NULL, 0, ERR_OK)\r
+#define TCP_EVENT_ERR(errf,arg,err)  lwip_tcp_event((arg), NULL, \\r
+                LWIP_EVENT_ERR, NULL, 0, (err))\r
+#else /* LWIP_EVENT_API */\r
+#define TCP_EVENT_ACCEPT(pcb,err,ret)     \\r
+                        if((pcb)->accept != NULL) \\r
+                        (ret = (pcb)->accept((pcb)->callback_arg,(pcb),(err)))\r
+#define TCP_EVENT_SENT(pcb,space,ret) \\r
+                        if((pcb)->sent != NULL) \\r
+                        (ret = (pcb)->sent((pcb)->callback_arg,(pcb),(space)))\r
+#define TCP_EVENT_RECV(pcb,p,err,ret) \\r
+                        if((pcb)->recv != NULL) \\r
+                        { ret = (pcb)->recv((pcb)->callback_arg,(pcb),(p),(err)); } else { \\r
+                          if (p) pbuf_free(p); }\r
+#define TCP_EVENT_CONNECTED(pcb,err,ret) \\r
+                        if((pcb)->connected != NULL) \\r
+                        (ret = (pcb)->connected((pcb)->callback_arg,(pcb),(err)))\r
+#define TCP_EVENT_POLL(pcb,ret) \\r
+                        if((pcb)->poll != NULL) \\r
+                        (ret = (pcb)->poll((pcb)->callback_arg,(pcb)))\r
+#define TCP_EVENT_ERR(errf,arg,err) \\r
+                        if((errf) != NULL) \\r
+                        (errf)((arg),(err))\r
+#endif /* LWIP_EVENT_API */\r
+\r
+/* This structure represents a TCP segment on the unsent and unacked queues */\r
+struct tcp_seg {\r
+  struct tcp_seg *next;    /* used when putting segements on a queue */\r
+  struct pbuf *p;          /* buffer containing data + TCP header */\r
+  void *dataptr;           /* pointer to the TCP data in the pbuf */\r
+  u16_t len;               /* the TCP length of this segment */\r
+  struct tcp_hdr *tcphdr;  /* the TCP header */\r
+};\r
+\r
+/* Internal functions and global variables: */\r
+struct tcp_pcb *tcp_pcb_copy(struct tcp_pcb *pcb);\r
+void tcp_pcb_purge(struct tcp_pcb *pcb);\r
+void tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb);\r
+\r
+u8_t tcp_segs_free(struct tcp_seg *seg);\r
+u8_t tcp_seg_free(struct tcp_seg *seg);\r
+struct tcp_seg *tcp_seg_copy(struct tcp_seg *seg);\r
+\r
+#define tcp_ack(pcb)     if((pcb)->flags & TF_ACK_DELAY) { \\r
+                            (pcb)->flags &= ~TF_ACK_DELAY; \\r
+                            (pcb)->flags |= TF_ACK_NOW; \\r
+                            tcp_output(pcb); \\r
+                         } else { \\r
+                            (pcb)->flags |= TF_ACK_DELAY; \\r
+                         }\r
+\r
+#define tcp_ack_now(pcb) (pcb)->flags |= TF_ACK_NOW; \\r
+                         tcp_output(pcb)\r
+\r
+err_t tcp_send_ctrl(struct tcp_pcb *pcb, u8_t flags);\r
+err_t tcp_enqueue(struct tcp_pcb *pcb, void *dataptr, u16_t len,\r
+    u8_t flags, u8_t copy,\r
+                u8_t *optdata, u8_t optlen);\r
+\r
+void tcp_rexmit_seg(struct tcp_pcb *pcb, struct tcp_seg *seg);\r
+\r
+void tcp_rst(u32_t seqno, u32_t ackno,\r
+       struct ip_addr *local_ip, struct ip_addr *remote_ip,\r
+       u16_t local_port, u16_t remote_port);\r
+\r
+u32_t tcp_next_iss(void);\r
+\r
+void tcp_keepalive(struct tcp_pcb *pcb);\r
+\r
+extern struct tcp_pcb *tcp_input_pcb;\r
+extern u32_t tcp_ticks;\r
+\r
+#if TCP_DEBUG || TCP_INPUT_DEBUG || TCP_OUTPUT_DEBUG\r
+void tcp_debug_print(struct tcp_hdr *tcphdr);\r
+void tcp_debug_print_flags(u8_t flags);\r
+void tcp_debug_print_state(enum tcp_state s);\r
+void tcp_debug_print_pcbs(void);\r
+int tcp_pcbs_sane(void);\r
+#else\r
+#  define tcp_debug_print(tcphdr)\r
+#  define tcp_debug_print_flags(flags)\r
+#  define tcp_debug_print_state(s)\r
+#  define tcp_debug_print_pcbs()\r
+#  define tcp_pcbs_sane() 1\r
+#endif /* TCP_DEBUG */\r
+\r
+#if NO_SYS\r
+#define tcp_timer_needed()\r
+#else\r
+void tcp_timer_needed(void);\r
+#endif\r
+\r
+/* The TCP PCB lists. */\r
+union tcp_listen_pcbs_t { /* List of all TCP PCBs in LISTEN state. */\r
+       struct tcp_pcb_listen *listen_pcbs; \r
+       struct tcp_pcb *pcbs;\r
+};\r
+extern union tcp_listen_pcbs_t tcp_listen_pcbs;\r
+extern struct tcp_pcb *tcp_active_pcbs;  /* List of all TCP PCBs that are in a\r
+              state in which they accept or send\r
+              data. */\r
+extern struct tcp_pcb *tcp_tw_pcbs;      /* List of all TCP PCBs in TIME-WAIT. */\r
+\r
+extern struct tcp_pcb *tcp_tmp_pcb;      /* Only used for temporary storage. */\r
+\r
+/* Axioms about the above lists:   \r
+   1) Every TCP PCB that is not CLOSED is in one of the lists.\r
+   2) A PCB is only in one of the lists.\r
+   3) All PCBs in the tcp_listen_pcbs list is in LISTEN state.\r
+   4) All PCBs in the tcp_tw_pcbs list is in TIME-WAIT state.\r
+*/\r
+\r
+/* Define two macros, TCP_REG and TCP_RMV that registers a TCP PCB\r
+   with a PCB list or removes a PCB from a list, respectively. */\r
+#if 0\r
+#define TCP_REG(pcbs, npcb) do {\\r
+                            LWIP_DEBUGF(TCP_DEBUG, ("TCP_REG %p local port %d\n", npcb, npcb->local_port)); \\r
+                            for(tcp_tmp_pcb = *pcbs; \\r
+          tcp_tmp_pcb != NULL; \\r
+        tcp_tmp_pcb = tcp_tmp_pcb->next) { \\r
+                                LWIP_ASSERT("TCP_REG: already registered\n", tcp_tmp_pcb != npcb); \\r
+                            } \\r
+                            LWIP_ASSERT("TCP_REG: pcb->state != CLOSED", npcb->state != CLOSED); \\r
+                            npcb->next = *pcbs; \\r
+                            LWIP_ASSERT("TCP_REG: npcb->next != npcb", npcb->next != npcb); \\r
+                            *(pcbs) = npcb; \\r
+                            LWIP_ASSERT("TCP_RMV: tcp_pcbs sane", tcp_pcbs_sane()); \\r
+              tcp_timer_needed(); \\r
+                            } while(0)\r
+#define TCP_RMV(pcbs, npcb) do { \\r
+                            LWIP_ASSERT("TCP_RMV: pcbs != NULL", *pcbs != NULL); \\r
+                            LWIP_DEBUGF(TCP_DEBUG, ("TCP_RMV: removing %p from %p\n", npcb, *pcbs)); \\r
+                            if(*pcbs == npcb) { \\r
+                               *pcbs = (*pcbs)->next; \\r
+                            } else for(tcp_tmp_pcb = *pcbs; tcp_tmp_pcb != NULL; tcp_tmp_pcb = tcp_tmp_pcb->next) { \\r
+                               if(tcp_tmp_pcb->next != NULL && tcp_tmp_pcb->next == npcb) { \\r
+                                  tcp_tmp_pcb->next = npcb->next; \\r
+                                  break; \\r
+                               } \\r
+                            } \\r
+                            npcb->next = NULL; \\r
+                            LWIP_ASSERT("TCP_RMV: tcp_pcbs sane", tcp_pcbs_sane()); \\r
+                            LWIP_DEBUGF(TCP_DEBUG, ("TCP_RMV: removed %p from %p\n", npcb, *pcbs)); \\r
+                            } while(0)\r
+\r
+#else /* LWIP_DEBUG */\r
+#define TCP_REG(pcbs, npcb) do { \\r
+                            npcb->next = *pcbs; \\r
+                            *(pcbs) = npcb; \\r
+              tcp_timer_needed(); \\r
+                            } while(0)\r
+#define TCP_RMV(pcbs, npcb) do { \\r
+                            if(*(pcbs) == npcb) { \\r
+                               (*(pcbs)) = (*pcbs)->next; \\r
+                            } else for(tcp_tmp_pcb = *pcbs; tcp_tmp_pcb != NULL; tcp_tmp_pcb = tcp_tmp_pcb->next) { \\r
+                               if(tcp_tmp_pcb->next != NULL && tcp_tmp_pcb->next == npcb) { \\r
+                                  tcp_tmp_pcb->next = npcb->next; \\r
+                                  break; \\r
+                               } \\r
+                            } \\r
+                            npcb->next = NULL; \\r
+                            } while(0)\r
+#endif /* LWIP_DEBUG */\r
+#endif /* __LWIP_TCP_H__ */\r
+\r
+\r
+\r
index 316ae4fc53659bed05a6696fe31c7fb94cab8de7..242664ef71aadce7fc2cca9f23129ad30d17d134 100644 (file)
@@ -1,68 +1,68 @@
-/*
- * 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 <adam@sics.se>
- *
- */
-#ifndef __LWIP_TCPIP_H__
-#define __LWIP_TCPIP_H__
-
-#include "lwip/api_msg.h"
-#include "lwip/pbuf.h"
-
-void tcpip_init(void (* tcpip_init_done)(void *), void *arg);
-void tcpip_apimsg(struct api_msg *apimsg);
-err_t tcpip_input(struct pbuf *p, struct netif *inp);
-err_t tcpip_callback(void (*f)(void *ctx), void *ctx);
-
-void tcpip_tcp_timer_needed(void);
-
-enum tcpip_msg_type {
-  TCPIP_MSG_API,
-  TCPIP_MSG_INPUT,
-  TCPIP_MSG_CALLBACK
-};
-
-struct tcpip_msg {
-  enum tcpip_msg_type type;
-  sys_sem_t *sem;
-  union {
-    struct api_msg *apimsg;
-    struct {
-      struct pbuf *p;
-      struct netif *netif;
-    } inp;
-    struct {
-      void (*f)(void *ctx);
-      void *ctx;
-    } cb;
-  } msg;
-};
-
-
-#endif /* __LWIP_TCPIP_H__ */
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+#ifndef __LWIP_TCPIP_H__\r
+#define __LWIP_TCPIP_H__\r
+\r
+#include "lwip/api_msg.h"\r
+#include "lwip/pbuf.h"\r
+\r
+void tcpip_init(void (* tcpip_init_done)(void *), void *arg);\r
+void tcpip_apimsg(struct api_msg *apimsg);\r
+err_t tcpip_input(struct pbuf *p, struct netif *inp);\r
+err_t tcpip_callback(void (*f)(void *ctx), void *ctx);\r
+\r
+void tcpip_tcp_timer_needed(void);\r
+\r
+enum tcpip_msg_type {\r
+  TCPIP_MSG_API,\r
+  TCPIP_MSG_INPUT,\r
+  TCPIP_MSG_CALLBACK\r
+};\r
+\r
+struct tcpip_msg {\r
+  enum tcpip_msg_type type;\r
+  sys_sem_t *sem;\r
+  union {\r
+    struct api_msg *apimsg;\r
+    struct {\r
+      struct pbuf *p;\r
+      struct netif *netif;\r
+    } inp;\r
+    struct {\r
+      void (*f)(void *ctx);\r
+      void *ctx;\r
+    } cb;\r
+  } msg;\r
+};\r
+\r
+\r
+#endif /* __LWIP_TCPIP_H__ */\r
index c54859476176a0e4b3687954caeac1cbc9397101..c9d7958d825397959d87c84e6a2e27804d1308d2 100644 (file)
-/*
- * 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 <adam@sics.se>
- *
- */
-#ifndef __LWIP_UDP_H__
-#define __LWIP_UDP_H__
-
-#include "lwip/arch.h"
-
-#include "lwip/pbuf.h"
-#include "lwip/inet.h"
-#include "lwip/ip.h"
-
-#define UDP_HLEN 8
-
-struct udp_hdr {
-  PACK_STRUCT_FIELD(u16_t src);
-  PACK_STRUCT_FIELD(u16_t dest);  /* src/dest UDP ports */
-  PACK_STRUCT_FIELD(u16_t len);
-  PACK_STRUCT_FIELD(u16_t chksum);
-} PACK_STRUCT_STRUCT;
-
-#define UDP_FLAGS_NOCHKSUM 0x01U
-#define UDP_FLAGS_UDPLITE  0x02U
-#define UDP_FLAGS_CONNECTED  0x04U
-
-struct udp_pcb {
-/* Common members of all PCB types */
-  IP_PCB;
-
-/* Protocol specific PCB members */
-
-  struct udp_pcb *next;
-
-  u8_t flags;
-  u16_t local_port, remote_port;
-  
-  u16_t chksum_len;
-  
-  void (* recv)(void *arg, struct udp_pcb *pcb, struct pbuf *p,
-    struct ip_addr *addr, u16_t port);
-  void *recv_arg;  
-};
-
-/* The following functions is the application layer interface to the
-   UDP code. */
-struct udp_pcb * udp_new        (void);
-void             udp_remove     (struct udp_pcb *pcb);
-err_t            udp_bind       (struct udp_pcb *pcb, struct ip_addr *ipaddr,
-                 u16_t port);
-err_t            udp_connect    (struct udp_pcb *pcb, struct ip_addr *ipaddr,
-                 u16_t port);
-void             udp_disconnect    (struct udp_pcb *pcb);
-void             udp_recv       (struct udp_pcb *pcb,
-         void (* recv)(void *arg, struct udp_pcb *upcb,
-                 struct pbuf *p,
-                 struct ip_addr *addr,
-                 u16_t port),
-         void *recv_arg);
-err_t            udp_sendto     (struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *dst_ip, u16_t dst_port);
-err_t            udp_send       (struct udp_pcb *pcb, struct pbuf *p);
-
-#define          udp_flags(pcb)  ((pcb)->flags)
-#define          udp_setflags(pcb, f)  ((pcb)->flags = (f))
-
-/* The following functions are the lower layer interface to UDP. */
-void             udp_input      (struct pbuf *p, struct netif *inp);
-void             udp_init       (void);
-
-#if UDP_DEBUG
-int udp_debug_print(struct udp_hdr *udphdr);
-#else
-#define udp_debug_print(udphdr)
-#endif
-#endif /* __LWIP_UDP_H__ */
-
-
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+#ifndef __LWIP_UDP_H__\r
+#define __LWIP_UDP_H__\r
+\r
+#include "lwip/arch.h"\r
+\r
+#include "lwip/pbuf.h"\r
+#include "lwip/inet.h"\r
+#include "lwip/ip.h"\r
+\r
+#define UDP_HLEN 8\r
+\r
+struct udp_hdr {\r
+  PACK_STRUCT_FIELD(u16_t src);\r
+  PACK_STRUCT_FIELD(u16_t dest);  /* src/dest UDP ports */\r
+  PACK_STRUCT_FIELD(u16_t len);\r
+  PACK_STRUCT_FIELD(u16_t chksum);\r
+} PACK_STRUCT_STRUCT;\r
+\r
+#define UDP_FLAGS_NOCHKSUM 0x01U\r
+#define UDP_FLAGS_UDPLITE  0x02U\r
+#define UDP_FLAGS_CONNECTED  0x04U\r
+\r
+struct udp_pcb {\r
+/* Common members of all PCB types */\r
+  IP_PCB;\r
+\r
+/* Protocol specific PCB members */\r
+\r
+  struct udp_pcb *next;\r
+\r
+  u8_t flags;\r
+  u16_t local_port, remote_port;\r
+  \r
+  u16_t chksum_len;\r
+  \r
+  void (* recv)(void *arg, struct udp_pcb *pcb, struct pbuf *p,\r
+    struct ip_addr *addr, u16_t port);\r
+  void *recv_arg;  \r
+};\r
+\r
+/* The following functions is the application layer interface to the\r
+   UDP code. */\r
+struct udp_pcb * udp_new        (void);\r
+void             udp_remove     (struct udp_pcb *pcb);\r
+err_t            udp_bind       (struct udp_pcb *pcb, struct ip_addr *ipaddr,\r
+                 u16_t port);\r
+err_t            udp_connect    (struct udp_pcb *pcb, struct ip_addr *ipaddr,\r
+                 u16_t port);\r
+void             udp_disconnect    (struct udp_pcb *pcb);\r
+void             udp_recv       (struct udp_pcb *pcb,\r
+         void (* recv)(void *arg, struct udp_pcb *upcb,\r
+                 struct pbuf *p,\r
+                 struct ip_addr *addr,\r
+                 u16_t port),\r
+         void *recv_arg);\r
+err_t            udp_sendto     (struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *dst_ip, u16_t dst_port);\r
+err_t            udp_send       (struct udp_pcb *pcb, struct pbuf *p);\r
+\r
+#define          udp_flags(pcb)  ((pcb)->flags)\r
+#define          udp_setflags(pcb, f)  ((pcb)->flags = (f))\r
+\r
+/* The following functions are the lower layer interface to UDP. */\r
+void             udp_input      (struct pbuf *p, struct netif *inp);\r
+void             udp_init       (void);\r
+\r
+#if UDP_DEBUG\r
+int udp_debug_print(struct udp_hdr *udphdr);\r
+#else\r
+#define udp_debug_print(udphdr)\r
+#endif\r
+#endif /* __LWIP_UDP_H__ */\r
+\r
+\r
index 08437afe54995310a43d20ba51bf2908dd365ec6..26fa3effb0613e94527f78624418dc14ee8367e8 100644 (file)
-/*
- * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
- * Copyright (c) 2003-2004 Leon Woestenberg <leon.woestenberg@axon.tv>
- * Copyright (c) 2003-2004 Axon Digital Design B.V., The Netherlands.
- * 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 <adam@sics.se>
- *
- */
-
-#ifndef __NETIF_ETHARP_H__
-#define __NETIF_ETHARP_H__
-
-#ifndef ETH_PAD_SIZE
-#define ETH_PAD_SIZE 0
-#endif
-
-#include "lwip/pbuf.h"
-#include "lwip/ip_addr.h"
-#include "lwip/netif.h"
-#include "lwip/ip.h"
-
-#ifdef PACK_STRUCT_USE_INCLUDES
-#  include "arch/bpstruct.h"
-#endif
-PACK_STRUCT_BEGIN
-struct eth_addr {
-  PACK_STRUCT_FIELD(u8_t addr[6]);
-} PACK_STRUCT_STRUCT;
-PACK_STRUCT_END
-#ifdef PACK_STRUCT_USE_INCLUDES
-#  include "arch/epstruct.h"
-#endif
-
-#ifdef PACK_STRUCT_USE_INCLUDES
-#  include "arch/bpstruct.h"
-#endif
-PACK_STRUCT_BEGIN
-struct eth_hdr {
-#if ETH_PAD_SIZE
-  PACK_STRUCT_FIELD(u8_t padding[ETH_PAD_SIZE]);
-#endif
-  PACK_STRUCT_FIELD(struct eth_addr dest);
-  PACK_STRUCT_FIELD(struct eth_addr src);
-  PACK_STRUCT_FIELD(u16_t type);
-} PACK_STRUCT_STRUCT;
-PACK_STRUCT_END
-#ifdef PACK_STRUCT_USE_INCLUDES
-#  include "arch/epstruct.h"
-#endif
-
-#ifdef PACK_STRUCT_USE_INCLUDES
-#  include "arch/bpstruct.h"
-#endif
-PACK_STRUCT_BEGIN
-/** the ARP message */
-struct etharp_hdr {
-  PACK_STRUCT_FIELD(struct eth_hdr ethhdr);
-  PACK_STRUCT_FIELD(u16_t hwtype);
-  PACK_STRUCT_FIELD(u16_t proto);
-  PACK_STRUCT_FIELD(u16_t _hwlen_protolen);
-  PACK_STRUCT_FIELD(u16_t opcode);
-  PACK_STRUCT_FIELD(struct eth_addr shwaddr);
-  PACK_STRUCT_FIELD(struct ip_addr2 sipaddr);
-  PACK_STRUCT_FIELD(struct eth_addr dhwaddr);
-  PACK_STRUCT_FIELD(struct ip_addr2 dipaddr);
-} PACK_STRUCT_STRUCT;
-PACK_STRUCT_END
-#ifdef PACK_STRUCT_USE_INCLUDES
-#  include "arch/epstruct.h"
-#endif
-
-#ifdef PACK_STRUCT_USE_INCLUDES
-#  include "arch/bpstruct.h"
-#endif
-PACK_STRUCT_BEGIN
-struct ethip_hdr {
-  PACK_STRUCT_FIELD(struct eth_hdr eth);
-  PACK_STRUCT_FIELD(struct ip_hdr ip);
-} PACK_STRUCT_STRUCT;
-PACK_STRUCT_END
-#ifdef PACK_STRUCT_USE_INCLUDES
-#  include "arch/epstruct.h"
-#endif
-
-/** 5 seconds period */
-#define ARP_TMR_INTERVAL 5000
-
-#define ETHTYPE_ARP 0x0806
-#define ETHTYPE_IP  0x0800
-
-void etharp_init(void);
-void etharp_tmr(void);
-void etharp_ip_input(struct netif *netif, struct pbuf *p);
-void etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr,
-         struct pbuf *p);
-err_t etharp_output(struct netif *netif, struct ip_addr *ipaddr,
-         struct pbuf *q);
-err_t etharp_query(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q);
-err_t etharp_request(struct netif *netif, struct ip_addr *ipaddr);
-
-#endif /* __NETIF_ARP_H__ */
+/*\r
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.\r
+ * Copyright (c) 2003-2004 Leon Woestenberg <leon.woestenberg@axon.tv>\r
+ * Copyright (c) 2003-2004 Axon Digital Design B.V., The Netherlands.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+\r
+#ifndef __NETIF_ETHARP_H__\r
+#define __NETIF_ETHARP_H__\r
+\r
+#ifndef ETH_PAD_SIZE\r
+#define ETH_PAD_SIZE 0\r
+#endif\r
+\r
+#include "lwip/pbuf.h"\r
+#include "lwip/ip_addr.h"\r
+#include "lwip/netif.h"\r
+#include "lwip/ip.h"\r
+\r
+#ifdef PACK_STRUCT_USE_INCLUDES\r
+#  include "arch/bpstruct.h"\r
+#endif\r
+PACK_STRUCT_BEGIN\r
+struct eth_addr {\r
+  PACK_STRUCT_FIELD(u8_t addr[6]);\r
+} PACK_STRUCT_STRUCT;\r
+PACK_STRUCT_END\r
+#ifdef PACK_STRUCT_USE_INCLUDES\r
+#  include "arch/epstruct.h"\r
+#endif\r
+\r
+#ifdef PACK_STRUCT_USE_INCLUDES\r
+#  include "arch/bpstruct.h"\r
+#endif\r
+PACK_STRUCT_BEGIN\r
+struct eth_hdr {\r
+#if ETH_PAD_SIZE\r
+  PACK_STRUCT_FIELD(u8_t padding[ETH_PAD_SIZE]);\r
+#endif\r
+  PACK_STRUCT_FIELD(struct eth_addr dest);\r
+  PACK_STRUCT_FIELD(struct eth_addr src);\r
+  PACK_STRUCT_FIELD(u16_t type);\r
+} PACK_STRUCT_STRUCT;\r
+PACK_STRUCT_END\r
+#ifdef PACK_STRUCT_USE_INCLUDES\r
+#  include "arch/epstruct.h"\r
+#endif\r
+\r
+#ifdef PACK_STRUCT_USE_INCLUDES\r
+#  include "arch/bpstruct.h"\r
+#endif\r
+PACK_STRUCT_BEGIN\r
+/** the ARP message */\r
+struct etharp_hdr {\r
+  PACK_STRUCT_FIELD(struct eth_hdr ethhdr);\r
+  PACK_STRUCT_FIELD(u16_t hwtype);\r
+  PACK_STRUCT_FIELD(u16_t proto);\r
+  PACK_STRUCT_FIELD(u16_t _hwlen_protolen);\r
+  PACK_STRUCT_FIELD(u16_t opcode);\r
+  PACK_STRUCT_FIELD(struct eth_addr shwaddr);\r
+  PACK_STRUCT_FIELD(struct ip_addr2 sipaddr);\r
+  PACK_STRUCT_FIELD(struct eth_addr dhwaddr);\r
+  PACK_STRUCT_FIELD(struct ip_addr2 dipaddr);\r
+} PACK_STRUCT_STRUCT;\r
+PACK_STRUCT_END\r
+#ifdef PACK_STRUCT_USE_INCLUDES\r
+#  include "arch/epstruct.h"\r
+#endif\r
+\r
+#ifdef PACK_STRUCT_USE_INCLUDES\r
+#  include "arch/bpstruct.h"\r
+#endif\r
+PACK_STRUCT_BEGIN\r
+struct ethip_hdr {\r
+  PACK_STRUCT_FIELD(struct eth_hdr eth);\r
+  PACK_STRUCT_FIELD(struct ip_hdr ip);\r
+} PACK_STRUCT_STRUCT;\r
+PACK_STRUCT_END\r
+#ifdef PACK_STRUCT_USE_INCLUDES\r
+#  include "arch/epstruct.h"\r
+#endif\r
+\r
+/** 5 seconds period */\r
+#define ARP_TMR_INTERVAL 5000\r
+\r
+#define ETHTYPE_ARP 0x0806\r
+#define ETHTYPE_IP  0x0800\r
+\r
+void etharp_init(void);\r
+void etharp_tmr(void);\r
+void etharp_ip_input(struct netif *netif, struct pbuf *p);\r
+void etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr,\r
+         struct pbuf *p);\r
+err_t etharp_output(struct netif *netif, struct ip_addr *ipaddr,\r
+         struct pbuf *q);\r
+err_t etharp_query(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q);\r
+err_t etharp_request(struct netif *netif, struct ip_addr *ipaddr);\r
+\r
+#endif /* __NETIF_ARP_H__ */\r
index 97b3c67645badf25cf923eae628ab30480fa9202..7fd54873397e37e0425764881a10b30b15e2b505 100644 (file)
@@ -1,39 +1,39 @@
-/*
- * 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 <adam@sics.se>
- *
- */
-#ifndef __NETIF_LOOPIF_H__
-#define __NETIF_LOOPIF_H__
-
-#include "lwip/netif.h"
-
-err_t loopif_init(struct netif *netif);
-
-#endif /* __NETIF_LOOPIF_H__ */
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+#ifndef __NETIF_LOOPIF_H__\r
+#define __NETIF_LOOPIF_H__\r
+\r
+#include "lwip/netif.h"\r
+\r
+err_t loopif_init(struct netif *netif);\r
+\r
+#endif /* __NETIF_LOOPIF_H__ */\r
index bf70046a9f6e8e8c020725f8fd3abe627cb63292..d9060fc9734231af45a4048d8108631ff491f3f9 100644 (file)
@@ -1,42 +1,42 @@
-/*
- * Copyright (c) 2001, 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. Neither the name of the Institute nor the names of its contributors 
- *    may be used to endorse or promote products derived from this software 
- *    without specific prior written permission. 
- *
- * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE OR CONTRIBUTORS 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 <adam@sics.se>
- *
- */
-#ifndef __NETIF_SLIPIF_H__
-#define __NETIF_SLIPIF_H__
-
-#include "lwip/netif.h"
-
-err_t slipif_init(struct netif * netif);
-#endif 
-
+/*\r
+ * Copyright (c) 2001, Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ *\r
+ * Redistribution and use in source and binary forms, with or without \r
+ * modification, are permitted provided that the following conditions \r
+ * are met: \r
+ * 1. Redistributions of source code must retain the above copyright \r
+ *    notice, this list of conditions and the following disclaimer. \r
+ * 2. Redistributions in binary form must reproduce the above copyright \r
+ *    notice, this list of conditions and the following disclaimer in the \r
+ *    documentation and/or other materials provided with the distribution. \r
+ * 3. Neither the name of the Institute nor the names of its contributors \r
+ *    may be used to endorse or promote products derived from this software \r
+ *    without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND \r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE \r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE \r
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE \r
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL \r
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS \r
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) \r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT \r
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY \r
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF \r
+ * SUCH DAMAGE. \r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+#ifndef __NETIF_SLIPIF_H__\r
+#define __NETIF_SLIPIF_H__\r
+\r
+#include "lwip/netif.h"\r
+\r
+err_t slipif_init(struct netif * netif);\r
\r
+#endif \r
+\r
index f5bcc07cf46d9b79fe62478fbc00f5b446c733db..9440a6c11d7e1f2f06b39ed26454acb5f86c1454 100644 (file)
-/*
- * 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 <adam@sics.se>
- *
- */
-#include "lwip/opt.h"
-
-#if LWIP_HAVE_LOOPIF
-
-#include "netif/loopif.h"
-#include "lwip/mem.h"
-
-#if defined(LWIP_DEBUG) && defined(LWIP_TCPDUMP)
-#include "netif/tcpdump.h"
-#endif /* LWIP_DEBUG && LWIP_TCPDUMP */
-
-#include "lwip/tcp.h"
-#include "lwip/ip.h"
-
-static void
-loopif_input( void * arg )
-{
-       struct netif *netif = (struct netif *)( ((void **)arg)[ 0 ] );
-       struct pbuf *r = (struct pbuf *)( ((void **)arg)[ 1 ] );
-
-       mem_free( arg );
-       netif -> input( r, netif );
-}
-
-static err_t
-loopif_output(struct netif *netif, struct pbuf *p,
-       struct ip_addr *ipaddr)
-{
-  struct pbuf *q, *r;
-  char *ptr;
-  void **arg;
-
-#if defined(LWIP_DEBUG) && defined(LWIP_TCPDUMP)
-  tcpdump(p);
-#endif /* LWIP_DEBUG && LWIP_TCPDUMP */
-  
-  r = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM);
-  if (r != NULL) {
-    ptr = r->payload;
-    
-    for(q = p; q != NULL; q = q->next) {
-      memcpy(ptr, q->payload, q->len);
-      ptr += q->len;
-    }
-
-    arg = mem_malloc( sizeof( void *[2]));
-       if( NULL == arg ) {
-               return ERR_MEM;
-       }
-       
-       arg[0] = netif;
-       arg[1] = r;
-       /**
-        * workaround (patch #1779) to try to prevent bug #2595:
-        * When connecting to "localhost" with the loopif interface,
-        * tcp_output doesn't get the opportunity to finnish sending the
-        * segment before tcp_process gets it, resulting in tcp_process
-        * referencing pcb->unacked-> which still is NULL.
-        * 
-        * TODO: Is there still a race condition here? Leon
-        */
-       sys_timeout( 1, loopif_input, arg );
-       
-    return ERR_OK;    
-  }
-  return ERR_MEM;
-}
-
-err_t
-loopif_init(struct netif *netif)
-{
-  netif->name[0] = 'l';
-  netif->name[1] = 'o';
-#if 0 /** TODO: I think this should be enabled, or not? Leon */
-  netif->input = loopif_input;
-#endif
-  netif->output = loopif_output;
-  return ERR_OK;
-}
-
-#endif /* LWIP_HAVE_LOOPIF */
-
-
-
-
-
-
-
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+#include "lwip/opt.h"\r
+\r
+#if LWIP_HAVE_LOOPIF\r
+\r
+#include "netif/loopif.h"\r
+#include "lwip/mem.h"\r
+\r
+#if defined(LWIP_DEBUG) && defined(LWIP_TCPDUMP)\r
+#include "netif/tcpdump.h"\r
+#endif /* LWIP_DEBUG && LWIP_TCPDUMP */\r
+\r
+#include "lwip/tcp.h"\r
+#include "lwip/ip.h"\r
+\r
+static void\r
+loopif_input( void * arg )\r
+{\r
+       struct netif *netif = (struct netif *)( ((void **)arg)[ 0 ] );\r
+       struct pbuf *r = (struct pbuf *)( ((void **)arg)[ 1 ] );\r
+\r
+       mem_free( arg );\r
+       netif -> input( r, netif );\r
+}\r
+\r
+static err_t\r
+loopif_output(struct netif *netif, struct pbuf *p,\r
+       struct ip_addr *ipaddr)\r
+{\r
+  struct pbuf *q, *r;\r
+  char *ptr;\r
+  void **arg;\r
+\r
+#if defined(LWIP_DEBUG) && defined(LWIP_TCPDUMP)\r
+  tcpdump(p);\r
+#endif /* LWIP_DEBUG && LWIP_TCPDUMP */\r
+  \r
+  r = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM);\r
+  if (r != NULL) {\r
+    ptr = r->payload;\r
+    \r
+    for(q = p; q != NULL; q = q->next) {\r
+      memcpy(ptr, q->payload, q->len);\r
+      ptr += q->len;\r
+    }\r
+\r
+    arg = mem_malloc( sizeof( void *[2]));\r
+       if( NULL == arg ) {\r
+               return ERR_MEM;\r
+       }\r
+       \r
+       arg[0] = netif;\r
+       arg[1] = r;\r
+       /**\r
+        * workaround (patch #1779) to try to prevent bug #2595:\r
+        * When connecting to "localhost" with the loopif interface,\r
+        * tcp_output doesn't get the opportunity to finnish sending the\r
+        * segment before tcp_process gets it, resulting in tcp_process\r
+        * referencing pcb->unacked-> which still is NULL.\r
+        * \r
+        * TODO: Is there still a race condition here? Leon\r
+        */\r
+       sys_timeout( 1, loopif_input, arg );\r
+       \r
+    return ERR_OK;    \r
+  }\r
+  return ERR_MEM;\r
+}\r
+\r
+err_t\r
+loopif_init(struct netif *netif)\r
+{\r
+  netif->name[0] = 'l';\r
+  netif->name[1] = 'o';\r
+#if 0 /** TODO: I think this should be enabled, or not? Leon */\r
+  netif->input = loopif_input;\r
+#endif\r
+  netif->output = loopif_output;\r
+  return ERR_OK;\r
+}\r
+\r
+#endif /* LWIP_HAVE_LOOPIF */\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
index 33349640223faa403d5428769cd757619300d80b..0786a2e81cf9a04537939e75d73a8ce44af5371e 100644 (file)
-/*****************************************************************************
-* auth.c - Network Authentication and Phase Control program file.
-*
-* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
-* Copyright (c) 1997 by Global Election Systems Inc.  All rights reserved.
-*
-* The authors hereby grant permission to use, copy, modify, distribute,
-* and license this software and its documentation for any purpose, provided
-* that existing copyright notices are retained in all copies and that this
-* notice and the following disclaimer are included verbatim in any 
-* distributions. No written agreement, license, or royalty fee is required
-* for any of the authorized uses.
-*
-* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *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 CONTRIBUTORS 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.
-*
-******************************************************************************
-* REVISION HISTORY
-*
-* 03-01-01 Marc Boucher <marc@mbsi.ca>
-*   Ported to lwIP.
-* 97-12-08 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
-*   Ported from public pppd code.
-*****************************************************************************/
-/*
- * auth.c - PPP authentication and phase control.
- *
- * Copyright (c) 1993 The Australian National University.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the Australian National University.  The name of the University
- * may not be used to endorse or promote products derived from this
- * software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Copyright (c) 1989 Carnegie Mellon University.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by Carnegie Mellon University.  The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include "ppp.h"
-#if PPP_SUPPORT > 0
-#include "fsm.h"
-#include "lcp.h"
-#include "pap.h"
-#include "chap.h"
-#include "auth.h"
-#include "ipcp.h"
-
-#if CBCP_SUPPORT > 0
-#include "cbcp.h"
-#endif
-
-#include "pppdebug.h"
-
-
-/*************************/
-/*** LOCAL DEFINITIONS ***/
-/*************************/
-
-/* Bits in auth_pending[] */
-#define PAP_WITHPEER    1
-#define PAP_PEER    2
-#define CHAP_WITHPEER   4
-#define CHAP_PEER   8
-
-
-                                                                    
-/************************/
-/*** LOCAL DATA TYPES ***/
-/************************/
-/* Used for storing a sequence of words.  Usually malloced. */
-struct wordlist {
-    struct wordlist *next;
-    char        word[1];
-};
-
-
-
-/***********************************/
-/*** LOCAL FUNCTION DECLARATIONS ***/
-/***********************************/
-extern char *crypt (const char *, const char *);
-
-/* Prototypes for procedures local to this file. */
-
-static void network_phase (int);
-static void check_idle (void *);
-static void connect_time_expired (void *);
-#if 0
-static int  login (char *, char *, char **, int *);
-#endif
-static void logout (void);
-static int  null_login (int);
-static int  get_pap_passwd (int, char *, char *);
-static int  have_pap_secret (void);
-static int  have_chap_secret (char *, char *, u32_t);
-static int  ip_addr_check (u32_t, struct wordlist *);
-#if 0 /* PAP_SUPPORT > 0 || CHAP_SUPPORT > 0 */
-static void set_allowed_addrs(int unit, struct wordlist *addrs);
-static void free_wordlist (struct wordlist *);
-#endif
-#if CBCP_SUPPORT > 0
-static void callback_phase (int);
-#endif
-
-
-/******************************/
-/*** PUBLIC DATA STRUCTURES ***/
-/******************************/
-
-
-/*****************************/
-/*** LOCAL DATA STRUCTURES ***/
-/*****************************/
-#if PAP_SUPPORT > 0 || CHAP_SUPPORT > 0
-/* The name by which the peer authenticated itself to us. */
-static char peer_authname[MAXNAMELEN];
-#endif
-
-/* Records which authentication operations haven't completed yet. */
-static int auth_pending[NUM_PPP];
-
-/* Set if we have successfully called login() */
-static int logged_in;
-
-/* Set if we have run the /etc/ppp/auth-up script. */
-static int did_authup;
-
-/* List of addresses which the peer may use. */
-static struct wordlist *addresses[NUM_PPP];
-
-/* Number of network protocols which we have opened. */
-static int num_np_open;
-
-/* Number of network protocols which have come up. */
-static int num_np_up;
-
-#if PAP_SUPPORT > 0 || CHAP_SUPPORT > 0
-/* Set if we got the contents of passwd[] from the pap-secrets file. */
-static int passwd_from_file;
-#endif
-
-
-
-/***********************************/
-/*** PUBLIC FUNCTION DEFINITIONS ***/
-/***********************************/
-/*
- * An Open on LCP has requested a change from Dead to Establish phase.
- * Do what's necessary to bring the physical layer up.
- */
-void link_required(int unit)
-{
-    AUTHDEBUG((LOG_INFO, "link_required: %d\n", unit));
-}
-
-/*
- * LCP has terminated the link; go to the Dead phase and take the
- * physical layer down.
- */
-void link_terminated(int unit)
-{
-    AUTHDEBUG((LOG_INFO, "link_terminated: %d\n", unit));
-    
-    if (lcp_phase[unit] == PHASE_DEAD)
-        return;
-    if (logged_in)
-        logout();
-    lcp_phase[unit] = PHASE_DEAD;
-    AUTHDEBUG((LOG_NOTICE, "Connection terminated.\n"));
-       pppMainWakeup(unit);
-}
-
-/*
- * LCP has gone down; it will either die or try to re-establish.
- */
-void link_down(int unit)
-{
-    int i;
-    struct protent *protp;
-    
-    AUTHDEBUG((LOG_INFO, "link_down: %d\n", unit));
-    if (did_authup) {
-        /* XXX Do link down processing. */
-        did_authup = 0;
-    }
-    for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i) {
-        if (!protp->enabled_flag)
-            continue;
-        if (protp->protocol != PPP_LCP && protp->lowerdown != NULL)
-            (*protp->lowerdown)(unit);
-        if (protp->protocol < 0xC000 && protp->close != NULL)
-            (*protp->close)(unit, "LCP down");
-    }
-    num_np_open = 0;
-    num_np_up = 0;
-    if (lcp_phase[unit] != PHASE_DEAD)
-        lcp_phase[unit] = PHASE_TERMINATE;
-       pppMainWakeup(unit);
-}
-
-/*
- * The link is established.
- * Proceed to the Dead, Authenticate or Network phase as appropriate.
- */
-void link_established(int unit)
-{
-    int auth;
-    int i;
-    struct protent *protp;
-    lcp_options *wo = &lcp_wantoptions[unit];
-    lcp_options *go = &lcp_gotoptions[unit];
-#if PAP_SUPPORT > 0 || CHAP_SUPPORT > 0
-    lcp_options *ho = &lcp_hisoptions[unit];
-#endif
-    
-    AUTHDEBUG((LOG_INFO, "link_established: %d\n", unit));
-    /*
-     * Tell higher-level protocols that LCP is up.
-     */
-    for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i)
-        if (protp->protocol != PPP_LCP && protp->enabled_flag
-                && protp->lowerup != NULL)
-            (*protp->lowerup)(unit);
-    
-    if (ppp_settings.auth_required && !(go->neg_chap || go->neg_upap)) {
-        /*
-         * We wanted the peer to authenticate itself, and it refused:
-         * treat it as though it authenticated with PAP using a username
-         * of "" and a password of "".  If that's not OK, boot it out.
-         */
-        if (!wo->neg_upap || !null_login(unit)) {
-            AUTHDEBUG((LOG_WARNING, "peer refused to authenticate\n"));
-            lcp_close(unit, "peer refused to authenticate");
-            return;
-        }
-    }
-    
-    lcp_phase[unit] = PHASE_AUTHENTICATE;
-    auth = 0;
-#if CHAP_SUPPORT > 0
-    if (go->neg_chap) {
-        ChapAuthPeer(unit, ppp_settings.our_name, go->chap_mdtype);
-        auth |= CHAP_PEER;
-    } 
-#endif
-#if PAP_SUPPORT > 0 && CHAP_SUPPORT > 0
-    else
-#endif
-#if PAP_SUPPORT > 0
-    if (go->neg_upap) {
-        upap_authpeer(unit);
-        auth |= PAP_PEER;
-    }
-#endif
-#if CHAP_SUPPORT > 0
-    if (ho->neg_chap) {
-        ChapAuthWithPeer(unit, ppp_settings.user, ho->chap_mdtype);
-        auth |= CHAP_WITHPEER;
-    }
-#endif
-#if PAP_SUPPORT > 0 && CHAP_SUPPORT > 0
-    else
-#endif
-#if PAP_SUPPORT > 0
-    if (ho->neg_upap) {
-        if (ppp_settings.passwd[0] == 0) {
-            passwd_from_file = 1;
-            if (!get_pap_passwd(unit, ppp_settings.user, ppp_settings.passwd))
-                AUTHDEBUG((LOG_ERR, "No secret found for PAP login\n"));
-        }
-        upap_authwithpeer(unit, ppp_settings.user, ppp_settings.passwd);
-        auth |= PAP_WITHPEER;
-    }
-#endif
-    auth_pending[unit] = auth;
-    
-    if (!auth)
-        network_phase(unit);
-}
-
-
-/*
- * The peer has failed to authenticate himself using `protocol'.
- */
-void auth_peer_fail(int unit, u16_t protocol)
-{
-    AUTHDEBUG((LOG_INFO, "auth_peer_fail: %d proto=%X\n", unit, protocol));
-    /*
-     * Authentication failure: take the link down
-     */
-    lcp_close(unit, "Authentication failed");
-}
-
-
-#if PAP_SUPPORT > 0 || CHAP_SUPPORT > 0
-/*
- * The peer has been successfully authenticated using `protocol'.
- */
-void auth_peer_success(int unit, u16_t protocol, char *name, int namelen)
-{
-    int pbit;
-    
-    AUTHDEBUG((LOG_INFO, "auth_peer_success: %d proto=%X\n", unit, protocol));
-    switch (protocol) {
-    case PPP_CHAP:
-        pbit = CHAP_PEER;
-        break;
-    case PPP_PAP:
-        pbit = PAP_PEER;
-        break;
-    default:
-        AUTHDEBUG((LOG_WARNING, "auth_peer_success: unknown protocol %x\n",
-               protocol));
-        return;
-    }
-    
-    /*
-     * Save the authenticated name of the peer for later.
-     */
-    if (namelen > sizeof(peer_authname) - 1)
-        namelen = sizeof(peer_authname) - 1;
-    BCOPY(name, peer_authname, namelen);
-    peer_authname[namelen] = 0;
-    
-    /*
-     * If there is no more authentication still to be done,
-     * proceed to the network (or callback) phase.
-     */
-    if ((auth_pending[unit] &= ~pbit) == 0)
-        network_phase(unit);
-}
-
-/*
- * We have failed to authenticate ourselves to the peer using `protocol'.
- */
-void auth_withpeer_fail(int unit, u16_t protocol)
-{
-    int errCode = PPPERR_AUTHFAIL;
-    
-    AUTHDEBUG((LOG_INFO, "auth_withpeer_fail: %d proto=%X\n", unit, protocol));
-    if (passwd_from_file)
-        BZERO(ppp_settings.passwd, MAXSECRETLEN);
-    /* 
-     * XXX Warning: the unit number indicates the interface which is
-     * not necessarily the PPP connection.  It works here as long
-     * as we are only supporting PPP interfaces.
-     */
-    pppIOCtl(unit, PPPCTLS_ERRCODE, &errCode);
-
-    /*
-     * We've failed to authenticate ourselves to our peer.
-     * He'll probably take the link down, and there's not much
-     * we can do except wait for that.
-     */
-}
-
-/*
- * We have successfully authenticated ourselves with the peer using `protocol'.
- */
-void auth_withpeer_success(int unit, u16_t protocol)
-{
-    int pbit;
-    
-    AUTHDEBUG((LOG_INFO, "auth_withpeer_success: %d proto=%X\n", unit, protocol));
-    switch (protocol) {
-    case PPP_CHAP:
-        pbit = CHAP_WITHPEER;
-        break;
-    case PPP_PAP:
-        if (passwd_from_file)
-            BZERO(ppp_settings.passwd, MAXSECRETLEN);
-        pbit = PAP_WITHPEER;
-        break;
-    default:
-        AUTHDEBUG((LOG_WARNING, "auth_peer_success: unknown protocol %x\n",
-               protocol));
-        pbit = 0;
-    }
-    
-    /*
-     * If there is no more authentication still being done,
-     * proceed to the network (or callback) phase.
-     */
-    if ((auth_pending[unit] &= ~pbit) == 0)
-        network_phase(unit);
-}
-#endif
-
-
-/*
- * np_up - a network protocol has come up.
- */
-void np_up(int unit, u16_t proto)
-{
-    AUTHDEBUG((LOG_INFO, "np_up: %d proto=%X\n", unit, proto));
-    if (num_np_up == 0) {
-       AUTHDEBUG((LOG_INFO, "np_up: maxconnect=%d idle_time_limit=%d\n",ppp_settings.maxconnect,ppp_settings.idle_time_limit));
-        /*
-         * At this point we consider that the link has come up successfully.
-         */
-        if (ppp_settings.idle_time_limit > 0)
-            TIMEOUT(check_idle, NULL, ppp_settings.idle_time_limit);
-        
-        /*
-         * Set a timeout to close the connection once the maximum
-         * connect time has expired.
-         */
-        if (ppp_settings.maxconnect > 0)
-            TIMEOUT(connect_time_expired, 0, ppp_settings.maxconnect);
-    }
-    ++num_np_up;
-}
-
-/*
- * np_down - a network protocol has gone down.
- */
-void np_down(int unit, u16_t proto)
-{
-    AUTHDEBUG((LOG_INFO, "np_down: %d proto=%X\n", unit, proto));
-    if (--num_np_up == 0 && ppp_settings.idle_time_limit > 0) {
-        UNTIMEOUT(check_idle, NULL);
-    }
-}
-
-/*
- * np_finished - a network protocol has finished using the link.
- */
-void np_finished(int unit, u16_t proto)
-{
-    AUTHDEBUG((LOG_INFO, "np_finished: %d proto=%X\n", unit, proto));
-    if (--num_np_open <= 0) {
-        /* no further use for the link: shut up shop. */
-        lcp_close(0, "No network protocols running");
-    }
-}
-
-/*
- * auth_reset - called when LCP is starting negotiations to recheck
- * authentication options, i.e. whether we have appropriate secrets
- * to use for authenticating ourselves and/or the peer.
- */
-void auth_reset(int unit)
-{
-    lcp_options *go = &lcp_gotoptions[unit];
-    lcp_options *ao = &lcp_allowoptions[0];
-    ipcp_options *ipwo = &ipcp_wantoptions[0];
-    u32_t remote;
-    
-    AUTHDEBUG((LOG_INFO, "auth_reset: %d\n", unit));
-    ao->neg_upap = !ppp_settings.refuse_pap && (ppp_settings.passwd[0] != 0 || get_pap_passwd(unit, NULL, NULL));
-    ao->neg_chap = !ppp_settings.refuse_chap && ppp_settings.passwd[0] != 0 /*have_chap_secret(ppp_settings.user, ppp_settings.remote_name, (u32_t)0)*/;
-    
-    if (go->neg_upap && !have_pap_secret())
-        go->neg_upap = 0;
-    if (go->neg_chap) {
-        remote = ipwo->accept_remote? 0: ipwo->hisaddr;
-        if (!have_chap_secret(ppp_settings.remote_name, ppp_settings.our_name, remote))
-            go->neg_chap = 0;
-    }
-}
-
-
-#if PAP_SUPPORT > 0
-/*
- * check_passwd - Check the user name and passwd against the PAP secrets
- * file.  If requested, also check against the system password database,
- * and login the user if OK.
- *
- * returns:
- *  UPAP_AUTHNAK: Authentication failed.
- *  UPAP_AUTHACK: Authentication succeeded.
- * In either case, msg points to an appropriate message.
- */
-int check_passwd(
-       int unit,
-       char *auser,
-       int userlen,
-       char *apasswd,
-       int passwdlen,
-       char **msg,
-       int *msglen
-)
-{
-#if 1
-       *msg = (char *) 0;
-       return UPAP_AUTHACK;     /* XXX Assume all entries OK. */
-#else
-    int ret = 0;
-    struct wordlist *addrs = NULL;
-    char passwd[256], user[256];
-    char secret[MAXWORDLEN];
-    static u_short attempts = 0;
-    
-    /*
-     * Make copies of apasswd and auser, then null-terminate them.
-     */
-    BCOPY(apasswd, passwd, passwdlen);
-    passwd[passwdlen] = '\0';
-    BCOPY(auser, user, userlen);
-    user[userlen] = '\0';
-    *msg = (char *) 0;
-
-    /* XXX Validate user name and password. */
-    ret = UPAP_AUTHACK;     /* XXX Assume all entries OK. */
-        
-    if (ret == UPAP_AUTHNAK) {
-        if (*msg == (char *) 0)
-            *msg = "Login incorrect";
-        *msglen = strlen(*msg);
-        /*
-         * Frustrate passwd stealer programs.
-         * Allow 10 tries, but start backing off after 3 (stolen from login).
-         * On 10'th, drop the connection.
-         */
-        if (attempts++ >= 10) {
-            AUTHDEBUG((LOG_WARNING, "%d LOGIN FAILURES BY %s\n", attempts, user));
-            /*ppp_panic("Excess Bad Logins");*/
-        }
-        if (attempts > 3) {
-            sys_msleep((attempts - 3) * 5);
-        }
-        if (addrs != NULL) {
-            free_wordlist(addrs);
-        }
-    } else {
-        attempts = 0;           /* Reset count */
-        if (*msg == (char *) 0)
-            *msg = "Login ok";
-        *msglen = strlen(*msg);
-        set_allowed_addrs(unit, addrs);
-    }
-    
-    BZERO(passwd, sizeof(passwd));
-    BZERO(secret, sizeof(secret));
-    
-    return ret;
-#endif
-}
-#endif
-
-
-/*
- * auth_ip_addr - check whether the peer is authorized to use
- * a given IP address.  Returns 1 if authorized, 0 otherwise.
- */
-int auth_ip_addr(int unit, u32_t addr)
-{
-    return ip_addr_check(addr, addresses[unit]);
-}
-
-/*
- * bad_ip_adrs - return 1 if the IP address is one we don't want
- * to use, such as an address in the loopback net or a multicast address.
- * addr is in network byte order.
- */
-int bad_ip_adrs(u32_t addr)
-{
-    addr = ntohl(addr);
-    return (addr >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET
-        || IN_MULTICAST(addr) || IN_BADCLASS(addr);
-}
-
-
-#if CHAP_SUPPORT > 0
-/*
- * get_secret - open the CHAP secret file and return the secret
- * for authenticating the given client on the given server.
- * (We could be either client or server).
- */
-int get_secret(
-    int unit,
-    char *client,
-    char *server,
-    char *secret,
-    int *secret_len,
-    int save_addrs
-)
-{
-#if 1
-    int len;
-    struct wordlist *addrs;
-    
-    addrs = NULL;
-
-    if(!client || !client[0] || strcmp(client, ppp_settings.user)) {
-       return 0;
-    }
-
-    len = strlen(ppp_settings.passwd);
-    if (len > MAXSECRETLEN) {
-        AUTHDEBUG((LOG_ERR, "Secret for %s on %s is too long\n", client, server));
-        len = MAXSECRETLEN;
-    }
-    BCOPY(ppp_settings.passwd, secret, len);
-    *secret_len = len;
-    
-    return 1;
-#else
-    int ret = 0, len;
-    struct wordlist *addrs;
-    char secbuf[MAXWORDLEN];
-    
-    addrs = NULL;
-    secbuf[0] = 0;
-
-    /* XXX Find secret. */  
-    if (ret < 0)
-        return 0;
-    
-    if (save_addrs)
-        set_allowed_addrs(unit, addrs);
-    
-    len = strlen(secbuf);
-    if (len > MAXSECRETLEN) {
-        AUTHDEBUG((LOG_ERR, "Secret for %s on %s is too long\n", client, server));
-        len = MAXSECRETLEN;
-    }
-    BCOPY(secbuf, secret, len);
-    BZERO(secbuf, sizeof(secbuf));
-    *secret_len = len;
-    
-    return 1;
-#endif
-}
-#endif
-
-
-#if 0 /* UNUSED */
-/*
- * auth_check_options - called to check authentication options.
- */
-void auth_check_options(void)
-{
-    lcp_options *wo = &lcp_wantoptions[0];
-    int can_auth;
-    ipcp_options *ipwo = &ipcp_wantoptions[0];
-    u32_t remote;
-    
-    /* Default our_name to hostname, and user to our_name */
-    if (ppp_settings.our_name[0] == 0 || ppp_settings.usehostname)
-        strcpy(ppp_settings.our_name, ppp_settings.hostname);
-    if (ppp_settings.user[0] == 0)
-        strcpy(ppp_settings.user, ppp_settings.our_name);
-    
-    /* If authentication is required, ask peer for CHAP or PAP. */
-    if (ppp_settings.auth_required && !wo->neg_chap && !wo->neg_upap) {
-        wo->neg_chap = 1;
-        wo->neg_upap = 1;
-    }
-    
-    /*
-     * Check whether we have appropriate secrets to use
-     * to authenticate the peer.
-     */
-    can_auth = wo->neg_upap && have_pap_secret();
-    if (!can_auth && wo->neg_chap) {
-        remote = ipwo->accept_remote? 0: ipwo->hisaddr;
-        can_auth = have_chap_secret(ppp_settings.remote_name, ppp_settings.our_name, remote);
-    }
-    
-    if (ppp_settings.auth_required && !can_auth) {
-        ppp_panic("No auth secret");
-    }
-}
-#endif
-
-
-/**********************************/
-/*** LOCAL FUNCTION DEFINITIONS ***/
-/**********************************/
-/*
- * Proceed to the network phase.
- */
-static void network_phase(int unit)
-{
-    int i;
-    struct protent *protp;
-    lcp_options *go = &lcp_gotoptions[unit];
-    
-    /*
-     * If the peer had to authenticate, run the auth-up script now.
-     */
-    if ((go->neg_chap || go->neg_upap) && !did_authup) {
-        /* XXX Do setup for peer authentication. */
-        did_authup = 1;
-    }
-    
-#if CBCP_SUPPORT > 0
-    /*
-     * If we negotiated callback, do it now.
-     */
-    if (go->neg_cbcp) {
-        lcp_phase[unit] = PHASE_CALLBACK;
-        (*cbcp_protent.open)(unit);
-        return;
-    }
-#endif
-    
-    lcp_phase[unit] = PHASE_NETWORK;
-    for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i)
-        if (protp->protocol < 0xC000 && protp->enabled_flag
-                && protp->open != NULL) {
-            (*protp->open)(unit);
-            if (protp->protocol != PPP_CCP)
-                ++num_np_open;
-        }
-    
-    if (num_np_open == 0)
-        /* nothing to do */
-        lcp_close(0, "No network protocols running");
-}
-
-/*
- * check_idle - check whether the link has been idle for long
- * enough that we can shut it down.
- */
-static void check_idle(void *arg)
-{
-    struct ppp_idle idle;
-    u_short itime;
-    
-       (void)arg;
-    if (!get_idle_time(0, &idle))
-        return;
-    itime = LWIP_MIN(idle.xmit_idle, idle.recv_idle);
-    if (itime >= ppp_settings.idle_time_limit) {
-        /* link is idle: shut it down. */
-        AUTHDEBUG((LOG_INFO, "Terminating connection due to lack of activity.\n"));
-        lcp_close(0, "Link inactive");
-    } else {
-        TIMEOUT(check_idle, NULL, ppp_settings.idle_time_limit - itime);
-    }
-}
-
-/*
- * connect_time_expired - log a message and close the connection.
- */
-static void connect_time_expired(void *arg)
-{
-       (void)arg;
-
-    AUTHDEBUG((LOG_INFO, "Connect time expired\n"));
-    lcp_close(0, "Connect time expired");   /* Close connection */
-}
-
-#if 0
-/*
- * login - Check the user name and password against the system
- * password database, and login the user if OK.
- *
- * returns:
- *  UPAP_AUTHNAK: Login failed.
- *  UPAP_AUTHACK: Login succeeded.
- * In either case, msg points to an appropriate message.
- */
-static int login(char *user, char *passwd, char **msg, int *msglen)
-{
-    /* XXX Fail until we decide that we want to support logins. */
-    return (UPAP_AUTHNAK);
-}
-#endif
-
-/*
- * logout - Logout the user.
- */
-static void logout(void)
-{
-    logged_in = 0;
-}
-
-
-/*
- * null_login - Check if a username of "" and a password of "" are
- * acceptable, and iff so, set the list of acceptable IP addresses
- * and return 1.
- */
-static int null_login(int unit)
-{
-       (void)unit;
-    /* XXX Fail until we decide that we want to support logins. */
-    return 0;
-}
-
-
-/*
- * get_pap_passwd - get a password for authenticating ourselves with
- * our peer using PAP.  Returns 1 on success, 0 if no suitable password
- * could be found.
- */
-static int get_pap_passwd(int unit, char *user, char *passwd)
-{
-/* normally we would reject PAP if no password is provided,
-   but this causes problems with some providers (like CHT in Taiwan)
-   who incorrectly request PAP and expect a bogus/empty password, so
-   always provide a default user/passwd of "none"/"none"
-*/
-    if(user)
-       strcpy(user,   "none");
-    if(passwd)
-       strcpy(passwd, "none");
-
-    return 1;
-}
-
-
-/*
- * have_pap_secret - check whether we have a PAP file with any
- * secrets that we could possibly use for authenticating the peer.
- */
-static int have_pap_secret(void)
-{
-    /* XXX Fail until we set up our passwords. */
-    return 0;
-}
-
-
-/*
- * have_chap_secret - check whether we have a CHAP file with a
- * secret that we could possibly use for authenticating `client'
- * on `server'.  Either can be the null string, meaning we don't
- * know the identity yet.
- */
-static int have_chap_secret(char *client, char *server, u32_t remote)
-{
-       (void)client;
-       (void)server;
-       (void)remote;
-    /* XXX Fail until we set up our passwords. */
-    return 0;
-}
-
-
-#if 0 /* PAP_SUPPORT > 0 || CHAP_SUPPORT > 0 */
-/*
- * set_allowed_addrs() - set the list of allowed addresses.
- */
-static void set_allowed_addrs(int unit, struct wordlist *addrs)
-{
-    if (addresses[unit] != NULL)
-        free_wordlist(addresses[unit]);
-    addresses[unit] = addrs;
-
-#if 0
-    /*
-     * If there's only one authorized address we might as well
-     * ask our peer for that one right away
-     */
-    if (addrs != NULL && addrs->next == NULL) {
-        char *p = addrs->word;
-        struct ipcp_options *wo = &ipcp_wantoptions[unit];
-        u32_t a;
-        struct hostent *hp;
-        
-        if (wo->hisaddr == 0 && *p != '!' && *p != '-'
-                && strchr(p, '/') == NULL) {
-            hp = gethostbyname(p);
-            if (hp != NULL && hp->h_addrtype == AF_INET)
-                a = *(u32_t *)hp->h_addr;
-            else
-                a = inet_addr(p);
-            if (a != (u32_t) -1)
-                wo->hisaddr = a;
-        }
-    }
-#endif
-}
-#endif
-
-static int ip_addr_check(u32_t addr, struct wordlist *addrs)
-{
-    
-    /* don't allow loopback or multicast address */
-    if (bad_ip_adrs(addr))
-        return 0;
-    
-    if (addrs == NULL)
-        return !ppp_settings.auth_required;      /* no addresses authorized */
-    
-    /* XXX All other addresses allowed. */
-    return 1;
-}
-
-#if 0 /* PAP_SUPPORT > 0 || CHAP_SUPPORT */
-/*
- * free_wordlist - release memory allocated for a wordlist.
- */
-static void free_wordlist(struct wordlist *wp)
-{
-    struct wordlist *next;
-    
-    while (wp != NULL) {
-        next = wp->next;
-        free(wp);
-        wp = next;
-    }
-}
-#endif
-
-#endif /* PPP_SUPPORT */
+/*****************************************************************************\r
+* auth.c - Network Authentication and Phase Control program file.\r
+*\r
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.\r
+* Copyright (c) 1997 by Global Election Systems Inc.  All rights reserved.\r
+*\r
+* The authors hereby grant permission to use, copy, modify, distribute,\r
+* and license this software and its documentation for any purpose, provided\r
+* that existing copyright notices are retained in all copies and that this\r
+* notice and the following disclaimer are included verbatim in any \r
+* distributions. No written agreement, license, or royalty fee is required\r
+* for any of the authorized uses.\r
+*\r
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR\r
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+*\r
+******************************************************************************\r
+* REVISION HISTORY\r
+*\r
+* 03-01-01 Marc Boucher <marc@mbsi.ca>\r
+*   Ported to lwIP.\r
+* 97-12-08 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.\r
+*   Ported from public pppd code.\r
+*****************************************************************************/\r
+/*\r
+ * auth.c - PPP authentication and phase control.\r
+ *\r
+ * Copyright (c) 1993 The Australian National University.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms are permitted\r
+ * provided that the above copyright notice and this paragraph are\r
+ * duplicated in all such forms and that any documentation,\r
+ * advertising materials, and other materials related to such\r
+ * distribution and use acknowledge that the software was developed\r
+ * by the Australian National University.  The name of the University\r
+ * may not be used to endorse or promote products derived from this\r
+ * software without specific prior written permission.\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR\r
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r
+ *\r
+ * Copyright (c) 1989 Carnegie Mellon University.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms are permitted\r
+ * provided that the above copyright notice and this paragraph are\r
+ * duplicated in all such forms and that any documentation,\r
+ * advertising materials, and other materials related to such\r
+ * distribution and use acknowledge that the software was developed\r
+ * by Carnegie Mellon University.  The name of the\r
+ * University may not be used to endorse or promote products derived\r
+ * from this software without specific prior written permission.\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR\r
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r
+ */\r
+\r
+#include "ppp.h"\r
+#if PPP_SUPPORT > 0\r
+#include "fsm.h"\r
+#include "lcp.h"\r
+#include "pap.h"\r
+#include "chap.h"\r
+#include "auth.h"\r
+#include "ipcp.h"\r
+\r
+#if CBCP_SUPPORT > 0\r
+#include "cbcp.h"\r
+#endif\r
+\r
+#include "pppdebug.h"\r
+\r
+\r
+/*************************/\r
+/*** LOCAL DEFINITIONS ***/\r
+/*************************/\r
+\r
+/* Bits in auth_pending[] */\r
+#define PAP_WITHPEER    1\r
+#define PAP_PEER    2\r
+#define CHAP_WITHPEER   4\r
+#define CHAP_PEER   8\r
+\r
+\r
+                                                                    \r
+/************************/\r
+/*** LOCAL DATA TYPES ***/\r
+/************************/\r
+/* Used for storing a sequence of words.  Usually malloced. */\r
+struct wordlist {\r
+    struct wordlist *next;\r
+    char        word[1];\r
+};\r
+\r
+\r
+\r
+/***********************************/\r
+/*** LOCAL FUNCTION DECLARATIONS ***/\r
+/***********************************/\r
+extern char *crypt (const char *, const char *);\r
+\r
+/* Prototypes for procedures local to this file. */\r
+\r
+static void network_phase (int);\r
+static void check_idle (void *);\r
+static void connect_time_expired (void *);\r
+#if 0\r
+static int  login (char *, char *, char **, int *);\r
+#endif\r
+static void logout (void);\r
+static int  null_login (int);\r
+static int  get_pap_passwd (int, char *, char *);\r
+static int  have_pap_secret (void);\r
+static int  have_chap_secret (char *, char *, u32_t);\r
+static int  ip_addr_check (u32_t, struct wordlist *);\r
+#if 0 /* PAP_SUPPORT > 0 || CHAP_SUPPORT > 0 */\r
+static void set_allowed_addrs(int unit, struct wordlist *addrs);\r
+static void free_wordlist (struct wordlist *);\r
+#endif\r
+#if CBCP_SUPPORT > 0\r
+static void callback_phase (int);\r
+#endif\r
+\r
+\r
+/******************************/\r
+/*** PUBLIC DATA STRUCTURES ***/\r
+/******************************/\r
+\r
+\r
+/*****************************/\r
+/*** LOCAL DATA STRUCTURES ***/\r
+/*****************************/\r
+#if PAP_SUPPORT > 0 || CHAP_SUPPORT > 0\r
+/* The name by which the peer authenticated itself to us. */\r
+static char peer_authname[MAXNAMELEN];\r
+#endif\r
+\r
+/* Records which authentication operations haven't completed yet. */\r
+static int auth_pending[NUM_PPP];\r
+\r
+/* Set if we have successfully called login() */\r
+static int logged_in;\r
+\r
+/* Set if we have run the /etc/ppp/auth-up script. */\r
+static int did_authup;\r
+\r
+/* List of addresses which the peer may use. */\r
+static struct wordlist *addresses[NUM_PPP];\r
+\r
+/* Number of network protocols which we have opened. */\r
+static int num_np_open;\r
+\r
+/* Number of network protocols which have come up. */\r
+static int num_np_up;\r
+\r
+#if PAP_SUPPORT > 0 || CHAP_SUPPORT > 0\r
+/* Set if we got the contents of passwd[] from the pap-secrets file. */\r
+static int passwd_from_file;\r
+#endif\r
+\r
+\r
+\r
+/***********************************/\r
+/*** PUBLIC FUNCTION DEFINITIONS ***/\r
+/***********************************/\r
+/*\r
+ * An Open on LCP has requested a change from Dead to Establish phase.\r
+ * Do what's necessary to bring the physical layer up.\r
+ */\r
+void link_required(int unit)\r
+{\r
+    AUTHDEBUG((LOG_INFO, "link_required: %d\n", unit));\r
+}\r
+\r
+/*\r
+ * LCP has terminated the link; go to the Dead phase and take the\r
+ * physical layer down.\r
+ */\r
+void link_terminated(int unit)\r
+{\r
+    AUTHDEBUG((LOG_INFO, "link_terminated: %d\n", unit));\r
+    \r
+    if (lcp_phase[unit] == PHASE_DEAD)\r
+        return;\r
+    if (logged_in)\r
+        logout();\r
+    lcp_phase[unit] = PHASE_DEAD;\r
+    AUTHDEBUG((LOG_NOTICE, "Connection terminated.\n"));\r
+       pppMainWakeup(unit);\r
+}\r
+\r
+/*\r
+ * LCP has gone down; it will either die or try to re-establish.\r
+ */\r
+void link_down(int unit)\r
+{\r
+    int i;\r
+    struct protent *protp;\r
+    \r
+    AUTHDEBUG((LOG_INFO, "link_down: %d\n", unit));\r
+    if (did_authup) {\r
+        /* XXX Do link down processing. */\r
+        did_authup = 0;\r
+    }\r
+    for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i) {\r
+        if (!protp->enabled_flag)\r
+            continue;\r
+        if (protp->protocol != PPP_LCP && protp->lowerdown != NULL)\r
+            (*protp->lowerdown)(unit);\r
+        if (protp->protocol < 0xC000 && protp->close != NULL)\r
+            (*protp->close)(unit, "LCP down");\r
+    }\r
+    num_np_open = 0;\r
+    num_np_up = 0;\r
+    if (lcp_phase[unit] != PHASE_DEAD)\r
+        lcp_phase[unit] = PHASE_TERMINATE;\r
+       pppMainWakeup(unit);\r
+}\r
+\r
+/*\r
+ * The link is established.\r
+ * Proceed to the Dead, Authenticate or Network phase as appropriate.\r
+ */\r
+void link_established(int unit)\r
+{\r
+    int auth;\r
+    int i;\r
+    struct protent *protp;\r
+    lcp_options *wo = &lcp_wantoptions[unit];\r
+    lcp_options *go = &lcp_gotoptions[unit];\r
+#if PAP_SUPPORT > 0 || CHAP_SUPPORT > 0\r
+    lcp_options *ho = &lcp_hisoptions[unit];\r
+#endif\r
+    \r
+    AUTHDEBUG((LOG_INFO, "link_established: %d\n", unit));\r
+    /*\r
+     * Tell higher-level protocols that LCP is up.\r
+     */\r
+    for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i)\r
+        if (protp->protocol != PPP_LCP && protp->enabled_flag\r
+                && protp->lowerup != NULL)\r
+            (*protp->lowerup)(unit);\r
+    \r
+    if (ppp_settings.auth_required && !(go->neg_chap || go->neg_upap)) {\r
+        /*\r
+         * We wanted the peer to authenticate itself, and it refused:\r
+         * treat it as though it authenticated with PAP using a username\r
+         * of "" and a password of "".  If that's not OK, boot it out.\r
+         */\r
+        if (!wo->neg_upap || !null_login(unit)) {\r
+            AUTHDEBUG((LOG_WARNING, "peer refused to authenticate\n"));\r
+            lcp_close(unit, "peer refused to authenticate");\r
+            return;\r
+        }\r
+    }\r
+    \r
+    lcp_phase[unit] = PHASE_AUTHENTICATE;\r
+    auth = 0;\r
+#if CHAP_SUPPORT > 0\r
+    if (go->neg_chap) {\r
+        ChapAuthPeer(unit, ppp_settings.our_name, go->chap_mdtype);\r
+        auth |= CHAP_PEER;\r
+    } \r
+#endif\r
+#if PAP_SUPPORT > 0 && CHAP_SUPPORT > 0\r
+    else\r
+#endif\r
+#if PAP_SUPPORT > 0\r
+    if (go->neg_upap) {\r
+        upap_authpeer(unit);\r
+        auth |= PAP_PEER;\r
+    }\r
+#endif\r
+#if CHAP_SUPPORT > 0\r
+    if (ho->neg_chap) {\r
+        ChapAuthWithPeer(unit, ppp_settings.user, ho->chap_mdtype);\r
+        auth |= CHAP_WITHPEER;\r
+    }\r
+#endif\r
+#if PAP_SUPPORT > 0 && CHAP_SUPPORT > 0\r
+    else\r
+#endif\r
+#if PAP_SUPPORT > 0\r
+    if (ho->neg_upap) {\r
+        if (ppp_settings.passwd[0] == 0) {\r
+            passwd_from_file = 1;\r
+            if (!get_pap_passwd(unit, ppp_settings.user, ppp_settings.passwd))\r
+                AUTHDEBUG((LOG_ERR, "No secret found for PAP login\n"));\r
+        }\r
+        upap_authwithpeer(unit, ppp_settings.user, ppp_settings.passwd);\r
+        auth |= PAP_WITHPEER;\r
+    }\r
+#endif\r
+    auth_pending[unit] = auth;\r
+    \r
+    if (!auth)\r
+        network_phase(unit);\r
+}\r
+\r
+\r
+/*\r
+ * The peer has failed to authenticate himself using `protocol'.\r
+ */\r
+void auth_peer_fail(int unit, u16_t protocol)\r
+{\r
+    AUTHDEBUG((LOG_INFO, "auth_peer_fail: %d proto=%X\n", unit, protocol));\r
+    /*\r
+     * Authentication failure: take the link down\r
+     */\r
+    lcp_close(unit, "Authentication failed");\r
+}\r
+\r
+\r
+#if PAP_SUPPORT > 0 || CHAP_SUPPORT > 0\r
+/*\r
+ * The peer has been successfully authenticated using `protocol'.\r
+ */\r
+void auth_peer_success(int unit, u16_t protocol, char *name, int namelen)\r
+{\r
+    int pbit;\r
+    \r
+    AUTHDEBUG((LOG_INFO, "auth_peer_success: %d proto=%X\n", unit, protocol));\r
+    switch (protocol) {\r
+    case PPP_CHAP:\r
+        pbit = CHAP_PEER;\r
+        break;\r
+    case PPP_PAP:\r
+        pbit = PAP_PEER;\r
+        break;\r
+    default:\r
+        AUTHDEBUG((LOG_WARNING, "auth_peer_success: unknown protocol %x\n",\r
+               protocol));\r
+        return;\r
+    }\r
+    \r
+    /*\r
+     * Save the authenticated name of the peer for later.\r
+     */\r
+    if (namelen > sizeof(peer_authname) - 1)\r
+        namelen = sizeof(peer_authname) - 1;\r
+    BCOPY(name, peer_authname, namelen);\r
+    peer_authname[namelen] = 0;\r
+    \r
+    /*\r
+     * If there is no more authentication still to be done,\r
+     * proceed to the network (or callback) phase.\r
+     */\r
+    if ((auth_pending[unit] &= ~pbit) == 0)\r
+        network_phase(unit);\r
+}\r
+\r
+/*\r
+ * We have failed to authenticate ourselves to the peer using `protocol'.\r
+ */\r
+void auth_withpeer_fail(int unit, u16_t protocol)\r
+{\r
+    int errCode = PPPERR_AUTHFAIL;\r
+    \r
+    AUTHDEBUG((LOG_INFO, "auth_withpeer_fail: %d proto=%X\n", unit, protocol));\r
+    if (passwd_from_file)\r
+        BZERO(ppp_settings.passwd, MAXSECRETLEN);\r
+    /* \r
+     * XXX Warning: the unit number indicates the interface which is\r
+     * not necessarily the PPP connection.  It works here as long\r
+     * as we are only supporting PPP interfaces.\r
+     */\r
+    pppIOCtl(unit, PPPCTLS_ERRCODE, &errCode);\r
+\r
+    /*\r
+     * We've failed to authenticate ourselves to our peer.\r
+     * He'll probably take the link down, and there's not much\r
+     * we can do except wait for that.\r
+     */\r
+}\r
+\r
+/*\r
+ * We have successfully authenticated ourselves with the peer using `protocol'.\r
+ */\r
+void auth_withpeer_success(int unit, u16_t protocol)\r
+{\r
+    int pbit;\r
+    \r
+    AUTHDEBUG((LOG_INFO, "auth_withpeer_success: %d proto=%X\n", unit, protocol));\r
+    switch (protocol) {\r
+    case PPP_CHAP:\r
+        pbit = CHAP_WITHPEER;\r
+        break;\r
+    case PPP_PAP:\r
+        if (passwd_from_file)\r
+            BZERO(ppp_settings.passwd, MAXSECRETLEN);\r
+        pbit = PAP_WITHPEER;\r
+        break;\r
+    default:\r
+        AUTHDEBUG((LOG_WARNING, "auth_peer_success: unknown protocol %x\n",\r
+               protocol));\r
+        pbit = 0;\r
+    }\r
+    \r
+    /*\r
+     * If there is no more authentication still being done,\r
+     * proceed to the network (or callback) phase.\r
+     */\r
+    if ((auth_pending[unit] &= ~pbit) == 0)\r
+        network_phase(unit);\r
+}\r
+#endif\r
+\r
+\r
+/*\r
+ * np_up - a network protocol has come up.\r
+ */\r
+void np_up(int unit, u16_t proto)\r
+{\r
+    AUTHDEBUG((LOG_INFO, "np_up: %d proto=%X\n", unit, proto));\r
+    if (num_np_up == 0) {\r
+       AUTHDEBUG((LOG_INFO, "np_up: maxconnect=%d idle_time_limit=%d\n",ppp_settings.maxconnect,ppp_settings.idle_time_limit));\r
+        /*\r
+         * At this point we consider that the link has come up successfully.\r
+         */\r
+        if (ppp_settings.idle_time_limit > 0)\r
+            TIMEOUT(check_idle, NULL, ppp_settings.idle_time_limit);\r
+        \r
+        /*\r
+         * Set a timeout to close the connection once the maximum\r
+         * connect time has expired.\r
+         */\r
+        if (ppp_settings.maxconnect > 0)\r
+            TIMEOUT(connect_time_expired, 0, ppp_settings.maxconnect);\r
+    }\r
+    ++num_np_up;\r
+}\r
+\r
+/*\r
+ * np_down - a network protocol has gone down.\r
+ */\r
+void np_down(int unit, u16_t proto)\r
+{\r
+    AUTHDEBUG((LOG_INFO, "np_down: %d proto=%X\n", unit, proto));\r
+    if (--num_np_up == 0 && ppp_settings.idle_time_limit > 0) {\r
+        UNTIMEOUT(check_idle, NULL);\r
+    }\r
+}\r
+\r
+/*\r
+ * np_finished - a network protocol has finished using the link.\r
+ */\r
+void np_finished(int unit, u16_t proto)\r
+{\r
+    AUTHDEBUG((LOG_INFO, "np_finished: %d proto=%X\n", unit, proto));\r
+    if (--num_np_open <= 0) {\r
+        /* no further use for the link: shut up shop. */\r
+        lcp_close(0, "No network protocols running");\r
+    }\r
+}\r
+\r
+/*\r
+ * auth_reset - called when LCP is starting negotiations to recheck\r
+ * authentication options, i.e. whether we have appropriate secrets\r
+ * to use for authenticating ourselves and/or the peer.\r
+ */\r
+void auth_reset(int unit)\r
+{\r
+    lcp_options *go = &lcp_gotoptions[unit];\r
+    lcp_options *ao = &lcp_allowoptions[0];\r
+    ipcp_options *ipwo = &ipcp_wantoptions[0];\r
+    u32_t remote;\r
+    \r
+    AUTHDEBUG((LOG_INFO, "auth_reset: %d\n", unit));\r
+    ao->neg_upap = !ppp_settings.refuse_pap && (ppp_settings.passwd[0] != 0 || get_pap_passwd(unit, NULL, NULL));\r
+    ao->neg_chap = !ppp_settings.refuse_chap && ppp_settings.passwd[0] != 0 /*have_chap_secret(ppp_settings.user, ppp_settings.remote_name, (u32_t)0)*/;\r
+    \r
+    if (go->neg_upap && !have_pap_secret())\r
+        go->neg_upap = 0;\r
+    if (go->neg_chap) {\r
+        remote = ipwo->accept_remote? 0: ipwo->hisaddr;\r
+        if (!have_chap_secret(ppp_settings.remote_name, ppp_settings.our_name, remote))\r
+            go->neg_chap = 0;\r
+    }\r
+}\r
+\r
+\r
+#if PAP_SUPPORT > 0\r
+/*\r
+ * check_passwd - Check the user name and passwd against the PAP secrets\r
+ * file.  If requested, also check against the system password database,\r
+ * and login the user if OK.\r
+ *\r
+ * returns:\r
+ *  UPAP_AUTHNAK: Authentication failed.\r
+ *  UPAP_AUTHACK: Authentication succeeded.\r
+ * In either case, msg points to an appropriate message.\r
+ */\r
+int check_passwd(\r
+       int unit,\r
+       char *auser,\r
+       int userlen,\r
+       char *apasswd,\r
+       int passwdlen,\r
+       char **msg,\r
+       int *msglen\r
+)\r
+{\r
+#if 1\r
+       *msg = (char *) 0;\r
+       return UPAP_AUTHACK;     /* XXX Assume all entries OK. */\r
+#else\r
+    int ret = 0;\r
+    struct wordlist *addrs = NULL;\r
+    char passwd[256], user[256];\r
+    char secret[MAXWORDLEN];\r
+    static u_short attempts = 0;\r
+    \r
+    /*\r
+     * Make copies of apasswd and auser, then null-terminate them.\r
+     */\r
+    BCOPY(apasswd, passwd, passwdlen);\r
+    passwd[passwdlen] = '\0';\r
+    BCOPY(auser, user, userlen);\r
+    user[userlen] = '\0';\r
+    *msg = (char *) 0;\r
+\r
+    /* XXX Validate user name and password. */\r
+    ret = UPAP_AUTHACK;     /* XXX Assume all entries OK. */\r
+        \r
+    if (ret == UPAP_AUTHNAK) {\r
+        if (*msg == (char *) 0)\r
+            *msg = "Login incorrect";\r
+        *msglen = strlen(*msg);\r
+        /*\r
+         * Frustrate passwd stealer programs.\r
+         * Allow 10 tries, but start backing off after 3 (stolen from login).\r
+         * On 10'th, drop the connection.\r
+         */\r
+        if (attempts++ >= 10) {\r
+            AUTHDEBUG((LOG_WARNING, "%d LOGIN FAILURES BY %s\n", attempts, user));\r
+            /*ppp_panic("Excess Bad Logins");*/\r
+        }\r
+        if (attempts > 3) {\r
+            sys_msleep((attempts - 3) * 5);\r
+        }\r
+        if (addrs != NULL) {\r
+            free_wordlist(addrs);\r
+        }\r
+    } else {\r
+        attempts = 0;           /* Reset count */\r
+        if (*msg == (char *) 0)\r
+            *msg = "Login ok";\r
+        *msglen = strlen(*msg);\r
+        set_allowed_addrs(unit, addrs);\r
+    }\r
+    \r
+    BZERO(passwd, sizeof(passwd));\r
+    BZERO(secret, sizeof(secret));\r
+    \r
+    return ret;\r
+#endif\r
+}\r
+#endif\r
+\r
+\r
+/*\r
+ * auth_ip_addr - check whether the peer is authorized to use\r
+ * a given IP address.  Returns 1 if authorized, 0 otherwise.\r
+ */\r
+int auth_ip_addr(int unit, u32_t addr)\r
+{\r
+    return ip_addr_check(addr, addresses[unit]);\r
+}\r
+\r
+/*\r
+ * bad_ip_adrs - return 1 if the IP address is one we don't want\r
+ * to use, such as an address in the loopback net or a multicast address.\r
+ * addr is in network byte order.\r
+ */\r
+int bad_ip_adrs(u32_t addr)\r
+{\r
+    addr = ntohl(addr);\r
+    return (addr >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET\r
+        || IN_MULTICAST(addr) || IN_BADCLASS(addr);\r
+}\r
+\r
+\r
+#if CHAP_SUPPORT > 0\r
+/*\r
+ * get_secret - open the CHAP secret file and return the secret\r
+ * for authenticating the given client on the given server.\r
+ * (We could be either client or server).\r
+ */\r
+int get_secret(\r
+    int unit,\r
+    char *client,\r
+    char *server,\r
+    char *secret,\r
+    int *secret_len,\r
+    int save_addrs\r
+)\r
+{\r
+#if 1\r
+    int len;\r
+    struct wordlist *addrs;\r
+    \r
+    addrs = NULL;\r
+\r
+    if(!client || !client[0] || strcmp(client, ppp_settings.user)) {\r
+       return 0;\r
+    }\r
+\r
+    len = strlen(ppp_settings.passwd);\r
+    if (len > MAXSECRETLEN) {\r
+        AUTHDEBUG((LOG_ERR, "Secret for %s on %s is too long\n", client, server));\r
+        len = MAXSECRETLEN;\r
+    }\r
+    BCOPY(ppp_settings.passwd, secret, len);\r
+    *secret_len = len;\r
+    \r
+    return 1;\r
+#else\r
+    int ret = 0, len;\r
+    struct wordlist *addrs;\r
+    char secbuf[MAXWORDLEN];\r
+    \r
+    addrs = NULL;\r
+    secbuf[0] = 0;\r
+\r
+    /* XXX Find secret. */  \r
+    if (ret < 0)\r
+        return 0;\r
+    \r
+    if (save_addrs)\r
+        set_allowed_addrs(unit, addrs);\r
+    \r
+    len = strlen(secbuf);\r
+    if (len > MAXSECRETLEN) {\r
+        AUTHDEBUG((LOG_ERR, "Secret for %s on %s is too long\n", client, server));\r
+        len = MAXSECRETLEN;\r
+    }\r
+    BCOPY(secbuf, secret, len);\r
+    BZERO(secbuf, sizeof(secbuf));\r
+    *secret_len = len;\r
+    \r
+    return 1;\r
+#endif\r
+}\r
+#endif\r
+\r
+\r
+#if 0 /* UNUSED */\r
+/*\r
+ * auth_check_options - called to check authentication options.\r
+ */\r
+void auth_check_options(void)\r
+{\r
+    lcp_options *wo = &lcp_wantoptions[0];\r
+    int can_auth;\r
+    ipcp_options *ipwo = &ipcp_wantoptions[0];\r
+    u32_t remote;\r
+    \r
+    /* Default our_name to hostname, and user to our_name */\r
+    if (ppp_settings.our_name[0] == 0 || ppp_settings.usehostname)\r
+        strcpy(ppp_settings.our_name, ppp_settings.hostname);\r
+    if (ppp_settings.user[0] == 0)\r
+        strcpy(ppp_settings.user, ppp_settings.our_name);\r
+    \r
+    /* If authentication is required, ask peer for CHAP or PAP. */\r
+    if (ppp_settings.auth_required && !wo->neg_chap && !wo->neg_upap) {\r
+        wo->neg_chap = 1;\r
+        wo->neg_upap = 1;\r
+    }\r
+    \r
+    /*\r
+     * Check whether we have appropriate secrets to use\r
+     * to authenticate the peer.\r
+     */\r
+    can_auth = wo->neg_upap && have_pap_secret();\r
+    if (!can_auth && wo->neg_chap) {\r
+        remote = ipwo->accept_remote? 0: ipwo->hisaddr;\r
+        can_auth = have_chap_secret(ppp_settings.remote_name, ppp_settings.our_name, remote);\r
+    }\r
+    \r
+    if (ppp_settings.auth_required && !can_auth) {\r
+        ppp_panic("No auth secret");\r
+    }\r
+}\r
+#endif\r
+\r
+\r
+/**********************************/\r
+/*** LOCAL FUNCTION DEFINITIONS ***/\r
+/**********************************/\r
+/*\r
+ * Proceed to the network phase.\r
+ */\r
+static void network_phase(int unit)\r
+{\r
+    int i;\r
+    struct protent *protp;\r
+    lcp_options *go = &lcp_gotoptions[unit];\r
+    \r
+    /*\r
+     * If the peer had to authenticate, run the auth-up script now.\r
+     */\r
+    if ((go->neg_chap || go->neg_upap) && !did_authup) {\r
+        /* XXX Do setup for peer authentication. */\r
+        did_authup = 1;\r
+    }\r
+    \r
+#if CBCP_SUPPORT > 0\r
+    /*\r
+     * If we negotiated callback, do it now.\r
+     */\r
+    if (go->neg_cbcp) {\r
+        lcp_phase[unit] = PHASE_CALLBACK;\r
+        (*cbcp_protent.open)(unit);\r
+        return;\r
+    }\r
+#endif\r
+    \r
+    lcp_phase[unit] = PHASE_NETWORK;\r
+    for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i)\r
+        if (protp->protocol < 0xC000 && protp->enabled_flag\r
+                && protp->open != NULL) {\r
+            (*protp->open)(unit);\r
+            if (protp->protocol != PPP_CCP)\r
+                ++num_np_open;\r
+        }\r
+    \r
+    if (num_np_open == 0)\r
+        /* nothing to do */\r
+        lcp_close(0, "No network protocols running");\r
+}\r
+\r
+/*\r
+ * check_idle - check whether the link has been idle for long\r
+ * enough that we can shut it down.\r
+ */\r
+static void check_idle(void *arg)\r
+{\r
+    struct ppp_idle idle;\r
+    u_short itime;\r
+    \r
+       (void)arg;\r
+    if (!get_idle_time(0, &idle))\r
+        return;\r
+    itime = LWIP_MIN(idle.xmit_idle, idle.recv_idle);\r
+    if (itime >= ppp_settings.idle_time_limit) {\r
+        /* link is idle: shut it down. */\r
+        AUTHDEBUG((LOG_INFO, "Terminating connection due to lack of activity.\n"));\r
+        lcp_close(0, "Link inactive");\r
+    } else {\r
+        TIMEOUT(check_idle, NULL, ppp_settings.idle_time_limit - itime);\r
+    }\r
+}\r
+\r
+/*\r
+ * connect_time_expired - log a message and close the connection.\r
+ */\r
+static void connect_time_expired(void *arg)\r
+{\r
+       (void)arg;\r
+\r
+    AUTHDEBUG((LOG_INFO, "Connect time expired\n"));\r
+    lcp_close(0, "Connect time expired");   /* Close connection */\r
+}\r
+\r
+#if 0\r
+/*\r
+ * login - Check the user name and password against the system\r
+ * password database, and login the user if OK.\r
+ *\r
+ * returns:\r
+ *  UPAP_AUTHNAK: Login failed.\r
+ *  UPAP_AUTHACK: Login succeeded.\r
+ * In either case, msg points to an appropriate message.\r
+ */\r
+static int login(char *user, char *passwd, char **msg, int *msglen)\r
+{\r
+    /* XXX Fail until we decide that we want to support logins. */\r
+    return (UPAP_AUTHNAK);\r
+}\r
+#endif\r
+\r
+/*\r
+ * logout - Logout the user.\r
+ */\r
+static void logout(void)\r
+{\r
+    logged_in = 0;\r
+}\r
+\r
+\r
+/*\r
+ * null_login - Check if a username of "" and a password of "" are\r
+ * acceptable, and iff so, set the list of acceptable IP addresses\r
+ * and return 1.\r
+ */\r
+static int null_login(int unit)\r
+{\r
+       (void)unit;\r
+    /* XXX Fail until we decide that we want to support logins. */\r
+    return 0;\r
+}\r
+\r
+\r
+/*\r
+ * get_pap_passwd - get a password for authenticating ourselves with\r
+ * our peer using PAP.  Returns 1 on success, 0 if no suitable password\r
+ * could be found.\r
+ */\r
+static int get_pap_passwd(int unit, char *user, char *passwd)\r
+{\r
+/* normally we would reject PAP if no password is provided,\r
+   but this causes problems with some providers (like CHT in Taiwan)\r
+   who incorrectly request PAP and expect a bogus/empty password, so\r
+   always provide a default user/passwd of "none"/"none"\r
+*/\r
+    if(user)\r
+       strcpy(user,   "none");\r
+    if(passwd)\r
+       strcpy(passwd, "none");\r
+\r
+    return 1;\r
+}\r
+\r
+\r
+/*\r
+ * have_pap_secret - check whether we have a PAP file with any\r
+ * secrets that we could possibly use for authenticating the peer.\r
+ */\r
+static int have_pap_secret(void)\r
+{\r
+    /* XXX Fail until we set up our passwords. */\r
+    return 0;\r
+}\r
+\r
+\r
+/*\r
+ * have_chap_secret - check whether we have a CHAP file with a\r
+ * secret that we could possibly use for authenticating `client'\r
+ * on `server'.  Either can be the null string, meaning we don't\r
+ * know the identity yet.\r
+ */\r
+static int have_chap_secret(char *client, char *server, u32_t remote)\r
+{\r
+       (void)client;\r
+       (void)server;\r
+       (void)remote;\r
+    /* XXX Fail until we set up our passwords. */\r
+    return 0;\r
+}\r
+\r
+\r
+#if 0 /* PAP_SUPPORT > 0 || CHAP_SUPPORT > 0 */\r
+/*\r
+ * set_allowed_addrs() - set the list of allowed addresses.\r
+ */\r
+static void set_allowed_addrs(int unit, struct wordlist *addrs)\r
+{\r
+    if (addresses[unit] != NULL)\r
+        free_wordlist(addresses[unit]);\r
+    addresses[unit] = addrs;\r
+\r
+#if 0\r
+    /*\r
+     * If there's only one authorized address we might as well\r
+     * ask our peer for that one right away\r
+     */\r
+    if (addrs != NULL && addrs->next == NULL) {\r
+        char *p = addrs->word;\r
+        struct ipcp_options *wo = &ipcp_wantoptions[unit];\r
+        u32_t a;\r
+        struct hostent *hp;\r
+        \r
+        if (wo->hisaddr == 0 && *p != '!' && *p != '-'\r
+                && strchr(p, '/') == NULL) {\r
+            hp = gethostbyname(p);\r
+            if (hp != NULL && hp->h_addrtype == AF_INET)\r
+                a = *(u32_t *)hp->h_addr;\r
+            else\r
+                a = inet_addr(p);\r
+            if (a != (u32_t) -1)\r
+                wo->hisaddr = a;\r
+        }\r
+    }\r
+#endif\r
+}\r
+#endif\r
+\r
+static int ip_addr_check(u32_t addr, struct wordlist *addrs)\r
+{\r
+    \r
+    /* don't allow loopback or multicast address */\r
+    if (bad_ip_adrs(addr))\r
+        return 0;\r
+    \r
+    if (addrs == NULL)\r
+        return !ppp_settings.auth_required;      /* no addresses authorized */\r
+    \r
+    /* XXX All other addresses allowed. */\r
+    return 1;\r
+}\r
+\r
+#if 0 /* PAP_SUPPORT > 0 || CHAP_SUPPORT */\r
+/*\r
+ * free_wordlist - release memory allocated for a wordlist.\r
+ */\r
+static void free_wordlist(struct wordlist *wp)\r
+{\r
+    struct wordlist *next;\r
+    \r
+    while (wp != NULL) {\r
+        next = wp->next;\r
+        free(wp);\r
+        wp = next;\r
+    }\r
+}\r
+#endif\r
+\r
+#endif /* PPP_SUPPORT */\r
index d6a5de5b79a6c6eec007a25a3bc139ad7db047bd..58174056c5bfd8a7aaa07d76a6a8cd1276be0f09 100644 (file)
@@ -1,94 +1,94 @@
-/*****************************************************************************
-* auth.h -  PPP Authentication and phase control header file.
-*
-* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
-* portions Copyright (c) 1998 Global Election Systems Inc.
-*
-* The authors hereby grant permission to use, copy, modify, distribute,
-* and license this software and its documentation for any purpose, provided
-* that existing copyright notices are retained in all copies and that this
-* notice and the following disclaimer are included verbatim in any 
-* distributions. No written agreement, license, or royalty fee is required
-* for any of the authorized uses.
-*
-* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *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 CONTRIBUTORS 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.
-*
-******************************************************************************
-* REVISION HISTORY
-*
-* 03-01-01 Marc Boucher <marc@mbsi.ca>
-*   Ported to lwIP.
-* 97-12-04 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
-*      Original derived from BSD pppd.h.
-*****************************************************************************/
-/*
- * pppd.h - PPP daemon global declarations.
- *
- * Copyright (c) 1989 Carnegie Mellon University.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by Carnegie Mellon University.  The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- */
-
-#ifndef AUTH_H
-#define AUTH_H
-
-/***********************
-*** PUBLIC FUNCTIONS ***
-***********************/
-void link_required (int);              /* we are starting to use the link */
-void link_terminated (int);    /* we are finished with the link */
-void link_down (int);                  /* the LCP layer has left the Opened state */
-void link_established (int);   /* the link is up; authenticate now */
-void np_up (int, u16_t);                       /* a network protocol has come up */
-void np_down (int, u16_t);             /* a network protocol has gone down */
-void np_finished (int, u16_t); /* a network protocol no longer needs link */
-void auth_peer_fail (int, u16_t);/* peer failed to authenticate itself */
-
-/* peer successfully authenticated itself */
-void auth_peer_success (int, u16_t, char *, int);
-
-/* we failed to authenticate ourselves */
-void auth_withpeer_fail (int, u16_t);
-
-/* we successfully authenticated ourselves */
-void auth_withpeer_success (int, u16_t);
-
-/* check authentication options supplied */
-void auth_check_options (void);
-void auth_reset (int);                 /* check what secrets we have */
-
-/* Check peer-supplied username/password */
-int  check_passwd (int, char *, int, char *, int, char **, int *);
-
-/* get "secret" for chap */
-int  get_secret (int, char *, char *, char *, int *, int);
-
-/* check if IP address is authorized */
-int  auth_ip_addr (int, u32_t);
-
-/* check if IP address is unreasonable */
-int  bad_ip_adrs (u32_t);
-
-
-#endif /* AUTH_H */
+/*****************************************************************************\r
+* auth.h -  PPP Authentication and phase control header file.\r
+*\r
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.\r
+* portions Copyright (c) 1998 Global Election Systems Inc.\r
+*\r
+* The authors hereby grant permission to use, copy, modify, distribute,\r
+* and license this software and its documentation for any purpose, provided\r
+* that existing copyright notices are retained in all copies and that this\r
+* notice and the following disclaimer are included verbatim in any \r
+* distributions. No written agreement, license, or royalty fee is required\r
+* for any of the authorized uses.\r
+*\r
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR\r
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+*\r
+******************************************************************************\r
+* REVISION HISTORY\r
+*\r
+* 03-01-01 Marc Boucher <marc@mbsi.ca>\r
+*   Ported to lwIP.\r
+* 97-12-04 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.\r
+*      Original derived from BSD pppd.h.\r
+*****************************************************************************/\r
+/*\r
+ * pppd.h - PPP daemon global declarations.\r
+ *\r
+ * Copyright (c) 1989 Carnegie Mellon University.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms are permitted\r
+ * provided that the above copyright notice and this paragraph are\r
+ * duplicated in all such forms and that any documentation,\r
+ * advertising materials, and other materials related to such\r
+ * distribution and use acknowledge that the software was developed\r
+ * by Carnegie Mellon University.  The name of the\r
+ * University may not be used to endorse or promote products derived\r
+ * from this software without specific prior written permission.\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR\r
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r
+ *\r
+ */\r
+\r
+#ifndef AUTH_H\r
+#define AUTH_H\r
+\r
+/***********************\r
+*** PUBLIC FUNCTIONS ***\r
+***********************/\r
+void link_required (int);              /* we are starting to use the link */\r
+void link_terminated (int);    /* we are finished with the link */\r
+void link_down (int);                  /* the LCP layer has left the Opened state */\r
+void link_established (int);   /* the link is up; authenticate now */\r
+void np_up (int, u16_t);                       /* a network protocol has come up */\r
+void np_down (int, u16_t);             /* a network protocol has gone down */\r
+void np_finished (int, u16_t); /* a network protocol no longer needs link */\r
+void auth_peer_fail (int, u16_t);/* peer failed to authenticate itself */\r
+\r
+/* peer successfully authenticated itself */\r
+void auth_peer_success (int, u16_t, char *, int);\r
+\r
+/* we failed to authenticate ourselves */\r
+void auth_withpeer_fail (int, u16_t);\r
+\r
+/* we successfully authenticated ourselves */\r
+void auth_withpeer_success (int, u16_t);\r
+\r
+/* check authentication options supplied */\r
+void auth_check_options (void);\r
+void auth_reset (int);                 /* check what secrets we have */\r
+\r
+/* Check peer-supplied username/password */\r
+int  check_passwd (int, char *, int, char *, int, char **, int *);\r
+\r
+/* get "secret" for chap */\r
+int  get_secret (int, char *, char *, char *, int *, int);\r
+\r
+/* check if IP address is authorized */\r
+int  auth_ip_addr (int, u32_t);\r
+\r
+/* check if IP address is unreasonable */\r
+int  bad_ip_adrs (u32_t);\r
+\r
+\r
+#endif /* AUTH_H */\r
index 4d1dc0d245b3d8203062baa358fe95cf5ca9d8f7..30441bdc8328b211a920f05e9932bee53c9dea83 100644 (file)
-/*** WARNING - THIS HAS NEVER BEEN FINISHED ***/
-/*****************************************************************************
-* chap.c - Network Challenge Handshake Authentication Protocol program file.
-*
-* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
-* portions Copyright (c) 1997 by Global Election Systems Inc.
-*
-* The authors hereby grant permission to use, copy, modify, distribute,
-* and license this software and its documentation for any purpose, provided
-* that existing copyright notices are retained in all copies and that this
-* notice and the following disclaimer are included verbatim in any 
-* distributions. No written agreement, license, or royalty fee is required
-* for any of the authorized uses.
-*
-* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *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 CONTRIBUTORS 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.
-*
-******************************************************************************
-* REVISION HISTORY
-*
-* 03-01-01 Marc Boucher <marc@mbsi.ca>
-*   Ported to lwIP.
-* 97-12-04 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
-*      Original based on BSD chap.c.
-*****************************************************************************/
-/*
- * chap.c - Challenge Handshake Authentication Protocol.
- *
- * Copyright (c) 1993 The Australian National University.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the Australian National University.  The name of the University
- * may not be used to endorse or promote products derived from this
- * software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Copyright (c) 1991 Gregory M. Christy.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by Gregory M. Christy.  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 ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include "ppp.h"
-#if PPP_SUPPORT > 0
-#include "magic.h"
-
-#if CHAP_SUPPORT > 0
-
-#include "randm.h"
-#include "auth.h"
-#include "md5.h"
-#include "chap.h"
-#include "chpms.h"
-#include "pppdebug.h"
-
-
-/*************************/
-/*** LOCAL DEFINITIONS ***/
-/*************************/
-
-
-/************************/
-/*** LOCAL DATA TYPES ***/
-/************************/
-
-
-/***********************************/
-/*** LOCAL FUNCTION DECLARATIONS ***/
-/***********************************/
-/*
- * Protocol entry points.
- */
-static void ChapInit (int);
-static void ChapLowerUp (int);
-static void ChapLowerDown (int);
-static void ChapInput (int, u_char *, int);
-static void ChapProtocolReject (int);
-static int  ChapPrintPkt (u_char *, int,
-                             void (*) (void *, char *, ...), void *);
-
-static void ChapChallengeTimeout (void *);
-static void ChapResponseTimeout (void *);
-static void ChapReceiveChallenge (chap_state *, u_char *, int, int);
-static void ChapRechallenge (void *);
-static void ChapReceiveResponse (chap_state *, u_char *, int, int);
-static void ChapReceiveSuccess(chap_state *cstate, u_char *inp, u_char id, int len);
-static void ChapReceiveFailure(chap_state *cstate, u_char *inp, u_char id, int len);
-static void ChapSendStatus (chap_state *, int);
-static void ChapSendChallenge (chap_state *);
-static void ChapSendResponse (chap_state *);
-static void ChapGenChallenge (chap_state *);
-
-
-/******************************/
-/*** PUBLIC DATA STRUCTURES ***/
-/******************************/
-chap_state chap[NUM_PPP];              /* CHAP state; one for each unit */
-
-struct protent chap_protent = {
-    PPP_CHAP,
-    ChapInit,
-    ChapInput,
-    ChapProtocolReject,
-    ChapLowerUp,
-    ChapLowerDown,
-    NULL,
-    NULL,
-#if 0
-    ChapPrintPkt,
-    NULL,
-#endif
-    1,
-    "CHAP",
-#if 0
-    NULL,
-    NULL,
-    NULL
-#endif
-};
-
-
-
-/*****************************/
-/*** LOCAL DATA STRUCTURES ***/
-/*****************************/
-static char *ChapCodenames[] = {
-       "Challenge", "Response", "Success", "Failure"
-};
-
-
-
-/***********************************/
-/*** PUBLIC FUNCTION DEFINITIONS ***/
-/***********************************/
-/*
- * ChapAuthWithPeer - Authenticate us with our peer (start client).
- *
- */
-void ChapAuthWithPeer(int unit, char *our_name, int digest)
-{
-       chap_state *cstate = &chap[unit];
-       
-       cstate->resp_name = our_name;
-       cstate->resp_type = digest;
-       
-       if (cstate->clientstate == CHAPCS_INITIAL ||
-                       cstate->clientstate == CHAPCS_PENDING) {
-               /* lower layer isn't up - wait until later */
-               cstate->clientstate = CHAPCS_PENDING;
-               return;
-       }
-       
-       /*
-        * We get here as a result of LCP coming up.
-        * So even if CHAP was open before, we will 
-        * have to re-authenticate ourselves.
-        */
-       cstate->clientstate = CHAPCS_LISTEN;
-}
-
-
-/*
- * ChapAuthPeer - Authenticate our peer (start server).
- */
-void ChapAuthPeer(int unit, char *our_name, int digest)
-{
-       chap_state *cstate = &chap[unit];
-       
-       cstate->chal_name = our_name;
-       cstate->chal_type = digest;
-       
-       if (cstate->serverstate == CHAPSS_INITIAL ||
-                       cstate->serverstate == CHAPSS_PENDING) {
-               /* lower layer isn't up - wait until later */
-               cstate->serverstate = CHAPSS_PENDING;
-               return;
-       }
-       
-       ChapGenChallenge(cstate);
-       ChapSendChallenge(cstate);              /* crank it up dude! */
-       cstate->serverstate = CHAPSS_INITIAL_CHAL;
-}
-
-
-
-
-/**********************************/
-/*** LOCAL FUNCTION DEFINITIONS ***/
-/**********************************/
-/*
- * ChapInit - Initialize a CHAP unit.
- */
-static void ChapInit(int unit)
-{
-       chap_state *cstate = &chap[unit];
-       
-       BZERO(cstate, sizeof(*cstate));
-       cstate->unit = unit;
-       cstate->clientstate = CHAPCS_INITIAL;
-       cstate->serverstate = CHAPSS_INITIAL;
-       cstate->timeouttime = CHAP_DEFTIMEOUT;
-       cstate->max_transmits = CHAP_DEFTRANSMITS;
-       /* random number generator is initialized in magic_init */
-}
-
-
-/*
- * ChapChallengeTimeout - Timeout expired on sending challenge.
- */
-static void ChapChallengeTimeout(void *arg)
-{
-       chap_state *cstate = (chap_state *) arg;
-       
-       /* if we aren't sending challenges, don't worry.  then again we */
-       /* probably shouldn't be here either */
-       if (cstate->serverstate != CHAPSS_INITIAL_CHAL &&
-                       cstate->serverstate != CHAPSS_RECHALLENGE)
-               return;
-       
-       if (cstate->chal_transmits >= cstate->max_transmits) {
-               /* give up on peer */
-               CHAPDEBUG((LOG_ERR, "Peer failed to respond to CHAP challenge\n"));
-               cstate->serverstate = CHAPSS_BADAUTH;
-               auth_peer_fail(cstate->unit, PPP_CHAP);
-               return;
-       }
-       
-       ChapSendChallenge(cstate);              /* Re-send challenge */
-}
-
-
-/*
- * ChapResponseTimeout - Timeout expired on sending response.
- */
-static void ChapResponseTimeout(void *arg)
-{
-       chap_state *cstate = (chap_state *) arg;
-       
-       /* if we aren't sending a response, don't worry. */
-       if (cstate->clientstate != CHAPCS_RESPONSE)
-               return;
-       
-       ChapSendResponse(cstate);               /* re-send response */
-}
-
-
-/*
- * ChapRechallenge - Time to challenge the peer again.
- */
-static void ChapRechallenge(void *arg)
-{
-       chap_state *cstate = (chap_state *) arg;
-       
-       /* if we aren't sending a response, don't worry. */
-       if (cstate->serverstate != CHAPSS_OPEN)
-               return;
-       
-       ChapGenChallenge(cstate);
-       ChapSendChallenge(cstate);
-       cstate->serverstate = CHAPSS_RECHALLENGE;
-}
-
-
-/*
- * ChapLowerUp - The lower layer is up.
- *
- * Start up if we have pending requests.
- */
-static void ChapLowerUp(int unit)
-{
-       chap_state *cstate = &chap[unit];
-       
-       if (cstate->clientstate == CHAPCS_INITIAL)
-               cstate->clientstate = CHAPCS_CLOSED;
-       else if (cstate->clientstate == CHAPCS_PENDING)
-               cstate->clientstate = CHAPCS_LISTEN;
-       
-       if (cstate->serverstate == CHAPSS_INITIAL)
-               cstate->serverstate = CHAPSS_CLOSED;
-       else if (cstate->serverstate == CHAPSS_PENDING) {
-               ChapGenChallenge(cstate);
-               ChapSendChallenge(cstate);
-               cstate->serverstate = CHAPSS_INITIAL_CHAL;
-       }
-}
-
-
-/*
- * ChapLowerDown - The lower layer is down.
- *
- * Cancel all timeouts.
- */
-static void ChapLowerDown(int unit)
-{
-       chap_state *cstate = &chap[unit];
-       
-       /* Timeout(s) pending?  Cancel if so. */
-       if (cstate->serverstate == CHAPSS_INITIAL_CHAL ||
-                       cstate->serverstate == CHAPSS_RECHALLENGE)
-               UNTIMEOUT(ChapChallengeTimeout, cstate);
-       else if (cstate->serverstate == CHAPSS_OPEN
-                       && cstate->chal_interval != 0)
-               UNTIMEOUT(ChapRechallenge, cstate);
-       if (cstate->clientstate == CHAPCS_RESPONSE)
-               UNTIMEOUT(ChapResponseTimeout, cstate);
-       
-       cstate->clientstate = CHAPCS_INITIAL;
-       cstate->serverstate = CHAPSS_INITIAL;
-}
-
-
-/*
- * ChapProtocolReject - Peer doesn't grok CHAP.
- */
-static void ChapProtocolReject(int unit)
-{
-       chap_state *cstate = &chap[unit];
-       
-       if (cstate->serverstate != CHAPSS_INITIAL &&
-                       cstate->serverstate != CHAPSS_CLOSED)
-               auth_peer_fail(unit, PPP_CHAP);
-       if (cstate->clientstate != CHAPCS_INITIAL &&
-                       cstate->clientstate != CHAPCS_CLOSED)
-               auth_withpeer_fail(unit, PPP_CHAP);
-       ChapLowerDown(unit);            /* shutdown chap */
-}
-
-
-/*
- * ChapInput - Input CHAP packet.
- */
-static void ChapInput(int unit, u_char *inpacket, int packet_len)
-{
-       chap_state *cstate = &chap[unit];
-       u_char *inp;
-       u_char code, id;
-       int len;
-       
-       /*
-        * Parse header (code, id and length).
-        * If packet too short, drop it.
-        */
-       inp = inpacket;
-       if (packet_len < CHAP_HEADERLEN) {
-               CHAPDEBUG((LOG_INFO, "ChapInput: rcvd short header.\n"));
-               return;
-       }
-       GETCHAR(code, inp);
-       GETCHAR(id, inp);
-       GETSHORT(len, inp);
-       if (len < CHAP_HEADERLEN) {
-               CHAPDEBUG((LOG_INFO, "ChapInput: rcvd illegal length.\n"));
-               return;
-       }
-       if (len > packet_len) {
-               CHAPDEBUG((LOG_INFO, "ChapInput: rcvd short packet.\n"));
-               return;
-       }
-       len -= CHAP_HEADERLEN;
-       
-       /*
-        * Action depends on code (as in fact it usually does :-).
-        */
-       switch (code) {
-       case CHAP_CHALLENGE:
-               ChapReceiveChallenge(cstate, inp, id, len);
-               break;
-       
-       case CHAP_RESPONSE:
-               ChapReceiveResponse(cstate, inp, id, len);
-               break;
-       
-       case CHAP_FAILURE:
-               ChapReceiveFailure(cstate, inp, id, len);
-               break;
-       
-       case CHAP_SUCCESS:
-               ChapReceiveSuccess(cstate, inp, id, len);
-               break;
-       
-       default:                                /* Need code reject? */
-               CHAPDEBUG((LOG_WARNING, "Unknown CHAP code (%d) received.\n", code));
-               break;
-       }
-}
-
-
-/*
- * ChapReceiveChallenge - Receive Challenge and send Response.
- */
-static void ChapReceiveChallenge(chap_state *cstate, u_char *inp, int id, int len)
-{
-       int rchallenge_len;
-       u_char *rchallenge;
-       int secret_len;
-       char secret[MAXSECRETLEN];
-       char rhostname[256];
-       MD5_CTX mdContext;
-       u_char hash[MD5_SIGNATURE_SIZE];
-       
-       CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: Rcvd id %d.\n", id));
-       if (cstate->clientstate == CHAPCS_CLOSED ||
-               cstate->clientstate == CHAPCS_PENDING) {
-               CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: in state %d\n",
-                          cstate->clientstate));
-               return;
-       }
-       
-       if (len < 2) {
-               CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: rcvd short packet.\n"));
-               return;
-       }
-       
-       GETCHAR(rchallenge_len, inp);
-       len -= sizeof (u_char) + rchallenge_len;        /* now name field length */
-       if (len < 0) {
-               CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: rcvd short packet.\n"));
-               return;
-       }
-       rchallenge = inp;
-       INCPTR(rchallenge_len, inp);
-       
-       if (len >= sizeof(rhostname))
-               len = sizeof(rhostname) - 1;
-       BCOPY(inp, rhostname, len);
-       rhostname[len] = '\000';
-       
-       CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: received name field '%s'\n",
-              rhostname));
-       
-       /* Microsoft doesn't send their name back in the PPP packet */
-       if (ppp_settings.remote_name[0] != 0 && (ppp_settings.explicit_remote || rhostname[0] == 0)) {
-               strncpy(rhostname, ppp_settings.remote_name, sizeof(rhostname));
-               rhostname[sizeof(rhostname) - 1] = 0;
-               CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: using '%s' as remote name\n",
-                          rhostname));
-       }
-       
-       /* get secret for authenticating ourselves with the specified host */
-       if (!get_secret(cstate->unit, cstate->resp_name, rhostname,
-                           secret, &secret_len, 0)) {
-               secret_len = 0;         /* assume null secret if can't find one */
-               CHAPDEBUG((LOG_WARNING, "No CHAP secret found for authenticating us to %s\n", rhostname));
-       }
-       
-       /* cancel response send timeout if necessary */
-       if (cstate->clientstate == CHAPCS_RESPONSE)
-               UNTIMEOUT(ChapResponseTimeout, cstate);
-       
-       cstate->resp_id = id;
-       cstate->resp_transmits = 0;
-       
-       /*  generate MD based on negotiated type */
-       switch (cstate->resp_type) { 
-       
-       case CHAP_DIGEST_MD5:
-               MD5Init(&mdContext);
-               MD5Update(&mdContext, &cstate->resp_id, 1);
-               MD5Update(&mdContext, (u_char*)secret, secret_len);
-               MD5Update(&mdContext, rchallenge, rchallenge_len);
-               MD5Final(hash, &mdContext);
-               BCOPY(hash, cstate->response, MD5_SIGNATURE_SIZE);
-               cstate->resp_length = MD5_SIGNATURE_SIZE;
-               break;
-       
-#ifdef CHAPMS
-       case CHAP_MICROSOFT:
-               ChapMS(cstate, rchallenge, rchallenge_len, secret, secret_len);
-               break;
-#endif
-       
-       default:
-               CHAPDEBUG((LOG_INFO, "unknown digest type %d\n", cstate->resp_type));
-               return;
-       }
-       
-       BZERO(secret, sizeof(secret));
-       ChapSendResponse(cstate);
-}
-
-
-/*
- * ChapReceiveResponse - Receive and process response.
- */
-static void ChapReceiveResponse(chap_state *cstate, u_char *inp, int id, int len)
-{
-       u_char *remmd, remmd_len;
-       int secret_len, old_state;
-       int code;
-       char rhostname[256];
-       MD5_CTX mdContext;
-       char secret[MAXSECRETLEN];
-       u_char hash[MD5_SIGNATURE_SIZE];
-       
-       CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: Rcvd id %d.\n", id));
-       
-       if (cstate->serverstate == CHAPSS_CLOSED ||
-                       cstate->serverstate == CHAPSS_PENDING) {
-               CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: in state %d\n",
-               cstate->serverstate));
-               return;
-       }
-       
-       if (id != cstate->chal_id)
-               return;                 /* doesn't match ID of last challenge */
-       
-       /*
-       * If we have received a duplicate or bogus Response,
-       * we have to send the same answer (Success/Failure)
-       * as we did for the first Response we saw.
-       */
-       if (cstate->serverstate == CHAPSS_OPEN) {
-               ChapSendStatus(cstate, CHAP_SUCCESS);
-               return;
-       }
-       if (cstate->serverstate == CHAPSS_BADAUTH) {
-               ChapSendStatus(cstate, CHAP_FAILURE);
-               return;
-       }
-       
-       if (len < 2) {
-               CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: rcvd short packet.\n"));
-               return;
-       }
-       GETCHAR(remmd_len, inp);                /* get length of MD */
-       remmd = inp;                    /* get pointer to MD */
-       INCPTR(remmd_len, inp);
-       
-       len -= sizeof (u_char) + remmd_len;
-       if (len < 0) {
-               CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: rcvd short packet.\n"));
-               return;
-       }
-       
-       UNTIMEOUT(ChapChallengeTimeout, cstate);
-       
-       if (len >= sizeof(rhostname))
-               len = sizeof(rhostname) - 1;
-       BCOPY(inp, rhostname, len);
-       rhostname[len] = '\000';
-       
-       CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: received name field: %s\n",
-                               rhostname));
-       
-       /*
-       * Get secret for authenticating them with us,
-       * do the hash ourselves, and compare the result.
-       */
-       code = CHAP_FAILURE;
-       if (!get_secret(cstate->unit, rhostname, cstate->chal_name,
-       secret, &secret_len, 1)) {
-/*        CHAPDEBUG((LOG_WARNING, TL_CHAP, "No CHAP secret found for authenticating %s\n", rhostname)); */
-               CHAPDEBUG((LOG_WARNING, "No CHAP secret found for authenticating %s\n",
-               rhostname));
-       } else {
-       
-               /*  generate MD based on negotiated type */
-               switch (cstate->chal_type) { 
-               
-               case CHAP_DIGEST_MD5:           /* only MD5 is defined for now */
-                       if (remmd_len != MD5_SIGNATURE_SIZE)
-                               break;                  /* it's not even the right length */
-                       MD5Init(&mdContext);
-                       MD5Update(&mdContext, &cstate->chal_id, 1);
-                       MD5Update(&mdContext, (u_char*)secret, secret_len);
-                       MD5Update(&mdContext, cstate->challenge, cstate->chal_len);
-                       MD5Final(hash, &mdContext); 
-                       
-                       /* compare local and remote MDs and send the appropriate status */
-                       if (memcmp (hash, remmd, MD5_SIGNATURE_SIZE) == 0)
-                               code = CHAP_SUCCESS;    /* they are the same! */
-                       break;
-               
-               default:
-                       CHAPDEBUG((LOG_INFO, "unknown digest type %d\n", cstate->chal_type));
-               }
-       }
-       
-       BZERO(secret, sizeof(secret));
-       ChapSendStatus(cstate, code);
-       
-       if (code == CHAP_SUCCESS) {
-               old_state = cstate->serverstate;
-               cstate->serverstate = CHAPSS_OPEN;
-               if (old_state == CHAPSS_INITIAL_CHAL) {
-                       auth_peer_success(cstate->unit, PPP_CHAP, rhostname, len);
-               }
-               if (cstate->chal_interval != 0)
-                       TIMEOUT(ChapRechallenge, cstate, cstate->chal_interval);
-       } else {
-               CHAPDEBUG((LOG_ERR, "CHAP peer authentication failed\n"));
-               cstate->serverstate = CHAPSS_BADAUTH;
-               auth_peer_fail(cstate->unit, PPP_CHAP);
-       }
-}
-
-/*
- * ChapReceiveSuccess - Receive Success
- */
-static void ChapReceiveSuccess(chap_state *cstate, u_char *inp, u_char id, int len)
-{
-
-       CHAPDEBUG((LOG_INFO, "ChapReceiveSuccess: Rcvd id %d.\n", id));
-       
-       if (cstate->clientstate == CHAPCS_OPEN)
-               /* presumably an answer to a duplicate response */
-               return;
-       
-       if (cstate->clientstate != CHAPCS_RESPONSE) {
-               /* don't know what this is */
-               CHAPDEBUG((LOG_INFO, "ChapReceiveSuccess: in state %d\n",
-                          cstate->clientstate));
-               return;
-       }
-       
-       UNTIMEOUT(ChapResponseTimeout, cstate);
-       
-       /*
-        * Print message.
-        */
-       if (len > 0)
-               PRINTMSG(inp, len);
-       
-       cstate->clientstate = CHAPCS_OPEN;
-       
-       auth_withpeer_success(cstate->unit, PPP_CHAP);
-}
-
-
-/*
- * ChapReceiveFailure - Receive failure.
- */
-static void ChapReceiveFailure(chap_state *cstate, u_char *inp, u_char id, int len)
-{
-       CHAPDEBUG((LOG_INFO, "ChapReceiveFailure: Rcvd id %d.\n", id));
-       
-       if (cstate->clientstate != CHAPCS_RESPONSE) {
-               /* don't know what this is */
-               CHAPDEBUG((LOG_INFO, "ChapReceiveFailure: in state %d\n",
-                          cstate->clientstate));
-               return;
-       }
-       
-       UNTIMEOUT(ChapResponseTimeout, cstate);
-       
-       /*
-        * Print message.
-        */
-       if (len > 0)
-               PRINTMSG(inp, len);
-       
-       CHAPDEBUG((LOG_ERR, "CHAP authentication failed\n"));
-       auth_withpeer_fail(cstate->unit, PPP_CHAP);
-}
-
-
-/*
- * ChapSendChallenge - Send an Authenticate challenge.
- */
-static void ChapSendChallenge(chap_state *cstate)
-{
-       u_char *outp;
-       int chal_len, name_len;
-       int outlen;
-       
-       chal_len = cstate->chal_len;
-       name_len = strlen(cstate->chal_name);
-       outlen = CHAP_HEADERLEN + sizeof (u_char) + chal_len + name_len;
-       outp = outpacket_buf[cstate->unit];
-       
-       MAKEHEADER(outp, PPP_CHAP);             /* paste in a CHAP header */
-       
-       PUTCHAR(CHAP_CHALLENGE, outp);
-       PUTCHAR(cstate->chal_id, outp);
-       PUTSHORT(outlen, outp);
-       
-       PUTCHAR(chal_len, outp);                /* put length of challenge */
-       BCOPY(cstate->challenge, outp, chal_len);
-       INCPTR(chal_len, outp);
-       
-       BCOPY(cstate->chal_name, outp, name_len);       /* append hostname */
-       
-       pppWrite(cstate->unit, outpacket_buf[cstate->unit], outlen + PPP_HDRLEN);
-       
-       CHAPDEBUG((LOG_INFO, "ChapSendChallenge: Sent id %d.\n", cstate->chal_id));
-       
-       TIMEOUT(ChapChallengeTimeout, cstate, cstate->timeouttime);
-       ++cstate->chal_transmits;
-}
-
-
-/*
- * ChapSendStatus - Send a status response (ack or nak).
- */
-static void ChapSendStatus(chap_state *cstate, int code)
-{
-       u_char *outp;
-       int outlen, msglen;
-       char msg[256];
-       
-       if (code == CHAP_SUCCESS)
-               strcpy(msg, "Welcome!");
-       else
-               strcpy(msg, "I don't like you.  Go 'way.");
-       msglen = strlen(msg);
-       
-       outlen = CHAP_HEADERLEN + msglen;
-       outp = outpacket_buf[cstate->unit];
-       
-       MAKEHEADER(outp, PPP_CHAP);             /* paste in a header */
-       
-       PUTCHAR(code, outp);
-       PUTCHAR(cstate->chal_id, outp);
-       PUTSHORT(outlen, outp);
-       BCOPY(msg, outp, msglen);
-       pppWrite(cstate->unit, outpacket_buf[cstate->unit], outlen + PPP_HDRLEN);
-       
-       CHAPDEBUG((LOG_INFO, "ChapSendStatus: Sent code %d, id %d.\n", code,
-              cstate->chal_id));
-}
-
-/*
- * ChapGenChallenge is used to generate a pseudo-random challenge string of
- * a pseudo-random length between min_len and max_len.  The challenge
- * string and its length are stored in *cstate, and various other fields of
- * *cstate are initialized.
- */
-
-static void ChapGenChallenge(chap_state *cstate)
-{
-       int chal_len;
-       u_char *ptr = cstate->challenge;
-       int i;
-       
-       /* pick a random challenge length between MIN_CHALLENGE_LENGTH and 
-          MAX_CHALLENGE_LENGTH */  
-       chal_len = (unsigned)
-                               ((((magic() >> 16) *
-                               (MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH)) >> 16)
-                            + MIN_CHALLENGE_LENGTH);
-       cstate->chal_len = chal_len;
-       cstate->chal_id = ++cstate->id;
-       cstate->chal_transmits = 0;
-       
-       /* generate a random string */
-       for (i = 0; i < chal_len; i++ )
-               *ptr++ = (char) (magic() & 0xff);
-}
-
-/*
- * ChapSendResponse - send a response packet with values as specified
- * in *cstate.
- */
-/* ARGSUSED */
-static void ChapSendResponse(chap_state *cstate)
-{
-       u_char *outp;
-       int outlen, md_len, name_len;
-       
-       md_len = cstate->resp_length;
-       name_len = strlen(cstate->resp_name);
-       outlen = CHAP_HEADERLEN + sizeof (u_char) + md_len + name_len;
-       outp = outpacket_buf[cstate->unit];
-       
-       MAKEHEADER(outp, PPP_CHAP);
-       
-       PUTCHAR(CHAP_RESPONSE, outp);   /* we are a response */
-       PUTCHAR(cstate->resp_id, outp); /* copy id from challenge packet */
-       PUTSHORT(outlen, outp);                 /* packet length */
-       
-       PUTCHAR(md_len, outp);                  /* length of MD */
-       BCOPY(cstate->response, outp, md_len);          /* copy MD to buffer */
-       INCPTR(md_len, outp);
-       
-       BCOPY(cstate->resp_name, outp, name_len);       /* append our name */
-       
-       /* send the packet */
-       pppWrite(cstate->unit, outpacket_buf[cstate->unit], outlen + PPP_HDRLEN);
-       
-       cstate->clientstate = CHAPCS_RESPONSE;
-       TIMEOUT(ChapResponseTimeout, cstate, cstate->timeouttime);
-       ++cstate->resp_transmits;
-}
-
-/*
- * ChapPrintPkt - print the contents of a CHAP packet.
- */
-static int ChapPrintPkt(
-       u_char *p,
-       int plen,
-       void (*printer) (void *, char *, ...),
-       void *arg
-)
-{
-       int code, id, len;
-       int clen, nlen;
-       u_char x;
-       
-       if (plen < CHAP_HEADERLEN)
-               return 0;
-       GETCHAR(code, p);
-       GETCHAR(id, p);
-       GETSHORT(len, p);
-       if (len < CHAP_HEADERLEN || len > plen)
-               return 0;
-       
-       if (code >= 1 && code <= sizeof(ChapCodenames) / sizeof(char *))
-               printer(arg, " %s", ChapCodenames[code-1]);
-       else
-               printer(arg, " code=0x%x", code);
-       printer(arg, " id=0x%x", id);
-       len -= CHAP_HEADERLEN;
-       switch (code) {
-       case CHAP_CHALLENGE:
-       case CHAP_RESPONSE:
-               if (len < 1)
-                       break;
-               clen = p[0];
-               if (len < clen + 1)
-                       break;
-               ++p;
-               nlen = len - clen - 1;
-               printer(arg, " <");
-               for (; clen > 0; --clen) {
-                       GETCHAR(x, p);
-                       printer(arg, "%.2x", x);
-               }
-               printer(arg, ">, name = %.*Z", nlen, p);
-               break;
-       case CHAP_FAILURE:
-       case CHAP_SUCCESS:
-               printer(arg, " %.*Z", len, p);
-               break;
-       default:
-               for (clen = len; clen > 0; --clen) {
-                       GETCHAR(x, p);
-                       printer(arg, " %.2x", x);
-               }
-       }
-       
-       return len + CHAP_HEADERLEN;
-}
-
-#endif
-
-#endif /* PPP_SUPPORT */
+/*** WARNING - THIS HAS NEVER BEEN FINISHED ***/\r
+/*****************************************************************************\r
+* chap.c - Network Challenge Handshake Authentication Protocol program file.\r
+*\r
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.\r
+* portions Copyright (c) 1997 by Global Election Systems Inc.\r
+*\r
+* The authors hereby grant permission to use, copy, modify, distribute,\r
+* and license this software and its documentation for any purpose, provided\r
+* that existing copyright notices are retained in all copies and that this\r
+* notice and the following disclaimer are included verbatim in any \r
+* distributions. No written agreement, license, or royalty fee is required\r
+* for any of the authorized uses.\r
+*\r
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR\r
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+*\r
+******************************************************************************\r
+* REVISION HISTORY\r
+*\r
+* 03-01-01 Marc Boucher <marc@mbsi.ca>\r
+*   Ported to lwIP.\r
+* 97-12-04 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.\r
+*      Original based on BSD chap.c.\r
+*****************************************************************************/\r
+/*\r
+ * chap.c - Challenge Handshake Authentication Protocol.\r
+ *\r
+ * Copyright (c) 1993 The Australian National University.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms are permitted\r
+ * provided that the above copyright notice and this paragraph are\r
+ * duplicated in all such forms and that any documentation,\r
+ * advertising materials, and other materials related to such\r
+ * distribution and use acknowledge that the software was developed\r
+ * by the Australian National University.  The name of the University\r
+ * may not be used to endorse or promote products derived from this\r
+ * software without specific prior written permission.\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR\r
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r
+ *\r
+ * Copyright (c) 1991 Gregory M. Christy.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms are permitted\r
+ * provided that the above copyright notice and this paragraph are\r
+ * duplicated in all such forms and that any documentation,\r
+ * advertising materials, and other materials related to such\r
+ * distribution and use acknowledge that the software was developed\r
+ * by Gregory M. Christy.  The name of the author may not be used to\r
+ * endorse or promote products derived from this software without\r
+ * specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR\r
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r
+ */\r
+\r
+#include "ppp.h"\r
+#if PPP_SUPPORT > 0\r
+#include "magic.h"\r
+\r
+#if CHAP_SUPPORT > 0\r
+\r
+#include "randm.h"\r
+#include "auth.h"\r
+#include "md5.h"\r
+#include "chap.h"\r
+#include "chpms.h"\r
+#include "pppdebug.h"\r
+\r
+\r
+/*************************/\r
+/*** LOCAL DEFINITIONS ***/\r
+/*************************/\r
+\r
+\r
+/************************/\r
+/*** LOCAL DATA TYPES ***/\r
+/************************/\r
+\r
+\r
+/***********************************/\r
+/*** LOCAL FUNCTION DECLARATIONS ***/\r
+/***********************************/\r
+/*\r
+ * Protocol entry points.\r
+ */\r
+static void ChapInit (int);\r
+static void ChapLowerUp (int);\r
+static void ChapLowerDown (int);\r
+static void ChapInput (int, u_char *, int);\r
+static void ChapProtocolReject (int);\r
+static int  ChapPrintPkt (u_char *, int,\r
+                             void (*) (void *, char *, ...), void *);\r
+\r
+static void ChapChallengeTimeout (void *);\r
+static void ChapResponseTimeout (void *);\r
+static void ChapReceiveChallenge (chap_state *, u_char *, int, int);\r
+static void ChapRechallenge (void *);\r
+static void ChapReceiveResponse (chap_state *, u_char *, int, int);\r
+static void ChapReceiveSuccess(chap_state *cstate, u_char *inp, u_char id, int len);\r
+static void ChapReceiveFailure(chap_state *cstate, u_char *inp, u_char id, int len);\r
+static void ChapSendStatus (chap_state *, int);\r
+static void ChapSendChallenge (chap_state *);\r
+static void ChapSendResponse (chap_state *);\r
+static void ChapGenChallenge (chap_state *);\r
+\r
+\r
+/******************************/\r
+/*** PUBLIC DATA STRUCTURES ***/\r
+/******************************/\r
+chap_state chap[NUM_PPP];              /* CHAP state; one for each unit */\r
+\r
+struct protent chap_protent = {\r
+    PPP_CHAP,\r
+    ChapInit,\r
+    ChapInput,\r
+    ChapProtocolReject,\r
+    ChapLowerUp,\r
+    ChapLowerDown,\r
+    NULL,\r
+    NULL,\r
+#if 0\r
+    ChapPrintPkt,\r
+    NULL,\r
+#endif\r
+    1,\r
+    "CHAP",\r
+#if 0\r
+    NULL,\r
+    NULL,\r
+    NULL\r
+#endif\r
+};\r
+\r
+\r
+\r
+/*****************************/\r
+/*** LOCAL DATA STRUCTURES ***/\r
+/*****************************/\r
+static char *ChapCodenames[] = {\r
+       "Challenge", "Response", "Success", "Failure"\r
+};\r
+\r
+\r
+\r
+/***********************************/\r
+/*** PUBLIC FUNCTION DEFINITIONS ***/\r
+/***********************************/\r
+/*\r
+ * ChapAuthWithPeer - Authenticate us with our peer (start client).\r
+ *\r
+ */\r
+void ChapAuthWithPeer(int unit, char *our_name, int digest)\r
+{\r
+       chap_state *cstate = &chap[unit];\r
+       \r
+       cstate->resp_name = our_name;\r
+       cstate->resp_type = digest;\r
+       \r
+       if (cstate->clientstate == CHAPCS_INITIAL ||\r
+                       cstate->clientstate == CHAPCS_PENDING) {\r
+               /* lower layer isn't up - wait until later */\r
+               cstate->clientstate = CHAPCS_PENDING;\r
+               return;\r
+       }\r
+       \r
+       /*\r
+        * We get here as a result of LCP coming up.\r
+        * So even if CHAP was open before, we will \r
+        * have to re-authenticate ourselves.\r
+        */\r
+       cstate->clientstate = CHAPCS_LISTEN;\r
+}\r
+\r
+\r
+/*\r
+ * ChapAuthPeer - Authenticate our peer (start server).\r
+ */\r
+void ChapAuthPeer(int unit, char *our_name, int digest)\r
+{\r
+       chap_state *cstate = &chap[unit];\r
+       \r
+       cstate->chal_name = our_name;\r
+       cstate->chal_type = digest;\r
+       \r
+       if (cstate->serverstate == CHAPSS_INITIAL ||\r
+                       cstate->serverstate == CHAPSS_PENDING) {\r
+               /* lower layer isn't up - wait until later */\r
+               cstate->serverstate = CHAPSS_PENDING;\r
+               return;\r
+       }\r
+       \r
+       ChapGenChallenge(cstate);\r
+       ChapSendChallenge(cstate);              /* crank it up dude! */\r
+       cstate->serverstate = CHAPSS_INITIAL_CHAL;\r
+}\r
+\r
+\r
+\r
+\r
+/**********************************/\r
+/*** LOCAL FUNCTION DEFINITIONS ***/\r
+/**********************************/\r
+/*\r
+ * ChapInit - Initialize a CHAP unit.\r
+ */\r
+static void ChapInit(int unit)\r
+{\r
+       chap_state *cstate = &chap[unit];\r
+       \r
+       BZERO(cstate, sizeof(*cstate));\r
+       cstate->unit = unit;\r
+       cstate->clientstate = CHAPCS_INITIAL;\r
+       cstate->serverstate = CHAPSS_INITIAL;\r
+       cstate->timeouttime = CHAP_DEFTIMEOUT;\r
+       cstate->max_transmits = CHAP_DEFTRANSMITS;\r
+       /* random number generator is initialized in magic_init */\r
+}\r
+\r
+\r
+/*\r
+ * ChapChallengeTimeout - Timeout expired on sending challenge.\r
+ */\r
+static void ChapChallengeTimeout(void *arg)\r
+{\r
+       chap_state *cstate = (chap_state *) arg;\r
+       \r
+       /* if we aren't sending challenges, don't worry.  then again we */\r
+       /* probably shouldn't be here either */\r
+       if (cstate->serverstate != CHAPSS_INITIAL_CHAL &&\r
+                       cstate->serverstate != CHAPSS_RECHALLENGE)\r
+               return;\r
+       \r
+       if (cstate->chal_transmits >= cstate->max_transmits) {\r
+               /* give up on peer */\r
+               CHAPDEBUG((LOG_ERR, "Peer failed to respond to CHAP challenge\n"));\r
+               cstate->serverstate = CHAPSS_BADAUTH;\r
+               auth_peer_fail(cstate->unit, PPP_CHAP);\r
+               return;\r
+       }\r
+       \r
+       ChapSendChallenge(cstate);              /* Re-send challenge */\r
+}\r
+\r
+\r
+/*\r
+ * ChapResponseTimeout - Timeout expired on sending response.\r
+ */\r
+static void ChapResponseTimeout(void *arg)\r
+{\r
+       chap_state *cstate = (chap_state *) arg;\r
+       \r
+       /* if we aren't sending a response, don't worry. */\r
+       if (cstate->clientstate != CHAPCS_RESPONSE)\r
+               return;\r
+       \r
+       ChapSendResponse(cstate);               /* re-send response */\r
+}\r
+\r
+\r
+/*\r
+ * ChapRechallenge - Time to challenge the peer again.\r
+ */\r
+static void ChapRechallenge(void *arg)\r
+{\r
+       chap_state *cstate = (chap_state *) arg;\r
+       \r
+       /* if we aren't sending a response, don't worry. */\r
+       if (cstate->serverstate != CHAPSS_OPEN)\r
+               return;\r
+       \r
+       ChapGenChallenge(cstate);\r
+       ChapSendChallenge(cstate);\r
+       cstate->serverstate = CHAPSS_RECHALLENGE;\r
+}\r
+\r
+\r
+/*\r
+ * ChapLowerUp - The lower layer is up.\r
+ *\r
+ * Start up if we have pending requests.\r
+ */\r
+static void ChapLowerUp(int unit)\r
+{\r
+       chap_state *cstate = &chap[unit];\r
+       \r
+       if (cstate->clientstate == CHAPCS_INITIAL)\r
+               cstate->clientstate = CHAPCS_CLOSED;\r
+       else if (cstate->clientstate == CHAPCS_PENDING)\r
+               cstate->clientstate = CHAPCS_LISTEN;\r
+       \r
+       if (cstate->serverstate == CHAPSS_INITIAL)\r
+               cstate->serverstate = CHAPSS_CLOSED;\r
+       else if (cstate->serverstate == CHAPSS_PENDING) {\r
+               ChapGenChallenge(cstate);\r
+               ChapSendChallenge(cstate);\r
+               cstate->serverstate = CHAPSS_INITIAL_CHAL;\r
+       }\r
+}\r
+\r
+\r
+/*\r
+ * ChapLowerDown - The lower layer is down.\r
+ *\r
+ * Cancel all timeouts.\r
+ */\r
+static void ChapLowerDown(int unit)\r
+{\r
+       chap_state *cstate = &chap[unit];\r
+       \r
+       /* Timeout(s) pending?  Cancel if so. */\r
+       if (cstate->serverstate == CHAPSS_INITIAL_CHAL ||\r
+                       cstate->serverstate == CHAPSS_RECHALLENGE)\r
+               UNTIMEOUT(ChapChallengeTimeout, cstate);\r
+       else if (cstate->serverstate == CHAPSS_OPEN\r
+                       && cstate->chal_interval != 0)\r
+               UNTIMEOUT(ChapRechallenge, cstate);\r
+       if (cstate->clientstate == CHAPCS_RESPONSE)\r
+               UNTIMEOUT(ChapResponseTimeout, cstate);\r
+       \r
+       cstate->clientstate = CHAPCS_INITIAL;\r
+       cstate->serverstate = CHAPSS_INITIAL;\r
+}\r
+\r
+\r
+/*\r
+ * ChapProtocolReject - Peer doesn't grok CHAP.\r
+ */\r
+static void ChapProtocolReject(int unit)\r
+{\r
+       chap_state *cstate = &chap[unit];\r
+       \r
+       if (cstate->serverstate != CHAPSS_INITIAL &&\r
+                       cstate->serverstate != CHAPSS_CLOSED)\r
+               auth_peer_fail(unit, PPP_CHAP);\r
+       if (cstate->clientstate != CHAPCS_INITIAL &&\r
+                       cstate->clientstate != CHAPCS_CLOSED)\r
+               auth_withpeer_fail(unit, PPP_CHAP);\r
+       ChapLowerDown(unit);            /* shutdown chap */\r
+}\r
+\r
+\r
+/*\r
+ * ChapInput - Input CHAP packet.\r
+ */\r
+static void ChapInput(int unit, u_char *inpacket, int packet_len)\r
+{\r
+       chap_state *cstate = &chap[unit];\r
+       u_char *inp;\r
+       u_char code, id;\r
+       int len;\r
+       \r
+       /*\r
+        * Parse header (code, id and length).\r
+        * If packet too short, drop it.\r
+        */\r
+       inp = inpacket;\r
+       if (packet_len < CHAP_HEADERLEN) {\r
+               CHAPDEBUG((LOG_INFO, "ChapInput: rcvd short header.\n"));\r
+               return;\r
+       }\r
+       GETCHAR(code, inp);\r
+       GETCHAR(id, inp);\r
+       GETSHORT(len, inp);\r
+       if (len < CHAP_HEADERLEN) {\r
+               CHAPDEBUG((LOG_INFO, "ChapInput: rcvd illegal length.\n"));\r
+               return;\r
+       }\r
+       if (len > packet_len) {\r
+               CHAPDEBUG((LOG_INFO, "ChapInput: rcvd short packet.\n"));\r
+               return;\r
+       }\r
+       len -= CHAP_HEADERLEN;\r
+       \r
+       /*\r
+        * Action depends on code (as in fact it usually does :-).\r
+        */\r
+       switch (code) {\r
+       case CHAP_CHALLENGE:\r
+               ChapReceiveChallenge(cstate, inp, id, len);\r
+               break;\r
+       \r
+       case CHAP_RESPONSE:\r
+               ChapReceiveResponse(cstate, inp, id, len);\r
+               break;\r
+       \r
+       case CHAP_FAILURE:\r
+               ChapReceiveFailure(cstate, inp, id, len);\r
+               break;\r
+       \r
+       case CHAP_SUCCESS:\r
+               ChapReceiveSuccess(cstate, inp, id, len);\r
+               break;\r
+       \r
+       default:                                /* Need code reject? */\r
+               CHAPDEBUG((LOG_WARNING, "Unknown CHAP code (%d) received.\n", code));\r
+               break;\r
+       }\r
+}\r
+\r
+\r
+/*\r
+ * ChapReceiveChallenge - Receive Challenge and send Response.\r
+ */\r
+static void ChapReceiveChallenge(chap_state *cstate, u_char *inp, int id, int len)\r
+{\r
+       int rchallenge_len;\r
+       u_char *rchallenge;\r
+       int secret_len;\r
+       char secret[MAXSECRETLEN];\r
+       char rhostname[256];\r
+       MD5_CTX mdContext;\r
+       u_char hash[MD5_SIGNATURE_SIZE];\r
+       \r
+       CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: Rcvd id %d.\n", id));\r
+       if (cstate->clientstate == CHAPCS_CLOSED ||\r
+               cstate->clientstate == CHAPCS_PENDING) {\r
+               CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: in state %d\n",\r
+                          cstate->clientstate));\r
+               return;\r
+       }\r
+       \r
+       if (len < 2) {\r
+               CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: rcvd short packet.\n"));\r
+               return;\r
+       }\r
+       \r
+       GETCHAR(rchallenge_len, inp);\r
+       len -= sizeof (u_char) + rchallenge_len;        /* now name field length */\r
+       if (len < 0) {\r
+               CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: rcvd short packet.\n"));\r
+               return;\r
+       }\r
+       rchallenge = inp;\r
+       INCPTR(rchallenge_len, inp);\r
+       \r
+       if (len >= sizeof(rhostname))\r
+               len = sizeof(rhostname) - 1;\r
+       BCOPY(inp, rhostname, len);\r
+       rhostname[len] = '\000';\r
+       \r
+       CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: received name field '%s'\n",\r
+              rhostname));\r
+       \r
+       /* Microsoft doesn't send their name back in the PPP packet */\r
+       if (ppp_settings.remote_name[0] != 0 && (ppp_settings.explicit_remote || rhostname[0] == 0)) {\r
+               strncpy(rhostname, ppp_settings.remote_name, sizeof(rhostname));\r
+               rhostname[sizeof(rhostname) - 1] = 0;\r
+               CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: using '%s' as remote name\n",\r
+                          rhostname));\r
+       }\r
+       \r
+       /* get secret for authenticating ourselves with the specified host */\r
+       if (!get_secret(cstate->unit, cstate->resp_name, rhostname,\r
+                           secret, &secret_len, 0)) {\r
+               secret_len = 0;         /* assume null secret if can't find one */\r
+               CHAPDEBUG((LOG_WARNING, "No CHAP secret found for authenticating us to %s\n", rhostname));\r
+       }\r
+       \r
+       /* cancel response send timeout if necessary */\r
+       if (cstate->clientstate == CHAPCS_RESPONSE)\r
+               UNTIMEOUT(ChapResponseTimeout, cstate);\r
+       \r
+       cstate->resp_id = id;\r
+       cstate->resp_transmits = 0;\r
+       \r
+       /*  generate MD based on negotiated type */\r
+       switch (cstate->resp_type) { \r
+       \r
+       case CHAP_DIGEST_MD5:\r
+               MD5Init(&mdContext);\r
+               MD5Update(&mdContext, &cstate->resp_id, 1);\r
+               MD5Update(&mdContext, (u_char*)secret, secret_len);\r
+               MD5Update(&mdContext, rchallenge, rchallenge_len);\r
+               MD5Final(hash, &mdContext);\r
+               BCOPY(hash, cstate->response, MD5_SIGNATURE_SIZE);\r
+               cstate->resp_length = MD5_SIGNATURE_SIZE;\r
+               break;\r
+       \r
+#ifdef CHAPMS\r
+       case CHAP_MICROSOFT:\r
+               ChapMS(cstate, rchallenge, rchallenge_len, secret, secret_len);\r
+               break;\r
+#endif\r
+       \r
+       default:\r
+               CHAPDEBUG((LOG_INFO, "unknown digest type %d\n", cstate->resp_type));\r
+               return;\r
+       }\r
+       \r
+       BZERO(secret, sizeof(secret));\r
+       ChapSendResponse(cstate);\r
+}\r
+\r
+\r
+/*\r
+ * ChapReceiveResponse - Receive and process response.\r
+ */\r
+static void ChapReceiveResponse(chap_state *cstate, u_char *inp, int id, int len)\r
+{\r
+       u_char *remmd, remmd_len;\r
+       int secret_len, old_state;\r
+       int code;\r
+       char rhostname[256];\r
+       MD5_CTX mdContext;\r
+       char secret[MAXSECRETLEN];\r
+       u_char hash[MD5_SIGNATURE_SIZE];\r
+       \r
+       CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: Rcvd id %d.\n", id));\r
+       \r
+       if (cstate->serverstate == CHAPSS_CLOSED ||\r
+                       cstate->serverstate == CHAPSS_PENDING) {\r
+               CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: in state %d\n",\r
+               cstate->serverstate));\r
+               return;\r
+       }\r
+       \r
+       if (id != cstate->chal_id)\r
+               return;                 /* doesn't match ID of last challenge */\r
+       \r
+       /*\r
+       * If we have received a duplicate or bogus Response,\r
+       * we have to send the same answer (Success/Failure)\r
+       * as we did for the first Response we saw.\r
+       */\r
+       if (cstate->serverstate == CHAPSS_OPEN) {\r
+               ChapSendStatus(cstate, CHAP_SUCCESS);\r
+               return;\r
+       }\r
+       if (cstate->serverstate == CHAPSS_BADAUTH) {\r
+               ChapSendStatus(cstate, CHAP_FAILURE);\r
+               return;\r
+       }\r
+       \r
+       if (len < 2) {\r
+               CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: rcvd short packet.\n"));\r
+               return;\r
+       }\r
+       GETCHAR(remmd_len, inp);                /* get length of MD */\r
+       remmd = inp;                    /* get pointer to MD */\r
+       INCPTR(remmd_len, inp);\r
+       \r
+       len -= sizeof (u_char) + remmd_len;\r
+       if (len < 0) {\r
+               CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: rcvd short packet.\n"));\r
+               return;\r
+       }\r
+       \r
+       UNTIMEOUT(ChapChallengeTimeout, cstate);\r
+       \r
+       if (len >= sizeof(rhostname))\r
+               len = sizeof(rhostname) - 1;\r
+       BCOPY(inp, rhostname, len);\r
+       rhostname[len] = '\000';\r
+       \r
+       CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: received name field: %s\n",\r
+                               rhostname));\r
+       \r
+       /*\r
+       * Get secret for authenticating them with us,\r
+       * do the hash ourselves, and compare the result.\r
+       */\r
+       code = CHAP_FAILURE;\r
+       if (!get_secret(cstate->unit, rhostname, cstate->chal_name,\r
+       secret, &secret_len, 1)) {\r
+/*        CHAPDEBUG((LOG_WARNING, TL_CHAP, "No CHAP secret found for authenticating %s\n", rhostname)); */\r
+               CHAPDEBUG((LOG_WARNING, "No CHAP secret found for authenticating %s\n",\r
+               rhostname));\r
+       } else {\r
+       \r
+               /*  generate MD based on negotiated type */\r
+               switch (cstate->chal_type) { \r
+               \r
+               case CHAP_DIGEST_MD5:           /* only MD5 is defined for now */\r
+                       if (remmd_len != MD5_SIGNATURE_SIZE)\r
+                               break;                  /* it's not even the right length */\r
+                       MD5Init(&mdContext);\r
+                       MD5Update(&mdContext, &cstate->chal_id, 1);\r
+                       MD5Update(&mdContext, (u_char*)secret, secret_len);\r
+                       MD5Update(&mdContext, cstate->challenge, cstate->chal_len);\r
+                       MD5Final(hash, &mdContext); \r
+                       \r
+                       /* compare local and remote MDs and send the appropriate status */\r
+                       if (memcmp (hash, remmd, MD5_SIGNATURE_SIZE) == 0)\r
+                               code = CHAP_SUCCESS;    /* they are the same! */\r
+                       break;\r
+               \r
+               default:\r
+                       CHAPDEBUG((LOG_INFO, "unknown digest type %d\n", cstate->chal_type));\r
+               }\r
+       }\r
+       \r
+       BZERO(secret, sizeof(secret));\r
+       ChapSendStatus(cstate, code);\r
+       \r
+       if (code == CHAP_SUCCESS) {\r
+               old_state = cstate->serverstate;\r
+               cstate->serverstate = CHAPSS_OPEN;\r
+               if (old_state == CHAPSS_INITIAL_CHAL) {\r
+                       auth_peer_success(cstate->unit, PPP_CHAP, rhostname, len);\r
+               }\r
+               if (cstate->chal_interval != 0)\r
+                       TIMEOUT(ChapRechallenge, cstate, cstate->chal_interval);\r
+       } else {\r
+               CHAPDEBUG((LOG_ERR, "CHAP peer authentication failed\n"));\r
+               cstate->serverstate = CHAPSS_BADAUTH;\r
+               auth_peer_fail(cstate->unit, PPP_CHAP);\r
+       }\r
+}\r
+\r
+/*\r
+ * ChapReceiveSuccess - Receive Success\r
+ */\r
+static void ChapReceiveSuccess(chap_state *cstate, u_char *inp, u_char id, int len)\r
+{\r
+\r
+       CHAPDEBUG((LOG_INFO, "ChapReceiveSuccess: Rcvd id %d.\n", id));\r
+       \r
+       if (cstate->clientstate == CHAPCS_OPEN)\r
+               /* presumably an answer to a duplicate response */\r
+               return;\r
+       \r
+       if (cstate->clientstate != CHAPCS_RESPONSE) {\r
+               /* don't know what this is */\r
+               CHAPDEBUG((LOG_INFO, "ChapReceiveSuccess: in state %d\n",\r
+                          cstate->clientstate));\r
+               return;\r
+       }\r
+       \r
+       UNTIMEOUT(ChapResponseTimeout, cstate);\r
+       \r
+       /*\r
+        * Print message.\r
+        */\r
+       if (len > 0)\r
+               PRINTMSG(inp, len);\r
+       \r
+       cstate->clientstate = CHAPCS_OPEN;\r
+       \r
+       auth_withpeer_success(cstate->unit, PPP_CHAP);\r
+}\r
+\r
+\r
+/*\r
+ * ChapReceiveFailure - Receive failure.\r
+ */\r
+static void ChapReceiveFailure(chap_state *cstate, u_char *inp, u_char id, int len)\r
+{\r
+       CHAPDEBUG((LOG_INFO, "ChapReceiveFailure: Rcvd id %d.\n", id));\r
+       \r
+       if (cstate->clientstate != CHAPCS_RESPONSE) {\r
+               /* don't know what this is */\r
+               CHAPDEBUG((LOG_INFO, "ChapReceiveFailure: in state %d\n",\r
+                          cstate->clientstate));\r
+               return;\r
+       }\r
+       \r
+       UNTIMEOUT(ChapResponseTimeout, cstate);\r
+       \r
+       /*\r
+        * Print message.\r
+        */\r
+       if (len > 0)\r
+               PRINTMSG(inp, len);\r
+       \r
+       CHAPDEBUG((LOG_ERR, "CHAP authentication failed\n"));\r
+       auth_withpeer_fail(cstate->unit, PPP_CHAP);\r
+}\r
+\r
+\r
+/*\r
+ * ChapSendChallenge - Send an Authenticate challenge.\r
+ */\r
+static void ChapSendChallenge(chap_state *cstate)\r
+{\r
+       u_char *outp;\r
+       int chal_len, name_len;\r
+       int outlen;\r
+       \r
+       chal_len = cstate->chal_len;\r
+       name_len = strlen(cstate->chal_name);\r
+       outlen = CHAP_HEADERLEN + sizeof (u_char) + chal_len + name_len;\r
+       outp = outpacket_buf[cstate->unit];\r
+       \r
+       MAKEHEADER(outp, PPP_CHAP);             /* paste in a CHAP header */\r
+       \r
+       PUTCHAR(CHAP_CHALLENGE, outp);\r
+       PUTCHAR(cstate->chal_id, outp);\r
+       PUTSHORT(outlen, outp);\r
+       \r
+       PUTCHAR(chal_len, outp);                /* put length of challenge */\r
+       BCOPY(cstate->challenge, outp, chal_len);\r
+       INCPTR(chal_len, outp);\r
+       \r
+       BCOPY(cstate->chal_name, outp, name_len);       /* append hostname */\r
+       \r
+       pppWrite(cstate->unit, outpacket_buf[cstate->unit], outlen + PPP_HDRLEN);\r
+       \r
+       CHAPDEBUG((LOG_INFO, "ChapSendChallenge: Sent id %d.\n", cstate->chal_id));\r
+       \r
+       TIMEOUT(ChapChallengeTimeout, cstate, cstate->timeouttime);\r
+       ++cstate->chal_transmits;\r
+}\r
+\r
+\r
+/*\r
+ * ChapSendStatus - Send a status response (ack or nak).\r
+ */\r
+static void ChapSendStatus(chap_state *cstate, int code)\r
+{\r
+       u_char *outp;\r
+       int outlen, msglen;\r
+       char msg[256];\r
+       \r
+       if (code == CHAP_SUCCESS)\r
+               strcpy(msg, "Welcome!");\r
+       else\r
+               strcpy(msg, "I don't like you.  Go 'way.");\r
+       msglen = strlen(msg);\r
+       \r
+       outlen = CHAP_HEADERLEN + msglen;\r
+       outp = outpacket_buf[cstate->unit];\r
+       \r
+       MAKEHEADER(outp, PPP_CHAP);             /* paste in a header */\r
+       \r
+       PUTCHAR(code, outp);\r
+       PUTCHAR(cstate->chal_id, outp);\r
+       PUTSHORT(outlen, outp);\r
+       BCOPY(msg, outp, msglen);\r
+       pppWrite(cstate->unit, outpacket_buf[cstate->unit], outlen + PPP_HDRLEN);\r
+       \r
+       CHAPDEBUG((LOG_INFO, "ChapSendStatus: Sent code %d, id %d.\n", code,\r
+              cstate->chal_id));\r
+}\r
+\r
+/*\r
+ * ChapGenChallenge is used to generate a pseudo-random challenge string of\r
+ * a pseudo-random length between min_len and max_len.  The challenge\r
+ * string and its length are stored in *cstate, and various other fields of\r
+ * *cstate are initialized.\r
+ */\r
+\r
+static void ChapGenChallenge(chap_state *cstate)\r
+{\r
+       int chal_len;\r
+       u_char *ptr = cstate->challenge;\r
+       int i;\r
+       \r
+       /* pick a random challenge length between MIN_CHALLENGE_LENGTH and \r
+          MAX_CHALLENGE_LENGTH */  \r
+       chal_len = (unsigned)\r
+                               ((((magic() >> 16) *\r
+                               (MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH)) >> 16)\r
+                            + MIN_CHALLENGE_LENGTH);\r
+       cstate->chal_len = chal_len;\r
+       cstate->chal_id = ++cstate->id;\r
+       cstate->chal_transmits = 0;\r
+       \r
+       /* generate a random string */\r
+       for (i = 0; i < chal_len; i++ )\r
+               *ptr++ = (char) (magic() & 0xff);\r
+}\r
+\r
+/*\r
+ * ChapSendResponse - send a response packet with values as specified\r
+ * in *cstate.\r
+ */\r
+/* ARGSUSED */\r
+static void ChapSendResponse(chap_state *cstate)\r
+{\r
+       u_char *outp;\r
+       int outlen, md_len, name_len;\r
+       \r
+       md_len = cstate->resp_length;\r
+       name_len = strlen(cstate->resp_name);\r
+       outlen = CHAP_HEADERLEN + sizeof (u_char) + md_len + name_len;\r
+       outp = outpacket_buf[cstate->unit];\r
+       \r
+       MAKEHEADER(outp, PPP_CHAP);\r
+       \r
+       PUTCHAR(CHAP_RESPONSE, outp);   /* we are a response */\r
+       PUTCHAR(cstate->resp_id, outp); /* copy id from challenge packet */\r
+       PUTSHORT(outlen, outp);                 /* packet length */\r
+       \r
+       PUTCHAR(md_len, outp);                  /* length of MD */\r
+       BCOPY(cstate->response, outp, md_len);          /* copy MD to buffer */\r
+       INCPTR(md_len, outp);\r
+       \r
+       BCOPY(cstate->resp_name, outp, name_len);       /* append our name */\r
+       \r
+       /* send the packet */\r
+       pppWrite(cstate->unit, outpacket_buf[cstate->unit], outlen + PPP_HDRLEN);\r
+       \r
+       cstate->clientstate = CHAPCS_RESPONSE;\r
+       TIMEOUT(ChapResponseTimeout, cstate, cstate->timeouttime);\r
+       ++cstate->resp_transmits;\r
+}\r
+\r
+/*\r
+ * ChapPrintPkt - print the contents of a CHAP packet.\r
+ */\r
+static int ChapPrintPkt(\r
+       u_char *p,\r
+       int plen,\r
+       void (*printer) (void *, char *, ...),\r
+       void *arg\r
+)\r
+{\r
+       int code, id, len;\r
+       int clen, nlen;\r
+       u_char x;\r
+       \r
+       if (plen < CHAP_HEADERLEN)\r
+               return 0;\r
+       GETCHAR(code, p);\r
+       GETCHAR(id, p);\r
+       GETSHORT(len, p);\r
+       if (len < CHAP_HEADERLEN || len > plen)\r
+               return 0;\r
+       \r
+       if (code >= 1 && code <= sizeof(ChapCodenames) / sizeof(char *))\r
+               printer(arg, " %s", ChapCodenames[code-1]);\r
+       else\r
+               printer(arg, " code=0x%x", code);\r
+       printer(arg, " id=0x%x", id);\r
+       len -= CHAP_HEADERLEN;\r
+       switch (code) {\r
+       case CHAP_CHALLENGE:\r
+       case CHAP_RESPONSE:\r
+               if (len < 1)\r
+                       break;\r
+               clen = p[0];\r
+               if (len < clen + 1)\r
+                       break;\r
+               ++p;\r
+               nlen = len - clen - 1;\r
+               printer(arg, " <");\r
+               for (; clen > 0; --clen) {\r
+                       GETCHAR(x, p);\r
+                       printer(arg, "%.2x", x);\r
+               }\r
+               printer(arg, ">, name = %.*Z", nlen, p);\r
+               break;\r
+       case CHAP_FAILURE:\r
+       case CHAP_SUCCESS:\r
+               printer(arg, " %.*Z", len, p);\r
+               break;\r
+       default:\r
+               for (clen = len; clen > 0; --clen) {\r
+                       GETCHAR(x, p);\r
+                       printer(arg, " %.2x", x);\r
+               }\r
+       }\r
+       \r
+       return len + CHAP_HEADERLEN;\r
+}\r
+\r
+#endif\r
+\r
+#endif /* PPP_SUPPORT */\r
index 6fd9727525a3fe6691512616fcb9a8c37bb38d6c..1aca13414fe13816e9cbc67f83e1c43e1e766893 100644 (file)
-/*****************************************************************************
-* chap.h - Network Challenge Handshake Authentication Protocol header file.
-*
-* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
-* portions Copyright (c) 1998 Global Election Systems Inc.
-*
-* The authors hereby grant permission to use, copy, modify, distribute,
-* and license this software and its documentation for any purpose, provided
-* that existing copyright notices are retained in all copies and that this
-* notice and the following disclaimer are included verbatim in any 
-* distributions. No written agreement, license, or royalty fee is required
-* for any of the authorized uses.
-*
-* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *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 CONTRIBUTORS 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.
-*
-******************************************************************************
-* REVISION HISTORY
-*
-* 03-01-01 Marc Boucher <marc@mbsi.ca>
-*   Ported to lwIP.
-* 97-12-03 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
-*      Original built from BSD network code.
-******************************************************************************/
-/*
- * chap.h - Challenge Handshake Authentication Protocol definitions.
- *
- * Copyright (c) 1993 The Australian National University.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the Australian National University.  The name of the University
- * may not be used to endorse or promote products derived from this
- * software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Copyright (c) 1991 Gregory M. Christy
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the author.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * $Id: chap.h,v 1.1 2003/05/27 14:37:56 jani Exp $
- */
-
-#ifndef CHAP_H
-#define CHAP_H
-
-/*************************
-*** PUBLIC DEFINITIONS ***
-*************************/
-
-/* Code + ID + length */
-#define CHAP_HEADERLEN         4
-
-/*
- * CHAP codes.
- */
-
-#define CHAP_DIGEST_MD5                5       /* use MD5 algorithm */
-#define MD5_SIGNATURE_SIZE     16      /* 16 bytes in a MD5 message digest */
-#define CHAP_MICROSOFT         0x80    /* use Microsoft-compatible alg. */
-#define MS_CHAP_RESPONSE_LEN   49      /* Response length for MS-CHAP */
-
-#define CHAP_CHALLENGE         1
-#define CHAP_RESPONSE          2
-#define CHAP_SUCCESS           3
-#define CHAP_FAILURE           4
-
-/*
- *  Challenge lengths (for challenges we send) and other limits.
- */
-#define MIN_CHALLENGE_LENGTH   32
-#define MAX_CHALLENGE_LENGTH   64
-#define MAX_RESPONSE_LENGTH    64      /* sufficient for MD5 or MS-CHAP */
-
-/*
- * Client (peer) states.
- */
-#define CHAPCS_INITIAL         0       /* Lower layer down, not opened */
-#define CHAPCS_CLOSED          1       /* Lower layer up, not opened */
-#define CHAPCS_PENDING         2       /* Auth us to peer when lower up */
-#define CHAPCS_LISTEN          3       /* Listening for a challenge */
-#define CHAPCS_RESPONSE                4       /* Sent response, waiting for status */
-#define CHAPCS_OPEN            5       /* We've received Success */
-
-/*
- * Server (authenticator) states.
- */
-#define CHAPSS_INITIAL         0       /* Lower layer down, not opened */
-#define CHAPSS_CLOSED          1       /* Lower layer up, not opened */
-#define CHAPSS_PENDING         2       /* Auth peer when lower up */
-#define CHAPSS_INITIAL_CHAL    3       /* We've sent the first challenge */
-#define CHAPSS_OPEN            4       /* We've sent a Success msg */
-#define CHAPSS_RECHALLENGE     5       /* We've sent another challenge */
-#define CHAPSS_BADAUTH         6       /* We've sent a Failure msg */
-
-/************************
-*** PUBLIC DATA TYPES ***
-************************/
-
-/*
- * Each interface is described by a chap structure.
- */
-
-typedef struct chap_state {
-    int unit;                  /* Interface unit number */
-    int clientstate;           /* Client state */
-    int serverstate;           /* Server state */
-    u_char challenge[MAX_CHALLENGE_LENGTH]; /* last challenge string sent */
-    u_char chal_len;           /* challenge length */
-    u_char chal_id;            /* ID of last challenge */
-    u_char chal_type;          /* hash algorithm for challenges */
-    u_char id;                 /* Current id */
-    char *chal_name;           /* Our name to use with challenge */
-    int chal_interval;         /* Time until we challenge peer again */
-    int timeouttime;           /* Timeout time in seconds */
-    int max_transmits;         /* Maximum # of challenge transmissions */
-    int chal_transmits;                /* Number of transmissions of challenge */
-    int resp_transmits;                /* Number of transmissions of response */
-    u_char response[MAX_RESPONSE_LENGTH];      /* Response to send */
-    u_char resp_length;                /* length of response */
-    u_char resp_id;            /* ID for response messages */
-    u_char resp_type;          /* hash algorithm for responses */
-    char *resp_name;           /* Our name to send with response */
-} chap_state;
-
-
-/******************
-*** PUBLIC DATA ***
-******************/
-extern chap_state chap[];
-
-extern struct protent chap_protent;
-
-
-/***********************
-*** PUBLIC FUNCTIONS ***
-***********************/
-
-void ChapAuthWithPeer (int, char *, int);
-void ChapAuthPeer (int, char *, int);
-
-#endif /* CHAP_H */
-
+/*****************************************************************************\r
+* chap.h - Network Challenge Handshake Authentication Protocol header file.\r
+*\r
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.\r
+* portions Copyright (c) 1998 Global Election Systems Inc.\r
+*\r
+* The authors hereby grant permission to use, copy, modify, distribute,\r
+* and license this software and its documentation for any purpose, provided\r
+* that existing copyright notices are retained in all copies and that this\r
+* notice and the following disclaimer are included verbatim in any \r
+* distributions. No written agreement, license, or royalty fee is required\r
+* for any of the authorized uses.\r
+*\r
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR\r
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+*\r
+******************************************************************************\r
+* REVISION HISTORY\r
+*\r
+* 03-01-01 Marc Boucher <marc@mbsi.ca>\r
+*   Ported to lwIP.\r
+* 97-12-03 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.\r
+*      Original built from BSD network code.\r
+******************************************************************************/\r
+/*\r
+ * chap.h - Challenge Handshake Authentication Protocol definitions.\r
+ *\r
+ * Copyright (c) 1993 The Australian National University.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms are permitted\r
+ * provided that the above copyright notice and this paragraph are\r
+ * duplicated in all such forms and that any documentation,\r
+ * advertising materials, and other materials related to such\r
+ * distribution and use acknowledge that the software was developed\r
+ * by the Australian National University.  The name of the University\r
+ * may not be used to endorse or promote products derived from this\r
+ * software without specific prior written permission.\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR\r
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r
+ *\r
+ * Copyright (c) 1991 Gregory M. Christy\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms are permitted\r
+ * provided that the above copyright notice and this paragraph are\r
+ * duplicated in all such forms and that any documentation,\r
+ * advertising materials, and other materials related to such\r
+ * distribution and use acknowledge that the software was developed\r
+ * by the author.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR\r
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r
+ *\r
+ * $Id: chap.h,v 1.1 2003/05/27 14:37:56 jani Exp $\r
+ */\r
+\r
+#ifndef CHAP_H\r
+#define CHAP_H\r
+\r
+/*************************\r
+*** PUBLIC DEFINITIONS ***\r
+*************************/\r
+\r
+/* Code + ID + length */\r
+#define CHAP_HEADERLEN         4\r
+\r
+/*\r
+ * CHAP codes.\r
+ */\r
+\r
+#define CHAP_DIGEST_MD5                5       /* use MD5 algorithm */\r
+#define MD5_SIGNATURE_SIZE     16      /* 16 bytes in a MD5 message digest */\r
+#define CHAP_MICROSOFT         0x80    /* use Microsoft-compatible alg. */\r
+#define MS_CHAP_RESPONSE_LEN   49      /* Response length for MS-CHAP */\r
+\r
+#define CHAP_CHALLENGE         1\r
+#define CHAP_RESPONSE          2\r
+#define CHAP_SUCCESS           3\r
+#define CHAP_FAILURE           4\r
+\r
+/*\r
+ *  Challenge lengths (for challenges we send) and other limits.\r
+ */\r
+#define MIN_CHALLENGE_LENGTH   32\r
+#define MAX_CHALLENGE_LENGTH   64\r
+#define MAX_RESPONSE_LENGTH    64      /* sufficient for MD5 or MS-CHAP */\r
+\r
+/*\r
+ * Client (peer) states.\r
+ */\r
+#define CHAPCS_INITIAL         0       /* Lower layer down, not opened */\r
+#define CHAPCS_CLOSED          1       /* Lower layer up, not opened */\r
+#define CHAPCS_PENDING         2       /* Auth us to peer when lower up */\r
+#define CHAPCS_LISTEN          3       /* Listening for a challenge */\r
+#define CHAPCS_RESPONSE                4       /* Sent response, waiting for status */\r
+#define CHAPCS_OPEN            5       /* We've received Success */\r
+\r
+/*\r
+ * Server (authenticator) states.\r
+ */\r
+#define CHAPSS_INITIAL         0       /* Lower layer down, not opened */\r
+#define CHAPSS_CLOSED          1       /* Lower layer up, not opened */\r
+#define CHAPSS_PENDING         2       /* Auth peer when lower up */\r
+#define CHAPSS_INITIAL_CHAL    3       /* We've sent the first challenge */\r
+#define CHAPSS_OPEN            4       /* We've sent a Success msg */\r
+#define CHAPSS_RECHALLENGE     5       /* We've sent another challenge */\r
+#define CHAPSS_BADAUTH         6       /* We've sent a Failure msg */\r
+\r
+/************************\r
+*** PUBLIC DATA TYPES ***\r
+************************/\r
+\r
+/*\r
+ * Each interface is described by a chap structure.\r
+ */\r
+\r
+typedef struct chap_state {\r
+    int unit;                  /* Interface unit number */\r
+    int clientstate;           /* Client state */\r
+    int serverstate;           /* Server state */\r
+    u_char challenge[MAX_CHALLENGE_LENGTH]; /* last challenge string sent */\r
+    u_char chal_len;           /* challenge length */\r
+    u_char chal_id;            /* ID of last challenge */\r
+    u_char chal_type;          /* hash algorithm for challenges */\r
+    u_char id;                 /* Current id */\r
+    char *chal_name;           /* Our name to use with challenge */\r
+    int chal_interval;         /* Time until we challenge peer again */\r
+    int timeouttime;           /* Timeout time in seconds */\r
+    int max_transmits;         /* Maximum # of challenge transmissions */\r
+    int chal_transmits;                /* Number of transmissions of challenge */\r
+    int resp_transmits;                /* Number of transmissions of response */\r
+    u_char response[MAX_RESPONSE_LENGTH];      /* Response to send */\r
+    u_char resp_length;                /* length of response */\r
+    u_char resp_id;            /* ID for response messages */\r
+    u_char resp_type;          /* hash algorithm for responses */\r
+    char *resp_name;           /* Our name to send with response */\r
+} chap_state;\r
+\r
+\r
+/******************\r
+*** PUBLIC DATA ***\r
+******************/\r
+extern chap_state chap[];\r
+\r
+extern struct protent chap_protent;\r
+\r
+\r
+/***********************\r
+*** PUBLIC FUNCTIONS ***\r
+***********************/\r
+\r
+void ChapAuthWithPeer (int, char *, int);\r
+void ChapAuthPeer (int, char *, int);\r
+\r
+#endif /* CHAP_H */\r
+\r
index 01755ba39ca6e3afaeb58ca69870348a93da0ec8..30643446034382f722681c0f0f59d58a425a4fb7 100644 (file)
-/*** WARNING - THIS CODE HAS NOT BEEN FINISHED! ***/
-/*****************************************************************************
-* chpms.c - Network MicroSoft Challenge Handshake Authentication Protocol program file.
-*
-* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
-* Copyright (c) 1997 by Global Election Systems Inc.  All rights reserved.
-*
-* The authors hereby grant permission to use, copy, modify, distribute,
-* and license this software and its documentation for any purpose, provided
-* that existing copyright notices are retained in all copies and that this
-* notice and the following disclaimer are included verbatim in any 
-* distributions. No written agreement, license, or royalty fee is required
-* for any of the authorized uses.
-*
-* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *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 CONTRIBUTORS 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.
-*
-******************************************************************************
-* REVISION HISTORY
-*
-* 03-01-01 Marc Boucher <marc@mbsi.ca>
-*   Ported to lwIP.
-* 97-12-08 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
-*      Original based on BSD chap_ms.c.
-*****************************************************************************/
-/*
- * chap_ms.c - Microsoft MS-CHAP compatible implementation.
- *
- * Copyright (c) 1995 Eric Rosenquist, Strata Software Limited.
- * http://www.strataware.com/
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by Eric Rosenquist.  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 ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-/*
- * Modifications by Lauri Pesonen / lpesonen@clinet.fi, april 1997
- *
- *   Implemented LANManager type password response to MS-CHAP challenges.
- *   Now pppd provides both NT style and LANMan style blocks, and the
- *   prefered is set by option "ms-lanman". Default is to use NT.
- *   The hash text (StdText) was taken from Win95 RASAPI32.DLL.
- *
- *   You should also use DOMAIN\\USERNAME as described in README.MSCHAP80
- */
-
-#define USE_CRYPT
-
-
-#include "ppp.h"
-
-#if MSCHAP_SUPPORT > 0
-
-#include "md4.h"
-#ifndef USE_CRYPT
-#include "des.h"
-#endif
-#include "chap.h"
-#include "chpms.h"
-#include "pppdebug.h"
-
-
-/*************************/
-/*** LOCAL DEFINITIONS ***/
-/*************************/
-
-
-/************************/
-/*** LOCAL DATA TYPES ***/
-/************************/
-typedef struct {
-    u_char LANManResp[24];
-    u_char NTResp[24];
-    u_char UseNT;              /* If 1, ignore the LANMan response field */
-} MS_ChapResponse;
-/* We use MS_CHAP_RESPONSE_LEN, rather than sizeof(MS_ChapResponse),
-   in case this struct gets padded. */
-
-
-
-/***********************************/
-/*** LOCAL FUNCTION DECLARATIONS ***/
-/***********************************/
-
-/* XXX Don't know what to do with these. */
-extern void setkey(const char *);
-extern void encrypt(char *, int);
-
-static void    DesEncrypt (u_char *, u_char *, u_char *);
-static void    MakeKey (u_char *, u_char *);
-
-#ifdef USE_CRYPT
-static void    Expand (u_char *, u_char *);
-static void    Collapse (u_char *, u_char *);
-#endif
-
-static void ChallengeResponse(
-       u_char *challenge,      /* IN   8 octets */
-       u_char *pwHash,         /* IN  16 octets */
-       u_char *response        /* OUT 24 octets */
-);
-static void ChapMS_NT(
-       char *rchallenge,
-       int rchallenge_len,
-       char *secret,
-       int secret_len,
-       MS_ChapResponse *response
-);
-static u_char Get7Bits(
-       u_char *input,
-       int startBit
-);
-
-
-/***********************************/
-/*** PUBLIC FUNCTION DEFINITIONS ***/
-/***********************************/
-void ChapMS(
-       chap_state *cstate,
-       char *rchallenge,
-       int rchallenge_len,
-       char *secret,
-       int secret_len
-)
-{
-       MS_ChapResponse response;
-#ifdef MSLANMAN
-       extern int ms_lanman;
-#endif
-       
-#if 0
-       CHAPDEBUG((LOG_INFO, "ChapMS: secret is '%.*s'\n", secret_len, secret));
-#endif
-       BZERO(&response, sizeof(response));
-       
-       /* Calculate both always */
-       ChapMS_NT(rchallenge, rchallenge_len, secret, secret_len, &response);
-       
-#ifdef MSLANMAN
-       ChapMS_LANMan(rchallenge, rchallenge_len, secret, secret_len, &response);
-       
-       /* prefered method is set by option  */
-       response.UseNT = !ms_lanman;
-#else
-       response.UseNT = 1;
-#endif
-       
-       BCOPY(&response, cstate->response, MS_CHAP_RESPONSE_LEN);
-       cstate->resp_length = MS_CHAP_RESPONSE_LEN;
-}
-
-
-/**********************************/
-/*** LOCAL FUNCTION DEFINITIONS ***/
-/**********************************/
-static void ChallengeResponse(
-       u_char *challenge,      /* IN   8 octets */
-       u_char *pwHash,         /* IN  16 octets */
-       u_char *response        /* OUT 24 octets */
-)
-{
-       char    ZPasswordHash[21];
-       
-       BZERO(ZPasswordHash, sizeof(ZPasswordHash));
-       BCOPY(pwHash, ZPasswordHash, 16);
-       
-#if 0
-       log_packet(ZPasswordHash, sizeof(ZPasswordHash), "ChallengeResponse - ZPasswordHash", LOG_DEBUG);
-#endif
-       
-       DesEncrypt(challenge, ZPasswordHash +  0, response + 0);
-       DesEncrypt(challenge, ZPasswordHash +  7, response + 8);
-       DesEncrypt(challenge, ZPasswordHash + 14, response + 16);
-       
-#if 0
-       log_packet(response, 24, "ChallengeResponse - response", LOG_DEBUG);
-#endif
-}
-
-
-#ifdef USE_CRYPT
-static void DesEncrypt(
-       u_char *clear,  /* IN  8 octets */
-       u_char *key,    /* IN  7 octets */
-       u_char *cipher  /* OUT 8 octets */
-)
-{
-       u_char des_key[8];
-       u_char crypt_key[66];
-       u_char des_input[66];
-       
-       MakeKey(key, des_key);
-       
-       Expand(des_key, crypt_key);
-       setkey(crypt_key);
-       
-#if 0
-       CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet input : %02X%02X%02X%02X%02X%02X%02X%02X\n",
-              clear[0], clear[1], clear[2], clear[3], clear[4], clear[5], clear[6], clear[7]));
-#endif
-       
-       Expand(clear, des_input);
-       encrypt(des_input, 0);
-       Collapse(des_input, cipher);
-       
-#if 0
-       CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet output: %02X%02X%02X%02X%02X%02X%02X%02X\n",
-              cipher[0], cipher[1], cipher[2], cipher[3], cipher[4], cipher[5], cipher[6], cipher[7]));
-#endif
-}
-
-#else /* USE_CRYPT */
-
-static void DesEncrypt(
-       u_char *clear,  /* IN  8 octets */
-       u_char *key,    /* IN  7 octets */
-       u_char *cipher  /* OUT 8 octets */
-)
-{
-       des_cblock              des_key;
-       des_key_schedule        key_schedule;
-       
-       MakeKey(key, des_key);
-       
-       des_set_key(&des_key, key_schedule);
-       
-#if 0
-       CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet input : %02X%02X%02X%02X%02X%02X%02X%02X\n",
-              clear[0], clear[1], clear[2], clear[3], clear[4], clear[5], clear[6], clear[7]));
-#endif
-       
-       des_ecb_encrypt((des_cblock *)clear, (des_cblock *)cipher, key_schedule, 1);
-       
-#if 0
-       CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet output: %02X%02X%02X%02X%02X%02X%02X%02X\n",
-              cipher[0], cipher[1], cipher[2], cipher[3], cipher[4], cipher[5], cipher[6], cipher[7]));
-#endif
-}
-
-#endif /* USE_CRYPT */
-
-
-static u_char Get7Bits(
-       u_char *input,
-       int startBit
-)
-{
-       register unsigned int   word;
-       
-       word  = (unsigned)input[startBit / 8] << 8;
-       word |= (unsigned)input[startBit / 8 + 1];
-       
-       word >>= 15 - (startBit % 8 + 7);
-       
-       return word & 0xFE;
-}
-
-#ifdef USE_CRYPT
-
-/* in == 8-byte string (expanded version of the 56-bit key)
- * out == 64-byte string where each byte is either 1 or 0
- * Note that the low-order "bit" is always ignored by by setkey()
- */
-static void Expand(u_char *in, u_char *out)
-{
-       int j, c;
-       int i;
-       
-       for(i = 0; i < 64; in++){
-               c = *in;
-               for(j = 7; j >= 0; j--)
-                       *out++ = (c >> j) & 01;
-               i += 8;
-       }
-}
-
-/* The inverse of Expand
- */
-static void Collapse(u_char *in, u_char *out)
-{
-       int j;
-       int i;
-       unsigned int c;
-       
-       for (i = 0; i < 64; i += 8, out++) {
-               c = 0;
-               for (j = 7; j >= 0; j--, in++)
-                       c |= *in << j;
-               *out = c & 0xff;
-       }
-}
-#endif
-
-static void MakeKey(
-       u_char *key,            /* IN  56 bit DES key missing parity bits */
-       u_char *des_key         /* OUT 64 bit DES key with parity bits added */
-)
-{
-       des_key[0] = Get7Bits(key,  0);
-       des_key[1] = Get7Bits(key,  7);
-       des_key[2] = Get7Bits(key, 14);
-       des_key[3] = Get7Bits(key, 21);
-       des_key[4] = Get7Bits(key, 28);
-       des_key[5] = Get7Bits(key, 35);
-       des_key[6] = Get7Bits(key, 42);
-       des_key[7] = Get7Bits(key, 49);
-       
-#ifndef USE_CRYPT
-       des_set_odd_parity((des_cblock *)des_key);
-#endif
-       
-#if 0
-       CHAPDEBUG((LOG_INFO, "MakeKey: 56-bit input : %02X%02X%02X%02X%02X%02X%02X\n",
-              key[0], key[1], key[2], key[3], key[4], key[5], key[6]));
-       CHAPDEBUG((LOG_INFO, "MakeKey: 64-bit output: %02X%02X%02X%02X%02X%02X%02X%02X\n",
-              des_key[0], des_key[1], des_key[2], des_key[3], des_key[4], des_key[5], des_key[6], des_key[7]));
-#endif
-}
-
-static void ChapMS_NT(
-       char *rchallenge,
-       int rchallenge_len,
-       char *secret,
-       int secret_len,
-       MS_ChapResponse *response
-)
-{
-       int                     i;
-       MDstruct        md4Context;
-       u_char          unicodePassword[MAX_NT_PASSWORD * 2];
-       static int      low_byte_first = -1;
-       
-       /* Initialize the Unicode version of the secret (== password). */
-       /* This implicitly supports 8-bit ISO8859/1 characters. */
-       BZERO(unicodePassword, sizeof(unicodePassword));
-       for (i = 0; i < secret_len; i++)
-               unicodePassword[i * 2] = (u_char)secret[i];
-       
-       MDbegin(&md4Context);
-       MDupdate(&md4Context, unicodePassword, secret_len * 2 * 8);     /* Unicode is 2 bytes/char, *8 for bit count */
-       
-       if (low_byte_first == -1)
-               low_byte_first = (htons((unsigned short int)1) != 1);
-       if (low_byte_first == 0)
-               MDreverse((u_long *)&md4Context);  /*  sfb 961105 */
-       
-       MDupdate(&md4Context, NULL, 0); /* Tell MD4 we're done */
-       
-       ChallengeResponse(rchallenge, (char *)md4Context.buffer, response->NTResp);
-}
-
-#ifdef MSLANMAN
-static u_char *StdText = (u_char *)"KGS!@#$%"; /* key from rasapi32.dll */
-
-static ChapMS_LANMan(
-       char *rchallenge,
-       int rchallenge_len,
-       char *secret,
-       int secret_len,
-       MS_ChapResponse *response
-)
-{
-       int                     i;
-       u_char          UcasePassword[MAX_NT_PASSWORD]; /* max is actually 14 */
-       u_char          PasswordHash[16];
-       
-       /* LANMan password is case insensitive */
-       BZERO(UcasePassword, sizeof(UcasePassword));
-       for (i = 0; i < secret_len; i++)
-               UcasePassword[i] = (u_char)toupper(secret[i]);
-       DesEncrypt( StdText, UcasePassword + 0, PasswordHash + 0 );
-       DesEncrypt( StdText, UcasePassword + 7, PasswordHash + 8 );
-       ChallengeResponse(rchallenge, PasswordHash, response->LANManResp);
-}
-#endif
-
-#endif /* MSCHAP_SUPPORT */
-
+/*** WARNING - THIS CODE HAS NOT BEEN FINISHED! ***/\r
+/*****************************************************************************\r
+* chpms.c - Network MicroSoft Challenge Handshake Authentication Protocol program file.\r
+*\r
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.\r
+* Copyright (c) 1997 by Global Election Systems Inc.  All rights reserved.\r
+*\r
+* The authors hereby grant permission to use, copy, modify, distribute,\r
+* and license this software and its documentation for any purpose, provided\r
+* that existing copyright notices are retained in all copies and that this\r
+* notice and the following disclaimer are included verbatim in any \r
+* distributions. No written agreement, license, or royalty fee is required\r
+* for any of the authorized uses.\r
+*\r
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR\r
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+*\r
+******************************************************************************\r
+* REVISION HISTORY\r
+*\r
+* 03-01-01 Marc Boucher <marc@mbsi.ca>\r
+*   Ported to lwIP.\r
+* 97-12-08 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.\r
+*      Original based on BSD chap_ms.c.\r
+*****************************************************************************/\r
+/*\r
+ * chap_ms.c - Microsoft MS-CHAP compatible implementation.\r
+ *\r
+ * Copyright (c) 1995 Eric Rosenquist, Strata Software Limited.\r
+ * http://www.strataware.com/\r
+ *\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms are permitted\r
+ * provided that the above copyright notice and this paragraph are\r
+ * duplicated in all such forms and that any documentation,\r
+ * advertising materials, and other materials related to such\r
+ * distribution and use acknowledge that the software was developed\r
+ * by Eric Rosenquist.  The name of the author may not be used to\r
+ * endorse or promote products derived from this software without\r
+ * specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR\r
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r
+ */\r
+\r
+/*\r
+ * Modifications by Lauri Pesonen / lpesonen@clinet.fi, april 1997\r
+ *\r
+ *   Implemented LANManager type password response to MS-CHAP challenges.\r
+ *   Now pppd provides both NT style and LANMan style blocks, and the\r
+ *   prefered is set by option "ms-lanman". Default is to use NT.\r
+ *   The hash text (StdText) was taken from Win95 RASAPI32.DLL.\r
+ *\r
+ *   You should also use DOMAIN\\USERNAME as described in README.MSCHAP80\r
+ */\r
+\r
+#define USE_CRYPT\r
+\r
+\r
+#include "ppp.h"\r
+\r
+#if MSCHAP_SUPPORT > 0\r
+\r
+#include "md4.h"\r
+#ifndef USE_CRYPT\r
+#include "des.h"\r
+#endif\r
+#include "chap.h"\r
+#include "chpms.h"\r
+#include "pppdebug.h"\r
+\r
+\r
+/*************************/\r
+/*** LOCAL DEFINITIONS ***/\r
+/*************************/\r
+\r
+\r
+/************************/\r
+/*** LOCAL DATA TYPES ***/\r
+/************************/\r
+typedef struct {\r
+    u_char LANManResp[24];\r
+    u_char NTResp[24];\r
+    u_char UseNT;              /* If 1, ignore the LANMan response field */\r
+} MS_ChapResponse;\r
+/* We use MS_CHAP_RESPONSE_LEN, rather than sizeof(MS_ChapResponse),\r
+   in case this struct gets padded. */\r
+\r
+\r
+\r
+/***********************************/\r
+/*** LOCAL FUNCTION DECLARATIONS ***/\r
+/***********************************/\r
+\r
+/* XXX Don't know what to do with these. */\r
+extern void setkey(const char *);\r
+extern void encrypt(char *, int);\r
+\r
+static void    DesEncrypt (u_char *, u_char *, u_char *);\r
+static void    MakeKey (u_char *, u_char *);\r
+\r
+#ifdef USE_CRYPT\r
+static void    Expand (u_char *, u_char *);\r
+static void    Collapse (u_char *, u_char *);\r
+#endif\r
+\r
+static void ChallengeResponse(\r
+       u_char *challenge,      /* IN   8 octets */\r
+       u_char *pwHash,         /* IN  16 octets */\r
+       u_char *response        /* OUT 24 octets */\r
+);\r
+static void ChapMS_NT(\r
+       char *rchallenge,\r
+       int rchallenge_len,\r
+       char *secret,\r
+       int secret_len,\r
+       MS_ChapResponse *response\r
+);\r
+static u_char Get7Bits(\r
+       u_char *input,\r
+       int startBit\r
+);\r
+\r
+\r
+/***********************************/\r
+/*** PUBLIC FUNCTION DEFINITIONS ***/\r
+/***********************************/\r
+void ChapMS(\r
+       chap_state *cstate,\r
+       char *rchallenge,\r
+       int rchallenge_len,\r
+       char *secret,\r
+       int secret_len\r
+)\r
+{\r
+       MS_ChapResponse response;\r
+#ifdef MSLANMAN\r
+       extern int ms_lanman;\r
+#endif\r
+       \r
+#if 0\r
+       CHAPDEBUG((LOG_INFO, "ChapMS: secret is '%.*s'\n", secret_len, secret));\r
+#endif\r
+       BZERO(&response, sizeof(response));\r
+       \r
+       /* Calculate both always */\r
+       ChapMS_NT(rchallenge, rchallenge_len, secret, secret_len, &response);\r
+       \r
+#ifdef MSLANMAN\r
+       ChapMS_LANMan(rchallenge, rchallenge_len, secret, secret_len, &response);\r
+       \r
+       /* prefered method is set by option  */\r
+       response.UseNT = !ms_lanman;\r
+#else\r
+       response.UseNT = 1;\r
+#endif\r
+       \r
+       BCOPY(&response, cstate->response, MS_CHAP_RESPONSE_LEN);\r
+       cstate->resp_length = MS_CHAP_RESPONSE_LEN;\r
+}\r
+\r
+\r
+/**********************************/\r
+/*** LOCAL FUNCTION DEFINITIONS ***/\r
+/**********************************/\r
+static void ChallengeResponse(\r
+       u_char *challenge,      /* IN   8 octets */\r
+       u_char *pwHash,         /* IN  16 octets */\r
+       u_char *response        /* OUT 24 octets */\r
+)\r
+{\r
+       char    ZPasswordHash[21];\r
+       \r
+       BZERO(ZPasswordHash, sizeof(ZPasswordHash));\r
+       BCOPY(pwHash, ZPasswordHash, 16);\r
+       \r
+#if 0\r
+       log_packet(ZPasswordHash, sizeof(ZPasswordHash), "ChallengeResponse - ZPasswordHash", LOG_DEBUG);\r
+#endif\r
+       \r
+       DesEncrypt(challenge, ZPasswordHash +  0, response + 0);\r
+       DesEncrypt(challenge, ZPasswordHash +  7, response + 8);\r
+       DesEncrypt(challenge, ZPasswordHash + 14, response + 16);\r
+       \r
+#if 0\r
+       log_packet(response, 24, "ChallengeResponse - response", LOG_DEBUG);\r
+#endif\r
+}\r
+\r
+\r
+#ifdef USE_CRYPT\r
+static void DesEncrypt(\r
+       u_char *clear,  /* IN  8 octets */\r
+       u_char *key,    /* IN  7 octets */\r
+       u_char *cipher  /* OUT 8 octets */\r
+)\r
+{\r
+       u_char des_key[8];\r
+       u_char crypt_key[66];\r
+       u_char des_input[66];\r
+       \r
+       MakeKey(key, des_key);\r
+       \r
+       Expand(des_key, crypt_key);\r
+       setkey(crypt_key);\r
+       \r
+#if 0\r
+       CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet input : %02X%02X%02X%02X%02X%02X%02X%02X\n",\r
+              clear[0], clear[1], clear[2], clear[3], clear[4], clear[5], clear[6], clear[7]));\r
+#endif\r
+       \r
+       Expand(clear, des_input);\r
+       encrypt(des_input, 0);\r
+       Collapse(des_input, cipher);\r
+       \r
+#if 0\r
+       CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet output: %02X%02X%02X%02X%02X%02X%02X%02X\n",\r
+              cipher[0], cipher[1], cipher[2], cipher[3], cipher[4], cipher[5], cipher[6], cipher[7]));\r
+#endif\r
+}\r
+\r
+#else /* USE_CRYPT */\r
+\r
+static void DesEncrypt(\r
+       u_char *clear,  /* IN  8 octets */\r
+       u_char *key,    /* IN  7 octets */\r
+       u_char *cipher  /* OUT 8 octets */\r
+)\r
+{\r
+       des_cblock              des_key;\r
+       des_key_schedule        key_schedule;\r
+       \r
+       MakeKey(key, des_key);\r
+       \r
+       des_set_key(&des_key, key_schedule);\r
+       \r
+#if 0\r
+       CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet input : %02X%02X%02X%02X%02X%02X%02X%02X\n",\r
+              clear[0], clear[1], clear[2], clear[3], clear[4], clear[5], clear[6], clear[7]));\r
+#endif\r
+       \r
+       des_ecb_encrypt((des_cblock *)clear, (des_cblock *)cipher, key_schedule, 1);\r
+       \r
+#if 0\r
+       CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet output: %02X%02X%02X%02X%02X%02X%02X%02X\n",\r
+              cipher[0], cipher[1], cipher[2], cipher[3], cipher[4], cipher[5], cipher[6], cipher[7]));\r
+#endif\r
+}\r
+\r
+#endif /* USE_CRYPT */\r
+\r
+\r
+static u_char Get7Bits(\r
+       u_char *input,\r
+       int startBit\r
+)\r
+{\r
+       register unsigned int   word;\r
+       \r
+       word  = (unsigned)input[startBit / 8] << 8;\r
+       word |= (unsigned)input[startBit / 8 + 1];\r
+       \r
+       word >>= 15 - (startBit % 8 + 7);\r
+       \r
+       return word & 0xFE;\r
+}\r
+\r
+#ifdef USE_CRYPT\r
+\r
+/* in == 8-byte string (expanded version of the 56-bit key)\r
+ * out == 64-byte string where each byte is either 1 or 0\r
+ * Note that the low-order "bit" is always ignored by by setkey()\r
+ */\r
+static void Expand(u_char *in, u_char *out)\r
+{\r
+       int j, c;\r
+       int i;\r
+       \r
+       for(i = 0; i < 64; in++){\r
+               c = *in;\r
+               for(j = 7; j >= 0; j--)\r
+                       *out++ = (c >> j) & 01;\r
+               i += 8;\r
+       }\r
+}\r
+\r
+/* The inverse of Expand\r
+ */\r
+static void Collapse(u_char *in, u_char *out)\r
+{\r
+       int j;\r
+       int i;\r
+       unsigned int c;\r
+       \r
+       for (i = 0; i < 64; i += 8, out++) {\r
+               c = 0;\r
+               for (j = 7; j >= 0; j--, in++)\r
+                       c |= *in << j;\r
+               *out = c & 0xff;\r
+       }\r
+}\r
+#endif\r
+\r
+static void MakeKey(\r
+       u_char *key,            /* IN  56 bit DES key missing parity bits */\r
+       u_char *des_key         /* OUT 64 bit DES key with parity bits added */\r
+)\r
+{\r
+       des_key[0] = Get7Bits(key,  0);\r
+       des_key[1] = Get7Bits(key,  7);\r
+       des_key[2] = Get7Bits(key, 14);\r
+       des_key[3] = Get7Bits(key, 21);\r
+       des_key[4] = Get7Bits(key, 28);\r
+       des_key[5] = Get7Bits(key, 35);\r
+       des_key[6] = Get7Bits(key, 42);\r
+       des_key[7] = Get7Bits(key, 49);\r
+       \r
+#ifndef USE_CRYPT\r
+       des_set_odd_parity((des_cblock *)des_key);\r
+#endif\r
+       \r
+#if 0\r
+       CHAPDEBUG((LOG_INFO, "MakeKey: 56-bit input : %02X%02X%02X%02X%02X%02X%02X\n",\r
+              key[0], key[1], key[2], key[3], key[4], key[5], key[6]));\r
+       CHAPDEBUG((LOG_INFO, "MakeKey: 64-bit output: %02X%02X%02X%02X%02X%02X%02X%02X\n",\r
+              des_key[0], des_key[1], des_key[2], des_key[3], des_key[4], des_key[5], des_key[6], des_key[7]));\r
+#endif\r
+}\r
+\r
+static void ChapMS_NT(\r
+       char *rchallenge,\r
+       int rchallenge_len,\r
+       char *secret,\r
+       int secret_len,\r
+       MS_ChapResponse *response\r
+)\r
+{\r
+       int                     i;\r
+       MDstruct        md4Context;\r
+       u_char          unicodePassword[MAX_NT_PASSWORD * 2];\r
+       static int      low_byte_first = -1;\r
+       \r
+       /* Initialize the Unicode version of the secret (== password). */\r
+       /* This implicitly supports 8-bit ISO8859/1 characters. */\r
+       BZERO(unicodePassword, sizeof(unicodePassword));\r
+       for (i = 0; i < secret_len; i++)\r
+               unicodePassword[i * 2] = (u_char)secret[i];\r
+       \r
+       MDbegin(&md4Context);\r
+       MDupdate(&md4Context, unicodePassword, secret_len * 2 * 8);     /* Unicode is 2 bytes/char, *8 for bit count */\r
+       \r
+       if (low_byte_first == -1)\r
+               low_byte_first = (htons((unsigned short int)1) != 1);\r
+       if (low_byte_first == 0)\r
+               MDreverse((u_long *)&md4Context);  /*  sfb 961105 */\r
+       \r
+       MDupdate(&md4Context, NULL, 0); /* Tell MD4 we're done */\r
+       \r
+       ChallengeResponse(rchallenge, (char *)md4Context.buffer, response->NTResp);\r
+}\r
+\r
+#ifdef MSLANMAN\r
+static u_char *StdText = (u_char *)"KGS!@#$%"; /* key from rasapi32.dll */\r
+\r
+static ChapMS_LANMan(\r
+       char *rchallenge,\r
+       int rchallenge_len,\r
+       char *secret,\r
+       int secret_len,\r
+       MS_ChapResponse *response\r
+)\r
+{\r
+       int                     i;\r
+       u_char          UcasePassword[MAX_NT_PASSWORD]; /* max is actually 14 */\r
+       u_char          PasswordHash[16];\r
+       \r
+       /* LANMan password is case insensitive */\r
+       BZERO(UcasePassword, sizeof(UcasePassword));\r
+       for (i = 0; i < secret_len; i++)\r
+               UcasePassword[i] = (u_char)toupper(secret[i]);\r
+       DesEncrypt( StdText, UcasePassword + 0, PasswordHash + 0 );\r
+       DesEncrypt( StdText, UcasePassword + 7, PasswordHash + 8 );\r
+       ChallengeResponse(rchallenge, PasswordHash, response->LANManResp);\r
+}\r
+#endif\r
+\r
+#endif /* MSCHAP_SUPPORT */\r
+\r
index c58447215a7b3aef8e7b754b3cc01c00243eb489..0b30c6554b5fbbc52482e089713e5681d943fa06 100644 (file)
@@ -1,64 +1,64 @@
-/*****************************************************************************
-* chpms.h - Network Microsoft Challenge Handshake Protocol header file.
-*
-* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
-* portions Copyright (c) 1998 Global Election Systems Inc.
-*
-* The authors hereby grant permission to use, copy, modify, distribute,
-* and license this software and its documentation for any purpose, provided
-* that existing copyright notices are retained in all copies and that this
-* notice and the following disclaimer are included verbatim in any 
-* distributions. No written agreement, license, or royalty fee is required
-* for any of the authorized uses.
-*
-* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *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 CONTRIBUTORS 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.
-*
-******************************************************************************
-* REVISION HISTORY
-*
-* 03-01-01 Marc Boucher <marc@mbsi.ca>
-*   Ported to lwIP.
-* 98-01-30 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
-*      Original built from BSD network code.
-******************************************************************************/
-/*
- * chap.h - Challenge Handshake Authentication Protocol definitions.
- *
- * Copyright (c) 1995 Eric Rosenquist, Strata Software Limited.
- * http://www.strataware.com/
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by Eric Rosenquist.  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 ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * $Id: chpms.h,v 1.3 2004/02/07 00:30:03 likewise Exp $
- */
-
-#ifndef CHPMS_H
-#define CHPMS_H
-
-#define MAX_NT_PASSWORD        256     /* Maximum number of (Unicode) chars in an NT password */
-
-void ChapMS (chap_state *, char *, int, char *, int);
-
-#endif /* CHPMS_H */
+/*****************************************************************************\r
+* chpms.h - Network Microsoft Challenge Handshake Protocol header file.\r
+*\r
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.\r
+* portions Copyright (c) 1998 Global Election Systems Inc.\r
+*\r
+* The authors hereby grant permission to use, copy, modify, distribute,\r
+* and license this software and its documentation for any purpose, provided\r
+* that existing copyright notices are retained in all copies and that this\r
+* notice and the following disclaimer are included verbatim in any \r
+* distributions. No written agreement, license, or royalty fee is required\r
+* for any of the authorized uses.\r
+*\r
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR\r
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+*\r
+******************************************************************************\r
+* REVISION HISTORY\r
+*\r
+* 03-01-01 Marc Boucher <marc@mbsi.ca>\r
+*   Ported to lwIP.\r
+* 98-01-30 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.\r
+*      Original built from BSD network code.\r
+******************************************************************************/\r
+/*\r
+ * chap.h - Challenge Handshake Authentication Protocol definitions.\r
+ *\r
+ * Copyright (c) 1995 Eric Rosenquist, Strata Software Limited.\r
+ * http://www.strataware.com/\r
+ *\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms are permitted\r
+ * provided that the above copyright notice and this paragraph are\r
+ * duplicated in all such forms and that any documentation,\r
+ * advertising materials, and other materials related to such\r
+ * distribution and use acknowledge that the software was developed\r
+ * by Eric Rosenquist.  The name of the author may not be used to\r
+ * endorse or promote products derived from this software without\r
+ * specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR\r
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r
+ *\r
+ * $Id: chpms.h,v 1.3 2004/02/07 00:30:03 likewise Exp $\r
+ */\r
+\r
+#ifndef CHPMS_H\r
+#define CHPMS_H\r
+\r
+#define MAX_NT_PASSWORD        256     /* Maximum number of (Unicode) chars in an NT password */\r
+\r
+void ChapMS (chap_state *, char *, int, char *, int);\r
+\r
+#endif /* CHPMS_H */\r
index fe8b38a93596226f2f71f563461786b42b54da37..6cad71525e004e0bac5a94d99b8eb3617d2ab5ee 100644 (file)
-/*****************************************************************************
-* fsm.c - Network Control Protocol Finite State Machine program file.
-*
-* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
-* portions Copyright (c) 1997 by Global Election Systems Inc.
-*
-* The authors hereby grant permission to use, copy, modify, distribute,
-* and license this software and its documentation for any purpose, provided
-* that existing copyright notices are retained in all copies and that this
-* notice and the following disclaimer are included verbatim in any 
-* distributions. No written agreement, license, or royalty fee is required
-* for any of the authorized uses.
-*
-* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *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 CONTRIBUTORS 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.
-*
-******************************************************************************
-* REVISION HISTORY
-*
-* 03-01-01 Marc Boucher <marc@mbsi.ca>
-*   Ported to lwIP.
-* 97-12-01 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
-*      Original based on BSD fsm.c.
-*****************************************************************************/
-/*
- * fsm.c - {Link, IP} Control Protocol Finite State Machine.
- *
- * Copyright (c) 1989 Carnegie Mellon University.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by Carnegie Mellon University.  The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-
-/*
- * TODO:
- * Randomize fsm id on link/init.
- * Deal with variable outgoing MTU.
- */
-
-#include "ppp.h"
-#if PPP_SUPPORT > 0
-#include "fsm.h"
-#include "pppdebug.h"
-
-
-/*************************/
-/*** LOCAL DEFINITIONS ***/
-/*************************/
-
-
-/************************/
-/*** LOCAL DATA TYPES ***/
-/************************/
-
-
-/***********************************/
-/*** LOCAL FUNCTION DECLARATIONS ***/
-/***********************************/
-static void fsm_timeout (void *);
-static void fsm_rconfreq (fsm *, u_char, u_char *, int);
-static void fsm_rconfack (fsm *, int, u_char *, int);
-static void fsm_rconfnakrej (fsm *, int, int, u_char *, int);
-static void fsm_rtermreq (fsm *, int, u_char *, int);
-static void fsm_rtermack (fsm *);
-static void fsm_rcoderej (fsm *, u_char *, int);
-static void fsm_sconfreq (fsm *, int);
-
-#define PROTO_NAME(f)  ((f)->callbacks->proto_name)
-
-
-/******************************/
-/*** PUBLIC DATA STRUCTURES ***/
-/******************************/
-
-
-/*****************************/
-/*** LOCAL DATA STRUCTURES ***/
-/*****************************/
-int peer_mru[NUM_PPP];
-
-
-/***********************************/
-/*** PUBLIC FUNCTION DEFINITIONS ***/
-/***********************************/
-
-/*
- * fsm_init - Initialize fsm.
- *
- * Initialize fsm state.
- */
-void fsm_init(fsm *f)
-{
-       f->state = INITIAL;
-       f->flags = 0;
-       f->id = 0;                              /* XXX Start with random id? */
-       f->timeouttime = FSM_DEFTIMEOUT;
-       f->maxconfreqtransmits = FSM_DEFMAXCONFREQS;
-       f->maxtermtransmits = FSM_DEFMAXTERMREQS;
-       f->maxnakloops = FSM_DEFMAXNAKLOOPS;
-       f->term_reason_len = 0;
-}
-
-
-/*
- * fsm_lowerup - The lower layer is up.
- */
-void fsm_lowerup(fsm *f)
-{
-       int oldState = f->state;
-
-       switch( f->state ){
-       case INITIAL:
-               f->state = CLOSED;
-               break;
-       
-       case STARTING:
-               if( f->flags & OPT_SILENT )
-                       f->state = STOPPED;
-               else {
-                       /* Send an initial configure-request */
-                       fsm_sconfreq(f, 0);
-                       f->state = REQSENT;
-               }
-       break;
-       
-       default:
-               FSMDEBUG((LOG_INFO, "%s: Up event in state %d!\n",
-                               PROTO_NAME(f), f->state));
-       }
-       
-       FSMDEBUG((LOG_INFO, "%s: lowerup state %d -> %d\n",
-                       PROTO_NAME(f), oldState, f->state));
-}
-
-
-/*
- * fsm_lowerdown - The lower layer is down.
- *
- * Cancel all timeouts and inform upper layers.
- */
-void fsm_lowerdown(fsm *f)
-{
-       int oldState = f->state;
-       
-       switch( f->state ){
-       case CLOSED:
-               f->state = INITIAL;
-               break;
-       
-       case STOPPED:
-               f->state = STARTING;
-               if( f->callbacks->starting )
-                       (*f->callbacks->starting)(f);
-               break;
-       
-       case CLOSING:
-               f->state = INITIAL;
-               UNTIMEOUT(fsm_timeout, f);      /* Cancel timeout */
-               break;
-       
-       case STOPPING:
-       case REQSENT:
-       case ACKRCVD:
-       case ACKSENT:
-               f->state = STARTING;
-               UNTIMEOUT(fsm_timeout, f);      /* Cancel timeout */
-               break;
-       
-       case OPENED:
-               if( f->callbacks->down )
-                       (*f->callbacks->down)(f);
-               f->state = STARTING;
-               break;
-       
-       default:
-               FSMDEBUG((LOG_INFO, "%s: Down event in state %d!\n",
-                               PROTO_NAME(f), f->state));
-       }
-       
-       FSMDEBUG((LOG_INFO, "%s: lowerdown state %d -> %d\n",
-                       PROTO_NAME(f), oldState, f->state));
-}
-
-
-/*
- * fsm_open - Link is allowed to come up.
- */
-void fsm_open(fsm *f)
-{
-       int oldState = f->state;
-       
-       switch( f->state ){
-               case INITIAL:
-                       f->state = STARTING;
-                       if( f->callbacks->starting )
-                               (*f->callbacks->starting)(f);
-                       break;
-               
-               case CLOSED:
-               if( f->flags & OPT_SILENT )
-                       f->state = STOPPED;
-               else {
-                       /* Send an initial configure-request */
-                       fsm_sconfreq(f, 0);
-                       f->state = REQSENT;
-               }
-               break;
-       
-       case CLOSING:
-               f->state = STOPPING;
-               /* fall through */
-       case STOPPED:
-       case OPENED:
-               if( f->flags & OPT_RESTART ){
-                       fsm_lowerdown(f);
-                       fsm_lowerup(f);
-               }
-               break;
-       }
-       
-       FSMDEBUG((LOG_INFO, "%s: open state %d -> %d\n",
-                       PROTO_NAME(f), oldState, f->state));
-}
-
-
-/*
- * fsm_close - Start closing connection.
- *
- * Cancel timeouts and either initiate close or possibly go directly to
- * the CLOSED state.
- */
-void fsm_close(fsm *f, char *reason)
-{
-       int oldState = f->state;
-       
-       f->term_reason = reason;
-       f->term_reason_len = (reason == NULL? 0: strlen(reason));
-       switch( f->state ){
-       case STARTING:
-               f->state = INITIAL;
-               break;
-       case STOPPED:
-               f->state = CLOSED;
-               break;
-       case STOPPING:
-               f->state = CLOSING;
-               break;
-       
-       case REQSENT:
-       case ACKRCVD:
-       case ACKSENT:
-       case OPENED:
-               if( f->state != OPENED )
-                       UNTIMEOUT(fsm_timeout, f);      /* Cancel timeout */
-               else if( f->callbacks->down )
-                       (*f->callbacks->down)(f);       /* Inform upper layers we're down */
-               
-               /* Init restart counter, send Terminate-Request */
-               f->retransmits = f->maxtermtransmits;
-               fsm_sdata(f, TERMREQ, f->reqid = ++f->id,
-                                       (u_char *) f->term_reason, f->term_reason_len);
-               TIMEOUT(fsm_timeout, f, f->timeouttime);
-               --f->retransmits;
-               
-               f->state = CLOSING;
-               break;
-       }
-       
-       FSMDEBUG((LOG_INFO, "%s: close reason=%s state %d -> %d\n",
-                       PROTO_NAME(f), reason, oldState, f->state));
-}
-
-
-/*
- * fsm_sdata - Send some data.
- *
- * Used for all packets sent to our peer by this module.
- */
-void fsm_sdata(
-       fsm *f,
-       u_char code, 
-       u_char id,
-       u_char *data,
-       int datalen
-)
-{
-       u_char *outp;
-       int outlen;
-       
-       /* Adjust length to be smaller than MTU */
-       outp = outpacket_buf[f->unit];
-       if (datalen > peer_mru[f->unit] - (int)HEADERLEN)
-               datalen = peer_mru[f->unit] - HEADERLEN;
-       if (datalen && data != outp + PPP_HDRLEN + HEADERLEN)
-               BCOPY(data, outp + PPP_HDRLEN + HEADERLEN, datalen);
-       outlen = datalen + HEADERLEN;
-       MAKEHEADER(outp, f->protocol);
-       PUTCHAR(code, outp);
-       PUTCHAR(id, outp);
-       PUTSHORT(outlen, outp);
-       pppWrite(f->unit, outpacket_buf[f->unit], outlen + PPP_HDRLEN);
-       FSMDEBUG((LOG_INFO, "fsm_sdata(%s): Sent code %d,%d,%d.\n",
-                               PROTO_NAME(f), code, id, outlen));
-}
-
-
-/*
- * fsm_input - Input packet.
- */
-void fsm_input(fsm *f, u_char *inpacket, int l)
-{
-       u_char *inp = inpacket;
-       u_char code, id;
-       int len;
-       
-       /*
-       * Parse header (code, id and length).
-       * If packet too short, drop it.
-       */
-       if (l < HEADERLEN) {
-               FSMDEBUG((LOG_WARNING, "fsm_input(%x): Rcvd short header.\n",
-                                       f->protocol));
-               return;
-       }
-       GETCHAR(code, inp);
-       GETCHAR(id, inp);
-       GETSHORT(len, inp);
-       if (len < HEADERLEN) {
-               FSMDEBUG((LOG_INFO, "fsm_input(%x): Rcvd illegal length.\n",
-                               f->protocol));
-               return;
-       }
-       if (len > l) {
-               FSMDEBUG((LOG_INFO, "fsm_input(%x): Rcvd short packet.\n",
-                               f->protocol));
-               return;
-       }
-       len -= HEADERLEN;               /* subtract header length */
-       
-       if( f->state == INITIAL || f->state == STARTING ){
-               FSMDEBUG((LOG_INFO, "fsm_input(%x): Rcvd packet in state %d.\n",
-                               f->protocol, f->state));
-               return;
-       }
-       FSMDEBUG((LOG_INFO, "fsm_input(%s):%d,%d,%d\n", PROTO_NAME(f), code, id, l));
-       /*
-        * Action depends on code.
-        */
-       switch (code) {
-       case CONFREQ:
-               fsm_rconfreq(f, id, inp, len);
-               break;
-       
-       case CONFACK:
-               fsm_rconfack(f, id, inp, len);
-               break;
-       
-       case CONFNAK:
-       case CONFREJ:
-               fsm_rconfnakrej(f, code, id, inp, len);
-               break;
-       
-       case TERMREQ:
-               fsm_rtermreq(f, id, inp, len);
-               break;
-       
-       case TERMACK:
-               fsm_rtermack(f);
-               break;
-       
-       case CODEREJ:
-               fsm_rcoderej(f, inp, len);
-               break;
-       
-       default:
-               if( !f->callbacks->extcode
-                               || !(*f->callbacks->extcode)(f, code, id, inp, len) )
-                       fsm_sdata(f, CODEREJ, ++f->id, inpacket, len + HEADERLEN);
-               break;
-       }
-}
-
-
-/*
- * fsm_protreject - Peer doesn't speak this protocol.
- *
- * Treat this as a catastrophic error (RXJ-).
- */
-void fsm_protreject(fsm *f)
-{
-       switch( f->state ){
-       case CLOSING:
-               UNTIMEOUT(fsm_timeout, f);      /* Cancel timeout */
-               /* fall through */
-       case CLOSED:
-               f->state = CLOSED;
-               if( f->callbacks->finished )
-                       (*f->callbacks->finished)(f);
-               break;
-       
-       case STOPPING:
-       case REQSENT:
-       case ACKRCVD:
-       case ACKSENT:
-               UNTIMEOUT(fsm_timeout, f);      /* Cancel timeout */
-               /* fall through */
-       case STOPPED:
-               f->state = STOPPED;
-               if( f->callbacks->finished )
-                       (*f->callbacks->finished)(f);
-               break;
-       
-       case OPENED:
-               if( f->callbacks->down )
-                       (*f->callbacks->down)(f);
-               
-               /* Init restart counter, send Terminate-Request */
-               f->retransmits = f->maxtermtransmits;
-               fsm_sdata(f, TERMREQ, f->reqid = ++f->id,
-                                       (u_char *) f->term_reason, f->term_reason_len);
-               TIMEOUT(fsm_timeout, f, f->timeouttime);
-               --f->retransmits;
-               
-               f->state = STOPPING;
-               break;
-       
-       default:
-               FSMDEBUG((LOG_INFO, "%s: Protocol-reject event in state %d!\n",
-                                       PROTO_NAME(f), f->state));
-       }
-}
-
-
-
-
-
-/**********************************/
-/*** LOCAL FUNCTION DEFINITIONS ***/
-/**********************************/
-
-/*
- * fsm_timeout - Timeout expired.
- */
-static void fsm_timeout(void *arg)
-{
-    fsm *f = (fsm *) arg;
-
-    switch (f->state) {
-    case CLOSING:
-    case STOPPING:
-               if( f->retransmits <= 0 ){
-                   FSMDEBUG((LOG_WARNING, "%s: timeout sending Terminate-Request state=%d\n",
-                                          PROTO_NAME(f), f->state));
-                   /*
-                    * We've waited for an ack long enough.  Peer probably heard us.
-                    */
-                   f->state = (f->state == CLOSING)? CLOSED: STOPPED;
-                   if( f->callbacks->finished )
-                       (*f->callbacks->finished)(f);
-               } else {
-                   FSMDEBUG((LOG_WARNING, "%s: timeout resending Terminate-Requests state=%d\n",
-                                          PROTO_NAME(f), f->state));
-                   /* Send Terminate-Request */
-                   fsm_sdata(f, TERMREQ, f->reqid = ++f->id,
-                             (u_char *) f->term_reason, f->term_reason_len);
-                   TIMEOUT(fsm_timeout, f, f->timeouttime);
-                   --f->retransmits;
-               }
-               break;
-
-    case REQSENT:
-    case ACKRCVD:
-    case ACKSENT:
-               if (f->retransmits <= 0) {
-                   FSMDEBUG((LOG_WARNING, "%s: timeout sending Config-Requests state=%d\n",
-                          PROTO_NAME(f), f->state));
-                   f->state = STOPPED;
-                   if( (f->flags & OPT_PASSIVE) == 0 && f->callbacks->finished )
-                               (*f->callbacks->finished)(f);
-       
-               } else {
-                   FSMDEBUG((LOG_WARNING, "%s: timeout resending Config-Request state=%d\n",
-                          PROTO_NAME(f), f->state));
-                   /* Retransmit the configure-request */
-                   if (f->callbacks->retransmit)
-                               (*f->callbacks->retransmit)(f);
-                   fsm_sconfreq(f, 1);         /* Re-send Configure-Request */
-                   if( f->state == ACKRCVD )
-                               f->state = REQSENT;
-               }
-               break;
-
-    default:
-               FSMDEBUG((LOG_INFO, "%s: Timeout event in state %d!\n",
-                                 PROTO_NAME(f), f->state));
-           }
-}
-
-
-/*
- * fsm_rconfreq - Receive Configure-Request.
- */
-static void fsm_rconfreq(fsm *f, u_char id, u_char *inp, int len)
-{
-       int code, reject_if_disagree;
-       
-       FSMDEBUG((LOG_INFO, "fsm_rconfreq(%s): Rcvd id %d state=%d\n", 
-                               PROTO_NAME(f), id, f->state));
-       switch( f->state ){
-       case CLOSED:
-               /* Go away, we're closed */
-               fsm_sdata(f, TERMACK, id, NULL, 0);
-               return;
-       case CLOSING:
-       case STOPPING:
-               return;
-       
-       case OPENED:
-               /* Go down and restart negotiation */
-               if( f->callbacks->down )
-                       (*f->callbacks->down)(f);       /* Inform upper layers */
-               fsm_sconfreq(f, 0);             /* Send initial Configure-Request */
-               break;
-       
-       case STOPPED:
-               /* Negotiation started by our peer */
-               fsm_sconfreq(f, 0);             /* Send initial Configure-Request */
-               f->state = REQSENT;
-               break;
-       }
-       
-       /*
-       * Pass the requested configuration options
-       * to protocol-specific code for checking.
-       */
-       if (f->callbacks->reqci){               /* Check CI */
-               reject_if_disagree = (f->nakloops >= f->maxnakloops);
-               code = (*f->callbacks->reqci)(f, inp, &len, reject_if_disagree);
-       } 
-       else if (len)
-               code = CONFREJ;                 /* Reject all CI */
-       else
-               code = CONFACK;
-       
-       /* send the Ack, Nak or Rej to the peer */
-       fsm_sdata(f, (u_char)code, id, inp, len);
-       
-       if (code == CONFACK) {
-               if (f->state == ACKRCVD) {
-                       UNTIMEOUT(fsm_timeout, f);      /* Cancel timeout */
-                       f->state = OPENED;
-                       if (f->callbacks->up)
-                               (*f->callbacks->up)(f); /* Inform upper layers */
-               } 
-               else
-                       f->state = ACKSENT;
-               f->nakloops = 0;
-       } 
-       else {
-               /* we sent CONFACK or CONFREJ */
-               if (f->state != ACKRCVD)
-                       f->state = REQSENT;
-               if( code == CONFNAK )
-                       ++f->nakloops;
-       }
-}
-
-
-/*
- * fsm_rconfack - Receive Configure-Ack.
- */
-static void fsm_rconfack(fsm *f, int id, u_char *inp, int len)
-{
-       FSMDEBUG((LOG_INFO, "fsm_rconfack(%s): Rcvd id %d state=%d\n",
-                               PROTO_NAME(f), id, f->state));
-       
-       if (id != f->reqid || f->seen_ack)              /* Expected id? */
-               return;                                 /* Nope, toss... */
-       if( !(f->callbacks->ackci? (*f->callbacks->ackci)(f, inp, len):
-                                                               (len == 0)) ){
-               /* Ack is bad - ignore it */
-               FSMDEBUG((LOG_INFO, "%s: received bad Ack (length %d)\n",
-                                       PROTO_NAME(f), len));
-               return;
-       }
-       f->seen_ack = 1;
-       
-       switch (f->state) {
-       case CLOSED:
-       case STOPPED:
-               fsm_sdata(f, TERMACK, (u_char)id, NULL, 0);
-               break;
-       
-       case REQSENT:
-               f->state = ACKRCVD;
-               f->retransmits = f->maxconfreqtransmits;
-               break;
-       
-       case ACKRCVD:
-               /* Huh? an extra valid Ack? oh well... */
-               UNTIMEOUT(fsm_timeout, f);      /* Cancel timeout */
-               fsm_sconfreq(f, 0);
-               f->state = REQSENT;
-               break;
-       
-       case ACKSENT:
-               UNTIMEOUT(fsm_timeout, f);      /* Cancel timeout */
-               f->state = OPENED;
-               f->retransmits = f->maxconfreqtransmits;
-               if (f->callbacks->up)
-                       (*f->callbacks->up)(f); /* Inform upper layers */
-               break;
-       
-       case OPENED:
-               /* Go down and restart negotiation */
-               if (f->callbacks->down)
-                       (*f->callbacks->down)(f);       /* Inform upper layers */
-               fsm_sconfreq(f, 0);             /* Send initial Configure-Request */
-               f->state = REQSENT;
-               break;
-       }
-}
-
-
-/*
- * fsm_rconfnakrej - Receive Configure-Nak or Configure-Reject.
- */
-static void fsm_rconfnakrej(fsm *f, int code, int id, u_char *inp, int len)
-{
-       int (*proc) (fsm *, u_char *, int);
-       int ret;
-       
-       FSMDEBUG((LOG_INFO, "fsm_rconfnakrej(%s): Rcvd id %d state=%d\n",
-                               PROTO_NAME(f), id, f->state));
-       
-       if (id != f->reqid || f->seen_ack)      /* Expected id? */
-               return;                         /* Nope, toss... */
-       proc = (code == CONFNAK)? f->callbacks->nakci: f->callbacks->rejci;
-       if (!proc || !(ret = proc(f, inp, len))) {
-               /* Nak/reject is bad - ignore it */
-               FSMDEBUG((LOG_INFO, "%s: received bad %s (length %d)\n",
-                                       PROTO_NAME(f), (code==CONFNAK? "Nak": "reject"), len));
-               return;
-       }
-       f->seen_ack = 1;
-       
-       switch (f->state) {
-       case CLOSED:
-       case STOPPED:
-               fsm_sdata(f, TERMACK, (u_char)id, NULL, 0);
-               break;
-       
-       case REQSENT:
-       case ACKSENT:
-               /* They didn't agree to what we wanted - try another request */
-               UNTIMEOUT(fsm_timeout, f);      /* Cancel timeout */
-               if (ret < 0)
-                       f->state = STOPPED;             /* kludge for stopping CCP */
-               else
-                       fsm_sconfreq(f, 0);             /* Send Configure-Request */
-               break;
-       
-       case ACKRCVD:
-               /* Got a Nak/reject when we had already had an Ack?? oh well... */
-               UNTIMEOUT(fsm_timeout, f);      /* Cancel timeout */
-               fsm_sconfreq(f, 0);
-               f->state = REQSENT;
-               break;
-       
-       case OPENED:
-               /* Go down and restart negotiation */
-               if (f->callbacks->down)
-                       (*f->callbacks->down)(f);       /* Inform upper layers */
-               fsm_sconfreq(f, 0);             /* Send initial Configure-Request */
-               f->state = REQSENT;
-               break;
-       }
-}
-
-
-/*
- * fsm_rtermreq - Receive Terminate-Req.
- */
-static void fsm_rtermreq(fsm *f, int id, u_char *p, int len)
-{
-       FSMDEBUG((LOG_INFO, "fsm_rtermreq(%s): Rcvd id %d state=%d\n",
-                               PROTO_NAME(f), id, f->state));
-       
-       switch (f->state) {
-       case ACKRCVD:
-       case ACKSENT:
-               f->state = REQSENT;             /* Start over but keep trying */
-               break;
-       
-       case OPENED:
-               if (len > 0) {
-                       FSMDEBUG((LOG_INFO, "%s terminated by peer (%x)\n", PROTO_NAME(f), p));
-               } else {
-                       FSMDEBUG((LOG_INFO, "%s terminated by peer\n", PROTO_NAME(f)));
-               }
-               if (f->callbacks->down)
-                       (*f->callbacks->down)(f);       /* Inform upper layers */
-               f->retransmits = 0;
-               f->state = STOPPING;
-               TIMEOUT(fsm_timeout, f, f->timeouttime);
-               break;
-       }
-       
-       fsm_sdata(f, TERMACK, (u_char)id, NULL, 0);
-}
-
-
-/*
- * fsm_rtermack - Receive Terminate-Ack.
- */
-static void fsm_rtermack(fsm *f)
-{
-       FSMDEBUG((LOG_INFO, "fsm_rtermack(%s): state=%d\n", 
-                               PROTO_NAME(f), f->state));
-       
-       switch (f->state) {
-       case CLOSING:
-               UNTIMEOUT(fsm_timeout, f);
-               f->state = CLOSED;
-               if( f->callbacks->finished )
-                       (*f->callbacks->finished)(f);
-               break;
-       case STOPPING:
-               UNTIMEOUT(fsm_timeout, f);
-               f->state = STOPPED;
-               if( f->callbacks->finished )
-                       (*f->callbacks->finished)(f);
-               break;
-       
-       case ACKRCVD:
-               f->state = REQSENT;
-               break;
-       
-       case OPENED:
-               if (f->callbacks->down)
-                       (*f->callbacks->down)(f);       /* Inform upper layers */
-               fsm_sconfreq(f, 0);
-               break;
-       }
-}
-
-
-/*
- * fsm_rcoderej - Receive an Code-Reject.
- */
-static void fsm_rcoderej(fsm *f, u_char *inp, int len)
-{
-       u_char code, id;
-       
-       FSMDEBUG((LOG_INFO, "fsm_rcoderej(%s): state=%d\n", 
-                               PROTO_NAME(f), f->state));
-       
-       if (len < HEADERLEN) {
-               FSMDEBUG((LOG_INFO, "fsm_rcoderej: Rcvd short Code-Reject packet!\n"));
-               return;
-       }
-       GETCHAR(code, inp);
-       GETCHAR(id, inp);
-       FSMDEBUG((LOG_WARNING, "%s: Rcvd Code-Reject for code %d, id %d\n",
-                               PROTO_NAME(f), code, id));
-       
-       if( f->state == ACKRCVD )
-               f->state = REQSENT;
-}
-
-
-/*
- * fsm_sconfreq - Send a Configure-Request.
- */
-static void fsm_sconfreq(fsm *f, int retransmit)
-{
-       u_char *outp;
-       int cilen;
-       
-       if( f->state != REQSENT && f->state != ACKRCVD && f->state != ACKSENT ){
-               /* Not currently negotiating - reset options */
-               if( f->callbacks->resetci )
-                       (*f->callbacks->resetci)(f);
-               f->nakloops = 0;
-               }
-       
-       if( !retransmit ){
-               /* New request - reset retransmission counter, use new ID */
-               f->retransmits = f->maxconfreqtransmits;
-               f->reqid = ++f->id;
-       }
-       
-       f->seen_ack = 0;
-       
-       /*
-        * Make up the request packet
-        */
-       outp = outpacket_buf[f->unit] + PPP_HDRLEN + HEADERLEN;
-       if( f->callbacks->cilen && f->callbacks->addci ){
-               cilen = (*f->callbacks->cilen)(f);
-               if( cilen > peer_mru[f->unit] - (int)HEADERLEN )
-                       cilen = peer_mru[f->unit] - HEADERLEN;
-               if (f->callbacks->addci)
-                       (*f->callbacks->addci)(f, outp, &cilen);
-       } else
-               cilen = 0;
-       
-       /* send the request to our peer */
-       fsm_sdata(f, CONFREQ, f->reqid, outp, cilen);
-       
-       /* start the retransmit timer */
-       --f->retransmits;
-       TIMEOUT(fsm_timeout, f, f->timeouttime);
-       
-       FSMDEBUG((LOG_INFO, "%s: sending Configure-Request, id %d\n",
-                               PROTO_NAME(f), f->reqid));
-}
-
-#endif /* PPP_SUPPORT */
+/*****************************************************************************\r
+* fsm.c - Network Control Protocol Finite State Machine program file.\r
+*\r
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.\r
+* portions Copyright (c) 1997 by Global Election Systems Inc.\r
+*\r
+* The authors hereby grant permission to use, copy, modify, distribute,\r
+* and license this software and its documentation for any purpose, provided\r
+* that existing copyright notices are retained in all copies and that this\r
+* notice and the following disclaimer are included verbatim in any \r
+* distributions. No written agreement, license, or royalty fee is required\r
+* for any of the authorized uses.\r
+*\r
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR\r
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+*\r
+******************************************************************************\r
+* REVISION HISTORY\r
+*\r
+* 03-01-01 Marc Boucher <marc@mbsi.ca>\r
+*   Ported to lwIP.\r
+* 97-12-01 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.\r
+*      Original based on BSD fsm.c.\r
+*****************************************************************************/\r
+/*\r
+ * fsm.c - {Link, IP} Control Protocol Finite State Machine.\r
+ *\r
+ * Copyright (c) 1989 Carnegie Mellon University.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms are permitted\r
+ * provided that the above copyright notice and this paragraph are\r
+ * duplicated in all such forms and that any documentation,\r
+ * advertising materials, and other materials related to such\r
+ * distribution and use acknowledge that the software was developed\r
+ * by Carnegie Mellon University.  The name of the\r
+ * University may not be used to endorse or promote products derived\r
+ * from this software without specific prior written permission.\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR\r
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r
+ */\r
+\r
+\r
+/*\r
+ * TODO:\r
+ * Randomize fsm id on link/init.\r
+ * Deal with variable outgoing MTU.\r
+ */\r
+\r
+#include "ppp.h"\r
+#if PPP_SUPPORT > 0\r
+#include "fsm.h"\r
+#include "pppdebug.h"\r
+\r
+\r
+/*************************/\r
+/*** LOCAL DEFINITIONS ***/\r
+/*************************/\r
+\r
+\r
+/************************/\r
+/*** LOCAL DATA TYPES ***/\r
+/************************/\r
+\r
+\r
+/***********************************/\r
+/*** LOCAL FUNCTION DECLARATIONS ***/\r
+/***********************************/\r
+static void fsm_timeout (void *);\r
+static void fsm_rconfreq (fsm *, u_char, u_char *, int);\r
+static void fsm_rconfack (fsm *, int, u_char *, int);\r
+static void fsm_rconfnakrej (fsm *, int, int, u_char *, int);\r
+static void fsm_rtermreq (fsm *, int, u_char *, int);\r
+static void fsm_rtermack (fsm *);\r
+static void fsm_rcoderej (fsm *, u_char *, int);\r
+static void fsm_sconfreq (fsm *, int);\r
+\r
+#define PROTO_NAME(f)  ((f)->callbacks->proto_name)\r
+\r
+\r
+/******************************/\r
+/*** PUBLIC DATA STRUCTURES ***/\r
+/******************************/\r
+\r
+\r
+/*****************************/\r
+/*** LOCAL DATA STRUCTURES ***/\r
+/*****************************/\r
+int peer_mru[NUM_PPP];\r
+\r
+\r
+/***********************************/\r
+/*** PUBLIC FUNCTION DEFINITIONS ***/\r
+/***********************************/\r
+\r
+/*\r
+ * fsm_init - Initialize fsm.\r
+ *\r
+ * Initialize fsm state.\r
+ */\r
+void fsm_init(fsm *f)\r
+{\r
+       f->state = INITIAL;\r
+       f->flags = 0;\r
+       f->id = 0;                              /* XXX Start with random id? */\r
+       f->timeouttime = FSM_DEFTIMEOUT;\r
+       f->maxconfreqtransmits = FSM_DEFMAXCONFREQS;\r
+       f->maxtermtransmits = FSM_DEFMAXTERMREQS;\r
+       f->maxnakloops = FSM_DEFMAXNAKLOOPS;\r
+       f->term_reason_len = 0;\r
+}\r
+\r
+\r
+/*\r
+ * fsm_lowerup - The lower layer is up.\r
+ */\r
+void fsm_lowerup(fsm *f)\r
+{\r
+       int oldState = f->state;\r
+\r
+       switch( f->state ){\r
+       case INITIAL:\r
+               f->state = CLOSED;\r
+               break;\r
+       \r
+       case STARTING:\r
+               if( f->flags & OPT_SILENT )\r
+                       f->state = STOPPED;\r
+               else {\r
+                       /* Send an initial configure-request */\r
+                       fsm_sconfreq(f, 0);\r
+                       f->state = REQSENT;\r
+               }\r
+       break;\r
+       \r
+       default:\r
+               FSMDEBUG((LOG_INFO, "%s: Up event in state %d!\n",\r
+                               PROTO_NAME(f), f->state));\r
+       }\r
+       \r
+       FSMDEBUG((LOG_INFO, "%s: lowerup state %d -> %d\n",\r
+                       PROTO_NAME(f), oldState, f->state));\r
+}\r
+\r
+\r
+/*\r
+ * fsm_lowerdown - The lower layer is down.\r
+ *\r
+ * Cancel all timeouts and inform upper layers.\r
+ */\r
+void fsm_lowerdown(fsm *f)\r
+{\r
+       int oldState = f->state;\r
+       \r
+       switch( f->state ){\r
+       case CLOSED:\r
+               f->state = INITIAL;\r
+               break;\r
+       \r
+       case STOPPED:\r
+               f->state = STARTING;\r
+               if( f->callbacks->starting )\r
+                       (*f->callbacks->starting)(f);\r
+               break;\r
+       \r
+       case CLOSING:\r
+               f->state = INITIAL;\r
+               UNTIMEOUT(fsm_timeout, f);      /* Cancel timeout */\r
+               break;\r
+       \r
+       case STOPPING:\r
+       case REQSENT:\r
+       case ACKRCVD:\r
+       case ACKSENT:\r
+               f->state = STARTING;\r
+               UNTIMEOUT(fsm_timeout, f);      /* Cancel timeout */\r
+               break;\r
+       \r
+       case OPENED:\r
+               if( f->callbacks->down )\r
+                       (*f->callbacks->down)(f);\r
+               f->state = STARTING;\r
+               break;\r
+       \r
+       default:\r
+               FSMDEBUG((LOG_INFO, "%s: Down event in state %d!\n",\r
+                               PROTO_NAME(f), f->state));\r
+       }\r
+       \r
+       FSMDEBUG((LOG_INFO, "%s: lowerdown state %d -> %d\n",\r
+                       PROTO_NAME(f), oldState, f->state));\r
+}\r
+\r
+\r
+/*\r
+ * fsm_open - Link is allowed to come up.\r
+ */\r
+void fsm_open(fsm *f)\r
+{\r
+       int oldState = f->state;\r
+       \r
+       switch( f->state ){\r
+               case INITIAL:\r
+                       f->state = STARTING;\r
+                       if( f->callbacks->starting )\r
+                               (*f->callbacks->starting)(f);\r
+                       break;\r
+               \r
+               case CLOSED:\r
+               if( f->flags & OPT_SILENT )\r
+                       f->state = STOPPED;\r
+               else {\r
+                       /* Send an initial configure-request */\r
+                       fsm_sconfreq(f, 0);\r
+                       f->state = REQSENT;\r
+               }\r
+               break;\r
+       \r
+       case CLOSING:\r
+               f->state = STOPPING;\r
+               /* fall through */\r
+       case STOPPED:\r
+       case OPENED:\r
+               if( f->flags & OPT_RESTART ){\r
+                       fsm_lowerdown(f);\r
+                       fsm_lowerup(f);\r
+               }\r
+               break;\r
+       }\r
+       \r
+       FSMDEBUG((LOG_INFO, "%s: open state %d -> %d\n",\r
+                       PROTO_NAME(f), oldState, f->state));\r
+}\r
+\r
+\r
+/*\r
+ * fsm_close - Start closing connection.\r
+ *\r
+ * Cancel timeouts and either initiate close or possibly go directly to\r
+ * the CLOSED state.\r
+ */\r
+void fsm_close(fsm *f, char *reason)\r
+{\r
+       int oldState = f->state;\r
+       \r
+       f->term_reason = reason;\r
+       f->term_reason_len = (reason == NULL? 0: strlen(reason));\r
+       switch( f->state ){\r
+       case STARTING:\r
+               f->state = INITIAL;\r
+               break;\r
+       case STOPPED:\r
+               f->state = CLOSED;\r
+               break;\r
+       case STOPPING:\r
+               f->state = CLOSING;\r
+               break;\r
+       \r
+       case REQSENT:\r
+       case ACKRCVD:\r
+       case ACKSENT:\r
+       case OPENED:\r
+               if( f->state != OPENED )\r
+                       UNTIMEOUT(fsm_timeout, f);      /* Cancel timeout */\r
+               else if( f->callbacks->down )\r
+                       (*f->callbacks->down)(f);       /* Inform upper layers we're down */\r
+               \r
+               /* Init restart counter, send Terminate-Request */\r
+               f->retransmits = f->maxtermtransmits;\r
+               fsm_sdata(f, TERMREQ, f->reqid = ++f->id,\r
+                                       (u_char *) f->term_reason, f->term_reason_len);\r
+               TIMEOUT(fsm_timeout, f, f->timeouttime);\r
+               --f->retransmits;\r
+               \r
+               f->state = CLOSING;\r
+               break;\r
+       }\r
+       \r
+       FSMDEBUG((LOG_INFO, "%s: close reason=%s state %d -> %d\n",\r
+                       PROTO_NAME(f), reason, oldState, f->state));\r
+}\r
+\r
+\r
+/*\r
+ * fsm_sdata - Send some data.\r
+ *\r
+ * Used for all packets sent to our peer by this module.\r
+ */\r
+void fsm_sdata(\r
+       fsm *f,\r
+       u_char code, \r
+       u_char id,\r
+       u_char *data,\r
+       int datalen\r
+)\r
+{\r
+       u_char *outp;\r
+       int outlen;\r
+       \r
+       /* Adjust length to be smaller than MTU */\r
+       outp = outpacket_buf[f->unit];\r
+       if (datalen > peer_mru[f->unit] - (int)HEADERLEN)\r
+               datalen = peer_mru[f->unit] - HEADERLEN;\r
+       if (datalen && data != outp + PPP_HDRLEN + HEADERLEN)\r
+               BCOPY(data, outp + PPP_HDRLEN + HEADERLEN, datalen);\r
+       outlen = datalen + HEADERLEN;\r
+       MAKEHEADER(outp, f->protocol);\r
+       PUTCHAR(code, outp);\r
+       PUTCHAR(id, outp);\r
+       PUTSHORT(outlen, outp);\r
+       pppWrite(f->unit, outpacket_buf[f->unit], outlen + PPP_HDRLEN);\r
+       FSMDEBUG((LOG_INFO, "fsm_sdata(%s): Sent code %d,%d,%d.\n",\r
+                               PROTO_NAME(f), code, id, outlen));\r
+}\r
+\r
+\r
+/*\r
+ * fsm_input - Input packet.\r
+ */\r
+void fsm_input(fsm *f, u_char *inpacket, int l)\r
+{\r
+       u_char *inp = inpacket;\r
+       u_char code, id;\r
+       int len;\r
+       \r
+       /*\r
+       * Parse header (code, id and length).\r
+       * If packet too short, drop it.\r
+       */\r
+       if (l < HEADERLEN) {\r
+               FSMDEBUG((LOG_WARNING, "fsm_input(%x): Rcvd short header.\n",\r
+                                       f->protocol));\r
+               return;\r
+       }\r
+       GETCHAR(code, inp);\r
+       GETCHAR(id, inp);\r
+       GETSHORT(len, inp);\r
+       if (len < HEADERLEN) {\r
+               FSMDEBUG((LOG_INFO, "fsm_input(%x): Rcvd illegal length.\n",\r
+                               f->protocol));\r
+               return;\r
+       }\r
+       if (len > l) {\r
+               FSMDEBUG((LOG_INFO, "fsm_input(%x): Rcvd short packet.\n",\r
+                               f->protocol));\r
+               return;\r
+       }\r
+       len -= HEADERLEN;               /* subtract header length */\r
+       \r
+       if( f->state == INITIAL || f->state == STARTING ){\r
+               FSMDEBUG((LOG_INFO, "fsm_input(%x): Rcvd packet in state %d.\n",\r
+                               f->protocol, f->state));\r
+               return;\r
+       }\r
+       FSMDEBUG((LOG_INFO, "fsm_input(%s):%d,%d,%d\n", PROTO_NAME(f), code, id, l));\r
+       /*\r
+        * Action depends on code.\r
+        */\r
+       switch (code) {\r
+       case CONFREQ:\r
+               fsm_rconfreq(f, id, inp, len);\r
+               break;\r
+       \r
+       case CONFACK:\r
+               fsm_rconfack(f, id, inp, len);\r
+               break;\r
+       \r
+       case CONFNAK:\r
+       case CONFREJ:\r
+               fsm_rconfnakrej(f, code, id, inp, len);\r
+               break;\r
+       \r
+       case TERMREQ:\r
+               fsm_rtermreq(f, id, inp, len);\r
+               break;\r
+       \r
+       case TERMACK:\r
+               fsm_rtermack(f);\r
+               break;\r
+       \r
+       case CODEREJ:\r
+               fsm_rcoderej(f, inp, len);\r
+               break;\r
+       \r
+       default:\r
+               if( !f->callbacks->extcode\r
+                               || !(*f->callbacks->extcode)(f, code, id, inp, len) )\r
+                       fsm_sdata(f, CODEREJ, ++f->id, inpacket, len + HEADERLEN);\r
+               break;\r
+       }\r
+}\r
+\r
+\r
+/*\r
+ * fsm_protreject - Peer doesn't speak this protocol.\r
+ *\r
+ * Treat this as a catastrophic error (RXJ-).\r
+ */\r
+void fsm_protreject(fsm *f)\r
+{\r
+       switch( f->state ){\r
+       case CLOSING:\r
+               UNTIMEOUT(fsm_timeout, f);      /* Cancel timeout */\r
+               /* fall through */\r
+       case CLOSED:\r
+               f->state = CLOSED;\r
+               if( f->callbacks->finished )\r
+                       (*f->callbacks->finished)(f);\r
+               break;\r
+       \r
+       case STOPPING:\r
+       case REQSENT:\r
+       case ACKRCVD:\r
+       case ACKSENT:\r
+               UNTIMEOUT(fsm_timeout, f);      /* Cancel timeout */\r
+               /* fall through */\r
+       case STOPPED:\r
+               f->state = STOPPED;\r
+               if( f->callbacks->finished )\r
+                       (*f->callbacks->finished)(f);\r
+               break;\r
+       \r
+       case OPENED:\r
+               if( f->callbacks->down )\r
+                       (*f->callbacks->down)(f);\r
+               \r
+               /* Init restart counter, send Terminate-Request */\r
+               f->retransmits = f->maxtermtransmits;\r
+               fsm_sdata(f, TERMREQ, f->reqid = ++f->id,\r
+                                       (u_char *) f->term_reason, f->term_reason_len);\r
+               TIMEOUT(fsm_timeout, f, f->timeouttime);\r
+               --f->retransmits;\r
+               \r
+               f->state = STOPPING;\r
+               break;\r
+       \r
+       default:\r
+               FSMDEBUG((LOG_INFO, "%s: Protocol-reject event in state %d!\n",\r
+                                       PROTO_NAME(f), f->state));\r
+       }\r
+}\r
+\r
+\r
+\r
+\r
+\r
+/**********************************/\r
+/*** LOCAL FUNCTION DEFINITIONS ***/\r
+/**********************************/\r
+\r
+/*\r
+ * fsm_timeout - Timeout expired.\r
+ */\r
+static void fsm_timeout(void *arg)\r
+{\r
+    fsm *f = (fsm *) arg;\r
+\r
+    switch (f->state) {\r
+    case CLOSING:\r
+    case STOPPING:\r
+               if( f->retransmits <= 0 ){\r
+                   FSMDEBUG((LOG_WARNING, "%s: timeout sending Terminate-Request state=%d\n",\r
+                                          PROTO_NAME(f), f->state));\r
+                   /*\r
+                    * We've waited for an ack long enough.  Peer probably heard us.\r
+                    */\r
+                   f->state = (f->state == CLOSING)? CLOSED: STOPPED;\r
+                   if( f->callbacks->finished )\r
+                       (*f->callbacks->finished)(f);\r
+               } else {\r
+                   FSMDEBUG((LOG_WARNING, "%s: timeout resending Terminate-Requests state=%d\n",\r
+                                          PROTO_NAME(f), f->state));\r
+                   /* Send Terminate-Request */\r
+                   fsm_sdata(f, TERMREQ, f->reqid = ++f->id,\r
+                             (u_char *) f->term_reason, f->term_reason_len);\r
+                   TIMEOUT(fsm_timeout, f, f->timeouttime);\r
+                   --f->retransmits;\r
+               }\r
+               break;\r
+\r
+    case REQSENT:\r
+    case ACKRCVD:\r
+    case ACKSENT:\r
+               if (f->retransmits <= 0) {\r
+                   FSMDEBUG((LOG_WARNING, "%s: timeout sending Config-Requests state=%d\n",\r
+                          PROTO_NAME(f), f->state));\r
+                   f->state = STOPPED;\r
+                   if( (f->flags & OPT_PASSIVE) == 0 && f->callbacks->finished )\r
+                               (*f->callbacks->finished)(f);\r
+       \r
+               } else {\r
+                   FSMDEBUG((LOG_WARNING, "%s: timeout resending Config-Request state=%d\n",\r
+                          PROTO_NAME(f), f->state));\r
+                   /* Retransmit the configure-request */\r
+                   if (f->callbacks->retransmit)\r
+                               (*f->callbacks->retransmit)(f);\r
+                   fsm_sconfreq(f, 1);         /* Re-send Configure-Request */\r
+                   if( f->state == ACKRCVD )\r
+                               f->state = REQSENT;\r
+               }\r
+               break;\r
+\r
+    default:\r
+               FSMDEBUG((LOG_INFO, "%s: Timeout event in state %d!\n",\r
+                                 PROTO_NAME(f), f->state));\r
+           }\r
+}\r
+\r
+\r
+/*\r
+ * fsm_rconfreq - Receive Configure-Request.\r
+ */\r
+static void fsm_rconfreq(fsm *f, u_char id, u_char *inp, int len)\r
+{\r
+       int code, reject_if_disagree;\r
+       \r
+       FSMDEBUG((LOG_INFO, "fsm_rconfreq(%s): Rcvd id %d state=%d\n", \r
+                               PROTO_NAME(f), id, f->state));\r
+       switch( f->state ){\r
+       case CLOSED:\r
+               /* Go away, we're closed */\r
+               fsm_sdata(f, TERMACK, id, NULL, 0);\r
+               return;\r
+       case CLOSING:\r
+       case STOPPING:\r
+               return;\r
+       \r
+       case OPENED:\r
+               /* Go down and restart negotiation */\r
+               if( f->callbacks->down )\r
+                       (*f->callbacks->down)(f);       /* Inform upper layers */\r
+               fsm_sconfreq(f, 0);             /* Send initial Configure-Request */\r
+               break;\r
+       \r
+       case STOPPED:\r
+               /* Negotiation started by our peer */\r
+               fsm_sconfreq(f, 0);             /* Send initial Configure-Request */\r
+               f->state = REQSENT;\r
+               break;\r
+       }\r
+       \r
+       /*\r
+       * Pass the requested configuration options\r
+       * to protocol-specific code for checking.\r
+       */\r
+       if (f->callbacks->reqci){               /* Check CI */\r
+               reject_if_disagree = (f->nakloops >= f->maxnakloops);\r
+               code = (*f->callbacks->reqci)(f, inp, &len, reject_if_disagree);\r
+       } \r
+       else if (len)\r
+               code = CONFREJ;                 /* Reject all CI */\r
+       else\r
+               code = CONFACK;\r
+       \r
+       /* send the Ack, Nak or Rej to the peer */\r
+       fsm_sdata(f, (u_char)code, id, inp, len);\r
+       \r
+       if (code == CONFACK) {\r
+               if (f->state == ACKRCVD) {\r
+                       UNTIMEOUT(fsm_timeout, f);      /* Cancel timeout */\r
+                       f->state = OPENED;\r
+                       if (f->callbacks->up)\r
+                               (*f->callbacks->up)(f); /* Inform upper layers */\r
+               } \r
+               else\r
+                       f->state = ACKSENT;\r
+               f->nakloops = 0;\r
+       } \r
+       else {\r
+               /* we sent CONFACK or CONFREJ */\r
+               if (f->state != ACKRCVD)\r
+                       f->state = REQSENT;\r
+               if( code == CONFNAK )\r
+                       ++f->nakloops;\r
+       }\r
+}\r
+\r
+\r
+/*\r
+ * fsm_rconfack - Receive Configure-Ack.\r
+ */\r
+static void fsm_rconfack(fsm *f, int id, u_char *inp, int len)\r
+{\r
+       FSMDEBUG((LOG_INFO, "fsm_rconfack(%s): Rcvd id %d state=%d\n",\r
+                               PROTO_NAME(f), id, f->state));\r
+       \r
+       if (id != f->reqid || f->seen_ack)              /* Expected id? */\r
+               return;                                 /* Nope, toss... */\r
+       if( !(f->callbacks->ackci? (*f->callbacks->ackci)(f, inp, len):\r
+                                                               (len == 0)) ){\r
+               /* Ack is bad - ignore it */\r
+               FSMDEBUG((LOG_INFO, "%s: received bad Ack (length %d)\n",\r
+                                       PROTO_NAME(f), len));\r
+               return;\r
+       }\r
+       f->seen_ack = 1;\r
+       \r
+       switch (f->state) {\r
+       case CLOSED:\r
+       case STOPPED:\r
+               fsm_sdata(f, TERMACK, (u_char)id, NULL, 0);\r
+               break;\r
+       \r
+       case REQSENT:\r
+               f->state = ACKRCVD;\r
+               f->retransmits = f->maxconfreqtransmits;\r
+               break;\r
+       \r
+       case ACKRCVD:\r
+               /* Huh? an extra valid Ack? oh well... */\r
+               UNTIMEOUT(fsm_timeout, f);      /* Cancel timeout */\r
+               fsm_sconfreq(f, 0);\r
+               f->state = REQSENT;\r
+               break;\r
+       \r
+       case ACKSENT:\r
+               UNTIMEOUT(fsm_timeout, f);      /* Cancel timeout */\r
+               f->state = OPENED;\r
+               f->retransmits = f->maxconfreqtransmits;\r
+               if (f->callbacks->up)\r
+                       (*f->callbacks->up)(f); /* Inform upper layers */\r
+               break;\r
+       \r
+       case OPENED:\r
+               /* Go down and restart negotiation */\r
+               if (f->callbacks->down)\r
+                       (*f->callbacks->down)(f);       /* Inform upper layers */\r
+               fsm_sconfreq(f, 0);             /* Send initial Configure-Request */\r
+               f->state = REQSENT;\r
+               break;\r
+       }\r
+}\r
+\r
+\r
+/*\r
+ * fsm_rconfnakrej - Receive Configure-Nak or Configure-Reject.\r
+ */\r
+static void fsm_rconfnakrej(fsm *f, int code, int id, u_char *inp, int len)\r
+{\r
+       int (*proc) (fsm *, u_char *, int);\r
+       int ret;\r
+       \r
+       FSMDEBUG((LOG_INFO, "fsm_rconfnakrej(%s): Rcvd id %d state=%d\n",\r
+                               PROTO_NAME(f), id, f->state));\r
+       \r
+       if (id != f->reqid || f->seen_ack)      /* Expected id? */\r
+               return;                         /* Nope, toss... */\r
+       proc = (code == CONFNAK)? f->callbacks->nakci: f->callbacks->rejci;\r
+       if (!proc || !(ret = proc(f, inp, len))) {\r
+               /* Nak/reject is bad - ignore it */\r
+               FSMDEBUG((LOG_INFO, "%s: received bad %s (length %d)\n",\r
+                                       PROTO_NAME(f), (code==CONFNAK? "Nak": "reject"), len));\r
+               return;\r
+       }\r
+       f->seen_ack = 1;\r
+       \r
+       switch (f->state) {\r
+       case CLOSED:\r
+       case STOPPED:\r
+               fsm_sdata(f, TERMACK, (u_char)id, NULL, 0);\r
+               break;\r
+       \r
+       case REQSENT:\r
+       case ACKSENT:\r
+               /* They didn't agree to what we wanted - try another request */\r
+               UNTIMEOUT(fsm_timeout, f);      /* Cancel timeout */\r
+               if (ret < 0)\r
+                       f->state = STOPPED;             /* kludge for stopping CCP */\r
+               else\r
+                       fsm_sconfreq(f, 0);             /* Send Configure-Request */\r
+               break;\r
+       \r
+       case ACKRCVD:\r
+               /* Got a Nak/reject when we had already had an Ack?? oh well... */\r
+               UNTIMEOUT(fsm_timeout, f);      /* Cancel timeout */\r
+               fsm_sconfreq(f, 0);\r
+               f->state = REQSENT;\r
+               break;\r
+       \r
+       case OPENED:\r
+               /* Go down and restart negotiation */\r
+               if (f->callbacks->down)\r
+                       (*f->callbacks->down)(f);       /* Inform upper layers */\r
+               fsm_sconfreq(f, 0);             /* Send initial Configure-Request */\r
+               f->state = REQSENT;\r
+               break;\r
+       }\r
+}\r
+\r
+\r
+/*\r
+ * fsm_rtermreq - Receive Terminate-Req.\r
+ */\r
+static void fsm_rtermreq(fsm *f, int id, u_char *p, int len)\r
+{\r
+       FSMDEBUG((LOG_INFO, "fsm_rtermreq(%s): Rcvd id %d state=%d\n",\r
+                               PROTO_NAME(f), id, f->state));\r
+       \r
+       switch (f->state) {\r
+       case ACKRCVD:\r
+       case ACKSENT:\r
+               f->state = REQSENT;             /* Start over but keep trying */\r
+               break;\r
+       \r
+       case OPENED:\r
+               if (len > 0) {\r
+                       FSMDEBUG((LOG_INFO, "%s terminated by peer (%x)\n", PROTO_NAME(f), p));\r
+               } else {\r
+                       FSMDEBUG((LOG_INFO, "%s terminated by peer\n", PROTO_NAME(f)));\r
+               }\r
+               if (f->callbacks->down)\r
+                       (*f->callbacks->down)(f);       /* Inform upper layers */\r
+               f->retransmits = 0;\r
+               f->state = STOPPING;\r
+               TIMEOUT(fsm_timeout, f, f->timeouttime);\r
+               break;\r
+       }\r
+       \r
+       fsm_sdata(f, TERMACK, (u_char)id, NULL, 0);\r
+}\r
+\r
+\r
+/*\r
+ * fsm_rtermack - Receive Terminate-Ack.\r
+ */\r
+static void fsm_rtermack(fsm *f)\r
+{\r
+       FSMDEBUG((LOG_INFO, "fsm_rtermack(%s): state=%d\n", \r
+                               PROTO_NAME(f), f->state));\r
+       \r
+       switch (f->state) {\r
+       case CLOSING:\r
+               UNTIMEOUT(fsm_timeout, f);\r
+               f->state = CLOSED;\r
+               if( f->callbacks->finished )\r
+                       (*f->callbacks->finished)(f);\r
+               break;\r
+       case STOPPING:\r
+               UNTIMEOUT(fsm_timeout, f);\r
+               f->state = STOPPED;\r
+               if( f->callbacks->finished )\r
+                       (*f->callbacks->finished)(f);\r
+               break;\r
+       \r
+       case ACKRCVD:\r
+               f->state = REQSENT;\r
+               break;\r
+       \r
+       case OPENED:\r
+               if (f->callbacks->down)\r
+                       (*f->callbacks->down)(f);       /* Inform upper layers */\r
+               fsm_sconfreq(f, 0);\r
+               break;\r
+       }\r
+}\r
+\r
+\r
+/*\r
+ * fsm_rcoderej - Receive an Code-Reject.\r
+ */\r
+static void fsm_rcoderej(fsm *f, u_char *inp, int len)\r
+{\r
+       u_char code, id;\r
+       \r
+       FSMDEBUG((LOG_INFO, "fsm_rcoderej(%s): state=%d\n", \r
+                               PROTO_NAME(f), f->state));\r
+       \r
+       if (len < HEADERLEN) {\r
+               FSMDEBUG((LOG_INFO, "fsm_rcoderej: Rcvd short Code-Reject packet!\n"));\r
+               return;\r
+       }\r
+       GETCHAR(code, inp);\r
+       GETCHAR(id, inp);\r
+       FSMDEBUG((LOG_WARNING, "%s: Rcvd Code-Reject for code %d, id %d\n",\r
+                               PROTO_NAME(f), code, id));\r
+       \r
+       if( f->state == ACKRCVD )\r
+               f->state = REQSENT;\r
+}\r
+\r
+\r
+/*\r
+ * fsm_sconfreq - Send a Configure-Request.\r
+ */\r
+static void fsm_sconfreq(fsm *f, int retransmit)\r
+{\r
+       u_char *outp;\r
+       int cilen;\r
+       \r
+       if( f->state != REQSENT && f->state != ACKRCVD && f->state != ACKSENT ){\r
+               /* Not currently negotiating - reset options */\r
+               if( f->callbacks->resetci )\r
+                       (*f->callbacks->resetci)(f);\r
+               f->nakloops = 0;\r
+               }\r
+       \r
+       if( !retransmit ){\r
+               /* New request - reset retransmission counter, use new ID */\r
+               f->retransmits = f->maxconfreqtransmits;\r
+               f->reqid = ++f->id;\r
+       }\r
+       \r
+       f->seen_ack = 0;\r
+       \r
+       /*\r
+        * Make up the request packet\r
+        */\r
+       outp = outpacket_buf[f->unit] + PPP_HDRLEN + HEADERLEN;\r
+       if( f->callbacks->cilen && f->callbacks->addci ){\r
+               cilen = (*f->callbacks->cilen)(f);\r
+               if( cilen > peer_mru[f->unit] - (int)HEADERLEN )\r
+                       cilen = peer_mru[f->unit] - HEADERLEN;\r
+               if (f->callbacks->addci)\r
+                       (*f->callbacks->addci)(f, outp, &cilen);\r
+       } else\r
+               cilen = 0;\r
+       \r
+       /* send the request to our peer */\r
+       fsm_sdata(f, CONFREQ, f->reqid, outp, cilen);\r
+       \r
+       /* start the retransmit timer */\r
+       --f->retransmits;\r
+       TIMEOUT(fsm_timeout, f, f->timeouttime);\r
+       \r
+       FSMDEBUG((LOG_INFO, "%s: sending Configure-Request, id %d\n",\r
+                               PROTO_NAME(f), f->reqid));\r
+}\r
+\r
+#endif /* PPP_SUPPORT */\r
index 0e1d9f61a6739eb3b71aba52df4cafdb0cad065f..4cca402e02d3d460a94775fd453e083d2ce59ef2 100644 (file)
-/*****************************************************************************
-* fsm.h - Network Control Protocol Finite State Machine header file.
-*
-* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
-* Copyright (c) 1997 Global Election Systems Inc.
-*
-* The authors hereby grant permission to use, copy, modify, distribute,
-* and license this software and its documentation for any purpose, provided
-* that existing copyright notices are retained in all copies and that this
-* notice and the following disclaimer are included verbatim in any 
-* distributions. No written agreement, license, or royalty fee is required
-* for any of the authorized uses.
-*
-* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *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 CONTRIBUTORS 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.
-*
-******************************************************************************
-* REVISION HISTORY
-*
-* 03-01-01 Marc Boucher <marc@mbsi.ca>
-*   Ported to lwIP.
-* 97-11-05 Guy Lancaster <glanca@gesn.com>, Global Election Systems Inc.
-*      Original based on BSD code.
-*****************************************************************************/
-/*
- * fsm.h - {Link, IP} Control Protocol Finite State Machine definitions.
- *
- * Copyright (c) 1989 Carnegie Mellon University.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by Carnegie Mellon University.  The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * $Id: fsm.h,v 1.1 2003/05/27 14:37:56 jani Exp $
- */
-
-#ifndef FSM_H
-#define FSM_H
-
-
-/*****************************************************************************
-************************* PUBLIC DEFINITIONS *********************************
-*****************************************************************************/
-/*
- * LCP Packet header = Code, id, length.
- */
-#define HEADERLEN      (sizeof (u_char) + sizeof (u_char) + sizeof (u_short))
-
-
-/*
- *  CP (LCP, IPCP, etc.) codes.
- */
-#define CONFREQ                1               /* Configuration Request */
-#define CONFACK                2               /* Configuration Ack */
-#define CONFNAK                3               /* Configuration Nak */
-#define CONFREJ                4               /* Configuration Reject */
-#define TERMREQ                5               /* Termination Request */
-#define TERMACK                6               /* Termination Ack */
-#define CODEREJ                7               /* Code Reject */
-
-/*
- * Link states.
- */
-#define INITIAL                0               /* Down, hasn't been opened */
-#define STARTING       1               /* Down, been opened */
-#define CLOSED         2               /* Up, hasn't been opened */
-#define STOPPED                3               /* Open, waiting for down event */
-#define CLOSING                4               /* Terminating the connection, not open */
-#define STOPPING       5               /* Terminating, but open */
-#define REQSENT                6               /* We've sent a Config Request */
-#define ACKRCVD                7               /* We've received a Config Ack */
-#define ACKSENT                8               /* We've sent a Config Ack */
-#define OPENED         9               /* Connection available */
-
-
-/*
- * Flags - indicate options controlling FSM operation
- */
-#define OPT_PASSIVE    1               /* Don't die if we don't get a response */
-#define OPT_RESTART    2               /* Treat 2nd OPEN as DOWN, UP */
-#define OPT_SILENT     4               /* Wait for peer to speak first */
-
-
-/*****************************************************************************
-************************* PUBLIC DATA TYPES **********************************
-*****************************************************************************/
-/*
- * Each FSM is described by an fsm structure and fsm callbacks.
- */
-typedef struct fsm {
-    int unit;                          /* Interface unit number */
-    u_short protocol;          /* Data Link Layer Protocol field value */
-    int state;                         /* State */
-    int flags;                         /* Contains option bits */
-    u_char id;                         /* Current id */
-    u_char reqid;                      /* Current request id */
-    u_char seen_ack;           /* Have received valid Ack/Nak/Rej to Req */
-    int timeouttime;           /* Timeout time in milliseconds */
-    int maxconfreqtransmits;/* Maximum Configure-Request transmissions */
-    int retransmits;           /* Number of retransmissions left */
-    int maxtermtransmits;      /* Maximum Terminate-Request transmissions */
-    int nakloops;                      /* Number of nak loops since last ack */
-    int maxnakloops;           /* Maximum number of nak loops tolerated */
-    struct fsm_callbacks* callbacks;/* Callback routines */
-    char* term_reason;         /* Reason for closing protocol */
-    int term_reason_len;       /* Length of term_reason */
-} fsm;
-
-
-typedef struct fsm_callbacks {
-    void (*resetci)                    /* Reset our Configuration Information */
-               (fsm*);
-    int  (*cilen)                      /* Length of our Configuration Information */
-               (fsm*);
-    void (*addci)                      /* Add our Configuration Information */
-               (fsm*, u_char*, int*);
-    int  (*ackci)                      /* ACK our Configuration Information */
-               (fsm*, u_char*, int);
-    int  (*nakci)                      /* NAK our Configuration Information */
-               (fsm*, u_char*, int);
-    int  (*rejci)                      /* Reject our Configuration Information */
-               (fsm*, u_char*, int);
-    int  (*reqci)                      /* Request peer's Configuration Information */
-               (fsm*, u_char*, int*, int);
-    void (*up)                         /* Called when fsm reaches OPENED state */
-               (fsm*);
-    void (*down)                       /* Called when fsm leaves OPENED state */
-               (fsm*);
-    void (*starting)           /* Called when we want the lower layer */
-               (fsm*);
-    void (*finished)           /* Called when we don't want the lower layer */
-               (fsm*);
-    void (*protreject)         /* Called when Protocol-Reject received */
-               (int);
-    void (*retransmit)         /* Retransmission is necessary */
-               (fsm*);
-    int  (*extcode)                    /* Called when unknown code received */
-               (fsm*, int, u_char, u_char*, int);
-    char *proto_name;          /* String name for protocol (for messages) */
-} fsm_callbacks;
-
-
-/*****************************************************************************
-*********************** PUBLIC DATA STRUCTURES *******************************
-*****************************************************************************/
-/*
- * Variables
- */
-extern int peer_mru[];         /* currently negotiated peer MRU (per unit) */
-
-
-/*****************************************************************************
-************************** PUBLIC FUNCTIONS **********************************
-*****************************************************************************/
-
-/*
- * Prototypes
- */
-void fsm_init (fsm*);
-void fsm_lowerup (fsm*);
-void fsm_lowerdown (fsm*);
-void fsm_open (fsm*);
-void fsm_close (fsm*, char*);
-void fsm_input (fsm*, u_char*, int);
-void fsm_protreject (fsm*);
-void fsm_sdata (fsm*, u_char, u_char, u_char*, int);
-
-
-#endif /* FSM_H */
-
+/*****************************************************************************\r
+* fsm.h - Network Control Protocol Finite State Machine header file.\r
+*\r
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.\r
+* Copyright (c) 1997 Global Election Systems Inc.\r
+*\r
+* The authors hereby grant permission to use, copy, modify, distribute,\r
+* and license this software and its documentation for any purpose, provided\r
+* that existing copyright notices are retained in all copies and that this\r
+* notice and the following disclaimer are included verbatim in any \r
+* distributions. No written agreement, license, or royalty fee is required\r
+* for any of the authorized uses.\r
+*\r
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR\r
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+*\r
+******************************************************************************\r
+* REVISION HISTORY\r
+*\r
+* 03-01-01 Marc Boucher <marc@mbsi.ca>\r
+*   Ported to lwIP.\r
+* 97-11-05 Guy Lancaster <glanca@gesn.com>, Global Election Systems Inc.\r
+*      Original based on BSD code.\r
+*****************************************************************************/\r
+/*\r
+ * fsm.h - {Link, IP} Control Protocol Finite State Machine definitions.\r
+ *\r
+ * Copyright (c) 1989 Carnegie Mellon University.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms are permitted\r
+ * provided that the above copyright notice and this paragraph are\r
+ * duplicated in all such forms and that any documentation,\r
+ * advertising materials, and other materials related to such\r
+ * distribution and use acknowledge that the software was developed\r
+ * by Carnegie Mellon University.  The name of the\r
+ * University may not be used to endorse or promote products derived\r
+ * from this software without specific prior written permission.\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR\r
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r
+ *\r
+ * $Id: fsm.h,v 1.1 2003/05/27 14:37:56 jani Exp $\r
+ */\r
+\r
+#ifndef FSM_H\r
+#define FSM_H\r
+\r
+\r
+/*****************************************************************************\r
+************************* PUBLIC DEFINITIONS *********************************\r
+*****************************************************************************/\r
+/*\r
+ * LCP Packet header = Code, id, length.\r
+ */\r
+#define HEADERLEN      (sizeof (u_char) + sizeof (u_char) + sizeof (u_short))\r
+\r
+\r
+/*\r
+ *  CP (LCP, IPCP, etc.) codes.\r
+ */\r
+#define CONFREQ                1               /* Configuration Request */\r
+#define CONFACK                2               /* Configuration Ack */\r
+#define CONFNAK                3               /* Configuration Nak */\r
+#define CONFREJ                4               /* Configuration Reject */\r
+#define TERMREQ                5               /* Termination Request */\r
+#define TERMACK                6               /* Termination Ack */\r
+#define CODEREJ                7               /* Code Reject */\r
+\r
+/*\r
+ * Link states.\r
+ */\r
+#define INITIAL                0               /* Down, hasn't been opened */\r
+#define STARTING       1               /* Down, been opened */\r
+#define CLOSED         2               /* Up, hasn't been opened */\r
+#define STOPPED                3               /* Open, waiting for down event */\r
+#define CLOSING                4               /* Terminating the connection, not open */\r
+#define STOPPING       5               /* Terminating, but open */\r
+#define REQSENT                6               /* We've sent a Config Request */\r
+#define ACKRCVD                7               /* We've received a Config Ack */\r
+#define ACKSENT                8               /* We've sent a Config Ack */\r
+#define OPENED         9               /* Connection available */\r
+\r
+\r
+/*\r
+ * Flags - indicate options controlling FSM operation\r
+ */\r
+#define OPT_PASSIVE    1               /* Don't die if we don't get a response */\r
+#define OPT_RESTART    2               /* Treat 2nd OPEN as DOWN, UP */\r
+#define OPT_SILENT     4               /* Wait for peer to speak first */\r
+\r
+\r
+/*****************************************************************************\r
+************************* PUBLIC DATA TYPES **********************************\r
+*****************************************************************************/\r
+/*\r
+ * Each FSM is described by an fsm structure and fsm callbacks.\r
+ */\r
+typedef struct fsm {\r
+    int unit;                          /* Interface unit number */\r
+    u_short protocol;          /* Data Link Layer Protocol field value */\r
+    int state;                         /* State */\r
+    int flags;                         /* Contains option bits */\r
+    u_char id;                         /* Current id */\r
+    u_char reqid;                      /* Current request id */\r
+    u_char seen_ack;           /* Have received valid Ack/Nak/Rej to Req */\r
+    int timeouttime;           /* Timeout time in milliseconds */\r
+    int maxconfreqtransmits;/* Maximum Configure-Request transmissions */\r
+    int retransmits;           /* Number of retransmissions left */\r
+    int maxtermtransmits;      /* Maximum Terminate-Request transmissions */\r
+    int nakloops;                      /* Number of nak loops since last ack */\r
+    int maxnakloops;           /* Maximum number of nak loops tolerated */\r
+    struct fsm_callbacks* callbacks;/* Callback routines */\r
+    char* term_reason;         /* Reason for closing protocol */\r
+    int term_reason_len;       /* Length of term_reason */\r
+} fsm;\r
+\r
+\r
+typedef struct fsm_callbacks {\r
+    void (*resetci)                    /* Reset our Configuration Information */\r
+               (fsm*);\r
+    int  (*cilen)                      /* Length of our Configuration Information */\r
+               (fsm*);\r
+    void (*addci)                      /* Add our Configuration Information */\r
+               (fsm*, u_char*, int*);\r
+    int  (*ackci)                      /* ACK our Configuration Information */\r
+               (fsm*, u_char*, int);\r
+    int  (*nakci)                      /* NAK our Configuration Information */\r
+               (fsm*, u_char*, int);\r
+    int  (*rejci)                      /* Reject our Configuration Information */\r
+               (fsm*, u_char*, int);\r
+    int  (*reqci)                      /* Request peer's Configuration Information */\r
+               (fsm*, u_char*, int*, int);\r
+    void (*up)                         /* Called when fsm reaches OPENED state */\r
+               (fsm*);\r
+    void (*down)                       /* Called when fsm leaves OPENED state */\r
+               (fsm*);\r
+    void (*starting)           /* Called when we want the lower layer */\r
+               (fsm*);\r
+    void (*finished)           /* Called when we don't want the lower layer */\r
+               (fsm*);\r
+    void (*protreject)         /* Called when Protocol-Reject received */\r
+               (int);\r
+    void (*retransmit)         /* Retransmission is necessary */\r
+               (fsm*);\r
+    int  (*extcode)                    /* Called when unknown code received */\r
+               (fsm*, int, u_char, u_char*, int);\r
+    char *proto_name;          /* String name for protocol (for messages) */\r
+} fsm_callbacks;\r
+\r
+\r
+/*****************************************************************************\r
+*********************** PUBLIC DATA STRUCTURES *******************************\r
+*****************************************************************************/\r
+/*\r
+ * Variables\r
+ */\r
+extern int peer_mru[];         /* currently negotiated peer MRU (per unit) */\r
+\r
+\r
+/*****************************************************************************\r
+************************** PUBLIC FUNCTIONS **********************************\r
+*****************************************************************************/\r
+\r
+/*\r
+ * Prototypes\r
+ */\r
+void fsm_init (fsm*);\r
+void fsm_lowerup (fsm*);\r
+void fsm_lowerdown (fsm*);\r
+void fsm_open (fsm*);\r
+void fsm_close (fsm*, char*);\r
+void fsm_input (fsm*, u_char*, int);\r
+void fsm_protreject (fsm*);\r
+void fsm_sdata (fsm*, u_char, u_char, u_char*, int);\r
+\r
+\r
+#endif /* FSM_H */\r
+\r
index d5b251880997bba95b0036f161107d8c246af9da..ec3207a0c43fd9f39f135f4b95437e425eb375ec 100644 (file)
-/*****************************************************************************
-* ipcp.c - Network PPP IP Control Protocol program file.
-*
-* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
-* portions Copyright (c) 1997 by Global Election Systems Inc.
-*
-* The authors hereby grant permission to use, copy, modify, distribute,
-* and license this software and its documentation for any purpose, provided
-* that existing copyright notices are retained in all copies and that this
-* notice and the following disclaimer are included verbatim in any 
-* distributions. No written agreement, license, or royalty fee is required
-* for any of the authorized uses.
-*
-* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *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 CONTRIBUTORS 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.
-*
-******************************************************************************
-* REVISION HISTORY
-*
-* 03-01-01 Marc Boucher <marc@mbsi.ca>
-*   Ported to lwIP.
-* 97-12-08 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
-*      Original.
-*****************************************************************************/
-/*
- * ipcp.c - PPP IP Control Protocol.
- *
- * Copyright (c) 1989 Carnegie Mellon University.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by Carnegie Mellon University.  The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include <string.h>
-
-#include "ppp.h"
-#if PPP_SUPPORT > 0
-#include "auth.h"
-#include "fsm.h"
-#include "vj.h"
-#include "ipcp.h"
-#include "pppdebug.h"
-
-
-/*************************/
-/*** LOCAL DEFINITIONS ***/
-/*************************/
-/* #define OLD_CI_ADDRS 1 */   /* Support deprecated address negotiation. */
-
-/*
- * Lengths of configuration options.
- */
-#define CILEN_VOID     2
-#define CILEN_COMPRESS 4       /* min length for compression protocol opt. */
-#define CILEN_VJ       6       /* length for RFC1332 Van-Jacobson opt. */
-#define CILEN_ADDR     6       /* new-style single address option */
-#define CILEN_ADDRS    10      /* old-style dual address option */
-
-
-
-/***********************************/
-/*** LOCAL FUNCTION DECLARATIONS ***/
-/***********************************/
-/*
- * Callbacks for fsm code.  (CI = Configuration Information)
- */
-static void ipcp_resetci (fsm *);      /* Reset our CI */
-static int  ipcp_cilen (fsm *);                /* Return length of our CI */
-static void ipcp_addci (fsm *, u_char *, int *); /* Add our CI */
-static int  ipcp_ackci (fsm *, u_char *, int); /* Peer ack'd our CI */
-static int  ipcp_nakci (fsm *, u_char *, int); /* Peer nak'd our CI */
-static int  ipcp_rejci (fsm *, u_char *, int); /* Peer rej'd our CI */
-static int  ipcp_reqci (fsm *, u_char *, int *, int); /* Rcv CI */
-static void ipcp_up (fsm *);           /* We're UP */
-static void ipcp_down (fsm *);         /* We're DOWN */
-#if 0
-static void ipcp_script (fsm *, char *); /* Run an up/down script */
-#endif
-static void ipcp_finished (fsm *);     /* Don't need lower layer */
-
-/*
- * Protocol entry points from main code.
- */
-static void ipcp_init (int);
-static void ipcp_open (int);
-static void ipcp_close (int, char *);
-static void ipcp_lowerup (int);
-static void ipcp_lowerdown (int);
-static void ipcp_input (int, u_char *, int);
-static void ipcp_protrej (int);
-
-static void ipcp_clear_addrs (int);
-
-#define CODENAME(x)    ((x) == CONFACK ? "ACK" : \
-                        (x) == CONFNAK ? "NAK" : "REJ")
-
-
-
-/******************************/
-/*** PUBLIC DATA STRUCTURES ***/
-/******************************/
-/* global vars */
-ipcp_options ipcp_wantoptions[NUM_PPP];        /* Options that we want to request */
-ipcp_options ipcp_gotoptions[NUM_PPP]; /* Options that peer ack'd */
-ipcp_options ipcp_allowoptions[NUM_PPP];       /* Options we allow peer to request */
-ipcp_options ipcp_hisoptions[NUM_PPP]; /* Options that we ack'd */
-
-fsm ipcp_fsm[NUM_PPP];         /* IPCP fsm structure */
-
-struct protent ipcp_protent = {
-    PPP_IPCP,
-    ipcp_init,
-    ipcp_input,
-    ipcp_protrej,
-    ipcp_lowerup,
-    ipcp_lowerdown,
-    ipcp_open,
-    ipcp_close,
-#if 0
-    ipcp_printpkt,
-    NULL,
-#endif
-    1,
-    "IPCP",
-#if 0
-    ip_check_options,
-    NULL,
-    ip_active_pkt
-#endif
-};
-
-
-
-/*****************************/
-/*** LOCAL DATA STRUCTURES ***/
-/*****************************/
-/* local vars */
-static int cis_received[NUM_PPP];              /* # Conf-Reqs received */
-static int default_route_set[NUM_PPP]; /* Have set up a default route */
-
-static fsm_callbacks ipcp_callbacks = { /* IPCP callback routines */
-    ipcp_resetci,              /* Reset our Configuration Information */
-    ipcp_cilen,                        /* Length of our Configuration Information */
-    ipcp_addci,                        /* Add our Configuration Information */
-    ipcp_ackci,                        /* ACK our Configuration Information */
-    ipcp_nakci,                        /* NAK our Configuration Information */
-    ipcp_rejci,                        /* Reject our Configuration Information */
-    ipcp_reqci,                        /* Request peer's Configuration Information */
-    ipcp_up,                   /* Called when fsm reaches OPENED state */
-    ipcp_down,                 /* Called when fsm leaves OPENED state */
-    NULL,                              /* Called when we want the lower layer up */
-    ipcp_finished,             /* Called when we want the lower layer down */
-    NULL,                              /* Called when Protocol-Reject received */
-    NULL,                              /* Retransmission is necessary */
-    NULL,                              /* Called to handle protocol-specific codes */
-    "IPCP"                             /* String name of protocol */
-};
-
-
-
-/**********************************/
-/*** LOCAL FUNCTION DEFINITIONS ***/
-/**********************************/
-
-/*
- * Non-standard inet_ntoa left here for compat with original ppp
- * sources. Assumes u32_t instead of struct in_addr.
- */ 
-
-char * _inet_ntoa(u32_t n)
-{
-       struct in_addr ia;
-       ia.s_addr = n;
-       return inet_ntoa(ia);
-}
-
-#define inet_ntoa _inet_ntoa
-
-/*
- * ipcp_init - Initialize IPCP.
- */
-static void ipcp_init(int unit)
-{
-       fsm *f = &ipcp_fsm[unit];
-       ipcp_options *wo = &ipcp_wantoptions[unit];
-       ipcp_options *ao = &ipcp_allowoptions[unit];
-       
-       f->unit = unit;
-       f->protocol = PPP_IPCP;
-       f->callbacks = &ipcp_callbacks;
-       fsm_init(&ipcp_fsm[unit]);
-       
-       memset(wo, 0, sizeof(*wo));
-       memset(ao, 0, sizeof(*ao));
-       
-       wo->neg_addr = 1;
-       wo->ouraddr = 0;
-#if VJ_SUPPORT > 0
-       wo->neg_vj = 1;
-#else
-       wo->neg_vj = 0;
-#endif
-       wo->vj_protocol = IPCP_VJ_COMP;
-       wo->maxslotindex = MAX_SLOTS - 1;
-       wo->cflag = 0;
-       
-       wo->default_route = 1;
-       
-       ao->neg_addr = 1;
-#if VJ_SUPPORT > 0
-       ao->neg_vj = 1;
-#else
-       ao->neg_vj = 0;
-#endif
-       ao->maxslotindex = MAX_SLOTS - 1;
-       ao->cflag = 1;
-       
-       ao->default_route = 1;
-}
-
-
-/*
- * ipcp_open - IPCP is allowed to come up.
- */
-static void ipcp_open(int unit)
-{
-       fsm_open(&ipcp_fsm[unit]);
-}
-
-
-/*
- * ipcp_close - Take IPCP down.
- */
-static void ipcp_close(int unit, char *reason)
-{
-       fsm_close(&ipcp_fsm[unit], reason);
-}
-
-
-/*
- * ipcp_lowerup - The lower layer is up.
- */
-static void ipcp_lowerup(int unit)
-{
-       fsm_lowerup(&ipcp_fsm[unit]);
-}
-
-
-/*
- * ipcp_lowerdown - The lower layer is down.
- */
-static void ipcp_lowerdown(int unit)
-{
-       fsm_lowerdown(&ipcp_fsm[unit]);
-}
-
-
-/*
- * ipcp_input - Input IPCP packet.
- */
-static void ipcp_input(int unit, u_char *p, int len)
-{
-       fsm_input(&ipcp_fsm[unit], p, len);
-}
-
-
-/*
- * ipcp_protrej - A Protocol-Reject was received for IPCP.
- *
- * Pretend the lower layer went down, so we shut up.
- */
-static void ipcp_protrej(int unit)
-{
-       fsm_lowerdown(&ipcp_fsm[unit]);
-}
-
-
-/*
- * ipcp_resetci - Reset our CI.
- */
-static void ipcp_resetci(fsm *f)
-{
-       ipcp_options *wo = &ipcp_wantoptions[f->unit];
-       
-       wo->req_addr = wo->neg_addr && ipcp_allowoptions[f->unit].neg_addr;
-       if (wo->ouraddr == 0)
-               wo->accept_local = 1;
-       if (wo->hisaddr == 0)
-               wo->accept_remote = 1;
-       /* Request DNS addresses from the peer */
-       wo->req_dns1 = ppp_settings.usepeerdns;
-       wo->req_dns2 = ppp_settings.usepeerdns;
-       ipcp_gotoptions[f->unit] = *wo;
-       cis_received[f->unit] = 0;
-}
-
-
-/*
- * ipcp_cilen - Return length of our CI.
- */
-static int ipcp_cilen(fsm *f)
-{
-       ipcp_options *go = &ipcp_gotoptions[f->unit];
-       ipcp_options *wo = &ipcp_wantoptions[f->unit];
-       ipcp_options *ho = &ipcp_hisoptions[f->unit];
-       
-#define LENCIVJ(neg, old)      (neg ? (old? CILEN_COMPRESS : CILEN_VJ) : 0)
-#define LENCIADDR(neg, old)    (neg ? (old? CILEN_ADDRS : CILEN_ADDR) : 0)
-#define LENCIDNS(neg)          (neg ? (CILEN_ADDR) : 0)
-       
-       /*
-        * First see if we want to change our options to the old
-        * forms because we have received old forms from the peer.
-        */
-       if (wo->neg_addr && !go->neg_addr && !go->old_addrs) {
-               /* use the old style of address negotiation */
-               go->neg_addr = 1;
-               go->old_addrs = 1;
-       }
-       if (wo->neg_vj && !go->neg_vj && !go->old_vj) {
-               /* try an older style of VJ negotiation */
-               if (cis_received[f->unit] == 0) {
-                       /* keep trying the new style until we see some CI from the peer */
-                       go->neg_vj = 1;
-               } else {
-                       /* use the old style only if the peer did */
-                       if (ho->neg_vj && ho->old_vj) {
-                               go->neg_vj = 1;
-                               go->old_vj = 1;
-                               go->vj_protocol = ho->vj_protocol;
-                       }
-               }
-       }
-       
-       return (LENCIADDR(go->neg_addr, go->old_addrs)
-                       + LENCIVJ(go->neg_vj, go->old_vj) +
-                       LENCIDNS(go->req_dns1) +
-                       LENCIDNS(go->req_dns2));
-}
-
-
-/*
- * ipcp_addci - Add our desired CIs to a packet.
- */
-static void ipcp_addci(fsm *f, u_char *ucp, int *lenp)
-{
-       ipcp_options *go = &ipcp_gotoptions[f->unit];
-       int len = *lenp;
-       
-#define ADDCIVJ(opt, neg, val, old, maxslotindex, cflag) \
-       if (neg) { \
-               int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \
-               if (len >= vjlen) { \
-                       PUTCHAR(opt, ucp); \
-                       PUTCHAR(vjlen, ucp); \
-                       PUTSHORT(val, ucp); \
-                       if (!old) { \
-                               PUTCHAR(maxslotindex, ucp); \
-                               PUTCHAR(cflag, ucp); \
-                       } \
-                       len -= vjlen; \
-               } else \
-                       neg = 0; \
-       }
-       
-#define ADDCIADDR(opt, neg, old, val1, val2) \
-       if (neg) { \
-               int addrlen = (old? CILEN_ADDRS: CILEN_ADDR); \
-               if (len >= addrlen) { \
-                       u32_t l; \
-                       PUTCHAR(opt, ucp); \
-                       PUTCHAR(addrlen, ucp); \
-                       l = ntohl(val1); \
-                       PUTLONG(l, ucp); \
-                       if (old) { \
-                               l = ntohl(val2); \
-                               PUTLONG(l, ucp); \
-                       } \
-                       len -= addrlen; \
-               } else \
-                       neg = 0; \
-       }
-
-#define ADDCIDNS(opt, neg, addr) \
-       if (neg) { \
-               if (len >= CILEN_ADDR) { \
-                       u32_t l; \
-                       PUTCHAR(opt, ucp); \
-                       PUTCHAR(CILEN_ADDR, ucp); \
-                       l = ntohl(addr); \
-                       PUTLONG(l, ucp); \
-                       len -= CILEN_ADDR; \
-               } else \
-                       neg = 0; \
-       }
-       
-       ADDCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), go->neg_addr,
-                         go->old_addrs, go->ouraddr, go->hisaddr);
-       
-       ADDCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj,
-                       go->maxslotindex, go->cflag);
-       
-       ADDCIDNS(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]);
-
-       ADDCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]);
-
-       *lenp -= len;
-}
-
-
-/*
- * ipcp_ackci - Ack our CIs.
- *
- * Returns:
- *     0 - Ack was bad.
- *     1 - Ack was good.
- */
-static int ipcp_ackci(fsm *f, u_char *p, int len)
-{
-       ipcp_options *go = &ipcp_gotoptions[f->unit];
-       u_short cilen, citype, cishort;
-       u32_t cilong;
-       u_char cimaxslotindex, cicflag;
-       
-       /*
-        * CIs must be in exactly the same order that we sent...
-        * Check packet length and CI length at each step.
-        * If we find any deviations, then this packet is bad.
-        */
-       
-#define ACKCIVJ(opt, neg, val, old, maxslotindex, cflag) \
-       if (neg) { \
-               int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \
-               if ((len -= vjlen) < 0) \
-                       goto bad; \
-               GETCHAR(citype, p); \
-               GETCHAR(cilen, p); \
-               if (cilen != vjlen || \
-                               citype != opt)  \
-                       goto bad; \
-               GETSHORT(cishort, p); \
-               if (cishort != val) \
-                       goto bad; \
-               if (!old) { \
-                       GETCHAR(cimaxslotindex, p); \
-                       if (cimaxslotindex != maxslotindex) \
-                               goto bad; \
-                       GETCHAR(cicflag, p); \
-                       if (cicflag != cflag) \
-                               goto bad; \
-               } \
-       }
-       
-#define ACKCIADDR(opt, neg, old, val1, val2) \
-       if (neg) { \
-               int addrlen = (old? CILEN_ADDRS: CILEN_ADDR); \
-               u32_t l; \
-               if ((len -= addrlen) < 0) \
-                       goto bad; \
-               GETCHAR(citype, p); \
-               GETCHAR(cilen, p); \
-               if (cilen != addrlen || \
-                               citype != opt) \
-                       goto bad; \
-               GETLONG(l, p); \
-               cilong = htonl(l); \
-               if (val1 != cilong) \
-                       goto bad; \
-               if (old) { \
-                       GETLONG(l, p); \
-                       cilong = htonl(l); \
-                       if (val2 != cilong) \
-                               goto bad; \
-               } \
-       }
-
-#define ACKCIDNS(opt, neg, addr) \
-       if (neg) { \
-               u32_t l; \
-               if ((len -= CILEN_ADDR) < 0) \
-                       goto bad; \
-               GETCHAR(citype, p); \
-               GETCHAR(cilen, p); \
-               if (cilen != CILEN_ADDR || \
-                               citype != opt) \
-                       goto bad; \
-               GETLONG(l, p); \
-               cilong = htonl(l); \
-               if (addr != cilong) \
-                       goto bad; \
-       }
-       
-       ACKCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), go->neg_addr,
-                         go->old_addrs, go->ouraddr, go->hisaddr);
-       
-       ACKCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj,
-                       go->maxslotindex, go->cflag);
-       
-       ACKCIDNS(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]);
-
-       ACKCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]);
-
-       /*
-        * If there are any remaining CIs, then this packet is bad.
-        */
-       if (len != 0)
-               goto bad;
-       return (1);
-       
-bad:
-       IPCPDEBUG((LOG_INFO, "ipcp_ackci: received bad Ack!\n"));
-       return (0);
-}
-
-/*
- * ipcp_nakci - Peer has sent a NAK for some of our CIs.
- * This should not modify any state if the Nak is bad
- * or if IPCP is in the OPENED state.
- *
- * Returns:
- *     0 - Nak was bad.
- *     1 - Nak was good.
- */
-static int ipcp_nakci(fsm *f, u_char *p, int len)
-{
-       ipcp_options *go = &ipcp_gotoptions[f->unit];
-       u_char cimaxslotindex, cicflag;
-       u_char citype, cilen, *next;
-       u_short cishort;
-       u32_t ciaddr1, ciaddr2, l, cidnsaddr;
-       ipcp_options no;                /* options we've seen Naks for */
-       ipcp_options try;               /* options to request next time */
-       
-       BZERO(&no, sizeof(no));
-       try = *go;
-       
-       /*
-        * Any Nak'd CIs must be in exactly the same order that we sent.
-        * Check packet length and CI length at each step.
-        * If we find any deviations, then this packet is bad.
-        */
-#define NAKCIADDR(opt, neg, old, code) \
-       if (go->neg && \
-                       len >= (cilen = (old? CILEN_ADDRS: CILEN_ADDR)) && \
-                       p[1] == cilen && \
-                       p[0] == opt) { \
-               len -= cilen; \
-               INCPTR(2, p); \
-               GETLONG(l, p); \
-               ciaddr1 = htonl(l); \
-               if (old) { \
-                       GETLONG(l, p); \
-                       ciaddr2 = htonl(l); \
-                       no.old_addrs = 1; \
-               } else \
-                       ciaddr2 = 0; \
-               no.neg = 1; \
-               code \
-       }
-       
-#define NAKCIVJ(opt, neg, code) \
-       if (go->neg && \
-                       ((cilen = p[1]) == CILEN_COMPRESS || cilen == CILEN_VJ) && \
-                       len >= cilen && \
-                       p[0] == opt) { \
-               len -= cilen; \
-               INCPTR(2, p); \
-               GETSHORT(cishort, p); \
-               no.neg = 1; \
-               code \
-       }
-       
-#define NAKCIDNS(opt, neg, code) \
-       if (go->neg && \
-                       ((cilen = p[1]) == CILEN_ADDR) && \
-                       len >= cilen && \
-                       p[0] == opt) { \
-               len -= cilen; \
-               INCPTR(2, p); \
-               GETLONG(l, p); \
-               cidnsaddr = htonl(l); \
-               no.neg = 1; \
-               code \
-       }
-       
-       /*
-        * Accept the peer's idea of {our,his} address, if different
-        * from our idea, only if the accept_{local,remote} flag is set.
-        */
-       NAKCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), neg_addr, go->old_addrs,
-         if (go->accept_local && ciaddr1) { /* Do we know our address? */
-                 try.ouraddr = ciaddr1;
-                 IPCPDEBUG((LOG_INFO, "local IP address %s\n",
-                            inet_ntoa(ciaddr1)));
-         }
-         if (go->accept_remote && ciaddr2) { /* Does he know his? */
-                 try.hisaddr = ciaddr2;
-                 IPCPDEBUG((LOG_INFO, "remote IP address %s\n",
-                            inet_ntoa(ciaddr2)));
-         }
-       );
-       
-       /*
-        * Accept the peer's value of maxslotindex provided that it
-        * is less than what we asked for.  Turn off slot-ID compression
-        * if the peer wants.  Send old-style compress-type option if
-        * the peer wants.
-        */
-       NAKCIVJ(CI_COMPRESSTYPE, neg_vj,
-               if (cilen == CILEN_VJ) {
-                       GETCHAR(cimaxslotindex, p);
-                       GETCHAR(cicflag, p);
-                       if (cishort == IPCP_VJ_COMP) {
-                               try.old_vj = 0;
-                               if (cimaxslotindex < go->maxslotindex)
-                                       try.maxslotindex = cimaxslotindex;
-                               if (!cicflag)
-                                       try.cflag = 0;
-                       } else {
-                               try.neg_vj = 0;
-                       }
-               } else {
-                       if (cishort == IPCP_VJ_COMP || cishort == IPCP_VJ_COMP_OLD) {
-                               try.old_vj = 1;
-                               try.vj_protocol = cishort;
-                       } else {
-                               try.neg_vj = 0;
-                       }
-               }
-       );
-       
-       NAKCIDNS(CI_MS_DNS1, req_dns1,
-                       try.dnsaddr[0] = cidnsaddr;
-                       IPCPDEBUG((LOG_INFO, "primary DNS address %s\n", inet_ntoa(cidnsaddr)));
-                       );
-
-       NAKCIDNS(CI_MS_DNS2, req_dns2,
-                       try.dnsaddr[1] = cidnsaddr;
-                       IPCPDEBUG((LOG_INFO, "secondary DNS address %s\n", inet_ntoa(cidnsaddr)));
-                       );
-
-       /*
-       * There may be remaining CIs, if the peer is requesting negotiation
-       * on an option that we didn't include in our request packet.
-       * If they want to negotiate about IP addresses, we comply.
-       * If they want us to ask for compression, we refuse.
-       */
-       while (len > CILEN_VOID) {
-               GETCHAR(citype, p);
-               GETCHAR(cilen, p);
-               if( (len -= cilen) < 0 )
-                       goto bad;
-               next = p + cilen - 2;
-               
-               switch (citype) {
-               case CI_COMPRESSTYPE:
-                       if (go->neg_vj || no.neg_vj ||
-                                       (cilen != CILEN_VJ && cilen != CILEN_COMPRESS))
-                               goto bad;
-                       no.neg_vj = 1;
-                       break;
-               case CI_ADDRS:
-                       if ((go->neg_addr && go->old_addrs) || no.old_addrs
-                                       || cilen != CILEN_ADDRS)
-                               goto bad;
-                       try.neg_addr = 1;
-                       try.old_addrs = 1;
-                       GETLONG(l, p);
-                       ciaddr1 = htonl(l);
-                       if (ciaddr1 && go->accept_local)
-                               try.ouraddr = ciaddr1;
-                       GETLONG(l, p);
-                       ciaddr2 = htonl(l);
-                       if (ciaddr2 && go->accept_remote)
-                               try.hisaddr = ciaddr2;
-                       no.old_addrs = 1;
-                       break;
-               case CI_ADDR:
-                       if (go->neg_addr || no.neg_addr || cilen != CILEN_ADDR)
-                               goto bad;
-                       try.old_addrs = 0;
-                       GETLONG(l, p);
-                       ciaddr1 = htonl(l);
-                       if (ciaddr1 && go->accept_local)
-                               try.ouraddr = ciaddr1;
-                       if (try.ouraddr != 0)
-                               try.neg_addr = 1;
-                       no.neg_addr = 1;
-                       break;
-               }
-               p = next;
-       }
-       
-       /* If there is still anything left, this packet is bad. */
-       if (len != 0)
-               goto bad;
-       
-       /*
-        * OK, the Nak is good.  Now we can update state.
-        */
-       if (f->state != OPENED)
-               *go = try;
-       
-       return 1;
-       
-bad:
-       IPCPDEBUG((LOG_INFO, "ipcp_nakci: received bad Nak!\n"));
-       return 0;
-}
-
-
-/*
- * ipcp_rejci - Reject some of our CIs.
- */
-static int ipcp_rejci(fsm *f, u_char *p, int len)
-{
-       ipcp_options *go = &ipcp_gotoptions[f->unit];
-       u_char cimaxslotindex, ciflag, cilen;
-       u_short cishort;
-       u32_t cilong;
-       ipcp_options try;               /* options to request next time */
-       
-       try = *go;
-       /*
-        * Any Rejected CIs must be in exactly the same order that we sent.
-        * Check packet length and CI length at each step.
-        * If we find any deviations, then this packet is bad.
-        */
-#define REJCIADDR(opt, neg, old, val1, val2) \
-       if (go->neg && \
-                       len >= (cilen = old? CILEN_ADDRS: CILEN_ADDR) && \
-                       p[1] == cilen && \
-                       p[0] == opt) { \
-               u32_t l; \
-               len -= cilen; \
-               INCPTR(2, p); \
-               GETLONG(l, p); \
-               cilong = htonl(l); \
-               /* Check rejected value. */ \
-               if (cilong != val1) \
-                       goto bad; \
-               if (old) { \
-                       GETLONG(l, p); \
-                       cilong = htonl(l); \
-                       /* Check rejected value. */ \
-                       if (cilong != val2) \
-                               goto bad; \
-               } \
-               try.neg = 0; \
-       }
-       
-#define REJCIVJ(opt, neg, val, old, maxslot, cflag) \
-       if (go->neg && \
-                       p[1] == (old? CILEN_COMPRESS : CILEN_VJ) && \
-                       len >= p[1] && \
-                       p[0] == opt) { \
-               len -= p[1]; \
-               INCPTR(2, p); \
-               GETSHORT(cishort, p); \
-               /* Check rejected value. */  \
-               if (cishort != val) \
-                       goto bad; \
-               if (!old) { \
-                       GETCHAR(cimaxslotindex, p); \
-                       if (cimaxslotindex != maxslot) \
-                               goto bad; \
-                       GETCHAR(ciflag, p); \
-                       if (ciflag != cflag) \
-                               goto bad; \
-               } \
-               try.neg = 0; \
-       }
-       
-#define REJCIDNS(opt, neg, dnsaddr) \
-       if (go->neg && \
-                       ((cilen = p[1]) == CILEN_ADDR) && \
-                       len >= cilen && \
-                       p[0] == opt) { \
-               u32_t l; \
-               len -= cilen; \
-               INCPTR(2, p); \
-               GETLONG(l, p); \
-               cilong = htonl(l); \
-               /* Check rejected value. */ \
-               if (cilong != dnsaddr) \
-                       goto bad; \
-               try.neg = 0; \
-       }
-
-       REJCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), neg_addr,
-                         go->old_addrs, go->ouraddr, go->hisaddr);
-       
-       REJCIVJ(CI_COMPRESSTYPE, neg_vj, go->vj_protocol, go->old_vj,
-                       go->maxslotindex, go->cflag);
-       
-       REJCIDNS(CI_MS_DNS1, req_dns1, go->dnsaddr[0]);
-
-       REJCIDNS(CI_MS_DNS2, req_dns2, go->dnsaddr[1]);
-
-       /*
-        * If there are any remaining CIs, then this packet is bad.
-        */
-       if (len != 0)
-               goto bad;
-       /*
-        * Now we can update state.
-        */
-       if (f->state != OPENED)
-               *go = try;
-       return 1;
-       
-bad:
-       IPCPDEBUG((LOG_INFO, "ipcp_rejci: received bad Reject!\n"));
-       return 0;
-}
-
-
-/*
- * ipcp_reqci - Check the peer's requested CIs and send appropriate response.
- *
- * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified
- * appropriately.  If reject_if_disagree is non-zero, doesn't return
- * CONFNAK; returns CONFREJ if it can't return CONFACK.
- */
-static int ipcp_reqci(
-       fsm *f,
-       u_char *inp,            /* Requested CIs */
-       int *len,                       /* Length of requested CIs */
-       int reject_if_disagree
-)
-{
-       ipcp_options *wo = &ipcp_wantoptions[f->unit];
-       ipcp_options *ho = &ipcp_hisoptions[f->unit];
-       ipcp_options *ao = &ipcp_allowoptions[f->unit];
-#ifdef OLD_CI_ADDRS
-       ipcp_options *go = &ipcp_gotoptions[f->unit];
-#endif
-       u_char *cip, *next;                             /* Pointer to current and next CIs */
-       u_short cilen, citype;                  /* Parsed len, type */
-       u_short cishort;                                /* Parsed short value */
-       u32_t tl, ciaddr1;                      /* Parsed address values */
-#ifdef OLD_CI_ADDRS
-       u32_t ciaddr2;                          /* Parsed address values */
-#endif
-       int rc = CONFACK;                               /* Final packet return code */
-       int orc;                                                /* Individual option return code */
-       u_char *p;                                              /* Pointer to next char to parse */
-       u_char *ucp = inp;                              /* Pointer to current output char */
-       int l = *len;                                   /* Length left */
-       u_char maxslotindex, cflag;
-       int d;
-       
-       cis_received[f->unit] = 1;
-       
-       /*
-        * Reset all his options.
-        */
-       BZERO(ho, sizeof(*ho));
-       
-       /*
-        * Process all his options.
-        */
-       next = inp;
-       while (l) {
-               orc = CONFACK;                          /* Assume success */
-               cip = p = next;                         /* Remember begining of CI */
-               if (l < 2 ||                            /* Not enough data for CI header or */
-                               p[1] < 2 ||                     /*  CI length too small or */
-                               p[1] > l) {                     /*  CI length too big? */
-                       IPCPDEBUG((LOG_INFO, "ipcp_reqci: bad CI length!\n"));
-                       orc = CONFREJ;                  /* Reject bad CI */
-                       cilen = l;                              /* Reject till end of packet */
-                       l = 0;                                  /* Don't loop again */
-                       goto endswitch;
-               }
-               GETCHAR(citype, p);                     /* Parse CI type */
-               GETCHAR(cilen, p);                      /* Parse CI length */
-               l -= cilen;                                     /* Adjust remaining length */
-               next += cilen;                          /* Step to next CI */
-
-               switch (citype) {                       /* Check CI type */
-#ifdef OLD_CI_ADDRS /* Need to save space... */
-               case CI_ADDRS:
-                       IPCPDEBUG((LOG_INFO, "ipcp_reqci: received ADDRS\n"));
-                       if (!ao->neg_addr ||
-                                       cilen != CILEN_ADDRS) { /* Check CI length */
-                               orc = CONFREJ;          /* Reject CI */
-                               break;
-                       }
-                       
-                       /*
-                        * If he has no address, or if we both have his address but
-                        * disagree about it, then NAK it with our idea.
-                        * In particular, if we don't know his address, but he does,
-                        * then accept it.
-                        */
-                       GETLONG(tl, p);         /* Parse source address (his) */
-                       ciaddr1 = htonl(tl);
-                       IPCPDEBUG((LOG_INFO, "his addr %s\n", inet_ntoa(ciaddr1)));
-                       if (ciaddr1 != wo->hisaddr
-                                       && (ciaddr1 == 0 || !wo->accept_remote)) {
-                               orc = CONFNAK;
-                               if (!reject_if_disagree) {
-                                       DECPTR(sizeof(u32_t), p);
-                                       tl = ntohl(wo->hisaddr);
-                                       PUTLONG(tl, p);
-                               }
-                       } else if (ciaddr1 == 0 && wo->hisaddr == 0) {
-                               /*
-                                * If neither we nor he knows his address, reject the option.
-                                */
-                               orc = CONFREJ;
-                               wo->req_addr = 0;       /* don't NAK with 0.0.0.0 later */
-                               break;
-                       }
-                       
-                       /*
-                        * If he doesn't know our address, or if we both have our address
-                        * but disagree about it, then NAK it with our idea.
-                        */
-                       GETLONG(tl, p);         /* Parse desination address (ours) */
-                       ciaddr2 = htonl(tl);
-                       IPCPDEBUG((LOG_INFO, "our addr %s\n", inet_ntoa(ciaddr2)));
-                       if (ciaddr2 != wo->ouraddr) {
-                               if (ciaddr2 == 0 || !wo->accept_local) {
-                                       orc = CONFNAK;
-                                       if (!reject_if_disagree) {
-                                               DECPTR(sizeof(u32_t), p);
-                                               tl = ntohl(wo->ouraddr);
-                                               PUTLONG(tl, p);
-                                       }
-                               } else {
-                                       go->ouraddr = ciaddr2;  /* accept peer's idea */
-                               }
-                       }
-                       
-                       ho->neg_addr = 1;
-                       ho->old_addrs = 1;
-                       ho->hisaddr = ciaddr1;
-                       ho->ouraddr = ciaddr2;
-                       break;
-#endif
-               
-               case CI_ADDR:
-                       if (!ao->neg_addr) {
-                               IPCPDEBUG((LOG_INFO, "ipcp_reqci: Reject ADDR not allowed\n"));
-                               orc = CONFREJ;                          /* Reject CI */
-                               break;
-                       } else if (cilen != CILEN_ADDR) {       /* Check CI length */
-                               IPCPDEBUG((LOG_INFO, "ipcp_reqci: Reject ADDR bad len\n"));
-                               orc = CONFREJ;                          /* Reject CI */
-                               break;
-                       }
-                       
-                       /*
-                        * If he has no address, or if we both have his address but
-                        * disagree about it, then NAK it with our idea.
-                        * In particular, if we don't know his address, but he does,
-                        * then accept it.
-                        */
-                       GETLONG(tl, p); /* Parse source address (his) */
-                       ciaddr1 = htonl(tl);
-                       if (ciaddr1 != wo->hisaddr
-                                       && (ciaddr1 == 0 || !wo->accept_remote)) {
-                               orc = CONFNAK;
-                               if (!reject_if_disagree) {
-                                       DECPTR(sizeof(u32_t), p);
-                                       tl = ntohl(wo->hisaddr);
-                                       PUTLONG(tl, p);
-                               }
-                               IPCPDEBUG((LOG_INFO, "ipcp_reqci: Nak ADDR %s\n", inet_ntoa(ciaddr1)));
-                       } else if (ciaddr1 == 0 && wo->hisaddr == 0) {
-                               /*
-                                * Don't ACK an address of 0.0.0.0 - reject it instead.
-                                */
-                               IPCPDEBUG((LOG_INFO, "ipcp_reqci: Reject ADDR %s\n", inet_ntoa(ciaddr1)));
-                               orc = CONFREJ;
-                               wo->req_addr = 0;       /* don't NAK with 0.0.0.0 later */
-                               break;
-                       }
-                       
-                       ho->neg_addr = 1;
-                       ho->hisaddr = ciaddr1;
-                       IPCPDEBUG((LOG_INFO, "ipcp_reqci: ADDR %s\n", inet_ntoa(ciaddr1)));
-                       break;
-               
-               case CI_MS_DNS1:
-               case CI_MS_DNS2:
-                       /* Microsoft primary or secondary DNS request */
-                       d = citype == CI_MS_DNS2;
-                       
-                       /* If we do not have a DNS address then we cannot send it */
-                       if (ao->dnsaddr[d] == 0 ||
-                                       cilen != CILEN_ADDR) {  /* Check CI length */
-                               IPCPDEBUG((LOG_INFO, "ipcp_reqci: Rejecting DNS%d Request\n", d+1));
-                               orc = CONFREJ;                          /* Reject CI */
-                               break;
-                       }
-                       GETLONG(tl, p);
-                       if (htonl(tl) != ao->dnsaddr[d]) {
-                               IPCPDEBUG((LOG_INFO, "ipcp_reqci: Naking DNS%d Request %d\n",
-                                                       d+1, inet_ntoa(tl)));
-                               DECPTR(sizeof(u32_t), p);
-                               tl = ntohl(ao->dnsaddr[d]);
-                               PUTLONG(tl, p);
-                               orc = CONFNAK;
-                       }
-                       IPCPDEBUG((LOG_INFO, "ipcp_reqci: received DNS%d Request\n", d+1));
-                       break;
-               
-               case CI_MS_WINS1:
-               case CI_MS_WINS2:
-                       /* Microsoft primary or secondary WINS request */
-                       d = citype == CI_MS_WINS2;
-                       IPCPDEBUG((LOG_INFO, "ipcp_reqci: received WINS%d Request\n", d+1));
-                       
-                       /* If we do not have a DNS address then we cannot send it */
-                       if (ao->winsaddr[d] == 0 ||
-                               cilen != CILEN_ADDR) {  /* Check CI length */
-                               orc = CONFREJ;                  /* Reject CI */
-                               break;
-                       }
-                       GETLONG(tl, p);
-                       if (htonl(tl) != ao->winsaddr[d]) {
-                               DECPTR(sizeof(u32_t), p);
-                               tl = ntohl(ao->winsaddr[d]);
-                               PUTLONG(tl, p);
-                               orc = CONFNAK;
-                       }
-                       break;
-               
-               case CI_COMPRESSTYPE:
-                       if (!ao->neg_vj) {
-                               IPCPDEBUG((LOG_INFO, "ipcp_reqci: Rejecting COMPRESSTYPE not allowed\n"));
-                               orc = CONFREJ;
-                               break;
-                       } else if (cilen != CILEN_VJ && cilen != CILEN_COMPRESS) {
-                               IPCPDEBUG((LOG_INFO, "ipcp_reqci: Rejecting COMPRESSTYPE len=%d\n", cilen));
-                               orc = CONFREJ;
-                               break;
-                       }
-                       GETSHORT(cishort, p);
-                       
-                       if (!(cishort == IPCP_VJ_COMP ||
-                                       (cishort == IPCP_VJ_COMP_OLD && cilen == CILEN_COMPRESS))) {
-                               IPCPDEBUG((LOG_INFO, "ipcp_reqci: Rejecting COMPRESSTYPE %d\n", cishort));
-                               orc = CONFREJ;
-                               break;
-                       }
-                       
-                       ho->neg_vj = 1;
-                       ho->vj_protocol = cishort;
-                       if (cilen == CILEN_VJ) {
-                               GETCHAR(maxslotindex, p);
-                               if (maxslotindex > ao->maxslotindex) { 
-                                       IPCPDEBUG((LOG_INFO, "ipcp_reqci: Naking VJ max slot %d\n", maxslotindex));
-                                       orc = CONFNAK;
-                                       if (!reject_if_disagree){
-                                               DECPTR(1, p);
-                                               PUTCHAR(ao->maxslotindex, p);
-                                       }
-                               }
-                               GETCHAR(cflag, p);
-                               if (cflag && !ao->cflag) {
-                                       IPCPDEBUG((LOG_INFO, "ipcp_reqci: Naking VJ cflag %d\n", cflag));
-                                       orc = CONFNAK;
-                                       if (!reject_if_disagree){
-                                               DECPTR(1, p);
-                                               PUTCHAR(wo->cflag, p);
-                                       }
-                               }
-                               ho->maxslotindex = maxslotindex;
-                               ho->cflag = cflag;
-                       } else {
-                               ho->old_vj = 1;
-                               ho->maxslotindex = MAX_SLOTS - 1;
-                               ho->cflag = 1;
-                       }
-                       IPCPDEBUG((LOG_INFO, 
-                                               "ipcp_reqci: received COMPRESSTYPE p=%d old=%d maxslot=%d cflag=%d\n",
-                                               ho->vj_protocol, ho->old_vj, ho->maxslotindex, ho->cflag));
-                       break;
-                       
-               default:
-                       IPCPDEBUG((LOG_INFO, "ipcp_reqci: Rejecting unknown CI type %d\n", citype));
-                       orc = CONFREJ;
-                       break;
-               }
-               
-endswitch:
-               if (orc == CONFACK &&           /* Good CI */
-                               rc != CONFACK)          /*  but prior CI wasnt? */
-                       continue;                               /* Don't send this one */
-               
-               if (orc == CONFNAK) {           /* Nak this CI? */
-                       if (reject_if_disagree) {       /* Getting fed up with sending NAKs? */
-                               IPCPDEBUG((LOG_INFO, "ipcp_reqci: Rejecting too many naks\n"));
-                               orc = CONFREJ;          /* Get tough if so */
-                       } else {
-                               if (rc == CONFREJ)      /* Rejecting prior CI? */
-                                       continue;               /* Don't send this one */
-                               if (rc == CONFACK) {    /* Ack'd all prior CIs? */
-                                       rc = CONFNAK;   /* Not anymore... */
-                                       ucp = inp;              /* Backup */
-                               }
-                       }
-               }
-               
-               if (orc == CONFREJ &&           /* Reject this CI */
-                               rc != CONFREJ) {        /*  but no prior ones? */
-                       rc = CONFREJ;
-                       ucp = inp;                              /* Backup */
-               }
-               
-               /* Need to move CI? */
-               if (ucp != cip)
-                       BCOPY(cip, ucp, cilen); /* Move it */
-               
-               /* Update output pointer */
-               INCPTR(cilen, ucp);
-       }
-       
-       /*
-        * If we aren't rejecting this packet, and we want to negotiate
-        * their address, and they didn't send their address, then we
-        * send a NAK with a CI_ADDR option appended.  We assume the
-        * input buffer is long enough that we can append the extra
-        * option safely.
-        */
-       if (rc != CONFREJ && !ho->neg_addr &&
-                       wo->req_addr && !reject_if_disagree) {
-               IPCPDEBUG((LOG_INFO, "ipcp_reqci: Requesting peer address\n"));
-               if (rc == CONFACK) {
-                       rc = CONFNAK;
-                       ucp = inp;                              /* reset pointer */
-                       wo->req_addr = 0;               /* don't ask again */
-               }
-               PUTCHAR(CI_ADDR, ucp);
-               PUTCHAR(CILEN_ADDR, ucp);
-               tl = ntohl(wo->hisaddr);
-               PUTLONG(tl, ucp);
-       }
-       
-       *len = (int)(ucp - inp);                /* Compute output length */
-       IPCPDEBUG((LOG_INFO, "ipcp_reqci: returning Configure-%s\n", CODENAME(rc)));
-       return (rc);                    /* Return final code */
-}
-
-
-#if 0
-/*
- * ip_check_options - check that any IP-related options are OK,
- * and assign appropriate defaults.
- */
-static void ip_check_options(u_long localAddr)
-{
-       ipcp_options *wo = &ipcp_wantoptions[0];
-
-       /*
-        * Load our default IP address but allow the remote host to give us
-        * a new address.
-        */
-       if (wo->ouraddr == 0 && !ppp_settings.disable_defaultip) {
-               wo->accept_local = 1;   /* don't insist on this default value */
-               wo->ouraddr = htonl(localAddr);
-       }
-}
-#endif
-
-
-/*
- * ipcp_up - IPCP has come UP.
- *
- * Configure the IP network interface appropriately and bring it up.
- */
-static void ipcp_up(fsm *f)
-{
-       u32_t mask;
-       ipcp_options *ho = &ipcp_hisoptions[f->unit];
-       ipcp_options *go = &ipcp_gotoptions[f->unit];
-       ipcp_options *wo = &ipcp_wantoptions[f->unit];
-       
-       np_up(f->unit, PPP_IP);
-       IPCPDEBUG((LOG_INFO, "ipcp: up\n"));
-       
-       /*
-        * We must have a non-zero IP address for both ends of the link.
-        */
-       if (!ho->neg_addr)
-               ho->hisaddr = wo->hisaddr;
-       
-       if (ho->hisaddr == 0) {
-               IPCPDEBUG((LOG_ERR, "Could not determine remote IP address\n"));
-               ipcp_close(f->unit, "Could not determine remote IP address");
-               return;
-       }
-       if (go->ouraddr == 0) {
-               IPCPDEBUG((LOG_ERR, "Could not determine local IP address\n"));
-               ipcp_close(f->unit, "Could not determine local IP address");
-               return;
-       }
-       
-       if (ppp_settings.usepeerdns && (go->dnsaddr[0] || go->dnsaddr[1])) {
-               /*pppGotDNSAddrs(go->dnsaddr[0], go->dnsaddr[1]);*/
-       }
-
-       /*
-        * Check that the peer is allowed to use the IP address it wants.
-        */
-       if (!auth_ip_addr(f->unit, ho->hisaddr)) {
-               IPCPDEBUG((LOG_ERR, "Peer is not authorized to use remote address %s\n",
-                               inet_ntoa(ho->hisaddr)));
-               ipcp_close(f->unit, "Unauthorized remote IP address");
-               return;
-       }
-       
-       /* set tcp compression */
-       sifvjcomp(f->unit, ho->neg_vj, ho->cflag, ho->maxslotindex);
-       
-       /*
-        * Set IP addresses and (if specified) netmask.
-        */
-       mask = GetMask(go->ouraddr);
-       
-       if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask, go->dnsaddr[0], go->dnsaddr[1])) {
-               IPCPDEBUG((LOG_WARNING, "sifaddr failed\n"));
-               ipcp_close(f->unit, "Interface configuration failed");
-               return;
-       }
-       
-       /* bring the interface up for IP */
-       if (!sifup(f->unit)) {
-               IPCPDEBUG((LOG_WARNING, "sifup failed\n"));
-               ipcp_close(f->unit, "Interface configuration failed");
-               return;
-       }
-       
-       sifnpmode(f->unit, PPP_IP, NPMODE_PASS);
-       
-       /* assign a default route through the interface if required */
-       if (ipcp_wantoptions[f->unit].default_route) 
-               if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr))
-                       default_route_set[f->unit] = 1;
-       
-       IPCPDEBUG((LOG_NOTICE, "local  IP address %s\n", inet_ntoa(go->ouraddr)));
-       IPCPDEBUG((LOG_NOTICE, "remote IP address %s\n", inet_ntoa(ho->hisaddr)));
-       if (go->dnsaddr[0]) {
-               IPCPDEBUG((LOG_NOTICE, "primary   DNS address %s\n", inet_ntoa(go->dnsaddr[0])));
-       }
-       if (go->dnsaddr[1]) {
-               IPCPDEBUG((LOG_NOTICE, "secondary DNS address %s\n", inet_ntoa(go->dnsaddr[1])));
-       }
-}
-
-
-/*
- * ipcp_down - IPCP has gone DOWN.
- *
- * Take the IP network interface down, clear its addresses
- * and delete routes through it.
- */
-static void ipcp_down(fsm *f)
-{
-       IPCPDEBUG((LOG_INFO, "ipcp: down\n"));
-       np_down(f->unit, PPP_IP);
-       sifvjcomp(f->unit, 0, 0, 0);
-       
-       sifdown(f->unit);
-       ipcp_clear_addrs(f->unit);
-}
-
-
-/*
- * ipcp_clear_addrs() - clear the interface addresses, routes, etc.
- */
-static void ipcp_clear_addrs(int unit)
-{
-       u32_t ouraddr, hisaddr;
-       
-       ouraddr = ipcp_gotoptions[unit].ouraddr;
-       hisaddr = ipcp_hisoptions[unit].hisaddr;
-       if (default_route_set[unit]) {
-               cifdefaultroute(unit, ouraddr, hisaddr);
-               default_route_set[unit] = 0;
-       }
-       cifaddr(unit, ouraddr, hisaddr);
-}
-
-
-/*
- * ipcp_finished - possibly shut down the lower layers.
- */
-static void ipcp_finished(fsm *f)
-{
-       np_finished(f->unit, PPP_IP);
-}
-
-#if 0
-static int ipcp_printpkt(
-       u_char *p,
-       int plen,
-       void (*printer) (void *, char *, ...),
-       void *arg
-)
-{
-       (void)p;
-       (void)plen;
-       (void)printer;
-       (void)arg;
-       return 0;
-}
-
-/*
- * ip_active_pkt - see if this IP packet is worth bringing the link up for.
- * We don't bring the link up for IP fragments or for TCP FIN packets
- * with no data.
- */
-#define IP_HDRLEN      20      /* bytes */
-#define IP_OFFMASK     0x1fff
-#define IPPROTO_TCP    6
-#define TCP_HDRLEN     20
-#define TH_FIN         0x01
-
-/*
- * We use these macros because the IP header may be at an odd address,
- * and some compilers might use word loads to get th_off or ip_hl.
- */
-
-#define net_short(x)   (((x)[0] << 8) + (x)[1])
-#define get_iphl(x)    (((unsigned char *)(x))[0] & 0xF)
-#define get_ipoff(x)   net_short((unsigned char *)(x) + 6)
-#define get_ipproto(x) (((unsigned char *)(x))[9])
-#define get_tcpoff(x)  (((unsigned char *)(x))[12] >> 4)
-#define get_tcpflags(x)        (((unsigned char *)(x))[13])
-
-static int ip_active_pkt(u_char *pkt, int len)
-{
-       u_char *tcp;
-       int hlen;
-       
-       len -= PPP_HDRLEN;
-       pkt += PPP_HDRLEN;
-       if (len < IP_HDRLEN)
-               return 0;
-       if ((get_ipoff(pkt) & IP_OFFMASK) != 0)
-               return 0;
-       if (get_ipproto(pkt) != IPPROTO_TCP)
-               return 1;
-       hlen = get_iphl(pkt) * 4;
-       if (len < hlen + TCP_HDRLEN)
-               return 0;
-       tcp = pkt + hlen;
-       if ((get_tcpflags(tcp) & TH_FIN) != 0 && len == hlen + get_tcpoff(tcp) * 4)
-               return 0;
-       return 1;
-}
-#endif
-
-#endif /* PPP_SUPPORT */
+/*****************************************************************************\r
+* ipcp.c - Network PPP IP Control Protocol program file.\r
+*\r
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.\r
+* portions Copyright (c) 1997 by Global Election Systems Inc.\r
+*\r
+* The authors hereby grant permission to use, copy, modify, distribute,\r
+* and license this software and its documentation for any purpose, provided\r
+* that existing copyright notices are retained in all copies and that this\r
+* notice and the following disclaimer are included verbatim in any \r
+* distributions. No written agreement, license, or royalty fee is required\r
+* for any of the authorized uses.\r
+*\r
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR\r
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+*\r
+******************************************************************************\r
+* REVISION HISTORY\r
+*\r
+* 03-01-01 Marc Boucher <marc@mbsi.ca>\r
+*   Ported to lwIP.\r
+* 97-12-08 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.\r
+*      Original.\r
+*****************************************************************************/\r
+/*\r
+ * ipcp.c - PPP IP Control Protocol.\r
+ *\r
+ * Copyright (c) 1989 Carnegie Mellon University.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms are permitted\r
+ * provided that the above copyright notice and this paragraph are\r
+ * duplicated in all such forms and that any documentation,\r
+ * advertising materials, and other materials related to such\r
+ * distribution and use acknowledge that the software was developed\r
+ * by Carnegie Mellon University.  The name of the\r
+ * University may not be used to endorse or promote products derived\r
+ * from this software without specific prior written permission.\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR\r
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r
+ */\r
+\r
+#include <string.h>\r
+\r
+#include "ppp.h"\r
+#if PPP_SUPPORT > 0\r
+#include "auth.h"\r
+#include "fsm.h"\r
+#include "vj.h"\r
+#include "ipcp.h"\r
+#include "pppdebug.h"\r
+\r
+\r
+/*************************/\r
+/*** LOCAL DEFINITIONS ***/\r
+/*************************/\r
+/* #define OLD_CI_ADDRS 1 */   /* Support deprecated address negotiation. */\r
+\r
+/*\r
+ * Lengths of configuration options.\r
+ */\r
+#define CILEN_VOID     2\r
+#define CILEN_COMPRESS 4       /* min length for compression protocol opt. */\r
+#define CILEN_VJ       6       /* length for RFC1332 Van-Jacobson opt. */\r
+#define CILEN_ADDR     6       /* new-style single address option */\r
+#define CILEN_ADDRS    10      /* old-style dual address option */\r
+\r
+\r
+\r
+/***********************************/\r
+/*** LOCAL FUNCTION DECLARATIONS ***/\r
+/***********************************/\r
+/*\r
+ * Callbacks for fsm code.  (CI = Configuration Information)\r
+ */\r
+static void ipcp_resetci (fsm *);      /* Reset our CI */\r
+static int  ipcp_cilen (fsm *);                /* Return length of our CI */\r
+static void ipcp_addci (fsm *, u_char *, int *); /* Add our CI */\r
+static int  ipcp_ackci (fsm *, u_char *, int); /* Peer ack'd our CI */\r
+static int  ipcp_nakci (fsm *, u_char *, int); /* Peer nak'd our CI */\r
+static int  ipcp_rejci (fsm *, u_char *, int); /* Peer rej'd our CI */\r
+static int  ipcp_reqci (fsm *, u_char *, int *, int); /* Rcv CI */\r
+static void ipcp_up (fsm *);           /* We're UP */\r
+static void ipcp_down (fsm *);         /* We're DOWN */\r
+#if 0\r
+static void ipcp_script (fsm *, char *); /* Run an up/down script */\r
+#endif\r
+static void ipcp_finished (fsm *);     /* Don't need lower layer */\r
+\r
+/*\r
+ * Protocol entry points from main code.\r
+ */\r
+static void ipcp_init (int);\r
+static void ipcp_open (int);\r
+static void ipcp_close (int, char *);\r
+static void ipcp_lowerup (int);\r
+static void ipcp_lowerdown (int);\r
+static void ipcp_input (int, u_char *, int);\r
+static void ipcp_protrej (int);\r
+\r
+static void ipcp_clear_addrs (int);\r
+\r
+#define CODENAME(x)    ((x) == CONFACK ? "ACK" : \\r
+                        (x) == CONFNAK ? "NAK" : "REJ")\r
+\r
+\r
+\r
+/******************************/\r
+/*** PUBLIC DATA STRUCTURES ***/\r
+/******************************/\r
+/* global vars */\r
+ipcp_options ipcp_wantoptions[NUM_PPP];        /* Options that we want to request */\r
+ipcp_options ipcp_gotoptions[NUM_PPP]; /* Options that peer ack'd */\r
+ipcp_options ipcp_allowoptions[NUM_PPP];       /* Options we allow peer to request */\r
+ipcp_options ipcp_hisoptions[NUM_PPP]; /* Options that we ack'd */\r
+\r
+fsm ipcp_fsm[NUM_PPP];         /* IPCP fsm structure */\r
+\r
+struct protent ipcp_protent = {\r
+    PPP_IPCP,\r
+    ipcp_init,\r
+    ipcp_input,\r
+    ipcp_protrej,\r
+    ipcp_lowerup,\r
+    ipcp_lowerdown,\r
+    ipcp_open,\r
+    ipcp_close,\r
+#if 0\r
+    ipcp_printpkt,\r
+    NULL,\r
+#endif\r
+    1,\r
+    "IPCP",\r
+#if 0\r
+    ip_check_options,\r
+    NULL,\r
+    ip_active_pkt\r
+#endif\r
+};\r
+\r
+\r
+\r
+/*****************************/\r
+/*** LOCAL DATA STRUCTURES ***/\r
+/*****************************/\r
+/* local vars */\r
+static int cis_received[NUM_PPP];              /* # Conf-Reqs received */\r
+static int default_route_set[NUM_PPP]; /* Have set up a default route */\r
+\r
+static fsm_callbacks ipcp_callbacks = { /* IPCP callback routines */\r
+    ipcp_resetci,              /* Reset our Configuration Information */\r
+    ipcp_cilen,                        /* Length of our Configuration Information */\r
+    ipcp_addci,                        /* Add our Configuration Information */\r
+    ipcp_ackci,                        /* ACK our Configuration Information */\r
+    ipcp_nakci,                        /* NAK our Configuration Information */\r
+    ipcp_rejci,                        /* Reject our Configuration Information */\r
+    ipcp_reqci,                        /* Request peer's Configuration Information */\r
+    ipcp_up,                   /* Called when fsm reaches OPENED state */\r
+    ipcp_down,                 /* Called when fsm leaves OPENED state */\r
+    NULL,                              /* Called when we want the lower layer up */\r
+    ipcp_finished,             /* Called when we want the lower layer down */\r
+    NULL,                              /* Called when Protocol-Reject received */\r
+    NULL,                              /* Retransmission is necessary */\r
+    NULL,                              /* Called to handle protocol-specific codes */\r
+    "IPCP"                             /* String name of protocol */\r
+};\r
+\r
+\r
+\r
+/**********************************/\r
+/*** LOCAL FUNCTION DEFINITIONS ***/\r
+/**********************************/\r
+\r
+/*\r
+ * Non-standard inet_ntoa left here for compat with original ppp\r
+ * sources. Assumes u32_t instead of struct in_addr.\r
+ */ \r
+\r
+char * _inet_ntoa(u32_t n)\r
+{\r
+       struct in_addr ia;\r
+       ia.s_addr = n;\r
+       return inet_ntoa(ia);\r
+}\r
+\r
+#define inet_ntoa _inet_ntoa\r
+\r
+/*\r
+ * ipcp_init - Initialize IPCP.\r
+ */\r
+static void ipcp_init(int unit)\r
+{\r
+       fsm *f = &ipcp_fsm[unit];\r
+       ipcp_options *wo = &ipcp_wantoptions[unit];\r
+       ipcp_options *ao = &ipcp_allowoptions[unit];\r
+       \r
+       f->unit = unit;\r
+       f->protocol = PPP_IPCP;\r
+       f->callbacks = &ipcp_callbacks;\r
+       fsm_init(&ipcp_fsm[unit]);\r
+       \r
+       memset(wo, 0, sizeof(*wo));\r
+       memset(ao, 0, sizeof(*ao));\r
+       \r
+       wo->neg_addr = 1;\r
+       wo->ouraddr = 0;\r
+#if VJ_SUPPORT > 0\r
+       wo->neg_vj = 1;\r
+#else\r
+       wo->neg_vj = 0;\r
+#endif\r
+       wo->vj_protocol = IPCP_VJ_COMP;\r
+       wo->maxslotindex = MAX_SLOTS - 1;\r
+       wo->cflag = 0;\r
+       \r
+       wo->default_route = 1;\r
+       \r
+       ao->neg_addr = 1;\r
+#if VJ_SUPPORT > 0\r
+       ao->neg_vj = 1;\r
+#else\r
+       ao->neg_vj = 0;\r
+#endif\r
+       ao->maxslotindex = MAX_SLOTS - 1;\r
+       ao->cflag = 1;\r
+       \r
+       ao->default_route = 1;\r
+}\r
+\r
+\r
+/*\r
+ * ipcp_open - IPCP is allowed to come up.\r
+ */\r
+static void ipcp_open(int unit)\r
+{\r
+       fsm_open(&ipcp_fsm[unit]);\r
+}\r
+\r
+\r
+/*\r
+ * ipcp_close - Take IPCP down.\r
+ */\r
+static void ipcp_close(int unit, char *reason)\r
+{\r
+       fsm_close(&ipcp_fsm[unit], reason);\r
+}\r
+\r
+\r
+/*\r
+ * ipcp_lowerup - The lower layer is up.\r
+ */\r
+static void ipcp_lowerup(int unit)\r
+{\r
+       fsm_lowerup(&ipcp_fsm[unit]);\r
+}\r
+\r
+\r
+/*\r
+ * ipcp_lowerdown - The lower layer is down.\r
+ */\r
+static void ipcp_lowerdown(int unit)\r
+{\r
+       fsm_lowerdown(&ipcp_fsm[unit]);\r
+}\r
+\r
+\r
+/*\r
+ * ipcp_input - Input IPCP packet.\r
+ */\r
+static void ipcp_input(int unit, u_char *p, int len)\r
+{\r
+       fsm_input(&ipcp_fsm[unit], p, len);\r
+}\r
+\r
+\r
+/*\r
+ * ipcp_protrej - A Protocol-Reject was received for IPCP.\r
+ *\r
+ * Pretend the lower layer went down, so we shut up.\r
+ */\r
+static void ipcp_protrej(int unit)\r
+{\r
+       fsm_lowerdown(&ipcp_fsm[unit]);\r
+}\r
+\r
+\r
+/*\r
+ * ipcp_resetci - Reset our CI.\r
+ */\r
+static void ipcp_resetci(fsm *f)\r
+{\r
+       ipcp_options *wo = &ipcp_wantoptions[f->unit];\r
+       \r
+       wo->req_addr = wo->neg_addr && ipcp_allowoptions[f->unit].neg_addr;\r
+       if (wo->ouraddr == 0)\r
+               wo->accept_local = 1;\r
+       if (wo->hisaddr == 0)\r
+               wo->accept_remote = 1;\r
+       /* Request DNS addresses from the peer */\r
+       wo->req_dns1 = ppp_settings.usepeerdns;\r
+       wo->req_dns2 = ppp_settings.usepeerdns;\r
+       ipcp_gotoptions[f->unit] = *wo;\r
+       cis_received[f->unit] = 0;\r
+}\r
+\r
+\r
+/*\r
+ * ipcp_cilen - Return length of our CI.\r
+ */\r
+static int ipcp_cilen(fsm *f)\r
+{\r
+       ipcp_options *go = &ipcp_gotoptions[f->unit];\r
+       ipcp_options *wo = &ipcp_wantoptions[f->unit];\r
+       ipcp_options *ho = &ipcp_hisoptions[f->unit];\r
+       \r
+#define LENCIVJ(neg, old)      (neg ? (old? CILEN_COMPRESS : CILEN_VJ) : 0)\r
+#define LENCIADDR(neg, old)    (neg ? (old? CILEN_ADDRS : CILEN_ADDR) : 0)\r
+#define LENCIDNS(neg)          (neg ? (CILEN_ADDR) : 0)\r
+       \r
+       /*\r
+        * First see if we want to change our options to the old\r
+        * forms because we have received old forms from the peer.\r
+        */\r
+       if (wo->neg_addr && !go->neg_addr && !go->old_addrs) {\r
+               /* use the old style of address negotiation */\r
+               go->neg_addr = 1;\r
+               go->old_addrs = 1;\r
+       }\r
+       if (wo->neg_vj && !go->neg_vj && !go->old_vj) {\r
+               /* try an older style of VJ negotiation */\r
+               if (cis_received[f->unit] == 0) {\r
+                       /* keep trying the new style until we see some CI from the peer */\r
+                       go->neg_vj = 1;\r
+               } else {\r
+                       /* use the old style only if the peer did */\r
+                       if (ho->neg_vj && ho->old_vj) {\r
+                               go->neg_vj = 1;\r
+                               go->old_vj = 1;\r
+                               go->vj_protocol = ho->vj_protocol;\r
+                       }\r
+               }\r
+       }\r
+       \r
+       return (LENCIADDR(go->neg_addr, go->old_addrs)\r
+                       + LENCIVJ(go->neg_vj, go->old_vj) +\r
+                       LENCIDNS(go->req_dns1) +\r
+                       LENCIDNS(go->req_dns2));\r
+}\r
+\r
+\r
+/*\r
+ * ipcp_addci - Add our desired CIs to a packet.\r
+ */\r
+static void ipcp_addci(fsm *f, u_char *ucp, int *lenp)\r
+{\r
+       ipcp_options *go = &ipcp_gotoptions[f->unit];\r
+       int len = *lenp;\r
+       \r
+#define ADDCIVJ(opt, neg, val, old, maxslotindex, cflag) \\r
+       if (neg) { \\r
+               int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \\r
+               if (len >= vjlen) { \\r
+                       PUTCHAR(opt, ucp); \\r
+                       PUTCHAR(vjlen, ucp); \\r
+                       PUTSHORT(val, ucp); \\r
+                       if (!old) { \\r
+                               PUTCHAR(maxslotindex, ucp); \\r
+                               PUTCHAR(cflag, ucp); \\r
+                       } \\r
+                       len -= vjlen; \\r
+               } else \\r
+                       neg = 0; \\r
+       }\r
+       \r
+#define ADDCIADDR(opt, neg, old, val1, val2) \\r
+       if (neg) { \\r
+               int addrlen = (old? CILEN_ADDRS: CILEN_ADDR); \\r
+               if (len >= addrlen) { \\r
+                       u32_t l; \\r
+                       PUTCHAR(opt, ucp); \\r
+                       PUTCHAR(addrlen, ucp); \\r
+                       l = ntohl(val1); \\r
+                       PUTLONG(l, ucp); \\r
+                       if (old) { \\r
+                               l = ntohl(val2); \\r
+                               PUTLONG(l, ucp); \\r
+                       } \\r
+                       len -= addrlen; \\r
+               } else \\r
+                       neg = 0; \\r
+       }\r
+\r
+#define ADDCIDNS(opt, neg, addr) \\r
+       if (neg) { \\r
+               if (len >= CILEN_ADDR) { \\r
+                       u32_t l; \\r
+                       PUTCHAR(opt, ucp); \\r
+                       PUTCHAR(CILEN_ADDR, ucp); \\r
+                       l = ntohl(addr); \\r
+                       PUTLONG(l, ucp); \\r
+                       len -= CILEN_ADDR; \\r
+               } else \\r
+                       neg = 0; \\r
+       }\r
+       \r
+       ADDCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), go->neg_addr,\r
+                         go->old_addrs, go->ouraddr, go->hisaddr);\r
+       \r
+       ADDCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj,\r
+                       go->maxslotindex, go->cflag);\r
+       \r
+       ADDCIDNS(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]);\r
+\r
+       ADDCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]);\r
+\r
+       *lenp -= len;\r
+}\r
+\r
+\r
+/*\r
+ * ipcp_ackci - Ack our CIs.\r
+ *\r
+ * Returns:\r
+ *     0 - Ack was bad.\r
+ *     1 - Ack was good.\r
+ */\r
+static int ipcp_ackci(fsm *f, u_char *p, int len)\r
+{\r
+       ipcp_options *go = &ipcp_gotoptions[f->unit];\r
+       u_short cilen, citype, cishort;\r
+       u32_t cilong;\r
+       u_char cimaxslotindex, cicflag;\r
+       \r
+       /*\r
+        * CIs must be in exactly the same order that we sent...\r
+        * Check packet length and CI length at each step.\r
+        * If we find any deviations, then this packet is bad.\r
+        */\r
+       \r
+#define ACKCIVJ(opt, neg, val, old, maxslotindex, cflag) \\r
+       if (neg) { \\r
+               int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \\r
+               if ((len -= vjlen) < 0) \\r
+                       goto bad; \\r
+               GETCHAR(citype, p); \\r
+               GETCHAR(cilen, p); \\r
+               if (cilen != vjlen || \\r
+                               citype != opt)  \\r
+                       goto bad; \\r
+               GETSHORT(cishort, p); \\r
+               if (cishort != val) \\r
+                       goto bad; \\r
+               if (!old) { \\r
+                       GETCHAR(cimaxslotindex, p); \\r
+                       if (cimaxslotindex != maxslotindex) \\r
+                               goto bad; \\r
+                       GETCHAR(cicflag, p); \\r
+                       if (cicflag != cflag) \\r
+                               goto bad; \\r
+               } \\r
+       }\r
+       \r
+#define ACKCIADDR(opt, neg, old, val1, val2) \\r
+       if (neg) { \\r
+               int addrlen = (old? CILEN_ADDRS: CILEN_ADDR); \\r
+               u32_t l; \\r
+               if ((len -= addrlen) < 0) \\r
+                       goto bad; \\r
+               GETCHAR(citype, p); \\r
+               GETCHAR(cilen, p); \\r
+               if (cilen != addrlen || \\r
+                               citype != opt) \\r
+                       goto bad; \\r
+               GETLONG(l, p); \\r
+               cilong = htonl(l); \\r
+               if (val1 != cilong) \\r
+                       goto bad; \\r
+               if (old) { \\r
+                       GETLONG(l, p); \\r
+                       cilong = htonl(l); \\r
+                       if (val2 != cilong) \\r
+                               goto bad; \\r
+               } \\r
+       }\r
+\r
+#define ACKCIDNS(opt, neg, addr) \\r
+       if (neg) { \\r
+               u32_t l; \\r
+               if ((len -= CILEN_ADDR) < 0) \\r
+                       goto bad; \\r
+               GETCHAR(citype, p); \\r
+               GETCHAR(cilen, p); \\r
+               if (cilen != CILEN_ADDR || \\r
+                               citype != opt) \\r
+                       goto bad; \\r
+               GETLONG(l, p); \\r
+               cilong = htonl(l); \\r
+               if (addr != cilong) \\r
+                       goto bad; \\r
+       }\r
+       \r
+       ACKCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), go->neg_addr,\r
+                         go->old_addrs, go->ouraddr, go->hisaddr);\r
+       \r
+       ACKCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj,\r
+                       go->maxslotindex, go->cflag);\r
+       \r
+       ACKCIDNS(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]);\r
+\r
+       ACKCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]);\r
+\r
+       /*\r
+        * If there are any remaining CIs, then this packet is bad.\r
+        */\r
+       if (len != 0)\r
+               goto bad;\r
+       return (1);\r
+       \r
+bad:\r
+       IPCPDEBUG((LOG_INFO, "ipcp_ackci: received bad Ack!\n"));\r
+       return (0);\r
+}\r
+\r
+/*\r
+ * ipcp_nakci - Peer has sent a NAK for some of our CIs.\r
+ * This should not modify any state if the Nak is bad\r
+ * or if IPCP is in the OPENED state.\r
+ *\r
+ * Returns:\r
+ *     0 - Nak was bad.\r
+ *     1 - Nak was good.\r
+ */\r
+static int ipcp_nakci(fsm *f, u_char *p, int len)\r
+{\r
+       ipcp_options *go = &ipcp_gotoptions[f->unit];\r
+       u_char cimaxslotindex, cicflag;\r
+       u_char citype, cilen, *next;\r
+       u_short cishort;\r
+       u32_t ciaddr1, ciaddr2, l, cidnsaddr;\r
+       ipcp_options no;                /* options we've seen Naks for */\r
+       ipcp_options try;               /* options to request next time */\r
+       \r
+       BZERO(&no, sizeof(no));\r
+       try = *go;\r
+       \r
+       /*\r
+        * Any Nak'd CIs must be in exactly the same order that we sent.\r
+        * Check packet length and CI length at each step.\r
+        * If we find any deviations, then this packet is bad.\r
+        */\r
+#define NAKCIADDR(opt, neg, old, code) \\r
+       if (go->neg && \\r
+                       len >= (cilen = (old? CILEN_ADDRS: CILEN_ADDR)) && \\r
+                       p[1] == cilen && \\r
+                       p[0] == opt) { \\r
+               len -= cilen; \\r
+               INCPTR(2, p); \\r
+               GETLONG(l, p); \\r
+               ciaddr1 = htonl(l); \\r
+               if (old) { \\r
+                       GETLONG(l, p); \\r
+                       ciaddr2 = htonl(l); \\r
+                       no.old_addrs = 1; \\r
+               } else \\r
+                       ciaddr2 = 0; \\r
+               no.neg = 1; \\r
+               code \\r
+       }\r
+       \r
+#define NAKCIVJ(opt, neg, code) \\r
+       if (go->neg && \\r
+                       ((cilen = p[1]) == CILEN_COMPRESS || cilen == CILEN_VJ) && \\r
+                       len >= cilen && \\r
+                       p[0] == opt) { \\r
+               len -= cilen; \\r
+               INCPTR(2, p); \\r
+               GETSHORT(cishort, p); \\r
+               no.neg = 1; \\r
+               code \\r
+       }\r
+       \r
+#define NAKCIDNS(opt, neg, code) \\r
+       if (go->neg && \\r
+                       ((cilen = p[1]) == CILEN_ADDR) && \\r
+                       len >= cilen && \\r
+                       p[0] == opt) { \\r
+               len -= cilen; \\r
+               INCPTR(2, p); \\r
+               GETLONG(l, p); \\r
+               cidnsaddr = htonl(l); \\r
+               no.neg = 1; \\r
+               code \\r
+       }\r
+       \r
+       /*\r
+        * Accept the peer's idea of {our,his} address, if different\r
+        * from our idea, only if the accept_{local,remote} flag is set.\r
+        */\r
+       NAKCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), neg_addr, go->old_addrs,\r
+         if (go->accept_local && ciaddr1) { /* Do we know our address? */\r
+                 try.ouraddr = ciaddr1;\r
+                 IPCPDEBUG((LOG_INFO, "local IP address %s\n",\r
+                            inet_ntoa(ciaddr1)));\r
+         }\r
+         if (go->accept_remote && ciaddr2) { /* Does he know his? */\r
+                 try.hisaddr = ciaddr2;\r
+                 IPCPDEBUG((LOG_INFO, "remote IP address %s\n",\r
+                            inet_ntoa(ciaddr2)));\r
+         }\r
+       );\r
+       \r
+       /*\r
+        * Accept the peer's value of maxslotindex provided that it\r
+        * is less than what we asked for.  Turn off slot-ID compression\r
+        * if the peer wants.  Send old-style compress-type option if\r
+        * the peer wants.\r
+        */\r
+       NAKCIVJ(CI_COMPRESSTYPE, neg_vj,\r
+               if (cilen == CILEN_VJ) {\r
+                       GETCHAR(cimaxslotindex, p);\r
+                       GETCHAR(cicflag, p);\r
+                       if (cishort == IPCP_VJ_COMP) {\r
+                               try.old_vj = 0;\r
+                               if (cimaxslotindex < go->maxslotindex)\r
+                                       try.maxslotindex = cimaxslotindex;\r
+                               if (!cicflag)\r
+                                       try.cflag = 0;\r
+                       } else {\r
+                               try.neg_vj = 0;\r
+                       }\r
+               } else {\r
+                       if (cishort == IPCP_VJ_COMP || cishort == IPCP_VJ_COMP_OLD) {\r
+                               try.old_vj = 1;\r
+                               try.vj_protocol = cishort;\r
+                       } else {\r
+                               try.neg_vj = 0;\r
+                       }\r
+               }\r
+       );\r
+       \r
+       NAKCIDNS(CI_MS_DNS1, req_dns1,\r
+                       try.dnsaddr[0] = cidnsaddr;\r
+                       IPCPDEBUG((LOG_INFO, "primary DNS address %s\n", inet_ntoa(cidnsaddr)));\r
+                       );\r
+\r
+       NAKCIDNS(CI_MS_DNS2, req_dns2,\r
+                       try.dnsaddr[1] = cidnsaddr;\r
+                       IPCPDEBUG((LOG_INFO, "secondary DNS address %s\n", inet_ntoa(cidnsaddr)));\r
+                       );\r
+\r
+       /*\r
+       * There may be remaining CIs, if the peer is requesting negotiation\r
+       * on an option that we didn't include in our request packet.\r
+       * If they want to negotiate about IP addresses, we comply.\r
+       * If they want us to ask for compression, we refuse.\r
+       */\r
+       while (len > CILEN_VOID) {\r
+               GETCHAR(citype, p);\r
+               GETCHAR(cilen, p);\r
+               if( (len -= cilen) < 0 )\r
+                       goto bad;\r
+               next = p + cilen - 2;\r
+               \r
+               switch (citype) {\r
+               case CI_COMPRESSTYPE:\r
+                       if (go->neg_vj || no.neg_vj ||\r
+                                       (cilen != CILEN_VJ && cilen != CILEN_COMPRESS))\r
+                               goto bad;\r
+                       no.neg_vj = 1;\r
+                       break;\r
+               case CI_ADDRS:\r
+                       if ((go->neg_addr && go->old_addrs) || no.old_addrs\r
+                                       || cilen != CILEN_ADDRS)\r
+                               goto bad;\r
+                       try.neg_addr = 1;\r
+                       try.old_addrs = 1;\r
+                       GETLONG(l, p);\r
+                       ciaddr1 = htonl(l);\r
+                       if (ciaddr1 && go->accept_local)\r
+                               try.ouraddr = ciaddr1;\r
+                       GETLONG(l, p);\r
+                       ciaddr2 = htonl(l);\r
+                       if (ciaddr2 && go->accept_remote)\r
+                               try.hisaddr = ciaddr2;\r
+                       no.old_addrs = 1;\r
+                       break;\r
+               case CI_ADDR:\r
+                       if (go->neg_addr || no.neg_addr || cilen != CILEN_ADDR)\r
+                               goto bad;\r
+                       try.old_addrs = 0;\r
+                       GETLONG(l, p);\r
+                       ciaddr1 = htonl(l);\r
+                       if (ciaddr1 && go->accept_local)\r
+                               try.ouraddr = ciaddr1;\r
+                       if (try.ouraddr != 0)\r
+                               try.neg_addr = 1;\r
+                       no.neg_addr = 1;\r
+                       break;\r
+               }\r
+               p = next;\r
+       }\r
+       \r
+       /* If there is still anything left, this packet is bad. */\r
+       if (len != 0)\r
+               goto bad;\r
+       \r
+       /*\r
+        * OK, the Nak is good.  Now we can update state.\r
+        */\r
+       if (f->state != OPENED)\r
+               *go = try;\r
+       \r
+       return 1;\r
+       \r
+bad:\r
+       IPCPDEBUG((LOG_INFO, "ipcp_nakci: received bad Nak!\n"));\r
+       return 0;\r
+}\r
+\r
+\r
+/*\r
+ * ipcp_rejci - Reject some of our CIs.\r
+ */\r
+static int ipcp_rejci(fsm *f, u_char *p, int len)\r
+{\r
+       ipcp_options *go = &ipcp_gotoptions[f->unit];\r
+       u_char cimaxslotindex, ciflag, cilen;\r
+       u_short cishort;\r
+       u32_t cilong;\r
+       ipcp_options try;               /* options to request next time */\r
+       \r
+       try = *go;\r
+       /*\r
+        * Any Rejected CIs must be in exactly the same order that we sent.\r
+        * Check packet length and CI length at each step.\r
+        * If we find any deviations, then this packet is bad.\r
+        */\r
+#define REJCIADDR(opt, neg, old, val1, val2) \\r
+       if (go->neg && \\r
+                       len >= (cilen = old? CILEN_ADDRS: CILEN_ADDR) && \\r
+                       p[1] == cilen && \\r
+                       p[0] == opt) { \\r
+               u32_t l; \\r
+               len -= cilen; \\r
+               INCPTR(2, p); \\r
+               GETLONG(l, p); \\r
+               cilong = htonl(l); \\r
+               /* Check rejected value. */ \\r
+               if (cilong != val1) \\r
+                       goto bad; \\r
+               if (old) { \\r
+                       GETLONG(l, p); \\r
+                       cilong = htonl(l); \\r
+                       /* Check rejected value. */ \\r
+                       if (cilong != val2) \\r
+                               goto bad; \\r
+               } \\r
+               try.neg = 0; \\r
+       }\r
+       \r
+#define REJCIVJ(opt, neg, val, old, maxslot, cflag) \\r
+       if (go->neg && \\r
+                       p[1] == (old? CILEN_COMPRESS : CILEN_VJ) && \\r
+                       len >= p[1] && \\r
+                       p[0] == opt) { \\r
+               len -= p[1]; \\r
+               INCPTR(2, p); \\r
+               GETSHORT(cishort, p); \\r
+               /* Check rejected value. */  \\r
+               if (cishort != val) \\r
+                       goto bad; \\r
+               if (!old) { \\r
+                       GETCHAR(cimaxslotindex, p); \\r
+                       if (cimaxslotindex != maxslot) \\r
+                               goto bad; \\r
+                       GETCHAR(ciflag, p); \\r
+                       if (ciflag != cflag) \\r
+                               goto bad; \\r
+               } \\r
+               try.neg = 0; \\r
+       }\r
+       \r
+#define REJCIDNS(opt, neg, dnsaddr) \\r
+       if (go->neg && \\r
+                       ((cilen = p[1]) == CILEN_ADDR) && \\r
+                       len >= cilen && \\r
+                       p[0] == opt) { \\r
+               u32_t l; \\r
+               len -= cilen; \\r
+               INCPTR(2, p); \\r
+               GETLONG(l, p); \\r
+               cilong = htonl(l); \\r
+               /* Check rejected value. */ \\r
+               if (cilong != dnsaddr) \\r
+                       goto bad; \\r
+               try.neg = 0; \\r
+       }\r
+\r
+       REJCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), neg_addr,\r
+                         go->old_addrs, go->ouraddr, go->hisaddr);\r
+       \r
+       REJCIVJ(CI_COMPRESSTYPE, neg_vj, go->vj_protocol, go->old_vj,\r
+                       go->maxslotindex, go->cflag);\r
+       \r
+       REJCIDNS(CI_MS_DNS1, req_dns1, go->dnsaddr[0]);\r
+\r
+       REJCIDNS(CI_MS_DNS2, req_dns2, go->dnsaddr[1]);\r
+\r
+       /*\r
+        * If there are any remaining CIs, then this packet is bad.\r
+        */\r
+       if (len != 0)\r
+               goto bad;\r
+       /*\r
+        * Now we can update state.\r
+        */\r
+       if (f->state != OPENED)\r
+               *go = try;\r
+       return 1;\r
+       \r
+bad:\r
+       IPCPDEBUG((LOG_INFO, "ipcp_rejci: received bad Reject!\n"));\r
+       return 0;\r
+}\r
+\r
+\r
+/*\r
+ * ipcp_reqci - Check the peer's requested CIs and send appropriate response.\r
+ *\r
+ * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified\r
+ * appropriately.  If reject_if_disagree is non-zero, doesn't return\r
+ * CONFNAK; returns CONFREJ if it can't return CONFACK.\r
+ */\r
+static int ipcp_reqci(\r
+       fsm *f,\r
+       u_char *inp,            /* Requested CIs */\r
+       int *len,                       /* Length of requested CIs */\r
+       int reject_if_disagree\r
+)\r
+{\r
+       ipcp_options *wo = &ipcp_wantoptions[f->unit];\r
+       ipcp_options *ho = &ipcp_hisoptions[f->unit];\r
+       ipcp_options *ao = &ipcp_allowoptions[f->unit];\r
+#ifdef OLD_CI_ADDRS\r
+       ipcp_options *go = &ipcp_gotoptions[f->unit];\r
+#endif\r
+       u_char *cip, *next;                             /* Pointer to current and next CIs */\r
+       u_short cilen, citype;                  /* Parsed len, type */\r
+       u_short cishort;                                /* Parsed short value */\r
+       u32_t tl, ciaddr1;                      /* Parsed address values */\r
+#ifdef OLD_CI_ADDRS\r
+       u32_t ciaddr2;                          /* Parsed address values */\r
+#endif\r
+       int rc = CONFACK;                               /* Final packet return code */\r
+       int orc;                                                /* Individual option return code */\r
+       u_char *p;                                              /* Pointer to next char to parse */\r
+       u_char *ucp = inp;                              /* Pointer to current output char */\r
+       int l = *len;                                   /* Length left */\r
+       u_char maxslotindex, cflag;\r
+       int d;\r
+       \r
+       cis_received[f->unit] = 1;\r
+       \r
+       /*\r
+        * Reset all his options.\r
+        */\r
+       BZERO(ho, sizeof(*ho));\r
+       \r
+       /*\r
+        * Process all his options.\r
+        */\r
+       next = inp;\r
+       while (l) {\r
+               orc = CONFACK;                          /* Assume success */\r
+               cip = p = next;                         /* Remember begining of CI */\r
+               if (l < 2 ||                            /* Not enough data for CI header or */\r
+                               p[1] < 2 ||                     /*  CI length too small or */\r
+                               p[1] > l) {                     /*  CI length too big? */\r
+                       IPCPDEBUG((LOG_INFO, "ipcp_reqci: bad CI length!\n"));\r
+                       orc = CONFREJ;                  /* Reject bad CI */\r
+                       cilen = l;                              /* Reject till end of packet */\r
+                       l = 0;                                  /* Don't loop again */\r
+                       goto endswitch;\r
+               }\r
+               GETCHAR(citype, p);                     /* Parse CI type */\r
+               GETCHAR(cilen, p);                      /* Parse CI length */\r
+               l -= cilen;                                     /* Adjust remaining length */\r
+               next += cilen;                          /* Step to next CI */\r
+\r
+               switch (citype) {                       /* Check CI type */\r
+#ifdef OLD_CI_ADDRS /* Need to save space... */\r
+               case CI_ADDRS:\r
+                       IPCPDEBUG((LOG_INFO, "ipcp_reqci: received ADDRS\n"));\r
+                       if (!ao->neg_addr ||\r
+                                       cilen != CILEN_ADDRS) { /* Check CI length */\r
+                               orc = CONFREJ;          /* Reject CI */\r
+                               break;\r
+                       }\r
+                       \r
+                       /*\r
+                        * If he has no address, or if we both have his address but\r
+                        * disagree about it, then NAK it with our idea.\r
+                        * In particular, if we don't know his address, but he does,\r
+                        * then accept it.\r
+                        */\r
+                       GETLONG(tl, p);         /* Parse source address (his) */\r
+                       ciaddr1 = htonl(tl);\r
+                       IPCPDEBUG((LOG_INFO, "his addr %s\n", inet_ntoa(ciaddr1)));\r
+                       if (ciaddr1 != wo->hisaddr\r
+                                       && (ciaddr1 == 0 || !wo->accept_remote)) {\r
+                               orc = CONFNAK;\r
+                               if (!reject_if_disagree) {\r
+                                       DECPTR(sizeof(u32_t), p);\r
+                                       tl = ntohl(wo->hisaddr);\r
+                                       PUTLONG(tl, p);\r
+                               }\r
+                       } else if (ciaddr1 == 0 && wo->hisaddr == 0) {\r
+                               /*\r
+                                * If neither we nor he knows his address, reject the option.\r
+                                */\r
+                               orc = CONFREJ;\r
+                               wo->req_addr = 0;       /* don't NAK with 0.0.0.0 later */\r
+                               break;\r
+                       }\r
+                       \r
+                       /*\r
+                        * If he doesn't know our address, or if we both have our address\r
+                        * but disagree about it, then NAK it with our idea.\r
+                        */\r
+                       GETLONG(tl, p);         /* Parse desination address (ours) */\r
+                       ciaddr2 = htonl(tl);\r
+                       IPCPDEBUG((LOG_INFO, "our addr %s\n", inet_ntoa(ciaddr2)));\r
+                       if (ciaddr2 != wo->ouraddr) {\r
+                               if (ciaddr2 == 0 || !wo->accept_local) {\r
+                                       orc = CONFNAK;\r
+                                       if (!reject_if_disagree) {\r
+                                               DECPTR(sizeof(u32_t), p);\r
+                                               tl = ntohl(wo->ouraddr);\r
+                                               PUTLONG(tl, p);\r
+                                       }\r
+                               } else {\r
+                                       go->ouraddr = ciaddr2;  /* accept peer's idea */\r
+                               }\r
+                       }\r
+                       \r
+                       ho->neg_addr = 1;\r
+                       ho->old_addrs = 1;\r
+                       ho->hisaddr = ciaddr1;\r
+                       ho->ouraddr = ciaddr2;\r
+                       break;\r
+#endif\r
+               \r
+               case CI_ADDR:\r
+                       if (!ao->neg_addr) {\r
+                               IPCPDEBUG((LOG_INFO, "ipcp_reqci: Reject ADDR not allowed\n"));\r
+                               orc = CONFREJ;                          /* Reject CI */\r
+                               break;\r
+                       } else if (cilen != CILEN_ADDR) {       /* Check CI length */\r
+                               IPCPDEBUG((LOG_INFO, "ipcp_reqci: Reject ADDR bad len\n"));\r
+                               orc = CONFREJ;                          /* Reject CI */\r
+                               break;\r
+                       }\r
+                       \r
+                       /*\r
+                        * If he has no address, or if we both have his address but\r
+                        * disagree about it, then NAK it with our idea.\r
+                        * In particular, if we don't know his address, but he does,\r
+                        * then accept it.\r
+                        */\r
+                       GETLONG(tl, p); /* Parse source address (his) */\r
+                       ciaddr1 = htonl(tl);\r
+                       if (ciaddr1 != wo->hisaddr\r
+                                       && (ciaddr1 == 0 || !wo->accept_remote)) {\r
+                               orc = CONFNAK;\r
+                               if (!reject_if_disagree) {\r
+                                       DECPTR(sizeof(u32_t), p);\r
+                                       tl = ntohl(wo->hisaddr);\r
+                                       PUTLONG(tl, p);\r
+                               }\r
+                               IPCPDEBUG((LOG_INFO, "ipcp_reqci: Nak ADDR %s\n", inet_ntoa(ciaddr1)));\r
+                       } else if (ciaddr1 == 0 && wo->hisaddr == 0) {\r
+                               /*\r
+                                * Don't ACK an address of 0.0.0.0 - reject it instead.\r
+                                */\r
+                               IPCPDEBUG((LOG_INFO, "ipcp_reqci: Reject ADDR %s\n", inet_ntoa(ciaddr1)));\r
+                               orc = CONFREJ;\r
+                               wo->req_addr = 0;       /* don't NAK with 0.0.0.0 later */\r
+                               break;\r
+                       }\r
+                       \r
+                       ho->neg_addr = 1;\r
+                       ho->hisaddr = ciaddr1;\r
+                       IPCPDEBUG((LOG_INFO, "ipcp_reqci: ADDR %s\n", inet_ntoa(ciaddr1)));\r
+                       break;\r
+               \r
+               case CI_MS_DNS1:\r
+               case CI_MS_DNS2:\r
+                       /* Microsoft primary or secondary DNS request */\r
+                       d = citype == CI_MS_DNS2;\r
+                       \r
+                       /* If we do not have a DNS address then we cannot send it */\r
+                       if (ao->dnsaddr[d] == 0 ||\r
+                                       cilen != CILEN_ADDR) {  /* Check CI length */\r
+                               IPCPDEBUG((LOG_INFO, "ipcp_reqci: Rejecting DNS%d Request\n", d+1));\r
+                               orc = CONFREJ;                          /* Reject CI */\r
+                               break;\r
+                       }\r
+                       GETLONG(tl, p);\r
+                       if (htonl(tl) != ao->dnsaddr[d]) {\r
+                               IPCPDEBUG((LOG_INFO, "ipcp_reqci: Naking DNS%d Request %d\n",\r
+                                                       d+1, inet_ntoa(tl)));\r
+                               DECPTR(sizeof(u32_t), p);\r
+                               tl = ntohl(ao->dnsaddr[d]);\r
+                               PUTLONG(tl, p);\r
+                               orc = CONFNAK;\r
+                       }\r
+                       IPCPDEBUG((LOG_INFO, "ipcp_reqci: received DNS%d Request\n", d+1));\r
+                       break;\r
+               \r
+               case CI_MS_WINS1:\r
+               case CI_MS_WINS2:\r
+                       /* Microsoft primary or secondary WINS request */\r
+                       d = citype == CI_MS_WINS2;\r
+                       IPCPDEBUG((LOG_INFO, "ipcp_reqci: received WINS%d Request\n", d+1));\r
+                       \r
+                       /* If we do not have a DNS address then we cannot send it */\r
+                       if (ao->winsaddr[d] == 0 ||\r
+                               cilen != CILEN_ADDR) {  /* Check CI length */\r
+                               orc = CONFREJ;                  /* Reject CI */\r
+                               break;\r
+                       }\r
+                       GETLONG(tl, p);\r
+                       if (htonl(tl) != ao->winsaddr[d]) {\r
+                               DECPTR(sizeof(u32_t), p);\r
+                               tl = ntohl(ao->winsaddr[d]);\r
+                               PUTLONG(tl, p);\r
+                               orc = CONFNAK;\r
+                       }\r
+                       break;\r
+               \r
+               case CI_COMPRESSTYPE:\r
+                       if (!ao->neg_vj) {\r
+                               IPCPDEBUG((LOG_INFO, "ipcp_reqci: Rejecting COMPRESSTYPE not allowed\n"));\r
+                               orc = CONFREJ;\r
+                               break;\r
+                       } else if (cilen != CILEN_VJ && cilen != CILEN_COMPRESS) {\r
+                               IPCPDEBUG((LOG_INFO, "ipcp_reqci: Rejecting COMPRESSTYPE len=%d\n", cilen));\r
+                               orc = CONFREJ;\r
+                               break;\r
+                       }\r
+                       GETSHORT(cishort, p);\r
+                       \r
+                       if (!(cishort == IPCP_VJ_COMP ||\r
+                                       (cishort == IPCP_VJ_COMP_OLD && cilen == CILEN_COMPRESS))) {\r
+                               IPCPDEBUG((LOG_INFO, "ipcp_reqci: Rejecting COMPRESSTYPE %d\n", cishort));\r
+                               orc = CONFREJ;\r
+                               break;\r
+                       }\r
+                       \r
+                       ho->neg_vj = 1;\r
+                       ho->vj_protocol = cishort;\r
+                       if (cilen == CILEN_VJ) {\r
+                               GETCHAR(maxslotindex, p);\r
+                               if (maxslotindex > ao->maxslotindex) { \r
+                                       IPCPDEBUG((LOG_INFO, "ipcp_reqci: Naking VJ max slot %d\n", maxslotindex));\r
+                                       orc = CONFNAK;\r
+                                       if (!reject_if_disagree){\r
+                                               DECPTR(1, p);\r
+                                               PUTCHAR(ao->maxslotindex, p);\r
+                                       }\r
+                               }\r
+                               GETCHAR(cflag, p);\r
+                               if (cflag && !ao->cflag) {\r
+                                       IPCPDEBUG((LOG_INFO, "ipcp_reqci: Naking VJ cflag %d\n", cflag));\r
+                                       orc = CONFNAK;\r
+                                       if (!reject_if_disagree){\r
+                                               DECPTR(1, p);\r
+                                               PUTCHAR(wo->cflag, p);\r
+                                       }\r
+                               }\r
+                               ho->maxslotindex = maxslotindex;\r
+                               ho->cflag = cflag;\r
+                       } else {\r
+                               ho->old_vj = 1;\r
+                               ho->maxslotindex = MAX_SLOTS - 1;\r
+                               ho->cflag = 1;\r
+                       }\r
+                       IPCPDEBUG((LOG_INFO, \r
+                                               "ipcp_reqci: received COMPRESSTYPE p=%d old=%d maxslot=%d cflag=%d\n",\r
+                                               ho->vj_protocol, ho->old_vj, ho->maxslotindex, ho->cflag));\r
+                       break;\r
+                       \r
+               default:\r
+                       IPCPDEBUG((LOG_INFO, "ipcp_reqci: Rejecting unknown CI type %d\n", citype));\r
+                       orc = CONFREJ;\r
+                       break;\r
+               }\r
+               \r
+endswitch:\r
+               if (orc == CONFACK &&           /* Good CI */\r
+                               rc != CONFACK)          /*  but prior CI wasnt? */\r
+                       continue;                               /* Don't send this one */\r
+               \r
+               if (orc == CONFNAK) {           /* Nak this CI? */\r
+                       if (reject_if_disagree) {       /* Getting fed up with sending NAKs? */\r
+                               IPCPDEBUG((LOG_INFO, "ipcp_reqci: Rejecting too many naks\n"));\r
+                               orc = CONFREJ;          /* Get tough if so */\r
+                       } else {\r
+                               if (rc == CONFREJ)      /* Rejecting prior CI? */\r
+                                       continue;               /* Don't send this one */\r
+                               if (rc == CONFACK) {    /* Ack'd all prior CIs? */\r
+                                       rc = CONFNAK;   /* Not anymore... */\r
+                                       ucp = inp;              /* Backup */\r
+                               }\r
+                       }\r
+               }\r
+               \r
+               if (orc == CONFREJ &&           /* Reject this CI */\r
+                               rc != CONFREJ) {        /*  but no prior ones? */\r
+                       rc = CONFREJ;\r
+                       ucp = inp;                              /* Backup */\r
+               }\r
+               \r
+               /* Need to move CI? */\r
+               if (ucp != cip)\r
+                       BCOPY(cip, ucp, cilen); /* Move it */\r
+               \r
+               /* Update output pointer */\r
+               INCPTR(cilen, ucp);\r
+       }\r
+       \r
+       /*\r
+        * If we aren't rejecting this packet, and we want to negotiate\r
+        * their address, and they didn't send their address, then we\r
+        * send a NAK with a CI_ADDR option appended.  We assume the\r
+        * input buffer is long enough that we can append the extra\r
+        * option safely.\r
+        */\r
+       if (rc != CONFREJ && !ho->neg_addr &&\r
+                       wo->req_addr && !reject_if_disagree) {\r
+               IPCPDEBUG((LOG_INFO, "ipcp_reqci: Requesting peer address\n"));\r
+               if (rc == CONFACK) {\r
+                       rc = CONFNAK;\r
+                       ucp = inp;                              /* reset pointer */\r
+                       wo->req_addr = 0;               /* don't ask again */\r
+               }\r
+               PUTCHAR(CI_ADDR, ucp);\r
+               PUTCHAR(CILEN_ADDR, ucp);\r
+               tl = ntohl(wo->hisaddr);\r
+               PUTLONG(tl, ucp);\r
+       }\r
+       \r
+       *len = (int)(ucp - inp);                /* Compute output length */\r
+       IPCPDEBUG((LOG_INFO, "ipcp_reqci: returning Configure-%s\n", CODENAME(rc)));\r
+       return (rc);                    /* Return final code */\r
+}\r
+\r
+\r
+#if 0\r
+/*\r
+ * ip_check_options - check that any IP-related options are OK,\r
+ * and assign appropriate defaults.\r
+ */\r
+static void ip_check_options(u_long localAddr)\r
+{\r
+       ipcp_options *wo = &ipcp_wantoptions[0];\r
+\r
+       /*\r
+        * Load our default IP address but allow the remote host to give us\r
+        * a new address.\r
+        */\r
+       if (wo->ouraddr == 0 && !ppp_settings.disable_defaultip) {\r
+               wo->accept_local = 1;   /* don't insist on this default value */\r
+               wo->ouraddr = htonl(localAddr);\r
+       }\r
+}\r
+#endif\r
+\r
+\r
+/*\r
+ * ipcp_up - IPCP has come UP.\r
+ *\r
+ * Configure the IP network interface appropriately and bring it up.\r
+ */\r
+static void ipcp_up(fsm *f)\r
+{\r
+       u32_t mask;\r
+       ipcp_options *ho = &ipcp_hisoptions[f->unit];\r
+       ipcp_options *go = &ipcp_gotoptions[f->unit];\r
+       ipcp_options *wo = &ipcp_wantoptions[f->unit];\r
+       \r
+       np_up(f->unit, PPP_IP);\r
+       IPCPDEBUG((LOG_INFO, "ipcp: up\n"));\r
+       \r
+       /*\r
+        * We must have a non-zero IP address for both ends of the link.\r
+        */\r
+       if (!ho->neg_addr)\r
+               ho->hisaddr = wo->hisaddr;\r
+       \r
+       if (ho->hisaddr == 0) {\r
+               IPCPDEBUG((LOG_ERR, "Could not determine remote IP address\n"));\r
+               ipcp_close(f->unit, "Could not determine remote IP address");\r
+               return;\r
+       }\r
+       if (go->ouraddr == 0) {\r
+               IPCPDEBUG((LOG_ERR, "Could not determine local IP address\n"));\r
+               ipcp_close(f->unit, "Could not determine local IP address");\r
+               return;\r
+       }\r
+       \r
+       if (ppp_settings.usepeerdns && (go->dnsaddr[0] || go->dnsaddr[1])) {\r
+               /*pppGotDNSAddrs(go->dnsaddr[0], go->dnsaddr[1]);*/\r
+       }\r
+\r
+       /*\r
+        * Check that the peer is allowed to use the IP address it wants.\r
+        */\r
+       if (!auth_ip_addr(f->unit, ho->hisaddr)) {\r
+               IPCPDEBUG((LOG_ERR, "Peer is not authorized to use remote address %s\n",\r
+                               inet_ntoa(ho->hisaddr)));\r
+               ipcp_close(f->unit, "Unauthorized remote IP address");\r
+               return;\r
+       }\r
+       \r
+       /* set tcp compression */\r
+       sifvjcomp(f->unit, ho->neg_vj, ho->cflag, ho->maxslotindex);\r
+       \r
+       /*\r
+        * Set IP addresses and (if specified) netmask.\r
+        */\r
+       mask = GetMask(go->ouraddr);\r
+       \r
+       if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask, go->dnsaddr[0], go->dnsaddr[1])) {\r
+               IPCPDEBUG((LOG_WARNING, "sifaddr failed\n"));\r
+               ipcp_close(f->unit, "Interface configuration failed");\r
+               return;\r
+       }\r
+       \r
+       /* bring the interface up for IP */\r
+       if (!sifup(f->unit)) {\r
+               IPCPDEBUG((LOG_WARNING, "sifup failed\n"));\r
+               ipcp_close(f->unit, "Interface configuration failed");\r
+               return;\r
+       }\r
+       \r
+       sifnpmode(f->unit, PPP_IP, NPMODE_PASS);\r
+       \r
+       /* assign a default route through the interface if required */\r
+       if (ipcp_wantoptions[f->unit].default_route) \r
+               if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr))\r
+                       default_route_set[f->unit] = 1;\r
+       \r
+       IPCPDEBUG((LOG_NOTICE, "local  IP address %s\n", inet_ntoa(go->ouraddr)));\r
+       IPCPDEBUG((LOG_NOTICE, "remote IP address %s\n", inet_ntoa(ho->hisaddr)));\r
+       if (go->dnsaddr[0]) {\r
+               IPCPDEBUG((LOG_NOTICE, "primary   DNS address %s\n", inet_ntoa(go->dnsaddr[0])));\r
+       }\r
+       if (go->dnsaddr[1]) {\r
+               IPCPDEBUG((LOG_NOTICE, "secondary DNS address %s\n", inet_ntoa(go->dnsaddr[1])));\r
+       }\r
+}\r
+\r
+\r
+/*\r
+ * ipcp_down - IPCP has gone DOWN.\r
+ *\r
+ * Take the IP network interface down, clear its addresses\r
+ * and delete routes through it.\r
+ */\r
+static void ipcp_down(fsm *f)\r
+{\r
+       IPCPDEBUG((LOG_INFO, "ipcp: down\n"));\r
+       np_down(f->unit, PPP_IP);\r
+       sifvjcomp(f->unit, 0, 0, 0);\r
+       \r
+       sifdown(f->unit);\r
+       ipcp_clear_addrs(f->unit);\r
+}\r
+\r
+\r
+/*\r
+ * ipcp_clear_addrs() - clear the interface addresses, routes, etc.\r
+ */\r
+static void ipcp_clear_addrs(int unit)\r
+{\r
+       u32_t ouraddr, hisaddr;\r
+       \r
+       ouraddr = ipcp_gotoptions[unit].ouraddr;\r
+       hisaddr = ipcp_hisoptions[unit].hisaddr;\r
+       if (default_route_set[unit]) {\r
+               cifdefaultroute(unit, ouraddr, hisaddr);\r
+               default_route_set[unit] = 0;\r
+       }\r
+       cifaddr(unit, ouraddr, hisaddr);\r
+}\r
+\r
+\r
+/*\r
+ * ipcp_finished - possibly shut down the lower layers.\r
+ */\r
+static void ipcp_finished(fsm *f)\r
+{\r
+       np_finished(f->unit, PPP_IP);\r
+}\r
+\r
+#if 0\r
+static int ipcp_printpkt(\r
+       u_char *p,\r
+       int plen,\r
+       void (*printer) (void *, char *, ...),\r
+       void *arg\r
+)\r
+{\r
+       (void)p;\r
+       (void)plen;\r
+       (void)printer;\r
+       (void)arg;\r
+       return 0;\r
+}\r
+\r
+/*\r
+ * ip_active_pkt - see if this IP packet is worth bringing the link up for.\r
+ * We don't bring the link up for IP fragments or for TCP FIN packets\r
+ * with no data.\r
+ */\r
+#define IP_HDRLEN      20      /* bytes */\r
+#define IP_OFFMASK     0x1fff\r
+#define IPPROTO_TCP    6\r
+#define TCP_HDRLEN     20\r
+#define TH_FIN         0x01\r
+\r
+/*\r
+ * We use these macros because the IP header may be at an odd address,\r
+ * and some compilers might use word loads to get th_off or ip_hl.\r
+ */\r
+\r
+#define net_short(x)   (((x)[0] << 8) + (x)[1])\r
+#define get_iphl(x)    (((unsigned char *)(x))[0] & 0xF)\r
+#define get_ipoff(x)   net_short((unsigned char *)(x) + 6)\r
+#define get_ipproto(x) (((unsigned char *)(x))[9])\r
+#define get_tcpoff(x)  (((unsigned char *)(x))[12] >> 4)\r
+#define get_tcpflags(x)        (((unsigned char *)(x))[13])\r
+\r
+static int ip_active_pkt(u_char *pkt, int len)\r
+{\r
+       u_char *tcp;\r
+       int hlen;\r
+       \r
+       len -= PPP_HDRLEN;\r
+       pkt += PPP_HDRLEN;\r
+       if (len < IP_HDRLEN)\r
+               return 0;\r
+       if ((get_ipoff(pkt) & IP_OFFMASK) != 0)\r
+               return 0;\r
+       if (get_ipproto(pkt) != IPPROTO_TCP)\r
+               return 1;\r
+       hlen = get_iphl(pkt) * 4;\r
+       if (len < hlen + TCP_HDRLEN)\r
+               return 0;\r
+       tcp = pkt + hlen;\r
+       if ((get_tcpflags(tcp) & TH_FIN) != 0 && len == hlen + get_tcpoff(tcp) * 4)\r
+               return 0;\r
+       return 1;\r
+}\r
+#endif\r
+\r
+#endif /* PPP_SUPPORT */\r
index 416aa79a2e1cd212d90fc8209c19b098de966038..28fc36ed8c20f3431babae0efad64c10b419d5b4 100644 (file)
-/*****************************************************************************
-* ipcp.h -  PPP IP NCP: Internet Protocol Network Control Protocol header file.
-*
-* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
-* portions Copyright (c) 1997 Global Election Systems Inc.
-*
-* The authors hereby grant permission to use, copy, modify, distribute,
-* and license this software and its documentation for any purpose, provided
-* that existing copyright notices are retained in all copies and that this
-* notice and the following disclaimer are included verbatim in any 
-* distributions. No written agreement, license, or royalty fee is required
-* for any of the authorized uses.
-*
-* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *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 CONTRIBUTORS 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.
-*
-******************************************************************************
-* REVISION HISTORY
-*
-* 03-01-01 Marc Boucher <marc@mbsi.ca>
-*   Ported to lwIP.
-* 97-12-04 Guy Lancaster <glanca@gesn.com>, Global Election Systems Inc.
-*      Original derived from BSD codes.
-*****************************************************************************/
-/*
- * ipcp.h - IP Control Protocol definitions.
- *
- * Copyright (c) 1989 Carnegie Mellon University.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by Carnegie Mellon University.  The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * $Id: ipcp.h,v 1.1 2003/05/27 14:37:56 jani Exp $
- */
-
-#ifndef IPCP_H
-#define IPCP_H
-
-/*************************
-*** PUBLIC DEFINITIONS ***
-*************************/
-/*
- * Options.
- */
-#define CI_ADDRS       1                       /* IP Addresses */
-#define CI_COMPRESSTYPE        2               /* Compression Type */
-#define        CI_ADDR         3
-
-#define CI_MS_WINS1    128                     /* Primary WINS value */
-#define CI_MS_DNS1     129                     /* Primary DNS value */
-#define CI_MS_WINS2    130                     /* Secondary WINS value */
-#define CI_MS_DNS2     131                     /* Secondary DNS value */
-
-#define IPCP_VJMODE_OLD 1              /* "old" mode (option # = 0x0037) */
-#define IPCP_VJMODE_RFC1172 2  /* "old-rfc"mode (option # = 0x002d) */
-#define IPCP_VJMODE_RFC1332 3  /* "new-rfc"mode (option # = 0x002d, */
-                                /*  maxslot and slot number compression) */
-
-#define IPCP_VJ_COMP 0x002d            /* current value for VJ compression option*/
-#define IPCP_VJ_COMP_OLD 0x0037        /* "old" (i.e, broken) value for VJ */
-                                                               /* compression option*/ 
-
-
-/************************
-*** PUBLIC DATA TYPES ***
-************************/
-
-typedef struct ipcp_options {
-    u_int neg_addr : 1;                        /* Negotiate IP Address? */
-    u_int old_addrs : 1;                       /* Use old (IP-Addresses) option? */
-    u_int req_addr : 1;                        /* Ask peer to send IP address? */
-    u_int default_route : 1;           /* Assign default route through interface? */
-    u_int proxy_arp : 1;                       /* Make proxy ARP entry for peer? */
-    u_int neg_vj : 1;                          /* Van Jacobson Compression? */
-    u_int old_vj : 1;                          /* use old (short) form of VJ option? */
-    u_int accept_local : 1;            /* accept peer's value for ouraddr */
-    u_int accept_remote : 1;           /* accept peer's value for hisaddr */
-    u_int req_dns1 : 1;                        /* Ask peer to send primary DNS address? */
-    u_int req_dns2 : 1;                        /* Ask peer to send secondary DNS address? */
-    u_short vj_protocol;               /* protocol value to use in VJ option */
-    u_char maxslotindex;               /* VJ slots - 1. */
-    u_char cflag;                              /* VJ slot compression flag. */
-    u32_t ouraddr, hisaddr;    /* Addresses in NETWORK BYTE ORDER */
-    u32_t dnsaddr[2];          /* Primary and secondary MS DNS entries */
-    u32_t winsaddr[2];         /* Primary and secondary MS WINS entries */
-} ipcp_options;
-
-
-/*****************************
-*** PUBLIC DATA STRUCTURES ***
-*****************************/
-
-extern fsm ipcp_fsm[];
-extern ipcp_options ipcp_wantoptions[];
-extern ipcp_options ipcp_gotoptions[];
-extern ipcp_options ipcp_allowoptions[];
-extern ipcp_options ipcp_hisoptions[];
-
-extern struct protent ipcp_protent;
-
-
-/***********************
-*** PUBLIC FUNCTIONS ***
-***********************/
-
-
-#endif /* IPCP_H */
-
+/*****************************************************************************\r
+* ipcp.h -  PPP IP NCP: Internet Protocol Network Control Protocol header file.\r
+*\r
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.\r
+* portions Copyright (c) 1997 Global Election Systems Inc.\r
+*\r
+* The authors hereby grant permission to use, copy, modify, distribute,\r
+* and license this software and its documentation for any purpose, provided\r
+* that existing copyright notices are retained in all copies and that this\r
+* notice and the following disclaimer are included verbatim in any \r
+* distributions. No written agreement, license, or royalty fee is required\r
+* for any of the authorized uses.\r
+*\r
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR\r
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+*\r
+******************************************************************************\r
+* REVISION HISTORY\r
+*\r
+* 03-01-01 Marc Boucher <marc@mbsi.ca>\r
+*   Ported to lwIP.\r
+* 97-12-04 Guy Lancaster <glanca@gesn.com>, Global Election Systems Inc.\r
+*      Original derived from BSD codes.\r
+*****************************************************************************/\r
+/*\r
+ * ipcp.h - IP Control Protocol definitions.\r
+ *\r
+ * Copyright (c) 1989 Carnegie Mellon University.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms are permitted\r
+ * provided that the above copyright notice and this paragraph are\r
+ * duplicated in all such forms and that any documentation,\r
+ * advertising materials, and other materials related to such\r
+ * distribution and use acknowledge that the software was developed\r
+ * by Carnegie Mellon University.  The name of the\r
+ * University may not be used to endorse or promote products derived\r
+ * from this software without specific prior written permission.\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR\r
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r
+ *\r
+ * $Id: ipcp.h,v 1.1 2003/05/27 14:37:56 jani Exp $\r
+ */\r
+\r
+#ifndef IPCP_H\r
+#define IPCP_H\r
+\r
+/*************************\r
+*** PUBLIC DEFINITIONS ***\r
+*************************/\r
+/*\r
+ * Options.\r
+ */\r
+#define CI_ADDRS       1                       /* IP Addresses */\r
+#define CI_COMPRESSTYPE        2               /* Compression Type */\r
+#define        CI_ADDR         3\r
+\r
+#define CI_MS_WINS1    128                     /* Primary WINS value */\r
+#define CI_MS_DNS1     129                     /* Primary DNS value */\r
+#define CI_MS_WINS2    130                     /* Secondary WINS value */\r
+#define CI_MS_DNS2     131                     /* Secondary DNS value */\r
+\r
+#define IPCP_VJMODE_OLD 1              /* "old" mode (option # = 0x0037) */\r
+#define IPCP_VJMODE_RFC1172 2  /* "old-rfc"mode (option # = 0x002d) */\r
+#define IPCP_VJMODE_RFC1332 3  /* "new-rfc"mode (option # = 0x002d, */\r
+                                /*  maxslot and slot number compression) */\r
+\r
+#define IPCP_VJ_COMP 0x002d            /* current value for VJ compression option*/\r
+#define IPCP_VJ_COMP_OLD 0x0037        /* "old" (i.e, broken) value for VJ */\r
+                                                               /* compression option*/ \r
+\r
+\r
+/************************\r
+*** PUBLIC DATA TYPES ***\r
+************************/\r
+\r
+typedef struct ipcp_options {\r
+    u_int neg_addr : 1;                        /* Negotiate IP Address? */\r
+    u_int old_addrs : 1;                       /* Use old (IP-Addresses) option? */\r
+    u_int req_addr : 1;                        /* Ask peer to send IP address? */\r
+    u_int default_route : 1;           /* Assign default route through interface? */\r
+    u_int proxy_arp : 1;                       /* Make proxy ARP entry for peer? */\r
+    u_int neg_vj : 1;                          /* Van Jacobson Compression? */\r
+    u_int old_vj : 1;                          /* use old (short) form of VJ option? */\r
+    u_int accept_local : 1;            /* accept peer's value for ouraddr */\r
+    u_int accept_remote : 1;           /* accept peer's value for hisaddr */\r
+    u_int req_dns1 : 1;                        /* Ask peer to send primary DNS address? */\r
+    u_int req_dns2 : 1;                        /* Ask peer to send secondary DNS address? */\r
+    u_short vj_protocol;               /* protocol value to use in VJ option */\r
+    u_char maxslotindex;               /* VJ slots - 1. */\r
+    u_char cflag;                              /* VJ slot compression flag. */\r
+    u32_t ouraddr, hisaddr;    /* Addresses in NETWORK BYTE ORDER */\r
+    u32_t dnsaddr[2];          /* Primary and secondary MS DNS entries */\r
+    u32_t winsaddr[2];         /* Primary and secondary MS WINS entries */\r
+} ipcp_options;\r
+\r
+\r
+/*****************************\r
+*** PUBLIC DATA STRUCTURES ***\r
+*****************************/\r
+\r
+extern fsm ipcp_fsm[];\r
+extern ipcp_options ipcp_wantoptions[];\r
+extern ipcp_options ipcp_gotoptions[];\r
+extern ipcp_options ipcp_allowoptions[];\r
+extern ipcp_options ipcp_hisoptions[];\r
+\r
+extern struct protent ipcp_protent;\r
+\r
+\r
+/***********************\r
+*** PUBLIC FUNCTIONS ***\r
+***********************/\r
+\r
+\r
+#endif /* IPCP_H */\r
+\r
index e974a2d443ad38aa09dd7ce3297051386e0a8bf9..22ba078a3f806bc0276180be10e073362e14faad 100644 (file)
-/*****************************************************************************
-* lcp.c - Network Link Control Protocol program file.
-*
-* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
-* portions Copyright (c) 1997 by Global Election Systems Inc.
-*
-* The authors hereby grant permission to use, copy, modify, distribute,
-* and license this software and its documentation for any purpose, provided
-* that existing copyright notices are retained in all copies and that this
-* notice and the following disclaimer are included verbatim in any 
-* distributions. No written agreement, license, or royalty fee is required
-* for any of the authorized uses.
-*
-* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *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 CONTRIBUTORS 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.
-*
-******************************************************************************
-* REVISION HISTORY
-*
-* 03-01-01 Marc Boucher <marc@mbsi.ca>
-*   Ported to lwIP.
-* 97-12-01 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
-*      Original.
-*****************************************************************************/
-
-/*
- * lcp.c - PPP Link Control Protocol.
- *
- * Copyright (c) 1989 Carnegie Mellon University.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by Carnegie Mellon University.  The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-#include <string.h>
-#include "ppp.h"
-#if PPP_SUPPORT > 0
-#include "fsm.h"
-#include "chap.h"
-#include "magic.h"
-#include "auth.h"
-#include "lcp.h"
-#include "pppdebug.h"
-
-
-/*************************/
-/*** LOCAL DEFINITIONS ***/
-/*************************/
-/*
- * Length of each type of configuration option (in octets)
- */
-#define CILEN_VOID     2
-#define CILEN_CHAR     3
-#define CILEN_SHORT    4       /* CILEN_VOID + sizeof(short) */
-#define CILEN_CHAP     5       /* CILEN_VOID + sizeof(short) + 1 */
-#define CILEN_LONG     6       /* CILEN_VOID + sizeof(long) */
-#define CILEN_LQR      8       /* CILEN_VOID + sizeof(short) + sizeof(long) */
-#define CILEN_CBCP     3
-
-
-/***********************************/
-/*** LOCAL FUNCTION DECLARATIONS ***/
-/***********************************/
-/*
- * Callbacks for fsm code.  (CI = Configuration Information)
- */
-static void lcp_resetci (fsm*);                /* Reset our CI */
-static int  lcp_cilen (fsm*);                  /* Return length of our CI */
-static void lcp_addci (fsm*, u_char*, int*);       /* Add our CI to pkt */
-static int  lcp_ackci (fsm*, u_char*, int);/* Peer ack'd our CI */
-static int  lcp_nakci (fsm*, u_char*, int);/* Peer nak'd our CI */
-static int  lcp_rejci (fsm*, u_char*, int);/* Peer rej'd our CI */
-static int  lcp_reqci (fsm*, u_char*, int*, int);  /* Rcv peer CI */
-static void lcp_up (fsm*);                         /* We're UP */
-static void lcp_down (fsm*);               /* We're DOWN */
-static void lcp_starting (fsm*);           /* We need lower layer up */
-static void lcp_finished (fsm*);               /* We need lower layer down */
-static int  lcp_extcode (fsm*, int, u_char, u_char*, int);
-
-static void lcp_rprotrej (fsm*, u_char*, int);
-
-/*
- * routines to send LCP echos to peer
- */
-static void lcp_echo_lowerup (int);
-static void lcp_echo_lowerdown (int);
-static void LcpEchoTimeout (void*);
-static void lcp_received_echo_reply (fsm*, int, u_char*, int);
-static void LcpSendEchoRequest (fsm*);
-static void LcpLinkFailure (fsm*);
-static void LcpEchoCheck (fsm*);
-
-/*
- * Protocol entry points.
- * Some of these are called directly.
- */
-static void lcp_input (int, u_char *, int);
-static void lcp_protrej (int);
-
-#define CODENAME(x)    ((x) == CONFACK ? "ACK" : \
-                        (x) == CONFNAK ? "NAK" : "REJ")
-
-
-/******************************/
-/*** PUBLIC DATA STRUCTURES ***/
-/******************************/
-/* global vars */
-LinkPhase lcp_phase[NUM_PPP];                  /* Phase of link session (RFC 1661) */
-lcp_options lcp_wantoptions[NUM_PPP];  /* Options that we want to request */
-lcp_options lcp_gotoptions[NUM_PPP];   /* Options that peer ack'd */
-lcp_options lcp_allowoptions[NUM_PPP]; /* Options we allow peer to request */
-lcp_options lcp_hisoptions[NUM_PPP];   /* Options that we ack'd */
-ext_accm xmit_accm[NUM_PPP];                   /* extended transmit ACCM */
-
-
-
-/*****************************/
-/*** LOCAL DATA STRUCTURES ***/
-/*****************************/
-static fsm lcp_fsm[NUM_PPP];                   /* LCP fsm structure (global)*/
-static u_int    lcp_echo_interval = LCP_ECHOINTERVAL; /* Interval between LCP echo-requests */
-static u_int    lcp_echo_fails = LCP_MAXECHOFAILS; /* Tolerance to unanswered echo-requests */
-static u32_t lcp_echos_pending = 0;    /* Number of outstanding echo msgs */
-static u32_t lcp_echo_number   = 0;    /* ID number of next echo frame */
-static u32_t lcp_echo_timer_running = 0;  /* TRUE if a timer is running */
-
-static u_char nak_buffer[PPP_MRU];     /* where we construct a nak packet */
-
-static fsm_callbacks lcp_callbacks = { /* LCP callback routines */
-    lcp_resetci,               /* Reset our Configuration Information */
-    lcp_cilen,                 /* Length of our Configuration Information */
-    lcp_addci,                 /* Add our Configuration Information */
-    lcp_ackci,                 /* ACK our Configuration Information */
-    lcp_nakci,                 /* NAK our Configuration Information */
-    lcp_rejci,                 /* Reject our Configuration Information */
-    lcp_reqci,                 /* Request peer's Configuration Information */
-    lcp_up,                            /* Called when fsm reaches OPENED state */
-    lcp_down,                  /* Called when fsm leaves OPENED state */
-    lcp_starting,              /* Called when we want the lower layer up */
-    lcp_finished,              /* Called when we want the lower layer down */
-    NULL,                              /* Called when Protocol-Reject received */
-    NULL,                              /* Retransmission is necessary */
-    lcp_extcode,               /* Called to handle LCP-specific codes */
-    "LCP"                              /* String name of protocol */
-};
-
-struct protent lcp_protent = {
-    PPP_LCP,
-    lcp_init,
-    lcp_input,
-    lcp_protrej,
-    lcp_lowerup,
-    lcp_lowerdown,
-    lcp_open,
-    lcp_close,
-#if 0
-    lcp_printpkt,
-    NULL,
-#endif
-    1,
-    "LCP",
-#if 0
-    NULL,
-    NULL,
-    NULL
-#endif
-};
-
-int lcp_loopbackfail = DEFLOOPBACKFAIL;
-
-
-
-/***********************************/
-/*** PUBLIC FUNCTION DEFINITIONS ***/
-/***********************************/
-/*
- * lcp_init - Initialize LCP.
- */
-void lcp_init(int unit)
-{
-       fsm *f = &lcp_fsm[unit];
-       lcp_options *wo = &lcp_wantoptions[unit];
-       lcp_options *ao = &lcp_allowoptions[unit];
-       
-       f->unit = unit;
-       f->protocol = PPP_LCP;
-       f->callbacks = &lcp_callbacks;
-       
-       fsm_init(f);
-       
-       wo->passive = 0;
-       wo->silent = 0;
-       wo->restart = 0;                        /* Set to 1 in kernels or multi-line
-                                                                * implementations */
-       wo->neg_mru = 1;
-       wo->mru = PPP_DEFMRU;
-       wo->neg_asyncmap = 1;
-       wo->asyncmap = 0x00000000l;     /* Assume don't need to escape any ctl chars. */
-       wo->neg_chap = 0;                       /* Set to 1 on server */
-       wo->neg_upap = 0;                       /* Set to 1 on server */
-       wo->chap_mdtype = CHAP_DIGEST_MD5;
-       wo->neg_magicnumber = 1;
-       wo->neg_pcompression = 1;
-       wo->neg_accompression = 1;
-       wo->neg_lqr = 0;                        /* no LQR implementation yet */
-       wo->neg_cbcp = 0;
-       
-       ao->neg_mru = 1;
-       ao->mru = PPP_MAXMRU;
-       ao->neg_asyncmap = 1;
-       ao->asyncmap = 0x00000000l;     /* Assume don't need to escape any ctl chars. */
-       ao->neg_chap = (CHAP_SUPPORT != 0);
-       ao->chap_mdtype = CHAP_DIGEST_MD5;
-       ao->neg_upap = (PAP_SUPPORT != 0);
-       ao->neg_magicnumber = 1;
-       ao->neg_pcompression = 1;
-       ao->neg_accompression = 1;
-       ao->neg_lqr = 0;                        /* no LQR implementation yet */
-       ao->neg_cbcp = (CBCP_SUPPORT != 0);
-
-       /* 
-        * Set transmit escape for the flag and escape characters plus anything
-        * set for the allowable options.
-        */
-       memset(xmit_accm[unit], 0, sizeof(xmit_accm[0]));
-       xmit_accm[unit][15] = 0x60;
-       xmit_accm[unit][0] = (u_char)(ao->asyncmap & 0xFF);
-       xmit_accm[unit][1] = (u_char)((ao->asyncmap >> 8) & 0xFF);
-       xmit_accm[unit][2] = (u_char)((ao->asyncmap >> 16) & 0xFF);
-       xmit_accm[unit][3] = (u_char)((ao->asyncmap >> 24) & 0xFF);
-       LCPDEBUG((LOG_INFO, "lcp_init: xmit_accm=%X %X %X %X\n",
-                               xmit_accm[unit][0],
-                               xmit_accm[unit][1],
-                               xmit_accm[unit][2],
-                               xmit_accm[unit][3]));
-       
-       lcp_phase[unit] = PHASE_INITIALIZE;
-}
-
-
-/*
- * lcp_open - LCP is allowed to come up.
- */
-void lcp_open(int unit)
-{
-       fsm *f = &lcp_fsm[unit];
-       lcp_options *wo = &lcp_wantoptions[unit];
-       
-       f->flags = 0;
-       if (wo->passive)
-               f->flags |= OPT_PASSIVE;
-       if (wo->silent)
-               f->flags |= OPT_SILENT;
-       fsm_open(f);
-       
-       lcp_phase[unit] = PHASE_ESTABLISH; 
-}
-
-
-/*
- * lcp_close - Take LCP down.
- */
-void lcp_close(int unit, char *reason)
-{
-       fsm *f = &lcp_fsm[unit];
-       
-       if (lcp_phase[unit] != PHASE_DEAD)
-               lcp_phase[unit] = PHASE_TERMINATE;
-       if (f->state == STOPPED && f->flags & (OPT_PASSIVE|OPT_SILENT)) {
-               /*
-                * This action is not strictly according to the FSM in RFC1548,
-                * but it does mean that the program terminates if you do an
-                * lcp_close() in passive/silent mode when a connection hasn't
-                * been established.
-                */
-               f->state = CLOSED;
-               lcp_finished(f);
-       }
-       else
-               fsm_close(&lcp_fsm[unit], reason);
-}
-
-
-/*
- * lcp_lowerup - The lower layer is up.
- */
-void lcp_lowerup(int unit)
-{
-       lcp_options *wo = &lcp_wantoptions[unit];
-       
-       /*
-       * Don't use A/C or protocol compression on transmission,
-       * but accept A/C and protocol compressed packets
-       * if we are going to ask for A/C and protocol compression.
-       */
-       ppp_set_xaccm(unit, &xmit_accm[unit]);
-       ppp_send_config(unit, PPP_MRU, 0xffffffffl, 0, 0);
-       ppp_recv_config(unit, PPP_MRU, 0x00000000l,
-                                       wo->neg_pcompression, wo->neg_accompression);
-       peer_mru[unit] = PPP_MRU;
-       lcp_allowoptions[unit].asyncmap 
-               = (u_long)xmit_accm[unit][0]
-                       | ((u_long)xmit_accm[unit][1] << 8)
-                       | ((u_long)xmit_accm[unit][2] << 16)
-                       | ((u_long)xmit_accm[unit][3] << 24);
-       LCPDEBUG((LOG_INFO, "lcp_lowerup: asyncmap=%X %X %X %X\n",
-                               xmit_accm[unit][3],
-                               xmit_accm[unit][2],
-                               xmit_accm[unit][1],
-                               xmit_accm[unit][0]));
-       
-       fsm_lowerup(&lcp_fsm[unit]);
-}
-
-
-/*
- * lcp_lowerdown - The lower layer is down.
- */
-void lcp_lowerdown(int unit)
-{
-       fsm_lowerdown(&lcp_fsm[unit]);
-}
-
-/*
- * lcp_sprotrej - Send a Protocol-Reject for some protocol.
- */
-void lcp_sprotrej(int unit, u_char *p, int len)
-{
-       /*
-       * Send back the protocol and the information field of the
-       * rejected packet.  We only get here if LCP is in the OPENED state.
-       */
-
-       fsm_sdata(&lcp_fsm[unit], PROTREJ, ++lcp_fsm[unit].id,
-                               p, len);
-}
-
-
-
-/**********************************/
-/*** LOCAL FUNCTION DEFINITIONS ***/
-/**********************************/
-/*
- * lcp_input - Input LCP packet.
- */
-static void lcp_input(int unit, u_char *p, int len)
-{
-       fsm *f = &lcp_fsm[unit];
-       
-       fsm_input(f, p, len);
-}
-
-
-/*
- * lcp_extcode - Handle a LCP-specific code.
- */
-static int lcp_extcode(fsm *f, int code, u_char id, u_char *inp, int len)
-{
-       u_char *magp;
-       
-       switch( code ){
-       case PROTREJ:
-               lcp_rprotrej(f, inp, len);
-               break;
-       
-       case ECHOREQ:
-               if (f->state != OPENED)
-                       break;
-               LCPDEBUG((LOG_INFO, "lcp: Echo-Request, Rcvd id %d\n", id));
-               magp = inp;
-               PUTLONG(lcp_gotoptions[f->unit].magicnumber, magp);
-               fsm_sdata(f, ECHOREP, id, inp, len);
-               break;
-       
-       case ECHOREP:
-               lcp_received_echo_reply(f, id, inp, len);
-               break;
-       
-       case DISCREQ:
-               break;
-       
-       default:
-               return 0;
-       }
-       return 1;
-}
-
-    
-/*
- * lcp_rprotrej - Receive an Protocol-Reject.
- *
- * Figure out which protocol is rejected and inform it.
- */
-static void lcp_rprotrej(fsm *f, u_char *inp, int len)
-{
-       int i;
-       struct protent *protp;
-       u_short prot;
-       
-       if (len < sizeof (u_short)) {
-               LCPDEBUG((LOG_INFO,
-                               "lcp_rprotrej: Rcvd short Protocol-Reject packet!\n"));
-               return;
-       }
-       
-       GETSHORT(prot, inp);
-       
-       LCPDEBUG((LOG_INFO,
-                       "lcp_rprotrej: Rcvd Protocol-Reject packet for %x!\n",
-                       prot));
-       
-       /*
-       * Protocol-Reject packets received in any state other than the LCP
-       * OPENED state SHOULD be silently discarded.
-       */
-       if( f->state != OPENED ){
-               LCPDEBUG((LOG_INFO, "Protocol-Reject discarded: LCP in state %d\n",
-                               f->state));
-               return;
-       }
-       
-       /*
-       * Upcall the proper Protocol-Reject routine.
-       */
-       for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i)
-               if (protp->protocol == prot && protp->enabled_flag) {
-                       (*protp->protrej)(f->unit);
-                       return;
-               }
-       
-       LCPDEBUG((LOG_WARNING, "Protocol-Reject for unsupported protocol 0x%x\n",
-                       prot));
-}
-
-
-/*
- * lcp_protrej - A Protocol-Reject was received.
- */
-static void lcp_protrej(int unit)
-{
-       (void)unit;
-       /*
-       * Can't reject LCP!
-       */
-       LCPDEBUG((LOG_WARNING,
-                       "lcp_protrej: Received Protocol-Reject for LCP!\n"));
-       fsm_protreject(&lcp_fsm[unit]);
-}
-
-
-/*
- * lcp_resetci - Reset our CI.
- */
-static void lcp_resetci(fsm *f)
-{
-       lcp_wantoptions[f->unit].magicnumber = magic();
-       lcp_wantoptions[f->unit].numloops = 0;
-       lcp_gotoptions[f->unit] = lcp_wantoptions[f->unit];
-       peer_mru[f->unit] = PPP_MRU;
-       auth_reset(f->unit);
-}
-
-
-/*
- * lcp_cilen - Return length of our CI.
- */
-static int lcp_cilen(fsm *f)
-{
-       lcp_options *go = &lcp_gotoptions[f->unit];
-
-#define LENCIVOID(neg) ((neg) ? CILEN_VOID : 0)
-#define LENCICHAP(neg) ((neg) ? CILEN_CHAP : 0)
-#define LENCISHORT(neg)        ((neg) ? CILEN_SHORT : 0)
-#define LENCILONG(neg) ((neg) ? CILEN_LONG : 0)
-#define LENCILQR(neg)  ((neg) ? CILEN_LQR: 0)
-#define LENCICBCP(neg) ((neg) ? CILEN_CBCP: 0)
-       /*
-       * NB: we only ask for one of CHAP and UPAP, even if we will
-       * accept either.
-       */
-       return (LENCISHORT(go->neg_mru && go->mru != PPP_DEFMRU) +
-               LENCILONG(go->neg_asyncmap && go->asyncmap != 0xFFFFFFFFl) +
-               LENCICHAP(go->neg_chap) +
-               LENCISHORT(!go->neg_chap && go->neg_upap) +
-               LENCILQR(go->neg_lqr) +
-               LENCICBCP(go->neg_cbcp) +
-               LENCILONG(go->neg_magicnumber) +
-               LENCIVOID(go->neg_pcompression) +
-               LENCIVOID(go->neg_accompression));
-}
-
-
-/*
- * lcp_addci - Add our desired CIs to a packet.
- */
-static void lcp_addci(fsm *f, u_char *ucp, int *lenp)
-{
-       lcp_options *go = &lcp_gotoptions[f->unit];
-       u_char *start_ucp = ucp;
-       
-#define ADDCIVOID(opt, neg) \
-       if (neg) { \
-           LCPDEBUG((LOG_INFO, "lcp_addci: opt=%d\n", opt)); \
-               PUTCHAR(opt, ucp); \
-               PUTCHAR(CILEN_VOID, ucp); \
-       }
-#define ADDCISHORT(opt, neg, val) \
-       if (neg) { \
-           LCPDEBUG((LOG_INFO, "lcp_addci: INT opt=%d %X\n", opt, val)); \
-               PUTCHAR(opt, ucp); \
-               PUTCHAR(CILEN_SHORT, ucp); \
-               PUTSHORT(val, ucp); \
-       }
-#define ADDCICHAP(opt, neg, val, digest) \
-       if (neg) { \
-           LCPDEBUG((LOG_INFO, "lcp_addci: CHAP opt=%d %X\n", opt, val)); \
-               PUTCHAR(opt, ucp); \
-               PUTCHAR(CILEN_CHAP, ucp); \
-               PUTSHORT(val, ucp); \
-               PUTCHAR(digest, ucp); \
-       }
-#define ADDCILONG(opt, neg, val) \
-       if (neg) { \
-           LCPDEBUG((LOG_INFO, "lcp_addci: L opt=%d %lX\n", opt, val)); \
-               PUTCHAR(opt, ucp); \
-               PUTCHAR(CILEN_LONG, ucp); \
-               PUTLONG(val, ucp); \
-       }
-#define ADDCILQR(opt, neg, val) \
-       if (neg) { \
-           LCPDEBUG((LOG_INFO, "lcp_addci: LQR opt=%d %lX\n", opt, val)); \
-               PUTCHAR(opt, ucp); \
-               PUTCHAR(CILEN_LQR, ucp); \
-               PUTSHORT(PPP_LQR, ucp); \
-               PUTLONG(val, ucp); \
-       }
-#define ADDCICHAR(opt, neg, val) \
-       if (neg) { \
-           LCPDEBUG((LOG_INFO, "lcp_addci: CHAR opt=%d %X '%z'\n", opt, val, val)); \
-               PUTCHAR(opt, ucp); \
-               PUTCHAR(CILEN_CHAR, ucp); \
-               PUTCHAR(val, ucp); \
-       }
-       
-       ADDCISHORT(CI_MRU, go->neg_mru && go->mru != PPP_DEFMRU, go->mru);
-       ADDCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFFl,
-                       go->asyncmap);
-       ADDCICHAP(CI_AUTHTYPE, go->neg_chap, PPP_CHAP, go->chap_mdtype);
-       ADDCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, PPP_PAP);
-       ADDCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period);
-       ADDCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT);
-       ADDCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber);
-       ADDCIVOID(CI_PCOMPRESSION, go->neg_pcompression);
-       ADDCIVOID(CI_ACCOMPRESSION, go->neg_accompression);
-       
-       if (ucp - start_ucp != *lenp) {
-               /* this should never happen, because peer_mtu should be 1500 */
-               LCPDEBUG((LOG_ERR, "Bug in lcp_addci: wrong length\n"));
-       }
-}
-
-
-/*
- * lcp_ackci - Ack our CIs.
- * This should not modify any state if the Ack is bad.
- *
- * Returns:
- *     0 - Ack was bad.
- *     1 - Ack was good.
- */
-static int lcp_ackci(fsm *f, u_char *p, int len)
-{
-       lcp_options *go = &lcp_gotoptions[f->unit];
-       u_char cilen, citype, cichar;
-       u_short cishort;
-       u32_t cilong;
-       
-       /*
-       * CIs must be in exactly the same order that we sent.
-       * Check packet length and CI length at each step.
-       * If we find any deviations, then this packet is bad.
-       */
-#define ACKCIVOID(opt, neg) \
-       if (neg) { \
-               if ((len -= CILEN_VOID) < 0) \
-                       goto bad; \
-               GETCHAR(citype, p); \
-               GETCHAR(cilen, p); \
-               if (cilen != CILEN_VOID || \
-                               citype != opt) \
-                       goto bad; \
-       }
-#define ACKCISHORT(opt, neg, val) \
-       if (neg) { \
-               if ((len -= CILEN_SHORT) < 0) \
-                       goto bad; \
-               GETCHAR(citype, p); \
-               GETCHAR(cilen, p); \
-               if (cilen != CILEN_SHORT || \
-                               citype != opt) \
-                       goto bad; \
-               GETSHORT(cishort, p); \
-               if (cishort != val) \
-                       goto bad; \
-       }
-#define ACKCICHAR(opt, neg, val) \
-       if (neg) { \
-               if ((len -= CILEN_CHAR) < 0) \
-                       goto bad; \
-               GETCHAR(citype, p); \
-               GETCHAR(cilen, p); \
-               if (cilen != CILEN_CHAR || \
-                               citype != opt) \
-                       goto bad; \
-               GETCHAR(cichar, p); \
-               if (cichar != val) \
-                       goto bad; \
-       }
-#define ACKCICHAP(opt, neg, val, digest) \
-       if (neg) { \
-               if ((len -= CILEN_CHAP) < 0) \
-                       goto bad; \
-               GETCHAR(citype, p); \
-               GETCHAR(cilen, p); \
-               if (cilen != CILEN_CHAP || \
-                               citype != opt) \
-                       goto bad; \
-               GETSHORT(cishort, p); \
-               if (cishort != val) \
-                       goto bad; \
-               GETCHAR(cichar, p); \
-               if (cichar != digest) \
-                       goto bad; \
-       }
-#define ACKCILONG(opt, neg, val) \
-       if (neg) { \
-               if ((len -= CILEN_LONG) < 0) \
-                       goto bad; \
-               GETCHAR(citype, p); \
-               GETCHAR(cilen, p); \
-               if (cilen != CILEN_LONG || \
-                               citype != opt) \
-                       goto bad; \
-               GETLONG(cilong, p); \
-               if (cilong != val) \
-                       goto bad; \
-       }
-#define ACKCILQR(opt, neg, val) \
-       if (neg) { \
-               if ((len -= CILEN_LQR) < 0) \
-                       goto bad; \
-               GETCHAR(citype, p); \
-               GETCHAR(cilen, p); \
-               if (cilen != CILEN_LQR || \
-                               citype != opt) \
-                       goto bad; \
-               GETSHORT(cishort, p); \
-               if (cishort != PPP_LQR) \
-                       goto bad; \
-               GETLONG(cilong, p); \
-               if (cilong != val) \
-                       goto bad; \
-       }
-       
-       ACKCISHORT(CI_MRU, go->neg_mru && go->mru != PPP_DEFMRU, go->mru);
-       ACKCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFFl,
-                       go->asyncmap);
-       ACKCICHAP(CI_AUTHTYPE, go->neg_chap, PPP_CHAP, go->chap_mdtype);
-       ACKCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, PPP_PAP);
-       ACKCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period);
-       ACKCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT);
-       ACKCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber);
-       ACKCIVOID(CI_PCOMPRESSION, go->neg_pcompression);
-       ACKCIVOID(CI_ACCOMPRESSION, go->neg_accompression);
-       
-       /*
-        * If there are any remaining CIs, then this packet is bad.
-        */
-       if (len != 0)
-               goto bad;
-       LCPDEBUG((LOG_INFO, "lcp_acki: Ack\n"));
-       return (1);
-bad:
-       LCPDEBUG((LOG_WARNING, "lcp_acki: received bad Ack!\n"));
-       return (0);
-}
-
-
-/*
- * lcp_nakci - Peer has sent a NAK for some of our CIs.
- * This should not modify any state if the Nak is bad
- * or if LCP is in the OPENED state.
- *
- * Returns:
- *     0 - Nak was bad.
- *     1 - Nak was good.
- */
-static int lcp_nakci(fsm *f, u_char *p, int len)
-{
-       lcp_options *go = &lcp_gotoptions[f->unit];
-       lcp_options *wo = &lcp_wantoptions[f->unit];
-       u_char citype, cichar, *next;
-       u_short cishort;
-       u32_t cilong;
-       lcp_options no;         /* options we've seen Naks for */
-       lcp_options try;                /* options to request next time */
-       int looped_back = 0;
-       int cilen;
-       
-       BZERO(&no, sizeof(no));
-       try = *go;
-       
-       /*
-       * Any Nak'd CIs must be in exactly the same order that we sent.
-       * Check packet length and CI length at each step.
-       * If we find any deviations, then this packet is bad.
-       */
-#define NAKCIVOID(opt, neg, code) \
-       if (go->neg && \
-                       len >= CILEN_VOID && \
-                       p[1] == CILEN_VOID && \
-                       p[0] == opt) { \
-               len -= CILEN_VOID; \
-               INCPTR(CILEN_VOID, p); \
-               no.neg = 1; \
-               code \
-       }
-#define NAKCICHAP(opt, neg, code) \
-       if (go->neg && \
-                       len >= CILEN_CHAP && \
-                       p[1] == CILEN_CHAP && \
-                       p[0] == opt) { \
-               len -= CILEN_CHAP; \
-               INCPTR(2, p); \
-               GETSHORT(cishort, p); \
-               GETCHAR(cichar, p); \
-               no.neg = 1; \
-               code \
-       }
-#define NAKCICHAR(opt, neg, code) \
-       if (go->neg && \
-                       len >= CILEN_CHAR && \
-                       p[1] == CILEN_CHAR && \
-                       p[0] == opt) { \
-               len -= CILEN_CHAR; \
-               INCPTR(2, p); \
-               GETCHAR(cichar, p); \
-               no.neg = 1; \
-               code \
-       }
-#define NAKCISHORT(opt, neg, code) \
-       if (go->neg && \
-                       len >= CILEN_SHORT && \
-                       p[1] == CILEN_SHORT && \
-                       p[0] == opt) { \
-               len -= CILEN_SHORT; \
-               INCPTR(2, p); \
-               GETSHORT(cishort, p); \
-               no.neg = 1; \
-               code \
-       }
-#define NAKCILONG(opt, neg, code) \
-       if (go->neg && \
-                       len >= CILEN_LONG && \
-                       p[1] == CILEN_LONG && \
-                       p[0] == opt) { \
-               len -= CILEN_LONG; \
-               INCPTR(2, p); \
-               GETLONG(cilong, p); \
-               no.neg = 1; \
-               code \
-       }
-#define NAKCILQR(opt, neg, code) \
-       if (go->neg && \
-                       len >= CILEN_LQR && \
-                       p[1] == CILEN_LQR && \
-                       p[0] == opt) { \
-               len -= CILEN_LQR; \
-               INCPTR(2, p); \
-               GETSHORT(cishort, p); \
-               GETLONG(cilong, p); \
-               no.neg = 1; \
-               code \
-       }
-       
-       /*
-       * We don't care if they want to send us smaller packets than
-       * we want.  Therefore, accept any MRU less than what we asked for,
-       * but then ignore the new value when setting the MRU in the kernel.
-       * If they send us a bigger MRU than what we asked, accept it, up to
-       * the limit of the default MRU we'd get if we didn't negotiate.
-       */
-       if (go->neg_mru && go->mru != PPP_DEFMRU) {
-               NAKCISHORT(CI_MRU, neg_mru,
-                       if (cishort <= wo->mru || cishort < PPP_DEFMRU)
-                               try.mru = cishort;
-               );
-       }
-       
-       /*
-       * Add any characters they want to our (receive-side) asyncmap.
-       */
-       if (go->neg_asyncmap && go->asyncmap != 0xFFFFFFFFl) {
-               NAKCILONG(CI_ASYNCMAP, neg_asyncmap,
-                       try.asyncmap = go->asyncmap | cilong;
-               );
-       }
-       
-       /*
-       * If they've nak'd our authentication-protocol, check whether
-       * they are proposing a different protocol, or a different
-       * hash algorithm for CHAP.
-       */
-       if ((go->neg_chap || go->neg_upap)
-                       && len >= CILEN_SHORT
-                       && p[0] == CI_AUTHTYPE && p[1] >= CILEN_SHORT && p[1] <= len) {
-               cilen = p[1];
-       len -= cilen;
-       no.neg_chap = go->neg_chap;
-       no.neg_upap = go->neg_upap;
-       INCPTR(2, p);
-       GETSHORT(cishort, p);
-       if (cishort == PPP_PAP && cilen == CILEN_SHORT) {
-               /*
-                * If we were asking for CHAP, they obviously don't want to do it.
-                * If we weren't asking for CHAP, then we were asking for PAP,
-                * in which case this Nak is bad.
-                */
-               if (!go->neg_chap)
-                       goto bad;
-               try.neg_chap = 0;
-       
-       } else if (cishort == PPP_CHAP && cilen == CILEN_CHAP) {
-               GETCHAR(cichar, p);
-               if (go->neg_chap) {
-                       /*
-                        * We were asking for CHAP/MD5; they must want a different
-                        * algorithm.  If they can't do MD5, we'll have to stop
-                        * asking for CHAP.
-                        */
-                       if (cichar != go->chap_mdtype)
-                               try.neg_chap = 0;
-               } else {
-                       /*
-                        * Stop asking for PAP if we were asking for it.
-                        */
-                       try.neg_upap = 0;
-               }
-       
-       } else {
-               /*
-                * We don't recognize what they're suggesting.
-                * Stop asking for what we were asking for.
-                */
-               if (go->neg_chap)
-                       try.neg_chap = 0;
-               else
-                       try.neg_upap = 0;
-               p += cilen - CILEN_SHORT;
-       }
-       }
-       
-       /*
-       * If they can't cope with our link quality protocol, we'll have
-       * to stop asking for LQR.  We haven't got any other protocol.
-       * If they Nak the reporting period, take their value XXX ?
-       */
-       NAKCILQR(CI_QUALITY, neg_lqr,
-               if (cishort != PPP_LQR)
-                       try.neg_lqr = 0;
-               else
-                       try.lqr_period = cilong;
-       );
-       
-       /*
-       * Only implementing CBCP...not the rest of the callback options
-       */
-       NAKCICHAR(CI_CALLBACK, neg_cbcp,
-               try.neg_cbcp = 0;
-       );
-       
-       /*
-       * Check for a looped-back line.
-       */
-       NAKCILONG(CI_MAGICNUMBER, neg_magicnumber,
-               try.magicnumber = magic();
-               looped_back = 1;
-       );
-       
-       /*
-       * Peer shouldn't send Nak for protocol compression or
-       * address/control compression requests; they should send
-       * a Reject instead.  If they send a Nak, treat it as a Reject.
-       */
-       NAKCIVOID(CI_PCOMPRESSION, neg_pcompression,
-               try.neg_pcompression = 0;
-       );
-       NAKCIVOID(CI_ACCOMPRESSION, neg_accompression,
-               try.neg_accompression = 0;
-       );
-       
-       /*
-       * There may be remaining CIs, if the peer is requesting negotiation
-       * on an option that we didn't include in our request packet.
-       * If we see an option that we requested, or one we've already seen
-       * in this packet, then this packet is bad.
-       * If we wanted to respond by starting to negotiate on the requested
-       * option(s), we could, but we don't, because except for the
-       * authentication type and quality protocol, if we are not negotiating
-       * an option, it is because we were told not to.
-       * For the authentication type, the Nak from the peer means
-       * `let me authenticate myself with you' which is a bit pointless.
-       * For the quality protocol, the Nak means `ask me to send you quality
-       * reports', but if we didn't ask for them, we don't want them.
-       * An option we don't recognize represents the peer asking to
-       * negotiate some option we don't support, so ignore it.
-       */
-       while (len > CILEN_VOID) {
-               GETCHAR(citype, p);
-               GETCHAR(cilen, p);
-               if (cilen < CILEN_VOID || (len -= cilen) < 0)
-                       goto bad;
-               next = p + cilen - 2;
-               
-               switch (citype) {
-               case CI_MRU:
-                       if ((go->neg_mru && go->mru != PPP_DEFMRU)
-                                       || no.neg_mru || cilen != CILEN_SHORT)
-                               goto bad;
-                       GETSHORT(cishort, p);
-                       if (cishort < PPP_DEFMRU)
-                               try.mru = cishort;
-                       break;
-               case CI_ASYNCMAP:
-                       if ((go->neg_asyncmap && go->asyncmap != 0xFFFFFFFFl)
-                                       || no.neg_asyncmap || cilen != CILEN_LONG)
-                               goto bad;
-                       break;
-               case CI_AUTHTYPE:
-                       if (go->neg_chap || no.neg_chap || go->neg_upap || no.neg_upap)
-                               goto bad;
-                       break;
-               case CI_MAGICNUMBER:
-                       if (go->neg_magicnumber || no.neg_magicnumber ||
-                                       cilen != CILEN_LONG)
-                               goto bad;
-                       break;
-               case CI_PCOMPRESSION:
-                       if (go->neg_pcompression || no.neg_pcompression
-                                       || cilen != CILEN_VOID)
-                               goto bad;
-                       break;
-               case CI_ACCOMPRESSION:
-                       if (go->neg_accompression || no.neg_accompression
-                                       || cilen != CILEN_VOID)
-                               goto bad;
-                       break;
-               case CI_QUALITY:
-                       if (go->neg_lqr || no.neg_lqr || cilen != CILEN_LQR)
-                               goto bad;
-                       break;
-               }
-               p = next;
-       }
-       
-       /* If there is still anything left, this packet is bad. */
-       if (len != 0)
-               goto bad;
-       
-       /*
-       * OK, the Nak is good.  Now we can update state.
-       */
-       if (f->state != OPENED) {
-               if (looped_back) {
-                       if (++try.numloops >= lcp_loopbackfail) {
-                               LCPDEBUG((LOG_NOTICE, "Serial line is looped back.\n"));
-                               lcp_close(f->unit, "Loopback detected");
-                       }
-               } 
-               else
-                       try.numloops = 0;
-               *go = try;
-       }
-       
-       return 1;
-       
-bad:
-       LCPDEBUG((LOG_WARNING, "lcp_nakci: received bad Nak!\n"));
-       return 0;
-}
-
-
-/*
- * lcp_rejci - Peer has Rejected some of our CIs.
- * This should not modify any state if the Reject is bad
- * or if LCP is in the OPENED state.
- *
- * Returns:
- *     0 - Reject was bad.
- *     1 - Reject was good.
- */
-static int lcp_rejci(fsm *f, u_char *p, int len)
-{
-       lcp_options *go = &lcp_gotoptions[f->unit];
-       u_char cichar;
-       u_short cishort;
-       u32_t cilong;
-       lcp_options try;                /* options to request next time */
-       
-       try = *go;
-       
-       /*
-       * Any Rejected CIs must be in exactly the same order that we sent.
-       * Check packet length and CI length at each step.
-       * If we find any deviations, then this packet is bad.
-       */
-#define REJCIVOID(opt, neg) \
-       if (go->neg && \
-                       len >= CILEN_VOID && \
-                       p[1] == CILEN_VOID && \
-                       p[0] == opt) { \
-               len -= CILEN_VOID; \
-               INCPTR(CILEN_VOID, p); \
-               try.neg = 0; \
-               LCPDEBUG((LOG_INFO, "lcp_rejci: void opt %d rejected\n", opt)); \
-       }
-#define REJCISHORT(opt, neg, val) \
-       if (go->neg && \
-                       len >= CILEN_SHORT && \
-                       p[1] == CILEN_SHORT && \
-                       p[0] == opt) { \
-               len -= CILEN_SHORT; \
-               INCPTR(2, p); \
-               GETSHORT(cishort, p); \
-               /* Check rejected value. */ \
-               if (cishort != val) \
-                       goto bad; \
-               try.neg = 0; \
-               LCPDEBUG((LOG_INFO,"lcp_rejci: short opt %d rejected\n", opt)); \
-       }
-#define REJCICHAP(opt, neg, val, digest) \
-       if (go->neg && \
-                       len >= CILEN_CHAP && \
-                       p[1] == CILEN_CHAP && \
-                       p[0] == opt) { \
-               len -= CILEN_CHAP; \
-               INCPTR(2, p); \
-               GETSHORT(cishort, p); \
-               GETCHAR(cichar, p); \
-               /* Check rejected value. */ \
-               if (cishort != val || cichar != digest) \
-                       goto bad; \
-               try.neg = 0; \
-               try.neg_upap = 0; \
-               LCPDEBUG((LOG_INFO,"lcp_rejci: chap opt %d rejected\n", opt)); \
-       }
-#define REJCILONG(opt, neg, val) \
-       if (go->neg && \
-                       len >= CILEN_LONG && \
-                       p[1] == CILEN_LONG && \
-                       p[0] == opt) { \
-               len -= CILEN_LONG; \
-               INCPTR(2, p); \
-               GETLONG(cilong, p); \
-               /* Check rejected value. */ \
-               if (cilong != val) \
-                       goto bad; \
-               try.neg = 0; \
-               LCPDEBUG((LOG_INFO,"lcp_rejci: long opt %d rejected\n", opt)); \
-       }
-#define REJCILQR(opt, neg, val) \
-       if (go->neg && \
-                       len >= CILEN_LQR && \
-                       p[1] == CILEN_LQR && \
-                       p[0] == opt) { \
-               len -= CILEN_LQR; \
-               INCPTR(2, p); \
-               GETSHORT(cishort, p); \
-               GETLONG(cilong, p); \
-               /* Check rejected value. */ \
-               if (cishort != PPP_LQR || cilong != val) \
-                       goto bad; \
-               try.neg = 0; \
-               LCPDEBUG((LOG_INFO,"lcp_rejci: LQR opt %d rejected\n", opt)); \
-       }
-#define REJCICBCP(opt, neg, val) \
-       if (go->neg && \
-                       len >= CILEN_CBCP && \
-                       p[1] == CILEN_CBCP && \
-                       p[0] == opt) { \
-               len -= CILEN_CBCP; \
-               INCPTR(2, p); \
-               GETCHAR(cichar, p); \
-               /* Check rejected value. */ \
-               if (cichar != val) \
-                       goto bad; \
-               try.neg = 0; \
-               LCPDEBUG((LOG_INFO,"lcp_rejci: Callback opt %d rejected\n", opt)); \
-       }
-       
-       REJCISHORT(CI_MRU, neg_mru, go->mru);
-       REJCILONG(CI_ASYNCMAP, neg_asyncmap, go->asyncmap);
-       REJCICHAP(CI_AUTHTYPE, neg_chap, PPP_CHAP, go->chap_mdtype);
-       if (!go->neg_chap) {
-               REJCISHORT(CI_AUTHTYPE, neg_upap, PPP_PAP);
-       }
-       REJCILQR(CI_QUALITY, neg_lqr, go->lqr_period);
-       REJCICBCP(CI_CALLBACK, neg_cbcp, CBCP_OPT);
-       REJCILONG(CI_MAGICNUMBER, neg_magicnumber, go->magicnumber);
-       REJCIVOID(CI_PCOMPRESSION, neg_pcompression);
-       REJCIVOID(CI_ACCOMPRESSION, neg_accompression);
-       
-       /*
-       * If there are any remaining CIs, then this packet is bad.
-       */
-       if (len != 0)
-               goto bad;
-       /*
-       * Now we can update state.
-       */
-       if (f->state != OPENED)
-               *go = try;
-       return 1;
-       
-bad:
-       LCPDEBUG((LOG_WARNING, "lcp_rejci: received bad Reject!\n"));
-       return 0;
-}
-
-
-/*
- * lcp_reqci - Check the peer's requested CIs and send appropriate response.
- *
- * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified
- * appropriately.  If reject_if_disagree is non-zero, doesn't return
- * CONFNAK; returns CONFREJ if it can't return CONFACK.
- */
-static int lcp_reqci(fsm *f, 
-                                               u_char *inp,            /* Requested CIs */
-                                               int *lenp,                      /* Length of requested CIs */
-                                               int reject_if_disagree)
-{
-       lcp_options *go = &lcp_gotoptions[f->unit];
-       lcp_options *ho = &lcp_hisoptions[f->unit];
-       lcp_options *ao = &lcp_allowoptions[f->unit];
-       u_char *cip, *next;                     /* Pointer to current and next CIs */
-       int cilen, citype, cichar;      /* Parsed len, type, char value */
-       u_short cishort;                        /* Parsed short value */
-       u32_t cilong;                   /* Parse long value */
-       int rc = CONFACK;                       /* Final packet return code */
-       int orc;                                        /* Individual option return code */
-       u_char *p;                                      /* Pointer to next char to parse */
-       u_char *rejp;                           /* Pointer to next char in reject frame */
-       u_char *nakp;                           /* Pointer to next char in Nak frame */
-       int l = *lenp;                          /* Length left */
-#if TRACELCP > 0
-       char traceBuf[80];
-       int traceNdx = 0;
-#endif
-       
-       /*
-        * Reset all his options.
-        */
-       BZERO(ho, sizeof(*ho));
-       
-       /*
-        * Process all his options.
-        */
-       next = inp;
-       nakp = nak_buffer;
-       rejp = inp;
-       while (l) {
-               orc = CONFACK;                  /* Assume success */
-               cip = p = next;                 /* Remember begining of CI */
-               if (l < 2 ||                    /* Not enough data for CI header or */
-                               p[1] < 2 ||                     /*  CI length too small or */
-                               p[1] > l) {                     /*  CI length too big? */
-                       LCPDEBUG((LOG_WARNING, "lcp_reqci: bad CI length!\n"));
-                       orc = CONFREJ;          /* Reject bad CI */
-                       cilen = l;                      /* Reject till end of packet */
-                       l = 0;                  /* Don't loop again */
-                       citype = 0;
-                       goto endswitch;
-               }
-               GETCHAR(citype, p);             /* Parse CI type */
-               GETCHAR(cilen, p);              /* Parse CI length */
-               l -= cilen;                     /* Adjust remaining length */
-               next += cilen;                  /* Step to next CI */
-               
-               switch (citype) {               /* Check CI type */
-               case CI_MRU:
-                       if (!ao->neg_mru) {             /* Allow option? */
-                               LCPDEBUG((LOG_INFO, "lcp_reqci: Reject MRU - not allowed\n"));
-                               orc = CONFREJ;          /* Reject CI */
-                               break;
-                       } else if (cilen != CILEN_SHORT) {      /* Check CI length */
-                               LCPDEBUG((LOG_INFO, "lcp_reqci: Reject MRU - bad length\n"));
-                               orc = CONFREJ;          /* Reject CI */
-                               break;
-                       }
-                       GETSHORT(cishort, p);   /* Parse MRU */
-                       
-                       /*
-                        * He must be able to receive at least our minimum.
-                        * No need to check a maximum.  If he sends a large number,
-                        * we'll just ignore it.
-                        */
-                       if (cishort < PPP_MINMRU) {
-                               LCPDEBUG((LOG_INFO, "lcp_reqci: Nak - MRU too small\n"));
-                               orc = CONFNAK;          /* Nak CI */
-                               PUTCHAR(CI_MRU, nakp);
-                               PUTCHAR(CILEN_SHORT, nakp);
-                               PUTSHORT(PPP_MINMRU, nakp);     /* Give him a hint */
-                               break;
-                       }
-                       ho->neg_mru = 1;                /* Remember he sent MRU */
-                       ho->mru = cishort;              /* And remember value */
-#if TRACELCP > 0
-                       sprintf(&traceBuf[traceNdx], " MRU %d", cishort);
-                       traceNdx = strlen(traceBuf);
-#endif
-                       break;
-               
-               case CI_ASYNCMAP:
-                       if (!ao->neg_asyncmap) {
-                               LCPDEBUG((LOG_INFO, "lcp_reqci: Reject ASYNCMAP not allowed\n"));
-                               orc = CONFREJ;
-                               break;
-                       } else if (cilen != CILEN_LONG) {
-                               LCPDEBUG((LOG_INFO, "lcp_reqci: Reject ASYNCMAP bad length\n"));
-                               orc = CONFREJ;
-                               break;
-                       }
-                       GETLONG(cilong, p);
-                       
-                       /*
-                        * Asyncmap must have set at least the bits
-                        * which are set in lcp_allowoptions[unit].asyncmap.
-                        */
-                       if ((ao->asyncmap & ~cilong) != 0) {
-                               LCPDEBUG((LOG_INFO, "lcp_reqci: Nak ASYNCMAP %lX missing %lX\n", 
-                                                       cilong, ao->asyncmap));
-                               orc = CONFNAK;
-                               PUTCHAR(CI_ASYNCMAP, nakp);
-                               PUTCHAR(CILEN_LONG, nakp);
-                               PUTLONG(ao->asyncmap | cilong, nakp);
-                               break;
-                       }
-                       ho->neg_asyncmap = 1;
-                       ho->asyncmap = cilong;
-#if TRACELCP > 0
-                       sprintf(&traceBuf[traceNdx], " ASYNCMAP=%lX", cilong);
-                       traceNdx = strlen(traceBuf);
-#endif
-                       break;
-               
-               case CI_AUTHTYPE:
-                       if (cilen < CILEN_SHORT) {
-                               LCPDEBUG((LOG_INFO, "lcp_reqci: Reject AUTHTYPE missing arg\n"));
-                               orc = CONFREJ;
-                               break;
-                       } else if (!(ao->neg_upap || ao->neg_chap)) {
-                               /*
-                                * Reject the option if we're not willing to authenticate.
-                                */
-                               LCPDEBUG((LOG_INFO, "lcp_reqci: Reject AUTHTYPE not allowed\n"));
-                               orc = CONFREJ;
-                               break;
-                       }
-                       GETSHORT(cishort, p);
-                       
-                       /*
-                        * Authtype must be UPAP or CHAP.
-                        *
-                        * Note: if both ao->neg_upap and ao->neg_chap are set,
-                        * and the peer sends a Configure-Request with two
-                        * authenticate-protocol requests, one for CHAP and one
-                        * for UPAP, then we will reject the second request.
-                        * Whether we end up doing CHAP or UPAP depends then on
-                        * the ordering of the CIs in the peer's Configure-Request.
-                        */
-                       
-                       if (cishort == PPP_PAP) {
-                               if (ho->neg_chap) {     /* we've already accepted CHAP */
-                                       LCPDEBUG((LOG_WARNING, "lcp_reqci: Reject AUTHTYPE PAP already accepted\n"));
-                                       orc = CONFREJ;
-                                       break;
-                               } else if (cilen != CILEN_SHORT) {
-                                       LCPDEBUG((LOG_WARNING, "lcp_reqci: Reject AUTHTYPE PAP bad len\n"));
-                                       orc = CONFREJ;
-                                       break;
-                               }
-                               if (!ao->neg_upap) {    /* we don't want to do PAP */
-                                       LCPDEBUG((LOG_WARNING, "lcp_reqci: Nak AUTHTYPE PAP not allowed\n"));
-                                       orc = CONFNAK;  /* NAK it and suggest CHAP */
-                                       PUTCHAR(CI_AUTHTYPE, nakp);
-                                       PUTCHAR(CILEN_CHAP, nakp);
-                                       PUTSHORT(PPP_CHAP, nakp);
-                                       PUTCHAR(ao->chap_mdtype, nakp);
-                                       break;
-                               }
-                               ho->neg_upap = 1;
-#if TRACELCP > 0
-                               sprintf(&traceBuf[traceNdx], " PAP (%X)", cishort);
-                               traceNdx = strlen(traceBuf);
-#endif
-                               break;
-                       }
-                       if (cishort == PPP_CHAP) {
-                               if (ho->neg_upap) {     /* we've already accepted PAP */
-                                       LCPDEBUG((LOG_WARNING, "lcp_reqci: Reject AUTHTYPE CHAP accepted PAP\n"));
-                                       orc = CONFREJ;
-                                       break;
-                               } else if (cilen != CILEN_CHAP) {
-                                       LCPDEBUG((LOG_WARNING, "lcp_reqci: Reject AUTHTYPE CHAP bad len\n"));
-                                       orc = CONFREJ;
-                                       break;
-                               }
-                               if (!ao->neg_chap) {    /* we don't want to do CHAP */
-                                       LCPDEBUG((LOG_WARNING, "lcp_reqci: Nak AUTHTYPE CHAP not allowed\n"));
-                                       orc = CONFNAK;  /* NAK it and suggest PAP */
-                                       PUTCHAR(CI_AUTHTYPE, nakp);
-                                       PUTCHAR(CILEN_SHORT, nakp);
-                                       PUTSHORT(PPP_PAP, nakp);
-                                       break;
-                               }
-                               GETCHAR(cichar, p);     /* get digest type*/
-                               if (cichar != CHAP_DIGEST_MD5
-#ifdef CHAPMS
-                                               && cichar != CHAP_MICROSOFT
-#endif
-                               ) {
-                                       LCPDEBUG((LOG_WARNING, "lcp_reqci: Nak AUTHTYPE CHAP digest=%d\n", cichar));
-                                       orc = CONFNAK;
-                                       PUTCHAR(CI_AUTHTYPE, nakp);
-                                       PUTCHAR(CILEN_CHAP, nakp);
-                                       PUTSHORT(PPP_CHAP, nakp);
-                                       PUTCHAR(ao->chap_mdtype, nakp);
-                                       break;
-                               }
-#if TRACELCP > 0
-                               sprintf(&traceBuf[traceNdx], " CHAP %X,%d", cishort, cichar);
-                               traceNdx = strlen(traceBuf);
-#endif
-                               ho->chap_mdtype = cichar; /* save md type */
-                               ho->neg_chap = 1;
-                               break;
-                       }
-                       
-                       /*
-                        * We don't recognize the protocol they're asking for.
-                        * Nak it with something we're willing to do.
-                        * (At this point we know ao->neg_upap || ao->neg_chap.)
-                        */
-                       orc = CONFNAK;
-                       PUTCHAR(CI_AUTHTYPE, nakp);
-                       if (ao->neg_chap) {
-                               LCPDEBUG((LOG_WARNING, "lcp_reqci: Nak AUTHTYPE %d req CHAP\n", cishort));
-                               PUTCHAR(CILEN_CHAP, nakp);
-                               PUTSHORT(PPP_CHAP, nakp);
-                               PUTCHAR(ao->chap_mdtype, nakp);
-                       } 
-                       else {
-                               LCPDEBUG((LOG_WARNING, "lcp_reqci: Nak AUTHTYPE %d req PAP\n", cishort));
-                               PUTCHAR(CILEN_SHORT, nakp);
-                               PUTSHORT(PPP_PAP, nakp);
-                       }
-                       break;
-               
-               case CI_QUALITY:
-                       GETSHORT(cishort, p);
-                       GETLONG(cilong, p);
-#if TRACELCP > 0
-                       sprintf(&traceBuf[traceNdx], " QUALITY (%x %x)", cishort, (unsigned int) cilong);
-                       traceNdx = strlen(traceBuf);
-#endif
-
-                       if (!ao->neg_lqr ||
-                                       cilen != CILEN_LQR) {
-                               orc = CONFREJ;
-                               break;
-                       }
-                       
-                       /*
-                        * Check the protocol and the reporting period.
-                        * XXX When should we Nak this, and what with?
-                        */
-                       if (cishort != PPP_LQR) {
-                               orc = CONFNAK;
-                               PUTCHAR(CI_QUALITY, nakp);
-                               PUTCHAR(CILEN_LQR, nakp);
-                               PUTSHORT(PPP_LQR, nakp);
-                               PUTLONG(ao->lqr_period, nakp);
-                               break;
-                       }
-                       break;
-               
-               case CI_MAGICNUMBER:
-                       if (!(ao->neg_magicnumber || go->neg_magicnumber) ||
-                                       cilen != CILEN_LONG) {
-                               orc = CONFREJ;
-                               break;
-                       }
-                       GETLONG(cilong, p);
-#if TRACELCP > 0
-                       sprintf(&traceBuf[traceNdx], " MAGICNUMBER (%lX)", cilong);
-                       traceNdx = strlen(traceBuf);
-#endif
-
-                       /*
-                        * He must have a different magic number.
-                        */
-                       if (go->neg_magicnumber &&
-                                       cilong == go->magicnumber) {
-                               cilong = magic();       /* Don't put magic() inside macro! */
-                               orc = CONFNAK;
-                               PUTCHAR(CI_MAGICNUMBER, nakp);
-                               PUTCHAR(CILEN_LONG, nakp);
-                               PUTLONG(cilong, nakp);
-                               break;
-                       }
-                       ho->neg_magicnumber = 1;
-                       ho->magicnumber = cilong;
-                       break;
-               
-               
-               case CI_PCOMPRESSION:
-#if TRACELCP > 0
-                       sprintf(&traceBuf[traceNdx], " PCOMPRESSION");
-                       traceNdx = strlen(traceBuf);
-#endif
-                       if (!ao->neg_pcompression ||
-                                       cilen != CILEN_VOID) {
-                               orc = CONFREJ;
-                               break;
-                       }
-                       ho->neg_pcompression = 1;
-                       break;
-               
-               case CI_ACCOMPRESSION:
-#if TRACELCP > 0
-                       sprintf(&traceBuf[traceNdx], " ACCOMPRESSION");
-                       traceNdx = strlen(traceBuf);
-#endif
-                       if (!ao->neg_accompression ||
-                                       cilen != CILEN_VOID) {
-                               orc = CONFREJ;
-                               break;
-                       }
-                       ho->neg_accompression = 1;
-                       break;
-               
-               case CI_MRRU:
-#if TRACELCP > 0
-                       sprintf(&traceBuf[traceNdx], " CI_MRRU");
-                       traceNdx = strlen(traceBuf);
-#endif
-                       orc = CONFREJ;
-                       break;
-               
-               case CI_SSNHF:
-#if TRACELCP > 0
-                       sprintf(&traceBuf[traceNdx], " CI_SSNHF");
-                       traceNdx = strlen(traceBuf);
-#endif
-                       orc = CONFREJ;
-                       break;
-               
-               case CI_EPDISC:
-#if TRACELCP > 0
-                       sprintf(&traceBuf[traceNdx], " CI_EPDISC");
-                       traceNdx = strlen(traceBuf);
-#endif
-                       orc = CONFREJ;
-                       break;
-               
-               default:
-#if TRACELCP
-                       sprintf(&traceBuf[traceNdx], " unknown %d", citype);
-                       traceNdx = strlen(traceBuf);
-#endif
-                       orc = CONFREJ;
-                       break;
-               }
-               
-       endswitch:
-#if TRACELCP
-               if (traceNdx >= 80 - 32) {
-                       LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd%s\n", traceBuf));
-                       traceNdx = 0;
-               }
-#endif
-               if (orc == CONFACK &&           /* Good CI */
-                               rc != CONFACK)          /*  but prior CI wasnt? */
-                       continue;                       /* Don't send this one */
-               
-               if (orc == CONFNAK) {           /* Nak this CI? */
-                       if (reject_if_disagree  /* Getting fed up with sending NAKs? */
-                                       && citype != CI_MAGICNUMBER) {
-                               orc = CONFREJ;          /* Get tough if so */
-                       } 
-                       else {
-                               if (rc == CONFREJ)      /* Rejecting prior CI? */
-                                       continue;               /* Don't send this one */
-                               rc = CONFNAK;
-                       }
-               }
-               if (orc == CONFREJ) {           /* Reject this CI */
-                       rc = CONFREJ;
-                       if (cip != rejp)                /* Need to move rejected CI? */
-                               BCOPY(cip, rejp, cilen); /* Move it */
-                       INCPTR(cilen, rejp);    /* Update output pointer */
-               }
-       }
-       
-       /*
-        * If we wanted to send additional NAKs (for unsent CIs), the
-        * code would go here.  The extra NAKs would go at *nakp.
-        * At present there are no cases where we want to ask the
-        * peer to negotiate an option.
-        */
-       
-       switch (rc) {
-       case CONFACK:
-               *lenp = (int)(next - inp);
-               break;
-       case CONFNAK:
-               /*
-                * Copy the Nak'd options from the nak_buffer to the caller's buffer.
-                */
-               *lenp = (int)(nakp - nak_buffer);
-               BCOPY(nak_buffer, inp, *lenp);
-               break;
-       case CONFREJ:
-               *lenp = (int)(rejp - inp);
-               break;
-       }
-       
-#if TRACELCP > 0
-       if (traceNdx > 0) {
-               LCPDEBUG((LOG_INFO, "lcp_reqci: %s\n", traceBuf));
-       }
-#endif
-       LCPDEBUG((LOG_INFO, "lcp_reqci: returning CONF%s.\n", CODENAME(rc)));
-       return (rc);                    /* Return final code */
-}
-
-
-/*
- * lcp_up - LCP has come UP.
- */
-static void lcp_up(fsm *f)
-{
-       lcp_options *wo = &lcp_wantoptions[f->unit];
-       lcp_options *ho = &lcp_hisoptions[f->unit];
-       lcp_options *go = &lcp_gotoptions[f->unit];
-       lcp_options *ao = &lcp_allowoptions[f->unit];
-       
-       if (!go->neg_magicnumber)
-               go->magicnumber = 0;
-       if (!ho->neg_magicnumber)
-               ho->magicnumber = 0;
-       
-       /*
-       * Set our MTU to the smaller of the MTU we wanted and
-       * the MRU our peer wanted.  If we negotiated an MRU,
-       * set our MRU to the larger of value we wanted and
-       * the value we got in the negotiation.
-       */
-       ppp_send_config(f->unit, LWIP_MIN(ao->mru, (ho->neg_mru? ho->mru: PPP_MRU)),
-                               (ho->neg_asyncmap? ho->asyncmap: 0xffffffffl),
-                               ho->neg_pcompression, ho->neg_accompression);
-       /*
-       * If the asyncmap hasn't been negotiated, we really should
-       * set the receive asyncmap to ffffffff, but we set it to 0
-       * for backwards contemptibility.
-       */
-       ppp_recv_config(f->unit, (go->neg_mru? LWIP_MAX(wo->mru, go->mru): PPP_MRU),
-                               (go->neg_asyncmap? go->asyncmap: 0x00000000),
-                               go->neg_pcompression, go->neg_accompression);
-       
-       if (ho->neg_mru)
-               peer_mru[f->unit] = ho->mru;
-       
-       lcp_echo_lowerup(f->unit);  /* Enable echo messages */
-       
-       link_established(f->unit);
-}
-
-
-/*
- * lcp_down - LCP has gone DOWN.
- *
- * Alert other protocols.
- */
-static void lcp_down(fsm *f)
-{
-       lcp_options *go = &lcp_gotoptions[f->unit];
-       
-       lcp_echo_lowerdown(f->unit);
-       
-       link_down(f->unit);
-       
-       ppp_send_config(f->unit, PPP_MRU, 0xffffffffl, 0, 0);
-       ppp_recv_config(f->unit, PPP_MRU,
-                               (go->neg_asyncmap? go->asyncmap: 0x00000000),
-                               go->neg_pcompression, go->neg_accompression);
-       peer_mru[f->unit] = PPP_MRU;
-}
-
-
-/*
- * lcp_starting - LCP needs the lower layer up.
- */
-static void lcp_starting(fsm *f)
-{
-       link_required(f->unit);
-}
-
-
-/*
- * lcp_finished - LCP has finished with the lower layer.
- */
-static void lcp_finished(fsm *f)
-{
-       link_terminated(f->unit);
-}
-
-
-#if 0
-/*
- * print_string - print a readable representation of a string using
- * printer.
- */
-static void print_string(
-    char *p,
-    int len,
-    void (*printer) (void *, char *, ...),
-    void *arg
-)
-{
-    int c;
-    
-    printer(arg, "\"");
-    for (; len > 0; --len) {
-        c = *p++;
-        if (' ' <= c && c <= '~') {
-            if (c == '\\' || c == '"')
-                printer(arg, "\\");
-            printer(arg, "%c", c);
-        } else {
-            switch (c) {
-            case '\n':
-                printer(arg, "\\n");
-                break;
-            case '\r':
-                printer(arg, "\\r");
-                break;
-            case '\t':
-                printer(arg, "\\t");
-                break;
-            default:
-                printer(arg, "\\%.3o", c);
-            }
-        }
-    }
-    printer(arg, "\"");
-}
-
-
-/*
- * lcp_printpkt - print the contents of an LCP packet.
- */
-static char *lcp_codenames[] = {
-       "ConfReq", "ConfAck", "ConfNak", "ConfRej",
-       "TermReq", "TermAck", "CodeRej", "ProtRej",
-       "EchoReq", "EchoRep", "DiscReq"
-};
-
-static int lcp_printpkt(
-       u_char *p,
-       int plen,
-       void (*printer) (void *, char *, ...),
-       void *arg
-)
-{
-       int code, id, len, olen;
-       u_char *pstart, *optend;
-       u_short cishort;
-       u32_t cilong;
-       
-       if (plen < HEADERLEN)
-               return 0;
-       pstart = p;
-       GETCHAR(code, p);
-       GETCHAR(id, p);
-       GETSHORT(len, p);
-       if (len < HEADERLEN || len > plen)
-               return 0;
-       
-       if (code >= 1 && code <= sizeof(lcp_codenames) / sizeof(char *))
-               printer(arg, " %s", lcp_codenames[code-1]);
-       else
-               printer(arg, " code=0x%x", code);
-       printer(arg, " id=0x%x", id);
-       len -= HEADERLEN;
-       switch (code) {
-       case CONFREQ:
-       case CONFACK:
-       case CONFNAK:
-       case CONFREJ:
-               /* print option list */
-               while (len >= 2) {
-                       GETCHAR(code, p);
-                       GETCHAR(olen, p);
-                       p -= 2;
-                       if (olen < 2 || olen > len) {
-                               break;
-                       }
-                       printer(arg, " <");
-                       len -= olen;
-                       optend = p + olen;
-                       switch (code) {
-                       case CI_MRU:
-                               if (olen == CILEN_SHORT) {
-                                       p += 2;
-                                       GETSHORT(cishort, p);
-                                       printer(arg, "mru %d", cishort);
-                               }
-                               break;
-                       case CI_ASYNCMAP:
-                               if (olen == CILEN_LONG) {
-                                       p += 2;
-                                       GETLONG(cilong, p);
-                                       printer(arg, "asyncmap 0x%lx", cilong);
-                               }
-                               break;
-                       case CI_AUTHTYPE:
-                               if (olen >= CILEN_SHORT) {
-                                       p += 2;
-                                       printer(arg, "auth ");
-                                       GETSHORT(cishort, p);
-                                       switch (cishort) {
-                                       case PPP_PAP:
-                                               printer(arg, "pap");
-                                               break;
-                                       case PPP_CHAP:
-                                               printer(arg, "chap");
-                                               break;
-                                       default:
-                                               printer(arg, "0x%x", cishort);
-                                       }
-                               }
-                               break;
-                       case CI_QUALITY:
-                               if (olen >= CILEN_SHORT) {
-                                       p += 2;
-                                       printer(arg, "quality ");
-                                       GETSHORT(cishort, p);
-                                       switch (cishort) {
-                                       case PPP_LQR:
-                                               printer(arg, "lqr");
-                                               break;
-                                       default:
-                                               printer(arg, "0x%x", cishort);
-                                       }
-                               }
-                               break;
-                       case CI_CALLBACK:
-                               if (olen >= CILEN_CHAR) {
-                                       p += 2;
-                                       printer(arg, "callback ");
-                                       GETSHORT(cishort, p);
-                                       switch (cishort) {
-                                       case CBCP_OPT:
-                                               printer(arg, "CBCP");
-                                               break;
-                                       default:
-                                               printer(arg, "0x%x", cishort);
-                                       }
-                               }
-                               break;
-                       case CI_MAGICNUMBER:
-                               if (olen == CILEN_LONG) {
-                                       p += 2;
-                                       GETLONG(cilong, p);
-                                       printer(arg, "magic 0x%x", cilong);
-                               }
-                               break;
-                       case CI_PCOMPRESSION:
-                               if (olen == CILEN_VOID) {
-                                       p += 2;
-                                       printer(arg, "pcomp");
-                               }
-                               break;
-                       case CI_ACCOMPRESSION:
-                               if (olen == CILEN_VOID) {
-                                       p += 2;
-                                       printer(arg, "accomp");
-                               }
-                               break;
-                       }
-                       while (p < optend) {
-                               GETCHAR(code, p);
-                               printer(arg, " %.2x", code);
-                       }
-                       printer(arg, ">");
-               }
-               break;
-       
-       case TERMACK:
-       case TERMREQ:
-               if (len > 0 && *p >= ' ' && *p < 0x7f) {
-                       printer(arg, " ");
-                       print_string((char*)p, len, printer, arg);
-                       p += len;
-                       len = 0;
-               }
-               break;
-       
-       case ECHOREQ:
-       case ECHOREP:
-       case DISCREQ:
-               if (len >= 4) {
-                       GETLONG(cilong, p);
-                       printer(arg, " magic=0x%x", cilong);
-                       p += 4;
-                       len -= 4;
-               }
-               break;
-       }
-       
-       /* print the rest of the bytes in the packet */
-       for (; len > 0; --len) {
-               GETCHAR(code, p);
-               printer(arg, " %.2x", code);
-       }
-       
-       return (int)(p - pstart);
-}
-#endif
-
-/*
- * Time to shut down the link because there is nothing out there.
- */
-
-static void LcpLinkFailure (fsm *f)
-{
-       if (f->state == OPENED) {
-               LCPDEBUG((LOG_INFO, "No response to %d echo-requests\n", lcp_echos_pending));
-               LCPDEBUG((LOG_NOTICE, "Serial link appears to be disconnected.\n"));
-               lcp_close(f->unit, "Peer not responding");
-       }
-}
-
-/*
- * Timer expired for the LCP echo requests from this process.
- */
-
-static void LcpEchoCheck (fsm *f)
-{
-       LcpSendEchoRequest (f);
-       
-       /*
-        * Start the timer for the next interval.
-        */
-       LWIP_ASSERT("lcp_echo_timer_running == 0", lcp_echo_timer_running == 0);
-
-       TIMEOUT (LcpEchoTimeout, f, lcp_echo_interval);
-       lcp_echo_timer_running = 1;
-}
-
-/*
- * LcpEchoTimeout - Timer expired on the LCP echo
- */
-
-static void LcpEchoTimeout (void *arg)
-{
-       if (lcp_echo_timer_running != 0) {
-               lcp_echo_timer_running = 0;
-               LcpEchoCheck ((fsm *) arg);
-       }
-}
-
-/*
- * LcpEchoReply - LCP has received a reply to the echo
- */
-static void lcp_received_echo_reply (fsm *f, int id, u_char *inp, int len)
-{
-       u32_t magic;
-       
-       (void)id;
-
-       /* Check the magic number - don't count replies from ourselves. */
-       if (len < 4) {
-               LCPDEBUG((LOG_WARNING, "lcp: received short Echo-Reply, length %d\n", len));
-               return;
-       }
-       GETLONG(magic, inp);
-       if (lcp_gotoptions[f->unit].neg_magicnumber
-                       && magic == lcp_gotoptions[f->unit].magicnumber) {
-               LCPDEBUG((LOG_WARNING, "appear to have received our own echo-reply!\n"));
-               return;
-       }
-       
-       /* Reset the number of outstanding echo frames */
-       lcp_echos_pending = 0;
-}
-
-/*
- * LcpSendEchoRequest - Send an echo request frame to the peer
- */
-
-static void LcpSendEchoRequest (fsm *f)
-{
-       u32_t lcp_magic;
-       u_char pkt[4], *pktp;
-       
-       /*
-       * Detect the failure of the peer at this point.
-       */
-       if (lcp_echo_fails != 0) {
-               if (lcp_echos_pending++ >= lcp_echo_fails) {
-                       LcpLinkFailure(f);
-                       lcp_echos_pending = 0;
-               }
-       }
-       
-       /*
-       * Make and send the echo request frame.
-       */
-       if (f->state == OPENED) {
-               lcp_magic = lcp_gotoptions[f->unit].magicnumber;
-               pktp = pkt;
-               PUTLONG(lcp_magic, pktp);
-               fsm_sdata(f, ECHOREQ, (u_char)(lcp_echo_number++ & 0xFF), pkt, (int)(pktp - pkt));
-       }
-}
-
-/*
- * lcp_echo_lowerup - Start the timer for the LCP frame
- */
-
-static void lcp_echo_lowerup (int unit)
-{
-       fsm *f = &lcp_fsm[unit];
-       
-       /* Clear the parameters for generating echo frames */
-       lcp_echos_pending      = 0;
-       lcp_echo_number        = 0;
-       lcp_echo_timer_running = 0;
-       
-       /* If a timeout interval is specified then start the timer */
-       if (lcp_echo_interval != 0)
-               LcpEchoCheck (f);
-}
-
-/*
- * lcp_echo_lowerdown - Stop the timer for the LCP frame
- */
-
-static void lcp_echo_lowerdown (int unit)
-{
-       fsm *f = &lcp_fsm[unit];
-       
-       if (lcp_echo_timer_running != 0) {
-               UNTIMEOUT (LcpEchoTimeout, f);
-               lcp_echo_timer_running = 0;
-       }
-}
-
-#endif /* PPP_SUPPORT */
+/*****************************************************************************\r
+* lcp.c - Network Link Control Protocol program file.\r
+*\r
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.\r
+* portions Copyright (c) 1997 by Global Election Systems Inc.\r
+*\r
+* The authors hereby grant permission to use, copy, modify, distribute,\r
+* and license this software and its documentation for any purpose, provided\r
+* that existing copyright notices are retained in all copies and that this\r
+* notice and the following disclaimer are included verbatim in any \r
+* distributions. No written agreement, license, or royalty fee is required\r
+* for any of the authorized uses.\r
+*\r
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR\r
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+*\r
+******************************************************************************\r
+* REVISION HISTORY\r
+*\r
+* 03-01-01 Marc Boucher <marc@mbsi.ca>\r
+*   Ported to lwIP.\r
+* 97-12-01 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.\r
+*      Original.\r
+*****************************************************************************/\r
+\r
+/*\r
+ * lcp.c - PPP Link Control Protocol.\r
+ *\r
+ * Copyright (c) 1989 Carnegie Mellon University.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms are permitted\r
+ * provided that the above copyright notice and this paragraph are\r
+ * duplicated in all such forms and that any documentation,\r
+ * advertising materials, and other materials related to such\r
+ * distribution and use acknowledge that the software was developed\r
+ * by Carnegie Mellon University.  The name of the\r
+ * University may not be used to endorse or promote products derived\r
+ * from this software without specific prior written permission.\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR\r
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r
+ */\r
\r
+#include <string.h>\r
\r
+#include "ppp.h"\r
+#if PPP_SUPPORT > 0\r
+#include "fsm.h"\r
+#include "chap.h"\r
+#include "magic.h"\r
+#include "auth.h"\r
+#include "lcp.h"\r
+#include "pppdebug.h"\r
+\r
+\r
+/*************************/\r
+/*** LOCAL DEFINITIONS ***/\r
+/*************************/\r
+/*\r
+ * Length of each type of configuration option (in octets)\r
+ */\r
+#define CILEN_VOID     2\r
+#define CILEN_CHAR     3\r
+#define CILEN_SHORT    4       /* CILEN_VOID + sizeof(short) */\r
+#define CILEN_CHAP     5       /* CILEN_VOID + sizeof(short) + 1 */\r
+#define CILEN_LONG     6       /* CILEN_VOID + sizeof(long) */\r
+#define CILEN_LQR      8       /* CILEN_VOID + sizeof(short) + sizeof(long) */\r
+#define CILEN_CBCP     3\r
+\r
+\r
+/***********************************/\r
+/*** LOCAL FUNCTION DECLARATIONS ***/\r
+/***********************************/\r
+/*\r
+ * Callbacks for fsm code.  (CI = Configuration Information)\r
+ */\r
+static void lcp_resetci (fsm*);                /* Reset our CI */\r
+static int  lcp_cilen (fsm*);                  /* Return length of our CI */\r
+static void lcp_addci (fsm*, u_char*, int*);       /* Add our CI to pkt */\r
+static int  lcp_ackci (fsm*, u_char*, int);/* Peer ack'd our CI */\r
+static int  lcp_nakci (fsm*, u_char*, int);/* Peer nak'd our CI */\r
+static int  lcp_rejci (fsm*, u_char*, int);/* Peer rej'd our CI */\r
+static int  lcp_reqci (fsm*, u_char*, int*, int);  /* Rcv peer CI */\r
+static void lcp_up (fsm*);                         /* We're UP */\r
+static void lcp_down (fsm*);               /* We're DOWN */\r
+static void lcp_starting (fsm*);           /* We need lower layer up */\r
+static void lcp_finished (fsm*);               /* We need lower layer down */\r
+static int  lcp_extcode (fsm*, int, u_char, u_char*, int);\r
+\r
+static void lcp_rprotrej (fsm*, u_char*, int);\r
+\r
+/*\r
+ * routines to send LCP echos to peer\r
+ */\r
+static void lcp_echo_lowerup (int);\r
+static void lcp_echo_lowerdown (int);\r
+static void LcpEchoTimeout (void*);\r
+static void lcp_received_echo_reply (fsm*, int, u_char*, int);\r
+static void LcpSendEchoRequest (fsm*);\r
+static void LcpLinkFailure (fsm*);\r
+static void LcpEchoCheck (fsm*);\r
+\r
+/*\r
+ * Protocol entry points.\r
+ * Some of these are called directly.\r
+ */\r
+static void lcp_input (int, u_char *, int);\r
+static void lcp_protrej (int);\r
+\r
+#define CODENAME(x)    ((x) == CONFACK ? "ACK" : \\r
+                        (x) == CONFNAK ? "NAK" : "REJ")\r
+\r
+\r
+/******************************/\r
+/*** PUBLIC DATA STRUCTURES ***/\r
+/******************************/\r
+/* global vars */\r
+LinkPhase lcp_phase[NUM_PPP];                  /* Phase of link session (RFC 1661) */\r
+lcp_options lcp_wantoptions[NUM_PPP];  /* Options that we want to request */\r
+lcp_options lcp_gotoptions[NUM_PPP];   /* Options that peer ack'd */\r
+lcp_options lcp_allowoptions[NUM_PPP]; /* Options we allow peer to request */\r
+lcp_options lcp_hisoptions[NUM_PPP];   /* Options that we ack'd */\r
+ext_accm xmit_accm[NUM_PPP];                   /* extended transmit ACCM */\r
+\r
+\r
+\r
+/*****************************/\r
+/*** LOCAL DATA STRUCTURES ***/\r
+/*****************************/\r
+static fsm lcp_fsm[NUM_PPP];                   /* LCP fsm structure (global)*/\r
+static u_int    lcp_echo_interval = LCP_ECHOINTERVAL; /* Interval between LCP echo-requests */\r
+static u_int    lcp_echo_fails = LCP_MAXECHOFAILS; /* Tolerance to unanswered echo-requests */\r
+static u32_t lcp_echos_pending = 0;    /* Number of outstanding echo msgs */\r
+static u32_t lcp_echo_number   = 0;    /* ID number of next echo frame */\r
+static u32_t lcp_echo_timer_running = 0;  /* TRUE if a timer is running */\r
+\r
+static u_char nak_buffer[PPP_MRU];     /* where we construct a nak packet */\r
+\r
+static fsm_callbacks lcp_callbacks = { /* LCP callback routines */\r
+    lcp_resetci,               /* Reset our Configuration Information */\r
+    lcp_cilen,                 /* Length of our Configuration Information */\r
+    lcp_addci,                 /* Add our Configuration Information */\r
+    lcp_ackci,                 /* ACK our Configuration Information */\r
+    lcp_nakci,                 /* NAK our Configuration Information */\r
+    lcp_rejci,                 /* Reject our Configuration Information */\r
+    lcp_reqci,                 /* Request peer's Configuration Information */\r
+    lcp_up,                            /* Called when fsm reaches OPENED state */\r
+    lcp_down,                  /* Called when fsm leaves OPENED state */\r
+    lcp_starting,              /* Called when we want the lower layer up */\r
+    lcp_finished,              /* Called when we want the lower layer down */\r
+    NULL,                              /* Called when Protocol-Reject received */\r
+    NULL,                              /* Retransmission is necessary */\r
+    lcp_extcode,               /* Called to handle LCP-specific codes */\r
+    "LCP"                              /* String name of protocol */\r
+};\r
+\r
+struct protent lcp_protent = {\r
+    PPP_LCP,\r
+    lcp_init,\r
+    lcp_input,\r
+    lcp_protrej,\r
+    lcp_lowerup,\r
+    lcp_lowerdown,\r
+    lcp_open,\r
+    lcp_close,\r
+#if 0\r
+    lcp_printpkt,\r
+    NULL,\r
+#endif\r
+    1,\r
+    "LCP",\r
+#if 0\r
+    NULL,\r
+    NULL,\r
+    NULL\r
+#endif\r
+};\r
+\r
+int lcp_loopbackfail = DEFLOOPBACKFAIL;\r
+\r
+\r
+\r
+/***********************************/\r
+/*** PUBLIC FUNCTION DEFINITIONS ***/\r
+/***********************************/\r
+/*\r
+ * lcp_init - Initialize LCP.\r
+ */\r
+void lcp_init(int unit)\r
+{\r
+       fsm *f = &lcp_fsm[unit];\r
+       lcp_options *wo = &lcp_wantoptions[unit];\r
+       lcp_options *ao = &lcp_allowoptions[unit];\r
+       \r
+       f->unit = unit;\r
+       f->protocol = PPP_LCP;\r
+       f->callbacks = &lcp_callbacks;\r
+       \r
+       fsm_init(f);\r
+       \r
+       wo->passive = 0;\r
+       wo->silent = 0;\r
+       wo->restart = 0;                        /* Set to 1 in kernels or multi-line\r
+                                                                * implementations */\r
+       wo->neg_mru = 1;\r
+       wo->mru = PPP_DEFMRU;\r
+       wo->neg_asyncmap = 1;\r
+       wo->asyncmap = 0x00000000l;     /* Assume don't need to escape any ctl chars. */\r
+       wo->neg_chap = 0;                       /* Set to 1 on server */\r
+       wo->neg_upap = 0;                       /* Set to 1 on server */\r
+       wo->chap_mdtype = CHAP_DIGEST_MD5;\r
+       wo->neg_magicnumber = 1;\r
+       wo->neg_pcompression = 1;\r
+       wo->neg_accompression = 1;\r
+       wo->neg_lqr = 0;                        /* no LQR implementation yet */\r
+       wo->neg_cbcp = 0;\r
+       \r
+       ao->neg_mru = 1;\r
+       ao->mru = PPP_MAXMRU;\r
+       ao->neg_asyncmap = 1;\r
+       ao->asyncmap = 0x00000000l;     /* Assume don't need to escape any ctl chars. */\r
+       ao->neg_chap = (CHAP_SUPPORT != 0);\r
+       ao->chap_mdtype = CHAP_DIGEST_MD5;\r
+       ao->neg_upap = (PAP_SUPPORT != 0);\r
+       ao->neg_magicnumber = 1;\r
+       ao->neg_pcompression = 1;\r
+       ao->neg_accompression = 1;\r
+       ao->neg_lqr = 0;                        /* no LQR implementation yet */\r
+       ao->neg_cbcp = (CBCP_SUPPORT != 0);\r
+\r
+       /* \r
+        * Set transmit escape for the flag and escape characters plus anything\r
+        * set for the allowable options.\r
+        */\r
+       memset(xmit_accm[unit], 0, sizeof(xmit_accm[0]));\r
+       xmit_accm[unit][15] = 0x60;\r
+       xmit_accm[unit][0] = (u_char)(ao->asyncmap & 0xFF);\r
+       xmit_accm[unit][1] = (u_char)((ao->asyncmap >> 8) & 0xFF);\r
+       xmit_accm[unit][2] = (u_char)((ao->asyncmap >> 16) & 0xFF);\r
+       xmit_accm[unit][3] = (u_char)((ao->asyncmap >> 24) & 0xFF);\r
+       LCPDEBUG((LOG_INFO, "lcp_init: xmit_accm=%X %X %X %X\n",\r
+                               xmit_accm[unit][0],\r
+                               xmit_accm[unit][1],\r
+                               xmit_accm[unit][2],\r
+                               xmit_accm[unit][3]));\r
+       \r
+       lcp_phase[unit] = PHASE_INITIALIZE;\r
+}\r
+\r
+\r
+/*\r
+ * lcp_open - LCP is allowed to come up.\r
+ */\r
+void lcp_open(int unit)\r
+{\r
+       fsm *f = &lcp_fsm[unit];\r
+       lcp_options *wo = &lcp_wantoptions[unit];\r
+       \r
+       f->flags = 0;\r
+       if (wo->passive)\r
+               f->flags |= OPT_PASSIVE;\r
+       if (wo->silent)\r
+               f->flags |= OPT_SILENT;\r
+       fsm_open(f);\r
+       \r
+       lcp_phase[unit] = PHASE_ESTABLISH; \r
+}\r
+\r
+\r
+/*\r
+ * lcp_close - Take LCP down.\r
+ */\r
+void lcp_close(int unit, char *reason)\r
+{\r
+       fsm *f = &lcp_fsm[unit];\r
+       \r
+       if (lcp_phase[unit] != PHASE_DEAD)\r
+               lcp_phase[unit] = PHASE_TERMINATE;\r
+       if (f->state == STOPPED && f->flags & (OPT_PASSIVE|OPT_SILENT)) {\r
+               /*\r
+                * This action is not strictly according to the FSM in RFC1548,\r
+                * but it does mean that the program terminates if you do an\r
+                * lcp_close() in passive/silent mode when a connection hasn't\r
+                * been established.\r
+                */\r
+               f->state = CLOSED;\r
+               lcp_finished(f);\r
+       }\r
+       else\r
+               fsm_close(&lcp_fsm[unit], reason);\r
+}\r
+\r
+\r
+/*\r
+ * lcp_lowerup - The lower layer is up.\r
+ */\r
+void lcp_lowerup(int unit)\r
+{\r
+       lcp_options *wo = &lcp_wantoptions[unit];\r
+       \r
+       /*\r
+       * Don't use A/C or protocol compression on transmission,\r
+       * but accept A/C and protocol compressed packets\r
+       * if we are going to ask for A/C and protocol compression.\r
+       */\r
+       ppp_set_xaccm(unit, &xmit_accm[unit]);\r
+       ppp_send_config(unit, PPP_MRU, 0xffffffffl, 0, 0);\r
+       ppp_recv_config(unit, PPP_MRU, 0x00000000l,\r
+                                       wo->neg_pcompression, wo->neg_accompression);\r
+       peer_mru[unit] = PPP_MRU;\r
+       lcp_allowoptions[unit].asyncmap \r
+               = (u_long)xmit_accm[unit][0]\r
+                       | ((u_long)xmit_accm[unit][1] << 8)\r
+                       | ((u_long)xmit_accm[unit][2] << 16)\r
+                       | ((u_long)xmit_accm[unit][3] << 24);\r
+       LCPDEBUG((LOG_INFO, "lcp_lowerup: asyncmap=%X %X %X %X\n",\r
+                               xmit_accm[unit][3],\r
+                               xmit_accm[unit][2],\r
+                               xmit_accm[unit][1],\r
+                               xmit_accm[unit][0]));\r
+       \r
+       fsm_lowerup(&lcp_fsm[unit]);\r
+}\r
+\r
+\r
+/*\r
+ * lcp_lowerdown - The lower layer is down.\r
+ */\r
+void lcp_lowerdown(int unit)\r
+{\r
+       fsm_lowerdown(&lcp_fsm[unit]);\r
+}\r
+\r
+/*\r
+ * lcp_sprotrej - Send a Protocol-Reject for some protocol.\r
+ */\r
+void lcp_sprotrej(int unit, u_char *p, int len)\r
+{\r
+       /*\r
+       * Send back the protocol and the information field of the\r
+       * rejected packet.  We only get here if LCP is in the OPENED state.\r
+       */\r
+\r
+       fsm_sdata(&lcp_fsm[unit], PROTREJ, ++lcp_fsm[unit].id,\r
+                               p, len);\r
+}\r
+\r
+\r
+\r
+/**********************************/\r
+/*** LOCAL FUNCTION DEFINITIONS ***/\r
+/**********************************/\r
+/*\r
+ * lcp_input - Input LCP packet.\r
+ */\r
+static void lcp_input(int unit, u_char *p, int len)\r
+{\r
+       fsm *f = &lcp_fsm[unit];\r
+       \r
+       fsm_input(f, p, len);\r
+}\r
+\r
+\r
+/*\r
+ * lcp_extcode - Handle a LCP-specific code.\r
+ */\r
+static int lcp_extcode(fsm *f, int code, u_char id, u_char *inp, int len)\r
+{\r
+       u_char *magp;\r
+       \r
+       switch( code ){\r
+       case PROTREJ:\r
+               lcp_rprotrej(f, inp, len);\r
+               break;\r
+       \r
+       case ECHOREQ:\r
+               if (f->state != OPENED)\r
+                       break;\r
+               LCPDEBUG((LOG_INFO, "lcp: Echo-Request, Rcvd id %d\n", id));\r
+               magp = inp;\r
+               PUTLONG(lcp_gotoptions[f->unit].magicnumber, magp);\r
+               fsm_sdata(f, ECHOREP, id, inp, len);\r
+               break;\r
+       \r
+       case ECHOREP:\r
+               lcp_received_echo_reply(f, id, inp, len);\r
+               break;\r
+       \r
+       case DISCREQ:\r
+               break;\r
+       \r
+       default:\r
+               return 0;\r
+       }\r
+       return 1;\r
+}\r
+\r
+    \r
+/*\r
+ * lcp_rprotrej - Receive an Protocol-Reject.\r
+ *\r
+ * Figure out which protocol is rejected and inform it.\r
+ */\r
+static void lcp_rprotrej(fsm *f, u_char *inp, int len)\r
+{\r
+       int i;\r
+       struct protent *protp;\r
+       u_short prot;\r
+       \r
+       if (len < sizeof (u_short)) {\r
+               LCPDEBUG((LOG_INFO,\r
+                               "lcp_rprotrej: Rcvd short Protocol-Reject packet!\n"));\r
+               return;\r
+       }\r
+       \r
+       GETSHORT(prot, inp);\r
+       \r
+       LCPDEBUG((LOG_INFO,\r
+                       "lcp_rprotrej: Rcvd Protocol-Reject packet for %x!\n",\r
+                       prot));\r
+       \r
+       /*\r
+       * Protocol-Reject packets received in any state other than the LCP\r
+       * OPENED state SHOULD be silently discarded.\r
+       */\r
+       if( f->state != OPENED ){\r
+               LCPDEBUG((LOG_INFO, "Protocol-Reject discarded: LCP in state %d\n",\r
+                               f->state));\r
+               return;\r
+       }\r
+       \r
+       /*\r
+       * Upcall the proper Protocol-Reject routine.\r
+       */\r
+       for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i)\r
+               if (protp->protocol == prot && protp->enabled_flag) {\r
+                       (*protp->protrej)(f->unit);\r
+                       return;\r
+               }\r
+       \r
+       LCPDEBUG((LOG_WARNING, "Protocol-Reject for unsupported protocol 0x%x\n",\r
+                       prot));\r
+}\r
+\r
+\r
+/*\r
+ * lcp_protrej - A Protocol-Reject was received.\r
+ */\r
+static void lcp_protrej(int unit)\r
+{\r
+       (void)unit;\r
+       /*\r
+       * Can't reject LCP!\r
+       */\r
+       LCPDEBUG((LOG_WARNING,\r
+                       "lcp_protrej: Received Protocol-Reject for LCP!\n"));\r
+       fsm_protreject(&lcp_fsm[unit]);\r
+}\r
+\r
+\r
+/*\r
+ * lcp_resetci - Reset our CI.\r
+ */\r
+static void lcp_resetci(fsm *f)\r
+{\r
+       lcp_wantoptions[f->unit].magicnumber = magic();\r
+       lcp_wantoptions[f->unit].numloops = 0;\r
+       lcp_gotoptions[f->unit] = lcp_wantoptions[f->unit];\r
+       peer_mru[f->unit] = PPP_MRU;\r
+       auth_reset(f->unit);\r
+}\r
+\r
+\r
+/*\r
+ * lcp_cilen - Return length of our CI.\r
+ */\r
+static int lcp_cilen(fsm *f)\r
+{\r
+       lcp_options *go = &lcp_gotoptions[f->unit];\r
+\r
+#define LENCIVOID(neg) ((neg) ? CILEN_VOID : 0)\r
+#define LENCICHAP(neg) ((neg) ? CILEN_CHAP : 0)\r
+#define LENCISHORT(neg)        ((neg) ? CILEN_SHORT : 0)\r
+#define LENCILONG(neg) ((neg) ? CILEN_LONG : 0)\r
+#define LENCILQR(neg)  ((neg) ? CILEN_LQR: 0)\r
+#define LENCICBCP(neg) ((neg) ? CILEN_CBCP: 0)\r
+       /*\r
+       * NB: we only ask for one of CHAP and UPAP, even if we will\r
+       * accept either.\r
+       */\r
+       return (LENCISHORT(go->neg_mru && go->mru != PPP_DEFMRU) +\r
+               LENCILONG(go->neg_asyncmap && go->asyncmap != 0xFFFFFFFFl) +\r
+               LENCICHAP(go->neg_chap) +\r
+               LENCISHORT(!go->neg_chap && go->neg_upap) +\r
+               LENCILQR(go->neg_lqr) +\r
+               LENCICBCP(go->neg_cbcp) +\r
+               LENCILONG(go->neg_magicnumber) +\r
+               LENCIVOID(go->neg_pcompression) +\r
+               LENCIVOID(go->neg_accompression));\r
+}\r
+\r
+\r
+/*\r
+ * lcp_addci - Add our desired CIs to a packet.\r
+ */\r
+static void lcp_addci(fsm *f, u_char *ucp, int *lenp)\r
+{\r
+       lcp_options *go = &lcp_gotoptions[f->unit];\r
+       u_char *start_ucp = ucp;\r
+       \r
+#define ADDCIVOID(opt, neg) \\r
+       if (neg) { \\r
+           LCPDEBUG((LOG_INFO, "lcp_addci: opt=%d\n", opt)); \\r
+               PUTCHAR(opt, ucp); \\r
+               PUTCHAR(CILEN_VOID, ucp); \\r
+       }\r
+#define ADDCISHORT(opt, neg, val) \\r
+       if (neg) { \\r
+           LCPDEBUG((LOG_INFO, "lcp_addci: INT opt=%d %X\n", opt, val)); \\r
+               PUTCHAR(opt, ucp); \\r
+               PUTCHAR(CILEN_SHORT, ucp); \\r
+               PUTSHORT(val, ucp); \\r
+       }\r
+#define ADDCICHAP(opt, neg, val, digest) \\r
+       if (neg) { \\r
+           LCPDEBUG((LOG_INFO, "lcp_addci: CHAP opt=%d %X\n", opt, val)); \\r
+               PUTCHAR(opt, ucp); \\r
+               PUTCHAR(CILEN_CHAP, ucp); \\r
+               PUTSHORT(val, ucp); \\r
+               PUTCHAR(digest, ucp); \\r
+       }\r
+#define ADDCILONG(opt, neg, val) \\r
+       if (neg) { \\r
+           LCPDEBUG((LOG_INFO, "lcp_addci: L opt=%d %lX\n", opt, val)); \\r
+               PUTCHAR(opt, ucp); \\r
+               PUTCHAR(CILEN_LONG, ucp); \\r
+               PUTLONG(val, ucp); \\r
+       }\r
+#define ADDCILQR(opt, neg, val) \\r
+       if (neg) { \\r
+           LCPDEBUG((LOG_INFO, "lcp_addci: LQR opt=%d %lX\n", opt, val)); \\r
+               PUTCHAR(opt, ucp); \\r
+               PUTCHAR(CILEN_LQR, ucp); \\r
+               PUTSHORT(PPP_LQR, ucp); \\r
+               PUTLONG(val, ucp); \\r
+       }\r
+#define ADDCICHAR(opt, neg, val) \\r
+       if (neg) { \\r
+           LCPDEBUG((LOG_INFO, "lcp_addci: CHAR opt=%d %X '%z'\n", opt, val, val)); \\r
+               PUTCHAR(opt, ucp); \\r
+               PUTCHAR(CILEN_CHAR, ucp); \\r
+               PUTCHAR(val, ucp); \\r
+       }\r
+       \r
+       ADDCISHORT(CI_MRU, go->neg_mru && go->mru != PPP_DEFMRU, go->mru);\r
+       ADDCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFFl,\r
+                       go->asyncmap);\r
+       ADDCICHAP(CI_AUTHTYPE, go->neg_chap, PPP_CHAP, go->chap_mdtype);\r
+       ADDCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, PPP_PAP);\r
+       ADDCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period);\r
+       ADDCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT);\r
+       ADDCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber);\r
+       ADDCIVOID(CI_PCOMPRESSION, go->neg_pcompression);\r
+       ADDCIVOID(CI_ACCOMPRESSION, go->neg_accompression);\r
+       \r
+       if (ucp - start_ucp != *lenp) {\r
+               /* this should never happen, because peer_mtu should be 1500 */\r
+               LCPDEBUG((LOG_ERR, "Bug in lcp_addci: wrong length\n"));\r
+       }\r
+}\r
+\r
+\r
+/*\r
+ * lcp_ackci - Ack our CIs.\r
+ * This should not modify any state if the Ack is bad.\r
+ *\r
+ * Returns:\r
+ *     0 - Ack was bad.\r
+ *     1 - Ack was good.\r
+ */\r
+static int lcp_ackci(fsm *f, u_char *p, int len)\r
+{\r
+       lcp_options *go = &lcp_gotoptions[f->unit];\r
+       u_char cilen, citype, cichar;\r
+       u_short cishort;\r
+       u32_t cilong;\r
+       \r
+       /*\r
+       * CIs must be in exactly the same order that we sent.\r
+       * Check packet length and CI length at each step.\r
+       * If we find any deviations, then this packet is bad.\r
+       */\r
+#define ACKCIVOID(opt, neg) \\r
+       if (neg) { \\r
+               if ((len -= CILEN_VOID) < 0) \\r
+                       goto bad; \\r
+               GETCHAR(citype, p); \\r
+               GETCHAR(cilen, p); \\r
+               if (cilen != CILEN_VOID || \\r
+                               citype != opt) \\r
+                       goto bad; \\r
+       }\r
+#define ACKCISHORT(opt, neg, val) \\r
+       if (neg) { \\r
+               if ((len -= CILEN_SHORT) < 0) \\r
+                       goto bad; \\r
+               GETCHAR(citype, p); \\r
+               GETCHAR(cilen, p); \\r
+               if (cilen != CILEN_SHORT || \\r
+                               citype != opt) \\r
+                       goto bad; \\r
+               GETSHORT(cishort, p); \\r
+               if (cishort != val) \\r
+                       goto bad; \\r
+       }\r
+#define ACKCICHAR(opt, neg, val) \\r
+       if (neg) { \\r
+               if ((len -= CILEN_CHAR) < 0) \\r
+                       goto bad; \\r
+               GETCHAR(citype, p); \\r
+               GETCHAR(cilen, p); \\r
+               if (cilen != CILEN_CHAR || \\r
+                               citype != opt) \\r
+                       goto bad; \\r
+               GETCHAR(cichar, p); \\r
+               if (cichar != val) \\r
+                       goto bad; \\r
+       }\r
+#define ACKCICHAP(opt, neg, val, digest) \\r
+       if (neg) { \\r
+               if ((len -= CILEN_CHAP) < 0) \\r
+                       goto bad; \\r
+               GETCHAR(citype, p); \\r
+               GETCHAR(cilen, p); \\r
+               if (cilen != CILEN_CHAP || \\r
+                               citype != opt) \\r
+                       goto bad; \\r
+               GETSHORT(cishort, p); \\r
+               if (cishort != val) \\r
+                       goto bad; \\r
+               GETCHAR(cichar, p); \\r
+               if (cichar != digest) \\r
+                       goto bad; \\r
+       }\r
+#define ACKCILONG(opt, neg, val) \\r
+       if (neg) { \\r
+               if ((len -= CILEN_LONG) < 0) \\r
+                       goto bad; \\r
+               GETCHAR(citype, p); \\r
+               GETCHAR(cilen, p); \\r
+               if (cilen != CILEN_LONG || \\r
+                               citype != opt) \\r
+                       goto bad; \\r
+               GETLONG(cilong, p); \\r
+               if (cilong != val) \\r
+                       goto bad; \\r
+       }\r
+#define ACKCILQR(opt, neg, val) \\r
+       if (neg) { \\r
+               if ((len -= CILEN_LQR) < 0) \\r
+                       goto bad; \\r
+               GETCHAR(citype, p); \\r
+               GETCHAR(cilen, p); \\r
+               if (cilen != CILEN_LQR || \\r
+                               citype != opt) \\r
+                       goto bad; \\r
+               GETSHORT(cishort, p); \\r
+               if (cishort != PPP_LQR) \\r
+                       goto bad; \\r
+               GETLONG(cilong, p); \\r
+               if (cilong != val) \\r
+                       goto bad; \\r
+       }\r
+       \r
+       ACKCISHORT(CI_MRU, go->neg_mru && go->mru != PPP_DEFMRU, go->mru);\r
+       ACKCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFFl,\r
+                       go->asyncmap);\r
+       ACKCICHAP(CI_AUTHTYPE, go->neg_chap, PPP_CHAP, go->chap_mdtype);\r
+       ACKCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, PPP_PAP);\r
+       ACKCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period);\r
+       ACKCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT);\r
+       ACKCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber);\r
+       ACKCIVOID(CI_PCOMPRESSION, go->neg_pcompression);\r
+       ACKCIVOID(CI_ACCOMPRESSION, go->neg_accompression);\r
+       \r
+       /*\r
+        * If there are any remaining CIs, then this packet is bad.\r
+        */\r
+       if (len != 0)\r
+               goto bad;\r
+       LCPDEBUG((LOG_INFO, "lcp_acki: Ack\n"));\r
+       return (1);\r
+bad:\r
+       LCPDEBUG((LOG_WARNING, "lcp_acki: received bad Ack!\n"));\r
+       return (0);\r
+}\r
+\r
+\r
+/*\r
+ * lcp_nakci - Peer has sent a NAK for some of our CIs.\r
+ * This should not modify any state if the Nak is bad\r
+ * or if LCP is in the OPENED state.\r
+ *\r
+ * Returns:\r
+ *     0 - Nak was bad.\r
+ *     1 - Nak was good.\r
+ */\r
+static int lcp_nakci(fsm *f, u_char *p, int len)\r
+{\r
+       lcp_options *go = &lcp_gotoptions[f->unit];\r
+       lcp_options *wo = &lcp_wantoptions[f->unit];\r
+       u_char citype, cichar, *next;\r
+       u_short cishort;\r
+       u32_t cilong;\r
+       lcp_options no;         /* options we've seen Naks for */\r
+       lcp_options try;                /* options to request next time */\r
+       int looped_back = 0;\r
+       int cilen;\r
+       \r
+       BZERO(&no, sizeof(no));\r
+       try = *go;\r
+       \r
+       /*\r
+       * Any Nak'd CIs must be in exactly the same order that we sent.\r
+       * Check packet length and CI length at each step.\r
+       * If we find any deviations, then this packet is bad.\r
+       */\r
+#define NAKCIVOID(opt, neg, code) \\r
+       if (go->neg && \\r
+                       len >= CILEN_VOID && \\r
+                       p[1] == CILEN_VOID && \\r
+                       p[0] == opt) { \\r
+               len -= CILEN_VOID; \\r
+               INCPTR(CILEN_VOID, p); \\r
+               no.neg = 1; \\r
+               code \\r
+       }\r
+#define NAKCICHAP(opt, neg, code) \\r
+       if (go->neg && \\r
+                       len >= CILEN_CHAP && \\r
+                       p[1] == CILEN_CHAP && \\r
+                       p[0] == opt) { \\r
+               len -= CILEN_CHAP; \\r
+               INCPTR(2, p); \\r
+               GETSHORT(cishort, p); \\r
+               GETCHAR(cichar, p); \\r
+               no.neg = 1; \\r
+               code \\r
+       }\r
+#define NAKCICHAR(opt, neg, code) \\r
+       if (go->neg && \\r
+                       len >= CILEN_CHAR && \\r
+                       p[1] == CILEN_CHAR && \\r
+                       p[0] == opt) { \\r
+               len -= CILEN_CHAR; \\r
+               INCPTR(2, p); \\r
+               GETCHAR(cichar, p); \\r
+               no.neg = 1; \\r
+               code \\r
+       }\r
+#define NAKCISHORT(opt, neg, code) \\r
+       if (go->neg && \\r
+                       len >= CILEN_SHORT && \\r
+                       p[1] == CILEN_SHORT && \\r
+                       p[0] == opt) { \\r
+               len -= CILEN_SHORT; \\r
+               INCPTR(2, p); \\r
+               GETSHORT(cishort, p); \\r
+               no.neg = 1; \\r
+               code \\r
+       }\r
+#define NAKCILONG(opt, neg, code) \\r
+       if (go->neg && \\r
+                       len >= CILEN_LONG && \\r
+                       p[1] == CILEN_LONG && \\r
+                       p[0] == opt) { \\r
+               len -= CILEN_LONG; \\r
+               INCPTR(2, p); \\r
+               GETLONG(cilong, p); \\r
+               no.neg = 1; \\r
+               code \\r
+       }\r
+#define NAKCILQR(opt, neg, code) \\r
+       if (go->neg && \\r
+                       len >= CILEN_LQR && \\r
+                       p[1] == CILEN_LQR && \\r
+                       p[0] == opt) { \\r
+               len -= CILEN_LQR; \\r
+               INCPTR(2, p); \\r
+               GETSHORT(cishort, p); \\r
+               GETLONG(cilong, p); \\r
+               no.neg = 1; \\r
+               code \\r
+       }\r
+       \r
+       /*\r
+       * We don't care if they want to send us smaller packets than\r
+       * we want.  Therefore, accept any MRU less than what we asked for,\r
+       * but then ignore the new value when setting the MRU in the kernel.\r
+       * If they send us a bigger MRU than what we asked, accept it, up to\r
+       * the limit of the default MRU we'd get if we didn't negotiate.\r
+       */\r
+       if (go->neg_mru && go->mru != PPP_DEFMRU) {\r
+               NAKCISHORT(CI_MRU, neg_mru,\r
+                       if (cishort <= wo->mru || cishort < PPP_DEFMRU)\r
+                               try.mru = cishort;\r
+               );\r
+       }\r
+       \r
+       /*\r
+       * Add any characters they want to our (receive-side) asyncmap.\r
+       */\r
+       if (go->neg_asyncmap && go->asyncmap != 0xFFFFFFFFl) {\r
+               NAKCILONG(CI_ASYNCMAP, neg_asyncmap,\r
+                       try.asyncmap = go->asyncmap | cilong;\r
+               );\r
+       }\r
+       \r
+       /*\r
+       * If they've nak'd our authentication-protocol, check whether\r
+       * they are proposing a different protocol, or a different\r
+       * hash algorithm for CHAP.\r
+       */\r
+       if ((go->neg_chap || go->neg_upap)\r
+                       && len >= CILEN_SHORT\r
+                       && p[0] == CI_AUTHTYPE && p[1] >= CILEN_SHORT && p[1] <= len) {\r
+               cilen = p[1];\r
+       len -= cilen;\r
+       no.neg_chap = go->neg_chap;\r
+       no.neg_upap = go->neg_upap;\r
+       INCPTR(2, p);\r
+       GETSHORT(cishort, p);\r
+       if (cishort == PPP_PAP && cilen == CILEN_SHORT) {\r
+               /*\r
+                * If we were asking for CHAP, they obviously don't want to do it.\r
+                * If we weren't asking for CHAP, then we were asking for PAP,\r
+                * in which case this Nak is bad.\r
+                */\r
+               if (!go->neg_chap)\r
+                       goto bad;\r
+               try.neg_chap = 0;\r
+       \r
+       } else if (cishort == PPP_CHAP && cilen == CILEN_CHAP) {\r
+               GETCHAR(cichar, p);\r
+               if (go->neg_chap) {\r
+                       /*\r
+                        * We were asking for CHAP/MD5; they must want a different\r
+                        * algorithm.  If they can't do MD5, we'll have to stop\r
+                        * asking for CHAP.\r
+                        */\r
+                       if (cichar != go->chap_mdtype)\r
+                               try.neg_chap = 0;\r
+               } else {\r
+                       /*\r
+                        * Stop asking for PAP if we were asking for it.\r
+                        */\r
+                       try.neg_upap = 0;\r
+               }\r
+       \r
+       } else {\r
+               /*\r
+                * We don't recognize what they're suggesting.\r
+                * Stop asking for what we were asking for.\r
+                */\r
+               if (go->neg_chap)\r
+                       try.neg_chap = 0;\r
+               else\r
+                       try.neg_upap = 0;\r
+               p += cilen - CILEN_SHORT;\r
+       }\r
+       }\r
+       \r
+       /*\r
+       * If they can't cope with our link quality protocol, we'll have\r
+       * to stop asking for LQR.  We haven't got any other protocol.\r
+       * If they Nak the reporting period, take their value XXX ?\r
+       */\r
+       NAKCILQR(CI_QUALITY, neg_lqr,\r
+               if (cishort != PPP_LQR)\r
+                       try.neg_lqr = 0;\r
+               else\r
+                       try.lqr_period = cilong;\r
+       );\r
+       \r
+       /*\r
+       * Only implementing CBCP...not the rest of the callback options\r
+       */\r
+       NAKCICHAR(CI_CALLBACK, neg_cbcp,\r
+               try.neg_cbcp = 0;\r
+       );\r
+       \r
+       /*\r
+       * Check for a looped-back line.\r
+       */\r
+       NAKCILONG(CI_MAGICNUMBER, neg_magicnumber,\r
+               try.magicnumber = magic();\r
+               looped_back = 1;\r
+       );\r
+       \r
+       /*\r
+       * Peer shouldn't send Nak for protocol compression or\r
+       * address/control compression requests; they should send\r
+       * a Reject instead.  If they send a Nak, treat it as a Reject.\r
+       */\r
+       NAKCIVOID(CI_PCOMPRESSION, neg_pcompression,\r
+               try.neg_pcompression = 0;\r
+       );\r
+       NAKCIVOID(CI_ACCOMPRESSION, neg_accompression,\r
+               try.neg_accompression = 0;\r
+       );\r
+       \r
+       /*\r
+       * There may be remaining CIs, if the peer is requesting negotiation\r
+       * on an option that we didn't include in our request packet.\r
+       * If we see an option that we requested, or one we've already seen\r
+       * in this packet, then this packet is bad.\r
+       * If we wanted to respond by starting to negotiate on the requested\r
+       * option(s), we could, but we don't, because except for the\r
+       * authentication type and quality protocol, if we are not negotiating\r
+       * an option, it is because we were told not to.\r
+       * For the authentication type, the Nak from the peer means\r
+       * `let me authenticate myself with you' which is a bit pointless.\r
+       * For the quality protocol, the Nak means `ask me to send you quality\r
+       * reports', but if we didn't ask for them, we don't want them.\r
+       * An option we don't recognize represents the peer asking to\r
+       * negotiate some option we don't support, so ignore it.\r
+       */\r
+       while (len > CILEN_VOID) {\r
+               GETCHAR(citype, p);\r
+               GETCHAR(cilen, p);\r
+               if (cilen < CILEN_VOID || (len -= cilen) < 0)\r
+                       goto bad;\r
+               next = p + cilen - 2;\r
+               \r
+               switch (citype) {\r
+               case CI_MRU:\r
+                       if ((go->neg_mru && go->mru != PPP_DEFMRU)\r
+                                       || no.neg_mru || cilen != CILEN_SHORT)\r
+                               goto bad;\r
+                       GETSHORT(cishort, p);\r
+                       if (cishort < PPP_DEFMRU)\r
+                               try.mru = cishort;\r
+                       break;\r
+               case CI_ASYNCMAP:\r
+                       if ((go->neg_asyncmap && go->asyncmap != 0xFFFFFFFFl)\r
+                                       || no.neg_asyncmap || cilen != CILEN_LONG)\r
+                               goto bad;\r
+                       break;\r
+               case CI_AUTHTYPE:\r
+                       if (go->neg_chap || no.neg_chap || go->neg_upap || no.neg_upap)\r
+                               goto bad;\r
+                       break;\r
+               case CI_MAGICNUMBER:\r
+                       if (go->neg_magicnumber || no.neg_magicnumber ||\r
+                                       cilen != CILEN_LONG)\r
+                               goto bad;\r
+                       break;\r
+               case CI_PCOMPRESSION:\r
+                       if (go->neg_pcompression || no.neg_pcompression\r
+                                       || cilen != CILEN_VOID)\r
+                               goto bad;\r
+                       break;\r
+               case CI_ACCOMPRESSION:\r
+                       if (go->neg_accompression || no.neg_accompression\r
+                                       || cilen != CILEN_VOID)\r
+                               goto bad;\r
+                       break;\r
+               case CI_QUALITY:\r
+                       if (go->neg_lqr || no.neg_lqr || cilen != CILEN_LQR)\r
+                               goto bad;\r
+                       break;\r
+               }\r
+               p = next;\r
+       }\r
+       \r
+       /* If there is still anything left, this packet is bad. */\r
+       if (len != 0)\r
+               goto bad;\r
+       \r
+       /*\r
+       * OK, the Nak is good.  Now we can update state.\r
+       */\r
+       if (f->state != OPENED) {\r
+               if (looped_back) {\r
+                       if (++try.numloops >= lcp_loopbackfail) {\r
+                               LCPDEBUG((LOG_NOTICE, "Serial line is looped back.\n"));\r
+                               lcp_close(f->unit, "Loopback detected");\r
+                       }\r
+               } \r
+               else\r
+                       try.numloops = 0;\r
+               *go = try;\r
+       }\r
+       \r
+       return 1;\r
+       \r
+bad:\r
+       LCPDEBUG((LOG_WARNING, "lcp_nakci: received bad Nak!\n"));\r
+       return 0;\r
+}\r
+\r
+\r
+/*\r
+ * lcp_rejci - Peer has Rejected some of our CIs.\r
+ * This should not modify any state if the Reject is bad\r
+ * or if LCP is in the OPENED state.\r
+ *\r
+ * Returns:\r
+ *     0 - Reject was bad.\r
+ *     1 - Reject was good.\r
+ */\r
+static int lcp_rejci(fsm *f, u_char *p, int len)\r
+{\r
+       lcp_options *go = &lcp_gotoptions[f->unit];\r
+       u_char cichar;\r
+       u_short cishort;\r
+       u32_t cilong;\r
+       lcp_options try;                /* options to request next time */\r
+       \r
+       try = *go;\r
+       \r
+       /*\r
+       * Any Rejected CIs must be in exactly the same order that we sent.\r
+       * Check packet length and CI length at each step.\r
+       * If we find any deviations, then this packet is bad.\r
+       */\r
+#define REJCIVOID(opt, neg) \\r
+       if (go->neg && \\r
+                       len >= CILEN_VOID && \\r
+                       p[1] == CILEN_VOID && \\r
+                       p[0] == opt) { \\r
+               len -= CILEN_VOID; \\r
+               INCPTR(CILEN_VOID, p); \\r
+               try.neg = 0; \\r
+               LCPDEBUG((LOG_INFO, "lcp_rejci: void opt %d rejected\n", opt)); \\r
+       }\r
+#define REJCISHORT(opt, neg, val) \\r
+       if (go->neg && \\r
+                       len >= CILEN_SHORT && \\r
+                       p[1] == CILEN_SHORT && \\r
+                       p[0] == opt) { \\r
+               len -= CILEN_SHORT; \\r
+               INCPTR(2, p); \\r
+               GETSHORT(cishort, p); \\r
+               /* Check rejected value. */ \\r
+               if (cishort != val) \\r
+                       goto bad; \\r
+               try.neg = 0; \\r
+               LCPDEBUG((LOG_INFO,"lcp_rejci: short opt %d rejected\n", opt)); \\r
+       }\r
+#define REJCICHAP(opt, neg, val, digest) \\r
+       if (go->neg && \\r
+                       len >= CILEN_CHAP && \\r
+                       p[1] == CILEN_CHAP && \\r
+                       p[0] == opt) { \\r
+               len -= CILEN_CHAP; \\r
+               INCPTR(2, p); \\r
+               GETSHORT(cishort, p); \\r
+               GETCHAR(cichar, p); \\r
+               /* Check rejected value. */ \\r
+               if (cishort != val || cichar != digest) \\r
+                       goto bad; \\r
+               try.neg = 0; \\r
+               try.neg_upap = 0; \\r
+               LCPDEBUG((LOG_INFO,"lcp_rejci: chap opt %d rejected\n", opt)); \\r
+       }\r
+#define REJCILONG(opt, neg, val) \\r
+       if (go->neg && \\r
+                       len >= CILEN_LONG && \\r
+                       p[1] == CILEN_LONG && \\r
+                       p[0] == opt) { \\r
+               len -= CILEN_LONG; \\r
+               INCPTR(2, p); \\r
+               GETLONG(cilong, p); \\r
+               /* Check rejected value. */ \\r
+               if (cilong != val) \\r
+                       goto bad; \\r
+               try.neg = 0; \\r
+               LCPDEBUG((LOG_INFO,"lcp_rejci: long opt %d rejected\n", opt)); \\r
+       }\r
+#define REJCILQR(opt, neg, val) \\r
+       if (go->neg && \\r
+                       len >= CILEN_LQR && \\r
+                       p[1] == CILEN_LQR && \\r
+                       p[0] == opt) { \\r
+               len -= CILEN_LQR; \\r
+               INCPTR(2, p); \\r
+               GETSHORT(cishort, p); \\r
+               GETLONG(cilong, p); \\r
+               /* Check rejected value. */ \\r
+               if (cishort != PPP_LQR || cilong != val) \\r
+                       goto bad; \\r
+               try.neg = 0; \\r
+               LCPDEBUG((LOG_INFO,"lcp_rejci: LQR opt %d rejected\n", opt)); \\r
+       }\r
+#define REJCICBCP(opt, neg, val) \\r
+       if (go->neg && \\r
+                       len >= CILEN_CBCP && \\r
+                       p[1] == CILEN_CBCP && \\r
+                       p[0] == opt) { \\r
+               len -= CILEN_CBCP; \\r
+               INCPTR(2, p); \\r
+               GETCHAR(cichar, p); \\r
+               /* Check rejected value. */ \\r
+               if (cichar != val) \\r
+                       goto bad; \\r
+               try.neg = 0; \\r
+               LCPDEBUG((LOG_INFO,"lcp_rejci: Callback opt %d rejected\n", opt)); \\r
+       }\r
+       \r
+       REJCISHORT(CI_MRU, neg_mru, go->mru);\r
+       REJCILONG(CI_ASYNCMAP, neg_asyncmap, go->asyncmap);\r
+       REJCICHAP(CI_AUTHTYPE, neg_chap, PPP_CHAP, go->chap_mdtype);\r
+       if (!go->neg_chap) {\r
+               REJCISHORT(CI_AUTHTYPE, neg_upap, PPP_PAP);\r
+       }\r
+       REJCILQR(CI_QUALITY, neg_lqr, go->lqr_period);\r
+       REJCICBCP(CI_CALLBACK, neg_cbcp, CBCP_OPT);\r
+       REJCILONG(CI_MAGICNUMBER, neg_magicnumber, go->magicnumber);\r
+       REJCIVOID(CI_PCOMPRESSION, neg_pcompression);\r
+       REJCIVOID(CI_ACCOMPRESSION, neg_accompression);\r
+       \r
+       /*\r
+       * If there are any remaining CIs, then this packet is bad.\r
+       */\r
+       if (len != 0)\r
+               goto bad;\r
+       /*\r
+       * Now we can update state.\r
+       */\r
+       if (f->state != OPENED)\r
+               *go = try;\r
+       return 1;\r
+       \r
+bad:\r
+       LCPDEBUG((LOG_WARNING, "lcp_rejci: received bad Reject!\n"));\r
+       return 0;\r
+}\r
+\r
+\r
+/*\r
+ * lcp_reqci - Check the peer's requested CIs and send appropriate response.\r
+ *\r
+ * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified\r
+ * appropriately.  If reject_if_disagree is non-zero, doesn't return\r
+ * CONFNAK; returns CONFREJ if it can't return CONFACK.\r
+ */\r
+static int lcp_reqci(fsm *f, \r
+                                               u_char *inp,            /* Requested CIs */\r
+                                               int *lenp,                      /* Length of requested CIs */\r
+                                               int reject_if_disagree)\r
+{\r
+       lcp_options *go = &lcp_gotoptions[f->unit];\r
+       lcp_options *ho = &lcp_hisoptions[f->unit];\r
+       lcp_options *ao = &lcp_allowoptions[f->unit];\r
+       u_char *cip, *next;                     /* Pointer to current and next CIs */\r
+       int cilen, citype, cichar;      /* Parsed len, type, char value */\r
+       u_short cishort;                        /* Parsed short value */\r
+       u32_t cilong;                   /* Parse long value */\r
+       int rc = CONFACK;                       /* Final packet return code */\r
+       int orc;                                        /* Individual option return code */\r
+       u_char *p;                                      /* Pointer to next char to parse */\r
+       u_char *rejp;                           /* Pointer to next char in reject frame */\r
+       u_char *nakp;                           /* Pointer to next char in Nak frame */\r
+       int l = *lenp;                          /* Length left */\r
+#if TRACELCP > 0\r
+       char traceBuf[80];\r
+       int traceNdx = 0;\r
+#endif\r
+       \r
+       /*\r
+        * Reset all his options.\r
+        */\r
+       BZERO(ho, sizeof(*ho));\r
+       \r
+       /*\r
+        * Process all his options.\r
+        */\r
+       next = inp;\r
+       nakp = nak_buffer;\r
+       rejp = inp;\r
+       while (l) {\r
+               orc = CONFACK;                  /* Assume success */\r
+               cip = p = next;                 /* Remember begining of CI */\r
+               if (l < 2 ||                    /* Not enough data for CI header or */\r
+                               p[1] < 2 ||                     /*  CI length too small or */\r
+                               p[1] > l) {                     /*  CI length too big? */\r
+                       LCPDEBUG((LOG_WARNING, "lcp_reqci: bad CI length!\n"));\r
+                       orc = CONFREJ;          /* Reject bad CI */\r
+                       cilen = l;                      /* Reject till end of packet */\r
+                       l = 0;                  /* Don't loop again */\r
+                       citype = 0;\r
+                       goto endswitch;\r
+               }\r
+               GETCHAR(citype, p);             /* Parse CI type */\r
+               GETCHAR(cilen, p);              /* Parse CI length */\r
+               l -= cilen;                     /* Adjust remaining length */\r
+               next += cilen;                  /* Step to next CI */\r
+               \r
+               switch (citype) {               /* Check CI type */\r
+               case CI_MRU:\r
+                       if (!ao->neg_mru) {             /* Allow option? */\r
+                               LCPDEBUG((LOG_INFO, "lcp_reqci: Reject MRU - not allowed\n"));\r
+                               orc = CONFREJ;          /* Reject CI */\r
+                               break;\r
+                       } else if (cilen != CILEN_SHORT) {      /* Check CI length */\r
+                               LCPDEBUG((LOG_INFO, "lcp_reqci: Reject MRU - bad length\n"));\r
+                               orc = CONFREJ;          /* Reject CI */\r
+                               break;\r
+                       }\r
+                       GETSHORT(cishort, p);   /* Parse MRU */\r
+                       \r
+                       /*\r
+                        * He must be able to receive at least our minimum.\r
+                        * No need to check a maximum.  If he sends a large number,\r
+                        * we'll just ignore it.\r
+                        */\r
+                       if (cishort < PPP_MINMRU) {\r
+                               LCPDEBUG((LOG_INFO, "lcp_reqci: Nak - MRU too small\n"));\r
+                               orc = CONFNAK;          /* Nak CI */\r
+                               PUTCHAR(CI_MRU, nakp);\r
+                               PUTCHAR(CILEN_SHORT, nakp);\r
+                               PUTSHORT(PPP_MINMRU, nakp);     /* Give him a hint */\r
+                               break;\r
+                       }\r
+                       ho->neg_mru = 1;                /* Remember he sent MRU */\r
+                       ho->mru = cishort;              /* And remember value */\r
+#if TRACELCP > 0\r
+                       sprintf(&traceBuf[traceNdx], " MRU %d", cishort);\r
+                       traceNdx = strlen(traceBuf);\r
+#endif\r
+                       break;\r
+               \r
+               case CI_ASYNCMAP:\r
+                       if (!ao->neg_asyncmap) {\r
+                               LCPDEBUG((LOG_INFO, "lcp_reqci: Reject ASYNCMAP not allowed\n"));\r
+                               orc = CONFREJ;\r
+                               break;\r
+                       } else if (cilen != CILEN_LONG) {\r
+                               LCPDEBUG((LOG_INFO, "lcp_reqci: Reject ASYNCMAP bad length\n"));\r
+                               orc = CONFREJ;\r
+                               break;\r
+                       }\r
+                       GETLONG(cilong, p);\r
+                       \r
+                       /*\r
+                        * Asyncmap must have set at least the bits\r
+                        * which are set in lcp_allowoptions[unit].asyncmap.\r
+                        */\r
+                       if ((ao->asyncmap & ~cilong) != 0) {\r
+                               LCPDEBUG((LOG_INFO, "lcp_reqci: Nak ASYNCMAP %lX missing %lX\n", \r
+                                                       cilong, ao->asyncmap));\r
+                               orc = CONFNAK;\r
+                               PUTCHAR(CI_ASYNCMAP, nakp);\r
+                               PUTCHAR(CILEN_LONG, nakp);\r
+                               PUTLONG(ao->asyncmap | cilong, nakp);\r
+                               break;\r
+                       }\r
+                       ho->neg_asyncmap = 1;\r
+                       ho->asyncmap = cilong;\r
+#if TRACELCP > 0\r
+                       sprintf(&traceBuf[traceNdx], " ASYNCMAP=%lX", cilong);\r
+                       traceNdx = strlen(traceBuf);\r
+#endif\r
+                       break;\r
+               \r
+               case CI_AUTHTYPE:\r
+                       if (cilen < CILEN_SHORT) {\r
+                               LCPDEBUG((LOG_INFO, "lcp_reqci: Reject AUTHTYPE missing arg\n"));\r
+                               orc = CONFREJ;\r
+                               break;\r
+                       } else if (!(ao->neg_upap || ao->neg_chap)) {\r
+                               /*\r
+                                * Reject the option if we're not willing to authenticate.\r
+                                */\r
+                               LCPDEBUG((LOG_INFO, "lcp_reqci: Reject AUTHTYPE not allowed\n"));\r
+                               orc = CONFREJ;\r
+                               break;\r
+                       }\r
+                       GETSHORT(cishort, p);\r
+                       \r
+                       /*\r
+                        * Authtype must be UPAP or CHAP.\r
+                        *\r
+                        * Note: if both ao->neg_upap and ao->neg_chap are set,\r
+                        * and the peer sends a Configure-Request with two\r
+                        * authenticate-protocol requests, one for CHAP and one\r
+                        * for UPAP, then we will reject the second request.\r
+                        * Whether we end up doing CHAP or UPAP depends then on\r
+                        * the ordering of the CIs in the peer's Configure-Request.\r
+                        */\r
+                       \r
+                       if (cishort == PPP_PAP) {\r
+                               if (ho->neg_chap) {     /* we've already accepted CHAP */\r
+                                       LCPDEBUG((LOG_WARNING, "lcp_reqci: Reject AUTHTYPE PAP already accepted\n"));\r
+                                       orc = CONFREJ;\r
+                                       break;\r
+                               } else if (cilen != CILEN_SHORT) {\r
+                                       LCPDEBUG((LOG_WARNING, "lcp_reqci: Reject AUTHTYPE PAP bad len\n"));\r
+                                       orc = CONFREJ;\r
+                                       break;\r
+                               }\r
+                               if (!ao->neg_upap) {    /* we don't want to do PAP */\r
+                                       LCPDEBUG((LOG_WARNING, "lcp_reqci: Nak AUTHTYPE PAP not allowed\n"));\r
+                                       orc = CONFNAK;  /* NAK it and suggest CHAP */\r
+                                       PUTCHAR(CI_AUTHTYPE, nakp);\r
+                                       PUTCHAR(CILEN_CHAP, nakp);\r
+                                       PUTSHORT(PPP_CHAP, nakp);\r
+                                       PUTCHAR(ao->chap_mdtype, nakp);\r
+                                       break;\r
+                               }\r
+                               ho->neg_upap = 1;\r
+#if TRACELCP > 0\r
+                               sprintf(&traceBuf[traceNdx], " PAP (%X)", cishort);\r
+                               traceNdx = strlen(traceBuf);\r
+#endif\r
+                               break;\r
+                       }\r
+                       if (cishort == PPP_CHAP) {\r
+                               if (ho->neg_upap) {     /* we've already accepted PAP */\r
+                                       LCPDEBUG((LOG_WARNING, "lcp_reqci: Reject AUTHTYPE CHAP accepted PAP\n"));\r
+                                       orc = CONFREJ;\r
+                                       break;\r
+                               } else if (cilen != CILEN_CHAP) {\r
+                                       LCPDEBUG((LOG_WARNING, "lcp_reqci: Reject AUTHTYPE CHAP bad len\n"));\r
+                                       orc = CONFREJ;\r
+                                       break;\r
+                               }\r
+                               if (!ao->neg_chap) {    /* we don't want to do CHAP */\r
+                                       LCPDEBUG((LOG_WARNING, "lcp_reqci: Nak AUTHTYPE CHAP not allowed\n"));\r
+                                       orc = CONFNAK;  /* NAK it and suggest PAP */\r
+                                       PUTCHAR(CI_AUTHTYPE, nakp);\r
+                                       PUTCHAR(CILEN_SHORT, nakp);\r
+                                       PUTSHORT(PPP_PAP, nakp);\r
+                                       break;\r
+                               }\r
+                               GETCHAR(cichar, p);     /* get digest type*/\r
+                               if (cichar != CHAP_DIGEST_MD5\r
+#ifdef CHAPMS\r
+                                               && cichar != CHAP_MICROSOFT\r
+#endif\r
+                               ) {\r
+                                       LCPDEBUG((LOG_WARNING, "lcp_reqci: Nak AUTHTYPE CHAP digest=%d\n", cichar));\r
+                                       orc = CONFNAK;\r
+                                       PUTCHAR(CI_AUTHTYPE, nakp);\r
+                                       PUTCHAR(CILEN_CHAP, nakp);\r
+                                       PUTSHORT(PPP_CHAP, nakp);\r
+                                       PUTCHAR(ao->chap_mdtype, nakp);\r
+                                       break;\r
+                               }\r
+#if TRACELCP > 0\r
+                               sprintf(&traceBuf[traceNdx], " CHAP %X,%d", cishort, cichar);\r
+                               traceNdx = strlen(traceBuf);\r
+#endif\r
+                               ho->chap_mdtype = cichar; /* save md type */\r
+                               ho->neg_chap = 1;\r
+                               break;\r
+                       }\r
+                       \r
+                       /*\r
+                        * We don't recognize the protocol they're asking for.\r
+                        * Nak it with something we're willing to do.\r
+                        * (At this point we know ao->neg_upap || ao->neg_chap.)\r
+                        */\r
+                       orc = CONFNAK;\r
+                       PUTCHAR(CI_AUTHTYPE, nakp);\r
+                       if (ao->neg_chap) {\r
+                               LCPDEBUG((LOG_WARNING, "lcp_reqci: Nak AUTHTYPE %d req CHAP\n", cishort));\r
+                               PUTCHAR(CILEN_CHAP, nakp);\r
+                               PUTSHORT(PPP_CHAP, nakp);\r
+                               PUTCHAR(ao->chap_mdtype, nakp);\r
+                       } \r
+                       else {\r
+                               LCPDEBUG((LOG_WARNING, "lcp_reqci: Nak AUTHTYPE %d req PAP\n", cishort));\r
+                               PUTCHAR(CILEN_SHORT, nakp);\r
+                               PUTSHORT(PPP_PAP, nakp);\r
+                       }\r
+                       break;\r
+               \r
+               case CI_QUALITY:\r
+                       GETSHORT(cishort, p);\r
+                       GETLONG(cilong, p);\r
+#if TRACELCP > 0\r
+                       sprintf(&traceBuf[traceNdx], " QUALITY (%x %x)", cishort, (unsigned int) cilong);\r
+                       traceNdx = strlen(traceBuf);\r
+#endif\r
+\r
+                       if (!ao->neg_lqr ||\r
+                                       cilen != CILEN_LQR) {\r
+                               orc = CONFREJ;\r
+                               break;\r
+                       }\r
+                       \r
+                       /*\r
+                        * Check the protocol and the reporting period.\r
+                        * XXX When should we Nak this, and what with?\r
+                        */\r
+                       if (cishort != PPP_LQR) {\r
+                               orc = CONFNAK;\r
+                               PUTCHAR(CI_QUALITY, nakp);\r
+                               PUTCHAR(CILEN_LQR, nakp);\r
+                               PUTSHORT(PPP_LQR, nakp);\r
+                               PUTLONG(ao->lqr_period, nakp);\r
+                               break;\r
+                       }\r
+                       break;\r
+               \r
+               case CI_MAGICNUMBER:\r
+                       if (!(ao->neg_magicnumber || go->neg_magicnumber) ||\r
+                                       cilen != CILEN_LONG) {\r
+                               orc = CONFREJ;\r
+                               break;\r
+                       }\r
+                       GETLONG(cilong, p);\r
+#if TRACELCP > 0\r
+                       sprintf(&traceBuf[traceNdx], " MAGICNUMBER (%lX)", cilong);\r
+                       traceNdx = strlen(traceBuf);\r
+#endif\r
+\r
+                       /*\r
+                        * He must have a different magic number.\r
+                        */\r
+                       if (go->neg_magicnumber &&\r
+                                       cilong == go->magicnumber) {\r
+                               cilong = magic();       /* Don't put magic() inside macro! */\r
+                               orc = CONFNAK;\r
+                               PUTCHAR(CI_MAGICNUMBER, nakp);\r
+                               PUTCHAR(CILEN_LONG, nakp);\r
+                               PUTLONG(cilong, nakp);\r
+                               break;\r
+                       }\r
+                       ho->neg_magicnumber = 1;\r
+                       ho->magicnumber = cilong;\r
+                       break;\r
+               \r
+               \r
+               case CI_PCOMPRESSION:\r
+#if TRACELCP > 0\r
+                       sprintf(&traceBuf[traceNdx], " PCOMPRESSION");\r
+                       traceNdx = strlen(traceBuf);\r
+#endif\r
+                       if (!ao->neg_pcompression ||\r
+                                       cilen != CILEN_VOID) {\r
+                               orc = CONFREJ;\r
+                               break;\r
+                       }\r
+                       ho->neg_pcompression = 1;\r
+                       break;\r
+               \r
+               case CI_ACCOMPRESSION:\r
+#if TRACELCP > 0\r
+                       sprintf(&traceBuf[traceNdx], " ACCOMPRESSION");\r
+                       traceNdx = strlen(traceBuf);\r
+#endif\r
+                       if (!ao->neg_accompression ||\r
+                                       cilen != CILEN_VOID) {\r
+                               orc = CONFREJ;\r
+                               break;\r
+                       }\r
+                       ho->neg_accompression = 1;\r
+                       break;\r
+               \r
+               case CI_MRRU:\r
+#if TRACELCP > 0\r
+                       sprintf(&traceBuf[traceNdx], " CI_MRRU");\r
+                       traceNdx = strlen(traceBuf);\r
+#endif\r
+                       orc = CONFREJ;\r
+                       break;\r
+               \r
+               case CI_SSNHF:\r
+#if TRACELCP > 0\r
+                       sprintf(&traceBuf[traceNdx], " CI_SSNHF");\r
+                       traceNdx = strlen(traceBuf);\r
+#endif\r
+                       orc = CONFREJ;\r
+                       break;\r
+               \r
+               case CI_EPDISC:\r
+#if TRACELCP > 0\r
+                       sprintf(&traceBuf[traceNdx], " CI_EPDISC");\r
+                       traceNdx = strlen(traceBuf);\r
+#endif\r
+                       orc = CONFREJ;\r
+                       break;\r
+               \r
+               default:\r
+#if TRACELCP\r
+                       sprintf(&traceBuf[traceNdx], " unknown %d", citype);\r
+                       traceNdx = strlen(traceBuf);\r
+#endif\r
+                       orc = CONFREJ;\r
+                       break;\r
+               }\r
+               \r
+       endswitch:\r
+#if TRACELCP\r
+               if (traceNdx >= 80 - 32) {\r
+                       LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd%s\n", traceBuf));\r
+                       traceNdx = 0;\r
+               }\r
+#endif\r
+               if (orc == CONFACK &&           /* Good CI */\r
+                               rc != CONFACK)          /*  but prior CI wasnt? */\r
+                       continue;                       /* Don't send this one */\r
+               \r
+               if (orc == CONFNAK) {           /* Nak this CI? */\r
+                       if (reject_if_disagree  /* Getting fed up with sending NAKs? */\r
+                                       && citype != CI_MAGICNUMBER) {\r
+                               orc = CONFREJ;          /* Get tough if so */\r
+                       } \r
+                       else {\r
+                               if (rc == CONFREJ)      /* Rejecting prior CI? */\r
+                                       continue;               /* Don't send this one */\r
+                               rc = CONFNAK;\r
+                       }\r
+               }\r
+               if (orc == CONFREJ) {           /* Reject this CI */\r
+                       rc = CONFREJ;\r
+                       if (cip != rejp)                /* Need to move rejected CI? */\r
+                               BCOPY(cip, rejp, cilen); /* Move it */\r
+                       INCPTR(cilen, rejp);    /* Update output pointer */\r
+               }\r
+       }\r
+       \r
+       /*\r
+        * If we wanted to send additional NAKs (for unsent CIs), the\r
+        * code would go here.  The extra NAKs would go at *nakp.\r
+        * At present there are no cases where we want to ask the\r
+        * peer to negotiate an option.\r
+        */\r
+       \r
+       switch (rc) {\r
+       case CONFACK:\r
+               *lenp = (int)(next - inp);\r
+               break;\r
+       case CONFNAK:\r
+               /*\r
+                * Copy the Nak'd options from the nak_buffer to the caller's buffer.\r
+                */\r
+               *lenp = (int)(nakp - nak_buffer);\r
+               BCOPY(nak_buffer, inp, *lenp);\r
+               break;\r
+       case CONFREJ:\r
+               *lenp = (int)(rejp - inp);\r
+               break;\r
+       }\r
+       \r
+#if TRACELCP > 0\r
+       if (traceNdx > 0) {\r
+               LCPDEBUG((LOG_INFO, "lcp_reqci: %s\n", traceBuf));\r
+       }\r
+#endif\r
+       LCPDEBUG((LOG_INFO, "lcp_reqci: returning CONF%s.\n", CODENAME(rc)));\r
+       return (rc);                    /* Return final code */\r
+}\r
+\r
+\r
+/*\r
+ * lcp_up - LCP has come UP.\r
+ */\r
+static void lcp_up(fsm *f)\r
+{\r
+       lcp_options *wo = &lcp_wantoptions[f->unit];\r
+       lcp_options *ho = &lcp_hisoptions[f->unit];\r
+       lcp_options *go = &lcp_gotoptions[f->unit];\r
+       lcp_options *ao = &lcp_allowoptions[f->unit];\r
+       \r
+       if (!go->neg_magicnumber)\r
+               go->magicnumber = 0;\r
+       if (!ho->neg_magicnumber)\r
+               ho->magicnumber = 0;\r
+       \r
+       /*\r
+       * Set our MTU to the smaller of the MTU we wanted and\r
+       * the MRU our peer wanted.  If we negotiated an MRU,\r
+       * set our MRU to the larger of value we wanted and\r
+       * the value we got in the negotiation.\r
+       */\r
+       ppp_send_config(f->unit, LWIP_MIN(ao->mru, (ho->neg_mru? ho->mru: PPP_MRU)),\r
+                               (ho->neg_asyncmap? ho->asyncmap: 0xffffffffl),\r
+                               ho->neg_pcompression, ho->neg_accompression);\r
+       /*\r
+       * If the asyncmap hasn't been negotiated, we really should\r
+       * set the receive asyncmap to ffffffff, but we set it to 0\r
+       * for backwards contemptibility.\r
+       */\r
+       ppp_recv_config(f->unit, (go->neg_mru? LWIP_MAX(wo->mru, go->mru): PPP_MRU),\r
+                               (go->neg_asyncmap? go->asyncmap: 0x00000000),\r
+                               go->neg_pcompression, go->neg_accompression);\r
+       \r
+       if (ho->neg_mru)\r
+               peer_mru[f->unit] = ho->mru;\r
+       \r
+       lcp_echo_lowerup(f->unit);  /* Enable echo messages */\r
+       \r
+       link_established(f->unit);\r
+}\r
+\r
+\r
+/*\r
+ * lcp_down - LCP has gone DOWN.\r
+ *\r
+ * Alert other protocols.\r
+ */\r
+static void lcp_down(fsm *f)\r
+{\r
+       lcp_options *go = &lcp_gotoptions[f->unit];\r
+       \r
+       lcp_echo_lowerdown(f->unit);\r
+       \r
+       link_down(f->unit);\r
+       \r
+       ppp_send_config(f->unit, PPP_MRU, 0xffffffffl, 0, 0);\r
+       ppp_recv_config(f->unit, PPP_MRU,\r
+                               (go->neg_asyncmap? go->asyncmap: 0x00000000),\r
+                               go->neg_pcompression, go->neg_accompression);\r
+       peer_mru[f->unit] = PPP_MRU;\r
+}\r
+\r
+\r
+/*\r
+ * lcp_starting - LCP needs the lower layer up.\r
+ */\r
+static void lcp_starting(fsm *f)\r
+{\r
+       link_required(f->unit);\r
+}\r
+\r
+\r
+/*\r
+ * lcp_finished - LCP has finished with the lower layer.\r
+ */\r
+static void lcp_finished(fsm *f)\r
+{\r
+       link_terminated(f->unit);\r
+}\r
+\r
+\r
+#if 0\r
+/*\r
+ * print_string - print a readable representation of a string using\r
+ * printer.\r
+ */\r
+static void print_string(\r
+    char *p,\r
+    int len,\r
+    void (*printer) (void *, char *, ...),\r
+    void *arg\r
+)\r
+{\r
+    int c;\r
+    \r
+    printer(arg, "\"");\r
+    for (; len > 0; --len) {\r
+        c = *p++;\r
+        if (' ' <= c && c <= '~') {\r
+            if (c == '\\' || c == '"')\r
+                printer(arg, "\\");\r
+            printer(arg, "%c", c);\r
+        } else {\r
+            switch (c) {\r
+            case '\n':\r
+                printer(arg, "\\n");\r
+                break;\r
+            case '\r':\r
+                printer(arg, "\\r");\r
+                break;\r
+            case '\t':\r
+                printer(arg, "\\t");\r
+                break;\r
+            default:\r
+                printer(arg, "\\%.3o", c);\r
+            }\r
+        }\r
+    }\r
+    printer(arg, "\"");\r
+}\r
+\r
+\r
+/*\r
+ * lcp_printpkt - print the contents of an LCP packet.\r
+ */\r
+static char *lcp_codenames[] = {\r
+       "ConfReq", "ConfAck", "ConfNak", "ConfRej",\r
+       "TermReq", "TermAck", "CodeRej", "ProtRej",\r
+       "EchoReq", "EchoRep", "DiscReq"\r
+};\r
+\r
+static int lcp_printpkt(\r
+       u_char *p,\r
+       int plen,\r
+       void (*printer) (void *, char *, ...),\r
+       void *arg\r
+)\r
+{\r
+       int code, id, len, olen;\r
+       u_char *pstart, *optend;\r
+       u_short cishort;\r
+       u32_t cilong;\r
+       \r
+       if (plen < HEADERLEN)\r
+               return 0;\r
+       pstart = p;\r
+       GETCHAR(code, p);\r
+       GETCHAR(id, p);\r
+       GETSHORT(len, p);\r
+       if (len < HEADERLEN || len > plen)\r
+               return 0;\r
+       \r
+       if (code >= 1 && code <= sizeof(lcp_codenames) / sizeof(char *))\r
+               printer(arg, " %s", lcp_codenames[code-1]);\r
+       else\r
+               printer(arg, " code=0x%x", code);\r
+       printer(arg, " id=0x%x", id);\r
+       len -= HEADERLEN;\r
+       switch (code) {\r
+       case CONFREQ:\r
+       case CONFACK:\r
+       case CONFNAK:\r
+       case CONFREJ:\r
+               /* print option list */\r
+               while (len >= 2) {\r
+                       GETCHAR(code, p);\r
+                       GETCHAR(olen, p);\r
+                       p -= 2;\r
+                       if (olen < 2 || olen > len) {\r
+                               break;\r
+                       }\r
+                       printer(arg, " <");\r
+                       len -= olen;\r
+                       optend = p + olen;\r
+                       switch (code) {\r
+                       case CI_MRU:\r
+                               if (olen == CILEN_SHORT) {\r
+                                       p += 2;\r
+                                       GETSHORT(cishort, p);\r
+                                       printer(arg, "mru %d", cishort);\r
+                               }\r
+                               break;\r
+                       case CI_ASYNCMAP:\r
+                               if (olen == CILEN_LONG) {\r
+                                       p += 2;\r
+                                       GETLONG(cilong, p);\r
+                                       printer(arg, "asyncmap 0x%lx", cilong);\r
+                               }\r
+                               break;\r
+                       case CI_AUTHTYPE:\r
+                               if (olen >= CILEN_SHORT) {\r
+                                       p += 2;\r
+                                       printer(arg, "auth ");\r
+                                       GETSHORT(cishort, p);\r
+                                       switch (cishort) {\r
+                                       case PPP_PAP:\r
+                                               printer(arg, "pap");\r
+                                               break;\r
+                                       case PPP_CHAP:\r
+                                               printer(arg, "chap");\r
+                                               break;\r
+                                       default:\r
+                                               printer(arg, "0x%x", cishort);\r
+                                       }\r
+                               }\r
+                               break;\r
+                       case CI_QUALITY:\r
+                               if (olen >= CILEN_SHORT) {\r
+                                       p += 2;\r
+                                       printer(arg, "quality ");\r
+                                       GETSHORT(cishort, p);\r
+                                       switch (cishort) {\r
+                                       case PPP_LQR:\r
+                                               printer(arg, "lqr");\r
+                                               break;\r
+                                       default:\r
+                                               printer(arg, "0x%x", cishort);\r
+                                       }\r
+                               }\r
+                               break;\r
+                       case CI_CALLBACK:\r
+                               if (olen >= CILEN_CHAR) {\r
+                                       p += 2;\r
+                                       printer(arg, "callback ");\r
+                                       GETSHORT(cishort, p);\r
+                                       switch (cishort) {\r
+                                       case CBCP_OPT:\r
+                                               printer(arg, "CBCP");\r
+                                               break;\r
+                                       default:\r
+                                               printer(arg, "0x%x", cishort);\r
+                                       }\r
+                               }\r
+                               break;\r
+                       case CI_MAGICNUMBER:\r
+                               if (olen == CILEN_LONG) {\r
+                                       p += 2;\r
+                                       GETLONG(cilong, p);\r
+                                       printer(arg, "magic 0x%x", cilong);\r
+                               }\r
+                               break;\r
+                       case CI_PCOMPRESSION:\r
+                               if (olen == CILEN_VOID) {\r
+                                       p += 2;\r
+                                       printer(arg, "pcomp");\r
+                               }\r
+                               break;\r
+                       case CI_ACCOMPRESSION:\r
+                               if (olen == CILEN_VOID) {\r
+                                       p += 2;\r
+                                       printer(arg, "accomp");\r
+                               }\r
+                               break;\r
+                       }\r
+                       while (p < optend) {\r
+                               GETCHAR(code, p);\r
+                               printer(arg, " %.2x", code);\r
+                       }\r
+                       printer(arg, ">");\r
+               }\r
+               break;\r
+       \r
+       case TERMACK:\r
+       case TERMREQ:\r
+               if (len > 0 && *p >= ' ' && *p < 0x7f) {\r
+                       printer(arg, " ");\r
+                       print_string((char*)p, len, printer, arg);\r
+                       p += len;\r
+                       len = 0;\r
+               }\r
+               break;\r
+       \r
+       case ECHOREQ:\r
+       case ECHOREP:\r
+       case DISCREQ:\r
+               if (len >= 4) {\r
+                       GETLONG(cilong, p);\r
+                       printer(arg, " magic=0x%x", cilong);\r
+                       p += 4;\r
+                       len -= 4;\r
+               }\r
+               break;\r
+       }\r
+       \r
+       /* print the rest of the bytes in the packet */\r
+       for (; len > 0; --len) {\r
+               GETCHAR(code, p);\r
+               printer(arg, " %.2x", code);\r
+       }\r
+       \r
+       return (int)(p - pstart);\r
+}\r
+#endif\r
+\r
+/*\r
+ * Time to shut down the link because there is nothing out there.\r
+ */\r
+\r
+static void LcpLinkFailure (fsm *f)\r
+{\r
+       if (f->state == OPENED) {\r
+               LCPDEBUG((LOG_INFO, "No response to %d echo-requests\n", lcp_echos_pending));\r
+               LCPDEBUG((LOG_NOTICE, "Serial link appears to be disconnected.\n"));\r
+               lcp_close(f->unit, "Peer not responding");\r
+       }\r
+}\r
+\r
+/*\r
+ * Timer expired for the LCP echo requests from this process.\r
+ */\r
+\r
+static void LcpEchoCheck (fsm *f)\r
+{\r
+       LcpSendEchoRequest (f);\r
+       \r
+       /*\r
+        * Start the timer for the next interval.\r
+        */\r
+       LWIP_ASSERT("lcp_echo_timer_running == 0", lcp_echo_timer_running == 0);\r
+\r
+       TIMEOUT (LcpEchoTimeout, f, lcp_echo_interval);\r
+       lcp_echo_timer_running = 1;\r
+}\r
+\r
+/*\r
+ * LcpEchoTimeout - Timer expired on the LCP echo\r
+ */\r
+\r
+static void LcpEchoTimeout (void *arg)\r
+{\r
+       if (lcp_echo_timer_running != 0) {\r
+               lcp_echo_timer_running = 0;\r
+               LcpEchoCheck ((fsm *) arg);\r
+       }\r
+}\r
+\r
+/*\r
+ * LcpEchoReply - LCP has received a reply to the echo\r
+ */\r
+static void lcp_received_echo_reply (fsm *f, int id, u_char *inp, int len)\r
+{\r
+       u32_t magic;\r
+       \r
+       (void)id;\r
+\r
+       /* Check the magic number - don't count replies from ourselves. */\r
+       if (len < 4) {\r
+               LCPDEBUG((LOG_WARNING, "lcp: received short Echo-Reply, length %d\n", len));\r
+               return;\r
+       }\r
+       GETLONG(magic, inp);\r
+       if (lcp_gotoptions[f->unit].neg_magicnumber\r
+                       && magic == lcp_gotoptions[f->unit].magicnumber) {\r
+               LCPDEBUG((LOG_WARNING, "appear to have received our own echo-reply!\n"));\r
+               return;\r
+       }\r
+       \r
+       /* Reset the number of outstanding echo frames */\r
+       lcp_echos_pending = 0;\r
+}\r
+\r
+/*\r
+ * LcpSendEchoRequest - Send an echo request frame to the peer\r
+ */\r
+\r
+static void LcpSendEchoRequest (fsm *f)\r
+{\r
+       u32_t lcp_magic;\r
+       u_char pkt[4], *pktp;\r
+       \r
+       /*\r
+       * Detect the failure of the peer at this point.\r
+       */\r
+       if (lcp_echo_fails != 0) {\r
+               if (lcp_echos_pending++ >= lcp_echo_fails) {\r
+                       LcpLinkFailure(f);\r
+                       lcp_echos_pending = 0;\r
+               }\r
+       }\r
+       \r
+       /*\r
+       * Make and send the echo request frame.\r
+       */\r
+       if (f->state == OPENED) {\r
+               lcp_magic = lcp_gotoptions[f->unit].magicnumber;\r
+               pktp = pkt;\r
+               PUTLONG(lcp_magic, pktp);\r
+               fsm_sdata(f, ECHOREQ, (u_char)(lcp_echo_number++ & 0xFF), pkt, (int)(pktp - pkt));\r
+       }\r
+}\r
+\r
+/*\r
+ * lcp_echo_lowerup - Start the timer for the LCP frame\r
+ */\r
+\r
+static void lcp_echo_lowerup (int unit)\r
+{\r
+       fsm *f = &lcp_fsm[unit];\r
+       \r
+       /* Clear the parameters for generating echo frames */\r
+       lcp_echos_pending      = 0;\r
+       lcp_echo_number        = 0;\r
+       lcp_echo_timer_running = 0;\r
+       \r
+       /* If a timeout interval is specified then start the timer */\r
+       if (lcp_echo_interval != 0)\r
+               LcpEchoCheck (f);\r
+}\r
+\r
+/*\r
+ * lcp_echo_lowerdown - Stop the timer for the LCP frame\r
+ */\r
+\r
+static void lcp_echo_lowerdown (int unit)\r
+{\r
+       fsm *f = &lcp_fsm[unit];\r
+       \r
+       if (lcp_echo_timer_running != 0) {\r
+               UNTIMEOUT (LcpEchoTimeout, f);\r
+               lcp_echo_timer_running = 0;\r
+       }\r
+}\r
+\r
+#endif /* PPP_SUPPORT */\r
index 3876d39ae890439c4c3878c4de91d97ce7d5b492..2c0c34007762eb73afd05c4f6f19dbaf67b100fd 100644 (file)
-/*****************************************************************************
-* lcp.h - Network Link Control Protocol header file.
-*
-* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
-* portions Copyright (c) 1997 Global Election Systems Inc.
-*
-* The authors hereby grant permission to use, copy, modify, distribute,
-* and license this software and its documentation for any purpose, provided
-* that existing copyright notices are retained in all copies and that this
-* notice and the following disclaimer are included verbatim in any 
-* distributions. No written agreement, license, or royalty fee is required
-* for any of the authorized uses.
-*
-* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *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 CONTRIBUTORS 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.
-*
-******************************************************************************
-* REVISION HISTORY
-*
-* 03-01-01 Marc Boucher <marc@mbsi.ca>
-*   Ported to lwIP.
-* 97-11-05 Guy Lancaster <glanca@gesn.com>, Global Election Systems Inc.
-*      Original derived from BSD codes.
-*****************************************************************************/
-/*
- * lcp.h - Link Control Protocol definitions.
- *
- * Copyright (c) 1989 Carnegie Mellon University.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by Carnegie Mellon University.  The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * $Id: lcp.h,v 1.1 2003/05/27 14:37:56 jani Exp $
- */
-
-#ifndef LCP_H
-#define LCP_H
-
-
-/*************************
-*** PUBLIC DEFINITIONS ***
-*************************/
-/*
- * Options.
- */
-#define CI_MRU         1       /* Maximum Receive Unit */
-#define CI_ASYNCMAP    2       /* Async Control Character Map */
-#define CI_AUTHTYPE    3       /* Authentication Type */
-#define CI_QUALITY     4       /* Quality Protocol */
-#define CI_MAGICNUMBER 5       /* Magic Number */
-#define CI_PCOMPRESSION        7       /* Protocol Field Compression */
-#define CI_ACCOMPRESSION 8     /* Address/Control Field Compression */
-#define CI_CALLBACK    13      /* callback */
-#define CI_MRRU                17      /* max reconstructed receive unit; multilink */
-#define CI_SSNHF       18      /* short sequence numbers for multilink */
-#define CI_EPDISC      19      /* endpoint discriminator */
-
-/*
- * LCP-specific packet types.
- */
-#define PROTREJ                8       /* Protocol Reject */
-#define ECHOREQ                9       /* Echo Request */
-#define ECHOREP                10      /* Echo Reply */
-#define DISCREQ                11      /* Discard Request */
-#define CBCP_OPT       6       /* Use callback control protocol */
-
-
-/************************
-*** PUBLIC DATA TYPES ***
-************************/
-
-/*
- * The state of options is described by an lcp_options structure.
- */
-typedef struct lcp_options {
-    u_int passive : 1;                 /* Don't die if we don't get a response */
-    u_int silent : 1;                          /* Wait for the other end to start first */
-    u_int restart : 1;                 /* Restart vs. exit after close */
-    u_int neg_mru : 1;                 /* Negotiate the MRU? */
-    u_int neg_asyncmap : 1;            /* Negotiate the async map? */
-    u_int neg_upap : 1;                        /* Ask for UPAP authentication? */
-    u_int neg_chap : 1;                        /* Ask for CHAP authentication? */
-    u_int neg_magicnumber : 1; /* Ask for magic number? */
-    u_int neg_pcompression : 1;        /* HDLC Protocol Field Compression? */
-    u_int neg_accompression : 1;       /* HDLC Address/Control Field Compression? */
-    u_int neg_lqr : 1;                 /* Negotiate use of Link Quality Reports */
-    u_int neg_cbcp : 1;                        /* Negotiate use of CBCP */
-#ifdef PPP_MULTILINK
-    u_int neg_mrru : 1;                        /* Negotiate multilink MRRU */
-    u_int neg_ssnhf : 1;               /* Negotiate short sequence numbers */
-    u_int neg_endpoint : 1;            /* Negotiate endpoint discriminator */
-#endif
-    u_short mru;                       /* Value of MRU */
-#ifdef PPP_MULTILINK
-    u_short mrru;                      /* Value of MRRU, and multilink enable */
-#endif
-    u_char chap_mdtype;                        /* which MD type (hashing algorithm) */
-    u32_t asyncmap;                    /* Value of async map */
-    u32_t magicnumber;
-    int numloops;                              /* Number of loops during magic number neg. */
-    u32_t lqr_period;          /* Reporting period for LQR 1/100ths second */
-#ifdef PPP_MULTILINK
-    struct epdisc endpoint;    /* endpoint discriminator */
-#endif
-} lcp_options;
-
-/*
- * Values for phase from BSD pppd.h based on RFC 1661.
- */
-typedef enum {
-       PHASE_DEAD = 0,
-       PHASE_INITIALIZE,
-       PHASE_ESTABLISH,
-       PHASE_AUTHENTICATE,
-       PHASE_CALLBACK,
-       PHASE_NETWORK,
-       PHASE_TERMINATE
-} LinkPhase;
-
-
-/*****************************
-*** PUBLIC DATA STRUCTURES ***
-*****************************/
-
-extern LinkPhase lcp_phase[NUM_PPP];   /* Phase of link session (RFC 1661) */
-extern lcp_options lcp_wantoptions[];
-extern lcp_options lcp_gotoptions[];
-extern lcp_options lcp_allowoptions[];
-extern lcp_options lcp_hisoptions[];
-extern ext_accm xmit_accm[];
-
-
-/***********************
-*** PUBLIC FUNCTIONS ***
-***********************/
-
-void lcp_init (int);
-void lcp_open (int);
-void lcp_close (int, char *);
-void lcp_lowerup (int);
-void lcp_lowerdown (int);
-void lcp_sprotrej (int, u_char *, int);        /* send protocol reject */
-
-extern struct protent lcp_protent;
-
-/* Default number of times we receive our magic number from the peer
-   before deciding the link is looped-back. */
-#define DEFLOOPBACKFAIL        10
-
-#endif /* LCP_H */
-
+/*****************************************************************************\r
+* lcp.h - Network Link Control Protocol header file.\r
+*\r
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.\r
+* portions Copyright (c) 1997 Global Election Systems Inc.\r
+*\r
+* The authors hereby grant permission to use, copy, modify, distribute,\r
+* and license this software and its documentation for any purpose, provided\r
+* that existing copyright notices are retained in all copies and that this\r
+* notice and the following disclaimer are included verbatim in any \r
+* distributions. No written agreement, license, or royalty fee is required\r
+* for any of the authorized uses.\r
+*\r
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR\r
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+*\r
+******************************************************************************\r
+* REVISION HISTORY\r
+*\r
+* 03-01-01 Marc Boucher <marc@mbsi.ca>\r
+*   Ported to lwIP.\r
+* 97-11-05 Guy Lancaster <glanca@gesn.com>, Global Election Systems Inc.\r
+*      Original derived from BSD codes.\r
+*****************************************************************************/\r
+/*\r
+ * lcp.h - Link Control Protocol definitions.\r
+ *\r
+ * Copyright (c) 1989 Carnegie Mellon University.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms are permitted\r
+ * provided that the above copyright notice and this paragraph are\r
+ * duplicated in all such forms and that any documentation,\r
+ * advertising materials, and other materials related to such\r
+ * distribution and use acknowledge that the software was developed\r
+ * by Carnegie Mellon University.  The name of the\r
+ * University may not be used to endorse or promote products derived\r
+ * from this software without specific prior written permission.\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR\r
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r
+ *\r
+ * $Id: lcp.h,v 1.1 2003/05/27 14:37:56 jani Exp $\r
+ */\r
+\r
+#ifndef LCP_H\r
+#define LCP_H\r
+\r
+\r
+/*************************\r
+*** PUBLIC DEFINITIONS ***\r
+*************************/\r
+/*\r
+ * Options.\r
+ */\r
+#define CI_MRU         1       /* Maximum Receive Unit */\r
+#define CI_ASYNCMAP    2       /* Async Control Character Map */\r
+#define CI_AUTHTYPE    3       /* Authentication Type */\r
+#define CI_QUALITY     4       /* Quality Protocol */\r
+#define CI_MAGICNUMBER 5       /* Magic Number */\r
+#define CI_PCOMPRESSION        7       /* Protocol Field Compression */\r
+#define CI_ACCOMPRESSION 8     /* Address/Control Field Compression */\r
+#define CI_CALLBACK    13      /* callback */\r
+#define CI_MRRU                17      /* max reconstructed receive unit; multilink */\r
+#define CI_SSNHF       18      /* short sequence numbers for multilink */\r
+#define CI_EPDISC      19      /* endpoint discriminator */\r
+\r
+/*\r
+ * LCP-specific packet types.\r
+ */\r
+#define PROTREJ                8       /* Protocol Reject */\r
+#define ECHOREQ                9       /* Echo Request */\r
+#define ECHOREP                10      /* Echo Reply */\r
+#define DISCREQ                11      /* Discard Request */\r
+#define CBCP_OPT       6       /* Use callback control protocol */\r
+\r
+\r
+/************************\r
+*** PUBLIC DATA TYPES ***\r
+************************/\r
+\r
+/*\r
+ * The state of options is described by an lcp_options structure.\r
+ */\r
+typedef struct lcp_options {\r
+    u_int passive : 1;                 /* Don't die if we don't get a response */\r
+    u_int silent : 1;                          /* Wait for the other end to start first */\r
+    u_int restart : 1;                 /* Restart vs. exit after close */\r
+    u_int neg_mru : 1;                 /* Negotiate the MRU? */\r
+    u_int neg_asyncmap : 1;            /* Negotiate the async map? */\r
+    u_int neg_upap : 1;                        /* Ask for UPAP authentication? */\r
+    u_int neg_chap : 1;                        /* Ask for CHAP authentication? */\r
+    u_int neg_magicnumber : 1; /* Ask for magic number? */\r
+    u_int neg_pcompression : 1;        /* HDLC Protocol Field Compression? */\r
+    u_int neg_accompression : 1;       /* HDLC Address/Control Field Compression? */\r
+    u_int neg_lqr : 1;                 /* Negotiate use of Link Quality Reports */\r
+    u_int neg_cbcp : 1;                        /* Negotiate use of CBCP */\r
+#ifdef PPP_MULTILINK\r
+    u_int neg_mrru : 1;                        /* Negotiate multilink MRRU */\r
+    u_int neg_ssnhf : 1;               /* Negotiate short sequence numbers */\r
+    u_int neg_endpoint : 1;            /* Negotiate endpoint discriminator */\r
+#endif\r
+    u_short mru;                       /* Value of MRU */\r
+#ifdef PPP_MULTILINK\r
+    u_short mrru;                      /* Value of MRRU, and multilink enable */\r
+#endif\r
+    u_char chap_mdtype;                        /* which MD type (hashing algorithm) */\r
+    u32_t asyncmap;                    /* Value of async map */\r
+    u32_t magicnumber;\r
+    int numloops;                              /* Number of loops during magic number neg. */\r
+    u32_t lqr_period;          /* Reporting period for LQR 1/100ths second */\r
+#ifdef PPP_MULTILINK\r
+    struct epdisc endpoint;    /* endpoint discriminator */\r
+#endif\r
+} lcp_options;\r
+\r
+/*\r
+ * Values for phase from BSD pppd.h based on RFC 1661.\r
+ */\r
+typedef enum {\r
+       PHASE_DEAD = 0,\r
+       PHASE_INITIALIZE,\r
+       PHASE_ESTABLISH,\r
+       PHASE_AUTHENTICATE,\r
+       PHASE_CALLBACK,\r
+       PHASE_NETWORK,\r
+       PHASE_TERMINATE\r
+} LinkPhase;\r
+\r
+\r
+/*****************************\r
+*** PUBLIC DATA STRUCTURES ***\r
+*****************************/\r
+\r
+extern LinkPhase lcp_phase[NUM_PPP];   /* Phase of link session (RFC 1661) */\r
+extern lcp_options lcp_wantoptions[];\r
+extern lcp_options lcp_gotoptions[];\r
+extern lcp_options lcp_allowoptions[];\r
+extern lcp_options lcp_hisoptions[];\r
+extern ext_accm xmit_accm[];\r
+\r
+\r
+/***********************\r
+*** PUBLIC FUNCTIONS ***\r
+***********************/\r
+\r
+void lcp_init (int);\r
+void lcp_open (int);\r
+void lcp_close (int, char *);\r
+void lcp_lowerup (int);\r
+void lcp_lowerdown (int);\r
+void lcp_sprotrej (int, u_char *, int);        /* send protocol reject */\r
+\r
+extern struct protent lcp_protent;\r
+\r
+/* Default number of times we receive our magic number from the peer\r
+   before deciding the link is looped-back. */\r
+#define DEFLOOPBACKFAIL        10\r
+\r
+#endif /* LCP_H */\r
+\r
index 427401691296a2bf56926fde59faf768e2127bf8..6e9d4753867a89cee2b0682ec0f549d8429410f4 100644 (file)
@@ -1,79 +1,79 @@
-/*****************************************************************************
-* magic.c - Network Random Number Generator program file.
-*
-* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
-* portions Copyright (c) 1997 by Global Election Systems Inc.
-*
-* The authors hereby grant permission to use, copy, modify, distribute,
-* and license this software and its documentation for any purpose, provided
-* that existing copyright notices are retained in all copies and that this
-* notice and the following disclaimer are included verbatim in any 
-* distributions. No written agreement, license, or royalty fee is required
-* for any of the authorized uses.
-*
-* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *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 CONTRIBUTORS 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.
-*
-******************************************************************************
-* REVISION HISTORY
-*
-* 03-01-01 Marc Boucher <marc@mbsi.ca>
-*   Ported to lwIP.
-* 97-12-04 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
-*      Original based on BSD magic.c.
-*****************************************************************************/
-/*
- * magic.c - PPP Magic Number routines.
- *
- * Copyright (c) 1989 Carnegie Mellon University.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by Carnegie Mellon University.  The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include "ppp.h"
-#include "randm.h"
-#include "magic.h"
-
-
-/***********************************/
-/*** PUBLIC FUNCTION DEFINITIONS ***/
-/***********************************/
-/*
- * magicInit - Initialize the magic number generator.
- *
- * Since we use another random number generator that has its own
- * initialization, we do nothing here.
- */
-void magicInit()
-{
-       return;
-}
-
-/*
- * magic - Returns the next magic number.
- */
-u32_t magic()
-{
-    return avRandom();
-}
-
-
+/*****************************************************************************\r
+* magic.c - Network Random Number Generator program file.\r
+*\r
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.\r
+* portions Copyright (c) 1997 by Global Election Systems Inc.\r
+*\r
+* The authors hereby grant permission to use, copy, modify, distribute,\r
+* and license this software and its documentation for any purpose, provided\r
+* that existing copyright notices are retained in all copies and that this\r
+* notice and the following disclaimer are included verbatim in any \r
+* distributions. No written agreement, license, or royalty fee is required\r
+* for any of the authorized uses.\r
+*\r
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR\r
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+*\r
+******************************************************************************\r
+* REVISION HISTORY\r
+*\r
+* 03-01-01 Marc Boucher <marc@mbsi.ca>\r
+*   Ported to lwIP.\r
+* 97-12-04 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.\r
+*      Original based on BSD magic.c.\r
+*****************************************************************************/\r
+/*\r
+ * magic.c - PPP Magic Number routines.\r
+ *\r
+ * Copyright (c) 1989 Carnegie Mellon University.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms are permitted\r
+ * provided that the above copyright notice and this paragraph are\r
+ * duplicated in all such forms and that any documentation,\r
+ * advertising materials, and other materials related to such\r
+ * distribution and use acknowledge that the software was developed\r
+ * by Carnegie Mellon University.  The name of the\r
+ * University may not be used to endorse or promote products derived\r
+ * from this software without specific prior written permission.\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR\r
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r
+ */\r
+\r
+#include "ppp.h"\r
+#include "randm.h"\r
+#include "magic.h"\r
+\r
+\r
+/***********************************/\r
+/*** PUBLIC FUNCTION DEFINITIONS ***/\r
+/***********************************/\r
+/*\r
+ * magicInit - Initialize the magic number generator.\r
+ *\r
+ * Since we use another random number generator that has its own\r
+ * initialization, we do nothing here.\r
+ */\r
+void magicInit()\r
+{\r
+       return;\r
+}\r
+\r
+/*\r
+ * magic - Returns the next magic number.\r
+ */\r
+u32_t magic()\r
+{\r
+    return avRandom();\r
+}\r
+\r
+\r
index 7574f32b9f63cb57d7ceb71e1b61efe7049f4dae..6e9b10b58b956b8a263a2198fc4ea8abf9caa71f 100644 (file)
@@ -1,64 +1,64 @@
-/*****************************************************************************
-* magic.h - Network Random Number Generator header file.
-*
-* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
-* portions Copyright (c) 1997 Global Election Systems Inc.
-*
-* The authors hereby grant permission to use, copy, modify, distribute,
-* and license this software and its documentation for any purpose, provided
-* that existing copyright notices are retained in all copies and that this
-* notice and the following disclaimer are included verbatim in any 
-* distributions. No written agreement, license, or royalty fee is required
-* for any of the authorized uses.
-*
-* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *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 CONTRIBUTORS 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.
-*
-******************************************************************************
-* REVISION HISTORY
-*
-* 03-01-01 Marc Boucher <marc@mbsi.ca>
-*   Ported to lwIP.
-* 97-12-04 Guy Lancaster <glanca@gesn.com>, Global Election Systems Inc.
-*   Original derived from BSD codes.
-*****************************************************************************/
-/*
- * magic.h - PPP Magic Number definitions.
- *
- * Copyright (c) 1989 Carnegie Mellon University.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by Carnegie Mellon University.  The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * $Id: magic.h,v 1.1 2003/05/27 14:37:56 jani Exp $
- */
-
-#ifndef MAGIC_H
-#define MAGIC_H
-
-/*****************************************************************************
-************************** PUBLIC FUNCTIONS **********************************
-*****************************************************************************/
-
-void magicInit(void);   /* Initialize the magic number generator */
-u32_t magic(void);  /* Returns the next magic number */
-
-#endif /* MAGIC_H */
+/*****************************************************************************\r
+* magic.h - Network Random Number Generator header file.\r
+*\r
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.\r
+* portions Copyright (c) 1997 Global Election Systems Inc.\r
+*\r
+* The authors hereby grant permission to use, copy, modify, distribute,\r
+* and license this software and its documentation for any purpose, provided\r
+* that existing copyright notices are retained in all copies and that this\r
+* notice and the following disclaimer are included verbatim in any \r
+* distributions. No written agreement, license, or royalty fee is required\r
+* for any of the authorized uses.\r
+*\r
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR\r
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+*\r
+******************************************************************************\r
+* REVISION HISTORY\r
+*\r
+* 03-01-01 Marc Boucher <marc@mbsi.ca>\r
+*   Ported to lwIP.\r
+* 97-12-04 Guy Lancaster <glanca@gesn.com>, Global Election Systems Inc.\r
+*   Original derived from BSD codes.\r
+*****************************************************************************/\r
+/*\r
+ * magic.h - PPP Magic Number definitions.\r
+ *\r
+ * Copyright (c) 1989 Carnegie Mellon University.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms are permitted\r
+ * provided that the above copyright notice and this paragraph are\r
+ * duplicated in all such forms and that any documentation,\r
+ * advertising materials, and other materials related to such\r
+ * distribution and use acknowledge that the software was developed\r
+ * by Carnegie Mellon University.  The name of the\r
+ * University may not be used to endorse or promote products derived\r
+ * from this software without specific prior written permission.\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR\r
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r
+ *\r
+ * $Id: magic.h,v 1.1 2003/05/27 14:37:56 jani Exp $\r
+ */\r
+\r
+#ifndef MAGIC_H\r
+#define MAGIC_H\r
+\r
+/*****************************************************************************\r
+************************** PUBLIC FUNCTIONS **********************************\r
+*****************************************************************************/\r
+\r
+void magicInit(void);   /* Initialize the magic number generator */\r
+u32_t magic(void);  /* Returns the next magic number */\r
+\r
+#endif /* MAGIC_H */\r
index e077cdea5f922dd3a5ba8aa8d2f84abaeb65bb55..488d64af56d57900b263e183150ececd739d0e93 100644 (file)
-/*
- ***********************************************************************
- ** md5.c -- the source code for MD5 routines                         **
- ** RSA Data Security, Inc. MD5 Message-Digest Algorithm              **
- ** Created: 2/17/90 RLR                                              **
- ** Revised: 1/91 SRD,AJ,BSK,JT Reference C ver., 7/10 constant corr. **
- ***********************************************************************
- */
-
-/*
- ***********************************************************************
- ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved.  **
- **                                                                   **
- ** License to copy and use this software is granted provided that    **
- ** it is identified as the "RSA Data Security, Inc. MD5 Message-     **
- ** Digest Algorithm" in all material mentioning or referencing this  **
- ** software or this function.                                        **
- **                                                                   **
- ** License is also granted to make and use derivative works          **
- ** provided that such works are identified as "derived from the RSA  **
- ** Data Security, Inc. MD5 Message-Digest Algorithm" in all          **
- ** material mentioning or referencing the derived work.              **
- **                                                                   **
- ** RSA Data Security, Inc. makes no representations concerning       **
- ** either the merchantability of this software or the suitability    **
- ** of this software for any particular purpose.  It is provided "as  **
- ** is" without express or implied warranty of any kind.              **
- **                                                                   **
- ** These notices must be retained in any copies of any part of this  **
- ** documentation and/or software.                                    **
- ***********************************************************************
- */
-
-#include "ppp.h"
-#include "md5.h"
-#include "pppdebug.h"
-
-#if CHAP_SUPPORT > 0 || MD5_SUPPORT > 0
-
-/*
- ***********************************************************************
- **  Message-digest routines:                                         **
- **  To form the message digest for a message M                       **
- **    (1) Initialize a context buffer mdContext using MD5Init        **
- **    (2) Call MD5Update on mdContext and M                          **
- **    (3) Call MD5Final on mdContext                                 **
- **  The message digest is now in mdContext->digest[0...15]           **
- ***********************************************************************
- */
-
-/* forward declaration */
-static void Transform (u32_t *buf, u32_t *in);
-
-static unsigned char PADDING[64] = {
-  0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-/* F, G, H and I are basic MD5 functions */
-#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
-#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
-#define H(x, y, z) ((x) ^ (y) ^ (z))
-#define I(x, y, z) ((y) ^ ((x) | (~z)))
-
-/* ROTATE_LEFT rotates x left n bits */
-#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
-
-/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */
-/* Rotation is separate from addition to prevent recomputation */
-#define FF(a, b, c, d, x, s, ac) \
-  {(a) += F ((b), (c), (d)) + (x) + (u32_t)(ac); \
-   (a) = ROTATE_LEFT ((a), (s)); \
-   (a) += (b); \
-  }
-#define GG(a, b, c, d, x, s, ac) \
-  {(a) += G ((b), (c), (d)) + (x) + (u32_t)(ac); \
-   (a) = ROTATE_LEFT ((a), (s)); \
-   (a) += (b); \
-  }
-#define HH(a, b, c, d, x, s, ac) \
-  {(a) += H ((b), (c), (d)) + (x) + (u32_t)(ac); \
-   (a) = ROTATE_LEFT ((a), (s)); \
-   (a) += (b); \
-  }
-#define II(a, b, c, d, x, s, ac) \
-  {(a) += I ((b), (c), (d)) + (x) + (u32_t)(ac); \
-   (a) = ROTATE_LEFT ((a), (s)); \
-   (a) += (b); \
-  }
-
-#ifdef __STDC__
-#define UL(x)  x##UL
-#else
-#ifdef WIN32
-#define UL(x)  x##UL
-#else
-#define UL(x)  x
-#endif
-#endif
-
-/* The routine MD5Init initializes the message-digest context
-   mdContext. All fields are set to zero.
- */
-void MD5Init (MD5_CTX *mdContext)
-{
-  mdContext->i[0] = mdContext->i[1] = (u32_t)0;
-
-  /* Load magic initialization constants.
-   */
-  mdContext->buf[0] = (u32_t)0x67452301UL;
-  mdContext->buf[1] = (u32_t)0xefcdab89UL;
-  mdContext->buf[2] = (u32_t)0x98badcfeUL;
-  mdContext->buf[3] = (u32_t)0x10325476UL;
-}
-
-/* The routine MD5Update updates the message-digest context to
-   account for the presence of each of the characters inBuf[0..inLen-1]
-   in the message whose digest is being computed.
- */
-void MD5Update(MD5_CTX *mdContext, unsigned char *inBuf, unsigned int inLen)
-{
-  u32_t in[16];
-  int mdi;
-  unsigned int i, ii;
-
-#if 0
-  ppp_trace(LOG_INFO, "MD5Update: %u:%.*H\n", inLen, MIN(inLen, 20) * 2, inBuf);
-  ppp_trace(LOG_INFO, "MD5Update: %u:%s\n", inLen, inBuf);
-#endif
-  
-  /* compute number of bytes mod 64 */
-  mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
-
-  /* update number of bits */
-  if ((mdContext->i[0] + ((u32_t)inLen << 3)) < mdContext->i[0])
-    mdContext->i[1]++;
-  mdContext->i[0] += ((u32_t)inLen << 3);
-  mdContext->i[1] += ((u32_t)inLen >> 29);
-
-  while (inLen--) {
-    /* add new character to buffer, increment mdi */
-    mdContext->in[mdi++] = *inBuf++;
-
-    /* transform if necessary */
-    if (mdi == 0x40) {
-      for (i = 0, ii = 0; i < 16; i++, ii += 4)
-        in[i] = (((u32_t)mdContext->in[ii+3]) << 24) |
-                (((u32_t)mdContext->in[ii+2]) << 16) |
-                               (((u32_t)mdContext->in[ii+1]) << 8) |
-                ((u32_t)mdContext->in[ii]);
-      Transform (mdContext->buf, in);
-      mdi = 0;
-    }
-  }
-}
-
-/* The routine MD5Final terminates the message-digest computation and
-   ends with the desired message digest in mdContext->digest[0...15].
- */
-void MD5Final (unsigned char hash[], MD5_CTX *mdContext)
-{
-  u32_t in[16];
-  int mdi;
-  unsigned int i, ii;
-  unsigned int padLen;
-
-  /* save number of bits */
-  in[14] = mdContext->i[0];
-  in[15] = mdContext->i[1];
-
-  /* compute number of bytes mod 64 */
-  mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
-
-  /* pad out to 56 mod 64 */
-  padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi);
-  MD5Update (mdContext, PADDING, padLen);
-
-  /* append length in bits and transform */
-  for (i = 0, ii = 0; i < 14; i++, ii += 4)
-    in[i] = (((u32_t)mdContext->in[ii+3]) << 24) |
-            (((u32_t)mdContext->in[ii+2]) << 16) |
-            (((u32_t)mdContext->in[ii+1]) << 8) |
-            ((u32_t)mdContext->in[ii]);
-  Transform (mdContext->buf, in);
-
-  /* store buffer in digest */
-  for (i = 0, ii = 0; i < 4; i++, ii += 4) {
-    mdContext->digest[ii] = (unsigned char)(mdContext->buf[i] & 0xFF);
-       mdContext->digest[ii+1] =
-      (unsigned char)((mdContext->buf[i] >> 8) & 0xFF);
-    mdContext->digest[ii+2] =
-      (unsigned char)((mdContext->buf[i] >> 16) & 0xFF);
-    mdContext->digest[ii+3] =
-      (unsigned char)((mdContext->buf[i] >> 24) & 0xFF);
-  }
-  memcpy(hash, mdContext->digest, 16);
-}
-
-/* Basic MD5 step. Transforms buf based on in.
- */
-static void Transform (u32_t *buf, u32_t *in)
-{
-  u32_t a = buf[0], b = buf[1], c = buf[2], d = buf[3];
-
-  /* Round 1 */
-#define S11 7
-#define S12 12
-#define S13 17
-#define S14 22
-  FF ( a, b, c, d, in[ 0], S11, UL(3614090360)); /* 1 */
-  FF ( d, a, b, c, in[ 1], S12, UL(3905402710)); /* 2 */
-  FF ( c, d, a, b, in[ 2], S13, UL( 606105819)); /* 3 */
-  FF ( b, c, d, a, in[ 3], S14, UL(3250441966)); /* 4 */
-  FF ( a, b, c, d, in[ 4], S11, UL(4118548399)); /* 5 */
-  FF ( d, a, b, c, in[ 5], S12, UL(1200080426)); /* 6 */
-  FF ( c, d, a, b, in[ 6], S13, UL(2821735955)); /* 7 */
-  FF ( b, c, d, a, in[ 7], S14, UL(4249261313)); /* 8 */
-  FF ( a, b, c, d, in[ 8], S11, UL(1770035416)); /* 9 */
-  FF ( d, a, b, c, in[ 9], S12, UL(2336552879)); /* 10 */
-  FF ( c, d, a, b, in[10], S13, UL(4294925233)); /* 11 */
-  FF ( b, c, d, a, in[11], S14, UL(2304563134)); /* 12 */
-  FF ( a, b, c, d, in[12], S11, UL(1804603682)); /* 13 */
-  FF ( d, a, b, c, in[13], S12, UL(4254626195)); /* 14 */
-  FF ( c, d, a, b, in[14], S13, UL(2792965006)); /* 15 */
-  FF ( b, c, d, a, in[15], S14, UL(1236535329)); /* 16 */
-
-  /* Round 2 */
-#define S21 5
-#define S22 9
-#define S23 14
-#define S24 20
-  GG ( a, b, c, d, in[ 1], S21, UL(4129170786)); /* 17 */
-  GG ( d, a, b, c, in[ 6], S22, UL(3225465664)); /* 18 */
-  GG ( c, d, a, b, in[11], S23, UL( 643717713)); /* 19 */
-  GG ( b, c, d, a, in[ 0], S24, UL(3921069994)); /* 20 */
-  GG ( a, b, c, d, in[ 5], S21, UL(3593408605)); /* 21 */
-  GG ( d, a, b, c, in[10], S22, UL(  38016083)); /* 22 */
-  GG ( c, d, a, b, in[15], S23, UL(3634488961)); /* 23 */
-  GG ( b, c, d, a, in[ 4], S24, UL(3889429448)); /* 24 */
-  GG ( a, b, c, d, in[ 9], S21, UL( 568446438)); /* 25 */
-  GG ( d, a, b, c, in[14], S22, UL(3275163606)); /* 26 */
-  GG ( c, d, a, b, in[ 3], S23, UL(4107603335)); /* 27 */
-  GG ( b, c, d, a, in[ 8], S24, UL(1163531501)); /* 28 */
-  GG ( a, b, c, d, in[13], S21, UL(2850285829)); /* 29 */
-  GG ( d, a, b, c, in[ 2], S22, UL(4243563512)); /* 30 */
-  GG ( c, d, a, b, in[ 7], S23, UL(1735328473)); /* 31 */
-  GG ( b, c, d, a, in[12], S24, UL(2368359562)); /* 32 */
-
-  /* Round 3 */
-#define S31 4
-#define S32 11
-#define S33 16
-#define S34 23
-  HH ( a, b, c, d, in[ 5], S31, UL(4294588738)); /* 33 */
-  HH ( d, a, b, c, in[ 8], S32, UL(2272392833)); /* 34 */
-  HH ( c, d, a, b, in[11], S33, UL(1839030562)); /* 35 */
-  HH ( b, c, d, a, in[14], S34, UL(4259657740)); /* 36 */
-  HH ( a, b, c, d, in[ 1], S31, UL(2763975236)); /* 37 */
-  HH ( d, a, b, c, in[ 4], S32, UL(1272893353)); /* 38 */
-  HH ( c, d, a, b, in[ 7], S33, UL(4139469664)); /* 39 */
-  HH ( b, c, d, a, in[10], S34, UL(3200236656)); /* 40 */
-  HH ( a, b, c, d, in[13], S31, UL( 681279174)); /* 41 */
-  HH ( d, a, b, c, in[ 0], S32, UL(3936430074)); /* 42 */
-  HH ( c, d, a, b, in[ 3], S33, UL(3572445317)); /* 43 */
-  HH ( b, c, d, a, in[ 6], S34, UL(  76029189)); /* 44 */
-  HH ( a, b, c, d, in[ 9], S31, UL(3654602809)); /* 45 */
-  HH ( d, a, b, c, in[12], S32, UL(3873151461)); /* 46 */
-  HH ( c, d, a, b, in[15], S33, UL( 530742520)); /* 47 */
-  HH ( b, c, d, a, in[ 2], S34, UL(3299628645)); /* 48 */
-
-  /* Round 4 */
-#define S41 6
-#define S42 10
-#define S43 15
-#define S44 21
-  II ( a, b, c, d, in[ 0], S41, UL(4096336452)); /* 49 */
-  II ( d, a, b, c, in[ 7], S42, UL(1126891415)); /* 50 */
-  II ( c, d, a, b, in[14], S43, UL(2878612391)); /* 51 */
-  II ( b, c, d, a, in[ 5], S44, UL(4237533241)); /* 52 */
-  II ( a, b, c, d, in[12], S41, UL(1700485571)); /* 53 */
-  II ( d, a, b, c, in[ 3], S42, UL(2399980690)); /* 54 */
-  II ( c, d, a, b, in[10], S43, UL(4293915773)); /* 55 */
-  II ( b, c, d, a, in[ 1], S44, UL(2240044497)); /* 56 */
-  II ( a, b, c, d, in[ 8], S41, UL(1873313359)); /* 57 */
-  II ( d, a, b, c, in[15], S42, UL(4264355552)); /* 58 */
-  II ( c, d, a, b, in[ 6], S43, UL(2734768916)); /* 59 */
-  II ( b, c, d, a, in[13], S44, UL(1309151649)); /* 60 */
-  II ( a, b, c, d, in[ 4], S41, UL(4149444226)); /* 61 */
-  II ( d, a, b, c, in[11], S42, UL(3174756917)); /* 62 */
-  II ( c, d, a, b, in[ 2], S43, UL( 718787259)); /* 63 */
-  II ( b, c, d, a, in[ 9], S44, UL(3951481745)); /* 64 */
-
-  buf[0] += a;
-  buf[1] += b;
-  buf[2] += c;
-  buf[3] += d;
-}
-
-#endif
-
+/*\r
+ ***********************************************************************\r
+ ** md5.c -- the source code for MD5 routines                         **\r
+ ** RSA Data Security, Inc. MD5 Message-Digest Algorithm              **\r
+ ** Created: 2/17/90 RLR                                              **\r
+ ** Revised: 1/91 SRD,AJ,BSK,JT Reference C ver., 7/10 constant corr. **\r
+ ***********************************************************************\r
+ */\r
+\r
+/*\r
+ ***********************************************************************\r
+ ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved.  **\r
+ **                                                                   **\r
+ ** License to copy and use this software is granted provided that    **\r
+ ** it is identified as the "RSA Data Security, Inc. MD5 Message-     **\r
+ ** Digest Algorithm" in all material mentioning or referencing this  **\r
+ ** software or this function.                                        **\r
+ **                                                                   **\r
+ ** License is also granted to make and use derivative works          **\r
+ ** provided that such works are identified as "derived from the RSA  **\r
+ ** Data Security, Inc. MD5 Message-Digest Algorithm" in all          **\r
+ ** material mentioning or referencing the derived work.              **\r
+ **                                                                   **\r
+ ** RSA Data Security, Inc. makes no representations concerning       **\r
+ ** either the merchantability of this software or the suitability    **\r
+ ** of this software for any particular purpose.  It is provided "as  **\r
+ ** is" without express or implied warranty of any kind.              **\r
+ **                                                                   **\r
+ ** These notices must be retained in any copies of any part of this  **\r
+ ** documentation and/or software.                                    **\r
+ ***********************************************************************\r
+ */\r
+\r
+#include "ppp.h"\r
+#include "md5.h"\r
+#include "pppdebug.h"\r
+\r
+#if CHAP_SUPPORT > 0 || MD5_SUPPORT > 0\r
+\r
+/*\r
+ ***********************************************************************\r
+ **  Message-digest routines:                                         **\r
+ **  To form the message digest for a message M                       **\r
+ **    (1) Initialize a context buffer mdContext using MD5Init        **\r
+ **    (2) Call MD5Update on mdContext and M                          **\r
+ **    (3) Call MD5Final on mdContext                                 **\r
+ **  The message digest is now in mdContext->digest[0...15]           **\r
+ ***********************************************************************\r
+ */\r
+\r
+/* forward declaration */\r
+static void Transform (u32_t *buf, u32_t *in);\r
+\r
+static unsigned char PADDING[64] = {\r
+  0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\r
+};\r
+\r
+/* F, G, H and I are basic MD5 functions */\r
+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))\r
+#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))\r
+#define H(x, y, z) ((x) ^ (y) ^ (z))\r
+#define I(x, y, z) ((y) ^ ((x) | (~z)))\r
+\r
+/* ROTATE_LEFT rotates x left n bits */\r
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))\r
+\r
+/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */\r
+/* Rotation is separate from addition to prevent recomputation */\r
+#define FF(a, b, c, d, x, s, ac) \\r
+  {(a) += F ((b), (c), (d)) + (x) + (u32_t)(ac); \\r
+   (a) = ROTATE_LEFT ((a), (s)); \\r
+   (a) += (b); \\r
+  }\r
+#define GG(a, b, c, d, x, s, ac) \\r
+  {(a) += G ((b), (c), (d)) + (x) + (u32_t)(ac); \\r
+   (a) = ROTATE_LEFT ((a), (s)); \\r
+   (a) += (b); \\r
+  }\r
+#define HH(a, b, c, d, x, s, ac) \\r
+  {(a) += H ((b), (c), (d)) + (x) + (u32_t)(ac); \\r
+   (a) = ROTATE_LEFT ((a), (s)); \\r
+   (a) += (b); \\r
+  }\r
+#define II(a, b, c, d, x, s, ac) \\r
+  {(a) += I ((b), (c), (d)) + (x) + (u32_t)(ac); \\r
+   (a) = ROTATE_LEFT ((a), (s)); \\r
+   (a) += (b); \\r
+  }\r
+\r
+#ifdef __STDC__\r
+#define UL(x)  x##UL\r
+#else\r
+#ifdef WIN32\r
+#define UL(x)  x##UL\r
+#else\r
+#define UL(x)  x\r
+#endif\r
+#endif\r
+\r
+/* The routine MD5Init initializes the message-digest context\r
+   mdContext. All fields are set to zero.\r
+ */\r
+void MD5Init (MD5_CTX *mdContext)\r
+{\r
+  mdContext->i[0] = mdContext->i[1] = (u32_t)0;\r
+\r
+  /* Load magic initialization constants.\r
+   */\r
+  mdContext->buf[0] = (u32_t)0x67452301UL;\r
+  mdContext->buf[1] = (u32_t)0xefcdab89UL;\r
+  mdContext->buf[2] = (u32_t)0x98badcfeUL;\r
+  mdContext->buf[3] = (u32_t)0x10325476UL;\r
+}\r
+\r
+/* The routine MD5Update updates the message-digest context to\r
+   account for the presence of each of the characters inBuf[0..inLen-1]\r
+   in the message whose digest is being computed.\r
+ */\r
+void MD5Update(MD5_CTX *mdContext, unsigned char *inBuf, unsigned int inLen)\r
+{\r
+  u32_t in[16];\r
+  int mdi;\r
+  unsigned int i, ii;\r
+\r
+#if 0\r
+  ppp_trace(LOG_INFO, "MD5Update: %u:%.*H\n", inLen, MIN(inLen, 20) * 2, inBuf);\r
+  ppp_trace(LOG_INFO, "MD5Update: %u:%s\n", inLen, inBuf);\r
+#endif\r
+  \r
+  /* compute number of bytes mod 64 */\r
+  mdi = (int)((mdContext->i[0] >> 3) & 0x3F);\r
+\r
+  /* update number of bits */\r
+  if ((mdContext->i[0] + ((u32_t)inLen << 3)) < mdContext->i[0])\r
+    mdContext->i[1]++;\r
+  mdContext->i[0] += ((u32_t)inLen << 3);\r
+  mdContext->i[1] += ((u32_t)inLen >> 29);\r
+\r
+  while (inLen--) {\r
+    /* add new character to buffer, increment mdi */\r
+    mdContext->in[mdi++] = *inBuf++;\r
+\r
+    /* transform if necessary */\r
+    if (mdi == 0x40) {\r
+      for (i = 0, ii = 0; i < 16; i++, ii += 4)\r
+        in[i] = (((u32_t)mdContext->in[ii+3]) << 24) |\r
+                (((u32_t)mdContext->in[ii+2]) << 16) |\r
+                               (((u32_t)mdContext->in[ii+1]) << 8) |\r
+                ((u32_t)mdContext->in[ii]);\r
+      Transform (mdContext->buf, in);\r
+      mdi = 0;\r
+    }\r
+  }\r
+}\r
+\r
+/* The routine MD5Final terminates the message-digest computation and\r
+   ends with the desired message digest in mdContext->digest[0...15].\r
+ */\r
+void MD5Final (unsigned char hash[], MD5_CTX *mdContext)\r
+{\r
+  u32_t in[16];\r
+  int mdi;\r
+  unsigned int i, ii;\r
+  unsigned int padLen;\r
+\r
+  /* save number of bits */\r
+  in[14] = mdContext->i[0];\r
+  in[15] = mdContext->i[1];\r
+\r
+  /* compute number of bytes mod 64 */\r
+  mdi = (int)((mdContext->i[0] >> 3) & 0x3F);\r
+\r
+  /* pad out to 56 mod 64 */\r
+  padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi);\r
+  MD5Update (mdContext, PADDING, padLen);\r
+\r
+  /* append length in bits and transform */\r
+  for (i = 0, ii = 0; i < 14; i++, ii += 4)\r
+    in[i] = (((u32_t)mdContext->in[ii+3]) << 24) |\r
+            (((u32_t)mdContext->in[ii+2]) << 16) |\r
+            (((u32_t)mdContext->in[ii+1]) << 8) |\r
+            ((u32_t)mdContext->in[ii]);\r
+  Transform (mdContext->buf, in);\r
+\r
+  /* store buffer in digest */\r
+  for (i = 0, ii = 0; i < 4; i++, ii += 4) {\r
+    mdContext->digest[ii] = (unsigned char)(mdContext->buf[i] & 0xFF);\r
+       mdContext->digest[ii+1] =\r
+      (unsigned char)((mdContext->buf[i] >> 8) & 0xFF);\r
+    mdContext->digest[ii+2] =\r
+      (unsigned char)((mdContext->buf[i] >> 16) & 0xFF);\r
+    mdContext->digest[ii+3] =\r
+      (unsigned char)((mdContext->buf[i] >> 24) & 0xFF);\r
+  }\r
+  memcpy(hash, mdContext->digest, 16);\r
+}\r
+\r
+/* Basic MD5 step. Transforms buf based on in.\r
+ */\r
+static void Transform (u32_t *buf, u32_t *in)\r
+{\r
+  u32_t a = buf[0], b = buf[1], c = buf[2], d = buf[3];\r
+\r
+  /* Round 1 */\r
+#define S11 7\r
+#define S12 12\r
+#define S13 17\r
+#define S14 22\r
+  FF ( a, b, c, d, in[ 0], S11, UL(3614090360)); /* 1 */\r
+  FF ( d, a, b, c, in[ 1], S12, UL(3905402710)); /* 2 */\r
+  FF ( c, d, a, b, in[ 2], S13, UL( 606105819)); /* 3 */\r
+  FF ( b, c, d, a, in[ 3], S14, UL(3250441966)); /* 4 */\r
+  FF ( a, b, c, d, in[ 4], S11, UL(4118548399)); /* 5 */\r
+  FF ( d, a, b, c, in[ 5], S12, UL(1200080426)); /* 6 */\r
+  FF ( c, d, a, b, in[ 6], S13, UL(2821735955)); /* 7 */\r
+  FF ( b, c, d, a, in[ 7], S14, UL(4249261313)); /* 8 */\r
+  FF ( a, b, c, d, in[ 8], S11, UL(1770035416)); /* 9 */\r
+  FF ( d, a, b, c, in[ 9], S12, UL(2336552879)); /* 10 */\r
+  FF ( c, d, a, b, in[10], S13, UL(4294925233)); /* 11 */\r
+  FF ( b, c, d, a, in[11], S14, UL(2304563134)); /* 12 */\r
+  FF ( a, b, c, d, in[12], S11, UL(1804603682)); /* 13 */\r
+  FF ( d, a, b, c, in[13], S12, UL(4254626195)); /* 14 */\r
+  FF ( c, d, a, b, in[14], S13, UL(2792965006)); /* 15 */\r
+  FF ( b, c, d, a, in[15], S14, UL(1236535329)); /* 16 */\r
+\r
+  /* Round 2 */\r
+#define S21 5\r
+#define S22 9\r
+#define S23 14\r
+#define S24 20\r
+  GG ( a, b, c, d, in[ 1], S21, UL(4129170786)); /* 17 */\r
+  GG ( d, a, b, c, in[ 6], S22, UL(3225465664)); /* 18 */\r
+  GG ( c, d, a, b, in[11], S23, UL( 643717713)); /* 19 */\r
+  GG ( b, c, d, a, in[ 0], S24, UL(3921069994)); /* 20 */\r
+  GG ( a, b, c, d, in[ 5], S21, UL(3593408605)); /* 21 */\r
+  GG ( d, a, b, c, in[10], S22, UL(  38016083)); /* 22 */\r
+  GG ( c, d, a, b, in[15], S23, UL(3634488961)); /* 23 */\r
+  GG ( b, c, d, a, in[ 4], S24, UL(3889429448)); /* 24 */\r
+  GG ( a, b, c, d, in[ 9], S21, UL( 568446438)); /* 25 */\r
+  GG ( d, a, b, c, in[14], S22, UL(3275163606)); /* 26 */\r
+  GG ( c, d, a, b, in[ 3], S23, UL(4107603335)); /* 27 */\r
+  GG ( b, c, d, a, in[ 8], S24, UL(1163531501)); /* 28 */\r
+  GG ( a, b, c, d, in[13], S21, UL(2850285829)); /* 29 */\r
+  GG ( d, a, b, c, in[ 2], S22, UL(4243563512)); /* 30 */\r
+  GG ( c, d, a, b, in[ 7], S23, UL(1735328473)); /* 31 */\r
+  GG ( b, c, d, a, in[12], S24, UL(2368359562)); /* 32 */\r
+\r
+  /* Round 3 */\r
+#define S31 4\r
+#define S32 11\r
+#define S33 16\r
+#define S34 23\r
+  HH ( a, b, c, d, in[ 5], S31, UL(4294588738)); /* 33 */\r
+  HH ( d, a, b, c, in[ 8], S32, UL(2272392833)); /* 34 */\r
+  HH ( c, d, a, b, in[11], S33, UL(1839030562)); /* 35 */\r
+  HH ( b, c, d, a, in[14], S34, UL(4259657740)); /* 36 */\r
+  HH ( a, b, c, d, in[ 1], S31, UL(2763975236)); /* 37 */\r
+  HH ( d, a, b, c, in[ 4], S32, UL(1272893353)); /* 38 */\r
+  HH ( c, d, a, b, in[ 7], S33, UL(4139469664)); /* 39 */\r
+  HH ( b, c, d, a, in[10], S34, UL(3200236656)); /* 40 */\r
+  HH ( a, b, c, d, in[13], S31, UL( 681279174)); /* 41 */\r
+  HH ( d, a, b, c, in[ 0], S32, UL(3936430074)); /* 42 */\r
+  HH ( c, d, a, b, in[ 3], S33, UL(3572445317)); /* 43 */\r
+  HH ( b, c, d, a, in[ 6], S34, UL(  76029189)); /* 44 */\r
+  HH ( a, b, c, d, in[ 9], S31, UL(3654602809)); /* 45 */\r
+  HH ( d, a, b, c, in[12], S32, UL(3873151461)); /* 46 */\r
+  HH ( c, d, a, b, in[15], S33, UL( 530742520)); /* 47 */\r
+  HH ( b, c, d, a, in[ 2], S34, UL(3299628645)); /* 48 */\r
+\r
+  /* Round 4 */\r
+#define S41 6\r
+#define S42 10\r
+#define S43 15\r
+#define S44 21\r
+  II ( a, b, c, d, in[ 0], S41, UL(4096336452)); /* 49 */\r
+  II ( d, a, b, c, in[ 7], S42, UL(1126891415)); /* 50 */\r
+  II ( c, d, a, b, in[14], S43, UL(2878612391)); /* 51 */\r
+  II ( b, c, d, a, in[ 5], S44, UL(4237533241)); /* 52 */\r
+  II ( a, b, c, d, in[12], S41, UL(1700485571)); /* 53 */\r
+  II ( d, a, b, c, in[ 3], S42, UL(2399980690)); /* 54 */\r
+  II ( c, d, a, b, in[10], S43, UL(4293915773)); /* 55 */\r
+  II ( b, c, d, a, in[ 1], S44, UL(2240044497)); /* 56 */\r
+  II ( a, b, c, d, in[ 8], S41, UL(1873313359)); /* 57 */\r
+  II ( d, a, b, c, in[15], S42, UL(4264355552)); /* 58 */\r
+  II ( c, d, a, b, in[ 6], S43, UL(2734768916)); /* 59 */\r
+  II ( b, c, d, a, in[13], S44, UL(1309151649)); /* 60 */\r
+  II ( a, b, c, d, in[ 4], S41, UL(4149444226)); /* 61 */\r
+  II ( d, a, b, c, in[11], S42, UL(3174756917)); /* 62 */\r
+  II ( c, d, a, b, in[ 2], S43, UL( 718787259)); /* 63 */\r
+  II ( b, c, d, a, in[ 9], S44, UL(3951481745)); /* 64 */\r
+\r
+  buf[0] += a;\r
+  buf[1] += b;\r
+  buf[2] += c;\r
+  buf[3] += d;\r
+}\r
+\r
+#endif\r
+\r
index 0e81cdc34bd8e7d6874fd853ade7e61a92871432..83d318cfba42f35ca6332d17cd3d9d5f9cf542b9 100644 (file)
@@ -1,55 +1,55 @@
-/*
- ***********************************************************************
- ** md5.h -- header file for implementation of MD5                    **
- ** RSA Data Security, Inc. MD5 Message-Digest Algorithm              **
- ** Created: 2/17/90 RLR                                              **
- ** Revised: 12/27/90 SRD,AJ,BSK,JT Reference C version               **
- ** Revised (for MD5): RLR 4/27/91                                    **
- **   -- G modified to have y&~z instead of y&z                       **
- **   -- FF, GG, HH modified to add in last register done             **
- **   -- Access pattern: round 2 works mod 5, round 3 works mod 3     **
- **   -- distinct additive constant for each step                     **
- **   -- round 4 added, working mod 7                                 **
- ***********************************************************************
- */
-
-/*
- ***********************************************************************
- ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved.  **
- **                                                                   **
- ** License to copy and use this software is granted provided that    **
- ** it is identified as the "RSA Data Security, Inc. MD5 Message-     **
- ** Digest Algorithm" in all material mentioning or referencing this  **
- ** software or this function.                                        **
- **                                                                   **
- ** License is also granted to make and use derivative works          **
- ** provided that such works are identified as "derived from the RSA  **
- ** Data Security, Inc. MD5 Message-Digest Algorithm" in all          **
- ** material mentioning or referencing the derived work.              **
- **                                                                   **
- ** RSA Data Security, Inc. makes no representations concerning       **
- ** either the merchantability of this software or the suitability    **
- ** of this software for any particular purpose.  It is provided "as  **
- ** is" without express or implied warranty of any kind.              **
- **                                                                   **
- ** These notices must be retained in any copies of any part of this  **
- ** documentation and/or software.                                    **
- ***********************************************************************
- */
-
-#ifndef MD5_H
-#define MD5_H
-
-/* Data structure for MD5 (Message-Digest) computation */
-typedef struct {
-  u32_t i[2];                   /* number of _bits_ handled mod 2^64 */
-  u32_t buf[4];                                    /* scratch buffer */
-  unsigned char in[64];                              /* input buffer */
-  unsigned char digest[16];     /* actual digest after MD5Final call */
-} MD5_CTX;
-
-void MD5Init (MD5_CTX *mdContext);
-void MD5Update (MD5_CTX *mdContext, unsigned char *inBuf, unsigned int inLen);
-void MD5Final (unsigned char hash[], MD5_CTX *mdContext);
-
-#endif /* MD5_H */
+/*\r
+ ***********************************************************************\r
+ ** md5.h -- header file for implementation of MD5                    **\r
+ ** RSA Data Security, Inc. MD5 Message-Digest Algorithm              **\r
+ ** Created: 2/17/90 RLR                                              **\r
+ ** Revised: 12/27/90 SRD,AJ,BSK,JT Reference C version               **\r
+ ** Revised (for MD5): RLR 4/27/91                                    **\r
+ **   -- G modified to have y&~z instead of y&z                       **\r
+ **   -- FF, GG, HH modified to add in last register done             **\r
+ **   -- Access pattern: round 2 works mod 5, round 3 works mod 3     **\r
+ **   -- distinct additive constant for each step                     **\r
+ **   -- round 4 added, working mod 7                                 **\r
+ ***********************************************************************\r
+ */\r
+\r
+/*\r
+ ***********************************************************************\r
+ ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved.  **\r
+ **                                                                   **\r
+ ** License to copy and use this software is granted provided that    **\r
+ ** it is identified as the "RSA Data Security, Inc. MD5 Message-     **\r
+ ** Digest Algorithm" in all material mentioning or referencing this  **\r
+ ** software or this function.                                        **\r
+ **                                                                   **\r
+ ** License is also granted to make and use derivative works          **\r
+ ** provided that such works are identified as "derived from the RSA  **\r
+ ** Data Security, Inc. MD5 Message-Digest Algorithm" in all          **\r
+ ** material mentioning or referencing the derived work.              **\r
+ **                                                                   **\r
+ ** RSA Data Security, Inc. makes no representations concerning       **\r
+ ** either the merchantability of this software or the suitability    **\r
+ ** of this software for any particular purpose.  It is provided "as  **\r
+ ** is" without express or implied warranty of any kind.              **\r
+ **                                                                   **\r
+ ** These notices must be retained in any copies of any part of this  **\r
+ ** documentation and/or software.                                    **\r
+ ***********************************************************************\r
+ */\r
+\r
+#ifndef MD5_H\r
+#define MD5_H\r
+\r
+/* Data structure for MD5 (Message-Digest) computation */\r
+typedef struct {\r
+  u32_t i[2];                   /* number of _bits_ handled mod 2^64 */\r
+  u32_t buf[4];                                    /* scratch buffer */\r
+  unsigned char in[64];                              /* input buffer */\r
+  unsigned char digest[16];     /* actual digest after MD5Final call */\r
+} MD5_CTX;\r
+\r
+void MD5Init (MD5_CTX *mdContext);\r
+void MD5Update (MD5_CTX *mdContext, unsigned char *inBuf, unsigned int inLen);\r
+void MD5Final (unsigned char hash[], MD5_CTX *mdContext);\r
+\r
+#endif /* MD5_H */\r
index 23e438ff2901b6b5cd397d44f3cdb06801875396..4b105ef3ecb5f55e28e774ed5e0bf850ad50cec9 100644 (file)
-/*****************************************************************************
-* pap.c - Network Password Authentication Protocol program file.
-*
-* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
-* portions Copyright (c) 1997 by Global Election Systems Inc.
-*
-* The authors hereby grant permission to use, copy, modify, distribute,
-* and license this software and its documentation for any purpose, provided
-* that existing copyright notices are retained in all copies and that this
-* notice and the following disclaimer are included verbatim in any 
-* distributions. No written agreement, license, or royalty fee is required
-* for any of the authorized uses.
-*
-* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *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 CONTRIBUTORS 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.
-*
-******************************************************************************
-* REVISION HISTORY
-*
-* 03-01-01 Marc Boucher <marc@mbsi.ca>
-*   Ported to lwIP.
-* 97-12-12 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
-*      Original.
-*****************************************************************************/
-/*
- * upap.c - User/Password Authentication Protocol.
- *
- * Copyright (c) 1989 Carnegie Mellon University.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by Carnegie Mellon University.  The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include "ppp.h"
-#include "auth.h"
-#include "pap.h"
-#include "pppdebug.h"
-
-
-#if PAP_SUPPORT > 0
-
-/***********************************/
-/*** LOCAL FUNCTION DECLARATIONS ***/
-/***********************************/
-/*
- * Protocol entry points.
- */
-static void upap_init (int);
-static void upap_lowerup (int);
-static void upap_lowerdown (int);
-static void upap_input (int, u_char *, int);
-static void upap_protrej (int);
-
-static void upap_timeout (void *);
-static void upap_reqtimeout (void *);
-static void upap_rauthreq (upap_state *, u_char *, int, int);
-static void upap_rauthack (upap_state *, u_char *, int, int);
-static void upap_rauthnak (upap_state *, u_char *, int, int);
-static void upap_sauthreq (upap_state *);
-static void upap_sresp (upap_state *, u_char, u_char, char *, int);
-
-
-
-
-/******************************/
-/*** PUBLIC DATA STRUCTURES ***/
-/******************************/
-struct protent pap_protent = {
-    PPP_PAP,
-    upap_init,
-    upap_input,
-    upap_protrej,
-    upap_lowerup,
-    upap_lowerdown,
-    NULL,
-    NULL,
-#if 0
-    upap_printpkt,
-    NULL,
-#endif
-    1,
-    "PAP",
-#if 0
-    NULL,
-    NULL,
-    NULL
-#endif
-};
-
-upap_state upap[NUM_PPP];              /* UPAP state; one for each unit */
-
-
-
-/***********************************/
-/*** PUBLIC FUNCTION DEFINITIONS ***/
-/***********************************/
-/*
- *  Set the default login name and password for the pap sessions
- */
-void upap_setloginpasswd(int unit, const char *luser, const char *lpassword)
-{
-       upap_state *u = &upap[unit];
-       
-       /* Save the username and password we're given */
-       u->us_user = luser;
-       u->us_userlen = strlen(luser);
-       u->us_passwd = lpassword;
-       u->us_passwdlen = strlen(lpassword);
-}
-
-
-/*
- * upap_authwithpeer - Authenticate us with our peer (start client).
- *
- * Set new state and send authenticate's.
- */
-void upap_authwithpeer(int unit, char *user, char *password)
-{
-       upap_state *u = &upap[unit];
-       
-       UPAPDEBUG((LOG_INFO, "upap_authwithpeer: %d user=%s password=%s s=%d\n",
-                               unit, user, password, u->us_clientstate));
-       
-       upap_setloginpasswd(unit, user, password);
-
-       u->us_transmits = 0;
-       
-       /* Lower layer up yet? */
-       if (u->us_clientstate == UPAPCS_INITIAL ||
-                       u->us_clientstate == UPAPCS_PENDING) {
-               u->us_clientstate = UPAPCS_PENDING;
-               return;
-       }
-       
-       upap_sauthreq(u);                       /* Start protocol */
-}
-
-
-/*
- * upap_authpeer - Authenticate our peer (start server).
- *
- * Set new state.
- */
-void upap_authpeer(int unit)
-{
-       upap_state *u = &upap[unit];
-       
-       /* Lower layer up yet? */
-       if (u->us_serverstate == UPAPSS_INITIAL ||
-                       u->us_serverstate == UPAPSS_PENDING) {
-               u->us_serverstate = UPAPSS_PENDING;
-               return;
-       }
-       
-       u->us_serverstate = UPAPSS_LISTEN;
-       if (u->us_reqtimeout > 0)
-               TIMEOUT(upap_reqtimeout, u, u->us_reqtimeout);
-}
-
-
-
-/**********************************/
-/*** LOCAL FUNCTION DEFINITIONS ***/
-/**********************************/
-/*
- * upap_init - Initialize a UPAP unit.
- */
-static void upap_init(int unit)
-{
-       upap_state *u = &upap[unit];
-
-       UPAPDEBUG((LOG_INFO, "upap_init: %d\n", unit)); 
-       u->us_unit = unit;
-       u->us_user = NULL;
-       u->us_userlen = 0;
-       u->us_passwd = NULL;
-       u->us_passwdlen = 0;
-       u->us_clientstate = UPAPCS_INITIAL;
-       u->us_serverstate = UPAPSS_INITIAL;
-       u->us_id = 0;
-       u->us_timeouttime = UPAP_DEFTIMEOUT;
-       u->us_maxtransmits = 10;
-       u->us_reqtimeout = UPAP_DEFREQTIME;
-}
-
-/*
- * upap_timeout - Retransmission timer for sending auth-reqs expired.
- */
-static void upap_timeout(void *arg)
-{
-       upap_state *u = (upap_state *) arg;
-       
-       UPAPDEBUG((LOG_INFO, "upap_timeout: %d timeout %d expired s=%d\n", 
-                               u->us_unit, u->us_timeouttime, u->us_clientstate));
-       
-       if (u->us_clientstate != UPAPCS_AUTHREQ)
-               return;
-       
-       if (u->us_transmits >= u->us_maxtransmits) {
-               /* give up in disgust */
-               UPAPDEBUG((LOG_ERR, "No response to PAP authenticate-requests\n"));
-               u->us_clientstate = UPAPCS_BADAUTH;
-               auth_withpeer_fail(u->us_unit, PPP_PAP);
-               return;
-       }
-       
-       upap_sauthreq(u);               /* Send Authenticate-Request */
-}
-
-
-/*
- * upap_reqtimeout - Give up waiting for the peer to send an auth-req.
- */
-static void upap_reqtimeout(void *arg)
-{
-       upap_state *u = (upap_state *) arg;
-       
-       if (u->us_serverstate != UPAPSS_LISTEN)
-               return;                 /* huh?? */
-       
-       auth_peer_fail(u->us_unit, PPP_PAP);
-       u->us_serverstate = UPAPSS_BADAUTH;
-}
-
-
-/*
- * upap_lowerup - The lower layer is up.
- *
- * Start authenticating if pending.
- */
-static void upap_lowerup(int unit)
-{
-       upap_state *u = &upap[unit];
-       
-       UPAPDEBUG((LOG_INFO, "upap_lowerup: %d s=%d\n", unit, u->us_clientstate));
-       
-       if (u->us_clientstate == UPAPCS_INITIAL)
-               u->us_clientstate = UPAPCS_CLOSED;
-       else if (u->us_clientstate == UPAPCS_PENDING) {
-               upap_sauthreq(u);       /* send an auth-request */
-       }
-       
-       if (u->us_serverstate == UPAPSS_INITIAL)
-               u->us_serverstate = UPAPSS_CLOSED;
-       else if (u->us_serverstate == UPAPSS_PENDING) {
-               u->us_serverstate = UPAPSS_LISTEN;
-               if (u->us_reqtimeout > 0)
-                       TIMEOUT(upap_reqtimeout, u, u->us_reqtimeout);
-       }
-}
-
-
-/*
- * upap_lowerdown - The lower layer is down.
- *
- * Cancel all timeouts.
- */
-static void upap_lowerdown(int unit)
-{
-       upap_state *u = &upap[unit];
-       
-       UPAPDEBUG((LOG_INFO, "upap_lowerdown: %d s=%d\n", unit, u->us_clientstate));
-       
-       if (u->us_clientstate == UPAPCS_AUTHREQ)        /* Timeout pending? */
-               UNTIMEOUT(upap_timeout, u);             /* Cancel timeout */
-       if (u->us_serverstate == UPAPSS_LISTEN && u->us_reqtimeout > 0)
-               UNTIMEOUT(upap_reqtimeout, u);
-       
-       u->us_clientstate = UPAPCS_INITIAL;
-       u->us_serverstate = UPAPSS_INITIAL;
-}
-
-
-/*
- * upap_protrej - Peer doesn't speak this protocol.
- *
- * This shouldn't happen.  In any case, pretend lower layer went down.
- */
-static void upap_protrej(int unit)
-{
-       upap_state *u = &upap[unit];
-       
-       if (u->us_clientstate == UPAPCS_AUTHREQ) {
-               UPAPDEBUG((LOG_ERR, "PAP authentication failed due to protocol-reject\n"));
-               auth_withpeer_fail(unit, PPP_PAP);
-       }
-       if (u->us_serverstate == UPAPSS_LISTEN) {
-               UPAPDEBUG((LOG_ERR, "PAP authentication of peer failed (protocol-reject)\n"));
-               auth_peer_fail(unit, PPP_PAP);
-       }
-       upap_lowerdown(unit);
-}
-
-
-/*
- * upap_input - Input UPAP packet.
- */
-static void upap_input(int unit, u_char *inpacket, int l)
-{
-       upap_state *u = &upap[unit];
-       u_char *inp;
-       u_char code, id;
-       int len;
-       
-       /*
-        * Parse header (code, id and length).
-        * If packet too short, drop it.
-        */
-       inp = inpacket;
-       if (l < UPAP_HEADERLEN) {
-               UPAPDEBUG((LOG_INFO, "pap_input: rcvd short header.\n"));
-               return;
-       }
-       GETCHAR(code, inp);
-       GETCHAR(id, inp);
-       GETSHORT(len, inp);
-       if (len < UPAP_HEADERLEN) {
-               UPAPDEBUG((LOG_INFO, "pap_input: rcvd illegal length.\n"));
-               return;
-       }
-       if (len > l) {
-               UPAPDEBUG((LOG_INFO, "pap_input: rcvd short packet.\n"));
-               return;
-       }
-       len -= UPAP_HEADERLEN;
-       
-       /*
-        * Action depends on code.
-        */
-       switch (code) {
-       case UPAP_AUTHREQ:
-               upap_rauthreq(u, inp, id, len);
-               break;
-       
-       case UPAP_AUTHACK:
-               upap_rauthack(u, inp, id, len);
-               break;
-       
-       case UPAP_AUTHNAK:
-               upap_rauthnak(u, inp, id, len);
-               break;
-       
-       default:                                /* XXX Need code reject */
-               break;
-       }
-}
-
-
-/*
- * upap_rauth - Receive Authenticate.
- */
-static void upap_rauthreq(
-       upap_state *u, 
-       u_char *inp, 
-       int id,
-       int len
-)
-{
-       u_char ruserlen, rpasswdlen;
-       char *ruser, *rpasswd;
-       int retcode;
-       char *msg;
-       int msglen;
-       
-       UPAPDEBUG((LOG_INFO, "pap_rauth: Rcvd id %d.\n", id));
-       
-       if (u->us_serverstate < UPAPSS_LISTEN)
-               return;
-       
-       /*
-        * If we receive a duplicate authenticate-request, we are
-        * supposed to return the same status as for the first request.
-        */
-       if (u->us_serverstate == UPAPSS_OPEN) {
-               upap_sresp(u, UPAP_AUTHACK, id, "", 0); /* return auth-ack */
-               return;
-       }
-       if (u->us_serverstate == UPAPSS_BADAUTH) {
-               upap_sresp(u, UPAP_AUTHNAK, id, "", 0); /* return auth-nak */
-               return;
-       }
-       
-       /*
-        * Parse user/passwd.
-        */
-       if (len < sizeof (u_char)) {
-               UPAPDEBUG((LOG_INFO, "pap_rauth: rcvd short packet.\n"));
-               return;
-       }
-       GETCHAR(ruserlen, inp);
-       len -= sizeof (u_char) + ruserlen + sizeof (u_char);
-       if (len < 0) {
-               UPAPDEBUG((LOG_INFO, "pap_rauth: rcvd short packet.\n"));
-               return;
-       }
-       ruser = (char *) inp;
-       INCPTR(ruserlen, inp);
-       GETCHAR(rpasswdlen, inp);
-       if (len < rpasswdlen) {
-               UPAPDEBUG((LOG_INFO, "pap_rauth: rcvd short packet.\n"));
-               return;
-       }
-       rpasswd = (char *) inp;
-       
-       /*
-        * Check the username and password given.
-        */
-       retcode = check_passwd(u->us_unit, ruser, ruserlen, rpasswd,
-                          rpasswdlen, &msg, &msglen);
-       BZERO(rpasswd, rpasswdlen);
-       
-       upap_sresp(u, retcode, id, msg, msglen);
-       
-       if (retcode == UPAP_AUTHACK) {
-               u->us_serverstate = UPAPSS_OPEN;
-               auth_peer_success(u->us_unit, PPP_PAP, ruser, ruserlen);
-       } else {
-               u->us_serverstate = UPAPSS_BADAUTH;
-               auth_peer_fail(u->us_unit, PPP_PAP);
-       }
-       
-       if (u->us_reqtimeout > 0)
-               UNTIMEOUT(upap_reqtimeout, u);
-}
-
-
-/*
- * upap_rauthack - Receive Authenticate-Ack.
- */
-static void upap_rauthack(
-       upap_state *u,
-       u_char *inp,
-       int id,
-       int len
-)
-{
-       u_char msglen;
-       char *msg;
-       
-       UPAPDEBUG((LOG_INFO, "pap_rauthack: Rcvd id %d s=%d\n", id, u->us_clientstate));
-       
-       if (u->us_clientstate != UPAPCS_AUTHREQ) /* XXX */
-               return;
-       
-       /*
-        * Parse message.
-        */
-       if (len < sizeof (u_char)) {
-               UPAPDEBUG((LOG_INFO, "pap_rauthack: rcvd short packet.\n"));
-               return;
-       }
-       GETCHAR(msglen, inp);
-       len -= sizeof (u_char);
-       if (len < msglen) {
-               UPAPDEBUG((LOG_INFO, "pap_rauthack: rcvd short packet.\n"));
-               return;
-       }
-       msg = (char *) inp;
-       PRINTMSG(msg, msglen);
-       
-       u->us_clientstate = UPAPCS_OPEN;
-       
-       auth_withpeer_success(u->us_unit, PPP_PAP);
-}
-
-
-/*
- * upap_rauthnak - Receive Authenticate-Nakk.
- */
-static void upap_rauthnak(
-       upap_state *u,
-       u_char *inp,
-       int id,
-       int len
-)
-{
-       u_char msglen;
-       char *msg;
-       
-       UPAPDEBUG((LOG_INFO, "pap_rauthnak: Rcvd id %d s=%d\n", id, u->us_clientstate));
-       
-       if (u->us_clientstate != UPAPCS_AUTHREQ) /* XXX */
-               return;
-       
-       /*
-        * Parse message.
-        */
-       if (len < sizeof (u_char)) {
-               UPAPDEBUG((LOG_INFO, "pap_rauthnak: rcvd short packet.\n"));
-               return;
-       }
-       GETCHAR(msglen, inp);
-       len -= sizeof (u_char);
-       if (len < msglen) {
-               UPAPDEBUG((LOG_INFO, "pap_rauthnak: rcvd short packet.\n"));
-               return;
-       }
-       msg = (char *) inp;
-       PRINTMSG(msg, msglen);
-       
-       u->us_clientstate = UPAPCS_BADAUTH;
-       
-       UPAPDEBUG((LOG_ERR, "PAP authentication failed\n"));
-       auth_withpeer_fail(u->us_unit, PPP_PAP);
-}
-
-
-/*
- * upap_sauthreq - Send an Authenticate-Request.
- */
-static void upap_sauthreq(upap_state *u)
-{
-       u_char *outp;
-       int outlen;
-       
-       outlen = UPAP_HEADERLEN + 2 * sizeof (u_char) 
-                       + u->us_userlen + u->us_passwdlen;
-       outp = outpacket_buf[u->us_unit];
-       
-       MAKEHEADER(outp, PPP_PAP);
-       
-       PUTCHAR(UPAP_AUTHREQ, outp);
-       PUTCHAR(++u->us_id, outp);
-       PUTSHORT(outlen, outp);
-       PUTCHAR(u->us_userlen, outp);
-       BCOPY(u->us_user, outp, u->us_userlen);
-       INCPTR(u->us_userlen, outp);
-       PUTCHAR(u->us_passwdlen, outp);
-       BCOPY(u->us_passwd, outp, u->us_passwdlen);
-       
-       pppWrite(u->us_unit, outpacket_buf[u->us_unit], outlen + PPP_HDRLEN);
-       
-       UPAPDEBUG((LOG_INFO, "pap_sauth: Sent id %d\n", u->us_id));
-       
-       TIMEOUT(upap_timeout, u, u->us_timeouttime);
-       ++u->us_transmits;
-       u->us_clientstate = UPAPCS_AUTHREQ;
-}
-
-
-/*
- * upap_sresp - Send a response (ack or nak).
- */
-static void upap_sresp(
-       upap_state *u,
-       u_char code, 
-       u_char id,
-       char *msg,
-       int msglen
-)
-{
-       u_char *outp;
-       int outlen;
-       
-       outlen = UPAP_HEADERLEN + sizeof (u_char) + msglen;
-       outp = outpacket_buf[u->us_unit];
-       MAKEHEADER(outp, PPP_PAP);
-       
-       PUTCHAR(code, outp);
-       PUTCHAR(id, outp);
-       PUTSHORT(outlen, outp);
-       PUTCHAR(msglen, outp);
-       BCOPY(msg, outp, msglen);
-       pppWrite(u->us_unit, outpacket_buf[u->us_unit], outlen + PPP_HDRLEN);
-       
-       UPAPDEBUG((LOG_INFO, "pap_sresp: Sent code %d, id %d s=%d\n", 
-                               code, id, u->us_clientstate));
-}
-
-#if 0
-/*
- * upap_printpkt - print the contents of a PAP packet.
- */
-static int upap_printpkt(
-       u_char *p,
-       int plen,
-       void (*printer) (void *, char *, ...),
-       void *arg
-)
-{
-       (void)p;
-       (void)plen;
-       (void)printer;
-       (void)arg;
-       return 0;
-}
-#endif
-
-#endif /* PAP_SUPPORT */
-
+/*****************************************************************************\r
+* pap.c - Network Password Authentication Protocol program file.\r
+*\r
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.\r
+* portions Copyright (c) 1997 by Global Election Systems Inc.\r
+*\r
+* The authors hereby grant permission to use, copy, modify, distribute,\r
+* and license this software and its documentation for any purpose, provided\r
+* that existing copyright notices are retained in all copies and that this\r
+* notice and the following disclaimer are included verbatim in any \r
+* distributions. No written agreement, license, or royalty fee is required\r
+* for any of the authorized uses.\r
+*\r
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR\r
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+*\r
+******************************************************************************\r
+* REVISION HISTORY\r
+*\r
+* 03-01-01 Marc Boucher <marc@mbsi.ca>\r
+*   Ported to lwIP.\r
+* 97-12-12 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.\r
+*      Original.\r
+*****************************************************************************/\r
+/*\r
+ * upap.c - User/Password Authentication Protocol.\r
+ *\r
+ * Copyright (c) 1989 Carnegie Mellon University.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms are permitted\r
+ * provided that the above copyright notice and this paragraph are\r
+ * duplicated in all such forms and that any documentation,\r
+ * advertising materials, and other materials related to such\r
+ * distribution and use acknowledge that the software was developed\r
+ * by Carnegie Mellon University.  The name of the\r
+ * University may not be used to endorse or promote products derived\r
+ * from this software without specific prior written permission.\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR\r
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r
+ */\r
+\r
+#include "ppp.h"\r
+#include "auth.h"\r
+#include "pap.h"\r
+#include "pppdebug.h"\r
+\r
+\r
+#if PAP_SUPPORT > 0\r
+\r
+/***********************************/\r
+/*** LOCAL FUNCTION DECLARATIONS ***/\r
+/***********************************/\r
+/*\r
+ * Protocol entry points.\r
+ */\r
+static void upap_init (int);\r
+static void upap_lowerup (int);\r
+static void upap_lowerdown (int);\r
+static void upap_input (int, u_char *, int);\r
+static void upap_protrej (int);\r
+\r
+static void upap_timeout (void *);\r
+static void upap_reqtimeout (void *);\r
+static void upap_rauthreq (upap_state *, u_char *, int, int);\r
+static void upap_rauthack (upap_state *, u_char *, int, int);\r
+static void upap_rauthnak (upap_state *, u_char *, int, int);\r
+static void upap_sauthreq (upap_state *);\r
+static void upap_sresp (upap_state *, u_char, u_char, char *, int);\r
+\r
+\r
+\r
+\r
+/******************************/\r
+/*** PUBLIC DATA STRUCTURES ***/\r
+/******************************/\r
+struct protent pap_protent = {\r
+    PPP_PAP,\r
+    upap_init,\r
+    upap_input,\r
+    upap_protrej,\r
+    upap_lowerup,\r
+    upap_lowerdown,\r
+    NULL,\r
+    NULL,\r
+#if 0\r
+    upap_printpkt,\r
+    NULL,\r
+#endif\r
+    1,\r
+    "PAP",\r
+#if 0\r
+    NULL,\r
+    NULL,\r
+    NULL\r
+#endif\r
+};\r
+\r
+upap_state upap[NUM_PPP];              /* UPAP state; one for each unit */\r
+\r
+\r
+\r
+/***********************************/\r
+/*** PUBLIC FUNCTION DEFINITIONS ***/\r
+/***********************************/\r
+/*\r
+ *  Set the default login name and password for the pap sessions\r
+ */\r
+void upap_setloginpasswd(int unit, const char *luser, const char *lpassword)\r
+{\r
+       upap_state *u = &upap[unit];\r
+       \r
+       /* Save the username and password we're given */\r
+       u->us_user = luser;\r
+       u->us_userlen = strlen(luser);\r
+       u->us_passwd = lpassword;\r
+       u->us_passwdlen = strlen(lpassword);\r
+}\r
+\r
+\r
+/*\r
+ * upap_authwithpeer - Authenticate us with our peer (start client).\r
+ *\r
+ * Set new state and send authenticate's.\r
+ */\r
+void upap_authwithpeer(int unit, char *user, char *password)\r
+{\r
+       upap_state *u = &upap[unit];\r
+       \r
+       UPAPDEBUG((LOG_INFO, "upap_authwithpeer: %d user=%s password=%s s=%d\n",\r
+                               unit, user, password, u->us_clientstate));\r
+       \r
+       upap_setloginpasswd(unit, user, password);\r
+\r
+       u->us_transmits = 0;\r
+       \r
+       /* Lower layer up yet? */\r
+       if (u->us_clientstate == UPAPCS_INITIAL ||\r
+                       u->us_clientstate == UPAPCS_PENDING) {\r
+               u->us_clientstate = UPAPCS_PENDING;\r
+               return;\r
+       }\r
+       \r
+       upap_sauthreq(u);                       /* Start protocol */\r
+}\r
+\r
+\r
+/*\r
+ * upap_authpeer - Authenticate our peer (start server).\r
+ *\r
+ * Set new state.\r
+ */\r
+void upap_authpeer(int unit)\r
+{\r
+       upap_state *u = &upap[unit];\r
+       \r
+       /* Lower layer up yet? */\r
+       if (u->us_serverstate == UPAPSS_INITIAL ||\r
+                       u->us_serverstate == UPAPSS_PENDING) {\r
+               u->us_serverstate = UPAPSS_PENDING;\r
+               return;\r
+       }\r
+       \r
+       u->us_serverstate = UPAPSS_LISTEN;\r
+       if (u->us_reqtimeout > 0)\r
+               TIMEOUT(upap_reqtimeout, u, u->us_reqtimeout);\r
+}\r
+\r
+\r
+\r
+/**********************************/\r
+/*** LOCAL FUNCTION DEFINITIONS ***/\r
+/**********************************/\r
+/*\r
+ * upap_init - Initialize a UPAP unit.\r
+ */\r
+static void upap_init(int unit)\r
+{\r
+       upap_state *u = &upap[unit];\r
+\r
+       UPAPDEBUG((LOG_INFO, "upap_init: %d\n", unit)); \r
+       u->us_unit = unit;\r
+       u->us_user = NULL;\r
+       u->us_userlen = 0;\r
+       u->us_passwd = NULL;\r
+       u->us_passwdlen = 0;\r
+       u->us_clientstate = UPAPCS_INITIAL;\r
+       u->us_serverstate = UPAPSS_INITIAL;\r
+       u->us_id = 0;\r
+       u->us_timeouttime = UPAP_DEFTIMEOUT;\r
+       u->us_maxtransmits = 10;\r
+       u->us_reqtimeout = UPAP_DEFREQTIME;\r
+}\r
+\r
+/*\r
+ * upap_timeout - Retransmission timer for sending auth-reqs expired.\r
+ */\r
+static void upap_timeout(void *arg)\r
+{\r
+       upap_state *u = (upap_state *) arg;\r
+       \r
+       UPAPDEBUG((LOG_INFO, "upap_timeout: %d timeout %d expired s=%d\n", \r
+                               u->us_unit, u->us_timeouttime, u->us_clientstate));\r
+       \r
+       if (u->us_clientstate != UPAPCS_AUTHREQ)\r
+               return;\r
+       \r
+       if (u->us_transmits >= u->us_maxtransmits) {\r
+               /* give up in disgust */\r
+               UPAPDEBUG((LOG_ERR, "No response to PAP authenticate-requests\n"));\r
+               u->us_clientstate = UPAPCS_BADAUTH;\r
+               auth_withpeer_fail(u->us_unit, PPP_PAP);\r
+               return;\r
+       }\r
+       \r
+       upap_sauthreq(u);               /* Send Authenticate-Request */\r
+}\r
+\r
+\r
+/*\r
+ * upap_reqtimeout - Give up waiting for the peer to send an auth-req.\r
+ */\r
+static void upap_reqtimeout(void *arg)\r
+{\r
+       upap_state *u = (upap_state *) arg;\r
+       \r
+       if (u->us_serverstate != UPAPSS_LISTEN)\r
+               return;                 /* huh?? */\r
+       \r
+       auth_peer_fail(u->us_unit, PPP_PAP);\r
+       u->us_serverstate = UPAPSS_BADAUTH;\r
+}\r
+\r
+\r
+/*\r
+ * upap_lowerup - The lower layer is up.\r
+ *\r
+ * Start authenticating if pending.\r
+ */\r
+static void upap_lowerup(int unit)\r
+{\r
+       upap_state *u = &upap[unit];\r
+       \r
+       UPAPDEBUG((LOG_INFO, "upap_lowerup: %d s=%d\n", unit, u->us_clientstate));\r
+       \r
+       if (u->us_clientstate == UPAPCS_INITIAL)\r
+               u->us_clientstate = UPAPCS_CLOSED;\r
+       else if (u->us_clientstate == UPAPCS_PENDING) {\r
+               upap_sauthreq(u);       /* send an auth-request */\r
+       }\r
+       \r
+       if (u->us_serverstate == UPAPSS_INITIAL)\r
+               u->us_serverstate = UPAPSS_CLOSED;\r
+       else if (u->us_serverstate == UPAPSS_PENDING) {\r
+               u->us_serverstate = UPAPSS_LISTEN;\r
+               if (u->us_reqtimeout > 0)\r
+                       TIMEOUT(upap_reqtimeout, u, u->us_reqtimeout);\r
+       }\r
+}\r
+\r
+\r
+/*\r
+ * upap_lowerdown - The lower layer is down.\r
+ *\r
+ * Cancel all timeouts.\r
+ */\r
+static void upap_lowerdown(int unit)\r
+{\r
+       upap_state *u = &upap[unit];\r
+       \r
+       UPAPDEBUG((LOG_INFO, "upap_lowerdown: %d s=%d\n", unit, u->us_clientstate));\r
+       \r
+       if (u->us_clientstate == UPAPCS_AUTHREQ)        /* Timeout pending? */\r
+               UNTIMEOUT(upap_timeout, u);             /* Cancel timeout */\r
+       if (u->us_serverstate == UPAPSS_LISTEN && u->us_reqtimeout > 0)\r
+               UNTIMEOUT(upap_reqtimeout, u);\r
+       \r
+       u->us_clientstate = UPAPCS_INITIAL;\r
+       u->us_serverstate = UPAPSS_INITIAL;\r
+}\r
+\r
+\r
+/*\r
+ * upap_protrej - Peer doesn't speak this protocol.\r
+ *\r
+ * This shouldn't happen.  In any case, pretend lower layer went down.\r
+ */\r
+static void upap_protrej(int unit)\r
+{\r
+       upap_state *u = &upap[unit];\r
+       \r
+       if (u->us_clientstate == UPAPCS_AUTHREQ) {\r
+               UPAPDEBUG((LOG_ERR, "PAP authentication failed due to protocol-reject\n"));\r
+               auth_withpeer_fail(unit, PPP_PAP);\r
+       }\r
+       if (u->us_serverstate == UPAPSS_LISTEN) {\r
+               UPAPDEBUG((LOG_ERR, "PAP authentication of peer failed (protocol-reject)\n"));\r
+               auth_peer_fail(unit, PPP_PAP);\r
+       }\r
+       upap_lowerdown(unit);\r
+}\r
+\r
+\r
+/*\r
+ * upap_input - Input UPAP packet.\r
+ */\r
+static void upap_input(int unit, u_char *inpacket, int l)\r
+{\r
+       upap_state *u = &upap[unit];\r
+       u_char *inp;\r
+       u_char code, id;\r
+       int len;\r
+       \r
+       /*\r
+        * Parse header (code, id and length).\r
+        * If packet too short, drop it.\r
+        */\r
+       inp = inpacket;\r
+       if (l < UPAP_HEADERLEN) {\r
+               UPAPDEBUG((LOG_INFO, "pap_input: rcvd short header.\n"));\r
+               return;\r
+       }\r
+       GETCHAR(code, inp);\r
+       GETCHAR(id, inp);\r
+       GETSHORT(len, inp);\r
+       if (len < UPAP_HEADERLEN) {\r
+               UPAPDEBUG((LOG_INFO, "pap_input: rcvd illegal length.\n"));\r
+               return;\r
+       }\r
+       if (len > l) {\r
+               UPAPDEBUG((LOG_INFO, "pap_input: rcvd short packet.\n"));\r
+               return;\r
+       }\r
+       len -= UPAP_HEADERLEN;\r
+       \r
+       /*\r
+        * Action depends on code.\r
+        */\r
+       switch (code) {\r
+       case UPAP_AUTHREQ:\r
+               upap_rauthreq(u, inp, id, len);\r
+               break;\r
+       \r
+       case UPAP_AUTHACK:\r
+               upap_rauthack(u, inp, id, len);\r
+               break;\r
+       \r
+       case UPAP_AUTHNAK:\r
+               upap_rauthnak(u, inp, id, len);\r
+               break;\r
+       \r
+       default:                                /* XXX Need code reject */\r
+               break;\r
+       }\r
+}\r
+\r
+\r
+/*\r
+ * upap_rauth - Receive Authenticate.\r
+ */\r
+static void upap_rauthreq(\r
+       upap_state *u, \r
+       u_char *inp, \r
+       int id,\r
+       int len\r
+)\r
+{\r
+       u_char ruserlen, rpasswdlen;\r
+       char *ruser, *rpasswd;\r
+       int retcode;\r
+       char *msg;\r
+       int msglen;\r
+       \r
+       UPAPDEBUG((LOG_INFO, "pap_rauth: Rcvd id %d.\n", id));\r
+       \r
+       if (u->us_serverstate < UPAPSS_LISTEN)\r
+               return;\r
+       \r
+       /*\r
+        * If we receive a duplicate authenticate-request, we are\r
+        * supposed to return the same status as for the first request.\r
+        */\r
+       if (u->us_serverstate == UPAPSS_OPEN) {\r
+               upap_sresp(u, UPAP_AUTHACK, id, "", 0); /* return auth-ack */\r
+               return;\r
+       }\r
+       if (u->us_serverstate == UPAPSS_BADAUTH) {\r
+               upap_sresp(u, UPAP_AUTHNAK, id, "", 0); /* return auth-nak */\r
+               return;\r
+       }\r
+       \r
+       /*\r
+        * Parse user/passwd.\r
+        */\r
+       if (len < sizeof (u_char)) {\r
+               UPAPDEBUG((LOG_INFO, "pap_rauth: rcvd short packet.\n"));\r
+               return;\r
+       }\r
+       GETCHAR(ruserlen, inp);\r
+       len -= sizeof (u_char) + ruserlen + sizeof (u_char);\r
+       if (len < 0) {\r
+               UPAPDEBUG((LOG_INFO, "pap_rauth: rcvd short packet.\n"));\r
+               return;\r
+       }\r
+       ruser = (char *) inp;\r
+       INCPTR(ruserlen, inp);\r
+       GETCHAR(rpasswdlen, inp);\r
+       if (len < rpasswdlen) {\r
+               UPAPDEBUG((LOG_INFO, "pap_rauth: rcvd short packet.\n"));\r
+               return;\r
+       }\r
+       rpasswd = (char *) inp;\r
+       \r
+       /*\r
+        * Check the username and password given.\r
+        */\r
+       retcode = check_passwd(u->us_unit, ruser, ruserlen, rpasswd,\r
+                          rpasswdlen, &msg, &msglen);\r
+       BZERO(rpasswd, rpasswdlen);\r
+       \r
+       upap_sresp(u, retcode, id, msg, msglen);\r
+       \r
+       if (retcode == UPAP_AUTHACK) {\r
+               u->us_serverstate = UPAPSS_OPEN;\r
+               auth_peer_success(u->us_unit, PPP_PAP, ruser, ruserlen);\r
+       } else {\r
+               u->us_serverstate = UPAPSS_BADAUTH;\r
+               auth_peer_fail(u->us_unit, PPP_PAP);\r
+       }\r
+       \r
+       if (u->us_reqtimeout > 0)\r
+               UNTIMEOUT(upap_reqtimeout, u);\r
+}\r
+\r
+\r
+/*\r
+ * upap_rauthack - Receive Authenticate-Ack.\r
+ */\r
+static void upap_rauthack(\r
+       upap_state *u,\r
+       u_char *inp,\r
+       int id,\r
+       int len\r
+)\r
+{\r
+       u_char msglen;\r
+       char *msg;\r
+       \r
+       UPAPDEBUG((LOG_INFO, "pap_rauthack: Rcvd id %d s=%d\n", id, u->us_clientstate));\r
+       \r
+       if (u->us_clientstate != UPAPCS_AUTHREQ) /* XXX */\r
+               return;\r
+       \r
+       /*\r
+        * Parse message.\r
+        */\r
+       if (len < sizeof (u_char)) {\r
+               UPAPDEBUG((LOG_INFO, "pap_rauthack: rcvd short packet.\n"));\r
+               return;\r
+       }\r
+       GETCHAR(msglen, inp);\r
+       len -= sizeof (u_char);\r
+       if (len < msglen) {\r
+               UPAPDEBUG((LOG_INFO, "pap_rauthack: rcvd short packet.\n"));\r
+               return;\r
+       }\r
+       msg = (char *) inp;\r
+       PRINTMSG(msg, msglen);\r
+       \r
+       u->us_clientstate = UPAPCS_OPEN;\r
+       \r
+       auth_withpeer_success(u->us_unit, PPP_PAP);\r
+}\r
+\r
+\r
+/*\r
+ * upap_rauthnak - Receive Authenticate-Nakk.\r
+ */\r
+static void upap_rauthnak(\r
+       upap_state *u,\r
+       u_char *inp,\r
+       int id,\r
+       int len\r
+)\r
+{\r
+       u_char msglen;\r
+       char *msg;\r
+       \r
+       UPAPDEBUG((LOG_INFO, "pap_rauthnak: Rcvd id %d s=%d\n", id, u->us_clientstate));\r
+       \r
+       if (u->us_clientstate != UPAPCS_AUTHREQ) /* XXX */\r
+               return;\r
+       \r
+       /*\r
+        * Parse message.\r
+        */\r
+       if (len < sizeof (u_char)) {\r
+               UPAPDEBUG((LOG_INFO, "pap_rauthnak: rcvd short packet.\n"));\r
+               return;\r
+       }\r
+       GETCHAR(msglen, inp);\r
+       len -= sizeof (u_char);\r
+       if (len < msglen) {\r
+               UPAPDEBUG((LOG_INFO, "pap_rauthnak: rcvd short packet.\n"));\r
+               return;\r
+       }\r
+       msg = (char *) inp;\r
+       PRINTMSG(msg, msglen);\r
+       \r
+       u->us_clientstate = UPAPCS_BADAUTH;\r
+       \r
+       UPAPDEBUG((LOG_ERR, "PAP authentication failed\n"));\r
+       auth_withpeer_fail(u->us_unit, PPP_PAP);\r
+}\r
+\r
+\r
+/*\r
+ * upap_sauthreq - Send an Authenticate-Request.\r
+ */\r
+static void upap_sauthreq(upap_state *u)\r
+{\r
+       u_char *outp;\r
+       int outlen;\r
+       \r
+       outlen = UPAP_HEADERLEN + 2 * sizeof (u_char) \r
+                       + u->us_userlen + u->us_passwdlen;\r
+       outp = outpacket_buf[u->us_unit];\r
+       \r
+       MAKEHEADER(outp, PPP_PAP);\r
+       \r
+       PUTCHAR(UPAP_AUTHREQ, outp);\r
+       PUTCHAR(++u->us_id, outp);\r
+       PUTSHORT(outlen, outp);\r
+       PUTCHAR(u->us_userlen, outp);\r
+       BCOPY(u->us_user, outp, u->us_userlen);\r
+       INCPTR(u->us_userlen, outp);\r
+       PUTCHAR(u->us_passwdlen, outp);\r
+       BCOPY(u->us_passwd, outp, u->us_passwdlen);\r
+       \r
+       pppWrite(u->us_unit, outpacket_buf[u->us_unit], outlen + PPP_HDRLEN);\r
+       \r
+       UPAPDEBUG((LOG_INFO, "pap_sauth: Sent id %d\n", u->us_id));\r
+       \r
+       TIMEOUT(upap_timeout, u, u->us_timeouttime);\r
+       ++u->us_transmits;\r
+       u->us_clientstate = UPAPCS_AUTHREQ;\r
+}\r
+\r
+\r
+/*\r
+ * upap_sresp - Send a response (ack or nak).\r
+ */\r
+static void upap_sresp(\r
+       upap_state *u,\r
+       u_char code, \r
+       u_char id,\r
+       char *msg,\r
+       int msglen\r
+)\r
+{\r
+       u_char *outp;\r
+       int outlen;\r
+       \r
+       outlen = UPAP_HEADERLEN + sizeof (u_char) + msglen;\r
+       outp = outpacket_buf[u->us_unit];\r
+       MAKEHEADER(outp, PPP_PAP);\r
+       \r
+       PUTCHAR(code, outp);\r
+       PUTCHAR(id, outp);\r
+       PUTSHORT(outlen, outp);\r
+       PUTCHAR(msglen, outp);\r
+       BCOPY(msg, outp, msglen);\r
+       pppWrite(u->us_unit, outpacket_buf[u->us_unit], outlen + PPP_HDRLEN);\r
+       \r
+       UPAPDEBUG((LOG_INFO, "pap_sresp: Sent code %d, id %d s=%d\n", \r
+                               code, id, u->us_clientstate));\r
+}\r
+\r
+#if 0\r
+/*\r
+ * upap_printpkt - print the contents of a PAP packet.\r
+ */\r
+static int upap_printpkt(\r
+       u_char *p,\r
+       int plen,\r
+       void (*printer) (void *, char *, ...),\r
+       void *arg\r
+)\r
+{\r
+       (void)p;\r
+       (void)plen;\r
+       (void)printer;\r
+       (void)arg;\r
+       return 0;\r
+}\r
+#endif\r
+\r
+#endif /* PAP_SUPPORT */\r
+\r
index 215c8a4f2eac502b0fdcdfe086985f260b2c19f8..59eb2c71e9241a384f2d7d97d253c4a829c56745 100644 (file)
-/*****************************************************************************
-* pap.h -  PPP Password Authentication Protocol header file.
-*
-* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
-* portions Copyright (c) 1997 Global Election Systems Inc.
-*
-* The authors hereby grant permission to use, copy, modify, distribute,
-* and license this software and its documentation for any purpose, provided
-* that existing copyright notices are retained in all copies and that this
-* notice and the following disclaimer are included verbatim in any 
-* distributions. No written agreement, license, or royalty fee is required
-* for any of the authorized uses.
-*
-* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *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 CONTRIBUTORS 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.
-*
-******************************************************************************
-* REVISION HISTORY
-*
-* 03-01-01 Marc Boucher <marc@mbsi.ca>
-*   Ported to lwIP.
-* 97-12-04 Guy Lancaster <glanca@gesn.com>, Global Election Systems Inc.
-*      Original derived from BSD codes.
-*****************************************************************************/
-/*
- * upap.h - User/Password Authentication Protocol definitions.
- *
- * Copyright (c) 1989 Carnegie Mellon University.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by Carnegie Mellon University.  The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-
-#ifndef PAP_H
-#define PAP_H
-
-/*************************
-*** PUBLIC DEFINITIONS ***
-*************************/
-/*
- * Packet header = Code, id, length.
- */
-#define UPAP_HEADERLEN (sizeof (u_char) + sizeof (u_char) + sizeof (u_short))
-
-
-/*
- * UPAP codes.
- */
-#define UPAP_AUTHREQ   1       /* Authenticate-Request */
-#define UPAP_AUTHACK   2       /* Authenticate-Ack */
-#define UPAP_AUTHNAK   3       /* Authenticate-Nak */
-
-/*
- * Client states.
- */
-#define UPAPCS_INITIAL 0       /* Connection down */
-#define UPAPCS_CLOSED  1       /* Connection up, haven't requested auth */
-#define UPAPCS_PENDING 2       /* Connection down, have requested auth */
-#define UPAPCS_AUTHREQ 3       /* We've sent an Authenticate-Request */
-#define UPAPCS_OPEN            4       /* We've received an Ack */
-#define UPAPCS_BADAUTH 5       /* We've received a Nak */
-
-/*
- * Server states.
- */
-#define UPAPSS_INITIAL 0       /* Connection down */
-#define UPAPSS_CLOSED  1       /* Connection up, haven't requested auth */
-#define UPAPSS_PENDING 2       /* Connection down, have requested auth */
-#define UPAPSS_LISTEN  3       /* Listening for an Authenticate */
-#define UPAPSS_OPEN            4       /* We've sent an Ack */
-#define UPAPSS_BADAUTH 5       /* We've sent a Nak */
-
-
-/************************
-*** PUBLIC DATA TYPES ***
-************************/
-
-/*
- * Each interface is described by upap structure.
- */
-typedef struct upap_state {
-    int us_unit;                       /* Interface unit number */
-    const char *us_user;       /* User */
-    int us_userlen;                    /* User length */
-    const char *us_passwd;     /* Password */
-    int us_passwdlen;          /* Password length */
-    int us_clientstate;                /* Client state */
-    int us_serverstate;                /* Server state */
-    u_char us_id;                      /* Current id */
-    int us_timeouttime;                /* Timeout (seconds) for auth-req retrans. */
-    int us_transmits;          /* Number of auth-reqs sent */
-    int us_maxtransmits;       /* Maximum number of auth-reqs to send */
-    int us_reqtimeout;         /* Time to wait for auth-req from peer */
-} upap_state;
-
-
-/***********************
-*** PUBLIC FUNCTIONS ***
-***********************/
-
-extern upap_state upap[];
-
-void upap_setloginpasswd(int unit, const char *luser, const char *lpassword);
-void upap_authwithpeer (int, char *, char *);
-void upap_authpeer (int);
-
-extern struct protent pap_protent;
-
-#endif /* PAP_H */
-
+/*****************************************************************************\r
+* pap.h -  PPP Password Authentication Protocol header file.\r
+*\r
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.\r
+* portions Copyright (c) 1997 Global Election Systems Inc.\r
+*\r
+* The authors hereby grant permission to use, copy, modify, distribute,\r
+* and license this software and its documentation for any purpose, provided\r
+* that existing copyright notices are retained in all copies and that this\r
+* notice and the following disclaimer are included verbatim in any \r
+* distributions. No written agreement, license, or royalty fee is required\r
+* for any of the authorized uses.\r
+*\r
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR\r
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+*\r
+******************************************************************************\r
+* REVISION HISTORY\r
+*\r
+* 03-01-01 Marc Boucher <marc@mbsi.ca>\r
+*   Ported to lwIP.\r
+* 97-12-04 Guy Lancaster <glanca@gesn.com>, Global Election Systems Inc.\r
+*      Original derived from BSD codes.\r
+*****************************************************************************/\r
+/*\r
+ * upap.h - User/Password Authentication Protocol definitions.\r
+ *\r
+ * Copyright (c) 1989 Carnegie Mellon University.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms are permitted\r
+ * provided that the above copyright notice and this paragraph are\r
+ * duplicated in all such forms and that any documentation,\r
+ * advertising materials, and other materials related to such\r
+ * distribution and use acknowledge that the software was developed\r
+ * by Carnegie Mellon University.  The name of the\r
+ * University may not be used to endorse or promote products derived\r
+ * from this software without specific prior written permission.\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR\r
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r
+ */\r
+\r
+\r
+#ifndef PAP_H\r
+#define PAP_H\r
+\r
+/*************************\r
+*** PUBLIC DEFINITIONS ***\r
+*************************/\r
+/*\r
+ * Packet header = Code, id, length.\r
+ */\r
+#define UPAP_HEADERLEN (sizeof (u_char) + sizeof (u_char) + sizeof (u_short))\r
+\r
+\r
+/*\r
+ * UPAP codes.\r
+ */\r
+#define UPAP_AUTHREQ   1       /* Authenticate-Request */\r
+#define UPAP_AUTHACK   2       /* Authenticate-Ack */\r
+#define UPAP_AUTHNAK   3       /* Authenticate-Nak */\r
+\r
+/*\r
+ * Client states.\r
+ */\r
+#define UPAPCS_INITIAL 0       /* Connection down */\r
+#define UPAPCS_CLOSED  1       /* Connection up, haven't requested auth */\r
+#define UPAPCS_PENDING 2       /* Connection down, have requested auth */\r
+#define UPAPCS_AUTHREQ 3       /* We've sent an Authenticate-Request */\r
+#define UPAPCS_OPEN            4       /* We've received an Ack */\r
+#define UPAPCS_BADAUTH 5       /* We've received a Nak */\r
+\r
+/*\r
+ * Server states.\r
+ */\r
+#define UPAPSS_INITIAL 0       /* Connection down */\r
+#define UPAPSS_CLOSED  1       /* Connection up, haven't requested auth */\r
+#define UPAPSS_PENDING 2       /* Connection down, have requested auth */\r
+#define UPAPSS_LISTEN  3       /* Listening for an Authenticate */\r
+#define UPAPSS_OPEN            4       /* We've sent an Ack */\r
+#define UPAPSS_BADAUTH 5       /* We've sent a Nak */\r
+\r
+\r
+/************************\r
+*** PUBLIC DATA TYPES ***\r
+************************/\r
+\r
+/*\r
+ * Each interface is described by upap structure.\r
+ */\r
+typedef struct upap_state {\r
+    int us_unit;                       /* Interface unit number */\r
+    const char *us_user;       /* User */\r
+    int us_userlen;                    /* User length */\r
+    const char *us_passwd;     /* Password */\r
+    int us_passwdlen;          /* Password length */\r
+    int us_clientstate;                /* Client state */\r
+    int us_serverstate;                /* Server state */\r
+    u_char us_id;                      /* Current id */\r
+    int us_timeouttime;                /* Timeout (seconds) for auth-req retrans. */\r
+    int us_transmits;          /* Number of auth-reqs sent */\r
+    int us_maxtransmits;       /* Maximum number of auth-reqs to send */\r
+    int us_reqtimeout;         /* Time to wait for auth-req from peer */\r
+} upap_state;\r
+\r
+\r
+/***********************\r
+*** PUBLIC FUNCTIONS ***\r
+***********************/\r
+\r
+extern upap_state upap[];\r
+\r
+void upap_setloginpasswd(int unit, const char *luser, const char *lpassword);\r
+void upap_authwithpeer (int, char *, char *);\r
+void upap_authpeer (int);\r
+\r
+extern struct protent pap_protent;\r
+\r
+#endif /* PAP_H */\r
+\r
index df402189e9710f10566af9c775888ae26b026baa..00a7956df9bf64e2f89e5f9306427cb85b300dbb 100644 (file)
-/*****************************************************************************
-* ppp.c - Network Point to Point Protocol program file.
-*
-* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
-* portions Copyright (c) 1997 by Global Election Systems Inc.
-*
-* The authors hereby grant permission to use, copy, modify, distribute,
-* and license this software and its documentation for any purpose, provided
-* that existing copyright notices are retained in all copies and that this
-* notice and the following disclaimer are included verbatim in any 
-* distributions. No written agreement, license, or royalty fee is required
-* for any of the authorized uses.
-*
-* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *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 CONTRIBUTORS 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.
-*
-******************************************************************************
-* REVISION HISTORY
-*
-* 03-01-01 Marc Boucher <marc@mbsi.ca>
-*   Ported to lwIP.
-* 97-11-05 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
-*   Original.
-*****************************************************************************/
-
-/*
- * ppp_defs.h - PPP definitions.
- *
- * if_pppvar.h - private structures and declarations for PPP.
- *
- * Copyright (c) 1994 The Australian National University.
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation is hereby granted, provided that the above copyright
- * notice appears in all copies.  This software is provided without any
- * warranty, express or implied. The Australian National University
- * makes no representations about the suitability of this software for
- * any purpose.
- *
- * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY
- * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
- * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY
- * OF SUCH DAMAGE.
- *
- * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO
- * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
- * OR MODIFICATIONS.
- */
-
-/*
- * if_ppp.h - Point-to-Point Protocol definitions.
- *
- * Copyright (c) 1989 Carnegie Mellon University.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by Carnegie Mellon University.  The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-#include <string.h>
-#include "ppp.h"
-#if PPP_SUPPORT > 0
-#include "randm.h"
-#include "fsm.h"
-#if PAP_SUPPORT > 0
-#include "pap.h"
-#endif
-#if CHAP_SUPPORT > 0
-#include "chap.h"
-#endif
-#include "ipcp.h"
-#include "lcp.h"
-#include "magic.h"
-#include "auth.h"
-#if VJ_SUPPORT > 0
-#include "vj.h"
-#endif
-
-#include "pppdebug.h"
-
-/*************************/
-/*** LOCAL DEFINITIONS ***/
-/*************************/
-
-/*
- * The basic PPP frame.
- */
-#define PPP_ADDRESS(p)  (((u_char *)(p))[0])
-#define PPP_CONTROL(p)  (((u_char *)(p))[1])
-#define PPP_PROTOCOL(p) ((((u_char *)(p))[2] << 8) + ((u_char *)(p))[3])
-
-/* PPP packet parser states.  Current state indicates operation yet to be
- * completed. */
-typedef enum {
-    PDIDLE = 0,                 /* Idle state - waiting. */
-    PDSTART,                    /* Process start flag. */
-    PDADDRESS,                  /* Process address field. */
-    PDCONTROL,                  /* Process control field. */
-    PDPROTOCOL1,                /* Process protocol field 1. */
-    PDPROTOCOL2,                /* Process protocol field 2. */
-    PDDATA                      /* Process data byte. */
-} PPPDevStates;
-
-#define ESCAPE_P(accm, c) ((accm)[(c) >> 3] & pppACCMMask[c & 0x07])
-
-/************************/
-/*** LOCAL DATA TYPES ***/
-/************************/
-/*
- * PPP interface control block.
- */
-typedef struct PPPControl_s {
-    char openFlag;                      /* True when in use. */
-    char oldFrame;                      /* Old framing character for fd. */
-    sio_fd_t fd;                    /* File device ID of port. */
-    int  kill_link;                     /* Shut the link down. */
-    int  sig_hup;                       /* Carrier lost. */
-    int  if_up;                         /* True when the interface is up. */
-    int  errCode;                       /* Code indicating why interface is down. */
-    struct pbuf *inHead, *inTail;       /* The input packet. */
-    PPPDevStates inState;               /* The input process state. */
-    char inEscaped;                     /* Escape next character. */
-    u16_t inProtocol;                   /* The input protocol code. */
-    u16_t inFCS;                        /* Input Frame Check Sequence value. */
-    int  mtu;                           /* Peer's mru */
-    int  pcomp;                         /* Does peer accept protocol compression? */
-    int  accomp;                        /* Does peer accept addr/ctl compression? */
-    u_long lastXMit;                    /* Time of last transmission. */
-    ext_accm inACCM;                    /* Async-Ctl-Char-Map for input. */
-    ext_accm outACCM;                   /* Async-Ctl-Char-Map for output. */
-#if VJ_SUPPORT > 0
-    int  vjEnabled;                     /* Flag indicating VJ compression enabled. */
-    struct vjcompress vjComp;           /* Van Jabobsen compression header. */
-#endif
-
-    struct netif netif;
-
-    struct ppp_addrs addrs;
-
-    void (*linkStatusCB)(void *ctx, int errCode, void *arg);
-    void *linkStatusCtx;
-
-} PPPControl;
-
-
-/*
- * Ioctl definitions.
- */
-
-struct npioctl {
-    int     protocol;           /* PPP procotol, e.g. PPP_IP */
-    enum NPmode mode;
-};
-
-
-
-/***********************************/
-/*** LOCAL FUNCTION DECLARATIONS ***/
-/***********************************/
-static void pppMain(void *pd);
-static void pppDrop(PPPControl *pc);
-static void pppInProc(int pd, u_char *s, int l);
-
-
-/******************************/
-/*** PUBLIC DATA STRUCTURES ***/
-/******************************/
-u_long subnetMask;
-
-static PPPControl pppControl[NUM_PPP]; /* The PPP interface control blocks. */
-
-/*
- * PPP Data Link Layer "protocol" table.
- * One entry per supported protocol.
- * The last entry must be NULL.
- */
-struct protent *ppp_protocols[] = {
-    &lcp_protent,
-#if PAP_SUPPORT > 0
-    &pap_protent,
-#endif
-#if CHAP_SUPPORT > 0
-    &chap_protent,
-#endif
-#if CBCP_SUPPORT > 0
-    &cbcp_protent,
-#endif
-    &ipcp_protent,
-#if CCP_SUPPORT > 0
-    &ccp_protent,
-#endif
-    NULL
-};
-
-
-/*
- * Buffers for outgoing packets.  This must be accessed only from the appropriate
- * PPP task so that it doesn't need to be protected to avoid collisions.
- */
-u_char outpacket_buf[NUM_PPP][PPP_MRU+PPP_HDRLEN];  
-
-
-/*****************************/
-/*** LOCAL DATA STRUCTURES ***/
-/*****************************/
-
-/*
- * FCS lookup table as calculated by genfcstab.
- */
-static const u_short fcstab[256] = {
-    0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
-    0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
-    0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
-    0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
-    0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
-    0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
-    0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
-    0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
-    0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
-    0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
-    0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
-    0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
-    0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
-    0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
-    0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
-    0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
-    0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
-    0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
-    0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
-    0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
-    0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
-    0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
-    0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
-    0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
-    0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
-    0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
-    0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
-    0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
-    0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
-    0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
-    0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
-    0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
-};
-
-/* PPP's Asynchronous-Control-Character-Map.  The mask array is used
- * to select the specific bit for a character. */
-static u_char pppACCMMask[] = {
-    0x01,
-    0x02,
-    0x04,
-    0x08,
-    0x10,
-    0x20,
-    0x40,
-    0x80
-};
-
-
-/***********************************/
-/*** PUBLIC FUNCTION DEFINITIONS ***/
-/***********************************/
-/* Initialize the PPP subsystem. */
-
-struct ppp_settings ppp_settings;
-
-void pppInit(void)
-{
-    struct protent *protp;
-    int i, j;
-    
-       memset(&ppp_settings, 0, sizeof(ppp_settings));
-       ppp_settings.usepeerdns = 1;
-       pppSetAuth(PPPAUTHTYPE_NONE, NULL, NULL);
-
-       magicInit();
-
-    for (i = 0; i < NUM_PPP; i++) {
-        pppControl[i].openFlag = 0;
-
-               subnetMask = htonl(0xffffff00);
-    
-        /*
-         * Initialize to the standard option set.
-         */
-        for (j = 0; (protp = ppp_protocols[j]) != NULL; ++j)
-            (*protp->init)(i);
-    }
-
-#if LINK_STATS
-    /* Clear the statistics. */
-    memset(&lwip_stats.link, 0, sizeof(lwip_stats.link));
-#endif
-}
-
-void pppSetAuth(enum pppAuthType authType, const char *user, const char *passwd)
-{
-    switch(authType) {
-       case PPPAUTHTYPE_NONE:
-       default:
-#ifdef LWIP_PPP_STRICT_PAP_REJECT
-           ppp_settings.refuse_pap = 1;
-#else
-           /* some providers request pap and accept an empty login/pw */
-           ppp_settings.refuse_pap = 0;
-#endif
-           ppp_settings.refuse_chap = 1;
-           break;
-       case PPPAUTHTYPE_ANY:
-/* Warning: Using PPPAUTHTYPE_ANY might have security consequences.
- * RFC 1994 says:
- *
- * In practice, within or associated with each PPP server, there is a
- * database which associates "user" names with authentication
- * information ("secrets").  It is not anticipated that a particular
- * named user would be authenticated by multiple methods.  This would
- * make the user vulnerable to attacks which negotiate the least secure
- * method from among a set (such as PAP rather than CHAP).  If the same
- * secret was used, PAP would reveal the secret to be used later with
- * CHAP.
- *
- * Instead, for each user name there should be an indication of exactly
- * one method used to authenticate that user name.  If a user needs to
- * make use of different authentication methods under different
- * circumstances, then distinct user names SHOULD be employed, each of
- * which identifies exactly one authentication method.
- *
- */
-           ppp_settings.refuse_pap = 0;
-           ppp_settings.refuse_chap = 0;
-           break;
-       case PPPAUTHTYPE_PAP:
-           ppp_settings.refuse_pap = 0;
-           ppp_settings.refuse_chap = 1;
-           break;
-       case PPPAUTHTYPE_CHAP:
-           ppp_settings.refuse_pap = 1;
-           ppp_settings.refuse_chap = 0;
-           break;
-    }
-
-    if(user) {
-       strncpy(ppp_settings.user, user, sizeof(ppp_settings.user)-1);
-       ppp_settings.user[sizeof(ppp_settings.user)-1] = '\0';
-    } else
-       ppp_settings.user[0] = '\0';
-
-    if(passwd) {
-       strncpy(ppp_settings.passwd, passwd, sizeof(ppp_settings.passwd)-1);
-       ppp_settings.passwd[sizeof(ppp_settings.passwd)-1] = '\0';
-    } else
-       ppp_settings.passwd[0] = '\0';
-}
-
-/* Open a new PPP connection using the given I/O device.
- * This initializes the PPP control block but does not
- * attempt to negotiate the LCP session.  If this port
- * connects to a modem, the modem connection must be
- * established before calling this.
- * Return a new PPP connection descriptor on success or
- * an error code (negative) on failure. */
-int pppOpen(sio_fd_t fd, void (*linkStatusCB)(void *ctx, int errCode, void *arg), void *linkStatusCtx)
-{
-    PPPControl *pc;
-    int pd;
-
-    /* Find a free PPP session descriptor. Critical region? */
-    for (pd = 0; pd < NUM_PPP && pppControl[pd].openFlag != 0; pd++);
-    if (pd >= NUM_PPP)
-        pd = PPPERR_OPEN;
-    else
-        pppControl[pd].openFlag = !0;
-
-    /* Launch a deamon thread. */
-    if (pd >= 0) {
-
-        pppControl[pd].openFlag = 1;
-
-        lcp_init(pd);
-        pc = &pppControl[pd];
-        pc->fd = fd;
-        pc->kill_link = 0;
-        pc->sig_hup = 0;
-        pc->if_up = 0;
-        pc->errCode = 0;
-        pc->inState = PDIDLE;
-        pc->inHead = NULL;
-        pc->inTail = NULL;
-        pc->inEscaped = 0;
-        pc->lastXMit = 0;
-
-#if VJ_SUPPORT > 0
-        pc->vjEnabled = 0;
-        vj_compress_init(&pc->vjComp);
-#endif
-
-        /* 
-         * Default the in and out accm so that escape and flag characters
-         * are always escaped. 
-         */
-        memset(pc->inACCM, 0, sizeof(ext_accm));
-        pc->inACCM[15] = 0x60;
-        memset(pc->outACCM, 0, sizeof(ext_accm));
-        pc->outACCM[15] = 0x60;
-
-       pc->linkStatusCB = linkStatusCB;
-       pc->linkStatusCtx = linkStatusCtx;
-
-       sys_thread_new(pppMain, (void*)pd, PPP_THREAD_PRIO);
-       if(!linkStatusCB) {
-               while(pd >= 0 && !pc->if_up) {
-                       sys_msleep(500);
-                       if (lcp_phase[pd] == PHASE_DEAD) {
-                               pppClose(pd);
-                               if (pc->errCode)
-                                       pd = pc->errCode;
-                               else
-                                       pd = PPPERR_CONNECT;
-                       }
-               }
-       }
-    }
-    return pd;
-}
-
-/* Close a PPP connection and release the descriptor. 
- * Any outstanding packets in the queues are dropped.
- * Return 0 on success, an error code on failure. */
-int pppClose(int pd)
-{
-    PPPControl *pc = &pppControl[pd];
-    int st = 0;
-
-    /* Disconnect */
-    pc->kill_link = !0;
-    pppMainWakeup(pd);
-    
-    if(!pc->linkStatusCB) {
-           while(st >= 0 && lcp_phase[pd] != PHASE_DEAD) {
-                   sys_msleep(500);
-                   break;
-           }
-    }
-    return st;
-}
-
-/* This function is called when carrier is lost on the PPP channel. */
-void pppSigHUP(int pd)
-{
-    PPPControl *pc = &pppControl[pd];
-
-    pc->sig_hup = 1;
-    pppMainWakeup(pd);
-}
-
-static void nPut(PPPControl *pc, struct pbuf *nb)
-{
-       struct pbuf *b;
-       int c;
-
-       for(b = nb; b != NULL; b = b->next) {
-           if((c = sio_write(pc->fd, b->payload, b->len)) != b->len) {
-               PPPDEBUG((LOG_WARNING,
-                           "PPP nPut: incomplete sio_write(%d,, %u) = %d\n", pc->fd, b->len, c));
-#if LINK_STATS
-               lwip_stats.link.err++;
-#endif /* LINK_STATS */
-               pc->lastXMit = 0; /* prepend PPP_FLAG to next packet */
-               break;
-           }
-       }
-       pbuf_free(nb);
-
-#if LINK_STATS
-       lwip_stats.link.xmit++;
-#endif /* LINK_STATS */
-}
-
-/* 
- * pppAppend - append given character to end of given pbuf.  If outACCM
- * is not NULL and the character needs to be escaped, do so.
- * If pbuf is full, append another.
- * Return the current pbuf.
- */
-static struct pbuf *pppAppend(u_char c, struct pbuf *nb, ext_accm *outACCM)
-{
-    struct pbuf *tb = nb;
-    
-    /* Make sure there is room for the character and an escape code.
-     * Sure we don't quite fill the buffer if the character doesn't
-     * get escaped but is one character worth complicating this? */
-    /* Note: We assume no packet header. */
-    if (nb && (PBUF_POOL_BUFSIZE - nb->len) < 2) {
-       tb = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL);
-       if (tb) {
-           nb->next = tb;
-        }
-#if LINK_STATS
-       else {
-           lwip_stats.link.memerr++;
-       }
-#endif /* LINK_STATS */
-       nb = tb;
-    }
-    if (nb) {
-       if (outACCM && ESCAPE_P(*outACCM, c)) {
-            *((u_char*)nb->payload + nb->len++) = PPP_ESCAPE;
-            *((u_char*)nb->payload + nb->len++) = c ^ PPP_TRANS;
-        }
-        else
-            *((u_char*)nb->payload + nb->len++) = c;
-    }
-        
-    return tb;
-}
-
-/* Send a packet on the given connection. */
-static err_t pppifOutput(struct netif *netif, struct pbuf *pb, struct ip_addr *ipaddr)
-{
-    int pd = (int)netif->state;
-    u_short protocol = PPP_IP;
-    PPPControl *pc = &pppControl[pd];
-    u_int fcsOut = PPP_INITFCS;
-    struct pbuf *headMB = NULL, *tailMB = NULL, *p;
-    u_char c;
-
-    (void)ipaddr;
-
-    /* Validate parameters. */
-    /* We let any protocol value go through - it can't hurt us
-     * and the peer will just drop it if it's not accepting it. */
-       if (pd < 0 || pd >= NUM_PPP || !pc->openFlag || !pb) {
-        PPPDEBUG((LOG_WARNING, "pppifOutput[%d]: bad parms prot=%d pb=%p\n",
-                    pd, protocol, pb));
-#if LINK_STATS
-               lwip_stats.link.opterr++;
-               lwip_stats.link.drop++;
-#endif
-               return ERR_ARG;
-       }
-
-    /* Check that the link is up. */
-       if (lcp_phase[pd] == PHASE_DEAD) {
-        PPPDEBUG((LOG_ERR, "pppifOutput[%d]: link not up\n", pd));
-#if LINK_STATS
-               lwip_stats.link.rterr++;
-               lwip_stats.link.drop++;
-#endif
-               return ERR_RTE;
-       }
-
-    /* Grab an output buffer. */
-       headMB = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL);
-    if (headMB == NULL) {
-        PPPDEBUG((LOG_WARNING, "pppifOutput[%d]: first alloc fail\n", pd));
-#if LINK_STATS
-               lwip_stats.link.memerr++;
-               lwip_stats.link.drop++;
-#endif /* LINK_STATS */
-        return ERR_MEM;
-    }
-        
-#if VJ_SUPPORT > 0
-    /* 
-     * Attempt Van Jacobson header compression if VJ is configured and
-     * this is an IP packet. 
-     */
-    if (protocol == PPP_IP && pc->vjEnabled) {
-        switch (vj_compress_tcp(&pc->vjComp, pb)) {
-        case TYPE_IP:
-            /* No change...
-            protocol = PPP_IP_PROTOCOL;
-             */
-            break;
-        case TYPE_COMPRESSED_TCP:
-            protocol = PPP_VJC_COMP;
-            break;
-        case TYPE_UNCOMPRESSED_TCP:
-            protocol = PPP_VJC_UNCOMP;
-            break;
-        default:
-            PPPDEBUG((LOG_WARNING, "pppifOutput[%d]: bad IP packet\n", pd));
-#if LINK_STATS
-                       lwip_stats.link.proterr++;
-                       lwip_stats.link.drop++;
-#endif
-               pbuf_free(headMB);
-            return ERR_VAL;
-        }
-    }
-#endif
-        
-    tailMB = headMB;
-        
-    /* Build the PPP header. */
-    if ((sys_jiffies() - pc->lastXMit) >= PPP_MAXIDLEFLAG)
-        tailMB = pppAppend(PPP_FLAG, tailMB, NULL);
-    pc->lastXMit = sys_jiffies();
-    if (!pc->accomp) {
-        fcsOut = PPP_FCS(fcsOut, PPP_ALLSTATIONS);
-        tailMB = pppAppend(PPP_ALLSTATIONS, tailMB, &pc->outACCM);
-        fcsOut = PPP_FCS(fcsOut, PPP_UI);
-        tailMB = pppAppend(PPP_UI, tailMB, &pc->outACCM);
-    }
-    if (!pc->pcomp || protocol > 0xFF) {
-        c = (protocol >> 8) & 0xFF;
-        fcsOut = PPP_FCS(fcsOut, c);
-        tailMB = pppAppend(c, tailMB, &pc->outACCM);
-    }
-    c = protocol & 0xFF;
-    fcsOut = PPP_FCS(fcsOut, c);
-    tailMB = pppAppend(c, tailMB, &pc->outACCM);
-    
-    /* Load packet. */
-       for(p = pb; p; p = p->next) {
-       int n;
-       u_char *sPtr;
-
-        sPtr = (u_char*)p->payload;
-        n = p->len;
-        while (n-- > 0) {
-            c = *sPtr++;
-            
-            /* Update FCS before checking for special characters. */
-            fcsOut = PPP_FCS(fcsOut, c);
-            
-            /* Copy to output buffer escaping special characters. */
-            tailMB = pppAppend(c, tailMB, &pc->outACCM);
-        }
-    }
-
-    /* Add FCS and trailing flag. */
-    c = ~fcsOut & 0xFF;
-    tailMB = pppAppend(c, tailMB, &pc->outACCM);
-    c = (~fcsOut >> 8) & 0xFF;
-    tailMB = pppAppend(c, tailMB, &pc->outACCM);
-    tailMB = pppAppend(PPP_FLAG, tailMB, NULL);
-        
-    /* If we failed to complete the packet, throw it away. */
-    if (!tailMB) {
-        PPPDEBUG((LOG_WARNING,
-                    "pppifOutput[%d]: Alloc err - dropping proto=%d\n", 
-                    pd, protocol));
-        pbuf_free(headMB);
-#if LINK_STATS
-               lwip_stats.link.memerr++;
-               lwip_stats.link.drop++;
-#endif
-        return ERR_MEM;
-    }
-
-       /* Send it. */
-    PPPDEBUG((LOG_INFO, "pppifOutput[%d]: proto=0x%04X\n", pd, protocol));
-
-    nPut(pc, headMB);
-
-    return ERR_OK;
-}
-
-/* Get and set parameters for the given connection.
- * Return 0 on success, an error code on failure. */
-int  pppIOCtl(int pd, int cmd, void *arg)
-{
-    PPPControl *pc = &pppControl[pd];
-    int st = 0;
-
-    if (pd < 0 || pd >= NUM_PPP)
-        st = PPPERR_PARAM;
-    else {
-        switch(cmd) {
-        case PPPCTLG_UPSTATUS:      /* Get the PPP up status. */
-            if (arg) 
-                *(int *)arg = (int)(pc->if_up);
-            else
-                st = PPPERR_PARAM;
-            break;
-        case PPPCTLS_ERRCODE:       /* Set the PPP error code. */
-            if (arg) 
-                pc->errCode = *(int *)arg;
-            else
-                st = PPPERR_PARAM;
-            break;
-        case PPPCTLG_ERRCODE:       /* Get the PPP error code. */
-            if (arg) 
-                *(int *)arg = (int)(pc->errCode);
-            else
-                st = PPPERR_PARAM;
-            break;
-        case PPPCTLG_FD:
-            if (arg) 
-                *(sio_fd_t *)arg = pc->fd;
-            else
-                st = PPPERR_PARAM;
-            break;
-        default:
-            st = PPPERR_PARAM;
-            break;
-        }
-    }
-    
-    return st;
-}
-
-/*
- * Return the Maximum Transmission Unit for the given PPP connection.
- */
-u_int pppMTU(int pd)
-{
-    PPPControl *pc = &pppControl[pd];
-    u_int st;
-    
-    /* Validate parameters. */
-    if (pd < 0 || pd >= NUM_PPP || !pc->openFlag)
-        st = 0;
-    else
-        st = pc->mtu;
-        
-    return st;
-}
-
-/*
- * Write n characters to a ppp link.
- *  RETURN: >= 0 Number of characters written
- *           -1 Failed to write to device
- */
-int pppWrite(int pd, const u_char *s, int n)
-{
-    PPPControl *pc = &pppControl[pd];
-    u_char c;
-    u_int fcsOut = PPP_INITFCS;
-    struct pbuf *headMB = NULL, *tailMB;
-       headMB = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL);
-    if (headMB == NULL) {
-#if LINK_STATS
-               lwip_stats.link.memerr++;
-               lwip_stats.link.proterr++;
-#endif /* LINK_STATS */
-               return PPPERR_ALLOC;
-    }
-
-    tailMB = headMB;
-        
-    /* If the link has been idle, we'll send a fresh flag character to
-     * flush any noise. */
-    if ((sys_jiffies() - pc->lastXMit) >= PPP_MAXIDLEFLAG)
-        tailMB = pppAppend(PPP_FLAG, tailMB, NULL);
-    pc->lastXMit = sys_jiffies();
-     
-    /* Load output buffer. */
-    while (n-- > 0) {
-        c = *s++;
-        
-        /* Update FCS before checking for special characters. */
-        fcsOut = PPP_FCS(fcsOut, c);
-        
-        /* Copy to output buffer escaping special characters. */
-        tailMB = pppAppend(c, tailMB, &pc->outACCM);
-    }
-    
-    /* Add FCS and trailing flag. */
-    c = ~fcsOut & 0xFF;
-    tailMB = pppAppend(c, tailMB, &pc->outACCM);
-    c = (~fcsOut >> 8) & 0xFF;
-    tailMB = pppAppend(c, tailMB, &pc->outACCM);
-    tailMB = pppAppend(PPP_FLAG, tailMB, NULL);
-        
-    /* If we failed to complete the packet, throw it away.
-     * Otherwise send it. */
-    if (!tailMB) {
-               PPPDEBUG((LOG_WARNING,
-                "pppWrite[%d]: Alloc err - dropping pbuf len=%d\n", pd, headMB->len));
-/*                "pppWrite[%d]: Alloc err - dropping %d:%.*H", pd, headMB->len, LWIP_MIN(headMB->len * 2, 40), headMB->payload)); */
-               pbuf_free(headMB);
-#if LINK_STATS
-               lwip_stats.link.memerr++;
-               lwip_stats.link.proterr++;
-#endif /* LINK_STATS */
-               return PPPERR_ALLOC;
-       }
-
-    PPPDEBUG((LOG_INFO, "pppWrite[%d]: len=%d\n", pd, headMB->len));
-/*     "pppWrite[%d]: %d:%.*H", pd, headMB->len, LWIP_MIN(headMB->len * 2, 40), headMB->payload)); */
-    nPut(pc, headMB);
-
-    return PPPERR_NONE;
-}
-
-/*
- * ppp_send_config - configure the transmit characteristics of
- * the ppp interface.
- */
-void ppp_send_config(
-    int unit, 
-    int mtu,
-    u32_t asyncmap,
-    int pcomp, 
-    int accomp
-)
-{
-    PPPControl *pc = &pppControl[unit];
-    int i;
-    
-    pc->mtu = mtu;
-    pc->pcomp = pcomp;
-    pc->accomp = accomp;
-    
-    /* Load the ACCM bits for the 32 control codes. */
-    for (i = 0; i < 32/8; i++)
-        pc->outACCM[i] = (u_char)((asyncmap >> (8 * i)) & 0xFF);
-    PPPDEBUG((LOG_INFO, "ppp_send_config[%d]: outACCM=%X %X %X %X\n",
-                unit,
-                pc->outACCM[0], pc->outACCM[1], pc->outACCM[2], pc->outACCM[3]));
-}
-
-
-/*
- * ppp_set_xaccm - set the extended transmit ACCM for the interface.
- */
-void ppp_set_xaccm(int unit, ext_accm *accm)
-{
-    memcpy(pppControl[unit].outACCM, accm, sizeof(ext_accm));
-    PPPDEBUG((LOG_INFO, "ppp_set_xaccm[%d]: outACCM=%X %X %X %X\n",
-                unit,
-                pppControl[unit].outACCM[0],
-                pppControl[unit].outACCM[1],
-                pppControl[unit].outACCM[2],
-                pppControl[unit].outACCM[3]));
-}
-
-
-/*
- * ppp_recv_config - configure the receive-side characteristics of
- * the ppp interface.
- */
-void ppp_recv_config(
-    int unit, 
-    int mru,
-    u32_t asyncmap,
-    int pcomp, 
-    int accomp
-)
-{
-    PPPControl *pc = &pppControl[unit];
-    int i;
-    
-       (void)accomp;
-       (void)pcomp;
-       (void)mru;
-
-    /* Load the ACCM bits for the 32 control codes. */
-    for (i = 0; i < 32 / 8; i++)
-        pc->inACCM[i] = (u_char)(asyncmap >> (i * 8));
-    PPPDEBUG((LOG_INFO, "ppp_recv_config[%d]: inACCM=%X %X %X %X\n",
-                unit,
-                pc->inACCM[0], pc->inACCM[1], pc->inACCM[2], pc->inACCM[3]));
-}
-
-#if 0
-/*
- * ccp_test - ask kernel whether a given compression method
- * is acceptable for use.  Returns 1 if the method and parameters
- * are OK, 0 if the method is known but the parameters are not OK
- * (e.g. code size should be reduced), or -1 if the method is unknown.
- */
-int ccp_test(
-    int unit, 
-    int opt_len, 
-    int for_transmit,
-    u_char *opt_ptr
-)
-{
-    return 0;   /* XXX Currently no compression. */
-}
-
-/*
- * ccp_flags_set - inform kernel about the current state of CCP.
- */
-void ccp_flags_set(int unit, int isopen, int isup)
-{
-    /* XXX */
-}
-
-/*
- * ccp_fatal_error - returns 1 if decompression was disabled as a
- * result of an error detected after decompression of a packet,
- * 0 otherwise.  This is necessary because of patent nonsense.
- */
-int ccp_fatal_error(int unit)
-{
-    /* XXX */
-    return 0;
-}
-#endif
-
-/*
- * get_idle_time - return how long the link has been idle.
- */
-int get_idle_time(int u, struct ppp_idle *ip)
-{   
-    /* XXX */
-       (void)u;
-       (void)ip;
-
-    return 0;
-}
-
-
-/*
- * Return user specified netmask, modified by any mask we might determine
- * for address `addr' (in network byte order).
- * Here we scan through the system's list of interfaces, looking for
- * any non-point-to-point interfaces which might appear to be on the same
- * network as `addr'.  If we find any, we OR in their netmask to the
- * user-specified netmask.
- */
-u32_t GetMask(u32_t addr)
-{
-    u32_t mask, nmask;
-    
-    htonl(addr);
-    if (IN_CLASSA(addr))    /* determine network mask for address class */
-        nmask = IN_CLASSA_NET;
-    else if (IN_CLASSB(addr))
-        nmask = IN_CLASSB_NET;
-    else
-        nmask = IN_CLASSC_NET;
-    /* class D nets are disallowed by bad_ip_adrs */
-    mask = subnetMask | htonl(nmask);
-    
-    /* XXX
-     * Scan through the system's network interfaces.
-     * Get each netmask and OR them into our mask.
-     */
-    
-    return mask;
-}
-
-/*
- * sifvjcomp - config tcp header compression
- */
-int sifvjcomp(
-    int pd, 
-    int vjcomp, 
-    int cidcomp, 
-    int maxcid
-)
-{
-#if VJ_SUPPORT > 0
-    PPPControl *pc = &pppControl[pd];
-    
-    pc->vjEnabled = vjcomp;
-    pc->vjComp.compressSlot = cidcomp;
-    pc->vjComp.maxSlotIndex = maxcid;
-    PPPDEBUG((LOG_INFO, "sifvjcomp: VJ compress enable=%d slot=%d max slot=%d\n",
-                vjcomp, cidcomp, maxcid));
-#endif
-
-    return 0;
-}
-
-/*
- * pppifNetifInit - netif init callback
- */
-static err_t pppifNetifInit(struct netif *netif)
-{
-       netif->name[0] = 'p';
-       netif->name[1] = 'p';
-       netif->output = pppifOutput;
-       netif->mtu = pppMTU((int)netif->state);
-       return ERR_OK;
-}
-
-
-/*
- * sifup - Config the interface up and enable IP packets to pass.
- */
-int sifup(int pd)
-{
-    PPPControl *pc = &pppControl[pd];
-    int st = 1;
-    
-    if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) {
-        st = 0;
-        PPPDEBUG((LOG_WARNING, "sifup[%d]: bad parms\n", pd));
-    } else {
-               netif_remove(&pc->netif);
-               if (netif_add(&pc->netif, &pc->addrs.our_ipaddr, &pc->addrs.netmask, &pc->addrs.his_ipaddr, (void *)pd, pppifNetifInit, ip_input)) {
-                       pc->if_up = 1;
-                       pc->errCode = PPPERR_NONE;
-
-                       PPPDEBUG((LOG_DEBUG, "sifup: unit %d: linkStatusCB=%lx errCode=%d\n", pd, pc->linkStatusCB, pc->errCode));
-                       if(pc->linkStatusCB)
-                               pc->linkStatusCB(pc->linkStatusCtx, pc->errCode, &pc->addrs);
-               } else {
-               st = 0;
-               PPPDEBUG((LOG_ERR, "sifup[%d]: netif_add failed\n", pd));
-               }
-    }
-
-    return st;
-}
-
-/*
- * sifnpmode - Set the mode for handling packets for a given NP.
- */
-int sifnpmode(int u, int proto, enum NPmode mode)
-{
-       (void)u;
-       (void)proto;
-       (void)mode;
-    return 0;
-}
-
-/*
- * sifdown - Config the interface down and disable IP.
- */
-int sifdown(int pd)
-{
-    PPPControl *pc = &pppControl[pd];
-    int st = 1;
-    
-    if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) {
-        st = 0;
-        PPPDEBUG((LOG_WARNING, "sifdown[%d]: bad parms\n", pd));
-    } else {
-        pc->if_up = 0;
-       netif_remove(&pc->netif);
-       PPPDEBUG((LOG_DEBUG, "sifdown: unit %d: linkStatusCB=%lx errCode=%d\n", pd, pc->linkStatusCB, pc->errCode));
-       if(pc->linkStatusCB)
-               pc->linkStatusCB(pc->linkStatusCtx, PPPERR_CONNECT, NULL);
-       }
-    return st;
-}
-
-/*
- * sifaddr - Config the interface IP addresses and netmask.
- */
-int sifaddr(
-    int pd,             /* Interface unit ??? */
-    u32_t o,        /* Our IP address ??? */
-    u32_t h,        /* His IP address ??? */
-    u32_t m,        /* IP subnet mask ??? */
-    u32_t ns1,      /* Primary DNS */
-    u32_t ns2       /* Secondary DNS */
-)
-{
-    PPPControl *pc = &pppControl[pd];
-    int st = 1;
-    
-    if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) {
-        st = 0;
-        PPPDEBUG((LOG_WARNING, "sifup[%d]: bad parms\n", pd));
-    } else {
-               memcpy(&pc->addrs.our_ipaddr, &o, sizeof(o));
-               memcpy(&pc->addrs.his_ipaddr, &h, sizeof(h));
-               memcpy(&pc->addrs.netmask, &m, sizeof(m));
-               memcpy(&pc->addrs.dns1, &ns1, sizeof(ns1));
-               memcpy(&pc->addrs.dns2, &ns2, sizeof(ns2));
-    }
-    return st;
-}
-
-/*
- * cifaddr - Clear the interface IP addresses, and delete routes
- * through the interface if possible.
- */
-int cifaddr(
-    int pd,         /* Interface unit ??? */
-    u32_t o,    /* Our IP address ??? */
-    u32_t h     /* IP broadcast address ??? */
-)
-{
-    PPPControl *pc = &pppControl[pd];
-    int st = 1;
-    
-       (void)o;
-       (void)h;
-    if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) {
-        st = 0;
-        PPPDEBUG((LOG_WARNING, "sifup[%d]: bad parms\n", pd));
-    } else {
-               IP4_ADDR(&pc->addrs.our_ipaddr, 0,0,0,0);
-               IP4_ADDR(&pc->addrs.his_ipaddr, 0,0,0,0);
-               IP4_ADDR(&pc->addrs.netmask, 255,255,255,0);
-               IP4_ADDR(&pc->addrs.dns1, 0,0,0,0);
-               IP4_ADDR(&pc->addrs.dns2, 0,0,0,0);
-    }
-    return st;
-}
-
-/*
- * sifdefaultroute - assign a default route through the address given.
- */
-int sifdefaultroute(int pd, u32_t l, u32_t g)
-{
-    PPPControl *pc = &pppControl[pd];
-    int st = 1;
-    
-       (void)l;
-       (void)g;
-    if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) {
-        st = 0;
-        PPPDEBUG((LOG_WARNING, "sifup[%d]: bad parms\n", pd));
-    } else {
-               netif_set_default(&pc->netif);
-    }
-
-    /* TODO: check how PPP handled the netMask, previously not set by ipSetDefault */
-
-    return st;
-}
-
-/*
- * cifdefaultroute - delete a default route through the address given.
- */
-int cifdefaultroute(int pd, u32_t l, u32_t g)
-{
-    PPPControl *pc = &pppControl[pd];
-    int st = 1;
-    
-       (void)l;
-       (void)g;
-    if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) {
-        st = 0;
-        PPPDEBUG((LOG_WARNING, "sifup[%d]: bad parms\n", pd));
-    } else {
-               netif_set_default(NULL);
-    }
-
-    return st;
-}
-
-void
-pppMainWakeup(int pd)
-{
-       PPPDEBUG((LOG_DEBUG, "pppMainWakeup: unit %d\n", pd));
-       sio_read_abort(pppControl[pd].fd);
-}
-
-/* these callbacks are necessary because lcp_* functions
-   must be called in the same context as pppInput(),
-   namely the tcpip_thread(), essentially because
-   they manipulate timeouts which are thread-private
-*/
-
-static void
-pppStartCB(void *arg)
-{
-    int pd = (int)arg;
-
-       PPPDEBUG((LOG_DEBUG, "pppStartCB: unit %d\n", pd));
-    lcp_lowerup(pd);
-    lcp_open(pd);      /* Start protocol */
-}
-
-static void
-pppStopCB(void *arg)
-{
-    int pd = (int)arg;
-
-       PPPDEBUG((LOG_DEBUG, "pppStopCB: unit %d\n", pd));
-    lcp_close(pd, "User request");
-}
-
-static void
-pppHupCB(void *arg)
-{
-    int pd = (int)arg;
-
-       PPPDEBUG((LOG_DEBUG, "pppHupCB: unit %d\n", pd));
-    lcp_lowerdown(pd);
-    link_terminated(pd);
-}
-/**********************************/
-/*** LOCAL FUNCTION DEFINITIONS ***/
-/**********************************/
-/* The main PPP process function.  This implements the state machine according
- * to section 4 of RFC 1661: The Point-To-Point Protocol. */
-static void pppMain(void *arg)
-{
-    int pd = (int)arg;
-    struct pbuf *p;
-    PPPControl* pc;
-
-    pc = &pppControl[pd];
-
-    p = pbuf_alloc(PBUF_RAW, PPP_MRU+PPP_HDRLEN, PBUF_RAM);
-    if(!p) {
-               LWIP_ASSERT("p != NULL", p);
-               pc->errCode = PPPERR_ALLOC;
-               goto out;
-    }
-
-    /*
-     * Start the connection and handle incoming events (packet or timeout).
-     */
-       PPPDEBUG((LOG_INFO, "pppMain: unit %d: Connecting\n", pd));
-    tcpip_callback(pppStartCB, arg);
-    while (lcp_phase[pd] != PHASE_DEAD) {
-        if (pc->kill_link) {
-               PPPDEBUG((LOG_DEBUG, "pppMainWakeup: unit %d kill_link -> pppStopCB\n", pd));
-               pc->errCode = PPPERR_USER;
-               /* This will leave us at PHASE_DEAD. */
-               tcpip_callback(pppStopCB, arg);
-               pc->kill_link = 0;
-        }
-        else if (pc->sig_hup) {
-               PPPDEBUG((LOG_DEBUG, "pppMainWakeup: unit %d sig_hup -> pppHupCB\n", pd));
-               pc->sig_hup = 0;
-               tcpip_callback(pppHupCB, arg);
-        } else {
-               int c = sio_read(pc->fd, p->payload, p->len);
-               if(c > 0) {
-                       pppInProc(pd, p->payload, c);
-               } else {
-                   PPPDEBUG((LOG_DEBUG, "pppMainWakeup: unit %d sio_read len=%d returned %d\n", pd, p->len, c));
-                   sys_msleep(1); /* give other tasks a chance to run */
-               }
-        }
-    }
-       PPPDEBUG((LOG_INFO, "pppMain: unit %d: PHASE_DEAD\n", pd));
-    pbuf_free(p);
-
-out:
-       PPPDEBUG((LOG_DEBUG, "pppMain: unit %d: linkStatusCB=%lx errCode=%d\n", pd, pc->linkStatusCB, pc->errCode));
-    if(pc->linkStatusCB)
-           pc->linkStatusCB(pc->linkStatusCtx, pc->errCode ? pc->errCode : PPPERR_PROTOCOL, NULL);
-
-    pc->openFlag = 0;
-}
-
-static struct pbuf *pppSingleBuf(struct pbuf *p)
-{
-       struct pbuf *q, *b;
-       u_char *pl;
-
-       if(p->tot_len == p->len)
-               return p;
-
-       q = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM);
-       if(!q) {
-               PPPDEBUG((LOG_ERR,
-                        "pppSingleBuf: unable to alloc new buf (%d)\n", p->tot_len));
-               return p; /* live dangerously */
-       }
-
-       for(b = p, pl = q->payload; b != NULL; b = b->next) {
-               memcpy(pl, b->payload, b->len);
-               pl += b->len;
-       }
-
-       pbuf_free(p);
-
-       return q;
-}
-
-struct pppInputHeader {
-       int unit;
-       u16_t proto;
-};
-
-/*
- * Pass the processed input packet to the appropriate handler.
- * This function and all handlers run in the context of the tcpip_thread
- */
-static void pppInput(void *arg)
-{
-       struct pbuf *nb = (struct pbuf *)arg;
-    u16_t protocol;
-    int pd;
-
-       pd = ((struct pppInputHeader *)nb->payload)->unit;
-       protocol = ((struct pppInputHeader *)nb->payload)->proto;
-
-    pbuf_header(nb, -(int)sizeof(struct pppInputHeader));
-
-#if LINK_STATS
-    lwip_stats.link.recv++;
-#endif /* LINK_STATS */
-
-    /*
-     * Toss all non-LCP packets unless LCP is OPEN.
-     * Until we get past the authentication phase, toss all packets
-     * except LCP, LQR and authentication packets.
-     */
-    if((lcp_phase[pd] <= PHASE_AUTHENTICATE) && (protocol != PPP_LCP)) {
-           if(!((protocol == PPP_LQR) || (protocol == PPP_PAP) || (protocol == PPP_CHAP)) ||
-                       (lcp_phase[pd] != PHASE_AUTHENTICATE)) {
-               PPPDEBUG((LOG_INFO, "pppInput: discarding proto 0x%04X in phase %d\n", protocol, lcp_phase[pd]));
-               goto drop;
-           }
-    }
-
-    switch(protocol) {
-    case PPP_VJC_COMP:      /* VJ compressed TCP */
-#if VJ_SUPPORT > 0
-        PPPDEBUG((LOG_INFO, "pppInput[%d]: vj_comp in pbuf len=%d\n", pd, nb->len));
-        /*
-         * Clip off the VJ header and prepend the rebuilt TCP/IP header and
-         * pass the result to IP.
-         */
-        if (vj_uncompress_tcp(&nb, &pppControl[pd].vjComp) >= 0) {
-            pppControl[pd].netif.input(nb, &pppControl[pd].netif);
-                       return;
-        }
-       /* Something's wrong so drop it. */
-       PPPDEBUG((LOG_WARNING, "pppInput[%d]: Dropping VJ compressed\n", pd));
-#else
-        /* No handler for this protocol so drop the packet. */
-        PPPDEBUG((LOG_INFO, "pppInput[%d]: drop VJ Comp in %d:%s\n", pd, nb->len, nb->payload));
-#endif /* VJ_SUPPORT > 0 */
-       break;
-    case PPP_VJC_UNCOMP:    /* VJ uncompressed TCP */
-#if VJ_SUPPORT > 0
-        PPPDEBUG((LOG_INFO, "pppInput[%d]: vj_un in pbuf len=%d\n", pd, nb->len));
-        /*
-         * Process the TCP/IP header for VJ header compression and then pass
-         * the packet to IP.
-         */
-        if (vj_uncompress_uncomp(nb, &pppControl[pd].vjComp) >= 0) {
-            pppControl[pd].netif.input(nb, &pppControl[pd].netif);
-                       return;
-        }
-       /* Something's wrong so drop it. */
-       PPPDEBUG((LOG_WARNING, "pppInput[%d]: Dropping VJ uncompressed\n", pd));
-#else
-        /* No handler for this protocol so drop the packet. */
-        PPPDEBUG((LOG_INFO,
-                    "pppInput[%d]: drop VJ UnComp in %d:.*H\n", 
-                    pd, nb->len, LWIP_MIN(nb->len * 2, 40), nb->payload));
-#endif /* VJ_SUPPORT > 0 */
-       break;
-    case PPP_IP:            /* Internet Protocol */
-        PPPDEBUG((LOG_INFO, "pppInput[%d]: ip in pbuf len=%d\n", pd, nb->len));
-        pppControl[pd].netif.input(nb, &pppControl[pd].netif);
-               return;
-    default:
-       {
-               struct protent *protp;
-               int i;
-
-               /*
-                * Upcall the proper protocol input routine.
-                */
-               for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i) {
-                       if (protp->protocol == protocol && protp->enabled_flag) {
-                               PPPDEBUG((LOG_INFO, "pppInput[%d]: %s len=%d\n", pd, protp->name, nb->len));
-                               nb = pppSingleBuf(nb);
-                               (*protp->input)(pd, nb->payload, nb->len);
-                               goto out;
-                       }
-               }
-
-               /* No handler for this protocol so reject the packet. */
-               PPPDEBUG((LOG_INFO, "pppInput[%d]: rejecting unsupported proto 0x%04X len=%d\n", pd, protocol, nb->len));
-               pbuf_header(nb, sizeof(protocol));
-#if BYTE_ORDER == LITTLE_ENDIAN
-               protocol = htons(protocol);
-               memcpy(nb->payload, &protocol, sizeof(protocol));
-#endif
-               lcp_sprotrej(pd, nb->payload, nb->len);
-       }
-       break;
-    }
-
-drop:
-#if LINK_STATS
-    lwip_stats.link.drop++;
-#endif
-
-out:
-    pbuf_free(nb);
-    return;
-}
-
-
-/*
- * Drop the input packet.
- */
-static void pppDrop(PPPControl *pc)
-{
-    if (pc->inHead != NULL) {
-#if 0      
-        PPPDEBUG((LOG_INFO, "pppDrop: %d:%.*H\n", pc->inHead->len, min(60, pc->inHead->len * 2), pc->inHead->payload));
-#endif 
-        PPPDEBUG((LOG_INFO, "pppDrop: pbuf len=%d\n", pc->inHead->len));
-       if (pc->inTail && (pc->inTail != pc->inHead))
-           pbuf_free(pc->inTail);
-        pbuf_free(pc->inHead);
-        pc->inHead = NULL;
-        pc->inTail = NULL;
-    }
-#if VJ_SUPPORT > 0
-    vj_uncompress_err(&pc->vjComp);
-#endif
-
-#if LINK_STATS
-    lwip_stats.link.drop++;
-#endif /* LINK_STATS */
-}
-
-
-/*
- * Process a received octet string.
- */
-static void pppInProc(int pd, u_char *s, int l)
-{
-    PPPControl *pc = &pppControl[pd];
-    struct pbuf *nextNBuf;
-    u_char curChar;
-
-    PPPDEBUG((LOG_DEBUG, "pppInProc[%d]: got %d bytes\n", pd, l));
-    while (l-- > 0) {
-        curChar = *s++;
-        
-        /* Handle special characters. */
-        if (ESCAPE_P(pc->inACCM, curChar)) {
-            /* Check for escape sequences. */
-            /* XXX Note that this does not handle an escaped 0x5d character which
-             * would appear as an escape character.  Since this is an ASCII ']'
-             * and there is no reason that I know of to escape it, I won't complicate
-             * the code to handle this case. GLL */
-            if (curChar == PPP_ESCAPE)
-                pc->inEscaped = 1;
-            /* Check for the flag character. */
-            else if (curChar == PPP_FLAG) {
-                /* If this is just an extra flag character, ignore it. */
-                if (pc->inState <= PDADDRESS)
-                    ;
-                /* If we haven't received the packet header, drop what has come in. */
-                else if (pc->inState < PDDATA) {
-                    PPPDEBUG((LOG_WARNING,
-                                "pppInProc[%d]: Dropping incomplete packet %d\n", 
-                                pd, pc->inState));
-#if LINK_STATS
-                                       lwip_stats.link.lenerr++;
-#endif
-                    pppDrop(pc);
-                }
-                /* If the fcs is invalid, drop the packet. */
-                else if (pc->inFCS != PPP_GOODFCS) {
-                    PPPDEBUG((LOG_INFO,
-                                "pppInProc[%d]: Dropping bad fcs 0x%04X proto=0x%04X\n", 
-                                pd, pc->inFCS, pc->inProtocol));
-#if LINK_STATS
-                                       lwip_stats.link.chkerr++;
-#endif
-                    pppDrop(pc);
-                }
-                /* Otherwise it's a good packet so pass it on. */
-                else {
-                    
-                    /* Trim off the checksum. */
-                   if(pc->inTail->len >= 2) {
-                       pc->inTail->len -= 2;
-
-                       pc->inTail->tot_len = pc->inTail->len;
-                       if (pc->inTail != pc->inHead) {
-                           pbuf_cat(pc->inHead, pc->inTail);
-                       }
-                   } else {
-                       pc->inTail->tot_len = pc->inTail->len;
-                       if (pc->inTail != pc->inHead) {
-                           pbuf_cat(pc->inHead, pc->inTail);
-                       }
-
-                       pbuf_realloc(pc->inHead, pc->inHead->tot_len - 2);
-                   }
-
-                    /* Dispatch the packet thereby consuming it. */
-                   if(tcpip_callback(pppInput, pc->inHead) != ERR_OK) {
-                       PPPDEBUG((LOG_ERR,
-                                   "pppInProc[%d]: tcpip_callback() failed, dropping packet\n", pd));
-                       pbuf_free(pc->inHead);
-#if LINK_STATS
-                       lwip_stats.link.drop++;
-#endif
-                   }
-                    pc->inHead = NULL;
-                    pc->inTail = NULL;
-                }
-                    
-                /* Prepare for a new packet. */
-                pc->inFCS = PPP_INITFCS;
-                pc->inState = PDADDRESS;
-                pc->inEscaped = 0;
-            }
-            /* Other characters are usually control characters that may have
-             * been inserted by the physical layer so here we just drop them. */
-            else {
-                PPPDEBUG((LOG_WARNING,
-                            "pppInProc[%d]: Dropping ACCM char <%d>\n", pd, curChar));
-            }
-        }
-        /* Process other characters. */
-        else {
-            /* Unencode escaped characters. */
-            if (pc->inEscaped) {
-                pc->inEscaped = 0;
-                curChar ^= PPP_TRANS;
-            }
-            
-            /* Process character relative to current state. */
-            switch(pc->inState) {
-            case PDIDLE:                    /* Idle state - waiting. */
-                /* Drop the character if it's not 0xff
-                 * we would have processed a flag character above. */
-                if (curChar != PPP_ALLSTATIONS) {
-                       break;
-                               }
-
-                               /* Fall through */
-            case PDSTART:                   /* Process start flag. */
-                /* Prepare for a new packet. */
-                pc->inFCS = PPP_INITFCS;
-
-                               /* Fall through */
-            case PDADDRESS:                 /* Process address field. */
-                if (curChar == PPP_ALLSTATIONS) {
-                    pc->inState = PDCONTROL;
-                    break;
-                }
-                /* Else assume compressed address and control fields so
-                 * fall through to get the protocol... */
-            case PDCONTROL:                 /* Process control field. */
-                /* If we don't get a valid control code, restart. */
-                if (curChar == PPP_UI) {
-                    pc->inState = PDPROTOCOL1;
-                       break;
-                }
-#if 0
-                else {
-                    PPPDEBUG((LOG_WARNING,
-                                "pppInProc[%d]: Invalid control <%d>\n", pd, curChar));
-                    pc->inState = PDSTART;
-                }
-#endif
-            case PDPROTOCOL1:               /* Process protocol field 1. */
-                /* If the lower bit is set, this is the end of the protocol
-                 * field. */
-                if (curChar & 1) {
-                    pc->inProtocol = curChar;
-                    pc->inState = PDDATA;
-                }
-                else {
-                    pc->inProtocol = (u_int)curChar << 8;
-                    pc->inState = PDPROTOCOL2;
-                }
-                break;
-            case PDPROTOCOL2:               /* Process protocol field 2. */
-                pc->inProtocol |= curChar;
-                pc->inState = PDDATA;
-                break;
-            case PDDATA:                    /* Process data byte. */
-                /* Make space to receive processed data. */
-                if (pc->inTail == NULL || pc->inTail->len == PBUF_POOL_BUFSIZE) {
-                   if(pc->inTail) {
-                       pc->inTail->tot_len = pc->inTail->len;
-                       if (pc->inTail != pc->inHead) {
-                           pbuf_cat(pc->inHead, pc->inTail);
-                       }
-                   }
-                    /* If we haven't started a packet, we need a packet header. */
-                    nextNBuf = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL);
-                    if (nextNBuf == NULL) {
-                        /* No free buffers.  Drop the input packet and let the
-                         * higher layers deal with it.  Continue processing
-                         * the received pbuf chain in case a new packet starts. */
-                        PPPDEBUG((LOG_ERR, "pppInProc[%d]: NO FREE MBUFS!\n", pd));
-#if LINK_STATS
-                                               lwip_stats.link.memerr++;
-#endif /* LINK_STATS */
-                        pppDrop(pc);
-                        pc->inState = PDSTART;  /* Wait for flag sequence. */
-                       break;
-                    }
-                   if (pc->inHead == NULL) {
-                       struct pppInputHeader *pih = nextNBuf->payload;
-
-                       pih->unit = pd;
-                       pih->proto = pc->inProtocol;
-
-                       nextNBuf->len += sizeof(*pih);
-
-                       pc->inHead = nextNBuf;
-                   }
-                   pc->inTail = nextNBuf;
-                }
-                /* Load character into buffer. */
-                ((u_char*)pc->inTail->payload)[pc->inTail->len++] = curChar;
-                break;
-            }
-
-            /* update the frame check sequence number. */
-            pc->inFCS = PPP_FCS(pc->inFCS, curChar);
-        }
-    }
-       avRandomize();
-}
-
-#endif /* PPP_SUPPORT */
+/*****************************************************************************\r
+* ppp.c - Network Point to Point Protocol program file.\r
+*\r
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.\r
+* portions Copyright (c) 1997 by Global Election Systems Inc.\r
+*\r
+* The authors hereby grant permission to use, copy, modify, distribute,\r
+* and license this software and its documentation for any purpose, provided\r
+* that existing copyright notices are retained in all copies and that this\r
+* notice and the following disclaimer are included verbatim in any \r
+* distributions. No written agreement, license, or royalty fee is required\r
+* for any of the authorized uses.\r
+*\r
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR\r
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+*\r
+******************************************************************************\r
+* REVISION HISTORY\r
+*\r
+* 03-01-01 Marc Boucher <marc@mbsi.ca>\r
+*   Ported to lwIP.\r
+* 97-11-05 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.\r
+*   Original.\r
+*****************************************************************************/\r
+\r
+/*\r
+ * ppp_defs.h - PPP definitions.\r
+ *\r
+ * if_pppvar.h - private structures and declarations for PPP.\r
+ *\r
+ * Copyright (c) 1994 The Australian National University.\r
+ * All rights reserved.\r
+ *\r
+ * Permission to use, copy, modify, and distribute this software and its\r
+ * documentation is hereby granted, provided that the above copyright\r
+ * notice appears in all copies.  This software is provided without any\r
+ * warranty, express or implied. The Australian National University\r
+ * makes no representations about the suitability of this software for\r
+ * any purpose.\r
+ *\r
+ * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY\r
+ * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES\r
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF\r
+ * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY\r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,\r
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY\r
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS\r
+ * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO\r
+ * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,\r
+ * OR MODIFICATIONS.\r
+ */\r
+\r
+/*\r
+ * if_ppp.h - Point-to-Point Protocol definitions.\r
+ *\r
+ * Copyright (c) 1989 Carnegie Mellon University.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms are permitted\r
+ * provided that the above copyright notice and this paragraph are\r
+ * duplicated in all such forms and that any documentation,\r
+ * advertising materials, and other materials related to such\r
+ * distribution and use acknowledge that the software was developed\r
+ * by Carnegie Mellon University.  The name of the\r
+ * University may not be used to endorse or promote products derived\r
+ * from this software without specific prior written permission.\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR\r
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r
+ */\r
\r
+#include <string.h>\r
\r
+#include "ppp.h"\r
+#if PPP_SUPPORT > 0\r
+#include "randm.h"\r
+#include "fsm.h"\r
+#if PAP_SUPPORT > 0\r
+#include "pap.h"\r
+#endif\r
+#if CHAP_SUPPORT > 0\r
+#include "chap.h"\r
+#endif\r
+#include "ipcp.h"\r
+#include "lcp.h"\r
+#include "magic.h"\r
+#include "auth.h"\r
+#if VJ_SUPPORT > 0\r
+#include "vj.h"\r
+#endif\r
+\r
+#include "pppdebug.h"\r
+\r
+/*************************/\r
+/*** LOCAL DEFINITIONS ***/\r
+/*************************/\r
+\r
+/*\r
+ * The basic PPP frame.\r
+ */\r
+#define PPP_ADDRESS(p)  (((u_char *)(p))[0])\r
+#define PPP_CONTROL(p)  (((u_char *)(p))[1])\r
+#define PPP_PROTOCOL(p) ((((u_char *)(p))[2] << 8) + ((u_char *)(p))[3])\r
+\r
+/* PPP packet parser states.  Current state indicates operation yet to be\r
+ * completed. */\r
+typedef enum {\r
+    PDIDLE = 0,                 /* Idle state - waiting. */\r
+    PDSTART,                    /* Process start flag. */\r
+    PDADDRESS,                  /* Process address field. */\r
+    PDCONTROL,                  /* Process control field. */\r
+    PDPROTOCOL1,                /* Process protocol field 1. */\r
+    PDPROTOCOL2,                /* Process protocol field 2. */\r
+    PDDATA                      /* Process data byte. */\r
+} PPPDevStates;\r
+\r
+#define ESCAPE_P(accm, c) ((accm)[(c) >> 3] & pppACCMMask[c & 0x07])\r
+\r
+/************************/\r
+/*** LOCAL DATA TYPES ***/\r
+/************************/\r
+/*\r
+ * PPP interface control block.\r
+ */\r
+typedef struct PPPControl_s {\r
+    char openFlag;                      /* True when in use. */\r
+    char oldFrame;                      /* Old framing character for fd. */\r
+    sio_fd_t fd;                    /* File device ID of port. */\r
+    int  kill_link;                     /* Shut the link down. */\r
+    int  sig_hup;                       /* Carrier lost. */\r
+    int  if_up;                         /* True when the interface is up. */\r
+    int  errCode;                       /* Code indicating why interface is down. */\r
+    struct pbuf *inHead, *inTail;       /* The input packet. */\r
+    PPPDevStates inState;               /* The input process state. */\r
+    char inEscaped;                     /* Escape next character. */\r
+    u16_t inProtocol;                   /* The input protocol code. */\r
+    u16_t inFCS;                        /* Input Frame Check Sequence value. */\r
+    int  mtu;                           /* Peer's mru */\r
+    int  pcomp;                         /* Does peer accept protocol compression? */\r
+    int  accomp;                        /* Does peer accept addr/ctl compression? */\r
+    u_long lastXMit;                    /* Time of last transmission. */\r
+    ext_accm inACCM;                    /* Async-Ctl-Char-Map for input. */\r
+    ext_accm outACCM;                   /* Async-Ctl-Char-Map for output. */\r
+#if VJ_SUPPORT > 0\r
+    int  vjEnabled;                     /* Flag indicating VJ compression enabled. */\r
+    struct vjcompress vjComp;           /* Van Jabobsen compression header. */\r
+#endif\r
+\r
+    struct netif netif;\r
+\r
+    struct ppp_addrs addrs;\r
+\r
+    void (*linkStatusCB)(void *ctx, int errCode, void *arg);\r
+    void *linkStatusCtx;\r
+\r
+} PPPControl;\r
+\r
+\r
+/*\r
+ * Ioctl definitions.\r
+ */\r
+\r
+struct npioctl {\r
+    int     protocol;           /* PPP procotol, e.g. PPP_IP */\r
+    enum NPmode mode;\r
+};\r
+\r
+\r
+\r
+/***********************************/\r
+/*** LOCAL FUNCTION DECLARATIONS ***/\r
+/***********************************/\r
+static void pppMain(void *pd);\r
+static void pppDrop(PPPControl *pc);\r
+static void pppInProc(int pd, u_char *s, int l);\r
+\r
+\r
+/******************************/\r
+/*** PUBLIC DATA STRUCTURES ***/\r
+/******************************/\r
+u_long subnetMask;\r
+\r
+static PPPControl pppControl[NUM_PPP]; /* The PPP interface control blocks. */\r
+\r
+/*\r
+ * PPP Data Link Layer "protocol" table.\r
+ * One entry per supported protocol.\r
+ * The last entry must be NULL.\r
+ */\r
+struct protent *ppp_protocols[] = {\r
+    &lcp_protent,\r
+#if PAP_SUPPORT > 0\r
+    &pap_protent,\r
+#endif\r
+#if CHAP_SUPPORT > 0\r
+    &chap_protent,\r
+#endif\r
+#if CBCP_SUPPORT > 0\r
+    &cbcp_protent,\r
+#endif\r
+    &ipcp_protent,\r
+#if CCP_SUPPORT > 0\r
+    &ccp_protent,\r
+#endif\r
+    NULL\r
+};\r
+\r
+\r
+/*\r
+ * Buffers for outgoing packets.  This must be accessed only from the appropriate\r
+ * PPP task so that it doesn't need to be protected to avoid collisions.\r
+ */\r
+u_char outpacket_buf[NUM_PPP][PPP_MRU+PPP_HDRLEN];  \r
+\r
+\r
+/*****************************/\r
+/*** LOCAL DATA STRUCTURES ***/\r
+/*****************************/\r
+\r
+/*\r
+ * FCS lookup table as calculated by genfcstab.\r
+ */\r
+static const u_short fcstab[256] = {\r
+    0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,\r
+    0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,\r
+    0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,\r
+    0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,\r
+    0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,\r
+    0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,\r
+    0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,\r
+    0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,\r
+    0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,\r
+    0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,\r
+    0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,\r
+    0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,\r
+    0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,\r
+    0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,\r
+    0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,\r
+    0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,\r
+    0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,\r
+    0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,\r
+    0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,\r
+    0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,\r
+    0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,\r
+    0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,\r
+    0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,\r
+    0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,\r
+    0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,\r
+    0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,\r
+    0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,\r
+    0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,\r
+    0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,\r
+    0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,\r
+    0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,\r
+    0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78\r
+};\r
+\r
+/* PPP's Asynchronous-Control-Character-Map.  The mask array is used\r
+ * to select the specific bit for a character. */\r
+static u_char pppACCMMask[] = {\r
+    0x01,\r
+    0x02,\r
+    0x04,\r
+    0x08,\r
+    0x10,\r
+    0x20,\r
+    0x40,\r
+    0x80\r
+};\r
+\r
+\r
+/***********************************/\r
+/*** PUBLIC FUNCTION DEFINITIONS ***/\r
+/***********************************/\r
+/* Initialize the PPP subsystem. */\r
+\r
+struct ppp_settings ppp_settings;\r
+\r
+void pppInit(void)\r
+{\r
+    struct protent *protp;\r
+    int i, j;\r
+    \r
+       memset(&ppp_settings, 0, sizeof(ppp_settings));\r
+       ppp_settings.usepeerdns = 1;\r
+       pppSetAuth(PPPAUTHTYPE_NONE, NULL, NULL);\r
+\r
+       magicInit();\r
+\r
+    for (i = 0; i < NUM_PPP; i++) {\r
+        pppControl[i].openFlag = 0;\r
+\r
+               subnetMask = htonl(0xffffff00);\r
+    \r
+        /*\r
+         * Initialize to the standard option set.\r
+         */\r
+        for (j = 0; (protp = ppp_protocols[j]) != NULL; ++j)\r
+            (*protp->init)(i);\r
+    }\r
+\r
+#if LINK_STATS\r
+    /* Clear the statistics. */\r
+    memset(&lwip_stats.link, 0, sizeof(lwip_stats.link));\r
+#endif\r
+}\r
+\r
+void pppSetAuth(enum pppAuthType authType, const char *user, const char *passwd)\r
+{\r
+    switch(authType) {\r
+       case PPPAUTHTYPE_NONE:\r
+       default:\r
+#ifdef LWIP_PPP_STRICT_PAP_REJECT\r
+           ppp_settings.refuse_pap = 1;\r
+#else\r
+           /* some providers request pap and accept an empty login/pw */\r
+           ppp_settings.refuse_pap = 0;\r
+#endif\r
+           ppp_settings.refuse_chap = 1;\r
+           break;\r
+       case PPPAUTHTYPE_ANY:\r
+/* Warning: Using PPPAUTHTYPE_ANY might have security consequences.\r
+ * RFC 1994 says:\r
+ *\r
+ * In practice, within or associated with each PPP server, there is a\r
+ * database which associates "user" names with authentication\r
+ * information ("secrets").  It is not anticipated that a particular\r
+ * named user would be authenticated by multiple methods.  This would\r
+ * make the user vulnerable to attacks which negotiate the least secure\r
+ * method from among a set (such as PAP rather than CHAP).  If the same\r
+ * secret was used, PAP would reveal the secret to be used later with\r
+ * CHAP.\r
+ *\r
+ * Instead, for each user name there should be an indication of exactly\r
+ * one method used to authenticate that user name.  If a user needs to\r
+ * make use of different authentication methods under different\r
+ * circumstances, then distinct user names SHOULD be employed, each of\r
+ * which identifies exactly one authentication method.\r
+ *\r
+ */\r
+           ppp_settings.refuse_pap = 0;\r
+           ppp_settings.refuse_chap = 0;\r
+           break;\r
+       case PPPAUTHTYPE_PAP:\r
+           ppp_settings.refuse_pap = 0;\r
+           ppp_settings.refuse_chap = 1;\r
+           break;\r
+       case PPPAUTHTYPE_CHAP:\r
+           ppp_settings.refuse_pap = 1;\r
+           ppp_settings.refuse_chap = 0;\r
+           break;\r
+    }\r
+\r
+    if(user) {\r
+       strncpy(ppp_settings.user, user, sizeof(ppp_settings.user)-1);\r
+       ppp_settings.user[sizeof(ppp_settings.user)-1] = '\0';\r
+    } else\r
+       ppp_settings.user[0] = '\0';\r
+\r
+    if(passwd) {\r
+       strncpy(ppp_settings.passwd, passwd, sizeof(ppp_settings.passwd)-1);\r
+       ppp_settings.passwd[sizeof(ppp_settings.passwd)-1] = '\0';\r
+    } else\r
+       ppp_settings.passwd[0] = '\0';\r
+}\r
+\r
+/* Open a new PPP connection using the given I/O device.\r
+ * This initializes the PPP control block but does not\r
+ * attempt to negotiate the LCP session.  If this port\r
+ * connects to a modem, the modem connection must be\r
+ * established before calling this.\r
+ * Return a new PPP connection descriptor on success or\r
+ * an error code (negative) on failure. */\r
+int pppOpen(sio_fd_t fd, void (*linkStatusCB)(void *ctx, int errCode, void *arg), void *linkStatusCtx)\r
+{\r
+    PPPControl *pc;\r
+    int pd;\r
+\r
+    /* Find a free PPP session descriptor. Critical region? */\r
+    for (pd = 0; pd < NUM_PPP && pppControl[pd].openFlag != 0; pd++);\r
+    if (pd >= NUM_PPP)\r
+        pd = PPPERR_OPEN;\r
+    else\r
+        pppControl[pd].openFlag = !0;\r
+\r
+    /* Launch a deamon thread. */\r
+    if (pd >= 0) {\r
+\r
+        pppControl[pd].openFlag = 1;\r
+\r
+        lcp_init(pd);\r
+        pc = &pppControl[pd];\r
+        pc->fd = fd;\r
+        pc->kill_link = 0;\r
+        pc->sig_hup = 0;\r
+        pc->if_up = 0;\r
+        pc->errCode = 0;\r
+        pc->inState = PDIDLE;\r
+        pc->inHead = NULL;\r
+        pc->inTail = NULL;\r
+        pc->inEscaped = 0;\r
+        pc->lastXMit = 0;\r
+\r
+#if VJ_SUPPORT > 0\r
+        pc->vjEnabled = 0;\r
+        vj_compress_init(&pc->vjComp);\r
+#endif\r
+\r
+        /* \r
+         * Default the in and out accm so that escape and flag characters\r
+         * are always escaped. \r
+         */\r
+        memset(pc->inACCM, 0, sizeof(ext_accm));\r
+        pc->inACCM[15] = 0x60;\r
+        memset(pc->outACCM, 0, sizeof(ext_accm));\r
+        pc->outACCM[15] = 0x60;\r
+\r
+       pc->linkStatusCB = linkStatusCB;\r
+       pc->linkStatusCtx = linkStatusCtx;\r
+\r
+       sys_thread_new(pppMain, (void*)pd, PPP_THREAD_PRIO);\r
+       if(!linkStatusCB) {\r
+               while(pd >= 0 && !pc->if_up) {\r
+                       sys_msleep(500);\r
+                       if (lcp_phase[pd] == PHASE_DEAD) {\r
+                               pppClose(pd);\r
+                               if (pc->errCode)\r
+                                       pd = pc->errCode;\r
+                               else\r
+                                       pd = PPPERR_CONNECT;\r
+                       }\r
+               }\r
+       }\r
+    }\r
+    return pd;\r
+}\r
+\r
+/* Close a PPP connection and release the descriptor. \r
+ * Any outstanding packets in the queues are dropped.\r
+ * Return 0 on success, an error code on failure. */\r
+int pppClose(int pd)\r
+{\r
+    PPPControl *pc = &pppControl[pd];\r
+    int st = 0;\r
+\r
+    /* Disconnect */\r
+    pc->kill_link = !0;\r
+    pppMainWakeup(pd);\r
+    \r
+    if(!pc->linkStatusCB) {\r
+           while(st >= 0 && lcp_phase[pd] != PHASE_DEAD) {\r
+                   sys_msleep(500);\r
+                   break;\r
+           }\r
+    }\r
+    return st;\r
+}\r
+\r
+/* This function is called when carrier is lost on the PPP channel. */\r
+void pppSigHUP(int pd)\r
+{\r
+    PPPControl *pc = &pppControl[pd];\r
+\r
+    pc->sig_hup = 1;\r
+    pppMainWakeup(pd);\r
+}\r
+\r
+static void nPut(PPPControl *pc, struct pbuf *nb)\r
+{\r
+       struct pbuf *b;\r
+       int c;\r
+\r
+       for(b = nb; b != NULL; b = b->next) {\r
+           if((c = sio_write(pc->fd, b->payload, b->len)) != b->len) {\r
+               PPPDEBUG((LOG_WARNING,\r
+                           "PPP nPut: incomplete sio_write(%d,, %u) = %d\n", pc->fd, b->len, c));\r
+#if LINK_STATS\r
+               lwip_stats.link.err++;\r
+#endif /* LINK_STATS */\r
+               pc->lastXMit = 0; /* prepend PPP_FLAG to next packet */\r
+               break;\r
+           }\r
+       }\r
+       pbuf_free(nb);\r
+\r
+#if LINK_STATS\r
+       lwip_stats.link.xmit++;\r
+#endif /* LINK_STATS */\r
+}\r
+\r
+/* \r
+ * pppAppend - append given character to end of given pbuf.  If outACCM\r
+ * is not NULL and the character needs to be escaped, do so.\r
+ * If pbuf is full, append another.\r
+ * Return the current pbuf.\r
+ */\r
+static struct pbuf *pppAppend(u_char c, struct pbuf *nb, ext_accm *outACCM)\r
+{\r
+    struct pbuf *tb = nb;\r
+    \r
+    /* Make sure there is room for the character and an escape code.\r
+     * Sure we don't quite fill the buffer if the character doesn't\r
+     * get escaped but is one character worth complicating this? */\r
+    /* Note: We assume no packet header. */\r
+    if (nb && (PBUF_POOL_BUFSIZE - nb->len) < 2) {\r
+       tb = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL);\r
+       if (tb) {\r
+           nb->next = tb;\r
+        }\r
+#if LINK_STATS\r
+       else {\r
+           lwip_stats.link.memerr++;\r
+       }\r
+#endif /* LINK_STATS */\r
+       nb = tb;\r
+    }\r
+    if (nb) {\r
+       if (outACCM && ESCAPE_P(*outACCM, c)) {\r
+            *((u_char*)nb->payload + nb->len++) = PPP_ESCAPE;\r
+            *((u_char*)nb->payload + nb->len++) = c ^ PPP_TRANS;\r
+        }\r
+        else\r
+            *((u_char*)nb->payload + nb->len++) = c;\r
+    }\r
+        \r
+    return tb;\r
+}\r
+\r
+/* Send a packet on the given connection. */\r
+static err_t pppifOutput(struct netif *netif, struct pbuf *pb, struct ip_addr *ipaddr)\r
+{\r
+    int pd = (int)netif->state;\r
+    u_short protocol = PPP_IP;\r
+    PPPControl *pc = &pppControl[pd];\r
+    u_int fcsOut = PPP_INITFCS;\r
+    struct pbuf *headMB = NULL, *tailMB = NULL, *p;\r
+    u_char c;\r
+\r
+    (void)ipaddr;\r
+\r
+    /* Validate parameters. */\r
+    /* We let any protocol value go through - it can't hurt us\r
+     * and the peer will just drop it if it's not accepting it. */\r
+       if (pd < 0 || pd >= NUM_PPP || !pc->openFlag || !pb) {\r
+        PPPDEBUG((LOG_WARNING, "pppifOutput[%d]: bad parms prot=%d pb=%p\n",\r
+                    pd, protocol, pb));\r
+#if LINK_STATS\r
+               lwip_stats.link.opterr++;\r
+               lwip_stats.link.drop++;\r
+#endif\r
+               return ERR_ARG;\r
+       }\r
+\r
+    /* Check that the link is up. */\r
+       if (lcp_phase[pd] == PHASE_DEAD) {\r
+        PPPDEBUG((LOG_ERR, "pppifOutput[%d]: link not up\n", pd));\r
+#if LINK_STATS\r
+               lwip_stats.link.rterr++;\r
+               lwip_stats.link.drop++;\r
+#endif\r
+               return ERR_RTE;\r
+       }\r
+\r
+    /* Grab an output buffer. */\r
+       headMB = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL);\r
+    if (headMB == NULL) {\r
+        PPPDEBUG((LOG_WARNING, "pppifOutput[%d]: first alloc fail\n", pd));\r
+#if LINK_STATS\r
+               lwip_stats.link.memerr++;\r
+               lwip_stats.link.drop++;\r
+#endif /* LINK_STATS */\r
+        return ERR_MEM;\r
+    }\r
+        \r
+#if VJ_SUPPORT > 0\r
+    /* \r
+     * Attempt Van Jacobson header compression if VJ is configured and\r
+     * this is an IP packet. \r
+     */\r
+    if (protocol == PPP_IP && pc->vjEnabled) {\r
+        switch (vj_compress_tcp(&pc->vjComp, pb)) {\r
+        case TYPE_IP:\r
+            /* No change...\r
+            protocol = PPP_IP_PROTOCOL;\r
+             */\r
+            break;\r
+        case TYPE_COMPRESSED_TCP:\r
+            protocol = PPP_VJC_COMP;\r
+            break;\r
+        case TYPE_UNCOMPRESSED_TCP:\r
+            protocol = PPP_VJC_UNCOMP;\r
+            break;\r
+        default:\r
+            PPPDEBUG((LOG_WARNING, "pppifOutput[%d]: bad IP packet\n", pd));\r
+#if LINK_STATS\r
+                       lwip_stats.link.proterr++;\r
+                       lwip_stats.link.drop++;\r
+#endif\r
+               pbuf_free(headMB);\r
+            return ERR_VAL;\r
+        }\r
+    }\r
+#endif\r
+        \r
+    tailMB = headMB;\r
+        \r
+    /* Build the PPP header. */\r
+    if ((sys_jiffies() - pc->lastXMit) >= PPP_MAXIDLEFLAG)\r
+        tailMB = pppAppend(PPP_FLAG, tailMB, NULL);\r
+    pc->lastXMit = sys_jiffies();\r
+    if (!pc->accomp) {\r
+        fcsOut = PPP_FCS(fcsOut, PPP_ALLSTATIONS);\r
+        tailMB = pppAppend(PPP_ALLSTATIONS, tailMB, &pc->outACCM);\r
+        fcsOut = PPP_FCS(fcsOut, PPP_UI);\r
+        tailMB = pppAppend(PPP_UI, tailMB, &pc->outACCM);\r
+    }\r
+    if (!pc->pcomp || protocol > 0xFF) {\r
+        c = (protocol >> 8) & 0xFF;\r
+        fcsOut = PPP_FCS(fcsOut, c);\r
+        tailMB = pppAppend(c, tailMB, &pc->outACCM);\r
+    }\r
+    c = protocol & 0xFF;\r
+    fcsOut = PPP_FCS(fcsOut, c);\r
+    tailMB = pppAppend(c, tailMB, &pc->outACCM);\r
+    \r
+    /* Load packet. */\r
+       for(p = pb; p; p = p->next) {\r
+       int n;\r
+       u_char *sPtr;\r
+\r
+        sPtr = (u_char*)p->payload;\r
+        n = p->len;\r
+        while (n-- > 0) {\r
+            c = *sPtr++;\r
+            \r
+            /* Update FCS before checking for special characters. */\r
+            fcsOut = PPP_FCS(fcsOut, c);\r
+            \r
+            /* Copy to output buffer escaping special characters. */\r
+            tailMB = pppAppend(c, tailMB, &pc->outACCM);\r
+        }\r
+    }\r
+\r
+    /* Add FCS and trailing flag. */\r
+    c = ~fcsOut & 0xFF;\r
+    tailMB = pppAppend(c, tailMB, &pc->outACCM);\r
+    c = (~fcsOut >> 8) & 0xFF;\r
+    tailMB = pppAppend(c, tailMB, &pc->outACCM);\r
+    tailMB = pppAppend(PPP_FLAG, tailMB, NULL);\r
+        \r
+    /* If we failed to complete the packet, throw it away. */\r
+    if (!tailMB) {\r
+        PPPDEBUG((LOG_WARNING,\r
+                    "pppifOutput[%d]: Alloc err - dropping proto=%d\n", \r
+                    pd, protocol));\r
+        pbuf_free(headMB);\r
+#if LINK_STATS\r
+               lwip_stats.link.memerr++;\r
+               lwip_stats.link.drop++;\r
+#endif\r
+        return ERR_MEM;\r
+    }\r
+\r
+       /* Send it. */\r
+    PPPDEBUG((LOG_INFO, "pppifOutput[%d]: proto=0x%04X\n", pd, protocol));\r
+\r
+    nPut(pc, headMB);\r
+\r
+    return ERR_OK;\r
+}\r
+\r
+/* Get and set parameters for the given connection.\r
+ * Return 0 on success, an error code on failure. */\r
+int  pppIOCtl(int pd, int cmd, void *arg)\r
+{\r
+    PPPControl *pc = &pppControl[pd];\r
+    int st = 0;\r
+\r
+    if (pd < 0 || pd >= NUM_PPP)\r
+        st = PPPERR_PARAM;\r
+    else {\r
+        switch(cmd) {\r
+        case PPPCTLG_UPSTATUS:      /* Get the PPP up status. */\r
+            if (arg) \r
+                *(int *)arg = (int)(pc->if_up);\r
+            else\r
+                st = PPPERR_PARAM;\r
+            break;\r
+        case PPPCTLS_ERRCODE:       /* Set the PPP error code. */\r
+            if (arg) \r
+                pc->errCode = *(int *)arg;\r
+            else\r
+                st = PPPERR_PARAM;\r
+            break;\r
+        case PPPCTLG_ERRCODE:       /* Get the PPP error code. */\r
+            if (arg) \r
+                *(int *)arg = (int)(pc->errCode);\r
+            else\r
+                st = PPPERR_PARAM;\r
+            break;\r
+        case PPPCTLG_FD:\r
+            if (arg) \r
+                *(sio_fd_t *)arg = pc->fd;\r
+            else\r
+                st = PPPERR_PARAM;\r
+            break;\r
+        default:\r
+            st = PPPERR_PARAM;\r
+            break;\r
+        }\r
+    }\r
+    \r
+    return st;\r
+}\r
+\r
+/*\r
+ * Return the Maximum Transmission Unit for the given PPP connection.\r
+ */\r
+u_int pppMTU(int pd)\r
+{\r
+    PPPControl *pc = &pppControl[pd];\r
+    u_int st;\r
+    \r
+    /* Validate parameters. */\r
+    if (pd < 0 || pd >= NUM_PPP || !pc->openFlag)\r
+        st = 0;\r
+    else\r
+        st = pc->mtu;\r
+        \r
+    return st;\r
+}\r
+\r
+/*\r
+ * Write n characters to a ppp link.\r
+ *  RETURN: >= 0 Number of characters written\r
+ *           -1 Failed to write to device\r
+ */\r
+int pppWrite(int pd, const u_char *s, int n)\r
+{\r
+    PPPControl *pc = &pppControl[pd];\r
+    u_char c;\r
+    u_int fcsOut = PPP_INITFCS;\r
+    struct pbuf *headMB = NULL, *tailMB;\r
+       headMB = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL);\r
+    if (headMB == NULL) {\r
+#if LINK_STATS\r
+               lwip_stats.link.memerr++;\r
+               lwip_stats.link.proterr++;\r
+#endif /* LINK_STATS */\r
+               return PPPERR_ALLOC;\r
+    }\r
+\r
+    tailMB = headMB;\r
+        \r
+    /* If the link has been idle, we'll send a fresh flag character to\r
+     * flush any noise. */\r
+    if ((sys_jiffies() - pc->lastXMit) >= PPP_MAXIDLEFLAG)\r
+        tailMB = pppAppend(PPP_FLAG, tailMB, NULL);\r
+    pc->lastXMit = sys_jiffies();\r
+     \r
+    /* Load output buffer. */\r
+    while (n-- > 0) {\r
+        c = *s++;\r
+        \r
+        /* Update FCS before checking for special characters. */\r
+        fcsOut = PPP_FCS(fcsOut, c);\r
+        \r
+        /* Copy to output buffer escaping special characters. */\r
+        tailMB = pppAppend(c, tailMB, &pc->outACCM);\r
+    }\r
+    \r
+    /* Add FCS and trailing flag. */\r
+    c = ~fcsOut & 0xFF;\r
+    tailMB = pppAppend(c, tailMB, &pc->outACCM);\r
+    c = (~fcsOut >> 8) & 0xFF;\r
+    tailMB = pppAppend(c, tailMB, &pc->outACCM);\r
+    tailMB = pppAppend(PPP_FLAG, tailMB, NULL);\r
+        \r
+    /* If we failed to complete the packet, throw it away.\r
+     * Otherwise send it. */\r
+    if (!tailMB) {\r
+               PPPDEBUG((LOG_WARNING,\r
+                "pppWrite[%d]: Alloc err - dropping pbuf len=%d\n", pd, headMB->len));\r
+/*                "pppWrite[%d]: Alloc err - dropping %d:%.*H", pd, headMB->len, LWIP_MIN(headMB->len * 2, 40), headMB->payload)); */\r
+               pbuf_free(headMB);\r
+#if LINK_STATS\r
+               lwip_stats.link.memerr++;\r
+               lwip_stats.link.proterr++;\r
+#endif /* LINK_STATS */\r
+               return PPPERR_ALLOC;\r
+       }\r
+\r
+    PPPDEBUG((LOG_INFO, "pppWrite[%d]: len=%d\n", pd, headMB->len));\r
+/*     "pppWrite[%d]: %d:%.*H", pd, headMB->len, LWIP_MIN(headMB->len * 2, 40), headMB->payload)); */\r
+    nPut(pc, headMB);\r
+\r
+    return PPPERR_NONE;\r
+}\r
+\r
+/*\r
+ * ppp_send_config - configure the transmit characteristics of\r
+ * the ppp interface.\r
+ */\r
+void ppp_send_config(\r
+    int unit, \r
+    int mtu,\r
+    u32_t asyncmap,\r
+    int pcomp, \r
+    int accomp\r
+)\r
+{\r
+    PPPControl *pc = &pppControl[unit];\r
+    int i;\r
+    \r
+    pc->mtu = mtu;\r
+    pc->pcomp = pcomp;\r
+    pc->accomp = accomp;\r
+    \r
+    /* Load the ACCM bits for the 32 control codes. */\r
+    for (i = 0; i < 32/8; i++)\r
+        pc->outACCM[i] = (u_char)((asyncmap >> (8 * i)) & 0xFF);\r
+    PPPDEBUG((LOG_INFO, "ppp_send_config[%d]: outACCM=%X %X %X %X\n",\r
+                unit,\r
+                pc->outACCM[0], pc->outACCM[1], pc->outACCM[2], pc->outACCM[3]));\r
+}\r
+\r
+\r
+/*\r
+ * ppp_set_xaccm - set the extended transmit ACCM for the interface.\r
+ */\r
+void ppp_set_xaccm(int unit, ext_accm *accm)\r
+{\r
+    memcpy(pppControl[unit].outACCM, accm, sizeof(ext_accm));\r
+    PPPDEBUG((LOG_INFO, "ppp_set_xaccm[%d]: outACCM=%X %X %X %X\n",\r
+                unit,\r
+                pppControl[unit].outACCM[0],\r
+                pppControl[unit].outACCM[1],\r
+                pppControl[unit].outACCM[2],\r
+                pppControl[unit].outACCM[3]));\r
+}\r
+\r
+\r
+/*\r
+ * ppp_recv_config - configure the receive-side characteristics of\r
+ * the ppp interface.\r
+ */\r
+void ppp_recv_config(\r
+    int unit, \r
+    int mru,\r
+    u32_t asyncmap,\r
+    int pcomp, \r
+    int accomp\r
+)\r
+{\r
+    PPPControl *pc = &pppControl[unit];\r
+    int i;\r
+    \r
+       (void)accomp;\r
+       (void)pcomp;\r
+       (void)mru;\r
+\r
+    /* Load the ACCM bits for the 32 control codes. */\r
+    for (i = 0; i < 32 / 8; i++)\r
+        pc->inACCM[i] = (u_char)(asyncmap >> (i * 8));\r
+    PPPDEBUG((LOG_INFO, "ppp_recv_config[%d]: inACCM=%X %X %X %X\n",\r
+                unit,\r
+                pc->inACCM[0], pc->inACCM[1], pc->inACCM[2], pc->inACCM[3]));\r
+}\r
+\r
+#if 0\r
+/*\r
+ * ccp_test - ask kernel whether a given compression method\r
+ * is acceptable for use.  Returns 1 if the method and parameters\r
+ * are OK, 0 if the method is known but the parameters are not OK\r
+ * (e.g. code size should be reduced), or -1 if the method is unknown.\r
+ */\r
+int ccp_test(\r
+    int unit, \r
+    int opt_len, \r
+    int for_transmit,\r
+    u_char *opt_ptr\r
+)\r
+{\r
+    return 0;   /* XXX Currently no compression. */\r
+}\r
+\r
+/*\r
+ * ccp_flags_set - inform kernel about the current state of CCP.\r
+ */\r
+void ccp_flags_set(int unit, int isopen, int isup)\r
+{\r
+    /* XXX */\r
+}\r
+\r
+/*\r
+ * ccp_fatal_error - returns 1 if decompression was disabled as a\r
+ * result of an error detected after decompression of a packet,\r
+ * 0 otherwise.  This is necessary because of patent nonsense.\r
+ */\r
+int ccp_fatal_error(int unit)\r
+{\r
+    /* XXX */\r
+    return 0;\r
+}\r
+#endif\r
+\r
+/*\r
+ * get_idle_time - return how long the link has been idle.\r
+ */\r
+int get_idle_time(int u, struct ppp_idle *ip)\r
+{   \r
+    /* XXX */\r
+       (void)u;\r
+       (void)ip;\r
+\r
+    return 0;\r
+}\r
+\r
+\r
+/*\r
+ * Return user specified netmask, modified by any mask we might determine\r
+ * for address `addr' (in network byte order).\r
+ * Here we scan through the system's list of interfaces, looking for\r
+ * any non-point-to-point interfaces which might appear to be on the same\r
+ * network as `addr'.  If we find any, we OR in their netmask to the\r
+ * user-specified netmask.\r
+ */\r
+u32_t GetMask(u32_t addr)\r
+{\r
+    u32_t mask, nmask;\r
+    \r
+    htonl(addr);\r
+    if (IN_CLASSA(addr))    /* determine network mask for address class */\r
+        nmask = IN_CLASSA_NET;\r
+    else if (IN_CLASSB(addr))\r
+        nmask = IN_CLASSB_NET;\r
+    else\r
+        nmask = IN_CLASSC_NET;\r
+    /* class D nets are disallowed by bad_ip_adrs */\r
+    mask = subnetMask | htonl(nmask);\r
+    \r
+    /* XXX\r
+     * Scan through the system's network interfaces.\r
+     * Get each netmask and OR them into our mask.\r
+     */\r
+    \r
+    return mask;\r
+}\r
+\r
+/*\r
+ * sifvjcomp - config tcp header compression\r
+ */\r
+int sifvjcomp(\r
+    int pd, \r
+    int vjcomp, \r
+    int cidcomp, \r
+    int maxcid\r
+)\r
+{\r
+#if VJ_SUPPORT > 0\r
+    PPPControl *pc = &pppControl[pd];\r
+    \r
+    pc->vjEnabled = vjcomp;\r
+    pc->vjComp.compressSlot = cidcomp;\r
+    pc->vjComp.maxSlotIndex = maxcid;\r
+    PPPDEBUG((LOG_INFO, "sifvjcomp: VJ compress enable=%d slot=%d max slot=%d\n",\r
+                vjcomp, cidcomp, maxcid));\r
+#endif\r
+\r
+    return 0;\r
+}\r
+\r
+/*\r
+ * pppifNetifInit - netif init callback\r
+ */\r
+static err_t pppifNetifInit(struct netif *netif)\r
+{\r
+       netif->name[0] = 'p';\r
+       netif->name[1] = 'p';\r
+       netif->output = pppifOutput;\r
+       netif->mtu = pppMTU((int)netif->state);\r
+       return ERR_OK;\r
+}\r
+\r
+\r
+/*\r
+ * sifup - Config the interface up and enable IP packets to pass.\r
+ */\r
+int sifup(int pd)\r
+{\r
+    PPPControl *pc = &pppControl[pd];\r
+    int st = 1;\r
+    \r
+    if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) {\r
+        st = 0;\r
+        PPPDEBUG((LOG_WARNING, "sifup[%d]: bad parms\n", pd));\r
+    } else {\r
+               netif_remove(&pc->netif);\r
+               if (netif_add(&pc->netif, &pc->addrs.our_ipaddr, &pc->addrs.netmask, &pc->addrs.his_ipaddr, (void *)pd, pppifNetifInit, ip_input)) {\r
+                       pc->if_up = 1;\r
+                       pc->errCode = PPPERR_NONE;\r
+\r
+                       PPPDEBUG((LOG_DEBUG, "sifup: unit %d: linkStatusCB=%lx errCode=%d\n", pd, pc->linkStatusCB, pc->errCode));\r
+                       if(pc->linkStatusCB)\r
+                               pc->linkStatusCB(pc->linkStatusCtx, pc->errCode, &pc->addrs);\r
+               } else {\r
+               st = 0;\r
+               PPPDEBUG((LOG_ERR, "sifup[%d]: netif_add failed\n", pd));\r
+               }\r
+    }\r
+\r
+    return st;\r
+}\r
+\r
+/*\r
+ * sifnpmode - Set the mode for handling packets for a given NP.\r
+ */\r
+int sifnpmode(int u, int proto, enum NPmode mode)\r
+{\r
+       (void)u;\r
+       (void)proto;\r
+       (void)mode;\r
+    return 0;\r
+}\r
+\r
+/*\r
+ * sifdown - Config the interface down and disable IP.\r
+ */\r
+int sifdown(int pd)\r
+{\r
+    PPPControl *pc = &pppControl[pd];\r
+    int st = 1;\r
+    \r
+    if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) {\r
+        st = 0;\r
+        PPPDEBUG((LOG_WARNING, "sifdown[%d]: bad parms\n", pd));\r
+    } else {\r
+        pc->if_up = 0;\r
+       netif_remove(&pc->netif);\r
+       PPPDEBUG((LOG_DEBUG, "sifdown: unit %d: linkStatusCB=%lx errCode=%d\n", pd, pc->linkStatusCB, pc->errCode));\r
+       if(pc->linkStatusCB)\r
+               pc->linkStatusCB(pc->linkStatusCtx, PPPERR_CONNECT, NULL);\r
+       }\r
+    return st;\r
+}\r
+\r
+/*\r
+ * sifaddr - Config the interface IP addresses and netmask.\r
+ */\r
+int sifaddr(\r
+    int pd,             /* Interface unit ??? */\r
+    u32_t o,        /* Our IP address ??? */\r
+    u32_t h,        /* His IP address ??? */\r
+    u32_t m,        /* IP subnet mask ??? */\r
+    u32_t ns1,      /* Primary DNS */\r
+    u32_t ns2       /* Secondary DNS */\r
+)\r
+{\r
+    PPPControl *pc = &pppControl[pd];\r
+    int st = 1;\r
+    \r
+    if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) {\r
+        st = 0;\r
+        PPPDEBUG((LOG_WARNING, "sifup[%d]: bad parms\n", pd));\r
+    } else {\r
+               memcpy(&pc->addrs.our_ipaddr, &o, sizeof(o));\r
+               memcpy(&pc->addrs.his_ipaddr, &h, sizeof(h));\r
+               memcpy(&pc->addrs.netmask, &m, sizeof(m));\r
+               memcpy(&pc->addrs.dns1, &ns1, sizeof(ns1));\r
+               memcpy(&pc->addrs.dns2, &ns2, sizeof(ns2));\r
+    }\r
+    return st;\r
+}\r
+\r
+/*\r
+ * cifaddr - Clear the interface IP addresses, and delete routes\r
+ * through the interface if possible.\r
+ */\r
+int cifaddr(\r
+    int pd,         /* Interface unit ??? */\r
+    u32_t o,    /* Our IP address ??? */\r
+    u32_t h     /* IP broadcast address ??? */\r
+)\r
+{\r
+    PPPControl *pc = &pppControl[pd];\r
+    int st = 1;\r
+    \r
+       (void)o;\r
+       (void)h;\r
+    if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) {\r
+        st = 0;\r
+        PPPDEBUG((LOG_WARNING, "sifup[%d]: bad parms\n", pd));\r
+    } else {\r
+               IP4_ADDR(&pc->addrs.our_ipaddr, 0,0,0,0);\r
+               IP4_ADDR(&pc->addrs.his_ipaddr, 0,0,0,0);\r
+               IP4_ADDR(&pc->addrs.netmask, 255,255,255,0);\r
+               IP4_ADDR(&pc->addrs.dns1, 0,0,0,0);\r
+               IP4_ADDR(&pc->addrs.dns2, 0,0,0,0);\r
+    }\r
+    return st;\r
+}\r
+\r
+/*\r
+ * sifdefaultroute - assign a default route through the address given.\r
+ */\r
+int sifdefaultroute(int pd, u32_t l, u32_t g)\r
+{\r
+    PPPControl *pc = &pppControl[pd];\r
+    int st = 1;\r
+    \r
+       (void)l;\r
+       (void)g;\r
+    if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) {\r
+        st = 0;\r
+        PPPDEBUG((LOG_WARNING, "sifup[%d]: bad parms\n", pd));\r
+    } else {\r
+               netif_set_default(&pc->netif);\r
+    }\r
+\r
+    /* TODO: check how PPP handled the netMask, previously not set by ipSetDefault */\r
+\r
+    return st;\r
+}\r
+\r
+/*\r
+ * cifdefaultroute - delete a default route through the address given.\r
+ */\r
+int cifdefaultroute(int pd, u32_t l, u32_t g)\r
+{\r
+    PPPControl *pc = &pppControl[pd];\r
+    int st = 1;\r
+    \r
+       (void)l;\r
+       (void)g;\r
+    if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) {\r
+        st = 0;\r
+        PPPDEBUG((LOG_WARNING, "sifup[%d]: bad parms\n", pd));\r
+    } else {\r
+               netif_set_default(NULL);\r
+    }\r
+\r
+    return st;\r
+}\r
+\r
+void\r
+pppMainWakeup(int pd)\r
+{\r
+       PPPDEBUG((LOG_DEBUG, "pppMainWakeup: unit %d\n", pd));\r
+       sio_read_abort(pppControl[pd].fd);\r
+}\r
+\r
+/* these callbacks are necessary because lcp_* functions\r
+   must be called in the same context as pppInput(),\r
+   namely the tcpip_thread(), essentially because\r
+   they manipulate timeouts which are thread-private\r
+*/\r
+\r
+static void\r
+pppStartCB(void *arg)\r
+{\r
+    int pd = (int)arg;\r
+\r
+       PPPDEBUG((LOG_DEBUG, "pppStartCB: unit %d\n", pd));\r
+    lcp_lowerup(pd);\r
+    lcp_open(pd);      /* Start protocol */\r
+}\r
+\r
+static void\r
+pppStopCB(void *arg)\r
+{\r
+    int pd = (int)arg;\r
+\r
+       PPPDEBUG((LOG_DEBUG, "pppStopCB: unit %d\n", pd));\r
+    lcp_close(pd, "User request");\r
+}\r
+\r
+static void\r
+pppHupCB(void *arg)\r
+{\r
+    int pd = (int)arg;\r
+\r
+       PPPDEBUG((LOG_DEBUG, "pppHupCB: unit %d\n", pd));\r
+    lcp_lowerdown(pd);\r
+    link_terminated(pd);\r
+}\r
+/**********************************/\r
+/*** LOCAL FUNCTION DEFINITIONS ***/\r
+/**********************************/\r
+/* The main PPP process function.  This implements the state machine according\r
+ * to section 4 of RFC 1661: The Point-To-Point Protocol. */\r
+static void pppMain(void *arg)\r
+{\r
+    int pd = (int)arg;\r
+    struct pbuf *p;\r
+    PPPControl* pc;\r
+\r
+    pc = &pppControl[pd];\r
+\r
+    p = pbuf_alloc(PBUF_RAW, PPP_MRU+PPP_HDRLEN, PBUF_RAM);\r
+    if(!p) {\r
+               LWIP_ASSERT("p != NULL", p);\r
+               pc->errCode = PPPERR_ALLOC;\r
+               goto out;\r
+    }\r
+\r
+    /*\r
+     * Start the connection and handle incoming events (packet or timeout).\r
+     */\r
+       PPPDEBUG((LOG_INFO, "pppMain: unit %d: Connecting\n", pd));\r
+    tcpip_callback(pppStartCB, arg);\r
+    while (lcp_phase[pd] != PHASE_DEAD) {\r
+        if (pc->kill_link) {\r
+               PPPDEBUG((LOG_DEBUG, "pppMainWakeup: unit %d kill_link -> pppStopCB\n", pd));\r
+               pc->errCode = PPPERR_USER;\r
+               /* This will leave us at PHASE_DEAD. */\r
+               tcpip_callback(pppStopCB, arg);\r
+               pc->kill_link = 0;\r
+        }\r
+        else if (pc->sig_hup) {\r
+               PPPDEBUG((LOG_DEBUG, "pppMainWakeup: unit %d sig_hup -> pppHupCB\n", pd));\r
+               pc->sig_hup = 0;\r
+               tcpip_callback(pppHupCB, arg);\r
+        } else {\r
+               int c = sio_read(pc->fd, p->payload, p->len);\r
+               if(c > 0) {\r
+                       pppInProc(pd, p->payload, c);\r
+               } else {\r
+                   PPPDEBUG((LOG_DEBUG, "pppMainWakeup: unit %d sio_read len=%d returned %d\n", pd, p->len, c));\r
+                   sys_msleep(1); /* give other tasks a chance to run */\r
+               }\r
+        }\r
+    }\r
+       PPPDEBUG((LOG_INFO, "pppMain: unit %d: PHASE_DEAD\n", pd));\r
+    pbuf_free(p);\r
+\r
+out:\r
+       PPPDEBUG((LOG_DEBUG, "pppMain: unit %d: linkStatusCB=%lx errCode=%d\n", pd, pc->linkStatusCB, pc->errCode));\r
+    if(pc->linkStatusCB)\r
+           pc->linkStatusCB(pc->linkStatusCtx, pc->errCode ? pc->errCode : PPPERR_PROTOCOL, NULL);\r
+\r
+    pc->openFlag = 0;\r
+}\r
+\r
+static struct pbuf *pppSingleBuf(struct pbuf *p)\r
+{\r
+       struct pbuf *q, *b;\r
+       u_char *pl;\r
+\r
+       if(p->tot_len == p->len)\r
+               return p;\r
+\r
+       q = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM);\r
+       if(!q) {\r
+               PPPDEBUG((LOG_ERR,\r
+                        "pppSingleBuf: unable to alloc new buf (%d)\n", p->tot_len));\r
+               return p; /* live dangerously */\r
+       }\r
+\r
+       for(b = p, pl = q->payload; b != NULL; b = b->next) {\r
+               memcpy(pl, b->payload, b->len);\r
+               pl += b->len;\r
+       }\r
+\r
+       pbuf_free(p);\r
+\r
+       return q;\r
+}\r
+\r
+struct pppInputHeader {\r
+       int unit;\r
+       u16_t proto;\r
+};\r
+\r
+/*\r
+ * Pass the processed input packet to the appropriate handler.\r
+ * This function and all handlers run in the context of the tcpip_thread\r
+ */\r
+static void pppInput(void *arg)\r
+{\r
+       struct pbuf *nb = (struct pbuf *)arg;\r
+    u16_t protocol;\r
+    int pd;\r
+\r
+       pd = ((struct pppInputHeader *)nb->payload)->unit;\r
+       protocol = ((struct pppInputHeader *)nb->payload)->proto;\r
+\r
+    pbuf_header(nb, -(int)sizeof(struct pppInputHeader));\r
+\r
+#if LINK_STATS\r
+    lwip_stats.link.recv++;\r
+#endif /* LINK_STATS */\r
+\r
+    /*\r
+     * Toss all non-LCP packets unless LCP is OPEN.\r
+     * Until we get past the authentication phase, toss all packets\r
+     * except LCP, LQR and authentication packets.\r
+     */\r
+    if((lcp_phase[pd] <= PHASE_AUTHENTICATE) && (protocol != PPP_LCP)) {\r
+           if(!((protocol == PPP_LQR) || (protocol == PPP_PAP) || (protocol == PPP_CHAP)) ||\r
+                       (lcp_phase[pd] != PHASE_AUTHENTICATE)) {\r
+               PPPDEBUG((LOG_INFO, "pppInput: discarding proto 0x%04X in phase %d\n", protocol, lcp_phase[pd]));\r
+               goto drop;\r
+           }\r
+    }\r
+\r
+    switch(protocol) {\r
+    case PPP_VJC_COMP:      /* VJ compressed TCP */\r
+#if VJ_SUPPORT > 0\r
+        PPPDEBUG((LOG_INFO, "pppInput[%d]: vj_comp in pbuf len=%d\n", pd, nb->len));\r
+        /*\r
+         * Clip off the VJ header and prepend the rebuilt TCP/IP header and\r
+         * pass the result to IP.\r
+         */\r
+        if (vj_uncompress_tcp(&nb, &pppControl[pd].vjComp) >= 0) {\r
+            pppControl[pd].netif.input(nb, &pppControl[pd].netif);\r
+                       return;\r
+        }\r
+       /* Something's wrong so drop it. */\r
+       PPPDEBUG((LOG_WARNING, "pppInput[%d]: Dropping VJ compressed\n", pd));\r
+#else\r
+        /* No handler for this protocol so drop the packet. */\r
+        PPPDEBUG((LOG_INFO, "pppInput[%d]: drop VJ Comp in %d:%s\n", pd, nb->len, nb->payload));\r
+#endif /* VJ_SUPPORT > 0 */\r
+       break;\r
+    case PPP_VJC_UNCOMP:    /* VJ uncompressed TCP */\r
+#if VJ_SUPPORT > 0\r
+        PPPDEBUG((LOG_INFO, "pppInput[%d]: vj_un in pbuf len=%d\n", pd, nb->len));\r
+        /*\r
+         * Process the TCP/IP header for VJ header compression and then pass\r
+         * the packet to IP.\r
+         */\r
+        if (vj_uncompress_uncomp(nb, &pppControl[pd].vjComp) >= 0) {\r
+            pppControl[pd].netif.input(nb, &pppControl[pd].netif);\r
+                       return;\r
+        }\r
+       /* Something's wrong so drop it. */\r
+       PPPDEBUG((LOG_WARNING, "pppInput[%d]: Dropping VJ uncompressed\n", pd));\r
+#else\r
+        /* No handler for this protocol so drop the packet. */\r
+        PPPDEBUG((LOG_INFO,\r
+                    "pppInput[%d]: drop VJ UnComp in %d:.*H\n", \r
+                    pd, nb->len, LWIP_MIN(nb->len * 2, 40), nb->payload));\r
+#endif /* VJ_SUPPORT > 0 */\r
+       break;\r
+    case PPP_IP:            /* Internet Protocol */\r
+        PPPDEBUG((LOG_INFO, "pppInput[%d]: ip in pbuf len=%d\n", pd, nb->len));\r
+        pppControl[pd].netif.input(nb, &pppControl[pd].netif);\r
+               return;\r
+    default:\r
+       {\r
+               struct protent *protp;\r
+               int i;\r
+\r
+               /*\r
+                * Upcall the proper protocol input routine.\r
+                */\r
+               for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i) {\r
+                       if (protp->protocol == protocol && protp->enabled_flag) {\r
+                               PPPDEBUG((LOG_INFO, "pppInput[%d]: %s len=%d\n", pd, protp->name, nb->len));\r
+                               nb = pppSingleBuf(nb);\r
+                               (*protp->input)(pd, nb->payload, nb->len);\r
+                               goto out;\r
+                       }\r
+               }\r
+\r
+               /* No handler for this protocol so reject the packet. */\r
+               PPPDEBUG((LOG_INFO, "pppInput[%d]: rejecting unsupported proto 0x%04X len=%d\n", pd, protocol, nb->len));\r
+               pbuf_header(nb, sizeof(protocol));\r
+#if BYTE_ORDER == LITTLE_ENDIAN\r
+               protocol = htons(protocol);\r
+               memcpy(nb->payload, &protocol, sizeof(protocol));\r
+#endif\r
+               lcp_sprotrej(pd, nb->payload, nb->len);\r
+       }\r
+       break;\r
+    }\r
+\r
+drop:\r
+#if LINK_STATS\r
+    lwip_stats.link.drop++;\r
+#endif\r
+\r
+out:\r
+    pbuf_free(nb);\r
+    return;\r
+}\r
+\r
+\r
+/*\r
+ * Drop the input packet.\r
+ */\r
+static void pppDrop(PPPControl *pc)\r
+{\r
+    if (pc->inHead != NULL) {\r
+#if 0      \r
+        PPPDEBUG((LOG_INFO, "pppDrop: %d:%.*H\n", pc->inHead->len, min(60, pc->inHead->len * 2), pc->inHead->payload));\r
+#endif \r
+        PPPDEBUG((LOG_INFO, "pppDrop: pbuf len=%d\n", pc->inHead->len));\r
+       if (pc->inTail && (pc->inTail != pc->inHead))\r
+           pbuf_free(pc->inTail);\r
+        pbuf_free(pc->inHead);\r
+        pc->inHead = NULL;\r
+        pc->inTail = NULL;\r
+    }\r
+#if VJ_SUPPORT > 0\r
+    vj_uncompress_err(&pc->vjComp);\r
+#endif\r
+\r
+#if LINK_STATS\r
+    lwip_stats.link.drop++;\r
+#endif /* LINK_STATS */\r
+}\r
+\r
+\r
+/*\r
+ * Process a received octet string.\r
+ */\r
+static void pppInProc(int pd, u_char *s, int l)\r
+{\r
+    PPPControl *pc = &pppControl[pd];\r
+    struct pbuf *nextNBuf;\r
+    u_char curChar;\r
+\r
+    PPPDEBUG((LOG_DEBUG, "pppInProc[%d]: got %d bytes\n", pd, l));\r
+    while (l-- > 0) {\r
+        curChar = *s++;\r
+        \r
+        /* Handle special characters. */\r
+        if (ESCAPE_P(pc->inACCM, curChar)) {\r
+            /* Check for escape sequences. */\r
+            /* XXX Note that this does not handle an escaped 0x5d character which\r
+             * would appear as an escape character.  Since this is an ASCII ']'\r
+             * and there is no reason that I know of to escape it, I won't complicate\r
+             * the code to handle this case. GLL */\r
+            if (curChar == PPP_ESCAPE)\r
+                pc->inEscaped = 1;\r
+            /* Check for the flag character. */\r
+            else if (curChar == PPP_FLAG) {\r
+                /* If this is just an extra flag character, ignore it. */\r
+                if (pc->inState <= PDADDRESS)\r
+                    ;\r
+                /* If we haven't received the packet header, drop what has come in. */\r
+                else if (pc->inState < PDDATA) {\r
+                    PPPDEBUG((LOG_WARNING,\r
+                                "pppInProc[%d]: Dropping incomplete packet %d\n", \r
+                                pd, pc->inState));\r
+#if LINK_STATS\r
+                                       lwip_stats.link.lenerr++;\r
+#endif\r
+                    pppDrop(pc);\r
+                }\r
+                /* If the fcs is invalid, drop the packet. */\r
+                else if (pc->inFCS != PPP_GOODFCS) {\r
+                    PPPDEBUG((LOG_INFO,\r
+                                "pppInProc[%d]: Dropping bad fcs 0x%04X proto=0x%04X\n", \r
+                                pd, pc->inFCS, pc->inProtocol));\r
+#if LINK_STATS\r
+                                       lwip_stats.link.chkerr++;\r
+#endif\r
+                    pppDrop(pc);\r
+                }\r
+                /* Otherwise it's a good packet so pass it on. */\r
+                else {\r
+                    \r
+                    /* Trim off the checksum. */\r
+                   if(pc->inTail->len >= 2) {\r
+                       pc->inTail->len -= 2;\r
+\r
+                       pc->inTail->tot_len = pc->inTail->len;\r
+                       if (pc->inTail != pc->inHead) {\r
+                           pbuf_cat(pc->inHead, pc->inTail);\r
+                       }\r
+                   } else {\r
+                       pc->inTail->tot_len = pc->inTail->len;\r
+                       if (pc->inTail != pc->inHead) {\r
+                           pbuf_cat(pc->inHead, pc->inTail);\r
+                       }\r
+\r
+                       pbuf_realloc(pc->inHead, pc->inHead->tot_len - 2);\r
+                   }\r
+\r
+                    /* Dispatch the packet thereby consuming it. */\r
+                   if(tcpip_callback(pppInput, pc->inHead) != ERR_OK) {\r
+                       PPPDEBUG((LOG_ERR,\r
+                                   "pppInProc[%d]: tcpip_callback() failed, dropping packet\n", pd));\r
+                       pbuf_free(pc->inHead);\r
+#if LINK_STATS\r
+                       lwip_stats.link.drop++;\r
+#endif\r
+                   }\r
+                    pc->inHead = NULL;\r
+                    pc->inTail = NULL;\r
+                }\r
+                    \r
+                /* Prepare for a new packet. */\r
+                pc->inFCS = PPP_INITFCS;\r
+                pc->inState = PDADDRESS;\r
+                pc->inEscaped = 0;\r
+            }\r
+            /* Other characters are usually control characters that may have\r
+             * been inserted by the physical layer so here we just drop them. */\r
+            else {\r
+                PPPDEBUG((LOG_WARNING,\r
+                            "pppInProc[%d]: Dropping ACCM char <%d>\n", pd, curChar));\r
+            }\r
+        }\r
+        /* Process other characters. */\r
+        else {\r
+            /* Unencode escaped characters. */\r
+            if (pc->inEscaped) {\r
+                pc->inEscaped = 0;\r
+                curChar ^= PPP_TRANS;\r
+            }\r
+            \r
+            /* Process character relative to current state. */\r
+            switch(pc->inState) {\r
+            case PDIDLE:                    /* Idle state - waiting. */\r
+                /* Drop the character if it's not 0xff\r
+                 * we would have processed a flag character above. */\r
+                if (curChar != PPP_ALLSTATIONS) {\r
+                       break;\r
+                               }\r
+\r
+                               /* Fall through */\r
+            case PDSTART:                   /* Process start flag. */\r
+                /* Prepare for a new packet. */\r
+                pc->inFCS = PPP_INITFCS;\r
+\r
+                               /* Fall through */\r
+            case PDADDRESS:                 /* Process address field. */\r
+                if (curChar == PPP_ALLSTATIONS) {\r
+                    pc->inState = PDCONTROL;\r
+                    break;\r
+                }\r
+                /* Else assume compressed address and control fields so\r
+                 * fall through to get the protocol... */\r
+            case PDCONTROL:                 /* Process control field. */\r
+                /* If we don't get a valid control code, restart. */\r
+                if (curChar == PPP_UI) {\r
+                    pc->inState = PDPROTOCOL1;\r
+                       break;\r
+                }\r
+#if 0\r
+                else {\r
+                    PPPDEBUG((LOG_WARNING,\r
+                                "pppInProc[%d]: Invalid control <%d>\n", pd, curChar));\r
+                    pc->inState = PDSTART;\r
+                }\r
+#endif\r
+            case PDPROTOCOL1:               /* Process protocol field 1. */\r
+                /* If the lower bit is set, this is the end of the protocol\r
+                 * field. */\r
+                if (curChar & 1) {\r
+                    pc->inProtocol = curChar;\r
+                    pc->inState = PDDATA;\r
+                }\r
+                else {\r
+                    pc->inProtocol = (u_int)curChar << 8;\r
+                    pc->inState = PDPROTOCOL2;\r
+                }\r
+                break;\r
+            case PDPROTOCOL2:               /* Process protocol field 2. */\r
+                pc->inProtocol |= curChar;\r
+                pc->inState = PDDATA;\r
+                break;\r
+            case PDDATA:                    /* Process data byte. */\r
+                /* Make space to receive processed data. */\r
+                if (pc->inTail == NULL || pc->inTail->len == PBUF_POOL_BUFSIZE) {\r
+                   if(pc->inTail) {\r
+                       pc->inTail->tot_len = pc->inTail->len;\r
+                       if (pc->inTail != pc->inHead) {\r
+                           pbuf_cat(pc->inHead, pc->inTail);\r
+                       }\r
+                   }\r
+                    /* If we haven't started a packet, we need a packet header. */\r
+                    nextNBuf = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL);\r
+                    if (nextNBuf == NULL) {\r
+                        /* No free buffers.  Drop the input packet and let the\r
+                         * higher layers deal with it.  Continue processing\r
+                         * the received pbuf chain in case a new packet starts. */\r
+                        PPPDEBUG((LOG_ERR, "pppInProc[%d]: NO FREE MBUFS!\n", pd));\r
+#if LINK_STATS\r
+                                               lwip_stats.link.memerr++;\r
+#endif /* LINK_STATS */\r
+                        pppDrop(pc);\r
+                        pc->inState = PDSTART;  /* Wait for flag sequence. */\r
+                       break;\r
+                    }\r
+                   if (pc->inHead == NULL) {\r
+                       struct pppInputHeader *pih = nextNBuf->payload;\r
+\r
+                       pih->unit = pd;\r
+                       pih->proto = pc->inProtocol;\r
+\r
+                       nextNBuf->len += sizeof(*pih);\r
+\r
+                       pc->inHead = nextNBuf;\r
+                   }\r
+                   pc->inTail = nextNBuf;\r
+                }\r
+                /* Load character into buffer. */\r
+                ((u_char*)pc->inTail->payload)[pc->inTail->len++] = curChar;\r
+                break;\r
+            }\r
+\r
+            /* update the frame check sequence number. */\r
+            pc->inFCS = PPP_FCS(pc->inFCS, curChar);\r
+        }\r
+    }\r
+       avRandomize();\r
+}\r
+\r
+#endif /* PPP_SUPPORT */\r
index dbe12171e83beca26818af78a2bd526975a0888a..bd45a3c1d4136877232f3622e7aadb04640e64e4 100644 (file)
-/*****************************************************************************
-* ppp.h - Network Point to Point Protocol header file.
-*
-* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
-* portions Copyright (c) 1997 Global Election Systems Inc.
-*
-* The authors hereby grant permission to use, copy, modify, distribute,
-* and license this software and its documentation for any purpose, provided
-* that existing copyright notices are retained in all copies and that this
-* notice and the following disclaimer are included verbatim in any 
-* distributions. No written agreement, license, or royalty fee is required
-* for any of the authorized uses.
-*
-* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *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 CONTRIBUTORS 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.
-*
-******************************************************************************
-* REVISION HISTORY
-*
-* 03-01-01 Marc Boucher <marc@mbsi.ca>
-*   Ported to lwIP.
-* 97-11-05 Guy Lancaster <glanca@gesn.com>, Global Election Systems Inc.
-*      Original derived from BSD codes.
-*****************************************************************************/
-
-#ifndef PPP_H
-#define PPP_H
-
-#include "lwip/opt.h"
-
-#if PPP_SUPPORT > 0
-#include "lwip/sio.h"
-#include "lwip/api.h"
-#include "lwip/sockets.h"
-#include "lwip/stats.h"
-#include "lwip/mem.h"
-#include "lwip/tcpip.h"
-#include "lwip/netif.h"
-
-/*
- * pppd.h - PPP daemon global declarations.
- *
- * Copyright (c) 1989 Carnegie Mellon University.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by Carnegie Mellon University.  The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- */
-/*
- * ppp_defs.h - PPP definitions.
- *
- * Copyright (c) 1994 The Australian National University.
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation is hereby granted, provided that the above copyright
- * notice appears in all copies.  This software is provided without any
- * warranty, express or implied. The Australian National University
- * makes no representations about the suitability of this software for
- * any purpose.
- *
- * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY
- * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
- * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY
- * OF SUCH DAMAGE.
- *
- * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO
- * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
- * OR MODIFICATIONS.
- */
-
-#define TIMEOUT(f, a, t)    sys_untimeout((f), (a)), sys_timeout((t)*1000, (f), (a))
-#define UNTIMEOUT(f, a)     sys_untimeout((f), (a))
-
-
-# ifndef __u_char_defined
-
-/* Type definitions for BSD code. */
-typedef unsigned long u_long;
-typedef unsigned int u_int;
-typedef unsigned short u_short;
-typedef unsigned char u_char;
-
-#endif
-
-/*
- * Constants and structures defined by the internet system,
- * Per RFC 790, September 1981, and numerous additions.
- */
-
-/*
- * The basic PPP frame.
- */
-#define PPP_HDRLEN  4       /* octets for standard ppp header */
-#define PPP_FCSLEN  2       /* octets for FCS */
-
-
-/*
- * Significant octet values.
- */
-#define PPP_ALLSTATIONS 0xff    /* All-Stations broadcast address */
-#define PPP_UI          0x03    /* Unnumbered Information */
-#define PPP_FLAG        0x7e    /* Flag Sequence */
-#define PPP_ESCAPE      0x7d    /* Asynchronous Control Escape */
-#define PPP_TRANS       0x20    /* Asynchronous transparency modifier */
-
-/*
- * Protocol field values.
- */
-#define PPP_IP          0x21    /* Internet Protocol */
-#define PPP_AT          0x29    /* AppleTalk Protocol */
-#define PPP_VJC_COMP    0x2d    /* VJ compressed TCP */
-#define PPP_VJC_UNCOMP  0x2f    /* VJ uncompressed TCP */
-#define PPP_COMP        0xfd    /* compressed packet */
-#define PPP_IPCP        0x8021  /* IP Control Protocol */
-#define PPP_ATCP        0x8029  /* AppleTalk Control Protocol */
-#define PPP_CCP         0x80fd  /* Compression Control Protocol */
-#define PPP_LCP         0xc021  /* Link Control Protocol */
-#define PPP_PAP         0xc023  /* Password Authentication Protocol */
-#define PPP_LQR         0xc025  /* Link Quality Report protocol */
-#define PPP_CHAP        0xc223  /* Cryptographic Handshake Auth. Protocol */
-#define PPP_CBCP        0xc029  /* Callback Control Protocol */
-
-/*
- * Values for FCS calculations.
- */
-#define PPP_INITFCS 0xffff  /* Initial FCS value */
-#define PPP_GOODFCS 0xf0b8  /* Good final FCS value */
-#define PPP_FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
-
-/*
- * Extended asyncmap - allows any character to be escaped.
- */
-typedef u_char  ext_accm[32];
-
-/*
- * What to do with network protocol (NP) packets.
- */
-enum NPmode {
-    NPMODE_PASS,        /* pass the packet through */
-    NPMODE_DROP,        /* silently drop the packet */
-    NPMODE_ERROR,       /* return an error */
-    NPMODE_QUEUE        /* save it up for later. */
-};
-
-/*
- * Inline versions of get/put char/short/long.
- * Pointer is advanced; we assume that both arguments
- * are lvalues and will already be in registers.
- * cp MUST be u_char *.
- */
-#define GETCHAR(c, cp) { \
-    (c) = *(cp)++; \
-}
-#define PUTCHAR(c, cp) { \
-    *(cp)++ = (u_char) (c); \
-}
-
-
-#define GETSHORT(s, cp) { \
-    (s) = *(cp)++ << 8; \
-    (s) |= *(cp)++; \
-}
-#define PUTSHORT(s, cp) { \
-    *(cp)++ = (u_char) ((s) >> 8); \
-    *(cp)++ = (u_char) (s); \
-}
-
-#define GETLONG(l, cp) { \
-    (l) = *(cp)++ << 8; \
-    (l) |= *(cp)++; (l) <<= 8; \
-    (l) |= *(cp)++; (l) <<= 8; \
-    (l) |= *(cp)++; \
-}
-#define PUTLONG(l, cp) { \
-    *(cp)++ = (u_char) ((l) >> 24); \
-    *(cp)++ = (u_char) ((l) >> 16); \
-    *(cp)++ = (u_char) ((l) >> 8); \
-    *(cp)++ = (u_char) (l); \
-}
-
-
-#define INCPTR(n, cp)   ((cp) += (n))
-#define DECPTR(n, cp)   ((cp) -= (n))
-
-#define BCMP(s0, s1, l)     memcmp((u_char *)(s0), (u_char *)(s1), (l))
-#define BCOPY(s, d, l)      memcpy((d), (s), (l))
-#define BZERO(s, n)         memset(s, 0, n)
-#if PPP_DEBUG
-#define PRINTMSG(m, l)  { m[l] = '\0'; ppp_trace(LOG_INFO, "Remote message: %s\n", m); }
-#else
-#define PRINTMSG(m, l)
-#endif
-
-/*
- * MAKEHEADER - Add PPP Header fields to a packet.
- */
-#define MAKEHEADER(p, t) { \
-    PUTCHAR(PPP_ALLSTATIONS, p); \
-    PUTCHAR(PPP_UI, p); \
-    PUTSHORT(t, p); }
-
-/*************************
-*** PUBLIC DEFINITIONS ***
-*************************/
-
-/* Error codes. */
-#define PPPERR_NONE 0                          /* No error. */
-#define PPPERR_PARAM -1                                /* Invalid parameter. */
-#define PPPERR_OPEN -2                         /* Unable to open PPP session. */
-#define PPPERR_DEVICE -3                       /* Invalid I/O device for PPP. */
-#define PPPERR_ALLOC -4                                /* Unable to allocate resources. */
-#define PPPERR_USER -5                         /* User interrupt. */
-#define PPPERR_CONNECT -6                      /* Connection lost. */
-#define PPPERR_AUTHFAIL -7                     /* Failed authentication challenge. */
-#define PPPERR_PROTOCOL -8                     /* Failed to meet protocol. */
-
-/*
- * PPP IOCTL commands.
- */
-/*
- * Get the up status - 0 for down, non-zero for up.  The argument must
- * point to an int.
- */
-#define PPPCTLG_UPSTATUS 100   /* Get the up status - 0 down else up */
-#define PPPCTLS_ERRCODE 101            /* Set the error code */
-#define PPPCTLG_ERRCODE 102            /* Get the error code */
-#define        PPPCTLG_FD              103             /* Get the fd associated with the ppp */
-
-/************************
-*** PUBLIC DATA TYPES ***
-************************/
-
-/*
- * The following struct gives the addresses of procedures to call
- * for a particular protocol.
- */
-struct protent {
-    u_short protocol;       /* PPP protocol number */
-    /* Initialization procedure */
-    void (*init) (int unit);
-    /* Process a received packet */
-    void (*input) (int unit, u_char *pkt, int len);
-    /* Process a received protocol-reject */
-    void (*protrej) (int unit);
-    /* Lower layer has come up */
-    void (*lowerup) (int unit);
-    /* Lower layer has gone down */
-    void (*lowerdown) (int unit);
-    /* Open the protocol */
-    void (*open) (int unit);
-    /* Close the protocol */
-    void (*close) (int unit, char *reason);
-#if 0
-    /* Print a packet in readable form */
-    int  (*printpkt) (u_char *pkt, int len,
-              void (*printer) (void *, char *, ...),
-              void *arg);
-    /* Process a received data packet */
-    void (*datainput) (int unit, u_char *pkt, int len);
-#endif
-    int  enabled_flag;      /* 0 iff protocol is disabled */
-    char *name;         /* Text name of protocol */
-#if 0
-    /* Check requested options, assign defaults */
-    void (*check_options) (u_long);
-    /* Configure interface for demand-dial */
-    int  (*demand_conf) (int unit);
-    /* Say whether to bring up link for this pkt */
-    int  (*active_pkt) (u_char *pkt, int len);
-#endif
-};
-
-/*
- * The following structure records the time in seconds since
- * the last NP packet was sent or received.
- */
-struct ppp_idle {
-    u_short xmit_idle;      /* seconds since last NP packet sent */
-    u_short recv_idle;      /* seconds since last NP packet received */
-};
-
-struct ppp_settings {
-
-       u_int  disable_defaultip : 1;   /* Don't use hostname for default IP addrs */
-       u_int  auth_required : 1;      /* Peer is required to authenticate */
-       u_int  explicit_remote : 1;    /* remote_name specified with remotename opt */
-       u_int  refuse_pap : 1;         /* Don't wanna auth. ourselves with PAP */
-       u_int  refuse_chap : 1;        /* Don't wanna auth. ourselves with CHAP */
-       u_int  usehostname : 1;        /* Use hostname for our_name */
-       u_int  usepeerdns : 1;         /* Ask peer for DNS adds */
-
-       u_short idle_time_limit; /* Shut down link if idle for this long */
-       int  maxconnect;         /* Maximum connect time (seconds) */
-
-       char user[MAXNAMELEN + 1];/* Username for PAP */
-       char passwd[MAXSECRETLEN + 1];           /* Password for PAP, secret for CHAP */
-       char our_name[MAXNAMELEN + 1];         /* Our name for authentication purposes */
-       char remote_name[MAXNAMELEN + 1];      /* Peer's name for authentication */
-};
-
-struct ppp_addrs {
-    struct ip_addr our_ipaddr, his_ipaddr, netmask, dns1, dns2;
-};
-
-/*****************************
-*** PUBLIC DATA STRUCTURES ***
-*****************************/
-/* Buffers for outgoing packets. */
-extern u_char outpacket_buf[NUM_PPP][PPP_MRU+PPP_HDRLEN];
-
-extern struct ppp_settings ppp_settings;
-
-extern struct protent *ppp_protocols[];/* Table of pointers to supported protocols */
-
-
-/***********************
-*** PUBLIC FUNCTIONS ***
-***********************/
-
-/* Initialize the PPP subsystem. */
-void pppInit(void);
-
-/* Warning: Using PPPAUTHTYPE_ANY might have security consequences.
- * RFC 1994 says:
- *
- * In practice, within or associated with each PPP server, there is a
- * database which associates "user" names with authentication
- * information ("secrets").  It is not anticipated that a particular
- * named user would be authenticated by multiple methods.  This would
- * make the user vulnerable to attacks which negotiate the least secure
- * method from among a set (such as PAP rather than CHAP).  If the same
- * secret was used, PAP would reveal the secret to be used later with
- * CHAP.
- *
- * Instead, for each user name there should be an indication of exactly
- * one method used to authenticate that user name.  If a user needs to
- * make use of different authentication methods under different
- * circumstances, then distinct user names SHOULD be employed, each of
- * which identifies exactly one authentication method.
- *
- */
-enum pppAuthType {
-    PPPAUTHTYPE_NONE,
-    PPPAUTHTYPE_ANY,
-    PPPAUTHTYPE_PAP,
-    PPPAUTHTYPE_CHAP
-};
-
-void pppSetAuth(enum pppAuthType authType, const char *user, const char *passwd);
-
-/*
- * Open a new PPP connection using the given I/O device.
- * This initializes the PPP control block but does not
- * attempt to negotiate the LCP session.
- * Return a new PPP connection descriptor on success or
- * an error code (negative) on failure. 
- */
-int pppOpen(sio_fd_t fd, void (*linkStatusCB)(void *ctx, int errCode, void *arg), void *linkStatusCtx);
-
-/*
- * Close a PPP connection and release the descriptor. 
- * Any outstanding packets in the queues are dropped.
- * Return 0 on success, an error code on failure. 
- */
-int pppClose(int pd);
-
-/*
- * Indicate to the PPP process that the line has disconnected.
- */
-void pppSigHUP(int pd);
-
-/*
- * Get and set parameters for the given connection.
- * Return 0 on success, an error code on failure. 
- */
-int  pppIOCtl(int pd, int cmd, void *arg);
-
-/*
- * Return the Maximum Transmission Unit for the given PPP connection.
- */
-u_int pppMTU(int pd);
-
-/*
- * Write n characters to a ppp link.
- *     RETURN: >= 0 Number of characters written
- *                      -1 Failed to write to device
- */
-int pppWrite(int pd, const u_char *s, int n);
-
-void pppMainWakeup(int pd);
-
-/* Configure i/f transmit parameters */
-void ppp_send_config (int, int, u32_t, int, int);
-/* Set extended transmit ACCM */
-void ppp_set_xaccm (int, ext_accm *);
-/* Configure i/f receive parameters */
-void ppp_recv_config (int, int, u32_t, int, int);
-/* Find out how long link has been idle */
-int  get_idle_time (int, struct ppp_idle *);
-
-/* Configure VJ TCP header compression */
-int  sifvjcomp (int, int, int, int);
-/* Configure i/f down (for IP) */
-int  sifup (int);              
-/* Set mode for handling packets for proto */
-int  sifnpmode (int u, int proto, enum NPmode mode);
-/* Configure i/f down (for IP) */
-int  sifdown (int);    
-/* Configure IP addresses for i/f */
-int  sifaddr (int, u32_t, u32_t, u32_t, u32_t, u32_t);
-/* Reset i/f IP addresses */
-int  cifaddr (int, u32_t, u32_t);
-/* Create default route through i/f */
-int  sifdefaultroute (int, u32_t, u32_t);
-/* Delete default route through i/f */
-int  cifdefaultroute (int, u32_t, u32_t);
-
-/* Get appropriate netmask for address */
-u32_t GetMask (u32_t); 
-
-#endif /* PPP_SUPPORT */
-
-#endif /* PPP_H */
+/*****************************************************************************\r
+* ppp.h - Network Point to Point Protocol header file.\r
+*\r
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.\r
+* portions Copyright (c) 1997 Global Election Systems Inc.\r
+*\r
+* The authors hereby grant permission to use, copy, modify, distribute,\r
+* and license this software and its documentation for any purpose, provided\r
+* that existing copyright notices are retained in all copies and that this\r
+* notice and the following disclaimer are included verbatim in any \r
+* distributions. No written agreement, license, or royalty fee is required\r
+* for any of the authorized uses.\r
+*\r
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR\r
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+*\r
+******************************************************************************\r
+* REVISION HISTORY\r
+*\r
+* 03-01-01 Marc Boucher <marc@mbsi.ca>\r
+*   Ported to lwIP.\r
+* 97-11-05 Guy Lancaster <glanca@gesn.com>, Global Election Systems Inc.\r
+*      Original derived from BSD codes.\r
+*****************************************************************************/\r
+\r
+#ifndef PPP_H\r
+#define PPP_H\r
+\r
+#include "lwip/opt.h"\r
+\r
+#if PPP_SUPPORT > 0\r
+#include "lwip/sio.h"\r
+#include "lwip/api.h"\r
+#include "lwip/sockets.h"\r
+#include "lwip/stats.h"\r
+#include "lwip/mem.h"\r
+#include "lwip/tcpip.h"\r
+#include "lwip/netif.h"\r
+\r
+/*\r
+ * pppd.h - PPP daemon global declarations.\r
+ *\r
+ * Copyright (c) 1989 Carnegie Mellon University.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms are permitted\r
+ * provided that the above copyright notice and this paragraph are\r
+ * duplicated in all such forms and that any documentation,\r
+ * advertising materials, and other materials related to such\r
+ * distribution and use acknowledge that the software was developed\r
+ * by Carnegie Mellon University.  The name of the\r
+ * University may not be used to endorse or promote products derived\r
+ * from this software without specific prior written permission.\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR\r
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r
+ *\r
+ */\r
+/*\r
+ * ppp_defs.h - PPP definitions.\r
+ *\r
+ * Copyright (c) 1994 The Australian National University.\r
+ * All rights reserved.\r
+ *\r
+ * Permission to use, copy, modify, and distribute this software and its\r
+ * documentation is hereby granted, provided that the above copyright\r
+ * notice appears in all copies.  This software is provided without any\r
+ * warranty, express or implied. The Australian National University\r
+ * makes no representations about the suitability of this software for\r
+ * any purpose.\r
+ *\r
+ * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY\r
+ * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES\r
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF\r
+ * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY\r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,\r
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY\r
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS\r
+ * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO\r
+ * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,\r
+ * OR MODIFICATIONS.\r
+ */\r
+\r
+#define TIMEOUT(f, a, t)    sys_untimeout((f), (a)), sys_timeout((t)*1000, (f), (a))\r
+#define UNTIMEOUT(f, a)     sys_untimeout((f), (a))\r
+\r
+\r
+# ifndef __u_char_defined\r
+\r
+/* Type definitions for BSD code. */\r
+typedef unsigned long u_long;\r
+typedef unsigned int u_int;\r
+typedef unsigned short u_short;\r
+typedef unsigned char u_char;\r
+\r
+#endif\r
+\r
+/*\r
+ * Constants and structures defined by the internet system,\r
+ * Per RFC 790, September 1981, and numerous additions.\r
+ */\r
+\r
+/*\r
+ * The basic PPP frame.\r
+ */\r
+#define PPP_HDRLEN  4       /* octets for standard ppp header */\r
+#define PPP_FCSLEN  2       /* octets for FCS */\r
+\r
+\r
+/*\r
+ * Significant octet values.\r
+ */\r
+#define PPP_ALLSTATIONS 0xff    /* All-Stations broadcast address */\r
+#define PPP_UI          0x03    /* Unnumbered Information */\r
+#define PPP_FLAG        0x7e    /* Flag Sequence */\r
+#define PPP_ESCAPE      0x7d    /* Asynchronous Control Escape */\r
+#define PPP_TRANS       0x20    /* Asynchronous transparency modifier */\r
+\r
+/*\r
+ * Protocol field values.\r
+ */\r
+#define PPP_IP          0x21    /* Internet Protocol */\r
+#define PPP_AT          0x29    /* AppleTalk Protocol */\r
+#define PPP_VJC_COMP    0x2d    /* VJ compressed TCP */\r
+#define PPP_VJC_UNCOMP  0x2f    /* VJ uncompressed TCP */\r
+#define PPP_COMP        0xfd    /* compressed packet */\r
+#define PPP_IPCP        0x8021  /* IP Control Protocol */\r
+#define PPP_ATCP        0x8029  /* AppleTalk Control Protocol */\r
+#define PPP_CCP         0x80fd  /* Compression Control Protocol */\r
+#define PPP_LCP         0xc021  /* Link Control Protocol */\r
+#define PPP_PAP         0xc023  /* Password Authentication Protocol */\r
+#define PPP_LQR         0xc025  /* Link Quality Report protocol */\r
+#define PPP_CHAP        0xc223  /* Cryptographic Handshake Auth. Protocol */\r
+#define PPP_CBCP        0xc029  /* Callback Control Protocol */\r
+\r
+/*\r
+ * Values for FCS calculations.\r
+ */\r
+#define PPP_INITFCS 0xffff  /* Initial FCS value */\r
+#define PPP_GOODFCS 0xf0b8  /* Good final FCS value */\r
+#define PPP_FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])\r
+\r
+/*\r
+ * Extended asyncmap - allows any character to be escaped.\r
+ */\r
+typedef u_char  ext_accm[32];\r
+\r
+/*\r
+ * What to do with network protocol (NP) packets.\r
+ */\r
+enum NPmode {\r
+    NPMODE_PASS,        /* pass the packet through */\r
+    NPMODE_DROP,        /* silently drop the packet */\r
+    NPMODE_ERROR,       /* return an error */\r
+    NPMODE_QUEUE        /* save it up for later. */\r
+};\r
+\r
+/*\r
+ * Inline versions of get/put char/short/long.\r
+ * Pointer is advanced; we assume that both arguments\r
+ * are lvalues and will already be in registers.\r
+ * cp MUST be u_char *.\r
+ */\r
+#define GETCHAR(c, cp) { \\r
+    (c) = *(cp)++; \\r
+}\r
+#define PUTCHAR(c, cp) { \\r
+    *(cp)++ = (u_char) (c); \\r
+}\r
+\r
+\r
+#define GETSHORT(s, cp) { \\r
+    (s) = *(cp)++ << 8; \\r
+    (s) |= *(cp)++; \\r
+}\r
+#define PUTSHORT(s, cp) { \\r
+    *(cp)++ = (u_char) ((s) >> 8); \\r
+    *(cp)++ = (u_char) (s); \\r
+}\r
+\r
+#define GETLONG(l, cp) { \\r
+    (l) = *(cp)++ << 8; \\r
+    (l) |= *(cp)++; (l) <<= 8; \\r
+    (l) |= *(cp)++; (l) <<= 8; \\r
+    (l) |= *(cp)++; \\r
+}\r
+#define PUTLONG(l, cp) { \\r
+    *(cp)++ = (u_char) ((l) >> 24); \\r
+    *(cp)++ = (u_char) ((l) >> 16); \\r
+    *(cp)++ = (u_char) ((l) >> 8); \\r
+    *(cp)++ = (u_char) (l); \\r
+}\r
+\r
+\r
+#define INCPTR(n, cp)   ((cp) += (n))\r
+#define DECPTR(n, cp)   ((cp) -= (n))\r
+\r
+#define BCMP(s0, s1, l)     memcmp((u_char *)(s0), (u_char *)(s1), (l))\r
+#define BCOPY(s, d, l)      memcpy((d), (s), (l))\r
+#define BZERO(s, n)         memset(s, 0, n)\r
+#if PPP_DEBUG\r
+#define PRINTMSG(m, l)  { m[l] = '\0'; ppp_trace(LOG_INFO, "Remote message: %s\n", m); }\r
+#else\r
+#define PRINTMSG(m, l)\r
+#endif\r
+\r
+/*\r
+ * MAKEHEADER - Add PPP Header fields to a packet.\r
+ */\r
+#define MAKEHEADER(p, t) { \\r
+    PUTCHAR(PPP_ALLSTATIONS, p); \\r
+    PUTCHAR(PPP_UI, p); \\r
+    PUTSHORT(t, p); }\r
+\r
+/*************************\r
+*** PUBLIC DEFINITIONS ***\r
+*************************/\r
+\r
+/* Error codes. */\r
+#define PPPERR_NONE 0                          /* No error. */\r
+#define PPPERR_PARAM -1                                /* Invalid parameter. */\r
+#define PPPERR_OPEN -2                         /* Unable to open PPP session. */\r
+#define PPPERR_DEVICE -3                       /* Invalid I/O device for PPP. */\r
+#define PPPERR_ALLOC -4                                /* Unable to allocate resources. */\r
+#define PPPERR_USER -5                         /* User interrupt. */\r
+#define PPPERR_CONNECT -6                      /* Connection lost. */\r
+#define PPPERR_AUTHFAIL -7                     /* Failed authentication challenge. */\r
+#define PPPERR_PROTOCOL -8                     /* Failed to meet protocol. */\r
+\r
+/*\r
+ * PPP IOCTL commands.\r
+ */\r
+/*\r
+ * Get the up status - 0 for down, non-zero for up.  The argument must\r
+ * point to an int.\r
+ */\r
+#define PPPCTLG_UPSTATUS 100   /* Get the up status - 0 down else up */\r
+#define PPPCTLS_ERRCODE 101            /* Set the error code */\r
+#define PPPCTLG_ERRCODE 102            /* Get the error code */\r
+#define        PPPCTLG_FD              103             /* Get the fd associated with the ppp */\r
+\r
+/************************\r
+*** PUBLIC DATA TYPES ***\r
+************************/\r
+\r
+/*\r
+ * The following struct gives the addresses of procedures to call\r
+ * for a particular protocol.\r
+ */\r
+struct protent {\r
+    u_short protocol;       /* PPP protocol number */\r
+    /* Initialization procedure */\r
+    void (*init) (int unit);\r
+    /* Process a received packet */\r
+    void (*input) (int unit, u_char *pkt, int len);\r
+    /* Process a received protocol-reject */\r
+    void (*protrej) (int unit);\r
+    /* Lower layer has come up */\r
+    void (*lowerup) (int unit);\r
+    /* Lower layer has gone down */\r
+    void (*lowerdown) (int unit);\r
+    /* Open the protocol */\r
+    void (*open) (int unit);\r
+    /* Close the protocol */\r
+    void (*close) (int unit, char *reason);\r
+#if 0\r
+    /* Print a packet in readable form */\r
+    int  (*printpkt) (u_char *pkt, int len,\r
+              void (*printer) (void *, char *, ...),\r
+              void *arg);\r
+    /* Process a received data packet */\r
+    void (*datainput) (int unit, u_char *pkt, int len);\r
+#endif\r
+    int  enabled_flag;      /* 0 iff protocol is disabled */\r
+    char *name;         /* Text name of protocol */\r
+#if 0\r
+    /* Check requested options, assign defaults */\r
+    void (*check_options) (u_long);\r
+    /* Configure interface for demand-dial */\r
+    int  (*demand_conf) (int unit);\r
+    /* Say whether to bring up link for this pkt */\r
+    int  (*active_pkt) (u_char *pkt, int len);\r
+#endif\r
+};\r
+\r
+/*\r
+ * The following structure records the time in seconds since\r
+ * the last NP packet was sent or received.\r
+ */\r
+struct ppp_idle {\r
+    u_short xmit_idle;      /* seconds since last NP packet sent */\r
+    u_short recv_idle;      /* seconds since last NP packet received */\r
+};\r
+\r
+struct ppp_settings {\r
+\r
+       u_int  disable_defaultip : 1;   /* Don't use hostname for default IP addrs */\r
+       u_int  auth_required : 1;      /* Peer is required to authenticate */\r
+       u_int  explicit_remote : 1;    /* remote_name specified with remotename opt */\r
+       u_int  refuse_pap : 1;         /* Don't wanna auth. ourselves with PAP */\r
+       u_int  refuse_chap : 1;        /* Don't wanna auth. ourselves with CHAP */\r
+       u_int  usehostname : 1;        /* Use hostname for our_name */\r
+       u_int  usepeerdns : 1;         /* Ask peer for DNS adds */\r
+\r
+       u_short idle_time_limit; /* Shut down link if idle for this long */\r
+       int  maxconnect;         /* Maximum connect time (seconds) */\r
+\r
+       char user[MAXNAMELEN + 1];/* Username for PAP */\r
+       char passwd[MAXSECRETLEN + 1];           /* Password for PAP, secret for CHAP */\r
+       char our_name[MAXNAMELEN + 1];         /* Our name for authentication purposes */\r
+       char remote_name[MAXNAMELEN + 1];      /* Peer's name for authentication */\r
+};\r
+\r
+struct ppp_addrs {\r
+    struct ip_addr our_ipaddr, his_ipaddr, netmask, dns1, dns2;\r
+};\r
+\r
+/*****************************\r
+*** PUBLIC DATA STRUCTURES ***\r
+*****************************/\r
+/* Buffers for outgoing packets. */\r
+extern u_char outpacket_buf[NUM_PPP][PPP_MRU+PPP_HDRLEN];\r
+\r
+extern struct ppp_settings ppp_settings;\r
+\r
+extern struct protent *ppp_protocols[];/* Table of pointers to supported protocols */\r
+\r
+\r
+/***********************\r
+*** PUBLIC FUNCTIONS ***\r
+***********************/\r
+\r
+/* Initialize the PPP subsystem. */\r
+void pppInit(void);\r
+\r
+/* Warning: Using PPPAUTHTYPE_ANY might have security consequences.\r
+ * RFC 1994 says:\r
+ *\r
+ * In practice, within or associated with each PPP server, there is a\r
+ * database which associates "user" names with authentication\r
+ * information ("secrets").  It is not anticipated that a particular\r
+ * named user would be authenticated by multiple methods.  This would\r
+ * make the user vulnerable to attacks which negotiate the least secure\r
+ * method from among a set (such as PAP rather than CHAP).  If the same\r
+ * secret was used, PAP would reveal the secret to be used later with\r
+ * CHAP.\r
+ *\r
+ * Instead, for each user name there should be an indication of exactly\r
+ * one method used to authenticate that user name.  If a user needs to\r
+ * make use of different authentication methods under different\r
+ * circumstances, then distinct user names SHOULD be employed, each of\r
+ * which identifies exactly one authentication method.\r
+ *\r
+ */\r
+enum pppAuthType {\r
+    PPPAUTHTYPE_NONE,\r
+    PPPAUTHTYPE_ANY,\r
+    PPPAUTHTYPE_PAP,\r
+    PPPAUTHTYPE_CHAP\r
+};\r
+\r
+void pppSetAuth(enum pppAuthType authType, const char *user, const char *passwd);\r
+\r
+/*\r
+ * Open a new PPP connection using the given I/O device.\r
+ * This initializes the PPP control block but does not\r
+ * attempt to negotiate the LCP session.\r
+ * Return a new PPP connection descriptor on success or\r
+ * an error code (negative) on failure. \r
+ */\r
+int pppOpen(sio_fd_t fd, void (*linkStatusCB)(void *ctx, int errCode, void *arg), void *linkStatusCtx);\r
+\r
+/*\r
+ * Close a PPP connection and release the descriptor. \r
+ * Any outstanding packets in the queues are dropped.\r
+ * Return 0 on success, an error code on failure. \r
+ */\r
+int pppClose(int pd);\r
+\r
+/*\r
+ * Indicate to the PPP process that the line has disconnected.\r
+ */\r
+void pppSigHUP(int pd);\r
+\r
+/*\r
+ * Get and set parameters for the given connection.\r
+ * Return 0 on success, an error code on failure. \r
+ */\r
+int  pppIOCtl(int pd, int cmd, void *arg);\r
+\r
+/*\r
+ * Return the Maximum Transmission Unit for the given PPP connection.\r
+ */\r
+u_int pppMTU(int pd);\r
+\r
+/*\r
+ * Write n characters to a ppp link.\r
+ *     RETURN: >= 0 Number of characters written\r
+ *                      -1 Failed to write to device\r
+ */\r
+int pppWrite(int pd, const u_char *s, int n);\r
+\r
+void pppMainWakeup(int pd);\r
+\r
+/* Configure i/f transmit parameters */\r
+void ppp_send_config (int, int, u32_t, int, int);\r
+/* Set extended transmit ACCM */\r
+void ppp_set_xaccm (int, ext_accm *);\r
+/* Configure i/f receive parameters */\r
+void ppp_recv_config (int, int, u32_t, int, int);\r
+/* Find out how long link has been idle */\r
+int  get_idle_time (int, struct ppp_idle *);\r
+\r
+/* Configure VJ TCP header compression */\r
+int  sifvjcomp (int, int, int, int);\r
+/* Configure i/f down (for IP) */\r
+int  sifup (int);              \r
+/* Set mode for handling packets for proto */\r
+int  sifnpmode (int u, int proto, enum NPmode mode);\r
+/* Configure i/f down (for IP) */\r
+int  sifdown (int);    \r
+/* Configure IP addresses for i/f */\r
+int  sifaddr (int, u32_t, u32_t, u32_t, u32_t, u32_t);\r
+/* Reset i/f IP addresses */\r
+int  cifaddr (int, u32_t, u32_t);\r
+/* Create default route through i/f */\r
+int  sifdefaultroute (int, u32_t, u32_t);\r
+/* Delete default route through i/f */\r
+int  cifdefaultroute (int, u32_t, u32_t);\r
+\r
+/* Get appropriate netmask for address */\r
+u32_t GetMask (u32_t); \r
+\r
+#endif /* PPP_SUPPORT */\r
+\r
+#endif /* PPP_H */\r
index de1478cee832505541b76f2c49f7174209661f33..e4cf25a393c56306ebbb6863827b9e9a8f5fc897 100644 (file)
@@ -1,89 +1,89 @@
-/*****************************************************************************
-* pppdebug.h - System debugging utilities.
-*
-* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
-* portions Copyright (c) 1998 Global Election Systems Inc.
-* portions Copyright (c) 2001 by Cognizant Pty Ltd.
-*
-* The authors hereby grant permission to use, copy, modify, distribute,
-* and license this software and its documentation for any purpose, provided
-* that existing copyright notices are retained in all copies and that this
-* notice and the following disclaimer are included verbatim in any 
-* distributions. No written agreement, license, or royalty fee is required
-* for any of the authorized uses.
-*
-* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *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 CONTRIBUTORS 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.
-*
-******************************************************************************
-* REVISION HISTORY (please don't use tabs!)
-*
-* 03-01-01 Marc Boucher <marc@mbsi.ca>
-*   Ported to lwIP.
-* 98-07-29 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
-*      Original.
-*
-*****************************************************************************
-*/
-#ifndef PPPDEBUG_H
-#define PPPDEBUG_H
-
-/************************
-*** PUBLIC DATA TYPES ***
-************************/
-/* Trace levels. */
-typedef enum {
-       LOG_CRITICAL = 0,
-       LOG_ERR = 1,
-       LOG_NOTICE = 2,
-       LOG_WARNING = 3,
-       LOG_INFO = 5,
-       LOG_DETAIL = 6,
-       LOG_DEBUG = 7
-} LogCodes;
-
-
-/***********************
-*** PUBLIC FUNCTIONS ***
-***********************/
-/*
- *     ppp_trace - a form of printf to send tracing information to stderr
- */
-void ppp_trace(int level, const char *format,...);
-
-#if PPP_DEBUG > 0
-
-#define AUTHDEBUG(a) ppp_trace a
-#define IPCPDEBUG(a) ppp_trace a
-#define UPAPDEBUG(a) ppp_trace a
-#define LCPDEBUG(a) ppp_trace a
-#define FSMDEBUG(a) ppp_trace a
-#define CHAPDEBUG(a) ppp_trace a
-#define PPPDEBUG(a) ppp_trace a
-
-#define TRACELCP 1
-
-#else
-
-#define AUTHDEBUG(a)
-#define IPCPDEBUG(a)
-#define UPAPDEBUG(a)
-#define LCPDEBUG(a)
-#define FSMDEBUG(a)
-#define CHAPDEBUG(a)
-
-#define PPPDEBUG(a)
-
-#define TRACELCP 0
-
-#endif
-
-#endif /* PPPDEBUG_H */
+/*****************************************************************************\r
+* pppdebug.h - System debugging utilities.\r
+*\r
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.\r
+* portions Copyright (c) 1998 Global Election Systems Inc.\r
+* portions Copyright (c) 2001 by Cognizant Pty Ltd.\r
+*\r
+* The authors hereby grant permission to use, copy, modify, distribute,\r
+* and license this software and its documentation for any purpose, provided\r
+* that existing copyright notices are retained in all copies and that this\r
+* notice and the following disclaimer are included verbatim in any \r
+* distributions. No written agreement, license, or royalty fee is required\r
+* for any of the authorized uses.\r
+*\r
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR\r
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+*\r
+******************************************************************************\r
+* REVISION HISTORY (please don't use tabs!)\r
+*\r
+* 03-01-01 Marc Boucher <marc@mbsi.ca>\r
+*   Ported to lwIP.\r
+* 98-07-29 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.\r
+*      Original.\r
+*\r
+*****************************************************************************\r
+*/\r
+#ifndef PPPDEBUG_H\r
+#define PPPDEBUG_H\r
+\r
+/************************\r
+*** PUBLIC DATA TYPES ***\r
+************************/\r
+/* Trace levels. */\r
+typedef enum {\r
+       LOG_CRITICAL = 0,\r
+       LOG_ERR = 1,\r
+       LOG_NOTICE = 2,\r
+       LOG_WARNING = 3,\r
+       LOG_INFO = 5,\r
+       LOG_DETAIL = 6,\r
+       LOG_DEBUG = 7\r
+} LogCodes;\r
+\r
+\r
+/***********************\r
+*** PUBLIC FUNCTIONS ***\r
+***********************/\r
+/*\r
+ *     ppp_trace - a form of printf to send tracing information to stderr\r
+ */\r
+void ppp_trace(int level, const char *format,...);\r
+\r
+#if PPP_DEBUG > 0\r
+\r
+#define AUTHDEBUG(a) ppp_trace a\r
+#define IPCPDEBUG(a) ppp_trace a\r
+#define UPAPDEBUG(a) ppp_trace a\r
+#define LCPDEBUG(a) ppp_trace a\r
+#define FSMDEBUG(a) ppp_trace a\r
+#define CHAPDEBUG(a) ppp_trace a\r
+#define PPPDEBUG(a) ppp_trace a\r
+\r
+#define TRACELCP 1\r
+\r
+#else\r
+\r
+#define AUTHDEBUG(a)\r
+#define IPCPDEBUG(a)\r
+#define UPAPDEBUG(a)\r
+#define LCPDEBUG(a)\r
+#define FSMDEBUG(a)\r
+#define CHAPDEBUG(a)\r
+\r
+#define PPPDEBUG(a)\r
+\r
+#define TRACELCP 0\r
+\r
+#endif\r
+\r
+#endif /* PPPDEBUG_H */\r
index 05eeb4410d7ca60ca2be5dc6d5077e1d214f1c1e..d4431dd8ec104e1fba076ead68e71830aab33122 100644 (file)
-/*****************************************************************************
-* randm.c - Random number generator program file.
-*
-* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
-* Copyright (c) 1998 by Global Election Systems Inc.
-*
-* The authors hereby grant permission to use, copy, modify, distribute,
-* and license this software and its documentation for any purpose, provided
-* that existing copyright notices are retained in all copies and that this
-* notice and the following disclaimer are included verbatim in any 
-* distributions. No written agreement, license, or royalty fee is required
-* for any of the authorized uses.
-*
-* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *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 CONTRIBUTORS 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.
-*
-******************************************************************************
-* REVISION HISTORY
-*
-* 03-01-01 Marc Boucher <marc@mbsi.ca>
-*   Ported to lwIP.
-* 98-06-03 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
-*   Extracted from avos.
-*****************************************************************************/
-
-#include "ppp.h"
-#if PPP_SUPPORT > 0
-#include "md5.h"
-#include "randm.h"
-
-#include "pppdebug.h"
-
-
-#if MD5_SUPPORT>0   /* this module depends on MD5 */
-#define RANDPOOLSZ 16   /* Bytes stored in the pool of randomness. */
-
-/*****************************/
-/*** LOCAL DATA STRUCTURES ***/
-/*****************************/
-static char randPool[RANDPOOLSZ];   /* Pool of randomness. */
-static long randCount = 0;      /* Pseudo-random incrementer */
-
-
-/***********************************/
-/*** PUBLIC FUNCTION DEFINITIONS ***/
-/***********************************/
-/*
- * Initialize the random number generator.
- *
- * Since this is to be called on power up, we don't have much
- *  system randomess to work with.  Here all we use is the
- *  real-time clock.  We'll accumulate more randomness as soon
- *  as things start happening.
- */
-void avRandomInit()
-{
-    avChurnRand(NULL, 0);
-}
-
-/*
- * Churn the randomness pool on a random event.  Call this early and often
- *  on random and semi-random system events to build randomness in time for
- *  usage.  For randomly timed events, pass a null pointer and a zero length
- *  and this will use the system timer and other sources to add randomness.
- *  If new random data is available, pass a pointer to that and it will be
- *  included.
- *
- * Ref: Applied Cryptography 2nd Ed. by Bruce Schneier p. 427
- */
-void avChurnRand(char *randData, u32_t randLen)
-{
-    MD5_CTX md5;
-
-/*  ppp_trace(LOG_INFO, "churnRand: %u@%P\n", randLen, randData); */
-    MD5Init(&md5);
-    MD5Update(&md5, (u_char *)randPool, sizeof(randPool));
-    if (randData)
-        MD5Update(&md5, (u_char *)randData, randLen);
-    else {
-        struct {
-            /* INCLUDE fields for any system sources of randomness */
-            char foobar;
-        } sysData;
-
-        /* Load sysData fields here. */
-        ;
-        MD5Update(&md5, (u_char *)&sysData, sizeof(sysData));
-    }
-    MD5Final((u_char *)randPool, &md5);
-/*  ppp_trace(LOG_INFO, "churnRand: -> 0\n"); */
-}
-
-/*
- * Use the random pool to generate random data.  This degrades to pseudo
- *  random when used faster than randomness is supplied using churnRand().
- * Note: It's important that there be sufficient randomness in randPool
- *  before this is called for otherwise the range of the result may be
- *  narrow enough to make a search feasible.
- *
- * Ref: Applied Cryptography 2nd Ed. by Bruce Schneier p. 427
- *
- * XXX Why does he not just call churnRand() for each block?  Probably
- *  so that you don't ever publish the seed which could possibly help
- *  predict future values.
- * XXX Why don't we preserve md5 between blocks and just update it with
- *  randCount each time?  Probably there is a weakness but I wish that
- *  it was documented.
- */
-void avGenRand(char *buf, u32_t bufLen)
-{
-    MD5_CTX md5;
-    u_char tmp[16];
-    u32_t n;
-
-    while (bufLen > 0) {
-        n = LWIP_MIN(bufLen, RANDPOOLSZ);
-        MD5Init(&md5);
-        MD5Update(&md5, (u_char *)randPool, sizeof(randPool));
-        MD5Update(&md5, (u_char *)&randCount, sizeof(randCount));
-        MD5Final(tmp, &md5);
-        randCount++;
-        memcpy(buf, tmp, n);
-        buf += n;
-        bufLen -= n;
-    }
-}
-
-/*
- * Return a new random number.
- */
-u32_t avRandom()
-{
-    u32_t newRand;
-
-    avGenRand((char *)&newRand, sizeof(newRand));
-
-    return newRand;
-}
-
-#else /* MD5_SUPPORT */
-
-
-/*****************************/
-/*** LOCAL DATA STRUCTURES ***/
-/*****************************/
-static int  avRandomized = 0;       /* Set when truely randomized. */
-static u32_t avRandomSeed = 0;      /* Seed used for random number generation. */
-
-
-/***********************************/
-/*** PUBLIC FUNCTION DEFINITIONS ***/
-/***********************************/
-/*
- * Initialize the random number generator.
- *
- * Here we attempt to compute a random number seed but even if
- * it isn't random, we'll randomize it later.
- *
- * The current method uses the fields from the real time clock,
- * the idle process counter, the millisecond counter, and the
- * hardware timer tick counter.  When this is invoked
- * in startup(), then the idle counter and timer values may
- * repeat after each boot and the real time clock may not be
- * operational.  Thus we call it again on the first random
- * event.
- */
-void avRandomInit()
-{
-#if 0
-    /* Get a pointer into the last 4 bytes of clockBuf. */
-    u32_t *lptr1 = (u32_t *)((char *)&clockBuf[3]);
-
-    /*
-     * Initialize our seed using the real-time clock, the idle
-     * counter, the millisecond timer, and the hardware timer
-     * tick counter.  The real-time clock and the hardware
-     * tick counter are the best sources of randomness but
-     * since the tick counter is only 16 bit (and truncated
-     * at that), the idle counter and millisecond timer
-     * (which may be small values) are added to help
-     * randomize the lower 16 bits of the seed.
-     */
-    readClk();
-    avRandomSeed += *(u32_t *)clockBuf + *lptr1 + OSIdleCtr
-             + ppp_mtime() + ((u32_t)TM1 << 16) + TM1;
-#else
-    avRandomSeed += sys_jiffies(); /* XXX */
-#endif
-        
-    /* Initialize the Borland random number generator. */
-    srand((unsigned)avRandomSeed);
-}
-
-/*
- * Randomize our random seed value.  Here we use the fact that
- * this function is called at *truely random* times by the polling
- * and network functions.  Here we only get 16 bits of new random
- * value but we use the previous value to randomize the other 16
- * bits.
- */
-void avRandomize(void)
-{
-    static u32_t last_jiffies;
-
-    if (!avRandomized) {
-        avRandomized = !0;
-        avRandomInit();
-        /* The initialization function also updates the seed. */
-    } else {
-/*        avRandomSeed += (avRandomSeed << 16) + TM1; */
-       avRandomSeed += (sys_jiffies() - last_jiffies); /* XXX */
-    }
-    last_jiffies = sys_jiffies();
-}
-
-/*
- * Return a new random number.
- * Here we use the Borland rand() function to supply a pseudo random
- * number which we make truely random by combining it with our own
- * seed which is randomized by truely random events. 
- * Thus the numbers will be truely random unless there have been no
- * operator or network events in which case it will be pseudo random
- * seeded by the real time clock.
- */
-u32_t avRandom()
-{
-    return ((((u32_t)rand() << 16) + rand()) + avRandomSeed);
-}
-
-
-
-#endif /* MD5_SUPPORT */
-#endif /* PPP_SUPPORT */
-
+/*****************************************************************************\r
+* randm.c - Random number generator program file.\r
+*\r
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.\r
+* Copyright (c) 1998 by Global Election Systems Inc.\r
+*\r
+* The authors hereby grant permission to use, copy, modify, distribute,\r
+* and license this software and its documentation for any purpose, provided\r
+* that existing copyright notices are retained in all copies and that this\r
+* notice and the following disclaimer are included verbatim in any \r
+* distributions. No written agreement, license, or royalty fee is required\r
+* for any of the authorized uses.\r
+*\r
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR\r
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+*\r
+******************************************************************************\r
+* REVISION HISTORY\r
+*\r
+* 03-01-01 Marc Boucher <marc@mbsi.ca>\r
+*   Ported to lwIP.\r
+* 98-06-03 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.\r
+*   Extracted from avos.\r
+*****************************************************************************/\r
+\r
+#include "ppp.h"\r
+#if PPP_SUPPORT > 0\r
+#include "md5.h"\r
+#include "randm.h"\r
+\r
+#include "pppdebug.h"\r
+\r
+\r
+#if MD5_SUPPORT>0   /* this module depends on MD5 */\r
+#define RANDPOOLSZ 16   /* Bytes stored in the pool of randomness. */\r
+\r
+/*****************************/\r
+/*** LOCAL DATA STRUCTURES ***/\r
+/*****************************/\r
+static char randPool[RANDPOOLSZ];   /* Pool of randomness. */\r
+static long randCount = 0;      /* Pseudo-random incrementer */\r
+\r
+\r
+/***********************************/\r
+/*** PUBLIC FUNCTION DEFINITIONS ***/\r
+/***********************************/\r
+/*\r
+ * Initialize the random number generator.\r
+ *\r
+ * Since this is to be called on power up, we don't have much\r
+ *  system randomess to work with.  Here all we use is the\r
+ *  real-time clock.  We'll accumulate more randomness as soon\r
+ *  as things start happening.\r
+ */\r
+void avRandomInit()\r
+{\r
+    avChurnRand(NULL, 0);\r
+}\r
+\r
+/*\r
+ * Churn the randomness pool on a random event.  Call this early and often\r
+ *  on random and semi-random system events to build randomness in time for\r
+ *  usage.  For randomly timed events, pass a null pointer and a zero length\r
+ *  and this will use the system timer and other sources to add randomness.\r
+ *  If new random data is available, pass a pointer to that and it will be\r
+ *  included.\r
+ *\r
+ * Ref: Applied Cryptography 2nd Ed. by Bruce Schneier p. 427\r
+ */\r
+void avChurnRand(char *randData, u32_t randLen)\r
+{\r
+    MD5_CTX md5;\r
+\r
+/*  ppp_trace(LOG_INFO, "churnRand: %u@%P\n", randLen, randData); */\r
+    MD5Init(&md5);\r
+    MD5Update(&md5, (u_char *)randPool, sizeof(randPool));\r
+    if (randData)\r
+        MD5Update(&md5, (u_char *)randData, randLen);\r
+    else {\r
+        struct {\r
+            /* INCLUDE fields for any system sources of randomness */\r
+            char foobar;\r
+        } sysData;\r
+\r
+        /* Load sysData fields here. */\r
+        ;\r
+        MD5Update(&md5, (u_char *)&sysData, sizeof(sysData));\r
+    }\r
+    MD5Final((u_char *)randPool, &md5);\r
+/*  ppp_trace(LOG_INFO, "churnRand: -> 0\n"); */\r
+}\r
+\r
+/*\r
+ * Use the random pool to generate random data.  This degrades to pseudo\r
+ *  random when used faster than randomness is supplied using churnRand().\r
+ * Note: It's important that there be sufficient randomness in randPool\r
+ *  before this is called for otherwise the range of the result may be\r
+ *  narrow enough to make a search feasible.\r
+ *\r
+ * Ref: Applied Cryptography 2nd Ed. by Bruce Schneier p. 427\r
+ *\r
+ * XXX Why does he not just call churnRand() for each block?  Probably\r
+ *  so that you don't ever publish the seed which could possibly help\r
+ *  predict future values.\r
+ * XXX Why don't we preserve md5 between blocks and just update it with\r
+ *  randCount each time?  Probably there is a weakness but I wish that\r
+ *  it was documented.\r
+ */\r
+void avGenRand(char *buf, u32_t bufLen)\r
+{\r
+    MD5_CTX md5;\r
+    u_char tmp[16];\r
+    u32_t n;\r
+\r
+    while (bufLen > 0) {\r
+        n = LWIP_MIN(bufLen, RANDPOOLSZ);\r
+        MD5Init(&md5);\r
+        MD5Update(&md5, (u_char *)randPool, sizeof(randPool));\r
+        MD5Update(&md5, (u_char *)&randCount, sizeof(randCount));\r
+        MD5Final(tmp, &md5);\r
+        randCount++;\r
+        memcpy(buf, tmp, n);\r
+        buf += n;\r
+        bufLen -= n;\r
+    }\r
+}\r
+\r
+/*\r
+ * Return a new random number.\r
+ */\r
+u32_t avRandom()\r
+{\r
+    u32_t newRand;\r
+\r
+    avGenRand((char *)&newRand, sizeof(newRand));\r
+\r
+    return newRand;\r
+}\r
+\r
+#else /* MD5_SUPPORT */\r
+\r
+\r
+/*****************************/\r
+/*** LOCAL DATA STRUCTURES ***/\r
+/*****************************/\r
+static int  avRandomized = 0;       /* Set when truely randomized. */\r
+static u32_t avRandomSeed = 0;      /* Seed used for random number generation. */\r
+\r
+\r
+/***********************************/\r
+/*** PUBLIC FUNCTION DEFINITIONS ***/\r
+/***********************************/\r
+/*\r
+ * Initialize the random number generator.\r
+ *\r
+ * Here we attempt to compute a random number seed but even if\r
+ * it isn't random, we'll randomize it later.\r
+ *\r
+ * The current method uses the fields from the real time clock,\r
+ * the idle process counter, the millisecond counter, and the\r
+ * hardware timer tick counter.  When this is invoked\r
+ * in startup(), then the idle counter and timer values may\r
+ * repeat after each boot and the real time clock may not be\r
+ * operational.  Thus we call it again on the first random\r
+ * event.\r
+ */\r
+void avRandomInit()\r
+{\r
+#if 0\r
+    /* Get a pointer into the last 4 bytes of clockBuf. */\r
+    u32_t *lptr1 = (u32_t *)((char *)&clockBuf[3]);\r
+\r
+    /*\r
+     * Initialize our seed using the real-time clock, the idle\r
+     * counter, the millisecond timer, and the hardware timer\r
+     * tick counter.  The real-time clock and the hardware\r
+     * tick counter are the best sources of randomness but\r
+     * since the tick counter is only 16 bit (and truncated\r
+     * at that), the idle counter and millisecond timer\r
+     * (which may be small values) are added to help\r
+     * randomize the lower 16 bits of the seed.\r
+     */\r
+    readClk();\r
+    avRandomSeed += *(u32_t *)clockBuf + *lptr1 + OSIdleCtr\r
+             + ppp_mtime() + ((u32_t)TM1 << 16) + TM1;\r
+#else\r
+    avRandomSeed += sys_jiffies(); /* XXX */\r
+#endif\r
+        \r
+    /* Initialize the Borland random number generator. */\r
+    srand((unsigned)avRandomSeed);\r
+}\r
+\r
+/*\r
+ * Randomize our random seed value.  Here we use the fact that\r
+ * this function is called at *truely random* times by the polling\r
+ * and network functions.  Here we only get 16 bits of new random\r
+ * value but we use the previous value to randomize the other 16\r
+ * bits.\r
+ */\r
+void avRandomize(void)\r
+{\r
+    static u32_t last_jiffies;\r
+\r
+    if (!avRandomized) {\r
+        avRandomized = !0;\r
+        avRandomInit();\r
+        /* The initialization function also updates the seed. */\r
+    } else {\r
+/*        avRandomSeed += (avRandomSeed << 16) + TM1; */\r
+       avRandomSeed += (sys_jiffies() - last_jiffies); /* XXX */\r
+    }\r
+    last_jiffies = sys_jiffies();\r
+}\r
+\r
+/*\r
+ * Return a new random number.\r
+ * Here we use the Borland rand() function to supply a pseudo random\r
+ * number which we make truely random by combining it with our own\r
+ * seed which is randomized by truely random events. \r
+ * Thus the numbers will be truely random unless there have been no\r
+ * operator or network events in which case it will be pseudo random\r
+ * seeded by the real time clock.\r
+ */\r
+u32_t avRandom()\r
+{\r
+    return ((((u32_t)rand() << 16) + rand()) + avRandomSeed);\r
+}\r
+\r
+\r
+\r
+#endif /* MD5_SUPPORT */\r
+#endif /* PPP_SUPPORT */\r
+\r
index baa42f0c2cdfe3f82a0f3a7483f48b43b6419e84..2563d8976719a8332d38df26879cf6a38f395a37 100644 (file)
@@ -1,81 +1,81 @@
-/*****************************************************************************
-* randm.h - Random number generator header file.
-*
-* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
-* Copyright (c) 1998 Global Election Systems Inc.
-*
-* The authors hereby grant permission to use, copy, modify, distribute,
-* and license this software and its documentation for any purpose, provided
-* that existing copyright notices are retained in all copies and that this
-* notice and the following disclaimer are included verbatim in any 
-* distributions. No written agreement, license, or royalty fee is required
-* for any of the authorized uses.
-*
-* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *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 CONTRIBUTORS 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.
-*
-******************************************************************************
-* REVISION HISTORY
-*
-* 03-01-01 Marc Boucher <marc@mbsi.ca>
-*   Ported to lwIP.
-* 98-05-29 Guy Lancaster <glanca@gesn.com>, Global Election Systems Inc.
-*      Extracted from avos.
-*****************************************************************************/
-
-#ifndef RANDM_H
-#define RANDM_H
-
-/***********************
-*** PUBLIC FUNCTIONS ***
-***********************/
-/*
- * Initialize the random number generator.
- */
-void avRandomInit(void);
-
-/*
- * Churn the randomness pool on a random event.  Call this early and often
- *     on random and semi-random system events to build randomness in time for
- *     usage.  For randomly timed events, pass a null pointer and a zero length
- *     and this will use the system timer and other sources to add randomness.
- *     If new random data is available, pass a pointer to that and it will be
- *     included.
- */
-void avChurnRand(char *randData, u32_t randLen);
-
-/*
- * Randomize our random seed value.  To be called for truely random events
- * such as user operations and network traffic.
- */
-#if MD5_SUPPORT
-#define avRandomize()  avChurnRand(NULL, 0)
-#else
-void avRandomize(void);
-#endif
-
-/*
- * Use the random pool to generate random data.  This degrades to pseudo
- *     random when used faster than randomness is supplied using churnRand().
- *     Thus it's important to make sure that the results of this are not
- *     published directly because one could predict the next result to at
- *     least some degree.  Also, it's important to get a good seed before
- *     the first use.
- */
-void avGenRand(char *buf, u32_t bufLen);
-
-/*
- * Return a new random number.
- */
-u32_t avRandom(void);
-
-
-#endif /* RANDM_H */
+/*****************************************************************************\r
+* randm.h - Random number generator header file.\r
+*\r
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.\r
+* Copyright (c) 1998 Global Election Systems Inc.\r
+*\r
+* The authors hereby grant permission to use, copy, modify, distribute,\r
+* and license this software and its documentation for any purpose, provided\r
+* that existing copyright notices are retained in all copies and that this\r
+* notice and the following disclaimer are included verbatim in any \r
+* distributions. No written agreement, license, or royalty fee is required\r
+* for any of the authorized uses.\r
+*\r
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR\r
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+*\r
+******************************************************************************\r
+* REVISION HISTORY\r
+*\r
+* 03-01-01 Marc Boucher <marc@mbsi.ca>\r
+*   Ported to lwIP.\r
+* 98-05-29 Guy Lancaster <glanca@gesn.com>, Global Election Systems Inc.\r
+*      Extracted from avos.\r
+*****************************************************************************/\r
+\r
+#ifndef RANDM_H\r
+#define RANDM_H\r
+\r
+/***********************\r
+*** PUBLIC FUNCTIONS ***\r
+***********************/\r
+/*\r
+ * Initialize the random number generator.\r
+ */\r
+void avRandomInit(void);\r
+\r
+/*\r
+ * Churn the randomness pool on a random event.  Call this early and often\r
+ *     on random and semi-random system events to build randomness in time for\r
+ *     usage.  For randomly timed events, pass a null pointer and a zero length\r
+ *     and this will use the system timer and other sources to add randomness.\r
+ *     If new random data is available, pass a pointer to that and it will be\r
+ *     included.\r
+ */\r
+void avChurnRand(char *randData, u32_t randLen);\r
+\r
+/*\r
+ * Randomize our random seed value.  To be called for truely random events\r
+ * such as user operations and network traffic.\r
+ */\r
+#if MD5_SUPPORT\r
+#define avRandomize()  avChurnRand(NULL, 0)\r
+#else\r
+void avRandomize(void);\r
+#endif\r
+\r
+/*\r
+ * Use the random pool to generate random data.  This degrades to pseudo\r
+ *     random when used faster than randomness is supplied using churnRand().\r
+ *     Thus it's important to make sure that the results of this are not\r
+ *     published directly because one could predict the next result to at\r
+ *     least some degree.  Also, it's important to get a good seed before\r
+ *     the first use.\r
+ */\r
+void avGenRand(char *buf, u32_t bufLen);\r
+\r
+/*\r
+ * Return a new random number.\r
+ */\r
+u32_t avRandom(void);\r
+\r
+\r
+#endif /* RANDM_H */\r
index 0636ee11bd89afc885a57dd467f2b0fc67800592..2c11affe35821fd4774a66d45c72c8841664589c 100644 (file)
-/*
- * Routines to compress and uncompess tcp packets (for transmission
- * over low speed serial lines.
- *
- * Copyright (c) 1989 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley.  The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- *     Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989:
- *     - Initial distribution.
- *
- * Modified June 1993 by Paul Mackerras, paulus@cs.anu.edu.au,
- * so that the entire packet being decompressed doesn't have
- * to be in contiguous memory (just the compressed header).
- *
- * Modified March 1998 by Guy Lancaster, glanca@gesn.com,
- * for a 16 bit processor.
- */
-
-#include <string.h>
-
-#include "ppp.h"
-#include "vj.h"
-#include "pppdebug.h"
-
-#if VJ_SUPPORT > 0
-
-#if LINK_STATS
-#define INCR(counter) ++comp->stats.counter
-#else
-#define INCR(counter)
-#endif
-
-#if defined(NO_CHAR_BITFIELDS)
-#define getip_hl(base) ((base).ip_hl_v&0xf)
-#define getth_off(base)        (((base).th_x2_off&0xf0)>>4)
-#else
-#define getip_hl(base) ((base).ip_hl)
-#define getth_off(base)        ((base).th_off)
-#endif
-
-void vj_compress_init(struct vjcompress *comp)
-{
-       register u_int i;
-       register struct cstate *tstate = comp->tstate;
-       
-#if MAX_SLOTS == 0
-       memset((char *)comp, 0, sizeof(*comp));
-#endif
-       comp->maxSlotIndex = MAX_SLOTS - 1;
-       comp->compressSlot = 0;         /* Disable slot ID compression by default. */
-       for (i = MAX_SLOTS - 1; i > 0; --i) {
-               tstate[i].cs_id = i;
-               tstate[i].cs_next = &tstate[i - 1];
-       }
-       tstate[0].cs_next = &tstate[MAX_SLOTS - 1];
-       tstate[0].cs_id = 0;
-       comp->last_cs = &tstate[0];
-       comp->last_recv = 255;
-       comp->last_xmit = 255;
-       comp->flags = VJF_TOSS;
-}
-
-
-/* ENCODE encodes a number that is known to be non-zero.  ENCODEZ
- * checks for zero (since zero has to be encoded in the long, 3 byte
- * form).
- */
-#define ENCODE(n) { \
-       if ((u_short)(n) >= 256) { \
-               *cp++ = 0; \
-               cp[1] = (n); \
-               cp[0] = (n) >> 8; \
-               cp += 2; \
-       } else { \
-               *cp++ = (n); \
-       } \
-}
-#define ENCODEZ(n) { \
-       if ((u_short)(n) >= 256 || (u_short)(n) == 0) { \
-               *cp++ = 0; \
-               cp[1] = (n); \
-               cp[0] = (n) >> 8; \
-               cp += 2; \
-       } else { \
-               *cp++ = (n); \
-       } \
-}
-
-#define DECODEL(f) { \
-       if (*cp == 0) {\
-               u32_t tmp = ntohl(f) + ((cp[1] << 8) | cp[2]); \
-               (f) = htonl(tmp); \
-               cp += 3; \
-       } else { \
-               u32_t tmp = ntohl(f) + (u32_t)*cp++; \
-               (f) = htonl(tmp); \
-       } \
-}
-
-#define DECODES(f) { \
-       if (*cp == 0) {\
-               u_short tmp = ntohs(f) + (((u_short)cp[1] << 8) | cp[2]); \
-               (f) = htons(tmp); \
-               cp += 3; \
-       } else { \
-               u_short tmp = ntohs(f) + (u_short)*cp++; \
-               (f) = htons(tmp); \
-       } \
-}
-
-#define DECODEU(f) { \
-       if (*cp == 0) {\
-               (f) = htons(((u_short)cp[1] << 8) | cp[2]); \
-               cp += 3; \
-       } else { \
-               (f) = htons((u_short)*cp++); \
-       } \
-}
-
-/*
- * vj_compress_tcp - Attempt to do Van Jacobsen header compression on a
- * packet.  This assumes that nb and comp are not null and that the first
- * buffer of the chain contains a valid IP header.
- * Return the VJ type code indicating whether or not the packet was
- * compressed.
- */
-u_int vj_compress_tcp(
-       struct vjcompress *comp,
-       struct pbuf *pb
-)
-{
-       register struct ip *ip = (struct ip *)pb->payload;
-       register struct cstate *cs = comp->last_cs->cs_next;
-       register u_short hlen = getip_hl(*ip);
-       register struct tcphdr *oth;
-       register struct tcphdr *th;
-       register u_short deltaS, deltaA;
-       register u_long deltaL;
-       register u_int changes = 0;
-       u_char new_seq[16];
-       register u_char *cp = new_seq;
-
-       /*      
-        * Check that the packet is IP proto TCP.
-        */
-       if (ip->ip_p != IPPROTO_TCP)
-               return (TYPE_IP);
-               
-       /*
-        * Bail if this is an IP fragment or if the TCP packet isn't
-        * `compressible' (i.e., ACK isn't set or some other control bit is
-        * set).  
-        */
-       if ((ip->ip_off & htons(0x3fff)) || pb->tot_len < 40)
-               return (TYPE_IP);
-       th = (struct tcphdr *)&((long *)ip)[hlen];
-       if ((th->th_flags & (TCP_SYN|TCP_FIN|TCP_RST|TCP_ACK)) != TCP_ACK)
-               return (TYPE_IP);
-               
-       /*
-        * Packet is compressible -- we're going to send either a
-        * COMPRESSED_TCP or UNCOMPRESSED_TCP packet.  Either way we need
-        * to locate (or create) the connection state.  Special case the
-        * most recently used connection since it's most likely to be used
-        * again & we don't have to do any reordering if it's used.
-        */
-       INCR(vjs_packets);
-       if (ip->ip_src.s_addr != cs->cs_ip.ip_src.s_addr 
-                       || ip->ip_dst.s_addr != cs->cs_ip.ip_dst.s_addr 
-                       || *(long *)th != ((long *)&cs->cs_ip)[getip_hl(cs->cs_ip)]) {
-               /*
-                * Wasn't the first -- search for it.
-                *
-                * States are kept in a circularly linked list with
-                * last_cs pointing to the end of the list.  The
-                * list is kept in lru order by moving a state to the
-                * head of the list whenever it is referenced.  Since
-                * the list is short and, empirically, the connection
-                * we want is almost always near the front, we locate
-                * states via linear search.  If we don't find a state
-                * for the datagram, the oldest state is (re-)used.
-                */
-               register struct cstate *lcs;
-               register struct cstate *lastcs = comp->last_cs;
-               
-               do {
-                       lcs = cs; cs = cs->cs_next;
-                       INCR(vjs_searches);
-                       if (ip->ip_src.s_addr == cs->cs_ip.ip_src.s_addr
-                                       && ip->ip_dst.s_addr == cs->cs_ip.ip_dst.s_addr
-                                       && *(long *)th == ((long *)&cs->cs_ip)[getip_hl(cs->cs_ip)])
-                               goto found;
-               } while (cs != lastcs);
-               
-               /*
-                * Didn't find it -- re-use oldest cstate.  Send an
-                * uncompressed packet that tells the other side what
-                * connection number we're using for this conversation.
-                * Note that since the state list is circular, the oldest
-                * state points to the newest and we only need to set
-                * last_cs to update the lru linkage.
-                */
-               INCR(vjs_misses);
-               comp->last_cs = lcs;
-               hlen += getth_off(*th);
-               hlen <<= 2;
-               /* Check that the IP/TCP headers are contained in the first buffer. */
-               if (hlen > pb->len)
-                       return (TYPE_IP);
-               goto uncompressed;
-               
-               found:
-               /*
-                * Found it -- move to the front on the connection list.
-                */
-               if (cs == lastcs)
-                       comp->last_cs = lcs;
-               else {
-                       lcs->cs_next = cs->cs_next;
-                       cs->cs_next = lastcs->cs_next;
-                       lastcs->cs_next = cs;
-               }
-       }
-       
-       oth = (struct tcphdr *)&((long *)&cs->cs_ip)[hlen];
-       deltaS = hlen;
-       hlen += getth_off(*th);
-       hlen <<= 2;
-       /* Check that the IP/TCP headers are contained in the first buffer. */
-       if (hlen > pb->len) {
-               PPPDEBUG((LOG_INFO, "vj_compress_tcp: header len %d spans buffers\n", 
-                                       hlen));
-               return (TYPE_IP);
-       }
-       
-       /*
-        * Make sure that only what we expect to change changed. The first
-        * line of the `if' checks the IP protocol version, header length &
-        * type of service.  The 2nd line checks the "Don't fragment" bit.
-        * The 3rd line checks the time-to-live and protocol (the protocol
-        * check is unnecessary but costless).  The 4th line checks the TCP
-        * header length.  The 5th line checks IP options, if any.  The 6th
-        * line checks TCP options, if any.  If any of these things are
-        * different between the previous & current datagram, we send the
-        * current datagram `uncompressed'.
-        */
-       if (((u_short *)ip)[0] != ((u_short *)&cs->cs_ip)[0] 
-                       || ((u_short *)ip)[3] != ((u_short *)&cs->cs_ip)[3] 
-                       || ((u_short *)ip)[4] != ((u_short *)&cs->cs_ip)[4] 
-                       || getth_off(*th) != getth_off(*oth) 
-                       || (deltaS > 5 && BCMP(ip + 1, &cs->cs_ip + 1, (deltaS - 5) << 2)) 
-                       || (getth_off(*th) > 5 && BCMP(th + 1, oth + 1, (getth_off(*th) - 5) << 2)))
-               goto uncompressed;
-       
-       /*
-        * Figure out which of the changing fields changed.  The
-        * receiver expects changes in the order: urgent, window,
-        * ack, seq (the order minimizes the number of temporaries
-        * needed in this section of code).
-        */
-       if (th->th_flags & TCP_URG) {
-               deltaS = ntohs(th->th_urp);
-               ENCODEZ(deltaS);
-               changes |= NEW_U;
-       } else if (th->th_urp != oth->th_urp)
-               /* argh! URG not set but urp changed -- a sensible
-                * implementation should never do this but RFC793
-                * doesn't prohibit the change so we have to deal
-                * with it. */
-               goto uncompressed;
-       
-       if ((deltaS = (u_short)(ntohs(th->th_win) - ntohs(oth->th_win))) != 0) {
-               ENCODE(deltaS);
-               changes |= NEW_W;
-       }
-       
-       if ((deltaL = ntohl(th->th_ack) - ntohl(oth->th_ack)) != 0) {
-               if (deltaL > 0xffff)
-                       goto uncompressed;
-               deltaA = (u_short)deltaL;
-               ENCODE(deltaA);
-               changes |= NEW_A;
-       }
-       
-       if ((deltaL = ntohl(th->th_seq) - ntohl(oth->th_seq)) != 0) {
-               if (deltaL > 0xffff)
-                       goto uncompressed;
-               deltaS = (u_short)deltaL;
-               ENCODE(deltaS);
-               changes |= NEW_S;
-       }
-       
-       switch(changes) {
-       
-       case 0:
-               /*
-                * Nothing changed. If this packet contains data and the
-                * last one didn't, this is probably a data packet following
-                * an ack (normal on an interactive connection) and we send
-                * it compressed.  Otherwise it's probably a retransmit,
-                * retransmitted ack or window probe.  Send it uncompressed
-                * in case the other side missed the compressed version.
-                */
-               if (ip->ip_len != cs->cs_ip.ip_len &&
-                       ntohs(cs->cs_ip.ip_len) == hlen)
-               break;
-       
-       /* (fall through) */
-       
-       case SPECIAL_I:
-       case SPECIAL_D:
-               /*
-                * actual changes match one of our special case encodings --
-                * send packet uncompressed.
-                */
-               goto uncompressed;
-       
-       case NEW_S|NEW_A:
-               if (deltaS == deltaA && deltaS == ntohs(cs->cs_ip.ip_len) - hlen) {
-                       /* special case for echoed terminal traffic */
-                       changes = SPECIAL_I;
-                       cp = new_seq;
-               }
-               break;
-       
-       case NEW_S:
-               if (deltaS == ntohs(cs->cs_ip.ip_len) - hlen) {
-                       /* special case for data xfer */
-                       changes = SPECIAL_D;
-                       cp = new_seq;
-               }
-               break;
-       }
-       
-       deltaS = (u_short)(ntohs(ip->ip_id) - ntohs(cs->cs_ip.ip_id));
-       if (deltaS != 1) {
-               ENCODEZ(deltaS);
-               changes |= NEW_I;
-       }
-       if (th->th_flags & TCP_PSH)
-       changes |= TCP_PUSH_BIT;
-       /*
-        * Grab the cksum before we overwrite it below.  Then update our
-        * state with this packet's header.
-        */
-       deltaA = ntohs(th->th_sum);
-       BCOPY(ip, &cs->cs_ip, hlen);
-       
-       /*
-        * We want to use the original packet as our compressed packet.
-        * (cp - new_seq) is the number of bytes we need for compressed
-        * sequence numbers.  In addition we need one byte for the change
-        * mask, one for the connection id and two for the tcp checksum.
-        * So, (cp - new_seq) + 4 bytes of header are needed.  hlen is how
-        * many bytes of the original packet to toss so subtract the two to
-        * get the new packet size.
-        */
-       deltaS = (u_short)(cp - new_seq);
-       if (!comp->compressSlot || comp->last_xmit != cs->cs_id) {
-               comp->last_xmit = cs->cs_id;
-               hlen -= deltaS + 4;
-               pbuf_header(pb, -hlen);
-               cp = (u_char *)pb->payload;
-               *cp++ = changes | NEW_C;
-               *cp++ = cs->cs_id;
-       } else {
-               hlen -= deltaS + 3;
-               pbuf_header(pb, -hlen);
-               cp = (u_char *)pb->payload;
-               *cp++ = changes;
-       }
-       *cp++ = deltaA >> 8;
-       *cp++ = deltaA;
-       BCOPY(new_seq, cp, deltaS);
-       INCR(vjs_compressed);
-       return (TYPE_COMPRESSED_TCP);
-
-       /*
-        * Update connection state cs & send uncompressed packet (that is,
-        * a regular ip/tcp packet but with the 'conversation id' we hope
-        * to use on future compressed packets in the protocol field).
-        */
-uncompressed:
-       BCOPY(ip, &cs->cs_ip, hlen);
-       ip->ip_p = cs->cs_id;
-       comp->last_xmit = cs->cs_id;
-       return (TYPE_UNCOMPRESSED_TCP);
-}
-
-/*
- * Called when we may have missed a packet.
- */
-void vj_uncompress_err(struct vjcompress *comp)
-{
-    comp->flags |= VJF_TOSS;
-       INCR(vjs_errorin);
-}
-
-/*
- * "Uncompress" a packet of type TYPE_UNCOMPRESSED_TCP.
- * Return 0 on success, -1 on failure.
- */
-int vj_uncompress_uncomp(
-       struct pbuf *nb,
-       struct vjcompress *comp
-)
-{
-       register u_int hlen;
-       register struct cstate *cs;
-       register struct ip *ip;
-       
-       ip = (struct ip *)nb->payload;
-       hlen = getip_hl(*ip) << 2;
-       if (ip->ip_p >= MAX_SLOTS
-                       || hlen + sizeof(struct tcphdr) > nb->len
-                       || (hlen += getth_off(*((struct tcphdr *)&((char *)ip)[hlen])) << 2)
-                           > nb->len
-                       || hlen > MAX_HDR) {
-               PPPDEBUG((LOG_INFO, "vj_uncompress_uncomp: bad cid=%d, hlen=%d buflen=%d\n", 
-                                       ip->ip_p, hlen, nb->len));
-               comp->flags |= VJF_TOSS;
-               INCR(vjs_errorin);
-               return -1;
-       }
-       cs = &comp->rstate[comp->last_recv = ip->ip_p];
-       comp->flags &=~ VJF_TOSS;
-       ip->ip_p = IPPROTO_TCP;
-       BCOPY(ip, &cs->cs_ip, hlen);
-       cs->cs_hlen = hlen;
-       INCR(vjs_uncompressedin);
-       return 0;
-}
-
-/*
- * Uncompress a packet of type TYPE_COMPRESSED_TCP.
- * The packet is composed of a buffer chain and the first buffer
- * must contain an accurate chain length.
- * The first buffer must include the entire compressed TCP/IP header. 
- * This procedure replaces the compressed header with the uncompressed
- * header and returns the length of the VJ header.
- */
-int vj_uncompress_tcp(
-       struct pbuf **nb,
-       struct vjcompress *comp
-)
-{
-       u_char *cp;
-       struct tcphdr *th;
-       struct cstate *cs;
-       u_short *bp;
-       struct pbuf *n0 = *nb;
-       u32_t tmp;
-       u_int vjlen, hlen, changes;
-       
-       INCR(vjs_compressedin);
-       cp = (u_char *)n0->payload;
-       changes = *cp++;
-       if (changes & NEW_C) {
-               /* 
-                * Make sure the state index is in range, then grab the state.
-                * If we have a good state index, clear the 'discard' flag. 
-                */
-               if (*cp >= MAX_SLOTS) {
-                       PPPDEBUG((LOG_INFO, "vj_uncompress_tcp: bad cid=%d\n", *cp));
-                       goto bad;
-               }
-               
-               comp->flags &=~ VJF_TOSS;
-               comp->last_recv = *cp++;
-       } else {
-               /* 
-                * this packet has an implicit state index.  If we've
-                * had a line error since the last time we got an
-                * explicit state index, we have to toss the packet. 
-                */
-               if (comp->flags & VJF_TOSS) {
-                       PPPDEBUG((LOG_INFO, "vj_uncompress_tcp: tossing\n"));
-                       INCR(vjs_tossed);
-                       return (-1);
-               }
-       }
-       cs = &comp->rstate[comp->last_recv];
-       hlen = getip_hl(cs->cs_ip) << 2;
-       th = (struct tcphdr *)&((u_char *)&cs->cs_ip)[hlen];
-       th->th_sum = htons((*cp << 8) | cp[1]);
-       cp += 2;
-       if (changes & TCP_PUSH_BIT)
-               th->th_flags |= TCP_PSH;
-       else
-               th->th_flags &=~ TCP_PSH;
-       
-       switch (changes & SPECIALS_MASK) {
-       case SPECIAL_I:
-               {
-                       register u32_t i = ntohs(cs->cs_ip.ip_len) - cs->cs_hlen;
-                       /* some compilers can't nest inline assembler.. */
-                       tmp = ntohl(th->th_ack) + i;
-                       th->th_ack = htonl(tmp);
-                       tmp = ntohl(th->th_seq) + i;
-                       th->th_seq = htonl(tmp);
-               }
-               break;
-       
-       case SPECIAL_D:
-               /* some compilers can't nest inline assembler.. */
-               tmp = ntohl(th->th_seq) + ntohs(cs->cs_ip.ip_len) - cs->cs_hlen;
-               th->th_seq = htonl(tmp);
-               break;
-       
-       default:
-               if (changes & NEW_U) {
-                       th->th_flags |= TCP_URG;
-                       DECODEU(th->th_urp);
-               } else
-                       th->th_flags &=~ TCP_URG;
-               if (changes & NEW_W)
-                       DECODES(th->th_win);
-               if (changes & NEW_A)
-                       DECODEL(th->th_ack);
-               if (changes & NEW_S)
-                       DECODEL(th->th_seq);
-               break;
-       }
-       if (changes & NEW_I) {
-               DECODES(cs->cs_ip.ip_id);
-       } else {
-               cs->cs_ip.ip_id = ntohs(cs->cs_ip.ip_id) + 1;
-               cs->cs_ip.ip_id = htons(cs->cs_ip.ip_id);
-       }
-       
-       /*
-        * At this point, cp points to the first byte of data in the
-        * packet.  Fill in the IP total length and update the IP
-        * header checksum.
-        */
-       vjlen = (u_short)(cp - (u_char*)n0->payload);
-       if (n0->len < vjlen) {
-               /* 
-                * We must have dropped some characters (crc should detect
-                * this but the old slip framing won't) 
-                */
-               PPPDEBUG((LOG_INFO, "vj_uncompress_tcp: head buffer %d too short %d\n", 
-                                 n0->len, vjlen));
-               goto bad;
-       }
-       
-#if BYTE_ORDER == LITTLE_ENDIAN
-       tmp = n0->tot_len - vjlen + cs->cs_hlen;
-       cs->cs_ip.ip_len = htons(tmp);
-#else
-       cs->cs_ip.ip_len = htons(n0->tot_len - vjlen + cs->cs_hlen);
-#endif
-       
-       /* recompute the ip header checksum */
-       bp = (u_short *) &cs->cs_ip;
-       cs->cs_ip.ip_sum = 0;
-       for (tmp = 0; hlen > 0; hlen -= 2)
-               tmp += *bp++;
-       tmp = (tmp & 0xffff) + (tmp >> 16);
-       tmp = (tmp & 0xffff) + (tmp >> 16);
-       cs->cs_ip.ip_sum = (u_short)(~tmp);
-       
-       /* Remove the compressed header and prepend the uncompressed header. */
-       pbuf_header(n0, -vjlen);
-
-       if(MEM_ALIGN(n0->payload) != n0->payload) {
-               struct pbuf *np, *q;
-               u8_t *bufptr;
-
-               np = pbuf_alloc(PBUF_RAW, n0->len + cs->cs_hlen, PBUF_POOL);
-               if(!np) {
-                       PPPDEBUG((LOG_WARNING, "vj_uncompress_tcp: realign failed\n"));
-                       *nb = NULL;
-                       goto bad;
-               }
-
-               pbuf_header(np, -cs->cs_hlen);
-
-               bufptr = n0->payload;
-               for(q = np; q != NULL; q = q->next) {
-                       memcpy(q->payload, bufptr, q->len);
-                       bufptr += q->len;
-               }
-
-               if(n0->next) {
-                       pbuf_chain(np, n0->next);
-                       pbuf_dechain(n0);
-               }
-               pbuf_free(n0);
-               n0 = np;
-       }
-
-       if(pbuf_header(n0, cs->cs_hlen)) {
-               struct pbuf *np;
-
-               LWIP_ASSERT("vj_uncompress_tcp: cs->cs_hlen <= PBUF_POOL_BUFSIZE", cs->cs_hlen <= PBUF_POOL_BUFSIZE);
-               np = pbuf_alloc(PBUF_RAW, cs->cs_hlen, PBUF_POOL);
-               if(!np) {
-                       PPPDEBUG((LOG_WARNING, "vj_uncompress_tcp: prepend failed\n"));
-                       *nb = NULL;
-                       goto bad;
-               }
-               pbuf_cat(np, n0);
-               n0 = np;
-       }
-       LWIP_ASSERT("n0->len >= cs->cs_hlen", n0->len >= cs->cs_hlen);
-       memcpy(n0->payload, &cs->cs_ip, cs->cs_hlen);
-
-       *nb = n0;
-
-       return vjlen;
-       
-bad:
-       comp->flags |= VJF_TOSS;
-       INCR(vjs_errorin);
-       return (-1);
-}
-
-#endif
-
-
+/*\r
+ * Routines to compress and uncompess tcp packets (for transmission\r
+ * over low speed serial lines.\r
+ *\r
+ * Copyright (c) 1989 Regents of the University of California.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms are permitted\r
+ * provided that the above copyright notice and this paragraph are\r
+ * duplicated in all such forms and that any documentation,\r
+ * advertising materials, and other materials related to such\r
+ * distribution and use acknowledge that the software was developed\r
+ * by the University of California, Berkeley.  The name of the\r
+ * University may not be used to endorse or promote products derived\r
+ * from this software without specific prior written permission.\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR\r
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r
+ *\r
+ *     Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989:\r
+ *     - Initial distribution.\r
+ *\r
+ * Modified June 1993 by Paul Mackerras, paulus@cs.anu.edu.au,\r
+ * so that the entire packet being decompressed doesn't have\r
+ * to be in contiguous memory (just the compressed header).\r
+ *\r
+ * Modified March 1998 by Guy Lancaster, glanca@gesn.com,\r
+ * for a 16 bit processor.\r
+ */\r
+\r
+#include <string.h>\r
+\r
+#include "ppp.h"\r
+#include "vj.h"\r
+#include "pppdebug.h"\r
+\r
+#if VJ_SUPPORT > 0\r
+\r
+#if LINK_STATS\r
+#define INCR(counter) ++comp->stats.counter\r
+#else\r
+#define INCR(counter)\r
+#endif\r
+\r
+#if defined(NO_CHAR_BITFIELDS)\r
+#define getip_hl(base) ((base).ip_hl_v&0xf)\r
+#define getth_off(base)        (((base).th_x2_off&0xf0)>>4)\r
+#else\r
+#define getip_hl(base) ((base).ip_hl)\r
+#define getth_off(base)        ((base).th_off)\r
+#endif\r
+\r
+void vj_compress_init(struct vjcompress *comp)\r
+{\r
+       register u_int i;\r
+       register struct cstate *tstate = comp->tstate;\r
+       \r
+#if MAX_SLOTS == 0\r
+       memset((char *)comp, 0, sizeof(*comp));\r
+#endif\r
+       comp->maxSlotIndex = MAX_SLOTS - 1;\r
+       comp->compressSlot = 0;         /* Disable slot ID compression by default. */\r
+       for (i = MAX_SLOTS - 1; i > 0; --i) {\r
+               tstate[i].cs_id = i;\r
+               tstate[i].cs_next = &tstate[i - 1];\r
+       }\r
+       tstate[0].cs_next = &tstate[MAX_SLOTS - 1];\r
+       tstate[0].cs_id = 0;\r
+       comp->last_cs = &tstate[0];\r
+       comp->last_recv = 255;\r
+       comp->last_xmit = 255;\r
+       comp->flags = VJF_TOSS;\r
+}\r
+\r
+\r
+/* ENCODE encodes a number that is known to be non-zero.  ENCODEZ\r
+ * checks for zero (since zero has to be encoded in the long, 3 byte\r
+ * form).\r
+ */\r
+#define ENCODE(n) { \\r
+       if ((u_short)(n) >= 256) { \\r
+               *cp++ = 0; \\r
+               cp[1] = (n); \\r
+               cp[0] = (n) >> 8; \\r
+               cp += 2; \\r
+       } else { \\r
+               *cp++ = (n); \\r
+       } \\r
+}\r
+#define ENCODEZ(n) { \\r
+       if ((u_short)(n) >= 256 || (u_short)(n) == 0) { \\r
+               *cp++ = 0; \\r
+               cp[1] = (n); \\r
+               cp[0] = (n) >> 8; \\r
+               cp += 2; \\r
+       } else { \\r
+               *cp++ = (n); \\r
+       } \\r
+}\r
+\r
+#define DECODEL(f) { \\r
+       if (*cp == 0) {\\r
+               u32_t tmp = ntohl(f) + ((cp[1] << 8) | cp[2]); \\r
+               (f) = htonl(tmp); \\r
+               cp += 3; \\r
+       } else { \\r
+               u32_t tmp = ntohl(f) + (u32_t)*cp++; \\r
+               (f) = htonl(tmp); \\r
+       } \\r
+}\r
+\r
+#define DECODES(f) { \\r
+       if (*cp == 0) {\\r
+               u_short tmp = ntohs(f) + (((u_short)cp[1] << 8) | cp[2]); \\r
+               (f) = htons(tmp); \\r
+               cp += 3; \\r
+       } else { \\r
+               u_short tmp = ntohs(f) + (u_short)*cp++; \\r
+               (f) = htons(tmp); \\r
+       } \\r
+}\r
+\r
+#define DECODEU(f) { \\r
+       if (*cp == 0) {\\r
+               (f) = htons(((u_short)cp[1] << 8) | cp[2]); \\r
+               cp += 3; \\r
+       } else { \\r
+               (f) = htons((u_short)*cp++); \\r
+       } \\r
+}\r
+\r
+/*\r
+ * vj_compress_tcp - Attempt to do Van Jacobsen header compression on a\r
+ * packet.  This assumes that nb and comp are not null and that the first\r
+ * buffer of the chain contains a valid IP header.\r
+ * Return the VJ type code indicating whether or not the packet was\r
+ * compressed.\r
+ */\r
+u_int vj_compress_tcp(\r
+       struct vjcompress *comp,\r
+       struct pbuf *pb\r
+)\r
+{\r
+       register struct ip *ip = (struct ip *)pb->payload;\r
+       register struct cstate *cs = comp->last_cs->cs_next;\r
+       register u_short hlen = getip_hl(*ip);\r
+       register struct tcphdr *oth;\r
+       register struct tcphdr *th;\r
+       register u_short deltaS, deltaA;\r
+       register u_long deltaL;\r
+       register u_int changes = 0;\r
+       u_char new_seq[16];\r
+       register u_char *cp = new_seq;\r
+\r
+       /*      \r
+        * Check that the packet is IP proto TCP.\r
+        */\r
+       if (ip->ip_p != IPPROTO_TCP)\r
+               return (TYPE_IP);\r
+               \r
+       /*\r
+        * Bail if this is an IP fragment or if the TCP packet isn't\r
+        * `compressible' (i.e., ACK isn't set or some other control bit is\r
+        * set).  \r
+        */\r
+       if ((ip->ip_off & htons(0x3fff)) || pb->tot_len < 40)\r
+               return (TYPE_IP);\r
+       th = (struct tcphdr *)&((long *)ip)[hlen];\r
+       if ((th->th_flags & (TCP_SYN|TCP_FIN|TCP_RST|TCP_ACK)) != TCP_ACK)\r
+               return (TYPE_IP);\r
+               \r
+       /*\r
+        * Packet is compressible -- we're going to send either a\r
+        * COMPRESSED_TCP or UNCOMPRESSED_TCP packet.  Either way we need\r
+        * to locate (or create) the connection state.  Special case the\r
+        * most recently used connection since it's most likely to be used\r
+        * again & we don't have to do any reordering if it's used.\r
+        */\r
+       INCR(vjs_packets);\r
+       if (ip->ip_src.s_addr != cs->cs_ip.ip_src.s_addr \r
+                       || ip->ip_dst.s_addr != cs->cs_ip.ip_dst.s_addr \r
+                       || *(long *)th != ((long *)&cs->cs_ip)[getip_hl(cs->cs_ip)]) {\r
+               /*\r
+                * Wasn't the first -- search for it.\r
+                *\r
+                * States are kept in a circularly linked list with\r
+                * last_cs pointing to the end of the list.  The\r
+                * list is kept in lru order by moving a state to the\r
+                * head of the list whenever it is referenced.  Since\r
+                * the list is short and, empirically, the connection\r
+                * we want is almost always near the front, we locate\r
+                * states via linear search.  If we don't find a state\r
+                * for the datagram, the oldest state is (re-)used.\r
+                */\r
+               register struct cstate *lcs;\r
+               register struct cstate *lastcs = comp->last_cs;\r
+               \r
+               do {\r
+                       lcs = cs; cs = cs->cs_next;\r
+                       INCR(vjs_searches);\r
+                       if (ip->ip_src.s_addr == cs->cs_ip.ip_src.s_addr\r
+                                       && ip->ip_dst.s_addr == cs->cs_ip.ip_dst.s_addr\r
+                                       && *(long *)th == ((long *)&cs->cs_ip)[getip_hl(cs->cs_ip)])\r
+                               goto found;\r
+               } while (cs != lastcs);\r
+               \r
+               /*\r
+                * Didn't find it -- re-use oldest cstate.  Send an\r
+                * uncompressed packet that tells the other side what\r
+                * connection number we're using for this conversation.\r
+                * Note that since the state list is circular, the oldest\r
+                * state points to the newest and we only need to set\r
+                * last_cs to update the lru linkage.\r
+                */\r
+               INCR(vjs_misses);\r
+               comp->last_cs = lcs;\r
+               hlen += getth_off(*th);\r
+               hlen <<= 2;\r
+               /* Check that the IP/TCP headers are contained in the first buffer. */\r
+               if (hlen > pb->len)\r
+                       return (TYPE_IP);\r
+               goto uncompressed;\r
+               \r
+               found:\r
+               /*\r
+                * Found it -- move to the front on the connection list.\r
+                */\r
+               if (cs == lastcs)\r
+                       comp->last_cs = lcs;\r
+               else {\r
+                       lcs->cs_next = cs->cs_next;\r
+                       cs->cs_next = lastcs->cs_next;\r
+                       lastcs->cs_next = cs;\r
+               }\r
+       }\r
+       \r
+       oth = (struct tcphdr *)&((long *)&cs->cs_ip)[hlen];\r
+       deltaS = hlen;\r
+       hlen += getth_off(*th);\r
+       hlen <<= 2;\r
+       /* Check that the IP/TCP headers are contained in the first buffer. */\r
+       if (hlen > pb->len) {\r
+               PPPDEBUG((LOG_INFO, "vj_compress_tcp: header len %d spans buffers\n", \r
+                                       hlen));\r
+               return (TYPE_IP);\r
+       }\r
+       \r
+       /*\r
+        * Make sure that only what we expect to change changed. The first\r
+        * line of the `if' checks the IP protocol version, header length &\r
+        * type of service.  The 2nd line checks the "Don't fragment" bit.\r
+        * The 3rd line checks the time-to-live and protocol (the protocol\r
+        * check is unnecessary but costless).  The 4th line checks the TCP\r
+        * header length.  The 5th line checks IP options, if any.  The 6th\r
+        * line checks TCP options, if any.  If any of these things are\r
+        * different between the previous & current datagram, we send the\r
+        * current datagram `uncompressed'.\r
+        */\r
+       if (((u_short *)ip)[0] != ((u_short *)&cs->cs_ip)[0] \r
+                       || ((u_short *)ip)[3] != ((u_short *)&cs->cs_ip)[3] \r
+                       || ((u_short *)ip)[4] != ((u_short *)&cs->cs_ip)[4] \r
+                       || getth_off(*th) != getth_off(*oth) \r
+                       || (deltaS > 5 && BCMP(ip + 1, &cs->cs_ip + 1, (deltaS - 5) << 2)) \r
+                       || (getth_off(*th) > 5 && BCMP(th + 1, oth + 1, (getth_off(*th) - 5) << 2)))\r
+               goto uncompressed;\r
+       \r
+       /*\r
+        * Figure out which of the changing fields changed.  The\r
+        * receiver expects changes in the order: urgent, window,\r
+        * ack, seq (the order minimizes the number of temporaries\r
+        * needed in this section of code).\r
+        */\r
+       if (th->th_flags & TCP_URG) {\r
+               deltaS = ntohs(th->th_urp);\r
+               ENCODEZ(deltaS);\r
+               changes |= NEW_U;\r
+       } else if (th->th_urp != oth->th_urp)\r
+               /* argh! URG not set but urp changed -- a sensible\r
+                * implementation should never do this but RFC793\r
+                * doesn't prohibit the change so we have to deal\r
+                * with it. */\r
+               goto uncompressed;\r
+       \r
+       if ((deltaS = (u_short)(ntohs(th->th_win) - ntohs(oth->th_win))) != 0) {\r
+               ENCODE(deltaS);\r
+               changes |= NEW_W;\r
+       }\r
+       \r
+       if ((deltaL = ntohl(th->th_ack) - ntohl(oth->th_ack)) != 0) {\r
+               if (deltaL > 0xffff)\r
+                       goto uncompressed;\r
+               deltaA = (u_short)deltaL;\r
+               ENCODE(deltaA);\r
+               changes |= NEW_A;\r
+       }\r
+       \r
+       if ((deltaL = ntohl(th->th_seq) - ntohl(oth->th_seq)) != 0) {\r
+               if (deltaL > 0xffff)\r
+                       goto uncompressed;\r
+               deltaS = (u_short)deltaL;\r
+               ENCODE(deltaS);\r
+               changes |= NEW_S;\r
+       }\r
+       \r
+       switch(changes) {\r
+       \r
+       case 0:\r
+               /*\r
+                * Nothing changed. If this packet contains data and the\r
+                * last one didn't, this is probably a data packet following\r
+                * an ack (normal on an interactive connection) and we send\r
+                * it compressed.  Otherwise it's probably a retransmit,\r
+                * retransmitted ack or window probe.  Send it uncompressed\r
+                * in case the other side missed the compressed version.\r
+                */\r
+               if (ip->ip_len != cs->cs_ip.ip_len &&\r
+                       ntohs(cs->cs_ip.ip_len) == hlen)\r
+               break;\r
+       \r
+       /* (fall through) */\r
+       \r
+       case SPECIAL_I:\r
+       case SPECIAL_D:\r
+               /*\r
+                * actual changes match one of our special case encodings --\r
+                * send packet uncompressed.\r
+                */\r
+               goto uncompressed;\r
+       \r
+       case NEW_S|NEW_A:\r
+               if (deltaS == deltaA && deltaS == ntohs(cs->cs_ip.ip_len) - hlen) {\r
+                       /* special case for echoed terminal traffic */\r
+                       changes = SPECIAL_I;\r
+                       cp = new_seq;\r
+               }\r
+               break;\r
+       \r
+       case NEW_S:\r
+               if (deltaS == ntohs(cs->cs_ip.ip_len) - hlen) {\r
+                       /* special case for data xfer */\r
+                       changes = SPECIAL_D;\r
+                       cp = new_seq;\r
+               }\r
+               break;\r
+       }\r
+       \r
+       deltaS = (u_short)(ntohs(ip->ip_id) - ntohs(cs->cs_ip.ip_id));\r
+       if (deltaS != 1) {\r
+               ENCODEZ(deltaS);\r
+               changes |= NEW_I;\r
+       }\r
+       if (th->th_flags & TCP_PSH)\r
+       changes |= TCP_PUSH_BIT;\r
+       /*\r
+        * Grab the cksum before we overwrite it below.  Then update our\r
+        * state with this packet's header.\r
+        */\r
+       deltaA = ntohs(th->th_sum);\r
+       BCOPY(ip, &cs->cs_ip, hlen);\r
+       \r
+       /*\r
+        * We want to use the original packet as our compressed packet.\r
+        * (cp - new_seq) is the number of bytes we need for compressed\r
+        * sequence numbers.  In addition we need one byte for the change\r
+        * mask, one for the connection id and two for the tcp checksum.\r
+        * So, (cp - new_seq) + 4 bytes of header are needed.  hlen is how\r
+        * many bytes of the original packet to toss so subtract the two to\r
+        * get the new packet size.\r
+        */\r
+       deltaS = (u_short)(cp - new_seq);\r
+       if (!comp->compressSlot || comp->last_xmit != cs->cs_id) {\r
+               comp->last_xmit = cs->cs_id;\r
+               hlen -= deltaS + 4;\r
+               pbuf_header(pb, -hlen);\r
+               cp = (u_char *)pb->payload;\r
+               *cp++ = changes | NEW_C;\r
+               *cp++ = cs->cs_id;\r
+       } else {\r
+               hlen -= deltaS + 3;\r
+               pbuf_header(pb, -hlen);\r
+               cp = (u_char *)pb->payload;\r
+               *cp++ = changes;\r
+       }\r
+       *cp++ = deltaA >> 8;\r
+       *cp++ = deltaA;\r
+       BCOPY(new_seq, cp, deltaS);\r
+       INCR(vjs_compressed);\r
+       return (TYPE_COMPRESSED_TCP);\r
+\r
+       /*\r
+        * Update connection state cs & send uncompressed packet (that is,\r
+        * a regular ip/tcp packet but with the 'conversation id' we hope\r
+        * to use on future compressed packets in the protocol field).\r
+        */\r
+uncompressed:\r
+       BCOPY(ip, &cs->cs_ip, hlen);\r
+       ip->ip_p = cs->cs_id;\r
+       comp->last_xmit = cs->cs_id;\r
+       return (TYPE_UNCOMPRESSED_TCP);\r
+}\r
+\r
+/*\r
+ * Called when we may have missed a packet.\r
+ */\r
+void vj_uncompress_err(struct vjcompress *comp)\r
+{\r
+    comp->flags |= VJF_TOSS;\r
+       INCR(vjs_errorin);\r
+}\r
+\r
+/*\r
+ * "Uncompress" a packet of type TYPE_UNCOMPRESSED_TCP.\r
+ * Return 0 on success, -1 on failure.\r
+ */\r
+int vj_uncompress_uncomp(\r
+       struct pbuf *nb,\r
+       struct vjcompress *comp\r
+)\r
+{\r
+       register u_int hlen;\r
+       register struct cstate *cs;\r
+       register struct ip *ip;\r
+       \r
+       ip = (struct ip *)nb->payload;\r
+       hlen = getip_hl(*ip) << 2;\r
+       if (ip->ip_p >= MAX_SLOTS\r
+                       || hlen + sizeof(struct tcphdr) > nb->len\r
+                       || (hlen += getth_off(*((struct tcphdr *)&((char *)ip)[hlen])) << 2)\r
+                           > nb->len\r
+                       || hlen > MAX_HDR) {\r
+               PPPDEBUG((LOG_INFO, "vj_uncompress_uncomp: bad cid=%d, hlen=%d buflen=%d\n", \r
+                                       ip->ip_p, hlen, nb->len));\r
+               comp->flags |= VJF_TOSS;\r
+               INCR(vjs_errorin);\r
+               return -1;\r
+       }\r
+       cs = &comp->rstate[comp->last_recv = ip->ip_p];\r
+       comp->flags &=~ VJF_TOSS;\r
+       ip->ip_p = IPPROTO_TCP;\r
+       BCOPY(ip, &cs->cs_ip, hlen);\r
+       cs->cs_hlen = hlen;\r
+       INCR(vjs_uncompressedin);\r
+       return 0;\r
+}\r
+\r
+/*\r
+ * Uncompress a packet of type TYPE_COMPRESSED_TCP.\r
+ * The packet is composed of a buffer chain and the first buffer\r
+ * must contain an accurate chain length.\r
+ * The first buffer must include the entire compressed TCP/IP header. \r
+ * This procedure replaces the compressed header with the uncompressed\r
+ * header and returns the length of the VJ header.\r
+ */\r
+int vj_uncompress_tcp(\r
+       struct pbuf **nb,\r
+       struct vjcompress *comp\r
+)\r
+{\r
+       u_char *cp;\r
+       struct tcphdr *th;\r
+       struct cstate *cs;\r
+       u_short *bp;\r
+       struct pbuf *n0 = *nb;\r
+       u32_t tmp;\r
+       u_int vjlen, hlen, changes;\r
+       \r
+       INCR(vjs_compressedin);\r
+       cp = (u_char *)n0->payload;\r
+       changes = *cp++;\r
+       if (changes & NEW_C) {\r
+               /* \r
+                * Make sure the state index is in range, then grab the state.\r
+                * If we have a good state index, clear the 'discard' flag. \r
+                */\r
+               if (*cp >= MAX_SLOTS) {\r
+                       PPPDEBUG((LOG_INFO, "vj_uncompress_tcp: bad cid=%d\n", *cp));\r
+                       goto bad;\r
+               }\r
+               \r
+               comp->flags &=~ VJF_TOSS;\r
+               comp->last_recv = *cp++;\r
+       } else {\r
+               /* \r
+                * this packet has an implicit state index.  If we've\r
+                * had a line error since the last time we got an\r
+                * explicit state index, we have to toss the packet. \r
+                */\r
+               if (comp->flags & VJF_TOSS) {\r
+                       PPPDEBUG((LOG_INFO, "vj_uncompress_tcp: tossing\n"));\r
+                       INCR(vjs_tossed);\r
+                       return (-1);\r
+               }\r
+       }\r
+       cs = &comp->rstate[comp->last_recv];\r
+       hlen = getip_hl(cs->cs_ip) << 2;\r
+       th = (struct tcphdr *)&((u_char *)&cs->cs_ip)[hlen];\r
+       th->th_sum = htons((*cp << 8) | cp[1]);\r
+       cp += 2;\r
+       if (changes & TCP_PUSH_BIT)\r
+               th->th_flags |= TCP_PSH;\r
+       else\r
+               th->th_flags &=~ TCP_PSH;\r
+       \r
+       switch (changes & SPECIALS_MASK) {\r
+       case SPECIAL_I:\r
+               {\r
+                       register u32_t i = ntohs(cs->cs_ip.ip_len) - cs->cs_hlen;\r
+                       /* some compilers can't nest inline assembler.. */\r
+                       tmp = ntohl(th->th_ack) + i;\r
+                       th->th_ack = htonl(tmp);\r
+                       tmp = ntohl(th->th_seq) + i;\r
+                       th->th_seq = htonl(tmp);\r
+               }\r
+               break;\r
+       \r
+       case SPECIAL_D:\r
+               /* some compilers can't nest inline assembler.. */\r
+               tmp = ntohl(th->th_seq) + ntohs(cs->cs_ip.ip_len) - cs->cs_hlen;\r
+               th->th_seq = htonl(tmp);\r
+               break;\r
+       \r
+       default:\r
+               if (changes & NEW_U) {\r
+                       th->th_flags |= TCP_URG;\r
+                       DECODEU(th->th_urp);\r
+               } else\r
+                       th->th_flags &=~ TCP_URG;\r
+               if (changes & NEW_W)\r
+                       DECODES(th->th_win);\r
+               if (changes & NEW_A)\r
+                       DECODEL(th->th_ack);\r
+               if (changes & NEW_S)\r
+                       DECODEL(th->th_seq);\r
+               break;\r
+       }\r
+       if (changes & NEW_I) {\r
+               DECODES(cs->cs_ip.ip_id);\r
+       } else {\r
+               cs->cs_ip.ip_id = ntohs(cs->cs_ip.ip_id) + 1;\r
+               cs->cs_ip.ip_id = htons(cs->cs_ip.ip_id);\r
+       }\r
+       \r
+       /*\r
+        * At this point, cp points to the first byte of data in the\r
+        * packet.  Fill in the IP total length and update the IP\r
+        * header checksum.\r
+        */\r
+       vjlen = (u_short)(cp - (u_char*)n0->payload);\r
+       if (n0->len < vjlen) {\r
+               /* \r
+                * We must have dropped some characters (crc should detect\r
+                * this but the old slip framing won't) \r
+                */\r
+               PPPDEBUG((LOG_INFO, "vj_uncompress_tcp: head buffer %d too short %d\n", \r
+                                 n0->len, vjlen));\r
+               goto bad;\r
+       }\r
+       \r
+#if BYTE_ORDER == LITTLE_ENDIAN\r
+       tmp = n0->tot_len - vjlen + cs->cs_hlen;\r
+       cs->cs_ip.ip_len = htons(tmp);\r
+#else\r
+       cs->cs_ip.ip_len = htons(n0->tot_len - vjlen + cs->cs_hlen);\r
+#endif\r
+       \r
+       /* recompute the ip header checksum */\r
+       bp = (u_short *) &cs->cs_ip;\r
+       cs->cs_ip.ip_sum = 0;\r
+       for (tmp = 0; hlen > 0; hlen -= 2)\r
+               tmp += *bp++;\r
+       tmp = (tmp & 0xffff) + (tmp >> 16);\r
+       tmp = (tmp & 0xffff) + (tmp >> 16);\r
+       cs->cs_ip.ip_sum = (u_short)(~tmp);\r
+       \r
+       /* Remove the compressed header and prepend the uncompressed header. */\r
+       pbuf_header(n0, -vjlen);\r
+\r
+       if(MEM_ALIGN(n0->payload) != n0->payload) {\r
+               struct pbuf *np, *q;\r
+               u8_t *bufptr;\r
+\r
+               np = pbuf_alloc(PBUF_RAW, n0->len + cs->cs_hlen, PBUF_POOL);\r
+               if(!np) {\r
+                       PPPDEBUG((LOG_WARNING, "vj_uncompress_tcp: realign failed\n"));\r
+                       *nb = NULL;\r
+                       goto bad;\r
+               }\r
+\r
+               pbuf_header(np, -cs->cs_hlen);\r
+\r
+               bufptr = n0->payload;\r
+               for(q = np; q != NULL; q = q->next) {\r
+                       memcpy(q->payload, bufptr, q->len);\r
+                       bufptr += q->len;\r
+               }\r
+\r
+               if(n0->next) {\r
+                       pbuf_chain(np, n0->next);\r
+                       pbuf_dechain(n0);\r
+               }\r
+               pbuf_free(n0);\r
+               n0 = np;\r
+       }\r
+\r
+       if(pbuf_header(n0, cs->cs_hlen)) {\r
+               struct pbuf *np;\r
+\r
+               LWIP_ASSERT("vj_uncompress_tcp: cs->cs_hlen <= PBUF_POOL_BUFSIZE", cs->cs_hlen <= PBUF_POOL_BUFSIZE);\r
+               np = pbuf_alloc(PBUF_RAW, cs->cs_hlen, PBUF_POOL);\r
+               if(!np) {\r
+                       PPPDEBUG((LOG_WARNING, "vj_uncompress_tcp: prepend failed\n"));\r
+                       *nb = NULL;\r
+                       goto bad;\r
+               }\r
+               pbuf_cat(np, n0);\r
+               n0 = np;\r
+       }\r
+       LWIP_ASSERT("n0->len >= cs->cs_hlen", n0->len >= cs->cs_hlen);\r
+       memcpy(n0->payload, &cs->cs_ip, cs->cs_hlen);\r
+\r
+       *nb = n0;\r
+\r
+       return vjlen;\r
+       \r
+bad:\r
+       comp->flags |= VJF_TOSS;\r
+       INCR(vjs_errorin);\r
+       return (-1);\r
+}\r
+\r
+#endif\r
+\r
+\r
index 717208145731c10c507c906ebdc86f6b756ef86a..9da27148114bb7f5324497fc7118c1cf3b32fa14 100644 (file)
-/*
- * Definitions for tcp compression routines.
- *
- * $Id: vj.h,v 1.4 2004/02/07 00:30:03 likewise Exp $
- *
- * Copyright (c) 1989 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley.  The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- *     Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989:
- *     - Initial distribution.
- */
-
-#ifndef VJ_H
-#define VJ_H
-
-#include "vjbsdhdr.h"
-
-#define MAX_SLOTS      16                      /* must be > 2 and < 256 */
-#define MAX_HDR                128
-
-/*
- * Compressed packet format:
- *
- * The first octet contains the packet type (top 3 bits), TCP
- * 'push' bit, and flags that indicate which of the 4 TCP sequence
- * numbers have changed (bottom 5 bits).  The next octet is a
- * conversation number that associates a saved IP/TCP header with
- * the compressed packet.  The next two octets are the TCP checksum
- * from the original datagram.  The next 0 to 15 octets are
- * sequence number changes, one change per bit set in the header
- * (there may be no changes and there are two special cases where
- * the receiver implicitly knows what changed -- see below).
- * 
- * There are 5 numbers which can change (they are always inserted
- * in the following order): TCP urgent pointer, window,
- * acknowlegement, sequence number and IP ID.  (The urgent pointer
- * is different from the others in that its value is sent, not the
- * change in value.)  Since typical use of SLIP links is biased
- * toward small packets (see comments on MTU/MSS below), changes
- * use a variable length coding with one octet for numbers in the
- * range 1 - 255 and 3 octets (0, MSB, LSB) for numbers in the
- * range 256 - 65535 or 0.  (If the change in sequence number or
- * ack is more than 65535, an uncompressed packet is sent.)
- */
-
-/*
- * Packet types (must not conflict with IP protocol version)
- *
- * The top nibble of the first octet is the packet type.  There are
- * three possible types: IP (not proto TCP or tcp with one of the
- * control flags set); uncompressed TCP (a normal IP/TCP packet but
- * with the 8-bit protocol field replaced by an 8-bit connection id --
- * this type of packet syncs the sender & receiver); and compressed
- * TCP (described above).
- *
- * LSB of 4-bit field is TCP "PUSH" bit (a worthless anachronism) and
- * is logically part of the 4-bit "changes" field that follows.  Top
- * three bits are actual packet type.  For backward compatibility
- * and in the interest of conserving bits, numbers are chosen so the
- * IP protocol version number (4) which normally appears in this nibble
- * means "IP packet".
- */
-
-/* packet types */
-#define TYPE_IP 0x40
-#define TYPE_UNCOMPRESSED_TCP 0x70
-#define TYPE_COMPRESSED_TCP 0x80
-#define TYPE_ERROR 0x00
-
-/* Bits in first octet of compressed packet */
-#define NEW_C  0x40    /* flag bits for what changed in a packet */
-#define NEW_I  0x20
-#define NEW_S  0x08
-#define NEW_A  0x04
-#define NEW_W  0x02
-#define NEW_U  0x01
-
-/* reserved, special-case values of above */
-#define SPECIAL_I (NEW_S|NEW_W|NEW_U)          /* echoed interactive traffic */
-#define SPECIAL_D (NEW_S|NEW_A|NEW_W|NEW_U)    /* unidirectional data */
-#define SPECIALS_MASK (NEW_S|NEW_A|NEW_W|NEW_U)
-
-#define TCP_PUSH_BIT 0x10
-
-
-/*
- * "state" data for each active tcp conversation on the wire.  This is
- * basically a copy of the entire IP/TCP header from the last packet
- * we saw from the conversation together with a small identifier
- * the transmit & receive ends of the line use to locate saved header.
- */
-struct cstate {
-    struct cstate *cs_next;    /* next most recently used state (xmit only) */
-    u_short cs_hlen;           /* size of hdr (receive only) */
-    u_char cs_id;                      /* connection # associated with this state */
-    u_char cs_filler;
-    union {
-               char csu_hdr[MAX_HDR];
-               struct ip csu_ip;       /* ip/tcp hdr from most recent packet */
-    } vjcs_u;
-};
-#define cs_ip vjcs_u.csu_ip
-#define cs_hdr vjcs_u.csu_hdr
-
-
-struct vjstat {
-    unsigned long vjs_packets;                 /* outbound packets */
-    unsigned long vjs_compressed;              /* outbound compressed packets */
-    unsigned long vjs_searches;                        /* searches for connection state */
-    unsigned long vjs_misses;                  /* times couldn't find conn. state */
-    unsigned long vjs_uncompressedin;  /* inbound uncompressed packets */
-    unsigned long vjs_compressedin;            /* inbound compressed packets */
-    unsigned long vjs_errorin;                 /* inbound unknown type packets */
-    unsigned long vjs_tossed;                  /* inbound packets tossed because of error */
-};
-
-/*
- * all the state data for one serial line (we need one of these per line).
- */
-struct vjcompress {
-    struct cstate *last_cs;    /* most recently used tstate */
-    u_char last_recv;          /* last rcvd conn. id */
-    u_char last_xmit;          /* last sent conn. id */
-    u_short flags;
-    u_char maxSlotIndex;
-    u_char compressSlot;       /* Flag indicating OK to compress slot ID. */
-#if LINK_STATS
-    struct vjstat stats;
-#endif
-    struct cstate tstate[MAX_SLOTS];   /* xmit connection states */
-    struct cstate rstate[MAX_SLOTS];   /* receive connection states */
-};
-
-/* flag values */
-#define VJF_TOSS 1U            /* tossing rcvd frames because of input err */
-
-extern void  vj_compress_init (struct vjcompress *comp);
-extern u_int vj_compress_tcp (struct vjcompress *comp, struct pbuf *pb);
-extern void  vj_uncompress_err (struct vjcompress *comp);
-extern int vj_uncompress_uncomp(struct pbuf *nb, struct vjcompress *comp);
-extern int vj_uncompress_tcp(struct pbuf **nb, struct vjcompress *comp);
-
-#endif /* VJ_H */
+/*\r
+ * Definitions for tcp compression routines.\r
+ *\r
+ * $Id: vj.h,v 1.4 2004/02/07 00:30:03 likewise Exp $\r
+ *\r
+ * Copyright (c) 1989 Regents of the University of California.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms are permitted\r
+ * provided that the above copyright notice and this paragraph are\r
+ * duplicated in all such forms and that any documentation,\r
+ * advertising materials, and other materials related to such\r
+ * distribution and use acknowledge that the software was developed\r
+ * by the University of California, Berkeley.  The name of the\r
+ * University may not be used to endorse or promote products derived\r
+ * from this software without specific prior written permission.\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR\r
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r
+ *\r
+ *     Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989:\r
+ *     - Initial distribution.\r
+ */\r
+\r
+#ifndef VJ_H\r
+#define VJ_H\r
+\r
+#include "vjbsdhdr.h"\r
+\r
+#define MAX_SLOTS      16                      /* must be > 2 and < 256 */\r
+#define MAX_HDR                128\r
+\r
+/*\r
+ * Compressed packet format:\r
+ *\r
+ * The first octet contains the packet type (top 3 bits), TCP\r
+ * 'push' bit, and flags that indicate which of the 4 TCP sequence\r
+ * numbers have changed (bottom 5 bits).  The next octet is a\r
+ * conversation number that associates a saved IP/TCP header with\r
+ * the compressed packet.  The next two octets are the TCP checksum\r
+ * from the original datagram.  The next 0 to 15 octets are\r
+ * sequence number changes, one change per bit set in the header\r
+ * (there may be no changes and there are two special cases where\r
+ * the receiver implicitly knows what changed -- see below).\r
+ * \r
+ * There are 5 numbers which can change (they are always inserted\r
+ * in the following order): TCP urgent pointer, window,\r
+ * acknowlegement, sequence number and IP ID.  (The urgent pointer\r
+ * is different from the others in that its value is sent, not the\r
+ * change in value.)  Since typical use of SLIP links is biased\r
+ * toward small packets (see comments on MTU/MSS below), changes\r
+ * use a variable length coding with one octet for numbers in the\r
+ * range 1 - 255 and 3 octets (0, MSB, LSB) for numbers in the\r
+ * range 256 - 65535 or 0.  (If the change in sequence number or\r
+ * ack is more than 65535, an uncompressed packet is sent.)\r
+ */\r
+\r
+/*\r
+ * Packet types (must not conflict with IP protocol version)\r
+ *\r
+ * The top nibble of the first octet is the packet type.  There are\r
+ * three possible types: IP (not proto TCP or tcp with one of the\r
+ * control flags set); uncompressed TCP (a normal IP/TCP packet but\r
+ * with the 8-bit protocol field replaced by an 8-bit connection id --\r
+ * this type of packet syncs the sender & receiver); and compressed\r
+ * TCP (described above).\r
+ *\r
+ * LSB of 4-bit field is TCP "PUSH" bit (a worthless anachronism) and\r
+ * is logically part of the 4-bit "changes" field that follows.  Top\r
+ * three bits are actual packet type.  For backward compatibility\r
+ * and in the interest of conserving bits, numbers are chosen so the\r
+ * IP protocol version number (4) which normally appears in this nibble\r
+ * means "IP packet".\r
+ */\r
+\r
+/* packet types */\r
+#define TYPE_IP 0x40\r
+#define TYPE_UNCOMPRESSED_TCP 0x70\r
+#define TYPE_COMPRESSED_TCP 0x80\r
+#define TYPE_ERROR 0x00\r
+\r
+/* Bits in first octet of compressed packet */\r
+#define NEW_C  0x40    /* flag bits for what changed in a packet */\r
+#define NEW_I  0x20\r
+#define NEW_S  0x08\r
+#define NEW_A  0x04\r
+#define NEW_W  0x02\r
+#define NEW_U  0x01\r
+\r
+/* reserved, special-case values of above */\r
+#define SPECIAL_I (NEW_S|NEW_W|NEW_U)          /* echoed interactive traffic */\r
+#define SPECIAL_D (NEW_S|NEW_A|NEW_W|NEW_U)    /* unidirectional data */\r
+#define SPECIALS_MASK (NEW_S|NEW_A|NEW_W|NEW_U)\r
+\r
+#define TCP_PUSH_BIT 0x10\r
+\r
+\r
+/*\r
+ * "state" data for each active tcp conversation on the wire.  This is\r
+ * basically a copy of the entire IP/TCP header from the last packet\r
+ * we saw from the conversation together with a small identifier\r
+ * the transmit & receive ends of the line use to locate saved header.\r
+ */\r
+struct cstate {\r
+    struct cstate *cs_next;    /* next most recently used state (xmit only) */\r
+    u_short cs_hlen;           /* size of hdr (receive only) */\r
+    u_char cs_id;                      /* connection # associated with this state */\r
+    u_char cs_filler;\r
+    union {\r
+               char csu_hdr[MAX_HDR];\r
+               struct ip csu_ip;       /* ip/tcp hdr from most recent packet */\r
+    } vjcs_u;\r
+};\r
+#define cs_ip vjcs_u.csu_ip\r
+#define cs_hdr vjcs_u.csu_hdr\r
+\r
+\r
+struct vjstat {\r
+    unsigned long vjs_packets;                 /* outbound packets */\r
+    unsigned long vjs_compressed;              /* outbound compressed packets */\r
+    unsigned long vjs_searches;                        /* searches for connection state */\r
+    unsigned long vjs_misses;                  /* times couldn't find conn. state */\r
+    unsigned long vjs_uncompressedin;  /* inbound uncompressed packets */\r
+    unsigned long vjs_compressedin;            /* inbound compressed packets */\r
+    unsigned long vjs_errorin;                 /* inbound unknown type packets */\r
+    unsigned long vjs_tossed;                  /* inbound packets tossed because of error */\r
+};\r
+\r
+/*\r
+ * all the state data for one serial line (we need one of these per line).\r
+ */\r
+struct vjcompress {\r
+    struct cstate *last_cs;    /* most recently used tstate */\r
+    u_char last_recv;          /* last rcvd conn. id */\r
+    u_char last_xmit;          /* last sent conn. id */\r
+    u_short flags;\r
+    u_char maxSlotIndex;\r
+    u_char compressSlot;       /* Flag indicating OK to compress slot ID. */\r
+#if LINK_STATS\r
+    struct vjstat stats;\r
+#endif\r
+    struct cstate tstate[MAX_SLOTS];   /* xmit connection states */\r
+    struct cstate rstate[MAX_SLOTS];   /* receive connection states */\r
+};\r
+\r
+/* flag values */\r
+#define VJF_TOSS 1U            /* tossing rcvd frames because of input err */\r
+\r
+extern void  vj_compress_init (struct vjcompress *comp);\r
+extern u_int vj_compress_tcp (struct vjcompress *comp, struct pbuf *pb);\r
+extern void  vj_uncompress_err (struct vjcompress *comp);\r
+extern int vj_uncompress_uncomp(struct pbuf *nb, struct vjcompress *comp);\r
+extern int vj_uncompress_tcp(struct pbuf **nb, struct vjcompress *comp);\r
+\r
+#endif /* VJ_H */\r
index a089352ade270e0f6b7d7f427696b7fd97193eb3..a7d180c16c80de16b992d13a8037ee210178557c 100644 (file)
@@ -1,76 +1,76 @@
-#ifndef VJBSDHDR_H
-#define VJBSDHDR_H
-
-#include "lwip/tcp.h"
-
-
-/*
- * Structure of an internet header, naked of options.
- *
- * We declare ip_len and ip_off to be short, rather than u_short
- * pragmatically since otherwise unsigned comparisons can result
- * against negative integers quite easily, and fail in subtle ways.
- */
-PACK_STRUCT_BEGIN
-struct ip
-{
-#if defined(NO_CHAR_BITFIELDS)
-       u_char ip_hl_v; /* bug in GCC for mips means the bitfield stuff will sometimes break - so we use a char for both and get round it with macro's instead... */
-#else
-#if BYTE_ORDER == LITTLE_ENDIAN
-       unsigned ip_hl:4,                               /* header length */
-               ip_v:4;                                         /* version */
-#elif BYTE_ORDER == BIG_ENDIAN 
-       unsigned ip_v:4,                                        /* version */
-               ip_hl:4;                                        /* header length */
-#else
-       COMPLAIN - NO BYTE ORDER SELECTED!
-#endif
-#endif
-       u_char  ip_tos;                                 /* type of service */
-       u_short ip_len;                                 /* total length */
-       u_short ip_id;                                  /* identification */
-       u_short ip_off;                                 /* fragment offset field */
-#define        IP_DF 0x4000                            /* dont fragment flag */
-#define        IP_MF 0x2000                            /* more fragments flag */
-#define        IP_OFFMASK 0x1fff                       /* mask for fragmenting bits */
-       u_char  ip_ttl;                                 /* time to live */
-       u_char  ip_p;                                   /* protocol */
-       u_short ip_sum;                                 /* checksum */
-       struct  in_addr ip_src,ip_dst;  /* source and dest address */
-};
-PACK_STRUCT_END
-
-typedef u32_t tcp_seq;
-
-/*
- * TCP header.
- * Per RFC 793, September, 1981.
- */
-PACK_STRUCT_BEGIN
-struct tcphdr  
-{
-       u_short th_sport;               /* source port */
-       u_short th_dport;               /* destination port */
-       tcp_seq th_seq;                 /* sequence number */
-       tcp_seq th_ack;                 /* acknowledgement number */
-#if defined(NO_CHAR_BITFIELDS)
-       u_char th_x2_off;
-#else
-#if BYTE_ORDER == LITTLE_ENDIAN
-       unsigned        th_x2:4,                /* (unused) */
-                       th_off:4;               /* data offset */
-#endif
-#if BYTE_ORDER == BIG_ENDIAN 
-       unsigned        th_off:4,               /* data offset */
-                       th_x2:4;                /* (unused) */
-#endif
-#endif
-       u_char  th_flags;
-       u_short th_win;                 /* window */
-       u_short th_sum;                 /* checksum */
-       u_short th_urp;                 /* urgent pointer */
-};
-PACK_STRUCT_END
-
-#endif /* VJBSDHDR_H */
+#ifndef VJBSDHDR_H\r
+#define VJBSDHDR_H\r
+\r
+#include "lwip/tcp.h"\r
+\r
+\r
+/*\r
+ * Structure of an internet header, naked of options.\r
+ *\r
+ * We declare ip_len and ip_off to be short, rather than u_short\r
+ * pragmatically since otherwise unsigned comparisons can result\r
+ * against negative integers quite easily, and fail in subtle ways.\r
+ */\r
+PACK_STRUCT_BEGIN\r
+struct ip\r
+{\r
+#if defined(NO_CHAR_BITFIELDS)\r
+       u_char ip_hl_v; /* bug in GCC for mips means the bitfield stuff will sometimes break - so we use a char for both and get round it with macro's instead... */\r
+#else\r
+#if BYTE_ORDER == LITTLE_ENDIAN\r
+       unsigned ip_hl:4,                               /* header length */\r
+               ip_v:4;                                         /* version */\r
+#elif BYTE_ORDER == BIG_ENDIAN \r
+       unsigned ip_v:4,                                        /* version */\r
+               ip_hl:4;                                        /* header length */\r
+#else\r
+       COMPLAIN - NO BYTE ORDER SELECTED!\r
+#endif\r
+#endif\r
+       u_char  ip_tos;                                 /* type of service */\r
+       u_short ip_len;                                 /* total length */\r
+       u_short ip_id;                                  /* identification */\r
+       u_short ip_off;                                 /* fragment offset field */\r
+#define        IP_DF 0x4000                            /* dont fragment flag */\r
+#define        IP_MF 0x2000                            /* more fragments flag */\r
+#define        IP_OFFMASK 0x1fff                       /* mask for fragmenting bits */\r
+       u_char  ip_ttl;                                 /* time to live */\r
+       u_char  ip_p;                                   /* protocol */\r
+       u_short ip_sum;                                 /* checksum */\r
+       struct  in_addr ip_src,ip_dst;  /* source and dest address */\r
+};\r
+PACK_STRUCT_END\r
+\r
+typedef u32_t tcp_seq;\r
+\r
+/*\r
+ * TCP header.\r
+ * Per RFC 793, September, 1981.\r
+ */\r
+PACK_STRUCT_BEGIN\r
+struct tcphdr  \r
+{\r
+       u_short th_sport;               /* source port */\r
+       u_short th_dport;               /* destination port */\r
+       tcp_seq th_seq;                 /* sequence number */\r
+       tcp_seq th_ack;                 /* acknowledgement number */\r
+#if defined(NO_CHAR_BITFIELDS)\r
+       u_char th_x2_off;\r
+#else\r
+#if BYTE_ORDER == LITTLE_ENDIAN\r
+       unsigned        th_x2:4,                /* (unused) */\r
+                       th_off:4;               /* data offset */\r
+#endif\r
+#if BYTE_ORDER == BIG_ENDIAN \r
+       unsigned        th_off:4,               /* data offset */\r
+                       th_x2:4;                /* (unused) */\r
+#endif\r
+#endif\r
+       u_char  th_flags;\r
+       u_short th_win;                 /* window */\r
+       u_short th_sum;                 /* checksum */\r
+       u_short th_urp;                 /* urgent pointer */\r
+};\r
+PACK_STRUCT_END\r
+\r
+#endif /* VJBSDHDR_H */\r
index 776c13f7a691de131aef155cd238f70f994cb16b..1dca4cadd7ae75a9e695acef8adb1ae96abe6ec2 100644 (file)
-/*
- * 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. Neither the name of the Institute nor the names of its contributors 
- *    may be used to endorse or promote products derived from this software 
- *    without specific prior written permission. 
- *
- * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE OR CONTRIBUTORS 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 built upon the file: src/arch/rtxc/netif/sioslip.c
- *
- * Author: Magnus Ivarsson <magnus.ivarsson(at)volvo.com> 
- */
-
-/* 
- * This is an arch independent SLIP netif. The specific serial hooks must be provided 
- * by another file.They are sio_open, sio_recv and sio_send
- */ 
-
-#include "netif/slipif.h"
-#include "lwip/opt.h"
-#include "lwip/def.h"
-#include "lwip/pbuf.h"
-#include "lwip/sys.h"
-#include "lwip/stats.h"
-#include "lwip/sio.h"
-
-#define SLIP_END     0300
-#define SLIP_ESC     0333
-#define SLIP_ESC_END 0334
-#define SLIP_ESC_ESC 0335
-
-#define MAX_SIZE     1500
-
-/**
- * Send a pbuf doing the necessary SLIP encapsulation
- *
- * Uses the serial layer's sio_send() 
- */ 
-err_t
-slipif_output(struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr)
-{
-  struct pbuf *q;
-  int i;
-  u8_t c;
-
-  /* Send pbuf out on the serial I/O device. */
-  sio_send(SLIP_END, netif->state);
-
-  for(q = p; q != NULL; q = q->next) {
-    for(i = 0; i < q->len; i++) {
-      c = ((u8_t *)q->payload)[i];
-      switch (c) {
-      case SLIP_END:
-  sio_send(SLIP_ESC, netif->state);
-  sio_send(SLIP_ESC_END, netif->state);
-  break;
-      case SLIP_ESC:
-  sio_send(SLIP_ESC, netif->state);
-  sio_send(SLIP_ESC_ESC, netif->state);
-  break;
-      default:
-  sio_send(c, netif->state);
-  break;
-      }
-    }
-  }
-  sio_send(SLIP_END, netif->state);
-  return 0;
-}
-
-/**
- * Handle the incoming SLIP stream character by character
- *
- * Poll the serial layer by calling sio_recv()
- * 
- * @return The IP packet when SLIP_END is received 
- */ 
-static struct pbuf *
-slipif_input( struct netif * netif )
-{
-  u8_t c;
-  struct pbuf *p, *q;
-  int recved;
-  int i;
-
-  q = p = NULL;
-  recved = i = 0;
-  c = 0;
-
-  while (1) {
-    c = sio_recv(netif->state);
-    switch (c) {
-    case SLIP_END:
-      if (recved > 0) {
-  /* Received whole packet. */
-  pbuf_realloc(q, recved);
-  
-  LINK_STATS_INC(link.recv);
-  
-  LWIP_DEBUGF(SLIP_DEBUG, ("slipif: Got packet\n"));
-  return q;
-      }
-      break;
-
-    case SLIP_ESC:
-      c = sio_recv(netif->state);
-      switch (c) {
-      case SLIP_ESC_END:
-  c = SLIP_END;
-  break;
-      case SLIP_ESC_ESC:
-  c = SLIP_ESC;
-  break;
-      }
-      /* FALLTHROUGH */
-      
-    default:
-      if (p == NULL) {
-  LWIP_DEBUGF(SLIP_DEBUG, ("slipif_input: alloc\n"));
-  p = pbuf_alloc(PBUF_LINK, PBUF_POOL_BUFSIZE, PBUF_POOL);
-
-  if (p == NULL) {
-    LINK_STATS_INC(link.drop);
-    LWIP_DEBUGF(SLIP_DEBUG, ("slipif_input: no new pbuf! (DROP)\n"));
-  }
-  
-  if (q != NULL) {
-    pbuf_cat(q, p);
-  } else {
-    q = p;
-  }
-      }
-      if (p != NULL && recved < MAX_SIZE) {
-  ((u8_t *)p->payload)[i] = c;
-  recved++;
-  i++;
-  if (i >= p->len) {
-    i = 0;
-    p = NULL;
-  }
-      }
-      break;
-    }
-    
-  }
-  return NULL;
-}
-
-/**
- * The SLIP input thread 
- *
- * Feed the IP layer with incoming packets
- */ 
-static void
-slipif_loop(void *nf)
-{
-  struct pbuf *p;
-  struct netif *netif = (struct netif *)nf;
-
-  while (1) {
-    p = slipif_input(netif);
-    netif->input(p, netif);
-  }
-}
-
-/**
- * SLIP netif initialization
- *
- * Call the arch specific sio_open and remember
- * the opened device in the state field of the netif.
- */ 
-err_t
-slipif_init(struct netif *netif)
-{
-  
-  LWIP_DEBUGF(SLIP_DEBUG, ("slipif_init: netif->num=%x\n", (int)netif->num));
-
-  netif->name[0] = 's';
-  netif->name[1] = 'l';
-  netif->output = slipif_output;
-  netif->mtu = 1500;  
-  netif->flags = NETIF_FLAG_POINTTOPOINT;
-
-  netif->state = sio_open(netif->num);
-  if (!netif->state)
-      return ERR_IF;
-
-  sys_thread_new(slipif_loop, netif, SLIPIF_THREAD_PRIO);
-  return ERR_OK;
-}
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ *\r
+ * Redistribution and use in source and binary forms, with or without \r
+ * modification, are permitted provided that the following conditions \r
+ * are met: \r
+ * 1. Redistributions of source code must retain the above copyright \r
+ *    notice, this list of conditions and the following disclaimer. \r
+ * 2. Redistributions in binary form must reproduce the above copyright \r
+ *    notice, this list of conditions and the following disclaimer in the \r
+ *    documentation and/or other materials provided with the distribution. \r
+ * 3. Neither the name of the Institute nor the names of its contributors \r
+ *    may be used to endorse or promote products derived from this software \r
+ *    without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND \r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE \r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE \r
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE \r
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL \r
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS \r
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) \r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT \r
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY \r
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF \r
+ * SUCH DAMAGE. \r
+ *\r
+ * This file is built upon the file: src/arch/rtxc/netif/sioslip.c\r
+ *\r
+ * Author: Magnus Ivarsson <magnus.ivarsson(at)volvo.com> \r
+ */\r
+\r
+/* \r
+ * This is an arch independent SLIP netif. The specific serial hooks must be provided \r
+ * by another file.They are sio_open, sio_recv and sio_send\r
+ */ \r
+\r
+#include "netif/slipif.h"\r
+#include "lwip/opt.h"\r
+#include "lwip/def.h"\r
+#include "lwip/pbuf.h"\r
+#include "lwip/sys.h"\r
+#include "lwip/stats.h"\r
+#include "lwip/sio.h"\r
+\r
+#define SLIP_END     0300\r
+#define SLIP_ESC     0333\r
+#define SLIP_ESC_END 0334\r
+#define SLIP_ESC_ESC 0335\r
+\r
+#define MAX_SIZE     1500\r
+\r
+/**\r
+ * Send a pbuf doing the necessary SLIP encapsulation\r
+ *\r
+ * Uses the serial layer's sio_send() \r
+ */ \r
+err_t\r
+slipif_output(struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr)\r
+{\r
+  struct pbuf *q;\r
+  int i;\r
+  u8_t c;\r
+\r
+  /* Send pbuf out on the serial I/O device. */\r
+  sio_send(SLIP_END, netif->state);\r
+\r
+  for(q = p; q != NULL; q = q->next) {\r
+    for(i = 0; i < q->len; i++) {\r
+      c = ((u8_t *)q->payload)[i];\r
+      switch (c) {\r
+      case SLIP_END:\r
+  sio_send(SLIP_ESC, netif->state);\r
+  sio_send(SLIP_ESC_END, netif->state);\r
+  break;\r
+      case SLIP_ESC:\r
+  sio_send(SLIP_ESC, netif->state);\r
+  sio_send(SLIP_ESC_ESC, netif->state);\r
+  break;\r
+      default:\r
+  sio_send(c, netif->state);\r
+  break;\r
+      }\r
+    }\r
+  }\r
+  sio_send(SLIP_END, netif->state);\r
+  return 0;\r
+}\r
+\r
+/**\r
+ * Handle the incoming SLIP stream character by character\r
+ *\r
+ * Poll the serial layer by calling sio_recv()\r
+ * \r
+ * @return The IP packet when SLIP_END is received \r
+ */ \r
+static struct pbuf *\r
+slipif_input( struct netif * netif )\r
+{\r
+  u8_t c;\r
+  struct pbuf *p, *q;\r
+  int recved;\r
+  int i;\r
+\r
+  q = p = NULL;\r
+  recved = i = 0;\r
+  c = 0;\r
+\r
+  while (1) {\r
+    c = sio_recv(netif->state);\r
+    switch (c) {\r
+    case SLIP_END:\r
+      if (recved > 0) {\r
+  /* Received whole packet. */\r
+  pbuf_realloc(q, recved);\r
+  \r
+  LINK_STATS_INC(link.recv);\r
+  \r
+  LWIP_DEBUGF(SLIP_DEBUG, ("slipif: Got packet\n"));\r
+  return q;\r
+      }\r
+      break;\r
+\r
+    case SLIP_ESC:\r
+      c = sio_recv(netif->state);\r
+      switch (c) {\r
+      case SLIP_ESC_END:\r
+  c = SLIP_END;\r
+  break;\r
+      case SLIP_ESC_ESC:\r
+  c = SLIP_ESC;\r
+  break;\r
+      }\r
+      /* FALLTHROUGH */\r
+      \r
+    default:\r
+      if (p == NULL) {\r
+  LWIP_DEBUGF(SLIP_DEBUG, ("slipif_input: alloc\n"));\r
+  p = pbuf_alloc(PBUF_LINK, PBUF_POOL_BUFSIZE, PBUF_POOL);\r
+\r
+  if (p == NULL) {\r
+    LINK_STATS_INC(link.drop);\r
+    LWIP_DEBUGF(SLIP_DEBUG, ("slipif_input: no new pbuf! (DROP)\n"));\r
+  }\r
+  \r
+  if (q != NULL) {\r
+    pbuf_cat(q, p);\r
+  } else {\r
+    q = p;\r
+  }\r
+      }\r
+      if (p != NULL && recved < MAX_SIZE) {\r
+  ((u8_t *)p->payload)[i] = c;\r
+  recved++;\r
+  i++;\r
+  if (i >= p->len) {\r
+    i = 0;\r
+    p = NULL;\r
+  }\r
+      }\r
+      break;\r
+    }\r
+    \r
+  }\r
+  return NULL;\r
+}\r
+\r
+/**\r
+ * The SLIP input thread \r
+ *\r
+ * Feed the IP layer with incoming packets\r
+ */ \r
+static void\r
+slipif_loop(void *nf)\r
+{\r
+  struct pbuf *p;\r
+  struct netif *netif = (struct netif *)nf;\r
+\r
+  while (1) {\r
+    p = slipif_input(netif);\r
+    netif->input(p, netif);\r
+  }\r
+}\r
+\r
+/**\r
+ * SLIP netif initialization\r
+ *\r
+ * Call the arch specific sio_open and remember\r
+ * the opened device in the state field of the netif.\r
+ */ \r
+err_t\r
+slipif_init(struct netif *netif)\r
+{\r
+  \r
+  LWIP_DEBUGF(SLIP_DEBUG, ("slipif_init: netif->num=%x\n", (int)netif->num));\r
+\r
+  netif->name[0] = 's';\r
+  netif->name[1] = 'l';\r
+  netif->output = slipif_output;\r
+  netif->mtu = 1500;  \r
+  netif->flags = NETIF_FLAG_POINTTOPOINT;\r
+\r
+  netif->state = sio_open(netif->num);\r
+  if (!netif->state)\r
+      return ERR_IF;\r
+\r
+  sys_thread_new(slipif_loop, netif, SLIPIF_THREAD_PRIO);\r
+  return ERR_OK;\r
+}\r
index 316d193eceac7b43b67e038221474a6ef1c835c8..848f15915b4908f5e974d8901ff479c8d8888153 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index 37abd4bae93b91d3b795425ca00f66032ab84387..88b7cf880c76c2540d8ab8e75f14c1f535583f81 100644 (file)
@@ -1,4 +1,4 @@
-#      FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+#      FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 #\r
 #      This file is part of the FreeRTOS.org distribution.\r
 #\r
index c9f8e23eea669cbf3bde7cbf519a456bc76a3bbd..b248a5be1fa19791fed47acb28db9bb40dfb6d5f 100644 (file)
-/*
-    FreeRTOS V4.1.0 - copyright (C) 2003-2006 Richard Barry.
-    MCF5235 Port - Copyright (C) 2006 Christian Walter.
-
-    This file is part of the FreeRTOS distribution.
-
-    FreeRTOS is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    FreeRTOS is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with FreeRTOS; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-    A special exception to the GPL can be applied should you wish to distribute
-    a combined work that includes FreeRTOS, without being obliged to provide
-    the source code for any proprietary components.  See the licensing section
-    of http://www.FreeRTOS.org for full details of how and when the exception
-    can be applied.
-
-    ***************************************************************************
-    See http://www.FreeRTOS.org for documentation, latest information, license
-    and contact details.  Please ensure to read the configuration and relevant
+/*\r
+    FreeRTOS V4.1.0 - copyright (C) 2003-2006 Richard Barry.\r
+    MCF5235 Port - Copyright (C) 2006 Christian Walter.\r
+\r
+    This file is part of the FreeRTOS distribution.\r
+\r
+    FreeRTOS is free software; you can redistribute it and/or modify\r
+    it under the terms of the GNU General Public License as published by\r
+    the Free Software Foundation; either version 2 of the License, or\r
+    (at your option) any later version.\r
+\r
+    FreeRTOS is distributed in the hope that it will be useful,\r
+    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+    GNU General Public License for more details.\r
+\r
+    You should have received a copy of the GNU General Public License\r
+    along with FreeRTOS; if not, write to the Free Software\r
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+\r
+    A special exception to the GPL can be applied should you wish to distribute\r
+    a combined work that includes FreeRTOS, without being obliged to provide\r
+    the source code for any proprietary components.  See the licensing section\r
+    of http://www.FreeRTOS.org for full details of how and when the exception\r
+    can be applied.\r
+\r
+    ***************************************************************************\r
+    See http://www.FreeRTOS.org for documentation, latest information, license\r
+    and contact details.  Please ensure to read the configuration and relevant\r
     port sections of the online documentation.\r
 \r
        Also see http://www.SafeRTOS.com for an IEC 61508 compliant version along\r
-       with commercial development and support options.
-    ***************************************************************************
-*/
-
-/* ------------------------ System includes ------------------------------- */
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <assert.h>
-
-/* ------------------------ FreeRTOS includes ----------------------------- */
-#include "FreeRTOS.h"
-#include "task.h"
-
-/* ------------------------ LWIP includes --------------------------------- */
-#include "lwip/api.h"
-#include "lwip/tcpip.h"
-#include "lwip/memp.h"
-
-/* ------------------------ Project includes ------------------------------ */
-#include "mcf5xxx.h"
-#include "mcf523x.h"
-#include "serial.h"
-
-#include "web.h"
-#include "integer.h"
-#include "PollQ.h"
-#include "semtest.h"
-#include "BlockQ.h"
-#include "dynamic.h"
-#include "flop.h"
-
-/* ------------------------ Defines --------------------------------------- */
-#define mainCOM_TEST_BAUD_RATE      ( ( unsigned portLONG ) 38400 )
-
-/* Priorities for the demo application tasks. */
-#define mainLED_TASK_PRIORITY       ( tskIDLE_PRIORITY + 3 )
-#define mainCOM_TEST_PRIORITY       ( tskIDLE_PRIORITY + 2 )
-#define mainQUEUE_POLL_PRIORITY     ( tskIDLE_PRIORITY + 2 )
-#define mainCHECK_TASK_PRIORITY     ( tskIDLE_PRIORITY + 4 )
-#define mainSEM_TEST_PRIORITY       ( tskIDLE_PRIORITY + 1 )
-#define mainBLOCK_Q_PRIORITY        ( tskIDLE_PRIORITY + 2 )
-#define mainWEB_TASK_PRIORITY       ( tskIDLE_PRIORITY + 3 )
-#define STACK_DEFAULT               ( 1024 )
-
-/* Interval in which tasks are checked. */
-#define mainCHECK_PERIOD            ( ( portTickType ) 2000 / portTICK_RATE_MS  )
-
-/* Constants used by the vMemCheckTask() task. */
-#define mainCOUNT_INITIAL_VALUE     ( ( unsigned portLONG ) 0 )
-#define mainNO_TASK                 ( 0 )
-
-/* The size of the memory blocks allocated by the vMemCheckTask() task. */
-#define mainMEM_CHECK_SIZE_1        ( ( size_t ) 51 )
-#define mainMEM_CHECK_SIZE_2        ( ( size_t ) 52 )
-#define mainMEM_CHECK_SIZE_3        ( ( size_t ) 151 )
-
-/* ------------------------ Static variables ------------------------------ */
-xComPortHandle  xSTDComPort = NULL;
-
-/* ------------------------ Static functions ------------------------------ */
-static          portTASK_FUNCTION( vErrorChecks, pvParameters );
-static portLONG prvCheckOtherTasksAreStillRunning( unsigned portLONG
-                                                   ulMemCheckTaskCount );
-static          portTASK_FUNCTION( vMemCheckTask, pvParameters );
-
-/* ------------------------ Implementation -------------------------------- */
-int
-main( int argc, char *argv[] )
-{
-    asm volatile    ( "move.w  #0x2000, %sr\n\t" );
-
-    xSTDComPort = xSerialPortInitMinimal( 38400, 8 );
-    vlwIPInit(  );
-
-    /* Start the demo/test application tasks. */
-    vStartIntegerMathTasks( tskIDLE_PRIORITY );
-    vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
-    //vStartMathTasks( tskIDLE_PRIORITY );
-    vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
-    vStartDynamicPriorityTasks(  );
-    vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
-
-    /* Start the webserver. */
-    ( void )sys_thread_new( vBasicWEBServer, NULL, mainWEB_TASK_PRIORITY );
-
-    /* Start the check task - which is defined in this file. */
-    xTaskCreate( vErrorChecks, ( signed portCHAR * )"Check", 512, NULL,
-                 mainCHECK_TASK_PRIORITY, NULL );
-        /* Now all the tasks have been started - start the scheduler. */
-    vTaskStartScheduler(  );
-
-    /* Should never get here! */
-    return 0;
-}
-
-static
-portTASK_FUNCTION( vErrorChecks, pvParameters )
-{
-    unsigned portLONG ulMemCheckTaskRunningCount;
-    xTaskHandle     xCreatedTask;
-
-    /* The parameters are not used in this function. */
-    ( void )pvParameters;
-
-    for( ;; )
-    {
-        ulMemCheckTaskRunningCount = mainCOUNT_INITIAL_VALUE;
-        xCreatedTask = mainNO_TASK;
-        if( xTaskCreate( vMemCheckTask, ( signed portCHAR * )"MEM",
-                         configMINIMAL_STACK_SIZE, ( void * )&ulMemCheckTaskRunningCount,
-                         tskIDLE_PRIORITY, &xCreatedTask ) != pdPASS )
-        {
-            xSerialPutChar( xSTDComPort, 'E', portMAX_DELAY );
-        }
-        /* Delay until it is time to execute again. */
-        vTaskDelay( mainCHECK_PERIOD );
-
-        /* Delete the dynamically created task. */
-        if( xCreatedTask != mainNO_TASK )
-        {
-            vTaskDelete( xCreatedTask );
-        }
-
-        if( prvCheckOtherTasksAreStillRunning( ulMemCheckTaskRunningCount ) != pdPASS )
-        {
-            xSerialPutChar( xSTDComPort, 'E', portMAX_DELAY );
-        }
-        else
-        {
-            xSerialPutChar( xSTDComPort, '.', portMAX_DELAY );
-        }
-    }
-}
-
-static portLONG
-prvCheckOtherTasksAreStillRunning( unsigned portLONG ulMemCheckTaskCount )
-{
-    portLONG        lReturn = ( portLONG ) pdPASS;
-
-    /* Check all the demo tasks (other than the flash tasks) to ensure
-     * that they are all still running, and that none of them have detected
-     * an error.
-     */
-    if( xAreIntegerMathsTaskStillRunning(  ) != pdTRUE )
-    {
-        lReturn = ( portLONG ) pdFAIL;
-    }
-
-    if( xArePollingQueuesStillRunning(  ) != pdTRUE )
-    {
-        lReturn = ( portLONG ) pdFAIL;
-    }
-
-    if( xAreSemaphoreTasksStillRunning(  ) != pdTRUE )
-    {
-        lReturn = ( portLONG ) pdFAIL;
-    }
-
-    if( xAreDynamicPriorityTasksStillRunning(  ) != pdTRUE )
-    {
-        lReturn = ( portLONG ) pdFAIL;
-    }
-
-    if( xAreBlockingQueuesStillRunning(  ) != pdTRUE )
-    {
-        lReturn = ( portLONG ) pdFAIL;
-    }
-
-    if( ulMemCheckTaskCount == mainCOUNT_INITIAL_VALUE )
-    {
-        /* The vMemCheckTask did not increment the counter - it must
-         * have failed.
-         */
-        lReturn = ( portLONG ) pdFAIL;
-    }
-    return lReturn;
-}
-
-static void
-vMemCheckTask( void *pvParameters )
-{
-    unsigned portLONG *pulMemCheckTaskRunningCounter;
-    void           *pvMem1, *pvMem2, *pvMem3;
-    static portLONG lErrorOccurred = pdFALSE;
-
-    /* This task is dynamically created then deleted during each cycle of the
-       vErrorChecks task to check the operation of the memory allocator.  Each time
-       the task is created memory is allocated for the stack and TCB.  Each time
-       the task is deleted this memory is returned to the heap.  This task itself
-       exercises the allocator by allocating and freeing blocks.
-
-       The task executes at the idle priority so does not require a delay.
-
-       pulMemCheckTaskRunningCounter is incremented each cycle to indicate to the
-       vErrorChecks() task that this task is still executing without error. */
-
-    pulMemCheckTaskRunningCounter = ( unsigned portLONG * )pvParameters;
-
-    for( ;; )
-    {
-        if( lErrorOccurred == pdFALSE )
-        {
-            /* We have never seen an error so increment the counter. */
-            ( *pulMemCheckTaskRunningCounter )++;
-        }
-
-        /* Allocate some memory - just to give the allocator some extra
-           exercise.  This has to be in a critical section to ensure the
-           task does not get deleted while it has memory allocated. */
-        vTaskSuspendAll(  );
-        {
-            pvMem1 = pvPortMalloc( mainMEM_CHECK_SIZE_1 );
-            if( pvMem1 == NULL )
-            {
-                lErrorOccurred = pdTRUE;
-            }
-            else
-            {
-                memset( pvMem1, 0xaa, mainMEM_CHECK_SIZE_1 );
-                vPortFree( pvMem1 );
-            }
-        }
-        xTaskResumeAll(  );
-
-        /* Again - with a different size block. */
-        vTaskSuspendAll(  );
-        {
-            pvMem2 = pvPortMalloc( mainMEM_CHECK_SIZE_2 );
-            if( pvMem2 == NULL )
-            {
-                lErrorOccurred = pdTRUE;
-            }
-            else
-            {
-                memset( pvMem2, 0xaa, mainMEM_CHECK_SIZE_2 );
-                vPortFree( pvMem2 );
-            }
-        }
-        xTaskResumeAll(  );
-
-        /* Again - with a different size block. */
-        vTaskSuspendAll(  );
-        {
-            pvMem3 = pvPortMalloc( mainMEM_CHECK_SIZE_3 );
-            if( pvMem3 == NULL )
-            {
-                lErrorOccurred = pdTRUE;
-            }
-            else
-            {
-                memset( pvMem3, 0xaa, mainMEM_CHECK_SIZE_3 );
-                vPortFree( pvMem3 );
-            }
-        }
-        xTaskResumeAll(  );
-    }
-}
+       with commercial development and support options.\r
+    ***************************************************************************\r
+*/\r
+\r
+/* ------------------------ System includes ------------------------------- */\r
+#include <stdlib.h>\r
+#include <stdio.h>\r
+#include <string.h>\r
+#include <assert.h>\r
+\r
+/* ------------------------ FreeRTOS includes ----------------------------- */\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+\r
+/* ------------------------ LWIP includes --------------------------------- */\r
+#include "lwip/api.h"\r
+#include "lwip/tcpip.h"\r
+#include "lwip/memp.h"\r
+\r
+/* ------------------------ Project includes ------------------------------ */\r
+#include "mcf5xxx.h"\r
+#include "mcf523x.h"\r
+#include "serial.h"\r
+\r
+#include "web.h"\r
+#include "integer.h"\r
+#include "PollQ.h"\r
+#include "semtest.h"\r
+#include "BlockQ.h"\r
+#include "dynamic.h"\r
+#include "flop.h"\r
+\r
+/* ------------------------ Defines --------------------------------------- */\r
+#define mainCOM_TEST_BAUD_RATE      ( ( unsigned portLONG ) 38400 )\r
+\r
+/* Priorities for the demo application tasks. */\r
+#define mainLED_TASK_PRIORITY       ( tskIDLE_PRIORITY + 3 )\r
+#define mainCOM_TEST_PRIORITY       ( tskIDLE_PRIORITY + 2 )\r
+#define mainQUEUE_POLL_PRIORITY     ( tskIDLE_PRIORITY + 2 )\r
+#define mainCHECK_TASK_PRIORITY     ( tskIDLE_PRIORITY + 4 )\r
+#define mainSEM_TEST_PRIORITY       ( tskIDLE_PRIORITY + 1 )\r
+#define mainBLOCK_Q_PRIORITY        ( tskIDLE_PRIORITY + 2 )\r
+#define mainWEB_TASK_PRIORITY       ( tskIDLE_PRIORITY + 3 )\r
+#define STACK_DEFAULT               ( 1024 )\r
+\r
+/* Interval in which tasks are checked. */\r
+#define mainCHECK_PERIOD            ( ( portTickType ) 2000 / portTICK_RATE_MS  )\r
+\r
+/* Constants used by the vMemCheckTask() task. */\r
+#define mainCOUNT_INITIAL_VALUE     ( ( unsigned portLONG ) 0 )\r
+#define mainNO_TASK                 ( 0 )\r
+\r
+/* The size of the memory blocks allocated by the vMemCheckTask() task. */\r
+#define mainMEM_CHECK_SIZE_1        ( ( size_t ) 51 )\r
+#define mainMEM_CHECK_SIZE_2        ( ( size_t ) 52 )\r
+#define mainMEM_CHECK_SIZE_3        ( ( size_t ) 151 )\r
+\r
+/* ------------------------ Static variables ------------------------------ */\r
+xComPortHandle  xSTDComPort = NULL;\r
+\r
+/* ------------------------ Static functions ------------------------------ */\r
+static          portTASK_FUNCTION( vErrorChecks, pvParameters );\r
+static portLONG prvCheckOtherTasksAreStillRunning( unsigned portLONG\r
+                                                   ulMemCheckTaskCount );\r
+static          portTASK_FUNCTION( vMemCheckTask, pvParameters );\r
+\r
+/* ------------------------ Implementation -------------------------------- */\r
+int\r
+main( int argc, char *argv[] )\r
+{\r
+    asm volatile    ( "move.w  #0x2000, %sr\n\t" );\r
+\r
+    xSTDComPort = xSerialPortInitMinimal( 38400, 8 );\r
+    vlwIPInit(  );\r
+\r
+    /* Start the demo/test application tasks. */\r
+    vStartIntegerMathTasks( tskIDLE_PRIORITY );\r
+    vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );\r
+    //vStartMathTasks( tskIDLE_PRIORITY );\r
+    vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );\r
+    vStartDynamicPriorityTasks(  );\r
+    vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );\r
+\r
+    /* Start the webserver. */\r
+    ( void )sys_thread_new( vBasicWEBServer, NULL, mainWEB_TASK_PRIORITY );\r
+\r
+    /* Start the check task - which is defined in this file. */\r
+    xTaskCreate( vErrorChecks, ( signed portCHAR * )"Check", 512, NULL,\r
+                 mainCHECK_TASK_PRIORITY, NULL );\r
+        /* Now all the tasks have been started - start the scheduler. */\r
+    vTaskStartScheduler(  );\r
+\r
+    /* Should never get here! */\r
+    return 0;\r
+}\r
+\r
+static\r
+portTASK_FUNCTION( vErrorChecks, pvParameters )\r
+{\r
+    unsigned portLONG ulMemCheckTaskRunningCount;\r
+    xTaskHandle     xCreatedTask;\r
+\r
+    /* The parameters are not used in this function. */\r
+    ( void )pvParameters;\r
+\r
+    for( ;; )\r
+    {\r
+        ulMemCheckTaskRunningCount = mainCOUNT_INITIAL_VALUE;\r
+        xCreatedTask = mainNO_TASK;\r
+        if( xTaskCreate( vMemCheckTask, ( signed portCHAR * )"MEM",\r
+                         configMINIMAL_STACK_SIZE, ( void * )&ulMemCheckTaskRunningCount,\r
+                         tskIDLE_PRIORITY, &xCreatedTask ) != pdPASS )\r
+        {\r
+            xSerialPutChar( xSTDComPort, 'E', portMAX_DELAY );\r
+        }\r
+        /* Delay until it is time to execute again. */\r
+        vTaskDelay( mainCHECK_PERIOD );\r
+\r
+        /* Delete the dynamically created task. */\r
+        if( xCreatedTask != mainNO_TASK )\r
+        {\r
+            vTaskDelete( xCreatedTask );\r
+        }\r
+\r
+        if( prvCheckOtherTasksAreStillRunning( ulMemCheckTaskRunningCount ) != pdPASS )\r
+        {\r
+            xSerialPutChar( xSTDComPort, 'E', portMAX_DELAY );\r
+        }\r
+        else\r
+        {\r
+            xSerialPutChar( xSTDComPort, '.', portMAX_DELAY );\r
+        }\r
+    }\r
+}\r
+\r
+static portLONG\r
+prvCheckOtherTasksAreStillRunning( unsigned portLONG ulMemCheckTaskCount )\r
+{\r
+    portLONG        lReturn = ( portLONG ) pdPASS;\r
+\r
+    /* Check all the demo tasks (other than the flash tasks) to ensure\r
+     * that they are all still running, and that none of them have detected\r
+     * an error.\r
+     */\r
+    if( xAreIntegerMathsTaskStillRunning(  ) != pdTRUE )\r
+    {\r
+        lReturn = ( portLONG ) pdFAIL;\r
+    }\r
+\r
+    if( xArePollingQueuesStillRunning(  ) != pdTRUE )\r
+    {\r
+        lReturn = ( portLONG ) pdFAIL;\r
+    }\r
+\r
+    if( xAreSemaphoreTasksStillRunning(  ) != pdTRUE )\r
+    {\r
+        lReturn = ( portLONG ) pdFAIL;\r
+    }\r
+\r
+    if( xAreDynamicPriorityTasksStillRunning(  ) != pdTRUE )\r
+    {\r
+        lReturn = ( portLONG ) pdFAIL;\r
+    }\r
+\r
+    if( xAreBlockingQueuesStillRunning(  ) != pdTRUE )\r
+    {\r
+        lReturn = ( portLONG ) pdFAIL;\r
+    }\r
+\r
+    if( ulMemCheckTaskCount == mainCOUNT_INITIAL_VALUE )\r
+    {\r
+        /* The vMemCheckTask did not increment the counter - it must\r
+         * have failed.\r
+         */\r
+        lReturn = ( portLONG ) pdFAIL;\r
+    }\r
+    return lReturn;\r
+}\r
+\r
+static void\r
+vMemCheckTask( void *pvParameters )\r
+{\r
+    unsigned portLONG *pulMemCheckTaskRunningCounter;\r
+    void           *pvMem1, *pvMem2, *pvMem3;\r
+    static portLONG lErrorOccurred = pdFALSE;\r
+\r
+    /* This task is dynamically created then deleted during each cycle of the\r
+       vErrorChecks task to check the operation of the memory allocator.  Each time\r
+       the task is created memory is allocated for the stack and TCB.  Each time\r
+       the task is deleted this memory is returned to the heap.  This task itself\r
+       exercises the allocator by allocating and freeing blocks.\r
+\r
+       The task executes at the idle priority so does not require a delay.\r
+\r
+       pulMemCheckTaskRunningCounter is incremented each cycle to indicate to the\r
+       vErrorChecks() task that this task is still executing without error. */\r
+\r
+    pulMemCheckTaskRunningCounter = ( unsigned portLONG * )pvParameters;\r
+\r
+    for( ;; )\r
+    {\r
+        if( lErrorOccurred == pdFALSE )\r
+        {\r
+            /* We have never seen an error so increment the counter. */\r
+            ( *pulMemCheckTaskRunningCounter )++;\r
+        }\r
+\r
+        /* Allocate some memory - just to give the allocator some extra\r
+           exercise.  This has to be in a critical section to ensure the\r
+           task does not get deleted while it has memory allocated. */\r
+        vTaskSuspendAll(  );\r
+        {\r
+            pvMem1 = pvPortMalloc( mainMEM_CHECK_SIZE_1 );\r
+            if( pvMem1 == NULL )\r
+            {\r
+                lErrorOccurred = pdTRUE;\r
+            }\r
+            else\r
+            {\r
+                memset( pvMem1, 0xaa, mainMEM_CHECK_SIZE_1 );\r
+                vPortFree( pvMem1 );\r
+            }\r
+        }\r
+        xTaskResumeAll(  );\r
+\r
+        /* Again - with a different size block. */\r
+        vTaskSuspendAll(  );\r
+        {\r
+            pvMem2 = pvPortMalloc( mainMEM_CHECK_SIZE_2 );\r
+            if( pvMem2 == NULL )\r
+            {\r
+                lErrorOccurred = pdTRUE;\r
+            }\r
+            else\r
+            {\r
+                memset( pvMem2, 0xaa, mainMEM_CHECK_SIZE_2 );\r
+                vPortFree( pvMem2 );\r
+            }\r
+        }\r
+        xTaskResumeAll(  );\r
+\r
+        /* Again - with a different size block. */\r
+        vTaskSuspendAll(  );\r
+        {\r
+            pvMem3 = pvPortMalloc( mainMEM_CHECK_SIZE_3 );\r
+            if( pvMem3 == NULL )\r
+            {\r
+                lErrorOccurred = pdTRUE;\r
+            }\r
+            else\r
+            {\r
+                memset( pvMem3, 0xaa, mainMEM_CHECK_SIZE_3 );\r
+                vPortFree( pvMem3 );\r
+            }\r
+        }\r
+        xTaskResumeAll(  );\r
+    }\r
+}\r
index 4b7761fd59c78e3bf3b85fb136304115a9743d2f..ae9dd63f6d2bf01bbf0da2df8cab0adcebe825f0 100644 (file)
@@ -1,46 +1,46 @@
-/*
- * These files are taken from the MCF523X source code example package
- * which is available on the Freescale website. Freescale explicitly 
- * grants the redistribution and modification of these source files.
- * The complete licensing information is available in the file 
- * LICENSE_FREESCALE.TXT.
- *
- * File:       mcf523x.h
- * Purpose:    Register and bit definitions for the MCF523X
- *
- * Notes:      
- *     
- */
-
-#ifndef __MCF523X_H__
-#define __MCF523X_H__
-
-/*********************************************************************/
-
-#include "mcf523x/mcf523x_fec.h"
-#include "mcf523x/mcf523x_rng.h"
-#include "mcf523x/mcf523x_fmpll.h"
-#include "mcf523x/mcf523x_cs.h"
-#include "mcf523x/mcf523x_intc0.h"
-#include "mcf523x/mcf523x_intc1.h"
-#include "mcf523x/mcf523x_sdramc.h"
-#include "mcf523x/mcf523x_sram.h"
-#include "mcf523x/mcf523x_uart.h"
-#include "mcf523x/mcf523x_timer.h"
-#include "mcf523x/mcf523x_qspi.h"
-#include "mcf523x/mcf523x_eport.h"
-#include "mcf523x/mcf523x_i2c.h"
-#include "mcf523x/mcf523x_scm.h"
-#include "mcf523x/mcf523x_pit.h"
-#include "mcf523x/mcf523x_can.h"
-#include "mcf523x/mcf523x_wtm.h"
-#include "mcf523x/mcf523x_gpio.h"
-#include "mcf523x/mcf523x_mdha.h"
-#include "mcf523x/mcf523x_ccm.h"
-#include "mcf523x/mcf523x_rcm.h"
-#include "mcf523x/mcf523x_etpu.h"
-
-
-/********************************************************************/
-
-#endif /* __MCF523X_H__ */
+/*\r
+ * These files are taken from the MCF523X source code example package\r
+ * which is available on the Freescale website. Freescale explicitly \r
+ * grants the redistribution and modification of these source files.\r
+ * The complete licensing information is available in the file \r
+ * LICENSE_FREESCALE.TXT.\r
+ *\r
+ * File:       mcf523x.h\r
+ * Purpose:    Register and bit definitions for the MCF523X\r
+ *\r
+ * Notes:      \r
+ *     \r
+ */\r
+\r
+#ifndef __MCF523X_H__\r
+#define __MCF523X_H__\r
+\r
+/*********************************************************************/\r
+\r
+#include "mcf523x/mcf523x_fec.h"\r
+#include "mcf523x/mcf523x_rng.h"\r
+#include "mcf523x/mcf523x_fmpll.h"\r
+#include "mcf523x/mcf523x_cs.h"\r
+#include "mcf523x/mcf523x_intc0.h"\r
+#include "mcf523x/mcf523x_intc1.h"\r
+#include "mcf523x/mcf523x_sdramc.h"\r
+#include "mcf523x/mcf523x_sram.h"\r
+#include "mcf523x/mcf523x_uart.h"\r
+#include "mcf523x/mcf523x_timer.h"\r
+#include "mcf523x/mcf523x_qspi.h"\r
+#include "mcf523x/mcf523x_eport.h"\r
+#include "mcf523x/mcf523x_i2c.h"\r
+#include "mcf523x/mcf523x_scm.h"\r
+#include "mcf523x/mcf523x_pit.h"\r
+#include "mcf523x/mcf523x_can.h"\r
+#include "mcf523x/mcf523x_wtm.h"\r
+#include "mcf523x/mcf523x_gpio.h"\r
+#include "mcf523x/mcf523x_mdha.h"\r
+#include "mcf523x/mcf523x_ccm.h"\r
+#include "mcf523x/mcf523x_rcm.h"\r
+#include "mcf523x/mcf523x_etpu.h"\r
+\r
+\r
+/********************************************************************/\r
+\r
+#endif /* __MCF523X_H__ */\r
index 7aaa344962c3b0fe81a93f0928878436c75f1758..a193ba6fd0e25f342186824953ebe6abb2d38306 100644 (file)
-/*
- * These files are taken from the MCF523X source code example package
- * which is available on the Freescale website. Freescale explicitly 
- * grants the redistribution and modification of these source files.
- * The complete licensing information is available in the file 
- * LICENSE_FREESCALE.TXT.
- *
- * File:       mcf523x_can.h
- * Purpose:    Register and bit definitions for the MCF523X
- *
- * Notes:      
- *     
- */
-
-#ifndef __MCF523X_CAN_H__
-#define __MCF523X_CAN_H__
-
-/*********************************************************************
-*
-* FlexCAN Module (CAN)
-*
-*********************************************************************/
-
-/* Register read/write macros */
-#define MCF_CAN_CANMCR0        (*(vuint32*)(void*)(&__IPSBAR[0x1C0000]))
-#define MCF_CAN_CANCTRL0       (*(vuint32*)(void*)(&__IPSBAR[0x1C0004]))
-#define MCF_CAN_TIMER0         (*(vuint32*)(void*)(&__IPSBAR[0x1C0008]))
-#define MCF_CAN_RXGMASK0       (*(vuint32*)(void*)(&__IPSBAR[0x1C0010]))
-#define MCF_CAN_RX14MASK0      (*(vuint32*)(void*)(&__IPSBAR[0x1C0014]))
-#define MCF_CAN_RX15MASK0      (*(vuint32*)(void*)(&__IPSBAR[0x1C0018]))
-#define MCF_CAN_ERRCNT0        (*(vuint32*)(void*)(&__IPSBAR[0x1C001C]))
-#define MCF_CAN_ERRSTAT0       (*(vuint32*)(void*)(&__IPSBAR[0x1C0020]))
-#define MCF_CAN_IMASK0         (*(vuint16*)(void*)(&__IPSBAR[0x1C002A]))
-#define MCF_CAN_IFLAG0         (*(vuint16*)(void*)(&__IPSBAR[0x1C0032]))
-#define MCF_CAN_CANMCR1        (*(vuint32*)(void*)(&__IPSBAR[0x1F0000]))
-#define MCF_CAN_CANCTRL1       (*(vuint32*)(void*)(&__IPSBAR[0x1F0004]))
-#define MCF_CAN_TIMER1         (*(vuint32*)(void*)(&__IPSBAR[0x1F0008]))
-#define MCF_CAN_RXGMASK1       (*(vuint32*)(void*)(&__IPSBAR[0x1F0010]))
-#define MCF_CAN_RX14MASK1      (*(vuint32*)(void*)(&__IPSBAR[0x1F0014]))
-#define MCF_CAN_RX15MASK1      (*(vuint32*)(void*)(&__IPSBAR[0x1F0018]))
-#define MCF_CAN_ERRCNT1        (*(vuint32*)(void*)(&__IPSBAR[0x1F001C]))
-#define MCF_CAN_ERRSTAT1       (*(vuint32*)(void*)(&__IPSBAR[0x1F0020]))
-#define MCF_CAN_IMASK1         (*(vuint16*)(void*)(&__IPSBAR[0x1F002A]))
-#define MCF_CAN_IFLAG1         (*(vuint16*)(void*)(&__IPSBAR[0x1F0032]))
-#define MCF_CAN_CANMCR(x)      (*(vuint32*)(void*)(&__IPSBAR[0x1C0000+((x)*0x30000)]))
-#define MCF_CAN_CANCTRL(x)     (*(vuint32*)(void*)(&__IPSBAR[0x1C0004+((x)*0x30000)]))
-#define MCF_CAN_TIMER(x)       (*(vuint32*)(void*)(&__IPSBAR[0x1C0008+((x)*0x30000)]))
-#define MCF_CAN_RXGMASK(x)     (*(vuint32*)(void*)(&__IPSBAR[0x1C0010+((x)*0x30000)]))
-#define MCF_CAN_RX14MASK(x)    (*(vuint32*)(void*)(&__IPSBAR[0x1C0014+((x)*0x30000)]))
-#define MCF_CAN_RX15MASK(x)    (*(vuint32*)(void*)(&__IPSBAR[0x1C0018+((x)*0x30000)]))
-#define MCF_CAN_ERRCNT(x)      (*(vuint32*)(void*)(&__IPSBAR[0x1C001C+((x)*0x30000)]))
-#define MCF_CAN_ERRSTAT(x)     (*(vuint32*)(void*)(&__IPSBAR[0x1C0020+((x)*0x30000)]))
-#define MCF_CAN_IMASK(x)       (*(vuint16*)(void*)(&__IPSBAR[0x1C002A+((x)*0x30000)]))
-#define MCF_CAN_IFLAG(x)       (*(vuint16*)(void*)(&__IPSBAR[0x1C0032+((x)*0x30000)]))
-
-#define MCF_CAN_MBUF0_CTRL(x)          (*(vuint16 *)(void *)(&__IPSBAR[0x1C0080+((x)*0x30000)]))
-#define MCF_CAN_MBUF0_TMSTP(x)         (*(vuint16 *)(void *)(&__IPSBAR[0x1C0082+((x)*0x30000)]))
-#define MCF_CAN_MBUF0_ID(x)        (*(vuint32 *)(void *)(&__IPSBAR[0x1C0084+((x)*0x30000)]))
-#define MCF_CAN_MBUF0_BYTE0(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C0088+((x)*0x30000)]))
-#define MCF_CAN_MBUF0_BYTE1(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C0089+((x)*0x30000)]))
-#define MCF_CAN_MBUF0_BYTE2(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C008A+((x)*0x30000)]))
-#define MCF_CAN_MBUF0_BYTE3(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C008B+((x)*0x30000)]))
-#define MCF_CAN_MBUF0_BYTE4(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C008C+((x)*0x30000)]))
-#define MCF_CAN_MBUF0_BYTE5(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C008D+((x)*0x30000)]))
-#define MCF_CAN_MBUF0_BYTE6(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C008E+((x)*0x30000)]))
-#define MCF_CAN_MBUF0_BYTE7(x)      (*(vuint8  *)(void *)(&__IPSBAR[0x1C008F+((x)*0x30000)]))
-#define MCF_CAN_MBUF1_CTRL(x)          (*(vuint16 *)(void *)(&__IPSBAR[0x1C0090+((x)*0x30000)]))
-#define MCF_CAN_MBUF1_TMSTP(x)         (*(vuint16 *)(void *)(&__IPSBAR[0x1C0092+((x)*0x30000)]))
-#define MCF_CAN_MBUF1_ID(x)                    (*(vuint32 *)(void *)(&__IPSBAR[0x1C0094+((x)*0x30000)]))
-#define MCF_CAN_MBUF1_BYTE0(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C0098+((x)*0x30000)]))
-#define MCF_CAN_MBUF1_BYTE1(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C0099+((x)*0x30000)]))
-#define MCF_CAN_MBUF1_BYTE2(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C009A+((x)*0x30000)]))
-#define MCF_CAN_MBUF1_BYTE3(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C009B+((x)*0x30000)]))
-#define MCF_CAN_MBUF1_BYTE4(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C009C+((x)*0x30000)]))
-#define MCF_CAN_MBUF1_BYTE5(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C009D+((x)*0x30000)]))
-#define MCF_CAN_MBUF1_BYTE6(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C009E+((x)*0x30000)]))
-#define MCF_CAN_MBUF1_BYTE7(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C009F+((x)*0x30000)]))
-#define MCF_CAN_MBUF2_CTRL(x)          (*(vuint16 *)(void *)(&__IPSBAR[0x1C00A0+((x)*0x30000)]))
-#define MCF_CAN_MBUF2_ID(x)        (*(vuint32 *)(void *)(&__IPSBAR[0x1C00A4+((x)*0x30000)]))
-#define MCF_CAN_MBUF2_BYTE0(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00A8+((x)*0x30000)]))
-#define MCF_CAN_MBUF2_BYTE1(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00A9+((x)*0x30000)]))
-#define MCF_CAN_MBUF2_BYTE2(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00AA+((x)*0x30000)]))
-#define MCF_CAN_MBUF2_BYTE3(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00AB+((x)*0x30000)]))
-#define MCF_CAN_MBUF2_BYTE4(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00AC+((x)*0x30000)]))
-#define MCF_CAN_MBUF2_BYTE5(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00AD+((x)*0x30000)]))
-#define MCF_CAN_MBUF2_BYTE6(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00AE+((x)*0x30000)]))
-#define MCF_CAN_MBUF2_BYTE7(x)      (*(vuint8  *)(void *)(&__IPSBAR[0x1C00AF+((x)*0x30000)]))
-#define MCF_CAN_MBUF3_CTRL(x)          (*(vuint16 *)(void *)(&__IPSBAR[0x1C00B0+((x)*0x30000)]))
-#define MCF_CAN_MBUF3_ID(x)                    (*(vuint32 *)(void *)(&__IPSBAR[0x1C00B4+((x)*0x30000)]))
-#define MCF_CAN_MBUF3_BYTE0(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00B8+((x)*0x30000)]))
-#define MCF_CAN_MBUF3_BYTE1(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00B9+((x)*0x30000)]))
-#define MCF_CAN_MBUF3_BYTE2(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00BA+((x)*0x30000)]))
-#define MCF_CAN_MBUF3_BYTE3(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00BB+((x)*0x30000)]))
-#define MCF_CAN_MBUF3_BYTE4(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00BC+((x)*0x30000)]))
-#define MCF_CAN_MBUF3_BYTE5(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00BD+((x)*0x30000)]))
-#define MCF_CAN_MBUF3_BYTE6(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00BE+((x)*0x30000)]))
-#define MCF_CAN_MBUF3_BYTE7(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00BF+((x)*0x30000)]))
-#define MCF_CAN_MBUF4_CTRL(x)          (*(vuint16 *)(void *)(&__IPSBAR[0x1C00C0+((x)*0x30000)]))
-#define MCF_CAN_MBUF4_ID(x)        (*(vuint32 *)(void *)(&__IPSBAR[0x1C00C4+((x)*0x30000)]))
-#define MCF_CAN_MBUF4_BYTE0(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00C8+((x)*0x30000)]))
-#define MCF_CAN_MBUF4_BYTE1(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00C9+((x)*0x30000)]))
-#define MCF_CAN_MBUF4_BYTE2(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00CA+((x)*0x30000)]))
-#define MCF_CAN_MBUF4_BYTE3(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00CB+((x)*0x30000)]))
-#define MCF_CAN_MBUF4_BYTE4(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00CC+((x)*0x30000)]))
-#define MCF_CAN_MBUF4_BYTE5(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00CD+((x)*0x30000)]))
-#define MCF_CAN_MBUF4_BYTE6(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00CE+((x)*0x30000)]))
-#define MCF_CAN_MBUF4_BYTE7(x)      (*(vuint8  *)(void *)(&__IPSBAR[0x1C00CF+((x)*0x30000)]))
-#define MCF_CAN_MBUF5_CTRL(x)          (*(vuint16 *)(void *)(&__IPSBAR[0x1C00D0+((x)*0x30000)]))
-#define MCF_CAN_MBUF5_ID(x)                    (*(vuint32 *)(void *)(&__IPSBAR[0x1C00D4+((x)*0x30000)]))
-#define MCF_CAN_MBUF5_BYTE0(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00D8+((x)*0x30000)]))
-#define MCF_CAN_MBUF5_BYTE1(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00D9+((x)*0x30000)]))
-#define MCF_CAN_MBUF5_BYTE2(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00DA+((x)*0x30000)]))
-#define MCF_CAN_MBUF5_BYTE3(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00DB+((x)*0x30000)]))
-#define MCF_CAN_MBUF5_BYTE4(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00DC+((x)*0x30000)]))
-#define MCF_CAN_MBUF5_BYTE5(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00DD+((x)*0x30000)]))
-#define MCF_CAN_MBUF5_BYTE6(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00DE+((x)*0x30000)]))
-#define MCF_CAN_MBUF5_BYTE7(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00DF+((x)*0x30000)]))
-#define MCF_CAN_MBUF6_CTRL(x)          (*(vuint16 *)(void *)(&__IPSBAR[0x1C00E0+((x)*0x30000)]))
-#define MCF_CAN_MBUF6_ID(x)        (*(vuint32 *)(void *)(&__IPSBAR[0x1C00E4+((x)*0x30000)]))
-#define MCF_CAN_MBUF6_BYTE0(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00E8+((x)*0x30000)]))
-#define MCF_CAN_MBUF6_BYTE1(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00E9+((x)*0x30000)]))
-#define MCF_CAN_MBUF6_BYTE2(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00EA+((x)*0x30000)]))
-#define MCF_CAN_MBUF6_BYTE3(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00EB+((x)*0x30000)]))
-#define MCF_CAN_MBUF6_BYTE4(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00EC+((x)*0x30000)]))
-#define MCF_CAN_MBUF6_BYTE5(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00ED+((x)*0x30000)]))
-#define MCF_CAN_MBUF6_BYTE6(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00EE+((x)*0x30000)]))
-#define MCF_CAN_MBUF6_BYTE7(x)      (*(vuint8  *)(void *)(&__IPSBAR[0x1C00EF+((x)*0x30000)]))
-#define MCF_CAN_MBUF7_CTRL(x)          (*(vuint16 *)(void *)(&__IPSBAR[0x1C00F0+((x)*0x30000)]))
-#define MCF_CAN_MBUF7_ID(x)                    (*(vuint32 *)(void *)(&__IPSBAR[0x1C00F4+((x)*0x30000)]))
-#define MCF_CAN_MBUF7_BYTE0(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00F8+((x)*0x30000)]))
-#define MCF_CAN_MBUF7_BYTE1(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00F9+((x)*0x30000)]))
-#define MCF_CAN_MBUF7_BYTE2(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00FA+((x)*0x30000)]))
-#define MCF_CAN_MBUF7_BYTE3(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00FB+((x)*0x30000)]))
-#define MCF_CAN_MBUF7_BYTE4(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00FC+((x)*0x30000)]))
-#define MCF_CAN_MBUF7_BYTE5(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00FD+((x)*0x30000)]))
-#define MCF_CAN_MBUF7_BYTE6(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00FE+((x)*0x30000)]))
-#define MCF_CAN_MBUF7_BYTE7(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00FF+((x)*0x30000)]))
-#define MCF_CAN_MBUF8_CTRL(x)          (*(vuint16 *)(void *)(&__IPSBAR[0x1C0100+((x)*0x30000)]))
-#define MCF_CAN_MBUF8_ID(x)        (*(vuint32 *)(void *)(&__IPSBAR[0x1C0104+((x)*0x30000)]))
-#define MCF_CAN_MBUF8_BYTE0(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C0108+((x)*0x30000)]))
-#define MCF_CAN_MBUF8_BYTE1(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C0109+((x)*0x30000)]))
-#define MCF_CAN_MBUF8_BYTE2(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C010A+((x)*0x30000)]))
-#define MCF_CAN_MBUF8_BYTE3(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C010B+((x)*0x30000)]))
-#define MCF_CAN_MBUF8_BYTE4(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C010C+((x)*0x30000)]))
-#define MCF_CAN_MBUF8_BYTE5(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C010D+((x)*0x30000)]))
-#define MCF_CAN_MBUF8_BYTE6(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C010E+((x)*0x30000)]))
-#define MCF_CAN_MBUF8_BYTE7(x)      (*(vuint8  *)(void *)(&__IPSBAR[0x1C010F+((x)*0x30000)]))
-#define MCF_CAN_MBUF9_CTRL(x)          (*(vuint16 *)(void *)(&__IPSBAR[0x1C0100+((x)*0x30000)]))
-#define MCF_CAN_MBUF9_ID(x)                    (*(vuint32 *)(void *)(&__IPSBAR[0x1C0114+((x)*0x30000)]))
-#define MCF_CAN_MBUF9_BYTE0(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C0118+((x)*0x30000)]))
-#define MCF_CAN_MBUF9_BYTE1(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C0119+((x)*0x30000)]))
-#define MCF_CAN_MBUF9_BYTE2(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C011A+((x)*0x30000)]))
-#define MCF_CAN_MBUF9_BYTE3(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C011B+((x)*0x30000)]))
-#define MCF_CAN_MBUF9_BYTE4(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C011C+((x)*0x30000)]))
-#define MCF_CAN_MBUF9_BYTE5(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C011D+((x)*0x30000)]))
-#define MCF_CAN_MBUF9_BYTE6(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C011E+((x)*0x30000)]))
-#define MCF_CAN_MBUF9_BYTE7(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C011F+((x)*0x30000)]))
-#define MCF_CAN_MBUF10_CTRL(x)         (*(vuint16 *)(void *)(&__IPSBAR[0x1C0120+((x)*0x30000)]))
-#define MCF_CAN_MBUF10_ID(x)       (*(vuint32 *)(void *)(&__IPSBAR[0x1C0124+((x)*0x30000)]))
-#define MCF_CAN_MBUF10_BYTE0(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C0128+((x)*0x30000)]))
-#define MCF_CAN_MBUF10_BYTE1(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C0129+((x)*0x30000)]))
-#define MCF_CAN_MBUF10_BYTE2(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C012A+((x)*0x30000)]))
-#define MCF_CAN_MBUF10_BYTE3(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C012B+((x)*0x30000)]))
-#define MCF_CAN_MBUF10_BYTE4(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C012C+((x)*0x30000)]))
-#define MCF_CAN_MBUF10_BYTE5(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C012D+((x)*0x30000)]))
-#define MCF_CAN_MBUF10_BYTE6(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C012E+((x)*0x30000)]))
-#define MCF_CAN_MBUF10_BYTE7(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C012F+((x)*0x30000)]))
-#define MCF_CAN_MBUF11_CTRL(x)         (*(vuint16 *)(void *)(&__IPSBAR[0x1C0130+((x)*0x30000)]))
-#define MCF_CAN_MBUF11_ID(x)           (*(vuint32 *)(void *)(&__IPSBAR[0x1C0134+((x)*0x30000)]))
-#define MCF_CAN_MBUF11_BYTE0(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C0138+((x)*0x30000)]))
-#define MCF_CAN_MBUF11_BYTE1(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C0139+((x)*0x30000)]))
-#define MCF_CAN_MBUF11_BYTE2(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C013A+((x)*0x30000)]))
-#define MCF_CAN_MBUF11_BYTE3(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C013B+((x)*0x30000)]))
-#define MCF_CAN_MBUF11_BYTE4(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C013C+((x)*0x30000)]))
-#define MCF_CAN_MBUF11_BYTE5(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C013D+((x)*0x30000)]))
-#define MCF_CAN_MBUF11_BYTE6(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C013E+((x)*0x30000)]))
-#define MCF_CAN_MBUF11_BYTE7(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C013F+((x)*0x30000)]))
-#define MCF_CAN_MBUF12_CTRL(x)         (*(vuint16 *)(void *)(&__IPSBAR[0x1C0140+((x)*0x30000)]))
-#define MCF_CAN_MBUF12_ID(x)       (*(vuint32 *)(void *)(&__IPSBAR[0x1C0144+((x)*0x30000)]))
-#define MCF_CAN_MBUF12_BYTE0(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C0148+((x)*0x30000)]))
-#define MCF_CAN_MBUF12_BYTE1(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C0149+((x)*0x30000)]))
-#define MCF_CAN_MBUF12_BYTE2(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C014A+((x)*0x30000)]))
-#define MCF_CAN_MBUF12_BYTE3(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C014B+((x)*0x30000)]))
-#define MCF_CAN_MBUF12_BYTE4(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C014C+((x)*0x30000)]))
-#define MCF_CAN_MBUF12_BYTE5(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C014D+((x)*0x30000)]))
-#define MCF_CAN_MBUF12_BYTE6(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C014E+((x)*0x30000)]))
-#define MCF_CAN_MBUF12_BYTE7(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C014F+((x)*0x30000)]))
-#define MCF_CAN_MBUF13_CTRL(x)         (*(vuint16 *)(void *)(&__IPSBAR[0x1C0150+((x)*0x30000)]))
-#define MCF_CAN_MBUF13_ID(x)           (*(vuint32 *)(void *)(&__IPSBAR[0x1C0154+((x)*0x30000)]))
-#define MCF_CAN_MBUF13_BYTE0(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C0158+((x)*0x30000)]))
-#define MCF_CAN_MBUF13_BYTE1(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C0159+((x)*0x30000)]))
-#define MCF_CAN_MBUF13_BYTE2(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C015A+((x)*0x30000)]))
-#define MCF_CAN_MBUF13_BYTE3(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C015B+((x)*0x30000)]))
-#define MCF_CAN_MBUF13_BYTE4(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C015C+((x)*0x30000)]))
-#define MCF_CAN_MBUF13_BYTE5(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C015D+((x)*0x30000)]))
-#define MCF_CAN_MBUF13_BYTE6(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C015E+((x)*0x30000)]))
-#define MCF_CAN_MBUF13_BYTE7(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C015F+((x)*0x30000)]))
-#define MCF_CAN_MBUF14_CTRL(x)         (*(vuint16 *)(void *)(&__IPSBAR[0x1C0160+((x)*0x30000)]))
-#define MCF_CAN_MBUF14_ID(x)       (*(vuint32 *)(void *)(&__IPSBAR[0x1C0164+((x)*0x30000)]))
-#define MCF_CAN_MBUF14_BYTE0(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C0168+((x)*0x30000)]))
-#define MCF_CAN_MBUF14_BYTE1(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C0169+((x)*0x30000)]))
-#define MCF_CAN_MBUF14_BYTE2(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C016A+((x)*0x30000)]))
-#define MCF_CAN_MBUF14_BYTE3(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C016B+((x)*0x30000)]))
-#define MCF_CAN_MBUF14_BYTE4(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C016C+((x)*0x30000)]))
-#define MCF_CAN_MBUF14_BYTE5(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C016D+((x)*0x30000)]))
-#define MCF_CAN_MBUF14_BYTE6(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C016E+((x)*0x30000)]))
-#define MCF_CAN_MBUF14_BYTE7(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C016F+((x)*0x30000)]))
-#define MCF_CAN_MBUF15_CTRL(x)         (*(vuint16 *)(void *)(&__IPSBAR[0x1C0170+((x)*0x30000)]))
-#define MCF_CAN_MBUF15_ID(x)           (*(vuint32 *)(void *)(&__IPSBAR[0x1C0174+((x)*0x30000)]))
-#define MCF_CAN_MBUF15_BYTE0(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C0178+((x)*0x30000)]))
-#define MCF_CAN_MBUF15_BYTE1(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C0179+((x)*0x30000)]))
-#define MCF_CAN_MBUF15_BYTE2(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C017A+((x)*0x30000)]))
-#define MCF_CAN_MBUF15_BYTE3(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C017B+((x)*0x30000)]))
-#define MCF_CAN_MBUF15_BYTE4(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C017C+((x)*0x30000)]))
-#define MCF_CAN_MBUF15_BYTE5(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C017D+((x)*0x30000)]))
-#define MCF_CAN_MBUF15_BYTE6(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C017E+((x)*0x30000)]))
-#define MCF_CAN_MBUF15_BYTE7(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C017F+((x)*0x30000)]))
-                                                                                                                                                                 
-                                                                                                                                                                 
-#define MCF_CAN_MBUF0_DATAL(x)     (*(vuint32  *)(void *)(&__IPSBAR[0x1C0088+((x)*0x30000)]))
-#define MCF_CAN_MBUF0_DATAH(x)     (*(vuint32  *)(void *)(&__IPSBAR[0x1C008C+((x)*0x30000)]))
-#define MCF_CAN_MBUF1_DATAL(x)         (*(vuint32  *)(void *)(&__IPSBAR[0x1C0098+((x)*0x30000)]))
-#define MCF_CAN_MBUF1_DATAH(x)         (*(vuint32  *)(void *)(&__IPSBAR[0x1C009C+((x)*0x30000)]))
-#define MCF_CAN_MBUF2_DATAL(x)     (*(vuint32  *)(void *)(&__IPSBAR[0x1C00A8+((x)*0x30000)]))
-#define MCF_CAN_MBUF2_DATAH(x)     (*(vuint32  *)(void *)(&__IPSBAR[0x1C00AC+((x)*0x30000)]))
-                                                                                                                                                                 
-                                                                                                                                                                 
-/* Bit definitions and macros for MCF_CAN_CANMCR */                                                              
-#define MCF_CAN_CANMCR_MAXMB(x)            (((x)&0x0000000F)<<0)                                 
-#define MCF_CAN_CANMCR_SUPV                (0x00800000)                                                          
-#define MCF_CAN_CANMCR_FRZACK              (0x01000000)                                                          
-#define MCF_CAN_CANMCR_SOFTRST             (0x02000000)                                                          
-#define MCF_CAN_CANMCR_HALT                (0x10000000)                                                          
-#define MCF_CAN_CANMCR_FRZ                 (0x40000000)                                                          
-#define MCF_CAN_CANMCR_MDIS                (0x80000000)                                                          
-
-/* Bit definitions and macros for MCF_CAN_CANCTRL */
-#define MCF_CAN_CANCTRL_PROPSEG(x)         (((x)&0x00000007)<<0)
-#define MCF_CAN_CANCTRL_LOM                (0x00000008)
-#define MCF_CAN_CANCTRL_LBUF               (0x00000010)
-#define MCF_CAN_CANCTRL_TSYNC              (0x00000020)
-#define MCF_CAN_CANCTRL_BOFFREC            (0x00000040)
-#define MCF_CAN_CANCTRL_SAMP               (0x00000080)
-#define MCF_CAN_CANCTRL_LPB                (0x00001000)
-#define MCF_CAN_CANCTRL_CLKSRC             (0x00002000)
-#define MCF_CAN_CANCTRL_ERRMSK             (0x00004000)
-#define MCF_CAN_CANCTRL_BOFFMSK            (0x00008000)
-#define MCF_CAN_CANCTRL_PSEG2(x)           (((x)&0x00000007)<<16)
-#define MCF_CAN_CANCTRL_PSEG1(x)           (((x)&0x00000007)<<19)
-#define MCF_CAN_CANCTRL_RJW(x)             (((x)&0x00000003)<<22)
-#define MCF_CAN_CANCTRL_PRESDIV(x)         (((x)&0x000000FF)<<24)
-
-/* Bit definitions and macros for MCF_CAN_TIMER */
-#define MCF_CAN_TIMER_TIMER(x)             (((x)&0x0000FFFF)<<0)
-
-/* Bit definitions and macros for MCF_CAN_RXGMASK */
-#define MCF_CAN_RXGMASK_MI(x)              (((x)&0x1FFFFFFF)<<0)
-
-/* Bit definitions and macros for MCF_CAN_RX14MASK */
-#define MCF_CAN_RX14MASK_MI(x)             (((x)&0x1FFFFFFF)<<0)
-
-/* Bit definitions and macros for MCF_CAN_RX15MASK */
-#define MCF_CAN_RX15MASK_MI(x)             (((x)&0x1FFFFFFF)<<0)
-
-/* Bit definitions and macros for MCF_CAN_ERRCNT */
-#define MCF_CAN_ERRCNT_TXECTR(x)           (((x)&0x000000FF)<<0)
-#define MCF_CAN_ERRCNT_RXECTR(x)           (((x)&0x000000FF)<<8)
-
-/* Bit definitions and macros for MCF_CAN_ERRSTAT */
-#define MCF_CAN_ERRSTAT_WAKINT             (0x00000001)
-#define MCF_CAN_ERRSTAT_ERRINT             (0x00000002)
-#define MCF_CAN_ERRSTAT_BOFFINT            (0x00000004)
-#define MCF_CAN_ERRSTAT_FLTCONF(x)         (((x)&0x00000003)<<4)
-#define MCF_CAN_ERRSTAT_TXRX               (0x00000040)
-#define MCF_CAN_ERRSTAT_IDLE               (0x00000080)
-#define MCF_CAN_ERRSTAT_RXWRN              (0x00000100)
-#define MCF_CAN_ERRSTAT_TXWRN              (0x00000200)
-#define MCF_CAN_ERRSTAT_STFERR             (0x00000400)
-#define MCF_CAN_ERRSTAT_FRMERR             (0x00000800)
-#define MCF_CAN_ERRSTAT_CRCERR             (0x00001000)
-#define MCF_CAN_ERRSTAT_ACKERR             (0x00002000)
-#define MCF_CAN_ERRSTAT_BITERR(x)          (((x)&0x00000003)<<14)
-#define MCF_CAN_ERRSTAT_FLTCONF_ACTIVE     (0x00000000)
-#define MCF_CAN_ERRSTAT_FLTCONF_PASSIVE    (0x00000010)
-#define MCF_CAN_ERRSTAT_FLTCONF_BUSOFF     (0x00000020)
-
-/* Bit definitions and macros for MCF_CAN_IMASK */
-#define MCF_CAN_IMASK_BUF0M                (0x0001)
-#define MCF_CAN_IMASK_BUF1M                (0x0002)
-#define MCF_CAN_IMASK_BUF2M                (0x0004)
-#define MCF_CAN_IMASK_BUF3M                (0x0008)
-#define MCF_CAN_IMASK_BUF4M                (0x0010)
-#define MCF_CAN_IMASK_BUF5M                (0x0020)
-#define MCF_CAN_IMASK_BUF6M                (0x0040)
-#define MCF_CAN_IMASK_BUF7M                (0x0080)
-#define MCF_CAN_IMASK_BUF8M                (0x0100)
-#define MCF_CAN_IMASK_BUF9M                (0x0200)
-#define MCF_CAN_IMASK_BUF10M               (0x0400)
-#define MCF_CAN_IMASK_BUF11M               (0x0800)
-#define MCF_CAN_IMASK_BUF12M               (0x1000)
-#define MCF_CAN_IMASK_BUF13M               (0x2000)
-#define MCF_CAN_IMASK_BUF14M               (0x4000)
-#define MCF_CAN_IMASK_BUF15M               (0x8000)
-
-/* Bit definitions and macros for MCF_CAN_IFLAG */
-#define MCF_CAN_IFLAG_BUF0I                (0x0001)
-#define MCF_CAN_IFLAG_BUF1I                (0x0002)
-#define MCF_CAN_IFLAG_BUF2I                (0x0004)
-#define MCF_CAN_IFLAG_BUF3I                (0x0008)
-#define MCF_CAN_IFLAG_BUF4I                (0x0010)
-#define MCF_CAN_IFLAG_BUF5I                (0x0020)
-#define MCF_CAN_IFLAG_BUF6I                (0x0040)
-#define MCF_CAN_IFLAG_BUF7I                (0x0080)
-#define MCF_CAN_IFLAG_BUF8I                (0x0100)
-#define MCF_CAN_IFLAG_BUF9I                (0x0200)
-#define MCF_CAN_IFLAG_BUF10I               (0x0400)
-#define MCF_CAN_IFLAG_BUF11I               (0x0800)
-#define MCF_CAN_IFLAG_BUF12I               (0x1000)
-#define MCF_CAN_IFLAG_BUF13I               (0x2000)
-#define MCF_CAN_IFLAG_BUF14I               (0x4000)
-#define MCF_CAN_IFLAG_BUF15I               (0x8000)
-
-/********************************************************************/
-
-#endif /* __MCF523X_CAN_H__ */
+/*\r
+ * These files are taken from the MCF523X source code example package\r
+ * which is available on the Freescale website. Freescale explicitly \r
+ * grants the redistribution and modification of these source files.\r
+ * The complete licensing information is available in the file \r
+ * LICENSE_FREESCALE.TXT.\r
+ *\r
+ * File:       mcf523x_can.h\r
+ * Purpose:    Register and bit definitions for the MCF523X\r
+ *\r
+ * Notes:      \r
+ *     \r
+ */\r
+\r
+#ifndef __MCF523X_CAN_H__\r
+#define __MCF523X_CAN_H__\r
+\r
+/*********************************************************************\r
+*\r
+* FlexCAN Module (CAN)\r
+*\r
+*********************************************************************/\r
+\r
+/* Register read/write macros */\r
+#define MCF_CAN_CANMCR0        (*(vuint32*)(void*)(&__IPSBAR[0x1C0000]))\r
+#define MCF_CAN_CANCTRL0       (*(vuint32*)(void*)(&__IPSBAR[0x1C0004]))\r
+#define MCF_CAN_TIMER0         (*(vuint32*)(void*)(&__IPSBAR[0x1C0008]))\r
+#define MCF_CAN_RXGMASK0       (*(vuint32*)(void*)(&__IPSBAR[0x1C0010]))\r
+#define MCF_CAN_RX14MASK0      (*(vuint32*)(void*)(&__IPSBAR[0x1C0014]))\r
+#define MCF_CAN_RX15MASK0      (*(vuint32*)(void*)(&__IPSBAR[0x1C0018]))\r
+#define MCF_CAN_ERRCNT0        (*(vuint32*)(void*)(&__IPSBAR[0x1C001C]))\r
+#define MCF_CAN_ERRSTAT0       (*(vuint32*)(void*)(&__IPSBAR[0x1C0020]))\r
+#define MCF_CAN_IMASK0         (*(vuint16*)(void*)(&__IPSBAR[0x1C002A]))\r
+#define MCF_CAN_IFLAG0         (*(vuint16*)(void*)(&__IPSBAR[0x1C0032]))\r
+#define MCF_CAN_CANMCR1        (*(vuint32*)(void*)(&__IPSBAR[0x1F0000]))\r
+#define MCF_CAN_CANCTRL1       (*(vuint32*)(void*)(&__IPSBAR[0x1F0004]))\r
+#define MCF_CAN_TIMER1         (*(vuint32*)(void*)(&__IPSBAR[0x1F0008]))\r
+#define MCF_CAN_RXGMASK1       (*(vuint32*)(void*)(&__IPSBAR[0x1F0010]))\r
+#define MCF_CAN_RX14MASK1      (*(vuint32*)(void*)(&__IPSBAR[0x1F0014]))\r
+#define MCF_CAN_RX15MASK1      (*(vuint32*)(void*)(&__IPSBAR[0x1F0018]))\r
+#define MCF_CAN_ERRCNT1        (*(vuint32*)(void*)(&__IPSBAR[0x1F001C]))\r
+#define MCF_CAN_ERRSTAT1       (*(vuint32*)(void*)(&__IPSBAR[0x1F0020]))\r
+#define MCF_CAN_IMASK1         (*(vuint16*)(void*)(&__IPSBAR[0x1F002A]))\r
+#define MCF_CAN_IFLAG1         (*(vuint16*)(void*)(&__IPSBAR[0x1F0032]))\r
+#define MCF_CAN_CANMCR(x)      (*(vuint32*)(void*)(&__IPSBAR[0x1C0000+((x)*0x30000)]))\r
+#define MCF_CAN_CANCTRL(x)     (*(vuint32*)(void*)(&__IPSBAR[0x1C0004+((x)*0x30000)]))\r
+#define MCF_CAN_TIMER(x)       (*(vuint32*)(void*)(&__IPSBAR[0x1C0008+((x)*0x30000)]))\r
+#define MCF_CAN_RXGMASK(x)     (*(vuint32*)(void*)(&__IPSBAR[0x1C0010+((x)*0x30000)]))\r
+#define MCF_CAN_RX14MASK(x)    (*(vuint32*)(void*)(&__IPSBAR[0x1C0014+((x)*0x30000)]))\r
+#define MCF_CAN_RX15MASK(x)    (*(vuint32*)(void*)(&__IPSBAR[0x1C0018+((x)*0x30000)]))\r
+#define MCF_CAN_ERRCNT(x)      (*(vuint32*)(void*)(&__IPSBAR[0x1C001C+((x)*0x30000)]))\r
+#define MCF_CAN_ERRSTAT(x)     (*(vuint32*)(void*)(&__IPSBAR[0x1C0020+((x)*0x30000)]))\r
+#define MCF_CAN_IMASK(x)       (*(vuint16*)(void*)(&__IPSBAR[0x1C002A+((x)*0x30000)]))\r
+#define MCF_CAN_IFLAG(x)       (*(vuint16*)(void*)(&__IPSBAR[0x1C0032+((x)*0x30000)]))\r
+\r
+#define MCF_CAN_MBUF0_CTRL(x)          (*(vuint16 *)(void *)(&__IPSBAR[0x1C0080+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF0_TMSTP(x)         (*(vuint16 *)(void *)(&__IPSBAR[0x1C0082+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF0_ID(x)        (*(vuint32 *)(void *)(&__IPSBAR[0x1C0084+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF0_BYTE0(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C0088+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF0_BYTE1(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C0089+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF0_BYTE2(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C008A+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF0_BYTE3(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C008B+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF0_BYTE4(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C008C+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF0_BYTE5(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C008D+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF0_BYTE6(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C008E+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF0_BYTE7(x)      (*(vuint8  *)(void *)(&__IPSBAR[0x1C008F+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF1_CTRL(x)          (*(vuint16 *)(void *)(&__IPSBAR[0x1C0090+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF1_TMSTP(x)         (*(vuint16 *)(void *)(&__IPSBAR[0x1C0092+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF1_ID(x)                    (*(vuint32 *)(void *)(&__IPSBAR[0x1C0094+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF1_BYTE0(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C0098+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF1_BYTE1(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C0099+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF1_BYTE2(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C009A+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF1_BYTE3(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C009B+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF1_BYTE4(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C009C+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF1_BYTE5(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C009D+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF1_BYTE6(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C009E+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF1_BYTE7(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C009F+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF2_CTRL(x)          (*(vuint16 *)(void *)(&__IPSBAR[0x1C00A0+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF2_ID(x)        (*(vuint32 *)(void *)(&__IPSBAR[0x1C00A4+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF2_BYTE0(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00A8+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF2_BYTE1(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00A9+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF2_BYTE2(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00AA+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF2_BYTE3(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00AB+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF2_BYTE4(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00AC+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF2_BYTE5(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00AD+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF2_BYTE6(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00AE+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF2_BYTE7(x)      (*(vuint8  *)(void *)(&__IPSBAR[0x1C00AF+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF3_CTRL(x)          (*(vuint16 *)(void *)(&__IPSBAR[0x1C00B0+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF3_ID(x)                    (*(vuint32 *)(void *)(&__IPSBAR[0x1C00B4+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF3_BYTE0(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00B8+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF3_BYTE1(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00B9+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF3_BYTE2(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00BA+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF3_BYTE3(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00BB+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF3_BYTE4(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00BC+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF3_BYTE5(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00BD+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF3_BYTE6(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00BE+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF3_BYTE7(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00BF+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF4_CTRL(x)          (*(vuint16 *)(void *)(&__IPSBAR[0x1C00C0+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF4_ID(x)        (*(vuint32 *)(void *)(&__IPSBAR[0x1C00C4+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF4_BYTE0(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00C8+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF4_BYTE1(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00C9+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF4_BYTE2(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00CA+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF4_BYTE3(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00CB+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF4_BYTE4(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00CC+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF4_BYTE5(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00CD+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF4_BYTE6(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00CE+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF4_BYTE7(x)      (*(vuint8  *)(void *)(&__IPSBAR[0x1C00CF+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF5_CTRL(x)          (*(vuint16 *)(void *)(&__IPSBAR[0x1C00D0+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF5_ID(x)                    (*(vuint32 *)(void *)(&__IPSBAR[0x1C00D4+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF5_BYTE0(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00D8+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF5_BYTE1(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00D9+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF5_BYTE2(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00DA+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF5_BYTE3(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00DB+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF5_BYTE4(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00DC+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF5_BYTE5(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00DD+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF5_BYTE6(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00DE+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF5_BYTE7(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00DF+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF6_CTRL(x)          (*(vuint16 *)(void *)(&__IPSBAR[0x1C00E0+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF6_ID(x)        (*(vuint32 *)(void *)(&__IPSBAR[0x1C00E4+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF6_BYTE0(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00E8+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF6_BYTE1(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00E9+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF6_BYTE2(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00EA+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF6_BYTE3(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00EB+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF6_BYTE4(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00EC+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF6_BYTE5(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00ED+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF6_BYTE6(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C00EE+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF6_BYTE7(x)      (*(vuint8  *)(void *)(&__IPSBAR[0x1C00EF+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF7_CTRL(x)          (*(vuint16 *)(void *)(&__IPSBAR[0x1C00F0+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF7_ID(x)                    (*(vuint32 *)(void *)(&__IPSBAR[0x1C00F4+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF7_BYTE0(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00F8+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF7_BYTE1(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00F9+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF7_BYTE2(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00FA+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF7_BYTE3(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00FB+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF7_BYTE4(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00FC+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF7_BYTE5(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00FD+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF7_BYTE6(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00FE+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF7_BYTE7(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C00FF+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF8_CTRL(x)          (*(vuint16 *)(void *)(&__IPSBAR[0x1C0100+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF8_ID(x)        (*(vuint32 *)(void *)(&__IPSBAR[0x1C0104+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF8_BYTE0(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C0108+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF8_BYTE1(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C0109+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF8_BYTE2(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C010A+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF8_BYTE3(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C010B+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF8_BYTE4(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C010C+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF8_BYTE5(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C010D+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF8_BYTE6(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C010E+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF8_BYTE7(x)      (*(vuint8  *)(void *)(&__IPSBAR[0x1C010F+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF9_CTRL(x)          (*(vuint16 *)(void *)(&__IPSBAR[0x1C0100+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF9_ID(x)                    (*(vuint32 *)(void *)(&__IPSBAR[0x1C0114+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF9_BYTE0(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C0118+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF9_BYTE1(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C0119+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF9_BYTE2(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C011A+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF9_BYTE3(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C011B+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF9_BYTE4(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C011C+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF9_BYTE5(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C011D+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF9_BYTE6(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C011E+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF9_BYTE7(x)         (*(vuint8  *)(void *)(&__IPSBAR[0x1C011F+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF10_CTRL(x)         (*(vuint16 *)(void *)(&__IPSBAR[0x1C0120+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF10_ID(x)       (*(vuint32 *)(void *)(&__IPSBAR[0x1C0124+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF10_BYTE0(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C0128+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF10_BYTE1(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C0129+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF10_BYTE2(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C012A+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF10_BYTE3(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C012B+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF10_BYTE4(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C012C+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF10_BYTE5(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C012D+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF10_BYTE6(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C012E+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF10_BYTE7(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C012F+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF11_CTRL(x)         (*(vuint16 *)(void *)(&__IPSBAR[0x1C0130+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF11_ID(x)           (*(vuint32 *)(void *)(&__IPSBAR[0x1C0134+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF11_BYTE0(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C0138+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF11_BYTE1(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C0139+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF11_BYTE2(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C013A+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF11_BYTE3(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C013B+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF11_BYTE4(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C013C+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF11_BYTE5(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C013D+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF11_BYTE6(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C013E+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF11_BYTE7(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C013F+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF12_CTRL(x)         (*(vuint16 *)(void *)(&__IPSBAR[0x1C0140+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF12_ID(x)       (*(vuint32 *)(void *)(&__IPSBAR[0x1C0144+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF12_BYTE0(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C0148+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF12_BYTE1(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C0149+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF12_BYTE2(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C014A+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF12_BYTE3(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C014B+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF12_BYTE4(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C014C+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF12_BYTE5(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C014D+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF12_BYTE6(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C014E+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF12_BYTE7(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C014F+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF13_CTRL(x)         (*(vuint16 *)(void *)(&__IPSBAR[0x1C0150+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF13_ID(x)           (*(vuint32 *)(void *)(&__IPSBAR[0x1C0154+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF13_BYTE0(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C0158+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF13_BYTE1(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C0159+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF13_BYTE2(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C015A+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF13_BYTE3(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C015B+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF13_BYTE4(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C015C+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF13_BYTE5(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C015D+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF13_BYTE6(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C015E+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF13_BYTE7(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C015F+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF14_CTRL(x)         (*(vuint16 *)(void *)(&__IPSBAR[0x1C0160+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF14_ID(x)       (*(vuint32 *)(void *)(&__IPSBAR[0x1C0164+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF14_BYTE0(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C0168+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF14_BYTE1(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C0169+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF14_BYTE2(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C016A+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF14_BYTE3(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C016B+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF14_BYTE4(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C016C+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF14_BYTE5(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C016D+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF14_BYTE6(x)            (*(vuint8  *)(void *)(&__IPSBAR[0x1C016E+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF14_BYTE7(x)     (*(vuint8  *)(void *)(&__IPSBAR[0x1C016F+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF15_CTRL(x)         (*(vuint16 *)(void *)(&__IPSBAR[0x1C0170+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF15_ID(x)           (*(vuint32 *)(void *)(&__IPSBAR[0x1C0174+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF15_BYTE0(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C0178+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF15_BYTE1(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C0179+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF15_BYTE2(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C017A+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF15_BYTE3(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C017B+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF15_BYTE4(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C017C+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF15_BYTE5(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C017D+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF15_BYTE6(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C017E+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF15_BYTE7(x)                (*(vuint8  *)(void *)(&__IPSBAR[0x1C017F+((x)*0x30000)]))\r
+                                                                                                                                                                 \r
+                                                                                                                                                                 \r
+#define MCF_CAN_MBUF0_DATAL(x)     (*(vuint32  *)(void *)(&__IPSBAR[0x1C0088+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF0_DATAH(x)     (*(vuint32  *)(void *)(&__IPSBAR[0x1C008C+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF1_DATAL(x)         (*(vuint32  *)(void *)(&__IPSBAR[0x1C0098+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF1_DATAH(x)         (*(vuint32  *)(void *)(&__IPSBAR[0x1C009C+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF2_DATAL(x)     (*(vuint32  *)(void *)(&__IPSBAR[0x1C00A8+((x)*0x30000)]))\r
+#define MCF_CAN_MBUF2_DATAH(x)     (*(vuint32  *)(void *)(&__IPSBAR[0x1C00AC+((x)*0x30000)]))\r
+                                                                                                                                                                 \r
+                                                                                                                                                                 \r
+/* Bit definitions and macros for MCF_CAN_CANMCR */                                                              \r
+#define MCF_CAN_CANMCR_MAXMB(x)            (((x)&0x0000000F)<<0)                                 \r
+#define MCF_CAN_CANMCR_SUPV                (0x00800000)                                                          \r
+#define MCF_CAN_CANMCR_FRZACK              (0x01000000)                                                          \r
+#define MCF_CAN_CANMCR_SOFTRST             (0x02000000)                                                          \r
+#define MCF_CAN_CANMCR_HALT                (0x10000000)                                                          \r
+#define MCF_CAN_CANMCR_FRZ                 (0x40000000)                                                          \r
+#define MCF_CAN_CANMCR_MDIS                (0x80000000)                                                          \r
+\r
+/* Bit definitions and macros for MCF_CAN_CANCTRL */\r
+#define MCF_CAN_CANCTRL_PROPSEG(x)         (((x)&0x00000007)<<0)\r
+#define MCF_CAN_CANCTRL_LOM                (0x00000008)\r
+#define MCF_CAN_CANCTRL_LBUF               (0x00000010)\r
+#define MCF_CAN_CANCTRL_TSYNC              (0x00000020)\r
+#define MCF_CAN_CANCTRL_BOFFREC            (0x00000040)\r
+#define MCF_CAN_CANCTRL_SAMP               (0x00000080)\r
+#define MCF_CAN_CANCTRL_LPB                (0x00001000)\r
+#define MCF_CAN_CANCTRL_CLKSRC             (0x00002000)\r
+#define MCF_CAN_CANCTRL_ERRMSK             (0x00004000)\r
+#define MCF_CAN_CANCTRL_BOFFMSK            (0x00008000)\r
+#define MCF_CAN_CANCTRL_PSEG2(x)           (((x)&0x00000007)<<16)\r
+#define MCF_CAN_CANCTRL_PSEG1(x)           (((x)&0x00000007)<<19)\r
+#define MCF_CAN_CANCTRL_RJW(x)             (((x)&0x00000003)<<22)\r
+#define MCF_CAN_CANCTRL_PRESDIV(x)         (((x)&0x000000FF)<<24)\r
+\r
+/* Bit definitions and macros for MCF_CAN_TIMER */\r
+#define MCF_CAN_TIMER_TIMER(x)             (((x)&0x0000FFFF)<<0)\r
+\r
+/* Bit definitions and macros for MCF_CAN_RXGMASK */\r
+#define MCF_CAN_RXGMASK_MI(x)              (((x)&0x1FFFFFFF)<<0)\r
+\r
+/* Bit definitions and macros for MCF_CAN_RX14MASK */\r
+#define MCF_CAN_RX14MASK_MI(x)             (((x)&0x1FFFFFFF)<<0)\r
+\r
+/* Bit definitions and macros for MCF_CAN_RX15MASK */\r
+#define MCF_CAN_RX15MASK_MI(x)             (((x)&0x1FFFFFFF)<<0)\r
+\r
+/* Bit definitions and macros for MCF_CAN_ERRCNT */\r
+#define MCF_CAN_ERRCNT_TXECTR(x)           (((x)&0x000000FF)<<0)\r
+#define MCF_CAN_ERRCNT_RXECTR(x)           (((x)&0x000000FF)<<8)\r
+\r
+/* Bit definitions and macros for MCF_CAN_ERRSTAT */\r
+#define MCF_CAN_ERRSTAT_WAKINT             (0x00000001)\r
+#define MCF_CAN_ERRSTAT_ERRINT             (0x00000002)\r
+#define MCF_CAN_ERRSTAT_BOFFINT            (0x00000004)\r
+#define MCF_CAN_ERRSTAT_FLTCONF(x)         (((x)&0x00000003)<<4)\r
+#define MCF_CAN_ERRSTAT_TXRX               (0x00000040)\r
+#define MCF_CAN_ERRSTAT_IDLE               (0x00000080)\r
+#define MCF_CAN_ERRSTAT_RXWRN              (0x00000100)\r
+#define MCF_CAN_ERRSTAT_TXWRN              (0x00000200)\r
+#define MCF_CAN_ERRSTAT_STFERR             (0x00000400)\r
+#define MCF_CAN_ERRSTAT_FRMERR             (0x00000800)\r
+#define MCF_CAN_ERRSTAT_CRCERR             (0x00001000)\r
+#define MCF_CAN_ERRSTAT_ACKERR             (0x00002000)\r
+#define MCF_CAN_ERRSTAT_BITERR(x)          (((x)&0x00000003)<<14)\r
+#define MCF_CAN_ERRSTAT_FLTCONF_ACTIVE     (0x00000000)\r
+#define MCF_CAN_ERRSTAT_FLTCONF_PASSIVE    (0x00000010)\r
+#define MCF_CAN_ERRSTAT_FLTCONF_BUSOFF     (0x00000020)\r
+\r
+/* Bit definitions and macros for MCF_CAN_IMASK */\r
+#define MCF_CAN_IMASK_BUF0M                (0x0001)\r
+#define MCF_CAN_IMASK_BUF1M                (0x0002)\r
+#define MCF_CAN_IMASK_BUF2M                (0x0004)\r
+#define MCF_CAN_IMASK_BUF3M                (0x0008)\r
+#define MCF_CAN_IMASK_BUF4M                (0x0010)\r
+#define MCF_CAN_IMASK_BUF5M                (0x0020)\r
+#define MCF_CAN_IMASK_BUF6M                (0x0040)\r
+#define MCF_CAN_IMASK_BUF7M                (0x0080)\r
+#define MCF_CAN_IMASK_BUF8M                (0x0100)\r
+#define MCF_CAN_IMASK_BUF9M                (0x0200)\r
+#define MCF_CAN_IMASK_BUF10M               (0x0400)\r
+#define MCF_CAN_IMASK_BUF11M               (0x0800)\r
+#define MCF_CAN_IMASK_BUF12M               (0x1000)\r
+#define MCF_CAN_IMASK_BUF13M               (0x2000)\r
+#define MCF_CAN_IMASK_BUF14M               (0x4000)\r
+#define MCF_CAN_IMASK_BUF15M               (0x8000)\r
+\r
+/* Bit definitions and macros for MCF_CAN_IFLAG */\r
+#define MCF_CAN_IFLAG_BUF0I                (0x0001)\r
+#define MCF_CAN_IFLAG_BUF1I                (0x0002)\r
+#define MCF_CAN_IFLAG_BUF2I                (0x0004)\r
+#define MCF_CAN_IFLAG_BUF3I                (0x0008)\r
+#define MCF_CAN_IFLAG_BUF4I                (0x0010)\r
+#define MCF_CAN_IFLAG_BUF5I                (0x0020)\r
+#define MCF_CAN_IFLAG_BUF6I                (0x0040)\r
+#define MCF_CAN_IFLAG_BUF7I                (0x0080)\r
+#define MCF_CAN_IFLAG_BUF8I                (0x0100)\r
+#define MCF_CAN_IFLAG_BUF9I                (0x0200)\r
+#define MCF_CAN_IFLAG_BUF10I               (0x0400)\r
+#define MCF_CAN_IFLAG_BUF11I               (0x0800)\r
+#define MCF_CAN_IFLAG_BUF12I               (0x1000)\r
+#define MCF_CAN_IFLAG_BUF13I               (0x2000)\r
+#define MCF_CAN_IFLAG_BUF14I               (0x4000)\r
+#define MCF_CAN_IFLAG_BUF15I               (0x8000)\r
+\r
+/********************************************************************/\r
+\r
+#endif /* __MCF523X_CAN_H__ */\r
index da9bdb79e090e5b9cbd13fa70d0a9f592ec91f9d..dd3b71c6492b91374c33e4ba79397887457e1fc4 100644 (file)
@@ -1,56 +1,56 @@
-/*
- * These files are taken from the MCF523X source code example package
- * which is available on the Freescale website. Freescale explicitly 
- * grants the redistribution and modification of these source files.
- * The complete licensing information is available in the file 
- * LICENSE_FREESCALE.TXT.
- *
- * File:       mcf523x_ccm.h
- * Purpose:    Register and bit definitions for the MCF523X
- *
- * Notes:      
- *     
- */
-
-#ifndef __MCF523X_CCM_H__
-#define __MCF523X_CCM_H__
-
-/*********************************************************************
-*
-* Chip Configuration Module (CCM)
-*
-*********************************************************************/
-
-/* Register read/write macros */
-#define MCF_CCM_CCR     (*(vuint16*)(void*)(&__IPSBAR[0x110004]))
-#define MCF_CCM_LPCR    (*(vuint8 *)(void*)(&__IPSBAR[0x110007]))
-#define MCF_CCM_CIR     (*(vuint16*)(void*)(&__IPSBAR[0x11000A]))
-#define MCF_CCM_RCON    (*(vuint16*)(void*)(&__IPSBAR[0x110008]))
-
-/* Bit definitions and macros for MCF_CCM_CCR */
-#define MCF_CCM_CCR_BMT(x)        (((x)&0x0007)<<0)
-#define MCF_CCM_CCR_BME           (0x0008)
-#define MCF_CCM_CCR_SZEN          (0x0040)
-#define MCF_CCM_CCR_MODE(x)       (((x)&0x0007)<<8)
-
-/* Bit definitions and macros for MCF_CCM_LPCR */
-#define MCF_CCM_LPCR_STPMD(x)     (((x)&0x03)<<3)
-#define MCF_CCM_LPCR_LPMD(x)      (((x)&0x03)<<6)
-#define MCF_CCM_LPCR_LPMD_STOP    (0xC0)
-#define MCF_CCM_LPCR_LPMD_WAIT    (0x80)
-#define MCF_CCM_LPCR_LPMD_DOZE    (0x40)
-#define MCF_CCM_LPCR_LPMD_RUN     (0x00)
-
-/* Bit definitions and macros for MCF_CCM_CIR */
-#define MCF_CCM_CIR_PRN(x)        (((x)&0x003F)<<0)
-#define MCF_CCM_CIR_PIN(x)        (((x)&0x03FF)<<6)
-
-/* Bit definitions and macros for MCF_CCM_RCON */
-#define MCF_CCM_RCON_MODE         (0x0001)
-#define MCF_CCM_RCON_BOOTPS(x)    (((x)&0x0003)<<3)
-#define MCF_CCM_RCON_RLOAD        (0x0020)
-#define MCF_CCM_RCON_RCSC(x)      (((x)&0x0003)<<8)
-
-/********************************************************************/
-
-#endif /* __MCF523X_CCM_H__ */
+/*\r
+ * These files are taken from the MCF523X source code example package\r
+ * which is available on the Freescale website. Freescale explicitly \r
+ * grants the redistribution and modification of these source files.\r
+ * The complete licensing information is available in the file \r
+ * LICENSE_FREESCALE.TXT.\r
+ *\r
+ * File:       mcf523x_ccm.h\r
+ * Purpose:    Register and bit definitions for the MCF523X\r
+ *\r
+ * Notes:      \r
+ *     \r
+ */\r
+\r
+#ifndef __MCF523X_CCM_H__\r
+#define __MCF523X_CCM_H__\r
+\r
+/*********************************************************************\r
+*\r
+* Chip Configuration Module (CCM)\r
+*\r
+*********************************************************************/\r
+\r
+/* Register read/write macros */\r
+#define MCF_CCM_CCR     (*(vuint16*)(void*)(&__IPSBAR[0x110004]))\r
+#define MCF_CCM_LPCR    (*(vuint8 *)(void*)(&__IPSBAR[0x110007]))\r
+#define MCF_CCM_CIR     (*(vuint16*)(void*)(&__IPSBAR[0x11000A]))\r
+#define MCF_CCM_RCON    (*(vuint16*)(void*)(&__IPSBAR[0x110008]))\r
+\r
+/* Bit definitions and macros for MCF_CCM_CCR */\r
+#define MCF_CCM_CCR_BMT(x)        (((x)&0x0007)<<0)\r
+#define MCF_CCM_CCR_BME           (0x0008)\r
+#define MCF_CCM_CCR_SZEN          (0x0040)\r
+#define MCF_CCM_CCR_MODE(x)       (((x)&0x0007)<<8)\r
+\r
+/* Bit definitions and macros for MCF_CCM_LPCR */\r
+#define MCF_CCM_LPCR_STPMD(x)     (((x)&0x03)<<3)\r
+#define MCF_CCM_LPCR_LPMD(x)      (((x)&0x03)<<6)\r
+#define MCF_CCM_LPCR_LPMD_STOP    (0xC0)\r
+#define MCF_CCM_LPCR_LPMD_WAIT    (0x80)\r
+#define MCF_CCM_LPCR_LPMD_DOZE    (0x40)\r
+#define MCF_CCM_LPCR_LPMD_RUN     (0x00)\r
+\r
+/* Bit definitions and macros for MCF_CCM_CIR */\r
+#define MCF_CCM_CIR_PRN(x)        (((x)&0x003F)<<0)\r
+#define MCF_CCM_CIR_PIN(x)        (((x)&0x03FF)<<6)\r
+\r
+/* Bit definitions and macros for MCF_CCM_RCON */\r
+#define MCF_CCM_RCON_MODE         (0x0001)\r
+#define MCF_CCM_RCON_BOOTPS(x)    (((x)&0x0003)<<3)\r
+#define MCF_CCM_RCON_RLOAD        (0x0020)\r
+#define MCF_CCM_RCON_RCSC(x)      (((x)&0x0003)<<8)\r
+\r
+/********************************************************************/\r
+\r
+#endif /* __MCF523X_CCM_H__ */\r
index 27251c80a325569c5405c73a8e8957a4d1da5064..240cdf214c10cc3b16a933d019f028c132227a71 100644 (file)
-/*
- * These files are taken from the MCF523X source code example package
- * which is available on the Freescale website. Freescale explicitly 
- * grants the redistribution and modification of these source files.
- * The complete licensing information is available in the file 
- * LICENSE_FREESCALE.TXT.
- *
- * File:       mcf523x_cs.h
- * Purpose:    Register and bit definitions for the MCF523X
- *
- * Notes:      
- *     
- */
-
-#ifndef __MCF523X_CS_H__
-#define __MCF523X_CS_H__
-
-/*********************************************************************
-*
-* Chip Selects (CS)
-*
-*********************************************************************/
-
-/* Register read/write macros */
-#define MCF_CS_CSAR0      (*(vuint16*)(void*)(&__IPSBAR[0x000080]))
-#define MCF_CS_CSMR0      (*(vuint32*)(void*)(&__IPSBAR[0x000084]))
-#define MCF_CS_CSCR0      (*(vuint16*)(void*)(&__IPSBAR[0x00008A]))
-#define MCF_CS_CSAR1      (*(vuint16*)(void*)(&__IPSBAR[0x00008C]))
-#define MCF_CS_CSMR1      (*(vuint32*)(void*)(&__IPSBAR[0x000090]))
-#define MCF_CS_CSCR1      (*(vuint16*)(void*)(&__IPSBAR[0x000096]))
-#define MCF_CS_CSAR2      (*(vuint16*)(void*)(&__IPSBAR[0x000098]))
-#define MCF_CS_CSMR2      (*(vuint32*)(void*)(&__IPSBAR[0x00009C]))
-#define MCF_CS_CSCR2      (*(vuint16*)(void*)(&__IPSBAR[0x0000A2]))
-#define MCF_CS_CSAR3      (*(vuint16*)(void*)(&__IPSBAR[0x0000A4]))
-#define MCF_CS_CSMR3      (*(vuint32*)(void*)(&__IPSBAR[0x0000A8]))
-#define MCF_CS_CSCR3      (*(vuint16*)(void*)(&__IPSBAR[0x0000AE]))
-#define MCF_CS_CSAR4      (*(vuint16*)(void*)(&__IPSBAR[0x0000B0]))
-#define MCF_CS_CSMR4      (*(vuint32*)(void*)(&__IPSBAR[0x0000B4]))
-#define MCF_CS_CSCR4      (*(vuint16*)(void*)(&__IPSBAR[0x0000BA]))
-#define MCF_CS_CSAR5      (*(vuint16*)(void*)(&__IPSBAR[0x0000BC]))
-#define MCF_CS_CSMR5      (*(vuint32*)(void*)(&__IPSBAR[0x0000C0]))
-#define MCF_CS_CSCR5      (*(vuint16*)(void*)(&__IPSBAR[0x0000C6]))
-#define MCF_CS_CSAR6      (*(vuint16*)(void*)(&__IPSBAR[0x0000C8]))
-#define MCF_CS_CSMR6      (*(vuint32*)(void*)(&__IPSBAR[0x0000CC]))
-#define MCF_CS_CSCR6      (*(vuint16*)(void*)(&__IPSBAR[0x0000D2]))
-#define MCF_CS_CSAR7      (*(vuint16*)(void*)(&__IPSBAR[0x0000D4]))
-#define MCF_CS_CSMR7      (*(vuint32*)(void*)(&__IPSBAR[0x0000D8]))
-#define MCF_CS_CSCR7      (*(vuint16*)(void*)(&__IPSBAR[0x0000DE]))
-#define MCF_CS_CSAR(x)    (*(vuint16*)(void*)(&__IPSBAR[0x000080+((x)*0x00C)]))
-#define MCF_CS_CSMR(x)    (*(vuint32*)(void*)(&__IPSBAR[0x000084+((x)*0x00C)]))
-#define MCF_CS_CSCR(x)    (*(vuint16*)(void*)(&__IPSBAR[0x00008A+((x)*0x00C)]))
-
-/* Bit definitions and macros for MCF_CS_CSAR */
-#define MCF_CS_CSAR_BA(x)        ((uint16)(((x)&0xFFFF0000)>>16))
-
-/* Bit definitions and macros for MCF_CS_CSMR */
-#define MCF_CS_CSMR_V            (0x00000001)
-#define MCF_CS_CSMR_UD           (0x00000002)
-#define MCF_CS_CSMR_UC           (0x00000004)
-#define MCF_CS_CSMR_SD           (0x00000008)
-#define MCF_CS_CSMR_SC           (0x00000010)
-#define MCF_CS_CSMR_CI           (0x00000020)
-#define MCF_CS_CSMR_AM           (0x00000040)
-#define MCF_CS_CSMR_WP           (0x00000100)
-#define MCF_CS_CSMR_BAM(x)       (((x)&0x0000FFFF)<<16)
-#define MCF_CS_CSMR_BAM_4G       (0xFFFF0000)
-#define MCF_CS_CSMR_BAM_2G       (0x7FFF0000)
-#define MCF_CS_CSMR_BAM_1G       (0x3FFF0000)
-#define MCF_CS_CSMR_BAM_1024M    (0x3FFF0000)
-#define MCF_CS_CSMR_BAM_512M     (0x1FFF0000)
-#define MCF_CS_CSMR_BAM_256M     (0x0FFF0000)
-#define MCF_CS_CSMR_BAM_128M     (0x07FF0000)
-#define MCF_CS_CSMR_BAM_64M      (0x03FF0000)
-#define MCF_CS_CSMR_BAM_32M      (0x01FF0000)
-#define MCF_CS_CSMR_BAM_16M      (0x00FF0000)
-#define MCF_CS_CSMR_BAM_8M       (0x007F0000)
-#define MCF_CS_CSMR_BAM_4M       (0x003F0000)
-#define MCF_CS_CSMR_BAM_2M       (0x001F0000)
-#define MCF_CS_CSMR_BAM_1M       (0x000F0000)
-#define MCF_CS_CSMR_BAM_1024K    (0x000F0000)
-#define MCF_CS_CSMR_BAM_512K     (0x00070000)
-#define MCF_CS_CSMR_BAM_256K     (0x00030000)
-#define MCF_CS_CSMR_BAM_128K     (0x00010000)
-#define MCF_CS_CSMR_BAM_64K      (0x00000000)
-
-/* Bit definitions and macros for MCF_CS_CSCR */
-#define MCF_CS_CSCR_SWWS(x)      (((x)&0x0007)<<0)
-#define MCF_CS_CSCR_BSTW         (0x0008)
-#define MCF_CS_CSCR_BSTR         (0x0010)
-#define MCF_CS_CSCR_BEM          (0x0020)
-#define MCF_CS_CSCR_PS(x)        (((x)&0x0003)<<6)
-#define MCF_CS_CSCR_AA           (0x0100)
-#define MCF_CS_CSCR_IWS(x)       (((x)&0x000F)<<10)
-#define MCF_CS_CSCR_SRWS(x)      (((x)&0x0003)<<14)
-#define MCF_CS_CSCR_PS_8         (0x0040)
-#define MCF_CS_CSCR_PS_16        (0x0080)
-#define MCF_CS_CSCR_PS_32        (0x0000)
-
-/********************************************************************/
-
-#endif /* __MCF523X_CS_H__ */
+/*\r
+ * These files are taken from the MCF523X source code example package\r
+ * which is available on the Freescale website. Freescale explicitly \r
+ * grants the redistribution and modification of these source files.\r
+ * The complete licensing information is available in the file \r
+ * LICENSE_FREESCALE.TXT.\r
+ *\r
+ * File:       mcf523x_cs.h\r
+ * Purpose:    Register and bit definitions for the MCF523X\r
+ *\r
+ * Notes:      \r
+ *     \r
+ */\r
+\r
+#ifndef __MCF523X_CS_H__\r
+#define __MCF523X_CS_H__\r
+\r
+/*********************************************************************\r
+*\r
+* Chip Selects (CS)\r
+*\r
+*********************************************************************/\r
+\r
+/* Register read/write macros */\r
+#define MCF_CS_CSAR0      (*(vuint16*)(void*)(&__IPSBAR[0x000080]))\r
+#define MCF_CS_CSMR0      (*(vuint32*)(void*)(&__IPSBAR[0x000084]))\r
+#define MCF_CS_CSCR0      (*(vuint16*)(void*)(&__IPSBAR[0x00008A]))\r
+#define MCF_CS_CSAR1      (*(vuint16*)(void*)(&__IPSBAR[0x00008C]))\r
+#define MCF_CS_CSMR1      (*(vuint32*)(void*)(&__IPSBAR[0x000090]))\r
+#define MCF_CS_CSCR1      (*(vuint16*)(void*)(&__IPSBAR[0x000096]))\r
+#define MCF_CS_CSAR2      (*(vuint16*)(void*)(&__IPSBAR[0x000098]))\r
+#define MCF_CS_CSMR2      (*(vuint32*)(void*)(&__IPSBAR[0x00009C]))\r
+#define MCF_CS_CSCR2      (*(vuint16*)(void*)(&__IPSBAR[0x0000A2]))\r
+#define MCF_CS_CSAR3      (*(vuint16*)(void*)(&__IPSBAR[0x0000A4]))\r
+#define MCF_CS_CSMR3      (*(vuint32*)(void*)(&__IPSBAR[0x0000A8]))\r
+#define MCF_CS_CSCR3      (*(vuint16*)(void*)(&__IPSBAR[0x0000AE]))\r
+#define MCF_CS_CSAR4      (*(vuint16*)(void*)(&__IPSBAR[0x0000B0]))\r
+#define MCF_CS_CSMR4      (*(vuint32*)(void*)(&__IPSBAR[0x0000B4]))\r
+#define MCF_CS_CSCR4      (*(vuint16*)(void*)(&__IPSBAR[0x0000BA]))\r
+#define MCF_CS_CSAR5      (*(vuint16*)(void*)(&__IPSBAR[0x0000BC]))\r
+#define MCF_CS_CSMR5      (*(vuint32*)(void*)(&__IPSBAR[0x0000C0]))\r
+#define MCF_CS_CSCR5      (*(vuint16*)(void*)(&__IPSBAR[0x0000C6]))\r
+#define MCF_CS_CSAR6      (*(vuint16*)(void*)(&__IPSBAR[0x0000C8]))\r
+#define MCF_CS_CSMR6      (*(vuint32*)(void*)(&__IPSBAR[0x0000CC]))\r
+#define MCF_CS_CSCR6      (*(vuint16*)(void*)(&__IPSBAR[0x0000D2]))\r
+#define MCF_CS_CSAR7      (*(vuint16*)(void*)(&__IPSBAR[0x0000D4]))\r
+#define MCF_CS_CSMR7      (*(vuint32*)(void*)(&__IPSBAR[0x0000D8]))\r
+#define MCF_CS_CSCR7      (*(vuint16*)(void*)(&__IPSBAR[0x0000DE]))\r
+#define MCF_CS_CSAR(x)    (*(vuint16*)(void*)(&__IPSBAR[0x000080+((x)*0x00C)]))\r
+#define MCF_CS_CSMR(x)    (*(vuint32*)(void*)(&__IPSBAR[0x000084+((x)*0x00C)]))\r
+#define MCF_CS_CSCR(x)    (*(vuint16*)(void*)(&__IPSBAR[0x00008A+((x)*0x00C)]))\r
+\r
+/* Bit definitions and macros for MCF_CS_CSAR */\r
+#define MCF_CS_CSAR_BA(x)        ((uint16)(((x)&0xFFFF0000)>>16))\r
+\r
+/* Bit definitions and macros for MCF_CS_CSMR */\r
+#define MCF_CS_CSMR_V            (0x00000001)\r
+#define MCF_CS_CSMR_UD           (0x00000002)\r
+#define MCF_CS_CSMR_UC           (0x00000004)\r
+#define MCF_CS_CSMR_SD           (0x00000008)\r
+#define MCF_CS_CSMR_SC           (0x00000010)\r
+#define MCF_CS_CSMR_CI           (0x00000020)\r
+#define MCF_CS_CSMR_AM           (0x00000040)\r
+#define MCF_CS_CSMR_WP           (0x00000100)\r
+#define MCF_CS_CSMR_BAM(x)       (((x)&0x0000FFFF)<<16)\r
+#define MCF_CS_CSMR_BAM_4G       (0xFFFF0000)\r
+#define MCF_CS_CSMR_BAM_2G       (0x7FFF0000)\r
+#define MCF_CS_CSMR_BAM_1G       (0x3FFF0000)\r
+#define MCF_CS_CSMR_BAM_1024M    (0x3FFF0000)\r
+#define MCF_CS_CSMR_BAM_512M     (0x1FFF0000)\r
+#define MCF_CS_CSMR_BAM_256M     (0x0FFF0000)\r
+#define MCF_CS_CSMR_BAM_128M     (0x07FF0000)\r
+#define MCF_CS_CSMR_BAM_64M      (0x03FF0000)\r
+#define MCF_CS_CSMR_BAM_32M      (0x01FF0000)\r
+#define MCF_CS_CSMR_BAM_16M      (0x00FF0000)\r
+#define MCF_CS_CSMR_BAM_8M       (0x007F0000)\r
+#define MCF_CS_CSMR_BAM_4M       (0x003F0000)\r
+#define MCF_CS_CSMR_BAM_2M       (0x001F0000)\r
+#define MCF_CS_CSMR_BAM_1M       (0x000F0000)\r
+#define MCF_CS_CSMR_BAM_1024K    (0x000F0000)\r
+#define MCF_CS_CSMR_BAM_512K     (0x00070000)\r
+#define MCF_CS_CSMR_BAM_256K     (0x00030000)\r
+#define MCF_CS_CSMR_BAM_128K     (0x00010000)\r
+#define MCF_CS_CSMR_BAM_64K      (0x00000000)\r
+\r
+/* Bit definitions and macros for MCF_CS_CSCR */\r
+#define MCF_CS_CSCR_SWWS(x)      (((x)&0x0007)<<0)\r
+#define MCF_CS_CSCR_BSTW         (0x0008)\r
+#define MCF_CS_CSCR_BSTR         (0x0010)\r
+#define MCF_CS_CSCR_BEM          (0x0020)\r
+#define MCF_CS_CSCR_PS(x)        (((x)&0x0003)<<6)\r
+#define MCF_CS_CSCR_AA           (0x0100)\r
+#define MCF_CS_CSCR_IWS(x)       (((x)&0x000F)<<10)\r
+#define MCF_CS_CSCR_SRWS(x)      (((x)&0x0003)<<14)\r
+#define MCF_CS_CSCR_PS_8         (0x0040)\r
+#define MCF_CS_CSCR_PS_16        (0x0080)\r
+#define MCF_CS_CSCR_PS_32        (0x0000)\r
+\r
+/********************************************************************/\r
+\r
+#endif /* __MCF523X_CS_H__ */\r
index 5629ebfa47da6e4602da99098c27040a13202feb..9ee8d7c1c1e1c02ecf92e374f7147ae9e588f3e4 100644 (file)
@@ -1,92 +1,92 @@
-/*
- * These files are taken from the MCF523X source code example package
- * which is available on the Freescale website. Freescale explicitly 
- * grants the redistribution and modification of these source files.
- * The complete licensing information is available in the file 
- * LICENSE_FREESCALE.TXT.
- *
- * File:       mcf523x_eport.h
- * Purpose:    Register and bit definitions for the MCF523X
- *
- * Notes:      
- *     
- */
-
-#ifndef __MCF523X_EPORT_H__
-#define __MCF523X_EPORT_H__
-
-/*********************************************************************
-*
-* Edge Port Module (EPORT)
-*
-*********************************************************************/
-
-/* Register read/write macros */
-#define MCF_EPORT_EPPAR    (*(vuint16*)(void*)(&__IPSBAR[0x130000]))
-#define MCF_EPORT_EPDDR    (*(vuint8 *)(void*)(&__IPSBAR[0x130002]))
-#define MCF_EPORT_EPIER    (*(vuint8 *)(void*)(&__IPSBAR[0x130003]))
-#define MCF_EPORT_EPDR     (*(vuint8 *)(void*)(&__IPSBAR[0x130004]))
-#define MCF_EPORT_EPPDR    (*(vuint8 *)(void*)(&__IPSBAR[0x130005]))
-#define MCF_EPORT_EPFR     (*(vuint8 *)(void*)(&__IPSBAR[0x130006]))
-
-/* Bit definitions and macros for MCF_EPORT_EPPAR */
-#define MCF_EPORT_EPPAR_EPPA1(x)         (((x)&0x0003)<<2)
-#define MCF_EPORT_EPPAR_EPPA2(x)         (((x)&0x0003)<<4)
-#define MCF_EPORT_EPPAR_EPPA3(x)         (((x)&0x0003)<<6)
-#define MCF_EPORT_EPPAR_EPPA4(x)         (((x)&0x0003)<<8)
-#define MCF_EPORT_EPPAR_EPPA5(x)         (((x)&0x0003)<<10)
-#define MCF_EPORT_EPPAR_EPPA6(x)         (((x)&0x0003)<<12)
-#define MCF_EPORT_EPPAR_EPPA7(x)         (((x)&0x0003)<<14)
-#define MCF_EPORT_EPPAR_EPPAx_LEVEL      (0)
-#define MCF_EPORT_EPPAR_EPPAx_RISING     (1)
-#define MCF_EPORT_EPPAR_EPPAx_FALLING    (2)
-#define MCF_EPORT_EPPAR_EPPAx_BOTH       (3)
-
-/* Bit definitions and macros for MCF_EPORT_EPDDR */
-#define MCF_EPORT_EPDDR_EPDD1            (0x02)
-#define MCF_EPORT_EPDDR_EPDD2            (0x04)
-#define MCF_EPORT_EPDDR_EPDD3            (0x08)
-#define MCF_EPORT_EPDDR_EPDD4            (0x10)
-#define MCF_EPORT_EPDDR_EPDD5            (0x20)
-#define MCF_EPORT_EPDDR_EPDD6            (0x40)
-#define MCF_EPORT_EPDDR_EPDD7            (0x80)
-
-/* Bit definitions and macros for MCF_EPORT_EPIER */
-#define MCF_EPORT_EPIER_EPIE1            (0x02)
-#define MCF_EPORT_EPIER_EPIE2            (0x04)
-#define MCF_EPORT_EPIER_EPIE3            (0x08)
-#define MCF_EPORT_EPIER_EPIE4            (0x10)
-#define MCF_EPORT_EPIER_EPIE5            (0x20)
-#define MCF_EPORT_EPIER_EPIE6            (0x40)
-#define MCF_EPORT_EPIER_EPIE7            (0x80)
-
-/* Bit definitions and macros for MCF_EPORT_EPDR */
-#define MCF_EPORT_EPDR_EPD1              (0x02)
-#define MCF_EPORT_EPDR_EPD2              (0x04)
-#define MCF_EPORT_EPDR_EPD3              (0x08)
-#define MCF_EPORT_EPDR_EPD4              (0x10)
-#define MCF_EPORT_EPDR_EPD5              (0x20)
-#define MCF_EPORT_EPDR_EPD6              (0x40)
-#define MCF_EPORT_EPDR_EPD7              (0x80)
-
-/* Bit definitions and macros for MCF_EPORT_EPPDR */
-#define MCF_EPORT_EPPDR_EPPD1            (0x02)
-#define MCF_EPORT_EPPDR_EPPD2            (0x04)
-#define MCF_EPORT_EPPDR_EPPD3            (0x08)
-#define MCF_EPORT_EPPDR_EPPD4            (0x10)
-#define MCF_EPORT_EPPDR_EPPD5            (0x20)
-#define MCF_EPORT_EPPDR_EPPD6            (0x40)
-#define MCF_EPORT_EPPDR_EPPD7            (0x80)
-
-/* Bit definitions and macros for MCF_EPORT_EPFR */
-#define MCF_EPORT_EPFR_EPF1              (0x02)
-#define MCF_EPORT_EPFR_EPF2              (0x04)
-#define MCF_EPORT_EPFR_EPF3              (0x08)
-#define MCF_EPORT_EPFR_EPF4              (0x10)
-#define MCF_EPORT_EPFR_EPF5              (0x20)
-#define MCF_EPORT_EPFR_EPF6              (0x40)
-#define MCF_EPORT_EPFR_EPF7              (0x80)
-
-/********************************************************************/
-
-#endif /* __MCF523X_EPORT_H__ */
+/*\r
+ * These files are taken from the MCF523X source code example package\r
+ * which is available on the Freescale website. Freescale explicitly \r
+ * grants the redistribution and modification of these source files.\r
+ * The complete licensing information is available in the file \r
+ * LICENSE_FREESCALE.TXT.\r
+ *\r
+ * File:       mcf523x_eport.h\r
+ * Purpose:    Register and bit definitions for the MCF523X\r
+ *\r
+ * Notes:      \r
+ *     \r
+ */\r
+\r
+#ifndef __MCF523X_EPORT_H__\r
+#define __MCF523X_EPORT_H__\r
+\r
+/*********************************************************************\r
+*\r
+* Edge Port Module (EPORT)\r
+*\r
+*********************************************************************/\r
+\r
+/* Register read/write macros */\r
+#define MCF_EPORT_EPPAR    (*(vuint16*)(void*)(&__IPSBAR[0x130000]))\r
+#define MCF_EPORT_EPDDR    (*(vuint8 *)(void*)(&__IPSBAR[0x130002]))\r
+#define MCF_EPORT_EPIER    (*(vuint8 *)(void*)(&__IPSBAR[0x130003]))\r
+#define MCF_EPORT_EPDR     (*(vuint8 *)(void*)(&__IPSBAR[0x130004]))\r
+#define MCF_EPORT_EPPDR    (*(vuint8 *)(void*)(&__IPSBAR[0x130005]))\r
+#define MCF_EPORT_EPFR     (*(vuint8 *)(void*)(&__IPSBAR[0x130006]))\r
+\r
+/* Bit definitions and macros for MCF_EPORT_EPPAR */\r
+#define MCF_EPORT_EPPAR_EPPA1(x)         (((x)&0x0003)<<2)\r
+#define MCF_EPORT_EPPAR_EPPA2(x)         (((x)&0x0003)<<4)\r
+#define MCF_EPORT_EPPAR_EPPA3(x)         (((x)&0x0003)<<6)\r
+#define MCF_EPORT_EPPAR_EPPA4(x)         (((x)&0x0003)<<8)\r
+#define MCF_EPORT_EPPAR_EPPA5(x)         (((x)&0x0003)<<10)\r
+#define MCF_EPORT_EPPAR_EPPA6(x)         (((x)&0x0003)<<12)\r
+#define MCF_EPORT_EPPAR_EPPA7(x)         (((x)&0x0003)<<14)\r
+#define MCF_EPORT_EPPAR_EPPAx_LEVEL      (0)\r
+#define MCF_EPORT_EPPAR_EPPAx_RISING     (1)\r
+#define MCF_EPORT_EPPAR_EPPAx_FALLING    (2)\r
+#define MCF_EPORT_EPPAR_EPPAx_BOTH       (3)\r
+\r
+/* Bit definitions and macros for MCF_EPORT_EPDDR */\r
+#define MCF_EPORT_EPDDR_EPDD1            (0x02)\r
+#define MCF_EPORT_EPDDR_EPDD2            (0x04)\r
+#define MCF_EPORT_EPDDR_EPDD3            (0x08)\r
+#define MCF_EPORT_EPDDR_EPDD4            (0x10)\r
+#define MCF_EPORT_EPDDR_EPDD5            (0x20)\r
+#define MCF_EPORT_EPDDR_EPDD6            (0x40)\r
+#define MCF_EPORT_EPDDR_EPDD7            (0x80)\r
+\r
+/* Bit definitions and macros for MCF_EPORT_EPIER */\r
+#define MCF_EPORT_EPIER_EPIE1            (0x02)\r
+#define MCF_EPORT_EPIER_EPIE2            (0x04)\r
+#define MCF_EPORT_EPIER_EPIE3            (0x08)\r
+#define MCF_EPORT_EPIER_EPIE4            (0x10)\r
+#define MCF_EPORT_EPIER_EPIE5            (0x20)\r
+#define MCF_EPORT_EPIER_EPIE6            (0x40)\r
+#define MCF_EPORT_EPIER_EPIE7            (0x80)\r
+\r
+/* Bit definitions and macros for MCF_EPORT_EPDR */\r
+#define MCF_EPORT_EPDR_EPD1              (0x02)\r
+#define MCF_EPORT_EPDR_EPD2              (0x04)\r
+#define MCF_EPORT_EPDR_EPD3              (0x08)\r
+#define MCF_EPORT_EPDR_EPD4              (0x10)\r
+#define MCF_EPORT_EPDR_EPD5              (0x20)\r
+#define MCF_EPORT_EPDR_EPD6              (0x40)\r
+#define MCF_EPORT_EPDR_EPD7              (0x80)\r
+\r
+/* Bit definitions and macros for MCF_EPORT_EPPDR */\r
+#define MCF_EPORT_EPPDR_EPPD1            (0x02)\r
+#define MCF_EPORT_EPPDR_EPPD2            (0x04)\r
+#define MCF_EPORT_EPPDR_EPPD3            (0x08)\r
+#define MCF_EPORT_EPPDR_EPPD4            (0x10)\r
+#define MCF_EPORT_EPPDR_EPPD5            (0x20)\r
+#define MCF_EPORT_EPPDR_EPPD6            (0x40)\r
+#define MCF_EPORT_EPPDR_EPPD7            (0x80)\r
+\r
+/* Bit definitions and macros for MCF_EPORT_EPFR */\r
+#define MCF_EPORT_EPFR_EPF1              (0x02)\r
+#define MCF_EPORT_EPFR_EPF2              (0x04)\r
+#define MCF_EPORT_EPFR_EPF3              (0x08)\r
+#define MCF_EPORT_EPFR_EPF4              (0x10)\r
+#define MCF_EPORT_EPFR_EPF5              (0x20)\r
+#define MCF_EPORT_EPFR_EPF6              (0x40)\r
+#define MCF_EPORT_EPFR_EPF7              (0x80)\r
+\r
+/********************************************************************/\r
+\r
+#endif /* __MCF523X_EPORT_H__ */\r
index 91075acf887ff54525d998177f9e6b273bb4c725..5a0d9ca749491507ce4d991fefd7a2f7f34f4329 100644 (file)
-/*
- * These files are taken from the MCF523X source code example package
- * which is available on the Freescale website. Freescale explicitly 
- * grants the redistribution and modification of these source files.
- * The complete licensing information is available in the file 
- * LICENSE_FREESCALE.TXT.
- *
- * File:       mcf523x_etpu.h
- * Purpose:    Register and bit definitions for the MCF523X
- *
- * Notes:      
- *     
- */
-
-#ifndef __MCF523X_ETPU_H__
-#define __MCF523X_ETPU_H__
-
-/*********************************************************************
-*
-* enhanced Time Processor Unit (ETPU)
-*
-*********************************************************************/
-
-/* Register read/write macros */
-#define MCF_ETPU_EMCR          (*(vuint32*)(void*)(&__IPSBAR[0x1D0000]))
-#define MCF_ETPU_ECDCR         (*(vuint32*)(void*)(&__IPSBAR[0x1D0004]))
-#define MCF_ETPU_EMISCCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D000C]))
-#define MCF_ETPU_ESCMODR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0010]))
-#define MCF_ETPU_EECR          (*(vuint32*)(void*)(&__IPSBAR[0x1D0014]))
-#define MCF_ETPU_ETBCR         (*(vuint32*)(void*)(&__IPSBAR[0x1D0020]))
-#define MCF_ETPU_ETB1R         (*(vuint32*)(void*)(&__IPSBAR[0x1D0024]))
-#define MCF_ETPU_ETB2R         (*(vuint32*)(void*)(&__IPSBAR[0x1D0028]))
-#define MCF_ETPU_EREDCR        (*(vuint32*)(void*)(&__IPSBAR[0x1D002C]))
-#define MCF_ETPU_ECISR         (*(vuint32*)(void*)(&__IPSBAR[0x1D0200]))
-#define MCF_ETPU_ECDTRSR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0210]))
-#define MCF_ETPU_ECIOSR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0220]))
-#define MCF_ETPU_ECDTROSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D0230]))
-#define MCF_ETPU_ECIER         (*(vuint32*)(void*)(&__IPSBAR[0x1D0240]))
-#define MCF_ETPU_ECDTRER       (*(vuint32*)(void*)(&__IPSBAR[0x1D0250]))
-#define MCF_ETPU_ECPSSR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0280]))
-#define MCF_ETPU_ECSSR         (*(vuint32*)(void*)(&__IPSBAR[0x1D0290]))
-#define MCF_ETPU_EC0SCR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0404]))
-#define MCF_ETPU_EC1SCR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0414]))
-#define MCF_ETPU_EC2SCR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0424]))
-#define MCF_ETPU_EC3SCR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0434]))
-#define MCF_ETPU_EC4SCR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0444]))
-#define MCF_ETPU_EC5SCR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0454]))
-#define MCF_ETPU_EC6SCR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0464]))
-#define MCF_ETPU_EC7SCR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0474]))
-#define MCF_ETPU_EC8SCR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0484]))
-#define MCF_ETPU_EC9SCR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0494]))
-#define MCF_ETPU_EC10SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D04A4]))
-#define MCF_ETPU_EC11SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D04B4]))
-#define MCF_ETPU_EC12SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D04C4]))
-#define MCF_ETPU_EC13SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D04D4]))
-#define MCF_ETPU_EC14SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D04E4]))
-#define MCF_ETPU_EC15SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D04F4]))
-#define MCF_ETPU_EC16SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0504]))
-#define MCF_ETPU_EC17SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0514]))
-#define MCF_ETPU_EC18SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0524]))
-#define MCF_ETPU_EC19SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0534]))
-#define MCF_ETPU_EC20SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0544]))
-#define MCF_ETPU_EC21SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0554]))
-#define MCF_ETPU_EC22SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0564]))
-#define MCF_ETPU_EC23SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0574]))
-#define MCF_ETPU_EC24SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0584]))
-#define MCF_ETPU_EC25SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0594]))
-#define MCF_ETPU_EC26SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D05A4]))
-#define MCF_ETPU_EC27SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D05B4]))
-#define MCF_ETPU_EC28SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D05C4]))
-#define MCF_ETPU_EC29SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D05D4]))
-#define MCF_ETPU_EC30SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D05E4]))
-#define MCF_ETPU_EC31SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D05F4]))
-#define MCF_ETPU_ECnSCR(x)     (*(vuint32*)(void*)(&__IPSBAR[0x1D0404+((x)*0x010)]))
-#define MCF_ETPU_EC0CR         (*(vuint32*)(void*)(&__IPSBAR[0x1D0400]))
-#define MCF_ETPU_EC1CR         (*(vuint32*)(void*)(&__IPSBAR[0x1D0410]))
-#define MCF_ETPU_EC2CR         (*(vuint32*)(void*)(&__IPSBAR[0x1D0420]))
-#define MCF_ETPU_EC3CR         (*(vuint32*)(void*)(&__IPSBAR[0x1D0430]))
-#define MCF_ETPU_EC4CR         (*(vuint32*)(void*)(&__IPSBAR[0x1D0440]))
-#define MCF_ETPU_EC5CR         (*(vuint32*)(void*)(&__IPSBAR[0x1D0450]))
-#define MCF_ETPU_EC6CR         (*(vuint32*)(void*)(&__IPSBAR[0x1D0460]))
-#define MCF_ETPU_EC7CR         (*(vuint32*)(void*)(&__IPSBAR[0x1D0470]))
-#define MCF_ETPU_EC8CR         (*(vuint32*)(void*)(&__IPSBAR[0x1D0480]))
-#define MCF_ETPU_EC9CR         (*(vuint32*)(void*)(&__IPSBAR[0x1D0490]))
-#define MCF_ETPU_EC10CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D04A0]))
-#define MCF_ETPU_EC11CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D04B0]))
-#define MCF_ETPU_EC12CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D04C0]))
-#define MCF_ETPU_EC13CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D04D0]))
-#define MCF_ETPU_EC14CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D04E0]))
-#define MCF_ETPU_EC15CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D04F0]))
-#define MCF_ETPU_EC16CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0500]))
-#define MCF_ETPU_EC17CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0510]))
-#define MCF_ETPU_EC18CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0520]))
-#define MCF_ETPU_EC19CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0530]))
-#define MCF_ETPU_EC20CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0540]))
-#define MCF_ETPU_EC21CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0550]))
-#define MCF_ETPU_EC22CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0560]))
-#define MCF_ETPU_EC23CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0570]))
-#define MCF_ETPU_EC24CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0580]))
-#define MCF_ETPU_EC25CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0590]))
-#define MCF_ETPU_EC26CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D05A0]))
-#define MCF_ETPU_EC27CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D05B0]))
-#define MCF_ETPU_EC28CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D05C0]))
-#define MCF_ETPU_EC29CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D05D0]))
-#define MCF_ETPU_EC30CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D05E0]))
-#define MCF_ETPU_EC31CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D05F0]))
-#define MCF_ETPU_ECnCR(x)      (*(vuint32*)(void*)(&__IPSBAR[0x1D0400+((x)*0x010)]))
-#define MCF_ETPU_EC0HSSR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0408]))
-#define MCF_ETPU_EC1HSSR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0418]))
-#define MCF_ETPU_EC2HSSR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0428]))
-#define MCF_ETPU_EC3HSSR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0438]))
-#define MCF_ETPU_EC4HSSR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0448]))
-#define MCF_ETPU_EC5HSSR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0458]))
-#define MCF_ETPU_EC6HSSR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0468]))
-#define MCF_ETPU_EC7HSSR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0478]))
-#define MCF_ETPU_EC8HSSR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0488]))
-#define MCF_ETPU_EC9HSSR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0498]))
-#define MCF_ETPU_EC10HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D04A8]))
-#define MCF_ETPU_EC11HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D04B8]))
-#define MCF_ETPU_EC12HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D04C8]))
-#define MCF_ETPU_EC13HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D04D8]))
-#define MCF_ETPU_EC14HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D04E8]))
-#define MCF_ETPU_EC15HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D04F8]))
-#define MCF_ETPU_EC16HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D0508]))
-#define MCF_ETPU_EC17HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D0518]))
-#define MCF_ETPU_EC18HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D0528]))
-#define MCF_ETPU_EC19HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D0538]))
-#define MCF_ETPU_EC20HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D0548]))
-#define MCF_ETPU_EC21HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D0558]))
-#define MCF_ETPU_EC22HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D0568]))
-#define MCF_ETPU_EC23HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D0578]))
-#define MCF_ETPU_EC24HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D0588]))
-#define MCF_ETPU_EC25HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D0598]))
-#define MCF_ETPU_EC26HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D05A8]))
-#define MCF_ETPU_EC27HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D05B8]))
-#define MCF_ETPU_EC28HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D05C8]))
-#define MCF_ETPU_EC29HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D05D8]))
-#define MCF_ETPU_EC30HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D05E8]))
-#define MCF_ETPU_EC31HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D05F8]))
-#define MCF_ETPU_ECnHSSR(x)    (*(vuint32*)(void*)(&__IPSBAR[0x1D0408+((x)*0x010)]))
-
-/* Bit definitions and macros for MCF_ETPU_EMCR */
-#define MCF_ETPU_EMCR_GTBE               (0x00000001)
-#define MCF_ETPU_EMCR_VIS                (0x00000040)
-#define MCF_ETPU_EMCR_SCMMISEN           (0x00000200)
-#define MCF_ETPU_EMCR_SCMMISF            (0x00000400)
-#define MCF_ETPU_EMCR_SCMSIZE(x)         (((x)&0x0000001F)<<16)
-#define MCF_ETPU_EMCR_ILF2               (0x01000000)
-#define MCF_ETPU_EMCR_ILF1               (0x02000000)
-#define MCF_ETPU_EMCR_MGE2               (0x04000000)
-#define MCF_ETPU_EMCR_MGE1               (0x08000000)
-#define MCF_ETPU_EMCR_GEC                (0x80000000)
-
-/* Bit definitions and macros for MCF_ETPU_ECDCR */
-#define MCF_ETPU_ECDCR_PARM1(x)          (((x)&0x0000007F)<<0)
-#define MCF_ETPU_ECDCR_WR                (0x00000080)
-#define MCF_ETPU_ECDCR_PARM0(x)          (((x)&0x0000007F)<<8)
-#define MCF_ETPU_ECDCR_PWIDTH            (0x00008000)
-#define MCF_ETPU_ECDCR_PBASE(x)          (((x)&0x000003FF)<<16)
-#define MCF_ETPU_ECDCR_CTBASE(x)         (((x)&0x0000001F)<<26)
-#define MCF_ETPU_ECDCR_STS               (0x80000000)
-
-/* Bit definitions and macros for MCF_ETPU_EECR */
-#define MCF_ETPU_EECR_ETB(x)             (((x)&0x0000001F)<<0)
-#define MCF_ETPU_EECR_CDFC(x)            (((x)&0x00000003)<<14)
-#define MCF_ETPU_EECR_FPSK(x)            (((x)&0x00000007)<<16)
-#define MCF_ETPU_EECR_HLTF               (0x00800000)
-#define MCF_ETPU_EECR_STF                (0x10000000)
-#define MCF_ETPU_EECR_MDIS               (0x40000000)
-#define MCF_ETPU_EECR_FEND               (0x80000000)
-
-/* Bit definitions and macros for MCF_ETPU_ETBCR */
-#define MCF_ETPU_ETBCR_TCR1P(x)          (((x)&0x000000FF)<<0)
-#define MCF_ETPU_ETBCR_TCR1CTL(x)        (((x)&0x00000003)<<14)
-#define MCF_ETPU_ETBCR_TCR2P(x)          (((x)&0x0000003F)<<16)
-#define MCF_ETPU_ETBCR_AM                (0x02000000)
-#define MCF_ETPU_ETBCR_TCRCF(x)          (((x)&0x00000003)<<27)
-#define MCF_ETPU_ETBCR_TCR2CTL(x)        (((x)&0x00000007)<<29)
-
-/* Bit definitions and macros for MCF_ETPU_ETB1R */
-#define MCF_ETPU_ETB1R_TCR1(x)           (((x)&0x00FFFFFF)<<0)
-
-/* Bit definitions and macros for MCF_ETPU_ETB2R */
-#define MCF_ETPU_ETB2R_TCR2(x)           (((x)&0x00FFFFFF)<<0)
-
-/* Bit definitions and macros for MCF_ETPU_EREDCR */
-#define MCF_ETPU_EREDCR_SRV2(x)          (((x)&0x0000000F)<<0)
-#define MCF_ETPU_EREDCR_SERVER_ID2(x)    (((x)&0x0000000F)<<8)
-#define MCF_ETPU_EREDCR_RSC2             (0x00004000)
-#define MCF_ETPU_EREDCR_REN2             (0x00008000)
-#define MCF_ETPU_EREDCR_SRV1(x)          (((x)&0x0000000F)<<16)
-#define MCF_ETPU_EREDCR_SERVER_ID1(x)    (((x)&0x0000000F)<<24)
-#define MCF_ETPU_EREDCR_RSC1             (0x40000000)
-#define MCF_ETPU_EREDCR_REN1             (0x80000000)
-
-/* Bit definitions and macros for MCF_ETPU_ECISR */
-#define MCF_ETPU_ECISR_CIS0              (0x00000001)
-#define MCF_ETPU_ECISR_CIS1              (0x00000002)
-#define MCF_ETPU_ECISR_CIS2              (0x00000004)
-#define MCF_ETPU_ECISR_CIS3              (0x00000008)
-#define MCF_ETPU_ECISR_CIS4              (0x00000010)
-#define MCF_ETPU_ECISR_CIS5              (0x00000020)
-#define MCF_ETPU_ECISR_CIS6              (0x00000040)
-#define MCF_ETPU_ECISR_CIS7              (0x00000080)
-#define MCF_ETPU_ECISR_CIS8              (0x00000100)
-#define MCF_ETPU_ECISR_CIS9              (0x00000200)
-#define MCF_ETPU_ECISR_CIS10             (0x00000400)
-#define MCF_ETPU_ECISR_CIS11             (0x00000800)
-#define MCF_ETPU_ECISR_CIS12             (0x00001000)
-#define MCF_ETPU_ECISR_CIS13             (0x00002000)
-#define MCF_ETPU_ECISR_CIS14             (0x00004000)
-#define MCF_ETPU_ECISR_CIS15             (0x00008000)
-#define MCF_ETPU_ECISR_CIS16             (0x00010000)
-#define MCF_ETPU_ECISR_CIS17             (0x00020000)
-#define MCF_ETPU_ECISR_CIS18             (0x00040000)
-#define MCF_ETPU_ECISR_CIS19             (0x00080000)
-#define MCF_ETPU_ECISR_CIS20             (0x00100000)
-#define MCF_ETPU_ECISR_CIS21             (0x00200000)
-#define MCF_ETPU_ECISR_CIS22             (0x00400000)
-#define MCF_ETPU_ECISR_CIS23             (0x00800000)
-#define MCF_ETPU_ECISR_CIS24             (0x01000000)
-#define MCF_ETPU_ECISR_CIS25             (0x02000000)
-#define MCF_ETPU_ECISR_CIS26             (0x04000000)
-#define MCF_ETPU_ECISR_CIS27             (0x08000000)
-#define MCF_ETPU_ECISR_CIS28             (0x10000000)
-#define MCF_ETPU_ECISR_CIS29             (0x20000000)
-#define MCF_ETPU_ECISR_CIS30             (0x40000000)
-#define MCF_ETPU_ECISR_CIS31             (0x80000000)
-
-/* Bit definitions and macros for MCF_ETPU_ECDTRSR */
-#define MCF_ETPU_ECDTRSR_DTRS0           (0x00000001)
-#define MCF_ETPU_ECDTRSR_DTRS1           (0x00000002)
-#define MCF_ETPU_ECDTRSR_DTRS2           (0x00000004)
-#define MCF_ETPU_ECDTRSR_DTRS3           (0x00000008)
-#define MCF_ETPU_ECDTRSR_DTRS4           (0x00000010)
-#define MCF_ETPU_ECDTRSR_DTRS5           (0x00000020)
-#define MCF_ETPU_ECDTRSR_DTRS6           (0x00000040)
-#define MCF_ETPU_ECDTRSR_DTRS7           (0x00000080)
-#define MCF_ETPU_ECDTRSR_DTRS8           (0x00000100)
-#define MCF_ETPU_ECDTRSR_DTRS9           (0x00000200)
-#define MCF_ETPU_ECDTRSR_DTRS10          (0x00000400)
-#define MCF_ETPU_ECDTRSR_DTRS11          (0x00000800)
-#define MCF_ETPU_ECDTRSR_DTRS12          (0x00001000)
-#define MCF_ETPU_ECDTRSR_DTRS13          (0x00002000)
-#define MCF_ETPU_ECDTRSR_DTRS14          (0x00004000)
-#define MCF_ETPU_ECDTRSR_DTRS15          (0x00008000)
-#define MCF_ETPU_ECDTRSR_DTRS16          (0x00010000)
-#define MCF_ETPU_ECDTRSR_DTRS17          (0x00020000)
-#define MCF_ETPU_ECDTRSR_DTRS18          (0x00040000)
-#define MCF_ETPU_ECDTRSR_DTRS19          (0x00080000)
-#define MCF_ETPU_ECDTRSR_DTRS20          (0x00100000)
-#define MCF_ETPU_ECDTRSR_DTRS21          (0x00200000)
-#define MCF_ETPU_ECDTRSR_DTRS22          (0x00400000)
-#define MCF_ETPU_ECDTRSR_DTRS23          (0x00800000)
-#define MCF_ETPU_ECDTRSR_DTRS24          (0x01000000)
-#define MCF_ETPU_ECDTRSR_DTRS25          (0x02000000)
-#define MCF_ETPU_ECDTRSR_DTRS26          (0x04000000)
-#define MCF_ETPU_ECDTRSR_DTRS27          (0x08000000)
-#define MCF_ETPU_ECDTRSR_DTRS28          (0x10000000)
-#define MCF_ETPU_ECDTRSR_DTRS29          (0x20000000)
-#define MCF_ETPU_ECDTRSR_DTRS30          (0x40000000)
-#define MCF_ETPU_ECDTRSR_DTRS31          (0x80000000)
-
-/* Bit definitions and macros for MCF_ETPU_ECIOSR */
-#define MCF_ETPU_ECIOSR_CIOS0            (0x00000001)
-#define MCF_ETPU_ECIOSR_CIOS1            (0x00000002)
-#define MCF_ETPU_ECIOSR_CIOS2            (0x00000004)
-#define MCF_ETPU_ECIOSR_CIOS3            (0x00000008)
-#define MCF_ETPU_ECIOSR_CIOS4            (0x00000010)
-#define MCF_ETPU_ECIOSR_CIOS5            (0x00000020)
-#define MCF_ETPU_ECIOSR_CIOS6            (0x00000040)
-#define MCF_ETPU_ECIOSR_CIOS7            (0x00000080)
-#define MCF_ETPU_ECIOSR_CIOS8            (0x00000100)
-#define MCF_ETPU_ECIOSR_CIOS9            (0x00000200)
-#define MCF_ETPU_ECIOSR_CIOS10           (0x00000400)
-#define MCF_ETPU_ECIOSR_CIOS11           (0x00000800)
-#define MCF_ETPU_ECIOSR_CIOS12           (0x00001000)
-#define MCF_ETPU_ECIOSR_CIOS13           (0x00002000)
-#define MCF_ETPU_ECIOSR_CIOS14           (0x00004000)
-#define MCF_ETPU_ECIOSR_CIOS15           (0x00008000)
-#define MCF_ETPU_ECIOSR_CIOS16           (0x00010000)
-#define MCF_ETPU_ECIOSR_CIOS17           (0x00020000)
-#define MCF_ETPU_ECIOSR_CIOS18           (0x00040000)
-#define MCF_ETPU_ECIOSR_CIOS19           (0x00080000)
-#define MCF_ETPU_ECIOSR_CIOS20           (0x00100000)
-#define MCF_ETPU_ECIOSR_CIOS21           (0x00200000)
-#define MCF_ETPU_ECIOSR_CIOS22           (0x00400000)
-#define MCF_ETPU_ECIOSR_CIOS23           (0x00800000)
-#define MCF_ETPU_ECIOSR_CIOS24           (0x01000000)
-#define MCF_ETPU_ECIOSR_CIOS25           (0x02000000)
-#define MCF_ETPU_ECIOSR_CIOS26           (0x04000000)
-#define MCF_ETPU_ECIOSR_CIOS27           (0x08000000)
-#define MCF_ETPU_ECIOSR_CIOS28           (0x10000000)
-#define MCF_ETPU_ECIOSR_CIOS29           (0x20000000)
-#define MCF_ETPU_ECIOSR_CIOS30           (0x40000000)
-#define MCF_ETPU_ECIOSR_CIOS31           (0x80000000)
-
-/* Bit definitions and macros for MCF_ETPU_ECDTROSR */
-#define MCF_ETPU_ECDTROSR_DTROS0         (0x00000001)
-#define MCF_ETPU_ECDTROSR_DTROS1         (0x00000002)
-#define MCF_ETPU_ECDTROSR_DTROS2         (0x00000004)
-#define MCF_ETPU_ECDTROSR_DTROS3         (0x00000008)
-#define MCF_ETPU_ECDTROSR_DTROS4         (0x00000010)
-#define MCF_ETPU_ECDTROSR_DTROS5         (0x00000020)
-#define MCF_ETPU_ECDTROSR_DTROS6         (0x00000040)
-#define MCF_ETPU_ECDTROSR_DTROS7         (0x00000080)
-#define MCF_ETPU_ECDTROSR_DTROS8         (0x00000100)
-#define MCF_ETPU_ECDTROSR_DTROS9         (0x00000200)
-#define MCF_ETPU_ECDTROSR_DTROS10        (0x00000400)
-#define MCF_ETPU_ECDTROSR_DTROS11        (0x00000800)
-#define MCF_ETPU_ECDTROSR_DTROS12        (0x00001000)
-#define MCF_ETPU_ECDTROSR_DTROS13        (0x00002000)
-#define MCF_ETPU_ECDTROSR_DTROS14        (0x00004000)
-#define MCF_ETPU_ECDTROSR_DTROS15        (0x00008000)
-#define MCF_ETPU_ECDTROSR_DTROS16        (0x00010000)
-#define MCF_ETPU_ECDTROSR_DTROS17        (0x00020000)
-#define MCF_ETPU_ECDTROSR_DTROS18        (0x00040000)
-#define MCF_ETPU_ECDTROSR_DTROS19        (0x00080000)
-#define MCF_ETPU_ECDTROSR_DTROS20        (0x00100000)
-#define MCF_ETPU_ECDTROSR_DTROS21        (0x00200000)
-#define MCF_ETPU_ECDTROSR_DTROS22        (0x00400000)
-#define MCF_ETPU_ECDTROSR_DTROS23        (0x00800000)
-#define MCF_ETPU_ECDTROSR_DTROS24        (0x01000000)
-#define MCF_ETPU_ECDTROSR_DTROS25        (0x02000000)
-#define MCF_ETPU_ECDTROSR_DTROS26        (0x04000000)
-#define MCF_ETPU_ECDTROSR_DTROS27        (0x08000000)
-#define MCF_ETPU_ECDTROSR_DTROS28        (0x10000000)
-#define MCF_ETPU_ECDTROSR_DTROS29        (0x20000000)
-#define MCF_ETPU_ECDTROSR_DTROS30        (0x40000000)
-#define MCF_ETPU_ECDTROSR_DTROS31        (0x80000000)
-
-/* Bit definitions and macros for MCF_ETPU_ECIER */
-#define MCF_ETPU_ECIER_CIE0              (0x00000001)
-#define MCF_ETPU_ECIER_CIE1              (0x00000002)
-#define MCF_ETPU_ECIER_CIE2              (0x00000004)
-#define MCF_ETPU_ECIER_CIE3              (0x00000008)
-#define MCF_ETPU_ECIER_CIE4              (0x00000010)
-#define MCF_ETPU_ECIER_CIE5              (0x00000020)
-#define MCF_ETPU_ECIER_CIE6              (0x00000040)
-#define MCF_ETPU_ECIER_CIE7              (0x00000080)
-#define MCF_ETPU_ECIER_CIE8              (0x00000100)
-#define MCF_ETPU_ECIER_CIE9              (0x00000200)
-#define MCF_ETPU_ECIER_CIE10             (0x00000400)
-#define MCF_ETPU_ECIER_CIE11             (0x00000800)
-#define MCF_ETPU_ECIER_CIE12             (0x00001000)
-#define MCF_ETPU_ECIER_CIE13             (0x00002000)
-#define MCF_ETPU_ECIER_CIE14             (0x00004000)
-#define MCF_ETPU_ECIER_CIE15             (0x00008000)
-#define MCF_ETPU_ECIER_CIE16             (0x00010000)
-#define MCF_ETPU_ECIER_CIE17             (0x00020000)
-#define MCF_ETPU_ECIER_CIE18             (0x00040000)
-#define MCF_ETPU_ECIER_CIE19             (0x00080000)
-#define MCF_ETPU_ECIER_CIE20             (0x00100000)
-#define MCF_ETPU_ECIER_CIE21             (0x00200000)
-#define MCF_ETPU_ECIER_CIE22             (0x00400000)
-#define MCF_ETPU_ECIER_CIE23             (0x00800000)
-#define MCF_ETPU_ECIER_CIE24             (0x01000000)
-#define MCF_ETPU_ECIER_CIE25             (0x02000000)
-#define MCF_ETPU_ECIER_CIE26             (0x04000000)
-#define MCF_ETPU_ECIER_CIE27             (0x08000000)
-#define MCF_ETPU_ECIER_CIE28             (0x10000000)
-#define MCF_ETPU_ECIER_CIE29             (0x20000000)
-#define MCF_ETPU_ECIER_CIE30             (0x40000000)
-#define MCF_ETPU_ECIER_CIE31             (0x80000000)
-
-/* Bit definitions and macros for MCF_ETPU_ECDTRER */
-#define MCF_ETPU_ECDTRER_DTRE0           (0x00000001)
-#define MCF_ETPU_ECDTRER_DTRE1           (0x00000002)
-#define MCF_ETPU_ECDTRER_DTRE2           (0x00000004)
-#define MCF_ETPU_ECDTRER_DTRE3           (0x00000008)
-#define MCF_ETPU_ECDTRER_DTRE4           (0x00000010)
-#define MCF_ETPU_ECDTRER_DTRE5           (0x00000020)
-#define MCF_ETPU_ECDTRER_DTRE6           (0x00000040)
-#define MCF_ETPU_ECDTRER_DTRE7           (0x00000080)
-#define MCF_ETPU_ECDTRER_DTRE8           (0x00000100)
-#define MCF_ETPU_ECDTRER_DTRE9           (0x00000200)
-#define MCF_ETPU_ECDTRER_DTRE10          (0x00000400)
-#define MCF_ETPU_ECDTRER_DTRE11          (0x00000800)
-#define MCF_ETPU_ECDTRER_DTRE12          (0x00001000)
-#define MCF_ETPU_ECDTRER_DTRE13          (0x00002000)
-#define MCF_ETPU_ECDTRER_DTRE14          (0x00004000)
-#define MCF_ETPU_ECDTRER_DTRE15          (0x00008000)
-#define MCF_ETPU_ECDTRER_DTRE16          (0x00010000)
-#define MCF_ETPU_ECDTRER_DTRE17          (0x00020000)
-#define MCF_ETPU_ECDTRER_DTRE18          (0x00040000)
-#define MCF_ETPU_ECDTRER_DTRE19          (0x00080000)
-#define MCF_ETPU_ECDTRER_DTRE20          (0x00100000)
-#define MCF_ETPU_ECDTRER_DTRE21          (0x00200000)
-#define MCF_ETPU_ECDTRER_DTRE22          (0x00400000)
-#define MCF_ETPU_ECDTRER_DTRE23          (0x00800000)
-#define MCF_ETPU_ECDTRER_DTRE24          (0x01000000)
-#define MCF_ETPU_ECDTRER_DTRE25          (0x02000000)
-#define MCF_ETPU_ECDTRER_DTRE26          (0x04000000)
-#define MCF_ETPU_ECDTRER_DTRE27          (0x08000000)
-#define MCF_ETPU_ECDTRER_DTRE28          (0x10000000)
-#define MCF_ETPU_ECDTRER_DTRE29          (0x20000000)
-#define MCF_ETPU_ECDTRER_DTRE30          (0x40000000)
-#define MCF_ETPU_ECDTRER_DTRE31          (0x80000000)
-
-/* Bit definitions and macros for MCF_ETPU_ECPSSR */
-#define MCF_ETPU_ECPSSR_SR0              (0x00000001)
-#define MCF_ETPU_ECPSSR_SR1              (0x00000002)
-#define MCF_ETPU_ECPSSR_SR2              (0x00000004)
-#define MCF_ETPU_ECPSSR_SR3              (0x00000008)
-#define MCF_ETPU_ECPSSR_SR4              (0x00000010)
-#define MCF_ETPU_ECPSSR_SR5              (0x00000020)
-#define MCF_ETPU_ECPSSR_SR6              (0x00000040)
-#define MCF_ETPU_ECPSSR_SR7              (0x00000080)
-#define MCF_ETPU_ECPSSR_SR8              (0x00000100)
-#define MCF_ETPU_ECPSSR_SR9              (0x00000200)
-#define MCF_ETPU_ECPSSR_SR10             (0x00000400)
-#define MCF_ETPU_ECPSSR_SR11             (0x00000800)
-#define MCF_ETPU_ECPSSR_SR12             (0x00001000)
-#define MCF_ETPU_ECPSSR_SR13             (0x00002000)
-#define MCF_ETPU_ECPSSR_SR14             (0x00004000)
-#define MCF_ETPU_ECPSSR_SR15             (0x00008000)
-#define MCF_ETPU_ECPSSR_SR16             (0x00010000)
-#define MCF_ETPU_ECPSSR_SR17             (0x00020000)
-#define MCF_ETPU_ECPSSR_SR18             (0x00040000)
-#define MCF_ETPU_ECPSSR_SR19             (0x00080000)
-#define MCF_ETPU_ECPSSR_SR20             (0x00100000)
-#define MCF_ETPU_ECPSSR_SR21             (0x00200000)
-#define MCF_ETPU_ECPSSR_SR22             (0x00400000)
-#define MCF_ETPU_ECPSSR_SR23             (0x00800000)
-#define MCF_ETPU_ECPSSR_SR24             (0x01000000)
-#define MCF_ETPU_ECPSSR_SR25             (0x02000000)
-#define MCF_ETPU_ECPSSR_SR26             (0x04000000)
-#define MCF_ETPU_ECPSSR_SR27             (0x08000000)
-#define MCF_ETPU_ECPSSR_SR28             (0x10000000)
-#define MCF_ETPU_ECPSSR_SR29             (0x20000000)
-#define MCF_ETPU_ECPSSR_SR30             (0x40000000)
-#define MCF_ETPU_ECPSSR_SR31             (0x80000000)
-
-/* Bit definitions and macros for MCF_ETPU_ECSSR */
-#define MCF_ETPU_ECSSR_SS0               (0x00000001)
-#define MCF_ETPU_ECSSR_SS1               (0x00000002)
-#define MCF_ETPU_ECSSR_SS2               (0x00000004)
-#define MCF_ETPU_ECSSR_SS3               (0x00000008)
-#define MCF_ETPU_ECSSR_SS4               (0x00000010)
-#define MCF_ETPU_ECSSR_SS5               (0x00000020)
-#define MCF_ETPU_ECSSR_SS6               (0x00000040)
-#define MCF_ETPU_ECSSR_SS7               (0x00000080)
-#define MCF_ETPU_ECSSR_SS8               (0x00000100)
-#define MCF_ETPU_ECSSR_SS9               (0x00000200)
-#define MCF_ETPU_ECSSR_SS10              (0x00000400)
-#define MCF_ETPU_ECSSR_SS11              (0x00000800)
-#define MCF_ETPU_ECSSR_SS12              (0x00001000)
-#define MCF_ETPU_ECSSR_SS13              (0x00002000)
-#define MCF_ETPU_ECSSR_SS14              (0x00004000)
-#define MCF_ETPU_ECSSR_SS15              (0x00008000)
-#define MCF_ETPU_ECSSR_SS16              (0x00010000)
-#define MCF_ETPU_ECSSR_SS17              (0x00020000)
-#define MCF_ETPU_ECSSR_SS18              (0x00040000)
-#define MCF_ETPU_ECSSR_SS19              (0x00080000)
-#define MCF_ETPU_ECSSR_SS20              (0x00100000)
-#define MCF_ETPU_ECSSR_SS21              (0x00200000)
-#define MCF_ETPU_ECSSR_SS22              (0x00400000)
-#define MCF_ETPU_ECSSR_SS23              (0x00800000)
-#define MCF_ETPU_ECSSR_SS24              (0x01000000)
-#define MCF_ETPU_ECSSR_SS25              (0x02000000)
-#define MCF_ETPU_ECSSR_SS26              (0x04000000)
-#define MCF_ETPU_ECSSR_SS27              (0x08000000)
-#define MCF_ETPU_ECSSR_SS28              (0x10000000)
-#define MCF_ETPU_ECSSR_SS29              (0x20000000)
-#define MCF_ETPU_ECSSR_SS30              (0x40000000)
-#define MCF_ETPU_ECSSR_SS31              (0x80000000)
-
-/* Bit definitions and macros for MCF_ETPU_ECnSCR */
-#define MCF_ETPU_ECnSCR_FM(x)            (((x)&0x00000003)<<0)
-#define MCF_ETPU_ECnSCR_OBE              (0x00002000)
-#define MCF_ETPU_ECnSCR_OPS              (0x00004000)
-#define MCF_ETPU_ECnSCR_IPS              (0x00008000)
-#define MCF_ETPU_ECnSCR_DTROS            (0x00400000)
-#define MCF_ETPU_ECnSCR_DTRS             (0x00800000)
-#define MCF_ETPU_ECnSCR_CIOS             (0x40000000)
-#define MCF_ETPU_ECnSCR_CIS              (0x80000000)
-
-/* Bit definitions and macros for MCF_ETPU_ECnCR */
-#define MCF_ETPU_ECnCR_CPBA(x)           (((x)&0x000007FF)<<0)
-#define MCF_ETPU_ECnCR_OPOL              (0x00004000)
-#define MCF_ETPU_ECnCR_ODIS              (0x00008000)
-#define MCF_ETPU_ECnCR_CFS(x)            (((x)&0x0000001F)<<16)
-#define MCF_ETPU_ECnCR_ETCS              (0x01000000)
-#define MCF_ETPU_ECnCR_CPR(x)            (((x)&0x00000003)<<28)
-#define MCF_ETPU_ECnCR_DTRE              (0x40000000)
-#define MCF_ETPU_ECnCR_CIE               (0x80000000)
-
-/* Bit definitions and macros for MCF_ETPU_ECnHSSR */
-#define MCF_ETPU_ECnHSSR_HSR(x)          (((x)&0x00000007)<<0)
-
-/********************************************************************/
-
-#endif /* __MCF523X_ETPU_H__ */
+/*\r
+ * These files are taken from the MCF523X source code example package\r
+ * which is available on the Freescale website. Freescale explicitly \r
+ * grants the redistribution and modification of these source files.\r
+ * The complete licensing information is available in the file \r
+ * LICENSE_FREESCALE.TXT.\r
+ *\r
+ * File:       mcf523x_etpu.h\r
+ * Purpose:    Register and bit definitions for the MCF523X\r
+ *\r
+ * Notes:      \r
+ *     \r
+ */\r
+\r
+#ifndef __MCF523X_ETPU_H__\r
+#define __MCF523X_ETPU_H__\r
+\r
+/*********************************************************************\r
+*\r
+* enhanced Time Processor Unit (ETPU)\r
+*\r
+*********************************************************************/\r
+\r
+/* Register read/write macros */\r
+#define MCF_ETPU_EMCR          (*(vuint32*)(void*)(&__IPSBAR[0x1D0000]))\r
+#define MCF_ETPU_ECDCR         (*(vuint32*)(void*)(&__IPSBAR[0x1D0004]))\r
+#define MCF_ETPU_EMISCCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D000C]))\r
+#define MCF_ETPU_ESCMODR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0010]))\r
+#define MCF_ETPU_EECR          (*(vuint32*)(void*)(&__IPSBAR[0x1D0014]))\r
+#define MCF_ETPU_ETBCR         (*(vuint32*)(void*)(&__IPSBAR[0x1D0020]))\r
+#define MCF_ETPU_ETB1R         (*(vuint32*)(void*)(&__IPSBAR[0x1D0024]))\r
+#define MCF_ETPU_ETB2R         (*(vuint32*)(void*)(&__IPSBAR[0x1D0028]))\r
+#define MCF_ETPU_EREDCR        (*(vuint32*)(void*)(&__IPSBAR[0x1D002C]))\r
+#define MCF_ETPU_ECISR         (*(vuint32*)(void*)(&__IPSBAR[0x1D0200]))\r
+#define MCF_ETPU_ECDTRSR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0210]))\r
+#define MCF_ETPU_ECIOSR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0220]))\r
+#define MCF_ETPU_ECDTROSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D0230]))\r
+#define MCF_ETPU_ECIER         (*(vuint32*)(void*)(&__IPSBAR[0x1D0240]))\r
+#define MCF_ETPU_ECDTRER       (*(vuint32*)(void*)(&__IPSBAR[0x1D0250]))\r
+#define MCF_ETPU_ECPSSR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0280]))\r
+#define MCF_ETPU_ECSSR         (*(vuint32*)(void*)(&__IPSBAR[0x1D0290]))\r
+#define MCF_ETPU_EC0SCR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0404]))\r
+#define MCF_ETPU_EC1SCR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0414]))\r
+#define MCF_ETPU_EC2SCR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0424]))\r
+#define MCF_ETPU_EC3SCR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0434]))\r
+#define MCF_ETPU_EC4SCR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0444]))\r
+#define MCF_ETPU_EC5SCR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0454]))\r
+#define MCF_ETPU_EC6SCR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0464]))\r
+#define MCF_ETPU_EC7SCR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0474]))\r
+#define MCF_ETPU_EC8SCR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0484]))\r
+#define MCF_ETPU_EC9SCR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0494]))\r
+#define MCF_ETPU_EC10SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D04A4]))\r
+#define MCF_ETPU_EC11SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D04B4]))\r
+#define MCF_ETPU_EC12SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D04C4]))\r
+#define MCF_ETPU_EC13SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D04D4]))\r
+#define MCF_ETPU_EC14SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D04E4]))\r
+#define MCF_ETPU_EC15SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D04F4]))\r
+#define MCF_ETPU_EC16SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0504]))\r
+#define MCF_ETPU_EC17SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0514]))\r
+#define MCF_ETPU_EC18SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0524]))\r
+#define MCF_ETPU_EC19SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0534]))\r
+#define MCF_ETPU_EC20SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0544]))\r
+#define MCF_ETPU_EC21SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0554]))\r
+#define MCF_ETPU_EC22SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0564]))\r
+#define MCF_ETPU_EC23SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0574]))\r
+#define MCF_ETPU_EC24SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0584]))\r
+#define MCF_ETPU_EC25SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0594]))\r
+#define MCF_ETPU_EC26SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D05A4]))\r
+#define MCF_ETPU_EC27SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D05B4]))\r
+#define MCF_ETPU_EC28SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D05C4]))\r
+#define MCF_ETPU_EC29SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D05D4]))\r
+#define MCF_ETPU_EC30SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D05E4]))\r
+#define MCF_ETPU_EC31SCR       (*(vuint32*)(void*)(&__IPSBAR[0x1D05F4]))\r
+#define MCF_ETPU_ECnSCR(x)     (*(vuint32*)(void*)(&__IPSBAR[0x1D0404+((x)*0x010)]))\r
+#define MCF_ETPU_EC0CR         (*(vuint32*)(void*)(&__IPSBAR[0x1D0400]))\r
+#define MCF_ETPU_EC1CR         (*(vuint32*)(void*)(&__IPSBAR[0x1D0410]))\r
+#define MCF_ETPU_EC2CR         (*(vuint32*)(void*)(&__IPSBAR[0x1D0420]))\r
+#define MCF_ETPU_EC3CR         (*(vuint32*)(void*)(&__IPSBAR[0x1D0430]))\r
+#define MCF_ETPU_EC4CR         (*(vuint32*)(void*)(&__IPSBAR[0x1D0440]))\r
+#define MCF_ETPU_EC5CR         (*(vuint32*)(void*)(&__IPSBAR[0x1D0450]))\r
+#define MCF_ETPU_EC6CR         (*(vuint32*)(void*)(&__IPSBAR[0x1D0460]))\r
+#define MCF_ETPU_EC7CR         (*(vuint32*)(void*)(&__IPSBAR[0x1D0470]))\r
+#define MCF_ETPU_EC8CR         (*(vuint32*)(void*)(&__IPSBAR[0x1D0480]))\r
+#define MCF_ETPU_EC9CR         (*(vuint32*)(void*)(&__IPSBAR[0x1D0490]))\r
+#define MCF_ETPU_EC10CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D04A0]))\r
+#define MCF_ETPU_EC11CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D04B0]))\r
+#define MCF_ETPU_EC12CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D04C0]))\r
+#define MCF_ETPU_EC13CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D04D0]))\r
+#define MCF_ETPU_EC14CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D04E0]))\r
+#define MCF_ETPU_EC15CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D04F0]))\r
+#define MCF_ETPU_EC16CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0500]))\r
+#define MCF_ETPU_EC17CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0510]))\r
+#define MCF_ETPU_EC18CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0520]))\r
+#define MCF_ETPU_EC19CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0530]))\r
+#define MCF_ETPU_EC20CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0540]))\r
+#define MCF_ETPU_EC21CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0550]))\r
+#define MCF_ETPU_EC22CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0560]))\r
+#define MCF_ETPU_EC23CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0570]))\r
+#define MCF_ETPU_EC24CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0580]))\r
+#define MCF_ETPU_EC25CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D0590]))\r
+#define MCF_ETPU_EC26CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D05A0]))\r
+#define MCF_ETPU_EC27CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D05B0]))\r
+#define MCF_ETPU_EC28CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D05C0]))\r
+#define MCF_ETPU_EC29CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D05D0]))\r
+#define MCF_ETPU_EC30CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D05E0]))\r
+#define MCF_ETPU_EC31CR        (*(vuint32*)(void*)(&__IPSBAR[0x1D05F0]))\r
+#define MCF_ETPU_ECnCR(x)      (*(vuint32*)(void*)(&__IPSBAR[0x1D0400+((x)*0x010)]))\r
+#define MCF_ETPU_EC0HSSR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0408]))\r
+#define MCF_ETPU_EC1HSSR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0418]))\r
+#define MCF_ETPU_EC2HSSR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0428]))\r
+#define MCF_ETPU_EC3HSSR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0438]))\r
+#define MCF_ETPU_EC4HSSR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0448]))\r
+#define MCF_ETPU_EC5HSSR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0458]))\r
+#define MCF_ETPU_EC6HSSR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0468]))\r
+#define MCF_ETPU_EC7HSSR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0478]))\r
+#define MCF_ETPU_EC8HSSR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0488]))\r
+#define MCF_ETPU_EC9HSSR       (*(vuint32*)(void*)(&__IPSBAR[0x1D0498]))\r
+#define MCF_ETPU_EC10HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D04A8]))\r
+#define MCF_ETPU_EC11HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D04B8]))\r
+#define MCF_ETPU_EC12HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D04C8]))\r
+#define MCF_ETPU_EC13HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D04D8]))\r
+#define MCF_ETPU_EC14HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D04E8]))\r
+#define MCF_ETPU_EC15HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D04F8]))\r
+#define MCF_ETPU_EC16HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D0508]))\r
+#define MCF_ETPU_EC17HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D0518]))\r
+#define MCF_ETPU_EC18HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D0528]))\r
+#define MCF_ETPU_EC19HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D0538]))\r
+#define MCF_ETPU_EC20HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D0548]))\r
+#define MCF_ETPU_EC21HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D0558]))\r
+#define MCF_ETPU_EC22HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D0568]))\r
+#define MCF_ETPU_EC23HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D0578]))\r
+#define MCF_ETPU_EC24HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D0588]))\r
+#define MCF_ETPU_EC25HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D0598]))\r
+#define MCF_ETPU_EC26HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D05A8]))\r
+#define MCF_ETPU_EC27HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D05B8]))\r
+#define MCF_ETPU_EC28HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D05C8]))\r
+#define MCF_ETPU_EC29HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D05D8]))\r
+#define MCF_ETPU_EC30HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D05E8]))\r
+#define MCF_ETPU_EC31HSSR      (*(vuint32*)(void*)(&__IPSBAR[0x1D05F8]))\r
+#define MCF_ETPU_ECnHSSR(x)    (*(vuint32*)(void*)(&__IPSBAR[0x1D0408+((x)*0x010)]))\r
+\r
+/* Bit definitions and macros for MCF_ETPU_EMCR */\r
+#define MCF_ETPU_EMCR_GTBE               (0x00000001)\r
+#define MCF_ETPU_EMCR_VIS                (0x00000040)\r
+#define MCF_ETPU_EMCR_SCMMISEN           (0x00000200)\r
+#define MCF_ETPU_EMCR_SCMMISF            (0x00000400)\r
+#define MCF_ETPU_EMCR_SCMSIZE(x)         (((x)&0x0000001F)<<16)\r
+#define MCF_ETPU_EMCR_ILF2               (0x01000000)\r
+#define MCF_ETPU_EMCR_ILF1               (0x02000000)\r
+#define MCF_ETPU_EMCR_MGE2               (0x04000000)\r
+#define MCF_ETPU_EMCR_MGE1               (0x08000000)\r
+#define MCF_ETPU_EMCR_GEC                (0x80000000)\r
+\r
+/* Bit definitions and macros for MCF_ETPU_ECDCR */\r
+#define MCF_ETPU_ECDCR_PARM1(x)          (((x)&0x0000007F)<<0)\r
+#define MCF_ETPU_ECDCR_WR                (0x00000080)\r
+#define MCF_ETPU_ECDCR_PARM0(x)          (((x)&0x0000007F)<<8)\r
+#define MCF_ETPU_ECDCR_PWIDTH            (0x00008000)\r
+#define MCF_ETPU_ECDCR_PBASE(x)          (((x)&0x000003FF)<<16)\r
+#define MCF_ETPU_ECDCR_CTBASE(x)         (((x)&0x0000001F)<<26)\r
+#define MCF_ETPU_ECDCR_STS               (0x80000000)\r
+\r
+/* Bit definitions and macros for MCF_ETPU_EECR */\r
+#define MCF_ETPU_EECR_ETB(x)             (((x)&0x0000001F)<<0)\r
+#define MCF_ETPU_EECR_CDFC(x)            (((x)&0x00000003)<<14)\r
+#define MCF_ETPU_EECR_FPSK(x)            (((x)&0x00000007)<<16)\r
+#define MCF_ETPU_EECR_HLTF               (0x00800000)\r
+#define MCF_ETPU_EECR_STF                (0x10000000)\r
+#define MCF_ETPU_EECR_MDIS               (0x40000000)\r
+#define MCF_ETPU_EECR_FEND               (0x80000000)\r
+\r
+/* Bit definitions and macros for MCF_ETPU_ETBCR */\r
+#define MCF_ETPU_ETBCR_TCR1P(x)          (((x)&0x000000FF)<<0)\r
+#define MCF_ETPU_ETBCR_TCR1CTL(x)        (((x)&0x00000003)<<14)\r
+#define MCF_ETPU_ETBCR_TCR2P(x)          (((x)&0x0000003F)<<16)\r
+#define MCF_ETPU_ETBCR_AM                (0x02000000)\r
+#define MCF_ETPU_ETBCR_TCRCF(x)          (((x)&0x00000003)<<27)\r
+#define MCF_ETPU_ETBCR_TCR2CTL(x)        (((x)&0x00000007)<<29)\r
+\r
+/* Bit definitions and macros for MCF_ETPU_ETB1R */\r
+#define MCF_ETPU_ETB1R_TCR1(x)           (((x)&0x00FFFFFF)<<0)\r
+\r
+/* Bit definitions and macros for MCF_ETPU_ETB2R */\r
+#define MCF_ETPU_ETB2R_TCR2(x)           (((x)&0x00FFFFFF)<<0)\r
+\r
+/* Bit definitions and macros for MCF_ETPU_EREDCR */\r
+#define MCF_ETPU_EREDCR_SRV2(x)          (((x)&0x0000000F)<<0)\r
+#define MCF_ETPU_EREDCR_SERVER_ID2(x)    (((x)&0x0000000F)<<8)\r
+#define MCF_ETPU_EREDCR_RSC2             (0x00004000)\r
+#define MCF_ETPU_EREDCR_REN2             (0x00008000)\r
+#define MCF_ETPU_EREDCR_SRV1(x)          (((x)&0x0000000F)<<16)\r
+#define MCF_ETPU_EREDCR_SERVER_ID1(x)    (((x)&0x0000000F)<<24)\r
+#define MCF_ETPU_EREDCR_RSC1             (0x40000000)\r
+#define MCF_ETPU_EREDCR_REN1             (0x80000000)\r
+\r
+/* Bit definitions and macros for MCF_ETPU_ECISR */\r
+#define MCF_ETPU_ECISR_CIS0              (0x00000001)\r
+#define MCF_ETPU_ECISR_CIS1              (0x00000002)\r
+#define MCF_ETPU_ECISR_CIS2              (0x00000004)\r
+#define MCF_ETPU_ECISR_CIS3              (0x00000008)\r
+#define MCF_ETPU_ECISR_CIS4              (0x00000010)\r
+#define MCF_ETPU_ECISR_CIS5              (0x00000020)\r
+#define MCF_ETPU_ECISR_CIS6              (0x00000040)\r
+#define MCF_ETPU_ECISR_CIS7              (0x00000080)\r
+#define MCF_ETPU_ECISR_CIS8              (0x00000100)\r
+#define MCF_ETPU_ECISR_CIS9              (0x00000200)\r
+#define MCF_ETPU_ECISR_CIS10             (0x00000400)\r
+#define MCF_ETPU_ECISR_CIS11             (0x00000800)\r
+#define MCF_ETPU_ECISR_CIS12             (0x00001000)\r
+#define MCF_ETPU_ECISR_CIS13             (0x00002000)\r
+#define MCF_ETPU_ECISR_CIS14             (0x00004000)\r
+#define MCF_ETPU_ECISR_CIS15             (0x00008000)\r
+#define MCF_ETPU_ECISR_CIS16             (0x00010000)\r
+#define MCF_ETPU_ECISR_CIS17             (0x00020000)\r
+#define MCF_ETPU_ECISR_CIS18             (0x00040000)\r
+#define MCF_ETPU_ECISR_CIS19             (0x00080000)\r
+#define MCF_ETPU_ECISR_CIS20             (0x00100000)\r
+#define MCF_ETPU_ECISR_CIS21             (0x00200000)\r
+#define MCF_ETPU_ECISR_CIS22             (0x00400000)\r
+#define MCF_ETPU_ECISR_CIS23             (0x00800000)\r
+#define MCF_ETPU_ECISR_CIS24             (0x01000000)\r
+#define MCF_ETPU_ECISR_CIS25             (0x02000000)\r
+#define MCF_ETPU_ECISR_CIS26             (0x04000000)\r
+#define MCF_ETPU_ECISR_CIS27             (0x08000000)\r
+#define MCF_ETPU_ECISR_CIS28             (0x10000000)\r
+#define MCF_ETPU_ECISR_CIS29             (0x20000000)\r
+#define MCF_ETPU_ECISR_CIS30             (0x40000000)\r
+#define MCF_ETPU_ECISR_CIS31             (0x80000000)\r
+\r
+/* Bit definitions and macros for MCF_ETPU_ECDTRSR */\r
+#define MCF_ETPU_ECDTRSR_DTRS0           (0x00000001)\r
+#define MCF_ETPU_ECDTRSR_DTRS1           (0x00000002)\r
+#define MCF_ETPU_ECDTRSR_DTRS2           (0x00000004)\r
+#define MCF_ETPU_ECDTRSR_DTRS3           (0x00000008)\r
+#define MCF_ETPU_ECDTRSR_DTRS4           (0x00000010)\r
+#define MCF_ETPU_ECDTRSR_DTRS5           (0x00000020)\r
+#define MCF_ETPU_ECDTRSR_DTRS6           (0x00000040)\r
+#define MCF_ETPU_ECDTRSR_DTRS7           (0x00000080)\r
+#define MCF_ETPU_ECDTRSR_DTRS8           (0x00000100)\r
+#define MCF_ETPU_ECDTRSR_DTRS9           (0x00000200)\r
+#define MCF_ETPU_ECDTRSR_DTRS10          (0x00000400)\r
+#define MCF_ETPU_ECDTRSR_DTRS11          (0x00000800)\r
+#define MCF_ETPU_ECDTRSR_DTRS12          (0x00001000)\r
+#define MCF_ETPU_ECDTRSR_DTRS13          (0x00002000)\r
+#define MCF_ETPU_ECDTRSR_DTRS14          (0x00004000)\r
+#define MCF_ETPU_ECDTRSR_DTRS15          (0x00008000)\r
+#define MCF_ETPU_ECDTRSR_DTRS16          (0x00010000)\r
+#define MCF_ETPU_ECDTRSR_DTRS17          (0x00020000)\r
+#define MCF_ETPU_ECDTRSR_DTRS18          (0x00040000)\r
+#define MCF_ETPU_ECDTRSR_DTRS19          (0x00080000)\r
+#define MCF_ETPU_ECDTRSR_DTRS20          (0x00100000)\r
+#define MCF_ETPU_ECDTRSR_DTRS21          (0x00200000)\r
+#define MCF_ETPU_ECDTRSR_DTRS22          (0x00400000)\r
+#define MCF_ETPU_ECDTRSR_DTRS23          (0x00800000)\r
+#define MCF_ETPU_ECDTRSR_DTRS24          (0x01000000)\r
+#define MCF_ETPU_ECDTRSR_DTRS25          (0x02000000)\r
+#define MCF_ETPU_ECDTRSR_DTRS26          (0x04000000)\r
+#define MCF_ETPU_ECDTRSR_DTRS27          (0x08000000)\r
+#define MCF_ETPU_ECDTRSR_DTRS28          (0x10000000)\r
+#define MCF_ETPU_ECDTRSR_DTRS29          (0x20000000)\r
+#define MCF_ETPU_ECDTRSR_DTRS30          (0x40000000)\r
+#define MCF_ETPU_ECDTRSR_DTRS31          (0x80000000)\r
+\r
+/* Bit definitions and macros for MCF_ETPU_ECIOSR */\r
+#define MCF_ETPU_ECIOSR_CIOS0            (0x00000001)\r
+#define MCF_ETPU_ECIOSR_CIOS1            (0x00000002)\r
+#define MCF_ETPU_ECIOSR_CIOS2            (0x00000004)\r
+#define MCF_ETPU_ECIOSR_CIOS3            (0x00000008)\r
+#define MCF_ETPU_ECIOSR_CIOS4            (0x00000010)\r
+#define MCF_ETPU_ECIOSR_CIOS5            (0x00000020)\r
+#define MCF_ETPU_ECIOSR_CIOS6            (0x00000040)\r
+#define MCF_ETPU_ECIOSR_CIOS7            (0x00000080)\r
+#define MCF_ETPU_ECIOSR_CIOS8            (0x00000100)\r
+#define MCF_ETPU_ECIOSR_CIOS9            (0x00000200)\r
+#define MCF_ETPU_ECIOSR_CIOS10           (0x00000400)\r
+#define MCF_ETPU_ECIOSR_CIOS11           (0x00000800)\r
+#define MCF_ETPU_ECIOSR_CIOS12           (0x00001000)\r
+#define MCF_ETPU_ECIOSR_CIOS13           (0x00002000)\r
+#define MCF_ETPU_ECIOSR_CIOS14           (0x00004000)\r
+#define MCF_ETPU_ECIOSR_CIOS15           (0x00008000)\r
+#define MCF_ETPU_ECIOSR_CIOS16           (0x00010000)\r
+#define MCF_ETPU_ECIOSR_CIOS17           (0x00020000)\r
+#define MCF_ETPU_ECIOSR_CIOS18           (0x00040000)\r
+#define MCF_ETPU_ECIOSR_CIOS19           (0x00080000)\r
+#define MCF_ETPU_ECIOSR_CIOS20           (0x00100000)\r
+#define MCF_ETPU_ECIOSR_CIOS21           (0x00200000)\r
+#define MCF_ETPU_ECIOSR_CIOS22           (0x00400000)\r
+#define MCF_ETPU_ECIOSR_CIOS23           (0x00800000)\r
+#define MCF_ETPU_ECIOSR_CIOS24           (0x01000000)\r
+#define MCF_ETPU_ECIOSR_CIOS25           (0x02000000)\r
+#define MCF_ETPU_ECIOSR_CIOS26           (0x04000000)\r
+#define MCF_ETPU_ECIOSR_CIOS27           (0x08000000)\r
+#define MCF_ETPU_ECIOSR_CIOS28           (0x10000000)\r
+#define MCF_ETPU_ECIOSR_CIOS29           (0x20000000)\r
+#define MCF_ETPU_ECIOSR_CIOS30           (0x40000000)\r
+#define MCF_ETPU_ECIOSR_CIOS31           (0x80000000)\r
+\r
+/* Bit definitions and macros for MCF_ETPU_ECDTROSR */\r
+#define MCF_ETPU_ECDTROSR_DTROS0         (0x00000001)\r
+#define MCF_ETPU_ECDTROSR_DTROS1         (0x00000002)\r
+#define MCF_ETPU_ECDTROSR_DTROS2         (0x00000004)\r
+#define MCF_ETPU_ECDTROSR_DTROS3         (0x00000008)\r
+#define MCF_ETPU_ECDTROSR_DTROS4         (0x00000010)\r
+#define MCF_ETPU_ECDTROSR_DTROS5         (0x00000020)\r
+#define MCF_ETPU_ECDTROSR_DTROS6         (0x00000040)\r
+#define MCF_ETPU_ECDTROSR_DTROS7         (0x00000080)\r
+#define MCF_ETPU_ECDTROSR_DTROS8         (0x00000100)\r
+#define MCF_ETPU_ECDTROSR_DTROS9         (0x00000200)\r
+#define MCF_ETPU_ECDTROSR_DTROS10        (0x00000400)\r
+#define MCF_ETPU_ECDTROSR_DTROS11        (0x00000800)\r
+#define MCF_ETPU_ECDTROSR_DTROS12        (0x00001000)\r
+#define MCF_ETPU_ECDTROSR_DTROS13        (0x00002000)\r
+#define MCF_ETPU_ECDTROSR_DTROS14        (0x00004000)\r
+#define MCF_ETPU_ECDTROSR_DTROS15        (0x00008000)\r
+#define MCF_ETPU_ECDTROSR_DTROS16        (0x00010000)\r
+#define MCF_ETPU_ECDTROSR_DTROS17        (0x00020000)\r
+#define MCF_ETPU_ECDTROSR_DTROS18        (0x00040000)\r
+#define MCF_ETPU_ECDTROSR_DTROS19        (0x00080000)\r
+#define MCF_ETPU_ECDTROSR_DTROS20        (0x00100000)\r
+#define MCF_ETPU_ECDTROSR_DTROS21        (0x00200000)\r
+#define MCF_ETPU_ECDTROSR_DTROS22        (0x00400000)\r
+#define MCF_ETPU_ECDTROSR_DTROS23        (0x00800000)\r
+#define MCF_ETPU_ECDTROSR_DTROS24        (0x01000000)\r
+#define MCF_ETPU_ECDTROSR_DTROS25        (0x02000000)\r
+#define MCF_ETPU_ECDTROSR_DTROS26        (0x04000000)\r
+#define MCF_ETPU_ECDTROSR_DTROS27        (0x08000000)\r
+#define MCF_ETPU_ECDTROSR_DTROS28        (0x10000000)\r
+#define MCF_ETPU_ECDTROSR_DTROS29        (0x20000000)\r
+#define MCF_ETPU_ECDTROSR_DTROS30        (0x40000000)\r
+#define MCF_ETPU_ECDTROSR_DTROS31        (0x80000000)\r
+\r
+/* Bit definitions and macros for MCF_ETPU_ECIER */\r
+#define MCF_ETPU_ECIER_CIE0              (0x00000001)\r
+#define MCF_ETPU_ECIER_CIE1              (0x00000002)\r
+#define MCF_ETPU_ECIER_CIE2              (0x00000004)\r
+#define MCF_ETPU_ECIER_CIE3              (0x00000008)\r
+#define MCF_ETPU_ECIER_CIE4              (0x00000010)\r
+#define MCF_ETPU_ECIER_CIE5              (0x00000020)\r
+#define MCF_ETPU_ECIER_CIE6              (0x00000040)\r
+#define MCF_ETPU_ECIER_CIE7              (0x00000080)\r
+#define MCF_ETPU_ECIER_CIE8              (0x00000100)\r
+#define MCF_ETPU_ECIER_CIE9              (0x00000200)\r
+#define MCF_ETPU_ECIER_CIE10             (0x00000400)\r
+#define MCF_ETPU_ECIER_CIE11             (0x00000800)\r
+#define MCF_ETPU_ECIER_CIE12             (0x00001000)\r
+#define MCF_ETPU_ECIER_CIE13             (0x00002000)\r
+#define MCF_ETPU_ECIER_CIE14             (0x00004000)\r
+#define MCF_ETPU_ECIER_CIE15             (0x00008000)\r
+#define MCF_ETPU_ECIER_CIE16             (0x00010000)\r
+#define MCF_ETPU_ECIER_CIE17             (0x00020000)\r
+#define MCF_ETPU_ECIER_CIE18             (0x00040000)\r
+#define MCF_ETPU_ECIER_CIE19             (0x00080000)\r
+#define MCF_ETPU_ECIER_CIE20             (0x00100000)\r
+#define MCF_ETPU_ECIER_CIE21             (0x00200000)\r
+#define MCF_ETPU_ECIER_CIE22             (0x00400000)\r
+#define MCF_ETPU_ECIER_CIE23             (0x00800000)\r
+#define MCF_ETPU_ECIER_CIE24             (0x01000000)\r
+#define MCF_ETPU_ECIER_CIE25             (0x02000000)\r
+#define MCF_ETPU_ECIER_CIE26             (0x04000000)\r
+#define MCF_ETPU_ECIER_CIE27             (0x08000000)\r
+#define MCF_ETPU_ECIER_CIE28             (0x10000000)\r
+#define MCF_ETPU_ECIER_CIE29             (0x20000000)\r
+#define MCF_ETPU_ECIER_CIE30             (0x40000000)\r
+#define MCF_ETPU_ECIER_CIE31             (0x80000000)\r
+\r
+/* Bit definitions and macros for MCF_ETPU_ECDTRER */\r
+#define MCF_ETPU_ECDTRER_DTRE0           (0x00000001)\r
+#define MCF_ETPU_ECDTRER_DTRE1           (0x00000002)\r
+#define MCF_ETPU_ECDTRER_DTRE2           (0x00000004)\r
+#define MCF_ETPU_ECDTRER_DTRE3           (0x00000008)\r
+#define MCF_ETPU_ECDTRER_DTRE4           (0x00000010)\r
+#define MCF_ETPU_ECDTRER_DTRE5           (0x00000020)\r
+#define MCF_ETPU_ECDTRER_DTRE6           (0x00000040)\r
+#define MCF_ETPU_ECDTRER_DTRE7           (0x00000080)\r
+#define MCF_ETPU_ECDTRER_DTRE8           (0x00000100)\r
+#define MCF_ETPU_ECDTRER_DTRE9           (0x00000200)\r
+#define MCF_ETPU_ECDTRER_DTRE10          (0x00000400)\r
+#define MCF_ETPU_ECDTRER_DTRE11          (0x00000800)\r
+#define MCF_ETPU_ECDTRER_DTRE12          (0x00001000)\r
+#define MCF_ETPU_ECDTRER_DTRE13          (0x00002000)\r
+#define MCF_ETPU_ECDTRER_DTRE14          (0x00004000)\r
+#define MCF_ETPU_ECDTRER_DTRE15          (0x00008000)\r
+#define MCF_ETPU_ECDTRER_DTRE16          (0x00010000)\r
+#define MCF_ETPU_ECDTRER_DTRE17          (0x00020000)\r
+#define MCF_ETPU_ECDTRER_DTRE18          (0x00040000)\r
+#define MCF_ETPU_ECDTRER_DTRE19          (0x00080000)\r
+#define MCF_ETPU_ECDTRER_DTRE20          (0x00100000)\r
+#define MCF_ETPU_ECDTRER_DTRE21          (0x00200000)\r
+#define MCF_ETPU_ECDTRER_DTRE22          (0x00400000)\r
+#define MCF_ETPU_ECDTRER_DTRE23          (0x00800000)\r
+#define MCF_ETPU_ECDTRER_DTRE24          (0x01000000)\r
+#define MCF_ETPU_ECDTRER_DTRE25          (0x02000000)\r
+#define MCF_ETPU_ECDTRER_DTRE26          (0x04000000)\r
+#define MCF_ETPU_ECDTRER_DTRE27          (0x08000000)\r
+#define MCF_ETPU_ECDTRER_DTRE28          (0x10000000)\r
+#define MCF_ETPU_ECDTRER_DTRE29          (0x20000000)\r
+#define MCF_ETPU_ECDTRER_DTRE30          (0x40000000)\r
+#define MCF_ETPU_ECDTRER_DTRE31          (0x80000000)\r
+\r
+/* Bit definitions and macros for MCF_ETPU_ECPSSR */\r
+#define MCF_ETPU_ECPSSR_SR0              (0x00000001)\r
+#define MCF_ETPU_ECPSSR_SR1              (0x00000002)\r
+#define MCF_ETPU_ECPSSR_SR2              (0x00000004)\r
+#define MCF_ETPU_ECPSSR_SR3              (0x00000008)\r
+#define MCF_ETPU_ECPSSR_SR4              (0x00000010)\r
+#define MCF_ETPU_ECPSSR_SR5              (0x00000020)\r
+#define MCF_ETPU_ECPSSR_SR6              (0x00000040)\r
+#define MCF_ETPU_ECPSSR_SR7              (0x00000080)\r
+#define MCF_ETPU_ECPSSR_SR8              (0x00000100)\r
+#define MCF_ETPU_ECPSSR_SR9              (0x00000200)\r
+#define MCF_ETPU_ECPSSR_SR10             (0x00000400)\r
+#define MCF_ETPU_ECPSSR_SR11             (0x00000800)\r
+#define MCF_ETPU_ECPSSR_SR12             (0x00001000)\r
+#define MCF_ETPU_ECPSSR_SR13             (0x00002000)\r
+#define MCF_ETPU_ECPSSR_SR14             (0x00004000)\r
+#define MCF_ETPU_ECPSSR_SR15             (0x00008000)\r
+#define MCF_ETPU_ECPSSR_SR16             (0x00010000)\r
+#define MCF_ETPU_ECPSSR_SR17             (0x00020000)\r
+#define MCF_ETPU_ECPSSR_SR18             (0x00040000)\r
+#define MCF_ETPU_ECPSSR_SR19             (0x00080000)\r
+#define MCF_ETPU_ECPSSR_SR20             (0x00100000)\r
+#define MCF_ETPU_ECPSSR_SR21             (0x00200000)\r
+#define MCF_ETPU_ECPSSR_SR22             (0x00400000)\r
+#define MCF_ETPU_ECPSSR_SR23             (0x00800000)\r
+#define MCF_ETPU_ECPSSR_SR24             (0x01000000)\r
+#define MCF_ETPU_ECPSSR_SR25             (0x02000000)\r
+#define MCF_ETPU_ECPSSR_SR26             (0x04000000)\r
+#define MCF_ETPU_ECPSSR_SR27             (0x08000000)\r
+#define MCF_ETPU_ECPSSR_SR28             (0x10000000)\r
+#define MCF_ETPU_ECPSSR_SR29             (0x20000000)\r
+#define MCF_ETPU_ECPSSR_SR30             (0x40000000)\r
+#define MCF_ETPU_ECPSSR_SR31             (0x80000000)\r
+\r
+/* Bit definitions and macros for MCF_ETPU_ECSSR */\r
+#define MCF_ETPU_ECSSR_SS0               (0x00000001)\r
+#define MCF_ETPU_ECSSR_SS1               (0x00000002)\r
+#define MCF_ETPU_ECSSR_SS2               (0x00000004)\r
+#define MCF_ETPU_ECSSR_SS3               (0x00000008)\r
+#define MCF_ETPU_ECSSR_SS4               (0x00000010)\r
+#define MCF_ETPU_ECSSR_SS5               (0x00000020)\r
+#define MCF_ETPU_ECSSR_SS6               (0x00000040)\r
+#define MCF_ETPU_ECSSR_SS7               (0x00000080)\r
+#define MCF_ETPU_ECSSR_SS8               (0x00000100)\r
+#define MCF_ETPU_ECSSR_SS9               (0x00000200)\r
+#define MCF_ETPU_ECSSR_SS10              (0x00000400)\r
+#define MCF_ETPU_ECSSR_SS11              (0x00000800)\r
+#define MCF_ETPU_ECSSR_SS12              (0x00001000)\r
+#define MCF_ETPU_ECSSR_SS13              (0x00002000)\r
+#define MCF_ETPU_ECSSR_SS14              (0x00004000)\r
+#define MCF_ETPU_ECSSR_SS15              (0x00008000)\r
+#define MCF_ETPU_ECSSR_SS16              (0x00010000)\r
+#define MCF_ETPU_ECSSR_SS17              (0x00020000)\r
+#define MCF_ETPU_ECSSR_SS18              (0x00040000)\r
+#define MCF_ETPU_ECSSR_SS19              (0x00080000)\r
+#define MCF_ETPU_ECSSR_SS20              (0x00100000)\r
+#define MCF_ETPU_ECSSR_SS21              (0x00200000)\r
+#define MCF_ETPU_ECSSR_SS22              (0x00400000)\r
+#define MCF_ETPU_ECSSR_SS23              (0x00800000)\r
+#define MCF_ETPU_ECSSR_SS24              (0x01000000)\r
+#define MCF_ETPU_ECSSR_SS25              (0x02000000)\r
+#define MCF_ETPU_ECSSR_SS26              (0x04000000)\r
+#define MCF_ETPU_ECSSR_SS27              (0x08000000)\r
+#define MCF_ETPU_ECSSR_SS28              (0x10000000)\r
+#define MCF_ETPU_ECSSR_SS29              (0x20000000)\r
+#define MCF_ETPU_ECSSR_SS30              (0x40000000)\r
+#define MCF_ETPU_ECSSR_SS31              (0x80000000)\r
+\r
+/* Bit definitions and macros for MCF_ETPU_ECnSCR */\r
+#define MCF_ETPU_ECnSCR_FM(x)            (((x)&0x00000003)<<0)\r
+#define MCF_ETPU_ECnSCR_OBE              (0x00002000)\r
+#define MCF_ETPU_ECnSCR_OPS              (0x00004000)\r
+#define MCF_ETPU_ECnSCR_IPS              (0x00008000)\r
+#define MCF_ETPU_ECnSCR_DTROS            (0x00400000)\r
+#define MCF_ETPU_ECnSCR_DTRS             (0x00800000)\r
+#define MCF_ETPU_ECnSCR_CIOS             (0x40000000)\r
+#define MCF_ETPU_ECnSCR_CIS              (0x80000000)\r
+\r
+/* Bit definitions and macros for MCF_ETPU_ECnCR */\r
+#define MCF_ETPU_ECnCR_CPBA(x)           (((x)&0x000007FF)<<0)\r
+#define MCF_ETPU_ECnCR_OPOL              (0x00004000)\r
+#define MCF_ETPU_ECnCR_ODIS              (0x00008000)\r
+#define MCF_ETPU_ECnCR_CFS(x)            (((x)&0x0000001F)<<16)\r
+#define MCF_ETPU_ECnCR_ETCS              (0x01000000)\r
+#define MCF_ETPU_ECnCR_CPR(x)            (((x)&0x00000003)<<28)\r
+#define MCF_ETPU_ECnCR_DTRE              (0x40000000)\r
+#define MCF_ETPU_ECnCR_CIE               (0x80000000)\r
+\r
+/* Bit definitions and macros for MCF_ETPU_ECnHSSR */\r
+#define MCF_ETPU_ECnHSSR_HSR(x)          (((x)&0x00000007)<<0)\r
+\r
+/********************************************************************/\r
+\r
+#endif /* __MCF523X_ETPU_H__ */\r
index 2b20a153f14fc0b631f84da6deae0abdc26130ce..a4a209d50199cd00bc970ef4a687575d5c1a5703 100644 (file)
-/*
- * These files are taken from the MCF523X source code example package
- * which is available on the Freescale website. Freescale explicitly 
- * grants the redistribution and modification of these source files.
- * The complete licensing information is available in the file 
- * LICENSE_FREESCALE.TXT.
- *
- * File:       mcf523x_fec.h
- * Purpose:    Register and bit definitions for the MCF523X
- *
- * Notes:      
- *     
- */
-
-#ifndef __MCF523X_FEC_H__
-#define __MCF523X_FEC_H__
-
-/*********************************************************************
-*
-* Fast Ethernet Controller (FEC)
-*
-*********************************************************************/
-
-/* Register read/write macros */
-#define MCF_FEC_EIR                   (*(vuint32*)(void*)(&__IPSBAR[0x001004]))
-#define MCF_FEC_EIMR                  (*(vuint32*)(void*)(&__IPSBAR[0x001008]))
-#define MCF_FEC_RDAR                  (*(vuint32*)(void*)(&__IPSBAR[0x001010]))
-#define MCF_FEC_TDAR                  (*(vuint32*)(void*)(&__IPSBAR[0x001014]))
-#define MCF_FEC_ECR                   (*(vuint32*)(void*)(&__IPSBAR[0x001024]))
-#define MCF_FEC_MMFR                  (*(vuint32*)(void*)(&__IPSBAR[0x001040]))
-#define MCF_FEC_MSCR                  (*(vuint32*)(void*)(&__IPSBAR[0x001044]))
-#define MCF_FEC_MIBC                  (*(vuint32*)(void*)(&__IPSBAR[0x001064]))
-#define MCF_FEC_RCR                   (*(vuint32*)(void*)(&__IPSBAR[0x001084]))
-#define MCF_FEC_TCR                   (*(vuint32*)(void*)(&__IPSBAR[0x0010C4]))
-#define MCF_FEC_PALR                  (*(vuint32*)(void*)(&__IPSBAR[0x0010E4]))
-#define MCF_FEC_PAUR                  (*(vuint32*)(void*)(&__IPSBAR[0x0010E8]))
-#define MCF_FEC_OPD                   (*(vuint32*)(void*)(&__IPSBAR[0x0010EC]))
-#define MCF_FEC_IAUR                  (*(vuint32*)(void*)(&__IPSBAR[0x001118]))
-#define MCF_FEC_IALR                  (*(vuint32*)(void*)(&__IPSBAR[0x00111C]))
-#define MCF_FEC_GAUR                  (*(vuint32*)(void*)(&__IPSBAR[0x001120]))
-#define MCF_FEC_GALR                  (*(vuint32*)(void*)(&__IPSBAR[0x001124]))
-#define MCF_FEC_TFWR                  (*(vuint32*)(void*)(&__IPSBAR[0x001144]))
-#define MCF_FEC_FRBR                  (*(vuint32*)(void*)(&__IPSBAR[0x00114C]))
-#define MCF_FEC_FRSR                  (*(vuint32*)(void*)(&__IPSBAR[0x001150]))
-#define MCF_FEC_ERDSR                 (*(vuint32*)(void*)(&__IPSBAR[0x001180]))
-#define MCF_FEC_ETDSR                 (*(vuint32*)(void*)(&__IPSBAR[0x001184]))
-#define MCF_FEC_EMRBR                 (*(vuint32*)(void*)(&__IPSBAR[0x001188]))
-#define MCF_FEC_RMON_T_DROP           (*(vuint32*)(void*)(&__IPSBAR[0x001200]))
-#define MCF_FEC_RMON_T_PACKETS        (*(vuint32*)(void*)(&__IPSBAR[0x001204]))
-#define MCF_FEC_RMON_T_BC_PKT         (*(vuint32*)(void*)(&__IPSBAR[0x001208]))
-#define MCF_FEC_RMON_T_MC_PKT         (*(vuint32*)(void*)(&__IPSBAR[0x00120C]))
-#define MCF_FEC_RMON_T_CRC_ALIGN      (*(vuint32*)(void*)(&__IPSBAR[0x001210]))
-#define MCF_FEC_RMON_T_UNDERSIZE      (*(vuint32*)(void*)(&__IPSBAR[0x001214]))
-#define MCF_FEC_RMON_T_OVERSIZE       (*(vuint32*)(void*)(&__IPSBAR[0x001218]))
-#define MCF_FEC_RMON_T_FRAG           (*(vuint32*)(void*)(&__IPSBAR[0x00121C]))
-#define MCF_FEC_RMON_T_JAB            (*(vuint32*)(void*)(&__IPSBAR[0x001220]))
-#define MCF_FEC_RMON_T_COL            (*(vuint32*)(void*)(&__IPSBAR[0x001224]))
-#define MCF_FEC_RMON_T_P64            (*(vuint32*)(void*)(&__IPSBAR[0x001228]))
-#define MCF_FEC_RMON_T_P65TO127       (*(vuint32*)(void*)(&__IPSBAR[0x00122C]))
-#define MCF_FEC_RMON_T_P128TO255      (*(vuint32*)(void*)(&__IPSBAR[0x001230]))
-#define MCF_FEC_RMON_T_P256TO511      (*(vuint32*)(void*)(&__IPSBAR[0x001234]))
-#define MCF_FEC_RMON_T_P512TO1023     (*(vuint32*)(void*)(&__IPSBAR[0x001238]))
-#define MCF_FEC_RMON_T_P1024TO2047    (*(vuint32*)(void*)(&__IPSBAR[0x00123C]))
-#define MCF_FEC_RMON_T_P_GTE2048      (*(vuint32*)(void*)(&__IPSBAR[0x001240]))
-#define MCF_FEC_RMON_T_OCTETS         (*(vuint32*)(void*)(&__IPSBAR[0x001244]))
-#define MCF_FEC_IEEE_T_DROP           (*(vuint32*)(void*)(&__IPSBAR[0x001248]))
-#define MCF_FEC_IEEE_T_FRAME_OK       (*(vuint32*)(void*)(&__IPSBAR[0x00124C]))
-#define MCF_FEC_IEEE_T_1COL           (*(vuint32*)(void*)(&__IPSBAR[0x001250]))
-#define MCF_FEC_IEEE_T_MCOL           (*(vuint32*)(void*)(&__IPSBAR[0x001254]))
-#define MCF_FEC_IEEE_T_DEF            (*(vuint32*)(void*)(&__IPSBAR[0x001258]))
-#define MCF_FEC_IEEE_T_LCOL           (*(vuint32*)(void*)(&__IPSBAR[0x00125C]))
-#define MCF_FEC_IEEE_T_EXCOL          (*(vuint32*)(void*)(&__IPSBAR[0x001260]))
-#define MCF_FEC_IEEE_T_MACERR         (*(vuint32*)(void*)(&__IPSBAR[0x001264]))
-#define MCF_FEC_IEEE_T_CSERR          (*(vuint32*)(void*)(&__IPSBAR[0x001268]))
-#define MCF_FEC_IEEE_T_SQE            (*(vuint32*)(void*)(&__IPSBAR[0x00126C]))
-#define MCF_FEC_IEEE_T_FDXFC          (*(vuint32*)(void*)(&__IPSBAR[0x001270]))
-#define MCF_FEC_IEEE_T_OCTETS_OK      (*(vuint32*)(void*)(&__IPSBAR[0x001274]))
-#define MCF_FEC_RMON_R_PACKETS        (*(vuint32*)(void*)(&__IPSBAR[0x001284]))
-#define MCF_FEC_RMON_R_BC_PKT         (*(vuint32*)(void*)(&__IPSBAR[0x001288]))
-#define MCF_FEC_RMON_R_MC_PKT         (*(vuint32*)(void*)(&__IPSBAR[0x00128C]))
-#define MCF_FEC_RMON_R_CRC_ALIGN      (*(vuint32*)(void*)(&__IPSBAR[0x001290]))
-#define MCF_FEC_RMON_R_UNDERSIZE      (*(vuint32*)(void*)(&__IPSBAR[0x001294]))
-#define MCF_FEC_RMON_R_OVERSIZE       (*(vuint32*)(void*)(&__IPSBAR[0x001298]))
-#define MCF_FEC_RMON_R_FRAG           (*(vuint32*)(void*)(&__IPSBAR[0x00129C]))
-#define MCF_FEC_RMON_R_JAB            (*(vuint32*)(void*)(&__IPSBAR[0x0012A0]))
-#define MCF_FEC_RMON_R_RESVD_0        (*(vuint32*)(void*)(&__IPSBAR[0x0012A4]))
-#define MCF_FEC_RMON_R_P64            (*(vuint32*)(void*)(&__IPSBAR[0x0012A8]))
-#define MCF_FEC_RMON_R_P65TO127       (*(vuint32*)(void*)(&__IPSBAR[0x0012AC]))
-#define MCF_FEC_RMON_R_P128TO255      (*(vuint32*)(void*)(&__IPSBAR[0x0012B0]))
-#define MCF_FEC_RMON_R_P256TO511      (*(vuint32*)(void*)(&__IPSBAR[0x0012B4]))
-#define MCF_FEC_RMON_R_512TO1023      (*(vuint32*)(void*)(&__IPSBAR[0x0012B8]))
-#define MCF_FEC_RMON_R_P_GTE2048      (*(vuint32*)(void*)(&__IPSBAR[0x0012C0]))
-#define MCF_FEC_RMON_R_1024TO2047     (*(vuint32*)(void*)(&__IPSBAR[0x0012BC]))
-#define MCF_FEC_RMON_R_OCTETS         (*(vuint32*)(void*)(&__IPSBAR[0x0012C4]))
-#define MCF_FEC_IEEE_R_DROP           (*(vuint32*)(void*)(&__IPSBAR[0x0012C8]))
-#define MCF_FEC_IEEE_R_FRAME_OK       (*(vuint32*)(void*)(&__IPSBAR[0x0012CC]))
-#define MCF_FEC_IEEE_R_CRC            (*(vuint32*)(void*)(&__IPSBAR[0x0012D0]))
-#define MCF_FEC_IEEE_R_ALIGN          (*(vuint32*)(void*)(&__IPSBAR[0x0012D4]))
-#define MCF_FEC_IEEE_R_MACERR         (*(vuint32*)(void*)(&__IPSBAR[0x0012D8]))
-#define MCF_FEC_IEEE_R_FDXFC          (*(vuint32*)(void*)(&__IPSBAR[0x0012DC]))
-#define MCF_FEC_IEEE_R_OCTETS_OK      (*(vuint32*)(void*)(&__IPSBAR[0x0012E0]))
-
-/* Bit definitions and macros for MCF_FEC_EIR */
-#define MCF_FEC_EIR_UN                  (0x00080000)
-#define MCF_FEC_EIR_RL                  (0x00100000)
-#define MCF_FEC_EIR_LC                  (0x00200000)
-#define MCF_FEC_EIR_EBERR               (0x00400000)
-#define MCF_FEC_EIR_MII                 (0x00800000)
-#define MCF_FEC_EIR_RXB                 (0x01000000)
-#define MCF_FEC_EIR_RXF                 (0x02000000)
-#define MCF_FEC_EIR_TXB                 (0x04000000)
-#define MCF_FEC_EIR_TXF                 (0x08000000)
-#define MCF_FEC_EIR_GRA                 (0x10000000)
-#define MCF_FEC_EIR_BABT                (0x20000000)
-#define MCF_FEC_EIR_BABR                (0x40000000)
-#define MCF_FEC_EIR_HBERR               (0x80000000)
-
-/* Bit definitions and macros for MCF_FEC_EIMR */
-#define MCF_FEC_EIMR_UN                 (0x00080000)
-#define MCF_FEC_EIMR_RL                 (0x00100000)
-#define MCF_FEC_EIMR_LC                 (0x00200000)
-#define MCF_FEC_EIMR_EBERR              (0x00400000)
-#define MCF_FEC_EIMR_MII                (0x00800000)
-#define MCF_FEC_EIMR_RXB                (0x01000000)
-#define MCF_FEC_EIMR_RXF                (0x02000000)
-#define MCF_FEC_EIMR_TXB                (0x04000000)
-#define MCF_FEC_EIMR_TXF                (0x08000000)
-#define MCF_FEC_EIMR_GRA                (0x10000000)
-#define MCF_FEC_EIMR_BABT               (0x20000000)
-#define MCF_FEC_EIMR_BABR               (0x40000000)
-#define MCF_FEC_EIMR_HBERR              (0x80000000)
-
-/* Bit definitions and macros for MCF_FEC_RDAR */
-#define MCF_FEC_RDAR_R_DES_ACTIVE       (0x01000000)
-
-/* Bit definitions and macros for MCF_FEC_TDAR */
-#define MCF_FEC_TDAR_X_DES_ACTIVE       (0x01000000)
-
-/* Bit definitions and macros for MCF_FEC_ECR */
-#define MCF_FEC_ECR_RESET               (0x00000001)
-#define MCF_FEC_ECR_ETHER_EN            (0x00000002)
-
-/* Bit definitions and macros for MCF_FEC_MMFR */
-#define MCF_FEC_MMFR_DATA(x)            (((x)&0x0000FFFF)<<0)
-#define MCF_FEC_MMFR_TA(x)              (((x)&0x00000003)<<16)
-#define MCF_FEC_MMFR_RA(x)              (((x)&0x0000001F)<<18)
-#define MCF_FEC_MMFR_PA(x)              (((x)&0x0000001F)<<23)
-#define MCF_FEC_MMFR_OP(x)              (((x)&0x00000003)<<28)
-#define MCF_FEC_MMFR_ST(x)              (((x)&0x00000003)<<30)
-#define MCF_FEC_MMFR_ST_01             (0x40000000)
-#define MCF_FEC_MMFR_OP_READ           (0x20000000)
-#define MCF_FEC_MMFR_OP_WRITE          (0x10000000)
-#define MCF_FEC_MMFR_TA_10             (0x00020000)
-
-
-/* Bit definitions and macros for MCF_FEC_MSCR */
-#define MCF_FEC_MSCR_MII_SPEED(x)       (((x)&0x0000003F)<<1)
-#define MCF_FEC_MSCR_DIS_PREAMBLE       (0x00000080)
-
-/* Bit definitions and macros for MCF_FEC_MIBC */
-#define MCF_FEC_MIBC_MIB_IDLE           (0x40000000)
-#define MCF_FEC_MIBC_MIB_DISABLE        (0x80000000)
-
-/* Bit definitions and macros for MCF_FEC_RCR */
-#define MCF_FEC_RCR_LOOP                (0x00000001)
-#define MCF_FEC_RCR_DRT                 (0x00000002)
-#define MCF_FEC_RCR_MII_MODE            (0x00000004)
-#define MCF_FEC_RCR_PROM                (0x00000008)
-#define MCF_FEC_RCR_BC_REJ              (0x00000010)
-#define MCF_FEC_RCR_FCE                 (0x00000020)
-#define MCF_FEC_RCR_MAX_FL(x)           (((x)&0x000007FF)<<16)
-
-/* Bit definitions and macros for MCF_FEC_TCR */
-#define MCF_FEC_TCR_GTS                 (0x00000001)
-#define MCF_FEC_TCR_HBC                 (0x00000002)
-#define MCF_FEC_TCR_FDEN                (0x00000004)
-#define MCF_FEC_TCR_TFC_PAUSE           (0x00000008)
-#define MCF_FEC_TCR_RFC_PAUSE           (0x00000010)
-
-/* Bit definitions and macros for MCF_FEC_PAUR */
-#define MCF_FEC_PAUR_TYPE(x)            (((x)&0x0000FFFF)<<0)
-#define MCF_FEC_PAUR_PADDR2(x)          (((x)&0x0000FFFF)<<16)
-
-/* Bit definitions and macros for MCF_FEC_OPD */
-#define MCF_FEC_OPD_PAUSE_DUR(x)        (((x)&0x0000FFFF)<<0)
-#define MCF_FEC_OPD_OPCODE(x)           (((x)&0x0000FFFF)<<16)
-
-/* Bit definitions and macros for MCF_FEC_TFWR */
-#define MCF_FEC_TFWR_X_WMRK(x)          (((x)&0x00000003)<<0)
-
-/* Bit definitions and macros for MCF_FEC_FRBR */
-#define MCF_FEC_FRBR_R_BOUND(x)         (((x)&0x000000FF)<<2)
-
-/* Bit definitions and macros for MCF_FEC_FRSR */
-#define MCF_FEC_FRSR_R_FSTART(x)        (((x)&0x000000FF)<<2)
-
-/* Bit definitions and macros for MCF_FEC_ERDSR */
-#define MCF_FEC_ERDSR_R_DES_START(x)    (((x)&0x3FFFFFFF)<<2)
-
-/* Bit definitions and macros for MCF_FEC_ETDSR */
-#define MCF_FEC_ETDSR_X_DES_START(x)    (((x)&0x3FFFFFFF)<<2)
-
-/* Bit definitions and macros for MCF_FEC_EMRBR */
-#define MCF_FEC_EMRBR_R_BUF_SIZE(x)     (((x)&0x0000007F)<<4)
-
-/********************************************************************/
-
-#endif /* __MCF523X_FEC_H__ */
+/*\r
+ * These files are taken from the MCF523X source code example package\r
+ * which is available on the Freescale website. Freescale explicitly \r
+ * grants the redistribution and modification of these source files.\r
+ * The complete licensing information is available in the file \r
+ * LICENSE_FREESCALE.TXT.\r
+ *\r
+ * File:       mcf523x_fec.h\r
+ * Purpose:    Register and bit definitions for the MCF523X\r
+ *\r
+ * Notes:      \r
+ *     \r
+ */\r
+\r
+#ifndef __MCF523X_FEC_H__\r
+#define __MCF523X_FEC_H__\r
+\r
+/*********************************************************************\r
+*\r
+* Fast Ethernet Controller (FEC)\r
+*\r
+*********************************************************************/\r
+\r
+/* Register read/write macros */\r
+#define MCF_FEC_EIR                   (*(vuint32*)(void*)(&__IPSBAR[0x001004]))\r
+#define MCF_FEC_EIMR                  (*(vuint32*)(void*)(&__IPSBAR[0x001008]))\r
+#define MCF_FEC_RDAR                  (*(vuint32*)(void*)(&__IPSBAR[0x001010]))\r
+#define MCF_FEC_TDAR                  (*(vuint32*)(void*)(&__IPSBAR[0x001014]))\r
+#define MCF_FEC_ECR                   (*(vuint32*)(void*)(&__IPSBAR[0x001024]))\r
+#define MCF_FEC_MMFR                  (*(vuint32*)(void*)(&__IPSBAR[0x001040]))\r
+#define MCF_FEC_MSCR                  (*(vuint32*)(void*)(&__IPSBAR[0x001044]))\r
+#define MCF_FEC_MIBC                  (*(vuint32*)(void*)(&__IPSBAR[0x001064]))\r
+#define MCF_FEC_RCR                   (*(vuint32*)(void*)(&__IPSBAR[0x001084]))\r
+#define MCF_FEC_TCR                   (*(vuint32*)(void*)(&__IPSBAR[0x0010C4]))\r
+#define MCF_FEC_PALR                  (*(vuint32*)(void*)(&__IPSBAR[0x0010E4]))\r
+#define MCF_FEC_PAUR                  (*(vuint32*)(void*)(&__IPSBAR[0x0010E8]))\r
+#define MCF_FEC_OPD                   (*(vuint32*)(void*)(&__IPSBAR[0x0010EC]))\r
+#define MCF_FEC_IAUR                  (*(vuint32*)(void*)(&__IPSBAR[0x001118]))\r
+#define MCF_FEC_IALR                  (*(vuint32*)(void*)(&__IPSBAR[0x00111C]))\r
+#define MCF_FEC_GAUR                  (*(vuint32*)(void*)(&__IPSBAR[0x001120]))\r
+#define MCF_FEC_GALR                  (*(vuint32*)(void*)(&__IPSBAR[0x001124]))\r
+#define MCF_FEC_TFWR                  (*(vuint32*)(void*)(&__IPSBAR[0x001144]))\r
+#define MCF_FEC_FRBR                  (*(vuint32*)(void*)(&__IPSBAR[0x00114C]))\r
+#define MCF_FEC_FRSR                  (*(vuint32*)(void*)(&__IPSBAR[0x001150]))\r
+#define MCF_FEC_ERDSR                 (*(vuint32*)(void*)(&__IPSBAR[0x001180]))\r
+#define MCF_FEC_ETDSR                 (*(vuint32*)(void*)(&__IPSBAR[0x001184]))\r
+#define MCF_FEC_EMRBR                 (*(vuint32*)(void*)(&__IPSBAR[0x001188]))\r
+#define MCF_FEC_RMON_T_DROP           (*(vuint32*)(void*)(&__IPSBAR[0x001200]))\r
+#define MCF_FEC_RMON_T_PACKETS        (*(vuint32*)(void*)(&__IPSBAR[0x001204]))\r
+#define MCF_FEC_RMON_T_BC_PKT         (*(vuint32*)(void*)(&__IPSBAR[0x001208]))\r
+#define MCF_FEC_RMON_T_MC_PKT         (*(vuint32*)(void*)(&__IPSBAR[0x00120C]))\r
+#define MCF_FEC_RMON_T_CRC_ALIGN      (*(vuint32*)(void*)(&__IPSBAR[0x001210]))\r
+#define MCF_FEC_RMON_T_UNDERSIZE      (*(vuint32*)(void*)(&__IPSBAR[0x001214]))\r
+#define MCF_FEC_RMON_T_OVERSIZE       (*(vuint32*)(void*)(&__IPSBAR[0x001218]))\r
+#define MCF_FEC_RMON_T_FRAG           (*(vuint32*)(void*)(&__IPSBAR[0x00121C]))\r
+#define MCF_FEC_RMON_T_JAB            (*(vuint32*)(void*)(&__IPSBAR[0x001220]))\r
+#define MCF_FEC_RMON_T_COL            (*(vuint32*)(void*)(&__IPSBAR[0x001224]))\r
+#define MCF_FEC_RMON_T_P64            (*(vuint32*)(void*)(&__IPSBAR[0x001228]))\r
+#define MCF_FEC_RMON_T_P65TO127       (*(vuint32*)(void*)(&__IPSBAR[0x00122C]))\r
+#define MCF_FEC_RMON_T_P128TO255      (*(vuint32*)(void*)(&__IPSBAR[0x001230]))\r
+#define MCF_FEC_RMON_T_P256TO511      (*(vuint32*)(void*)(&__IPSBAR[0x001234]))\r
+#define MCF_FEC_RMON_T_P512TO1023     (*(vuint32*)(void*)(&__IPSBAR[0x001238]))\r
+#define MCF_FEC_RMON_T_P1024TO2047    (*(vuint32*)(void*)(&__IPSBAR[0x00123C]))\r
+#define MCF_FEC_RMON_T_P_GTE2048      (*(vuint32*)(void*)(&__IPSBAR[0x001240]))\r
+#define MCF_FEC_RMON_T_OCTETS         (*(vuint32*)(void*)(&__IPSBAR[0x001244]))\r
+#define MCF_FEC_IEEE_T_DROP           (*(vuint32*)(void*)(&__IPSBAR[0x001248]))\r
+#define MCF_FEC_IEEE_T_FRAME_OK       (*(vuint32*)(void*)(&__IPSBAR[0x00124C]))\r
+#define MCF_FEC_IEEE_T_1COL           (*(vuint32*)(void*)(&__IPSBAR[0x001250]))\r
+#define MCF_FEC_IEEE_T_MCOL           (*(vuint32*)(void*)(&__IPSBAR[0x001254]))\r
+#define MCF_FEC_IEEE_T_DEF            (*(vuint32*)(void*)(&__IPSBAR[0x001258]))\r
+#define MCF_FEC_IEEE_T_LCOL           (*(vuint32*)(void*)(&__IPSBAR[0x00125C]))\r
+#define MCF_FEC_IEEE_T_EXCOL          (*(vuint32*)(void*)(&__IPSBAR[0x001260]))\r
+#define MCF_FEC_IEEE_T_MACERR         (*(vuint32*)(void*)(&__IPSBAR[0x001264]))\r
+#define MCF_FEC_IEEE_T_CSERR          (*(vuint32*)(void*)(&__IPSBAR[0x001268]))\r
+#define MCF_FEC_IEEE_T_SQE            (*(vuint32*)(void*)(&__IPSBAR[0x00126C]))\r
+#define MCF_FEC_IEEE_T_FDXFC          (*(vuint32*)(void*)(&__IPSBAR[0x001270]))\r
+#define MCF_FEC_IEEE_T_OCTETS_OK      (*(vuint32*)(void*)(&__IPSBAR[0x001274]))\r
+#define MCF_FEC_RMON_R_PACKETS        (*(vuint32*)(void*)(&__IPSBAR[0x001284]))\r
+#define MCF_FEC_RMON_R_BC_PKT         (*(vuint32*)(void*)(&__IPSBAR[0x001288]))\r
+#define MCF_FEC_RMON_R_MC_PKT         (*(vuint32*)(void*)(&__IPSBAR[0x00128C]))\r
+#define MCF_FEC_RMON_R_CRC_ALIGN      (*(vuint32*)(void*)(&__IPSBAR[0x001290]))\r
+#define MCF_FEC_RMON_R_UNDERSIZE      (*(vuint32*)(void*)(&__IPSBAR[0x001294]))\r
+#define MCF_FEC_RMON_R_OVERSIZE       (*(vuint32*)(void*)(&__IPSBAR[0x001298]))\r
+#define MCF_FEC_RMON_R_FRAG           (*(vuint32*)(void*)(&__IPSBAR[0x00129C]))\r
+#define MCF_FEC_RMON_R_JAB            (*(vuint32*)(void*)(&__IPSBAR[0x0012A0]))\r
+#define MCF_FEC_RMON_R_RESVD_0        (*(vuint32*)(void*)(&__IPSBAR[0x0012A4]))\r
+#define MCF_FEC_RMON_R_P64            (*(vuint32*)(void*)(&__IPSBAR[0x0012A8]))\r
+#define MCF_FEC_RMON_R_P65TO127       (*(vuint32*)(void*)(&__IPSBAR[0x0012AC]))\r
+#define MCF_FEC_RMON_R_P128TO255      (*(vuint32*)(void*)(&__IPSBAR[0x0012B0]))\r
+#define MCF_FEC_RMON_R_P256TO511      (*(vuint32*)(void*)(&__IPSBAR[0x0012B4]))\r
+#define MCF_FEC_RMON_R_512TO1023      (*(vuint32*)(void*)(&__IPSBAR[0x0012B8]))\r
+#define MCF_FEC_RMON_R_P_GTE2048      (*(vuint32*)(void*)(&__IPSBAR[0x0012C0]))\r
+#define MCF_FEC_RMON_R_1024TO2047     (*(vuint32*)(void*)(&__IPSBAR[0x0012BC]))\r
+#define MCF_FEC_RMON_R_OCTETS         (*(vuint32*)(void*)(&__IPSBAR[0x0012C4]))\r
+#define MCF_FEC_IEEE_R_DROP           (*(vuint32*)(void*)(&__IPSBAR[0x0012C8]))\r
+#define MCF_FEC_IEEE_R_FRAME_OK       (*(vuint32*)(void*)(&__IPSBAR[0x0012CC]))\r
+#define MCF_FEC_IEEE_R_CRC            (*(vuint32*)(void*)(&__IPSBAR[0x0012D0]))\r
+#define MCF_FEC_IEEE_R_ALIGN          (*(vuint32*)(void*)(&__IPSBAR[0x0012D4]))\r
+#define MCF_FEC_IEEE_R_MACERR         (*(vuint32*)(void*)(&__IPSBAR[0x0012D8]))\r
+#define MCF_FEC_IEEE_R_FDXFC          (*(vuint32*)(void*)(&__IPSBAR[0x0012DC]))\r
+#define MCF_FEC_IEEE_R_OCTETS_OK      (*(vuint32*)(void*)(&__IPSBAR[0x0012E0]))\r
+\r
+/* Bit definitions and macros for MCF_FEC_EIR */\r
+#define MCF_FEC_EIR_UN                  (0x00080000)\r
+#define MCF_FEC_EIR_RL                  (0x00100000)\r
+#define MCF_FEC_EIR_LC                  (0x00200000)\r
+#define MCF_FEC_EIR_EBERR               (0x00400000)\r
+#define MCF_FEC_EIR_MII                 (0x00800000)\r
+#define MCF_FEC_EIR_RXB                 (0x01000000)\r
+#define MCF_FEC_EIR_RXF                 (0x02000000)\r
+#define MCF_FEC_EIR_TXB                 (0x04000000)\r
+#define MCF_FEC_EIR_TXF                 (0x08000000)\r
+#define MCF_FEC_EIR_GRA                 (0x10000000)\r
+#define MCF_FEC_EIR_BABT                (0x20000000)\r
+#define MCF_FEC_EIR_BABR                (0x40000000)\r
+#define MCF_FEC_EIR_HBERR               (0x80000000)\r
+\r
+/* Bit definitions and macros for MCF_FEC_EIMR */\r
+#define MCF_FEC_EIMR_UN                 (0x00080000)\r
+#define MCF_FEC_EIMR_RL                 (0x00100000)\r
+#define MCF_FEC_EIMR_LC                 (0x00200000)\r
+#define MCF_FEC_EIMR_EBERR              (0x00400000)\r
+#define MCF_FEC_EIMR_MII                (0x00800000)\r
+#define MCF_FEC_EIMR_RXB                (0x01000000)\r
+#define MCF_FEC_EIMR_RXF                (0x02000000)\r
+#define MCF_FEC_EIMR_TXB                (0x04000000)\r
+#define MCF_FEC_EIMR_TXF                (0x08000000)\r
+#define MCF_FEC_EIMR_GRA                (0x10000000)\r
+#define MCF_FEC_EIMR_BABT               (0x20000000)\r
+#define MCF_FEC_EIMR_BABR               (0x40000000)\r
+#define MCF_FEC_EIMR_HBERR              (0x80000000)\r
+\r
+/* Bit definitions and macros for MCF_FEC_RDAR */\r
+#define MCF_FEC_RDAR_R_DES_ACTIVE       (0x01000000)\r
+\r
+/* Bit definitions and macros for MCF_FEC_TDAR */\r
+#define MCF_FEC_TDAR_X_DES_ACTIVE       (0x01000000)\r
+\r
+/* Bit definitions and macros for MCF_FEC_ECR */\r
+#define MCF_FEC_ECR_RESET               (0x00000001)\r
+#define MCF_FEC_ECR_ETHER_EN            (0x00000002)\r
+\r
+/* Bit definitions and macros for MCF_FEC_MMFR */\r
+#define MCF_FEC_MMFR_DATA(x)            (((x)&0x0000FFFF)<<0)\r
+#define MCF_FEC_MMFR_TA(x)              (((x)&0x00000003)<<16)\r
+#define MCF_FEC_MMFR_RA(x)              (((x)&0x0000001F)<<18)\r
+#define MCF_FEC_MMFR_PA(x)              (((x)&0x0000001F)<<23)\r
+#define MCF_FEC_MMFR_OP(x)              (((x)&0x00000003)<<28)\r
+#define MCF_FEC_MMFR_ST(x)              (((x)&0x00000003)<<30)\r
+#define MCF_FEC_MMFR_ST_01             (0x40000000)\r
+#define MCF_FEC_MMFR_OP_READ           (0x20000000)\r
+#define MCF_FEC_MMFR_OP_WRITE          (0x10000000)\r
+#define MCF_FEC_MMFR_TA_10             (0x00020000)\r
+\r
+\r
+/* Bit definitions and macros for MCF_FEC_MSCR */\r
+#define MCF_FEC_MSCR_MII_SPEED(x)       (((x)&0x0000003F)<<1)\r
+#define MCF_FEC_MSCR_DIS_PREAMBLE       (0x00000080)\r
+\r
+/* Bit definitions and macros for MCF_FEC_MIBC */\r
+#define MCF_FEC_MIBC_MIB_IDLE           (0x40000000)\r
+#define MCF_FEC_MIBC_MIB_DISABLE        (0x80000000)\r
+\r
+/* Bit definitions and macros for MCF_FEC_RCR */\r
+#define MCF_FEC_RCR_LOOP                (0x00000001)\r
+#define MCF_FEC_RCR_DRT                 (0x00000002)\r
+#define MCF_FEC_RCR_MII_MODE            (0x00000004)\r
+#define MCF_FEC_RCR_PROM                (0x00000008)\r
+#define MCF_FEC_RCR_BC_REJ              (0x00000010)\r
+#define MCF_FEC_RCR_FCE                 (0x00000020)\r
+#define MCF_FEC_RCR_MAX_FL(x)           (((x)&0x000007FF)<<16)\r
+\r
+/* Bit definitions and macros for MCF_FEC_TCR */\r
+#define MCF_FEC_TCR_GTS                 (0x00000001)\r
+#define MCF_FEC_TCR_HBC                 (0x00000002)\r
+#define MCF_FEC_TCR_FDEN                (0x00000004)\r
+#define MCF_FEC_TCR_TFC_PAUSE           (0x00000008)\r
+#define MCF_FEC_TCR_RFC_PAUSE           (0x00000010)\r
+\r
+/* Bit definitions and macros for MCF_FEC_PAUR */\r
+#define MCF_FEC_PAUR_TYPE(x)            (((x)&0x0000FFFF)<<0)\r
+#define MCF_FEC_PAUR_PADDR2(x)          (((x)&0x0000FFFF)<<16)\r
+\r
+/* Bit definitions and macros for MCF_FEC_OPD */\r
+#define MCF_FEC_OPD_PAUSE_DUR(x)        (((x)&0x0000FFFF)<<0)\r
+#define MCF_FEC_OPD_OPCODE(x)           (((x)&0x0000FFFF)<<16)\r
+\r
+/* Bit definitions and macros for MCF_FEC_TFWR */\r
+#define MCF_FEC_TFWR_X_WMRK(x)          (((x)&0x00000003)<<0)\r
+\r
+/* Bit definitions and macros for MCF_FEC_FRBR */\r
+#define MCF_FEC_FRBR_R_BOUND(x)         (((x)&0x000000FF)<<2)\r
+\r
+/* Bit definitions and macros for MCF_FEC_FRSR */\r
+#define MCF_FEC_FRSR_R_FSTART(x)        (((x)&0x000000FF)<<2)\r
+\r
+/* Bit definitions and macros for MCF_FEC_ERDSR */\r
+#define MCF_FEC_ERDSR_R_DES_START(x)    (((x)&0x3FFFFFFF)<<2)\r
+\r
+/* Bit definitions and macros for MCF_FEC_ETDSR */\r
+#define MCF_FEC_ETDSR_X_DES_START(x)    (((x)&0x3FFFFFFF)<<2)\r
+\r
+/* Bit definitions and macros for MCF_FEC_EMRBR */\r
+#define MCF_FEC_EMRBR_R_BUF_SIZE(x)     (((x)&0x0000007F)<<4)\r
+\r
+/********************************************************************/\r
+\r
+#endif /* __MCF523X_FEC_H__ */\r
index d9dc941d46401b55dc2b06215cd0bb7ae14f2ef4..3f132e896a56e1e05a41e328cf3043a3d0596d74 100644 (file)
@@ -1,55 +1,55 @@
-/*
- * These files are taken from the MCF523X source code example package
- * which is available on the Freescale website. Freescale explicitly 
- * grants the redistribution and modification of these source files.
- * The complete licensing information is available in the file 
- * LICENSE_FREESCALE.TXT.
- *
- * File:       mcf523x_fmpll.h
- * Purpose:    Register and bit definitions for the MCF523X
- *
- * Notes:      
- *     
- */
-
-#ifndef __MCF523X_FMPLL_H__
-#define __MCF523X_FMPLL_H__
-
-/*********************************************************************
-*
-* Frequency Modulated Phase Locked Loop (FMPLL)
-*
-*********************************************************************/
-
-/* Register read/write macros */
-#define MCF_FMPLL_SYNCR    (*(vuint32*)(void*)(&__IPSBAR[0x120000]))
-#define MCF_FMPLL_SYNSR    (*(vuint32*)(void*)(&__IPSBAR[0x120004]))
-
-/* Bit definitions and macros for MCF_FMPLL_SYNCR */
-#define MCF_FMPLL_SYNCR_EXP(x)       (((x)&0x000003FF)<<0)
-#define MCF_FMPLL_SYNCR_DEPTH(x)     (((x)&0x00000003)<<10)
-#define MCF_FMPLL_SYNCR_RATE         (0x00001000)
-#define MCF_FMPLL_SYNCR_LOCIRQ       (0x00002000)
-#define MCF_FMPLL_SYNCR_LOLIRQ       (0x00004000)
-#define MCF_FMPLL_SYNCR_DISCLK       (0x00008000)
-#define MCF_FMPLL_SYNCR_LOCRE        (0x00010000)
-#define MCF_FMPLL_SYNCR_LOLRE        (0x00020000)
-#define MCF_FMPLL_SYNCR_LOCEN        (0x00040000)
-#define MCF_FMPLL_SYNCR_RFD(x)       (((x)&0x00000007)<<19)
-#define MCF_FMPLL_SYNCR_MFD(x)       (((x)&0x00000007)<<24)
-
-/* Bit definitions and macros for MCF_FMPLL_SYNSR */
-#define MCF_FMPLL_SYNSR_CALPASS      (0x00000001)
-#define MCF_FMPLL_SYNSR_CALDONE      (0x00000002)
-#define MCF_FMPLL_SYNSR_LOCF         (0x00000004)
-#define MCF_FMPLL_SYNSR_LOCK         (0x00000008)
-#define MCF_FMPLL_SYNSR_LOCKS        (0x00000010)
-#define MCF_FMPLL_SYNSR_PLLREF       (0x00000020)
-#define MCF_FMPLL_SYNSR_PLLSEL       (0x00000040)
-#define MCF_FMPLL_SYNSR_MODE         (0x00000080)
-#define MCF_FMPLL_SYNSR_LOC          (0x00000100)
-#define MCF_FMPLL_SYNSR_LOLF         (0x00000200)
-
-/********************************************************************/
-
-#endif /* __MCF523X_FMPLL_H__ */
+/*\r
+ * These files are taken from the MCF523X source code example package\r
+ * which is available on the Freescale website. Freescale explicitly \r
+ * grants the redistribution and modification of these source files.\r
+ * The complete licensing information is available in the file \r
+ * LICENSE_FREESCALE.TXT.\r
+ *\r
+ * File:       mcf523x_fmpll.h\r
+ * Purpose:    Register and bit definitions for the MCF523X\r
+ *\r
+ * Notes:      \r
+ *     \r
+ */\r
+\r
+#ifndef __MCF523X_FMPLL_H__\r
+#define __MCF523X_FMPLL_H__\r
+\r
+/*********************************************************************\r
+*\r
+* Frequency Modulated Phase Locked Loop (FMPLL)\r
+*\r
+*********************************************************************/\r
+\r
+/* Register read/write macros */\r
+#define MCF_FMPLL_SYNCR    (*(vuint32*)(void*)(&__IPSBAR[0x120000]))\r
+#define MCF_FMPLL_SYNSR    (*(vuint32*)(void*)(&__IPSBAR[0x120004]))\r
+\r
+/* Bit definitions and macros for MCF_FMPLL_SYNCR */\r
+#define MCF_FMPLL_SYNCR_EXP(x)       (((x)&0x000003FF)<<0)\r
+#define MCF_FMPLL_SYNCR_DEPTH(x)     (((x)&0x00000003)<<10)\r
+#define MCF_FMPLL_SYNCR_RATE         (0x00001000)\r
+#define MCF_FMPLL_SYNCR_LOCIRQ       (0x00002000)\r
+#define MCF_FMPLL_SYNCR_LOLIRQ       (0x00004000)\r
+#define MCF_FMPLL_SYNCR_DISCLK       (0x00008000)\r
+#define MCF_FMPLL_SYNCR_LOCRE        (0x00010000)\r
+#define MCF_FMPLL_SYNCR_LOLRE        (0x00020000)\r
+#define MCF_FMPLL_SYNCR_LOCEN        (0x00040000)\r
+#define MCF_FMPLL_SYNCR_RFD(x)       (((x)&0x00000007)<<19)\r
+#define MCF_FMPLL_SYNCR_MFD(x)       (((x)&0x00000007)<<24)\r
+\r
+/* Bit definitions and macros for MCF_FMPLL_SYNSR */\r
+#define MCF_FMPLL_SYNSR_CALPASS      (0x00000001)\r
+#define MCF_FMPLL_SYNSR_CALDONE      (0x00000002)\r
+#define MCF_FMPLL_SYNSR_LOCF         (0x00000004)\r
+#define MCF_FMPLL_SYNSR_LOCK         (0x00000008)\r
+#define MCF_FMPLL_SYNSR_LOCKS        (0x00000010)\r
+#define MCF_FMPLL_SYNSR_PLLREF       (0x00000020)\r
+#define MCF_FMPLL_SYNSR_PLLSEL       (0x00000040)\r
+#define MCF_FMPLL_SYNSR_MODE         (0x00000080)\r
+#define MCF_FMPLL_SYNSR_LOC          (0x00000100)\r
+#define MCF_FMPLL_SYNSR_LOLF         (0x00000200)\r
+\r
+/********************************************************************/\r
+\r
+#endif /* __MCF523X_FMPLL_H__ */\r
index 455ac850ddea9c994238ae6157ddb8f2ea96ff0e..df8c366001d481f9b41bc1a595dc035c719e5861 100644 (file)
-/*
- * These files are taken from the MCF523X source code example package
- * which is available on the Freescale website. Freescale explicitly 
- * grants the redistribution and modification of these source files.
- * The complete licensing information is available in the file 
- * LICENSE_FREESCALE.TXT.
- *
- * File:       mcf523x_gpio.h
- * Purpose:    Register and bit definitions for the MCF523X
- *
- * Notes:      
- *     
- */
-
-#ifndef __MCF523X_GPIO_H__
-#define __MCF523X_GPIO_H__
-
-/*********************************************************************
-*
-* General Purpose I/O (GPIO)
-*
-*********************************************************************/
-
-/* Register read/write macros */
-#define MCF_GPIO_PODR_ADDR        (*(vuint8 *)(void*)(&__IPSBAR[0x100000]))
-#define MCF_GPIO_PODR_DATAH       (*(vuint8 *)(void*)(&__IPSBAR[0x100001]))
-#define MCF_GPIO_PODR_DATAL       (*(vuint8 *)(void*)(&__IPSBAR[0x100002]))
-#define MCF_GPIO_PODR_BUSCTL      (*(vuint8 *)(void*)(&__IPSBAR[0x100003]))
-#define MCF_GPIO_PODR_BS          (*(vuint8 *)(void*)(&__IPSBAR[0x100004]))
-#define MCF_GPIO_PODR_CS          (*(vuint8 *)(void*)(&__IPSBAR[0x100005]))
-#define MCF_GPIO_PODR_SDRAM       (*(vuint8 *)(void*)(&__IPSBAR[0x100006]))
-#define MCF_GPIO_PODR_FECI2C      (*(vuint8 *)(void*)(&__IPSBAR[0x100007]))
-#define MCF_GPIO_PODR_UARTH       (*(vuint8 *)(void*)(&__IPSBAR[0x100008]))
-#define MCF_GPIO_PODR_UARTL       (*(vuint8 *)(void*)(&__IPSBAR[0x100009]))
-#define MCF_GPIO_PODR_QSPI        (*(vuint8 *)(void*)(&__IPSBAR[0x10000A]))
-#define MCF_GPIO_PODR_TIMER       (*(vuint8 *)(void*)(&__IPSBAR[0x10000B]))
-#define MCF_GPIO_PODR_ETPU        (*(vuint8 *)(void*)(&__IPSBAR[0x10000C]))
-#define MCF_GPIO_PDDR_APDDR       (*(vuint8 *)(void*)(&__IPSBAR[0x100010]))
-#define MCF_GPIO_PDDR_DATAH       (*(vuint8 *)(void*)(&__IPSBAR[0x100011]))
-#define MCF_GPIO_PDDR_DATAL       (*(vuint8 *)(void*)(&__IPSBAR[0x100012]))
-#define MCF_GPIO_PDDR_BUSCTL      (*(vuint8 *)(void*)(&__IPSBAR[0x100013]))
-#define MCF_GPIO_PDDR_BS          (*(vuint8 *)(void*)(&__IPSBAR[0x100014]))
-#define MCF_GPIO_PDDR_CS          (*(vuint8 *)(void*)(&__IPSBAR[0x100015]))
-#define MCF_GPIO_PDDR_SDRAM       (*(vuint8 *)(void*)(&__IPSBAR[0x100016]))
-#define MCF_GPIO_PDDR_FECI2C      (*(vuint8 *)(void*)(&__IPSBAR[0x100017]))
-#define MCF_GPIO_PDDR_UARTH       (*(vuint8 *)(void*)(&__IPSBAR[0x100018]))
-#define MCF_GPIO_PDDR_UARTL       (*(vuint8 *)(void*)(&__IPSBAR[0x100019]))
-#define MCF_GPIO_PDDR_QSPI        (*(vuint8 *)(void*)(&__IPSBAR[0x10001A]))
-#define MCF_GPIO_PDDR_TIMER       (*(vuint8 *)(void*)(&__IPSBAR[0x10001B]))
-#define MCF_GPIO_PDDR_ETPU        (*(vuint8 *)(void*)(&__IPSBAR[0x10001C]))
-#define MCF_GPIO_PPDSDR_ADDR      (*(vuint8 *)(void*)(&__IPSBAR[0x100020]))
-#define MCF_GPIO_PPDSDR_DATAH     (*(vuint8 *)(void*)(&__IPSBAR[0x100021]))
-#define MCF_GPIO_PPDSDR_DATAL     (*(vuint8 *)(void*)(&__IPSBAR[0x100022]))
-#define MCF_GPIO_PPDSDR_BUSCTL    (*(vuint8 *)(void*)(&__IPSBAR[0x100023]))
-#define MCF_GPIO_PPDSDR_BS        (*(vuint8 *)(void*)(&__IPSBAR[0x100024]))
-#define MCF_GPIO_PPDSDR_FECI2C    (*(vuint8 *)(void*)(&__IPSBAR[0x100027]))
-#define MCF_GPIO_PPDSDR_CS        (*(vuint8 *)(void*)(&__IPSBAR[0x100025]))
-#define MCF_GPIO_PPDSDR_SDRAM     (*(vuint8 *)(void*)(&__IPSBAR[0x100026]))
-#define MCF_GPIO_PPDSDR_UARTH     (*(vuint8 *)(void*)(&__IPSBAR[0x100028]))
-#define MCF_GPIO_PPDSDR_UARTL     (*(vuint8 *)(void*)(&__IPSBAR[0x100029]))
-#define MCF_GPIO_PPDSDR_QSPI      (*(vuint8 *)(void*)(&__IPSBAR[0x10002A]))
-#define MCF_GPIO_PPDSDR_TIMER     (*(vuint8 *)(void*)(&__IPSBAR[0x10002B]))
-#define MCF_GPIO_PPDSDR_ETPU      (*(vuint8 *)(void*)(&__IPSBAR[0x10002C]))
-#define MCF_GPIO_PCLRR_ADDR       (*(vuint8 *)(void*)(&__IPSBAR[0x100030]))
-#define MCF_GPIO_PCLRR_DATAH      (*(vuint8 *)(void*)(&__IPSBAR[0x100031]))
-#define MCF_GPIO_PCLRR_DATAL      (*(vuint8 *)(void*)(&__IPSBAR[0x100032]))
-#define MCF_GPIO_PCLRR_BUSCTL     (*(vuint8 *)(void*)(&__IPSBAR[0x100033]))
-#define MCF_GPIO_PCLRR_BS         (*(vuint8 *)(void*)(&__IPSBAR[0x100034]))
-#define MCF_GPIO_PCLRR_CS         (*(vuint8 *)(void*)(&__IPSBAR[0x100035]))
-#define MCF_GPIO_PCLRR_SDRAM      (*(vuint8 *)(void*)(&__IPSBAR[0x100036]))
-#define MCF_GPIO_PCLRR_FECI2C     (*(vuint8 *)(void*)(&__IPSBAR[0x100037]))
-#define MCF_GPIO_PCLRR_UARTH      (*(vuint8 *)(void*)(&__IPSBAR[0x100038]))
-#define MCF_GPIO_PCLRR_UARTL      (*(vuint8 *)(void*)(&__IPSBAR[0x100039]))
-#define MCF_GPIO_PCLRR_QSPI       (*(vuint8 *)(void*)(&__IPSBAR[0x10003A]))
-#define MCF_GPIO_PCLRR_TIMER      (*(vuint8 *)(void*)(&__IPSBAR[0x10003B]))
-#define MCF_GPIO_PCLRR_ETPU       (*(vuint8 *)(void*)(&__IPSBAR[0x10003C]))
-#define MCF_GPIO_PAR_AD           (*(vuint8 *)(void*)(&__IPSBAR[0x100040]))
-#define MCF_GPIO_PAR_BUSCTL       (*(vuint16*)(void*)(&__IPSBAR[0x100042]))
-#define MCF_GPIO_PAR_BS           (*(vuint8 *)(void*)(&__IPSBAR[0x100044]))
-#define MCF_GPIO_PAR_CS           (*(vuint8 *)(void*)(&__IPSBAR[0x100045]))
-#define MCF_GPIO_PAR_SDRAM        (*(vuint8 *)(void*)(&__IPSBAR[0x100046]))
-#define MCF_GPIO_PAR_FECI2C       (*(vuint8 *)(void*)(&__IPSBAR[0x100047]))
-#define MCF_GPIO_PAR_UART         (*(vuint16*)(void*)(&__IPSBAR[0x100048]))
-#define MCF_GPIO_PAR_QSPI         (*(vuint8 *)(void*)(&__IPSBAR[0x10004A]))
-#define MCF_GPIO_PAR_TIMER        (*(vuint16*)(void*)(&__IPSBAR[0x10004C]))
-#define MCF_GPIO_PAR_ETPU         (*(vuint8 *)(void*)(&__IPSBAR[0x10004E]))
-#define MCF_GPIO_DSCR_EIM         (*(vuint8 *)(void*)(&__IPSBAR[0x100050]))
-#define MCF_GPIO_DSCR_ETPU        (*(vuint8 *)(void*)(&__IPSBAR[0x100051]))
-#define MCF_GPIO_DSCR_FECI2C      (*(vuint8 *)(void*)(&__IPSBAR[0x100052]))
-#define MCF_GPIO_DSCR_UART        (*(vuint8 *)(void*)(&__IPSBAR[0x100053]))
-#define MCF_GPIO_DSCR_QSPI        (*(vuint8 *)(void*)(&__IPSBAR[0x100054]))
-#define MCF_GPIO_DSCR_TIMER       (*(vuint8 *)(void*)(&__IPSBAR[0x100055]))
-
-/* Bit definitions and macros for MCF_GPIO_PODR_ADDR */
-#define MCF_GPIO_PODR_ADDR_PODR_ADDR5            (0x20)
-#define MCF_GPIO_PODR_ADDR_PODR_ADDR6            (0x40)
-#define MCF_GPIO_PODR_ADDR_PODR_ADDR7            (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PODR_DATAH */
-#define MCF_GPIO_PODR_DATAH_PODR_DATAH0          (0x01)
-#define MCF_GPIO_PODR_DATAH_PODR_DATAH1          (0x02)
-#define MCF_GPIO_PODR_DATAH_PODR_DATAH2          (0x04)
-#define MCF_GPIO_PODR_DATAH_PODR_DATAH3          (0x08)
-#define MCF_GPIO_PODR_DATAH_PODR_DATAH4          (0x10)
-#define MCF_GPIO_PODR_DATAH_PODR_DATAH5          (0x20)
-#define MCF_GPIO_PODR_DATAH_PODR_DATAH6          (0x40)
-#define MCF_GPIO_PODR_DATAH_PODR_DATAH7          (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PODR_DATAL */
-#define MCF_GPIO_PODR_DATAL_PODR_DATAL0          (0x01)
-#define MCF_GPIO_PODR_DATAL_PODR_DATAL1          (0x02)
-#define MCF_GPIO_PODR_DATAL_PODR_DATAL2          (0x04)
-#define MCF_GPIO_PODR_DATAL_PODR_DATAL3          (0x08)
-#define MCF_GPIO_PODR_DATAL_PODR_DATAL4          (0x10)
-#define MCF_GPIO_PODR_DATAL_PODR_DATAL5          (0x20)
-#define MCF_GPIO_PODR_DATAL_PODR_DATAL6          (0x40)
-#define MCF_GPIO_PODR_DATAL_PODR_DATAL7          (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PODR_BUSCTL */
-#define MCF_GPIO_PODR_BUSCTL_PODR_BUSCTL0        (0x01)
-#define MCF_GPIO_PODR_BUSCTL_PODR_BUSCTL1        (0x02)
-#define MCF_GPIO_PODR_BUSCTL_PODR_BUSCTL2        (0x04)
-#define MCF_GPIO_PODR_BUSCTL_PODR_BUSCTL3        (0x08)
-#define MCF_GPIO_PODR_BUSCTL_PODR_BUSCTL4        (0x10)
-#define MCF_GPIO_PODR_BUSCTL_PODR_BUSCTL5        (0x20)
-#define MCF_GPIO_PODR_BUSCTL_PODR_BUSCTL6        (0x40)
-#define MCF_GPIO_PODR_BUSCTL_PODR_BUSCTL7        (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PODR_BS */
-#define MCF_GPIO_PODR_BS_PODR_BS0                (0x01)
-#define MCF_GPIO_PODR_BS_PODR_BS1                (0x02)
-#define MCF_GPIO_PODR_BS_PODR_BS2                (0x04)
-#define MCF_GPIO_PODR_BS_PODR_BS3                (0x08)
-
-/* Bit definitions and macros for MCF_GPIO_PODR_CS */
-#define MCF_GPIO_PODR_CS_PODR_CS1                (0x02)
-#define MCF_GPIO_PODR_CS_PODR_CS2                (0x04)
-#define MCF_GPIO_PODR_CS_PODR_CS3                (0x08)
-#define MCF_GPIO_PODR_CS_PODR_CS4                (0x10)
-#define MCF_GPIO_PODR_CS_PODR_CS5                (0x20)
-#define MCF_GPIO_PODR_CS_PODR_CS6                (0x40)
-#define MCF_GPIO_PODR_CS_PODR_CS7                (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PODR_SDRAM */
-#define MCF_GPIO_PODR_SDRAM_PODR_SDRAM0          (0x01)
-#define MCF_GPIO_PODR_SDRAM_PODR_SDRAM1          (0x02)
-#define MCF_GPIO_PODR_SDRAM_PODR_SDRAM2          (0x04)
-#define MCF_GPIO_PODR_SDRAM_PODR_SDRAM3          (0x08)
-#define MCF_GPIO_PODR_SDRAM_PODR_SDRAM4          (0x10)
-#define MCF_GPIO_PODR_SDRAM_PODR_SDRAM5          (0x20)
-
-/* Bit definitions and macros for MCF_GPIO_PODR_FECI2C */
-#define MCF_GPIO_PODR_FECI2C_PODR_FECI2C0        (0x01)
-#define MCF_GPIO_PODR_FECI2C_PODR_FECI2C1        (0x02)
-#define MCF_GPIO_PODR_FECI2C_PODR_FECI2C2        (0x04)
-#define MCF_GPIO_PODR_FECI2C_PODR_FECI2C3        (0x08)
-
-/* Bit definitions and macros for MCF_GPIO_PODR_UARTH */
-#define MCF_GPIO_PODR_UARTH_PODR_UARTH0          (0x01)
-#define MCF_GPIO_PODR_UARTH_PODR_UARTH1          (0x02)
-
-/* Bit definitions and macros for MCF_GPIO_PODR_UARTL */
-#define MCF_GPIO_PODR_UARTL_PODR_UARTL0          (0x01)
-#define MCF_GPIO_PODR_UARTL_PODR_UARTL1          (0x02)
-#define MCF_GPIO_PODR_UARTL_PODR_UARTL2          (0x04)
-#define MCF_GPIO_PODR_UARTL_PODR_UARTL3          (0x08)
-#define MCF_GPIO_PODR_UARTL_PODR_UARTL4          (0x10)
-#define MCF_GPIO_PODR_UARTL_PODR_UARTL5          (0x20)
-#define MCF_GPIO_PODR_UARTL_PODR_UARTL6          (0x40)
-#define MCF_GPIO_PODR_UARTL_PODR_UARTL7          (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PODR_QSPI */
-#define MCF_GPIO_PODR_QSPI_PODR_QSPI0            (0x01)
-#define MCF_GPIO_PODR_QSPI_PODR_QSPI1            (0x02)
-#define MCF_GPIO_PODR_QSPI_PODR_QSPI2            (0x04)
-#define MCF_GPIO_PODR_QSPI_PODR_QSPI3            (0x08)
-#define MCF_GPIO_PODR_QSPI_PODR_QSPI4            (0x10)
-
-/* Bit definitions and macros for MCF_GPIO_PODR_TIMER */
-#define MCF_GPIO_PODR_TIMER_PODR_TIMER0          (0x01)
-#define MCF_GPIO_PODR_TIMER_PODR_TIMER1          (0x02)
-#define MCF_GPIO_PODR_TIMER_PODR_TIMER2          (0x04)
-#define MCF_GPIO_PODR_TIMER_PODR_TIMER3          (0x08)
-#define MCF_GPIO_PODR_TIMER_PODR_TIMER4          (0x10)
-#define MCF_GPIO_PODR_TIMER_PODR_TIMER5          (0x20)
-#define MCF_GPIO_PODR_TIMER_PODR_TIMER6          (0x40)
-#define MCF_GPIO_PODR_TIMER_PODR_TIMER7          (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PODR_ETPU */
-#define MCF_GPIO_PODR_ETPU_PODR_ETPU0            (0x01)
-#define MCF_GPIO_PODR_ETPU_PODR_ETPU1            (0x02)
-#define MCF_GPIO_PODR_ETPU_PODR_ETPU2            (0x04)
-
-/* Bit definitions and macros for MCF_GPIO_PDDR_APDDR */
-#define MCF_GPIO_PDDR_APDDR_PDDR_APDDR5          (0x20)
-#define MCF_GPIO_PDDR_APDDR_PDDR_APDDR6          (0x40)
-#define MCF_GPIO_PDDR_APDDR_PDDR_APDDR7          (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PDDR_DATAH */
-#define MCF_GPIO_PDDR_DATAH_PDDR_DATAH0          (0x01)
-#define MCF_GPIO_PDDR_DATAH_PDDR_DATAH1          (0x02)
-#define MCF_GPIO_PDDR_DATAH_PDDR_DATAH2          (0x04)
-#define MCF_GPIO_PDDR_DATAH_PDDR_DATAH3          (0x08)
-#define MCF_GPIO_PDDR_DATAH_PDDR_DATAH4          (0x10)
-#define MCF_GPIO_PDDR_DATAH_PDDR_DATAH5          (0x20)
-#define MCF_GPIO_PDDR_DATAH_PDDR_DATAH6          (0x40)
-#define MCF_GPIO_PDDR_DATAH_PDDR_DATAH7          (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PDDR_DATAL */
-#define MCF_GPIO_PDDR_DATAL_PDDR_DATAL0          (0x01)
-#define MCF_GPIO_PDDR_DATAL_PDDR_DATAL1          (0x02)
-#define MCF_GPIO_PDDR_DATAL_PDDR_DATAL2          (0x04)
-#define MCF_GPIO_PDDR_DATAL_PDDR_DATAL3          (0x08)
-#define MCF_GPIO_PDDR_DATAL_PDDR_DATAL4          (0x10)
-#define MCF_GPIO_PDDR_DATAL_PDDR_DATAL5          (0x20)
-#define MCF_GPIO_PDDR_DATAL_PDDR_DATAL6          (0x40)
-#define MCF_GPIO_PDDR_DATAL_PDDR_DATAL7          (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PDDR_BUSCTL */
-#define MCF_GPIO_PDDR_BUSCTL_PDDR_BUSCTL0        (0x01)
-#define MCF_GPIO_PDDR_BUSCTL_PDDR_BUSCTL1        (0x02)
-#define MCF_GPIO_PDDR_BUSCTL_PDDR_BUSCTL2        (0x04)
-#define MCF_GPIO_PDDR_BUSCTL_PDDR_BUSCTL3        (0x08)
-#define MCF_GPIO_PDDR_BUSCTL_PDDR_BUSCTL4        (0x10)
-#define MCF_GPIO_PDDR_BUSCTL_PDDR_BUSCTL5        (0x20)
-#define MCF_GPIO_PDDR_BUSCTL_PDDR_BUSCTL6        (0x40)
-#define MCF_GPIO_PDDR_BUSCTL_PDDR_BUSCTL7        (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PDDR_BS */
-#define MCF_GPIO_PDDR_BS_PDDR_BS0                (0x01)
-#define MCF_GPIO_PDDR_BS_PDDR_BS3(x)             (((x)&0x07)<<1)
-
-/* Bit definitions and macros for MCF_GPIO_PDDR_CS */
-#define MCF_GPIO_PDDR_CS_PDDR_CS1                (0x02)
-#define MCF_GPIO_PDDR_CS_PDDR_CS2                (0x04)
-#define MCF_GPIO_PDDR_CS_PDDR_CS3                (0x08)
-#define MCF_GPIO_PDDR_CS_PDDR_CS4                (0x10)
-#define MCF_GPIO_PDDR_CS_PDDR_CS5                (0x20)
-#define MCF_GPIO_PDDR_CS_PDDR_CS6                (0x40)
-#define MCF_GPIO_PDDR_CS_PDDR_CS7                (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PDDR_SDRAM */
-#define MCF_GPIO_PDDR_SDRAM_PDDR_SDRAM0          (0x01)
-#define MCF_GPIO_PDDR_SDRAM_PDDR_SDRAM1          (0x02)
-#define MCF_GPIO_PDDR_SDRAM_PDDR_SDRAM2          (0x04)
-#define MCF_GPIO_PDDR_SDRAM_PDDR_SDRAM3          (0x08)
-#define MCF_GPIO_PDDR_SDRAM_PDDR_SDRAM4          (0x10)
-#define MCF_GPIO_PDDR_SDRAM_PDDR_SDRAM5          (0x20)
-
-/* Bit definitions and macros for MCF_GPIO_PDDR_FECI2C */
-#define MCF_GPIO_PDDR_FECI2C_PDDR_FECI2C0        (0x01)
-#define MCF_GPIO_PDDR_FECI2C_PDDR_FECI2C1        (0x02)
-#define MCF_GPIO_PDDR_FECI2C_PDDR_FECI2C2        (0x04)
-#define MCF_GPIO_PDDR_FECI2C_PDDR_FECI2C3        (0x08)
-
-/* Bit definitions and macros for MCF_GPIO_PDDR_UARTH */
-#define MCF_GPIO_PDDR_UARTH_PDDR_UARTH0          (0x01)
-#define MCF_GPIO_PDDR_UARTH_PDDR_UARTH1          (0x02)
-
-/* Bit definitions and macros for MCF_GPIO_PDDR_UARTL */
-#define MCF_GPIO_PDDR_UARTL_PDDR_UARTL0          (0x01)
-#define MCF_GPIO_PDDR_UARTL_PDDR_UARTL1          (0x02)
-#define MCF_GPIO_PDDR_UARTL_PDDR_UARTL2          (0x04)
-#define MCF_GPIO_PDDR_UARTL_PDDR_UARTL3          (0x08)
-#define MCF_GPIO_PDDR_UARTL_PDDR_UARTL4          (0x10)
-#define MCF_GPIO_PDDR_UARTL_PDDR_UARTL5          (0x20)
-#define MCF_GPIO_PDDR_UARTL_PDDR_UARTL6          (0x40)
-#define MCF_GPIO_PDDR_UARTL_PDDR_UARTL7          (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PDDR_QSPI */
-#define MCF_GPIO_PDDR_QSPI_PDDR_QSPI0            (0x01)
-#define MCF_GPIO_PDDR_QSPI_PDDR_QSPI1            (0x02)
-#define MCF_GPIO_PDDR_QSPI_PDDR_QSPI2            (0x04)
-#define MCF_GPIO_PDDR_QSPI_PDDR_QSPI3            (0x08)
-#define MCF_GPIO_PDDR_QSPI_PDDR_QSPI4            (0x10)
-
-/* Bit definitions and macros for MCF_GPIO_PDDR_TIMER */
-#define MCF_GPIO_PDDR_TIMER_PDDR_TIMER0          (0x01)
-#define MCF_GPIO_PDDR_TIMER_PDDR_TIMER1          (0x02)
-#define MCF_GPIO_PDDR_TIMER_PDDR_TIMER2          (0x04)
-#define MCF_GPIO_PDDR_TIMER_PDDR_TIMER3          (0x08)
-#define MCF_GPIO_PDDR_TIMER_PDDR_TIMER4          (0x10)
-#define MCF_GPIO_PDDR_TIMER_PDDR_TIMER5          (0x20)
-#define MCF_GPIO_PDDR_TIMER_PDDR_TIMER6          (0x40)
-#define MCF_GPIO_PDDR_TIMER_PDDR_TIMER7          (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PDDR_ETPU */
-#define MCF_GPIO_PDDR_ETPU_PDDR_ETPU0            (0x01)
-#define MCF_GPIO_PDDR_ETPU_PDDR_ETPU1            (0x02)
-#define MCF_GPIO_PDDR_ETPU_PDDR_ETPU2            (0x04)
-
-/* Bit definitions and macros for MCF_GPIO_PPDSDR_ADDR */
-#define MCF_GPIO_PPDSDR_ADDR_PPDSDR_ADDR5        (0x20)
-#define MCF_GPIO_PPDSDR_ADDR_PPDSDR_ADDR6        (0x40)
-#define MCF_GPIO_PPDSDR_ADDR_PPDSDR_ADDR7        (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PPDSDR_DATAH */
-#define MCF_GPIO_PPDSDR_DATAH_PPDSDR_DATAH0      (0x01)
-#define MCF_GPIO_PPDSDR_DATAH_PPDSDR_DATAH1      (0x02)
-#define MCF_GPIO_PPDSDR_DATAH_PPDSDR_DATAH2      (0x04)
-#define MCF_GPIO_PPDSDR_DATAH_PPDSDR_DATAH3      (0x08)
-#define MCF_GPIO_PPDSDR_DATAH_PPDSDR_DATAH4      (0x10)
-#define MCF_GPIO_PPDSDR_DATAH_PPDSDR_DATAH5      (0x20)
-#define MCF_GPIO_PPDSDR_DATAH_PPDSDR_DATAH6      (0x40)
-#define MCF_GPIO_PPDSDR_DATAH_PPDSDR_DATAH7      (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PPDSDR_DATAL */
-#define MCF_GPIO_PPDSDR_DATAL_PPDSDR_DATAL0      (0x01)
-#define MCF_GPIO_PPDSDR_DATAL_PPDSDR_DATAL1      (0x02)
-#define MCF_GPIO_PPDSDR_DATAL_PPDSDR_DATAL2      (0x04)
-#define MCF_GPIO_PPDSDR_DATAL_PPDSDR_DATAL3      (0x08)
-#define MCF_GPIO_PPDSDR_DATAL_PPDSDR_DATAL4      (0x10)
-#define MCF_GPIO_PPDSDR_DATAL_PPDSDR_DATAL5      (0x20)
-#define MCF_GPIO_PPDSDR_DATAL_PPDSDR_DATAL6      (0x40)
-#define MCF_GPIO_PPDSDR_DATAL_PPDSDR_DATAL7      (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PPDSDR_BUSCTL */
-#define MCF_GPIO_PPDSDR_BUSCTL_PPDSDR_BUSCTL0    (0x01)
-#define MCF_GPIO_PPDSDR_BUSCTL_PPDSDR_BUSCTL1    (0x02)
-#define MCF_GPIO_PPDSDR_BUSCTL_PPDSDR_BUSCTL2    (0x04)
-#define MCF_GPIO_PPDSDR_BUSCTL_PPDSDR_BUSCTL3    (0x08)
-#define MCF_GPIO_PPDSDR_BUSCTL_PPDSDR_BUSCTL4    (0x10)
-#define MCF_GPIO_PPDSDR_BUSCTL_PPDSDR_BUSCTL5    (0x20)
-#define MCF_GPIO_PPDSDR_BUSCTL_PPDSDR_BUSCTL6    (0x40)
-#define MCF_GPIO_PPDSDR_BUSCTL_PPDSDR_BUSCTL7    (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PPDSDR_BS */
-#define MCF_GPIO_PPDSDR_BS_PPDSDR_BS0            (0x01)
-#define MCF_GPIO_PPDSDR_BS_PPDSDR_BS1            (0x02)
-#define MCF_GPIO_PPDSDR_BS_PPDSDR_BS2            (0x04)
-#define MCF_GPIO_PPDSDR_BS_PPDSDR_BS3            (0x08)
-
-/* Bit definitions and macros for MCF_GPIO_PPDSDR_FECI2C */
-#define MCF_GPIO_PPDSDR_FECI2C_PPDSDR_FECI2C0    (0x01)
-#define MCF_GPIO_PPDSDR_FECI2C_PPDSDR_FECI2C1    (0x02)
-#define MCF_GPIO_PPDSDR_FECI2C_PPDSDR_FECI2C2    (0x04)
-#define MCF_GPIO_PPDSDR_FECI2C_PPDSDR_FECI2C3    (0x08)
-
-/* Bit definitions and macros for MCF_GPIO_PPDSDR_CS */
-#define MCF_GPIO_PPDSDR_CS_PPDSDR_CS1            (0x02)
-#define MCF_GPIO_PPDSDR_CS_PPDSDR_CS2            (0x04)
-#define MCF_GPIO_PPDSDR_CS_PPDSDR_CS3            (0x08)
-#define MCF_GPIO_PPDSDR_CS_PPDSDR_CS4            (0x10)
-#define MCF_GPIO_PPDSDR_CS_PPDSDR_CS5            (0x20)
-#define MCF_GPIO_PPDSDR_CS_PPDSDR_CS6            (0x40)
-#define MCF_GPIO_PPDSDR_CS_PPDSDR_CS7            (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PPDSDR_SDRAM */
-#define MCF_GPIO_PPDSDR_SDRAM_PPDSDR_SDRAM0      (0x01)
-#define MCF_GPIO_PPDSDR_SDRAM_PPDSDR_SDRAM1      (0x02)
-#define MCF_GPIO_PPDSDR_SDRAM_PPDSDR_SDRAM2      (0x04)
-#define MCF_GPIO_PPDSDR_SDRAM_PPDSDR_SDRAM3      (0x08)
-#define MCF_GPIO_PPDSDR_SDRAM_PPDSDR_SDRAM4      (0x10)
-#define MCF_GPIO_PPDSDR_SDRAM_PPDSDR_SDRAM5      (0x20)
-#define MCF_GPIO_PPDSDR_SDRAM_PPDSDR_SDRAM6      (0x40)
-#define MCF_GPIO_PPDSDR_SDRAM_PPDSDR_SDRAM7      (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PPDSDR_UARTH */
-#define MCF_GPIO_PPDSDR_UARTH_PPDSDR_UARTH0      (0x01)
-#define MCF_GPIO_PPDSDR_UARTH_PPDSDR_UARTH1      (0x02)
-
-/* Bit definitions and macros for MCF_GPIO_PPDSDR_UARTL */
-#define MCF_GPIO_PPDSDR_UARTL_PPDSDR_UARTL0      (0x01)
-#define MCF_GPIO_PPDSDR_UARTL_PPDSDR_UARTL1      (0x02)
-#define MCF_GPIO_PPDSDR_UARTL_PPDSDR_UARTL2      (0x04)
-#define MCF_GPIO_PPDSDR_UARTL_PPDSDR_UARTL3      (0x08)
-#define MCF_GPIO_PPDSDR_UARTL_PPDSDR_UARTL4      (0x10)
-#define MCF_GPIO_PPDSDR_UARTL_PPDSDR_UARTL5      (0x20)
-#define MCF_GPIO_PPDSDR_UARTL_PPDSDR_UARTL6      (0x40)
-#define MCF_GPIO_PPDSDR_UARTL_PPDSDR_UARTL7      (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PPDSDR_QSPI */
-#define MCF_GPIO_PPDSDR_QSPI_PPDSDR_QSPI0        (0x01)
-#define MCF_GPIO_PPDSDR_QSPI_PPDSDR_QSPI1        (0x02)
-#define MCF_GPIO_PPDSDR_QSPI_PPDSDR_QSPI2        (0x04)
-#define MCF_GPIO_PPDSDR_QSPI_PPDSDR_QSPI3        (0x08)
-#define MCF_GPIO_PPDSDR_QSPI_PPDSDR_QSPI4        (0x10)
-
-/* Bit definitions and macros for MCF_GPIO_PPDSDR_TIMER */
-#define MCF_GPIO_PPDSDR_TIMER_PPDSDR_TIMER0      (0x01)
-#define MCF_GPIO_PPDSDR_TIMER_PPDSDR_TIMER1      (0x02)
-#define MCF_GPIO_PPDSDR_TIMER_PPDSDR_TIMER2      (0x04)
-#define MCF_GPIO_PPDSDR_TIMER_PPDSDR_TIMER3      (0x08)
-#define MCF_GPIO_PPDSDR_TIMER_PPDSDR_TIMER4      (0x10)
-#define MCF_GPIO_PPDSDR_TIMER_PPDSDR_TIMER5      (0x20)
-#define MCF_GPIO_PPDSDR_TIMER_PPDSDR_TIMER6      (0x40)
-#define MCF_GPIO_PPDSDR_TIMER_PPDSDR_TIMER7      (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PPDSDR_ETPU */
-#define MCF_GPIO_PPDSDR_ETPU_PPDSDR_ETPU0        (0x01)
-#define MCF_GPIO_PPDSDR_ETPU_PPDSDR_ETPU1        (0x02)
-#define MCF_GPIO_PPDSDR_ETPU_PPDSDR_ETPU2        (0x04)
-
-/* Bit definitions and macros for MCF_GPIO_PCLRR_ADDR */
-#define MCF_GPIO_PCLRR_ADDR_PCLRR_ADDR5          (0x20)
-#define MCF_GPIO_PCLRR_ADDR_PCLRR_ADDR6          (0x40)
-#define MCF_GPIO_PCLRR_ADDR_PCLRR_ADDR7          (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PCLRR_DATAH */
-#define MCF_GPIO_PCLRR_DATAH_PCLRR_DATAH0        (0x01)
-#define MCF_GPIO_PCLRR_DATAH_PCLRR_DATAH1        (0x02)
-#define MCF_GPIO_PCLRR_DATAH_PCLRR_DATAH2        (0x04)
-#define MCF_GPIO_PCLRR_DATAH_PCLRR_DATAH3        (0x08)
-#define MCF_GPIO_PCLRR_DATAH_PCLRR_DATAH4        (0x10)
-#define MCF_GPIO_PCLRR_DATAH_PCLRR_DATAH5        (0x20)
-#define MCF_GPIO_PCLRR_DATAH_PCLRR_DATAH6        (0x40)
-#define MCF_GPIO_PCLRR_DATAH_PCLRR_DATAH7        (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PCLRR_DATAL */
-#define MCF_GPIO_PCLRR_DATAL_PCLRR_DATAL0        (0x01)
-#define MCF_GPIO_PCLRR_DATAL_PCLRR_DATAL1        (0x02)
-#define MCF_GPIO_PCLRR_DATAL_PCLRR_DATAL2        (0x04)
-#define MCF_GPIO_PCLRR_DATAL_PCLRR_DATAL3        (0x08)
-#define MCF_GPIO_PCLRR_DATAL_PCLRR_DATAL4        (0x10)
-#define MCF_GPIO_PCLRR_DATAL_PCLRR_DATAL5        (0x20)
-#define MCF_GPIO_PCLRR_DATAL_PCLRR_DATAL6        (0x40)
-#define MCF_GPIO_PCLRR_DATAL_PCLRR_DATAL7        (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PCLRR_BUSCTL */
-#define MCF_GPIO_PCLRR_BUSCTL_PCLRR_BUSCTL0      (0x01)
-#define MCF_GPIO_PCLRR_BUSCTL_PCLRR_BUSCTL1      (0x02)
-#define MCF_GPIO_PCLRR_BUSCTL_PCLRR_BUSCTL2      (0x04)
-#define MCF_GPIO_PCLRR_BUSCTL_PCLRR_BUSCTL3      (0x08)
-#define MCF_GPIO_PCLRR_BUSCTL_PCLRR_BUSCTL4      (0x10)
-#define MCF_GPIO_PCLRR_BUSCTL_PCLRR_BUSCTL5      (0x20)
-#define MCF_GPIO_PCLRR_BUSCTL_PCLRR_BUSCTL6      (0x40)
-#define MCF_GPIO_PCLRR_BUSCTL_PCLRR_BUSCTL7      (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PCLRR_BS */
-#define MCF_GPIO_PCLRR_BS_PCLRR_BS0              (0x01)
-#define MCF_GPIO_PCLRR_BS_PCLRR_BS1              (0x02)
-#define MCF_GPIO_PCLRR_BS_PCLRR_BS2              (0x04)
-#define MCF_GPIO_PCLRR_BS_PCLRR_BS3              (0x08)
-
-/* Bit definitions and macros for MCF_GPIO_PCLRR_CS */
-#define MCF_GPIO_PCLRR_CS_PCLRR_CS1              (0x02)
-#define MCF_GPIO_PCLRR_CS_PCLRR_CS2              (0x04)
-#define MCF_GPIO_PCLRR_CS_PCLRR_CS3              (0x08)
-#define MCF_GPIO_PCLRR_CS_PCLRR_CS4              (0x10)
-#define MCF_GPIO_PCLRR_CS_PCLRR_CS5              (0x20)
-#define MCF_GPIO_PCLRR_CS_PCLRR_CS6              (0x40)
-#define MCF_GPIO_PCLRR_CS_PCLRR_CS7              (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PCLRR_SDRAM */
-#define MCF_GPIO_PCLRR_SDRAM_PCLRR_SDRAM0        (0x01)
-#define MCF_GPIO_PCLRR_SDRAM_PCLRR_SDRAM1        (0x02)
-#define MCF_GPIO_PCLRR_SDRAM_PCLRR_SDRAM2        (0x04)
-#define MCF_GPIO_PCLRR_SDRAM_PCLRR_SDRAM3        (0x08)
-#define MCF_GPIO_PCLRR_SDRAM_PCLRR_SDRAM4        (0x10)
-#define MCF_GPIO_PCLRR_SDRAM_PCLRR_SDRAM5        (0x20)
-
-/* Bit definitions and macros for MCF_GPIO_PCLRR_FECI2C */
-#define MCF_GPIO_PCLRR_FECI2C_PCLRR_FECI2C0      (0x01)
-#define MCF_GPIO_PCLRR_FECI2C_PCLRR_FECI2C1      (0x02)
-#define MCF_GPIO_PCLRR_FECI2C_PCLRR_FECI2C2      (0x04)
-#define MCF_GPIO_PCLRR_FECI2C_PCLRR_FECI2C3      (0x08)
-
-/* Bit definitions and macros for MCF_GPIO_PCLRR_UARTH */
-#define MCF_GPIO_PCLRR_UARTH_PCLRR_UARTH0        (0x01)
-#define MCF_GPIO_PCLRR_UARTH_PCLRR_UARTH1        (0x02)
-
-/* Bit definitions and macros for MCF_GPIO_PCLRR_UARTL */
-#define MCF_GPIO_PCLRR_UARTL_PCLRR_UARTL0        (0x01)
-#define MCF_GPIO_PCLRR_UARTL_PCLRR_UARTL1        (0x02)
-#define MCF_GPIO_PCLRR_UARTL_PCLRR_UARTL2        (0x04)
-#define MCF_GPIO_PCLRR_UARTL_PCLRR_UARTL3        (0x08)
-#define MCF_GPIO_PCLRR_UARTL_PCLRR_UARTL4        (0x10)
-#define MCF_GPIO_PCLRR_UARTL_PCLRR_UARTL5        (0x20)
-#define MCF_GPIO_PCLRR_UARTL_PCLRR_UARTL6        (0x40)
-#define MCF_GPIO_PCLRR_UARTL_PCLRR_UARTL7        (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PCLRR_QSPI */
-#define MCF_GPIO_PCLRR_QSPI_PCLRR_QSPI0          (0x01)
-#define MCF_GPIO_PCLRR_QSPI_PCLRR_QSPI1          (0x02)
-#define MCF_GPIO_PCLRR_QSPI_PCLRR_QSPI2          (0x04)
-#define MCF_GPIO_PCLRR_QSPI_PCLRR_QSPI3          (0x08)
-#define MCF_GPIO_PCLRR_QSPI_PCLRR_QSPI4          (0x10)
-
-/* Bit definitions and macros for MCF_GPIO_PCLRR_TIMER */
-#define MCF_GPIO_PCLRR_TIMER_PCLRR_TIMER0        (0x01)
-#define MCF_GPIO_PCLRR_TIMER_PCLRR_TIMER1        (0x02)
-#define MCF_GPIO_PCLRR_TIMER_PCLRR_TIMER2        (0x04)
-#define MCF_GPIO_PCLRR_TIMER_PCLRR_TIMER3        (0x08)
-#define MCF_GPIO_PCLRR_TIMER_PCLRR_TIMER4        (0x10)
-#define MCF_GPIO_PCLRR_TIMER_PCLRR_TIMER5        (0x20)
-#define MCF_GPIO_PCLRR_TIMER_PCLRR_TIMER6        (0x40)
-#define MCF_GPIO_PCLRR_TIMER_PCLRR_TIMER7        (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PCLRR_ETPU */
-#define MCF_GPIO_PCLRR_ETPU_PCLRR_ETPU0          (0x01)
-#define MCF_GPIO_PCLRR_ETPU_PCLRR_ETPU1          (0x02)
-#define MCF_GPIO_PCLRR_ETPU_PCLRR_ETPU2          (0x04)
-
-/* Bit definitions and macros for MCF_GPIO_PAR_AD */
-#define MCF_GPIO_PAR_AD_PAR_DATAL                (0x01)
-#define MCF_GPIO_PAR_AD_PAR_ADDR21               (0x20)
-#define MCF_GPIO_PAR_AD_PAR_ADDR22               (0x40)
-#define MCF_GPIO_PAR_AD_PAR_ADDR23               (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PAR_BUSCTL */
-#define MCF_GPIO_PAR_BUSCTL_PAR_TIP(x)           (((x)&0x0003)<<0)
-#define MCF_GPIO_PAR_BUSCTL_PAR_TS(x)            (((x)&0x0003)<<2)
-#define MCF_GPIO_PAR_BUSCTL_PAR_TSIZ0            (0x0010)
-#define MCF_GPIO_PAR_BUSCTL_PAR_TSIZ1            (0x0040)
-#define MCF_GPIO_PAR_BUSCTL_PAR_RWB              (0x0100)
-#define MCF_GPIO_PAR_BUSCTL_PAR_TEA(x)           (((x)&0x0003)<<10)
-#define MCF_GPIO_PAR_BUSCTL_PAR_TA               (0x1000)
-#define MCF_GPIO_PAR_BUSCTL_PAR_OE               (0x4000)
-#define MCF_GPIO_PAR_BUSCTL_PAR_TEA_GPIO         (0x0000)
-#define MCF_GPIO_PAR_BUSCTL_PAR_TEA_DMA          (0x0800)
-#define MCF_GPIO_PAR_BUSCTL_PAR_TEA_TEA          (0x0C00)
-#define MCF_GPIO_PAR_BUSCTL_PAR_TS_GPIO          (0x0000)
-#define MCF_GPIO_PAR_BUSCTL_PAR_TS_DMA           (0x0080)
-#define MCF_GPIO_PAR_BUSCTL_PAR_TS_TS            (0x00C0)
-#define MCF_GPIO_PAR_BUSCTL_PAR_TIP_GPIO         (0x0000)
-#define MCF_GPIO_PAR_BUSCTL_PAR_TIP_DMA          (0x0002)
-#define MCF_GPIO_PAR_BUSCTL_PAR_TIP_TEA          (0x0003)
-
-/* Bit definitions and macros for MCF_GPIO_PAR_BS */
-#define MCF_GPIO_PAR_BS_PAR_BS0                  (0x01)
-#define MCF_GPIO_PAR_BS_PAR_BS1                  (0x02)
-#define MCF_GPIO_PAR_BS_PAR_BS2                  (0x04)
-#define MCF_GPIO_PAR_BS_PAR_BS3                  (0x08)
-
-/* Bit definitions and macros for MCF_GPIO_PAR_CS */
-#define MCF_GPIO_PAR_CS_PAR_CS1                  (0x02)
-#define MCF_GPIO_PAR_CS_PAR_CS2                  (0x04)
-#define MCF_GPIO_PAR_CS_PAR_CS3                  (0x08)
-#define MCF_GPIO_PAR_CS_PAR_CS4                  (0x10)
-#define MCF_GPIO_PAR_CS_PAR_CS5                  (0x20)
-#define MCF_GPIO_PAR_CS_PAR_CS6                  (0x40)
-#define MCF_GPIO_PAR_CS_PAR_CS7                  (0x80)
-
-/* Bit definitions and macros for MCF_GPIO_PAR_SDRAM */
-#define MCF_GPIO_PAR_SDRAM_PAR_SDCS0             (0x01)
-#define MCF_GPIO_PAR_SDRAM_PAR_SDCS1             (0x02)
-#define MCF_GPIO_PAR_SDRAM_PAR_SCKE              (0x04)
-#define MCF_GPIO_PAR_SDRAM_PAR_SRAS              (0x08)
-#define MCF_GPIO_PAR_SDRAM_PAR_SCAS              (0x10)
-#define MCF_GPIO_PAR_SDRAM_PAR_SDWE              (0x20)
-#define MCF_GPIO_PAR_SDRAM_PAR_CSSDCS(x)         (((x)&0x03)<<6)
-
-/* Bit definitions and macros for MCF_GPIO_PAR_FECI2C */
-#define MCF_GPIO_PAR_FECI2C_PAR_SDA(x)           (((x)&0x03)<<0)
-#define MCF_GPIO_PAR_FECI2C_PAR_SCL(x)           (((x)&0x03)<<2)
-#define MCF_GPIO_PAR_FECI2C_PAR_EMDIO(x)         (((x)&0x03)<<4)
-#define MCF_GPIO_PAR_FECI2C_PAR_EMDC(x)          (((x)&0x03)<<6)
-#define MCF_GPIO_PAR_FECI2C_PAR_EMDC_GPIO        (0x00)
-#define MCF_GPIO_PAR_FECI2C_PAR_EMDC_UART2       (0x40)
-#define MCF_GPIO_PAR_FECI2C_PAR_EMDC_I2C         (0x80)
-#define MCF_GPIO_PAR_FECI2C_PAR_EMDC_FEC         (0xC0)
-#define MCF_GPIO_PAR_FECI2C_PAR_EMDIO_GPIO       (0x00)
-#define MCF_GPIO_PAR_FECI2C_PAR_EMDIO_UART2      (0x10)
-#define MCF_GPIO_PAR_FECI2C_PAR_EMDIO_I2C        (0x20)
-#define MCF_GPIO_PAR_FECI2C_PAR_EMDIO_FEC        (0x30)
-#define MCF_GPIO_PAR_FECI2C_PAR_SCL_GPIO         (0x00)
-#define MCF_GPIO_PAR_FECI2C_PAR_SCL_FLEX         (0x08)
-#define MCF_GPIO_PAR_FECI2C_PAR_SCL_I2C          (0x0C)
-#define MCF_GPIO_PAR_FECI2C_PAR_SDA_GPIO         (0x00)
-#define MCF_GPIO_PAR_FECI2C_PAR_SDA_FLEX         (0x02)
-#define MCF_GPIO_PAR_FECI2C_PAR_SDA_I2C          (0x03)
-
-/* Bit definitions and macros for MCF_GPIO_PAR_UART */
-#define MCF_GPIO_PAR_UART_PAR_U0RTS              (0x0001)
-#define MCF_GPIO_PAR_UART_PAR_U0CTS              (0x0002)
-#define MCF_GPIO_PAR_UART_PAR_U0TXD              (0x0004)
-#define MCF_GPIO_PAR_UART_PAR_U0RXD              (0x0008)
-#define MCF_GPIO_PAR_UART_PAR_U1RTS(x)           (((x)&0x0003)<<4)
-#define MCF_GPIO_PAR_UART_PAR_U1CTS(x)           (((x)&0x0003)<<6)
-#define MCF_GPIO_PAR_UART_PAR_U1TXD(x)           (((x)&0x0003)<<8)
-#define MCF_GPIO_PAR_UART_PAR_U1RXD(x)           (((x)&0x0003)<<10)
-#define MCF_GPIO_PAR_UART_PAR_U2TXD              (0x1000)
-#define MCF_GPIO_PAR_UART_PAR_U2RXD              (0x2000)
-#define MCF_GPIO_PAR_UART_PAR_CAN1EN             (0x4000)
-#define MCF_GPIO_PAR_UART_PAR_DREQ2              (0x8000)
-#define MCF_GPIO_PAR_UART_PAR_U1RXD_GPIO         (0x0000)
-#define MCF_GPIO_PAR_UART_PAR_U1RXD_FLEX         (0x0800)
-#define MCF_GPIO_PAR_UART_PAR_U1RXD_UART1        (0x0C00)
-#define MCF_GPIO_PAR_UART_PAR_U1TXD_GPIO         (0x0000)
-#define MCF_GPIO_PAR_UART_PAR_U1TXD_FLEX         (0x0200)
-#define MCF_GPIO_PAR_UART_PAR_U1TXD_UART1        (0x0300)
-#define MCF_GPIO_PAR_UART_PAR_U1CTS_GPIO         (0x0000)
-#define MCF_GPIO_PAR_UART_PAR_U1CTS_UART2        (0x0080)
-#define MCF_GPIO_PAR_UART_PAR_U1CTS_UART1        (0x00C0)
-#define MCF_GPIO_PAR_UART_PAR_U1RTS_GPIO         (0x0000)
-#define MCF_GPIO_PAR_UART_PAR_U1RTS_UART2        (0x0020)
-#define MCF_GPIO_PAR_UART_PAR_U1RTS_UART1        (0x0030)
-
-/* Bit definitions and macros for MCF_GPIO_PAR_QSPI */
-#define MCF_GPIO_PAR_QSPI_PAR_SCK(x)             (((x)&0x03)<<0)
-#define MCF_GPIO_PAR_QSPI_PAR_DOUT               (0x04)
-#define MCF_GPIO_PAR_QSPI_PAR_DIN(x)             (((x)&0x03)<<3)
-#define MCF_GPIO_PAR_QSPI_PAR_PCS0               (0x20)
-#define MCF_GPIO_PAR_QSPI_PAR_PCS1(x)            (((x)&0x03)<<6)
-#define MCF_GPIO_PAR_QSPI_PAR_PCS1_GPIO          (0x00)
-#define MCF_GPIO_PAR_QSPI_PAR_PCS1_SDRAMC        (0x80)
-#define MCF_GPIO_PAR_QSPI_PAR_PCS1_QSPI          (0xC0)
-#define MCF_GPIO_PAR_QSPI_PAR_DIN_GPIO           (0x00)
-#define MCF_GPIO_PAR_QSPI_PAR_DIN_I2C            (0x10)
-#define MCF_GPIO_PAR_QSPI_PAR_DIN_QSPI           (0x1C)
-#define MCF_GPIO_PAR_QSPI_PAR_SCK_GPIO           (0x00)
-#define MCF_GPIO_PAR_QSPI_PAR_SCK_I2C            (0x02)
-#define MCF_GPIO_PAR_QSPI_PAR_SCK_QSPI           (0x03)
-
-/* Bit definitions and macros for MCF_GPIO_PAR_TIMER */
-#define MCF_GPIO_PAR_TIMER_PAR_T0OUT(x)          (((x)&0x0003)<<0)
-#define MCF_GPIO_PAR_TIMER_PAR_T1OUT(x)          (((x)&0x0003)<<2)
-#define MCF_GPIO_PAR_TIMER_PAR_T2OUT(x)          (((x)&0x0003)<<4)
-#define MCF_GPIO_PAR_TIMER_PAR_T3OUT(x)          (((x)&0x0003)<<6)
-#define MCF_GPIO_PAR_TIMER_PAR_T0IN(x)           (((x)&0x0003)<<8)
-#define MCF_GPIO_PAR_TIMER_PAR_T1IN(x)           (((x)&0x0003)<<10)
-#define MCF_GPIO_PAR_TIMER_PAR_T2IN(x)           (((x)&0x0003)<<12)
-#define MCF_GPIO_PAR_TIMER_PAR_T3IN(x)           (((x)&0x0003)<<14)
-#define MCF_GPIO_PAR_TIMER_PAR_T3IN_GPIO         (0x0000)
-#define MCF_GPIO_PAR_TIMER_PAR_T3IN_QSPI         (0x4000)
-#define MCF_GPIO_PAR_TIMER_PAR_T3IN_UART2        (0x8000)
-#define MCF_GPIO_PAR_TIMER_PAR_T3IN_T3IN         (0xC000)
-#define MCF_GPIO_PAR_TIMER_PAR_T2IN_GPIO         (0x0000)
-#define MCF_GPIO_PAR_TIMER_PAR_T2IN_T2OUT        (0x1000)
-#define MCF_GPIO_PAR_TIMER_PAR_T2IN_DMA          (0x2000)
-#define MCF_GPIO_PAR_TIMER_PAR_T2IN_T2IN         (0x3000)
-#define MCF_GPIO_PAR_TIMER_PAR_T1IN_GPIO         (0x0000)
-#define MCF_GPIO_PAR_TIMER_PAR_T1IN_T1OUT        (0x0400)
-#define MCF_GPIO_PAR_TIMER_PAR_T1IN_DMA          (0x0800)
-#define MCF_GPIO_PAR_TIMER_PAR_T1IN_T1IN         (0x0C00)
-#define MCF_GPIO_PAR_TIMER_PAR_T0IN_GPIO         (0x0000)
-#define MCF_GPIO_PAR_TIMER_PAR_T0IN_DMA          (0x0200)
-#define MCF_GPIO_PAR_TIMER_PAR_T0IN_T0IN         (0x0300)
-#define MCF_GPIO_PAR_TIMER_PAR_T3OUT_GPIO        (0x0000)
-#define MCF_GPIO_PAR_TIMER_PAR_T3OUT_QSPI        (0x0040)
-#define MCF_GPIO_PAR_TIMER_PAR_T3OUT_UART2       (0x0080)
-#define MCF_GPIO_PAR_TIMER_PAR_T3OUT_T3OUT       (0x00C0)
-#define MCF_GPIO_PAR_TIMER_PAR_T2OUT_GPIO        (0x0000)
-#define MCF_GPIO_PAR_TIMER_PAR_T2OUT_DMA         (0x0020)
-#define MCF_GPIO_PAR_TIMER_PAR_T2OUT_T2OUT       (0x0030)
-#define MCF_GPIO_PAR_TIMER_PAR_T1OUT_GPIO        (0x0000)
-#define MCF_GPIO_PAR_TIMER_PAR_T1OUT_DMA         (0x0008)
-#define MCF_GPIO_PAR_TIMER_PAR_T1OUT_T1OUT       (0x000C)
-#define MCF_GPIO_PAR_TIMER_PAR_T0OUT_GPIO        (0x0000)
-#define MCF_GPIO_PAR_TIMER_PAR_T0OUT_DMA         (0x0002)
-#define MCF_GPIO_PAR_TIMER_PAR_T0OUT_T0OUT       (0x0003)
-
-/* Bit definitions and macros for MCF_GPIO_PAR_ETPU */
-#define MCF_GPIO_PAR_ETPU_PAR_LTPU_ODIS          (0x01)
-#define MCF_GPIO_PAR_ETPU_PAR_UTPU_ODIS          (0x02)
-#define MCF_GPIO_PAR_ETPU_PAR_TCRCLK             (0x04)
-
-/* Bit definitions and macros for MCF_GPIO_DSCR_EIM */
-#define MCF_GPIO_DSCR_EIM_DSCR_EIM0              (0x01)
-#define MCF_GPIO_DSCR_EIM_DSCR_EIM1              (0x10)
-
-/* Bit definitions and macros for MCF_GPIO_DSCR_ETPU */
-#define MCF_GPIO_DSCR_ETPU_DSCR_ETPU_7_0         (0x01)
-#define MCF_GPIO_DSCR_ETPU_DSCR_ETPU_15_8        (0x04)
-#define MCF_GPIO_DSCR_ETPU_DSCR_ETPU_23_16       (0x10)
-#define MCF_GPIO_DSCR_ETPU_DSCR_ETPU_31_24       (0x40)
-
-/* Bit definitions and macros for MCF_GPIO_DSCR_FECI2C */
-#define MCF_GPIO_DSCR_FECI2C_DSCR_I2C            (0x01)
-#define MCF_GPIO_DSCR_FECI2C_DSCR_FEC            (0x10)
-
-/* Bit definitions and macros for MCF_GPIO_DSCR_UART */
-#define MCF_GPIO_DSCR_UART_DSCR_UART0            (0x01)
-#define MCF_GPIO_DSCR_UART_DSCR_UART1            (0x04)
-#define MCF_GPIO_DSCR_UART_DSCR_UART2            (0x10)
-#define MCF_GPIO_DSCR_UART_DSCR_IRQ              (0x40)
-
-/* Bit definitions and macros for MCF_GPIO_DSCR_QSPI */
-#define MCF_GPIO_DSCR_QSPI_DSCR_QSPI             (0x01)
-
-/* Bit definitions and macros for MCF_GPIO_DSCR_TIMER */
-#define MCF_GPIO_DSCR_TIMER_DSCR_TIMER           (0x01)
-
-/********************************************************************/
-
-#endif /* __MCF523X_GPIO_H__ */
+/*\r
+ * These files are taken from the MCF523X source code example package\r
+ * which is available on the Freescale website. Freescale explicitly \r
+ * grants the redistribution and modification of these source files.\r
+ * The complete licensing information is available in the file \r
+ * LICENSE_FREESCALE.TXT.\r
+ *\r
+ * File:       mcf523x_gpio.h\r
+ * Purpose:    Register and bit definitions for the MCF523X\r
+ *\r
+ * Notes:      \r
+ *     \r
+ */\r
+\r
+#ifndef __MCF523X_GPIO_H__\r
+#define __MCF523X_GPIO_H__\r
+\r
+/*********************************************************************\r
+*\r
+* General Purpose I/O (GPIO)\r
+*\r
+*********************************************************************/\r
+\r
+/* Register read/write macros */\r
+#define MCF_GPIO_PODR_ADDR        (*(vuint8 *)(void*)(&__IPSBAR[0x100000]))\r
+#define MCF_GPIO_PODR_DATAH       (*(vuint8 *)(void*)(&__IPSBAR[0x100001]))\r
+#define MCF_GPIO_PODR_DATAL       (*(vuint8 *)(void*)(&__IPSBAR[0x100002]))\r
+#define MCF_GPIO_PODR_BUSCTL      (*(vuint8 *)(void*)(&__IPSBAR[0x100003]))\r
+#define MCF_GPIO_PODR_BS          (*(vuint8 *)(void*)(&__IPSBAR[0x100004]))\r
+#define MCF_GPIO_PODR_CS          (*(vuint8 *)(void*)(&__IPSBAR[0x100005]))\r
+#define MCF_GPIO_PODR_SDRAM       (*(vuint8 *)(void*)(&__IPSBAR[0x100006]))\r
+#define MCF_GPIO_PODR_FECI2C      (*(vuint8 *)(void*)(&__IPSBAR[0x100007]))\r
+#define MCF_GPIO_PODR_UARTH       (*(vuint8 *)(void*)(&__IPSBAR[0x100008]))\r
+#define MCF_GPIO_PODR_UARTL       (*(vuint8 *)(void*)(&__IPSBAR[0x100009]))\r
+#define MCF_GPIO_PODR_QSPI        (*(vuint8 *)(void*)(&__IPSBAR[0x10000A]))\r
+#define MCF_GPIO_PODR_TIMER       (*(vuint8 *)(void*)(&__IPSBAR[0x10000B]))\r
+#define MCF_GPIO_PODR_ETPU        (*(vuint8 *)(void*)(&__IPSBAR[0x10000C]))\r
+#define MCF_GPIO_PDDR_APDDR       (*(vuint8 *)(void*)(&__IPSBAR[0x100010]))\r
+#define MCF_GPIO_PDDR_DATAH       (*(vuint8 *)(void*)(&__IPSBAR[0x100011]))\r
+#define MCF_GPIO_PDDR_DATAL       (*(vuint8 *)(void*)(&__IPSBAR[0x100012]))\r
+#define MCF_GPIO_PDDR_BUSCTL      (*(vuint8 *)(void*)(&__IPSBAR[0x100013]))\r
+#define MCF_GPIO_PDDR_BS          (*(vuint8 *)(void*)(&__IPSBAR[0x100014]))\r
+#define MCF_GPIO_PDDR_CS          (*(vuint8 *)(void*)(&__IPSBAR[0x100015]))\r
+#define MCF_GPIO_PDDR_SDRAM       (*(vuint8 *)(void*)(&__IPSBAR[0x100016]))\r
+#define MCF_GPIO_PDDR_FECI2C      (*(vuint8 *)(void*)(&__IPSBAR[0x100017]))\r
+#define MCF_GPIO_PDDR_UARTH       (*(vuint8 *)(void*)(&__IPSBAR[0x100018]))\r
+#define MCF_GPIO_PDDR_UARTL       (*(vuint8 *)(void*)(&__IPSBAR[0x100019]))\r
+#define MCF_GPIO_PDDR_QSPI        (*(vuint8 *)(void*)(&__IPSBAR[0x10001A]))\r
+#define MCF_GPIO_PDDR_TIMER       (*(vuint8 *)(void*)(&__IPSBAR[0x10001B]))\r
+#define MCF_GPIO_PDDR_ETPU        (*(vuint8 *)(void*)(&__IPSBAR[0x10001C]))\r
+#define MCF_GPIO_PPDSDR_ADDR      (*(vuint8 *)(void*)(&__IPSBAR[0x100020]))\r
+#define MCF_GPIO_PPDSDR_DATAH     (*(vuint8 *)(void*)(&__IPSBAR[0x100021]))\r
+#define MCF_GPIO_PPDSDR_DATAL     (*(vuint8 *)(void*)(&__IPSBAR[0x100022]))\r
+#define MCF_GPIO_PPDSDR_BUSCTL    (*(vuint8 *)(void*)(&__IPSBAR[0x100023]))\r
+#define MCF_GPIO_PPDSDR_BS        (*(vuint8 *)(void*)(&__IPSBAR[0x100024]))\r
+#define MCF_GPIO_PPDSDR_FECI2C    (*(vuint8 *)(void*)(&__IPSBAR[0x100027]))\r
+#define MCF_GPIO_PPDSDR_CS        (*(vuint8 *)(void*)(&__IPSBAR[0x100025]))\r
+#define MCF_GPIO_PPDSDR_SDRAM     (*(vuint8 *)(void*)(&__IPSBAR[0x100026]))\r
+#define MCF_GPIO_PPDSDR_UARTH     (*(vuint8 *)(void*)(&__IPSBAR[0x100028]))\r
+#define MCF_GPIO_PPDSDR_UARTL     (*(vuint8 *)(void*)(&__IPSBAR[0x100029]))\r
+#define MCF_GPIO_PPDSDR_QSPI      (*(vuint8 *)(void*)(&__IPSBAR[0x10002A]))\r
+#define MCF_GPIO_PPDSDR_TIMER     (*(vuint8 *)(void*)(&__IPSBAR[0x10002B]))\r
+#define MCF_GPIO_PPDSDR_ETPU      (*(vuint8 *)(void*)(&__IPSBAR[0x10002C]))\r
+#define MCF_GPIO_PCLRR_ADDR       (*(vuint8 *)(void*)(&__IPSBAR[0x100030]))\r
+#define MCF_GPIO_PCLRR_DATAH      (*(vuint8 *)(void*)(&__IPSBAR[0x100031]))\r
+#define MCF_GPIO_PCLRR_DATAL      (*(vuint8 *)(void*)(&__IPSBAR[0x100032]))\r
+#define MCF_GPIO_PCLRR_BUSCTL     (*(vuint8 *)(void*)(&__IPSBAR[0x100033]))\r
+#define MCF_GPIO_PCLRR_BS         (*(vuint8 *)(void*)(&__IPSBAR[0x100034]))\r
+#define MCF_GPIO_PCLRR_CS         (*(vuint8 *)(void*)(&__IPSBAR[0x100035]))\r
+#define MCF_GPIO_PCLRR_SDRAM      (*(vuint8 *)(void*)(&__IPSBAR[0x100036]))\r
+#define MCF_GPIO_PCLRR_FECI2C     (*(vuint8 *)(void*)(&__IPSBAR[0x100037]))\r
+#define MCF_GPIO_PCLRR_UARTH      (*(vuint8 *)(void*)(&__IPSBAR[0x100038]))\r
+#define MCF_GPIO_PCLRR_UARTL      (*(vuint8 *)(void*)(&__IPSBAR[0x100039]))\r
+#define MCF_GPIO_PCLRR_QSPI       (*(vuint8 *)(void*)(&__IPSBAR[0x10003A]))\r
+#define MCF_GPIO_PCLRR_TIMER      (*(vuint8 *)(void*)(&__IPSBAR[0x10003B]))\r
+#define MCF_GPIO_PCLRR_ETPU       (*(vuint8 *)(void*)(&__IPSBAR[0x10003C]))\r
+#define MCF_GPIO_PAR_AD           (*(vuint8 *)(void*)(&__IPSBAR[0x100040]))\r
+#define MCF_GPIO_PAR_BUSCTL       (*(vuint16*)(void*)(&__IPSBAR[0x100042]))\r
+#define MCF_GPIO_PAR_BS           (*(vuint8 *)(void*)(&__IPSBAR[0x100044]))\r
+#define MCF_GPIO_PAR_CS           (*(vuint8 *)(void*)(&__IPSBAR[0x100045]))\r
+#define MCF_GPIO_PAR_SDRAM        (*(vuint8 *)(void*)(&__IPSBAR[0x100046]))\r
+#define MCF_GPIO_PAR_FECI2C       (*(vuint8 *)(void*)(&__IPSBAR[0x100047]))\r
+#define MCF_GPIO_PAR_UART         (*(vuint16*)(void*)(&__IPSBAR[0x100048]))\r
+#define MCF_GPIO_PAR_QSPI         (*(vuint8 *)(void*)(&__IPSBAR[0x10004A]))\r
+#define MCF_GPIO_PAR_TIMER        (*(vuint16*)(void*)(&__IPSBAR[0x10004C]))\r
+#define MCF_GPIO_PAR_ETPU         (*(vuint8 *)(void*)(&__IPSBAR[0x10004E]))\r
+#define MCF_GPIO_DSCR_EIM         (*(vuint8 *)(void*)(&__IPSBAR[0x100050]))\r
+#define MCF_GPIO_DSCR_ETPU        (*(vuint8 *)(void*)(&__IPSBAR[0x100051]))\r
+#define MCF_GPIO_DSCR_FECI2C      (*(vuint8 *)(void*)(&__IPSBAR[0x100052]))\r
+#define MCF_GPIO_DSCR_UART        (*(vuint8 *)(void*)(&__IPSBAR[0x100053]))\r
+#define MCF_GPIO_DSCR_QSPI        (*(vuint8 *)(void*)(&__IPSBAR[0x100054]))\r
+#define MCF_GPIO_DSCR_TIMER       (*(vuint8 *)(void*)(&__IPSBAR[0x100055]))\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PODR_ADDR */\r
+#define MCF_GPIO_PODR_ADDR_PODR_ADDR5            (0x20)\r
+#define MCF_GPIO_PODR_ADDR_PODR_ADDR6            (0x40)\r
+#define MCF_GPIO_PODR_ADDR_PODR_ADDR7            (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PODR_DATAH */\r
+#define MCF_GPIO_PODR_DATAH_PODR_DATAH0          (0x01)\r
+#define MCF_GPIO_PODR_DATAH_PODR_DATAH1          (0x02)\r
+#define MCF_GPIO_PODR_DATAH_PODR_DATAH2          (0x04)\r
+#define MCF_GPIO_PODR_DATAH_PODR_DATAH3          (0x08)\r
+#define MCF_GPIO_PODR_DATAH_PODR_DATAH4          (0x10)\r
+#define MCF_GPIO_PODR_DATAH_PODR_DATAH5          (0x20)\r
+#define MCF_GPIO_PODR_DATAH_PODR_DATAH6          (0x40)\r
+#define MCF_GPIO_PODR_DATAH_PODR_DATAH7          (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PODR_DATAL */\r
+#define MCF_GPIO_PODR_DATAL_PODR_DATAL0          (0x01)\r
+#define MCF_GPIO_PODR_DATAL_PODR_DATAL1          (0x02)\r
+#define MCF_GPIO_PODR_DATAL_PODR_DATAL2          (0x04)\r
+#define MCF_GPIO_PODR_DATAL_PODR_DATAL3          (0x08)\r
+#define MCF_GPIO_PODR_DATAL_PODR_DATAL4          (0x10)\r
+#define MCF_GPIO_PODR_DATAL_PODR_DATAL5          (0x20)\r
+#define MCF_GPIO_PODR_DATAL_PODR_DATAL6          (0x40)\r
+#define MCF_GPIO_PODR_DATAL_PODR_DATAL7          (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PODR_BUSCTL */\r
+#define MCF_GPIO_PODR_BUSCTL_PODR_BUSCTL0        (0x01)\r
+#define MCF_GPIO_PODR_BUSCTL_PODR_BUSCTL1        (0x02)\r
+#define MCF_GPIO_PODR_BUSCTL_PODR_BUSCTL2        (0x04)\r
+#define MCF_GPIO_PODR_BUSCTL_PODR_BUSCTL3        (0x08)\r
+#define MCF_GPIO_PODR_BUSCTL_PODR_BUSCTL4        (0x10)\r
+#define MCF_GPIO_PODR_BUSCTL_PODR_BUSCTL5        (0x20)\r
+#define MCF_GPIO_PODR_BUSCTL_PODR_BUSCTL6        (0x40)\r
+#define MCF_GPIO_PODR_BUSCTL_PODR_BUSCTL7        (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PODR_BS */\r
+#define MCF_GPIO_PODR_BS_PODR_BS0                (0x01)\r
+#define MCF_GPIO_PODR_BS_PODR_BS1                (0x02)\r
+#define MCF_GPIO_PODR_BS_PODR_BS2                (0x04)\r
+#define MCF_GPIO_PODR_BS_PODR_BS3                (0x08)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PODR_CS */\r
+#define MCF_GPIO_PODR_CS_PODR_CS1                (0x02)\r
+#define MCF_GPIO_PODR_CS_PODR_CS2                (0x04)\r
+#define MCF_GPIO_PODR_CS_PODR_CS3                (0x08)\r
+#define MCF_GPIO_PODR_CS_PODR_CS4                (0x10)\r
+#define MCF_GPIO_PODR_CS_PODR_CS5                (0x20)\r
+#define MCF_GPIO_PODR_CS_PODR_CS6                (0x40)\r
+#define MCF_GPIO_PODR_CS_PODR_CS7                (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PODR_SDRAM */\r
+#define MCF_GPIO_PODR_SDRAM_PODR_SDRAM0          (0x01)\r
+#define MCF_GPIO_PODR_SDRAM_PODR_SDRAM1          (0x02)\r
+#define MCF_GPIO_PODR_SDRAM_PODR_SDRAM2          (0x04)\r
+#define MCF_GPIO_PODR_SDRAM_PODR_SDRAM3          (0x08)\r
+#define MCF_GPIO_PODR_SDRAM_PODR_SDRAM4          (0x10)\r
+#define MCF_GPIO_PODR_SDRAM_PODR_SDRAM5          (0x20)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PODR_FECI2C */\r
+#define MCF_GPIO_PODR_FECI2C_PODR_FECI2C0        (0x01)\r
+#define MCF_GPIO_PODR_FECI2C_PODR_FECI2C1        (0x02)\r
+#define MCF_GPIO_PODR_FECI2C_PODR_FECI2C2        (0x04)\r
+#define MCF_GPIO_PODR_FECI2C_PODR_FECI2C3        (0x08)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PODR_UARTH */\r
+#define MCF_GPIO_PODR_UARTH_PODR_UARTH0          (0x01)\r
+#define MCF_GPIO_PODR_UARTH_PODR_UARTH1          (0x02)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PODR_UARTL */\r
+#define MCF_GPIO_PODR_UARTL_PODR_UARTL0          (0x01)\r
+#define MCF_GPIO_PODR_UARTL_PODR_UARTL1          (0x02)\r
+#define MCF_GPIO_PODR_UARTL_PODR_UARTL2          (0x04)\r
+#define MCF_GPIO_PODR_UARTL_PODR_UARTL3          (0x08)\r
+#define MCF_GPIO_PODR_UARTL_PODR_UARTL4          (0x10)\r
+#define MCF_GPIO_PODR_UARTL_PODR_UARTL5          (0x20)\r
+#define MCF_GPIO_PODR_UARTL_PODR_UARTL6          (0x40)\r
+#define MCF_GPIO_PODR_UARTL_PODR_UARTL7          (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PODR_QSPI */\r
+#define MCF_GPIO_PODR_QSPI_PODR_QSPI0            (0x01)\r
+#define MCF_GPIO_PODR_QSPI_PODR_QSPI1            (0x02)\r
+#define MCF_GPIO_PODR_QSPI_PODR_QSPI2            (0x04)\r
+#define MCF_GPIO_PODR_QSPI_PODR_QSPI3            (0x08)\r
+#define MCF_GPIO_PODR_QSPI_PODR_QSPI4            (0x10)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PODR_TIMER */\r
+#define MCF_GPIO_PODR_TIMER_PODR_TIMER0          (0x01)\r
+#define MCF_GPIO_PODR_TIMER_PODR_TIMER1          (0x02)\r
+#define MCF_GPIO_PODR_TIMER_PODR_TIMER2          (0x04)\r
+#define MCF_GPIO_PODR_TIMER_PODR_TIMER3          (0x08)\r
+#define MCF_GPIO_PODR_TIMER_PODR_TIMER4          (0x10)\r
+#define MCF_GPIO_PODR_TIMER_PODR_TIMER5          (0x20)\r
+#define MCF_GPIO_PODR_TIMER_PODR_TIMER6          (0x40)\r
+#define MCF_GPIO_PODR_TIMER_PODR_TIMER7          (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PODR_ETPU */\r
+#define MCF_GPIO_PODR_ETPU_PODR_ETPU0            (0x01)\r
+#define MCF_GPIO_PODR_ETPU_PODR_ETPU1            (0x02)\r
+#define MCF_GPIO_PODR_ETPU_PODR_ETPU2            (0x04)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PDDR_APDDR */\r
+#define MCF_GPIO_PDDR_APDDR_PDDR_APDDR5          (0x20)\r
+#define MCF_GPIO_PDDR_APDDR_PDDR_APDDR6          (0x40)\r
+#define MCF_GPIO_PDDR_APDDR_PDDR_APDDR7          (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PDDR_DATAH */\r
+#define MCF_GPIO_PDDR_DATAH_PDDR_DATAH0          (0x01)\r
+#define MCF_GPIO_PDDR_DATAH_PDDR_DATAH1          (0x02)\r
+#define MCF_GPIO_PDDR_DATAH_PDDR_DATAH2          (0x04)\r
+#define MCF_GPIO_PDDR_DATAH_PDDR_DATAH3          (0x08)\r
+#define MCF_GPIO_PDDR_DATAH_PDDR_DATAH4          (0x10)\r
+#define MCF_GPIO_PDDR_DATAH_PDDR_DATAH5          (0x20)\r
+#define MCF_GPIO_PDDR_DATAH_PDDR_DATAH6          (0x40)\r
+#define MCF_GPIO_PDDR_DATAH_PDDR_DATAH7          (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PDDR_DATAL */\r
+#define MCF_GPIO_PDDR_DATAL_PDDR_DATAL0          (0x01)\r
+#define MCF_GPIO_PDDR_DATAL_PDDR_DATAL1          (0x02)\r
+#define MCF_GPIO_PDDR_DATAL_PDDR_DATAL2          (0x04)\r
+#define MCF_GPIO_PDDR_DATAL_PDDR_DATAL3          (0x08)\r
+#define MCF_GPIO_PDDR_DATAL_PDDR_DATAL4          (0x10)\r
+#define MCF_GPIO_PDDR_DATAL_PDDR_DATAL5          (0x20)\r
+#define MCF_GPIO_PDDR_DATAL_PDDR_DATAL6          (0x40)\r
+#define MCF_GPIO_PDDR_DATAL_PDDR_DATAL7          (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PDDR_BUSCTL */\r
+#define MCF_GPIO_PDDR_BUSCTL_PDDR_BUSCTL0        (0x01)\r
+#define MCF_GPIO_PDDR_BUSCTL_PDDR_BUSCTL1        (0x02)\r
+#define MCF_GPIO_PDDR_BUSCTL_PDDR_BUSCTL2        (0x04)\r
+#define MCF_GPIO_PDDR_BUSCTL_PDDR_BUSCTL3        (0x08)\r
+#define MCF_GPIO_PDDR_BUSCTL_PDDR_BUSCTL4        (0x10)\r
+#define MCF_GPIO_PDDR_BUSCTL_PDDR_BUSCTL5        (0x20)\r
+#define MCF_GPIO_PDDR_BUSCTL_PDDR_BUSCTL6        (0x40)\r
+#define MCF_GPIO_PDDR_BUSCTL_PDDR_BUSCTL7        (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PDDR_BS */\r
+#define MCF_GPIO_PDDR_BS_PDDR_BS0                (0x01)\r
+#define MCF_GPIO_PDDR_BS_PDDR_BS3(x)             (((x)&0x07)<<1)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PDDR_CS */\r
+#define MCF_GPIO_PDDR_CS_PDDR_CS1                (0x02)\r
+#define MCF_GPIO_PDDR_CS_PDDR_CS2                (0x04)\r
+#define MCF_GPIO_PDDR_CS_PDDR_CS3                (0x08)\r
+#define MCF_GPIO_PDDR_CS_PDDR_CS4                (0x10)\r
+#define MCF_GPIO_PDDR_CS_PDDR_CS5                (0x20)\r
+#define MCF_GPIO_PDDR_CS_PDDR_CS6                (0x40)\r
+#define MCF_GPIO_PDDR_CS_PDDR_CS7                (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PDDR_SDRAM */\r
+#define MCF_GPIO_PDDR_SDRAM_PDDR_SDRAM0          (0x01)\r
+#define MCF_GPIO_PDDR_SDRAM_PDDR_SDRAM1          (0x02)\r
+#define MCF_GPIO_PDDR_SDRAM_PDDR_SDRAM2          (0x04)\r
+#define MCF_GPIO_PDDR_SDRAM_PDDR_SDRAM3          (0x08)\r
+#define MCF_GPIO_PDDR_SDRAM_PDDR_SDRAM4          (0x10)\r
+#define MCF_GPIO_PDDR_SDRAM_PDDR_SDRAM5          (0x20)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PDDR_FECI2C */\r
+#define MCF_GPIO_PDDR_FECI2C_PDDR_FECI2C0        (0x01)\r
+#define MCF_GPIO_PDDR_FECI2C_PDDR_FECI2C1        (0x02)\r
+#define MCF_GPIO_PDDR_FECI2C_PDDR_FECI2C2        (0x04)\r
+#define MCF_GPIO_PDDR_FECI2C_PDDR_FECI2C3        (0x08)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PDDR_UARTH */\r
+#define MCF_GPIO_PDDR_UARTH_PDDR_UARTH0          (0x01)\r
+#define MCF_GPIO_PDDR_UARTH_PDDR_UARTH1          (0x02)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PDDR_UARTL */\r
+#define MCF_GPIO_PDDR_UARTL_PDDR_UARTL0          (0x01)\r
+#define MCF_GPIO_PDDR_UARTL_PDDR_UARTL1          (0x02)\r
+#define MCF_GPIO_PDDR_UARTL_PDDR_UARTL2          (0x04)\r
+#define MCF_GPIO_PDDR_UARTL_PDDR_UARTL3          (0x08)\r
+#define MCF_GPIO_PDDR_UARTL_PDDR_UARTL4          (0x10)\r
+#define MCF_GPIO_PDDR_UARTL_PDDR_UARTL5          (0x20)\r
+#define MCF_GPIO_PDDR_UARTL_PDDR_UARTL6          (0x40)\r
+#define MCF_GPIO_PDDR_UARTL_PDDR_UARTL7          (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PDDR_QSPI */\r
+#define MCF_GPIO_PDDR_QSPI_PDDR_QSPI0            (0x01)\r
+#define MCF_GPIO_PDDR_QSPI_PDDR_QSPI1            (0x02)\r
+#define MCF_GPIO_PDDR_QSPI_PDDR_QSPI2            (0x04)\r
+#define MCF_GPIO_PDDR_QSPI_PDDR_QSPI3            (0x08)\r
+#define MCF_GPIO_PDDR_QSPI_PDDR_QSPI4            (0x10)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PDDR_TIMER */\r
+#define MCF_GPIO_PDDR_TIMER_PDDR_TIMER0          (0x01)\r
+#define MCF_GPIO_PDDR_TIMER_PDDR_TIMER1          (0x02)\r
+#define MCF_GPIO_PDDR_TIMER_PDDR_TIMER2          (0x04)\r
+#define MCF_GPIO_PDDR_TIMER_PDDR_TIMER3          (0x08)\r
+#define MCF_GPIO_PDDR_TIMER_PDDR_TIMER4          (0x10)\r
+#define MCF_GPIO_PDDR_TIMER_PDDR_TIMER5          (0x20)\r
+#define MCF_GPIO_PDDR_TIMER_PDDR_TIMER6          (0x40)\r
+#define MCF_GPIO_PDDR_TIMER_PDDR_TIMER7          (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PDDR_ETPU */\r
+#define MCF_GPIO_PDDR_ETPU_PDDR_ETPU0            (0x01)\r
+#define MCF_GPIO_PDDR_ETPU_PDDR_ETPU1            (0x02)\r
+#define MCF_GPIO_PDDR_ETPU_PDDR_ETPU2            (0x04)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PPDSDR_ADDR */\r
+#define MCF_GPIO_PPDSDR_ADDR_PPDSDR_ADDR5        (0x20)\r
+#define MCF_GPIO_PPDSDR_ADDR_PPDSDR_ADDR6        (0x40)\r
+#define MCF_GPIO_PPDSDR_ADDR_PPDSDR_ADDR7        (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PPDSDR_DATAH */\r
+#define MCF_GPIO_PPDSDR_DATAH_PPDSDR_DATAH0      (0x01)\r
+#define MCF_GPIO_PPDSDR_DATAH_PPDSDR_DATAH1      (0x02)\r
+#define MCF_GPIO_PPDSDR_DATAH_PPDSDR_DATAH2      (0x04)\r
+#define MCF_GPIO_PPDSDR_DATAH_PPDSDR_DATAH3      (0x08)\r
+#define MCF_GPIO_PPDSDR_DATAH_PPDSDR_DATAH4      (0x10)\r
+#define MCF_GPIO_PPDSDR_DATAH_PPDSDR_DATAH5      (0x20)\r
+#define MCF_GPIO_PPDSDR_DATAH_PPDSDR_DATAH6      (0x40)\r
+#define MCF_GPIO_PPDSDR_DATAH_PPDSDR_DATAH7      (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PPDSDR_DATAL */\r
+#define MCF_GPIO_PPDSDR_DATAL_PPDSDR_DATAL0      (0x01)\r
+#define MCF_GPIO_PPDSDR_DATAL_PPDSDR_DATAL1      (0x02)\r
+#define MCF_GPIO_PPDSDR_DATAL_PPDSDR_DATAL2      (0x04)\r
+#define MCF_GPIO_PPDSDR_DATAL_PPDSDR_DATAL3      (0x08)\r
+#define MCF_GPIO_PPDSDR_DATAL_PPDSDR_DATAL4      (0x10)\r
+#define MCF_GPIO_PPDSDR_DATAL_PPDSDR_DATAL5      (0x20)\r
+#define MCF_GPIO_PPDSDR_DATAL_PPDSDR_DATAL6      (0x40)\r
+#define MCF_GPIO_PPDSDR_DATAL_PPDSDR_DATAL7      (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PPDSDR_BUSCTL */\r
+#define MCF_GPIO_PPDSDR_BUSCTL_PPDSDR_BUSCTL0    (0x01)\r
+#define MCF_GPIO_PPDSDR_BUSCTL_PPDSDR_BUSCTL1    (0x02)\r
+#define MCF_GPIO_PPDSDR_BUSCTL_PPDSDR_BUSCTL2    (0x04)\r
+#define MCF_GPIO_PPDSDR_BUSCTL_PPDSDR_BUSCTL3    (0x08)\r
+#define MCF_GPIO_PPDSDR_BUSCTL_PPDSDR_BUSCTL4    (0x10)\r
+#define MCF_GPIO_PPDSDR_BUSCTL_PPDSDR_BUSCTL5    (0x20)\r
+#define MCF_GPIO_PPDSDR_BUSCTL_PPDSDR_BUSCTL6    (0x40)\r
+#define MCF_GPIO_PPDSDR_BUSCTL_PPDSDR_BUSCTL7    (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PPDSDR_BS */\r
+#define MCF_GPIO_PPDSDR_BS_PPDSDR_BS0            (0x01)\r
+#define MCF_GPIO_PPDSDR_BS_PPDSDR_BS1            (0x02)\r
+#define MCF_GPIO_PPDSDR_BS_PPDSDR_BS2            (0x04)\r
+#define MCF_GPIO_PPDSDR_BS_PPDSDR_BS3            (0x08)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PPDSDR_FECI2C */\r
+#define MCF_GPIO_PPDSDR_FECI2C_PPDSDR_FECI2C0    (0x01)\r
+#define MCF_GPIO_PPDSDR_FECI2C_PPDSDR_FECI2C1    (0x02)\r
+#define MCF_GPIO_PPDSDR_FECI2C_PPDSDR_FECI2C2    (0x04)\r
+#define MCF_GPIO_PPDSDR_FECI2C_PPDSDR_FECI2C3    (0x08)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PPDSDR_CS */\r
+#define MCF_GPIO_PPDSDR_CS_PPDSDR_CS1            (0x02)\r
+#define MCF_GPIO_PPDSDR_CS_PPDSDR_CS2            (0x04)\r
+#define MCF_GPIO_PPDSDR_CS_PPDSDR_CS3            (0x08)\r
+#define MCF_GPIO_PPDSDR_CS_PPDSDR_CS4            (0x10)\r
+#define MCF_GPIO_PPDSDR_CS_PPDSDR_CS5            (0x20)\r
+#define MCF_GPIO_PPDSDR_CS_PPDSDR_CS6            (0x40)\r
+#define MCF_GPIO_PPDSDR_CS_PPDSDR_CS7            (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PPDSDR_SDRAM */\r
+#define MCF_GPIO_PPDSDR_SDRAM_PPDSDR_SDRAM0      (0x01)\r
+#define MCF_GPIO_PPDSDR_SDRAM_PPDSDR_SDRAM1      (0x02)\r
+#define MCF_GPIO_PPDSDR_SDRAM_PPDSDR_SDRAM2      (0x04)\r
+#define MCF_GPIO_PPDSDR_SDRAM_PPDSDR_SDRAM3      (0x08)\r
+#define MCF_GPIO_PPDSDR_SDRAM_PPDSDR_SDRAM4      (0x10)\r
+#define MCF_GPIO_PPDSDR_SDRAM_PPDSDR_SDRAM5      (0x20)\r
+#define MCF_GPIO_PPDSDR_SDRAM_PPDSDR_SDRAM6      (0x40)\r
+#define MCF_GPIO_PPDSDR_SDRAM_PPDSDR_SDRAM7      (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PPDSDR_UARTH */\r
+#define MCF_GPIO_PPDSDR_UARTH_PPDSDR_UARTH0      (0x01)\r
+#define MCF_GPIO_PPDSDR_UARTH_PPDSDR_UARTH1      (0x02)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PPDSDR_UARTL */\r
+#define MCF_GPIO_PPDSDR_UARTL_PPDSDR_UARTL0      (0x01)\r
+#define MCF_GPIO_PPDSDR_UARTL_PPDSDR_UARTL1      (0x02)\r
+#define MCF_GPIO_PPDSDR_UARTL_PPDSDR_UARTL2      (0x04)\r
+#define MCF_GPIO_PPDSDR_UARTL_PPDSDR_UARTL3      (0x08)\r
+#define MCF_GPIO_PPDSDR_UARTL_PPDSDR_UARTL4      (0x10)\r
+#define MCF_GPIO_PPDSDR_UARTL_PPDSDR_UARTL5      (0x20)\r
+#define MCF_GPIO_PPDSDR_UARTL_PPDSDR_UARTL6      (0x40)\r
+#define MCF_GPIO_PPDSDR_UARTL_PPDSDR_UARTL7      (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PPDSDR_QSPI */\r
+#define MCF_GPIO_PPDSDR_QSPI_PPDSDR_QSPI0        (0x01)\r
+#define MCF_GPIO_PPDSDR_QSPI_PPDSDR_QSPI1        (0x02)\r
+#define MCF_GPIO_PPDSDR_QSPI_PPDSDR_QSPI2        (0x04)\r
+#define MCF_GPIO_PPDSDR_QSPI_PPDSDR_QSPI3        (0x08)\r
+#define MCF_GPIO_PPDSDR_QSPI_PPDSDR_QSPI4        (0x10)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PPDSDR_TIMER */\r
+#define MCF_GPIO_PPDSDR_TIMER_PPDSDR_TIMER0      (0x01)\r
+#define MCF_GPIO_PPDSDR_TIMER_PPDSDR_TIMER1      (0x02)\r
+#define MCF_GPIO_PPDSDR_TIMER_PPDSDR_TIMER2      (0x04)\r
+#define MCF_GPIO_PPDSDR_TIMER_PPDSDR_TIMER3      (0x08)\r
+#define MCF_GPIO_PPDSDR_TIMER_PPDSDR_TIMER4      (0x10)\r
+#define MCF_GPIO_PPDSDR_TIMER_PPDSDR_TIMER5      (0x20)\r
+#define MCF_GPIO_PPDSDR_TIMER_PPDSDR_TIMER6      (0x40)\r
+#define MCF_GPIO_PPDSDR_TIMER_PPDSDR_TIMER7      (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PPDSDR_ETPU */\r
+#define MCF_GPIO_PPDSDR_ETPU_PPDSDR_ETPU0        (0x01)\r
+#define MCF_GPIO_PPDSDR_ETPU_PPDSDR_ETPU1        (0x02)\r
+#define MCF_GPIO_PPDSDR_ETPU_PPDSDR_ETPU2        (0x04)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PCLRR_ADDR */\r
+#define MCF_GPIO_PCLRR_ADDR_PCLRR_ADDR5          (0x20)\r
+#define MCF_GPIO_PCLRR_ADDR_PCLRR_ADDR6          (0x40)\r
+#define MCF_GPIO_PCLRR_ADDR_PCLRR_ADDR7          (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PCLRR_DATAH */\r
+#define MCF_GPIO_PCLRR_DATAH_PCLRR_DATAH0        (0x01)\r
+#define MCF_GPIO_PCLRR_DATAH_PCLRR_DATAH1        (0x02)\r
+#define MCF_GPIO_PCLRR_DATAH_PCLRR_DATAH2        (0x04)\r
+#define MCF_GPIO_PCLRR_DATAH_PCLRR_DATAH3        (0x08)\r
+#define MCF_GPIO_PCLRR_DATAH_PCLRR_DATAH4        (0x10)\r
+#define MCF_GPIO_PCLRR_DATAH_PCLRR_DATAH5        (0x20)\r
+#define MCF_GPIO_PCLRR_DATAH_PCLRR_DATAH6        (0x40)\r
+#define MCF_GPIO_PCLRR_DATAH_PCLRR_DATAH7        (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PCLRR_DATAL */\r
+#define MCF_GPIO_PCLRR_DATAL_PCLRR_DATAL0        (0x01)\r
+#define MCF_GPIO_PCLRR_DATAL_PCLRR_DATAL1        (0x02)\r
+#define MCF_GPIO_PCLRR_DATAL_PCLRR_DATAL2        (0x04)\r
+#define MCF_GPIO_PCLRR_DATAL_PCLRR_DATAL3        (0x08)\r
+#define MCF_GPIO_PCLRR_DATAL_PCLRR_DATAL4        (0x10)\r
+#define MCF_GPIO_PCLRR_DATAL_PCLRR_DATAL5        (0x20)\r
+#define MCF_GPIO_PCLRR_DATAL_PCLRR_DATAL6        (0x40)\r
+#define MCF_GPIO_PCLRR_DATAL_PCLRR_DATAL7        (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PCLRR_BUSCTL */\r
+#define MCF_GPIO_PCLRR_BUSCTL_PCLRR_BUSCTL0      (0x01)\r
+#define MCF_GPIO_PCLRR_BUSCTL_PCLRR_BUSCTL1      (0x02)\r
+#define MCF_GPIO_PCLRR_BUSCTL_PCLRR_BUSCTL2      (0x04)\r
+#define MCF_GPIO_PCLRR_BUSCTL_PCLRR_BUSCTL3      (0x08)\r
+#define MCF_GPIO_PCLRR_BUSCTL_PCLRR_BUSCTL4      (0x10)\r
+#define MCF_GPIO_PCLRR_BUSCTL_PCLRR_BUSCTL5      (0x20)\r
+#define MCF_GPIO_PCLRR_BUSCTL_PCLRR_BUSCTL6      (0x40)\r
+#define MCF_GPIO_PCLRR_BUSCTL_PCLRR_BUSCTL7      (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PCLRR_BS */\r
+#define MCF_GPIO_PCLRR_BS_PCLRR_BS0              (0x01)\r
+#define MCF_GPIO_PCLRR_BS_PCLRR_BS1              (0x02)\r
+#define MCF_GPIO_PCLRR_BS_PCLRR_BS2              (0x04)\r
+#define MCF_GPIO_PCLRR_BS_PCLRR_BS3              (0x08)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PCLRR_CS */\r
+#define MCF_GPIO_PCLRR_CS_PCLRR_CS1              (0x02)\r
+#define MCF_GPIO_PCLRR_CS_PCLRR_CS2              (0x04)\r
+#define MCF_GPIO_PCLRR_CS_PCLRR_CS3              (0x08)\r
+#define MCF_GPIO_PCLRR_CS_PCLRR_CS4              (0x10)\r
+#define MCF_GPIO_PCLRR_CS_PCLRR_CS5              (0x20)\r
+#define MCF_GPIO_PCLRR_CS_PCLRR_CS6              (0x40)\r
+#define MCF_GPIO_PCLRR_CS_PCLRR_CS7              (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PCLRR_SDRAM */\r
+#define MCF_GPIO_PCLRR_SDRAM_PCLRR_SDRAM0        (0x01)\r
+#define MCF_GPIO_PCLRR_SDRAM_PCLRR_SDRAM1        (0x02)\r
+#define MCF_GPIO_PCLRR_SDRAM_PCLRR_SDRAM2        (0x04)\r
+#define MCF_GPIO_PCLRR_SDRAM_PCLRR_SDRAM3        (0x08)\r
+#define MCF_GPIO_PCLRR_SDRAM_PCLRR_SDRAM4        (0x10)\r
+#define MCF_GPIO_PCLRR_SDRAM_PCLRR_SDRAM5        (0x20)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PCLRR_FECI2C */\r
+#define MCF_GPIO_PCLRR_FECI2C_PCLRR_FECI2C0      (0x01)\r
+#define MCF_GPIO_PCLRR_FECI2C_PCLRR_FECI2C1      (0x02)\r
+#define MCF_GPIO_PCLRR_FECI2C_PCLRR_FECI2C2      (0x04)\r
+#define MCF_GPIO_PCLRR_FECI2C_PCLRR_FECI2C3      (0x08)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PCLRR_UARTH */\r
+#define MCF_GPIO_PCLRR_UARTH_PCLRR_UARTH0        (0x01)\r
+#define MCF_GPIO_PCLRR_UARTH_PCLRR_UARTH1        (0x02)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PCLRR_UARTL */\r
+#define MCF_GPIO_PCLRR_UARTL_PCLRR_UARTL0        (0x01)\r
+#define MCF_GPIO_PCLRR_UARTL_PCLRR_UARTL1        (0x02)\r
+#define MCF_GPIO_PCLRR_UARTL_PCLRR_UARTL2        (0x04)\r
+#define MCF_GPIO_PCLRR_UARTL_PCLRR_UARTL3        (0x08)\r
+#define MCF_GPIO_PCLRR_UARTL_PCLRR_UARTL4        (0x10)\r
+#define MCF_GPIO_PCLRR_UARTL_PCLRR_UARTL5        (0x20)\r
+#define MCF_GPIO_PCLRR_UARTL_PCLRR_UARTL6        (0x40)\r
+#define MCF_GPIO_PCLRR_UARTL_PCLRR_UARTL7        (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PCLRR_QSPI */\r
+#define MCF_GPIO_PCLRR_QSPI_PCLRR_QSPI0          (0x01)\r
+#define MCF_GPIO_PCLRR_QSPI_PCLRR_QSPI1          (0x02)\r
+#define MCF_GPIO_PCLRR_QSPI_PCLRR_QSPI2          (0x04)\r
+#define MCF_GPIO_PCLRR_QSPI_PCLRR_QSPI3          (0x08)\r
+#define MCF_GPIO_PCLRR_QSPI_PCLRR_QSPI4          (0x10)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PCLRR_TIMER */\r
+#define MCF_GPIO_PCLRR_TIMER_PCLRR_TIMER0        (0x01)\r
+#define MCF_GPIO_PCLRR_TIMER_PCLRR_TIMER1        (0x02)\r
+#define MCF_GPIO_PCLRR_TIMER_PCLRR_TIMER2        (0x04)\r
+#define MCF_GPIO_PCLRR_TIMER_PCLRR_TIMER3        (0x08)\r
+#define MCF_GPIO_PCLRR_TIMER_PCLRR_TIMER4        (0x10)\r
+#define MCF_GPIO_PCLRR_TIMER_PCLRR_TIMER5        (0x20)\r
+#define MCF_GPIO_PCLRR_TIMER_PCLRR_TIMER6        (0x40)\r
+#define MCF_GPIO_PCLRR_TIMER_PCLRR_TIMER7        (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PCLRR_ETPU */\r
+#define MCF_GPIO_PCLRR_ETPU_PCLRR_ETPU0          (0x01)\r
+#define MCF_GPIO_PCLRR_ETPU_PCLRR_ETPU1          (0x02)\r
+#define MCF_GPIO_PCLRR_ETPU_PCLRR_ETPU2          (0x04)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PAR_AD */\r
+#define MCF_GPIO_PAR_AD_PAR_DATAL                (0x01)\r
+#define MCF_GPIO_PAR_AD_PAR_ADDR21               (0x20)\r
+#define MCF_GPIO_PAR_AD_PAR_ADDR22               (0x40)\r
+#define MCF_GPIO_PAR_AD_PAR_ADDR23               (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PAR_BUSCTL */\r
+#define MCF_GPIO_PAR_BUSCTL_PAR_TIP(x)           (((x)&0x0003)<<0)\r
+#define MCF_GPIO_PAR_BUSCTL_PAR_TS(x)            (((x)&0x0003)<<2)\r
+#define MCF_GPIO_PAR_BUSCTL_PAR_TSIZ0            (0x0010)\r
+#define MCF_GPIO_PAR_BUSCTL_PAR_TSIZ1            (0x0040)\r
+#define MCF_GPIO_PAR_BUSCTL_PAR_RWB              (0x0100)\r
+#define MCF_GPIO_PAR_BUSCTL_PAR_TEA(x)           (((x)&0x0003)<<10)\r
+#define MCF_GPIO_PAR_BUSCTL_PAR_TA               (0x1000)\r
+#define MCF_GPIO_PAR_BUSCTL_PAR_OE               (0x4000)\r
+#define MCF_GPIO_PAR_BUSCTL_PAR_TEA_GPIO         (0x0000)\r
+#define MCF_GPIO_PAR_BUSCTL_PAR_TEA_DMA          (0x0800)\r
+#define MCF_GPIO_PAR_BUSCTL_PAR_TEA_TEA          (0x0C00)\r
+#define MCF_GPIO_PAR_BUSCTL_PAR_TS_GPIO          (0x0000)\r
+#define MCF_GPIO_PAR_BUSCTL_PAR_TS_DMA           (0x0080)\r
+#define MCF_GPIO_PAR_BUSCTL_PAR_TS_TS            (0x00C0)\r
+#define MCF_GPIO_PAR_BUSCTL_PAR_TIP_GPIO         (0x0000)\r
+#define MCF_GPIO_PAR_BUSCTL_PAR_TIP_DMA          (0x0002)\r
+#define MCF_GPIO_PAR_BUSCTL_PAR_TIP_TEA          (0x0003)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PAR_BS */\r
+#define MCF_GPIO_PAR_BS_PAR_BS0                  (0x01)\r
+#define MCF_GPIO_PAR_BS_PAR_BS1                  (0x02)\r
+#define MCF_GPIO_PAR_BS_PAR_BS2                  (0x04)\r
+#define MCF_GPIO_PAR_BS_PAR_BS3                  (0x08)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PAR_CS */\r
+#define MCF_GPIO_PAR_CS_PAR_CS1                  (0x02)\r
+#define MCF_GPIO_PAR_CS_PAR_CS2                  (0x04)\r
+#define MCF_GPIO_PAR_CS_PAR_CS3                  (0x08)\r
+#define MCF_GPIO_PAR_CS_PAR_CS4                  (0x10)\r
+#define MCF_GPIO_PAR_CS_PAR_CS5                  (0x20)\r
+#define MCF_GPIO_PAR_CS_PAR_CS6                  (0x40)\r
+#define MCF_GPIO_PAR_CS_PAR_CS7                  (0x80)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PAR_SDRAM */\r
+#define MCF_GPIO_PAR_SDRAM_PAR_SDCS0             (0x01)\r
+#define MCF_GPIO_PAR_SDRAM_PAR_SDCS1             (0x02)\r
+#define MCF_GPIO_PAR_SDRAM_PAR_SCKE              (0x04)\r
+#define MCF_GPIO_PAR_SDRAM_PAR_SRAS              (0x08)\r
+#define MCF_GPIO_PAR_SDRAM_PAR_SCAS              (0x10)\r
+#define MCF_GPIO_PAR_SDRAM_PAR_SDWE              (0x20)\r
+#define MCF_GPIO_PAR_SDRAM_PAR_CSSDCS(x)         (((x)&0x03)<<6)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PAR_FECI2C */\r
+#define MCF_GPIO_PAR_FECI2C_PAR_SDA(x)           (((x)&0x03)<<0)\r
+#define MCF_GPIO_PAR_FECI2C_PAR_SCL(x)           (((x)&0x03)<<2)\r
+#define MCF_GPIO_PAR_FECI2C_PAR_EMDIO(x)         (((x)&0x03)<<4)\r
+#define MCF_GPIO_PAR_FECI2C_PAR_EMDC(x)          (((x)&0x03)<<6)\r
+#define MCF_GPIO_PAR_FECI2C_PAR_EMDC_GPIO        (0x00)\r
+#define MCF_GPIO_PAR_FECI2C_PAR_EMDC_UART2       (0x40)\r
+#define MCF_GPIO_PAR_FECI2C_PAR_EMDC_I2C         (0x80)\r
+#define MCF_GPIO_PAR_FECI2C_PAR_EMDC_FEC         (0xC0)\r
+#define MCF_GPIO_PAR_FECI2C_PAR_EMDIO_GPIO       (0x00)\r
+#define MCF_GPIO_PAR_FECI2C_PAR_EMDIO_UART2      (0x10)\r
+#define MCF_GPIO_PAR_FECI2C_PAR_EMDIO_I2C        (0x20)\r
+#define MCF_GPIO_PAR_FECI2C_PAR_EMDIO_FEC        (0x30)\r
+#define MCF_GPIO_PAR_FECI2C_PAR_SCL_GPIO         (0x00)\r
+#define MCF_GPIO_PAR_FECI2C_PAR_SCL_FLEX         (0x08)\r
+#define MCF_GPIO_PAR_FECI2C_PAR_SCL_I2C          (0x0C)\r
+#define MCF_GPIO_PAR_FECI2C_PAR_SDA_GPIO         (0x00)\r
+#define MCF_GPIO_PAR_FECI2C_PAR_SDA_FLEX         (0x02)\r
+#define MCF_GPIO_PAR_FECI2C_PAR_SDA_I2C          (0x03)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PAR_UART */\r
+#define MCF_GPIO_PAR_UART_PAR_U0RTS              (0x0001)\r
+#define MCF_GPIO_PAR_UART_PAR_U0CTS              (0x0002)\r
+#define MCF_GPIO_PAR_UART_PAR_U0TXD              (0x0004)\r
+#define MCF_GPIO_PAR_UART_PAR_U0RXD              (0x0008)\r
+#define MCF_GPIO_PAR_UART_PAR_U1RTS(x)           (((x)&0x0003)<<4)\r
+#define MCF_GPIO_PAR_UART_PAR_U1CTS(x)           (((x)&0x0003)<<6)\r
+#define MCF_GPIO_PAR_UART_PAR_U1TXD(x)           (((x)&0x0003)<<8)\r
+#define MCF_GPIO_PAR_UART_PAR_U1RXD(x)           (((x)&0x0003)<<10)\r
+#define MCF_GPIO_PAR_UART_PAR_U2TXD              (0x1000)\r
+#define MCF_GPIO_PAR_UART_PAR_U2RXD              (0x2000)\r
+#define MCF_GPIO_PAR_UART_PAR_CAN1EN             (0x4000)\r
+#define MCF_GPIO_PAR_UART_PAR_DREQ2              (0x8000)\r
+#define MCF_GPIO_PAR_UART_PAR_U1RXD_GPIO         (0x0000)\r
+#define MCF_GPIO_PAR_UART_PAR_U1RXD_FLEX         (0x0800)\r
+#define MCF_GPIO_PAR_UART_PAR_U1RXD_UART1        (0x0C00)\r
+#define MCF_GPIO_PAR_UART_PAR_U1TXD_GPIO         (0x0000)\r
+#define MCF_GPIO_PAR_UART_PAR_U1TXD_FLEX         (0x0200)\r
+#define MCF_GPIO_PAR_UART_PAR_U1TXD_UART1        (0x0300)\r
+#define MCF_GPIO_PAR_UART_PAR_U1CTS_GPIO         (0x0000)\r
+#define MCF_GPIO_PAR_UART_PAR_U1CTS_UART2        (0x0080)\r
+#define MCF_GPIO_PAR_UART_PAR_U1CTS_UART1        (0x00C0)\r
+#define MCF_GPIO_PAR_UART_PAR_U1RTS_GPIO         (0x0000)\r
+#define MCF_GPIO_PAR_UART_PAR_U1RTS_UART2        (0x0020)\r
+#define MCF_GPIO_PAR_UART_PAR_U1RTS_UART1        (0x0030)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PAR_QSPI */\r
+#define MCF_GPIO_PAR_QSPI_PAR_SCK(x)             (((x)&0x03)<<0)\r
+#define MCF_GPIO_PAR_QSPI_PAR_DOUT               (0x04)\r
+#define MCF_GPIO_PAR_QSPI_PAR_DIN(x)             (((x)&0x03)<<3)\r
+#define MCF_GPIO_PAR_QSPI_PAR_PCS0               (0x20)\r
+#define MCF_GPIO_PAR_QSPI_PAR_PCS1(x)            (((x)&0x03)<<6)\r
+#define MCF_GPIO_PAR_QSPI_PAR_PCS1_GPIO          (0x00)\r
+#define MCF_GPIO_PAR_QSPI_PAR_PCS1_SDRAMC        (0x80)\r
+#define MCF_GPIO_PAR_QSPI_PAR_PCS1_QSPI          (0xC0)\r
+#define MCF_GPIO_PAR_QSPI_PAR_DIN_GPIO           (0x00)\r
+#define MCF_GPIO_PAR_QSPI_PAR_DIN_I2C            (0x10)\r
+#define MCF_GPIO_PAR_QSPI_PAR_DIN_QSPI           (0x1C)\r
+#define MCF_GPIO_PAR_QSPI_PAR_SCK_GPIO           (0x00)\r
+#define MCF_GPIO_PAR_QSPI_PAR_SCK_I2C            (0x02)\r
+#define MCF_GPIO_PAR_QSPI_PAR_SCK_QSPI           (0x03)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PAR_TIMER */\r
+#define MCF_GPIO_PAR_TIMER_PAR_T0OUT(x)          (((x)&0x0003)<<0)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T1OUT(x)          (((x)&0x0003)<<2)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T2OUT(x)          (((x)&0x0003)<<4)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T3OUT(x)          (((x)&0x0003)<<6)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T0IN(x)           (((x)&0x0003)<<8)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T1IN(x)           (((x)&0x0003)<<10)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T2IN(x)           (((x)&0x0003)<<12)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T3IN(x)           (((x)&0x0003)<<14)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T3IN_GPIO         (0x0000)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T3IN_QSPI         (0x4000)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T3IN_UART2        (0x8000)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T3IN_T3IN         (0xC000)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T2IN_GPIO         (0x0000)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T2IN_T2OUT        (0x1000)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T2IN_DMA          (0x2000)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T2IN_T2IN         (0x3000)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T1IN_GPIO         (0x0000)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T1IN_T1OUT        (0x0400)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T1IN_DMA          (0x0800)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T1IN_T1IN         (0x0C00)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T0IN_GPIO         (0x0000)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T0IN_DMA          (0x0200)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T0IN_T0IN         (0x0300)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T3OUT_GPIO        (0x0000)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T3OUT_QSPI        (0x0040)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T3OUT_UART2       (0x0080)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T3OUT_T3OUT       (0x00C0)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T2OUT_GPIO        (0x0000)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T2OUT_DMA         (0x0020)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T2OUT_T2OUT       (0x0030)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T1OUT_GPIO        (0x0000)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T1OUT_DMA         (0x0008)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T1OUT_T1OUT       (0x000C)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T0OUT_GPIO        (0x0000)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T0OUT_DMA         (0x0002)\r
+#define MCF_GPIO_PAR_TIMER_PAR_T0OUT_T0OUT       (0x0003)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_PAR_ETPU */\r
+#define MCF_GPIO_PAR_ETPU_PAR_LTPU_ODIS          (0x01)\r
+#define MCF_GPIO_PAR_ETPU_PAR_UTPU_ODIS          (0x02)\r
+#define MCF_GPIO_PAR_ETPU_PAR_TCRCLK             (0x04)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_DSCR_EIM */\r
+#define MCF_GPIO_DSCR_EIM_DSCR_EIM0              (0x01)\r
+#define MCF_GPIO_DSCR_EIM_DSCR_EIM1              (0x10)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_DSCR_ETPU */\r
+#define MCF_GPIO_DSCR_ETPU_DSCR_ETPU_7_0         (0x01)\r
+#define MCF_GPIO_DSCR_ETPU_DSCR_ETPU_15_8        (0x04)\r
+#define MCF_GPIO_DSCR_ETPU_DSCR_ETPU_23_16       (0x10)\r
+#define MCF_GPIO_DSCR_ETPU_DSCR_ETPU_31_24       (0x40)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_DSCR_FECI2C */\r
+#define MCF_GPIO_DSCR_FECI2C_DSCR_I2C            (0x01)\r
+#define MCF_GPIO_DSCR_FECI2C_DSCR_FEC            (0x10)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_DSCR_UART */\r
+#define MCF_GPIO_DSCR_UART_DSCR_UART0            (0x01)\r
+#define MCF_GPIO_DSCR_UART_DSCR_UART1            (0x04)\r
+#define MCF_GPIO_DSCR_UART_DSCR_UART2            (0x10)\r
+#define MCF_GPIO_DSCR_UART_DSCR_IRQ              (0x40)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_DSCR_QSPI */\r
+#define MCF_GPIO_DSCR_QSPI_DSCR_QSPI             (0x01)\r
+\r
+/* Bit definitions and macros for MCF_GPIO_DSCR_TIMER */\r
+#define MCF_GPIO_DSCR_TIMER_DSCR_TIMER           (0x01)\r
+\r
+/********************************************************************/\r
+\r
+#endif /* __MCF523X_GPIO_H__ */\r
index ee46655070fc79c9d58fc3153cb49ca7cf40d9ed..3bb780b826335a52926c590c78881c66fd3e3b4b 100644 (file)
@@ -1,63 +1,63 @@
-/*
- * These files are taken from the MCF523X source code example package
- * which is available on the Freescale website. Freescale explicitly 
- * grants the redistribution and modification of these source files.
- * The complete licensing information is available in the file 
- * LICENSE_FREESCALE.TXT.
- *
- * File:       mcf523x_i2c.h
- * Purpose:    Register and bit definitions for the MCF523X
- *
- * Notes:      
- *     
- */
-
-#ifndef __MCF523X_I2C_H__
-#define __MCF523X_I2C_H__
-
-/*********************************************************************
-*
-* I2C Module (I2C)
-*
-*********************************************************************/
-
-/* Register read/write macros */
-#define MCF_I2C_I2AR     (*(vuint8 *)(void*)(&__IPSBAR[0x000300]))
-#define MCF_I2C_I2FDR    (*(vuint8 *)(void*)(&__IPSBAR[0x000304]))
-#define MCF_I2C_I2CR     (*(vuint8 *)(void*)(&__IPSBAR[0x000308]))
-#define MCF_I2C_I2SR     (*(vuint8 *)(void*)(&__IPSBAR[0x00030C]))
-#define MCF_I2C_I2DR     (*(vuint8 *)(void*)(&__IPSBAR[0x000310]))
-#define MCF_I2C_I2ICR    (*(vuint8 *)(void*)(&__IPSBAR[0x000320]))
-
-/* Bit definitions and macros for MCF_I2C_I2AR */
-#define MCF_I2C_I2AR_ADR(x)    (((x)&0x7F)<<1)
-
-/* Bit definitions and macros for MCF_I2C_I2FDR */
-#define MCF_I2C_I2FDR_IC(x)    (((x)&0x3F)<<0)
-
-/* Bit definitions and macros for MCF_I2C_I2CR */
-#define MCF_I2C_I2CR_RSTA      (0x04)
-#define MCF_I2C_I2CR_TXAK      (0x08)
-#define MCF_I2C_I2CR_MTX       (0x10)
-#define MCF_I2C_I2CR_MSTA      (0x20)
-#define MCF_I2C_I2CR_IIEN      (0x40)
-#define MCF_I2C_I2CR_IEN       (0x80)
-
-/* Bit definitions and macros for MCF_I2C_I2SR */
-#define MCF_I2C_I2SR_RXAK      (0x01)
-#define MCF_I2C_I2SR_IIF       (0x02)
-#define MCF_I2C_I2SR_SRW       (0x04)
-#define MCF_I2C_I2SR_IAL       (0x10)
-#define MCF_I2C_I2SR_IBB       (0x20)
-#define MCF_I2C_I2SR_IAAS      (0x40)
-#define MCF_I2C_I2SR_ICF       (0x80)
-
-/* Bit definitions and macros for MCF_I2C_I2ICR */
-#define MCF_I2C_I2ICR_IE       (0x01)
-#define MCF_I2C_I2ICR_RE       (0x02)
-#define MCF_I2C_I2ICR_TE       (0x04)
-#define MCF_I2C_I2ICR_BNBE     (0x08)
-
-/********************************************************************/
-
-#endif /* __MCF523X_I2C_H__ */
+/*\r
+ * These files are taken from the MCF523X source code example package\r
+ * which is available on the Freescale website. Freescale explicitly \r
+ * grants the redistribution and modification of these source files.\r
+ * The complete licensing information is available in the file \r
+ * LICENSE_FREESCALE.TXT.\r
+ *\r
+ * File:       mcf523x_i2c.h\r
+ * Purpose:    Register and bit definitions for the MCF523X\r
+ *\r
+ * Notes:      \r
+ *     \r
+ */\r
+\r
+#ifndef __MCF523X_I2C_H__\r
+#define __MCF523X_I2C_H__\r
+\r
+/*********************************************************************\r
+*\r
+* I2C Module (I2C)\r
+*\r
+*********************************************************************/\r
+\r
+/* Register read/write macros */\r
+#define MCF_I2C_I2AR     (*(vuint8 *)(void*)(&__IPSBAR[0x000300]))\r
+#define MCF_I2C_I2FDR    (*(vuint8 *)(void*)(&__IPSBAR[0x000304]))\r
+#define MCF_I2C_I2CR     (*(vuint8 *)(void*)(&__IPSBAR[0x000308]))\r
+#define MCF_I2C_I2SR     (*(vuint8 *)(void*)(&__IPSBAR[0x00030C]))\r
+#define MCF_I2C_I2DR     (*(vuint8 *)(void*)(&__IPSBAR[0x000310]))\r
+#define MCF_I2C_I2ICR    (*(vuint8 *)(void*)(&__IPSBAR[0x000320]))\r
+\r
+/* Bit definitions and macros for MCF_I2C_I2AR */\r
+#define MCF_I2C_I2AR_ADR(x)    (((x)&0x7F)<<1)\r
+\r
+/* Bit definitions and macros for MCF_I2C_I2FDR */\r
+#define MCF_I2C_I2FDR_IC(x)    (((x)&0x3F)<<0)\r
+\r
+/* Bit definitions and macros for MCF_I2C_I2CR */\r
+#define MCF_I2C_I2CR_RSTA      (0x04)\r
+#define MCF_I2C_I2CR_TXAK      (0x08)\r
+#define MCF_I2C_I2CR_MTX       (0x10)\r
+#define MCF_I2C_I2CR_MSTA      (0x20)\r
+#define MCF_I2C_I2CR_IIEN      (0x40)\r
+#define MCF_I2C_I2CR_IEN       (0x80)\r
+\r
+/* Bit definitions and macros for MCF_I2C_I2SR */\r
+#define MCF_I2C_I2SR_RXAK      (0x01)\r
+#define MCF_I2C_I2SR_IIF       (0x02)\r
+#define MCF_I2C_I2SR_SRW       (0x04)\r
+#define MCF_I2C_I2SR_IAL       (0x10)\r
+#define MCF_I2C_I2SR_IBB       (0x20)\r
+#define MCF_I2C_I2SR_IAAS      (0x40)\r
+#define MCF_I2C_I2SR_ICF       (0x80)\r
+\r
+/* Bit definitions and macros for MCF_I2C_I2ICR */\r
+#define MCF_I2C_I2ICR_IE       (0x01)\r
+#define MCF_I2C_I2ICR_RE       (0x02)\r
+#define MCF_I2C_I2ICR_TE       (0x04)\r
+#define MCF_I2C_I2ICR_BNBE     (0x08)\r
+\r
+/********************************************************************/\r
+\r
+#endif /* __MCF523X_I2C_H__ */\r
index 7d19e9863186f5a8d95ccbcdba9b04681fe3a850..2e06524f460f115204b2ea31896649569a575a58 100644 (file)
-/*
- * These files are taken from the MCF523X source code example package
- * which is available on the Freescale website. Freescale explicitly 
- * grants the redistribution and modification of these source files.
- * The complete licensing information is available in the file 
- * LICENSE_FREESCALE.TXT.
- *
- * File:       mcf523x_intc0.h
- * Purpose:    Register and bit definitions for the MCF523X
- *
- * Notes:      
- *     
- */
-
-#ifndef __MCF523X_INTC0_H__
-#define __MCF523X_INTC0_H__
-
-/*********************************************************************
-*
-* Interrupt Controller 0 (INTC0)
-*
-*********************************************************************/
-
-/* Register read/write macros */
-#define MCF_INTC0_IPRH         (*(vuint32*)(void*)(&__IPSBAR[0x000C00]))
-#define MCF_INTC0_IPRL         (*(vuint32*)(void*)(&__IPSBAR[0x000C04]))
-#define MCF_INTC0_IMRH         (*(vuint32*)(void*)(&__IPSBAR[0x000C08]))
-#define MCF_INTC0_IMRL         (*(vuint32*)(void*)(&__IPSBAR[0x000C0C]))
-#define MCF_INTC0_INTFRCH      (*(vuint32*)(void*)(&__IPSBAR[0x000C10]))
-#define MCF_INTC0_INTFRCL      (*(vuint32*)(void*)(&__IPSBAR[0x000C14]))
-#define MCF_INTC0_IRLR         (*(vuint8 *)(void*)(&__IPSBAR[0x000C18]))
-#define MCF_INTC0_IACKLPR      (*(vuint8 *)(void*)(&__IPSBAR[0x000C19]))
-#define MCF_INTC0_ICR0         (*(vuint8 *)(void*)(&__IPSBAR[0x000C40]))
-#define MCF_INTC0_ICR1         (*(vuint8 *)(void*)(&__IPSBAR[0x000C41]))
-#define MCF_INTC0_ICR2         (*(vuint8 *)(void*)(&__IPSBAR[0x000C42]))
-#define MCF_INTC0_ICR3         (*(vuint8 *)(void*)(&__IPSBAR[0x000C43]))
-#define MCF_INTC0_ICR4         (*(vuint8 *)(void*)(&__IPSBAR[0x000C44]))
-#define MCF_INTC0_ICR5         (*(vuint8 *)(void*)(&__IPSBAR[0x000C45]))
-#define MCF_INTC0_ICR6         (*(vuint8 *)(void*)(&__IPSBAR[0x000C46]))
-#define MCF_INTC0_ICR7         (*(vuint8 *)(void*)(&__IPSBAR[0x000C47]))
-#define MCF_INTC0_ICR8         (*(vuint8 *)(void*)(&__IPSBAR[0x000C48]))
-#define MCF_INTC0_ICR9         (*(vuint8 *)(void*)(&__IPSBAR[0x000C49]))
-#define MCF_INTC0_ICR10        (*(vuint8 *)(void*)(&__IPSBAR[0x000C4A]))
-#define MCF_INTC0_ICR11        (*(vuint8 *)(void*)(&__IPSBAR[0x000C4B]))
-#define MCF_INTC0_ICR12        (*(vuint8 *)(void*)(&__IPSBAR[0x000C4C]))
-#define MCF_INTC0_ICR13        (*(vuint8 *)(void*)(&__IPSBAR[0x000C4D]))
-#define MCF_INTC0_ICR14        (*(vuint8 *)(void*)(&__IPSBAR[0x000C4E]))
-#define MCF_INTC0_ICR15        (*(vuint8 *)(void*)(&__IPSBAR[0x000C4F]))
-#define MCF_INTC0_ICR16        (*(vuint8 *)(void*)(&__IPSBAR[0x000C50]))
-#define MCF_INTC0_ICR17        (*(vuint8 *)(void*)(&__IPSBAR[0x000C51]))
-#define MCF_INTC0_ICR18        (*(vuint8 *)(void*)(&__IPSBAR[0x000C52]))
-#define MCF_INTC0_ICR19        (*(vuint8 *)(void*)(&__IPSBAR[0x000C53]))
-#define MCF_INTC0_ICR20        (*(vuint8 *)(void*)(&__IPSBAR[0x000C54]))
-#define MCF_INTC0_ICR21        (*(vuint8 *)(void*)(&__IPSBAR[0x000C55]))
-#define MCF_INTC0_ICR22        (*(vuint8 *)(void*)(&__IPSBAR[0x000C56]))
-#define MCF_INTC0_ICR23        (*(vuint8 *)(void*)(&__IPSBAR[0x000C57]))
-#define MCF_INTC0_ICR24        (*(vuint8 *)(void*)(&__IPSBAR[0x000C58]))
-#define MCF_INTC0_ICR25        (*(vuint8 *)(void*)(&__IPSBAR[0x000C59]))
-#define MCF_INTC0_ICR26        (*(vuint8 *)(void*)(&__IPSBAR[0x000C5A]))
-#define MCF_INTC0_ICR27        (*(vuint8 *)(void*)(&__IPSBAR[0x000C5B]))
-#define MCF_INTC0_ICR28        (*(vuint8 *)(void*)(&__IPSBAR[0x000C5C]))
-#define MCF_INTC0_ICR29        (*(vuint8 *)(void*)(&__IPSBAR[0x000C5D]))
-#define MCF_INTC0_ICR30        (*(vuint8 *)(void*)(&__IPSBAR[0x000C5E]))
-#define MCF_INTC0_ICR31        (*(vuint8 *)(void*)(&__IPSBAR[0x000C5F]))
-#define MCF_INTC0_ICR32        (*(vuint8 *)(void*)(&__IPSBAR[0x000C60]))
-#define MCF_INTC0_ICR33        (*(vuint8 *)(void*)(&__IPSBAR[0x000C61]))
-#define MCF_INTC0_ICR34        (*(vuint8 *)(void*)(&__IPSBAR[0x000C62]))
-#define MCF_INTC0_ICR35        (*(vuint8 *)(void*)(&__IPSBAR[0x000C63]))
-#define MCF_INTC0_ICR36        (*(vuint8 *)(void*)(&__IPSBAR[0x000C64]))
-#define MCF_INTC0_ICR37        (*(vuint8 *)(void*)(&__IPSBAR[0x000C65]))
-#define MCF_INTC0_ICR38        (*(vuint8 *)(void*)(&__IPSBAR[0x000C66]))
-#define MCF_INTC0_ICR39        (*(vuint8 *)(void*)(&__IPSBAR[0x000C67]))
-#define MCF_INTC0_ICR40        (*(vuint8 *)(void*)(&__IPSBAR[0x000C68]))
-#define MCF_INTC0_ICR41        (*(vuint8 *)(void*)(&__IPSBAR[0x000C69]))
-#define MCF_INTC0_ICR42        (*(vuint8 *)(void*)(&__IPSBAR[0x000C6A]))
-#define MCF_INTC0_ICR43        (*(vuint8 *)(void*)(&__IPSBAR[0x000C6B]))
-#define MCF_INTC0_ICR44        (*(vuint8 *)(void*)(&__IPSBAR[0x000C6C]))
-#define MCF_INTC0_ICR45        (*(vuint8 *)(void*)(&__IPSBAR[0x000C6D]))
-#define MCF_INTC0_ICR46        (*(vuint8 *)(void*)(&__IPSBAR[0x000C6E]))
-#define MCF_INTC0_ICR47        (*(vuint8 *)(void*)(&__IPSBAR[0x000C6F]))
-#define MCF_INTC0_ICR48        (*(vuint8 *)(void*)(&__IPSBAR[0x000C70]))
-#define MCF_INTC0_ICR49        (*(vuint8 *)(void*)(&__IPSBAR[0x000C71]))
-#define MCF_INTC0_ICR50        (*(vuint8 *)(void*)(&__IPSBAR[0x000C72]))
-#define MCF_INTC0_ICR51        (*(vuint8 *)(void*)(&__IPSBAR[0x000C73]))
-#define MCF_INTC0_ICR52        (*(vuint8 *)(void*)(&__IPSBAR[0x000C74]))
-#define MCF_INTC0_ICR53        (*(vuint8 *)(void*)(&__IPSBAR[0x000C75]))
-#define MCF_INTC0_ICR54        (*(vuint8 *)(void*)(&__IPSBAR[0x000C76]))
-#define MCF_INTC0_ICR55        (*(vuint8 *)(void*)(&__IPSBAR[0x000C77]))
-#define MCF_INTC0_ICR56        (*(vuint8 *)(void*)(&__IPSBAR[0x000C78]))
-#define MCF_INTC0_ICR57        (*(vuint8 *)(void*)(&__IPSBAR[0x000C79]))
-#define MCF_INTC0_ICR58        (*(vuint8 *)(void*)(&__IPSBAR[0x000C7A]))
-#define MCF_INTC0_ICR59        (*(vuint8 *)(void*)(&__IPSBAR[0x000C7B]))
-#define MCF_INTC0_ICR60        (*(vuint8 *)(void*)(&__IPSBAR[0x000C7C]))
-#define MCF_INTC0_ICR61        (*(vuint8 *)(void*)(&__IPSBAR[0x000C7D]))
-#define MCF_INTC0_ICR62        (*(vuint8 *)(void*)(&__IPSBAR[0x000C7E]))
-#define MCF_INTC0_ICR63        (*(vuint8 *)(void*)(&__IPSBAR[0x000C7F]))
-#define MCF_INTC0_ICRn(x)      (*(vuint8 *)(void*)(&__IPSBAR[0x000C40+((x)*0x001)]))
-#define MCF_INTC0_SWIACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000CE0]))
-#define MCF_INTC0_L1IACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000CE4]))
-#define MCF_INTC0_L2IACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000CE8]))
-#define MCF_INTC0_L3IACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000CEC]))
-#define MCF_INTC0_L4IACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000CF0]))
-#define MCF_INTC0_L5IACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000CF4]))
-#define MCF_INTC0_L6IACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000CF8]))
-#define MCF_INTC0_L7IACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000CFC]))
-#define MCF_INTC0_LnIACK(x)    (*(vuint8 *)(void*)(&__IPSBAR[0x000CE4+((x)*0x004)]))
-
-/* Bit definitions and macros for MCF_INTC0_IPRH */
-#define MCF_INTC0_IPRH_INT32          (0x00000001)
-#define MCF_INTC0_IPRH_INT33          (0x00000002)
-#define MCF_INTC0_IPRH_INT34          (0x00000004)
-#define MCF_INTC0_IPRH_INT35          (0x00000008)
-#define MCF_INTC0_IPRH_INT36          (0x00000010)
-#define MCF_INTC0_IPRH_INT37          (0x00000020)
-#define MCF_INTC0_IPRH_INT38          (0x00000040)
-#define MCF_INTC0_IPRH_INT39          (0x00000080)
-#define MCF_INTC0_IPRH_INT40          (0x00000100)
-#define MCF_INTC0_IPRH_INT41          (0x00000200)
-#define MCF_INTC0_IPRH_INT42          (0x00000400)
-#define MCF_INTC0_IPRH_INT43          (0x00000800)
-#define MCF_INTC0_IPRH_INT44          (0x00001000)
-#define MCF_INTC0_IPRH_INT45          (0x00002000)
-#define MCF_INTC0_IPRH_INT46          (0x00004000)
-#define MCF_INTC0_IPRH_INT47          (0x00008000)
-#define MCF_INTC0_IPRH_INT48          (0x00010000)
-#define MCF_INTC0_IPRH_INT49          (0x00020000)
-#define MCF_INTC0_IPRH_INT50          (0x00040000)
-#define MCF_INTC0_IPRH_INT51          (0x00080000)
-#define MCF_INTC0_IPRH_INT52          (0x00100000)
-#define MCF_INTC0_IPRH_INT53          (0x00200000)
-#define MCF_INTC0_IPRH_INT54          (0x00400000)
-#define MCF_INTC0_IPRH_INT55          (0x00800000)
-#define MCF_INTC0_IPRH_INT56          (0x01000000)
-#define MCF_INTC0_IPRH_INT57          (0x02000000)
-#define MCF_INTC0_IPRH_INT58          (0x04000000)
-#define MCF_INTC0_IPRH_INT59          (0x08000000)
-#define MCF_INTC0_IPRH_INT60          (0x10000000)
-#define MCF_INTC0_IPRH_INT61          (0x20000000)
-#define MCF_INTC0_IPRH_INT62          (0x40000000)
-#define MCF_INTC0_IPRH_INT63          (0x80000000)
-
-/* Bit definitions and macros for MCF_INTC0_IPRL */
-#define MCF_INTC0_IPRL_INT1           (0x00000002)
-#define MCF_INTC0_IPRL_INT2           (0x00000004)
-#define MCF_INTC0_IPRL_INT3           (0x00000008)
-#define MCF_INTC0_IPRL_INT4           (0x00000010)
-#define MCF_INTC0_IPRL_INT5           (0x00000020)
-#define MCF_INTC0_IPRL_INT6           (0x00000040)
-#define MCF_INTC0_IPRL_INT7           (0x00000080)
-#define MCF_INTC0_IPRL_INT8           (0x00000100)
-#define MCF_INTC0_IPRL_INT9           (0x00000200)
-#define MCF_INTC0_IPRL_INT10          (0x00000400)
-#define MCF_INTC0_IPRL_INT11          (0x00000800)
-#define MCF_INTC0_IPRL_INT12          (0x00001000)
-#define MCF_INTC0_IPRL_INT13          (0x00002000)
-#define MCF_INTC0_IPRL_INT14          (0x00004000)
-#define MCF_INTC0_IPRL_INT15          (0x00008000)
-#define MCF_INTC0_IPRL_INT16          (0x00010000)
-#define MCF_INTC0_IPRL_INT17          (0x00020000)
-#define MCF_INTC0_IPRL_INT18          (0x00040000)
-#define MCF_INTC0_IPRL_INT19          (0x00080000)
-#define MCF_INTC0_IPRL_INT20          (0x00100000)
-#define MCF_INTC0_IPRL_INT21          (0x00200000)
-#define MCF_INTC0_IPRL_INT22          (0x00400000)
-#define MCF_INTC0_IPRL_INT23          (0x00800000)
-#define MCF_INTC0_IPRL_INT24          (0x01000000)
-#define MCF_INTC0_IPRL_INT25          (0x02000000)
-#define MCF_INTC0_IPRL_INT26          (0x04000000)
-#define MCF_INTC0_IPRL_INT27          (0x08000000)
-#define MCF_INTC0_IPRL_INT28          (0x10000000)
-#define MCF_INTC0_IPRL_INT29          (0x20000000)
-#define MCF_INTC0_IPRL_INT30          (0x40000000)
-#define MCF_INTC0_IPRL_INT31          (0x80000000)
-
-/* Bit definitions and macros for MCF_INTC0_IMRH */
-#define MCF_INTC0_IMRH_INT_MASK32     (0x00000001)
-#define MCF_INTC0_IMRH_INT_MASK33     (0x00000002)
-#define MCF_INTC0_IMRH_INT_MASK34     (0x00000004)
-#define MCF_INTC0_IMRH_INT_MASK35     (0x00000008)
-#define MCF_INTC0_IMRH_INT_MASK36     (0x00000010)
-#define MCF_INTC0_IMRH_INT_MASK37     (0x00000020)
-#define MCF_INTC0_IMRH_INT_MASK38     (0x00000040)
-#define MCF_INTC0_IMRH_INT_MASK39     (0x00000080)
-#define MCF_INTC0_IMRH_INT_MASK40     (0x00000100)
-#define MCF_INTC0_IMRH_INT_MASK41     (0x00000200)
-#define MCF_INTC0_IMRH_INT_MASK42     (0x00000400)
-#define MCF_INTC0_IMRH_INT_MASK43     (0x00000800)
-#define MCF_INTC0_IMRH_INT_MASK44     (0x00001000)
-#define MCF_INTC0_IMRH_INT_MASK45     (0x00002000)
-#define MCF_INTC0_IMRH_INT_MASK46     (0x00004000)
-#define MCF_INTC0_IMRH_INT_MASK47     (0x00008000)
-#define MCF_INTC0_IMRH_INT_MASK48     (0x00010000)
-#define MCF_INTC0_IMRH_INT_MASK49     (0x00020000)
-#define MCF_INTC0_IMRH_INT_MASK50     (0x00040000)
-#define MCF_INTC0_IMRH_INT_MASK51     (0x00080000)
-#define MCF_INTC0_IMRH_INT_MASK52     (0x00100000)
-#define MCF_INTC0_IMRH_INT_MASK53     (0x00200000)
-#define MCF_INTC0_IMRH_INT_MASK54     (0x00400000)
-#define MCF_INTC0_IMRH_INT_MASK55     (0x00800000)
-#define MCF_INTC0_IMRH_INT_MASK56     (0x01000000)
-#define MCF_INTC0_IMRH_INT_MASK57     (0x02000000)
-#define MCF_INTC0_IMRH_INT_MASK58     (0x04000000)
-#define MCF_INTC0_IMRH_INT_MASK59     (0x08000000)
-#define MCF_INTC0_IMRH_INT_MASK60     (0x10000000)
-#define MCF_INTC0_IMRH_INT_MASK61     (0x20000000)
-#define MCF_INTC0_IMRH_INT_MASK62     (0x40000000)
-#define MCF_INTC0_IMRH_INT_MASK63     (0x80000000)
-
-/* Bit definitions and macros for MCF_INTC0_IMRL */
-#define MCF_INTC0_IMRL_MASKALL        (0x00000001)
-#define MCF_INTC0_IMRL_INT_MASK1      (0x00000002)
-#define MCF_INTC0_IMRL_INT_MASK2      (0x00000004)
-#define MCF_INTC0_IMRL_INT_MASK3      (0x00000008)
-#define MCF_INTC0_IMRL_INT_MASK4      (0x00000010)
-#define MCF_INTC0_IMRL_INT_MASK5      (0x00000020)
-#define MCF_INTC0_IMRL_INT_MASK6      (0x00000040)
-#define MCF_INTC0_IMRL_INT_MASK7      (0x00000080)
-#define MCF_INTC0_IMRL_INT_MASK8      (0x00000100)
-#define MCF_INTC0_IMRL_INT_MASK9      (0x00000200)
-#define MCF_INTC0_IMRL_INT_MASK10     (0x00000400)
-#define MCF_INTC0_IMRL_INT_MASK11     (0x00000800)
-#define MCF_INTC0_IMRL_INT_MASK12     (0x00001000)
-#define MCF_INTC0_IMRL_INT_MASK13     (0x00002000)
-#define MCF_INTC0_IMRL_INT_MASK14     (0x00004000)
-#define MCF_INTC0_IMRL_INT_MASK15     (0x00008000)
-#define MCF_INTC0_IMRL_INT_MASK16     (0x00010000)
-#define MCF_INTC0_IMRL_INT_MASK17     (0x00020000)
-#define MCF_INTC0_IMRL_INT_MASK18     (0x00040000)
-#define MCF_INTC0_IMRL_INT_MASK19     (0x00080000)
-#define MCF_INTC0_IMRL_INT_MASK20     (0x00100000)
-#define MCF_INTC0_IMRL_INT_MASK21     (0x00200000)
-#define MCF_INTC0_IMRL_INT_MASK22     (0x00400000)
-#define MCF_INTC0_IMRL_INT_MASK23     (0x00800000)
-#define MCF_INTC0_IMRL_INT_MASK24     (0x01000000)
-#define MCF_INTC0_IMRL_INT_MASK25     (0x02000000)
-#define MCF_INTC0_IMRL_INT_MASK26     (0x04000000)
-#define MCF_INTC0_IMRL_INT_MASK27     (0x08000000)
-#define MCF_INTC0_IMRL_INT_MASK28     (0x10000000)
-#define MCF_INTC0_IMRL_INT_MASK29     (0x20000000)
-#define MCF_INTC0_IMRL_INT_MASK30     (0x40000000)
-#define MCF_INTC0_IMRL_INT_MASK31     (0x80000000)
-
-/* Bit definitions and macros for MCF_INTC0_INTFRCH */
-#define MCF_INTC0_INTFRCH_INTFRC32    (0x00000001)
-#define MCF_INTC0_INTFRCH_INTFRC33    (0x00000002)
-#define MCF_INTC0_INTFRCH_INTFRC34    (0x00000004)
-#define MCF_INTC0_INTFRCH_INTFRC35    (0x00000008)
-#define MCF_INTC0_INTFRCH_INTFRC36    (0x00000010)
-#define MCF_INTC0_INTFRCH_INTFRC37    (0x00000020)
-#define MCF_INTC0_INTFRCH_INTFRC38    (0x00000040)
-#define MCF_INTC0_INTFRCH_INTFRC39    (0x00000080)
-#define MCF_INTC0_INTFRCH_INTFRC40    (0x00000100)
-#define MCF_INTC0_INTFRCH_INTFRC41    (0x00000200)
-#define MCF_INTC0_INTFRCH_INTFRC42    (0x00000400)
-#define MCF_INTC0_INTFRCH_INTFRC43    (0x00000800)
-#define MCF_INTC0_INTFRCH_INTFRC44    (0x00001000)
-#define MCF_INTC0_INTFRCH_INTFRC45    (0x00002000)
-#define MCF_INTC0_INTFRCH_INTFRC46    (0x00004000)
-#define MCF_INTC0_INTFRCH_INTFRC47    (0x00008000)
-#define MCF_INTC0_INTFRCH_INTFRC48    (0x00010000)
-#define MCF_INTC0_INTFRCH_INTFRC49    (0x00020000)
-#define MCF_INTC0_INTFRCH_INTFRC50    (0x00040000)
-#define MCF_INTC0_INTFRCH_INTFRC51    (0x00080000)
-#define MCF_INTC0_INTFRCH_INTFRC52    (0x00100000)
-#define MCF_INTC0_INTFRCH_INTFRC53    (0x00200000)
-#define MCF_INTC0_INTFRCH_INTFRC54    (0x00400000)
-#define MCF_INTC0_INTFRCH_INTFRC55    (0x00800000)
-#define MCF_INTC0_INTFRCH_INTFRC56    (0x01000000)
-#define MCF_INTC0_INTFRCH_INTFRC57    (0x02000000)
-#define MCF_INTC0_INTFRCH_INTFRC58    (0x04000000)
-#define MCF_INTC0_INTFRCH_INTFRC59    (0x08000000)
-#define MCF_INTC0_INTFRCH_INTFRC60    (0x10000000)
-#define MCF_INTC0_INTFRCH_INTFRC61    (0x20000000)
-#define MCF_INTC0_INTFRCH_INTFRC62    (0x40000000)
-#define MCF_INTC0_INTFRCH_INTFRC63    (0x80000000)
-
-/* Bit definitions and macros for MCF_INTC0_INTFRCL */
-#define MCF_INTC0_INTFRCL_INTFRC1     (0x00000002)
-#define MCF_INTC0_INTFRCL_INTFRC2     (0x00000004)
-#define MCF_INTC0_INTFRCL_INTFRC3     (0x00000008)
-#define MCF_INTC0_INTFRCL_INTFRC4     (0x00000010)
-#define MCF_INTC0_INTFRCL_INTFRC5     (0x00000020)
-#define MCF_INTC0_INTFRCL_INT6        (0x00000040)
-#define MCF_INTC0_INTFRCL_INT7        (0x00000080)
-#define MCF_INTC0_INTFRCL_INT8        (0x00000100)
-#define MCF_INTC0_INTFRCL_INT9        (0x00000200)
-#define MCF_INTC0_INTFRCL_INT10       (0x00000400)
-#define MCF_INTC0_INTFRCL_INTFRC11    (0x00000800)
-#define MCF_INTC0_INTFRCL_INTFRC12    (0x00001000)
-#define MCF_INTC0_INTFRCL_INTFRC13    (0x00002000)
-#define MCF_INTC0_INTFRCL_INTFRC14    (0x00004000)
-#define MCF_INTC0_INTFRCL_INT15       (0x00008000)
-#define MCF_INTC0_INTFRCL_INTFRC16    (0x00010000)
-#define MCF_INTC0_INTFRCL_INTFRC17    (0x00020000)
-#define MCF_INTC0_INTFRCL_INTFRC18    (0x00040000)
-#define MCF_INTC0_INTFRCL_INTFRC19    (0x00080000)
-#define MCF_INTC0_INTFRCL_INTFRC20    (0x00100000)
-#define MCF_INTC0_INTFRCL_INTFRC21    (0x00200000)
-#define MCF_INTC0_INTFRCL_INTFRC22    (0x00400000)
-#define MCF_INTC0_INTFRCL_INTFRC23    (0x00800000)
-#define MCF_INTC0_INTFRCL_INTFRC24    (0x01000000)
-#define MCF_INTC0_INTFRCL_INTFRC25    (0x02000000)
-#define MCF_INTC0_INTFRCL_INTFRC26    (0x04000000)
-#define MCF_INTC0_INTFRCL_INTFRC27    (0x08000000)
-#define MCF_INTC0_INTFRCL_INTFRC28    (0x10000000)
-#define MCF_INTC0_INTFRCL_INTFRC29    (0x20000000)
-#define MCF_INTC0_INTFRCL_INTFRC30    (0x40000000)
-#define MCF_INTC0_INTFRCL_INTFRC31    (0x80000000)
-
-/* Bit definitions and macros for MCF_INTC0_IRLR */
-#define MCF_INTC0_IRLR_IRQ(x)         (((x)&0x7F)<<1)
-
-/* Bit definitions and macros for MCF_INTC0_IACKLPR */
-#define MCF_INTC0_IACKLPR_PRI(x)      (((x)&0x0F)<<0)
-#define MCF_INTC0_IACKLPR_LEVEL(x)    (((x)&0x07)<<4)
-
-/* Bit definitions and macros for MCF_INTC0_ICRn */
-#define MCF_INTC0_ICRn_IP(x)          (((x)&0x07)<<0)
-#define MCF_INTC0_ICRn_IL(x)          (((x)&0x07)<<3)
-
-/********************************************************************/
-
-#endif /* __MCF523X_INTC0_H__ */
+/*\r
+ * These files are taken from the MCF523X source code example package\r
+ * which is available on the Freescale website. Freescale explicitly \r
+ * grants the redistribution and modification of these source files.\r
+ * The complete licensing information is available in the file \r
+ * LICENSE_FREESCALE.TXT.\r
+ *\r
+ * File:       mcf523x_intc0.h\r
+ * Purpose:    Register and bit definitions for the MCF523X\r
+ *\r
+ * Notes:      \r
+ *     \r
+ */\r
+\r
+#ifndef __MCF523X_INTC0_H__\r
+#define __MCF523X_INTC0_H__\r
+\r
+/*********************************************************************\r
+*\r
+* Interrupt Controller 0 (INTC0)\r
+*\r
+*********************************************************************/\r
+\r
+/* Register read/write macros */\r
+#define MCF_INTC0_IPRH         (*(vuint32*)(void*)(&__IPSBAR[0x000C00]))\r
+#define MCF_INTC0_IPRL         (*(vuint32*)(void*)(&__IPSBAR[0x000C04]))\r
+#define MCF_INTC0_IMRH         (*(vuint32*)(void*)(&__IPSBAR[0x000C08]))\r
+#define MCF_INTC0_IMRL         (*(vuint32*)(void*)(&__IPSBAR[0x000C0C]))\r
+#define MCF_INTC0_INTFRCH      (*(vuint32*)(void*)(&__IPSBAR[0x000C10]))\r
+#define MCF_INTC0_INTFRCL      (*(vuint32*)(void*)(&__IPSBAR[0x000C14]))\r
+#define MCF_INTC0_IRLR         (*(vuint8 *)(void*)(&__IPSBAR[0x000C18]))\r
+#define MCF_INTC0_IACKLPR      (*(vuint8 *)(void*)(&__IPSBAR[0x000C19]))\r
+#define MCF_INTC0_ICR0         (*(vuint8 *)(void*)(&__IPSBAR[0x000C40]))\r
+#define MCF_INTC0_ICR1         (*(vuint8 *)(void*)(&__IPSBAR[0x000C41]))\r
+#define MCF_INTC0_ICR2         (*(vuint8 *)(void*)(&__IPSBAR[0x000C42]))\r
+#define MCF_INTC0_ICR3         (*(vuint8 *)(void*)(&__IPSBAR[0x000C43]))\r
+#define MCF_INTC0_ICR4         (*(vuint8 *)(void*)(&__IPSBAR[0x000C44]))\r
+#define MCF_INTC0_ICR5         (*(vuint8 *)(void*)(&__IPSBAR[0x000C45]))\r
+#define MCF_INTC0_ICR6         (*(vuint8 *)(void*)(&__IPSBAR[0x000C46]))\r
+#define MCF_INTC0_ICR7         (*(vuint8 *)(void*)(&__IPSBAR[0x000C47]))\r
+#define MCF_INTC0_ICR8         (*(vuint8 *)(void*)(&__IPSBAR[0x000C48]))\r
+#define MCF_INTC0_ICR9         (*(vuint8 *)(void*)(&__IPSBAR[0x000C49]))\r
+#define MCF_INTC0_ICR10        (*(vuint8 *)(void*)(&__IPSBAR[0x000C4A]))\r
+#define MCF_INTC0_ICR11        (*(vuint8 *)(void*)(&__IPSBAR[0x000C4B]))\r
+#define MCF_INTC0_ICR12        (*(vuint8 *)(void*)(&__IPSBAR[0x000C4C]))\r
+#define MCF_INTC0_ICR13        (*(vuint8 *)(void*)(&__IPSBAR[0x000C4D]))\r
+#define MCF_INTC0_ICR14        (*(vuint8 *)(void*)(&__IPSBAR[0x000C4E]))\r
+#define MCF_INTC0_ICR15        (*(vuint8 *)(void*)(&__IPSBAR[0x000C4F]))\r
+#define MCF_INTC0_ICR16        (*(vuint8 *)(void*)(&__IPSBAR[0x000C50]))\r
+#define MCF_INTC0_ICR17        (*(vuint8 *)(void*)(&__IPSBAR[0x000C51]))\r
+#define MCF_INTC0_ICR18        (*(vuint8 *)(void*)(&__IPSBAR[0x000C52]))\r
+#define MCF_INTC0_ICR19        (*(vuint8 *)(void*)(&__IPSBAR[0x000C53]))\r
+#define MCF_INTC0_ICR20        (*(vuint8 *)(void*)(&__IPSBAR[0x000C54]))\r
+#define MCF_INTC0_ICR21        (*(vuint8 *)(void*)(&__IPSBAR[0x000C55]))\r
+#define MCF_INTC0_ICR22        (*(vuint8 *)(void*)(&__IPSBAR[0x000C56]))\r
+#define MCF_INTC0_ICR23        (*(vuint8 *)(void*)(&__IPSBAR[0x000C57]))\r
+#define MCF_INTC0_ICR24        (*(vuint8 *)(void*)(&__IPSBAR[0x000C58]))\r
+#define MCF_INTC0_ICR25        (*(vuint8 *)(void*)(&__IPSBAR[0x000C59]))\r
+#define MCF_INTC0_ICR26        (*(vuint8 *)(void*)(&__IPSBAR[0x000C5A]))\r
+#define MCF_INTC0_ICR27        (*(vuint8 *)(void*)(&__IPSBAR[0x000C5B]))\r
+#define MCF_INTC0_ICR28        (*(vuint8 *)(void*)(&__IPSBAR[0x000C5C]))\r
+#define MCF_INTC0_ICR29        (*(vuint8 *)(void*)(&__IPSBAR[0x000C5D]))\r
+#define MCF_INTC0_ICR30        (*(vuint8 *)(void*)(&__IPSBAR[0x000C5E]))\r
+#define MCF_INTC0_ICR31        (*(vuint8 *)(void*)(&__IPSBAR[0x000C5F]))\r
+#define MCF_INTC0_ICR32        (*(vuint8 *)(void*)(&__IPSBAR[0x000C60]))\r
+#define MCF_INTC0_ICR33        (*(vuint8 *)(void*)(&__IPSBAR[0x000C61]))\r
+#define MCF_INTC0_ICR34        (*(vuint8 *)(void*)(&__IPSBAR[0x000C62]))\r
+#define MCF_INTC0_ICR35        (*(vuint8 *)(void*)(&__IPSBAR[0x000C63]))\r
+#define MCF_INTC0_ICR36        (*(vuint8 *)(void*)(&__IPSBAR[0x000C64]))\r
+#define MCF_INTC0_ICR37        (*(vuint8 *)(void*)(&__IPSBAR[0x000C65]))\r
+#define MCF_INTC0_ICR38        (*(vuint8 *)(void*)(&__IPSBAR[0x000C66]))\r
+#define MCF_INTC0_ICR39        (*(vuint8 *)(void*)(&__IPSBAR[0x000C67]))\r
+#define MCF_INTC0_ICR40        (*(vuint8 *)(void*)(&__IPSBAR[0x000C68]))\r
+#define MCF_INTC0_ICR41        (*(vuint8 *)(void*)(&__IPSBAR[0x000C69]))\r
+#define MCF_INTC0_ICR42        (*(vuint8 *)(void*)(&__IPSBAR[0x000C6A]))\r
+#define MCF_INTC0_ICR43        (*(vuint8 *)(void*)(&__IPSBAR[0x000C6B]))\r
+#define MCF_INTC0_ICR44        (*(vuint8 *)(void*)(&__IPSBAR[0x000C6C]))\r
+#define MCF_INTC0_ICR45        (*(vuint8 *)(void*)(&__IPSBAR[0x000C6D]))\r
+#define MCF_INTC0_ICR46        (*(vuint8 *)(void*)(&__IPSBAR[0x000C6E]))\r
+#define MCF_INTC0_ICR47        (*(vuint8 *)(void*)(&__IPSBAR[0x000C6F]))\r
+#define MCF_INTC0_ICR48        (*(vuint8 *)(void*)(&__IPSBAR[0x000C70]))\r
+#define MCF_INTC0_ICR49        (*(vuint8 *)(void*)(&__IPSBAR[0x000C71]))\r
+#define MCF_INTC0_ICR50        (*(vuint8 *)(void*)(&__IPSBAR[0x000C72]))\r
+#define MCF_INTC0_ICR51        (*(vuint8 *)(void*)(&__IPSBAR[0x000C73]))\r
+#define MCF_INTC0_ICR52        (*(vuint8 *)(void*)(&__IPSBAR[0x000C74]))\r
+#define MCF_INTC0_ICR53        (*(vuint8 *)(void*)(&__IPSBAR[0x000C75]))\r
+#define MCF_INTC0_ICR54        (*(vuint8 *)(void*)(&__IPSBAR[0x000C76]))\r
+#define MCF_INTC0_ICR55        (*(vuint8 *)(void*)(&__IPSBAR[0x000C77]))\r
+#define MCF_INTC0_ICR56        (*(vuint8 *)(void*)(&__IPSBAR[0x000C78]))\r
+#define MCF_INTC0_ICR57        (*(vuint8 *)(void*)(&__IPSBAR[0x000C79]))\r
+#define MCF_INTC0_ICR58        (*(vuint8 *)(void*)(&__IPSBAR[0x000C7A]))\r
+#define MCF_INTC0_ICR59        (*(vuint8 *)(void*)(&__IPSBAR[0x000C7B]))\r
+#define MCF_INTC0_ICR60        (*(vuint8 *)(void*)(&__IPSBAR[0x000C7C]))\r
+#define MCF_INTC0_ICR61        (*(vuint8 *)(void*)(&__IPSBAR[0x000C7D]))\r
+#define MCF_INTC0_ICR62        (*(vuint8 *)(void*)(&__IPSBAR[0x000C7E]))\r
+#define MCF_INTC0_ICR63        (*(vuint8 *)(void*)(&__IPSBAR[0x000C7F]))\r
+#define MCF_INTC0_ICRn(x)      (*(vuint8 *)(void*)(&__IPSBAR[0x000C40+((x)*0x001)]))\r
+#define MCF_INTC0_SWIACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000CE0]))\r
+#define MCF_INTC0_L1IACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000CE4]))\r
+#define MCF_INTC0_L2IACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000CE8]))\r
+#define MCF_INTC0_L3IACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000CEC]))\r
+#define MCF_INTC0_L4IACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000CF0]))\r
+#define MCF_INTC0_L5IACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000CF4]))\r
+#define MCF_INTC0_L6IACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000CF8]))\r
+#define MCF_INTC0_L7IACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000CFC]))\r
+#define MCF_INTC0_LnIACK(x)    (*(vuint8 *)(void*)(&__IPSBAR[0x000CE4+((x)*0x004)]))\r
+\r
+/* Bit definitions and macros for MCF_INTC0_IPRH */\r
+#define MCF_INTC0_IPRH_INT32          (0x00000001)\r
+#define MCF_INTC0_IPRH_INT33          (0x00000002)\r
+#define MCF_INTC0_IPRH_INT34          (0x00000004)\r
+#define MCF_INTC0_IPRH_INT35          (0x00000008)\r
+#define MCF_INTC0_IPRH_INT36          (0x00000010)\r
+#define MCF_INTC0_IPRH_INT37          (0x00000020)\r
+#define MCF_INTC0_IPRH_INT38          (0x00000040)\r
+#define MCF_INTC0_IPRH_INT39          (0x00000080)\r
+#define MCF_INTC0_IPRH_INT40          (0x00000100)\r
+#define MCF_INTC0_IPRH_INT41          (0x00000200)\r
+#define MCF_INTC0_IPRH_INT42          (0x00000400)\r
+#define MCF_INTC0_IPRH_INT43          (0x00000800)\r
+#define MCF_INTC0_IPRH_INT44          (0x00001000)\r
+#define MCF_INTC0_IPRH_INT45          (0x00002000)\r
+#define MCF_INTC0_IPRH_INT46          (0x00004000)\r
+#define MCF_INTC0_IPRH_INT47          (0x00008000)\r
+#define MCF_INTC0_IPRH_INT48          (0x00010000)\r
+#define MCF_INTC0_IPRH_INT49          (0x00020000)\r
+#define MCF_INTC0_IPRH_INT50          (0x00040000)\r
+#define MCF_INTC0_IPRH_INT51          (0x00080000)\r
+#define MCF_INTC0_IPRH_INT52          (0x00100000)\r
+#define MCF_INTC0_IPRH_INT53          (0x00200000)\r
+#define MCF_INTC0_IPRH_INT54          (0x00400000)\r
+#define MCF_INTC0_IPRH_INT55          (0x00800000)\r
+#define MCF_INTC0_IPRH_INT56          (0x01000000)\r
+#define MCF_INTC0_IPRH_INT57          (0x02000000)\r
+#define MCF_INTC0_IPRH_INT58          (0x04000000)\r
+#define MCF_INTC0_IPRH_INT59          (0x08000000)\r
+#define MCF_INTC0_IPRH_INT60          (0x10000000)\r
+#define MCF_INTC0_IPRH_INT61          (0x20000000)\r
+#define MCF_INTC0_IPRH_INT62          (0x40000000)\r
+#define MCF_INTC0_IPRH_INT63          (0x80000000)\r
+\r
+/* Bit definitions and macros for MCF_INTC0_IPRL */\r
+#define MCF_INTC0_IPRL_INT1           (0x00000002)\r
+#define MCF_INTC0_IPRL_INT2           (0x00000004)\r
+#define MCF_INTC0_IPRL_INT3           (0x00000008)\r
+#define MCF_INTC0_IPRL_INT4           (0x00000010)\r
+#define MCF_INTC0_IPRL_INT5           (0x00000020)\r
+#define MCF_INTC0_IPRL_INT6           (0x00000040)\r
+#define MCF_INTC0_IPRL_INT7           (0x00000080)\r
+#define MCF_INTC0_IPRL_INT8           (0x00000100)\r
+#define MCF_INTC0_IPRL_INT9           (0x00000200)\r
+#define MCF_INTC0_IPRL_INT10          (0x00000400)\r
+#define MCF_INTC0_IPRL_INT11          (0x00000800)\r
+#define MCF_INTC0_IPRL_INT12          (0x00001000)\r
+#define MCF_INTC0_IPRL_INT13          (0x00002000)\r
+#define MCF_INTC0_IPRL_INT14          (0x00004000)\r
+#define MCF_INTC0_IPRL_INT15          (0x00008000)\r
+#define MCF_INTC0_IPRL_INT16          (0x00010000)\r
+#define MCF_INTC0_IPRL_INT17          (0x00020000)\r
+#define MCF_INTC0_IPRL_INT18          (0x00040000)\r
+#define MCF_INTC0_IPRL_INT19          (0x00080000)\r
+#define MCF_INTC0_IPRL_INT20          (0x00100000)\r
+#define MCF_INTC0_IPRL_INT21          (0x00200000)\r
+#define MCF_INTC0_IPRL_INT22          (0x00400000)\r
+#define MCF_INTC0_IPRL_INT23          (0x00800000)\r
+#define MCF_INTC0_IPRL_INT24          (0x01000000)\r
+#define MCF_INTC0_IPRL_INT25          (0x02000000)\r
+#define MCF_INTC0_IPRL_INT26          (0x04000000)\r
+#define MCF_INTC0_IPRL_INT27          (0x08000000)\r
+#define MCF_INTC0_IPRL_INT28          (0x10000000)\r
+#define MCF_INTC0_IPRL_INT29          (0x20000000)\r
+#define MCF_INTC0_IPRL_INT30          (0x40000000)\r
+#define MCF_INTC0_IPRL_INT31          (0x80000000)\r
+\r
+/* Bit definitions and macros for MCF_INTC0_IMRH */\r
+#define MCF_INTC0_IMRH_INT_MASK32     (0x00000001)\r
+#define MCF_INTC0_IMRH_INT_MASK33     (0x00000002)\r
+#define MCF_INTC0_IMRH_INT_MASK34     (0x00000004)\r
+#define MCF_INTC0_IMRH_INT_MASK35     (0x00000008)\r
+#define MCF_INTC0_IMRH_INT_MASK36     (0x00000010)\r
+#define MCF_INTC0_IMRH_INT_MASK37     (0x00000020)\r
+#define MCF_INTC0_IMRH_INT_MASK38     (0x00000040)\r
+#define MCF_INTC0_IMRH_INT_MASK39     (0x00000080)\r
+#define MCF_INTC0_IMRH_INT_MASK40     (0x00000100)\r
+#define MCF_INTC0_IMRH_INT_MASK41     (0x00000200)\r
+#define MCF_INTC0_IMRH_INT_MASK42     (0x00000400)\r
+#define MCF_INTC0_IMRH_INT_MASK43     (0x00000800)\r
+#define MCF_INTC0_IMRH_INT_MASK44     (0x00001000)\r
+#define MCF_INTC0_IMRH_INT_MASK45     (0x00002000)\r
+#define MCF_INTC0_IMRH_INT_MASK46     (0x00004000)\r
+#define MCF_INTC0_IMRH_INT_MASK47     (0x00008000)\r
+#define MCF_INTC0_IMRH_INT_MASK48     (0x00010000)\r
+#define MCF_INTC0_IMRH_INT_MASK49     (0x00020000)\r
+#define MCF_INTC0_IMRH_INT_MASK50     (0x00040000)\r
+#define MCF_INTC0_IMRH_INT_MASK51     (0x00080000)\r
+#define MCF_INTC0_IMRH_INT_MASK52     (0x00100000)\r
+#define MCF_INTC0_IMRH_INT_MASK53     (0x00200000)\r
+#define MCF_INTC0_IMRH_INT_MASK54     (0x00400000)\r
+#define MCF_INTC0_IMRH_INT_MASK55     (0x00800000)\r
+#define MCF_INTC0_IMRH_INT_MASK56     (0x01000000)\r
+#define MCF_INTC0_IMRH_INT_MASK57     (0x02000000)\r
+#define MCF_INTC0_IMRH_INT_MASK58     (0x04000000)\r
+#define MCF_INTC0_IMRH_INT_MASK59     (0x08000000)\r
+#define MCF_INTC0_IMRH_INT_MASK60     (0x10000000)\r
+#define MCF_INTC0_IMRH_INT_MASK61     (0x20000000)\r
+#define MCF_INTC0_IMRH_INT_MASK62     (0x40000000)\r
+#define MCF_INTC0_IMRH_INT_MASK63     (0x80000000)\r
+\r
+/* Bit definitions and macros for MCF_INTC0_IMRL */\r
+#define MCF_INTC0_IMRL_MASKALL        (0x00000001)\r
+#define MCF_INTC0_IMRL_INT_MASK1      (0x00000002)\r
+#define MCF_INTC0_IMRL_INT_MASK2      (0x00000004)\r
+#define MCF_INTC0_IMRL_INT_MASK3      (0x00000008)\r
+#define MCF_INTC0_IMRL_INT_MASK4      (0x00000010)\r
+#define MCF_INTC0_IMRL_INT_MASK5      (0x00000020)\r
+#define MCF_INTC0_IMRL_INT_MASK6      (0x00000040)\r
+#define MCF_INTC0_IMRL_INT_MASK7      (0x00000080)\r
+#define MCF_INTC0_IMRL_INT_MASK8      (0x00000100)\r
+#define MCF_INTC0_IMRL_INT_MASK9      (0x00000200)\r
+#define MCF_INTC0_IMRL_INT_MASK10     (0x00000400)\r
+#define MCF_INTC0_IMRL_INT_MASK11     (0x00000800)\r
+#define MCF_INTC0_IMRL_INT_MASK12     (0x00001000)\r
+#define MCF_INTC0_IMRL_INT_MASK13     (0x00002000)\r
+#define MCF_INTC0_IMRL_INT_MASK14     (0x00004000)\r
+#define MCF_INTC0_IMRL_INT_MASK15     (0x00008000)\r
+#define MCF_INTC0_IMRL_INT_MASK16     (0x00010000)\r
+#define MCF_INTC0_IMRL_INT_MASK17     (0x00020000)\r
+#define MCF_INTC0_IMRL_INT_MASK18     (0x00040000)\r
+#define MCF_INTC0_IMRL_INT_MASK19     (0x00080000)\r
+#define MCF_INTC0_IMRL_INT_MASK20     (0x00100000)\r
+#define MCF_INTC0_IMRL_INT_MASK21     (0x00200000)\r
+#define MCF_INTC0_IMRL_INT_MASK22     (0x00400000)\r
+#define MCF_INTC0_IMRL_INT_MASK23     (0x00800000)\r
+#define MCF_INTC0_IMRL_INT_MASK24     (0x01000000)\r
+#define MCF_INTC0_IMRL_INT_MASK25     (0x02000000)\r
+#define MCF_INTC0_IMRL_INT_MASK26     (0x04000000)\r
+#define MCF_INTC0_IMRL_INT_MASK27     (0x08000000)\r
+#define MCF_INTC0_IMRL_INT_MASK28     (0x10000000)\r
+#define MCF_INTC0_IMRL_INT_MASK29     (0x20000000)\r
+#define MCF_INTC0_IMRL_INT_MASK30     (0x40000000)\r
+#define MCF_INTC0_IMRL_INT_MASK31     (0x80000000)\r
+\r
+/* Bit definitions and macros for MCF_INTC0_INTFRCH */\r
+#define MCF_INTC0_INTFRCH_INTFRC32    (0x00000001)\r
+#define MCF_INTC0_INTFRCH_INTFRC33    (0x00000002)\r
+#define MCF_INTC0_INTFRCH_INTFRC34    (0x00000004)\r
+#define MCF_INTC0_INTFRCH_INTFRC35    (0x00000008)\r
+#define MCF_INTC0_INTFRCH_INTFRC36    (0x00000010)\r
+#define MCF_INTC0_INTFRCH_INTFRC37    (0x00000020)\r
+#define MCF_INTC0_INTFRCH_INTFRC38    (0x00000040)\r
+#define MCF_INTC0_INTFRCH_INTFRC39    (0x00000080)\r
+#define MCF_INTC0_INTFRCH_INTFRC40    (0x00000100)\r
+#define MCF_INTC0_INTFRCH_INTFRC41    (0x00000200)\r
+#define MCF_INTC0_INTFRCH_INTFRC42    (0x00000400)\r
+#define MCF_INTC0_INTFRCH_INTFRC43    (0x00000800)\r
+#define MCF_INTC0_INTFRCH_INTFRC44    (0x00001000)\r
+#define MCF_INTC0_INTFRCH_INTFRC45    (0x00002000)\r
+#define MCF_INTC0_INTFRCH_INTFRC46    (0x00004000)\r
+#define MCF_INTC0_INTFRCH_INTFRC47    (0x00008000)\r
+#define MCF_INTC0_INTFRCH_INTFRC48    (0x00010000)\r
+#define MCF_INTC0_INTFRCH_INTFRC49    (0x00020000)\r
+#define MCF_INTC0_INTFRCH_INTFRC50    (0x00040000)\r
+#define MCF_INTC0_INTFRCH_INTFRC51    (0x00080000)\r
+#define MCF_INTC0_INTFRCH_INTFRC52    (0x00100000)\r
+#define MCF_INTC0_INTFRCH_INTFRC53    (0x00200000)\r
+#define MCF_INTC0_INTFRCH_INTFRC54    (0x00400000)\r
+#define MCF_INTC0_INTFRCH_INTFRC55    (0x00800000)\r
+#define MCF_INTC0_INTFRCH_INTFRC56    (0x01000000)\r
+#define MCF_INTC0_INTFRCH_INTFRC57    (0x02000000)\r
+#define MCF_INTC0_INTFRCH_INTFRC58    (0x04000000)\r
+#define MCF_INTC0_INTFRCH_INTFRC59    (0x08000000)\r
+#define MCF_INTC0_INTFRCH_INTFRC60    (0x10000000)\r
+#define MCF_INTC0_INTFRCH_INTFRC61    (0x20000000)\r
+#define MCF_INTC0_INTFRCH_INTFRC62    (0x40000000)\r
+#define MCF_INTC0_INTFRCH_INTFRC63    (0x80000000)\r
+\r
+/* Bit definitions and macros for MCF_INTC0_INTFRCL */\r
+#define MCF_INTC0_INTFRCL_INTFRC1     (0x00000002)\r
+#define MCF_INTC0_INTFRCL_INTFRC2     (0x00000004)\r
+#define MCF_INTC0_INTFRCL_INTFRC3     (0x00000008)\r
+#define MCF_INTC0_INTFRCL_INTFRC4     (0x00000010)\r
+#define MCF_INTC0_INTFRCL_INTFRC5     (0x00000020)\r
+#define MCF_INTC0_INTFRCL_INT6        (0x00000040)\r
+#define MCF_INTC0_INTFRCL_INT7        (0x00000080)\r
+#define MCF_INTC0_INTFRCL_INT8        (0x00000100)\r
+#define MCF_INTC0_INTFRCL_INT9        (0x00000200)\r
+#define MCF_INTC0_INTFRCL_INT10       (0x00000400)\r
+#define MCF_INTC0_INTFRCL_INTFRC11    (0x00000800)\r
+#define MCF_INTC0_INTFRCL_INTFRC12    (0x00001000)\r
+#define MCF_INTC0_INTFRCL_INTFRC13    (0x00002000)\r
+#define MCF_INTC0_INTFRCL_INTFRC14    (0x00004000)\r
+#define MCF_INTC0_INTFRCL_INT15       (0x00008000)\r
+#define MCF_INTC0_INTFRCL_INTFRC16    (0x00010000)\r
+#define MCF_INTC0_INTFRCL_INTFRC17    (0x00020000)\r
+#define MCF_INTC0_INTFRCL_INTFRC18    (0x00040000)\r
+#define MCF_INTC0_INTFRCL_INTFRC19    (0x00080000)\r
+#define MCF_INTC0_INTFRCL_INTFRC20    (0x00100000)\r
+#define MCF_INTC0_INTFRCL_INTFRC21    (0x00200000)\r
+#define MCF_INTC0_INTFRCL_INTFRC22    (0x00400000)\r
+#define MCF_INTC0_INTFRCL_INTFRC23    (0x00800000)\r
+#define MCF_INTC0_INTFRCL_INTFRC24    (0x01000000)\r
+#define MCF_INTC0_INTFRCL_INTFRC25    (0x02000000)\r
+#define MCF_INTC0_INTFRCL_INTFRC26    (0x04000000)\r
+#define MCF_INTC0_INTFRCL_INTFRC27    (0x08000000)\r
+#define MCF_INTC0_INTFRCL_INTFRC28    (0x10000000)\r
+#define MCF_INTC0_INTFRCL_INTFRC29    (0x20000000)\r
+#define MCF_INTC0_INTFRCL_INTFRC30    (0x40000000)\r
+#define MCF_INTC0_INTFRCL_INTFRC31    (0x80000000)\r
+\r
+/* Bit definitions and macros for MCF_INTC0_IRLR */\r
+#define MCF_INTC0_IRLR_IRQ(x)         (((x)&0x7F)<<1)\r
+\r
+/* Bit definitions and macros for MCF_INTC0_IACKLPR */\r
+#define MCF_INTC0_IACKLPR_PRI(x)      (((x)&0x0F)<<0)\r
+#define MCF_INTC0_IACKLPR_LEVEL(x)    (((x)&0x07)<<4)\r
+\r
+/* Bit definitions and macros for MCF_INTC0_ICRn */\r
+#define MCF_INTC0_ICRn_IP(x)          (((x)&0x07)<<0)\r
+#define MCF_INTC0_ICRn_IL(x)          (((x)&0x07)<<3)\r
+\r
+/********************************************************************/\r
+\r
+#endif /* __MCF523X_INTC0_H__ */\r
index 45613eaaf0aa0577ed9dfc37a6785eac071a6c8f..7e8972c07897e1daeb86a6bf357ac46b443dae23 100644 (file)
-/*
- * These files are taken from the MCF523X source code example package
- * which is available on the Freescale website. Freescale explicitly 
- * grants the redistribution and modification of these source files.
- * The complete licensing information is available in the file 
- * LICENSE_FREESCALE.TXT.
- *
- * File:       mcf523x_intc1.h
- * Purpose:    Register and bit definitions for the MCF523X
- *
- * Notes:      
- *     
- */
-
-#ifndef __MCF523X_INTC1_H__
-#define __MCF523X_INTC1_H__
-
-/*********************************************************************
-*
-* Interrupt Controller 1 (INTC1)
-*
-*********************************************************************/
-
-/* Register read/write macros */
-#define MCF_INTC1_IPRH         (*(vuint32*)(void*)(&__IPSBAR[0x000D00]))
-#define MCF_INTC1_IPRL         (*(vuint32*)(void*)(&__IPSBAR[0x000D04]))
-#define MCF_INTC1_IMRH         (*(vuint32*)(void*)(&__IPSBAR[0x000D08]))
-#define MCF_INTC1_IMRL         (*(vuint32*)(void*)(&__IPSBAR[0x000D0C]))
-#define MCF_INTC1_INTFRCH      (*(vuint32*)(void*)(&__IPSBAR[0x000D10]))
-#define MCF_INTC1_INTFRCL      (*(vuint32*)(void*)(&__IPSBAR[0x000D14]))
-#define MCF_INTC1_IRLR         (*(vuint8 *)(void*)(&__IPSBAR[0x000D18]))
-#define MCF_INTC1_IACKLPR      (*(vuint8 *)(void*)(&__IPSBAR[0x000D19]))
-#define MCF_INTC1_ICR0         (*(vuint8 *)(void*)(&__IPSBAR[0x000D40]))
-#define MCF_INTC1_ICR1         (*(vuint8 *)(void*)(&__IPSBAR[0x000D41]))
-#define MCF_INTC1_ICR2         (*(vuint8 *)(void*)(&__IPSBAR[0x000D42]))
-#define MCF_INTC1_ICR3         (*(vuint8 *)(void*)(&__IPSBAR[0x000D43]))
-#define MCF_INTC1_ICR4         (*(vuint8 *)(void*)(&__IPSBAR[0x000D44]))
-#define MCF_INTC1_ICR5         (*(vuint8 *)(void*)(&__IPSBAR[0x000D45]))
-#define MCF_INTC1_ICR6         (*(vuint8 *)(void*)(&__IPSBAR[0x000D46]))
-#define MCF_INTC1_ICR7         (*(vuint8 *)(void*)(&__IPSBAR[0x000D47]))
-#define MCF_INTC1_ICR8         (*(vuint8 *)(void*)(&__IPSBAR[0x000D48]))
-#define MCF_INTC1_ICR9         (*(vuint8 *)(void*)(&__IPSBAR[0x000D49]))
-#define MCF_INTC1_ICR10        (*(vuint8 *)(void*)(&__IPSBAR[0x000D4A]))
-#define MCF_INTC1_ICR11        (*(vuint8 *)(void*)(&__IPSBAR[0x000D4B]))
-#define MCF_INTC1_ICR12        (*(vuint8 *)(void*)(&__IPSBAR[0x000D4C]))
-#define MCF_INTC1_ICR13        (*(vuint8 *)(void*)(&__IPSBAR[0x000D4D]))
-#define MCF_INTC1_ICR14        (*(vuint8 *)(void*)(&__IPSBAR[0x000D4E]))
-#define MCF_INTC1_ICR15        (*(vuint8 *)(void*)(&__IPSBAR[0x000D4F]))
-#define MCF_INTC1_ICR16        (*(vuint8 *)(void*)(&__IPSBAR[0x000D50]))
-#define MCF_INTC1_ICR17        (*(vuint8 *)(void*)(&__IPSBAR[0x000D51]))
-#define MCF_INTC1_ICR18        (*(vuint8 *)(void*)(&__IPSBAR[0x000D52]))
-#define MCF_INTC1_ICR19        (*(vuint8 *)(void*)(&__IPSBAR[0x000D53]))
-#define MCF_INTC1_ICR20        (*(vuint8 *)(void*)(&__IPSBAR[0x000D54]))
-#define MCF_INTC1_ICR21        (*(vuint8 *)(void*)(&__IPSBAR[0x000D55]))
-#define MCF_INTC1_ICR22        (*(vuint8 *)(void*)(&__IPSBAR[0x000D56]))
-#define MCF_INTC1_ICR23        (*(vuint8 *)(void*)(&__IPSBAR[0x000D57]))
-#define MCF_INTC1_ICR24        (*(vuint8 *)(void*)(&__IPSBAR[0x000D58]))
-#define MCF_INTC1_ICR25        (*(vuint8 *)(void*)(&__IPSBAR[0x000D59]))
-#define MCF_INTC1_ICR26        (*(vuint8 *)(void*)(&__IPSBAR[0x000D5A]))
-#define MCF_INTC1_ICR27        (*(vuint8 *)(void*)(&__IPSBAR[0x000D5B]))
-#define MCF_INTC1_ICR28        (*(vuint8 *)(void*)(&__IPSBAR[0x000D5C]))
-#define MCF_INTC1_ICR29        (*(vuint8 *)(void*)(&__IPSBAR[0x000D5D]))
-#define MCF_INTC1_ICR30        (*(vuint8 *)(void*)(&__IPSBAR[0x000D5E]))
-#define MCF_INTC1_ICR31        (*(vuint8 *)(void*)(&__IPSBAR[0x000D5F]))
-#define MCF_INTC1_ICR32        (*(vuint8 *)(void*)(&__IPSBAR[0x000D60]))
-#define MCF_INTC1_ICR33        (*(vuint8 *)(void*)(&__IPSBAR[0x000D61]))
-#define MCF_INTC1_ICR34        (*(vuint8 *)(void*)(&__IPSBAR[0x000D62]))
-#define MCF_INTC1_ICR35        (*(vuint8 *)(void*)(&__IPSBAR[0x000D63]))
-#define MCF_INTC1_ICR36        (*(vuint8 *)(void*)(&__IPSBAR[0x000D64]))
-#define MCF_INTC1_ICR37        (*(vuint8 *)(void*)(&__IPSBAR[0x000D65]))
-#define MCF_INTC1_ICR38        (*(vuint8 *)(void*)(&__IPSBAR[0x000D66]))
-#define MCF_INTC1_ICR39        (*(vuint8 *)(void*)(&__IPSBAR[0x000D67]))
-#define MCF_INTC1_ICR40        (*(vuint8 *)(void*)(&__IPSBAR[0x000D68]))
-#define MCF_INTC1_ICR41        (*(vuint8 *)(void*)(&__IPSBAR[0x000D69]))
-#define MCF_INTC1_ICR42        (*(vuint8 *)(void*)(&__IPSBAR[0x000D6A]))
-#define MCF_INTC1_ICR43        (*(vuint8 *)(void*)(&__IPSBAR[0x000D6B]))
-#define MCF_INTC1_ICR44        (*(vuint8 *)(void*)(&__IPSBAR[0x000D6C]))
-#define MCF_INTC1_ICR45        (*(vuint8 *)(void*)(&__IPSBAR[0x000D6D]))
-#define MCF_INTC1_ICR46        (*(vuint8 *)(void*)(&__IPSBAR[0x000D6E]))
-#define MCF_INTC1_ICR47        (*(vuint8 *)(void*)(&__IPSBAR[0x000D6F]))
-#define MCF_INTC1_ICR48        (*(vuint8 *)(void*)(&__IPSBAR[0x000D70]))
-#define MCF_INTC1_ICR49        (*(vuint8 *)(void*)(&__IPSBAR[0x000D71]))
-#define MCF_INTC1_ICR50        (*(vuint8 *)(void*)(&__IPSBAR[0x000D72]))
-#define MCF_INTC1_ICR51        (*(vuint8 *)(void*)(&__IPSBAR[0x000D73]))
-#define MCF_INTC1_ICR52        (*(vuint8 *)(void*)(&__IPSBAR[0x000D74]))
-#define MCF_INTC1_ICR53        (*(vuint8 *)(void*)(&__IPSBAR[0x000D75]))
-#define MCF_INTC1_ICR54        (*(vuint8 *)(void*)(&__IPSBAR[0x000D76]))
-#define MCF_INTC1_ICR55        (*(vuint8 *)(void*)(&__IPSBAR[0x000D77]))
-#define MCF_INTC1_ICR56        (*(vuint8 *)(void*)(&__IPSBAR[0x000D78]))
-#define MCF_INTC1_ICR57        (*(vuint8 *)(void*)(&__IPSBAR[0x000D79]))
-#define MCF_INTC1_ICR58        (*(vuint8 *)(void*)(&__IPSBAR[0x000D7A]))
-#define MCF_INTC1_ICR59        (*(vuint8 *)(void*)(&__IPSBAR[0x000D7B]))
-#define MCF_INTC1_ICR60        (*(vuint8 *)(void*)(&__IPSBAR[0x000D7C]))
-#define MCF_INTC1_ICR61        (*(vuint8 *)(void*)(&__IPSBAR[0x000D7D]))
-#define MCF_INTC1_ICR62        (*(vuint8 *)(void*)(&__IPSBAR[0x000D7E]))
-#define MCF_INTC1_ICR63        (*(vuint8 *)(void*)(&__IPSBAR[0x000D7F]))
-#define MCF_INTC1_ICRn(x)      (*(vuint8 *)(void*)(&__IPSBAR[0x000D40+((x)*0x001)]))
-#define MCF_INTC1_SWIACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000DE0]))
-#define MCF_INTC1_L1IACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000DE4]))
-#define MCF_INTC1_L2IACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000DE8]))
-#define MCF_INTC1_L3IACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000DEC]))
-#define MCF_INTC1_L4IACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000DF0]))
-#define MCF_INTC1_L5IACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000DF4]))
-#define MCF_INTC1_L6IACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000DF8]))
-#define MCF_INTC1_L7IACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000DFC]))
-#define MCF_INTC1_LnIACK(x)    (*(vuint8 *)(void*)(&__IPSBAR[0x000DE4+((x)*0x004)]))
-
-/* Bit definitions and macros for MCF_INTC1_IPRH */
-#define MCF_INTC1_IPRH_INT32          (0x00000001)
-#define MCF_INTC1_IPRH_INT33          (0x00000002)
-#define MCF_INTC1_IPRH_INT34          (0x00000004)
-#define MCF_INTC1_IPRH_INT35          (0x00000008)
-#define MCF_INTC1_IPRH_INT36          (0x00000010)
-#define MCF_INTC1_IPRH_INT37          (0x00000020)
-#define MCF_INTC1_IPRH_INT38          (0x00000040)
-#define MCF_INTC1_IPRH_INT39          (0x00000080)
-#define MCF_INTC1_IPRH_INT40          (0x00000100)
-#define MCF_INTC1_IPRH_INT41          (0x00000200)
-#define MCF_INTC1_IPRH_INT42          (0x00000400)
-#define MCF_INTC1_IPRH_INT43          (0x00000800)
-#define MCF_INTC1_IPRH_INT44          (0x00001000)
-#define MCF_INTC1_IPRH_INT45          (0x00002000)
-#define MCF_INTC1_IPRH_INT46          (0x00004000)
-#define MCF_INTC1_IPRH_INT47          (0x00008000)
-#define MCF_INTC1_IPRH_INT48          (0x00010000)
-#define MCF_INTC1_IPRH_INT49          (0x00020000)
-#define MCF_INTC1_IPRH_INT50          (0x00040000)
-#define MCF_INTC1_IPRH_INT51          (0x00080000)
-#define MCF_INTC1_IPRH_INT52          (0x00100000)
-#define MCF_INTC1_IPRH_INT53          (0x00200000)
-#define MCF_INTC1_IPRH_INT54          (0x00400000)
-#define MCF_INTC1_IPRH_INT55          (0x00800000)
-#define MCF_INTC1_IPRH_INT56          (0x01000000)
-#define MCF_INTC1_IPRH_INT57          (0x02000000)
-#define MCF_INTC1_IPRH_INT58          (0x04000000)
-#define MCF_INTC1_IPRH_INT59          (0x08000000)
-#define MCF_INTC1_IPRH_INT60          (0x10000000)
-#define MCF_INTC1_IPRH_INT61          (0x20000000)
-#define MCF_INTC1_IPRH_INT62          (0x40000000)
-#define MCF_INTC1_IPRH_INT63          (0x80000000)
-
-/* Bit definitions and macros for MCF_INTC1_IPRL */
-#define MCF_INTC1_IPRL_INT1           (0x00000002)
-#define MCF_INTC1_IPRL_INT2           (0x00000004)
-#define MCF_INTC1_IPRL_INT3           (0x00000008)
-#define MCF_INTC1_IPRL_INT4           (0x00000010)
-#define MCF_INTC1_IPRL_INT5           (0x00000020)
-#define MCF_INTC1_IPRL_INT6           (0x00000040)
-#define MCF_INTC1_IPRL_INT7           (0x00000080)
-#define MCF_INTC1_IPRL_INT8           (0x00000100)
-#define MCF_INTC1_IPRL_INT9           (0x00000200)
-#define MCF_INTC1_IPRL_INT10          (0x00000400)
-#define MCF_INTC1_IPRL_INT11          (0x00000800)
-#define MCF_INTC1_IPRL_INT12          (0x00001000)
-#define MCF_INTC1_IPRL_INT13          (0x00002000)
-#define MCF_INTC1_IPRL_INT14          (0x00004000)
-#define MCF_INTC1_IPRL_INT15          (0x00008000)
-#define MCF_INTC1_IPRL_INT16          (0x00010000)
-#define MCF_INTC1_IPRL_INT17          (0x00020000)
-#define MCF_INTC1_IPRL_INT18          (0x00040000)
-#define MCF_INTC1_IPRL_INT19          (0x00080000)
-#define MCF_INTC1_IPRL_INT20          (0x00100000)
-#define MCF_INTC1_IPRL_INT21          (0x00200000)
-#define MCF_INTC1_IPRL_INT22          (0x00400000)
-#define MCF_INTC1_IPRL_INT23          (0x00800000)
-#define MCF_INTC1_IPRL_INT24          (0x01000000)
-#define MCF_INTC1_IPRL_INT25          (0x02000000)
-#define MCF_INTC1_IPRL_INT26          (0x04000000)
-#define MCF_INTC1_IPRL_INT27          (0x08000000)
-#define MCF_INTC1_IPRL_INT28          (0x10000000)
-#define MCF_INTC1_IPRL_INT29          (0x20000000)
-#define MCF_INTC1_IPRL_INT30          (0x40000000)
-#define MCF_INTC1_IPRL_INT31          (0x80000000)
-
-/* Bit definitions and macros for MCF_INTC1_IMRH */
-#define MCF_INTC1_IMRH_INT_MASK32     (0x00000001)
-#define MCF_INTC1_IMRH_INT_MASK33     (0x00000002)
-#define MCF_INTC1_IMRH_INT_MASK34     (0x00000004)
-#define MCF_INTC1_IMRH_INT_MASK35     (0x00000008)
-#define MCF_INTC1_IMRH_INT_MASK36     (0x00000010)
-#define MCF_INTC1_IMRH_INT_MASK37     (0x00000020)
-#define MCF_INTC1_IMRH_INT_MASK38     (0x00000040)
-#define MCF_INTC1_IMRH_INT_MASK39     (0x00000080)
-#define MCF_INTC1_IMRH_INT_MASK40     (0x00000100)
-#define MCF_INTC1_IMRH_INT_MASK41     (0x00000200)
-#define MCF_INTC1_IMRH_INT_MASK42     (0x00000400)
-#define MCF_INTC1_IMRH_INT_MASK43     (0x00000800)
-#define MCF_INTC1_IMRH_INT_MASK44     (0x00001000)
-#define MCF_INTC1_IMRH_INT_MASK45     (0x00002000)
-#define MCF_INTC1_IMRH_INT_MASK46     (0x00004000)
-#define MCF_INTC1_IMRH_INT_MASK47     (0x00008000)
-#define MCF_INTC1_IMRH_INT_MASK48     (0x00010000)
-#define MCF_INTC1_IMRH_INT_MASK49     (0x00020000)
-#define MCF_INTC1_IMRH_INT_MASK50     (0x00040000)
-#define MCF_INTC1_IMRH_INT_MASK51     (0x00080000)
-#define MCF_INTC1_IMRH_INT_MASK52     (0x00100000)
-#define MCF_INTC1_IMRH_INT_MASK53     (0x00200000)
-#define MCF_INTC1_IMRH_INT_MASK54     (0x00400000)
-#define MCF_INTC1_IMRH_INT_MASK55     (0x00800000)
-#define MCF_INTC1_IMRH_INT_MASK56     (0x01000000)
-#define MCF_INTC1_IMRH_INT_MASK57     (0x02000000)
-#define MCF_INTC1_IMRH_INT_MASK58     (0x04000000)
-#define MCF_INTC1_IMRH_INT_MASK59     (0x08000000)
-#define MCF_INTC1_IMRH_INT_MASK60     (0x10000000)
-#define MCF_INTC1_IMRH_INT_MASK61     (0x20000000)
-#define MCF_INTC1_IMRH_INT_MASK62     (0x40000000)
-#define MCF_INTC1_IMRH_INT_MASK63     (0x80000000)
-
-/* Bit definitions and macros for MCF_INTC1_IMRL */
-#define MCF_INTC1_IMRL_MASKALL        (0x00000001)
-#define MCF_INTC1_IMRL_INT_MASK1      (0x00000002)
-#define MCF_INTC1_IMRL_INT_MASK2      (0x00000004)
-#define MCF_INTC1_IMRL_INT_MASK3      (0x00000008)
-#define MCF_INTC1_IMRL_INT_MASK4      (0x00000010)
-#define MCF_INTC1_IMRL_INT_MASK5      (0x00000020)
-#define MCF_INTC1_IMRL_INT_MASK6      (0x00000040)
-#define MCF_INTC1_IMRL_INT_MASK7      (0x00000080)
-#define MCF_INTC1_IMRL_INT_MASK8      (0x00000100)
-#define MCF_INTC1_IMRL_INT_MASK9      (0x00000200)
-#define MCF_INTC1_IMRL_INT_MASK10     (0x00000400)
-#define MCF_INTC1_IMRL_INT_MASK11     (0x00000800)
-#define MCF_INTC1_IMRL_INT_MASK12     (0x00001000)
-#define MCF_INTC1_IMRL_INT_MASK13     (0x00002000)
-#define MCF_INTC1_IMRL_INT_MASK14     (0x00004000)
-#define MCF_INTC1_IMRL_INT_MASK15     (0x00008000)
-#define MCF_INTC1_IMRL_INT_MASK16     (0x00010000)
-#define MCF_INTC1_IMRL_INT_MASK17     (0x00020000)
-#define MCF_INTC1_IMRL_INT_MASK18     (0x00040000)
-#define MCF_INTC1_IMRL_INT_MASK19     (0x00080000)
-#define MCF_INTC1_IMRL_INT_MASK20     (0x00100000)
-#define MCF_INTC1_IMRL_INT_MASK21     (0x00200000)
-#define MCF_INTC1_IMRL_INT_MASK22     (0x00400000)
-#define MCF_INTC1_IMRL_INT_MASK23     (0x00800000)
-#define MCF_INTC1_IMRL_INT_MASK24     (0x01000000)
-#define MCF_INTC1_IMRL_INT_MASK25     (0x02000000)
-#define MCF_INTC1_IMRL_INT_MASK26     (0x04000000)
-#define MCF_INTC1_IMRL_INT_MASK27     (0x08000000)
-#define MCF_INTC1_IMRL_INT_MASK28     (0x10000000)
-#define MCF_INTC1_IMRL_INT_MASK29     (0x20000000)
-#define MCF_INTC1_IMRL_INT_MASK30     (0x40000000)
-#define MCF_INTC1_IMRL_INT_MASK31     (0x80000000)
-
-/* Bit definitions and macros for MCF_INTC1_INTFRCH */
-#define MCF_INTC1_INTFRCH_INTFRC32    (0x00000001)
-#define MCF_INTC1_INTFRCH_INTFRC33    (0x00000002)
-#define MCF_INTC1_INTFRCH_INTFRC34    (0x00000004)
-#define MCF_INTC1_INTFRCH_INTFRC35    (0x00000008)
-#define MCF_INTC1_INTFRCH_INTFRC36    (0x00000010)
-#define MCF_INTC1_INTFRCH_INTFRC37    (0x00000020)
-#define MCF_INTC1_INTFRCH_INTFRC38    (0x00000040)
-#define MCF_INTC1_INTFRCH_INTFRC39    (0x00000080)
-#define MCF_INTC1_INTFRCH_INTFRC40    (0x00000100)
-#define MCF_INTC1_INTFRCH_INTFRC41    (0x00000200)
-#define MCF_INTC1_INTFRCH_INTFRC42    (0x00000400)
-#define MCF_INTC1_INTFRCH_INTFRC43    (0x00000800)
-#define MCF_INTC1_INTFRCH_INTFRC44    (0x00001000)
-#define MCF_INTC1_INTFRCH_INTFRC45    (0x00002000)
-#define MCF_INTC1_INTFRCH_INTFRC46    (0x00004000)
-#define MCF_INTC1_INTFRCH_INTFRC47    (0x00008000)
-#define MCF_INTC1_INTFRCH_INTFRC48    (0x00010000)
-#define MCF_INTC1_INTFRCH_INTFRC49    (0x00020000)
-#define MCF_INTC1_INTFRCH_INTFRC50    (0x00040000)
-#define MCF_INTC1_INTFRCH_INTFRC51    (0x00080000)
-#define MCF_INTC1_INTFRCH_INTFRC52    (0x00100000)
-#define MCF_INTC1_INTFRCH_INTFRC53    (0x00200000)
-#define MCF_INTC1_INTFRCH_INTFRC54    (0x00400000)
-#define MCF_INTC1_INTFRCH_INTFRC55    (0x00800000)
-#define MCF_INTC1_INTFRCH_INTFRC56    (0x01000000)
-#define MCF_INTC1_INTFRCH_INTFRC57    (0x02000000)
-#define MCF_INTC1_INTFRCH_INTFRC58    (0x04000000)
-#define MCF_INTC1_INTFRCH_INTFRC59    (0x08000000)
-#define MCF_INTC1_INTFRCH_INTFRC60    (0x10000000)
-#define MCF_INTC1_INTFRCH_INTFRC61    (0x20000000)
-#define MCF_INTC1_INTFRCH_INTFRC62    (0x40000000)
-#define MCF_INTC1_INTFRCH_INTFRC63    (0x80000000)
-
-/* Bit definitions and macros for MCF_INTC1_INTFRCL */
-#define MCF_INTC1_INTFRCL_INTFRC1     (0x00000002)
-#define MCF_INTC1_INTFRCL_INTFRC2     (0x00000004)
-#define MCF_INTC1_INTFRCL_INTFRC3     (0x00000008)
-#define MCF_INTC1_INTFRCL_INTFRC4     (0x00000010)
-#define MCF_INTC1_INTFRCL_INTFRC5     (0x00000020)
-#define MCF_INTC1_INTFRCL_INT6        (0x00000040)
-#define MCF_INTC1_INTFRCL_INT7        (0x00000080)
-#define MCF_INTC1_INTFRCL_INT8        (0x00000100)
-#define MCF_INTC1_INTFRCL_INT9        (0x00000200)
-#define MCF_INTC1_INTFRCL_INT10       (0x00000400)
-#define MCF_INTC1_INTFRCL_INTFRC11    (0x00000800)
-#define MCF_INTC1_INTFRCL_INTFRC12    (0x00001000)
-#define MCF_INTC1_INTFRCL_INTFRC13    (0x00002000)
-#define MCF_INTC1_INTFRCL_INTFRC14    (0x00004000)
-#define MCF_INTC1_INTFRCL_INT15       (0x00008000)
-#define MCF_INTC1_INTFRCL_INTFRC16    (0x00010000)
-#define MCF_INTC1_INTFRCL_INTFRC17    (0x00020000)
-#define MCF_INTC1_INTFRCL_INTFRC18    (0x00040000)
-#define MCF_INTC1_INTFRCL_INTFRC19    (0x00080000)
-#define MCF_INTC1_INTFRCL_INTFRC20    (0x00100000)
-#define MCF_INTC1_INTFRCL_INTFRC21    (0x00200000)
-#define MCF_INTC1_INTFRCL_INTFRC22    (0x00400000)
-#define MCF_INTC1_INTFRCL_INTFRC23    (0x00800000)
-#define MCF_INTC1_INTFRCL_INTFRC24    (0x01000000)
-#define MCF_INTC1_INTFRCL_INTFRC25    (0x02000000)
-#define MCF_INTC1_INTFRCL_INTFRC26    (0x04000000)
-#define MCF_INTC1_INTFRCL_INTFRC27    (0x08000000)
-#define MCF_INTC1_INTFRCL_INTFRC28    (0x10000000)
-#define MCF_INTC1_INTFRCL_INTFRC29    (0x20000000)
-#define MCF_INTC1_INTFRCL_INTFRC30    (0x40000000)
-#define MCF_INTC1_INTFRCL_INTFRC31    (0x80000000)
-
-/* Bit definitions and macros for MCF_INTC1_IRLR */
-#define MCF_INTC1_IRLR_IRQ(x)         (((x)&0x7F)<<1)
-
-/* Bit definitions and macros for MCF_INTC1_IACKLPR */
-#define MCF_INTC1_IACKLPR_PRI(x)      (((x)&0x0F)<<0)
-#define MCF_INTC1_IACKLPR_LEVEL(x)    (((x)&0x07)<<4)
-
-/* Bit definitions and macros for MCF_INTC1_ICRn */
-#define MCF_INTC1_ICRn_IP(x)          (((x)&0x07)<<0)
-#define MCF_INTC1_ICRn_IL(x)          (((x)&0x07)<<3)
-
-/********************************************************************/
-
-#endif /* __MCF523X_INTC1_H__ */
+/*\r
+ * These files are taken from the MCF523X source code example package\r
+ * which is available on the Freescale website. Freescale explicitly \r
+ * grants the redistribution and modification of these source files.\r
+ * The complete licensing information is available in the file \r
+ * LICENSE_FREESCALE.TXT.\r
+ *\r
+ * File:       mcf523x_intc1.h\r
+ * Purpose:    Register and bit definitions for the MCF523X\r
+ *\r
+ * Notes:      \r
+ *     \r
+ */\r
+\r
+#ifndef __MCF523X_INTC1_H__\r
+#define __MCF523X_INTC1_H__\r
+\r
+/*********************************************************************\r
+*\r
+* Interrupt Controller 1 (INTC1)\r
+*\r
+*********************************************************************/\r
+\r
+/* Register read/write macros */\r
+#define MCF_INTC1_IPRH         (*(vuint32*)(void*)(&__IPSBAR[0x000D00]))\r
+#define MCF_INTC1_IPRL         (*(vuint32*)(void*)(&__IPSBAR[0x000D04]))\r
+#define MCF_INTC1_IMRH         (*(vuint32*)(void*)(&__IPSBAR[0x000D08]))\r
+#define MCF_INTC1_IMRL         (*(vuint32*)(void*)(&__IPSBAR[0x000D0C]))\r
+#define MCF_INTC1_INTFRCH      (*(vuint32*)(void*)(&__IPSBAR[0x000D10]))\r
+#define MCF_INTC1_INTFRCL      (*(vuint32*)(void*)(&__IPSBAR[0x000D14]))\r
+#define MCF_INTC1_IRLR         (*(vuint8 *)(void*)(&__IPSBAR[0x000D18]))\r
+#define MCF_INTC1_IACKLPR      (*(vuint8 *)(void*)(&__IPSBAR[0x000D19]))\r
+#define MCF_INTC1_ICR0         (*(vuint8 *)(void*)(&__IPSBAR[0x000D40]))\r
+#define MCF_INTC1_ICR1         (*(vuint8 *)(void*)(&__IPSBAR[0x000D41]))\r
+#define MCF_INTC1_ICR2         (*(vuint8 *)(void*)(&__IPSBAR[0x000D42]))\r
+#define MCF_INTC1_ICR3         (*(vuint8 *)(void*)(&__IPSBAR[0x000D43]))\r
+#define MCF_INTC1_ICR4         (*(vuint8 *)(void*)(&__IPSBAR[0x000D44]))\r
+#define MCF_INTC1_ICR5         (*(vuint8 *)(void*)(&__IPSBAR[0x000D45]))\r
+#define MCF_INTC1_ICR6         (*(vuint8 *)(void*)(&__IPSBAR[0x000D46]))\r
+#define MCF_INTC1_ICR7         (*(vuint8 *)(void*)(&__IPSBAR[0x000D47]))\r
+#define MCF_INTC1_ICR8         (*(vuint8 *)(void*)(&__IPSBAR[0x000D48]))\r
+#define MCF_INTC1_ICR9         (*(vuint8 *)(void*)(&__IPSBAR[0x000D49]))\r
+#define MCF_INTC1_ICR10        (*(vuint8 *)(void*)(&__IPSBAR[0x000D4A]))\r
+#define MCF_INTC1_ICR11        (*(vuint8 *)(void*)(&__IPSBAR[0x000D4B]))\r
+#define MCF_INTC1_ICR12        (*(vuint8 *)(void*)(&__IPSBAR[0x000D4C]))\r
+#define MCF_INTC1_ICR13        (*(vuint8 *)(void*)(&__IPSBAR[0x000D4D]))\r
+#define MCF_INTC1_ICR14        (*(vuint8 *)(void*)(&__IPSBAR[0x000D4E]))\r
+#define MCF_INTC1_ICR15        (*(vuint8 *)(void*)(&__IPSBAR[0x000D4F]))\r
+#define MCF_INTC1_ICR16        (*(vuint8 *)(void*)(&__IPSBAR[0x000D50]))\r
+#define MCF_INTC1_ICR17        (*(vuint8 *)(void*)(&__IPSBAR[0x000D51]))\r
+#define MCF_INTC1_ICR18        (*(vuint8 *)(void*)(&__IPSBAR[0x000D52]))\r
+#define MCF_INTC1_ICR19        (*(vuint8 *)(void*)(&__IPSBAR[0x000D53]))\r
+#define MCF_INTC1_ICR20        (*(vuint8 *)(void*)(&__IPSBAR[0x000D54]))\r
+#define MCF_INTC1_ICR21        (*(vuint8 *)(void*)(&__IPSBAR[0x000D55]))\r
+#define MCF_INTC1_ICR22        (*(vuint8 *)(void*)(&__IPSBAR[0x000D56]))\r
+#define MCF_INTC1_ICR23        (*(vuint8 *)(void*)(&__IPSBAR[0x000D57]))\r
+#define MCF_INTC1_ICR24        (*(vuint8 *)(void*)(&__IPSBAR[0x000D58]))\r
+#define MCF_INTC1_ICR25        (*(vuint8 *)(void*)(&__IPSBAR[0x000D59]))\r
+#define MCF_INTC1_ICR26        (*(vuint8 *)(void*)(&__IPSBAR[0x000D5A]))\r
+#define MCF_INTC1_ICR27        (*(vuint8 *)(void*)(&__IPSBAR[0x000D5B]))\r
+#define MCF_INTC1_ICR28        (*(vuint8 *)(void*)(&__IPSBAR[0x000D5C]))\r
+#define MCF_INTC1_ICR29        (*(vuint8 *)(void*)(&__IPSBAR[0x000D5D]))\r
+#define MCF_INTC1_ICR30        (*(vuint8 *)(void*)(&__IPSBAR[0x000D5E]))\r
+#define MCF_INTC1_ICR31        (*(vuint8 *)(void*)(&__IPSBAR[0x000D5F]))\r
+#define MCF_INTC1_ICR32        (*(vuint8 *)(void*)(&__IPSBAR[0x000D60]))\r
+#define MCF_INTC1_ICR33        (*(vuint8 *)(void*)(&__IPSBAR[0x000D61]))\r
+#define MCF_INTC1_ICR34        (*(vuint8 *)(void*)(&__IPSBAR[0x000D62]))\r
+#define MCF_INTC1_ICR35        (*(vuint8 *)(void*)(&__IPSBAR[0x000D63]))\r
+#define MCF_INTC1_ICR36        (*(vuint8 *)(void*)(&__IPSBAR[0x000D64]))\r
+#define MCF_INTC1_ICR37        (*(vuint8 *)(void*)(&__IPSBAR[0x000D65]))\r
+#define MCF_INTC1_ICR38        (*(vuint8 *)(void*)(&__IPSBAR[0x000D66]))\r
+#define MCF_INTC1_ICR39        (*(vuint8 *)(void*)(&__IPSBAR[0x000D67]))\r
+#define MCF_INTC1_ICR40        (*(vuint8 *)(void*)(&__IPSBAR[0x000D68]))\r
+#define MCF_INTC1_ICR41        (*(vuint8 *)(void*)(&__IPSBAR[0x000D69]))\r
+#define MCF_INTC1_ICR42        (*(vuint8 *)(void*)(&__IPSBAR[0x000D6A]))\r
+#define MCF_INTC1_ICR43        (*(vuint8 *)(void*)(&__IPSBAR[0x000D6B]))\r
+#define MCF_INTC1_ICR44        (*(vuint8 *)(void*)(&__IPSBAR[0x000D6C]))\r
+#define MCF_INTC1_ICR45        (*(vuint8 *)(void*)(&__IPSBAR[0x000D6D]))\r
+#define MCF_INTC1_ICR46        (*(vuint8 *)(void*)(&__IPSBAR[0x000D6E]))\r
+#define MCF_INTC1_ICR47        (*(vuint8 *)(void*)(&__IPSBAR[0x000D6F]))\r
+#define MCF_INTC1_ICR48        (*(vuint8 *)(void*)(&__IPSBAR[0x000D70]))\r
+#define MCF_INTC1_ICR49        (*(vuint8 *)(void*)(&__IPSBAR[0x000D71]))\r
+#define MCF_INTC1_ICR50        (*(vuint8 *)(void*)(&__IPSBAR[0x000D72]))\r
+#define MCF_INTC1_ICR51        (*(vuint8 *)(void*)(&__IPSBAR[0x000D73]))\r
+#define MCF_INTC1_ICR52        (*(vuint8 *)(void*)(&__IPSBAR[0x000D74]))\r
+#define MCF_INTC1_ICR53        (*(vuint8 *)(void*)(&__IPSBAR[0x000D75]))\r
+#define MCF_INTC1_ICR54        (*(vuint8 *)(void*)(&__IPSBAR[0x000D76]))\r
+#define MCF_INTC1_ICR55        (*(vuint8 *)(void*)(&__IPSBAR[0x000D77]))\r
+#define MCF_INTC1_ICR56        (*(vuint8 *)(void*)(&__IPSBAR[0x000D78]))\r
+#define MCF_INTC1_ICR57        (*(vuint8 *)(void*)(&__IPSBAR[0x000D79]))\r
+#define MCF_INTC1_ICR58        (*(vuint8 *)(void*)(&__IPSBAR[0x000D7A]))\r
+#define MCF_INTC1_ICR59        (*(vuint8 *)(void*)(&__IPSBAR[0x000D7B]))\r
+#define MCF_INTC1_ICR60        (*(vuint8 *)(void*)(&__IPSBAR[0x000D7C]))\r
+#define MCF_INTC1_ICR61        (*(vuint8 *)(void*)(&__IPSBAR[0x000D7D]))\r
+#define MCF_INTC1_ICR62        (*(vuint8 *)(void*)(&__IPSBAR[0x000D7E]))\r
+#define MCF_INTC1_ICR63        (*(vuint8 *)(void*)(&__IPSBAR[0x000D7F]))\r
+#define MCF_INTC1_ICRn(x)      (*(vuint8 *)(void*)(&__IPSBAR[0x000D40+((x)*0x001)]))\r
+#define MCF_INTC1_SWIACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000DE0]))\r
+#define MCF_INTC1_L1IACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000DE4]))\r
+#define MCF_INTC1_L2IACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000DE8]))\r
+#define MCF_INTC1_L3IACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000DEC]))\r
+#define MCF_INTC1_L4IACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000DF0]))\r
+#define MCF_INTC1_L5IACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000DF4]))\r
+#define MCF_INTC1_L6IACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000DF8]))\r
+#define MCF_INTC1_L7IACK       (*(vuint8 *)(void*)(&__IPSBAR[0x000DFC]))\r
+#define MCF_INTC1_LnIACK(x)    (*(vuint8 *)(void*)(&__IPSBAR[0x000DE4+((x)*0x004)]))\r
+\r
+/* Bit definitions and macros for MCF_INTC1_IPRH */\r
+#define MCF_INTC1_IPRH_INT32          (0x00000001)\r
+#define MCF_INTC1_IPRH_INT33          (0x00000002)\r
+#define MCF_INTC1_IPRH_INT34          (0x00000004)\r
+#define MCF_INTC1_IPRH_INT35          (0x00000008)\r
+#define MCF_INTC1_IPRH_INT36          (0x00000010)\r
+#define MCF_INTC1_IPRH_INT37          (0x00000020)\r
+#define MCF_INTC1_IPRH_INT38          (0x00000040)\r
+#define MCF_INTC1_IPRH_INT39          (0x00000080)\r
+#define MCF_INTC1_IPRH_INT40          (0x00000100)\r
+#define MCF_INTC1_IPRH_INT41          (0x00000200)\r
+#define MCF_INTC1_IPRH_INT42          (0x00000400)\r
+#define MCF_INTC1_IPRH_INT43          (0x00000800)\r
+#define MCF_INTC1_IPRH_INT44          (0x00001000)\r
+#define MCF_INTC1_IPRH_INT45          (0x00002000)\r
+#define MCF_INTC1_IPRH_INT46          (0x00004000)\r
+#define MCF_INTC1_IPRH_INT47          (0x00008000)\r
+#define MCF_INTC1_IPRH_INT48          (0x00010000)\r
+#define MCF_INTC1_IPRH_INT49          (0x00020000)\r
+#define MCF_INTC1_IPRH_INT50          (0x00040000)\r
+#define MCF_INTC1_IPRH_INT51          (0x00080000)\r
+#define MCF_INTC1_IPRH_INT52          (0x00100000)\r
+#define MCF_INTC1_IPRH_INT53          (0x00200000)\r
+#define MCF_INTC1_IPRH_INT54          (0x00400000)\r
+#define MCF_INTC1_IPRH_INT55          (0x00800000)\r
+#define MCF_INTC1_IPRH_INT56          (0x01000000)\r
+#define MCF_INTC1_IPRH_INT57          (0x02000000)\r
+#define MCF_INTC1_IPRH_INT58          (0x04000000)\r
+#define MCF_INTC1_IPRH_INT59          (0x08000000)\r
+#define MCF_INTC1_IPRH_INT60          (0x10000000)\r
+#define MCF_INTC1_IPRH_INT61          (0x20000000)\r
+#define MCF_INTC1_IPRH_INT62          (0x40000000)\r
+#define MCF_INTC1_IPRH_INT63          (0x80000000)\r
+\r
+/* Bit definitions and macros for MCF_INTC1_IPRL */\r
+#define MCF_INTC1_IPRL_INT1           (0x00000002)\r
+#define MCF_INTC1_IPRL_INT2           (0x00000004)\r
+#define MCF_INTC1_IPRL_INT3           (0x00000008)\r
+#define MCF_INTC1_IPRL_INT4           (0x00000010)\r
+#define MCF_INTC1_IPRL_INT5           (0x00000020)\r
+#define MCF_INTC1_IPRL_INT6           (0x00000040)\r
+#define MCF_INTC1_IPRL_INT7           (0x00000080)\r
+#define MCF_INTC1_IPRL_INT8           (0x00000100)\r
+#define MCF_INTC1_IPRL_INT9           (0x00000200)\r
+#define MCF_INTC1_IPRL_INT10          (0x00000400)\r
+#define MCF_INTC1_IPRL_INT11          (0x00000800)\r
+#define MCF_INTC1_IPRL_INT12          (0x00001000)\r
+#define MCF_INTC1_IPRL_INT13          (0x00002000)\r
+#define MCF_INTC1_IPRL_INT14          (0x00004000)\r
+#define MCF_INTC1_IPRL_INT15          (0x00008000)\r
+#define MCF_INTC1_IPRL_INT16          (0x00010000)\r
+#define MCF_INTC1_IPRL_INT17          (0x00020000)\r
+#define MCF_INTC1_IPRL_INT18          (0x00040000)\r
+#define MCF_INTC1_IPRL_INT19          (0x00080000)\r
+#define MCF_INTC1_IPRL_INT20          (0x00100000)\r
+#define MCF_INTC1_IPRL_INT21          (0x00200000)\r
+#define MCF_INTC1_IPRL_INT22          (0x00400000)\r
+#define MCF_INTC1_IPRL_INT23          (0x00800000)\r
+#define MCF_INTC1_IPRL_INT24          (0x01000000)\r
+#define MCF_INTC1_IPRL_INT25          (0x02000000)\r
+#define MCF_INTC1_IPRL_INT26          (0x04000000)\r
+#define MCF_INTC1_IPRL_INT27          (0x08000000)\r
+#define MCF_INTC1_IPRL_INT28          (0x10000000)\r
+#define MCF_INTC1_IPRL_INT29          (0x20000000)\r
+#define MCF_INTC1_IPRL_INT30          (0x40000000)\r
+#define MCF_INTC1_IPRL_INT31          (0x80000000)\r
+\r
+/* Bit definitions and macros for MCF_INTC1_IMRH */\r
+#define MCF_INTC1_IMRH_INT_MASK32     (0x00000001)\r
+#define MCF_INTC1_IMRH_INT_MASK33     (0x00000002)\r
+#define MCF_INTC1_IMRH_INT_MASK34     (0x00000004)\r
+#define MCF_INTC1_IMRH_INT_MASK35     (0x00000008)\r
+#define MCF_INTC1_IMRH_INT_MASK36     (0x00000010)\r
+#define MCF_INTC1_IMRH_INT_MASK37     (0x00000020)\r
+#define MCF_INTC1_IMRH_INT_MASK38     (0x00000040)\r
+#define MCF_INTC1_IMRH_INT_MASK39     (0x00000080)\r
+#define MCF_INTC1_IMRH_INT_MASK40     (0x00000100)\r
+#define MCF_INTC1_IMRH_INT_MASK41     (0x00000200)\r
+#define MCF_INTC1_IMRH_INT_MASK42     (0x00000400)\r
+#define MCF_INTC1_IMRH_INT_MASK43     (0x00000800)\r
+#define MCF_INTC1_IMRH_INT_MASK44     (0x00001000)\r
+#define MCF_INTC1_IMRH_INT_MASK45     (0x00002000)\r
+#define MCF_INTC1_IMRH_INT_MASK46     (0x00004000)\r
+#define MCF_INTC1_IMRH_INT_MASK47     (0x00008000)\r
+#define MCF_INTC1_IMRH_INT_MASK48     (0x00010000)\r
+#define MCF_INTC1_IMRH_INT_MASK49     (0x00020000)\r
+#define MCF_INTC1_IMRH_INT_MASK50     (0x00040000)\r
+#define MCF_INTC1_IMRH_INT_MASK51     (0x00080000)\r
+#define MCF_INTC1_IMRH_INT_MASK52     (0x00100000)\r
+#define MCF_INTC1_IMRH_INT_MASK53     (0x00200000)\r
+#define MCF_INTC1_IMRH_INT_MASK54     (0x00400000)\r
+#define MCF_INTC1_IMRH_INT_MASK55     (0x00800000)\r
+#define MCF_INTC1_IMRH_INT_MASK56     (0x01000000)\r
+#define MCF_INTC1_IMRH_INT_MASK57     (0x02000000)\r
+#define MCF_INTC1_IMRH_INT_MASK58     (0x04000000)\r
+#define MCF_INTC1_IMRH_INT_MASK59     (0x08000000)\r
+#define MCF_INTC1_IMRH_INT_MASK60     (0x10000000)\r
+#define MCF_INTC1_IMRH_INT_MASK61     (0x20000000)\r
+#define MCF_INTC1_IMRH_INT_MASK62     (0x40000000)\r
+#define MCF_INTC1_IMRH_INT_MASK63     (0x80000000)\r
+\r
+/* Bit definitions and macros for MCF_INTC1_IMRL */\r
+#define MCF_INTC1_IMRL_MASKALL        (0x00000001)\r
+#define MCF_INTC1_IMRL_INT_MASK1      (0x00000002)\r
+#define MCF_INTC1_IMRL_INT_MASK2      (0x00000004)\r
+#define MCF_INTC1_IMRL_INT_MASK3      (0x00000008)\r
+#define MCF_INTC1_IMRL_INT_MASK4      (0x00000010)\r
+#define MCF_INTC1_IMRL_INT_MASK5      (0x00000020)\r
+#define MCF_INTC1_IMRL_INT_MASK6      (0x00000040)\r
+#define MCF_INTC1_IMRL_INT_MASK7      (0x00000080)\r
+#define MCF_INTC1_IMRL_INT_MASK8      (0x00000100)\r
+#define MCF_INTC1_IMRL_INT_MASK9      (0x00000200)\r
+#define MCF_INTC1_IMRL_INT_MASK10     (0x00000400)\r
+#define MCF_INTC1_IMRL_INT_MASK11     (0x00000800)\r
+#define MCF_INTC1_IMRL_INT_MASK12     (0x00001000)\r
+#define MCF_INTC1_IMRL_INT_MASK13     (0x00002000)\r
+#define MCF_INTC1_IMRL_INT_MASK14     (0x00004000)\r
+#define MCF_INTC1_IMRL_INT_MASK15     (0x00008000)\r
+#define MCF_INTC1_IMRL_INT_MASK16     (0x00010000)\r
+#define MCF_INTC1_IMRL_INT_MASK17     (0x00020000)\r
+#define MCF_INTC1_IMRL_INT_MASK18     (0x00040000)\r
+#define MCF_INTC1_IMRL_INT_MASK19     (0x00080000)\r
+#define MCF_INTC1_IMRL_INT_MASK20     (0x00100000)\r
+#define MCF_INTC1_IMRL_INT_MASK21     (0x00200000)\r
+#define MCF_INTC1_IMRL_INT_MASK22     (0x00400000)\r
+#define MCF_INTC1_IMRL_INT_MASK23     (0x00800000)\r
+#define MCF_INTC1_IMRL_INT_MASK24     (0x01000000)\r
+#define MCF_INTC1_IMRL_INT_MASK25     (0x02000000)\r
+#define MCF_INTC1_IMRL_INT_MASK26     (0x04000000)\r
+#define MCF_INTC1_IMRL_INT_MASK27     (0x08000000)\r
+#define MCF_INTC1_IMRL_INT_MASK28     (0x10000000)\r
+#define MCF_INTC1_IMRL_INT_MASK29     (0x20000000)\r
+#define MCF_INTC1_IMRL_INT_MASK30     (0x40000000)\r
+#define MCF_INTC1_IMRL_INT_MASK31     (0x80000000)\r
+\r
+/* Bit definitions and macros for MCF_INTC1_INTFRCH */\r
+#define MCF_INTC1_INTFRCH_INTFRC32    (0x00000001)\r
+#define MCF_INTC1_INTFRCH_INTFRC33    (0x00000002)\r
+#define MCF_INTC1_INTFRCH_INTFRC34    (0x00000004)\r
+#define MCF_INTC1_INTFRCH_INTFRC35    (0x00000008)\r
+#define MCF_INTC1_INTFRCH_INTFRC36    (0x00000010)\r
+#define MCF_INTC1_INTFRCH_INTFRC37    (0x00000020)\r
+#define MCF_INTC1_INTFRCH_INTFRC38    (0x00000040)\r
+#define MCF_INTC1_INTFRCH_INTFRC39    (0x00000080)\r
+#define MCF_INTC1_INTFRCH_INTFRC40    (0x00000100)\r
+#define MCF_INTC1_INTFRCH_INTFRC41    (0x00000200)\r
+#define MCF_INTC1_INTFRCH_INTFRC42    (0x00000400)\r
+#define MCF_INTC1_INTFRCH_INTFRC43    (0x00000800)\r
+#define MCF_INTC1_INTFRCH_INTFRC44    (0x00001000)\r
+#define MCF_INTC1_INTFRCH_INTFRC45    (0x00002000)\r
+#define MCF_INTC1_INTFRCH_INTFRC46    (0x00004000)\r
+#define MCF_INTC1_INTFRCH_INTFRC47    (0x00008000)\r
+#define MCF_INTC1_INTFRCH_INTFRC48    (0x00010000)\r
+#define MCF_INTC1_INTFRCH_INTFRC49    (0x00020000)\r
+#define MCF_INTC1_INTFRCH_INTFRC50    (0x00040000)\r
+#define MCF_INTC1_INTFRCH_INTFRC51    (0x00080000)\r
+#define MCF_INTC1_INTFRCH_INTFRC52    (0x00100000)\r
+#define MCF_INTC1_INTFRCH_INTFRC53    (0x00200000)\r
+#define MCF_INTC1_INTFRCH_INTFRC54    (0x00400000)\r
+#define MCF_INTC1_INTFRCH_INTFRC55    (0x00800000)\r
+#define MCF_INTC1_INTFRCH_INTFRC56    (0x01000000)\r
+#define MCF_INTC1_INTFRCH_INTFRC57    (0x02000000)\r
+#define MCF_INTC1_INTFRCH_INTFRC58    (0x04000000)\r
+#define MCF_INTC1_INTFRCH_INTFRC59    (0x08000000)\r
+#define MCF_INTC1_INTFRCH_INTFRC60    (0x10000000)\r
+#define MCF_INTC1_INTFRCH_INTFRC61    (0x20000000)\r
+#define MCF_INTC1_INTFRCH_INTFRC62    (0x40000000)\r
+#define MCF_INTC1_INTFRCH_INTFRC63    (0x80000000)\r
+\r
+/* Bit definitions and macros for MCF_INTC1_INTFRCL */\r
+#define MCF_INTC1_INTFRCL_INTFRC1     (0x00000002)\r
+#define MCF_INTC1_INTFRCL_INTFRC2     (0x00000004)\r
+#define MCF_INTC1_INTFRCL_INTFRC3     (0x00000008)\r
+#define MCF_INTC1_INTFRCL_INTFRC4     (0x00000010)\r
+#define MCF_INTC1_INTFRCL_INTFRC5     (0x00000020)\r
+#define MCF_INTC1_INTFRCL_INT6        (0x00000040)\r
+#define MCF_INTC1_INTFRCL_INT7        (0x00000080)\r
+#define MCF_INTC1_INTFRCL_INT8        (0x00000100)\r
+#define MCF_INTC1_INTFRCL_INT9        (0x00000200)\r
+#define MCF_INTC1_INTFRCL_INT10       (0x00000400)\r
+#define MCF_INTC1_INTFRCL_INTFRC11    (0x00000800)\r
+#define MCF_INTC1_INTFRCL_INTFRC12    (0x00001000)\r
+#define MCF_INTC1_INTFRCL_INTFRC13    (0x00002000)\r
+#define MCF_INTC1_INTFRCL_INTFRC14    (0x00004000)\r
+#define MCF_INTC1_INTFRCL_INT15       (0x00008000)\r
+#define MCF_INTC1_INTFRCL_INTFRC16    (0x00010000)\r
+#define MCF_INTC1_INTFRCL_INTFRC17    (0x00020000)\r
+#define MCF_INTC1_INTFRCL_INTFRC18    (0x00040000)\r
+#define MCF_INTC1_INTFRCL_INTFRC19    (0x00080000)\r
+#define MCF_INTC1_INTFRCL_INTFRC20    (0x00100000)\r
+#define MCF_INTC1_INTFRCL_INTFRC21    (0x00200000)\r
+#define MCF_INTC1_INTFRCL_INTFRC22    (0x00400000)\r
+#define MCF_INTC1_INTFRCL_INTFRC23    (0x00800000)\r
+#define MCF_INTC1_INTFRCL_INTFRC24    (0x01000000)\r
+#define MCF_INTC1_INTFRCL_INTFRC25    (0x02000000)\r
+#define MCF_INTC1_INTFRCL_INTFRC26    (0x04000000)\r
+#define MCF_INTC1_INTFRCL_INTFRC27    (0x08000000)\r
+#define MCF_INTC1_INTFRCL_INTFRC28    (0x10000000)\r
+#define MCF_INTC1_INTFRCL_INTFRC29    (0x20000000)\r
+#define MCF_INTC1_INTFRCL_INTFRC30    (0x40000000)\r
+#define MCF_INTC1_INTFRCL_INTFRC31    (0x80000000)\r
+\r
+/* Bit definitions and macros for MCF_INTC1_IRLR */\r
+#define MCF_INTC1_IRLR_IRQ(x)         (((x)&0x7F)<<1)\r
+\r
+/* Bit definitions and macros for MCF_INTC1_IACKLPR */\r
+#define MCF_INTC1_IACKLPR_PRI(x)      (((x)&0x0F)<<0)\r
+#define MCF_INTC1_IACKLPR_LEVEL(x)    (((x)&0x07)<<4)\r
+\r
+/* Bit definitions and macros for MCF_INTC1_ICRn */\r
+#define MCF_INTC1_ICRn_IP(x)          (((x)&0x07)<<0)\r
+#define MCF_INTC1_ICRn_IL(x)          (((x)&0x07)<<3)\r
+\r
+/********************************************************************/\r
+\r
+#endif /* __MCF523X_INTC1_H__ */\r
index adc714f6dbb0a685fb2e79631f08a51d6a4e7587..cc2ff27102686e5def607ab60350a8311202c61b 100644 (file)
-/*
- * These files are taken from the MCF523X source code example package
- * which is available on the Freescale website. Freescale explicitly 
- * grants the redistribution and modification of these source files.
- * The complete licensing information is available in the file 
- * LICENSE_FREESCALE.TXT.
- *
- * File:       mcf523x_mdha.h
- * Purpose:    Register and bit definitions for the MCF523X
- *
- * Notes:      
- *     
- */
-
-#ifndef __MCF523X_MDHA_H__
-#define __MCF523X_MDHA_H__
-
-/*********************************************************************
-*
-* Message Digest Hardware Accelerator (MDHA)
-*
-*********************************************************************/
-
-/* Register read/write macros */
-#define MCF_MDHA_MDMR     (*(vuint32*)(void*)(&__IPSBAR[0x190000]))
-#define MCF_MDHA_MDCR     (*(vuint32*)(void*)(&__IPSBAR[0x190004]))
-#define MCF_MDHA_MDCMR    (*(vuint32*)(void*)(&__IPSBAR[0x190008]))
-#define MCF_MDHA_MDSR     (*(vuint32*)(void*)(&__IPSBAR[0x19000C]))
-#define MCF_MDHA_MDISR     (*(vuint32*)(void*)(&__IPSBAR[0x190010]))
-#define MCF_MDHA_MDIMR    (*(vuint32*)(void*)(&__IPSBAR[0x190014]))
-#define MCF_MDHA_MDDSR    (*(vuint32*)(void*)(&__IPSBAR[0x19001C]))
-#define MCF_MDHA_MDIN     (*(vuint32*)(void*)(&__IPSBAR[0x190020]))
-#define MCF_MDHA_MDA0     (*(vuint32*)(void*)(&__IPSBAR[0x190030]))
-#define MCF_MDHA_MDB0     (*(vuint32*)(void*)(&__IPSBAR[0x190034]))
-#define MCF_MDHA_MDC0     (*(vuint32*)(void*)(&__IPSBAR[0x190038]))
-#define MCF_MDHA_MDD0     (*(vuint32*)(void*)(&__IPSBAR[0x19003C]))
-#define MCF_MDHA_MDE0     (*(vuint32*)(void*)(&__IPSBAR[0x190040]))
-#define MCF_MDHA_MDMDS    (*(vuint32*)(void*)(&__IPSBAR[0x190044]))
-#define MCF_MDHA_MDA1     (*(vuint32*)(void*)(&__IPSBAR[0x190070]))
-#define MCF_MDHA_MDB1     (*(vuint32*)(void*)(&__IPSBAR[0x190074]))
-#define MCF_MDHA_MDC1     (*(vuint32*)(void*)(&__IPSBAR[0x190078]))
-#define MCF_MDHA_MDD1     (*(vuint32*)(void*)(&__IPSBAR[0x19007C]))
-#define MCF_MDHA_MDE1     (*(vuint32*)(void*)(&__IPSBAR[0x190080]))
-
-/* Bit definitions and macros for MCF_MDHA_MDMR */
-#define MCF_MDHA_MDMR_ALG             (0x00000001)
-#define MCF_MDHA_MDMR_PDATA           (0x00000004)
-#define MCF_MDHA_MDMR_MAC(x)          (((x)&0x00000003)<<3)
-#define MCF_MDHA_MDMR_INIT            (0x00000020)
-#define MCF_MDHA_MDMR_IPAD            (0x00000040)
-#define MCF_MDHA_MDMR_OPAD            (0x00000080)
-#define MCF_MDHA_MDMR_SWAP            (0x00000100)
-#define MCF_MDHA_MDMR_MACFULL         (0x00000200)
-#define MCF_MDHA_MDMR_SSL             (0x00000400)
-
-/* Bit definitions and macros for MCF_MDHA_MDCR */
-#define MCF_MDHA_MDCR_IE              (0x00000001)
-
-/* Bit definitions and macros for MCF_MDHA_MDCMR */
-#define MCF_MDHA_MDCMR_SWR             (0x00000001)
-#define MCF_MDHA_MDCMR_RI             (0x00000002)
-#define MCF_MDHA_MDCMR_CI             (0x00000004)
-#define MCF_MDHA_MDCMR_GO             (0x00000008)
-
-/* Bit definitions and macros for MCF_MDHA_MDSR */
-#define MCF_MDHA_MDSR_INT             (0x00000001)
-#define MCF_MDHA_MDSR_DONE            (0x00000002)
-#define MCF_MDHA_MDSR_ERR             (0x00000004)
-#define MCF_MDHA_MDSR_RD              (0x00000008)
-#define MCF_MDHA_MDSR_BUSY            (0x00000010)
-#define MCF_MDHA_MDSR_END             (0x00000020)
-#define MCF_MDHA_MDSR_HSH             (0x00000040)
-#define MCF_MDHA_MDSR_GNW             (0x00000080)
-#define MCF_MDHA_MDSR_FS(x)           (((x)&0x00000007)<<8)
-#define MCF_MDHA_MDSR_APD(x)          (((x)&0x00000007)<<13)
-#define MCF_MDHA_MDSR_IFL(x)          (((x)&0x000000FF)<<16)
-
-/* Bit definitions and macros for MCF_MDHA_MDIR */
-#define MCF_MDHA_MDIR_IFO             (0x00000001)
-#define MCF_MDHA_MDIR_NON             (0x00000004)
-#define MCF_MDHA_MDIR_IME             (0x00000010)
-#define MCF_MDHA_MDIR_IDS             (0x00000020)
-#define MCF_MDHA_MDIR_RMDP            (0x00000080)
-#define MCF_MDHA_MDIR_ERE             (0x00000100)
-#define MCF_MDHA_MDIR_GTDS            (0x00000200)
-
-/* Bit definitions and macros for MCF_MDHA_MDIMR */
-#define MCF_MDHA_MDIMR_IFO            (0x00000001)
-#define MCF_MDHA_MDIMR_NON            (0x00000004)
-#define MCF_MDHA_MDIMR_IME            (0x00000010)
-#define MCF_MDHA_MDIMR_IDS            (0x00000020)
-#define MCF_MDHA_MDIMR_RMDP           (0x00000080)
-#define MCF_MDHA_MDIMR_ERE            (0x00000100)
-#define MCF_MDHA_MDIMR_GTDS           (0x00000200)
-
-/* Bit definitions and macros for MCF_MDHA_MDDSR */
-#define MCF_MDHA_MDDSR_DATASIZE(x)    (((x)&0x1FFFFFFF)<<0)
-
-/********************************************************************/
-
-#endif /* __MCF523X_MDHA_H__ */
+/*\r
+ * These files are taken from the MCF523X source code example package\r
+ * which is available on the Freescale website. Freescale explicitly \r
+ * grants the redistribution and modification of these source files.\r
+ * The complete licensing information is available in the file \r
+ * LICENSE_FREESCALE.TXT.\r
+ *\r
+ * File:       mcf523x_mdha.h\r
+ * Purpose:    Register and bit definitions for the MCF523X\r
+ *\r
+ * Notes:      \r
+ *     \r
+ */\r
+\r
+#ifndef __MCF523X_MDHA_H__\r
+#define __MCF523X_MDHA_H__\r
+\r
+/*********************************************************************\r
+*\r
+* Message Digest Hardware Accelerator (MDHA)\r
+*\r
+*********************************************************************/\r
+\r
+/* Register read/write macros */\r
+#define MCF_MDHA_MDMR     (*(vuint32*)(void*)(&__IPSBAR[0x190000]))\r
+#define MCF_MDHA_MDCR     (*(vuint32*)(void*)(&__IPSBAR[0x190004]))\r
+#define MCF_MDHA_MDCMR    (*(vuint32*)(void*)(&__IPSBAR[0x190008]))\r
+#define MCF_MDHA_MDSR     (*(vuint32*)(void*)(&__IPSBAR[0x19000C]))\r
+#define MCF_MDHA_MDISR     (*(vuint32*)(void*)(&__IPSBAR[0x190010]))\r
+#define MCF_MDHA_MDIMR    (*(vuint32*)(void*)(&__IPSBAR[0x190014]))\r
+#define MCF_MDHA_MDDSR    (*(vuint32*)(void*)(&__IPSBAR[0x19001C]))\r
+#define MCF_MDHA_MDIN     (*(vuint32*)(void*)(&__IPSBAR[0x190020]))\r
+#define MCF_MDHA_MDA0     (*(vuint32*)(void*)(&__IPSBAR[0x190030]))\r
+#define MCF_MDHA_MDB0     (*(vuint32*)(void*)(&__IPSBAR[0x190034]))\r
+#define MCF_MDHA_MDC0     (*(vuint32*)(void*)(&__IPSBAR[0x190038]))\r
+#define MCF_MDHA_MDD0     (*(vuint32*)(void*)(&__IPSBAR[0x19003C]))\r
+#define MCF_MDHA_MDE0     (*(vuint32*)(void*)(&__IPSBAR[0x190040]))\r
+#define MCF_MDHA_MDMDS    (*(vuint32*)(void*)(&__IPSBAR[0x190044]))\r
+#define MCF_MDHA_MDA1     (*(vuint32*)(void*)(&__IPSBAR[0x190070]))\r
+#define MCF_MDHA_MDB1     (*(vuint32*)(void*)(&__IPSBAR[0x190074]))\r
+#define MCF_MDHA_MDC1     (*(vuint32*)(void*)(&__IPSBAR[0x190078]))\r
+#define MCF_MDHA_MDD1     (*(vuint32*)(void*)(&__IPSBAR[0x19007C]))\r
+#define MCF_MDHA_MDE1     (*(vuint32*)(void*)(&__IPSBAR[0x190080]))\r
+\r
+/* Bit definitions and macros for MCF_MDHA_MDMR */\r
+#define MCF_MDHA_MDMR_ALG             (0x00000001)\r
+#define MCF_MDHA_MDMR_PDATA           (0x00000004)\r
+#define MCF_MDHA_MDMR_MAC(x)          (((x)&0x00000003)<<3)\r
+#define MCF_MDHA_MDMR_INIT            (0x00000020)\r
+#define MCF_MDHA_MDMR_IPAD            (0x00000040)\r
+#define MCF_MDHA_MDMR_OPAD            (0x00000080)\r
+#define MCF_MDHA_MDMR_SWAP            (0x00000100)\r
+#define MCF_MDHA_MDMR_MACFULL         (0x00000200)\r
+#define MCF_MDHA_MDMR_SSL             (0x00000400)\r
+\r
+/* Bit definitions and macros for MCF_MDHA_MDCR */\r
+#define MCF_MDHA_MDCR_IE              (0x00000001)\r
+\r
+/* Bit definitions and macros for MCF_MDHA_MDCMR */\r
+#define MCF_MDHA_MDCMR_SWR             (0x00000001)\r
+#define MCF_MDHA_MDCMR_RI             (0x00000002)\r
+#define MCF_MDHA_MDCMR_CI             (0x00000004)\r
+#define MCF_MDHA_MDCMR_GO             (0x00000008)\r
+\r
+/* Bit definitions and macros for MCF_MDHA_MDSR */\r
+#define MCF_MDHA_MDSR_INT             (0x00000001)\r
+#define MCF_MDHA_MDSR_DONE            (0x00000002)\r
+#define MCF_MDHA_MDSR_ERR             (0x00000004)\r
+#define MCF_MDHA_MDSR_RD              (0x00000008)\r
+#define MCF_MDHA_MDSR_BUSY            (0x00000010)\r
+#define MCF_MDHA_MDSR_END             (0x00000020)\r
+#define MCF_MDHA_MDSR_HSH             (0x00000040)\r
+#define MCF_MDHA_MDSR_GNW             (0x00000080)\r
+#define MCF_MDHA_MDSR_FS(x)           (((x)&0x00000007)<<8)\r
+#define MCF_MDHA_MDSR_APD(x)          (((x)&0x00000007)<<13)\r
+#define MCF_MDHA_MDSR_IFL(x)          (((x)&0x000000FF)<<16)\r
+\r
+/* Bit definitions and macros for MCF_MDHA_MDIR */\r
+#define MCF_MDHA_MDIR_IFO             (0x00000001)\r
+#define MCF_MDHA_MDIR_NON             (0x00000004)\r
+#define MCF_MDHA_MDIR_IME             (0x00000010)\r
+#define MCF_MDHA_MDIR_IDS             (0x00000020)\r
+#define MCF_MDHA_MDIR_RMDP            (0x00000080)\r
+#define MCF_MDHA_MDIR_ERE             (0x00000100)\r
+#define MCF_MDHA_MDIR_GTDS            (0x00000200)\r
+\r
+/* Bit definitions and macros for MCF_MDHA_MDIMR */\r
+#define MCF_MDHA_MDIMR_IFO            (0x00000001)\r
+#define MCF_MDHA_MDIMR_NON            (0x00000004)\r
+#define MCF_MDHA_MDIMR_IME            (0x00000010)\r
+#define MCF_MDHA_MDIMR_IDS            (0x00000020)\r
+#define MCF_MDHA_MDIMR_RMDP           (0x00000080)\r
+#define MCF_MDHA_MDIMR_ERE            (0x00000100)\r
+#define MCF_MDHA_MDIMR_GTDS           (0x00000200)\r
+\r
+/* Bit definitions and macros for MCF_MDHA_MDDSR */\r
+#define MCF_MDHA_MDDSR_DATASIZE(x)    (((x)&0x1FFFFFFF)<<0)\r
+\r
+/********************************************************************/\r
+\r
+#endif /* __MCF523X_MDHA_H__ */\r
index 0763d20f2e8bac38868c6c4f3185e9e58416c7a1..a3798f070af7f44f377911305701853400cdf345 100644 (file)
@@ -1,89 +1,89 @@
-/*
- * These files are taken from the MCF523X source code example package
- * which is available on the Freescale website. Freescale explicitly 
- * grants the redistribution and modification of these source files.
- * The complete licensing information is available in the file 
- * LICENSE_FREESCALE.TXT.
- *
- * File:       mcf523x_pit.h
- * Purpose:    Register and bit definitions for the MCF523X
- *
- * Notes:      
- *     
- */
-
-#ifndef __MCF523X_PIT_H__
-#define __MCF523X_PIT_H__
-
-/*********************************************************************
-*
-* Programmable Interrupt Timer Modules (PIT)
-*
-*********************************************************************/
-
-/* Register read/write macros */
-#define MCF_PIT_PCSR0       (*(vuint16*)(void*)(&__IPSBAR[0x150000]))
-#define MCF_PIT_PMR0        (*(vuint16*)(void*)(&__IPSBAR[0x150002]))
-#define MCF_PIT_PCNTR0      (*(vuint16*)(void*)(&__IPSBAR[0x150004]))
-#define MCF_PIT_PCSR1       (*(vuint16*)(void*)(&__IPSBAR[0x160000]))
-#define MCF_PIT_PMR1        (*(vuint16*)(void*)(&__IPSBAR[0x160002]))
-#define MCF_PIT_PCNTR1      (*(vuint16*)(void*)(&__IPSBAR[0x160004]))
-#define MCF_PIT_PCSR2       (*(vuint16*)(void*)(&__IPSBAR[0x170000]))
-#define MCF_PIT_PMR2        (*(vuint16*)(void*)(&__IPSBAR[0x170002]))
-#define MCF_PIT_PCNTR2      (*(vuint16*)(void*)(&__IPSBAR[0x170004]))
-#define MCF_PIT_PCSR3       (*(vuint16*)(void*)(&__IPSBAR[0x180000]))
-#define MCF_PIT_PMR3        (*(vuint16*)(void*)(&__IPSBAR[0x180002]))
-#define MCF_PIT_PCNTR3      (*(vuint16*)(void*)(&__IPSBAR[0x180004]))
-#define MCF_PIT_PCSR(x)     (*(vuint16*)(void*)(&__IPSBAR[0x150000+((x)*0x10000)]))
-#define MCF_PIT_PMR(x)      (*(vuint16*)(void*)(&__IPSBAR[0x150002+((x)*0x10000)]))
-#define MCF_PIT_PCNTR(x)    (*(vuint16*)(void*)(&__IPSBAR[0x150004+((x)*0x10000)]))
-
-/* Bit definitions and macros for MCF_PIT_PCSR */
-#define MCF_PIT_PCSR_EN        (0x0001)
-#define MCF_PIT_PCSR_RLD       (0x0002)
-#define MCF_PIT_PCSR_PIF       (0x0004)
-#define MCF_PIT_PCSR_PIE       (0x0008)
-#define MCF_PIT_PCSR_OVW       (0x0010)
-#define MCF_PIT_PCSR_HALTED    (0x0020)
-#define MCF_PIT_PCSR_DOZE      (0x0040)
-#define MCF_PIT_PCSR_PRE(x)    (((x)&0x000F)<<8)
-
-/* Bit definitions and macros for MCF_PIT_PMR */
-#define MCF_PIT_PMR_PM0        (0x0001)
-#define MCF_PIT_PMR_PM1        (0x0002)
-#define MCF_PIT_PMR_PM2        (0x0004)
-#define MCF_PIT_PMR_PM3        (0x0008)
-#define MCF_PIT_PMR_PM4        (0x0010)
-#define MCF_PIT_PMR_PM5        (0x0020)
-#define MCF_PIT_PMR_PM6        (0x0040)
-#define MCF_PIT_PMR_PM7        (0x0080)
-#define MCF_PIT_PMR_PM8        (0x0100)
-#define MCF_PIT_PMR_PM9        (0x0200)
-#define MCF_PIT_PMR_PM10       (0x0400)
-#define MCF_PIT_PMR_PM11       (0x0800)
-#define MCF_PIT_PMR_PM12       (0x1000)
-#define MCF_PIT_PMR_PM13       (0x2000)
-#define MCF_PIT_PMR_PM14       (0x4000)
-#define MCF_PIT_PMR_PM15       (0x8000)
-
-/* Bit definitions and macros for MCF_PIT_PCNTR */
-#define MCF_PIT_PCNTR_PC0      (0x0001)
-#define MCF_PIT_PCNTR_PC1      (0x0002)
-#define MCF_PIT_PCNTR_PC2      (0x0004)
-#define MCF_PIT_PCNTR_PC3      (0x0008)
-#define MCF_PIT_PCNTR_PC4      (0x0010)
-#define MCF_PIT_PCNTR_PC5      (0x0020)
-#define MCF_PIT_PCNTR_PC6      (0x0040)
-#define MCF_PIT_PCNTR_PC7      (0x0080)
-#define MCF_PIT_PCNTR_PC8      (0x0100)
-#define MCF_PIT_PCNTR_PC9      (0x0200)
-#define MCF_PIT_PCNTR_PC10     (0x0400)
-#define MCF_PIT_PCNTR_PC11     (0x0800)
-#define MCF_PIT_PCNTR_PC12     (0x1000)
-#define MCF_PIT_PCNTR_PC13     (0x2000)
-#define MCF_PIT_PCNTR_PC14     (0x4000)
-#define MCF_PIT_PCNTR_PC15     (0x8000)
-
-/********************************************************************/
-
-#endif /* __MCF523X_PIT_H__ */
+/*\r
+ * These files are taken from the MCF523X source code example package\r
+ * which is available on the Freescale website. Freescale explicitly \r
+ * grants the redistribution and modification of these source files.\r
+ * The complete licensing information is available in the file \r
+ * LICENSE_FREESCALE.TXT.\r
+ *\r
+ * File:       mcf523x_pit.h\r
+ * Purpose:    Register and bit definitions for the MCF523X\r
+ *\r
+ * Notes:      \r
+ *     \r
+ */\r
+\r
+#ifndef __MCF523X_PIT_H__\r
+#define __MCF523X_PIT_H__\r
+\r
+/*********************************************************************\r
+*\r
+* Programmable Interrupt Timer Modules (PIT)\r
+*\r
+*********************************************************************/\r
+\r
+/* Register read/write macros */\r
+#define MCF_PIT_PCSR0       (*(vuint16*)(void*)(&__IPSBAR[0x150000]))\r
+#define MCF_PIT_PMR0        (*(vuint16*)(void*)(&__IPSBAR[0x150002]))\r
+#define MCF_PIT_PCNTR0      (*(vuint16*)(void*)(&__IPSBAR[0x150004]))\r
+#define MCF_PIT_PCSR1       (*(vuint16*)(void*)(&__IPSBAR[0x160000]))\r
+#define MCF_PIT_PMR1        (*(vuint16*)(void*)(&__IPSBAR[0x160002]))\r
+#define MCF_PIT_PCNTR1      (*(vuint16*)(void*)(&__IPSBAR[0x160004]))\r
+#define MCF_PIT_PCSR2       (*(vuint16*)(void*)(&__IPSBAR[0x170000]))\r
+#define MCF_PIT_PMR2        (*(vuint16*)(void*)(&__IPSBAR[0x170002]))\r
+#define MCF_PIT_PCNTR2      (*(vuint16*)(void*)(&__IPSBAR[0x170004]))\r
+#define MCF_PIT_PCSR3       (*(vuint16*)(void*)(&__IPSBAR[0x180000]))\r
+#define MCF_PIT_PMR3        (*(vuint16*)(void*)(&__IPSBAR[0x180002]))\r
+#define MCF_PIT_PCNTR3      (*(vuint16*)(void*)(&__IPSBAR[0x180004]))\r
+#define MCF_PIT_PCSR(x)     (*(vuint16*)(void*)(&__IPSBAR[0x150000+((x)*0x10000)]))\r
+#define MCF_PIT_PMR(x)      (*(vuint16*)(void*)(&__IPSBAR[0x150002+((x)*0x10000)]))\r
+#define MCF_PIT_PCNTR(x)    (*(vuint16*)(void*)(&__IPSBAR[0x150004+((x)*0x10000)]))\r
+\r
+/* Bit definitions and macros for MCF_PIT_PCSR */\r
+#define MCF_PIT_PCSR_EN        (0x0001)\r
+#define MCF_PIT_PCSR_RLD       (0x0002)\r
+#define MCF_PIT_PCSR_PIF       (0x0004)\r
+#define MCF_PIT_PCSR_PIE       (0x0008)\r
+#define MCF_PIT_PCSR_OVW       (0x0010)\r
+#define MCF_PIT_PCSR_HALTED    (0x0020)\r
+#define MCF_PIT_PCSR_DOZE      (0x0040)\r
+#define MCF_PIT_PCSR_PRE(x)    (((x)&0x000F)<<8)\r
+\r
+/* Bit definitions and macros for MCF_PIT_PMR */\r
+#define MCF_PIT_PMR_PM0        (0x0001)\r
+#define MCF_PIT_PMR_PM1        (0x0002)\r
+#define MCF_PIT_PMR_PM2        (0x0004)\r
+#define MCF_PIT_PMR_PM3        (0x0008)\r
+#define MCF_PIT_PMR_PM4        (0x0010)\r
+#define MCF_PIT_PMR_PM5        (0x0020)\r
+#define MCF_PIT_PMR_PM6        (0x0040)\r
+#define MCF_PIT_PMR_PM7        (0x0080)\r
+#define MCF_PIT_PMR_PM8        (0x0100)\r
+#define MCF_PIT_PMR_PM9        (0x0200)\r
+#define MCF_PIT_PMR_PM10       (0x0400)\r
+#define MCF_PIT_PMR_PM11       (0x0800)\r
+#define MCF_PIT_PMR_PM12       (0x1000)\r
+#define MCF_PIT_PMR_PM13       (0x2000)\r
+#define MCF_PIT_PMR_PM14       (0x4000)\r
+#define MCF_PIT_PMR_PM15       (0x8000)\r
+\r
+/* Bit definitions and macros for MCF_PIT_PCNTR */\r
+#define MCF_PIT_PCNTR_PC0      (0x0001)\r
+#define MCF_PIT_PCNTR_PC1      (0x0002)\r
+#define MCF_PIT_PCNTR_PC2      (0x0004)\r
+#define MCF_PIT_PCNTR_PC3      (0x0008)\r
+#define MCF_PIT_PCNTR_PC4      (0x0010)\r
+#define MCF_PIT_PCNTR_PC5      (0x0020)\r
+#define MCF_PIT_PCNTR_PC6      (0x0040)\r
+#define MCF_PIT_PCNTR_PC7      (0x0080)\r
+#define MCF_PIT_PCNTR_PC8      (0x0100)\r
+#define MCF_PIT_PCNTR_PC9      (0x0200)\r
+#define MCF_PIT_PCNTR_PC10     (0x0400)\r
+#define MCF_PIT_PCNTR_PC11     (0x0800)\r
+#define MCF_PIT_PCNTR_PC12     (0x1000)\r
+#define MCF_PIT_PCNTR_PC13     (0x2000)\r
+#define MCF_PIT_PCNTR_PC14     (0x4000)\r
+#define MCF_PIT_PCNTR_PC15     (0x8000)\r
+\r
+/********************************************************************/\r
+\r
+#endif /* __MCF523X_PIT_H__ */\r
index ed32d6d40f068009e7b494e49adfa8c6c762cf68..9f05ada6113aaeef70d2e1cec43ae3faa43f6426 100644 (file)
@@ -1,69 +1,69 @@
-/*
- * These files are taken from the MCF523X source code example package
- * which is available on the Freescale website. Freescale explicitly 
- * grants the redistribution and modification of these source files.
- * The complete licensing information is available in the file 
- * LICENSE_FREESCALE.TXT.
- *
- * File:       mcf523x_qspi.h
- * Purpose:    Register and bit definitions for the MCF523X
- *
- * Notes:      
- *     
- */
-
-#ifndef __MCF523X_QSPI_H__
-#define __MCF523X_QSPI_H__
-
-/*********************************************************************
-*
-* Queued Serial Peripheral Interface (QSPI)
-*
-*********************************************************************/
-
-/* Register read/write macros */
-#define MCF_QSPI_QMR      (*(vuint16*)(void*)(&__IPSBAR[0x000340]))
-#define MCF_QSPI_QDLYR    (*(vuint16*)(void*)(&__IPSBAR[0x000344]))
-#define MCF_QSPI_QWR      (*(vuint16*)(void*)(&__IPSBAR[0x000348]))
-#define MCF_QSPI_QIR      (*(vuint16*)(void*)(&__IPSBAR[0x00034C]))
-#define MCF_QSPI_QAR      (*(vuint16*)(void*)(&__IPSBAR[0x000350]))
-#define MCF_QSPI_QDR      (*(vuint16*)(void*)(&__IPSBAR[0x000354]))
-
-/* Bit definitions and macros for MCF_QSPI_QMR */
-#define MCF_QSPI_QMR_BAUD(x)     (((x)&0x00FF)<<0)
-#define MCF_QSPI_QMR_CPHA        (0x0100)
-#define MCF_QSPI_QMR_CPOL        (0x0200)
-#define MCF_QSPI_QMR_BITS(x)     (((x)&0x000F)<<10)
-#define MCF_QSPI_QMR_DOHIE       (0x4000)
-#define MCF_QSPI_QMR_MSTR        (0x8000)
-
-/* Bit definitions and macros for MCF_QSPI_QDLYR */
-#define MCF_QSPI_QDLYR_DTL(x)    (((x)&0x00FF)<<0)
-#define MCF_QSPI_QDLYR_QCD(x)    (((x)&0x007F)<<8)
-#define MCF_QSPI_QDLYR_SPE       (0x8000)
-
-/* Bit definitions and macros for MCF_QSPI_QWR */
-#define MCF_QSPI_QWR_NEWQP(x)    (((x)&0x000F)<<0)
-#define MCF_QSPI_QWR_ENDQP(x)    (((x)&0x000F)<<8)
-#define MCF_QSPI_QWR_CSIV        (0x1000)
-#define MCF_QSPI_QWR_WRTO        (0x2000)
-#define MCF_QSPI_QWR_WREN        (0x4000)
-#define MCF_QSPI_QWR_HALT        (0x8000)
-
-/* Bit definitions and macros for MCF_QSPI_QIR */
-#define MCF_QSPI_QIR_SPIF        (0x0001)
-#define MCF_QSPI_QIR_ABRT        (0x0004)
-#define MCF_QSPI_QIR_WCEF        (0x0008)
-#define MCF_QSPI_QIR_SPIFE       (0x0100)
-#define MCF_QSPI_QIR_ABRTE       (0x0400)
-#define MCF_QSPI_QIR_WCEFE       (0x0800)
-#define MCF_QSPI_QIR_ABRTL       (0x1000)
-#define MCF_QSPI_QIR_ABRTB       (0x4000)
-#define MCF_QSPI_QIR_WCEFB       (0x8000)
-
-/* Bit definitions and macros for MCF_QSPI_QAR */
-#define MCF_QSPI_QAR_ADDR(x)     (((x)&0x003F)<<0)
-
-/********************************************************************/
-
-#endif /* __MCF523X_QSPI_H__ */
+/*\r
+ * These files are taken from the MCF523X source code example package\r
+ * which is available on the Freescale website. Freescale explicitly \r
+ * grants the redistribution and modification of these source files.\r
+ * The complete licensing information is available in the file \r
+ * LICENSE_FREESCALE.TXT.\r
+ *\r
+ * File:       mcf523x_qspi.h\r
+ * Purpose:    Register and bit definitions for the MCF523X\r
+ *\r
+ * Notes:      \r
+ *     \r
+ */\r
+\r
+#ifndef __MCF523X_QSPI_H__\r
+#define __MCF523X_QSPI_H__\r
+\r
+/*********************************************************************\r
+*\r
+* Queued Serial Peripheral Interface (QSPI)\r
+*\r
+*********************************************************************/\r
+\r
+/* Register read/write macros */\r
+#define MCF_QSPI_QMR      (*(vuint16*)(void*)(&__IPSBAR[0x000340]))\r
+#define MCF_QSPI_QDLYR    (*(vuint16*)(void*)(&__IPSBAR[0x000344]))\r
+#define MCF_QSPI_QWR      (*(vuint16*)(void*)(&__IPSBAR[0x000348]))\r
+#define MCF_QSPI_QIR      (*(vuint16*)(void*)(&__IPSBAR[0x00034C]))\r
+#define MCF_QSPI_QAR      (*(vuint16*)(void*)(&__IPSBAR[0x000350]))\r
+#define MCF_QSPI_QDR      (*(vuint16*)(void*)(&__IPSBAR[0x000354]))\r
+\r
+/* Bit definitions and macros for MCF_QSPI_QMR */\r
+#define MCF_QSPI_QMR_BAUD(x)     (((x)&0x00FF)<<0)\r
+#define MCF_QSPI_QMR_CPHA        (0x0100)\r
+#define MCF_QSPI_QMR_CPOL        (0x0200)\r
+#define MCF_QSPI_QMR_BITS(x)     (((x)&0x000F)<<10)\r
+#define MCF_QSPI_QMR_DOHIE       (0x4000)\r
+#define MCF_QSPI_QMR_MSTR        (0x8000)\r
+\r
+/* Bit definitions and macros for MCF_QSPI_QDLYR */\r
+#define MCF_QSPI_QDLYR_DTL(x)    (((x)&0x00FF)<<0)\r
+#define MCF_QSPI_QDLYR_QCD(x)    (((x)&0x007F)<<8)\r
+#define MCF_QSPI_QDLYR_SPE       (0x8000)\r
+\r
+/* Bit definitions and macros for MCF_QSPI_QWR */\r
+#define MCF_QSPI_QWR_NEWQP(x)    (((x)&0x000F)<<0)\r
+#define MCF_QSPI_QWR_ENDQP(x)    (((x)&0x000F)<<8)\r
+#define MCF_QSPI_QWR_CSIV        (0x1000)\r
+#define MCF_QSPI_QWR_WRTO        (0x2000)\r
+#define MCF_QSPI_QWR_WREN        (0x4000)\r
+#define MCF_QSPI_QWR_HALT        (0x8000)\r
+\r
+/* Bit definitions and macros for MCF_QSPI_QIR */\r
+#define MCF_QSPI_QIR_SPIF        (0x0001)\r
+#define MCF_QSPI_QIR_ABRT        (0x0004)\r
+#define MCF_QSPI_QIR_WCEF        (0x0008)\r
+#define MCF_QSPI_QIR_SPIFE       (0x0100)\r
+#define MCF_QSPI_QIR_ABRTE       (0x0400)\r
+#define MCF_QSPI_QIR_WCEFE       (0x0800)\r
+#define MCF_QSPI_QIR_ABRTL       (0x1000)\r
+#define MCF_QSPI_QIR_ABRTB       (0x4000)\r
+#define MCF_QSPI_QIR_WCEFB       (0x8000)\r
+\r
+/* Bit definitions and macros for MCF_QSPI_QAR */\r
+#define MCF_QSPI_QAR_ADDR(x)     (((x)&0x003F)<<0)\r
+\r
+/********************************************************************/\r
+\r
+#endif /* __MCF523X_QSPI_H__ */\r
index 784d0fab0a53bc5db1e5aab3884a3d3d213dff6b..cae92d22b2553ed93a1bd3a2e176c530a7da75f4 100644 (file)
@@ -1,42 +1,42 @@
-/*
- * These files are taken from the MCF523X source code example package
- * which is available on the Freescale website. Freescale explicitly 
- * grants the redistribution and modification of these source files.
- * The complete licensing information is available in the file 
- * LICENSE_FREESCALE.TXT.
- *
- * File:       mcf523x_rcm.h
- * Purpose:    Register and bit definitions for the MCF523X
- *
- * Notes:      
- *     
- */
-
-#ifndef __MCF523X_RCM_H__
-#define __MCF523X_RCM_H__
-
-/*********************************************************************
-*
-* Reset Configuration Module (RCM)
-*
-*********************************************************************/
-
-/* Register read/write macros */
-#define MCF_RCM_RCR    (*(vuint8 *)(void*)(&__IPSBAR[0x110000]))
-#define MCF_RCM_RSR    (*(vuint8 *)(void*)(&__IPSBAR[0x110001]))
-
-/* Bit definitions and macros for MCF_RCM_RCR */
-#define MCF_RCM_RCR_FRCRSTOUT    (0x40)
-#define MCF_RCM_RCR_SOFTRST      (0x80)
-
-/* Bit definitions and macros for MCF_RCM_RSR */
-#define MCF_RCM_RSR_LOL          (0x01)
-#define MCF_RCM_RSR_LOC          (0x02)
-#define MCF_RCM_RSR_EXT          (0x04)
-#define MCF_RCM_RSR_POR          (0x08)
-#define MCF_RCM_RSR_WDR          (0x10)
-#define MCF_RCM_RSR_SOFT         (0x20)
-
-/********************************************************************/
-
-#endif /* __MCF523X_RCM_H__ */
+/*\r
+ * These files are taken from the MCF523X source code example package\r
+ * which is available on the Freescale website. Freescale explicitly \r
+ * grants the redistribution and modification of these source files.\r
+ * The complete licensing information is available in the file \r
+ * LICENSE_FREESCALE.TXT.\r
+ *\r
+ * File:       mcf523x_rcm.h\r
+ * Purpose:    Register and bit definitions for the MCF523X\r
+ *\r
+ * Notes:      \r
+ *     \r
+ */\r
+\r
+#ifndef __MCF523X_RCM_H__\r
+#define __MCF523X_RCM_H__\r
+\r
+/*********************************************************************\r
+*\r
+* Reset Configuration Module (RCM)\r
+*\r
+*********************************************************************/\r
+\r
+/* Register read/write macros */\r
+#define MCF_RCM_RCR    (*(vuint8 *)(void*)(&__IPSBAR[0x110000]))\r
+#define MCF_RCM_RSR    (*(vuint8 *)(void*)(&__IPSBAR[0x110001]))\r
+\r
+/* Bit definitions and macros for MCF_RCM_RCR */\r
+#define MCF_RCM_RCR_FRCRSTOUT    (0x40)\r
+#define MCF_RCM_RCR_SOFTRST      (0x80)\r
+\r
+/* Bit definitions and macros for MCF_RCM_RSR */\r
+#define MCF_RCM_RSR_LOL          (0x01)\r
+#define MCF_RCM_RSR_LOC          (0x02)\r
+#define MCF_RCM_RSR_EXT          (0x04)\r
+#define MCF_RCM_RSR_POR          (0x08)\r
+#define MCF_RCM_RSR_WDR          (0x10)\r
+#define MCF_RCM_RSR_SOFT         (0x20)\r
+\r
+/********************************************************************/\r
+\r
+#endif /* __MCF523X_RCM_H__ */\r
index 744bd0ae351adf87e2f1e4aee0b6a61963b751e5..4bfca3d6cc20f44c584be8b904951a5a65bae934 100644 (file)
@@ -1,46 +1,46 @@
-/*
- * These files are taken from the MCF523X source code example package
- * which is available on the Freescale website. Freescale explicitly 
- * grants the redistribution and modification of these source files.
- * The complete licensing information is available in the file 
- * LICENSE_FREESCALE.TXT.
- *
- * File:       mcf523x_rng.h
- * Purpose:    Register and bit definitions for the MCF523X
- *
- * Notes:      
- *     
- */
-
-#ifndef __MCF523X_RNG_H__
-#define __MCF523X_RNG_H__
-
-/*********************************************************************
-*
-* Random Number Generator (RNG)
-*
-*********************************************************************/
-
-/* Register read/write macros */
-#define MCF_RNG_RNGCR     (*(vuint32*)(void*)(&__IPSBAR[0x1A0000]))
-#define MCF_RNG_RNGSR     (*(vuint32*)(void*)(&__IPSBAR[0x1A0004]))
-#define MCF_RNG_RNGER     (*(vuint32*)(void*)(&__IPSBAR[0x1A0008]))
-#define MCF_RNG_RNGOUT    (*(vuint32*)(void*)(&__IPSBAR[0x1A000C]))
-
-/* Bit definitions and macros for MCF_RNG_RNGCR */
-#define MCF_RNG_RNGCR_GO        (0x00000001)
-#define MCF_RNG_RNGCR_HA        (0x00000002)
-#define MCF_RNG_RNGCR_IM        (0x00000004)
-#define MCF_RNG_RNGCR_CI        (0x00000008)
-
-/* Bit definitions and macros for MCF_RNG_RNGSR */
-#define MCF_RNG_RNGSR_SV        (0x00000001)
-#define MCF_RNG_RNGSR_LRS       (0x00000002)
-#define MCF_RNG_RNGSR_FUF       (0x00000004)
-#define MCF_RNG_RNGSR_EI        (0x00000008)
-#define MCF_RNG_RNGSR_OFL(x)    (((x)&0x000000FF)<<8)
-#define MCF_RNG_RNGSR_OFS(x)    (((x)&0x000000FF)<<16)
-
-/********************************************************************/
-
-#endif /* __MCF523X_RNG_H__ */
+/*\r
+ * These files are taken from the MCF523X source code example package\r
+ * which is available on the Freescale website. Freescale explicitly \r
+ * grants the redistribution and modification of these source files.\r
+ * The complete licensing information is available in the file \r
+ * LICENSE_FREESCALE.TXT.\r
+ *\r
+ * File:       mcf523x_rng.h\r
+ * Purpose:    Register and bit definitions for the MCF523X\r
+ *\r
+ * Notes:      \r
+ *     \r
+ */\r
+\r
+#ifndef __MCF523X_RNG_H__\r
+#define __MCF523X_RNG_H__\r
+\r
+/*********************************************************************\r
+*\r
+* Random Number Generator (RNG)\r
+*\r
+*********************************************************************/\r
+\r
+/* Register read/write macros */\r
+#define MCF_RNG_RNGCR     (*(vuint32*)(void*)(&__IPSBAR[0x1A0000]))\r
+#define MCF_RNG_RNGSR     (*(vuint32*)(void*)(&__IPSBAR[0x1A0004]))\r
+#define MCF_RNG_RNGER     (*(vuint32*)(void*)(&__IPSBAR[0x1A0008]))\r
+#define MCF_RNG_RNGOUT    (*(vuint32*)(void*)(&__IPSBAR[0x1A000C]))\r
+\r
+/* Bit definitions and macros for MCF_RNG_RNGCR */\r
+#define MCF_RNG_RNGCR_GO        (0x00000001)\r
+#define MCF_RNG_RNGCR_HA        (0x00000002)\r
+#define MCF_RNG_RNGCR_IM        (0x00000004)\r
+#define MCF_RNG_RNGCR_CI        (0x00000008)\r
+\r
+/* Bit definitions and macros for MCF_RNG_RNGSR */\r
+#define MCF_RNG_RNGSR_SV        (0x00000001)\r
+#define MCF_RNG_RNGSR_LRS       (0x00000002)\r
+#define MCF_RNG_RNGSR_FUF       (0x00000004)\r
+#define MCF_RNG_RNGSR_EI        (0x00000008)\r
+#define MCF_RNG_RNGSR_OFL(x)    (((x)&0x000000FF)<<8)\r
+#define MCF_RNG_RNGSR_OFS(x)    (((x)&0x000000FF)<<16)\r
+\r
+/********************************************************************/\r
+\r
+#endif /* __MCF523X_RNG_H__ */\r
index d9ef0f0eb4f518b71a287786434bf722519686d2..e330ee990f3b7b37afda14069a4e0573335d6a78 100644 (file)
-/*
- * These files are taken from the MCF523X source code example package
- * which is available on the Freescale website. Freescale explicitly 
- * grants the redistribution and modification of these source files.
- * The complete licensing information is available in the file 
- * LICENSE_FREESCALE.TXT.
- *
- * File:       mcf523x_scm.h
- * Purpose:    Register and bit definitions for the MCF523X
- *
- * Notes:      
- *     
- */
-
-#ifndef __MCF523X_SCM_H__
-#define __MCF523X_SCM_H__
-
-/*********************************************************************
-*
-* System Control Module (SCM)
-*
-*********************************************************************/
-
-/* Register read/write macros */
-#define MCF_SCM_IPSBAR     (*(vuint32*)(void*)(&__IPSBAR[0x000000]))
-#define MCF_SCM_RAMBAR     (*(vuint32*)(void*)(&__IPSBAR[0x000008]))
-#define MCF_SCM_CRSR       (*(vuint8 *)(void*)(&__IPSBAR[0x000010]))
-#define MCF_SCM_CWCR       (*(vuint8 *)(void*)(&__IPSBAR[0x000011]))
-#define MCF_SCM_LPICR      (*(vuint8 *)(void*)(&__IPSBAR[0x000012]))
-#define MCF_SCM_CWSR       (*(vuint8 *)(void*)(&__IPSBAR[0x000013]))
-#define MCF_SCM_DMAREQC    (*(vuint32*)(void*)(&__IPSBAR[0x000014]))
-#define MCF_SCM_MPARK      (*(vuint32*)(void*)(&__IPSBAR[0x00001C]))
-#define MCF_SCM_MPR        (*(vuint8 *)(void*)(&__IPSBAR[0x000020]))
-#define MCF_SCM_PACR0      (*(vuint8 *)(void*)(&__IPSBAR[0x000024]))
-#define MCF_SCM_PACR1      (*(vuint8 *)(void*)(&__IPSBAR[0x000025]))
-#define MCF_SCM_PACR2      (*(vuint8 *)(void*)(&__IPSBAR[0x000026]))
-#define MCF_SCM_PACR3      (*(vuint8 *)(void*)(&__IPSBAR[0x000027]))
-#define MCF_SCM_PACR4      (*(vuint8 *)(void*)(&__IPSBAR[0x000028]))
-#define MCF_SCM_PACR5      (*(vuint8 *)(void*)(&__IPSBAR[0x00002A]))
-#define MCF_SCM_PACR6      (*(vuint8 *)(void*)(&__IPSBAR[0x00002B]))
-#define MCF_SCM_PACR7      (*(vuint8 *)(void*)(&__IPSBAR[0x00002C]))
-#define MCF_SCM_PACR8      (*(vuint8 *)(void*)(&__IPSBAR[0x00002E]))
-#define MCF_SCM_GPACR0     (*(vuint8 *)(void*)(&__IPSBAR[0x000030]))
-
-/* Bit definitions and macros for MCF_SCM_IPSBAR */
-#define MCF_SCM_IPSBAR_V                 (0x00000001)
-#define MCF_SCM_IPSBAR_BA(x)             (((x)&0x00000003)<<30)
-
-/* Bit definitions and macros for MCF_SCM_RAMBAR */
-#define MCF_SCM_RAMBAR_BDE               (0x00000200)
-#define MCF_SCM_RAMBAR_BA(x)             (((x)&0x0000FFFF)<<16)
-
-/* Bit definitions and macros for MCF_SCM_CRSR */
-#define MCF_SCM_CRSR_CWDR                (0x20)
-#define MCF_SCM_CRSR_EXT                 (0x80)
-
-/* Bit definitions and macros for MCF_SCM_CWCR */
-#define MCF_SCM_CWCR_CWTIC               (0x01)
-#define MCF_SCM_CWCR_CWTAVAL             (0x02)
-#define MCF_SCM_CWCR_CWTA                (0x04)
-#define MCF_SCM_CWCR_CWT(x)              (((x)&0x07)<<3)
-#define MCF_SCM_CWCR_CWRI                (0x40)
-#define MCF_SCM_CWCR_CWE                 (0x80)
-
-/* Bit definitions and macros for MCF_SCM_LPICR */
-#define MCF_SCM_LPICR_XLPM_IPL(x)        (((x)&0x07)<<4)
-#define MCF_SCM_LPICR_ENBSTOP            (0x80)
-
-/* Bit definitions and macros for MCF_SCM_DMAREQC */
-#define MCF_SCM_DMAREQC_DMAC0(x)         (((x)&0x0000000F)<<0)
-#define MCF_SCM_DMAREQC_DMAC1(x)         (((x)&0x0000000F)<<4)
-#define MCF_SCM_DMAREQC_DMAC2(x)         (((x)&0x0000000F)<<8)
-#define MCF_SCM_DMAREQC_DMAC3(x)         (((x)&0x0000000F)<<12)
-
-/* Bit definitions and macros for MCF_SCM_MPARK */
-#define MCF_SCM_MPARK_LCKOUT_TIME(x)     (((x)&0x0000000F)<<8)
-#define MCF_SCM_MPARK_PRKLAST            (0x00001000)
-#define MCF_SCM_MPARK_TIMEOUT            (0x00002000)
-#define MCF_SCM_MPARK_FIXED              (0x00004000)
-#define MCF_SCM_MPARK_M1_PRTY(x)         (((x)&0x00000003)<<16)
-#define MCF_SCM_MPARK_M0_PRTY(x)         (((x)&0x00000003)<<18)
-#define MCF_SCM_MPARK_M2_PRTY(x)         (((x)&0x00000003)<<20)
-#define MCF_SCM_MPARK_M3_PRTY(x)         (((x)&0x00000003)<<22)
-#define MCF_SCM_MPARK_BCR24BIT           (0x01000000)
-#define MCF_SCM_MPARK_M2_P_EN            (0x02000000)
-
-/* Bit definitions and macros for MCF_SCM_MPR */
-#define MCF_SCM_MPR_MPR(x)               (((x)&0x0F)<<0)
-
-/* Bit definitions and macros for MCF_SCM_PACR0 */
-#define MCF_SCM_PACR0_ACCESS_CTRL0(x)    (((x)&0x07)<<0)
-#define MCF_SCM_PACR0_LOCK0              (0x08)
-#define MCF_SCM_PACR0_ACCESS_CTRL1(x)    (((x)&0x07)<<4)
-#define MCF_SCM_PACR0_LOCK1              (0x80)
-
-/* Bit definitions and macros for MCF_SCM_PACR1 */
-#define MCF_SCM_PACR1_ACCESS_CTRL0(x)    (((x)&0x07)<<0)
-#define MCF_SCM_PACR1_LOCK0              (0x08)
-#define MCF_SCM_PACR1_ACCESS_CTRL1(x)    (((x)&0x07)<<4)
-#define MCF_SCM_PACR1_LOCK1              (0x80)
-
-/* Bit definitions and macros for MCF_SCM_PACR2 */
-#define MCF_SCM_PACR2_ACCESS_CTRL0(x)    (((x)&0x07)<<0)
-#define MCF_SCM_PACR2_LOCK0              (0x08)
-#define MCF_SCM_PACR2_ACCESS_CTRL1(x)    (((x)&0x07)<<4)
-#define MCF_SCM_PACR2_LOCK1              (0x80)
-
-/* Bit definitions and macros for MCF_SCM_PACR3 */
-#define MCF_SCM_PACR3_ACCESS_CTRL0(x)    (((x)&0x07)<<0)
-#define MCF_SCM_PACR3_LOCK0              (0x08)
-#define MCF_SCM_PACR3_ACCESS_CTRL1(x)    (((x)&0x07)<<4)
-#define MCF_SCM_PACR3_LOCK1              (0x80)
-
-/* Bit definitions and macros for MCF_SCM_PACR4 */
-#define MCF_SCM_PACR4_ACCESS_CTRL0(x)    (((x)&0x07)<<0)
-#define MCF_SCM_PACR4_LOCK0              (0x08)
-#define MCF_SCM_PACR4_ACCESS_CTRL1(x)    (((x)&0x07)<<4)
-#define MCF_SCM_PACR4_LOCK1              (0x80)
-
-/* Bit definitions and macros for MCF_SCM_PACR5 */
-#define MCF_SCM_PACR5_ACCESS_CTRL0(x)    (((x)&0x07)<<0)
-#define MCF_SCM_PACR5_LOCK0              (0x08)
-#define MCF_SCM_PACR5_ACCESS_CTRL1(x)    (((x)&0x07)<<4)
-#define MCF_SCM_PACR5_LOCK1              (0x80)
-
-/* Bit definitions and macros for MCF_SCM_PACR6 */
-#define MCF_SCM_PACR6_ACCESS_CTRL0(x)    (((x)&0x07)<<0)
-#define MCF_SCM_PACR6_LOCK0              (0x08)
-#define MCF_SCM_PACR6_ACCESS_CTRL1(x)    (((x)&0x07)<<4)
-#define MCF_SCM_PACR6_LOCK1              (0x80)
-
-/* Bit definitions and macros for MCF_SCM_PACR7 */
-#define MCF_SCM_PACR7_ACCESS_CTRL0(x)    (((x)&0x07)<<0)
-#define MCF_SCM_PACR7_LOCK0              (0x08)
-#define MCF_SCM_PACR7_ACCESS_CTRL1(x)    (((x)&0x07)<<4)
-#define MCF_SCM_PACR7_LOCK1              (0x80)
-
-/* Bit definitions and macros for MCF_SCM_PACR8 */
-#define MCF_SCM_PACR8_ACCESS_CTRL0(x)    (((x)&0x07)<<0)
-#define MCF_SCM_PACR8_LOCK0              (0x08)
-#define MCF_SCM_PACR8_ACCESS_CTRL1(x)    (((x)&0x07)<<4)
-#define MCF_SCM_PACR8_LOCK1              (0x80)
-
-/* Bit definitions and macros for MCF_SCM_GPACR0 */
-#define MCF_SCM_GPACR0_ACCESS_CTRL(x)    (((x)&0x0F)<<0)
-#define MCF_SCM_GPACR0_LOCK              (0x80)
-
-/********************************************************************/
-
-#endif /* __MCF523X_SCM_H__ */
+/*\r
+ * These files are taken from the MCF523X source code example package\r
+ * which is available on the Freescale website. Freescale explicitly \r
+ * grants the redistribution and modification of these source files.\r
+ * The complete licensing information is available in the file \r
+ * LICENSE_FREESCALE.TXT.\r
+ *\r
+ * File:       mcf523x_scm.h\r
+ * Purpose:    Register and bit definitions for the MCF523X\r
+ *\r
+ * Notes:      \r
+ *     \r
+ */\r
+\r
+#ifndef __MCF523X_SCM_H__\r
+#define __MCF523X_SCM_H__\r
+\r
+/*********************************************************************\r
+*\r
+* System Control Module (SCM)\r
+*\r
+*********************************************************************/\r
+\r
+/* Register read/write macros */\r
+#define MCF_SCM_IPSBAR     (*(vuint32*)(void*)(&__IPSBAR[0x000000]))\r
+#define MCF_SCM_RAMBAR     (*(vuint32*)(void*)(&__IPSBAR[0x000008]))\r
+#define MCF_SCM_CRSR       (*(vuint8 *)(void*)(&__IPSBAR[0x000010]))\r
+#define MCF_SCM_CWCR       (*(vuint8 *)(void*)(&__IPSBAR[0x000011]))\r
+#define MCF_SCM_LPICR      (*(vuint8 *)(void*)(&__IPSBAR[0x000012]))\r
+#define MCF_SCM_CWSR       (*(vuint8 *)(void*)(&__IPSBAR[0x000013]))\r
+#define MCF_SCM_DMAREQC    (*(vuint32*)(void*)(&__IPSBAR[0x000014]))\r
+#define MCF_SCM_MPARK      (*(vuint32*)(void*)(&__IPSBAR[0x00001C]))\r
+#define MCF_SCM_MPR        (*(vuint8 *)(void*)(&__IPSBAR[0x000020]))\r
+#define MCF_SCM_PACR0      (*(vuint8 *)(void*)(&__IPSBAR[0x000024]))\r
+#define MCF_SCM_PACR1      (*(vuint8 *)(void*)(&__IPSBAR[0x000025]))\r
+#define MCF_SCM_PACR2      (*(vuint8 *)(void*)(&__IPSBAR[0x000026]))\r
+#define MCF_SCM_PACR3      (*(vuint8 *)(void*)(&__IPSBAR[0x000027]))\r
+#define MCF_SCM_PACR4      (*(vuint8 *)(void*)(&__IPSBAR[0x000028]))\r
+#define MCF_SCM_PACR5      (*(vuint8 *)(void*)(&__IPSBAR[0x00002A]))\r
+#define MCF_SCM_PACR6      (*(vuint8 *)(void*)(&__IPSBAR[0x00002B]))\r
+#define MCF_SCM_PACR7      (*(vuint8 *)(void*)(&__IPSBAR[0x00002C]))\r
+#define MCF_SCM_PACR8      (*(vuint8 *)(void*)(&__IPSBAR[0x00002E]))\r
+#define MCF_SCM_GPACR0     (*(vuint8 *)(void*)(&__IPSBAR[0x000030]))\r
+\r
+/* Bit definitions and macros for MCF_SCM_IPSBAR */\r
+#define MCF_SCM_IPSBAR_V                 (0x00000001)\r
+#define MCF_SCM_IPSBAR_BA(x)             (((x)&0x00000003)<<30)\r
+\r
+/* Bit definitions and macros for MCF_SCM_RAMBAR */\r
+#define MCF_SCM_RAMBAR_BDE               (0x00000200)\r
+#define MCF_SCM_RAMBAR_BA(x)             (((x)&0x0000FFFF)<<16)\r
+\r
+/* Bit definitions and macros for MCF_SCM_CRSR */\r
+#define MCF_SCM_CRSR_CWDR                (0x20)\r
+#define MCF_SCM_CRSR_EXT                 (0x80)\r
+\r
+/* Bit definitions and macros for MCF_SCM_CWCR */\r
+#define MCF_SCM_CWCR_CWTIC               (0x01)\r
+#define MCF_SCM_CWCR_CWTAVAL             (0x02)\r
+#define MCF_SCM_CWCR_CWTA                (0x04)\r
+#define MCF_SCM_CWCR_CWT(x)              (((x)&0x07)<<3)\r
+#define MCF_SCM_CWCR_CWRI                (0x40)\r
+#define MCF_SCM_CWCR_CWE                 (0x80)\r
+\r
+/* Bit definitions and macros for MCF_SCM_LPICR */\r
+#define MCF_SCM_LPICR_XLPM_IPL(x)        (((x)&0x07)<<4)\r
+#define MCF_SCM_LPICR_ENBSTOP            (0x80)\r
+\r
+/* Bit definitions and macros for MCF_SCM_DMAREQC */\r
+#define MCF_SCM_DMAREQC_DMAC0(x)         (((x)&0x0000000F)<<0)\r
+#define MCF_SCM_DMAREQC_DMAC1(x)         (((x)&0x0000000F)<<4)\r
+#define MCF_SCM_DMAREQC_DMAC2(x)         (((x)&0x0000000F)<<8)\r
+#define MCF_SCM_DMAREQC_DMAC3(x)         (((x)&0x0000000F)<<12)\r
+\r
+/* Bit definitions and macros for MCF_SCM_MPARK */\r
+#define MCF_SCM_MPARK_LCKOUT_TIME(x)     (((x)&0x0000000F)<<8)\r
+#define MCF_SCM_MPARK_PRKLAST            (0x00001000)\r
+#define MCF_SCM_MPARK_TIMEOUT            (0x00002000)\r
+#define MCF_SCM_MPARK_FIXED              (0x00004000)\r
+#define MCF_SCM_MPARK_M1_PRTY(x)         (((x)&0x00000003)<<16)\r
+#define MCF_SCM_MPARK_M0_PRTY(x)         (((x)&0x00000003)<<18)\r
+#define MCF_SCM_MPARK_M2_PRTY(x)         (((x)&0x00000003)<<20)\r
+#define MCF_SCM_MPARK_M3_PRTY(x)         (((x)&0x00000003)<<22)\r
+#define MCF_SCM_MPARK_BCR24BIT           (0x01000000)\r
+#define MCF_SCM_MPARK_M2_P_EN            (0x02000000)\r
+\r
+/* Bit definitions and macros for MCF_SCM_MPR */\r
+#define MCF_SCM_MPR_MPR(x)               (((x)&0x0F)<<0)\r
+\r
+/* Bit definitions and macros for MCF_SCM_PACR0 */\r
+#define MCF_SCM_PACR0_ACCESS_CTRL0(x)    (((x)&0x07)<<0)\r
+#define MCF_SCM_PACR0_LOCK0              (0x08)\r
+#define MCF_SCM_PACR0_ACCESS_CTRL1(x)    (((x)&0x07)<<4)\r
+#define MCF_SCM_PACR0_LOCK1              (0x80)\r
+\r
+/* Bit definitions and macros for MCF_SCM_PACR1 */\r
+#define MCF_SCM_PACR1_ACCESS_CTRL0(x)    (((x)&0x07)<<0)\r
+#define MCF_SCM_PACR1_LOCK0              (0x08)\r
+#define MCF_SCM_PACR1_ACCESS_CTRL1(x)    (((x)&0x07)<<4)\r
+#define MCF_SCM_PACR1_LOCK1              (0x80)\r
+\r
+/* Bit definitions and macros for MCF_SCM_PACR2 */\r
+#define MCF_SCM_PACR2_ACCESS_CTRL0(x)    (((x)&0x07)<<0)\r
+#define MCF_SCM_PACR2_LOCK0              (0x08)\r
+#define MCF_SCM_PACR2_ACCESS_CTRL1(x)    (((x)&0x07)<<4)\r
+#define MCF_SCM_PACR2_LOCK1              (0x80)\r
+\r
+/* Bit definitions and macros for MCF_SCM_PACR3 */\r
+#define MCF_SCM_PACR3_ACCESS_CTRL0(x)    (((x)&0x07)<<0)\r
+#define MCF_SCM_PACR3_LOCK0              (0x08)\r
+#define MCF_SCM_PACR3_ACCESS_CTRL1(x)    (((x)&0x07)<<4)\r
+#define MCF_SCM_PACR3_LOCK1              (0x80)\r
+\r
+/* Bit definitions and macros for MCF_SCM_PACR4 */\r
+#define MCF_SCM_PACR4_ACCESS_CTRL0(x)    (((x)&0x07)<<0)\r
+#define MCF_SCM_PACR4_LOCK0              (0x08)\r
+#define MCF_SCM_PACR4_ACCESS_CTRL1(x)    (((x)&0x07)<<4)\r
+#define MCF_SCM_PACR4_LOCK1              (0x80)\r
+\r
+/* Bit definitions and macros for MCF_SCM_PACR5 */\r
+#define MCF_SCM_PACR5_ACCESS_CTRL0(x)    (((x)&0x07)<<0)\r
+#define MCF_SCM_PACR5_LOCK0              (0x08)\r
+#define MCF_SCM_PACR5_ACCESS_CTRL1(x)    (((x)&0x07)<<4)\r
+#define MCF_SCM_PACR5_LOCK1              (0x80)\r
+\r
+/* Bit definitions and macros for MCF_SCM_PACR6 */\r
+#define MCF_SCM_PACR6_ACCESS_CTRL0(x)    (((x)&0x07)<<0)\r
+#define MCF_SCM_PACR6_LOCK0              (0x08)\r
+#define MCF_SCM_PACR6_ACCESS_CTRL1(x)    (((x)&0x07)<<4)\r
+#define MCF_SCM_PACR6_LOCK1              (0x80)\r
+\r
+/* Bit definitions and macros for MCF_SCM_PACR7 */\r
+#define MCF_SCM_PACR7_ACCESS_CTRL0(x)    (((x)&0x07)<<0)\r
+#define MCF_SCM_PACR7_LOCK0              (0x08)\r
+#define MCF_SCM_PACR7_ACCESS_CTRL1(x)    (((x)&0x07)<<4)\r
+#define MCF_SCM_PACR7_LOCK1              (0x80)\r
+\r
+/* Bit definitions and macros for MCF_SCM_PACR8 */\r
+#define MCF_SCM_PACR8_ACCESS_CTRL0(x)    (((x)&0x07)<<0)\r
+#define MCF_SCM_PACR8_LOCK0              (0x08)\r
+#define MCF_SCM_PACR8_ACCESS_CTRL1(x)    (((x)&0x07)<<4)\r
+#define MCF_SCM_PACR8_LOCK1              (0x80)\r
+\r
+/* Bit definitions and macros for MCF_SCM_GPACR0 */\r
+#define MCF_SCM_GPACR0_ACCESS_CTRL(x)    (((x)&0x0F)<<0)\r
+#define MCF_SCM_GPACR0_LOCK              (0x80)\r
+\r
+/********************************************************************/\r
+\r
+#endif /* __MCF523X_SCM_H__ */\r
index dbf38f8b609804bbbeb4d3e4ba183d40f1e35e12..87eb0acef618b335a64483115b404b4e5091e298 100644 (file)
@@ -1,94 +1,94 @@
-/*
- * These files are taken from the MCF523X source code example package
- * which is available on the Freescale website. Freescale explicitly 
- * grants the redistribution and modification of these source files.
- * The complete licensing information is available in the file 
- * LICENSE_FREESCALE.TXT.
- *
- * File:       mcf523x_sdramc.h
- * Purpose:    Register and bit definitions for the MCF523X
- *
- * Notes:      
- *     
- */
-
-#ifndef __MCF523X_SDRAMC_H__
-#define __MCF523X_SDRAMC_H__
-
-/*********************************************************************
-*
-* SDRAM Controller (SDRAMC)
-*
-*********************************************************************/
-
-/* Register read/write macros */
-#define MCF_SDRAMC_DCR      (*(vuint16*)(void*)(&__IPSBAR[0x000040]))
-#define MCF_SDRAMC_DACR0    (*(vuint32*)(void*)(&__IPSBAR[0x000048]))
-#define MCF_SDRAMC_DMR0     (*(vuint32*)(void*)(&__IPSBAR[0x00004C]))
-#define MCF_SDRAMC_DACR1    (*(vuint32*)(void*)(&__IPSBAR[0x000050]))
-#define MCF_SDRAMC_DMR1     (*(vuint32*)(void*)(&__IPSBAR[0x000054]))
-
-/* Bit definitions and macros for MCF_SDRAMC_DCR */
-#define MCF_SDRAMC_DCR_RC(x)        (((x)&0x01FF)<<0)
-#define MCF_SDRAMC_DCR_RTIM(x)      (((x)&0x0003)<<9)
-#define MCF_SDRAMC_DCR_IS           (0x0800)
-#define MCF_SDRAMC_DCR_COC          (0x1000)
-#define MCF_SDRAMC_DCR_NAM          (0x2000)
-
-/* Bit definitions and macros for MCF_SDRAMC_DACR0 */
-#define MCF_SDRAMC_DACR0_IP         (0x00000008)
-#define MCF_SDRAMC_DACR0_PS(x)      (((x)&0x00000003)<<4)
-#define MCF_SDRAMC_DACR0_MRS        (0x00000040)
-#define MCF_SDRAMC_DACR0_CBM(x)     (((x)&0x00000007)<<8)
-#define MCF_SDRAMC_DACR0_CASL(x)    (((x)&0x00000003)<<12)
-#define MCF_SDRAMC_DACR0_RE         (0x00008000)
-#define MCF_SDRAMC_DACR0_BA(x)      (((x)&0x00003FFF)<<18)
-
-/* Bit definitions and macros for MCF_SDRAMC_DMR0 */
-#define MCF_SDRAMC_DMR0_V           (0x00000001)
-#define MCF_SDRAMC_DMR0_WP          (0x00000100)
-#define MCF_SDRAMC_DMR0_BAM(x)      (((x)&0x00003FFF)<<18)
-
-/* Bit definitions and macros for MCF_SDRAMC_DACR1 */
-#define MCF_SDRAMC_DACR1_IP         (0x00000008)
-#define MCF_SDRAMC_DACR1_PS(x)      (((x)&0x00000003)<<4)
-#define MCF_SDRAMC_DACR1_MRS        (0x00000040)
-#define MCF_SDRAMC_DACR1_CBM(x)     (((x)&0x00000007)<<8)
-#define MCF_SDRAMC_DACR1_CASL(x)    (((x)&0x00000003)<<12)
-#define MCF_SDRAMC_DACR1_RE         (0x00008000)
-#define MCF_SDRAMC_DACR1_BA(x)      (((x)&0x00003FFF)<<18)
-
-/* Bit definitions and macros for MCF_SDRAMC_DMR1 */
-#define MCF_SDRAMC_DMR1_V           (0x00000001)
-#define MCF_SDRAMC_DMR1_WP          (0x00000100)
-#define MCF_SDRAMC_DMR1_BAM(x)      (((x)&0x00003FFF)<<18)
-
-/********************************************************************/
-
-#define MCF_SDRAMC_DMR_BAM_4G                  (0xFFFC0000)
-#define MCF_SDRAMC_DMR_BAM_2G                  (0x7FFC0000)
-#define MCF_SDRAMC_DMR_BAM_1G                  (0x3FFC0000)
-#define MCF_SDRAMC_DMR_BAM_1024M               (0x3FFC0000)
-#define MCF_SDRAMC_DMR_BAM_512M                        (0x1FFC0000)
-#define MCF_SDRAMC_DMR_BAM_256M                        (0x0FFC0000)
-#define MCF_SDRAMC_DMR_BAM_128M                        (0x07FC0000)
-#define MCF_SDRAMC_DMR_BAM_64M                 (0x03FC0000)
-#define MCF_SDRAMC_DMR_BAM_32M                 (0x01FC0000)
-#define MCF_SDRAMC_DMR_BAM_16M                 (0x00FC0000)
-#define MCF_SDRAMC_DMR_BAM_8M                  (0x007C0000)
-#define MCF_SDRAMC_DMR_BAM_4M                  (0x003C0000)
-#define MCF_SDRAMC_DMR_BAM_2M                  (0x001C0000)
-#define MCF_SDRAMC_DMR_BAM_1M                  (0x000C0000)
-#define MCF_SDRAMC_DMR_BAM_1024K               (0x000C0000)
-#define MCF_SDRAMC_DMR_BAM_512K                        (0x00040000)
-#define MCF_SDRAMC_DMR_BAM_256K                        (0x00000000)
-#define MCF_SDRAMC_DMR_WP                              (0x00000100)
-#define MCF_SDRAMC_DMR_CI                              (0x00000040)
-#define MCF_SDRAMC_DMR_AM                              (0x00000020)
-#define MCF_SDRAMC_DMR_SC                              (0x00000010)
-#define MCF_SDRAMC_DMR_SD                              (0x00000008)
-#define MCF_SDRAMC_DMR_UC                              (0x00000004)
-#define MCF_SDRAMC_DMR_UD                              (0x00000002)
-#define MCF_SDRAMC_DMR_V                               (0x00000001)
-
-#endif /* __MCF523X_SDRAMC_H__ */
+/*\r
+ * These files are taken from the MCF523X source code example package\r
+ * which is available on the Freescale website. Freescale explicitly \r
+ * grants the redistribution and modification of these source files.\r
+ * The complete licensing information is available in the file \r
+ * LICENSE_FREESCALE.TXT.\r
+ *\r
+ * File:       mcf523x_sdramc.h\r
+ * Purpose:    Register and bit definitions for the MCF523X\r
+ *\r
+ * Notes:      \r
+ *     \r
+ */\r
+\r
+#ifndef __MCF523X_SDRAMC_H__\r
+#define __MCF523X_SDRAMC_H__\r
+\r
+/*********************************************************************\r
+*\r
+* SDRAM Controller (SDRAMC)\r
+*\r
+*********************************************************************/\r
+\r
+/* Register read/write macros */\r
+#define MCF_SDRAMC_DCR      (*(vuint16*)(void*)(&__IPSBAR[0x000040]))\r
+#define MCF_SDRAMC_DACR0    (*(vuint32*)(void*)(&__IPSBAR[0x000048]))\r
+#define MCF_SDRAMC_DMR0     (*(vuint32*)(void*)(&__IPSBAR[0x00004C]))\r
+#define MCF_SDRAMC_DACR1    (*(vuint32*)(void*)(&__IPSBAR[0x000050]))\r
+#define MCF_SDRAMC_DMR1     (*(vuint32*)(void*)(&__IPSBAR[0x000054]))\r
+\r
+/* Bit definitions and macros for MCF_SDRAMC_DCR */\r
+#define MCF_SDRAMC_DCR_RC(x)        (((x)&0x01FF)<<0)\r
+#define MCF_SDRAMC_DCR_RTIM(x)      (((x)&0x0003)<<9)\r
+#define MCF_SDRAMC_DCR_IS           (0x0800)\r
+#define MCF_SDRAMC_DCR_COC          (0x1000)\r
+#define MCF_SDRAMC_DCR_NAM          (0x2000)\r
+\r
+/* Bit definitions and macros for MCF_SDRAMC_DACR0 */\r
+#define MCF_SDRAMC_DACR0_IP         (0x00000008)\r
+#define MCF_SDRAMC_DACR0_PS(x)      (((x)&0x00000003)<<4)\r
+#define MCF_SDRAMC_DACR0_MRS        (0x00000040)\r
+#define MCF_SDRAMC_DACR0_CBM(x)     (((x)&0x00000007)<<8)\r
+#define MCF_SDRAMC_DACR0_CASL(x)    (((x)&0x00000003)<<12)\r
+#define MCF_SDRAMC_DACR0_RE         (0x00008000)\r
+#define MCF_SDRAMC_DACR0_BA(x)      (((x)&0x00003FFF)<<18)\r
+\r
+/* Bit definitions and macros for MCF_SDRAMC_DMR0 */\r
+#define MCF_SDRAMC_DMR0_V           (0x00000001)\r
+#define MCF_SDRAMC_DMR0_WP          (0x00000100)\r
+#define MCF_SDRAMC_DMR0_BAM(x)      (((x)&0x00003FFF)<<18)\r
+\r
+/* Bit definitions and macros for MCF_SDRAMC_DACR1 */\r
+#define MCF_SDRAMC_DACR1_IP         (0x00000008)\r
+#define MCF_SDRAMC_DACR1_PS(x)      (((x)&0x00000003)<<4)\r
+#define MCF_SDRAMC_DACR1_MRS        (0x00000040)\r
+#define MCF_SDRAMC_DACR1_CBM(x)     (((x)&0x00000007)<<8)\r
+#define MCF_SDRAMC_DACR1_CASL(x)    (((x)&0x00000003)<<12)\r
+#define MCF_SDRAMC_DACR1_RE         (0x00008000)\r
+#define MCF_SDRAMC_DACR1_BA(x)      (((x)&0x00003FFF)<<18)\r
+\r
+/* Bit definitions and macros for MCF_SDRAMC_DMR1 */\r
+#define MCF_SDRAMC_DMR1_V           (0x00000001)\r
+#define MCF_SDRAMC_DMR1_WP          (0x00000100)\r
+#define MCF_SDRAMC_DMR1_BAM(x)      (((x)&0x00003FFF)<<18)\r
+\r
+/********************************************************************/\r
+\r
+#define MCF_SDRAMC_DMR_BAM_4G                  (0xFFFC0000)\r
+#define MCF_SDRAMC_DMR_BAM_2G                  (0x7FFC0000)\r
+#define MCF_SDRAMC_DMR_BAM_1G                  (0x3FFC0000)\r
+#define MCF_SDRAMC_DMR_BAM_1024M               (0x3FFC0000)\r
+#define MCF_SDRAMC_DMR_BAM_512M                        (0x1FFC0000)\r
+#define MCF_SDRAMC_DMR_BAM_256M                        (0x0FFC0000)\r
+#define MCF_SDRAMC_DMR_BAM_128M                        (0x07FC0000)\r
+#define MCF_SDRAMC_DMR_BAM_64M                 (0x03FC0000)\r
+#define MCF_SDRAMC_DMR_BAM_32M                 (0x01FC0000)\r
+#define MCF_SDRAMC_DMR_BAM_16M                 (0x00FC0000)\r
+#define MCF_SDRAMC_DMR_BAM_8M                  (0x007C0000)\r
+#define MCF_SDRAMC_DMR_BAM_4M                  (0x003C0000)\r
+#define MCF_SDRAMC_DMR_BAM_2M                  (0x001C0000)\r
+#define MCF_SDRAMC_DMR_BAM_1M                  (0x000C0000)\r
+#define MCF_SDRAMC_DMR_BAM_1024K               (0x000C0000)\r
+#define MCF_SDRAMC_DMR_BAM_512K                        (0x00040000)\r
+#define MCF_SDRAMC_DMR_BAM_256K                        (0x00000000)\r
+#define MCF_SDRAMC_DMR_WP                              (0x00000100)\r
+#define MCF_SDRAMC_DMR_CI                              (0x00000040)\r
+#define MCF_SDRAMC_DMR_AM                              (0x00000020)\r
+#define MCF_SDRAMC_DMR_SC                              (0x00000010)\r
+#define MCF_SDRAMC_DMR_SD                              (0x00000008)\r
+#define MCF_SDRAMC_DMR_UC                              (0x00000004)\r
+#define MCF_SDRAMC_DMR_UD                              (0x00000002)\r
+#define MCF_SDRAMC_DMR_V                               (0x00000001)\r
+\r
+#endif /* __MCF523X_SDRAMC_H__ */\r
index e03d2e05c7b840a67b411fce62c2cb9a058d5807..ae4dc57abb98aa82e01a2bb600b835296d09e618 100644 (file)
-/*
- * These files are taken from the MCF523X source code example package
- * which is available on the Freescale website. Freescale explicitly 
- * grants the redistribution and modification of these source files.
- * The complete licensing information is available in the file 
- * LICENSE_FREESCALE.TXT.
- *
- * File:       mcf523x_skha.h
- * Purpose:    Register and bit definitions for the MCF523X
- *
- * Notes:      
- *     
- */
-
-#ifndef __MCF523X_SKHA_H__
-#define __MCF523X_SKHA_H__
-
-/*********************************************************************
-*
-* Symmetric Key Hardware Accelerator (SKHA)
-*
-*********************************************************************/
-
-/* Register read/write macros */
-#define MCF_SKHA_SKMR         (*(vuint32*)(void*)(&__IPSBAR[0x1B0000]))
-#define MCF_SKHA_SKCR         (*(vuint32*)(void*)(&__IPSBAR[0x1B0004]))
-#define MCF_SKHA_SKCMR        (*(vuint32*)(void*)(&__IPSBAR[0x1B0008]))
-#define MCF_SKHA_SKSR         (*(vuint32*)(void*)(&__IPSBAR[0x1B000C]))
-#define MCF_SKHA_SKIR         (*(vuint32*)(void*)(&__IPSBAR[0x1B0010]))
-#define MCF_SKHA_SKIMR        (*(vuint32*)(void*)(&__IPSBAR[0x1B0014]))
-#define MCF_SKHA_SKKSR        (*(vuint32*)(void*)(&__IPSBAR[0x1B0018]))
-#define MCF_SKHA_SKDSR        (*(vuint32*)(void*)(&__IPSBAR[0x1B001C]))
-#define MCF_SKHA_SKIN         (*(vuint32*)(void*)(&__IPSBAR[0x1B0020]))
-#define MCF_SKHA_SKOUT        (*(vuint32*)(void*)(&__IPSBAR[0x1B0024]))
-#define MCF_SKHA_SKKDR0       (*(vuint32*)(void*)(&__IPSBAR[0x1B0030]))
-#define MCF_SKHA_SKKDR1       (*(vuint32*)(void*)(&__IPSBAR[0x1B0034]))
-#define MCF_SKHA_SKKDR2       (*(vuint32*)(void*)(&__IPSBAR[0x1B0038]))
-#define MCF_SKHA_SKKDR3       (*(vuint32*)(void*)(&__IPSBAR[0x1B003C]))
-#define MCF_SKHA_SKKDR4       (*(vuint32*)(void*)(&__IPSBAR[0x1B0040]))
-#define MCF_SKHA_SKKDR5       (*(vuint32*)(void*)(&__IPSBAR[0x1B0044]))
-#define MCF_SKHA_SKKDRn(x)    (*(vuint32*)(void*)(&__IPSBAR[0x1B0030+((x)*0x004)]))
-#define MCF_SKHA_SKCR0        (*(vuint32*)(void*)(&__IPSBAR[0x1B0070]))
-#define MCF_SKHA_SKCR1        (*(vuint32*)(void*)(&__IPSBAR[0x1B0074]))
-#define MCF_SKHA_SKCR2        (*(vuint32*)(void*)(&__IPSBAR[0x1B0078]))
-#define MCF_SKHA_SKCR3        (*(vuint32*)(void*)(&__IPSBAR[0x1B007C]))
-#define MCF_SKHA_SKCR4        (*(vuint32*)(void*)(&__IPSBAR[0x1B0080]))
-#define MCF_SKHA_SKCR5        (*(vuint32*)(void*)(&__IPSBAR[0x1B0084]))
-#define MCF_SKHA_SKCR6        (*(vuint32*)(void*)(&__IPSBAR[0x1B0088]))
-#define MCF_SKHA_SKCR7        (*(vuint32*)(void*)(&__IPSBAR[0x1B008C]))
-#define MCF_SKHA_SKCR8        (*(vuint32*)(void*)(&__IPSBAR[0x1B0090]))
-#define MCF_SKHA_SKCR9        (*(vuint32*)(void*)(&__IPSBAR[0x1B0094]))
-#define MCF_SKHA_SKCR10       (*(vuint32*)(void*)(&__IPSBAR[0x1B0098]))
-#define MCF_SKHA_SKCR11       (*(vuint32*)(void*)(&__IPSBAR[0x1B009C]))
-#define MCF_SKHA_SKCRn(x)     (*(vuint32*)(void*)(&__IPSBAR[0x1B0070+((x)*0x004)]))
-
-/* Bit definitions and macros for MCF_SKHA_SKMR */
-#define MCF_SKHA_SKMR_ALG(x)         (((x)&0x00000003)<<0)
-#define MCF_SKHA_SKMR_DIR            (0x00000004)
-#define MCF_SKHA_SKMR_CM(x)          (((x)&0x00000003)<<3)
-#define MCF_SKHA_SKMR_DKP            (0x00000100)
-#define MCF_SKHA_SKMR_CTRM(x)        (((x)&0x0000000F)<<9)
-#define MCF_SKHA_SKMR_CM_ECB         (0x00000000)
-#define MCF_SKHA_SKMR_CM_CBC         (0x00000008)
-#define MCF_SKHA_SKMR_CM_CTR         (0x00000018)
-#define MCF_SKHA_SKMR_DIR_DEC        (0x00000000)
-#define MCF_SKHA_SKMR_DIR_ENC        (0x00000004)
-#define MCF_SKHA_SKMR_ALG_AES        (0x00000000)
-#define MCF_SKHA_SKMR_ALG_DES        (0x00000001)
-#define MCF_SKHA_SKMR_ALG_TDES       (0x00000002)
-
-/* Bit definitions and macros for MCF_SKHA_SKCR */
-#define MCF_SKHA_SKCR_IE             (0x00000001)
-
-/* Bit definitions and macros for MCF_SKHA_SKCMR */
-#define MCF_SKHA_SKCMR_SWR           (0x00000001)
-#define MCF_SKHA_SKCMR_RI            (0x00000002)
-#define MCF_SKHA_SKCMR_CI            (0x00000004)
-#define MCF_SKHA_SKCMR_GO            (0x00000008)
-
-/* Bit definitions and macros for MCF_SKHA_SKSR */
-#define MCF_SKHA_SKSR_INT            (0x00000001)
-#define MCF_SKHA_SKSR_DONE           (0x00000002)
-#define MCF_SKHA_SKSR_ERR            (0x00000004)
-#define MCF_SKHA_SKSR_RD             (0x00000008)
-#define MCF_SKHA_SKSR_BUSY           (0x00000010)
-#define MCF_SKHA_SKSR_IFL(x)         (((x)&0x000000FF)<<16)
-#define MCF_SKHA_SKSR_OFL(x)         (((x)&0x000000FF)<<24)
-
-/* Bit definitions and macros for MCF_SKHA_SKIR */
-#define MCF_SKHA_SKIR_IFO            (0x00000001)
-#define MCF_SKHA_SKIR_OFU            (0x00000002)
-#define MCF_SKHA_SKIR_NEIF           (0x00000004)
-#define MCF_SKHA_SKIR_NEOF           (0x00000008)
-#define MCF_SKHA_SKIR_IME            (0x00000010)
-#define MCF_SKHA_SKIR_DSE            (0x00000020)
-#define MCF_SKHA_SKIR_KSE            (0x00000040)
-#define MCF_SKHA_SKIR_RMDP           (0x00000080)
-#define MCF_SKHA_SKIR_ERE            (0x00000100)
-#define MCF_SKHA_SKIR_KPE            (0x00000200)
-#define MCF_SKHA_SKIR_KRE            (0x00000400)
-
-/* Bit definitions and macros for MCF_SKHA_SKIMR */
-#define MCF_SKHA_SKIMR_IFO           (0x00000001)
-#define MCF_SKHA_SKIMR_OFU           (0x00000002)
-#define MCF_SKHA_SKIMR_NEIF          (0x00000004)
-#define MCF_SKHA_SKIMR_NEOF          (0x00000008)
-#define MCF_SKHA_SKIMR_IME           (0x00000010)
-#define MCF_SKHA_SKIMR_DSE           (0x00000020)
-#define MCF_SKHA_SKIMR_KSE           (0x00000040)
-#define MCF_SKHA_SKIMR_RMDP          (0x00000080)
-#define MCF_SKHA_SKIMR_ERE           (0x00000100)
-#define MCF_SKHA_SKIMR_KPE           (0x00000200)
-#define MCF_SKHA_SKIMR_KRE           (0x00000400)
-
-/* Bit definitions and macros for MCF_SKHA_SKKSR */
-#define MCF_SKHA_SKKSR_KEYSIZE(x)    (((x)&0x0000003F)<<0)
-
-/********************************************************************/
-
-#endif /* __MCF523X_SKHA_H__ */
+/*\r
+ * These files are taken from the MCF523X source code example package\r
+ * which is available on the Freescale website. Freescale explicitly \r
+ * grants the redistribution and modification of these source files.\r
+ * The complete licensing information is available in the file \r
+ * LICENSE_FREESCALE.TXT.\r
+ *\r
+ * File:       mcf523x_skha.h\r
+ * Purpose:    Register and bit definitions for the MCF523X\r
+ *\r
+ * Notes:      \r
+ *     \r
+ */\r
+\r
+#ifndef __MCF523X_SKHA_H__\r
+#define __MCF523X_SKHA_H__\r
+\r
+/*********************************************************************\r
+*\r
+* Symmetric Key Hardware Accelerator (SKHA)\r
+*\r
+*********************************************************************/\r
+\r
+/* Register read/write macros */\r
+#define MCF_SKHA_SKMR         (*(vuint32*)(void*)(&__IPSBAR[0x1B0000]))\r
+#define MCF_SKHA_SKCR         (*(vuint32*)(void*)(&__IPSBAR[0x1B0004]))\r
+#define MCF_SKHA_SKCMR        (*(vuint32*)(void*)(&__IPSBAR[0x1B0008]))\r
+#define MCF_SKHA_SKSR         (*(vuint32*)(void*)(&__IPSBAR[0x1B000C]))\r
+#define MCF_SKHA_SKIR         (*(vuint32*)(void*)(&__IPSBAR[0x1B0010]))\r
+#define MCF_SKHA_SKIMR        (*(vuint32*)(void*)(&__IPSBAR[0x1B0014]))\r
+#define MCF_SKHA_SKKSR        (*(vuint32*)(void*)(&__IPSBAR[0x1B0018]))\r
+#define MCF_SKHA_SKDSR        (*(vuint32*)(void*)(&__IPSBAR[0x1B001C]))\r
+#define MCF_SKHA_SKIN         (*(vuint32*)(void*)(&__IPSBAR[0x1B0020]))\r
+#define MCF_SKHA_SKOUT        (*(vuint32*)(void*)(&__IPSBAR[0x1B0024]))\r
+#define MCF_SKHA_SKKDR0       (*(vuint32*)(void*)(&__IPSBAR[0x1B0030]))\r
+#define MCF_SKHA_SKKDR1       (*(vuint32*)(void*)(&__IPSBAR[0x1B0034]))\r
+#define MCF_SKHA_SKKDR2       (*(vuint32*)(void*)(&__IPSBAR[0x1B0038]))\r
+#define MCF_SKHA_SKKDR3       (*(vuint32*)(void*)(&__IPSBAR[0x1B003C]))\r
+#define MCF_SKHA_SKKDR4       (*(vuint32*)(void*)(&__IPSBAR[0x1B0040]))\r
+#define MCF_SKHA_SKKDR5       (*(vuint32*)(void*)(&__IPSBAR[0x1B0044]))\r
+#define MCF_SKHA_SKKDRn(x)    (*(vuint32*)(void*)(&__IPSBAR[0x1B0030+((x)*0x004)]))\r
+#define MCF_SKHA_SKCR0        (*(vuint32*)(void*)(&__IPSBAR[0x1B0070]))\r
+#define MCF_SKHA_SKCR1        (*(vuint32*)(void*)(&__IPSBAR[0x1B0074]))\r
+#define MCF_SKHA_SKCR2        (*(vuint32*)(void*)(&__IPSBAR[0x1B0078]))\r
+#define MCF_SKHA_SKCR3        (*(vuint32*)(void*)(&__IPSBAR[0x1B007C]))\r
+#define MCF_SKHA_SKCR4        (*(vuint32*)(void*)(&__IPSBAR[0x1B0080]))\r
+#define MCF_SKHA_SKCR5        (*(vuint32*)(void*)(&__IPSBAR[0x1B0084]))\r
+#define MCF_SKHA_SKCR6        (*(vuint32*)(void*)(&__IPSBAR[0x1B0088]))\r
+#define MCF_SKHA_SKCR7        (*(vuint32*)(void*)(&__IPSBAR[0x1B008C]))\r
+#define MCF_SKHA_SKCR8        (*(vuint32*)(void*)(&__IPSBAR[0x1B0090]))\r
+#define MCF_SKHA_SKCR9        (*(vuint32*)(void*)(&__IPSBAR[0x1B0094]))\r
+#define MCF_SKHA_SKCR10       (*(vuint32*)(void*)(&__IPSBAR[0x1B0098]))\r
+#define MCF_SKHA_SKCR11       (*(vuint32*)(void*)(&__IPSBAR[0x1B009C]))\r
+#define MCF_SKHA_SKCRn(x)     (*(vuint32*)(void*)(&__IPSBAR[0x1B0070+((x)*0x004)]))\r
+\r
+/* Bit definitions and macros for MCF_SKHA_SKMR */\r
+#define MCF_SKHA_SKMR_ALG(x)         (((x)&0x00000003)<<0)\r
+#define MCF_SKHA_SKMR_DIR            (0x00000004)\r
+#define MCF_SKHA_SKMR_CM(x)          (((x)&0x00000003)<<3)\r
+#define MCF_SKHA_SKMR_DKP            (0x00000100)\r
+#define MCF_SKHA_SKMR_CTRM(x)        (((x)&0x0000000F)<<9)\r
+#define MCF_SKHA_SKMR_CM_ECB         (0x00000000)\r
+#define MCF_SKHA_SKMR_CM_CBC         (0x00000008)\r
+#define MCF_SKHA_SKMR_CM_CTR         (0x00000018)\r
+#define MCF_SKHA_SKMR_DIR_DEC        (0x00000000)\r
+#define MCF_SKHA_SKMR_DIR_ENC        (0x00000004)\r
+#define MCF_SKHA_SKMR_ALG_AES        (0x00000000)\r
+#define MCF_SKHA_SKMR_ALG_DES        (0x00000001)\r
+#define MCF_SKHA_SKMR_ALG_TDES       (0x00000002)\r
+\r
+/* Bit definitions and macros for MCF_SKHA_SKCR */\r
+#define MCF_SKHA_SKCR_IE             (0x00000001)\r
+\r
+/* Bit definitions and macros for MCF_SKHA_SKCMR */\r
+#define MCF_SKHA_SKCMR_SWR           (0x00000001)\r
+#define MCF_SKHA_SKCMR_RI            (0x00000002)\r
+#define MCF_SKHA_SKCMR_CI            (0x00000004)\r
+#define MCF_SKHA_SKCMR_GO            (0x00000008)\r
+\r
+/* Bit definitions and macros for MCF_SKHA_SKSR */\r
+#define MCF_SKHA_SKSR_INT            (0x00000001)\r
+#define MCF_SKHA_SKSR_DONE           (0x00000002)\r
+#define MCF_SKHA_SKSR_ERR            (0x00000004)\r
+#define MCF_SKHA_SKSR_RD             (0x00000008)\r
+#define MCF_SKHA_SKSR_BUSY           (0x00000010)\r
+#define MCF_SKHA_SKSR_IFL(x)         (((x)&0x000000FF)<<16)\r
+#define MCF_SKHA_SKSR_OFL(x)         (((x)&0x000000FF)<<24)\r
+\r
+/* Bit definitions and macros for MCF_SKHA_SKIR */\r
+#define MCF_SKHA_SKIR_IFO            (0x00000001)\r
+#define MCF_SKHA_SKIR_OFU            (0x00000002)\r
+#define MCF_SKHA_SKIR_NEIF           (0x00000004)\r
+#define MCF_SKHA_SKIR_NEOF           (0x00000008)\r
+#define MCF_SKHA_SKIR_IME            (0x00000010)\r
+#define MCF_SKHA_SKIR_DSE            (0x00000020)\r
+#define MCF_SKHA_SKIR_KSE            (0x00000040)\r
+#define MCF_SKHA_SKIR_RMDP           (0x00000080)\r
+#define MCF_SKHA_SKIR_ERE            (0x00000100)\r
+#define MCF_SKHA_SKIR_KPE            (0x00000200)\r
+#define MCF_SKHA_SKIR_KRE            (0x00000400)\r
+\r
+/* Bit definitions and macros for MCF_SKHA_SKIMR */\r
+#define MCF_SKHA_SKIMR_IFO           (0x00000001)\r
+#define MCF_SKHA_SKIMR_OFU           (0x00000002)\r
+#define MCF_SKHA_SKIMR_NEIF          (0x00000004)\r
+#define MCF_SKHA_SKIMR_NEOF          (0x00000008)\r
+#define MCF_SKHA_SKIMR_IME           (0x00000010)\r
+#define MCF_SKHA_SKIMR_DSE           (0x00000020)\r
+#define MCF_SKHA_SKIMR_KSE           (0x00000040)\r
+#define MCF_SKHA_SKIMR_RMDP          (0x00000080)\r
+#define MCF_SKHA_SKIMR_ERE           (0x00000100)\r
+#define MCF_SKHA_SKIMR_KPE           (0x00000200)\r
+#define MCF_SKHA_SKIMR_KRE           (0x00000400)\r
+\r
+/* Bit definitions and macros for MCF_SKHA_SKKSR */\r
+#define MCF_SKHA_SKKSR_KEYSIZE(x)    (((x)&0x0000003F)<<0)\r
+\r
+/********************************************************************/\r
+\r
+#endif /* __MCF523X_SKHA_H__ */\r
index b40dda0e6a3d3b16b24734da202967d611ce6200..74626c2be45a4514dd49aa769e9112ad1a98ed67 100644 (file)
@@ -1,42 +1,42 @@
-/*
- * These files are taken from the MCF523X source code example package
- * which is available on the Freescale website. Freescale explicitly 
- * grants the redistribution and modification of these source files.
- * The complete licensing information is available in the file 
- * LICENSE_FREESCALE.TXT.
- *
- * File:       mcf523x_sram.h
- * Purpose:    Register and bit definitions for the MCF523X
- *
- * Notes:      
- *     
- */
-
-#ifndef __MCF523X_SRAM_H__
-#define __MCF523X_SRAM_H__
-
-/*********************************************************************
-*
-* 64KByte System SRAM (SRAM)
-*
-*********************************************************************/
-
-/* Register read/write macros */
-#define MCF_SRAM_RAMBAR    (*(vuint32*)(void*)(&__IPSBAR[0x20000000]))
-
-/* Bit definitions and macros for MCF_SRAM_RAMBAR */
-#define MCF_SRAM_RAMBAR_V        (0x00000001)
-#define MCF_SRAM_RAMBAR_UD       (0x00000002)
-#define MCF_SRAM_RAMBAR_UC       (0x00000004)
-#define MCF_SRAM_RAMBAR_SD       (0x00000008)
-#define MCF_SRAM_RAMBAR_SC       (0x00000010)
-#define MCF_SRAM_RAMBAR_CI       (0x00000020)
-#define MCF_SRAM_RAMBAR_WP       (0x00000100)
-#define MCF_SRAM_RAMBAR_SPV      (0x00000200)
-#define MCF_SRAM_RAMBAR_PRI2     (0x00000400)
-#define MCF_SRAM_RAMBAR_PRI1     (0x00000800)
-#define MCF_SRAM_RAMBAR_BA(x)    (((x)&0x0000FFFF)<<16)
-
-/********************************************************************/
-
-#endif /* __MCF523X_SRAM_H__ */
+/*\r
+ * These files are taken from the MCF523X source code example package\r
+ * which is available on the Freescale website. Freescale explicitly \r
+ * grants the redistribution and modification of these source files.\r
+ * The complete licensing information is available in the file \r
+ * LICENSE_FREESCALE.TXT.\r
+ *\r
+ * File:       mcf523x_sram.h\r
+ * Purpose:    Register and bit definitions for the MCF523X\r
+ *\r
+ * Notes:      \r
+ *     \r
+ */\r
+\r
+#ifndef __MCF523X_SRAM_H__\r
+#define __MCF523X_SRAM_H__\r
+\r
+/*********************************************************************\r
+*\r
+* 64KByte System SRAM (SRAM)\r
+*\r
+*********************************************************************/\r
+\r
+/* Register read/write macros */\r
+#define MCF_SRAM_RAMBAR    (*(vuint32*)(void*)(&__IPSBAR[0x20000000]))\r
+\r
+/* Bit definitions and macros for MCF_SRAM_RAMBAR */\r
+#define MCF_SRAM_RAMBAR_V        (0x00000001)\r
+#define MCF_SRAM_RAMBAR_UD       (0x00000002)\r
+#define MCF_SRAM_RAMBAR_UC       (0x00000004)\r
+#define MCF_SRAM_RAMBAR_SD       (0x00000008)\r
+#define MCF_SRAM_RAMBAR_SC       (0x00000010)\r
+#define MCF_SRAM_RAMBAR_CI       (0x00000020)\r
+#define MCF_SRAM_RAMBAR_WP       (0x00000100)\r
+#define MCF_SRAM_RAMBAR_SPV      (0x00000200)\r
+#define MCF_SRAM_RAMBAR_PRI2     (0x00000400)\r
+#define MCF_SRAM_RAMBAR_PRI1     (0x00000800)\r
+#define MCF_SRAM_RAMBAR_BA(x)    (((x)&0x0000FFFF)<<16)\r
+\r
+/********************************************************************/\r
+\r
+#endif /* __MCF523X_SRAM_H__ */\r
index e9db74c27236efe6c6bc71022cf697653242b0c0..359e895f7ac16395455d1a9355220f6ceef57d30 100644 (file)
@@ -1,83 +1,83 @@
-/*
- * These files are taken from the MCF523X source code example package
- * which is available on the Freescale website. Freescale explicitly 
- * grants the redistribution and modification of these source files.
- * The complete licensing information is available in the file 
- * LICENSE_FREESCALE.TXT.
- *
- * File:       mcf523x_timer.h
- * Purpose:    Register and bit definitions for the MCF523X
- *
- * Notes:      
- *     
- */
-
-#ifndef __MCF523X_TIMER_H__
-#define __MCF523X_TIMER_H__
-
-/*********************************************************************
-*
-* DMA Timers (TIMER)
-*
-*********************************************************************/
-
-/* Register read/write macros */
-#define MCF_TIMER_DTMR0       (*(vuint16*)(void*)(&__IPSBAR[0x000400]))
-#define MCF_TIMER_DTXMR0      (*(vuint8 *)(void*)(&__IPSBAR[0x000402]))
-#define MCF_TIMER_DTER0       (*(vuint8 *)(void*)(&__IPSBAR[0x000403]))
-#define MCF_TIMER_DTRR0       (*(vuint32*)(void*)(&__IPSBAR[0x000404]))
-#define MCF_TIMER_DTCR0       (*(vuint32*)(void*)(&__IPSBAR[0x000408]))
-#define MCF_TIMER_DTCN0       (*(vuint32*)(void*)(&__IPSBAR[0x00040C]))
-#define MCF_TIMER_DTMR1       (*(vuint16*)(void*)(&__IPSBAR[0x000440]))
-#define MCF_TIMER_DTXMR1      (*(vuint8 *)(void*)(&__IPSBAR[0x000442]))
-#define MCF_TIMER_DTER1       (*(vuint8 *)(void*)(&__IPSBAR[0x000443]))
-#define MCF_TIMER_DTRR1       (*(vuint32*)(void*)(&__IPSBAR[0x000444]))
-#define MCF_TIMER_DTCR1       (*(vuint32*)(void*)(&__IPSBAR[0x000448]))
-#define MCF_TIMER_DTCN1       (*(vuint32*)(void*)(&__IPSBAR[0x00044C]))
-#define MCF_TIMER_DTMR2       (*(vuint16*)(void*)(&__IPSBAR[0x000480]))
-#define MCF_TIMER_DTXMR2      (*(vuint8 *)(void*)(&__IPSBAR[0x000482]))
-#define MCF_TIMER_DTER2       (*(vuint8 *)(void*)(&__IPSBAR[0x000483]))
-#define MCF_TIMER_DTRR2       (*(vuint32*)(void*)(&__IPSBAR[0x000484]))
-#define MCF_TIMER_DTCR2       (*(vuint32*)(void*)(&__IPSBAR[0x000488]))
-#define MCF_TIMER_DTCN2       (*(vuint32*)(void*)(&__IPSBAR[0x00048C]))
-#define MCF_TIMER_DTMR3       (*(vuint16*)(void*)(&__IPSBAR[0x0004C0]))
-#define MCF_TIMER_DTXMR3      (*(vuint8 *)(void*)(&__IPSBAR[0x0004C2]))
-#define MCF_TIMER_DTER3       (*(vuint8 *)(void*)(&__IPSBAR[0x0004C3]))
-#define MCF_TIMER_DTRR3       (*(vuint32*)(void*)(&__IPSBAR[0x0004C4]))
-#define MCF_TIMER_DTCR3       (*(vuint32*)(void*)(&__IPSBAR[0x0004C8]))
-#define MCF_TIMER_DTCN3       (*(vuint32*)(void*)(&__IPSBAR[0x0004CC]))
-#define MCF_TIMER_DTMR(x)     (*(vuint16*)(void*)(&__IPSBAR[0x000400+((x)*0x040)]))
-#define MCF_TIMER_DTXMR(x)    (*(vuint8 *)(void*)(&__IPSBAR[0x000402+((x)*0x040)]))
-#define MCF_TIMER_DTER(x)     (*(vuint8 *)(void*)(&__IPSBAR[0x000403+((x)*0x040)]))
-#define MCF_TIMER_DTRR(x)     (*(vuint32*)(void*)(&__IPSBAR[0x000404+((x)*0x040)]))
-#define MCF_TIMER_DTCR(x)     (*(vuint32*)(void*)(&__IPSBAR[0x000408+((x)*0x040)]))
-#define MCF_TIMER_DTCN(x)     (*(vuint32*)(void*)(&__IPSBAR[0x00040C+((x)*0x040)]))
-
-/* Bit definitions and macros for MCF_TIMER_DTMR */
-#define MCF_TIMER_DTMR_RST          (0x0001)
-#define MCF_TIMER_DTMR_CLK(x)       (((x)&0x0003)<<1)
-#define MCF_TIMER_DTMR_FRR          (0x0008)
-#define MCF_TIMER_DTMR_ORRI         (0x0010)
-#define MCF_TIMER_DTMR_OM           (0x0020)
-#define MCF_TIMER_DTMR_CE(x)        (((x)&0x0003)<<6)
-#define MCF_TIMER_DTMR_PS(x)        (((x)&0x00FF)<<8)
-#define MCF_TIMER_DTMR_CE_ANY       (0x00C0)
-#define MCF_TIMER_DTMR_CE_FALL      (0x0080)
-#define MCF_TIMER_DTMR_CE_RISE      (0x0040)
-#define MCF_TIMER_DTMR_CE_NONE      (0x0000)
-#define MCF_TIMER_DTMR_CLK_DTIN     (0x0006)
-#define MCF_TIMER_DTMR_CLK_DIV16    (0x0004)
-#define MCF_TIMER_DTMR_CLK_DIV1     (0x0002)
-#define MCF_TIMER_DTMR_CLK_STOP     (0x0000)
-
-/* Bit definitions and macros for MCF_TIMER_DTXMR */
-#define MCF_TIMER_DTXMR_MODE16      (0x01)
-#define MCF_TIMER_DTXMR_DMAEN       (0x80)
-
-/* Bit definitions and macros for MCF_TIMER_DTER */
-#define MCF_TIMER_DTER_CAP          (0x01)
-#define MCF_TIMER_DTER_REF          (0x02)
-
-/********************************************************************/
-
-#endif /* __MCF523X_TIMER_H__ */
+/*\r
+ * These files are taken from the MCF523X source code example package\r
+ * which is available on the Freescale website. Freescale explicitly \r
+ * grants the redistribution and modification of these source files.\r
+ * The complete licensing information is available in the file \r
+ * LICENSE_FREESCALE.TXT.\r
+ *\r
+ * File:       mcf523x_timer.h\r
+ * Purpose:    Register and bit definitions for the MCF523X\r
+ *\r
+ * Notes:      \r
+ *     \r
+ */\r
+\r
+#ifndef __MCF523X_TIMER_H__\r
+#define __MCF523X_TIMER_H__\r
+\r
+/*********************************************************************\r
+*\r
+* DMA Timers (TIMER)\r
+*\r
+*********************************************************************/\r
+\r
+/* Register read/write macros */\r
+#define MCF_TIMER_DTMR0       (*(vuint16*)(void*)(&__IPSBAR[0x000400]))\r
+#define MCF_TIMER_DTXMR0      (*(vuint8 *)(void*)(&__IPSBAR[0x000402]))\r
+#define MCF_TIMER_DTER0       (*(vuint8 *)(void*)(&__IPSBAR[0x000403]))\r
+#define MCF_TIMER_DTRR0       (*(vuint32*)(void*)(&__IPSBAR[0x000404]))\r
+#define MCF_TIMER_DTCR0       (*(vuint32*)(void*)(&__IPSBAR[0x000408]))\r
+#define MCF_TIMER_DTCN0       (*(vuint32*)(void*)(&__IPSBAR[0x00040C]))\r
+#define MCF_TIMER_DTMR1       (*(vuint16*)(void*)(&__IPSBAR[0x000440]))\r
+#define MCF_TIMER_DTXMR1      (*(vuint8 *)(void*)(&__IPSBAR[0x000442]))\r
+#define MCF_TIMER_DTER1       (*(vuint8 *)(void*)(&__IPSBAR[0x000443]))\r
+#define MCF_TIMER_DTRR1       (*(vuint32*)(void*)(&__IPSBAR[0x000444]))\r
+#define MCF_TIMER_DTCR1       (*(vuint32*)(void*)(&__IPSBAR[0x000448]))\r
+#define MCF_TIMER_DTCN1       (*(vuint32*)(void*)(&__IPSBAR[0x00044C]))\r
+#define MCF_TIMER_DTMR2       (*(vuint16*)(void*)(&__IPSBAR[0x000480]))\r
+#define MCF_TIMER_DTXMR2      (*(vuint8 *)(void*)(&__IPSBAR[0x000482]))\r
+#define MCF_TIMER_DTER2       (*(vuint8 *)(void*)(&__IPSBAR[0x000483]))\r
+#define MCF_TIMER_DTRR2       (*(vuint32*)(void*)(&__IPSBAR[0x000484]))\r
+#define MCF_TIMER_DTCR2       (*(vuint32*)(void*)(&__IPSBAR[0x000488]))\r
+#define MCF_TIMER_DTCN2       (*(vuint32*)(void*)(&__IPSBAR[0x00048C]))\r
+#define MCF_TIMER_DTMR3       (*(vuint16*)(void*)(&__IPSBAR[0x0004C0]))\r
+#define MCF_TIMER_DTXMR3      (*(vuint8 *)(void*)(&__IPSBAR[0x0004C2]))\r
+#define MCF_TIMER_DTER3       (*(vuint8 *)(void*)(&__IPSBAR[0x0004C3]))\r
+#define MCF_TIMER_DTRR3       (*(vuint32*)(void*)(&__IPSBAR[0x0004C4]))\r
+#define MCF_TIMER_DTCR3       (*(vuint32*)(void*)(&__IPSBAR[0x0004C8]))\r
+#define MCF_TIMER_DTCN3       (*(vuint32*)(void*)(&__IPSBAR[0x0004CC]))\r
+#define MCF_TIMER_DTMR(x)     (*(vuint16*)(void*)(&__IPSBAR[0x000400+((x)*0x040)]))\r
+#define MCF_TIMER_DTXMR(x)    (*(vuint8 *)(void*)(&__IPSBAR[0x000402+((x)*0x040)]))\r
+#define MCF_TIMER_DTER(x)     (*(vuint8 *)(void*)(&__IPSBAR[0x000403+((x)*0x040)]))\r
+#define MCF_TIMER_DTRR(x)     (*(vuint32*)(void*)(&__IPSBAR[0x000404+((x)*0x040)]))\r
+#define MCF_TIMER_DTCR(x)     (*(vuint32*)(void*)(&__IPSBAR[0x000408+((x)*0x040)]))\r
+#define MCF_TIMER_DTCN(x)     (*(vuint32*)(void*)(&__IPSBAR[0x00040C+((x)*0x040)]))\r
+\r
+/* Bit definitions and macros for MCF_TIMER_DTMR */\r
+#define MCF_TIMER_DTMR_RST          (0x0001)\r
+#define MCF_TIMER_DTMR_CLK(x)       (((x)&0x0003)<<1)\r
+#define MCF_TIMER_DTMR_FRR          (0x0008)\r
+#define MCF_TIMER_DTMR_ORRI         (0x0010)\r
+#define MCF_TIMER_DTMR_OM           (0x0020)\r
+#define MCF_TIMER_DTMR_CE(x)        (((x)&0x0003)<<6)\r
+#define MCF_TIMER_DTMR_PS(x)        (((x)&0x00FF)<<8)\r
+#define MCF_TIMER_DTMR_CE_ANY       (0x00C0)\r
+#define MCF_TIMER_DTMR_CE_FALL      (0x0080)\r
+#define MCF_TIMER_DTMR_CE_RISE      (0x0040)\r
+#define MCF_TIMER_DTMR_CE_NONE      (0x0000)\r
+#define MCF_TIMER_DTMR_CLK_DTIN     (0x0006)\r
+#define MCF_TIMER_DTMR_CLK_DIV16    (0x0004)\r
+#define MCF_TIMER_DTMR_CLK_DIV1     (0x0002)\r
+#define MCF_TIMER_DTMR_CLK_STOP     (0x0000)\r
+\r
+/* Bit definitions and macros for MCF_TIMER_DTXMR */\r
+#define MCF_TIMER_DTXMR_MODE16      (0x01)\r
+#define MCF_TIMER_DTXMR_DMAEN       (0x80)\r
+\r
+/* Bit definitions and macros for MCF_TIMER_DTER */\r
+#define MCF_TIMER_DTER_CAP          (0x01)\r
+#define MCF_TIMER_DTER_REF          (0x02)\r
+\r
+/********************************************************************/\r
+\r
+#endif /* __MCF523X_TIMER_H__ */\r
index 43a44a67fb9bdf303c867e7a32569f6cf7b106bf..f70a71c4e11b6cd3a7043bb581f15de593822737 100644 (file)
-/*
- * These files are taken from the MCF523X source code example package
- * which is available on the Freescale website. Freescale explicitly 
- * grants the redistribution and modification of these source files.
- * The complete licensing information is available in the file 
- * LICENSE_FREESCALE.TXT.
- *
- * File:       mcf523x_uart.h
- * Purpose:    Register and bit definitions for the MCF523X
- *
- * Notes:      
- *     
- */
-
-#ifndef __MCF523X_UART_H__
-#define __MCF523X_UART_H__
-
-/*********************************************************************
-*
-* Universal Asynchronous Receiver Transmitter (UART)
-*
-*********************************************************************/
-
-/* Register read/write macros */
-#define MCF_UART_UMR0        (*(vuint8 *)(void*)(&__IPSBAR[0x000200]))
-#define MCF_UART_USR0        (*(vuint8 *)(void*)(&__IPSBAR[0x000204]))
-#define MCF_UART_UCSR0       (*(vuint8 *)(void*)(&__IPSBAR[0x000204]))
-#define MCF_UART_UCR0        (*(vuint8 *)(void*)(&__IPSBAR[0x000208]))
-#define MCF_UART_URB0        (*(vuint8 *)(void*)(&__IPSBAR[0x00020C]))
-#define MCF_UART_UTB0        (*(vuint8 *)(void*)(&__IPSBAR[0x00020C]))
-#define MCF_UART_UIPCR0      (*(vuint8 *)(void*)(&__IPSBAR[0x000210]))
-#define MCF_UART_UACR0       (*(vuint8 *)(void*)(&__IPSBAR[0x000210]))
-#define MCF_UART_UISR0       (*(vuint8 *)(void*)(&__IPSBAR[0x000214]))
-#define MCF_UART_UIMR0       (*(vuint8 *)(void*)(&__IPSBAR[0x000214]))
-#define MCF_UART_UBG10       (*(vuint8 *)(void*)(&__IPSBAR[0x000218]))
-#define MCF_UART_UBG20       (*(vuint8 *)(void*)(&__IPSBAR[0x00021C]))
-#define MCF_UART_UIP0        (*(vuint8 *)(void*)(&__IPSBAR[0x000234]))
-#define MCF_UART_UOP10       (*(vuint8 *)(void*)(&__IPSBAR[0x000238]))
-#define MCF_UART_UOP00       (*(vuint8 *)(void*)(&__IPSBAR[0x00023C]))
-#define MCF_UART_UMR1        (*(vuint8 *)(void*)(&__IPSBAR[0x000240]))
-#define MCF_UART_USR1        (*(vuint8 *)(void*)(&__IPSBAR[0x000244]))
-#define MCF_UART_UCSR1       (*(vuint8 *)(void*)(&__IPSBAR[0x000244]))
-#define MCF_UART_UCR1        (*(vuint8 *)(void*)(&__IPSBAR[0x000248]))
-#define MCF_UART_URB1        (*(vuint8 *)(void*)(&__IPSBAR[0x00024C]))
-#define MCF_UART_UTB1        (*(vuint8 *)(void*)(&__IPSBAR[0x00024C]))
-#define MCF_UART_UIPCR1      (*(vuint8 *)(void*)(&__IPSBAR[0x000250]))
-#define MCF_UART_UACR1       (*(vuint8 *)(void*)(&__IPSBAR[0x000250]))
-#define MCF_UART_UISR1       (*(vuint8 *)(void*)(&__IPSBAR[0x000254]))
-#define MCF_UART_UIMR1       (*(vuint8 *)(void*)(&__IPSBAR[0x000254]))
-#define MCF_UART_UBG11       (*(vuint8 *)(void*)(&__IPSBAR[0x000258]))
-#define MCF_UART_UBG21       (*(vuint8 *)(void*)(&__IPSBAR[0x00025C]))
-#define MCF_UART_UIP1        (*(vuint8 *)(void*)(&__IPSBAR[0x000274]))
-#define MCF_UART_UOP11       (*(vuint8 *)(void*)(&__IPSBAR[0x000278]))
-#define MCF_UART_UOP01       (*(vuint8 *)(void*)(&__IPSBAR[0x00027C]))
-#define MCF_UART_UMR2        (*(vuint8 *)(void*)(&__IPSBAR[0x000280]))
-#define MCF_UART_USR2        (*(vuint8 *)(void*)(&__IPSBAR[0x000284]))
-#define MCF_UART_UCSR2       (*(vuint8 *)(void*)(&__IPSBAR[0x000284]))
-#define MCF_UART_UCR2        (*(vuint8 *)(void*)(&__IPSBAR[0x000288]))
-#define MCF_UART_URB2        (*(vuint8 *)(void*)(&__IPSBAR[0x00028C]))
-#define MCF_UART_UTB2        (*(vuint8 *)(void*)(&__IPSBAR[0x00028C]))
-#define MCF_UART_UIPCR2      (*(vuint8 *)(void*)(&__IPSBAR[0x000290]))
-#define MCF_UART_UACR2       (*(vuint8 *)(void*)(&__IPSBAR[0x000290]))
-#define MCF_UART_UISR2       (*(vuint8 *)(void*)(&__IPSBAR[0x000294]))
-#define MCF_UART_UIMR2       (*(vuint8 *)(void*)(&__IPSBAR[0x000294]))
-#define MCF_UART_UBG12       (*(vuint8 *)(void*)(&__IPSBAR[0x000298]))
-#define MCF_UART_UBG22       (*(vuint8 *)(void*)(&__IPSBAR[0x00029C]))
-#define MCF_UART_UIP2        (*(vuint8 *)(void*)(&__IPSBAR[0x0002B4]))
-#define MCF_UART_UOP12       (*(vuint8 *)(void*)(&__IPSBAR[0x0002B8]))
-#define MCF_UART_UOP02       (*(vuint8 *)(void*)(&__IPSBAR[0x0002BC]))
-#define MCF_UART_UMR(x)      (*(vuint8 *)(void*)(&__IPSBAR[0x000200+((x)*0x040)]))
-#define MCF_UART_USR(x)      (*(vuint8 *)(void*)(&__IPSBAR[0x000204+((x)*0x040)]))
-#define MCF_UART_UCSR(x)     (*(vuint8 *)(void*)(&__IPSBAR[0x000204+((x)*0x040)]))
-#define MCF_UART_UCR(x)      (*(vuint8 *)(void*)(&__IPSBAR[0x000208+((x)*0x040)]))
-#define MCF_UART_URB(x)      (*(vuint8 *)(void*)(&__IPSBAR[0x00020C+((x)*0x040)]))
-#define MCF_UART_UTB(x)      (*(vuint8 *)(void*)(&__IPSBAR[0x00020C+((x)*0x040)]))
-#define MCF_UART_UIPCR(x)    (*(vuint8 *)(void*)(&__IPSBAR[0x000210+((x)*0x040)]))
-#define MCF_UART_UACR(x)     (*(vuint8 *)(void*)(&__IPSBAR[0x000210+((x)*0x040)]))
-#define MCF_UART_UISR(x)     (*(vuint8 *)(void*)(&__IPSBAR[0x000214+((x)*0x040)]))
-#define MCF_UART_UIMR(x)     (*(vuint8 *)(void*)(&__IPSBAR[0x000214+((x)*0x040)]))
-#define MCF_UART_UBG1(x)     (*(vuint8 *)(void*)(&__IPSBAR[0x000218+((x)*0x040)]))
-#define MCF_UART_UBG2(x)     (*(vuint8 *)(void*)(&__IPSBAR[0x00021C+((x)*0x040)]))
-#define MCF_UART_UIP(x)      (*(vuint8 *)(void*)(&__IPSBAR[0x000234+((x)*0x040)]))
-#define MCF_UART_UOP1(x)     (*(vuint8 *)(void*)(&__IPSBAR[0x000238+((x)*0x040)]))
-#define MCF_UART_UOP0(x)     (*(vuint8 *)(void*)(&__IPSBAR[0x00023C+((x)*0x040)]))
-
-/* Bit definitions and macros for MCF_UART_UMR */
-#define MCF_UART_UMR_BC(x)              (((x)&0x03)<<0)
-#define MCF_UART_UMR_PT                 (0x04)
-#define MCF_UART_UMR_PM(x)              (((x)&0x03)<<3)
-#define MCF_UART_UMR_ERR                (0x20)
-#define MCF_UART_UMR_RXIRQ              (0x40)
-#define MCF_UART_UMR_RXRTS              (0x80)
-#define MCF_UART_UMR_SB(x)              (((x)&0x0F)<<0)
-#define MCF_UART_UMR_TXCTS              (0x10)
-#define MCF_UART_UMR_TXRTS              (0x20)
-#define MCF_UART_UMR_CM(x)              (((x)&0x03)<<6)
-#define MCF_UART_UMR_PM_MULTI_ADDR      (0x1C)
-#define MCF_UART_UMR_PM_MULTI_DATA      (0x18)
-#define MCF_UART_UMR_PM_NONE            (0x10)
-#define MCF_UART_UMR_PM_FORCE_HI        (0x0C)
-#define MCF_UART_UMR_PM_FORCE_LO        (0x08)
-#define MCF_UART_UMR_PM_ODD             (0x04)
-#define MCF_UART_UMR_PM_EVEN            (0x00)
-#define MCF_UART_UMR_BC_5               (0x00)
-#define MCF_UART_UMR_BC_6               (0x01)
-#define MCF_UART_UMR_BC_7               (0x02)
-#define MCF_UART_UMR_BC_8               (0x03)
-#define MCF_UART_UMR_CM_NORMAL          (0x00)
-#define MCF_UART_UMR_CM_ECHO            (0x40)
-#define MCF_UART_UMR_CM_LOCAL_LOOP      (0x80)
-#define MCF_UART_UMR_CM_REMOTE_LOOP     (0xC0)
-#define MCF_UART_UMR_SB_STOP_BITS_1     (0x07)
-#define MCF_UART_UMR_SB_STOP_BITS_15    (0x08)
-#define MCF_UART_UMR_SB_STOP_BITS_2     (0x0F)
-
-/* Bit definitions and macros for MCF_UART_USR */
-#define MCF_UART_USR_RXRDY              (0x01)
-#define MCF_UART_USR_FFULL              (0x02)
-#define MCF_UART_USR_TXRDY              (0x04)
-#define MCF_UART_USR_TXEMP              (0x08)
-#define MCF_UART_USR_OE                 (0x10)
-#define MCF_UART_USR_PE                 (0x20)
-#define MCF_UART_USR_FE                 (0x40)
-#define MCF_UART_USR_RB                 (0x80)
-
-/* Bit definitions and macros for MCF_UART_UCSR */
-#define MCF_UART_UCSR_TCS(x)            (((x)&0x0F)<<0)
-#define MCF_UART_UCSR_RCS(x)            (((x)&0x0F)<<4)
-#define MCF_UART_UCSR_RCS_SYS_CLK       (0xD0)
-#define MCF_UART_UCSR_RCS_CTM16         (0xE0)
-#define MCF_UART_UCSR_RCS_CTM           (0xF0)
-#define MCF_UART_UCSR_TCS_SYS_CLK       (0x0D)
-#define MCF_UART_UCSR_TCS_CTM16         (0x0E)
-#define MCF_UART_UCSR_TCS_CTM           (0x0F)
-
-/* Bit definitions and macros for MCF_UART_UCR */
-#define MCF_UART_UCR_RXC(x)             (((x)&0x03)<<0)
-#define MCF_UART_UCR_TXC(x)             (((x)&0x03)<<2)
-#define MCF_UART_UCR_MISC(x)            (((x)&0x07)<<4)
-#define MCF_UART_UCR_NONE               (0x00)
-#define MCF_UART_UCR_STOP_BREAK         (0x70)
-#define MCF_UART_UCR_START_BREAK        (0x60)
-#define MCF_UART_UCR_BKCHGINT           (0x50)
-#define MCF_UART_UCR_RESET_ERROR        (0x40)
-#define MCF_UART_UCR_RESET_TX           (0x30)
-#define MCF_UART_UCR_RESET_RX           (0x20)
-#define MCF_UART_UCR_RESET_MR           (0x10)
-#define MCF_UART_UCR_TX_DISABLED        (0x08)
-#define MCF_UART_UCR_TX_ENABLED         (0x04)
-#define MCF_UART_UCR_RX_DISABLED        (0x02)
-#define MCF_UART_UCR_RX_ENABLED         (0x01)
-
-/* Bit definitions and macros for MCF_UART_UIPCR */
-#define MCF_UART_UIPCR_CTS              (0x01)
-#define MCF_UART_UIPCR_COS              (0x10)
-
-/* Bit definitions and macros for MCF_UART_UACR */
-#define MCF_UART_UACR_IEC               (0x01)
-
-/* Bit definitions and macros for MCF_UART_UISR */
-#define MCF_UART_UISR_TXRDY             (0x01)
-#define MCF_UART_UISR_RXRDY_FU          (0x02)
-#define MCF_UART_UISR_DB                (0x04)
-#define MCF_UART_UISR_RXFTO             (0x08)
-#define MCF_UART_UISR_TXFIFO            (0x10)
-#define MCF_UART_UISR_RXFIFO            (0x20)
-#define MCF_UART_UISR_COS               (0x80)
-
-/* Bit definitions and macros for MCF_UART_UIMR */
-#define MCF_UART_UIMR_TXRDY             (0x01)
-#define MCF_UART_UIMR_RXRDY_FU          (0x02)
-#define MCF_UART_UIMR_DB                (0x04)
-#define MCF_UART_UIMR_COS               (0x80)
-
-/* Bit definitions and macros for MCF_UART_UIP */
-#define MCF_UART_UIP_CTS                (0x01)
-
-/* Bit definitions and macros for MCF_UART_UOP1 */
-#define MCF_UART_UOP1_RTS               (0x01)
-
-/* Bit definitions and macros for MCF_UART_UOP0 */
-#define MCF_UART_UOP0_RTS               (0x01)
-
-/********************************************************************/
-
-#endif /* __MCF523X_UART_H__ */
+/*\r
+ * These files are taken from the MCF523X source code example package\r
+ * which is available on the Freescale website. Freescale explicitly \r
+ * grants the redistribution and modification of these source files.\r
+ * The complete licensing information is available in the file \r
+ * LICENSE_FREESCALE.TXT.\r
+ *\r
+ * File:       mcf523x_uart.h\r
+ * Purpose:    Register and bit definitions for the MCF523X\r
+ *\r
+ * Notes:      \r
+ *     \r
+ */\r
+\r
+#ifndef __MCF523X_UART_H__\r
+#define __MCF523X_UART_H__\r
+\r
+/*********************************************************************\r
+*\r
+* Universal Asynchronous Receiver Transmitter (UART)\r
+*\r
+*********************************************************************/\r
+\r
+/* Register read/write macros */\r
+#define MCF_UART_UMR0        (*(vuint8 *)(void*)(&__IPSBAR[0x000200]))\r
+#define MCF_UART_USR0        (*(vuint8 *)(void*)(&__IPSBAR[0x000204]))\r
+#define MCF_UART_UCSR0       (*(vuint8 *)(void*)(&__IPSBAR[0x000204]))\r
+#define MCF_UART_UCR0        (*(vuint8 *)(void*)(&__IPSBAR[0x000208]))\r
+#define MCF_UART_URB0        (*(vuint8 *)(void*)(&__IPSBAR[0x00020C]))\r
+#define MCF_UART_UTB0        (*(vuint8 *)(void*)(&__IPSBAR[0x00020C]))\r
+#define MCF_UART_UIPCR0      (*(vuint8 *)(void*)(&__IPSBAR[0x000210]))\r
+#define MCF_UART_UACR0       (*(vuint8 *)(void*)(&__IPSBAR[0x000210]))\r
+#define MCF_UART_UISR0       (*(vuint8 *)(void*)(&__IPSBAR[0x000214]))\r
+#define MCF_UART_UIMR0       (*(vuint8 *)(void*)(&__IPSBAR[0x000214]))\r
+#define MCF_UART_UBG10       (*(vuint8 *)(void*)(&__IPSBAR[0x000218]))\r
+#define MCF_UART_UBG20       (*(vuint8 *)(void*)(&__IPSBAR[0x00021C]))\r
+#define MCF_UART_UIP0        (*(vuint8 *)(void*)(&__IPSBAR[0x000234]))\r
+#define MCF_UART_UOP10       (*(vuint8 *)(void*)(&__IPSBAR[0x000238]))\r
+#define MCF_UART_UOP00       (*(vuint8 *)(void*)(&__IPSBAR[0x00023C]))\r
+#define MCF_UART_UMR1        (*(vuint8 *)(void*)(&__IPSBAR[0x000240]))\r
+#define MCF_UART_USR1        (*(vuint8 *)(void*)(&__IPSBAR[0x000244]))\r
+#define MCF_UART_UCSR1       (*(vuint8 *)(void*)(&__IPSBAR[0x000244]))\r
+#define MCF_UART_UCR1        (*(vuint8 *)(void*)(&__IPSBAR[0x000248]))\r
+#define MCF_UART_URB1        (*(vuint8 *)(void*)(&__IPSBAR[0x00024C]))\r
+#define MCF_UART_UTB1        (*(vuint8 *)(void*)(&__IPSBAR[0x00024C]))\r
+#define MCF_UART_UIPCR1      (*(vuint8 *)(void*)(&__IPSBAR[0x000250]))\r
+#define MCF_UART_UACR1       (*(vuint8 *)(void*)(&__IPSBAR[0x000250]))\r
+#define MCF_UART_UISR1       (*(vuint8 *)(void*)(&__IPSBAR[0x000254]))\r
+#define MCF_UART_UIMR1       (*(vuint8 *)(void*)(&__IPSBAR[0x000254]))\r
+#define MCF_UART_UBG11       (*(vuint8 *)(void*)(&__IPSBAR[0x000258]))\r
+#define MCF_UART_UBG21       (*(vuint8 *)(void*)(&__IPSBAR[0x00025C]))\r
+#define MCF_UART_UIP1        (*(vuint8 *)(void*)(&__IPSBAR[0x000274]))\r
+#define MCF_UART_UOP11       (*(vuint8 *)(void*)(&__IPSBAR[0x000278]))\r
+#define MCF_UART_UOP01       (*(vuint8 *)(void*)(&__IPSBAR[0x00027C]))\r
+#define MCF_UART_UMR2        (*(vuint8 *)(void*)(&__IPSBAR[0x000280]))\r
+#define MCF_UART_USR2        (*(vuint8 *)(void*)(&__IPSBAR[0x000284]))\r
+#define MCF_UART_UCSR2       (*(vuint8 *)(void*)(&__IPSBAR[0x000284]))\r
+#define MCF_UART_UCR2        (*(vuint8 *)(void*)(&__IPSBAR[0x000288]))\r
+#define MCF_UART_URB2        (*(vuint8 *)(void*)(&__IPSBAR[0x00028C]))\r
+#define MCF_UART_UTB2        (*(vuint8 *)(void*)(&__IPSBAR[0x00028C]))\r
+#define MCF_UART_UIPCR2      (*(vuint8 *)(void*)(&__IPSBAR[0x000290]))\r
+#define MCF_UART_UACR2       (*(vuint8 *)(void*)(&__IPSBAR[0x000290]))\r
+#define MCF_UART_UISR2       (*(vuint8 *)(void*)(&__IPSBAR[0x000294]))\r
+#define MCF_UART_UIMR2       (*(vuint8 *)(void*)(&__IPSBAR[0x000294]))\r
+#define MCF_UART_UBG12       (*(vuint8 *)(void*)(&__IPSBAR[0x000298]))\r
+#define MCF_UART_UBG22       (*(vuint8 *)(void*)(&__IPSBAR[0x00029C]))\r
+#define MCF_UART_UIP2        (*(vuint8 *)(void*)(&__IPSBAR[0x0002B4]))\r
+#define MCF_UART_UOP12       (*(vuint8 *)(void*)(&__IPSBAR[0x0002B8]))\r
+#define MCF_UART_UOP02       (*(vuint8 *)(void*)(&__IPSBAR[0x0002BC]))\r
+#define MCF_UART_UMR(x)      (*(vuint8 *)(void*)(&__IPSBAR[0x000200+((x)*0x040)]))\r
+#define MCF_UART_USR(x)      (*(vuint8 *)(void*)(&__IPSBAR[0x000204+((x)*0x040)]))\r
+#define MCF_UART_UCSR(x)     (*(vuint8 *)(void*)(&__IPSBAR[0x000204+((x)*0x040)]))\r
+#define MCF_UART_UCR(x)      (*(vuint8 *)(void*)(&__IPSBAR[0x000208+((x)*0x040)]))\r
+#define MCF_UART_URB(x)      (*(vuint8 *)(void*)(&__IPSBAR[0x00020C+((x)*0x040)]))\r
+#define MCF_UART_UTB(x)      (*(vuint8 *)(void*)(&__IPSBAR[0x00020C+((x)*0x040)]))\r
+#define MCF_UART_UIPCR(x)    (*(vuint8 *)(void*)(&__IPSBAR[0x000210+((x)*0x040)]))\r
+#define MCF_UART_UACR(x)     (*(vuint8 *)(void*)(&__IPSBAR[0x000210+((x)*0x040)]))\r
+#define MCF_UART_UISR(x)     (*(vuint8 *)(void*)(&__IPSBAR[0x000214+((x)*0x040)]))\r
+#define MCF_UART_UIMR(x)     (*(vuint8 *)(void*)(&__IPSBAR[0x000214+((x)*0x040)]))\r
+#define MCF_UART_UBG1(x)     (*(vuint8 *)(void*)(&__IPSBAR[0x000218+((x)*0x040)]))\r
+#define MCF_UART_UBG2(x)     (*(vuint8 *)(void*)(&__IPSBAR[0x00021C+((x)*0x040)]))\r
+#define MCF_UART_UIP(x)      (*(vuint8 *)(void*)(&__IPSBAR[0x000234+((x)*0x040)]))\r
+#define MCF_UART_UOP1(x)     (*(vuint8 *)(void*)(&__IPSBAR[0x000238+((x)*0x040)]))\r
+#define MCF_UART_UOP0(x)     (*(vuint8 *)(void*)(&__IPSBAR[0x00023C+((x)*0x040)]))\r
+\r
+/* Bit definitions and macros for MCF_UART_UMR */\r
+#define MCF_UART_UMR_BC(x)              (((x)&0x03)<<0)\r
+#define MCF_UART_UMR_PT                 (0x04)\r
+#define MCF_UART_UMR_PM(x)              (((x)&0x03)<<3)\r
+#define MCF_UART_UMR_ERR                (0x20)\r
+#define MCF_UART_UMR_RXIRQ              (0x40)\r
+#define MCF_UART_UMR_RXRTS              (0x80)\r
+#define MCF_UART_UMR_SB(x)              (((x)&0x0F)<<0)\r
+#define MCF_UART_UMR_TXCTS              (0x10)\r
+#define MCF_UART_UMR_TXRTS              (0x20)\r
+#define MCF_UART_UMR_CM(x)              (((x)&0x03)<<6)\r
+#define MCF_UART_UMR_PM_MULTI_ADDR      (0x1C)\r
+#define MCF_UART_UMR_PM_MULTI_DATA      (0x18)\r
+#define MCF_UART_UMR_PM_NONE            (0x10)\r
+#define MCF_UART_UMR_PM_FORCE_HI        (0x0C)\r
+#define MCF_UART_UMR_PM_FORCE_LO        (0x08)\r
+#define MCF_UART_UMR_PM_ODD             (0x04)\r
+#define MCF_UART_UMR_PM_EVEN            (0x00)\r
+#define MCF_UART_UMR_BC_5               (0x00)\r
+#define MCF_UART_UMR_BC_6               (0x01)\r
+#define MCF_UART_UMR_BC_7               (0x02)\r
+#define MCF_UART_UMR_BC_8               (0x03)\r
+#define MCF_UART_UMR_CM_NORMAL          (0x00)\r
+#define MCF_UART_UMR_CM_ECHO            (0x40)\r
+#define MCF_UART_UMR_CM_LOCAL_LOOP      (0x80)\r
+#define MCF_UART_UMR_CM_REMOTE_LOOP     (0xC0)\r
+#define MCF_UART_UMR_SB_STOP_BITS_1     (0x07)\r
+#define MCF_UART_UMR_SB_STOP_BITS_15    (0x08)\r
+#define MCF_UART_UMR_SB_STOP_BITS_2     (0x0F)\r
+\r
+/* Bit definitions and macros for MCF_UART_USR */\r
+#define MCF_UART_USR_RXRDY              (0x01)\r
+#define MCF_UART_USR_FFULL              (0x02)\r
+#define MCF_UART_USR_TXRDY              (0x04)\r
+#define MCF_UART_USR_TXEMP              (0x08)\r
+#define MCF_UART_USR_OE                 (0x10)\r
+#define MCF_UART_USR_PE                 (0x20)\r
+#define MCF_UART_USR_FE                 (0x40)\r
+#define MCF_UART_USR_RB                 (0x80)\r
+\r
+/* Bit definitions and macros for MCF_UART_UCSR */\r
+#define MCF_UART_UCSR_TCS(x)            (((x)&0x0F)<<0)\r
+#define MCF_UART_UCSR_RCS(x)            (((x)&0x0F)<<4)\r
+#define MCF_UART_UCSR_RCS_SYS_CLK       (0xD0)\r
+#define MCF_UART_UCSR_RCS_CTM16         (0xE0)\r
+#define MCF_UART_UCSR_RCS_CTM           (0xF0)\r
+#define MCF_UART_UCSR_TCS_SYS_CLK       (0x0D)\r
+#define MCF_UART_UCSR_TCS_CTM16         (0x0E)\r
+#define MCF_UART_UCSR_TCS_CTM           (0x0F)\r
+\r
+/* Bit definitions and macros for MCF_UART_UCR */\r
+#define MCF_UART_UCR_RXC(x)             (((x)&0x03)<<0)\r
+#define MCF_UART_UCR_TXC(x)             (((x)&0x03)<<2)\r
+#define MCF_UART_UCR_MISC(x)            (((x)&0x07)<<4)\r
+#define MCF_UART_UCR_NONE               (0x00)\r
+#define MCF_UART_UCR_STOP_BREAK         (0x70)\r
+#define MCF_UART_UCR_START_BREAK        (0x60)\r
+#define MCF_UART_UCR_BKCHGINT           (0x50)\r
+#define MCF_UART_UCR_RESET_ERROR        (0x40)\r
+#define MCF_UART_UCR_RESET_TX           (0x30)\r
+#define MCF_UART_UCR_RESET_RX           (0x20)\r
+#define MCF_UART_UCR_RESET_MR           (0x10)\r
+#define MCF_UART_UCR_TX_DISABLED        (0x08)\r
+#define MCF_UART_UCR_TX_ENABLED         (0x04)\r
+#define MCF_UART_UCR_RX_DISABLED        (0x02)\r
+#define MCF_UART_UCR_RX_ENABLED         (0x01)\r
+\r
+/* Bit definitions and macros for MCF_UART_UIPCR */\r
+#define MCF_UART_UIPCR_CTS              (0x01)\r
+#define MCF_UART_UIPCR_COS              (0x10)\r
+\r
+/* Bit definitions and macros for MCF_UART_UACR */\r
+#define MCF_UART_UACR_IEC               (0x01)\r
+\r
+/* Bit definitions and macros for MCF_UART_UISR */\r
+#define MCF_UART_UISR_TXRDY             (0x01)\r
+#define MCF_UART_UISR_RXRDY_FU          (0x02)\r
+#define MCF_UART_UISR_DB                (0x04)\r
+#define MCF_UART_UISR_RXFTO             (0x08)\r
+#define MCF_UART_UISR_TXFIFO            (0x10)\r
+#define MCF_UART_UISR_RXFIFO            (0x20)\r
+#define MCF_UART_UISR_COS               (0x80)\r
+\r
+/* Bit definitions and macros for MCF_UART_UIMR */\r
+#define MCF_UART_UIMR_TXRDY             (0x01)\r
+#define MCF_UART_UIMR_RXRDY_FU          (0x02)\r
+#define MCF_UART_UIMR_DB                (0x04)\r
+#define MCF_UART_UIMR_COS               (0x80)\r
+\r
+/* Bit definitions and macros for MCF_UART_UIP */\r
+#define MCF_UART_UIP_CTS                (0x01)\r
+\r
+/* Bit definitions and macros for MCF_UART_UOP1 */\r
+#define MCF_UART_UOP1_RTS               (0x01)\r
+\r
+/* Bit definitions and macros for MCF_UART_UOP0 */\r
+#define MCF_UART_UOP0_RTS               (0x01)\r
+\r
+/********************************************************************/\r
+\r
+#endif /* __MCF523X_UART_H__ */\r
index 4894867917953525d96b9a7e248efafeabbe1f4f..1e5f9f97fe57334a9d6d9f8e8e38d4940c78f224 100644 (file)
@@ -1,92 +1,92 @@
-/*
- * These files are taken from the MCF523X source code example package
- * which is available on the Freescale website. Freescale explicitly 
- * grants the redistribution and modification of these source files.
- * The complete licensing information is available in the file 
- * LICENSE_FREESCALE.TXT.
- *
- * File:       mcf523x_wtm.h
- * Purpose:    Register and bit definitions for the MCF523X
- *
- * Notes:      
- *     
- */
-
-#ifndef __MCF523X_WTM_H__
-#define __MCF523X_WTM_H__
-
-/*********************************************************************
-*
-* Watchdog Timer Modules (WTM)
-*
-*********************************************************************/
-
-/* Register read/write macros */
-#define MCF_WTM_WCR      (*(vuint16*)(void*)(&__IPSBAR[0x140000]))
-#define MCF_WTM_WMR      (*(vuint16*)(void*)(&__IPSBAR[0x140002]))
-#define MCF_WTM_WCNTR    (*(vuint16*)(void*)(&__IPSBAR[0x140004]))
-#define MCF_WTM_WSR      (*(vuint16*)(void*)(&__IPSBAR[0x140006]))
-
-/* Bit definitions and macros for MCF_WTM_WCR */
-#define MCF_WTM_WCR_EN        (0x0001)
-#define MCF_WTM_WCR_HALTED    (0x0002)
-#define MCF_WTM_WCR_DOZE      (0x0004)
-#define MCF_WTM_WCR_WAIT      (0x0008)
-
-/* Bit definitions and macros for MCF_WTM_WMR */
-#define MCF_WTM_WMR_WM0       (0x0001)
-#define MCF_WTM_WMR_WM1       (0x0002)
-#define MCF_WTM_WMR_WM2       (0x0004)
-#define MCF_WTM_WMR_WM3       (0x0008)
-#define MCF_WTM_WMR_WM4       (0x0010)
-#define MCF_WTM_WMR_WM5       (0x0020)
-#define MCF_WTM_WMR_WM6       (0x0040)
-#define MCF_WTM_WMR_WM7       (0x0080)
-#define MCF_WTM_WMR_WM8       (0x0100)
-#define MCF_WTM_WMR_WM9       (0x0200)
-#define MCF_WTM_WMR_WM10      (0x0400)
-#define MCF_WTM_WMR_WM11      (0x0800)
-#define MCF_WTM_WMR_WM12      (0x1000)
-#define MCF_WTM_WMR_WM13      (0x2000)
-#define MCF_WTM_WMR_WM14      (0x4000)
-#define MCF_WTM_WMR_WM15      (0x8000)
-
-/* Bit definitions and macros for MCF_WTM_WCNTR */
-#define MCF_WTM_WCNTR_WC0     (0x0001)
-#define MCF_WTM_WCNTR_WC1     (0x0002)
-#define MCF_WTM_WCNTR_WC2     (0x0004)
-#define MCF_WTM_WCNTR_WC3     (0x0008)
-#define MCF_WTM_WCNTR_WC4     (0x0010)
-#define MCF_WTM_WCNTR_WC5     (0x0020)
-#define MCF_WTM_WCNTR_WC6     (0x0040)
-#define MCF_WTM_WCNTR_WC7     (0x0080)
-#define MCF_WTM_WCNTR_WC8     (0x0100)
-#define MCF_WTM_WCNTR_WC9     (0x0200)
-#define MCF_WTM_WCNTR_WC10    (0x0400)
-#define MCF_WTM_WCNTR_WC11    (0x0800)
-#define MCF_WTM_WCNTR_WC12    (0x1000)
-#define MCF_WTM_WCNTR_WC13    (0x2000)
-#define MCF_WTM_WCNTR_WC14    (0x4000)
-#define MCF_WTM_WCNTR_WC15    (0x8000)
-
-/* Bit definitions and macros for MCF_WTM_WSR */
-#define MCF_WTM_WSR_WS0       (0x0001)
-#define MCF_WTM_WSR_WS1       (0x0002)
-#define MCF_WTM_WSR_WS2       (0x0004)
-#define MCF_WTM_WSR_WS3       (0x0008)
-#define MCF_WTM_WSR_WS4       (0x0010)
-#define MCF_WTM_WSR_WS5       (0x0020)
-#define MCF_WTM_WSR_WS6       (0x0040)
-#define MCF_WTM_WSR_WS7       (0x0080)
-#define MCF_WTM_WSR_WS8       (0x0100)
-#define MCF_WTM_WSR_WS9       (0x0200)
-#define MCF_WTM_WSR_WS10      (0x0400)
-#define MCF_WTM_WSR_WS11      (0x0800)
-#define MCF_WTM_WSR_WS12      (0x1000)
-#define MCF_WTM_WSR_WS13      (0x2000)
-#define MCF_WTM_WSR_WS14      (0x4000)
-#define MCF_WTM_WSR_WS15      (0x8000)
-
-/********************************************************************/
-
-#endif /* __MCF523X_WTM_H__ */
+/*\r
+ * These files are taken from the MCF523X source code example package\r
+ * which is available on the Freescale website. Freescale explicitly \r
+ * grants the redistribution and modification of these source files.\r
+ * The complete licensing information is available in the file \r
+ * LICENSE_FREESCALE.TXT.\r
+ *\r
+ * File:       mcf523x_wtm.h\r
+ * Purpose:    Register and bit definitions for the MCF523X\r
+ *\r
+ * Notes:      \r
+ *     \r
+ */\r
+\r
+#ifndef __MCF523X_WTM_H__\r
+#define __MCF523X_WTM_H__\r
+\r
+/*********************************************************************\r
+*\r
+* Watchdog Timer Modules (WTM)\r
+*\r
+*********************************************************************/\r
+\r
+/* Register read/write macros */\r
+#define MCF_WTM_WCR      (*(vuint16*)(void*)(&__IPSBAR[0x140000]))\r
+#define MCF_WTM_WMR      (*(vuint16*)(void*)(&__IPSBAR[0x140002]))\r
+#define MCF_WTM_WCNTR    (*(vuint16*)(void*)(&__IPSBAR[0x140004]))\r
+#define MCF_WTM_WSR      (*(vuint16*)(void*)(&__IPSBAR[0x140006]))\r
+\r
+/* Bit definitions and macros for MCF_WTM_WCR */\r
+#define MCF_WTM_WCR_EN        (0x0001)\r
+#define MCF_WTM_WCR_HALTED    (0x0002)\r
+#define MCF_WTM_WCR_DOZE      (0x0004)\r
+#define MCF_WTM_WCR_WAIT      (0x0008)\r
+\r
+/* Bit definitions and macros for MCF_WTM_WMR */\r
+#define MCF_WTM_WMR_WM0       (0x0001)\r
+#define MCF_WTM_WMR_WM1       (0x0002)\r
+#define MCF_WTM_WMR_WM2       (0x0004)\r
+#define MCF_WTM_WMR_WM3       (0x0008)\r
+#define MCF_WTM_WMR_WM4       (0x0010)\r
+#define MCF_WTM_WMR_WM5       (0x0020)\r
+#define MCF_WTM_WMR_WM6       (0x0040)\r
+#define MCF_WTM_WMR_WM7       (0x0080)\r
+#define MCF_WTM_WMR_WM8       (0x0100)\r
+#define MCF_WTM_WMR_WM9       (0x0200)\r
+#define MCF_WTM_WMR_WM10      (0x0400)\r
+#define MCF_WTM_WMR_WM11      (0x0800)\r
+#define MCF_WTM_WMR_WM12      (0x1000)\r
+#define MCF_WTM_WMR_WM13      (0x2000)\r
+#define MCF_WTM_WMR_WM14      (0x4000)\r
+#define MCF_WTM_WMR_WM15      (0x8000)\r
+\r
+/* Bit definitions and macros for MCF_WTM_WCNTR */\r
+#define MCF_WTM_WCNTR_WC0     (0x0001)\r
+#define MCF_WTM_WCNTR_WC1     (0x0002)\r
+#define MCF_WTM_WCNTR_WC2     (0x0004)\r
+#define MCF_WTM_WCNTR_WC3     (0x0008)\r
+#define MCF_WTM_WCNTR_WC4     (0x0010)\r
+#define MCF_WTM_WCNTR_WC5     (0x0020)\r
+#define MCF_WTM_WCNTR_WC6     (0x0040)\r
+#define MCF_WTM_WCNTR_WC7     (0x0080)\r
+#define MCF_WTM_WCNTR_WC8     (0x0100)\r
+#define MCF_WTM_WCNTR_WC9     (0x0200)\r
+#define MCF_WTM_WCNTR_WC10    (0x0400)\r
+#define MCF_WTM_WCNTR_WC11    (0x0800)\r
+#define MCF_WTM_WCNTR_WC12    (0x1000)\r
+#define MCF_WTM_WCNTR_WC13    (0x2000)\r
+#define MCF_WTM_WCNTR_WC14    (0x4000)\r
+#define MCF_WTM_WCNTR_WC15    (0x8000)\r
+\r
+/* Bit definitions and macros for MCF_WTM_WSR */\r
+#define MCF_WTM_WSR_WS0       (0x0001)\r
+#define MCF_WTM_WSR_WS1       (0x0002)\r
+#define MCF_WTM_WSR_WS2       (0x0004)\r
+#define MCF_WTM_WSR_WS3       (0x0008)\r
+#define MCF_WTM_WSR_WS4       (0x0010)\r
+#define MCF_WTM_WSR_WS5       (0x0020)\r
+#define MCF_WTM_WSR_WS6       (0x0040)\r
+#define MCF_WTM_WSR_WS7       (0x0080)\r
+#define MCF_WTM_WSR_WS8       (0x0100)\r
+#define MCF_WTM_WSR_WS9       (0x0200)\r
+#define MCF_WTM_WSR_WS10      (0x0400)\r
+#define MCF_WTM_WSR_WS11      (0x0800)\r
+#define MCF_WTM_WSR_WS12      (0x1000)\r
+#define MCF_WTM_WSR_WS13      (0x2000)\r
+#define MCF_WTM_WSR_WS14      (0x4000)\r
+#define MCF_WTM_WSR_WS15      (0x8000)\r
+\r
+/********************************************************************/\r
+\r
+#endif /* __MCF523X_WTM_H__ */\r
index 692d690e149e40561ae9af4bf2978da81e280f33..01153e4090c70e5ecd8d256085d6e0176e595dcf 100644 (file)
-/*
- * These files are taken from the MCF523X source code example package
- * which is available on the Freescale website. Freescale explicitly 
- * grants the redistribution and modification of these source files.
- * The complete licensing information is available in the file 
- * LICENSE_FREESCALE.TXT.
- *
- * File:               mcf5xxx.h
- * Purpose:            Definitions common to all ColdFire processors
- *
- * Notes:
- */
-
-#ifndef _CPU_MCF5XXX_H
-#define _CPU_MCF5XXX_H
-
-/***********************************************************************/
-/*
- * Misc. Defines
- */
-
-#ifdef FALSE
-#undef FALSE
-#endif
-#define FALSE  (0)
-
-#ifdef TRUE
-#undef TRUE
-#endif
-#define        TRUE    (1)
-
-#ifdef NULL
-#undef NULL
-#endif
-#define NULL   (0)
-
-/***********************************************************************/
-/*
- * The basic data types
- */
-
-typedef unsigned char          uint8;  /*  8 bits */
-typedef unsigned short int     uint16; /* 16 bits */
-typedef unsigned long int      uint32; /* 32 bits */
-
-typedef signed char                    int8;   /*  8 bits */
-typedef signed short int       int16;  /* 16 bits */
-typedef signed long int                int32;  /* 32 bits */
-
-typedef volatile uint8         vuint8;  /*  8 bits */
-typedef volatile uint16                vuint16; /* 16 bits */
-typedef volatile uint32                vuint32; /* 32 bits */
-
-/***********************************************************************/
-/*
- * Common M68K & ColdFire definitions
- */
-
-#define ADDRESS                        uint32
-#define INSTRUCTION            uint16
-#define ILLEGAL                        0x4AFC
-#define CPU_WORD_SIZE  16
-
-#define MCF5XXX_SR_T           (0x8000)
-#define MCF5XXX_SR_S           (0x2000)
-#define MCF5XXX_SR_M           (0x1000)
-#define MCF5XXX_SR_IPL         (0x0700)
-#define MCF5XXX_SR_IPL_0       (0x0000)
-#define MCF5XXX_SR_IPL_1       (0x0100)
-#define MCF5XXX_SR_IPL_2       (0x0200)
-#define MCF5XXX_SR_IPL_3       (0x0300)
-#define MCF5XXX_SR_IPL_4       (0x0400)
-#define MCF5XXX_SR_IPL_5       (0x0500)
-#define MCF5XXX_SR_IPL_6       (0x0600)
-#define MCF5XXX_SR_IPL_7       (0x0700)
-#define MCF5XXX_SR_X           (0x0010)
-#define MCF5XXX_SR_N           (0x0008)
-#define MCF5XXX_SR_Z           (0x0004)
-#define MCF5XXX_SR_V           (0x0002)
-#define MCF5XXX_SR_C           (0x0001)
-
-#define MCF5XXX_CACR_CENB              (0x80000000)
-#define MCF5XXX_CACR_CPDI              (0x10000000)
-#define MCF5XXX_CACR_CPD               (0x10000000)
-#define MCF5XXX_CACR_CFRZ              (0x08000000)
-#define MCF5XXX_CACR_CINV              (0x01000000)
-#define MCF5XXX_CACR_DIDI              (0x00800000)
-#define MCF5XXX_CACR_DISD              (0x00400000)
-#define MCF5XXX_CACR_INVI              (0x00200000)
-#define MCF5XXX_CACR_INVD              (0x00100000)
-#define MCF5XXX_CACR_CEIB              (0x00000400)
-#define MCF5XXX_CACR_DCM_WR            (0x00000000)
-#define MCF5XXX_CACR_DCM_CB            (0x00000100)
-#define MCF5XXX_CACR_DCM_IP            (0x00000200)
-#define MCF5XXX_CACR_DCM               (0x00000200)
-#define MCF5XXX_CACR_DCM_II            (0x00000300)
-#define MCF5XXX_CACR_DBWE              (0x00000100)
-#define MCF5XXX_CACR_DWP               (0x00000020)
-#define MCF5XXX_CACR_EUST              (0x00000010)
-#define MCF5XXX_CACR_CLNF_00   (0x00000000)
-#define MCF5XXX_CACR_CLNF_01   (0x00000002)
-#define MCF5XXX_CACR_CLNF_10   (0x00000004)
-#define MCF5XXX_CACR_CLNF_11   (0x00000006)
-
-#define MCF5XXX_ACR_AB(a)              ((a)&0xFF000000)
-#define MCF5XXX_ACR_AM(a)              (((a)&0xFF000000) >> 8)
-#define MCF5XXX_ACR_EN                 (0x00008000)
-#define MCF5XXX_ACR_SM_USER            (0x00000000)
-#define MCF5XXX_ACR_SM_SUPER   (0x00002000)
-#define MCF5XXX_ACR_SM_IGNORE  (0x00006000)
-#define MCF5XXX_ACR_ENIB               (0x00000080)
-#define MCF5XXX_ACR_CM                 (0x00000040)
-#define MCF5XXX_ACR_DCM_WR             (0x00000000)
-#define MCF5XXX_ACR_DCM_CB             (0x00000020)
-#define MCF5XXX_ACR_DCM_IP             (0x00000040)
-#define MCF5XXX_ACR_DCM_II             (0x00000060)
-#define MCF5XXX_ACR_CM                 (0x00000040)
-#define MCF5XXX_ACR_BWE                        (0x00000020)
-#define MCF5XXX_ACR_WP                 (0x00000004)
-
-#define MCF5XXX_RAMBAR_BA(a)   ((a)&0xFFFFC000)
-#define MCF5XXX_RAMBAR_PRI_00  (0x00000000)
-#define MCF5XXX_RAMBAR_PRI_01  (0x00004000)
-#define MCF5XXX_RAMBAR_PRI_10  (0x00008000)
-#define MCF5XXX_RAMBAR_PRI_11  (0x0000C000)
-#define MCF5XXX_RAMBAR_WP              (0x00000100)
-#define MCF5XXX_RAMBAR_CI              (0x00000020)
-#define MCF5XXX_RAMBAR_SC              (0x00000010)
-#define MCF5XXX_RAMBAR_SD              (0x00000008)
-#define MCF5XXX_RAMBAR_UC              (0x00000004)
-#define MCF5XXX_RAMBAR_UD              (0x00000002)
-#define MCF5XXX_RAMBAR_V               (0x00000001)
-
-/***********************************************************************/
-/*
- * The ColdFire family of processors has a simplified exception stack
- * frame that looks like the following:
- *
- *              3322222222221111 111111
- *              1098765432109876 5432109876543210
- *           8 +----------------+----------------+
- *             |         Program Counter         |
- *           4 +----------------+----------------+
- *             |FS/Fmt/Vector/FS|      SR        |
- *   SP -->  0 +----------------+----------------+
- *
- * The stack self-aligns to a 4-byte boundary at an exception, with
- * the FS/Fmt/Vector/FS field indicating the size of the adjustment
- * (SP += 0,1,2,3 bytes).
- */
-
-#define MCF5XXX_RD_SF_FORMAT(PTR)      \
-       ((*((uint16 *)(PTR)) >> 12) & 0x00FF)
-
-#define MCF5XXX_RD_SF_VECTOR(PTR)      \
-       ((*((uint16 *)(PTR)) >>  2) & 0x00FF)
-
-#define MCF5XXX_RD_SF_FS(PTR)          \
-       ( ((*((uint16 *)(PTR)) & 0x0C00) >> 8) | (*((uint16 *)(PTR)) & 0x0003) )
-
-#define MCF5XXX_SF_SR(PTR)     *((uint16 *)(PTR)+1)
-#define MCF5XXX_SF_PC(PTR)     *((uint32 *)(PTR)+1)
-
-/********************************************************************/
-/*
- * Functions provided by mcf5xxx.s
- */
-int    asm_set_ipl (uint32);
-void   mcf5xxx_wr_cacr (uint32);
-void   mcf5xxx_wr_acr0 (uint32);
-void   mcf5xxx_wr_acr1 (uint32);
-void   mcf5xxx_wr_acr2 (uint32);
-void   mcf5xxx_wr_acr3 (uint32);
-void   mcf5xxx_wr_other_a7 (uint32);
-void   mcf5xxx_wr_other_sp (uint32);
-void   mcf5xxx_wr_vbr (uint32);
-void   mcf5xxx_wr_macsr (uint32);
-void   mcf5xxx_wr_mask (uint32);
-void   mcf5xxx_wr_acc0 (uint32);
-void   mcf5xxx_wr_accext01 (uint32);
-void   mcf5xxx_wr_accext23 (uint32);
-void   mcf5xxx_wr_acc1 (uint32);
-void   mcf5xxx_wr_acc2 (uint32);
-void   mcf5xxx_wr_acc3 (uint32);
-void   mcf5xxx_wr_sr (uint32);
-void   mcf5xxx_wr_rambar0 (uint32);
-void   mcf5xxx_wr_rambar1 (uint32);
-void   mcf5xxx_wr_mbar (uint32);
-void   mcf5xxx_wr_mbar0 (uint32);
-void   mcf5xxx_wr_mbar1 (uint32);
-
-/********************************************************************/
-
-#endif /* _CPU_MCF5XXX_H */
-
+/*\r
+ * These files are taken from the MCF523X source code example package\r
+ * which is available on the Freescale website. Freescale explicitly \r
+ * grants the redistribution and modification of these source files.\r
+ * The complete licensing information is available in the file \r
+ * LICENSE_FREESCALE.TXT.\r
+ *\r
+ * File:               mcf5xxx.h\r
+ * Purpose:            Definitions common to all ColdFire processors\r
+ *\r
+ * Notes:\r
+ */\r
+\r
+#ifndef _CPU_MCF5XXX_H\r
+#define _CPU_MCF5XXX_H\r
+\r
+/***********************************************************************/\r
+/*\r
+ * Misc. Defines\r
+ */\r
+\r
+#ifdef FALSE\r
+#undef FALSE\r
+#endif\r
+#define FALSE  (0)\r
+\r
+#ifdef TRUE\r
+#undef TRUE\r
+#endif\r
+#define        TRUE    (1)\r
+\r
+#ifdef NULL\r
+#undef NULL\r
+#endif\r
+#define NULL   (0)\r
+\r
+/***********************************************************************/\r
+/*\r
+ * The basic data types\r
+ */\r
+\r
+typedef unsigned char          uint8;  /*  8 bits */\r
+typedef unsigned short int     uint16; /* 16 bits */\r
+typedef unsigned long int      uint32; /* 32 bits */\r
+\r
+typedef signed char                    int8;   /*  8 bits */\r
+typedef signed short int       int16;  /* 16 bits */\r
+typedef signed long int                int32;  /* 32 bits */\r
+\r
+typedef volatile uint8         vuint8;  /*  8 bits */\r
+typedef volatile uint16                vuint16; /* 16 bits */\r
+typedef volatile uint32                vuint32; /* 32 bits */\r
+\r
+/***********************************************************************/\r
+/*\r
+ * Common M68K & ColdFire definitions\r
+ */\r
+\r
+#define ADDRESS                        uint32\r
+#define INSTRUCTION            uint16\r
+#define ILLEGAL                        0x4AFC\r
+#define CPU_WORD_SIZE  16\r
+\r
+#define MCF5XXX_SR_T           (0x8000)\r
+#define MCF5XXX_SR_S           (0x2000)\r
+#define MCF5XXX_SR_M           (0x1000)\r
+#define MCF5XXX_SR_IPL         (0x0700)\r
+#define MCF5XXX_SR_IPL_0       (0x0000)\r
+#define MCF5XXX_SR_IPL_1       (0x0100)\r
+#define MCF5XXX_SR_IPL_2       (0x0200)\r
+#define MCF5XXX_SR_IPL_3       (0x0300)\r
+#define MCF5XXX_SR_IPL_4       (0x0400)\r
+#define MCF5XXX_SR_IPL_5       (0x0500)\r
+#define MCF5XXX_SR_IPL_6       (0x0600)\r
+#define MCF5XXX_SR_IPL_7       (0x0700)\r
+#define MCF5XXX_SR_X           (0x0010)\r
+#define MCF5XXX_SR_N           (0x0008)\r
+#define MCF5XXX_SR_Z           (0x0004)\r
+#define MCF5XXX_SR_V           (0x0002)\r
+#define MCF5XXX_SR_C           (0x0001)\r
+\r
+#define MCF5XXX_CACR_CENB              (0x80000000)\r
+#define MCF5XXX_CACR_CPDI              (0x10000000)\r
+#define MCF5XXX_CACR_CPD               (0x10000000)\r
+#define MCF5XXX_CACR_CFRZ              (0x08000000)\r
+#define MCF5XXX_CACR_CINV              (0x01000000)\r
+#define MCF5XXX_CACR_DIDI              (0x00800000)\r
+#define MCF5XXX_CACR_DISD              (0x00400000)\r
+#define MCF5XXX_CACR_INVI              (0x00200000)\r
+#define MCF5XXX_CACR_INVD              (0x00100000)\r
+#define MCF5XXX_CACR_CEIB              (0x00000400)\r
+#define MCF5XXX_CACR_DCM_WR            (0x00000000)\r
+#define MCF5XXX_CACR_DCM_CB            (0x00000100)\r
+#define MCF5XXX_CACR_DCM_IP            (0x00000200)\r
+#define MCF5XXX_CACR_DCM               (0x00000200)\r
+#define MCF5XXX_CACR_DCM_II            (0x00000300)\r
+#define MCF5XXX_CACR_DBWE              (0x00000100)\r
+#define MCF5XXX_CACR_DWP               (0x00000020)\r
+#define MCF5XXX_CACR_EUST              (0x00000010)\r
+#define MCF5XXX_CACR_CLNF_00   (0x00000000)\r
+#define MCF5XXX_CACR_CLNF_01   (0x00000002)\r
+#define MCF5XXX_CACR_CLNF_10   (0x00000004)\r
+#define MCF5XXX_CACR_CLNF_11   (0x00000006)\r
+\r
+#define MCF5XXX_ACR_AB(a)              ((a)&0xFF000000)\r
+#define MCF5XXX_ACR_AM(a)              (((a)&0xFF000000) >> 8)\r
+#define MCF5XXX_ACR_EN                 (0x00008000)\r
+#define MCF5XXX_ACR_SM_USER            (0x00000000)\r
+#define MCF5XXX_ACR_SM_SUPER   (0x00002000)\r
+#define MCF5XXX_ACR_SM_IGNORE  (0x00006000)\r
+#define MCF5XXX_ACR_ENIB               (0x00000080)\r
+#define MCF5XXX_ACR_CM                 (0x00000040)\r
+#define MCF5XXX_ACR_DCM_WR             (0x00000000)\r
+#define MCF5XXX_ACR_DCM_CB             (0x00000020)\r
+#define MCF5XXX_ACR_DCM_IP             (0x00000040)\r
+#define MCF5XXX_ACR_DCM_II             (0x00000060)\r
+#define MCF5XXX_ACR_CM                 (0x00000040)\r
+#define MCF5XXX_ACR_BWE                        (0x00000020)\r
+#define MCF5XXX_ACR_WP                 (0x00000004)\r
+\r
+#define MCF5XXX_RAMBAR_BA(a)   ((a)&0xFFFFC000)\r
+#define MCF5XXX_RAMBAR_PRI_00  (0x00000000)\r
+#define MCF5XXX_RAMBAR_PRI_01  (0x00004000)\r
+#define MCF5XXX_RAMBAR_PRI_10  (0x00008000)\r
+#define MCF5XXX_RAMBAR_PRI_11  (0x0000C000)\r
+#define MCF5XXX_RAMBAR_WP              (0x00000100)\r
+#define MCF5XXX_RAMBAR_CI              (0x00000020)\r
+#define MCF5XXX_RAMBAR_SC              (0x00000010)\r
+#define MCF5XXX_RAMBAR_SD              (0x00000008)\r
+#define MCF5XXX_RAMBAR_UC              (0x00000004)\r
+#define MCF5XXX_RAMBAR_UD              (0x00000002)\r
+#define MCF5XXX_RAMBAR_V               (0x00000001)\r
+\r
+/***********************************************************************/\r
+/*\r
+ * The ColdFire family of processors has a simplified exception stack\r
+ * frame that looks like the following:\r
+ *\r
+ *              3322222222221111 111111\r
+ *              1098765432109876 5432109876543210\r
+ *           8 +----------------+----------------+\r
+ *             |         Program Counter         |\r
+ *           4 +----------------+----------------+\r
+ *             |FS/Fmt/Vector/FS|      SR        |\r
+ *   SP -->  0 +----------------+----------------+\r
+ *\r
+ * The stack self-aligns to a 4-byte boundary at an exception, with\r
+ * the FS/Fmt/Vector/FS field indicating the size of the adjustment\r
+ * (SP += 0,1,2,3 bytes).\r
+ */\r
+\r
+#define MCF5XXX_RD_SF_FORMAT(PTR)      \\r
+       ((*((uint16 *)(PTR)) >> 12) & 0x00FF)\r
+\r
+#define MCF5XXX_RD_SF_VECTOR(PTR)      \\r
+       ((*((uint16 *)(PTR)) >>  2) & 0x00FF)\r
+\r
+#define MCF5XXX_RD_SF_FS(PTR)          \\r
+       ( ((*((uint16 *)(PTR)) & 0x0C00) >> 8) | (*((uint16 *)(PTR)) & 0x0003) )\r
+\r
+#define MCF5XXX_SF_SR(PTR)     *((uint16 *)(PTR)+1)\r
+#define MCF5XXX_SF_PC(PTR)     *((uint32 *)(PTR)+1)\r
+\r
+/********************************************************************/\r
+/*\r
+ * Functions provided by mcf5xxx.s\r
+ */\r
\r
+int    asm_set_ipl (uint32);\r
+void   mcf5xxx_wr_cacr (uint32);\r
+void   mcf5xxx_wr_acr0 (uint32);\r
+void   mcf5xxx_wr_acr1 (uint32);\r
+void   mcf5xxx_wr_acr2 (uint32);\r
+void   mcf5xxx_wr_acr3 (uint32);\r
+void   mcf5xxx_wr_other_a7 (uint32);\r
+void   mcf5xxx_wr_other_sp (uint32);\r
+void   mcf5xxx_wr_vbr (uint32);\r
+void   mcf5xxx_wr_macsr (uint32);\r
+void   mcf5xxx_wr_mask (uint32);\r
+void   mcf5xxx_wr_acc0 (uint32);\r
+void   mcf5xxx_wr_accext01 (uint32);\r
+void   mcf5xxx_wr_accext23 (uint32);\r
+void   mcf5xxx_wr_acc1 (uint32);\r
+void   mcf5xxx_wr_acc2 (uint32);\r
+void   mcf5xxx_wr_acc3 (uint32);\r
+void   mcf5xxx_wr_sr (uint32);\r
+void   mcf5xxx_wr_rambar0 (uint32);\r
+void   mcf5xxx_wr_rambar1 (uint32);\r
+void   mcf5xxx_wr_mbar (uint32);\r
+void   mcf5xxx_wr_mbar0 (uint32);\r
+void   mcf5xxx_wr_mbar1 (uint32);\r
+\r
+/********************************************************************/\r
+\r
+#endif /* _CPU_MCF5XXX_H */\r
+\r
index 377f219f831fb01e53359dc14a4273851dc84dd3..f1a83ffd6ba5c96d8b0adaeee5fb7efd3c6942a9 100644 (file)
@@ -1,77 +1,77 @@
-/*
- * 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 <adam@sics.se>
- * Modifcations: Christian Walter <wolti@sil.at>
- */
-#ifndef __CC_H__
-#define __CC_H__
-
-/* ------------------------ System includes ------------------------------- */
-#include <string.h>
-
-/* ------------------------ Project includes ------------------------------ */
-#include "cpu.h"
-#include "sys_arch.h"
-
-/* ------------------------ Defines --------------------------------------- */
-
-#define PACK_STRUCT_BEGIN
-#define PACK_STRUCT_STRUCT      __attribute__ ((__packed__))
-#define PACK_STRUCT_END
-
-#define PACK_STRUCT_FIELD( x )  x
-
-#define ALIGN_STRUCT_8_BEGIN
-#define ALIGN_STRUCT_8          __attribute__ ((aligned (8)))
-#define ALIGN_STRUCT_8_END
-
-#define LWIP_PLATFORM_ASSERT( x ) sys_assert( x )
-#define LWIP_PLATFORM_DIAG( x, ... ) do{ sys_debug x; } while( 0 );
-
-/* Define (sn)printf formatters for these lwIP types */
-#define U16_F                   "hu"
-#define S16_F                   "hd"
-#define X16_F                   "hx"
-#define U32_F                   "lu"
-#define S32_F                   "ld"
-#define X32_F                   "lx"
-
-/* ------------------------ Type definitions (lwIP) ----------------------- */
-typedef unsigned char u8_t;
-typedef signed char s8_t;
-typedef unsigned short u16_t;
-typedef signed short s16_t;
-typedef unsigned long u32_t;
-typedef signed long s32_t;
-typedef u32_t   mem_ptr_t;
-typedef int     sys_prot_t;
-
-/* ------------------------ Prototypes ------------------------------------ */
-
-#endif
+/*\r
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without modification,\r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED\r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT\r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY\r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ *\r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ * Modifcations: Christian Walter <wolti@sil.at>\r
+ */\r
+#ifndef __CC_H__\r
+#define __CC_H__\r
+\r
+/* ------------------------ System includes ------------------------------- */\r
+#include <string.h>\r
+\r
+/* ------------------------ Project includes ------------------------------ */\r
+#include "cpu.h"\r
+#include "sys_arch.h"\r
+\r
+/* ------------------------ Defines --------------------------------------- */\r
+\r
+#define PACK_STRUCT_BEGIN\r
+#define PACK_STRUCT_STRUCT      __attribute__ ((__packed__))\r
+#define PACK_STRUCT_END\r
+\r
+#define PACK_STRUCT_FIELD( x )  x\r
+\r
+#define ALIGN_STRUCT_8_BEGIN\r
+#define ALIGN_STRUCT_8          __attribute__ ((aligned (8)))\r
+#define ALIGN_STRUCT_8_END\r
+\r
+#define LWIP_PLATFORM_ASSERT( x ) sys_assert( x )\r
+#define LWIP_PLATFORM_DIAG( x, ... ) do{ sys_debug x; } while( 0 );\r
+\r
+/* Define (sn)printf formatters for these lwIP types */\r
+#define U16_F                   "hu"\r
+#define S16_F                   "hd"\r
+#define X16_F                   "hx"\r
+#define U32_F                   "lu"\r
+#define S32_F                   "ld"\r
+#define X32_F                   "lx"\r
+\r
+/* ------------------------ Type definitions (lwIP) ----------------------- */\r
+typedef unsigned char u8_t;\r
+typedef signed char s8_t;\r
+typedef unsigned short u16_t;\r
+typedef signed short s16_t;\r
+typedef unsigned long u32_t;\r
+typedef signed long s32_t;\r
+typedef u32_t   mem_ptr_t;\r
+typedef int     sys_prot_t;\r
+\r
+/* ------------------------ Prototypes ------------------------------------ */\r
+\r
+#endif\r
index 743f808109ddde1702115857fc1e2b1e6dadbac9..fcdb1bc1d0a58a2ee1604771e753b8195883ee4e 100644 (file)
@@ -1,38 +1,38 @@
-/*
- * 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 <adam@sics.se>
- *
- */
-#ifndef __CPU_H__
-#define __CPU_H__
-
-/* ------------------------ Defines --------------------------------------- */
-#define BYTE_ORDER BIG_ENDIAN
-
-#endif
+/*\r
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without modification,\r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED\r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT\r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY\r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ *\r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+#ifndef __CPU_H__\r
+#define __CPU_H__\r
+\r
+/* ------------------------ Defines --------------------------------------- */\r
+#define BYTE_ORDER BIG_ENDIAN\r
+\r
+#endif\r
index f94640e9f022998fd475128c1b6a05a1d034a959..5c58a65123dca7a914dfd2dbaa00330cd9e42b07 100644 (file)
@@ -1,39 +1,39 @@
-/*
- * 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 <adam@sics.se>
- *
- */
-#ifndef __PERF_H__
-#define __PERF_H__
-
-/* ------------------------ Defines --------------------------------------- */
-#define PERF_START              /* null definition */
-#define PERF_STOP(x)            /* null definition */
-
-#endif
+/*\r
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without modification,\r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED\r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT\r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY\r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ *\r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+#ifndef __PERF_H__\r
+#define __PERF_H__\r
+\r
+/* ------------------------ Defines --------------------------------------- */\r
+#define PERF_START              /* null definition */\r
+#define PERF_STOP(x)            /* null definition */\r
+\r
+#endif\r
index 9e47406ca171663fb5f7f060bb7f1c0f45af5946..e1ea31da8734e06b906a729fc326bc5af62f1e9f 100644 (file)
@@ -1,62 +1,62 @@
-/*
- * 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 <adam@sics.se>
- *
- */
-#ifndef __SYS_ARCH_H__
-#define __SYS_ARCH_H__
-
-/* ------------------------ Project includes ------------------------------ */
-#include "FreeRTOS.h"
-#include "task.h"
-#include "queue.h"
-#include "semphr.h"
-
-/* ------------------------ Defines --------------------------------------- */
-#define SYS_MBOX_NULL           ( xQueueHandle )0
-#define SYS_THREAD_NULL         NULL
-#define SYS_SEM_NULL            ( xSemaphoreHandle )0
-#define SIO_FD_NULL             ( sio_fd_t )NULL
-
-/* ------------------------ Type definitions ------------------------------ */
-
-
-typedef xSemaphoreHandle sys_sem_t;
-typedef xQueueHandle sys_mbox_t;
-typedef void   *sys_thread_t;
-
-/* ------------------------ Prototypes ------------------------------------ */
-sys_thread_t    sys_arch_thread_new( void ( *thread ) ( void *arg ), void *arg,
-                                     int prio, size_t ssize );
-sys_thread_t    sys_arch_thread_current( void );
-void            sys_arch_thread_remove( sys_thread_t hdl );
-void            sys_assert( const char *const msg );
-void            sys_debug( const char *const fmt, ... );
-
-#endif
+/*\r
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without modification,\r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED\r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT\r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY\r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ *\r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+#ifndef __SYS_ARCH_H__\r
+#define __SYS_ARCH_H__\r
+\r
+/* ------------------------ Project includes ------------------------------ */\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+#include "queue.h"\r
+#include "semphr.h"\r
+\r
+/* ------------------------ Defines --------------------------------------- */\r
+#define SYS_MBOX_NULL           ( xQueueHandle )0\r
+#define SYS_THREAD_NULL         NULL\r
+#define SYS_SEM_NULL            ( xSemaphoreHandle )0\r
+#define SIO_FD_NULL             ( sio_fd_t )NULL\r
+\r
+/* ------------------------ Type definitions ------------------------------ */\r
+\r
+\r
+typedef xSemaphoreHandle sys_sem_t;\r
+typedef xQueueHandle sys_mbox_t;\r
+typedef void   *sys_thread_t;\r
+\r
+/* ------------------------ Prototypes ------------------------------------ */\r
+sys_thread_t    sys_arch_thread_new( void ( *thread ) ( void *arg ), void *arg,\r
+                                     int prio, size_t ssize );\r
+sys_thread_t    sys_arch_thread_current( void );\r
+void            sys_arch_thread_remove( sys_thread_t hdl );\r
+void            sys_assert( const char *const msg );\r
+void            sys_debug( const char *const fmt, ... );\r
+\r
+#endif\r
index d114dfb7c884581704836f75993074aa66afa8d7..a1c7605e311b40e01b5dcf93fed6c74029902ab5 100644 (file)
-/*
- * Copyright (c) 2006 Christian Walter
- * 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.
- *
- * Author: Christian Walter <wolti@sil.at>
- *
- * TODO:
- *  - Introduce another task create function in the sys_arch layer which allows
- *    for passing the stack size.
- *  - Avoid copying the buffers - this requires changeing the nbuf driver code
- *    to use the lwIP pbuf buffer implementation.
- *
- * File: $Id: fec.c,v 1.3 2006/08/29 18:53:46 wolti Exp $
- */
-
-/* ------------------------ System includes ------------------------------- */
-#include <stdlib.h>
-
-/* ------------------------ Platform includes ----------------------------- */
-#include "mcf5xxx.h"
-#include "mcf523x.h"
-
-#include "nbuf.h"
-
-/* ------------------------ lwIP includes --------------------------------- */
-#include "lwip/opt.h"
-#include "lwip/def.h"
-#include "lwip/mem.h"
-#include "lwip/pbuf.h"
-#include "lwip/sys.h"
-#include "lwip/stats.h"
-#include "lwip/debug.h"
-#include "netif/etharp.h"
-
-/* ------------------------ Defines --------------------------------------- */
-#ifdef FEC_DEBUG
-#define FEC_DEBUG_INIT \
-    do \
-    { \
-        MCF_GPIO_PDDR_FECI2C = ( MCF_GPIO_PDDR_FECI2C_PDDR_FECI2C0 | \
-                                 MCF_GPIO_PDDR_FECI2C_PDDR_FECI2C1 ); \
-    } while( 0 )
-
-#define FEC_DEBUG_RX_TIMING( x ) \
-    do \
-    { \
-        if( x ) \
-            MCF_GPIO_PPDSDR_FECI2C = MCF_GPIO_PDDR_FECI2C_PDDR_FECI2C0; \
-        else \
-            MCF_GPIO_PCLRR_FECI2C = ~( MCF_GPIO_PDDR_FECI2C_PDDR_FECI2C0 ); \
-    } while( 0 )
-
-#define FEC_DEBUG_TX_TIMING( x ) \
-    do \
-    { \
-        if( x ) \
-            MCF_GPIO_PPDSDR_FECI2C = MCF_GPIO_PDDR_FECI2C_PDDR_FECI2C1; \
-        else \
-            MCF_GPIO_PCLRR_FECI2C = ~( MCF_GPIO_PDDR_FECI2C_PDDR_FECI2C1 ); \
-    } while( 0 )
-
-#else
-#define FEC_DEBUG               DBG_OFF
-#define FEC_DEBUG_INIT
-#define FEC_DEBUG_RX_TIMING( x )
-#define FEC_DEBUG_TX_TIMING( x )
-#endif
-
-#define MCF_FEC_INT_LEVEL       ( 6 )
-#define MCF_FEC_INT_PRIORITY    ( 0 )
-#define MCF_FEC_VEC_RXF         ( 64 + 27 )
-#define MCF_FEC_MTU             ( 1518 )
-
-#define ETH_ADDR_LEN            ( 6 )
-
-#define TASK_PRIORITY           ( configMAX_PRIORITIES - 1 )
-
-/* ------------------------ Type definitions ------------------------------ */
-typedef struct
-{
-    struct netif   *netif;      /* lwIP network interface. */
-    struct eth_addr *self;      /* MAC address of FEC interface. */
-    sys_sem_t       tx_sem;     /* Control access to transmitter. */
-    sys_sem_t       rx_sem;     /* Semaphore to signal receive thread. */
-} mcf523xfec_if_t;
-
-/* ------------------------ Static variables ------------------------------ */
-static mcf523xfec_if_t *fecif_g;
-
-/* ------------------------ Static functions ------------------------------ */
-static err_t    mcf523xfec_output( struct netif *, struct pbuf *, struct ip_addr * );
-static err_t    mcf523xfec_output_raw( struct netif *, struct pbuf * );
-
-static void     mcf523xfec_reset( mcf523xfec_if_t * fecif );
-static void     mcf523xfec_enable( mcf523xfec_if_t * fecif );
-static void     mcf523xfec_disable( mcf523xfec_if_t * fecif );
-static void     mcf523xfec_get_mac( mcf523xfec_if_t * fecif, struct eth_addr *mac );
-static void     mcf523xfec_rx_irq( void );
-static void     mcf523xfec_rx_task( void *arg );
-
-static void     arp_timer( void *arg );
-static void     eth_input( struct netif *netif, struct pbuf *p );
-
-/* ------------------------ Start implementation -------------------------- */
-
-static void
-arp_timer( void *arg )
-{
-    ( void )arg;
-    etharp_tmr(  );
-    sys_timeout( ARP_TMR_INTERVAL, arp_timer, NULL );
-}
-
-err_t
-mcf523xfec_output_raw( struct netif *netif, struct pbuf *p )
-{
-    err_t           res;
-    nbuf_t         *pNBuf;
-    mcf523xfec_if_t *fecif = netif->state;
-    int             i;
-    struct pbuf    *q;
-
-#if ETH_PAD_SIZE
-    pbuf_header( p, -ETH_PAD_SIZE );    /* drop the padding word */
-#endif
-
-
-    /* Test if we can handle such big frames. If not drop it. */
-    if( p->tot_len > MCF_FEC_MTU )
-    {
-#if LINK_STATS
-        lwip_stats.link.lenerr++;
-#endif
-        res = ERR_BUF;
-    }
-    /* Test if our network buffer scheme can handle a packet of this size. If
-     * not drop it and return a memory error. */
-    else if( p->tot_len > TX_BUFFER_SIZE )
-    {
-#ifdef LINK_STATS
-        lwip_stats.link.memerr++;
-#endif
-        res = ERR_MEM;
-    }
-    /* Allocate a transmit buffer. If no buffer is available drop the frame. */
-    else if( ( pNBuf = nbuf_tx_allocate(  ) ) == NULL )
-    {
-        LWIP_ASSERT( "mcf523xfec_output_raw: pNBuf != NULL\n", pNBuf != NULL );
-#ifdef LINK_STATS
-        lwip_stats.link.memerr++;
-#endif
-        res = ERR_MEM;
-    }
-    else
-    {
-        q = p;
-        i = 0;
-        do
-        {
-            memcpy( &pNBuf->data[i], q->payload, q->len );
-            i += q->len;
-        }
-        while( ( q = q->next ) != NULL );
-        pNBuf->length = p->tot_len;
-
-        /* Set Frame ready for transmission. */
-        pNBuf->status |= TX_BD_R;
-        /* Mark the buffer as not in use so the FEC can take it. */
-        nbuf_tx_release( pNBuf );
-        /* Indicate that a new transmit buffer has been produced. */
-        MCF_FEC_TDAR = 1;
-#if LINK_STATS
-        lwip_stats.link.xmit++;
-#endif
-        res = ERR_OK;
-    }
-
-    sys_sem_signal( fecif->tx_sem );
-#if ETH_PAD_SIZE
-    buf_header( p, ETH_PAD_SIZE );
-#endif
-
-    return res;
-}
-
-/* This function is called by the TCP/IP stack when an IP packet should be
- * sent. It uses the ethernet ARP module provided by lwIP to resolve the
- * destination MAC address. The ARP module will later call our low level
- * output function mcf523xfec_output_raw.
- */
-err_t
-mcf523xfec_output( struct netif * netif, struct pbuf * p, struct ip_addr * ipaddr )
-{
-    err_t           res;
-    mcf523xfec_if_t *fecif = netif->state;
-
-    FEC_DEBUG_TX_TIMING( 1 );
-    /* Make sure only one thread is in this function. */
-    sys_sem_wait( fecif->tx_sem );
-    res = etharp_output( netif, ipaddr, p );
-    FEC_DEBUG_TX_TIMING( 0 );
-    return res;
-}
-
-void
-mcf523xfec_rx_task( void *arg )
-{
-    mcf523xfec_if_t *fecif = arg;
-    struct pbuf    *p, *q;
-    nbuf_t         *pNBuf;
-    uint8          *pPayLoad;
-
-    do
-    {
-        sys_sem_wait( fecif->rx_sem );
-        while( nbuf_rx_next_ready(  ) )
-        {
-            pNBuf = nbuf_rx_allocate(  );
-            if( pNBuf != NULL )
-            {
-                LWIP_ASSERT( "mcf523xfec_rx_task: pNBuf->status & RX_BD_L ",
-                             pNBuf->status & RX_BD_L );
-
-                /* This flags indicate that the frame has been damaged. In
-                 * this case we must update the link stats if enabled and
-                 * remove the frame from the FEC. */
-                if ( pNBuf->status & ( RX_BD_LG | RX_BD_NO |
-                                       RX_BD_CR | RX_BD_OV ) )
-                {
-#ifdef LINK_STATS
-                    lwip_stats.link.drop++;
-                    if ( pNBuf->status & RX_BD_LG)
-                    {
-                        lwip_stats.link.lenerr++;
-                    }
-                    else if ( pNBuf->status & ( RX_BD_NO | RX_BD_OV ) )
-                    {
-                        lwip_stats.link.err++;
-                    }
-                    else
-                    {
-                        lwip_stats.link.chkerr++;
-                    }
-#endif
-                }
-                else
-                {
-                    /* The frame must no be valid. Perform some checks to see if the FEC
-                     * driver is working correctly.
-                     */
-                    LWIP_ASSERT( "mcf523xfec_rx_task: pNBuf->length != 0", pNBuf->length != 0 );
-                    p = pbuf_alloc( PBUF_RAW, pNBuf->length, PBUF_POOL );
-                    if( p != NULL )
-                    {
-#if ETH_PAD_SIZE
-                        pbuf_header( p, -ETH_PAD_SIZE );
-#endif
-                        pPayLoad = pNBuf->data;
-                        for( q = p; q != NULL; q = q->next )
-                        {
-                            memcpy( q->payload, pPayLoad, q->len );
-                            pPayLoad += q->len;
-                        }
-#if ETH_PAD_SIZE
-                        pbuf_header( p, ETH_PAD_SIZE );
-#endif
-
-                        /* Ethernet frame received. Handling it is not device
-                         * dependent and therefore done in another function.
-                         */
-                        eth_input( fecif->netif, p );
-                    }
-                }
-                nbuf_rx_release( pNBuf );
-
-                /* Tell the HW that there are new free RX buffers. */
-                MCF_FEC_RDAR = 1;
-            }
-            else
-            {
-#if LINK_STATS
-                lwip_stats.link.memerr++;
-                lwip_stats.link.drop++;
-#endif
-            }
-        }
-        /* Set RX Debug PIN to low since handling of next frame is possible. */
-        FEC_DEBUG_RX_TIMING( 0 );
-    }
-    while( 1 );
-}
-
-void
-eth_input( struct netif *netif, struct pbuf *p )
-{
-    struct eth_hdr *eth_hdr = p->payload;
-
-    LWIP_ASSERT( "eth_input: p != NULL ", p != NULL );
-
-    switch ( htons( eth_hdr->type ) )
-    {
-    case ETHTYPE_IP:
-        /* Pass to ARP layer. */
-        etharp_ip_input( netif, p );
-
-        /* Skip Ethernet header. */
-        pbuf_header( p, ( s16_t ) - sizeof( struct eth_hdr ) );
-
-        /* Pass to network layer. */
-        netif->input( p, netif );
-        break;
-
-    case ETHTYPE_ARP:
-        /* Pass to ARP layer. */
-        etharp_arp_input( netif, ( struct eth_addr * )netif->hwaddr, p );
-        break;
-
-    default:
-        pbuf_free( p );
-        break;
-    }
-}
-
-void
-mcf523xfec_rx_irq( void )
-{
-    static portBASE_TYPE xNeedSwitch = pdFALSE;
-
-    /* Workaround GCC if frame pointers are enabled. This is an ISR and
-     * we must not modify the stack before portENTER_SWITCHING_ISR( )
-     * has been called. */
-#if _GCC_USES_FP == 1
-    asm volatile    ( "unlk %fp\n\t" );
-#endif
-
-    /* This ISR can cause a context switch, so the first statement must be
-     * a call to the portENTER_SWITCHING_ISR() macro.
-     */
-    portENTER_SWITCHING_ISR(  );
-
-    /* Set Debug PIN to high to measure RX latency. */
-    FEC_DEBUG_RX_TIMING( 1 );
-
-    /* Clear FEC RX Event from the Event Register (by writing 1) */
-    if( MCF_FEC_EIR & ( MCF_FEC_EIR_RXB | MCF_FEC_EIR_RXF ) )
-    {
-        /* Clear interrupt from EIR register immediately */
-        MCF_FEC_EIR = ( MCF_FEC_EIR_RXB | MCF_FEC_EIR_RXF );
-        xNeedSwitch = xSemaphoreGiveFromISR( fecif_g->rx_sem, pdFALSE );
-    }
-    portEXIT_SWITCHING_ISR( xNeedSwitch );
-}
-
-void
-mcf523xfec_reset( mcf523xfec_if_t * fecif )
-{
-    extern void     ( *__RAMVEC[] ) (  );
-
-    int             old_ipl = asm_set_ipl( 7 );
-
-    /* Reset the FEC - equivalent to a hard reset */
-    MCF_FEC_ECR = MCF_FEC_ECR_RESET;
-
-    /* Wait for the reset sequence to complete */
-    while( MCF_FEC_ECR & MCF_FEC_ECR_RESET );
-
-    /* Disable all FEC interrupts by clearing the EIMR register */
-    MCF_FEC_EIMR = 0;
-
-    /* Clear any interrupts by setting all bits in the EIR register */
-    MCF_FEC_EIR = 0xFFFFFFFFUL;
-
-    /* Configure Interrupt vectors. */
-    __RAMVEC[MCF_FEC_VEC_RXF] = mcf523xfec_rx_irq;
-
-    /* Set the source address for the controller */
-    MCF_FEC_PALR =
-        ( fecif->self->addr[0] << 24U ) | ( fecif->self->addr[1] << 16U ) |
-        ( fecif->self->addr[2] << 8U ) | ( fecif->self->addr[3] << 0U );
-    MCF_FEC_PAUR = ( fecif->self->addr[4] << 24U ) | ( fecif->self->addr[5] << 16U );
-
-    /* Initialize the hash table registers */
-    MCF_FEC_IAUR = 0;
-    MCF_FEC_IALR = 0;
-
-    /* Set Receive Buffer Size */
-#if RX_BUFFER_SIZE != 2048
-#error "RX_BUFFER_SIZE must be set to 2048 for safe FEC operation."
-#endif
-    MCF_FEC_EMRBR = RX_BUFFER_SIZE - 1;
-
-    /* Point to the start of the circular Rx buffer descriptor queue */
-    MCF_FEC_ERDSR = nbuf_get_start( NBUF_RX );
-
-    /* Point to the start of the circular Tx buffer descriptor queue */
-    MCF_FEC_ETDSR = nbuf_get_start( NBUF_TX );
-
-    /* Set the tranceiver interface to MII mode */
-    MCF_FEC_RCR = MCF_FEC_RCR_MAX_FL( MCF_FEC_MTU ) | MCF_FEC_RCR_MII_MODE;
-
-    /* Set MII Speed Control Register for 2.5Mhz */
-    MCF_FEC_MSCR = MCF_FEC_MSCR_MII_SPEED( FSYS_2 / ( 2UL * 2500000UL ) );
-
-    /* Only operate in half-duplex, no heart beat control */
-    MCF_FEC_TCR = 0;
-
-    /* Enable Debug support */
-    FEC_DEBUG_INIT;
-    FEC_DEBUG_RX_TIMING( 0 );
-    FEC_DEBUG_TX_TIMING( 0 );
-    ( void )asm_set_ipl( old_ipl );
-}
-
-void
-mcf523xfec_get_mac( mcf523xfec_if_t * hw, struct eth_addr *mac )
-{
-    int             i;
-    static const struct eth_addr mac_default = {
-        {0x00, 0xCF, 0x52, 0x35, 0x00, 0x01}
-    };
-
-    ( void )hw;
-
-    for( i = 0; i < ETH_ADDR_LEN; i++ )
-    {
-        mac->addr[i] = mac_default.addr[i];
-    }
-}
-
-void
-mcf523xfec_enable( mcf523xfec_if_t * fecif )
-{
-    ( void )fecif;
-
-    int             old_ipl = asm_set_ipl( 7 );
-
-    /* Configure I/O pins for the FEC. */
-    MCF_GPIO_PAR_FECI2C = ( MCF_GPIO_PAR_FECI2C_PAR_EMDC_FEC | MCF_GPIO_PAR_FECI2C_PAR_EMDIO_FEC );
-
-    /* Allow interrupts by setting IMR register */
-    MCF_FEC_EIMR = MCF_FEC_EIMR_RXF;
-
-    /* Configure the interrupt controller. */
-    MCF_INTC0_ICR27 = ( MCF_INTC0_ICRn_IL( MCF_FEC_INT_LEVEL ) |
-                        MCF_INTC0_ICRn_IP( MCF_FEC_INT_PRIORITY ) );
-    MCF_INTC0_IMRL &= ~( MCF_INTC0_IMRL_INT_MASK27 | MCF_INTC0_IMRL_MASKALL );
-
-    /* Enable FEC */
-    MCF_FEC_ECR = MCF_FEC_ECR_ETHER_EN;
-
-    /* Indicate that there have been empty receive buffers produced */
-    MCF_FEC_RDAR = 1;
-    ( void )asm_set_ipl( old_ipl );
-}
-
-void
-mcf523xfec_disable( mcf523xfec_if_t * fecif )
-{
-    ( void )fecif;
-
-    int             old_ipl = asm_set_ipl( 7 );
-
-    /* Set the Graceful Transmit Stop bit */
-    MCF_FEC_TCR = ( MCF_FEC_TCR | MCF_FEC_TCR_GTS );
-
-    /* Wait for the current transmission to complete */
-    while( !( MCF_FEC_EIR & MCF_FEC_EIR_GRA ) );
-
-    /* Clear the GRA event */
-    MCF_FEC_EIR = MCF_FEC_EIR_GRA;
-
-    /* Disable the FEC */
-    MCF_FEC_ECR = 0;
-
-    /* Disable all FEC interrupts by clearing the IMR register */
-    MCF_FEC_EIMR = 0;
-
-    /* Unconfigure the interrupt controller. */
-    MCF_INTC0_ICR27 = MCF_INTC0_ICRn_IL( 0 ) | MCF_INTC0_ICRn_IP( 0 );
-    MCF_INTC0_IMRL |= MCF_INTC0_IMRL_INT_MASK27;
-
-    /* Clear the GTS bit so frames can be tranmitted when restarted */
-    MCF_FEC_TCR = ( MCF_FEC_TCR & ~MCF_FEC_TCR_GTS );
-
-    /* Disable I/O pins used by the FEC. */
-    MCF_GPIO_PAR_FECI2C &= ~( MCF_GPIO_PAR_FECI2C_PAR_EMDC_FEC |
-                              MCF_GPIO_PAR_FECI2C_PAR_EMDIO_FEC );
-    ( void )asm_set_ipl( old_ipl );
-}
-
-err_t
-mcf523xfec_init( struct netif *netif )
-{
-    err_t           res;
-
-    mcf523xfec_if_t *fecif = mem_malloc( sizeof( mcf523xfec_if_t ) );
-
-    if( fecif != NULL )
-    {
-        /* Global copy used in ISR. */
-        fecif_g = fecif;
-        fecif->self = ( struct eth_addr * )&netif->hwaddr[0];
-        fecif->netif = netif;
-        fecif->tx_sem = NULL;
-        fecif->rx_sem = NULL;
-
-        if( ( fecif->tx_sem = sys_sem_new( 1 ) ) == NULL )
-        {
-            res = ERR_MEM;
-        }
-        else if( ( fecif->rx_sem = sys_sem_new( 0 ) ) == NULL )
-        {
-            res = ERR_MEM;
-        }
-        else if( sys_thread_new( mcf523xfec_rx_task, fecif, TASK_PRIORITY ) == NULL )
-        {
-            res = ERR_MEM;
-        }
-        else
-        {
-            netif->state = fecif;
-            netif->name[0] = 'C';
-            netif->name[1] = 'F';
-            netif->hwaddr_len = ETH_ADDR_LEN;
-            netif->mtu = MCF_FEC_MTU;
-            netif->flags = NETIF_FLAG_BROADCAST;
-            netif->output = mcf523xfec_output;
-            netif->linkoutput = mcf523xfec_output_raw;
-
-            nbuf_init(  );
-            mcf523xfec_get_mac( fecif, fecif->self );
-            mcf523xfec_reset( fecif );
-            mcf523xfec_enable( fecif );
-
-            etharp_init(  );
-            sys_timeout( ARP_TMR_INTERVAL, arp_timer, NULL );
-
-            res = ERR_OK;
-        }
-
-        if( res != ERR_OK )
-        {
-            free( fecif );
-            if( fecif->tx_sem != NULL )
-            {
-                mem_free( fecif->tx_sem );
-            }
-            if( fecif->rx_sem != NULL )
-            {
-                mem_free( fecif->rx_sem );
-            }
-        }
-    }
-    else
-    {
-        res = ERR_MEM;
-    }
-
-    return res;
-}
+/*\r
+ * Copyright (c) 2006 Christian Walter\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without modification,\r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED\r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT\r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY\r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * Author: Christian Walter <wolti@sil.at>\r
+ *\r
+ * TODO:\r
+ *  - Introduce another task create function in the sys_arch layer which allows\r
+ *    for passing the stack size.\r
+ *  - Avoid copying the buffers - this requires changeing the nbuf driver code\r
+ *    to use the lwIP pbuf buffer implementation.\r
+ *\r
+ * File: $Id: fec.c,v 1.3 2006/08/29 18:53:46 wolti Exp $\r
+ */\r
+\r
+/* ------------------------ System includes ------------------------------- */\r
+#include <stdlib.h>\r
+\r
+/* ------------------------ Platform includes ----------------------------- */\r
+#include "mcf5xxx.h"\r
+#include "mcf523x.h"\r
+\r
+#include "nbuf.h"\r
+\r
+/* ------------------------ lwIP includes --------------------------------- */\r
+#include "lwip/opt.h"\r
+#include "lwip/def.h"\r
+#include "lwip/mem.h"\r
+#include "lwip/pbuf.h"\r
+#include "lwip/sys.h"\r
+#include "lwip/stats.h"\r
+#include "lwip/debug.h"\r
+#include "netif/etharp.h"\r
+\r
+/* ------------------------ Defines --------------------------------------- */\r
+#ifdef FEC_DEBUG\r
+#define FEC_DEBUG_INIT \\r
+    do \\r
+    { \\r
+        MCF_GPIO_PDDR_FECI2C = ( MCF_GPIO_PDDR_FECI2C_PDDR_FECI2C0 | \\r
+                                 MCF_GPIO_PDDR_FECI2C_PDDR_FECI2C1 ); \\r
+    } while( 0 )\r
+\r
+#define FEC_DEBUG_RX_TIMING( x ) \\r
+    do \\r
+    { \\r
+        if( x ) \\r
+            MCF_GPIO_PPDSDR_FECI2C = MCF_GPIO_PDDR_FECI2C_PDDR_FECI2C0; \\r
+        else \\r
+            MCF_GPIO_PCLRR_FECI2C = ~( MCF_GPIO_PDDR_FECI2C_PDDR_FECI2C0 ); \\r
+    } while( 0 )\r
+\r
+#define FEC_DEBUG_TX_TIMING( x ) \\r
+    do \\r
+    { \\r
+        if( x ) \\r
+            MCF_GPIO_PPDSDR_FECI2C = MCF_GPIO_PDDR_FECI2C_PDDR_FECI2C1; \\r
+        else \\r
+            MCF_GPIO_PCLRR_FECI2C = ~( MCF_GPIO_PDDR_FECI2C_PDDR_FECI2C1 ); \\r
+    } while( 0 )\r
+\r
+#else\r
+#define FEC_DEBUG               DBG_OFF\r
+#define FEC_DEBUG_INIT\r
+#define FEC_DEBUG_RX_TIMING( x )\r
+#define FEC_DEBUG_TX_TIMING( x )\r
+#endif\r
+\r
+#define MCF_FEC_INT_LEVEL       ( 6 )\r
+#define MCF_FEC_INT_PRIORITY    ( 0 )\r
+#define MCF_FEC_VEC_RXF         ( 64 + 27 )\r
+#define MCF_FEC_MTU             ( 1518 )\r
+\r
+#define ETH_ADDR_LEN            ( 6 )\r
+\r
+#define TASK_PRIORITY           ( configMAX_PRIORITIES - 1 )\r
+\r
+/* ------------------------ Type definitions ------------------------------ */\r
+typedef struct\r
+{\r
+    struct netif   *netif;      /* lwIP network interface. */\r
+    struct eth_addr *self;      /* MAC address of FEC interface. */\r
+    sys_sem_t       tx_sem;     /* Control access to transmitter. */\r
+    sys_sem_t       rx_sem;     /* Semaphore to signal receive thread. */\r
+} mcf523xfec_if_t;\r
+\r
+/* ------------------------ Static variables ------------------------------ */\r
+static mcf523xfec_if_t *fecif_g;\r
+\r
+/* ------------------------ Static functions ------------------------------ */\r
+static err_t    mcf523xfec_output( struct netif *, struct pbuf *, struct ip_addr * );\r
+static err_t    mcf523xfec_output_raw( struct netif *, struct pbuf * );\r
+\r
+static void     mcf523xfec_reset( mcf523xfec_if_t * fecif );\r
+static void     mcf523xfec_enable( mcf523xfec_if_t * fecif );\r
+static void     mcf523xfec_disable( mcf523xfec_if_t * fecif );\r
+static void     mcf523xfec_get_mac( mcf523xfec_if_t * fecif, struct eth_addr *mac );\r
+static void     mcf523xfec_rx_irq( void );\r
+static void     mcf523xfec_rx_task( void *arg );\r
+\r
+static void     arp_timer( void *arg );\r
+static void     eth_input( struct netif *netif, struct pbuf *p );\r
+\r
+/* ------------------------ Start implementation -------------------------- */\r
+\r
+static void\r
+arp_timer( void *arg )\r
+{\r
+    ( void )arg;\r
+    etharp_tmr(  );\r
+    sys_timeout( ARP_TMR_INTERVAL, arp_timer, NULL );\r
+}\r
+\r
+err_t\r
+mcf523xfec_output_raw( struct netif *netif, struct pbuf *p )\r
+{\r
+    err_t           res;\r
+    nbuf_t         *pNBuf;\r
+    mcf523xfec_if_t *fecif = netif->state;\r
+    int             i;\r
+    struct pbuf    *q;\r
+\r
+#if ETH_PAD_SIZE\r
+    pbuf_header( p, -ETH_PAD_SIZE );    /* drop the padding word */\r
+#endif\r
+\r
+\r
+    /* Test if we can handle such big frames. If not drop it. */\r
+    if( p->tot_len > MCF_FEC_MTU )\r
+    {\r
+#if LINK_STATS\r
+        lwip_stats.link.lenerr++;\r
+#endif\r
+        res = ERR_BUF;\r
+    }\r
+    /* Test if our network buffer scheme can handle a packet of this size. If\r
+     * not drop it and return a memory error. */\r
+    else if( p->tot_len > TX_BUFFER_SIZE )\r
+    {\r
+#ifdef LINK_STATS\r
+        lwip_stats.link.memerr++;\r
+#endif\r
+        res = ERR_MEM;\r
+    }\r
+    /* Allocate a transmit buffer. If no buffer is available drop the frame. */\r
+    else if( ( pNBuf = nbuf_tx_allocate(  ) ) == NULL )\r
+    {\r
+        LWIP_ASSERT( "mcf523xfec_output_raw: pNBuf != NULL\n", pNBuf != NULL );\r
+#ifdef LINK_STATS\r
+        lwip_stats.link.memerr++;\r
+#endif\r
+        res = ERR_MEM;\r
+    }\r
+    else\r
+    {\r
+        q = p;\r
+        i = 0;\r
+        do\r
+        {\r
+            memcpy( &pNBuf->data[i], q->payload, q->len );\r
+            i += q->len;\r
+        }\r
+        while( ( q = q->next ) != NULL );\r
+        pNBuf->length = p->tot_len;\r
+\r
+        /* Set Frame ready for transmission. */\r
+        pNBuf->status |= TX_BD_R;\r
+        /* Mark the buffer as not in use so the FEC can take it. */\r
+        nbuf_tx_release( pNBuf );\r
+        /* Indicate that a new transmit buffer has been produced. */\r
+        MCF_FEC_TDAR = 1;\r
+#if LINK_STATS\r
+        lwip_stats.link.xmit++;\r
+#endif\r
+        res = ERR_OK;\r
+    }\r
+\r
+    sys_sem_signal( fecif->tx_sem );\r
+#if ETH_PAD_SIZE\r
+    buf_header( p, ETH_PAD_SIZE );\r
+#endif\r
+\r
+    return res;\r
+}\r
+\r
+/* This function is called by the TCP/IP stack when an IP packet should be\r
+ * sent. It uses the ethernet ARP module provided by lwIP to resolve the\r
+ * destination MAC address. The ARP module will later call our low level\r
+ * output function mcf523xfec_output_raw.\r
+ */\r
+err_t\r
+mcf523xfec_output( struct netif * netif, struct pbuf * p, struct ip_addr * ipaddr )\r
+{\r
+    err_t           res;\r
+    mcf523xfec_if_t *fecif = netif->state;\r
+\r
+    FEC_DEBUG_TX_TIMING( 1 );\r
+    /* Make sure only one thread is in this function. */\r
+    sys_sem_wait( fecif->tx_sem );\r
+    res = etharp_output( netif, ipaddr, p );\r
+    FEC_DEBUG_TX_TIMING( 0 );\r
+    return res;\r
+}\r
+\r
+void\r
+mcf523xfec_rx_task( void *arg )\r
+{\r
+    mcf523xfec_if_t *fecif = arg;\r
+    struct pbuf    *p, *q;\r
+    nbuf_t         *pNBuf;\r
+    uint8          *pPayLoad;\r
+\r
+    do\r
+    {\r
+        sys_sem_wait( fecif->rx_sem );\r
+        while( nbuf_rx_next_ready(  ) )\r
+        {\r
+            pNBuf = nbuf_rx_allocate(  );\r
+            if( pNBuf != NULL )\r
+            {\r
+                LWIP_ASSERT( "mcf523xfec_rx_task: pNBuf->status & RX_BD_L ",\r
+                             pNBuf->status & RX_BD_L );\r
+\r
+                /* This flags indicate that the frame has been damaged. In\r
+                 * this case we must update the link stats if enabled and\r
+                 * remove the frame from the FEC. */\r
+                if ( pNBuf->status & ( RX_BD_LG | RX_BD_NO |\r
+                                       RX_BD_CR | RX_BD_OV ) )\r
+                {\r
+#ifdef LINK_STATS\r
+                    lwip_stats.link.drop++;\r
+                    if ( pNBuf->status & RX_BD_LG)\r
+                    {\r
+                        lwip_stats.link.lenerr++;\r
+                    }\r
+                    else if ( pNBuf->status & ( RX_BD_NO | RX_BD_OV ) )\r
+                    {\r
+                        lwip_stats.link.err++;\r
+                    }\r
+                    else\r
+                    {\r
+                        lwip_stats.link.chkerr++;\r
+                    }\r
+#endif\r
+                }\r
+                else\r
+                {\r
+                    /* The frame must no be valid. Perform some checks to see if the FEC\r
+                     * driver is working correctly.\r
+                     */\r
+                    LWIP_ASSERT( "mcf523xfec_rx_task: pNBuf->length != 0", pNBuf->length != 0 );\r
+                    p = pbuf_alloc( PBUF_RAW, pNBuf->length, PBUF_POOL );\r
+                    if( p != NULL )\r
+                    {\r
+#if ETH_PAD_SIZE\r
+                        pbuf_header( p, -ETH_PAD_SIZE );\r
+#endif\r
+                        pPayLoad = pNBuf->data;\r
+                        for( q = p; q != NULL; q = q->next )\r
+                        {\r
+                            memcpy( q->payload, pPayLoad, q->len );\r
+                            pPayLoad += q->len;\r
+                        }\r
+#if ETH_PAD_SIZE\r
+                        pbuf_header( p, ETH_PAD_SIZE );\r
+#endif\r
+\r
+                        /* Ethernet frame received. Handling it is not device\r
+                         * dependent and therefore done in another function.\r
+                         */\r
+                        eth_input( fecif->netif, p );\r
+                    }\r
+                }\r
+                nbuf_rx_release( pNBuf );\r
+\r
+                /* Tell the HW that there are new free RX buffers. */\r
+                MCF_FEC_RDAR = 1;\r
+            }\r
+            else\r
+            {\r
+#if LINK_STATS\r
+                lwip_stats.link.memerr++;\r
+                lwip_stats.link.drop++;\r
+#endif\r
+            }\r
+        }\r
+        /* Set RX Debug PIN to low since handling of next frame is possible. */\r
+        FEC_DEBUG_RX_TIMING( 0 );\r
+    }\r
+    while( 1 );\r
+}\r
+\r
+void\r
+eth_input( struct netif *netif, struct pbuf *p )\r
+{\r
+    struct eth_hdr *eth_hdr = p->payload;\r
+\r
+    LWIP_ASSERT( "eth_input: p != NULL ", p != NULL );\r
+\r
+    switch ( htons( eth_hdr->type ) )\r
+    {\r
+    case ETHTYPE_IP:\r
+        /* Pass to ARP layer. */\r
+        etharp_ip_input( netif, p );\r
+\r
+        /* Skip Ethernet header. */\r
+        pbuf_header( p, ( s16_t ) - sizeof( struct eth_hdr ) );\r
+\r
+        /* Pass to network layer. */\r
+        netif->input( p, netif );\r
+        break;\r
+\r
+    case ETHTYPE_ARP:\r
+        /* Pass to ARP layer. */\r
+        etharp_arp_input( netif, ( struct eth_addr * )netif->hwaddr, p );\r
+        break;\r
+\r
+    default:\r
+        pbuf_free( p );\r
+        break;\r
+    }\r
+}\r
+\r
+void\r
+mcf523xfec_rx_irq( void )\r
+{\r
+    static portBASE_TYPE xNeedSwitch = pdFALSE;\r
+\r
+    /* Workaround GCC if frame pointers are enabled. This is an ISR and\r
+     * we must not modify the stack before portENTER_SWITCHING_ISR( )\r
+     * has been called. */\r
+#if _GCC_USES_FP == 1\r
+    asm volatile    ( "unlk %fp\n\t" );\r
+#endif\r
+\r
+    /* This ISR can cause a context switch, so the first statement must be\r
+     * a call to the portENTER_SWITCHING_ISR() macro.\r
+     */\r
+    portENTER_SWITCHING_ISR(  );\r
+\r
+    /* Set Debug PIN to high to measure RX latency. */\r
+    FEC_DEBUG_RX_TIMING( 1 );\r
+\r
+    /* Clear FEC RX Event from the Event Register (by writing 1) */\r
+    if( MCF_FEC_EIR & ( MCF_FEC_EIR_RXB | MCF_FEC_EIR_RXF ) )\r
+    {\r
+        /* Clear interrupt from EIR register immediately */\r
+        MCF_FEC_EIR = ( MCF_FEC_EIR_RXB | MCF_FEC_EIR_RXF );\r
+        xNeedSwitch = xSemaphoreGiveFromISR( fecif_g->rx_sem, pdFALSE );\r
+    }\r
+    portEXIT_SWITCHING_ISR( xNeedSwitch );\r
+}\r
+\r
+void\r
+mcf523xfec_reset( mcf523xfec_if_t * fecif )\r
+{\r
+    extern void     ( *__RAMVEC[] ) (  );\r
+\r
+    int             old_ipl = asm_set_ipl( 7 );\r
+\r
+    /* Reset the FEC - equivalent to a hard reset */\r
+    MCF_FEC_ECR = MCF_FEC_ECR_RESET;\r
+\r
+    /* Wait for the reset sequence to complete */\r
+    while( MCF_FEC_ECR & MCF_FEC_ECR_RESET );\r
+\r
+    /* Disable all FEC interrupts by clearing the EIMR register */\r
+    MCF_FEC_EIMR = 0;\r
+\r
+    /* Clear any interrupts by setting all bits in the EIR register */\r
+    MCF_FEC_EIR = 0xFFFFFFFFUL;\r
+\r
+    /* Configure Interrupt vectors. */\r
+    __RAMVEC[MCF_FEC_VEC_RXF] = mcf523xfec_rx_irq;\r
+\r
+    /* Set the source address for the controller */\r
+    MCF_FEC_PALR =\r
+        ( fecif->self->addr[0] << 24U ) | ( fecif->self->addr[1] << 16U ) |\r
+        ( fecif->self->addr[2] << 8U ) | ( fecif->self->addr[3] << 0U );\r
+    MCF_FEC_PAUR = ( fecif->self->addr[4] << 24U ) | ( fecif->self->addr[5] << 16U );\r
+\r
+    /* Initialize the hash table registers */\r
+    MCF_FEC_IAUR = 0;\r
+    MCF_FEC_IALR = 0;\r
+\r
+    /* Set Receive Buffer Size */\r
+#if RX_BUFFER_SIZE != 2048\r
+#error "RX_BUFFER_SIZE must be set to 2048 for safe FEC operation."\r
+#endif\r
+    MCF_FEC_EMRBR = RX_BUFFER_SIZE - 1;\r
+\r
+    /* Point to the start of the circular Rx buffer descriptor queue */\r
+    MCF_FEC_ERDSR = nbuf_get_start( NBUF_RX );\r
+\r
+    /* Point to the start of the circular Tx buffer descriptor queue */\r
+    MCF_FEC_ETDSR = nbuf_get_start( NBUF_TX );\r
+\r
+    /* Set the tranceiver interface to MII mode */\r
+    MCF_FEC_RCR = MCF_FEC_RCR_MAX_FL( MCF_FEC_MTU ) | MCF_FEC_RCR_MII_MODE;\r
+\r
+    /* Set MII Speed Control Register for 2.5Mhz */\r
+    MCF_FEC_MSCR = MCF_FEC_MSCR_MII_SPEED( FSYS_2 / ( 2UL * 2500000UL ) );\r
+\r
+    /* Only operate in half-duplex, no heart beat control */\r
+    MCF_FEC_TCR = 0;\r
+\r
+    /* Enable Debug support */\r
+    FEC_DEBUG_INIT;\r
+    FEC_DEBUG_RX_TIMING( 0 );\r
+    FEC_DEBUG_TX_TIMING( 0 );\r
+    ( void )asm_set_ipl( old_ipl );\r
+}\r
+\r
+void\r
+mcf523xfec_get_mac( mcf523xfec_if_t * hw, struct eth_addr *mac )\r
+{\r
+    int             i;\r
+    static const struct eth_addr mac_default = {\r
+        {0x00, 0xCF, 0x52, 0x35, 0x00, 0x01}\r
+    };\r
+\r
+    ( void )hw;\r
+\r
+    for( i = 0; i < ETH_ADDR_LEN; i++ )\r
+    {\r
+        mac->addr[i] = mac_default.addr[i];\r
+    }\r
+}\r
+\r
+void\r
+mcf523xfec_enable( mcf523xfec_if_t * fecif )\r
+{\r
+    ( void )fecif;\r
+\r
+    int             old_ipl = asm_set_ipl( 7 );\r
+\r
+    /* Configure I/O pins for the FEC. */\r
+    MCF_GPIO_PAR_FECI2C = ( MCF_GPIO_PAR_FECI2C_PAR_EMDC_FEC | MCF_GPIO_PAR_FECI2C_PAR_EMDIO_FEC );\r
+\r
+    /* Allow interrupts by setting IMR register */\r
+    MCF_FEC_EIMR = MCF_FEC_EIMR_RXF;\r
+\r
+    /* Configure the interrupt controller. */\r
+    MCF_INTC0_ICR27 = ( MCF_INTC0_ICRn_IL( MCF_FEC_INT_LEVEL ) |\r
+                        MCF_INTC0_ICRn_IP( MCF_FEC_INT_PRIORITY ) );\r
+    MCF_INTC0_IMRL &= ~( MCF_INTC0_IMRL_INT_MASK27 | MCF_INTC0_IMRL_MASKALL );\r
+\r
+    /* Enable FEC */\r
+    MCF_FEC_ECR = MCF_FEC_ECR_ETHER_EN;\r
+\r
+    /* Indicate that there have been empty receive buffers produced */\r
+    MCF_FEC_RDAR = 1;\r
+    ( void )asm_set_ipl( old_ipl );\r
+}\r
+\r
+void\r
+mcf523xfec_disable( mcf523xfec_if_t * fecif )\r
+{\r
+    ( void )fecif;\r
+\r
+    int             old_ipl = asm_set_ipl( 7 );\r
+\r
+    /* Set the Graceful Transmit Stop bit */\r
+    MCF_FEC_TCR = ( MCF_FEC_TCR | MCF_FEC_TCR_GTS );\r
+\r
+    /* Wait for the current transmission to complete */\r
+    while( !( MCF_FEC_EIR & MCF_FEC_EIR_GRA ) );\r
+\r
+    /* Clear the GRA event */\r
+    MCF_FEC_EIR = MCF_FEC_EIR_GRA;\r
+\r
+    /* Disable the FEC */\r
+    MCF_FEC_ECR = 0;\r
+\r
+    /* Disable all FEC interrupts by clearing the IMR register */\r
+    MCF_FEC_EIMR = 0;\r
+\r
+    /* Unconfigure the interrupt controller. */\r
+    MCF_INTC0_ICR27 = MCF_INTC0_ICRn_IL( 0 ) | MCF_INTC0_ICRn_IP( 0 );\r
+    MCF_INTC0_IMRL |= MCF_INTC0_IMRL_INT_MASK27;\r
+\r
+    /* Clear the GTS bit so frames can be tranmitted when restarted */\r
+    MCF_FEC_TCR = ( MCF_FEC_TCR & ~MCF_FEC_TCR_GTS );\r
+\r
+    /* Disable I/O pins used by the FEC. */\r
+    MCF_GPIO_PAR_FECI2C &= ~( MCF_GPIO_PAR_FECI2C_PAR_EMDC_FEC |\r
+                              MCF_GPIO_PAR_FECI2C_PAR_EMDIO_FEC );\r
+    ( void )asm_set_ipl( old_ipl );\r
+}\r
+\r
+err_t\r
+mcf523xfec_init( struct netif *netif )\r
+{\r
+    err_t           res;\r
+\r
+    mcf523xfec_if_t *fecif = mem_malloc( sizeof( mcf523xfec_if_t ) );\r
+\r
+    if( fecif != NULL )\r
+    {\r
+        /* Global copy used in ISR. */\r
+        fecif_g = fecif;\r
+        fecif->self = ( struct eth_addr * )&netif->hwaddr[0];\r
+        fecif->netif = netif;\r
+        fecif->tx_sem = NULL;\r
+        fecif->rx_sem = NULL;\r
+\r
+        if( ( fecif->tx_sem = sys_sem_new( 1 ) ) == NULL )\r
+        {\r
+            res = ERR_MEM;\r
+        }\r
+        else if( ( fecif->rx_sem = sys_sem_new( 0 ) ) == NULL )\r
+        {\r
+            res = ERR_MEM;\r
+        }\r
+        else if( sys_thread_new( mcf523xfec_rx_task, fecif, TASK_PRIORITY ) == NULL )\r
+        {\r
+            res = ERR_MEM;\r
+        }\r
+        else\r
+        {\r
+            netif->state = fecif;\r
+            netif->name[0] = 'C';\r
+            netif->name[1] = 'F';\r
+            netif->hwaddr_len = ETH_ADDR_LEN;\r
+            netif->mtu = MCF_FEC_MTU;\r
+            netif->flags = NETIF_FLAG_BROADCAST;\r
+            netif->output = mcf523xfec_output;\r
+            netif->linkoutput = mcf523xfec_output_raw;\r
+\r
+            nbuf_init(  );\r
+            mcf523xfec_get_mac( fecif, fecif->self );\r
+            mcf523xfec_reset( fecif );\r
+            mcf523xfec_enable( fecif );\r
+\r
+            etharp_init(  );\r
+            sys_timeout( ARP_TMR_INTERVAL, arp_timer, NULL );\r
+\r
+            res = ERR_OK;\r
+        }\r
+\r
+        if( res != ERR_OK )\r
+        {\r
+            free( fecif );\r
+            if( fecif->tx_sem != NULL )\r
+            {\r
+                mem_free( fecif->tx_sem );\r
+            }\r
+            if( fecif->rx_sem != NULL )\r
+            {\r
+                mem_free( fecif->rx_sem );\r
+            }\r
+        }\r
+    }\r
+    else\r
+    {\r
+        res = ERR_MEM;\r
+    }\r
+\r
+    return res;\r
+}\r
index 5663f0343ce70d63a9aa3d76fdb253d26c3c31e0..d2f717c80f06195961a77daf2308f74655db70be 100644 (file)
@@ -1,40 +1,40 @@
-/*
- * Copyright (c) 2006 Christian Walter
- * 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.
- *
- * Author: Christian Walter <wolti@sil.at>
- *
- * File: $Id: fec.h,v 1.1 2006/08/29 00:04:06 wolti Exp $
- */
-
-#ifndef _FEC_H
-#define _FEC_H
-
-/* ------------------------ Defines --------------------------------------- */
-
-/* ------------------------ Prototypes ------------------------------------ */
-err_t           mcf523xfec_init( struct netif *netif );
-
-#endif
+/*\r
+ * Copyright (c) 2006 Christian Walter\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without modification,\r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED\r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT\r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY\r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * Author: Christian Walter <wolti@sil.at>\r
+ *\r
+ * File: $Id: fec.h,v 1.1 2006/08/29 00:04:06 wolti Exp $\r
+ */\r
+\r
+#ifndef _FEC_H\r
+#define _FEC_H\r
+\r
+/* ------------------------ Defines --------------------------------------- */\r
+\r
+/* ------------------------ Prototypes ------------------------------------ */\r
+err_t           mcf523xfec_init( struct netif *netif );\r
+\r
+#endif\r
index b4e70556a57b93cdfd0f2ecb791ccc6247a2a5eb..5c97159ee2fef8063156e0efb05f6cc0cf05b8f3 100644 (file)
-/*
- * Network buffer code based on the MCF523x examples from Freescale.
- *
- * File: $Id: nbuf.c,v 1.2 2006/08/31 22:28:21 wolti Exp $
- */
-
-/* ------------------------ Platform includes ----------------------------- */
-#include "mcf5xxx.h"
-#include "mcf523x.h"
-
-#include "nbuf.h"
-
-/* ------------------------ Static variables ------------------------------ */
-
-/* Buffer descriptor indexes */
-static uint8    tx_bd_idx;
-static uint8    rx_bd_idx;
-
-/* Buffer Descriptors -- must be aligned on a 4-byte boundary but a
- * 16-byte boundary is recommended. */
-static nbuf_t   tx_nbuf[sizeof( nbuf_t ) * NUM_TXBDS] ATTR_FECMEM;
-static nbuf_t   rx_nbuf[sizeof( nbuf_t ) * NUM_RXBDS] ATTR_FECMEM;
-
-/* Data Buffers -- must be aligned on a 16-byte boundary. */
-static uint8    tx_buf[TX_BUFFER_SIZE * NUM_TXBDS] ATTR_FECMEM;
-static uint8    rx_buf[RX_BUFFER_SIZE * NUM_RXBDS] ATTR_FECMEM;
-
-/* ------------------------ Start implementation -------------------------- */
-void
-nbuf_init(  )
-{
-
-    uint8           i;
-
-    /* Initialize receive descriptor ring */
-    for( i = 0; i < NUM_RXBDS; i++ )
-    {
-        rx_nbuf[i].status = RX_BD_E;
-        rx_nbuf[i].length = 0;
-        rx_nbuf[i].data = &rx_buf[i * RX_BUFFER_SIZE];
-    }
-
-    /* Set the Wrap bit on the last one in the ring */
-    rx_nbuf[NUM_RXBDS - 1].status |= RX_BD_W;
-
-    /* Initialize transmit descriptor ring */
-    for( i = 0; i < NUM_TXBDS; i++ )
-    {
-        tx_nbuf[i].status = TX_BD_L | TX_BD_TC;
-        tx_nbuf[i].length = 0;
-        tx_nbuf[i].data = &tx_buf[i * TX_BUFFER_SIZE];
-    }
-
-    /* Set the Wrap bit on the last one in the ring */
-    tx_nbuf[NUM_TXBDS - 1].status |= TX_BD_W;
-
-    /* Initialize the buffer descriptor indexes */
-    tx_bd_idx = rx_bd_idx = 0;
-
-    return;
-}
-
-
-/********************************************************************/
-uint32
-nbuf_get_start( uint8 direction )
-{
-    /*
-     * Return the address of the first buffer descriptor in the ring.
-     * This routine is needed by the FEC of the MPC860T , MCF5282, and MCF523x
-     * in order to write the Rx/Tx descriptor ring start registers
-     */
-    switch ( direction )
-    {
-    case NBUF_RX:
-        return ( uint32 ) rx_nbuf;
-    case NBUF_TX:
-    default:
-        return ( uint32 ) tx_nbuf;
-    }
-}
-
-
-/********************************************************************/
-nbuf_t         *
-nbuf_rx_allocate(  )
-{
-    /* This routine alters shared data. Disable interrupts! */
-    int             old_ipl = asm_set_ipl( 6 );
-
-    /* Return a pointer to the next empty Rx Buffer Descriptor */
-    int             i = rx_bd_idx;
-
-
-    /* Check to see if the ring of BDs is full */
-    if( rx_nbuf[i].status & RX_BD_INUSE )
-        return NULL;
-
-    /* Mark the buffer as in use */
-    rx_nbuf[i].status |= RX_BD_INUSE;
-
-    /* increment the circular index */
-    rx_bd_idx = ( uint8 ) ( ( rx_bd_idx + 1 ) % NUM_RXBDS );
-
-    /* Restore previous IPL */
-    asm_set_ipl( old_ipl );
-
-    return &rx_nbuf[i];
-}
-
-
-/********************************************************************/
-nbuf_t         *
-nbuf_tx_allocate(  )
-{
-    /* This routine alters shared data. Disable interrupts! */
-    int             old_ipl = asm_set_ipl( 6 );
-
-    /* Return a pointer to the next empty Tx Buffer Descriptor */
-    int             i = tx_bd_idx;
-
-    /* Check to see if ring of BDs is full */
-    if( ( tx_nbuf[i].status & TX_BD_INUSE ) || ( tx_nbuf[i].status & TX_BD_R ) )
-        return NULL;
-
-    /* Mark the buffer as Ready (in use) */
-    /* FEC must set R bit in transmit routine */
-    tx_nbuf[i].status |= TX_BD_INUSE;
-
-    /* increment the circular index */
-    tx_bd_idx = ( uint8 ) ( ( tx_bd_idx + 1 ) % NUM_TXBDS );
-
-    /* Restore previous IPL */
-    asm_set_ipl( old_ipl );
-
-    return &tx_nbuf[i];
-}
-
-
-/********************************************************************/
-void
-nbuf_rx_release( nbuf_t * pNbuf )
-{
-    /* This routine alters shared data. Disable interrupts! */
-    int             old_ipl = asm_set_ipl( 6 );
-
-    /* Mark the buffer as empty and not in use */
-    pNbuf->status |= RX_BD_E;
-    pNbuf->status &= ~RX_BD_INUSE;
-
-    /* Restore previous IPL */
-    asm_set_ipl( old_ipl );
-}
-
-/********************************************************************/
-void
-nbuf_tx_release( nbuf_t * pNbuf )
-{
-    /* This routine alters shared data. Disable interrupts! */
-    int             old_ipl = asm_set_ipl( 6 );
-
-    /* Mark the buffer as not in use */
-    pNbuf->status &= ~TX_BD_INUSE;
-
-    /* Restore previous IPL */
-    asm_set_ipl( old_ipl );
-}
-
-/********************************************************************/
-int
-nbuf_rx_next_ready(  )
-{
-    /****************************************************************
- This function checks the EMPTY bit of the next Rx buffer to be
- allocated. If the EMPTY bit is cleared, then the next buffer in
- the ring has been filled by the FEC and has not already been
- allocated and passed up the stack. In this case, the next buffer
- in the ring is ready to be allocated. Otherwise, the  buffer is
- either empty or not empty but still in use by a higher level
- protocol. The FEC receive routine uses this function to determine
- if multiple buffers where filled by the FEC during a single
- interrupt event.
- ****************************************************************/
-
-    return ( !( rx_nbuf[rx_bd_idx].status & RX_BD_E ) );
-}
+/*\r
+ * Network buffer code based on the MCF523x examples from Freescale.\r
+ *\r
+ * File: $Id: nbuf.c,v 1.2 2006/08/31 22:28:21 wolti Exp $\r
+ */\r
+\r
+/* ------------------------ Platform includes ----------------------------- */\r
+#include "mcf5xxx.h"\r
+#include "mcf523x.h"\r
+\r
+#include "nbuf.h"\r
+\r
+/* ------------------------ Static variables ------------------------------ */\r
+\r
+/* Buffer descriptor indexes */\r
+static uint8    tx_bd_idx;\r
+static uint8    rx_bd_idx;\r
+\r
+/* Buffer Descriptors -- must be aligned on a 4-byte boundary but a\r
+ * 16-byte boundary is recommended. */\r
+static nbuf_t   tx_nbuf[sizeof( nbuf_t ) * NUM_TXBDS] ATTR_FECMEM;\r
+static nbuf_t   rx_nbuf[sizeof( nbuf_t ) * NUM_RXBDS] ATTR_FECMEM;\r
+\r
+/* Data Buffers -- must be aligned on a 16-byte boundary. */\r
+static uint8    tx_buf[TX_BUFFER_SIZE * NUM_TXBDS] ATTR_FECMEM;\r
+static uint8    rx_buf[RX_BUFFER_SIZE * NUM_RXBDS] ATTR_FECMEM;\r
+\r
+/* ------------------------ Start implementation -------------------------- */\r
+void\r
+nbuf_init(  )\r
+{\r
+\r
+    uint8           i;\r
+\r
+    /* Initialize receive descriptor ring */\r
+    for( i = 0; i < NUM_RXBDS; i++ )\r
+    {\r
+        rx_nbuf[i].status = RX_BD_E;\r
+        rx_nbuf[i].length = 0;\r
+        rx_nbuf[i].data = &rx_buf[i * RX_BUFFER_SIZE];\r
+    }\r
+\r
+    /* Set the Wrap bit on the last one in the ring */\r
+    rx_nbuf[NUM_RXBDS - 1].status |= RX_BD_W;\r
+\r
+    /* Initialize transmit descriptor ring */\r
+    for( i = 0; i < NUM_TXBDS; i++ )\r
+    {\r
+        tx_nbuf[i].status = TX_BD_L | TX_BD_TC;\r
+        tx_nbuf[i].length = 0;\r
+        tx_nbuf[i].data = &tx_buf[i * TX_BUFFER_SIZE];\r
+    }\r
+\r
+    /* Set the Wrap bit on the last one in the ring */\r
+    tx_nbuf[NUM_TXBDS - 1].status |= TX_BD_W;\r
+\r
+    /* Initialize the buffer descriptor indexes */\r
+    tx_bd_idx = rx_bd_idx = 0;\r
+\r
+    return;\r
+}\r
+\r
+\r
+/********************************************************************/\r
+uint32\r
+nbuf_get_start( uint8 direction )\r
+{\r
+    /*\r
+     * Return the address of the first buffer descriptor in the ring.\r
+     * This routine is needed by the FEC of the MPC860T , MCF5282, and MCF523x\r
+     * in order to write the Rx/Tx descriptor ring start registers\r
+     */\r
+    switch ( direction )\r
+    {\r
+    case NBUF_RX:\r
+        return ( uint32 ) rx_nbuf;\r
+    case NBUF_TX:\r
+    default:\r
+        return ( uint32 ) tx_nbuf;\r
+    }\r
+}\r
+\r
+\r
+/********************************************************************/\r
+nbuf_t         *\r
+nbuf_rx_allocate(  )\r
+{\r
+    /* This routine alters shared data. Disable interrupts! */\r
+    int             old_ipl = asm_set_ipl( 6 );\r
+\r
+    /* Return a pointer to the next empty Rx Buffer Descriptor */\r
+    int             i = rx_bd_idx;\r
+\r
+\r
+    /* Check to see if the ring of BDs is full */\r
+    if( rx_nbuf[i].status & RX_BD_INUSE )\r
+        return NULL;\r
+\r
+    /* Mark the buffer as in use */\r
+    rx_nbuf[i].status |= RX_BD_INUSE;\r
+\r
+    /* increment the circular index */\r
+    rx_bd_idx = ( uint8 ) ( ( rx_bd_idx + 1 ) % NUM_RXBDS );\r
+\r
+    /* Restore previous IPL */\r
+    asm_set_ipl( old_ipl );\r
+\r
+    return &rx_nbuf[i];\r
+}\r
+\r
+\r
+/********************************************************************/\r
+nbuf_t         *\r
+nbuf_tx_allocate(  )\r
+{\r
+    /* This routine alters shared data. Disable interrupts! */\r
+    int             old_ipl = asm_set_ipl( 6 );\r
+\r
+    /* Return a pointer to the next empty Tx Buffer Descriptor */\r
+    int             i = tx_bd_idx;\r
+\r
+    /* Check to see if ring of BDs is full */\r
+    if( ( tx_nbuf[i].status & TX_BD_INUSE ) || ( tx_nbuf[i].status & TX_BD_R ) )\r
+        return NULL;\r
+\r
+    /* Mark the buffer as Ready (in use) */\r
+    /* FEC must set R bit in transmit routine */\r
+    tx_nbuf[i].status |= TX_BD_INUSE;\r
+\r
+    /* increment the circular index */\r
+    tx_bd_idx = ( uint8 ) ( ( tx_bd_idx + 1 ) % NUM_TXBDS );\r
+\r
+    /* Restore previous IPL */\r
+    asm_set_ipl( old_ipl );\r
+\r
+    return &tx_nbuf[i];\r
+}\r
+\r
+\r
+/********************************************************************/\r
+void\r
+nbuf_rx_release( nbuf_t * pNbuf )\r
+{\r
+    /* This routine alters shared data. Disable interrupts! */\r
+    int             old_ipl = asm_set_ipl( 6 );\r
+\r
+    /* Mark the buffer as empty and not in use */\r
+    pNbuf->status |= RX_BD_E;\r
+    pNbuf->status &= ~RX_BD_INUSE;\r
+\r
+    /* Restore previous IPL */\r
+    asm_set_ipl( old_ipl );\r
+}\r
+\r
+/********************************************************************/\r
+void\r
+nbuf_tx_release( nbuf_t * pNbuf )\r
+{\r
+    /* This routine alters shared data. Disable interrupts! */\r
+    int             old_ipl = asm_set_ipl( 6 );\r
+\r
+    /* Mark the buffer as not in use */\r
+    pNbuf->status &= ~TX_BD_INUSE;\r
+\r
+    /* Restore previous IPL */\r
+    asm_set_ipl( old_ipl );\r
+}\r
+\r
+/********************************************************************/\r
+int\r
+nbuf_rx_next_ready(  )\r
+{\r
+    /****************************************************************\r
+ This function checks the EMPTY bit of the next Rx buffer to be\r
+ allocated. If the EMPTY bit is cleared, then the next buffer in\r
+ the ring has been filled by the FEC and has not already been\r
+ allocated and passed up the stack. In this case, the next buffer\r
+ in the ring is ready to be allocated. Otherwise, the  buffer is\r
+ either empty or not empty but still in use by a higher level\r
+ protocol. The FEC receive routine uses this function to determine\r
+ if multiple buffers where filled by the FEC during a single\r
+ interrupt event.\r
+ ****************************************************************/\r
+\r
+    return ( !( rx_nbuf[rx_bd_idx].status & RX_BD_E ) );\r
+}\r
index ecbc70a235ac57b072a6000c669d0168194d5252..cbd07495152336160809306f4c2392cd9127708b 100644 (file)
@@ -1,95 +1,95 @@
-/*
- * Network buffer code based on the MCF523x examples from Freescale.
- *
- * Freescale explicitly grants the redistribution and modification
- * of these source files. The complete licensing information is
- * available in the file LICENSE_FREESCALE.TXT.
- *
- * Modifications Copyright (c) 2006 Christian Walter <wolti@sil.at>
- *
- * File: $Id: nbuf.h,v 1.3 2006/09/24 22:50:23 wolti Exp $
- */
-
-#ifndef _NBUF_H
-#define _NBUF_H
-
-/* ------------------------ Defines --------------------------------------- */
-
-#ifdef __GNUC__
-#define ATTR_FECMEM             \
-    __attribute__((section(".nbuf"),aligned(16)))
-#endif
-
-#define NBUF_RX                 ( 1 )
-#define NBUF_TX                 ( 0 )
-
-/* We set the receiver buffers to the maximum size the FEC supports ( See
- * MCF5235 reference manual 19.2.5.1.2 - Driver/DMA Operation with Receive
- * BDs). This gives us the benefit that any frame fits into one buffer. A
- * maximum size of 2047 is guaranteed by the FEC and 2048 is therefore a
- * safe value.
- * Note: The value MUST be dividable by 16!
- */
-#define RX_BUFFER_SIZE          ( 2048 )
-
-/* Size of the transmit buffers. If you set this value to small all frames
- * greater than this size will be dropped. The value 1520 was choosen because
- * it is bigger than the FEC MTU (1518) and is dividable by 16.
- * Note: The value MUST be dividable by 16! */
-#define TX_BUFFER_SIZE          ( 1520 )
-
-/* Number of Receive and Transmit Buffers and Buffer Descriptors */
-#define NUM_RXBDS               ( 2 )
-#define NUM_TXBDS               ( 2 )
-
-/* ------------------------ Defines ( Buffer Descriptor Flags )------------ */
-
-#define TX_BD_R                 ( 0x8000 )
-#define TX_BD_INUSE             ( 0x4000 )
-#define TX_BD_TO1               ( 0x4000 )
-#define TX_BD_W                 ( 0x2000 )
-#define TX_BD_TO2               ( 0x1000 )
-#define TX_BD_L                 ( 0x0800 )
-#define TX_BD_TC                ( 0x0400 )
-#define TX_BD_DEF               ( 0x0200 )
-#define TX_BD_HB                ( 0x0100 )
-#define TX_BD_LC                ( 0x0080 )
-#define TX_BD_RL                ( 0x0040 )
-#define TX_BD_UN                ( 0x0002 )
-#define TX_BD_CSL               ( 0x0001 )
-
-#define RX_BD_E                 ( 0x8000 )
-#define RX_BD_INUSE             ( 0x4000 )
-#define RX_BD_R01               ( 0x4000 )
-#define RX_BD_W                 ( 0x2000 )
-#define RX_BD_R02               ( 0x1000 )
-#define RX_BD_L                 ( 0x0800 )
-#define RX_BD_M                 ( 0x0100 )
-#define RX_BD_BC                ( 0x0080 )
-#define RX_BD_MC                ( 0x0040 )
-#define RX_BD_LG                ( 0x0020 )
-#define RX_BD_NO                ( 0x0010 )
-#define RX_BD_SH                ( 0x0008 )
-#define RX_BD_CR                ( 0x0004 )
-#define RX_BD_OV                ( 0x0002 )
-#define RX_BD_TR                ( 0x0001 )
-
-/* ------------------------ Type definitions ------------------------------ */
-typedef struct
-{
-    uint16          status;     /* control and status */
-    uint16          length;     /* transfer length */
-    uint8          *data;       /* buffer address */
-} nbuf_t;
-
-/* ------------------------ Prototypes ------------------------------------ */
-
-void            nbuf_init( void );
-uint32          nbuf_get_start( uint8 );
-nbuf_t         *nbuf_rx_allocate( void );
-nbuf_t         *nbuf_tx_allocate( void );
-void            nbuf_rx_release( nbuf_t * );
-void            nbuf_tx_release( nbuf_t * );
-int             nbuf_rx_next_ready( void );
-
-#endif
+/*\r
+ * Network buffer code based on the MCF523x examples from Freescale.\r
+ *\r
+ * Freescale explicitly grants the redistribution and modification\r
+ * of these source files. The complete licensing information is\r
+ * available in the file LICENSE_FREESCALE.TXT.\r
+ *\r
+ * Modifications Copyright (c) 2006 Christian Walter <wolti@sil.at>\r
+ *\r
+ * File: $Id: nbuf.h,v 1.3 2006/09/24 22:50:23 wolti Exp $\r
+ */\r
+\r
+#ifndef _NBUF_H\r
+#define _NBUF_H\r
+\r
+/* ------------------------ Defines --------------------------------------- */\r
+\r
+#ifdef __GNUC__\r
+#define ATTR_FECMEM             \\r
+    __attribute__((section(".nbuf"),aligned(16)))\r
+#endif\r
+\r
+#define NBUF_RX                 ( 1 )\r
+#define NBUF_TX                 ( 0 )\r
+\r
+/* We set the receiver buffers to the maximum size the FEC supports ( See\r
+ * MCF5235 reference manual 19.2.5.1.2 - Driver/DMA Operation with Receive\r
+ * BDs). This gives us the benefit that any frame fits into one buffer. A\r
+ * maximum size of 2047 is guaranteed by the FEC and 2048 is therefore a\r
+ * safe value.\r
+ * Note: The value MUST be dividable by 16!\r
+ */\r
+#define RX_BUFFER_SIZE          ( 2048 )\r
+\r
+/* Size of the transmit buffers. If you set this value to small all frames\r
+ * greater than this size will be dropped. The value 1520 was choosen because\r
+ * it is bigger than the FEC MTU (1518) and is dividable by 16.\r
+ * Note: The value MUST be dividable by 16! */\r
+#define TX_BUFFER_SIZE          ( 1520 )\r
+\r
+/* Number of Receive and Transmit Buffers and Buffer Descriptors */\r
+#define NUM_RXBDS               ( 2 )\r
+#define NUM_TXBDS               ( 2 )\r
+\r
+/* ------------------------ Defines ( Buffer Descriptor Flags )------------ */\r
+\r
+#define TX_BD_R                 ( 0x8000 )\r
+#define TX_BD_INUSE             ( 0x4000 )\r
+#define TX_BD_TO1               ( 0x4000 )\r
+#define TX_BD_W                 ( 0x2000 )\r
+#define TX_BD_TO2               ( 0x1000 )\r
+#define TX_BD_L                 ( 0x0800 )\r
+#define TX_BD_TC                ( 0x0400 )\r
+#define TX_BD_DEF               ( 0x0200 )\r
+#define TX_BD_HB                ( 0x0100 )\r
+#define TX_BD_LC                ( 0x0080 )\r
+#define TX_BD_RL                ( 0x0040 )\r
+#define TX_BD_UN                ( 0x0002 )\r
+#define TX_BD_CSL               ( 0x0001 )\r
+\r
+#define RX_BD_E                 ( 0x8000 )\r
+#define RX_BD_INUSE             ( 0x4000 )\r
+#define RX_BD_R01               ( 0x4000 )\r
+#define RX_BD_W                 ( 0x2000 )\r
+#define RX_BD_R02               ( 0x1000 )\r
+#define RX_BD_L                 ( 0x0800 )\r
+#define RX_BD_M                 ( 0x0100 )\r
+#define RX_BD_BC                ( 0x0080 )\r
+#define RX_BD_MC                ( 0x0040 )\r
+#define RX_BD_LG                ( 0x0020 )\r
+#define RX_BD_NO                ( 0x0010 )\r
+#define RX_BD_SH                ( 0x0008 )\r
+#define RX_BD_CR                ( 0x0004 )\r
+#define RX_BD_OV                ( 0x0002 )\r
+#define RX_BD_TR                ( 0x0001 )\r
+\r
+/* ------------------------ Type definitions ------------------------------ */\r
+typedef struct\r
+{\r
+    uint16          status;     /* control and status */\r
+    uint16          length;     /* transfer length */\r
+    uint8          *data;       /* buffer address */\r
+} nbuf_t;\r
+\r
+/* ------------------------ Prototypes ------------------------------------ */\r
+\r
+void            nbuf_init( void );\r
+uint32          nbuf_get_start( uint8 );\r
+nbuf_t         *nbuf_rx_allocate( void );\r
+nbuf_t         *nbuf_tx_allocate( void );\r
+void            nbuf_rx_release( nbuf_t * );\r
+void            nbuf_tx_release( nbuf_t * );\r
+int             nbuf_rx_next_ready( void );\r
+\r
+#endif\r
index dc46d5a317c32c0efb56b7a8e751c373e412e8a3..218e91db063e72f8e352600c14779fdd6a354e68 100644 (file)
-/*
- * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
- * Modifications Copyright (c) 2006 Christian Walter <wolti@sil.at>
- * 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 <adam@sics.se>
- * Modifcations: Christian Walter <wolti@sil.at>
- *
- * $Id: sys_arch.c,v 1.6 2006/09/24 22:04:53 wolti Exp $
- */
-
-/* ------------------------ System includes ------------------------------- */
-#include <string.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <stdio.h>
-
-/* ------------------------ FreeRTOS includes ----------------------------- */
-#include "FreeRTOS.h"
-#include "task.h"
-#include "semphr.h"
-
-/* ------------------------ lwIP includes --------------------------------- */
-#include "lwip/debug.h"
-#include "lwip/def.h"
-#include "lwip/sys.h"
-#include "lwip/mem.h"
-#include "lwip/sio.h"
-#include "lwip/stats.h"
-
-/* ------------------------ Project includes ------------------------------ */
-
-/* ------------------------ Defines --------------------------------------- */
-/* This is the number of threads that can be started with sys_thead_new() */
-#define SYS_MBOX_SIZE               ( 16 )
-#define MS_TO_TICKS( ms )           \
-    ( portTickType )( ( portTickType ) ( ms ) / portTICK_RATE_MS )
-#define TICKS_TO_MS( ticks )        \
-    ( unsigned portLONG )( ( portTickType ) ( ticks ) * portTICK_RATE_MS )
-#define THREAD_STACK_SIZE           ( 1024 )
-#define THREAD_NAME                 "lwIP"
-
-#define THREAD_INIT( tcb ) \
-    do { \
-        tcb->next = NULL; \
-        tcb->pid = ( xTaskHandle )0; \
-        tcb->timeouts.next = NULL; \
-    } while( 0 )
-
-/* ------------------------ Type definitions ------------------------------ */
-typedef struct sys_tcb
-{
-    struct sys_tcb *next;
-    struct sys_timeouts timeouts;
-    xTaskHandle     pid;
-} sys_tcb_t;
-
-/* ------------------------ Prototypes ------------------------------------ */
-
-/* ------------------------ Static functions ------------------------------ */
-sys_tcb_t      *sys_thread_current( void );
-
-/* ------------------------ Static variables ------------------------------ */
-static sys_tcb_t *tasks = NULL;
-
-/* ------------------------ Start implementation -------------------------- */
-void
-sys_init( void )
-{
-    LWIP_ASSERT( "sys_init: not called first", tasks == NULL );
-    tasks = NULL;
-}
-
-/*
- * This optional function does a "fast" critical region protection and returns
- * the previous protection level. This function is only called during very short
- * critical regions. An embedded system which supports ISR-based drivers might
- * want to implement this function by disabling interrupts. Task-based systems
- * might want to implement this by using a mutex or disabling tasking. This
- * function should support recursive calls from the same task or interrupt. In
- * other words, sys_arch_protect() could be called while already protected. In
- * that case the return value indicates that it is already protected.
- *
- * sys_arch_protect() is only required if your port is supporting an operating
- * system.
- */
-sys_prot_t
-sys_arch_protect( void )
-{
-    vPortEnterCritical(  );
-    return 1;
-}
-
-/*
- * This optional function does a "fast" set of critical region protection to the
- * value specified by pval. See the documentation for sys_arch_protect() for
- * more information. This function is only required if your port is supporting
- * an operating system.
- */
-void
-sys_arch_unprotect( sys_prot_t pval )
-{
-    ( void )pval;
-    vPortExitCritical(  );
-}
-
-/*
- * Prints an assertion messages and aborts execution.
- */
-void
-sys_assert( const char *msg )
-{
-       fputs( msg, stderr );
-       fputs( "\n\r", stderr );
-    vPortEnterCritical(  );
-    for( ;; );
-}
-
-void
-sys_debug( const char *const fmt, ... )
-{
-    va_list         ap;
-
-    va_start( ap, fmt );
-    ( void )vprintf( fmt, ap );
-    ( void )putchar( '\r' );
-    va_end( ap );
-}
-
-/* ------------------------ Start implementation ( Threads ) -------------- */
-
-sys_thread_t
-sys_thread_new( void ( *thread ) ( void *arg ), void *arg, int prio )
-{
-    return sys_arch_thread_new( thread, arg, prio, THREAD_STACK_SIZE );
-}
-
-/*
- * Starts a new thread with priority "prio" that will begin its execution in the
- * function "thread()". The "arg" argument will be passed as an argument to the
- * thread() function. The argument "ssize" is the requested stack size for the
- * new thread. The id of the new thread is returned. Both the id and the
-  * priority are system dependent.
- */
-sys_thread_t
-sys_arch_thread_new( void ( *thread ) ( void *arg ), void *arg, int prio, size_t ssize )
-{
-    sys_thread_t    thread_hdl = SYS_THREAD_NULL;
-    int             i;
-    sys_tcb_t      *p;
-    char            thread_name[ configMAX_TASK_NAME_LEN ];
-
-    /* We disable the FreeRTOS scheduler because it might be the case that the new
-     * tasks gets scheduled inside the xTaskCreate function. To prevent this we
-     * disable the scheduling. Note that this can happen although we have interrupts
-     * disabled because xTaskCreate contains a call to taskYIELD( ).
-     */
-    vPortEnterCritical(  );
-
-    p = tasks;
-    i = 0;
-    /* We are called the first time. Initialize it. */
-    if( p == NULL )
-    {
-        p = pvPortMalloc( sizeof( sys_tcb_t ) );
-        if( p != NULL )
-        {
-            tasks = p;
-        }
-    }
-    else
-    {
-        /* First task already counter. */
-        i++;
-        /* Cycle to the end of the list. */
-        while( p->next != NULL )
-        {
-            i++;
-            p = p->next;
-        }
-        p->next = pvPortMalloc( sizeof( sys_tcb_t ) );
-        p = p->next;
-    }
-
-    if( p != NULL )
-    {
-        /* Memory allocated. Initialize the data structure. */
-        THREAD_INIT( p );
-        ( void )snprintf( thread_name, configMAX_TASK_NAME_LEN, "lwIP%d", i );
-
-        /* Now q points to a free element in the list. */
-        if( xTaskCreate( thread, thread_name, ssize, arg, prio, &p->pid ) == pdPASS )
-        {
-            thread_hdl = p;
-        }
-        else
-        {
-            vPortFree( p );
-        }
-    }
-
-    vPortExitCritical(  );
-    return thread_hdl;
-}
-
-void
-sys_arch_thread_remove( sys_thread_t hdl )
-{
-    sys_tcb_t      *current = tasks, *prev;
-    sys_tcb_t      *toremove = hdl;
-    xTaskHandle     pid = ( xTaskHandle ) 0;
-
-    LWIP_ASSERT( "sys_arch_thread_remove: assertion hdl != NULL failed!", hdl != NULL );
-
-    /* If we have to remove the first task we must update the global "tasks"
-     * variable. */
-    vPortEnterCritical(  );
-    if( hdl != NULL )
-    {
-        prev = NULL;
-        while( ( current != NULL ) && ( current != toremove ) )
-        {
-            prev = current;
-            current = current->next;
-        }
-        /* Found it. */
-        if( current == toremove )
-        {
-            /* Not the first entry in the list. */
-            if( prev != NULL )
-            {
-                prev->next = toremove->next;
-            }
-            else
-            {
-                tasks = toremove->next;
-            }
-            LWIP_ASSERT( "sys_arch_thread_remove: can't remove thread with timeouts!",
-                         toremove->timeouts.next == NULL );
-            pid = toremove->pid;
-            THREAD_INIT( toremove );
-            vPortFree( toremove );
-        }
-    }
-    /* We are done with accessing the shared datastructure. Release the 
-     * resources.
-     */
-    vPortExitCritical(  );
-    if( pid != ( xTaskHandle ) 0 )
-    {
-        vTaskDelete( pid );
-        /* not reached. */
-    }
-}
-
-/*
- * Returns the thread control block for the currently active task. In case
- * of an error the functions returns NULL.
- */
-sys_thread_t
-sys_arch_thread_current( void )
-{
-    sys_tcb_t      *p = tasks;
-    xTaskHandle     pid = xTaskGetCurrentTaskHandle(  );
-
-    vPortEnterCritical(  );
-    while( ( p != NULL ) && ( p->pid != pid ) )
-    {
-        p = p->next;
-    }
-    vPortExitCritical(  );
-    return p;
-}
-
-/*
- * Returns a pointer to the per-thread sys_timeouts structure. In lwIP,
- * each thread has a list of timeouts which is represented 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 threaded sys_arch implementation, this function will
- * simply return a pointer to a global sys_timeouts variable stored in
- * the sys_arch module.
- */
-struct sys_timeouts *
-sys_arch_timeouts( void )
-{
-    sys_tcb_t      *ptask;
-
-    ptask = sys_arch_thread_current(  );
-    LWIP_ASSERT( "sys_arch_timeouts: ptask != NULL", ptask != NULL );
-    return ptask != NULL ? &( ptask->timeouts ) : NULL;
-}
-
-/* ------------------------ Start implementation ( Semaphores ) ----------- */
-
-/* Creates and returns a new semaphore. The "count" argument specifies
- * the initial state of the semaphore.
- */
-sys_sem_t
-sys_sem_new( u8_t count )
-{
-    xSemaphoreHandle xSemaphore;
-
-    vSemaphoreCreateBinary( xSemaphore );
-    if( xSemaphore != SYS_SEM_NULL )
-    {
-        if( count == 0 )
-        {
-            xSemaphoreTake( xSemaphore, 1 );
-        }
-#ifdef SYS_STATS
-        vPortEnterCritical(  );
-        lwip_stats.sys.sem.used++;
-        if( lwip_stats.sys.sem.used > lwip_stats.sys.sem.max )
-        {
-            lwip_stats.sys.sem.max = lwip_stats.sys.sem.used;
-        }
-        vPortExitCritical(  );
-#endif
-    }
-    else
-    {
-        LWIP_ASSERT( "sys_sem_new: xSemaphore == SYS_SEM_NULL", xSemaphore != SYS_SEM_NULL );
-    }
-
-    return xSemaphore;
-}
-
-/* Deallocates a semaphore */
-void
-sys_sem_free( sys_sem_t sem )
-{
-    LWIP_ASSERT( "sys_sem_free: sem != SYS_SEM_NULL", sem != SYS_SEM_NULL );
-    if( sem != SYS_SEM_NULL )
-    {
-#ifdef SYS_STATS
-        vPortEnterCritical(  );
-        lwip_stats.sys.sem.used--;
-        vPortExitCritical(  );
-#endif
-        vQueueDelete( sem );
-    }
-}
-
-/* Signals a semaphore */
-void
-sys_sem_signal( sys_sem_t sem )
-{
-    LWIP_ASSERT( "sys_sem_signal: sem != SYS_SEM_NULL", sem != SYS_SEM_NULL );
-    xSemaphoreGive( sem );
-}
-
-/*
- * Blocks the thread while waiting for the semaphore to be
- * signaled. If the "timeout" argument is non-zero, the thread should
- * only be blocked for the specified time (measured in
- * milliseconds).
- *
- * If the timeout argument is non-zero, the return value is the number of
- * milliseconds spent waiting for the semaphore to be signaled. If the
- * semaphore wasn't signaled within the specified time, the return value is
- * SYS_ARCH_TIMEOUT. If the thread didn't have to wait for the semaphore
- * (i.e., it was already signaled), the function may return zero.
- *
- * Notice that lwIP implements a function with a similar name,
- * sys_sem_wait(), that uses the sys_arch_sem_wait() function.
- */
-u32_t
-sys_arch_sem_wait( sys_sem_t sem, u32_t timeout )
-{
-    portBASE_TYPE   xStatus;
-    portTickType    xTicksStart, xTicksEnd, xTicksElapsed;
-    u32_t           timespent;
-
-    LWIP_ASSERT( "sys_arch_sem_wait: sem != SYS_SEM_NULL", sem != SYS_SEM_NULL );
-    xTicksStart = xTaskGetTickCount(  );
-    if( timeout == 0 )
-    {
-        do
-        {
-            xStatus = xSemaphoreTake( sem, MS_TO_TICKS( 100 ) );
-        }
-        while( xStatus != pdTRUE );
-    }
-    else
-    {
-        xStatus = xSemaphoreTake( sem, MS_TO_TICKS( timeout ) );
-    }
-
-    /* Semaphore was signaled. */
-    if( xStatus == pdTRUE )
-    {
-        xTicksEnd = xTaskGetTickCount(  );
-        xTicksElapsed = xTicksEnd - xTicksStart;
-        timespent = TICKS_TO_MS( xTicksElapsed );
-    }
-    else
-    {
-        timespent = SYS_ARCH_TIMEOUT;
-    }
-    return timespent;
-}
-
-
-/* ------------------------ Start implementation ( Mailboxes ) ------------ */
-
-/* Creates an empty mailbox. */
-sys_mbox_t
-sys_mbox_new( void )
-{
-    xQueueHandle    mbox;
-
-    mbox = xQueueCreate( SYS_MBOX_SIZE, sizeof( void * ) );
-    if( mbox != SYS_MBOX_NULL )
-    {
-#ifdef SYS_STATS
-        vPortEnterCritical(  );
-        lwip_stats.sys.mbox.used++;
-        if( lwip_stats.sys.mbox.used > lwip_stats.sys.mbox.max )
-        {
-            lwip_stats.sys.mbox.max = lwip_stats.sys.mbox.used;
-        }
-        vPortExitCritical(  );
-#endif
-    }
-    return mbox;
-}
-
-/*
-  Deallocates a mailbox. If there are messages still present in the
-  mailbox when the mailbox is deallocated, it is an indication of a
-  programming error in lwIP and the developer should be notified.
-*/
-void
-sys_mbox_free( sys_mbox_t mbox )
-{
-    void           *msg;
-
-    LWIP_ASSERT( "sys_mbox_free: mbox != SYS_MBOX_NULL", mbox != SYS_MBOX_NULL );
-    if( mbox != SYS_MBOX_NULL )
-    {
-        while( uxQueueMessagesWaiting( mbox ) != 0 )
-        {
-            if( sys_arch_mbox_fetch( mbox, &msg, 1 ) != SYS_ARCH_TIMEOUT )
-            {
-                LWIP_ASSERT( "sys_mbox_free: memory leak (msg != NULL)", msg == NULL );
-            }
-        }
-        vQueueDelete( mbox );
-#ifdef SYS_STATS
-        vPortEnterCritical(  );
-        lwip_stats.sys.mbox.used--;
-        vPortExitCritical(  );
-#endif
-    }
-}
-
-/*
- * This function sends a message to a mailbox. It is unusual in that no error
- * return is made. This is because the caller is responsible for ensuring that
- * the mailbox queue will not fail. The caller does this by limiting the number
- * of msg structures which exist for a given mailbox.
- */
-void
-sys_mbox_post( sys_mbox_t mbox, void *data )
-{
-    portBASE_TYPE   xQueueSent;
-
-    /* Queue must not be full - Otherwise it is an error. */
-    xQueueSent = xQueueSend( mbox, &data, 0 );
-    LWIP_ASSERT( "sys_mbox_post: xQueueSent == pdPASS", xQueueSent == pdPASS );
-}
-
-/*
- * Blocks the thread until a message arrives in the mailbox, but does
- * not block the thread longer than "timeout" milliseconds (similar to
- * the sys_arch_sem_wait() function). The "msg" argument is a result
- * parameter that is set by the function (i.e., by doing "*msg =
- * ptr"). The "msg" parameter maybe NULL to indicate that the message
- * should be dropped.
- *
- * Note that a function with a similar name, sys_mbox_fetch(), is
- * implemented by lwIP.
- */
-u32_t
-sys_arch_mbox_fetch( sys_mbox_t mbox, void **msg, u32_t timeout )
-{
-    void           *ret_msg;
-    portBASE_TYPE   xStatus;
-    portTickType    xTicksStart, xTicksEnd, xTicksElapsed;
-    u32_t           timespent;
-
-    LWIP_ASSERT( "sys_arch_mbox_fetch: mbox != SYS_MBOX_NULL", mbox != SYS_MBOX_NULL );
-    xTicksStart = xTaskGetTickCount(  );
-    if( timeout == 0 )
-    {
-        do
-        {
-            xStatus = xQueueReceive( mbox, &ret_msg, MS_TO_TICKS( 100 ) );
-        }
-        while( xStatus != pdTRUE );
-    }
-    else
-    {
-        xStatus = xQueueReceive( mbox, &ret_msg, MS_TO_TICKS( timeout ) );
-    }
-
-    if( xStatus == pdTRUE )
-    {
-        if( msg )
-        {
-            *msg = ret_msg;
-        }
-        xTicksEnd = xTaskGetTickCount(  );
-        xTicksElapsed = xTicksEnd - xTicksStart;
-        timespent = TICKS_TO_MS( xTicksElapsed );
-    }
-    else
-    {
-        if( msg )
-        {
-            *msg = NULL;
-        }
-        timespent = SYS_ARCH_TIMEOUT;
-    }
-    return timespent;
-}
-
-u32_t
-sys_jiffies( void )
-{
-    portTickType    xTicks = xTaskGetTickCount(  );
-
-    return ( u32_t )TICKS_TO_MS( xTicks );
-}
+/*\r
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.\r
+ * Modifications Copyright (c) 2006 Christian Walter <wolti@sil.at>\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without modification,\r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED\r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT\r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY\r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ *\r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ * Modifcations: Christian Walter <wolti@sil.at>\r
+ *\r
+ * $Id: sys_arch.c,v 1.6 2006/09/24 22:04:53 wolti Exp $\r
+ */\r
+\r
+/* ------------------------ System includes ------------------------------- */\r
+#include <string.h>\r
+#include <stdlib.h>\r
+#include <stdarg.h>\r
+#include <stdio.h>\r
+\r
+/* ------------------------ FreeRTOS includes ----------------------------- */\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+#include "semphr.h"\r
+\r
+/* ------------------------ lwIP includes --------------------------------- */\r
+#include "lwip/debug.h"\r
+#include "lwip/def.h"\r
+#include "lwip/sys.h"\r
+#include "lwip/mem.h"\r
+#include "lwip/sio.h"\r
+#include "lwip/stats.h"\r
+\r
+/* ------------------------ Project includes ------------------------------ */\r
+\r
+/* ------------------------ Defines --------------------------------------- */\r
+/* This is the number of threads that can be started with sys_thead_new() */\r
+#define SYS_MBOX_SIZE               ( 16 )\r
+#define MS_TO_TICKS( ms )           \\r
+    ( portTickType )( ( portTickType ) ( ms ) / portTICK_RATE_MS )\r
+#define TICKS_TO_MS( ticks )        \\r
+    ( unsigned portLONG )( ( portTickType ) ( ticks ) * portTICK_RATE_MS )\r
+#define THREAD_STACK_SIZE           ( 1024 )\r
+#define THREAD_NAME                 "lwIP"\r
+\r
+#define THREAD_INIT( tcb ) \\r
+    do { \\r
+        tcb->next = NULL; \\r
+        tcb->pid = ( xTaskHandle )0; \\r
+        tcb->timeouts.next = NULL; \\r
+    } while( 0 )\r
+\r
+/* ------------------------ Type definitions ------------------------------ */\r
+typedef struct sys_tcb\r
+{\r
+    struct sys_tcb *next;\r
+    struct sys_timeouts timeouts;\r
+    xTaskHandle     pid;\r
+} sys_tcb_t;\r
+\r
+/* ------------------------ Prototypes ------------------------------------ */\r
+\r
+/* ------------------------ Static functions ------------------------------ */\r
+sys_tcb_t      *sys_thread_current( void );\r
+\r
+/* ------------------------ Static variables ------------------------------ */\r
+static sys_tcb_t *tasks = NULL;\r
+\r
+/* ------------------------ Start implementation -------------------------- */\r
+void\r
+sys_init( void )\r
+{\r
+    LWIP_ASSERT( "sys_init: not called first", tasks == NULL );\r
+    tasks = NULL;\r
+}\r
+\r
+/*\r
+ * This optional function does a "fast" critical region protection and returns\r
+ * the previous protection level. This function is only called during very short\r
+ * critical regions. An embedded system which supports ISR-based drivers might\r
+ * want to implement this function by disabling interrupts. Task-based systems\r
+ * might want to implement this by using a mutex or disabling tasking. This\r
+ * function should support recursive calls from the same task or interrupt. In\r
+ * other words, sys_arch_protect() could be called while already protected. In\r
+ * that case the return value indicates that it is already protected.\r
+ *\r
+ * sys_arch_protect() is only required if your port is supporting an operating\r
+ * system.\r
+ */\r
+sys_prot_t\r
+sys_arch_protect( void )\r
+{\r
+    vPortEnterCritical(  );\r
+    return 1;\r
+}\r
+\r
+/*\r
+ * This optional function does a "fast" set of critical region protection to the\r
+ * value specified by pval. See the documentation for sys_arch_protect() for\r
+ * more information. This function is only required if your port is supporting\r
+ * an operating system.\r
+ */\r
+void\r
+sys_arch_unprotect( sys_prot_t pval )\r
+{\r
+    ( void )pval;\r
+    vPortExitCritical(  );\r
+}\r
+\r
+/*\r
+ * Prints an assertion messages and aborts execution.\r
+ */\r
+void\r
+sys_assert( const char *msg )\r
+{\r
+       fputs( msg, stderr );\r
+       fputs( "\n\r", stderr );\r
+    vPortEnterCritical(  );\r
+    for( ;; );\r
+}\r
+\r
+void\r
+sys_debug( const char *const fmt, ... )\r
+{\r
+    va_list         ap;\r
+\r
+    va_start( ap, fmt );\r
+    ( void )vprintf( fmt, ap );\r
+    ( void )putchar( '\r' );\r
+    va_end( ap );\r
+}\r
+\r
+/* ------------------------ Start implementation ( Threads ) -------------- */\r
+\r
+sys_thread_t\r
+sys_thread_new( void ( *thread ) ( void *arg ), void *arg, int prio )\r
+{\r
+    return sys_arch_thread_new( thread, arg, prio, THREAD_STACK_SIZE );\r
+}\r
+\r
+/*\r
+ * Starts a new thread with priority "prio" that will begin its execution in the\r
+ * function "thread()". The "arg" argument will be passed as an argument to the\r
+ * thread() function. The argument "ssize" is the requested stack size for the\r
+ * new thread. The id of the new thread is returned. Both the id and the\r
+  * priority are system dependent.\r
+ */\r
+sys_thread_t\r
+sys_arch_thread_new( void ( *thread ) ( void *arg ), void *arg, int prio, size_t ssize )\r
+{\r
+    sys_thread_t    thread_hdl = SYS_THREAD_NULL;\r
+    int             i;\r
+    sys_tcb_t      *p;\r
+    char            thread_name[ configMAX_TASK_NAME_LEN ];\r
+\r
+    /* We disable the FreeRTOS scheduler because it might be the case that the new\r
+     * tasks gets scheduled inside the xTaskCreate function. To prevent this we\r
+     * disable the scheduling. Note that this can happen although we have interrupts\r
+     * disabled because xTaskCreate contains a call to taskYIELD( ).\r
+     */\r
+    vPortEnterCritical(  );\r
+\r
+    p = tasks;\r
+    i = 0;\r
+    /* We are called the first time. Initialize it. */\r
+    if( p == NULL )\r
+    {\r
+        p = pvPortMalloc( sizeof( sys_tcb_t ) );\r
+        if( p != NULL )\r
+        {\r
+            tasks = p;\r
+        }\r
+    }\r
+    else\r
+    {\r
+        /* First task already counter. */\r
+        i++;\r
+        /* Cycle to the end of the list. */\r
+        while( p->next != NULL )\r
+        {\r
+            i++;\r
+            p = p->next;\r
+        }\r
+        p->next = pvPortMalloc( sizeof( sys_tcb_t ) );\r
+        p = p->next;\r
+    }\r
+\r
+    if( p != NULL )\r
+    {\r
+        /* Memory allocated. Initialize the data structure. */\r
+        THREAD_INIT( p );\r
+        ( void )snprintf( thread_name, configMAX_TASK_NAME_LEN, "lwIP%d", i );\r
+\r
+        /* Now q points to a free element in the list. */\r
+        if( xTaskCreate( thread, thread_name, ssize, arg, prio, &p->pid ) == pdPASS )\r
+        {\r
+            thread_hdl = p;\r
+        }\r
+        else\r
+        {\r
+            vPortFree( p );\r
+        }\r
+    }\r
+\r
+    vPortExitCritical(  );\r
+    return thread_hdl;\r
+}\r
+\r
+void\r
+sys_arch_thread_remove( sys_thread_t hdl )\r
+{\r
+    sys_tcb_t      *current = tasks, *prev;\r
+    sys_tcb_t      *toremove = hdl;\r
+    xTaskHandle     pid = ( xTaskHandle ) 0;\r
+\r
+    LWIP_ASSERT( "sys_arch_thread_remove: assertion hdl != NULL failed!", hdl != NULL );\r
+\r
+    /* If we have to remove the first task we must update the global "tasks"\r
+     * variable. */\r
+    vPortEnterCritical(  );\r
+    if( hdl != NULL )\r
+    {\r
+        prev = NULL;\r
+        while( ( current != NULL ) && ( current != toremove ) )\r
+        {\r
+            prev = current;\r
+            current = current->next;\r
+        }\r
+        /* Found it. */\r
+        if( current == toremove )\r
+        {\r
+            /* Not the first entry in the list. */\r
+            if( prev != NULL )\r
+            {\r
+                prev->next = toremove->next;\r
+            }\r
+            else\r
+            {\r
+                tasks = toremove->next;\r
+            }\r
+            LWIP_ASSERT( "sys_arch_thread_remove: can't remove thread with timeouts!",\r
+                         toremove->timeouts.next == NULL );\r
+            pid = toremove->pid;\r
+            THREAD_INIT( toremove );\r
+            vPortFree( toremove );\r
+        }\r
+    }\r
+    /* We are done with accessing the shared datastructure. Release the \r
+     * resources.\r
+     */\r
+    vPortExitCritical(  );\r
+    if( pid != ( xTaskHandle ) 0 )\r
+    {\r
+        vTaskDelete( pid );\r
+        /* not reached. */\r
+    }\r
+}\r
+\r
+/*\r
+ * Returns the thread control block for the currently active task. In case\r
+ * of an error the functions returns NULL.\r
+ */\r
+sys_thread_t\r
+sys_arch_thread_current( void )\r
+{\r
+    sys_tcb_t      *p = tasks;\r
+    xTaskHandle     pid = xTaskGetCurrentTaskHandle(  );\r
+\r
+    vPortEnterCritical(  );\r
+    while( ( p != NULL ) && ( p->pid != pid ) )\r
+    {\r
+        p = p->next;\r
+    }\r
+    vPortExitCritical(  );\r
+    return p;\r
+}\r
+\r
+/*\r
+ * Returns a pointer to the per-thread sys_timeouts structure. In lwIP,\r
+ * each thread has a list of timeouts which is represented as a linked\r
+ * list of sys_timeout structures. The sys_timeouts structure holds a\r
+ * pointer to a linked list of timeouts. This function is called by\r
+ * the lwIP timeout scheduler and must not return a NULL value.\r
+ *\r
+ * In a single threaded sys_arch implementation, this function will\r
+ * simply return a pointer to a global sys_timeouts variable stored in\r
+ * the sys_arch module.\r
+ */\r
+struct sys_timeouts *\r
+sys_arch_timeouts( void )\r
+{\r
+    sys_tcb_t      *ptask;\r
+\r
+    ptask = sys_arch_thread_current(  );\r
+    LWIP_ASSERT( "sys_arch_timeouts: ptask != NULL", ptask != NULL );\r
+    return ptask != NULL ? &( ptask->timeouts ) : NULL;\r
+}\r
+\r
+/* ------------------------ Start implementation ( Semaphores ) ----------- */\r
+\r
+/* Creates and returns a new semaphore. The "count" argument specifies\r
+ * the initial state of the semaphore.\r
+ */\r
+sys_sem_t\r
+sys_sem_new( u8_t count )\r
+{\r
+    xSemaphoreHandle xSemaphore;\r
+\r
+    vSemaphoreCreateBinary( xSemaphore );\r
+    if( xSemaphore != SYS_SEM_NULL )\r
+    {\r
+        if( count == 0 )\r
+        {\r
+            xSemaphoreTake( xSemaphore, 1 );\r
+        }\r
+#ifdef SYS_STATS\r
+        vPortEnterCritical(  );\r
+        lwip_stats.sys.sem.used++;\r
+        if( lwip_stats.sys.sem.used > lwip_stats.sys.sem.max )\r
+        {\r
+            lwip_stats.sys.sem.max = lwip_stats.sys.sem.used;\r
+        }\r
+        vPortExitCritical(  );\r
+#endif\r
+    }\r
+    else\r
+    {\r
+        LWIP_ASSERT( "sys_sem_new: xSemaphore == SYS_SEM_NULL", xSemaphore != SYS_SEM_NULL );\r
+    }\r
+\r
+    return xSemaphore;\r
+}\r
+\r
+/* Deallocates a semaphore */\r
+void\r
+sys_sem_free( sys_sem_t sem )\r
+{\r
+    LWIP_ASSERT( "sys_sem_free: sem != SYS_SEM_NULL", sem != SYS_SEM_NULL );\r
+    if( sem != SYS_SEM_NULL )\r
+    {\r
+#ifdef SYS_STATS\r
+        vPortEnterCritical(  );\r
+        lwip_stats.sys.sem.used--;\r
+        vPortExitCritical(  );\r
+#endif\r
+        vQueueDelete( sem );\r
+    }\r
+}\r
+\r
+/* Signals a semaphore */\r
+void\r
+sys_sem_signal( sys_sem_t sem )\r
+{\r
+    LWIP_ASSERT( "sys_sem_signal: sem != SYS_SEM_NULL", sem != SYS_SEM_NULL );\r
+    xSemaphoreGive( sem );\r
+}\r
+\r
+/*\r
+ * Blocks the thread while waiting for the semaphore to be\r
+ * signaled. If the "timeout" argument is non-zero, the thread should\r
+ * only be blocked for the specified time (measured in\r
+ * milliseconds).\r
+ *\r
+ * If the timeout argument is non-zero, the return value is the number of\r
+ * milliseconds spent waiting for the semaphore to be signaled. If the\r
+ * semaphore wasn't signaled within the specified time, the return value is\r
+ * SYS_ARCH_TIMEOUT. If the thread didn't have to wait for the semaphore\r
+ * (i.e., it was already signaled), the function may return zero.\r
+ *\r
+ * Notice that lwIP implements a function with a similar name,\r
+ * sys_sem_wait(), that uses the sys_arch_sem_wait() function.\r
+ */\r
+u32_t\r
+sys_arch_sem_wait( sys_sem_t sem, u32_t timeout )\r
+{\r
+    portBASE_TYPE   xStatus;\r
+    portTickType    xTicksStart, xTicksEnd, xTicksElapsed;\r
+    u32_t           timespent;\r
+\r
+    LWIP_ASSERT( "sys_arch_sem_wait: sem != SYS_SEM_NULL", sem != SYS_SEM_NULL );\r
+    xTicksStart = xTaskGetTickCount(  );\r
+    if( timeout == 0 )\r
+    {\r
+        do\r
+        {\r
+            xStatus = xSemaphoreTake( sem, MS_TO_TICKS( 100 ) );\r
+        }\r
+        while( xStatus != pdTRUE );\r
+    }\r
+    else\r
+    {\r
+        xStatus = xSemaphoreTake( sem, MS_TO_TICKS( timeout ) );\r
+    }\r
+\r
+    /* Semaphore was signaled. */\r
+    if( xStatus == pdTRUE )\r
+    {\r
+        xTicksEnd = xTaskGetTickCount(  );\r
+        xTicksElapsed = xTicksEnd - xTicksStart;\r
+        timespent = TICKS_TO_MS( xTicksElapsed );\r
+    }\r
+    else\r
+    {\r
+        timespent = SYS_ARCH_TIMEOUT;\r
+    }\r
+    return timespent;\r
+}\r
+\r
+\r
+/* ------------------------ Start implementation ( Mailboxes ) ------------ */\r
+\r
+/* Creates an empty mailbox. */\r
+sys_mbox_t\r
+sys_mbox_new( void )\r
+{\r
+    xQueueHandle    mbox;\r
+\r
+    mbox = xQueueCreate( SYS_MBOX_SIZE, sizeof( void * ) );\r
+    if( mbox != SYS_MBOX_NULL )\r
+    {\r
+#ifdef SYS_STATS\r
+        vPortEnterCritical(  );\r
+        lwip_stats.sys.mbox.used++;\r
+        if( lwip_stats.sys.mbox.used > lwip_stats.sys.mbox.max )\r
+        {\r
+            lwip_stats.sys.mbox.max = lwip_stats.sys.mbox.used;\r
+        }\r
+        vPortExitCritical(  );\r
+#endif\r
+    }\r
+    return mbox;\r
+}\r
+\r
+/*\r
+  Deallocates a mailbox. If there are messages still present in the\r
+  mailbox when the mailbox is deallocated, it is an indication of a\r
+  programming error in lwIP and the developer should be notified.\r
+*/\r
+void\r
+sys_mbox_free( sys_mbox_t mbox )\r
+{\r
+    void           *msg;\r
+\r
+    LWIP_ASSERT( "sys_mbox_free: mbox != SYS_MBOX_NULL", mbox != SYS_MBOX_NULL );\r
+    if( mbox != SYS_MBOX_NULL )\r
+    {\r
+        while( uxQueueMessagesWaiting( mbox ) != 0 )\r
+        {\r
+            if( sys_arch_mbox_fetch( mbox, &msg, 1 ) != SYS_ARCH_TIMEOUT )\r
+            {\r
+                LWIP_ASSERT( "sys_mbox_free: memory leak (msg != NULL)", msg == NULL );\r
+            }\r
+        }\r
+        vQueueDelete( mbox );\r
+#ifdef SYS_STATS\r
+        vPortEnterCritical(  );\r
+        lwip_stats.sys.mbox.used--;\r
+        vPortExitCritical(  );\r
+#endif\r
+    }\r
+}\r
+\r
+/*\r
+ * This function sends a message to a mailbox. It is unusual in that no error\r
+ * return is made. This is because the caller is responsible for ensuring that\r
+ * the mailbox queue will not fail. The caller does this by limiting the number\r
+ * of msg structures which exist for a given mailbox.\r
+ */\r
+void\r
+sys_mbox_post( sys_mbox_t mbox, void *data )\r
+{\r
+    portBASE_TYPE   xQueueSent;\r
+\r
+    /* Queue must not be full - Otherwise it is an error. */\r
+    xQueueSent = xQueueSend( mbox, &data, 0 );\r
+    LWIP_ASSERT( "sys_mbox_post: xQueueSent == pdPASS", xQueueSent == pdPASS );\r
+}\r
+\r
+/*\r
+ * Blocks the thread until a message arrives in the mailbox, but does\r
+ * not block the thread longer than "timeout" milliseconds (similar to\r
+ * the sys_arch_sem_wait() function). The "msg" argument is a result\r
+ * parameter that is set by the function (i.e., by doing "*msg =\r
+ * ptr"). The "msg" parameter maybe NULL to indicate that the message\r
+ * should be dropped.\r
+ *\r
+ * Note that a function with a similar name, sys_mbox_fetch(), is\r
+ * implemented by lwIP.\r
+ */\r
+u32_t\r
+sys_arch_mbox_fetch( sys_mbox_t mbox, void **msg, u32_t timeout )\r
+{\r
+    void           *ret_msg;\r
+    portBASE_TYPE   xStatus;\r
+    portTickType    xTicksStart, xTicksEnd, xTicksElapsed;\r
+    u32_t           timespent;\r
+\r
+    LWIP_ASSERT( "sys_arch_mbox_fetch: mbox != SYS_MBOX_NULL", mbox != SYS_MBOX_NULL );\r
+    xTicksStart = xTaskGetTickCount(  );\r
+    if( timeout == 0 )\r
+    {\r
+        do\r
+        {\r
+            xStatus = xQueueReceive( mbox, &ret_msg, MS_TO_TICKS( 100 ) );\r
+        }\r
+        while( xStatus != pdTRUE );\r
+    }\r
+    else\r
+    {\r
+        xStatus = xQueueReceive( mbox, &ret_msg, MS_TO_TICKS( timeout ) );\r
+    }\r
+\r
+    if( xStatus == pdTRUE )\r
+    {\r
+        if( msg )\r
+        {\r
+            *msg = ret_msg;\r
+        }\r
+        xTicksEnd = xTaskGetTickCount(  );\r
+        xTicksElapsed = xTicksEnd - xTicksStart;\r
+        timespent = TICKS_TO_MS( xTicksElapsed );\r
+    }\r
+    else\r
+    {\r
+        if( msg )\r
+        {\r
+            *msg = NULL;\r
+        }\r
+        timespent = SYS_ARCH_TIMEOUT;\r
+    }\r
+    return timespent;\r
+}\r
+\r
+u32_t\r
+sys_jiffies( void )\r
+{\r
+    portTickType    xTicks = xTaskGetTickCount(  );\r
+\r
+    return ( u32_t )TICKS_TO_MS( xTicks );\r
+}\r
index 3d83d1ea4b3ba07ead465135f72c84b86acaf66f..d9cf7efbe70b5906f0f13ea3b30cedcfcc635aa7 100644 (file)
-/*
- * 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 <adam@sics.se>
- *
- */
-
-/* This is the part of the API that is linked with
-   the application */
-
-#include "lwip/opt.h"
-#include "lwip/api.h"
-#include "lwip/api_msg.h"
-#include "lwip/memp.h"
-
-
-struct
-netbuf *netbuf_new(void)
-{
-  struct netbuf *buf;
-
-  buf = memp_malloc(MEMP_NETBUF);
-  if (buf != NULL) {
-    buf->p = NULL;
-    buf->ptr = NULL;
-    return buf;
-  } else {
-    return NULL;
-  }
-}
-
-void
-netbuf_delete(struct netbuf *buf)
-{
-  if (buf != NULL) {
-    if (buf->p != NULL) {
-      pbuf_free(buf->p);
-      buf->p = buf->ptr = NULL;
-    }
-    memp_free(MEMP_NETBUF, buf);
-  }
-}
-
-void *
-netbuf_alloc(struct netbuf *buf, u16_t size)
-{
-  /* Deallocate any previously allocated memory. */
-  if (buf->p != NULL) {
-    pbuf_free(buf->p);
-  }
-  buf->p = pbuf_alloc(PBUF_TRANSPORT, size, PBUF_RAM);
-  if (buf->p == NULL) {
-     return NULL;
-  }
-  buf->ptr = buf->p;
-  return buf->p->payload;
-}
-
-void
-netbuf_free(struct netbuf *buf)
-{
-  if (buf->p != NULL) {
-    pbuf_free(buf->p);
-  }
-  buf->p = buf->ptr = NULL;
-}
-
-void
-netbuf_ref(struct netbuf *buf, void *dataptr, u16_t size)
-{
-  if (buf->p != NULL) {
-    pbuf_free(buf->p);
-  }
-  buf->p = pbuf_alloc(PBUF_TRANSPORT, 0, PBUF_REF);
-  buf->p->payload = dataptr;
-  buf->p->len = buf->p->tot_len = size;
-  buf->ptr = buf->p;
-}
-
-void
-netbuf_chain(struct netbuf *head, struct netbuf *tail)
-{
-  pbuf_chain(head->p, tail->p);
-  head->ptr = head->p;
-  memp_free(MEMP_NETBUF, tail);
-}
-
-u16_t
-netbuf_len(struct netbuf *buf)
-{
-  return buf->p->tot_len;
-}
-
-err_t
-netbuf_data(struct netbuf *buf, void **dataptr, u16_t *len)
-{
-  if (buf->ptr == NULL) {
-    return ERR_BUF;
-  }
-  *dataptr = buf->ptr->payload;
-  *len = buf->ptr->len;
-  return ERR_OK;
-}
-
-s8_t
-netbuf_next(struct netbuf *buf)
-{
-  if (buf->ptr->next == NULL) {
-    return -1;
-  }
-  buf->ptr = buf->ptr->next;
-  if (buf->ptr->next == NULL) {
-    return 1;
-  }
-  return 0;
-}
-
-void
-netbuf_first(struct netbuf *buf)
-{
-  buf->ptr = buf->p;
-}
-
-void
-netbuf_copy_partial(struct netbuf *buf, void *dataptr, u16_t len, u16_t offset)
-{
-  struct pbuf *p;
-  u16_t i, left;
-
-  left = 0;
-
-  if(buf == NULL || dataptr == NULL) {
-    return;
-  }
-  
-  /* This implementation is bad. It should use bcopy
-     instead. */
-  for(p = buf->p; left < len && p != NULL; p = p->next) {
-    if (offset != 0 && offset >= p->len) {
-      offset -= p->len;
-    } else {    
-      for(i = offset; i < p->len; ++i) {
-  ((u8_t *)dataptr)[left] = ((u8_t *)p->payload)[i];
-  if (++left >= len) {
-    return;
-  }
-      }
-      offset = 0;
-    }
-  }
-}
-
-void
-netbuf_copy(struct netbuf *buf, void *dataptr, u16_t len)
-{
-  netbuf_copy_partial(buf, dataptr, len, 0);
-}
-
-struct ip_addr *
-netbuf_fromaddr(struct netbuf *buf)
-{
-  return buf->fromaddr;
-}
-
-u16_t
-netbuf_fromport(struct netbuf *buf)
-{
-  return buf->fromport;
-}
-
-struct
-netconn *netconn_new_with_proto_and_callback(enum netconn_type t, u16_t proto,
-                                   void (*callback)(struct netconn *, enum netconn_evt, u16_t len))
-{
-  struct netconn *conn;
-  struct api_msg *msg;
-
-  conn = memp_malloc(MEMP_NETCONN);
-  if (conn == NULL) {
-    return NULL;
-  }
-  
-  conn->err = ERR_OK;
-  conn->type = t;
-  conn->pcb.tcp = NULL;
-
-  if ((conn->mbox = sys_mbox_new()) == SYS_MBOX_NULL) {
-    memp_free(MEMP_NETCONN, conn);
-    return NULL;
-  }
-  conn->recvmbox = SYS_MBOX_NULL;
-  conn->acceptmbox = SYS_MBOX_NULL;
-  conn->sem = SYS_SEM_NULL;
-  conn->state = NETCONN_NONE;
-  conn->socket = 0;
-  conn->callback = callback;
-  conn->recv_avail = 0;
-
-  if((msg = memp_malloc(MEMP_API_MSG)) == NULL) {
-    memp_free(MEMP_NETCONN, conn);
-    return NULL;
-  }
-  
-  msg->type = API_MSG_NEWCONN;
-  msg->msg.msg.bc.port = proto; /* misusing the port field */
-  msg->msg.conn = conn;
-  api_msg_post(msg);  
-  sys_mbox_fetch(conn->mbox, NULL);
-  memp_free(MEMP_API_MSG, msg);
-
-  if ( conn->err != ERR_OK ) {
-    memp_free(MEMP_NETCONN, conn);
-    return NULL;
-  }
-
-  return conn;
-}
-
-
-struct
-netconn *netconn_new(enum netconn_type t)
-{
-  return netconn_new_with_proto_and_callback(t,0,NULL);
-}
-
-struct
-netconn *netconn_new_with_callback(enum netconn_type t,
-                                   void (*callback)(struct netconn *, enum netconn_evt, u16_t len))
-{
-  return netconn_new_with_proto_and_callback(t,0,callback);
-}
-
-
-err_t
-netconn_delete(struct netconn *conn)
-{
-  struct api_msg *msg;
-  void *mem;
-  
-  if (conn == NULL) {
-    return ERR_OK;
-  }
-  
-  if ((msg = memp_malloc(MEMP_API_MSG)) == NULL) {
-    return ERR_MEM;
-  }
-  
-  msg->type = API_MSG_DELCONN;
-  msg->msg.conn = conn;
-  api_msg_post(msg);  
-  sys_mbox_fetch(conn->mbox, NULL);
-  memp_free(MEMP_API_MSG, msg);
-
-  /* Drain the recvmbox. */
-  if (conn->recvmbox != SYS_MBOX_NULL) {
-    while (sys_arch_mbox_fetch(conn->recvmbox, &mem, 1) != SYS_ARCH_TIMEOUT) {
-      if (conn->type == NETCONN_TCP) {
-        if(mem != NULL)
-          pbuf_free((struct pbuf *)mem);
-      } else {
-        netbuf_delete((struct netbuf *)mem);
-      }
-    }
-    sys_mbox_free(conn->recvmbox);
-    conn->recvmbox = SYS_MBOX_NULL;
-  }
-
-  /* Drain the acceptmbox. */
-  if (conn->acceptmbox != SYS_MBOX_NULL) {
-    while (sys_arch_mbox_fetch(conn->acceptmbox, &mem, 1) != SYS_ARCH_TIMEOUT) {
-      netconn_delete((struct netconn *)mem);
-    }
-    
-    sys_mbox_free(conn->acceptmbox);
-    conn->acceptmbox = SYS_MBOX_NULL;
-  }
-
-  sys_mbox_free(conn->mbox);
-  conn->mbox = SYS_MBOX_NULL;
-  if (conn->sem != SYS_SEM_NULL) {
-    sys_sem_free(conn->sem);
-  }
-  /*  conn->sem = SYS_SEM_NULL;*/
-  memp_free(MEMP_NETCONN, conn);
-  return ERR_OK;
-}
-
-enum netconn_type
-netconn_type(struct netconn *conn)
-{
-  return conn->type;
-}
-
-err_t
-netconn_peer(struct netconn *conn, struct ip_addr *addr,
-       u16_t *port)
-{
-  switch (conn->type) {
-  case NETCONN_RAW:
-    /* return an error as connecting is only a helper for upper layers */
-    return ERR_CONN;
-  case NETCONN_UDPLITE:
-  case NETCONN_UDPNOCHKSUM:
-  case NETCONN_UDP:
-    if (conn->pcb.udp == NULL ||
-  ((conn->pcb.udp->flags & UDP_FLAGS_CONNECTED) == 0))
-     return ERR_CONN;
-    *addr = (conn->pcb.udp->remote_ip);
-    *port = conn->pcb.udp->remote_port;
-    break;
-  case NETCONN_TCP:
-    if (conn->pcb.tcp == NULL)
-      return ERR_CONN;
-    *addr = (conn->pcb.tcp->remote_ip);
-    *port = conn->pcb.tcp->remote_port;
-    break;
-  }
-  return (conn->err = ERR_OK);
-}
-
-err_t
-netconn_addr(struct netconn *conn, struct ip_addr **addr,
-       u16_t *port)
-{
-  switch (conn->type) {
-  case NETCONN_RAW:
-    *addr = &(conn->pcb.raw->local_ip);
-    *port = conn->pcb.raw->protocol;
-    break;
-  case NETCONN_UDPLITE:
-  case NETCONN_UDPNOCHKSUM:
-  case NETCONN_UDP:
-    *addr = &(conn->pcb.udp->local_ip);
-    *port = conn->pcb.udp->local_port;
-    break;
-  case NETCONN_TCP:
-    *addr = &(conn->pcb.tcp->local_ip);
-    *port = conn->pcb.tcp->local_port;
-    break;
-  }
-  return (conn->err = ERR_OK);
-}
-
-err_t
-netconn_bind(struct netconn *conn, struct ip_addr *addr,
-      u16_t port)
-{
-  struct api_msg *msg;
-
-  if (conn == NULL) {
-    return ERR_VAL;
-  }
-
-  if (conn->type != NETCONN_TCP &&
-     conn->recvmbox == SYS_MBOX_NULL) {
-    if ((conn->recvmbox = sys_mbox_new()) == SYS_MBOX_NULL) {
-      return ERR_MEM;
-    }
-  }
-  
-  if ((msg = memp_malloc(MEMP_API_MSG)) == NULL) {
-    return (conn->err = ERR_MEM);
-  }
-  msg->type = API_MSG_BIND;
-  msg->msg.conn = conn;
-  msg->msg.msg.bc.ipaddr = addr;
-  msg->msg.msg.bc.port = port;
-  api_msg_post(msg);
-  sys_mbox_fetch(conn->mbox, NULL);
-  memp_free(MEMP_API_MSG, msg);
-  return conn->err;
-}
-
-
-err_t
-netconn_connect(struct netconn *conn, struct ip_addr *addr,
-       u16_t port)
-{
-  struct api_msg *msg;
-  
-  if (conn == NULL) {
-    return ERR_VAL;
-  }
-
-
-  if (conn->recvmbox == SYS_MBOX_NULL) {
-    if ((conn->recvmbox = sys_mbox_new()) == SYS_MBOX_NULL) {
-      return ERR_MEM;
-    }
-  }
-  
-  if ((msg = memp_malloc(MEMP_API_MSG)) == NULL) {
-    return ERR_MEM;
-  }
-  msg->type = API_MSG_CONNECT;
-  msg->msg.conn = conn;  
-  msg->msg.msg.bc.ipaddr = addr;
-  msg->msg.msg.bc.port = port;
-  api_msg_post(msg);
-  sys_mbox_fetch(conn->mbox, NULL);
-  memp_free(MEMP_API_MSG, msg);
-  return conn->err;
-}
-
-err_t
-netconn_disconnect(struct netconn *conn)
-{
-  struct api_msg *msg;
-  
-  if (conn == NULL) {
-    return ERR_VAL;
-  }
-
-  if ((msg = memp_malloc(MEMP_API_MSG)) == NULL) {
-    return ERR_MEM;
-  }
-  msg->type = API_MSG_DISCONNECT;
-  msg->msg.conn = conn;  
-  api_msg_post(msg);
-  sys_mbox_fetch(conn->mbox, NULL);
-  memp_free(MEMP_API_MSG, msg);
-  return conn->err;
-
-}
-
-err_t
-netconn_listen(struct netconn *conn)
-{
-  struct api_msg *msg;
-
-  if (conn == NULL) {
-    return ERR_VAL;
-  }
-
-  if (conn->acceptmbox == SYS_MBOX_NULL) {
-    conn->acceptmbox = sys_mbox_new();
-    if (conn->acceptmbox == SYS_MBOX_NULL) {
-      return ERR_MEM;
-    }
-  }
-  
-  if ((msg = memp_malloc(MEMP_API_MSG)) == NULL) {
-    return (conn->err = ERR_MEM);
-  }
-  msg->type = API_MSG_LISTEN;
-  msg->msg.conn = conn;
-  api_msg_post(msg);
-  sys_mbox_fetch(conn->mbox, NULL);
-  memp_free(MEMP_API_MSG, msg);
-  return conn->err;
-}
-
-struct netconn *
-netconn_accept(struct netconn *conn)
-{
-  struct netconn *newconn;
-  
-  if (conn == NULL) {
-    return NULL;
-  }
-  
-  sys_mbox_fetch(conn->acceptmbox, (void **)&newconn);
-  /* Register event with callback */
-  if (conn->callback)
-      (*conn->callback)(conn, NETCONN_EVT_RCVMINUS, 0);
-  
-  return newconn;
-}
-
-struct netbuf *
-netconn_recv(struct netconn *conn)
-{
-  struct api_msg *msg;
-  struct netbuf *buf;
-  struct pbuf *p;
-  u16_t len;
-    
-  if (conn == NULL) {
-    return NULL;
-  }
-  
-  if (conn->recvmbox == SYS_MBOX_NULL) {
-    conn->err = ERR_CONN;
-    return NULL;
-  }
-
-  if (conn->err != ERR_OK) {
-    return NULL;
-  }
-
-  if (conn->type == NETCONN_TCP) {
-    if (conn->pcb.tcp->state == LISTEN) {
-      conn->err = ERR_CONN;
-      return NULL;
-    }
-
-
-    buf = memp_malloc(MEMP_NETBUF);
-
-    if (buf == NULL) {
-      conn->err = ERR_MEM;
-      return NULL;
-    }
-    
-    sys_mbox_fetch(conn->recvmbox, (void **)&p);
-
-    if (p != NULL)
-    {
-        len = p->tot_len;
-        conn->recv_avail -= len;
-    }
-    else
-        len = 0;
-    
-    /* Register event with callback */
-      if (conn->callback)
-        (*conn->callback)(conn, NETCONN_EVT_RCVMINUS, len);
-
-    /* If we are closed, we indicate that we no longer wish to receive
-       data by setting conn->recvmbox to SYS_MBOX_NULL. */
-    if (p == NULL) {
-      memp_free(MEMP_NETBUF, buf);
-      sys_mbox_free(conn->recvmbox);
-      conn->recvmbox = SYS_MBOX_NULL;
-      return NULL;
-    }
-
-    buf->p = p;
-    buf->ptr = p;
-    buf->fromport = 0;
-    buf->fromaddr = NULL;
-
-    /* Let the stack know that we have taken the data. */
-    if ((msg = memp_malloc(MEMP_API_MSG)) == NULL) {
-      conn->err = ERR_MEM;
-      return buf;
-    }
-    msg->type = API_MSG_RECV;
-    msg->msg.conn = conn;
-    if (buf != NULL) {
-      msg->msg.msg.len = buf->p->tot_len;
-    } else {
-      msg->msg.msg.len = 1;
-    }
-    api_msg_post(msg);
-
-    sys_mbox_fetch(conn->mbox, NULL);
-    memp_free(MEMP_API_MSG, msg);
-  } else {
-    sys_mbox_fetch(conn->recvmbox, (void **)&buf);
-  conn->recv_avail -= buf->p->tot_len;
-    /* Register event with callback */
-    if (conn->callback)
-        (*conn->callback)(conn, NETCONN_EVT_RCVMINUS, buf->p->tot_len);
-  }
-
-  
-
-    
-  LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_recv: received %p (err %d)\n", (void *)buf, conn->err));
-
-
-  return buf;
-}
-
-err_t
-netconn_send(struct netconn *conn, struct netbuf *buf)
-{
-  struct api_msg *msg;
-
-  if (conn == NULL) {
-    return ERR_VAL;
-  }
-
-  if (conn->err != ERR_OK) {
-    return conn->err;
-  }
-
-  if ((msg = memp_malloc(MEMP_API_MSG)) == NULL) {
-    return (conn->err = ERR_MEM);
-  }
-
-  LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_send: sending %d bytes\n", buf->p->tot_len));
-  msg->type = API_MSG_SEND;
-  msg->msg.conn = conn;
-  msg->msg.msg.p = buf->p;
-  api_msg_post(msg);
-
-  sys_mbox_fetch(conn->mbox, NULL);
-  memp_free(MEMP_API_MSG, msg);
-  return conn->err;
-}
-
-err_t
-netconn_write(struct netconn *conn, void *dataptr, u16_t size, u8_t copy)
-{
-  struct api_msg *msg;
-  u16_t len;
-  
-  if (conn == NULL) {
-    return ERR_VAL;
-  }
-
-  if (conn->err != ERR_OK) {
-    return conn->err;
-  }
-  
-  if (conn->sem == SYS_SEM_NULL) {
-    conn->sem = sys_sem_new(0);
-    if (conn->sem == SYS_SEM_NULL) {
-      return ERR_MEM;
-    }
-  }
-
-  if ((msg = memp_malloc(MEMP_API_MSG)) == NULL) {
-    return (conn->err = ERR_MEM);
-  }
-  msg->type = API_MSG_WRITE;
-  msg->msg.conn = conn;
-        
-
-  conn->state = NETCONN_WRITE;
-  while (conn->err == ERR_OK && size > 0) {
-    msg->msg.msg.w.dataptr = dataptr;
-    msg->msg.msg.w.copy = copy;
-    
-    if (conn->type == NETCONN_TCP) {
-      if (tcp_sndbuf(conn->pcb.tcp) == 0) {
-  sys_sem_wait(conn->sem);
-  if (conn->err != ERR_OK) {
-    goto ret;
-  }
-      }
-      if (size > tcp_sndbuf(conn->pcb.tcp)) {
-  /* We cannot send more than one send buffer's worth of data at a
-     time. */
-  len = tcp_sndbuf(conn->pcb.tcp);
-      } else {
-  len = size;
-      }
-    } else {
-      len = size;
-    }
-    
-    LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_write: writing %d bytes (%d)\n", len, copy));
-    msg->msg.msg.w.len = len;
-    api_msg_post(msg);
-    sys_mbox_fetch(conn->mbox, NULL);    
-    if (conn->err == ERR_OK) {
-      dataptr = (void *)((u8_t *)dataptr + len);
-      size -= len;
-    } else if (conn->err == ERR_MEM) {
-      conn->err = ERR_OK;
-      sys_sem_wait(conn->sem);
-    } else {
-      goto ret;
-    }
-  }
- ret:
-  memp_free(MEMP_API_MSG, msg);
-  conn->state = NETCONN_NONE;
-  if (conn->sem != SYS_SEM_NULL) {
-    sys_sem_free(conn->sem);
-    conn->sem = SYS_SEM_NULL;
-  }
-  
-  return conn->err;
-}
-
-err_t
-netconn_close(struct netconn *conn)
-{
-  struct api_msg *msg;
-
-  if (conn == NULL) {
-    return ERR_VAL;
-  }
-  if ((msg = memp_malloc(MEMP_API_MSG)) == NULL) {
-    return (conn->err = ERR_MEM);
-  }
-
-  conn->state = NETCONN_CLOSE;
- again:
-  msg->type = API_MSG_CLOSE;
-  msg->msg.conn = conn;
-  api_msg_post(msg);
-  sys_mbox_fetch(conn->mbox, NULL);
-  if (conn->err == ERR_MEM &&
-     conn->sem != SYS_SEM_NULL) {
-    sys_sem_wait(conn->sem);
-    goto again;
-  }
-  conn->state = NETCONN_NONE;
-  memp_free(MEMP_API_MSG, msg);
-  return conn->err;
-}
-
-err_t
-netconn_err(struct netconn *conn)
-{
-  return conn->err;
-}
-
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+\r
+/* This is the part of the API that is linked with\r
+   the application */\r
+\r
+#include "lwip/opt.h"\r
+#include "lwip/api.h"\r
+#include "lwip/api_msg.h"\r
+#include "lwip/memp.h"\r
+\r
+\r
+struct\r
+netbuf *netbuf_new(void)\r
+{\r
+  struct netbuf *buf;\r
+\r
+  buf = memp_malloc(MEMP_NETBUF);\r
+  if (buf != NULL) {\r
+    buf->p = NULL;\r
+    buf->ptr = NULL;\r
+    return buf;\r
+  } else {\r
+    return NULL;\r
+  }\r
+}\r
+\r
+void\r
+netbuf_delete(struct netbuf *buf)\r
+{\r
+  if (buf != NULL) {\r
+    if (buf->p != NULL) {\r
+      pbuf_free(buf->p);\r
+      buf->p = buf->ptr = NULL;\r
+    }\r
+    memp_free(MEMP_NETBUF, buf);\r
+  }\r
+}\r
+\r
+void *\r
+netbuf_alloc(struct netbuf *buf, u16_t size)\r
+{\r
+  /* Deallocate any previously allocated memory. */\r
+  if (buf->p != NULL) {\r
+    pbuf_free(buf->p);\r
+  }\r
+  buf->p = pbuf_alloc(PBUF_TRANSPORT, size, PBUF_RAM);\r
+  if (buf->p == NULL) {\r
+     return NULL;\r
+  }\r
+  buf->ptr = buf->p;\r
+  return buf->p->payload;\r
+}\r
+\r
+void\r
+netbuf_free(struct netbuf *buf)\r
+{\r
+  if (buf->p != NULL) {\r
+    pbuf_free(buf->p);\r
+  }\r
+  buf->p = buf->ptr = NULL;\r
+}\r
+\r
+void\r
+netbuf_ref(struct netbuf *buf, void *dataptr, u16_t size)\r
+{\r
+  if (buf->p != NULL) {\r
+    pbuf_free(buf->p);\r
+  }\r
+  buf->p = pbuf_alloc(PBUF_TRANSPORT, 0, PBUF_REF);\r
+  buf->p->payload = dataptr;\r
+  buf->p->len = buf->p->tot_len = size;\r
+  buf->ptr = buf->p;\r
+}\r
+\r
+void\r
+netbuf_chain(struct netbuf *head, struct netbuf *tail)\r
+{\r
+  pbuf_chain(head->p, tail->p);\r
+  head->ptr = head->p;\r
+  memp_free(MEMP_NETBUF, tail);\r
+}\r
+\r
+u16_t\r
+netbuf_len(struct netbuf *buf)\r
+{\r
+  return buf->p->tot_len;\r
+}\r
+\r
+err_t\r
+netbuf_data(struct netbuf *buf, void **dataptr, u16_t *len)\r
+{\r
+  if (buf->ptr == NULL) {\r
+    return ERR_BUF;\r
+  }\r
+  *dataptr = buf->ptr->payload;\r
+  *len = buf->ptr->len;\r
+  return ERR_OK;\r
+}\r
+\r
+s8_t\r
+netbuf_next(struct netbuf *buf)\r
+{\r
+  if (buf->ptr->next == NULL) {\r
+    return -1;\r
+  }\r
+  buf->ptr = buf->ptr->next;\r
+  if (buf->ptr->next == NULL) {\r
+    return 1;\r
+  }\r
+  return 0;\r
+}\r
+\r
+void\r
+netbuf_first(struct netbuf *buf)\r
+{\r
+  buf->ptr = buf->p;\r
+}\r
+\r
+void\r
+netbuf_copy_partial(struct netbuf *buf, void *dataptr, u16_t len, u16_t offset)\r
+{\r
+  struct pbuf *p;\r
+  u16_t i, left;\r
+\r
+  left = 0;\r
+\r
+  if(buf == NULL || dataptr == NULL) {\r
+    return;\r
+  }\r
+  \r
+  /* This implementation is bad. It should use bcopy\r
+     instead. */\r
+  for(p = buf->p; left < len && p != NULL; p = p->next) {\r
+    if (offset != 0 && offset >= p->len) {\r
+      offset -= p->len;\r
+    } else {    \r
+      for(i = offset; i < p->len; ++i) {\r
+  ((u8_t *)dataptr)[left] = ((u8_t *)p->payload)[i];\r
+  if (++left >= len) {\r
+    return;\r
+  }\r
+      }\r
+      offset = 0;\r
+    }\r
+  }\r
+}\r
+\r
+void\r
+netbuf_copy(struct netbuf *buf, void *dataptr, u16_t len)\r
+{\r
+  netbuf_copy_partial(buf, dataptr, len, 0);\r
+}\r
+\r
+struct ip_addr *\r
+netbuf_fromaddr(struct netbuf *buf)\r
+{\r
+  return buf->fromaddr;\r
+}\r
+\r
+u16_t\r
+netbuf_fromport(struct netbuf *buf)\r
+{\r
+  return buf->fromport;\r
+}\r
+\r
+struct\r
+netconn *netconn_new_with_proto_and_callback(enum netconn_type t, u16_t proto,\r
+                                   void (*callback)(struct netconn *, enum netconn_evt, u16_t len))\r
+{\r
+  struct netconn *conn;\r
+  struct api_msg *msg;\r
+\r
+  conn = memp_malloc(MEMP_NETCONN);\r
+  if (conn == NULL) {\r
+    return NULL;\r
+  }\r
+  \r
+  conn->err = ERR_OK;\r
+  conn->type = t;\r
+  conn->pcb.tcp = NULL;\r
+\r
+  if ((conn->mbox = sys_mbox_new()) == SYS_MBOX_NULL) {\r
+    memp_free(MEMP_NETCONN, conn);\r
+    return NULL;\r
+  }\r
+  conn->recvmbox = SYS_MBOX_NULL;\r
+  conn->acceptmbox = SYS_MBOX_NULL;\r
+  conn->sem = SYS_SEM_NULL;\r
+  conn->state = NETCONN_NONE;\r
+  conn->socket = 0;\r
+  conn->callback = callback;\r
+  conn->recv_avail = 0;\r
+\r
+  if((msg = memp_malloc(MEMP_API_MSG)) == NULL) {\r
+    memp_free(MEMP_NETCONN, conn);\r
+    return NULL;\r
+  }\r
+  \r
+  msg->type = API_MSG_NEWCONN;\r
+  msg->msg.msg.bc.port = proto; /* misusing the port field */\r
+  msg->msg.conn = conn;\r
+  api_msg_post(msg);  \r
+  sys_mbox_fetch(conn->mbox, NULL);\r
+  memp_free(MEMP_API_MSG, msg);\r
+\r
+  if ( conn->err != ERR_OK ) {\r
+    memp_free(MEMP_NETCONN, conn);\r
+    return NULL;\r
+  }\r
+\r
+  return conn;\r
+}\r
+\r
+\r
+struct\r
+netconn *netconn_new(enum netconn_type t)\r
+{\r
+  return netconn_new_with_proto_and_callback(t,0,NULL);\r
+}\r
+\r
+struct\r
+netconn *netconn_new_with_callback(enum netconn_type t,\r
+                                   void (*callback)(struct netconn *, enum netconn_evt, u16_t len))\r
+{\r
+  return netconn_new_with_proto_and_callback(t,0,callback);\r
+}\r
+\r
+\r
+err_t\r
+netconn_delete(struct netconn *conn)\r
+{\r
+  struct api_msg *msg;\r
+  void *mem;\r
+  \r
+  if (conn == NULL) {\r
+    return ERR_OK;\r
+  }\r
+  \r
+  if ((msg = memp_malloc(MEMP_API_MSG)) == NULL) {\r
+    return ERR_MEM;\r
+  }\r
+  \r
+  msg->type = API_MSG_DELCONN;\r
+  msg->msg.conn = conn;\r
+  api_msg_post(msg);  \r
+  sys_mbox_fetch(conn->mbox, NULL);\r
+  memp_free(MEMP_API_MSG, msg);\r
+\r
+  /* Drain the recvmbox. */\r
+  if (conn->recvmbox != SYS_MBOX_NULL) {\r
+    while (sys_arch_mbox_fetch(conn->recvmbox, &mem, 1) != SYS_ARCH_TIMEOUT) {\r
+      if (conn->type == NETCONN_TCP) {\r
+        if(mem != NULL)\r
+          pbuf_free((struct pbuf *)mem);\r
+      } else {\r
+        netbuf_delete((struct netbuf *)mem);\r
+      }\r
+    }\r
+    sys_mbox_free(conn->recvmbox);\r
+    conn->recvmbox = SYS_MBOX_NULL;\r
+  }\r
\r
+\r
+  /* Drain the acceptmbox. */\r
+  if (conn->acceptmbox != SYS_MBOX_NULL) {\r
+    while (sys_arch_mbox_fetch(conn->acceptmbox, &mem, 1) != SYS_ARCH_TIMEOUT) {\r
+      netconn_delete((struct netconn *)mem);\r
+    }\r
+    \r
+    sys_mbox_free(conn->acceptmbox);\r
+    conn->acceptmbox = SYS_MBOX_NULL;\r
+  }\r
+\r
+  sys_mbox_free(conn->mbox);\r
+  conn->mbox = SYS_MBOX_NULL;\r
+  if (conn->sem != SYS_SEM_NULL) {\r
+    sys_sem_free(conn->sem);\r
+  }\r
+  /*  conn->sem = SYS_SEM_NULL;*/\r
+  memp_free(MEMP_NETCONN, conn);\r
+  return ERR_OK;\r
+}\r
+\r
+enum netconn_type\r
+netconn_type(struct netconn *conn)\r
+{\r
+  return conn->type;\r
+}\r
+\r
+err_t\r
+netconn_peer(struct netconn *conn, struct ip_addr *addr,\r
+       u16_t *port)\r
+{\r
+  switch (conn->type) {\r
+  case NETCONN_RAW:\r
+    /* return an error as connecting is only a helper for upper layers */\r
+    return ERR_CONN;\r
+  case NETCONN_UDPLITE:\r
+  case NETCONN_UDPNOCHKSUM:\r
+  case NETCONN_UDP:\r
+    if (conn->pcb.udp == NULL ||\r
+  ((conn->pcb.udp->flags & UDP_FLAGS_CONNECTED) == 0))\r
+     return ERR_CONN;\r
+    *addr = (conn->pcb.udp->remote_ip);\r
+    *port = conn->pcb.udp->remote_port;\r
+    break;\r
+  case NETCONN_TCP:\r
+    if (conn->pcb.tcp == NULL)\r
+      return ERR_CONN;\r
+    *addr = (conn->pcb.tcp->remote_ip);\r
+    *port = conn->pcb.tcp->remote_port;\r
+    break;\r
+  }\r
+  return (conn->err = ERR_OK);\r
+}\r
+\r
+err_t\r
+netconn_addr(struct netconn *conn, struct ip_addr **addr,\r
+       u16_t *port)\r
+{\r
+  switch (conn->type) {\r
+  case NETCONN_RAW:\r
+    *addr = &(conn->pcb.raw->local_ip);\r
+    *port = conn->pcb.raw->protocol;\r
+    break;\r
+  case NETCONN_UDPLITE:\r
+  case NETCONN_UDPNOCHKSUM:\r
+  case NETCONN_UDP:\r
+    *addr = &(conn->pcb.udp->local_ip);\r
+    *port = conn->pcb.udp->local_port;\r
+    break;\r
+  case NETCONN_TCP:\r
+    *addr = &(conn->pcb.tcp->local_ip);\r
+    *port = conn->pcb.tcp->local_port;\r
+    break;\r
+  }\r
+  return (conn->err = ERR_OK);\r
+}\r
+\r
+err_t\r
+netconn_bind(struct netconn *conn, struct ip_addr *addr,\r
+      u16_t port)\r
+{\r
+  struct api_msg *msg;\r
+\r
+  if (conn == NULL) {\r
+    return ERR_VAL;\r
+  }\r
+\r
+  if (conn->type != NETCONN_TCP &&\r
+     conn->recvmbox == SYS_MBOX_NULL) {\r
+    if ((conn->recvmbox = sys_mbox_new()) == SYS_MBOX_NULL) {\r
+      return ERR_MEM;\r
+    }\r
+  }\r
+  \r
+  if ((msg = memp_malloc(MEMP_API_MSG)) == NULL) {\r
+    return (conn->err = ERR_MEM);\r
+  }\r
+  msg->type = API_MSG_BIND;\r
+  msg->msg.conn = conn;\r
+  msg->msg.msg.bc.ipaddr = addr;\r
+  msg->msg.msg.bc.port = port;\r
+  api_msg_post(msg);\r
+  sys_mbox_fetch(conn->mbox, NULL);\r
+  memp_free(MEMP_API_MSG, msg);\r
+  return conn->err;\r
+}\r
+\r
+\r
+err_t\r
+netconn_connect(struct netconn *conn, struct ip_addr *addr,\r
+       u16_t port)\r
+{\r
+  struct api_msg *msg;\r
+  \r
+  if (conn == NULL) {\r
+    return ERR_VAL;\r
+  }\r
+\r
+\r
+  if (conn->recvmbox == SYS_MBOX_NULL) {\r
+    if ((conn->recvmbox = sys_mbox_new()) == SYS_MBOX_NULL) {\r
+      return ERR_MEM;\r
+    }\r
+  }\r
+  \r
+  if ((msg = memp_malloc(MEMP_API_MSG)) == NULL) {\r
+    return ERR_MEM;\r
+  }\r
+  msg->type = API_MSG_CONNECT;\r
+  msg->msg.conn = conn;  \r
+  msg->msg.msg.bc.ipaddr = addr;\r
+  msg->msg.msg.bc.port = port;\r
+  api_msg_post(msg);\r
+  sys_mbox_fetch(conn->mbox, NULL);\r
+  memp_free(MEMP_API_MSG, msg);\r
+  return conn->err;\r
+}\r
+\r
+err_t\r
+netconn_disconnect(struct netconn *conn)\r
+{\r
+  struct api_msg *msg;\r
+  \r
+  if (conn == NULL) {\r
+    return ERR_VAL;\r
+  }\r
+\r
+  if ((msg = memp_malloc(MEMP_API_MSG)) == NULL) {\r
+    return ERR_MEM;\r
+  }\r
+  msg->type = API_MSG_DISCONNECT;\r
+  msg->msg.conn = conn;  \r
+  api_msg_post(msg);\r
+  sys_mbox_fetch(conn->mbox, NULL);\r
+  memp_free(MEMP_API_MSG, msg);\r
+  return conn->err;\r
+\r
+}\r
+\r
+err_t\r
+netconn_listen(struct netconn *conn)\r
+{\r
+  struct api_msg *msg;\r
+\r
+  if (conn == NULL) {\r
+    return ERR_VAL;\r
+  }\r
+\r
+  if (conn->acceptmbox == SYS_MBOX_NULL) {\r
+    conn->acceptmbox = sys_mbox_new();\r
+    if (conn->acceptmbox == SYS_MBOX_NULL) {\r
+      return ERR_MEM;\r
+    }\r
+  }\r
+  \r
+  if ((msg = memp_malloc(MEMP_API_MSG)) == NULL) {\r
+    return (conn->err = ERR_MEM);\r
+  }\r
+  msg->type = API_MSG_LISTEN;\r
+  msg->msg.conn = conn;\r
+  api_msg_post(msg);\r
+  sys_mbox_fetch(conn->mbox, NULL);\r
+  memp_free(MEMP_API_MSG, msg);\r
+  return conn->err;\r
+}\r
+\r
+struct netconn *\r
+netconn_accept(struct netconn *conn)\r
+{\r
+  struct netconn *newconn;\r
+  \r
+  if (conn == NULL) {\r
+    return NULL;\r
+  }\r
+  \r
+  sys_mbox_fetch(conn->acceptmbox, (void **)&newconn);\r
+  /* Register event with callback */\r
+  if (conn->callback)\r
+      (*conn->callback)(conn, NETCONN_EVT_RCVMINUS, 0);\r
+  \r
+  return newconn;\r
+}\r
+\r
+struct netbuf *\r
+netconn_recv(struct netconn *conn)\r
+{\r
+  struct api_msg *msg;\r
+  struct netbuf *buf;\r
+  struct pbuf *p;\r
+  u16_t len;\r
+    \r
+  if (conn == NULL) {\r
+    return NULL;\r
+  }\r
+  \r
+  if (conn->recvmbox == SYS_MBOX_NULL) {\r
+    conn->err = ERR_CONN;\r
+    return NULL;\r
+  }\r
+\r
+  if (conn->err != ERR_OK) {\r
+    return NULL;\r
+  }\r
+\r
+  if (conn->type == NETCONN_TCP) {\r
+    if (conn->pcb.tcp->state == LISTEN) {\r
+      conn->err = ERR_CONN;\r
+      return NULL;\r
+    }\r
+\r
+\r
+    buf = memp_malloc(MEMP_NETBUF);\r
+\r
+    if (buf == NULL) {\r
+      conn->err = ERR_MEM;\r
+      return NULL;\r
+    }\r
+    \r
+    sys_mbox_fetch(conn->recvmbox, (void **)&p);\r
+\r
+    if (p != NULL)\r
+    {\r
+        len = p->tot_len;\r
+        conn->recv_avail -= len;\r
+    }\r
+    else\r
+        len = 0;\r
+    \r
+    /* Register event with callback */\r
+      if (conn->callback)\r
+        (*conn->callback)(conn, NETCONN_EVT_RCVMINUS, len);\r
+\r
+    /* If we are closed, we indicate that we no longer wish to receive\r
+       data by setting conn->recvmbox to SYS_MBOX_NULL. */\r
+    if (p == NULL) {\r
+      memp_free(MEMP_NETBUF, buf);\r
+      sys_mbox_free(conn->recvmbox);\r
+      conn->recvmbox = SYS_MBOX_NULL;\r
+      return NULL;\r
+    }\r
+\r
+    buf->p = p;\r
+    buf->ptr = p;\r
+    buf->fromport = 0;\r
+    buf->fromaddr = NULL;\r
+\r
+    /* Let the stack know that we have taken the data. */\r
+    if ((msg = memp_malloc(MEMP_API_MSG)) == NULL) {\r
+      conn->err = ERR_MEM;\r
+      return buf;\r
+    }\r
+    msg->type = API_MSG_RECV;\r
+    msg->msg.conn = conn;\r
+    if (buf != NULL) {\r
+      msg->msg.msg.len = buf->p->tot_len;\r
+    } else {\r
+      msg->msg.msg.len = 1;\r
+    }\r
+    api_msg_post(msg);\r
+\r
+    sys_mbox_fetch(conn->mbox, NULL);\r
+    memp_free(MEMP_API_MSG, msg);\r
+  } else {\r
+    sys_mbox_fetch(conn->recvmbox, (void **)&buf);\r
+  conn->recv_avail -= buf->p->tot_len;\r
+    /* Register event with callback */\r
+    if (conn->callback)\r
+        (*conn->callback)(conn, NETCONN_EVT_RCVMINUS, buf->p->tot_len);\r
+  }\r
+\r
+  \r
+\r
+    \r
+  LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_recv: received %p (err %d)\n", (void *)buf, conn->err));\r
+\r
+\r
+  return buf;\r
+}\r
+\r
+err_t\r
+netconn_send(struct netconn *conn, struct netbuf *buf)\r
+{\r
+  struct api_msg *msg;\r
+\r
+  if (conn == NULL) {\r
+    return ERR_VAL;\r
+  }\r
+\r
+  if (conn->err != ERR_OK) {\r
+    return conn->err;\r
+  }\r
+\r
+  if ((msg = memp_malloc(MEMP_API_MSG)) == NULL) {\r
+    return (conn->err = ERR_MEM);\r
+  }\r
+\r
+  LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_send: sending %d bytes\n", buf->p->tot_len));\r
+  msg->type = API_MSG_SEND;\r
+  msg->msg.conn = conn;\r
+  msg->msg.msg.p = buf->p;\r
+  api_msg_post(msg);\r
+\r
+  sys_mbox_fetch(conn->mbox, NULL);\r
+  memp_free(MEMP_API_MSG, msg);\r
+  return conn->err;\r
+}\r
+\r
+err_t\r
+netconn_write(struct netconn *conn, void *dataptr, u16_t size, u8_t copy)\r
+{\r
+  struct api_msg *msg;\r
+  u16_t len;\r
+  \r
+  if (conn == NULL) {\r
+    return ERR_VAL;\r
+  }\r
+\r
+  if (conn->err != ERR_OK) {\r
+    return conn->err;\r
+  }\r
+  \r
+  if (conn->sem == SYS_SEM_NULL) {\r
+    conn->sem = sys_sem_new(0);\r
+    if (conn->sem == SYS_SEM_NULL) {\r
+      return ERR_MEM;\r
+    }\r
+  }\r
+\r
+  if ((msg = memp_malloc(MEMP_API_MSG)) == NULL) {\r
+    return (conn->err = ERR_MEM);\r
+  }\r
+  msg->type = API_MSG_WRITE;\r
+  msg->msg.conn = conn;\r
+        \r
+\r
+  conn->state = NETCONN_WRITE;\r
+  while (conn->err == ERR_OK && size > 0) {\r
+    msg->msg.msg.w.dataptr = dataptr;\r
+    msg->msg.msg.w.copy = copy;\r
+    \r
+    if (conn->type == NETCONN_TCP) {\r
+      if (tcp_sndbuf(conn->pcb.tcp) == 0) {\r
+  sys_sem_wait(conn->sem);\r
+  if (conn->err != ERR_OK) {\r
+    goto ret;\r
+  }\r
+      }\r
+      if (size > tcp_sndbuf(conn->pcb.tcp)) {\r
+  /* We cannot send more than one send buffer's worth of data at a\r
+     time. */\r
+  len = tcp_sndbuf(conn->pcb.tcp);\r
+      } else {\r
+  len = size;\r
+      }\r
+    } else {\r
+      len = size;\r
+    }\r
+    \r
+    LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_write: writing %d bytes (%d)\n", len, copy));\r
+    msg->msg.msg.w.len = len;\r
+    api_msg_post(msg);\r
+    sys_mbox_fetch(conn->mbox, NULL);    \r
+    if (conn->err == ERR_OK) {\r
+      dataptr = (void *)((u8_t *)dataptr + len);\r
+      size -= len;\r
+    } else if (conn->err == ERR_MEM) {\r
+      conn->err = ERR_OK;\r
+      sys_sem_wait(conn->sem);\r
+    } else {\r
+      goto ret;\r
+    }\r
+  }\r
+ ret:\r
+  memp_free(MEMP_API_MSG, msg);\r
+  conn->state = NETCONN_NONE;\r
+  if (conn->sem != SYS_SEM_NULL) {\r
+    sys_sem_free(conn->sem);\r
+    conn->sem = SYS_SEM_NULL;\r
+  }\r
+  \r
+  return conn->err;\r
+}\r
+\r
+err_t\r
+netconn_close(struct netconn *conn)\r
+{\r
+  struct api_msg *msg;\r
+\r
+  if (conn == NULL) {\r
+    return ERR_VAL;\r
+  }\r
+  if ((msg = memp_malloc(MEMP_API_MSG)) == NULL) {\r
+    return (conn->err = ERR_MEM);\r
+  }\r
+\r
+  conn->state = NETCONN_CLOSE;\r
+ again:\r
+  msg->type = API_MSG_CLOSE;\r
+  msg->msg.conn = conn;\r
+  api_msg_post(msg);\r
+  sys_mbox_fetch(conn->mbox, NULL);\r
+  if (conn->err == ERR_MEM &&\r
+     conn->sem != SYS_SEM_NULL) {\r
+    sys_sem_wait(conn->sem);\r
+    goto again;\r
+  }\r
+  conn->state = NETCONN_NONE;\r
+  memp_free(MEMP_API_MSG, msg);\r
+  return conn->err;\r
+}\r
+\r
+err_t\r
+netconn_err(struct netconn *conn)\r
+{\r
+  return conn->err;\r
+}\r
+\r
index 0cbe626fb5237ccad90891676848aa8523487851..9b9bf9c91984eeb67eb859bf62a0b107b881a8d7 100644 (file)
-/*
- * 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 <adam@sics.se>
- *
- */
-
-#include "lwip/opt.h"
-#include "lwip/arch.h"
-#include "lwip/api_msg.h"
-#include "lwip/memp.h"
-#include "lwip/sys.h"
-#include "lwip/tcpip.h"
-
-#if LWIP_RAW
-static u8_t
-recv_raw(void *arg, struct raw_pcb *pcb, struct pbuf *p,
-    struct ip_addr *addr)
-{
-  struct netbuf *buf;
-  struct netconn *conn;
-
-  conn = arg;
-  if (!conn) return 0;
-
-  if (conn->recvmbox != SYS_MBOX_NULL) {
-    if (!(buf = memp_malloc(MEMP_NETBUF))) {
-      return 0;
-    }
-    pbuf_ref(p);
-    buf->p = p;
-    buf->ptr = p;
-    buf->fromaddr = addr;
-    buf->fromport = pcb->protocol;
-
-    conn->recv_avail += p->tot_len;
-    /* Register event with callback */
-    if (conn->callback)
-        (*conn->callback)(conn, NETCONN_EVT_RCVPLUS, p->tot_len);
-    sys_mbox_post(conn->recvmbox, buf);
-  }
-
-  return 0; /* do not eat the packet */
-}
-#endif
-#if LWIP_UDP
-static void
-recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p,
-   struct ip_addr *addr, u16_t port)
-{
-  struct netbuf *buf;
-  struct netconn *conn;
-
-  conn = arg;
-  
-  if (conn == NULL) {
-    pbuf_free(p);
-    return;
-  }
-  if (conn->recvmbox != SYS_MBOX_NULL) {
-    buf = memp_malloc(MEMP_NETBUF);
-    if (buf == NULL) {
-      pbuf_free(p);
-      return;
-    } else {
-      buf->p = p;
-      buf->ptr = p;
-      buf->fromaddr = addr;
-      buf->fromport = port;
-    }
-
-  conn->recv_avail += p->tot_len;
-    /* Register event with callback */
-    if (conn->callback)
-        (*conn->callback)(conn, NETCONN_EVT_RCVPLUS, p->tot_len);
-    sys_mbox_post(conn->recvmbox, buf);
-  }
-}
-#endif /* LWIP_UDP */
-#if LWIP_TCP
-
-static err_t
-recv_tcp(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
-{
-  struct netconn *conn;
-  u16_t len;
-  
-  conn = arg;
-
-  if (conn == NULL) {
-    pbuf_free(p);
-    return ERR_VAL;
-  }
-
-  if (conn->recvmbox != SYS_MBOX_NULL) {
-        
-    conn->err = err;
-    if (p != NULL) {
-        len = p->tot_len;
-        conn->recv_avail += len;
-    }
-    else
-        len = 0;
-    /* Register event with callback */
-    if (conn->callback)
-        (*conn->callback)(conn, NETCONN_EVT_RCVPLUS, len);
-    sys_mbox_post(conn->recvmbox, p);
-  }  
-  return ERR_OK;
-}
-
-
-static err_t
-poll_tcp(void *arg, struct tcp_pcb *pcb)
-{
-  struct netconn *conn;
-
-  conn = arg;
-  if (conn != NULL &&
-     (conn->state == NETCONN_WRITE || conn->state == NETCONN_CLOSE) &&
-     conn->sem != SYS_SEM_NULL) {
-    sys_sem_signal(conn->sem);
-  }
-  return ERR_OK;
-}
-
-static err_t
-sent_tcp(void *arg, struct tcp_pcb *pcb, u16_t len)
-{
-  struct netconn *conn;
-
-  conn = arg;
-  if (conn != NULL && conn->sem != SYS_SEM_NULL) {
-    sys_sem_signal(conn->sem);
-  }
-
-  if (conn && conn->callback)
-      if (tcp_sndbuf(conn->pcb.tcp) > TCP_SNDLOWAT)
-          (*conn->callback)(conn, NETCONN_EVT_SENDPLUS, len);
-  
-  return ERR_OK;
-}
-
-static void
-err_tcp(void *arg, err_t err)
-{
-  struct netconn *conn;
-
-  conn = arg;
-
-  conn->pcb.tcp = NULL;
-
-  
-  conn->err = err;
-  if (conn->recvmbox != SYS_MBOX_NULL) {
-    /* Register event with callback */
-    if (conn->callback)
-      (*conn->callback)(conn, NETCONN_EVT_RCVPLUS, 0);
-    sys_mbox_post(conn->recvmbox, NULL);
-  }
-  if (conn->mbox != SYS_MBOX_NULL) {
-    sys_mbox_post(conn->mbox, NULL);
-  }
-  if (conn->acceptmbox != SYS_MBOX_NULL) {
-     /* Register event with callback */
-    if (conn->callback)
-      (*conn->callback)(conn, NETCONN_EVT_RCVPLUS, 0);
-    sys_mbox_post(conn->acceptmbox, NULL);
-  }
-  if (conn->sem != SYS_SEM_NULL) {
-    sys_sem_signal(conn->sem);
-  }
-}
-
-static void
-setup_tcp(struct netconn *conn)
-{
-  struct tcp_pcb *pcb;
-  
-  pcb = conn->pcb.tcp;
-  tcp_arg(pcb, conn);
-  tcp_recv(pcb, recv_tcp);
-  tcp_sent(pcb, sent_tcp);
-  tcp_poll(pcb, poll_tcp, 4);
-  tcp_err(pcb, err_tcp);
-}
-
-static err_t
-accept_function(void *arg, struct tcp_pcb *newpcb, err_t err)
-{
-  sys_mbox_t mbox;
-  struct netconn *newconn;
-  struct netconn *conn;
-  
-#if API_MSG_DEBUG
-#if TCP_DEBUG
-  tcp_debug_print_state(newpcb->state);
-#endif /* TCP_DEBUG */
-#endif /* API_MSG_DEBUG */
-  conn = (struct netconn *)arg;
-  mbox = conn->acceptmbox;
-  newconn = memp_malloc(MEMP_NETCONN);
-  if (newconn == NULL) {
-    return ERR_MEM;
-  }
-  newconn->type = NETCONN_TCP;
-  newconn->pcb.tcp = newpcb;
-  setup_tcp(newconn);
-  newconn->recvmbox = sys_mbox_new();
-  if (newconn->recvmbox == SYS_MBOX_NULL) {
-    memp_free(MEMP_NETCONN, newconn);
-    return ERR_MEM;
-  }
-  newconn->mbox = sys_mbox_new();
-  if (newconn->mbox == SYS_MBOX_NULL) {
-    sys_mbox_free(newconn->recvmbox);
-    memp_free(MEMP_NETCONN, newconn);
-    return ERR_MEM;
-  }
-  newconn->sem = sys_sem_new(0);
-  if (newconn->sem == SYS_SEM_NULL) {
-    sys_mbox_free(newconn->recvmbox);
-    sys_mbox_free(newconn->mbox);
-    memp_free(MEMP_NETCONN, newconn);
-    return ERR_MEM;
-  }
-  newconn->acceptmbox = SYS_MBOX_NULL;
-  newconn->err = err;
-  /* Register event with callback */
-  if (conn->callback)
-  {
-    (*conn->callback)(conn, NETCONN_EVT_RCVPLUS, 0);
-    /* We have to set the callback here even though
-     * the new socket is unknown. Mark the socket as -1. */
-    newconn->callback = conn->callback;
-    newconn->socket = -1;
-  }
-  
-  sys_mbox_post(mbox, newconn);
-  return ERR_OK;
-}
-#endif /* LWIP_TCP */
-
-static void
-do_newconn(struct api_msg_msg *msg)
-{
-   if(msg->conn->pcb.tcp != NULL) {
-   /* This "new" connection already has a PCB allocated. */
-   /* Is this an error condition? Should it be deleted? 
-      We currently just are happy and return. */
-     sys_mbox_post(msg->conn->mbox, NULL);
-     return;
-   }
-
-   msg->conn->err = ERR_OK;
-
-   /* Allocate a PCB for this connection */
-   switch(msg->conn->type) {
-#if LWIP_RAW
-   case NETCONN_RAW:
-      msg->conn->pcb.raw = raw_new(msg->msg.bc.port); /* misusing the port field */
-      raw_recv(msg->conn->pcb.raw, recv_raw, msg->conn);
-     break;
-#endif
-#if LWIP_UDP
-   case NETCONN_UDPLITE:
-      msg->conn->pcb.udp = udp_new();
-      if(msg->conn->pcb.udp == NULL) {
-         msg->conn->err = ERR_MEM;
-         break;
-      }
-      udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_UDPLITE);
-      udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);
-      break;
-   case NETCONN_UDPNOCHKSUM:
-      msg->conn->pcb.udp = udp_new();
-      if(msg->conn->pcb.udp == NULL) {
-         msg->conn->err = ERR_MEM;
-         break;
-      }
-      udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_NOCHKSUM);
-      udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);
-      break;
-   case NETCONN_UDP:
-      msg->conn->pcb.udp = udp_new();
-      if(msg->conn->pcb.udp == NULL) {
-         msg->conn->err = ERR_MEM;
-         break;
-      }
-      udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);
-      break;
-#endif /* LWIP_UDP */
-#if LWIP_TCP
-   case NETCONN_TCP:
-      msg->conn->pcb.tcp = tcp_new();
-      if(msg->conn->pcb.tcp == NULL) {
-         msg->conn->err = ERR_MEM;
-         break;
-      }
-      setup_tcp(msg->conn);
-      break;
-#endif
-   }
-   
-  
-  sys_mbox_post(msg->conn->mbox, NULL);
-}
-
-
-static void
-do_delconn(struct api_msg_msg *msg)
-{
-  if (msg->conn->pcb.tcp != NULL) {
-    switch (msg->conn->type) {
-#if LWIP_RAW
-    case NETCONN_RAW:
-      raw_remove(msg->conn->pcb.raw);
-      break;
-#endif
-#if LWIP_UDP
-    case NETCONN_UDPLITE:
-      /* FALLTHROUGH */
-    case NETCONN_UDPNOCHKSUM:
-      /* FALLTHROUGH */
-    case NETCONN_UDP:
-      msg->conn->pcb.udp->recv_arg = NULL;
-      udp_remove(msg->conn->pcb.udp);
-      break;
-#endif /* LWIP_UDP */
-#if LWIP_TCP      
-    case NETCONN_TCP:
-      if (msg->conn->pcb.tcp->state == LISTEN) {
-  tcp_arg(msg->conn->pcb.tcp, NULL);
-  tcp_accept(msg->conn->pcb.tcp, NULL);  
-  tcp_close(msg->conn->pcb.tcp);
-      } else {
-  tcp_arg(msg->conn->pcb.tcp, NULL);
-  tcp_sent(msg->conn->pcb.tcp, NULL);
-  tcp_recv(msg->conn->pcb.tcp, NULL);  
-  tcp_poll(msg->conn->pcb.tcp, NULL, 0);
-  tcp_err(msg->conn->pcb.tcp, NULL);
-  if (tcp_close(msg->conn->pcb.tcp) != ERR_OK) {
-    tcp_abort(msg->conn->pcb.tcp);
-  }
-      }
-#endif
-    default:  
-    break;
-    }
-  }
-  /* Trigger select() in socket layer */
-  if (msg->conn->callback)
-  {
-      (*msg->conn->callback)(msg->conn, NETCONN_EVT_RCVPLUS, 0);
-      (*msg->conn->callback)(msg->conn, NETCONN_EVT_SENDPLUS, 0);
-  }
-  
-  if (msg->conn->mbox != SYS_MBOX_NULL) {
-    sys_mbox_post(msg->conn->mbox, NULL);
-  }
-}
-
-static void
-do_bind(struct api_msg_msg *msg)
-{
-  if (msg->conn->pcb.tcp == NULL) {
-    switch (msg->conn->type) {
-#if LWIP_RAW
-    case NETCONN_RAW:
-      msg->conn->pcb.raw = raw_new(msg->msg.bc.port); /* misusing the port field as protocol */
-      raw_recv(msg->conn->pcb.raw, recv_raw, msg->conn);
-      break;
-#endif
-#if LWIP_UDP
-    case NETCONN_UDPLITE:
-      msg->conn->pcb.udp = udp_new();
-      udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_UDPLITE);
-      udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);
-      break;
-    case NETCONN_UDPNOCHKSUM:
-      msg->conn->pcb.udp = udp_new();
-      udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_NOCHKSUM);
-      udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);
-      break;
-    case NETCONN_UDP:
-      msg->conn->pcb.udp = udp_new();
-      udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);
-      break;
-#endif /* LWIP_UDP */
-#if LWIP_TCP      
-    case NETCONN_TCP:
-      msg->conn->pcb.tcp = tcp_new();
-      setup_tcp(msg->conn);
-#endif /* LWIP_TCP */
-    default:  
-    break;
-    }
-  }
-  switch (msg->conn->type) {
-#if LWIP_RAW
-  case NETCONN_RAW:
-    msg->conn->err = raw_bind(msg->conn->pcb.raw,msg->msg.bc.ipaddr);
-    break;
-#endif
-#if LWIP_UDP
-  case NETCONN_UDPLITE:
-    /* FALLTHROUGH */
-  case NETCONN_UDPNOCHKSUM:
-    /* FALLTHROUGH */
-  case NETCONN_UDP:
-    msg->conn->err = udp_bind(msg->conn->pcb.udp, msg->msg.bc.ipaddr, msg->msg.bc.port);
-    break;
-#endif /* LWIP_UDP */
-#if LWIP_TCP
-  case NETCONN_TCP:
-    msg->conn->err = tcp_bind(msg->conn->pcb.tcp,
-            msg->msg.bc.ipaddr, msg->msg.bc.port);
-#endif /* LWIP_TCP */
-  default:
-    break;
-  }
-  sys_mbox_post(msg->conn->mbox, NULL);
-}
-#if LWIP_TCP
-
-static err_t
-do_connected(void *arg, struct tcp_pcb *pcb, err_t err)
-{
-  struct netconn *conn;
-
-  conn = arg;
-
-  if (conn == NULL) {
-    return ERR_VAL;
-  }
-  
-  conn->err = err;
-  if (conn->type == NETCONN_TCP && err == ERR_OK) {
-    setup_tcp(conn);
-  }    
-  sys_mbox_post(conn->mbox, NULL);
-  return ERR_OK;
-}
-#endif  
-
-static void
-do_connect(struct api_msg_msg *msg)
-{
-  if (msg->conn->pcb.tcp == NULL) {
-    switch (msg->conn->type) {
-#if LWIP_RAW
-    case NETCONN_RAW:
-      msg->conn->pcb.raw = raw_new(msg->msg.bc.port); /* misusing the port field as protocol */
-      raw_recv(msg->conn->pcb.raw, recv_raw, msg->conn);
-      break;
-#endif
-#if LWIP_UDP
-    case NETCONN_UDPLITE:
-      msg->conn->pcb.udp = udp_new();
-      if (msg->conn->pcb.udp == NULL) {
-  msg->conn->err = ERR_MEM;
-  sys_mbox_post(msg->conn->mbox, NULL);
-  return;
-      }
-      udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_UDPLITE);
-      udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);
-      break;
-    case NETCONN_UDPNOCHKSUM:
-      msg->conn->pcb.udp = udp_new();
-      if (msg->conn->pcb.udp == NULL) {
-  msg->conn->err = ERR_MEM;
-  sys_mbox_post(msg->conn->mbox, NULL);
-  return;
-      }
-      udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_NOCHKSUM);
-      udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);
-      break;
-    case NETCONN_UDP:
-      msg->conn->pcb.udp = udp_new();
-      if (msg->conn->pcb.udp == NULL) {
-  msg->conn->err = ERR_MEM;
-  sys_mbox_post(msg->conn->mbox, NULL);
-  return;
-      }
-      udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);
-      break;
-#endif /* LWIP_UDP */
-#if LWIP_TCP      
-    case NETCONN_TCP:
-      msg->conn->pcb.tcp = tcp_new();      
-      if (msg->conn->pcb.tcp == NULL) {
-  msg->conn->err = ERR_MEM;
-  sys_mbox_post(msg->conn->mbox, NULL);
-  return;
-      }
-#endif
-    default:
-      break;
-    }
-  }
-  switch (msg->conn->type) {
-#if LWIP_RAW
-  case NETCONN_RAW:
-    raw_connect(msg->conn->pcb.raw, msg->msg.bc.ipaddr);
-    sys_mbox_post(msg->conn->mbox, NULL);
-    break;
-#endif
-#if LWIP_UDP
-  case NETCONN_UDPLITE:
-    /* FALLTHROUGH */
-  case NETCONN_UDPNOCHKSUM:
-    /* FALLTHROUGH */
-  case NETCONN_UDP:
-    udp_connect(msg->conn->pcb.udp, msg->msg.bc.ipaddr, msg->msg.bc.port);
-    sys_mbox_post(msg->conn->mbox, NULL);
-    break;
-#endif 
-#if LWIP_TCP      
-  case NETCONN_TCP:
-    /*    tcp_arg(msg->conn->pcb.tcp, msg->conn);*/
-    setup_tcp(msg->conn);
-    tcp_connect(msg->conn->pcb.tcp, msg->msg.bc.ipaddr, msg->msg.bc.port,
-    do_connected);
-    /*tcp_output(msg->conn->pcb.tcp);*/
-#endif
-
-  default:
-    break;
-  }
-}
-
-static void
-do_disconnect(struct api_msg_msg *msg)
-{
-
-  switch (msg->conn->type) {
-#if LWIP_RAW
-  case NETCONN_RAW:
-    /* Do nothing as connecting is only a helper for upper lwip layers */
-    break;
-#endif
-#if LWIP_UDP
-  case NETCONN_UDPLITE:
-    /* FALLTHROUGH */
-  case NETCONN_UDPNOCHKSUM:
-    /* FALLTHROUGH */
-  case NETCONN_UDP:
-    udp_disconnect(msg->conn->pcb.udp);
-    break;
-#endif 
-  case NETCONN_TCP:
-    break;
-  }
-  sys_mbox_post(msg->conn->mbox, NULL);
-}
-
-
-static void
-do_listen(struct api_msg_msg *msg)
-{
-  if (msg->conn->pcb.tcp != NULL) {
-    switch (msg->conn->type) {
-#if LWIP_RAW
-    case NETCONN_RAW:
-      LWIP_DEBUGF(API_MSG_DEBUG, ("api_msg: listen RAW: cannot listen for RAW.\n"));
-      break;
-#endif
-#if LWIP_UDP
-    case NETCONN_UDPLITE:
-      /* FALLTHROUGH */
-    case NETCONN_UDPNOCHKSUM:
-      /* FALLTHROUGH */
-    case NETCONN_UDP:
-      LWIP_DEBUGF(API_MSG_DEBUG, ("api_msg: listen UDP: cannot listen for UDP.\n"));
-      break;
-#endif /* LWIP_UDP */
-#if LWIP_TCP      
-    case NETCONN_TCP:
-      msg->conn->pcb.tcp = tcp_listen(msg->conn->pcb.tcp);
-      if (msg->conn->pcb.tcp == NULL) {
-  msg->conn->err = ERR_MEM;
-      } else {
-  if (msg->conn->acceptmbox == SYS_MBOX_NULL) {
-    msg->conn->acceptmbox = sys_mbox_new();
-    if (msg->conn->acceptmbox == SYS_MBOX_NULL) {
-      msg->conn->err = ERR_MEM;
-      break;
-    }
-  }
-  tcp_arg(msg->conn->pcb.tcp, msg->conn);
-  tcp_accept(msg->conn->pcb.tcp, accept_function);
-      }
-#endif
-    default:
-      break;
-    }
-  }
-  sys_mbox_post(msg->conn->mbox, NULL);
-}
-
-static void
-do_accept(struct api_msg_msg *msg)
-{
-  if (msg->conn->pcb.tcp != NULL) {
-    switch (msg->conn->type) {
-#if LWIP_RAW
-    case NETCONN_RAW:
-      LWIP_DEBUGF(API_MSG_DEBUG, ("api_msg: accept RAW: cannot accept for RAW.\n"));
-      break;
-#endif
-#if LWIP_UDP
-    case NETCONN_UDPLITE:
-      /* FALLTHROUGH */
-    case NETCONN_UDPNOCHKSUM:
-      /* FALLTHROUGH */
-    case NETCONN_UDP:    
-      LWIP_DEBUGF(API_MSG_DEBUG, ("api_msg: accept UDP: cannot accept for UDP.\n"));
-      break;
-#endif /* LWIP_UDP */
-    case NETCONN_TCP:
-      break;
-    }
-  }
-}
-
-static void
-do_send(struct api_msg_msg *msg)
-{
-  if (msg->conn->pcb.tcp != NULL) {
-    switch (msg->conn->type) {
-#if LWIP_RAW
-    case NETCONN_RAW:
-      raw_send(msg->conn->pcb.raw, msg->msg.p);
-      break;
-#endif
-#if LWIP_UDP
-    case NETCONN_UDPLITE:
-      /* FALLTHROUGH */
-    case NETCONN_UDPNOCHKSUM:
-      /* FALLTHROUGH */
-    case NETCONN_UDP:
-      udp_send(msg->conn->pcb.udp, msg->msg.p);
-      break;
-#endif /* LWIP_UDP */
-    case NETCONN_TCP:
-      break;
-    }
-  }
-  sys_mbox_post(msg->conn->mbox, NULL);
-}
-
-static void
-do_recv(struct api_msg_msg *msg)
-{
-#if LWIP_TCP
-  if (msg->conn->pcb.tcp != NULL) {
-    if (msg->conn->type == NETCONN_TCP) {
-      tcp_recved(msg->conn->pcb.tcp, msg->msg.len);
-    }
-  }
-#endif  
-  sys_mbox_post(msg->conn->mbox, NULL);
-}
-
-static void
-do_write(struct api_msg_msg *msg)
-{
-#if LWIP_TCP  
-  err_t err;
-#endif  
-  if (msg->conn->pcb.tcp != NULL) {
-    switch (msg->conn->type) {
-#if LWIP_RAW
-    case NETCONN_RAW:
-      msg->conn->err = ERR_VAL;
-      break;
-#endif
-#if LWIP_UDP 
-    case NETCONN_UDPLITE:
-      /* FALLTHROUGH */
-    case NETCONN_UDPNOCHKSUM:
-      /* FALLTHROUGH */
-    case NETCONN_UDP:
-      msg->conn->err = ERR_VAL;
-      break;
-#endif /* LWIP_UDP */
-#if LWIP_TCP 
-    case NETCONN_TCP:      
-      err = tcp_write(msg->conn->pcb.tcp, msg->msg.w.dataptr,
-                      msg->msg.w.len, msg->msg.w.copy);
-      /* This is the Nagle algorithm: inhibit the sending of new TCP
-   segments when new outgoing data arrives from the user if any
-   previously transmitted data on the connection remains
-   unacknowledged. */
-      if(err == ERR_OK && (msg->conn->pcb.tcp->unacked == NULL || (msg->conn->pcb.tcp->flags & TF_NODELAY)) ) {
-  tcp_output(msg->conn->pcb.tcp);
-      }
-      msg->conn->err = err;
-      if (msg->conn->callback)
-          if (err == ERR_OK)
-          {
-              if (tcp_sndbuf(msg->conn->pcb.tcp) <= TCP_SNDLOWAT)
-                  (*msg->conn->callback)(msg->conn, NETCONN_EVT_SENDMINUS, msg->msg.w.len);
-          }
-#endif
-    default:
-      break;
-    }
-  }
-  sys_mbox_post(msg->conn->mbox, NULL);
-}
-
-static void
-do_close(struct api_msg_msg *msg)
-{
-  err_t err;
-
-  err = ERR_OK;
-
-  if (msg->conn->pcb.tcp != NULL) {
-    switch (msg->conn->type) {
-#if LWIP_RAW
-    case NETCONN_RAW:
-      break;
-#endif
-#if LWIP_UDP
-    case NETCONN_UDPLITE:
-      /* FALLTHROUGH */
-    case NETCONN_UDPNOCHKSUM:
-      /* FALLTHROUGH */
-    case NETCONN_UDP:
-      break;
-#endif /* LWIP_UDP */
-#if LWIP_TCP
-    case NETCONN_TCP:
-      if (msg->conn->pcb.tcp->state == LISTEN) {
-  err = tcp_close(msg->conn->pcb.tcp);
-      }
-      msg->conn->err = err;      
-#endif
-    default:      
-      break;
-    }
-  }
-  sys_mbox_post(msg->conn->mbox, NULL);
-}
-
-typedef void (* api_msg_decode)(struct api_msg_msg *msg);
-static api_msg_decode decode[API_MSG_MAX] = {
-  do_newconn,
-  do_delconn,
-  do_bind,
-  do_connect,
-  do_disconnect,
-  do_listen,
-  do_accept,
-  do_send,
-  do_recv,
-  do_write,
-  do_close
-  };
-void
-api_msg_input(struct api_msg *msg)
-{  
-  decode[msg->type](&(msg->msg));
-}
-
-void
-api_msg_post(struct api_msg *msg)
-{
-  tcpip_apimsg(msg);
-}
-
-
-
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+\r
+#include "lwip/opt.h"\r
+#include "lwip/arch.h"\r
+#include "lwip/api_msg.h"\r
+#include "lwip/memp.h"\r
+#include "lwip/sys.h"\r
+#include "lwip/tcpip.h"\r
+\r
+#if LWIP_RAW\r
+static u8_t\r
+recv_raw(void *arg, struct raw_pcb *pcb, struct pbuf *p,\r
+    struct ip_addr *addr)\r
+{\r
+  struct netbuf *buf;\r
+  struct netconn *conn;\r
+\r
+  conn = arg;\r
+  if (!conn) return 0;\r
+\r
+  if (conn->recvmbox != SYS_MBOX_NULL) {\r
+    if (!(buf = memp_malloc(MEMP_NETBUF))) {\r
+      return 0;\r
+    }\r
+    pbuf_ref(p);\r
+    buf->p = p;\r
+    buf->ptr = p;\r
+    buf->fromaddr = addr;\r
+    buf->fromport = pcb->protocol;\r
+\r
+    conn->recv_avail += p->tot_len;\r
+    /* Register event with callback */\r
+    if (conn->callback)\r
+        (*conn->callback)(conn, NETCONN_EVT_RCVPLUS, p->tot_len);\r
+    sys_mbox_post(conn->recvmbox, buf);\r
+  }\r
+\r
+  return 0; /* do not eat the packet */\r
+}\r
+#endif\r
+#if LWIP_UDP\r
+static void\r
+recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p,\r
+   struct ip_addr *addr, u16_t port)\r
+{\r
+  struct netbuf *buf;\r
+  struct netconn *conn;\r
+\r
+  conn = arg;\r
+  \r
+  if (conn == NULL) {\r
+    pbuf_free(p);\r
+    return;\r
+  }\r
+  if (conn->recvmbox != SYS_MBOX_NULL) {\r
+    buf = memp_malloc(MEMP_NETBUF);\r
+    if (buf == NULL) {\r
+      pbuf_free(p);\r
+      return;\r
+    } else {\r
+      buf->p = p;\r
+      buf->ptr = p;\r
+      buf->fromaddr = addr;\r
+      buf->fromport = port;\r
+    }\r
+\r
+  conn->recv_avail += p->tot_len;\r
+    /* Register event with callback */\r
+    if (conn->callback)\r
+        (*conn->callback)(conn, NETCONN_EVT_RCVPLUS, p->tot_len);\r
+    sys_mbox_post(conn->recvmbox, buf);\r
+  }\r
+}\r
+#endif /* LWIP_UDP */\r
+#if LWIP_TCP\r
+\r
+static err_t\r
+recv_tcp(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)\r
+{\r
+  struct netconn *conn;\r
+  u16_t len;\r
+  \r
+  conn = arg;\r
+\r
+  if (conn == NULL) {\r
+    pbuf_free(p);\r
+    return ERR_VAL;\r
+  }\r
+\r
+  if (conn->recvmbox != SYS_MBOX_NULL) {\r
+        \r
+    conn->err = err;\r
+    if (p != NULL) {\r
+        len = p->tot_len;\r
+        conn->recv_avail += len;\r
+    }\r
+    else\r
+        len = 0;\r
+    /* Register event with callback */\r
+    if (conn->callback)\r
+        (*conn->callback)(conn, NETCONN_EVT_RCVPLUS, len);\r
+    sys_mbox_post(conn->recvmbox, p);\r
+  }  \r
+  return ERR_OK;\r
+}\r
+\r
+\r
+static err_t\r
+poll_tcp(void *arg, struct tcp_pcb *pcb)\r
+{\r
+  struct netconn *conn;\r
+\r
+  conn = arg;\r
+  if (conn != NULL &&\r
+     (conn->state == NETCONN_WRITE || conn->state == NETCONN_CLOSE) &&\r
+     conn->sem != SYS_SEM_NULL) {\r
+    sys_sem_signal(conn->sem);\r
+  }\r
+  return ERR_OK;\r
+}\r
+\r
+static err_t\r
+sent_tcp(void *arg, struct tcp_pcb *pcb, u16_t len)\r
+{\r
+  struct netconn *conn;\r
+\r
+  conn = arg;\r
+  if (conn != NULL && conn->sem != SYS_SEM_NULL) {\r
+    sys_sem_signal(conn->sem);\r
+  }\r
+\r
+  if (conn && conn->callback)\r
+      if (tcp_sndbuf(conn->pcb.tcp) > TCP_SNDLOWAT)\r
+          (*conn->callback)(conn, NETCONN_EVT_SENDPLUS, len);\r
+  \r
+  return ERR_OK;\r
+}\r
+\r
+static void\r
+err_tcp(void *arg, err_t err)\r
+{\r
+  struct netconn *conn;\r
+\r
+  conn = arg;\r
+\r
+  conn->pcb.tcp = NULL;\r
+\r
+  \r
+  conn->err = err;\r
+  if (conn->recvmbox != SYS_MBOX_NULL) {\r
+    /* Register event with callback */\r
+    if (conn->callback)\r
+      (*conn->callback)(conn, NETCONN_EVT_RCVPLUS, 0);\r
+    sys_mbox_post(conn->recvmbox, NULL);\r
+  }\r
+  if (conn->mbox != SYS_MBOX_NULL) {\r
+    sys_mbox_post(conn->mbox, NULL);\r
+  }\r
+  if (conn->acceptmbox != SYS_MBOX_NULL) {\r
+     /* Register event with callback */\r
+    if (conn->callback)\r
+      (*conn->callback)(conn, NETCONN_EVT_RCVPLUS, 0);\r
+    sys_mbox_post(conn->acceptmbox, NULL);\r
+  }\r
+  if (conn->sem != SYS_SEM_NULL) {\r
+    sys_sem_signal(conn->sem);\r
+  }\r
+}\r
+\r
+static void\r
+setup_tcp(struct netconn *conn)\r
+{\r
+  struct tcp_pcb *pcb;\r
+  \r
+  pcb = conn->pcb.tcp;\r
+  tcp_arg(pcb, conn);\r
+  tcp_recv(pcb, recv_tcp);\r
+  tcp_sent(pcb, sent_tcp);\r
+  tcp_poll(pcb, poll_tcp, 4);\r
+  tcp_err(pcb, err_tcp);\r
+}\r
+\r
+static err_t\r
+accept_function(void *arg, struct tcp_pcb *newpcb, err_t err)\r
+{\r
+  sys_mbox_t mbox;\r
+  struct netconn *newconn;\r
+  struct netconn *conn;\r
+  \r
+#if API_MSG_DEBUG\r
+#if TCP_DEBUG\r
+  tcp_debug_print_state(newpcb->state);\r
+#endif /* TCP_DEBUG */\r
+#endif /* API_MSG_DEBUG */\r
+  conn = (struct netconn *)arg;\r
+  mbox = conn->acceptmbox;\r
+  newconn = memp_malloc(MEMP_NETCONN);\r
+  if (newconn == NULL) {\r
+    return ERR_MEM;\r
+  }\r
+  newconn->type = NETCONN_TCP;\r
+  newconn->pcb.tcp = newpcb;\r
+  setup_tcp(newconn);\r
+  newconn->recvmbox = sys_mbox_new();\r
+  if (newconn->recvmbox == SYS_MBOX_NULL) {\r
+    memp_free(MEMP_NETCONN, newconn);\r
+    return ERR_MEM;\r
+  }\r
+  newconn->mbox = sys_mbox_new();\r
+  if (newconn->mbox == SYS_MBOX_NULL) {\r
+    sys_mbox_free(newconn->recvmbox);\r
+    memp_free(MEMP_NETCONN, newconn);\r
+    return ERR_MEM;\r
+  }\r
+  newconn->sem = sys_sem_new(0);\r
+  if (newconn->sem == SYS_SEM_NULL) {\r
+    sys_mbox_free(newconn->recvmbox);\r
+    sys_mbox_free(newconn->mbox);\r
+    memp_free(MEMP_NETCONN, newconn);\r
+    return ERR_MEM;\r
+  }\r
+  newconn->acceptmbox = SYS_MBOX_NULL;\r
+  newconn->err = err;\r
+  /* Register event with callback */\r
+  if (conn->callback)\r
+  {\r
+    (*conn->callback)(conn, NETCONN_EVT_RCVPLUS, 0);\r
+    /* We have to set the callback here even though\r
+     * the new socket is unknown. Mark the socket as -1. */\r
+    newconn->callback = conn->callback;\r
+    newconn->socket = -1;\r
+  }\r
+  \r
+  sys_mbox_post(mbox, newconn);\r
+  return ERR_OK;\r
+}\r
+#endif /* LWIP_TCP */\r
+\r
+static void\r
+do_newconn(struct api_msg_msg *msg)\r
+{\r
+   if(msg->conn->pcb.tcp != NULL) {\r
+   /* This "new" connection already has a PCB allocated. */\r
+   /* Is this an error condition? Should it be deleted? \r
+      We currently just are happy and return. */\r
+     sys_mbox_post(msg->conn->mbox, NULL);\r
+     return;\r
+   }\r
+\r
+   msg->conn->err = ERR_OK;\r
+\r
+   /* Allocate a PCB for this connection */\r
+   switch(msg->conn->type) {\r
+#if LWIP_RAW\r
+   case NETCONN_RAW:\r
+      msg->conn->pcb.raw = raw_new(msg->msg.bc.port); /* misusing the port field */\r
+      raw_recv(msg->conn->pcb.raw, recv_raw, msg->conn);\r
+     break;\r
+#endif\r
+#if LWIP_UDP\r
+   case NETCONN_UDPLITE:\r
+      msg->conn->pcb.udp = udp_new();\r
+      if(msg->conn->pcb.udp == NULL) {\r
+         msg->conn->err = ERR_MEM;\r
+         break;\r
+      }\r
+      udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_UDPLITE);\r
+      udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);\r
+      break;\r
+   case NETCONN_UDPNOCHKSUM:\r
+      msg->conn->pcb.udp = udp_new();\r
+      if(msg->conn->pcb.udp == NULL) {\r
+         msg->conn->err = ERR_MEM;\r
+         break;\r
+      }\r
+      udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_NOCHKSUM);\r
+      udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);\r
+      break;\r
+   case NETCONN_UDP:\r
+      msg->conn->pcb.udp = udp_new();\r
+      if(msg->conn->pcb.udp == NULL) {\r
+         msg->conn->err = ERR_MEM;\r
+         break;\r
+      }\r
+      udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);\r
+      break;\r
+#endif /* LWIP_UDP */\r
+#if LWIP_TCP\r
+   case NETCONN_TCP:\r
+      msg->conn->pcb.tcp = tcp_new();\r
+      if(msg->conn->pcb.tcp == NULL) {\r
+         msg->conn->err = ERR_MEM;\r
+         break;\r
+      }\r
+      setup_tcp(msg->conn);\r
+      break;\r
+#endif\r
+   }\r
+   \r
+  \r
+  sys_mbox_post(msg->conn->mbox, NULL);\r
+}\r
+\r
+\r
+static void\r
+do_delconn(struct api_msg_msg *msg)\r
+{\r
+  if (msg->conn->pcb.tcp != NULL) {\r
+    switch (msg->conn->type) {\r
+#if LWIP_RAW\r
+    case NETCONN_RAW:\r
+      raw_remove(msg->conn->pcb.raw);\r
+      break;\r
+#endif\r
+#if LWIP_UDP\r
+    case NETCONN_UDPLITE:\r
+      /* FALLTHROUGH */\r
+    case NETCONN_UDPNOCHKSUM:\r
+      /* FALLTHROUGH */\r
+    case NETCONN_UDP:\r
+      msg->conn->pcb.udp->recv_arg = NULL;\r
+      udp_remove(msg->conn->pcb.udp);\r
+      break;\r
+#endif /* LWIP_UDP */\r
+#if LWIP_TCP      \r
+    case NETCONN_TCP:\r
+      if (msg->conn->pcb.tcp->state == LISTEN) {\r
+  tcp_arg(msg->conn->pcb.tcp, NULL);\r
+  tcp_accept(msg->conn->pcb.tcp, NULL);  \r
+  tcp_close(msg->conn->pcb.tcp);\r
+      } else {\r
+  tcp_arg(msg->conn->pcb.tcp, NULL);\r
+  tcp_sent(msg->conn->pcb.tcp, NULL);\r
+  tcp_recv(msg->conn->pcb.tcp, NULL);  \r
+  tcp_poll(msg->conn->pcb.tcp, NULL, 0);\r
+  tcp_err(msg->conn->pcb.tcp, NULL);\r
+  if (tcp_close(msg->conn->pcb.tcp) != ERR_OK) {\r
+    tcp_abort(msg->conn->pcb.tcp);\r
+  }\r
+      }\r
+#endif\r
+    default:  \r
+    break;\r
+    }\r
+  }\r
+  /* Trigger select() in socket layer */\r
+  if (msg->conn->callback)\r
+  {\r
+      (*msg->conn->callback)(msg->conn, NETCONN_EVT_RCVPLUS, 0);\r
+      (*msg->conn->callback)(msg->conn, NETCONN_EVT_SENDPLUS, 0);\r
+  }\r
+  \r
+  if (msg->conn->mbox != SYS_MBOX_NULL) {\r
+    sys_mbox_post(msg->conn->mbox, NULL);\r
+  }\r
+}\r
+\r
+static void\r
+do_bind(struct api_msg_msg *msg)\r
+{\r
+  if (msg->conn->pcb.tcp == NULL) {\r
+    switch (msg->conn->type) {\r
+#if LWIP_RAW\r
+    case NETCONN_RAW:\r
+      msg->conn->pcb.raw = raw_new(msg->msg.bc.port); /* misusing the port field as protocol */\r
+      raw_recv(msg->conn->pcb.raw, recv_raw, msg->conn);\r
+      break;\r
+#endif\r
+#if LWIP_UDP\r
+    case NETCONN_UDPLITE:\r
+      msg->conn->pcb.udp = udp_new();\r
+      udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_UDPLITE);\r
+      udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);\r
+      break;\r
+    case NETCONN_UDPNOCHKSUM:\r
+      msg->conn->pcb.udp = udp_new();\r
+      udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_NOCHKSUM);\r
+      udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);\r
+      break;\r
+    case NETCONN_UDP:\r
+      msg->conn->pcb.udp = udp_new();\r
+      udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);\r
+      break;\r
+#endif /* LWIP_UDP */\r
+#if LWIP_TCP      \r
+    case NETCONN_TCP:\r
+      msg->conn->pcb.tcp = tcp_new();\r
+      setup_tcp(msg->conn);\r
+#endif /* LWIP_TCP */\r
+    default:  \r
+    break;\r
+    }\r
+  }\r
+  switch (msg->conn->type) {\r
+#if LWIP_RAW\r
+  case NETCONN_RAW:\r
+    msg->conn->err = raw_bind(msg->conn->pcb.raw,msg->msg.bc.ipaddr);\r
+    break;\r
+#endif\r
+#if LWIP_UDP\r
+  case NETCONN_UDPLITE:\r
+    /* FALLTHROUGH */\r
+  case NETCONN_UDPNOCHKSUM:\r
+    /* FALLTHROUGH */\r
+  case NETCONN_UDP:\r
+    msg->conn->err = udp_bind(msg->conn->pcb.udp, msg->msg.bc.ipaddr, msg->msg.bc.port);\r
+    break;\r
+#endif /* LWIP_UDP */\r
+#if LWIP_TCP\r
+  case NETCONN_TCP:\r
+    msg->conn->err = tcp_bind(msg->conn->pcb.tcp,\r
+            msg->msg.bc.ipaddr, msg->msg.bc.port);\r
+#endif /* LWIP_TCP */\r
+  default:\r
+    break;\r
+  }\r
+  sys_mbox_post(msg->conn->mbox, NULL);\r
+}\r
+#if LWIP_TCP\r
+\r
+static err_t\r
+do_connected(void *arg, struct tcp_pcb *pcb, err_t err)\r
+{\r
+  struct netconn *conn;\r
+\r
+  conn = arg;\r
+\r
+  if (conn == NULL) {\r
+    return ERR_VAL;\r
+  }\r
+  \r
+  conn->err = err;\r
+  if (conn->type == NETCONN_TCP && err == ERR_OK) {\r
+    setup_tcp(conn);\r
+  }    \r
+  sys_mbox_post(conn->mbox, NULL);\r
+  return ERR_OK;\r
+}\r
+#endif  \r
+\r
+static void\r
+do_connect(struct api_msg_msg *msg)\r
+{\r
+  if (msg->conn->pcb.tcp == NULL) {\r
+    switch (msg->conn->type) {\r
+#if LWIP_RAW\r
+    case NETCONN_RAW:\r
+      msg->conn->pcb.raw = raw_new(msg->msg.bc.port); /* misusing the port field as protocol */\r
+      raw_recv(msg->conn->pcb.raw, recv_raw, msg->conn);\r
+      break;\r
+#endif\r
+#if LWIP_UDP\r
+    case NETCONN_UDPLITE:\r
+      msg->conn->pcb.udp = udp_new();\r
+      if (msg->conn->pcb.udp == NULL) {\r
+  msg->conn->err = ERR_MEM;\r
+  sys_mbox_post(msg->conn->mbox, NULL);\r
+  return;\r
+      }\r
+      udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_UDPLITE);\r
+      udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);\r
+      break;\r
+    case NETCONN_UDPNOCHKSUM:\r
+      msg->conn->pcb.udp = udp_new();\r
+      if (msg->conn->pcb.udp == NULL) {\r
+  msg->conn->err = ERR_MEM;\r
+  sys_mbox_post(msg->conn->mbox, NULL);\r
+  return;\r
+      }\r
+      udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_NOCHKSUM);\r
+      udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);\r
+      break;\r
+    case NETCONN_UDP:\r
+      msg->conn->pcb.udp = udp_new();\r
+      if (msg->conn->pcb.udp == NULL) {\r
+  msg->conn->err = ERR_MEM;\r
+  sys_mbox_post(msg->conn->mbox, NULL);\r
+  return;\r
+      }\r
+      udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);\r
+      break;\r
+#endif /* LWIP_UDP */\r
+#if LWIP_TCP      \r
+    case NETCONN_TCP:\r
+      msg->conn->pcb.tcp = tcp_new();      \r
+      if (msg->conn->pcb.tcp == NULL) {\r
+  msg->conn->err = ERR_MEM;\r
+  sys_mbox_post(msg->conn->mbox, NULL);\r
+  return;\r
+      }\r
+#endif\r
+    default:\r
+      break;\r
+    }\r
+  }\r
+  switch (msg->conn->type) {\r
+#if LWIP_RAW\r
+  case NETCONN_RAW:\r
+    raw_connect(msg->conn->pcb.raw, msg->msg.bc.ipaddr);\r
+    sys_mbox_post(msg->conn->mbox, NULL);\r
+    break;\r
+#endif\r
+#if LWIP_UDP\r
+  case NETCONN_UDPLITE:\r
+    /* FALLTHROUGH */\r
+  case NETCONN_UDPNOCHKSUM:\r
+    /* FALLTHROUGH */\r
+  case NETCONN_UDP:\r
+    udp_connect(msg->conn->pcb.udp, msg->msg.bc.ipaddr, msg->msg.bc.port);\r
+    sys_mbox_post(msg->conn->mbox, NULL);\r
+    break;\r
+#endif \r
+#if LWIP_TCP      \r
+  case NETCONN_TCP:\r
+    /*    tcp_arg(msg->conn->pcb.tcp, msg->conn);*/\r
+    setup_tcp(msg->conn);\r
+    tcp_connect(msg->conn->pcb.tcp, msg->msg.bc.ipaddr, msg->msg.bc.port,\r
+    do_connected);\r
+    /*tcp_output(msg->conn->pcb.tcp);*/\r
+#endif\r
+\r
+  default:\r
+    break;\r
+  }\r
+}\r
+\r
+static void\r
+do_disconnect(struct api_msg_msg *msg)\r
+{\r
+\r
+  switch (msg->conn->type) {\r
+#if LWIP_RAW\r
+  case NETCONN_RAW:\r
+    /* Do nothing as connecting is only a helper for upper lwip layers */\r
+    break;\r
+#endif\r
+#if LWIP_UDP\r
+  case NETCONN_UDPLITE:\r
+    /* FALLTHROUGH */\r
+  case NETCONN_UDPNOCHKSUM:\r
+    /* FALLTHROUGH */\r
+  case NETCONN_UDP:\r
+    udp_disconnect(msg->conn->pcb.udp);\r
+    break;\r
+#endif \r
+  case NETCONN_TCP:\r
+    break;\r
+  }\r
+  sys_mbox_post(msg->conn->mbox, NULL);\r
+}\r
+\r
+\r
+static void\r
+do_listen(struct api_msg_msg *msg)\r
+{\r
+  if (msg->conn->pcb.tcp != NULL) {\r
+    switch (msg->conn->type) {\r
+#if LWIP_RAW\r
+    case NETCONN_RAW:\r
+      LWIP_DEBUGF(API_MSG_DEBUG, ("api_msg: listen RAW: cannot listen for RAW.\n"));\r
+      break;\r
+#endif\r
+#if LWIP_UDP\r
+    case NETCONN_UDPLITE:\r
+      /* FALLTHROUGH */\r
+    case NETCONN_UDPNOCHKSUM:\r
+      /* FALLTHROUGH */\r
+    case NETCONN_UDP:\r
+      LWIP_DEBUGF(API_MSG_DEBUG, ("api_msg: listen UDP: cannot listen for UDP.\n"));\r
+      break;\r
+#endif /* LWIP_UDP */\r
+#if LWIP_TCP      \r
+    case NETCONN_TCP:\r
+      msg->conn->pcb.tcp = tcp_listen(msg->conn->pcb.tcp);\r
+      if (msg->conn->pcb.tcp == NULL) {\r
+  msg->conn->err = ERR_MEM;\r
+      } else {\r
+  if (msg->conn->acceptmbox == SYS_MBOX_NULL) {\r
+    msg->conn->acceptmbox = sys_mbox_new();\r
+    if (msg->conn->acceptmbox == SYS_MBOX_NULL) {\r
+      msg->conn->err = ERR_MEM;\r
+      break;\r
+    }\r
+  }\r
+  tcp_arg(msg->conn->pcb.tcp, msg->conn);\r
+  tcp_accept(msg->conn->pcb.tcp, accept_function);\r
+      }\r
+#endif\r
+    default:\r
+      break;\r
+    }\r
+  }\r
+  sys_mbox_post(msg->conn->mbox, NULL);\r
+}\r
+\r
+static void\r
+do_accept(struct api_msg_msg *msg)\r
+{\r
+  if (msg->conn->pcb.tcp != NULL) {\r
+    switch (msg->conn->type) {\r
+#if LWIP_RAW\r
+    case NETCONN_RAW:\r
+      LWIP_DEBUGF(API_MSG_DEBUG, ("api_msg: accept RAW: cannot accept for RAW.\n"));\r
+      break;\r
+#endif\r
+#if LWIP_UDP\r
+    case NETCONN_UDPLITE:\r
+      /* FALLTHROUGH */\r
+    case NETCONN_UDPNOCHKSUM:\r
+      /* FALLTHROUGH */\r
+    case NETCONN_UDP:    \r
+      LWIP_DEBUGF(API_MSG_DEBUG, ("api_msg: accept UDP: cannot accept for UDP.\n"));\r
+      break;\r
+#endif /* LWIP_UDP */\r
+    case NETCONN_TCP:\r
+      break;\r
+    }\r
+  }\r
+}\r
+\r
+static void\r
+do_send(struct api_msg_msg *msg)\r
+{\r
+  if (msg->conn->pcb.tcp != NULL) {\r
+    switch (msg->conn->type) {\r
+#if LWIP_RAW\r
+    case NETCONN_RAW:\r
+      raw_send(msg->conn->pcb.raw, msg->msg.p);\r
+      break;\r
+#endif\r
+#if LWIP_UDP\r
+    case NETCONN_UDPLITE:\r
+      /* FALLTHROUGH */\r
+    case NETCONN_UDPNOCHKSUM:\r
+      /* FALLTHROUGH */\r
+    case NETCONN_UDP:\r
+      udp_send(msg->conn->pcb.udp, msg->msg.p);\r
+      break;\r
+#endif /* LWIP_UDP */\r
+    case NETCONN_TCP:\r
+      break;\r
+    }\r
+  }\r
+  sys_mbox_post(msg->conn->mbox, NULL);\r
+}\r
+\r
+static void\r
+do_recv(struct api_msg_msg *msg)\r
+{\r
+#if LWIP_TCP\r
+  if (msg->conn->pcb.tcp != NULL) {\r
+    if (msg->conn->type == NETCONN_TCP) {\r
+      tcp_recved(msg->conn->pcb.tcp, msg->msg.len);\r
+    }\r
+  }\r
+#endif  \r
+  sys_mbox_post(msg->conn->mbox, NULL);\r
+}\r
+\r
+static void\r
+do_write(struct api_msg_msg *msg)\r
+{\r
+#if LWIP_TCP  \r
+  err_t err;\r
+#endif  \r
+  if (msg->conn->pcb.tcp != NULL) {\r
+    switch (msg->conn->type) {\r
+#if LWIP_RAW\r
+    case NETCONN_RAW:\r
+      msg->conn->err = ERR_VAL;\r
+      break;\r
+#endif\r
+#if LWIP_UDP \r
+    case NETCONN_UDPLITE:\r
+      /* FALLTHROUGH */\r
+    case NETCONN_UDPNOCHKSUM:\r
+      /* FALLTHROUGH */\r
+    case NETCONN_UDP:\r
+      msg->conn->err = ERR_VAL;\r
+      break;\r
+#endif /* LWIP_UDP */\r
+#if LWIP_TCP \r
+    case NETCONN_TCP:      \r
+      err = tcp_write(msg->conn->pcb.tcp, msg->msg.w.dataptr,\r
+                      msg->msg.w.len, msg->msg.w.copy);\r
+      /* This is the Nagle algorithm: inhibit the sending of new TCP\r
+   segments when new outgoing data arrives from the user if any\r
+   previously transmitted data on the connection remains\r
+   unacknowledged. */\r
+      if(err == ERR_OK && (msg->conn->pcb.tcp->unacked == NULL || (msg->conn->pcb.tcp->flags & TF_NODELAY)) ) {\r
+  tcp_output(msg->conn->pcb.tcp);\r
+      }\r
+      msg->conn->err = err;\r
+      if (msg->conn->callback)\r
+          if (err == ERR_OK)\r
+          {\r
+              if (tcp_sndbuf(msg->conn->pcb.tcp) <= TCP_SNDLOWAT)\r
+                  (*msg->conn->callback)(msg->conn, NETCONN_EVT_SENDMINUS, msg->msg.w.len);\r
+          }\r
+#endif\r
+    default:\r
+      break;\r
+    }\r
+  }\r
+  sys_mbox_post(msg->conn->mbox, NULL);\r
+}\r
+\r
+static void\r
+do_close(struct api_msg_msg *msg)\r
+{\r
+  err_t err;\r
+\r
+  err = ERR_OK;\r
+\r
+  if (msg->conn->pcb.tcp != NULL) {\r
+    switch (msg->conn->type) {\r
+#if LWIP_RAW\r
+    case NETCONN_RAW:\r
+      break;\r
+#endif\r
+#if LWIP_UDP\r
+    case NETCONN_UDPLITE:\r
+      /* FALLTHROUGH */\r
+    case NETCONN_UDPNOCHKSUM:\r
+      /* FALLTHROUGH */\r
+    case NETCONN_UDP:\r
+      break;\r
+#endif /* LWIP_UDP */\r
+#if LWIP_TCP\r
+    case NETCONN_TCP:\r
+      if (msg->conn->pcb.tcp->state == LISTEN) {\r
+  err = tcp_close(msg->conn->pcb.tcp);\r
+      }\r
+      msg->conn->err = err;      \r
+#endif\r
+    default:      \r
+      break;\r
+    }\r
+  }\r
+  sys_mbox_post(msg->conn->mbox, NULL);\r
+}\r
+\r
+typedef void (* api_msg_decode)(struct api_msg_msg *msg);\r
+static api_msg_decode decode[API_MSG_MAX] = {\r
+  do_newconn,\r
+  do_delconn,\r
+  do_bind,\r
+  do_connect,\r
+  do_disconnect,\r
+  do_listen,\r
+  do_accept,\r
+  do_send,\r
+  do_recv,\r
+  do_write,\r
+  do_close\r
+  };\r
+void\r
+api_msg_input(struct api_msg *msg)\r
+{  \r
+  decode[msg->type](&(msg->msg));\r
+}\r
+\r
+void\r
+api_msg_post(struct api_msg *msg)\r
+{\r
+  tcpip_apimsg(msg);\r
+}\r
+\r
+\r
+\r
index b582d88a2b4f6943bbdaa9fa7fca6bb91a60bb27..cc6367814734a1ebbfab543822da22dcb4006e9e 100644 (file)
@@ -1,59 +1,59 @@
-/*
- * 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 <adam@sics.se>
- *
- */
-
-#include "lwip/err.h"
-
-#ifdef LWIP_DEBUG
-
-static char *err_strerr[] = {"Ok.",
-           "Out of memory error.",
-           "Buffer error.",
-           "Connection aborted.",
-           "Connection reset.",
-           "Connection closed.",
-           "Not connected.",
-           "Illegal value.",
-           "Illegal argument.",
-           "Routing problem.",
-           "Address in use."
-};
-
-
-char *
-lwip_strerr(err_t err)
-{
-  return err_strerr[-err];
-
-}
-
-
-#endif /* LWIP_DEBUG */
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+\r
+#include "lwip/err.h"\r
+\r
+#ifdef LWIP_DEBUG\r
+\r
+static char *err_strerr[] = {"Ok.",\r
+           "Out of memory error.",\r
+           "Buffer error.",\r
+           "Connection aborted.",\r
+           "Connection reset.",\r
+           "Connection closed.",\r
+           "Not connected.",\r
+           "Illegal value.",\r
+           "Illegal argument.",\r
+           "Routing problem.",\r
+           "Address in use."\r
+};\r
+\r
+\r
+char *\r
+lwip_strerr(err_t err)\r
+{\r
+  return err_strerr[-err];\r
+\r
+}\r
+\r
+\r
+#endif /* LWIP_DEBUG */\r
index 290a7b73755326cfbca09f572232543c80efab8a..26e6d86300c270802858d780a5781b02cfab2a47 100644 (file)
-/*
- * 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 <adam@sics.se>
- *
- * Improved by Marc Boucher <marc@mbsi.ca> and David Haas <dhaas@alum.rpi.edu>
- *
- */
-
-#include <string.h>
-#include <errno.h>
-
-#include "lwip/opt.h"
-#include "lwip/api.h"
-#include "lwip/arch.h"
-#include "lwip/sys.h"
-
-#include "lwip/sockets.h"
-
-#define NUM_SOCKETS MEMP_NUM_NETCONN
-
-struct lwip_socket {
-  struct netconn *conn;
-  struct netbuf *lastdata;
-  u16_t lastoffset;
-  u16_t rcvevent;
-  u16_t sendevent;
-  u16_t  flags;
-  int err;
-};
-
-struct lwip_select_cb
-{
-    struct lwip_select_cb *next;
-    fd_set *readset;
-    fd_set *writeset;
-    fd_set *exceptset;
-    int sem_signalled;
-    sys_sem_t sem;
-};
-
-static struct lwip_socket sockets[NUM_SOCKETS];
-static struct lwip_select_cb *select_cb_list = 0;
-
-static sys_sem_t socksem = 0;
-static sys_sem_t selectsem = 0;
-
-static void
-event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len);
-
-static int err_to_errno_table[11] = {
-    0,      /* ERR_OK    0      No error, everything OK. */
-    ENOMEM,    /* ERR_MEM  -1      Out of memory error.     */
-    ENOBUFS,    /* ERR_BUF  -2      Buffer error.            */
-    ECONNABORTED,  /* ERR_ABRT -3      Connection aborted.      */
-    ECONNRESET,    /* ERR_RST  -4      Connection reset.        */
-    ESHUTDOWN,    /* ERR_CLSD -5      Connection closed.       */
-    ENOTCONN,    /* ERR_CONN -6      Not connected.           */
-    EINVAL,    /* ERR_VAL  -7      Illegal value.           */
-    EIO,    /* ERR_ARG  -8      Illegal argument.        */
-    EHOSTUNREACH,  /* ERR_RTE  -9      Routing problem.         */
-    EADDRINUSE    /* ERR_USE  -10     Address in use.          */
-};
-
-#define ERR_TO_ERRNO_TABLE_SIZE \
-  (sizeof(err_to_errno_table)/sizeof(err_to_errno_table[0]))
-
-#define err_to_errno(err) \
-  (-(err) >= 0 && -(err) < ERR_TO_ERRNO_TABLE_SIZE ? \
-    err_to_errno_table[-(err)] : EIO)
-
-#ifdef ERRNO
-#define set_errno(err) errno = (err)
-#else
-#define set_errno(err)
-#endif
-
-#define sock_set_errno(sk, e) do { \
-      sk->err = (e); \
-      set_errno(sk->err); \
-} while (0)
-
-
-static struct lwip_socket *
-get_socket(int s)
-{
-  struct lwip_socket *sock;
-
-  if ((s < 0) || (s > NUM_SOCKETS)) {
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("get_socket(%d): invalid\n", s));
-    set_errno(EBADF);
-    return NULL;
-  }
-
-  sock = &sockets[s];
-
-  if (!sock->conn) {
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("get_socket(%d): not active\n", s));
-    set_errno(EBADF);
-    return NULL;
-  }
-
-  return sock;
-}
-
-static int
-alloc_socket(struct netconn *newconn)
-{
-  int i;
-
-  if (!socksem)
-      socksem = sys_sem_new(1);
-
-  /* Protect socket array */
-  sys_sem_wait(socksem);
-
-  /* allocate a new socket identifier */
-  for(i = 0; i < NUM_SOCKETS; ++i) {
-    if (!sockets[i].conn) {
-      sockets[i].conn = newconn;
-      sockets[i].lastdata = NULL;
-      sockets[i].lastoffset = 0;
-      sockets[i].rcvevent = 0;
-      sockets[i].sendevent = 1; /* TCP send buf is empty */
-      sockets[i].flags = 0;
-      sockets[i].err = 0;
-      sys_sem_signal(socksem);
-      return i;
-    }
-  }
-  sys_sem_signal(socksem);
-  return -1;
-}
-
-int
-lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
-{
-  struct lwip_socket *sock;
-  struct netconn *newconn;
-  struct ip_addr naddr;
-  u16_t port;
-  int newsock;
-  struct sockaddr_in sin;
-
-  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d)...\n", s));
-  sock = get_socket(s);
-  if (!sock) {
-    set_errno(EBADF);
-    return -1;
-  }
-
-  newconn = netconn_accept(sock->conn);
-
-  /* get the IP address and port of the remote host */
-  netconn_peer(newconn, &naddr, &port);
-
-  memset(&sin, 0, sizeof(sin));
-  sin.sin_len = sizeof(sin);
-  sin.sin_family = AF_INET;
-  sin.sin_port = htons(port);
-  sin.sin_addr.s_addr = naddr.addr;
-
-  if (*addrlen > sizeof(sin))
-      *addrlen = sizeof(sin);
-
-  memcpy(addr, &sin, *addrlen);
-
-  newsock = alloc_socket(newconn);
-  if (newsock == -1) {
-    netconn_delete(newconn);
-  sock_set_errno(sock, ENOBUFS);
-  return -1;
-  }
-  newconn->callback = event_callback;
-  sock = get_socket(newsock);
-
-  sys_sem_wait(socksem);
-  sock->rcvevent += -1 - newconn->socket;
-  newconn->socket = newsock;
-  sys_sem_signal(socksem);
-
-  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d) returning new sock=%d addr=", s, newsock));
-  ip_addr_debug_print(SOCKETS_DEBUG, &naddr);
-  LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u\n", port));
-
-  sock_set_errno(sock, 0);
-  return newsock;
-}
-
-int
-lwip_bind(int s, struct sockaddr *name, socklen_t namelen)
-{
-  struct lwip_socket *sock;
-  struct ip_addr local_addr;
-  u16_t local_port;
-  err_t err;
-
-  sock = get_socket(s);
-  if (!sock) {
-    set_errno(EBADF);
-    return -1;
-  }
-
-  local_addr.addr = ((struct sockaddr_in *)name)->sin_addr.s_addr;
-  local_port = ((struct sockaddr_in *)name)->sin_port;
-
-  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d, addr=", s));
-  ip_addr_debug_print(SOCKETS_DEBUG, &local_addr);
-  LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u)\n", ntohs(local_port)));
-
-  err = netconn_bind(sock->conn, &local_addr, ntohs(local_port));
-
-  if (err != ERR_OK) {
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d) failed, err=%d\n", s, err));
-    sock_set_errno(sock, err_to_errno(err));
-    return -1;
-  }
-
-  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d) succeeded\n", s));
-  sock_set_errno(sock, 0);
-  return 0;
-}
-
-int
-lwip_close(int s)
-{
-  struct lwip_socket *sock;
-
-  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_close(%d)\n", s));
-  if (!socksem)
-      socksem = sys_sem_new(1);
-
-  /* We cannot allow multiple closes of the same socket. */
-  sys_sem_wait(socksem);
-
-  sock = get_socket(s);
-  if (!sock) {
-      sys_sem_signal(socksem);
-      set_errno(EBADF);
-      return -1;
-  }
-
-  netconn_delete(sock->conn);
-  if (sock->lastdata) {
-    netbuf_delete(sock->lastdata);
-  }
-  sock->lastdata = NULL;
-  sock->lastoffset = 0;
-  sock->conn = NULL;
-  sys_sem_signal(socksem);
-  sock_set_errno(sock, 0);
-  return 0;
-}
-
-int
-lwip_connect(int s, struct sockaddr *name, socklen_t namelen)
-{
-  struct lwip_socket *sock;
-  err_t err;
-
-  sock = get_socket(s);
-  if (!sock) {
-    set_errno(EBADF);
-    return -1;
-  }
-
-  if (((struct sockaddr_in *)name)->sin_family == AF_UNSPEC) {
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, AF_UNSPEC)\n", s));
-    err = netconn_disconnect(sock->conn);
-  } else {
-    struct ip_addr remote_addr;
-    u16_t remote_port;
-
-    remote_addr.addr = ((struct sockaddr_in *)name)->sin_addr.s_addr;
-    remote_port = ((struct sockaddr_in *)name)->sin_port;
-
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, addr=", s));
-    ip_addr_debug_print(SOCKETS_DEBUG, &remote_addr);
-    LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u)\n", ntohs(remote_port)));
-
-    err = netconn_connect(sock->conn, &remote_addr, ntohs(remote_port));
-   }
-
-  if (err != ERR_OK) {
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d) failed, err=%d\n", s, err));
-    sock_set_errno(sock, err_to_errno(err));
-    return -1;
-  }
-
-  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d) succeeded\n", s));
-  sock_set_errno(sock, 0);
-  return 0;
-}
-
-int
-lwip_listen(int s, int backlog)
-{
-  struct lwip_socket *sock;
-  err_t err;
-
-  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_listen(%d, backlog=%d)\n", s, backlog));
-  sock = get_socket(s);
-  if (!sock) {
-    set_errno(EBADF);
-    return -1;
-  }
-
-  err = netconn_listen(sock->conn);
-
-  if (err != ERR_OK) {
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_listen(%d) failed, err=%d\n", s, err));
-    sock_set_errno(sock, err_to_errno(err));
-    return -1;
-  }
-
-  sock_set_errno(sock, 0);
-  return 0;
-}
-
-int
-lwip_recvfrom(int s, void *mem, int len, unsigned int flags,
-        struct sockaddr *from, socklen_t *fromlen)
-{
-  struct lwip_socket *sock;
-  struct netbuf *buf;
-  u16_t buflen, copylen;
-  struct ip_addr *addr;
-  u16_t port;
-
-
-  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d, %p, %d, 0x%x, ..)\n", s, mem, len, flags));
-  sock = get_socket(s);
-  if (!sock) {
-    set_errno(EBADF);
-    return -1;
-  }
-
-  /* Check if there is data left from the last recv operation. */
-  if (sock->lastdata) {
-    buf = sock->lastdata;
-  } else {
-    /* If this is non-blocking call, then check first */
-    if (((flags & MSG_DONTWAIT) || (sock->flags & O_NONBLOCK))
-  && !sock->rcvevent)
-    {
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): returning EWOULDBLOCK\n", s));
-      sock_set_errno(sock, EWOULDBLOCK);
-      return -1;
-    }
-
-    /* No data was left from the previous operation, so we try to get
-       some from the network. */
-    buf = netconn_recv(sock->conn);
-
-    if (!buf) {
-      /* We should really do some error checking here. */
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): buf == NULL!\n", s));
-      sock_set_errno(sock, 0);
-      return 0;
-    }
-  }
-
-  buflen = netbuf_len(buf);
-
-  buflen -= sock->lastoffset;
-
-  if (len > buflen) {
-    copylen = buflen;
-  } else {
-    copylen = len;
-  }
-
-  /* copy the contents of the received buffer into
-     the supplied memory pointer mem */
-  netbuf_copy_partial(buf, mem, copylen, sock->lastoffset);
-
-  /* Check to see from where the data was. */
-  if (from && fromlen) {
-    struct sockaddr_in sin;
-
-    addr = netbuf_fromaddr(buf);
-    port = netbuf_fromport(buf);
-
-    memset(&sin, 0, sizeof(sin));
-    sin.sin_len = sizeof(sin);
-    sin.sin_family = AF_INET;
-    sin.sin_port = htons(port);
-    sin.sin_addr.s_addr = addr->addr;
-
-    if (*fromlen > sizeof(sin))
-      *fromlen = sizeof(sin);
-
-    memcpy(from, &sin, *fromlen);
-
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): addr=", s));
-    ip_addr_debug_print(SOCKETS_DEBUG, addr);
-    LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u len=%u\n", port, copylen));
-  } else {
-#if SOCKETS_DEBUG
-    addr = netbuf_fromaddr(buf);
-    port = netbuf_fromport(buf);
-
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): addr=", s));
-    ip_addr_debug_print(SOCKETS_DEBUG, addr);
-    LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u len=%u\n", port, copylen));
-#endif
-
-  }
-
-  /* If this is a TCP socket, check if there is data left in the
-     buffer. If so, it should be saved in the sock structure for next
-     time around. */
-  if (netconn_type(sock->conn) == NETCONN_TCP && buflen - copylen > 0) {
-    sock->lastdata = buf;
-    sock->lastoffset += copylen;
-  } else {
-    sock->lastdata = NULL;
-    sock->lastoffset = 0;
-    netbuf_delete(buf);
-  }
-
-
-  sock_set_errno(sock, 0);
-  return copylen;
-}
-
-int
-lwip_read(int s, void *mem, int len)
-{
-  return lwip_recvfrom(s, mem, len, 0, NULL, NULL);
-}
-
-int
-lwip_recv(int s, void *mem, int len, unsigned int flags)
-{
-  return lwip_recvfrom(s, mem, len, flags, NULL, NULL);
-}
-
-int
-lwip_send(int s, void *data, int size, unsigned int flags)
-{
-  struct lwip_socket *sock;
-  struct netbuf *buf;
-  err_t err;
-
-  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d, data=%p, size=%d, flags=0x%x)\n", s, data, size, flags));
-
-  sock = get_socket(s);
-  if (!sock) {
-    set_errno(EBADF);
-    return -1;
-  }
-
-  switch (netconn_type(sock->conn)) {
-  case NETCONN_RAW:
-  case NETCONN_UDP:
-  case NETCONN_UDPLITE:
-  case NETCONN_UDPNOCHKSUM:
-    /* create a buffer */
-    buf = netbuf_new();
-
-    if (!buf) {
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) ENOBUFS\n", s));
-      sock_set_errno(sock, ENOBUFS);
-      return -1;
-    }
-
-    /* make the buffer point to the data that should
-       be sent */
-    netbuf_ref(buf, data, size);
-
-    /* send the data */
-    err = netconn_send(sock->conn, buf);
-
-    /* deallocated the buffer */
-    netbuf_delete(buf);
-    break;
-  case NETCONN_TCP:
-    err = netconn_write(sock->conn, data, size, NETCONN_COPY);
-    break;
-  default:
-    err = ERR_ARG;
-    break;
-  }
-  if (err != ERR_OK) {
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) err=%d\n", s, err));
-    sock_set_errno(sock, err_to_errno(err));
-    return -1;
-  }
-
-  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) ok size=%d\n", s, size));
-  sock_set_errno(sock, 0);
-  return size;
-}
-
-int
-lwip_sendto(int s, void *data, int size, unsigned int flags,
-       struct sockaddr *to, socklen_t tolen)
-{
-  struct lwip_socket *sock;
-  struct ip_addr remote_addr, addr;
-  u16_t remote_port, port;
-  int ret,connected;
-
-  sock = get_socket(s);
-  if (!sock) {
-    set_errno(EBADF);
-    return -1;
-  }
-
-  /* get the peer if currently connected */
-  connected = (netconn_peer(sock->conn, &addr, &port) == ERR_OK);
-
-  remote_addr.addr = ((struct sockaddr_in *)to)->sin_addr.s_addr;
-  remote_port = ((struct sockaddr_in *)to)->sin_port;
-
-  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_sendto(%d, data=%p, size=%d, flags=0x%x to=", s, data, size, flags));
-  ip_addr_debug_print(SOCKETS_DEBUG, &remote_addr);
-  LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u\n", ntohs(remote_port)));
-
-  netconn_connect(sock->conn, &remote_addr, ntohs(remote_port));
-
-  ret = lwip_send(s, data, size, flags);
-
-  /* reset the remote address and port number
-     of the connection */
-  if (connected)
-    netconn_connect(sock->conn, &addr, port);
-  else
-  netconn_disconnect(sock->conn);
-  return ret;
-}
-
-int
-lwip_socket(int domain, int type, int protocol)
-{
-  struct netconn *conn;
-  int i;
-
-  /* create a netconn */
-  switch (type) {
-  case SOCK_RAW:
-    conn = netconn_new_with_proto_and_callback(NETCONN_RAW, protocol, event_callback);
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_RAW, %d) = ", domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol));
-    break;
-  case SOCK_DGRAM:
-    conn = netconn_new_with_callback(NETCONN_UDP, event_callback);
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_DGRAM, %d) = ", domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol));
-    break;
-  case SOCK_STREAM:
-    conn = netconn_new_with_callback(NETCONN_TCP, event_callback);
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_STREAM, %d) = ", domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol));
-    break;
-  default:
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%d, %d/UNKNOWN, %d) = -1\n", domain, type, protocol));
-    set_errno(EINVAL);
-    return -1;
-  }
-
-  if (!conn) {
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("-1 / ENOBUFS (could not create netconn)\n"));
-    set_errno(ENOBUFS);
-    return -1;
-  }
-
-  i = alloc_socket(conn);
-
-  if (i == -1) {
-    netconn_delete(conn);
-  set_errno(ENOBUFS);
-  return -1;
-  }
-  conn->socket = i;
-  LWIP_DEBUGF(SOCKETS_DEBUG, ("%d\n", i));
-  set_errno(0);
-  return i;
-}
-
-int
-lwip_write(int s, void *data, int size)
-{
-   return lwip_send(s, data, size, 0);
-}
-
-
-static int
-lwip_selscan(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset)
-{
-    int i, nready = 0;
-    fd_set lreadset, lwriteset, lexceptset;
-    struct lwip_socket *p_sock;
-
-    FD_ZERO(&lreadset);
-    FD_ZERO(&lwriteset);
-    FD_ZERO(&lexceptset);
-
-    /* Go through each socket in each list to count number of sockets which
-       currently match */
-    for(i = 0; i < maxfdp1; i++)
-    {
-        if (FD_ISSET(i, readset))
-        {
-            /* See if netconn of this socket is ready for read */
-            p_sock = get_socket(i);
-            if (p_sock && (p_sock->lastdata || p_sock->rcvevent))
-            {
-                FD_SET(i, &lreadset);
-               LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for reading\n", i));
-                nready++;
-            }
-        }
-        if (FD_ISSET(i, writeset))
-        {
-            /* See if netconn of this socket is ready for write */
-            p_sock = get_socket(i);
-            if (p_sock && p_sock->sendevent)
-            {
-                FD_SET(i, &lwriteset);
-               LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for writing\n", i));
-                nready++;
-            }
-        }
-    }
-    *readset = lreadset;
-    *writeset = lwriteset;
-    FD_ZERO(exceptset);
-
-    return nready;
-}
-
-
-
-int
-lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
-               struct timeval *timeout)
-{
-    int i;
-    int nready;
-    fd_set lreadset, lwriteset, lexceptset;
-    u32_t msectimeout;
-    struct lwip_select_cb select_cb;
-    struct lwip_select_cb *p_selcb;
-
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select(%d, %p, %p, %p, tvsec=%ld tvusec=%ld)\n", maxfdp1, (void *)readset, (void *) writeset, (void *) exceptset, timeout ? timeout->tv_sec : -1L, timeout ? timeout->tv_usec : -1L));
-
-    select_cb.next = 0;
-    select_cb.readset = readset;
-    select_cb.writeset = writeset;
-    select_cb.exceptset = exceptset;
-    select_cb.sem_signalled = 0;
-
-    /* Protect ourselves searching through the list */
-    if (!selectsem)
-        selectsem = sys_sem_new(1);
-    sys_sem_wait(selectsem);
-
-    if (readset)
-        lreadset = *readset;
-    else
-        FD_ZERO(&lreadset);
-    if (writeset)
-        lwriteset = *writeset;
-    else
-        FD_ZERO(&lwriteset);
-    if (exceptset)
-        lexceptset = *exceptset;
-    else
-        FD_ZERO(&lexceptset);
-
-    /* Go through each socket in each list to count number of sockets which
-       currently match */
-    nready = lwip_selscan(maxfdp1, &lreadset, &lwriteset, &lexceptset);
-
-    /* If we don't have any current events, then suspend if we are supposed to */
-    if (!nready)
-    {
-        if (timeout && timeout->tv_sec == 0 && timeout->tv_usec == 0)
-        {
-            sys_sem_signal(selectsem);
-            if (readset)
-                FD_ZERO(readset);
-            if (writeset)
-                FD_ZERO(writeset);
-            if (exceptset)
-                FD_ZERO(exceptset);
-
-           LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: no timeout, returning 0\n"));
-           set_errno(0);
-
-            return 0;
-        }
-
-        /* add our semaphore to list */
-        /* We don't actually need any dynamic memory. Our entry on the
-         * list is only valid while we are in this function, so it's ok
-         * to use local variables */
-
-        select_cb.sem = sys_sem_new(0);
-        /* Note that we are still protected */
-        /* Put this select_cb on top of list */
-        select_cb.next = select_cb_list;
-        select_cb_list = &select_cb;
-
-        /* Now we can safely unprotect */
-        sys_sem_signal(selectsem);
-
-        /* Now just wait to be woken */
-        if (timeout == 0)
-            /* Wait forever */
-            msectimeout = 0;
-        else
-            msectimeout =  ((timeout->tv_sec * 1000) + ((timeout->tv_usec + 500)/1000));
-
-        i = sys_sem_wait_timeout(select_cb.sem, msectimeout);
-
-        /* Take us off the list */
-        sys_sem_wait(selectsem);
-        if (select_cb_list == &select_cb)
-            select_cb_list = select_cb.next;
-        else
-            for (p_selcb = select_cb_list; p_selcb; p_selcb = p_selcb->next)
-                if (p_selcb->next == &select_cb)
-                {
-                    p_selcb->next = select_cb.next;
-                    break;
-                }
-
-        sys_sem_signal(selectsem);
-
-        sys_sem_free(select_cb.sem);
-        if (i == 0)             /* Timeout */
-        {
-            if (readset)
-                FD_ZERO(readset);
-            if (writeset)
-                FD_ZERO(writeset);
-            if (exceptset)
-                FD_ZERO(exceptset);
-
-           LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: timeout expired\n"));
-           set_errno(0);
-
-            return 0;
-        }
-
-        if (readset)
-            lreadset = *readset;
-        else
-            FD_ZERO(&lreadset);
-        if (writeset)
-            lwriteset = *writeset;
-        else
-            FD_ZERO(&lwriteset);
-        if (exceptset)
-            lexceptset = *exceptset;
-        else
-            FD_ZERO(&lexceptset);
-
-        /* See what's set */
-        nready = lwip_selscan(maxfdp1, &lreadset, &lwriteset, &lexceptset);
-    }
-    else
-        sys_sem_signal(selectsem);
-
-    if (readset)
-        *readset = lreadset;
-    if (writeset)
-        *writeset = lwriteset;
-    if (exceptset)
-        *exceptset = lexceptset;
-
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: nready=%d\n", nready));
-    set_errno(0);
-
-    return nready;
-}
-
-
-static void
-event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len)
-{
-    int s;
-    struct lwip_socket *sock;
-    struct lwip_select_cb *scb;
-
-    /* Get socket */
-    if (conn)
-    {
-        s = conn->socket;
-        if (s < 0)
-        {
-            /* Data comes in right away after an accept, even though
-             * the server task might not have created a new socket yet.
-             * Just count down (or up) if that's the case and we
-             * will use the data later. Note that only receive events
-             * can happen before the new socket is set up. */
-            if (evt == NETCONN_EVT_RCVPLUS)
-                conn->socket--;
-            return;
-        }
-
-        sock = get_socket(s);
-        if (!sock)
-            return;
-    }
-    else
-        return;
-
-    if (!selectsem)
-        selectsem = sys_sem_new(1);
-
-    sys_sem_wait(selectsem);
-    /* Set event as required */
-    switch (evt)
-    {
-      case NETCONN_EVT_RCVPLUS:
-        sock->rcvevent++;
-        break;
-      case NETCONN_EVT_RCVMINUS:
-        sock->rcvevent--;
-        break;
-      case NETCONN_EVT_SENDPLUS:
-        sock->sendevent = 1;
-        break;
-      case NETCONN_EVT_SENDMINUS:
-        sock->sendevent = 0;
-        break;
-    }
-    sys_sem_signal(selectsem);
-
-    /* Now decide if anyone is waiting for this socket */
-    /* NOTE: This code is written this way to protect the select link list
-       but to avoid a deadlock situation by releasing socksem before
-       signalling for the select. This means we need to go through the list
-       multiple times ONLY IF a select was actually waiting. We go through
-       the list the number of waiting select calls + 1. This list is
-       expected to be small. */
-    while (1)
-    {
-        sys_sem_wait(selectsem);
-        for (scb = select_cb_list; scb; scb = scb->next)
-        {
-            if (scb->sem_signalled == 0)
-            {
-                /* Test this select call for our socket */
-                if (scb->readset && FD_ISSET(s, scb->readset))
-                    if (sock->rcvevent)
-                        break;
-                if (scb->writeset && FD_ISSET(s, scb->writeset))
-                    if (sock->sendevent)
-                        break;
-            }
-        }
-        if (scb)
-        {
-            scb->sem_signalled = 1;
-            sys_sem_signal(selectsem);
-            sys_sem_signal(scb->sem);
-        } else {
-            sys_sem_signal(selectsem);
-            break;
-        }
-    }
-
-}
-
-
-
-
-int lwip_shutdown(int s, int how)
-{
-  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_shutdown(%d, how=%d)\n", s, how));
-  return lwip_close(s); /* XXX temporary hack until proper implementation */
-}
-
-int lwip_getpeername (int s, struct sockaddr *name, socklen_t *namelen)
-{
-  struct lwip_socket *sock;
-  struct sockaddr_in sin;
-  struct ip_addr naddr;
-
-  sock = get_socket(s);
-  if (!sock) {
-    set_errno(EBADF);
-    return -1;
-  }
-
-  memset(&sin, 0, sizeof(sin));
-  sin.sin_len = sizeof(sin);
-  sin.sin_family = AF_INET;
-
-  /* get the IP address and port of the remote host */
-  netconn_peer(sock->conn, &naddr, &sin.sin_port);
-
-  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getpeername(%d, addr=", s));
-  ip_addr_debug_print(SOCKETS_DEBUG, &naddr);
-  LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%d)\n", sin.sin_port));
-
-  sin.sin_port = htons(sin.sin_port);
-  sin.sin_addr.s_addr = naddr.addr;
-
-  if (*namelen > sizeof(sin))
-      *namelen = sizeof(sin);
-
-  memcpy(name, &sin, *namelen);
-  sock_set_errno(sock, 0);
-  return 0;
-}
-
-int lwip_getsockname (int s, struct sockaddr *name, socklen_t *namelen)
-{
-  struct lwip_socket *sock;
-  struct sockaddr_in sin;
-  struct ip_addr *naddr;
-
-  sock = get_socket(s);
-  if (!sock) {
-    set_errno(EBADF);
-    return -1;
-  }
-
-  memset(&sin, 0, sizeof(sin));
-  sin.sin_len = sizeof(sin);
-  sin.sin_family = AF_INET;
-
-  /* get the IP address and port of the remote host */
-  netconn_addr(sock->conn, &naddr, &sin.sin_port);
-
-  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockname(%d, addr=", s));
-  ip_addr_debug_print(SOCKETS_DEBUG, naddr);
-  LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%d)\n", sin.sin_port));
-
-  sin.sin_port = htons(sin.sin_port);
-  sin.sin_addr.s_addr = naddr->addr;
-
-  if (*namelen > sizeof(sin))
-      *namelen = sizeof(sin);
-
-  memcpy(name, &sin, *namelen);
-  sock_set_errno(sock, 0);
-  return 0;
-}
-
-int lwip_getsockopt (int s, int level, int optname, void *optval, socklen_t *optlen)
-{
-  int err = 0;
-  struct lwip_socket *sock = get_socket(s);
-
-  if(!sock) {
-       set_errno(EBADF);
-    return -1;
-  }
-
-  if( NULL == optval || NULL == optlen ) {
-    sock_set_errno( sock, EFAULT );
-    return -1;
-  }
-
-  /* Do length and type checks for the various options first, to keep it readable. */
-  switch( level ) {
-   
-/* Level: SOL_SOCKET */
-  case SOL_SOCKET:
-      switch(optname) {
-         
-      case SO_ACCEPTCONN:
-      case SO_BROADCAST:
-      /* UNIMPL case SO_DEBUG: */
-      /* UNIMPL case SO_DONTROUTE: */
-      case SO_ERROR:
-      case SO_KEEPALIVE:
-      /* UNIMPL case SO_OOBINLINE: */
-      /* UNIMPL case SO_RCVBUF: */
-      /* UNIMPL case SO_SNDBUF: */
-      /* UNIMPL case SO_RCVLOWAT: */
-      /* UNIMPL case SO_SNDLOWAT: */
-#if SO_REUSE
-      case SO_REUSEADDR:
-      case SO_REUSEPORT:
-#endif /* SO_REUSE */
-      case SO_TYPE:
-      /* UNIMPL case SO_USELOOPBACK: */
-        if( *optlen < sizeof(int) ) {
-          err = EINVAL;
-        }
-          break;
-
-      default:
-        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, UNIMPL: optname=0x%x, ..)\n", s, optname));
-        err = ENOPROTOOPT;
-      }  /* switch */
-      break;
-                     
-/* Level: IPPROTO_IP */
-  case IPPROTO_IP:
-      switch(optname) {
-      /* UNIMPL case IP_HDRINCL: */
-      /* UNIMPL case IP_RCVDSTADDR: */
-      /* UNIMPL case IP_RCVIF: */
-      case IP_TTL:
-      case IP_TOS:
-        if( *optlen < sizeof(int) ) {
-          err = EINVAL;
-        }
-        break;
-
-      default:
-        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, UNIMPL: optname=0x%x, ..)\n", s, optname));
-        err = ENOPROTOOPT;
-      }  /* switch */
-      break;
-         
-/* Level: IPPROTO_TCP */
-  case IPPROTO_TCP:
-      if( *optlen < sizeof(int) ) {
-        err = EINVAL;
-        break;
-    }
-      
-      /* If this is no TCP socket, ignore any options. */
-      if ( sock->conn->type != NETCONN_TCP ) return 0;
-
-      switch( optname ) {
-      case TCP_NODELAY:
-      case TCP_KEEPALIVE:
-        break;
-         
-      default:
-        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, UNIMPL: optname=0x%x, ..)\n", s, optname));
-        err = ENOPROTOOPT;
-      }  /* switch */
-      break;
-
-/* UNDEFINED LEVEL */
-  default:
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, level=0x%x, UNIMPL: optname=0x%x, ..)\n", s, level, optname));
-      err = ENOPROTOOPT;
-  }  /* switch */
-
-   
-  if( 0 != err ) {
-    sock_set_errno(sock, err);
-    return -1;
-  }
-   
-
-
-  /* Now do the actual option processing */
-
-  switch(level) {
-   
-/* Level: SOL_SOCKET */
-  case SOL_SOCKET:
-    switch( optname ) {
-
-    /* The option flags */
-    case SO_ACCEPTCONN:
-    case SO_BROADCAST:
-    /* UNIMPL case SO_DEBUG: */
-    /* UNIMPL case SO_DONTROUTE: */
-    case SO_KEEPALIVE:
-    /* UNIMPL case SO_OOBINCLUDE: */
-#if SO_REUSE
-    case SO_REUSEADDR:
-    case SO_REUSEPORT:
-#endif /* SO_REUSE */
-    /*case SO_USELOOPBACK: UNIMPL */
-      *(int*)optval = sock->conn->pcb.tcp->so_options & optname;
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, optname=0x%x, ..) = %s\n", s, optname, (*(int*)optval?"on":"off")));
-      break;
-
-    case SO_TYPE:
-      switch (sock->conn->type) {
-      case NETCONN_RAW:
-        *(int*)optval = SOCK_RAW;
-        break;
-      case NETCONN_TCP:
-        *(int*)optval = SOCK_STREAM;
-        break;
-      case NETCONN_UDP:
-      case NETCONN_UDPLITE:
-      case NETCONN_UDPNOCHKSUM:
-        *(int*)optval = SOCK_DGRAM;
-        break;
-      default: /* unrecognized socket type */
-        *(int*)optval = sock->conn->type;
-        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, SO_TYPE): unrecognized socket type %d\n", s, *(int *)optval));
-      }  /* switch */
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, SO_TYPE) = %d\n", s, *(int *)optval));
-      break;
-
-    case SO_ERROR:
-      *(int *)optval = sock->err;
-      sock->err = 0;
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, SO_ERROR) = %d\n", s, *(int *)optval));
-      break;
-    }  /* switch */
-    break;
-
-/* Level: IPPROTO_IP */
-  case IPPROTO_IP:
-    switch( optname ) {
-    case IP_TTL:
-      *(int*)optval = sock->conn->pcb.tcp->ttl;
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_TTL) = %d\n", s, *(int *)optval));
-      break;
-    case IP_TOS:
-      *(int*)optval = sock->conn->pcb.tcp->tos;
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_TOS) = %d\n", s, *(int *)optval));
-      break;
-    }  /* switch */
-    break;
-
-/* Level: IPPROTO_TCP */
-  case IPPROTO_TCP:
-    switch( optname ) {
-    case TCP_NODELAY:
-      *(int*)optval = (sock->conn->pcb.tcp->flags & TF_NODELAY);
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, TCP_NODELAY) = %s\n", s, (*(int*)optval)?"on":"off") );
-      break;
-    case TCP_KEEPALIVE:
-      *(int*)optval = (int)sock->conn->pcb.tcp->keepalive;
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, TCP_KEEPALIVE) = %d\n", s, *(int *)optval));
-      break;
-    }  /* switch */
-    break;
-  }
-
-
-  sock_set_errno(sock, err);
-  return err ? -1 : 0;
-}
-
-int lwip_setsockopt (int s, int level, int optname, const void *optval, socklen_t optlen)
-{
-  struct lwip_socket *sock = get_socket(s);
-  int err = 0;
-
-  if(!sock) {
-       set_errno(EBADF);
-    return -1;
-  }
-
-  if( NULL == optval ) {
-    sock_set_errno( sock, EFAULT );
-    return -1;
-  }
-
-
-  /* Do length and type checks for the various options first, to keep it readable. */
-  switch( level ) {
-
-/* Level: SOL_SOCKET */
-  case SOL_SOCKET:
-    switch(optname) {
-
-    case SO_BROADCAST:
-    /* UNIMPL case SO_DEBUG: */
-    /* UNIMPL case SO_DONTROUTE: */
-    case SO_KEEPALIVE:
-    /* UNIMPL case SO_OOBINLINE: */
-    /* UNIMPL case SO_RCVBUF: */
-    /* UNIMPL case SO_SNDBUF: */
-    /* UNIMPL case SO_RCVLOWAT: */
-    /* UNIMPL case SO_SNDLOWAT: */
-#if SO_REUSE
-    case SO_REUSEADDR:
-    case SO_REUSEPORT:
-#endif /* SO_REUSE */
-    /* UNIMPL case SO_USELOOPBACK: */
-      if( optlen < sizeof(int) ) {
-        err = EINVAL;
-      }
-      break;
-    default:
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, SOL_SOCKET, UNIMPL: optname=0x%x, ..)\n", s, optname));
-      err = ENOPROTOOPT;
-    }  /* switch */
-    break;
-
-/* Level: IPPROTO_IP */
-  case IPPROTO_IP:
-    switch(optname) {
-    /* UNIMPL case IP_HDRINCL: */
-    /* UNIMPL case IP_RCVDSTADDR: */
-    /* UNIMPL case IP_RCVIF: */
-    case IP_TTL:
-    case IP_TOS:
-      if( optlen < sizeof(int) ) {
-        err = EINVAL;
-      }
-        break;
-      default:
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, UNIMPL: optname=0x%x, ..)\n", s, optname));
-      err = ENOPROTOOPT;
-    }  /* switch */
-    break;
-
-/* Level: IPPROTO_TCP */
-  case IPPROTO_TCP:
-    if( optlen < sizeof(int) ) {
-      err = EINVAL;
-        break;
-    }
-
-    /* If this is no TCP socket, ignore any options. */
-    if ( sock->conn->type != NETCONN_TCP ) return 0;
-
-    switch( optname ) {
-    case TCP_NODELAY:
-    case TCP_KEEPALIVE:
-      break;
-
-    default:
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, UNIMPL: optname=0x%x, ..)\n", s, optname));
-      err = ENOPROTOOPT;
-    }  /* switch */
-    break;
-
-/* UNDEFINED LEVEL */      
-  default:
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, level=0x%x, UNIMPL: optname=0x%x, ..)\n", s, level, optname));
-    err = ENOPROTOOPT;
-  }  /* switch */
-
-
-  if( 0 != err ) {
-    sock_set_errno(sock, err);
-    return -1;
-  }
-
-
-
-  /* Now do the actual option processing */
-
-  switch(level) {
-
-/* Level: SOL_SOCKET */
-  case SOL_SOCKET:
-    switch(optname) {
-
-    /* The option flags */
-    case SO_BROADCAST:
-    /* UNIMPL case SO_DEBUG: */
-    /* UNIMPL case SO_DONTROUTE: */
-    case SO_KEEPALIVE:
-    /* UNIMPL case SO_OOBINCLUDE: */
-#if SO_REUSE
-    case SO_REUSEADDR:
-    case SO_REUSEPORT:
-#endif /* SO_REUSE */
-    /* UNIMPL case SO_USELOOPBACK: */
-      if ( *(int*)optval ) {
-        sock->conn->pcb.tcp->so_options |= optname;
-      } else {
-        sock->conn->pcb.tcp->so_options &= ~optname;
-      }
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, SOL_SOCKET, optname=0x%x, ..) -> %s\n", s, optname, (*(int*)optval?"on":"off")));
-      break;
-    }  /* switch */
-    break;
-
-/* Level: IPPROTO_IP */
-  case IPPROTO_IP:
-    switch( optname ) {
-    case IP_TTL:
-      sock->conn->pcb.tcp->ttl = (u8_t)(*(int*)optval);
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, IP_TTL, ..) -> %u\n", s, sock->conn->pcb.tcp->ttl));
-      break;
-    case IP_TOS:
-      sock->conn->pcb.tcp->tos = (u8_t)(*(int*)optval);
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, IP_TOS, ..)-> %u\n", s, sock->conn->pcb.tcp->tos));
-      break;
-    }  /* switch */
-    break;
-
-/* Level: IPPROTO_TCP */
-  case IPPROTO_TCP:
-    switch( optname ) {
-    case TCP_NODELAY:
-      if ( *(int*)optval ) {
-        sock->conn->pcb.tcp->flags |= TF_NODELAY;
-      } else {
-        sock->conn->pcb.tcp->flags &= ~TF_NODELAY;
-      }
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_NODELAY) -> %s\n", s, (*(int *)optval)?"on":"off") );
-      break;
-    case TCP_KEEPALIVE:
-      sock->conn->pcb.tcp->keepalive = (u32_t)(*(int*)optval);
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPALIVE) -> %lu\n", s, sock->conn->pcb.tcp->keepalive));
-      break;
-    }  /* switch */
-    break;
-  }  /* switch */
-
-  sock_set_errno(sock, err);
-  return err ? -1 : 0;
-}
-
-int lwip_ioctl(int s, long cmd, void *argp)
-{
-  struct lwip_socket *sock = get_socket(s);
-
-  if(!sock) {
-       set_errno(EBADF);
-    return -1;
-  }
-
-  switch (cmd) {
-  case FIONREAD:
-    if (!argp) {
-      sock_set_errno(sock, EINVAL);
-      return -1;
-    }
-
-    *((u16_t*)argp) = sock->conn->recv_avail;
-
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, FIONREAD, %p) = %u\n", s, argp, *((u16_t*)argp)));
-    sock_set_errno(sock, 0);
-    return 0;
-
-  case FIONBIO:
-    if (argp && *(u32_t*)argp)
-      sock->flags |= O_NONBLOCK;
-    else
-      sock->flags &= ~O_NONBLOCK;
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, FIONBIO, %d)\n", s, !!(sock->flags & O_NONBLOCK)));
-    sock_set_errno(sock, 0);
-    return 0;
-
-  default:
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, UNIMPL: 0x%lx, %p)\n", s, cmd, argp));
-    sock_set_errno(sock, ENOSYS); /* not yet implemented */
-    return -1;
-  }
-}
-
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without modification,\r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED\r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT\r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY\r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ *\r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ * Improved by Marc Boucher <marc@mbsi.ca> and David Haas <dhaas@alum.rpi.edu>\r
+ *\r
+ */\r
+\r
+#include <string.h>\r
+#include <errno.h>\r
+\r
+#include "lwip/opt.h"\r
+#include "lwip/api.h"\r
+#include "lwip/arch.h"\r
+#include "lwip/sys.h"\r
+\r
+#include "lwip/sockets.h"\r
+\r
+#define NUM_SOCKETS MEMP_NUM_NETCONN\r
+\r
+struct lwip_socket {\r
+  struct netconn *conn;\r
+  struct netbuf *lastdata;\r
+  u16_t lastoffset;\r
+  u16_t rcvevent;\r
+  u16_t sendevent;\r
+  u16_t  flags;\r
+  int err;\r
+};\r
+\r
+struct lwip_select_cb\r
+{\r
+    struct lwip_select_cb *next;\r
+    fd_set *readset;\r
+    fd_set *writeset;\r
+    fd_set *exceptset;\r
+    int sem_signalled;\r
+    sys_sem_t sem;\r
+};\r
+\r
+static struct lwip_socket sockets[NUM_SOCKETS];\r
+static struct lwip_select_cb *select_cb_list = 0;\r
+\r
+static sys_sem_t socksem = 0;\r
+static sys_sem_t selectsem = 0;\r
+\r
+static void\r
+event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len);\r
+\r
+static int err_to_errno_table[11] = {\r
+    0,      /* ERR_OK    0      No error, everything OK. */\r
+    ENOMEM,    /* ERR_MEM  -1      Out of memory error.     */\r
+    ENOBUFS,    /* ERR_BUF  -2      Buffer error.            */\r
+    ECONNABORTED,  /* ERR_ABRT -3      Connection aborted.      */\r
+    ECONNRESET,    /* ERR_RST  -4      Connection reset.        */\r
+    ESHUTDOWN,    /* ERR_CLSD -5      Connection closed.       */\r
+    ENOTCONN,    /* ERR_CONN -6      Not connected.           */\r
+    EINVAL,    /* ERR_VAL  -7      Illegal value.           */\r
+    EIO,    /* ERR_ARG  -8      Illegal argument.        */\r
+    EHOSTUNREACH,  /* ERR_RTE  -9      Routing problem.         */\r
+    EADDRINUSE    /* ERR_USE  -10     Address in use.          */\r
+};\r
+\r
+#define ERR_TO_ERRNO_TABLE_SIZE \\r
+  (sizeof(err_to_errno_table)/sizeof(err_to_errno_table[0]))\r
+\r
+#define err_to_errno(err) \\r
+  (-(err) >= 0 && -(err) < ERR_TO_ERRNO_TABLE_SIZE ? \\r
+    err_to_errno_table[-(err)] : EIO)\r
+\r
+#ifdef ERRNO\r
+#define set_errno(err) errno = (err)\r
+#else\r
+#define set_errno(err)\r
+#endif\r
+\r
+#define sock_set_errno(sk, e) do { \\r
+      sk->err = (e); \\r
+      set_errno(sk->err); \\r
+} while (0)\r
+\r
+\r
+static struct lwip_socket *\r
+get_socket(int s)\r
+{\r
+  struct lwip_socket *sock;\r
+\r
+  if ((s < 0) || (s > NUM_SOCKETS)) {\r
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("get_socket(%d): invalid\n", s));\r
+    set_errno(EBADF);\r
+    return NULL;\r
+  }\r
+\r
+  sock = &sockets[s];\r
+\r
+  if (!sock->conn) {\r
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("get_socket(%d): not active\n", s));\r
+    set_errno(EBADF);\r
+    return NULL;\r
+  }\r
+\r
+  return sock;\r
+}\r
+\r
+static int\r
+alloc_socket(struct netconn *newconn)\r
+{\r
+  int i;\r
+\r
+  if (!socksem)\r
+      socksem = sys_sem_new(1);\r
+\r
+  /* Protect socket array */\r
+  sys_sem_wait(socksem);\r
+\r
+  /* allocate a new socket identifier */\r
+  for(i = 0; i < NUM_SOCKETS; ++i) {\r
+    if (!sockets[i].conn) {\r
+      sockets[i].conn = newconn;\r
+      sockets[i].lastdata = NULL;\r
+      sockets[i].lastoffset = 0;\r
+      sockets[i].rcvevent = 0;\r
+      sockets[i].sendevent = 1; /* TCP send buf is empty */\r
+      sockets[i].flags = 0;\r
+      sockets[i].err = 0;\r
+      sys_sem_signal(socksem);\r
+      return i;\r
+    }\r
+  }\r
+  sys_sem_signal(socksem);\r
+  return -1;\r
+}\r
+\r
+int\r
+lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen)\r
+{\r
+  struct lwip_socket *sock;\r
+  struct netconn *newconn;\r
+  struct ip_addr naddr;\r
+  u16_t port;\r
+  int newsock;\r
+  struct sockaddr_in sin;\r
+\r
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d)...\n", s));\r
+  sock = get_socket(s);\r
+  if (!sock) {\r
+    set_errno(EBADF);\r
+    return -1;\r
+  }\r
+\r
+  newconn = netconn_accept(sock->conn);\r
+\r
+  /* get the IP address and port of the remote host */\r
+  netconn_peer(newconn, &naddr, &port);\r
+\r
+  memset(&sin, 0, sizeof(sin));\r
+  sin.sin_len = sizeof(sin);\r
+  sin.sin_family = AF_INET;\r
+  sin.sin_port = htons(port);\r
+  sin.sin_addr.s_addr = naddr.addr;\r
+\r
+  if (*addrlen > sizeof(sin))\r
+      *addrlen = sizeof(sin);\r
+\r
+  memcpy(addr, &sin, *addrlen);\r
+\r
+  newsock = alloc_socket(newconn);\r
+  if (newsock == -1) {\r
+    netconn_delete(newconn);\r
+  sock_set_errno(sock, ENOBUFS);\r
+  return -1;\r
+  }\r
+  newconn->callback = event_callback;\r
+  sock = get_socket(newsock);\r
+\r
+  sys_sem_wait(socksem);\r
+  sock->rcvevent += -1 - newconn->socket;\r
+  newconn->socket = newsock;\r
+  sys_sem_signal(socksem);\r
+\r
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d) returning new sock=%d addr=", s, newsock));\r
+  ip_addr_debug_print(SOCKETS_DEBUG, &naddr);\r
+  LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u\n", port));\r
+\r
+  sock_set_errno(sock, 0);\r
+  return newsock;\r
+}\r
+\r
+int\r
+lwip_bind(int s, struct sockaddr *name, socklen_t namelen)\r
+{\r
+  struct lwip_socket *sock;\r
+  struct ip_addr local_addr;\r
+  u16_t local_port;\r
+  err_t err;\r
+\r
+  sock = get_socket(s);\r
+  if (!sock) {\r
+    set_errno(EBADF);\r
+    return -1;\r
+  }\r
+\r
+  local_addr.addr = ((struct sockaddr_in *)name)->sin_addr.s_addr;\r
+  local_port = ((struct sockaddr_in *)name)->sin_port;\r
+\r
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d, addr=", s));\r
+  ip_addr_debug_print(SOCKETS_DEBUG, &local_addr);\r
+  LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u)\n", ntohs(local_port)));\r
+\r
+  err = netconn_bind(sock->conn, &local_addr, ntohs(local_port));\r
+\r
+  if (err != ERR_OK) {\r
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d) failed, err=%d\n", s, err));\r
+    sock_set_errno(sock, err_to_errno(err));\r
+    return -1;\r
+  }\r
+\r
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d) succeeded\n", s));\r
+  sock_set_errno(sock, 0);\r
+  return 0;\r
+}\r
+\r
+int\r
+lwip_close(int s)\r
+{\r
+  struct lwip_socket *sock;\r
+\r
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_close(%d)\n", s));\r
+  if (!socksem)\r
+      socksem = sys_sem_new(1);\r
+\r
+  /* We cannot allow multiple closes of the same socket. */\r
+  sys_sem_wait(socksem);\r
+\r
+  sock = get_socket(s);\r
+  if (!sock) {\r
+      sys_sem_signal(socksem);\r
+      set_errno(EBADF);\r
+      return -1;\r
+  }\r
+\r
+  netconn_delete(sock->conn);\r
+  if (sock->lastdata) {\r
+    netbuf_delete(sock->lastdata);\r
+  }\r
+  sock->lastdata = NULL;\r
+  sock->lastoffset = 0;\r
+  sock->conn = NULL;\r
+  sys_sem_signal(socksem);\r
+  sock_set_errno(sock, 0);\r
+  return 0;\r
+}\r
+\r
+int\r
+lwip_connect(int s, struct sockaddr *name, socklen_t namelen)\r
+{\r
+  struct lwip_socket *sock;\r
+  err_t err;\r
+\r
+  sock = get_socket(s);\r
+  if (!sock) {\r
+    set_errno(EBADF);\r
+    return -1;\r
+  }\r
+\r
+  if (((struct sockaddr_in *)name)->sin_family == AF_UNSPEC) {\r
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, AF_UNSPEC)\n", s));\r
+    err = netconn_disconnect(sock->conn);\r
+  } else {\r
+    struct ip_addr remote_addr;\r
+    u16_t remote_port;\r
+\r
+    remote_addr.addr = ((struct sockaddr_in *)name)->sin_addr.s_addr;\r
+    remote_port = ((struct sockaddr_in *)name)->sin_port;\r
+\r
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, addr=", s));\r
+    ip_addr_debug_print(SOCKETS_DEBUG, &remote_addr);\r
+    LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u)\n", ntohs(remote_port)));\r
+\r
+    err = netconn_connect(sock->conn, &remote_addr, ntohs(remote_port));\r
+   }\r
+\r
+  if (err != ERR_OK) {\r
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d) failed, err=%d\n", s, err));\r
+    sock_set_errno(sock, err_to_errno(err));\r
+    return -1;\r
+  }\r
+\r
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d) succeeded\n", s));\r
+  sock_set_errno(sock, 0);\r
+  return 0;\r
+}\r
+\r
+int\r
+lwip_listen(int s, int backlog)\r
+{\r
+  struct lwip_socket *sock;\r
+  err_t err;\r
+\r
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_listen(%d, backlog=%d)\n", s, backlog));\r
+  sock = get_socket(s);\r
+  if (!sock) {\r
+    set_errno(EBADF);\r
+    return -1;\r
+  }\r
+\r
+  err = netconn_listen(sock->conn);\r
+\r
+  if (err != ERR_OK) {\r
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_listen(%d) failed, err=%d\n", s, err));\r
+    sock_set_errno(sock, err_to_errno(err));\r
+    return -1;\r
+  }\r
+\r
+  sock_set_errno(sock, 0);\r
+  return 0;\r
+}\r
+\r
+int\r
+lwip_recvfrom(int s, void *mem, int len, unsigned int flags,\r
+        struct sockaddr *from, socklen_t *fromlen)\r
+{\r
+  struct lwip_socket *sock;\r
+  struct netbuf *buf;\r
+  u16_t buflen, copylen;\r
+  struct ip_addr *addr;\r
+  u16_t port;\r
+\r
+\r
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d, %p, %d, 0x%x, ..)\n", s, mem, len, flags));\r
+  sock = get_socket(s);\r
+  if (!sock) {\r
+    set_errno(EBADF);\r
+    return -1;\r
+  }\r
+\r
+  /* Check if there is data left from the last recv operation. */\r
+  if (sock->lastdata) {\r
+    buf = sock->lastdata;\r
+  } else {\r
+    /* If this is non-blocking call, then check first */\r
+    if (((flags & MSG_DONTWAIT) || (sock->flags & O_NONBLOCK))\r
+  && !sock->rcvevent)\r
+    {\r
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): returning EWOULDBLOCK\n", s));\r
+      sock_set_errno(sock, EWOULDBLOCK);\r
+      return -1;\r
+    }\r
+\r
+    /* No data was left from the previous operation, so we try to get\r
+       some from the network. */\r
+    buf = netconn_recv(sock->conn);\r
+\r
+    if (!buf) {\r
+      /* We should really do some error checking here. */\r
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): buf == NULL!\n", s));\r
+      sock_set_errno(sock, 0);\r
+      return 0;\r
+    }\r
+  }\r
+\r
+  buflen = netbuf_len(buf);\r
+\r
+  buflen -= sock->lastoffset;\r
+\r
+  if (len > buflen) {\r
+    copylen = buflen;\r
+  } else {\r
+    copylen = len;\r
+  }\r
+\r
+  /* copy the contents of the received buffer into\r
+     the supplied memory pointer mem */\r
+  netbuf_copy_partial(buf, mem, copylen, sock->lastoffset);\r
+\r
+  /* Check to see from where the data was. */\r
+  if (from && fromlen) {\r
+    struct sockaddr_in sin;\r
+\r
+    addr = netbuf_fromaddr(buf);\r
+    port = netbuf_fromport(buf);\r
+\r
+    memset(&sin, 0, sizeof(sin));\r
+    sin.sin_len = sizeof(sin);\r
+    sin.sin_family = AF_INET;\r
+    sin.sin_port = htons(port);\r
+    sin.sin_addr.s_addr = addr->addr;\r
+\r
+    if (*fromlen > sizeof(sin))\r
+      *fromlen = sizeof(sin);\r
+\r
+    memcpy(from, &sin, *fromlen);\r
+\r
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): addr=", s));\r
+    ip_addr_debug_print(SOCKETS_DEBUG, addr);\r
+    LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u len=%u\n", port, copylen));\r
+  } else {\r
+#if SOCKETS_DEBUG\r
+    addr = netbuf_fromaddr(buf);\r
+    port = netbuf_fromport(buf);\r
+\r
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): addr=", s));\r
+    ip_addr_debug_print(SOCKETS_DEBUG, addr);\r
+    LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u len=%u\n", port, copylen));\r
+#endif\r
+\r
+  }\r
+\r
+  /* If this is a TCP socket, check if there is data left in the\r
+     buffer. If so, it should be saved in the sock structure for next\r
+     time around. */\r
+  if (netconn_type(sock->conn) == NETCONN_TCP && buflen - copylen > 0) {\r
+    sock->lastdata = buf;\r
+    sock->lastoffset += copylen;\r
+  } else {\r
+    sock->lastdata = NULL;\r
+    sock->lastoffset = 0;\r
+    netbuf_delete(buf);\r
+  }\r
+\r
+\r
+  sock_set_errno(sock, 0);\r
+  return copylen;\r
+}\r
+\r
+int\r
+lwip_read(int s, void *mem, int len)\r
+{\r
+  return lwip_recvfrom(s, mem, len, 0, NULL, NULL);\r
+}\r
+\r
+int\r
+lwip_recv(int s, void *mem, int len, unsigned int flags)\r
+{\r
+  return lwip_recvfrom(s, mem, len, flags, NULL, NULL);\r
+}\r
+\r
+int\r
+lwip_send(int s, void *data, int size, unsigned int flags)\r
+{\r
+  struct lwip_socket *sock;\r
+  struct netbuf *buf;\r
+  err_t err;\r
+\r
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d, data=%p, size=%d, flags=0x%x)\n", s, data, size, flags));\r
+\r
+  sock = get_socket(s);\r
+  if (!sock) {\r
+    set_errno(EBADF);\r
+    return -1;\r
+  }\r
+\r
+  switch (netconn_type(sock->conn)) {\r
+  case NETCONN_RAW:\r
+  case NETCONN_UDP:\r
+  case NETCONN_UDPLITE:\r
+  case NETCONN_UDPNOCHKSUM:\r
+    /* create a buffer */\r
+    buf = netbuf_new();\r
+\r
+    if (!buf) {\r
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) ENOBUFS\n", s));\r
+      sock_set_errno(sock, ENOBUFS);\r
+      return -1;\r
+    }\r
+\r
+    /* make the buffer point to the data that should\r
+       be sent */\r
+    netbuf_ref(buf, data, size);\r
+\r
+    /* send the data */\r
+    err = netconn_send(sock->conn, buf);\r
+\r
+    /* deallocated the buffer */\r
+    netbuf_delete(buf);\r
+    break;\r
+  case NETCONN_TCP:\r
+    err = netconn_write(sock->conn, data, size, NETCONN_COPY);\r
+    break;\r
+  default:\r
+    err = ERR_ARG;\r
+    break;\r
+  }\r
+  if (err != ERR_OK) {\r
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) err=%d\n", s, err));\r
+    sock_set_errno(sock, err_to_errno(err));\r
+    return -1;\r
+  }\r
+\r
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) ok size=%d\n", s, size));\r
+  sock_set_errno(sock, 0);\r
+  return size;\r
+}\r
+\r
+int\r
+lwip_sendto(int s, void *data, int size, unsigned int flags,\r
+       struct sockaddr *to, socklen_t tolen)\r
+{\r
+  struct lwip_socket *sock;\r
+  struct ip_addr remote_addr, addr;\r
+  u16_t remote_port, port;\r
+  int ret,connected;\r
+\r
+  sock = get_socket(s);\r
+  if (!sock) {\r
+    set_errno(EBADF);\r
+    return -1;\r
+  }\r
+\r
+  /* get the peer if currently connected */\r
+  connected = (netconn_peer(sock->conn, &addr, &port) == ERR_OK);\r
+\r
+  remote_addr.addr = ((struct sockaddr_in *)to)->sin_addr.s_addr;\r
+  remote_port = ((struct sockaddr_in *)to)->sin_port;\r
+\r
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_sendto(%d, data=%p, size=%d, flags=0x%x to=", s, data, size, flags));\r
+  ip_addr_debug_print(SOCKETS_DEBUG, &remote_addr);\r
+  LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u\n", ntohs(remote_port)));\r
+\r
+  netconn_connect(sock->conn, &remote_addr, ntohs(remote_port));\r
+\r
+  ret = lwip_send(s, data, size, flags);\r
+\r
+  /* reset the remote address and port number\r
+     of the connection */\r
+  if (connected)\r
+    netconn_connect(sock->conn, &addr, port);\r
+  else\r
+  netconn_disconnect(sock->conn);\r
+  return ret;\r
+}\r
+\r
+int\r
+lwip_socket(int domain, int type, int protocol)\r
+{\r
+  struct netconn *conn;\r
+  int i;\r
+\r
+  /* create a netconn */\r
+  switch (type) {\r
+  case SOCK_RAW:\r
+    conn = netconn_new_with_proto_and_callback(NETCONN_RAW, protocol, event_callback);\r
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_RAW, %d) = ", domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol));\r
+    break;\r
+  case SOCK_DGRAM:\r
+    conn = netconn_new_with_callback(NETCONN_UDP, event_callback);\r
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_DGRAM, %d) = ", domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol));\r
+    break;\r
+  case SOCK_STREAM:\r
+    conn = netconn_new_with_callback(NETCONN_TCP, event_callback);\r
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_STREAM, %d) = ", domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol));\r
+    break;\r
+  default:\r
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%d, %d/UNKNOWN, %d) = -1\n", domain, type, protocol));\r
+    set_errno(EINVAL);\r
+    return -1;\r
+  }\r
+\r
+  if (!conn) {\r
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("-1 / ENOBUFS (could not create netconn)\n"));\r
+    set_errno(ENOBUFS);\r
+    return -1;\r
+  }\r
+\r
+  i = alloc_socket(conn);\r
+\r
+  if (i == -1) {\r
+    netconn_delete(conn);\r
+  set_errno(ENOBUFS);\r
+  return -1;\r
+  }\r
+  conn->socket = i;\r
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("%d\n", i));\r
+  set_errno(0);\r
+  return i;\r
+}\r
+\r
+int\r
+lwip_write(int s, void *data, int size)\r
+{\r
+   return lwip_send(s, data, size, 0);\r
+}\r
+\r
+\r
+static int\r
+lwip_selscan(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset)\r
+{\r
+    int i, nready = 0;\r
+    fd_set lreadset, lwriteset, lexceptset;\r
+    struct lwip_socket *p_sock;\r
+\r
+    FD_ZERO(&lreadset);\r
+    FD_ZERO(&lwriteset);\r
+    FD_ZERO(&lexceptset);\r
+\r
+    /* Go through each socket in each list to count number of sockets which\r
+       currently match */\r
+    for(i = 0; i < maxfdp1; i++)\r
+    {\r
+        if (FD_ISSET(i, readset))\r
+        {\r
+            /* See if netconn of this socket is ready for read */\r
+            p_sock = get_socket(i);\r
+            if (p_sock && (p_sock->lastdata || p_sock->rcvevent))\r
+            {\r
+                FD_SET(i, &lreadset);\r
+               LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for reading\n", i));\r
+                nready++;\r
+            }\r
+        }\r
+        if (FD_ISSET(i, writeset))\r
+        {\r
+            /* See if netconn of this socket is ready for write */\r
+            p_sock = get_socket(i);\r
+            if (p_sock && p_sock->sendevent)\r
+            {\r
+                FD_SET(i, &lwriteset);\r
+               LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for writing\n", i));\r
+                nready++;\r
+            }\r
+        }\r
+    }\r
+    *readset = lreadset;\r
+    *writeset = lwriteset;\r
+    FD_ZERO(exceptset);\r
+\r
+    return nready;\r
+}\r
+\r
+\r
+\r
+int\r
+lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,\r
+               struct timeval *timeout)\r
+{\r
+    int i;\r
+    int nready;\r
+    fd_set lreadset, lwriteset, lexceptset;\r
+    u32_t msectimeout;\r
+    struct lwip_select_cb select_cb;\r
+    struct lwip_select_cb *p_selcb;\r
+\r
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select(%d, %p, %p, %p, tvsec=%ld tvusec=%ld)\n", maxfdp1, (void *)readset, (void *) writeset, (void *) exceptset, timeout ? timeout->tv_sec : -1L, timeout ? timeout->tv_usec : -1L));\r
+\r
+    select_cb.next = 0;\r
+    select_cb.readset = readset;\r
+    select_cb.writeset = writeset;\r
+    select_cb.exceptset = exceptset;\r
+    select_cb.sem_signalled = 0;\r
+\r
+    /* Protect ourselves searching through the list */\r
+    if (!selectsem)\r
+        selectsem = sys_sem_new(1);\r
+    sys_sem_wait(selectsem);\r
+\r
+    if (readset)\r
+        lreadset = *readset;\r
+    else\r
+        FD_ZERO(&lreadset);\r
+    if (writeset)\r
+        lwriteset = *writeset;\r
+    else\r
+        FD_ZERO(&lwriteset);\r
+    if (exceptset)\r
+        lexceptset = *exceptset;\r
+    else\r
+        FD_ZERO(&lexceptset);\r
+\r
+    /* Go through each socket in each list to count number of sockets which\r
+       currently match */\r
+    nready = lwip_selscan(maxfdp1, &lreadset, &lwriteset, &lexceptset);\r
+\r
+    /* If we don't have any current events, then suspend if we are supposed to */\r
+    if (!nready)\r
+    {\r
+        if (timeout && timeout->tv_sec == 0 && timeout->tv_usec == 0)\r
+        {\r
+            sys_sem_signal(selectsem);\r
+            if (readset)\r
+                FD_ZERO(readset);\r
+            if (writeset)\r
+                FD_ZERO(writeset);\r
+            if (exceptset)\r
+                FD_ZERO(exceptset);\r
+\r
+           LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: no timeout, returning 0\n"));\r
+           set_errno(0);\r
+\r
+            return 0;\r
+        }\r
+\r
+        /* add our semaphore to list */\r
+        /* We don't actually need any dynamic memory. Our entry on the\r
+         * list is only valid while we are in this function, so it's ok\r
+         * to use local variables */\r
+\r
+        select_cb.sem = sys_sem_new(0);\r
+        /* Note that we are still protected */\r
+        /* Put this select_cb on top of list */\r
+        select_cb.next = select_cb_list;\r
+        select_cb_list = &select_cb;\r
+\r
+        /* Now we can safely unprotect */\r
+        sys_sem_signal(selectsem);\r
+\r
+        /* Now just wait to be woken */\r
+        if (timeout == 0)\r
+            /* Wait forever */\r
+            msectimeout = 0;\r
+        else\r
+            msectimeout =  ((timeout->tv_sec * 1000) + ((timeout->tv_usec + 500)/1000));\r
+\r
+        i = sys_sem_wait_timeout(select_cb.sem, msectimeout);\r
+\r
+        /* Take us off the list */\r
+        sys_sem_wait(selectsem);\r
+        if (select_cb_list == &select_cb)\r
+            select_cb_list = select_cb.next;\r
+        else\r
+            for (p_selcb = select_cb_list; p_selcb; p_selcb = p_selcb->next)\r
+                if (p_selcb->next == &select_cb)\r
+                {\r
+                    p_selcb->next = select_cb.next;\r
+                    break;\r
+                }\r
+\r
+        sys_sem_signal(selectsem);\r
+\r
+        sys_sem_free(select_cb.sem);\r
+        if (i == 0)             /* Timeout */\r
+        {\r
+            if (readset)\r
+                FD_ZERO(readset);\r
+            if (writeset)\r
+                FD_ZERO(writeset);\r
+            if (exceptset)\r
+                FD_ZERO(exceptset);\r
+\r
+           LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: timeout expired\n"));\r
+           set_errno(0);\r
+\r
+            return 0;\r
+        }\r
+\r
+        if (readset)\r
+            lreadset = *readset;\r
+        else\r
+            FD_ZERO(&lreadset);\r
+        if (writeset)\r
+            lwriteset = *writeset;\r
+        else\r
+            FD_ZERO(&lwriteset);\r
+        if (exceptset)\r
+            lexceptset = *exceptset;\r
+        else\r
+            FD_ZERO(&lexceptset);\r
+\r
+        /* See what's set */\r
+        nready = lwip_selscan(maxfdp1, &lreadset, &lwriteset, &lexceptset);\r
+    }\r
+    else\r
+        sys_sem_signal(selectsem);\r
+\r
+    if (readset)\r
+        *readset = lreadset;\r
+    if (writeset)\r
+        *writeset = lwriteset;\r
+    if (exceptset)\r
+        *exceptset = lexceptset;\r
+\r
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: nready=%d\n", nready));\r
+    set_errno(0);\r
+\r
+    return nready;\r
+}\r
+\r
+\r
+static void\r
+event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len)\r
+{\r
+    int s;\r
+    struct lwip_socket *sock;\r
+    struct lwip_select_cb *scb;\r
+\r
+    /* Get socket */\r
+    if (conn)\r
+    {\r
+        s = conn->socket;\r
+        if (s < 0)\r
+        {\r
+            /* Data comes in right away after an accept, even though\r
+             * the server task might not have created a new socket yet.\r
+             * Just count down (or up) if that's the case and we\r
+             * will use the data later. Note that only receive events\r
+             * can happen before the new socket is set up. */\r
+            if (evt == NETCONN_EVT_RCVPLUS)\r
+                conn->socket--;\r
+            return;\r
+        }\r
+\r
+        sock = get_socket(s);\r
+        if (!sock)\r
+            return;\r
+    }\r
+    else\r
+        return;\r
+\r
+    if (!selectsem)\r
+        selectsem = sys_sem_new(1);\r
+\r
+    sys_sem_wait(selectsem);\r
+    /* Set event as required */\r
+    switch (evt)\r
+    {\r
+      case NETCONN_EVT_RCVPLUS:\r
+        sock->rcvevent++;\r
+        break;\r
+      case NETCONN_EVT_RCVMINUS:\r
+        sock->rcvevent--;\r
+        break;\r
+      case NETCONN_EVT_SENDPLUS:\r
+        sock->sendevent = 1;\r
+        break;\r
+      case NETCONN_EVT_SENDMINUS:\r
+        sock->sendevent = 0;\r
+        break;\r
+    }\r
+    sys_sem_signal(selectsem);\r
+\r
+    /* Now decide if anyone is waiting for this socket */\r
+    /* NOTE: This code is written this way to protect the select link list\r
+       but to avoid a deadlock situation by releasing socksem before\r
+       signalling for the select. This means we need to go through the list\r
+       multiple times ONLY IF a select was actually waiting. We go through\r
+       the list the number of waiting select calls + 1. This list is\r
+       expected to be small. */\r
+    while (1)\r
+    {\r
+        sys_sem_wait(selectsem);\r
+        for (scb = select_cb_list; scb; scb = scb->next)\r
+        {\r
+            if (scb->sem_signalled == 0)\r
+            {\r
+                /* Test this select call for our socket */\r
+                if (scb->readset && FD_ISSET(s, scb->readset))\r
+                    if (sock->rcvevent)\r
+                        break;\r
+                if (scb->writeset && FD_ISSET(s, scb->writeset))\r
+                    if (sock->sendevent)\r
+                        break;\r
+            }\r
+        }\r
+        if (scb)\r
+        {\r
+            scb->sem_signalled = 1;\r
+            sys_sem_signal(selectsem);\r
+            sys_sem_signal(scb->sem);\r
+        } else {\r
+            sys_sem_signal(selectsem);\r
+            break;\r
+        }\r
+    }\r
+\r
+}\r
+\r
+\r
+\r
+\r
+int lwip_shutdown(int s, int how)\r
+{\r
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_shutdown(%d, how=%d)\n", s, how));\r
+  return lwip_close(s); /* XXX temporary hack until proper implementation */\r
+}\r
+\r
+int lwip_getpeername (int s, struct sockaddr *name, socklen_t *namelen)\r
+{\r
+  struct lwip_socket *sock;\r
+  struct sockaddr_in sin;\r
+  struct ip_addr naddr;\r
+\r
+  sock = get_socket(s);\r
+  if (!sock) {\r
+    set_errno(EBADF);\r
+    return -1;\r
+  }\r
+\r
+  memset(&sin, 0, sizeof(sin));\r
+  sin.sin_len = sizeof(sin);\r
+  sin.sin_family = AF_INET;\r
+\r
+  /* get the IP address and port of the remote host */\r
+  netconn_peer(sock->conn, &naddr, &sin.sin_port);\r
+\r
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getpeername(%d, addr=", s));\r
+  ip_addr_debug_print(SOCKETS_DEBUG, &naddr);\r
+  LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%d)\n", sin.sin_port));\r
+\r
+  sin.sin_port = htons(sin.sin_port);\r
+  sin.sin_addr.s_addr = naddr.addr;\r
+\r
+  if (*namelen > sizeof(sin))\r
+      *namelen = sizeof(sin);\r
+\r
+  memcpy(name, &sin, *namelen);\r
+  sock_set_errno(sock, 0);\r
+  return 0;\r
+}\r
+\r
+int lwip_getsockname (int s, struct sockaddr *name, socklen_t *namelen)\r
+{\r
+  struct lwip_socket *sock;\r
+  struct sockaddr_in sin;\r
+  struct ip_addr *naddr;\r
+\r
+  sock = get_socket(s);\r
+  if (!sock) {\r
+    set_errno(EBADF);\r
+    return -1;\r
+  }\r
+\r
+  memset(&sin, 0, sizeof(sin));\r
+  sin.sin_len = sizeof(sin);\r
+  sin.sin_family = AF_INET;\r
+\r
+  /* get the IP address and port of the remote host */\r
+  netconn_addr(sock->conn, &naddr, &sin.sin_port);\r
+\r
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockname(%d, addr=", s));\r
+  ip_addr_debug_print(SOCKETS_DEBUG, naddr);\r
+  LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%d)\n", sin.sin_port));\r
+\r
+  sin.sin_port = htons(sin.sin_port);\r
+  sin.sin_addr.s_addr = naddr->addr;\r
+\r
+  if (*namelen > sizeof(sin))\r
+      *namelen = sizeof(sin);\r
+\r
+  memcpy(name, &sin, *namelen);\r
+  sock_set_errno(sock, 0);\r
+  return 0;\r
+}\r
+\r
+int lwip_getsockopt (int s, int level, int optname, void *optval, socklen_t *optlen)\r
+{\r
+  int err = 0;\r
+  struct lwip_socket *sock = get_socket(s);\r
+\r
+  if(!sock) {\r
+       set_errno(EBADF);\r
+    return -1;\r
+  }\r
+\r
+  if( NULL == optval || NULL == optlen ) {\r
+    sock_set_errno( sock, EFAULT );\r
+    return -1;\r
+  }\r
+\r
+  /* Do length and type checks for the various options first, to keep it readable. */\r
+  switch( level ) {\r
+   \r
+/* Level: SOL_SOCKET */\r
+  case SOL_SOCKET:\r
+      switch(optname) {\r
+         \r
+      case SO_ACCEPTCONN:\r
+      case SO_BROADCAST:\r
+      /* UNIMPL case SO_DEBUG: */\r
+      /* UNIMPL case SO_DONTROUTE: */\r
+      case SO_ERROR:\r
+      case SO_KEEPALIVE:\r
+      /* UNIMPL case SO_OOBINLINE: */\r
+      /* UNIMPL case SO_RCVBUF: */\r
+      /* UNIMPL case SO_SNDBUF: */\r
+      /* UNIMPL case SO_RCVLOWAT: */\r
+      /* UNIMPL case SO_SNDLOWAT: */\r
+#if SO_REUSE\r
+      case SO_REUSEADDR:\r
+      case SO_REUSEPORT:\r
+#endif /* SO_REUSE */\r
+      case SO_TYPE:\r
+      /* UNIMPL case SO_USELOOPBACK: */\r
+        if( *optlen < sizeof(int) ) {\r
+          err = EINVAL;\r
+        }\r
+          break;\r
+\r
+      default:\r
+        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, UNIMPL: optname=0x%x, ..)\n", s, optname));\r
+        err = ENOPROTOOPT;\r
+      }  /* switch */\r
+      break;\r
+                     \r
+/* Level: IPPROTO_IP */\r
+  case IPPROTO_IP:\r
+      switch(optname) {\r
+      /* UNIMPL case IP_HDRINCL: */\r
+      /* UNIMPL case IP_RCVDSTADDR: */\r
+      /* UNIMPL case IP_RCVIF: */\r
+      case IP_TTL:\r
+      case IP_TOS:\r
+        if( *optlen < sizeof(int) ) {\r
+          err = EINVAL;\r
+        }\r
+        break;\r
+\r
+      default:\r
+        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, UNIMPL: optname=0x%x, ..)\n", s, optname));\r
+        err = ENOPROTOOPT;\r
+      }  /* switch */\r
+      break;\r
+         \r
+/* Level: IPPROTO_TCP */\r
+  case IPPROTO_TCP:\r
+      if( *optlen < sizeof(int) ) {\r
+        err = EINVAL;\r
+        break;\r
+    }\r
+      \r
+      /* If this is no TCP socket, ignore any options. */\r
+      if ( sock->conn->type != NETCONN_TCP ) return 0;\r
+\r
+      switch( optname ) {\r
+      case TCP_NODELAY:\r
+      case TCP_KEEPALIVE:\r
+        break;\r
+         \r
+      default:\r
+        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, UNIMPL: optname=0x%x, ..)\n", s, optname));\r
+        err = ENOPROTOOPT;\r
+      }  /* switch */\r
+      break;\r
+\r
+/* UNDEFINED LEVEL */\r
+  default:\r
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, level=0x%x, UNIMPL: optname=0x%x, ..)\n", s, level, optname));\r
+      err = ENOPROTOOPT;\r
+  }  /* switch */\r
+\r
+   \r
+  if( 0 != err ) {\r
+    sock_set_errno(sock, err);\r
+    return -1;\r
+  }\r
+   \r
+\r
+\r
+  /* Now do the actual option processing */\r
+\r
+  switch(level) {\r
+   \r
+/* Level: SOL_SOCKET */\r
+  case SOL_SOCKET:\r
+    switch( optname ) {\r
+\r
+    /* The option flags */\r
+    case SO_ACCEPTCONN:\r
+    case SO_BROADCAST:\r
+    /* UNIMPL case SO_DEBUG: */\r
+    /* UNIMPL case SO_DONTROUTE: */\r
+    case SO_KEEPALIVE:\r
+    /* UNIMPL case SO_OOBINCLUDE: */\r
+#if SO_REUSE\r
+    case SO_REUSEADDR:\r
+    case SO_REUSEPORT:\r
+#endif /* SO_REUSE */\r
+    /*case SO_USELOOPBACK: UNIMPL */\r
+      *(int*)optval = sock->conn->pcb.tcp->so_options & optname;\r
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, optname=0x%x, ..) = %s\n", s, optname, (*(int*)optval?"on":"off")));\r
+      break;\r
+\r
+    case SO_TYPE:\r
+      switch (sock->conn->type) {\r
+      case NETCONN_RAW:\r
+        *(int*)optval = SOCK_RAW;\r
+        break;\r
+      case NETCONN_TCP:\r
+        *(int*)optval = SOCK_STREAM;\r
+        break;\r
+      case NETCONN_UDP:\r
+      case NETCONN_UDPLITE:\r
+      case NETCONN_UDPNOCHKSUM:\r
+        *(int*)optval = SOCK_DGRAM;\r
+        break;\r
+      default: /* unrecognized socket type */\r
+        *(int*)optval = sock->conn->type;\r
+        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, SO_TYPE): unrecognized socket type %d\n", s, *(int *)optval));\r
+      }  /* switch */\r
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, SO_TYPE) = %d\n", s, *(int *)optval));\r
+      break;\r
+\r
+    case SO_ERROR:\r
+      *(int *)optval = sock->err;\r
+      sock->err = 0;\r
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, SO_ERROR) = %d\n", s, *(int *)optval));\r
+      break;\r
+    }  /* switch */\r
+    break;\r
+\r
+/* Level: IPPROTO_IP */\r
+  case IPPROTO_IP:\r
+    switch( optname ) {\r
+    case IP_TTL:\r
+      *(int*)optval = sock->conn->pcb.tcp->ttl;\r
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_TTL) = %d\n", s, *(int *)optval));\r
+      break;\r
+    case IP_TOS:\r
+      *(int*)optval = sock->conn->pcb.tcp->tos;\r
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_TOS) = %d\n", s, *(int *)optval));\r
+      break;\r
+    }  /* switch */\r
+    break;\r
+\r
+/* Level: IPPROTO_TCP */\r
+  case IPPROTO_TCP:\r
+    switch( optname ) {\r
+    case TCP_NODELAY:\r
+      *(int*)optval = (sock->conn->pcb.tcp->flags & TF_NODELAY);\r
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, TCP_NODELAY) = %s\n", s, (*(int*)optval)?"on":"off") );\r
+      break;\r
+    case TCP_KEEPALIVE:\r
+      *(int*)optval = (int)sock->conn->pcb.tcp->keepalive;\r
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, TCP_KEEPALIVE) = %d\n", s, *(int *)optval));\r
+      break;\r
+    }  /* switch */\r
+    break;\r
+  }\r
+\r
+\r
+  sock_set_errno(sock, err);\r
+  return err ? -1 : 0;\r
+}\r
+\r
+int lwip_setsockopt (int s, int level, int optname, const void *optval, socklen_t optlen)\r
+{\r
+  struct lwip_socket *sock = get_socket(s);\r
+  int err = 0;\r
+\r
+  if(!sock) {\r
+       set_errno(EBADF);\r
+    return -1;\r
+  }\r
+\r
+  if( NULL == optval ) {\r
+    sock_set_errno( sock, EFAULT );\r
+    return -1;\r
+  }\r
+\r
+\r
+  /* Do length and type checks for the various options first, to keep it readable. */\r
+  switch( level ) {\r
+\r
+/* Level: SOL_SOCKET */\r
+  case SOL_SOCKET:\r
+    switch(optname) {\r
+\r
+    case SO_BROADCAST:\r
+    /* UNIMPL case SO_DEBUG: */\r
+    /* UNIMPL case SO_DONTROUTE: */\r
+    case SO_KEEPALIVE:\r
+    /* UNIMPL case SO_OOBINLINE: */\r
+    /* UNIMPL case SO_RCVBUF: */\r
+    /* UNIMPL case SO_SNDBUF: */\r
+    /* UNIMPL case SO_RCVLOWAT: */\r
+    /* UNIMPL case SO_SNDLOWAT: */\r
+#if SO_REUSE\r
+    case SO_REUSEADDR:\r
+    case SO_REUSEPORT:\r
+#endif /* SO_REUSE */\r
+    /* UNIMPL case SO_USELOOPBACK: */\r
+      if( optlen < sizeof(int) ) {\r
+        err = EINVAL;\r
+      }\r
+      break;\r
+    default:\r
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, SOL_SOCKET, UNIMPL: optname=0x%x, ..)\n", s, optname));\r
+      err = ENOPROTOOPT;\r
+    }  /* switch */\r
+    break;\r
+\r
+/* Level: IPPROTO_IP */\r
+  case IPPROTO_IP:\r
+    switch(optname) {\r
+    /* UNIMPL case IP_HDRINCL: */\r
+    /* UNIMPL case IP_RCVDSTADDR: */\r
+    /* UNIMPL case IP_RCVIF: */\r
+    case IP_TTL:\r
+    case IP_TOS:\r
+      if( optlen < sizeof(int) ) {\r
+        err = EINVAL;\r
+      }\r
+        break;\r
+      default:\r
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, UNIMPL: optname=0x%x, ..)\n", s, optname));\r
+      err = ENOPROTOOPT;\r
+    }  /* switch */\r
+    break;\r
+\r
+/* Level: IPPROTO_TCP */\r
+  case IPPROTO_TCP:\r
+    if( optlen < sizeof(int) ) {\r
+      err = EINVAL;\r
+        break;\r
+    }\r
+\r
+    /* If this is no TCP socket, ignore any options. */\r
+    if ( sock->conn->type != NETCONN_TCP ) return 0;\r
+\r
+    switch( optname ) {\r
+    case TCP_NODELAY:\r
+    case TCP_KEEPALIVE:\r
+      break;\r
+\r
+    default:\r
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, UNIMPL: optname=0x%x, ..)\n", s, optname));\r
+      err = ENOPROTOOPT;\r
+    }  /* switch */\r
+    break;\r
+\r
+/* UNDEFINED LEVEL */      \r
+  default:\r
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, level=0x%x, UNIMPL: optname=0x%x, ..)\n", s, level, optname));\r
+    err = ENOPROTOOPT;\r
+  }  /* switch */\r
+\r
+\r
+  if( 0 != err ) {\r
+    sock_set_errno(sock, err);\r
+    return -1;\r
+  }\r
+\r
+\r
+\r
+  /* Now do the actual option processing */\r
+\r
+  switch(level) {\r
+\r
+/* Level: SOL_SOCKET */\r
+  case SOL_SOCKET:\r
+    switch(optname) {\r
+\r
+    /* The option flags */\r
+    case SO_BROADCAST:\r
+    /* UNIMPL case SO_DEBUG: */\r
+    /* UNIMPL case SO_DONTROUTE: */\r
+    case SO_KEEPALIVE:\r
+    /* UNIMPL case SO_OOBINCLUDE: */\r
+#if SO_REUSE\r
+    case SO_REUSEADDR:\r
+    case SO_REUSEPORT:\r
+#endif /* SO_REUSE */\r
+    /* UNIMPL case SO_USELOOPBACK: */\r
+      if ( *(int*)optval ) {\r
+        sock->conn->pcb.tcp->so_options |= optname;\r
+      } else {\r
+        sock->conn->pcb.tcp->so_options &= ~optname;\r
+      }\r
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, SOL_SOCKET, optname=0x%x, ..) -> %s\n", s, optname, (*(int*)optval?"on":"off")));\r
+      break;\r
+    }  /* switch */\r
+    break;\r
+\r
+/* Level: IPPROTO_IP */\r
+  case IPPROTO_IP:\r
+    switch( optname ) {\r
+    case IP_TTL:\r
+      sock->conn->pcb.tcp->ttl = (u8_t)(*(int*)optval);\r
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, IP_TTL, ..) -> %u\n", s, sock->conn->pcb.tcp->ttl));\r
+      break;\r
+    case IP_TOS:\r
+      sock->conn->pcb.tcp->tos = (u8_t)(*(int*)optval);\r
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, IP_TOS, ..)-> %u\n", s, sock->conn->pcb.tcp->tos));\r
+      break;\r
+    }  /* switch */\r
+    break;\r
+\r
+/* Level: IPPROTO_TCP */\r
+  case IPPROTO_TCP:\r
+    switch( optname ) {\r
+    case TCP_NODELAY:\r
+      if ( *(int*)optval ) {\r
+        sock->conn->pcb.tcp->flags |= TF_NODELAY;\r
+      } else {\r
+        sock->conn->pcb.tcp->flags &= ~TF_NODELAY;\r
+      }\r
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_NODELAY) -> %s\n", s, (*(int *)optval)?"on":"off") );\r
+      break;\r
+    case TCP_KEEPALIVE:\r
+      sock->conn->pcb.tcp->keepalive = (u32_t)(*(int*)optval);\r
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPALIVE) -> %lu\n", s, sock->conn->pcb.tcp->keepalive));\r
+      break;\r
+    }  /* switch */\r
+    break;\r
+  }  /* switch */\r
+\r
+  sock_set_errno(sock, err);\r
+  return err ? -1 : 0;\r
+}\r
+\r
+int lwip_ioctl(int s, long cmd, void *argp)\r
+{\r
+  struct lwip_socket *sock = get_socket(s);\r
+\r
+  if(!sock) {\r
+       set_errno(EBADF);\r
+    return -1;\r
+  }\r
+\r
+  switch (cmd) {\r
+  case FIONREAD:\r
+    if (!argp) {\r
+      sock_set_errno(sock, EINVAL);\r
+      return -1;\r
+    }\r
+\r
+    *((u16_t*)argp) = sock->conn->recv_avail;\r
+\r
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, FIONREAD, %p) = %u\n", s, argp, *((u16_t*)argp)));\r
+    sock_set_errno(sock, 0);\r
+    return 0;\r
+\r
+  case FIONBIO:\r
+    if (argp && *(u32_t*)argp)\r
+      sock->flags |= O_NONBLOCK;\r
+    else\r
+      sock->flags &= ~O_NONBLOCK;\r
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, FIONBIO, %d)\n", s, !!(sock->flags & O_NONBLOCK)));\r
+    sock_set_errno(sock, 0);\r
+    return 0;\r
+\r
+  default:\r
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, UNIMPL: 0x%lx, %p)\n", s, cmd, argp));\r
+    sock_set_errno(sock, ENOSYS); /* not yet implemented */\r
+    return -1;\r
+  }\r
+}\r
+\r
index ce8a2ca5d12616d4ba54de9814b30893fb2e02f6..db86cf4ca31207c24c9b86d8c62a72d79fccd35a 100644 (file)
-/*
- * 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 <adam@sics.se>
- *
- */
-
-#include "lwip/opt.h"
-
-#include "lwip/sys.h"
-
-#include "lwip/memp.h"
-#include "lwip/pbuf.h"
-
-#include "lwip/ip.h"
-#include "lwip/ip_frag.h"
-#include "lwip/udp.h"
-#include "lwip/tcp.h"
-
-#include "lwip/tcpip.h"
-
-static void (* tcpip_init_done)(void *arg) = NULL;
-static void *tcpip_init_done_arg;
-static sys_mbox_t mbox;
-
-#if LWIP_TCP
-static int tcpip_tcp_timer_active = 0;
-
-static void
-tcpip_tcp_timer(void *arg)
-{
-  (void)arg;
-
-  /* call TCP timer handler */
-  tcp_tmr();
-  /* timer still needed? */
-  if (tcp_active_pcbs || tcp_tw_pcbs) {
-    /* restart timer */
-    sys_timeout(TCP_TMR_INTERVAL, tcpip_tcp_timer, NULL);
-  } else {
-    /* disable timer */
-    tcpip_tcp_timer_active = 0;
-  }
-}
-
-#if !NO_SYS
-void
-tcp_timer_needed(void)
-{
-  /* timer is off but needed again? */
-  if (!tcpip_tcp_timer_active && (tcp_active_pcbs || tcp_tw_pcbs)) {
-    /* enable and start timer */
-    tcpip_tcp_timer_active = 1;
-    sys_timeout(TCP_TMR_INTERVAL, tcpip_tcp_timer, NULL);
-  }
-}
-#endif /* !NO_SYS */
-#endif /* LWIP_TCP */
-
-#if IP_REASSEMBLY
-static void
-ip_timer(void *data)
-{
-  LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip: ip_reass_tmr()\n"));
-  ip_reass_tmr();
-  sys_timeout(1000, ip_timer, NULL);
-}
-#endif
-
-static void
-tcpip_thread(void *arg)
-{
-  struct tcpip_msg *msg;
-
-  (void)arg;
-
-  ip_init();
-#if LWIP_UDP  
-  udp_init();
-#endif
-#if LWIP_TCP
-  tcp_init();
-#endif
-#if IP_REASSEMBLY
-  sys_timeout(1000, ip_timer, NULL);
-#endif
-  if (tcpip_init_done != NULL) {
-    tcpip_init_done(tcpip_init_done_arg);
-  }
-
-  while (1) {                          /* MAIN Loop */
-    sys_mbox_fetch(mbox, (void *)&msg);
-    switch (msg->type) {
-    case TCPIP_MSG_API:
-      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: API message %p\n", (void *)msg));
-      api_msg_input(msg->msg.apimsg);
-      break;
-    case TCPIP_MSG_INPUT:
-      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: IP packet %p\n", (void *)msg));
-      ip_input(msg->msg.inp.p, msg->msg.inp.netif);
-      break;
-    case TCPIP_MSG_CALLBACK:
-      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK %p\n", (void *)msg));
-      msg->msg.cb.f(msg->msg.cb.ctx);
-      break;
-    default:
-      break;
-    }
-    memp_free(MEMP_TCPIP_MSG, msg);
-  }
-}
-
-err_t
-tcpip_input(struct pbuf *p, struct netif *inp)
-{
-  struct tcpip_msg *msg;
-  
-  msg = memp_malloc(MEMP_TCPIP_MSG);
-  if (msg == NULL) {
-    pbuf_free(p);    
-    return ERR_MEM;  
-  }
-  
-  msg->type = TCPIP_MSG_INPUT;
-  msg->msg.inp.p = p;
-  msg->msg.inp.netif = inp;
-  sys_mbox_post(mbox, msg);
-  return ERR_OK;
-}
-
-err_t
-tcpip_callback(void (*f)(void *ctx), void *ctx)
-{
-  struct tcpip_msg *msg;
-  
-  msg = memp_malloc(MEMP_TCPIP_MSG);
-  if (msg == NULL) {
-    return ERR_MEM;  
-  }
-  
-  msg->type = TCPIP_MSG_CALLBACK;
-  msg->msg.cb.f = f;
-  msg->msg.cb.ctx = ctx;
-  sys_mbox_post(mbox, msg);
-  return ERR_OK;
-}
-
-void
-tcpip_apimsg(struct api_msg *apimsg)
-{
-  struct tcpip_msg *msg;
-  msg = memp_malloc(MEMP_TCPIP_MSG);
-  if (msg == NULL) {
-    memp_free(MEMP_API_MSG, apimsg);
-    return;
-  }
-  msg->type = TCPIP_MSG_API;
-  msg->msg.apimsg = apimsg;
-  sys_mbox_post(mbox, msg);
-}
-
-void
-tcpip_init(void (* initfunc)(void *), void *arg)
-{
-  tcpip_init_done = initfunc;
-  tcpip_init_done_arg = arg;
-  mbox = sys_mbox_new();
-  sys_thread_new(tcpip_thread, NULL, TCPIP_THREAD_PRIO);
-}
-
-
-
-
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+\r
+#include "lwip/opt.h"\r
+\r
+#include "lwip/sys.h"\r
+\r
+#include "lwip/memp.h"\r
+#include "lwip/pbuf.h"\r
+\r
+#include "lwip/ip.h"\r
+#include "lwip/ip_frag.h"\r
+#include "lwip/udp.h"\r
+#include "lwip/tcp.h"\r
+\r
+#include "lwip/tcpip.h"\r
+\r
+static void (* tcpip_init_done)(void *arg) = NULL;\r
+static void *tcpip_init_done_arg;\r
+static sys_mbox_t mbox;\r
+\r
+#if LWIP_TCP\r
+static int tcpip_tcp_timer_active = 0;\r
+\r
+static void\r
+tcpip_tcp_timer(void *arg)\r
+{\r
+  (void)arg;\r
+\r
+  /* call TCP timer handler */\r
+  tcp_tmr();\r
+  /* timer still needed? */\r
+  if (tcp_active_pcbs || tcp_tw_pcbs) {\r
+    /* restart timer */\r
+    sys_timeout(TCP_TMR_INTERVAL, tcpip_tcp_timer, NULL);\r
+  } else {\r
+    /* disable timer */\r
+    tcpip_tcp_timer_active = 0;\r
+  }\r
+}\r
+\r
+#if !NO_SYS\r
+void\r
+tcp_timer_needed(void)\r
+{\r
+  /* timer is off but needed again? */\r
+  if (!tcpip_tcp_timer_active && (tcp_active_pcbs || tcp_tw_pcbs)) {\r
+    /* enable and start timer */\r
+    tcpip_tcp_timer_active = 1;\r
+    sys_timeout(TCP_TMR_INTERVAL, tcpip_tcp_timer, NULL);\r
+  }\r
+}\r
+#endif /* !NO_SYS */\r
+#endif /* LWIP_TCP */\r
+\r
+#if IP_REASSEMBLY\r
+static void\r
+ip_timer(void *data)\r
+{\r
+  LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip: ip_reass_tmr()\n"));\r
+  ip_reass_tmr();\r
+  sys_timeout(1000, ip_timer, NULL);\r
+}\r
+#endif\r
+\r
+static void\r
+tcpip_thread(void *arg)\r
+{\r
+  struct tcpip_msg *msg;\r
+\r
+  (void)arg;\r
+\r
+  ip_init();\r
+#if LWIP_UDP  \r
+  udp_init();\r
+#endif\r
+#if LWIP_TCP\r
+  tcp_init();\r
+#endif\r
+#if IP_REASSEMBLY\r
+  sys_timeout(1000, ip_timer, NULL);\r
+#endif\r
+  if (tcpip_init_done != NULL) {\r
+    tcpip_init_done(tcpip_init_done_arg);\r
+  }\r
+\r
+  while (1) {                          /* MAIN Loop */\r
+    sys_mbox_fetch(mbox, (void *)&msg);\r
+    switch (msg->type) {\r
+    case TCPIP_MSG_API:\r
+      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: API message %p\n", (void *)msg));\r
+      api_msg_input(msg->msg.apimsg);\r
+      break;\r
+    case TCPIP_MSG_INPUT:\r
+      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: IP packet %p\n", (void *)msg));\r
+      ip_input(msg->msg.inp.p, msg->msg.inp.netif);\r
+      break;\r
+    case TCPIP_MSG_CALLBACK:\r
+      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK %p\n", (void *)msg));\r
+      msg->msg.cb.f(msg->msg.cb.ctx);\r
+      break;\r
+    default:\r
+      break;\r
+    }\r
+    memp_free(MEMP_TCPIP_MSG, msg);\r
+  }\r
+}\r
+\r
+err_t\r
+tcpip_input(struct pbuf *p, struct netif *inp)\r
+{\r
+  struct tcpip_msg *msg;\r
+  \r
+  msg = memp_malloc(MEMP_TCPIP_MSG);\r
+  if (msg == NULL) {\r
+    pbuf_free(p);    \r
+    return ERR_MEM;  \r
+  }\r
+  \r
+  msg->type = TCPIP_MSG_INPUT;\r
+  msg->msg.inp.p = p;\r
+  msg->msg.inp.netif = inp;\r
+  sys_mbox_post(mbox, msg);\r
+  return ERR_OK;\r
+}\r
+\r
+err_t\r
+tcpip_callback(void (*f)(void *ctx), void *ctx)\r
+{\r
+  struct tcpip_msg *msg;\r
+  \r
+  msg = memp_malloc(MEMP_TCPIP_MSG);\r
+  if (msg == NULL) {\r
+    return ERR_MEM;  \r
+  }\r
+  \r
+  msg->type = TCPIP_MSG_CALLBACK;\r
+  msg->msg.cb.f = f;\r
+  msg->msg.cb.ctx = ctx;\r
+  sys_mbox_post(mbox, msg);\r
+  return ERR_OK;\r
+}\r
+\r
+void\r
+tcpip_apimsg(struct api_msg *apimsg)\r
+{\r
+  struct tcpip_msg *msg;\r
+  msg = memp_malloc(MEMP_TCPIP_MSG);\r
+  if (msg == NULL) {\r
+    memp_free(MEMP_API_MSG, apimsg);\r
+    return;\r
+  }\r
+  msg->type = TCPIP_MSG_API;\r
+  msg->msg.apimsg = apimsg;\r
+  sys_mbox_post(mbox, msg);\r
+}\r
+\r
+void\r
+tcpip_init(void (* initfunc)(void *), void *arg)\r
+{\r
+  tcpip_init_done = initfunc;\r
+  tcpip_init_done_arg = arg;\r
+  mbox = sys_mbox_new();\r
+  sys_thread_new(tcpip_thread, NULL, TCPIP_THREAD_PRIO);\r
+}\r
+\r
+\r
+\r
+\r
index b688afa19fc36f489a56563f88c01c6cfcc6abb8..ad292d23b8e55191bbd38c750a63d97c68fb0d6e 100644 (file)
-/**
- * @file
- *
- * Dynamic Host Configuration Protocol client
- */
-
-/*
- *
- * Copyright (c) 2001-2004 Leon Woestenberg <leon.woestenberg@gmx.net>
- * Copyright (c) 2001-2004 Axon Digital Design B.V., The Netherlands.
- * 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 a contribution to the lwIP TCP/IP stack.
- * The Swedish Institute of Computer Science and Adam Dunkels
- * are specifically granted permission to redistribute this
- * source code.
- *
- * Author: Leon Woestenberg <leon.woestenberg@gmx.net>
- *
- * This is a DHCP client for the lwIP TCP/IP stack. It aims to conform
- * with RFC 2131 and RFC 2132.
- *
- * TODO:
- * - Proper parsing of DHCP messages exploiting file/sname field overloading.
- * - Add JavaDoc style documentation (API, internals).
- * - Support for interfaces other than Ethernet (SLIP, PPP, ...)
- *
- * Please coordinate changes and requests with Leon Woestenberg
- * <leon.woestenberg@gmx.net>
- *
- * Integration with your code:
- *
- * In lwip/dhcp.h
- * #define DHCP_COARSE_TIMER_SECS (recommended 60 which is a minute)
- * #define DHCP_FINE_TIMER_MSECS (recommended 500 which equals TCP coarse timer)
- *
- * Then have your application call dhcp_coarse_tmr() and
- * dhcp_fine_tmr() on the defined intervals.
- *
- * dhcp_start(struct netif *netif);
- * starts a DHCP client instance which configures the interface by
- * obtaining an IP address lease and maintaining it.
- *
- * Use dhcp_release(netif) to end the lease and use dhcp_stop(netif)
- * to remove the DHCP client.
- *
- */
-#include <string.h>
-#include "lwip/stats.h"
-#include "lwip/mem.h"
-#include "lwip/udp.h"
-#include "lwip/ip_addr.h"
-#include "lwip/netif.h"
-#include "lwip/inet.h"
-#include "netif/etharp.h"
-
-#include "lwip/sys.h"
-#include "lwip/opt.h"
-#include "lwip/dhcp.h"
-
-#if LWIP_DHCP /* don't build if not configured for use in lwipopt.h */
-
-/** global transaction identifier, must be
- *  unique for each DHCP request. We simply increment, starting
- *  with this value (easy to match with a packet analyzer) */
-static u32_t xid = 0xABCD0000;
-
-/** DHCP client state machine functions */
-static void dhcp_handle_ack(struct netif *netif);
-static void dhcp_handle_nak(struct netif *netif);
-static void dhcp_handle_offer(struct netif *netif);
-
-static err_t dhcp_discover(struct netif *netif);
-static err_t dhcp_select(struct netif *netif);
-static void dhcp_check(struct netif *netif);
-static void dhcp_bind(struct netif *netif);
-static err_t dhcp_decline(struct netif *netif);
-static err_t dhcp_rebind(struct netif *netif);
-static void dhcp_set_state(struct dhcp *dhcp, u8_t new_state);
-
-/** receive, unfold, parse and free incoming messages */
-static void dhcp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u16_t port);
-static err_t dhcp_unfold_reply(struct dhcp *dhcp);
-static u8_t *dhcp_get_option_ptr(struct dhcp *dhcp, u8_t option_type);
-static u8_t dhcp_get_option_byte(u8_t *ptr);
-static u16_t dhcp_get_option_short(u8_t *ptr);
-static u32_t dhcp_get_option_long(u8_t *ptr);
-static void dhcp_free_reply(struct dhcp *dhcp);
-
-/** set the DHCP timers */
-static void dhcp_timeout(struct netif *netif);
-static void dhcp_t1_timeout(struct netif *netif);
-static void dhcp_t2_timeout(struct netif *netif);
-
-/** build outgoing messages */
-/** create a DHCP request, fill in common headers */
-static err_t dhcp_create_request(struct netif *netif);
-/** free a DHCP request */
-static void dhcp_delete_request(struct netif *netif);
-/** add a DHCP option (type, then length in bytes) */
-static void dhcp_option(struct dhcp *dhcp, u8_t option_type, u8_t option_len);
-/** add option values */
-static void dhcp_option_byte(struct dhcp *dhcp, u8_t value);
-static void dhcp_option_short(struct dhcp *dhcp, u16_t value);
-static void dhcp_option_long(struct dhcp *dhcp, u32_t value);
-/** always add the DHCP options trailer to end and pad */
-static void dhcp_option_trailer(struct dhcp *dhcp);
-
-/**
- * Back-off the DHCP client (because of a received NAK response).
- *
- * Back-off the DHCP client because of a received NAK. Receiving a
- * NAK means the client asked for something non-sensible, for
- * example when it tries to renew a lease obtained on another network.
- *
- * We back-off and will end up restarting a fresh DHCP negotiation later.
- *
- * @param state pointer to DHCP state structure
- */
-static void dhcp_handle_nak(struct netif *netif) {
-  struct dhcp *dhcp = netif->dhcp;
-  u16_t msecs = 10 * 1000;
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_handle_nak(netif=%p) %c%c%"U16_F"\n", 
-    (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num));
-  dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_handle_nak(): set request timeout %"U16_F" msecs\n", msecs));
-  dhcp_set_state(dhcp, DHCP_BACKING_OFF);
-}
-
-/**
- * Checks if the offered IP address is already in use.
- *
- * It does so by sending an ARP request for the offered address and
- * entering CHECKING state. If no ARP reply is received within a small
- * interval, the address is assumed to be free for use by us.
- */
-static void dhcp_check(struct netif *netif)
-{
-  struct dhcp *dhcp = netif->dhcp;
-  err_t result;
-  u16_t msecs;
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_check(netif=%p) %c%c\n", (void *)netif, (s16_t)netif->name[0],
-    (s16_t)netif->name[1]));
-  /* create an ARP query for the offered IP address, expecting that no host
-     responds, as the IP address should not be in use. */
-  result = etharp_query(netif, &dhcp->offered_ip_addr, NULL);
-  if (result != ERR_OK) {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_check: could not perform ARP query\n"));
-  }
-  dhcp->tries++;
-  msecs = 500;
-  dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_check(): set request timeout %"U16_F" msecs\n", msecs));
-  dhcp_set_state(dhcp, DHCP_CHECKING);
-}
-
-/**
- * Remember the configuration offered by a DHCP server.
- *
- * @param state pointer to DHCP state structure
- */
-static void dhcp_handle_offer(struct netif *netif)
-{
-  struct dhcp *dhcp = netif->dhcp;
-  /* obtain the server address */
-  u8_t *option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_SERVER_ID);
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_handle_offer(netif=%p) %c%c%"U16_F"\n",
-    (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num));
-  if (option_ptr != NULL)
-  {
-    dhcp->server_ip_addr.addr = htonl(dhcp_get_option_long(&option_ptr[2]));
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_STATE, ("dhcp_handle_offer(): server 0x%08"X32_F"\n", dhcp->server_ip_addr.addr));
-    /* remember offered address */
-    ip_addr_set(&dhcp->offered_ip_addr, (struct ip_addr *)&dhcp->msg_in->yiaddr);
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_STATE, ("dhcp_handle_offer(): offer for 0x%08"X32_F"\n", dhcp->offered_ip_addr.addr));
-
-    dhcp_select(netif);
-  }
-}
-
-/**
- * Select a DHCP server offer out of all offers.
- *
- * Simply select the first offer received.
- *
- * @param netif the netif under DHCP control
- * @return lwIP specific error (see error.h)
- */
-static err_t dhcp_select(struct netif *netif)
-{
-  struct dhcp *dhcp = netif->dhcp;
-  err_t result;
-  u32_t msecs;
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_select(netif=%p) %c%c%"U16_F"\n", (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num));
-
-  /* create and initialize the DHCP message header */
-  result = dhcp_create_request(netif);
-  if (result == ERR_OK)
-  {
-    dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN);
-    dhcp_option_byte(dhcp, DHCP_REQUEST);
-
-    dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
-    dhcp_option_short(dhcp, 576);
-
-    /* MUST request the offered IP address */
-    dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4);
-    dhcp_option_long(dhcp, ntohl(dhcp->offered_ip_addr.addr));
-
-    dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4);
-    dhcp_option_long(dhcp, ntohl(dhcp->server_ip_addr.addr));
-
-    dhcp_option(dhcp, DHCP_OPTION_PARAMETER_REQUEST_LIST, 4/*num options*/);
-    dhcp_option_byte(dhcp, DHCP_OPTION_SUBNET_MASK);
-    dhcp_option_byte(dhcp, DHCP_OPTION_ROUTER);
-    dhcp_option_byte(dhcp, DHCP_OPTION_BROADCAST);
-    dhcp_option_byte(dhcp, DHCP_OPTION_DNS_SERVER);
-
-    dhcp_option_trailer(dhcp);
-    /* shrink the pbuf to the actual content length */
-    pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
-
-    /* TODO: we really should bind to a specific local interface here
-       but we cannot specify an unconfigured netif as it is addressless */
-    udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);
-    /* send broadcast to any DHCP server */
-    udp_connect(dhcp->pcb, IP_ADDR_BROADCAST, DHCP_SERVER_PORT);
-    udp_send(dhcp->pcb, dhcp->p_out);
-    /* reconnect to any (or to server here?!) */
-    udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT);
-    dhcp_delete_request(netif);
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_select: REQUESTING\n"));
-    dhcp_set_state(dhcp, DHCP_REQUESTING);
-  } else {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_select: could not allocate DHCP request\n"));
-  }
-  dhcp->tries++;
-  msecs = dhcp->tries < 4 ? dhcp->tries * 1000 : 4 * 1000;
-  dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_STATE, ("dhcp_select(): set request timeout %"U32_F" msecs\n", msecs));
-  return result;
-}
-
-/**
- * The DHCP timer that checks for lease renewal/rebind timeouts.
- *
- */
-void dhcp_coarse_tmr()
-{
-  struct netif *netif = netif_list;
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_coarse_tmr()\n"));
-  /* iterate through all network interfaces */
-  while (netif != NULL) {
-    /* only act on DHCP configured interfaces */
-    if (netif->dhcp != NULL) {
-      /* timer is active (non zero), and triggers (zeroes) now? */
-      if (netif->dhcp->t2_timeout-- == 1) {
-        LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_coarse_tmr(): t2 timeout\n"));
-        /* this clients' rebind timeout triggered */
-        dhcp_t2_timeout(netif);
-      /* timer is active (non zero), and triggers (zeroes) now */
-      } else if (netif->dhcp->t1_timeout-- == 1) {
-        LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_coarse_tmr(): t1 timeout\n"));
-        /* this clients' renewal timeout triggered */
-        dhcp_t1_timeout(netif);
-      }
-    }
-    /* proceed to next netif */
-    netif = netif->next;
-  }
-}
-
-/**
- * DHCP transaction timeout handling
- *
- * A DHCP server is expected to respond within a short period of time.
- * This timer checks whether an outstanding DHCP request is timed out.
- * 
- */
-void dhcp_fine_tmr()
-{
-  struct netif *netif = netif_list;
-  /* loop through netif's */
-  while (netif != NULL) {
-    /* only act on DHCP configured interfaces */
-    if (netif->dhcp != NULL) {
-      /* timer is active (non zero), and is about to trigger now */
-      if (netif->dhcp->request_timeout-- == 1) {
-        /* { netif->dhcp->request_timeout == 0 } */
-        LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_fine_tmr(): request timeout\n"));
-        /* this clients' request timeout triggered */
-        dhcp_timeout(netif);
-      }
-    }
-    /* proceed to next network interface */
-    netif = netif->next;
-  }
-}
-
-/**
- * A DHCP negotiation transaction, or ARP request, has timed out.
- *
- * The timer that was started with the DHCP or ARP request has
- * timed out, indicating no response was received in time.
- *
- * @param netif the netif under DHCP control
- *
- */
-static void dhcp_timeout(struct netif *netif)
-{
-  struct dhcp *dhcp = netif->dhcp;
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_timeout()\n"));
-  /* back-off period has passed, or server selection timed out */
-  if ((dhcp->state == DHCP_BACKING_OFF) || (dhcp->state == DHCP_SELECTING)) {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_timeout(): restarting discovery\n"));
-    dhcp_discover(netif);
-  /* receiving the requested lease timed out */
-  } else if (dhcp->state == DHCP_REQUESTING) {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_timeout(): REQUESTING, DHCP request timed out\n"));
-    if (dhcp->tries <= 5) {
-      dhcp_select(netif);
-    } else {
-      LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_timeout(): REQUESTING, releasing, restarting\n"));
-      dhcp_release(netif);
-      dhcp_discover(netif);
-    }
-  /* received no ARP reply for the offered address (which is good) */
-  } else if (dhcp->state == DHCP_CHECKING) {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_timeout(): CHECKING, ARP request timed out\n"));
-    if (dhcp->tries <= 1) {
-      dhcp_check(netif);
-    /* no ARP replies on the offered address,
-       looks like the IP address is indeed free */
-    } else {
-      /* bind the interface to the offered address */
-      dhcp_bind(netif);
-    }
-  }
-  /* did not get response to renew request? */
-  else if (dhcp->state == DHCP_RENEWING) {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_timeout(): RENEWING, DHCP request timed out\n"));
-    /* just retry renewal */
-    /* note that the rebind timer will eventually time-out if renew does not work */
-    dhcp_renew(netif);
-  /* did not get response to rebind request? */
-  } else if (dhcp->state == DHCP_REBINDING) {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_timeout(): REBINDING, DHCP request timed out\n"));
-    if (dhcp->tries <= 8) {
-      dhcp_rebind(netif);
-    } else {
-      LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_timeout(): RELEASING, DISCOVERING\n"));
-      dhcp_release(netif);
-      dhcp_discover(netif);
-    }
-  }
-}
-
-/**
- * The renewal period has timed out.
- *
- * @param netif the netif under DHCP control
- */
-static void dhcp_t1_timeout(struct netif *netif)
-{
-  struct dhcp *dhcp = netif->dhcp;
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_STATE, ("dhcp_t1_timeout()\n"));
-  if ((dhcp->state == DHCP_REQUESTING) || (dhcp->state == DHCP_BOUND) || (dhcp->state == DHCP_RENEWING)) {
-    /* just retry to renew - note that the rebind timer (t2) will
-     * eventually time-out if renew tries fail. */
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_t1_timeout(): must renew\n"));
-    dhcp_renew(netif);
-  }
-}
-
-/**
- * The rebind period has timed out.
- *
- */
-static void dhcp_t2_timeout(struct netif *netif)
-{
-  struct dhcp *dhcp = netif->dhcp;
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_t2_timeout()\n"));
-  if ((dhcp->state == DHCP_REQUESTING) || (dhcp->state == DHCP_BOUND) || (dhcp->state == DHCP_RENEWING)) {
-    /* just retry to rebind */
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_t2_timeout(): must rebind\n"));
-    dhcp_rebind(netif);
-  }
-}
-
-/**
- *
- * @param netif the netif under DHCP control
- */
-static void dhcp_handle_ack(struct netif *netif)
-{
-  struct dhcp *dhcp = netif->dhcp;
-  u8_t *option_ptr;
-  /* clear options we might not get from the ACK */
-  dhcp->offered_sn_mask.addr = 0;
-  dhcp->offered_gw_addr.addr = 0;
-  dhcp->offered_bc_addr.addr = 0;
-
-  /* lease time given? */
-  option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_LEASE_TIME);
-  if (option_ptr != NULL) {
-    /* remember offered lease time */
-    dhcp->offered_t0_lease = dhcp_get_option_long(option_ptr + 2);
-  }
-  /* renewal period given? */
-  option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_T1);
-  if (option_ptr != NULL) {
-    /* remember given renewal period */
-    dhcp->offered_t1_renew = dhcp_get_option_long(option_ptr + 2);
-  } else {
-    /* calculate safe periods for renewal */
-    dhcp->offered_t1_renew = dhcp->offered_t0_lease / 2;
-  }
-
-  /* renewal period given? */
-  option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_T2);
-  if (option_ptr != NULL) {
-    /* remember given rebind period */
-    dhcp->offered_t2_rebind = dhcp_get_option_long(option_ptr + 2);
-  } else {
-    /* calculate safe periods for rebinding */
-    dhcp->offered_t2_rebind = dhcp->offered_t0_lease;
-  }
-
-  /* (y)our internet address */
-  ip_addr_set(&dhcp->offered_ip_addr, &dhcp->msg_in->yiaddr);
-
-/**
- * Patch #1308
- * TODO: we must check if the file field is not overloaded by DHCP options!
- */
-#if 0
-  /* boot server address */
-  ip_addr_set(&dhcp->offered_si_addr, &dhcp->msg_in->siaddr);
-  /* boot file name */
-  if (dhcp->msg_in->file[0]) {
-    dhcp->boot_file_name = mem_malloc(strlen(dhcp->msg_in->file) + 1);
-    strcpy(dhcp->boot_file_name, dhcp->msg_in->file);
-  }
-#endif
-
-  /* subnet mask */
-  option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_SUBNET_MASK);
-  /* subnet mask given? */
-  if (option_ptr != NULL) {
-    dhcp->offered_sn_mask.addr = htonl(dhcp_get_option_long(&option_ptr[2]));
-  }
-
-  /* gateway router */
-  option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_ROUTER);
-  if (option_ptr != NULL) {
-    dhcp->offered_gw_addr.addr = htonl(dhcp_get_option_long(&option_ptr[2]));
-  }
-
-  /* broadcast address */
-  option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_BROADCAST);
-  if (option_ptr != NULL) {
-    dhcp->offered_bc_addr.addr = htonl(dhcp_get_option_long(&option_ptr[2]));
-  }
-  
-  /* DNS servers */
-  option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_DNS_SERVER);
-  if (option_ptr != NULL) {
-    u8_t n;
-    dhcp->dns_count = dhcp_get_option_byte(&option_ptr[1]);
-    /* limit to at most DHCP_MAX_DNS DNS servers */
-    if (dhcp->dns_count > DHCP_MAX_DNS) dhcp->dns_count = DHCP_MAX_DNS;
-    for (n = 0; n < dhcp->dns_count; n++)
-    {
-      dhcp->offered_dns_addr[n].addr = htonl(dhcp_get_option_long(&option_ptr[2+(n<<2)]));
-    }
-  }
-}
-
-/**
- * Start DHCP negotiation for a network interface.
- *
- * If no DHCP client instance was attached to this interface,
- * a new client is created first. If a DHCP client instance
- * was already present, it restarts negotiation.
- *
- * @param netif The lwIP network interface
- * @return lwIP error code
- * - ERR_OK - No error
- * - ERR_MEM - Out of memory
- *
- */
-err_t dhcp_start(struct netif *netif)
-{
-  struct dhcp *dhcp = netif->dhcp;
-  err_t result = ERR_OK;
-
-  LWIP_ASSERT("netif != NULL", netif != NULL);
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_start(netif=%p) %c%c%"U16_F"\n", (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num));
-  netif->flags &= ~NETIF_FLAG_DHCP;
-
-  /* no DHCP client attached yet? */
-  if (dhcp == NULL) {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_start(): starting new DHCP client\n"));
-    dhcp = mem_malloc(sizeof(struct dhcp));
-    if (dhcp == NULL) {
-      LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_start(): could not allocate dhcp\n"));
-      return ERR_MEM;
-    }
-    /* store this dhcp client in the netif */
-    netif->dhcp = dhcp;
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_start(): allocated dhcp"));
-  /* already has DHCP client attached */
-  } else {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE | 3, ("dhcp_start(): restarting DHCP configuration\n"));
-  }
-       
-       /* clear data structure */
-       memset(dhcp, 0, sizeof(struct dhcp));
-  /* allocate UDP PCB */
-       dhcp->pcb = udp_new();
-       if (dhcp->pcb == NULL) {
-         LWIP_DEBUGF(DHCP_DEBUG  | DBG_TRACE, ("dhcp_start(): could not obtain pcb\n"));
-         mem_free((void *)dhcp);
-         netif->dhcp = dhcp = NULL;
-         return ERR_MEM;
-       }
-       LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_start(): starting DHCP configuration\n"));
-  /* (re)start the DHCP negotiation */
-  result = dhcp_discover(netif);
-  if (result != ERR_OK) {
-    /* free resources allocated above */
-    dhcp_stop(netif);
-    return ERR_MEM;
-  }
-  netif->flags |= NETIF_FLAG_DHCP;
-  return result;
-}
-
-/**
- * Inform a DHCP server of our manual configuration.
- *
- * This informs DHCP servers of our fixed IP address configuration
- * by sending an INFORM message. It does not involve DHCP address
- * configuration, it is just here to be nice to the network.
- *
- * @param netif The lwIP network interface
- *
- */
-void dhcp_inform(struct netif *netif)
-{
-  struct dhcp *dhcp;
-  err_t result = ERR_OK;
-  dhcp = mem_malloc(sizeof(struct dhcp));
-  if (dhcp == NULL) {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_inform(): could not allocate dhcp\n"));
-    return;
-  }
-  netif->dhcp = dhcp;
-  memset(dhcp, 0, sizeof(struct dhcp));
-
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_inform(): allocated dhcp\n"));
-  dhcp->pcb = udp_new();
-  if (dhcp->pcb == NULL) {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_inform(): could not obtain pcb"));
-    mem_free((void *)dhcp);
-    return;
-  }
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_inform(): created new udp pcb\n"));
-  /* create and initialize the DHCP message header */
-  result = dhcp_create_request(netif);
-  if (result == ERR_OK) {
-
-    dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN);
-    dhcp_option_byte(dhcp, DHCP_INFORM);
-
-    dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
-    /* TODO: use netif->mtu ?! */
-    dhcp_option_short(dhcp, 576);
-
-    dhcp_option_trailer(dhcp);
-
-    pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
-
-    udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);
-    udp_connect(dhcp->pcb, IP_ADDR_BROADCAST, DHCP_SERVER_PORT);
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_inform: INFORMING\n"));
-    udp_send(dhcp->pcb, dhcp->p_out);
-    udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT);
-    dhcp_delete_request(netif);
-  } else {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_inform: could not allocate DHCP request\n"));
-  }
-
-  if (dhcp != NULL)
-  {
-    if (dhcp->pcb != NULL) udp_remove(dhcp->pcb);
-    dhcp->pcb = NULL;
-    mem_free((void *)dhcp);
-    netif->dhcp = NULL;
-  }
-}
-
-#if DHCP_DOES_ARP_CHECK
-/**
- * Match an ARP reply with the offered IP address.
- *
- * @param addr The IP address we received a reply from
- *
- */
-void dhcp_arp_reply(struct netif *netif, struct ip_addr *addr)
-{
-  LWIP_ASSERT("netif != NULL", netif != NULL);
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_arp_reply()\n"));
-  /* is a DHCP client doing an ARP check? */
-  if ((netif->dhcp != NULL) && (netif->dhcp->state == DHCP_CHECKING)) {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_arp_reply(): CHECKING, arp reply for 0x%08"X32_F"\n", addr->addr));
-    /* did a host respond with the address we
-       were offered by the DHCP server? */
-    if (ip_addr_cmp(addr, &netif->dhcp->offered_ip_addr)) {
-      /* we will not accept the offered address */
-      LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE | 1, ("dhcp_arp_reply(): arp reply matched with offered address, declining\n"));
-      dhcp_decline(netif);
-    }
-  }
-}
-
-/**
- * Decline an offered lease.
- *
- * Tell the DHCP server we do not accept the offered address.
- * One reason to decline the lease is when we find out the address
- * is already in use by another host (through ARP).
- */
-static err_t dhcp_decline(struct netif *netif)
-{
-  struct dhcp *dhcp = netif->dhcp;
-  err_t result = ERR_OK;
-  u16_t msecs;
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_decline()\n"));
-  dhcp_set_state(dhcp, DHCP_BACKING_OFF);
-  /* create and initialize the DHCP message header */
-  result = dhcp_create_request(netif);
-  if (result == ERR_OK)
-  {
-    dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN);
-    dhcp_option_byte(dhcp, DHCP_DECLINE);
-
-    dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
-    dhcp_option_short(dhcp, 576);
-
-    dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4);
-    dhcp_option_long(dhcp, ntohl(dhcp->offered_ip_addr.addr));
-
-    dhcp_option_trailer(dhcp);
-    /* resize pbuf to reflect true size of options */
-    pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
-
-    udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);
-    /* @todo: should we really connect here? we are performing sendto() */
-    udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT);
-    /* per section 4.4.4, broadcast DECLINE messages */
-    udp_sendto(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT);
-    dhcp_delete_request(netif);
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_decline: BACKING OFF\n"));
-  } else {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_decline: could not allocate DHCP request\n"));
-  }
-  dhcp->tries++;
-  msecs = 10*1000;
-  dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
-   LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_decline(): set request timeout %"U16_F" msecs\n", msecs));
-  return result;
-}
-#endif
-
-
-/**
- * Start the DHCP process, discover a DHCP server.
- *
- */
-static err_t dhcp_discover(struct netif *netif)
-{
-  struct dhcp *dhcp = netif->dhcp;
-  err_t result = ERR_OK;
-  u16_t msecs;
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_discover()\n"));
-  ip_addr_set(&dhcp->offered_ip_addr, IP_ADDR_ANY);
-  /* create and initialize the DHCP message header */
-  result = dhcp_create_request(netif);
-  if (result == ERR_OK)
-  {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_discover: making request\n"));
-    dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN);
-    dhcp_option_byte(dhcp, DHCP_DISCOVER);
-
-    dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
-    dhcp_option_short(dhcp, 576);
-
-    dhcp_option(dhcp, DHCP_OPTION_PARAMETER_REQUEST_LIST, 4/*num options*/);
-    dhcp_option_byte(dhcp, DHCP_OPTION_SUBNET_MASK);
-    dhcp_option_byte(dhcp, DHCP_OPTION_ROUTER);
-    dhcp_option_byte(dhcp, DHCP_OPTION_BROADCAST);
-    dhcp_option_byte(dhcp, DHCP_OPTION_DNS_SERVER);
-
-    dhcp_option_trailer(dhcp);
-
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_discover: realloc()ing\n"));
-    pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
-
-    /* set receive callback function with netif as user data */
-    udp_recv(dhcp->pcb, dhcp_recv, netif);
-    udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);
-    udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT);
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_discover: sendto(DISCOVER, IP_ADDR_BROADCAST, DHCP_SERVER_PORT)\n"));
-    udp_sendto(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT);
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_discover: deleting()ing\n"));
-    dhcp_delete_request(netif);
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_discover: SELECTING\n"));
-    dhcp_set_state(dhcp, DHCP_SELECTING);
-  } else {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_discover: could not allocate DHCP request\n"));
-  }
-  dhcp->tries++;
-  msecs = dhcp->tries < 4 ? (dhcp->tries + 1) * 1000 : 10 * 1000;
-  dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_discover(): set request timeout %"U16_F" msecs\n", msecs));
-  return result;
-}
-
-
-/**
- * Bind the interface to the offered IP address.
- *
- * @param netif network interface to bind to the offered address
- */
-static void dhcp_bind(struct netif *netif)
-{
-  struct dhcp *dhcp = netif->dhcp;
-  struct ip_addr sn_mask, gw_addr;
-  LWIP_ASSERT("dhcp_bind: netif != NULL", netif != NULL);
-  LWIP_ASSERT("dhcp_bind: dhcp != NULL", dhcp != NULL);
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_bind(netif=%p) %c%c%"U16_F"\n", (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num));
-
-  /* temporary DHCP lease? */
-  if (dhcp->offered_t1_renew != 0xffffffffUL) {
-    /* set renewal period timer */
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_bind(): t1 renewal timer %"U32_F" secs\n", dhcp->offered_t1_renew));
-    dhcp->t1_timeout = (dhcp->offered_t1_renew + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS;
-    if (dhcp->t1_timeout == 0) dhcp->t1_timeout = 1;
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_bind(): set request timeout %"U32_F" msecs\n", dhcp->offered_t1_renew*1000));
-  }
-  /* set renewal period timer */
-  if (dhcp->offered_t2_rebind != 0xffffffffUL) {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_bind(): t2 rebind timer %"U32_F" secs\n", dhcp->offered_t2_rebind));
-    dhcp->t2_timeout = (dhcp->offered_t2_rebind + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS;
-    if (dhcp->t2_timeout == 0) dhcp->t2_timeout = 1;
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_bind(): set request timeout %"U32_F" msecs\n", dhcp->offered_t2_rebind*1000));
-  }
-  /* copy offered network mask */
-  ip_addr_set(&sn_mask, &dhcp->offered_sn_mask);
-
-  /* subnet mask not given? */
-  /* TODO: this is not a valid check. what if the network mask is 0? */
-  if (sn_mask.addr == 0) {
-    /* choose a safe subnet mask given the network class */
-    u8_t first_octet = ip4_addr1(&sn_mask);
-    if (first_octet <= 127) sn_mask.addr = htonl(0xff000000);
-    else if (first_octet >= 192) sn_mask.addr = htonl(0xffffff00);
-    else sn_mask.addr = htonl(0xffff0000);
-  }
-
-  ip_addr_set(&gw_addr, &dhcp->offered_gw_addr);
-  /* gateway address not given? */
-  if (gw_addr.addr == 0) {
-    /* copy network address */
-    gw_addr.addr = (dhcp->offered_ip_addr.addr & sn_mask.addr);
-    /* use first host address on network as gateway */
-    gw_addr.addr |= htonl(0x00000001);
-  }
-
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_STATE, ("dhcp_bind(): IP: 0x%08"X32_F"\n", dhcp->offered_ip_addr.addr));
-  netif_set_ipaddr(netif, &dhcp->offered_ip_addr);
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_STATE, ("dhcp_bind(): SN: 0x%08"X32_F"\n", sn_mask.addr));
-  netif_set_netmask(netif, &sn_mask);
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_STATE, ("dhcp_bind(): GW: 0x%08"X32_F"\n", gw_addr.addr));
-  netif_set_gw(netif, &gw_addr);
-  /* bring the interface up */
-  netif_set_up(netif);
-  /* netif is now bound to DHCP leased address */
-  dhcp_set_state(dhcp, DHCP_BOUND);
-}
-
-/**
- * Renew an existing DHCP lease at the involved DHCP server.
- *
- * @param netif network interface which must renew its lease
- */
-err_t dhcp_renew(struct netif *netif)
-{
-  struct dhcp *dhcp = netif->dhcp;
-  err_t result;
-  u16_t msecs;
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_renew()\n"));
-  dhcp_set_state(dhcp, DHCP_RENEWING);
-
-  /* create and initialize the DHCP message header */
-  result = dhcp_create_request(netif);
-  if (result == ERR_OK) {
-
-    dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN);
-    dhcp_option_byte(dhcp, DHCP_REQUEST);
-
-    dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
-    /* TODO: use netif->mtu in some way */
-    dhcp_option_short(dhcp, 576);
-
-#if 0
-    dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4);
-    dhcp_option_long(dhcp, ntohl(dhcp->offered_ip_addr.addr));
-#endif
-
-#if 0
-    dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4);
-    dhcp_option_long(dhcp, ntohl(dhcp->server_ip_addr.addr));
-#endif
-    /* append DHCP message trailer */
-    dhcp_option_trailer(dhcp);
-
-    pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
-
-    udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);
-    udp_connect(dhcp->pcb, &dhcp->server_ip_addr, DHCP_SERVER_PORT);
-    udp_send(dhcp->pcb, dhcp->p_out);
-    dhcp_delete_request(netif);
-
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_renew: RENEWING\n"));
-  } else {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_renew: could not allocate DHCP request\n"));
-  }
-  dhcp->tries++;
-  /* back-off on retries, but to a maximum of 20 seconds */
-  msecs = dhcp->tries < 10 ? dhcp->tries * 2000 : 20 * 1000;
-  dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
-   LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_renew(): set request timeout %"U16_F" msecs\n", msecs));
-  return result;
-}
-
-/**
- * Rebind with a DHCP server for an existing DHCP lease.
- *
- * @param netif network interface which must rebind with a DHCP server
- */
-static err_t dhcp_rebind(struct netif *netif)
-{
-  struct dhcp *dhcp = netif->dhcp;
-  err_t result;
-  u16_t msecs;
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_rebind()\n"));
-  dhcp_set_state(dhcp, DHCP_REBINDING);
-
-  /* create and initialize the DHCP message header */
-  result = dhcp_create_request(netif);
-  if (result == ERR_OK)
-  {
-
-    dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN);
-    dhcp_option_byte(dhcp, DHCP_REQUEST);
-
-    dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
-    dhcp_option_short(dhcp, 576);
-
-#if 0
-    dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4);
-    dhcp_option_long(dhcp, ntohl(dhcp->offered_ip_addr.addr));
-
-    dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4);
-    dhcp_option_long(dhcp, ntohl(dhcp->server_ip_addr.addr));
-#endif
-
-    dhcp_option_trailer(dhcp);
-
-    pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
-
-    /* set remote IP association to any DHCP server */
-    udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);
-    udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT);
-    /* broadcast to server */
-    udp_sendto(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT);
-    dhcp_delete_request(netif);
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_rebind: REBINDING\n"));
-  } else {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_rebind: could not allocate DHCP request\n"));
-  }
-  dhcp->tries++;
-  msecs = dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000;
-  dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
-   LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_rebind(): set request timeout %"U16_F" msecs\n", msecs));
-  return result;
-}
-
-/**
- * Release a DHCP lease.
- *
- * @param netif network interface which must release its lease
- */
-err_t dhcp_release(struct netif *netif)
-{
-  struct dhcp *dhcp = netif->dhcp;
-  err_t result;
-  u16_t msecs;
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_release()\n"));
-
-  /* idle DHCP client */
-  dhcp_set_state(dhcp, DHCP_OFF);
-  /* clean old DHCP offer */
-  dhcp->server_ip_addr.addr = 0;
-  dhcp->offered_ip_addr.addr = dhcp->offered_sn_mask.addr = 0;
-  dhcp->offered_gw_addr.addr = dhcp->offered_bc_addr.addr = 0;
-  dhcp->offered_t0_lease = dhcp->offered_t1_renew = dhcp->offered_t2_rebind = 0;
-  dhcp->dns_count = 0;
-  
-  /* create and initialize the DHCP message header */
-  result = dhcp_create_request(netif);
-  if (result == ERR_OK) {
-    dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN);
-    dhcp_option_byte(dhcp, DHCP_RELEASE);
-
-    dhcp_option_trailer(dhcp);
-
-    pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
-
-    udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);
-    udp_connect(dhcp->pcb, &dhcp->server_ip_addr, DHCP_SERVER_PORT);
-    udp_send(dhcp->pcb, dhcp->p_out);
-    dhcp_delete_request(netif);
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_release: RELEASED, DHCP_OFF\n"));
-  } else {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_release: could not allocate DHCP request\n"));
-  }
-  dhcp->tries++;
-  msecs = dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000;
-  dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_release(): set request timeout %"U16_F" msecs\n", msecs));
-  /* bring the interface down */
-  netif_set_down(netif);
-  /* remove IP address from interface */
-  netif_set_ipaddr(netif, IP_ADDR_ANY);
-  netif_set_gw(netif, IP_ADDR_ANY);
-  netif_set_netmask(netif, IP_ADDR_ANY);
-  
-  /* TODO: netif_down(netif); */
-  return result;
-}
-/**
- * Remove the DHCP client from the interface.
- *
- * @param netif The network interface to stop DHCP on
- */
-void dhcp_stop(struct netif *netif)
-{
-  struct dhcp *dhcp = netif->dhcp;
-  LWIP_ASSERT("dhcp_stop: netif != NULL", netif != NULL);
-
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_stop()\n"));
-  /* netif is DHCP configured? */
-  if (dhcp != NULL)
-  {
-    if (dhcp->pcb != NULL)
-    {
-      udp_remove(dhcp->pcb);
-      dhcp->pcb = NULL;
-    }
-    if (dhcp->p != NULL)
-    {
-      pbuf_free(dhcp->p);
-      dhcp->p = NULL;
-    }
-    /* free unfolded reply */
-    dhcp_free_reply(dhcp);
-    mem_free((void *)dhcp);
-    netif->dhcp = NULL;
-  }
-}
-
-/*
- * Set the DHCP state of a DHCP client.
- *
- * If the state changed, reset the number of tries.
- *
- * TODO: we might also want to reset the timeout here?
- */
-static void dhcp_set_state(struct dhcp *dhcp, u8_t new_state)
-{
-  if (new_state != dhcp->state)
-  {
-    dhcp->state = new_state;
-    dhcp->tries = 0;
-  }
-}
-
-/*
- * Concatenate an option type and length field to the outgoing
- * DHCP message.
- *
- */
-static void dhcp_option(struct dhcp *dhcp, u8_t option_type, u8_t option_len)
-{
-  LWIP_ASSERT("dhcp_option_short: dhcp->options_out_len + 2 + option_len <= DHCP_OPTIONS_LEN", dhcp->options_out_len + 2 + option_len <= DHCP_OPTIONS_LEN);
-  dhcp->msg_out->options[dhcp->options_out_len++] = option_type;
-  dhcp->msg_out->options[dhcp->options_out_len++] = option_len;
-}
-/*
- * Concatenate a single byte to the outgoing DHCP message.
- *
- */
-static void dhcp_option_byte(struct dhcp *dhcp, u8_t value)
-{
-  LWIP_ASSERT("dhcp_option_short: dhcp->options_out_len < DHCP_OPTIONS_LEN", dhcp->options_out_len < DHCP_OPTIONS_LEN);
-  dhcp->msg_out->options[dhcp->options_out_len++] = value;
-}
-static void dhcp_option_short(struct dhcp *dhcp, u16_t value)
-{
-  LWIP_ASSERT("dhcp_option_short: dhcp->options_out_len + 2 <= DHCP_OPTIONS_LEN", dhcp->options_out_len + 2 <= DHCP_OPTIONS_LEN);
-  dhcp->msg_out->options[dhcp->options_out_len++] = (value & 0xff00U) >> 8;
-  dhcp->msg_out->options[dhcp->options_out_len++] =  value & 0x00ffU;
-}
-static void dhcp_option_long(struct dhcp *dhcp, u32_t value)
-{
-  LWIP_ASSERT("dhcp_option_long: dhcp->options_out_len + 4 <= DHCP_OPTIONS_LEN", dhcp->options_out_len + 4 <= DHCP_OPTIONS_LEN);
-  dhcp->msg_out->options[dhcp->options_out_len++] = (value & 0xff000000UL) >> 24;
-  dhcp->msg_out->options[dhcp->options_out_len++] = (value & 0x00ff0000UL) >> 16;
-  dhcp->msg_out->options[dhcp->options_out_len++] = (value & 0x0000ff00UL) >> 8;
-  dhcp->msg_out->options[dhcp->options_out_len++] = (value & 0x000000ffUL);
-}
-
-/**
- * Extract the DHCP message and the DHCP options.
- *
- * Extract the DHCP message and the DHCP options, each into a contiguous
- * piece of memory. As a DHCP message is variable sized by its options,
- * and also allows overriding some fields for options, the easy approach
- * is to first unfold the options into a conitguous piece of memory, and
- * use that further on.
- *
- */
-static err_t dhcp_unfold_reply(struct dhcp *dhcp)
-{
-  struct pbuf *p = dhcp->p;
-  u8_t *ptr;
-  u16_t i;
-  u16_t j = 0;
-  LWIP_ASSERT("dhcp->p != NULL", dhcp->p != NULL);
-  /* free any left-overs from previous unfolds */
-  dhcp_free_reply(dhcp);
-  /* options present? */
-  if (dhcp->p->tot_len > (sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN))
-  {
-    dhcp->options_in_len = dhcp->p->tot_len - (sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN);
-    dhcp->options_in = mem_malloc(dhcp->options_in_len);
-    if (dhcp->options_in == NULL)
-    {
-      LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_unfold_reply(): could not allocate dhcp->options\n"));
-      return ERR_MEM;
-    }
-  }
-  dhcp->msg_in = mem_malloc(sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN);
-  if (dhcp->msg_in == NULL)
-  {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_unfold_reply(): could not allocate dhcp->msg_in\n"));
-    mem_free((void *)dhcp->options_in);
-    dhcp->options_in = NULL;
-    return ERR_MEM;
-  }
-
-  ptr = (u8_t *)dhcp->msg_in;
-  /* proceed through struct dhcp_msg */
-  for (i = 0; i < sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN; i++)
-  {
-    *ptr++ = ((u8_t *)p->payload)[j++];
-    /* reached end of pbuf? */
-    if (j == p->len)
-    {
-      /* proceed to next pbuf in chain */
-      p = p->next;
-      j = 0;
-    }
-  }
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_unfold_reply(): copied %"U16_F" bytes into dhcp->msg_in[]\n", i));
-  if (dhcp->options_in != NULL) {
-    ptr = (u8_t *)dhcp->options_in;
-    /* proceed through options */
-    for (i = 0; i < dhcp->options_in_len; i++) {
-      *ptr++ = ((u8_t *)p->payload)[j++];
-      /* reached end of pbuf? */
-      if (j == p->len) {
-        /* proceed to next pbuf in chain */
-        p = p->next;
-        j = 0;
-      }
-    }
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_unfold_reply(): copied %"U16_F" bytes to dhcp->options_in[]\n", i));
-  }
-  return ERR_OK;
-}
-
-/**
- * Free the incoming DHCP message including contiguous copy of
- * its DHCP options.
- *
- */
-static void dhcp_free_reply(struct dhcp *dhcp)
-{
-  if (dhcp->msg_in != NULL) {
-    mem_free((void *)dhcp->msg_in);
-    dhcp->msg_in = NULL;
-  }
-  if (dhcp->options_in) {
-    mem_free((void *)dhcp->options_in);
-    dhcp->options_in = NULL;
-    dhcp->options_in_len = 0;
-  }
-  LWIP_DEBUGF(DHCP_DEBUG, ("dhcp_free_reply(): free'd\n"));
-}
-
-
-/**
- * If an incoming DHCP message is in response to us, then trigger the state machine
- */
-static void dhcp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u16_t port)
-{
-  struct netif *netif = (struct netif *)arg;
-  struct dhcp *dhcp = netif->dhcp;
-  struct dhcp_msg *reply_msg = (struct dhcp_msg *)p->payload;
-  u8_t *options_ptr;
-  u8_t msg_type;
-  u8_t i;
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_recv(pbuf = %p) from DHCP server %"U16_F".%"U16_F".%"U16_F".%"U16_F" port %"U16_F"\n", (void*)p,
-    (u16_t)(ntohl(addr->addr) >> 24 & 0xff), (u16_t)(ntohl(addr->addr) >> 16 & 0xff),
-    (u16_t)(ntohl(addr->addr) >>  8 & 0xff), (u16_t)(ntohl(addr->addr) & 0xff), port));
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("pbuf->len = %"U16_F"\n", p->len));
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("pbuf->tot_len = %"U16_F"\n", p->tot_len));
-  /* prevent warnings about unused arguments */
-  (void)pcb; (void)addr; (void)port;
-  dhcp->p = p;
-  /* TODO: check packet length before reading them */
-  if (reply_msg->op != DHCP_BOOTREPLY) {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 1, ("not a DHCP reply message, but type %"U16_F"\n", (u16_t)reply_msg->op));
-    pbuf_free(p);
-    dhcp->p = NULL;
-    return;
-  }
-  /* iterate through hardware address and match against DHCP message */
-  for (i = 0; i < netif->hwaddr_len; i++) {
-    if (netif->hwaddr[i] != reply_msg->chaddr[i]) {
-      LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("netif->hwaddr[%"U16_F"]==%02"X16_F" != reply_msg->chaddr[%"U16_F"]==%02"X16_F"\n",
-        (u16_t)i, (u16_t)netif->hwaddr[i], (u16_t)i, (u16_t)reply_msg->chaddr[i]));
-      pbuf_free(p);
-      dhcp->p = NULL;
-      return;
-    }
-  }
-  /* match transaction ID against what we expected */
-  if (ntohl(reply_msg->xid) != dhcp->xid) {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("transaction id mismatch\n"));
-    pbuf_free(p);
-    dhcp->p = NULL;
-    return;
-  }
-  /* option fields could be unfold? */
-  if (dhcp_unfold_reply(dhcp) != ERR_OK) {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("problem unfolding DHCP message - too short on memory?\n"));
-    pbuf_free(p);
-    dhcp->p = NULL;
-    return;
-  }
-
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("searching DHCP_OPTION_MESSAGE_TYPE\n"));
-  /* obtain pointer to DHCP message type */
-  options_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_MESSAGE_TYPE);
-  if (options_ptr == NULL) {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 1, ("DHCP_OPTION_MESSAGE_TYPE option not found\n"));
-    pbuf_free(p);
-    dhcp->p = NULL;
-    return;
-  }
-
-  /* read DHCP message type */
-  msg_type = dhcp_get_option_byte(options_ptr + 2);
-  /* message type is DHCP ACK? */
-  if (msg_type == DHCP_ACK) {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 1, ("DHCP_ACK received\n"));
-    /* in requesting state? */
-    if (dhcp->state == DHCP_REQUESTING) {
-      dhcp_handle_ack(netif);
-      dhcp->request_timeout = 0;
-#if DHCP_DOES_ARP_CHECK
-      /* check if the acknowledged lease address is already in use */
-      dhcp_check(netif);
-#else
-      /* bind interface to the acknowledged lease address */
-      dhcp_bind(netif);
-#endif
-    }
-    /* already bound to the given lease address? */
-    else if ((dhcp->state == DHCP_REBOOTING) || (dhcp->state == DHCP_REBINDING) || (dhcp->state == DHCP_RENEWING)) {
-      dhcp->request_timeout = 0;
-      dhcp_bind(netif);
-    }
-  }
-  /* received a DHCP_NAK in appropriate state? */
-  else if ((msg_type == DHCP_NAK) &&
-    ((dhcp->state == DHCP_REBOOTING) || (dhcp->state == DHCP_REQUESTING) ||
-     (dhcp->state == DHCP_REBINDING) || (dhcp->state == DHCP_RENEWING  ))) {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 1, ("DHCP_NAK received\n"));
-    dhcp->request_timeout = 0;
-    dhcp_handle_nak(netif);
-  }
-  /* received a DHCP_OFFER in DHCP_SELECTING state? */
-  else if ((msg_type == DHCP_OFFER) && (dhcp->state == DHCP_SELECTING)) {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 1, ("DHCP_OFFER received in DHCP_SELECTING state\n"));
-    dhcp->request_timeout = 0;
-    /* remember offered lease */
-    dhcp_handle_offer(netif);
-  }
-  pbuf_free(p);
-  dhcp->p = NULL;
-}
-
-
-static err_t dhcp_create_request(struct netif *netif)
-{
-  struct dhcp *dhcp = netif->dhcp;
-  u16_t i;
-  LWIP_ASSERT("dhcp_create_request: dhcp->p_out == NULL", dhcp->p_out == NULL);
-  LWIP_ASSERT("dhcp_create_request: dhcp->msg_out == NULL", dhcp->msg_out == NULL);
-  dhcp->p_out = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct dhcp_msg), PBUF_RAM);
-  if (dhcp->p_out == NULL) {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_create_request(): could not allocate pbuf\n"));
-    return ERR_MEM;
-  }
-  /* give unique transaction identifier to this request */
-  dhcp->xid = xid++;
-
-  dhcp->msg_out = (struct dhcp_msg *)dhcp->p_out->payload;
-
-  dhcp->msg_out->op = DHCP_BOOTREQUEST;
-  /* TODO: make link layer independent */
-  dhcp->msg_out->htype = DHCP_HTYPE_ETH;
-  /* TODO: make link layer independent */
-  dhcp->msg_out->hlen = DHCP_HLEN_ETH;
-  dhcp->msg_out->hops = 0;
-  dhcp->msg_out->xid = htonl(dhcp->xid);
-  dhcp->msg_out->secs = 0;
-  dhcp->msg_out->flags = 0;
-  dhcp->msg_out->ciaddr.addr = netif->ip_addr.addr;
-  dhcp->msg_out->yiaddr.addr = 0;
-  dhcp->msg_out->siaddr.addr = 0;
-  dhcp->msg_out->giaddr.addr = 0;
-  for (i = 0; i < DHCP_CHADDR_LEN; i++) {
-    /* copy netif hardware address, pad with zeroes */
-    dhcp->msg_out->chaddr[i] = (i < netif->hwaddr_len) ? netif->hwaddr[i] : 0/* pad byte*/;
-  }
-  for (i = 0; i < DHCP_SNAME_LEN; i++) dhcp->msg_out->sname[i] = 0;
-  for (i = 0; i < DHCP_FILE_LEN; i++) dhcp->msg_out->file[i] = 0;
-  dhcp->msg_out->cookie = htonl(0x63825363UL);
-  dhcp->options_out_len = 0;
-  /* fill options field with an incrementing array (for debugging purposes) */
-  for (i = 0; i < DHCP_OPTIONS_LEN; i++) dhcp->msg_out->options[i] = i;
-  return ERR_OK;
-}
-
-static void dhcp_delete_request(struct netif *netif)
-{
-  struct dhcp *dhcp = netif->dhcp;
-  LWIP_ASSERT("dhcp_free_msg: dhcp->p_out != NULL", dhcp->p_out != NULL);
-  LWIP_ASSERT("dhcp_free_msg: dhcp->msg_out != NULL", dhcp->msg_out != NULL);
-  pbuf_free(dhcp->p_out);
-  dhcp->p_out = NULL;
-  dhcp->msg_out = NULL;
-}
-
-/**
- * Add a DHCP message trailer
- *
- * Adds the END option to the DHCP message, and if
- * necessary, up to three padding bytes.
- */
-
-static void dhcp_option_trailer(struct dhcp *dhcp)
-{
-  LWIP_ASSERT("dhcp_option_trailer: dhcp->msg_out != NULL\n", dhcp->msg_out != NULL);
-  LWIP_ASSERT("dhcp_option_trailer: dhcp->options_out_len < DHCP_OPTIONS_LEN\n", dhcp->options_out_len < DHCP_OPTIONS_LEN);
-  dhcp->msg_out->options[dhcp->options_out_len++] = DHCP_OPTION_END;
-  /* packet is too small, or not 4 byte aligned? */
-  while ((dhcp->options_out_len < DHCP_MIN_OPTIONS_LEN) || (dhcp->options_out_len & 3)) {
-    /* LWIP_DEBUGF(DHCP_DEBUG,("dhcp_option_trailer:dhcp->options_out_len=%"U16_F", DHCP_OPTIONS_LEN=%"U16_F, dhcp->options_out_len, DHCP_OPTIONS_LEN)); */
-    LWIP_ASSERT("dhcp_option_trailer: dhcp->options_out_len < DHCP_OPTIONS_LEN\n", dhcp->options_out_len < DHCP_OPTIONS_LEN);
-    /* add a fill/padding byte */
-    dhcp->msg_out->options[dhcp->options_out_len++] = 0;
-  }
-}
-
-/**
- * Find the offset of a DHCP option inside the DHCP message.
- *
- * @param client DHCP client
- * @param option_type
- *
- * @return a byte offset into the UDP message where the option was found, or
- * zero if the given option was not found.
- */
-static u8_t *dhcp_get_option_ptr(struct dhcp *dhcp, u8_t option_type)
-{
-  u8_t overload = DHCP_OVERLOAD_NONE;
-
-  /* options available? */
-  if ((dhcp->options_in != NULL) && (dhcp->options_in_len > 0)) {
-    /* start with options field */
-    u8_t *options = (u8_t *)dhcp->options_in;
-    u16_t offset = 0;
-    /* at least 1 byte to read and no end marker, then at least 3 bytes to read? */
-    while ((offset < dhcp->options_in_len) && (options[offset] != DHCP_OPTION_END)) {
-      /* LWIP_DEBUGF(DHCP_DEBUG, ("msg_offset=%"U16_F", q->len=%"U16_F, msg_offset, q->len)); */
-      /* are the sname and/or file field overloaded with options? */
-      if (options[offset] == DHCP_OPTION_OVERLOAD) {
-        LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("overloaded message detected\n"));
-        /* skip option type and length */
-        offset += 2;
-        overload = options[offset++];
-      }
-      /* requested option found */
-      else if (options[offset] == option_type) {
-        LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("option found at offset %"U16_F" in options\n", offset));
-        return &options[offset];
-      /* skip option */
-      } else {
-         LWIP_DEBUGF(DHCP_DEBUG, ("skipping option %"U16_F" in options\n", options[offset]));
-        /* skip option type */
-        offset++;
-        /* skip option length, and then length bytes */
-        offset += 1 + options[offset];
-      }
-    }
-    /* is this an overloaded message? */
-    if (overload != DHCP_OVERLOAD_NONE) {
-      u16_t field_len;
-      if (overload == DHCP_OVERLOAD_FILE) {
-        LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 1, ("overloaded file field\n"));
-        options = (u8_t *)&dhcp->msg_in->file;
-        field_len = DHCP_FILE_LEN;
-      } else if (overload == DHCP_OVERLOAD_SNAME) {
-        LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 1, ("overloaded sname field\n"));
-        options = (u8_t *)&dhcp->msg_in->sname;
-        field_len = DHCP_SNAME_LEN;
-      /* TODO: check if else if () is necessary */
-      } else {
-        LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 1, ("overloaded sname and file field\n"));
-        options = (u8_t *)&dhcp->msg_in->sname;
-        field_len = DHCP_FILE_LEN + DHCP_SNAME_LEN;
-      }
-      offset = 0;
-
-      /* at least 1 byte to read and no end marker */
-      while ((offset < field_len) && (options[offset] != DHCP_OPTION_END)) {
-        if (options[offset] == option_type) {
-           LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("option found at offset=%"U16_F"\n", offset));
-          return &options[offset];
-        /* skip option */
-        } else {
-          LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("skipping option %"U16_F"\n", options[offset]));
-          /* skip option type */
-          offset++;
-          offset += 1 + options[offset];
-        }
-      }
-    }
-  }
-  return 0;
-}
-
-/**
- * Return the byte of DHCP option data.
- *
- * @param client DHCP client.
- * @param ptr pointer obtained by dhcp_get_option_ptr().
- *
- * @return byte value at the given address.
- */
-static u8_t dhcp_get_option_byte(u8_t *ptr)
-{
-  LWIP_DEBUGF(DHCP_DEBUG, ("option byte value=%"U16_F"\n", (u16_t)(*ptr)));
-  return *ptr;
-}
-
-/**
- * Return the 16-bit value of DHCP option data.
- *
- * @param client DHCP client.
- * @param ptr pointer obtained by dhcp_get_option_ptr().
- *
- * @return byte value at the given address.
- */
-static u16_t dhcp_get_option_short(u8_t *ptr)
-{
-  u16_t value;
-  value = *ptr++ << 8;
-  value |= *ptr;
-  LWIP_DEBUGF(DHCP_DEBUG, ("option short value=%"U16_F"\n", value));
-  return value;
-}
-
-/**
- * Return the 32-bit value of DHCP option data.
- *
- * @param client DHCP client.
- * @param ptr pointer obtained by dhcp_get_option_ptr().
- *
- * @return byte value at the given address.
- */
-static u32_t dhcp_get_option_long(u8_t *ptr)
-{
-  u32_t value;
-  value = (u32_t)(*ptr++) << 24;
-  value |= (u32_t)(*ptr++) << 16;
-  value |= (u32_t)(*ptr++) << 8;
-  value |= (u32_t)(*ptr++);
-  LWIP_DEBUGF(DHCP_DEBUG, ("option long value=%"U32_F"\n", value));
-  return value;
-}
-
-#endif /* LWIP_DHCP */
+/**\r
+ * @file\r
+ *\r
+ * Dynamic Host Configuration Protocol client\r
+ */\r
+\r
+/*\r
+ *\r
+ * Copyright (c) 2001-2004 Leon Woestenberg <leon.woestenberg@gmx.net>\r
+ * Copyright (c) 2001-2004 Axon Digital Design B.V., The Netherlands.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without modification,\r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED\r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT\r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY\r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is a contribution to the lwIP TCP/IP stack.\r
+ * The Swedish Institute of Computer Science and Adam Dunkels\r
+ * are specifically granted permission to redistribute this\r
+ * source code.\r
+ *\r
+ * Author: Leon Woestenberg <leon.woestenberg@gmx.net>\r
+ *\r
+ * This is a DHCP client for the lwIP TCP/IP stack. It aims to conform\r
+ * with RFC 2131 and RFC 2132.\r
+ *\r
+ * TODO:\r
+ * - Proper parsing of DHCP messages exploiting file/sname field overloading.\r
+ * - Add JavaDoc style documentation (API, internals).\r
+ * - Support for interfaces other than Ethernet (SLIP, PPP, ...)\r
+ *\r
+ * Please coordinate changes and requests with Leon Woestenberg\r
+ * <leon.woestenberg@gmx.net>\r
+ *\r
+ * Integration with your code:\r
+ *\r
+ * In lwip/dhcp.h\r
+ * #define DHCP_COARSE_TIMER_SECS (recommended 60 which is a minute)\r
+ * #define DHCP_FINE_TIMER_MSECS (recommended 500 which equals TCP coarse timer)\r
+ *\r
+ * Then have your application call dhcp_coarse_tmr() and\r
+ * dhcp_fine_tmr() on the defined intervals.\r
+ *\r
+ * dhcp_start(struct netif *netif);\r
+ * starts a DHCP client instance which configures the interface by\r
+ * obtaining an IP address lease and maintaining it.\r
+ *\r
+ * Use dhcp_release(netif) to end the lease and use dhcp_stop(netif)\r
+ * to remove the DHCP client.\r
+ *\r
+ */\r
\r
+#include <string.h>\r
\r
+#include "lwip/stats.h"\r
+#include "lwip/mem.h"\r
+#include "lwip/udp.h"\r
+#include "lwip/ip_addr.h"\r
+#include "lwip/netif.h"\r
+#include "lwip/inet.h"\r
+#include "netif/etharp.h"\r
+\r
+#include "lwip/sys.h"\r
+#include "lwip/opt.h"\r
+#include "lwip/dhcp.h"\r
+\r
+#if LWIP_DHCP /* don't build if not configured for use in lwipopt.h */\r
+\r
+/** global transaction identifier, must be\r
+ *  unique for each DHCP request. We simply increment, starting\r
+ *  with this value (easy to match with a packet analyzer) */\r
+static u32_t xid = 0xABCD0000;\r
+\r
+/** DHCP client state machine functions */\r
+static void dhcp_handle_ack(struct netif *netif);\r
+static void dhcp_handle_nak(struct netif *netif);\r
+static void dhcp_handle_offer(struct netif *netif);\r
+\r
+static err_t dhcp_discover(struct netif *netif);\r
+static err_t dhcp_select(struct netif *netif);\r
+static void dhcp_check(struct netif *netif);\r
+static void dhcp_bind(struct netif *netif);\r
+static err_t dhcp_decline(struct netif *netif);\r
+static err_t dhcp_rebind(struct netif *netif);\r
+static void dhcp_set_state(struct dhcp *dhcp, u8_t new_state);\r
+\r
+/** receive, unfold, parse and free incoming messages */\r
+static void dhcp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u16_t port);\r
+static err_t dhcp_unfold_reply(struct dhcp *dhcp);\r
+static u8_t *dhcp_get_option_ptr(struct dhcp *dhcp, u8_t option_type);\r
+static u8_t dhcp_get_option_byte(u8_t *ptr);\r
+static u16_t dhcp_get_option_short(u8_t *ptr);\r
+static u32_t dhcp_get_option_long(u8_t *ptr);\r
+static void dhcp_free_reply(struct dhcp *dhcp);\r
+\r
+/** set the DHCP timers */\r
+static void dhcp_timeout(struct netif *netif);\r
+static void dhcp_t1_timeout(struct netif *netif);\r
+static void dhcp_t2_timeout(struct netif *netif);\r
+\r
+/** build outgoing messages */\r
+/** create a DHCP request, fill in common headers */\r
+static err_t dhcp_create_request(struct netif *netif);\r
+/** free a DHCP request */\r
+static void dhcp_delete_request(struct netif *netif);\r
+/** add a DHCP option (type, then length in bytes) */\r
+static void dhcp_option(struct dhcp *dhcp, u8_t option_type, u8_t option_len);\r
+/** add option values */\r
+static void dhcp_option_byte(struct dhcp *dhcp, u8_t value);\r
+static void dhcp_option_short(struct dhcp *dhcp, u16_t value);\r
+static void dhcp_option_long(struct dhcp *dhcp, u32_t value);\r
+/** always add the DHCP options trailer to end and pad */\r
+static void dhcp_option_trailer(struct dhcp *dhcp);\r
+\r
+/**\r
+ * Back-off the DHCP client (because of a received NAK response).\r
+ *\r
+ * Back-off the DHCP client because of a received NAK. Receiving a\r
+ * NAK means the client asked for something non-sensible, for\r
+ * example when it tries to renew a lease obtained on another network.\r
+ *\r
+ * We back-off and will end up restarting a fresh DHCP negotiation later.\r
+ *\r
+ * @param state pointer to DHCP state structure\r
+ */\r
+static void dhcp_handle_nak(struct netif *netif) {\r
+  struct dhcp *dhcp = netif->dhcp;\r
+  u16_t msecs = 10 * 1000;\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_handle_nak(netif=%p) %c%c%"U16_F"\n", \r
+    (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num));\r
+  dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_handle_nak(): set request timeout %"U16_F" msecs\n", msecs));\r
+  dhcp_set_state(dhcp, DHCP_BACKING_OFF);\r
+}\r
+\r
+/**\r
+ * Checks if the offered IP address is already in use.\r
+ *\r
+ * It does so by sending an ARP request for the offered address and\r
+ * entering CHECKING state. If no ARP reply is received within a small\r
+ * interval, the address is assumed to be free for use by us.\r
+ */\r
+static void dhcp_check(struct netif *netif)\r
+{\r
+  struct dhcp *dhcp = netif->dhcp;\r
+  err_t result;\r
+  u16_t msecs;\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_check(netif=%p) %c%c\n", (void *)netif, (s16_t)netif->name[0],\r
+    (s16_t)netif->name[1]));\r
+  /* create an ARP query for the offered IP address, expecting that no host\r
+     responds, as the IP address should not be in use. */\r
+  result = etharp_query(netif, &dhcp->offered_ip_addr, NULL);\r
+  if (result != ERR_OK) {\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_check: could not perform ARP query\n"));\r
+  }\r
+  dhcp->tries++;\r
+  msecs = 500;\r
+  dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_check(): set request timeout %"U16_F" msecs\n", msecs));\r
+  dhcp_set_state(dhcp, DHCP_CHECKING);\r
+}\r
+\r
+/**\r
+ * Remember the configuration offered by a DHCP server.\r
+ *\r
+ * @param state pointer to DHCP state structure\r
+ */\r
+static void dhcp_handle_offer(struct netif *netif)\r
+{\r
+  struct dhcp *dhcp = netif->dhcp;\r
+  /* obtain the server address */\r
+  u8_t *option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_SERVER_ID);\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_handle_offer(netif=%p) %c%c%"U16_F"\n",\r
+    (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num));\r
+  if (option_ptr != NULL)\r
+  {\r
+    dhcp->server_ip_addr.addr = htonl(dhcp_get_option_long(&option_ptr[2]));\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_STATE, ("dhcp_handle_offer(): server 0x%08"X32_F"\n", dhcp->server_ip_addr.addr));\r
+    /* remember offered address */\r
+    ip_addr_set(&dhcp->offered_ip_addr, (struct ip_addr *)&dhcp->msg_in->yiaddr);\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_STATE, ("dhcp_handle_offer(): offer for 0x%08"X32_F"\n", dhcp->offered_ip_addr.addr));\r
+\r
+    dhcp_select(netif);\r
+  }\r
+}\r
+\r
+/**\r
+ * Select a DHCP server offer out of all offers.\r
+ *\r
+ * Simply select the first offer received.\r
+ *\r
+ * @param netif the netif under DHCP control\r
+ * @return lwIP specific error (see error.h)\r
+ */\r
+static err_t dhcp_select(struct netif *netif)\r
+{\r
+  struct dhcp *dhcp = netif->dhcp;\r
+  err_t result;\r
+  u32_t msecs;\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_select(netif=%p) %c%c%"U16_F"\n", (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num));\r
+\r
+  /* create and initialize the DHCP message header */\r
+  result = dhcp_create_request(netif);\r
+  if (result == ERR_OK)\r
+  {\r
+    dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN);\r
+    dhcp_option_byte(dhcp, DHCP_REQUEST);\r
+\r
+    dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);\r
+    dhcp_option_short(dhcp, 576);\r
+\r
+    /* MUST request the offered IP address */\r
+    dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4);\r
+    dhcp_option_long(dhcp, ntohl(dhcp->offered_ip_addr.addr));\r
+\r
+    dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4);\r
+    dhcp_option_long(dhcp, ntohl(dhcp->server_ip_addr.addr));\r
+\r
+    dhcp_option(dhcp, DHCP_OPTION_PARAMETER_REQUEST_LIST, 4/*num options*/);\r
+    dhcp_option_byte(dhcp, DHCP_OPTION_SUBNET_MASK);\r
+    dhcp_option_byte(dhcp, DHCP_OPTION_ROUTER);\r
+    dhcp_option_byte(dhcp, DHCP_OPTION_BROADCAST);\r
+    dhcp_option_byte(dhcp, DHCP_OPTION_DNS_SERVER);\r
+\r
+    dhcp_option_trailer(dhcp);\r
+    /* shrink the pbuf to the actual content length */\r
+    pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);\r
+\r
+    /* TODO: we really should bind to a specific local interface here\r
+       but we cannot specify an unconfigured netif as it is addressless */\r
+    udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);\r
+    /* send broadcast to any DHCP server */\r
+    udp_connect(dhcp->pcb, IP_ADDR_BROADCAST, DHCP_SERVER_PORT);\r
+    udp_send(dhcp->pcb, dhcp->p_out);\r
+    /* reconnect to any (or to server here?!) */\r
+    udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT);\r
+    dhcp_delete_request(netif);\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_select: REQUESTING\n"));\r
+    dhcp_set_state(dhcp, DHCP_REQUESTING);\r
+  } else {\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_select: could not allocate DHCP request\n"));\r
+  }\r
+  dhcp->tries++;\r
+  msecs = dhcp->tries < 4 ? dhcp->tries * 1000 : 4 * 1000;\r
+  dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_STATE, ("dhcp_select(): set request timeout %"U32_F" msecs\n", msecs));\r
+  return result;\r
+}\r
+\r
+/**\r
+ * The DHCP timer that checks for lease renewal/rebind timeouts.\r
+ *\r
+ */\r
+void dhcp_coarse_tmr()\r
+{\r
+  struct netif *netif = netif_list;\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_coarse_tmr()\n"));\r
+  /* iterate through all network interfaces */\r
+  while (netif != NULL) {\r
+    /* only act on DHCP configured interfaces */\r
+    if (netif->dhcp != NULL) {\r
+      /* timer is active (non zero), and triggers (zeroes) now? */\r
+      if (netif->dhcp->t2_timeout-- == 1) {\r
+        LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_coarse_tmr(): t2 timeout\n"));\r
+        /* this clients' rebind timeout triggered */\r
+        dhcp_t2_timeout(netif);\r
+      /* timer is active (non zero), and triggers (zeroes) now */\r
+      } else if (netif->dhcp->t1_timeout-- == 1) {\r
+        LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_coarse_tmr(): t1 timeout\n"));\r
+        /* this clients' renewal timeout triggered */\r
+        dhcp_t1_timeout(netif);\r
+      }\r
+    }\r
+    /* proceed to next netif */\r
+    netif = netif->next;\r
+  }\r
+}\r
+\r
+/**\r
+ * DHCP transaction timeout handling\r
+ *\r
+ * A DHCP server is expected to respond within a short period of time.\r
+ * This timer checks whether an outstanding DHCP request is timed out.\r
+ * \r
+ */\r
+void dhcp_fine_tmr()\r
+{\r
+  struct netif *netif = netif_list;\r
+  /* loop through netif's */\r
+  while (netif != NULL) {\r
+    /* only act on DHCP configured interfaces */\r
+    if (netif->dhcp != NULL) {\r
+      /* timer is active (non zero), and is about to trigger now */\r
+      if (netif->dhcp->request_timeout-- == 1) {\r
+        /* { netif->dhcp->request_timeout == 0 } */\r
+        LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_fine_tmr(): request timeout\n"));\r
+        /* this clients' request timeout triggered */\r
+        dhcp_timeout(netif);\r
+      }\r
+    }\r
+    /* proceed to next network interface */\r
+    netif = netif->next;\r
+  }\r
+}\r
+\r
+/**\r
+ * A DHCP negotiation transaction, or ARP request, has timed out.\r
+ *\r
+ * The timer that was started with the DHCP or ARP request has\r
+ * timed out, indicating no response was received in time.\r
+ *\r
+ * @param netif the netif under DHCP control\r
+ *\r
+ */\r
+static void dhcp_timeout(struct netif *netif)\r
+{\r
+  struct dhcp *dhcp = netif->dhcp;\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_timeout()\n"));\r
+  /* back-off period has passed, or server selection timed out */\r
+  if ((dhcp->state == DHCP_BACKING_OFF) || (dhcp->state == DHCP_SELECTING)) {\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_timeout(): restarting discovery\n"));\r
+    dhcp_discover(netif);\r
+  /* receiving the requested lease timed out */\r
+  } else if (dhcp->state == DHCP_REQUESTING) {\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_timeout(): REQUESTING, DHCP request timed out\n"));\r
+    if (dhcp->tries <= 5) {\r
+      dhcp_select(netif);\r
+    } else {\r
+      LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_timeout(): REQUESTING, releasing, restarting\n"));\r
+      dhcp_release(netif);\r
+      dhcp_discover(netif);\r
+    }\r
+  /* received no ARP reply for the offered address (which is good) */\r
+  } else if (dhcp->state == DHCP_CHECKING) {\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_timeout(): CHECKING, ARP request timed out\n"));\r
+    if (dhcp->tries <= 1) {\r
+      dhcp_check(netif);\r
+    /* no ARP replies on the offered address,\r
+       looks like the IP address is indeed free */\r
+    } else {\r
+      /* bind the interface to the offered address */\r
+      dhcp_bind(netif);\r
+    }\r
+  }\r
+  /* did not get response to renew request? */\r
+  else if (dhcp->state == DHCP_RENEWING) {\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_timeout(): RENEWING, DHCP request timed out\n"));\r
+    /* just retry renewal */\r
+    /* note that the rebind timer will eventually time-out if renew does not work */\r
+    dhcp_renew(netif);\r
+  /* did not get response to rebind request? */\r
+  } else if (dhcp->state == DHCP_REBINDING) {\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_timeout(): REBINDING, DHCP request timed out\n"));\r
+    if (dhcp->tries <= 8) {\r
+      dhcp_rebind(netif);\r
+    } else {\r
+      LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_timeout(): RELEASING, DISCOVERING\n"));\r
+      dhcp_release(netif);\r
+      dhcp_discover(netif);\r
+    }\r
+  }\r
+}\r
+\r
+/**\r
+ * The renewal period has timed out.\r
+ *\r
+ * @param netif the netif under DHCP control\r
+ */\r
+static void dhcp_t1_timeout(struct netif *netif)\r
+{\r
+  struct dhcp *dhcp = netif->dhcp;\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_STATE, ("dhcp_t1_timeout()\n"));\r
+  if ((dhcp->state == DHCP_REQUESTING) || (dhcp->state == DHCP_BOUND) || (dhcp->state == DHCP_RENEWING)) {\r
+    /* just retry to renew - note that the rebind timer (t2) will\r
+     * eventually time-out if renew tries fail. */\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_t1_timeout(): must renew\n"));\r
+    dhcp_renew(netif);\r
+  }\r
+}\r
+\r
+/**\r
+ * The rebind period has timed out.\r
+ *\r
+ */\r
+static void dhcp_t2_timeout(struct netif *netif)\r
+{\r
+  struct dhcp *dhcp = netif->dhcp;\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_t2_timeout()\n"));\r
+  if ((dhcp->state == DHCP_REQUESTING) || (dhcp->state == DHCP_BOUND) || (dhcp->state == DHCP_RENEWING)) {\r
+    /* just retry to rebind */\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_t2_timeout(): must rebind\n"));\r
+    dhcp_rebind(netif);\r
+  }\r
+}\r
+\r
+/**\r
+ *\r
+ * @param netif the netif under DHCP control\r
+ */\r
+static void dhcp_handle_ack(struct netif *netif)\r
+{\r
+  struct dhcp *dhcp = netif->dhcp;\r
+  u8_t *option_ptr;\r
+  /* clear options we might not get from the ACK */\r
+  dhcp->offered_sn_mask.addr = 0;\r
+  dhcp->offered_gw_addr.addr = 0;\r
+  dhcp->offered_bc_addr.addr = 0;\r
+\r
+  /* lease time given? */\r
+  option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_LEASE_TIME);\r
+  if (option_ptr != NULL) {\r
+    /* remember offered lease time */\r
+    dhcp->offered_t0_lease = dhcp_get_option_long(option_ptr + 2);\r
+  }\r
+  /* renewal period given? */\r
+  option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_T1);\r
+  if (option_ptr != NULL) {\r
+    /* remember given renewal period */\r
+    dhcp->offered_t1_renew = dhcp_get_option_long(option_ptr + 2);\r
+  } else {\r
+    /* calculate safe periods for renewal */\r
+    dhcp->offered_t1_renew = dhcp->offered_t0_lease / 2;\r
+  }\r
+\r
+  /* renewal period given? */\r
+  option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_T2);\r
+  if (option_ptr != NULL) {\r
+    /* remember given rebind period */\r
+    dhcp->offered_t2_rebind = dhcp_get_option_long(option_ptr + 2);\r
+  } else {\r
+    /* calculate safe periods for rebinding */\r
+    dhcp->offered_t2_rebind = dhcp->offered_t0_lease;\r
+  }\r
+\r
+  /* (y)our internet address */\r
+  ip_addr_set(&dhcp->offered_ip_addr, &dhcp->msg_in->yiaddr);\r
+\r
+/**\r
+ * Patch #1308\r
+ * TODO: we must check if the file field is not overloaded by DHCP options!\r
+ */\r
+#if 0\r
+  /* boot server address */\r
+  ip_addr_set(&dhcp->offered_si_addr, &dhcp->msg_in->siaddr);\r
+  /* boot file name */\r
+  if (dhcp->msg_in->file[0]) {\r
+    dhcp->boot_file_name = mem_malloc(strlen(dhcp->msg_in->file) + 1);\r
+    strcpy(dhcp->boot_file_name, dhcp->msg_in->file);\r
+  }\r
+#endif\r
+\r
+  /* subnet mask */\r
+  option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_SUBNET_MASK);\r
+  /* subnet mask given? */\r
+  if (option_ptr != NULL) {\r
+    dhcp->offered_sn_mask.addr = htonl(dhcp_get_option_long(&option_ptr[2]));\r
+  }\r
+\r
+  /* gateway router */\r
+  option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_ROUTER);\r
+  if (option_ptr != NULL) {\r
+    dhcp->offered_gw_addr.addr = htonl(dhcp_get_option_long(&option_ptr[2]));\r
+  }\r
+\r
+  /* broadcast address */\r
+  option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_BROADCAST);\r
+  if (option_ptr != NULL) {\r
+    dhcp->offered_bc_addr.addr = htonl(dhcp_get_option_long(&option_ptr[2]));\r
+  }\r
+  \r
+  /* DNS servers */\r
+  option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_DNS_SERVER);\r
+  if (option_ptr != NULL) {\r
+    u8_t n;\r
+    dhcp->dns_count = dhcp_get_option_byte(&option_ptr[1]);\r
+    /* limit to at most DHCP_MAX_DNS DNS servers */\r
+    if (dhcp->dns_count > DHCP_MAX_DNS) dhcp->dns_count = DHCP_MAX_DNS;\r
+    for (n = 0; n < dhcp->dns_count; n++)\r
+    {\r
+      dhcp->offered_dns_addr[n].addr = htonl(dhcp_get_option_long(&option_ptr[2+(n<<2)]));\r
+    }\r
+  }\r
+}\r
+\r
+/**\r
+ * Start DHCP negotiation for a network interface.\r
+ *\r
+ * If no DHCP client instance was attached to this interface,\r
+ * a new client is created first. If a DHCP client instance\r
+ * was already present, it restarts negotiation.\r
+ *\r
+ * @param netif The lwIP network interface\r
+ * @return lwIP error code\r
+ * - ERR_OK - No error\r
+ * - ERR_MEM - Out of memory\r
+ *\r
+ */\r
+err_t dhcp_start(struct netif *netif)\r
+{\r
+  struct dhcp *dhcp = netif->dhcp;\r
+  err_t result = ERR_OK;\r
+\r
+  LWIP_ASSERT("netif != NULL", netif != NULL);\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_start(netif=%p) %c%c%"U16_F"\n", (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num));\r
+  netif->flags &= ~NETIF_FLAG_DHCP;\r
+\r
+  /* no DHCP client attached yet? */\r
+  if (dhcp == NULL) {\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_start(): starting new DHCP client\n"));\r
+    dhcp = mem_malloc(sizeof(struct dhcp));\r
+    if (dhcp == NULL) {\r
+      LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_start(): could not allocate dhcp\n"));\r
+      return ERR_MEM;\r
+    }\r
+    /* store this dhcp client in the netif */\r
+    netif->dhcp = dhcp;\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_start(): allocated dhcp"));\r
+  /* already has DHCP client attached */\r
+  } else {\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE | 3, ("dhcp_start(): restarting DHCP configuration\n"));\r
+  }\r
+       \r
+       /* clear data structure */\r
+       memset(dhcp, 0, sizeof(struct dhcp));\r
+  /* allocate UDP PCB */\r
+       dhcp->pcb = udp_new();\r
+       if (dhcp->pcb == NULL) {\r
+         LWIP_DEBUGF(DHCP_DEBUG  | DBG_TRACE, ("dhcp_start(): could not obtain pcb\n"));\r
+         mem_free((void *)dhcp);\r
+         netif->dhcp = dhcp = NULL;\r
+         return ERR_MEM;\r
+       }\r
+       LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_start(): starting DHCP configuration\n"));\r
+  /* (re)start the DHCP negotiation */\r
+  result = dhcp_discover(netif);\r
+  if (result != ERR_OK) {\r
+    /* free resources allocated above */\r
+    dhcp_stop(netif);\r
+    return ERR_MEM;\r
+  }\r
+  netif->flags |= NETIF_FLAG_DHCP;\r
+  return result;\r
+}\r
+\r
+/**\r
+ * Inform a DHCP server of our manual configuration.\r
+ *\r
+ * This informs DHCP servers of our fixed IP address configuration\r
+ * by sending an INFORM message. It does not involve DHCP address\r
+ * configuration, it is just here to be nice to the network.\r
+ *\r
+ * @param netif The lwIP network interface\r
+ *\r
+ */\r
+void dhcp_inform(struct netif *netif)\r
+{\r
+  struct dhcp *dhcp;\r
+  err_t result = ERR_OK;\r
+  dhcp = mem_malloc(sizeof(struct dhcp));\r
+  if (dhcp == NULL) {\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_inform(): could not allocate dhcp\n"));\r
+    return;\r
+  }\r
+  netif->dhcp = dhcp;\r
+  memset(dhcp, 0, sizeof(struct dhcp));\r
+\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_inform(): allocated dhcp\n"));\r
+  dhcp->pcb = udp_new();\r
+  if (dhcp->pcb == NULL) {\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_inform(): could not obtain pcb"));\r
+    mem_free((void *)dhcp);\r
+    return;\r
+  }\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_inform(): created new udp pcb\n"));\r
+  /* create and initialize the DHCP message header */\r
+  result = dhcp_create_request(netif);\r
+  if (result == ERR_OK) {\r
+\r
+    dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN);\r
+    dhcp_option_byte(dhcp, DHCP_INFORM);\r
+\r
+    dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);\r
+    /* TODO: use netif->mtu ?! */\r
+    dhcp_option_short(dhcp, 576);\r
+\r
+    dhcp_option_trailer(dhcp);\r
+\r
+    pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);\r
+\r
+    udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);\r
+    udp_connect(dhcp->pcb, IP_ADDR_BROADCAST, DHCP_SERVER_PORT);\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_inform: INFORMING\n"));\r
+    udp_send(dhcp->pcb, dhcp->p_out);\r
+    udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT);\r
+    dhcp_delete_request(netif);\r
+  } else {\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_inform: could not allocate DHCP request\n"));\r
+  }\r
+\r
+  if (dhcp != NULL)\r
+  {\r
+    if (dhcp->pcb != NULL) udp_remove(dhcp->pcb);\r
+    dhcp->pcb = NULL;\r
+    mem_free((void *)dhcp);\r
+    netif->dhcp = NULL;\r
+  }\r
+}\r
+\r
+#if DHCP_DOES_ARP_CHECK\r
+/**\r
+ * Match an ARP reply with the offered IP address.\r
+ *\r
+ * @param addr The IP address we received a reply from\r
+ *\r
+ */\r
+void dhcp_arp_reply(struct netif *netif, struct ip_addr *addr)\r
+{\r
+  LWIP_ASSERT("netif != NULL", netif != NULL);\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_arp_reply()\n"));\r
+  /* is a DHCP client doing an ARP check? */\r
+  if ((netif->dhcp != NULL) && (netif->dhcp->state == DHCP_CHECKING)) {\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_arp_reply(): CHECKING, arp reply for 0x%08"X32_F"\n", addr->addr));\r
+    /* did a host respond with the address we\r
+       were offered by the DHCP server? */\r
+    if (ip_addr_cmp(addr, &netif->dhcp->offered_ip_addr)) {\r
+      /* we will not accept the offered address */\r
+      LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE | 1, ("dhcp_arp_reply(): arp reply matched with offered address, declining\n"));\r
+      dhcp_decline(netif);\r
+    }\r
+  }\r
+}\r
+\r
+/**\r
+ * Decline an offered lease.\r
+ *\r
+ * Tell the DHCP server we do not accept the offered address.\r
+ * One reason to decline the lease is when we find out the address\r
+ * is already in use by another host (through ARP).\r
+ */\r
+static err_t dhcp_decline(struct netif *netif)\r
+{\r
+  struct dhcp *dhcp = netif->dhcp;\r
+  err_t result = ERR_OK;\r
+  u16_t msecs;\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_decline()\n"));\r
+  dhcp_set_state(dhcp, DHCP_BACKING_OFF);\r
+  /* create and initialize the DHCP message header */\r
+  result = dhcp_create_request(netif);\r
+  if (result == ERR_OK)\r
+  {\r
+    dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN);\r
+    dhcp_option_byte(dhcp, DHCP_DECLINE);\r
+\r
+    dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);\r
+    dhcp_option_short(dhcp, 576);\r
+\r
+    dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4);\r
+    dhcp_option_long(dhcp, ntohl(dhcp->offered_ip_addr.addr));\r
+\r
+    dhcp_option_trailer(dhcp);\r
+    /* resize pbuf to reflect true size of options */\r
+    pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);\r
+\r
+    udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);\r
+    /* @todo: should we really connect here? we are performing sendto() */\r
+    udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT);\r
+    /* per section 4.4.4, broadcast DECLINE messages */\r
+    udp_sendto(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT);\r
+    dhcp_delete_request(netif);\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_decline: BACKING OFF\n"));\r
+  } else {\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_decline: could not allocate DHCP request\n"));\r
+  }\r
+  dhcp->tries++;\r
+  msecs = 10*1000;\r
+  dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;\r
+   LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_decline(): set request timeout %"U16_F" msecs\n", msecs));\r
+  return result;\r
+}\r
+#endif\r
+\r
+\r
+/**\r
+ * Start the DHCP process, discover a DHCP server.\r
+ *\r
+ */\r
+static err_t dhcp_discover(struct netif *netif)\r
+{\r
+  struct dhcp *dhcp = netif->dhcp;\r
+  err_t result = ERR_OK;\r
+  u16_t msecs;\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_discover()\n"));\r
+  ip_addr_set(&dhcp->offered_ip_addr, IP_ADDR_ANY);\r
+  /* create and initialize the DHCP message header */\r
+  result = dhcp_create_request(netif);\r
+  if (result == ERR_OK)\r
+  {\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_discover: making request\n"));\r
+    dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN);\r
+    dhcp_option_byte(dhcp, DHCP_DISCOVER);\r
+\r
+    dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);\r
+    dhcp_option_short(dhcp, 576);\r
+\r
+    dhcp_option(dhcp, DHCP_OPTION_PARAMETER_REQUEST_LIST, 4/*num options*/);\r
+    dhcp_option_byte(dhcp, DHCP_OPTION_SUBNET_MASK);\r
+    dhcp_option_byte(dhcp, DHCP_OPTION_ROUTER);\r
+    dhcp_option_byte(dhcp, DHCP_OPTION_BROADCAST);\r
+    dhcp_option_byte(dhcp, DHCP_OPTION_DNS_SERVER);\r
+\r
+    dhcp_option_trailer(dhcp);\r
+\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_discover: realloc()ing\n"));\r
+    pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);\r
+\r
+    /* set receive callback function with netif as user data */\r
+    udp_recv(dhcp->pcb, dhcp_recv, netif);\r
+    udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);\r
+    udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT);\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_discover: sendto(DISCOVER, IP_ADDR_BROADCAST, DHCP_SERVER_PORT)\n"));\r
+    udp_sendto(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT);\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_discover: deleting()ing\n"));\r
+    dhcp_delete_request(netif);\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_discover: SELECTING\n"));\r
+    dhcp_set_state(dhcp, DHCP_SELECTING);\r
+  } else {\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_discover: could not allocate DHCP request\n"));\r
+  }\r
+  dhcp->tries++;\r
+  msecs = dhcp->tries < 4 ? (dhcp->tries + 1) * 1000 : 10 * 1000;\r
+  dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_discover(): set request timeout %"U16_F" msecs\n", msecs));\r
+  return result;\r
+}\r
+\r
+\r
+/**\r
+ * Bind the interface to the offered IP address.\r
+ *\r
+ * @param netif network interface to bind to the offered address\r
+ */\r
+static void dhcp_bind(struct netif *netif)\r
+{\r
+  struct dhcp *dhcp = netif->dhcp;\r
+  struct ip_addr sn_mask, gw_addr;\r
+  LWIP_ASSERT("dhcp_bind: netif != NULL", netif != NULL);\r
+  LWIP_ASSERT("dhcp_bind: dhcp != NULL", dhcp != NULL);\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_bind(netif=%p) %c%c%"U16_F"\n", (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num));\r
+\r
+  /* temporary DHCP lease? */\r
+  if (dhcp->offered_t1_renew != 0xffffffffUL) {\r
+    /* set renewal period timer */\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_bind(): t1 renewal timer %"U32_F" secs\n", dhcp->offered_t1_renew));\r
+    dhcp->t1_timeout = (dhcp->offered_t1_renew + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS;\r
+    if (dhcp->t1_timeout == 0) dhcp->t1_timeout = 1;\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_bind(): set request timeout %"U32_F" msecs\n", dhcp->offered_t1_renew*1000));\r
+  }\r
+  /* set renewal period timer */\r
+  if (dhcp->offered_t2_rebind != 0xffffffffUL) {\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_bind(): t2 rebind timer %"U32_F" secs\n", dhcp->offered_t2_rebind));\r
+    dhcp->t2_timeout = (dhcp->offered_t2_rebind + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS;\r
+    if (dhcp->t2_timeout == 0) dhcp->t2_timeout = 1;\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_bind(): set request timeout %"U32_F" msecs\n", dhcp->offered_t2_rebind*1000));\r
+  }\r
+  /* copy offered network mask */\r
+  ip_addr_set(&sn_mask, &dhcp->offered_sn_mask);\r
+\r
+  /* subnet mask not given? */\r
+  /* TODO: this is not a valid check. what if the network mask is 0? */\r
+  if (sn_mask.addr == 0) {\r
+    /* choose a safe subnet mask given the network class */\r
+    u8_t first_octet = ip4_addr1(&sn_mask);\r
+    if (first_octet <= 127) sn_mask.addr = htonl(0xff000000);\r
+    else if (first_octet >= 192) sn_mask.addr = htonl(0xffffff00);\r
+    else sn_mask.addr = htonl(0xffff0000);\r
+  }\r
+\r
+  ip_addr_set(&gw_addr, &dhcp->offered_gw_addr);\r
+  /* gateway address not given? */\r
+  if (gw_addr.addr == 0) {\r
+    /* copy network address */\r
+    gw_addr.addr = (dhcp->offered_ip_addr.addr & sn_mask.addr);\r
+    /* use first host address on network as gateway */\r
+    gw_addr.addr |= htonl(0x00000001);\r
+  }\r
+\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_STATE, ("dhcp_bind(): IP: 0x%08"X32_F"\n", dhcp->offered_ip_addr.addr));\r
+  netif_set_ipaddr(netif, &dhcp->offered_ip_addr);\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_STATE, ("dhcp_bind(): SN: 0x%08"X32_F"\n", sn_mask.addr));\r
+  netif_set_netmask(netif, &sn_mask);\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_STATE, ("dhcp_bind(): GW: 0x%08"X32_F"\n", gw_addr.addr));\r
+  netif_set_gw(netif, &gw_addr);\r
+  /* bring the interface up */\r
+  netif_set_up(netif);\r
+  /* netif is now bound to DHCP leased address */\r
+  dhcp_set_state(dhcp, DHCP_BOUND);\r
+}\r
+\r
+/**\r
+ * Renew an existing DHCP lease at the involved DHCP server.\r
+ *\r
+ * @param netif network interface which must renew its lease\r
+ */\r
+err_t dhcp_renew(struct netif *netif)\r
+{\r
+  struct dhcp *dhcp = netif->dhcp;\r
+  err_t result;\r
+  u16_t msecs;\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_renew()\n"));\r
+  dhcp_set_state(dhcp, DHCP_RENEWING);\r
+\r
+  /* create and initialize the DHCP message header */\r
+  result = dhcp_create_request(netif);\r
+  if (result == ERR_OK) {\r
+\r
+    dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN);\r
+    dhcp_option_byte(dhcp, DHCP_REQUEST);\r
+\r
+    dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);\r
+    /* TODO: use netif->mtu in some way */\r
+    dhcp_option_short(dhcp, 576);\r
+\r
+#if 0\r
+    dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4);\r
+    dhcp_option_long(dhcp, ntohl(dhcp->offered_ip_addr.addr));\r
+#endif\r
+\r
+#if 0\r
+    dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4);\r
+    dhcp_option_long(dhcp, ntohl(dhcp->server_ip_addr.addr));\r
+#endif\r
+    /* append DHCP message trailer */\r
+    dhcp_option_trailer(dhcp);\r
+\r
+    pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);\r
+\r
+    udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);\r
+    udp_connect(dhcp->pcb, &dhcp->server_ip_addr, DHCP_SERVER_PORT);\r
+    udp_send(dhcp->pcb, dhcp->p_out);\r
+    dhcp_delete_request(netif);\r
+\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_renew: RENEWING\n"));\r
+  } else {\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_renew: could not allocate DHCP request\n"));\r
+  }\r
+  dhcp->tries++;\r
+  /* back-off on retries, but to a maximum of 20 seconds */\r
+  msecs = dhcp->tries < 10 ? dhcp->tries * 2000 : 20 * 1000;\r
+  dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;\r
+   LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_renew(): set request timeout %"U16_F" msecs\n", msecs));\r
+  return result;\r
+}\r
+\r
+/**\r
+ * Rebind with a DHCP server for an existing DHCP lease.\r
+ *\r
+ * @param netif network interface which must rebind with a DHCP server\r
+ */\r
+static err_t dhcp_rebind(struct netif *netif)\r
+{\r
+  struct dhcp *dhcp = netif->dhcp;\r
+  err_t result;\r
+  u16_t msecs;\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_rebind()\n"));\r
+  dhcp_set_state(dhcp, DHCP_REBINDING);\r
+\r
+  /* create and initialize the DHCP message header */\r
+  result = dhcp_create_request(netif);\r
+  if (result == ERR_OK)\r
+  {\r
+\r
+    dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN);\r
+    dhcp_option_byte(dhcp, DHCP_REQUEST);\r
+\r
+    dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);\r
+    dhcp_option_short(dhcp, 576);\r
+\r
+#if 0\r
+    dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4);\r
+    dhcp_option_long(dhcp, ntohl(dhcp->offered_ip_addr.addr));\r
+\r
+    dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4);\r
+    dhcp_option_long(dhcp, ntohl(dhcp->server_ip_addr.addr));\r
+#endif\r
+\r
+    dhcp_option_trailer(dhcp);\r
+\r
+    pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);\r
+\r
+    /* set remote IP association to any DHCP server */\r
+    udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);\r
+    udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT);\r
+    /* broadcast to server */\r
+    udp_sendto(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT);\r
+    dhcp_delete_request(netif);\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_rebind: REBINDING\n"));\r
+  } else {\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_rebind: could not allocate DHCP request\n"));\r
+  }\r
+  dhcp->tries++;\r
+  msecs = dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000;\r
+  dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;\r
+   LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_rebind(): set request timeout %"U16_F" msecs\n", msecs));\r
+  return result;\r
+}\r
+\r
+/**\r
+ * Release a DHCP lease.\r
+ *\r
+ * @param netif network interface which must release its lease\r
+ */\r
+err_t dhcp_release(struct netif *netif)\r
+{\r
+  struct dhcp *dhcp = netif->dhcp;\r
+  err_t result;\r
+  u16_t msecs;\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_release()\n"));\r
+\r
+  /* idle DHCP client */\r
+  dhcp_set_state(dhcp, DHCP_OFF);\r
+  /* clean old DHCP offer */\r
+  dhcp->server_ip_addr.addr = 0;\r
+  dhcp->offered_ip_addr.addr = dhcp->offered_sn_mask.addr = 0;\r
+  dhcp->offered_gw_addr.addr = dhcp->offered_bc_addr.addr = 0;\r
+  dhcp->offered_t0_lease = dhcp->offered_t1_renew = dhcp->offered_t2_rebind = 0;\r
+  dhcp->dns_count = 0;\r
+  \r
+  /* create and initialize the DHCP message header */\r
+  result = dhcp_create_request(netif);\r
+  if (result == ERR_OK) {\r
+    dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN);\r
+    dhcp_option_byte(dhcp, DHCP_RELEASE);\r
+\r
+    dhcp_option_trailer(dhcp);\r
+\r
+    pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);\r
+\r
+    udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);\r
+    udp_connect(dhcp->pcb, &dhcp->server_ip_addr, DHCP_SERVER_PORT);\r
+    udp_send(dhcp->pcb, dhcp->p_out);\r
+    dhcp_delete_request(netif);\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_release: RELEASED, DHCP_OFF\n"));\r
+  } else {\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_release: could not allocate DHCP request\n"));\r
+  }\r
+  dhcp->tries++;\r
+  msecs = dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000;\r
+  dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_release(): set request timeout %"U16_F" msecs\n", msecs));\r
+  /* bring the interface down */\r
+  netif_set_down(netif);\r
+  /* remove IP address from interface */\r
+  netif_set_ipaddr(netif, IP_ADDR_ANY);\r
+  netif_set_gw(netif, IP_ADDR_ANY);\r
+  netif_set_netmask(netif, IP_ADDR_ANY);\r
+  \r
+  /* TODO: netif_down(netif); */\r
+  return result;\r
+}\r
+/**\r
+ * Remove the DHCP client from the interface.\r
+ *\r
+ * @param netif The network interface to stop DHCP on\r
+ */\r
+void dhcp_stop(struct netif *netif)\r
+{\r
+  struct dhcp *dhcp = netif->dhcp;\r
+  LWIP_ASSERT("dhcp_stop: netif != NULL", netif != NULL);\r
+\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_stop()\n"));\r
+  /* netif is DHCP configured? */\r
+  if (dhcp != NULL)\r
+  {\r
+    if (dhcp->pcb != NULL)\r
+    {\r
+      udp_remove(dhcp->pcb);\r
+      dhcp->pcb = NULL;\r
+    }\r
+    if (dhcp->p != NULL)\r
+    {\r
+      pbuf_free(dhcp->p);\r
+      dhcp->p = NULL;\r
+    }\r
+    /* free unfolded reply */\r
+    dhcp_free_reply(dhcp);\r
+    mem_free((void *)dhcp);\r
+    netif->dhcp = NULL;\r
+  }\r
+}\r
+\r
+/*\r
+ * Set the DHCP state of a DHCP client.\r
+ *\r
+ * If the state changed, reset the number of tries.\r
+ *\r
+ * TODO: we might also want to reset the timeout here?\r
+ */\r
+static void dhcp_set_state(struct dhcp *dhcp, u8_t new_state)\r
+{\r
+  if (new_state != dhcp->state)\r
+  {\r
+    dhcp->state = new_state;\r
+    dhcp->tries = 0;\r
+  }\r
+}\r
+\r
+/*\r
+ * Concatenate an option type and length field to the outgoing\r
+ * DHCP message.\r
+ *\r
+ */\r
+static void dhcp_option(struct dhcp *dhcp, u8_t option_type, u8_t option_len)\r
+{\r
+  LWIP_ASSERT("dhcp_option_short: dhcp->options_out_len + 2 + option_len <= DHCP_OPTIONS_LEN", dhcp->options_out_len + 2 + option_len <= DHCP_OPTIONS_LEN);\r
+  dhcp->msg_out->options[dhcp->options_out_len++] = option_type;\r
+  dhcp->msg_out->options[dhcp->options_out_len++] = option_len;\r
+}\r
+/*\r
+ * Concatenate a single byte to the outgoing DHCP message.\r
+ *\r
+ */\r
+static void dhcp_option_byte(struct dhcp *dhcp, u8_t value)\r
+{\r
+  LWIP_ASSERT("dhcp_option_short: dhcp->options_out_len < DHCP_OPTIONS_LEN", dhcp->options_out_len < DHCP_OPTIONS_LEN);\r
+  dhcp->msg_out->options[dhcp->options_out_len++] = value;\r
+}\r
+static void dhcp_option_short(struct dhcp *dhcp, u16_t value)\r
+{\r
+  LWIP_ASSERT("dhcp_option_short: dhcp->options_out_len + 2 <= DHCP_OPTIONS_LEN", dhcp->options_out_len + 2 <= DHCP_OPTIONS_LEN);\r
+  dhcp->msg_out->options[dhcp->options_out_len++] = (value & 0xff00U) >> 8;\r
+  dhcp->msg_out->options[dhcp->options_out_len++] =  value & 0x00ffU;\r
+}\r
+static void dhcp_option_long(struct dhcp *dhcp, u32_t value)\r
+{\r
+  LWIP_ASSERT("dhcp_option_long: dhcp->options_out_len + 4 <= DHCP_OPTIONS_LEN", dhcp->options_out_len + 4 <= DHCP_OPTIONS_LEN);\r
+  dhcp->msg_out->options[dhcp->options_out_len++] = (value & 0xff000000UL) >> 24;\r
+  dhcp->msg_out->options[dhcp->options_out_len++] = (value & 0x00ff0000UL) >> 16;\r
+  dhcp->msg_out->options[dhcp->options_out_len++] = (value & 0x0000ff00UL) >> 8;\r
+  dhcp->msg_out->options[dhcp->options_out_len++] = (value & 0x000000ffUL);\r
+}\r
+\r
+/**\r
+ * Extract the DHCP message and the DHCP options.\r
+ *\r
+ * Extract the DHCP message and the DHCP options, each into a contiguous\r
+ * piece of memory. As a DHCP message is variable sized by its options,\r
+ * and also allows overriding some fields for options, the easy approach\r
+ * is to first unfold the options into a conitguous piece of memory, and\r
+ * use that further on.\r
+ *\r
+ */\r
+static err_t dhcp_unfold_reply(struct dhcp *dhcp)\r
+{\r
+  struct pbuf *p = dhcp->p;\r
+  u8_t *ptr;\r
+  u16_t i;\r
+  u16_t j = 0;\r
+  LWIP_ASSERT("dhcp->p != NULL", dhcp->p != NULL);\r
+  /* free any left-overs from previous unfolds */\r
+  dhcp_free_reply(dhcp);\r
+  /* options present? */\r
+  if (dhcp->p->tot_len > (sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN))\r
+  {\r
+    dhcp->options_in_len = dhcp->p->tot_len - (sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN);\r
+    dhcp->options_in = mem_malloc(dhcp->options_in_len);\r
+    if (dhcp->options_in == NULL)\r
+    {\r
+      LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_unfold_reply(): could not allocate dhcp->options\n"));\r
+      return ERR_MEM;\r
+    }\r
+  }\r
+  dhcp->msg_in = mem_malloc(sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN);\r
+  if (dhcp->msg_in == NULL)\r
+  {\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_unfold_reply(): could not allocate dhcp->msg_in\n"));\r
+    mem_free((void *)dhcp->options_in);\r
+    dhcp->options_in = NULL;\r
+    return ERR_MEM;\r
+  }\r
+\r
+  ptr = (u8_t *)dhcp->msg_in;\r
+  /* proceed through struct dhcp_msg */\r
+  for (i = 0; i < sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN; i++)\r
+  {\r
+    *ptr++ = ((u8_t *)p->payload)[j++];\r
+    /* reached end of pbuf? */\r
+    if (j == p->len)\r
+    {\r
+      /* proceed to next pbuf in chain */\r
+      p = p->next;\r
+      j = 0;\r
+    }\r
+  }\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_unfold_reply(): copied %"U16_F" bytes into dhcp->msg_in[]\n", i));\r
+  if (dhcp->options_in != NULL) {\r
+    ptr = (u8_t *)dhcp->options_in;\r
+    /* proceed through options */\r
+    for (i = 0; i < dhcp->options_in_len; i++) {\r
+      *ptr++ = ((u8_t *)p->payload)[j++];\r
+      /* reached end of pbuf? */\r
+      if (j == p->len) {\r
+        /* proceed to next pbuf in chain */\r
+        p = p->next;\r
+        j = 0;\r
+      }\r
+    }\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_unfold_reply(): copied %"U16_F" bytes to dhcp->options_in[]\n", i));\r
+  }\r
+  return ERR_OK;\r
+}\r
+\r
+/**\r
+ * Free the incoming DHCP message including contiguous copy of\r
+ * its DHCP options.\r
+ *\r
+ */\r
+static void dhcp_free_reply(struct dhcp *dhcp)\r
+{\r
+  if (dhcp->msg_in != NULL) {\r
+    mem_free((void *)dhcp->msg_in);\r
+    dhcp->msg_in = NULL;\r
+  }\r
+  if (dhcp->options_in) {\r
+    mem_free((void *)dhcp->options_in);\r
+    dhcp->options_in = NULL;\r
+    dhcp->options_in_len = 0;\r
+  }\r
+  LWIP_DEBUGF(DHCP_DEBUG, ("dhcp_free_reply(): free'd\n"));\r
+}\r
+\r
+\r
+/**\r
+ * If an incoming DHCP message is in response to us, then trigger the state machine\r
+ */\r
+static void dhcp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u16_t port)\r
+{\r
+  struct netif *netif = (struct netif *)arg;\r
+  struct dhcp *dhcp = netif->dhcp;\r
+  struct dhcp_msg *reply_msg = (struct dhcp_msg *)p->payload;\r
+  u8_t *options_ptr;\r
+  u8_t msg_type;\r
+  u8_t i;\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_recv(pbuf = %p) from DHCP server %"U16_F".%"U16_F".%"U16_F".%"U16_F" port %"U16_F"\n", (void*)p,\r
+    (u16_t)(ntohl(addr->addr) >> 24 & 0xff), (u16_t)(ntohl(addr->addr) >> 16 & 0xff),\r
+    (u16_t)(ntohl(addr->addr) >>  8 & 0xff), (u16_t)(ntohl(addr->addr) & 0xff), port));\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("pbuf->len = %"U16_F"\n", p->len));\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("pbuf->tot_len = %"U16_F"\n", p->tot_len));\r
+  /* prevent warnings about unused arguments */\r
+  (void)pcb; (void)addr; (void)port;\r
+  dhcp->p = p;\r
+  /* TODO: check packet length before reading them */\r
+  if (reply_msg->op != DHCP_BOOTREPLY) {\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 1, ("not a DHCP reply message, but type %"U16_F"\n", (u16_t)reply_msg->op));\r
+    pbuf_free(p);\r
+    dhcp->p = NULL;\r
+    return;\r
+  }\r
+  /* iterate through hardware address and match against DHCP message */\r
+  for (i = 0; i < netif->hwaddr_len; i++) {\r
+    if (netif->hwaddr[i] != reply_msg->chaddr[i]) {\r
+      LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("netif->hwaddr[%"U16_F"]==%02"X16_F" != reply_msg->chaddr[%"U16_F"]==%02"X16_F"\n",\r
+        (u16_t)i, (u16_t)netif->hwaddr[i], (u16_t)i, (u16_t)reply_msg->chaddr[i]));\r
+      pbuf_free(p);\r
+      dhcp->p = NULL;\r
+      return;\r
+    }\r
+  }\r
+  /* match transaction ID against what we expected */\r
+  if (ntohl(reply_msg->xid) != dhcp->xid) {\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("transaction id mismatch\n"));\r
+    pbuf_free(p);\r
+    dhcp->p = NULL;\r
+    return;\r
+  }\r
+  /* option fields could be unfold? */\r
+  if (dhcp_unfold_reply(dhcp) != ERR_OK) {\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("problem unfolding DHCP message - too short on memory?\n"));\r
+    pbuf_free(p);\r
+    dhcp->p = NULL;\r
+    return;\r
+  }\r
+\r
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("searching DHCP_OPTION_MESSAGE_TYPE\n"));\r
+  /* obtain pointer to DHCP message type */\r
+  options_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_MESSAGE_TYPE);\r
+  if (options_ptr == NULL) {\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 1, ("DHCP_OPTION_MESSAGE_TYPE option not found\n"));\r
+    pbuf_free(p);\r
+    dhcp->p = NULL;\r
+    return;\r
+  }\r
+\r
+  /* read DHCP message type */\r
+  msg_type = dhcp_get_option_byte(options_ptr + 2);\r
+  /* message type is DHCP ACK? */\r
+  if (msg_type == DHCP_ACK) {\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 1, ("DHCP_ACK received\n"));\r
+    /* in requesting state? */\r
+    if (dhcp->state == DHCP_REQUESTING) {\r
+      dhcp_handle_ack(netif);\r
+      dhcp->request_timeout = 0;\r
+#if DHCP_DOES_ARP_CHECK\r
+      /* check if the acknowledged lease address is already in use */\r
+      dhcp_check(netif);\r
+#else\r
+      /* bind interface to the acknowledged lease address */\r
+      dhcp_bind(netif);\r
+#endif\r
+    }\r
+    /* already bound to the given lease address? */\r
+    else if ((dhcp->state == DHCP_REBOOTING) || (dhcp->state == DHCP_REBINDING) || (dhcp->state == DHCP_RENEWING)) {\r
+      dhcp->request_timeout = 0;\r
+      dhcp_bind(netif);\r
+    }\r
+  }\r
+  /* received a DHCP_NAK in appropriate state? */\r
+  else if ((msg_type == DHCP_NAK) &&\r
+    ((dhcp->state == DHCP_REBOOTING) || (dhcp->state == DHCP_REQUESTING) ||\r
+     (dhcp->state == DHCP_REBINDING) || (dhcp->state == DHCP_RENEWING  ))) {\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 1, ("DHCP_NAK received\n"));\r
+    dhcp->request_timeout = 0;\r
+    dhcp_handle_nak(netif);\r
+  }\r
+  /* received a DHCP_OFFER in DHCP_SELECTING state? */\r
+  else if ((msg_type == DHCP_OFFER) && (dhcp->state == DHCP_SELECTING)) {\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 1, ("DHCP_OFFER received in DHCP_SELECTING state\n"));\r
+    dhcp->request_timeout = 0;\r
+    /* remember offered lease */\r
+    dhcp_handle_offer(netif);\r
+  }\r
+  pbuf_free(p);\r
+  dhcp->p = NULL;\r
+}\r
+\r
+\r
+static err_t dhcp_create_request(struct netif *netif)\r
+{\r
+  struct dhcp *dhcp = netif->dhcp;\r
+  u16_t i;\r
+  LWIP_ASSERT("dhcp_create_request: dhcp->p_out == NULL", dhcp->p_out == NULL);\r
+  LWIP_ASSERT("dhcp_create_request: dhcp->msg_out == NULL", dhcp->msg_out == NULL);\r
+  dhcp->p_out = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct dhcp_msg), PBUF_RAM);\r
+  if (dhcp->p_out == NULL) {\r
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_create_request(): could not allocate pbuf\n"));\r
+    return ERR_MEM;\r
+  }\r
+  /* give unique transaction identifier to this request */\r
+  dhcp->xid = xid++;\r
+\r
+  dhcp->msg_out = (struct dhcp_msg *)dhcp->p_out->payload;\r
+\r
+  dhcp->msg_out->op = DHCP_BOOTREQUEST;\r
+  /* TODO: make link layer independent */\r
+  dhcp->msg_out->htype = DHCP_HTYPE_ETH;\r
+  /* TODO: make link layer independent */\r
+  dhcp->msg_out->hlen = DHCP_HLEN_ETH;\r
+  dhcp->msg_out->hops = 0;\r
+  dhcp->msg_out->xid = htonl(dhcp->xid);\r
+  dhcp->msg_out->secs = 0;\r
+  dhcp->msg_out->flags = 0;\r
+  dhcp->msg_out->ciaddr.addr = netif->ip_addr.addr;\r
+  dhcp->msg_out->yiaddr.addr = 0;\r
+  dhcp->msg_out->siaddr.addr = 0;\r
+  dhcp->msg_out->giaddr.addr = 0;\r
+  for (i = 0; i < DHCP_CHADDR_LEN; i++) {\r
+    /* copy netif hardware address, pad with zeroes */\r
+    dhcp->msg_out->chaddr[i] = (i < netif->hwaddr_len) ? netif->hwaddr[i] : 0/* pad byte*/;\r
+  }\r
+  for (i = 0; i < DHCP_SNAME_LEN; i++) dhcp->msg_out->sname[i] = 0;\r
+  for (i = 0; i < DHCP_FILE_LEN; i++) dhcp->msg_out->file[i] = 0;\r
+  dhcp->msg_out->cookie = htonl(0x63825363UL);\r
+  dhcp->options_out_len = 0;\r
+  /* fill options field with an incrementing array (for debugging purposes) */\r
+  for (i = 0; i < DHCP_OPTIONS_LEN; i++) dhcp->msg_out->options[i] = i;\r
+  return ERR_OK;\r
+}\r
+\r
+static void dhcp_delete_request(struct netif *netif)\r
+{\r
+  struct dhcp *dhcp = netif->dhcp;\r
+  LWIP_ASSERT("dhcp_free_msg: dhcp->p_out != NULL", dhcp->p_out != NULL);\r
+  LWIP_ASSERT("dhcp_free_msg: dhcp->msg_out != NULL", dhcp->msg_out != NULL);\r
+  pbuf_free(dhcp->p_out);\r
+  dhcp->p_out = NULL;\r
+  dhcp->msg_out = NULL;\r
+}\r
+\r
+/**\r
+ * Add a DHCP message trailer\r
+ *\r
+ * Adds the END option to the DHCP message, and if\r
+ * necessary, up to three padding bytes.\r
+ */\r
+\r
+static void dhcp_option_trailer(struct dhcp *dhcp)\r
+{\r
+  LWIP_ASSERT("dhcp_option_trailer: dhcp->msg_out != NULL\n", dhcp->msg_out != NULL);\r
+  LWIP_ASSERT("dhcp_option_trailer: dhcp->options_out_len < DHCP_OPTIONS_LEN\n", dhcp->options_out_len < DHCP_OPTIONS_LEN);\r
+  dhcp->msg_out->options[dhcp->options_out_len++] = DHCP_OPTION_END;\r
+  /* packet is too small, or not 4 byte aligned? */\r
+  while ((dhcp->options_out_len < DHCP_MIN_OPTIONS_LEN) || (dhcp->options_out_len & 3)) {\r
+    /* LWIP_DEBUGF(DHCP_DEBUG,("dhcp_option_trailer:dhcp->options_out_len=%"U16_F", DHCP_OPTIONS_LEN=%"U16_F, dhcp->options_out_len, DHCP_OPTIONS_LEN)); */\r
+    LWIP_ASSERT("dhcp_option_trailer: dhcp->options_out_len < DHCP_OPTIONS_LEN\n", dhcp->options_out_len < DHCP_OPTIONS_LEN);\r
+    /* add a fill/padding byte */\r
+    dhcp->msg_out->options[dhcp->options_out_len++] = 0;\r
+  }\r
+}\r
+\r
+/**\r
+ * Find the offset of a DHCP option inside the DHCP message.\r
+ *\r
+ * @param client DHCP client\r
+ * @param option_type\r
+ *\r
+ * @return a byte offset into the UDP message where the option was found, or\r
+ * zero if the given option was not found.\r
+ */\r
+static u8_t *dhcp_get_option_ptr(struct dhcp *dhcp, u8_t option_type)\r
+{\r
+  u8_t overload = DHCP_OVERLOAD_NONE;\r
+\r
+  /* options available? */\r
+  if ((dhcp->options_in != NULL) && (dhcp->options_in_len > 0)) {\r
+    /* start with options field */\r
+    u8_t *options = (u8_t *)dhcp->options_in;\r
+    u16_t offset = 0;\r
+    /* at least 1 byte to read and no end marker, then at least 3 bytes to read? */\r
+    while ((offset < dhcp->options_in_len) && (options[offset] != DHCP_OPTION_END)) {\r
+      /* LWIP_DEBUGF(DHCP_DEBUG, ("msg_offset=%"U16_F", q->len=%"U16_F, msg_offset, q->len)); */\r
+      /* are the sname and/or file field overloaded with options? */\r
+      if (options[offset] == DHCP_OPTION_OVERLOAD) {\r
+        LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("overloaded message detected\n"));\r
+        /* skip option type and length */\r
+        offset += 2;\r
+        overload = options[offset++];\r
+      }\r
+      /* requested option found */\r
+      else if (options[offset] == option_type) {\r
+        LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("option found at offset %"U16_F" in options\n", offset));\r
+        return &options[offset];\r
+      /* skip option */\r
+      } else {\r
+         LWIP_DEBUGF(DHCP_DEBUG, ("skipping option %"U16_F" in options\n", options[offset]));\r
+        /* skip option type */\r
+        offset++;\r
+        /* skip option length, and then length bytes */\r
+        offset += 1 + options[offset];\r
+      }\r
+    }\r
+    /* is this an overloaded message? */\r
+    if (overload != DHCP_OVERLOAD_NONE) {\r
+      u16_t field_len;\r
+      if (overload == DHCP_OVERLOAD_FILE) {\r
+        LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 1, ("overloaded file field\n"));\r
+        options = (u8_t *)&dhcp->msg_in->file;\r
+        field_len = DHCP_FILE_LEN;\r
+      } else if (overload == DHCP_OVERLOAD_SNAME) {\r
+        LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 1, ("overloaded sname field\n"));\r
+        options = (u8_t *)&dhcp->msg_in->sname;\r
+        field_len = DHCP_SNAME_LEN;\r
+      /* TODO: check if else if () is necessary */\r
+      } else {\r
+        LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 1, ("overloaded sname and file field\n"));\r
+        options = (u8_t *)&dhcp->msg_in->sname;\r
+        field_len = DHCP_FILE_LEN + DHCP_SNAME_LEN;\r
+      }\r
+      offset = 0;\r
+\r
+      /* at least 1 byte to read and no end marker */\r
+      while ((offset < field_len) && (options[offset] != DHCP_OPTION_END)) {\r
+        if (options[offset] == option_type) {\r
+           LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("option found at offset=%"U16_F"\n", offset));\r
+          return &options[offset];\r
+        /* skip option */\r
+        } else {\r
+          LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("skipping option %"U16_F"\n", options[offset]));\r
+          /* skip option type */\r
+          offset++;\r
+          offset += 1 + options[offset];\r
+        }\r
+      }\r
+    }\r
+  }\r
+  return 0;\r
+}\r
+\r
+/**\r
+ * Return the byte of DHCP option data.\r
+ *\r
+ * @param client DHCP client.\r
+ * @param ptr pointer obtained by dhcp_get_option_ptr().\r
+ *\r
+ * @return byte value at the given address.\r
+ */\r
+static u8_t dhcp_get_option_byte(u8_t *ptr)\r
+{\r
+  LWIP_DEBUGF(DHCP_DEBUG, ("option byte value=%"U16_F"\n", (u16_t)(*ptr)));\r
+  return *ptr;\r
+}\r
+\r
+/**\r
+ * Return the 16-bit value of DHCP option data.\r
+ *\r
+ * @param client DHCP client.\r
+ * @param ptr pointer obtained by dhcp_get_option_ptr().\r
+ *\r
+ * @return byte value at the given address.\r
+ */\r
+static u16_t dhcp_get_option_short(u8_t *ptr)\r
+{\r
+  u16_t value;\r
+  value = *ptr++ << 8;\r
+  value |= *ptr;\r
+  LWIP_DEBUGF(DHCP_DEBUG, ("option short value=%"U16_F"\n", value));\r
+  return value;\r
+}\r
+\r
+/**\r
+ * Return the 32-bit value of DHCP option data.\r
+ *\r
+ * @param client DHCP client.\r
+ * @param ptr pointer obtained by dhcp_get_option_ptr().\r
+ *\r
+ * @return byte value at the given address.\r
+ */\r
+static u32_t dhcp_get_option_long(u8_t *ptr)\r
+{\r
+  u32_t value;\r
+  value = (u32_t)(*ptr++) << 24;\r
+  value |= (u32_t)(*ptr++) << 16;\r
+  value |= (u32_t)(*ptr++) << 8;\r
+  value |= (u32_t)(*ptr++);\r
+  LWIP_DEBUGF(DHCP_DEBUG, ("option long value=%"U32_F"\n", value));\r
+  return value;\r
+}\r
+\r
+#endif /* LWIP_DHCP */\r
index 556cbeb5f052f4f38fc89efb18d7cd7d8ebca105..baeee51c3bca9bf442b55f2e034d128d71190c9e 100644 (file)
-/*
- * 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 <adam@sics.se>
- *
- */
-
-
-/* inet.c
- *
- * Functions common to all TCP/IP modules, such as the Internet checksum and the
- * byte order functions.
- *
- */
-
-
-#include "lwip/opt.h"
-
-#include "lwip/arch.h"
-
-#include "lwip/def.h"
-#include "lwip/inet.h"
-
-#include "lwip/sys.h"
-
-/* This is a reference implementation of the checksum algorithm, with the
- * aim of being simple, correct and fully portable. Checksumming is the
- * first thing you would want to optimize for your platform. You will
- * need to port it to your architecture and in your sys_arch.h:
- * 
- * #define LWIP_CHKSUM <your_checksum_routine> 
-*/
-#ifndef LWIP_CHKSUM
-#define LWIP_CHKSUM lwip_standard_chksum
-
-/**
- * lwip checksum
- *
- * @param dataptr points to start of data to be summed at any boundary
- * @param len length of data to be summed
- * @return host order (!) lwip checksum (non-inverted Internet sum) 
- *
- * @note accumulator size limits summable lenght to 64k
- * @note host endianess is irrelevant (p3 RFC1071)
- */
-static u16_t
-lwip_standard_chksum(void *dataptr, u16_t len)
-{
-  u32_t acc;
-  u16_t src;
-  u8_t *octetptr;
-
-  acc = 0;
-  /* dataptr may be at odd or even addresses */
-  octetptr = (u8_t*)dataptr;
-  while (len > 1)
-  {
-    /* declare first octet as most significant
-       thus assume network order, ignoring host order */
-    src = (*octetptr) << 8;
-    octetptr++;
-    /* declare second octet as least significant */
-    src |= (*octetptr);
-    octetptr++;
-    acc += src;
-    len -= 2;
-  }
-  if (len > 0)
-  {
-    /* accumulate remaining octet */
-    src = (*octetptr) << 8;
-    acc += src;
-  }
-  /* add deferred carry bits */
-  acc = (acc >> 16) + (acc & 0x0000ffffUL);
-  if ((acc & 0xffff0000) != 0) {
-    acc = (acc >> 16) + (acc & 0x0000ffffUL);
-  }
-  /* This maybe a little confusing: reorder sum using htons()
-     instead of ntohs() since it has a little less call overhead.
-     The caller must invert bits for Internet sum ! */
-  return htons((u16_t)acc);
-}
-
-#endif
-
-#if 0
-/*
- * Curt McDowell
- * Broadcom Corp.
- * csm@broadcom.com
- *
- * IP checksum two bytes at a time with support for
- * unaligned buffer.
- * Works for len up to and including 0x20000.
- * by Curt McDowell, Broadcom Corp. 12/08/2005
- */
-
-static u16_t
-lwip_standard_chksum2(void *dataptr, int len)
-{
-  u8_t *pb = dataptr;
-  u16_t *ps, t = 0;
-  u32_t sum = 0;
-  int odd = ((u32_t)pb & 1);
-
-  /* Get aligned to u16_t */
-  if (odd && len > 0) {
-    ((u8_t *)&t)[1] = *pb++;
-    len--;
-  }
-
-  /* Add the bulk of the data */
-  ps = (u16_t *)pb;
-  while (len > 1) {
-    sum += *ps++;
-    len -= 2;
-  }
-
-  /* Consume left-over byte, if any */
-  if (len > 0)
-    ((u8_t *)&t)[0] = *(u8_t *)ps;;
-
-  /* Add end bytes */
-  sum += t;
-
-  /*  Fold 32-bit sum to 16 bits */
-  while (sum >> 16)
-    sum = (sum & 0xffff) + (sum >> 16);
-
-  /* Swap if alignment was odd */
-  if (odd)
-    sum = ((sum & 0xff) << 8) | ((sum & 0xff00) >> 8);
-
-  return sum;
-}
-
-/**
- * An optimized checksum routine. Basically, it uses loop-unrolling on
- * the checksum loop, treating the head and tail bytes specially, whereas
- * the inner loop acts on 8 bytes at a time. 
- *
- * @arg start of buffer to be checksummed. May be an odd byte address.
- * @len number of bytes in the buffer to be checksummed.
- * 
- * @todo First argument type conflicts with generic checksum routine.
- * 
- * by Curt McDowell, Broadcom Corp. December 8th, 2005
- */
-
-static u16_t
-lwip_standard_chksum4(u8_t *pb, int len)
-{
-  u16_t *ps, t = 0;
-  u32_t *pl;
-  u32_t sum = 0, tmp;
-  /* starts at odd byte address? */
-  int odd = ((u32_t)pb & 1);
-
-  if (odd && len > 0) {
-    ((u8_t *)&t)[1] = *pb++;
-    len--;
-  }
-
-  ps = (u16_t *)pb;
-
-  if (((u32_t)ps & 3) && len > 1) {
-    sum += *ps++;
-    len -= 2;
-  }
-
-  pl = (u32_t *)ps;
-
-  while (len > 7)  {
-    tmp = sum + *pl++;          /* ping */
-    if (tmp < sum)
-      tmp++;                    /* add back carry */
-
-    sum = tmp + *pl++;          /* pong */
-    if (sum < tmp)
-      sum++;                    /* add back carry */
-
-    len -= 8;
-  }
-
-  /* make room in upper bits */
-  sum = (sum >> 16) + (sum & 0xffff);
-
-  ps = (u16_t *)pl;
-
-  /* 16-bit aligned word remaining? */
-  while (len > 1) {
-    sum += *ps++;
-    len -= 2;
-  }
-
-  /* dangling tail byte remaining? */
-  if (len > 0)                  /* include odd byte */
-    ((u8_t *)&t)[0] = *(u8_t *)ps;
-
-  sum += t;                     /* add end bytes */
-
-  while (sum >> 16)             /* combine halves */
-    sum = (sum >> 16) + (sum & 0xffff);
-
-  if (odd)
-    sum = ((sum & 0xff) << 8) | ((sum & 0xff00) >> 8);
-
-  return sum;
-}
-#endif
-
-/* inet_chksum_pseudo:
- *
- * Calculates the pseudo Internet checksum used by TCP and UDP for a pbuf chain.
- */
-
-u16_t
-inet_chksum_pseudo(struct pbuf *p,
-       struct ip_addr *src, struct ip_addr *dest,
-       u8_t proto, u16_t proto_len)
-{
-  u32_t acc;
-  struct pbuf *q;
-  u8_t swapped;
-
-  acc = 0;
-  swapped = 0;
-  /* iterate through all pbuf in chain */
-  for(q = p; q != NULL; q = q->next) {
-    LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): checksumming pbuf %p (has next %p) \n",
-      (void *)q, (void *)q->next));
-    acc += LWIP_CHKSUM(q->payload, q->len);
-    /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): unwrapped lwip_chksum()=%"X32_F" \n", acc));*/
-    while (acc >> 16) {
-      acc = (acc & 0xffffUL) + (acc >> 16);
-    }
-    if (q->len % 2 != 0) {
-      swapped = 1 - swapped;
-      acc = ((acc & 0xff) << 8) | ((acc & 0xff00UL) >> 8);
-    }
-    /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): wrapped lwip_chksum()=%"X32_F" \n", acc));*/
-  }
-
-  if (swapped) {
-    acc = ((acc & 0xff) << 8) | ((acc & 0xff00UL) >> 8);
-  }
-  acc += (src->addr & 0xffffUL);
-  acc += ((src->addr >> 16) & 0xffffUL);
-  acc += (dest->addr & 0xffffUL);
-  acc += ((dest->addr >> 16) & 0xffffUL);
-  acc += (u32_t)htons((u16_t)proto);
-  acc += (u32_t)htons(proto_len);
-
-  while (acc >> 16) {
-    acc = (acc & 0xffffUL) + (acc >> 16);
-  }
-  LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): pbuf chain lwip_chksum()=%"X32_F"\n", acc));
-  return (u16_t)~(acc & 0xffffUL);
-}
-
-/* inet_chksum:
- *
- * Calculates the Internet checksum over a portion of memory. Used primarely for IP
- * and ICMP.
- */
-
-u16_t
-inet_chksum(void *dataptr, u16_t len)
-{
-  u32_t acc;
-
-  acc = LWIP_CHKSUM(dataptr, len);
-  while (acc >> 16) {
-    acc = (acc & 0xffff) + (acc >> 16);
-  }
-  return (u16_t)~(acc & 0xffff);
-}
-
-u16_t
-inet_chksum_pbuf(struct pbuf *p)
-{
-  u32_t acc;
-  struct pbuf *q;
-  u8_t swapped;
-
-  acc = 0;
-  swapped = 0;
-  for(q = p; q != NULL; q = q->next) {
-    acc += LWIP_CHKSUM(q->payload, q->len);
-    while (acc >> 16) {
-      acc = (acc & 0xffffUL) + (acc >> 16);
-    }
-    if (q->len % 2 != 0) {
-      swapped = 1 - swapped;
-      acc = (acc & 0x00ffUL << 8) | (acc & 0xff00UL >> 8);
-    }
-  }
-
-  if (swapped) {
-    acc = ((acc & 0x00ffUL) << 8) | ((acc & 0xff00UL) >> 8);
-  }
-  return (u16_t)~(acc & 0xffffUL);
-}
-
-/* Here for now until needed in other places in lwIP */
-#ifndef isascii
-#define in_range(c, lo, up)  ((u8_t)c >= lo && (u8_t)c <= up)
-#define isascii(c)           in_range(c, 0x20, 0x7f)
-#define isdigit(c)           in_range(c, '0', '9')
-#define isxdigit(c)          (isdigit(c) || in_range(c, 'a', 'f') || in_range(c, 'A', 'F'))
-#define islower(c)           in_range(c, 'a', 'z')
-#define isspace(c)           (c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v')
-#endif         
-               
-
- /*
-  * Ascii internet address interpretation routine.
-  * The value returned is in network order.
-  */
-
- /*  */
- /* inet_addr */
- u32_t inet_addr(const char *cp)
- {
-     struct in_addr val;
-
-     if (inet_aton(cp, &val)) {
-         return (val.s_addr);
-     }
-     return (INADDR_NONE);
- }
-
- /*
-  * Check whether "cp" is a valid ascii representation
-  * of an Internet address and convert to a binary address.
-  * Returns 1 if the address is valid, 0 if not.
-  * This replaces inet_addr, the return value from which
-  * cannot distinguish between failure and a local broadcast address.
-  */
- /*  */
- /* inet_aton */
- s8_t
- inet_aton(const char *cp, struct in_addr *addr)
- {
-     u32_t val;
-     s32_t base, n;
-     char c;
-     u32_t parts[4];
-     u32_t* pp = parts;
-
-     c = *cp;
-     for (;;) {
-         /*
-          * Collect number up to ``.''.
-          * Values are specified as for C:
-          * 0x=hex, 0=octal, isdigit=decimal.
-          */
-         if (!isdigit(c))
-             return (0);
-         val = 0; base = 10;
-         if (c == '0') {
-             c = *++cp;
-             if (c == 'x' || c == 'X')
-                 base = 16, c = *++cp;
-             else
-                 base = 8;
-         }
-         for (;;) {
-             if (isdigit(c)) {
-                 val = (val * base) + (s16_t)(c - '0');
-                 c = *++cp;
-             } else if (base == 16 && isxdigit(c)) {
-                 val = (val << 4) |
-                     (s16_t)(c + 10 - (islower(c) ? 'a' : 'A'));
-                 c = *++cp;
-             } else
-             break;
-         }
-         if (c == '.') {
-             /*
-              * Internet format:
-              *  a.b.c.d
-              *  a.b.c   (with c treated as 16 bits)
-              *  a.b (with b treated as 24 bits)
-              */
-             if (pp >= parts + 3)
-                 return (0);
-             *pp++ = val;
-             c = *++cp;
-         } else
-             break;
-     }
-     /*
-      * Check for trailing characters.
-      */
-     if (c != '\0' && (!isascii(c) || !isspace(c)))
-         return (0);
-     /*
-      * Concoct the address according to
-      * the number of parts specified.
-      */
-     n = pp - parts + 1;
-     switch (n) {
-
-     case 0:
-         return (0);     /* initial nondigit */
-
-     case 1:             /* a -- 32 bits */
-         break;
-
-     case 2:             /* a.b -- 8.24 bits */
-         if (val > 0xffffff)
-             return (0);
-         val |= parts[0] << 24;
-         break;
-
-     case 3:             /* a.b.c -- 8.8.16 bits */
-         if (val > 0xffff)
-             return (0);
-         val |= (parts[0] << 24) | (parts[1] << 16);
-         break;
-
-     case 4:             /* a.b.c.d -- 8.8.8.8 bits */
-         if (val > 0xff)
-             return (0);
-         val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
-         break;
-     }
-     if (addr)
-         addr->s_addr = htonl(val);
-     return (1);
- }
-
-/* Convert numeric IP address into decimal dotted ASCII representation.
- * returns ptr to static buffer; not reentrant!
- */
-char *inet_ntoa(struct in_addr addr)
-{
-  static char str[16];
-  u32_t s_addr = addr.s_addr;
-  char inv[3];
-  char *rp;
-  u8_t *ap;
-  u8_t rem;
-  u8_t n;
-  u8_t i;
-
-  rp = str;
-  ap = (u8_t *)&s_addr;
-  for(n = 0; n < 4; n++) {
-    i = 0;
-    do {
-      rem = *ap % (u8_t)10;
-      *ap /= (u8_t)10;
-      inv[i++] = '0' + rem;
-    } while(*ap);
-    while(i--)
-      *rp++ = inv[i];
-    *rp++ = '.';
-    ap++;
-  }
-  *--rp = 0;
-  return str;
-}
-
-
-#ifndef BYTE_ORDER
-#error BYTE_ORDER is not defined
-#endif
-#if BYTE_ORDER == LITTLE_ENDIAN
-
-u16_t
-htons(u16_t n)
-{
-  return ((n & 0xff) << 8) | ((n & 0xff00) >> 8);
-}
-
-u16_t
-ntohs(u16_t n)
-{
-  return htons(n);
-}
-
-u32_t
-htonl(u32_t n)
-{
-  return ((n & 0xff) << 24) |
-    ((n & 0xff00) << 8) |
-    ((n & 0xff0000) >> 8) |
-    ((n & 0xff000000) >> 24);
-}
-
-u32_t
-ntohl(u32_t n)
-{
-  return htonl(n);
-}
-
-#endif /* BYTE_ORDER == LITTLE_ENDIAN */
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without modification,\r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED\r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT\r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY\r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ *\r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+\r
+\r
+/* inet.c\r
+ *\r
+ * Functions common to all TCP/IP modules, such as the Internet checksum and the\r
+ * byte order functions.\r
+ *\r
+ */\r
+\r
+\r
+#include "lwip/opt.h"\r
+\r
+#include "lwip/arch.h"\r
+\r
+#include "lwip/def.h"\r
+#include "lwip/inet.h"\r
+\r
+#include "lwip/sys.h"\r
+\r
+/* This is a reference implementation of the checksum algorithm, with the\r
+ * aim of being simple, correct and fully portable. Checksumming is the\r
+ * first thing you would want to optimize for your platform. You will\r
+ * need to port it to your architecture and in your sys_arch.h:\r
+ * \r
+ * #define LWIP_CHKSUM <your_checksum_routine> \r
+*/\r
+#ifndef LWIP_CHKSUM\r
+#define LWIP_CHKSUM lwip_standard_chksum\r
+\r
+/**\r
+ * lwip checksum\r
+ *\r
+ * @param dataptr points to start of data to be summed at any boundary\r
+ * @param len length of data to be summed\r
+ * @return host order (!) lwip checksum (non-inverted Internet sum) \r
+ *\r
+ * @note accumulator size limits summable lenght to 64k\r
+ * @note host endianess is irrelevant (p3 RFC1071)\r
+ */\r
+static u16_t\r
+lwip_standard_chksum(void *dataptr, u16_t len)\r
+{\r
+  u32_t acc;\r
+  u16_t src;\r
+  u8_t *octetptr;\r
+\r
+  acc = 0;\r
+  /* dataptr may be at odd or even addresses */\r
+  octetptr = (u8_t*)dataptr;\r
+  while (len > 1)\r
+  {\r
+    /* declare first octet as most significant\r
+       thus assume network order, ignoring host order */\r
+    src = (*octetptr) << 8;\r
+    octetptr++;\r
+    /* declare second octet as least significant */\r
+    src |= (*octetptr);\r
+    octetptr++;\r
+    acc += src;\r
+    len -= 2;\r
+  }\r
+  if (len > 0)\r
+  {\r
+    /* accumulate remaining octet */\r
+    src = (*octetptr) << 8;\r
+    acc += src;\r
+  }\r
+  /* add deferred carry bits */\r
+  acc = (acc >> 16) + (acc & 0x0000ffffUL);\r
+  if ((acc & 0xffff0000) != 0) {\r
+    acc = (acc >> 16) + (acc & 0x0000ffffUL);\r
+  }\r
+  /* This maybe a little confusing: reorder sum using htons()\r
+     instead of ntohs() since it has a little less call overhead.\r
+     The caller must invert bits for Internet sum ! */\r
+  return htons((u16_t)acc);\r
+}\r
+\r
+#endif\r
+\r
+#if 0\r
+/*\r
+ * Curt McDowell\r
+ * Broadcom Corp.\r
+ * csm@broadcom.com\r
+ *\r
+ * IP checksum two bytes at a time with support for\r
+ * unaligned buffer.\r
+ * Works for len up to and including 0x20000.\r
+ * by Curt McDowell, Broadcom Corp. 12/08/2005\r
+ */\r
+\r
+static u16_t\r
+lwip_standard_chksum2(void *dataptr, int len)\r
+{\r
+  u8_t *pb = dataptr;\r
+  u16_t *ps, t = 0;\r
+  u32_t sum = 0;\r
+  int odd = ((u32_t)pb & 1);\r
+\r
+  /* Get aligned to u16_t */\r
+  if (odd && len > 0) {\r
+    ((u8_t *)&t)[1] = *pb++;\r
+    len--;\r
+  }\r
+\r
+  /* Add the bulk of the data */\r
+  ps = (u16_t *)pb;\r
+  while (len > 1) {\r
+    sum += *ps++;\r
+    len -= 2;\r
+  }\r
+\r
+  /* Consume left-over byte, if any */\r
+  if (len > 0)\r
+    ((u8_t *)&t)[0] = *(u8_t *)ps;;\r
+\r
+  /* Add end bytes */\r
+  sum += t;\r
+\r
+  /*  Fold 32-bit sum to 16 bits */\r
+  while (sum >> 16)\r
+    sum = (sum & 0xffff) + (sum >> 16);\r
+\r
+  /* Swap if alignment was odd */\r
+  if (odd)\r
+    sum = ((sum & 0xff) << 8) | ((sum & 0xff00) >> 8);\r
+\r
+  return sum;\r
+}\r
+\r
+/**\r
+ * An optimized checksum routine. Basically, it uses loop-unrolling on\r
+ * the checksum loop, treating the head and tail bytes specially, whereas\r
+ * the inner loop acts on 8 bytes at a time. \r
+ *\r
+ * @arg start of buffer to be checksummed. May be an odd byte address.\r
+ * @len number of bytes in the buffer to be checksummed.\r
+ * \r
+ * @todo First argument type conflicts with generic checksum routine.\r
+ * \r
+ * by Curt McDowell, Broadcom Corp. December 8th, 2005\r
+ */\r
+\r
+static u16_t\r
+lwip_standard_chksum4(u8_t *pb, int len)\r
+{\r
+  u16_t *ps, t = 0;\r
+  u32_t *pl;\r
+  u32_t sum = 0, tmp;\r
+  /* starts at odd byte address? */\r
+  int odd = ((u32_t)pb & 1);\r
+\r
+  if (odd && len > 0) {\r
+    ((u8_t *)&t)[1] = *pb++;\r
+    len--;\r
+  }\r
+\r
+  ps = (u16_t *)pb;\r
+\r
+  if (((u32_t)ps & 3) && len > 1) {\r
+    sum += *ps++;\r
+    len -= 2;\r
+  }\r
+\r
+  pl = (u32_t *)ps;\r
+\r
+  while (len > 7)  {\r
+    tmp = sum + *pl++;          /* ping */\r
+    if (tmp < sum)\r
+      tmp++;                    /* add back carry */\r
+\r
+    sum = tmp + *pl++;          /* pong */\r
+    if (sum < tmp)\r
+      sum++;                    /* add back carry */\r
+\r
+    len -= 8;\r
+  }\r
+\r
+  /* make room in upper bits */\r
+  sum = (sum >> 16) + (sum & 0xffff);\r
+\r
+  ps = (u16_t *)pl;\r
+\r
+  /* 16-bit aligned word remaining? */\r
+  while (len > 1) {\r
+    sum += *ps++;\r
+    len -= 2;\r
+  }\r
+\r
+  /* dangling tail byte remaining? */\r
+  if (len > 0)                  /* include odd byte */\r
+    ((u8_t *)&t)[0] = *(u8_t *)ps;\r
+\r
+  sum += t;                     /* add end bytes */\r
+\r
+  while (sum >> 16)             /* combine halves */\r
+    sum = (sum >> 16) + (sum & 0xffff);\r
+\r
+  if (odd)\r
+    sum = ((sum & 0xff) << 8) | ((sum & 0xff00) >> 8);\r
+\r
+  return sum;\r
+}\r
+#endif\r
+\r
+/* inet_chksum_pseudo:\r
+ *\r
+ * Calculates the pseudo Internet checksum used by TCP and UDP for a pbuf chain.\r
+ */\r
+\r
+u16_t\r
+inet_chksum_pseudo(struct pbuf *p,\r
+       struct ip_addr *src, struct ip_addr *dest,\r
+       u8_t proto, u16_t proto_len)\r
+{\r
+  u32_t acc;\r
+  struct pbuf *q;\r
+  u8_t swapped;\r
+\r
+  acc = 0;\r
+  swapped = 0;\r
+  /* iterate through all pbuf in chain */\r
+  for(q = p; q != NULL; q = q->next) {\r
+    LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): checksumming pbuf %p (has next %p) \n",\r
+      (void *)q, (void *)q->next));\r
+    acc += LWIP_CHKSUM(q->payload, q->len);\r
+    /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): unwrapped lwip_chksum()=%"X32_F" \n", acc));*/\r
+    while (acc >> 16) {\r
+      acc = (acc & 0xffffUL) + (acc >> 16);\r
+    }\r
+    if (q->len % 2 != 0) {\r
+      swapped = 1 - swapped;\r
+      acc = ((acc & 0xff) << 8) | ((acc & 0xff00UL) >> 8);\r
+    }\r
+    /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): wrapped lwip_chksum()=%"X32_F" \n", acc));*/\r
+  }\r
+\r
+  if (swapped) {\r
+    acc = ((acc & 0xff) << 8) | ((acc & 0xff00UL) >> 8);\r
+  }\r
+  acc += (src->addr & 0xffffUL);\r
+  acc += ((src->addr >> 16) & 0xffffUL);\r
+  acc += (dest->addr & 0xffffUL);\r
+  acc += ((dest->addr >> 16) & 0xffffUL);\r
+  acc += (u32_t)htons((u16_t)proto);\r
+  acc += (u32_t)htons(proto_len);\r
+\r
+  while (acc >> 16) {\r
+    acc = (acc & 0xffffUL) + (acc >> 16);\r
+  }\r
+  LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): pbuf chain lwip_chksum()=%"X32_F"\n", acc));\r
+  return (u16_t)~(acc & 0xffffUL);\r
+}\r
+\r
+/* inet_chksum:\r
+ *\r
+ * Calculates the Internet checksum over a portion of memory. Used primarely for IP\r
+ * and ICMP.\r
+ */\r
+\r
+u16_t\r
+inet_chksum(void *dataptr, u16_t len)\r
+{\r
+  u32_t acc;\r
+\r
+  acc = LWIP_CHKSUM(dataptr, len);\r
+  while (acc >> 16) {\r
+    acc = (acc & 0xffff) + (acc >> 16);\r
+  }\r
+  return (u16_t)~(acc & 0xffff);\r
+}\r
+\r
+u16_t\r
+inet_chksum_pbuf(struct pbuf *p)\r
+{\r
+  u32_t acc;\r
+  struct pbuf *q;\r
+  u8_t swapped;\r
+\r
+  acc = 0;\r
+  swapped = 0;\r
+  for(q = p; q != NULL; q = q->next) {\r
+    acc += LWIP_CHKSUM(q->payload, q->len);\r
+    while (acc >> 16) {\r
+      acc = (acc & 0xffffUL) + (acc >> 16);\r
+    }\r
+    if (q->len % 2 != 0) {\r
+      swapped = 1 - swapped;\r
+      acc = (acc & 0x00ffUL << 8) | (acc & 0xff00UL >> 8);\r
+    }\r
+  }\r
+\r
+  if (swapped) {\r
+    acc = ((acc & 0x00ffUL) << 8) | ((acc & 0xff00UL) >> 8);\r
+  }\r
+  return (u16_t)~(acc & 0xffffUL);\r
+}\r
+\r
+/* Here for now until needed in other places in lwIP */\r
+#ifndef isascii\r
+#define in_range(c, lo, up)  ((u8_t)c >= lo && (u8_t)c <= up)\r
+#define isascii(c)           in_range(c, 0x20, 0x7f)\r
+#define isdigit(c)           in_range(c, '0', '9')\r
+#define isxdigit(c)          (isdigit(c) || in_range(c, 'a', 'f') || in_range(c, 'A', 'F'))\r
+#define islower(c)           in_range(c, 'a', 'z')\r
+#define isspace(c)           (c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v')\r
+#endif         \r
+               \r
+\r
+ /*\r
+  * Ascii internet address interpretation routine.\r
+  * The value returned is in network order.\r
+  */\r
+\r
+ /*  */\r
+ /* inet_addr */\r
+ u32_t inet_addr(const char *cp)\r
+ {\r
+     struct in_addr val;\r
+\r
+     if (inet_aton(cp, &val)) {\r
+         return (val.s_addr);\r
+     }\r
+     return (INADDR_NONE);\r
+ }\r
+\r
+ /*\r
+  * Check whether "cp" is a valid ascii representation\r
+  * of an Internet address and convert to a binary address.\r
+  * Returns 1 if the address is valid, 0 if not.\r
+  * This replaces inet_addr, the return value from which\r
+  * cannot distinguish between failure and a local broadcast address.\r
+  */\r
+ /*  */\r
+ /* inet_aton */\r
+ s8_t\r
+ inet_aton(const char *cp, struct in_addr *addr)\r
+ {\r
+     u32_t val;\r
+     s32_t base, n;\r
+     char c;\r
+     u32_t parts[4];\r
+     u32_t* pp = parts;\r
+\r
+     c = *cp;\r
+     for (;;) {\r
+         /*\r
+          * Collect number up to ``.''.\r
+          * Values are specified as for C:\r
+          * 0x=hex, 0=octal, isdigit=decimal.\r
+          */\r
+         if (!isdigit(c))\r
+             return (0);\r
+         val = 0; base = 10;\r
+         if (c == '0') {\r
+             c = *++cp;\r
+             if (c == 'x' || c == 'X')\r
+                 base = 16, c = *++cp;\r
+             else\r
+                 base = 8;\r
+         }\r
+         for (;;) {\r
+             if (isdigit(c)) {\r
+                 val = (val * base) + (s16_t)(c - '0');\r
+                 c = *++cp;\r
+             } else if (base == 16 && isxdigit(c)) {\r
+                 val = (val << 4) |\r
+                     (s16_t)(c + 10 - (islower(c) ? 'a' : 'A'));\r
+                 c = *++cp;\r
+             } else\r
+             break;\r
+         }\r
+         if (c == '.') {\r
+             /*\r
+              * Internet format:\r
+              *  a.b.c.d\r
+              *  a.b.c   (with c treated as 16 bits)\r
+              *  a.b (with b treated as 24 bits)\r
+              */\r
+             if (pp >= parts + 3)\r
+                 return (0);\r
+             *pp++ = val;\r
+             c = *++cp;\r
+         } else\r
+             break;\r
+     }\r
+     /*\r
+      * Check for trailing characters.\r
+      */\r
+     if (c != '\0' && (!isascii(c) || !isspace(c)))\r
+         return (0);\r
+     /*\r
+      * Concoct the address according to\r
+      * the number of parts specified.\r
+      */\r
+     n = pp - parts + 1;\r
+     switch (n) {\r
+\r
+     case 0:\r
+         return (0);     /* initial nondigit */\r
+\r
+     case 1:             /* a -- 32 bits */\r
+         break;\r
+\r
+     case 2:             /* a.b -- 8.24 bits */\r
+         if (val > 0xffffff)\r
+             return (0);\r
+         val |= parts[0] << 24;\r
+         break;\r
+\r
+     case 3:             /* a.b.c -- 8.8.16 bits */\r
+         if (val > 0xffff)\r
+             return (0);\r
+         val |= (parts[0] << 24) | (parts[1] << 16);\r
+         break;\r
+\r
+     case 4:             /* a.b.c.d -- 8.8.8.8 bits */\r
+         if (val > 0xff)\r
+             return (0);\r
+         val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);\r
+         break;\r
+     }\r
+     if (addr)\r
+         addr->s_addr = htonl(val);\r
+     return (1);\r
+ }\r
+\r
+/* Convert numeric IP address into decimal dotted ASCII representation.\r
+ * returns ptr to static buffer; not reentrant!\r
+ */\r
+char *inet_ntoa(struct in_addr addr)\r
+{\r
+  static char str[16];\r
+  u32_t s_addr = addr.s_addr;\r
+  char inv[3];\r
+  char *rp;\r
+  u8_t *ap;\r
+  u8_t rem;\r
+  u8_t n;\r
+  u8_t i;\r
+\r
+  rp = str;\r
+  ap = (u8_t *)&s_addr;\r
+  for(n = 0; n < 4; n++) {\r
+    i = 0;\r
+    do {\r
+      rem = *ap % (u8_t)10;\r
+      *ap /= (u8_t)10;\r
+      inv[i++] = '0' + rem;\r
+    } while(*ap);\r
+    while(i--)\r
+      *rp++ = inv[i];\r
+    *rp++ = '.';\r
+    ap++;\r
+  }\r
+  *--rp = 0;\r
+  return str;\r
+}\r
+\r
+\r
+#ifndef BYTE_ORDER\r
+#error BYTE_ORDER is not defined\r
+#endif\r
+#if BYTE_ORDER == LITTLE_ENDIAN\r
+\r
+u16_t\r
+htons(u16_t n)\r
+{\r
+  return ((n & 0xff) << 8) | ((n & 0xff00) >> 8);\r
+}\r
+\r
+u16_t\r
+ntohs(u16_t n)\r
+{\r
+  return htons(n);\r
+}\r
+\r
+u32_t\r
+htonl(u32_t n)\r
+{\r
+  return ((n & 0xff) << 24) |\r
+    ((n & 0xff00) << 8) |\r
+    ((n & 0xff0000) >> 8) |\r
+    ((n & 0xff000000) >> 24);\r
+}\r
+\r
+u32_t\r
+ntohl(u32_t n)\r
+{\r
+  return htonl(n);\r
+}\r
+\r
+#endif /* BYTE_ORDER == LITTLE_ENDIAN */\r
index c04915b73d009a6e9be6050231fb60b2b984e5d3..aebc6f381e670a728968465889df3f363d70af12 100644 (file)
-/*
- * 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 <adam@sics.se>
- *
- */
-
-
-/* inet6.c
- *
- * Functions common to all TCP/IP modules, such as the Internet checksum and the
- * byte order functions.
- *
- */
-
-
-#include "lwip/opt.h"
-
-#include "lwip/def.h"
-#include "lwip/inet.h"
-
-
-
-/* chksum:
- *
- * Sums up all 16 bit words in a memory portion. Also includes any odd byte.
- * This function is used by the other checksum functions.
- *
- * For now, this is not optimized. Must be optimized for the particular processor
- * arcitecture on which it is to run. Preferebly coded in assembler.
- */
-
-static u32_t
-chksum(void *dataptr, u16_t len)
-{
-  u16_t *sdataptr = dataptr;
-  u32_t acc;
-  
-  
-  for(acc = 0; len > 1; len -= 2) {
-    acc += *sdataptr++;
-  }
-
-  /* add up any odd byte */
-  if (len == 1) {
-    acc += htons((u16_t)(*(u8_t *)dataptr) << 8);
-  }
-
-  return acc;
-
-}
-
-/* inet_chksum_pseudo:
- *
- * Calculates the pseudo Internet checksum used by TCP and UDP for a pbuf chain.
- */
-
-u16_t
-inet_chksum_pseudo(struct pbuf *p,
-       struct ip_addr *src, struct ip_addr *dest,
-       u8_t proto, u32_t proto_len)
-{
-  u32_t acc;
-  struct pbuf *q;
-  u8_t swapped, i;
-
-  acc = 0;
-  swapped = 0;
-  for(q = p; q != NULL; q = q->next) {    
-    acc += chksum(q->payload, q->len);
-    while (acc >> 16) {
-      acc = (acc & 0xffff) + (acc >> 16);
-    }
-    if (q->len % 2 != 0) {
-      swapped = 1 - swapped;
-      acc = ((acc & 0xff) << 8) | ((acc & 0xff00) >> 8);
-    }
-  }
-
-  if (swapped) {
-    acc = ((acc & 0xff) << 8) | ((acc & 0xff00) >> 8);
-  }
-  
-  for(i = 0; i < 8; i++) {
-    acc += ((u16_t *)src->addr)[i] & 0xffff;
-    acc += ((u16_t *)dest->addr)[i] & 0xffff;
-    while (acc >> 16) {
-      acc = (acc & 0xffff) + (acc >> 16);
-    }
-  }
-  acc += (u16_t)htons((u16_t)proto);
-  acc += ((u16_t *)&proto_len)[0] & 0xffff;
-  acc += ((u16_t *)&proto_len)[1] & 0xffff;
-
-  while (acc >> 16) {
-    acc = (acc & 0xffff) + (acc >> 16);
-  }
-  return ~(acc & 0xffff);
-}
-
-/* inet_chksum:
- *
- * Calculates the Internet checksum over a portion of memory. Used primarely for IP
- * and ICMP.
- */
-
-u16_t
-inet_chksum(void *dataptr, u16_t len)
-{
-  u32_t acc, sum;
-
-  acc = chksum(dataptr, len);
-  sum = (acc & 0xffff) + (acc >> 16);
-  sum += (sum >> 16);
-  return ~(sum & 0xffff);
-}
-
-u16_t
-inet_chksum_pbuf(struct pbuf *p)
-{
-  u32_t acc;
-  struct pbuf *q;
-  u8_t swapped;
-  
-  acc = 0;
-  swapped = 0;
-  for(q = p; q != NULL; q = q->next) {
-    acc += chksum(q->payload, q->len);
-    while (acc >> 16) {
-      acc = (acc & 0xffff) + (acc >> 16);
-    }    
-    if (q->len % 2 != 0) {
-      swapped = 1 - swapped;
-      acc = (acc & 0xff << 8) | (acc & 0xff00 >> 8);
-    }
-  }
-  if (swapped) {
-    acc = ((acc & 0xff) << 8) | ((acc & 0xff00) >> 8);
-  }
-  return ~(acc & 0xffff);
-}
-
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+\r
+\r
+/* inet6.c\r
+ *\r
+ * Functions common to all TCP/IP modules, such as the Internet checksum and the\r
+ * byte order functions.\r
+ *\r
+ */\r
+\r
+\r
+#include "lwip/opt.h"\r
+\r
+#include "lwip/def.h"\r
+#include "lwip/inet.h"\r
+\r
+\r
+\r
+/* chksum:\r
+ *\r
+ * Sums up all 16 bit words in a memory portion. Also includes any odd byte.\r
+ * This function is used by the other checksum functions.\r
+ *\r
+ * For now, this is not optimized. Must be optimized for the particular processor\r
+ * arcitecture on which it is to run. Preferebly coded in assembler.\r
+ */\r
+\r
+static u32_t\r
+chksum(void *dataptr, u16_t len)\r
+{\r
+  u16_t *sdataptr = dataptr;\r
+  u32_t acc;\r
+  \r
+  \r
+  for(acc = 0; len > 1; len -= 2) {\r
+    acc += *sdataptr++;\r
+  }\r
+\r
+  /* add up any odd byte */\r
+  if (len == 1) {\r
+    acc += htons((u16_t)(*(u8_t *)dataptr) << 8);\r
+  }\r
+\r
+  return acc;\r
+\r
+}\r
+\r
+/* inet_chksum_pseudo:\r
+ *\r
+ * Calculates the pseudo Internet checksum used by TCP and UDP for a pbuf chain.\r
+ */\r
+\r
+u16_t\r
+inet_chksum_pseudo(struct pbuf *p,\r
+       struct ip_addr *src, struct ip_addr *dest,\r
+       u8_t proto, u32_t proto_len)\r
+{\r
+  u32_t acc;\r
+  struct pbuf *q;\r
+  u8_t swapped, i;\r
+\r
+  acc = 0;\r
+  swapped = 0;\r
+  for(q = p; q != NULL; q = q->next) {    \r
+    acc += chksum(q->payload, q->len);\r
+    while (acc >> 16) {\r
+      acc = (acc & 0xffff) + (acc >> 16);\r
+    }\r
+    if (q->len % 2 != 0) {\r
+      swapped = 1 - swapped;\r
+      acc = ((acc & 0xff) << 8) | ((acc & 0xff00) >> 8);\r
+    }\r
+  }\r
+\r
+  if (swapped) {\r
+    acc = ((acc & 0xff) << 8) | ((acc & 0xff00) >> 8);\r
+  }\r
+  \r
+  for(i = 0; i < 8; i++) {\r
+    acc += ((u16_t *)src->addr)[i] & 0xffff;\r
+    acc += ((u16_t *)dest->addr)[i] & 0xffff;\r
+    while (acc >> 16) {\r
+      acc = (acc & 0xffff) + (acc >> 16);\r
+    }\r
+  }\r
+  acc += (u16_t)htons((u16_t)proto);\r
+  acc += ((u16_t *)&proto_len)[0] & 0xffff;\r
+  acc += ((u16_t *)&proto_len)[1] & 0xffff;\r
+\r
+  while (acc >> 16) {\r
+    acc = (acc & 0xffff) + (acc >> 16);\r
+  }\r
+  return ~(acc & 0xffff);\r
+}\r
+\r
+/* inet_chksum:\r
+ *\r
+ * Calculates the Internet checksum over a portion of memory. Used primarely for IP\r
+ * and ICMP.\r
+ */\r
+\r
+u16_t\r
+inet_chksum(void *dataptr, u16_t len)\r
+{\r
+  u32_t acc, sum;\r
+\r
+  acc = chksum(dataptr, len);\r
+  sum = (acc & 0xffff) + (acc >> 16);\r
+  sum += (sum >> 16);\r
+  return ~(sum & 0xffff);\r
+}\r
+\r
+u16_t\r
+inet_chksum_pbuf(struct pbuf *p)\r
+{\r
+  u32_t acc;\r
+  struct pbuf *q;\r
+  u8_t swapped;\r
+  \r
+  acc = 0;\r
+  swapped = 0;\r
+  for(q = p; q != NULL; q = q->next) {\r
+    acc += chksum(q->payload, q->len);\r
+    while (acc >> 16) {\r
+      acc = (acc & 0xffff) + (acc >> 16);\r
+    }    \r
+    if (q->len % 2 != 0) {\r
+      swapped = 1 - swapped;\r
+      acc = (acc & 0xff << 8) | (acc & 0xff00 >> 8);\r
+    }\r
+  }\r
\r
+  if (swapped) {\r
+    acc = ((acc & 0xff) << 8) | ((acc & 0xff00) >> 8);\r
+  }\r
+  return ~(acc & 0xffff);\r
+}\r
+\r
index db820148b909f63ccec5e3658a6b987858e0665b..c67ccbcf343e3094d3d420c2784843277d20f8a0 100644 (file)
-/*
- * 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 <adam@sics.se>
- *
- */
-
-/* Some ICMP messages should be passed to the transport protocols. This
-   is not implemented. */
-
-#include <string.h>
-
-#include "lwip/opt.h"
-#include "lwip/icmp.h"
-#include "lwip/inet.h"
-#include "lwip/ip.h"
-#include "lwip/def.h"
-#include "lwip/stats.h"
-#include "lwip/snmp.h"
-
-void
-icmp_input(struct pbuf *p, struct netif *inp)
-{
-  u8_t type;
-  u8_t code;
-  struct icmp_echo_hdr *iecho;
-  struct ip_hdr *iphdr;
-  struct ip_addr tmpaddr;
-  u16_t hlen;
-
-  ICMP_STATS_INC(icmp.recv);
-  snmp_inc_icmpinmsgs();
-
-
-  iphdr = p->payload;
-  hlen = IPH_HL(iphdr) * 4;
-  if (pbuf_header(p, -((s16_t)hlen)) || (p->tot_len < sizeof(u16_t)*2)) {
-    LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: short ICMP (%"U16_F" bytes) received\n", p->tot_len));
-    pbuf_free(p);
-    ICMP_STATS_INC(icmp.lenerr);
-    snmp_inc_icmpinerrors();
-    return;
-  }
-
-  type = *((u8_t *)p->payload);
-  code = *(((u8_t *)p->payload)+1);
-  switch (type) {
-  case ICMP_ECHO:
-    /* broadcast or multicast destination address? */
-    if (ip_addr_isbroadcast(&iphdr->dest, inp) || ip_addr_ismulticast(&iphdr->dest)) {
-      LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: Not echoing to multicast or broadcast pings\n"));
-      ICMP_STATS_INC(icmp.err);
-      pbuf_free(p);
-      return;
-    }
-    LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ping\n"));
-    if (p->tot_len < sizeof(struct icmp_echo_hdr)) {
-      LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: bad ICMP echo received\n"));
-      pbuf_free(p);
-      ICMP_STATS_INC(icmp.lenerr);
-      snmp_inc_icmpinerrors();
-
-      return;
-    }
-    iecho = p->payload;
-    if (inet_chksum_pbuf(p) != 0) {
-      LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: checksum failed for received ICMP echo\n"));
-      pbuf_free(p);
-      ICMP_STATS_INC(icmp.chkerr);
-      snmp_inc_icmpinerrors();
-      return;
-    }
-    tmpaddr.addr = iphdr->src.addr;
-    iphdr->src.addr = iphdr->dest.addr;
-    iphdr->dest.addr = tmpaddr.addr;
-    ICMPH_TYPE_SET(iecho, ICMP_ER);
-    /* adjust the checksum */
-    if (iecho->chksum >= htons(0xffff - (ICMP_ECHO << 8))) {
-      iecho->chksum += htons(ICMP_ECHO << 8) + 1;
-    } else {
-      iecho->chksum += htons(ICMP_ECHO << 8);
-    }
-    ICMP_STATS_INC(icmp.xmit);
-    /* increase number of messages attempted to send */
-    snmp_inc_icmpoutmsgs();
-    /* increase number of echo replies attempted to send */
-    snmp_inc_icmpoutechoreps();
-
-    pbuf_header(p, hlen);
-    ip_output_if(p, &(iphdr->src), IP_HDRINCL,
-                IPH_TTL(iphdr), 0, IP_PROTO_ICMP, inp);
-    break;
-  default:
-  LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ICMP type %"S16_F" code %"S16_F" not supported.\n", (s16_t)type, (s16_t)code));
-    ICMP_STATS_INC(icmp.proterr);
-    ICMP_STATS_INC(icmp.drop);
-  }
-  pbuf_free(p);
-}
-
-void
-icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t)
-{
-  struct pbuf *q;
-  struct ip_hdr *iphdr;
-  struct icmp_dur_hdr *idur;
-
-  q = pbuf_alloc(PBUF_IP, 8 + IP_HLEN + 8, PBUF_RAM);
-  /* ICMP header + IP header + 8 bytes of data */
-
-  iphdr = p->payload;
-
-  idur = q->payload;
-  ICMPH_TYPE_SET(idur, ICMP_DUR);
-  ICMPH_CODE_SET(idur, t);
-
-  memcpy((u8_t *)q->payload + 8, p->payload, IP_HLEN + 8);
-
-  /* calculate checksum */
-  idur->chksum = 0;
-  idur->chksum = inet_chksum(idur, q->len);
-  ICMP_STATS_INC(icmp.xmit);
-  /* increase number of messages attempted to send */
-  snmp_inc_icmpoutmsgs();
-  /* increase number of destination unreachable messages attempted to send */
-  snmp_inc_icmpoutdestunreachs();
-
-  ip_output(q, NULL, &(iphdr->src),
-           ICMP_TTL, 0, IP_PROTO_ICMP);
-  pbuf_free(q);
-}
-
-#if IP_FORWARD
-void
-icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t)
-{
-  struct pbuf *q;
-  struct ip_hdr *iphdr;
-  struct icmp_te_hdr *tehdr;
-
-  q = pbuf_alloc(PBUF_IP, 8 + IP_HLEN + 8, PBUF_RAM);
-
-  iphdr = p->payload;
-  LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded from "));
-  ip_addr_debug_print(ICMP_DEBUG, &(iphdr->src));
-  LWIP_DEBUGF(ICMP_DEBUG, (" to "));
-  ip_addr_debug_print(ICMP_DEBUG, &(iphdr->dest));
-  LWIP_DEBUGF(ICMP_DEBUG, ("\n"));
-
-  tehdr = q->payload;
-  ICMPH_TYPE_SET(tehdr, ICMP_TE);
-  ICMPH_CODE_SET(tehdr, t);
-
-  /* copy fields from original packet */
-  memcpy((u8_t *)q->payload + 8, (u8_t *)p->payload, IP_HLEN + 8);
-
-  /* calculate checksum */
-  tehdr->chksum = 0;
-  tehdr->chksum = inet_chksum(tehdr, q->len);
-  ICMP_STATS_INC(icmp.xmit);
-  /* increase number of messages attempted to send */
-  snmp_inc_icmpoutmsgs();
-  /* increase number of destination unreachable messages attempted to send */
-  snmp_inc_icmpouttimeexcds();
-  ip_output(q, NULL, &(iphdr->src),
-           ICMP_TTL, 0, IP_PROTO_ICMP);
-  pbuf_free(q);
-}
-
-#endif /* IP_FORWARD */
-
-
-
-
-
-
-
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without modification,\r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED\r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT\r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY\r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ *\r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+\r
+/* Some ICMP messages should be passed to the transport protocols. This\r
+   is not implemented. */\r
+\r
+#include <string.h>\r
+\r
+#include "lwip/opt.h"\r
+#include "lwip/icmp.h"\r
+#include "lwip/inet.h"\r
+#include "lwip/ip.h"\r
+#include "lwip/def.h"\r
+#include "lwip/stats.h"\r
+#include "lwip/snmp.h"\r
+\r
+void\r
+icmp_input(struct pbuf *p, struct netif *inp)\r
+{\r
+  u8_t type;\r
+  u8_t code;\r
+  struct icmp_echo_hdr *iecho;\r
+  struct ip_hdr *iphdr;\r
+  struct ip_addr tmpaddr;\r
+  u16_t hlen;\r
+\r
+  ICMP_STATS_INC(icmp.recv);\r
+  snmp_inc_icmpinmsgs();\r
+\r
+\r
+  iphdr = p->payload;\r
+  hlen = IPH_HL(iphdr) * 4;\r
+  if (pbuf_header(p, -((s16_t)hlen)) || (p->tot_len < sizeof(u16_t)*2)) {\r
+    LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: short ICMP (%"U16_F" bytes) received\n", p->tot_len));\r
+    pbuf_free(p);\r
+    ICMP_STATS_INC(icmp.lenerr);\r
+    snmp_inc_icmpinerrors();\r
+    return;\r
+  }\r
+\r
+  type = *((u8_t *)p->payload);\r
+  code = *(((u8_t *)p->payload)+1);\r
+  switch (type) {\r
+  case ICMP_ECHO:\r
+    /* broadcast or multicast destination address? */\r
+    if (ip_addr_isbroadcast(&iphdr->dest, inp) || ip_addr_ismulticast(&iphdr->dest)) {\r
+      LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: Not echoing to multicast or broadcast pings\n"));\r
+      ICMP_STATS_INC(icmp.err);\r
+      pbuf_free(p);\r
+      return;\r
+    }\r
+    LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ping\n"));\r
+    if (p->tot_len < sizeof(struct icmp_echo_hdr)) {\r
+      LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: bad ICMP echo received\n"));\r
+      pbuf_free(p);\r
+      ICMP_STATS_INC(icmp.lenerr);\r
+      snmp_inc_icmpinerrors();\r
+\r
+      return;\r
+    }\r
+    iecho = p->payload;\r
+    if (inet_chksum_pbuf(p) != 0) {\r
+      LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: checksum failed for received ICMP echo\n"));\r
+      pbuf_free(p);\r
+      ICMP_STATS_INC(icmp.chkerr);\r
+      snmp_inc_icmpinerrors();\r
+      return;\r
+    }\r
+    tmpaddr.addr = iphdr->src.addr;\r
+    iphdr->src.addr = iphdr->dest.addr;\r
+    iphdr->dest.addr = tmpaddr.addr;\r
+    ICMPH_TYPE_SET(iecho, ICMP_ER);\r
+    /* adjust the checksum */\r
+    if (iecho->chksum >= htons(0xffff - (ICMP_ECHO << 8))) {\r
+      iecho->chksum += htons(ICMP_ECHO << 8) + 1;\r
+    } else {\r
+      iecho->chksum += htons(ICMP_ECHO << 8);\r
+    }\r
+    ICMP_STATS_INC(icmp.xmit);\r
+    /* increase number of messages attempted to send */\r
+    snmp_inc_icmpoutmsgs();\r
+    /* increase number of echo replies attempted to send */\r
+    snmp_inc_icmpoutechoreps();\r
+\r
+    pbuf_header(p, hlen);\r
+    ip_output_if(p, &(iphdr->src), IP_HDRINCL,\r
+                IPH_TTL(iphdr), 0, IP_PROTO_ICMP, inp);\r
+    break;\r
+  default:\r
+  LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ICMP type %"S16_F" code %"S16_F" not supported.\n", (s16_t)type, (s16_t)code));\r
+    ICMP_STATS_INC(icmp.proterr);\r
+    ICMP_STATS_INC(icmp.drop);\r
+  }\r
+  pbuf_free(p);\r
+}\r
+\r
+void\r
+icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t)\r
+{\r
+  struct pbuf *q;\r
+  struct ip_hdr *iphdr;\r
+  struct icmp_dur_hdr *idur;\r
+\r
+  q = pbuf_alloc(PBUF_IP, 8 + IP_HLEN + 8, PBUF_RAM);\r
+  /* ICMP header + IP header + 8 bytes of data */\r
+\r
+  iphdr = p->payload;\r
+\r
+  idur = q->payload;\r
+  ICMPH_TYPE_SET(idur, ICMP_DUR);\r
+  ICMPH_CODE_SET(idur, t);\r
+\r
+  memcpy((u8_t *)q->payload + 8, p->payload, IP_HLEN + 8);\r
+\r
+  /* calculate checksum */\r
+  idur->chksum = 0;\r
+  idur->chksum = inet_chksum(idur, q->len);\r
+  ICMP_STATS_INC(icmp.xmit);\r
+  /* increase number of messages attempted to send */\r
+  snmp_inc_icmpoutmsgs();\r
+  /* increase number of destination unreachable messages attempted to send */\r
+  snmp_inc_icmpoutdestunreachs();\r
+\r
+  ip_output(q, NULL, &(iphdr->src),\r
+           ICMP_TTL, 0, IP_PROTO_ICMP);\r
+  pbuf_free(q);\r
+}\r
+\r
+#if IP_FORWARD\r
+void\r
+icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t)\r
+{\r
+  struct pbuf *q;\r
+  struct ip_hdr *iphdr;\r
+  struct icmp_te_hdr *tehdr;\r
+\r
+  q = pbuf_alloc(PBUF_IP, 8 + IP_HLEN + 8, PBUF_RAM);\r
+\r
+  iphdr = p->payload;\r
+  LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded from "));\r
+  ip_addr_debug_print(ICMP_DEBUG, &(iphdr->src));\r
+  LWIP_DEBUGF(ICMP_DEBUG, (" to "));\r
+  ip_addr_debug_print(ICMP_DEBUG, &(iphdr->dest));\r
+  LWIP_DEBUGF(ICMP_DEBUG, ("\n"));\r
+\r
+  tehdr = q->payload;\r
+  ICMPH_TYPE_SET(tehdr, ICMP_TE);\r
+  ICMPH_CODE_SET(tehdr, t);\r
+\r
+  /* copy fields from original packet */\r
+  memcpy((u8_t *)q->payload + 8, (u8_t *)p->payload, IP_HLEN + 8);\r
+\r
+  /* calculate checksum */\r
+  tehdr->chksum = 0;\r
+  tehdr->chksum = inet_chksum(tehdr, q->len);\r
+  ICMP_STATS_INC(icmp.xmit);\r
+  /* increase number of messages attempted to send */\r
+  snmp_inc_icmpoutmsgs();\r
+  /* increase number of destination unreachable messages attempted to send */\r
+  snmp_inc_icmpouttimeexcds();\r
+  ip_output(q, NULL, &(iphdr->src),\r
+           ICMP_TTL, 0, IP_PROTO_ICMP);\r
+  pbuf_free(q);\r
+}\r
+\r
+#endif /* IP_FORWARD */\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
index 4db68c8e8603f1ac735ab05e3d51fea9508d785d..1a6d7bd22cc9bc4bcd95ff0f44a317f281a1708d 100644 (file)
-/* @file
- *
- * This is the IP layer implementation for incoming and outgoing IP traffic.
- * 
- * @see ip_frag.c
- *
- */
-/*
- * 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 <adam@sics.se>
- *
- */
-
-#include "lwip/opt.h"
-
-#include "lwip/def.h"
-#include "lwip/mem.h"
-#include "lwip/ip.h"
-#include "lwip/ip_frag.h"
-#include "lwip/inet.h"
-#include "lwip/netif.h"
-#include "lwip/icmp.h"
-#include "lwip/raw.h"
-#include "lwip/udp.h"
-#include "lwip/tcp.h"
-
-#include "lwip/stats.h"
-
-#include "arch/perf.h"
-
-#include "lwip/snmp.h"
-#if LWIP_DHCP
-#  include "lwip/dhcp.h"
-#endif /* LWIP_DHCP */
-
-
-/**
- * Initializes the IP layer.
- */
-
-void
-ip_init(void)
-{
-  /* no initializations as of yet */
-}
-
-/**
- * Finds the appropriate network interface for a given IP address. It
- * searches the list of network interfaces linearly. A match is found
- * if the masked IP address of the network interface equals the masked
- * IP address given to the function.
- */
-
-struct netif *
-ip_route(struct ip_addr *dest)
-{
-  struct netif *netif;
-
-  /* iterate through netifs */
-  for(netif = netif_list; netif != NULL; netif = netif->next) {
-    /* network mask matches? */
-    if (ip_addr_netcmp(dest, &(netif->ip_addr), &(netif->netmask))) {
-      /* return netif on which to forward IP packet */
-      return netif;
-    }
-  }
-  /* no matching netif found, use default netif */
-  return netif_default;
-}
-#if IP_FORWARD
-
-/**
- * Forwards an IP packet. It finds an appropriate route for the
- * packet, decrements the TTL value of the packet, adjusts the
- * checksum and outputs the packet on the appropriate interface.
- */
-
-static struct netif *
-ip_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp)
-{
-  struct netif *netif;
-
-  PERF_START;
-  /* Find network interface where to forward this IP packet to. */
-  netif = ip_route((struct ip_addr *)&(iphdr->dest));
-  if (netif == NULL) {
-    LWIP_DEBUGF(IP_DEBUG, ("ip_forward: no forwarding route for 0x%"X32_F" found\n",
-                      iphdr->dest.addr));
-    snmp_inc_ipnoroutes();
-    return (struct netif *)NULL;
-  }
-  /* Do not forward packets onto the same network interface on which
-   * they arrived. */
-  if (netif == inp) {
-    LWIP_DEBUGF(IP_DEBUG, ("ip_forward: not bouncing packets back on incoming interface.\n"));
-    snmp_inc_ipnoroutes();
-    return (struct netif *)NULL;
-  }
-
-  /* decrement TTL */
-  IPH_TTL_SET(iphdr, IPH_TTL(iphdr) - 1);
-  /* send ICMP if TTL == 0 */
-  if (IPH_TTL(iphdr) == 0) {
-    /* Don't send ICMP messages in response to ICMP messages */
-    if (IPH_PROTO(iphdr) != IP_PROTO_ICMP) {
-      icmp_time_exceeded(p, ICMP_TE_TTL);
-      snmp_inc_icmpouttimeexcds();
-    }
-    return (struct netif *)NULL;
-  }
-
-  /* Incrementally update the IP checksum. */
-  if (IPH_CHKSUM(iphdr) >= htons(0xffff - 0x100)) {
-    IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + htons(0x100) + 1);
-  } else {
-    IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + htons(0x100));
-  }
-
-  LWIP_DEBUGF(IP_DEBUG, ("ip_forward: forwarding packet to 0x%"X32_F"\n",
-                    iphdr->dest.addr));
-
-  IP_STATS_INC(ip.fw);
-  IP_STATS_INC(ip.xmit);
-    snmp_inc_ipforwdatagrams();
-
-  PERF_STOP("ip_forward");
-  /* transmit pbuf on chosen interface */
-  netif->output(netif, p, (struct ip_addr *)&(iphdr->dest));
-  return netif;
-}
-#endif /* IP_FORWARD */
-
-/**
- * This function is called by the network interface device driver when
- * an IP packet is received. The function does the basic checks of the
- * IP header such as packet size being at least larger than the header
- * size etc. If the packet was not destined for us, the packet is
- * forwarded (using ip_forward). The IP checksum is always checked.
- *
- * Finally, the packet is sent to the upper layer protocol input function.
- * 
- * 
- * 
- */
-
-err_t
-ip_input(struct pbuf *p, struct netif *inp) {
-  struct ip_hdr *iphdr;
-  struct netif *netif;
-  u16_t iphdrlen;
-
-  IP_STATS_INC(ip.recv);
-  snmp_inc_ipinreceives();
-
-  /* identify the IP header */
-  iphdr = p->payload;
-  if (IPH_V(iphdr) != 4) {
-    LWIP_DEBUGF(IP_DEBUG | 1, ("IP packet dropped due to bad version number %"U16_F"\n", IPH_V(iphdr)));
-    ip_debug_print(p);
-    pbuf_free(p);
-    IP_STATS_INC(ip.err);
-    IP_STATS_INC(ip.drop);
-    snmp_inc_ipunknownprotos();
-    return ERR_OK;
-  }
-  /* obtain IP header length in number of 32-bit words */
-  iphdrlen = IPH_HL(iphdr);
-  /* calculate IP header length in bytes */
-  iphdrlen *= 4;
-
-  /* header length exceeds first pbuf length? */
-  if (iphdrlen > p->len) {
-    LWIP_DEBUGF(IP_DEBUG | 2, ("IP header (len %"U16_F") does not fit in first pbuf (len %"U16_F"), IP packet droppped.\n",
-      iphdrlen, p->len));
-    /* free (drop) packet pbufs */
-    pbuf_free(p);
-    IP_STATS_INC(ip.lenerr);
-    IP_STATS_INC(ip.drop);
-    snmp_inc_ipindiscards();
-    return ERR_OK;
-  }
-
-  /* verify checksum */
-#if CHECKSUM_CHECK_IP
-  if (inet_chksum(iphdr, iphdrlen) != 0) {
-
-    LWIP_DEBUGF(IP_DEBUG | 2, ("Checksum (0x%"X16_F") failed, IP packet dropped.\n", inet_chksum(iphdr, iphdrlen)));
-    ip_debug_print(p);
-    pbuf_free(p);
-    IP_STATS_INC(ip.chkerr);
-    IP_STATS_INC(ip.drop);
-    snmp_inc_ipindiscards();
-    return ERR_OK;
-  }
-#endif
-
-  /* Trim pbuf. This should have been done at the netif layer,
-   * but we'll do it anyway just to be sure that its done. */
-  pbuf_realloc(p, ntohs(IPH_LEN(iphdr)));
-
-  /* match packet against an interface, i.e. is this packet for us? */
-  for (netif = netif_list; netif != NULL; netif = netif->next) {
-
-    LWIP_DEBUGF(IP_DEBUG, ("ip_input: iphdr->dest 0x%"X32_F" netif->ip_addr 0x%"X32_F" (0x%"X32_F", 0x%"X32_F", 0x%"X32_F")\n",
-      iphdr->dest.addr, netif->ip_addr.addr,
-      iphdr->dest.addr & netif->netmask.addr,
-      netif->ip_addr.addr & netif->netmask.addr,
-      iphdr->dest.addr & ~(netif->netmask.addr)));
-
-    /* interface is up and configured? */
-    if ((netif_is_up(netif)) && (!ip_addr_isany(&(netif->ip_addr))))
-    {
-      /* unicast to this interface address? */
-      if (ip_addr_cmp(&(iphdr->dest), &(netif->ip_addr)) ||
-         /* or broadcast on this interface network address? */
-         ip_addr_isbroadcast(&(iphdr->dest), netif)) {
-        LWIP_DEBUGF(IP_DEBUG, ("ip_input: packet accepted on interface %c%c\n",
-          netif->name[0], netif->name[1]));
-        /* break out of for loop */
-        break;
-      }
-    }
-  }
-#if LWIP_DHCP
-  /* Pass DHCP messages regardless of destination address. DHCP traffic is addressed
-   * using link layer addressing (such as Ethernet MAC) so we must not filter on IP.
-   * According to RFC 1542 section 3.1.1, referred by RFC 2131).
-   */
-  if (netif == NULL) {
-    /* remote port is DHCP server? */
-    if (IPH_PROTO(iphdr) == IP_PROTO_UDP) {
-      LWIP_DEBUGF(IP_DEBUG | DBG_TRACE | 1, ("ip_input: UDP packet to DHCP client port %"U16_F"\n",
-        ntohs(((struct udp_hdr *)((u8_t *)iphdr + iphdrlen))->dest)));
-      if (ntohs(((struct udp_hdr *)((u8_t *)iphdr + iphdrlen))->dest) == DHCP_CLIENT_PORT) {
-        LWIP_DEBUGF(IP_DEBUG | DBG_TRACE | 1, ("ip_input: DHCP packet accepted.\n"));
-        netif = inp;
-      }
-    }
-  }
-#endif /* LWIP_DHCP */
-  /* packet not for us? */
-  if (netif == NULL) {
-    /* packet not for us, route or discard */
-    LWIP_DEBUGF(IP_DEBUG | DBG_TRACE | 1, ("ip_input: packet not for us.\n"));
-#if IP_FORWARD
-    /* non-broadcast packet? */
-    if (!ip_addr_isbroadcast(&(iphdr->dest), inp)) {
-      /* try to forward IP packet on (other) interfaces */
-      ip_forward(p, iphdr, inp);
-    }
-    else
-#endif /* IP_FORWARD */
-    {
-      snmp_inc_ipindiscards();
-    }
-    pbuf_free(p);
-    return ERR_OK;
-  }
-  /* packet consists of multiple fragments? */
-  if ((IPH_OFFSET(iphdr) & htons(IP_OFFMASK | IP_MF)) != 0) {
-#if IP_REASSEMBLY /* packet fragment reassembly code present? */
-    LWIP_DEBUGF(IP_DEBUG, ("IP packet is a fragment (id=0x%04"X16_F" tot_len=%"U16_F" len=%"U16_F" MF=%"U16_F" offset=%"U16_F"), calling ip_reass()\n",
-      ntohs(IPH_ID(iphdr)), p->tot_len, ntohs(IPH_LEN(iphdr)), !!(IPH_OFFSET(iphdr) & htons(IP_MF)), (ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK)*8));
-    /* reassemble the packet*/
-    p = ip_reass(p);
-    /* packet not fully reassembled yet? */
-    if (p == NULL) {
-      return ERR_OK;
-    }
-    iphdr = p->payload;
-#else /* IP_REASSEMBLY == 0, no packet fragment reassembly code present */
-    pbuf_free(p);
-    LWIP_DEBUGF(IP_DEBUG | 2, ("IP packet dropped since it was fragmented (0x%"X16_F") (while IP_REASSEMBLY == 0).\n",
-      ntohs(IPH_OFFSET(iphdr))));
-    IP_STATS_INC(ip.opterr);
-    IP_STATS_INC(ip.drop);
-    snmp_inc_ipunknownprotos();
-    return ERR_OK;
-#endif /* IP_REASSEMBLY */
-  }
-
-#if IP_OPTIONS == 0 /* no support for IP options in the IP header? */
-  if (iphdrlen > IP_HLEN) {
-    LWIP_DEBUGF(IP_DEBUG | 2, ("IP packet dropped since there were IP options (while IP_OPTIONS == 0).\n"));
-    pbuf_free(p);
-    IP_STATS_INC(ip.opterr);
-    IP_STATS_INC(ip.drop);
-    snmp_inc_ipunknownprotos();
-    return ERR_OK;
-  }
-#endif /* IP_OPTIONS == 0 */
-
-  /* send to upper layers */
-  LWIP_DEBUGF(IP_DEBUG, ("ip_input: \n"));
-  ip_debug_print(p);
-  LWIP_DEBUGF(IP_DEBUG, ("ip_input: p->len %"U16_F" p->tot_len %"U16_F"\n", p->len, p->tot_len));
-
-#if LWIP_RAW
-  /* raw input did not eat the packet? */
-  if (raw_input(p, inp) == 0) {
-#endif /* LWIP_RAW */
-
-  switch (IPH_PROTO(iphdr)) {
-#if LWIP_UDP
-  case IP_PROTO_UDP:
-  case IP_PROTO_UDPLITE:
-    snmp_inc_ipindelivers();
-    udp_input(p, inp);
-    break;
-#endif /* LWIP_UDP */
-#if LWIP_TCP
-  case IP_PROTO_TCP:
-    snmp_inc_ipindelivers();
-    tcp_input(p, inp);
-    break;
-#endif /* LWIP_TCP */
-  case IP_PROTO_ICMP:
-    snmp_inc_ipindelivers();
-    icmp_input(p, inp);
-    break;
-  default:
-    /* send ICMP destination protocol unreachable unless is was a broadcast */
-    if (!ip_addr_isbroadcast(&(iphdr->dest), inp) &&
-        !ip_addr_ismulticast(&(iphdr->dest))) {
-      p->payload = iphdr;
-      icmp_dest_unreach(p, ICMP_DUR_PROTO);
-    }
-    pbuf_free(p);
-
-    LWIP_DEBUGF(IP_DEBUG | 2, ("Unsupported transport protocol %"U16_F"\n", IPH_PROTO(iphdr)));
-
-    IP_STATS_INC(ip.proterr);
-    IP_STATS_INC(ip.drop);
-    snmp_inc_ipunknownprotos();
-  }
-#if LWIP_RAW
-  } /* LWIP_RAW */
-#endif
-  return ERR_OK;
-}
-
-/**
- * Sends an IP packet on a network interface. This function constructs
- * the IP header and calculates the IP header checksum. If the source
- * IP address is NULL, the IP address of the outgoing network
- * interface is filled in as source address.
- */
-
-err_t
-ip_output_if(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
-             u8_t ttl, u8_t tos,
-             u8_t proto, struct netif *netif)
-{
-  struct ip_hdr *iphdr;
-  u16_t ip_id = 0;
-
-  snmp_inc_ipoutrequests();
-
-  if (dest != IP_HDRINCL) {
-    if (pbuf_header(p, IP_HLEN)) {
-      LWIP_DEBUGF(IP_DEBUG | 2, ("ip_output: not enough room for IP header in pbuf\n"));
-
-      IP_STATS_INC(ip.err);
-      snmp_inc_ipoutdiscards();
-      return ERR_BUF;
-    }
-
-    iphdr = p->payload;
-
-    IPH_TTL_SET(iphdr, ttl);
-    IPH_PROTO_SET(iphdr, proto);
-
-    ip_addr_set(&(iphdr->dest), dest);
-
-    IPH_VHLTOS_SET(iphdr, 4, IP_HLEN / 4, tos);
-    IPH_LEN_SET(iphdr, htons(p->tot_len));
-    IPH_OFFSET_SET(iphdr, htons(IP_DF));
-    IPH_ID_SET(iphdr, htons(ip_id));
-    ++ip_id;
-
-    if (ip_addr_isany(src)) {
-      ip_addr_set(&(iphdr->src), &(netif->ip_addr));
-    } else {
-      ip_addr_set(&(iphdr->src), src);
-    }
-
-    IPH_CHKSUM_SET(iphdr, 0);
-#if CHECKSUM_GEN_IP
-    IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN));
-#endif
-  } else {
-    iphdr = p->payload;
-    dest = &(iphdr->dest);
-  }
-
-#if IP_FRAG
-  /* don't fragment if interface has mtu set to 0 [loopif] */
-  if (netif->mtu && (p->tot_len > netif->mtu))
-    return ip_frag(p,netif,dest);
-#endif
-
-  IP_STATS_INC(ip.xmit);
-
-  LWIP_DEBUGF(IP_DEBUG, ("ip_output_if: %c%c%"U16_F"\n", netif->name[0], netif->name[1], netif->num));
-  ip_debug_print(p);
-
-  LWIP_DEBUGF(IP_DEBUG, ("netif->output()"));
-
-  return netif->output(netif, p, dest);
-}
-
-/**
- * Simple interface to ip_output_if. It finds the outgoing network
- * interface and calls upon ip_output_if to do the actual work.
- */
-
-err_t
-ip_output(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
-          u8_t ttl, u8_t tos, u8_t proto)
-{
-  struct netif *netif;
-
-  if ((netif = ip_route(dest)) == NULL) {
-    LWIP_DEBUGF(IP_DEBUG | 2, ("ip_output: No route to 0x%"X32_F"\n", dest->addr));
-
-    IP_STATS_INC(ip.rterr);
-    snmp_inc_ipoutdiscards();
-    return ERR_RTE;
-  }
-
-  return ip_output_if(p, src, dest, ttl, tos, proto, netif);
-}
-
-#if IP_DEBUG
-void
-ip_debug_print(struct pbuf *p)
-{
-  struct ip_hdr *iphdr = p->payload;
-  u8_t *payload;
-
-  payload = (u8_t *)iphdr + IP_HLEN;
-
-  LWIP_DEBUGF(IP_DEBUG, ("IP header:\n"));
-  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
-  LWIP_DEBUGF(IP_DEBUG, ("|%2"S16_F" |%2"S16_F" |  0x%02"X16_F" |     %5"U16_F"     | (v, hl, tos, len)\n",
-                    IPH_V(iphdr),
-                    IPH_HL(iphdr),
-                    IPH_TOS(iphdr),
-                    ntohs(IPH_LEN(iphdr))));
-  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
-  LWIP_DEBUGF(IP_DEBUG, ("|    %5"U16_F"      |%"U16_F"%"U16_F"%"U16_F"|    %4"U16_F"   | (id, flags, offset)\n",
-                    ntohs(IPH_ID(iphdr)),
-                    ntohs(IPH_OFFSET(iphdr)) >> 15 & 1,
-                    ntohs(IPH_OFFSET(iphdr)) >> 14 & 1,
-                    ntohs(IPH_OFFSET(iphdr)) >> 13 & 1,
-                    ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK));
-  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
-  LWIP_DEBUGF(IP_DEBUG, ("|  %3"U16_F"  |  %3"U16_F"  |    0x%04"X16_F"     | (ttl, proto, chksum)\n",
-                    IPH_TTL(iphdr),
-                    IPH_PROTO(iphdr),
-                    ntohs(IPH_CHKSUM(iphdr))));
-  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
-  LWIP_DEBUGF(IP_DEBUG, ("|  %3"U16_F"  |  %3"U16_F"  |  %3"U16_F"  |  %3"U16_F"  | (src)\n",
-                    ip4_addr1(&iphdr->src),
-                    ip4_addr2(&iphdr->src),
-                    ip4_addr3(&iphdr->src),
-                    ip4_addr4(&iphdr->src)));
-  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
-  LWIP_DEBUGF(IP_DEBUG, ("|  %3"U16_F"  |  %3"U16_F"  |  %3"U16_F"  |  %3"U16_F"  | (dest)\n",
-                    ip4_addr1(&iphdr->dest),
-                    ip4_addr2(&iphdr->dest),
-                    ip4_addr3(&iphdr->dest),
-                    ip4_addr4(&iphdr->dest)));
-  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
-}
-#endif /* IP_DEBUG */
-
-
-
-
-
-
+/* @file\r
+ *\r
+ * This is the IP layer implementation for incoming and outgoing IP traffic.\r
+ * \r
+ * @see ip_frag.c\r
+ *\r
+ */\r
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without modification,\r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED\r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT\r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY\r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ *\r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+\r
+#include "lwip/opt.h"\r
+\r
+#include "lwip/def.h"\r
+#include "lwip/mem.h"\r
+#include "lwip/ip.h"\r
+#include "lwip/ip_frag.h"\r
+#include "lwip/inet.h"\r
+#include "lwip/netif.h"\r
+#include "lwip/icmp.h"\r
+#include "lwip/raw.h"\r
+#include "lwip/udp.h"\r
+#include "lwip/tcp.h"\r
+\r
+#include "lwip/stats.h"\r
+\r
+#include "arch/perf.h"\r
+\r
+#include "lwip/snmp.h"\r
+#if LWIP_DHCP\r
+#  include "lwip/dhcp.h"\r
+#endif /* LWIP_DHCP */\r
+\r
+\r
+/**\r
+ * Initializes the IP layer.\r
+ */\r
+\r
+void\r
+ip_init(void)\r
+{\r
+  /* no initializations as of yet */\r
+}\r
+\r
+/**\r
+ * Finds the appropriate network interface for a given IP address. It\r
+ * searches the list of network interfaces linearly. A match is found\r
+ * if the masked IP address of the network interface equals the masked\r
+ * IP address given to the function.\r
+ */\r
+\r
+struct netif *\r
+ip_route(struct ip_addr *dest)\r
+{\r
+  struct netif *netif;\r
+\r
+  /* iterate through netifs */\r
+  for(netif = netif_list; netif != NULL; netif = netif->next) {\r
+    /* network mask matches? */\r
+    if (ip_addr_netcmp(dest, &(netif->ip_addr), &(netif->netmask))) {\r
+      /* return netif on which to forward IP packet */\r
+      return netif;\r
+    }\r
+  }\r
+  /* no matching netif found, use default netif */\r
+  return netif_default;\r
+}\r
+#if IP_FORWARD\r
+\r
+/**\r
+ * Forwards an IP packet. It finds an appropriate route for the\r
+ * packet, decrements the TTL value of the packet, adjusts the\r
+ * checksum and outputs the packet on the appropriate interface.\r
+ */\r
+\r
+static struct netif *\r
+ip_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp)\r
+{\r
+  struct netif *netif;\r
+\r
+  PERF_START;\r
+  /* Find network interface where to forward this IP packet to. */\r
+  netif = ip_route((struct ip_addr *)&(iphdr->dest));\r
+  if (netif == NULL) {\r
+    LWIP_DEBUGF(IP_DEBUG, ("ip_forward: no forwarding route for 0x%"X32_F" found\n",\r
+                      iphdr->dest.addr));\r
+    snmp_inc_ipnoroutes();\r
+    return (struct netif *)NULL;\r
+  }\r
+  /* Do not forward packets onto the same network interface on which\r
+   * they arrived. */\r
+  if (netif == inp) {\r
+    LWIP_DEBUGF(IP_DEBUG, ("ip_forward: not bouncing packets back on incoming interface.\n"));\r
+    snmp_inc_ipnoroutes();\r
+    return (struct netif *)NULL;\r
+  }\r
+\r
+  /* decrement TTL */\r
+  IPH_TTL_SET(iphdr, IPH_TTL(iphdr) - 1);\r
+  /* send ICMP if TTL == 0 */\r
+  if (IPH_TTL(iphdr) == 0) {\r
+    /* Don't send ICMP messages in response to ICMP messages */\r
+    if (IPH_PROTO(iphdr) != IP_PROTO_ICMP) {\r
+      icmp_time_exceeded(p, ICMP_TE_TTL);\r
+      snmp_inc_icmpouttimeexcds();\r
+    }\r
+    return (struct netif *)NULL;\r
+  }\r
+\r
+  /* Incrementally update the IP checksum. */\r
+  if (IPH_CHKSUM(iphdr) >= htons(0xffff - 0x100)) {\r
+    IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + htons(0x100) + 1);\r
+  } else {\r
+    IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + htons(0x100));\r
+  }\r
+\r
+  LWIP_DEBUGF(IP_DEBUG, ("ip_forward: forwarding packet to 0x%"X32_F"\n",\r
+                    iphdr->dest.addr));\r
+\r
+  IP_STATS_INC(ip.fw);\r
+  IP_STATS_INC(ip.xmit);\r
+    snmp_inc_ipforwdatagrams();\r
+\r
+  PERF_STOP("ip_forward");\r
+  /* transmit pbuf on chosen interface */\r
+  netif->output(netif, p, (struct ip_addr *)&(iphdr->dest));\r
+  return netif;\r
+}\r
+#endif /* IP_FORWARD */\r
+\r
+/**\r
+ * This function is called by the network interface device driver when\r
+ * an IP packet is received. The function does the basic checks of the\r
+ * IP header such as packet size being at least larger than the header\r
+ * size etc. If the packet was not destined for us, the packet is\r
+ * forwarded (using ip_forward). The IP checksum is always checked.\r
+ *\r
+ * Finally, the packet is sent to the upper layer protocol input function.\r
+ * \r
+ * \r
+ * \r
+ */\r
+\r
+err_t\r
+ip_input(struct pbuf *p, struct netif *inp) {\r
+  struct ip_hdr *iphdr;\r
+  struct netif *netif;\r
+  u16_t iphdrlen;\r
+\r
+  IP_STATS_INC(ip.recv);\r
+  snmp_inc_ipinreceives();\r
+\r
+  /* identify the IP header */\r
+  iphdr = p->payload;\r
+  if (IPH_V(iphdr) != 4) {\r
+    LWIP_DEBUGF(IP_DEBUG | 1, ("IP packet dropped due to bad version number %"U16_F"\n", IPH_V(iphdr)));\r
+    ip_debug_print(p);\r
+    pbuf_free(p);\r
+    IP_STATS_INC(ip.err);\r
+    IP_STATS_INC(ip.drop);\r
+    snmp_inc_ipunknownprotos();\r
+    return ERR_OK;\r
+  }\r
+  /* obtain IP header length in number of 32-bit words */\r
+  iphdrlen = IPH_HL(iphdr);\r
+  /* calculate IP header length in bytes */\r
+  iphdrlen *= 4;\r
+\r
+  /* header length exceeds first pbuf length? */\r
+  if (iphdrlen > p->len) {\r
+    LWIP_DEBUGF(IP_DEBUG | 2, ("IP header (len %"U16_F") does not fit in first pbuf (len %"U16_F"), IP packet droppped.\n",\r
+      iphdrlen, p->len));\r
+    /* free (drop) packet pbufs */\r
+    pbuf_free(p);\r
+    IP_STATS_INC(ip.lenerr);\r
+    IP_STATS_INC(ip.drop);\r
+    snmp_inc_ipindiscards();\r
+    return ERR_OK;\r
+  }\r
+\r
+  /* verify checksum */\r
+#if CHECKSUM_CHECK_IP\r
+  if (inet_chksum(iphdr, iphdrlen) != 0) {\r
+\r
+    LWIP_DEBUGF(IP_DEBUG | 2, ("Checksum (0x%"X16_F") failed, IP packet dropped.\n", inet_chksum(iphdr, iphdrlen)));\r
+    ip_debug_print(p);\r
+    pbuf_free(p);\r
+    IP_STATS_INC(ip.chkerr);\r
+    IP_STATS_INC(ip.drop);\r
+    snmp_inc_ipindiscards();\r
+    return ERR_OK;\r
+  }\r
+#endif\r
+\r
+  /* Trim pbuf. This should have been done at the netif layer,\r
+   * but we'll do it anyway just to be sure that its done. */\r
+  pbuf_realloc(p, ntohs(IPH_LEN(iphdr)));\r
+\r
+  /* match packet against an interface, i.e. is this packet for us? */\r
+  for (netif = netif_list; netif != NULL; netif = netif->next) {\r
+\r
+    LWIP_DEBUGF(IP_DEBUG, ("ip_input: iphdr->dest 0x%"X32_F" netif->ip_addr 0x%"X32_F" (0x%"X32_F", 0x%"X32_F", 0x%"X32_F")\n",\r
+      iphdr->dest.addr, netif->ip_addr.addr,\r
+      iphdr->dest.addr & netif->netmask.addr,\r
+      netif->ip_addr.addr & netif->netmask.addr,\r
+      iphdr->dest.addr & ~(netif->netmask.addr)));\r
+\r
+    /* interface is up and configured? */\r
+    if ((netif_is_up(netif)) && (!ip_addr_isany(&(netif->ip_addr))))\r
+    {\r
+      /* unicast to this interface address? */\r
+      if (ip_addr_cmp(&(iphdr->dest), &(netif->ip_addr)) ||\r
+         /* or broadcast on this interface network address? */\r
+         ip_addr_isbroadcast(&(iphdr->dest), netif)) {\r
+        LWIP_DEBUGF(IP_DEBUG, ("ip_input: packet accepted on interface %c%c\n",\r
+          netif->name[0], netif->name[1]));\r
+        /* break out of for loop */\r
+        break;\r
+      }\r
+    }\r
+  }\r
+#if LWIP_DHCP\r
+  /* Pass DHCP messages regardless of destination address. DHCP traffic is addressed\r
+   * using link layer addressing (such as Ethernet MAC) so we must not filter on IP.\r
+   * According to RFC 1542 section 3.1.1, referred by RFC 2131).\r
+   */\r
+  if (netif == NULL) {\r
+    /* remote port is DHCP server? */\r
+    if (IPH_PROTO(iphdr) == IP_PROTO_UDP) {\r
+      LWIP_DEBUGF(IP_DEBUG | DBG_TRACE | 1, ("ip_input: UDP packet to DHCP client port %"U16_F"\n",\r
+        ntohs(((struct udp_hdr *)((u8_t *)iphdr + iphdrlen))->dest)));\r
+      if (ntohs(((struct udp_hdr *)((u8_t *)iphdr + iphdrlen))->dest) == DHCP_CLIENT_PORT) {\r
+        LWIP_DEBUGF(IP_DEBUG | DBG_TRACE | 1, ("ip_input: DHCP packet accepted.\n"));\r
+        netif = inp;\r
+      }\r
+    }\r
+  }\r
+#endif /* LWIP_DHCP */\r
+  /* packet not for us? */\r
+  if (netif == NULL) {\r
+    /* packet not for us, route or discard */\r
+    LWIP_DEBUGF(IP_DEBUG | DBG_TRACE | 1, ("ip_input: packet not for us.\n"));\r
+#if IP_FORWARD\r
+    /* non-broadcast packet? */\r
+    if (!ip_addr_isbroadcast(&(iphdr->dest), inp)) {\r
+      /* try to forward IP packet on (other) interfaces */\r
+      ip_forward(p, iphdr, inp);\r
+    }\r
+    else\r
+#endif /* IP_FORWARD */\r
+    {\r
+      snmp_inc_ipindiscards();\r
+    }\r
+    pbuf_free(p);\r
+    return ERR_OK;\r
+  }\r
+  /* packet consists of multiple fragments? */\r
+  if ((IPH_OFFSET(iphdr) & htons(IP_OFFMASK | IP_MF)) != 0) {\r
+#if IP_REASSEMBLY /* packet fragment reassembly code present? */\r
+    LWIP_DEBUGF(IP_DEBUG, ("IP packet is a fragment (id=0x%04"X16_F" tot_len=%"U16_F" len=%"U16_F" MF=%"U16_F" offset=%"U16_F"), calling ip_reass()\n",\r
+      ntohs(IPH_ID(iphdr)), p->tot_len, ntohs(IPH_LEN(iphdr)), !!(IPH_OFFSET(iphdr) & htons(IP_MF)), (ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK)*8));\r
+    /* reassemble the packet*/\r
+    p = ip_reass(p);\r
+    /* packet not fully reassembled yet? */\r
+    if (p == NULL) {\r
+      return ERR_OK;\r
+    }\r
+    iphdr = p->payload;\r
+#else /* IP_REASSEMBLY == 0, no packet fragment reassembly code present */\r
+    pbuf_free(p);\r
+    LWIP_DEBUGF(IP_DEBUG | 2, ("IP packet dropped since it was fragmented (0x%"X16_F") (while IP_REASSEMBLY == 0).\n",\r
+      ntohs(IPH_OFFSET(iphdr))));\r
+    IP_STATS_INC(ip.opterr);\r
+    IP_STATS_INC(ip.drop);\r
+    snmp_inc_ipunknownprotos();\r
+    return ERR_OK;\r
+#endif /* IP_REASSEMBLY */\r
+  }\r
+\r
+#if IP_OPTIONS == 0 /* no support for IP options in the IP header? */\r
+  if (iphdrlen > IP_HLEN) {\r
+    LWIP_DEBUGF(IP_DEBUG | 2, ("IP packet dropped since there were IP options (while IP_OPTIONS == 0).\n"));\r
+    pbuf_free(p);\r
+    IP_STATS_INC(ip.opterr);\r
+    IP_STATS_INC(ip.drop);\r
+    snmp_inc_ipunknownprotos();\r
+    return ERR_OK;\r
+  }\r
+#endif /* IP_OPTIONS == 0 */\r
+\r
+  /* send to upper layers */\r
+  LWIP_DEBUGF(IP_DEBUG, ("ip_input: \n"));\r
+  ip_debug_print(p);\r
+  LWIP_DEBUGF(IP_DEBUG, ("ip_input: p->len %"U16_F" p->tot_len %"U16_F"\n", p->len, p->tot_len));\r
+\r
+#if LWIP_RAW\r
+  /* raw input did not eat the packet? */\r
+  if (raw_input(p, inp) == 0) {\r
+#endif /* LWIP_RAW */\r
+\r
+  switch (IPH_PROTO(iphdr)) {\r
+#if LWIP_UDP\r
+  case IP_PROTO_UDP:\r
+  case IP_PROTO_UDPLITE:\r
+    snmp_inc_ipindelivers();\r
+    udp_input(p, inp);\r
+    break;\r
+#endif /* LWIP_UDP */\r
+#if LWIP_TCP\r
+  case IP_PROTO_TCP:\r
+    snmp_inc_ipindelivers();\r
+    tcp_input(p, inp);\r
+    break;\r
+#endif /* LWIP_TCP */\r
+  case IP_PROTO_ICMP:\r
+    snmp_inc_ipindelivers();\r
+    icmp_input(p, inp);\r
+    break;\r
+  default:\r
+    /* send ICMP destination protocol unreachable unless is was a broadcast */\r
+    if (!ip_addr_isbroadcast(&(iphdr->dest), inp) &&\r
+        !ip_addr_ismulticast(&(iphdr->dest))) {\r
+      p->payload = iphdr;\r
+      icmp_dest_unreach(p, ICMP_DUR_PROTO);\r
+    }\r
+    pbuf_free(p);\r
+\r
+    LWIP_DEBUGF(IP_DEBUG | 2, ("Unsupported transport protocol %"U16_F"\n", IPH_PROTO(iphdr)));\r
+\r
+    IP_STATS_INC(ip.proterr);\r
+    IP_STATS_INC(ip.drop);\r
+    snmp_inc_ipunknownprotos();\r
+  }\r
+#if LWIP_RAW\r
+  } /* LWIP_RAW */\r
+#endif\r
+  return ERR_OK;\r
+}\r
+\r
+/**\r
+ * Sends an IP packet on a network interface. This function constructs\r
+ * the IP header and calculates the IP header checksum. If the source\r
+ * IP address is NULL, the IP address of the outgoing network\r
+ * interface is filled in as source address.\r
+ */\r
+\r
+err_t\r
+ip_output_if(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,\r
+             u8_t ttl, u8_t tos,\r
+             u8_t proto, struct netif *netif)\r
+{\r
+  struct ip_hdr *iphdr;\r
+  u16_t ip_id = 0;\r
+\r
+  snmp_inc_ipoutrequests();\r
+\r
+  if (dest != IP_HDRINCL) {\r
+    if (pbuf_header(p, IP_HLEN)) {\r
+      LWIP_DEBUGF(IP_DEBUG | 2, ("ip_output: not enough room for IP header in pbuf\n"));\r
+\r
+      IP_STATS_INC(ip.err);\r
+      snmp_inc_ipoutdiscards();\r
+      return ERR_BUF;\r
+    }\r
+\r
+    iphdr = p->payload;\r
+\r
+    IPH_TTL_SET(iphdr, ttl);\r
+    IPH_PROTO_SET(iphdr, proto);\r
+\r
+    ip_addr_set(&(iphdr->dest), dest);\r
+\r
+    IPH_VHLTOS_SET(iphdr, 4, IP_HLEN / 4, tos);\r
+    IPH_LEN_SET(iphdr, htons(p->tot_len));\r
+    IPH_OFFSET_SET(iphdr, htons(IP_DF));\r
+    IPH_ID_SET(iphdr, htons(ip_id));\r
+    ++ip_id;\r
+\r
+    if (ip_addr_isany(src)) {\r
+      ip_addr_set(&(iphdr->src), &(netif->ip_addr));\r
+    } else {\r
+      ip_addr_set(&(iphdr->src), src);\r
+    }\r
+\r
+    IPH_CHKSUM_SET(iphdr, 0);\r
+#if CHECKSUM_GEN_IP\r
+    IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN));\r
+#endif\r
+  } else {\r
+    iphdr = p->payload;\r
+    dest = &(iphdr->dest);\r
+  }\r
+\r
+#if IP_FRAG\r
+  /* don't fragment if interface has mtu set to 0 [loopif] */\r
+  if (netif->mtu && (p->tot_len > netif->mtu))\r
+    return ip_frag(p,netif,dest);\r
+#endif\r
+\r
+  IP_STATS_INC(ip.xmit);\r
+\r
+  LWIP_DEBUGF(IP_DEBUG, ("ip_output_if: %c%c%"U16_F"\n", netif->name[0], netif->name[1], netif->num));\r
+  ip_debug_print(p);\r
+\r
+  LWIP_DEBUGF(IP_DEBUG, ("netif->output()"));\r
+\r
+  return netif->output(netif, p, dest);\r
+}\r
+\r
+/**\r
+ * Simple interface to ip_output_if. It finds the outgoing network\r
+ * interface and calls upon ip_output_if to do the actual work.\r
+ */\r
+\r
+err_t\r
+ip_output(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,\r
+          u8_t ttl, u8_t tos, u8_t proto)\r
+{\r
+  struct netif *netif;\r
+\r
+  if ((netif = ip_route(dest)) == NULL) {\r
+    LWIP_DEBUGF(IP_DEBUG | 2, ("ip_output: No route to 0x%"X32_F"\n", dest->addr));\r
+\r
+    IP_STATS_INC(ip.rterr);\r
+    snmp_inc_ipoutdiscards();\r
+    return ERR_RTE;\r
+  }\r
+\r
+  return ip_output_if(p, src, dest, ttl, tos, proto, netif);\r
+}\r
+\r
+#if IP_DEBUG\r
+void\r
+ip_debug_print(struct pbuf *p)\r
+{\r
+  struct ip_hdr *iphdr = p->payload;\r
+  u8_t *payload;\r
+\r
+  payload = (u8_t *)iphdr + IP_HLEN;\r
+\r
+  LWIP_DEBUGF(IP_DEBUG, ("IP header:\n"));\r
+  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));\r
+  LWIP_DEBUGF(IP_DEBUG, ("|%2"S16_F" |%2"S16_F" |  0x%02"X16_F" |     %5"U16_F"     | (v, hl, tos, len)\n",\r
+                    IPH_V(iphdr),\r
+                    IPH_HL(iphdr),\r
+                    IPH_TOS(iphdr),\r
+                    ntohs(IPH_LEN(iphdr))));\r
+  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));\r
+  LWIP_DEBUGF(IP_DEBUG, ("|    %5"U16_F"      |%"U16_F"%"U16_F"%"U16_F"|    %4"U16_F"   | (id, flags, offset)\n",\r
+                    ntohs(IPH_ID(iphdr)),\r
+                    ntohs(IPH_OFFSET(iphdr)) >> 15 & 1,\r
+                    ntohs(IPH_OFFSET(iphdr)) >> 14 & 1,\r
+                    ntohs(IPH_OFFSET(iphdr)) >> 13 & 1,\r
+                    ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK));\r
+  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));\r
+  LWIP_DEBUGF(IP_DEBUG, ("|  %3"U16_F"  |  %3"U16_F"  |    0x%04"X16_F"     | (ttl, proto, chksum)\n",\r
+                    IPH_TTL(iphdr),\r
+                    IPH_PROTO(iphdr),\r
+                    ntohs(IPH_CHKSUM(iphdr))));\r
+  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));\r
+  LWIP_DEBUGF(IP_DEBUG, ("|  %3"U16_F"  |  %3"U16_F"  |  %3"U16_F"  |  %3"U16_F"  | (src)\n",\r
+                    ip4_addr1(&iphdr->src),\r
+                    ip4_addr2(&iphdr->src),\r
+                    ip4_addr3(&iphdr->src),\r
+                    ip4_addr4(&iphdr->src)));\r
+  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));\r
+  LWIP_DEBUGF(IP_DEBUG, ("|  %3"U16_F"  |  %3"U16_F"  |  %3"U16_F"  |  %3"U16_F"  | (dest)\n",\r
+                    ip4_addr1(&iphdr->dest),\r
+                    ip4_addr2(&iphdr->dest),\r
+                    ip4_addr3(&iphdr->dest),\r
+                    ip4_addr4(&iphdr->dest)));\r
+  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));\r
+}\r
+#endif /* IP_DEBUG */\r
+\r
+\r
+\r
+\r
+\r
+\r
index 2af526e9f3e62ad5f889d824aa82f6200445a647..cb465eef23dd3fb886d00aa07cea2717392d861f 100644 (file)
@@ -1,72 +1,72 @@
-/*
- * 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 <adam@sics.se>
- *
- */
-
-#include "lwip/ip_addr.h"
-#include "lwip/inet.h"
-#include "lwip/netif.h"
-
-/* used by IP_ADDR_ANY and IP_ADDR_BROADCAST in ip_addr.h */
-const struct ip_addr ip_addr_any = { 0x00000000UL };
-const struct ip_addr ip_addr_broadcast = { 0xffffffffUL };
-
-/* Determine if an address is a broadcast address on a network interface 
- * 
- * @param addr address to be checked
- * @param netif the network interface against which the address is checked
- * @return returns non-zero if the address is a broadcast address
- *
- */
-
-u8_t ip_addr_isbroadcast(struct ip_addr *addr, struct netif *netif)
-{
-  /* all ones (broadcast) or all zeroes (old skool broadcast) */
-  if ((addr->addr == ip_addr_broadcast.addr) ||
-      (addr->addr == ip_addr_any.addr))
-    return 1;
-  /* no broadcast support on this network interface? */
-  else if ((netif->flags & NETIF_FLAG_BROADCAST) == 0)
-    /* the given address cannot be a broadcast address
-     * nor can we check against any broadcast addresses */
-    return 0;
-  /* address matches network interface address exactly? => no broadcast */
-  else if (addr->addr == netif->ip_addr.addr)
-    return 0;
-  /*  on the same (sub) network... */
-  else if (ip_addr_netcmp(addr, &(netif->ip_addr), &(netif->netmask))
-         /* ...and host identifier bits are all ones? =>... */
-          && ((addr->addr & ~netif->netmask.addr) ==
-           (ip_addr_broadcast.addr & ~netif->netmask.addr)))
-    /* => network broadcast address */
-    return 1;
-  else
-    return 0;
-}
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+\r
+#include "lwip/ip_addr.h"\r
+#include "lwip/inet.h"\r
+#include "lwip/netif.h"\r
+\r
+/* used by IP_ADDR_ANY and IP_ADDR_BROADCAST in ip_addr.h */\r
+const struct ip_addr ip_addr_any = { 0x00000000UL };\r
+const struct ip_addr ip_addr_broadcast = { 0xffffffffUL };\r
+\r
+/* Determine if an address is a broadcast address on a network interface \r
+ * \r
+ * @param addr address to be checked\r
+ * @param netif the network interface against which the address is checked\r
+ * @return returns non-zero if the address is a broadcast address\r
+ *\r
+ */\r
+\r
+u8_t ip_addr_isbroadcast(struct ip_addr *addr, struct netif *netif)\r
+{\r
+  /* all ones (broadcast) or all zeroes (old skool broadcast) */\r
+  if ((addr->addr == ip_addr_broadcast.addr) ||\r
+      (addr->addr == ip_addr_any.addr))\r
+    return 1;\r
+  /* no broadcast support on this network interface? */\r
+  else if ((netif->flags & NETIF_FLAG_BROADCAST) == 0)\r
+    /* the given address cannot be a broadcast address\r
+     * nor can we check against any broadcast addresses */\r
+    return 0;\r
+  /* address matches network interface address exactly? => no broadcast */\r
+  else if (addr->addr == netif->ip_addr.addr)\r
+    return 0;\r
+  /*  on the same (sub) network... */\r
+  else if (ip_addr_netcmp(addr, &(netif->ip_addr), &(netif->netmask))\r
+         /* ...and host identifier bits are all ones? =>... */\r
+          && ((addr->addr & ~netif->netmask.addr) ==\r
+           (ip_addr_broadcast.addr & ~netif->netmask.addr)))\r
+    /* => network broadcast address */\r
+    return 1;\r
+  else\r
+    return 0;\r
+}\r
index 5a57138ce32299c32bc1d2926e99d705cb0c3828..a233674d1e1be003f7ae5d918cd7291b0ab1671c 100644 (file)
-/* @file
- * 
- * This is the IP packet segmentation and reassembly implementation.
- *
- */
-
-/*
- * 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: Jani Monoses <jani@iv.ro> 
- * original reassembly code by Adam Dunkels <adam@sics.se>
- * 
- */
-
-#include <string.h>
-
-#include "lwip/opt.h"
-/* #include "lwip/sys.h" */
-#include "lwip/ip.h"
-#include "lwip/ip_frag.h"
-#include "lwip/netif.h"
-#include "lwip/stats.h"
-
-
-/*
- * Copy len bytes from offset in pbuf to buffer 
- *
- * helper used by both ip_reass and ip_frag
- */
-static struct pbuf *
-copy_from_pbuf(struct pbuf *p, u16_t * offset,
-           u8_t * buffer, u16_t len)
-{
-  u16_t l;
-
-  p->payload = (u8_t *)p->payload + *offset;
-  p->len -= *offset;
-  while (len) {
-    l = len < p->len ? len : p->len;
-    memcpy(buffer, p->payload, l);
-    buffer += l;
-    len -= l;
-    if (len)
-      p = p->next;
-    else
-      *offset = l;
-  }
-  return p;
-}
-
-#define IP_REASS_BUFSIZE 5760
-#define IP_REASS_MAXAGE 30
-#define IP_REASS_TMO 1000
-
-static u8_t ip_reassbuf[IP_HLEN + IP_REASS_BUFSIZE];
-static u8_t ip_reassbitmap[IP_REASS_BUFSIZE / (8 * 8) + 1];
-static const u8_t bitmap_bits[8] = { 0xff, 0x7f, 0x3f, 0x1f,
-  0x0f, 0x07, 0x03, 0x01
-};
-static u16_t ip_reasslen;
-static u8_t ip_reassflags;
-#define IP_REASS_FLAG_LASTFRAG 0x01
-
-static u8_t ip_reasstmr;
-
-/**
- * Reassembly timer base function
- * for both NO_SYS == 0 and 1 (!).
- *
- * Should be called every 1000 msec.
- */
-void
-ip_reass_tmr(void)
-{
-  if (ip_reasstmr > 0) {
-    ip_reasstmr--;
-  }
-}
-
-/**
- * Reassembles incoming IP fragments into an IP datagram.
- *
- * @param p points to a pbuf chain of the fragment
- * @return NULL if reassembly is incomplete, ? otherwise
- */
-struct pbuf *
-ip_reass(struct pbuf *p)
-{
-  struct pbuf *q;
-  struct ip_hdr *fraghdr, *iphdr;
-  u16_t offset, len;
-  u16_t i;
-
-  IPFRAG_STATS_INC(ip_frag.recv);
-
-  iphdr = (struct ip_hdr *) ip_reassbuf;
-  fraghdr = (struct ip_hdr *) p->payload;
-  /* If ip_reasstmr is zero, no packet is present in the buffer, so we
-     write the IP header of the fragment into the reassembly
-     buffer. The timer is updated with the maximum age. */
-  if (ip_reasstmr == 0) {
-    LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_reass: new packet\n"));
-    memcpy(iphdr, fraghdr, IP_HLEN);
-    ip_reasstmr = IP_REASS_MAXAGE;
-    ip_reassflags = 0;
-    /* Clear the bitmap. */
-    memset(ip_reassbitmap, 0, sizeof(ip_reassbitmap));
-  }
-
-  /* Check if the incoming fragment matches the one currently present
-     in the reasembly buffer. If so, we proceed with copying the
-     fragment into the buffer. */
-  if (ip_addr_cmp(&iphdr->src, &fraghdr->src) &&
-      ip_addr_cmp(&iphdr->dest, &fraghdr->dest) &&
-      IPH_ID(iphdr) == IPH_ID(fraghdr)) {
-    LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_reass: matching previous fragment ID=%"X16_F"\n",
-      ntohs(IPH_ID(fraghdr))));
-    IPFRAG_STATS_INC(ip_frag.cachehit);
-    /* Find out the offset in the reassembly buffer where we should
-       copy the fragment. */
-    len = ntohs(IPH_LEN(fraghdr)) - IPH_HL(fraghdr) * 4;
-    offset = (ntohs(IPH_OFFSET(fraghdr)) & IP_OFFMASK) * 8;
-
-    /* If the offset or the offset + fragment length overflows the
-       reassembly buffer, we discard the entire packet. */
-    if (offset > IP_REASS_BUFSIZE || offset + len > IP_REASS_BUFSIZE) {
-      LWIP_DEBUGF(IP_REASS_DEBUG,
-       ("ip_reass: fragment outside of buffer (%"S16_F":%"S16_F"/%"S16_F").\n", offset,
-        offset + len, IP_REASS_BUFSIZE));
-      ip_reasstmr = 0;
-      goto nullreturn;
-    }
-
-    /* Copy the fragment into the reassembly buffer, at the right
-       offset. */
-    LWIP_DEBUGF(IP_REASS_DEBUG,
-     ("ip_reass: copying with offset %"S16_F" into %"S16_F":%"S16_F"\n", offset,
-      IP_HLEN + offset, IP_HLEN + offset + len));
-    i = IPH_HL(fraghdr) * 4;
-    copy_from_pbuf(p, &i, &ip_reassbuf[IP_HLEN + offset], len);
-
-    /* Update the bitmap. */
-    if (offset / (8 * 8) == (offset + len) / (8 * 8)) {
-      LWIP_DEBUGF(IP_REASS_DEBUG,
-       ("ip_reass: updating single byte in bitmap.\n"));
-      /* If the two endpoints are in the same byte, we only update that byte. */
-      LWIP_ASSERT("offset / (8 * 8) < sizeof(ip_reassbitmap)",
-                   offset / (8 * 8) < sizeof(ip_reassbitmap));
-      ip_reassbitmap[offset / (8 * 8)] |=
-        bitmap_bits[(offset / 8) & 7] &
-        ~bitmap_bits[((offset + len) / 8) & 7];
-    } else {
-      /* If the two endpoints are in different bytes, we update the
-         bytes in the endpoints and fill the stuff inbetween with
-         0xff. */
-      LWIP_ASSERT("offset / (8 * 8) < sizeof(ip_reassbitmap)",
-                   offset / (8 * 8) < sizeof(ip_reassbitmap));
-      ip_reassbitmap[offset / (8 * 8)] |= bitmap_bits[(offset / 8) & 7];
-      LWIP_DEBUGF(IP_REASS_DEBUG,
-       ("ip_reass: updating many bytes in bitmap (%"S16_F":%"S16_F").\n",
-        1 + offset / (8 * 8), (offset + len) / (8 * 8)));
-      for (i = 1 + offset / (8 * 8); i < (offset + len) / (8 * 8); ++i) {
-        ip_reassbitmap[i] = 0xff;
-      }
-      LWIP_ASSERT("(offset + len) / (8 * 8) < sizeof(ip_reassbitmap)",
-                   (offset + len) / (8 * 8) < sizeof(ip_reassbitmap));
-      ip_reassbitmap[(offset + len) / (8 * 8)] |=
-        ~bitmap_bits[((offset + len) / 8) & 7];
-    }
-
-    /* If this fragment has the More Fragments flag set to zero, we
-       know that this is the last fragment, so we can calculate the
-       size of the entire packet. We also set the
-       IP_REASS_FLAG_LASTFRAG flag to indicate that we have received
-       the final fragment. */
-
-    if ((ntohs(IPH_OFFSET(fraghdr)) & IP_MF) == 0) {
-      ip_reassflags |= IP_REASS_FLAG_LASTFRAG;
-      ip_reasslen = offset + len;
-      LWIP_DEBUGF(IP_REASS_DEBUG,
-       ("ip_reass: last fragment seen, total len %"S16_F"\n",
-        ip_reasslen));
-    }
-
-    /* Finally, we check if we have a full packet in the buffer. We do
-       this by checking if we have the last fragment and if all bits
-       in the bitmap are set. */
-    if (ip_reassflags & IP_REASS_FLAG_LASTFRAG) {
-      /* Check all bytes up to and including all but the last byte in
-         the bitmap. */
-      LWIP_ASSERT("ip_reasslen / (8 * 8) - 1 < sizeof(ip_reassbitmap)",
-                   ip_reasslen / (8 * 8) - 1 < sizeof(ip_reassbitmap));
-      for (i = 0; i < ip_reasslen / (8 * 8) - 1; ++i) {
-        if (ip_reassbitmap[i] != 0xff) {
-          LWIP_DEBUGF(IP_REASS_DEBUG,
-           ("ip_reass: last fragment seen, bitmap %"S16_F"/%"S16_F" failed (%"X16_F")\n",
-            i, ip_reasslen / (8 * 8) - 1, ip_reassbitmap[i]));
-          goto nullreturn;
-        }
-      }
-      /* Check the last byte in the bitmap. It should contain just the
-         right amount of bits. */
-      LWIP_ASSERT("ip_reasslen / (8 * 8) < sizeof(ip_reassbitmap)",
-                   ip_reasslen / (8 * 8) < sizeof(ip_reassbitmap));
-      if (ip_reassbitmap[ip_reasslen / (8 * 8)] !=
-        (u8_t) ~ bitmap_bits[ip_reasslen / 8 & 7]) {
-         LWIP_DEBUGF(IP_REASS_DEBUG,
-          ("ip_reass: last fragment seen, bitmap %"S16_F" didn't contain %"X16_F" (%"X16_F")\n",
-        ip_reasslen / (8 * 8), ~bitmap_bits[ip_reasslen / 8 & 7],
-        ip_reassbitmap[ip_reasslen / (8 * 8)]));
-        goto nullreturn;
-      }
-
-      /* Pretend to be a "normal" (i.e., not fragmented) IP packet
-         from now on. */
-      ip_reasslen += IP_HLEN;
-
-      IPH_LEN_SET(iphdr, htons(ip_reasslen));
-      IPH_OFFSET_SET(iphdr, 0);
-      IPH_CHKSUM_SET(iphdr, 0);
-      IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN));
-
-      /* If we have come this far, we have a full packet in the
-         buffer, so we allocate a pbuf and copy the packet into it. We
-         also reset the timer. */
-      ip_reasstmr = 0;
-      pbuf_free(p);
-      p = pbuf_alloc(PBUF_LINK, ip_reasslen, PBUF_POOL);
-      if (p != NULL) {
-        i = 0;
-        for (q = p; q != NULL; q = q->next) {
-          /* Copy enough bytes to fill this pbuf in the chain. The
-             available data in the pbuf is given by the q->len variable. */
-          LWIP_DEBUGF(IP_REASS_DEBUG,
-           ("ip_reass: memcpy from %p (%"S16_F") to %p, %"S16_F" bytes\n",
-            (void *)&ip_reassbuf[i], i, q->payload,
-            q->len > ip_reasslen - i ? ip_reasslen - i : q->len));
-          memcpy(q->payload, &ip_reassbuf[i],
-            q->len > ip_reasslen - i ? ip_reasslen - i : q->len);
-          i += q->len;
-        }
-        IPFRAG_STATS_INC(ip_frag.fw);
-      } else {
-        IPFRAG_STATS_INC(ip_frag.memerr);
-      }
-      LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_reass: p %p\n", (void*)p));
-      return p;
-    }
-  }
-
-nullreturn:
-  IPFRAG_STATS_INC(ip_frag.drop);
-  pbuf_free(p);
-  return NULL;
-}
-
-#define MAX_MTU 1500
-static u8_t buf[MEM_ALIGN_SIZE(MAX_MTU)];
-
-/**
- * Fragment an IP datagram if too large for the netif.
- *
- * Chop the datagram in MTU sized chunks and send them in order
- * by using a fixed size static memory buffer (PBUF_ROM)
- */
-err_t 
-ip_frag(struct pbuf *p, struct netif *netif, struct ip_addr *dest)
-{
-  struct pbuf *rambuf;
-  struct pbuf *header;
-  struct ip_hdr *iphdr;
-  u16_t nfb = 0;
-  u16_t left, cop;
-  u16_t mtu = netif->mtu;
-  u16_t ofo, omf;
-  u16_t last;
-  u16_t poff = IP_HLEN;
-  u16_t tmp;
-
-  /* Get a RAM based MTU sized pbuf */
-  rambuf = pbuf_alloc(PBUF_LINK, 0, PBUF_REF);
-  if (rambuf == NULL) {
-    return ERR_MEM;
-  }
-  rambuf->tot_len = rambuf->len = mtu;
-  rambuf->payload = MEM_ALIGN((void *)buf);
-
-  /* Copy the IP header in it */
-  iphdr = rambuf->payload;
-  memcpy(iphdr, p->payload, IP_HLEN);
-
-  /* Save original offset */
-  tmp = ntohs(IPH_OFFSET(iphdr));
-  ofo = tmp & IP_OFFMASK;
-  omf = tmp & IP_MF;
-
-  left = p->tot_len - IP_HLEN;
-
-  while (left) {
-    last = (left <= mtu - IP_HLEN);
-
-    /* Set new offset and MF flag */
-    ofo += nfb;
-    tmp = omf | (IP_OFFMASK & (ofo));
-    if (!last)
-      tmp = tmp | IP_MF;
-    IPH_OFFSET_SET(iphdr, htons(tmp));
-
-    /* Fill this fragment */
-    nfb = (mtu - IP_HLEN) / 8;
-    cop = last ? left : nfb * 8;
-
-    p = copy_from_pbuf(p, &poff, (u8_t *) iphdr + IP_HLEN, cop);
-
-    /* Correct header */
-    IPH_LEN_SET(iphdr, htons(cop + IP_HLEN));
-    IPH_CHKSUM_SET(iphdr, 0);
-    IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN));
-
-    if (last)
-      pbuf_realloc(rambuf, left + IP_HLEN);
-    /* This part is ugly: we alloc a RAM based pbuf for 
-     * the link level header for each chunk and then 
-     * free it.A PBUF_ROM style pbuf for which pbuf_header
-     * worked would make things simpler.
-     */
-    header = pbuf_alloc(PBUF_LINK, 0, PBUF_RAM);
-    if (header != NULL) {
-      pbuf_chain(header, rambuf);
-      netif->output(netif, header, dest);
-      IPFRAG_STATS_INC(ip_frag.xmit);
-      pbuf_free(header);
-    } else {
-      pbuf_free(rambuf);      
-      return ERR_MEM;    
-    }
-    left -= cop;
-  }
-  pbuf_free(rambuf);
-  return ERR_OK;
-}
+/* @file\r
+ * \r
+ * This is the IP packet segmentation and reassembly implementation.\r
+ *\r
+ */\r
+\r
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Jani Monoses <jani@iv.ro> \r
+ * original reassembly code by Adam Dunkels <adam@sics.se>\r
+ * \r
+ */\r
+\r
+#include <string.h>\r
+\r
+#include "lwip/opt.h"\r
+/* #include "lwip/sys.h" */\r
+#include "lwip/ip.h"\r
+#include "lwip/ip_frag.h"\r
+#include "lwip/netif.h"\r
+#include "lwip/stats.h"\r
+\r
+\r
+/*\r
+ * Copy len bytes from offset in pbuf to buffer \r
+ *\r
+ * helper used by both ip_reass and ip_frag\r
+ */\r
+static struct pbuf *\r
+copy_from_pbuf(struct pbuf *p, u16_t * offset,\r
+           u8_t * buffer, u16_t len)\r
+{\r
+  u16_t l;\r
+\r
+  p->payload = (u8_t *)p->payload + *offset;\r
+  p->len -= *offset;\r
+  while (len) {\r
+    l = len < p->len ? len : p->len;\r
+    memcpy(buffer, p->payload, l);\r
+    buffer += l;\r
+    len -= l;\r
+    if (len)\r
+      p = p->next;\r
+    else\r
+      *offset = l;\r
+  }\r
+  return p;\r
+}\r
+\r
+#define IP_REASS_BUFSIZE 5760\r
+#define IP_REASS_MAXAGE 30\r
+#define IP_REASS_TMO 1000\r
+\r
+static u8_t ip_reassbuf[IP_HLEN + IP_REASS_BUFSIZE];\r
+static u8_t ip_reassbitmap[IP_REASS_BUFSIZE / (8 * 8) + 1];\r
+static const u8_t bitmap_bits[8] = { 0xff, 0x7f, 0x3f, 0x1f,\r
+  0x0f, 0x07, 0x03, 0x01\r
+};\r
+static u16_t ip_reasslen;\r
+static u8_t ip_reassflags;\r
+#define IP_REASS_FLAG_LASTFRAG 0x01\r
+\r
+static u8_t ip_reasstmr;\r
+\r
+/**\r
+ * Reassembly timer base function\r
+ * for both NO_SYS == 0 and 1 (!).\r
+ *\r
+ * Should be called every 1000 msec.\r
+ */\r
+void\r
+ip_reass_tmr(void)\r
+{\r
+  if (ip_reasstmr > 0) {\r
+    ip_reasstmr--;\r
+  }\r
+}\r
+\r
+/**\r
+ * Reassembles incoming IP fragments into an IP datagram.\r
+ *\r
+ * @param p points to a pbuf chain of the fragment\r
+ * @return NULL if reassembly is incomplete, ? otherwise\r
+ */\r
+struct pbuf *\r
+ip_reass(struct pbuf *p)\r
+{\r
+  struct pbuf *q;\r
+  struct ip_hdr *fraghdr, *iphdr;\r
+  u16_t offset, len;\r
+  u16_t i;\r
+\r
+  IPFRAG_STATS_INC(ip_frag.recv);\r
+\r
+  iphdr = (struct ip_hdr *) ip_reassbuf;\r
+  fraghdr = (struct ip_hdr *) p->payload;\r
+  /* If ip_reasstmr is zero, no packet is present in the buffer, so we\r
+     write the IP header of the fragment into the reassembly\r
+     buffer. The timer is updated with the maximum age. */\r
+  if (ip_reasstmr == 0) {\r
+    LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_reass: new packet\n"));\r
+    memcpy(iphdr, fraghdr, IP_HLEN);\r
+    ip_reasstmr = IP_REASS_MAXAGE;\r
+    ip_reassflags = 0;\r
+    /* Clear the bitmap. */\r
+    memset(ip_reassbitmap, 0, sizeof(ip_reassbitmap));\r
+  }\r
+\r
+  /* Check if the incoming fragment matches the one currently present\r
+     in the reasembly buffer. If so, we proceed with copying the\r
+     fragment into the buffer. */\r
+  if (ip_addr_cmp(&iphdr->src, &fraghdr->src) &&\r
+      ip_addr_cmp(&iphdr->dest, &fraghdr->dest) &&\r
+      IPH_ID(iphdr) == IPH_ID(fraghdr)) {\r
+    LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_reass: matching previous fragment ID=%"X16_F"\n",\r
+      ntohs(IPH_ID(fraghdr))));\r
+    IPFRAG_STATS_INC(ip_frag.cachehit);\r
+    /* Find out the offset in the reassembly buffer where we should\r
+       copy the fragment. */\r
+    len = ntohs(IPH_LEN(fraghdr)) - IPH_HL(fraghdr) * 4;\r
+    offset = (ntohs(IPH_OFFSET(fraghdr)) & IP_OFFMASK) * 8;\r
+\r
+    /* If the offset or the offset + fragment length overflows the\r
+       reassembly buffer, we discard the entire packet. */\r
+    if (offset > IP_REASS_BUFSIZE || offset + len > IP_REASS_BUFSIZE) {\r
+      LWIP_DEBUGF(IP_REASS_DEBUG,\r
+       ("ip_reass: fragment outside of buffer (%"S16_F":%"S16_F"/%"S16_F").\n", offset,\r
+        offset + len, IP_REASS_BUFSIZE));\r
+      ip_reasstmr = 0;\r
+      goto nullreturn;\r
+    }\r
+\r
+    /* Copy the fragment into the reassembly buffer, at the right\r
+       offset. */\r
+    LWIP_DEBUGF(IP_REASS_DEBUG,\r
+     ("ip_reass: copying with offset %"S16_F" into %"S16_F":%"S16_F"\n", offset,\r
+      IP_HLEN + offset, IP_HLEN + offset + len));\r
+    i = IPH_HL(fraghdr) * 4;\r
+    copy_from_pbuf(p, &i, &ip_reassbuf[IP_HLEN + offset], len);\r
+\r
+    /* Update the bitmap. */\r
+    if (offset / (8 * 8) == (offset + len) / (8 * 8)) {\r
+      LWIP_DEBUGF(IP_REASS_DEBUG,\r
+       ("ip_reass: updating single byte in bitmap.\n"));\r
+      /* If the two endpoints are in the same byte, we only update that byte. */\r
+      LWIP_ASSERT("offset / (8 * 8) < sizeof(ip_reassbitmap)",\r
+                   offset / (8 * 8) < sizeof(ip_reassbitmap));\r
+      ip_reassbitmap[offset / (8 * 8)] |=\r
+        bitmap_bits[(offset / 8) & 7] &\r
+        ~bitmap_bits[((offset + len) / 8) & 7];\r
+    } else {\r
+      /* If the two endpoints are in different bytes, we update the\r
+         bytes in the endpoints and fill the stuff inbetween with\r
+         0xff. */\r
+      LWIP_ASSERT("offset / (8 * 8) < sizeof(ip_reassbitmap)",\r
+                   offset / (8 * 8) < sizeof(ip_reassbitmap));\r
+      ip_reassbitmap[offset / (8 * 8)] |= bitmap_bits[(offset / 8) & 7];\r
+      LWIP_DEBUGF(IP_REASS_DEBUG,\r
+       ("ip_reass: updating many bytes in bitmap (%"S16_F":%"S16_F").\n",\r
+        1 + offset / (8 * 8), (offset + len) / (8 * 8)));\r
+      for (i = 1 + offset / (8 * 8); i < (offset + len) / (8 * 8); ++i) {\r
+        ip_reassbitmap[i] = 0xff;\r
+      }\r
+      LWIP_ASSERT("(offset + len) / (8 * 8) < sizeof(ip_reassbitmap)",\r
+                   (offset + len) / (8 * 8) < sizeof(ip_reassbitmap));\r
+      ip_reassbitmap[(offset + len) / (8 * 8)] |=\r
+        ~bitmap_bits[((offset + len) / 8) & 7];\r
+    }\r
+\r
+    /* If this fragment has the More Fragments flag set to zero, we\r
+       know that this is the last fragment, so we can calculate the\r
+       size of the entire packet. We also set the\r
+       IP_REASS_FLAG_LASTFRAG flag to indicate that we have received\r
+       the final fragment. */\r
+\r
+    if ((ntohs(IPH_OFFSET(fraghdr)) & IP_MF) == 0) {\r
+      ip_reassflags |= IP_REASS_FLAG_LASTFRAG;\r
+      ip_reasslen = offset + len;\r
+      LWIP_DEBUGF(IP_REASS_DEBUG,\r
+       ("ip_reass: last fragment seen, total len %"S16_F"\n",\r
+        ip_reasslen));\r
+    }\r
+\r
+    /* Finally, we check if we have a full packet in the buffer. We do\r
+       this by checking if we have the last fragment and if all bits\r
+       in the bitmap are set. */\r
+    if (ip_reassflags & IP_REASS_FLAG_LASTFRAG) {\r
+      /* Check all bytes up to and including all but the last byte in\r
+         the bitmap. */\r
+      LWIP_ASSERT("ip_reasslen / (8 * 8) - 1 < sizeof(ip_reassbitmap)",\r
+                   ip_reasslen / (8 * 8) - 1 < sizeof(ip_reassbitmap));\r
+      for (i = 0; i < ip_reasslen / (8 * 8) - 1; ++i) {\r
+        if (ip_reassbitmap[i] != 0xff) {\r
+          LWIP_DEBUGF(IP_REASS_DEBUG,\r
+           ("ip_reass: last fragment seen, bitmap %"S16_F"/%"S16_F" failed (%"X16_F")\n",\r
+            i, ip_reasslen / (8 * 8) - 1, ip_reassbitmap[i]));\r
+          goto nullreturn;\r
+        }\r
+      }\r
+      /* Check the last byte in the bitmap. It should contain just the\r
+         right amount of bits. */\r
+      LWIP_ASSERT("ip_reasslen / (8 * 8) < sizeof(ip_reassbitmap)",\r
+                   ip_reasslen / (8 * 8) < sizeof(ip_reassbitmap));\r
+      if (ip_reassbitmap[ip_reasslen / (8 * 8)] !=\r
+        (u8_t) ~ bitmap_bits[ip_reasslen / 8 & 7]) {\r
+         LWIP_DEBUGF(IP_REASS_DEBUG,\r
+          ("ip_reass: last fragment seen, bitmap %"S16_F" didn't contain %"X16_F" (%"X16_F")\n",\r
+        ip_reasslen / (8 * 8), ~bitmap_bits[ip_reasslen / 8 & 7],\r
+        ip_reassbitmap[ip_reasslen / (8 * 8)]));\r
+        goto nullreturn;\r
+      }\r
+\r
+      /* Pretend to be a "normal" (i.e., not fragmented) IP packet\r
+         from now on. */\r
+      ip_reasslen += IP_HLEN;\r
+\r
+      IPH_LEN_SET(iphdr, htons(ip_reasslen));\r
+      IPH_OFFSET_SET(iphdr, 0);\r
+      IPH_CHKSUM_SET(iphdr, 0);\r
+      IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN));\r
+\r
+      /* If we have come this far, we have a full packet in the\r
+         buffer, so we allocate a pbuf and copy the packet into it. We\r
+         also reset the timer. */\r
+      ip_reasstmr = 0;\r
+      pbuf_free(p);\r
+      p = pbuf_alloc(PBUF_LINK, ip_reasslen, PBUF_POOL);\r
+      if (p != NULL) {\r
+        i = 0;\r
+        for (q = p; q != NULL; q = q->next) {\r
+          /* Copy enough bytes to fill this pbuf in the chain. The\r
+             available data in the pbuf is given by the q->len variable. */\r
+          LWIP_DEBUGF(IP_REASS_DEBUG,\r
+           ("ip_reass: memcpy from %p (%"S16_F") to %p, %"S16_F" bytes\n",\r
+            (void *)&ip_reassbuf[i], i, q->payload,\r
+            q->len > ip_reasslen - i ? ip_reasslen - i : q->len));\r
+          memcpy(q->payload, &ip_reassbuf[i],\r
+            q->len > ip_reasslen - i ? ip_reasslen - i : q->len);\r
+          i += q->len;\r
+        }\r
+        IPFRAG_STATS_INC(ip_frag.fw);\r
+      } else {\r
+        IPFRAG_STATS_INC(ip_frag.memerr);\r
+      }\r
+      LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_reass: p %p\n", (void*)p));\r
+      return p;\r
+    }\r
+  }\r
+\r
+nullreturn:\r
+  IPFRAG_STATS_INC(ip_frag.drop);\r
+  pbuf_free(p);\r
+  return NULL;\r
+}\r
+\r
+#define MAX_MTU 1500\r
+static u8_t buf[MEM_ALIGN_SIZE(MAX_MTU)];\r
+\r
+/**\r
+ * Fragment an IP datagram if too large for the netif.\r
+ *\r
+ * Chop the datagram in MTU sized chunks and send them in order\r
+ * by using a fixed size static memory buffer (PBUF_ROM)\r
+ */\r
+err_t \r
+ip_frag(struct pbuf *p, struct netif *netif, struct ip_addr *dest)\r
+{\r
+  struct pbuf *rambuf;\r
+  struct pbuf *header;\r
+  struct ip_hdr *iphdr;\r
+  u16_t nfb = 0;\r
+  u16_t left, cop;\r
+  u16_t mtu = netif->mtu;\r
+  u16_t ofo, omf;\r
+  u16_t last;\r
+  u16_t poff = IP_HLEN;\r
+  u16_t tmp;\r
+\r
+  /* Get a RAM based MTU sized pbuf */\r
+  rambuf = pbuf_alloc(PBUF_LINK, 0, PBUF_REF);\r
+  if (rambuf == NULL) {\r
+    return ERR_MEM;\r
+  }\r
+  rambuf->tot_len = rambuf->len = mtu;\r
+  rambuf->payload = MEM_ALIGN((void *)buf);\r
+\r
+  /* Copy the IP header in it */\r
+  iphdr = rambuf->payload;\r
+  memcpy(iphdr, p->payload, IP_HLEN);\r
+\r
+  /* Save original offset */\r
+  tmp = ntohs(IPH_OFFSET(iphdr));\r
+  ofo = tmp & IP_OFFMASK;\r
+  omf = tmp & IP_MF;\r
+\r
+  left = p->tot_len - IP_HLEN;\r
+\r
+  while (left) {\r
+    last = (left <= mtu - IP_HLEN);\r
+\r
+    /* Set new offset and MF flag */\r
+    ofo += nfb;\r
+    tmp = omf | (IP_OFFMASK & (ofo));\r
+    if (!last)\r
+      tmp = tmp | IP_MF;\r
+    IPH_OFFSET_SET(iphdr, htons(tmp));\r
+\r
+    /* Fill this fragment */\r
+    nfb = (mtu - IP_HLEN) / 8;\r
+    cop = last ? left : nfb * 8;\r
+\r
+    p = copy_from_pbuf(p, &poff, (u8_t *) iphdr + IP_HLEN, cop);\r
+\r
+    /* Correct header */\r
+    IPH_LEN_SET(iphdr, htons(cop + IP_HLEN));\r
+    IPH_CHKSUM_SET(iphdr, 0);\r
+    IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN));\r
+\r
+    if (last)\r
+      pbuf_realloc(rambuf, left + IP_HLEN);\r
+    /* This part is ugly: we alloc a RAM based pbuf for \r
+     * the link level header for each chunk and then \r
+     * free it.A PBUF_ROM style pbuf for which pbuf_header\r
+     * worked would make things simpler.\r
+     */\r
+    header = pbuf_alloc(PBUF_LINK, 0, PBUF_RAM);\r
+    if (header != NULL) {\r
+      pbuf_chain(header, rambuf);\r
+      netif->output(netif, header, dest);\r
+      IPFRAG_STATS_INC(ip_frag.xmit);\r
+      pbuf_free(header);\r
+    } else {\r
+      pbuf_free(rambuf);      \r
+      return ERR_MEM;    \r
+    }\r
+    left -= cop;\r
+  }\r
+  pbuf_free(rambuf);\r
+  return ERR_OK;\r
+}\r
index 10b6903c4c4829e5b6eb582884fadd10f44e2d8c..e22dfc3e86d6ae9f27469363344c56337de0bd8d 100644 (file)
-/*
- * 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 <adam@sics.se>
- *
- */
-
-/* Some ICMP messages should be passed to the transport protocols. This
-   is not implemented. */
-
-#include "lwip/opt.h"
-
-#include "lwip/icmp.h"
-#include "lwip/inet.h"
-#include "lwip/ip.h"
-#include "lwip/def.h"
-
-#include "lwip/stats.h"
-
-
-void
-icmp_input(struct pbuf *p, struct netif *inp)
-{
-  u8_t type;
-  struct icmp_echo_hdr *iecho;
-  struct ip_hdr *iphdr;
-  struct ip_addr tmpaddr;
-
-#ifdef ICMP_STATS
-  ++lwip_stats.icmp.recv;
-#endif /* ICMP_STATS */
-
-  /* TODO: check length before accessing payload! */
-
-  type = ((u8_t *)p->payload)[0];
-
-  switch (type) {
-  case ICMP6_ECHO:
-    LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ping\n"));
-
-    if (p->tot_len < sizeof(struct icmp_echo_hdr)) {
-      LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: bad ICMP echo received\n"));
-
-      pbuf_free(p);
-#ifdef ICMP_STATS
-      ++lwip_stats.icmp.lenerr;
-#endif /* ICMP_STATS */
-
-      return;
-    }
-    iecho = p->payload;
-    iphdr = (struct ip_hdr *)((u8_t *)p->payload - IP_HLEN);
-    if (inet_chksum_pbuf(p) != 0) {
-      LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: checksum failed for received ICMP echo (%"X16_F")\n", inet_chksum_pseudo(p, &(iphdr->src), &(iphdr->dest), IP_PROTO_ICMP, p->tot_len)));
-
-#ifdef ICMP_STATS
-      ++lwip_stats.icmp.chkerr;
-#endif /* ICMP_STATS */
-    /*      return;*/
-    }
-    LWIP_DEBUGF(ICMP_DEBUG, ("icmp: p->len %"S16_F" p->tot_len %"S16_F"\n", p->len, p->tot_len));
-    ip_addr_set(&tmpaddr, &(iphdr->src));
-    ip_addr_set(&(iphdr->src), &(iphdr->dest));
-    ip_addr_set(&(iphdr->dest), &tmpaddr);
-    iecho->type = ICMP6_ER;
-    /* adjust the checksum */
-    if (iecho->chksum >= htons(0xffff - (ICMP6_ECHO << 8))) {
-      iecho->chksum += htons(ICMP6_ECHO << 8) + 1;
-    } else {
-      iecho->chksum += htons(ICMP6_ECHO << 8);
-    }
-    LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: checksum failed for received ICMP echo (%"X16_F")\n", inet_chksum_pseudo(p, &(iphdr->src), &(iphdr->dest), IP_PROTO_ICMP, p->tot_len)));
-#ifdef ICMP_STATS
-    ++lwip_stats.icmp.xmit;
-#endif /* ICMP_STATS */
-
-    /*    LWIP_DEBUGF("icmp: p->len %"U16_F" p->tot_len %"U16_F"\n", p->len, p->tot_len);*/
-    ip_output_if (p, &(iphdr->src), IP_HDRINCL,
-     iphdr->hoplim, IP_PROTO_ICMP, inp);
-    break;
-  default:
-    LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ICMP type %"S16_F" not supported.\n", (s16_t)type));
-#ifdef ICMP_STATS
-    ++lwip_stats.icmp.proterr;
-    ++lwip_stats.icmp.drop;
-#endif /* ICMP_STATS */
-  }
-
-  pbuf_free(p);
-}
-
-void
-icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t)
-{
-  struct pbuf *q;
-  struct ip_hdr *iphdr;
-  struct icmp_dur_hdr *idur;
-
-  q = pbuf_alloc(PBUF_IP, 8 + IP_HLEN + 8, PBUF_RAM);
-  /* ICMP header + IP header + 8 bytes of data */
-
-  iphdr = p->payload;
-
-  idur = q->payload;
-  idur->type = (u8_t)ICMP6_DUR;
-  idur->icode = (u8_t)t;
-
-  memcpy((u8_t *)q->payload + 8, p->payload, IP_HLEN + 8);
-
-  /* calculate checksum */
-  idur->chksum = 0;
-  idur->chksum = inet_chksum(idur, q->len);
-#ifdef ICMP_STATS
-  ++lwip_stats.icmp.xmit;
-#endif /* ICMP_STATS */
-
-  ip_output(q, NULL,
-      (struct ip_addr *)&(iphdr->src), ICMP_TTL, IP_PROTO_ICMP);
-  pbuf_free(q);
-}
-
-void
-icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t)
-{
-  struct pbuf *q;
-  struct ip_hdr *iphdr;
-  struct icmp_te_hdr *tehdr;
-
-  LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded\n"));
-
-  q = pbuf_alloc(PBUF_IP, 8 + IP_HLEN + 8, PBUF_RAM);
-
-  iphdr = p->payload;
-
-  tehdr = q->payload;
-  tehdr->type = (u8_t)ICMP6_TE;
-  tehdr->icode = (u8_t)t;
-
-  /* copy fields from original packet */
-  memcpy((u8_t *)q->payload + 8, (u8_t *)p->payload, IP_HLEN + 8);
-
-  /* calculate checksum */
-  tehdr->chksum = 0;
-  tehdr->chksum = inet_chksum(tehdr, q->len);
-#ifdef ICMP_STATS
-  ++lwip_stats.icmp.xmit;
-#endif /* ICMP_STATS */
-  ip_output(q, NULL,
-      (struct ip_addr *)&(iphdr->src), ICMP_TTL, IP_PROTO_ICMP);
-  pbuf_free(q);
-}
-
-
-
-
-
-
-
-
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without modification,\r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED\r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT\r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY\r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ *\r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+\r
+/* Some ICMP messages should be passed to the transport protocols. This\r
+   is not implemented. */\r
+\r
+#include "lwip/opt.h"\r
+\r
+#include "lwip/icmp.h"\r
+#include "lwip/inet.h"\r
+#include "lwip/ip.h"\r
+#include "lwip/def.h"\r
+\r
+#include "lwip/stats.h"\r
+\r
+\r
+void\r
+icmp_input(struct pbuf *p, struct netif *inp)\r
+{\r
+  u8_t type;\r
+  struct icmp_echo_hdr *iecho;\r
+  struct ip_hdr *iphdr;\r
+  struct ip_addr tmpaddr;\r
+\r
+#ifdef ICMP_STATS\r
+  ++lwip_stats.icmp.recv;\r
+#endif /* ICMP_STATS */\r
+\r
+  /* TODO: check length before accessing payload! */\r
+\r
+  type = ((u8_t *)p->payload)[0];\r
+\r
+  switch (type) {\r
+  case ICMP6_ECHO:\r
+    LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ping\n"));\r
+\r
+    if (p->tot_len < sizeof(struct icmp_echo_hdr)) {\r
+      LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: bad ICMP echo received\n"));\r
+\r
+      pbuf_free(p);\r
+#ifdef ICMP_STATS\r
+      ++lwip_stats.icmp.lenerr;\r
+#endif /* ICMP_STATS */\r
+\r
+      return;\r
+    }\r
+    iecho = p->payload;\r
+    iphdr = (struct ip_hdr *)((u8_t *)p->payload - IP_HLEN);\r
+    if (inet_chksum_pbuf(p) != 0) {\r
+      LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: checksum failed for received ICMP echo (%"X16_F")\n", inet_chksum_pseudo(p, &(iphdr->src), &(iphdr->dest), IP_PROTO_ICMP, p->tot_len)));\r
+\r
+#ifdef ICMP_STATS\r
+      ++lwip_stats.icmp.chkerr;\r
+#endif /* ICMP_STATS */\r
+    /*      return;*/\r
+    }\r
+    LWIP_DEBUGF(ICMP_DEBUG, ("icmp: p->len %"S16_F" p->tot_len %"S16_F"\n", p->len, p->tot_len));\r
+    ip_addr_set(&tmpaddr, &(iphdr->src));\r
+    ip_addr_set(&(iphdr->src), &(iphdr->dest));\r
+    ip_addr_set(&(iphdr->dest), &tmpaddr);\r
+    iecho->type = ICMP6_ER;\r
+    /* adjust the checksum */\r
+    if (iecho->chksum >= htons(0xffff - (ICMP6_ECHO << 8))) {\r
+      iecho->chksum += htons(ICMP6_ECHO << 8) + 1;\r
+    } else {\r
+      iecho->chksum += htons(ICMP6_ECHO << 8);\r
+    }\r
+    LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: checksum failed for received ICMP echo (%"X16_F")\n", inet_chksum_pseudo(p, &(iphdr->src), &(iphdr->dest), IP_PROTO_ICMP, p->tot_len)));\r
+#ifdef ICMP_STATS\r
+    ++lwip_stats.icmp.xmit;\r
+#endif /* ICMP_STATS */\r
+\r
+    /*    LWIP_DEBUGF("icmp: p->len %"U16_F" p->tot_len %"U16_F"\n", p->len, p->tot_len);*/\r
+    ip_output_if (p, &(iphdr->src), IP_HDRINCL,\r
+     iphdr->hoplim, IP_PROTO_ICMP, inp);\r
+    break;\r
+  default:\r
+    LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ICMP type %"S16_F" not supported.\n", (s16_t)type));\r
+#ifdef ICMP_STATS\r
+    ++lwip_stats.icmp.proterr;\r
+    ++lwip_stats.icmp.drop;\r
+#endif /* ICMP_STATS */\r
+  }\r
+\r
+  pbuf_free(p);\r
+}\r
+\r
+void\r
+icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t)\r
+{\r
+  struct pbuf *q;\r
+  struct ip_hdr *iphdr;\r
+  struct icmp_dur_hdr *idur;\r
+\r
+  q = pbuf_alloc(PBUF_IP, 8 + IP_HLEN + 8, PBUF_RAM);\r
+  /* ICMP header + IP header + 8 bytes of data */\r
+\r
+  iphdr = p->payload;\r
+\r
+  idur = q->payload;\r
+  idur->type = (u8_t)ICMP6_DUR;\r
+  idur->icode = (u8_t)t;\r
+\r
+  memcpy((u8_t *)q->payload + 8, p->payload, IP_HLEN + 8);\r
+\r
+  /* calculate checksum */\r
+  idur->chksum = 0;\r
+  idur->chksum = inet_chksum(idur, q->len);\r
+#ifdef ICMP_STATS\r
+  ++lwip_stats.icmp.xmit;\r
+#endif /* ICMP_STATS */\r
+\r
+  ip_output(q, NULL,\r
+      (struct ip_addr *)&(iphdr->src), ICMP_TTL, IP_PROTO_ICMP);\r
+  pbuf_free(q);\r
+}\r
+\r
+void\r
+icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t)\r
+{\r
+  struct pbuf *q;\r
+  struct ip_hdr *iphdr;\r
+  struct icmp_te_hdr *tehdr;\r
+\r
+  LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded\n"));\r
+\r
+  q = pbuf_alloc(PBUF_IP, 8 + IP_HLEN + 8, PBUF_RAM);\r
+\r
+  iphdr = p->payload;\r
+\r
+  tehdr = q->payload;\r
+  tehdr->type = (u8_t)ICMP6_TE;\r
+  tehdr->icode = (u8_t)t;\r
+\r
+  /* copy fields from original packet */\r
+  memcpy((u8_t *)q->payload + 8, (u8_t *)p->payload, IP_HLEN + 8);\r
+\r
+  /* calculate checksum */\r
+  tehdr->chksum = 0;\r
+  tehdr->chksum = inet_chksum(tehdr, q->len);\r
+#ifdef ICMP_STATS\r
+  ++lwip_stats.icmp.xmit;\r
+#endif /* ICMP_STATS */\r
+  ip_output(q, NULL,\r
+      (struct ip_addr *)&(iphdr->src), ICMP_TTL, IP_PROTO_ICMP);\r
+  pbuf_free(q);\r
+}\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
index 03037c8183002a520911887b606b037c298c46b0..4d97f78c0b7f8f1466e50b6eac490484381bef00 100644 (file)
-/*
- * 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 <adam@sics.se>
- *
- */
-
-
-
-/* ip.c
- *
- * This is the code for the IP layer for IPv6.
- *
- */
-
-
-#include "lwip/opt.h"
-
-#include "lwip/def.h"
-#include "lwip/mem.h"
-#include "lwip/ip.h"
-#include "lwip/inet.h"
-#include "lwip/netif.h"
-#include "lwip/icmp.h"
-#include "lwip/udp.h"
-#include "lwip/tcp.h"
-
-#include "lwip/stats.h"
-
-#include "arch/perf.h"
-
-/* ip_init:
- *
- * Initializes the IP layer.
- */
-
-void
-ip_init(void)
-{
-}
-
-/* ip_route:
- *
- * Finds the appropriate network interface for a given IP address. It searches the
- * list of network interfaces linearly. A match is found if the masked IP address of
- * the network interface equals the masked IP address given to the function.
- */
-
-struct netif *
-ip_route(struct ip_addr *dest)
-{
-  struct netif *netif;
-
-  for(netif = netif_list; netif != NULL; netif = netif->next) {
-    if (ip_addr_netcmp(dest, &(netif->ip_addr), &(netif->netmask))) {
-      return netif;
-    }
-  }
-
-  return netif_default;
-}
-
-/* ip_forward:
- *
- * Forwards an IP packet. It finds an appropriate route for the packet, decrements
- * the TTL value of the packet, adjusts the checksum and outputs the packet on the
- * appropriate interface.
- */
-
-static void
-ip_forward(struct pbuf *p, struct ip_hdr *iphdr)
-{
-  struct netif *netif;
-
-  PERF_START;
-
-  if ((netif = ip_route((struct ip_addr *)&(iphdr->dest))) == NULL) {
-
-    LWIP_DEBUGF(IP_DEBUG, ("ip_input: no forwarding route found for "));
-#if IP_DEBUG
-    ip_addr_debug_print(IP_DEBUG, &(iphdr->dest));
-#endif /* IP_DEBUG */
-    LWIP_DEBUGF(IP_DEBUG, ("\n"));
-    pbuf_free(p);
-    return;
-  }
-  /* Decrement TTL and send ICMP if ttl == 0. */
-  if (--iphdr->hoplim == 0) {
-    /* Don't send ICMP messages in response to ICMP messages */
-    if (iphdr->nexthdr != IP_PROTO_ICMP) {
-      icmp_time_exceeded(p, ICMP_TE_TTL);
-    }
-    pbuf_free(p);
-    return;
-  }
-
-  /* Incremental update of the IP checksum. */
-  /*  if (iphdr->chksum >= htons(0xffff - 0x100)) {
-    iphdr->chksum += htons(0x100) + 1;
-  } else {
-    iphdr->chksum += htons(0x100);
-    }*/
-
-
-  LWIP_DEBUGF(IP_DEBUG, ("ip_forward: forwarding packet to "));
-#if IP_DEBUG
-  ip_addr_debug_print(IP_DEBUG, &(iphdr->dest));
-#endif /* IP_DEBUG */
-  LWIP_DEBUGF(IP_DEBUG, ("\n"));
-
-#ifdef IP_STATS
-  ++lwip_stats.ip.fw;
-  ++lwip_stats.ip.xmit;
-#endif /* IP_STATS */
-
-  PERF_STOP("ip_forward");
-
-  netif->output(netif, p, (struct ip_addr *)&(iphdr->dest));
-}
-
-/* ip_input:
- *
- * This function is called by the network interface device driver when an IP packet is
- * received. The function does the basic checks of the IP header such as packet size
- * being at least larger than the header size etc. If the packet was not destined for
- * us, the packet is forwarded (using ip_forward). The IP checksum is always checked.
- *
- * Finally, the packet is sent to the upper layer protocol input function.
- */
-
-void
-ip_input(struct pbuf *p, struct netif *inp) {
-  struct ip_hdr *iphdr;
-  struct netif *netif;
-
-
-  PERF_START;
-
-#if IP_DEBUG
-  ip_debug_print(p);
-#endif /* IP_DEBUG */
-
-
-#ifdef IP_STATS
-  ++lwip_stats.ip.recv;
-#endif /* IP_STATS */
-
-  /* identify the IP header */
-  iphdr = p->payload;
-
-
-  if (iphdr->v != 6) {
-    LWIP_DEBUGF(IP_DEBUG, ("IP packet dropped due to bad version number\n"));
-#if IP_DEBUG
-    ip_debug_print(p);
-#endif /* IP_DEBUG */
-    pbuf_free(p);
-#ifdef IP_STATS
-    ++lwip_stats.ip.err;
-    ++lwip_stats.ip.drop;
-#endif /* IP_STATS */
-    return;
-  }
-
-  /* is this packet for us? */
-  for(netif = netif_list; netif != NULL; netif = netif->next) {
-#if IP_DEBUG
-    LWIP_DEBUGF(IP_DEBUG, ("ip_input: iphdr->dest "));
-    ip_addr_debug_print(IP_DEBUG, &(iphdr->dest));
-    LWIP_DEBUGF(IP_DEBUG, ("netif->ip_addr "));
-    ip_addr_debug_print(IP_DEBUG, &(netif->ip_addr));
-    LWIP_DEBUGF(IP_DEBUG, ("\n"));
-#endif /* IP_DEBUG */
-    if (ip_addr_cmp(&(iphdr->dest), &(netif->ip_addr))) {
-      break;
-    }
-  }
-
-
-  if (netif == NULL) {
-    /* packet not for us, route or discard */
-#ifdef IP_FORWARD
-    ip_forward(p, iphdr);
-#endif
-    pbuf_free(p);
-    return;
-  }
-
-  pbuf_realloc(p, IP_HLEN + ntohs(iphdr->len));
-
-  /* send to upper layers */
-#if IP_DEBUG
-  /*  LWIP_DEBUGF("ip_input: \n");
-  ip_debug_print(p);
-  LWIP_DEBUGF("ip_input: p->len %"U16_F" p->tot_len %"U16_F"\n", p->len, p->tot_len);*/
-#endif /* IP_DEBUG */
-
-
-  pbuf_header(p, -IP_HLEN);
-
-  switch (iphdr->nexthdr) {
-  case IP_PROTO_UDP:
-    udp_input(p);
-    break;
-  case IP_PROTO_TCP:
-    tcp_input(p);
-    break;
-  case IP_PROTO_ICMP:
-    icmp_input(p, inp);
-    break;
-  default:
-    /* send ICMP destination protocol unreachable */
-    icmp_dest_unreach(p, ICMP_DUR_PROTO);
-    pbuf_free(p);
-    LWIP_DEBUGF(IP_DEBUG, ("Unsupported transport protocol %"U16_F"\n",
-          iphdr->nexthdr));
-
-#ifdef IP_STATS
-    ++lwip_stats.ip.proterr;
-    ++lwip_stats.ip.drop;
-#endif /* IP_STATS */
-
-  }
-  PERF_STOP("ip_input");
-}
-
-
-/* ip_output_if:
- *
- * Sends an IP packet on a network interface. This function constructs the IP header
- * and calculates the IP header checksum. If the source IP address is NULL,
- * the IP address of the outgoing network interface is filled in as source address.
- */
-
-err_t
-ip_output_if (struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
-       u8_t ttl,
-       u8_t proto, struct netif *netif)
-{
-  struct ip_hdr *iphdr;
-
-  PERF_START;
-
-  printf("len %"U16_F" tot_len %"U16_F"\n", p->len, p->tot_len);
-  if (pbuf_header(p, IP_HLEN)) {
-    LWIP_DEBUGF(IP_DEBUG, ("ip_output: not enough room for IP header in pbuf\n"));
-#ifdef IP_STATS
-    ++lwip_stats.ip.err;
-#endif /* IP_STATS */
-
-    return ERR_BUF;
-  }
-  printf("len %"U16_F" tot_len %"U16_F"\n", p->len, p->tot_len);
-
-  iphdr = p->payload;
-
-
-  if (dest != IP_HDRINCL) {
-    printf("!IP_HDRLINCL\n");
-    iphdr->hoplim = ttl;
-    iphdr->nexthdr = proto;
-    iphdr->len = htons(p->tot_len - IP_HLEN);
-    ip_addr_set(&(iphdr->dest), dest);
-
-    iphdr->v = 6;
-
-    if (ip_addr_isany(src)) {
-      ip_addr_set(&(iphdr->src), &(netif->ip_addr));
-    } else {
-      ip_addr_set(&(iphdr->src), src);
-    }
-
-  } else {
-    dest = &(iphdr->dest);
-  }
-
-#ifdef IP_STATS
-  ++lwip_stats.ip.xmit;
-#endif /* IP_STATS */
-
-  LWIP_DEBUGF(IP_DEBUG, ("ip_output_if: %c%c (len %"U16_F")\n", netif->name[0], netif->name[1], p->tot_len));
-#if IP_DEBUG
-  ip_debug_print(p);
-#endif /* IP_DEBUG */
-
-  PERF_STOP("ip_output_if");
-  return netif->output(netif, p, dest);
-}
-
-/* ip_output:
- *
- * Simple interface to ip_output_if. It finds the outgoing network interface and
- * calls upon ip_output_if to do the actual work.
- */
-
-err_t
-ip_output(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
-    u8_t ttl, u8_t proto)
-{
-  struct netif *netif;
-  if ((netif = ip_route(dest)) == NULL) {
-    LWIP_DEBUGF(IP_DEBUG, ("ip_output: No route to 0x%"X32_F"\n", dest->addr));
-#ifdef IP_STATS
-    ++lwip_stats.ip.rterr;
-#endif /* IP_STATS */
-    return ERR_RTE;
-  }
-
-  return ip_output_if (p, src, dest, ttl, proto, netif);
-}
-
-#if IP_DEBUG
-void
-ip_debug_print(struct pbuf *p)
-{
-  struct ip_hdr *iphdr = p->payload;
-  u8_t *payload;
-
-  payload = (u8_t *)iphdr + IP_HLEN;
-
-  LWIP_DEBUGF(IP_DEBUG, ("IP header:\n"));
-  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
-  LWIP_DEBUGF(IP_DEBUG, ("|%2"S16_F" |  %"X16_F"%"X16_F"  |      %"X16_F"%"X16_F"           | (v, traffic class, flow label)\n",
-        iphdr->v,
-        iphdr->tclass1, iphdr->tclass2,
-        iphdr->flow1, iphdr->flow2));
-  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
-  LWIP_DEBUGF(IP_DEBUG, ("|    %5"U16_F"      | %2"U16_F"  |  %2"U16_F"   | (len, nexthdr, hoplim)\n",
-        ntohs(iphdr->len),
-        iphdr->nexthdr,
-        iphdr->hoplim));
-  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
-  LWIP_DEBUGF(IP_DEBUG, ("|       %4"X32_F"      |       %4"X32_F"     | (src)\n",
-        ntohl(iphdr->src.addr[0]) >> 16 & 0xffff,
-        ntohl(iphdr->src.addr[0]) & 0xffff));
-  LWIP_DEBUGF(IP_DEBUG, ("|       %4"X32_F"      |       %4"X32_F"     | (src)\n",
-        ntohl(iphdr->src.addr[1]) >> 16 & 0xffff,
-        ntohl(iphdr->src.addr[1]) & 0xffff));
-  LWIP_DEBUGF(IP_DEBUG, ("|       %4"X32_F"      |       %4"X32_F"     | (src)\n",
-        ntohl(iphdr->src.addr[2]) >> 16 & 0xffff,
-        ntohl(iphdr->src.addr[2]) & 0xffff));
-  LWIP_DEBUGF(IP_DEBUG, ("|       %4"X32_F"      |       %4"X32_F"     | (src)\n",
-        ntohl(iphdr->src.addr[3]) >> 16 & 0xffff,
-        ntohl(iphdr->src.addr[3]) & 0xffff));
-  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
-  LWIP_DEBUGF(IP_DEBUG, ("|       %4"X32_F"      |       %4"X32_F"     | (dest)\n",
-        ntohl(iphdr->dest.addr[0]) >> 16 & 0xffff,
-        ntohl(iphdr->dest.addr[0]) & 0xffff));
-  LWIP_DEBUGF(IP_DEBUG, ("|       %4"X32_F"      |       %4"X32_F"     | (dest)\n",
-        ntohl(iphdr->dest.addr[1]) >> 16 & 0xffff,
-        ntohl(iphdr->dest.addr[1]) & 0xffff));
-  LWIP_DEBUGF(IP_DEBUG, ("|       %4"X32_F"      |       %4"X32_F"     | (dest)\n",
-        ntohl(iphdr->dest.addr[2]) >> 16 & 0xffff,
-        ntohl(iphdr->dest.addr[2]) & 0xffff));
-  LWIP_DEBUGF(IP_DEBUG, ("|       %4"X32_F"      |       %4"X32_F"     | (dest)\n",
-        ntohl(iphdr->dest.addr[3]) >> 16 & 0xffff,
-        ntohl(iphdr->dest.addr[3]) & 0xffff));
-  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
-}
-#endif /* IP_DEBUG */
-
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without modification,\r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED\r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT\r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY\r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ *\r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+\r
+\r
+\r
+/* ip.c\r
+ *\r
+ * This is the code for the IP layer for IPv6.\r
+ *\r
+ */\r
+\r
+\r
+#include "lwip/opt.h"\r
+\r
+#include "lwip/def.h"\r
+#include "lwip/mem.h"\r
+#include "lwip/ip.h"\r
+#include "lwip/inet.h"\r
+#include "lwip/netif.h"\r
+#include "lwip/icmp.h"\r
+#include "lwip/udp.h"\r
+#include "lwip/tcp.h"\r
+\r
+#include "lwip/stats.h"\r
+\r
+#include "arch/perf.h"\r
+\r
+/* ip_init:\r
+ *\r
+ * Initializes the IP layer.\r
+ */\r
+\r
+void\r
+ip_init(void)\r
+{\r
+}\r
+\r
+/* ip_route:\r
+ *\r
+ * Finds the appropriate network interface for a given IP address. It searches the\r
+ * list of network interfaces linearly. A match is found if the masked IP address of\r
+ * the network interface equals the masked IP address given to the function.\r
+ */\r
+\r
+struct netif *\r
+ip_route(struct ip_addr *dest)\r
+{\r
+  struct netif *netif;\r
+\r
+  for(netif = netif_list; netif != NULL; netif = netif->next) {\r
+    if (ip_addr_netcmp(dest, &(netif->ip_addr), &(netif->netmask))) {\r
+      return netif;\r
+    }\r
+  }\r
+\r
+  return netif_default;\r
+}\r
+\r
+/* ip_forward:\r
+ *\r
+ * Forwards an IP packet. It finds an appropriate route for the packet, decrements\r
+ * the TTL value of the packet, adjusts the checksum and outputs the packet on the\r
+ * appropriate interface.\r
+ */\r
+\r
+static void\r
+ip_forward(struct pbuf *p, struct ip_hdr *iphdr)\r
+{\r
+  struct netif *netif;\r
+\r
+  PERF_START;\r
+\r
+  if ((netif = ip_route((struct ip_addr *)&(iphdr->dest))) == NULL) {\r
+\r
+    LWIP_DEBUGF(IP_DEBUG, ("ip_input: no forwarding route found for "));\r
+#if IP_DEBUG\r
+    ip_addr_debug_print(IP_DEBUG, &(iphdr->dest));\r
+#endif /* IP_DEBUG */\r
+    LWIP_DEBUGF(IP_DEBUG, ("\n"));\r
+    pbuf_free(p);\r
+    return;\r
+  }\r
+  /* Decrement TTL and send ICMP if ttl == 0. */\r
+  if (--iphdr->hoplim == 0) {\r
+    /* Don't send ICMP messages in response to ICMP messages */\r
+    if (iphdr->nexthdr != IP_PROTO_ICMP) {\r
+      icmp_time_exceeded(p, ICMP_TE_TTL);\r
+    }\r
+    pbuf_free(p);\r
+    return;\r
+  }\r
+\r
+  /* Incremental update of the IP checksum. */\r
+  /*  if (iphdr->chksum >= htons(0xffff - 0x100)) {\r
+    iphdr->chksum += htons(0x100) + 1;\r
+  } else {\r
+    iphdr->chksum += htons(0x100);\r
+    }*/\r
+\r
+\r
+  LWIP_DEBUGF(IP_DEBUG, ("ip_forward: forwarding packet to "));\r
+#if IP_DEBUG\r
+  ip_addr_debug_print(IP_DEBUG, &(iphdr->dest));\r
+#endif /* IP_DEBUG */\r
+  LWIP_DEBUGF(IP_DEBUG, ("\n"));\r
+\r
+#ifdef IP_STATS\r
+  ++lwip_stats.ip.fw;\r
+  ++lwip_stats.ip.xmit;\r
+#endif /* IP_STATS */\r
+\r
+  PERF_STOP("ip_forward");\r
+\r
+  netif->output(netif, p, (struct ip_addr *)&(iphdr->dest));\r
+}\r
+\r
+/* ip_input:\r
+ *\r
+ * This function is called by the network interface device driver when an IP packet is\r
+ * received. The function does the basic checks of the IP header such as packet size\r
+ * being at least larger than the header size etc. If the packet was not destined for\r
+ * us, the packet is forwarded (using ip_forward). The IP checksum is always checked.\r
+ *\r
+ * Finally, the packet is sent to the upper layer protocol input function.\r
+ */\r
+\r
+void\r
+ip_input(struct pbuf *p, struct netif *inp) {\r
+  struct ip_hdr *iphdr;\r
+  struct netif *netif;\r
+\r
+\r
+  PERF_START;\r
+\r
+#if IP_DEBUG\r
+  ip_debug_print(p);\r
+#endif /* IP_DEBUG */\r
+\r
+\r
+#ifdef IP_STATS\r
+  ++lwip_stats.ip.recv;\r
+#endif /* IP_STATS */\r
+\r
+  /* identify the IP header */\r
+  iphdr = p->payload;\r
+\r
+\r
+  if (iphdr->v != 6) {\r
+    LWIP_DEBUGF(IP_DEBUG, ("IP packet dropped due to bad version number\n"));\r
+#if IP_DEBUG\r
+    ip_debug_print(p);\r
+#endif /* IP_DEBUG */\r
+    pbuf_free(p);\r
+#ifdef IP_STATS\r
+    ++lwip_stats.ip.err;\r
+    ++lwip_stats.ip.drop;\r
+#endif /* IP_STATS */\r
+    return;\r
+  }\r
+\r
+  /* is this packet for us? */\r
+  for(netif = netif_list; netif != NULL; netif = netif->next) {\r
+#if IP_DEBUG\r
+    LWIP_DEBUGF(IP_DEBUG, ("ip_input: iphdr->dest "));\r
+    ip_addr_debug_print(IP_DEBUG, &(iphdr->dest));\r
+    LWIP_DEBUGF(IP_DEBUG, ("netif->ip_addr "));\r
+    ip_addr_debug_print(IP_DEBUG, &(netif->ip_addr));\r
+    LWIP_DEBUGF(IP_DEBUG, ("\n"));\r
+#endif /* IP_DEBUG */\r
+    if (ip_addr_cmp(&(iphdr->dest), &(netif->ip_addr))) {\r
+      break;\r
+    }\r
+  }\r
+\r
+\r
+  if (netif == NULL) {\r
+    /* packet not for us, route or discard */\r
+#ifdef IP_FORWARD\r
+    ip_forward(p, iphdr);\r
+#endif\r
+    pbuf_free(p);\r
+    return;\r
+  }\r
+\r
+  pbuf_realloc(p, IP_HLEN + ntohs(iphdr->len));\r
+\r
+  /* send to upper layers */\r
+#if IP_DEBUG\r
+  /*  LWIP_DEBUGF("ip_input: \n");\r
+  ip_debug_print(p);\r
+  LWIP_DEBUGF("ip_input: p->len %"U16_F" p->tot_len %"U16_F"\n", p->len, p->tot_len);*/\r
+#endif /* IP_DEBUG */\r
+\r
+\r
+  pbuf_header(p, -IP_HLEN);\r
+\r
+  switch (iphdr->nexthdr) {\r
+  case IP_PROTO_UDP:\r
+    udp_input(p);\r
+    break;\r
+  case IP_PROTO_TCP:\r
+    tcp_input(p);\r
+    break;\r
+  case IP_PROTO_ICMP:\r
+    icmp_input(p, inp);\r
+    break;\r
+  default:\r
+    /* send ICMP destination protocol unreachable */\r
+    icmp_dest_unreach(p, ICMP_DUR_PROTO);\r
+    pbuf_free(p);\r
+    LWIP_DEBUGF(IP_DEBUG, ("Unsupported transport protocol %"U16_F"\n",\r
+          iphdr->nexthdr));\r
+\r
+#ifdef IP_STATS\r
+    ++lwip_stats.ip.proterr;\r
+    ++lwip_stats.ip.drop;\r
+#endif /* IP_STATS */\r
+\r
+  }\r
+  PERF_STOP("ip_input");\r
+}\r
+\r
+\r
+/* ip_output_if:\r
+ *\r
+ * Sends an IP packet on a network interface. This function constructs the IP header\r
+ * and calculates the IP header checksum. If the source IP address is NULL,\r
+ * the IP address of the outgoing network interface is filled in as source address.\r
+ */\r
+\r
+err_t\r
+ip_output_if (struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,\r
+       u8_t ttl,\r
+       u8_t proto, struct netif *netif)\r
+{\r
+  struct ip_hdr *iphdr;\r
+\r
+  PERF_START;\r
+\r
+  printf("len %"U16_F" tot_len %"U16_F"\n", p->len, p->tot_len);\r
+  if (pbuf_header(p, IP_HLEN)) {\r
+    LWIP_DEBUGF(IP_DEBUG, ("ip_output: not enough room for IP header in pbuf\n"));\r
+#ifdef IP_STATS\r
+    ++lwip_stats.ip.err;\r
+#endif /* IP_STATS */\r
+\r
+    return ERR_BUF;\r
+  }\r
+  printf("len %"U16_F" tot_len %"U16_F"\n", p->len, p->tot_len);\r
+\r
+  iphdr = p->payload;\r
+\r
+\r
+  if (dest != IP_HDRINCL) {\r
+    printf("!IP_HDRLINCL\n");\r
+    iphdr->hoplim = ttl;\r
+    iphdr->nexthdr = proto;\r
+    iphdr->len = htons(p->tot_len - IP_HLEN);\r
+    ip_addr_set(&(iphdr->dest), dest);\r
+\r
+    iphdr->v = 6;\r
+\r
+    if (ip_addr_isany(src)) {\r
+      ip_addr_set(&(iphdr->src), &(netif->ip_addr));\r
+    } else {\r
+      ip_addr_set(&(iphdr->src), src);\r
+    }\r
+\r
+  } else {\r
+    dest = &(iphdr->dest);\r
+  }\r
+\r
+#ifdef IP_STATS\r
+  ++lwip_stats.ip.xmit;\r
+#endif /* IP_STATS */\r
+\r
+  LWIP_DEBUGF(IP_DEBUG, ("ip_output_if: %c%c (len %"U16_F")\n", netif->name[0], netif->name[1], p->tot_len));\r
+#if IP_DEBUG\r
+  ip_debug_print(p);\r
+#endif /* IP_DEBUG */\r
+\r
+  PERF_STOP("ip_output_if");\r
+  return netif->output(netif, p, dest);\r
+}\r
+\r
+/* ip_output:\r
+ *\r
+ * Simple interface to ip_output_if. It finds the outgoing network interface and\r
+ * calls upon ip_output_if to do the actual work.\r
+ */\r
+\r
+err_t\r
+ip_output(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,\r
+    u8_t ttl, u8_t proto)\r
+{\r
+  struct netif *netif;\r
+  if ((netif = ip_route(dest)) == NULL) {\r
+    LWIP_DEBUGF(IP_DEBUG, ("ip_output: No route to 0x%"X32_F"\n", dest->addr));\r
+#ifdef IP_STATS\r
+    ++lwip_stats.ip.rterr;\r
+#endif /* IP_STATS */\r
+    return ERR_RTE;\r
+  }\r
+\r
+  return ip_output_if (p, src, dest, ttl, proto, netif);\r
+}\r
+\r
+#if IP_DEBUG\r
+void\r
+ip_debug_print(struct pbuf *p)\r
+{\r
+  struct ip_hdr *iphdr = p->payload;\r
+  u8_t *payload;\r
+\r
+  payload = (u8_t *)iphdr + IP_HLEN;\r
+\r
+  LWIP_DEBUGF(IP_DEBUG, ("IP header:\n"));\r
+  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));\r
+  LWIP_DEBUGF(IP_DEBUG, ("|%2"S16_F" |  %"X16_F"%"X16_F"  |      %"X16_F"%"X16_F"           | (v, traffic class, flow label)\n",\r
+        iphdr->v,\r
+        iphdr->tclass1, iphdr->tclass2,\r
+        iphdr->flow1, iphdr->flow2));\r
+  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));\r
+  LWIP_DEBUGF(IP_DEBUG, ("|    %5"U16_F"      | %2"U16_F"  |  %2"U16_F"   | (len, nexthdr, hoplim)\n",\r
+        ntohs(iphdr->len),\r
+        iphdr->nexthdr,\r
+        iphdr->hoplim));\r
+  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));\r
+  LWIP_DEBUGF(IP_DEBUG, ("|       %4"X32_F"      |       %4"X32_F"     | (src)\n",\r
+        ntohl(iphdr->src.addr[0]) >> 16 & 0xffff,\r
+        ntohl(iphdr->src.addr[0]) & 0xffff));\r
+  LWIP_DEBUGF(IP_DEBUG, ("|       %4"X32_F"      |       %4"X32_F"     | (src)\n",\r
+        ntohl(iphdr->src.addr[1]) >> 16 & 0xffff,\r
+        ntohl(iphdr->src.addr[1]) & 0xffff));\r
+  LWIP_DEBUGF(IP_DEBUG, ("|       %4"X32_F"      |       %4"X32_F"     | (src)\n",\r
+        ntohl(iphdr->src.addr[2]) >> 16 & 0xffff,\r
+        ntohl(iphdr->src.addr[2]) & 0xffff));\r
+  LWIP_DEBUGF(IP_DEBUG, ("|       %4"X32_F"      |       %4"X32_F"     | (src)\n",\r
+        ntohl(iphdr->src.addr[3]) >> 16 & 0xffff,\r
+        ntohl(iphdr->src.addr[3]) & 0xffff));\r
+  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));\r
+  LWIP_DEBUGF(IP_DEBUG, ("|       %4"X32_F"      |       %4"X32_F"     | (dest)\n",\r
+        ntohl(iphdr->dest.addr[0]) >> 16 & 0xffff,\r
+        ntohl(iphdr->dest.addr[0]) & 0xffff));\r
+  LWIP_DEBUGF(IP_DEBUG, ("|       %4"X32_F"      |       %4"X32_F"     | (dest)\n",\r
+        ntohl(iphdr->dest.addr[1]) >> 16 & 0xffff,\r
+        ntohl(iphdr->dest.addr[1]) & 0xffff));\r
+  LWIP_DEBUGF(IP_DEBUG, ("|       %4"X32_F"      |       %4"X32_F"     | (dest)\n",\r
+        ntohl(iphdr->dest.addr[2]) >> 16 & 0xffff,\r
+        ntohl(iphdr->dest.addr[2]) & 0xffff));\r
+  LWIP_DEBUGF(IP_DEBUG, ("|       %4"X32_F"      |       %4"X32_F"     | (dest)\n",\r
+        ntohl(iphdr->dest.addr[3]) >> 16 & 0xffff,\r
+        ntohl(iphdr->dest.addr[3]) & 0xffff));\r
+  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));\r
+}\r
+#endif /* IP_DEBUG */\r
+\r
index dcb507855b95a92f6077697393921edb8db99668..5341dedfd079c6ae09676c317d10e878d25a05cb 100644 (file)
@@ -1,90 +1,90 @@
-/*
- * 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 <adam@sics.se>
- *
- */
-
-#include "lwip/ip_addr.h"
-#include "lwip/inet.h"
-
-
-u8_t
-ip_addr_netcmp(struct ip_addr *addr1, struct ip_addr *addr2,
-                struct ip_addr *mask)
-{
-  return((addr1->addr[0] & mask->addr[0]) == (addr2->addr[0] & mask->addr[0]) &&
-         (addr1->addr[1] & mask->addr[1]) == (addr2->addr[1] & mask->addr[1]) &&
-         (addr1->addr[2] & mask->addr[2]) == (addr2->addr[2] & mask->addr[2]) &&
-         (addr1->addr[3] & mask->addr[3]) == (addr2->addr[3] & mask->addr[3]));
-        
-}
-
-u8_t
-ip_addr_cmp(struct ip_addr *addr1, struct ip_addr *addr2)
-{
-  return(addr1->addr[0] == addr2->addr[0] &&
-         addr1->addr[1] == addr2->addr[1] &&
-         addr1->addr[2] == addr2->addr[2] &&
-         addr1->addr[3] == addr2->addr[3]);
-}
-
-void
-ip_addr_set(struct ip_addr *dest, struct ip_addr *src)
-{
-  memcpy(dest, src, sizeof(struct ip_addr));
-  /*  dest->addr[0] = src->addr[0];
-  dest->addr[1] = src->addr[1];
-  dest->addr[2] = src->addr[2];
-  dest->addr[3] = src->addr[3];*/
-}
-
-u8_t
-ip_addr_isany(struct ip_addr *addr)
-{
-  if (addr == NULL) return 1;
-  return((addr->addr[0] | addr->addr[1] | addr->addr[2] | addr->addr[3]) == 0);
-}
-
-
-/*#if IP_DEBUG*/
-void
-ip_addr_debug_print(struct ip_addr *addr)
-{
-  printf("%"X32_F":%"X32_F":%"X32_F":%"X32_F":%"X32_F":%"X32_F":%"X32_F":%"X32_F",
-         ntohl(addr->addr[0]) >> 16 & 0xffff,
-         ntohl(addr->addr[0]) & 0xffff,
-         ntohl(addr->addr[1]) >> 16 & 0xffff,
-         ntohl(addr->addr[1]) & 0xffff,
-         ntohl(addr->addr[2]) >> 16 & 0xffff,
-         ntohl(addr->addr[2]) & 0xffff,
-         ntohl(addr->addr[3]) >> 16 & 0xffff,
-         ntohl(addr->addr[3]) & 0xffff);
-}
-/*#endif*/ /* IP_DEBUG */
-
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+\r
+#include "lwip/ip_addr.h"\r
+#include "lwip/inet.h"\r
+\r
+\r
+u8_t\r
+ip_addr_netcmp(struct ip_addr *addr1, struct ip_addr *addr2,\r
+                struct ip_addr *mask)\r
+{\r
+  return((addr1->addr[0] & mask->addr[0]) == (addr2->addr[0] & mask->addr[0]) &&\r
+         (addr1->addr[1] & mask->addr[1]) == (addr2->addr[1] & mask->addr[1]) &&\r
+         (addr1->addr[2] & mask->addr[2]) == (addr2->addr[2] & mask->addr[2]) &&\r
+         (addr1->addr[3] & mask->addr[3]) == (addr2->addr[3] & mask->addr[3]));\r
+        \r
+}\r
+\r
+u8_t\r
+ip_addr_cmp(struct ip_addr *addr1, struct ip_addr *addr2)\r
+{\r
+  return(addr1->addr[0] == addr2->addr[0] &&\r
+         addr1->addr[1] == addr2->addr[1] &&\r
+         addr1->addr[2] == addr2->addr[2] &&\r
+         addr1->addr[3] == addr2->addr[3]);\r
+}\r
+\r
+void\r
+ip_addr_set(struct ip_addr *dest, struct ip_addr *src)\r
+{\r
+  memcpy(dest, src, sizeof(struct ip_addr));\r
+  /*  dest->addr[0] = src->addr[0];\r
+  dest->addr[1] = src->addr[1];\r
+  dest->addr[2] = src->addr[2];\r
+  dest->addr[3] = src->addr[3];*/\r
+}\r
+\r
+u8_t\r
+ip_addr_isany(struct ip_addr *addr)\r
+{\r
+  if (addr == NULL) return 1;\r
+  return((addr->addr[0] | addr->addr[1] | addr->addr[2] | addr->addr[3]) == 0);\r
+}\r
+\r
+\r
+/*#if IP_DEBUG*/\r
+void\r
+ip_addr_debug_print(struct ip_addr *addr)\r
+{\r
+  printf("%"X32_F":%"X32_F":%"X32_F":%"X32_F":%"X32_F":%"X32_F":%"X32_F":%"X32_F",\r
+         ntohl(addr->addr[0]) >> 16 & 0xffff,\r
+         ntohl(addr->addr[0]) & 0xffff,\r
+         ntohl(addr->addr[1]) >> 16 & 0xffff,\r
+         ntohl(addr->addr[1]) & 0xffff,\r
+         ntohl(addr->addr[2]) >> 16 & 0xffff,\r
+         ntohl(addr->addr[2]) & 0xffff,\r
+         ntohl(addr->addr[3]) >> 16 & 0xffff,\r
+         ntohl(addr->addr[3]) & 0xffff);\r
+}\r
+/*#endif*/ /* IP_DEBUG */\r
+\r
index b38d8f15045e832654be52ab33b9c463cdb02b3c..d37c4c075bd8aae0e76b4e7748c5914454fe592c 100644 (file)
-/** @file
- *
- * Dynamic memory manager
- *
- */
-
-/* 
- * 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 <adam@sics.se>
- *
- */
-
-#include <string.h>
-
-#include "lwip/arch.h"
-#include "lwip/opt.h"
-#include "lwip/def.h"
-#include "lwip/mem.h"
-
-#include "lwip/sys.h"
-
-#include "lwip/stats.h"
-
-struct mem {
-  mem_size_t next, prev;
-#if MEM_ALIGNMENT == 1
-  u8_t used;
-#elif MEM_ALIGNMENT == 2
-  u16_t used;
-#elif MEM_ALIGNMENT == 4
-  u32_t used;
-#elif MEM_ALIGNMENT == 8
-  u64_t used;
-#else
-#error "unhandled MEM_ALIGNMENT size"
-#endif /* MEM_ALIGNMENT */
-}; 
-
-static struct mem *ram_end;
-static u8_t ram[MEM_SIZE + sizeof(struct mem) + MEM_ALIGNMENT];
-
-#define MIN_SIZE 12
-#if 0 /* this one does not align correctly for some, resulting in crashes */
-#define SIZEOF_STRUCT_MEM (unsigned int)MEM_ALIGN_SIZE(sizeof(struct mem))
-#else
-#define SIZEOF_STRUCT_MEM (sizeof(struct mem) + \
-                          (((sizeof(struct mem) % MEM_ALIGNMENT) == 0)? 0 : \
-                          (4 - (sizeof(struct mem) % MEM_ALIGNMENT))))
-#endif
-
-static struct mem *lfree;   /* pointer to the lowest free block */
-
-static sys_sem_t mem_sem;
-
-static void
-plug_holes(struct mem *mem)
-{
-  struct mem *nmem;
-  struct mem *pmem;
-
-  LWIP_ASSERT("plug_holes: mem >= ram", (u8_t *)mem >= ram);
-  LWIP_ASSERT("plug_holes: mem < ram_end", (u8_t *)mem < (u8_t *)ram_end);
-  LWIP_ASSERT("plug_holes: mem->used == 0", mem->used == 0);
-  
-  /* plug hole forward */
-  LWIP_ASSERT("plug_holes: mem->next <= MEM_SIZE", mem->next <= MEM_SIZE);
-  
-  nmem = (struct mem *)&ram[mem->next];
-  if (mem != nmem && nmem->used == 0 && (u8_t *)nmem != (u8_t *)ram_end) {
-    if (lfree == nmem) {
-      lfree = mem;
-    }
-    mem->next = nmem->next;
-    ((struct mem *)&ram[nmem->next])->prev = (u8_t *)mem - ram;
-  }
-
-  /* plug hole backward */
-  pmem = (struct mem *)&ram[mem->prev];
-  if (pmem != mem && pmem->used == 0) {
-    if (lfree == mem) {
-      lfree = pmem;
-    }
-    pmem->next = mem->next;
-    ((struct mem *)&ram[mem->next])->prev = (u8_t *)pmem - ram;
-  }
-
-}
-void
-mem_init(void)
-{
-  struct mem *mem;
-
-  memset(ram, 0, MEM_SIZE);
-  mem = (struct mem *)ram;
-  mem->next = MEM_SIZE;
-  mem->prev = 0;
-  mem->used = 0;
-  ram_end = (struct mem *)&ram[MEM_SIZE];
-  ram_end->used = 1;
-  ram_end->next = MEM_SIZE;
-  ram_end->prev = MEM_SIZE;
-
-  mem_sem = sys_sem_new(1);
-
-  lfree = (struct mem *)ram;
-
-#if MEM_STATS
-  lwip_stats.mem.avail = MEM_SIZE;
-#endif /* MEM_STATS */
-}
-void
-mem_free(void *rmem)
-{
-  struct mem *mem;
-
-  if (rmem == NULL) {
-    LWIP_DEBUGF(MEM_DEBUG | DBG_TRACE | 2, ("mem_free(p == NULL) was called.\n"));
-    return;
-  }
-  
-  sys_sem_wait(mem_sem);
-
-  LWIP_ASSERT("mem_free: legal memory", (u8_t *)rmem >= (u8_t *)ram &&
-    (u8_t *)rmem < (u8_t *)ram_end);
-  
-  if ((u8_t *)rmem < (u8_t *)ram || (u8_t *)rmem >= (u8_t *)ram_end) {
-    LWIP_DEBUGF(MEM_DEBUG | 3, ("mem_free: illegal memory\n"));
-#if MEM_STATS
-    ++lwip_stats.mem.err;
-#endif /* MEM_STATS */
-    sys_sem_signal(mem_sem);
-    return;
-  }
-  mem = (struct mem *)((u8_t *)rmem - SIZEOF_STRUCT_MEM);
-
-  LWIP_ASSERT("mem_free: mem->used", mem->used);
-  
-  mem->used = 0;
-
-  if (mem < lfree) {
-    lfree = mem;
-  }
-  
-#if MEM_STATS
-  lwip_stats.mem.used -= mem->next - ((u8_t *)mem - ram);
-  
-#endif /* MEM_STATS */
-  plug_holes(mem);
-  sys_sem_signal(mem_sem);
-}
-void *
-mem_reallocm(void *rmem, mem_size_t newsize)
-{
-  void *nmem;
-  nmem = mem_malloc(newsize);
-  if (nmem == NULL) {
-    return mem_realloc(rmem, newsize);
-  }
-  memcpy(nmem, rmem, newsize);
-  mem_free(rmem);
-  return nmem;
-}
-
-void *
-mem_realloc(void *rmem, mem_size_t newsize)
-{
-  mem_size_t size;
-  mem_size_t ptr, ptr2;
-  struct mem *mem, *mem2;
-
-  /* Expand the size of the allocated memory region so that we can
-     adjust for alignment. */
-  if ((newsize % MEM_ALIGNMENT) != 0) {
-   newsize += MEM_ALIGNMENT - ((newsize + SIZEOF_STRUCT_MEM) % MEM_ALIGNMENT);
-  }
-  
-  if (newsize > MEM_SIZE) {
-    return NULL;
-  }
-  
-  sys_sem_wait(mem_sem);
-  
-  LWIP_ASSERT("mem_realloc: legal memory", (u8_t *)rmem >= (u8_t *)ram &&
-   (u8_t *)rmem < (u8_t *)ram_end);
-  
-  if ((u8_t *)rmem < (u8_t *)ram || (u8_t *)rmem >= (u8_t *)ram_end) {
-    LWIP_DEBUGF(MEM_DEBUG | 3, ("mem_realloc: illegal memory\n"));
-    return rmem;
-  }
-  mem = (struct mem *)((u8_t *)rmem - SIZEOF_STRUCT_MEM);
-
-  ptr = (u8_t *)mem - ram;
-
-  size = mem->next - ptr - SIZEOF_STRUCT_MEM;
-#if MEM_STATS
-  lwip_stats.mem.used -= (size - newsize);
-#endif /* MEM_STATS */
-  
-  if (newsize + SIZEOF_STRUCT_MEM + MIN_SIZE < size) {
-    ptr2 = ptr + SIZEOF_STRUCT_MEM + newsize;
-    mem2 = (struct mem *)&ram[ptr2];
-    mem2->used = 0;
-    mem2->next = mem->next;
-    mem2->prev = ptr;
-    mem->next = ptr2;
-    if (mem2->next != MEM_SIZE) {
-      ((struct mem *)&ram[mem2->next])->prev = ptr2;
-    }
-
-    plug_holes(mem2);
-  }
-  sys_sem_signal(mem_sem);  
-  return rmem;
-}
-void *
-mem_malloc(mem_size_t size)
-{
-  mem_size_t ptr, ptr2;
-  struct mem *mem, *mem2;
-
-  if (size == 0) {
-    return NULL;
-  }
-
-  /* Expand the size of the allocated memory region so that we can
-     adjust for alignment. */
-  if ((size % MEM_ALIGNMENT) != 0) {
-    size += MEM_ALIGNMENT - ((size + SIZEOF_STRUCT_MEM) % MEM_ALIGNMENT);
-  }
-  
-  if (size > MEM_SIZE) {
-    return NULL;
-  }
-  
-  sys_sem_wait(mem_sem);
-
-  for (ptr = (u8_t *)lfree - ram; ptr < MEM_SIZE; ptr = ((struct mem *)&ram[ptr])->next) {
-    mem = (struct mem *)&ram[ptr];
-    if (!mem->used &&
-       mem->next - (ptr + SIZEOF_STRUCT_MEM) >= size + SIZEOF_STRUCT_MEM) {
-      ptr2 = ptr + SIZEOF_STRUCT_MEM + size;
-      mem2 = (struct mem *)&ram[ptr2];
-
-      mem2->prev = ptr;      
-      mem2->next = mem->next;
-      mem->next = ptr2;      
-      if (mem2->next != MEM_SIZE) {
-        ((struct mem *)&ram[mem2->next])->prev = ptr2;
-      }
-      
-      mem2->used = 0;      
-      mem->used = 1;
-#if MEM_STATS
-      lwip_stats.mem.used += (size + SIZEOF_STRUCT_MEM);
-      /*      if (lwip_stats.mem.max < lwip_stats.mem.used) {
-        lwip_stats.mem.max = lwip_stats.mem.used;
-  } */
-      if (lwip_stats.mem.max < ptr2) {
-        lwip_stats.mem.max = ptr2;
-      }      
-#endif /* MEM_STATS */
-
-      if (mem == lfree) {
-  /* Find next free block after mem */
-        while (lfree->used && lfree != ram_end) {
-    lfree = (struct mem *)&ram[lfree->next];
-        }
-        LWIP_ASSERT("mem_malloc: !lfree->used", !lfree->used);
-      }
-      sys_sem_signal(mem_sem);
-      LWIP_ASSERT("mem_malloc: allocated memory not above ram_end.",
-       (mem_ptr_t)mem + SIZEOF_STRUCT_MEM + size <= (mem_ptr_t)ram_end);
-      LWIP_ASSERT("mem_malloc: allocated memory properly aligned.",
-       (unsigned long)((u8_t *)mem + SIZEOF_STRUCT_MEM) % MEM_ALIGNMENT == 0);
-      return (u8_t *)mem + SIZEOF_STRUCT_MEM;
-    }    
-  }
-  LWIP_DEBUGF(MEM_DEBUG | 2, ("mem_malloc: could not allocate %"S16_F" bytes\n", (s16_t)size));
-#if MEM_STATS
-  ++lwip_stats.mem.err;
-#endif /* MEM_STATS */  
-  sys_sem_signal(mem_sem);
-  return NULL;
-}
+/** @file\r
+ *\r
+ * Dynamic memory manager\r
+ *\r
+ */\r
+\r
+/* \r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+\r
+#include <string.h>\r
+\r
+#include "lwip/arch.h"\r
+#include "lwip/opt.h"\r
+#include "lwip/def.h"\r
+#include "lwip/mem.h"\r
+\r
+#include "lwip/sys.h"\r
+\r
+#include "lwip/stats.h"\r
+\r
+struct mem {\r
+  mem_size_t next, prev;\r
+#if MEM_ALIGNMENT == 1\r
+  u8_t used;\r
+#elif MEM_ALIGNMENT == 2\r
+  u16_t used;\r
+#elif MEM_ALIGNMENT == 4\r
+  u32_t used;\r
+#elif MEM_ALIGNMENT == 8\r
+  u64_t used;\r
+#else\r
+#error "unhandled MEM_ALIGNMENT size"\r
+#endif /* MEM_ALIGNMENT */\r
+}; \r
+\r
+static struct mem *ram_end;\r
+static u8_t ram[MEM_SIZE + sizeof(struct mem) + MEM_ALIGNMENT];\r
+\r
+#define MIN_SIZE 12\r
+#if 0 /* this one does not align correctly for some, resulting in crashes */\r
+#define SIZEOF_STRUCT_MEM (unsigned int)MEM_ALIGN_SIZE(sizeof(struct mem))\r
+#else\r
+#define SIZEOF_STRUCT_MEM (sizeof(struct mem) + \\r
+                          (((sizeof(struct mem) % MEM_ALIGNMENT) == 0)? 0 : \\r
+                          (4 - (sizeof(struct mem) % MEM_ALIGNMENT))))\r
+#endif\r
+\r
+static struct mem *lfree;   /* pointer to the lowest free block */\r
+\r
+static sys_sem_t mem_sem;\r
+\r
+static void\r
+plug_holes(struct mem *mem)\r
+{\r
+  struct mem *nmem;\r
+  struct mem *pmem;\r
+\r
+  LWIP_ASSERT("plug_holes: mem >= ram", (u8_t *)mem >= ram);\r
+  LWIP_ASSERT("plug_holes: mem < ram_end", (u8_t *)mem < (u8_t *)ram_end);\r
+  LWIP_ASSERT("plug_holes: mem->used == 0", mem->used == 0);\r
+  \r
+  /* plug hole forward */\r
+  LWIP_ASSERT("plug_holes: mem->next <= MEM_SIZE", mem->next <= MEM_SIZE);\r
+  \r
+  nmem = (struct mem *)&ram[mem->next];\r
+  if (mem != nmem && nmem->used == 0 && (u8_t *)nmem != (u8_t *)ram_end) {\r
+    if (lfree == nmem) {\r
+      lfree = mem;\r
+    }\r
+    mem->next = nmem->next;\r
+    ((struct mem *)&ram[nmem->next])->prev = (u8_t *)mem - ram;\r
+  }\r
+\r
+  /* plug hole backward */\r
+  pmem = (struct mem *)&ram[mem->prev];\r
+  if (pmem != mem && pmem->used == 0) {\r
+    if (lfree == mem) {\r
+      lfree = pmem;\r
+    }\r
+    pmem->next = mem->next;\r
+    ((struct mem *)&ram[mem->next])->prev = (u8_t *)pmem - ram;\r
+  }\r
+\r
+}\r
+void\r
+mem_init(void)\r
+{\r
+  struct mem *mem;\r
+\r
+  memset(ram, 0, MEM_SIZE);\r
+  mem = (struct mem *)ram;\r
+  mem->next = MEM_SIZE;\r
+  mem->prev = 0;\r
+  mem->used = 0;\r
+  ram_end = (struct mem *)&ram[MEM_SIZE];\r
+  ram_end->used = 1;\r
+  ram_end->next = MEM_SIZE;\r
+  ram_end->prev = MEM_SIZE;\r
+\r
+  mem_sem = sys_sem_new(1);\r
+\r
+  lfree = (struct mem *)ram;\r
+\r
+#if MEM_STATS\r
+  lwip_stats.mem.avail = MEM_SIZE;\r
+#endif /* MEM_STATS */\r
+}\r
+void\r
+mem_free(void *rmem)\r
+{\r
+  struct mem *mem;\r
+\r
+  if (rmem == NULL) {\r
+    LWIP_DEBUGF(MEM_DEBUG | DBG_TRACE | 2, ("mem_free(p == NULL) was called.\n"));\r
+    return;\r
+  }\r
+  \r
+  sys_sem_wait(mem_sem);\r
+\r
+  LWIP_ASSERT("mem_free: legal memory", (u8_t *)rmem >= (u8_t *)ram &&\r
+    (u8_t *)rmem < (u8_t *)ram_end);\r
+  \r
+  if ((u8_t *)rmem < (u8_t *)ram || (u8_t *)rmem >= (u8_t *)ram_end) {\r
+    LWIP_DEBUGF(MEM_DEBUG | 3, ("mem_free: illegal memory\n"));\r
+#if MEM_STATS\r
+    ++lwip_stats.mem.err;\r
+#endif /* MEM_STATS */\r
+    sys_sem_signal(mem_sem);\r
+    return;\r
+  }\r
+  mem = (struct mem *)((u8_t *)rmem - SIZEOF_STRUCT_MEM);\r
+\r
+  LWIP_ASSERT("mem_free: mem->used", mem->used);\r
+  \r
+  mem->used = 0;\r
+\r
+  if (mem < lfree) {\r
+    lfree = mem;\r
+  }\r
+  \r
+#if MEM_STATS\r
+  lwip_stats.mem.used -= mem->next - ((u8_t *)mem - ram);\r
+  \r
+#endif /* MEM_STATS */\r
+  plug_holes(mem);\r
+  sys_sem_signal(mem_sem);\r
+}\r
+void *\r
+mem_reallocm(void *rmem, mem_size_t newsize)\r
+{\r
+  void *nmem;\r
+  nmem = mem_malloc(newsize);\r
+  if (nmem == NULL) {\r
+    return mem_realloc(rmem, newsize);\r
+  }\r
+  memcpy(nmem, rmem, newsize);\r
+  mem_free(rmem);\r
+  return nmem;\r
+}\r
+\r
+void *\r
+mem_realloc(void *rmem, mem_size_t newsize)\r
+{\r
+  mem_size_t size;\r
+  mem_size_t ptr, ptr2;\r
+  struct mem *mem, *mem2;\r
+\r
+  /* Expand the size of the allocated memory region so that we can\r
+     adjust for alignment. */\r
+  if ((newsize % MEM_ALIGNMENT) != 0) {\r
+   newsize += MEM_ALIGNMENT - ((newsize + SIZEOF_STRUCT_MEM) % MEM_ALIGNMENT);\r
+  }\r
+  \r
+  if (newsize > MEM_SIZE) {\r
+    return NULL;\r
+  }\r
+  \r
+  sys_sem_wait(mem_sem);\r
+  \r
+  LWIP_ASSERT("mem_realloc: legal memory", (u8_t *)rmem >= (u8_t *)ram &&\r
+   (u8_t *)rmem < (u8_t *)ram_end);\r
+  \r
+  if ((u8_t *)rmem < (u8_t *)ram || (u8_t *)rmem >= (u8_t *)ram_end) {\r
+    LWIP_DEBUGF(MEM_DEBUG | 3, ("mem_realloc: illegal memory\n"));\r
+    return rmem;\r
+  }\r
+  mem = (struct mem *)((u8_t *)rmem - SIZEOF_STRUCT_MEM);\r
+\r
+  ptr = (u8_t *)mem - ram;\r
+\r
+  size = mem->next - ptr - SIZEOF_STRUCT_MEM;\r
+#if MEM_STATS\r
+  lwip_stats.mem.used -= (size - newsize);\r
+#endif /* MEM_STATS */\r
+  \r
+  if (newsize + SIZEOF_STRUCT_MEM + MIN_SIZE < size) {\r
+    ptr2 = ptr + SIZEOF_STRUCT_MEM + newsize;\r
+    mem2 = (struct mem *)&ram[ptr2];\r
+    mem2->used = 0;\r
+    mem2->next = mem->next;\r
+    mem2->prev = ptr;\r
+    mem->next = ptr2;\r
+    if (mem2->next != MEM_SIZE) {\r
+      ((struct mem *)&ram[mem2->next])->prev = ptr2;\r
+    }\r
+\r
+    plug_holes(mem2);\r
+  }\r
+  sys_sem_signal(mem_sem);  \r
+  return rmem;\r
+}\r
+void *\r
+mem_malloc(mem_size_t size)\r
+{\r
+  mem_size_t ptr, ptr2;\r
+  struct mem *mem, *mem2;\r
+\r
+  if (size == 0) {\r
+    return NULL;\r
+  }\r
+\r
+  /* Expand the size of the allocated memory region so that we can\r
+     adjust for alignment. */\r
+  if ((size % MEM_ALIGNMENT) != 0) {\r
+    size += MEM_ALIGNMENT - ((size + SIZEOF_STRUCT_MEM) % MEM_ALIGNMENT);\r
+  }\r
+  \r
+  if (size > MEM_SIZE) {\r
+    return NULL;\r
+  }\r
+  \r
+  sys_sem_wait(mem_sem);\r
+\r
+  for (ptr = (u8_t *)lfree - ram; ptr < MEM_SIZE; ptr = ((struct mem *)&ram[ptr])->next) {\r
+    mem = (struct mem *)&ram[ptr];\r
+    if (!mem->used &&\r
+       mem->next - (ptr + SIZEOF_STRUCT_MEM) >= size + SIZEOF_STRUCT_MEM) {\r
+      ptr2 = ptr + SIZEOF_STRUCT_MEM + size;\r
+      mem2 = (struct mem *)&ram[ptr2];\r
+\r
+      mem2->prev = ptr;      \r
+      mem2->next = mem->next;\r
+      mem->next = ptr2;      \r
+      if (mem2->next != MEM_SIZE) {\r
+        ((struct mem *)&ram[mem2->next])->prev = ptr2;\r
+      }\r
+      \r
+      mem2->used = 0;      \r
+      mem->used = 1;\r
+#if MEM_STATS\r
+      lwip_stats.mem.used += (size + SIZEOF_STRUCT_MEM);\r
+      /*      if (lwip_stats.mem.max < lwip_stats.mem.used) {\r
+        lwip_stats.mem.max = lwip_stats.mem.used;\r
+  } */\r
+      if (lwip_stats.mem.max < ptr2) {\r
+        lwip_stats.mem.max = ptr2;\r
+      }      \r
+#endif /* MEM_STATS */\r
+\r
+      if (mem == lfree) {\r
+  /* Find next free block after mem */\r
+        while (lfree->used && lfree != ram_end) {\r
+    lfree = (struct mem *)&ram[lfree->next];\r
+        }\r
+        LWIP_ASSERT("mem_malloc: !lfree->used", !lfree->used);\r
+      }\r
+      sys_sem_signal(mem_sem);\r
+      LWIP_ASSERT("mem_malloc: allocated memory not above ram_end.",\r
+       (mem_ptr_t)mem + SIZEOF_STRUCT_MEM + size <= (mem_ptr_t)ram_end);\r
+      LWIP_ASSERT("mem_malloc: allocated memory properly aligned.",\r
+       (unsigned long)((u8_t *)mem + SIZEOF_STRUCT_MEM) % MEM_ALIGNMENT == 0);\r
+      return (u8_t *)mem + SIZEOF_STRUCT_MEM;\r
+    }    \r
+  }\r
+  LWIP_DEBUGF(MEM_DEBUG | 2, ("mem_malloc: could not allocate %"S16_F" bytes\n", (s16_t)size));\r
+#if MEM_STATS\r
+  ++lwip_stats.mem.err;\r
+#endif /* MEM_STATS */  \r
+  sys_sem_signal(mem_sem);\r
+  return NULL;\r
+}\r
index c0cfce29cf0a589414faa54f77b1907e4b0b2a65..f31b60190f346983b86eb475d08aa1c604cf510d 100644 (file)
-/*
- * 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 <adam@sics.se>
- *
- */
-
-#include "lwip/opt.h"
-
-#include "lwip/memp.h"
-
-#include "lwip/pbuf.h"
-#include "lwip/udp.h"
-#include "lwip/raw.h"
-#include "lwip/tcp.h"
-#include "lwip/api.h"
-#include "lwip/api_msg.h"
-#include "lwip/tcpip.h"
-
-#include "lwip/sys.h"
-#include "lwip/stats.h"
-
-struct memp {
-  struct memp *next;
-};
-
-
-
-static struct memp *memp_tab[MEMP_MAX];
-
-static const u16_t memp_sizes[MEMP_MAX] = {
-  sizeof(struct pbuf),
-  sizeof(struct raw_pcb),
-  sizeof(struct udp_pcb),
-  sizeof(struct tcp_pcb),
-  sizeof(struct tcp_pcb_listen),
-  sizeof(struct tcp_seg),
-  sizeof(struct netbuf),
-  sizeof(struct netconn),
-  sizeof(struct api_msg),
-  sizeof(struct tcpip_msg),
-  sizeof(struct sys_timeout)
-};
-
-static const u16_t memp_num[MEMP_MAX] = {
-  MEMP_NUM_PBUF,
-  MEMP_NUM_RAW_PCB,
-  MEMP_NUM_UDP_PCB,
-  MEMP_NUM_TCP_PCB,
-  MEMP_NUM_TCP_PCB_LISTEN,
-  MEMP_NUM_TCP_SEG,
-  MEMP_NUM_NETBUF,
-  MEMP_NUM_NETCONN,
-  MEMP_NUM_API_MSG,
-  MEMP_NUM_TCPIP_MSG,
-  MEMP_NUM_SYS_TIMEOUT
-};
-
-static u8_t memp_memory[(MEMP_NUM_PBUF *
-       MEM_ALIGN_SIZE(sizeof(struct pbuf) +
-          sizeof(struct memp)) +
-      MEMP_NUM_RAW_PCB *
-       MEM_ALIGN_SIZE(sizeof(struct raw_pcb) +
-          sizeof(struct memp)) +
-      MEMP_NUM_UDP_PCB *
-       MEM_ALIGN_SIZE(sizeof(struct udp_pcb) +
-          sizeof(struct memp)) +
-      MEMP_NUM_TCP_PCB *
-       MEM_ALIGN_SIZE(sizeof(struct tcp_pcb) +
-          sizeof(struct memp)) +
-      MEMP_NUM_TCP_PCB_LISTEN *
-       MEM_ALIGN_SIZE(sizeof(struct tcp_pcb_listen) +
-          sizeof(struct memp)) +
-      MEMP_NUM_TCP_SEG *
-       MEM_ALIGN_SIZE(sizeof(struct tcp_seg) +
-          sizeof(struct memp)) +
-      MEMP_NUM_NETBUF *
-       MEM_ALIGN_SIZE(sizeof(struct netbuf) +
-          sizeof(struct memp)) +
-      MEMP_NUM_NETCONN *
-       MEM_ALIGN_SIZE(sizeof(struct netconn) +
-          sizeof(struct memp)) +
-      MEMP_NUM_API_MSG *
-       MEM_ALIGN_SIZE(sizeof(struct api_msg) +
-          sizeof(struct memp)) +
-      MEMP_NUM_TCPIP_MSG *
-       MEM_ALIGN_SIZE(sizeof(struct tcpip_msg) +
-          sizeof(struct memp)) +
-      MEMP_NUM_SYS_TIMEOUT *
-       MEM_ALIGN_SIZE(sizeof(struct sys_timeout) +
-          sizeof(struct memp)))];
-
-
-#if !SYS_LIGHTWEIGHT_PROT
-static sys_sem_t mutex;
-#endif
-
-#if MEMP_SANITY_CHECK
-static int
-memp_sanity(void)
-{
-  s16_t i, c;
-  struct memp *m, *n;
-
-  for(i = 0; i < MEMP_MAX; i++) {
-    for(m = memp_tab[i]; m != NULL; m = m->next) {
-      c = 1;
-      for(n = memp_tab[i]; n != NULL; n = n->next) {
-         if (n == m) {
-          --c;
-        }
-        if (c < 0) return 0; /* LW was: abort(); */
-      }
-    }
-  }
-  return 1;
-}
-#endif /* MEMP_SANITY_CHECK*/
-
-void
-memp_init(void)
-{
-  struct memp *m, *memp;
-  u16_t i, j;
-  u16_t size;
-      
-#if MEMP_STATS
-  for(i = 0; i < MEMP_MAX; ++i) {
-    lwip_stats.memp[i].used = lwip_stats.memp[i].max =
-      lwip_stats.memp[i].err = 0;
-    lwip_stats.memp[i].avail = memp_num[i];
-  }
-#endif /* MEMP_STATS */
-
-  memp = (struct memp *)&memp_memory[0];
-  for(i = 0; i < MEMP_MAX; ++i) {
-    size = MEM_ALIGN_SIZE(memp_sizes[i] + sizeof(struct memp));
-    if (memp_num[i] > 0) {
-      memp_tab[i] = memp;
-      m = memp;
-      
-      for(j = 0; j < memp_num[i]; ++j) {
-  m->next = (struct memp *)MEM_ALIGN((u8_t *)m + size);
-  memp = m;
-  m = m->next;
-      }
-      memp->next = NULL;
-      memp = m;
-    } else {
-      memp_tab[i] = NULL;
-    }
-  }
-
-#if !SYS_LIGHTWEIGHT_PROT
-  mutex = sys_sem_new(1);
-#endif
-
-  
-}
-
-void *
-memp_malloc(memp_t type)
-{
-  struct memp *memp;
-  void *mem;
-#if SYS_LIGHTWEIGHT_PROT
-  SYS_ARCH_DECL_PROTECT(old_level);
-#endif
-  LWIP_ASSERT("memp_malloc: type < MEMP_MAX", type < MEMP_MAX);
-
-#if SYS_LIGHTWEIGHT_PROT
-  SYS_ARCH_PROTECT(old_level);
-#else /* SYS_LIGHTWEIGHT_PROT */  
-  sys_sem_wait(mutex);
-#endif /* SYS_LIGHTWEIGHT_PROT */  
-
-  memp = memp_tab[type];
-  
-  if (memp != NULL) {    
-    memp_tab[type] = memp->next;    
-    memp->next = NULL;
-#if MEMP_STATS
-    ++lwip_stats.memp[type].used;
-    if (lwip_stats.memp[type].used > lwip_stats.memp[type].max) {
-      lwip_stats.memp[type].max = lwip_stats.memp[type].used;
-    }
-#endif /* MEMP_STATS */
-#if SYS_LIGHTWEIGHT_PROT
-    SYS_ARCH_UNPROTECT(old_level);
-#else /* SYS_LIGHTWEIGHT_PROT */
-    sys_sem_signal(mutex);
-#endif /* SYS_LIGHTWEIGHT_PROT */  
-    LWIP_ASSERT("memp_malloc: memp properly aligned",
-     ((mem_ptr_t)MEM_ALIGN((u8_t *)memp + sizeof(struct memp)) % MEM_ALIGNMENT) == 0);
-
-    mem = MEM_ALIGN((u8_t *)memp + sizeof(struct memp));
-    return mem;
-  } else {
-    LWIP_DEBUGF(MEMP_DEBUG | 2, ("memp_malloc: out of memory in pool %"S16_F"\n", type));
-#if MEMP_STATS
-    ++lwip_stats.memp[type].err;
-#endif /* MEMP_STATS */
-#if SYS_LIGHTWEIGHT_PROT
-  SYS_ARCH_UNPROTECT(old_level);
-#else /* SYS_LIGHTWEIGHT_PROT */
-  sys_sem_signal(mutex);
-#endif /* SYS_LIGHTWEIGHT_PROT */  
-    return NULL;
-  }
-}
-
-void
-memp_free(memp_t type, void *mem)
-{
-  struct memp *memp;
-#if SYS_LIGHTWEIGHT_PROT
-  SYS_ARCH_DECL_PROTECT(old_level);
-#endif /* SYS_LIGHTWEIGHT_PROT */  
-
-  if (mem == NULL) {
-    return;
-  }
-  memp = (struct memp *)((u8_t *)mem - sizeof(struct memp));
-
-#if SYS_LIGHTWEIGHT_PROT
-    SYS_ARCH_PROTECT(old_level);
-#else /* SYS_LIGHTWEIGHT_PROT */  
-  sys_sem_wait(mutex);
-#endif /* SYS_LIGHTWEIGHT_PROT */  
-
-#if MEMP_STATS
-  lwip_stats.memp[type].used--; 
-#endif /* MEMP_STATS */
-  
-  memp->next = memp_tab[type]; 
-  memp_tab[type] = memp;
-
-#if MEMP_SANITY_CHECK
-  LWIP_ASSERT("memp sanity", memp_sanity());
-#endif  
-
-#if SYS_LIGHTWEIGHT_PROT
-  SYS_ARCH_UNPROTECT(old_level);
-#else /* SYS_LIGHTWEIGHT_PROT */
-  sys_sem_signal(mutex);
-#endif /* SYS_LIGHTWEIGHT_PROT */  
-}
-
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+\r
+#include "lwip/opt.h"\r
+\r
+#include "lwip/memp.h"\r
+\r
+#include "lwip/pbuf.h"\r
+#include "lwip/udp.h"\r
+#include "lwip/raw.h"\r
+#include "lwip/tcp.h"\r
+#include "lwip/api.h"\r
+#include "lwip/api_msg.h"\r
+#include "lwip/tcpip.h"\r
+\r
+#include "lwip/sys.h"\r
+#include "lwip/stats.h"\r
+\r
+struct memp {\r
+  struct memp *next;\r
+};\r
+\r
+\r
+\r
+static struct memp *memp_tab[MEMP_MAX];\r
+\r
+static const u16_t memp_sizes[MEMP_MAX] = {\r
+  sizeof(struct pbuf),\r
+  sizeof(struct raw_pcb),\r
+  sizeof(struct udp_pcb),\r
+  sizeof(struct tcp_pcb),\r
+  sizeof(struct tcp_pcb_listen),\r
+  sizeof(struct tcp_seg),\r
+  sizeof(struct netbuf),\r
+  sizeof(struct netconn),\r
+  sizeof(struct api_msg),\r
+  sizeof(struct tcpip_msg),\r
+  sizeof(struct sys_timeout)\r
+};\r
+\r
+static const u16_t memp_num[MEMP_MAX] = {\r
+  MEMP_NUM_PBUF,\r
+  MEMP_NUM_RAW_PCB,\r
+  MEMP_NUM_UDP_PCB,\r
+  MEMP_NUM_TCP_PCB,\r
+  MEMP_NUM_TCP_PCB_LISTEN,\r
+  MEMP_NUM_TCP_SEG,\r
+  MEMP_NUM_NETBUF,\r
+  MEMP_NUM_NETCONN,\r
+  MEMP_NUM_API_MSG,\r
+  MEMP_NUM_TCPIP_MSG,\r
+  MEMP_NUM_SYS_TIMEOUT\r
+};\r
+\r
+static u8_t memp_memory[(MEMP_NUM_PBUF *\r
+       MEM_ALIGN_SIZE(sizeof(struct pbuf) +\r
+          sizeof(struct memp)) +\r
+      MEMP_NUM_RAW_PCB *\r
+       MEM_ALIGN_SIZE(sizeof(struct raw_pcb) +\r
+          sizeof(struct memp)) +\r
+      MEMP_NUM_UDP_PCB *\r
+       MEM_ALIGN_SIZE(sizeof(struct udp_pcb) +\r
+          sizeof(struct memp)) +\r
+      MEMP_NUM_TCP_PCB *\r
+       MEM_ALIGN_SIZE(sizeof(struct tcp_pcb) +\r
+          sizeof(struct memp)) +\r
+      MEMP_NUM_TCP_PCB_LISTEN *\r
+       MEM_ALIGN_SIZE(sizeof(struct tcp_pcb_listen) +\r
+          sizeof(struct memp)) +\r
+      MEMP_NUM_TCP_SEG *\r
+       MEM_ALIGN_SIZE(sizeof(struct tcp_seg) +\r
+          sizeof(struct memp)) +\r
+      MEMP_NUM_NETBUF *\r
+       MEM_ALIGN_SIZE(sizeof(struct netbuf) +\r
+          sizeof(struct memp)) +\r
+      MEMP_NUM_NETCONN *\r
+       MEM_ALIGN_SIZE(sizeof(struct netconn) +\r
+          sizeof(struct memp)) +\r
+      MEMP_NUM_API_MSG *\r
+       MEM_ALIGN_SIZE(sizeof(struct api_msg) +\r
+          sizeof(struct memp)) +\r
+      MEMP_NUM_TCPIP_MSG *\r
+       MEM_ALIGN_SIZE(sizeof(struct tcpip_msg) +\r
+          sizeof(struct memp)) +\r
+      MEMP_NUM_SYS_TIMEOUT *\r
+       MEM_ALIGN_SIZE(sizeof(struct sys_timeout) +\r
+          sizeof(struct memp)))];\r
+\r
+\r
+#if !SYS_LIGHTWEIGHT_PROT\r
+static sys_sem_t mutex;\r
+#endif\r
+\r
+#if MEMP_SANITY_CHECK\r
+static int\r
+memp_sanity(void)\r
+{\r
+  s16_t i, c;\r
+  struct memp *m, *n;\r
+\r
+  for(i = 0; i < MEMP_MAX; i++) {\r
+    for(m = memp_tab[i]; m != NULL; m = m->next) {\r
+      c = 1;\r
+      for(n = memp_tab[i]; n != NULL; n = n->next) {\r
+         if (n == m) {\r
+          --c;\r
+        }\r
+        if (c < 0) return 0; /* LW was: abort(); */\r
+      }\r
+    }\r
+  }\r
+  return 1;\r
+}\r
+#endif /* MEMP_SANITY_CHECK*/\r
+\r
+void\r
+memp_init(void)\r
+{\r
+  struct memp *m, *memp;\r
+  u16_t i, j;\r
+  u16_t size;\r
+      \r
+#if MEMP_STATS\r
+  for(i = 0; i < MEMP_MAX; ++i) {\r
+    lwip_stats.memp[i].used = lwip_stats.memp[i].max =\r
+      lwip_stats.memp[i].err = 0;\r
+    lwip_stats.memp[i].avail = memp_num[i];\r
+  }\r
+#endif /* MEMP_STATS */\r
+\r
+  memp = (struct memp *)&memp_memory[0];\r
+  for(i = 0; i < MEMP_MAX; ++i) {\r
+    size = MEM_ALIGN_SIZE(memp_sizes[i] + sizeof(struct memp));\r
+    if (memp_num[i] > 0) {\r
+      memp_tab[i] = memp;\r
+      m = memp;\r
+      \r
+      for(j = 0; j < memp_num[i]; ++j) {\r
+  m->next = (struct memp *)MEM_ALIGN((u8_t *)m + size);\r
+  memp = m;\r
+  m = m->next;\r
+      }\r
+      memp->next = NULL;\r
+      memp = m;\r
+    } else {\r
+      memp_tab[i] = NULL;\r
+    }\r
+  }\r
+\r
+#if !SYS_LIGHTWEIGHT_PROT\r
+  mutex = sys_sem_new(1);\r
+#endif\r
+\r
+  \r
+}\r
+\r
+void *\r
+memp_malloc(memp_t type)\r
+{\r
+  struct memp *memp;\r
+  void *mem;\r
+#if SYS_LIGHTWEIGHT_PROT\r
+  SYS_ARCH_DECL_PROTECT(old_level);\r
+#endif\r
\r
+  LWIP_ASSERT("memp_malloc: type < MEMP_MAX", type < MEMP_MAX);\r
+\r
+#if SYS_LIGHTWEIGHT_PROT\r
+  SYS_ARCH_PROTECT(old_level);\r
+#else /* SYS_LIGHTWEIGHT_PROT */  \r
+  sys_sem_wait(mutex);\r
+#endif /* SYS_LIGHTWEIGHT_PROT */  \r
+\r
+  memp = memp_tab[type];\r
+  \r
+  if (memp != NULL) {    \r
+    memp_tab[type] = memp->next;    \r
+    memp->next = NULL;\r
+#if MEMP_STATS\r
+    ++lwip_stats.memp[type].used;\r
+    if (lwip_stats.memp[type].used > lwip_stats.memp[type].max) {\r
+      lwip_stats.memp[type].max = lwip_stats.memp[type].used;\r
+    }\r
+#endif /* MEMP_STATS */\r
+#if SYS_LIGHTWEIGHT_PROT\r
+    SYS_ARCH_UNPROTECT(old_level);\r
+#else /* SYS_LIGHTWEIGHT_PROT */\r
+    sys_sem_signal(mutex);\r
+#endif /* SYS_LIGHTWEIGHT_PROT */  \r
+    LWIP_ASSERT("memp_malloc: memp properly aligned",\r
+     ((mem_ptr_t)MEM_ALIGN((u8_t *)memp + sizeof(struct memp)) % MEM_ALIGNMENT) == 0);\r
+\r
+    mem = MEM_ALIGN((u8_t *)memp + sizeof(struct memp));\r
+    return mem;\r
+  } else {\r
+    LWIP_DEBUGF(MEMP_DEBUG | 2, ("memp_malloc: out of memory in pool %"S16_F"\n", type));\r
+#if MEMP_STATS\r
+    ++lwip_stats.memp[type].err;\r
+#endif /* MEMP_STATS */\r
+#if SYS_LIGHTWEIGHT_PROT\r
+  SYS_ARCH_UNPROTECT(old_level);\r
+#else /* SYS_LIGHTWEIGHT_PROT */\r
+  sys_sem_signal(mutex);\r
+#endif /* SYS_LIGHTWEIGHT_PROT */  \r
+    return NULL;\r
+  }\r
+}\r
+\r
+void\r
+memp_free(memp_t type, void *mem)\r
+{\r
+  struct memp *memp;\r
+#if SYS_LIGHTWEIGHT_PROT\r
+  SYS_ARCH_DECL_PROTECT(old_level);\r
+#endif /* SYS_LIGHTWEIGHT_PROT */  \r
+\r
+  if (mem == NULL) {\r
+    return;\r
+  }\r
+  memp = (struct memp *)((u8_t *)mem - sizeof(struct memp));\r
+\r
+#if SYS_LIGHTWEIGHT_PROT\r
+    SYS_ARCH_PROTECT(old_level);\r
+#else /* SYS_LIGHTWEIGHT_PROT */  \r
+  sys_sem_wait(mutex);\r
+#endif /* SYS_LIGHTWEIGHT_PROT */  \r
+\r
+#if MEMP_STATS\r
+  lwip_stats.memp[type].used--; \r
+#endif /* MEMP_STATS */\r
+  \r
+  memp->next = memp_tab[type]; \r
+  memp_tab[type] = memp;\r
+\r
+#if MEMP_SANITY_CHECK\r
+  LWIP_ASSERT("memp sanity", memp_sanity());\r
+#endif  \r
+\r
+#if SYS_LIGHTWEIGHT_PROT\r
+  SYS_ARCH_UNPROTECT(old_level);\r
+#else /* SYS_LIGHTWEIGHT_PROT */\r
+  sys_sem_signal(mutex);\r
+#endif /* SYS_LIGHTWEIGHT_PROT */  \r
+}\r
+\r
index 3525089b2f088619b105ef2024f658b25bb6dc8d..b831b7abadf94a042a7db24228ddf785abd5299e 100644 (file)
-/**
- * @file
- *
- * lwIP network interface 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 <adam@sics.se>
- *
- */
-
-#include "lwip/opt.h"
-
-#include "lwip/def.h"
-#include "lwip/ip_addr.h"
-#include "lwip/netif.h"
-#include "lwip/tcp.h"
-
-struct netif *netif_list = NULL;
-struct netif *netif_default = NULL;
-
-/**
- * Add a network interface to the list of lwIP netifs.
- *
- * @param netif a pre-allocated netif structure
- * @param ipaddr IP address for the new netif
- * @param netmask network mask for the new netif
- * @param gw default gateway IP address for the new netif
- * @param state opaque data passed to the new netif
- * @param init callback function that initializes the interface
- * @param input callback function that is called to pass
- * ingress packets up in the protocol layer stack.
- *
- * @return netif, or NULL if failed.
- */
-struct netif *
-netif_add(struct netif *netif, struct ip_addr *ipaddr, struct ip_addr *netmask,
-  struct ip_addr *gw,
-  void *state,
-  err_t (* init)(struct netif *netif),
-  err_t (* input)(struct pbuf *p, struct netif *netif))
-{
-  static s16_t netifnum = 0;
-  
-#if LWIP_DHCP
-  /* netif not under DHCP control by default */
-  netif->dhcp = NULL;
-#endif
-  /* remember netif specific state information data */
-  netif->state = state;
-  netif->num = netifnum++;
-  netif->input = input;
-
-  netif_set_addr(netif, ipaddr, netmask, gw);
-
-  /* call user specified initialization function for netif */
-  if (init(netif) != ERR_OK) {
-    return NULL;
-  }
-
-  /* add this netif to the list */
-  netif->next = netif_list;
-  netif_list = netif;
-  LWIP_DEBUGF(NETIF_DEBUG, ("netif: added interface %c%c IP addr ",
-    netif->name[0], netif->name[1]));
-  ip_addr_debug_print(NETIF_DEBUG, ipaddr);
-  LWIP_DEBUGF(NETIF_DEBUG, (" netmask "));
-  ip_addr_debug_print(NETIF_DEBUG, netmask);
-  LWIP_DEBUGF(NETIF_DEBUG, (" gw "));
-  ip_addr_debug_print(NETIF_DEBUG, gw);
-  LWIP_DEBUGF(NETIF_DEBUG, ("\n"));
-  return netif;
-}
-
-void
-netif_set_addr(struct netif *netif,struct ip_addr *ipaddr, struct ip_addr *netmask,
-    struct ip_addr *gw)
-{
-  netif_set_ipaddr(netif, ipaddr);
-  netif_set_netmask(netif, netmask);
-  netif_set_gw(netif, gw);
-}
-
-void netif_remove(struct netif * netif)
-{
-  if ( netif == NULL ) return;
-
-  /*  is it the first netif? */
-  if (netif_list == netif) {
-    netif_list = netif->next;
-  }
-  else {
-    /*  look for netif further down the list */
-    struct netif * tmpNetif;
-    for (tmpNetif = netif_list; tmpNetif != NULL; tmpNetif = tmpNetif->next) {
-      if (tmpNetif->next == netif) {
-        tmpNetif->next = netif->next;
-        break;
-        }
-    }
-    if (tmpNetif == NULL)
-      return; /*  we didn't find any netif today */
-  }
-  /* this netif is default? */
-  if (netif_default == netif)
-    /* reset default netif */
-    netif_default = NULL;
-  LWIP_DEBUGF( NETIF_DEBUG, ("netif_remove: removed netif\n") );
-}
-
-struct netif *
-netif_find(char *name)
-{
-  struct netif *netif;
-  u8_t num;
-
-  if (name == NULL) {
-    return NULL;
-  }
-
-  num = name[2] - '0';
-
-  for(netif = netif_list; netif != NULL; netif = netif->next) {
-    if (num == netif->num &&
-       name[0] == netif->name[0] &&
-       name[1] == netif->name[1]) {
-      LWIP_DEBUGF(NETIF_DEBUG, ("netif_find: found %c%c\n", name[0], name[1]));
-      return netif;
-    }
-  }
-  LWIP_DEBUGF(NETIF_DEBUG, ("netif_find: didn't find %c%c\n", name[0], name[1]));
-  return NULL;
-}
-
-void
-netif_set_ipaddr(struct netif *netif, struct ip_addr *ipaddr)
-{
-  /* TODO: Handling of obsolete pcbs */
-  /* See:  http://mail.gnu.org/archive/html/lwip-users/2003-03/msg00118.html */
-#if LWIP_TCP
-  struct tcp_pcb *pcb;
-  struct tcp_pcb_listen *lpcb;
-
-  /* address is actually being changed? */
-  if ((ip_addr_cmp(ipaddr, &(netif->ip_addr))) == 0)
-  {
-    /* extern struct tcp_pcb *tcp_active_pcbs; defined by tcp.h */
-    LWIP_DEBUGF(NETIF_DEBUG | 1, ("netif_set_ipaddr: netif address being changed\n"));
-    pcb = tcp_active_pcbs;
-    while (pcb != NULL) {
-      /* PCB bound to current local interface address? */
-      if (ip_addr_cmp(&(pcb->local_ip), &(netif->ip_addr))) {
-        /* this connection must be aborted */
-        struct tcp_pcb *next = pcb->next;
-        LWIP_DEBUGF(NETIF_DEBUG | 1, ("netif_set_ipaddr: aborting TCP pcb %p\n", (void *)pcb));
-        tcp_abort(pcb);
-        pcb = next;
-      } else {
-        pcb = pcb->next;
-      }
-    }
-    for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
-      /* PCB bound to current local interface address? */
-      if (ip_addr_cmp(&(lpcb->local_ip), &(netif->ip_addr))) {
-        /* The PCB is listening to the old ipaddr and
-         * is set to listen to the new one instead */
-        ip_addr_set(&(lpcb->local_ip), ipaddr);
-      }
-    }
-  }
-#endif
-  ip_addr_set(&(netif->ip_addr), ipaddr);
-#if 0 /* only allowed for Ethernet interfaces TODO: how can we check? */
-  /** For Ethernet network interfaces, we would like to send a
-   *  "gratuitous ARP"; this is an ARP packet sent by a node in order
-   *  to spontaneously cause other nodes to update an entry in their
-   *  ARP cache. From RFC 3220 "IP Mobility Support for IPv4" section 4.6.
-   */ 
-  etharp_query(netif, ipaddr, NULL);
-#endif
-  LWIP_DEBUGF(NETIF_DEBUG | DBG_TRACE | DBG_STATE | 3, ("netif: IP address of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
-    netif->name[0], netif->name[1],
-    ip4_addr1(&netif->ip_addr),
-    ip4_addr2(&netif->ip_addr),
-    ip4_addr3(&netif->ip_addr),
-    ip4_addr4(&netif->ip_addr)));
-}
-
-void
-netif_set_gw(struct netif *netif, struct ip_addr *gw)
-{
-  ip_addr_set(&(netif->gw), gw);
-  LWIP_DEBUGF(NETIF_DEBUG | DBG_TRACE | DBG_STATE | 3, ("netif: GW address of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
-    netif->name[0], netif->name[1],
-    ip4_addr1(&netif->gw),
-    ip4_addr2(&netif->gw),
-    ip4_addr3(&netif->gw),
-    ip4_addr4(&netif->gw)));
-}
-
-void
-netif_set_netmask(struct netif *netif, struct ip_addr *netmask)
-{
-  ip_addr_set(&(netif->netmask), netmask);
-  LWIP_DEBUGF(NETIF_DEBUG | DBG_TRACE | DBG_STATE | 3, ("netif: netmask of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
-    netif->name[0], netif->name[1],
-    ip4_addr1(&netif->netmask),
-    ip4_addr2(&netif->netmask),
-    ip4_addr3(&netif->netmask),
-    ip4_addr4(&netif->netmask)));
-}
-
-void
-netif_set_default(struct netif *netif)
-{
-  netif_default = netif;
-  LWIP_DEBUGF(NETIF_DEBUG, ("netif: setting default interface %c%c\n",
-           netif ? netif->name[0] : '\'', netif ? netif->name[1] : '\''));
-}
-
-/**
- * Bring an interface up, available for processing
- * traffic.
- * 
- * @note: Enabling DHCP on a down interface will make it come
- * up once configured.
- * 
- * @see dhcp_start()
- */ 
-void netif_set_up(struct netif *netif)
-{
-  netif->flags |= NETIF_FLAG_UP;
-}
-
-/**
- * Ask if an interface is up
- */ 
-u8_t netif_is_up(struct netif *netif)
-{
-  return (netif->flags & NETIF_FLAG_UP)?1:0;
-}
-
-/**
- * Bring an interface down, disabling any traffic processing.
- *
- * @note: Enabling DHCP on a down interface will make it come
- * up once configured.
- * 
- * @see dhcp_start()
- */ 
-void netif_set_down(struct netif *netif)
-{
-  netif->flags &= ~NETIF_FLAG_UP;
-}
-
-void
-netif_init(void)
-{
-  netif_list = netif_default = NULL;
-}
-
+/**\r
+ * @file\r
+ *\r
+ * lwIP network interface abstraction\r
+ */\r
+\r
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without modification,\r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED\r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT\r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY\r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ *\r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+\r
+#include "lwip/opt.h"\r
+\r
+#include "lwip/def.h"\r
+#include "lwip/ip_addr.h"\r
+#include "lwip/netif.h"\r
+#include "lwip/tcp.h"\r
+\r
+struct netif *netif_list = NULL;\r
+struct netif *netif_default = NULL;\r
+\r
+/**\r
+ * Add a network interface to the list of lwIP netifs.\r
+ *\r
+ * @param netif a pre-allocated netif structure\r
+ * @param ipaddr IP address for the new netif\r
+ * @param netmask network mask for the new netif\r
+ * @param gw default gateway IP address for the new netif\r
+ * @param state opaque data passed to the new netif\r
+ * @param init callback function that initializes the interface\r
+ * @param input callback function that is called to pass\r
+ * ingress packets up in the protocol layer stack.\r
+ *\r
+ * @return netif, or NULL if failed.\r
+ */\r
+struct netif *\r
+netif_add(struct netif *netif, struct ip_addr *ipaddr, struct ip_addr *netmask,\r
+  struct ip_addr *gw,\r
+  void *state,\r
+  err_t (* init)(struct netif *netif),\r
+  err_t (* input)(struct pbuf *p, struct netif *netif))\r
+{\r
+  static s16_t netifnum = 0;\r
+  \r
+#if LWIP_DHCP\r
+  /* netif not under DHCP control by default */\r
+  netif->dhcp = NULL;\r
+#endif\r
+  /* remember netif specific state information data */\r
+  netif->state = state;\r
+  netif->num = netifnum++;\r
+  netif->input = input;\r
+\r
+  netif_set_addr(netif, ipaddr, netmask, gw);\r
+\r
+  /* call user specified initialization function for netif */\r
+  if (init(netif) != ERR_OK) {\r
+    return NULL;\r
+  }\r
+\r
+  /* add this netif to the list */\r
+  netif->next = netif_list;\r
+  netif_list = netif;\r
+  LWIP_DEBUGF(NETIF_DEBUG, ("netif: added interface %c%c IP addr ",\r
+    netif->name[0], netif->name[1]));\r
+  ip_addr_debug_print(NETIF_DEBUG, ipaddr);\r
+  LWIP_DEBUGF(NETIF_DEBUG, (" netmask "));\r
+  ip_addr_debug_print(NETIF_DEBUG, netmask);\r
+  LWIP_DEBUGF(NETIF_DEBUG, (" gw "));\r
+  ip_addr_debug_print(NETIF_DEBUG, gw);\r
+  LWIP_DEBUGF(NETIF_DEBUG, ("\n"));\r
+  return netif;\r
+}\r
+\r
+void\r
+netif_set_addr(struct netif *netif,struct ip_addr *ipaddr, struct ip_addr *netmask,\r
+    struct ip_addr *gw)\r
+{\r
+  netif_set_ipaddr(netif, ipaddr);\r
+  netif_set_netmask(netif, netmask);\r
+  netif_set_gw(netif, gw);\r
+}\r
+\r
+void netif_remove(struct netif * netif)\r
+{\r
+  if ( netif == NULL ) return;\r
+\r
+  /*  is it the first netif? */\r
+  if (netif_list == netif) {\r
+    netif_list = netif->next;\r
+  }\r
+  else {\r
+    /*  look for netif further down the list */\r
+    struct netif * tmpNetif;\r
+    for (tmpNetif = netif_list; tmpNetif != NULL; tmpNetif = tmpNetif->next) {\r
+      if (tmpNetif->next == netif) {\r
+        tmpNetif->next = netif->next;\r
+        break;\r
+        }\r
+    }\r
+    if (tmpNetif == NULL)\r
+      return; /*  we didn't find any netif today */\r
+  }\r
+  /* this netif is default? */\r
+  if (netif_default == netif)\r
+    /* reset default netif */\r
+    netif_default = NULL;\r
+  LWIP_DEBUGF( NETIF_DEBUG, ("netif_remove: removed netif\n") );\r
+}\r
+\r
+struct netif *\r
+netif_find(char *name)\r
+{\r
+  struct netif *netif;\r
+  u8_t num;\r
+\r
+  if (name == NULL) {\r
+    return NULL;\r
+  }\r
+\r
+  num = name[2] - '0';\r
+\r
+  for(netif = netif_list; netif != NULL; netif = netif->next) {\r
+    if (num == netif->num &&\r
+       name[0] == netif->name[0] &&\r
+       name[1] == netif->name[1]) {\r
+      LWIP_DEBUGF(NETIF_DEBUG, ("netif_find: found %c%c\n", name[0], name[1]));\r
+      return netif;\r
+    }\r
+  }\r
+  LWIP_DEBUGF(NETIF_DEBUG, ("netif_find: didn't find %c%c\n", name[0], name[1]));\r
+  return NULL;\r
+}\r
+\r
+void\r
+netif_set_ipaddr(struct netif *netif, struct ip_addr *ipaddr)\r
+{\r
+  /* TODO: Handling of obsolete pcbs */\r
+  /* See:  http://mail.gnu.org/archive/html/lwip-users/2003-03/msg00118.html */\r
+#if LWIP_TCP\r
+  struct tcp_pcb *pcb;\r
+  struct tcp_pcb_listen *lpcb;\r
+\r
+  /* address is actually being changed? */\r
+  if ((ip_addr_cmp(ipaddr, &(netif->ip_addr))) == 0)\r
+  {\r
+    /* extern struct tcp_pcb *tcp_active_pcbs; defined by tcp.h */\r
+    LWIP_DEBUGF(NETIF_DEBUG | 1, ("netif_set_ipaddr: netif address being changed\n"));\r
+    pcb = tcp_active_pcbs;\r
+    while (pcb != NULL) {\r
+      /* PCB bound to current local interface address? */\r
+      if (ip_addr_cmp(&(pcb->local_ip), &(netif->ip_addr))) {\r
+        /* this connection must be aborted */\r
+        struct tcp_pcb *next = pcb->next;\r
+        LWIP_DEBUGF(NETIF_DEBUG | 1, ("netif_set_ipaddr: aborting TCP pcb %p\n", (void *)pcb));\r
+        tcp_abort(pcb);\r
+        pcb = next;\r
+      } else {\r
+        pcb = pcb->next;\r
+      }\r
+    }\r
+    for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {\r
+      /* PCB bound to current local interface address? */\r
+      if (ip_addr_cmp(&(lpcb->local_ip), &(netif->ip_addr))) {\r
+        /* The PCB is listening to the old ipaddr and\r
+         * is set to listen to the new one instead */\r
+        ip_addr_set(&(lpcb->local_ip), ipaddr);\r
+      }\r
+    }\r
+  }\r
+#endif\r
+  ip_addr_set(&(netif->ip_addr), ipaddr);\r
+#if 0 /* only allowed for Ethernet interfaces TODO: how can we check? */\r
+  /** For Ethernet network interfaces, we would like to send a\r
+   *  "gratuitous ARP"; this is an ARP packet sent by a node in order\r
+   *  to spontaneously cause other nodes to update an entry in their\r
+   *  ARP cache. From RFC 3220 "IP Mobility Support for IPv4" section 4.6.\r
+   */ \r
+  etharp_query(netif, ipaddr, NULL);\r
+#endif\r
+  LWIP_DEBUGF(NETIF_DEBUG | DBG_TRACE | DBG_STATE | 3, ("netif: IP address of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",\r
+    netif->name[0], netif->name[1],\r
+    ip4_addr1(&netif->ip_addr),\r
+    ip4_addr2(&netif->ip_addr),\r
+    ip4_addr3(&netif->ip_addr),\r
+    ip4_addr4(&netif->ip_addr)));\r
+}\r
+\r
+void\r
+netif_set_gw(struct netif *netif, struct ip_addr *gw)\r
+{\r
+  ip_addr_set(&(netif->gw), gw);\r
+  LWIP_DEBUGF(NETIF_DEBUG | DBG_TRACE | DBG_STATE | 3, ("netif: GW address of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",\r
+    netif->name[0], netif->name[1],\r
+    ip4_addr1(&netif->gw),\r
+    ip4_addr2(&netif->gw),\r
+    ip4_addr3(&netif->gw),\r
+    ip4_addr4(&netif->gw)));\r
+}\r
+\r
+void\r
+netif_set_netmask(struct netif *netif, struct ip_addr *netmask)\r
+{\r
+  ip_addr_set(&(netif->netmask), netmask);\r
+  LWIP_DEBUGF(NETIF_DEBUG | DBG_TRACE | DBG_STATE | 3, ("netif: netmask of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",\r
+    netif->name[0], netif->name[1],\r
+    ip4_addr1(&netif->netmask),\r
+    ip4_addr2(&netif->netmask),\r
+    ip4_addr3(&netif->netmask),\r
+    ip4_addr4(&netif->netmask)));\r
+}\r
+\r
+void\r
+netif_set_default(struct netif *netif)\r
+{\r
+  netif_default = netif;\r
+  LWIP_DEBUGF(NETIF_DEBUG, ("netif: setting default interface %c%c\n",\r
+           netif ? netif->name[0] : '\'', netif ? netif->name[1] : '\''));\r
+}\r
+\r
+/**\r
+ * Bring an interface up, available for processing\r
+ * traffic.\r
+ * \r
+ * @note: Enabling DHCP on a down interface will make it come\r
+ * up once configured.\r
+ * \r
+ * @see dhcp_start()\r
+ */ \r
+void netif_set_up(struct netif *netif)\r
+{\r
+  netif->flags |= NETIF_FLAG_UP;\r
+}\r
+\r
+/**\r
+ * Ask if an interface is up\r
+ */ \r
+u8_t netif_is_up(struct netif *netif)\r
+{\r
+  return (netif->flags & NETIF_FLAG_UP)?1:0;\r
+}\r
+\r
+/**\r
+ * Bring an interface down, disabling any traffic processing.\r
+ *\r
+ * @note: Enabling DHCP on a down interface will make it come\r
+ * up once configured.\r
+ * \r
+ * @see dhcp_start()\r
+ */ \r
+void netif_set_down(struct netif *netif)\r
+{\r
+  netif->flags &= ~NETIF_FLAG_UP;\r
+}\r
+\r
+void\r
+netif_init(void)\r
+{\r
+  netif_list = netif_default = NULL;\r
+}\r
+\r
index 2ece4b098db62471633e2267441389f3337b6ff7..c8e6e228866d7b3dc177002b00c91271db395bf8 100644 (file)
-/**
- * @file
- * Packet buffer management
- *
- * Packets are built from the pbuf data structure. It supports dynamic
- * memory allocation for packet contents or can reference externally
- * managed packet contents both in RAM and ROM. Quick allocation for
- * incoming packets is provided through pools with fixed sized pbufs.
- *
- * A packet may span over multiple pbufs, chained as a singly linked
- * list. This is called a "pbuf chain".
- *
- * Multiple packets may be queued, also using this singly linked list.
- * This is called a "packet queue".
- * 
- * So, a packet queue consists of one or more pbuf chains, each of
- * which consist of one or more pbufs. Currently, queues are only
- * supported in a limited section of lwIP, this is the etharp queueing
- * code. Outside of this section no packet queues are supported yet.
- * 
- * The differences between a pbuf chain and a packet queue are very
- * precise but subtle. 
- *
- * The last pbuf of a packet has a ->tot_len field that equals the
- * ->len field. It can be found by traversing the list. If the last
- * pbuf of a packet has a ->next field other than NULL, more packets
- * are on the queue.
- *
- * Therefore, looping through a pbuf of a single packet, has an
- * loop end condition (tot_len == p->len), NOT (next == NULL).
- */
-
-/*
- * 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 <adam@sics.se>
- *
- */
-
-#include <string.h>
-
-#include "lwip/opt.h"
-#include "lwip/stats.h"
-#include "lwip/def.h"
-#include "lwip/mem.h"
-#include "lwip/memp.h"
-#include "lwip/pbuf.h"
-#include "lwip/sys.h"
-#include "arch/perf.h"
-
-static u8_t pbuf_pool_memory[MEM_ALIGNMENT - 1 + PBUF_POOL_SIZE * MEM_ALIGN_SIZE(PBUF_POOL_BUFSIZE + sizeof(struct pbuf))];
-
-#if !SYS_LIGHTWEIGHT_PROT
-static volatile u8_t pbuf_pool_free_lock, pbuf_pool_alloc_lock;
-static sys_sem_t pbuf_pool_free_sem;
-#endif
-
-static struct pbuf *pbuf_pool = NULL;
-
-/**
- * Initializes the pbuf module.
- *
- * A large part of memory is allocated for holding the pool of pbufs.
- * The size of the individual pbufs in the pool is given by the size
- * parameter, and the number of pbufs in the pool by the num parameter.
- *
- * After the memory has been allocated, the pbufs are set up. The
- * ->next pointer in each pbuf is set up to point to the next pbuf in
- * the pool.
- *
- */
-void
-pbuf_init(void)
-{
-  struct pbuf *p, *q = NULL;
-  u16_t i;
-
-  pbuf_pool = (struct pbuf *)MEM_ALIGN(pbuf_pool_memory);
-
-#if PBUF_STATS
-  lwip_stats.pbuf.avail = PBUF_POOL_SIZE;
-#endif /* PBUF_STATS */
-
-  /* Set up ->next pointers to link the pbufs of the pool together */
-  p = pbuf_pool;
-
-  for(i = 0; i < PBUF_POOL_SIZE; ++i) {
-    p->next = (struct pbuf *)((u8_t *)p + PBUF_POOL_BUFSIZE + sizeof(struct pbuf));
-    p->len = p->tot_len = PBUF_POOL_BUFSIZE;
-    p->payload = MEM_ALIGN((void *)((u8_t *)p + sizeof(struct pbuf)));
-    p->flags = PBUF_FLAG_POOL;
-    q = p;
-    p = p->next;
-  }
-
-  /* The ->next pointer of last pbuf is NULL to indicate that there
-     are no more pbufs in the pool */
-  q->next = NULL;
-
-#if !SYS_LIGHTWEIGHT_PROT
-  pbuf_pool_alloc_lock = 0;
-  pbuf_pool_free_lock = 0;
-  pbuf_pool_free_sem = sys_sem_new(1);
-#endif
-}
-
-/**
- * @internal only called from pbuf_alloc()
- */
-static struct pbuf *
-pbuf_pool_alloc(void)
-{
-  struct pbuf *p = NULL;
-
-  SYS_ARCH_DECL_PROTECT(old_level);
-  SYS_ARCH_PROTECT(old_level);
-
-#if !SYS_LIGHTWEIGHT_PROT
-  /* Next, check the actual pbuf pool, but if the pool is locked, we
-     pretend to be out of buffers and return NULL. */
-  if (pbuf_pool_free_lock) {
-#if PBUF_STATS
-    ++lwip_stats.pbuf.alloc_locked;
-#endif /* PBUF_STATS */
-    return NULL;
-  }
-  pbuf_pool_alloc_lock = 1;
-  if (!pbuf_pool_free_lock) {
-#endif /* SYS_LIGHTWEIGHT_PROT */
-    p = pbuf_pool;
-    if (p) {
-      pbuf_pool = p->next;
-    }
-#if !SYS_LIGHTWEIGHT_PROT
-#if PBUF_STATS
-  } else {
-    ++lwip_stats.pbuf.alloc_locked;
-#endif /* PBUF_STATS */
-  }
-  pbuf_pool_alloc_lock = 0;
-#endif /* SYS_LIGHTWEIGHT_PROT */
-
-#if PBUF_STATS
-  if (p != NULL) {
-    ++lwip_stats.pbuf.used;
-    if (lwip_stats.pbuf.used > lwip_stats.pbuf.max) {
-      lwip_stats.pbuf.max = lwip_stats.pbuf.used;
-    }
-  }
-#endif /* PBUF_STATS */
-
-  SYS_ARCH_UNPROTECT(old_level);
-  return p;
-}
-
-
-/**
- * Allocates a pbuf of the given type (possibly a chain for PBUF_POOL type).
- *
- * The actual memory allocated for the pbuf is determined by the
- * layer at which the pbuf is allocated and the requested size
- * (from the size parameter).
- *
- * @param flag this parameter decides how and where the pbuf
- * should be allocated as follows:
- *
- * - PBUF_RAM: buffer memory for pbuf is allocated as one large
- *             chunk. This includes protocol headers as well.
- * - PBUF_ROM: no buffer memory is allocated for the pbuf, even for
- *             protocol headers. Additional headers must be prepended
- *             by allocating another pbuf and chain in to the front of
- *             the ROM pbuf. It is assumed that the memory used is really
- *             similar to ROM in that it is immutable and will not be
- *             changed. Memory which is dynamic should generally not
- *             be attached to PBUF_ROM pbufs. Use PBUF_REF instead.
- * - PBUF_REF: no buffer memory is allocated for the pbuf, even for
- *             protocol headers. It is assumed that the pbuf is only
- *             being used in a single thread. If the pbuf gets queued,
- *             then pbuf_take should be called to copy the buffer.
- * - PBUF_POOL: the pbuf is allocated as a pbuf chain, with pbufs from
- *              the pbuf pool that is allocated during pbuf_init().
- *
- * @return the allocated pbuf. If multiple pbufs where allocated, this
- * is the first pbuf of a pbuf chain.
- */
-struct pbuf *
-pbuf_alloc(pbuf_layer l, u16_t length, pbuf_flag flag)
-{
-  struct pbuf *p, *q, *r;
-  u16_t offset;
-  s32_t rem_len; /* remaining length */
-  LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 3, ("pbuf_alloc(length=%"U16_F")\n", length));
-
-  /* determine header offset */
-  offset = 0;
-  switch (l) {
-  case PBUF_TRANSPORT:
-    /* add room for transport (often TCP) layer header */
-    offset += PBUF_TRANSPORT_HLEN;
-    /* FALLTHROUGH */
-  case PBUF_IP:
-    /* add room for IP layer header */
-    offset += PBUF_IP_HLEN;
-    /* FALLTHROUGH */
-  case PBUF_LINK:
-    /* add room for link layer header */
-    offset += PBUF_LINK_HLEN;
-    break;
-  case PBUF_RAW:
-    break;
-  default:
-    LWIP_ASSERT("pbuf_alloc: bad pbuf layer", 0);
-    return NULL;
-  }
-
-  switch (flag) {
-  case PBUF_POOL:
-    /* allocate head of pbuf chain into p */
-    p = pbuf_pool_alloc();
-    LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 3, ("pbuf_alloc: allocated pbuf %p\n", (void *)p));
-    if (p == NULL) {
-#if PBUF_STATS
-      ++lwip_stats.pbuf.err;
-#endif /* PBUF_STATS */
-      return NULL;
-    }
-    p->next = NULL;
-
-    /* make the payload pointer point 'offset' bytes into pbuf data memory */
-    p->payload = MEM_ALIGN((void *)((u8_t *)p + (sizeof(struct pbuf) + offset)));
-    LWIP_ASSERT("pbuf_alloc: pbuf p->payload properly aligned",
-            ((mem_ptr_t)p->payload % MEM_ALIGNMENT) == 0);
-    /* the total length of the pbuf chain is the requested size */
-    p->tot_len = length;
-    /* set the length of the first pbuf in the chain */
-    p->len = length > PBUF_POOL_BUFSIZE - offset? PBUF_POOL_BUFSIZE - offset: length;
-    /* set reference count (needed here in case we fail) */
-    p->ref = 1;
-
-    /* now allocate the tail of the pbuf chain */
-
-    /* remember first pbuf for linkage in next iteration */
-    r = p;
-    /* remaining length to be allocated */
-    rem_len = length - p->len;
-    /* any remaining pbufs to be allocated? */
-    while (rem_len > 0) {
-      q = pbuf_pool_alloc();
-      if (q == NULL) {
-       LWIP_DEBUGF(PBUF_DEBUG | 2, ("pbuf_alloc: Out of pbufs in pool.\n"));
-#if PBUF_STATS
-        ++lwip_stats.pbuf.err;
-#endif /* PBUF_STATS */
-        /* free chain so far allocated */
-        pbuf_free(p);
-        /* bail out unsuccesfully */
-        return NULL;
-      }
-      q->next = NULL;
-      /* make previous pbuf point to this pbuf */
-      r->next = q;
-      /* set total length of this pbuf and next in chain */
-      q->tot_len = rem_len;
-      /* this pbuf length is pool size, unless smaller sized tail */
-      q->len = rem_len > PBUF_POOL_BUFSIZE? PBUF_POOL_BUFSIZE: rem_len;
-      q->payload = (void *)((u8_t *)q + sizeof(struct pbuf));
-      LWIP_ASSERT("pbuf_alloc: pbuf q->payload properly aligned",
-              ((mem_ptr_t)q->payload % MEM_ALIGNMENT) == 0);
-      q->ref = 1;
-      /* calculate remaining length to be allocated */
-      rem_len -= q->len;
-      /* remember this pbuf for linkage in next iteration */
-      r = q;
-    }
-    /* end of chain */
-    /*r->next = NULL;*/
-
-    break;
-  case PBUF_RAM:
-    /* If pbuf is to be allocated in RAM, allocate memory for it. */
-    p = mem_malloc(MEM_ALIGN_SIZE(sizeof(struct pbuf) + offset) + MEM_ALIGN_SIZE(length));
-    if (p == NULL) {
-      return NULL;
-    }
-    /* Set up internal structure of the pbuf. */
-    p->payload = MEM_ALIGN((void *)((u8_t *)p + sizeof(struct pbuf) + offset));
-    p->len = p->tot_len = length;
-    p->next = NULL;
-    p->flags = PBUF_FLAG_RAM;
-
-    LWIP_ASSERT("pbuf_alloc: pbuf->payload properly aligned",
-           ((mem_ptr_t)p->payload % MEM_ALIGNMENT) == 0);
-    break;
-  /* pbuf references existing (non-volatile static constant) ROM payload? */
-  case PBUF_ROM:
-  /* pbuf references existing (externally allocated) RAM payload? */
-  case PBUF_REF:
-    /* only allocate memory for the pbuf structure */
-    p = memp_malloc(MEMP_PBUF);
-    if (p == NULL) {
-      LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 2, ("pbuf_alloc: Could not allocate MEMP_PBUF for PBUF_%s.\n", flag == PBUF_ROM?"ROM":"REF"));
-      return NULL;
-    }
-    /* caller must set this field properly, afterwards */
-    p->payload = NULL;
-    p->len = p->tot_len = length;
-    p->next = NULL;
-    p->flags = (flag == PBUF_ROM? PBUF_FLAG_ROM: PBUF_FLAG_REF);
-    break;
-  default:
-    LWIP_ASSERT("pbuf_alloc: erroneous flag", 0);
-    return NULL;
-  }
-  /* set reference count */
-  p->ref = 1;
-  LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 3, ("pbuf_alloc(length=%"U16_F") == %p\n", length, (void *)p));
-  return p;
-}
-
-
-#if PBUF_STATS
-#define DEC_PBUF_STATS do { --lwip_stats.pbuf.used; } while (0)
-#else /* PBUF_STATS */
-#define DEC_PBUF_STATS
-#endif /* PBUF_STATS */
-
-#define PBUF_POOL_FAST_FREE(p)  do {                                    \
-                                  p->next = pbuf_pool;                  \
-                                  pbuf_pool = p;                        \
-                                  DEC_PBUF_STATS;                       \
-                                } while (0)
-
-#if SYS_LIGHTWEIGHT_PROT
-#define PBUF_POOL_FREE(p)  do {                                         \
-                                SYS_ARCH_DECL_PROTECT(old_level);       \
-                                SYS_ARCH_PROTECT(old_level);            \
-                                PBUF_POOL_FAST_FREE(p);                 \
-                                SYS_ARCH_UNPROTECT(old_level);          \
-                               } while (0)
-#else /* SYS_LIGHTWEIGHT_PROT */
-#define PBUF_POOL_FREE(p)  do {                                         \
-                             sys_sem_wait(pbuf_pool_free_sem);          \
-                             PBUF_POOL_FAST_FREE(p);                    \
-                             sys_sem_signal(pbuf_pool_free_sem);        \
-                           } while (0)
-#endif /* SYS_LIGHTWEIGHT_PROT */
-
-/**
- * Shrink a pbuf chain to a desired length.
- *
- * @param p pbuf to shrink.
- * @param new_len desired new length of pbuf chain
- *
- * Depending on the desired length, the first few pbufs in a chain might
- * be skipped and left unchanged. The new last pbuf in the chain will be
- * resized, and any remaining pbufs will be freed.
- *
- * @note If the pbuf is ROM/REF, only the ->tot_len and ->len fields are adjusted.
- * @note May not be called on a packet queue.
- *
- * @bug Cannot grow the size of a pbuf (chain) (yet).
- */
-void
-pbuf_realloc(struct pbuf *p, u16_t new_len)
-{
-  struct pbuf *q;
-  u16_t rem_len; /* remaining length */
-  s16_t grow;
-
-  LWIP_ASSERT("pbuf_realloc: sane p->flags", p->flags == PBUF_FLAG_POOL ||
-              p->flags == PBUF_FLAG_ROM ||
-              p->flags == PBUF_FLAG_RAM ||
-              p->flags == PBUF_FLAG_REF);
-
-  /* desired length larger than current length? */
-  if (new_len >= p->tot_len) {
-    /* enlarging not yet supported */
-    return;
-  }
-
-  /* the pbuf chain grows by (new_len - p->tot_len) bytes
-   * (which may be negative in case of shrinking) */
-  grow = new_len - p->tot_len;
-
-  /* first, step over any pbufs that should remain in the chain */
-  rem_len = new_len;
-  q = p;
-  /* should this pbuf be kept? */
-  while (rem_len > q->len) {
-    /* decrease remaining length by pbuf length */
-    rem_len -= q->len;
-    /* decrease total length indicator */
-    q->tot_len += grow;
-    /* proceed to next pbuf in chain */
-    q = q->next;
-  }
-  /* we have now reached the new last pbuf (in q) */
-  /* rem_len == desired length for pbuf q */
-
-  /* shrink allocated memory for PBUF_RAM */
-  /* (other types merely adjust their length fields */
-  if ((q->flags == PBUF_FLAG_RAM) && (rem_len != q->len)) {
-    /* reallocate and adjust the length of the pbuf that will be split */
-    mem_realloc(q, (u8_t *)q->payload - (u8_t *)q + rem_len);
-  }
-  /* adjust length fields for new last pbuf */
-  q->len = rem_len;
-  q->tot_len = q->len;
-
-  /* any remaining pbufs in chain? */
-  if (q->next != NULL) {
-    /* free remaining pbufs in chain */
-    pbuf_free(q->next);
-  }
-  /* q is last packet in chain */
-  q->next = NULL;
-
-}
-
-/**
- * Adjusts the payload pointer to hide or reveal headers in the payload.
- *
- * Adjusts the ->payload pointer so that space for a header
- * (dis)appears in the pbuf payload.
- *
- * The ->payload, ->tot_len and ->len fields are adjusted.
- *
- * @param hdr_size_inc Number of bytes to increment header size which
- * increases the size of the pbuf. New space is on the front.
- * (Using a negative value decreases the header size.)
- * If hdr_size_inc is 0, this function does nothing and returns succesful.
- *
- * PBUF_ROM and PBUF_REF type buffers cannot have their sizes increased, so
- * the call will fail. A check is made that the increase in header size does
- * not move the payload pointer in front of the start of the buffer.
- * @return non-zero on failure, zero on success.
- *
- */
-u8_t
-pbuf_header(struct pbuf *p, s16_t header_size_increment)
-{
-  void *payload;
-
-  LWIP_ASSERT("p != NULL", p != NULL);
-  if ((header_size_increment == 0) || (p == NULL)) return 0;
-  /* remember current payload pointer */
-  payload = p->payload;
-
-  /* pbuf types containing payloads? */
-  if (p->flags == PBUF_FLAG_RAM || p->flags == PBUF_FLAG_POOL) {
-    /* set new payload pointer */
-    p->payload = (u8_t *)p->payload - header_size_increment;
-    /* boundary check fails? */
-    if ((u8_t *)p->payload < (u8_t *)p + sizeof(struct pbuf)) {
-      LWIP_DEBUGF( PBUF_DEBUG | 2, ("pbuf_header: failed as %p < %p (not enough space for new header size)\n",
-        (void *)p->payload,
-        (void *)(p + 1)));\
-      /* restore old payload pointer */
-      p->payload = payload;
-      /* bail out unsuccesfully */
-      return 1;
-    }
-  /* pbuf types refering to external payloads? */
-  } else if (p->flags == PBUF_FLAG_REF || p->flags == PBUF_FLAG_ROM) {
-    /* hide a header in the payload? */
-    if ((header_size_increment < 0) && (header_size_increment - p->len <= 0)) {
-      /* increase payload pointer */
-      p->payload = (u8_t *)p->payload - header_size_increment;
-    } else {
-      /* cannot expand payload to front (yet!)
-       * bail out unsuccesfully */
-      return 1;
-    }
-  }
-  /* modify pbuf length fields */
-  p->len += header_size_increment;
-  p->tot_len += header_size_increment;
-
-  LWIP_DEBUGF( PBUF_DEBUG, ("pbuf_header: old %p new %p (%"S16_F")\n",
-    (void *)payload, (void *)p->payload, header_size_increment));
-
-  return 0;
-}
-
-/**
- * Dereference a pbuf chain or queue and deallocate any no-longer-used
- * pbufs at the head of this chain or queue.
- *
- * Decrements the pbuf reference count. If it reaches zero, the pbuf is
- * deallocated.
- *
- * For a pbuf chain, this is repeated for each pbuf in the chain,
- * up to the first pbuf which has a non-zero reference count after
- * decrementing. So, when all reference counts are one, the whole
- * chain is free'd.
- *
- * @param pbuf The pbuf (chain) to be dereferenced.
- *
- * @return the number of pbufs that were de-allocated
- * from the head of the chain.
- *
- * @note MUST NOT be called on a packet queue (Not verified to work yet).
- * @note the reference counter of a pbuf equals the number of pointers
- * that refer to the pbuf (or into the pbuf).
- *
- * @internal examples:
- *
- * Assuming existing chains a->b->c with the following reference
- * counts, calling pbuf_free(a) results in:
- * 
- * 1->2->3 becomes ...1->3
- * 3->3->3 becomes 2->3->3
- * 1->1->2 becomes ......1
- * 2->1->1 becomes 1->1->1
- * 1->1->1 becomes .......
- *
- */
-u8_t
-pbuf_free(struct pbuf *p)
-{
-  struct pbuf *q;
-  u8_t count;
-  SYS_ARCH_DECL_PROTECT(old_level);
-
-  LWIP_ASSERT("p != NULL", p != NULL);
-  /* if assertions are disabled, proceed with debug output */
-  if (p == NULL) {
-    LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 2, ("pbuf_free(p == NULL) was called.\n"));
-    return 0;
-  }
-  LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 3, ("pbuf_free(%p)\n", (void *)p));
-
-  PERF_START;
-
-  LWIP_ASSERT("pbuf_free: sane flags",
-    p->flags == PBUF_FLAG_RAM || p->flags == PBUF_FLAG_ROM ||
-    p->flags == PBUF_FLAG_REF || p->flags == PBUF_FLAG_POOL);
-
-  count = 0;
-  /* Since decrementing ref cannot be guaranteed to be a single machine operation
-   * we must protect it. Also, the later test of ref must be protected.
-   */
-  SYS_ARCH_PROTECT(old_level);
-  /* de-allocate all consecutive pbufs from the head of the chain that
-   * obtain a zero reference count after decrementing*/
-  while (p != NULL) {
-    /* all pbufs in a chain are referenced at least once */
-    LWIP_ASSERT("pbuf_free: p->ref > 0", p->ref > 0);
-    /* decrease reference count (number of pointers to pbuf) */
-    p->ref--;
-    /* this pbuf is no longer referenced to? */
-    if (p->ref == 0) {
-      /* remember next pbuf in chain for next iteration */
-      q = p->next;
-      LWIP_DEBUGF( PBUF_DEBUG | 2, ("pbuf_free: deallocating %p\n", (void *)p));
-      /* is this a pbuf from the pool? */
-      if (p->flags == PBUF_FLAG_POOL) {
-        p->len = p->tot_len = PBUF_POOL_BUFSIZE;
-        p->payload = (void *)((u8_t *)p + sizeof(struct pbuf));
-        PBUF_POOL_FREE(p);
-      /* is this a ROM or RAM referencing pbuf? */
-      } else if (p->flags == PBUF_FLAG_ROM || p->flags == PBUF_FLAG_REF) {
-        memp_free(MEMP_PBUF, p);
-      /* p->flags == PBUF_FLAG_RAM */
-      } else {
-        mem_free(p);
-      }
-      count++;
-      /* proceed to next pbuf */
-      p = q;
-    /* p->ref > 0, this pbuf is still referenced to */
-    /* (and so the remaining pbufs in chain as well) */
-    } else {
-      LWIP_DEBUGF( PBUF_DEBUG | 2, ("pbuf_free: %p has ref %"U16_F", ending here.\n", (void *)p, (u16_t)p->ref));
-      /* stop walking through the chain */
-      p = NULL;
-    }
-  }
-  SYS_ARCH_UNPROTECT(old_level);
-  PERF_STOP("pbuf_free");
-  /* return number of de-allocated pbufs */
-  return count;
-}
-
-/**
- * Count number of pbufs in a chain
- *
- * @param p first pbuf of chain
- * @return the number of pbufs in a chain
- */
-
-u8_t
-pbuf_clen(struct pbuf *p)
-{
-  u8_t len;
-
-  len = 0;
-  while (p != NULL) {
-    ++len;
-    p = p->next;
-  }
-  return len;
-}
-
-/**
- * Increment the reference count of the pbuf.
- *
- * @param p pbuf to increase reference counter of
- *
- */
-void
-pbuf_ref(struct pbuf *p)
-{
-  SYS_ARCH_DECL_PROTECT(old_level);
-  /* pbuf given? */
-  if (p != NULL) {
-    SYS_ARCH_PROTECT(old_level);
-    ++(p->ref);
-    SYS_ARCH_UNPROTECT(old_level);
-  }
-}
-
-/**
- * Concatenate two pbufs (each may be a pbuf chain) and take over
- * the caller's reference of the tail pbuf.
- * 
- * @note The caller MAY NOT reference the tail pbuf afterwards.
- * Use pbuf_chain() for that purpose.
- * 
- * @see pbuf_chain()
- */
-
-void
-pbuf_cat(struct pbuf *h, struct pbuf *t)
-{
-  struct pbuf *p;
-
-  LWIP_ASSERT("h != NULL (programmer violates API)", h != NULL);
-  LWIP_ASSERT("t != NULL (programmer violates API)", t != NULL);
-  if ((h == NULL) || (t == NULL)) return;
-
-  /* proceed to last pbuf of chain */
-  for (p = h; p->next != NULL; p = p->next) {
-    /* add total length of second chain to all totals of first chain */
-    p->tot_len += t->tot_len;
-  }
-  /* { p is last pbuf of first h chain, p->next == NULL } */
-  LWIP_ASSERT("p->tot_len == p->len (of last pbuf in chain)", p->tot_len == p->len);
-  LWIP_ASSERT("p->next == NULL", p->next == NULL);
-  /* add total length of second chain to last pbuf total of first chain */
-  p->tot_len += t->tot_len;
-  /* chain last pbuf of head (p) with first of tail (t) */
-  p->next = t;
-  /* p->next now references t, but the caller will drop its reference to t,
-   * so netto there is no change to the reference count of t.
-   */
-}
-
-/**
- * Chain two pbufs (or pbuf chains) together.
- * 
- * The caller MUST call pbuf_free(t) once it has stopped
- * using it. Use pbuf_cat() instead if you no longer use t.
- * 
- * @param h head pbuf (chain)
- * @param t tail pbuf (chain)
- * @note The pbufs MUST belong to the same packet.
- * @note MAY NOT be called on a packet queue.
- *
- * The ->tot_len fields of all pbufs of the head chain are adjusted.
- * The ->next field of the last pbuf of the head chain is adjusted.
- * The ->ref field of the first pbuf of the tail chain is adjusted.
- *
- */
-void
-pbuf_chain(struct pbuf *h, struct pbuf *t)
-{
-  pbuf_cat(h, t);
-  /* t is now referenced by h */
-  pbuf_ref(t);
-  LWIP_DEBUGF(PBUF_DEBUG | DBG_FRESH | 2, ("pbuf_chain: %p references %p\n", (void *)h, (void *)t));
-}
-
-/* For packet queueing. Note that queued packets MUST be dequeued first
- * using pbuf_dequeue() before calling other pbuf_() functions. */
-#if ARP_QUEUEING
-/**
- * Add a packet to the end of a queue.
- *
- * @param q pointer to first packet on the queue
- * @param n packet to be queued
- *
- * Both packets MUST be given, and must be different.
- */
-void
-pbuf_queue(struct pbuf *p, struct pbuf *n)
-{
-#if PBUF_DEBUG /* remember head of queue */
-  struct pbuf *q = p;
-#endif
-  /* programmer stupidity checks */
-  LWIP_ASSERT("p == NULL in pbuf_queue: this indicates a programmer error\n", p != NULL);
-  LWIP_ASSERT("n == NULL in pbuf_queue: this indicates a programmer error\n", n != NULL);
-  LWIP_ASSERT("p == n in pbuf_queue: this indicates a programmer error\n", p != n);
-  if ((p == NULL) || (n == NULL) || (p == n)){
-    LWIP_DEBUGF(PBUF_DEBUG | DBG_HALT | 3, ("pbuf_queue: programmer argument error\n"));
-    return;
-  }
-
-  /* iterate through all packets on queue */
-  while (p->next != NULL) {
-/* be very picky about pbuf chain correctness */
-#if PBUF_DEBUG
-    /* iterate through all pbufs in packet */
-    while (p->tot_len != p->len) {
-      /* make sure invariant condition holds */
-      LWIP_ASSERT("p->len < p->tot_len", p->len < p->tot_len);
-      /* make sure each packet is complete */
-      LWIP_ASSERT("p->next != NULL", p->next != NULL);
-      p = p->next;
-      /* { p->tot_len == p->len => p is last pbuf of a packet } */
-    }
-    /* { p is last pbuf of a packet } */
-    /* proceed to next packet on queue */
-#endif
-    /* proceed to next pbuf */
-    if (p->next != NULL) p = p->next;
-  }
-  /* { p->tot_len == p->len and p->next == NULL } ==>
-   * { p is last pbuf of last packet on queue } */
-  /* chain last pbuf of queue with n */
-  p->next = n;
-  /* n is now referenced to by the (packet p in the) queue */
-  pbuf_ref(n);
-#if PBUF_DEBUG
-  LWIP_DEBUGF(PBUF_DEBUG | DBG_FRESH | 2,
-    ("pbuf_queue: newly queued packet %p sits after packet %p in queue %p\n",
-    (void *)n, (void *)p, (void *)q));
-#endif
-}
-
-/**
- * Remove a packet from the head of a queue.
- *
- * The caller MUST reference the remainder of the queue (as returned). The
- * caller MUST NOT call pbuf_ref() as it implicitly takes over the reference
- * from p.
- * 
- * @param p pointer to first packet on the queue which will be dequeued.
- * @return first packet on the remaining queue (NULL if no further packets).
- *
- */
-struct pbuf *
-pbuf_dequeue(struct pbuf *p)
-{
-  struct pbuf *q;
-  LWIP_ASSERT("p != NULL", p != NULL);
-
-  /* iterate through all pbufs in packet p */
-  while (p->tot_len != p->len) {
-    /* make sure invariant condition holds */
-    LWIP_ASSERT("p->len < p->tot_len", p->len < p->tot_len);
-    /* make sure each packet is complete */
-    LWIP_ASSERT("p->next != NULL", p->next != NULL);
-    p = p->next;
-  }
-  /* { p->tot_len == p->len } => p is the last pbuf of the first packet */
-  /* remember next packet on queue in q */
-  q = p->next;
-  /* dequeue packet p from queue */
-  p->next = NULL;
-  /* any next packet on queue? */
-  if (q != NULL) {
-    /* although q is no longer referenced by p, it MUST be referenced by
-     * the caller, who is maintaining this packet queue. So, we do not call
-     * pbuf_free(q) here, resulting in an implicit pbuf_ref(q) for the caller. */
-    LWIP_DEBUGF(PBUF_DEBUG | DBG_FRESH | 2, ("pbuf_dequeue: first remaining packet on queue is %p\n", (void *)q));
-  } else {
-    LWIP_DEBUGF(PBUF_DEBUG | DBG_FRESH | 2, ("pbuf_dequeue: no further packets on queue\n"));
-  }
-  return q;
-}
-#endif
-
-/**
- *
- * Create PBUF_POOL (or PBUF_RAM) copies of PBUF_REF pbufs.
- *
- * Used to queue packets on behalf of the lwIP stack, such as
- * ARP based queueing.
- *
- * Go through a pbuf chain and replace any PBUF_REF buffers
- * with PBUF_POOL (or PBUF_RAM) pbufs, each taking a copy of
- * the referenced data.
- *
- * @note You MUST explicitly use p = pbuf_take(p);
- * The pbuf you give as argument, may have been replaced
- * by a (differently located) copy through pbuf_take()!
- *
- * @note Any replaced pbufs will be freed through pbuf_free().
- * This may deallocate them if they become no longer referenced.
- *
- * @param p Head of pbuf chain to process
- *
- * @return Pointer to head of pbuf chain
- */
-struct pbuf *
-pbuf_take(struct pbuf *p)
-{
-  struct pbuf *q , *prev, *head;
-  LWIP_ASSERT("pbuf_take: p != NULL\n", p != NULL);
-  LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 3, ("pbuf_take(%p)\n", (void*)p));
-
-  prev = NULL;
-  head = p;
-  /* iterate through pbuf chain */
-  do
-  {
-    /* pbuf is of type PBUF_REF? */
-    if (p->flags == PBUF_FLAG_REF) {
-      LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE, ("pbuf_take: encountered PBUF_REF %p\n", (void *)p));
-      /* allocate a pbuf (w/ payload) fully in RAM */
-      /* PBUF_POOL buffers are faster if we can use them */
-      if (p->len <= PBUF_POOL_BUFSIZE) {
-        q = pbuf_alloc(PBUF_RAW, p->len, PBUF_POOL);
-        if (q == NULL) {
-          LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 2, ("pbuf_take: Could not allocate PBUF_POOL\n"));
-        }
-      } else {
-        /* no replacement pbuf yet */
-        q = NULL;
-        LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 2, ("pbuf_take: PBUF_POOL too small to replace PBUF_REF\n"));
-      }
-      /* no (large enough) PBUF_POOL was available? retry with PBUF_RAM */
-      if (q == NULL) {
-        q = pbuf_alloc(PBUF_RAW, p->len, PBUF_RAM);
-        if (q == NULL) {
-          LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 2, ("pbuf_take: Could not allocate PBUF_RAM\n"));
-        }
-      }
-      /* replacement pbuf could be allocated? */
-      if (q != NULL)
-      {
-        /* copy p to q */
-        /* copy successor */
-        q->next = p->next;
-        /* remove linkage from original pbuf */
-        p->next = NULL;
-        /* remove linkage to original pbuf */
-        if (prev != NULL) {
-          /* prev->next == p at this point */
-          LWIP_ASSERT("prev->next == p", prev->next == p);
-          /* break chain and insert new pbuf instead */
-          prev->next = q;
-        /* prev == NULL, so we replaced the head pbuf of the chain */
-        } else {
-          head = q;
-        }
-        /* copy pbuf payload */
-        memcpy(q->payload, p->payload, p->len);
-        q->tot_len = p->tot_len;
-        q->len = p->len;
-        /* in case p was the first pbuf, it is no longer refered to by
-         * our caller, as the caller MUST do p = pbuf_take(p);
-         * in case p was not the first pbuf, it is no longer refered to
-         * by prev. we can safely free the pbuf here.
-         * (note that we have set p->next to NULL already so that
-         * we will not free the rest of the chain by accident.)
-         */
-        pbuf_free(p);
-        /* do not copy ref, since someone else might be using the old buffer */
-        LWIP_DEBUGF(PBUF_DEBUG, ("pbuf_take: replaced PBUF_REF %p with %p\n", (void *)p, (void *)q));
-        p = q;
-      } else {
-        /* deallocate chain */
-        pbuf_free(head);
-        LWIP_DEBUGF(PBUF_DEBUG | 2, ("pbuf_take: failed to allocate replacement pbuf for %p\n", (void *)p));
-        return NULL;
-      }
-    /* p->flags != PBUF_FLAG_REF */
-    } else {
-      LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 1, ("pbuf_take: skipping pbuf not of type PBUF_REF\n"));
-    }
-    /* remember this pbuf */
-    prev = p;
-    /* proceed to next pbuf in original chain */
-    p = p->next;
-  } while (p);
-  LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 1, ("pbuf_take: end of chain reached.\n"));
-
-  return head;
-}
-
-/**
- * Dechains the first pbuf from its succeeding pbufs in the chain.
- *
- * Makes p->tot_len field equal to p->len.
- * @param p pbuf to dechain
- * @return remainder of the pbuf chain, or NULL if it was de-allocated.
- * @note May not be called on a packet queue.
- */
-struct pbuf *
-pbuf_dechain(struct pbuf *p)
-{
-  struct pbuf *q;
-  u8_t tail_gone = 1;
-  /* tail */
-  q = p->next;
-  /* pbuf has successor in chain? */
-  if (q != NULL) {
-    /* assert tot_len invariant: (p->tot_len == p->len + (p->next? p->next->tot_len: 0) */
-    LWIP_ASSERT("p->tot_len == p->len + q->tot_len", q->tot_len == p->tot_len - p->len);
-    /* enforce invariant if assertion is disabled */
-    q->tot_len = p->tot_len - p->len;
-    /* decouple pbuf from remainder */
-    p->next = NULL;
-    /* total length of pbuf p is its own length only */
-    p->tot_len = p->len;
-    /* q is no longer referenced by p, free it */
-    LWIP_DEBUGF(PBUF_DEBUG | DBG_STATE, ("pbuf_dechain: unreferencing %p\n", (void *)q));
-    tail_gone = pbuf_free(q);
-    if (tail_gone > 0) {
-      LWIP_DEBUGF(PBUF_DEBUG | DBG_STATE,
-                  ("pbuf_dechain: deallocated %p (as it is no longer referenced)\n", (void *)q));
-    }
-    /* return remaining tail or NULL if deallocated */
-  }
-  /* assert tot_len invariant: (p->tot_len == p->len + (p->next? p->next->tot_len: 0) */
-  LWIP_ASSERT("p->tot_len == p->len", p->tot_len == p->len);
-  return (tail_gone > 0? NULL: q);
-}
+/**\r
+ * @file\r
+ * Packet buffer management\r
+ *\r
+ * Packets are built from the pbuf data structure. It supports dynamic\r
+ * memory allocation for packet contents or can reference externally\r
+ * managed packet contents both in RAM and ROM. Quick allocation for\r
+ * incoming packets is provided through pools with fixed sized pbufs.\r
+ *\r
+ * A packet may span over multiple pbufs, chained as a singly linked\r
+ * list. This is called a "pbuf chain".\r
+ *\r
+ * Multiple packets may be queued, also using this singly linked list.\r
+ * This is called a "packet queue".\r
+ * \r
+ * So, a packet queue consists of one or more pbuf chains, each of\r
+ * which consist of one or more pbufs. Currently, queues are only\r
+ * supported in a limited section of lwIP, this is the etharp queueing\r
+ * code. Outside of this section no packet queues are supported yet.\r
+ * \r
+ * The differences between a pbuf chain and a packet queue are very\r
+ * precise but subtle. \r
+ *\r
+ * The last pbuf of a packet has a ->tot_len field that equals the\r
+ * ->len field. It can be found by traversing the list. If the last\r
+ * pbuf of a packet has a ->next field other than NULL, more packets\r
+ * are on the queue.\r
+ *\r
+ * Therefore, looping through a pbuf of a single packet, has an\r
+ * loop end condition (tot_len == p->len), NOT (next == NULL).\r
+ */\r
+\r
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without modification,\r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED\r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT\r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY\r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ *\r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+\r
+#include <string.h>\r
+\r
+#include "lwip/opt.h"\r
+#include "lwip/stats.h"\r
+#include "lwip/def.h"\r
+#include "lwip/mem.h"\r
+#include "lwip/memp.h"\r
+#include "lwip/pbuf.h"\r
+#include "lwip/sys.h"\r
+#include "arch/perf.h"\r
+\r
+static u8_t pbuf_pool_memory[MEM_ALIGNMENT - 1 + PBUF_POOL_SIZE * MEM_ALIGN_SIZE(PBUF_POOL_BUFSIZE + sizeof(struct pbuf))];\r
+\r
+#if !SYS_LIGHTWEIGHT_PROT\r
+static volatile u8_t pbuf_pool_free_lock, pbuf_pool_alloc_lock;\r
+static sys_sem_t pbuf_pool_free_sem;\r
+#endif\r
+\r
+static struct pbuf *pbuf_pool = NULL;\r
+\r
+/**\r
+ * Initializes the pbuf module.\r
+ *\r
+ * A large part of memory is allocated for holding the pool of pbufs.\r
+ * The size of the individual pbufs in the pool is given by the size\r
+ * parameter, and the number of pbufs in the pool by the num parameter.\r
+ *\r
+ * After the memory has been allocated, the pbufs are set up. The\r
+ * ->next pointer in each pbuf is set up to point to the next pbuf in\r
+ * the pool.\r
+ *\r
+ */\r
+void\r
+pbuf_init(void)\r
+{\r
+  struct pbuf *p, *q = NULL;\r
+  u16_t i;\r
+\r
+  pbuf_pool = (struct pbuf *)MEM_ALIGN(pbuf_pool_memory);\r
+\r
+#if PBUF_STATS\r
+  lwip_stats.pbuf.avail = PBUF_POOL_SIZE;\r
+#endif /* PBUF_STATS */\r
+\r
+  /* Set up ->next pointers to link the pbufs of the pool together */\r
+  p = pbuf_pool;\r
+\r
+  for(i = 0; i < PBUF_POOL_SIZE; ++i) {\r
+    p->next = (struct pbuf *)((u8_t *)p + PBUF_POOL_BUFSIZE + sizeof(struct pbuf));\r
+    p->len = p->tot_len = PBUF_POOL_BUFSIZE;\r
+    p->payload = MEM_ALIGN((void *)((u8_t *)p + sizeof(struct pbuf)));\r
+    p->flags = PBUF_FLAG_POOL;\r
+    q = p;\r
+    p = p->next;\r
+  }\r
+\r
+  /* The ->next pointer of last pbuf is NULL to indicate that there\r
+     are no more pbufs in the pool */\r
+  q->next = NULL;\r
+\r
+#if !SYS_LIGHTWEIGHT_PROT\r
+  pbuf_pool_alloc_lock = 0;\r
+  pbuf_pool_free_lock = 0;\r
+  pbuf_pool_free_sem = sys_sem_new(1);\r
+#endif\r
+}\r
+\r
+/**\r
+ * @internal only called from pbuf_alloc()\r
+ */\r
+static struct pbuf *\r
+pbuf_pool_alloc(void)\r
+{\r
+  struct pbuf *p = NULL;\r
+\r
+  SYS_ARCH_DECL_PROTECT(old_level);\r
+  SYS_ARCH_PROTECT(old_level);\r
+\r
+#if !SYS_LIGHTWEIGHT_PROT\r
+  /* Next, check the actual pbuf pool, but if the pool is locked, we\r
+     pretend to be out of buffers and return NULL. */\r
+  if (pbuf_pool_free_lock) {\r
+#if PBUF_STATS\r
+    ++lwip_stats.pbuf.alloc_locked;\r
+#endif /* PBUF_STATS */\r
+    return NULL;\r
+  }\r
+  pbuf_pool_alloc_lock = 1;\r
+  if (!pbuf_pool_free_lock) {\r
+#endif /* SYS_LIGHTWEIGHT_PROT */\r
+    p = pbuf_pool;\r
+    if (p) {\r
+      pbuf_pool = p->next;\r
+    }\r
+#if !SYS_LIGHTWEIGHT_PROT\r
+#if PBUF_STATS\r
+  } else {\r
+    ++lwip_stats.pbuf.alloc_locked;\r
+#endif /* PBUF_STATS */\r
+  }\r
+  pbuf_pool_alloc_lock = 0;\r
+#endif /* SYS_LIGHTWEIGHT_PROT */\r
+\r
+#if PBUF_STATS\r
+  if (p != NULL) {\r
+    ++lwip_stats.pbuf.used;\r
+    if (lwip_stats.pbuf.used > lwip_stats.pbuf.max) {\r
+      lwip_stats.pbuf.max = lwip_stats.pbuf.used;\r
+    }\r
+  }\r
+#endif /* PBUF_STATS */\r
+\r
+  SYS_ARCH_UNPROTECT(old_level);\r
+  return p;\r
+}\r
+\r
+\r
+/**\r
+ * Allocates a pbuf of the given type (possibly a chain for PBUF_POOL type).\r
+ *\r
+ * The actual memory allocated for the pbuf is determined by the\r
+ * layer at which the pbuf is allocated and the requested size\r
+ * (from the size parameter).\r
+ *\r
+ * @param flag this parameter decides how and where the pbuf\r
+ * should be allocated as follows:\r
+ *\r
+ * - PBUF_RAM: buffer memory for pbuf is allocated as one large\r
+ *             chunk. This includes protocol headers as well.\r
+ * - PBUF_ROM: no buffer memory is allocated for the pbuf, even for\r
+ *             protocol headers. Additional headers must be prepended\r
+ *             by allocating another pbuf and chain in to the front of\r
+ *             the ROM pbuf. It is assumed that the memory used is really\r
+ *             similar to ROM in that it is immutable and will not be\r
+ *             changed. Memory which is dynamic should generally not\r
+ *             be attached to PBUF_ROM pbufs. Use PBUF_REF instead.\r
+ * - PBUF_REF: no buffer memory is allocated for the pbuf, even for\r
+ *             protocol headers. It is assumed that the pbuf is only\r
+ *             being used in a single thread. If the pbuf gets queued,\r
+ *             then pbuf_take should be called to copy the buffer.\r
+ * - PBUF_POOL: the pbuf is allocated as a pbuf chain, with pbufs from\r
+ *              the pbuf pool that is allocated during pbuf_init().\r
+ *\r
+ * @return the allocated pbuf. If multiple pbufs where allocated, this\r
+ * is the first pbuf of a pbuf chain.\r
+ */\r
+struct pbuf *\r
+pbuf_alloc(pbuf_layer l, u16_t length, pbuf_flag flag)\r
+{\r
+  struct pbuf *p, *q, *r;\r
+  u16_t offset;\r
+  s32_t rem_len; /* remaining length */\r
+  LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 3, ("pbuf_alloc(length=%"U16_F")\n", length));\r
+\r
+  /* determine header offset */\r
+  offset = 0;\r
+  switch (l) {\r
+  case PBUF_TRANSPORT:\r
+    /* add room for transport (often TCP) layer header */\r
+    offset += PBUF_TRANSPORT_HLEN;\r
+    /* FALLTHROUGH */\r
+  case PBUF_IP:\r
+    /* add room for IP layer header */\r
+    offset += PBUF_IP_HLEN;\r
+    /* FALLTHROUGH */\r
+  case PBUF_LINK:\r
+    /* add room for link layer header */\r
+    offset += PBUF_LINK_HLEN;\r
+    break;\r
+  case PBUF_RAW:\r
+    break;\r
+  default:\r
+    LWIP_ASSERT("pbuf_alloc: bad pbuf layer", 0);\r
+    return NULL;\r
+  }\r
+\r
+  switch (flag) {\r
+  case PBUF_POOL:\r
+    /* allocate head of pbuf chain into p */\r
+    p = pbuf_pool_alloc();\r
+    LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 3, ("pbuf_alloc: allocated pbuf %p\n", (void *)p));\r
+    if (p == NULL) {\r
+#if PBUF_STATS\r
+      ++lwip_stats.pbuf.err;\r
+#endif /* PBUF_STATS */\r
+      return NULL;\r
+    }\r
+    p->next = NULL;\r
+\r
+    /* make the payload pointer point 'offset' bytes into pbuf data memory */\r
+    p->payload = MEM_ALIGN((void *)((u8_t *)p + (sizeof(struct pbuf) + offset)));\r
+    LWIP_ASSERT("pbuf_alloc: pbuf p->payload properly aligned",\r
+            ((mem_ptr_t)p->payload % MEM_ALIGNMENT) == 0);\r
+    /* the total length of the pbuf chain is the requested size */\r
+    p->tot_len = length;\r
+    /* set the length of the first pbuf in the chain */\r
+    p->len = length > PBUF_POOL_BUFSIZE - offset? PBUF_POOL_BUFSIZE - offset: length;\r
+    /* set reference count (needed here in case we fail) */\r
+    p->ref = 1;\r
+\r
+    /* now allocate the tail of the pbuf chain */\r
+\r
+    /* remember first pbuf for linkage in next iteration */\r
+    r = p;\r
+    /* remaining length to be allocated */\r
+    rem_len = length - p->len;\r
+    /* any remaining pbufs to be allocated? */\r
+    while (rem_len > 0) {\r
+      q = pbuf_pool_alloc();\r
+      if (q == NULL) {\r
+       LWIP_DEBUGF(PBUF_DEBUG | 2, ("pbuf_alloc: Out of pbufs in pool.\n"));\r
+#if PBUF_STATS\r
+        ++lwip_stats.pbuf.err;\r
+#endif /* PBUF_STATS */\r
+        /* free chain so far allocated */\r
+        pbuf_free(p);\r
+        /* bail out unsuccesfully */\r
+        return NULL;\r
+      }\r
+      q->next = NULL;\r
+      /* make previous pbuf point to this pbuf */\r
+      r->next = q;\r
+      /* set total length of this pbuf and next in chain */\r
+      q->tot_len = rem_len;\r
+      /* this pbuf length is pool size, unless smaller sized tail */\r
+      q->len = rem_len > PBUF_POOL_BUFSIZE? PBUF_POOL_BUFSIZE: rem_len;\r
+      q->payload = (void *)((u8_t *)q + sizeof(struct pbuf));\r
+      LWIP_ASSERT("pbuf_alloc: pbuf q->payload properly aligned",\r
+              ((mem_ptr_t)q->payload % MEM_ALIGNMENT) == 0);\r
+      q->ref = 1;\r
+      /* calculate remaining length to be allocated */\r
+      rem_len -= q->len;\r
+      /* remember this pbuf for linkage in next iteration */\r
+      r = q;\r
+    }\r
+    /* end of chain */\r
+    /*r->next = NULL;*/\r
+\r
+    break;\r
+  case PBUF_RAM:\r
+    /* If pbuf is to be allocated in RAM, allocate memory for it. */\r
+    p = mem_malloc(MEM_ALIGN_SIZE(sizeof(struct pbuf) + offset) + MEM_ALIGN_SIZE(length));\r
+    if (p == NULL) {\r
+      return NULL;\r
+    }\r
+    /* Set up internal structure of the pbuf. */\r
+    p->payload = MEM_ALIGN((void *)((u8_t *)p + sizeof(struct pbuf) + offset));\r
+    p->len = p->tot_len = length;\r
+    p->next = NULL;\r
+    p->flags = PBUF_FLAG_RAM;\r
+\r
+    LWIP_ASSERT("pbuf_alloc: pbuf->payload properly aligned",\r
+           ((mem_ptr_t)p->payload % MEM_ALIGNMENT) == 0);\r
+    break;\r
+  /* pbuf references existing (non-volatile static constant) ROM payload? */\r
+  case PBUF_ROM:\r
+  /* pbuf references existing (externally allocated) RAM payload? */\r
+  case PBUF_REF:\r
+    /* only allocate memory for the pbuf structure */\r
+    p = memp_malloc(MEMP_PBUF);\r
+    if (p == NULL) {\r
+      LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 2, ("pbuf_alloc: Could not allocate MEMP_PBUF for PBUF_%s.\n", flag == PBUF_ROM?"ROM":"REF"));\r
+      return NULL;\r
+    }\r
+    /* caller must set this field properly, afterwards */\r
+    p->payload = NULL;\r
+    p->len = p->tot_len = length;\r
+    p->next = NULL;\r
+    p->flags = (flag == PBUF_ROM? PBUF_FLAG_ROM: PBUF_FLAG_REF);\r
+    break;\r
+  default:\r
+    LWIP_ASSERT("pbuf_alloc: erroneous flag", 0);\r
+    return NULL;\r
+  }\r
+  /* set reference count */\r
+  p->ref = 1;\r
+  LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 3, ("pbuf_alloc(length=%"U16_F") == %p\n", length, (void *)p));\r
+  return p;\r
+}\r
+\r
+\r
+#if PBUF_STATS\r
+#define DEC_PBUF_STATS do { --lwip_stats.pbuf.used; } while (0)\r
+#else /* PBUF_STATS */\r
+#define DEC_PBUF_STATS\r
+#endif /* PBUF_STATS */\r
+\r
+#define PBUF_POOL_FAST_FREE(p)  do {                                    \\r
+                                  p->next = pbuf_pool;                  \\r
+                                  pbuf_pool = p;                        \\r
+                                  DEC_PBUF_STATS;                       \\r
+                                } while (0)\r
+\r
+#if SYS_LIGHTWEIGHT_PROT\r
+#define PBUF_POOL_FREE(p)  do {                                         \\r
+                                SYS_ARCH_DECL_PROTECT(old_level);       \\r
+                                SYS_ARCH_PROTECT(old_level);            \\r
+                                PBUF_POOL_FAST_FREE(p);                 \\r
+                                SYS_ARCH_UNPROTECT(old_level);          \\r
+                               } while (0)\r
+#else /* SYS_LIGHTWEIGHT_PROT */\r
+#define PBUF_POOL_FREE(p)  do {                                         \\r
+                             sys_sem_wait(pbuf_pool_free_sem);          \\r
+                             PBUF_POOL_FAST_FREE(p);                    \\r
+                             sys_sem_signal(pbuf_pool_free_sem);        \\r
+                           } while (0)\r
+#endif /* SYS_LIGHTWEIGHT_PROT */\r
+\r
+/**\r
+ * Shrink a pbuf chain to a desired length.\r
+ *\r
+ * @param p pbuf to shrink.\r
+ * @param new_len desired new length of pbuf chain\r
+ *\r
+ * Depending on the desired length, the first few pbufs in a chain might\r
+ * be skipped and left unchanged. The new last pbuf in the chain will be\r
+ * resized, and any remaining pbufs will be freed.\r
+ *\r
+ * @note If the pbuf is ROM/REF, only the ->tot_len and ->len fields are adjusted.\r
+ * @note May not be called on a packet queue.\r
+ *\r
+ * @bug Cannot grow the size of a pbuf (chain) (yet).\r
+ */\r
+void\r
+pbuf_realloc(struct pbuf *p, u16_t new_len)\r
+{\r
+  struct pbuf *q;\r
+  u16_t rem_len; /* remaining length */\r
+  s16_t grow;\r
+\r
+  LWIP_ASSERT("pbuf_realloc: sane p->flags", p->flags == PBUF_FLAG_POOL ||\r
+              p->flags == PBUF_FLAG_ROM ||\r
+              p->flags == PBUF_FLAG_RAM ||\r
+              p->flags == PBUF_FLAG_REF);\r
+\r
+  /* desired length larger than current length? */\r
+  if (new_len >= p->tot_len) {\r
+    /* enlarging not yet supported */\r
+    return;\r
+  }\r
+\r
+  /* the pbuf chain grows by (new_len - p->tot_len) bytes\r
+   * (which may be negative in case of shrinking) */\r
+  grow = new_len - p->tot_len;\r
+\r
+  /* first, step over any pbufs that should remain in the chain */\r
+  rem_len = new_len;\r
+  q = p;\r
+  /* should this pbuf be kept? */\r
+  while (rem_len > q->len) {\r
+    /* decrease remaining length by pbuf length */\r
+    rem_len -= q->len;\r
+    /* decrease total length indicator */\r
+    q->tot_len += grow;\r
+    /* proceed to next pbuf in chain */\r
+    q = q->next;\r
+  }\r
+  /* we have now reached the new last pbuf (in q) */\r
+  /* rem_len == desired length for pbuf q */\r
+\r
+  /* shrink allocated memory for PBUF_RAM */\r
+  /* (other types merely adjust their length fields */\r
+  if ((q->flags == PBUF_FLAG_RAM) && (rem_len != q->len)) {\r
+    /* reallocate and adjust the length of the pbuf that will be split */\r
+    mem_realloc(q, (u8_t *)q->payload - (u8_t *)q + rem_len);\r
+  }\r
+  /* adjust length fields for new last pbuf */\r
+  q->len = rem_len;\r
+  q->tot_len = q->len;\r
+\r
+  /* any remaining pbufs in chain? */\r
+  if (q->next != NULL) {\r
+    /* free remaining pbufs in chain */\r
+    pbuf_free(q->next);\r
+  }\r
+  /* q is last packet in chain */\r
+  q->next = NULL;\r
+\r
+}\r
+\r
+/**\r
+ * Adjusts the payload pointer to hide or reveal headers in the payload.\r
+ *\r
+ * Adjusts the ->payload pointer so that space for a header\r
+ * (dis)appears in the pbuf payload.\r
+ *\r
+ * The ->payload, ->tot_len and ->len fields are adjusted.\r
+ *\r
+ * @param hdr_size_inc Number of bytes to increment header size which\r
+ * increases the size of the pbuf. New space is on the front.\r
+ * (Using a negative value decreases the header size.)\r
+ * If hdr_size_inc is 0, this function does nothing and returns succesful.\r
+ *\r
+ * PBUF_ROM and PBUF_REF type buffers cannot have their sizes increased, so\r
+ * the call will fail. A check is made that the increase in header size does\r
+ * not move the payload pointer in front of the start of the buffer.\r
+ * @return non-zero on failure, zero on success.\r
+ *\r
+ */\r
+u8_t\r
+pbuf_header(struct pbuf *p, s16_t header_size_increment)\r
+{\r
+  void *payload;\r
+\r
+  LWIP_ASSERT("p != NULL", p != NULL);\r
+  if ((header_size_increment == 0) || (p == NULL)) return 0;\r
\r
+  /* remember current payload pointer */\r
+  payload = p->payload;\r
+\r
+  /* pbuf types containing payloads? */\r
+  if (p->flags == PBUF_FLAG_RAM || p->flags == PBUF_FLAG_POOL) {\r
+    /* set new payload pointer */\r
+    p->payload = (u8_t *)p->payload - header_size_increment;\r
+    /* boundary check fails? */\r
+    if ((u8_t *)p->payload < (u8_t *)p + sizeof(struct pbuf)) {\r
+      LWIP_DEBUGF( PBUF_DEBUG | 2, ("pbuf_header: failed as %p < %p (not enough space for new header size)\n",\r
+        (void *)p->payload,\r
+        (void *)(p + 1)));\\r
+      /* restore old payload pointer */\r
+      p->payload = payload;\r
+      /* bail out unsuccesfully */\r
+      return 1;\r
+    }\r
+  /* pbuf types refering to external payloads? */\r
+  } else if (p->flags == PBUF_FLAG_REF || p->flags == PBUF_FLAG_ROM) {\r
+    /* hide a header in the payload? */\r
+    if ((header_size_increment < 0) && (header_size_increment - p->len <= 0)) {\r
+      /* increase payload pointer */\r
+      p->payload = (u8_t *)p->payload - header_size_increment;\r
+    } else {\r
+      /* cannot expand payload to front (yet!)\r
+       * bail out unsuccesfully */\r
+      return 1;\r
+    }\r
+  }\r
+  /* modify pbuf length fields */\r
+  p->len += header_size_increment;\r
+  p->tot_len += header_size_increment;\r
+\r
+  LWIP_DEBUGF( PBUF_DEBUG, ("pbuf_header: old %p new %p (%"S16_F")\n",\r
+    (void *)payload, (void *)p->payload, header_size_increment));\r
+\r
+  return 0;\r
+}\r
+\r
+/**\r
+ * Dereference a pbuf chain or queue and deallocate any no-longer-used\r
+ * pbufs at the head of this chain or queue.\r
+ *\r
+ * Decrements the pbuf reference count. If it reaches zero, the pbuf is\r
+ * deallocated.\r
+ *\r
+ * For a pbuf chain, this is repeated for each pbuf in the chain,\r
+ * up to the first pbuf which has a non-zero reference count after\r
+ * decrementing. So, when all reference counts are one, the whole\r
+ * chain is free'd.\r
+ *\r
+ * @param pbuf The pbuf (chain) to be dereferenced.\r
+ *\r
+ * @return the number of pbufs that were de-allocated\r
+ * from the head of the chain.\r
+ *\r
+ * @note MUST NOT be called on a packet queue (Not verified to work yet).\r
+ * @note the reference counter of a pbuf equals the number of pointers\r
+ * that refer to the pbuf (or into the pbuf).\r
+ *\r
+ * @internal examples:\r
+ *\r
+ * Assuming existing chains a->b->c with the following reference\r
+ * counts, calling pbuf_free(a) results in:\r
+ * \r
+ * 1->2->3 becomes ...1->3\r
+ * 3->3->3 becomes 2->3->3\r
+ * 1->1->2 becomes ......1\r
+ * 2->1->1 becomes 1->1->1\r
+ * 1->1->1 becomes .......\r
+ *\r
+ */\r
+u8_t\r
+pbuf_free(struct pbuf *p)\r
+{\r
+  struct pbuf *q;\r
+  u8_t count;\r
+  SYS_ARCH_DECL_PROTECT(old_level);\r
+\r
+  LWIP_ASSERT("p != NULL", p != NULL);\r
+  /* if assertions are disabled, proceed with debug output */\r
+  if (p == NULL) {\r
+    LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 2, ("pbuf_free(p == NULL) was called.\n"));\r
+    return 0;\r
+  }\r
+  LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 3, ("pbuf_free(%p)\n", (void *)p));\r
+\r
+  PERF_START;\r
+\r
+  LWIP_ASSERT("pbuf_free: sane flags",\r
+    p->flags == PBUF_FLAG_RAM || p->flags == PBUF_FLAG_ROM ||\r
+    p->flags == PBUF_FLAG_REF || p->flags == PBUF_FLAG_POOL);\r
+\r
+  count = 0;\r
+  /* Since decrementing ref cannot be guaranteed to be a single machine operation\r
+   * we must protect it. Also, the later test of ref must be protected.\r
+   */\r
+  SYS_ARCH_PROTECT(old_level);\r
+  /* de-allocate all consecutive pbufs from the head of the chain that\r
+   * obtain a zero reference count after decrementing*/\r
+  while (p != NULL) {\r
+    /* all pbufs in a chain are referenced at least once */\r
+    LWIP_ASSERT("pbuf_free: p->ref > 0", p->ref > 0);\r
+    /* decrease reference count (number of pointers to pbuf) */\r
+    p->ref--;\r
+    /* this pbuf is no longer referenced to? */\r
+    if (p->ref == 0) {\r
+      /* remember next pbuf in chain for next iteration */\r
+      q = p->next;\r
+      LWIP_DEBUGF( PBUF_DEBUG | 2, ("pbuf_free: deallocating %p\n", (void *)p));\r
+      /* is this a pbuf from the pool? */\r
+      if (p->flags == PBUF_FLAG_POOL) {\r
+        p->len = p->tot_len = PBUF_POOL_BUFSIZE;\r
+        p->payload = (void *)((u8_t *)p + sizeof(struct pbuf));\r
+        PBUF_POOL_FREE(p);\r
+      /* is this a ROM or RAM referencing pbuf? */\r
+      } else if (p->flags == PBUF_FLAG_ROM || p->flags == PBUF_FLAG_REF) {\r
+        memp_free(MEMP_PBUF, p);\r
+      /* p->flags == PBUF_FLAG_RAM */\r
+      } else {\r
+        mem_free(p);\r
+      }\r
+      count++;\r
+      /* proceed to next pbuf */\r
+      p = q;\r
+    /* p->ref > 0, this pbuf is still referenced to */\r
+    /* (and so the remaining pbufs in chain as well) */\r
+    } else {\r
+      LWIP_DEBUGF( PBUF_DEBUG | 2, ("pbuf_free: %p has ref %"U16_F", ending here.\n", (void *)p, (u16_t)p->ref));\r
+      /* stop walking through the chain */\r
+      p = NULL;\r
+    }\r
+  }\r
+  SYS_ARCH_UNPROTECT(old_level);\r
+  PERF_STOP("pbuf_free");\r
+  /* return number of de-allocated pbufs */\r
+  return count;\r
+}\r
+\r
+/**\r
+ * Count number of pbufs in a chain\r
+ *\r
+ * @param p first pbuf of chain\r
+ * @return the number of pbufs in a chain\r
+ */\r
+\r
+u8_t\r
+pbuf_clen(struct pbuf *p)\r
+{\r
+  u8_t len;\r
+\r
+  len = 0;\r
+  while (p != NULL) {\r
+    ++len;\r
+    p = p->next;\r
+  }\r
+  return len;\r
+}\r
+\r
+/**\r
+ * Increment the reference count of the pbuf.\r
+ *\r
+ * @param p pbuf to increase reference counter of\r
+ *\r
+ */\r
+void\r
+pbuf_ref(struct pbuf *p)\r
+{\r
+  SYS_ARCH_DECL_PROTECT(old_level);\r
+  /* pbuf given? */\r
+  if (p != NULL) {\r
+    SYS_ARCH_PROTECT(old_level);\r
+    ++(p->ref);\r
+    SYS_ARCH_UNPROTECT(old_level);\r
+  }\r
+}\r
+\r
+/**\r
+ * Concatenate two pbufs (each may be a pbuf chain) and take over\r
+ * the caller's reference of the tail pbuf.\r
+ * \r
+ * @note The caller MAY NOT reference the tail pbuf afterwards.\r
+ * Use pbuf_chain() for that purpose.\r
+ * \r
+ * @see pbuf_chain()\r
+ */\r
+\r
+void\r
+pbuf_cat(struct pbuf *h, struct pbuf *t)\r
+{\r
+  struct pbuf *p;\r
+\r
+  LWIP_ASSERT("h != NULL (programmer violates API)", h != NULL);\r
+  LWIP_ASSERT("t != NULL (programmer violates API)", t != NULL);\r
+  if ((h == NULL) || (t == NULL)) return;\r
+\r
+  /* proceed to last pbuf of chain */\r
+  for (p = h; p->next != NULL; p = p->next) {\r
+    /* add total length of second chain to all totals of first chain */\r
+    p->tot_len += t->tot_len;\r
+  }\r
+  /* { p is last pbuf of first h chain, p->next == NULL } */\r
+  LWIP_ASSERT("p->tot_len == p->len (of last pbuf in chain)", p->tot_len == p->len);\r
+  LWIP_ASSERT("p->next == NULL", p->next == NULL);\r
+  /* add total length of second chain to last pbuf total of first chain */\r
+  p->tot_len += t->tot_len;\r
+  /* chain last pbuf of head (p) with first of tail (t) */\r
+  p->next = t;\r
+  /* p->next now references t, but the caller will drop its reference to t,\r
+   * so netto there is no change to the reference count of t.\r
+   */\r
+}\r
+\r
+/**\r
+ * Chain two pbufs (or pbuf chains) together.\r
+ * \r
+ * The caller MUST call pbuf_free(t) once it has stopped\r
+ * using it. Use pbuf_cat() instead if you no longer use t.\r
+ * \r
+ * @param h head pbuf (chain)\r
+ * @param t tail pbuf (chain)\r
+ * @note The pbufs MUST belong to the same packet.\r
+ * @note MAY NOT be called on a packet queue.\r
+ *\r
+ * The ->tot_len fields of all pbufs of the head chain are adjusted.\r
+ * The ->next field of the last pbuf of the head chain is adjusted.\r
+ * The ->ref field of the first pbuf of the tail chain is adjusted.\r
+ *\r
+ */\r
+void\r
+pbuf_chain(struct pbuf *h, struct pbuf *t)\r
+{\r
+  pbuf_cat(h, t);\r
+  /* t is now referenced by h */\r
+  pbuf_ref(t);\r
+  LWIP_DEBUGF(PBUF_DEBUG | DBG_FRESH | 2, ("pbuf_chain: %p references %p\n", (void *)h, (void *)t));\r
+}\r
+\r
+/* For packet queueing. Note that queued packets MUST be dequeued first\r
+ * using pbuf_dequeue() before calling other pbuf_() functions. */\r
+#if ARP_QUEUEING\r
+/**\r
+ * Add a packet to the end of a queue.\r
+ *\r
+ * @param q pointer to first packet on the queue\r
+ * @param n packet to be queued\r
+ *\r
+ * Both packets MUST be given, and must be different.\r
+ */\r
+void\r
+pbuf_queue(struct pbuf *p, struct pbuf *n)\r
+{\r
+#if PBUF_DEBUG /* remember head of queue */\r
+  struct pbuf *q = p;\r
+#endif\r
+  /* programmer stupidity checks */\r
+  LWIP_ASSERT("p == NULL in pbuf_queue: this indicates a programmer error\n", p != NULL);\r
+  LWIP_ASSERT("n == NULL in pbuf_queue: this indicates a programmer error\n", n != NULL);\r
+  LWIP_ASSERT("p == n in pbuf_queue: this indicates a programmer error\n", p != n);\r
+  if ((p == NULL) || (n == NULL) || (p == n)){\r
+    LWIP_DEBUGF(PBUF_DEBUG | DBG_HALT | 3, ("pbuf_queue: programmer argument error\n"));\r
+    return;\r
+  }\r
+\r
+  /* iterate through all packets on queue */\r
+  while (p->next != NULL) {\r
+/* be very picky about pbuf chain correctness */\r
+#if PBUF_DEBUG\r
+    /* iterate through all pbufs in packet */\r
+    while (p->tot_len != p->len) {\r
+      /* make sure invariant condition holds */\r
+      LWIP_ASSERT("p->len < p->tot_len", p->len < p->tot_len);\r
+      /* make sure each packet is complete */\r
+      LWIP_ASSERT("p->next != NULL", p->next != NULL);\r
+      p = p->next;\r
+      /* { p->tot_len == p->len => p is last pbuf of a packet } */\r
+    }\r
+    /* { p is last pbuf of a packet } */\r
+    /* proceed to next packet on queue */\r
+#endif\r
+    /* proceed to next pbuf */\r
+    if (p->next != NULL) p = p->next;\r
+  }\r
+  /* { p->tot_len == p->len and p->next == NULL } ==>\r
+   * { p is last pbuf of last packet on queue } */\r
+  /* chain last pbuf of queue with n */\r
+  p->next = n;\r
+  /* n is now referenced to by the (packet p in the) queue */\r
+  pbuf_ref(n);\r
+#if PBUF_DEBUG\r
+  LWIP_DEBUGF(PBUF_DEBUG | DBG_FRESH | 2,\r
+    ("pbuf_queue: newly queued packet %p sits after packet %p in queue %p\n",\r
+    (void *)n, (void *)p, (void *)q));\r
+#endif\r
+}\r
+\r
+/**\r
+ * Remove a packet from the head of a queue.\r
+ *\r
+ * The caller MUST reference the remainder of the queue (as returned). The\r
+ * caller MUST NOT call pbuf_ref() as it implicitly takes over the reference\r
+ * from p.\r
+ * \r
+ * @param p pointer to first packet on the queue which will be dequeued.\r
+ * @return first packet on the remaining queue (NULL if no further packets).\r
+ *\r
+ */\r
+struct pbuf *\r
+pbuf_dequeue(struct pbuf *p)\r
+{\r
+  struct pbuf *q;\r
+  LWIP_ASSERT("p != NULL", p != NULL);\r
+\r
+  /* iterate through all pbufs in packet p */\r
+  while (p->tot_len != p->len) {\r
+    /* make sure invariant condition holds */\r
+    LWIP_ASSERT("p->len < p->tot_len", p->len < p->tot_len);\r
+    /* make sure each packet is complete */\r
+    LWIP_ASSERT("p->next != NULL", p->next != NULL);\r
+    p = p->next;\r
+  }\r
+  /* { p->tot_len == p->len } => p is the last pbuf of the first packet */\r
+  /* remember next packet on queue in q */\r
+  q = p->next;\r
+  /* dequeue packet p from queue */\r
+  p->next = NULL;\r
+  /* any next packet on queue? */\r
+  if (q != NULL) {\r
+    /* although q is no longer referenced by p, it MUST be referenced by\r
+     * the caller, who is maintaining this packet queue. So, we do not call\r
+     * pbuf_free(q) here, resulting in an implicit pbuf_ref(q) for the caller. */\r
+    LWIP_DEBUGF(PBUF_DEBUG | DBG_FRESH | 2, ("pbuf_dequeue: first remaining packet on queue is %p\n", (void *)q));\r
+  } else {\r
+    LWIP_DEBUGF(PBUF_DEBUG | DBG_FRESH | 2, ("pbuf_dequeue: no further packets on queue\n"));\r
+  }\r
+  return q;\r
+}\r
+#endif\r
+\r
+/**\r
+ *\r
+ * Create PBUF_POOL (or PBUF_RAM) copies of PBUF_REF pbufs.\r
+ *\r
+ * Used to queue packets on behalf of the lwIP stack, such as\r
+ * ARP based queueing.\r
+ *\r
+ * Go through a pbuf chain and replace any PBUF_REF buffers\r
+ * with PBUF_POOL (or PBUF_RAM) pbufs, each taking a copy of\r
+ * the referenced data.\r
+ *\r
+ * @note You MUST explicitly use p = pbuf_take(p);\r
+ * The pbuf you give as argument, may have been replaced\r
+ * by a (differently located) copy through pbuf_take()!\r
+ *\r
+ * @note Any replaced pbufs will be freed through pbuf_free().\r
+ * This may deallocate them if they become no longer referenced.\r
+ *\r
+ * @param p Head of pbuf chain to process\r
+ *\r
+ * @return Pointer to head of pbuf chain\r
+ */\r
+struct pbuf *\r
+pbuf_take(struct pbuf *p)\r
+{\r
+  struct pbuf *q , *prev, *head;\r
+  LWIP_ASSERT("pbuf_take: p != NULL\n", p != NULL);\r
+  LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 3, ("pbuf_take(%p)\n", (void*)p));\r
+\r
+  prev = NULL;\r
+  head = p;\r
+  /* iterate through pbuf chain */\r
+  do\r
+  {\r
+    /* pbuf is of type PBUF_REF? */\r
+    if (p->flags == PBUF_FLAG_REF) {\r
+      LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE, ("pbuf_take: encountered PBUF_REF %p\n", (void *)p));\r
+      /* allocate a pbuf (w/ payload) fully in RAM */\r
+      /* PBUF_POOL buffers are faster if we can use them */\r
+      if (p->len <= PBUF_POOL_BUFSIZE) {\r
+        q = pbuf_alloc(PBUF_RAW, p->len, PBUF_POOL);\r
+        if (q == NULL) {\r
+          LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 2, ("pbuf_take: Could not allocate PBUF_POOL\n"));\r
+        }\r
+      } else {\r
+        /* no replacement pbuf yet */\r
+        q = NULL;\r
+        LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 2, ("pbuf_take: PBUF_POOL too small to replace PBUF_REF\n"));\r
+      }\r
+      /* no (large enough) PBUF_POOL was available? retry with PBUF_RAM */\r
+      if (q == NULL) {\r
+        q = pbuf_alloc(PBUF_RAW, p->len, PBUF_RAM);\r
+        if (q == NULL) {\r
+          LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 2, ("pbuf_take: Could not allocate PBUF_RAM\n"));\r
+        }\r
+      }\r
+      /* replacement pbuf could be allocated? */\r
+      if (q != NULL)\r
+      {\r
+        /* copy p to q */\r
+        /* copy successor */\r
+        q->next = p->next;\r
+        /* remove linkage from original pbuf */\r
+        p->next = NULL;\r
+        /* remove linkage to original pbuf */\r
+        if (prev != NULL) {\r
+          /* prev->next == p at this point */\r
+          LWIP_ASSERT("prev->next == p", prev->next == p);\r
+          /* break chain and insert new pbuf instead */\r
+          prev->next = q;\r
+        /* prev == NULL, so we replaced the head pbuf of the chain */\r
+        } else {\r
+          head = q;\r
+        }\r
+        /* copy pbuf payload */\r
+        memcpy(q->payload, p->payload, p->len);\r
+        q->tot_len = p->tot_len;\r
+        q->len = p->len;\r
+        /* in case p was the first pbuf, it is no longer refered to by\r
+         * our caller, as the caller MUST do p = pbuf_take(p);\r
+         * in case p was not the first pbuf, it is no longer refered to\r
+         * by prev. we can safely free the pbuf here.\r
+         * (note that we have set p->next to NULL already so that\r
+         * we will not free the rest of the chain by accident.)\r
+         */\r
+        pbuf_free(p);\r
+        /* do not copy ref, since someone else might be using the old buffer */\r
+        LWIP_DEBUGF(PBUF_DEBUG, ("pbuf_take: replaced PBUF_REF %p with %p\n", (void *)p, (void *)q));\r
+        p = q;\r
+      } else {\r
+        /* deallocate chain */\r
+        pbuf_free(head);\r
+        LWIP_DEBUGF(PBUF_DEBUG | 2, ("pbuf_take: failed to allocate replacement pbuf for %p\n", (void *)p));\r
+        return NULL;\r
+      }\r
+    /* p->flags != PBUF_FLAG_REF */\r
+    } else {\r
+      LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 1, ("pbuf_take: skipping pbuf not of type PBUF_REF\n"));\r
+    }\r
+    /* remember this pbuf */\r
+    prev = p;\r
+    /* proceed to next pbuf in original chain */\r
+    p = p->next;\r
+  } while (p);\r
+  LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 1, ("pbuf_take: end of chain reached.\n"));\r
+\r
+  return head;\r
+}\r
+\r
+/**\r
+ * Dechains the first pbuf from its succeeding pbufs in the chain.\r
+ *\r
+ * Makes p->tot_len field equal to p->len.\r
+ * @param p pbuf to dechain\r
+ * @return remainder of the pbuf chain, or NULL if it was de-allocated.\r
+ * @note May not be called on a packet queue.\r
+ */\r
+struct pbuf *\r
+pbuf_dechain(struct pbuf *p)\r
+{\r
+  struct pbuf *q;\r
+  u8_t tail_gone = 1;\r
+  /* tail */\r
+  q = p->next;\r
+  /* pbuf has successor in chain? */\r
+  if (q != NULL) {\r
+    /* assert tot_len invariant: (p->tot_len == p->len + (p->next? p->next->tot_len: 0) */\r
+    LWIP_ASSERT("p->tot_len == p->len + q->tot_len", q->tot_len == p->tot_len - p->len);\r
+    /* enforce invariant if assertion is disabled */\r
+    q->tot_len = p->tot_len - p->len;\r
+    /* decouple pbuf from remainder */\r
+    p->next = NULL;\r
+    /* total length of pbuf p is its own length only */\r
+    p->tot_len = p->len;\r
+    /* q is no longer referenced by p, free it */\r
+    LWIP_DEBUGF(PBUF_DEBUG | DBG_STATE, ("pbuf_dechain: unreferencing %p\n", (void *)q));\r
+    tail_gone = pbuf_free(q);\r
+    if (tail_gone > 0) {\r
+      LWIP_DEBUGF(PBUF_DEBUG | DBG_STATE,\r
+                  ("pbuf_dechain: deallocated %p (as it is no longer referenced)\n", (void *)q));\r
+    }\r
+    /* return remaining tail or NULL if deallocated */\r
+  }\r
+  /* assert tot_len invariant: (p->tot_len == p->len + (p->next? p->next->tot_len: 0) */\r
+  LWIP_ASSERT("p->tot_len == p->len", p->tot_len == p->len);\r
+  return (tail_gone > 0? NULL: q);\r
+}\r
index 30199804dc1015feb65caf175dda97f99e5f0f63..b0e18b015229c5e6d035ecd0c2b195a15ba34945 100644 (file)
-/**
- * @file
- * 
- * Implementation of raw protocol PCBs for low-level handling of
- * different types of protocols besides (or overriding) those
- * already available in lwIP.
- *
- */
-/*
- * 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 <adam@sics.se>
- *
- */
-
-#include <string.h>
-
-#include "lwip/opt.h"
-
-#include "lwip/def.h"
-#include "lwip/memp.h"
-#include "lwip/inet.h"
-#include "lwip/ip_addr.h"
-#include "lwip/netif.h"
-#include "lwip/raw.h"
-
-#include "lwip/stats.h"
-
-#include "arch/perf.h"
-#include "lwip/snmp.h"
-
-#if LWIP_RAW
-
-/** The list of RAW PCBs */
-static struct raw_pcb *raw_pcbs = NULL;
-
-void
-raw_init(void)
-{
-  raw_pcbs = NULL;
-}
-
-/**
- * Determine if in incoming IP packet is covered by a RAW PCB
- * and if so, pass it to a user-provided receive callback function.
- *
- * Given an incoming IP datagram (as a chain of pbufs) this function
- * finds a corresponding RAW PCB and calls the corresponding receive
- * callback function.
- *
- * @param pbuf pbuf to be demultiplexed to a RAW PCB.
- * @param netif network interface on which the datagram was received.
- * @Return - 1 if the packet has been eaten by a RAW PCB receive
- *           callback function. The caller MAY NOT not reference the
- *           packet any longer, and MAY NOT call pbuf_free().
- * @return - 0 if packet is not eaten (pbuf is still referenced by the
- *           caller).
- *
- */
-u8_t
-raw_input(struct pbuf *p, struct netif *inp)
-{
-  struct raw_pcb *pcb;
-  struct ip_hdr *iphdr;
-  s16_t proto;
-  u8_t eaten = 0;
-
-  iphdr = p->payload;
-  proto = IPH_PROTO(iphdr);
-
-  pcb = raw_pcbs;
-  /* loop through all raw pcbs until the packet is eaten by one */
-  /* this allows multiple pcbs to match against the packet by design */
-  while ((eaten == 0) && (pcb != NULL)) {
-    if (pcb->protocol == proto) {
-      /* receive callback function available? */
-      if (pcb->recv != NULL) {
-        /* the receive callback function did not eat the packet? */
-        if (pcb->recv(pcb->recv_arg, pcb, p, &(iphdr->src)) != 0)
-        {
-          /* receive function ate the packet */
-          p = NULL;
-          eaten = 1;
-        }
-      }
-      /* no receive callback function was set for this raw PCB */
-      /* drop the packet */
-    }
-    pcb = pcb->next;
-  }
-  return eaten;
-}
-
-/**
- * Bind a RAW PCB.
- *
- * @param pcb RAW PCB to be bound with a local address ipaddr.
- * @param ipaddr local IP address to bind with. Use IP_ADDR_ANY to
- * bind to all local interfaces.
- *
- * @return lwIP error code.
- * - ERR_OK. Successful. No error occured.
- * - ERR_USE. The specified IP address is already bound to by
- * another RAW PCB.
- *
- * @see raw_disconnect()
- */
-err_t
-raw_bind(struct raw_pcb *pcb, struct ip_addr *ipaddr)
-{
-  ip_addr_set(&pcb->local_ip, ipaddr);
-  return ERR_OK;
-}
-
-/**
- * Connect an RAW PCB. This function is required by upper layers
- * of lwip. Using the raw api you could use raw_sendto() instead
- *
- * This will associate the RAW PCB with the remote address.
- *
- * @param pcb RAW PCB to be connected with remote address ipaddr and port.
- * @param ipaddr remote IP address to connect with.
- *
- * @return lwIP error code
- *
- * @see raw_disconnect() and raw_sendto()
- */
-err_t
-raw_connect(struct raw_pcb *pcb, struct ip_addr *ipaddr)
-{
-  ip_addr_set(&pcb->remote_ip, ipaddr);
-  return ERR_OK;
-}
-
-
-/**
- * Set the callback function for received packets that match the
- * raw PCB's protocol and binding. 
- * 
- * The callback function MUST either
- * - eat the packet by calling pbuf_free() and returning non-zero. The
- *   packet will not be passed to other raw PCBs or other protocol layers.
- * - not free the packet, and return zero. The packet will be matched
- *   against further PCBs and/or forwarded to another protocol layers.
- * 
- * @return non-zero if the packet was free()d, zero if the packet remains
- * available for others.
- */
-void
-raw_recv(struct raw_pcb *pcb,
-         u8_t (* recv)(void *arg, struct raw_pcb *upcb, struct pbuf *p,
-                      struct ip_addr *addr),
-         void *recv_arg)
-{
-  /* remember recv() callback and user data */
-  pcb->recv = recv;
-  pcb->recv_arg = recv_arg;
-}
-
-/**
- * Send the raw IP packet to the given address. Note that actually you cannot
- * modify the IP headers (this is inconsistent with the receive callback where
- * you actually get the IP headers), you can only specify the IP payload here.
- * It requires some more changes in lwIP. (there will be a raw_send() function
- * then.)
- *
- * @param pcb the raw pcb which to send
- * @param p the IP payload to send
- * @param ipaddr the destination address of the IP packet
- *
- */
-err_t
-raw_sendto(struct raw_pcb *pcb, struct pbuf *p, struct ip_addr *ipaddr)
-{
-  err_t err;
-  struct netif *netif;
-  struct ip_addr *src_ip;
-  struct pbuf *q; /* q will be sent down the stack */
-  
-  LWIP_DEBUGF(RAW_DEBUG | DBG_TRACE | 3, ("raw_sendto\n"));
-  
-  /* not enough space to add an IP header to first pbuf in given p chain? */
-  if (pbuf_header(p, IP_HLEN)) {
-    /* allocate header in new pbuf */
-    q = pbuf_alloc(PBUF_IP, 0, PBUF_RAM);
-    /* new header pbuf could not be allocated? */
-    if (q == NULL) {
-      LWIP_DEBUGF(RAW_DEBUG | DBG_TRACE | 2, ("raw_sendto: could not allocate header\n"));
-      return ERR_MEM;
-    }
-    /* chain header q in front of given pbuf p */
-    pbuf_chain(q, p);
-    /* { first pbuf q points to header pbuf } */
-    LWIP_DEBUGF(RAW_DEBUG, ("raw_sendto: added header pbuf %p before given pbuf %p\n", (void *)q, (void *)p));
-  }  else {
-    /* first pbuf q equals given pbuf */
-    q = p;
-    pbuf_header(q, -IP_HLEN);
-  }
-  
-  if ((netif = ip_route(ipaddr)) == NULL) {
-    LWIP_DEBUGF(RAW_DEBUG | 1, ("raw_sendto: No route to 0x%"X32_F"\n", ipaddr->addr));
-#if RAW_STATS
-    /*    ++lwip_stats.raw.rterr;*/
-#endif /* RAW_STATS */
-    /* free any temporary header pbuf allocated by pbuf_header() */
-    if (q != p) {
-      pbuf_free(q);
-    }
-    return ERR_RTE;
-  }
-
-  if (ip_addr_isany(&pcb->local_ip)) {
-    /* use outgoing network interface IP address as source address */
-    src_ip = &(netif->ip_addr);
-  } else {
-    /* use RAW PCB local IP address as source address */
-    src_ip = &(pcb->local_ip);
-  }
-
-  err = ip_output_if (q, src_ip, ipaddr, pcb->ttl, pcb->tos, pcb->protocol, netif);
-
-  /* did we chain a header earlier? */
-  if (q != p) {
-    /* free the header */
-    pbuf_free(q);
-  }
-  return err;
-}
-
-/**
- * Send the raw IP packet to the address given by raw_connect()
- *
- * @param pcb the raw pcb which to send
- * @param p the IP payload to send
- * @param ipaddr the destination address of the IP packet
- *
- */
-err_t
-raw_send(struct raw_pcb *pcb, struct pbuf *p)
-{
-  return raw_sendto(pcb, p, &pcb->remote_ip);
-}
-
-/**
- * Remove an RAW PCB.
- *
- * @param pcb RAW PCB to be removed. The PCB is removed from the list of
- * RAW PCB's and the data structure is freed from memory.
- *
- * @see raw_new()
- */
-void
-raw_remove(struct raw_pcb *pcb)
-{
-  struct raw_pcb *pcb2;
-  /* pcb to be removed is first in list? */
-  if (raw_pcbs == pcb) {
-    /* make list start at 2nd pcb */
-    raw_pcbs = raw_pcbs->next;
-    /* pcb not 1st in list */
-  } else for(pcb2 = raw_pcbs; pcb2 != NULL; pcb2 = pcb2->next) {
-    /* find pcb in raw_pcbs list */
-    if (pcb2->next != NULL && pcb2->next == pcb) {
-      /* remove pcb from list */
-      pcb2->next = pcb->next;
-    }
-  }
-  memp_free(MEMP_RAW_PCB, pcb);
-}
-
-/**
- * Create a RAW PCB.
- *
- * @return The RAW PCB which was created. NULL if the PCB data structure
- * could not be allocated.
- *
- * @param proto the protocol number of the IPs payload (e.g. IP_PROTO_ICMP)
- *
- * @see raw_remove()
- */
-struct raw_pcb *
-raw_new(u16_t proto) {
-  struct raw_pcb *pcb;
-
-  LWIP_DEBUGF(RAW_DEBUG | DBG_TRACE | 3, ("raw_new\n"));
-
-  pcb = memp_malloc(MEMP_RAW_PCB);
-  /* could allocate RAW PCB? */
-  if (pcb != NULL) {
-    /* initialize PCB to all zeroes */
-    memset(pcb, 0, sizeof(struct raw_pcb));
-    pcb->protocol = proto;
-    pcb->ttl = RAW_TTL;
-    pcb->next = raw_pcbs;
-    raw_pcbs = pcb;
-  }
-  return pcb;
-}
-
-#endif /* LWIP_RAW */
+/**\r
+ * @file\r
+ * \r
+ * Implementation of raw protocol PCBs for low-level handling of\r
+ * different types of protocols besides (or overriding) those\r
+ * already available in lwIP.\r
+ *\r
+ */\r
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without modification,\r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED\r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT\r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY\r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ *\r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+\r
+#include <string.h>\r
+\r
+#include "lwip/opt.h"\r
+\r
+#include "lwip/def.h"\r
+#include "lwip/memp.h"\r
+#include "lwip/inet.h"\r
+#include "lwip/ip_addr.h"\r
+#include "lwip/netif.h"\r
+#include "lwip/raw.h"\r
+\r
+#include "lwip/stats.h"\r
+\r
+#include "arch/perf.h"\r
+#include "lwip/snmp.h"\r
+\r
+#if LWIP_RAW\r
+\r
+/** The list of RAW PCBs */\r
+static struct raw_pcb *raw_pcbs = NULL;\r
+\r
+void\r
+raw_init(void)\r
+{\r
+  raw_pcbs = NULL;\r
+}\r
+\r
+/**\r
+ * Determine if in incoming IP packet is covered by a RAW PCB\r
+ * and if so, pass it to a user-provided receive callback function.\r
+ *\r
+ * Given an incoming IP datagram (as a chain of pbufs) this function\r
+ * finds a corresponding RAW PCB and calls the corresponding receive\r
+ * callback function.\r
+ *\r
+ * @param pbuf pbuf to be demultiplexed to a RAW PCB.\r
+ * @param netif network interface on which the datagram was received.\r
+ * @Return - 1 if the packet has been eaten by a RAW PCB receive\r
+ *           callback function. The caller MAY NOT not reference the\r
+ *           packet any longer, and MAY NOT call pbuf_free().\r
+ * @return - 0 if packet is not eaten (pbuf is still referenced by the\r
+ *           caller).\r
+ *\r
+ */\r
+u8_t\r
+raw_input(struct pbuf *p, struct netif *inp)\r
+{\r
+  struct raw_pcb *pcb;\r
+  struct ip_hdr *iphdr;\r
+  s16_t proto;\r
+  u8_t eaten = 0;\r
+\r
+  iphdr = p->payload;\r
+  proto = IPH_PROTO(iphdr);\r
+\r
+  pcb = raw_pcbs;\r
+  /* loop through all raw pcbs until the packet is eaten by one */\r
+  /* this allows multiple pcbs to match against the packet by design */\r
+  while ((eaten == 0) && (pcb != NULL)) {\r
+    if (pcb->protocol == proto) {\r
+      /* receive callback function available? */\r
+      if (pcb->recv != NULL) {\r
+        /* the receive callback function did not eat the packet? */\r
+        if (pcb->recv(pcb->recv_arg, pcb, p, &(iphdr->src)) != 0)\r
+        {\r
+          /* receive function ate the packet */\r
+          p = NULL;\r
+          eaten = 1;\r
+        }\r
+      }\r
+      /* no receive callback function was set for this raw PCB */\r
+      /* drop the packet */\r
+    }\r
+    pcb = pcb->next;\r
+  }\r
+  return eaten;\r
+}\r
+\r
+/**\r
+ * Bind a RAW PCB.\r
+ *\r
+ * @param pcb RAW PCB to be bound with a local address ipaddr.\r
+ * @param ipaddr local IP address to bind with. Use IP_ADDR_ANY to\r
+ * bind to all local interfaces.\r
+ *\r
+ * @return lwIP error code.\r
+ * - ERR_OK. Successful. No error occured.\r
+ * - ERR_USE. The specified IP address is already bound to by\r
+ * another RAW PCB.\r
+ *\r
+ * @see raw_disconnect()\r
+ */\r
+err_t\r
+raw_bind(struct raw_pcb *pcb, struct ip_addr *ipaddr)\r
+{\r
+  ip_addr_set(&pcb->local_ip, ipaddr);\r
+  return ERR_OK;\r
+}\r
+\r
+/**\r
+ * Connect an RAW PCB. This function is required by upper layers\r
+ * of lwip. Using the raw api you could use raw_sendto() instead\r
+ *\r
+ * This will associate the RAW PCB with the remote address.\r
+ *\r
+ * @param pcb RAW PCB to be connected with remote address ipaddr and port.\r
+ * @param ipaddr remote IP address to connect with.\r
+ *\r
+ * @return lwIP error code\r
+ *\r
+ * @see raw_disconnect() and raw_sendto()\r
+ */\r
+err_t\r
+raw_connect(struct raw_pcb *pcb, struct ip_addr *ipaddr)\r
+{\r
+  ip_addr_set(&pcb->remote_ip, ipaddr);\r
+  return ERR_OK;\r
+}\r
+\r
+\r
+/**\r
+ * Set the callback function for received packets that match the\r
+ * raw PCB's protocol and binding. \r
+ * \r
+ * The callback function MUST either\r
+ * - eat the packet by calling pbuf_free() and returning non-zero. The\r
+ *   packet will not be passed to other raw PCBs or other protocol layers.\r
+ * - not free the packet, and return zero. The packet will be matched\r
+ *   against further PCBs and/or forwarded to another protocol layers.\r
+ * \r
+ * @return non-zero if the packet was free()d, zero if the packet remains\r
+ * available for others.\r
+ */\r
+void\r
+raw_recv(struct raw_pcb *pcb,\r
+         u8_t (* recv)(void *arg, struct raw_pcb *upcb, struct pbuf *p,\r
+                      struct ip_addr *addr),\r
+         void *recv_arg)\r
+{\r
+  /* remember recv() callback and user data */\r
+  pcb->recv = recv;\r
+  pcb->recv_arg = recv_arg;\r
+}\r
+\r
+/**\r
+ * Send the raw IP packet to the given address. Note that actually you cannot\r
+ * modify the IP headers (this is inconsistent with the receive callback where\r
+ * you actually get the IP headers), you can only specify the IP payload here.\r
+ * It requires some more changes in lwIP. (there will be a raw_send() function\r
+ * then.)\r
+ *\r
+ * @param pcb the raw pcb which to send\r
+ * @param p the IP payload to send\r
+ * @param ipaddr the destination address of the IP packet\r
+ *\r
+ */\r
+err_t\r
+raw_sendto(struct raw_pcb *pcb, struct pbuf *p, struct ip_addr *ipaddr)\r
+{\r
+  err_t err;\r
+  struct netif *netif;\r
+  struct ip_addr *src_ip;\r
+  struct pbuf *q; /* q will be sent down the stack */\r
+  \r
+  LWIP_DEBUGF(RAW_DEBUG | DBG_TRACE | 3, ("raw_sendto\n"));\r
+  \r
+  /* not enough space to add an IP header to first pbuf in given p chain? */\r
+  if (pbuf_header(p, IP_HLEN)) {\r
+    /* allocate header in new pbuf */\r
+    q = pbuf_alloc(PBUF_IP, 0, PBUF_RAM);\r
+    /* new header pbuf could not be allocated? */\r
+    if (q == NULL) {\r
+      LWIP_DEBUGF(RAW_DEBUG | DBG_TRACE | 2, ("raw_sendto: could not allocate header\n"));\r
+      return ERR_MEM;\r
+    }\r
+    /* chain header q in front of given pbuf p */\r
+    pbuf_chain(q, p);\r
+    /* { first pbuf q points to header pbuf } */\r
+    LWIP_DEBUGF(RAW_DEBUG, ("raw_sendto: added header pbuf %p before given pbuf %p\n", (void *)q, (void *)p));\r
+  }  else {\r
+    /* first pbuf q equals given pbuf */\r
+    q = p;\r
+    pbuf_header(q, -IP_HLEN);\r
+  }\r
+  \r
+  if ((netif = ip_route(ipaddr)) == NULL) {\r
+    LWIP_DEBUGF(RAW_DEBUG | 1, ("raw_sendto: No route to 0x%"X32_F"\n", ipaddr->addr));\r
+#if RAW_STATS\r
+    /*    ++lwip_stats.raw.rterr;*/\r
+#endif /* RAW_STATS */\r
+    /* free any temporary header pbuf allocated by pbuf_header() */\r
+    if (q != p) {\r
+      pbuf_free(q);\r
+    }\r
+    return ERR_RTE;\r
+  }\r
+\r
+  if (ip_addr_isany(&pcb->local_ip)) {\r
+    /* use outgoing network interface IP address as source address */\r
+    src_ip = &(netif->ip_addr);\r
+  } else {\r
+    /* use RAW PCB local IP address as source address */\r
+    src_ip = &(pcb->local_ip);\r
+  }\r
+\r
+  err = ip_output_if (q, src_ip, ipaddr, pcb->ttl, pcb->tos, pcb->protocol, netif);\r
+\r
+  /* did we chain a header earlier? */\r
+  if (q != p) {\r
+    /* free the header */\r
+    pbuf_free(q);\r
+  }\r
+  return err;\r
+}\r
+\r
+/**\r
+ * Send the raw IP packet to the address given by raw_connect()\r
+ *\r
+ * @param pcb the raw pcb which to send\r
+ * @param p the IP payload to send\r
+ * @param ipaddr the destination address of the IP packet\r
+ *\r
+ */\r
+err_t\r
+raw_send(struct raw_pcb *pcb, struct pbuf *p)\r
+{\r
+  return raw_sendto(pcb, p, &pcb->remote_ip);\r
+}\r
+\r
+/**\r
+ * Remove an RAW PCB.\r
+ *\r
+ * @param pcb RAW PCB to be removed. The PCB is removed from the list of\r
+ * RAW PCB's and the data structure is freed from memory.\r
+ *\r
+ * @see raw_new()\r
+ */\r
+void\r
+raw_remove(struct raw_pcb *pcb)\r
+{\r
+  struct raw_pcb *pcb2;\r
+  /* pcb to be removed is first in list? */\r
+  if (raw_pcbs == pcb) {\r
+    /* make list start at 2nd pcb */\r
+    raw_pcbs = raw_pcbs->next;\r
+    /* pcb not 1st in list */\r
+  } else for(pcb2 = raw_pcbs; pcb2 != NULL; pcb2 = pcb2->next) {\r
+    /* find pcb in raw_pcbs list */\r
+    if (pcb2->next != NULL && pcb2->next == pcb) {\r
+      /* remove pcb from list */\r
+      pcb2->next = pcb->next;\r
+    }\r
+  }\r
+  memp_free(MEMP_RAW_PCB, pcb);\r
+}\r
+\r
+/**\r
+ * Create a RAW PCB.\r
+ *\r
+ * @return The RAW PCB which was created. NULL if the PCB data structure\r
+ * could not be allocated.\r
+ *\r
+ * @param proto the protocol number of the IPs payload (e.g. IP_PROTO_ICMP)\r
+ *\r
+ * @see raw_remove()\r
+ */\r
+struct raw_pcb *\r
+raw_new(u16_t proto) {\r
+  struct raw_pcb *pcb;\r
+\r
+  LWIP_DEBUGF(RAW_DEBUG | DBG_TRACE | 3, ("raw_new\n"));\r
+\r
+  pcb = memp_malloc(MEMP_RAW_PCB);\r
+  /* could allocate RAW PCB? */\r
+  if (pcb != NULL) {\r
+    /* initialize PCB to all zeroes */\r
+    memset(pcb, 0, sizeof(struct raw_pcb));\r
+    pcb->protocol = proto;\r
+    pcb->ttl = RAW_TTL;\r
+    pcb->next = raw_pcbs;\r
+    raw_pcbs = pcb;\r
+  }\r
+  return pcb;\r
+}\r
+\r
+#endif /* LWIP_RAW */\r
index c94623f7a895d585e793f075ca397e69fad768a5..1488781863676a74231fba638856ce3fd3f0501b 100644 (file)
-/*
- * 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 <adam@sics.se>
- *
- */
-
-#include <string.h>
-
-#include "lwip/opt.h"
-
-#include "lwip/def.h"
-
-#include "lwip/stats.h"
-#include "lwip/mem.h"
-
-
-#if LWIP_STATS
-struct stats_ lwip_stats;
-
-void
-stats_init(void)
-{
-  memset(&lwip_stats, 0, sizeof(struct stats_));
-}
-#if LWIP_STATS_DISPLAY
-void
-stats_display_proto(struct stats_proto *proto, char *name)
-{
-  LWIP_PLATFORM_DIAG(("\n%s\n\t", name));
-  LWIP_PLATFORM_DIAG(("xmit: %"S16_F"\n\t", proto->xmit)); 
-  LWIP_PLATFORM_DIAG(("rexmit: %"S16_F"\n\t", proto->rexmit)); 
-  LWIP_PLATFORM_DIAG(("recv: %"S16_F"\n\t", proto->recv)); 
-  LWIP_PLATFORM_DIAG(("fw: %"S16_F"\n\t", proto->fw)); 
-  LWIP_PLATFORM_DIAG(("drop: %"S16_F"\n\t", proto->drop)); 
-  LWIP_PLATFORM_DIAG(("chkerr: %"S16_F"\n\t", proto->chkerr)); 
-  LWIP_PLATFORM_DIAG(("lenerr: %"S16_F"\n\t", proto->lenerr)); 
-  LWIP_PLATFORM_DIAG(("memerr: %"S16_F"\n\t", proto->memerr)); 
-  LWIP_PLATFORM_DIAG(("rterr: %"S16_F"\n\t", proto->rterr)); 
-  LWIP_PLATFORM_DIAG(("proterr: %"S16_F"\n\t", proto->proterr)); 
-  LWIP_PLATFORM_DIAG(("opterr: %"S16_F"\n\t", proto->opterr)); 
-  LWIP_PLATFORM_DIAG(("err: %"S16_F"\n\t", proto->err)); 
-  LWIP_PLATFORM_DIAG(("cachehit: %"S16_F"\n", proto->cachehit)); 
-}
-
-void
-stats_display_pbuf(struct stats_pbuf *pbuf)
-{
-  LWIP_PLATFORM_DIAG(("\nPBUF\n\t"));
-  LWIP_PLATFORM_DIAG(("avail: %"S16_F"\n\t", pbuf->avail)); 
-  LWIP_PLATFORM_DIAG(("used: %"S16_F"\n\t", pbuf->used)); 
-  LWIP_PLATFORM_DIAG(("max: %"S16_F"\n\t", pbuf->max)); 
-  LWIP_PLATFORM_DIAG(("err: %"S16_F"\n\t", pbuf->err)); 
-  LWIP_PLATFORM_DIAG(("alloc_locked: %"S16_F"\n\t", pbuf->alloc_locked)); 
-  LWIP_PLATFORM_DIAG(("refresh_locked: %"S16_F"\n", pbuf->refresh_locked)); 
-}
-
-void
-stats_display_mem(struct stats_mem *mem, char *name)
-{
-  LWIP_PLATFORM_DIAG(("\n MEM %s\n\t", name));
-  LWIP_PLATFORM_DIAG(("avail: %"S16_F"\n\t", mem->avail)); 
-  LWIP_PLATFORM_DIAG(("used: %"S16_F"\n\t", mem->used)); 
-  LWIP_PLATFORM_DIAG(("max: %"S16_F"\n\t", mem->max)); 
-  LWIP_PLATFORM_DIAG(("err: %"S16_F"\n", mem->err));
-  
-}
-
-void
-stats_display(void)
-{
-  s16_t i;
-  char * memp_names[] = {"PBUF", "RAW_PCB", "UDP_PCB", "TCP_PCB", "TCP_PCB_LISTEN",
-                       "TCP_SEG", "NETBUF", "NETCONN", "API_MSG", "TCP_MSG", "TIMEOUT"};
-  stats_display_proto(&lwip_stats.link, "LINK");
-  stats_display_proto(&lwip_stats.ip_frag, "IP_FRAG");
-  stats_display_proto(&lwip_stats.ip, "IP");
-  stats_display_proto(&lwip_stats.icmp, "ICMP");
-  stats_display_proto(&lwip_stats.udp, "UDP");
-  stats_display_proto(&lwip_stats.tcp, "TCP");
-  stats_display_pbuf(&lwip_stats.pbuf);
-  stats_display_mem(&lwip_stats.mem, "HEAP");
-  for (i = 0; i < MEMP_MAX; i++) {
-    stats_display_mem(&lwip_stats.memp[i], memp_names[i]);
-  }
-       
-}
-#endif /* LWIP_STATS_DISPLAY */
-#endif /* LWIP_STATS */
-
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+\r
+#include <string.h>\r
+\r
+#include "lwip/opt.h"\r
+\r
+#include "lwip/def.h"\r
+\r
+#include "lwip/stats.h"\r
+#include "lwip/mem.h"\r
+\r
+\r
+#if LWIP_STATS\r
+struct stats_ lwip_stats;\r
+\r
+void\r
+stats_init(void)\r
+{\r
+  memset(&lwip_stats, 0, sizeof(struct stats_));\r
+}\r
+#if LWIP_STATS_DISPLAY\r
+void\r
+stats_display_proto(struct stats_proto *proto, char *name)\r
+{\r
+  LWIP_PLATFORM_DIAG(("\n%s\n\t", name));\r
+  LWIP_PLATFORM_DIAG(("xmit: %"S16_F"\n\t", proto->xmit)); \r
+  LWIP_PLATFORM_DIAG(("rexmit: %"S16_F"\n\t", proto->rexmit)); \r
+  LWIP_PLATFORM_DIAG(("recv: %"S16_F"\n\t", proto->recv)); \r
+  LWIP_PLATFORM_DIAG(("fw: %"S16_F"\n\t", proto->fw)); \r
+  LWIP_PLATFORM_DIAG(("drop: %"S16_F"\n\t", proto->drop)); \r
+  LWIP_PLATFORM_DIAG(("chkerr: %"S16_F"\n\t", proto->chkerr)); \r
+  LWIP_PLATFORM_DIAG(("lenerr: %"S16_F"\n\t", proto->lenerr)); \r
+  LWIP_PLATFORM_DIAG(("memerr: %"S16_F"\n\t", proto->memerr)); \r
+  LWIP_PLATFORM_DIAG(("rterr: %"S16_F"\n\t", proto->rterr)); \r
+  LWIP_PLATFORM_DIAG(("proterr: %"S16_F"\n\t", proto->proterr)); \r
+  LWIP_PLATFORM_DIAG(("opterr: %"S16_F"\n\t", proto->opterr)); \r
+  LWIP_PLATFORM_DIAG(("err: %"S16_F"\n\t", proto->err)); \r
+  LWIP_PLATFORM_DIAG(("cachehit: %"S16_F"\n", proto->cachehit)); \r
+}\r
+\r
+void\r
+stats_display_pbuf(struct stats_pbuf *pbuf)\r
+{\r
+  LWIP_PLATFORM_DIAG(("\nPBUF\n\t"));\r
+  LWIP_PLATFORM_DIAG(("avail: %"S16_F"\n\t", pbuf->avail)); \r
+  LWIP_PLATFORM_DIAG(("used: %"S16_F"\n\t", pbuf->used)); \r
+  LWIP_PLATFORM_DIAG(("max: %"S16_F"\n\t", pbuf->max)); \r
+  LWIP_PLATFORM_DIAG(("err: %"S16_F"\n\t", pbuf->err)); \r
+  LWIP_PLATFORM_DIAG(("alloc_locked: %"S16_F"\n\t", pbuf->alloc_locked)); \r
+  LWIP_PLATFORM_DIAG(("refresh_locked: %"S16_F"\n", pbuf->refresh_locked)); \r
+}\r
+\r
+void\r
+stats_display_mem(struct stats_mem *mem, char *name)\r
+{\r
+  LWIP_PLATFORM_DIAG(("\n MEM %s\n\t", name));\r
+  LWIP_PLATFORM_DIAG(("avail: %"S16_F"\n\t", mem->avail)); \r
+  LWIP_PLATFORM_DIAG(("used: %"S16_F"\n\t", mem->used)); \r
+  LWIP_PLATFORM_DIAG(("max: %"S16_F"\n\t", mem->max)); \r
+  LWIP_PLATFORM_DIAG(("err: %"S16_F"\n", mem->err));\r
+  \r
+}\r
+\r
+void\r
+stats_display(void)\r
+{\r
+  s16_t i;\r
+  char * memp_names[] = {"PBUF", "RAW_PCB", "UDP_PCB", "TCP_PCB", "TCP_PCB_LISTEN",\r
+                       "TCP_SEG", "NETBUF", "NETCONN", "API_MSG", "TCP_MSG", "TIMEOUT"};\r
+  stats_display_proto(&lwip_stats.link, "LINK");\r
+  stats_display_proto(&lwip_stats.ip_frag, "IP_FRAG");\r
+  stats_display_proto(&lwip_stats.ip, "IP");\r
+  stats_display_proto(&lwip_stats.icmp, "ICMP");\r
+  stats_display_proto(&lwip_stats.udp, "UDP");\r
+  stats_display_proto(&lwip_stats.tcp, "TCP");\r
+  stats_display_pbuf(&lwip_stats.pbuf);\r
+  stats_display_mem(&lwip_stats.mem, "HEAP");\r
+  for (i = 0; i < MEMP_MAX; i++) {\r
+    stats_display_mem(&lwip_stats.memp[i], memp_names[i]);\r
+  }\r
+       \r
+}\r
+#endif /* LWIP_STATS_DISPLAY */\r
+#endif /* LWIP_STATS */\r
+\r
index a7dbf34dabe6cff75687e192e712f9a2cb373dd6..207808284c590af4e8dae3c3b2d6d141b9a3994b 100644 (file)
-/*
- * 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 <adam@sics.se>
- *
- */
-
-#include "lwip/sys.h"
-#include "lwip/opt.h"
-#include "lwip/def.h"
-#include "lwip/memp.h"
-
-#if (NO_SYS == 0)
-
-struct sswt_cb
-{
-    s16_t timeflag;
-    sys_sem_t *psem;
-};
-
-
-
-void
-sys_mbox_fetch(sys_mbox_t mbox, void **msg)
-{
-  u32_t time;
-  struct sys_timeouts *timeouts;
-  struct sys_timeout *tmptimeout;
-  sys_timeout_handler h;
-  void *arg;
-
-
- again:
-  timeouts = sys_arch_timeouts();
-
-  if (!timeouts || !timeouts->next) {
-    sys_arch_mbox_fetch(mbox, msg, 0);
-  } else {
-    if (timeouts->next->time > 0) {
-      time = sys_arch_mbox_fetch(mbox, msg, timeouts->next->time);
-    } else {
-      time = SYS_ARCH_TIMEOUT;
-    }
-
-    if (time == SYS_ARCH_TIMEOUT) {
-      /* If time == SYS_ARCH_TIMEOUT, a timeout occured before a message
-   could be fetched. We should now call the timeout handler and
-   deallocate the memory allocated for the timeout. */
-      tmptimeout = timeouts->next;
-      timeouts->next = tmptimeout->next;
-      h = tmptimeout->h;
-      arg = tmptimeout->arg;
-      memp_free(MEMP_SYS_TIMEOUT, tmptimeout);
-      if (h != NULL) {
-        LWIP_DEBUGF(SYS_DEBUG, ("smf calling h=%p(%p)\n", (void *)h, (void *)arg));
-       h(arg);
-      }
-
-      /* We try again to fetch a message from the mbox. */
-      goto again;
-    } else {
-      /* If time != SYS_ARCH_TIMEOUT, a message was received before the timeout
-   occured. The time variable is set to the number of
-   milliseconds we waited for the message. */
-      if (time <= timeouts->next->time) {
-  timeouts->next->time -= time;
-      } else {
-  timeouts->next->time = 0;
-      }
-    }
-
-  }
-}
-
-void
-sys_sem_wait(sys_sem_t sem)
-{
-  u32_t time;
-  struct sys_timeouts *timeouts;
-  struct sys_timeout *tmptimeout;
-  sys_timeout_handler h;
-  void *arg;
-
-  /*  while (sys_arch_sem_wait(sem, 1000) == 0);
-      return;*/
-
- again:
-
-  timeouts = sys_arch_timeouts();
-
-  if (!timeouts || !timeouts->next) {
-    sys_arch_sem_wait(sem, 0);
-  } else {
-    if (timeouts->next->time > 0) {
-      time = sys_arch_sem_wait(sem, timeouts->next->time);
-    } else {
-      time = SYS_ARCH_TIMEOUT;
-    }
-
-    if (time == SYS_ARCH_TIMEOUT) {
-      /* If time == SYS_ARCH_TIMEOUT, a timeout occured before a message
-   could be fetched. We should now call the timeout handler and
-   deallocate the memory allocated for the timeout. */
-      tmptimeout = timeouts->next;
-      timeouts->next = tmptimeout->next;
-      h = tmptimeout->h;
-      arg = tmptimeout->arg;
-      memp_free(MEMP_SYS_TIMEOUT, tmptimeout);
-      if (h != NULL) {
-        LWIP_DEBUGF(SYS_DEBUG, ("ssw h=%p(%p)\n", (void *)h, (void *)arg));
-        h(arg);
-      }
-
-
-      /* We try again to fetch a message from the mbox. */
-      goto again;
-    } else {
-      /* If time != SYS_ARCH_TIMEOUT, a message was received before the timeout
-   occured. The time variable is set to the number of
-   milliseconds we waited for the message. */
-      if (time <= timeouts->next->time) {
-  timeouts->next->time -= time;
-      } else {
-  timeouts->next->time = 0;
-      }
-    }
-
-  }
-}
-
-void
-sys_timeout(u32_t msecs, sys_timeout_handler h, void *arg)
-{
-  struct sys_timeouts *timeouts;
-  struct sys_timeout *timeout, *t;
-
-  timeout = memp_malloc(MEMP_SYS_TIMEOUT);
-  if (timeout == NULL) {
-    return;
-  }
-  timeout->next = NULL;
-  timeout->h = h;
-  timeout->arg = arg;
-  timeout->time = msecs;
-
-  timeouts = sys_arch_timeouts();
-
-  LWIP_DEBUGF(SYS_DEBUG, ("sys_timeout: %p msecs=%"U32_F" h=%p arg=%p\n",
-    (void *)timeout, msecs, (void *)h, (void *)arg));
-
-  LWIP_ASSERT("sys_timeout: timeouts != NULL", timeouts != NULL);
-
-  if (timeouts->next == NULL) {
-    timeouts->next = timeout;
-    return;
-  }
-
-  if (timeouts->next->time > msecs) {
-    timeouts->next->time -= msecs;
-    timeout->next = timeouts->next;
-    timeouts->next = timeout;
-  } else {
-    for(t = timeouts->next; t != NULL; t = t->next) {
-      timeout->time -= t->time;
-      if (t->next == NULL || t->next->time > timeout->time) {
-        if (t->next != NULL) {
-          t->next->time -= timeout->time;
-        }
-        timeout->next = t->next;
-        t->next = timeout;
-        break;
-      }
-    }
-  }
-
-}
-
-/* Go through timeout list (for this task only) and remove the first matching entry,
-   even though the timeout has not triggered yet.
-*/
-
-void
-sys_untimeout(sys_timeout_handler h, void *arg)
-{
-    struct sys_timeouts *timeouts;
-    struct sys_timeout *prev_t, *t;
-
-    timeouts = sys_arch_timeouts();
-
-    if (timeouts->next == NULL)
-        return;
-
-    for (t = timeouts->next, prev_t = NULL; t != NULL; prev_t = t, t = t->next)
-    {
-        if ((t->h == h) && (t->arg == arg))
-        {
-            /* We have a match */
-            /* Unlink from previous in list */
-            if (prev_t == NULL)
-                timeouts->next = t->next;
-            else
-                prev_t->next = t->next;
-            /* If not the last one, add time of this one back to next */
-            if (t->next != NULL)
-                t->next->time += t->time;
-            memp_free(MEMP_SYS_TIMEOUT, t);
-            return;
-        }
-    }
-    return;
-}
-
-
-
-
-
-static void
-sswt_handler(void *arg)
-{
-    struct sswt_cb *sswt_cb = (struct sswt_cb *) arg;
-
-    /* Timeout. Set flag to TRUE and signal semaphore */
-    sswt_cb->timeflag = 1;
-    sys_sem_signal(*(sswt_cb->psem));
-}
-
-/* Wait for a semaphore with timeout (specified in ms) */
-/* timeout = 0: wait forever */
-/* Returns 0 on timeout. 1 otherwise */
-
-int
-sys_sem_wait_timeout(sys_sem_t sem, u32_t timeout)
-{
-    struct sswt_cb sswt_cb;
-
-    sswt_cb.psem = &sem;
-    sswt_cb.timeflag = 0;
-
-    /* If timeout is zero, then just wait forever */
-    if (timeout > 0)
-        /* Create a timer and pass it the address of our flag */
-        sys_timeout(timeout, sswt_handler, &sswt_cb);
-    sys_sem_wait(sem);
-    /* Was it a timeout? */
-    if (sswt_cb.timeflag)
-    {
-        /* timeout */
-        return 0;
-    } else {
-        /* Not a timeout. Remove timeout entry */
-        sys_untimeout(sswt_handler, &sswt_cb);
-        return 1;
-    }
-
-}
-
-
-void
-sys_msleep(u32_t ms)
-{
-  sys_sem_t delaysem = sys_sem_new(0);
-
-  sys_sem_wait_timeout(delaysem, ms);
-
-  sys_sem_free(delaysem);
-}
-
-
-#endif /* NO_SYS */
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without modification,\r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED\r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT\r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY\r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ *\r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+\r
+#include "lwip/sys.h"\r
+#include "lwip/opt.h"\r
+#include "lwip/def.h"\r
+#include "lwip/memp.h"\r
+\r
+#if (NO_SYS == 0)\r
+\r
+struct sswt_cb\r
+{\r
+    s16_t timeflag;\r
+    sys_sem_t *psem;\r
+};\r
+\r
+\r
+\r
+void\r
+sys_mbox_fetch(sys_mbox_t mbox, void **msg)\r
+{\r
+  u32_t time;\r
+  struct sys_timeouts *timeouts;\r
+  struct sys_timeout *tmptimeout;\r
+  sys_timeout_handler h;\r
+  void *arg;\r
+\r
+\r
+ again:\r
+  timeouts = sys_arch_timeouts();\r
+\r
+  if (!timeouts || !timeouts->next) {\r
+    sys_arch_mbox_fetch(mbox, msg, 0);\r
+  } else {\r
+    if (timeouts->next->time > 0) {\r
+      time = sys_arch_mbox_fetch(mbox, msg, timeouts->next->time);\r
+    } else {\r
+      time = SYS_ARCH_TIMEOUT;\r
+    }\r
+\r
+    if (time == SYS_ARCH_TIMEOUT) {\r
+      /* If time == SYS_ARCH_TIMEOUT, a timeout occured before a message\r
+   could be fetched. We should now call the timeout handler and\r
+   deallocate the memory allocated for the timeout. */\r
+      tmptimeout = timeouts->next;\r
+      timeouts->next = tmptimeout->next;\r
+      h = tmptimeout->h;\r
+      arg = tmptimeout->arg;\r
+      memp_free(MEMP_SYS_TIMEOUT, tmptimeout);\r
+      if (h != NULL) {\r
+        LWIP_DEBUGF(SYS_DEBUG, ("smf calling h=%p(%p)\n", (void *)h, (void *)arg));\r
+       h(arg);\r
+      }\r
+\r
+      /* We try again to fetch a message from the mbox. */\r
+      goto again;\r
+    } else {\r
+      /* If time != SYS_ARCH_TIMEOUT, a message was received before the timeout\r
+   occured. The time variable is set to the number of\r
+   milliseconds we waited for the message. */\r
+      if (time <= timeouts->next->time) {\r
+  timeouts->next->time -= time;\r
+      } else {\r
+  timeouts->next->time = 0;\r
+      }\r
+    }\r
+\r
+  }\r
+}\r
+\r
+void\r
+sys_sem_wait(sys_sem_t sem)\r
+{\r
+  u32_t time;\r
+  struct sys_timeouts *timeouts;\r
+  struct sys_timeout *tmptimeout;\r
+  sys_timeout_handler h;\r
+  void *arg;\r
+\r
+  /*  while (sys_arch_sem_wait(sem, 1000) == 0);\r
+      return;*/\r
+\r
+ again:\r
+\r
+  timeouts = sys_arch_timeouts();\r
+\r
+  if (!timeouts || !timeouts->next) {\r
+    sys_arch_sem_wait(sem, 0);\r
+  } else {\r
+    if (timeouts->next->time > 0) {\r
+      time = sys_arch_sem_wait(sem, timeouts->next->time);\r
+    } else {\r
+      time = SYS_ARCH_TIMEOUT;\r
+    }\r
+\r
+    if (time == SYS_ARCH_TIMEOUT) {\r
+      /* If time == SYS_ARCH_TIMEOUT, a timeout occured before a message\r
+   could be fetched. We should now call the timeout handler and\r
+   deallocate the memory allocated for the timeout. */\r
+      tmptimeout = timeouts->next;\r
+      timeouts->next = tmptimeout->next;\r
+      h = tmptimeout->h;\r
+      arg = tmptimeout->arg;\r
+      memp_free(MEMP_SYS_TIMEOUT, tmptimeout);\r
+      if (h != NULL) {\r
+        LWIP_DEBUGF(SYS_DEBUG, ("ssw h=%p(%p)\n", (void *)h, (void *)arg));\r
+        h(arg);\r
+      }\r
+\r
+\r
+      /* We try again to fetch a message from the mbox. */\r
+      goto again;\r
+    } else {\r
+      /* If time != SYS_ARCH_TIMEOUT, a message was received before the timeout\r
+   occured. The time variable is set to the number of\r
+   milliseconds we waited for the message. */\r
+      if (time <= timeouts->next->time) {\r
+  timeouts->next->time -= time;\r
+      } else {\r
+  timeouts->next->time = 0;\r
+      }\r
+    }\r
+\r
+  }\r
+}\r
+\r
+void\r
+sys_timeout(u32_t msecs, sys_timeout_handler h, void *arg)\r
+{\r
+  struct sys_timeouts *timeouts;\r
+  struct sys_timeout *timeout, *t;\r
+\r
+  timeout = memp_malloc(MEMP_SYS_TIMEOUT);\r
+  if (timeout == NULL) {\r
+    return;\r
+  }\r
+  timeout->next = NULL;\r
+  timeout->h = h;\r
+  timeout->arg = arg;\r
+  timeout->time = msecs;\r
+\r
+  timeouts = sys_arch_timeouts();\r
+\r
+  LWIP_DEBUGF(SYS_DEBUG, ("sys_timeout: %p msecs=%"U32_F" h=%p arg=%p\n",\r
+    (void *)timeout, msecs, (void *)h, (void *)arg));\r
+\r
+  LWIP_ASSERT("sys_timeout: timeouts != NULL", timeouts != NULL);\r
+\r
+  if (timeouts->next == NULL) {\r
+    timeouts->next = timeout;\r
+    return;\r
+  }\r
+\r
+  if (timeouts->next->time > msecs) {\r
+    timeouts->next->time -= msecs;\r
+    timeout->next = timeouts->next;\r
+    timeouts->next = timeout;\r
+  } else {\r
+    for(t = timeouts->next; t != NULL; t = t->next) {\r
+      timeout->time -= t->time;\r
+      if (t->next == NULL || t->next->time > timeout->time) {\r
+        if (t->next != NULL) {\r
+          t->next->time -= timeout->time;\r
+        }\r
+        timeout->next = t->next;\r
+        t->next = timeout;\r
+        break;\r
+      }\r
+    }\r
+  }\r
+\r
+}\r
+\r
+/* Go through timeout list (for this task only) and remove the first matching entry,\r
+   even though the timeout has not triggered yet.\r
+*/\r
+\r
+void\r
+sys_untimeout(sys_timeout_handler h, void *arg)\r
+{\r
+    struct sys_timeouts *timeouts;\r
+    struct sys_timeout *prev_t, *t;\r
+\r
+    timeouts = sys_arch_timeouts();\r
+\r
+    if (timeouts->next == NULL)\r
+        return;\r
+\r
+    for (t = timeouts->next, prev_t = NULL; t != NULL; prev_t = t, t = t->next)\r
+    {\r
+        if ((t->h == h) && (t->arg == arg))\r
+        {\r
+            /* We have a match */\r
+            /* Unlink from previous in list */\r
+            if (prev_t == NULL)\r
+                timeouts->next = t->next;\r
+            else\r
+                prev_t->next = t->next;\r
+            /* If not the last one, add time of this one back to next */\r
+            if (t->next != NULL)\r
+                t->next->time += t->time;\r
+            memp_free(MEMP_SYS_TIMEOUT, t);\r
+            return;\r
+        }\r
+    }\r
+    return;\r
+}\r
+\r
+\r
+\r
+\r
+\r
+static void\r
+sswt_handler(void *arg)\r
+{\r
+    struct sswt_cb *sswt_cb = (struct sswt_cb *) arg;\r
+\r
+    /* Timeout. Set flag to TRUE and signal semaphore */\r
+    sswt_cb->timeflag = 1;\r
+    sys_sem_signal(*(sswt_cb->psem));\r
+}\r
+\r
+/* Wait for a semaphore with timeout (specified in ms) */\r
+/* timeout = 0: wait forever */\r
+/* Returns 0 on timeout. 1 otherwise */\r
+\r
+int\r
+sys_sem_wait_timeout(sys_sem_t sem, u32_t timeout)\r
+{\r
+    struct sswt_cb sswt_cb;\r
+\r
+    sswt_cb.psem = &sem;\r
+    sswt_cb.timeflag = 0;\r
+\r
+    /* If timeout is zero, then just wait forever */\r
+    if (timeout > 0)\r
+        /* Create a timer and pass it the address of our flag */\r
+        sys_timeout(timeout, sswt_handler, &sswt_cb);\r
+    sys_sem_wait(sem);\r
+    /* Was it a timeout? */\r
+    if (sswt_cb.timeflag)\r
+    {\r
+        /* timeout */\r
+        return 0;\r
+    } else {\r
+        /* Not a timeout. Remove timeout entry */\r
+        sys_untimeout(sswt_handler, &sswt_cb);\r
+        return 1;\r
+    }\r
+\r
+}\r
+\r
+\r
+void\r
+sys_msleep(u32_t ms)\r
+{\r
+  sys_sem_t delaysem = sys_sem_new(0);\r
+\r
+  sys_sem_wait_timeout(delaysem, ms);\r
+\r
+  sys_sem_free(delaysem);\r
+}\r
+\r
+\r
+#endif /* NO_SYS */\r
index 41a9edb4e5b45207448cfa4b9cd5218edb5157e2..5ccccabfdf5f7bca825654c271ff380977055e26 100644 (file)
-/**
- * @file
- *
- * Transmission Control Protocol for IP
- *
- * This file contains common functions for the TCP implementation, such as functinos
- * for manipulating the data structures and the TCP timer functions. TCP functions
- * related to input and output is found in tcp_in.c and tcp_out.c respectively.
- *
- */
-
-/*
- * 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 <adam@sics.se>
- *
- */
-
-#include <string.h>
-
-#include "lwip/opt.h"
-#include "lwip/def.h"
-#include "lwip/mem.h"
-#include "lwip/memp.h"
-
-#include "lwip/tcp.h"
-#if LWIP_TCP
-
-/* Incremented every coarse grained timer shot
-   (typically every 500 ms, determined by TCP_COARSE_TIMEOUT). */
-u32_t tcp_ticks;
-const u8_t tcp_backoff[13] =
-    { 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7};
-
-/* The TCP PCB lists. */
-
-/** List of all TCP PCBs in LISTEN state */
-union tcp_listen_pcbs_t tcp_listen_pcbs;
-/** List of all TCP PCBs that are in a state in which
- * they accept or send data. */
-struct tcp_pcb *tcp_active_pcbs;  
-/** List of all TCP PCBs in TIME-WAIT state */
-struct tcp_pcb *tcp_tw_pcbs;
-
-struct tcp_pcb *tcp_tmp_pcb;
-
-static u8_t tcp_timer;
-static u16_t tcp_new_port(void);
-
-/**
- * Initializes the TCP layer.
- */
-void
-tcp_init(void)
-{
-  /* Clear globals. */
-  tcp_listen_pcbs.listen_pcbs = NULL;
-  tcp_active_pcbs = NULL;
-  tcp_tw_pcbs = NULL;
-  tcp_tmp_pcb = NULL;
-  
-  /* initialize timer */
-  tcp_ticks = 0;
-  tcp_timer = 0;
-  
-}
-
-/**
- * Called periodically to dispatch TCP timers.
- *
- */
-void
-tcp_tmr(void)
-{
-  /* Call tcp_fasttmr() every 250 ms */
-  tcp_fasttmr();
-
-  if (++tcp_timer & 1) {
-    /* Call tcp_tmr() every 500 ms, i.e., every other timer
-       tcp_tmr() is called. */
-    tcp_slowtmr();
-  }
-}
-
-/**
- * Closes the connection held by the PCB.
- *
- */
-err_t
-tcp_close(struct tcp_pcb *pcb)
-{
-  err_t err;
-
-#if TCP_DEBUG
-  LWIP_DEBUGF(TCP_DEBUG, ("tcp_close: closing in state "));
-  tcp_debug_print_state(pcb->state);
-  LWIP_DEBUGF(TCP_DEBUG, ("\n"));
-#endif /* TCP_DEBUG */
-  switch (pcb->state) {
-  case CLOSED:
-    /* Closing a pcb in the CLOSED state might seem erroneous,
-     * however, it is in this state once allocated and as yet unused
-     * and the user needs some way to free it should the need arise.
-     * Calling tcp_close() with a pcb that has already been closed, (i.e. twice)
-     * or for a pcb that has been used and then entered the CLOSED state 
-     * 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;
-    memp_free(MEMP_TCP_PCB, pcb);
-    pcb = NULL;
-    break;
-  case LISTEN:
-    err = ERR_OK;
-    tcp_pcb_remove((struct tcp_pcb **)&tcp_listen_pcbs.pcbs, pcb);
-    memp_free(MEMP_TCP_PCB_LISTEN, pcb);
-    pcb = NULL;
-    break;
-  case SYN_SENT:
-    err = ERR_OK;
-    tcp_pcb_remove(&tcp_active_pcbs, pcb);
-    memp_free(MEMP_TCP_PCB, pcb);
-    pcb = NULL;
-    break;
-  case SYN_RCVD:
-  case ESTABLISHED:
-    err = tcp_send_ctrl(pcb, TCP_FIN);
-    if (err == ERR_OK) {
-      pcb->state = FIN_WAIT_1;
-    }
-    break;
-  case CLOSE_WAIT:
-    err = tcp_send_ctrl(pcb, TCP_FIN);
-    if (err == ERR_OK) {
-      pcb->state = LAST_ACK;
-    }
-    break;
-  default:
-    /* Has already been closed, do nothing. */
-    err = ERR_OK;
-    pcb = NULL;
-    break;
-  }
-
-  if (pcb != NULL && err == ERR_OK) {
-    err = tcp_output(pcb);
-  }
-  return err;
-}
-
-/**
- * Aborts a connection by sending a RST to the remote host and deletes
- * the local protocol control block. This is done when a connection is
- * killed because of shortage of memory.
- *
- */
-void
-tcp_abort(struct tcp_pcb *pcb)
-{
-  u32_t seqno, ackno;
-  u16_t remote_port, local_port;
-  struct ip_addr remote_ip, local_ip;
-#if LWIP_CALLBACK_API  
-  void (* errf)(void *arg, err_t err);
-#endif /* LWIP_CALLBACK_API */
-  void *errf_arg;
-
-  
-  /* Figure out on which TCP PCB list we are, and remove us. If we
-     are in an active state, call the receive function associated with
-     the PCB with a NULL argument, and send an RST to the remote end. */
-  if (pcb->state == TIME_WAIT) {
-    tcp_pcb_remove(&tcp_tw_pcbs, pcb);
-    memp_free(MEMP_TCP_PCB, pcb);
-  } else {
-    seqno = pcb->snd_nxt;
-    ackno = pcb->rcv_nxt;
-    ip_addr_set(&local_ip, &(pcb->local_ip));
-    ip_addr_set(&remote_ip, &(pcb->remote_ip));
-    local_port = pcb->local_port;
-    remote_port = pcb->remote_port;
-#if LWIP_CALLBACK_API
-    errf = pcb->errf;
-#endif /* LWIP_CALLBACK_API */
-    errf_arg = pcb->callback_arg;
-    tcp_pcb_remove(&tcp_active_pcbs, pcb);
-    if (pcb->unacked != NULL) {
-      tcp_segs_free(pcb->unacked);
-    }
-    if (pcb->unsent != NULL) {
-      tcp_segs_free(pcb->unsent);
-    }
-#if TCP_QUEUE_OOSEQ    
-    if (pcb->ooseq != NULL) {
-      tcp_segs_free(pcb->ooseq);
-    }
-#endif /* TCP_QUEUE_OOSEQ */
-    memp_free(MEMP_TCP_PCB, pcb);
-    TCP_EVENT_ERR(errf, errf_arg, ERR_ABRT);
-    LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_abort: sending RST\n"));
-    tcp_rst(seqno, ackno, &local_ip, &remote_ip, local_port, remote_port);
-  }
-}
-
-/**
- * Binds the connection to a local portnumber and IP address. If the
- * IP address is not given (i.e., ipaddr == NULL), the IP address of
- * the outgoing network interface is used instead.
- *
- */
-
-err_t
-tcp_bind(struct tcp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
-{
-  struct tcp_pcb *cpcb;
-
-  if (port == 0) {
-    port = tcp_new_port();
-  }
-  /* Check if the address already is in use. */
-  for(cpcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs;
-      cpcb != NULL; cpcb = cpcb->next) {
-    if (cpcb->local_port == port) {
-      if (ip_addr_isany(&(cpcb->local_ip)) ||
-        ip_addr_isany(ipaddr) ||
-        ip_addr_cmp(&(cpcb->local_ip), ipaddr)) {
-          return ERR_USE;
-      }
-    }
-  }
-  for(cpcb = tcp_active_pcbs;
-      cpcb != NULL; cpcb = cpcb->next) {
-    if (cpcb->local_port == port) {
-      if (ip_addr_isany(&(cpcb->local_ip)) ||
-   ip_addr_isany(ipaddr) ||
-   ip_addr_cmp(&(cpcb->local_ip), ipaddr)) {
-  return ERR_USE;
-      }
-    }
-  }
-
-  if (!ip_addr_isany(ipaddr)) {
-    pcb->local_ip = *ipaddr;
-  }
-  pcb->local_port = port;
-  LWIP_DEBUGF(TCP_DEBUG, ("tcp_bind: bind to port %"U16_F"\n", port));
-  return ERR_OK;
-}
-#if LWIP_CALLBACK_API
-static err_t
-tcp_accept_null(void *arg, struct tcp_pcb *pcb, err_t err)
-{
-  (void)arg;
-  (void)pcb;
-  (void)err;
-
-  return ERR_ABRT;
-}
-#endif /* LWIP_CALLBACK_API */
-
-/**
- * Set the state of the connection to be LISTEN, which means that it
- * is able to accept incoming connections. The protocol control block
- * is reallocated in order to consume less memory. Setting the
- * connection to LISTEN is an irreversible process.
- *
- */
-struct tcp_pcb *
-tcp_listen(struct tcp_pcb *pcb)
-{
-  struct tcp_pcb_listen *lpcb;
-
-  /* already listening? */
-  if (pcb->state == LISTEN) {
-    return pcb;
-  }
-  lpcb = memp_malloc(MEMP_TCP_PCB_LISTEN);
-  if (lpcb == NULL) {
-    return NULL;
-  }
-  lpcb->callback_arg = pcb->callback_arg;
-  lpcb->local_port = pcb->local_port;
-  lpcb->state = LISTEN;
-  lpcb->so_options = pcb->so_options;
-  lpcb->so_options |= SOF_ACCEPTCONN;
-  lpcb->ttl = pcb->ttl;
-  lpcb->tos = pcb->tos;
-  ip_addr_set(&lpcb->local_ip, &pcb->local_ip);
-  memp_free(MEMP_TCP_PCB, pcb);
-#if LWIP_CALLBACK_API
-  lpcb->accept = tcp_accept_null;
-#endif /* LWIP_CALLBACK_API */
-  TCP_REG(&tcp_listen_pcbs.listen_pcbs, lpcb);
-  return (struct tcp_pcb *)lpcb;
-}
-
-/**
- * This function should be called by the application when it has
- * processed the data. The purpose is to advertise a larger window
- * when the data has been processed.
- *
- */
-void
-tcp_recved(struct tcp_pcb *pcb, u16_t len)
-{
-  if ((u32_t)pcb->rcv_wnd + len > TCP_WND) {
-    pcb->rcv_wnd = TCP_WND;
-  } else {
-    pcb->rcv_wnd += len;
-  }
-  if (!(pcb->flags & TF_ACK_DELAY) &&
-     !(pcb->flags & TF_ACK_NOW)) {
-    /*
-     * We send an ACK here (if one is not already pending, hence
-     * the above tests) as tcp_recved() implies that the application
-     * has processed some data, and so we can open the receiver's
-     * window to allow more to be transmitted.  This could result in
-     * two ACKs being sent for each received packet in some limited cases
-     * (where the application is only receiving data, and is slow to
-     * process it) but it is necessary to guarantee that the sender can
-     * continue to transmit.
-     */
-    tcp_ack(pcb);
-  } 
-  else if (pcb->flags & TF_ACK_DELAY && pcb->rcv_wnd >= TCP_WND/2) {
-    /* If we can send a window update such that there is a full
-     * segment available in the window, do so now.  This is sort of
-     * nagle-like in its goals, and tries to hit a compromise between
-     * sending acks each time the window is updated, and only sending
-     * window updates when a timer expires.  The "threshold" used
-     * above (currently TCP_WND/2) can be tuned to be more or less
-     * aggressive  */
-    tcp_ack_now(pcb);
-  }
-
-  LWIP_DEBUGF(TCP_DEBUG, ("tcp_recved: recveived %"U16_F" bytes, wnd %"U16_F" (%"U16_F").\n",
-         len, pcb->rcv_wnd, TCP_WND - pcb->rcv_wnd));
-}
-
-/**
- * A nastly hack featuring 'goto' statements that allocates a
- * new TCP local port.
- */
-static u16_t
-tcp_new_port(void)
-{
-  struct tcp_pcb *pcb;
-#ifndef TCP_LOCAL_PORT_RANGE_START
-#define TCP_LOCAL_PORT_RANGE_START 4096
-#define TCP_LOCAL_PORT_RANGE_END   0x7fff
-#endif
-  static u16_t port = TCP_LOCAL_PORT_RANGE_START;
-  
- again:
-  if (++port > TCP_LOCAL_PORT_RANGE_END) {
-    port = TCP_LOCAL_PORT_RANGE_START;
-  }
-  
-  for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
-    if (pcb->local_port == port) {
-      goto again;
-    }
-  }
-  for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
-    if (pcb->local_port == port) {
-      goto again;
-    }
-  }
-  for(pcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs; pcb != NULL; pcb = pcb->next) {
-    if (pcb->local_port == port) {
-      goto again;
-    }
-  }
-  return port;
-}
-
-/**
- * Connects to another host. The function given as the "connected"
- * argument will be called when the connection has been established.
- *
- */
-err_t
-tcp_connect(struct tcp_pcb *pcb, struct ip_addr *ipaddr, u16_t port,
-      err_t (* connected)(void *arg, struct tcp_pcb *tpcb, err_t err))
-{
-  u32_t optdata;
-  err_t ret;
-  u32_t iss;
-
-  LWIP_DEBUGF(TCP_DEBUG, ("tcp_connect to port %"U16_F"\n", port));
-  if (ipaddr != NULL) {
-    pcb->remote_ip = *ipaddr;
-  } else {
-    return ERR_VAL;
-  }
-  pcb->remote_port = port;
-  if (pcb->local_port == 0) {
-    pcb->local_port = tcp_new_port();
-  }
-  iss = tcp_next_iss();
-  pcb->rcv_nxt = 0;
-  pcb->snd_nxt = iss;
-  pcb->lastack = iss - 1;
-  pcb->snd_lbb = iss - 1;
-  pcb->rcv_wnd = TCP_WND;
-  pcb->snd_wnd = TCP_WND;
-  pcb->mss = TCP_MSS;
-  pcb->cwnd = 1;
-  pcb->ssthresh = pcb->mss * 10;
-  pcb->state = SYN_SENT;
-#if LWIP_CALLBACK_API  
-  pcb->connected = connected;
-#endif /* LWIP_CALLBACK_API */  
-  TCP_REG(&tcp_active_pcbs, pcb);
-  
-  /* Build an MSS option */
-  optdata = htonl(((u32_t)2 << 24) | 
-      ((u32_t)4 << 16) | 
-      (((u32_t)pcb->mss / 256) << 8) |
-      (pcb->mss & 255));
-
-  ret = tcp_enqueue(pcb, NULL, 0, TCP_SYN, 0, (u8_t *)&optdata, 4);
-  if (ret == ERR_OK) { 
-    tcp_output(pcb);
-  }
-  return ret;
-} 
-
-/**
- * Called every 500 ms and implements the retransmission timer and the timer that
- * removes PCBs that have been in TIME-WAIT for enough time. It also increments
- * various timers such as the inactivity timer in each PCB.
- */
-void
-tcp_slowtmr(void)
-{
-  struct tcp_pcb *pcb, *pcb2, *prev;
-  u32_t eff_wnd;
-  u8_t pcb_remove;      /* flag if a PCB should be removed */
-  err_t err;
-
-  err = ERR_OK;
-
-  ++tcp_ticks;
-
-  /* Steps through all of the active PCBs. */
-  prev = NULL;
-  pcb = tcp_active_pcbs;
-  if (pcb == NULL) {
-    LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: no active pcbs\n"));
-  }
-  while (pcb != NULL) {
-    LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: processing active pcb\n"));
-    LWIP_ASSERT("tcp_slowtmr: active pcb->state != CLOSED\n", pcb->state != CLOSED);
-    LWIP_ASSERT("tcp_slowtmr: active pcb->state != LISTEN\n", pcb->state != LISTEN);
-    LWIP_ASSERT("tcp_slowtmr: active pcb->state != TIME-WAIT\n", pcb->state != TIME_WAIT);
-
-    pcb_remove = 0;
-
-    if (pcb->state == SYN_SENT && pcb->nrtx == TCP_SYNMAXRTX) {
-      ++pcb_remove;
-      LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max SYN retries reached\n"));
-    }
-    else if (pcb->nrtx == TCP_MAXRTX) {
-      ++pcb_remove;
-      LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max DATA retries reached\n"));
-    } else {
-      ++pcb->rtime;
-      if (pcb->unacked != NULL && pcb->rtime >= pcb->rto) {
-
-        /* Time for a retransmission. */
-        LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_slowtmr: rtime %"U16_F" pcb->rto %"U16_F"\n",
-          pcb->rtime, pcb->rto));
-
-        /* Double retransmission time-out unless we are trying to
-         * connect to somebody (i.e., we are in SYN_SENT). */
-        if (pcb->state != SYN_SENT) {
-          pcb->rto = ((pcb->sa >> 3) + pcb->sv) << tcp_backoff[pcb->nrtx];
-        }
-        /* Reduce congestion window and ssthresh. */
-        eff_wnd = LWIP_MIN(pcb->cwnd, pcb->snd_wnd);
-        pcb->ssthresh = eff_wnd >> 1;
-        if (pcb->ssthresh < pcb->mss) {
-          pcb->ssthresh = pcb->mss * 2;
-        }
-        pcb->cwnd = pcb->mss;
-        LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_slowtmr: cwnd %"U16_F" ssthresh %"U16_F"\n",
-                                pcb->cwnd, pcb->ssthresh));
-        /* The following needs to be called AFTER cwnd is set to one mss - STJ */
-        tcp_rexmit_rto(pcb);
-     }
-    }
-    /* Check if this PCB has stayed too long in FIN-WAIT-2 */
-    if (pcb->state == FIN_WAIT_2) {
-      if ((u32_t)(tcp_ticks - pcb->tmr) >
-        TCP_FIN_WAIT_TIMEOUT / TCP_SLOW_INTERVAL) {
-        ++pcb_remove;
-        LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in FIN-WAIT-2\n"));
-      }
-    }
-
-   /* Check if KEEPALIVE should be sent */
-   if((pcb->so_options & SOF_KEEPALIVE) && ((pcb->state == ESTABLISHED) || (pcb->state == CLOSE_WAIT))) {
-      if((u32_t)(tcp_ticks - pcb->tmr) > (pcb->keepalive + TCP_MAXIDLE) / TCP_SLOW_INTERVAL)  {
-         LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: KEEPALIVE timeout. Aborting connection to %"U16_F".%"U16_F".%"U16_F".%"U16_F".\n",
-                                 ip4_addr1(&pcb->remote_ip), ip4_addr2(&pcb->remote_ip),
-                                 ip4_addr3(&pcb->remote_ip), ip4_addr4(&pcb->remote_ip)));
-
-         tcp_abort(pcb);
-      }
-      else if((u32_t)(tcp_ticks - pcb->tmr) > (pcb->keepalive + pcb->keep_cnt * TCP_KEEPINTVL) / TCP_SLOW_INTERVAL) {
-         tcp_keepalive(pcb);
-         pcb->keep_cnt++;
-      }
-   }
-
-    /* If this PCB has queued out of sequence data, but has been
-       inactive for too long, will drop the data (it will eventually
-       be retransmitted). */
-#if TCP_QUEUE_OOSEQ    
-    if (pcb->ooseq != NULL &&
-       (u32_t)tcp_ticks - pcb->tmr >=
-       pcb->rto * TCP_OOSEQ_TIMEOUT) {
-      tcp_segs_free(pcb->ooseq);
-      pcb->ooseq = NULL;
-      LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_slowtmr: dropping OOSEQ queued data\n"));
-    }
-#endif /* TCP_QUEUE_OOSEQ */
-
-    /* Check if this PCB has stayed too long in SYN-RCVD */
-    if (pcb->state == SYN_RCVD) {
-      if ((u32_t)(tcp_ticks - pcb->tmr) >
-        TCP_SYN_RCVD_TIMEOUT / TCP_SLOW_INTERVAL) {
-        ++pcb_remove;
-        LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in SYN-RCVD\n"));
-      }
-    }
-
-    /* Check if this PCB has stayed too long in LAST-ACK */
-    if (pcb->state == LAST_ACK) {
-      if ((u32_t)(tcp_ticks - pcb->tmr) > 2 * TCP_MSL / TCP_SLOW_INTERVAL) {
-        ++pcb_remove;
-        LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in LAST-ACK\n"));
-      }
-    }
-
-    /* If the PCB should be removed, do it. */
-    if (pcb_remove) {
-      tcp_pcb_purge(pcb);      
-      /* Remove PCB from tcp_active_pcbs list. */
-      if (prev != NULL) {
-  LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_active_pcbs", pcb != tcp_active_pcbs);
-        prev->next = pcb->next;
-      } else {
-        /* This PCB was the first. */
-        LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_active_pcbs", tcp_active_pcbs == pcb);
-        tcp_active_pcbs = pcb->next;
-      }
-
-      TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_ABRT);
-
-      pcb2 = pcb->next;
-      memp_free(MEMP_TCP_PCB, pcb);
-      pcb = pcb2;
-    } else {
-
-      /* We check if we should poll the connection. */
-      ++pcb->polltmr;
-      if (pcb->polltmr >= pcb->pollinterval) {
-        pcb->polltmr = 0;
-        LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: polling application\n"));
-        TCP_EVENT_POLL(pcb, err);
-        if (err == ERR_OK) {
-          tcp_output(pcb);
-        }
-      }
-      
-      prev = pcb;
-      pcb = pcb->next;
-    }
-  }
-
-  
-  /* Steps through all of the TIME-WAIT PCBs. */
-  prev = NULL;    
-  pcb = tcp_tw_pcbs;
-  while (pcb != NULL) {
-    LWIP_ASSERT("tcp_slowtmr: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT);
-    pcb_remove = 0;
-
-    /* Check if this PCB has stayed long enough in TIME-WAIT */
-    if ((u32_t)(tcp_ticks - pcb->tmr) > 2 * TCP_MSL / TCP_SLOW_INTERVAL) {
-      ++pcb_remove;
-    }
-    
-
-
-    /* If the PCB should be removed, do it. */
-    if (pcb_remove) {
-      tcp_pcb_purge(pcb);      
-      /* Remove PCB from tcp_tw_pcbs list. */
-      if (prev != NULL) {
-  LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_tw_pcbs", pcb != tcp_tw_pcbs);
-        prev->next = pcb->next;
-      } else {
-        /* This PCB was the first. */
-        LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_tw_pcbs", tcp_tw_pcbs == pcb);
-        tcp_tw_pcbs = pcb->next;
-      }
-      pcb2 = pcb->next;
-      memp_free(MEMP_TCP_PCB, pcb);
-      pcb = pcb2;
-    } else {
-      prev = pcb;
-      pcb = pcb->next;
-    }
-  }
-}
-
-/**
- * Is called every TCP_FAST_INTERVAL (250 ms) and sends delayed ACKs.
- */
-void
-tcp_fasttmr(void)
-{
-  struct tcp_pcb *pcb;
-
-  /* send delayed ACKs */  
-  for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
-    if (pcb->flags & TF_ACK_DELAY) {
-      LWIP_DEBUGF(TCP_DEBUG, ("tcp_fasttmr: delayed ACK\n"));
-      tcp_ack_now(pcb);
-      pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);
-    }
-  }
-}
-
-/**
- * Deallocates a list of TCP segments (tcp_seg structures).
- *
- */
-u8_t
-tcp_segs_free(struct tcp_seg *seg)
-{
-  u8_t count = 0;
-  struct tcp_seg *next;
-  while (seg != NULL) {
-    next = seg->next;
-    count += tcp_seg_free(seg);
-    seg = next;
-  }
-  return count;
-}
-
-/**
- * Frees a TCP segment.
- *
- */
-u8_t
-tcp_seg_free(struct tcp_seg *seg)
-{
-  u8_t count = 0;
-  
-  if (seg != NULL) {
-    if (seg->p != NULL) {
-      count = pbuf_free(seg->p);
-#if TCP_DEBUG
-      seg->p = NULL;
-#endif /* TCP_DEBUG */
-    }
-    memp_free(MEMP_TCP_SEG, seg);
-  }
-  return count;
-}
-
-/**
- * Sets the priority of a connection.
- *
- */
-void
-tcp_setprio(struct tcp_pcb *pcb, u8_t prio)
-{
-  pcb->prio = prio;
-}
-#if TCP_QUEUE_OOSEQ
-
-/**
- * Returns a copy of the given TCP segment.
- *
- */ 
-struct tcp_seg *
-tcp_seg_copy(struct tcp_seg *seg)
-{
-  struct tcp_seg *cseg;
-
-  cseg = memp_malloc(MEMP_TCP_SEG);
-  if (cseg == NULL) {
-    return NULL;
-  }
-  memcpy((u8_t *)cseg, (const u8_t *)seg, sizeof(struct tcp_seg)); 
-  pbuf_ref(cseg->p);
-  return cseg;
-}
-#endif
-
-#if LWIP_CALLBACK_API
-static err_t
-tcp_recv_null(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
-{
-  arg = arg;
-  if (p != NULL) {
-    pbuf_free(p);
-  } else if (err == ERR_OK) {
-    return tcp_close(pcb);
-  }
-  return ERR_OK;
-}
-#endif /* LWIP_CALLBACK_API */
-
-static void
-tcp_kill_prio(u8_t prio)
-{
-  struct tcp_pcb *pcb, *inactive;
-  u32_t inactivity;
-  u8_t mprio;
-
-
-  mprio = TCP_PRIO_MAX;
-  
-  /* We kill the oldest active connection that has lower priority than
-     prio. */
-  inactivity = 0;
-  inactive = NULL;
-  for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
-    if (pcb->prio <= prio &&
-       pcb->prio <= mprio &&
-       (u32_t)(tcp_ticks - pcb->tmr) >= inactivity) {
-      inactivity = tcp_ticks - pcb->tmr;
-      inactive = pcb;
-      mprio = pcb->prio;
-    }
-  }
-  if (inactive != NULL) {
-    LWIP_DEBUGF(TCP_DEBUG, ("tcp_kill_prio: killing oldest PCB %p (%"S32_F")\n",
-           (void *)inactive, inactivity));
-    tcp_abort(inactive);
-  }      
-}
-
-
-static void
-tcp_kill_timewait(void)
-{
-  struct tcp_pcb *pcb, *inactive;
-  u32_t inactivity;
-
-  inactivity = 0;
-  inactive = NULL;
-  for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
-    if ((u32_t)(tcp_ticks - pcb->tmr) >= inactivity) {
-      inactivity = tcp_ticks - pcb->tmr;
-      inactive = pcb;
-    }
-  }
-  if (inactive != NULL) {
-    LWIP_DEBUGF(TCP_DEBUG, ("tcp_kill_timewait: killing oldest TIME-WAIT PCB %p (%"S32_F")\n",
-           (void *)inactive, inactivity));
-    tcp_abort(inactive);
-  }      
-}
-
-
-
-struct tcp_pcb *
-tcp_alloc(u8_t prio)
-{
-  struct tcp_pcb *pcb;
-  u32_t iss;
-  
-  pcb = memp_malloc(MEMP_TCP_PCB);
-  if (pcb == NULL) {
-    /* Try killing oldest connection in TIME-WAIT. */
-    LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: killing off oldest TIME-WAIT connection\n"));
-    tcp_kill_timewait();
-    pcb = memp_malloc(MEMP_TCP_PCB);
-    if (pcb == NULL) {
-      tcp_kill_prio(prio);    
-      pcb = memp_malloc(MEMP_TCP_PCB);
-    }
-  }
-  if (pcb != NULL) {
-    memset(pcb, 0, sizeof(struct tcp_pcb));
-    pcb->prio = TCP_PRIO_NORMAL;
-    pcb->snd_buf = TCP_SND_BUF;
-    pcb->snd_queuelen = 0;
-    pcb->rcv_wnd = TCP_WND;
-    pcb->tos = 0;
-    pcb->ttl = TCP_TTL;
-    pcb->mss = TCP_MSS;
-    pcb->rto = 3000 / TCP_SLOW_INTERVAL;
-    pcb->sa = 0;
-    pcb->sv = 3000 / TCP_SLOW_INTERVAL;
-    pcb->rtime = 0;
-    pcb->cwnd = 1;
-    iss = tcp_next_iss();
-    pcb->snd_wl2 = iss;
-    pcb->snd_nxt = iss;
-    pcb->snd_max = iss;
-    pcb->lastack = iss;
-    pcb->snd_lbb = iss;   
-    pcb->tmr = tcp_ticks;
-
-    pcb->polltmr = 0;
-
-#if LWIP_CALLBACK_API
-    pcb->recv = tcp_recv_null;
-#endif /* LWIP_CALLBACK_API */  
-    
-    /* Init KEEPALIVE timer */
-    pcb->keepalive = TCP_KEEPDEFAULT;
-    pcb->keep_cnt = 0;
-  }
-  return pcb;
-}
-
-/**
- * Creates a new TCP protocol control block but doesn't place it on
- * any of the TCP PCB lists.
- *
- * @internal: Maybe there should be a idle TCP PCB list where these
- * PCBs are put on. We can then implement port reservation using
- * tcp_bind(). Currently, we lack this (BSD socket type of) feature.
- */
-
-struct tcp_pcb *
-tcp_new(void)
-{
-  return tcp_alloc(TCP_PRIO_NORMAL);
-}
-
-/*
- * tcp_arg():
- *
- * Used to specify the argument that should be passed callback
- * functions.
- *
- */ 
-
-void
-tcp_arg(struct tcp_pcb *pcb, void *arg)
-{  
-  pcb->callback_arg = arg;
-}
-#if LWIP_CALLBACK_API
-
-/**
- * Used to specify the function that should be called when a TCP
- * connection receives data.
- *
- */ 
-void
-tcp_recv(struct tcp_pcb *pcb,
-   err_t (* recv)(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err))
-{
-  pcb->recv = recv;
-}
-
-/**
- * Used to specify the function that should be called when TCP data
- * has been successfully delivered to the remote host.
- *
- */ 
-
-void
-tcp_sent(struct tcp_pcb *pcb,
-   err_t (* sent)(void *arg, struct tcp_pcb *tpcb, u16_t len))
-{
-  pcb->sent = sent;
-}
-
-/**
- * Used to specify the function that should be called when a fatal error
- * has occured on the connection.
- *
- */ 
-void
-tcp_err(struct tcp_pcb *pcb,
-   void (* errf)(void *arg, err_t err))
-{
-  pcb->errf = errf;
-}
-
-/**
- * Used for specifying the function that should be called when a
- * LISTENing connection has been connected to another host.
- *
- */ 
-void
-tcp_accept(struct tcp_pcb *pcb,
-     err_t (* accept)(void *arg, struct tcp_pcb *newpcb, err_t err))
-{
-  ((struct tcp_pcb_listen *)pcb)->accept = accept;
-}
-#endif /* LWIP_CALLBACK_API */
-
-
-/**
- * Used to specify the function that should be called periodically
- * from TCP. The interval is specified in terms of the TCP coarse
- * timer interval, which is called twice a second.
- *
- */ 
-void
-tcp_poll(struct tcp_pcb *pcb,
-   err_t (* poll)(void *arg, struct tcp_pcb *tpcb), u8_t interval)
-{
-#if LWIP_CALLBACK_API
-  pcb->poll = poll;
-#endif /* LWIP_CALLBACK_API */  
-  pcb->pollinterval = interval;
-}
-
-/**
- * Purges a TCP PCB. Removes any buffered data and frees the buffer memory.
- *
- */
-void
-tcp_pcb_purge(struct tcp_pcb *pcb)
-{
-  if (pcb->state != CLOSED &&
-     pcb->state != TIME_WAIT &&
-     pcb->state != LISTEN) {
-
-    LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge\n"));
-    
-    if (pcb->unsent != NULL) {    
-      LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: not all data sent\n"));
-    }
-    if (pcb->unacked != NULL) {    
-      LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->unacked\n"));
-    }
-#if TCP_QUEUE_OOSEQ /* LW */
-    if (pcb->ooseq != NULL) {    
-      LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->ooseq\n"));
-    }
-    
-    tcp_segs_free(pcb->ooseq);
-    pcb->ooseq = NULL;
-#endif /* TCP_QUEUE_OOSEQ */
-    tcp_segs_free(pcb->unsent);
-    tcp_segs_free(pcb->unacked);
-    pcb->unacked = pcb->unsent = NULL;
-  }
-}
-
-/**
- * Purges the PCB and removes it from a PCB list. Any delayed ACKs are sent first.
- *
- */
-void
-tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb)
-{
-  TCP_RMV(pcblist, pcb);
-
-  tcp_pcb_purge(pcb);
-  
-  /* if there is an outstanding delayed ACKs, send it */
-  if (pcb->state != TIME_WAIT &&
-     pcb->state != LISTEN &&
-     pcb->flags & TF_ACK_DELAY) {
-    pcb->flags |= TF_ACK_NOW;
-    tcp_output(pcb);
-  }  
-  pcb->state = CLOSED;
-
-  LWIP_ASSERT("tcp_pcb_remove: tcp_pcbs_sane()", tcp_pcbs_sane());
-}
-
-/**
- * Calculates a new initial sequence number for new connections.
- *
- */
-u32_t
-tcp_next_iss(void)
-{
-  static u32_t iss = 6510;
-  
-  iss += tcp_ticks;       /* XXX */
-  return iss;
-}
-
-#if TCP_DEBUG || TCP_INPUT_DEBUG || TCP_OUTPUT_DEBUG
-void
-tcp_debug_print(struct tcp_hdr *tcphdr)
-{
-  LWIP_DEBUGF(TCP_DEBUG, ("TCP header:\n"));
-  LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
-  LWIP_DEBUGF(TCP_DEBUG, ("|    %5"U16_F"      |    %5"U16_F"      | (src port, dest port)\n",
-         ntohs(tcphdr->src), ntohs(tcphdr->dest)));
-  LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
-  LWIP_DEBUGF(TCP_DEBUG, ("|           %010"U32_F"          | (seq no)\n",
-          ntohl(tcphdr->seqno)));
-  LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
-  LWIP_DEBUGF(TCP_DEBUG, ("|           %010"U32_F"          | (ack no)\n",
-         ntohl(tcphdr->ackno)));
-  LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
-  LWIP_DEBUGF(TCP_DEBUG, ("| %2"U16_F" |   |%"U16_F"%"U16_F"%"U16_F"%"U16_F"%"U16_F"%"U16_F"|     %5"U16_F"     | (hdrlen, flags (",
-       TCPH_HDRLEN(tcphdr),
-         TCPH_FLAGS(tcphdr) >> 5 & 1,
-         TCPH_FLAGS(tcphdr) >> 4 & 1,
-         TCPH_FLAGS(tcphdr) >> 3 & 1,
-         TCPH_FLAGS(tcphdr) >> 2 & 1,
-         TCPH_FLAGS(tcphdr) >> 1 & 1,
-         TCPH_FLAGS(tcphdr) & 1,
-         ntohs(tcphdr->wnd)));
-  tcp_debug_print_flags(TCPH_FLAGS(tcphdr));
-  LWIP_DEBUGF(TCP_DEBUG, ("), win)\n"));
-  LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
-  LWIP_DEBUGF(TCP_DEBUG, ("|    0x%04"X16_F"     |     %5"U16_F"     | (chksum, urgp)\n",
-         ntohs(tcphdr->chksum), ntohs(tcphdr->urgp)));
-  LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
-}
-
-void
-tcp_debug_print_state(enum tcp_state s)
-{
-  LWIP_DEBUGF(TCP_DEBUG, ("State: "));
-  switch (s) {
-  case CLOSED:
-    LWIP_DEBUGF(TCP_DEBUG, ("CLOSED\n"));
-    break;
- case LISTEN:
-   LWIP_DEBUGF(TCP_DEBUG, ("LISTEN\n"));
-   break;
-  case SYN_SENT:
-    LWIP_DEBUGF(TCP_DEBUG, ("SYN_SENT\n"));
-    break;
-  case SYN_RCVD:
-    LWIP_DEBUGF(TCP_DEBUG, ("SYN_RCVD\n"));
-    break;
-  case ESTABLISHED:
-    LWIP_DEBUGF(TCP_DEBUG, ("ESTABLISHED\n"));
-    break;
-  case FIN_WAIT_1:
-    LWIP_DEBUGF(TCP_DEBUG, ("FIN_WAIT_1\n"));
-    break;
-  case FIN_WAIT_2:
-    LWIP_DEBUGF(TCP_DEBUG, ("FIN_WAIT_2\n"));
-    break;
-  case CLOSE_WAIT:
-    LWIP_DEBUGF(TCP_DEBUG, ("CLOSE_WAIT\n"));
-    break;
-  case CLOSING:
-    LWIP_DEBUGF(TCP_DEBUG, ("CLOSING\n"));
-    break;
-  case LAST_ACK:
-    LWIP_DEBUGF(TCP_DEBUG, ("LAST_ACK\n"));
-    break;
-  case TIME_WAIT:
-    LWIP_DEBUGF(TCP_DEBUG, ("TIME_WAIT\n"));
-   break;
-  }
-}
-
-void
-tcp_debug_print_flags(u8_t flags)
-{
-  if (flags & TCP_FIN) {
-    LWIP_DEBUGF(TCP_DEBUG, ("FIN "));
-  }
-  if (flags & TCP_SYN) {
-    LWIP_DEBUGF(TCP_DEBUG, ("SYN "));
-  }
-  if (flags & TCP_RST) {
-    LWIP_DEBUGF(TCP_DEBUG, ("RST "));
-  }
-  if (flags & TCP_PSH) {
-    LWIP_DEBUGF(TCP_DEBUG, ("PSH "));
-  }
-  if (flags & TCP_ACK) {
-    LWIP_DEBUGF(TCP_DEBUG, ("ACK "));
-  }
-  if (flags & TCP_URG) {
-    LWIP_DEBUGF(TCP_DEBUG, ("URG "));
-  }
-  if (flags & TCP_ECE) {
-    LWIP_DEBUGF(TCP_DEBUG, ("ECE "));
-  }
-  if (flags & TCP_CWR) {
-    LWIP_DEBUGF(TCP_DEBUG, ("CWR "));
-  }
-}
-
-void
-tcp_debug_print_pcbs(void)
-{
-  struct tcp_pcb *pcb;
-  LWIP_DEBUGF(TCP_DEBUG, ("Active PCB states:\n"));
-  for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
-    LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ",
-                       pcb->local_port, pcb->remote_port,
-                       pcb->snd_nxt, pcb->rcv_nxt));
-    tcp_debug_print_state(pcb->state);
-  }    
-  LWIP_DEBUGF(TCP_DEBUG, ("Listen PCB states:\n"));
-  for(pcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs; pcb != NULL; pcb = pcb->next) {
-    LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ",
-                       pcb->local_port, pcb->remote_port,
-                       pcb->snd_nxt, pcb->rcv_nxt));
-    tcp_debug_print_state(pcb->state);
-  }    
-  LWIP_DEBUGF(TCP_DEBUG, ("TIME-WAIT PCB states:\n"));
-  for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
-    LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ",
-                       pcb->local_port, pcb->remote_port,
-                       pcb->snd_nxt, pcb->rcv_nxt));
-    tcp_debug_print_state(pcb->state);
-  }    
-}
-
-s16_t
-tcp_pcbs_sane(void)
-{
-  struct tcp_pcb *pcb;
-  for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
-    LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != CLOSED", pcb->state != CLOSED);
-    LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != LISTEN", pcb->state != LISTEN);
-    LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT);
-  }
-  for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
-    LWIP_ASSERT("tcp_pcbs_sane: tw pcb->state == TIME-WAIT", pcb->state == TIME_WAIT);
-  }
-  return 1;
-}
-#endif /* TCP_DEBUG */
-#endif /* LWIP_TCP */
-
-
-
-
-
-
-
-
-
-
+/**\r
+ * @file\r
+ *\r
+ * Transmission Control Protocol for IP\r
+ *\r
+ * This file contains common functions for the TCP implementation, such as functinos\r
+ * for manipulating the data structures and the TCP timer functions. TCP functions\r
+ * related to input and output is found in tcp_in.c and tcp_out.c respectively.\r
+ *\r
+ */\r
+\r
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+\r
+#include <string.h>\r
+\r
+#include "lwip/opt.h"\r
+#include "lwip/def.h"\r
+#include "lwip/mem.h"\r
+#include "lwip/memp.h"\r
+\r
+#include "lwip/tcp.h"\r
+#if LWIP_TCP\r
+\r
+/* Incremented every coarse grained timer shot\r
+   (typically every 500 ms, determined by TCP_COARSE_TIMEOUT). */\r
+u32_t tcp_ticks;\r
+const u8_t tcp_backoff[13] =\r
+    { 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7};\r
+\r
+/* The TCP PCB lists. */\r
+\r
+/** List of all TCP PCBs in LISTEN state */\r
+union tcp_listen_pcbs_t tcp_listen_pcbs;\r
+/** List of all TCP PCBs that are in a state in which\r
+ * they accept or send data. */\r
+struct tcp_pcb *tcp_active_pcbs;  \r
+/** List of all TCP PCBs in TIME-WAIT state */\r
+struct tcp_pcb *tcp_tw_pcbs;\r
+\r
+struct tcp_pcb *tcp_tmp_pcb;\r
+\r
+static u8_t tcp_timer;\r
+static u16_t tcp_new_port(void);\r
+\r
+/**\r
+ * Initializes the TCP layer.\r
+ */\r
+void\r
+tcp_init(void)\r
+{\r
+  /* Clear globals. */\r
+  tcp_listen_pcbs.listen_pcbs = NULL;\r
+  tcp_active_pcbs = NULL;\r
+  tcp_tw_pcbs = NULL;\r
+  tcp_tmp_pcb = NULL;\r
+  \r
+  /* initialize timer */\r
+  tcp_ticks = 0;\r
+  tcp_timer = 0;\r
+  \r
+}\r
+\r
+/**\r
+ * Called periodically to dispatch TCP timers.\r
+ *\r
+ */\r
+void\r
+tcp_tmr(void)\r
+{\r
+  /* Call tcp_fasttmr() every 250 ms */\r
+  tcp_fasttmr();\r
+\r
+  if (++tcp_timer & 1) {\r
+    /* Call tcp_tmr() every 500 ms, i.e., every other timer\r
+       tcp_tmr() is called. */\r
+    tcp_slowtmr();\r
+  }\r
+}\r
+\r
+/**\r
+ * Closes the connection held by the PCB.\r
+ *\r
+ */\r
+err_t\r
+tcp_close(struct tcp_pcb *pcb)\r
+{\r
+  err_t err;\r
+\r
+#if TCP_DEBUG\r
+  LWIP_DEBUGF(TCP_DEBUG, ("tcp_close: closing in state "));\r
+  tcp_debug_print_state(pcb->state);\r
+  LWIP_DEBUGF(TCP_DEBUG, ("\n"));\r
+#endif /* TCP_DEBUG */\r
+  switch (pcb->state) {\r
+  case CLOSED:\r
+    /* Closing a pcb in the CLOSED state might seem erroneous,\r
+     * however, it is in this state once allocated and as yet unused\r
+     * and the user needs some way to free it should the need arise.\r
+     * Calling tcp_close() with a pcb that has already been closed, (i.e. twice)\r
+     * or for a pcb that has been used and then entered the CLOSED state \r
+     * is erroneous, but this should never happen as the pcb has in those cases\r
+     * been freed, and so any remaining handles are bogus. */\r
+    err = ERR_OK;\r
+    memp_free(MEMP_TCP_PCB, pcb);\r
+    pcb = NULL;\r
+    break;\r
+  case LISTEN:\r
+    err = ERR_OK;\r
+    tcp_pcb_remove((struct tcp_pcb **)&tcp_listen_pcbs.pcbs, pcb);\r
+    memp_free(MEMP_TCP_PCB_LISTEN, pcb);\r
+    pcb = NULL;\r
+    break;\r
+  case SYN_SENT:\r
+    err = ERR_OK;\r
+    tcp_pcb_remove(&tcp_active_pcbs, pcb);\r
+    memp_free(MEMP_TCP_PCB, pcb);\r
+    pcb = NULL;\r
+    break;\r
+  case SYN_RCVD:\r
+  case ESTABLISHED:\r
+    err = tcp_send_ctrl(pcb, TCP_FIN);\r
+    if (err == ERR_OK) {\r
+      pcb->state = FIN_WAIT_1;\r
+    }\r
+    break;\r
+  case CLOSE_WAIT:\r
+    err = tcp_send_ctrl(pcb, TCP_FIN);\r
+    if (err == ERR_OK) {\r
+      pcb->state = LAST_ACK;\r
+    }\r
+    break;\r
+  default:\r
+    /* Has already been closed, do nothing. */\r
+    err = ERR_OK;\r
+    pcb = NULL;\r
+    break;\r
+  }\r
+\r
+  if (pcb != NULL && err == ERR_OK) {\r
+    err = tcp_output(pcb);\r
+  }\r
+  return err;\r
+}\r
+\r
+/**\r
+ * Aborts a connection by sending a RST to the remote host and deletes\r
+ * the local protocol control block. This is done when a connection is\r
+ * killed because of shortage of memory.\r
+ *\r
+ */\r
+void\r
+tcp_abort(struct tcp_pcb *pcb)\r
+{\r
+  u32_t seqno, ackno;\r
+  u16_t remote_port, local_port;\r
+  struct ip_addr remote_ip, local_ip;\r
+#if LWIP_CALLBACK_API  \r
+  void (* errf)(void *arg, err_t err);\r
+#endif /* LWIP_CALLBACK_API */\r
+  void *errf_arg;\r
+\r
+  \r
+  /* Figure out on which TCP PCB list we are, and remove us. If we\r
+     are in an active state, call the receive function associated with\r
+     the PCB with a NULL argument, and send an RST to the remote end. */\r
+  if (pcb->state == TIME_WAIT) {\r
+    tcp_pcb_remove(&tcp_tw_pcbs, pcb);\r
+    memp_free(MEMP_TCP_PCB, pcb);\r
+  } else {\r
+    seqno = pcb->snd_nxt;\r
+    ackno = pcb->rcv_nxt;\r
+    ip_addr_set(&local_ip, &(pcb->local_ip));\r
+    ip_addr_set(&remote_ip, &(pcb->remote_ip));\r
+    local_port = pcb->local_port;\r
+    remote_port = pcb->remote_port;\r
+#if LWIP_CALLBACK_API\r
+    errf = pcb->errf;\r
+#endif /* LWIP_CALLBACK_API */\r
+    errf_arg = pcb->callback_arg;\r
+    tcp_pcb_remove(&tcp_active_pcbs, pcb);\r
+    if (pcb->unacked != NULL) {\r
+      tcp_segs_free(pcb->unacked);\r
+    }\r
+    if (pcb->unsent != NULL) {\r
+      tcp_segs_free(pcb->unsent);\r
+    }\r
+#if TCP_QUEUE_OOSEQ    \r
+    if (pcb->ooseq != NULL) {\r
+      tcp_segs_free(pcb->ooseq);\r
+    }\r
+#endif /* TCP_QUEUE_OOSEQ */\r
+    memp_free(MEMP_TCP_PCB, pcb);\r
+    TCP_EVENT_ERR(errf, errf_arg, ERR_ABRT);\r
+    LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_abort: sending RST\n"));\r
+    tcp_rst(seqno, ackno, &local_ip, &remote_ip, local_port, remote_port);\r
+  }\r
+}\r
+\r
+/**\r
+ * Binds the connection to a local portnumber and IP address. If the\r
+ * IP address is not given (i.e., ipaddr == NULL), the IP address of\r
+ * the outgoing network interface is used instead.\r
+ *\r
+ */\r
+\r
+err_t\r
+tcp_bind(struct tcp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)\r
+{\r
+  struct tcp_pcb *cpcb;\r
+\r
+  if (port == 0) {\r
+    port = tcp_new_port();\r
+  }\r
+  /* Check if the address already is in use. */\r
+  for(cpcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs;\r
+      cpcb != NULL; cpcb = cpcb->next) {\r
+    if (cpcb->local_port == port) {\r
+      if (ip_addr_isany(&(cpcb->local_ip)) ||\r
+        ip_addr_isany(ipaddr) ||\r
+        ip_addr_cmp(&(cpcb->local_ip), ipaddr)) {\r
+          return ERR_USE;\r
+      }\r
+    }\r
+  }\r
+  for(cpcb = tcp_active_pcbs;\r
+      cpcb != NULL; cpcb = cpcb->next) {\r
+    if (cpcb->local_port == port) {\r
+      if (ip_addr_isany(&(cpcb->local_ip)) ||\r
+   ip_addr_isany(ipaddr) ||\r
+   ip_addr_cmp(&(cpcb->local_ip), ipaddr)) {\r
+  return ERR_USE;\r
+      }\r
+    }\r
+  }\r
+\r
+  if (!ip_addr_isany(ipaddr)) {\r
+    pcb->local_ip = *ipaddr;\r
+  }\r
+  pcb->local_port = port;\r
+  LWIP_DEBUGF(TCP_DEBUG, ("tcp_bind: bind to port %"U16_F"\n", port));\r
+  return ERR_OK;\r
+}\r
+#if LWIP_CALLBACK_API\r
+static err_t\r
+tcp_accept_null(void *arg, struct tcp_pcb *pcb, err_t err)\r
+{\r
+  (void)arg;\r
+  (void)pcb;\r
+  (void)err;\r
+\r
+  return ERR_ABRT;\r
+}\r
+#endif /* LWIP_CALLBACK_API */\r
+\r
+/**\r
+ * Set the state of the connection to be LISTEN, which means that it\r
+ * is able to accept incoming connections. The protocol control block\r
+ * is reallocated in order to consume less memory. Setting the\r
+ * connection to LISTEN is an irreversible process.\r
+ *\r
+ */\r
+struct tcp_pcb *\r
+tcp_listen(struct tcp_pcb *pcb)\r
+{\r
+  struct tcp_pcb_listen *lpcb;\r
+\r
+  /* already listening? */\r
+  if (pcb->state == LISTEN) {\r
+    return pcb;\r
+  }\r
+  lpcb = memp_malloc(MEMP_TCP_PCB_LISTEN);\r
+  if (lpcb == NULL) {\r
+    return NULL;\r
+  }\r
+  lpcb->callback_arg = pcb->callback_arg;\r
+  lpcb->local_port = pcb->local_port;\r
+  lpcb->state = LISTEN;\r
+  lpcb->so_options = pcb->so_options;\r
+  lpcb->so_options |= SOF_ACCEPTCONN;\r
+  lpcb->ttl = pcb->ttl;\r
+  lpcb->tos = pcb->tos;\r
+  ip_addr_set(&lpcb->local_ip, &pcb->local_ip);\r
+  memp_free(MEMP_TCP_PCB, pcb);\r
+#if LWIP_CALLBACK_API\r
+  lpcb->accept = tcp_accept_null;\r
+#endif /* LWIP_CALLBACK_API */\r
+  TCP_REG(&tcp_listen_pcbs.listen_pcbs, lpcb);\r
+  return (struct tcp_pcb *)lpcb;\r
+}\r
+\r
+/**\r
+ * This function should be called by the application when it has\r
+ * processed the data. The purpose is to advertise a larger window\r
+ * when the data has been processed.\r
+ *\r
+ */\r
+void\r
+tcp_recved(struct tcp_pcb *pcb, u16_t len)\r
+{\r
+  if ((u32_t)pcb->rcv_wnd + len > TCP_WND) {\r
+    pcb->rcv_wnd = TCP_WND;\r
+  } else {\r
+    pcb->rcv_wnd += len;\r
+  }\r
+  if (!(pcb->flags & TF_ACK_DELAY) &&\r
+     !(pcb->flags & TF_ACK_NOW)) {\r
+    /*\r
+     * We send an ACK here (if one is not already pending, hence\r
+     * the above tests) as tcp_recved() implies that the application\r
+     * has processed some data, and so we can open the receiver's\r
+     * window to allow more to be transmitted.  This could result in\r
+     * two ACKs being sent for each received packet in some limited cases\r
+     * (where the application is only receiving data, and is slow to\r
+     * process it) but it is necessary to guarantee that the sender can\r
+     * continue to transmit.\r
+     */\r
+    tcp_ack(pcb);\r
+  } \r
+  else if (pcb->flags & TF_ACK_DELAY && pcb->rcv_wnd >= TCP_WND/2) {\r
+    /* If we can send a window update such that there is a full\r
+     * segment available in the window, do so now.  This is sort of\r
+     * nagle-like in its goals, and tries to hit a compromise between\r
+     * sending acks each time the window is updated, and only sending\r
+     * window updates when a timer expires.  The "threshold" used\r
+     * above (currently TCP_WND/2) can be tuned to be more or less\r
+     * aggressive  */\r
+    tcp_ack_now(pcb);\r
+  }\r
+\r
+  LWIP_DEBUGF(TCP_DEBUG, ("tcp_recved: recveived %"U16_F" bytes, wnd %"U16_F" (%"U16_F").\n",\r
+         len, pcb->rcv_wnd, TCP_WND - pcb->rcv_wnd));\r
+}\r
+\r
+/**\r
+ * A nastly hack featuring 'goto' statements that allocates a\r
+ * new TCP local port.\r
+ */\r
+static u16_t\r
+tcp_new_port(void)\r
+{\r
+  struct tcp_pcb *pcb;\r
+#ifndef TCP_LOCAL_PORT_RANGE_START\r
+#define TCP_LOCAL_PORT_RANGE_START 4096\r
+#define TCP_LOCAL_PORT_RANGE_END   0x7fff\r
+#endif\r
+  static u16_t port = TCP_LOCAL_PORT_RANGE_START;\r
+  \r
+ again:\r
+  if (++port > TCP_LOCAL_PORT_RANGE_END) {\r
+    port = TCP_LOCAL_PORT_RANGE_START;\r
+  }\r
+  \r
+  for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {\r
+    if (pcb->local_port == port) {\r
+      goto again;\r
+    }\r
+  }\r
+  for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {\r
+    if (pcb->local_port == port) {\r
+      goto again;\r
+    }\r
+  }\r
+  for(pcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs; pcb != NULL; pcb = pcb->next) {\r
+    if (pcb->local_port == port) {\r
+      goto again;\r
+    }\r
+  }\r
+  return port;\r
+}\r
+\r
+/**\r
+ * Connects to another host. The function given as the "connected"\r
+ * argument will be called when the connection has been established.\r
+ *\r
+ */\r
+err_t\r
+tcp_connect(struct tcp_pcb *pcb, struct ip_addr *ipaddr, u16_t port,\r
+      err_t (* connected)(void *arg, struct tcp_pcb *tpcb, err_t err))\r
+{\r
+  u32_t optdata;\r
+  err_t ret;\r
+  u32_t iss;\r
+\r
+  LWIP_DEBUGF(TCP_DEBUG, ("tcp_connect to port %"U16_F"\n", port));\r
+  if (ipaddr != NULL) {\r
+    pcb->remote_ip = *ipaddr;\r
+  } else {\r
+    return ERR_VAL;\r
+  }\r
+  pcb->remote_port = port;\r
+  if (pcb->local_port == 0) {\r
+    pcb->local_port = tcp_new_port();\r
+  }\r
+  iss = tcp_next_iss();\r
+  pcb->rcv_nxt = 0;\r
+  pcb->snd_nxt = iss;\r
+  pcb->lastack = iss - 1;\r
+  pcb->snd_lbb = iss - 1;\r
+  pcb->rcv_wnd = TCP_WND;\r
+  pcb->snd_wnd = TCP_WND;\r
+  pcb->mss = TCP_MSS;\r
+  pcb->cwnd = 1;\r
+  pcb->ssthresh = pcb->mss * 10;\r
+  pcb->state = SYN_SENT;\r
+#if LWIP_CALLBACK_API  \r
+  pcb->connected = connected;\r
+#endif /* LWIP_CALLBACK_API */  \r
+  TCP_REG(&tcp_active_pcbs, pcb);\r
+  \r
+  /* Build an MSS option */\r
+  optdata = htonl(((u32_t)2 << 24) | \r
+      ((u32_t)4 << 16) | \r
+      (((u32_t)pcb->mss / 256) << 8) |\r
+      (pcb->mss & 255));\r
+\r
+  ret = tcp_enqueue(pcb, NULL, 0, TCP_SYN, 0, (u8_t *)&optdata, 4);\r
+  if (ret == ERR_OK) { \r
+    tcp_output(pcb);\r
+  }\r
+  return ret;\r
+} \r
+\r
+/**\r
+ * Called every 500 ms and implements the retransmission timer and the timer that\r
+ * removes PCBs that have been in TIME-WAIT for enough time. It also increments\r
+ * various timers such as the inactivity timer in each PCB.\r
+ */\r
+void\r
+tcp_slowtmr(void)\r
+{\r
+  struct tcp_pcb *pcb, *pcb2, *prev;\r
+  u32_t eff_wnd;\r
+  u8_t pcb_remove;      /* flag if a PCB should be removed */\r
+  err_t err;\r
+\r
+  err = ERR_OK;\r
+\r
+  ++tcp_ticks;\r
+\r
+  /* Steps through all of the active PCBs. */\r
+  prev = NULL;\r
+  pcb = tcp_active_pcbs;\r
+  if (pcb == NULL) {\r
+    LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: no active pcbs\n"));\r
+  }\r
+  while (pcb != NULL) {\r
+    LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: processing active pcb\n"));\r
+    LWIP_ASSERT("tcp_slowtmr: active pcb->state != CLOSED\n", pcb->state != CLOSED);\r
+    LWIP_ASSERT("tcp_slowtmr: active pcb->state != LISTEN\n", pcb->state != LISTEN);\r
+    LWIP_ASSERT("tcp_slowtmr: active pcb->state != TIME-WAIT\n", pcb->state != TIME_WAIT);\r
+\r
+    pcb_remove = 0;\r
+\r
+    if (pcb->state == SYN_SENT && pcb->nrtx == TCP_SYNMAXRTX) {\r
+      ++pcb_remove;\r
+      LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max SYN retries reached\n"));\r
+    }\r
+    else if (pcb->nrtx == TCP_MAXRTX) {\r
+      ++pcb_remove;\r
+      LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max DATA retries reached\n"));\r
+    } else {\r
+      ++pcb->rtime;\r
+      if (pcb->unacked != NULL && pcb->rtime >= pcb->rto) {\r
+\r
+        /* Time for a retransmission. */\r
+        LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_slowtmr: rtime %"U16_F" pcb->rto %"U16_F"\n",\r
+          pcb->rtime, pcb->rto));\r
+\r
+        /* Double retransmission time-out unless we are trying to\r
+         * connect to somebody (i.e., we are in SYN_SENT). */\r
+        if (pcb->state != SYN_SENT) {\r
+          pcb->rto = ((pcb->sa >> 3) + pcb->sv) << tcp_backoff[pcb->nrtx];\r
+        }\r
+        /* Reduce congestion window and ssthresh. */\r
+        eff_wnd = LWIP_MIN(pcb->cwnd, pcb->snd_wnd);\r
+        pcb->ssthresh = eff_wnd >> 1;\r
+        if (pcb->ssthresh < pcb->mss) {\r
+          pcb->ssthresh = pcb->mss * 2;\r
+        }\r
+        pcb->cwnd = pcb->mss;\r
+        LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_slowtmr: cwnd %"U16_F" ssthresh %"U16_F"\n",\r
+                                pcb->cwnd, pcb->ssthresh));\r
\r
+        /* The following needs to be called AFTER cwnd is set to one mss - STJ */\r
+        tcp_rexmit_rto(pcb);\r
+     }\r
+    }\r
+    /* Check if this PCB has stayed too long in FIN-WAIT-2 */\r
+    if (pcb->state == FIN_WAIT_2) {\r
+      if ((u32_t)(tcp_ticks - pcb->tmr) >\r
+        TCP_FIN_WAIT_TIMEOUT / TCP_SLOW_INTERVAL) {\r
+        ++pcb_remove;\r
+        LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in FIN-WAIT-2\n"));\r
+      }\r
+    }\r
+\r
+   /* Check if KEEPALIVE should be sent */\r
+   if((pcb->so_options & SOF_KEEPALIVE) && ((pcb->state == ESTABLISHED) || (pcb->state == CLOSE_WAIT))) {\r
+      if((u32_t)(tcp_ticks - pcb->tmr) > (pcb->keepalive + TCP_MAXIDLE) / TCP_SLOW_INTERVAL)  {\r
+         LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: KEEPALIVE timeout. Aborting connection to %"U16_F".%"U16_F".%"U16_F".%"U16_F".\n",\r
+                                 ip4_addr1(&pcb->remote_ip), ip4_addr2(&pcb->remote_ip),\r
+                                 ip4_addr3(&pcb->remote_ip), ip4_addr4(&pcb->remote_ip)));\r
+\r
+         tcp_abort(pcb);\r
+      }\r
+      else if((u32_t)(tcp_ticks - pcb->tmr) > (pcb->keepalive + pcb->keep_cnt * TCP_KEEPINTVL) / TCP_SLOW_INTERVAL) {\r
+         tcp_keepalive(pcb);\r
+         pcb->keep_cnt++;\r
+      }\r
+   }\r
+\r
+    /* If this PCB has queued out of sequence data, but has been\r
+       inactive for too long, will drop the data (it will eventually\r
+       be retransmitted). */\r
+#if TCP_QUEUE_OOSEQ    \r
+    if (pcb->ooseq != NULL &&\r
+       (u32_t)tcp_ticks - pcb->tmr >=\r
+       pcb->rto * TCP_OOSEQ_TIMEOUT) {\r
+      tcp_segs_free(pcb->ooseq);\r
+      pcb->ooseq = NULL;\r
+      LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_slowtmr: dropping OOSEQ queued data\n"));\r
+    }\r
+#endif /* TCP_QUEUE_OOSEQ */\r
+\r
+    /* Check if this PCB has stayed too long in SYN-RCVD */\r
+    if (pcb->state == SYN_RCVD) {\r
+      if ((u32_t)(tcp_ticks - pcb->tmr) >\r
+        TCP_SYN_RCVD_TIMEOUT / TCP_SLOW_INTERVAL) {\r
+        ++pcb_remove;\r
+        LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in SYN-RCVD\n"));\r
+      }\r
+    }\r
+\r
+    /* Check if this PCB has stayed too long in LAST-ACK */\r
+    if (pcb->state == LAST_ACK) {\r
+      if ((u32_t)(tcp_ticks - pcb->tmr) > 2 * TCP_MSL / TCP_SLOW_INTERVAL) {\r
+        ++pcb_remove;\r
+        LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in LAST-ACK\n"));\r
+      }\r
+    }\r
+\r
+    /* If the PCB should be removed, do it. */\r
+    if (pcb_remove) {\r
+      tcp_pcb_purge(pcb);      \r
+      /* Remove PCB from tcp_active_pcbs list. */\r
+      if (prev != NULL) {\r
+  LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_active_pcbs", pcb != tcp_active_pcbs);\r
+        prev->next = pcb->next;\r
+      } else {\r
+        /* This PCB was the first. */\r
+        LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_active_pcbs", tcp_active_pcbs == pcb);\r
+        tcp_active_pcbs = pcb->next;\r
+      }\r
+\r
+      TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_ABRT);\r
+\r
+      pcb2 = pcb->next;\r
+      memp_free(MEMP_TCP_PCB, pcb);\r
+      pcb = pcb2;\r
+    } else {\r
+\r
+      /* We check if we should poll the connection. */\r
+      ++pcb->polltmr;\r
+      if (pcb->polltmr >= pcb->pollinterval) {\r
+        pcb->polltmr = 0;\r
+        LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: polling application\n"));\r
+        TCP_EVENT_POLL(pcb, err);\r
+        if (err == ERR_OK) {\r
+          tcp_output(pcb);\r
+        }\r
+      }\r
+      \r
+      prev = pcb;\r
+      pcb = pcb->next;\r
+    }\r
+  }\r
+\r
+  \r
+  /* Steps through all of the TIME-WAIT PCBs. */\r
+  prev = NULL;    \r
+  pcb = tcp_tw_pcbs;\r
+  while (pcb != NULL) {\r
+    LWIP_ASSERT("tcp_slowtmr: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT);\r
+    pcb_remove = 0;\r
+\r
+    /* Check if this PCB has stayed long enough in TIME-WAIT */\r
+    if ((u32_t)(tcp_ticks - pcb->tmr) > 2 * TCP_MSL / TCP_SLOW_INTERVAL) {\r
+      ++pcb_remove;\r
+    }\r
+    \r
+\r
+\r
+    /* If the PCB should be removed, do it. */\r
+    if (pcb_remove) {\r
+      tcp_pcb_purge(pcb);      \r
+      /* Remove PCB from tcp_tw_pcbs list. */\r
+      if (prev != NULL) {\r
+  LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_tw_pcbs", pcb != tcp_tw_pcbs);\r
+        prev->next = pcb->next;\r
+      } else {\r
+        /* This PCB was the first. */\r
+        LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_tw_pcbs", tcp_tw_pcbs == pcb);\r
+        tcp_tw_pcbs = pcb->next;\r
+      }\r
+      pcb2 = pcb->next;\r
+      memp_free(MEMP_TCP_PCB, pcb);\r
+      pcb = pcb2;\r
+    } else {\r
+      prev = pcb;\r
+      pcb = pcb->next;\r
+    }\r
+  }\r
+}\r
+\r
+/**\r
+ * Is called every TCP_FAST_INTERVAL (250 ms) and sends delayed ACKs.\r
+ */\r
+void\r
+tcp_fasttmr(void)\r
+{\r
+  struct tcp_pcb *pcb;\r
+\r
+  /* send delayed ACKs */  \r
+  for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {\r
+    if (pcb->flags & TF_ACK_DELAY) {\r
+      LWIP_DEBUGF(TCP_DEBUG, ("tcp_fasttmr: delayed ACK\n"));\r
+      tcp_ack_now(pcb);\r
+      pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);\r
+    }\r
+  }\r
+}\r
+\r
+/**\r
+ * Deallocates a list of TCP segments (tcp_seg structures).\r
+ *\r
+ */\r
+u8_t\r
+tcp_segs_free(struct tcp_seg *seg)\r
+{\r
+  u8_t count = 0;\r
+  struct tcp_seg *next;\r
+  while (seg != NULL) {\r
+    next = seg->next;\r
+    count += tcp_seg_free(seg);\r
+    seg = next;\r
+  }\r
+  return count;\r
+}\r
+\r
+/**\r
+ * Frees a TCP segment.\r
+ *\r
+ */\r
+u8_t\r
+tcp_seg_free(struct tcp_seg *seg)\r
+{\r
+  u8_t count = 0;\r
+  \r
+  if (seg != NULL) {\r
+    if (seg->p != NULL) {\r
+      count = pbuf_free(seg->p);\r
+#if TCP_DEBUG\r
+      seg->p = NULL;\r
+#endif /* TCP_DEBUG */\r
+    }\r
+    memp_free(MEMP_TCP_SEG, seg);\r
+  }\r
+  return count;\r
+}\r
+\r
+/**\r
+ * Sets the priority of a connection.\r
+ *\r
+ */\r
+void\r
+tcp_setprio(struct tcp_pcb *pcb, u8_t prio)\r
+{\r
+  pcb->prio = prio;\r
+}\r
+#if TCP_QUEUE_OOSEQ\r
+\r
+/**\r
+ * Returns a copy of the given TCP segment.\r
+ *\r
+ */ \r
+struct tcp_seg *\r
+tcp_seg_copy(struct tcp_seg *seg)\r
+{\r
+  struct tcp_seg *cseg;\r
+\r
+  cseg = memp_malloc(MEMP_TCP_SEG);\r
+  if (cseg == NULL) {\r
+    return NULL;\r
+  }\r
+  memcpy((u8_t *)cseg, (const u8_t *)seg, sizeof(struct tcp_seg)); \r
+  pbuf_ref(cseg->p);\r
+  return cseg;\r
+}\r
+#endif\r
+\r
+#if LWIP_CALLBACK_API\r
+static err_t\r
+tcp_recv_null(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)\r
+{\r
+  arg = arg;\r
+  if (p != NULL) {\r
+    pbuf_free(p);\r
+  } else if (err == ERR_OK) {\r
+    return tcp_close(pcb);\r
+  }\r
+  return ERR_OK;\r
+}\r
+#endif /* LWIP_CALLBACK_API */\r
+\r
+static void\r
+tcp_kill_prio(u8_t prio)\r
+{\r
+  struct tcp_pcb *pcb, *inactive;\r
+  u32_t inactivity;\r
+  u8_t mprio;\r
+\r
+\r
+  mprio = TCP_PRIO_MAX;\r
+  \r
+  /* We kill the oldest active connection that has lower priority than\r
+     prio. */\r
+  inactivity = 0;\r
+  inactive = NULL;\r
+  for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {\r
+    if (pcb->prio <= prio &&\r
+       pcb->prio <= mprio &&\r
+       (u32_t)(tcp_ticks - pcb->tmr) >= inactivity) {\r
+      inactivity = tcp_ticks - pcb->tmr;\r
+      inactive = pcb;\r
+      mprio = pcb->prio;\r
+    }\r
+  }\r
+  if (inactive != NULL) {\r
+    LWIP_DEBUGF(TCP_DEBUG, ("tcp_kill_prio: killing oldest PCB %p (%"S32_F")\n",\r
+           (void *)inactive, inactivity));\r
+    tcp_abort(inactive);\r
+  }      \r
+}\r
+\r
+\r
+static void\r
+tcp_kill_timewait(void)\r
+{\r
+  struct tcp_pcb *pcb, *inactive;\r
+  u32_t inactivity;\r
+\r
+  inactivity = 0;\r
+  inactive = NULL;\r
+  for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {\r
+    if ((u32_t)(tcp_ticks - pcb->tmr) >= inactivity) {\r
+      inactivity = tcp_ticks - pcb->tmr;\r
+      inactive = pcb;\r
+    }\r
+  }\r
+  if (inactive != NULL) {\r
+    LWIP_DEBUGF(TCP_DEBUG, ("tcp_kill_timewait: killing oldest TIME-WAIT PCB %p (%"S32_F")\n",\r
+           (void *)inactive, inactivity));\r
+    tcp_abort(inactive);\r
+  }      \r
+}\r
+\r
+\r
+\r
+struct tcp_pcb *\r
+tcp_alloc(u8_t prio)\r
+{\r
+  struct tcp_pcb *pcb;\r
+  u32_t iss;\r
+  \r
+  pcb = memp_malloc(MEMP_TCP_PCB);\r
+  if (pcb == NULL) {\r
+    /* Try killing oldest connection in TIME-WAIT. */\r
+    LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: killing off oldest TIME-WAIT connection\n"));\r
+    tcp_kill_timewait();\r
+    pcb = memp_malloc(MEMP_TCP_PCB);\r
+    if (pcb == NULL) {\r
+      tcp_kill_prio(prio);    \r
+      pcb = memp_malloc(MEMP_TCP_PCB);\r
+    }\r
+  }\r
+  if (pcb != NULL) {\r
+    memset(pcb, 0, sizeof(struct tcp_pcb));\r
+    pcb->prio = TCP_PRIO_NORMAL;\r
+    pcb->snd_buf = TCP_SND_BUF;\r
+    pcb->snd_queuelen = 0;\r
+    pcb->rcv_wnd = TCP_WND;\r
+    pcb->tos = 0;\r
+    pcb->ttl = TCP_TTL;\r
+    pcb->mss = TCP_MSS;\r
+    pcb->rto = 3000 / TCP_SLOW_INTERVAL;\r
+    pcb->sa = 0;\r
+    pcb->sv = 3000 / TCP_SLOW_INTERVAL;\r
+    pcb->rtime = 0;\r
+    pcb->cwnd = 1;\r
+    iss = tcp_next_iss();\r
+    pcb->snd_wl2 = iss;\r
+    pcb->snd_nxt = iss;\r
+    pcb->snd_max = iss;\r
+    pcb->lastack = iss;\r
+    pcb->snd_lbb = iss;   \r
+    pcb->tmr = tcp_ticks;\r
+\r
+    pcb->polltmr = 0;\r
+\r
+#if LWIP_CALLBACK_API\r
+    pcb->recv = tcp_recv_null;\r
+#endif /* LWIP_CALLBACK_API */  \r
+    \r
+    /* Init KEEPALIVE timer */\r
+    pcb->keepalive = TCP_KEEPDEFAULT;\r
+    pcb->keep_cnt = 0;\r
+  }\r
+  return pcb;\r
+}\r
+\r
+/**\r
+ * Creates a new TCP protocol control block but doesn't place it on\r
+ * any of the TCP PCB lists.\r
+ *\r
+ * @internal: Maybe there should be a idle TCP PCB list where these\r
+ * PCBs are put on. We can then implement port reservation using\r
+ * tcp_bind(). Currently, we lack this (BSD socket type of) feature.\r
+ */\r
+\r
+struct tcp_pcb *\r
+tcp_new(void)\r
+{\r
+  return tcp_alloc(TCP_PRIO_NORMAL);\r
+}\r
+\r
+/*\r
+ * tcp_arg():\r
+ *\r
+ * Used to specify the argument that should be passed callback\r
+ * functions.\r
+ *\r
+ */ \r
+\r
+void\r
+tcp_arg(struct tcp_pcb *pcb, void *arg)\r
+{  \r
+  pcb->callback_arg = arg;\r
+}\r
+#if LWIP_CALLBACK_API\r
+\r
+/**\r
+ * Used to specify the function that should be called when a TCP\r
+ * connection receives data.\r
+ *\r
+ */ \r
+void\r
+tcp_recv(struct tcp_pcb *pcb,\r
+   err_t (* recv)(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err))\r
+{\r
+  pcb->recv = recv;\r
+}\r
+\r
+/**\r
+ * Used to specify the function that should be called when TCP data\r
+ * has been successfully delivered to the remote host.\r
+ *\r
+ */ \r
+\r
+void\r
+tcp_sent(struct tcp_pcb *pcb,\r
+   err_t (* sent)(void *arg, struct tcp_pcb *tpcb, u16_t len))\r
+{\r
+  pcb->sent = sent;\r
+}\r
+\r
+/**\r
+ * Used to specify the function that should be called when a fatal error\r
+ * has occured on the connection.\r
+ *\r
+ */ \r
+void\r
+tcp_err(struct tcp_pcb *pcb,\r
+   void (* errf)(void *arg, err_t err))\r
+{\r
+  pcb->errf = errf;\r
+}\r
+\r
+/**\r
+ * Used for specifying the function that should be called when a\r
+ * LISTENing connection has been connected to another host.\r
+ *\r
+ */ \r
+void\r
+tcp_accept(struct tcp_pcb *pcb,\r
+     err_t (* accept)(void *arg, struct tcp_pcb *newpcb, err_t err))\r
+{\r
+  ((struct tcp_pcb_listen *)pcb)->accept = accept;\r
+}\r
+#endif /* LWIP_CALLBACK_API */\r
+\r
+\r
+/**\r
+ * Used to specify the function that should be called periodically\r
+ * from TCP. The interval is specified in terms of the TCP coarse\r
+ * timer interval, which is called twice a second.\r
+ *\r
+ */ \r
+void\r
+tcp_poll(struct tcp_pcb *pcb,\r
+   err_t (* poll)(void *arg, struct tcp_pcb *tpcb), u8_t interval)\r
+{\r
+#if LWIP_CALLBACK_API\r
+  pcb->poll = poll;\r
+#endif /* LWIP_CALLBACK_API */  \r
+  pcb->pollinterval = interval;\r
+}\r
+\r
+/**\r
+ * Purges a TCP PCB. Removes any buffered data and frees the buffer memory.\r
+ *\r
+ */\r
+void\r
+tcp_pcb_purge(struct tcp_pcb *pcb)\r
+{\r
+  if (pcb->state != CLOSED &&\r
+     pcb->state != TIME_WAIT &&\r
+     pcb->state != LISTEN) {\r
+\r
+    LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge\n"));\r
+    \r
+    if (pcb->unsent != NULL) {    \r
+      LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: not all data sent\n"));\r
+    }\r
+    if (pcb->unacked != NULL) {    \r
+      LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->unacked\n"));\r
+    }\r
+#if TCP_QUEUE_OOSEQ /* LW */\r
+    if (pcb->ooseq != NULL) {    \r
+      LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->ooseq\n"));\r
+    }\r
+    \r
+    tcp_segs_free(pcb->ooseq);\r
+    pcb->ooseq = NULL;\r
+#endif /* TCP_QUEUE_OOSEQ */\r
+    tcp_segs_free(pcb->unsent);\r
+    tcp_segs_free(pcb->unacked);\r
+    pcb->unacked = pcb->unsent = NULL;\r
+  }\r
+}\r
+\r
+/**\r
+ * Purges the PCB and removes it from a PCB list. Any delayed ACKs are sent first.\r
+ *\r
+ */\r
+void\r
+tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb)\r
+{\r
+  TCP_RMV(pcblist, pcb);\r
+\r
+  tcp_pcb_purge(pcb);\r
+  \r
+  /* if there is an outstanding delayed ACKs, send it */\r
+  if (pcb->state != TIME_WAIT &&\r
+     pcb->state != LISTEN &&\r
+     pcb->flags & TF_ACK_DELAY) {\r
+    pcb->flags |= TF_ACK_NOW;\r
+    tcp_output(pcb);\r
+  }  \r
+  pcb->state = CLOSED;\r
+\r
+  LWIP_ASSERT("tcp_pcb_remove: tcp_pcbs_sane()", tcp_pcbs_sane());\r
+}\r
+\r
+/**\r
+ * Calculates a new initial sequence number for new connections.\r
+ *\r
+ */\r
+u32_t\r
+tcp_next_iss(void)\r
+{\r
+  static u32_t iss = 6510;\r
+  \r
+  iss += tcp_ticks;       /* XXX */\r
+  return iss;\r
+}\r
+\r
+#if TCP_DEBUG || TCP_INPUT_DEBUG || TCP_OUTPUT_DEBUG\r
+void\r
+tcp_debug_print(struct tcp_hdr *tcphdr)\r
+{\r
+  LWIP_DEBUGF(TCP_DEBUG, ("TCP header:\n"));\r
+  LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));\r
+  LWIP_DEBUGF(TCP_DEBUG, ("|    %5"U16_F"      |    %5"U16_F"      | (src port, dest port)\n",\r
+         ntohs(tcphdr->src), ntohs(tcphdr->dest)));\r
+  LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));\r
+  LWIP_DEBUGF(TCP_DEBUG, ("|           %010"U32_F"          | (seq no)\n",\r
+          ntohl(tcphdr->seqno)));\r
+  LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));\r
+  LWIP_DEBUGF(TCP_DEBUG, ("|           %010"U32_F"          | (ack no)\n",\r
+         ntohl(tcphdr->ackno)));\r
+  LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));\r
+  LWIP_DEBUGF(TCP_DEBUG, ("| %2"U16_F" |   |%"U16_F"%"U16_F"%"U16_F"%"U16_F"%"U16_F"%"U16_F"|     %5"U16_F"     | (hdrlen, flags (",\r
+       TCPH_HDRLEN(tcphdr),\r
+         TCPH_FLAGS(tcphdr) >> 5 & 1,\r
+         TCPH_FLAGS(tcphdr) >> 4 & 1,\r
+         TCPH_FLAGS(tcphdr) >> 3 & 1,\r
+         TCPH_FLAGS(tcphdr) >> 2 & 1,\r
+         TCPH_FLAGS(tcphdr) >> 1 & 1,\r
+         TCPH_FLAGS(tcphdr) & 1,\r
+         ntohs(tcphdr->wnd)));\r
+  tcp_debug_print_flags(TCPH_FLAGS(tcphdr));\r
+  LWIP_DEBUGF(TCP_DEBUG, ("), win)\n"));\r
+  LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));\r
+  LWIP_DEBUGF(TCP_DEBUG, ("|    0x%04"X16_F"     |     %5"U16_F"     | (chksum, urgp)\n",\r
+         ntohs(tcphdr->chksum), ntohs(tcphdr->urgp)));\r
+  LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));\r
+}\r
+\r
+void\r
+tcp_debug_print_state(enum tcp_state s)\r
+{\r
+  LWIP_DEBUGF(TCP_DEBUG, ("State: "));\r
+  switch (s) {\r
+  case CLOSED:\r
+    LWIP_DEBUGF(TCP_DEBUG, ("CLOSED\n"));\r
+    break;\r
+ case LISTEN:\r
+   LWIP_DEBUGF(TCP_DEBUG, ("LISTEN\n"));\r
+   break;\r
+  case SYN_SENT:\r
+    LWIP_DEBUGF(TCP_DEBUG, ("SYN_SENT\n"));\r
+    break;\r
+  case SYN_RCVD:\r
+    LWIP_DEBUGF(TCP_DEBUG, ("SYN_RCVD\n"));\r
+    break;\r
+  case ESTABLISHED:\r
+    LWIP_DEBUGF(TCP_DEBUG, ("ESTABLISHED\n"));\r
+    break;\r
+  case FIN_WAIT_1:\r
+    LWIP_DEBUGF(TCP_DEBUG, ("FIN_WAIT_1\n"));\r
+    break;\r
+  case FIN_WAIT_2:\r
+    LWIP_DEBUGF(TCP_DEBUG, ("FIN_WAIT_2\n"));\r
+    break;\r
+  case CLOSE_WAIT:\r
+    LWIP_DEBUGF(TCP_DEBUG, ("CLOSE_WAIT\n"));\r
+    break;\r
+  case CLOSING:\r
+    LWIP_DEBUGF(TCP_DEBUG, ("CLOSING\n"));\r
+    break;\r
+  case LAST_ACK:\r
+    LWIP_DEBUGF(TCP_DEBUG, ("LAST_ACK\n"));\r
+    break;\r
+  case TIME_WAIT:\r
+    LWIP_DEBUGF(TCP_DEBUG, ("TIME_WAIT\n"));\r
+   break;\r
+  }\r
+}\r
+\r
+void\r
+tcp_debug_print_flags(u8_t flags)\r
+{\r
+  if (flags & TCP_FIN) {\r
+    LWIP_DEBUGF(TCP_DEBUG, ("FIN "));\r
+  }\r
+  if (flags & TCP_SYN) {\r
+    LWIP_DEBUGF(TCP_DEBUG, ("SYN "));\r
+  }\r
+  if (flags & TCP_RST) {\r
+    LWIP_DEBUGF(TCP_DEBUG, ("RST "));\r
+  }\r
+  if (flags & TCP_PSH) {\r
+    LWIP_DEBUGF(TCP_DEBUG, ("PSH "));\r
+  }\r
+  if (flags & TCP_ACK) {\r
+    LWIP_DEBUGF(TCP_DEBUG, ("ACK "));\r
+  }\r
+  if (flags & TCP_URG) {\r
+    LWIP_DEBUGF(TCP_DEBUG, ("URG "));\r
+  }\r
+  if (flags & TCP_ECE) {\r
+    LWIP_DEBUGF(TCP_DEBUG, ("ECE "));\r
+  }\r
+  if (flags & TCP_CWR) {\r
+    LWIP_DEBUGF(TCP_DEBUG, ("CWR "));\r
+  }\r
+}\r
+\r
+void\r
+tcp_debug_print_pcbs(void)\r
+{\r
+  struct tcp_pcb *pcb;\r
+  LWIP_DEBUGF(TCP_DEBUG, ("Active PCB states:\n"));\r
+  for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {\r
+    LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ",\r
+                       pcb->local_port, pcb->remote_port,\r
+                       pcb->snd_nxt, pcb->rcv_nxt));\r
+    tcp_debug_print_state(pcb->state);\r
+  }    \r
+  LWIP_DEBUGF(TCP_DEBUG, ("Listen PCB states:\n"));\r
+  for(pcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs; pcb != NULL; pcb = pcb->next) {\r
+    LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ",\r
+                       pcb->local_port, pcb->remote_port,\r
+                       pcb->snd_nxt, pcb->rcv_nxt));\r
+    tcp_debug_print_state(pcb->state);\r
+  }    \r
+  LWIP_DEBUGF(TCP_DEBUG, ("TIME-WAIT PCB states:\n"));\r
+  for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {\r
+    LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ",\r
+                       pcb->local_port, pcb->remote_port,\r
+                       pcb->snd_nxt, pcb->rcv_nxt));\r
+    tcp_debug_print_state(pcb->state);\r
+  }    \r
+}\r
+\r
+s16_t\r
+tcp_pcbs_sane(void)\r
+{\r
+  struct tcp_pcb *pcb;\r
+  for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {\r
+    LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != CLOSED", pcb->state != CLOSED);\r
+    LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != LISTEN", pcb->state != LISTEN);\r
+    LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT);\r
+  }\r
+  for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {\r
+    LWIP_ASSERT("tcp_pcbs_sane: tw pcb->state == TIME-WAIT", pcb->state == TIME_WAIT);\r
+  }\r
+  return 1;\r
+}\r
+#endif /* TCP_DEBUG */\r
+#endif /* LWIP_TCP */\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
index 212f9c4db6b924d824b084a052de3312c637f883..9b8b99a333c73b218c9074e9ed10305522abe457 100644 (file)
-/**
- * @file
- *
- * Transmission Control Protocol, incoming traffic
- *
- * The input processing functions of TCP.
- *
- * 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 <adam@sics.se>
- *
- */
-
-#include "lwip/def.h"
-#include "lwip/opt.h"
-
-#include "lwip/ip_addr.h"
-#include "lwip/netif.h"
-#include "lwip/mem.h"
-#include "lwip/memp.h"
-
-#include "lwip/inet.h"
-#include "lwip/tcp.h"
-
-#include "lwip/stats.h"
-
-#include "arch/perf.h"
-#if LWIP_TCP
-/* 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);
-
-
-/* tcp_input:
- *
- * 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()).
- */
-
-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);
-
-  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);
-    pbuf_free(p);
-    return;
-  }
-
-  /* Don't even process incoming broadcasts/multicasts. */
-  if (ip_addr_isbroadcast(&(iphdr->dest), inp) ||
-      ip_addr_ismulticast(&(iphdr->dest))) {
-    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);
-
-    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);
-  pbuf_header(p, -(hdrlen * 4));
-
-  /* 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) & TCP_FLAGS;
-  tcplen = p->tot_len + ((flags & TCP_FIN || flags & 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;
-
-    tcp_input_pcb = pcb;
-    err = tcp_process(pcb);
-    tcp_input_pcb = NULL;
-    /* 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) {
-    /* Notify application that data has been received. */
-    TCP_EVENT_RECV(pcb, recv_data, ERR_OK, err);
-  }
-
-  /* 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);
-  }
-  /* If there were no errors, we try to send something out. */
-  if (err == ERR_OK) {
-    tcp_output(pcb);
-  }
-      }
-    }
-
-
-    /* We deallocate the incoming pbuf. If it was buffered by the
-       application, the application should have called pbuf_ref() to
-       increase the reference counter in the pbuf. If so, the buffer
-       isn't actually deallocated by the call to pbuf_free(), only the
-       reference count is decreased. */
-    if (inseg.p != NULL) pbuf_free(inseg.p);
-#if TCP_INPUT_DEBUG
-#if TCP_DEBUG
-    tcp_debug_print_state(pcb->state);
-#endif /* TCP_DEBUG */
-#endif /* TCP_INPUT_DEBUG */
-      
-  } 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");
-}
-
-/* tcp_listen_input():
- *
- * Called by tcp_input() when a segment arrives for a listening
- * connection.
- */
-
-static err_t
-tcp_listen_input(struct tcp_pcb_listen *pcb)
-{
-  struct tcp_pcb *npcb;
-  u32_t optdata;
-
-  /* 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));
-    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;
-    }
-    /* 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->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);
-
-    /* Build an MSS option. */
-    optdata = htonl(((u32_t)2 << 24) |
-        ((u32_t)4 << 16) |
-        (((u32_t)npcb->mss / 256) << 8) |
-        (npcb->mss & 255));
-    /* Send a SYN|ACK together with the MSS option. */
-    tcp_enqueue(npcb, NULL, 0, TCP_SYN | TCP_ACK, 0, (u8_t *)&optdata, 4);
-    return tcp_output(npcb);
-  }
-  return ERR_OK;
-}
-
-/* tcp_timewait_input():
- *
- * Called by tcp_input() when a segment arrives for a connection in
- * TIME_WAIT.
- */
-
-static err_t
-tcp_timewait_input(struct tcp_pcb *pcb)
-{
-  if (TCP_SEQ_GT(seqno + tcplen, pcb->rcv_nxt)) {
-    pcb->rcv_nxt = seqno + tcplen;
-  }
-  if (tcplen > 0) {
-    tcp_ack_now(pcb);
-  }
-  return tcp_output(pcb);
-}
-
-/* tcp_process
- *
- * 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.
- */
-
-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_GEQ(seqno, pcb->rcv_nxt) &&
-          TCP_SEQ_LEQ(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {
-      */
-      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;
-    }
-  }
-
-  /* Update the PCB (in)activity timer. */
-  pcb->tmr = tcp_ticks;
-  pcb->keep_cnt = 0;
-
-  /* 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->lastack = ackno;
-      pcb->snd_wnd = tcphdr->wnd;
-      pcb->snd_wl1 = seqno - 1; /* initialise to seqno - 1 to force window update */
-      pcb->state = ESTABLISHED;
-      pcb->cwnd = pcb->mss;
-      --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;
-      tcp_seg_free(rseg);
-
-      /* Parse any options in the SYNACK. */
-      tcp_parseopt(pcb);
-
-      /* Call the user specified function to call when sucessfully
-       * connected. */
-      TCP_EVENT_CONNECTED(pcb, ERR_OK, err);
-      tcp_ack(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 &&
-       !(flags & TCP_RST)) {
-      /* expected ACK number? */
-      if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)) {
-        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;
-        }
-        /* If there was any data contained within this ACK,
-         * we'd better pass it on to the application as well. */
-        tcp_receive(pcb);
-        pcb->cwnd = pcb->mss;
-      }
-      /* incorrect ACK number */
-      else {
-        /* send RST */
-        tcp_rst(ackno, seqno + tcplen, &(iphdr->dest), &(iphdr->src),
-          tcphdr->dest, tcphdr->src);
-      }
-    }
-    break;
-  case CLOSE_WAIT:
-    /* FALLTHROUGH */
-  case ESTABLISHED:
-    tcp_receive(pcb);
-    if (flags & TCP_FIN) {
-      tcp_ack_now(pcb);
-      pcb->state = CLOSE_WAIT;
-    }
-    break;
-  case FIN_WAIT_1:
-    tcp_receive(pcb);
-    if (flags & TCP_FIN) {
-      if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
-        LWIP_DEBUGF(TCP_DEBUG,
-          ("TCP connection closed %"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 (flags & TCP_FIN) {
-      LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed %"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 %"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 LAST_ACK:
-    tcp_receive(pcb);
-    if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
-      LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
-      pcb->state = CLOSED;
-      recv_flags = TF_CLOSED;
-    }
-    break;
-  default:
-    break;
-  }
-  return ERR_OK;
-}
-
-/* tcp_receive:
- *
- * 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.
- */
-
-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;
-
-
-  if (flags & TCP_ACK) {
-    right_wnd_edge = pcb->snd_wnd + pcb->snd_wl1;
-
-    /* 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;
-      LWIP_DEBUGF(TCP_WND_DEBUG, ("tcp_receive: window update %"U32_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" snd_max %"U32_F" ackno %"U32_F" wl1 %"U32_F" seqno %"U32_F" wl2 %"U32_F"\n",
-                               pcb->lastack, pcb->snd_max, ackno, pcb->snd_wl1, seqno, pcb->snd_wl2));
-      }
-#endif /* TCP_WND_DEBUG */
-    }
-
-
-    if (pcb->lastack == ackno) {
-      pcb->acked = 0;
-
-      if (pcb->snd_wl1 + pcb->snd_wnd == right_wnd_edge){
-        ++pcb->dupacks;
-        if (pcb->dupacks >= 3 && pcb->unacked != NULL) {
-          if (!(pcb->flags & TF_INFR)) {
-            /* This is fast retransmit. Retransmit the first unacked segment. */
-            LWIP_DEBUGF(TCP_FR_DEBUG, ("tcp_receive: dupacks %"U16_F" (%"U32_F"), fast retransmit %"U32_F"\n",
-                                       (u16_t)pcb->dupacks, pcb->lastack,
-                                       ntohl(pcb->unacked->tcphdr->seqno)));
-            tcp_rexmit(pcb);
-            /* Set ssthresh to max (FlightSize / 2, 2*SMSS) */
-            /*pcb->ssthresh = LWIP_MAX((pcb->snd_max -
-                                      pcb->lastack) / 2,
-                                      2 * pcb->mss);*/
-            /* Set ssthresh to half of the minimum of the currenct cwnd and the advertised window */
-            if(pcb->cwnd > pcb->snd_wnd)
-              pcb->ssthresh = pcb->snd_wnd / 2;
-            else
-              pcb->ssthresh = pcb->cwnd / 2;
-
-            pcb->cwnd = pcb->ssthresh + 3 * pcb->mss;
-            pcb->flags |= TF_INFR;
-          } else {
-            /* 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 {
-        LWIP_DEBUGF(TCP_FR_DEBUG, ("tcp_receive: dupack averted %"U32_F" %"U32_F"\n",
-                                   pcb->snd_wl1 + pcb->snd_wnd, right_wnd_edge));
-      }
-    } else
-      /*if (TCP_SEQ_LT(pcb->lastack, ackno) &&
-        TCP_SEQ_LEQ(ackno, pcb->snd_max)) { */
-      if(TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_max)){
-      /* 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. */
-      pcb->acked = 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));
-        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);
-        }
-      }
-      pcb->polltmr = 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_LEQ(ntohl(pcb->unsent->tcphdr->seqno) + TCP_TCPLEN(pcb->unsent), ackno) &&
-             TCP_SEQ_LEQ(ackno, pcb->snd_max)*/
-           TCP_SEQ_BETWEEN(ackno, ntohl(pcb->unsent->tcphdr->seqno) + TCP_TCPLEN(pcb->unsent), pcb->snd_max)
-           ) {
-      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));
-      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);
-      }
-
-      if (pcb->unsent != NULL) {
-        pcb->snd_nxt = htonl(pcb->unsent->tcphdr->seqno);
-      }
-    }
-    /* 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)) {
-      m = 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" miliseconds)\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;
-      if (inseg.p->len < off) {
-        new_tot_len = 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;
-        }
-        pbuf_header(p, -off);
-      } else {
-        pbuf_header(inseg.p, -off);
-      }
-      /* KJM following line changed to use p->payload rather than inseg->p->payload
-         to fix bug #9076 */
-      inseg.dataptr = p->payload;
-      inseg.len -= 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_GEQ(seqno, pcb->rcv_nxt) &&
-      TCP_SEQ_LT(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {*/
-    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. */
-#if TCP_QUEUE_OOSEQ
-        if (pcb->ooseq != NULL &&
-            TCP_SEQ_LEQ(pcb->ooseq->tcphdr->seqno, seqno + inseg.len)) {
-          /* We have to trim the second edge of the incoming
-             segment. */
-          inseg.len = pcb->ooseq->tcphdr->seqno - seqno;
-          pbuf_realloc(inseg.p, inseg.len);
-        }
-#endif /* TCP_QUEUE_OOSEQ */
-
-        tcplen = TCP_TCPLEN(&inseg);
-
-        /* First received FIN will be ACKed +1, on any successive (duplicate)
-         * FINs we are already in CLOSE_WAIT and have already done +1.
-         */
-        if (pcb->state != CLOSE_WAIT) {
-          pcb->rcv_nxt += tcplen;
-        }
-
-        /* Update the receiver's (our) window. */
-        if (pcb->rcv_wnd < tcplen) {
-          pcb->rcv_wnd = 0;
-        } else {
-          pcb->rcv_wnd -= tcplen;
-        }
-
-        /* 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);
-          if (pcb->rcv_wnd < TCP_TCPLEN(cseg)) {
-            pcb->rcv_wnd = 0;
-          } else {
-            pcb->rcv_wnd -= TCP_TCPLEN(cseg);
-          }
-          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;
-          }
-
-
-          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_ack_now(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 the old segment with the new
-                   one. */
-                cseg = tcp_seg_copy(&inseg);
-                if (cseg != NULL) {
-                  cseg->next = next->next;
-                  if (prev != NULL) {
-                    prev->next = cseg;
-                  } else {
-                    pcb->ooseq = cseg;
-                  }
-                }
-                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. */
-
-                  if (TCP_SEQ_GT(seqno + inseg.len, next->tcphdr->seqno)) {
-                    /* We need to trim the incoming segment. */
-                    inseg.len = next->tcphdr->seqno - seqno;
-                    pbuf_realloc(inseg.p, inseg.len);
-                  }
-                  cseg = tcp_seg_copy(&inseg);
-                  if (cseg != NULL) {
-                    cseg->next = next;
-                    pcb->ooseq = cseg;
-                  }
-                  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 and insert the
-                   incoming segment and trim the previous segment, if
-                   needed. */
-                if (TCP_SEQ_GT(seqno + inseg.len, next->tcphdr->seqno)) {
-                  /* We need to trim the incoming segment. */
-                  inseg.len = next->tcphdr->seqno - seqno;
-                  pbuf_realloc(inseg.p, inseg.len);
-                }
-
-                cseg = tcp_seg_copy(&inseg);
-                if (cseg != NULL) {
-                  cseg->next = next;
-                  prev->next = cseg;
-                  if (TCP_SEQ_GT(prev->tcphdr->seqno + prev->len, seqno)) {
-                    /* We need to trim the prev segment. */
-                    prev->len = seqno - prev->tcphdr->seqno;
-                    pbuf_realloc(prev->p, prev->len);
-                  }
-                }
-                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)) {
-                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 = seqno - next->tcphdr->seqno;
-                    pbuf_realloc(next->p, next->len);
-                  }
-                }
-                break;
-              }
-            }
-            prev = next;
-          }
-        }
-#endif /* TCP_QUEUE_OOSEQ */
-
-      }
-    } else {
-      /*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);
-      }
-    }
-  } 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);
-    }
-  }
-}
-
-/*
- * tcp_parseopt:
- *
- * Parses the options contained in the incoming segment. (Code taken
- * from uIP with only small changes.)
- *
- */
-
-static void
-tcp_parseopt(struct tcp_pcb *pcb)
-{
-  u8_t c;
-  u8_t *opts, opt;
-  u16_t mss;
-
-  opts = (u8_t *)tcphdr + TCP_HLEN;
-
-  /* Parse the TCP MSS option, if present. */
-  if(TCPH_HDRLEN(tcphdr) > 0x5) {
-    for(c = 0; c < (TCPH_HDRLEN(tcphdr) - 5) << 2 ;) {
-      opt = opts[c];
-      if (opt == 0x00) {
-        /* End of options. */
-  break;
-      } else if (opt == 0x01) {
-        ++c;
-        /* NOP option. */
-      } else if (opt == 0x02 &&
-        opts[c + 1] == 0x04) {
-        /* An MSS option with the right option length. */
-        mss = (opts[c + 2] << 8) | opts[c + 3];
-        pcb->mss = mss > TCP_MSS? TCP_MSS: mss;
-
-        /* And we are done processing options. */
-        break;
-      } else {
-  if (opts[c + 1] == 0) {
-          /* If the length field is zero, the options are malformed
-             and we don't process them further. */
-          break;
-        }
-        /* All other options have a length field, so that we easily
-           can skip past them. */
-        c += opts[c + 1];
-      }
-    }
-  }
-}
-#endif /* LWIP_TCP */
-
-
+/**\r
+ * @file\r
+ *\r
+ * Transmission Control Protocol, incoming traffic\r
+ *\r
+ * The input processing functions of TCP.\r
+ *\r
+ * These functions are generally called in the order (ip_input() ->) tcp_input() ->\r
+ * tcp_process() -> tcp_receive() (-> application).\r
+ * \r
+ */\r
+\r
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without modification,\r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED\r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT\r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY\r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ *\r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+\r
+#include "lwip/def.h"\r
+#include "lwip/opt.h"\r
+\r
+#include "lwip/ip_addr.h"\r
+#include "lwip/netif.h"\r
+#include "lwip/mem.h"\r
+#include "lwip/memp.h"\r
+\r
+#include "lwip/inet.h"\r
+#include "lwip/tcp.h"\r
+\r
+#include "lwip/stats.h"\r
+\r
+#include "arch/perf.h"\r
+#if LWIP_TCP\r
+/* These variables are global to all functions involved in the input\r
+   processing of TCP segments. They are set by the tcp_input()\r
+   function. */\r
+static struct tcp_seg inseg;\r
+static struct tcp_hdr *tcphdr;\r
+static struct ip_hdr *iphdr;\r
+static u32_t seqno, ackno;\r
+static u8_t flags;\r
+static u16_t tcplen;\r
+\r
+static u8_t recv_flags;\r
+static struct pbuf *recv_data;\r
+\r
+struct tcp_pcb *tcp_input_pcb;\r
+\r
+/* Forward declarations. */\r
+static err_t tcp_process(struct tcp_pcb *pcb);\r
+static void tcp_receive(struct tcp_pcb *pcb);\r
+static void tcp_parseopt(struct tcp_pcb *pcb);\r
+\r
+static err_t tcp_listen_input(struct tcp_pcb_listen *pcb);\r
+static err_t tcp_timewait_input(struct tcp_pcb *pcb);\r
+\r
+\r
+/* tcp_input:\r
+ *\r
+ * The initial input processing of TCP. It verifies the TCP header, demultiplexes\r
+ * the segment between the PCBs and passes it on to tcp_process(), which implements\r
+ * the TCP finite state machine. This function is called by the IP layer (in\r
+ * ip_input()).\r
+ */\r
+\r
+void\r
+tcp_input(struct pbuf *p, struct netif *inp)\r
+{\r
+  struct tcp_pcb *pcb, *prev;\r
+  struct tcp_pcb_listen *lpcb;\r
+  u8_t hdrlen;\r
+  err_t err;\r
+\r
+  PERF_START;\r
+\r
+  TCP_STATS_INC(tcp.recv);\r
+\r
+  iphdr = p->payload;\r
+  tcphdr = (struct tcp_hdr *)((u8_t *)p->payload + IPH_HL(iphdr) * 4);\r
+\r
+#if TCP_INPUT_DEBUG\r
+  tcp_debug_print(tcphdr);\r
+#endif\r
+\r
+  /* remove header from payload */\r
+  if (pbuf_header(p, -((s16_t)(IPH_HL(iphdr) * 4))) || (p->tot_len < sizeof(struct tcp_hdr))) {\r
+    /* drop short packets */\r
+    LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: short packet (%"U16_F" bytes) discarded\n", p->tot_len));\r
+    TCP_STATS_INC(tcp.lenerr);\r
+    TCP_STATS_INC(tcp.drop);\r
+    pbuf_free(p);\r
+    return;\r
+  }\r
+\r
+  /* Don't even process incoming broadcasts/multicasts. */\r
+  if (ip_addr_isbroadcast(&(iphdr->dest), inp) ||\r
+      ip_addr_ismulticast(&(iphdr->dest))) {\r
+    pbuf_free(p);\r
+    return;\r
+  }\r
+\r
+#if CHECKSUM_CHECK_TCP\r
+  /* Verify TCP checksum. */\r
+  if (inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src),\r
+      (struct ip_addr *)&(iphdr->dest),\r
+      IP_PROTO_TCP, p->tot_len) != 0) {\r
+      LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packet discarded due to failing checksum 0x%04"X16_F"\n",\r
+        inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src), (struct ip_addr *)&(iphdr->dest),\r
+      IP_PROTO_TCP, p->tot_len)));\r
+#if TCP_DEBUG\r
+    tcp_debug_print(tcphdr);\r
+#endif /* TCP_DEBUG */\r
+    TCP_STATS_INC(tcp.chkerr);\r
+    TCP_STATS_INC(tcp.drop);\r
+\r
+    pbuf_free(p);\r
+    return;\r
+  }\r
+#endif\r
+\r
+  /* Move the payload pointer in the pbuf so that it points to the\r
+     TCP data instead of the TCP header. */\r
+  hdrlen = TCPH_HDRLEN(tcphdr);\r
+  pbuf_header(p, -(hdrlen * 4));\r
+\r
+  /* Convert fields in TCP header to host byte order. */\r
+  tcphdr->src = ntohs(tcphdr->src);\r
+  tcphdr->dest = ntohs(tcphdr->dest);\r
+  seqno = tcphdr->seqno = ntohl(tcphdr->seqno);\r
+  ackno = tcphdr->ackno = ntohl(tcphdr->ackno);\r
+  tcphdr->wnd = ntohs(tcphdr->wnd);\r
+\r
+  flags = TCPH_FLAGS(tcphdr) & TCP_FLAGS;\r
+  tcplen = p->tot_len + ((flags & TCP_FIN || flags & TCP_SYN)? 1: 0);\r
+\r
+  /* Demultiplex an incoming segment. First, we check if it is destined\r
+     for an active connection. */\r
+  prev = NULL;\r
+\r
+  \r
+  for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {\r
+    LWIP_ASSERT("tcp_input: active pcb->state != CLOSED", pcb->state != CLOSED);\r
+    LWIP_ASSERT("tcp_input: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT);\r
+    LWIP_ASSERT("tcp_input: active pcb->state != LISTEN", pcb->state != LISTEN);\r
+    if (pcb->remote_port == tcphdr->src &&\r
+       pcb->local_port == tcphdr->dest &&\r
+       ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src)) &&\r
+       ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest))) {\r
+\r
+      /* Move this PCB to the front of the list so that subsequent\r
+   lookups will be faster (we exploit locality in TCP segment\r
+   arrivals). */\r
+      LWIP_ASSERT("tcp_input: pcb->next != pcb (before cache)", pcb->next != pcb);\r
+      if (prev != NULL) {\r
+  prev->next = pcb->next;\r
+  pcb->next = tcp_active_pcbs;\r
+  tcp_active_pcbs = pcb;\r
+      }\r
+      LWIP_ASSERT("tcp_input: pcb->next != pcb (after cache)", pcb->next != pcb);\r
+      break;\r
+    }\r
+    prev = pcb;\r
+  }\r
+\r
+  if (pcb == NULL) {\r
+    /* If it did not go to an active connection, we check the connections\r
+       in the TIME-WAIT state. */\r
+\r
+    for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {\r
+      LWIP_ASSERT("tcp_input: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT);\r
+      if (pcb->remote_port == tcphdr->src &&\r
+   pcb->local_port == tcphdr->dest &&\r
+   ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src)) &&\r
+         ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest))) {\r
+  /* We don't really care enough to move this PCB to the front\r
+     of the list since we are not very likely to receive that\r
+     many segments for connections in TIME-WAIT. */\r
+  LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for TIME_WAITing connection.\n"));\r
+  tcp_timewait_input(pcb);\r
+  pbuf_free(p);\r
+  return;\r
+      }\r
+    }\r
+\r
+  /* Finally, if we still did not get a match, we check all PCBs that\r
+     are LISTENing for incoming connections. */\r
+    prev = NULL;\r
+    for(lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {\r
+      if ((ip_addr_isany(&(lpcb->local_ip)) ||\r
+    ip_addr_cmp(&(lpcb->local_ip), &(iphdr->dest))) &&\r
+   lpcb->local_port == tcphdr->dest) {\r
+  /* Move this PCB to the front of the list so that subsequent\r
+     lookups will be faster (we exploit locality in TCP segment\r
+     arrivals). */\r
+  if (prev != NULL) {\r
+    ((struct tcp_pcb_listen *)prev)->next = lpcb->next;\r
+          /* our successor is the remainder of the listening list */\r
+    lpcb->next = tcp_listen_pcbs.listen_pcbs;\r
+          /* put this listening pcb at the head of the listening list */\r
+    tcp_listen_pcbs.listen_pcbs = lpcb;\r
+  }\r
+\r
+  LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for LISTENing connection.\n"));\r
+  tcp_listen_input(lpcb);\r
+  pbuf_free(p);\r
+  return;\r
+      }\r
+      prev = (struct tcp_pcb *)lpcb;\r
+    }\r
+  }\r
+\r
+#if TCP_INPUT_DEBUG\r
+  LWIP_DEBUGF(TCP_INPUT_DEBUG, ("+-+-+-+-+-+-+-+-+-+-+-+-+-+- tcp_input: flags "));\r
+  tcp_debug_print_flags(TCPH_FLAGS(tcphdr));\r
+  LWIP_DEBUGF(TCP_INPUT_DEBUG, ("-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n"));\r
+#endif /* TCP_INPUT_DEBUG */\r
+\r
+\r
+  if (pcb != NULL) {\r
+    /* The incoming segment belongs to a connection. */\r
+#if TCP_INPUT_DEBUG\r
+#if TCP_DEBUG\r
+    tcp_debug_print_state(pcb->state);\r
+#endif /* TCP_DEBUG */\r
+#endif /* TCP_INPUT_DEBUG */\r
+\r
+    /* Set up a tcp_seg structure. */\r
+    inseg.next = NULL;\r
+    inseg.len = p->tot_len;\r
+    inseg.dataptr = p->payload;\r
+    inseg.p = p;\r
+    inseg.tcphdr = tcphdr;\r
+\r
+    recv_data = NULL;\r
+    recv_flags = 0;\r
+\r
+    tcp_input_pcb = pcb;\r
+    err = tcp_process(pcb);\r
+    tcp_input_pcb = NULL;\r
+    /* A return value of ERR_ABRT means that tcp_abort() was called\r
+       and that the pcb has been freed. If so, we don't do anything. */\r
+    if (err != ERR_ABRT) {\r
+      if (recv_flags & TF_RESET) {\r
+  /* TF_RESET means that the connection was reset by the other\r
+     end. We then call the error callback to inform the\r
+     application that the connection is dead before we\r
+     deallocate the PCB. */\r
+  TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_RST);\r
+  tcp_pcb_remove(&tcp_active_pcbs, pcb);\r
+  memp_free(MEMP_TCP_PCB, pcb);\r
+      } else if (recv_flags & TF_CLOSED) {\r
+  /* The connection has been closed and we will deallocate the\r
+     PCB. */\r
+  tcp_pcb_remove(&tcp_active_pcbs, pcb);\r
+  memp_free(MEMP_TCP_PCB, pcb);\r
+      } else {\r
+  err = ERR_OK;\r
+  /* If the application has registered a "sent" function to be\r
+     called when new send buffer space is available, we call it\r
+     now. */\r
+  if (pcb->acked > 0) {\r
+    TCP_EVENT_SENT(pcb, pcb->acked, err);\r
+  }\r
+\r
+  if (recv_data != NULL) {\r
+    /* Notify application that data has been received. */\r
+    TCP_EVENT_RECV(pcb, recv_data, ERR_OK, err);\r
+  }\r
+\r
+  /* If a FIN segment was received, we call the callback\r
+     function with a NULL buffer to indicate EOF. */\r
+  if (recv_flags & TF_GOT_FIN) {\r
+    TCP_EVENT_RECV(pcb, NULL, ERR_OK, err);\r
+  }\r
+  /* If there were no errors, we try to send something out. */\r
+  if (err == ERR_OK) {\r
+    tcp_output(pcb);\r
+  }\r
+      }\r
+    }\r
+\r
+\r
+    /* We deallocate the incoming pbuf. If it was buffered by the\r
+       application, the application should have called pbuf_ref() to\r
+       increase the reference counter in the pbuf. If so, the buffer\r
+       isn't actually deallocated by the call to pbuf_free(), only the\r
+       reference count is decreased. */\r
+    if (inseg.p != NULL) pbuf_free(inseg.p);\r
+#if TCP_INPUT_DEBUG\r
+#if TCP_DEBUG\r
+    tcp_debug_print_state(pcb->state);\r
+#endif /* TCP_DEBUG */\r
+#endif /* TCP_INPUT_DEBUG */\r
+      \r
+  } else {\r
+\r
+    /* If no matching PCB was found, send a TCP RST (reset) to the\r
+       sender. */\r
+    LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_input: no PCB match found, resetting.\n"));\r
+    if (!(TCPH_FLAGS(tcphdr) & TCP_RST)) {\r
+      TCP_STATS_INC(tcp.proterr);\r
+      TCP_STATS_INC(tcp.drop);\r
+      tcp_rst(ackno, seqno + tcplen,\r
+        &(iphdr->dest), &(iphdr->src),\r
+        tcphdr->dest, tcphdr->src);\r
+    }\r
+    pbuf_free(p);\r
+  }\r
+\r
+  LWIP_ASSERT("tcp_input: tcp_pcbs_sane()", tcp_pcbs_sane());\r
+  PERF_STOP("tcp_input");\r
+}\r
+\r
+/* tcp_listen_input():\r
+ *\r
+ * Called by tcp_input() when a segment arrives for a listening\r
+ * connection.\r
+ */\r
+\r
+static err_t\r
+tcp_listen_input(struct tcp_pcb_listen *pcb)\r
+{\r
+  struct tcp_pcb *npcb;\r
+  u32_t optdata;\r
+\r
+  /* In the LISTEN state, we check for incoming SYN segments,\r
+     creates a new PCB, and responds with a SYN|ACK. */\r
+  if (flags & TCP_ACK) {\r
+    /* For incoming segments with the ACK flag set, respond with a\r
+       RST. */\r
+    LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_listen_input: ACK in LISTEN, sending reset\n"));\r
+    tcp_rst(ackno + 1, seqno + tcplen,\r
+      &(iphdr->dest), &(iphdr->src),\r
+      tcphdr->dest, tcphdr->src);\r
+  } else if (flags & TCP_SYN) {\r
+    LWIP_DEBUGF(TCP_DEBUG, ("TCP connection request %"U16_F" -> %"U16_F".\n", tcphdr->src, tcphdr->dest));\r
+    npcb = tcp_alloc(pcb->prio);\r
+    /* If a new PCB could not be created (probably due to lack of memory),\r
+       we don't do anything, but rely on the sender will retransmit the\r
+       SYN at a time when we have more memory available. */\r
+    if (npcb == NULL) {\r
+      LWIP_DEBUGF(TCP_DEBUG, ("tcp_listen_input: could not allocate PCB\n"));\r
+      TCP_STATS_INC(tcp.memerr);\r
+      return ERR_MEM;\r
+    }\r
+    /* Set up the new PCB. */\r
+    ip_addr_set(&(npcb->local_ip), &(iphdr->dest));\r
+    npcb->local_port = pcb->local_port;\r
+    ip_addr_set(&(npcb->remote_ip), &(iphdr->src));\r
+    npcb->remote_port = tcphdr->src;\r
+    npcb->state = SYN_RCVD;\r
+    npcb->rcv_nxt = seqno + 1;\r
+    npcb->snd_wnd = tcphdr->wnd;\r
+    npcb->ssthresh = npcb->snd_wnd;\r
+    npcb->snd_wl1 = seqno - 1;/* initialise to seqno-1 to force window update */\r
+    npcb->callback_arg = pcb->callback_arg;\r
+#if LWIP_CALLBACK_API\r
+    npcb->accept = pcb->accept;\r
+#endif /* LWIP_CALLBACK_API */\r
+    /* inherit socket options */\r
+    npcb->so_options = pcb->so_options & (SOF_DEBUG|SOF_DONTROUTE|SOF_KEEPALIVE|SOF_OOBINLINE|SOF_LINGER);\r
+    /* Register the new PCB so that we can begin receiving segments\r
+       for it. */\r
+    TCP_REG(&tcp_active_pcbs, npcb);\r
+\r
+    /* Parse any options in the SYN. */\r
+    tcp_parseopt(npcb);\r
+\r
+    /* Build an MSS option. */\r
+    optdata = htonl(((u32_t)2 << 24) |\r
+        ((u32_t)4 << 16) |\r
+        (((u32_t)npcb->mss / 256) << 8) |\r
+        (npcb->mss & 255));\r
+    /* Send a SYN|ACK together with the MSS option. */\r
+    tcp_enqueue(npcb, NULL, 0, TCP_SYN | TCP_ACK, 0, (u8_t *)&optdata, 4);\r
+    return tcp_output(npcb);\r
+  }\r
+  return ERR_OK;\r
+}\r
+\r
+/* tcp_timewait_input():\r
+ *\r
+ * Called by tcp_input() when a segment arrives for a connection in\r
+ * TIME_WAIT.\r
+ */\r
+\r
+static err_t\r
+tcp_timewait_input(struct tcp_pcb *pcb)\r
+{\r
+  if (TCP_SEQ_GT(seqno + tcplen, pcb->rcv_nxt)) {\r
+    pcb->rcv_nxt = seqno + tcplen;\r
+  }\r
+  if (tcplen > 0) {\r
+    tcp_ack_now(pcb);\r
+  }\r
+  return tcp_output(pcb);\r
+}\r
+\r
+/* tcp_process\r
+ *\r
+ * Implements the TCP state machine. Called by tcp_input. In some\r
+ * states tcp_receive() is called to receive data. The tcp_seg\r
+ * argument will be freed by the caller (tcp_input()) unless the\r
+ * recv_data pointer in the pcb is set.\r
+ */\r
+\r
+static err_t\r
+tcp_process(struct tcp_pcb *pcb)\r
+{\r
+  struct tcp_seg *rseg;\r
+  u8_t acceptable = 0;\r
+  err_t err;\r
+\r
+\r
+  err = ERR_OK;\r
+\r
+  /* Process incoming RST segments. */\r
+  if (flags & TCP_RST) {\r
+    /* First, determine if the reset is acceptable. */\r
+    if (pcb->state == SYN_SENT) {\r
+      if (ackno == pcb->snd_nxt) {\r
+        acceptable = 1;\r
+      }\r
+    } else {\r
+      /*if (TCP_SEQ_GEQ(seqno, pcb->rcv_nxt) &&\r
+          TCP_SEQ_LEQ(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {\r
+      */\r
+      if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt+pcb->rcv_wnd)) {\r
+        acceptable = 1;\r
+      }\r
+    }\r
+\r
+    if (acceptable) {\r
+      LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: Connection RESET\n"));\r
+      LWIP_ASSERT("tcp_input: pcb->state != CLOSED", pcb->state != CLOSED);\r
+      recv_flags = TF_RESET;\r
+      pcb->flags &= ~TF_ACK_DELAY;\r
+      return ERR_RST;\r
+    } else {\r
+      LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: unacceptable reset seqno %"U32_F" rcv_nxt %"U32_F"\n",\r
+       seqno, pcb->rcv_nxt));\r
+      LWIP_DEBUGF(TCP_DEBUG, ("tcp_process: unacceptable reset seqno %"U32_F" rcv_nxt %"U32_F"\n",\r
+       seqno, pcb->rcv_nxt));\r
+      return ERR_OK;\r
+    }\r
+  }\r
+\r
+  /* Update the PCB (in)activity timer. */\r
+  pcb->tmr = tcp_ticks;\r
+  pcb->keep_cnt = 0;\r
+\r
+  /* Do different things depending on the TCP state. */\r
+  switch (pcb->state) {\r
+  case SYN_SENT:\r
+    LWIP_DEBUGF(TCP_INPUT_DEBUG, ("SYN-SENT: ackno %"U32_F" pcb->snd_nxt %"U32_F" unacked %"U32_F"\n", ackno,\r
+     pcb->snd_nxt, ntohl(pcb->unacked->tcphdr->seqno)));\r
+    /* received SYN ACK with expected sequence number? */\r
+    if ((flags & TCP_ACK) && (flags & TCP_SYN)\r
+        && ackno == ntohl(pcb->unacked->tcphdr->seqno) + 1) {\r
+      pcb->snd_buf++;\r
+      pcb->rcv_nxt = seqno + 1;\r
+      pcb->lastack = ackno;\r
+      pcb->snd_wnd = tcphdr->wnd;\r
+      pcb->snd_wl1 = seqno - 1; /* initialise to seqno - 1 to force window update */\r
+      pcb->state = ESTABLISHED;\r
+      pcb->cwnd = pcb->mss;\r
+      --pcb->snd_queuelen;\r
+      LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_process: SYN-SENT --queuelen %"U16_F"\n", (u16_t)pcb->snd_queuelen));\r
+      rseg = pcb->unacked;\r
+      pcb->unacked = rseg->next;\r
+      tcp_seg_free(rseg);\r
+\r
+      /* Parse any options in the SYNACK. */\r
+      tcp_parseopt(pcb);\r
+\r
+      /* Call the user specified function to call when sucessfully\r
+       * connected. */\r
+      TCP_EVENT_CONNECTED(pcb, ERR_OK, err);\r
+      tcp_ack(pcb);\r
+    }\r
+    /* received ACK? possibly a half-open connection */\r
+    else if (flags & TCP_ACK) {\r
+      /* send a RST to bring the other side in a non-synchronized state. */\r
+      tcp_rst(ackno, seqno + tcplen, &(iphdr->dest), &(iphdr->src),\r
+        tcphdr->dest, tcphdr->src);\r
+    }\r
+    break;\r
+  case SYN_RCVD:\r
+    if (flags & TCP_ACK &&\r
+       !(flags & TCP_RST)) {\r
+      /* expected ACK number? */\r
+      if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)) {\r
+        pcb->state = ESTABLISHED;\r
+        LWIP_DEBUGF(TCP_DEBUG, ("TCP connection established %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));\r
+#if LWIP_CALLBACK_API\r
+        LWIP_ASSERT("pcb->accept != NULL", pcb->accept != NULL);\r
+#endif\r
+        /* Call the accept function. */\r
+        TCP_EVENT_ACCEPT(pcb, ERR_OK, err);\r
+        if (err != ERR_OK) {\r
+          /* If the accept function returns with an error, we abort\r
+           * the connection. */\r
+          tcp_abort(pcb);\r
+          return ERR_ABRT;\r
+        }\r
+        /* If there was any data contained within this ACK,\r
+         * we'd better pass it on to the application as well. */\r
+        tcp_receive(pcb);\r
+        pcb->cwnd = pcb->mss;\r
+      }\r
+      /* incorrect ACK number */\r
+      else {\r
+        /* send RST */\r
+        tcp_rst(ackno, seqno + tcplen, &(iphdr->dest), &(iphdr->src),\r
+          tcphdr->dest, tcphdr->src);\r
+      }\r
+    }\r
+    break;\r
+  case CLOSE_WAIT:\r
+    /* FALLTHROUGH */\r
+  case ESTABLISHED:\r
+    tcp_receive(pcb);\r
+    if (flags & TCP_FIN) {\r
+      tcp_ack_now(pcb);\r
+      pcb->state = CLOSE_WAIT;\r
+    }\r
+    break;\r
+  case FIN_WAIT_1:\r
+    tcp_receive(pcb);\r
+    if (flags & TCP_FIN) {\r
+      if (flags & TCP_ACK && ackno == pcb->snd_nxt) {\r
+        LWIP_DEBUGF(TCP_DEBUG,\r
+          ("TCP connection closed %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));\r
+        tcp_ack_now(pcb);\r
+        tcp_pcb_purge(pcb);\r
+        TCP_RMV(&tcp_active_pcbs, pcb);\r
+        pcb->state = TIME_WAIT;\r
+        TCP_REG(&tcp_tw_pcbs, pcb);\r
+      } else {\r
+        tcp_ack_now(pcb);\r
+        pcb->state = CLOSING;\r
+      }\r
+    } else if (flags & TCP_ACK && ackno == pcb->snd_nxt) {\r
+      pcb->state = FIN_WAIT_2;\r
+    }\r
+    break;\r
+  case FIN_WAIT_2:\r
+    tcp_receive(pcb);\r
+    if (flags & TCP_FIN) {\r
+      LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));\r
+      tcp_ack_now(pcb);\r
+      tcp_pcb_purge(pcb);\r
+      TCP_RMV(&tcp_active_pcbs, pcb);\r
+      pcb->state = TIME_WAIT;\r
+      TCP_REG(&tcp_tw_pcbs, pcb);\r
+    }\r
+    break;\r
+  case CLOSING:\r
+    tcp_receive(pcb);\r
+    if (flags & TCP_ACK && ackno == pcb->snd_nxt) {\r
+      LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));\r
+      tcp_ack_now(pcb);\r
+      tcp_pcb_purge(pcb);\r
+      TCP_RMV(&tcp_active_pcbs, pcb);\r
+      pcb->state = TIME_WAIT;\r
+      TCP_REG(&tcp_tw_pcbs, pcb);\r
+    }\r
+    break;\r
+  case LAST_ACK:\r
+    tcp_receive(pcb);\r
+    if (flags & TCP_ACK && ackno == pcb->snd_nxt) {\r
+      LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));\r
+      pcb->state = CLOSED;\r
+      recv_flags = TF_CLOSED;\r
+    }\r
+    break;\r
+  default:\r
+    break;\r
+  }\r
+  return ERR_OK;\r
+}\r
+\r
+/* tcp_receive:\r
+ *\r
+ * Called by tcp_process. Checks if the given segment is an ACK for outstanding\r
+ * data, and if so frees the memory of the buffered data. Next, is places the\r
+ * segment on any of the receive queues (pcb->recved or pcb->ooseq). If the segment\r
+ * is buffered, the pbuf is referenced by pbuf_ref so that it will not be freed until\r
+ * i it has been removed from the buffer.\r
+ *\r
+ * If the incoming segment constitutes an ACK for a segment that was used for RTT\r
+ * estimation, the RTT is estimated here as well.\r
+ */\r
+\r
+static void\r
+tcp_receive(struct tcp_pcb *pcb)\r
+{\r
+  struct tcp_seg *next;\r
+#if TCP_QUEUE_OOSEQ\r
+  struct tcp_seg *prev, *cseg;\r
+#endif\r
+  struct pbuf *p;\r
+  s32_t off;\r
+  s16_t m;\r
+  u32_t right_wnd_edge;\r
+  u16_t new_tot_len;\r
+\r
+\r
+  if (flags & TCP_ACK) {\r
+    right_wnd_edge = pcb->snd_wnd + pcb->snd_wl1;\r
+\r
+    /* Update window. */\r
+    if (TCP_SEQ_LT(pcb->snd_wl1, seqno) ||\r
+       (pcb->snd_wl1 == seqno && TCP_SEQ_LT(pcb->snd_wl2, ackno)) ||\r
+       (pcb->snd_wl2 == ackno && tcphdr->wnd > pcb->snd_wnd)) {\r
+      pcb->snd_wnd = tcphdr->wnd;\r
+      pcb->snd_wl1 = seqno;\r
+      pcb->snd_wl2 = ackno;\r
+      LWIP_DEBUGF(TCP_WND_DEBUG, ("tcp_receive: window update %"U32_F"\n", pcb->snd_wnd));\r
+#if TCP_WND_DEBUG\r
+    } else {\r
+      if (pcb->snd_wnd != tcphdr->wnd) {\r
+        LWIP_DEBUGF(TCP_WND_DEBUG, ("tcp_receive: no window update lastack %"U32_F" snd_max %"U32_F" ackno %"U32_F" wl1 %"U32_F" seqno %"U32_F" wl2 %"U32_F"\n",\r
+                               pcb->lastack, pcb->snd_max, ackno, pcb->snd_wl1, seqno, pcb->snd_wl2));\r
+      }\r
+#endif /* TCP_WND_DEBUG */\r
+    }\r
+\r
+\r
+    if (pcb->lastack == ackno) {\r
+      pcb->acked = 0;\r
+\r
+      if (pcb->snd_wl1 + pcb->snd_wnd == right_wnd_edge){\r
+        ++pcb->dupacks;\r
+        if (pcb->dupacks >= 3 && pcb->unacked != NULL) {\r
+          if (!(pcb->flags & TF_INFR)) {\r
+            /* This is fast retransmit. Retransmit the first unacked segment. */\r
+            LWIP_DEBUGF(TCP_FR_DEBUG, ("tcp_receive: dupacks %"U16_F" (%"U32_F"), fast retransmit %"U32_F"\n",\r
+                                       (u16_t)pcb->dupacks, pcb->lastack,\r
+                                       ntohl(pcb->unacked->tcphdr->seqno)));\r
+            tcp_rexmit(pcb);\r
+            /* Set ssthresh to max (FlightSize / 2, 2*SMSS) */\r
+            /*pcb->ssthresh = LWIP_MAX((pcb->snd_max -\r
+                                      pcb->lastack) / 2,\r
+                                      2 * pcb->mss);*/\r
+            /* Set ssthresh to half of the minimum of the currenct cwnd and the advertised window */\r
+            if(pcb->cwnd > pcb->snd_wnd)\r
+              pcb->ssthresh = pcb->snd_wnd / 2;\r
+            else\r
+              pcb->ssthresh = pcb->cwnd / 2;\r
+\r
+            pcb->cwnd = pcb->ssthresh + 3 * pcb->mss;\r
+            pcb->flags |= TF_INFR;\r
+          } else {\r
+            /* Inflate the congestion window, but not if it means that\r
+               the value overflows. */\r
+            if ((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) {\r
+              pcb->cwnd += pcb->mss;\r
+            }\r
+          }\r
+        }\r
+      } else {\r
+        LWIP_DEBUGF(TCP_FR_DEBUG, ("tcp_receive: dupack averted %"U32_F" %"U32_F"\n",\r
+                                   pcb->snd_wl1 + pcb->snd_wnd, right_wnd_edge));\r
+      }\r
+    } else\r
+      /*if (TCP_SEQ_LT(pcb->lastack, ackno) &&\r
+        TCP_SEQ_LEQ(ackno, pcb->snd_max)) { */\r
+      if(TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_max)){\r
+      /* We come here when the ACK acknowledges new data. */\r
+      \r
+      /* Reset the "IN Fast Retransmit" flag, since we are no longer\r
+         in fast retransmit. Also reset the congestion window to the\r
+         slow start threshold. */\r
+      if (pcb->flags & TF_INFR) {\r
+        pcb->flags &= ~TF_INFR;\r
+        pcb->cwnd = pcb->ssthresh;\r
+      }\r
+\r
+      /* Reset the number of retransmissions. */\r
+      pcb->nrtx = 0;\r
+\r
+      /* Reset the retransmission time-out. */\r
+      pcb->rto = (pcb->sa >> 3) + pcb->sv;\r
+\r
+      /* Update the send buffer space. */\r
+      pcb->acked = ackno - pcb->lastack;\r
+\r
+      pcb->snd_buf += pcb->acked;\r
+\r
+      /* Reset the fast retransmit variables. */\r
+      pcb->dupacks = 0;\r
+      pcb->lastack = ackno;\r
+\r
+      /* Update the congestion control variables (cwnd and\r
+         ssthresh). */\r
+      if (pcb->state >= ESTABLISHED) {\r
+        if (pcb->cwnd < pcb->ssthresh) {\r
+          if ((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) {\r
+            pcb->cwnd += pcb->mss;\r
+          }\r
+          LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: slow start cwnd %"U16_F"\n", pcb->cwnd));\r
+        } else {\r
+          u16_t new_cwnd = (pcb->cwnd + pcb->mss * pcb->mss / pcb->cwnd);\r
+          if (new_cwnd > pcb->cwnd) {\r
+            pcb->cwnd = new_cwnd;\r
+          }\r
+          LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: congestion avoidance cwnd %"U16_F"\n", pcb->cwnd));\r
+        }\r
+      }\r
+      LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: ACK for %"U32_F", unacked->seqno %"U32_F":%"U32_F"\n",\r
+                                    ackno,\r
+                                    pcb->unacked != NULL?\r
+                                    ntohl(pcb->unacked->tcphdr->seqno): 0,\r
+                                    pcb->unacked != NULL?\r
+                                    ntohl(pcb->unacked->tcphdr->seqno) + TCP_TCPLEN(pcb->unacked): 0));\r
+\r
+      /* Remove segment from the unacknowledged list if the incoming\r
+         ACK acknowlegdes them. */\r
+      while (pcb->unacked != NULL &&\r
+             TCP_SEQ_LEQ(ntohl(pcb->unacked->tcphdr->seqno) +\r
+                         TCP_TCPLEN(pcb->unacked), ackno)) {\r
+        LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %"U32_F":%"U32_F" from pcb->unacked\n",\r
+                                      ntohl(pcb->unacked->tcphdr->seqno),\r
+                                      ntohl(pcb->unacked->tcphdr->seqno) +\r
+                                      TCP_TCPLEN(pcb->unacked)));\r
+\r
+        next = pcb->unacked;\r
+        pcb->unacked = pcb->unacked->next;\r
+\r
+        LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"U16_F" ... ", (u16_t)pcb->snd_queuelen));\r
+        pcb->snd_queuelen -= pbuf_clen(next->p);\r
+        tcp_seg_free(next);\r
+\r
+        LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"U16_F" (after freeing unacked)\n", (u16_t)pcb->snd_queuelen));\r
+        if (pcb->snd_queuelen != 0) {\r
+          LWIP_ASSERT("tcp_receive: valid queue length", pcb->unacked != NULL ||\r
+                      pcb->unsent != NULL);\r
+        }\r
+      }\r
+      pcb->polltmr = 0;\r
+    }\r
+\r
+    /* We go through the ->unsent list to see if any of the segments\r
+       on the list are acknowledged by the ACK. This may seem\r
+       strange since an "unsent" segment shouldn't be acked. The\r
+       rationale is that lwIP puts all outstanding segments on the\r
+       ->unsent list after a retransmission, so these segments may\r
+       in fact have been sent once. */\r
+    while (pcb->unsent != NULL &&\r
+           /*TCP_SEQ_LEQ(ntohl(pcb->unsent->tcphdr->seqno) + TCP_TCPLEN(pcb->unsent), ackno) &&\r
+             TCP_SEQ_LEQ(ackno, pcb->snd_max)*/\r
+           TCP_SEQ_BETWEEN(ackno, ntohl(pcb->unsent->tcphdr->seqno) + TCP_TCPLEN(pcb->unsent), pcb->snd_max)\r
+           ) {\r
+      LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %"U32_F":%"U32_F" from pcb->unsent\n",\r
+                                    ntohl(pcb->unsent->tcphdr->seqno), ntohl(pcb->unsent->tcphdr->seqno) +\r
+                                    TCP_TCPLEN(pcb->unsent)));\r
+\r
+      next = pcb->unsent;\r
+      pcb->unsent = pcb->unsent->next;\r
+      LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"U16_F" ... ", (u16_t)pcb->snd_queuelen));\r
+      pcb->snd_queuelen -= pbuf_clen(next->p);\r
+      tcp_seg_free(next);\r
+      LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"U16_F" (after freeing unsent)\n", (u16_t)pcb->snd_queuelen));\r
+      if (pcb->snd_queuelen != 0) {\r
+        LWIP_ASSERT("tcp_receive: valid queue length",\r
+          pcb->unacked != NULL || pcb->unsent != NULL);\r
+      }\r
+\r
+      if (pcb->unsent != NULL) {\r
+        pcb->snd_nxt = htonl(pcb->unsent->tcphdr->seqno);\r
+      }\r
+    }\r
+    /* End of ACK for new data processing. */\r
+\r
+    LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: pcb->rttest %"U32_F" rtseq %"U32_F" ackno %"U32_F"\n",\r
+                                pcb->rttest, pcb->rtseq, ackno));\r
+\r
+    /* RTT estimation calculations. This is done by checking if the\r
+       incoming segment acknowledges the segment we use to take a\r
+       round-trip time measurement. */\r
+    if (pcb->rttest && TCP_SEQ_LT(pcb->rtseq, ackno)) {\r
+      m = tcp_ticks - pcb->rttest;\r
+\r
+      LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: experienced rtt %"U16_F" ticks (%"U16_F" msec).\n",\r
+                                  m, m * TCP_SLOW_INTERVAL));\r
+\r
+      /* This is taken directly from VJs original code in his paper */\r
+      m = m - (pcb->sa >> 3);\r
+      pcb->sa += m;\r
+      if (m < 0) {\r
+        m = -m;\r
+      }\r
+      m = m - (pcb->sv >> 2);\r
+      pcb->sv += m;\r
+      pcb->rto = (pcb->sa >> 3) + pcb->sv;\r
+\r
+      LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: RTO %"U16_F" (%"U16_F" miliseconds)\n",\r
+                                  pcb->rto, pcb->rto * TCP_SLOW_INTERVAL));\r
+\r
+      pcb->rttest = 0;\r
+    }\r
+  }\r
+\r
+  /* If the incoming segment contains data, we must process it\r
+     further. */\r
+  if (tcplen > 0) {\r
+    /* This code basically does three things:\r
+\r
+    +) If the incoming segment contains data that is the next\r
+    in-sequence data, this data is passed to the application. This\r
+    might involve trimming the first edge of the data. The rcv_nxt\r
+    variable and the advertised window are adjusted.\r
+\r
+    +) If the incoming segment has data that is above the next\r
+    sequence number expected (->rcv_nxt), the segment is placed on\r
+    the ->ooseq queue. This is done by finding the appropriate\r
+    place in the ->ooseq queue (which is ordered by sequence\r
+    number) and trim the segment in both ends if needed. An\r
+    immediate ACK is sent to indicate that we received an\r
+    out-of-sequence segment.\r
+\r
+    +) Finally, we check if the first segment on the ->ooseq queue\r
+    now is in sequence (i.e., if rcv_nxt >= ooseq->seqno). If\r
+    rcv_nxt > ooseq->seqno, we must trim the first edge of the\r
+    segment on ->ooseq before we adjust rcv_nxt. The data in the\r
+    segments that are now on sequence are chained onto the\r
+    incoming segment so that we only need to call the application\r
+    once.\r
+    */\r
+\r
+    /* First, we check if we must trim the first edge. We have to do\r
+       this if the sequence number of the incoming segment is less\r
+       than rcv_nxt, and the sequence number plus the length of the\r
+       segment is larger than rcv_nxt. */\r
+    /*    if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)){\r
+          if (TCP_SEQ_LT(pcb->rcv_nxt, seqno + tcplen)) {*/\r
+    if(TCP_SEQ_BETWEEN(pcb->rcv_nxt, seqno+1, seqno+tcplen-1)){\r
+      /* Trimming the first edge is done by pushing the payload\r
+         pointer in the pbuf downwards. This is somewhat tricky since\r
+         we do not want to discard the full contents of the pbuf up to\r
+         the new starting point of the data since we have to keep the\r
+         TCP header which is present in the first pbuf in the chain.\r
+         \r
+         What is done is really quite a nasty hack: the first pbuf in\r
+         the pbuf chain is pointed to by inseg.p. Since we need to be\r
+         able to deallocate the whole pbuf, we cannot change this\r
+         inseg.p pointer to point to any of the later pbufs in the\r
+         chain. Instead, we point the ->payload pointer in the first\r
+         pbuf to data in one of the later pbufs. We also set the\r
+         inseg.data pointer to point to the right place. This way, the\r
+         ->p pointer will still point to the first pbuf, but the\r
+         ->p->payload pointer will point to data in another pbuf.\r
+         \r
+         After we are done with adjusting the pbuf pointers we must\r
+         adjust the ->data pointer in the seg and the segment\r
+         length.*/\r
+      \r
+      off = pcb->rcv_nxt - seqno;\r
+      p = inseg.p;\r
+      if (inseg.p->len < off) {\r
+        new_tot_len = inseg.p->tot_len - off;\r
+        while (p->len < off) {\r
+          off -= p->len;\r
+          /* KJM following line changed (with addition of new_tot_len var)\r
+             to fix bug #9076\r
+             inseg.p->tot_len -= p->len; */\r
+          p->tot_len = new_tot_len;\r
+          p->len = 0;\r
+          p = p->next;\r
+        }\r
+        pbuf_header(p, -off);\r
+      } else {\r
+        pbuf_header(inseg.p, -off);\r
+      }\r
+      /* KJM following line changed to use p->payload rather than inseg->p->payload\r
+         to fix bug #9076 */\r
+      inseg.dataptr = p->payload;\r
+      inseg.len -= pcb->rcv_nxt - seqno;\r
+      inseg.tcphdr->seqno = seqno = pcb->rcv_nxt;\r
+    }\r
+    else{\r
+      if(TCP_SEQ_LT(seqno, pcb->rcv_nxt)){\r
+        /* the whole segment is < rcv_nxt */\r
+        /* must be a duplicate of a packet that has already been correctly handled */\r
+        \r
+        LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: duplicate seqno %"U32_F"\n", seqno));\r
+        tcp_ack_now(pcb);\r
+      }\r
+    }\r
+\r
+    /* The sequence number must be within the window (above rcv_nxt\r
+       and below rcv_nxt + rcv_wnd) in order to be further\r
+       processed. */\r
+    /*if (TCP_SEQ_GEQ(seqno, pcb->rcv_nxt) &&\r
+      TCP_SEQ_LT(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {*/\r
+    if(TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt + pcb->rcv_wnd - 1)){\r
+      if (pcb->rcv_nxt == seqno) {\r
+        /* The incoming segment is the next in sequence. We check if\r
+           we have to trim the end of the segment and update rcv_nxt\r
+           and pass the data to the application. */\r
+#if TCP_QUEUE_OOSEQ\r
+        if (pcb->ooseq != NULL &&\r
+            TCP_SEQ_LEQ(pcb->ooseq->tcphdr->seqno, seqno + inseg.len)) {\r
+          /* We have to trim the second edge of the incoming\r
+             segment. */\r
+          inseg.len = pcb->ooseq->tcphdr->seqno - seqno;\r
+          pbuf_realloc(inseg.p, inseg.len);\r
+        }\r
+#endif /* TCP_QUEUE_OOSEQ */\r
+\r
+        tcplen = TCP_TCPLEN(&inseg);\r
+\r
+        /* First received FIN will be ACKed +1, on any successive (duplicate)\r
+         * FINs we are already in CLOSE_WAIT and have already done +1.\r
+         */\r
+        if (pcb->state != CLOSE_WAIT) {\r
+          pcb->rcv_nxt += tcplen;\r
+        }\r
+\r
+        /* Update the receiver's (our) window. */\r
+        if (pcb->rcv_wnd < tcplen) {\r
+          pcb->rcv_wnd = 0;\r
+        } else {\r
+          pcb->rcv_wnd -= tcplen;\r
+        }\r
+\r
+        /* If there is data in the segment, we make preparations to\r
+           pass this up to the application. The ->recv_data variable\r
+           is used for holding the pbuf that goes to the\r
+           application. The code for reassembling out-of-sequence data\r
+           chains its data on this pbuf as well.\r
+\r
+           If the segment was a FIN, we set the TF_GOT_FIN flag that will\r
+           be used to indicate to the application that the remote side has\r
+           closed its end of the connection. */\r
+        if (inseg.p->tot_len > 0) {\r
+          recv_data = inseg.p;\r
+          /* Since this pbuf now is the responsibility of the\r
+             application, we delete our reference to it so that we won't\r
+             (mistakingly) deallocate it. */\r
+          inseg.p = NULL;\r
+        }\r
+        if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) {\r
+          LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: received FIN.\n"));\r
+          recv_flags = TF_GOT_FIN;\r
+        }\r
+\r
+#if TCP_QUEUE_OOSEQ\r
+        /* We now check if we have segments on the ->ooseq queue that\r
+           is now in sequence. */\r
+        while (pcb->ooseq != NULL &&\r
+               pcb->ooseq->tcphdr->seqno == pcb->rcv_nxt) {\r
+\r
+          cseg = pcb->ooseq;\r
+          seqno = pcb->ooseq->tcphdr->seqno;\r
+\r
+          pcb->rcv_nxt += TCP_TCPLEN(cseg);\r
+          if (pcb->rcv_wnd < TCP_TCPLEN(cseg)) {\r
+            pcb->rcv_wnd = 0;\r
+          } else {\r
+            pcb->rcv_wnd -= TCP_TCPLEN(cseg);\r
+          }\r
+          if (cseg->p->tot_len > 0) {\r
+            /* Chain this pbuf onto the pbuf that we will pass to\r
+               the application. */\r
+            if (recv_data) {\r
+              pbuf_cat(recv_data, cseg->p);\r
+            } else {\r
+              recv_data = cseg->p;\r
+            }\r
+            cseg->p = NULL;\r
+          }\r
+          if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) {\r
+            LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: dequeued FIN.\n"));\r
+            recv_flags = TF_GOT_FIN;\r
+          }\r
+\r
+\r
+          pcb->ooseq = cseg->next;\r
+          tcp_seg_free(cseg);\r
+        }\r
+#endif /* TCP_QUEUE_OOSEQ */\r
+\r
+\r
+        /* Acknowledge the segment(s). */\r
+        tcp_ack(pcb);\r
+\r
+      } else {\r
+        /* We get here if the incoming segment is out-of-sequence. */\r
+        tcp_ack_now(pcb);\r
+#if TCP_QUEUE_OOSEQ\r
+        /* We queue the segment on the ->ooseq queue. */\r
+        if (pcb->ooseq == NULL) {\r
+          pcb->ooseq = tcp_seg_copy(&inseg);\r
+        } else {\r
+          /* If the queue is not empty, we walk through the queue and\r
+             try to find a place where the sequence number of the\r
+             incoming segment is between the sequence numbers of the\r
+             previous and the next segment on the ->ooseq queue. That is\r
+             the place where we put the incoming segment. If needed, we\r
+             trim the second edges of the previous and the incoming\r
+             segment so that it will fit into the sequence.\r
+\r
+             If the incoming segment has the same sequence number as a\r
+             segment on the ->ooseq queue, we discard the segment that\r
+             contains less data. */\r
+\r
+          prev = NULL;\r
+          for(next = pcb->ooseq; next != NULL; next = next->next) {\r
+            if (seqno == next->tcphdr->seqno) {\r
+              /* The sequence number of the incoming segment is the\r
+                 same as the sequence number of the segment on\r
+                 ->ooseq. We check the lengths to see which one to\r
+                 discard. */\r
+              if (inseg.len > next->len) {\r
+                /* The incoming segment is larger than the old\r
+                   segment. We replace the old segment with the new\r
+                   one. */\r
+                cseg = tcp_seg_copy(&inseg);\r
+                if (cseg != NULL) {\r
+                  cseg->next = next->next;\r
+                  if (prev != NULL) {\r
+                    prev->next = cseg;\r
+                  } else {\r
+                    pcb->ooseq = cseg;\r
+                  }\r
+                }\r
+                break;\r
+              } else {\r
+                /* Either the lenghts are the same or the incoming\r
+                   segment was smaller than the old one; in either\r
+                   case, we ditch the incoming segment. */\r
+                break;\r
+              }\r
+            } else {\r
+              if (prev == NULL) {\r
+                if (TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {\r
+                  /* The sequence number of the incoming segment is lower\r
+                     than the sequence number of the first segment on the\r
+                     queue. We put the incoming segment first on the\r
+                     queue. */\r
+\r
+                  if (TCP_SEQ_GT(seqno + inseg.len, next->tcphdr->seqno)) {\r
+                    /* We need to trim the incoming segment. */\r
+                    inseg.len = next->tcphdr->seqno - seqno;\r
+                    pbuf_realloc(inseg.p, inseg.len);\r
+                  }\r
+                  cseg = tcp_seg_copy(&inseg);\r
+                  if (cseg != NULL) {\r
+                    cseg->next = next;\r
+                    pcb->ooseq = cseg;\r
+                  }\r
+                  break;\r
+                }\r
+              } else \r
+                /*if (TCP_SEQ_LT(prev->tcphdr->seqno, seqno) &&\r
+                  TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {*/\r
+                if(TCP_SEQ_BETWEEN(seqno, prev->tcphdr->seqno+1, next->tcphdr->seqno-1)){\r
+                /* The sequence number of the incoming segment is in\r
+                   between the sequence numbers of the previous and\r
+                   the next segment on ->ooseq. We trim and insert the\r
+                   incoming segment and trim the previous segment, if\r
+                   needed. */\r
+                if (TCP_SEQ_GT(seqno + inseg.len, next->tcphdr->seqno)) {\r
+                  /* We need to trim the incoming segment. */\r
+                  inseg.len = next->tcphdr->seqno - seqno;\r
+                  pbuf_realloc(inseg.p, inseg.len);\r
+                }\r
+\r
+                cseg = tcp_seg_copy(&inseg);\r
+                if (cseg != NULL) {\r
+                  cseg->next = next;\r
+                  prev->next = cseg;\r
+                  if (TCP_SEQ_GT(prev->tcphdr->seqno + prev->len, seqno)) {\r
+                    /* We need to trim the prev segment. */\r
+                    prev->len = seqno - prev->tcphdr->seqno;\r
+                    pbuf_realloc(prev->p, prev->len);\r
+                  }\r
+                }\r
+                break;\r
+              }\r
+              /* If the "next" segment is the last segment on the\r
+                 ooseq queue, we add the incoming segment to the end\r
+                 of the list. */\r
+              if (next->next == NULL &&\r
+                  TCP_SEQ_GT(seqno, next->tcphdr->seqno)) {\r
+                next->next = tcp_seg_copy(&inseg);\r
+                if (next->next != NULL) {\r
+                  if (TCP_SEQ_GT(next->tcphdr->seqno + next->len, seqno)) {\r
+                    /* We need to trim the last segment. */\r
+                    next->len = seqno - next->tcphdr->seqno;\r
+                    pbuf_realloc(next->p, next->len);\r
+                  }\r
+                }\r
+                break;\r
+              }\r
+            }\r
+            prev = next;\r
+          }\r
+        }\r
+#endif /* TCP_QUEUE_OOSEQ */\r
+\r
+      }\r
+    } else {\r
+      /*if (TCP_SEQ_GT(pcb->rcv_nxt, seqno) ||\r
+        TCP_SEQ_GEQ(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {*/\r
+      if(!TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt + pcb->rcv_wnd-1)){\r
+        tcp_ack_now(pcb);\r
+      }\r
+    }\r
+  } else {\r
+    /* Segments with length 0 is taken care of here. Segments that\r
+       fall out of the window are ACKed. */\r
+    /*if (TCP_SEQ_GT(pcb->rcv_nxt, seqno) ||\r
+      TCP_SEQ_GEQ(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {*/\r
+    if(!TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt + pcb->rcv_wnd-1)){\r
+      tcp_ack_now(pcb);\r
+    }\r
+  }\r
+}\r
+\r
+/*\r
+ * tcp_parseopt:\r
+ *\r
+ * Parses the options contained in the incoming segment. (Code taken\r
+ * from uIP with only small changes.)\r
+ *\r
+ */\r
+\r
+static void\r
+tcp_parseopt(struct tcp_pcb *pcb)\r
+{\r
+  u8_t c;\r
+  u8_t *opts, opt;\r
+  u16_t mss;\r
+\r
+  opts = (u8_t *)tcphdr + TCP_HLEN;\r
+\r
+  /* Parse the TCP MSS option, if present. */\r
+  if(TCPH_HDRLEN(tcphdr) > 0x5) {\r
+    for(c = 0; c < (TCPH_HDRLEN(tcphdr) - 5) << 2 ;) {\r
+      opt = opts[c];\r
+      if (opt == 0x00) {\r
+        /* End of options. */\r
+  break;\r
+      } else if (opt == 0x01) {\r
+        ++c;\r
+        /* NOP option. */\r
+      } else if (opt == 0x02 &&\r
+        opts[c + 1] == 0x04) {\r
+        /* An MSS option with the right option length. */\r
+        mss = (opts[c + 2] << 8) | opts[c + 3];\r
+        pcb->mss = mss > TCP_MSS? TCP_MSS: mss;\r
+\r
+        /* And we are done processing options. */\r
+        break;\r
+      } else {\r
+  if (opts[c + 1] == 0) {\r
+          /* If the length field is zero, the options are malformed\r
+             and we don't process them further. */\r
+          break;\r
+        }\r
+        /* All other options have a length field, so that we easily\r
+           can skip past them. */\r
+        c += opts[c + 1];\r
+      }\r
+    }\r
+  }\r
+}\r
+#endif /* LWIP_TCP */\r
+\r
+\r
index 62982bd14a91e2b38f0b7583988815a41b04491b..3e5306e219ba3bc28a1b2e00f73c07031c3524cd 100644 (file)
-/**
- * @file
- *
- * Transmission Control Protocol, outgoing traffic
- *
- * The output functions of TCP.
- *
- */
-
-/*
- * 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 <adam@sics.se>
- *
- */
-
-#include <string.h>
-
-#include "lwip/def.h"
-#include "lwip/opt.h"
-#include "lwip/mem.h"
-#include "lwip/memp.h"
-#include "lwip/sys.h"
-#include "lwip/ip_addr.h"
-#include "lwip/netif.h"
-#include "lwip/inet.h"
-#include "lwip/tcp.h"
-#include "lwip/stats.h"
-
-#if LWIP_TCP
-
-/* Forward declarations.*/
-static void tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb);
-
-err_t
-tcp_send_ctrl(struct tcp_pcb *pcb, u8_t flags)
-{
-  /* no data, no length, flags, copy=1, no optdata, no optdatalen */
-  return tcp_enqueue(pcb, NULL, 0, flags, 1, NULL, 0);
-}
-
-/**
- * Write data for sending (but does not send it immediately).
- *
- * It waits in the expectation of more data being sent soon (as
- * it can send them more efficiently by combining them together).
- * To prompt the system to send data now, call tcp_output() after
- * calling tcp_write().
- * 
- * @arg pcb Protocol control block of the TCP connection to enqueue data for. 
- * 
- * @see tcp_write()
- */
-
-err_t
-tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t copy)
-{
-  LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_write(pcb=%p, arg=%p, len=%"U16_F", copy=%"U16_F")\n", (void *)pcb,
-    arg, len, (u16_t)copy));
-  /* connection is in valid state for data transmission? */
-  if (pcb->state == ESTABLISHED ||
-     pcb->state == CLOSE_WAIT ||
-     pcb->state == SYN_SENT ||
-     pcb->state == SYN_RCVD) {
-    if (len > 0) {
-      return tcp_enqueue(pcb, (void *)arg, len, 0, copy, NULL, 0);
-    }
-    return ERR_OK;
-  } else {
-    LWIP_DEBUGF(TCP_OUTPUT_DEBUG | DBG_STATE | 3, ("tcp_write() called in invalid state\n"));
-    return ERR_CONN;
-  }
-}
-
-/**
- * Enqueue either data or TCP options (but not both) for tranmission
- * 
- * 
- * 
- * @arg pcb Protocol control block for the TCP connection to enqueue data for.
- * @arg arg Pointer to the data to be enqueued for sending.
- * @arg len Data length in bytes
- * @arg flags
- * @arg copy 1 if data must be copied, 0 if data is non-volatile and can be
- * referenced.
- * @arg optdata
- * @arg optlen
- */
-err_t
-tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len,
-  u8_t flags, u8_t copy,
-  u8_t *optdata, u8_t optlen)
-{
-  struct pbuf *p;
-  struct tcp_seg *seg, *useg, *queue;
-  u32_t left, seqno;
-  u16_t seglen;
-  void *ptr;
-  u8_t queuelen;
-
-  LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_enqueue(pcb=%p, arg=%p, len=%"U16_F", flags=%"X16_F", copy=%"U16_F")\n",
-    (void *)pcb, arg, len, (u16_t)flags, (u16_t)copy));
-  LWIP_ASSERT("tcp_enqueue: len == 0 || optlen == 0 (programmer violates API)",
-      len == 0 || optlen == 0);
-  LWIP_ASSERT("tcp_enqueue: arg == NULL || optdata == NULL (programmer violates API)",
-      arg == NULL || optdata == NULL);
-  /* fail on too much data */
-  if (len > pcb->snd_buf) {
-    LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_enqueue: too much data (len=%"U16_F" > snd_buf=%"U16_F")\n", len, pcb->snd_buf));
-    return ERR_MEM;
-  }
-  left = len;
-  ptr = arg;
-
-  /* seqno will be the sequence number of the first segment enqueued
-   * by the call to this function. */
-  seqno = pcb->snd_lbb;
-
-  LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue: queuelen: %"U16_F"\n", (u16_t)pcb->snd_queuelen));
-
-  /* If total number of pbufs on the unsent/unacked queues exceeds the
-   * configured maximum, return an error */
-  queuelen = pcb->snd_queuelen;
-  if (queuelen >= TCP_SND_QUEUELEN) {
-    LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_enqueue: too long queue %"U16_F" (max %"U16_F")\n", queuelen, TCP_SND_QUEUELEN));
-    TCP_STATS_INC(tcp.memerr);
-    return ERR_MEM;
-  }
-  if (queuelen != 0) {
-    LWIP_ASSERT("tcp_enqueue: pbufs on queue => at least one queue non-empty",
-      pcb->unacked != NULL || pcb->unsent != NULL);
-  } else {
-    LWIP_ASSERT("tcp_enqueue: no pbufs on queue => both queues empty",
-      pcb->unacked == NULL && pcb->unsent == NULL);
-  }
-
-  /* First, break up the data into segments and tuck them together in
-   * the local "queue" variable. */
-  useg = queue = seg = NULL;
-  seglen = 0;
-  while (queue == NULL || left > 0) {
-
-    /* The segment length should be the MSS if the data to be enqueued
-     * is larger than the MSS. */
-    seglen = left > pcb->mss? pcb->mss: left;
-
-    /* Allocate memory for tcp_seg, and fill in fields. */
-    seg = memp_malloc(MEMP_TCP_SEG);
-    if (seg == NULL) {
-      LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue: could not allocate memory for tcp_seg\n"));
-      goto memerr;
-    }
-    seg->next = NULL;
-    seg->p = NULL;
-
-    /* first segment of to-be-queued data? */
-    if (queue == NULL) {
-      queue = seg;
-    }
-    /* subsequent segments of to-be-queued data */
-    else {
-      /* Attach the segment to the end of the queued segments */
-      LWIP_ASSERT("useg != NULL", useg != NULL);
-      useg->next = seg;
-    }
-    /* remember last segment of to-be-queued data for next iteration */
-    useg = seg;
-
-    /* If copy is set, memory should be allocated
-     * and data copied into pbuf, otherwise data comes from
-     * ROM or other static memory, and need not be copied. If
-     * optdata is != NULL, we have options instead of data. */
-     
-    /* options? */
-    if (optdata != NULL) {
-      if ((seg->p = pbuf_alloc(PBUF_TRANSPORT, optlen, PBUF_RAM)) == NULL) {
-        goto memerr;
-      }
-      ++queuelen;
-      seg->dataptr = seg->p->payload;
-    }
-    /* copy from volatile memory? */
-    else if (copy) {
-      if ((seg->p = pbuf_alloc(PBUF_TRANSPORT, seglen, PBUF_RAM)) == NULL) {
-        LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue : could not allocate memory for pbuf copy size %"U16_F"\n", seglen));
-        goto memerr;
-      }
-      ++queuelen;
-      if (arg != NULL) {
-        memcpy(seg->p->payload, ptr, seglen);
-      }
-      seg->dataptr = seg->p->payload;
-    }
-    /* do not copy data */
-    else {
-      /* First, allocate a pbuf for holding the data.
-       * since the referenced data is available at least until it is sent out on the
-       * link (as it has to be ACKed by the remote party) we can safely use PBUF_ROM
-       * instead of PBUF_REF here.
-       */
-      if ((p = pbuf_alloc(PBUF_TRANSPORT, seglen, PBUF_ROM)) == NULL) {
-        LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue: could not allocate memory for zero-copy pbuf\n"));
-        goto memerr;
-      }
-      ++queuelen;
-      /* reference the non-volatile payload data */
-      p->payload = ptr;
-      seg->dataptr = ptr;
-
-      /* Second, allocate a pbuf for the headers. */
-      if ((seg->p = pbuf_alloc(PBUF_TRANSPORT, 0, PBUF_RAM)) == NULL) {
-        /* If allocation fails, we have to deallocate the data pbuf as
-         * well. */
-        pbuf_free(p);
-        LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue: could not allocate memory for header pbuf\n"));
-        goto memerr;
-      }
-      ++queuelen;
-
-      /* Concatenate the headers and data pbufs together. */
-      pbuf_cat(seg->p/*header*/, p/*data*/);
-      p = NULL;
-    }
-
-    /* Now that there are more segments queued, we check again if the
-    length of the queue exceeds the configured maximum. */
-    if (queuelen > TCP_SND_QUEUELEN) {
-      LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue: queue too long %"U16_F" (%"U16_F")\n", queuelen, TCP_SND_QUEUELEN));
-      goto memerr;
-    }
-
-    seg->len = seglen;
-
-    /* build TCP header */
-    if (pbuf_header(seg->p, TCP_HLEN)) {
-      LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue: no room for TCP header in pbuf.\n"));
-      TCP_STATS_INC(tcp.err);
-      goto memerr;
-    }
-    seg->tcphdr = seg->p->payload;
-    seg->tcphdr->src = htons(pcb->local_port);
-    seg->tcphdr->dest = htons(pcb->remote_port);
-    seg->tcphdr->seqno = htonl(seqno);
-    seg->tcphdr->urgp = 0;
-    TCPH_FLAGS_SET(seg->tcphdr, flags);
-    /* don't fill in tcphdr->ackno and tcphdr->wnd until later */
-
-    /* Copy the options into the header, if they are present. */
-    if (optdata == NULL) {
-      TCPH_HDRLEN_SET(seg->tcphdr, 5);
-    }
-    else {
-      TCPH_HDRLEN_SET(seg->tcphdr, (5 + optlen / 4));
-      /* Copy options into data portion of segment.
-       Options can thus only be sent in non data carrying
-       segments such as SYN|ACK. */
-      memcpy(seg->dataptr, optdata, optlen);
-    }
-    LWIP_DEBUGF(TCP_OUTPUT_DEBUG | DBG_TRACE, ("tcp_enqueue: queueing %"U32_F":%"U32_F" (0x%"X16_F")\n",
-      ntohl(seg->tcphdr->seqno),
-      ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg),
-      (u16_t)flags));
-
-    left -= seglen;
-    seqno += seglen;
-    ptr = (void *)((u8_t *)ptr + seglen);
-  }
-
-  /* Now that the data to be enqueued has been broken up into TCP
-  segments in the queue variable, we add them to the end of the
-  pcb->unsent queue. */
-  if (pcb->unsent == NULL) {
-    useg = NULL;
-  }
-  else {
-    for (useg = pcb->unsent; useg->next != NULL; useg = useg->next);
-  }
-  /* { useg is last segment on the unsent queue, NULL if list is empty } */
-
-  /* If there is room in the last pbuf on the unsent queue,
-  chain the first pbuf on the queue together with that. */
-  if (useg != NULL &&
-    TCP_TCPLEN(useg) != 0 &&
-    !(TCPH_FLAGS(useg->tcphdr) & (TCP_SYN | TCP_FIN)) &&
-    !(flags & (TCP_SYN | TCP_FIN)) &&
-    /* fit within max seg size */
-    useg->len + queue->len <= pcb->mss) {
-    /* Remove TCP header from first segment of our to-be-queued list */
-    pbuf_header(queue->p, -TCP_HLEN);
-    pbuf_cat(useg->p, queue->p);
-    useg->len += queue->len;
-    useg->next = queue->next;
-
-    LWIP_DEBUGF(TCP_OUTPUT_DEBUG | DBG_TRACE | DBG_STATE, ("tcp_enqueue: chaining segments, new len %"U16_F"\n", useg->len));
-    if (seg == queue) {
-      seg = NULL;
-    }
-    memp_free(MEMP_TCP_SEG, queue);
-  }
-  else {
-    /* empty list */
-    if (useg == NULL) {
-      /* initialize list with this segment */
-      pcb->unsent = queue;
-    }
-    /* enqueue segment */
-    else {
-      useg->next = queue;
-    }
-  }
-  if ((flags & TCP_SYN) || (flags & TCP_FIN)) {
-    ++len;
-  }
-  pcb->snd_lbb += len;
-
-  pcb->snd_buf -= len;
-
-  /* update number of segments on the queues */
-  pcb->snd_queuelen = queuelen;
-  LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue: %"S16_F" (after enqueued)\n", pcb->snd_queuelen));
-  if (pcb->snd_queuelen != 0) {
-    LWIP_ASSERT("tcp_enqueue: valid queue length",
-      pcb->unacked != NULL || pcb->unsent != NULL);
-  }
-
-  /* Set the PSH flag in the last segment that we enqueued, but only
-  if the segment has data (indicated by seglen > 0). */
-  if (seg != NULL && seglen > 0 && seg->tcphdr != NULL) {
-    TCPH_SET_FLAG(seg->tcphdr, TCP_PSH);
-  }
-
-  return ERR_OK;
-memerr:
-  TCP_STATS_INC(tcp.memerr);
-
-  if (queue != NULL) {
-    tcp_segs_free(queue);
-  }
-  if (pcb->snd_queuelen != 0) {
-    LWIP_ASSERT("tcp_enqueue: valid queue length", pcb->unacked != NULL ||
-      pcb->unsent != NULL);
-  }
-  LWIP_DEBUGF(TCP_QLEN_DEBUG | DBG_STATE, ("tcp_enqueue: %"S16_F" (with mem err)\n", pcb->snd_queuelen));
-  return ERR_MEM;
-}
-
-/* find out what we can send and send it */
-err_t
-tcp_output(struct tcp_pcb *pcb)
-{
-  struct pbuf *p;
-  struct tcp_hdr *tcphdr;
-  struct tcp_seg *seg, *useg;
-  u32_t wnd;
-#if TCP_CWND_DEBUG
-  s16_t i = 0;
-#endif /* TCP_CWND_DEBUG */
-
-  /* First, check if we are invoked by the TCP input processing
-     code. If so, we do not output anything. Instead, we rely on the
-     input processing code to call us when input processing is done
-     with. */
-  if (tcp_input_pcb == pcb) {
-    return ERR_OK;
-  }
-
-  wnd = LWIP_MIN(pcb->snd_wnd, pcb->cwnd);
-
-  seg = pcb->unsent;
-
-  /* useg should point to last segment on unacked queue */
-  useg = pcb->unacked;
-  if (useg != NULL) {
-    for (; useg->next != NULL; useg = useg->next);
-  }                                                                             
-   
-  /* If the TF_ACK_NOW flag is set and no data will be sent (either
-   * because the ->unsent queue is empty or because the window does
-   * not allow it), construct an empty ACK segment and send it.
-   *
-   * If data is to be sent, we will just piggyback the ACK (see below).
-   */
-  if (pcb->flags & TF_ACK_NOW &&
-     (seg == NULL ||
-      ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len > wnd)) {
-    p = pbuf_alloc(PBUF_IP, TCP_HLEN, PBUF_RAM);
-    if (p == NULL) {
-      LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: (ACK) could not allocate pbuf\n"));
-      return ERR_BUF;
-    }
-    LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: sending ACK for %"U32_F"\n", pcb->rcv_nxt));
-    /* remove ACK flags from the PCB, as we send an empty ACK now */
-    pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);
-
-    tcphdr = p->payload;
-    tcphdr->src = htons(pcb->local_port);
-    tcphdr->dest = htons(pcb->remote_port);
-    tcphdr->seqno = htonl(pcb->snd_nxt);
-    tcphdr->ackno = htonl(pcb->rcv_nxt);
-    TCPH_FLAGS_SET(tcphdr, TCP_ACK);
-    tcphdr->wnd = htons(pcb->rcv_wnd);
-    tcphdr->urgp = 0;
-    TCPH_HDRLEN_SET(tcphdr, 5);
-
-    tcphdr->chksum = 0;
-#if CHECKSUM_GEN_TCP
-    tcphdr->chksum = inet_chksum_pseudo(p, &(pcb->local_ip), &(pcb->remote_ip),
-          IP_PROTO_TCP, p->tot_len);
-#endif
-    ip_output(p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos,
-        IP_PROTO_TCP);
-    pbuf_free(p);
-
-    return ERR_OK;
-  }
-
-#if TCP_OUTPUT_DEBUG
-  if (seg == NULL) {
-    LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: nothing to send (%p)\n", (void*)pcb->unsent));
-  }
-#endif /* TCP_OUTPUT_DEBUG */
-#if TCP_CWND_DEBUG
-  if (seg == NULL) {
-    LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %"U32_F", cwnd %"U16_F", wnd %"U32_F", seg == NULL, ack %"U32_F"\n",
-                            pcb->snd_wnd, pcb->cwnd, wnd,
-                            pcb->lastack));
-  } else {
-    LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %"U32_F", cwnd %"U16_F", wnd %"U32_F", effwnd %"U32_F", seq %"U32_F", ack %"U32_F"\n",
-                            pcb->snd_wnd, pcb->cwnd, wnd,
-                            ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len,
-                            ntohl(seg->tcphdr->seqno), pcb->lastack));
-  }
-#endif /* TCP_CWND_DEBUG */
-  /* data available and window allows it to be sent? */
-  while (seg != NULL &&
-  ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len <= wnd) {
-#if TCP_CWND_DEBUG
-    LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %"U32_F", cwnd %"U16_F", wnd %"U32_F", effwnd %"U32_F", seq %"U32_F", ack %"U32_F", i %"S16_F"\n",
-                            pcb->snd_wnd, pcb->cwnd, wnd,
-                            ntohl(seg->tcphdr->seqno) + seg->len -
-                            pcb->lastack,
-                            ntohl(seg->tcphdr->seqno), pcb->lastack, i));
-    ++i;
-#endif /* TCP_CWND_DEBUG */
-
-    pcb->unsent = seg->next;
-
-    if (pcb->state != SYN_SENT) {
-      TCPH_SET_FLAG(seg->tcphdr, TCP_ACK);
-      pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);
-    }
-
-    tcp_output_segment(seg, pcb);
-    pcb->snd_nxt = ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg);
-    if (TCP_SEQ_LT(pcb->snd_max, pcb->snd_nxt)) {
-      pcb->snd_max = pcb->snd_nxt;
-    }
-    /* put segment on unacknowledged list if length > 0 */
-    if (TCP_TCPLEN(seg) > 0) {
-      seg->next = NULL;
-      /* unacked list is empty? */
-      if (pcb->unacked == NULL) {
-        pcb->unacked = seg;
-        useg = seg;
-      /* unacked list is not empty? */
-      } else {
-        /* In the case of fast retransmit, the packet should not go to the tail
-         * of the unacked queue, but rather at the head. We need to check for
-         * this case. -STJ Jul 27, 2004 */
-        if (TCP_SEQ_LT(ntohl(seg->tcphdr->seqno), ntohl(useg->tcphdr->seqno))){
-          /* add segment to head of unacked list */
-          seg->next = pcb->unacked;
-          pcb->unacked = seg;
-        } else {
-          /* add segment to tail of unacked list */
-          useg->next = seg;
-          useg = useg->next;
-        }
-      }
-    /* do not queue empty segments on the unacked list */
-    } else {
-      tcp_seg_free(seg);
-    }
-    seg = pcb->unsent;
-  }
-  return ERR_OK;
-}
-
-/**
- * Actually send a TCP segment over IP
- */
-static void
-tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb)
-{
-  u16_t len;
-  struct netif *netif;
-
-  /* The TCP header has already been constructed, but the ackno and
-   wnd fields remain. */
-  seg->tcphdr->ackno = htonl(pcb->rcv_nxt);
-
-  /* silly window avoidance */
-  if (pcb->rcv_wnd < pcb->mss) {
-    seg->tcphdr->wnd = 0;
-  } else {
-    /* advertise our receive window size in this TCP segment */
-    seg->tcphdr->wnd = htons(pcb->rcv_wnd);
-  }
-
-  /* If we don't have a local IP address, we get one by
-     calling ip_route(). */
-  if (ip_addr_isany(&(pcb->local_ip))) {
-    netif = ip_route(&(pcb->remote_ip));
-    if (netif == NULL) {
-      return;
-    }
-    ip_addr_set(&(pcb->local_ip), &(netif->ip_addr));
-  }
-
-  pcb->rtime = 0;
-
-  if (pcb->rttest == 0) {
-    pcb->rttest = tcp_ticks;
-    pcb->rtseq = ntohl(seg->tcphdr->seqno);
-
-    LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_output_segment: rtseq %"U32_F"\n", pcb->rtseq));
-  }
-  LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output_segment: %"U32_F":%"U32_F"\n",
-          htonl(seg->tcphdr->seqno), htonl(seg->tcphdr->seqno) +
-          seg->len));
-
-  len = (u16_t)((u8_t *)seg->tcphdr - (u8_t *)seg->p->payload);
-
-  seg->p->len -= len;
-  seg->p->tot_len -= len;
-
-  seg->p->payload = seg->tcphdr;
-
-  seg->tcphdr->chksum = 0;
-#if CHECKSUM_GEN_TCP
-  seg->tcphdr->chksum = inet_chksum_pseudo(seg->p,
-             &(pcb->local_ip),
-             &(pcb->remote_ip),
-             IP_PROTO_TCP, seg->p->tot_len);
-#endif
-  TCP_STATS_INC(tcp.xmit);
-
-  ip_output(seg->p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos,
-      IP_PROTO_TCP);
-}
-
-void
-tcp_rst(u32_t seqno, u32_t ackno,
-  struct ip_addr *local_ip, struct ip_addr *remote_ip,
-  u16_t local_port, u16_t remote_port)
-{
-  struct pbuf *p;
-  struct tcp_hdr *tcphdr;
-  p = pbuf_alloc(PBUF_IP, TCP_HLEN, PBUF_RAM);
-  if (p == NULL) {
-      LWIP_DEBUGF(TCP_DEBUG, ("tcp_rst: could not allocate memory for pbuf\n"));
-      return;
-  }
-
-  tcphdr = p->payload;
-  tcphdr->src = htons(local_port);
-  tcphdr->dest = htons(remote_port);
-  tcphdr->seqno = htonl(seqno);
-  tcphdr->ackno = htonl(ackno);
-  TCPH_FLAGS_SET(tcphdr, TCP_RST | TCP_ACK);
-  tcphdr->wnd = htons(TCP_WND);
-  tcphdr->urgp = 0;
-  TCPH_HDRLEN_SET(tcphdr, 5);
-
-  tcphdr->chksum = 0;
-#if CHECKSUM_GEN_TCP
-  tcphdr->chksum = inet_chksum_pseudo(p, local_ip, remote_ip,
-              IP_PROTO_TCP, p->tot_len);
-#endif
-  TCP_STATS_INC(tcp.xmit);
-   /* Send output with hardcoded TTL since we have no access to the pcb */
-  ip_output(p, local_ip, remote_ip, TCP_TTL, 0, IP_PROTO_TCP);
-  pbuf_free(p);
-  LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_rst: seqno %"U32_F" ackno %"U32_F".\n", seqno, ackno));
-}
-
-/* requeue all unacked segments for retransmission */
-void
-tcp_rexmit_rto(struct tcp_pcb *pcb)
-{
-  struct tcp_seg *seg;
-
-  if (pcb->unacked == NULL) {
-    return;
-  }
-
-  /* Move all unacked segments to the head of the unsent queue */
-  for (seg = pcb->unacked; seg->next != NULL; seg = seg->next);
-  /* concatenate unsent queue after unacked queue */
-  seg->next = pcb->unsent;
-  /* unsent queue is the concatenated queue (of unacked, unsent) */
-  pcb->unsent = pcb->unacked;
-  /* unacked queue is now empty */
-  pcb->unacked = NULL;
-
-  pcb->snd_nxt = ntohl(pcb->unsent->tcphdr->seqno);
-  /* increment number of retransmissions */
-  ++pcb->nrtx;
-
-  /* Don't take any RTT measurements after retransmitting. */
-  pcb->rttest = 0;
-
-  /* Do the actual retransmission */
-  tcp_output(pcb);
-}
-
-void
-tcp_rexmit(struct tcp_pcb *pcb)
-{
-  struct tcp_seg *seg;
-
-  if (pcb->unacked == NULL) {
-    return;
-  }
-
-  /* Move the first unacked segment to the unsent queue */
-  seg = pcb->unacked->next;
-  pcb->unacked->next = pcb->unsent;
-  pcb->unsent = pcb->unacked;
-  pcb->unacked = seg;
-
-  pcb->snd_nxt = ntohl(pcb->unsent->tcphdr->seqno);
-
-  ++pcb->nrtx;
-
-  /* Don't take any rtt measurements after retransmitting. */
-  pcb->rttest = 0;
-
-  /* Do the actual retransmission. */
-  tcp_output(pcb);
-
-}
-
-
-void
-tcp_keepalive(struct tcp_pcb *pcb)
-{
-   struct pbuf *p;
-   struct tcp_hdr *tcphdr;
-
-   LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: sending KEEPALIVE probe to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
-                           ip4_addr1(&pcb->remote_ip), ip4_addr2(&pcb->remote_ip),
-                           ip4_addr3(&pcb->remote_ip), ip4_addr4(&pcb->remote_ip)));
-
-   LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: tcp_ticks %"U32_F"   pcb->tmr %"U32_F"  pcb->keep_cnt %"U16_F"\n", tcp_ticks, pcb->tmr, pcb->keep_cnt));
-   
-   p = pbuf_alloc(PBUF_IP, TCP_HLEN, PBUF_RAM);
-
-   if(p == NULL) {
-      LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: could not allocate memory for pbuf\n"));
-      return;
-   }
-
-   tcphdr = p->payload;
-   tcphdr->src = htons(pcb->local_port);
-   tcphdr->dest = htons(pcb->remote_port);
-   tcphdr->seqno = htonl(pcb->snd_nxt - 1);
-   tcphdr->ackno = htonl(pcb->rcv_nxt);
-   tcphdr->wnd = htons(pcb->rcv_wnd);
-   tcphdr->urgp = 0;
-   TCPH_HDRLEN_SET(tcphdr, 5);
-   
-   tcphdr->chksum = 0;
-#if CHECKSUM_GEN_TCP
-   tcphdr->chksum = inet_chksum_pseudo(p, &pcb->local_ip, &pcb->remote_ip, IP_PROTO_TCP, p->tot_len);
-#endif
-  TCP_STATS_INC(tcp.xmit);
-
-   /* Send output to IP */
-  ip_output(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP);
-
-  pbuf_free(p);
-
-  LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_keepalive: seqno %"U32_F" ackno %"U32_F".\n", pcb->snd_nxt - 1, pcb->rcv_nxt));
-}
-
-#endif /* LWIP_TCP */
-
-
-
-
-
-
-
-
-
+/**\r
+ * @file\r
+ *\r
+ * Transmission Control Protocol, outgoing traffic\r
+ *\r
+ * The output functions of TCP.\r
+ *\r
+ */\r
+\r
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without modification,\r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED\r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT\r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY\r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ *\r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+\r
+#include <string.h>\r
+\r
+#include "lwip/def.h"\r
+#include "lwip/opt.h"\r
+#include "lwip/mem.h"\r
+#include "lwip/memp.h"\r
+#include "lwip/sys.h"\r
+#include "lwip/ip_addr.h"\r
+#include "lwip/netif.h"\r
+#include "lwip/inet.h"\r
+#include "lwip/tcp.h"\r
+#include "lwip/stats.h"\r
+\r
+#if LWIP_TCP\r
+\r
+/* Forward declarations.*/\r
+static void tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb);\r
+\r
+err_t\r
+tcp_send_ctrl(struct tcp_pcb *pcb, u8_t flags)\r
+{\r
+  /* no data, no length, flags, copy=1, no optdata, no optdatalen */\r
+  return tcp_enqueue(pcb, NULL, 0, flags, 1, NULL, 0);\r
+}\r
+\r
+/**\r
+ * Write data for sending (but does not send it immediately).\r
+ *\r
+ * It waits in the expectation of more data being sent soon (as\r
+ * it can send them more efficiently by combining them together).\r
+ * To prompt the system to send data now, call tcp_output() after\r
+ * calling tcp_write().\r
+ * \r
+ * @arg pcb Protocol control block of the TCP connection to enqueue data for. \r
+ * \r
+ * @see tcp_write()\r
+ */\r
+\r
+err_t\r
+tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t copy)\r
+{\r
+  LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_write(pcb=%p, arg=%p, len=%"U16_F", copy=%"U16_F")\n", (void *)pcb,\r
+    arg, len, (u16_t)copy));\r
+  /* connection is in valid state for data transmission? */\r
+  if (pcb->state == ESTABLISHED ||\r
+     pcb->state == CLOSE_WAIT ||\r
+     pcb->state == SYN_SENT ||\r
+     pcb->state == SYN_RCVD) {\r
+    if (len > 0) {\r
+      return tcp_enqueue(pcb, (void *)arg, len, 0, copy, NULL, 0);\r
+    }\r
+    return ERR_OK;\r
+  } else {\r
+    LWIP_DEBUGF(TCP_OUTPUT_DEBUG | DBG_STATE | 3, ("tcp_write() called in invalid state\n"));\r
+    return ERR_CONN;\r
+  }\r
+}\r
+\r
+/**\r
+ * Enqueue either data or TCP options (but not both) for tranmission\r
+ * \r
+ * \r
+ * \r
+ * @arg pcb Protocol control block for the TCP connection to enqueue data for.\r
+ * @arg arg Pointer to the data to be enqueued for sending.\r
+ * @arg len Data length in bytes\r
+ * @arg flags\r
+ * @arg copy 1 if data must be copied, 0 if data is non-volatile and can be\r
+ * referenced.\r
+ * @arg optdata\r
+ * @arg optlen\r
+ */\r
+err_t\r
+tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len,\r
+  u8_t flags, u8_t copy,\r
+  u8_t *optdata, u8_t optlen)\r
+{\r
+  struct pbuf *p;\r
+  struct tcp_seg *seg, *useg, *queue;\r
+  u32_t left, seqno;\r
+  u16_t seglen;\r
+  void *ptr;\r
+  u8_t queuelen;\r
+\r
+  LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_enqueue(pcb=%p, arg=%p, len=%"U16_F", flags=%"X16_F", copy=%"U16_F")\n",\r
+    (void *)pcb, arg, len, (u16_t)flags, (u16_t)copy));\r
+  LWIP_ASSERT("tcp_enqueue: len == 0 || optlen == 0 (programmer violates API)",\r
+      len == 0 || optlen == 0);\r
+  LWIP_ASSERT("tcp_enqueue: arg == NULL || optdata == NULL (programmer violates API)",\r
+      arg == NULL || optdata == NULL);\r
+  /* fail on too much data */\r
+  if (len > pcb->snd_buf) {\r
+    LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_enqueue: too much data (len=%"U16_F" > snd_buf=%"U16_F")\n", len, pcb->snd_buf));\r
+    return ERR_MEM;\r
+  }\r
+  left = len;\r
+  ptr = arg;\r
+\r
+  /* seqno will be the sequence number of the first segment enqueued\r
+   * by the call to this function. */\r
+  seqno = pcb->snd_lbb;\r
+\r
+  LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue: queuelen: %"U16_F"\n", (u16_t)pcb->snd_queuelen));\r
+\r
+  /* If total number of pbufs on the unsent/unacked queues exceeds the\r
+   * configured maximum, return an error */\r
+  queuelen = pcb->snd_queuelen;\r
+  if (queuelen >= TCP_SND_QUEUELEN) {\r
+    LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_enqueue: too long queue %"U16_F" (max %"U16_F")\n", queuelen, TCP_SND_QUEUELEN));\r
+    TCP_STATS_INC(tcp.memerr);\r
+    return ERR_MEM;\r
+  }\r
+  if (queuelen != 0) {\r
+    LWIP_ASSERT("tcp_enqueue: pbufs on queue => at least one queue non-empty",\r
+      pcb->unacked != NULL || pcb->unsent != NULL);\r
+  } else {\r
+    LWIP_ASSERT("tcp_enqueue: no pbufs on queue => both queues empty",\r
+      pcb->unacked == NULL && pcb->unsent == NULL);\r
+  }\r
+\r
+  /* First, break up the data into segments and tuck them together in\r
+   * the local "queue" variable. */\r
+  useg = queue = seg = NULL;\r
+  seglen = 0;\r
+  while (queue == NULL || left > 0) {\r
+\r
+    /* The segment length should be the MSS if the data to be enqueued\r
+     * is larger than the MSS. */\r
+    seglen = left > pcb->mss? pcb->mss: left;\r
+\r
+    /* Allocate memory for tcp_seg, and fill in fields. */\r
+    seg = memp_malloc(MEMP_TCP_SEG);\r
+    if (seg == NULL) {\r
+      LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue: could not allocate memory for tcp_seg\n"));\r
+      goto memerr;\r
+    }\r
+    seg->next = NULL;\r
+    seg->p = NULL;\r
+\r
+    /* first segment of to-be-queued data? */\r
+    if (queue == NULL) {\r
+      queue = seg;\r
+    }\r
+    /* subsequent segments of to-be-queued data */\r
+    else {\r
+      /* Attach the segment to the end of the queued segments */\r
+      LWIP_ASSERT("useg != NULL", useg != NULL);\r
+      useg->next = seg;\r
+    }\r
+    /* remember last segment of to-be-queued data for next iteration */\r
+    useg = seg;\r
+\r
+    /* If copy is set, memory should be allocated\r
+     * and data copied into pbuf, otherwise data comes from\r
+     * ROM or other static memory, and need not be copied. If\r
+     * optdata is != NULL, we have options instead of data. */\r
+     \r
+    /* options? */\r
+    if (optdata != NULL) {\r
+      if ((seg->p = pbuf_alloc(PBUF_TRANSPORT, optlen, PBUF_RAM)) == NULL) {\r
+        goto memerr;\r
+      }\r
+      ++queuelen;\r
+      seg->dataptr = seg->p->payload;\r
+    }\r
+    /* copy from volatile memory? */\r
+    else if (copy) {\r
+      if ((seg->p = pbuf_alloc(PBUF_TRANSPORT, seglen, PBUF_RAM)) == NULL) {\r
+        LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue : could not allocate memory for pbuf copy size %"U16_F"\n", seglen));\r
+        goto memerr;\r
+      }\r
+      ++queuelen;\r
+      if (arg != NULL) {\r
+        memcpy(seg->p->payload, ptr, seglen);\r
+      }\r
+      seg->dataptr = seg->p->payload;\r
+    }\r
+    /* do not copy data */\r
+    else {\r
+      /* First, allocate a pbuf for holding the data.\r
+       * since the referenced data is available at least until it is sent out on the\r
+       * link (as it has to be ACKed by the remote party) we can safely use PBUF_ROM\r
+       * instead of PBUF_REF here.\r
+       */\r
+      if ((p = pbuf_alloc(PBUF_TRANSPORT, seglen, PBUF_ROM)) == NULL) {\r
+        LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue: could not allocate memory for zero-copy pbuf\n"));\r
+        goto memerr;\r
+      }\r
+      ++queuelen;\r
+      /* reference the non-volatile payload data */\r
+      p->payload = ptr;\r
+      seg->dataptr = ptr;\r
+\r
+      /* Second, allocate a pbuf for the headers. */\r
+      if ((seg->p = pbuf_alloc(PBUF_TRANSPORT, 0, PBUF_RAM)) == NULL) {\r
+        /* If allocation fails, we have to deallocate the data pbuf as\r
+         * well. */\r
+        pbuf_free(p);\r
+        LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue: could not allocate memory for header pbuf\n"));\r
+        goto memerr;\r
+      }\r
+      ++queuelen;\r
+\r
+      /* Concatenate the headers and data pbufs together. */\r
+      pbuf_cat(seg->p/*header*/, p/*data*/);\r
+      p = NULL;\r
+    }\r
+\r
+    /* Now that there are more segments queued, we check again if the\r
+    length of the queue exceeds the configured maximum. */\r
+    if (queuelen > TCP_SND_QUEUELEN) {\r
+      LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue: queue too long %"U16_F" (%"U16_F")\n", queuelen, TCP_SND_QUEUELEN));\r
+      goto memerr;\r
+    }\r
+\r
+    seg->len = seglen;\r
+\r
+    /* build TCP header */\r
+    if (pbuf_header(seg->p, TCP_HLEN)) {\r
+      LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue: no room for TCP header in pbuf.\n"));\r
+      TCP_STATS_INC(tcp.err);\r
+      goto memerr;\r
+    }\r
+    seg->tcphdr = seg->p->payload;\r
+    seg->tcphdr->src = htons(pcb->local_port);\r
+    seg->tcphdr->dest = htons(pcb->remote_port);\r
+    seg->tcphdr->seqno = htonl(seqno);\r
+    seg->tcphdr->urgp = 0;\r
+    TCPH_FLAGS_SET(seg->tcphdr, flags);\r
+    /* don't fill in tcphdr->ackno and tcphdr->wnd until later */\r
+\r
+    /* Copy the options into the header, if they are present. */\r
+    if (optdata == NULL) {\r
+      TCPH_HDRLEN_SET(seg->tcphdr, 5);\r
+    }\r
+    else {\r
+      TCPH_HDRLEN_SET(seg->tcphdr, (5 + optlen / 4));\r
+      /* Copy options into data portion of segment.\r
+       Options can thus only be sent in non data carrying\r
+       segments such as SYN|ACK. */\r
+      memcpy(seg->dataptr, optdata, optlen);\r
+    }\r
+    LWIP_DEBUGF(TCP_OUTPUT_DEBUG | DBG_TRACE, ("tcp_enqueue: queueing %"U32_F":%"U32_F" (0x%"X16_F")\n",\r
+      ntohl(seg->tcphdr->seqno),\r
+      ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg),\r
+      (u16_t)flags));\r
+\r
+    left -= seglen;\r
+    seqno += seglen;\r
+    ptr = (void *)((u8_t *)ptr + seglen);\r
+  }\r
+\r
+  /* Now that the data to be enqueued has been broken up into TCP\r
+  segments in the queue variable, we add them to the end of the\r
+  pcb->unsent queue. */\r
+  if (pcb->unsent == NULL) {\r
+    useg = NULL;\r
+  }\r
+  else {\r
+    for (useg = pcb->unsent; useg->next != NULL; useg = useg->next);\r
+  }\r
+  /* { useg is last segment on the unsent queue, NULL if list is empty } */\r
+\r
+  /* If there is room in the last pbuf on the unsent queue,\r
+  chain the first pbuf on the queue together with that. */\r
+  if (useg != NULL &&\r
+    TCP_TCPLEN(useg) != 0 &&\r
+    !(TCPH_FLAGS(useg->tcphdr) & (TCP_SYN | TCP_FIN)) &&\r
+    !(flags & (TCP_SYN | TCP_FIN)) &&\r
+    /* fit within max seg size */\r
+    useg->len + queue->len <= pcb->mss) {\r
+    /* Remove TCP header from first segment of our to-be-queued list */\r
+    pbuf_header(queue->p, -TCP_HLEN);\r
+    pbuf_cat(useg->p, queue->p);\r
+    useg->len += queue->len;\r
+    useg->next = queue->next;\r
+\r
+    LWIP_DEBUGF(TCP_OUTPUT_DEBUG | DBG_TRACE | DBG_STATE, ("tcp_enqueue: chaining segments, new len %"U16_F"\n", useg->len));\r
+    if (seg == queue) {\r
+      seg = NULL;\r
+    }\r
+    memp_free(MEMP_TCP_SEG, queue);\r
+  }\r
+  else {\r
+    /* empty list */\r
+    if (useg == NULL) {\r
+      /* initialize list with this segment */\r
+      pcb->unsent = queue;\r
+    }\r
+    /* enqueue segment */\r
+    else {\r
+      useg->next = queue;\r
+    }\r
+  }\r
+  if ((flags & TCP_SYN) || (flags & TCP_FIN)) {\r
+    ++len;\r
+  }\r
+  pcb->snd_lbb += len;\r
+\r
+  pcb->snd_buf -= len;\r
+\r
+  /* update number of segments on the queues */\r
+  pcb->snd_queuelen = queuelen;\r
+  LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue: %"S16_F" (after enqueued)\n", pcb->snd_queuelen));\r
+  if (pcb->snd_queuelen != 0) {\r
+    LWIP_ASSERT("tcp_enqueue: valid queue length",\r
+      pcb->unacked != NULL || pcb->unsent != NULL);\r
+  }\r
+\r
+  /* Set the PSH flag in the last segment that we enqueued, but only\r
+  if the segment has data (indicated by seglen > 0). */\r
+  if (seg != NULL && seglen > 0 && seg->tcphdr != NULL) {\r
+    TCPH_SET_FLAG(seg->tcphdr, TCP_PSH);\r
+  }\r
+\r
+  return ERR_OK;\r
+memerr:\r
+  TCP_STATS_INC(tcp.memerr);\r
+\r
+  if (queue != NULL) {\r
+    tcp_segs_free(queue);\r
+  }\r
+  if (pcb->snd_queuelen != 0) {\r
+    LWIP_ASSERT("tcp_enqueue: valid queue length", pcb->unacked != NULL ||\r
+      pcb->unsent != NULL);\r
+  }\r
+  LWIP_DEBUGF(TCP_QLEN_DEBUG | DBG_STATE, ("tcp_enqueue: %"S16_F" (with mem err)\n", pcb->snd_queuelen));\r
+  return ERR_MEM;\r
+}\r
+\r
+/* find out what we can send and send it */\r
+err_t\r
+tcp_output(struct tcp_pcb *pcb)\r
+{\r
+  struct pbuf *p;\r
+  struct tcp_hdr *tcphdr;\r
+  struct tcp_seg *seg, *useg;\r
+  u32_t wnd;\r
+#if TCP_CWND_DEBUG\r
+  s16_t i = 0;\r
+#endif /* TCP_CWND_DEBUG */\r
+\r
+  /* First, check if we are invoked by the TCP input processing\r
+     code. If so, we do not output anything. Instead, we rely on the\r
+     input processing code to call us when input processing is done\r
+     with. */\r
+  if (tcp_input_pcb == pcb) {\r
+    return ERR_OK;\r
+  }\r
+\r
+  wnd = LWIP_MIN(pcb->snd_wnd, pcb->cwnd);\r
+\r
+  seg = pcb->unsent;\r
+\r
+  /* useg should point to last segment on unacked queue */\r
+  useg = pcb->unacked;\r
+  if (useg != NULL) {\r
+    for (; useg->next != NULL; useg = useg->next);\r
+  }                                                                             \r
+   \r
+  /* If the TF_ACK_NOW flag is set and no data will be sent (either\r
+   * because the ->unsent queue is empty or because the window does\r
+   * not allow it), construct an empty ACK segment and send it.\r
+   *\r
+   * If data is to be sent, we will just piggyback the ACK (see below).\r
+   */\r
+  if (pcb->flags & TF_ACK_NOW &&\r
+     (seg == NULL ||\r
+      ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len > wnd)) {\r
+    p = pbuf_alloc(PBUF_IP, TCP_HLEN, PBUF_RAM);\r
+    if (p == NULL) {\r
+      LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: (ACK) could not allocate pbuf\n"));\r
+      return ERR_BUF;\r
+    }\r
+    LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: sending ACK for %"U32_F"\n", pcb->rcv_nxt));\r
+    /* remove ACK flags from the PCB, as we send an empty ACK now */\r
+    pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);\r
+\r
+    tcphdr = p->payload;\r
+    tcphdr->src = htons(pcb->local_port);\r
+    tcphdr->dest = htons(pcb->remote_port);\r
+    tcphdr->seqno = htonl(pcb->snd_nxt);\r
+    tcphdr->ackno = htonl(pcb->rcv_nxt);\r
+    TCPH_FLAGS_SET(tcphdr, TCP_ACK);\r
+    tcphdr->wnd = htons(pcb->rcv_wnd);\r
+    tcphdr->urgp = 0;\r
+    TCPH_HDRLEN_SET(tcphdr, 5);\r
+\r
+    tcphdr->chksum = 0;\r
+#if CHECKSUM_GEN_TCP\r
+    tcphdr->chksum = inet_chksum_pseudo(p, &(pcb->local_ip), &(pcb->remote_ip),\r
+          IP_PROTO_TCP, p->tot_len);\r
+#endif\r
+    ip_output(p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos,\r
+        IP_PROTO_TCP);\r
+    pbuf_free(p);\r
+\r
+    return ERR_OK;\r
+  }\r
+\r
+#if TCP_OUTPUT_DEBUG\r
+  if (seg == NULL) {\r
+    LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: nothing to send (%p)\n", (void*)pcb->unsent));\r
+  }\r
+#endif /* TCP_OUTPUT_DEBUG */\r
+#if TCP_CWND_DEBUG\r
+  if (seg == NULL) {\r
+    LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %"U32_F", cwnd %"U16_F", wnd %"U32_F", seg == NULL, ack %"U32_F"\n",\r
+                            pcb->snd_wnd, pcb->cwnd, wnd,\r
+                            pcb->lastack));\r
+  } else {\r
+    LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %"U32_F", cwnd %"U16_F", wnd %"U32_F", effwnd %"U32_F", seq %"U32_F", ack %"U32_F"\n",\r
+                            pcb->snd_wnd, pcb->cwnd, wnd,\r
+                            ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len,\r
+                            ntohl(seg->tcphdr->seqno), pcb->lastack));\r
+  }\r
+#endif /* TCP_CWND_DEBUG */\r
+  /* data available and window allows it to be sent? */\r
+  while (seg != NULL &&\r
+  ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len <= wnd) {\r
+#if TCP_CWND_DEBUG\r
+    LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %"U32_F", cwnd %"U16_F", wnd %"U32_F", effwnd %"U32_F", seq %"U32_F", ack %"U32_F", i %"S16_F"\n",\r
+                            pcb->snd_wnd, pcb->cwnd, wnd,\r
+                            ntohl(seg->tcphdr->seqno) + seg->len -\r
+                            pcb->lastack,\r
+                            ntohl(seg->tcphdr->seqno), pcb->lastack, i));\r
+    ++i;\r
+#endif /* TCP_CWND_DEBUG */\r
+\r
+    pcb->unsent = seg->next;\r
+\r
+    if (pcb->state != SYN_SENT) {\r
+      TCPH_SET_FLAG(seg->tcphdr, TCP_ACK);\r
+      pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);\r
+    }\r
+\r
+    tcp_output_segment(seg, pcb);\r
+    pcb->snd_nxt = ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg);\r
+    if (TCP_SEQ_LT(pcb->snd_max, pcb->snd_nxt)) {\r
+      pcb->snd_max = pcb->snd_nxt;\r
+    }\r
+    /* put segment on unacknowledged list if length > 0 */\r
+    if (TCP_TCPLEN(seg) > 0) {\r
+      seg->next = NULL;\r
+      /* unacked list is empty? */\r
+      if (pcb->unacked == NULL) {\r
+        pcb->unacked = seg;\r
+        useg = seg;\r
+      /* unacked list is not empty? */\r
+      } else {\r
+        /* In the case of fast retransmit, the packet should not go to the tail\r
+         * of the unacked queue, but rather at the head. We need to check for\r
+         * this case. -STJ Jul 27, 2004 */\r
+        if (TCP_SEQ_LT(ntohl(seg->tcphdr->seqno), ntohl(useg->tcphdr->seqno))){\r
+          /* add segment to head of unacked list */\r
+          seg->next = pcb->unacked;\r
+          pcb->unacked = seg;\r
+        } else {\r
+          /* add segment to tail of unacked list */\r
+          useg->next = seg;\r
+          useg = useg->next;\r
+        }\r
+      }\r
+    /* do not queue empty segments on the unacked list */\r
+    } else {\r
+      tcp_seg_free(seg);\r
+    }\r
+    seg = pcb->unsent;\r
+  }\r
+  return ERR_OK;\r
+}\r
+\r
+/**\r
+ * Actually send a TCP segment over IP\r
+ */\r
+static void\r
+tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb)\r
+{\r
+  u16_t len;\r
+  struct netif *netif;\r
+\r
+  /* The TCP header has already been constructed, but the ackno and\r
+   wnd fields remain. */\r
+  seg->tcphdr->ackno = htonl(pcb->rcv_nxt);\r
+\r
+  /* silly window avoidance */\r
+  if (pcb->rcv_wnd < pcb->mss) {\r
+    seg->tcphdr->wnd = 0;\r
+  } else {\r
+    /* advertise our receive window size in this TCP segment */\r
+    seg->tcphdr->wnd = htons(pcb->rcv_wnd);\r
+  }\r
+\r
+  /* If we don't have a local IP address, we get one by\r
+     calling ip_route(). */\r
+  if (ip_addr_isany(&(pcb->local_ip))) {\r
+    netif = ip_route(&(pcb->remote_ip));\r
+    if (netif == NULL) {\r
+      return;\r
+    }\r
+    ip_addr_set(&(pcb->local_ip), &(netif->ip_addr));\r
+  }\r
+\r
+  pcb->rtime = 0;\r
+\r
+  if (pcb->rttest == 0) {\r
+    pcb->rttest = tcp_ticks;\r
+    pcb->rtseq = ntohl(seg->tcphdr->seqno);\r
+\r
+    LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_output_segment: rtseq %"U32_F"\n", pcb->rtseq));\r
+  }\r
+  LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output_segment: %"U32_F":%"U32_F"\n",\r
+          htonl(seg->tcphdr->seqno), htonl(seg->tcphdr->seqno) +\r
+          seg->len));\r
+\r
+  len = (u16_t)((u8_t *)seg->tcphdr - (u8_t *)seg->p->payload);\r
+\r
+  seg->p->len -= len;\r
+  seg->p->tot_len -= len;\r
+\r
+  seg->p->payload = seg->tcphdr;\r
+\r
+  seg->tcphdr->chksum = 0;\r
+#if CHECKSUM_GEN_TCP\r
+  seg->tcphdr->chksum = inet_chksum_pseudo(seg->p,\r
+             &(pcb->local_ip),\r
+             &(pcb->remote_ip),\r
+             IP_PROTO_TCP, seg->p->tot_len);\r
+#endif\r
+  TCP_STATS_INC(tcp.xmit);\r
+\r
+  ip_output(seg->p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos,\r
+      IP_PROTO_TCP);\r
+}\r
+\r
+void\r
+tcp_rst(u32_t seqno, u32_t ackno,\r
+  struct ip_addr *local_ip, struct ip_addr *remote_ip,\r
+  u16_t local_port, u16_t remote_port)\r
+{\r
+  struct pbuf *p;\r
+  struct tcp_hdr *tcphdr;\r
+  p = pbuf_alloc(PBUF_IP, TCP_HLEN, PBUF_RAM);\r
+  if (p == NULL) {\r
+      LWIP_DEBUGF(TCP_DEBUG, ("tcp_rst: could not allocate memory for pbuf\n"));\r
+      return;\r
+  }\r
+\r
+  tcphdr = p->payload;\r
+  tcphdr->src = htons(local_port);\r
+  tcphdr->dest = htons(remote_port);\r
+  tcphdr->seqno = htonl(seqno);\r
+  tcphdr->ackno = htonl(ackno);\r
+  TCPH_FLAGS_SET(tcphdr, TCP_RST | TCP_ACK);\r
+  tcphdr->wnd = htons(TCP_WND);\r
+  tcphdr->urgp = 0;\r
+  TCPH_HDRLEN_SET(tcphdr, 5);\r
+\r
+  tcphdr->chksum = 0;\r
+#if CHECKSUM_GEN_TCP\r
+  tcphdr->chksum = inet_chksum_pseudo(p, local_ip, remote_ip,\r
+              IP_PROTO_TCP, p->tot_len);\r
+#endif\r
+  TCP_STATS_INC(tcp.xmit);\r
+   /* Send output with hardcoded TTL since we have no access to the pcb */\r
+  ip_output(p, local_ip, remote_ip, TCP_TTL, 0, IP_PROTO_TCP);\r
+  pbuf_free(p);\r
+  LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_rst: seqno %"U32_F" ackno %"U32_F".\n", seqno, ackno));\r
+}\r
+\r
+/* requeue all unacked segments for retransmission */\r
+void\r
+tcp_rexmit_rto(struct tcp_pcb *pcb)\r
+{\r
+  struct tcp_seg *seg;\r
+\r
+  if (pcb->unacked == NULL) {\r
+    return;\r
+  }\r
+\r
+  /* Move all unacked segments to the head of the unsent queue */\r
+  for (seg = pcb->unacked; seg->next != NULL; seg = seg->next);\r
+  /* concatenate unsent queue after unacked queue */\r
+  seg->next = pcb->unsent;\r
+  /* unsent queue is the concatenated queue (of unacked, unsent) */\r
+  pcb->unsent = pcb->unacked;\r
+  /* unacked queue is now empty */\r
+  pcb->unacked = NULL;\r
+\r
+  pcb->snd_nxt = ntohl(pcb->unsent->tcphdr->seqno);\r
+  /* increment number of retransmissions */\r
+  ++pcb->nrtx;\r
+\r
+  /* Don't take any RTT measurements after retransmitting. */\r
+  pcb->rttest = 0;\r
+\r
+  /* Do the actual retransmission */\r
+  tcp_output(pcb);\r
+}\r
+\r
+void\r
+tcp_rexmit(struct tcp_pcb *pcb)\r
+{\r
+  struct tcp_seg *seg;\r
+\r
+  if (pcb->unacked == NULL) {\r
+    return;\r
+  }\r
+\r
+  /* Move the first unacked segment to the unsent queue */\r
+  seg = pcb->unacked->next;\r
+  pcb->unacked->next = pcb->unsent;\r
+  pcb->unsent = pcb->unacked;\r
+  pcb->unacked = seg;\r
+\r
+  pcb->snd_nxt = ntohl(pcb->unsent->tcphdr->seqno);\r
+\r
+  ++pcb->nrtx;\r
+\r
+  /* Don't take any rtt measurements after retransmitting. */\r
+  pcb->rttest = 0;\r
+\r
+  /* Do the actual retransmission. */\r
+  tcp_output(pcb);\r
+\r
+}\r
+\r
+\r
+void\r
+tcp_keepalive(struct tcp_pcb *pcb)\r
+{\r
+   struct pbuf *p;\r
+   struct tcp_hdr *tcphdr;\r
+\r
+   LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: sending KEEPALIVE probe to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",\r
+                           ip4_addr1(&pcb->remote_ip), ip4_addr2(&pcb->remote_ip),\r
+                           ip4_addr3(&pcb->remote_ip), ip4_addr4(&pcb->remote_ip)));\r
+\r
+   LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: tcp_ticks %"U32_F"   pcb->tmr %"U32_F"  pcb->keep_cnt %"U16_F"\n", tcp_ticks, pcb->tmr, pcb->keep_cnt));\r
+   \r
+   p = pbuf_alloc(PBUF_IP, TCP_HLEN, PBUF_RAM);\r
+\r
+   if(p == NULL) {\r
+      LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: could not allocate memory for pbuf\n"));\r
+      return;\r
+   }\r
+\r
+   tcphdr = p->payload;\r
+   tcphdr->src = htons(pcb->local_port);\r
+   tcphdr->dest = htons(pcb->remote_port);\r
+   tcphdr->seqno = htonl(pcb->snd_nxt - 1);\r
+   tcphdr->ackno = htonl(pcb->rcv_nxt);\r
+   tcphdr->wnd = htons(pcb->rcv_wnd);\r
+   tcphdr->urgp = 0;\r
+   TCPH_HDRLEN_SET(tcphdr, 5);\r
+   \r
+   tcphdr->chksum = 0;\r
+#if CHECKSUM_GEN_TCP\r
+   tcphdr->chksum = inet_chksum_pseudo(p, &pcb->local_ip, &pcb->remote_ip, IP_PROTO_TCP, p->tot_len);\r
+#endif\r
+  TCP_STATS_INC(tcp.xmit);\r
+\r
+   /* Send output to IP */\r
+  ip_output(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP);\r
+\r
+  pbuf_free(p);\r
+\r
+  LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_keepalive: seqno %"U32_F" ackno %"U32_F".\n", pcb->snd_nxt - 1, pcb->rcv_nxt));\r
+}\r
+\r
+#endif /* LWIP_TCP */\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
index d1e0eacacd48963efb049db24a561f0b4c22ac36..76ff59dba6fd7b519eac08b91b44ee3ecb04b40f 100644 (file)
-/**
- * @file
- * User Datagram Protocol module
- *
- */
-/*
- * 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 <adam@sics.se>
- *
- */
-
-
-/* udp.c
- *
- * The code for the User Datagram Protocol UDP.
- *
- */
-
-#include <string.h>
-
-#include "lwip/opt.h"
-
-#include "lwip/def.h"
-#include "lwip/memp.h"
-#include "lwip/inet.h"
-#include "lwip/ip_addr.h"
-#include "lwip/netif.h"
-#include "lwip/udp.h"
-#include "lwip/icmp.h"
-
-#include "lwip/stats.h"
-
-#include "arch/perf.h"
-#include "lwip/snmp.h"
-
-/* The list of UDP PCBs */
-#if LWIP_UDP
-/* was static, but we may want to access this from a socket layer */
-struct udp_pcb *udp_pcbs = NULL;
-
-static struct udp_pcb *pcb_cache = NULL;
-
-void
-udp_init(void)
-{
-  udp_pcbs = pcb_cache = NULL;
-}
-
-/**
- * Process an incoming UDP datagram.
- *
- * Given an incoming UDP datagram (as a chain of pbufs) this function
- * finds a corresponding UDP PCB and
- *
- * @param pbuf pbuf to be demultiplexed to a UDP PCB.
- * @param netif network interface on which the datagram was received.
- *
- */
-void
-udp_input(struct pbuf *p, struct netif *inp)
-{
-  struct udp_hdr *udphdr;
-  struct udp_pcb *pcb;
-  struct udp_pcb *uncon_pcb;
-  struct ip_hdr *iphdr;
-  u16_t src, dest;
-  u8_t local_match;
-
-  PERF_START;
-
-  UDP_STATS_INC(udp.recv);
-
-  iphdr = p->payload;
-
-  if (pbuf_header(p, -((s16_t)(UDP_HLEN + IPH_HL(iphdr) * 4)))) {
-    /* drop short packets */
-    LWIP_DEBUGF(UDP_DEBUG, ("udp_input: short UDP datagram (%"U16_F" bytes) discarded\n", p->tot_len));
-    UDP_STATS_INC(udp.lenerr);
-    UDP_STATS_INC(udp.drop);
-    snmp_inc_udpinerrors();
-    pbuf_free(p);
-    goto end;
-  }
-
-  udphdr = (struct udp_hdr *)((u8_t *)p->payload - UDP_HLEN);
-
-  LWIP_DEBUGF(UDP_DEBUG, ("udp_input: received datagram of length %"U16_F"\n", p->tot_len));
-
-  src = ntohs(udphdr->src);
-  dest = ntohs(udphdr->dest);
-
-  udp_debug_print(udphdr);
-
-  /* print the UDP source and destination */
-  LWIP_DEBUGF(UDP_DEBUG, ("udp (%"U16_F".%"U16_F".%"U16_F".%"U16_F", %"U16_F") <-- (%"U16_F".%"U16_F".%"U16_F".%"U16_F", %"U16_F")\n",
-    ip4_addr1(&iphdr->dest), ip4_addr2(&iphdr->dest),
-    ip4_addr3(&iphdr->dest), ip4_addr4(&iphdr->dest), ntohs(udphdr->dest),
-    ip4_addr1(&iphdr->src), ip4_addr2(&iphdr->src),
-    ip4_addr3(&iphdr->src), ip4_addr4(&iphdr->src), ntohs(udphdr->src)));
-
-  local_match = 0;
-  uncon_pcb = NULL;
-  /* Iterate through the UDP pcb list for a matching pcb */
-  for (pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) {
-    /* print the PCB local and remote address */
-    LWIP_DEBUGF(UDP_DEBUG, ("pcb (%"U16_F".%"U16_F".%"U16_F".%"U16_F", %"U16_F") --- (%"U16_F".%"U16_F".%"U16_F".%"U16_F", %"U16_F")\n",
-      ip4_addr1(&pcb->local_ip), ip4_addr2(&pcb->local_ip),
-      ip4_addr3(&pcb->local_ip), ip4_addr4(&pcb->local_ip), pcb->local_port,
-      ip4_addr1(&pcb->remote_ip), ip4_addr2(&pcb->remote_ip),
-      ip4_addr3(&pcb->remote_ip), ip4_addr4(&pcb->remote_ip), pcb->remote_port));
-
-    /* compare PCB local addr+port to UDP destination addr+port */
-    if ((pcb->local_port == dest) &&
-       (ip_addr_isany(&pcb->local_ip) ||
-        ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest)))) {
-       local_match = 1;
-       if ((uncon_pcb == NULL) && 
-           ((pcb->flags & UDP_FLAGS_CONNECTED) == 0)) {
-         /* the first unconnected matching PCB */     
-         uncon_pcb = pcb;
-       }
-    }
-    /* compare PCB remote addr+port to UDP source addr+port */
-    if ((local_match != 0) &&
-       (pcb->remote_port == src) &&
-       (ip_addr_isany(&pcb->remote_ip) ||
-       ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src)))) {
-       /* the first fully matching PCB */
-      break;
-    }
-  }
-  /* no fully matching pcb found? then look for an unconnected pcb */
-  if (pcb == NULL) {
-    pcb = uncon_pcb;
-  }
-
-  /* Check checksum if this is a match or if it was directed at us. */
-  if (pcb != NULL  || ip_addr_cmp(&inp->ip_addr, &iphdr->dest))
-    {
-    LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE, ("udp_input: calculating checksum\n"));
-    pbuf_header(p, UDP_HLEN);
-#ifdef IPv6
-    if (iphdr->nexthdr == IP_PROTO_UDPLITE) {
-#else
-    if (IPH_PROTO(iphdr) == IP_PROTO_UDPLITE) {
-#endif /* IPv4 */
-      /* Do the UDP Lite checksum */
-#if CHECKSUM_CHECK_UDP
-      if (inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src),
-         (struct ip_addr *)&(iphdr->dest),
-         IP_PROTO_UDPLITE, ntohs(udphdr->len)) != 0) {
-  LWIP_DEBUGF(UDP_DEBUG | 2, ("udp_input: UDP Lite datagram discarded due to failing checksum\n"));
-  UDP_STATS_INC(udp.chkerr);
-  UDP_STATS_INC(udp.drop);
-  snmp_inc_udpinerrors();
-  pbuf_free(p);
-  goto end;
-      }
-#endif
-    } else {
-#if CHECKSUM_CHECK_UDP
-      if (udphdr->chksum != 0) {
-  if (inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src),
-       (struct ip_addr *)&(iphdr->dest),
-        IP_PROTO_UDP, p->tot_len) != 0) {
-    LWIP_DEBUGF(UDP_DEBUG | 2, ("udp_input: UDP datagram discarded due to failing checksum\n"));
-
-    UDP_STATS_INC(udp.chkerr);
-    UDP_STATS_INC(udp.drop);
-    snmp_inc_udpinerrors();
-    pbuf_free(p);
-    goto end;
-  }
-      }
-#endif
-    }
-    pbuf_header(p, -UDP_HLEN);
-    if (pcb != NULL) {
-      snmp_inc_udpindatagrams();
-      /* callback */
-      if (pcb->recv != NULL)
-      {
-        pcb->recv(pcb->recv_arg, pcb, p, &(iphdr->src), src);
-      }
-        } else {
-      LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE, ("udp_input: not for us.\n"));
-
-      /* No match was found, send ICMP destination port unreachable unless
-      destination address was broadcast/multicast. */
-
-      if (!ip_addr_isbroadcast(&iphdr->dest, inp) &&
-          !ip_addr_ismulticast(&iphdr->dest)) {
-
-  /* adjust pbuf pointer */
-  p->payload = iphdr;
-  icmp_dest_unreach(p, ICMP_DUR_PORT);
-      }
-      UDP_STATS_INC(udp.proterr);
-      UDP_STATS_INC(udp.drop);
-    snmp_inc_udpnoports();
-      pbuf_free(p);
-    }
-  } else {
-    pbuf_free(p);
-  }
-  end:
-
-  PERF_STOP("udp_input");
-}
-
-/**
- * Send data to a specified address using UDP.
- *
- * @param pcb UDP PCB used to send the data.
- * @param pbuf chain of pbuf's to be sent.
- * @param dst_ip Destination IP address.
- * @param dst_port Destination UDP port.
- *
- * If the PCB already has a remote address association, it will
- * be restored after the data is sent.
- * 
- * @return lwIP error code.
- * - ERR_OK. Successful. No error occured.
- * - ERR_MEM. Out of memory.
- * - ERR_RTE. Could not find route to destination address.
- *
- * @see udp_disconnect() udp_send()
- */
-err_t
-udp_sendto(struct udp_pcb *pcb, struct pbuf *p,
-  struct ip_addr *dst_ip, u16_t dst_port)
-{
-  err_t err;
-  /* temporary space for current PCB remote address */
-  struct ip_addr pcb_remote_ip;
-  u16_t pcb_remote_port;
-  /* remember current remote peer address of PCB */
-  pcb_remote_ip.addr = pcb->remote_ip.addr;
-  pcb_remote_port = pcb->remote_port;
-  /* copy packet destination address to PCB remote peer address */
-  pcb->remote_ip.addr = dst_ip->addr;
-  pcb->remote_port = dst_port;
-  /* send to the packet destination address */
-  err = udp_send(pcb, p);
-  /* restore PCB remote peer address */
-  pcb->remote_ip.addr = pcb_remote_ip.addr;
-  pcb->remote_port = pcb_remote_port;
-  return err;
-}
-
-/**
- * Send data using UDP.
- *
- * @param pcb UDP PCB used to send the data.
- * @param pbuf chain of pbuf's to be sent.
- *
- * @return lwIP error code.
- * - ERR_OK. Successful. No error occured.
- * - ERR_MEM. Out of memory.
- * - ERR_RTE. Could not find route to destination address.
- *
- * @see udp_disconnect() udp_sendto()
- */
-err_t
-udp_send(struct udp_pcb *pcb, struct pbuf *p)
-{
-  struct udp_hdr *udphdr;
-  struct netif *netif;
-  struct ip_addr *src_ip;
-  err_t err;
-  struct pbuf *q; /* q will be sent down the stack */
-
-  LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | 3, ("udp_send\n"));
-
-  /* if the PCB is not yet bound to a port, bind it here */
-  if (pcb->local_port == 0) {
-    LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | 2, ("udp_send: not yet bound to a port, binding now\n"));
-    err = udp_bind(pcb, &pcb->local_ip, pcb->local_port);
-    if (err != ERR_OK) {
-      LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | 2, ("udp_send: forced port bind failed\n"));
-      return err;
-    }
-  }
-  /* find the outgoing network interface for this packet */
-  netif = ip_route(&(pcb->remote_ip));
-  /* no outgoing network interface could be found? */
-  if (netif == NULL) {
-    LWIP_DEBUGF(UDP_DEBUG | 1, ("udp_send: No route to 0x%"X32_F"\n", pcb->remote_ip.addr));
-    UDP_STATS_INC(udp.rterr);
-    return ERR_RTE;
-  }
-
-  /* not enough space to add an UDP header to first pbuf in given p chain? */
-  if (pbuf_header(p, UDP_HLEN)) {
-    /* allocate header in a seperate new pbuf */
-    q = pbuf_alloc(PBUF_IP, UDP_HLEN, PBUF_RAM);
-    /* new header pbuf could not be allocated? */
-    if (q == NULL) {
-      LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | 2, ("udp_send: could not allocate header\n"));
-      return ERR_MEM;
-    }
-    /* chain header q in front of given pbuf p */
-    pbuf_chain(q, p);
-    /* { first pbuf q points to header pbuf } */
-    LWIP_DEBUGF(UDP_DEBUG, ("udp_send: added header pbuf %p before given pbuf %p\n", (void *)q, (void *)p));
-  /* adding a header within p succeeded */
-  } else {
-    /* first pbuf q equals given pbuf */
-    q = p;
-    LWIP_DEBUGF(UDP_DEBUG, ("udp_send: added header in given pbuf %p\n", (void *)p));
-  }
-  /* { q now represents the packet to be sent } */
-  udphdr = q->payload;
-  udphdr->src = htons(pcb->local_port);
-  udphdr->dest = htons(pcb->remote_port);
-  /* in UDP, 0 checksum means 'no checksum' */
-  udphdr->chksum = 0x0000; 
-
-  /* PCB local address is IP_ANY_ADDR? */
-  if (ip_addr_isany(&pcb->local_ip)) {
-    /* use outgoing network interface IP address as source address */
-    src_ip = &(netif->ip_addr);
-  } else {
-    /* use UDP PCB local IP address as source address */
-    src_ip = &(pcb->local_ip);
-  }
-
-  LWIP_DEBUGF(UDP_DEBUG, ("udp_send: sending datagram of length %"U16_F"\n", q->tot_len));
-
-  /* UDP Lite protocol? */
-  if (pcb->flags & UDP_FLAGS_UDPLITE) {
-    LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP LITE packet length %"U16_F"\n", q->tot_len));
-    /* set UDP message length in UDP header */
-    udphdr->len = htons(pcb->chksum_len);
-    /* calculate checksum */
-#if CHECKSUM_GEN_UDP
-    udphdr->chksum = inet_chksum_pseudo(q, src_ip, &(pcb->remote_ip),
-          IP_PROTO_UDP, pcb->chksum_len);
-    /* chksum zero must become 0xffff, as zero means 'no checksum' */
-    if (udphdr->chksum == 0x0000) udphdr->chksum = 0xffff;
-#else
-    udphdr->chksum = 0x0000;
-#endif
-    /* output to IP */
-    LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,IP_PROTO_UDPLITE,)\n"));
-    err = ip_output_if (q, src_ip, &pcb->remote_ip, pcb->ttl, pcb->tos, IP_PROTO_UDPLITE, netif);    
-  /* UDP */
-  } else {
-    LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP packet length %"U16_F"\n", q->tot_len));
-    udphdr->len = htons(q->tot_len);
-    /* calculate checksum */
-#if CHECKSUM_GEN_UDP
-    if ((pcb->flags & UDP_FLAGS_NOCHKSUM) == 0) {
-      udphdr->chksum = inet_chksum_pseudo(q, src_ip, &pcb->remote_ip, IP_PROTO_UDP, q->tot_len);
-      /* chksum zero must become 0xffff, as zero means 'no checksum' */
-      if (udphdr->chksum == 0x0000) udphdr->chksum = 0xffff;
-    }
-#else
-    udphdr->chksum = 0x0000;
-#endif
-    LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP checksum 0x%04"X16_F"\n", udphdr->chksum));
-    LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,IP_PROTO_UDP,)\n"));
-    /* output to IP */
-    err = ip_output_if(q, src_ip, &pcb->remote_ip, pcb->ttl, pcb->tos, IP_PROTO_UDP, netif);    
-  }
-  /* TODO: must this be increased even if error occured? */
-  snmp_inc_udpoutdatagrams();
-
-  /* did we chain a seperate header pbuf earlier? */
-  if (q != p) {
-    /* free the header pbuf */
-    pbuf_free(q); q = NULL;
-    /* { p is still referenced by the caller, and will live on } */
-  }
-
-  UDP_STATS_INC(udp.xmit);
-  return err;
-}
-
-/**
- * Bind an UDP PCB.
- *
- * @param pcb UDP PCB to be bound with a local address ipaddr and port.
- * @param ipaddr local IP address to bind with. Use IP_ADDR_ANY to
- * bind to all local interfaces.
- * @param port local UDP port to bind with.
- *
- * @return lwIP error code.
- * - ERR_OK. Successful. No error occured.
- * - ERR_USE. The specified ipaddr and port are already bound to by
- * another UDP PCB.
- *
- * @see udp_disconnect()
- */
-err_t
-udp_bind(struct udp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
-{
-  struct udp_pcb *ipcb;
-  u8_t rebind;
-
-  LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | 3, ("udp_bind(ipaddr = "));
-  ip_addr_debug_print(UDP_DEBUG, ipaddr);
-  LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | 3, (", port = %"U16_F")\n", port));
-
-  rebind = 0;
-  /* Check for double bind and rebind of the same pcb */
-  for (ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) {
-    /* is this UDP PCB already on active list? */
-    if (pcb == ipcb) {
-      /* pcb may occur at most once in active list */
-      LWIP_ASSERT("rebind == 0", rebind == 0);
-      /* pcb already in list, just rebind */
-      rebind = 1;
-    }
-
-/* this code does not allow upper layer to share a UDP port for
-   listening to broadcast or multicast traffic (See SO_REUSE_ADDR and
-   SO_REUSE_PORT under *BSD). TODO: See where it fits instead, OR
-   combine with implementation of UDP PCB flags. Leon Woestenberg. */
-#ifdef LWIP_UDP_TODO
-    /* port matches that of PCB in list? */
-    else if ((ipcb->local_port == port) &&
-       /* IP address matches, or one is IP_ADDR_ANY? */
-       (ip_addr_isany(&(ipcb->local_ip)) ||
-       ip_addr_isany(ipaddr) ||
-       ip_addr_cmp(&(ipcb->local_ip), ipaddr))) {
-      /* other PCB already binds to this local IP and port */
-      LWIP_DEBUGF(UDP_DEBUG, ("udp_bind: local port %"U16_F" already bound by another pcb\n", port));
-      return ERR_USE;
-    }
-#endif
-
-  }
-
-  ip_addr_set(&pcb->local_ip, ipaddr);
-  /* 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
-#endif
-    port = UDP_LOCAL_PORT_RANGE_START;
-    ipcb = udp_pcbs;
-    while ((ipcb != NULL) && (port != UDP_LOCAL_PORT_RANGE_END)) {
-      if (ipcb->local_port == port) {
-        port++;
-        ipcb = udp_pcbs;
-      } else
-        ipcb = ipcb->next;
-    }
-    if (ipcb != NULL) {
-      /* no more ports available in local range */
-      LWIP_DEBUGF(UDP_DEBUG, ("udp_bind: out of free UDP ports\n"));
-      return ERR_USE;
-    }
-  }
-  pcb->local_port = port;
-  /* pcb not active yet? */
-  if (rebind == 0) {
-    /* place the PCB on the active list if not already there */
-    pcb->next = udp_pcbs;
-    udp_pcbs = pcb;
-  }
-  LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | DBG_STATE, ("udp_bind: bound to %"U16_F".%"U16_F".%"U16_F".%"U16_F", port %"U16_F"\n",
-   (u16_t)(ntohl(pcb->local_ip.addr) >> 24 & 0xff),
-   (u16_t)(ntohl(pcb->local_ip.addr) >> 16 & 0xff),
-   (u16_t)(ntohl(pcb->local_ip.addr) >> 8 & 0xff),
-   (u16_t)(ntohl(pcb->local_ip.addr) & 0xff), pcb->local_port));
-  return ERR_OK;
-}
-/**
- * Connect an UDP PCB.
- *
- * This will associate the UDP PCB with the remote address.
- *
- * @param pcb UDP PCB to be connected with remote address ipaddr and port.
- * @param ipaddr remote IP address to connect with.
- * @param port remote UDP port to connect with.
- *
- * @return lwIP error code
- *
- * @see udp_disconnect()
- */
-err_t
-udp_connect(struct udp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
-{
-  struct udp_pcb *ipcb;
-
-  if (pcb->local_port == 0) {
-    err_t err = udp_bind(pcb, &pcb->local_ip, pcb->local_port);
-    if (err != ERR_OK)
-      return err;
-  }
-
-  ip_addr_set(&pcb->remote_ip, ipaddr);
-  pcb->remote_port = port;
-  pcb->flags |= UDP_FLAGS_CONNECTED;
-/** TODO: this functionality belongs in upper layers */
-#ifdef LWIP_UDP_TODO
-  /* Nail down local IP for netconn_addr()/getsockname() */
-  if (ip_addr_isany(&pcb->local_ip) && !ip_addr_isany(&pcb->remote_ip)) {
-    struct netif *netif;
-
-    if ((netif = ip_route(&(pcb->remote_ip))) == NULL) {
-      LWIP_DEBUGF(UDP_DEBUG, ("udp_connect: No route to 0x%lx\n", pcb->remote_ip.addr));
-        UDP_STATS_INC(udp.rterr);
-      return ERR_RTE;
-    }
-    /** TODO: this will bind the udp pcb locally, to the interface which
-        is used to route output packets to the remote address. However, we
-        might want to accept incoming packets on any interface! */
-    pcb->local_ip = netif->ip_addr;
-  } else if (ip_addr_isany(&pcb->remote_ip)) {
-    pcb->local_ip.addr = 0;
-  }
-#endif
-  LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | DBG_STATE, ("udp_connect: connected to %"U16_F".%"U16_F".%"U16_F".%"U16_F",port %"U16_F"\n",
-   (u16_t)(ntohl(pcb->remote_ip.addr) >> 24 & 0xff),
-   (u16_t)(ntohl(pcb->remote_ip.addr) >> 16 & 0xff),
-   (u16_t)(ntohl(pcb->remote_ip.addr) >> 8 & 0xff),
-   (u16_t)(ntohl(pcb->remote_ip.addr) & 0xff), pcb->remote_port));
-
-  /* Insert UDP PCB into the list of active UDP PCBs. */
-  for(ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) {
-    if (pcb == ipcb) {
-      /* already on the list, just return */
-      return ERR_OK;
-    }
-  }
-  /* PCB not yet on the list, add PCB now */
-  pcb->next = udp_pcbs;
-  udp_pcbs = pcb;
-  return ERR_OK;
-}
-
-void
-udp_disconnect(struct udp_pcb *pcb)
-{
-  /* reset remote address association */
-  ip_addr_set(&pcb->remote_ip, IP_ADDR_ANY);
-  pcb->remote_port = 0;
-  /* mark PCB as unconnected */
-  pcb->flags &= ~UDP_FLAGS_CONNECTED;
-}
-
-void
-udp_recv(struct udp_pcb *pcb,
-   void (* recv)(void *arg, struct udp_pcb *upcb, struct pbuf *p,
-           struct ip_addr *addr, u16_t port),
-   void *recv_arg)
-{
-  /* remember recv() callback and user data */
-  pcb->recv = recv;
-  pcb->recv_arg = recv_arg;
-}
-/**
- * Remove an UDP PCB.
- *
- * @param pcb UDP PCB to be removed. The PCB is removed from the list of
- * UDP PCB's and the data structure is freed from memory.
- *
- * @see udp_new()
- */
-void
-udp_remove(struct udp_pcb *pcb)
-{
-  struct udp_pcb *pcb2;
-  /* pcb to be removed is first in list? */
-  if (udp_pcbs == pcb) {
-    /* make list start at 2nd pcb */
-    udp_pcbs = udp_pcbs->next;
-  /* pcb not 1st in list */
-  } else for(pcb2 = udp_pcbs; pcb2 != NULL; pcb2 = pcb2->next) {
-    /* find pcb in udp_pcbs list */
-    if (pcb2->next != NULL && pcb2->next == pcb) {
-      /* remove pcb from list */
-      pcb2->next = pcb->next;
-    }
-  }
-  memp_free(MEMP_UDP_PCB, pcb);
-}
-/**
- * Create a UDP PCB.
- *
- * @return The UDP PCB which was created. NULL if the PCB data structure
- * could not be allocated.
- *
- * @see udp_remove()
- */
-struct udp_pcb *
-udp_new(void) {
-  struct udp_pcb *pcb;
-  pcb = memp_malloc(MEMP_UDP_PCB);
-  /* could allocate UDP PCB? */
-  if (pcb != NULL) {
-    /* initialize PCB to all zeroes */
-    memset(pcb, 0, sizeof(struct udp_pcb));
-    pcb->ttl = UDP_TTL;
-  }
-  
-  
-  return pcb;
-}
-
-#if UDP_DEBUG
-void
-udp_debug_print(struct udp_hdr *udphdr)
-{
-  LWIP_DEBUGF(UDP_DEBUG, ("UDP header:\n"));
-  LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n"));
-  LWIP_DEBUGF(UDP_DEBUG, ("|     %5"U16_F"     |     %5"U16_F"     | (src port, dest port)\n",
-         ntohs(udphdr->src), ntohs(udphdr->dest)));
-  LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n"));
-  LWIP_DEBUGF(UDP_DEBUG, ("|     %5"U16_F"     |     0x%04"X16_F"    | (len, chksum)\n",
-         ntohs(udphdr->len), ntohs(udphdr->chksum)));
-  LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n"));
-}
-#endif /* UDP_DEBUG */
-
-#endif /* LWIP_UDP */
-
-
-
-
-
-
-
-
-
+/**\r
+ * @file\r
+ * User Datagram Protocol module\r
+ *\r
+ */\r
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without modification,\r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED\r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT\r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY\r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ *\r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+\r
+\r
+/* udp.c\r
+ *\r
+ * The code for the User Datagram Protocol UDP.\r
+ *\r
+ */\r
+\r
+#include <string.h>\r
+\r
+#include "lwip/opt.h"\r
+\r
+#include "lwip/def.h"\r
+#include "lwip/memp.h"\r
+#include "lwip/inet.h"\r
+#include "lwip/ip_addr.h"\r
+#include "lwip/netif.h"\r
+#include "lwip/udp.h"\r
+#include "lwip/icmp.h"\r
+\r
+#include "lwip/stats.h"\r
+\r
+#include "arch/perf.h"\r
+#include "lwip/snmp.h"\r
+\r
+/* The list of UDP PCBs */\r
+#if LWIP_UDP\r
+/* was static, but we may want to access this from a socket layer */\r
+struct udp_pcb *udp_pcbs = NULL;\r
+\r
+static struct udp_pcb *pcb_cache = NULL;\r
+\r
+void\r
+udp_init(void)\r
+{\r
+  udp_pcbs = pcb_cache = NULL;\r
+}\r
+\r
+/**\r
+ * Process an incoming UDP datagram.\r
+ *\r
+ * Given an incoming UDP datagram (as a chain of pbufs) this function\r
+ * finds a corresponding UDP PCB and\r
+ *\r
+ * @param pbuf pbuf to be demultiplexed to a UDP PCB.\r
+ * @param netif network interface on which the datagram was received.\r
+ *\r
+ */\r
+void\r
+udp_input(struct pbuf *p, struct netif *inp)\r
+{\r
+  struct udp_hdr *udphdr;\r
+  struct udp_pcb *pcb;\r
+  struct udp_pcb *uncon_pcb;\r
+  struct ip_hdr *iphdr;\r
+  u16_t src, dest;\r
+  u8_t local_match;\r
+\r
+  PERF_START;\r
+\r
+  UDP_STATS_INC(udp.recv);\r
+\r
+  iphdr = p->payload;\r
+\r
+  if (pbuf_header(p, -((s16_t)(UDP_HLEN + IPH_HL(iphdr) * 4)))) {\r
+    /* drop short packets */\r
+    LWIP_DEBUGF(UDP_DEBUG, ("udp_input: short UDP datagram (%"U16_F" bytes) discarded\n", p->tot_len));\r
+    UDP_STATS_INC(udp.lenerr);\r
+    UDP_STATS_INC(udp.drop);\r
+    snmp_inc_udpinerrors();\r
+    pbuf_free(p);\r
+    goto end;\r
+  }\r
+\r
+  udphdr = (struct udp_hdr *)((u8_t *)p->payload - UDP_HLEN);\r
+\r
+  LWIP_DEBUGF(UDP_DEBUG, ("udp_input: received datagram of length %"U16_F"\n", p->tot_len));\r
+\r
+  src = ntohs(udphdr->src);\r
+  dest = ntohs(udphdr->dest);\r
+\r
+  udp_debug_print(udphdr);\r
+\r
+  /* print the UDP source and destination */\r
+  LWIP_DEBUGF(UDP_DEBUG, ("udp (%"U16_F".%"U16_F".%"U16_F".%"U16_F", %"U16_F") <-- (%"U16_F".%"U16_F".%"U16_F".%"U16_F", %"U16_F")\n",\r
+    ip4_addr1(&iphdr->dest), ip4_addr2(&iphdr->dest),\r
+    ip4_addr3(&iphdr->dest), ip4_addr4(&iphdr->dest), ntohs(udphdr->dest),\r
+    ip4_addr1(&iphdr->src), ip4_addr2(&iphdr->src),\r
+    ip4_addr3(&iphdr->src), ip4_addr4(&iphdr->src), ntohs(udphdr->src)));\r
+\r
+  local_match = 0;\r
+  uncon_pcb = NULL;\r
+  /* Iterate through the UDP pcb list for a matching pcb */\r
+  for (pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) {\r
+    /* print the PCB local and remote address */\r
+    LWIP_DEBUGF(UDP_DEBUG, ("pcb (%"U16_F".%"U16_F".%"U16_F".%"U16_F", %"U16_F") --- (%"U16_F".%"U16_F".%"U16_F".%"U16_F", %"U16_F")\n",\r
+      ip4_addr1(&pcb->local_ip), ip4_addr2(&pcb->local_ip),\r
+      ip4_addr3(&pcb->local_ip), ip4_addr4(&pcb->local_ip), pcb->local_port,\r
+      ip4_addr1(&pcb->remote_ip), ip4_addr2(&pcb->remote_ip),\r
+      ip4_addr3(&pcb->remote_ip), ip4_addr4(&pcb->remote_ip), pcb->remote_port));\r
+\r
+    /* compare PCB local addr+port to UDP destination addr+port */\r
+    if ((pcb->local_port == dest) &&\r
+       (ip_addr_isany(&pcb->local_ip) ||\r
+        ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest)))) {\r
+       local_match = 1;\r
+       if ((uncon_pcb == NULL) && \r
+           ((pcb->flags & UDP_FLAGS_CONNECTED) == 0)) {\r
+         /* the first unconnected matching PCB */     \r
+         uncon_pcb = pcb;\r
+       }\r
+    }\r
+    /* compare PCB remote addr+port to UDP source addr+port */\r
+    if ((local_match != 0) &&\r
+       (pcb->remote_port == src) &&\r
+       (ip_addr_isany(&pcb->remote_ip) ||\r
+       ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src)))) {\r
+       /* the first fully matching PCB */\r
+      break;\r
+    }\r
+  }\r
+  /* no fully matching pcb found? then look for an unconnected pcb */\r
+  if (pcb == NULL) {\r
+    pcb = uncon_pcb;\r
+  }\r
+\r
+  /* Check checksum if this is a match or if it was directed at us. */\r
+  if (pcb != NULL  || ip_addr_cmp(&inp->ip_addr, &iphdr->dest))\r
+    {\r
+    LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE, ("udp_input: calculating checksum\n"));\r
+    pbuf_header(p, UDP_HLEN);\r
+#ifdef IPv6\r
+    if (iphdr->nexthdr == IP_PROTO_UDPLITE) {\r
+#else\r
+    if (IPH_PROTO(iphdr) == IP_PROTO_UDPLITE) {\r
+#endif /* IPv4 */\r
+      /* Do the UDP Lite checksum */\r
+#if CHECKSUM_CHECK_UDP\r
+      if (inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src),\r
+         (struct ip_addr *)&(iphdr->dest),\r
+         IP_PROTO_UDPLITE, ntohs(udphdr->len)) != 0) {\r
+  LWIP_DEBUGF(UDP_DEBUG | 2, ("udp_input: UDP Lite datagram discarded due to failing checksum\n"));\r
+  UDP_STATS_INC(udp.chkerr);\r
+  UDP_STATS_INC(udp.drop);\r
+  snmp_inc_udpinerrors();\r
+  pbuf_free(p);\r
+  goto end;\r
+      }\r
+#endif\r
+    } else {\r
+#if CHECKSUM_CHECK_UDP\r
+      if (udphdr->chksum != 0) {\r
+  if (inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src),\r
+       (struct ip_addr *)&(iphdr->dest),\r
+        IP_PROTO_UDP, p->tot_len) != 0) {\r
+    LWIP_DEBUGF(UDP_DEBUG | 2, ("udp_input: UDP datagram discarded due to failing checksum\n"));\r
+\r
+    UDP_STATS_INC(udp.chkerr);\r
+    UDP_STATS_INC(udp.drop);\r
+    snmp_inc_udpinerrors();\r
+    pbuf_free(p);\r
+    goto end;\r
+  }\r
+      }\r
+#endif\r
+    }\r
+    pbuf_header(p, -UDP_HLEN);\r
+    if (pcb != NULL) {\r
+      snmp_inc_udpindatagrams();\r
+      /* callback */\r
+      if (pcb->recv != NULL)\r
+      {\r
+        pcb->recv(pcb->recv_arg, pcb, p, &(iphdr->src), src);\r
+      }\r
+        } else {\r
+      LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE, ("udp_input: not for us.\n"));\r
+\r
+      /* No match was found, send ICMP destination port unreachable unless\r
+      destination address was broadcast/multicast. */\r
+\r
+      if (!ip_addr_isbroadcast(&iphdr->dest, inp) &&\r
+          !ip_addr_ismulticast(&iphdr->dest)) {\r
+\r
+  /* adjust pbuf pointer */\r
+  p->payload = iphdr;\r
+  icmp_dest_unreach(p, ICMP_DUR_PORT);\r
+      }\r
+      UDP_STATS_INC(udp.proterr);\r
+      UDP_STATS_INC(udp.drop);\r
+    snmp_inc_udpnoports();\r
+      pbuf_free(p);\r
+    }\r
+  } else {\r
+    pbuf_free(p);\r
+  }\r
+  end:\r
+\r
+  PERF_STOP("udp_input");\r
+}\r
+\r
+/**\r
+ * Send data to a specified address using UDP.\r
+ *\r
+ * @param pcb UDP PCB used to send the data.\r
+ * @param pbuf chain of pbuf's to be sent.\r
+ * @param dst_ip Destination IP address.\r
+ * @param dst_port Destination UDP port.\r
+ *\r
+ * If the PCB already has a remote address association, it will\r
+ * be restored after the data is sent.\r
+ * \r
+ * @return lwIP error code.\r
+ * - ERR_OK. Successful. No error occured.\r
+ * - ERR_MEM. Out of memory.\r
+ * - ERR_RTE. Could not find route to destination address.\r
+ *\r
+ * @see udp_disconnect() udp_send()\r
+ */\r
+err_t\r
+udp_sendto(struct udp_pcb *pcb, struct pbuf *p,\r
+  struct ip_addr *dst_ip, u16_t dst_port)\r
+{\r
+  err_t err;\r
+  /* temporary space for current PCB remote address */\r
+  struct ip_addr pcb_remote_ip;\r
+  u16_t pcb_remote_port;\r
+  /* remember current remote peer address of PCB */\r
+  pcb_remote_ip.addr = pcb->remote_ip.addr;\r
+  pcb_remote_port = pcb->remote_port;\r
+  /* copy packet destination address to PCB remote peer address */\r
+  pcb->remote_ip.addr = dst_ip->addr;\r
+  pcb->remote_port = dst_port;\r
+  /* send to the packet destination address */\r
+  err = udp_send(pcb, p);\r
+  /* restore PCB remote peer address */\r
+  pcb->remote_ip.addr = pcb_remote_ip.addr;\r
+  pcb->remote_port = pcb_remote_port;\r
+  return err;\r
+}\r
+\r
+/**\r
+ * Send data using UDP.\r
+ *\r
+ * @param pcb UDP PCB used to send the data.\r
+ * @param pbuf chain of pbuf's to be sent.\r
+ *\r
+ * @return lwIP error code.\r
+ * - ERR_OK. Successful. No error occured.\r
+ * - ERR_MEM. Out of memory.\r
+ * - ERR_RTE. Could not find route to destination address.\r
+ *\r
+ * @see udp_disconnect() udp_sendto()\r
+ */\r
+err_t\r
+udp_send(struct udp_pcb *pcb, struct pbuf *p)\r
+{\r
+  struct udp_hdr *udphdr;\r
+  struct netif *netif;\r
+  struct ip_addr *src_ip;\r
+  err_t err;\r
+  struct pbuf *q; /* q will be sent down the stack */\r
+\r
+  LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | 3, ("udp_send\n"));\r
+\r
+  /* if the PCB is not yet bound to a port, bind it here */\r
+  if (pcb->local_port == 0) {\r
+    LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | 2, ("udp_send: not yet bound to a port, binding now\n"));\r
+    err = udp_bind(pcb, &pcb->local_ip, pcb->local_port);\r
+    if (err != ERR_OK) {\r
+      LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | 2, ("udp_send: forced port bind failed\n"));\r
+      return err;\r
+    }\r
+  }\r
+  /* find the outgoing network interface for this packet */\r
+  netif = ip_route(&(pcb->remote_ip));\r
+  /* no outgoing network interface could be found? */\r
+  if (netif == NULL) {\r
+    LWIP_DEBUGF(UDP_DEBUG | 1, ("udp_send: No route to 0x%"X32_F"\n", pcb->remote_ip.addr));\r
+    UDP_STATS_INC(udp.rterr);\r
+    return ERR_RTE;\r
+  }\r
+\r
+  /* not enough space to add an UDP header to first pbuf in given p chain? */\r
+  if (pbuf_header(p, UDP_HLEN)) {\r
+    /* allocate header in a seperate new pbuf */\r
+    q = pbuf_alloc(PBUF_IP, UDP_HLEN, PBUF_RAM);\r
+    /* new header pbuf could not be allocated? */\r
+    if (q == NULL) {\r
+      LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | 2, ("udp_send: could not allocate header\n"));\r
+      return ERR_MEM;\r
+    }\r
+    /* chain header q in front of given pbuf p */\r
+    pbuf_chain(q, p);\r
+    /* { first pbuf q points to header pbuf } */\r
+    LWIP_DEBUGF(UDP_DEBUG, ("udp_send: added header pbuf %p before given pbuf %p\n", (void *)q, (void *)p));\r
+  /* adding a header within p succeeded */\r
+  } else {\r
+    /* first pbuf q equals given pbuf */\r
+    q = p;\r
+    LWIP_DEBUGF(UDP_DEBUG, ("udp_send: added header in given pbuf %p\n", (void *)p));\r
+  }\r
+  /* { q now represents the packet to be sent } */\r
+  udphdr = q->payload;\r
+  udphdr->src = htons(pcb->local_port);\r
+  udphdr->dest = htons(pcb->remote_port);\r
+  /* in UDP, 0 checksum means 'no checksum' */\r
+  udphdr->chksum = 0x0000; \r
+\r
+  /* PCB local address is IP_ANY_ADDR? */\r
+  if (ip_addr_isany(&pcb->local_ip)) {\r
+    /* use outgoing network interface IP address as source address */\r
+    src_ip = &(netif->ip_addr);\r
+  } else {\r
+    /* use UDP PCB local IP address as source address */\r
+    src_ip = &(pcb->local_ip);\r
+  }\r
+\r
+  LWIP_DEBUGF(UDP_DEBUG, ("udp_send: sending datagram of length %"U16_F"\n", q->tot_len));\r
+\r
+  /* UDP Lite protocol? */\r
+  if (pcb->flags & UDP_FLAGS_UDPLITE) {\r
+    LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP LITE packet length %"U16_F"\n", q->tot_len));\r
+    /* set UDP message length in UDP header */\r
+    udphdr->len = htons(pcb->chksum_len);\r
+    /* calculate checksum */\r
+#if CHECKSUM_GEN_UDP\r
+    udphdr->chksum = inet_chksum_pseudo(q, src_ip, &(pcb->remote_ip),\r
+          IP_PROTO_UDP, pcb->chksum_len);\r
+    /* chksum zero must become 0xffff, as zero means 'no checksum' */\r
+    if (udphdr->chksum == 0x0000) udphdr->chksum = 0xffff;\r
+#else\r
+    udphdr->chksum = 0x0000;\r
+#endif\r
+    /* output to IP */\r
+    LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,IP_PROTO_UDPLITE,)\n"));\r
+    err = ip_output_if (q, src_ip, &pcb->remote_ip, pcb->ttl, pcb->tos, IP_PROTO_UDPLITE, netif);    \r
+  /* UDP */\r
+  } else {\r
+    LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP packet length %"U16_F"\n", q->tot_len));\r
+    udphdr->len = htons(q->tot_len);\r
+    /* calculate checksum */\r
+#if CHECKSUM_GEN_UDP\r
+    if ((pcb->flags & UDP_FLAGS_NOCHKSUM) == 0) {\r
+      udphdr->chksum = inet_chksum_pseudo(q, src_ip, &pcb->remote_ip, IP_PROTO_UDP, q->tot_len);\r
+      /* chksum zero must become 0xffff, as zero means 'no checksum' */\r
+      if (udphdr->chksum == 0x0000) udphdr->chksum = 0xffff;\r
+    }\r
+#else\r
+    udphdr->chksum = 0x0000;\r
+#endif\r
+    LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP checksum 0x%04"X16_F"\n", udphdr->chksum));\r
+    LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,IP_PROTO_UDP,)\n"));\r
+    /* output to IP */\r
+    err = ip_output_if(q, src_ip, &pcb->remote_ip, pcb->ttl, pcb->tos, IP_PROTO_UDP, netif);    \r
+  }\r
+  /* TODO: must this be increased even if error occured? */\r
+  snmp_inc_udpoutdatagrams();\r
+\r
+  /* did we chain a seperate header pbuf earlier? */\r
+  if (q != p) {\r
+    /* free the header pbuf */\r
+    pbuf_free(q); q = NULL;\r
+    /* { p is still referenced by the caller, and will live on } */\r
+  }\r
+\r
+  UDP_STATS_INC(udp.xmit);\r
+  return err;\r
+}\r
+\r
+/**\r
+ * Bind an UDP PCB.\r
+ *\r
+ * @param pcb UDP PCB to be bound with a local address ipaddr and port.\r
+ * @param ipaddr local IP address to bind with. Use IP_ADDR_ANY to\r
+ * bind to all local interfaces.\r
+ * @param port local UDP port to bind with.\r
+ *\r
+ * @return lwIP error code.\r
+ * - ERR_OK. Successful. No error occured.\r
+ * - ERR_USE. The specified ipaddr and port are already bound to by\r
+ * another UDP PCB.\r
+ *\r
+ * @see udp_disconnect()\r
+ */\r
+err_t\r
+udp_bind(struct udp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)\r
+{\r
+  struct udp_pcb *ipcb;\r
+  u8_t rebind;\r
+\r
+  LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | 3, ("udp_bind(ipaddr = "));\r
+  ip_addr_debug_print(UDP_DEBUG, ipaddr);\r
+  LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | 3, (", port = %"U16_F")\n", port));\r
+\r
+  rebind = 0;\r
+  /* Check for double bind and rebind of the same pcb */\r
+  for (ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) {\r
+    /* is this UDP PCB already on active list? */\r
+    if (pcb == ipcb) {\r
+      /* pcb may occur at most once in active list */\r
+      LWIP_ASSERT("rebind == 0", rebind == 0);\r
+      /* pcb already in list, just rebind */\r
+      rebind = 1;\r
+    }\r
+\r
+/* this code does not allow upper layer to share a UDP port for\r
+   listening to broadcast or multicast traffic (See SO_REUSE_ADDR and\r
+   SO_REUSE_PORT under *BSD). TODO: See where it fits instead, OR\r
+   combine with implementation of UDP PCB flags. Leon Woestenberg. */\r
+#ifdef LWIP_UDP_TODO\r
+    /* port matches that of PCB in list? */\r
+    else if ((ipcb->local_port == port) &&\r
+       /* IP address matches, or one is IP_ADDR_ANY? */\r
+       (ip_addr_isany(&(ipcb->local_ip)) ||\r
+       ip_addr_isany(ipaddr) ||\r
+       ip_addr_cmp(&(ipcb->local_ip), ipaddr))) {\r
+      /* other PCB already binds to this local IP and port */\r
+      LWIP_DEBUGF(UDP_DEBUG, ("udp_bind: local port %"U16_F" already bound by another pcb\n", port));\r
+      return ERR_USE;\r
+    }\r
+#endif\r
+\r
+  }\r
+\r
+  ip_addr_set(&pcb->local_ip, ipaddr);\r
+  /* no port specified? */\r
+  if (port == 0) {\r
+#ifndef UDP_LOCAL_PORT_RANGE_START\r
+#define UDP_LOCAL_PORT_RANGE_START 4096\r
+#define UDP_LOCAL_PORT_RANGE_END   0x7fff\r
+#endif\r
+    port = UDP_LOCAL_PORT_RANGE_START;\r
+    ipcb = udp_pcbs;\r
+    while ((ipcb != NULL) && (port != UDP_LOCAL_PORT_RANGE_END)) {\r
+      if (ipcb->local_port == port) {\r
+        port++;\r
+        ipcb = udp_pcbs;\r
+      } else\r
+        ipcb = ipcb->next;\r
+    }\r
+    if (ipcb != NULL) {\r
+      /* no more ports available in local range */\r
+      LWIP_DEBUGF(UDP_DEBUG, ("udp_bind: out of free UDP ports\n"));\r
+      return ERR_USE;\r
+    }\r
+  }\r
+  pcb->local_port = port;\r
+  /* pcb not active yet? */\r
+  if (rebind == 0) {\r
+    /* place the PCB on the active list if not already there */\r
+    pcb->next = udp_pcbs;\r
+    udp_pcbs = pcb;\r
+  }\r
+  LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | DBG_STATE, ("udp_bind: bound to %"U16_F".%"U16_F".%"U16_F".%"U16_F", port %"U16_F"\n",\r
+   (u16_t)(ntohl(pcb->local_ip.addr) >> 24 & 0xff),\r
+   (u16_t)(ntohl(pcb->local_ip.addr) >> 16 & 0xff),\r
+   (u16_t)(ntohl(pcb->local_ip.addr) >> 8 & 0xff),\r
+   (u16_t)(ntohl(pcb->local_ip.addr) & 0xff), pcb->local_port));\r
+  return ERR_OK;\r
+}\r
+/**\r
+ * Connect an UDP PCB.\r
+ *\r
+ * This will associate the UDP PCB with the remote address.\r
+ *\r
+ * @param pcb UDP PCB to be connected with remote address ipaddr and port.\r
+ * @param ipaddr remote IP address to connect with.\r
+ * @param port remote UDP port to connect with.\r
+ *\r
+ * @return lwIP error code\r
+ *\r
+ * @see udp_disconnect()\r
+ */\r
+err_t\r
+udp_connect(struct udp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)\r
+{\r
+  struct udp_pcb *ipcb;\r
+\r
+  if (pcb->local_port == 0) {\r
+    err_t err = udp_bind(pcb, &pcb->local_ip, pcb->local_port);\r
+    if (err != ERR_OK)\r
+      return err;\r
+  }\r
+\r
+  ip_addr_set(&pcb->remote_ip, ipaddr);\r
+  pcb->remote_port = port;\r
+  pcb->flags |= UDP_FLAGS_CONNECTED;\r
+/** TODO: this functionality belongs in upper layers */\r
+#ifdef LWIP_UDP_TODO\r
+  /* Nail down local IP for netconn_addr()/getsockname() */\r
+  if (ip_addr_isany(&pcb->local_ip) && !ip_addr_isany(&pcb->remote_ip)) {\r
+    struct netif *netif;\r
+\r
+    if ((netif = ip_route(&(pcb->remote_ip))) == NULL) {\r
+      LWIP_DEBUGF(UDP_DEBUG, ("udp_connect: No route to 0x%lx\n", pcb->remote_ip.addr));\r
+        UDP_STATS_INC(udp.rterr);\r
+      return ERR_RTE;\r
+    }\r
+    /** TODO: this will bind the udp pcb locally, to the interface which\r
+        is used to route output packets to the remote address. However, we\r
+        might want to accept incoming packets on any interface! */\r
+    pcb->local_ip = netif->ip_addr;\r
+  } else if (ip_addr_isany(&pcb->remote_ip)) {\r
+    pcb->local_ip.addr = 0;\r
+  }\r
+#endif\r
+  LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | DBG_STATE, ("udp_connect: connected to %"U16_F".%"U16_F".%"U16_F".%"U16_F",port %"U16_F"\n",\r
+   (u16_t)(ntohl(pcb->remote_ip.addr) >> 24 & 0xff),\r
+   (u16_t)(ntohl(pcb->remote_ip.addr) >> 16 & 0xff),\r
+   (u16_t)(ntohl(pcb->remote_ip.addr) >> 8 & 0xff),\r
+   (u16_t)(ntohl(pcb->remote_ip.addr) & 0xff), pcb->remote_port));\r
+\r
+  /* Insert UDP PCB into the list of active UDP PCBs. */\r
+  for(ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) {\r
+    if (pcb == ipcb) {\r
+      /* already on the list, just return */\r
+      return ERR_OK;\r
+    }\r
+  }\r
+  /* PCB not yet on the list, add PCB now */\r
+  pcb->next = udp_pcbs;\r
+  udp_pcbs = pcb;\r
+  return ERR_OK;\r
+}\r
+\r
+void\r
+udp_disconnect(struct udp_pcb *pcb)\r
+{\r
+  /* reset remote address association */\r
+  ip_addr_set(&pcb->remote_ip, IP_ADDR_ANY);\r
+  pcb->remote_port = 0;\r
+  /* mark PCB as unconnected */\r
+  pcb->flags &= ~UDP_FLAGS_CONNECTED;\r
+}\r
+\r
+void\r
+udp_recv(struct udp_pcb *pcb,\r
+   void (* recv)(void *arg, struct udp_pcb *upcb, struct pbuf *p,\r
+           struct ip_addr *addr, u16_t port),\r
+   void *recv_arg)\r
+{\r
+  /* remember recv() callback and user data */\r
+  pcb->recv = recv;\r
+  pcb->recv_arg = recv_arg;\r
+}\r
+/**\r
+ * Remove an UDP PCB.\r
+ *\r
+ * @param pcb UDP PCB to be removed. The PCB is removed from the list of\r
+ * UDP PCB's and the data structure is freed from memory.\r
+ *\r
+ * @see udp_new()\r
+ */\r
+void\r
+udp_remove(struct udp_pcb *pcb)\r
+{\r
+  struct udp_pcb *pcb2;\r
+  /* pcb to be removed is first in list? */\r
+  if (udp_pcbs == pcb) {\r
+    /* make list start at 2nd pcb */\r
+    udp_pcbs = udp_pcbs->next;\r
+  /* pcb not 1st in list */\r
+  } else for(pcb2 = udp_pcbs; pcb2 != NULL; pcb2 = pcb2->next) {\r
+    /* find pcb in udp_pcbs list */\r
+    if (pcb2->next != NULL && pcb2->next == pcb) {\r
+      /* remove pcb from list */\r
+      pcb2->next = pcb->next;\r
+    }\r
+  }\r
+  memp_free(MEMP_UDP_PCB, pcb);\r
+}\r
+/**\r
+ * Create a UDP PCB.\r
+ *\r
+ * @return The UDP PCB which was created. NULL if the PCB data structure\r
+ * could not be allocated.\r
+ *\r
+ * @see udp_remove()\r
+ */\r
+struct udp_pcb *\r
+udp_new(void) {\r
+  struct udp_pcb *pcb;\r
+  pcb = memp_malloc(MEMP_UDP_PCB);\r
+  /* could allocate UDP PCB? */\r
+  if (pcb != NULL) {\r
+    /* initialize PCB to all zeroes */\r
+    memset(pcb, 0, sizeof(struct udp_pcb));\r
+    pcb->ttl = UDP_TTL;\r
+  }\r
+  \r
+  \r
+  return pcb;\r
+}\r
+\r
+#if UDP_DEBUG\r
+void\r
+udp_debug_print(struct udp_hdr *udphdr)\r
+{\r
+  LWIP_DEBUGF(UDP_DEBUG, ("UDP header:\n"));\r
+  LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n"));\r
+  LWIP_DEBUGF(UDP_DEBUG, ("|     %5"U16_F"     |     %5"U16_F"     | (src port, dest port)\n",\r
+         ntohs(udphdr->src), ntohs(udphdr->dest)));\r
+  LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n"));\r
+  LWIP_DEBUGF(UDP_DEBUG, ("|     %5"U16_F"     |     0x%04"X16_F"    | (len, chksum)\n",\r
+         ntohs(udphdr->len), ntohs(udphdr->chksum)));\r
+  LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n"));\r
+}\r
+#endif /* UDP_DEBUG */\r
+\r
+#endif /* LWIP_UDP */\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
index 634405b714f1f6465a4991386bf2344af12adddd..04307e7432baffa337e9ae6b0741ae1145a8c084 100644 (file)
-/*
- * 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 <adam@sics.se>
- *
- */
-#ifndef __LWIP_ICMP_H__
-#define __LWIP_ICMP_H__
-
-#include "lwip/arch.h"
-
-#include "lwip/opt.h"
-#include "lwip/pbuf.h"
-
-#include "lwip/ip_addr.h"
-#include "lwip/netif.h"
-
-#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_TSR 14    /* timestamp reply */
-#define ICMP_IRQ 15    /* information request */
-#define ICMP_IR 16     /* information reply */
-
-enum icmp_dur_type {
-  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 */
-};
-
-enum icmp_te_type {
-  ICMP_TE_TTL = 0,     /* time to live exceeded in transit */
-  ICMP_TE_FRAG = 1     /* fragment reassembly time exceeded */
-};
-
-void icmp_input(struct pbuf *p, struct netif *inp);
-
-void icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t);
-void icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t);
-
-#ifdef PACK_STRUCT_USE_INCLUDES
-#  include "arch/bpstruct.h"
-#endif
-PACK_STRUCT_BEGIN
-struct icmp_echo_hdr {
-  PACK_STRUCT_FIELD(u16_t _type_code);
-  PACK_STRUCT_FIELD(u16_t chksum);
-  PACK_STRUCT_FIELD(u16_t id);
-  PACK_STRUCT_FIELD(u16_t seqno);
-} PACK_STRUCT_STRUCT;
-PACK_STRUCT_END
-
-PACK_STRUCT_BEGIN
-struct icmp_dur_hdr {
-  PACK_STRUCT_FIELD(u16_t _type_code);
-  PACK_STRUCT_FIELD(u16_t chksum);
-  PACK_STRUCT_FIELD(u32_t unused);
-} PACK_STRUCT_STRUCT;
-PACK_STRUCT_END
-
-PACK_STRUCT_BEGIN
-struct icmp_te_hdr {
-  PACK_STRUCT_FIELD(u16_t _type_code);
-  PACK_STRUCT_FIELD(u16_t chksum);
-  PACK_STRUCT_FIELD(u32_t unused);
-} PACK_STRUCT_STRUCT;
-PACK_STRUCT_END
-#ifdef PACK_STRUCT_USE_INCLUDES
-#  include "arch/epstruct.h"
-#endif
-
-#define ICMPH_TYPE(hdr) (ntohs((hdr)->_type_code) >> 8)
-#define ICMPH_CODE(hdr) (ntohs((hdr)->_type_code) & 0xff)
-
-#define ICMPH_TYPE_SET(hdr, type) ((hdr)->_type_code = htons(ICMPH_CODE(hdr) | ((type) << 8)))
-#define ICMPH_CODE_SET(hdr, code) ((hdr)->_type_code = htons((code) | (ICMPH_TYPE(hdr) << 8)))
-
-#endif /* __LWIP_ICMP_H__ */
-    
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+#ifndef __LWIP_ICMP_H__\r
+#define __LWIP_ICMP_H__\r
+\r
+#include "lwip/arch.h"\r
+\r
+#include "lwip/opt.h"\r
+#include "lwip/pbuf.h"\r
+\r
+#include "lwip/ip_addr.h"\r
+#include "lwip/netif.h"\r
+\r
+#define ICMP_ER 0      /* echo reply */\r
+#define ICMP_DUR 3     /* destination unreachable */\r
+#define ICMP_SQ 4      /* source quench */\r
+#define ICMP_RD 5      /* redirect */\r
+#define ICMP_ECHO 8    /* echo */\r
+#define ICMP_TE 11     /* time exceeded */\r
+#define ICMP_PP 12     /* parameter problem */\r
+#define ICMP_TS 13     /* timestamp */\r
+#define ICMP_TSR 14    /* timestamp reply */\r
+#define ICMP_IRQ 15    /* information request */\r
+#define ICMP_IR 16     /* information reply */\r
+\r
+enum icmp_dur_type {\r
+  ICMP_DUR_NET = 0,    /* net unreachable */\r
+  ICMP_DUR_HOST = 1,   /* host unreachable */\r
+  ICMP_DUR_PROTO = 2,  /* protocol unreachable */\r
+  ICMP_DUR_PORT = 3,   /* port unreachable */\r
+  ICMP_DUR_FRAG = 4,   /* fragmentation needed and DF set */\r
+  ICMP_DUR_SR = 5      /* source route failed */\r
+};\r
+\r
+enum icmp_te_type {\r
+  ICMP_TE_TTL = 0,     /* time to live exceeded in transit */\r
+  ICMP_TE_FRAG = 1     /* fragment reassembly time exceeded */\r
+};\r
+\r
+void icmp_input(struct pbuf *p, struct netif *inp);\r
+\r
+void icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t);\r
+void icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t);\r
+\r
+#ifdef PACK_STRUCT_USE_INCLUDES\r
+#  include "arch/bpstruct.h"\r
+#endif\r
+PACK_STRUCT_BEGIN\r
+struct icmp_echo_hdr {\r
+  PACK_STRUCT_FIELD(u16_t _type_code);\r
+  PACK_STRUCT_FIELD(u16_t chksum);\r
+  PACK_STRUCT_FIELD(u16_t id);\r
+  PACK_STRUCT_FIELD(u16_t seqno);\r
+} PACK_STRUCT_STRUCT;\r
+PACK_STRUCT_END\r
+\r
+PACK_STRUCT_BEGIN\r
+struct icmp_dur_hdr {\r
+  PACK_STRUCT_FIELD(u16_t _type_code);\r
+  PACK_STRUCT_FIELD(u16_t chksum);\r
+  PACK_STRUCT_FIELD(u32_t unused);\r
+} PACK_STRUCT_STRUCT;\r
+PACK_STRUCT_END\r
+\r
+PACK_STRUCT_BEGIN\r
+struct icmp_te_hdr {\r
+  PACK_STRUCT_FIELD(u16_t _type_code);\r
+  PACK_STRUCT_FIELD(u16_t chksum);\r
+  PACK_STRUCT_FIELD(u32_t unused);\r
+} PACK_STRUCT_STRUCT;\r
+PACK_STRUCT_END\r
+#ifdef PACK_STRUCT_USE_INCLUDES\r
+#  include "arch/epstruct.h"\r
+#endif\r
+\r
+#define ICMPH_TYPE(hdr) (ntohs((hdr)->_type_code) >> 8)\r
+#define ICMPH_CODE(hdr) (ntohs((hdr)->_type_code) & 0xff)\r
+\r
+#define ICMPH_TYPE_SET(hdr, type) ((hdr)->_type_code = htons(ICMPH_CODE(hdr) | ((type) << 8)))\r
+#define ICMPH_CODE_SET(hdr, code) ((hdr)->_type_code = htons((code) | (ICMPH_TYPE(hdr) << 8)))\r
+\r
+#endif /* __LWIP_ICMP_H__ */\r
+    \r
index 6d79aab7a424871d0c03d01628d3d9dc860af2db..5428d54fdf989beacd56e6aa0e7c45a2114f1f0d 100644 (file)
@@ -1,87 +1,87 @@
-/*
- * 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 <adam@sics.se>
- *
- */
-#ifndef __LWIP_INET_H__
-#define __LWIP_INET_H__
-
-#include "lwip/arch.h"
-
-#include "lwip/opt.h"
-#include "lwip/pbuf.h"
-#include "lwip/ip_addr.h"
-
-u16_t inet_chksum(void *dataptr, u16_t len);
-#if 0 /* optimized routine */
-u16_t inet_chksum4(u8_t *dataptr, u16_t len);
-#endif
-u16_t inet_chksum_pbuf(struct pbuf *p);
-u16_t inet_chksum_pseudo(struct pbuf *p,
-       struct ip_addr *src, struct ip_addr *dest,
-       u8_t proto, u16_t proto_len);
-
-u32_t inet_addr(const char *cp);
-s8_t inet_aton(const char *cp, struct in_addr *addr);
-char *inet_ntoa(struct in_addr addr); /* returns ptr to static buffer; not reentrant! */
-
-#ifdef htons
-#undef htons
-#endif /* htons */
-#ifdef htonl
-#undef htonl
-#endif /* htonl */
-#ifdef ntohs
-#undef ntohs
-#endif /* ntohs */
-#ifdef ntohl
-#undef ntohl
-#endif /* ntohl */
-
-#if BYTE_ORDER == BIG_ENDIAN
-#define htons(x) (x)
-#define ntohs(x) (x)
-#define htonl(x) (x)
-#define ntohl(x) (x)
-#else
-#ifdef LWIP_PREFIX_BYTEORDER_FUNCS
-/* workaround for naming collisions on some platforms */
-#define htons lwip_htons
-#define ntohs lwip_ntohs
-#define htonl lwip_htonl
-#define ntohl lwip_ntohl
-#endif
-u16_t htons(u16_t x);
-u16_t ntohs(u16_t x);
-u32_t htonl(u32_t x);
-u32_t ntohl(u32_t x);
-#endif
-
-#endif /* __LWIP_INET_H__ */
-
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+#ifndef __LWIP_INET_H__\r
+#define __LWIP_INET_H__\r
+\r
+#include "lwip/arch.h"\r
+\r
+#include "lwip/opt.h"\r
+#include "lwip/pbuf.h"\r
+#include "lwip/ip_addr.h"\r
+\r
+u16_t inet_chksum(void *dataptr, u16_t len);\r
+#if 0 /* optimized routine */\r
+u16_t inet_chksum4(u8_t *dataptr, u16_t len);\r
+#endif\r
+u16_t inet_chksum_pbuf(struct pbuf *p);\r
+u16_t inet_chksum_pseudo(struct pbuf *p,\r
+       struct ip_addr *src, struct ip_addr *dest,\r
+       u8_t proto, u16_t proto_len);\r
+\r
+u32_t inet_addr(const char *cp);\r
+s8_t inet_aton(const char *cp, struct in_addr *addr);\r
+char *inet_ntoa(struct in_addr addr); /* returns ptr to static buffer; not reentrant! */\r
+\r
+#ifdef htons\r
+#undef htons\r
+#endif /* htons */\r
+#ifdef htonl\r
+#undef htonl\r
+#endif /* htonl */\r
+#ifdef ntohs\r
+#undef ntohs\r
+#endif /* ntohs */\r
+#ifdef ntohl\r
+#undef ntohl\r
+#endif /* ntohl */\r
+\r
+#if BYTE_ORDER == BIG_ENDIAN\r
+#define htons(x) (x)\r
+#define ntohs(x) (x)\r
+#define htonl(x) (x)\r
+#define ntohl(x) (x)\r
+#else\r
+#ifdef LWIP_PREFIX_BYTEORDER_FUNCS\r
+/* workaround for naming collisions on some platforms */\r
+#define htons lwip_htons\r
+#define ntohs lwip_ntohs\r
+#define htonl lwip_htonl\r
+#define ntohl lwip_ntohl\r
+#endif\r
+u16_t htons(u16_t x);\r
+u16_t ntohs(u16_t x);\r
+u32_t htonl(u32_t x);\r
+u32_t ntohl(u32_t x);\r
+#endif\r
+\r
+#endif /* __LWIP_INET_H__ */\r
+\r
index 4c15e1a0ea1eeac4cce3bccca5036fe82b12cfac..34ca7a8fc3a98bc76c68e01d0addffc741023063 100644 (file)
-/*
- * 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 <adam@sics.se>
- *
- */
-#ifndef __LWIP_IP_H__
-#define __LWIP_IP_H__
-
-#include "lwip/arch.h"
-
-#include "lwip/def.h"
-#include "lwip/pbuf.h"
-#include "lwip/ip_addr.h"
-
-#include "lwip/err.h"
-
-
-void ip_init(void);
-struct netif *ip_route(struct ip_addr *dest);
-err_t ip_input(struct pbuf *p, struct netif *inp);
-err_t ip_output(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
-               u8_t ttl, u8_t tos, u8_t proto);
-err_t ip_output_if(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
-                  u8_t ttl, u8_t tos, u8_t proto,
-       struct netif *netif);
-
-#define IP_HLEN 20
-
-#define IP_PROTO_ICMP 1
-#define IP_PROTO_UDP 17
-#define IP_PROTO_UDPLITE 170
-#define IP_PROTO_TCP 6
-
-/* This is passed as the destination address to ip_output_if (not
-   to ip_output), meaning that an IP header already is constructed
-   in the pbuf. This is used when TCP retransmits. */
-#ifdef IP_HDRINCL
-#undef IP_HDRINCL
-#endif /* IP_HDRINCL */
-#define IP_HDRINCL  NULL
-
-
-/* This is the common part of all PCB types. It needs to be at the
-   beginning of a PCB type definition. It is located here so that
-   changes to this common part are made in one location instead of
-   having to change all PCB structs. */
-#define IP_PCB struct ip_addr local_ip; \
-  struct ip_addr remote_ip; \
-   /* Socket options */  \
-  u16_t so_options;      \
-   /* Type Of Service */ \
-  u8_t tos;              \
-  /* Time To Live */     \
-  u8_t ttl
-
-/*
- * Option flags per-socket. These are the same like SO_XXX.
- */
-#define        SOF_DEBUG           (u16_t)0x0001U              /* turn on debugging info recording */
-#define        SOF_ACCEPTCONN  (u16_t)0x0002U          /* socket has had listen() */
-#define        SOF_REUSEADDR   (u16_t)0x0004U          /* allow local address reuse */
-#define        SOF_KEEPALIVE   (u16_t)0x0008U          /* keep connections alive */
-#define        SOF_DONTROUTE   (u16_t)0x0010U          /* just use interface addresses */
-#define        SOF_BROADCAST   (u16_t)0x0020U          /* permit sending of broadcast msgs */
-#define        SOF_USELOOPBACK (u16_t)0x0040U          /* bypass hardware when possible */
-#define        SOF_LINGER          (u16_t)0x0080U              /* linger on close if data present */
-#define        SOF_OOBINLINE   (u16_t)0x0100U          /* leave received OOB data in line */
-#define        SOF_REUSEPORT   (u16_t)0x0200U          /* allow local address & port reuse */
-
-
-
-#ifdef PACK_STRUCT_USE_INCLUDES
-#  include "arch/bpstruct.h"
-#endif
-PACK_STRUCT_BEGIN
-struct ip_hdr {
-  /* version / header length / type of service */
-  PACK_STRUCT_FIELD(u16_t _v_hl_tos);
-  /* total length */
-  PACK_STRUCT_FIELD(u16_t _len);
-  /* identification */
-  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 */
-  /* time to live / protocol*/
-  PACK_STRUCT_FIELD(u16_t _ttl_proto);
-  /* checksum */
-  PACK_STRUCT_FIELD(u16_t _chksum);
-  /* source and destination IP addresses */
-  PACK_STRUCT_FIELD(struct ip_addr src);
-  PACK_STRUCT_FIELD(struct ip_addr dest); 
-} PACK_STRUCT_STRUCT;
-PACK_STRUCT_END
-#ifdef PACK_STRUCT_USE_INCLUDES
-#  include "arch/epstruct.h"
-#endif
-
-#define IPH_V(hdr)  (ntohs((hdr)->_v_hl_tos) >> 12)
-#define IPH_HL(hdr) ((ntohs((hdr)->_v_hl_tos) >> 8) & 0x0f)
-#define IPH_TOS(hdr) (ntohs((hdr)->_v_hl_tos) & 0xff)
-#define IPH_LEN(hdr) ((hdr)->_len)
-#define IPH_ID(hdr) ((hdr)->_id)
-#define IPH_OFFSET(hdr) ((hdr)->_offset)
-#define IPH_TTL(hdr) (ntohs((hdr)->_ttl_proto) >> 8)
-#define IPH_PROTO(hdr) (ntohs((hdr)->_ttl_proto) & 0xff)
-#define IPH_CHKSUM(hdr) ((hdr)->_chksum)
-
-#define IPH_VHLTOS_SET(hdr, v, hl, tos) (hdr)->_v_hl_tos = (htons(((v) << 12) | ((hl) << 8) | (tos)))
-#define IPH_LEN_SET(hdr, len) (hdr)->_len = (len)
-#define IPH_ID_SET(hdr, id) (hdr)->_id = (id)
-#define IPH_OFFSET_SET(hdr, off) (hdr)->_offset = (off)
-#define IPH_TTL_SET(hdr, ttl) (hdr)->_ttl_proto = (htons(IPH_PROTO(hdr) | ((ttl) << 8)))
-#define IPH_PROTO_SET(hdr, proto) (hdr)->_ttl_proto = (htons((proto) | (IPH_TTL(hdr) << 8)))
-#define IPH_CHKSUM_SET(hdr, chksum) (hdr)->_chksum = (chksum)
-
-#if IP_DEBUG
-void ip_debug_print(struct pbuf *p);
-#else
-#define ip_debug_print(p)
-#endif /* IP_DEBUG */
-
-#endif /* __LWIP_IP_H__ */
-
-
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+#ifndef __LWIP_IP_H__\r
+#define __LWIP_IP_H__\r
+\r
+#include "lwip/arch.h"\r
+\r
+#include "lwip/def.h"\r
+#include "lwip/pbuf.h"\r
+#include "lwip/ip_addr.h"\r
+\r
+#include "lwip/err.h"\r
+\r
+\r
+void ip_init(void);\r
+struct netif *ip_route(struct ip_addr *dest);\r
+err_t ip_input(struct pbuf *p, struct netif *inp);\r
+err_t ip_output(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,\r
+               u8_t ttl, u8_t tos, u8_t proto);\r
+err_t ip_output_if(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,\r
+                  u8_t ttl, u8_t tos, u8_t proto,\r
+       struct netif *netif);\r
+\r
+#define IP_HLEN 20\r
+\r
+#define IP_PROTO_ICMP 1\r
+#define IP_PROTO_UDP 17\r
+#define IP_PROTO_UDPLITE 170\r
+#define IP_PROTO_TCP 6\r
+\r
+/* This is passed as the destination address to ip_output_if (not\r
+   to ip_output), meaning that an IP header already is constructed\r
+   in the pbuf. This is used when TCP retransmits. */\r
+#ifdef IP_HDRINCL\r
+#undef IP_HDRINCL\r
+#endif /* IP_HDRINCL */\r
+#define IP_HDRINCL  NULL\r
+\r
+\r
+/* This is the common part of all PCB types. It needs to be at the\r
+   beginning of a PCB type definition. It is located here so that\r
+   changes to this common part are made in one location instead of\r
+   having to change all PCB structs. */\r
+#define IP_PCB struct ip_addr local_ip; \\r
+  struct ip_addr remote_ip; \\r
+   /* Socket options */  \\r
+  u16_t so_options;      \\r
+   /* Type Of Service */ \\r
+  u8_t tos;              \\r
+  /* Time To Live */     \\r
+  u8_t ttl\r
+\r
+/*\r
+ * Option flags per-socket. These are the same like SO_XXX.\r
+ */\r
+#define        SOF_DEBUG           (u16_t)0x0001U              /* turn on debugging info recording */\r
+#define        SOF_ACCEPTCONN  (u16_t)0x0002U          /* socket has had listen() */\r
+#define        SOF_REUSEADDR   (u16_t)0x0004U          /* allow local address reuse */\r
+#define        SOF_KEEPALIVE   (u16_t)0x0008U          /* keep connections alive */\r
+#define        SOF_DONTROUTE   (u16_t)0x0010U          /* just use interface addresses */\r
+#define        SOF_BROADCAST   (u16_t)0x0020U          /* permit sending of broadcast msgs */\r
+#define        SOF_USELOOPBACK (u16_t)0x0040U          /* bypass hardware when possible */\r
+#define        SOF_LINGER          (u16_t)0x0080U              /* linger on close if data present */\r
+#define        SOF_OOBINLINE   (u16_t)0x0100U          /* leave received OOB data in line */\r
+#define        SOF_REUSEPORT   (u16_t)0x0200U          /* allow local address & port reuse */\r
+\r
+\r
+\r
+#ifdef PACK_STRUCT_USE_INCLUDES\r
+#  include "arch/bpstruct.h"\r
+#endif\r
+PACK_STRUCT_BEGIN\r
+struct ip_hdr {\r
+  /* version / header length / type of service */\r
+  PACK_STRUCT_FIELD(u16_t _v_hl_tos);\r
+  /* total length */\r
+  PACK_STRUCT_FIELD(u16_t _len);\r
+  /* identification */\r
+  PACK_STRUCT_FIELD(u16_t _id);\r
+  /* fragment offset field */\r
+  PACK_STRUCT_FIELD(u16_t _offset);\r
+#define IP_RF 0x8000        /* reserved fragment flag */\r
+#define IP_DF 0x4000        /* dont fragment flag */\r
+#define IP_MF 0x2000        /* more fragments flag */\r
+#define IP_OFFMASK 0x1fff   /* mask for fragmenting bits */\r
+  /* time to live / protocol*/\r
+  PACK_STRUCT_FIELD(u16_t _ttl_proto);\r
+  /* checksum */\r
+  PACK_STRUCT_FIELD(u16_t _chksum);\r
+  /* source and destination IP addresses */\r
+  PACK_STRUCT_FIELD(struct ip_addr src);\r
+  PACK_STRUCT_FIELD(struct ip_addr dest); \r
+} PACK_STRUCT_STRUCT;\r
+PACK_STRUCT_END\r
+#ifdef PACK_STRUCT_USE_INCLUDES\r
+#  include "arch/epstruct.h"\r
+#endif\r
+\r
+#define IPH_V(hdr)  (ntohs((hdr)->_v_hl_tos) >> 12)\r
+#define IPH_HL(hdr) ((ntohs((hdr)->_v_hl_tos) >> 8) & 0x0f)\r
+#define IPH_TOS(hdr) (ntohs((hdr)->_v_hl_tos) & 0xff)\r
+#define IPH_LEN(hdr) ((hdr)->_len)\r
+#define IPH_ID(hdr) ((hdr)->_id)\r
+#define IPH_OFFSET(hdr) ((hdr)->_offset)\r
+#define IPH_TTL(hdr) (ntohs((hdr)->_ttl_proto) >> 8)\r
+#define IPH_PROTO(hdr) (ntohs((hdr)->_ttl_proto) & 0xff)\r
+#define IPH_CHKSUM(hdr) ((hdr)->_chksum)\r
+\r
+#define IPH_VHLTOS_SET(hdr, v, hl, tos) (hdr)->_v_hl_tos = (htons(((v) << 12) | ((hl) << 8) | (tos)))\r
+#define IPH_LEN_SET(hdr, len) (hdr)->_len = (len)\r
+#define IPH_ID_SET(hdr, id) (hdr)->_id = (id)\r
+#define IPH_OFFSET_SET(hdr, off) (hdr)->_offset = (off)\r
+#define IPH_TTL_SET(hdr, ttl) (hdr)->_ttl_proto = (htons(IPH_PROTO(hdr) | ((ttl) << 8)))\r
+#define IPH_PROTO_SET(hdr, proto) (hdr)->_ttl_proto = (htons((proto) | (IPH_TTL(hdr) << 8)))\r
+#define IPH_CHKSUM_SET(hdr, chksum) (hdr)->_chksum = (chksum)\r
+\r
+#if IP_DEBUG\r
+void ip_debug_print(struct pbuf *p);\r
+#else\r
+#define ip_debug_print(p)\r
+#endif /* IP_DEBUG */\r
+\r
+#endif /* __LWIP_IP_H__ */\r
+\r
+\r
index 2819b15297e27523b50785339464a1c3eddce544..78aba80331125a58b00accb2ede4ccf159ffe96d 100644 (file)
-/*
- * 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 <adam@sics.se>
- *
- */
-#ifndef __LWIP_IP_ADDR_H__
-#define __LWIP_IP_ADDR_H__
-
-#include "lwip/arch.h"
-
-#ifdef PACK_STRUCT_USE_INCLUDES
-#  include "arch/bpstruct.h"
-#endif
-PACK_STRUCT_BEGIN
-struct ip_addr {
-  PACK_STRUCT_FIELD(u32_t addr);
-} PACK_STRUCT_STRUCT;
-PACK_STRUCT_END
-#ifdef PACK_STRUCT_USE_INCLUDES
-#  include "arch/epstruct.h"
-#endif
-
-#ifdef PACK_STRUCT_USE_INCLUDES
-#  include "arch/bpstruct.h"
-#endif
-PACK_STRUCT_BEGIN
-struct ip_addr2 {
-  PACK_STRUCT_FIELD(u16_t addrw[2]);
-} PACK_STRUCT_STRUCT;
-PACK_STRUCT_END
-#ifdef PACK_STRUCT_USE_INCLUDES
-#  include "arch/epstruct.h"
-#endif
-
-/* For compatibility with BSD code */
-struct in_addr {
-  u32_t s_addr;
-};
-
-struct netif;
-
-extern const struct ip_addr ip_addr_any;
-extern const struct ip_addr ip_addr_broadcast;
-
-/** IP_ADDR_ can be used as a fixed IP address
- *  for the wildcard and the broadcast address
- */
-#define IP_ADDR_ANY ((struct ip_addr *)&ip_addr_any)
-#define IP_ADDR_BROADCAST ((struct ip_addr *)&ip_addr_broadcast)
-
-#define INADDR_NONE    ((u32_t) 0xffffffff)  /* 255.255.255.255 */
-#define INADDR_LOOPBACK    ((u32_t) 0x7f000001)  /* 127.0.0.1 */
-
-/* Definitions of the bits in an Internet address integer.
-
-   On subnets, host and network parts are found according to
-   the subnet mask, not these masks.  */
-
-#define  IN_CLASSA(a)    ((((u32_t)(a)) & 0x80000000) == 0)
-#define  IN_CLASSA_NET    0xff000000
-#define  IN_CLASSA_NSHIFT  24
-#define  IN_CLASSA_HOST    (0xffffffff & ~IN_CLASSA_NET)
-#define  IN_CLASSA_MAX    128
-
-#define  IN_CLASSB(a)    ((((u32_t)(a)) & 0xc0000000) == 0x80000000)
-#define  IN_CLASSB_NET    0xffff0000
-#define  IN_CLASSB_NSHIFT  16
-#define  IN_CLASSB_HOST    (0xffffffff & ~IN_CLASSB_NET)
-#define  IN_CLASSB_MAX    65536
-
-#define  IN_CLASSC(a)    ((((u32_t)(a)) & 0xe0000000) == 0xc0000000)
-#define  IN_CLASSC_NET    0xffffff00
-#define  IN_CLASSC_NSHIFT  8
-#define  IN_CLASSC_HOST    (0xffffffff & ~IN_CLASSC_NET)
-
-#define IN_CLASSD(a)        (((u32_t)(a) & 0xf0000000) == 0xe0000000)
-#define IN_CLASSD_NET       0xf0000000  /* These ones aren't really */
-#define IN_CLASSD_NSHIFT    28      /* net and host fields, but */
-#define IN_CLASSD_HOST      0x0fffffff  /* routing needn't know.    */
-#define IN_MULTICAST(a)     IN_CLASSD(a)
-
-#define IN_EXPERIMENTAL(a)  (((u32_t)(a) & 0xf0000000) == 0xf0000000)
-#define IN_BADCLASS(a)      (((u32_t)(a) & 0xf0000000) == 0xf0000000)
-
-#define IN_LOOPBACKNET      127         /* official! */
-
-
-#define IP4_ADDR(ipaddr, a,b,c,d) (ipaddr)->addr = htonl(((u32_t)(a & 0xff) << 24) | ((u32_t)(b & 0xff) << 16) | \
-                                                         ((u32_t)(c & 0xff) << 8) | (u32_t)(d & 0xff))
-
-#define ip_addr_set(dest, src) (dest)->addr = \
-                               ((src) == NULL? 0:\
-                               (src)->addr)
-/**
- * Determine if two address are on the same network.
- *
- * @arg addr1 IP address 1
- * @arg addr2 IP address 2
- * @arg mask network identifier mask
- * @return !0 if the network identifiers of both address match
- */
-#define ip_addr_netcmp(addr1, addr2, mask) (((addr1)->addr & \
-                                              (mask)->addr) == \
-                                             ((addr2)->addr & \
-                                              (mask)->addr))
-#define ip_addr_cmp(addr1, addr2) ((addr1)->addr == (addr2)->addr)
-
-#define ip_addr_isany(addr1) ((addr1) == NULL || (addr1)->addr == 0)
-
-u8_t ip_addr_isbroadcast(struct ip_addr *, struct netif *);
-
-#define ip_addr_ismulticast(addr1) (((addr1)->addr & ntohl(0xf0000000)) == ntohl(0xe0000000))
-
-
-#define ip_addr_debug_print(debug, ipaddr) LWIP_DEBUGF(debug, ("%"U16_F".%"U16_F".%"U16_F".%"U16_F, \
-        ipaddr?(u16_t)(ntohl((ipaddr)->addr) >> 24) & 0xff:0, \
-        ipaddr?(u16_t)(ntohl((ipaddr)->addr) >> 16) & 0xff:0, \
-        ipaddr?(u16_t)(ntohl((ipaddr)->addr) >> 8) & 0xff:0, \
-        ipaddr?(u16_t)ntohl((ipaddr)->addr) & 0xff:0U))
-
-/* cast to unsigned int, as it is used as argument to printf functions
- * which expect integer arguments. CSi: use cc.h formatters (conversion chars)! */
-#define ip4_addr1(ipaddr) ((u16_t)(ntohl((ipaddr)->addr) >> 24) & 0xff)
-#define ip4_addr2(ipaddr) ((u16_t)(ntohl((ipaddr)->addr) >> 16) & 0xff)
-#define ip4_addr3(ipaddr) ((u16_t)(ntohl((ipaddr)->addr) >> 8) & 0xff)
-#define ip4_addr4(ipaddr) ((u16_t)(ntohl((ipaddr)->addr)) & 0xff)
-#endif /* __LWIP_IP_ADDR_H__ */
-
-
-
-
-
-
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without modification,\r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED\r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT\r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY\r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ *\r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+#ifndef __LWIP_IP_ADDR_H__\r
+#define __LWIP_IP_ADDR_H__\r
+\r
+#include "lwip/arch.h"\r
+\r
+#ifdef PACK_STRUCT_USE_INCLUDES\r
+#  include "arch/bpstruct.h"\r
+#endif\r
+PACK_STRUCT_BEGIN\r
+struct ip_addr {\r
+  PACK_STRUCT_FIELD(u32_t addr);\r
+} PACK_STRUCT_STRUCT;\r
+PACK_STRUCT_END\r
+#ifdef PACK_STRUCT_USE_INCLUDES\r
+#  include "arch/epstruct.h"\r
+#endif\r
+\r
+#ifdef PACK_STRUCT_USE_INCLUDES\r
+#  include "arch/bpstruct.h"\r
+#endif\r
+PACK_STRUCT_BEGIN\r
+struct ip_addr2 {\r
+  PACK_STRUCT_FIELD(u16_t addrw[2]);\r
+} PACK_STRUCT_STRUCT;\r
+PACK_STRUCT_END\r
+#ifdef PACK_STRUCT_USE_INCLUDES\r
+#  include "arch/epstruct.h"\r
+#endif\r
+\r
+/* For compatibility with BSD code */\r
+struct in_addr {\r
+  u32_t s_addr;\r
+};\r
+\r
+struct netif;\r
+\r
+extern const struct ip_addr ip_addr_any;\r
+extern const struct ip_addr ip_addr_broadcast;\r
+\r
+/** IP_ADDR_ can be used as a fixed IP address\r
+ *  for the wildcard and the broadcast address\r
+ */\r
+#define IP_ADDR_ANY ((struct ip_addr *)&ip_addr_any)\r
+#define IP_ADDR_BROADCAST ((struct ip_addr *)&ip_addr_broadcast)\r
+\r
+#define INADDR_NONE    ((u32_t) 0xffffffff)  /* 255.255.255.255 */\r
+#define INADDR_LOOPBACK    ((u32_t) 0x7f000001)  /* 127.0.0.1 */\r
+\r
+/* Definitions of the bits in an Internet address integer.\r
+\r
+   On subnets, host and network parts are found according to\r
+   the subnet mask, not these masks.  */\r
+\r
+#define  IN_CLASSA(a)    ((((u32_t)(a)) & 0x80000000) == 0)\r
+#define  IN_CLASSA_NET    0xff000000\r
+#define  IN_CLASSA_NSHIFT  24\r
+#define  IN_CLASSA_HOST    (0xffffffff & ~IN_CLASSA_NET)\r
+#define  IN_CLASSA_MAX    128\r
+\r
+#define  IN_CLASSB(a)    ((((u32_t)(a)) & 0xc0000000) == 0x80000000)\r
+#define  IN_CLASSB_NET    0xffff0000\r
+#define  IN_CLASSB_NSHIFT  16\r
+#define  IN_CLASSB_HOST    (0xffffffff & ~IN_CLASSB_NET)\r
+#define  IN_CLASSB_MAX    65536\r
+\r
+#define  IN_CLASSC(a)    ((((u32_t)(a)) & 0xe0000000) == 0xc0000000)\r
+#define  IN_CLASSC_NET    0xffffff00\r
+#define  IN_CLASSC_NSHIFT  8\r
+#define  IN_CLASSC_HOST    (0xffffffff & ~IN_CLASSC_NET)\r
+\r
+#define IN_CLASSD(a)        (((u32_t)(a) & 0xf0000000) == 0xe0000000)\r
+#define IN_CLASSD_NET       0xf0000000  /* These ones aren't really */\r
+#define IN_CLASSD_NSHIFT    28      /* net and host fields, but */\r
+#define IN_CLASSD_HOST      0x0fffffff  /* routing needn't know.    */\r
+#define IN_MULTICAST(a)     IN_CLASSD(a)\r
+\r
+#define IN_EXPERIMENTAL(a)  (((u32_t)(a) & 0xf0000000) == 0xf0000000)\r
+#define IN_BADCLASS(a)      (((u32_t)(a) & 0xf0000000) == 0xf0000000)\r
+\r
+#define IN_LOOPBACKNET      127         /* official! */\r
+\r
+\r
+#define IP4_ADDR(ipaddr, a,b,c,d) (ipaddr)->addr = htonl(((u32_t)(a & 0xff) << 24) | ((u32_t)(b & 0xff) << 16) | \\r
+                                                         ((u32_t)(c & 0xff) << 8) | (u32_t)(d & 0xff))\r
+\r
+#define ip_addr_set(dest, src) (dest)->addr = \\r
+                               ((src) == NULL? 0:\\r
+                               (src)->addr)\r
+/**\r
+ * Determine if two address are on the same network.\r
+ *\r
+ * @arg addr1 IP address 1\r
+ * @arg addr2 IP address 2\r
+ * @arg mask network identifier mask\r
+ * @return !0 if the network identifiers of both address match\r
+ */\r
+#define ip_addr_netcmp(addr1, addr2, mask) (((addr1)->addr & \\r
+                                              (mask)->addr) == \\r
+                                             ((addr2)->addr & \\r
+                                              (mask)->addr))\r
+#define ip_addr_cmp(addr1, addr2) ((addr1)->addr == (addr2)->addr)\r
+\r
+#define ip_addr_isany(addr1) ((addr1) == NULL || (addr1)->addr == 0)\r
+\r
+u8_t ip_addr_isbroadcast(struct ip_addr *, struct netif *);\r
+\r
+#define ip_addr_ismulticast(addr1) (((addr1)->addr & ntohl(0xf0000000)) == ntohl(0xe0000000))\r
+\r
+\r
+#define ip_addr_debug_print(debug, ipaddr) LWIP_DEBUGF(debug, ("%"U16_F".%"U16_F".%"U16_F".%"U16_F, \\r
+        ipaddr?(u16_t)(ntohl((ipaddr)->addr) >> 24) & 0xff:0, \\r
+        ipaddr?(u16_t)(ntohl((ipaddr)->addr) >> 16) & 0xff:0, \\r
+        ipaddr?(u16_t)(ntohl((ipaddr)->addr) >> 8) & 0xff:0, \\r
+        ipaddr?(u16_t)ntohl((ipaddr)->addr) & 0xff:0U))\r
+\r
+/* cast to unsigned int, as it is used as argument to printf functions\r
+ * which expect integer arguments. CSi: use cc.h formatters (conversion chars)! */\r
+#define ip4_addr1(ipaddr) ((u16_t)(ntohl((ipaddr)->addr) >> 24) & 0xff)\r
+#define ip4_addr2(ipaddr) ((u16_t)(ntohl((ipaddr)->addr) >> 16) & 0xff)\r
+#define ip4_addr3(ipaddr) ((u16_t)(ntohl((ipaddr)->addr) >> 8) & 0xff)\r
+#define ip4_addr4(ipaddr) ((u16_t)(ntohl((ipaddr)->addr)) & 0xff)\r
+#endif /* __LWIP_IP_ADDR_H__ */\r
+\r
+\r
+\r
+\r
+\r
+\r
index a982c5a63f2545248ac62de12b9f67c08df7beec..9b88b69486a033d5064d432809bfbae9d6935d50 100644 (file)
@@ -1,47 +1,47 @@
-/*
- * 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: Jani Monoses <jani@iv.ro>
- *
- */
-
-#ifndef __LWIP_IP_FRAG_H__
-#define __LWIP_IP_FRAG_H__
-
-#include "lwip/err.h"
-#include "lwip/pbuf.h"
-#include "lwip/netif.h"
-#include "lwip/ip_addr.h"
-
-void ip_reass_tmr(void);
-struct pbuf * ip_reass(struct pbuf *p);
-err_t ip_frag(struct pbuf *p, struct netif *netif, struct ip_addr *dest);
-
-#endif /* __LWIP_IP_FRAG_H__ */
-
-
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Jani Monoses <jani@iv.ro>\r
+ *\r
+ */\r
+\r
+#ifndef __LWIP_IP_FRAG_H__\r
+#define __LWIP_IP_FRAG_H__\r
+\r
+#include "lwip/err.h"\r
+#include "lwip/pbuf.h"\r
+#include "lwip/netif.h"\r
+#include "lwip/ip_addr.h"\r
+\r
+void ip_reass_tmr(void);\r
+struct pbuf * ip_reass(struct pbuf *p);\r
+err_t ip_frag(struct pbuf *p, struct netif *netif, struct ip_addr *dest);\r
+\r
+#endif /* __LWIP_IP_FRAG_H__ */\r
+\r
+\r
index 2b6adb1222a9a8fd78b6f1d42b4608b2abcf4335..9c63a3f45ae980b1dfbd0f40234dc7ecc9919b43 100644 (file)
@@ -1,90 +1,90 @@
-/*
- * 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 <adam@sics.se>
- *
- */
-#ifndef __LWIP_ICMP_H__
-#define __LWIP_ICMP_H__
-
-#include "lwip/arch.h"
-
-#include "lwip/opt.h"
-#include "lwip/pbuf.h"
-
-#include "lwip/netif.h"
-
-#define ICMP6_DUR  1
-#define ICMP6_TE   3
-#define ICMP6_ECHO 128    /* echo */
-#define ICMP6_ER   129      /* echo reply */
-
-
-enum icmp_dur_type {
-  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 */
-};
-
-enum icmp_te_type {
-  ICMP_TE_TTL = 0,     /* time to live exceeded in transit */
-  ICMP_TE_FRAG = 1     /* fragment reassembly time exceeded */
-};
-
-void icmp_input(struct pbuf *p, struct netif *inp);
-
-void icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t);
-void icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t);
-
-struct icmp_echo_hdr {
-  u8_t type;
-  u8_t icode;
-  u16_t chksum;
-  u16_t id;
-  u16_t seqno;
-};
-
-struct icmp_dur_hdr {
-  u8_t type;
-  u8_t icode;
-  u16_t chksum;
-  u32_t unused;
-};
-
-struct icmp_te_hdr {
-  u8_t type;
-  u8_t icode;
-  u16_t chksum;
-  u32_t unused;
-};
-
-#endif /* __LWIP_ICMP_H__ */
-    
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+#ifndef __LWIP_ICMP_H__\r
+#define __LWIP_ICMP_H__\r
+\r
+#include "lwip/arch.h"\r
+\r
+#include "lwip/opt.h"\r
+#include "lwip/pbuf.h"\r
+\r
+#include "lwip/netif.h"\r
+\r
+#define ICMP6_DUR  1\r
+#define ICMP6_TE   3\r
+#define ICMP6_ECHO 128    /* echo */\r
+#define ICMP6_ER   129      /* echo reply */\r
+\r
+\r
+enum icmp_dur_type {\r
+  ICMP_DUR_NET = 0,    /* net unreachable */\r
+  ICMP_DUR_HOST = 1,   /* host unreachable */\r
+  ICMP_DUR_PROTO = 2,  /* protocol unreachable */\r
+  ICMP_DUR_PORT = 3,   /* port unreachable */\r
+  ICMP_DUR_FRAG = 4,   /* fragmentation needed and DF set */\r
+  ICMP_DUR_SR = 5      /* source route failed */\r
+};\r
+\r
+enum icmp_te_type {\r
+  ICMP_TE_TTL = 0,     /* time to live exceeded in transit */\r
+  ICMP_TE_FRAG = 1     /* fragment reassembly time exceeded */\r
+};\r
+\r
+void icmp_input(struct pbuf *p, struct netif *inp);\r
+\r
+void icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t);\r
+void icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t);\r
+\r
+struct icmp_echo_hdr {\r
+  u8_t type;\r
+  u8_t icode;\r
+  u16_t chksum;\r
+  u16_t id;\r
+  u16_t seqno;\r
+};\r
+\r
+struct icmp_dur_hdr {\r
+  u8_t type;\r
+  u8_t icode;\r
+  u16_t chksum;\r
+  u32_t unused;\r
+};\r
+\r
+struct icmp_te_hdr {\r
+  u8_t type;\r
+  u8_t icode;\r
+  u16_t chksum;\r
+  u32_t unused;\r
+};\r
+\r
+#endif /* __LWIP_ICMP_H__ */\r
+    \r
index ae78343644b838092f7112b866102591370062ce..c9d07d7fd1c4501c301e8e07ce6fb0fc503c03d8 100644 (file)
@@ -1,62 +1,62 @@
-/*
- * 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 <adam@sics.se>
- *
- */
-#ifndef __LWIP_INET_H__
-#define __LWIP_INET_H__
-
-#include "lwip/arch.h"
-
-#include "lwip/opt.h"
-#include "lwip/pbuf.h"
-#include "lwip/ip_addr.h"
-
-u16_t inet_chksum(void *data, u16_t len);
-u16_t inet_chksum_pbuf(struct pbuf *p);
-u16_t inet_chksum_pseudo(struct pbuf *p,
-       struct ip_addr *src, struct ip_addr *dest,
-       u8_t proto, u32_t proto_len);
-
-u32_t inet_addr(const char *cp);
-s8_t inet_aton(const char *cp, struct in_addr *addr);
-
-#ifndef _MACHINE_ENDIAN_H_
-#ifndef _NETINET_IN_H
-#ifndef _LINUX_BYTEORDER_GENERIC_H
-u16_t htons(u16_t n);
-u16_t ntohs(u16_t n);
-u32_t htonl(u32_t n);
-u32_t ntohl(u32_t n);
-#endif /* _LINUX_BYTEORDER_GENERIC_H */
-#endif /* _NETINET_IN_H */
-#endif /* _MACHINE_ENDIAN_H_ */
-
-#endif /* __LWIP_INET_H__ */
-
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+#ifndef __LWIP_INET_H__\r
+#define __LWIP_INET_H__\r
+\r
+#include "lwip/arch.h"\r
+\r
+#include "lwip/opt.h"\r
+#include "lwip/pbuf.h"\r
+#include "lwip/ip_addr.h"\r
+\r
+u16_t inet_chksum(void *data, u16_t len);\r
+u16_t inet_chksum_pbuf(struct pbuf *p);\r
+u16_t inet_chksum_pseudo(struct pbuf *p,\r
+       struct ip_addr *src, struct ip_addr *dest,\r
+       u8_t proto, u32_t proto_len);\r
+\r
+u32_t inet_addr(const char *cp);\r
+s8_t inet_aton(const char *cp, struct in_addr *addr);\r
+\r
+#ifndef _MACHINE_ENDIAN_H_\r
+#ifndef _NETINET_IN_H\r
+#ifndef _LINUX_BYTEORDER_GENERIC_H\r
+u16_t htons(u16_t n);\r
+u16_t ntohs(u16_t n);\r
+u32_t htonl(u32_t n);\r
+u32_t ntohl(u32_t n);\r
+#endif /* _LINUX_BYTEORDER_GENERIC_H */\r
+#endif /* _NETINET_IN_H */\r
+#endif /* _MACHINE_ENDIAN_H_ */\r
+\r
+#endif /* __LWIP_INET_H__ */\r
+\r
index f46bf9a800901d46965c6007ca1c29132a935444..f316ce50a55f1ef669c96e4ede8f33076d4476cb 100644 (file)
@@ -1,96 +1,96 @@
-/*
- * 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 <adam@sics.se>
- *
- */
-#ifndef __LWIP_IP_H__
-#define __LWIP_IP_H__
-
-#include "lwip/opt.h"
-#include "lwip/def.h"
-#include "lwip/pbuf.h"
-#include "lwip/ip_addr.h"
-
-#include "lwip/err.h"
-
-#define IP_HLEN 40
-
-#define IP_PROTO_ICMP 58
-#define IP_PROTO_UDP 17
-#define IP_PROTO_UDPLITE 170
-#define IP_PROTO_TCP 6
-
-/* This is passed as the destination address to ip_output_if (not
-   to ip_output), meaning that an IP header already is constructed
-   in the pbuf. This is used when TCP retransmits. */
-#ifdef IP_HDRINCL
-#undef IP_HDRINCL
-#endif /* IP_HDRINCL */
-#define IP_HDRINCL  NULL
-
-
-/* The IPv6 header. */
-struct ip_hdr {
-#if BYTE_ORDER == LITTLE_ENDIAN
-  u8_t tclass1:4, v:4;
-  u8_t flow1:4, tclass2:4;  
-#else
-  u8_t v:4, tclass1:4;
-  u8_t tclass2:8, flow1:4;
-#endif
-  u16_t flow2;
-  u16_t len;                /* payload length */
-  u8_t nexthdr;             /* next header */
-  u8_t hoplim;              /* hop limit (TTL) */
-  struct ip_addr src, dest;          /* source and destination IP addresses */
-};
-
-void ip_init(void);
-
-#include "lwip/netif.h"
-
-struct netif *ip_route(struct ip_addr *dest);
-
-void ip_input(struct pbuf *p, struct netif *inp);
-
-/* source and destination addresses in network byte order, please */
-err_t ip_output(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
-         u8_t ttl, u8_t proto);
-
-err_t ip_output_if(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
-      u8_t ttl, u8_t proto,
-      struct netif *netif);
-
-#if IP_DEBUG
-void ip_debug_print(struct pbuf *p);
-#endif /* IP_DEBUG */
-
-#endif /* __LWIP_IP_H__ */
-
-
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+#ifndef __LWIP_IP_H__\r
+#define __LWIP_IP_H__\r
+\r
+#include "lwip/opt.h"\r
+#include "lwip/def.h"\r
+#include "lwip/pbuf.h"\r
+#include "lwip/ip_addr.h"\r
+\r
+#include "lwip/err.h"\r
+\r
+#define IP_HLEN 40\r
+\r
+#define IP_PROTO_ICMP 58\r
+#define IP_PROTO_UDP 17\r
+#define IP_PROTO_UDPLITE 170\r
+#define IP_PROTO_TCP 6\r
+\r
+/* This is passed as the destination address to ip_output_if (not\r
+   to ip_output), meaning that an IP header already is constructed\r
+   in the pbuf. This is used when TCP retransmits. */\r
+#ifdef IP_HDRINCL\r
+#undef IP_HDRINCL\r
+#endif /* IP_HDRINCL */\r
+#define IP_HDRINCL  NULL\r
+\r
+\r
+/* The IPv6 header. */\r
+struct ip_hdr {\r
+#if BYTE_ORDER == LITTLE_ENDIAN\r
+  u8_t tclass1:4, v:4;\r
+  u8_t flow1:4, tclass2:4;  \r
+#else\r
+  u8_t v:4, tclass1:4;\r
+  u8_t tclass2:8, flow1:4;\r
+#endif\r
+  u16_t flow2;\r
+  u16_t len;                /* payload length */\r
+  u8_t nexthdr;             /* next header */\r
+  u8_t hoplim;              /* hop limit (TTL) */\r
+  struct ip_addr src, dest;          /* source and destination IP addresses */\r
+};\r
+\r
+void ip_init(void);\r
+\r
+#include "lwip/netif.h"\r
+\r
+struct netif *ip_route(struct ip_addr *dest);\r
+\r
+void ip_input(struct pbuf *p, struct netif *inp);\r
+\r
+/* source and destination addresses in network byte order, please */\r
+err_t ip_output(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,\r
+         u8_t ttl, u8_t proto);\r
+\r
+err_t ip_output_if(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,\r
+      u8_t ttl, u8_t proto,\r
+      struct netif *netif);\r
+\r
+#if IP_DEBUG\r
+void ip_debug_print(struct pbuf *p);\r
+#endif /* IP_DEBUG */\r
+\r
+#endif /* __LWIP_IP_H__ */\r
+\r
+\r
index db1f090602a08c2458f53b7c6a5fb8c61788bf02..16fa569fa503e2a2b85a847019d9da77662a574f 100644 (file)
@@ -1,59 +1,59 @@
-/*
- * 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 <adam@sics.se>
- *
- */
-#ifndef __LWIP_IP_ADDR_H__
-#define __LWIP_IP_ADDR_H__
-
-#include "lwip/arch.h"
-
-#define IP_ADDR_ANY 0
-
-struct ip_addr {
-  u32_t addr[4];
-};
-
-#define IP6_ADDR(ipaddr, a,b,c,d,e,f,g,h) do { (ipaddr)->addr[0] = htonl((u32_t)((a & 0xffff) << 16) | (b & 0xffff)); \
-                                               (ipaddr)->addr[1] = htonl(((c & 0xffff) << 16) | (d & 0xffff)); \
-                                               (ipaddr)->addr[2] = htonl(((e & 0xffff) << 16) | (f & 0xffff)); \
-                                               (ipaddr)->addr[3] = htonl(((g & 0xffff) << 16) | (h & 0xffff)); } while(0)
-
-u8_t ip_addr_netcmp(struct ip_addr *addr1, struct ip_addr *addr2,
-        struct ip_addr *mask);
-u8_t ip_addr_cmp(struct ip_addr *addr1, struct ip_addr *addr2);
-void ip_addr_set(struct ip_addr *dest, struct ip_addr *src);
-u8_t ip_addr_isany(struct ip_addr *addr);
-
-
-#if IP_DEBUG
-void ip_addr_debug_print(struct ip_addr *addr);
-#endif /* IP_DEBUG */
-
-#endif /* __LWIP_IP_ADDR_H__ */
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+#ifndef __LWIP_IP_ADDR_H__\r
+#define __LWIP_IP_ADDR_H__\r
+\r
+#include "lwip/arch.h"\r
+\r
+#define IP_ADDR_ANY 0\r
+\r
+struct ip_addr {\r
+  u32_t addr[4];\r
+};\r
+\r
+#define IP6_ADDR(ipaddr, a,b,c,d,e,f,g,h) do { (ipaddr)->addr[0] = htonl((u32_t)((a & 0xffff) << 16) | (b & 0xffff)); \\r
+                                               (ipaddr)->addr[1] = htonl(((c & 0xffff) << 16) | (d & 0xffff)); \\r
+                                               (ipaddr)->addr[2] = htonl(((e & 0xffff) << 16) | (f & 0xffff)); \\r
+                                               (ipaddr)->addr[3] = htonl(((g & 0xffff) << 16) | (h & 0xffff)); } while(0)\r
+\r
+u8_t ip_addr_netcmp(struct ip_addr *addr1, struct ip_addr *addr2,\r
+        struct ip_addr *mask);\r
+u8_t ip_addr_cmp(struct ip_addr *addr1, struct ip_addr *addr2);\r
+void ip_addr_set(struct ip_addr *dest, struct ip_addr *src);\r
+u8_t ip_addr_isany(struct ip_addr *addr);\r
+\r
+\r
+#if IP_DEBUG\r
+void ip_addr_debug_print(struct ip_addr *addr);\r
+#endif /* IP_DEBUG */\r
+\r
+#endif /* __LWIP_IP_ADDR_H__ */\r
index 7f0ad596666dda1c26b722d7bbcab568258620d1..1059eca2e3699280c23e26b8a52bf5772dc29957 100644 (file)
-/*
- * 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 <adam@sics.se>
- *
- */
-#ifndef __LWIP_API_H__
-#define __LWIP_API_H__
-
-#include "lwip/opt.h"
-#include "lwip/pbuf.h"
-#include "lwip/sys.h"
-
-#include "lwip/ip.h"
-
-#include "lwip/raw.h"
-#include "lwip/udp.h"
-#include "lwip/tcp.h"
-
-#include "lwip/err.h"
-
-#define NETCONN_NOCOPY 0x00
-#define NETCONN_COPY   0x01
-
-enum netconn_type {
-  NETCONN_TCP,
-  NETCONN_UDP,
-  NETCONN_UDPLITE,
-  NETCONN_UDPNOCHKSUM,
-  NETCONN_RAW
-};
-
-enum netconn_state {
-  NETCONN_NONE,
-  NETCONN_WRITE,
-  NETCONN_ACCEPT,
-  NETCONN_RECV,
-  NETCONN_CONNECT,
-  NETCONN_CLOSE
-};
-
-enum netconn_evt {
-  NETCONN_EVT_RCVPLUS,
-  NETCONN_EVT_RCVMINUS,
-  NETCONN_EVT_SENDPLUS,
-  NETCONN_EVT_SENDMINUS
-};
-
-struct netbuf {
-  struct pbuf *p, *ptr;
-  struct ip_addr *fromaddr;
-  u16_t fromport;
-  err_t err;
-};
-
-struct netconn {
-  enum netconn_type type;
-  enum netconn_state state;
-  union {
-    struct tcp_pcb *tcp;
-    struct udp_pcb *udp;
-    struct raw_pcb *raw;
-  } pcb;
-  err_t err;
-  sys_mbox_t mbox;
-  sys_mbox_t recvmbox;
-  sys_mbox_t acceptmbox;
-  sys_sem_t sem;
-  int socket;
-  u16_t recv_avail;
-  void (* callback)(struct netconn *, enum netconn_evt, u16_t len);
-};
-
-/* Network buffer functions: */
-struct netbuf *   netbuf_new      (void);
-void              netbuf_delete   (struct netbuf *buf);
-void *            netbuf_alloc    (struct netbuf *buf, u16_t size);
-void              netbuf_free     (struct netbuf *buf);
-void              netbuf_ref      (struct netbuf *buf,
-           void *dataptr, u16_t size);
-void              netbuf_chain    (struct netbuf *head,
-           struct netbuf *tail);
-
-u16_t             netbuf_len      (struct netbuf *buf);
-err_t             netbuf_data     (struct netbuf *buf,
-           void **dataptr, u16_t *len);
-s8_t              netbuf_next     (struct netbuf *buf);
-void              netbuf_first    (struct netbuf *buf);
-
-void              netbuf_copy     (struct netbuf *buf,
-           void *dataptr, u16_t len);
-void              netbuf_copy_partial(struct netbuf *buf, void *dataptr, 
-              u16_t len, u16_t offset);
-struct ip_addr *  netbuf_fromaddr (struct netbuf *buf);
-u16_t             netbuf_fromport (struct netbuf *buf);
-
-/* Network connection functions: */
-struct netconn *  netconn_new     (enum netconn_type type);
-struct
-netconn *netconn_new_with_callback(enum netconn_type t,
-                                   void (*callback)(struct netconn *, enum netconn_evt, u16_t len));
-struct
-netconn *netconn_new_with_proto_and_callback(enum netconn_type t, u16_t proto,
-                                   void (*callback)(struct netconn *, enum netconn_evt, u16_t len));
-err_t             netconn_delete  (struct netconn *conn);
-enum netconn_type netconn_type    (struct netconn *conn);
-err_t             netconn_peer    (struct netconn *conn,
-           struct ip_addr *addr,
-           u16_t *port);
-err_t             netconn_addr    (struct netconn *conn,
-           struct ip_addr **addr,
-           u16_t *port);
-err_t             netconn_bind    (struct netconn *conn,
-           struct ip_addr *addr,
-           u16_t port);
-err_t             netconn_connect (struct netconn *conn,
-           struct ip_addr *addr,
-           u16_t port);
-err_t             netconn_disconnect (struct netconn *conn);
-err_t             netconn_listen  (struct netconn *conn);
-struct netconn *  netconn_accept  (struct netconn *conn);
-struct netbuf *   netconn_recv    (struct netconn *conn);
-err_t             netconn_send    (struct netconn *conn,
-           struct netbuf *buf);
-err_t             netconn_write   (struct netconn *conn,
-           void *dataptr, u16_t size,
-           u8_t copy);
-err_t             netconn_close   (struct netconn *conn);
-
-err_t             netconn_err     (struct netconn *conn);
-
-#endif /* __LWIP_API_H__ */
-
-
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+#ifndef __LWIP_API_H__\r
+#define __LWIP_API_H__\r
+\r
+#include "lwip/opt.h"\r
+#include "lwip/pbuf.h"\r
+#include "lwip/sys.h"\r
+\r
+#include "lwip/ip.h"\r
+\r
+#include "lwip/raw.h"\r
+#include "lwip/udp.h"\r
+#include "lwip/tcp.h"\r
+\r
+#include "lwip/err.h"\r
+\r
+#define NETCONN_NOCOPY 0x00\r
+#define NETCONN_COPY   0x01\r
+\r
+enum netconn_type {\r
+  NETCONN_TCP,\r
+  NETCONN_UDP,\r
+  NETCONN_UDPLITE,\r
+  NETCONN_UDPNOCHKSUM,\r
+  NETCONN_RAW\r
+};\r
+\r
+enum netconn_state {\r
+  NETCONN_NONE,\r
+  NETCONN_WRITE,\r
+  NETCONN_ACCEPT,\r
+  NETCONN_RECV,\r
+  NETCONN_CONNECT,\r
+  NETCONN_CLOSE\r
+};\r
+\r
+enum netconn_evt {\r
+  NETCONN_EVT_RCVPLUS,\r
+  NETCONN_EVT_RCVMINUS,\r
+  NETCONN_EVT_SENDPLUS,\r
+  NETCONN_EVT_SENDMINUS\r
+};\r
+\r
+struct netbuf {\r
+  struct pbuf *p, *ptr;\r
+  struct ip_addr *fromaddr;\r
+  u16_t fromport;\r
+  err_t err;\r
+};\r
+\r
+struct netconn {\r
+  enum netconn_type type;\r
+  enum netconn_state state;\r
+  union {\r
+    struct tcp_pcb *tcp;\r
+    struct udp_pcb *udp;\r
+    struct raw_pcb *raw;\r
+  } pcb;\r
+  err_t err;\r
+  sys_mbox_t mbox;\r
+  sys_mbox_t recvmbox;\r
+  sys_mbox_t acceptmbox;\r
+  sys_sem_t sem;\r
+  int socket;\r
+  u16_t recv_avail;\r
+  void (* callback)(struct netconn *, enum netconn_evt, u16_t len);\r
+};\r
+\r
+/* Network buffer functions: */\r
+struct netbuf *   netbuf_new      (void);\r
+void              netbuf_delete   (struct netbuf *buf);\r
+void *            netbuf_alloc    (struct netbuf *buf, u16_t size);\r
+void              netbuf_free     (struct netbuf *buf);\r
+void              netbuf_ref      (struct netbuf *buf,\r
+           void *dataptr, u16_t size);\r
+void              netbuf_chain    (struct netbuf *head,\r
+           struct netbuf *tail);\r
+\r
+u16_t             netbuf_len      (struct netbuf *buf);\r
+err_t             netbuf_data     (struct netbuf *buf,\r
+           void **dataptr, u16_t *len);\r
+s8_t              netbuf_next     (struct netbuf *buf);\r
+void              netbuf_first    (struct netbuf *buf);\r
+\r
+void              netbuf_copy     (struct netbuf *buf,\r
+           void *dataptr, u16_t len);\r
+void              netbuf_copy_partial(struct netbuf *buf, void *dataptr, \r
+              u16_t len, u16_t offset);\r
+struct ip_addr *  netbuf_fromaddr (struct netbuf *buf);\r
+u16_t             netbuf_fromport (struct netbuf *buf);\r
+\r
+/* Network connection functions: */\r
+struct netconn *  netconn_new     (enum netconn_type type);\r
+struct\r
+netconn *netconn_new_with_callback(enum netconn_type t,\r
+                                   void (*callback)(struct netconn *, enum netconn_evt, u16_t len));\r
+struct\r
+netconn *netconn_new_with_proto_and_callback(enum netconn_type t, u16_t proto,\r
+                                   void (*callback)(struct netconn *, enum netconn_evt, u16_t len));\r
+err_t             netconn_delete  (struct netconn *conn);\r
+enum netconn_type netconn_type    (struct netconn *conn);\r
+err_t             netconn_peer    (struct netconn *conn,\r
+           struct ip_addr *addr,\r
+           u16_t *port);\r
+err_t             netconn_addr    (struct netconn *conn,\r
+           struct ip_addr **addr,\r
+           u16_t *port);\r
+err_t             netconn_bind    (struct netconn *conn,\r
+           struct ip_addr *addr,\r
+           u16_t port);\r
+err_t             netconn_connect (struct netconn *conn,\r
+           struct ip_addr *addr,\r
+           u16_t port);\r
+err_t             netconn_disconnect (struct netconn *conn);\r
+err_t             netconn_listen  (struct netconn *conn);\r
+struct netconn *  netconn_accept  (struct netconn *conn);\r
+struct netbuf *   netconn_recv    (struct netconn *conn);\r
+err_t             netconn_send    (struct netconn *conn,\r
+           struct netbuf *buf);\r
+err_t             netconn_write   (struct netconn *conn,\r
+           void *dataptr, u16_t size,\r
+           u8_t copy);\r
+err_t             netconn_close   (struct netconn *conn);\r
+\r
+err_t             netconn_err     (struct netconn *conn);\r
+\r
+#endif /* __LWIP_API_H__ */\r
+\r
+\r
index 3fef3dd0c5ee6172c117ff983a801bef27eb1e34..87f3db5f12c2e906fe2ed1fb0ea558d1aea9b138 100644 (file)
@@ -1,94 +1,94 @@
-/*
- * 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 <adam@sics.se>
- *
- */
-#ifndef __LWIP_API_MSG_H__
-#define __LWIP_API_MSG_H__
-
-#include "lwip/opt.h"
-#include "lwip/pbuf.h"
-#include "lwip/sys.h"
-
-#include "lwip/ip.h"
-
-#include "lwip/udp.h"
-#include "lwip/tcp.h"
-
-#include "lwip/api.h"
-
-enum api_msg_type {
-  API_MSG_NEWCONN,
-  API_MSG_DELCONN,
-  
-  API_MSG_BIND,
-  API_MSG_CONNECT,
-  API_MSG_DISCONNECT,
-
-  API_MSG_LISTEN,
-  API_MSG_ACCEPT,
-
-  API_MSG_SEND,
-  API_MSG_RECV,
-  API_MSG_WRITE,
-
-  API_MSG_CLOSE,
-  
-  API_MSG_MAX
-};
-
-struct api_msg_msg {
-  struct netconn *conn;
-  enum netconn_type conntype;
-  union {
-    struct pbuf *p;   
-    struct  {
-      struct ip_addr *ipaddr;
-      u16_t port;
-    } bc;
-    struct {
-      void *dataptr;
-      u16_t len;
-      u8_t copy;
-    } w;    
-    sys_mbox_t mbox;
-    u16_t len;
-  } msg;
-};
-
-struct api_msg {
-  enum api_msg_type type;
-  struct api_msg_msg msg;
-};
-
-void api_msg_input(struct api_msg *msg);
-void api_msg_post(struct api_msg *msg);
-
-#endif /* __LWIP_API_MSG_H__ */
-
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+#ifndef __LWIP_API_MSG_H__\r
+#define __LWIP_API_MSG_H__\r
+\r
+#include "lwip/opt.h"\r
+#include "lwip/pbuf.h"\r
+#include "lwip/sys.h"\r
+\r
+#include "lwip/ip.h"\r
+\r
+#include "lwip/udp.h"\r
+#include "lwip/tcp.h"\r
+\r
+#include "lwip/api.h"\r
+\r
+enum api_msg_type {\r
+  API_MSG_NEWCONN,\r
+  API_MSG_DELCONN,\r
+  \r
+  API_MSG_BIND,\r
+  API_MSG_CONNECT,\r
+  API_MSG_DISCONNECT,\r
+\r
+  API_MSG_LISTEN,\r
+  API_MSG_ACCEPT,\r
+\r
+  API_MSG_SEND,\r
+  API_MSG_RECV,\r
+  API_MSG_WRITE,\r
+\r
+  API_MSG_CLOSE,\r
+  \r
+  API_MSG_MAX\r
+};\r
+\r
+struct api_msg_msg {\r
+  struct netconn *conn;\r
+  enum netconn_type conntype;\r
+  union {\r
+    struct pbuf *p;   \r
+    struct  {\r
+      struct ip_addr *ipaddr;\r
+      u16_t port;\r
+    } bc;\r
+    struct {\r
+      void *dataptr;\r
+      u16_t len;\r
+      u8_t copy;\r
+    } w;    \r
+    sys_mbox_t mbox;\r
+    u16_t len;\r
+  } msg;\r
+};\r
+\r
+struct api_msg {\r
+  enum api_msg_type type;\r
+  struct api_msg_msg msg;\r
+};\r
+\r
+void api_msg_input(struct api_msg *msg);\r
+void api_msg_post(struct api_msg *msg);\r
+\r
+#endif /* __LWIP_API_MSG_H__ */\r
+\r
index e0d622a4b2b0442e57a174548c34d81c5ea5a63b..f5e10513fb44f5ebbd9d1469403e311981b19b0c 100644 (file)
-/*
- * 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 <adam@sics.se>
- *
- */
-#ifndef __LWIP_ARCH_H__
-#define __LWIP_ARCH_H__
-
-#ifndef LITTLE_ENDIAN
-#define LITTLE_ENDIAN 1234
-#endif
-
-#ifndef BIG_ENDIAN
-#define BIG_ENDIAN 4321
-#endif
-
-#include "arch/cc.h"
-
-#ifndef PACK_STRUCT_BEGIN
-#define PACK_STRUCT_BEGIN
-#endif /* PACK_STRUCT_BEGIN */
-
-#ifndef PACK_STRUCT_END
-#define PACK_STRUCT_END
-#endif /* PACK_STRUCT_END */
-
-#ifndef PACK_STRUCT_FIELD
-#define PACK_STRUCT_FIELD(x) x
-#endif /* PACK_STRUCT_FIELD */
-
-
-
-#ifdef LWIP_PROVIDE_ERRNO
-
-#define  EPERM     1  /* Operation not permitted */
-#define  ENOENT     2  /* No such file or directory */
-#define  ESRCH     3  /* No such process */
-#define  EINTR     4  /* Interrupted system call */
-#define  EIO     5  /* I/O error */
-#define  ENXIO     6  /* No such device or address */
-#define  E2BIG     7  /* Arg list too long */
-#define  ENOEXEC     8  /* Exec format error */
-#define  EBADF     9  /* Bad file number */
-#define  ECHILD    10  /* No child processes */
-#define  EAGAIN    11  /* Try again */
-#define  ENOMEM    12  /* Out of memory */
-#define  EACCES    13  /* Permission denied */
-#define  EFAULT    14  /* Bad address */
-#define  ENOTBLK    15  /* Block device required */
-#define  EBUSY    16  /* Device or resource busy */
-#define  EEXIST    17  /* File exists */
-#define  EXDEV    18  /* Cross-device link */
-#define  ENODEV    19  /* No such device */
-#define  ENOTDIR    20  /* Not a directory */
-#define  EISDIR    21  /* Is a directory */
-#define  EINVAL    22  /* Invalid argument */
-#define  ENFILE    23  /* File table overflow */
-#define  EMFILE    24  /* Too many open files */
-#define  ENOTTY    25  /* Not a typewriter */
-#define  ETXTBSY    26  /* Text file busy */
-#define  EFBIG    27  /* File too large */
-#define  ENOSPC    28  /* No space left on device */
-#define  ESPIPE    29  /* Illegal seek */
-#define  EROFS    30  /* Read-only file system */
-#define  EMLINK    31  /* Too many links */
-#define  EPIPE    32  /* Broken pipe */
-#define  EDOM    33  /* Math argument out of domain of func */
-#define  ERANGE    34  /* Math result not representable */
-#define  EDEADLK    35  /* Resource deadlock would occur */
-#define  ENAMETOOLONG  36  /* File name too long */
-#define  ENOLCK    37  /* No record locks available */
-#define  ENOSYS    38  /* Function not implemented */
-#define  ENOTEMPTY  39  /* Directory not empty */
-#define  ELOOP    40  /* Too many symbolic links encountered */
-#define  EWOULDBLOCK  EAGAIN  /* Operation would block */
-#define  ENOMSG    42  /* No message of desired type */
-#define  EIDRM    43  /* Identifier removed */
-#define  ECHRNG    44  /* Channel number out of range */
-#define  EL2NSYNC  45  /* Level 2 not synchronized */
-#define  EL3HLT    46  /* Level 3 halted */
-#define  EL3RST    47  /* Level 3 reset */
-#define  ELNRNG    48  /* Link number out of range */
-#define  EUNATCH    49  /* Protocol driver not attached */
-#define  ENOCSI    50  /* No CSI structure available */
-#define  EL2HLT    51  /* Level 2 halted */
-#define  EBADE    52  /* Invalid exchange */
-#define  EBADR    53  /* Invalid request descriptor */
-#define  EXFULL    54  /* Exchange full */
-#define  ENOANO    55  /* No anode */
-#define  EBADRQC    56  /* Invalid request code */
-#define  EBADSLT    57  /* Invalid slot */
-
-#define  EDEADLOCK  EDEADLK
-
-#define  EBFONT    59  /* Bad font file format */
-#define  ENOSTR    60  /* Device not a stream */
-#define  ENODATA    61  /* No data available */
-#define  ETIME    62  /* Timer expired */
-#define  ENOSR    63  /* Out of streams resources */
-#define  ENONET    64  /* Machine is not on the network */
-#define  ENOPKG    65  /* Package not installed */
-#define  EREMOTE    66  /* Object is remote */
-#define  ENOLINK    67  /* Link has been severed */
-#define  EADV    68  /* Advertise error */
-#define  ESRMNT    69  /* Srmount error */
-#define  ECOMM    70  /* Communication error on send */
-#define  EPROTO    71  /* Protocol error */
-#define  EMULTIHOP  72  /* Multihop attempted */
-#define  EDOTDOT    73  /* RFS specific error */
-#define  EBADMSG    74  /* Not a data message */
-#define  EOVERFLOW  75  /* Value too large for defined data type */
-#define  ENOTUNIQ  76  /* Name not unique on network */
-#define  EBADFD    77  /* File descriptor in bad state */
-#define  EREMCHG    78  /* Remote address changed */
-#define  ELIBACC    79  /* Can not access a needed shared library */
-#define  ELIBBAD    80  /* Accessing a corrupted shared library */
-#define  ELIBSCN    81  /* .lib section in a.out corrupted */
-#define  ELIBMAX    82  /* Attempting to link in too many shared libraries */
-#define  ELIBEXEC  83  /* Cannot exec a shared library directly */
-#define  EILSEQ    84  /* Illegal byte sequence */
-#define  ERESTART  85  /* Interrupted system call should be restarted */
-#define  ESTRPIPE  86  /* Streams pipe error */
-#define  EUSERS    87  /* Too many users */
-#define  ENOTSOCK  88  /* Socket operation on non-socket */
-#define  EDESTADDRREQ  89  /* Destination address required */
-#define  EMSGSIZE  90  /* Message too long */
-#define  EPROTOTYPE  91  /* Protocol wrong type for socket */
-#define  ENOPROTOOPT  92  /* Protocol not available */
-#define  EPROTONOSUPPORT  93  /* Protocol not supported */
-#define  ESOCKTNOSUPPORT  94  /* Socket type not supported */
-#define  EOPNOTSUPP  95  /* Operation not supported on transport endpoint */
-#define  EPFNOSUPPORT  96  /* Protocol family not supported */
-#define  EAFNOSUPPORT  97  /* Address family not supported by protocol */
-#define  EADDRINUSE  98  /* Address already in use */
-#define  EADDRNOTAVAIL  99  /* Cannot assign requested address */
-#define  ENETDOWN  100  /* Network is down */
-#define  ENETUNREACH  101  /* Network is unreachable */
-#define  ENETRESET  102  /* Network dropped connection because of reset */
-#define  ECONNABORTED  103  /* Software caused connection abort */
-#define  ECONNRESET  104  /* Connection reset by peer */
-#define  ENOBUFS    105  /* No buffer space available */
-#define  EISCONN    106  /* Transport endpoint is already connected */
-#define  ENOTCONN  107  /* Transport endpoint is not connected */
-#define  ESHUTDOWN  108  /* Cannot send after transport endpoint shutdown */
-#define  ETOOMANYREFS  109  /* Too many references: cannot splice */
-#define  ETIMEDOUT  110  /* Connection timed out */
-#define  ECONNREFUSED  111  /* Connection refused */
-#define  EHOSTDOWN  112  /* Host is down */
-#define  EHOSTUNREACH  113  /* No route to host */
-#define  EALREADY  114  /* Operation already in progress */
-#define  EINPROGRESS  115  /* Operation now in progress */
-#define  ESTALE    116  /* Stale NFS file handle */
-#define  EUCLEAN    117  /* Structure needs cleaning */
-#define  ENOTNAM    118  /* Not a XENIX named type file */
-#define  ENAVAIL    119  /* No XENIX semaphores available */
-#define  EISNAM    120  /* Is a named type file */
-#define  EREMOTEIO  121  /* Remote I/O error */
-#define  EDQUOT    122  /* Quota exceeded */
-
-#define  ENOMEDIUM  123  /* No medium found */
-#define  EMEDIUMTYPE  124  /* Wrong medium type */
-
-
-#define        ENSROK          0       /* DNS server returned answer with no data */
-#define        ENSRNODATA      160     /* DNS server returned answer with no data */
-#define        ENSRFORMERR     161     /* DNS server claims query was misformatted */
-#define        ENSRSERVFAIL 162        /* DNS server returned general failure */
-#define        ENSRNOTFOUND 163        /* Domain name not found */
-#define        ENSRNOTIMP      164     /* DNS server does not implement requested operation */
-#define        ENSRREFUSED     165     /* DNS server refused query */
-#define        ENSRBADQUERY 166        /* Misformatted DNS query */
-#define        ENSRBADNAME     167     /* Misformatted domain name */
-#define        ENSRBADFAMILY 168       /* Unsupported address family */
-#define        ENSRBADRESP     169     /* Misformatted DNS reply */
-#define        ENSRCONNREFUSED 170     /* Could not contact DNS servers */
-#define        ENSRTIMEOUT     171     /* Timeout while contacting DNS servers */
-#define        ENSROF          172     /* End of file */
-#define        ENSRFILE        173     /* Error reading file */
-#define        ENSRNOMEM       174     /* Out of memory */
-#define        ENSRDESTRUCTION 175     /* Application terminated lookup */
-#define        ENSRQUERYDOMAINTOOLONG  176     /* Domain name is too long */
-#define        ENSRCNAMELOOP   177     /* Domain name is too long */
-
-#ifndef errno
-extern int errno;
-#endif
-
-#endif /* LWIP_PROVIDE_ERRNO */
-
-#endif /* __LWIP_ARCH_H__ */
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+#ifndef __LWIP_ARCH_H__\r
+#define __LWIP_ARCH_H__\r
+\r
+#ifndef LITTLE_ENDIAN\r
+#define LITTLE_ENDIAN 1234\r
+#endif\r
+\r
+#ifndef BIG_ENDIAN\r
+#define BIG_ENDIAN 4321\r
+#endif\r
+\r
+#include "arch/cc.h"\r
+\r
+#ifndef PACK_STRUCT_BEGIN\r
+#define PACK_STRUCT_BEGIN\r
+#endif /* PACK_STRUCT_BEGIN */\r
+\r
+#ifndef PACK_STRUCT_END\r
+#define PACK_STRUCT_END\r
+#endif /* PACK_STRUCT_END */\r
+\r
+#ifndef PACK_STRUCT_FIELD\r
+#define PACK_STRUCT_FIELD(x) x\r
+#endif /* PACK_STRUCT_FIELD */\r
+\r
+\r
+\r
+#ifdef LWIP_PROVIDE_ERRNO\r
+\r
+#define  EPERM     1  /* Operation not permitted */\r
+#define  ENOENT     2  /* No such file or directory */\r
+#define  ESRCH     3  /* No such process */\r
+#define  EINTR     4  /* Interrupted system call */\r
+#define  EIO     5  /* I/O error */\r
+#define  ENXIO     6  /* No such device or address */\r
+#define  E2BIG     7  /* Arg list too long */\r
+#define  ENOEXEC     8  /* Exec format error */\r
+#define  EBADF     9  /* Bad file number */\r
+#define  ECHILD    10  /* No child processes */\r
+#define  EAGAIN    11  /* Try again */\r
+#define  ENOMEM    12  /* Out of memory */\r
+#define  EACCES    13  /* Permission denied */\r
+#define  EFAULT    14  /* Bad address */\r
+#define  ENOTBLK    15  /* Block device required */\r
+#define  EBUSY    16  /* Device or resource busy */\r
+#define  EEXIST    17  /* File exists */\r
+#define  EXDEV    18  /* Cross-device link */\r
+#define  ENODEV    19  /* No such device */\r
+#define  ENOTDIR    20  /* Not a directory */\r
+#define  EISDIR    21  /* Is a directory */\r
+#define  EINVAL    22  /* Invalid argument */\r
+#define  ENFILE    23  /* File table overflow */\r
+#define  EMFILE    24  /* Too many open files */\r
+#define  ENOTTY    25  /* Not a typewriter */\r
+#define  ETXTBSY    26  /* Text file busy */\r
+#define  EFBIG    27  /* File too large */\r
+#define  ENOSPC    28  /* No space left on device */\r
+#define  ESPIPE    29  /* Illegal seek */\r
+#define  EROFS    30  /* Read-only file system */\r
+#define  EMLINK    31  /* Too many links */\r
+#define  EPIPE    32  /* Broken pipe */\r
+#define  EDOM    33  /* Math argument out of domain of func */\r
+#define  ERANGE    34  /* Math result not representable */\r
+#define  EDEADLK    35  /* Resource deadlock would occur */\r
+#define  ENAMETOOLONG  36  /* File name too long */\r
+#define  ENOLCK    37  /* No record locks available */\r
+#define  ENOSYS    38  /* Function not implemented */\r
+#define  ENOTEMPTY  39  /* Directory not empty */\r
+#define  ELOOP    40  /* Too many symbolic links encountered */\r
+#define  EWOULDBLOCK  EAGAIN  /* Operation would block */\r
+#define  ENOMSG    42  /* No message of desired type */\r
+#define  EIDRM    43  /* Identifier removed */\r
+#define  ECHRNG    44  /* Channel number out of range */\r
+#define  EL2NSYNC  45  /* Level 2 not synchronized */\r
+#define  EL3HLT    46  /* Level 3 halted */\r
+#define  EL3RST    47  /* Level 3 reset */\r
+#define  ELNRNG    48  /* Link number out of range */\r
+#define  EUNATCH    49  /* Protocol driver not attached */\r
+#define  ENOCSI    50  /* No CSI structure available */\r
+#define  EL2HLT    51  /* Level 2 halted */\r
+#define  EBADE    52  /* Invalid exchange */\r
+#define  EBADR    53  /* Invalid request descriptor */\r
+#define  EXFULL    54  /* Exchange full */\r
+#define  ENOANO    55  /* No anode */\r
+#define  EBADRQC    56  /* Invalid request code */\r
+#define  EBADSLT    57  /* Invalid slot */\r
+\r
+#define  EDEADLOCK  EDEADLK\r
+\r
+#define  EBFONT    59  /* Bad font file format */\r
+#define  ENOSTR    60  /* Device not a stream */\r
+#define  ENODATA    61  /* No data available */\r
+#define  ETIME    62  /* Timer expired */\r
+#define  ENOSR    63  /* Out of streams resources */\r
+#define  ENONET    64  /* Machine is not on the network */\r
+#define  ENOPKG    65  /* Package not installed */\r
+#define  EREMOTE    66  /* Object is remote */\r
+#define  ENOLINK    67  /* Link has been severed */\r
+#define  EADV    68  /* Advertise error */\r
+#define  ESRMNT    69  /* Srmount error */\r
+#define  ECOMM    70  /* Communication error on send */\r
+#define  EPROTO    71  /* Protocol error */\r
+#define  EMULTIHOP  72  /* Multihop attempted */\r
+#define  EDOTDOT    73  /* RFS specific error */\r
+#define  EBADMSG    74  /* Not a data message */\r
+#define  EOVERFLOW  75  /* Value too large for defined data type */\r
+#define  ENOTUNIQ  76  /* Name not unique on network */\r
+#define  EBADFD    77  /* File descriptor in bad state */\r
+#define  EREMCHG    78  /* Remote address changed */\r
+#define  ELIBACC    79  /* Can not access a needed shared library */\r
+#define  ELIBBAD    80  /* Accessing a corrupted shared library */\r
+#define  ELIBSCN    81  /* .lib section in a.out corrupted */\r
+#define  ELIBMAX    82  /* Attempting to link in too many shared libraries */\r
+#define  ELIBEXEC  83  /* Cannot exec a shared library directly */\r
+#define  EILSEQ    84  /* Illegal byte sequence */\r
+#define  ERESTART  85  /* Interrupted system call should be restarted */\r
+#define  ESTRPIPE  86  /* Streams pipe error */\r
+#define  EUSERS    87  /* Too many users */\r
+#define  ENOTSOCK  88  /* Socket operation on non-socket */\r
+#define  EDESTADDRREQ  89  /* Destination address required */\r
+#define  EMSGSIZE  90  /* Message too long */\r
+#define  EPROTOTYPE  91  /* Protocol wrong type for socket */\r
+#define  ENOPROTOOPT  92  /* Protocol not available */\r
+#define  EPROTONOSUPPORT  93  /* Protocol not supported */\r
+#define  ESOCKTNOSUPPORT  94  /* Socket type not supported */\r
+#define  EOPNOTSUPP  95  /* Operation not supported on transport endpoint */\r
+#define  EPFNOSUPPORT  96  /* Protocol family not supported */\r
+#define  EAFNOSUPPORT  97  /* Address family not supported by protocol */\r
+#define  EADDRINUSE  98  /* Address already in use */\r
+#define  EADDRNOTAVAIL  99  /* Cannot assign requested address */\r
+#define  ENETDOWN  100  /* Network is down */\r
+#define  ENETUNREACH  101  /* Network is unreachable */\r
+#define  ENETRESET  102  /* Network dropped connection because of reset */\r
+#define  ECONNABORTED  103  /* Software caused connection abort */\r
+#define  ECONNRESET  104  /* Connection reset by peer */\r
+#define  ENOBUFS    105  /* No buffer space available */\r
+#define  EISCONN    106  /* Transport endpoint is already connected */\r
+#define  ENOTCONN  107  /* Transport endpoint is not connected */\r
+#define  ESHUTDOWN  108  /* Cannot send after transport endpoint shutdown */\r
+#define  ETOOMANYREFS  109  /* Too many references: cannot splice */\r
+#define  ETIMEDOUT  110  /* Connection timed out */\r
+#define  ECONNREFUSED  111  /* Connection refused */\r
+#define  EHOSTDOWN  112  /* Host is down */\r
+#define  EHOSTUNREACH  113  /* No route to host */\r
+#define  EALREADY  114  /* Operation already in progress */\r
+#define  EINPROGRESS  115  /* Operation now in progress */\r
+#define  ESTALE    116  /* Stale NFS file handle */\r
+#define  EUCLEAN    117  /* Structure needs cleaning */\r
+#define  ENOTNAM    118  /* Not a XENIX named type file */\r
+#define  ENAVAIL    119  /* No XENIX semaphores available */\r
+#define  EISNAM    120  /* Is a named type file */\r
+#define  EREMOTEIO  121  /* Remote I/O error */\r
+#define  EDQUOT    122  /* Quota exceeded */\r
+\r
+#define  ENOMEDIUM  123  /* No medium found */\r
+#define  EMEDIUMTYPE  124  /* Wrong medium type */\r
+\r
+\r
+#define        ENSROK          0       /* DNS server returned answer with no data */\r
+#define        ENSRNODATA      160     /* DNS server returned answer with no data */\r
+#define        ENSRFORMERR     161     /* DNS server claims query was misformatted */\r
+#define        ENSRSERVFAIL 162        /* DNS server returned general failure */\r
+#define        ENSRNOTFOUND 163        /* Domain name not found */\r
+#define        ENSRNOTIMP      164     /* DNS server does not implement requested operation */\r
+#define        ENSRREFUSED     165     /* DNS server refused query */\r
+#define        ENSRBADQUERY 166        /* Misformatted DNS query */\r
+#define        ENSRBADNAME     167     /* Misformatted domain name */\r
+#define        ENSRBADFAMILY 168       /* Unsupported address family */\r
+#define        ENSRBADRESP     169     /* Misformatted DNS reply */\r
+#define        ENSRCONNREFUSED 170     /* Could not contact DNS servers */\r
+#define        ENSRTIMEOUT     171     /* Timeout while contacting DNS servers */\r
+#define        ENSROF          172     /* End of file */\r
+#define        ENSRFILE        173     /* Error reading file */\r
+#define        ENSRNOMEM       174     /* Out of memory */\r
+#define        ENSRDESTRUCTION 175     /* Application terminated lookup */\r
+#define        ENSRQUERYDOMAINTOOLONG  176     /* Domain name is too long */\r
+#define        ENSRCNAMELOOP   177     /* Domain name is too long */\r
+\r
+#ifndef errno\r
+extern int errno;\r
+#endif\r
+\r
+#endif /* LWIP_PROVIDE_ERRNO */\r
+\r
+#endif /* __LWIP_ARCH_H__ */\r
index 8f63a7b625e736543a98961a9a60f3ec4367ea04..3649cbd6ce4b13c73174beda8003d7dc7297741b 100644 (file)
@@ -1,87 +1,87 @@
-/*
- * 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 <adam@sics.se>
- *
- */
-#ifndef __LWIP_DEBUG_H__
-#define __LWIP_DEBUG_H__
-
-#include "arch/cc.h"
-
-/** lower two bits indicate debug level
- * - 0 off
- * - 1 warning
- * - 2 serious
- * - 3 severe
- */
-
-#define DBG_LEVEL_OFF     0
-#define DBG_LEVEL_WARNING 1  /* bad checksums, dropped packets, ... */
-#define DBG_LEVEL_SERIOUS 2  /* memory allocation failures, ... */
-#define DBG_LEVEL_SEVERE  3  /* */ 
-#define DBG_MASK_LEVEL    3
-
-/** flag for LWIP_DEBUGF to enable that debug message */
-#define DBG_ON  0x80U
-/** flag for LWIP_DEBUGF to disable that debug message */
-#define DBG_OFF 0x00U
-
-/** flag for LWIP_DEBUGF indicating a tracing message (to follow program flow) */
-#define DBG_TRACE   0x40U
-/** flag for LWIP_DEBUGF indicating a state debug message (to follow module states) */
-#define DBG_STATE   0x20U
-/** flag for LWIP_DEBUGF indicating newly added code, not thoroughly tested yet */
-#define DBG_FRESH   0x10U
-/** flag for LWIP_DEBUGF to halt after printing this debug message */
-#define DBG_HALT    0x08U
-
-#ifndef LWIP_NOASSERT
-#  define LWIP_ASSERT(x,y) do { if(!(y)) LWIP_PLATFORM_ASSERT(x); } while(0)
-#else
-#  define LWIP_ASSERT(x,y) 
-#endif
-
-#ifdef LWIP_DEBUG
-/** print debug message only if debug message type is enabled...
- *  AND is of correct type AND is at least DBG_LEVEL
- */
-#  define LWIP_DEBUGF(debug,x) do { if (((debug) & DBG_ON) && ((debug) & DBG_TYPES_ON) && ((s16_t)((debug) & DBG_MASK_LEVEL) >= DBG_MIN_LEVEL)) { LWIP_PLATFORM_DIAG(x); if ((debug) & DBG_HALT) while(1); } } while(0)
-#  define LWIP_ERROR(x)   do { LWIP_PLATFORM_DIAG(x); } while(0)  
-#else /* LWIP_DEBUG */
-#  define LWIP_DEBUGF(debug,x) 
-#  define LWIP_ERROR(x)  
-#endif /* LWIP_DEBUG */
-
-#endif /* __LWIP_DEBUG_H__ */
-
-
-
-
-
-
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+#ifndef __LWIP_DEBUG_H__\r
+#define __LWIP_DEBUG_H__\r
+\r
+#include "arch/cc.h"\r
+\r
+/** lower two bits indicate debug level\r
+ * - 0 off\r
+ * - 1 warning\r
+ * - 2 serious\r
+ * - 3 severe\r
+ */\r
+\r
+#define DBG_LEVEL_OFF     0\r
+#define DBG_LEVEL_WARNING 1  /* bad checksums, dropped packets, ... */\r
+#define DBG_LEVEL_SERIOUS 2  /* memory allocation failures, ... */\r
+#define DBG_LEVEL_SEVERE  3  /* */ \r
+#define DBG_MASK_LEVEL    3\r
+\r
+/** flag for LWIP_DEBUGF to enable that debug message */\r
+#define DBG_ON  0x80U\r
+/** flag for LWIP_DEBUGF to disable that debug message */\r
+#define DBG_OFF 0x00U\r
+\r
+/** flag for LWIP_DEBUGF indicating a tracing message (to follow program flow) */\r
+#define DBG_TRACE   0x40U\r
+/** flag for LWIP_DEBUGF indicating a state debug message (to follow module states) */\r
+#define DBG_STATE   0x20U\r
+/** flag for LWIP_DEBUGF indicating newly added code, not thoroughly tested yet */\r
+#define DBG_FRESH   0x10U\r
+/** flag for LWIP_DEBUGF to halt after printing this debug message */\r
+#define DBG_HALT    0x08U\r
+\r
+#ifndef LWIP_NOASSERT\r
+#  define LWIP_ASSERT(x,y) do { if(!(y)) LWIP_PLATFORM_ASSERT(x); } while(0)\r
+#else\r
+#  define LWIP_ASSERT(x,y) \r
+#endif\r
+\r
+#ifdef LWIP_DEBUG\r
+/** print debug message only if debug message type is enabled...\r
+ *  AND is of correct type AND is at least DBG_LEVEL\r
+ */\r
+#  define LWIP_DEBUGF(debug,x) do { if (((debug) & DBG_ON) && ((debug) & DBG_TYPES_ON) && ((s16_t)((debug) & DBG_MASK_LEVEL) >= DBG_MIN_LEVEL)) { LWIP_PLATFORM_DIAG(x); if ((debug) & DBG_HALT) while(1); } } while(0)\r
+#  define LWIP_ERROR(x)   do { LWIP_PLATFORM_DIAG(x); } while(0)  \r
+#else /* LWIP_DEBUG */\r
+#  define LWIP_DEBUGF(debug,x) \r
+#  define LWIP_ERROR(x)  \r
+#endif /* LWIP_DEBUG */\r
+\r
+#endif /* __LWIP_DEBUG_H__ */\r
+\r
+\r
+\r
+\r
+\r
+\r
index eba9b8774dbbb8ed834f113bb9d42a6365de63a5..f26bdd0406f74b773e1f19e20d3ddafb5a40c875 100644 (file)
@@ -1,47 +1,47 @@
-/*
- * 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 <adam@sics.se>
- *
- */
-#ifndef __LWIP_DEF_H__
-#define __LWIP_DEF_H__
-
-/* this might define NULL already */
-#include "arch/cc.h"
-
-#define LWIP_MAX(x , y)  (x) > (y) ? (x) : (y)
-#define LWIP_MIN(x , y)  (x) < (y) ? (x) : (y)
-
-#ifndef NULL
-#define NULL ((void *)0)
-#endif
-
-
-#endif /* __LWIP_DEF_H__ */
-
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+#ifndef __LWIP_DEF_H__\r
+#define __LWIP_DEF_H__\r
+\r
+/* this might define NULL already */\r
+#include "arch/cc.h"\r
+\r
+#define LWIP_MAX(x , y)  (x) > (y) ? (x) : (y)\r
+#define LWIP_MIN(x , y)  (x) < (y) ? (x) : (y)\r
+\r
+#ifndef NULL\r
+#define NULL ((void *)0)\r
+#endif\r
+\r
+\r
+#endif /* __LWIP_DEF_H__ */\r
+\r
index bfe753f26a8bd2bdb7c9abe6dd6d349ff57aeddd..df51bdc96e5cf64ee6f2b098a63419ac0b2bf9e9 100644 (file)
-/** @file
- */
-
-#ifndef __LWIP_DHCP_H__
-#define __LWIP_DHCP_H__
-
-#include "lwip/opt.h"
-#include "lwip/netif.h"
-#include "lwip/udp.h"
-
-/** period (in seconds) of the application calling dhcp_coarse_tmr() */
-#define DHCP_COARSE_TIMER_SECS 60 
-/** period (in milliseconds) of the application calling dhcp_fine_tmr() */
-#define DHCP_FINE_TIMER_MSECS 500 
-
-struct dhcp
-{
-  /** current DHCP state machine state */
-  u8_t state;
-  /** retries of current request */
-  u8_t tries;
-  /** transaction identifier of last sent request */ 
-  u32_t xid;
-  /** our connection to the DHCP server */ 
-  struct udp_pcb *pcb;
-  /** (first) pbuf of incoming msg */
-  struct pbuf *p;
-  /** incoming msg */
-  struct dhcp_msg *msg_in;
-  /** incoming msg options */
-  struct dhcp_msg *options_in; 
-  /** ingoing msg options length */
-  u16_t options_in_len;
-
-  struct pbuf *p_out; /* pbuf of outcoming msg */
-  struct dhcp_msg *msg_out; /* outgoing msg */
-  u16_t options_out_len; /* outgoing msg options length */
-  u16_t request_timeout; /* #ticks with period DHCP_FINE_TIMER_SECS for request timeout */
-  u16_t t1_timeout;  /* #ticks with period DHCP_COARSE_TIMER_SECS for renewal time */
-  u16_t t2_timeout;  /* #ticks with period DHCP_COARSE_TIMER_SECS for rebind time */
-  struct ip_addr server_ip_addr; /* dhcp server address that offered this lease */
-  struct ip_addr offered_ip_addr;
-  struct ip_addr offered_sn_mask;
-  struct ip_addr offered_gw_addr;
-  struct ip_addr offered_bc_addr;
-#define DHCP_MAX_DNS 2
-  u32_t dns_count; /* actual number of DNS servers obtained */
-  struct ip_addr offered_dns_addr[DHCP_MAX_DNS]; /* DNS server addresses */
-  u32_t offered_t0_lease; /* lease period (in seconds) */
-  u32_t offered_t1_renew; /* recommended renew time (usually 50% of lease period) */
-  u32_t offered_t2_rebind; /* recommended rebind time (usually 66% of lease period)  */
-/** Patch #1308
- *  TODO: See dhcp.c "TODO"s
- */
-#if 0
-  struct ip_addr offered_si_addr;
-  u8_t *boot_file_name;
-#endif
-};
-
-/* MUST be compiled with "pack structs" or equivalent! */
-#ifdef PACK_STRUCT_USE_INCLUDES
-#  include "arch/bpstruct.h"
-#endif
-PACK_STRUCT_BEGIN
-/** minimum set of fields of any DHCP message */
-struct dhcp_msg
-{
-  PACK_STRUCT_FIELD(u8_t op);
-  PACK_STRUCT_FIELD(u8_t htype);
-  PACK_STRUCT_FIELD(u8_t hlen);
-  PACK_STRUCT_FIELD(u8_t hops);
-  PACK_STRUCT_FIELD(u32_t xid);
-  PACK_STRUCT_FIELD(u16_t secs);
-  PACK_STRUCT_FIELD(u16_t flags);
-  PACK_STRUCT_FIELD(struct ip_addr ciaddr);
-  PACK_STRUCT_FIELD(struct ip_addr yiaddr);
-  PACK_STRUCT_FIELD(struct ip_addr siaddr);
-  PACK_STRUCT_FIELD(struct ip_addr giaddr);
-#define DHCP_CHADDR_LEN 16U
-  PACK_STRUCT_FIELD(u8_t chaddr[DHCP_CHADDR_LEN]);
-#define DHCP_SNAME_LEN 64U
-  PACK_STRUCT_FIELD(u8_t sname[DHCP_SNAME_LEN]);
-#define DHCP_FILE_LEN 128U
-  PACK_STRUCT_FIELD(u8_t file[DHCP_FILE_LEN]);
-  PACK_STRUCT_FIELD(u32_t cookie);
-#define DHCP_MIN_OPTIONS_LEN 68U
-/** make sure user does not configure this too small */
-#if ((defined(DHCP_OPTIONS_LEN)) && (DHCP_OPTIONS_LEN < DHCP_MIN_OPTIONS_LEN))
-#  undef DHCP_OPTIONS_LEN
-#endif
-/** allow this to be configured in lwipopts.h, but not too small */
-#if (!defined(DHCP_OPTIONS_LEN))
-/** set this to be sufficient for your options in outgoing DHCP msgs */
-#  define DHCP_OPTIONS_LEN DHCP_MIN_OPTIONS_LEN
-#endif
-  PACK_STRUCT_FIELD(u8_t options[DHCP_OPTIONS_LEN]);
-} PACK_STRUCT_STRUCT;
-PACK_STRUCT_END
-#ifdef PACK_STRUCT_USE_INCLUDES
-#  include "arch/epstruct.h"
-#endif
-
-/** start DHCP configuration */
-err_t dhcp_start(struct netif *netif);
-/** enforce early lease renewal (not needed normally)*/
-err_t dhcp_renew(struct netif *netif);
-/** release the DHCP lease, usually called before dhcp_stop()*/
-err_t dhcp_release(struct netif *netif);
-/** stop DHCP configuration */
-void dhcp_stop(struct netif *netif);
-/** inform server of our manual IP address */
-void dhcp_inform(struct netif *netif);
-
-/** if enabled, check whether the offered IP address is not in use, using ARP */
-#if DHCP_DOES_ARP_CHECK
-void dhcp_arp_reply(struct netif *netif, struct ip_addr *addr);
-#endif
-
-/** to be called every minute */
-void dhcp_coarse_tmr(void);
-/** to be called every half second */
-void dhcp_fine_tmr(void);
-/** DHCP message item offsets and length */
-#define DHCP_MSG_OFS (UDP_DATA_OFS)  
-  #define DHCP_OP_OFS (DHCP_MSG_OFS + 0)
-  #define DHCP_HTYPE_OFS (DHCP_MSG_OFS + 1)
-  #define DHCP_HLEN_OFS (DHCP_MSG_OFS + 2)
-  #define DHCP_HOPS_OFS (DHCP_MSG_OFS + 3)
-  #define DHCP_XID_OFS (DHCP_MSG_OFS + 4)
-  #define DHCP_SECS_OFS (DHCP_MSG_OFS + 8)
-  #define DHCP_FLAGS_OFS (DHCP_MSG_OFS + 10)
-  #define DHCP_CIADDR_OFS (DHCP_MSG_OFS + 12)
-  #define DHCP_YIADDR_OFS (DHCP_MSG_OFS + 16)
-  #define DHCP_SIADDR_OFS (DHCP_MSG_OFS + 20)
-  #define DHCP_GIADDR_OFS (DHCP_MSG_OFS + 24)
-  #define DHCP_CHADDR_OFS (DHCP_MSG_OFS + 28)
-  #define DHCP_SNAME_OFS (DHCP_MSG_OFS + 44)
-  #define DHCP_FILE_OFS (DHCP_MSG_OFS + 108)
-#define DHCP_MSG_LEN 236
-
-#define DHCP_COOKIE_OFS (DHCP_MSG_OFS + DHCP_MSG_LEN)
-#define DHCP_OPTIONS_OFS (DHCP_MSG_OFS + DHCP_MSG_LEN + 4)
-
-#define DHCP_CLIENT_PORT 68  
-#define DHCP_SERVER_PORT 67
-
-/** DHCP client states */
-#define DHCP_REQUESTING 1
-#define DHCP_INIT 2
-#define DHCP_REBOOTING 3
-#define DHCP_REBINDING 4
-#define DHCP_RENEWING 5
-#define DHCP_SELECTING 6
-#define DHCP_INFORMING 7
-#define DHCP_CHECKING 8
-#define DHCP_PERMANENT 9
-#define DHCP_BOUND 10
-/** not yet implemented #define DHCP_RELEASING 11 */
-#define DHCP_BACKING_OFF 12
-#define DHCP_OFF 13
-#define DHCP_BOOTREQUEST 1
-#define DHCP_BOOTREPLY 2
-
-#define DHCP_DISCOVER 1
-#define DHCP_OFFER 2
-#define DHCP_REQUEST 3
-#define DHCP_DECLINE 4
-#define DHCP_ACK 5
-#define DHCP_NAK 6
-#define DHCP_RELEASE 7
-#define DHCP_INFORM 8
-
-#define DHCP_HTYPE_ETH 1
-
-#define DHCP_HLEN_ETH 6
-
-#define DHCP_BROADCAST_FLAG 15
-#define DHCP_BROADCAST_MASK (1 << DHCP_FLAG_BROADCAST)
-
-/** BootP options */
-#define DHCP_OPTION_PAD 0
-#define DHCP_OPTION_SUBNET_MASK 1 /* RFC 2132 3.3 */
-#define DHCP_OPTION_ROUTER 3
-#define DHCP_OPTION_DNS_SERVER 6 
-#define DHCP_OPTION_HOSTNAME 12
-#define DHCP_OPTION_IP_TTL 23
-#define DHCP_OPTION_MTU 26
-#define DHCP_OPTION_BROADCAST 28
-#define DHCP_OPTION_TCP_TTL 37
-#define DHCP_OPTION_END 255
-
-/** DHCP options */
-#define DHCP_OPTION_REQUESTED_IP 50 /* RFC 2132 9.1, requested IP address */
-#define DHCP_OPTION_LEASE_TIME 51 /* RFC 2132 9.2, time in seconds, in 4 bytes */
-#define DHCP_OPTION_OVERLOAD 52 /* RFC2132 9.3, use file and/or sname field for options */
-
-#define DHCP_OPTION_MESSAGE_TYPE 53 /* RFC 2132 9.6, important for DHCP */
-#define DHCP_OPTION_MESSAGE_TYPE_LEN 1
-
-
-#define DHCP_OPTION_SERVER_ID 54 /* RFC 2132 9.7, server IP address */
-#define DHCP_OPTION_PARAMETER_REQUEST_LIST 55 /* RFC 2132 9.8, requested option types */
-
-#define DHCP_OPTION_MAX_MSG_SIZE 57 /* RFC 2132 9.10, message size accepted >= 576 */
-#define DHCP_OPTION_MAX_MSG_SIZE_LEN 2
-
-#define DHCP_OPTION_T1 58 /* T1 renewal time */
-#define DHCP_OPTION_T2 59 /* T2 rebinding time */
-#define DHCP_OPTION_CLIENT_ID 61
-#define DHCP_OPTION_TFTP_SERVERNAME 66
-#define DHCP_OPTION_BOOTFILE 67
-
-/** possible combinations of overloading the file and sname fields with options */
-#define DHCP_OVERLOAD_NONE 0
-#define DHCP_OVERLOAD_FILE 1
-#define DHCP_OVERLOAD_SNAME  2
-#define DHCP_OVERLOAD_SNAME_FILE 3
-
-#endif /*__LWIP_DHCP_H__*/
+/** @file\r
+ */\r
+\r
+#ifndef __LWIP_DHCP_H__\r
+#define __LWIP_DHCP_H__\r
+\r
+#include "lwip/opt.h"\r
+#include "lwip/netif.h"\r
+#include "lwip/udp.h"\r
+\r
+/** period (in seconds) of the application calling dhcp_coarse_tmr() */\r
+#define DHCP_COARSE_TIMER_SECS 60 \r
+/** period (in milliseconds) of the application calling dhcp_fine_tmr() */\r
+#define DHCP_FINE_TIMER_MSECS 500 \r
+\r
+struct dhcp\r
+{\r
+  /** current DHCP state machine state */\r
+  u8_t state;\r
+  /** retries of current request */\r
+  u8_t tries;\r
+  /** transaction identifier of last sent request */ \r
+  u32_t xid;\r
+  /** our connection to the DHCP server */ \r
+  struct udp_pcb *pcb;\r
+  /** (first) pbuf of incoming msg */\r
+  struct pbuf *p;\r
+  /** incoming msg */\r
+  struct dhcp_msg *msg_in;\r
+  /** incoming msg options */\r
+  struct dhcp_msg *options_in; \r
+  /** ingoing msg options length */\r
+  u16_t options_in_len;\r
+\r
+  struct pbuf *p_out; /* pbuf of outcoming msg */\r
+  struct dhcp_msg *msg_out; /* outgoing msg */\r
+  u16_t options_out_len; /* outgoing msg options length */\r
+  u16_t request_timeout; /* #ticks with period DHCP_FINE_TIMER_SECS for request timeout */\r
+  u16_t t1_timeout;  /* #ticks with period DHCP_COARSE_TIMER_SECS for renewal time */\r
+  u16_t t2_timeout;  /* #ticks with period DHCP_COARSE_TIMER_SECS for rebind time */\r
+  struct ip_addr server_ip_addr; /* dhcp server address that offered this lease */\r
+  struct ip_addr offered_ip_addr;\r
+  struct ip_addr offered_sn_mask;\r
+  struct ip_addr offered_gw_addr;\r
+  struct ip_addr offered_bc_addr;\r
+#define DHCP_MAX_DNS 2\r
+  u32_t dns_count; /* actual number of DNS servers obtained */\r
+  struct ip_addr offered_dns_addr[DHCP_MAX_DNS]; /* DNS server addresses */\r
\r
+  u32_t offered_t0_lease; /* lease period (in seconds) */\r
+  u32_t offered_t1_renew; /* recommended renew time (usually 50% of lease period) */\r
+  u32_t offered_t2_rebind; /* recommended rebind time (usually 66% of lease period)  */\r
+/** Patch #1308\r
+ *  TODO: See dhcp.c "TODO"s\r
+ */\r
+#if 0\r
+  struct ip_addr offered_si_addr;\r
+  u8_t *boot_file_name;\r
+#endif\r
+};\r
+\r
+/* MUST be compiled with "pack structs" or equivalent! */\r
+#ifdef PACK_STRUCT_USE_INCLUDES\r
+#  include "arch/bpstruct.h"\r
+#endif\r
+PACK_STRUCT_BEGIN\r
+/** minimum set of fields of any DHCP message */\r
+struct dhcp_msg\r
+{\r
+  PACK_STRUCT_FIELD(u8_t op);\r
+  PACK_STRUCT_FIELD(u8_t htype);\r
+  PACK_STRUCT_FIELD(u8_t hlen);\r
+  PACK_STRUCT_FIELD(u8_t hops);\r
+  PACK_STRUCT_FIELD(u32_t xid);\r
+  PACK_STRUCT_FIELD(u16_t secs);\r
+  PACK_STRUCT_FIELD(u16_t flags);\r
+  PACK_STRUCT_FIELD(struct ip_addr ciaddr);\r
+  PACK_STRUCT_FIELD(struct ip_addr yiaddr);\r
+  PACK_STRUCT_FIELD(struct ip_addr siaddr);\r
+  PACK_STRUCT_FIELD(struct ip_addr giaddr);\r
+#define DHCP_CHADDR_LEN 16U\r
+  PACK_STRUCT_FIELD(u8_t chaddr[DHCP_CHADDR_LEN]);\r
+#define DHCP_SNAME_LEN 64U\r
+  PACK_STRUCT_FIELD(u8_t sname[DHCP_SNAME_LEN]);\r
+#define DHCP_FILE_LEN 128U\r
+  PACK_STRUCT_FIELD(u8_t file[DHCP_FILE_LEN]);\r
+  PACK_STRUCT_FIELD(u32_t cookie);\r
+#define DHCP_MIN_OPTIONS_LEN 68U\r
+/** make sure user does not configure this too small */\r
+#if ((defined(DHCP_OPTIONS_LEN)) && (DHCP_OPTIONS_LEN < DHCP_MIN_OPTIONS_LEN))\r
+#  undef DHCP_OPTIONS_LEN\r
+#endif\r
+/** allow this to be configured in lwipopts.h, but not too small */\r
+#if (!defined(DHCP_OPTIONS_LEN))\r
+/** set this to be sufficient for your options in outgoing DHCP msgs */\r
+#  define DHCP_OPTIONS_LEN DHCP_MIN_OPTIONS_LEN\r
+#endif\r
+  PACK_STRUCT_FIELD(u8_t options[DHCP_OPTIONS_LEN]);\r
+} PACK_STRUCT_STRUCT;\r
+PACK_STRUCT_END\r
+#ifdef PACK_STRUCT_USE_INCLUDES\r
+#  include "arch/epstruct.h"\r
+#endif\r
+\r
+/** start DHCP configuration */\r
+err_t dhcp_start(struct netif *netif);\r
+/** enforce early lease renewal (not needed normally)*/\r
+err_t dhcp_renew(struct netif *netif);\r
+/** release the DHCP lease, usually called before dhcp_stop()*/\r
+err_t dhcp_release(struct netif *netif);\r
+/** stop DHCP configuration */\r
+void dhcp_stop(struct netif *netif);\r
+/** inform server of our manual IP address */\r
+void dhcp_inform(struct netif *netif);\r
+\r
+/** if enabled, check whether the offered IP address is not in use, using ARP */\r
+#if DHCP_DOES_ARP_CHECK\r
+void dhcp_arp_reply(struct netif *netif, struct ip_addr *addr);\r
+#endif\r
+\r
+/** to be called every minute */\r
+void dhcp_coarse_tmr(void);\r
+/** to be called every half second */\r
+void dhcp_fine_tmr(void);\r
\r
+/** DHCP message item offsets and length */\r
+#define DHCP_MSG_OFS (UDP_DATA_OFS)  \r
+  #define DHCP_OP_OFS (DHCP_MSG_OFS + 0)\r
+  #define DHCP_HTYPE_OFS (DHCP_MSG_OFS + 1)\r
+  #define DHCP_HLEN_OFS (DHCP_MSG_OFS + 2)\r
+  #define DHCP_HOPS_OFS (DHCP_MSG_OFS + 3)\r
+  #define DHCP_XID_OFS (DHCP_MSG_OFS + 4)\r
+  #define DHCP_SECS_OFS (DHCP_MSG_OFS + 8)\r
+  #define DHCP_FLAGS_OFS (DHCP_MSG_OFS + 10)\r
+  #define DHCP_CIADDR_OFS (DHCP_MSG_OFS + 12)\r
+  #define DHCP_YIADDR_OFS (DHCP_MSG_OFS + 16)\r
+  #define DHCP_SIADDR_OFS (DHCP_MSG_OFS + 20)\r
+  #define DHCP_GIADDR_OFS (DHCP_MSG_OFS + 24)\r
+  #define DHCP_CHADDR_OFS (DHCP_MSG_OFS + 28)\r
+  #define DHCP_SNAME_OFS (DHCP_MSG_OFS + 44)\r
+  #define DHCP_FILE_OFS (DHCP_MSG_OFS + 108)\r
+#define DHCP_MSG_LEN 236\r
+\r
+#define DHCP_COOKIE_OFS (DHCP_MSG_OFS + DHCP_MSG_LEN)\r
+#define DHCP_OPTIONS_OFS (DHCP_MSG_OFS + DHCP_MSG_LEN + 4)\r
+\r
+#define DHCP_CLIENT_PORT 68  \r
+#define DHCP_SERVER_PORT 67\r
+\r
+/** DHCP client states */\r
+#define DHCP_REQUESTING 1\r
+#define DHCP_INIT 2\r
+#define DHCP_REBOOTING 3\r
+#define DHCP_REBINDING 4\r
+#define DHCP_RENEWING 5\r
+#define DHCP_SELECTING 6\r
+#define DHCP_INFORMING 7\r
+#define DHCP_CHECKING 8\r
+#define DHCP_PERMANENT 9\r
+#define DHCP_BOUND 10\r
+/** not yet implemented #define DHCP_RELEASING 11 */\r
+#define DHCP_BACKING_OFF 12\r
+#define DHCP_OFF 13\r
\r
+#define DHCP_BOOTREQUEST 1\r
+#define DHCP_BOOTREPLY 2\r
+\r
+#define DHCP_DISCOVER 1\r
+#define DHCP_OFFER 2\r
+#define DHCP_REQUEST 3\r
+#define DHCP_DECLINE 4\r
+#define DHCP_ACK 5\r
+#define DHCP_NAK 6\r
+#define DHCP_RELEASE 7\r
+#define DHCP_INFORM 8\r
+\r
+#define DHCP_HTYPE_ETH 1\r
+\r
+#define DHCP_HLEN_ETH 6\r
+\r
+#define DHCP_BROADCAST_FLAG 15\r
+#define DHCP_BROADCAST_MASK (1 << DHCP_FLAG_BROADCAST)\r
+\r
+/** BootP options */\r
+#define DHCP_OPTION_PAD 0\r
+#define DHCP_OPTION_SUBNET_MASK 1 /* RFC 2132 3.3 */\r
+#define DHCP_OPTION_ROUTER 3\r
+#define DHCP_OPTION_DNS_SERVER 6 \r
+#define DHCP_OPTION_HOSTNAME 12\r
+#define DHCP_OPTION_IP_TTL 23\r
+#define DHCP_OPTION_MTU 26\r
+#define DHCP_OPTION_BROADCAST 28\r
+#define DHCP_OPTION_TCP_TTL 37\r
+#define DHCP_OPTION_END 255\r
+\r
+/** DHCP options */\r
+#define DHCP_OPTION_REQUESTED_IP 50 /* RFC 2132 9.1, requested IP address */\r
+#define DHCP_OPTION_LEASE_TIME 51 /* RFC 2132 9.2, time in seconds, in 4 bytes */\r
+#define DHCP_OPTION_OVERLOAD 52 /* RFC2132 9.3, use file and/or sname field for options */\r
+\r
+#define DHCP_OPTION_MESSAGE_TYPE 53 /* RFC 2132 9.6, important for DHCP */\r
+#define DHCP_OPTION_MESSAGE_TYPE_LEN 1\r
+\r
+\r
+#define DHCP_OPTION_SERVER_ID 54 /* RFC 2132 9.7, server IP address */\r
+#define DHCP_OPTION_PARAMETER_REQUEST_LIST 55 /* RFC 2132 9.8, requested option types */\r
+\r
+#define DHCP_OPTION_MAX_MSG_SIZE 57 /* RFC 2132 9.10, message size accepted >= 576 */\r
+#define DHCP_OPTION_MAX_MSG_SIZE_LEN 2\r
+\r
+#define DHCP_OPTION_T1 58 /* T1 renewal time */\r
+#define DHCP_OPTION_T2 59 /* T2 rebinding time */\r
+#define DHCP_OPTION_CLIENT_ID 61\r
+#define DHCP_OPTION_TFTP_SERVERNAME 66\r
+#define DHCP_OPTION_BOOTFILE 67\r
+\r
+/** possible combinations of overloading the file and sname fields with options */\r
+#define DHCP_OVERLOAD_NONE 0\r
+#define DHCP_OVERLOAD_FILE 1\r
+#define DHCP_OVERLOAD_SNAME  2\r
+#define DHCP_OVERLOAD_SNAME_FILE 3\r
+\r
+#endif /*__LWIP_DHCP_H__*/\r
index c92cb26d7693e422706442c74715fbdc939e1417..fc90f2eabadb9418db10aa6ff8c6d9437c096736 100644 (file)
@@ -1,70 +1,70 @@
-/*
- * 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 <adam@sics.se>
- *
- */
-#ifndef __LWIP_ERR_H__
-#define __LWIP_ERR_H__
-
-#include "lwip/opt.h"
-
-#include "arch/cc.h"
-
-typedef s8_t err_t;
-
-/* Definitions for error constants. */
-
-#define ERR_OK    0      /* No error, everything OK. */
-#define ERR_MEM  -1      /* Out of memory error.     */
-#define ERR_BUF  -2      /* Buffer error.            */
-
-
-#define ERR_ABRT -3      /* Connection aborted.      */
-#define ERR_RST  -4      /* Connection reset.        */
-#define ERR_CLSD -5      /* Connection closed.       */
-#define ERR_CONN -6      /* Not connected.           */
-
-#define ERR_VAL  -7      /* Illegal value.           */
-
-#define ERR_ARG  -8      /* Illegal argument.        */
-
-#define ERR_RTE  -9      /* Routing problem.         */
-
-#define ERR_USE  -10     /* Address in use.          */
-
-#define ERR_IF   -11     /* Low-level netif error    */
-#define ERR_ISCONN -12   /* Already connected.       */
-
-
-#ifdef LWIP_DEBUG
-extern char *lwip_strerr(err_t err);
-#else
-#define lwip_strerr(x) ""
-#endif /* LWIP_DEBUG */
-#endif /* __LWIP_ERR_H__ */
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+#ifndef __LWIP_ERR_H__\r
+#define __LWIP_ERR_H__\r
+\r
+#include "lwip/opt.h"\r
+\r
+#include "arch/cc.h"\r
+\r
+typedef s8_t err_t;\r
+\r
+/* Definitions for error constants. */\r
+\r
+#define ERR_OK    0      /* No error, everything OK. */\r
+#define ERR_MEM  -1      /* Out of memory error.     */\r
+#define ERR_BUF  -2      /* Buffer error.            */\r
+\r
+\r
+#define ERR_ABRT -3      /* Connection aborted.      */\r
+#define ERR_RST  -4      /* Connection reset.        */\r
+#define ERR_CLSD -5      /* Connection closed.       */\r
+#define ERR_CONN -6      /* Not connected.           */\r
+\r
+#define ERR_VAL  -7      /* Illegal value.           */\r
+\r
+#define ERR_ARG  -8      /* Illegal argument.        */\r
+\r
+#define ERR_RTE  -9      /* Routing problem.         */\r
+\r
+#define ERR_USE  -10     /* Address in use.          */\r
+\r
+#define ERR_IF   -11     /* Low-level netif error    */\r
+#define ERR_ISCONN -12   /* Already connected.       */\r
+\r
+\r
+#ifdef LWIP_DEBUG\r
+extern char *lwip_strerr(err_t err);\r
+#else\r
+#define lwip_strerr(x) ""\r
+#endif /* LWIP_DEBUG */\r
+#endif /* __LWIP_ERR_H__ */\r
index ee6fea7d8ceb7bf3dd1def96944501e9f83265be..b88ea9c8d1689b9a2c670dd0dc31d53701d687c9 100644 (file)
@@ -1,61 +1,61 @@
-/*
- * 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 <adam@sics.se>
- *
- */
-#ifndef __LWIP_MEM_H__
-#define __LWIP_MEM_H__
-
-#include "lwip/opt.h"
-#include "lwip/arch.h"
-
-#if MEM_SIZE > 64000l
-typedef u32_t mem_size_t;
-#else
-typedef u16_t mem_size_t;
-#endif /* MEM_SIZE > 64000 */
-
-
-void mem_init(void);
-
-void *mem_malloc(mem_size_t size);
-void mem_free(void *mem);
-void *mem_realloc(void *mem, mem_size_t size);
-void *mem_reallocm(void *mem, mem_size_t size);
-
-#ifndef MEM_ALIGN_SIZE
-#define MEM_ALIGN_SIZE(size) (((size) + MEM_ALIGNMENT - 1) & ~(MEM_ALIGNMENT-1))
-#endif
-
-#ifndef MEM_ALIGN
-#define MEM_ALIGN(addr) ((void *)(((mem_ptr_t)(addr) + MEM_ALIGNMENT - 1) & ~(mem_ptr_t)(MEM_ALIGNMENT-1)))
-#endif
-
-#endif /* __LWIP_MEM_H__ */
-
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+#ifndef __LWIP_MEM_H__\r
+#define __LWIP_MEM_H__\r
+\r
+#include "lwip/opt.h"\r
+#include "lwip/arch.h"\r
+\r
+#if MEM_SIZE > 64000l\r
+typedef u32_t mem_size_t;\r
+#else\r
+typedef u16_t mem_size_t;\r
+#endif /* MEM_SIZE > 64000 */\r
+\r
+\r
+void mem_init(void);\r
+\r
+void *mem_malloc(mem_size_t size);\r
+void mem_free(void *mem);\r
+void *mem_realloc(void *mem, mem_size_t size);\r
+void *mem_reallocm(void *mem, mem_size_t size);\r
+\r
+#ifndef MEM_ALIGN_SIZE\r
+#define MEM_ALIGN_SIZE(size) (((size) + MEM_ALIGNMENT - 1) & ~(MEM_ALIGNMENT-1))\r
+#endif\r
+\r
+#ifndef MEM_ALIGN\r
+#define MEM_ALIGN(addr) ((void *)(((mem_ptr_t)(addr) + MEM_ALIGNMENT - 1) & ~(mem_ptr_t)(MEM_ALIGNMENT-1)))\r
+#endif\r
+\r
+#endif /* __LWIP_MEM_H__ */\r
+\r
index 1cd46fa3fe378de2a896ed0624a2e2ca8610d6ba..6da033f27d3ea5b3612d98db2d4bb2a81faad605 100644 (file)
@@ -1,63 +1,63 @@
-/*
- * 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 <adam@sics.se>
- *
- */
-
-#ifndef __LWIP_MEMP_H__
-#define __LWIP_MEMP_H__
-
-#include "lwip/opt.h"
-
-typedef enum {
-  MEMP_PBUF,
-  MEMP_RAW_PCB,
-  MEMP_UDP_PCB,
-  MEMP_TCP_PCB,
-  MEMP_TCP_PCB_LISTEN,
-  MEMP_TCP_SEG,
-
-  MEMP_NETBUF,
-  MEMP_NETCONN,
-  MEMP_API_MSG,
-  MEMP_TCPIP_MSG,
-
-  MEMP_SYS_TIMEOUT,
-  
-  MEMP_MAX
-} memp_t;
-
-void memp_init(void);
-
-void *memp_malloc(memp_t type);
-void *memp_realloc(memp_t fromtype, memp_t totype, void *mem);
-void memp_free(memp_t type, void *mem);
-
-#endif /* __LWIP_MEMP_H__  */
-    
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+\r
+#ifndef __LWIP_MEMP_H__\r
+#define __LWIP_MEMP_H__\r
+\r
+#include "lwip/opt.h"\r
+\r
+typedef enum {\r
+  MEMP_PBUF,\r
+  MEMP_RAW_PCB,\r
+  MEMP_UDP_PCB,\r
+  MEMP_TCP_PCB,\r
+  MEMP_TCP_PCB_LISTEN,\r
+  MEMP_TCP_SEG,\r
+\r
+  MEMP_NETBUF,\r
+  MEMP_NETCONN,\r
+  MEMP_API_MSG,\r
+  MEMP_TCPIP_MSG,\r
+\r
+  MEMP_SYS_TIMEOUT,\r
+  \r
+  MEMP_MAX\r
+} memp_t;\r
+\r
+void memp_init(void);\r
+\r
+void *memp_malloc(memp_t type);\r
+void *memp_realloc(memp_t fromtype, memp_t totype, void *mem);\r
+void memp_free(memp_t type, void *mem);\r
+\r
+#endif /* __LWIP_MEMP_H__  */\r
+    \r
index ff50c6f9c85aa207375de628f2c90e9cd4e87f7f..374aaa5eff6338a7db76561b36407e6e3133a065 100644 (file)
-/*
- * 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 <adam@sics.se>
- *
- */
-#ifndef __LWIP_NETIF_H__
-#define __LWIP_NETIF_H__
-
-#include "lwip/opt.h"
-
-#include "lwip/err.h"
-
-#include "lwip/ip_addr.h"
-
-#include "lwip/inet.h"
-#include "lwip/pbuf.h"
-#if LWIP_DHCP
-#  include "lwip/dhcp.h"
-#endif
-
-/** must be the maximum of all used hardware address lengths
-    across all types of interfaces in use */
-#define NETIF_MAX_HWADDR_LEN 6U
-
-/** TODO: define the use (where, when, whom) of netif flags */
-
-/** whether the network interface is 'up'. this is
- * a software flag used to control whether this network
- * interface is enabled and processes traffic.
- */
-#define NETIF_FLAG_UP 0x1U
-/** if set, the netif has broadcast capability */
-#define NETIF_FLAG_BROADCAST 0x2U
-/** if set, the netif is one end of a point-to-point connection */
-#define NETIF_FLAG_POINTTOPOINT 0x4U
-/** if set, the interface is configured using DHCP */
-#define NETIF_FLAG_DHCP 0x08U
-/** if set, the interface has an active link
- *  (set by the network interface driver) */
-#define NETIF_FLAG_LINK_UP 0x10U
-
-/** Generic data structure used for all lwIP network interfaces.
- *  The following fields should be filled in by the initialization
- *  function for the device driver: hwaddr_len, hwaddr[], mtu, flags */
-
-struct netif {
-  /** pointer to next in linked list */
-  struct netif *next;
-
-  /** IP address configuration in network byte order */
-  struct ip_addr ip_addr;
-  struct ip_addr netmask;
-  struct ip_addr gw;
-
-  /** This function is called by the network device driver
-   *  to pass a packet up the TCP/IP stack. */
-  err_t (* input)(struct pbuf *p, struct netif *inp);
-  /** This function is called by the IP module when it wants
-   *  to send a packet on the interface. This function typically
-   *  first resolves the hardware address, then sends the packet. */
-  err_t (* output)(struct netif *netif, struct pbuf *p,
-       struct ip_addr *ipaddr);
-  /** This function is called by the ARP module when it wants
-   *  to send a packet on the interface. This function outputs
-   *  the pbuf as-is on the link medium. */
-  err_t (* linkoutput)(struct netif *netif, struct pbuf *p);
-  /** This field can be set by the device driver and could point
-   *  to state information for the device. */
-  void *state;
-#if LWIP_DHCP
-  /** the DHCP client state information for this netif */
-  struct dhcp *dhcp;
-#endif
-  /** number of bytes used in hwaddr */
-  u8_t hwaddr_len;
-  /** link level hardware address of this interface */
-  u8_t hwaddr[NETIF_MAX_HWADDR_LEN];
-  /** maximum transfer unit (in bytes) */
-  u16_t mtu;
-  /** flags (see NETIF_FLAG_ above) */
-  u8_t flags;
-  /** link type */
-  u8_t link_type;
-  /** descriptive abbreviation */
-  char name[2];
-  /** number of this interface */
-  u8_t num;
-};
-
-/** The list of network interfaces. */
-extern struct netif *netif_list;
-/** The default network interface. */
-extern struct netif *netif_default;
-
-/* netif_init() must be called first. */
-void netif_init(void);
-
-struct netif *netif_add(struct netif *netif, struct ip_addr *ipaddr, struct ip_addr *netmask,
-      struct ip_addr *gw,
-      void *state,
-      err_t (* init)(struct netif *netif),
-      err_t (* input)(struct pbuf *p, struct netif *netif));
-
-void
-netif_set_addr(struct netif *netif,struct ip_addr *ipaddr, struct ip_addr *netmask,
-    struct ip_addr *gw);
-void netif_remove(struct netif * netif);
-
-/* Returns a network interface given its name. The name is of the form
-   "et0", where the first two letters are the "name" field in the
-   netif structure, and the digit is in the num field in the same
-   structure. */
-struct netif *netif_find(char *name);
-
-void netif_set_default(struct netif *netif);
-
-void netif_set_ipaddr(struct netif *netif, struct ip_addr *ipaddr);
-void netif_set_netmask(struct netif *netif, struct ip_addr *netmast);
-void netif_set_gw(struct netif *netif, struct ip_addr *gw);
-void netif_set_up(struct netif *netif);
-void netif_set_down(struct netif *netif);
-u8_t netif_is_up(struct netif *netif);
-
-#endif /* __LWIP_NETIF_H__ */
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+#ifndef __LWIP_NETIF_H__\r
+#define __LWIP_NETIF_H__\r
+\r
+#include "lwip/opt.h"\r
+\r
+#include "lwip/err.h"\r
+\r
+#include "lwip/ip_addr.h"\r
+\r
+#include "lwip/inet.h"\r
+#include "lwip/pbuf.h"\r
+#if LWIP_DHCP\r
+#  include "lwip/dhcp.h"\r
+#endif\r
+\r
+/** must be the maximum of all used hardware address lengths\r
+    across all types of interfaces in use */\r
+#define NETIF_MAX_HWADDR_LEN 6U\r
+\r
+/** TODO: define the use (where, when, whom) of netif flags */\r
+\r
+/** whether the network interface is 'up'. this is\r
+ * a software flag used to control whether this network\r
+ * interface is enabled and processes traffic.\r
+ */\r
+#define NETIF_FLAG_UP 0x1U\r
+/** if set, the netif has broadcast capability */\r
+#define NETIF_FLAG_BROADCAST 0x2U\r
+/** if set, the netif is one end of a point-to-point connection */\r
+#define NETIF_FLAG_POINTTOPOINT 0x4U\r
+/** if set, the interface is configured using DHCP */\r
+#define NETIF_FLAG_DHCP 0x08U\r
+/** if set, the interface has an active link\r
+ *  (set by the network interface driver) */\r
+#define NETIF_FLAG_LINK_UP 0x10U\r
+\r
+/** Generic data structure used for all lwIP network interfaces.\r
+ *  The following fields should be filled in by the initialization\r
+ *  function for the device driver: hwaddr_len, hwaddr[], mtu, flags */\r
+\r
+struct netif {\r
+  /** pointer to next in linked list */\r
+  struct netif *next;\r
+\r
+  /** IP address configuration in network byte order */\r
+  struct ip_addr ip_addr;\r
+  struct ip_addr netmask;\r
+  struct ip_addr gw;\r
+\r
+  /** This function is called by the network device driver\r
+   *  to pass a packet up the TCP/IP stack. */\r
+  err_t (* input)(struct pbuf *p, struct netif *inp);\r
+  /** This function is called by the IP module when it wants\r
+   *  to send a packet on the interface. This function typically\r
+   *  first resolves the hardware address, then sends the packet. */\r
+  err_t (* output)(struct netif *netif, struct pbuf *p,\r
+       struct ip_addr *ipaddr);\r
+  /** This function is called by the ARP module when it wants\r
+   *  to send a packet on the interface. This function outputs\r
+   *  the pbuf as-is on the link medium. */\r
+  err_t (* linkoutput)(struct netif *netif, struct pbuf *p);\r
+  /** This field can be set by the device driver and could point\r
+   *  to state information for the device. */\r
+  void *state;\r
+#if LWIP_DHCP\r
+  /** the DHCP client state information for this netif */\r
+  struct dhcp *dhcp;\r
+#endif\r
+  /** number of bytes used in hwaddr */\r
+  u8_t hwaddr_len;\r
+  /** link level hardware address of this interface */\r
+  u8_t hwaddr[NETIF_MAX_HWADDR_LEN];\r
+  /** maximum transfer unit (in bytes) */\r
+  u16_t mtu;\r
+  /** flags (see NETIF_FLAG_ above) */\r
+  u8_t flags;\r
+  /** link type */\r
+  u8_t link_type;\r
+  /** descriptive abbreviation */\r
+  char name[2];\r
+  /** number of this interface */\r
+  u8_t num;\r
+};\r
+\r
+/** The list of network interfaces. */\r
+extern struct netif *netif_list;\r
+/** The default network interface. */\r
+extern struct netif *netif_default;\r
+\r
+/* netif_init() must be called first. */\r
+void netif_init(void);\r
+\r
+struct netif *netif_add(struct netif *netif, struct ip_addr *ipaddr, struct ip_addr *netmask,\r
+      struct ip_addr *gw,\r
+      void *state,\r
+      err_t (* init)(struct netif *netif),\r
+      err_t (* input)(struct pbuf *p, struct netif *netif));\r
+\r
+void\r
+netif_set_addr(struct netif *netif,struct ip_addr *ipaddr, struct ip_addr *netmask,\r
+    struct ip_addr *gw);\r
+void netif_remove(struct netif * netif);\r
+\r
+/* Returns a network interface given its name. The name is of the form\r
+   "et0", where the first two letters are the "name" field in the\r
+   netif structure, and the digit is in the num field in the same\r
+   structure. */\r
+struct netif *netif_find(char *name);\r
+\r
+void netif_set_default(struct netif *netif);\r
+\r
+void netif_set_ipaddr(struct netif *netif, struct ip_addr *ipaddr);\r
+void netif_set_netmask(struct netif *netif, struct ip_addr *netmast);\r
+void netif_set_gw(struct netif *netif, struct ip_addr *gw);\r
+void netif_set_up(struct netif *netif);\r
+void netif_set_down(struct netif *netif);\r
+u8_t netif_is_up(struct netif *netif);\r
+\r
+#endif /* __LWIP_NETIF_H__ */\r
index 45636cb24687cae7e241b6697adea00f2f14a1d1..64720a0302b4371dd3688281dd93af65207a8fcd 100644 (file)
-/*
- * 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 <adam@sics.se>
- *
- */
-#ifndef __LWIP_OPT_H__
-#define __LWIP_OPT_H__
-
-/* Include user defined options first */
-#include "lwipopts.h"
-#include "lwip/debug.h"
-
-/* Define default values for unconfigured parameters. */
-
-/* Platform specific locking */
-
-/*
- * enable SYS_LIGHTWEIGHT_PROT in lwipopts.h if you want inter-task protection
- * for certain critical regions during buffer allocation, deallocation and memory
- * allocation and deallocation.
- */
-#ifndef SYS_LIGHTWEIGHT_PROT
-#define SYS_LIGHTWEIGHT_PROT            0
-#endif
-
-#ifndef NO_SYS
-#define NO_SYS                          0
-#endif
-/* ---------- Memory options ---------- */
-/* MEM_ALIGNMENT: should be set to the alignment of the CPU for which
-   lwIP is compiled. 4 byte alignment -> define MEM_ALIGNMENT to 4, 2
-   byte alignment -> define MEM_ALIGNMENT to 2. */
-
-#ifndef MEM_ALIGNMENT
-#define MEM_ALIGNMENT                   1
-#endif
-
-/* MEM_SIZE: the size of the heap memory. If the application will send
-a lot of data that needs to be copied, this should be set high. */
-#ifndef MEM_SIZE
-#define MEM_SIZE                        1600
-#endif
-
-#ifndef MEMP_SANITY_CHECK
-#define MEMP_SANITY_CHECK       0
-#endif
-
-/* MEMP_NUM_PBUF: the number of memp struct pbufs. If the application
-   sends a lot of data out of ROM (or other static memory), this
-   should be set high. */
-#ifndef MEMP_NUM_PBUF
-#define MEMP_NUM_PBUF                   16
-#endif
-
-/* Number of raw connection PCBs */
-#ifndef MEMP_NUM_RAW_PCB
-#define MEMP_NUM_RAW_PCB                4
-#endif
-
-/* MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One
-   per active UDP "connection". */
-#ifndef MEMP_NUM_UDP_PCB
-#define MEMP_NUM_UDP_PCB                4
-#endif
-/* MEMP_NUM_TCP_PCB: the number of simulatenously active TCP
-   connections. */
-#ifndef MEMP_NUM_TCP_PCB
-#define MEMP_NUM_TCP_PCB                5
-#endif
-/* MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP
-   connections. */
-#ifndef MEMP_NUM_TCP_PCB_LISTEN
-#define MEMP_NUM_TCP_PCB_LISTEN         8
-#endif
-/* MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP
-   segments. */
-#ifndef MEMP_NUM_TCP_SEG
-#define MEMP_NUM_TCP_SEG                16
-#endif
-/* MEMP_NUM_SYS_TIMEOUT: the number of simulateously active
-   timeouts. */
-#ifndef MEMP_NUM_SYS_TIMEOUT
-#define MEMP_NUM_SYS_TIMEOUT            3
-#endif
-
-/* The following four are used only with the sequential API and can be
-   set to 0 if the application only will use the raw API. */
-/* MEMP_NUM_NETBUF: the number of struct netbufs. */
-#ifndef MEMP_NUM_NETBUF
-#define MEMP_NUM_NETBUF                 2
-#endif
-/* MEMP_NUM_NETCONN: the number of struct netconns. */
-#ifndef MEMP_NUM_NETCONN
-#define MEMP_NUM_NETCONN                4
-#endif
-/* MEMP_NUM_APIMSG: the number of struct api_msg, used for
-   communication between the TCP/IP stack and the sequential
-   programs. */
-#ifndef MEMP_NUM_API_MSG
-#define MEMP_NUM_API_MSG                8
-#endif
-/* MEMP_NUM_TCPIPMSG: the number of struct tcpip_msg, which is used
-   for sequential API communication and incoming packets. Used in
-   src/api/tcpip.c. */
-#ifndef MEMP_NUM_TCPIP_MSG
-#define MEMP_NUM_TCPIP_MSG              8
-#endif
-
-/* ---------- Pbuf options ---------- */
-/* PBUF_POOL_SIZE: the number of buffers in the pbuf pool. */
-
-#ifndef PBUF_POOL_SIZE
-#define PBUF_POOL_SIZE                  16
-#endif
-
-/* PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. */
-
-#ifndef PBUF_POOL_BUFSIZE
-#define PBUF_POOL_BUFSIZE               128
-#endif
-
-/* PBUF_LINK_HLEN: the number of bytes that should be allocated for a
-   link level header. Defaults to 14 for Ethernet. */
-
-#ifndef PBUF_LINK_HLEN
-#define PBUF_LINK_HLEN                  14
-#endif
-
-
-
-/* ---------- ARP options ---------- */
-
-/** Number of active hardware address, IP address pairs cached */
-#ifndef ARP_TABLE_SIZE
-#define ARP_TABLE_SIZE                  10
-#endif
-
-/**
- * If enabled, outgoing packets are queued during hardware address
- * resolution.
- *
- * This feature has not stabilized yet. Single-packet queueing is
- * believed to be stable, multi-packet queueing is believed to
- * clash with the TCP segment queueing.
- * 
- * As multi-packet-queueing is currently disabled, enabling this
- * _should_ work, but we need your testing feedback on lwip-users.
- *
- */
-#ifndef ARP_QUEUEING
-#define ARP_QUEUEING                    1
-#endif
-
-/* This option is deprecated */
-#ifdef ETHARP_QUEUE_FIRST
-#error ETHARP_QUEUE_FIRST option is deprecated. Remove it from your lwipopts.h.
-#endif
-
-/* This option is removed to comply with the ARP standard */
-#ifdef ETHARP_ALWAYS_INSERT
-#error ETHARP_ALWAYS_INSERT option is deprecated. Remove it from your lwipopts.h.
-#endif
-
-/* ---------- IP options ---------- */
-/* Define IP_FORWARD to 1 if you wish to have the ability to forward
-   IP packets across network interfaces. If you are going to run lwIP
-   on a device with only one network interface, define this to 0. */
-#ifndef IP_FORWARD
-#define IP_FORWARD                      0
-#endif
-
-/* If defined to 1, IP options are allowed (but not parsed). If
-   defined to 0, all packets with IP options are dropped. */
-#ifndef IP_OPTIONS
-#define IP_OPTIONS                      1
-#endif
-
-/** IP reassembly and segmentation. Even if they both deal with IP
- *  fragments, note that these are orthogonal, one dealing with incoming
- *  packets, the other with outgoing packets
- */
-
-/** Reassemble incoming fragmented IP packets */
-#ifndef IP_REASSEMBLY
-#define IP_REASSEMBLY                   1
-#endif
-
-/** Fragment outgoing IP packets if their size exceeds MTU */
-#ifndef IP_FRAG
-#define IP_FRAG                         1
-#endif
-
-/* ---------- ICMP options ---------- */
-
-#ifndef ICMP_TTL
-#define ICMP_TTL                        255
-#endif
-
-/* ---------- RAW options ---------- */
-
-#ifndef LWIP_RAW
-#define LWIP_RAW                        1
-#endif
-
-#ifndef RAW_TTL
-#define RAW_TTL                        255
-#endif
-
-/* ---------- DHCP options ---------- */
-
-#ifndef LWIP_DHCP
-#define LWIP_DHCP                       0
-#endif
-
-/* 1 if you want to do an ARP check on the offered address
-   (recommended). */
-#ifndef DHCP_DOES_ARP_CHECK
-#define DHCP_DOES_ARP_CHECK             1
-#endif
-
-/* ---------- UDP options ---------- */
-#ifndef LWIP_UDP
-#define LWIP_UDP                        1
-#endif
-
-#ifndef UDP_TTL
-#define UDP_TTL                         255
-#endif
-
-/* ---------- TCP options ---------- */
-#ifndef LWIP_TCP
-#define LWIP_TCP                        1
-#endif
-
-#ifndef TCP_TTL
-#define TCP_TTL                         255
-#endif
-
-#ifndef TCP_WND
-#define TCP_WND                         2048
-#endif 
-
-#ifndef TCP_MAXRTX
-#define TCP_MAXRTX                      12
-#endif
-
-#ifndef TCP_SYNMAXRTX
-#define TCP_SYNMAXRTX                   6
-#endif
-
-
-/* Controls if TCP should queue segments that arrive out of
-   order. Define to 0 if your device is low on memory. */
-#ifndef TCP_QUEUE_OOSEQ
-#define TCP_QUEUE_OOSEQ                 1
-#endif
-
-/* TCP Maximum segment size. */
-#ifndef TCP_MSS
-#define TCP_MSS                         128 /* A *very* conservative default. */
-#endif
-
-/* TCP sender buffer space (bytes). */
-#ifndef TCP_SND_BUF
-#define TCP_SND_BUF                     256
-#endif
-
-/* TCP sender buffer space (pbufs). This must be at least = 2 *
-   TCP_SND_BUF/TCP_MSS for things to work. */
-#ifndef TCP_SND_QUEUELEN
-#define TCP_SND_QUEUELEN                4 * TCP_SND_BUF/TCP_MSS
-#endif
-
-
-/* Maximum number of retransmissions of data segments. */
-
-/* Maximum number of retransmissions of SYN segments. */
-
-/* TCP writable space (bytes). This must be less than or equal
-   to TCP_SND_BUF. It is the amount of space which must be
-   available in the tcp snd_buf for select to return writable */
-#ifndef TCP_SNDLOWAT
-#define TCP_SNDLOWAT                    TCP_SND_BUF/2
-#endif
-
-/* Support loop interface (127.0.0.1) */
-#ifndef LWIP_HAVE_LOOPIF
-#define LWIP_HAVE_LOOPIF                0
-#endif
-
-#ifndef LWIP_EVENT_API
-#define LWIP_EVENT_API                  0
-#define LWIP_CALLBACK_API               1
-#else 
-#define LWIP_EVENT_API                  1
-#define LWIP_CALLBACK_API               0
-#endif 
-
-#ifndef LWIP_COMPAT_SOCKETS
-#define LWIP_COMPAT_SOCKETS             1
-#endif
-
-
-#ifndef TCPIP_THREAD_PRIO
-#define TCPIP_THREAD_PRIO               1
-#endif
-
-#ifndef SLIPIF_THREAD_PRIO
-#define SLIPIF_THREAD_PRIO              1
-#endif
-
-#ifndef PPP_THREAD_PRIO
-#define PPP_THREAD_PRIO                 1
-#endif
-
-#ifndef DEFAULT_THREAD_PRIO
-#define DEFAULT_THREAD_PRIO             1
-#endif
-
-
-/* ---------- Socket Options ---------- */
-/* Enable SO_REUSEADDR and SO_REUSEPORT options */ 
-#ifdef SO_REUSE
-/* I removed the lot since this was an ugly hack. It broke the raw-API.
-   It also came with many ugly goto's, Christiaan Simons. */
-#error "SO_REUSE currently unavailable, this was a hack"
-#endif                                                                        
-
-
-/* ---------- Statistics options ---------- */
-#ifndef LWIP_STATS
-#define LWIP_STATS                      1
-#endif
-
-#if LWIP_STATS
-
-#ifndef LWIP_STATS_DISPLAY
-#define LWIP_STATS_DISPLAY 0
-#endif
-
-#ifndef LINK_STATS
-#define LINK_STATS  1
-#endif
-
-#ifndef IP_STATS
-#define IP_STATS    1
-#endif
-
-#ifndef IPFRAG_STATS
-#define IPFRAG_STATS    1
-#endif
-
-#ifndef ICMP_STATS
-#define ICMP_STATS  1
-#endif
-
-#ifndef UDP_STATS
-#define UDP_STATS   1
-#endif
-
-#ifndef TCP_STATS
-#define TCP_STATS   1
-#endif
-
-#ifndef MEM_STATS
-#define MEM_STATS   1
-#endif
-
-#ifndef MEMP_STATS
-#define MEMP_STATS  1
-#endif
-
-#ifndef PBUF_STATS
-#define PBUF_STATS  1
-#endif
-
-#ifndef SYS_STATS
-#define SYS_STATS   1
-#endif
-
-#ifndef RAW_STATS
-#define RAW_STATS   0
-#endif
-
-#else
-
-#define LINK_STATS  0
-#define IP_STATS    0
-#define IPFRAG_STATS    0
-#define ICMP_STATS  0
-#define UDP_STATS   0
-#define TCP_STATS   0
-#define MEM_STATS   0
-#define MEMP_STATS  0
-#define PBUF_STATS  0
-#define SYS_STATS   0
-#define RAW_STATS   0
-#define LWIP_STATS_DISPLAY  0
-
-#endif /* LWIP_STATS */
-
-/* ---------- PPP options ---------- */
-
-#ifndef PPP_SUPPORT
-#define PPP_SUPPORT                     0      /* Set for PPP */
-#endif
-
-#if PPP_SUPPORT 
-
-#define NUM_PPP                         1      /* Max PPP sessions. */
-
-
-
-#ifndef PAP_SUPPORT
-#define PAP_SUPPORT                     0      /* Set for PAP. */
-#endif
-
-#ifndef CHAP_SUPPORT
-#define CHAP_SUPPORT                    0      /* Set for CHAP. */
-#endif
-
-#define MSCHAP_SUPPORT                  0      /* Set for MSCHAP (NOT FUNCTIONAL!) */
-#define CBCP_SUPPORT                    0      /* Set for CBCP (NOT FUNCTIONAL!) */
-#define CCP_SUPPORT                     0      /* Set for CCP (NOT FUNCTIONAL!) */
-
-#ifndef VJ_SUPPORT
-#define VJ_SUPPORT                      0      /* Set for VJ header compression. */
-#endif
-
-#ifndef MD5_SUPPORT
-#define MD5_SUPPORT                     0      /* Set for MD5 (see also CHAP) */
-#endif
-
-
-/*
- * Timeouts.
- */
-#define FSM_DEFTIMEOUT                  6       /* Timeout time in seconds */
-#define FSM_DEFMAXTERMREQS              2       /* Maximum Terminate-Request transmissions */
-#define FSM_DEFMAXCONFREQS              10      /* Maximum Configure-Request transmissions */
-#define FSM_DEFMAXNAKLOOPS              5       /* Maximum number of nak loops */
-
-#define UPAP_DEFTIMEOUT                 6       /* Timeout (seconds) for retransmitting req */
-#define UPAP_DEFREQTIME                 30      /* Time to wait for auth-req from peer */
-
-#define CHAP_DEFTIMEOUT                 6       /* Timeout time in seconds */
-#define CHAP_DEFTRANSMITS               10      /* max # times to send challenge */
-
-
-/* Interval in seconds between keepalive echo requests, 0 to disable. */
-#if 1
-#define LCP_ECHOINTERVAL                0
-#else
-#define LCP_ECHOINTERVAL                10
-#endif
-
-/* Number of unanswered echo requests before failure. */
-#define LCP_MAXECHOFAILS                3
-
-/* Max Xmit idle time (in jiffies) before resend flag char. */
-#define PPP_MAXIDLEFLAG                 100
-
-/*
- * Packet sizes
- *
- * Note - lcp shouldn't be allowed to negotiate stuff outside these
- *    limits.  See lcp.h in the pppd directory.
- * (XXX - these constants should simply be shared by lcp.c instead
- *    of living in lcp.h)
- */
-#define PPP_MTU                         1500     /* Default MTU (size of Info field) */
-#if 0
-#define PPP_MAXMTU  65535 - (PPP_HDRLEN + PPP_FCSLEN)
-#else
-#define PPP_MAXMTU                      1500 /* Largest MTU we allow */
-#endif
-#define PPP_MINMTU                      64
-#define PPP_MRU                         1500     /* default MRU = max length of info field */
-#define PPP_MAXMRU                      1500     /* Largest MRU we allow */
-#define PPP_DEFMRU                      296             /* Try for this */
-#define PPP_MINMRU                      128             /* No MRUs below this */
-
-
-#define MAXNAMELEN                      256     /* max length of hostname or name for auth */
-#define MAXSECRETLEN                    256     /* max length of password or secret */
-
-#endif /* PPP_SUPPORT */
-
-/* checksum options - set to zero for hardware checksum support */
-
-#ifndef CHECKSUM_GEN_IP
-#define CHECKSUM_GEN_IP                 1
-#endif
-#ifndef CHECKSUM_GEN_UDP
-#define CHECKSUM_GEN_UDP                1
-#endif
-#ifndef CHECKSUM_GEN_TCP
-#define CHECKSUM_GEN_TCP                1
-#endif
-#ifndef CHECKSUM_CHECK_IP
-#define CHECKSUM_CHECK_IP               1
-#endif
-#ifndef CHECKSUM_CHECK_UDP
-#define CHECKSUM_CHECK_UDP              1
-#endif
-
-#ifndef CHECKSUM_CHECK_TCP
-#define CHECKSUM_CHECK_TCP              1
-#endif
-
-/* Debugging options all default to off */
-
-#ifndef DBG_TYPES_ON
-#define DBG_TYPES_ON                    0
-#endif
-
-#ifndef ETHARP_DEBUG
-#define ETHARP_DEBUG                    DBG_OFF
-#endif
-
-#ifndef NETIF_DEBUG
-#define NETIF_DEBUG                     DBG_OFF
-#endif
-
-#ifndef PBUF_DEBUG
-#define PBUF_DEBUG                      DBG_OFF
-#endif
-
-#ifndef API_LIB_DEBUG
-#define API_LIB_DEBUG                   DBG_OFF
-#endif
-
-#ifndef API_MSG_DEBUG
-#define API_MSG_DEBUG                   DBG_OFF
-#endif
-
-#ifndef SOCKETS_DEBUG
-#define SOCKETS_DEBUG                   DBG_OFF
-#endif
-
-#ifndef ICMP_DEBUG
-#define ICMP_DEBUG                      DBG_OFF
-#endif
-
-#ifndef INET_DEBUG
-#define INET_DEBUG                      DBG_OFF
-#endif
-
-#ifndef IP_DEBUG
-#define IP_DEBUG                        DBG_OFF
-#endif
-
-#ifndef IP_REASS_DEBUG
-#define IP_REASS_DEBUG                  DBG_OFF
-#endif
-
-#ifndef RAW_DEBUG
-#define RAW_DEBUG                       DBG_OFF
-#endif
-
-#ifndef MEM_DEBUG
-#define MEM_DEBUG                       DBG_OFF
-#endif
-
-#ifndef MEMP_DEBUG
-#define MEMP_DEBUG                      DBG_OFF
-#endif
-
-#ifndef SYS_DEBUG
-#define SYS_DEBUG                       DBG_OFF
-#endif
-
-#ifndef TCP_DEBUG
-#define TCP_DEBUG                       DBG_OFF
-#endif
-
-#ifndef TCP_INPUT_DEBUG
-#define TCP_INPUT_DEBUG                 DBG_OFF
-#endif
-
-#ifndef TCP_FR_DEBUG
-#define TCP_FR_DEBUG                    DBG_OFF
-#endif
-
-#ifndef TCP_RTO_DEBUG
-#define TCP_RTO_DEBUG                   DBG_OFF
-#endif
-
-#ifndef TCP_REXMIT_DEBUG
-#define TCP_REXMIT_DEBUG                DBG_OFF
-#endif
-
-#ifndef TCP_CWND_DEBUG
-#define TCP_CWND_DEBUG                  DBG_OFF
-#endif
-
-#ifndef TCP_WND_DEBUG
-#define TCP_WND_DEBUG                   DBG_OFF
-#endif
-
-#ifndef TCP_OUTPUT_DEBUG
-#define TCP_OUTPUT_DEBUG                DBG_OFF
-#endif
-
-#ifndef TCP_RST_DEBUG
-#define TCP_RST_DEBUG                   DBG_OFF
-#endif
-
-#ifndef TCP_QLEN_DEBUG
-#define TCP_QLEN_DEBUG                  DBG_OFF
-#endif
-
-#ifndef UDP_DEBUG
-#define UDP_DEBUG                       DBG_OFF
-#endif
-
-#ifndef TCPIP_DEBUG
-#define TCPIP_DEBUG                     DBG_OFF
-#endif
-
-#ifndef PPP_DEBUG 
-#define PPP_DEBUG                       DBG_OFF
-#endif
-
-#ifndef SLIP_DEBUG 
-#define SLIP_DEBUG                      DBG_OFF
-#endif
-
-#ifndef DHCP_DEBUG 
-#define DHCP_DEBUG                      DBG_OFF
-#endif
-
-
-#ifndef DBG_MIN_LEVEL
-#define DBG_MIN_LEVEL                   DBG_LEVEL_OFF
-#endif
-
-#endif /* __LWIP_OPT_H__ */
-
-
-
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+#ifndef __LWIP_OPT_H__\r
+#define __LWIP_OPT_H__\r
+\r
+/* Include user defined options first */\r
+#include "lwipopts.h"\r
+#include "lwip/debug.h"\r
+\r
+/* Define default values for unconfigured parameters. */\r
+\r
+/* Platform specific locking */\r
+\r
+/*\r
+ * enable SYS_LIGHTWEIGHT_PROT in lwipopts.h if you want inter-task protection\r
+ * for certain critical regions during buffer allocation, deallocation and memory\r
+ * allocation and deallocation.\r
+ */\r
+#ifndef SYS_LIGHTWEIGHT_PROT\r
+#define SYS_LIGHTWEIGHT_PROT            0\r
+#endif\r
+\r
+#ifndef NO_SYS\r
+#define NO_SYS                          0\r
+#endif\r
+/* ---------- Memory options ---------- */\r
+/* MEM_ALIGNMENT: should be set to the alignment of the CPU for which\r
+   lwIP is compiled. 4 byte alignment -> define MEM_ALIGNMENT to 4, 2\r
+   byte alignment -> define MEM_ALIGNMENT to 2. */\r
+\r
+#ifndef MEM_ALIGNMENT\r
+#define MEM_ALIGNMENT                   1\r
+#endif\r
+\r
+/* MEM_SIZE: the size of the heap memory. If the application will send\r
+a lot of data that needs to be copied, this should be set high. */\r
+#ifndef MEM_SIZE\r
+#define MEM_SIZE                        1600\r
+#endif\r
+\r
+#ifndef MEMP_SANITY_CHECK\r
+#define MEMP_SANITY_CHECK       0\r
+#endif\r
+\r
+/* MEMP_NUM_PBUF: the number of memp struct pbufs. If the application\r
+   sends a lot of data out of ROM (or other static memory), this\r
+   should be set high. */\r
+#ifndef MEMP_NUM_PBUF\r
+#define MEMP_NUM_PBUF                   16\r
+#endif\r
+\r
+/* Number of raw connection PCBs */\r
+#ifndef MEMP_NUM_RAW_PCB\r
+#define MEMP_NUM_RAW_PCB                4\r
+#endif\r
+\r
+/* MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One\r
+   per active UDP "connection". */\r
+#ifndef MEMP_NUM_UDP_PCB\r
+#define MEMP_NUM_UDP_PCB                4\r
+#endif\r
+/* MEMP_NUM_TCP_PCB: the number of simulatenously active TCP\r
+   connections. */\r
+#ifndef MEMP_NUM_TCP_PCB\r
+#define MEMP_NUM_TCP_PCB                5\r
+#endif\r
+/* MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP\r
+   connections. */\r
+#ifndef MEMP_NUM_TCP_PCB_LISTEN\r
+#define MEMP_NUM_TCP_PCB_LISTEN         8\r
+#endif\r
+/* MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP\r
+   segments. */\r
+#ifndef MEMP_NUM_TCP_SEG\r
+#define MEMP_NUM_TCP_SEG                16\r
+#endif\r
+/* MEMP_NUM_SYS_TIMEOUT: the number of simulateously active\r
+   timeouts. */\r
+#ifndef MEMP_NUM_SYS_TIMEOUT\r
+#define MEMP_NUM_SYS_TIMEOUT            3\r
+#endif\r
+\r
+/* The following four are used only with the sequential API and can be\r
+   set to 0 if the application only will use the raw API. */\r
+/* MEMP_NUM_NETBUF: the number of struct netbufs. */\r
+#ifndef MEMP_NUM_NETBUF\r
+#define MEMP_NUM_NETBUF                 2\r
+#endif\r
+/* MEMP_NUM_NETCONN: the number of struct netconns. */\r
+#ifndef MEMP_NUM_NETCONN\r
+#define MEMP_NUM_NETCONN                4\r
+#endif\r
+/* MEMP_NUM_APIMSG: the number of struct api_msg, used for\r
+   communication between the TCP/IP stack and the sequential\r
+   programs. */\r
+#ifndef MEMP_NUM_API_MSG\r
+#define MEMP_NUM_API_MSG                8\r
+#endif\r
+/* MEMP_NUM_TCPIPMSG: the number of struct tcpip_msg, which is used\r
+   for sequential API communication and incoming packets. Used in\r
+   src/api/tcpip.c. */\r
+#ifndef MEMP_NUM_TCPIP_MSG\r
+#define MEMP_NUM_TCPIP_MSG              8\r
+#endif\r
+\r
+/* ---------- Pbuf options ---------- */\r
+/* PBUF_POOL_SIZE: the number of buffers in the pbuf pool. */\r
+\r
+#ifndef PBUF_POOL_SIZE\r
+#define PBUF_POOL_SIZE                  16\r
+#endif\r
+\r
+/* PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. */\r
+\r
+#ifndef PBUF_POOL_BUFSIZE\r
+#define PBUF_POOL_BUFSIZE               128\r
+#endif\r
+\r
+/* PBUF_LINK_HLEN: the number of bytes that should be allocated for a\r
+   link level header. Defaults to 14 for Ethernet. */\r
+\r
+#ifndef PBUF_LINK_HLEN\r
+#define PBUF_LINK_HLEN                  14\r
+#endif\r
+\r
+\r
+\r
+/* ---------- ARP options ---------- */\r
+\r
+/** Number of active hardware address, IP address pairs cached */\r
+#ifndef ARP_TABLE_SIZE\r
+#define ARP_TABLE_SIZE                  10\r
+#endif\r
+\r
+/**\r
+ * If enabled, outgoing packets are queued during hardware address\r
+ * resolution.\r
+ *\r
+ * This feature has not stabilized yet. Single-packet queueing is\r
+ * believed to be stable, multi-packet queueing is believed to\r
+ * clash with the TCP segment queueing.\r
+ * \r
+ * As multi-packet-queueing is currently disabled, enabling this\r
+ * _should_ work, but we need your testing feedback on lwip-users.\r
+ *\r
+ */\r
+#ifndef ARP_QUEUEING\r
+#define ARP_QUEUEING                    1\r
+#endif\r
+\r
+/* This option is deprecated */\r
+#ifdef ETHARP_QUEUE_FIRST\r
+#error ETHARP_QUEUE_FIRST option is deprecated. Remove it from your lwipopts.h.\r
+#endif\r
+\r
+/* This option is removed to comply with the ARP standard */\r
+#ifdef ETHARP_ALWAYS_INSERT\r
+#error ETHARP_ALWAYS_INSERT option is deprecated. Remove it from your lwipopts.h.\r
+#endif\r
+\r
+/* ---------- IP options ---------- */\r
+/* Define IP_FORWARD to 1 if you wish to have the ability to forward\r
+   IP packets across network interfaces. If you are going to run lwIP\r
+   on a device with only one network interface, define this to 0. */\r
+#ifndef IP_FORWARD\r
+#define IP_FORWARD                      0\r
+#endif\r
+\r
+/* If defined to 1, IP options are allowed (but not parsed). If\r
+   defined to 0, all packets with IP options are dropped. */\r
+#ifndef IP_OPTIONS\r
+#define IP_OPTIONS                      1\r
+#endif\r
+\r
+/** IP reassembly and segmentation. Even if they both deal with IP\r
+ *  fragments, note that these are orthogonal, one dealing with incoming\r
+ *  packets, the other with outgoing packets\r
+ */\r
+\r
+/** Reassemble incoming fragmented IP packets */\r
+#ifndef IP_REASSEMBLY\r
+#define IP_REASSEMBLY                   1\r
+#endif\r
+\r
+/** Fragment outgoing IP packets if their size exceeds MTU */\r
+#ifndef IP_FRAG\r
+#define IP_FRAG                         1\r
+#endif\r
+\r
+/* ---------- ICMP options ---------- */\r
+\r
+#ifndef ICMP_TTL\r
+#define ICMP_TTL                        255\r
+#endif\r
+\r
+/* ---------- RAW options ---------- */\r
+\r
+#ifndef LWIP_RAW\r
+#define LWIP_RAW                        1\r
+#endif\r
+\r
+#ifndef RAW_TTL\r
+#define RAW_TTL                        255\r
+#endif\r
+\r
+/* ---------- DHCP options ---------- */\r
+\r
+#ifndef LWIP_DHCP\r
+#define LWIP_DHCP                       0\r
+#endif\r
+\r
+/* 1 if you want to do an ARP check on the offered address\r
+   (recommended). */\r
+#ifndef DHCP_DOES_ARP_CHECK\r
+#define DHCP_DOES_ARP_CHECK             1\r
+#endif\r
+\r
+/* ---------- UDP options ---------- */\r
+#ifndef LWIP_UDP\r
+#define LWIP_UDP                        1\r
+#endif\r
+\r
+#ifndef UDP_TTL\r
+#define UDP_TTL                         255\r
+#endif\r
+\r
+/* ---------- TCP options ---------- */\r
+#ifndef LWIP_TCP\r
+#define LWIP_TCP                        1\r
+#endif\r
+\r
+#ifndef TCP_TTL\r
+#define TCP_TTL                         255\r
+#endif\r
+\r
+#ifndef TCP_WND\r
+#define TCP_WND                         2048\r
+#endif \r
+\r
+#ifndef TCP_MAXRTX\r
+#define TCP_MAXRTX                      12\r
+#endif\r
+\r
+#ifndef TCP_SYNMAXRTX\r
+#define TCP_SYNMAXRTX                   6\r
+#endif\r
+\r
+\r
+/* Controls if TCP should queue segments that arrive out of\r
+   order. Define to 0 if your device is low on memory. */\r
+#ifndef TCP_QUEUE_OOSEQ\r
+#define TCP_QUEUE_OOSEQ                 1\r
+#endif\r
+\r
+/* TCP Maximum segment size. */\r
+#ifndef TCP_MSS\r
+#define TCP_MSS                         128 /* A *very* conservative default. */\r
+#endif\r
+\r
+/* TCP sender buffer space (bytes). */\r
+#ifndef TCP_SND_BUF\r
+#define TCP_SND_BUF                     256\r
+#endif\r
+\r
+/* TCP sender buffer space (pbufs). This must be at least = 2 *\r
+   TCP_SND_BUF/TCP_MSS for things to work. */\r
+#ifndef TCP_SND_QUEUELEN\r
+#define TCP_SND_QUEUELEN                4 * TCP_SND_BUF/TCP_MSS\r
+#endif\r
+\r
+\r
+/* Maximum number of retransmissions of data segments. */\r
+\r
+/* Maximum number of retransmissions of SYN segments. */\r
+\r
+/* TCP writable space (bytes). This must be less than or equal\r
+   to TCP_SND_BUF. It is the amount of space which must be\r
+   available in the tcp snd_buf for select to return writable */\r
+#ifndef TCP_SNDLOWAT\r
+#define TCP_SNDLOWAT                    TCP_SND_BUF/2\r
+#endif\r
+\r
+/* Support loop interface (127.0.0.1) */\r
+#ifndef LWIP_HAVE_LOOPIF\r
+#define LWIP_HAVE_LOOPIF                0\r
+#endif\r
+\r
+#ifndef LWIP_EVENT_API\r
+#define LWIP_EVENT_API                  0\r
+#define LWIP_CALLBACK_API               1\r
+#else \r
+#define LWIP_EVENT_API                  1\r
+#define LWIP_CALLBACK_API               0\r
+#endif \r
+\r
+#ifndef LWIP_COMPAT_SOCKETS\r
+#define LWIP_COMPAT_SOCKETS             1\r
+#endif\r
+\r
+\r
+#ifndef TCPIP_THREAD_PRIO\r
+#define TCPIP_THREAD_PRIO               1\r
+#endif\r
+\r
+#ifndef SLIPIF_THREAD_PRIO\r
+#define SLIPIF_THREAD_PRIO              1\r
+#endif\r
+\r
+#ifndef PPP_THREAD_PRIO\r
+#define PPP_THREAD_PRIO                 1\r
+#endif\r
+\r
+#ifndef DEFAULT_THREAD_PRIO\r
+#define DEFAULT_THREAD_PRIO             1\r
+#endif\r
+\r
+\r
+/* ---------- Socket Options ---------- */\r
+/* Enable SO_REUSEADDR and SO_REUSEPORT options */ \r
+#ifdef SO_REUSE\r
+/* I removed the lot since this was an ugly hack. It broke the raw-API.\r
+   It also came with many ugly goto's, Christiaan Simons. */\r
+#error "SO_REUSE currently unavailable, this was a hack"\r
+#endif                                                                        \r
+\r
+\r
+/* ---------- Statistics options ---------- */\r
+#ifndef LWIP_STATS\r
+#define LWIP_STATS                      1\r
+#endif\r
+\r
+#if LWIP_STATS\r
+\r
+#ifndef LWIP_STATS_DISPLAY\r
+#define LWIP_STATS_DISPLAY 0\r
+#endif\r
+\r
+#ifndef LINK_STATS\r
+#define LINK_STATS  1\r
+#endif\r
+\r
+#ifndef IP_STATS\r
+#define IP_STATS    1\r
+#endif\r
+\r
+#ifndef IPFRAG_STATS\r
+#define IPFRAG_STATS    1\r
+#endif\r
+\r
+#ifndef ICMP_STATS\r
+#define ICMP_STATS  1\r
+#endif\r
+\r
+#ifndef UDP_STATS\r
+#define UDP_STATS   1\r
+#endif\r
+\r
+#ifndef TCP_STATS\r
+#define TCP_STATS   1\r
+#endif\r
+\r
+#ifndef MEM_STATS\r
+#define MEM_STATS   1\r
+#endif\r
+\r
+#ifndef MEMP_STATS\r
+#define MEMP_STATS  1\r
+#endif\r
+\r
+#ifndef PBUF_STATS\r
+#define PBUF_STATS  1\r
+#endif\r
+\r
+#ifndef SYS_STATS\r
+#define SYS_STATS   1\r
+#endif\r
+\r
+#ifndef RAW_STATS\r
+#define RAW_STATS   0\r
+#endif\r
+\r
+#else\r
+\r
+#define LINK_STATS  0\r
+#define IP_STATS    0\r
+#define IPFRAG_STATS    0\r
+#define ICMP_STATS  0\r
+#define UDP_STATS   0\r
+#define TCP_STATS   0\r
+#define MEM_STATS   0\r
+#define MEMP_STATS  0\r
+#define PBUF_STATS  0\r
+#define SYS_STATS   0\r
+#define RAW_STATS   0\r
+#define LWIP_STATS_DISPLAY  0\r
+\r
+#endif /* LWIP_STATS */\r
+\r
+/* ---------- PPP options ---------- */\r
+\r
+#ifndef PPP_SUPPORT\r
+#define PPP_SUPPORT                     0      /* Set for PPP */\r
+#endif\r
+\r
+#if PPP_SUPPORT \r
+\r
+#define NUM_PPP                         1      /* Max PPP sessions. */\r
+\r
+\r
+\r
+#ifndef PAP_SUPPORT\r
+#define PAP_SUPPORT                     0      /* Set for PAP. */\r
+#endif\r
+\r
+#ifndef CHAP_SUPPORT\r
+#define CHAP_SUPPORT                    0      /* Set for CHAP. */\r
+#endif\r
+\r
+#define MSCHAP_SUPPORT                  0      /* Set for MSCHAP (NOT FUNCTIONAL!) */\r
+#define CBCP_SUPPORT                    0      /* Set for CBCP (NOT FUNCTIONAL!) */\r
+#define CCP_SUPPORT                     0      /* Set for CCP (NOT FUNCTIONAL!) */\r
+\r
+#ifndef VJ_SUPPORT\r
+#define VJ_SUPPORT                      0      /* Set for VJ header compression. */\r
+#endif\r
+\r
+#ifndef MD5_SUPPORT\r
+#define MD5_SUPPORT                     0      /* Set for MD5 (see also CHAP) */\r
+#endif\r
+\r
+\r
+/*\r
+ * Timeouts.\r
+ */\r
+#define FSM_DEFTIMEOUT                  6       /* Timeout time in seconds */\r
+#define FSM_DEFMAXTERMREQS              2       /* Maximum Terminate-Request transmissions */\r
+#define FSM_DEFMAXCONFREQS              10      /* Maximum Configure-Request transmissions */\r
+#define FSM_DEFMAXNAKLOOPS              5       /* Maximum number of nak loops */\r
+\r
+#define UPAP_DEFTIMEOUT                 6       /* Timeout (seconds) for retransmitting req */\r
+#define UPAP_DEFREQTIME                 30      /* Time to wait for auth-req from peer */\r
+\r
+#define CHAP_DEFTIMEOUT                 6       /* Timeout time in seconds */\r
+#define CHAP_DEFTRANSMITS               10      /* max # times to send challenge */\r
+\r
+\r
+/* Interval in seconds between keepalive echo requests, 0 to disable. */\r
+#if 1\r
+#define LCP_ECHOINTERVAL                0\r
+#else\r
+#define LCP_ECHOINTERVAL                10\r
+#endif\r
+\r
+/* Number of unanswered echo requests before failure. */\r
+#define LCP_MAXECHOFAILS                3\r
+\r
+/* Max Xmit idle time (in jiffies) before resend flag char. */\r
+#define PPP_MAXIDLEFLAG                 100\r
+\r
+/*\r
+ * Packet sizes\r
+ *\r
+ * Note - lcp shouldn't be allowed to negotiate stuff outside these\r
+ *    limits.  See lcp.h in the pppd directory.\r
+ * (XXX - these constants should simply be shared by lcp.c instead\r
+ *    of living in lcp.h)\r
+ */\r
+#define PPP_MTU                         1500     /* Default MTU (size of Info field) */\r
+#if 0\r
+#define PPP_MAXMTU  65535 - (PPP_HDRLEN + PPP_FCSLEN)\r
+#else\r
+#define PPP_MAXMTU                      1500 /* Largest MTU we allow */\r
+#endif\r
+#define PPP_MINMTU                      64\r
+#define PPP_MRU                         1500     /* default MRU = max length of info field */\r
+#define PPP_MAXMRU                      1500     /* Largest MRU we allow */\r
+#define PPP_DEFMRU                      296             /* Try for this */\r
+#define PPP_MINMRU                      128             /* No MRUs below this */\r
+\r
+\r
+#define MAXNAMELEN                      256     /* max length of hostname or name for auth */\r
+#define MAXSECRETLEN                    256     /* max length of password or secret */\r
+\r
+#endif /* PPP_SUPPORT */\r
+\r
+/* checksum options - set to zero for hardware checksum support */\r
+\r
+#ifndef CHECKSUM_GEN_IP\r
+#define CHECKSUM_GEN_IP                 1\r
+#endif\r
\r
+#ifndef CHECKSUM_GEN_UDP\r
+#define CHECKSUM_GEN_UDP                1\r
+#endif\r
\r
+#ifndef CHECKSUM_GEN_TCP\r
+#define CHECKSUM_GEN_TCP                1\r
+#endif\r
\r
+#ifndef CHECKSUM_CHECK_IP\r
+#define CHECKSUM_CHECK_IP               1\r
+#endif\r
\r
+#ifndef CHECKSUM_CHECK_UDP\r
+#define CHECKSUM_CHECK_UDP              1\r
+#endif\r
+\r
+#ifndef CHECKSUM_CHECK_TCP\r
+#define CHECKSUM_CHECK_TCP              1\r
+#endif\r
+\r
+/* Debugging options all default to off */\r
+\r
+#ifndef DBG_TYPES_ON\r
+#define DBG_TYPES_ON                    0\r
+#endif\r
+\r
+#ifndef ETHARP_DEBUG\r
+#define ETHARP_DEBUG                    DBG_OFF\r
+#endif\r
+\r
+#ifndef NETIF_DEBUG\r
+#define NETIF_DEBUG                     DBG_OFF\r
+#endif\r
+\r
+#ifndef PBUF_DEBUG\r
+#define PBUF_DEBUG                      DBG_OFF\r
+#endif\r
+\r
+#ifndef API_LIB_DEBUG\r
+#define API_LIB_DEBUG                   DBG_OFF\r
+#endif\r
+\r
+#ifndef API_MSG_DEBUG\r
+#define API_MSG_DEBUG                   DBG_OFF\r
+#endif\r
+\r
+#ifndef SOCKETS_DEBUG\r
+#define SOCKETS_DEBUG                   DBG_OFF\r
+#endif\r
+\r
+#ifndef ICMP_DEBUG\r
+#define ICMP_DEBUG                      DBG_OFF\r
+#endif\r
+\r
+#ifndef INET_DEBUG\r
+#define INET_DEBUG                      DBG_OFF\r
+#endif\r
+\r
+#ifndef IP_DEBUG\r
+#define IP_DEBUG                        DBG_OFF\r
+#endif\r
+\r
+#ifndef IP_REASS_DEBUG\r
+#define IP_REASS_DEBUG                  DBG_OFF\r
+#endif\r
+\r
+#ifndef RAW_DEBUG\r
+#define RAW_DEBUG                       DBG_OFF\r
+#endif\r
+\r
+#ifndef MEM_DEBUG\r
+#define MEM_DEBUG                       DBG_OFF\r
+#endif\r
+\r
+#ifndef MEMP_DEBUG\r
+#define MEMP_DEBUG                      DBG_OFF\r
+#endif\r
+\r
+#ifndef SYS_DEBUG\r
+#define SYS_DEBUG                       DBG_OFF\r
+#endif\r
+\r
+#ifndef TCP_DEBUG\r
+#define TCP_DEBUG                       DBG_OFF\r
+#endif\r
+\r
+#ifndef TCP_INPUT_DEBUG\r
+#define TCP_INPUT_DEBUG                 DBG_OFF\r
+#endif\r
+\r
+#ifndef TCP_FR_DEBUG\r
+#define TCP_FR_DEBUG                    DBG_OFF\r
+#endif\r
+\r
+#ifndef TCP_RTO_DEBUG\r
+#define TCP_RTO_DEBUG                   DBG_OFF\r
+#endif\r
+\r
+#ifndef TCP_REXMIT_DEBUG\r
+#define TCP_REXMIT_DEBUG                DBG_OFF\r
+#endif\r
+\r
+#ifndef TCP_CWND_DEBUG\r
+#define TCP_CWND_DEBUG                  DBG_OFF\r
+#endif\r
+\r
+#ifndef TCP_WND_DEBUG\r
+#define TCP_WND_DEBUG                   DBG_OFF\r
+#endif\r
+\r
+#ifndef TCP_OUTPUT_DEBUG\r
+#define TCP_OUTPUT_DEBUG                DBG_OFF\r
+#endif\r
+\r
+#ifndef TCP_RST_DEBUG\r
+#define TCP_RST_DEBUG                   DBG_OFF\r
+#endif\r
+\r
+#ifndef TCP_QLEN_DEBUG\r
+#define TCP_QLEN_DEBUG                  DBG_OFF\r
+#endif\r
+\r
+#ifndef UDP_DEBUG\r
+#define UDP_DEBUG                       DBG_OFF\r
+#endif\r
+\r
+#ifndef TCPIP_DEBUG\r
+#define TCPIP_DEBUG                     DBG_OFF\r
+#endif\r
+\r
+#ifndef PPP_DEBUG \r
+#define PPP_DEBUG                       DBG_OFF\r
+#endif\r
+\r
+#ifndef SLIP_DEBUG \r
+#define SLIP_DEBUG                      DBG_OFF\r
+#endif\r
+\r
+#ifndef DHCP_DEBUG \r
+#define DHCP_DEBUG                      DBG_OFF\r
+#endif\r
+\r
+\r
+#ifndef DBG_MIN_LEVEL\r
+#define DBG_MIN_LEVEL                   DBG_LEVEL_OFF\r
+#endif\r
+\r
+#endif /* __LWIP_OPT_H__ */\r
+\r
+\r
+\r
index 546aa30357cefb90564f38c547081c6402f4ff81..0b187e1215f66f63b766c10407363b6ff7a16ea7 100644 (file)
-/*
- * 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 <adam@sics.se>
- *
- */
-
-#ifndef __LWIP_PBUF_H__
-#define __LWIP_PBUF_H__
-
-#include "arch/cc.h"
-
-
-#define PBUF_TRANSPORT_HLEN 20
-#define PBUF_IP_HLEN        20
-
-typedef enum {
-  PBUF_TRANSPORT,
-  PBUF_IP,
-  PBUF_LINK,
-  PBUF_RAW
-} pbuf_layer;
-
-typedef enum {
-  PBUF_RAM,
-  PBUF_ROM,
-  PBUF_REF,
-  PBUF_POOL
-} pbuf_flag;
-
-/* Definitions for the pbuf flag field. These are NOT the flags that
- * are passed to pbuf_alloc(). */
-#define PBUF_FLAG_RAM   0x00U    /* Flags that pbuf data is stored in RAM */
-#define PBUF_FLAG_ROM   0x01U    /* Flags that pbuf data is stored in ROM */
-#define PBUF_FLAG_POOL  0x02U    /* Flags that the pbuf comes from the pbuf pool */
-#define PBUF_FLAG_REF   0x04U    /* Flags thet the pbuf payload refers to RAM */
-
-/** indicates this packet was broadcast on the link */
-#define PBUF_FLAG_LINK_BROADCAST 0x80U
-
-struct pbuf {
-  /** next pbuf in singly linked pbuf chain */
-  struct pbuf *next;
-
-  /** pointer to the actual data in the buffer */
-  void *payload;
-  
-  /**
-   * total length of this buffer and all next buffers in chain
-   * belonging to the same packet.
-   *
-   * For non-queue packet chains this is the invariant:
-   * p->tot_len == p->len + (p->next? p->next->tot_len: 0)
-   */
-  u16_t tot_len;
-  
-  /** length of this buffer */
-  u16_t len;  
-
-  /** flags telling the type of pbuf, see PBUF_FLAG_ */
-  u16_t flags;
-  
-  /**
-   * the reference count always equals the number of pointers
-   * that refer to this pbuf. This can be pointers from an application,
-   * the stack itself, or pbuf->next pointers from a chain.
-   */
-  u16_t ref;
-  
-};
-
-void pbuf_init(void);
-
-struct pbuf *pbuf_alloc(pbuf_layer l, u16_t size, pbuf_flag flag);
-void pbuf_realloc(struct pbuf *p, u16_t size); 
-u8_t pbuf_header(struct pbuf *p, s16_t header_size);
-void pbuf_ref(struct pbuf *p);
-void pbuf_ref_chain(struct pbuf *p);
-u8_t pbuf_free(struct pbuf *p);
-u8_t pbuf_clen(struct pbuf *p);  
-void pbuf_cat(struct pbuf *h, struct pbuf *t);
-void pbuf_chain(struct pbuf *h, struct pbuf *t);
-struct pbuf *pbuf_take(struct pbuf *f);
-struct pbuf *pbuf_dechain(struct pbuf *p);
-void pbuf_queue(struct pbuf *p, struct pbuf *n);
-struct pbuf * pbuf_dequeue(struct pbuf *p);
-
-#endif /* __LWIP_PBUF_H__ */
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+\r
+#ifndef __LWIP_PBUF_H__\r
+#define __LWIP_PBUF_H__\r
+\r
+#include "arch/cc.h"\r
+\r
+\r
+#define PBUF_TRANSPORT_HLEN 20\r
+#define PBUF_IP_HLEN        20\r
+\r
+typedef enum {\r
+  PBUF_TRANSPORT,\r
+  PBUF_IP,\r
+  PBUF_LINK,\r
+  PBUF_RAW\r
+} pbuf_layer;\r
+\r
+typedef enum {\r
+  PBUF_RAM,\r
+  PBUF_ROM,\r
+  PBUF_REF,\r
+  PBUF_POOL\r
+} pbuf_flag;\r
+\r
+/* Definitions for the pbuf flag field. These are NOT the flags that\r
+ * are passed to pbuf_alloc(). */\r
+#define PBUF_FLAG_RAM   0x00U    /* Flags that pbuf data is stored in RAM */\r
+#define PBUF_FLAG_ROM   0x01U    /* Flags that pbuf data is stored in ROM */\r
+#define PBUF_FLAG_POOL  0x02U    /* Flags that the pbuf comes from the pbuf pool */\r
+#define PBUF_FLAG_REF   0x04U    /* Flags thet the pbuf payload refers to RAM */\r
+\r
+/** indicates this packet was broadcast on the link */\r
+#define PBUF_FLAG_LINK_BROADCAST 0x80U\r
+\r
+struct pbuf {\r
+  /** next pbuf in singly linked pbuf chain */\r
+  struct pbuf *next;\r
+\r
+  /** pointer to the actual data in the buffer */\r
+  void *payload;\r
+  \r
+  /**\r
+   * total length of this buffer and all next buffers in chain\r
+   * belonging to the same packet.\r
+   *\r
+   * For non-queue packet chains this is the invariant:\r
+   * p->tot_len == p->len + (p->next? p->next->tot_len: 0)\r
+   */\r
+  u16_t tot_len;\r
+  \r
+  /** length of this buffer */\r
+  u16_t len;  \r
+\r
+  /** flags telling the type of pbuf, see PBUF_FLAG_ */\r
+  u16_t flags;\r
+  \r
+  /**\r
+   * the reference count always equals the number of pointers\r
+   * that refer to this pbuf. This can be pointers from an application,\r
+   * the stack itself, or pbuf->next pointers from a chain.\r
+   */\r
+  u16_t ref;\r
+  \r
+};\r
+\r
+void pbuf_init(void);\r
+\r
+struct pbuf *pbuf_alloc(pbuf_layer l, u16_t size, pbuf_flag flag);\r
+void pbuf_realloc(struct pbuf *p, u16_t size); \r
+u8_t pbuf_header(struct pbuf *p, s16_t header_size);\r
+void pbuf_ref(struct pbuf *p);\r
+void pbuf_ref_chain(struct pbuf *p);\r
+u8_t pbuf_free(struct pbuf *p);\r
+u8_t pbuf_clen(struct pbuf *p);  \r
+void pbuf_cat(struct pbuf *h, struct pbuf *t);\r
+void pbuf_chain(struct pbuf *h, struct pbuf *t);\r
+struct pbuf *pbuf_take(struct pbuf *f);\r
+struct pbuf *pbuf_dechain(struct pbuf *p);\r
+void pbuf_queue(struct pbuf *p, struct pbuf *n);\r
+struct pbuf * pbuf_dequeue(struct pbuf *p);\r
+\r
+#endif /* __LWIP_PBUF_H__ */\r
index 6f7a98717f0523ae957a73c8b118e259a974d893..83b32da9d67272cd85fa483d4249e7e1d8556a05 100644 (file)
@@ -1,74 +1,74 @@
-/*
- * 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 <adam@sics.se>
- *
- */
-#ifndef __LWIP_RAW_H__
-#define __LWIP_RAW_H__
-
-#include "lwip/arch.h"
-
-#include "lwip/pbuf.h"
-#include "lwip/inet.h"
-#include "lwip/ip.h"
-
-struct raw_pcb {
-/* Common members of all PCB types */
-  IP_PCB;
-
-  struct raw_pcb *next;
-
-  u16_t protocol;
-
-  u8_t (* recv)(void *arg, struct raw_pcb *pcb, struct pbuf *p,
-    struct ip_addr *addr);
-  void *recv_arg;
-};
-
-/* The following functions is the application layer interface to the
-   RAW code. */
-struct raw_pcb * raw_new        (u16_t proto);
-void             raw_remove     (struct raw_pcb *pcb);
-err_t            raw_bind       (struct raw_pcb *pcb, struct ip_addr *ipaddr);
-err_t            raw_connect    (struct raw_pcb *pcb, struct ip_addr *ipaddr);
-
-void             raw_recv       (struct raw_pcb *pcb,
-                                 u8_t (* recv)(void *arg, struct raw_pcb *pcb,
-                                              struct pbuf *p,
-                                              struct ip_addr *addr),
-                                 void *recv_arg);
-err_t            raw_sendto    (struct raw_pcb *pcb, struct pbuf *p, struct ip_addr *ipaddr);
-err_t            raw_send       (struct raw_pcb *pcb, struct pbuf *p);
-
-/* The following functions are the lower layer interface to RAW. */
-u8_t              raw_input      (struct pbuf *p, struct netif *inp);
-void             raw_init       (void);
-
-
-#endif /* __LWIP_RAW_H__ */
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without modification,\r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED\r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT\r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY\r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ *\r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+#ifndef __LWIP_RAW_H__\r
+#define __LWIP_RAW_H__\r
+\r
+#include "lwip/arch.h"\r
+\r
+#include "lwip/pbuf.h"\r
+#include "lwip/inet.h"\r
+#include "lwip/ip.h"\r
+\r
+struct raw_pcb {\r
+/* Common members of all PCB types */\r
+  IP_PCB;\r
+\r
+  struct raw_pcb *next;\r
+\r
+  u16_t protocol;\r
+\r
+  u8_t (* recv)(void *arg, struct raw_pcb *pcb, struct pbuf *p,\r
+    struct ip_addr *addr);\r
+  void *recv_arg;\r
+};\r
+\r
+/* The following functions is the application layer interface to the\r
+   RAW code. */\r
+struct raw_pcb * raw_new        (u16_t proto);\r
+void             raw_remove     (struct raw_pcb *pcb);\r
+err_t            raw_bind       (struct raw_pcb *pcb, struct ip_addr *ipaddr);\r
+err_t            raw_connect    (struct raw_pcb *pcb, struct ip_addr *ipaddr);\r
+\r
+void             raw_recv       (struct raw_pcb *pcb,\r
+                                 u8_t (* recv)(void *arg, struct raw_pcb *pcb,\r
+                                              struct pbuf *p,\r
+                                              struct ip_addr *addr),\r
+                                 void *recv_arg);\r
+err_t            raw_sendto    (struct raw_pcb *pcb, struct pbuf *p, struct ip_addr *ipaddr);\r
+err_t            raw_send       (struct raw_pcb *pcb, struct pbuf *p);\r
+\r
+/* The following functions are the lower layer interface to RAW. */\r
+u8_t              raw_input      (struct pbuf *p, struct netif *inp);\r
+void             raw_init       (void);\r
+\r
+\r
+#endif /* __LWIP_RAW_H__ */\r
index 8a37aa35ab3eff4bc4f3d73e29d0c47c0f27dedf..5fc28a4d6d618748a4916c6228773bba642bc212 100644 (file)
@@ -1,63 +1,63 @@
-/*
- * 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.
- */
-
-/*
- * This is the interface to the platform specific serial IO module
- * It needs to be implemented by those platforms which need SLIP or PPP
- */
-
-#include "arch/cc.h"
-
-#ifndef __sio_fd_t_defined
-typedef void * sio_fd_t;
-#endif
-
-#ifndef sio_open
-sio_fd_t sio_open(u8_t);
-#endif
-
-#ifndef sio_send
-void sio_send(u8_t, sio_fd_t);
-#endif
-
-#ifndef sio_recv
-u8_t sio_recv(sio_fd_t);
-#endif
-
-#ifndef sio_read
-u32_t sio_read(sio_fd_t, u8_t *, u32_t);
-#endif
-
-#ifndef sio_write
-u32_t sio_write(sio_fd_t, u8_t *, u32_t);
-#endif
-
-#ifndef sio_read_abort
-void sio_read_abort(sio_fd_t);
-#endif
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ */\r
+\r
+/*\r
+ * This is the interface to the platform specific serial IO module\r
+ * It needs to be implemented by those platforms which need SLIP or PPP\r
+ */\r
+\r
+#include "arch/cc.h"\r
+\r
+#ifndef __sio_fd_t_defined\r
+typedef void * sio_fd_t;\r
+#endif\r
+\r
+#ifndef sio_open\r
+sio_fd_t sio_open(u8_t);\r
+#endif\r
+\r
+#ifndef sio_send\r
+void sio_send(u8_t, sio_fd_t);\r
+#endif\r
+\r
+#ifndef sio_recv\r
+u8_t sio_recv(sio_fd_t);\r
+#endif\r
+\r
+#ifndef sio_read\r
+u32_t sio_read(sio_fd_t, u8_t *, u32_t);\r
+#endif\r
+\r
+#ifndef sio_write\r
+u32_t sio_write(sio_fd_t, u8_t *, u32_t);\r
+#endif\r
+\r
+#ifndef sio_read_abort\r
+void sio_read_abort(sio_fd_t);\r
+#endif\r
index 7d160aaa440369f9889145e0bb18e5f6c40634dc..4e806914b4030d7b60b9a1709600fe924d07ea82 100644 (file)
-/*
- * Copyright (c) 2001, 2002 Leon Woestenberg <leon.woestenberg@axon.tv>
- * Copyright (c) 2001, 2002 Axon Digital Design B.V., The Netherlands.
- * 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: Leon Woestenberg <leon.woestenberg@axon.tv>
- *
- */
-#ifndef __LWIP_SNMP_H__
-#define __LWIP_SNMP_H__
-
-#include "lwip/opt.h"
-
-/* SNMP support available? */
-#if defined(LWIP_SNMP) && (LWIP_SNMP > 0)
-
-/* network interface */
-void snmp_add_ifinoctets(unsigned long value); 
-void snmp_inc_ifinucastpkts(void);
-void snmp_inc_ifinnucastpkts(void);
-void snmp_inc_ifindiscards(void);
-void snmp_add_ifoutoctets(unsigned long value);
-void snmp_inc_ifoutucastpkts(void);
-void snmp_inc_ifoutnucastpkts(void);
-void snmp_inc_ifoutdiscards(void);
-
-/* IP */
-void snmp_inc_ipinreceives(void);
-void snmp_inc_ipindelivers(void);
-void snmp_inc_ipindiscards(void);
-void snmp_inc_ipoutdiscards(void);
-void snmp_inc_ipoutrequests(void);
-void snmp_inc_ipunknownprotos(void);
-void snmp_inc_ipnoroutes(void);
-void snmp_inc_ipforwdatagrams(void);
-
-/* ICMP */
-void snmp_inc_icmpinmsgs(void);
-void snmp_inc_icmpinerrors(void);
-void snmp_inc_icmpindestunreachs(void);
-void snmp_inc_icmpintimeexcds(void);
-void snmp_inc_icmpinparmprobs(void);
-void snmp_inc_icmpinsrcquenchs(void);
-void snmp_inc_icmpinredirects(void);
-void snmp_inc_icmpinechos(void);
-void snmp_inc_icmpinechoreps(void);
-void snmp_inc_icmpintimestamps(void);
-void snmp_inc_icmpintimestampreps(void);
-void snmp_inc_icmpinaddrmasks(void);
-void snmp_inc_icmpinaddrmaskreps(void);
-void snmp_inc_icmpoutmsgs(void);
-void snmp_inc_icmpouterrors(void);
-void snmp_inc_icmpoutdestunreachs(void);
-void snmp_inc_icmpouttimeexcds(void);
-void snmp_inc_icmpoutparmprobs(void);
-void snmp_inc_icmpoutsrcquenchs(void);
-void snmp_inc_icmpoutredirects(void); 
-void snmp_inc_icmpoutechos(void);
-void snmp_inc_icmpoutechoreps(void);
-void snmp_inc_icmpouttimestamps(void);
-void snmp_inc_icmpouttimestampreps(void);
-void snmp_inc_icmpoutaddrmasks(void);
-void snmp_inc_icmpoutaddrmaskreps(void);
-
-/* TCP */
-void snmp_inc_tcpactiveopens(void);
-void snmp_inc_tcppassiveopens(void);
-void snmp_inc_tcpattemptfails(void);
-void snmp_inc_tcpestabresets(void);
-void snmp_inc_tcpcurrestab(void);
-void snmp_inc_tcpinsegs(void);
-void snmp_inc_tcpoutsegs(void);
-void snmp_inc_tcpretranssegs(void);
-void snmp_inc_tcpinerrs(void);
-void snmp_inc_tcpoutrsts(void);
-
-/* UDP */
-void snmp_inc_udpindatagrams(void);
-void snmp_inc_udpnoports(void);
-void snmp_inc_udpinerrors(void);
-void snmp_inc_udpoutdatagrams(void);
-
-/* LWIP_SNMP support not available */
-/* define everything to be empty */
-#else
-
-/* network interface */
-#define snmp_add_ifinoctets(value) 
-#define snmp_inc_ifinucastpkts()
-#define snmp_inc_ifinnucastpkts()
-#define snmp_inc_ifindiscards()
-#define snmp_add_ifoutoctets(value)
-#define snmp_inc_ifoutucastpkts()
-#define snmp_inc_ifoutnucastpkts()
-#define snmp_inc_ifoutdiscards()
-
-/* IP */
-#define snmp_inc_ipinreceives()
-#define snmp_inc_ipindelivers()
-#define snmp_inc_ipindiscards()
-#define snmp_inc_ipoutdiscards()
-#define snmp_inc_ipoutrequests()
-#define snmp_inc_ipunknownprotos()
-#define snmp_inc_ipnoroutes()
-#define snmp_inc_ipforwdatagrams()
-
-/* ICMP */
-#define snmp_inc_icmpinmsgs()
-#define snmp_inc_icmpinerrors() 
-#define snmp_inc_icmpindestunreachs() 
-#define snmp_inc_icmpintimeexcds()
-#define snmp_inc_icmpinparmprobs() 
-#define snmp_inc_icmpinsrcquenchs() 
-#define snmp_inc_icmpinredirects() 
-#define snmp_inc_icmpinechos() 
-#define snmp_inc_icmpinechoreps()
-#define snmp_inc_icmpintimestamps() 
-#define snmp_inc_icmpintimestampreps()
-#define snmp_inc_icmpinaddrmasks()
-#define snmp_inc_icmpinaddrmaskreps()
-#define snmp_inc_icmpoutmsgs()
-#define snmp_inc_icmpouterrors()
-#define snmp_inc_icmpoutdestunreachs() 
-#define snmp_inc_icmpouttimeexcds() 
-#define snmp_inc_icmpoutparmprobs()
-#define snmp_inc_icmpoutsrcquenchs()
-#define snmp_inc_icmpoutredirects() 
-#define snmp_inc_icmpoutechos() 
-#define snmp_inc_icmpoutechoreps()
-#define snmp_inc_icmpouttimestamps()
-#define snmp_inc_icmpouttimestampreps()
-#define snmp_inc_icmpoutaddrmasks()
-#define snmp_inc_icmpoutaddrmaskreps()
-/* TCP */
-#define snmp_inc_tcpactiveopens()
-#define snmp_inc_tcppassiveopens()
-#define snmp_inc_tcpattemptfails()
-#define snmp_inc_tcpestabresets()
-#define snmp_inc_tcpcurrestab()
-#define snmp_inc_tcpinsegs()
-#define snmp_inc_tcpoutsegs()
-#define snmp_inc_tcpretranssegs()
-#define snmp_inc_tcpinerrs()
-#define snmp_inc_tcpoutrsts()
-
-/* UDP */
-#define snmp_inc_udpindatagrams()
-#define snmp_inc_udpnoports()
-#define snmp_inc_udpinerrors()
-#define snmp_inc_udpoutdatagrams()
-
-#endif
-
-#endif /* __LWIP_SNMP_H__ */
+/*\r
+ * Copyright (c) 2001, 2002 Leon Woestenberg <leon.woestenberg@axon.tv>\r
+ * Copyright (c) 2001, 2002 Axon Digital Design B.V., The Netherlands.\r
+ * All rights reserved.\r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Leon Woestenberg <leon.woestenberg@axon.tv>\r
+ *\r
+ */\r
+#ifndef __LWIP_SNMP_H__\r
+#define __LWIP_SNMP_H__\r
+\r
+#include "lwip/opt.h"\r
+\r
+/* SNMP support available? */\r
+#if defined(LWIP_SNMP) && (LWIP_SNMP > 0)\r
+\r
+/* network interface */\r
+void snmp_add_ifinoctets(unsigned long value); \r
+void snmp_inc_ifinucastpkts(void);\r
+void snmp_inc_ifinnucastpkts(void);\r
+void snmp_inc_ifindiscards(void);\r
+void snmp_add_ifoutoctets(unsigned long value);\r
+void snmp_inc_ifoutucastpkts(void);\r
+void snmp_inc_ifoutnucastpkts(void);\r
+void snmp_inc_ifoutdiscards(void);\r
+\r
+/* IP */\r
+void snmp_inc_ipinreceives(void);\r
+void snmp_inc_ipindelivers(void);\r
+void snmp_inc_ipindiscards(void);\r
+void snmp_inc_ipoutdiscards(void);\r
+void snmp_inc_ipoutrequests(void);\r
+void snmp_inc_ipunknownprotos(void);\r
+void snmp_inc_ipnoroutes(void);\r
+void snmp_inc_ipforwdatagrams(void);\r
+\r
+/* ICMP */\r
+void snmp_inc_icmpinmsgs(void);\r
+void snmp_inc_icmpinerrors(void);\r
+void snmp_inc_icmpindestunreachs(void);\r
+void snmp_inc_icmpintimeexcds(void);\r
+void snmp_inc_icmpinparmprobs(void);\r
+void snmp_inc_icmpinsrcquenchs(void);\r
+void snmp_inc_icmpinredirects(void);\r
+void snmp_inc_icmpinechos(void);\r
+void snmp_inc_icmpinechoreps(void);\r
+void snmp_inc_icmpintimestamps(void);\r
+void snmp_inc_icmpintimestampreps(void);\r
+void snmp_inc_icmpinaddrmasks(void);\r
+void snmp_inc_icmpinaddrmaskreps(void);\r
+void snmp_inc_icmpoutmsgs(void);\r
+void snmp_inc_icmpouterrors(void);\r
+void snmp_inc_icmpoutdestunreachs(void);\r
+void snmp_inc_icmpouttimeexcds(void);\r
+void snmp_inc_icmpoutparmprobs(void);\r
+void snmp_inc_icmpoutsrcquenchs(void);\r
+void snmp_inc_icmpoutredirects(void); \r
+void snmp_inc_icmpoutechos(void);\r
+void snmp_inc_icmpoutechoreps(void);\r
+void snmp_inc_icmpouttimestamps(void);\r
+void snmp_inc_icmpouttimestampreps(void);\r
+void snmp_inc_icmpoutaddrmasks(void);\r
+void snmp_inc_icmpoutaddrmaskreps(void);\r
+\r
+/* TCP */\r
+void snmp_inc_tcpactiveopens(void);\r
+void snmp_inc_tcppassiveopens(void);\r
+void snmp_inc_tcpattemptfails(void);\r
+void snmp_inc_tcpestabresets(void);\r
+void snmp_inc_tcpcurrestab(void);\r
+void snmp_inc_tcpinsegs(void);\r
+void snmp_inc_tcpoutsegs(void);\r
+void snmp_inc_tcpretranssegs(void);\r
+void snmp_inc_tcpinerrs(void);\r
+void snmp_inc_tcpoutrsts(void);\r
+\r
+/* UDP */\r
+void snmp_inc_udpindatagrams(void);\r
+void snmp_inc_udpnoports(void);\r
+void snmp_inc_udpinerrors(void);\r
+void snmp_inc_udpoutdatagrams(void);\r
+\r
+/* LWIP_SNMP support not available */\r
+/* define everything to be empty */\r
+#else\r
+\r
+/* network interface */\r
+#define snmp_add_ifinoctets(value) \r
+#define snmp_inc_ifinucastpkts()\r
+#define snmp_inc_ifinnucastpkts()\r
+#define snmp_inc_ifindiscards()\r
+#define snmp_add_ifoutoctets(value)\r
+#define snmp_inc_ifoutucastpkts()\r
+#define snmp_inc_ifoutnucastpkts()\r
+#define snmp_inc_ifoutdiscards()\r
+\r
+/* IP */\r
+#define snmp_inc_ipinreceives()\r
+#define snmp_inc_ipindelivers()\r
+#define snmp_inc_ipindiscards()\r
+#define snmp_inc_ipoutdiscards()\r
+#define snmp_inc_ipoutrequests()\r
+#define snmp_inc_ipunknownprotos()\r
+#define snmp_inc_ipnoroutes()\r
+#define snmp_inc_ipforwdatagrams()\r
+\r
+/* ICMP */\r
+#define snmp_inc_icmpinmsgs()\r
+#define snmp_inc_icmpinerrors() \r
+#define snmp_inc_icmpindestunreachs() \r
+#define snmp_inc_icmpintimeexcds()\r
+#define snmp_inc_icmpinparmprobs() \r
+#define snmp_inc_icmpinsrcquenchs() \r
+#define snmp_inc_icmpinredirects() \r
+#define snmp_inc_icmpinechos() \r
+#define snmp_inc_icmpinechoreps()\r
+#define snmp_inc_icmpintimestamps() \r
+#define snmp_inc_icmpintimestampreps()\r
+#define snmp_inc_icmpinaddrmasks()\r
+#define snmp_inc_icmpinaddrmaskreps()\r
+#define snmp_inc_icmpoutmsgs()\r
+#define snmp_inc_icmpouterrors()\r
+#define snmp_inc_icmpoutdestunreachs() \r
+#define snmp_inc_icmpouttimeexcds() \r
+#define snmp_inc_icmpoutparmprobs()\r
+#define snmp_inc_icmpoutsrcquenchs()\r
+#define snmp_inc_icmpoutredirects() \r
+#define snmp_inc_icmpoutechos() \r
+#define snmp_inc_icmpoutechoreps()\r
+#define snmp_inc_icmpouttimestamps()\r
+#define snmp_inc_icmpouttimestampreps()\r
+#define snmp_inc_icmpoutaddrmasks()\r
+#define snmp_inc_icmpoutaddrmaskreps()\r
+/* TCP */\r
+#define snmp_inc_tcpactiveopens()\r
+#define snmp_inc_tcppassiveopens()\r
+#define snmp_inc_tcpattemptfails()\r
+#define snmp_inc_tcpestabresets()\r
+#define snmp_inc_tcpcurrestab()\r
+#define snmp_inc_tcpinsegs()\r
+#define snmp_inc_tcpoutsegs()\r
+#define snmp_inc_tcpretranssegs()\r
+#define snmp_inc_tcpinerrs()\r
+#define snmp_inc_tcpoutrsts()\r
+\r
+/* UDP */\r
+#define snmp_inc_udpindatagrams()\r
+#define snmp_inc_udpnoports()\r
+#define snmp_inc_udpinerrors()\r
+#define snmp_inc_udpoutdatagrams()\r
+\r
+#endif\r
+\r
+#endif /* __LWIP_SNMP_H__ */\r
index d5f8ccf74aa793629cb0fb081e347101f434e326..9c25035ad495dd9ef6650debfc4ae71638af74f1 100644 (file)
-/*
- * 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 <adam@sics.se>
- *
- */
-
-
-#ifndef __LWIP_SOCKETS_H__
-#define __LWIP_SOCKETS_H__
-#include "lwip/ip_addr.h"
-
-struct sockaddr_in {
-  u8_t sin_len;
-  u8_t sin_family;
-  u16_t sin_port;
-  struct in_addr sin_addr;
-  char sin_zero[8];
-};
-
-struct sockaddr {
-  u8_t sa_len;
-  u8_t sa_family;
-  char sa_data[14];
-};
-
-#ifndef socklen_t
-#  define socklen_t int
-#endif
-
-
-#define SOCK_STREAM     1
-#define SOCK_DGRAM      2
-#define SOCK_RAW        3
-
-/*
- * Option flags per-socket.
- */
-#define  SO_DEBUG  0x0001    /* turn on debugging info recording */
-#define  SO_ACCEPTCONN  0x0002    /* socket has had listen() */
-#define  SO_REUSEADDR  0x0004    /* allow local address reuse */
-#define  SO_KEEPALIVE  0x0008    /* keep connections alive */
-#define  SO_DONTROUTE  0x0010    /* just use interface addresses */
-#define  SO_BROADCAST  0x0020    /* permit sending of broadcast msgs */
-#define  SO_USELOOPBACK  0x0040    /* bypass hardware when possible */
-#define  SO_LINGER  0x0080    /* linger on close if data present */
-#define  SO_OOBINLINE  0x0100    /* leave received OOB data in line */
-#define         SO_REUSEPORT   0x0200          /* allow local address & port reuse */
-
-#define SO_DONTLINGER   (int)(~SO_LINGER)
-
-/*
- * Additional options, not kept in so_options.
- */
-#define SO_SNDBUF  0x1001    /* send buffer size */
-#define SO_RCVBUF  0x1002    /* receive buffer size */
-#define SO_SNDLOWAT  0x1003    /* send low-water mark */
-#define SO_RCVLOWAT  0x1004    /* receive low-water mark */
-#define SO_SNDTIMEO  0x1005    /* send timeout */
-#define SO_RCVTIMEO  0x1006    /* receive timeout */
-#define  SO_ERROR  0x1007    /* get error status and clear */
-#define  SO_TYPE    0x1008    /* get socket type */
-
-
-
-/*
- * Structure used for manipulating linger option.
- */
-struct linger {
-       int l_onoff;                /* option on/off */
-       int l_linger;               /* linger time */
-};
-
-/*
- * Level number for (get/set)sockopt() to apply to socket itself.
- */
-#define  SOL_SOCKET  0xfff    /* options for socket level */
-
-
-#define AF_UNSPEC       0
-#define AF_INET         2
-#define PF_INET         AF_INET
-#define PF_UNSPEC       AF_UNSPEC
-
-#define IPPROTO_IP      0
-#define IPPROTO_TCP     6
-#define IPPROTO_UDP     17
-
-#define INADDR_ANY      0
-#define INADDR_BROADCAST 0xffffffff
-
-/* Flags we can use with send and recv. */
-#define MSG_DONTWAIT    0x40            /* Nonblocking i/o for this operation only */
-
-
-/*
- * Options for level IPPROTO_IP
- */
-#define IP_TOS       1
-#define IP_TTL       2
-
-
-#define IPTOS_TOS_MASK          0x1E
-#define IPTOS_TOS(tos)          ((tos) & IPTOS_TOS_MASK)
-#define IPTOS_LOWDELAY          0x10
-#define IPTOS_THROUGHPUT        0x08
-#define IPTOS_RELIABILITY       0x04
-#define IPTOS_LOWCOST           0x02
-#define IPTOS_MINCOST           IPTOS_LOWCOST
-
-/*
- * Definitions for IP precedence (also in ip_tos) (hopefully unused)
- */
-#define IPTOS_PREC_MASK                 0xe0
-#define IPTOS_PREC(tos)                ((tos) & IPTOS_PREC_MASK)
-#define IPTOS_PREC_NETCONTROL           0xe0
-#define IPTOS_PREC_INTERNETCONTROL      0xc0
-#define IPTOS_PREC_CRITIC_ECP           0xa0
-#define IPTOS_PREC_FLASHOVERRIDE        0x80
-#define IPTOS_PREC_FLASH                0x60
-#define IPTOS_PREC_IMMEDIATE            0x40
-#define IPTOS_PREC_PRIORITY             0x20
-#define IPTOS_PREC_ROUTINE              0x00
-
-
-/*
- * Commands for ioctlsocket(),  taken from the BSD file fcntl.h.
- *
- *
- * Ioctl's have the command encoded in the lower word,
- * and the size of any in or out parameters in the upper
- * word.  The high 2 bits of the upper word are used
- * to encode the in/out status of the parameter; for now
- * we restrict parameters to at most 128 bytes.
- */
-#if !defined(FIONREAD) || !defined(FIONBIO)
-#define IOCPARM_MASK    0x7f            /* parameters must be < 128 bytes */
-#define IOC_VOID        0x20000000      /* no parameters */
-#define IOC_OUT         0x40000000      /* copy out parameters */
-#define IOC_IN          0x80000000      /* copy in parameters */
-#define IOC_INOUT       (IOC_IN|IOC_OUT)
-                                        /* 0x20000000 distinguishes new &
-                                           old ioctl's */
-#define _IO(x,y)        (IOC_VOID|((x)<<8)|(y))
-
-#define _IOR(x,y,t)     (IOC_OUT|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y))
-
-#define _IOW(x,y,t)     (IOC_IN|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y))
-#endif
-
-#ifndef FIONREAD
-#define FIONREAD    _IOR('f', 127, unsigned long) /* get # bytes to read */
-#endif
-#ifndef FIONBIO
-#define FIONBIO     _IOW('f', 126, unsigned long) /* set/clear non-blocking i/o */
-#endif
-
-/* Socket I/O Controls */
-#ifndef SIOCSHIWAT
-#define SIOCSHIWAT  _IOW('s',  0, unsigned long)  /* set high watermark */
-#define SIOCGHIWAT  _IOR('s',  1, unsigned long)  /* get high watermark */
-#define SIOCSLOWAT  _IOW('s',  2, unsigned long)  /* set low watermark */
-#define SIOCGLOWAT  _IOR('s',  3, unsigned long)  /* get low watermark */
-#define SIOCATMARK  _IOR('s',  7, unsigned long)  /* at oob mark? */
-#endif
-
-#ifndef O_NONBLOCK
-#define O_NONBLOCK    04000U
-#endif
-
-#ifndef FD_SET
-  #undef  FD_SETSIZE
-  #define FD_SETSIZE    16
-  #define FD_SET(n, p)  ((p)->fd_bits[(n)/8] |=  (1 << ((n) & 7)))
-  #define FD_CLR(n, p)  ((p)->fd_bits[(n)/8] &= ~(1 << ((n) & 7)))
-  #define FD_ISSET(n,p) ((p)->fd_bits[(n)/8] &   (1 << ((n) & 7)))
-  #define FD_ZERO(p)    memset((void*)(p),0,sizeof(*(p)))
-
-  typedef struct fd_set {
-          unsigned char fd_bits [(FD_SETSIZE+7)/8];
-        } fd_set;
-
-/* 
- * only define this in sockets.c so it does not interfere
- * with other projects namespaces where timeval is present
- */ 
-#ifndef LWIP_TIMEVAL_PRIVATE
-#define LWIP_TIMEVAL_PRIVATE 1
-#endif
-
-#if LWIP_TIMEVAL_PRIVATE
-  struct timeval {
-    long    tv_sec;         /* seconds */
-    long    tv_usec;        /* and microseconds */
-  };
-#endif
-
-#endif
-
-int lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen);
-int lwip_bind(int s, struct sockaddr *name, socklen_t namelen);
-int lwip_shutdown(int s, int how);
-int lwip_getpeername (int s, struct sockaddr *name, socklen_t *namelen);
-int lwip_getsockname (int s, struct sockaddr *name, socklen_t *namelen);
-int lwip_getsockopt (int s, int level, int optname, void *optval, socklen_t *optlen);
-int lwip_setsockopt (int s, int level, int optname, const void *optval, socklen_t optlen);
-int lwip_close(int s);
-int lwip_connect(int s, struct sockaddr *name, socklen_t namelen);
-int lwip_listen(int s, int backlog);
-int lwip_recv(int s, void *mem, int len, unsigned int flags);
-int lwip_read(int s, void *mem, int len);
-int lwip_recvfrom(int s, void *mem, int len, unsigned int flags,
-      struct sockaddr *from, socklen_t *fromlen);
-int lwip_send(int s, void *dataptr, int size, unsigned int flags);
-int lwip_sendto(int s, void *dataptr, int size, unsigned int flags,
-    struct sockaddr *to, socklen_t tolen);
-int lwip_socket(int domain, int type, int protocol);
-int lwip_write(int s, void *dataptr, int size);
-int lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
-                struct timeval *timeout);
-int lwip_ioctl(int s, long cmd, void *argp);
-
-#if LWIP_COMPAT_SOCKETS
-#define accept(a,b,c)         lwip_accept(a,b,c)
-#define bind(a,b,c)           lwip_bind(a,b,c)
-#define shutdown(a,b)         lwip_shutdown(a,b)
-#define close(s)              lwip_close(s)
-#define connect(a,b,c)        lwip_connect(a,b,c)
-#define getsockname(a,b,c)    lwip_getsockname(a,b,c)
-#define getpeername(a,b,c)    lwip_getpeername(a,b,c)
-#define setsockopt(a,b,c,d,e) lwip_setsockopt(a,b,c,d,e)
-#define getsockopt(a,b,c,d,e) lwip_getsockopt(a,b,c,d,e)
-#define listen(a,b)           lwip_listen(a,b)
-#define recv(a,b,c,d)         lwip_recv(a,b,c,d)
-#define read(a,b,c)           lwip_read(a,b,c)
-#define recvfrom(a,b,c,d,e,f) lwip_recvfrom(a,b,c,d,e,f)
-#define send(a,b,c,d)         lwip_send(a,b,c,d)
-#define sendto(a,b,c,d,e,f)   lwip_sendto(a,b,c,d,e,f)
-#define socket(a,b,c)         lwip_socket(a,b,c)
-#define write(a,b,c)          lwip_write(a,b,c)
-#define select(a,b,c,d,e)     lwip_select(a,b,c,d,e)
-#define ioctlsocket(a,b,c)    lwip_ioctl(a,b,c)
-#endif /* LWIP_COMPAT_SOCKETS */
-
-#endif /* __LWIP_SOCKETS_H__ */
-
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+\r
+\r
+#ifndef __LWIP_SOCKETS_H__\r
+#define __LWIP_SOCKETS_H__\r
+#include "lwip/ip_addr.h"\r
+\r
+struct sockaddr_in {\r
+  u8_t sin_len;\r
+  u8_t sin_family;\r
+  u16_t sin_port;\r
+  struct in_addr sin_addr;\r
+  char sin_zero[8];\r
+};\r
+\r
+struct sockaddr {\r
+  u8_t sa_len;\r
+  u8_t sa_family;\r
+  char sa_data[14];\r
+};\r
+\r
+#ifndef socklen_t\r
+#  define socklen_t int\r
+#endif\r
+\r
+\r
+#define SOCK_STREAM     1\r
+#define SOCK_DGRAM      2\r
+#define SOCK_RAW        3\r
+\r
+/*\r
+ * Option flags per-socket.\r
+ */\r
+#define  SO_DEBUG  0x0001    /* turn on debugging info recording */\r
+#define  SO_ACCEPTCONN  0x0002    /* socket has had listen() */\r
+#define  SO_REUSEADDR  0x0004    /* allow local address reuse */\r
+#define  SO_KEEPALIVE  0x0008    /* keep connections alive */\r
+#define  SO_DONTROUTE  0x0010    /* just use interface addresses */\r
+#define  SO_BROADCAST  0x0020    /* permit sending of broadcast msgs */\r
+#define  SO_USELOOPBACK  0x0040    /* bypass hardware when possible */\r
+#define  SO_LINGER  0x0080    /* linger on close if data present */\r
+#define  SO_OOBINLINE  0x0100    /* leave received OOB data in line */\r
+#define         SO_REUSEPORT   0x0200          /* allow local address & port reuse */\r
+\r
+#define SO_DONTLINGER   (int)(~SO_LINGER)\r
+\r
+/*\r
+ * Additional options, not kept in so_options.\r
+ */\r
+#define SO_SNDBUF  0x1001    /* send buffer size */\r
+#define SO_RCVBUF  0x1002    /* receive buffer size */\r
+#define SO_SNDLOWAT  0x1003    /* send low-water mark */\r
+#define SO_RCVLOWAT  0x1004    /* receive low-water mark */\r
+#define SO_SNDTIMEO  0x1005    /* send timeout */\r
+#define SO_RCVTIMEO  0x1006    /* receive timeout */\r
+#define  SO_ERROR  0x1007    /* get error status and clear */\r
+#define  SO_TYPE    0x1008    /* get socket type */\r
+\r
+\r
+\r
+/*\r
+ * Structure used for manipulating linger option.\r
+ */\r
+struct linger {\r
+       int l_onoff;                /* option on/off */\r
+       int l_linger;               /* linger time */\r
+};\r
+\r
+/*\r
+ * Level number for (get/set)sockopt() to apply to socket itself.\r
+ */\r
+#define  SOL_SOCKET  0xfff    /* options for socket level */\r
+\r
+\r
+#define AF_UNSPEC       0\r
+#define AF_INET         2\r
+#define PF_INET         AF_INET\r
+#define PF_UNSPEC       AF_UNSPEC\r
+\r
+#define IPPROTO_IP      0\r
+#define IPPROTO_TCP     6\r
+#define IPPROTO_UDP     17\r
+\r
+#define INADDR_ANY      0\r
+#define INADDR_BROADCAST 0xffffffff\r
+\r
+/* Flags we can use with send and recv. */\r
+#define MSG_DONTWAIT    0x40            /* Nonblocking i/o for this operation only */\r
+\r
+\r
+/*\r
+ * Options for level IPPROTO_IP\r
+ */\r
+#define IP_TOS       1\r
+#define IP_TTL       2\r
+\r
+\r
+#define IPTOS_TOS_MASK          0x1E\r
+#define IPTOS_TOS(tos)          ((tos) & IPTOS_TOS_MASK)\r
+#define IPTOS_LOWDELAY          0x10\r
+#define IPTOS_THROUGHPUT        0x08\r
+#define IPTOS_RELIABILITY       0x04\r
+#define IPTOS_LOWCOST           0x02\r
+#define IPTOS_MINCOST           IPTOS_LOWCOST\r
+\r
+/*\r
+ * Definitions for IP precedence (also in ip_tos) (hopefully unused)\r
+ */\r
+#define IPTOS_PREC_MASK                 0xe0\r
+#define IPTOS_PREC(tos)                ((tos) & IPTOS_PREC_MASK)\r
+#define IPTOS_PREC_NETCONTROL           0xe0\r
+#define IPTOS_PREC_INTERNETCONTROL      0xc0\r
+#define IPTOS_PREC_CRITIC_ECP           0xa0\r
+#define IPTOS_PREC_FLASHOVERRIDE        0x80\r
+#define IPTOS_PREC_FLASH                0x60\r
+#define IPTOS_PREC_IMMEDIATE            0x40\r
+#define IPTOS_PREC_PRIORITY             0x20\r
+#define IPTOS_PREC_ROUTINE              0x00\r
+\r
+\r
+/*\r
+ * Commands for ioctlsocket(),  taken from the BSD file fcntl.h.\r
+ *\r
+ *\r
+ * Ioctl's have the command encoded in the lower word,\r
+ * and the size of any in or out parameters in the upper\r
+ * word.  The high 2 bits of the upper word are used\r
+ * to encode the in/out status of the parameter; for now\r
+ * we restrict parameters to at most 128 bytes.\r
+ */\r
+#if !defined(FIONREAD) || !defined(FIONBIO)\r
+#define IOCPARM_MASK    0x7f            /* parameters must be < 128 bytes */\r
+#define IOC_VOID        0x20000000      /* no parameters */\r
+#define IOC_OUT         0x40000000      /* copy out parameters */\r
+#define IOC_IN          0x80000000      /* copy in parameters */\r
+#define IOC_INOUT       (IOC_IN|IOC_OUT)\r
+                                        /* 0x20000000 distinguishes new &\r
+                                           old ioctl's */\r
+#define _IO(x,y)        (IOC_VOID|((x)<<8)|(y))\r
+\r
+#define _IOR(x,y,t)     (IOC_OUT|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y))\r
+\r
+#define _IOW(x,y,t)     (IOC_IN|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y))\r
+#endif\r
+\r
+#ifndef FIONREAD\r
+#define FIONREAD    _IOR('f', 127, unsigned long) /* get # bytes to read */\r
+#endif\r
+#ifndef FIONBIO\r
+#define FIONBIO     _IOW('f', 126, unsigned long) /* set/clear non-blocking i/o */\r
+#endif\r
+\r
+/* Socket I/O Controls */\r
+#ifndef SIOCSHIWAT\r
+#define SIOCSHIWAT  _IOW('s',  0, unsigned long)  /* set high watermark */\r
+#define SIOCGHIWAT  _IOR('s',  1, unsigned long)  /* get high watermark */\r
+#define SIOCSLOWAT  _IOW('s',  2, unsigned long)  /* set low watermark */\r
+#define SIOCGLOWAT  _IOR('s',  3, unsigned long)  /* get low watermark */\r
+#define SIOCATMARK  _IOR('s',  7, unsigned long)  /* at oob mark? */\r
+#endif\r
+\r
+#ifndef O_NONBLOCK\r
+#define O_NONBLOCK    04000U\r
+#endif\r
+\r
+#ifndef FD_SET\r
+  #undef  FD_SETSIZE\r
+  #define FD_SETSIZE    16\r
+  #define FD_SET(n, p)  ((p)->fd_bits[(n)/8] |=  (1 << ((n) & 7)))\r
+  #define FD_CLR(n, p)  ((p)->fd_bits[(n)/8] &= ~(1 << ((n) & 7)))\r
+  #define FD_ISSET(n,p) ((p)->fd_bits[(n)/8] &   (1 << ((n) & 7)))\r
+  #define FD_ZERO(p)    memset((void*)(p),0,sizeof(*(p)))\r
+\r
+  typedef struct fd_set {\r
+          unsigned char fd_bits [(FD_SETSIZE+7)/8];\r
+        } fd_set;\r
+\r
+/* \r
+ * only define this in sockets.c so it does not interfere\r
+ * with other projects namespaces where timeval is present\r
+ */ \r
+#ifndef LWIP_TIMEVAL_PRIVATE\r
+#define LWIP_TIMEVAL_PRIVATE 1\r
+#endif\r
+\r
+#if LWIP_TIMEVAL_PRIVATE\r
+  struct timeval {\r
+    long    tv_sec;         /* seconds */\r
+    long    tv_usec;        /* and microseconds */\r
+  };\r
+#endif\r
+\r
+#endif\r
+\r
+int lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen);\r
+int lwip_bind(int s, struct sockaddr *name, socklen_t namelen);\r
+int lwip_shutdown(int s, int how);\r
+int lwip_getpeername (int s, struct sockaddr *name, socklen_t *namelen);\r
+int lwip_getsockname (int s, struct sockaddr *name, socklen_t *namelen);\r
+int lwip_getsockopt (int s, int level, int optname, void *optval, socklen_t *optlen);\r
+int lwip_setsockopt (int s, int level, int optname, const void *optval, socklen_t optlen);\r
+int lwip_close(int s);\r
+int lwip_connect(int s, struct sockaddr *name, socklen_t namelen);\r
+int lwip_listen(int s, int backlog);\r
+int lwip_recv(int s, void *mem, int len, unsigned int flags);\r
+int lwip_read(int s, void *mem, int len);\r
+int lwip_recvfrom(int s, void *mem, int len, unsigned int flags,\r
+      struct sockaddr *from, socklen_t *fromlen);\r
+int lwip_send(int s, void *dataptr, int size, unsigned int flags);\r
+int lwip_sendto(int s, void *dataptr, int size, unsigned int flags,\r
+    struct sockaddr *to, socklen_t tolen);\r
+int lwip_socket(int domain, int type, int protocol);\r
+int lwip_write(int s, void *dataptr, int size);\r
+int lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,\r
+                struct timeval *timeout);\r
+int lwip_ioctl(int s, long cmd, void *argp);\r
+\r
+#if LWIP_COMPAT_SOCKETS\r
+#define accept(a,b,c)         lwip_accept(a,b,c)\r
+#define bind(a,b,c)           lwip_bind(a,b,c)\r
+#define shutdown(a,b)         lwip_shutdown(a,b)\r
+#define close(s)              lwip_close(s)\r
+#define connect(a,b,c)        lwip_connect(a,b,c)\r
+#define getsockname(a,b,c)    lwip_getsockname(a,b,c)\r
+#define getpeername(a,b,c)    lwip_getpeername(a,b,c)\r
+#define setsockopt(a,b,c,d,e) lwip_setsockopt(a,b,c,d,e)\r
+#define getsockopt(a,b,c,d,e) lwip_getsockopt(a,b,c,d,e)\r
+#define listen(a,b)           lwip_listen(a,b)\r
+#define recv(a,b,c,d)         lwip_recv(a,b,c,d)\r
+#define read(a,b,c)           lwip_read(a,b,c)\r
+#define recvfrom(a,b,c,d,e,f) lwip_recvfrom(a,b,c,d,e,f)\r
+#define send(a,b,c,d)         lwip_send(a,b,c,d)\r
+#define sendto(a,b,c,d,e,f)   lwip_sendto(a,b,c,d,e,f)\r
+#define socket(a,b,c)         lwip_socket(a,b,c)\r
+#define write(a,b,c)          lwip_write(a,b,c)\r
+#define select(a,b,c,d,e)     lwip_select(a,b,c,d,e)\r
+#define ioctlsocket(a,b,c)    lwip_ioctl(a,b,c)\r
+#endif /* LWIP_COMPAT_SOCKETS */\r
+\r
+#endif /* __LWIP_SOCKETS_H__ */\r
+\r
index 71acfd068f3730beedf233d4089d6edeb5fedab4..29dfd5731e13b9ebec3eb506a8e3333f0cfa7a9b 100644 (file)
-/*
- * 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 <adam@sics.se>
- *
- */
-#ifndef __LWIP_STATS_H__
-#define __LWIP_STATS_H__
-
-#include "lwip/opt.h"
-#include "arch/cc.h"
-
-#include "lwip/mem.h"
-#include "lwip/memp.h"
-
-#if LWIP_STATS
-
-struct stats_proto {
-  u16_t xmit;    /* Transmitted packets. */
-  u16_t rexmit;  /* Retransmitted packets. */
-  u16_t recv;    /* Received packets. */
-  u16_t fw;      /* Forwarded packets. */
-  u16_t drop;    /* Dropped packets. */
-  u16_t chkerr;  /* Checksum error. */
-  u16_t lenerr;  /* Invalid length error. */
-  u16_t memerr;  /* Out of memory error. */
-  u16_t rterr;   /* Routing error. */
-  u16_t proterr; /* Protocol error. */
-  u16_t opterr;  /* Error in options. */
-  u16_t err;     /* Misc error. */
-  u16_t cachehit;
-};
-
-struct stats_mem {
-  mem_size_t avail;
-  mem_size_t used;
-  mem_size_t max;  
-  mem_size_t err;
-};
-
-struct stats_pbuf {
-  u16_t avail;
-  u16_t used;
-  u16_t max;  
-  u16_t err;
-
-  u16_t alloc_locked;
-  u16_t refresh_locked;
-};
-
-struct stats_syselem {
-  u16_t used;
-  u16_t max;
-  u16_t err;
-};
-
-struct stats_sys {
-  struct stats_syselem sem;
-  struct stats_syselem mbox;
-};
-
-struct stats_ {
-  struct stats_proto link;
-  struct stats_proto ip_frag;
-  struct stats_proto ip;
-  struct stats_proto icmp;
-  struct stats_proto udp;
-  struct stats_proto tcp;
-  struct stats_pbuf pbuf;
-  struct stats_mem mem;
-  struct stats_mem memp[MEMP_MAX];
-  struct stats_sys sys;
-};
-
-extern struct stats_ lwip_stats;
-
-
-void stats_init(void);
-
-#define STATS_INC(x) ++lwip_stats.x
-#else
-#define stats_init()
-#define STATS_INC(x)
-#endif /* LWIP_STATS */
-
-#if TCP_STATS
-#define TCP_STATS_INC(x) STATS_INC(x)
-#else
-#define TCP_STATS_INC(x)
-#endif
-
-#if UDP_STATS
-#define UDP_STATS_INC(x) STATS_INC(x)
-#else
-#define UDP_STATS_INC(x)
-#endif
-
-#if ICMP_STATS
-#define ICMP_STATS_INC(x) STATS_INC(x)
-#else
-#define ICMP_STATS_INC(x)
-#endif
-
-#if IP_STATS
-#define IP_STATS_INC(x) STATS_INC(x)
-#else
-#define IP_STATS_INC(x)
-#endif
-
-#if IPFRAG_STATS
-#define IPFRAG_STATS_INC(x) STATS_INC(x)
-#else
-#define IPFRAG_STATS_INC(x)
-#endif
-
-#if LINK_STATS
-#define LINK_STATS_INC(x) STATS_INC(x)
-#else
-#define LINK_STATS_INC(x)
-#endif
-
-/* Display of statistics */
-#if LWIP_STATS_DISPLAY
-void stats_display(void);
-#else
-#define stats_display()
-#endif
-
-#endif /* __LWIP_STATS_H__ */
-
-
-
-
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+#ifndef __LWIP_STATS_H__\r
+#define __LWIP_STATS_H__\r
+\r
+#include "lwip/opt.h"\r
+#include "arch/cc.h"\r
+\r
+#include "lwip/mem.h"\r
+#include "lwip/memp.h"\r
+\r
+#if LWIP_STATS\r
+\r
+struct stats_proto {\r
+  u16_t xmit;    /* Transmitted packets. */\r
+  u16_t rexmit;  /* Retransmitted packets. */\r
+  u16_t recv;    /* Received packets. */\r
+  u16_t fw;      /* Forwarded packets. */\r
+  u16_t drop;    /* Dropped packets. */\r
+  u16_t chkerr;  /* Checksum error. */\r
+  u16_t lenerr;  /* Invalid length error. */\r
+  u16_t memerr;  /* Out of memory error. */\r
+  u16_t rterr;   /* Routing error. */\r
+  u16_t proterr; /* Protocol error. */\r
+  u16_t opterr;  /* Error in options. */\r
+  u16_t err;     /* Misc error. */\r
+  u16_t cachehit;\r
+};\r
+\r
+struct stats_mem {\r
+  mem_size_t avail;\r
+  mem_size_t used;\r
+  mem_size_t max;  \r
+  mem_size_t err;\r
+};\r
+\r
+struct stats_pbuf {\r
+  u16_t avail;\r
+  u16_t used;\r
+  u16_t max;  \r
+  u16_t err;\r
+\r
+  u16_t alloc_locked;\r
+  u16_t refresh_locked;\r
+};\r
+\r
+struct stats_syselem {\r
+  u16_t used;\r
+  u16_t max;\r
+  u16_t err;\r
+};\r
+\r
+struct stats_sys {\r
+  struct stats_syselem sem;\r
+  struct stats_syselem mbox;\r
+};\r
+\r
+struct stats_ {\r
+  struct stats_proto link;\r
+  struct stats_proto ip_frag;\r
+  struct stats_proto ip;\r
+  struct stats_proto icmp;\r
+  struct stats_proto udp;\r
+  struct stats_proto tcp;\r
+  struct stats_pbuf pbuf;\r
+  struct stats_mem mem;\r
+  struct stats_mem memp[MEMP_MAX];\r
+  struct stats_sys sys;\r
+};\r
+\r
+extern struct stats_ lwip_stats;\r
+\r
+\r
+void stats_init(void);\r
+\r
+#define STATS_INC(x) ++lwip_stats.x\r
+#else\r
+#define stats_init()\r
+#define STATS_INC(x)\r
+#endif /* LWIP_STATS */\r
+\r
+#if TCP_STATS\r
+#define TCP_STATS_INC(x) STATS_INC(x)\r
+#else\r
+#define TCP_STATS_INC(x)\r
+#endif\r
+\r
+#if UDP_STATS\r
+#define UDP_STATS_INC(x) STATS_INC(x)\r
+#else\r
+#define UDP_STATS_INC(x)\r
+#endif\r
+\r
+#if ICMP_STATS\r
+#define ICMP_STATS_INC(x) STATS_INC(x)\r
+#else\r
+#define ICMP_STATS_INC(x)\r
+#endif\r
+\r
+#if IP_STATS\r
+#define IP_STATS_INC(x) STATS_INC(x)\r
+#else\r
+#define IP_STATS_INC(x)\r
+#endif\r
+\r
+#if IPFRAG_STATS\r
+#define IPFRAG_STATS_INC(x) STATS_INC(x)\r
+#else\r
+#define IPFRAG_STATS_INC(x)\r
+#endif\r
+\r
+#if LINK_STATS\r
+#define LINK_STATS_INC(x) STATS_INC(x)\r
+#else\r
+#define LINK_STATS_INC(x)\r
+#endif\r
+\r
+/* Display of statistics */\r
+#if LWIP_STATS_DISPLAY\r
+void stats_display(void);\r
+#else\r
+#define stats_display()\r
+#endif\r
+\r
+#endif /* __LWIP_STATS_H__ */\r
+\r
+\r
+\r
+\r
index 68926e95420ea3bb6419808a8d468e147568744c..d2328c4622f2629265f9121cb45c5abadc9fc702 100644 (file)
-/*
- * 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 <adam@sics.se>
- *
- */
-#ifndef __LWIP_SYS_H__
-#define __LWIP_SYS_H__
-
-#include "arch/cc.h"
-
-#include "lwip/opt.h"
-
-
-#if NO_SYS
-
-/* For a totally minimal and standalone system, we provide null
-   definitions of the sys_ functions. */
-typedef u8_t sys_sem_t;
-typedef u8_t sys_mbox_t;
-struct sys_timeout {u8_t dummy;};
-
-#define sys_init()
-#define sys_timeout(m,h,a)
-#define sys_untimeout(m,a)
-#define sys_sem_new(c) c
-#define sys_sem_signal(s)
-#define sys_sem_wait(s)
-#define sys_sem_free(s)
-#define sys_mbox_new() 0
-#define sys_mbox_fetch(m,d)
-#define sys_mbox_post(m,d)
-#define sys_mbox_free(m)
-
-#define sys_thread_new(t,a,p)
-
-#else /* NO_SYS */
-
-#include "arch/sys_arch.h"
-
-/** Return code for timeouts from sys_arch_mbox_fetch and sys_arch_sem_wait */
-#define SYS_ARCH_TIMEOUT 0xffffffff
-
-typedef void (* sys_timeout_handler)(void *arg);
-
-struct sys_timeout {
-  struct sys_timeout *next;
-  u32_t time;
-  sys_timeout_handler h;
-  void *arg;
-};
-
-struct sys_timeouts {
-  struct sys_timeout *next;
-};
-
-/* sys_init() must be called before anthing else. */
-void sys_init(void);
-
-/*
- * sys_timeout():
- *
- * Schedule a timeout a specified amount of milliseconds in the
- * future. When the timeout occurs, the specified timeout handler will
- * be called. The handler will be passed the "arg" argument when
- * called.
- *
- */
-void sys_timeout(u32_t msecs, sys_timeout_handler h, void *arg);
-void sys_untimeout(sys_timeout_handler h, void *arg);
-struct sys_timeouts *sys_arch_timeouts(void);
-
-/* Semaphore functions. */
-sys_sem_t sys_sem_new(u8_t count);
-void sys_sem_signal(sys_sem_t sem);
-u32_t sys_arch_sem_wait(sys_sem_t sem, u32_t timeout);
-void sys_sem_free(sys_sem_t sem);
-void sys_sem_wait(sys_sem_t sem);
-int sys_sem_wait_timeout(sys_sem_t sem, u32_t timeout);
-
-/* Time functions. */
-#ifndef sys_msleep
-void sys_msleep(u32_t ms); /* only has a (close to) 1 jiffy resolution. */
-#endif
-#ifndef sys_jiffies
-u32_t sys_jiffies(void); /* since power up. */
-#endif
-
-/* Mailbox functions. */
-sys_mbox_t sys_mbox_new(void);
-void sys_mbox_post(sys_mbox_t mbox, void *msg);
-u32_t sys_arch_mbox_fetch(sys_mbox_t mbox, void **msg, u32_t timeout);
-void sys_mbox_free(sys_mbox_t mbox);
-void sys_mbox_fetch(sys_mbox_t mbox, void **msg);
-
-
-/* Thread functions. */
-sys_thread_t sys_thread_new(void (* thread)(void *arg), void *arg, int prio);
-
-/* The following functions are used only in Unix code, and
-   can be omitted when porting the stack. */
-/* Returns the current time in microseconds. */
-unsigned long sys_now(void);
-
-#endif /* NO_SYS */
-
-/* Critical Region Protection */
-/* These functions must be implemented in the sys_arch.c file.
-   In some implementations they can provide a more light-weight protection
-   mechanism than using semaphores. Otherwise semaphores can be used for
-   implementation */
-#ifndef SYS_ARCH_PROTECT
-/** SYS_LIGHTWEIGHT_PROT
- * define SYS_LIGHTWEIGHT_PROT in lwipopts.h if you want inter-task protection
- * for certain critical regions during buffer allocation, deallocation and memory
- * allocation and deallocation.
- */
-#if SYS_LIGHTWEIGHT_PROT
-
-/** SYS_ARCH_DECL_PROTECT
- * declare a protection variable. This macro will default to defining a variable of
- * type sys_prot_t. If a particular port needs a different implementation, then
- * this macro may be defined in sys_arch.h.
- */
-#define SYS_ARCH_DECL_PROTECT(lev) sys_prot_t lev
-/** SYS_ARCH_PROTECT
- * Perform a "fast" protect. This could be implemented by
- * disabling interrupts for an embedded system or by using a semaphore or
- * mutex. The implementation should allow calling SYS_ARCH_PROTECT when
- * already protected. The old protection level is returned in the variable
- * "lev". This macro will default to calling the sys_arch_protect() function
- * which should be implemented in sys_arch.c. If a particular port needs a
- * different implementation, then this macro may be defined in sys_arch.h
- */
-#define SYS_ARCH_PROTECT(lev) lev = sys_arch_protect()
-/** SYS_ARCH_UNPROTECT
- * Perform a "fast" set of the protection level to "lev". This could be
- * implemented by setting the interrupt level to "lev" within the MACRO or by
- * using a semaphore or mutex.  This macro will default to calling the
- * sys_arch_unprotect() function which should be implemented in
- * sys_arch.c. If a particular port needs a different implementation, then
- * this macro may be defined in sys_arch.h
- */
-#define SYS_ARCH_UNPROTECT(lev) sys_arch_unprotect(lev)
-sys_prot_t sys_arch_protect(void);
-void sys_arch_unprotect(sys_prot_t pval);
-
-#else
-
-#define SYS_ARCH_DECL_PROTECT(lev)
-#define SYS_ARCH_PROTECT(lev)
-#define SYS_ARCH_UNPROTECT(lev)
-
-#endif /* SYS_LIGHTWEIGHT_PROT */
-
-#endif /* SYS_ARCH_PROTECT */
-
-#endif /* __LWIP_SYS_H__ */
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+#ifndef __LWIP_SYS_H__\r
+#define __LWIP_SYS_H__\r
+\r
+#include "arch/cc.h"\r
+\r
+#include "lwip/opt.h"\r
+\r
+\r
+#if NO_SYS\r
+\r
+/* For a totally minimal and standalone system, we provide null\r
+   definitions of the sys_ functions. */\r
+typedef u8_t sys_sem_t;\r
+typedef u8_t sys_mbox_t;\r
+struct sys_timeout {u8_t dummy;};\r
+\r
+#define sys_init()\r
+#define sys_timeout(m,h,a)\r
+#define sys_untimeout(m,a)\r
+#define sys_sem_new(c) c\r
+#define sys_sem_signal(s)\r
+#define sys_sem_wait(s)\r
+#define sys_sem_free(s)\r
+#define sys_mbox_new() 0\r
+#define sys_mbox_fetch(m,d)\r
+#define sys_mbox_post(m,d)\r
+#define sys_mbox_free(m)\r
+\r
+#define sys_thread_new(t,a,p)\r
+\r
+#else /* NO_SYS */\r
+\r
+#include "arch/sys_arch.h"\r
+\r
+/** Return code for timeouts from sys_arch_mbox_fetch and sys_arch_sem_wait */\r
+#define SYS_ARCH_TIMEOUT 0xffffffff\r
+\r
+typedef void (* sys_timeout_handler)(void *arg);\r
+\r
+struct sys_timeout {\r
+  struct sys_timeout *next;\r
+  u32_t time;\r
+  sys_timeout_handler h;\r
+  void *arg;\r
+};\r
+\r
+struct sys_timeouts {\r
+  struct sys_timeout *next;\r
+};\r
+\r
+/* sys_init() must be called before anthing else. */\r
+void sys_init(void);\r
+\r
+/*\r
+ * sys_timeout():\r
+ *\r
+ * Schedule a timeout a specified amount of milliseconds in the\r
+ * future. When the timeout occurs, the specified timeout handler will\r
+ * be called. The handler will be passed the "arg" argument when\r
+ * called.\r
+ *\r
+ */\r
+void sys_timeout(u32_t msecs, sys_timeout_handler h, void *arg);\r
+void sys_untimeout(sys_timeout_handler h, void *arg);\r
+struct sys_timeouts *sys_arch_timeouts(void);\r
+\r
+/* Semaphore functions. */\r
+sys_sem_t sys_sem_new(u8_t count);\r
+void sys_sem_signal(sys_sem_t sem);\r
+u32_t sys_arch_sem_wait(sys_sem_t sem, u32_t timeout);\r
+void sys_sem_free(sys_sem_t sem);\r
+void sys_sem_wait(sys_sem_t sem);\r
+int sys_sem_wait_timeout(sys_sem_t sem, u32_t timeout);\r
+\r
+/* Time functions. */\r
+#ifndef sys_msleep\r
+void sys_msleep(u32_t ms); /* only has a (close to) 1 jiffy resolution. */\r
+#endif\r
+#ifndef sys_jiffies\r
+u32_t sys_jiffies(void); /* since power up. */\r
+#endif\r
+\r
+/* Mailbox functions. */\r
+sys_mbox_t sys_mbox_new(void);\r
+void sys_mbox_post(sys_mbox_t mbox, void *msg);\r
+u32_t sys_arch_mbox_fetch(sys_mbox_t mbox, void **msg, u32_t timeout);\r
+void sys_mbox_free(sys_mbox_t mbox);\r
+void sys_mbox_fetch(sys_mbox_t mbox, void **msg);\r
+\r
+\r
+/* Thread functions. */\r
+sys_thread_t sys_thread_new(void (* thread)(void *arg), void *arg, int prio);\r
+\r
+/* The following functions are used only in Unix code, and\r
+   can be omitted when porting the stack. */\r
+/* Returns the current time in microseconds. */\r
+unsigned long sys_now(void);\r
+\r
+#endif /* NO_SYS */\r
+\r
+/* Critical Region Protection */\r
+/* These functions must be implemented in the sys_arch.c file.\r
+   In some implementations they can provide a more light-weight protection\r
+   mechanism than using semaphores. Otherwise semaphores can be used for\r
+   implementation */\r
+#ifndef SYS_ARCH_PROTECT\r
+/** SYS_LIGHTWEIGHT_PROT\r
+ * define SYS_LIGHTWEIGHT_PROT in lwipopts.h if you want inter-task protection\r
+ * for certain critical regions during buffer allocation, deallocation and memory\r
+ * allocation and deallocation.\r
+ */\r
+#if SYS_LIGHTWEIGHT_PROT\r
+\r
+/** SYS_ARCH_DECL_PROTECT\r
+ * declare a protection variable. This macro will default to defining a variable of\r
+ * type sys_prot_t. If a particular port needs a different implementation, then\r
+ * this macro may be defined in sys_arch.h.\r
+ */\r
+#define SYS_ARCH_DECL_PROTECT(lev) sys_prot_t lev\r
+/** SYS_ARCH_PROTECT\r
+ * Perform a "fast" protect. This could be implemented by\r
+ * disabling interrupts for an embedded system or by using a semaphore or\r
+ * mutex. The implementation should allow calling SYS_ARCH_PROTECT when\r
+ * already protected. The old protection level is returned in the variable\r
+ * "lev". This macro will default to calling the sys_arch_protect() function\r
+ * which should be implemented in sys_arch.c. If a particular port needs a\r
+ * different implementation, then this macro may be defined in sys_arch.h\r
+ */\r
+#define SYS_ARCH_PROTECT(lev) lev = sys_arch_protect()\r
+/** SYS_ARCH_UNPROTECT\r
+ * Perform a "fast" set of the protection level to "lev". This could be\r
+ * implemented by setting the interrupt level to "lev" within the MACRO or by\r
+ * using a semaphore or mutex.  This macro will default to calling the\r
+ * sys_arch_unprotect() function which should be implemented in\r
+ * sys_arch.c. If a particular port needs a different implementation, then\r
+ * this macro may be defined in sys_arch.h\r
+ */\r
+#define SYS_ARCH_UNPROTECT(lev) sys_arch_unprotect(lev)\r
+sys_prot_t sys_arch_protect(void);\r
+void sys_arch_unprotect(sys_prot_t pval);\r
+\r
+#else\r
+\r
+#define SYS_ARCH_DECL_PROTECT(lev)\r
+#define SYS_ARCH_PROTECT(lev)\r
+#define SYS_ARCH_UNPROTECT(lev)\r
+\r
+#endif /* SYS_LIGHTWEIGHT_PROT */\r
+\r
+#endif /* SYS_ARCH_PROTECT */\r
+\r
+#endif /* __LWIP_SYS_H__ */\r
index 5f968c684321e80163bb9fe0c9362564bb1c5ec0..1395e41610a922df45ae9dcd61a28c12394cef6d 100644 (file)
-/*
- * 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 <adam@sics.se>
- *
- */
-#ifndef __LWIP_TCP_H__
-#define __LWIP_TCP_H__
-
-#include "lwip/sys.h"
-#include "lwip/mem.h"
-
-#include "lwip/pbuf.h"
-#include "lwip/opt.h"
-#include "lwip/ip.h"
-#include "lwip/icmp.h"
-
-#include "lwip/err.h"
-
-struct tcp_pcb;
-
-/* Functions for interfacing with TCP: */
-
-/* Lower layer interface to TCP: */
-void             tcp_init    (void);  /* Must be called first to
-           initialize TCP. */
-void             tcp_tmr     (void);  /* Must be called every
-           TCP_TMR_INTERVAL
-           ms. (Typically 250 ms). */
-/* Application program's interface: */
-struct tcp_pcb * tcp_new     (void);
-struct tcp_pcb * tcp_alloc   (u8_t prio);
-
-void             tcp_arg     (struct tcp_pcb *pcb, void *arg);
-void             tcp_accept  (struct tcp_pcb *pcb,
-            err_t (* accept)(void *arg, struct tcp_pcb *newpcb,
-                 err_t err));
-void             tcp_recv    (struct tcp_pcb *pcb,
-            err_t (* recv)(void *arg, struct tcp_pcb *tpcb,
-          struct pbuf *p, err_t err));
-void             tcp_sent    (struct tcp_pcb *pcb,
-            err_t (* sent)(void *arg, struct tcp_pcb *tpcb,
-               u16_t len));
-void             tcp_poll    (struct tcp_pcb *pcb,
-            err_t (* poll)(void *arg, struct tcp_pcb *tpcb),
-            u8_t interval);
-void             tcp_err     (struct tcp_pcb *pcb,
-            void (* err)(void *arg, err_t err));
-
-#define          tcp_mss(pcb)      ((pcb)->mss)
-#define          tcp_sndbuf(pcb)   ((pcb)->snd_buf)
-
-void             tcp_recved  (struct tcp_pcb *pcb, u16_t len);
-err_t            tcp_bind    (struct tcp_pcb *pcb, struct ip_addr *ipaddr,
-            u16_t port);
-err_t            tcp_connect (struct tcp_pcb *pcb, struct ip_addr *ipaddr,
-            u16_t port, err_t (* connected)(void *arg,
-                    struct tcp_pcb *tpcb,
-                    err_t err));
-struct tcp_pcb * tcp_listen  (struct tcp_pcb *pcb);
-void             tcp_abort   (struct tcp_pcb *pcb);
-err_t            tcp_close   (struct tcp_pcb *pcb);
-err_t            tcp_write   (struct tcp_pcb *pcb, const void *dataptr, u16_t len,
-            u8_t copy);
-
-void             tcp_setprio (struct tcp_pcb *pcb, u8_t prio);
-
-#define TCP_PRIO_MIN    1
-#define TCP_PRIO_NORMAL 64
-#define TCP_PRIO_MAX    127
-
-/* It is also possible to call these two functions at the right
-   intervals (instead of calling tcp_tmr()). */
-void             tcp_slowtmr (void);
-void             tcp_fasttmr (void);
-
-
-/* Only used by IP to pass a TCP segment to TCP: */
-void             tcp_input   (struct pbuf *p, struct netif *inp);
-/* Used within the TCP code only: */
-err_t            tcp_output  (struct tcp_pcb *pcb);
-void             tcp_rexmit  (struct tcp_pcb *pcb);
-void             tcp_rexmit_rto  (struct tcp_pcb *pcb);
-
-
-
-#define TCP_SEQ_LT(a,b)     ((s32_t)((a)-(b)) < 0)
-#define TCP_SEQ_LEQ(a,b)    ((s32_t)((a)-(b)) <= 0)
-#define TCP_SEQ_GT(a,b)     ((s32_t)((a)-(b)) > 0)
-#define TCP_SEQ_GEQ(a,b)    ((s32_t)((a)-(b)) >= 0)
-/* is b<=a<=c? */
-#if 0 /* see bug #10548 */
-#define TCP_SEQ_BETWEEN(a,b,c) ((c)-(b) >= (a)-(b))
-#endif
-#define TCP_SEQ_BETWEEN(a,b,c) (TCP_SEQ_GEQ(a,b) && TCP_SEQ_LEQ(a,c))
-#define TCP_FIN 0x01U
-#define TCP_SYN 0x02U
-#define TCP_RST 0x04U
-#define TCP_PSH 0x08U
-#define TCP_ACK 0x10U
-#define TCP_URG 0x20U
-#define TCP_ECE 0x40U
-#define TCP_CWR 0x80U
-
-#define TCP_FLAGS 0x3fU
-
-/* Length of the TCP header, excluding options. */
-#define TCP_HLEN 20
-
-#ifndef TCP_TMR_INTERVAL
-#define TCP_TMR_INTERVAL       250  /* The TCP timer interval in
-                                       milliseconds. */
-#endif /* TCP_TMR_INTERVAL */
-
-#ifndef TCP_FAST_INTERVAL
-#define TCP_FAST_INTERVAL      TCP_TMR_INTERVAL /* the fine grained timeout in
-                                       milliseconds */
-#endif /* TCP_FAST_INTERVAL */
-
-#ifndef TCP_SLOW_INTERVAL
-#define TCP_SLOW_INTERVAL      (2*TCP_TMR_INTERVAL)  /* the coarse grained timeout in
-                                       milliseconds */
-#endif /* TCP_SLOW_INTERVAL */
-
-#define TCP_FIN_WAIT_TIMEOUT 20000 /* milliseconds */
-#define TCP_SYN_RCVD_TIMEOUT 20000 /* milliseconds */
-
-#define TCP_OOSEQ_TIMEOUT        6 /* x RTO */
-
-#define TCP_MSL 60000  /* The maximum segment lifetime in microseconds */
-
-/*
- * User-settable options (used with setsockopt).
- */
-#define        TCP_NODELAY        0x01    /* don't delay send to coalesce packets */
-#define TCP_KEEPALIVE  0x02    /* send KEEPALIVE probes when idle for pcb->keepalive miliseconds */
-
-/* Keepalive values */
-#define  TCP_KEEPDEFAULT   7200000                       /* KEEPALIVE timer in miliseconds */
-#define  TCP_KEEPINTVL     75000                         /* Time between KEEPALIVE probes in miliseconds */
-#define  TCP_KEEPCNT       9                             /* Counter for KEEPALIVE probes */
-#define  TCP_MAXIDLE       TCP_KEEPCNT * TCP_KEEPINTVL   /* Maximum KEEPALIVE probe time */
-
-
-#ifdef PACK_STRUCT_USE_INCLUDES
-#  include "arch/bpstruct.h"
-#endif
-PACK_STRUCT_BEGIN
-struct tcp_hdr {
-  PACK_STRUCT_FIELD(u16_t src);
-  PACK_STRUCT_FIELD(u16_t dest);
-  PACK_STRUCT_FIELD(u32_t seqno);
-  PACK_STRUCT_FIELD(u32_t ackno);
-  PACK_STRUCT_FIELD(u16_t _hdrlen_rsvd_flags);
-  PACK_STRUCT_FIELD(u16_t wnd);
-  PACK_STRUCT_FIELD(u16_t chksum);
-  PACK_STRUCT_FIELD(u16_t urgp);
-} PACK_STRUCT_STRUCT;
-PACK_STRUCT_END
-#ifdef PACK_STRUCT_USE_INCLUDES
-#  include "arch/epstruct.h"
-#endif
-
-#define TCPH_OFFSET(phdr) (ntohs((phdr)->_hdrlen_rsvd_flags) >> 8)
-#define TCPH_HDRLEN(phdr) (ntohs((phdr)->_hdrlen_rsvd_flags) >> 12)
-#define TCPH_FLAGS(phdr)  (ntohs((phdr)->_hdrlen_rsvd_flags) & TCP_FLAGS)
-
-#define TCPH_OFFSET_SET(phdr, offset) (phdr)->_hdrlen_rsvd_flags = htons(((offset) << 8) | TCPH_FLAGS(phdr))
-#define TCPH_HDRLEN_SET(phdr, len) (phdr)->_hdrlen_rsvd_flags = htons(((len) << 12) | TCPH_FLAGS(phdr))
-#define TCPH_FLAGS_SET(phdr, flags) (phdr)->_hdrlen_rsvd_flags = htons((ntohs((phdr)->_hdrlen_rsvd_flags) & ~TCP_FLAGS) | (flags))
-#define TCPH_SET_FLAG(phdr, flags ) (phdr)->_hdrlen_rsvd_flags = htons(ntohs((phdr)->_hdrlen_rsvd_flags) | (flags))
-#define TCPH_UNSET_FLAG(phdr, flags) (phdr)->_hdrlen_rsvd_flags = htons(ntohs((phdr)->_hdrlen_rsvd_flags) | (TCPH_FLAGS(phdr) & ~(flags)) )
-
-#define TCP_TCPLEN(seg) ((seg)->len + ((TCPH_FLAGS((seg)->tcphdr) & TCP_FIN || \
-          TCPH_FLAGS((seg)->tcphdr) & TCP_SYN)? 1: 0))
-
-enum tcp_state {
-  CLOSED      = 0,
-  LISTEN      = 1,
-  SYN_SENT    = 2,
-  SYN_RCVD    = 3,
-  ESTABLISHED = 4,
-  FIN_WAIT_1  = 5,
-  FIN_WAIT_2  = 6,
-  CLOSE_WAIT  = 7,
-  CLOSING     = 8,
-  LAST_ACK    = 9,
-  TIME_WAIT   = 10
-};
-
-/* the TCP protocol control block */
-struct tcp_pcb {
-/** common PCB members */
-  IP_PCB;
-/** protocol specific PCB members */
-  struct tcp_pcb *next; /* for the linked list */
-  enum tcp_state state; /* TCP state */
-  u8_t prio;
-  void *callback_arg;
-
-  u16_t local_port;
-  u16_t remote_port;
-  
-  u8_t flags;
-#define TF_ACK_DELAY (u8_t)0x01U   /* Delayed ACK. */
-#define TF_ACK_NOW   (u8_t)0x02U   /* Immediate ACK. */
-#define TF_INFR      (u8_t)0x04U   /* In fast recovery. */
-#define TF_RESET     (u8_t)0x08U   /* Connection was reset. */
-#define TF_CLOSED    (u8_t)0x10U   /* Connection was sucessfully closed. */
-#define TF_GOT_FIN   (u8_t)0x20U   /* Connection was closed by the remote end. */
-#define TF_NODELAY   (u8_t)0x40U   /* Disable Nagle algorithm */
-
-  /* receiver variables */
-  u32_t rcv_nxt;   /* next seqno expected */
-  u16_t rcv_wnd;   /* receiver window */
-  
-  /* Timers */
-  u32_t tmr;
-  u8_t polltmr, pollinterval;
-  
-  /* Retransmission timer. */
-  u16_t rtime;
-  
-  u16_t mss;   /* maximum segment size */
-  
-  /* RTT (round trip time) estimation variables */
-  u32_t rttest; /* RTT estimate in 500ms ticks */
-  u32_t rtseq;  /* sequence number being timed */
-  s16_t sa, sv; /* @todo document this */
-
-  u16_t rto;    /* retransmission time-out */
-  u8_t nrtx;    /* number of retransmissions */
-
-  /* fast retransmit/recovery */
-  u32_t lastack; /* Highest acknowledged seqno. */
-  u8_t dupacks;
-  
-  /* congestion avoidance/control variables */
-  u16_t cwnd;  
-  u16_t ssthresh;
-
-  /* sender variables */
-  u32_t snd_nxt,       /* next seqno to be sent */
-    snd_max,       /* Highest seqno sent. */
-    snd_wnd,       /* sender window */
-    snd_wl1, snd_wl2, /* Sequence and acknowledgement numbers of last
-       window update. */
-    snd_lbb;       /* Sequence number of next byte to be buffered. */
-
-  u16_t acked;
-  
-  u16_t snd_buf;   /* Available buffer space for sending (in bytes). */
-  u8_t snd_queuelen; /* Available buffer space for sending (in tcp_segs). */
-  
-  
-  /* These are ordered by sequence number: */
-  struct tcp_seg *unsent;   /* Unsent (queued) segments. */
-  struct tcp_seg *unacked;  /* Sent but unacknowledged segments. */
-#if TCP_QUEUE_OOSEQ  
-  struct tcp_seg *ooseq;    /* Received out of sequence segments. */
-#endif /* TCP_QUEUE_OOSEQ */
-
-#if LWIP_CALLBACK_API
-  /* Function to be called when more send buffer space is available. */
-  err_t (* sent)(void *arg, struct tcp_pcb *pcb, u16_t space);
-  
-  /* Function to be called when (in-sequence) data has arrived. */
-  err_t (* recv)(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err);
-
-  /* Function to be called when a connection has been set up. */
-  err_t (* connected)(void *arg, struct tcp_pcb *pcb, err_t err);
-
-  /* Function to call when a listener has been connected. */
-  err_t (* accept)(void *arg, struct tcp_pcb *newpcb, err_t err);
-
-  /* Function which is called periodically. */
-  err_t (* poll)(void *arg, struct tcp_pcb *pcb);
-
-  /* Function to be called whenever a fatal error occurs. */
-  void (* errf)(void *arg, err_t err);
-#endif /* LWIP_CALLBACK_API */
-
-  /* idle time before KEEPALIVE is sent */
-  u32_t keepalive;
-  
-  /* KEEPALIVE counter */
-  u8_t keep_cnt;
-};
-
-struct tcp_pcb_listen {  
-/* Common members of all PCB types */
-  IP_PCB;
-
-/* Protocol specific PCB members */
-  struct tcp_pcb_listen *next;   /* for the linked list */
-  
-  /* Even if state is obviously LISTEN this is here for
-   * field compatibility with tpc_pcb to which it is cast sometimes
-   * Until a cleaner solution emerges this is here.FIXME
-   */ 
-  enum tcp_state state;   /* TCP state */
-
-  u8_t prio;
-  void *callback_arg;
-  
-  u16_t local_port; 
-
-#if LWIP_CALLBACK_API
-  /* Function to call when a listener has been connected. */
-  err_t (* accept)(void *arg, struct tcp_pcb *newpcb, err_t err);
-#endif /* LWIP_CALLBACK_API */
-};
-
-#if LWIP_EVENT_API
-
-enum lwip_event {
-  LWIP_EVENT_ACCEPT,
-  LWIP_EVENT_SENT,
-  LWIP_EVENT_RECV,
-  LWIP_EVENT_CONNECTED,
-  LWIP_EVENT_POLL,
-  LWIP_EVENT_ERR
-};
-
-err_t lwip_tcp_event(void *arg, struct tcp_pcb *pcb,
-         enum lwip_event,
-         struct pbuf *p,
-         u16_t size,
-         err_t err);
-
-#define TCP_EVENT_ACCEPT(pcb,err,ret)    ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\
-                LWIP_EVENT_ACCEPT, NULL, 0, err)
-#define TCP_EVENT_SENT(pcb,space,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\
-                   LWIP_EVENT_SENT, NULL, space, ERR_OK)
-#define TCP_EVENT_RECV(pcb,p,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\
-                LWIP_EVENT_RECV, (p), 0, (err))
-#define TCP_EVENT_CONNECTED(pcb,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\
-                LWIP_EVENT_CONNECTED, NULL, 0, (err))
-#define TCP_EVENT_POLL(pcb,ret)       ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\
-                LWIP_EVENT_POLL, NULL, 0, ERR_OK)
-#define TCP_EVENT_ERR(errf,arg,err)  lwip_tcp_event((arg), NULL, \
-                LWIP_EVENT_ERR, NULL, 0, (err))
-#else /* LWIP_EVENT_API */
-#define TCP_EVENT_ACCEPT(pcb,err,ret)     \
-                        if((pcb)->accept != NULL) \
-                        (ret = (pcb)->accept((pcb)->callback_arg,(pcb),(err)))
-#define TCP_EVENT_SENT(pcb,space,ret) \
-                        if((pcb)->sent != NULL) \
-                        (ret = (pcb)->sent((pcb)->callback_arg,(pcb),(space)))
-#define TCP_EVENT_RECV(pcb,p,err,ret) \
-                        if((pcb)->recv != NULL) \
-                        { ret = (pcb)->recv((pcb)->callback_arg,(pcb),(p),(err)); } else { \
-                          if (p) pbuf_free(p); }
-#define TCP_EVENT_CONNECTED(pcb,err,ret) \
-                        if((pcb)->connected != NULL) \
-                        (ret = (pcb)->connected((pcb)->callback_arg,(pcb),(err)))
-#define TCP_EVENT_POLL(pcb,ret) \
-                        if((pcb)->poll != NULL) \
-                        (ret = (pcb)->poll((pcb)->callback_arg,(pcb)))
-#define TCP_EVENT_ERR(errf,arg,err) \
-                        if((errf) != NULL) \
-                        (errf)((arg),(err))
-#endif /* LWIP_EVENT_API */
-
-/* This structure represents a TCP segment on the unsent and unacked queues */
-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 */
-  struct tcp_hdr *tcphdr;  /* the TCP header */
-};
-
-/* Internal functions and global variables: */
-struct tcp_pcb *tcp_pcb_copy(struct tcp_pcb *pcb);
-void tcp_pcb_purge(struct tcp_pcb *pcb);
-void tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb);
-
-u8_t tcp_segs_free(struct tcp_seg *seg);
-u8_t tcp_seg_free(struct tcp_seg *seg);
-struct tcp_seg *tcp_seg_copy(struct tcp_seg *seg);
-
-#define tcp_ack(pcb)     if((pcb)->flags & TF_ACK_DELAY) { \
-                            (pcb)->flags &= ~TF_ACK_DELAY; \
-                            (pcb)->flags |= TF_ACK_NOW; \
-                            tcp_output(pcb); \
-                         } else { \
-                            (pcb)->flags |= TF_ACK_DELAY; \
-                         }
-
-#define tcp_ack_now(pcb) (pcb)->flags |= TF_ACK_NOW; \
-                         tcp_output(pcb)
-
-err_t tcp_send_ctrl(struct tcp_pcb *pcb, u8_t flags);
-err_t tcp_enqueue(struct tcp_pcb *pcb, void *dataptr, u16_t len,
-    u8_t flags, u8_t copy,
-                u8_t *optdata, u8_t optlen);
-
-void tcp_rexmit_seg(struct tcp_pcb *pcb, struct tcp_seg *seg);
-
-void tcp_rst(u32_t seqno, u32_t ackno,
-       struct ip_addr *local_ip, struct ip_addr *remote_ip,
-       u16_t local_port, u16_t remote_port);
-
-u32_t tcp_next_iss(void);
-
-void tcp_keepalive(struct tcp_pcb *pcb);
-
-extern struct tcp_pcb *tcp_input_pcb;
-extern u32_t tcp_ticks;
-
-#if TCP_DEBUG || TCP_INPUT_DEBUG || TCP_OUTPUT_DEBUG
-void tcp_debug_print(struct tcp_hdr *tcphdr);
-void tcp_debug_print_flags(u8_t flags);
-void tcp_debug_print_state(enum tcp_state s);
-void tcp_debug_print_pcbs(void);
-s16_t tcp_pcbs_sane(void);
-#else
-#  define tcp_debug_print(tcphdr)
-#  define tcp_debug_print_flags(flags)
-#  define tcp_debug_print_state(s)
-#  define tcp_debug_print_pcbs()
-#  define tcp_pcbs_sane() 1
-#endif /* TCP_DEBUG */
-
-#if NO_SYS
-#define tcp_timer_needed()
-#else
-void tcp_timer_needed(void);
-#endif
-
-/* The TCP PCB lists. */
-union tcp_listen_pcbs_t { /* List of all TCP PCBs in LISTEN state. */
-       struct tcp_pcb_listen *listen_pcbs; 
-       struct tcp_pcb *pcbs;
-};
-extern union tcp_listen_pcbs_t tcp_listen_pcbs;
-extern struct tcp_pcb *tcp_active_pcbs;  /* List of all TCP PCBs that are in a
-              state in which they accept or send
-              data. */
-extern struct tcp_pcb *tcp_tw_pcbs;      /* List of all TCP PCBs in TIME-WAIT. */
-
-extern struct tcp_pcb *tcp_tmp_pcb;      /* Only used for temporary storage. */
-
-/* Axioms about the above lists:   
-   1) Every TCP PCB that is not CLOSED is in one of the lists.
-   2) A PCB is only in one of the lists.
-   3) All PCBs in the tcp_listen_pcbs list is in LISTEN state.
-   4) All PCBs in the tcp_tw_pcbs list is in TIME-WAIT state.
-*/
-
-/* Define two macros, TCP_REG and TCP_RMV that registers a TCP PCB
-   with a PCB list or removes a PCB from a list, respectively. */
-#if 0
-#define TCP_REG(pcbs, npcb) do {\
-                            LWIP_DEBUGF(TCP_DEBUG, ("TCP_REG %p local port %d\n", npcb, npcb->local_port)); \
-                            for(tcp_tmp_pcb = *pcbs; \
-          tcp_tmp_pcb != NULL; \
-        tcp_tmp_pcb = tcp_tmp_pcb->next) { \
-                                LWIP_ASSERT("TCP_REG: already registered\n", tcp_tmp_pcb != npcb); \
-                            } \
-                            LWIP_ASSERT("TCP_REG: pcb->state != CLOSED", npcb->state != CLOSED); \
-                            npcb->next = *pcbs; \
-                            LWIP_ASSERT("TCP_REG: npcb->next != npcb", npcb->next != npcb); \
-                            *(pcbs) = npcb; \
-                            LWIP_ASSERT("TCP_RMV: tcp_pcbs sane", tcp_pcbs_sane()); \
-              tcp_timer_needed(); \
-                            } while(0)
-#define TCP_RMV(pcbs, npcb) do { \
-                            LWIP_ASSERT("TCP_RMV: pcbs != NULL", *pcbs != NULL); \
-                            LWIP_DEBUGF(TCP_DEBUG, ("TCP_RMV: removing %p from %p\n", npcb, *pcbs)); \
-                            if(*pcbs == npcb) { \
-                               *pcbs = (*pcbs)->next; \
-                            } else for(tcp_tmp_pcb = *pcbs; tcp_tmp_pcb != NULL; tcp_tmp_pcb = tcp_tmp_pcb->next) { \
-                               if(tcp_tmp_pcb->next != NULL && tcp_tmp_pcb->next == npcb) { \
-                                  tcp_tmp_pcb->next = npcb->next; \
-                                  break; \
-                               } \
-                            } \
-                            npcb->next = NULL; \
-                            LWIP_ASSERT("TCP_RMV: tcp_pcbs sane", tcp_pcbs_sane()); \
-                            LWIP_DEBUGF(TCP_DEBUG, ("TCP_RMV: removed %p from %p\n", npcb, *pcbs)); \
-                            } while(0)
-
-#else /* LWIP_DEBUG */
-#define TCP_REG(pcbs, npcb) do { \
-                            npcb->next = *pcbs; \
-                            *(pcbs) = npcb; \
-              tcp_timer_needed(); \
-                            } while(0)
-#define TCP_RMV(pcbs, npcb) do { \
-                            if(*(pcbs) == npcb) { \
-                               (*(pcbs)) = (*pcbs)->next; \
-                            } else for(tcp_tmp_pcb = *pcbs; tcp_tmp_pcb != NULL; tcp_tmp_pcb = tcp_tmp_pcb->next) { \
-                               if(tcp_tmp_pcb->next != NULL && tcp_tmp_pcb->next == npcb) { \
-                                  tcp_tmp_pcb->next = npcb->next; \
-                                  break; \
-                               } \
-                            } \
-                            npcb->next = NULL; \
-                            } while(0)
-#endif /* LWIP_DEBUG */
-#endif /* __LWIP_TCP_H__ */
-
-
-
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+#ifndef __LWIP_TCP_H__\r
+#define __LWIP_TCP_H__\r
+\r
+#include "lwip/sys.h"\r
+#include "lwip/mem.h"\r
+\r
+#include "lwip/pbuf.h"\r
+#include "lwip/opt.h"\r
+#include "lwip/ip.h"\r
+#include "lwip/icmp.h"\r
+\r
+#include "lwip/err.h"\r
+\r
+struct tcp_pcb;\r
+\r
+/* Functions for interfacing with TCP: */\r
+\r
+/* Lower layer interface to TCP: */\r
+void             tcp_init    (void);  /* Must be called first to\r
+           initialize TCP. */\r
+void             tcp_tmr     (void);  /* Must be called every\r
+           TCP_TMR_INTERVAL\r
+           ms. (Typically 250 ms). */\r
+/* Application program's interface: */\r
+struct tcp_pcb * tcp_new     (void);\r
+struct tcp_pcb * tcp_alloc   (u8_t prio);\r
+\r
+void             tcp_arg     (struct tcp_pcb *pcb, void *arg);\r
+void             tcp_accept  (struct tcp_pcb *pcb,\r
+            err_t (* accept)(void *arg, struct tcp_pcb *newpcb,\r
+                 err_t err));\r
+void             tcp_recv    (struct tcp_pcb *pcb,\r
+            err_t (* recv)(void *arg, struct tcp_pcb *tpcb,\r
+          struct pbuf *p, err_t err));\r
+void             tcp_sent    (struct tcp_pcb *pcb,\r
+            err_t (* sent)(void *arg, struct tcp_pcb *tpcb,\r
+               u16_t len));\r
+void             tcp_poll    (struct tcp_pcb *pcb,\r
+            err_t (* poll)(void *arg, struct tcp_pcb *tpcb),\r
+            u8_t interval);\r
+void             tcp_err     (struct tcp_pcb *pcb,\r
+            void (* err)(void *arg, err_t err));\r
+\r
+#define          tcp_mss(pcb)      ((pcb)->mss)\r
+#define          tcp_sndbuf(pcb)   ((pcb)->snd_buf)\r
+\r
+void             tcp_recved  (struct tcp_pcb *pcb, u16_t len);\r
+err_t            tcp_bind    (struct tcp_pcb *pcb, struct ip_addr *ipaddr,\r
+            u16_t port);\r
+err_t            tcp_connect (struct tcp_pcb *pcb, struct ip_addr *ipaddr,\r
+            u16_t port, err_t (* connected)(void *arg,\r
+                    struct tcp_pcb *tpcb,\r
+                    err_t err));\r
+struct tcp_pcb * tcp_listen  (struct tcp_pcb *pcb);\r
+void             tcp_abort   (struct tcp_pcb *pcb);\r
+err_t            tcp_close   (struct tcp_pcb *pcb);\r
+err_t            tcp_write   (struct tcp_pcb *pcb, const void *dataptr, u16_t len,\r
+            u8_t copy);\r
+\r
+void             tcp_setprio (struct tcp_pcb *pcb, u8_t prio);\r
+\r
+#define TCP_PRIO_MIN    1\r
+#define TCP_PRIO_NORMAL 64\r
+#define TCP_PRIO_MAX    127\r
+\r
+/* It is also possible to call these two functions at the right\r
+   intervals (instead of calling tcp_tmr()). */\r
+void             tcp_slowtmr (void);\r
+void             tcp_fasttmr (void);\r
+\r
+\r
+/* Only used by IP to pass a TCP segment to TCP: */\r
+void             tcp_input   (struct pbuf *p, struct netif *inp);\r
+/* Used within the TCP code only: */\r
+err_t            tcp_output  (struct tcp_pcb *pcb);\r
+void             tcp_rexmit  (struct tcp_pcb *pcb);\r
+void             tcp_rexmit_rto  (struct tcp_pcb *pcb);\r
+\r
+\r
+\r
+#define TCP_SEQ_LT(a,b)     ((s32_t)((a)-(b)) < 0)\r
+#define TCP_SEQ_LEQ(a,b)    ((s32_t)((a)-(b)) <= 0)\r
+#define TCP_SEQ_GT(a,b)     ((s32_t)((a)-(b)) > 0)\r
+#define TCP_SEQ_GEQ(a,b)    ((s32_t)((a)-(b)) >= 0)\r
+/* is b<=a<=c? */\r
+#if 0 /* see bug #10548 */\r
+#define TCP_SEQ_BETWEEN(a,b,c) ((c)-(b) >= (a)-(b))\r
+#endif\r
+#define TCP_SEQ_BETWEEN(a,b,c) (TCP_SEQ_GEQ(a,b) && TCP_SEQ_LEQ(a,c))\r
+#define TCP_FIN 0x01U\r
+#define TCP_SYN 0x02U\r
+#define TCP_RST 0x04U\r
+#define TCP_PSH 0x08U\r
+#define TCP_ACK 0x10U\r
+#define TCP_URG 0x20U\r
+#define TCP_ECE 0x40U\r
+#define TCP_CWR 0x80U\r
+\r
+#define TCP_FLAGS 0x3fU\r
+\r
+/* Length of the TCP header, excluding options. */\r
+#define TCP_HLEN 20\r
+\r
+#ifndef TCP_TMR_INTERVAL\r
+#define TCP_TMR_INTERVAL       250  /* The TCP timer interval in\r
+                                       milliseconds. */\r
+#endif /* TCP_TMR_INTERVAL */\r
+\r
+#ifndef TCP_FAST_INTERVAL\r
+#define TCP_FAST_INTERVAL      TCP_TMR_INTERVAL /* the fine grained timeout in\r
+                                       milliseconds */\r
+#endif /* TCP_FAST_INTERVAL */\r
+\r
+#ifndef TCP_SLOW_INTERVAL\r
+#define TCP_SLOW_INTERVAL      (2*TCP_TMR_INTERVAL)  /* the coarse grained timeout in\r
+                                       milliseconds */\r
+#endif /* TCP_SLOW_INTERVAL */\r
+\r
+#define TCP_FIN_WAIT_TIMEOUT 20000 /* milliseconds */\r
+#define TCP_SYN_RCVD_TIMEOUT 20000 /* milliseconds */\r
+\r
+#define TCP_OOSEQ_TIMEOUT        6 /* x RTO */\r
+\r
+#define TCP_MSL 60000  /* The maximum segment lifetime in microseconds */\r
+\r
+/*\r
+ * User-settable options (used with setsockopt).\r
+ */\r
+#define        TCP_NODELAY        0x01    /* don't delay send to coalesce packets */\r
+#define TCP_KEEPALIVE  0x02    /* send KEEPALIVE probes when idle for pcb->keepalive miliseconds */\r
+\r
+/* Keepalive values */\r
+#define  TCP_KEEPDEFAULT   7200000                       /* KEEPALIVE timer in miliseconds */\r
+#define  TCP_KEEPINTVL     75000                         /* Time between KEEPALIVE probes in miliseconds */\r
+#define  TCP_KEEPCNT       9                             /* Counter for KEEPALIVE probes */\r
+#define  TCP_MAXIDLE       TCP_KEEPCNT * TCP_KEEPINTVL   /* Maximum KEEPALIVE probe time */\r
+\r
+\r
+#ifdef PACK_STRUCT_USE_INCLUDES\r
+#  include "arch/bpstruct.h"\r
+#endif\r
+PACK_STRUCT_BEGIN\r
+struct tcp_hdr {\r
+  PACK_STRUCT_FIELD(u16_t src);\r
+  PACK_STRUCT_FIELD(u16_t dest);\r
+  PACK_STRUCT_FIELD(u32_t seqno);\r
+  PACK_STRUCT_FIELD(u32_t ackno);\r
+  PACK_STRUCT_FIELD(u16_t _hdrlen_rsvd_flags);\r
+  PACK_STRUCT_FIELD(u16_t wnd);\r
+  PACK_STRUCT_FIELD(u16_t chksum);\r
+  PACK_STRUCT_FIELD(u16_t urgp);\r
+} PACK_STRUCT_STRUCT;\r
+PACK_STRUCT_END\r
+#ifdef PACK_STRUCT_USE_INCLUDES\r
+#  include "arch/epstruct.h"\r
+#endif\r
+\r
+#define TCPH_OFFSET(phdr) (ntohs((phdr)->_hdrlen_rsvd_flags) >> 8)\r
+#define TCPH_HDRLEN(phdr) (ntohs((phdr)->_hdrlen_rsvd_flags) >> 12)\r
+#define TCPH_FLAGS(phdr)  (ntohs((phdr)->_hdrlen_rsvd_flags) & TCP_FLAGS)\r
+\r
+#define TCPH_OFFSET_SET(phdr, offset) (phdr)->_hdrlen_rsvd_flags = htons(((offset) << 8) | TCPH_FLAGS(phdr))\r
+#define TCPH_HDRLEN_SET(phdr, len) (phdr)->_hdrlen_rsvd_flags = htons(((len) << 12) | TCPH_FLAGS(phdr))\r
+#define TCPH_FLAGS_SET(phdr, flags) (phdr)->_hdrlen_rsvd_flags = htons((ntohs((phdr)->_hdrlen_rsvd_flags) & ~TCP_FLAGS) | (flags))\r
+#define TCPH_SET_FLAG(phdr, flags ) (phdr)->_hdrlen_rsvd_flags = htons(ntohs((phdr)->_hdrlen_rsvd_flags) | (flags))\r
+#define TCPH_UNSET_FLAG(phdr, flags) (phdr)->_hdrlen_rsvd_flags = htons(ntohs((phdr)->_hdrlen_rsvd_flags) | (TCPH_FLAGS(phdr) & ~(flags)) )\r
+\r
+#define TCP_TCPLEN(seg) ((seg)->len + ((TCPH_FLAGS((seg)->tcphdr) & TCP_FIN || \\r
+          TCPH_FLAGS((seg)->tcphdr) & TCP_SYN)? 1: 0))\r
+\r
+enum tcp_state {\r
+  CLOSED      = 0,\r
+  LISTEN      = 1,\r
+  SYN_SENT    = 2,\r
+  SYN_RCVD    = 3,\r
+  ESTABLISHED = 4,\r
+  FIN_WAIT_1  = 5,\r
+  FIN_WAIT_2  = 6,\r
+  CLOSE_WAIT  = 7,\r
+  CLOSING     = 8,\r
+  LAST_ACK    = 9,\r
+  TIME_WAIT   = 10\r
+};\r
+\r
+/* the TCP protocol control block */\r
+struct tcp_pcb {\r
+/** common PCB members */\r
+  IP_PCB;\r
+/** protocol specific PCB members */\r
+  struct tcp_pcb *next; /* for the linked list */\r
+  enum tcp_state state; /* TCP state */\r
+  u8_t prio;\r
+  void *callback_arg;\r
+\r
+  u16_t local_port;\r
+  u16_t remote_port;\r
+  \r
+  u8_t flags;\r
+#define TF_ACK_DELAY (u8_t)0x01U   /* Delayed ACK. */\r
+#define TF_ACK_NOW   (u8_t)0x02U   /* Immediate ACK. */\r
+#define TF_INFR      (u8_t)0x04U   /* In fast recovery. */\r
+#define TF_RESET     (u8_t)0x08U   /* Connection was reset. */\r
+#define TF_CLOSED    (u8_t)0x10U   /* Connection was sucessfully closed. */\r
+#define TF_GOT_FIN   (u8_t)0x20U   /* Connection was closed by the remote end. */\r
+#define TF_NODELAY   (u8_t)0x40U   /* Disable Nagle algorithm */\r
+\r
+  /* receiver variables */\r
+  u32_t rcv_nxt;   /* next seqno expected */\r
+  u16_t rcv_wnd;   /* receiver window */\r
+  \r
+  /* Timers */\r
+  u32_t tmr;\r
+  u8_t polltmr, pollinterval;\r
+  \r
+  /* Retransmission timer. */\r
+  u16_t rtime;\r
+  \r
+  u16_t mss;   /* maximum segment size */\r
+  \r
+  /* RTT (round trip time) estimation variables */\r
+  u32_t rttest; /* RTT estimate in 500ms ticks */\r
+  u32_t rtseq;  /* sequence number being timed */\r
+  s16_t sa, sv; /* @todo document this */\r
+\r
+  u16_t rto;    /* retransmission time-out */\r
+  u8_t nrtx;    /* number of retransmissions */\r
+\r
+  /* fast retransmit/recovery */\r
+  u32_t lastack; /* Highest acknowledged seqno. */\r
+  u8_t dupacks;\r
+  \r
+  /* congestion avoidance/control variables */\r
+  u16_t cwnd;  \r
+  u16_t ssthresh;\r
+\r
+  /* sender variables */\r
+  u32_t snd_nxt,       /* next seqno to be sent */\r
+    snd_max,       /* Highest seqno sent. */\r
+    snd_wnd,       /* sender window */\r
+    snd_wl1, snd_wl2, /* Sequence and acknowledgement numbers of last\r
+       window update. */\r
+    snd_lbb;       /* Sequence number of next byte to be buffered. */\r
+\r
+  u16_t acked;\r
+  \r
+  u16_t snd_buf;   /* Available buffer space for sending (in bytes). */\r
+  u8_t snd_queuelen; /* Available buffer space for sending (in tcp_segs). */\r
+  \r
+  \r
+  /* These are ordered by sequence number: */\r
+  struct tcp_seg *unsent;   /* Unsent (queued) segments. */\r
+  struct tcp_seg *unacked;  /* Sent but unacknowledged segments. */\r
+#if TCP_QUEUE_OOSEQ  \r
+  struct tcp_seg *ooseq;    /* Received out of sequence segments. */\r
+#endif /* TCP_QUEUE_OOSEQ */\r
+\r
+#if LWIP_CALLBACK_API\r
+  /* Function to be called when more send buffer space is available. */\r
+  err_t (* sent)(void *arg, struct tcp_pcb *pcb, u16_t space);\r
+  \r
+  /* Function to be called when (in-sequence) data has arrived. */\r
+  err_t (* recv)(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err);\r
+\r
+  /* Function to be called when a connection has been set up. */\r
+  err_t (* connected)(void *arg, struct tcp_pcb *pcb, err_t err);\r
+\r
+  /* Function to call when a listener has been connected. */\r
+  err_t (* accept)(void *arg, struct tcp_pcb *newpcb, err_t err);\r
+\r
+  /* Function which is called periodically. */\r
+  err_t (* poll)(void *arg, struct tcp_pcb *pcb);\r
+\r
+  /* Function to be called whenever a fatal error occurs. */\r
+  void (* errf)(void *arg, err_t err);\r
+#endif /* LWIP_CALLBACK_API */\r
+\r
+  /* idle time before KEEPALIVE is sent */\r
+  u32_t keepalive;\r
+  \r
+  /* KEEPALIVE counter */\r
+  u8_t keep_cnt;\r
+};\r
+\r
+struct tcp_pcb_listen {  \r
+/* Common members of all PCB types */\r
+  IP_PCB;\r
+\r
+/* Protocol specific PCB members */\r
+  struct tcp_pcb_listen *next;   /* for the linked list */\r
+  \r
+  /* Even if state is obviously LISTEN this is here for\r
+   * field compatibility with tpc_pcb to which it is cast sometimes\r
+   * Until a cleaner solution emerges this is here.FIXME\r
+   */ \r
+  enum tcp_state state;   /* TCP state */\r
+\r
+  u8_t prio;\r
+  void *callback_arg;\r
+  \r
+  u16_t local_port; \r
+\r
+#if LWIP_CALLBACK_API\r
+  /* Function to call when a listener has been connected. */\r
+  err_t (* accept)(void *arg, struct tcp_pcb *newpcb, err_t err);\r
+#endif /* LWIP_CALLBACK_API */\r
+};\r
+\r
+#if LWIP_EVENT_API\r
+\r
+enum lwip_event {\r
+  LWIP_EVENT_ACCEPT,\r
+  LWIP_EVENT_SENT,\r
+  LWIP_EVENT_RECV,\r
+  LWIP_EVENT_CONNECTED,\r
+  LWIP_EVENT_POLL,\r
+  LWIP_EVENT_ERR\r
+};\r
+\r
+err_t lwip_tcp_event(void *arg, struct tcp_pcb *pcb,\r
+         enum lwip_event,\r
+         struct pbuf *p,\r
+         u16_t size,\r
+         err_t err);\r
+\r
+#define TCP_EVENT_ACCEPT(pcb,err,ret)    ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\\r
+                LWIP_EVENT_ACCEPT, NULL, 0, err)\r
+#define TCP_EVENT_SENT(pcb,space,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\\r
+                   LWIP_EVENT_SENT, NULL, space, ERR_OK)\r
+#define TCP_EVENT_RECV(pcb,p,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\\r
+                LWIP_EVENT_RECV, (p), 0, (err))\r
+#define TCP_EVENT_CONNECTED(pcb,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\\r
+                LWIP_EVENT_CONNECTED, NULL, 0, (err))\r
+#define TCP_EVENT_POLL(pcb,ret)       ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\\r
+                LWIP_EVENT_POLL, NULL, 0, ERR_OK)\r
+#define TCP_EVENT_ERR(errf,arg,err)  lwip_tcp_event((arg), NULL, \\r
+                LWIP_EVENT_ERR, NULL, 0, (err))\r
+#else /* LWIP_EVENT_API */\r
+#define TCP_EVENT_ACCEPT(pcb,err,ret)     \\r
+                        if((pcb)->accept != NULL) \\r
+                        (ret = (pcb)->accept((pcb)->callback_arg,(pcb),(err)))\r
+#define TCP_EVENT_SENT(pcb,space,ret) \\r
+                        if((pcb)->sent != NULL) \\r
+                        (ret = (pcb)->sent((pcb)->callback_arg,(pcb),(space)))\r
+#define TCP_EVENT_RECV(pcb,p,err,ret) \\r
+                        if((pcb)->recv != NULL) \\r
+                        { ret = (pcb)->recv((pcb)->callback_arg,(pcb),(p),(err)); } else { \\r
+                          if (p) pbuf_free(p); }\r
+#define TCP_EVENT_CONNECTED(pcb,err,ret) \\r
+                        if((pcb)->connected != NULL) \\r
+                        (ret = (pcb)->connected((pcb)->callback_arg,(pcb),(err)))\r
+#define TCP_EVENT_POLL(pcb,ret) \\r
+                        if((pcb)->poll != NULL) \\r
+                        (ret = (pcb)->poll((pcb)->callback_arg,(pcb)))\r
+#define TCP_EVENT_ERR(errf,arg,err) \\r
+                        if((errf) != NULL) \\r
+                        (errf)((arg),(err))\r
+#endif /* LWIP_EVENT_API */\r
+\r
+/* This structure represents a TCP segment on the unsent and unacked queues */\r
+struct tcp_seg {\r
+  struct tcp_seg *next;    /* used when putting segements on a queue */\r
+  struct pbuf *p;          /* buffer containing data + TCP header */\r
+  void *dataptr;           /* pointer to the TCP data in the pbuf */\r
+  u16_t len;               /* the TCP length of this segment */\r
+  struct tcp_hdr *tcphdr;  /* the TCP header */\r
+};\r
+\r
+/* Internal functions and global variables: */\r
+struct tcp_pcb *tcp_pcb_copy(struct tcp_pcb *pcb);\r
+void tcp_pcb_purge(struct tcp_pcb *pcb);\r
+void tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb);\r
+\r
+u8_t tcp_segs_free(struct tcp_seg *seg);\r
+u8_t tcp_seg_free(struct tcp_seg *seg);\r
+struct tcp_seg *tcp_seg_copy(struct tcp_seg *seg);\r
+\r
+#define tcp_ack(pcb)     if((pcb)->flags & TF_ACK_DELAY) { \\r
+                            (pcb)->flags &= ~TF_ACK_DELAY; \\r
+                            (pcb)->flags |= TF_ACK_NOW; \\r
+                            tcp_output(pcb); \\r
+                         } else { \\r
+                            (pcb)->flags |= TF_ACK_DELAY; \\r
+                         }\r
+\r
+#define tcp_ack_now(pcb) (pcb)->flags |= TF_ACK_NOW; \\r
+                         tcp_output(pcb)\r
+\r
+err_t tcp_send_ctrl(struct tcp_pcb *pcb, u8_t flags);\r
+err_t tcp_enqueue(struct tcp_pcb *pcb, void *dataptr, u16_t len,\r
+    u8_t flags, u8_t copy,\r
+                u8_t *optdata, u8_t optlen);\r
+\r
+void tcp_rexmit_seg(struct tcp_pcb *pcb, struct tcp_seg *seg);\r
+\r
+void tcp_rst(u32_t seqno, u32_t ackno,\r
+       struct ip_addr *local_ip, struct ip_addr *remote_ip,\r
+       u16_t local_port, u16_t remote_port);\r
+\r
+u32_t tcp_next_iss(void);\r
+\r
+void tcp_keepalive(struct tcp_pcb *pcb);\r
+\r
+extern struct tcp_pcb *tcp_input_pcb;\r
+extern u32_t tcp_ticks;\r
+\r
+#if TCP_DEBUG || TCP_INPUT_DEBUG || TCP_OUTPUT_DEBUG\r
+void tcp_debug_print(struct tcp_hdr *tcphdr);\r
+void tcp_debug_print_flags(u8_t flags);\r
+void tcp_debug_print_state(enum tcp_state s);\r
+void tcp_debug_print_pcbs(void);\r
+s16_t tcp_pcbs_sane(void);\r
+#else\r
+#  define tcp_debug_print(tcphdr)\r
+#  define tcp_debug_print_flags(flags)\r
+#  define tcp_debug_print_state(s)\r
+#  define tcp_debug_print_pcbs()\r
+#  define tcp_pcbs_sane() 1\r
+#endif /* TCP_DEBUG */\r
+\r
+#if NO_SYS\r
+#define tcp_timer_needed()\r
+#else\r
+void tcp_timer_needed(void);\r
+#endif\r
+\r
+/* The TCP PCB lists. */\r
+union tcp_listen_pcbs_t { /* List of all TCP PCBs in LISTEN state. */\r
+       struct tcp_pcb_listen *listen_pcbs; \r
+       struct tcp_pcb *pcbs;\r
+};\r
+extern union tcp_listen_pcbs_t tcp_listen_pcbs;\r
+extern struct tcp_pcb *tcp_active_pcbs;  /* List of all TCP PCBs that are in a\r
+              state in which they accept or send\r
+              data. */\r
+extern struct tcp_pcb *tcp_tw_pcbs;      /* List of all TCP PCBs in TIME-WAIT. */\r
+\r
+extern struct tcp_pcb *tcp_tmp_pcb;      /* Only used for temporary storage. */\r
+\r
+/* Axioms about the above lists:   \r
+   1) Every TCP PCB that is not CLOSED is in one of the lists.\r
+   2) A PCB is only in one of the lists.\r
+   3) All PCBs in the tcp_listen_pcbs list is in LISTEN state.\r
+   4) All PCBs in the tcp_tw_pcbs list is in TIME-WAIT state.\r
+*/\r
+\r
+/* Define two macros, TCP_REG and TCP_RMV that registers a TCP PCB\r
+   with a PCB list or removes a PCB from a list, respectively. */\r
+#if 0\r
+#define TCP_REG(pcbs, npcb) do {\\r
+                            LWIP_DEBUGF(TCP_DEBUG, ("TCP_REG %p local port %d\n", npcb, npcb->local_port)); \\r
+                            for(tcp_tmp_pcb = *pcbs; \\r
+          tcp_tmp_pcb != NULL; \\r
+        tcp_tmp_pcb = tcp_tmp_pcb->next) { \\r
+                                LWIP_ASSERT("TCP_REG: already registered\n", tcp_tmp_pcb != npcb); \\r
+                            } \\r
+                            LWIP_ASSERT("TCP_REG: pcb->state != CLOSED", npcb->state != CLOSED); \\r
+                            npcb->next = *pcbs; \\r
+                            LWIP_ASSERT("TCP_REG: npcb->next != npcb", npcb->next != npcb); \\r
+                            *(pcbs) = npcb; \\r
+                            LWIP_ASSERT("TCP_RMV: tcp_pcbs sane", tcp_pcbs_sane()); \\r
+              tcp_timer_needed(); \\r
+                            } while(0)\r
+#define TCP_RMV(pcbs, npcb) do { \\r
+                            LWIP_ASSERT("TCP_RMV: pcbs != NULL", *pcbs != NULL); \\r
+                            LWIP_DEBUGF(TCP_DEBUG, ("TCP_RMV: removing %p from %p\n", npcb, *pcbs)); \\r
+                            if(*pcbs == npcb) { \\r
+                               *pcbs = (*pcbs)->next; \\r
+                            } else for(tcp_tmp_pcb = *pcbs; tcp_tmp_pcb != NULL; tcp_tmp_pcb = tcp_tmp_pcb->next) { \\r
+                               if(tcp_tmp_pcb->next != NULL && tcp_tmp_pcb->next == npcb) { \\r
+                                  tcp_tmp_pcb->next = npcb->next; \\r
+                                  break; \\r
+                               } \\r
+                            } \\r
+                            npcb->next = NULL; \\r
+                            LWIP_ASSERT("TCP_RMV: tcp_pcbs sane", tcp_pcbs_sane()); \\r
+                            LWIP_DEBUGF(TCP_DEBUG, ("TCP_RMV: removed %p from %p\n", npcb, *pcbs)); \\r
+                            } while(0)\r
+\r
+#else /* LWIP_DEBUG */\r
+#define TCP_REG(pcbs, npcb) do { \\r
+                            npcb->next = *pcbs; \\r
+                            *(pcbs) = npcb; \\r
+              tcp_timer_needed(); \\r
+                            } while(0)\r
+#define TCP_RMV(pcbs, npcb) do { \\r
+                            if(*(pcbs) == npcb) { \\r
+                               (*(pcbs)) = (*pcbs)->next; \\r
+                            } else for(tcp_tmp_pcb = *pcbs; tcp_tmp_pcb != NULL; tcp_tmp_pcb = tcp_tmp_pcb->next) { \\r
+                               if(tcp_tmp_pcb->next != NULL && tcp_tmp_pcb->next == npcb) { \\r
+                                  tcp_tmp_pcb->next = npcb->next; \\r
+                                  break; \\r
+                               } \\r
+                            } \\r
+                            npcb->next = NULL; \\r
+                            } while(0)\r
+#endif /* LWIP_DEBUG */\r
+#endif /* __LWIP_TCP_H__ */\r
+\r
+\r
+\r
index 316ae4fc53659bed05a6696fe31c7fb94cab8de7..242664ef71aadce7fc2cca9f23129ad30d17d134 100644 (file)
@@ -1,68 +1,68 @@
-/*
- * 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 <adam@sics.se>
- *
- */
-#ifndef __LWIP_TCPIP_H__
-#define __LWIP_TCPIP_H__
-
-#include "lwip/api_msg.h"
-#include "lwip/pbuf.h"
-
-void tcpip_init(void (* tcpip_init_done)(void *), void *arg);
-void tcpip_apimsg(struct api_msg *apimsg);
-err_t tcpip_input(struct pbuf *p, struct netif *inp);
-err_t tcpip_callback(void (*f)(void *ctx), void *ctx);
-
-void tcpip_tcp_timer_needed(void);
-
-enum tcpip_msg_type {
-  TCPIP_MSG_API,
-  TCPIP_MSG_INPUT,
-  TCPIP_MSG_CALLBACK
-};
-
-struct tcpip_msg {
-  enum tcpip_msg_type type;
-  sys_sem_t *sem;
-  union {
-    struct api_msg *apimsg;
-    struct {
-      struct pbuf *p;
-      struct netif *netif;
-    } inp;
-    struct {
-      void (*f)(void *ctx);
-      void *ctx;
-    } cb;
-  } msg;
-};
-
-
-#endif /* __LWIP_TCPIP_H__ */
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+#ifndef __LWIP_TCPIP_H__\r
+#define __LWIP_TCPIP_H__\r
+\r
+#include "lwip/api_msg.h"\r
+#include "lwip/pbuf.h"\r
+\r
+void tcpip_init(void (* tcpip_init_done)(void *), void *arg);\r
+void tcpip_apimsg(struct api_msg *apimsg);\r
+err_t tcpip_input(struct pbuf *p, struct netif *inp);\r
+err_t tcpip_callback(void (*f)(void *ctx), void *ctx);\r
+\r
+void tcpip_tcp_timer_needed(void);\r
+\r
+enum tcpip_msg_type {\r
+  TCPIP_MSG_API,\r
+  TCPIP_MSG_INPUT,\r
+  TCPIP_MSG_CALLBACK\r
+};\r
+\r
+struct tcpip_msg {\r
+  enum tcpip_msg_type type;\r
+  sys_sem_t *sem;\r
+  union {\r
+    struct api_msg *apimsg;\r
+    struct {\r
+      struct pbuf *p;\r
+      struct netif *netif;\r
+    } inp;\r
+    struct {\r
+      void (*f)(void *ctx);\r
+      void *ctx;\r
+    } cb;\r
+  } msg;\r
+};\r
+\r
+\r
+#endif /* __LWIP_TCPIP_H__ */\r
index ede04745f976637323d7909c3663f08bfed9a0a7..daaeca10775374c5181e1624697ea1b326e156b3 100644 (file)
-/*
- * 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 <adam@sics.se>
- *
- */
-#ifndef __LWIP_UDP_H__
-#define __LWIP_UDP_H__
-
-#include "lwip/arch.h"
-
-#include "lwip/pbuf.h"
-#include "lwip/inet.h"
-#include "lwip/ip.h"
-
-#define UDP_HLEN 8
-
-struct udp_hdr {
-  PACK_STRUCT_FIELD(u16_t src);
-  PACK_STRUCT_FIELD(u16_t dest);  /* src/dest UDP ports */
-  PACK_STRUCT_FIELD(u16_t len);
-  PACK_STRUCT_FIELD(u16_t chksum);
-} PACK_STRUCT_STRUCT;
-
-#define UDP_FLAGS_NOCHKSUM 0x01U
-#define UDP_FLAGS_UDPLITE  0x02U
-#define UDP_FLAGS_CONNECTED  0x04U
-
-struct udp_pcb {
-/* Common members of all PCB types */
-  IP_PCB;
-
-/* Protocol specific PCB members */
-
-  struct udp_pcb *next;
-
-  u8_t flags;
-  u16_t local_port, remote_port;
-  
-  u16_t chksum_len;
-  
-  void (* recv)(void *arg, struct udp_pcb *pcb, struct pbuf *p,
-    struct ip_addr *addr, u16_t port);
-  void *recv_arg;  
-};
-
-/* The following functions is the application layer interface to the
-   UDP code. */
-struct udp_pcb * udp_new        (void);
-void             udp_remove     (struct udp_pcb *pcb);
-err_t            udp_bind       (struct udp_pcb *pcb, struct ip_addr *ipaddr,
-                 u16_t port);
-err_t            udp_connect    (struct udp_pcb *pcb, struct ip_addr *ipaddr,
-                 u16_t port);
-void             udp_disconnect    (struct udp_pcb *pcb);
-void             udp_recv       (struct udp_pcb *pcb,
-         void (* recv)(void *arg, struct udp_pcb *upcb,
-                 struct pbuf *p,
-                 struct ip_addr *addr,
-                 u16_t port),
-         void *recv_arg);
-err_t            udp_sendto     (struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *dst_ip, u16_t dst_port);
-err_t            udp_send       (struct udp_pcb *pcb, struct pbuf *p);
-
-#define          udp_flags(pcb)  ((pcb)->flags)
-#define          udp_setflags(pcb, f)  ((pcb)->flags = (f))
-
-/* The following functions are the lower layer interface to UDP. */
-void             udp_input      (struct pbuf *p, struct netif *inp);
-void             udp_init       (void);
-
-#if UDP_DEBUG
-void udp_debug_print(struct udp_hdr *udphdr);
-#else
-#define udp_debug_print(udphdr)
-#endif
-#endif /* __LWIP_UDP_H__ */
-
-
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+#ifndef __LWIP_UDP_H__\r
+#define __LWIP_UDP_H__\r
+\r
+#include "lwip/arch.h"\r
+\r
+#include "lwip/pbuf.h"\r
+#include "lwip/inet.h"\r
+#include "lwip/ip.h"\r
+\r
+#define UDP_HLEN 8\r
+\r
+struct udp_hdr {\r
+  PACK_STRUCT_FIELD(u16_t src);\r
+  PACK_STRUCT_FIELD(u16_t dest);  /* src/dest UDP ports */\r
+  PACK_STRUCT_FIELD(u16_t len);\r
+  PACK_STRUCT_FIELD(u16_t chksum);\r
+} PACK_STRUCT_STRUCT;\r
+\r
+#define UDP_FLAGS_NOCHKSUM 0x01U\r
+#define UDP_FLAGS_UDPLITE  0x02U\r
+#define UDP_FLAGS_CONNECTED  0x04U\r
+\r
+struct udp_pcb {\r
+/* Common members of all PCB types */\r
+  IP_PCB;\r
+\r
+/* Protocol specific PCB members */\r
+\r
+  struct udp_pcb *next;\r
+\r
+  u8_t flags;\r
+  u16_t local_port, remote_port;\r
+  \r
+  u16_t chksum_len;\r
+  \r
+  void (* recv)(void *arg, struct udp_pcb *pcb, struct pbuf *p,\r
+    struct ip_addr *addr, u16_t port);\r
+  void *recv_arg;  \r
+};\r
+\r
+/* The following functions is the application layer interface to the\r
+   UDP code. */\r
+struct udp_pcb * udp_new        (void);\r
+void             udp_remove     (struct udp_pcb *pcb);\r
+err_t            udp_bind       (struct udp_pcb *pcb, struct ip_addr *ipaddr,\r
+                 u16_t port);\r
+err_t            udp_connect    (struct udp_pcb *pcb, struct ip_addr *ipaddr,\r
+                 u16_t port);\r
+void             udp_disconnect    (struct udp_pcb *pcb);\r
+void             udp_recv       (struct udp_pcb *pcb,\r
+         void (* recv)(void *arg, struct udp_pcb *upcb,\r
+                 struct pbuf *p,\r
+                 struct ip_addr *addr,\r
+                 u16_t port),\r
+         void *recv_arg);\r
+err_t            udp_sendto     (struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *dst_ip, u16_t dst_port);\r
+err_t            udp_send       (struct udp_pcb *pcb, struct pbuf *p);\r
+\r
+#define          udp_flags(pcb)  ((pcb)->flags)\r
+#define          udp_setflags(pcb, f)  ((pcb)->flags = (f))\r
+\r
+/* The following functions are the lower layer interface to UDP. */\r
+void             udp_input      (struct pbuf *p, struct netif *inp);\r
+void             udp_init       (void);\r
+\r
+#if UDP_DEBUG\r
+void udp_debug_print(struct udp_hdr *udphdr);\r
+#else\r
+#define udp_debug_print(udphdr)\r
+#endif\r
+#endif /* __LWIP_UDP_H__ */\r
+\r
+\r
index 08437afe54995310a43d20ba51bf2908dd365ec6..26fa3effb0613e94527f78624418dc14ee8367e8 100644 (file)
-/*
- * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
- * Copyright (c) 2003-2004 Leon Woestenberg <leon.woestenberg@axon.tv>
- * Copyright (c) 2003-2004 Axon Digital Design B.V., The Netherlands.
- * 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 <adam@sics.se>
- *
- */
-
-#ifndef __NETIF_ETHARP_H__
-#define __NETIF_ETHARP_H__
-
-#ifndef ETH_PAD_SIZE
-#define ETH_PAD_SIZE 0
-#endif
-
-#include "lwip/pbuf.h"
-#include "lwip/ip_addr.h"
-#include "lwip/netif.h"
-#include "lwip/ip.h"
-
-#ifdef PACK_STRUCT_USE_INCLUDES
-#  include "arch/bpstruct.h"
-#endif
-PACK_STRUCT_BEGIN
-struct eth_addr {
-  PACK_STRUCT_FIELD(u8_t addr[6]);
-} PACK_STRUCT_STRUCT;
-PACK_STRUCT_END
-#ifdef PACK_STRUCT_USE_INCLUDES
-#  include "arch/epstruct.h"
-#endif
-
-#ifdef PACK_STRUCT_USE_INCLUDES
-#  include "arch/bpstruct.h"
-#endif
-PACK_STRUCT_BEGIN
-struct eth_hdr {
-#if ETH_PAD_SIZE
-  PACK_STRUCT_FIELD(u8_t padding[ETH_PAD_SIZE]);
-#endif
-  PACK_STRUCT_FIELD(struct eth_addr dest);
-  PACK_STRUCT_FIELD(struct eth_addr src);
-  PACK_STRUCT_FIELD(u16_t type);
-} PACK_STRUCT_STRUCT;
-PACK_STRUCT_END
-#ifdef PACK_STRUCT_USE_INCLUDES
-#  include "arch/epstruct.h"
-#endif
-
-#ifdef PACK_STRUCT_USE_INCLUDES
-#  include "arch/bpstruct.h"
-#endif
-PACK_STRUCT_BEGIN
-/** the ARP message */
-struct etharp_hdr {
-  PACK_STRUCT_FIELD(struct eth_hdr ethhdr);
-  PACK_STRUCT_FIELD(u16_t hwtype);
-  PACK_STRUCT_FIELD(u16_t proto);
-  PACK_STRUCT_FIELD(u16_t _hwlen_protolen);
-  PACK_STRUCT_FIELD(u16_t opcode);
-  PACK_STRUCT_FIELD(struct eth_addr shwaddr);
-  PACK_STRUCT_FIELD(struct ip_addr2 sipaddr);
-  PACK_STRUCT_FIELD(struct eth_addr dhwaddr);
-  PACK_STRUCT_FIELD(struct ip_addr2 dipaddr);
-} PACK_STRUCT_STRUCT;
-PACK_STRUCT_END
-#ifdef PACK_STRUCT_USE_INCLUDES
-#  include "arch/epstruct.h"
-#endif
-
-#ifdef PACK_STRUCT_USE_INCLUDES
-#  include "arch/bpstruct.h"
-#endif
-PACK_STRUCT_BEGIN
-struct ethip_hdr {
-  PACK_STRUCT_FIELD(struct eth_hdr eth);
-  PACK_STRUCT_FIELD(struct ip_hdr ip);
-} PACK_STRUCT_STRUCT;
-PACK_STRUCT_END
-#ifdef PACK_STRUCT_USE_INCLUDES
-#  include "arch/epstruct.h"
-#endif
-
-/** 5 seconds period */
-#define ARP_TMR_INTERVAL 5000
-
-#define ETHTYPE_ARP 0x0806
-#define ETHTYPE_IP  0x0800
-
-void etharp_init(void);
-void etharp_tmr(void);
-void etharp_ip_input(struct netif *netif, struct pbuf *p);
-void etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr,
-         struct pbuf *p);
-err_t etharp_output(struct netif *netif, struct ip_addr *ipaddr,
-         struct pbuf *q);
-err_t etharp_query(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q);
-err_t etharp_request(struct netif *netif, struct ip_addr *ipaddr);
-
-#endif /* __NETIF_ARP_H__ */
+/*\r
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.\r
+ * Copyright (c) 2003-2004 Leon Woestenberg <leon.woestenberg@axon.tv>\r
+ * Copyright (c) 2003-2004 Axon Digital Design B.V., The Netherlands.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+\r
+#ifndef __NETIF_ETHARP_H__\r
+#define __NETIF_ETHARP_H__\r
+\r
+#ifndef ETH_PAD_SIZE\r
+#define ETH_PAD_SIZE 0\r
+#endif\r
+\r
+#include "lwip/pbuf.h"\r
+#include "lwip/ip_addr.h"\r
+#include "lwip/netif.h"\r
+#include "lwip/ip.h"\r
+\r
+#ifdef PACK_STRUCT_USE_INCLUDES\r
+#  include "arch/bpstruct.h"\r
+#endif\r
+PACK_STRUCT_BEGIN\r
+struct eth_addr {\r
+  PACK_STRUCT_FIELD(u8_t addr[6]);\r
+} PACK_STRUCT_STRUCT;\r
+PACK_STRUCT_END\r
+#ifdef PACK_STRUCT_USE_INCLUDES\r
+#  include "arch/epstruct.h"\r
+#endif\r
+\r
+#ifdef PACK_STRUCT_USE_INCLUDES\r
+#  include "arch/bpstruct.h"\r
+#endif\r
+PACK_STRUCT_BEGIN\r
+struct eth_hdr {\r
+#if ETH_PAD_SIZE\r
+  PACK_STRUCT_FIELD(u8_t padding[ETH_PAD_SIZE]);\r
+#endif\r
+  PACK_STRUCT_FIELD(struct eth_addr dest);\r
+  PACK_STRUCT_FIELD(struct eth_addr src);\r
+  PACK_STRUCT_FIELD(u16_t type);\r
+} PACK_STRUCT_STRUCT;\r
+PACK_STRUCT_END\r
+#ifdef PACK_STRUCT_USE_INCLUDES\r
+#  include "arch/epstruct.h"\r
+#endif\r
+\r
+#ifdef PACK_STRUCT_USE_INCLUDES\r
+#  include "arch/bpstruct.h"\r
+#endif\r
+PACK_STRUCT_BEGIN\r
+/** the ARP message */\r
+struct etharp_hdr {\r
+  PACK_STRUCT_FIELD(struct eth_hdr ethhdr);\r
+  PACK_STRUCT_FIELD(u16_t hwtype);\r
+  PACK_STRUCT_FIELD(u16_t proto);\r
+  PACK_STRUCT_FIELD(u16_t _hwlen_protolen);\r
+  PACK_STRUCT_FIELD(u16_t opcode);\r
+  PACK_STRUCT_FIELD(struct eth_addr shwaddr);\r
+  PACK_STRUCT_FIELD(struct ip_addr2 sipaddr);\r
+  PACK_STRUCT_FIELD(struct eth_addr dhwaddr);\r
+  PACK_STRUCT_FIELD(struct ip_addr2 dipaddr);\r
+} PACK_STRUCT_STRUCT;\r
+PACK_STRUCT_END\r
+#ifdef PACK_STRUCT_USE_INCLUDES\r
+#  include "arch/epstruct.h"\r
+#endif\r
+\r
+#ifdef PACK_STRUCT_USE_INCLUDES\r
+#  include "arch/bpstruct.h"\r
+#endif\r
+PACK_STRUCT_BEGIN\r
+struct ethip_hdr {\r
+  PACK_STRUCT_FIELD(struct eth_hdr eth);\r
+  PACK_STRUCT_FIELD(struct ip_hdr ip);\r
+} PACK_STRUCT_STRUCT;\r
+PACK_STRUCT_END\r
+#ifdef PACK_STRUCT_USE_INCLUDES\r
+#  include "arch/epstruct.h"\r
+#endif\r
+\r
+/** 5 seconds period */\r
+#define ARP_TMR_INTERVAL 5000\r
+\r
+#define ETHTYPE_ARP 0x0806\r
+#define ETHTYPE_IP  0x0800\r
+\r
+void etharp_init(void);\r
+void etharp_tmr(void);\r
+void etharp_ip_input(struct netif *netif, struct pbuf *p);\r
+void etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr,\r
+         struct pbuf *p);\r
+err_t etharp_output(struct netif *netif, struct ip_addr *ipaddr,\r
+         struct pbuf *q);\r
+err_t etharp_query(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q);\r
+err_t etharp_request(struct netif *netif, struct ip_addr *ipaddr);\r
+\r
+#endif /* __NETIF_ARP_H__ */\r
index 97b3c67645badf25cf923eae628ab30480fa9202..7fd54873397e37e0425764881a10b30b15e2b505 100644 (file)
@@ -1,39 +1,39 @@
-/*
- * 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 <adam@sics.se>
- *
- */
-#ifndef __NETIF_LOOPIF_H__
-#define __NETIF_LOOPIF_H__
-
-#include "lwip/netif.h"
-
-err_t loopif_init(struct netif *netif);
-
-#endif /* __NETIF_LOOPIF_H__ */
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+#ifndef __NETIF_LOOPIF_H__\r
+#define __NETIF_LOOPIF_H__\r
+\r
+#include "lwip/netif.h"\r
+\r
+err_t loopif_init(struct netif *netif);\r
+\r
+#endif /* __NETIF_LOOPIF_H__ */\r
index bf70046a9f6e8e8c020725f8fd3abe627cb63292..d9060fc9734231af45a4048d8108631ff491f3f9 100644 (file)
@@ -1,42 +1,42 @@
-/*
- * Copyright (c) 2001, 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. Neither the name of the Institute nor the names of its contributors 
- *    may be used to endorse or promote products derived from this software 
- *    without specific prior written permission. 
- *
- * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE OR CONTRIBUTORS 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 <adam@sics.se>
- *
- */
-#ifndef __NETIF_SLIPIF_H__
-#define __NETIF_SLIPIF_H__
-
-#include "lwip/netif.h"
-
-err_t slipif_init(struct netif * netif);
-#endif 
-
+/*\r
+ * Copyright (c) 2001, Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ *\r
+ * Redistribution and use in source and binary forms, with or without \r
+ * modification, are permitted provided that the following conditions \r
+ * are met: \r
+ * 1. Redistributions of source code must retain the above copyright \r
+ *    notice, this list of conditions and the following disclaimer. \r
+ * 2. Redistributions in binary form must reproduce the above copyright \r
+ *    notice, this list of conditions and the following disclaimer in the \r
+ *    documentation and/or other materials provided with the distribution. \r
+ * 3. Neither the name of the Institute nor the names of its contributors \r
+ *    may be used to endorse or promote products derived from this software \r
+ *    without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND \r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE \r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE \r
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE \r
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL \r
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS \r
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) \r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT \r
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY \r
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF \r
+ * SUCH DAMAGE. \r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+#ifndef __NETIF_SLIPIF_H__\r
+#define __NETIF_SLIPIF_H__\r
+\r
+#include "lwip/netif.h"\r
+\r
+err_t slipif_init(struct netif * netif);\r
\r
+#endif \r
+\r
index 7765046d4d53fd005f419067e0bda9bc79cf3c91..76a8ac4bf98f6a4d99b4b369866cea4351ecede2 100644 (file)
-/**
- * @file
- * Address Resolution Protocol module for IP over Ethernet
- *
- * Functionally, ARP is divided into two parts. The first maps an IP address
- * to a physical address when sending a packet, and the second part answers
- * requests from other machines for our physical address.
- *
- * This implementation complies with RFC 826 (Ethernet ARP). It supports
- * Gratuitious ARP from RFC3220 (IP Mobility Support for IPv4) section 4.6
- * if an interface calls etharp_query(our_netif, its_ip_addr, NULL) upon
- * address change.
- */
-
-/*
- * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
- * Copyright (c) 2003-2004 Leon Woestenberg <leon.woestenberg@axon.tv>
- * Copyright (c) 2003-2004 Axon Digital Design B.V., The Netherlands.
- * 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.
- *
- */
-
-#include "lwip/opt.h"
-#include "lwip/inet.h"
-#include "netif/etharp.h"
-#include "lwip/ip.h"
-#include "lwip/stats.h"
-
-/* ARP needs to inform DHCP of any ARP replies? */
-#if (LWIP_DHCP && DHCP_DOES_ARP_CHECK)
-#  include "lwip/dhcp.h"
-#endif
-
-/** the time an ARP entry stays valid after its last update,
- * (240 * 5) seconds = 20 minutes.
- */
-#define ARP_MAXAGE 240
-/** the time an ARP entry stays pending after first request,
- * (2 * 5) seconds = 10 seconds.
- * 
- * @internal Keep this number at least 2, otherwise it might
- * run out instantly if the timeout occurs directly after a request.
- */
-#define ARP_MAXPENDING 2
-
-#define HWTYPE_ETHERNET 1
-
-/** ARP message types */
-#define ARP_REQUEST 1
-#define ARP_REPLY 2
-
-#define ARPH_HWLEN(hdr) (ntohs((hdr)->_hwlen_protolen) >> 8)
-#define ARPH_PROTOLEN(hdr) (ntohs((hdr)->_hwlen_protolen) & 0xff)
-
-#define ARPH_HWLEN_SET(hdr, len) (hdr)->_hwlen_protolen = htons(ARPH_PROTOLEN(hdr) | ((len) << 8))
-#define ARPH_PROTOLEN_SET(hdr, len) (hdr)->_hwlen_protolen = htons((len) | (ARPH_HWLEN(hdr) << 8))
-
-enum etharp_state {
-  ETHARP_STATE_EMPTY,
-  ETHARP_STATE_PENDING,
-  ETHARP_STATE_STABLE,
-  /** @internal transitional state used in etharp_tmr() for convenience*/
-  ETHARP_STATE_EXPIRED
-};
-
-struct etharp_entry {
-#if ARP_QUEUEING
-  /** 
-   * Pointer to queue of pending outgoing packets on this ARP entry.
-   */
-   struct pbuf *p;
-#endif
-  struct ip_addr ipaddr;
-  struct eth_addr ethaddr;
-  enum etharp_state state;
-  u8_t ctime;
-};
-
-static const struct eth_addr ethbroadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}};
-static struct etharp_entry arp_table[ARP_TABLE_SIZE];
-
-/**
- * Try hard to create a new entry - we want the IP address to appear in
- * the cache (even if this means removing an active entry or so). */
-#define ETHARP_TRY_HARD 1
-
-static s8_t find_entry(struct ip_addr *ipaddr, u8_t flags);
-static err_t update_arp_entry(struct netif *netif, struct ip_addr *ipaddr, struct eth_addr *ethaddr, u8_t flags);
-/**
- * Initializes ARP module.
- */
-void
-etharp_init(void)
-{
-  u8_t i;
-  /* clear ARP entries */
-  for(i = 0; i < ARP_TABLE_SIZE; ++i) {
-    arp_table[i].state = ETHARP_STATE_EMPTY;
-#if ARP_QUEUEING
-    arp_table[i].p = NULL;
-#endif
-    arp_table[i].ctime = 0;
-  }
-}
-
-/**
- * Clears expired entries in the ARP table.
- *
- * This function should be called every ETHARP_TMR_INTERVAL microseconds (5 seconds),
- * in order to expire entries in the ARP table.
- */
-void
-etharp_tmr(void)
-{
-  u8_t i;
-
-  LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer\n"));
-  /* remove expired entries from the ARP table */
-  for (i = 0; i < ARP_TABLE_SIZE; ++i) {
-    arp_table[i].ctime++;
-    /* stable entry? */
-    if ((arp_table[i].state == ETHARP_STATE_STABLE) &&
-         /* entry has become old? */
-        (arp_table[i].ctime >= ARP_MAXAGE)) {
-      LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired stable entry %"U16_F".\n", (u16_t)i));
-      arp_table[i].state = ETHARP_STATE_EXPIRED;
-    /* pending entry? */
-    } else if (arp_table[i].state == ETHARP_STATE_PENDING) {
-      /* entry unresolved/pending for too long? */
-      if (arp_table[i].ctime >= ARP_MAXPENDING) {
-        LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired pending entry %"U16_F".\n", (u16_t)i));
-        arp_table[i].state = ETHARP_STATE_EXPIRED;
-#if ARP_QUEUEING
-      } else if (arp_table[i].p != NULL) {
-        /* resend an ARP query here */
-#endif
-      }
-    }
-    /* clean up entries that have just been expired */
-    if (arp_table[i].state == ETHARP_STATE_EXPIRED) {
-#if ARP_QUEUEING
-      /* and empty packet queue */
-      if (arp_table[i].p != NULL) {
-        /* remove all queued packets */
-        LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer: freeing entry %"U16_F", packet queue %p.\n", (u16_t)i, (void *)(arp_table[i].p)));
-        pbuf_free(arp_table[i].p);
-        arp_table[i].p = NULL;
-      }
-#endif
-      /* recycle entry for re-use */      
-      arp_table[i].state = ETHARP_STATE_EMPTY;
-    }
-  }
-}
-
-/**
- * Search the ARP table for a matching or new entry.
- * 
- * If an IP address is given, return a pending or stable ARP entry that matches
- * the address. If no match is found, create a new entry with this address set,
- * but in state ETHARP_EMPTY. The caller must check and possibly change the
- * state of the returned entry.
- * 
- * If ipaddr is NULL, return a initialized new entry in state ETHARP_EMPTY.
- * 
- * In all cases, attempt to create new entries from an empty entry. If no
- * empty entries are available and ETHARP_TRY_HARD flag is set, recycle
- * old entries. Heuristic choose the least important entry for recycling.
- *
- * @param ipaddr IP address to find in ARP cache, or to add if not found.
- * @param flags
- * - ETHARP_TRY_HARD: Try hard to create a entry by allowing recycling of
- * active (stable or pending) entries.
- *  
- * @return The ARP entry index that matched or is created, ERR_MEM if no
- * entry is found or could be recycled.
- */
-static s8_t find_entry(struct ip_addr *ipaddr, u8_t flags)
-{
-  s8_t old_pending = ARP_TABLE_SIZE, old_stable = ARP_TABLE_SIZE;
-  s8_t empty = ARP_TABLE_SIZE;
-  u8_t i = 0, age_pending = 0, age_stable = 0;
-#if ARP_QUEUEING
-  /* oldest entry with packets on queue */
-  s8_t old_queue = ARP_TABLE_SIZE;
-  /* its age */
-  u8_t age_queue = 0;
-#endif
-
-  /**
-   * a) do a search through the cache, remember candidates
-   * b) select candidate entry
-   * c) create new entry
-   */
-
-  /* a) in a single search sweep, do all of this
-   * 1) remember the first empty entry (if any)
-   * 2) remember the oldest stable entry (if any)
-   * 3) remember the oldest pending entry without queued packets (if any)
-   * 4) remember the oldest pending entry with queued packets (if any)
-   * 5) search for a matching IP entry, either pending or stable
-   *    until 5 matches, or all entries are searched for.
-   */
-
-  for (i = 0; i < ARP_TABLE_SIZE; ++i) {
-    /* no empty entry found yet and now we do find one? */
-    if ((empty == ARP_TABLE_SIZE) && (arp_table[i].state == ETHARP_STATE_EMPTY)) {
-      LWIP_DEBUGF(ETHARP_DEBUG, ("find_entry: found empty entry %"U16_F"\n", (u16_t)i));
-      /* remember first empty entry */
-      empty = i;
-    }
-    /* pending entry? */
-    else if (arp_table[i].state == ETHARP_STATE_PENDING) {
-      /* if given, does IP address match IP address in ARP entry? */
-      if (ipaddr && ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) {
-        LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("find_entry: found matching pending entry %"U16_F"\n", (u16_t)i));
-        /* found exact IP address match, simply bail out */
-        return i;
-#if ARP_QUEUEING
-      /* pending with queued packets? */
-      } else if (arp_table[i].p != NULL) {
-        if (arp_table[i].ctime >= age_queue) {
-          old_queue = i;
-          age_queue = arp_table[i].ctime;
-        }
-#endif
-      /* pending without queued packets? */
-      } else {
-        if (arp_table[i].ctime >= age_pending) {
-          old_pending = i;
-          age_pending = arp_table[i].ctime;
-        }
-      }        
-    }
-    /* stable entry? */
-    else if (arp_table[i].state == ETHARP_STATE_STABLE) {
-      /* if given, does IP address match IP address in ARP entry? */
-      if (ipaddr && ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) {
-        LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("find_entry: found matching stable entry %"U16_F"\n", (u16_t)i));
-        /* found exact IP address match, simply bail out */
-        return i;
-      /* remember entry with oldest stable entry in oldest, its age in maxtime */
-      } else if (arp_table[i].ctime >= age_stable) {
-        old_stable = i;
-        age_stable = arp_table[i].ctime;
-      }
-    }
-  }
-  /* { we have no match } => try to create a new entry */
-   
-  /* no empty entry found and not allowed to recycle? */
-  if ((empty == ARP_TABLE_SIZE) && ((flags & ETHARP_TRY_HARD) == 0))
-  {
-       return (s8_t)ERR_MEM;
-  }
-  
-  /* b) choose the least destructive entry to recycle:
-   * 1) empty entry
-   * 2) oldest stable entry
-   * 3) oldest pending entry without queued packets
-   * 4) oldest pending entry without queued packets
-   * 
-   * { ETHARP_TRY_HARD is set at this point }
-   */ 
-
-  /* 1) empty entry available? */
-  if (empty < ARP_TABLE_SIZE) {
-    i = empty;
-    LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("find_entry: selecting empty entry %"U16_F"\n", (u16_t)i));
-  }
-  /* 2) found recyclable stable entry? */
-  else if (old_stable < ARP_TABLE_SIZE) {
-    /* recycle oldest stable*/
-    i = old_stable;
-    LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("find_entry: selecting oldest stable entry %"U16_F"\n", (u16_t)i));
-#if ARP_QUEUEING
-    /* no queued packets should exist on stable entries */
-    LWIP_ASSERT("arp_table[i].p == NULL", arp_table[i].p == NULL);
-#endif
-  /* 3) found recyclable pending entry without queued packets? */
-  } else if (old_pending < ARP_TABLE_SIZE) {
-    /* recycle oldest pending */
-    i = old_pending;
-    LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("find_entry: selecting oldest pending entry %"U16_F" (without queue)\n", (u16_t)i));
-#if ARP_QUEUEING
-  /* 4) found recyclable pending entry with queued packets? */
-  } else if (old_queue < ARP_TABLE_SIZE) {
-    /* recycle oldest pending */
-    i = old_queue;
-    LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("find_entry: selecting oldest pending entry %"U16_F", freeing packet queue %p\n", (u16_t)i, (void *)(arp_table[i].p)));
-    pbuf_free(arp_table[i].p);
-    arp_table[i].p = NULL;
-#endif
-    /* no empty or recyclable entries found */
-  } else {
-    return (s8_t)ERR_MEM;
-  }
-
-  /* { empty or recyclable entry found } */
-  LWIP_ASSERT("i < ARP_TABLE_SIZE", i < ARP_TABLE_SIZE);
-
-  /* recycle entry (no-op for an already empty entry) */
-  arp_table[i].state = ETHARP_STATE_EMPTY;
-
-  /* IP address given? */
-  if (ipaddr != NULL) {
-    /* set IP address */
-    ip_addr_set(&arp_table[i].ipaddr, ipaddr);
-  }
-  arp_table[i].ctime = 0;
-  return (err_t)i;
-}
-
-/**
- * Update (or insert) a IP/MAC address pair in the ARP cache.
- *
- * If a pending entry is resolved, any queued packets will be sent
- * at this point.
- * 
- * @param ipaddr IP address of the inserted ARP entry.
- * @param ethaddr Ethernet address of the inserted ARP entry.
- * @param flags Defines behaviour:
- * - ETHARP_TRY_HARD Allows ARP to insert this as a new item. If not specified,
- * only existing ARP entries will be updated.
- *
- * @return
- * - ERR_OK Succesfully updated ARP cache.
- * - ERR_MEM If we could not add a new ARP entry when ETHARP_TRY_HARD was set.
- * - ERR_ARG Non-unicast address given, those will not appear in ARP cache.
- *
- * @see pbuf_free()
- */
-static err_t
-update_arp_entry(struct netif *netif, struct ip_addr *ipaddr, struct eth_addr *ethaddr, u8_t flags)
-{
-  s8_t i, k;
-  LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | 3, ("update_arp_entry()\n"));
-  LWIP_ASSERT("netif->hwaddr_len != 0", netif->hwaddr_len != 0);
-  LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: %"U16_F".%"U16_F".%"U16_F".%"U16_F" - %02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F"\n",
-                                        ip4_addr1(ipaddr), ip4_addr2(ipaddr), ip4_addr3(ipaddr), ip4_addr4(ipaddr), 
-                                        ethaddr->addr[0], ethaddr->addr[1], ethaddr->addr[2],
-                                        ethaddr->addr[3], ethaddr->addr[4], ethaddr->addr[5]));
-  /* non-unicast address? */
-  if (ip_addr_isany(ipaddr) ||
-      ip_addr_isbroadcast(ipaddr, netif) ||
-      ip_addr_ismulticast(ipaddr)) {
-    LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: will not add non-unicast IP address to ARP cache\n"));
-    return ERR_ARG;
-  }
-  /* find or create ARP entry */
-  i = find_entry(ipaddr, flags);
-  /* bail out if no entry could be found */
-  if (i < 0) return (err_t)i;
-  
-  /* mark it stable */
-  arp_table[i].state = ETHARP_STATE_STABLE;
-
-  LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: updating stable entry %"S16_F"\n", (s16_t)i));
-  /* update address */
-  for (k = 0; k < netif->hwaddr_len; ++k) {
-    arp_table[i].ethaddr.addr[k] = ethaddr->addr[k];
-  }
-  /* reset time stamp */
-  arp_table[i].ctime = 0;
-/* this is where we will send out queued packets! */
-#if ARP_QUEUEING
-  while (arp_table[i].p != NULL) {
-    /* get the first packet on the queue */
-    struct pbuf *p = arp_table[i].p;
-    /* Ethernet header */
-    struct eth_hdr *ethhdr = p->payload;
-    /* remember (and reference) remainder of queue */
-    /* note: this will also terminate the p pbuf chain */
-    arp_table[i].p = pbuf_dequeue(p);
-    /* fill-in Ethernet header */
-    for (k = 0; k < netif->hwaddr_len; ++k) {
-      ethhdr->dest.addr[k] = ethaddr->addr[k];
-      ethhdr->src.addr[k] = netif->hwaddr[k];
-    }
-    ethhdr->type = htons(ETHTYPE_IP);
-    LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: sending queued IP packet %p.\n", (void *)p));
-    /* send the queued IP packet */
-    netif->linkoutput(netif, p);
-    /* free the queued IP packet */
-    pbuf_free(p);
-  }
-#endif
-  return ERR_OK;
-}
-
-/**
- * Updates the ARP table using the given IP packet.
- *
- * Uses the incoming IP packet's source address to update the
- * ARP cache for the local network. The function does not alter
- * or free the packet. This function must be called before the
- * packet p is passed to the IP layer.
- *
- * @param netif The lwIP network interface on which the IP packet pbuf arrived.
- * @param pbuf The IP packet that arrived on netif.
- *
- * @return NULL
- *
- * @see pbuf_free()
- */
-void
-etharp_ip_input(struct netif *netif, struct pbuf *p)
-{
-  struct ethip_hdr *hdr;
-  LWIP_ASSERT("netif != NULL", netif != NULL);
-  /* Only insert an entry if the source IP address of the
-     incoming IP packet comes from a host on the local network. */
-  hdr = p->payload;
-  /* source is not on the local network? */
-  if (!ip_addr_netcmp(&(hdr->ip.src), &(netif->ip_addr), &(netif->netmask))) {
-    /* do nothing */
-    return;
-  }
-
-  LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_ip_input: updating ETHARP table.\n"));
-  /* update ARP table */
-  /* @todo We could use ETHARP_TRY_HARD if we think we are going to talk
-   * back soon (for example, if the destination IP address is ours. */
-  update_arp_entry(netif, &(hdr->ip.src), &(hdr->eth.src), 0);
-}
-
-
-/**
- * Responds to ARP requests to us. Upon ARP replies to us, add entry to cache  
- * send out queued IP packets. Updates cache with snooped address pairs.
- *
- * Should be called for incoming ARP packets. The pbuf in the argument
- * is freed by this function.
- *
- * @param netif The lwIP network interface on which the ARP packet pbuf arrived.
- * @param pbuf The ARP packet that arrived on netif. Is freed by this function.
- * @param ethaddr Ethernet address of netif.
- *
- * @return NULL
- *
- * @see pbuf_free()
- */
-void
-etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p)
-{
-  struct etharp_hdr *hdr;
-  /* these are aligned properly, whereas the ARP header fields might not be */
-  struct ip_addr sipaddr, dipaddr;
-  u8_t i;
-  u8_t for_us;
-
-  LWIP_ASSERT("netif != NULL", netif != NULL);
-  
-  /* drop short ARP packets */
-  if (p->tot_len < sizeof(struct etharp_hdr)) {
-    LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | 1, ("etharp_arp_input: packet dropped, too short (%"S16_F"/%"S16_F")\n", p->tot_len, sizeof(struct etharp_hdr)));
-    pbuf_free(p);
-    return;
-  }
-
-  hdr = p->payload;
-  /* get aligned copies of addresses */
-  *(struct ip_addr2 *)&sipaddr = hdr->sipaddr;
-  *(struct ip_addr2 *)&dipaddr = hdr->dipaddr;
-
-  /* this interface is not configured? */
-  if (netif->ip_addr.addr == 0) {
-    for_us = 0;
-  } else {
-    /* ARP packet directed to us? */
-    for_us = ip_addr_cmp(&dipaddr, &(netif->ip_addr));
-  }
-
-  /* ARP message directed to us? */
-  if (for_us) {
-    /* add IP address in ARP cache; assume requester wants to talk to us.
-     * can result in directly sending the queued packets for this host. */
-    update_arp_entry(netif, &sipaddr, &(hdr->shwaddr), ETHARP_TRY_HARD);
-  /* ARP message not directed to us? */
-  } else {
-    /* update the source IP address in the cache, if present */
-    update_arp_entry(netif, &sipaddr, &(hdr->shwaddr), 0);
-  }
-
-  /* now act on the message itself */
-  switch (htons(hdr->opcode)) {
-  /* ARP request? */
-  case ARP_REQUEST:
-    /* ARP request. If it asked for our address, we send out a
-     * reply. In any case, we time-stamp any existing ARP entry,
-     * and possiby send out an IP packet that was queued on it. */
-
-    LWIP_DEBUGF (ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: incoming ARP request\n"));
-    /* ARP request for our address? */
-    if (for_us) {
-
-      LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: replying to ARP request for our IP address\n"));
-      /* re-use pbuf to send ARP reply */
-      hdr->opcode = htons(ARP_REPLY);
-
-      hdr->dipaddr = hdr->sipaddr;
-      hdr->sipaddr = *(struct ip_addr2 *)&netif->ip_addr;
-
-      for(i = 0; i < netif->hwaddr_len; ++i) {
-        hdr->dhwaddr.addr[i] = hdr->shwaddr.addr[i];
-        hdr->shwaddr.addr[i] = ethaddr->addr[i];
-        hdr->ethhdr.dest.addr[i] = hdr->dhwaddr.addr[i];
-        hdr->ethhdr.src.addr[i] = ethaddr->addr[i];
-      }
-
-      hdr->hwtype = htons(HWTYPE_ETHERNET);
-      ARPH_HWLEN_SET(hdr, netif->hwaddr_len);
-
-      hdr->proto = htons(ETHTYPE_IP);
-      ARPH_PROTOLEN_SET(hdr, sizeof(struct ip_addr));
-
-      hdr->ethhdr.type = htons(ETHTYPE_ARP);
-      /* return ARP reply */
-      netif->linkoutput(netif, p);
-    /* we are not configured? */
-    } else if (netif->ip_addr.addr == 0) {
-      /* { for_us == 0 and netif->ip_addr.addr == 0 } */
-      LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: we are unconfigured, ARP request ignored.\n"));
-    /* request was not directed to us */
-    } else {
-      /* { for_us == 0 and netif->ip_addr.addr != 0 } */
-      LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: ARP request was not for us.\n"));
-    }
-    break;
-  case ARP_REPLY:
-    /* ARP reply. We already updated the ARP cache earlier. */
-    LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: incoming ARP reply\n"));
-#if (LWIP_DHCP && DHCP_DOES_ARP_CHECK)
-    /* DHCP wants to know about ARP replies from any host with an
-     * IP address also offered to us by the DHCP server. We do not
-     * want to take a duplicate IP address on a single network.
-     * @todo How should we handle redundant (fail-over) interfaces?
-     * */
-    dhcp_arp_reply(netif, &sipaddr);
-#endif
-    break;
-  default:
-    LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: ARP unknown opcode type %"S16_F"\n", htons(hdr->opcode)));
-    break;
-  }
-  /* free ARP packet */
-  pbuf_free(p);
-}
-
-/**
- * Resolve and fill-in Ethernet address header for outgoing packet.
- *
- * For IP multicast and broadcast, corresponding Ethernet addresses
- * are selected and the packet is transmitted on the link.
- *
- * For unicast addresses, the packet is submitted to etharp_query(). In
- * case the IP address is outside the local network, the IP address of
- * the gateway is used.
- *
- * @param netif The lwIP network interface which the IP packet will be sent on.
- * @param ipaddr The IP address of the packet destination.
- * @param pbuf The pbuf(s) containing the IP packet to be sent.
- *
- * @return
- * - ERR_RTE No route to destination (no gateway to external networks),
- * or the return type of either etharp_query() or netif->linkoutput().
- */
-err_t
-etharp_output(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)
-{
-  struct eth_addr *dest, *srcaddr, mcastaddr;
-  struct eth_hdr *ethhdr;
-  u8_t i;
-
-  /* make room for Ethernet header - should not fail */
-  if (pbuf_header(q, sizeof(struct eth_hdr)) != 0) {
-    /* bail out */
-    LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | 2, ("etharp_output: could not allocate room for header.\n"));
-    LINK_STATS_INC(link.lenerr);
-    return ERR_BUF;
-  }
-
-  /* assume unresolved Ethernet address */
-  dest = NULL;
-  /* Determine on destination hardware address. Broadcasts and multicasts
-   * are special, other IP addresses are looked up in the ARP table. */
-
-  /* broadcast destination IP address? */
-  if (ip_addr_isbroadcast(ipaddr, netif)) {
-    /* broadcast on Ethernet also */
-    dest = (struct eth_addr *)&ethbroadcast;
-  /* multicast destination IP address? */
-  } else if (ip_addr_ismulticast(ipaddr)) {
-    /* Hash IP multicast address to MAC address.*/
-    mcastaddr.addr[0] = 0x01;
-    mcastaddr.addr[1] = 0x00;
-    mcastaddr.addr[2] = 0x5e;
-    mcastaddr.addr[3] = ip4_addr2(ipaddr) & 0x7f;
-    mcastaddr.addr[4] = ip4_addr3(ipaddr);
-    mcastaddr.addr[5] = ip4_addr4(ipaddr);
-    /* destination Ethernet address is multicast */
-    dest = &mcastaddr;
-  /* unicast destination IP address? */
-  } else {
-    /* outside local network? */
-    if (!ip_addr_netcmp(ipaddr, &(netif->ip_addr), &(netif->netmask))) {
-      /* interface has default gateway? */
-      if (netif->gw.addr != 0) {
-        /* send to hardware address of default gateway IP address */
-        ipaddr = &(netif->gw);
-      /* no default gateway available */
-      } else {
-        /* no route to destination error (default gateway missing) */
-        return ERR_RTE;
-      }
-    }
-    /* queue on destination Ethernet address belonging to ipaddr */
-    return etharp_query(netif, ipaddr, q);
-  }
-
-  /* continuation for multicast/broadcast destinations */
-  /* obtain source Ethernet address of the given interface */
-  srcaddr = (struct eth_addr *)netif->hwaddr;
-  ethhdr = q->payload;
-  for (i = 0; i < netif->hwaddr_len; i++) {
-    ethhdr->dest.addr[i] = dest->addr[i];
-    ethhdr->src.addr[i] = srcaddr->addr[i];
-  }
-  ethhdr->type = htons(ETHTYPE_IP);
-  /* send packet directly on the link */
-  return netif->linkoutput(netif, q);
-}
-
-/**
- * Send an ARP request for the given IP address and/or queue a packet.
- *
- * If the IP address was not yet in the cache, a pending ARP cache entry
- * is added and an ARP request is sent for the given address. The packet
- * is queued on this entry.
- *
- * If the IP address was already pending in the cache, a new ARP request
- * is sent for the given address. The packet is queued on this entry.
- *
- * If the IP address was already stable in the cache, and a packet is
- * given, it is directly sent and no ARP request is sent out. 
- * 
- * If the IP address was already stable in the cache, and no packet is
- * given, an ARP request is sent out.
- * 
- * @param netif The lwIP network interface on which ipaddr
- * must be queried for.
- * @param ipaddr The IP address to be resolved.
- * @param q If non-NULL, a pbuf that must be delivered to the IP address.
- * q is not freed by this function.
- *
- * @return
- * - ERR_BUF Could not make room for Ethernet header.
- * - ERR_MEM Hardware address unknown, and no more ARP entries available
- *   to query for address or queue the packet.
- * - ERR_MEM Could not queue packet due to memory shortage.
- * - ERR_RTE No route to destination (no gateway to external networks).
- * - ERR_ARG Non-unicast address given, those will not appear in ARP cache.
- *
- */
-err_t etharp_query(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)
-{
-  struct eth_addr * srcaddr = (struct eth_addr *)netif->hwaddr;
-  err_t result = ERR_MEM;
-  s8_t i; /* ARP entry index */
-  u8_t k; /* Ethernet address octet index */
-
-  /* non-unicast address? */
-  if (ip_addr_isbroadcast(ipaddr, netif) ||
-      ip_addr_ismulticast(ipaddr) ||
-      ip_addr_isany(ipaddr)) {
-    LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_query: will not add non-unicast IP address to ARP cache\n"));
-    return ERR_ARG;
-  }
-
-  /* find entry in ARP cache, ask to create entry if queueing packet */
-  i = find_entry(ipaddr, ETHARP_TRY_HARD);
-
-  /* could not find or create entry? */
-  if (i < 0)
-  {
-    LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_query: could not create ARP entry\n"));
-    if (q) LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_query: packet dropped\n"));
-    return (err_t)i;
-  }
-
-  /* mark a fresh entry as pending (we just sent a request) */
-  if (arp_table[i].state == ETHARP_STATE_EMPTY) {
-    arp_table[i].state = ETHARP_STATE_PENDING;
-  }
-
-  /* { i is either a STABLE or (new or existing) PENDING entry } */
-  LWIP_ASSERT("arp_table[i].state == PENDING or STABLE",
-  ((arp_table[i].state == ETHARP_STATE_PENDING) ||
-   (arp_table[i].state == ETHARP_STATE_STABLE)));
-
-  /* do we have a pending entry? or an implicit query request? */
-  if ((arp_table[i].state == ETHARP_STATE_PENDING) || (q == NULL)) {
-    /* try to resolve it; send out ARP request */
-    result = etharp_request(netif, ipaddr);
-  }
-  
-  /* packet given? */
-  if (q != NULL) {
-    /* stable entry? */
-    if (arp_table[i].state == ETHARP_STATE_STABLE) {
-      /* we have a valid IP->Ethernet address mapping,
-       * fill in the Ethernet header for the outgoing packet */
-      struct eth_hdr *ethhdr = q->payload;
-      for(k = 0; k < netif->hwaddr_len; k++) {
-        ethhdr->dest.addr[k] = arp_table[i].ethaddr.addr[k];
-        ethhdr->src.addr[k]  = srcaddr->addr[k];
-      }
-      ethhdr->type = htons(ETHTYPE_IP);
-      LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_query: sending packet %p\n", (void *)q));
-      /* send the packet */
-      result = netif->linkoutput(netif, q);
-    /* pending entry? (either just created or already pending */
-    } else if (arp_table[i].state == ETHARP_STATE_PENDING) {
-#if ARP_QUEUEING /* queue the given q packet */
-      struct pbuf *p;
-      /* copy any PBUF_REF referenced payloads into PBUF_RAM */
-      /* (the caller of lwIP assumes the referenced payload can be
-       * freed after it returns from the lwIP call that brought us here) */
-      p = pbuf_take(q);
-      /* packet could be taken over? */
-      if (p != NULL) {
-        /* queue packet ... */
-        if (arp_table[i].p == NULL) {
-               /* ... in the empty queue */
-               pbuf_ref(p);
-               arp_table[i].p = p;
-#if 0 /* multi-packet-queueing disabled, see bug #11400 */
-        } else {
-               /* ... at tail of non-empty queue */
-          pbuf_queue(arp_table[i].p, p);
-#endif
-        }
-        LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_query: queued packet %p on ARP entry %"S16_F"\n", (void *)q, (s16_t)i));
-        result = ERR_OK;
-      } else {
-        LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_query: could not queue a copy of PBUF_REF packet %p (out of memory)\n", (void *)q));
-        /* { result == ERR_MEM } through initialization */
-      }
-#else /* ARP_QUEUEING == 0 */
-      /* q && state == PENDING && ARP_QUEUEING == 0 => result = ERR_MEM */
-      /* { result == ERR_MEM } through initialization */
-      LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_query: Ethernet destination address unknown, queueing disabled, packet %p dropped\n", (void *)q));
-#endif
-    }
-  }
-  return result;
-}
-
-err_t etharp_request(struct netif *netif, struct ip_addr *ipaddr)
-{
-  struct pbuf *p;
-  struct eth_addr * srcaddr = (struct eth_addr *)netif->hwaddr;
-  err_t result = ERR_OK;
-  u8_t k; /* ARP entry index */
-
-  /* allocate a pbuf for the outgoing ARP request packet */
-  p = pbuf_alloc(PBUF_LINK, sizeof(struct etharp_hdr), PBUF_RAM);
-  /* could allocate a pbuf for an ARP request? */
-  if (p != NULL) {
-    struct etharp_hdr *hdr = p->payload;
-    LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_request: sending ARP request.\n"));
-    hdr->opcode = htons(ARP_REQUEST);
-    for (k = 0; k < netif->hwaddr_len; k++)
-    {
-      hdr->shwaddr.addr[k] = srcaddr->addr[k];
-      /* the hardware address is what we ask for, in
-       * a request it is a don't-care value, we use zeroes */
-      hdr->dhwaddr.addr[k] = 0x00;
-    }
-    hdr->dipaddr = *(struct ip_addr2 *)ipaddr;
-    hdr->sipaddr = *(struct ip_addr2 *)&netif->ip_addr;
-
-    hdr->hwtype = htons(HWTYPE_ETHERNET);
-    ARPH_HWLEN_SET(hdr, netif->hwaddr_len);
-
-    hdr->proto = htons(ETHTYPE_IP);
-    ARPH_PROTOLEN_SET(hdr, sizeof(struct ip_addr));
-    for (k = 0; k < netif->hwaddr_len; ++k)
-    {
-      /* broadcast to all network interfaces on the local network */
-      hdr->ethhdr.dest.addr[k] = 0xff;
-      hdr->ethhdr.src.addr[k] = srcaddr->addr[k];
-    }
-    hdr->ethhdr.type = htons(ETHTYPE_ARP);
-    /* send ARP query */
-    result = netif->linkoutput(netif, p);
-    /* free ARP query packet */
-    pbuf_free(p);
-    p = NULL;
-  /* could not allocate pbuf for ARP request */
-  } else {
-    result = ERR_MEM;
-    LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | 2, ("etharp_request: could not allocate pbuf for ARP request.\n"));
-  }
-  return result;
-}
+/**\r
+ * @file\r
+ * Address Resolution Protocol module for IP over Ethernet\r
+ *\r
+ * Functionally, ARP is divided into two parts. The first maps an IP address\r
+ * to a physical address when sending a packet, and the second part answers\r
+ * requests from other machines for our physical address.\r
+ *\r
+ * This implementation complies with RFC 826 (Ethernet ARP). It supports\r
+ * Gratuitious ARP from RFC3220 (IP Mobility Support for IPv4) section 4.6\r
+ * if an interface calls etharp_query(our_netif, its_ip_addr, NULL) upon\r
+ * address change.\r
+ */\r
+\r
+/*\r
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.\r
+ * Copyright (c) 2003-2004 Leon Woestenberg <leon.woestenberg@axon.tv>\r
+ * Copyright (c) 2003-2004 Axon Digital Design B.V., The Netherlands.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without modification,\r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED\r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT\r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY\r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ *\r
+ */\r
+\r
+#include "lwip/opt.h"\r
+#include "lwip/inet.h"\r
+#include "netif/etharp.h"\r
+#include "lwip/ip.h"\r
+#include "lwip/stats.h"\r
+\r
+/* ARP needs to inform DHCP of any ARP replies? */\r
+#if (LWIP_DHCP && DHCP_DOES_ARP_CHECK)\r
+#  include "lwip/dhcp.h"\r
+#endif\r
+\r
+/** the time an ARP entry stays valid after its last update,\r
+ * (240 * 5) seconds = 20 minutes.\r
+ */\r
+#define ARP_MAXAGE 240\r
+/** the time an ARP entry stays pending after first request,\r
+ * (2 * 5) seconds = 10 seconds.\r
+ * \r
+ * @internal Keep this number at least 2, otherwise it might\r
+ * run out instantly if the timeout occurs directly after a request.\r
+ */\r
+#define ARP_MAXPENDING 2\r
+\r
+#define HWTYPE_ETHERNET 1\r
+\r
+/** ARP message types */\r
+#define ARP_REQUEST 1\r
+#define ARP_REPLY 2\r
+\r
+#define ARPH_HWLEN(hdr) (ntohs((hdr)->_hwlen_protolen) >> 8)\r
+#define ARPH_PROTOLEN(hdr) (ntohs((hdr)->_hwlen_protolen) & 0xff)\r
+\r
+#define ARPH_HWLEN_SET(hdr, len) (hdr)->_hwlen_protolen = htons(ARPH_PROTOLEN(hdr) | ((len) << 8))\r
+#define ARPH_PROTOLEN_SET(hdr, len) (hdr)->_hwlen_protolen = htons((len) | (ARPH_HWLEN(hdr) << 8))\r
+\r
+enum etharp_state {\r
+  ETHARP_STATE_EMPTY,\r
+  ETHARP_STATE_PENDING,\r
+  ETHARP_STATE_STABLE,\r
+  /** @internal transitional state used in etharp_tmr() for convenience*/\r
+  ETHARP_STATE_EXPIRED\r
+};\r
+\r
+struct etharp_entry {\r
+#if ARP_QUEUEING\r
+  /** \r
+   * Pointer to queue of pending outgoing packets on this ARP entry.\r
+   */\r
+   struct pbuf *p;\r
+#endif\r
+  struct ip_addr ipaddr;\r
+  struct eth_addr ethaddr;\r
+  enum etharp_state state;\r
+  u8_t ctime;\r
+};\r
+\r
+static const struct eth_addr ethbroadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}};\r
+static struct etharp_entry arp_table[ARP_TABLE_SIZE];\r
+\r
+/**\r
+ * Try hard to create a new entry - we want the IP address to appear in\r
+ * the cache (even if this means removing an active entry or so). */\r
+#define ETHARP_TRY_HARD 1\r
+\r
+static s8_t find_entry(struct ip_addr *ipaddr, u8_t flags);\r
+static err_t update_arp_entry(struct netif *netif, struct ip_addr *ipaddr, struct eth_addr *ethaddr, u8_t flags);\r
+/**\r
+ * Initializes ARP module.\r
+ */\r
+void\r
+etharp_init(void)\r
+{\r
+  u8_t i;\r
+  /* clear ARP entries */\r
+  for(i = 0; i < ARP_TABLE_SIZE; ++i) {\r
+    arp_table[i].state = ETHARP_STATE_EMPTY;\r
+#if ARP_QUEUEING\r
+    arp_table[i].p = NULL;\r
+#endif\r
+    arp_table[i].ctime = 0;\r
+  }\r
+}\r
+\r
+/**\r
+ * Clears expired entries in the ARP table.\r
+ *\r
+ * This function should be called every ETHARP_TMR_INTERVAL microseconds (5 seconds),\r
+ * in order to expire entries in the ARP table.\r
+ */\r
+void\r
+etharp_tmr(void)\r
+{\r
+  u8_t i;\r
+\r
+  LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer\n"));\r
+  /* remove expired entries from the ARP table */\r
+  for (i = 0; i < ARP_TABLE_SIZE; ++i) {\r
+    arp_table[i].ctime++;\r
+    /* stable entry? */\r
+    if ((arp_table[i].state == ETHARP_STATE_STABLE) &&\r
+         /* entry has become old? */\r
+        (arp_table[i].ctime >= ARP_MAXAGE)) {\r
+      LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired stable entry %"U16_F".\n", (u16_t)i));\r
+      arp_table[i].state = ETHARP_STATE_EXPIRED;\r
+    /* pending entry? */\r
+    } else if (arp_table[i].state == ETHARP_STATE_PENDING) {\r
+      /* entry unresolved/pending for too long? */\r
+      if (arp_table[i].ctime >= ARP_MAXPENDING) {\r
+        LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired pending entry %"U16_F".\n", (u16_t)i));\r
+        arp_table[i].state = ETHARP_STATE_EXPIRED;\r
+#if ARP_QUEUEING\r
+      } else if (arp_table[i].p != NULL) {\r
+        /* resend an ARP query here */\r
+#endif\r
+      }\r
+    }\r
+    /* clean up entries that have just been expired */\r
+    if (arp_table[i].state == ETHARP_STATE_EXPIRED) {\r
+#if ARP_QUEUEING\r
+      /* and empty packet queue */\r
+      if (arp_table[i].p != NULL) {\r
+        /* remove all queued packets */\r
+        LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer: freeing entry %"U16_F", packet queue %p.\n", (u16_t)i, (void *)(arp_table[i].p)));\r
+        pbuf_free(arp_table[i].p);\r
+        arp_table[i].p = NULL;\r
+      }\r
+#endif\r
+      /* recycle entry for re-use */      \r
+      arp_table[i].state = ETHARP_STATE_EMPTY;\r
+    }\r
+  }\r
+}\r
+\r
+/**\r
+ * Search the ARP table for a matching or new entry.\r
+ * \r
+ * If an IP address is given, return a pending or stable ARP entry that matches\r
+ * the address. If no match is found, create a new entry with this address set,\r
+ * but in state ETHARP_EMPTY. The caller must check and possibly change the\r
+ * state of the returned entry.\r
+ * \r
+ * If ipaddr is NULL, return a initialized new entry in state ETHARP_EMPTY.\r
+ * \r
+ * In all cases, attempt to create new entries from an empty entry. If no\r
+ * empty entries are available and ETHARP_TRY_HARD flag is set, recycle\r
+ * old entries. Heuristic choose the least important entry for recycling.\r
+ *\r
+ * @param ipaddr IP address to find in ARP cache, or to add if not found.\r
+ * @param flags\r
+ * - ETHARP_TRY_HARD: Try hard to create a entry by allowing recycling of\r
+ * active (stable or pending) entries.\r
+ *  \r
+ * @return The ARP entry index that matched or is created, ERR_MEM if no\r
+ * entry is found or could be recycled.\r
+ */\r
+static s8_t find_entry(struct ip_addr *ipaddr, u8_t flags)\r
+{\r
+  s8_t old_pending = ARP_TABLE_SIZE, old_stable = ARP_TABLE_SIZE;\r
+  s8_t empty = ARP_TABLE_SIZE;\r
+  u8_t i = 0, age_pending = 0, age_stable = 0;\r
+#if ARP_QUEUEING\r
+  /* oldest entry with packets on queue */\r
+  s8_t old_queue = ARP_TABLE_SIZE;\r
+  /* its age */\r
+  u8_t age_queue = 0;\r
+#endif\r
+\r
+  /**\r
+   * a) do a search through the cache, remember candidates\r
+   * b) select candidate entry\r
+   * c) create new entry\r
+   */\r
+\r
+  /* a) in a single search sweep, do all of this\r
+   * 1) remember the first empty entry (if any)\r
+   * 2) remember the oldest stable entry (if any)\r
+   * 3) remember the oldest pending entry without queued packets (if any)\r
+   * 4) remember the oldest pending entry with queued packets (if any)\r
+   * 5) search for a matching IP entry, either pending or stable\r
+   *    until 5 matches, or all entries are searched for.\r
+   */\r
+\r
+  for (i = 0; i < ARP_TABLE_SIZE; ++i) {\r
+    /* no empty entry found yet and now we do find one? */\r
+    if ((empty == ARP_TABLE_SIZE) && (arp_table[i].state == ETHARP_STATE_EMPTY)) {\r
+      LWIP_DEBUGF(ETHARP_DEBUG, ("find_entry: found empty entry %"U16_F"\n", (u16_t)i));\r
+      /* remember first empty entry */\r
+      empty = i;\r
+    }\r
+    /* pending entry? */\r
+    else if (arp_table[i].state == ETHARP_STATE_PENDING) {\r
+      /* if given, does IP address match IP address in ARP entry? */\r
+      if (ipaddr && ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) {\r
+        LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("find_entry: found matching pending entry %"U16_F"\n", (u16_t)i));\r
+        /* found exact IP address match, simply bail out */\r
+        return i;\r
+#if ARP_QUEUEING\r
+      /* pending with queued packets? */\r
+      } else if (arp_table[i].p != NULL) {\r
+        if (arp_table[i].ctime >= age_queue) {\r
+          old_queue = i;\r
+          age_queue = arp_table[i].ctime;\r
+        }\r
+#endif\r
+      /* pending without queued packets? */\r
+      } else {\r
+        if (arp_table[i].ctime >= age_pending) {\r
+          old_pending = i;\r
+          age_pending = arp_table[i].ctime;\r
+        }\r
+      }        \r
+    }\r
+    /* stable entry? */\r
+    else if (arp_table[i].state == ETHARP_STATE_STABLE) {\r
+      /* if given, does IP address match IP address in ARP entry? */\r
+      if (ipaddr && ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) {\r
+        LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("find_entry: found matching stable entry %"U16_F"\n", (u16_t)i));\r
+        /* found exact IP address match, simply bail out */\r
+        return i;\r
+      /* remember entry with oldest stable entry in oldest, its age in maxtime */\r
+      } else if (arp_table[i].ctime >= age_stable) {\r
+        old_stable = i;\r
+        age_stable = arp_table[i].ctime;\r
+      }\r
+    }\r
+  }\r
+  /* { we have no match } => try to create a new entry */\r
+   \r
+  /* no empty entry found and not allowed to recycle? */\r
+  if ((empty == ARP_TABLE_SIZE) && ((flags & ETHARP_TRY_HARD) == 0))\r
+  {\r
+       return (s8_t)ERR_MEM;\r
+  }\r
+  \r
+  /* b) choose the least destructive entry to recycle:\r
+   * 1) empty entry\r
+   * 2) oldest stable entry\r
+   * 3) oldest pending entry without queued packets\r
+   * 4) oldest pending entry without queued packets\r
+   * \r
+   * { ETHARP_TRY_HARD is set at this point }\r
+   */ \r
+\r
+  /* 1) empty entry available? */\r
+  if (empty < ARP_TABLE_SIZE) {\r
+    i = empty;\r
+    LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("find_entry: selecting empty entry %"U16_F"\n", (u16_t)i));\r
+  }\r
+  /* 2) found recyclable stable entry? */\r
+  else if (old_stable < ARP_TABLE_SIZE) {\r
+    /* recycle oldest stable*/\r
+    i = old_stable;\r
+    LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("find_entry: selecting oldest stable entry %"U16_F"\n", (u16_t)i));\r
+#if ARP_QUEUEING\r
+    /* no queued packets should exist on stable entries */\r
+    LWIP_ASSERT("arp_table[i].p == NULL", arp_table[i].p == NULL);\r
+#endif\r
+  /* 3) found recyclable pending entry without queued packets? */\r
+  } else if (old_pending < ARP_TABLE_SIZE) {\r
+    /* recycle oldest pending */\r
+    i = old_pending;\r
+    LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("find_entry: selecting oldest pending entry %"U16_F" (without queue)\n", (u16_t)i));\r
+#if ARP_QUEUEING\r
+  /* 4) found recyclable pending entry with queued packets? */\r
+  } else if (old_queue < ARP_TABLE_SIZE) {\r
+    /* recycle oldest pending */\r
+    i = old_queue;\r
+    LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("find_entry: selecting oldest pending entry %"U16_F", freeing packet queue %p\n", (u16_t)i, (void *)(arp_table[i].p)));\r
+    pbuf_free(arp_table[i].p);\r
+    arp_table[i].p = NULL;\r
+#endif\r
+    /* no empty or recyclable entries found */\r
+  } else {\r
+    return (s8_t)ERR_MEM;\r
+  }\r
+\r
+  /* { empty or recyclable entry found } */\r
+  LWIP_ASSERT("i < ARP_TABLE_SIZE", i < ARP_TABLE_SIZE);\r
+\r
+  /* recycle entry (no-op for an already empty entry) */\r
+  arp_table[i].state = ETHARP_STATE_EMPTY;\r
+\r
+  /* IP address given? */\r
+  if (ipaddr != NULL) {\r
+    /* set IP address */\r
+    ip_addr_set(&arp_table[i].ipaddr, ipaddr);\r
+  }\r
+  arp_table[i].ctime = 0;\r
+  return (err_t)i;\r
+}\r
+\r
+/**\r
+ * Update (or insert) a IP/MAC address pair in the ARP cache.\r
+ *\r
+ * If a pending entry is resolved, any queued packets will be sent\r
+ * at this point.\r
+ * \r
+ * @param ipaddr IP address of the inserted ARP entry.\r
+ * @param ethaddr Ethernet address of the inserted ARP entry.\r
+ * @param flags Defines behaviour:\r
+ * - ETHARP_TRY_HARD Allows ARP to insert this as a new item. If not specified,\r
+ * only existing ARP entries will be updated.\r
+ *\r
+ * @return\r
+ * - ERR_OK Succesfully updated ARP cache.\r
+ * - ERR_MEM If we could not add a new ARP entry when ETHARP_TRY_HARD was set.\r
+ * - ERR_ARG Non-unicast address given, those will not appear in ARP cache.\r
+ *\r
+ * @see pbuf_free()\r
+ */\r
+static err_t\r
+update_arp_entry(struct netif *netif, struct ip_addr *ipaddr, struct eth_addr *ethaddr, u8_t flags)\r
+{\r
+  s8_t i, k;\r
+  LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | 3, ("update_arp_entry()\n"));\r
+  LWIP_ASSERT("netif->hwaddr_len != 0", netif->hwaddr_len != 0);\r
+  LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: %"U16_F".%"U16_F".%"U16_F".%"U16_F" - %02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F"\n",\r
+                                        ip4_addr1(ipaddr), ip4_addr2(ipaddr), ip4_addr3(ipaddr), ip4_addr4(ipaddr), \r
+                                        ethaddr->addr[0], ethaddr->addr[1], ethaddr->addr[2],\r
+                                        ethaddr->addr[3], ethaddr->addr[4], ethaddr->addr[5]));\r
+  /* non-unicast address? */\r
+  if (ip_addr_isany(ipaddr) ||\r
+      ip_addr_isbroadcast(ipaddr, netif) ||\r
+      ip_addr_ismulticast(ipaddr)) {\r
+    LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: will not add non-unicast IP address to ARP cache\n"));\r
+    return ERR_ARG;\r
+  }\r
+  /* find or create ARP entry */\r
+  i = find_entry(ipaddr, flags);\r
+  /* bail out if no entry could be found */\r
+  if (i < 0) return (err_t)i;\r
+  \r
+  /* mark it stable */\r
+  arp_table[i].state = ETHARP_STATE_STABLE;\r
+\r
+  LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: updating stable entry %"S16_F"\n", (s16_t)i));\r
+  /* update address */\r
+  for (k = 0; k < netif->hwaddr_len; ++k) {\r
+    arp_table[i].ethaddr.addr[k] = ethaddr->addr[k];\r
+  }\r
+  /* reset time stamp */\r
+  arp_table[i].ctime = 0;\r
+/* this is where we will send out queued packets! */\r
+#if ARP_QUEUEING\r
+  while (arp_table[i].p != NULL) {\r
+    /* get the first packet on the queue */\r
+    struct pbuf *p = arp_table[i].p;\r
+    /* Ethernet header */\r
+    struct eth_hdr *ethhdr = p->payload;\r
+    /* remember (and reference) remainder of queue */\r
+    /* note: this will also terminate the p pbuf chain */\r
+    arp_table[i].p = pbuf_dequeue(p);\r
+    /* fill-in Ethernet header */\r
+    for (k = 0; k < netif->hwaddr_len; ++k) {\r
+      ethhdr->dest.addr[k] = ethaddr->addr[k];\r
+      ethhdr->src.addr[k] = netif->hwaddr[k];\r
+    }\r
+    ethhdr->type = htons(ETHTYPE_IP);\r
+    LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: sending queued IP packet %p.\n", (void *)p));\r
+    /* send the queued IP packet */\r
+    netif->linkoutput(netif, p);\r
+    /* free the queued IP packet */\r
+    pbuf_free(p);\r
+  }\r
+#endif\r
+  return ERR_OK;\r
+}\r
+\r
+/**\r
+ * Updates the ARP table using the given IP packet.\r
+ *\r
+ * Uses the incoming IP packet's source address to update the\r
+ * ARP cache for the local network. The function does not alter\r
+ * or free the packet. This function must be called before the\r
+ * packet p is passed to the IP layer.\r
+ *\r
+ * @param netif The lwIP network interface on which the IP packet pbuf arrived.\r
+ * @param pbuf The IP packet that arrived on netif.\r
+ *\r
+ * @return NULL\r
+ *\r
+ * @see pbuf_free()\r
+ */\r
+void\r
+etharp_ip_input(struct netif *netif, struct pbuf *p)\r
+{\r
+  struct ethip_hdr *hdr;\r
+  LWIP_ASSERT("netif != NULL", netif != NULL);\r
+  /* Only insert an entry if the source IP address of the\r
+     incoming IP packet comes from a host on the local network. */\r
+  hdr = p->payload;\r
+  /* source is not on the local network? */\r
+  if (!ip_addr_netcmp(&(hdr->ip.src), &(netif->ip_addr), &(netif->netmask))) {\r
+    /* do nothing */\r
+    return;\r
+  }\r
+\r
+  LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_ip_input: updating ETHARP table.\n"));\r
+  /* update ARP table */\r
+  /* @todo We could use ETHARP_TRY_HARD if we think we are going to talk\r
+   * back soon (for example, if the destination IP address is ours. */\r
+  update_arp_entry(netif, &(hdr->ip.src), &(hdr->eth.src), 0);\r
+}\r
+\r
+\r
+/**\r
+ * Responds to ARP requests to us. Upon ARP replies to us, add entry to cache  \r
+ * send out queued IP packets. Updates cache with snooped address pairs.\r
+ *\r
+ * Should be called for incoming ARP packets. The pbuf in the argument\r
+ * is freed by this function.\r
+ *\r
+ * @param netif The lwIP network interface on which the ARP packet pbuf arrived.\r
+ * @param pbuf The ARP packet that arrived on netif. Is freed by this function.\r
+ * @param ethaddr Ethernet address of netif.\r
+ *\r
+ * @return NULL\r
+ *\r
+ * @see pbuf_free()\r
+ */\r
+void\r
+etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p)\r
+{\r
+  struct etharp_hdr *hdr;\r
+  /* these are aligned properly, whereas the ARP header fields might not be */\r
+  struct ip_addr sipaddr, dipaddr;\r
+  u8_t i;\r
+  u8_t for_us;\r
+\r
+  LWIP_ASSERT("netif != NULL", netif != NULL);\r
+  \r
+  /* drop short ARP packets */\r
+  if (p->tot_len < sizeof(struct etharp_hdr)) {\r
+    LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | 1, ("etharp_arp_input: packet dropped, too short (%"S16_F"/%"S16_F")\n", p->tot_len, sizeof(struct etharp_hdr)));\r
+    pbuf_free(p);\r
+    return;\r
+  }\r
+\r
+  hdr = p->payload;\r
\r
+  /* get aligned copies of addresses */\r
+  *(struct ip_addr2 *)&sipaddr = hdr->sipaddr;\r
+  *(struct ip_addr2 *)&dipaddr = hdr->dipaddr;\r
+\r
+  /* this interface is not configured? */\r
+  if (netif->ip_addr.addr == 0) {\r
+    for_us = 0;\r
+  } else {\r
+    /* ARP packet directed to us? */\r
+    for_us = ip_addr_cmp(&dipaddr, &(netif->ip_addr));\r
+  }\r
+\r
+  /* ARP message directed to us? */\r
+  if (for_us) {\r
+    /* add IP address in ARP cache; assume requester wants to talk to us.\r
+     * can result in directly sending the queued packets for this host. */\r
+    update_arp_entry(netif, &sipaddr, &(hdr->shwaddr), ETHARP_TRY_HARD);\r
+  /* ARP message not directed to us? */\r
+  } else {\r
+    /* update the source IP address in the cache, if present */\r
+    update_arp_entry(netif, &sipaddr, &(hdr->shwaddr), 0);\r
+  }\r
+\r
+  /* now act on the message itself */\r
+  switch (htons(hdr->opcode)) {\r
+  /* ARP request? */\r
+  case ARP_REQUEST:\r
+    /* ARP request. If it asked for our address, we send out a\r
+     * reply. In any case, we time-stamp any existing ARP entry,\r
+     * and possiby send out an IP packet that was queued on it. */\r
+\r
+    LWIP_DEBUGF (ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: incoming ARP request\n"));\r
+    /* ARP request for our address? */\r
+    if (for_us) {\r
+\r
+      LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: replying to ARP request for our IP address\n"));\r
+      /* re-use pbuf to send ARP reply */\r
+      hdr->opcode = htons(ARP_REPLY);\r
+\r
+      hdr->dipaddr = hdr->sipaddr;\r
+      hdr->sipaddr = *(struct ip_addr2 *)&netif->ip_addr;\r
+\r
+      for(i = 0; i < netif->hwaddr_len; ++i) {\r
+        hdr->dhwaddr.addr[i] = hdr->shwaddr.addr[i];\r
+        hdr->shwaddr.addr[i] = ethaddr->addr[i];\r
+        hdr->ethhdr.dest.addr[i] = hdr->dhwaddr.addr[i];\r
+        hdr->ethhdr.src.addr[i] = ethaddr->addr[i];\r
+      }\r
+\r
+      hdr->hwtype = htons(HWTYPE_ETHERNET);\r
+      ARPH_HWLEN_SET(hdr, netif->hwaddr_len);\r
+\r
+      hdr->proto = htons(ETHTYPE_IP);\r
+      ARPH_PROTOLEN_SET(hdr, sizeof(struct ip_addr));\r
+\r
+      hdr->ethhdr.type = htons(ETHTYPE_ARP);\r
+      /* return ARP reply */\r
+      netif->linkoutput(netif, p);\r
+    /* we are not configured? */\r
+    } else if (netif->ip_addr.addr == 0) {\r
+      /* { for_us == 0 and netif->ip_addr.addr == 0 } */\r
+      LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: we are unconfigured, ARP request ignored.\n"));\r
+    /* request was not directed to us */\r
+    } else {\r
+      /* { for_us == 0 and netif->ip_addr.addr != 0 } */\r
+      LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: ARP request was not for us.\n"));\r
+    }\r
+    break;\r
+  case ARP_REPLY:\r
+    /* ARP reply. We already updated the ARP cache earlier. */\r
+    LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: incoming ARP reply\n"));\r
+#if (LWIP_DHCP && DHCP_DOES_ARP_CHECK)\r
+    /* DHCP wants to know about ARP replies from any host with an\r
+     * IP address also offered to us by the DHCP server. We do not\r
+     * want to take a duplicate IP address on a single network.\r
+     * @todo How should we handle redundant (fail-over) interfaces?\r
+     * */\r
+    dhcp_arp_reply(netif, &sipaddr);\r
+#endif\r
+    break;\r
+  default:\r
+    LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: ARP unknown opcode type %"S16_F"\n", htons(hdr->opcode)));\r
+    break;\r
+  }\r
+  /* free ARP packet */\r
+  pbuf_free(p);\r
+}\r
+\r
+/**\r
+ * Resolve and fill-in Ethernet address header for outgoing packet.\r
+ *\r
+ * For IP multicast and broadcast, corresponding Ethernet addresses\r
+ * are selected and the packet is transmitted on the link.\r
+ *\r
+ * For unicast addresses, the packet is submitted to etharp_query(). In\r
+ * case the IP address is outside the local network, the IP address of\r
+ * the gateway is used.\r
+ *\r
+ * @param netif The lwIP network interface which the IP packet will be sent on.\r
+ * @param ipaddr The IP address of the packet destination.\r
+ * @param pbuf The pbuf(s) containing the IP packet to be sent.\r
+ *\r
+ * @return\r
+ * - ERR_RTE No route to destination (no gateway to external networks),\r
+ * or the return type of either etharp_query() or netif->linkoutput().\r
+ */\r
+err_t\r
+etharp_output(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)\r
+{\r
+  struct eth_addr *dest, *srcaddr, mcastaddr;\r
+  struct eth_hdr *ethhdr;\r
+  u8_t i;\r
+\r
+  /* make room for Ethernet header - should not fail */\r
+  if (pbuf_header(q, sizeof(struct eth_hdr)) != 0) {\r
+    /* bail out */\r
+    LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | 2, ("etharp_output: could not allocate room for header.\n"));\r
+    LINK_STATS_INC(link.lenerr);\r
+    return ERR_BUF;\r
+  }\r
+\r
+  /* assume unresolved Ethernet address */\r
+  dest = NULL;\r
+  /* Determine on destination hardware address. Broadcasts and multicasts\r
+   * are special, other IP addresses are looked up in the ARP table. */\r
+\r
+  /* broadcast destination IP address? */\r
+  if (ip_addr_isbroadcast(ipaddr, netif)) {\r
+    /* broadcast on Ethernet also */\r
+    dest = (struct eth_addr *)&ethbroadcast;\r
+  /* multicast destination IP address? */\r
+  } else if (ip_addr_ismulticast(ipaddr)) {\r
+    /* Hash IP multicast address to MAC address.*/\r
+    mcastaddr.addr[0] = 0x01;\r
+    mcastaddr.addr[1] = 0x00;\r
+    mcastaddr.addr[2] = 0x5e;\r
+    mcastaddr.addr[3] = ip4_addr2(ipaddr) & 0x7f;\r
+    mcastaddr.addr[4] = ip4_addr3(ipaddr);\r
+    mcastaddr.addr[5] = ip4_addr4(ipaddr);\r
+    /* destination Ethernet address is multicast */\r
+    dest = &mcastaddr;\r
+  /* unicast destination IP address? */\r
+  } else {\r
+    /* outside local network? */\r
+    if (!ip_addr_netcmp(ipaddr, &(netif->ip_addr), &(netif->netmask))) {\r
+      /* interface has default gateway? */\r
+      if (netif->gw.addr != 0) {\r
+        /* send to hardware address of default gateway IP address */\r
+        ipaddr = &(netif->gw);\r
+      /* no default gateway available */\r
+      } else {\r
+        /* no route to destination error (default gateway missing) */\r
+        return ERR_RTE;\r
+      }\r
+    }\r
+    /* queue on destination Ethernet address belonging to ipaddr */\r
+    return etharp_query(netif, ipaddr, q);\r
+  }\r
+\r
+  /* continuation for multicast/broadcast destinations */\r
+  /* obtain source Ethernet address of the given interface */\r
+  srcaddr = (struct eth_addr *)netif->hwaddr;\r
+  ethhdr = q->payload;\r
+  for (i = 0; i < netif->hwaddr_len; i++) {\r
+    ethhdr->dest.addr[i] = dest->addr[i];\r
+    ethhdr->src.addr[i] = srcaddr->addr[i];\r
+  }\r
+  ethhdr->type = htons(ETHTYPE_IP);\r
+  /* send packet directly on the link */\r
+  return netif->linkoutput(netif, q);\r
+}\r
+\r
+/**\r
+ * Send an ARP request for the given IP address and/or queue a packet.\r
+ *\r
+ * If the IP address was not yet in the cache, a pending ARP cache entry\r
+ * is added and an ARP request is sent for the given address. The packet\r
+ * is queued on this entry.\r
+ *\r
+ * If the IP address was already pending in the cache, a new ARP request\r
+ * is sent for the given address. The packet is queued on this entry.\r
+ *\r
+ * If the IP address was already stable in the cache, and a packet is\r
+ * given, it is directly sent and no ARP request is sent out. \r
+ * \r
+ * If the IP address was already stable in the cache, and no packet is\r
+ * given, an ARP request is sent out.\r
+ * \r
+ * @param netif The lwIP network interface on which ipaddr\r
+ * must be queried for.\r
+ * @param ipaddr The IP address to be resolved.\r
+ * @param q If non-NULL, a pbuf that must be delivered to the IP address.\r
+ * q is not freed by this function.\r
+ *\r
+ * @return\r
+ * - ERR_BUF Could not make room for Ethernet header.\r
+ * - ERR_MEM Hardware address unknown, and no more ARP entries available\r
+ *   to query for address or queue the packet.\r
+ * - ERR_MEM Could not queue packet due to memory shortage.\r
+ * - ERR_RTE No route to destination (no gateway to external networks).\r
+ * - ERR_ARG Non-unicast address given, those will not appear in ARP cache.\r
+ *\r
+ */\r
+err_t etharp_query(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)\r
+{\r
+  struct eth_addr * srcaddr = (struct eth_addr *)netif->hwaddr;\r
+  err_t result = ERR_MEM;\r
+  s8_t i; /* ARP entry index */\r
+  u8_t k; /* Ethernet address octet index */\r
+\r
+  /* non-unicast address? */\r
+  if (ip_addr_isbroadcast(ipaddr, netif) ||\r
+      ip_addr_ismulticast(ipaddr) ||\r
+      ip_addr_isany(ipaddr)) {\r
+    LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_query: will not add non-unicast IP address to ARP cache\n"));\r
+    return ERR_ARG;\r
+  }\r
+\r
+  /* find entry in ARP cache, ask to create entry if queueing packet */\r
+  i = find_entry(ipaddr, ETHARP_TRY_HARD);\r
+\r
+  /* could not find or create entry? */\r
+  if (i < 0)\r
+  {\r
+    LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_query: could not create ARP entry\n"));\r
+    if (q) LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_query: packet dropped\n"));\r
+    return (err_t)i;\r
+  }\r
+\r
+  /* mark a fresh entry as pending (we just sent a request) */\r
+  if (arp_table[i].state == ETHARP_STATE_EMPTY) {\r
+    arp_table[i].state = ETHARP_STATE_PENDING;\r
+  }\r
+\r
+  /* { i is either a STABLE or (new or existing) PENDING entry } */\r
+  LWIP_ASSERT("arp_table[i].state == PENDING or STABLE",\r
+  ((arp_table[i].state == ETHARP_STATE_PENDING) ||\r
+   (arp_table[i].state == ETHARP_STATE_STABLE)));\r
+\r
+  /* do we have a pending entry? or an implicit query request? */\r
+  if ((arp_table[i].state == ETHARP_STATE_PENDING) || (q == NULL)) {\r
+    /* try to resolve it; send out ARP request */\r
+    result = etharp_request(netif, ipaddr);\r
+  }\r
+  \r
+  /* packet given? */\r
+  if (q != NULL) {\r
+    /* stable entry? */\r
+    if (arp_table[i].state == ETHARP_STATE_STABLE) {\r
+      /* we have a valid IP->Ethernet address mapping,\r
+       * fill in the Ethernet header for the outgoing packet */\r
+      struct eth_hdr *ethhdr = q->payload;\r
+      for(k = 0; k < netif->hwaddr_len; k++) {\r
+        ethhdr->dest.addr[k] = arp_table[i].ethaddr.addr[k];\r
+        ethhdr->src.addr[k]  = srcaddr->addr[k];\r
+      }\r
+      ethhdr->type = htons(ETHTYPE_IP);\r
+      LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_query: sending packet %p\n", (void *)q));\r
+      /* send the packet */\r
+      result = netif->linkoutput(netif, q);\r
+    /* pending entry? (either just created or already pending */\r
+    } else if (arp_table[i].state == ETHARP_STATE_PENDING) {\r
+#if ARP_QUEUEING /* queue the given q packet */\r
+      struct pbuf *p;\r
+      /* copy any PBUF_REF referenced payloads into PBUF_RAM */\r
+      /* (the caller of lwIP assumes the referenced payload can be\r
+       * freed after it returns from the lwIP call that brought us here) */\r
+      p = pbuf_take(q);\r
+      /* packet could be taken over? */\r
+      if (p != NULL) {\r
+        /* queue packet ... */\r
+        if (arp_table[i].p == NULL) {\r
+               /* ... in the empty queue */\r
+               pbuf_ref(p);\r
+               arp_table[i].p = p;\r
+#if 0 /* multi-packet-queueing disabled, see bug #11400 */\r
+        } else {\r
+               /* ... at tail of non-empty queue */\r
+          pbuf_queue(arp_table[i].p, p);\r
+#endif\r
+        }\r
+        LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_query: queued packet %p on ARP entry %"S16_F"\n", (void *)q, (s16_t)i));\r
+        result = ERR_OK;\r
+      } else {\r
+        LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_query: could not queue a copy of PBUF_REF packet %p (out of memory)\n", (void *)q));\r
+        /* { result == ERR_MEM } through initialization */\r
+      }\r
+#else /* ARP_QUEUEING == 0 */\r
+      /* q && state == PENDING && ARP_QUEUEING == 0 => result = ERR_MEM */\r
+      /* { result == ERR_MEM } through initialization */\r
+      LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_query: Ethernet destination address unknown, queueing disabled, packet %p dropped\n", (void *)q));\r
+#endif\r
+    }\r
+  }\r
+  return result;\r
+}\r
+\r
+err_t etharp_request(struct netif *netif, struct ip_addr *ipaddr)\r
+{\r
+  struct pbuf *p;\r
+  struct eth_addr * srcaddr = (struct eth_addr *)netif->hwaddr;\r
+  err_t result = ERR_OK;\r
+  u8_t k; /* ARP entry index */\r
+\r
+  /* allocate a pbuf for the outgoing ARP request packet */\r
+  p = pbuf_alloc(PBUF_LINK, sizeof(struct etharp_hdr), PBUF_RAM);\r
+  /* could allocate a pbuf for an ARP request? */\r
+  if (p != NULL) {\r
+    struct etharp_hdr *hdr = p->payload;\r
+    LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_request: sending ARP request.\n"));\r
+    hdr->opcode = htons(ARP_REQUEST);\r
+    for (k = 0; k < netif->hwaddr_len; k++)\r
+    {\r
+      hdr->shwaddr.addr[k] = srcaddr->addr[k];\r
+      /* the hardware address is what we ask for, in\r
+       * a request it is a don't-care value, we use zeroes */\r
+      hdr->dhwaddr.addr[k] = 0x00;\r
+    }\r
+    hdr->dipaddr = *(struct ip_addr2 *)ipaddr;\r
+    hdr->sipaddr = *(struct ip_addr2 *)&netif->ip_addr;\r
+\r
+    hdr->hwtype = htons(HWTYPE_ETHERNET);\r
+    ARPH_HWLEN_SET(hdr, netif->hwaddr_len);\r
+\r
+    hdr->proto = htons(ETHTYPE_IP);\r
+    ARPH_PROTOLEN_SET(hdr, sizeof(struct ip_addr));\r
+    for (k = 0; k < netif->hwaddr_len; ++k)\r
+    {\r
+      /* broadcast to all network interfaces on the local network */\r
+      hdr->ethhdr.dest.addr[k] = 0xff;\r
+      hdr->ethhdr.src.addr[k] = srcaddr->addr[k];\r
+    }\r
+    hdr->ethhdr.type = htons(ETHTYPE_ARP);\r
+    /* send ARP query */\r
+    result = netif->linkoutput(netif, p);\r
+    /* free ARP query packet */\r
+    pbuf_free(p);\r
+    p = NULL;\r
+  /* could not allocate pbuf for ARP request */\r
+  } else {\r
+    result = ERR_MEM;\r
+    LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | 2, ("etharp_request: could not allocate pbuf for ARP request.\n"));\r
+  }\r
+  return result;\r
+}\r
index 0c14e8de53734b61d8636639131011d61df49b59..3d93fe1e8c23c0d92dc3c9a9f56ba2cde933a58f 100644 (file)
-/*
- * 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 <adam@sics.se>
- *
- */
-
-/*
- * This file is a skeleton for developing Ethernet network interface
- * drivers for lwIP. Add code to the low_level functions and do a
- * search-and-replace for the word "ethernetif" to replace it with
- * something that better describes your network interface.
- */
-
-#include "lwip/opt.h"
-#include "lwip/def.h"
-#include "lwip/mem.h"
-#include "lwip/pbuf.h"
-#include "lwip/sys.h"
-#include <lwip/stats.h>
-
-#include "netif/etharp.h"
-
-/* Define those to better describe your network interface. */
-#define IFNAME0 'e'
-#define IFNAME1 'n'
-
-struct ethernetif {
-  struct eth_addr *ethaddr;
-  /* Add whatever per-interface state that is needed here. */
-};
-
-static const struct eth_addr ethbroadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}};
-
-/* Forward declarations. */
-static void  ethernetif_input(struct netif *netif);
-static err_t ethernetif_output(struct netif *netif, struct pbuf *p,
-             struct ip_addr *ipaddr);
-
-static void
-low_level_init(struct netif *netif)
-{
-  struct ethernetif *ethernetif = netif->state;
-  
-  /* set MAC hardware address length */
-  netif->hwaddr_len = 6;
-
-  /* set MAC hardware address */
-  netif->hwaddr[0] = ;
-  ...
-  netif->hwaddr[5] = ;
-
-  /* maximum transfer unit */
-  netif->mtu = 1500;
-  
-  /* broadcast capability */
-  netif->flags = NETIF_FLAG_BROADCAST;
-  /* Do whatever else is needed to initialize interface. */  
-}
-
-/*
- * low_level_output():
- *
- * Should do the actual transmission of the packet. The packet is
- * contained in the pbuf that is passed to the function. This pbuf
- * might be chained.
- *
- */
-
-static err_t
-low_level_output(struct netif *netif, struct pbuf *p)
-{
-  struct ethernetif *ethernetif = netif->state;
-  struct pbuf *q;
-
-  initiate transfer();
-  
-#if ETH_PAD_SIZE
-  pbuf_header(p, -ETH_PAD_SIZE);                       /* drop the padding word */
-#endif
-
-  for(q = p; q != NULL; q = q->next) {
-    /* Send the data from the pbuf to the interface, one pbuf at a
-       time. The size of the data in each pbuf is kept in the ->len
-       variable. */
-    send data from(q->payload, q->len);
-  }
-
-  signal that packet should be sent();
-
-#if ETH_PAD_SIZE
-  pbuf_header(p, ETH_PAD_SIZE);                        /* reclaim the padding word */
-#endif
-  
-#if LINK_STATS
-  lwip_stats.link.xmit++;
-#endif /* LINK_STATS */      
-
-  return ERR_OK;
-}
-
-/*
- * low_level_input():
- *
- * Should allocate a pbuf and transfer the bytes of the incoming
- * packet from the interface into the pbuf.
- *
- */
-
-static struct pbuf *
-low_level_input(struct netif *netif)
-{
-  struct ethernetif *ethernetif = netif->state;
-  struct pbuf *p, *q;
-  u16_t len;
-
-  /* Obtain the size of the packet and put it into the "len"
-     variable. */
-  len = ;
-
-#if ETH_PAD_SIZE
-  len += ETH_PAD_SIZE;                                         /* allow room for Ethernet padding */
-#endif
-
-  /* We allocate a pbuf chain of pbufs from the pool. */
-  p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
-  
-  if (p != NULL) {
-
-#if ETH_PAD_SIZE
-    pbuf_header(p, -ETH_PAD_SIZE);                     /* drop the padding word */
-#endif
-
-    /* We iterate over the pbuf chain until we have read the entire
-     * packet into the pbuf. */
-    for(q = p; q != NULL; q = q->next) {
-      /* Read enough bytes to fill this pbuf in the chain. The
-       * available data in the pbuf is given by the q->len
-       * variable. */
-      read data into(q->payload, q->len);
-    }
-    acknowledge that packet has been read();
-
-#if ETH_PAD_SIZE
-    pbuf_header(p, ETH_PAD_SIZE);                      /* reclaim the padding word */
-#endif
-
-#if LINK_STATS
-    lwip_stats.link.recv++;
-#endif /* LINK_STATS */      
-  } else {
-    drop packet();
-#if LINK_STATS
-    lwip_stats.link.memerr++;
-    lwip_stats.link.drop++;
-#endif /* LINK_STATS */      
-  }
-
-  return p;  
-}
-
-/*
- * ethernetif_output():
- *
- * This function is called by the TCP/IP stack when an IP packet
- * should be sent. It calls the function called low_level_output() to
- * do the actual transmission of the packet.
- *
- */
-
-static err_t
-ethernetif_output(struct netif *netif, struct pbuf *p,
-      struct ip_addr *ipaddr)
-{
-  
- /* resolve hardware address, then send (or queue) packet */
-  return etharp_output(netif, ipaddr, p);
-}
-
-/*
- * ethernetif_input():
- *
- * This function should be called when a packet is ready to be read
- * from the interface. It uses the function low_level_input() that
- * should handle the actual reception of bytes from the network
- * interface.
- *
- */
-
-static void
-ethernetif_input(struct netif *netif)
-{
-  struct ethernetif *ethernetif;
-  struct eth_hdr *ethhdr;
-  struct pbuf *p;
-
-  ethernetif = netif->state;
-  
-  /* move received packet into a new pbuf */
-  p = low_level_input(netif);
-  /* no packet could be read, silently ignore this */
-  if (p == NULL) return;
-  /* points to packet payload, which starts with an Ethernet header */
-  ethhdr = p->payload;
-
-#if LINK_STATS
-  lwip_stats.link.recv++;
-#endif /* LINK_STATS */
-
-  ethhdr = p->payload;
-    
-  switch (htons(ethhdr->type)) {
-  /* IP packet? */
-  case ETHTYPE_IP:
-    /* update ARP table */
-    etharp_ip_input(netif, p);
-    /* skip Ethernet header */
-    pbuf_header(p, -sizeof(struct eth_hdr));
-    /* pass to network layer */
-    netif->input(p, netif);
-    break;
-      
-    case ETHTYPE_ARP:
-      /* pass p to ARP module  */
-      etharp_arp_input(netif, ethernetif->ethaddr, p);
-      break;
-    default:
-      pbuf_free(p);
-      p = NULL;
-      break;
-  }
-}
-
-static void
-arp_timer(void *arg)
-{
-  etharp_tmr();
-  sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL);
-}
-
-/*
- * ethernetif_init():
- *
- * Should be called at the beginning of the program to set up the
- * network interface. It calls the function low_level_init() to do the
- * actual setup of the hardware.
- *
- */
-
-err_t
-ethernetif_init(struct netif *netif)
-{
-  struct ethernetif *ethernetif;
-    
-  ethernetif = mem_malloc(sizeof(struct ethernetif));
-  
-  if (ethernetif == NULL)
-  {
-       LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_init: out of memory\n"));
-       return ERR_MEM;
-  }
-  
-  netif->state = ethernetif;
-  netif->name[0] = IFNAME0;
-  netif->name[1] = IFNAME1;
-  netif->output = ethernetif_output;
-  netif->linkoutput = low_level_output;
-  
-  ethernetif->ethaddr = (struct eth_addr *)&(netif->hwaddr[0]);
-  
-  low_level_init(netif);
-
-  etharp_init();
-
-  sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL);
-
-  return ERR_OK;
-}
-
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+\r
+/*\r
+ * This file is a skeleton for developing Ethernet network interface\r
+ * drivers for lwIP. Add code to the low_level functions and do a\r
+ * search-and-replace for the word "ethernetif" to replace it with\r
+ * something that better describes your network interface.\r
+ */\r
+\r
+#include "lwip/opt.h"\r
+#include "lwip/def.h"\r
+#include "lwip/mem.h"\r
+#include "lwip/pbuf.h"\r
+#include "lwip/sys.h"\r
+#include <lwip/stats.h>\r
+\r
+#include "netif/etharp.h"\r
+\r
+/* Define those to better describe your network interface. */\r
+#define IFNAME0 'e'\r
+#define IFNAME1 'n'\r
+\r
+struct ethernetif {\r
+  struct eth_addr *ethaddr;\r
+  /* Add whatever per-interface state that is needed here. */\r
+};\r
+\r
+static const struct eth_addr ethbroadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}};\r
+\r
+/* Forward declarations. */\r
+static void  ethernetif_input(struct netif *netif);\r
+static err_t ethernetif_output(struct netif *netif, struct pbuf *p,\r
+             struct ip_addr *ipaddr);\r
+\r
+static void\r
+low_level_init(struct netif *netif)\r
+{\r
+  struct ethernetif *ethernetif = netif->state;\r
+  \r
+  /* set MAC hardware address length */\r
+  netif->hwaddr_len = 6;\r
+\r
+  /* set MAC hardware address */\r
+  netif->hwaddr[0] = ;\r
+  ...\r
+  netif->hwaddr[5] = ;\r
+\r
+  /* maximum transfer unit */\r
+  netif->mtu = 1500;\r
+  \r
+  /* broadcast capability */\r
+  netif->flags = NETIF_FLAG_BROADCAST;\r
\r
+  /* Do whatever else is needed to initialize interface. */  \r
+}\r
+\r
+/*\r
+ * low_level_output():\r
+ *\r
+ * Should do the actual transmission of the packet. The packet is\r
+ * contained in the pbuf that is passed to the function. This pbuf\r
+ * might be chained.\r
+ *\r
+ */\r
+\r
+static err_t\r
+low_level_output(struct netif *netif, struct pbuf *p)\r
+{\r
+  struct ethernetif *ethernetif = netif->state;\r
+  struct pbuf *q;\r
+\r
+  initiate transfer();\r
+  \r
+#if ETH_PAD_SIZE\r
+  pbuf_header(p, -ETH_PAD_SIZE);                       /* drop the padding word */\r
+#endif\r
+\r
+  for(q = p; q != NULL; q = q->next) {\r
+    /* Send the data from the pbuf to the interface, one pbuf at a\r
+       time. The size of the data in each pbuf is kept in the ->len\r
+       variable. */\r
+    send data from(q->payload, q->len);\r
+  }\r
+\r
+  signal that packet should be sent();\r
+\r
+#if ETH_PAD_SIZE\r
+  pbuf_header(p, ETH_PAD_SIZE);                        /* reclaim the padding word */\r
+#endif\r
+  \r
+#if LINK_STATS\r
+  lwip_stats.link.xmit++;\r
+#endif /* LINK_STATS */      \r
+\r
+  return ERR_OK;\r
+}\r
+\r
+/*\r
+ * low_level_input():\r
+ *\r
+ * Should allocate a pbuf and transfer the bytes of the incoming\r
+ * packet from the interface into the pbuf.\r
+ *\r
+ */\r
+\r
+static struct pbuf *\r
+low_level_input(struct netif *netif)\r
+{\r
+  struct ethernetif *ethernetif = netif->state;\r
+  struct pbuf *p, *q;\r
+  u16_t len;\r
+\r
+  /* Obtain the size of the packet and put it into the "len"\r
+     variable. */\r
+  len = ;\r
+\r
+#if ETH_PAD_SIZE\r
+  len += ETH_PAD_SIZE;                                         /* allow room for Ethernet padding */\r
+#endif\r
+\r
+  /* We allocate a pbuf chain of pbufs from the pool. */\r
+  p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);\r
+  \r
+  if (p != NULL) {\r
+\r
+#if ETH_PAD_SIZE\r
+    pbuf_header(p, -ETH_PAD_SIZE);                     /* drop the padding word */\r
+#endif\r
+\r
+    /* We iterate over the pbuf chain until we have read the entire\r
+     * packet into the pbuf. */\r
+    for(q = p; q != NULL; q = q->next) {\r
+      /* Read enough bytes to fill this pbuf in the chain. The\r
+       * available data in the pbuf is given by the q->len\r
+       * variable. */\r
+      read data into(q->payload, q->len);\r
+    }\r
+    acknowledge that packet has been read();\r
+\r
+#if ETH_PAD_SIZE\r
+    pbuf_header(p, ETH_PAD_SIZE);                      /* reclaim the padding word */\r
+#endif\r
+\r
+#if LINK_STATS\r
+    lwip_stats.link.recv++;\r
+#endif /* LINK_STATS */      \r
+  } else {\r
+    drop packet();\r
+#if LINK_STATS\r
+    lwip_stats.link.memerr++;\r
+    lwip_stats.link.drop++;\r
+#endif /* LINK_STATS */      \r
+  }\r
+\r
+  return p;  \r
+}\r
+\r
+/*\r
+ * ethernetif_output():\r
+ *\r
+ * This function is called by the TCP/IP stack when an IP packet\r
+ * should be sent. It calls the function called low_level_output() to\r
+ * do the actual transmission of the packet.\r
+ *\r
+ */\r
+\r
+static err_t\r
+ethernetif_output(struct netif *netif, struct pbuf *p,\r
+      struct ip_addr *ipaddr)\r
+{\r
+  \r
+ /* resolve hardware address, then send (or queue) packet */\r
+  return etharp_output(netif, ipaddr, p);\r
\r
+}\r
+\r
+/*\r
+ * ethernetif_input():\r
+ *\r
+ * This function should be called when a packet is ready to be read\r
+ * from the interface. It uses the function low_level_input() that\r
+ * should handle the actual reception of bytes from the network\r
+ * interface.\r
+ *\r
+ */\r
+\r
+static void\r
+ethernetif_input(struct netif *netif)\r
+{\r
+  struct ethernetif *ethernetif;\r
+  struct eth_hdr *ethhdr;\r
+  struct pbuf *p;\r
+\r
+  ethernetif = netif->state;\r
+  \r
+  /* move received packet into a new pbuf */\r
+  p = low_level_input(netif);\r
+  /* no packet could be read, silently ignore this */\r
+  if (p == NULL) return;\r
+  /* points to packet payload, which starts with an Ethernet header */\r
+  ethhdr = p->payload;\r
+\r
+#if LINK_STATS\r
+  lwip_stats.link.recv++;\r
+#endif /* LINK_STATS */\r
+\r
+  ethhdr = p->payload;\r
+    \r
+  switch (htons(ethhdr->type)) {\r
+  /* IP packet? */\r
+  case ETHTYPE_IP:\r
+    /* update ARP table */\r
+    etharp_ip_input(netif, p);\r
+    /* skip Ethernet header */\r
+    pbuf_header(p, -sizeof(struct eth_hdr));\r
+    /* pass to network layer */\r
+    netif->input(p, netif);\r
+    break;\r
+      \r
+    case ETHTYPE_ARP:\r
+      /* pass p to ARP module  */\r
+      etharp_arp_input(netif, ethernetif->ethaddr, p);\r
+      break;\r
+    default:\r
+      pbuf_free(p);\r
+      p = NULL;\r
+      break;\r
+  }\r
+}\r
+\r
+static void\r
+arp_timer(void *arg)\r
+{\r
+  etharp_tmr();\r
+  sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL);\r
+}\r
+\r
+/*\r
+ * ethernetif_init():\r
+ *\r
+ * Should be called at the beginning of the program to set up the\r
+ * network interface. It calls the function low_level_init() to do the\r
+ * actual setup of the hardware.\r
+ *\r
+ */\r
+\r
+err_t\r
+ethernetif_init(struct netif *netif)\r
+{\r
+  struct ethernetif *ethernetif;\r
+    \r
+  ethernetif = mem_malloc(sizeof(struct ethernetif));\r
+  \r
+  if (ethernetif == NULL)\r
+  {\r
+       LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_init: out of memory\n"));\r
+       return ERR_MEM;\r
+  }\r
+  \r
+  netif->state = ethernetif;\r
+  netif->name[0] = IFNAME0;\r
+  netif->name[1] = IFNAME1;\r
+  netif->output = ethernetif_output;\r
+  netif->linkoutput = low_level_output;\r
+  \r
+  ethernetif->ethaddr = (struct eth_addr *)&(netif->hwaddr[0]);\r
+  \r
+  low_level_init(netif);\r
+\r
+  etharp_init();\r
+\r
+  sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL);\r
+\r
+  return ERR_OK;\r
+}\r
+\r
index 0464cb8e80b6934ab451670f2f3a1aa18a97f069..cd523fb034b04c53601409f739e69a79217f1643 100644 (file)
-/*
- * 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 <adam@sics.se>
- *
- */
-#include "lwip/opt.h"
-
-#if LWIP_HAVE_LOOPIF
-
-#include "netif/loopif.h"
-#include "lwip/mem.h"
-
-#if defined(LWIP_DEBUG) && defined(LWIP_TCPDUMP)
-#include "netif/tcpdump.h"
-#endif /* LWIP_DEBUG && LWIP_TCPDUMP */
-
-#include "lwip/tcp.h"
-#include "lwip/ip.h"
-
-static void
-loopif_input( void * arg )
-{
-       struct netif *netif = (struct netif *)( ((void **)arg)[ 0 ] );
-       struct pbuf *r = (struct pbuf *)( ((void **)arg)[ 1 ] );
-
-       mem_free( arg );
-       netif -> input( r, netif );
-}
-
-static err_t
-loopif_output(struct netif *netif, struct pbuf *p,
-       struct ip_addr *ipaddr)
-{
-  struct pbuf *q, *r;
-  u8_t *ptr;
-  void **arg;
-
-#if defined(LWIP_DEBUG) && defined(LWIP_TCPDUMP)
-  tcpdump(p);
-#endif /* LWIP_DEBUG && LWIP_TCPDUMP */
-  
-  r = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM);
-  if (r != NULL) {
-    ptr = r->payload;
-    
-    for(q = p; q != NULL; q = q->next) {
-      memcpy(ptr, q->payload, q->len);
-      ptr += q->len;
-    }
-
-    arg = mem_malloc( sizeof( void *[2]));
-       if( NULL == arg ) {
-               return ERR_MEM;
-       }
-       
-       arg[0] = netif;
-       arg[1] = r;
-       /**
-        * workaround (patch #1779) to try to prevent bug #2595:
-        * When connecting to "localhost" with the loopif interface,
-        * tcp_output doesn't get the opportunity to finnish sending the
-        * segment before tcp_process gets it, resulting in tcp_process
-        * referencing pcb->unacked-> which still is NULL.
-        * 
-        * TODO: Is there still a race condition here? Leon
-        */
-       sys_timeout( 1, loopif_input, arg );
-       
-    return ERR_OK;    
-  }
-  return ERR_MEM;
-}
-
-err_t
-loopif_init(struct netif *netif)
-{
-  netif->name[0] = 'l';
-  netif->name[1] = 'o';
-#if 0 /** TODO: I think this should be enabled, or not? Leon */
-  netif->input = loopif_input;
-#endif
-  netif->output = loopif_output;
-  return ERR_OK;
-}
-
-#endif /* LWIP_HAVE_LOOPIF */
-
-
-
-
-
-
-
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification, \r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED \r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT \r
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \r
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY \r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ * \r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ */\r
+#include "lwip/opt.h"\r
+\r
+#if LWIP_HAVE_LOOPIF\r
+\r
+#include "netif/loopif.h"\r
+#include "lwip/mem.h"\r
+\r
+#if defined(LWIP_DEBUG) && defined(LWIP_TCPDUMP)\r
+#include "netif/tcpdump.h"\r
+#endif /* LWIP_DEBUG && LWIP_TCPDUMP */\r
+\r
+#include "lwip/tcp.h"\r
+#include "lwip/ip.h"\r
+\r
+static void\r
+loopif_input( void * arg )\r
+{\r
+       struct netif *netif = (struct netif *)( ((void **)arg)[ 0 ] );\r
+       struct pbuf *r = (struct pbuf *)( ((void **)arg)[ 1 ] );\r
+\r
+       mem_free( arg );\r
+       netif -> input( r, netif );\r
+}\r
+\r
+static err_t\r
+loopif_output(struct netif *netif, struct pbuf *p,\r
+       struct ip_addr *ipaddr)\r
+{\r
+  struct pbuf *q, *r;\r
+  u8_t *ptr;\r
+  void **arg;\r
+\r
+#if defined(LWIP_DEBUG) && defined(LWIP_TCPDUMP)\r
+  tcpdump(p);\r
+#endif /* LWIP_DEBUG && LWIP_TCPDUMP */\r
+  \r
+  r = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM);\r
+  if (r != NULL) {\r
+    ptr = r->payload;\r
+    \r
+    for(q = p; q != NULL; q = q->next) {\r
+      memcpy(ptr, q->payload, q->len);\r
+      ptr += q->len;\r
+    }\r
+\r
+    arg = mem_malloc( sizeof( void *[2]));\r
+       if( NULL == arg ) {\r
+               return ERR_MEM;\r
+       }\r
+       \r
+       arg[0] = netif;\r
+       arg[1] = r;\r
+       /**\r
+        * workaround (patch #1779) to try to prevent bug #2595:\r
+        * When connecting to "localhost" with the loopif interface,\r
+        * tcp_output doesn't get the opportunity to finnish sending the\r
+        * segment before tcp_process gets it, resulting in tcp_process\r
+        * referencing pcb->unacked-> which still is NULL.\r
+        * \r
+        * TODO: Is there still a race condition here? Leon\r
+        */\r
+       sys_timeout( 1, loopif_input, arg );\r
+       \r
+    return ERR_OK;    \r
+  }\r
+  return ERR_MEM;\r
+}\r
+\r
+err_t\r
+loopif_init(struct netif *netif)\r
+{\r
+  netif->name[0] = 'l';\r
+  netif->name[1] = 'o';\r
+#if 0 /** TODO: I think this should be enabled, or not? Leon */\r
+  netif->input = loopif_input;\r
+#endif\r
+  netif->output = loopif_output;\r
+  return ERR_OK;\r
+}\r
+\r
+#endif /* LWIP_HAVE_LOOPIF */\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
index 33349640223faa403d5428769cd757619300d80b..0786a2e81cf9a04537939e75d73a8ce44af5371e 100644 (file)
-/*****************************************************************************
-* auth.c - Network Authentication and Phase Control program file.
-*
-* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
-* Copyright (c) 1997 by Global Election Systems Inc.  All rights reserved.
-*
-* The authors hereby grant permission to use, copy, modify, distribute,
-* and license this software and its documentation for any purpose, provided
-* that existing copyright notices are retained in all copies and that this
-* notice and the following disclaimer are included verbatim in any 
-* distributions. No written agreement, license, or royalty fee is required
-* for any of the authorized uses.
-*
-* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *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 CONTRIBUTORS 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.
-*
-******************************************************************************
-* REVISION HISTORY
-*
-* 03-01-01 Marc Boucher <marc@mbsi.ca>
-*   Ported to lwIP.
-* 97-12-08 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
-*   Ported from public pppd code.
-*****************************************************************************/
-/*
- * auth.c - PPP authentication and phase control.
- *
- * Copyright (c) 1993 The Australian National University.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the Australian National University.  The name of the University
- * may not be used to endorse or promote products derived from this
- * software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Copyright (c) 1989 Carnegie Mellon University.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by Carnegie Mellon University.  The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include "ppp.h"
-#if PPP_SUPPORT > 0
-#include "fsm.h"
-#include "lcp.h"
-#include "pap.h"
-#include "chap.h"
-#include "auth.h"
-#include "ipcp.h"
-
-#if CBCP_SUPPORT > 0
-#include "cbcp.h"
-#endif
-
-#include "pppdebug.h"
-
-
-/*************************/
-/*** LOCAL DEFINITIONS ***/
-/*************************/
-
-/* Bits in auth_pending[] */
-#define PAP_WITHPEER    1
-#define PAP_PEER    2
-#define CHAP_WITHPEER   4
-#define CHAP_PEER   8
-
-
-                                                                    
-/************************/
-/*** LOCAL DATA TYPES ***/
-/************************/
-/* Used for storing a sequence of words.  Usually malloced. */
-struct wordlist {
-    struct wordlist *next;
-    char        word[1];
-};
-
-
-
-/***********************************/
-/*** LOCAL FUNCTION DECLARATIONS ***/
-/***********************************/
-extern char *crypt (const char *, const char *);
-
-/* Prototypes for procedures local to this file. */
-
-static void network_phase (int);
-static void check_idle (void *);
-static void connect_time_expired (void *);
-#if 0
-static int  login (char *, char *, char **, int *);
-#endif
-static void logout (void);
-static int  null_login (int);
-static int  get_pap_passwd (int, char *, char *);
-static int  have_pap_secret (void);
-static int  have_chap_secret (char *, char *, u32_t);
-static int  ip_addr_check (u32_t, struct wordlist *);
-#if 0 /* PAP_SUPPORT > 0 || CHAP_SUPPORT > 0 */
-static void set_allowed_addrs(int unit, struct wordlist *addrs);
-static void free_wordlist (struct wordlist *);
-#endif
-#if CBCP_SUPPORT > 0
-static void callback_phase (int);
-#endif
-
-
-/******************************/
-/*** PUBLIC DATA STRUCTURES ***/
-/******************************/
-
-
-/*****************************/
-/*** LOCAL DATA STRUCTURES ***/
-/*****************************/
-#if PAP_SUPPORT > 0 || CHAP_SUPPORT > 0
-/* The name by which the peer authenticated itself to us. */
-static char peer_authname[MAXNAMELEN];
-#endif
-
-/* Records which authentication operations haven't completed yet. */
-static int auth_pending[NUM_PPP];
-
-/* Set if we have successfully called login() */
-static int logged_in;
-
-/* Set if we have run the /etc/ppp/auth-up script. */
-static int did_authup;
-
-/* List of addresses which the peer may use. */
-static struct wordlist *addresses[NUM_PPP];
-
-/* Number of network protocols which we have opened. */
-static int num_np_open;
-
-/* Number of network protocols which have come up. */
-static int num_np_up;
-
-#if PAP_SUPPORT > 0 || CHAP_SUPPORT > 0
-/* Set if we got the contents of passwd[] from the pap-secrets file. */
-static int passwd_from_file;
-#endif
-
-
-
-/***********************************/
-/*** PUBLIC FUNCTION DEFINITIONS ***/
-/***********************************/
-/*
- * An Open on LCP has requested a change from Dead to Establish phase.
- * Do what's necessary to bring the physical layer up.
- */
-void link_required(int unit)
-{
-    AUTHDEBUG((LOG_INFO, "link_required: %d\n", unit));
-}
-
-/*
- * LCP has terminated the link; go to the Dead phase and take the
- * physical layer down.
- */
-void link_terminated(int unit)
-{
-    AUTHDEBUG((LOG_INFO, "link_terminated: %d\n", unit));
-    
-    if (lcp_phase[unit] == PHASE_DEAD)
-        return;
-    if (logged_in)
-        logout();
-    lcp_phase[unit] = PHASE_DEAD;
-    AUTHDEBUG((LOG_NOTICE, "Connection terminated.\n"));
-       pppMainWakeup(unit);
-}
-
-/*
- * LCP has gone down; it will either die or try to re-establish.
- */
-void link_down(int unit)
-{
-    int i;
-    struct protent *protp;
-    
-    AUTHDEBUG((LOG_INFO, "link_down: %d\n", unit));
-    if (did_authup) {
-        /* XXX Do link down processing. */
-        did_authup = 0;
-    }
-    for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i) {
-        if (!protp->enabled_flag)
-            continue;
-        if (protp->protocol != PPP_LCP && protp->lowerdown != NULL)
-            (*protp->lowerdown)(unit);
-        if (protp->protocol < 0xC000 && protp->close != NULL)
-            (*protp->close)(unit, "LCP down");
-    }
-    num_np_open = 0;
-    num_np_up = 0;
-    if (lcp_phase[unit] != PHASE_DEAD)
-        lcp_phase[unit] = PHASE_TERMINATE;
-       pppMainWakeup(unit);
-}
-
-/*
- * The link is established.
- * Proceed to the Dead, Authenticate or Network phase as appropriate.
- */
-void link_established(int unit)
-{
-    int auth;
-    int i;
-    struct protent *protp;
-    lcp_options *wo = &lcp_wantoptions[unit];
-    lcp_options *go = &lcp_gotoptions[unit];
-#if PAP_SUPPORT > 0 || CHAP_SUPPORT > 0
-    lcp_options *ho = &lcp_hisoptions[unit];
-#endif
-    
-    AUTHDEBUG((LOG_INFO, "link_established: %d\n", unit));
-    /*
-     * Tell higher-level protocols that LCP is up.
-     */
-    for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i)
-        if (protp->protocol != PPP_LCP && protp->enabled_flag
-                && protp->lowerup != NULL)
-            (*protp->lowerup)(unit);
-    
-    if (ppp_settings.auth_required && !(go->neg_chap || go->neg_upap)) {
-        /*
-         * We wanted the peer to authenticate itself, and it refused:
-         * treat it as though it authenticated with PAP using a username
-         * of "" and a password of "".  If that's not OK, boot it out.
-         */
-        if (!wo->neg_upap || !null_login(unit)) {
-            AUTHDEBUG((LOG_WARNING, "peer refused to authenticate\n"));
-            lcp_close(unit, "peer refused to authenticate");
-            return;
-        }
-    }
-    
-    lcp_phase[unit] = PHASE_AUTHENTICATE;
-    auth = 0;
-#if CHAP_SUPPORT > 0
-    if (go->neg_chap) {
-        ChapAuthPeer(unit, ppp_settings.our_name, go->chap_mdtype);
-        auth |= CHAP_PEER;
-    } 
-#endif
-#if PAP_SUPPORT > 0 && CHAP_SUPPORT > 0
-    else
-#endif
-#if PAP_SUPPORT > 0
-    if (go->neg_upap) {
-        upap_authpeer(unit);
-        auth |= PAP_PEER;
-    }
-#endif
-#if CHAP_SUPPORT > 0
-    if (ho->neg_chap) {
-        ChapAuthWithPeer(unit, ppp_settings.user, ho->chap_mdtype);
-        auth |= CHAP_WITHPEER;
-    }
-#endif
-#if PAP_SUPPORT > 0 && CHAP_SUPPORT > 0
-    else
-#endif
-#if PAP_SUPPORT > 0
-    if (ho->neg_upap) {
-        if (ppp_settings.passwd[0] == 0) {
-            passwd_from_file = 1;
-            if (!get_pap_passwd(unit, ppp_settings.user, ppp_settings.passwd))
-                AUTHDEBUG((LOG_ERR, "No secret found for PAP login\n"));
-        }
-        upap_authwithpeer(unit, ppp_settings.user, ppp_settings.passwd);
-        auth |= PAP_WITHPEER;
-    }
-#endif
-    auth_pending[unit] = auth;
-    
-    if (!auth)
-        network_phase(unit);
-}
-
-
-/*
- * The peer has failed to authenticate himself using `protocol'.
- */
-void auth_peer_fail(int unit, u16_t protocol)
-{
-    AUTHDEBUG((LOG_INFO, "auth_peer_fail: %d proto=%X\n", unit, protocol));
-    /*
-     * Authentication failure: take the link down
-     */
-    lcp_close(unit, "Authentication failed");
-}
-
-
-#if PAP_SUPPORT > 0 || CHAP_SUPPORT > 0
-/*
- * The peer has been successfully authenticated using `protocol'.
- */
-void auth_peer_success(int unit, u16_t protocol, char *name, int namelen)
-{
-    int pbit;
-    
-    AUTHDEBUG((LOG_INFO, "auth_peer_success: %d proto=%X\n", unit, protocol));
-    switch (protocol) {
-    case PPP_CHAP:
-        pbit = CHAP_PEER;
-        break;
-    case PPP_PAP:
-        pbit = PAP_PEER;
-        break;
-    default:
-        AUTHDEBUG((LOG_WARNING, "auth_peer_success: unknown protocol %x\n",
-               protocol));
-        return;
-    }
-    
-    /*
-     * Save the authenticated name of the peer for later.
-     */
-    if (namelen > sizeof(peer_authname) - 1)
-        namelen = sizeof(peer_authname) - 1;
-    BCOPY(name, peer_authname, namelen);
-    peer_authname[namelen] = 0;
-    
-    /*
-     * If there is no more authentication still to be done,
-     * proceed to the network (or callback) phase.
-     */
-    if ((auth_pending[unit] &= ~pbit) == 0)
-        network_phase(unit);
-}
-
-/*
- * We have failed to authenticate ourselves to the peer using `protocol'.
- */
-void auth_withpeer_fail(int unit, u16_t protocol)
-{
-    int errCode = PPPERR_AUTHFAIL;
-    
-    AUTHDEBUG((LOG_INFO, "auth_withpeer_fail: %d proto=%X\n", unit, protocol));
-    if (passwd_from_file)
-        BZERO(ppp_settings.passwd, MAXSECRETLEN);
-    /* 
-     * XXX Warning: the unit number indicates the interface which is
-     * not necessarily the PPP connection.  It works here as long
-     * as we are only supporting PPP interfaces.
-     */
-    pppIOCtl(unit, PPPCTLS_ERRCODE, &errCode);
-
-    /*
-     * We've failed to authenticate ourselves to our peer.
-     * He'll probably take the link down, and there's not much
-     * we can do except wait for that.
-     */
-}
-
-/*
- * We have successfully authenticated ourselves with the peer using `protocol'.
- */
-void auth_withpeer_success(int unit, u16_t protocol)
-{
-    int pbit;
-    
-    AUTHDEBUG((LOG_INFO, "auth_withpeer_success: %d proto=%X\n", unit, protocol));
-    switch (protocol) {
-    case PPP_CHAP:
-        pbit = CHAP_WITHPEER;
-        break;
-    case PPP_PAP:
-        if (passwd_from_file)
-            BZERO(ppp_settings.passwd, MAXSECRETLEN);
-        pbit = PAP_WITHPEER;
-        break;
-    default:
-        AUTHDEBUG((LOG_WARNING, "auth_peer_success: unknown protocol %x\n",
-               protocol));
-        pbit = 0;
-    }
-    
-    /*
-     * If there is no more authentication still being done,
-     * proceed to the network (or callback) phase.
-     */
-    if ((auth_pending[unit] &= ~pbit) == 0)
-        network_phase(unit);
-}
-#endif
-
-
-/*
- * np_up - a network protocol has come up.
- */
-void np_up(int unit, u16_t proto)
-{
-    AUTHDEBUG((LOG_INFO, "np_up: %d proto=%X\n", unit, proto));
-    if (num_np_up == 0) {
-       AUTHDEBUG((LOG_INFO, "np_up: maxconnect=%d idle_time_limit=%d\n",ppp_settings.maxconnect,ppp_settings.idle_time_limit));
-        /*
-         * At this point we consider that the link has come up successfully.
-         */
-        if (ppp_settings.idle_time_limit > 0)
-            TIMEOUT(check_idle, NULL, ppp_settings.idle_time_limit);
-        
-        /*
-         * Set a timeout to close the connection once the maximum
-         * connect time has expired.
-         */
-        if (ppp_settings.maxconnect > 0)
-            TIMEOUT(connect_time_expired, 0, ppp_settings.maxconnect);
-    }
-    ++num_np_up;
-}
-
-/*
- * np_down - a network protocol has gone down.
- */
-void np_down(int unit, u16_t proto)
-{
-    AUTHDEBUG((LOG_INFO, "np_down: %d proto=%X\n", unit, proto));
-    if (--num_np_up == 0 && ppp_settings.idle_time_limit > 0) {
-        UNTIMEOUT(check_idle, NULL);
-    }
-}
-
-/*
- * np_finished - a network protocol has finished using the link.
- */
-void np_finished(int unit, u16_t proto)
-{
-    AUTHDEBUG((LOG_INFO, "np_finished: %d proto=%X\n", unit, proto));
-    if (--num_np_open <= 0) {
-        /* no further use for the link: shut up shop. */
-        lcp_close(0, "No network protocols running");
-    }
-}
-
-/*
- * auth_reset - called when LCP is starting negotiations to recheck
- * authentication options, i.e. whether we have appropriate secrets
- * to use for authenticating ourselves and/or the peer.
- */
-void auth_reset(int unit)
-{
-    lcp_options *go = &lcp_gotoptions[unit];
-    lcp_options *ao = &lcp_allowoptions[0];
-    ipcp_options *ipwo = &ipcp_wantoptions[0];
-    u32_t remote;
-    
-    AUTHDEBUG((LOG_INFO, "auth_reset: %d\n", unit));
-    ao->neg_upap = !ppp_settings.refuse_pap && (ppp_settings.passwd[0] != 0 || get_pap_passwd(unit, NULL, NULL));
-    ao->neg_chap = !ppp_settings.refuse_chap && ppp_settings.passwd[0] != 0 /*have_chap_secret(ppp_settings.user, ppp_settings.remote_name, (u32_t)0)*/;
-    
-    if (go->neg_upap && !have_pap_secret())
-        go->neg_upap = 0;
-    if (go->neg_chap) {
-        remote = ipwo->accept_remote? 0: ipwo->hisaddr;
-        if (!have_chap_secret(ppp_settings.remote_name, ppp_settings.our_name, remote))
-            go->neg_chap = 0;
-    }
-}
-
-
-#if PAP_SUPPORT > 0
-/*
- * check_passwd - Check the user name and passwd against the PAP secrets
- * file.  If requested, also check against the system password database,
- * and login the user if OK.
- *
- * returns:
- *  UPAP_AUTHNAK: Authentication failed.
- *  UPAP_AUTHACK: Authentication succeeded.
- * In either case, msg points to an appropriate message.
- */
-int check_passwd(
-       int unit,
-       char *auser,
-       int userlen,
-       char *apasswd,
-       int passwdlen,
-       char **msg,
-       int *msglen
-)
-{
-#if 1
-       *msg = (char *) 0;
-       return UPAP_AUTHACK;     /* XXX Assume all entries OK. */
-#else
-    int ret = 0;
-    struct wordlist *addrs = NULL;
-    char passwd[256], user[256];
-    char secret[MAXWORDLEN];
-    static u_short attempts = 0;
-    
-    /*
-     * Make copies of apasswd and auser, then null-terminate them.
-     */
-    BCOPY(apasswd, passwd, passwdlen);
-    passwd[passwdlen] = '\0';
-    BCOPY(auser, user, userlen);
-    user[userlen] = '\0';
-    *msg = (char *) 0;
-
-    /* XXX Validate user name and password. */
-    ret = UPAP_AUTHACK;     /* XXX Assume all entries OK. */
-        
-    if (ret == UPAP_AUTHNAK) {
-        if (*msg == (char *) 0)
-            *msg = "Login incorrect";
-        *msglen = strlen(*msg);
-        /*
-         * Frustrate passwd stealer programs.
-         * Allow 10 tries, but start backing off after 3 (stolen from login).
-         * On 10'th, drop the connection.
-         */
-        if (attempts++ >= 10) {
-            AUTHDEBUG((LOG_WARNING, "%d LOGIN FAILURES BY %s\n", attempts, user));
-            /*ppp_panic("Excess Bad Logins");*/
-        }
-        if (attempts > 3) {
-            sys_msleep((attempts - 3) * 5);
-        }
-        if (addrs != NULL) {
-            free_wordlist(addrs);
-        }
-    } else {
-        attempts = 0;           /* Reset count */
-        if (*msg == (char *) 0)
-            *msg = "Login ok";
-        *msglen = strlen(*msg);
-        set_allowed_addrs(unit, addrs);
-    }
-    
-    BZERO(passwd, sizeof(passwd));
-    BZERO(secret, sizeof(secret));
-    
-    return ret;
-#endif
-}
-#endif
-
-
-/*
- * auth_ip_addr - check whether the peer is authorized to use
- * a given IP address.  Returns 1 if authorized, 0 otherwise.
- */
-int auth_ip_addr(int unit, u32_t addr)
-{
-    return ip_addr_check(addr, addresses[unit]);
-}
-
-/*
- * bad_ip_adrs - return 1 if the IP address is one we don't want
- * to use, such as an address in the loopback net or a multicast address.
- * addr is in network byte order.
- */
-int bad_ip_adrs(u32_t addr)
-{
-    addr = ntohl(addr);
-    return (addr >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET
-        || IN_MULTICAST(addr) || IN_BADCLASS(addr);
-}
-
-
-#if CHAP_SUPPORT > 0
-/*
- * get_secret - open the CHAP secret file and return the secret
- * for authenticating the given client on the given server.
- * (We could be either client or server).
- */
-int get_secret(
-    int unit,
-    char *client,
-    char *server,
-    char *secret,
-    int *secret_len,
-    int save_addrs
-)
-{
-#if 1
-    int len;
-    struct wordlist *addrs;
-    
-    addrs = NULL;
-
-    if(!client || !client[0] || strcmp(client, ppp_settings.user)) {
-       return 0;
-    }
-
-    len = strlen(ppp_settings.passwd);
-    if (len > MAXSECRETLEN) {
-        AUTHDEBUG((LOG_ERR, "Secret for %s on %s is too long\n", client, server));
-        len = MAXSECRETLEN;
-    }
-    BCOPY(ppp_settings.passwd, secret, len);
-    *secret_len = len;
-    
-    return 1;
-#else
-    int ret = 0, len;
-    struct wordlist *addrs;
-    char secbuf[MAXWORDLEN];
-    
-    addrs = NULL;
-    secbuf[0] = 0;
-
-    /* XXX Find secret. */  
-    if (ret < 0)
-        return 0;
-    
-    if (save_addrs)
-        set_allowed_addrs(unit, addrs);
-    
-    len = strlen(secbuf);
-    if (len > MAXSECRETLEN) {
-        AUTHDEBUG((LOG_ERR, "Secret for %s on %s is too long\n", client, server));
-        len = MAXSECRETLEN;
-    }
-    BCOPY(secbuf, secret, len);
-    BZERO(secbuf, sizeof(secbuf));
-    *secret_len = len;
-    
-    return 1;
-#endif
-}
-#endif
-
-
-#if 0 /* UNUSED */
-/*
- * auth_check_options - called to check authentication options.
- */
-void auth_check_options(void)
-{
-    lcp_options *wo = &lcp_wantoptions[0];
-    int can_auth;
-    ipcp_options *ipwo = &ipcp_wantoptions[0];
-    u32_t remote;
-    
-    /* Default our_name to hostname, and user to our_name */
-    if (ppp_settings.our_name[0] == 0 || ppp_settings.usehostname)
-        strcpy(ppp_settings.our_name, ppp_settings.hostname);
-    if (ppp_settings.user[0] == 0)
-        strcpy(ppp_settings.user, ppp_settings.our_name);
-    
-    /* If authentication is required, ask peer for CHAP or PAP. */
-    if (ppp_settings.auth_required && !wo->neg_chap && !wo->neg_upap) {
-        wo->neg_chap = 1;
-        wo->neg_upap = 1;
-    }
-    
-    /*
-     * Check whether we have appropriate secrets to use
-     * to authenticate the peer.
-     */
-    can_auth = wo->neg_upap && have_pap_secret();
-    if (!can_auth && wo->neg_chap) {
-        remote = ipwo->accept_remote? 0: ipwo->hisaddr;
-        can_auth = have_chap_secret(ppp_settings.remote_name, ppp_settings.our_name, remote);
-    }
-    
-    if (ppp_settings.auth_required && !can_auth) {
-        ppp_panic("No auth secret");
-    }
-}
-#endif
-
-
-/**********************************/
-/*** LOCAL FUNCTION DEFINITIONS ***/
-/**********************************/
-/*
- * Proceed to the network phase.
- */
-static void network_phase(int unit)
-{
-    int i;
-    struct protent *protp;
-    lcp_options *go = &lcp_gotoptions[unit];
-    
-    /*
-     * If the peer had to authenticate, run the auth-up script now.
-     */
-    if ((go->neg_chap || go->neg_upap) && !did_authup) {
-        /* XXX Do setup for peer authentication. */
-        did_authup = 1;
-    }
-    
-#if CBCP_SUPPORT > 0
-    /*
-     * If we negotiated callback, do it now.
-     */
-    if (go->neg_cbcp) {
-        lcp_phase[unit] = PHASE_CALLBACK;
-        (*cbcp_protent.open)(unit);
-        return;
-    }
-#endif
-    
-    lcp_phase[unit] = PHASE_NETWORK;
-    for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i)
-        if (protp->protocol < 0xC000 && protp->enabled_flag
-                && protp->open != NULL) {
-            (*protp->open)(unit);
-            if (protp->protocol != PPP_CCP)
-                ++num_np_open;
-        }
-    
-    if (num_np_open == 0)
-        /* nothing to do */
-        lcp_close(0, "No network protocols running");
-}
-
-/*
- * check_idle - check whether the link has been idle for long
- * enough that we can shut it down.
- */
-static void check_idle(void *arg)
-{
-    struct ppp_idle idle;
-    u_short itime;
-    
-       (void)arg;
-    if (!get_idle_time(0, &idle))
-        return;
-    itime = LWIP_MIN(idle.xmit_idle, idle.recv_idle);
-    if (itime >= ppp_settings.idle_time_limit) {
-        /* link is idle: shut it down. */
-        AUTHDEBUG((LOG_INFO, "Terminating connection due to lack of activity.\n"));
-        lcp_close(0, "Link inactive");
-    } else {
-        TIMEOUT(check_idle, NULL, ppp_settings.idle_time_limit - itime);
-    }
-}
-
-/*
- * connect_time_expired - log a message and close the connection.
- */
-static void connect_time_expired(void *arg)
-{
-       (void)arg;
-
-    AUTHDEBUG((LOG_INFO, "Connect time expired\n"));
-    lcp_close(0, "Connect time expired");   /* Close connection */
-}
-
-#if 0
-/*
- * login - Check the user name and password against the system
- * password database, and login the user if OK.
- *
- * returns:
- *  UPAP_AUTHNAK: Login failed.
- *  UPAP_AUTHACK: Login succeeded.
- * In either case, msg points to an appropriate message.
- */
-static int login(char *user, char *passwd, char **msg, int *msglen)
-{
-    /* XXX Fail until we decide that we want to support logins. */
-    return (UPAP_AUTHNAK);
-}
-#endif
-
-/*
- * logout - Logout the user.
- */
-static void logout(void)
-{
-    logged_in = 0;
-}
-
-
-/*
- * null_login - Check if a username of "" and a password of "" are
- * acceptable, and iff so, set the list of acceptable IP addresses
- * and return 1.
- */
-static int null_login(int unit)
-{
-       (void)unit;
-    /* XXX Fail until we decide that we want to support logins. */
-    return 0;
-}
-
-
-/*
- * get_pap_passwd - get a password for authenticating ourselves with
- * our peer using PAP.  Returns 1 on success, 0 if no suitable password
- * could be found.
- */
-static int get_pap_passwd(int unit, char *user, char *passwd)
-{
-/* normally we would reject PAP if no password is provided,
-   but this causes problems with some providers (like CHT in Taiwan)
-   who incorrectly request PAP and expect a bogus/empty password, so
-   always provide a default user/passwd of "none"/"none"
-*/
-    if(user)
-       strcpy(user,   "none");
-    if(passwd)
-       strcpy(passwd, "none");
-
-    return 1;
-}
-
-
-/*
- * have_pap_secret - check whether we have a PAP file with any
- * secrets that we could possibly use for authenticating the peer.
- */
-static int have_pap_secret(void)
-{
-    /* XXX Fail until we set up our passwords. */
-    return 0;
-}
-
-
-/*
- * have_chap_secret - check whether we have a CHAP file with a
- * secret that we could possibly use for authenticating `client'
- * on `server'.  Either can be the null string, meaning we don't
- * know the identity yet.
- */
-static int have_chap_secret(char *client, char *server, u32_t remote)
-{
-       (void)client;
-       (void)server;
-       (void)remote;
-    /* XXX Fail until we set up our passwords. */
-    return 0;
-}
-
-
-#if 0 /* PAP_SUPPORT > 0 || CHAP_SUPPORT > 0 */
-/*
- * set_allowed_addrs() - set the list of allowed addresses.
- */
-static void set_allowed_addrs(int unit, struct wordlist *addrs)
-{
-    if (addresses[unit] != NULL)
-        free_wordlist(addresses[unit]);
-    addresses[unit] = addrs;
-
-#if 0
-    /*
-     * If there's only one authorized address we might as well
-     * ask our peer for that one right away
-     */
-    if (addrs != NULL && addrs->next == NULL) {
-        char *p = addrs->word;
-        struct ipcp_options *wo = &ipcp_wantoptions[unit];
-        u32_t a;
-        struct hostent *hp;
-        
-        if (wo->hisaddr == 0 && *p != '!' && *p != '-'
-                && strchr(p, '/') == NULL) {
-            hp = gethostbyname(p);
-            if (hp != NULL && hp->h_addrtype == AF_INET)
-                a = *(u32_t *)hp->h_addr;
-            else
-                a = inet_addr(p);
-            if (a != (u32_t) -1)
-                wo->hisaddr = a;
-        }
-    }
-#endif
-}
-#endif
-
-static int ip_addr_check(u32_t addr, struct wordlist *addrs)
-{
-    
-    /* don't allow loopback or multicast address */
-    if (bad_ip_adrs(addr))
-        return 0;
-    
-    if (addrs == NULL)
-        return !ppp_settings.auth_required;      /* no addresses authorized */
-    
-    /* XXX All other addresses allowed. */
-    return 1;
-}
-
-#if 0 /* PAP_SUPPORT > 0 || CHAP_SUPPORT */
-/*
- * free_wordlist - release memory allocated for a wordlist.
- */
-static void free_wordlist(struct wordlist *wp)
-{
-    struct wordlist *next;
-    
-    while (wp != NULL) {
-        next = wp->next;
-        free(wp);
-        wp = next;
-    }
-}
-#endif
-
-#endif /* PPP_SUPPORT */
+/*****************************************************************************\r
+* auth.c - Network Authentication and Phase Control program file.\r
+*\r
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.\r
+* Copyright (c) 1997 by Global Election Systems Inc.  All rights reserved.\r
+*\r
+* The authors hereby grant permission to use, copy, modify, distribute,\r
+* and license this software and its documentation for any purpose, provided\r
+* that existing copyright notices are retained in all copies and that this\r
+* notice and the following disclaimer are included verbatim in any \r
+* distributions. No written agreement, license, or royalty fee is required\r
+* for any of the authorized uses.\r
+*\r
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR\r
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+*\r
+******************************************************************************\r
+* REVISION HISTORY\r
+*\r
+* 03-01-01 Marc Boucher <marc@mbsi.ca>\r
+*   Ported to lwIP.\r
+* 97-12-08 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.\r
+*   Ported from public pppd code.\r
+*****************************************************************************/\r
+/*\r
+ * auth.c - PPP authentication and phase control.\r
+ *\r
+ * Copyright (c) 1993 The Australian National University.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms are permitted\r
+ * provided that the above copyright notice and this paragraph are\r
+ * duplicated in all such forms and that any documentation,\r
+ * advertising materials, and other materials related to such\r
+ * distribution and use acknowledge that the software was developed\r
+ * by the Australian National University.  The name of the University\r
+ * may not be used to endorse or promote products derived from this\r
+ * software without specific prior written permission.\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR\r
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r
+ *\r
+ * Copyright (c) 1989 Carnegie Mellon University.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms are permitted\r
+ * provided that the above copyright notice and this paragraph are\r
+ * duplicated in all such forms and that any documentation,\r
+ * advertising materials, and other materials related to such\r
+ * distribution and use acknowledge that the software was developed\r
+ * by Carnegie Mellon University.  The name of the\r
+ * University may not be used to endorse or promote products derived\r
+ * from this software without specific prior written permission.\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR\r
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r
+ */\r
+\r
+#include "ppp.h"\r
+#if PPP_SUPPORT > 0\r
+#include "fsm.h"\r
+#include "lcp.h"\r
+#include "pap.h"\r
+#include "chap.h"\r
+#include "auth.h"\r
+#include "ipcp.h"\r
+\r
+#if CBCP_SUPPORT > 0\r
+#include "cbcp.h"\r
+#endif\r
+\r
+#include "pppdebug.h"\r
+\r
+\r
+/*************************/\r
+/*** LOCAL DEFINITIONS ***/\r
+/*************************/\r
+\r
+/* Bits in auth_pending[] */\r
+#define PAP_WITHPEER    1\r
+#define PAP_PEER    2\r
+#define CHAP_WITHPEER   4\r
+#define CHAP_PEER   8\r
+\r
+\r
+                                                                    \r
+/************************/\r
+/*** LOCAL DATA TYPES ***/\r
+/************************/\r
+/* Used for storing a sequence of words.  Usually malloced. */\r
+struct wordlist {\r
+    struct wordlist *next;\r
+    char        word[1];\r
+};\r
+\r
+\r
+\r
+/***********************************/\r
+/*** LOCAL FUNCTION DECLARATIONS ***/\r
+/***********************************/\r
+extern char *crypt (const char *, const char *);\r
+\r
+/* Prototypes for procedures local to this file. */\r
+\r
+static void network_phase (int);\r
+static void check_idle (void *);\r
+static void connect_time_expired (void *);\r
+#if 0\r
+static int  login (char *, char *, char **, int *);\r
+#endif\r
+static void logout (void);\r
+static int  null_login (int);\r
+static int  get_pap_passwd (int, char *, char *);\r
+static int  have_pap_secret (void);\r
+static int  have_chap_secret (char *, char *, u32_t);\r
+static int  ip_addr_check (u32_t, struct wordlist *);\r
+#if 0 /* PAP_SUPPORT > 0 || CHAP_SUPPORT > 0 */\r
+static void set_allowed_addrs(int unit, struct wordlist *addrs);\r
+static void free_wordlist (struct wordlist *);\r
+#endif\r
+#if CBCP_SUPPORT > 0\r
+static void callback_phase (int);\r
+#endif\r
+\r
+\r
+/******************************/\r
+/*** PUBLIC DATA STRUCTURES ***/\r
+/******************************/\r
+\r
+\r
+/*****************************/\r
+/*** LOCAL DATA STRUCTURES ***/\r
+/*****************************/\r
+#if PAP_SUPPORT > 0 || CHAP_SUPPORT > 0\r
+/* The name by which the peer authenticated itself to us. */\r
+static char peer_authname[MAXNAMELEN];\r
+#endif\r
+\r
+/* Records which authentication operations haven't completed yet. */\r
+static int auth_pending[NUM_PPP];\r
+\r
+/* Set if we have successfully called login() */\r
+static int logged_in;\r
+\r
+/* Set if we have run the /etc/ppp/auth-up script. */\r
+static int did_authup;\r
+\r
+/* List of addresses which the peer may use. */\r
+static struct wordlist *addresses[NUM_PPP];\r
+\r
+/* Number of network protocols which we have opened. */\r
+static int num_np_open;\r
+\r
+/* Number of network protocols which have come up. */\r
+static int num_np_up;\r
+\r
+#if PAP_SUPPORT > 0 || CHAP_SUPPORT > 0\r
+/* Set if we got the contents of passwd[] from the pap-secrets file. */\r
+static int passwd_from_file;\r
+#endif\r
+\r
+\r
+\r
+/***********************************/\r
+/*** PUBLIC FUNCTION DEFINITIONS ***/\r
+/***********************************/\r
+/*\r
+ * An Open on LCP has requested a change from Dead to Establish phase.\r
+ * Do what's necessary to bring the physical layer up.\r
+ */\r
+void link_required(int unit)\r
+{\r
+    AUTHDEBUG((LOG_INFO, "link_required: %d\n", unit));\r
+}\r
+\r
+/*\r
+ * LCP has terminated the link; go to the Dead phase and take the\r
+ * physical layer down.\r
+ */\r
+void link_terminated(int unit)\r
+{\r
+    AUTHDEBUG((LOG_INFO, "link_terminated: %d\n", unit));\r
+    \r
+    if (lcp_phase[unit] == PHASE_DEAD)\r
+        return;\r
+    if (logged_in)\r
+        logout();\r
+    lcp_phase[unit] = PHASE_DEAD;\r
+    AUTHDEBUG((LOG_NOTICE, "Connection terminated.\n"));\r
+       pppMainWakeup(unit);\r
+}\r
+\r
+/*\r
+ * LCP has gone down; it will either die or try to re-establish.\r
+ */\r
+void link_down(int unit)\r
+{\r
+    int i;\r
+    struct protent *protp;\r
+    \r
+    AUTHDEBUG((LOG_INFO, "link_down: %d\n", unit));\r
+    if (did_authup) {\r
+        /* XXX Do link down processing. */\r
+        did_authup = 0;\r
+    }\r
+    for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i) {\r
+        if (!protp->enabled_flag)\r
+            continue;\r
+        if (protp->protocol != PPP_LCP && protp->lowerdown != NULL)\r
+            (*protp->lowerdown)(unit);\r
+        if (protp->protocol < 0xC000 && protp->close != NULL)\r
+            (*protp->close)(unit, "LCP down");\r
+    }\r
+    num_np_open = 0;\r
+    num_np_up = 0;\r
+    if (lcp_phase[unit] != PHASE_DEAD)\r
+        lcp_phase[unit] = PHASE_TERMINATE;\r
+       pppMainWakeup(unit);\r
+}\r
+\r
+/*\r
+ * The link is established.\r
+ * Proceed to the Dead, Authenticate or Network phase as appropriate.\r
+ */\r
+void link_established(int unit)\r
+{\r
+    int auth;\r
+    int i;\r
+    struct protent *protp;\r
+    lcp_options *wo = &lcp_wantoptions[unit];\r
+    lcp_options *go = &lcp_gotoptions[unit];\r
+#if PAP_SUPPORT > 0 || CHAP_SUPPORT > 0\r
+    lcp_options *ho = &lcp_hisoptions[unit];\r
+#endif\r
+    \r
+    AUTHDEBUG((LOG_INFO, "link_established: %d\n", unit));\r
+    /*\r
+     * Tell higher-level protocols that LCP is up.\r
+     */\r
+    for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i)\r
+        if (protp->protocol != PPP_LCP && protp->enabled_flag\r
+                && protp->lowerup != NULL)\r
+            (*protp->lowerup)(unit);\r
+    \r
+    if (ppp_settings.auth_required && !(go->neg_chap || go->neg_upap)) {\r
+        /*\r
+         * We wanted the peer to authenticate itself, and it refused:\r
+         * treat it as though it authenticated with PAP using a username\r
+         * of "" and a password of "".  If that's not OK, boot it out.\r
+         */\r
+        if (!wo->neg_upap || !null_login(unit)) {\r
+            AUTHDEBUG((LOG_WARNING, "peer refused to authenticate\n"));\r
+            lcp_close(unit, "peer refused to authenticate");\r
+            return;\r
+        }\r
+    }\r
+    \r
+    lcp_phase[unit] = PHASE_AUTHENTICATE;\r
+    auth = 0;\r
+#if CHAP_SUPPORT > 0\r
+    if (go->neg_chap) {\r
+        ChapAuthPeer(unit, ppp_settings.our_name, go->chap_mdtype);\r
+        auth |= CHAP_PEER;\r
+    } \r
+#endif\r
+#if PAP_SUPPORT > 0 && CHAP_SUPPORT > 0\r
+    else\r
+#endif\r
+#if PAP_SUPPORT > 0\r
+    if (go->neg_upap) {\r
+        upap_authpeer(unit);\r
+        auth |= PAP_PEER;\r
+    }\r
+#endif\r
+#if CHAP_SUPPORT > 0\r
+    if (ho->neg_chap) {\r
+        ChapAuthWithPeer(unit, ppp_settings.user, ho->chap_mdtype);\r
+        auth |= CHAP_WITHPEER;\r
+    }\r
+#endif\r
+#if PAP_SUPPORT > 0 && CHAP_SUPPORT > 0\r
+    else\r
+#endif\r
+#if PAP_SUPPORT > 0\r
+    if (ho->neg_upap) {\r
+        if (ppp_settings.passwd[0] == 0) {\r
+            passwd_from_file = 1;\r
+            if (!get_pap_passwd(unit, ppp_settings.user, ppp_settings.passwd))\r
+                AUTHDEBUG((LOG_ERR, "No secret found for PAP login\n"));\r
+        }\r
+        upap_authwithpeer(unit, ppp_settings.user, ppp_settings.passwd);\r
+        auth |= PAP_WITHPEER;\r
+    }\r
+#endif\r
+    auth_pending[unit] = auth;\r
+    \r
+    if (!auth)\r
+        network_phase(unit);\r
+}\r
+\r
+\r
+/*\r
+ * The peer has failed to authenticate himself using `protocol'.\r
+ */\r
+void auth_peer_fail(int unit, u16_t protocol)\r
+{\r
+    AUTHDEBUG((LOG_INFO, "auth_peer_fail: %d proto=%X\n", unit, protocol));\r
+    /*\r
+     * Authentication failure: take the link down\r
+     */\r
+    lcp_close(unit, "Authentication failed");\r
+}\r
+\r
+\r
+#if PAP_SUPPORT > 0 || CHAP_SUPPORT > 0\r
+/*\r
+ * The peer has been successfully authenticated using `protocol'.\r
+ */\r
+void auth_peer_success(int unit, u16_t protocol, char *name, int namelen)\r
+{\r
+    int pbit;\r
+    \r
+    AUTHDEBUG((LOG_INFO, "auth_peer_success: %d proto=%X\n", unit, protocol));\r
+    switch (protocol) {\r
+    case PPP_CHAP:\r
+        pbit = CHAP_PEER;\r
+        break;\r
+    case PPP_PAP:\r
+        pbit = PAP_PEER;\r
+        break;\r
+    default:\r
+        AUTHDEBUG((LOG_WARNING, "auth_peer_success: unknown protocol %x\n",\r
+               protocol));\r
+        return;\r
+    }\r
+    \r
+    /*\r
+     * Save the authenticated name of the peer for later.\r
+     */\r
+    if (namelen > sizeof(peer_authname) - 1)\r
+        namelen = sizeof(peer_authname) - 1;\r
+    BCOPY(name, peer_authname, namelen);\r
+    peer_authname[namelen] = 0;\r
+    \r
+    /*\r
+     * If there is no more authentication still to be done,\r
+     * proceed to the network (or callback) phase.\r
+     */\r
+    if ((auth_pending[unit] &= ~pbit) == 0)\r
+        network_phase(unit);\r
+}\r
+\r
+/*\r
+ * We have failed to authenticate ourselves to the peer using `protocol'.\r
+ */\r
+void auth_withpeer_fail(int unit, u16_t protocol)\r
+{\r
+    int errCode = PPPERR_AUTHFAIL;\r
+    \r
+    AUTHDEBUG((LOG_INFO, "auth_withpeer_fail: %d proto=%X\n", unit, protocol));\r
+    if (passwd_from_file)\r
+        BZERO(ppp_settings.passwd, MAXSECRETLEN);\r
+    /* \r
+     * XXX Warning: the unit number indicates the interface which is\r
+     * not necessarily the PPP connection.  It works here as long\r
+     * as we are only supporting PPP interfaces.\r
+     */\r
+    pppIOCtl(unit, PPPCTLS_ERRCODE, &errCode);\r
+\r
+    /*\r
+     * We've failed to authenticate ourselves to our peer.\r
+     * He'll probably take the link down, and there's not much\r
+     * we can do except wait for that.\r
+     */\r
+}\r
+\r
+/*\r
+ * We have successfully authenticated ourselves with the peer using `protocol'.\r
+ */\r
+void auth_withpeer_success(int unit, u16_t protocol)\r
+{\r
+    int pbit;\r
+    \r
+    AUTHDEBUG((LOG_INFO, "auth_withpeer_success: %d proto=%X\n", unit, protocol));\r
+    switch (protocol) {\r
+    case PPP_CHAP:\r
+        pbit = CHAP_WITHPEER;\r
+        break;\r
+    case PPP_PAP:\r
+        if (passwd_from_file)\r
+            BZERO(ppp_settings.passwd, MAXSECRETLEN);\r
+        pbit = PAP_WITHPEER;\r
+        break;\r
+    default:\r
+        AUTHDEBUG((LOG_WARNING, "auth_peer_success: unknown protocol %x\n",\r
+               protocol));\r
+        pbit = 0;\r
+    }\r
+    \r
+    /*\r
+     * If there is no more authentication still being done,\r
+     * proceed to the network (or callback) phase.\r
+     */\r
+    if ((auth_pending[unit] &= ~pbit) == 0)\r
+        network_phase(unit);\r
+}\r
+#endif\r
+\r
+\r
+/*\r
+ * np_up - a network protocol has come up.\r
+ */\r
+void np_up(int unit, u16_t proto)\r
+{\r
+    AUTHDEBUG((LOG_INFO, "np_up: %d proto=%X\n", unit, proto));\r
+    if (num_np_up == 0) {\r
+       AUTHDEBUG((LOG_INFO, "np_up: maxconnect=%d idle_time_limit=%d\n",ppp_settings.maxconnect,ppp_settings.idle_time_limit));\r
+        /*\r
+         * At this point we consider that the link has come up successfully.\r
+         */\r
+        if (ppp_settings.idle_time_limit > 0)\r
+            TIMEOUT(check_idle, NULL, ppp_settings.idle_time_limit);\r
+        \r
+        /*\r
+         * Set a timeout to close the connection once the maximum\r
+         * connect time has expired.\r
+         */\r
+        if (ppp_settings.maxconnect > 0)\r
+            TIMEOUT(connect_time_expired, 0, ppp_settings.maxconnect);\r
+    }\r
+    ++num_np_up;\r
+}\r
+\r
+/*\r
+ * np_down - a network protocol has gone down.\r
+ */\r
+void np_down(int unit, u16_t proto)\r
+{\r
+    AUTHDEBUG((LOG_INFO, "np_down: %d proto=%X\n", unit, proto));\r
+    if (--num_np_up == 0 && ppp_settings.idle_time_limit > 0) {\r
+        UNTIMEOUT(check_idle, NULL);\r
+    }\r
+}\r
+\r
+/*\r
+ * np_finished - a network protocol has finished using the link.\r
+ */\r
+void np_finished(int unit, u16_t proto)\r
+{\r
+    AUTHDEBUG((LOG_INFO, "np_finished: %d proto=%X\n", unit, proto));\r
+    if (--num_np_open <= 0) {\r
+        /* no further use for the link: shut up shop. */\r
+        lcp_close(0, "No network protocols running");\r
+    }\r
+}\r
+\r
+/*\r
+ * auth_reset - called when LCP is starting negotiations to recheck\r
+ * authentication options, i.e. whether we have appropriate secrets\r
+ * to use for authenticating ourselves and/or the peer.\r
+ */\r
+void auth_reset(int unit)\r
+{\r
+    lcp_options *go = &lcp_gotoptions[unit];\r
+    lcp_options *ao = &lcp_allowoptions[0];\r
+    ipcp_options *ipwo = &ipcp_wantoptions[0];\r
+    u32_t remote;\r
+    \r
+    AUTHDEBUG((LOG_INFO, "auth_reset: %d\n", unit));\r
+    ao->neg_upap = !ppp_settings.refuse_pap && (ppp_settings.passwd[0] != 0 || get_pap_passwd(unit, NULL, NULL));\r
+    ao->neg_chap = !ppp_settings.refuse_chap && ppp_settings.passwd[0] != 0 /*have_chap_secret(ppp_settings.user, ppp_settings.remote_name, (u32_t)0)*/;\r
+    \r
+    if (go->neg_upap && !have_pap_secret())\r
+        go->neg_upap = 0;\r
+    if (go->neg_chap) {\r
+        remote = ipwo->accept_remote? 0: ipwo->hisaddr;\r
+        if (!have_chap_secret(ppp_settings.remote_name, ppp_settings.our_name, remote))\r
+            go->neg_chap = 0;\r
+    }\r
+}\r
+\r
+\r
+#if PAP_SUPPORT > 0\r
+/*\r
+ * check_passwd - Check the user name and passwd against the PAP secrets\r
+ * file.  If requested, also check against the system password database,\r
+ * and login the user if OK.\r
+ *\r
+ * returns:\r
+ *  UPAP_AUTHNAK: Authentication failed.\r
+ *  UPAP_AUTHACK: Authentication succeeded.\r
+ * In either case, msg points to an appropriate message.\r
+ */\r
+int check_passwd(\r
+       int unit,\r
+       char *auser,\r
+       int userlen,\r
+       char *apasswd,\r
+       int passwdlen,\r
+       char **msg,\r
+       int *msglen\r
+)\r
+{\r
+#if 1\r
+       *msg = (char *) 0;\r
+       return UPAP_AUTHACK;     /* XXX Assume all entries OK. */\r
+#else\r
+    int ret = 0;\r
+    struct wordlist *addrs = NULL;\r
+    char passwd[256], user[256];\r
+    char secret[MAXWORDLEN];\r
+    static u_short attempts = 0;\r
+    \r
+    /*\r
+     * Make copies of apasswd and auser, then null-terminate them.\r
+     */\r
+    BCOPY(apasswd, passwd, passwdlen);\r
+    passwd[passwdlen] = '\0';\r
+    BCOPY(auser, user, userlen);\r
+    user[userlen] = '\0';\r
+    *msg = (char *) 0;\r
+\r
+    /* XXX Validate user name and password. */\r
+    ret = UPAP_AUTHACK;     /* XXX Assume all entries OK. */\r
+        \r
+    if (ret == UPAP_AUTHNAK) {\r
+        if (*msg == (char *) 0)\r
+            *msg = "Login incorrect";\r
+        *msglen = strlen(*msg);\r
+        /*\r
+         * Frustrate passwd stealer programs.\r
+         * Allow 10 tries, but start backing off after 3 (stolen from login).\r
+         * On 10'th, drop the connection.\r
+         */\r
+        if (attempts++ >= 10) {\r
+            AUTHDEBUG((LOG_WARNING, "%d LOGIN FAILURES BY %s\n", attempts, user));\r
+            /*ppp_panic("Excess Bad Logins");*/\r
+        }\r
+        if (attempts > 3) {\r
+            sys_msleep((attempts - 3) * 5);\r
+        }\r
+        if (addrs != NULL) {\r
+            free_wordlist(addrs);\r
+        }\r
+    } else {\r
+        attempts = 0;           /* Reset count */\r
+        if (*msg == (char *) 0)\r
+            *msg = "Login ok";\r
+        *msglen = strlen(*msg);\r
+        set_allowed_addrs(unit, addrs);\r
+    }\r
+    \r
+    BZERO(passwd, sizeof(passwd));\r
+    BZERO(secret, sizeof(secret));\r
+    \r
+    return ret;\r
+#endif\r
+}\r
+#endif\r
+\r
+\r
+/*\r
+ * auth_ip_addr - check whether the peer is authorized to use\r
+ * a given IP address.  Returns 1 if authorized, 0 otherwise.\r
+ */\r
+int auth_ip_addr(int unit, u32_t addr)\r
+{\r
+    return ip_addr_check(addr, addresses[unit]);\r
+}\r
+\r
+/*\r
+ * bad_ip_adrs - return 1 if the IP address is one we don't want\r
+ * to use, such as an address in the loopback net or a multicast address.\r
+ * addr is in network byte order.\r
+ */\r
+int bad_ip_adrs(u32_t addr)\r
+{\r
+    addr = ntohl(addr);\r
+    return (addr >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET\r
+        || IN_MULTICAST(addr) || IN_BADCLASS(addr);\r
+}\r
+\r
+\r
+#if CHAP_SUPPORT > 0\r
+/*\r
+ * get_secret - open the CHAP secret file and return the secret\r
+ * for authenticating the given client on the given server.\r
+ * (We could be either client or server).\r
+ */\r
+int get_secret(\r
+    int unit,\r
+    char *client,\r
+    char *server,\r
+    char *secret,\r
+    int *secret_len,\r
+    int save_addrs\r
+)\r
+{\r
+#if 1\r
+    int len;\r
+    struct wordlist *addrs;\r
+    \r
+    addrs = NULL;\r
+\r
+    if(!client || !client[0] || strcmp(client, ppp_settings.user)) {\r
+       return 0;\r
+    }\r
+\r
+    len = strlen(ppp_settings.passwd);\r
+    if (len > MAXSECRETLEN) {\r
+        AUTHDEBUG((LOG_ERR, "Secret for %s on %s is too long\n", client, server));\r
+        len = MAXSECRETLEN;\r
+    }\r
+    BCOPY(ppp_settings.passwd, secret, len);\r
+    *secret_len = len;\r
+    \r
+    return 1;\r
+#else\r
+    int ret = 0, len;\r
+    struct wordlist *addrs;\r
+    char secbuf[MAXWORDLEN];\r
+    \r
+    addrs = NULL;\r
+    secbuf[0] = 0;\r
+\r
+    /* XXX Find secret. */  \r
+    if (ret < 0)\r
+        return 0;\r
+    \r
+    if (save_addrs)\r
+        set_allowed_addrs(unit, addrs);\r
+    \r
+    len = strlen(secbuf);\r
+    if (len > MAXSECRETLEN) {\r
+        AUTHDEBUG((LOG_ERR, "Secret for %s on %s is too long\n", client, server));\r
+        len = MAXSECRETLEN;\r
+    }\r
+    BCOPY(secbuf, secret, len);\r
+    BZERO(secbuf, sizeof(secbuf));\r
+    *secret_len = len;\r
+    \r
+    return 1;\r
+#endif\r
+}\r
+#endif\r
+\r
+\r
+#if 0 /* UNUSED */\r
+/*\r
+ * auth_check_options - called to check authentication options.\r
+ */\r
+void auth_check_options(void)\r
+{\r
+    lcp_options *wo = &lcp_wantoptions[0];\r
+    int can_auth;\r
+    ipcp_options *ipwo = &ipcp_wantoptions[0];\r
+    u32_t remote;\r
+    \r
+    /* Default our_name to hostname, and user to our_name */\r
+    if (ppp_settings.our_name[0] == 0 || ppp_settings.usehostname)\r
+        strcpy(ppp_settings.our_name, ppp_settings.hostname);\r
+    if (ppp_settings.user[0] == 0)\r
+        strcpy(ppp_settings.user, ppp_settings.our_name);\r
+    \r
+    /* If authentication is required, ask peer for CHAP or PAP. */\r
+    if (ppp_settings.auth_required && !wo->neg_chap && !wo->neg_upap) {\r
+        wo->neg_chap = 1;\r
+        wo->neg_upap = 1;\r
+    }\r
+    \r
+    /*\r
+     * Check whether we have appropriate secrets to use\r
+     * to authenticate the peer.\r
+     */\r
+    can_auth = wo->neg_upap && have_pap_secret();\r
+    if (!can_auth && wo->neg_chap) {\r
+        remote = ipwo->accept_remote? 0: ipwo->hisaddr;\r
+        can_auth = have_chap_secret(ppp_settings.remote_name, ppp_settings.our_name, remote);\r
+    }\r
+    \r
+    if (ppp_settings.auth_required && !can_auth) {\r
+        ppp_panic("No auth secret");\r
+    }\r
+}\r
+#endif\r
+\r
+\r
+/**********************************/\r
+/*** LOCAL FUNCTION DEFINITIONS ***/\r
+/**********************************/\r
+/*\r
+ * Proceed to the network phase.\r
+ */\r
+static void network_phase(int unit)\r
+{\r
+    int i;\r
+    struct protent *protp;\r
+    lcp_options *go = &lcp_gotoptions[unit];\r
+    \r
+    /*\r
+     * If the peer had to authenticate, run the auth-up script now.\r
+     */\r
+    if ((go->neg_chap || go->neg_upap) && !did_authup) {\r
+        /* XXX Do setup for peer authentication. */\r
+        did_authup = 1;\r
+    }\r
+    \r
+#if CBCP_SUPPORT > 0\r
+    /*\r
+     * If we negotiated callback, do it now.\r
+     */\r
+    if (go->neg_cbcp) {\r
+        lcp_phase[unit] = PHASE_CALLBACK;\r
+        (*cbcp_protent.open)(unit);\r
+        return;\r
+    }\r
+#endif\r
+    \r
+    lcp_phase[unit] = PHASE_NETWORK;\r
+    for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i)\r
+        if (protp->protocol < 0xC000 && protp->enabled_flag\r
+                && protp->open != NULL) {\r
+            (*protp->open)(unit);\r
+            if (protp->protocol != PPP_CCP)\r
+                ++num_np_open;\r
+        }\r
+    \r
+    if (num_np_open == 0)\r
+        /* nothing to do */\r
+        lcp_close(0, "No network protocols running");\r
+}\r
+\r
+/*\r
+ * check_idle - check whether the link has been idle for long\r
+ * enough that we can shut it down.\r
+ */\r
+static void check_idle(void *arg)\r
+{\r
+    struct ppp_idle idle;\r
+    u_short itime;\r
+    \r
+       (void)arg;\r
+    if (!get_idle_time(0, &idle))\r
+        return;\r
+    itime = LWIP_MIN(idle.xmit_idle, idle.recv_idle);\r
+    if (itime >= ppp_settings.idle_time_limit) {\r
+        /* link is idle: shut it down. */\r
+        AUTHDEBUG((LOG_INFO, "Terminating connection due to lack of activity.\n"));\r
+        lcp_close(0, "Link inactive");\r
+    } else {\r
+        TIMEOUT(check_idle, NULL, ppp_settings.idle_time_limit - itime);\r
+    }\r
+}\r
+\r
+/*\r
+ * connect_time_expired - log a message and close the connection.\r
+ */\r
+static void connect_time_expired(void *arg)\r
+{\r
+       (void)arg;\r
+\r
+    AUTHDEBUG((LOG_INFO, "Connect time expired\n"));\r
+    lcp_close(0, "Connect time expired");   /* Close connection */\r
+}\r
+\r
+#if 0\r
+/*\r
+ * login - Check the user name and password against the system\r
+ * password database, and login the user if OK.\r
+ *\r
+ * returns:\r
+ *  UPAP_AUTHNAK: Login failed.\r
+ *  UPAP_AUTHACK: Login succeeded.\r
+ * In either case, msg points to an appropriate message.\r
+ */\r
+static int login(char *user, char *passwd, char **msg, int *msglen)\r
+{\r
+    /* XXX Fail until we decide that we want to support logins. */\r
+    return (UPAP_AUTHNAK);\r
+}\r
+#endif\r
+\r
+/*\r
+ * logout - Logout the user.\r
+ */\r
+static void logout(void)\r
+{\r
+    logged_in = 0;\r
+}\r
+\r
+\r
+/*\r
+ * null_login - Check if a username of "" and a password of "" are\r
+ * acceptable, and iff so, set the list of acceptable IP addresses\r
+ * and return 1.\r
+ */\r
+static int null_login(int unit)\r
+{\r
+       (void)unit;\r
+    /* XXX Fail until we decide that we want to support logins. */\r
+    return 0;\r
+}\r
+\r
+\r
+/*\r
+ * get_pap_passwd - get a password for authenticating ourselves with\r
+ * our peer using PAP.  Returns 1 on success, 0 if no suitable password\r
+ * could be found.\r
+ */\r
+static int get_pap_passwd(int unit, char *user, char *passwd)\r
+{\r
+/* normally we would reject PAP if no password is provided,\r
+   but this causes problems with some providers (like CHT in Taiwan)\r
+   who incorrectly request PAP and expect a bogus/empty password, so\r
+   always provide a default user/passwd of "none"/"none"\r
+*/\r
+    if(user)\r
+       strcpy(user,   "none");\r
+    if(passwd)\r
+       strcpy(passwd, "none");\r
+\r
+    return 1;\r
+}\r
+\r
+\r
+/*\r
+ * have_pap_secret - check whether we have a PAP file with any\r
+ * secrets that we could possibly use for authenticating the peer.\r
+ */\r
+static int have_pap_secret(void)\r
+{\r
+    /* XXX Fail until we set up our passwords. */\r
+    return 0;\r
+}\r
+\r
+\r
+/*\r
+ * have_chap_secret - check whether we have a CHAP file with a\r
+ * secret that we could possibly use for authenticating `client'\r
+ * on `server'.  Either can be the null string, meaning we don't\r
+ * know the identity yet.\r
+ */\r
+static int have_chap_secret(char *client, char *server, u32_t remote)\r
+{\r
+       (void)client;\r
+       (void)server;\r
+       (void)remote;\r
+    /* XXX Fail until we set up our passwords. */\r
+    return 0;\r
+}\r
+\r
+\r
+#if 0 /* PAP_SUPPORT > 0 || CHAP_SUPPORT > 0 */\r
+/*\r
+ * set_allowed_addrs() - set the list of allowed addresses.\r
+ */\r
+static void set_allowed_addrs(int unit, struct wordlist *addrs)\r
+{\r
+    if (addresses[unit] != NULL)\r
+        free_wordlist(addresses[unit]);\r
+    addresses[unit] = addrs;\r
+\r
+#if 0\r
+    /*\r
+     * If there's only one authorized address we might as well\r
+     * ask our peer for that one right away\r
+     */\r
+    if (addrs != NULL && addrs->next == NULL) {\r
+        char *p = addrs->word;\r
+        struct ipcp_options *wo = &ipcp_wantoptions[unit];\r
+        u32_t a;\r
+        struct hostent *hp;\r
+        \r
+        if (wo->hisaddr == 0 && *p != '!' && *p != '-'\r
+                && strchr(p, '/') == NULL) {\r
+            hp = gethostbyname(p);\r
+            if (hp != NULL && hp->h_addrtype == AF_INET)\r
+                a = *(u32_t *)hp->h_addr;\r
+            else\r
+                a = inet_addr(p);\r
+            if (a != (u32_t) -1)\r
+                wo->hisaddr = a;\r
+        }\r
+    }\r
+#endif\r
+}\r
+#endif\r
+\r
+static int ip_addr_check(u32_t addr, struct wordlist *addrs)\r
+{\r
+    \r
+    /* don't allow loopback or multicast address */\r
+    if (bad_ip_adrs(addr))\r
+        return 0;\r
+    \r
+    if (addrs == NULL)\r
+        return !ppp_settings.auth_required;      /* no addresses authorized */\r
+    \r
+    /* XXX All other addresses allowed. */\r
+    return 1;\r
+}\r
+\r
+#if 0 /* PAP_SUPPORT > 0 || CHAP_SUPPORT */\r
+/*\r
+ * free_wordlist - release memory allocated for a wordlist.\r
+ */\r
+static void free_wordlist(struct wordlist *wp)\r
+{\r
+    struct wordlist *next;\r
+    \r
+    while (wp != NULL) {\r
+        next = wp->next;\r
+        free(wp);\r
+        wp = next;\r
+    }\r
+}\r
+#endif\r
+\r
+#endif /* PPP_SUPPORT */\r
index d6a5de5b79a6c6eec007a25a3bc139ad7db047bd..58174056c5bfd8a7aaa07d76a6a8cd1276be0f09 100644 (file)
@@ -1,94 +1,94 @@
-/*****************************************************************************
-* auth.h -  PPP Authentication and phase control header file.
-*
-* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
-* portions Copyright (c) 1998 Global Election Systems Inc.
-*
-* The authors hereby grant permission to use, copy, modify, distribute,
-* and license this software and its documentation for any purpose, provided
-* that existing copyright notices are retained in all copies and that this
-* notice and the following disclaimer are included verbatim in any 
-* distributions. No written agreement, license, or royalty fee is required
-* for any of the authorized uses.
-*
-* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *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 CONTRIBUTORS 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.
-*
-******************************************************************************
-* REVISION HISTORY
-*
-* 03-01-01 Marc Boucher <marc@mbsi.ca>
-*   Ported to lwIP.
-* 97-12-04 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
-*      Original derived from BSD pppd.h.
-*****************************************************************************/
-/*
- * pppd.h - PPP daemon global declarations.
- *
- * Copyright (c) 1989 Carnegie Mellon University.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by Carnegie Mellon University.  The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- */
-
-#ifndef AUTH_H
-#define AUTH_H
-
-/***********************
-*** PUBLIC FUNCTIONS ***
-***********************/
-void link_required (int);              /* we are starting to use the link */
-void link_terminated (int);    /* we are finished with the link */
-void link_down (int);                  /* the LCP layer has left the Opened state */
-void link_established (int);   /* the link is up; authenticate now */
-void np_up (int, u16_t);                       /* a network protocol has come up */
-void np_down (int, u16_t);             /* a network protocol has gone down */
-void np_finished (int, u16_t); /* a network protocol no longer needs link */
-void auth_peer_fail (int, u16_t);/* peer failed to authenticate itself */
-
-/* peer successfully authenticated itself */
-void auth_peer_success (int, u16_t, char *, int);
-
-/* we failed to authenticate ourselves */
-void auth_withpeer_fail (int, u16_t);
-
-/* we successfully authenticated ourselves */
-void auth_withpeer_success (int, u16_t);
-
-/* check authentication options supplied */
-void auth_check_options (void);
-void auth_reset (int);                 /* check what secrets we have */
-
-/* Check peer-supplied username/password */
-int  check_passwd (int, char *, int, char *, int, char **, int *);
-
-/* get "secret" for chap */
-int  get_secret (int, char *, char *, char *, int *, int);
-
-/* check if IP address is authorized */
-int  auth_ip_addr (int, u32_t);
-
-/* check if IP address is unreasonable */
-int  bad_ip_adrs (u32_t);
-
-
-#endif /* AUTH_H */
+/*****************************************************************************\r
+* auth.h -  PPP Authentication and phase control header file.\r
+*\r
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.\r
+* portions Copyright (c) 1998 Global Election Systems Inc.\r
+*\r
+* The authors hereby grant permission to use, copy, modify, distribute,\r
+* and license this software and its documentation for any purpose, provided\r
+* that existing copyright notices are retained in all copies and that this\r
+* notice and the following disclaimer are included verbatim in any \r
+* distributions. No written agreement, license, or royalty fee is required\r
+* for any of the authorized uses.\r
+*\r
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR\r
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+*\r
+******************************************************************************\r
+* REVISION HISTORY\r
+*\r
+* 03-01-01 Marc Boucher <marc@mbsi.ca>\r
+*   Ported to lwIP.\r
+* 97-12-04 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.\r
+*      Original derived from BSD pppd.h.\r
+*****************************************************************************/\r
+/*\r
+ * pppd.h - PPP daemon global declarations.\r
+ *\r
+ * Copyright (c) 1989 Carnegie Mellon University.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms are permitted\r
+ * provided that the above copyright notice and this paragraph are\r
+ * duplicated in all such forms and that any documentation,\r
+ * advertising materials, and other materials related to such\r
+ * distribution and use acknowledge that the software was developed\r
+ * by Carnegie Mellon University.  The name of the\r
+ * University may not be used to endorse or promote products derived\r
+ * from this software without specific prior written permission.\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR\r
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r
+ *\r
+ */\r
+\r
+#ifndef AUTH_H\r
+#define AUTH_H\r
+\r
+/***********************\r
+*** PUBLIC FUNCTIONS ***\r
+***********************/\r
+void link_required (int);              /* we are starting to use the link */\r
+void link_terminated (int);    /* we are finished with the link */\r
+void link_down (int);                  /* the LCP layer has left the Opened state */\r
+void link_established (int);   /* the link is up; authenticate now */\r
+void np_up (int, u16_t);                       /* a network protocol has come up */\r
+void np_down (int, u16_t);             /* a network protocol has gone down */\r
+void np_finished (int, u16_t); /* a network protocol no longer needs link */\r
+void auth_peer_fail (int, u16_t);/* peer failed to authenticate itself */\r
+\r
+/* peer successfully authenticated itself */\r
+void auth_peer_success (int, u16_t, char *, int);\r
+\r
+/* we failed to authenticate ourselves */\r
+void auth_withpeer_fail (int, u16_t);\r
+\r
+/* we successfully authenticated ourselves */\r
+void auth_withpeer_success (int, u16_t);\r
+\r
+/* check authentication options supplied */\r
+void auth_check_options (void);\r
+void auth_reset (int);                 /* check what secrets we have */\r
+\r
+/* Check peer-supplied username/password */\r
+int  check_passwd (int, char *, int, char *, int, char **, int *);\r
+\r
+/* get "secret" for chap */\r
+int  get_secret (int, char *, char *, char *, int *, int);\r
+\r
+/* check if IP address is authorized */\r
+int  auth_ip_addr (int, u32_t);\r
+\r
+/* check if IP address is unreasonable */\r
+int  bad_ip_adrs (u32_t);\r
+\r
+\r
+#endif /* AUTH_H */\r
index 4d1dc0d245b3d8203062baa358fe95cf5ca9d8f7..30441bdc8328b211a920f05e9932bee53c9dea83 100644 (file)
-/*** WARNING - THIS HAS NEVER BEEN FINISHED ***/
-/*****************************************************************************
-* chap.c - Network Challenge Handshake Authentication Protocol program file.
-*
-* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
-* portions Copyright (c) 1997 by Global Election Systems Inc.
-*
-* The authors hereby grant permission to use, copy, modify, distribute,
-* and license this software and its documentation for any purpose, provided
-* that existing copyright notices are retained in all copies and that this
-* notice and the following disclaimer are included verbatim in any 
-* distributions. No written agreement, license, or royalty fee is required
-* for any of the authorized uses.
-*
-* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *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 CONTRIBUTORS 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.
-*
-******************************************************************************
-* REVISION HISTORY
-*
-* 03-01-01 Marc Boucher <marc@mbsi.ca>
-*   Ported to lwIP.
-* 97-12-04 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
-*      Original based on BSD chap.c.
-*****************************************************************************/
-/*
- * chap.c - Challenge Handshake Authentication Protocol.
- *
- * Copyright (c) 1993 The Australian National University.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the Australian National University.  The name of the University
- * may not be used to endorse or promote products derived from this
- * software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Copyright (c) 1991 Gregory M. Christy.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by Gregory M. Christy.  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 ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include "ppp.h"
-#if PPP_SUPPORT > 0
-#include "magic.h"
-
-#if CHAP_SUPPORT > 0
-
-#include "randm.h"
-#include "auth.h"
-#include "md5.h"
-#include "chap.h"
-#include "chpms.h"
-#include "pppdebug.h"
-
-
-/*************************/
-/*** LOCAL DEFINITIONS ***/
-/*************************/
-
-
-/************************/
-/*** LOCAL DATA TYPES ***/
-/************************/
-
-
-/***********************************/
-/*** LOCAL FUNCTION DECLARATIONS ***/
-/***********************************/
-/*
- * Protocol entry points.
- */
-static void ChapInit (int);
-static void ChapLowerUp (int);
-static void ChapLowerDown (int);
-static void ChapInput (int, u_char *, int);
-static void ChapProtocolReject (int);
-static int  ChapPrintPkt (u_char *, int,
-                             void (*) (void *, char *, ...), void *);
-
-static void ChapChallengeTimeout (void *);
-static void ChapResponseTimeout (void *);
-static void ChapReceiveChallenge (chap_state *, u_char *, int, int);
-static void ChapRechallenge (void *);
-static void ChapReceiveResponse (chap_state *, u_char *, int, int);
-static void ChapReceiveSuccess(chap_state *cstate, u_char *inp, u_char id, int len);
-static void ChapReceiveFailure(chap_state *cstate, u_char *inp, u_char id, int len);
-static void ChapSendStatus (chap_state *, int);
-static void ChapSendChallenge (chap_state *);
-static void ChapSendResponse (chap_state *);
-static void ChapGenChallenge (chap_state *);
-
-
-/******************************/
-/*** PUBLIC DATA STRUCTURES ***/
-/******************************/
-chap_state chap[NUM_PPP];              /* CHAP state; one for each unit */
-
-struct protent chap_protent = {
-    PPP_CHAP,
-    ChapInit,
-    ChapInput,
-    ChapProtocolReject,
-    ChapLowerUp,
-    ChapLowerDown,
-    NULL,
-    NULL,
-#if 0
-    ChapPrintPkt,
-    NULL,
-#endif
-    1,
-    "CHAP",
-#if 0
-    NULL,
-    NULL,
-    NULL
-#endif
-};
-
-
-
-/*****************************/
-/*** LOCAL DATA STRUCTURES ***/
-/*****************************/
-static char *ChapCodenames[] = {
-       "Challenge", "Response", "Success", "Failure"
-};
-
-
-
-/***********************************/
-/*** PUBLIC FUNCTION DEFINITIONS ***/
-/***********************************/
-/*
- * ChapAuthWithPeer - Authenticate us with our peer (start client).
- *
- */
-void ChapAuthWithPeer(int unit, char *our_name, int digest)
-{
-       chap_state *cstate = &chap[unit];
-       
-       cstate->resp_name = our_name;
-       cstate->resp_type = digest;
-       
-       if (cstate->clientstate == CHAPCS_INITIAL ||
-                       cstate->clientstate == CHAPCS_PENDING) {
-               /* lower layer isn't up - wait until later */
-               cstate->clientstate = CHAPCS_PENDING;
-               return;
-       }
-       
-       /*
-        * We get here as a result of LCP coming up.
-        * So even if CHAP was open before, we will 
-        * have to re-authenticate ourselves.
-        */
-       cstate->clientstate = CHAPCS_LISTEN;
-}
-
-
-/*
- * ChapAuthPeer - Authenticate our peer (start server).
- */
-void ChapAuthPeer(int unit, char *our_name, int digest)
-{
-       chap_state *cstate = &chap[unit];
-       
-       cstate->chal_name = our_name;
-       cstate->chal_type = digest;
-       
-       if (cstate->serverstate == CHAPSS_INITIAL ||
-                       cstate->serverstate == CHAPSS_PENDING) {
-               /* lower layer isn't up - wait until later */
-               cstate->serverstate = CHAPSS_PENDING;
-               return;
-       }
-       
-       ChapGenChallenge(cstate);
-       ChapSendChallenge(cstate);              /* crank it up dude! */
-       cstate->serverstate = CHAPSS_INITIAL_CHAL;
-}
-
-
-
-
-/**********************************/
-/*** LOCAL FUNCTION DEFINITIONS ***/
-/**********************************/
-/*
- * ChapInit - Initialize a CHAP unit.
- */
-static void ChapInit(int unit)
-{
-       chap_state *cstate = &chap[unit];
-       
-       BZERO(cstate, sizeof(*cstate));
-       cstate->unit = unit;
-       cstate->clientstate = CHAPCS_INITIAL;
-       cstate->serverstate = CHAPSS_INITIAL;
-       cstate->timeouttime = CHAP_DEFTIMEOUT;
-       cstate->max_transmits = CHAP_DEFTRANSMITS;
-       /* random number generator is initialized in magic_init */
-}
-
-
-/*
- * ChapChallengeTimeout - Timeout expired on sending challenge.
- */
-static void ChapChallengeTimeout(void *arg)
-{
-       chap_state *cstate = (chap_state *) arg;
-       
-       /* if we aren't sending challenges, don't worry.  then again we */
-       /* probably shouldn't be here either */
-       if (cstate->serverstate != CHAPSS_INITIAL_CHAL &&
-                       cstate->serverstate != CHAPSS_RECHALLENGE)
-               return;
-       
-       if (cstate->chal_transmits >= cstate->max_transmits) {
-               /* give up on peer */
-               CHAPDEBUG((LOG_ERR, "Peer failed to respond to CHAP challenge\n"));
-               cstate->serverstate = CHAPSS_BADAUTH;
-               auth_peer_fail(cstate->unit, PPP_CHAP);
-               return;
-       }
-       
-       ChapSendChallenge(cstate);              /* Re-send challenge */
-}
-
-
-/*
- * ChapResponseTimeout - Timeout expired on sending response.
- */
-static void ChapResponseTimeout(void *arg)
-{
-       chap_state *cstate = (chap_state *) arg;
-       
-       /* if we aren't sending a response, don't worry. */
-       if (cstate->clientstate != CHAPCS_RESPONSE)
-               return;
-       
-       ChapSendResponse(cstate);               /* re-send response */
-}
-
-
-/*
- * ChapRechallenge - Time to challenge the peer again.
- */
-static void ChapRechallenge(void *arg)
-{
-       chap_state *cstate = (chap_state *) arg;
-       
-       /* if we aren't sending a response, don't worry. */
-       if (cstate->serverstate != CHAPSS_OPEN)
-               return;
-       
-       ChapGenChallenge(cstate);
-       ChapSendChallenge(cstate);
-       cstate->serverstate = CHAPSS_RECHALLENGE;
-}
-
-
-/*
- * ChapLowerUp - The lower layer is up.
- *
- * Start up if we have pending requests.
- */
-static void ChapLowerUp(int unit)
-{
-       chap_state *cstate = &chap[unit];
-       
-       if (cstate->clientstate == CHAPCS_INITIAL)
-               cstate->clientstate = CHAPCS_CLOSED;
-       else if (cstate->clientstate == CHAPCS_PENDING)
-               cstate->clientstate = CHAPCS_LISTEN;
-       
-       if (cstate->serverstate == CHAPSS_INITIAL)
-               cstate->serverstate = CHAPSS_CLOSED;
-       else if (cstate->serverstate == CHAPSS_PENDING) {
-               ChapGenChallenge(cstate);
-               ChapSendChallenge(cstate);
-               cstate->serverstate = CHAPSS_INITIAL_CHAL;
-       }
-}
-
-
-/*
- * ChapLowerDown - The lower layer is down.
- *
- * Cancel all timeouts.
- */
-static void ChapLowerDown(int unit)
-{
-       chap_state *cstate = &chap[unit];
-       
-       /* Timeout(s) pending?  Cancel if so. */
-       if (cstate->serverstate == CHAPSS_INITIAL_CHAL ||
-                       cstate->serverstate == CHAPSS_RECHALLENGE)
-               UNTIMEOUT(ChapChallengeTimeout, cstate);
-       else if (cstate->serverstate == CHAPSS_OPEN
-                       && cstate->chal_interval != 0)
-               UNTIMEOUT(ChapRechallenge, cstate);
-       if (cstate->clientstate == CHAPCS_RESPONSE)
-               UNTIMEOUT(ChapResponseTimeout, cstate);
-       
-       cstate->clientstate = CHAPCS_INITIAL;
-       cstate->serverstate = CHAPSS_INITIAL;
-}
-
-
-/*
- * ChapProtocolReject - Peer doesn't grok CHAP.
- */
-static void ChapProtocolReject(int unit)
-{
-       chap_state *cstate = &chap[unit];
-       
-       if (cstate->serverstate != CHAPSS_INITIAL &&
-                       cstate->serverstate != CHAPSS_CLOSED)
-               auth_peer_fail(unit, PPP_CHAP);
-       if (cstate->clientstate != CHAPCS_INITIAL &&
-                       cstate->clientstate != CHAPCS_CLOSED)
-               auth_withpeer_fail(unit, PPP_CHAP);
-       ChapLowerDown(unit);            /* shutdown chap */
-}
-
-
-/*
- * ChapInput - Input CHAP packet.
- */
-static void ChapInput(int unit, u_char *inpacket, int packet_len)
-{
-       chap_state *cstate = &chap[unit];
-       u_char *inp;
-       u_char code, id;
-       int len;
-       
-       /*
-        * Parse header (code, id and length).
-        * If packet too short, drop it.
-        */
-       inp = inpacket;
-       if (packet_len < CHAP_HEADERLEN) {
-               CHAPDEBUG((LOG_INFO, "ChapInput: rcvd short header.\n"));
-               return;
-       }
-       GETCHAR(code, inp);
-       GETCHAR(id, inp);
-       GETSHORT(len, inp);
-       if (len < CHAP_HEADERLEN) {
-               CHAPDEBUG((LOG_INFO, "ChapInput: rcvd illegal length.\n"));
-               return;
-       }
-       if (len > packet_len) {
-               CHAPDEBUG((LOG_INFO, "ChapInput: rcvd short packet.\n"));
-               return;
-       }
-       len -= CHAP_HEADERLEN;
-       
-       /*
-        * Action depends on code (as in fact it usually does :-).
-        */
-       switch (code) {
-       case CHAP_CHALLENGE:
-               ChapReceiveChallenge(cstate, inp, id, len);
-               break;
-       
-       case CHAP_RESPONSE:
-               ChapReceiveResponse(cstate, inp, id, len);
-               break;
-       
-       case CHAP_FAILURE:
-               ChapReceiveFailure(cstate, inp, id, len);
-               break;
-       
-       case CHAP_SUCCESS:
-               ChapReceiveSuccess(cstate, inp, id, len);
-               break;
-       
-       default:                                /* Need code reject? */
-               CHAPDEBUG((LOG_WARNING, "Unknown CHAP code (%d) received.\n", code));
-               break;
-       }
-}
-
-
-/*
- * ChapReceiveChallenge - Receive Challenge and send Response.
- */
-static void ChapReceiveChallenge(chap_state *cstate, u_char *inp, int id, int len)
-{
-       int rchallenge_len;
-       u_char *rchallenge;
-       int secret_len;
-       char secret[MAXSECRETLEN];
-       char rhostname[256];
-       MD5_CTX mdContext;
-       u_char hash[MD5_SIGNATURE_SIZE];
-       
-       CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: Rcvd id %d.\n", id));
-       if (cstate->clientstate == CHAPCS_CLOSED ||
-               cstate->clientstate == CHAPCS_PENDING) {
-               CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: in state %d\n",
-                          cstate->clientstate));
-               return;
-       }
-       
-       if (len < 2) {
-               CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: rcvd short packet.\n"));
-               return;
-       }
-       
-       GETCHAR(rchallenge_len, inp);
-       len -= sizeof (u_char) + rchallenge_len;        /* now name field length */
-       if (len < 0) {
-               CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: rcvd short packet.\n"));
-               return;
-       }
-       rchallenge = inp;
-       INCPTR(rchallenge_len, inp);
-       
-       if (len >= sizeof(rhostname))
-               len = sizeof(rhostname) - 1;
-       BCOPY(inp, rhostname, len);
-       rhostname[len] = '\000';
-       
-       CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: received name field '%s'\n",
-              rhostname));
-       
-       /* Microsoft doesn't send their name back in the PPP packet */
-       if (ppp_settings.remote_name[0] != 0 && (ppp_settings.explicit_remote || rhostname[0] == 0)) {
-               strncpy(rhostname, ppp_settings.remote_name, sizeof(rhostname));
-               rhostname[sizeof(rhostname) - 1] = 0;
-               CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: using '%s' as remote name\n",
-                          rhostname));
-       }
-       
-       /* get secret for authenticating ourselves with the specified host */
-       if (!get_secret(cstate->unit, cstate->resp_name, rhostname,
-                           secret, &secret_len, 0)) {
-               secret_len = 0;         /* assume null secret if can't find one */
-               CHAPDEBUG((LOG_WARNING, "No CHAP secret found for authenticating us to %s\n", rhostname));
-       }
-       
-       /* cancel response send timeout if necessary */
-       if (cstate->clientstate == CHAPCS_RESPONSE)
-               UNTIMEOUT(ChapResponseTimeout, cstate);
-       
-       cstate->resp_id = id;
-       cstate->resp_transmits = 0;
-       
-       /*  generate MD based on negotiated type */
-       switch (cstate->resp_type) { 
-       
-       case CHAP_DIGEST_MD5:
-               MD5Init(&mdContext);
-               MD5Update(&mdContext, &cstate->resp_id, 1);
-               MD5Update(&mdContext, (u_char*)secret, secret_len);
-               MD5Update(&mdContext, rchallenge, rchallenge_len);
-               MD5Final(hash, &mdContext);
-               BCOPY(hash, cstate->response, MD5_SIGNATURE_SIZE);
-               cstate->resp_length = MD5_SIGNATURE_SIZE;
-               break;
-       
-#ifdef CHAPMS
-       case CHAP_MICROSOFT:
-               ChapMS(cstate, rchallenge, rchallenge_len, secret, secret_len);
-               break;
-#endif
-       
-       default:
-               CHAPDEBUG((LOG_INFO, "unknown digest type %d\n", cstate->resp_type));
-               return;
-       }
-       
-       BZERO(secret, sizeof(secret));
-       ChapSendResponse(cstate);
-}
-
-
-/*
- * ChapReceiveResponse - Receive and process response.
- */
-static void ChapReceiveResponse(chap_state *cstate, u_char *inp, int id, int len)
-{
-       u_char *remmd, remmd_len;
-       int secret_len, old_state;
-       int code;
-       char rhostname[256];
-       MD5_CTX mdContext;
-       char secret[MAXSECRETLEN];
-       u_char hash[MD5_SIGNATURE_SIZE];
-       
-       CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: Rcvd id %d.\n", id));
-       
-       if (cstate->serverstate == CHAPSS_CLOSED ||
-                       cstate->serverstate == CHAPSS_PENDING) {
-               CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: in state %d\n",
-               cstate->serverstate));
-               return;
-       }
-       
-       if (id != cstate->chal_id)
-               return;                 /* doesn't match ID of last challenge */
-       
-       /*
-       * If we have received a duplicate or bogus Response,
-       * we have to send the same answer (Success/Failure)
-       * as we did for the first Response we saw.
-       */
-       if (cstate->serverstate == CHAPSS_OPEN) {
-               ChapSendStatus(cstate, CHAP_SUCCESS);
-               return;
-       }
-       if (cstate->serverstate == CHAPSS_BADAUTH) {
-               ChapSendStatus(cstate, CHAP_FAILURE);
-               return;
-       }
-       
-       if (len < 2) {
-               CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: rcvd short packet.\n"));
-               return;
-       }
-       GETCHAR(remmd_len, inp);                /* get length of MD */
-       remmd = inp;                    /* get pointer to MD */
-       INCPTR(remmd_len, inp);
-       
-       len -= sizeof (u_char) + remmd_len;
-       if (len < 0) {
-               CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: rcvd short packet.\n"));
-               return;
-       }
-       
-       UNTIMEOUT(ChapChallengeTimeout, cstate);
-       
-       if (len >= sizeof(rhostname))
-               len = sizeof(rhostname) - 1;
-       BCOPY(inp, rhostname, len);
-       rhostname[len] = '\000';
-       
-       CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: received name field: %s\n",
-                               rhostname));
-       
-       /*
-       * Get secret for authenticating them with us,
-       * do the hash ourselves, and compare the result.
-       */
-       code = CHAP_FAILURE;
-       if (!get_secret(cstate->unit, rhostname, cstate->chal_name,
-       secret, &secret_len, 1)) {
-/*        CHAPDEBUG((LOG_WARNING, TL_CHAP, "No CHAP secret found for authenticating %s\n", rhostname)); */
-               CHAPDEBUG((LOG_WARNING, "No CHAP secret found for authenticating %s\n",
-               rhostname));
-       } else {
-       
-               /*  generate MD based on negotiated type */
-               switch (cstate->chal_type) { 
-               
-               case CHAP_DIGEST_MD5:           /* only MD5 is defined for now */
-                       if (remmd_len != MD5_SIGNATURE_SIZE)
-                               break;                  /* it's not even the right length */
-                       MD5Init(&mdContext);
-                       MD5Update(&mdContext, &cstate->chal_id, 1);
-                       MD5Update(&mdContext, (u_char*)secret, secret_len);
-                       MD5Update(&mdContext, cstate->challenge, cstate->chal_len);
-                       MD5Final(hash, &mdContext); 
-                       
-                       /* compare local and remote MDs and send the appropriate status */
-                       if (memcmp (hash, remmd, MD5_SIGNATURE_SIZE) == 0)
-                               code = CHAP_SUCCESS;    /* they are the same! */
-                       break;
-               
-               default:
-                       CHAPDEBUG((LOG_INFO, "unknown digest type %d\n", cstate->chal_type));
-               }
-       }
-       
-       BZERO(secret, sizeof(secret));
-       ChapSendStatus(cstate, code);
-       
-       if (code == CHAP_SUCCESS) {
-               old_state = cstate->serverstate;
-               cstate->serverstate = CHAPSS_OPEN;
-               if (old_state == CHAPSS_INITIAL_CHAL) {
-                       auth_peer_success(cstate->unit, PPP_CHAP, rhostname, len);
-               }
-               if (cstate->chal_interval != 0)
-                       TIMEOUT(ChapRechallenge, cstate, cstate->chal_interval);
-       } else {
-               CHAPDEBUG((LOG_ERR, "CHAP peer authentication failed\n"));
-               cstate->serverstate = CHAPSS_BADAUTH;
-               auth_peer_fail(cstate->unit, PPP_CHAP);
-       }
-}
-
-/*
- * ChapReceiveSuccess - Receive Success
- */
-static void ChapReceiveSuccess(chap_state *cstate, u_char *inp, u_char id, int len)
-{
-
-       CHAPDEBUG((LOG_INFO, "ChapReceiveSuccess: Rcvd id %d.\n", id));
-       
-       if (cstate->clientstate == CHAPCS_OPEN)
-               /* presumably an answer to a duplicate response */
-               return;
-       
-       if (cstate->clientstate != CHAPCS_RESPONSE) {
-               /* don't know what this is */
-               CHAPDEBUG((LOG_INFO, "ChapReceiveSuccess: in state %d\n",
-                          cstate->clientstate));
-               return;
-       }
-       
-       UNTIMEOUT(ChapResponseTimeout, cstate);
-       
-       /*
-        * Print message.
-        */
-       if (len > 0)
-               PRINTMSG(inp, len);
-       
-       cstate->clientstate = CHAPCS_OPEN;
-       
-       auth_withpeer_success(cstate->unit, PPP_CHAP);
-}
-
-
-/*
- * ChapReceiveFailure - Receive failure.
- */
-static void ChapReceiveFailure(chap_state *cstate, u_char *inp, u_char id, int len)
-{
-       CHAPDEBUG((LOG_INFO, "ChapReceiveFailure: Rcvd id %d.\n", id));
-       
-       if (cstate->clientstate != CHAPCS_RESPONSE) {
-               /* don't know what this is */
-               CHAPDEBUG((LOG_INFO, "ChapReceiveFailure: in state %d\n",
-                          cstate->clientstate));
-               return;
-       }
-       
-       UNTIMEOUT(ChapResponseTimeout, cstate);
-       
-       /*
-        * Print message.
-        */
-       if (len > 0)
-               PRINTMSG(inp, len);
-       
-       CHAPDEBUG((LOG_ERR, "CHAP authentication failed\n"));
-       auth_withpeer_fail(cstate->unit, PPP_CHAP);
-}
-
-
-/*
- * ChapSendChallenge - Send an Authenticate challenge.
- */
-static void ChapSendChallenge(chap_state *cstate)
-{
-       u_char *outp;
-       int chal_len, name_len;
-       int outlen;
-       
-       chal_len = cstate->chal_len;
-       name_len = strlen(cstate->chal_name);
-       outlen = CHAP_HEADERLEN + sizeof (u_char) + chal_len + name_len;
-       outp = outpacket_buf[cstate->unit];
-       
-       MAKEHEADER(outp, PPP_CHAP);             /* paste in a CHAP header */
-       
-       PUTCHAR(CHAP_CHALLENGE, outp);
-       PUTCHAR(cstate->chal_id, outp);
-       PUTSHORT(outlen, outp);
-       
-       PUTCHAR(chal_len, outp);                /* put length of challenge */
-       BCOPY(cstate->challenge, outp, chal_len);
-       INCPTR(chal_len, outp);
-       
-       BCOPY(cstate->chal_name, outp, name_len);       /* append hostname */
-       
-       pppWrite(cstate->unit, outpacket_buf[cstate->unit], outlen + PPP_HDRLEN);
-       
-       CHAPDEBUG((LOG_INFO, "ChapSendChallenge: Sent id %d.\n", cstate->chal_id));
-       
-       TIMEOUT(ChapChallengeTimeout, cstate, cstate->timeouttime);
-       ++cstate->chal_transmits;
-}
-
-
-/*
- * ChapSendStatus - Send a status response (ack or nak).
- */
-static void ChapSendStatus(chap_state *cstate, int code)
-{
-       u_char *outp;
-       int outlen, msglen;
-       char msg[256];
-       
-       if (code == CHAP_SUCCESS)
-               strcpy(msg, "Welcome!");
-       else
-               strcpy(msg, "I don't like you.  Go 'way.");
-       msglen = strlen(msg);
-       
-       outlen = CHAP_HEADERLEN + msglen;
-       outp = outpacket_buf[cstate->unit];
-       
-       MAKEHEADER(outp, PPP_CHAP);             /* paste in a header */
-       
-       PUTCHAR(code, outp);
-       PUTCHAR(cstate->chal_id, outp);
-       PUTSHORT(outlen, outp);
-       BCOPY(msg, outp, msglen);
-       pppWrite(cstate->unit, outpacket_buf[cstate->unit], outlen + PPP_HDRLEN);
-       
-       CHAPDEBUG((LOG_INFO, "ChapSendStatus: Sent code %d, id %d.\n", code,
-              cstate->chal_id));
-}
-
-/*
- * ChapGenChallenge is used to generate a pseudo-random challenge string of
- * a pseudo-random length between min_len and max_len.  The challenge
- * string and its length are stored in *cstate, and various other fields of
- * *cstate are initialized.
- */
-
-static void ChapGenChallenge(chap_state *cstate)
-{
-       int chal_len;
-       u_char *ptr = cstate->challenge;
-       int i;
-       
-       /* pick a random challenge length between MIN_CHALLENGE_LENGTH and 
-          MAX_CHALLENGE_LENGTH */  
-       chal_len = (unsigned)
-                               ((((magic() >> 16) *
-                               (MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH)) >> 16)
-                            + MIN_CHALLENGE_LENGTH);
-       cstate->chal_len = chal_len;
-       cstate->chal_id = ++cstate->id;
-       cstate->chal_transmits = 0;
-       
-       /* generate a random string */
-       for (i = 0; i < chal_len; i++ )
-               *ptr++ = (char) (magic() & 0xff);
-}
-
-/*
- * ChapSendResponse - send a response packet with values as specified
- * in *cstate.
- */
-/* ARGSUSED */
-static void ChapSendResponse(chap_state *cstate)
-{
-       u_char *outp;
-       int outlen, md_len, name_len;
-       
-       md_len = cstate->resp_length;
-       name_len = strlen(cstate->resp_name);
-       outlen = CHAP_HEADERLEN + sizeof (u_char) + md_len + name_len;
-       outp = outpacket_buf[cstate->unit];
-       
-       MAKEHEADER(outp, PPP_CHAP);
-       
-       PUTCHAR(CHAP_RESPONSE, outp);   /* we are a response */
-       PUTCHAR(cstate->resp_id, outp); /* copy id from challenge packet */
-       PUTSHORT(outlen, outp);                 /* packet length */
-       
-       PUTCHAR(md_len, outp);                  /* length of MD */
-       BCOPY(cstate->response, outp, md_len);          /* copy MD to buffer */
-       INCPTR(md_len, outp);
-       
-       BCOPY(cstate->resp_name, outp, name_len);       /* append our name */
-       
-       /* send the packet */
-       pppWrite(cstate->unit, outpacket_buf[cstate->unit], outlen + PPP_HDRLEN);
-       
-       cstate->clientstate = CHAPCS_RESPONSE;
-       TIMEOUT(ChapResponseTimeout, cstate, cstate->timeouttime);
-       ++cstate->resp_transmits;
-}
-
-/*
- * ChapPrintPkt - print the contents of a CHAP packet.
- */
-static int ChapPrintPkt(
-       u_char *p,
-       int plen,
-       void (*printer) (void *, char *, ...),
-       void *arg
-)
-{
-       int code, id, len;
-       int clen, nlen;
-       u_char x;
-       
-       if (plen < CHAP_HEADERLEN)
-               return 0;
-       GETCHAR(code, p);
-       GETCHAR(id, p);
-       GETSHORT(len, p);
-       if (len < CHAP_HEADERLEN || len > plen)
-               return 0;
-       
-       if (code >= 1 && code <= sizeof(ChapCodenames) / sizeof(char *))
-               printer(arg, " %s", ChapCodenames[code-1]);
-       else
-               printer(arg, " code=0x%x", code);
-       printer(arg, " id=0x%x", id);
-       len -= CHAP_HEADERLEN;
-       switch (code) {
-       case CHAP_CHALLENGE:
-       case CHAP_RESPONSE:
-               if (len < 1)
-                       break;
-               clen = p[0];
-               if (len < clen + 1)
-                       break;
-               ++p;
-               nlen = len - clen - 1;
-               printer(arg, " <");
-               for (; clen > 0; --clen) {
-                       GETCHAR(x, p);
-                       printer(arg, "%.2x", x);
-               }
-               printer(arg, ">, name = %.*Z", nlen, p);
-               break;
-       case CHAP_FAILURE:
-       case CHAP_SUCCESS:
-               printer(arg, " %.*Z", len, p);
-               break;
-       default:
-               for (clen = len; clen > 0; --clen) {
-                       GETCHAR(x, p);
-                       printer(arg, " %.2x", x);
-               }
-       }
-       
-       return len + CHAP_HEADERLEN;
-}
-
-#endif
-
-#endif /* PPP_SUPPORT */
+/*** WARNING - THIS HAS NEVER BEEN FINISHED ***/\r
+/*****************************************************************************\r
+* chap.c - Network Challenge Handshake Authentication Protocol program file.\r
+*\r
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.\r
+* portions Copyright (c) 1997 by Global Election Systems Inc.\r
+*\r
+* The authors hereby grant permission to use, copy, modify, distribute,\r
+* and license this software and its documentation for any purpose, provided\r
+* that existing copyright notices are retained in all copies and that this\r
+* notice and the following disclaimer are included verbatim in any \r
+* distributions. No written agreement, license, or royalty fee is required\r
+* for any of the authorized uses.\r
+*\r
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR\r
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+*\r
+******************************************************************************\r
+* REVISION HISTORY\r
+*\r
+* 03-01-01 Marc Boucher <marc@mbsi.ca>\r
+*   Ported to lwIP.\r
+* 97-12-04 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.\r
+*      Original based on BSD chap.c.\r
+*****************************************************************************/\r
+/*\r
+ * chap.c - Challenge Handshake Authentication Protocol.\r
+ *\r
+ * Copyright (c) 1993 The Australian National University.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms are permitted\r
+ * provided that the above copyright notice and this paragraph are\r
+ * duplicated in all such forms and that any documentation,\r
+ * advertising materials, and other materials related to such\r
+ * distribution and use acknowledge that the software was developed\r
+ * by the Australian National University.  The name of the University\r
+ * may not be used to endorse or promote products derived from this\r
+ * software without specific prior written permission.\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR\r
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r
+ *\r
+ * Copyright (c) 1991 Gregory M. Christy.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms are permitted\r
+ * provided that the above copyright notice and this paragraph are\r
+ * duplicated in all such forms and that any documentation,\r
+ * advertising materials, and other materials related to such\r
+ * distribution and use acknowledge that the software was developed\r
+ * by Gregory M. Christy.  The name of the author may not be used to\r
+ * endorse or promote products derived from this software without\r
+ * specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR\r
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r
+ */\r
+\r
+#include "ppp.h"\r
+#if PPP_SUPPORT > 0\r
+#include "magic.h"\r
+\r
+#if CHAP_SUPPORT > 0\r
+\r
+#include "randm.h"\r
+#include "auth.h"\r
+#include "md5.h"\r
+#include "chap.h"\r
+#include "chpms.h"\r
+#include "pppdebug.h"\r
+\r
+\r
+/*************************/\r
+/*** LOCAL DEFINITIONS ***/\r
+/*************************/\r
+\r
+\r
+/************************/\r
+/*** LOCAL DATA TYPES ***/\r
+/************************/\r
+\r
+\r
+/***********************************/\r
+/*** LOCAL FUNCTION DECLARATIONS ***/\r
+/***********************************/\r
+/*\r
+ * Protocol entry points.\r
+ */\r
+static void ChapInit (int);\r
+static void ChapLowerUp (int);\r
+static void ChapLowerDown (int);\r
+static void ChapInput (int, u_char *, int);\r
+static void ChapProtocolReject (int);\r
+static int  ChapPrintPkt (u_char *, int,\r
+                             void (*) (void *, char *, ...), void *);\r
+\r
+static void ChapChallengeTimeout (void *);\r
+static void ChapResponseTimeout (void *);\r
+static void ChapReceiveChallenge (chap_state *, u_char *, int, int);\r
+static void ChapRechallenge (void *);\r
+static void ChapReceiveResponse (chap_state *, u_char *, int, int);\r
+static void ChapReceiveSuccess(chap_state *cstate, u_char *inp, u_char id, int len);\r
+static void ChapReceiveFailure(chap_state *cstate, u_char *inp, u_char id, int len);\r
+static void ChapSendStatus (chap_state *, int);\r
+static void ChapSendChallenge (chap_state *);\r
+static void ChapSendResponse (chap_state *);\r
+static void ChapGenChallenge (chap_state *);\r
+\r
+\r
+/******************************/\r
+/*** PUBLIC DATA STRUCTURES ***/\r
+/******************************/\r
+chap_state chap[NUM_PPP];              /* CHAP state; one for each unit */\r
+\r
+struct protent chap_protent = {\r
+    PPP_CHAP,\r
+    ChapInit,\r
+    ChapInput,\r
+    ChapProtocolReject,\r
+    ChapLowerUp,\r
+    ChapLowerDown,\r
+    NULL,\r
+    NULL,\r
+#if 0\r
+    ChapPrintPkt,\r
+    NULL,\r
+#endif\r
+    1,\r
+    "CHAP",\r
+#if 0\r
+    NULL,\r
+    NULL,\r
+    NULL\r
+#endif\r
+};\r
+\r
+\r
+\r
+/*****************************/\r
+/*** LOCAL DATA STRUCTURES ***/\r
+/*****************************/\r
+static char *ChapCodenames[] = {\r
+       "Challenge", "Response", "Success", "Failure"\r
+};\r
+\r
+\r
+\r
+/***********************************/\r
+/*** PUBLIC FUNCTION DEFINITIONS ***/\r
+/***********************************/\r
+/*\r
+ * ChapAuthWithPeer - Authenticate us with our peer (start client).\r
+ *\r
+ */\r
+void ChapAuthWithPeer(int unit, char *our_name, int digest)\r
+{\r
+       chap_state *cstate = &chap[unit];\r
+       \r
+       cstate->resp_name = our_name;\r
+       cstate->resp_type = digest;\r
+       \r
+       if (cstate->clientstate == CHAPCS_INITIAL ||\r
+                       cstate->clientstate == CHAPCS_PENDING) {\r
+               /* lower layer isn't up - wait until later */\r
+               cstate->clientstate = CHAPCS_PENDING;\r
+               return;\r
+       }\r
+       \r
+       /*\r
+        * We get here as a result of LCP coming up.\r
+        * So even if CHAP was open before, we will \r
+        * have to re-authenticate ourselves.\r
+        */\r
+       cstate->clientstate = CHAPCS_LISTEN;\r
+}\r
+\r
+\r
+/*\r
+ * ChapAuthPeer - Authenticate our peer (start server).\r
+ */\r
+void ChapAuthPeer(int unit, char *our_name, int digest)\r
+{\r
+       chap_state *cstate = &chap[unit];\r
+       \r
+       cstate->chal_name = our_name;\r
+       cstate->chal_type = digest;\r
+       \r
+       if (cstate->serverstate == CHAPSS_INITIAL ||\r
+                       cstate->serverstate == CHAPSS_PENDING) {\r
+               /* lower layer isn't up - wait until later */\r
+               cstate->serverstate = CHAPSS_PENDING;\r
+               return;\r
+       }\r
+       \r
+       ChapGenChallenge(cstate);\r
+       ChapSendChallenge(cstate);              /* crank it up dude! */\r
+       cstate->serverstate = CHAPSS_INITIAL_CHAL;\r
+}\r
+\r
+\r
+\r
+\r
+/**********************************/\r
+/*** LOCAL FUNCTION DEFINITIONS ***/\r
+/**********************************/\r
+/*\r
+ * ChapInit - Initialize a CHAP unit.\r
+ */\r
+static void ChapInit(int unit)\r
+{\r
+       chap_state *cstate = &chap[unit];\r
+       \r
+       BZERO(cstate, sizeof(*cstate));\r
+       cstate->unit = unit;\r
+       cstate->clientstate = CHAPCS_INITIAL;\r
+       cstate->serverstate = CHAPSS_INITIAL;\r
+       cstate->timeouttime = CHAP_DEFTIMEOUT;\r
+       cstate->max_transmits = CHAP_DEFTRANSMITS;\r
+       /* random number generator is initialized in magic_init */\r
+}\r
+\r
+\r
+/*\r
+ * ChapChallengeTimeout - Timeout expired on sending challenge.\r
+ */\r
+static void ChapChallengeTimeout(void *arg)\r
+{\r
+       chap_state *cstate = (chap_state *) arg;\r
+       \r
+       /* if we aren't sending challenges, don't worry.  then again we */\r
+       /* probably shouldn't be here either */\r
+       if (cstate->serverstate != CHAPSS_INITIAL_CHAL &&\r
+                       cstate->serverstate != CHAPSS_RECHALLENGE)\r
+               return;\r
+       \r
+       if (cstate->chal_transmits >= cstate->max_transmits) {\r
+               /* give up on peer */\r
+               CHAPDEBUG((LOG_ERR, "Peer failed to respond to CHAP challenge\n"));\r
+               cstate->serverstate = CHAPSS_BADAUTH;\r
+               auth_peer_fail(cstate->unit, PPP_CHAP);\r
+               return;\r
+       }\r
+       \r
+       ChapSendChallenge(cstate);              /* Re-send challenge */\r
+}\r
+\r
+\r
+/*\r
+ * ChapResponseTimeout - Timeout expired on sending response.\r
+ */\r
+static void ChapResponseTimeout(void *arg)\r
+{\r
+       chap_state *cstate = (chap_state *) arg;\r
+       \r
+       /* if we aren't sending a response, don't worry. */\r
+       if (cstate->clientstate != CHAPCS_RESPONSE)\r
+               return;\r
+       \r
+       ChapSendResponse(cstate);               /* re-send response */\r
+}\r
+\r
+\r
+/*\r
+ * ChapRechallenge - Time to challenge the peer again.\r
+ */\r
+static void ChapRechallenge(void *arg)\r
+{\r
+       chap_state *cstate = (chap_state *) arg;\r
+       \r
+       /* if we aren't sending a response, don't worry. */\r
+       if (cstate->serverstate != CHAPSS_OPEN)\r
+               return;\r
+       \r
+       ChapGenChallenge(cstate);\r
+       ChapSendChallenge(cstate);\r
+       cstate->serverstate = CHAPSS_RECHALLENGE;\r
+}\r
+\r
+\r
+/*\r
+ * ChapLowerUp - The lower layer is up.\r
+ *\r
+ * Start up if we have pending requests.\r
+ */\r
+static void ChapLowerUp(int unit)\r
+{\r
+       chap_state *cstate = &chap[unit];\r
+       \r
+       if (cstate->clientstate == CHAPCS_INITIAL)\r
+               cstate->clientstate = CHAPCS_CLOSED;\r
+       else if (cstate->clientstate == CHAPCS_PENDING)\r
+               cstate->clientstate = CHAPCS_LISTEN;\r
+       \r
+       if (cstate->serverstate == CHAPSS_INITIAL)\r
+               cstate->serverstate = CHAPSS_CLOSED;\r
+       else if (cstate->serverstate == CHAPSS_PENDING) {\r
+               ChapGenChallenge(cstate);\r
+               ChapSendChallenge(cstate);\r
+               cstate->serverstate = CHAPSS_INITIAL_CHAL;\r
+       }\r
+}\r
+\r
+\r
+/*\r
+ * ChapLowerDown - The lower layer is down.\r
+ *\r
+ * Cancel all timeouts.\r
+ */\r
+static void ChapLowerDown(int unit)\r
+{\r
+       chap_state *cstate = &chap[unit];\r
+       \r
+       /* Timeout(s) pending?  Cancel if so. */\r
+       if (cstate->serverstate == CHAPSS_INITIAL_CHAL ||\r
+                       cstate->serverstate == CHAPSS_RECHALLENGE)\r
+               UNTIMEOUT(ChapChallengeTimeout, cstate);\r
+       else if (cstate->serverstate == CHAPSS_OPEN\r
+                       && cstate->chal_interval != 0)\r
+               UNTIMEOUT(ChapRechallenge, cstate);\r
+       if (cstate->clientstate == CHAPCS_RESPONSE)\r
+               UNTIMEOUT(ChapResponseTimeout, cstate);\r
+       \r
+       cstate->clientstate = CHAPCS_INITIAL;\r
+       cstate->serverstate = CHAPSS_INITIAL;\r
+}\r
+\r
+\r
+/*\r
+ * ChapProtocolReject - Peer doesn't grok CHAP.\r
+ */\r
+static void ChapProtocolReject(int unit)\r
+{\r
+       chap_state *cstate = &chap[unit];\r
+       \r
+       if (cstate->serverstate != CHAPSS_INITIAL &&\r
+                       cstate->serverstate != CHAPSS_CLOSED)\r
+               auth_peer_fail(unit, PPP_CHAP);\r
+       if (cstate->clientstate != CHAPCS_INITIAL &&\r
+                       cstate->clientstate != CHAPCS_CLOSED)\r
+               auth_withpeer_fail(unit, PPP_CHAP);\r
+       ChapLowerDown(unit);            /* shutdown chap */\r
+}\r
+\r
+\r
+/*\r
+ * ChapInput - Input CHAP packet.\r
+ */\r
+static void ChapInput(int unit, u_char *inpacket, int packet_len)\r
+{\r
+       chap_state *cstate = &chap[unit];\r
+       u_char *inp;\r
+       u_char code, id;\r
+       int len;\r
+       \r
+       /*\r
+        * Parse header (code, id and length).\r
+        * If packet too short, drop it.\r
+        */\r
+       inp = inpacket;\r
+       if (packet_len < CHAP_HEADERLEN) {\r
+               CHAPDEBUG((LOG_INFO, "ChapInput: rcvd short header.\n"));\r
+               return;\r
+       }\r
+       GETCHAR(code, inp);\r
+       GETCHAR(id, inp);\r
+       GETSHORT(len, inp);\r
+       if (len < CHAP_HEADERLEN) {\r
+               CHAPDEBUG((LOG_INFO, "ChapInput: rcvd illegal length.\n"));\r
+               return;\r
+       }\r
+       if (len > packet_len) {\r
+               CHAPDEBUG((LOG_INFO, "ChapInput: rcvd short packet.\n"));\r
+               return;\r
+       }\r
+       len -= CHAP_HEADERLEN;\r
+       \r
+       /*\r
+        * Action depends on code (as in fact it usually does :-).\r
+        */\r
+       switch (code) {\r
+       case CHAP_CHALLENGE:\r
+               ChapReceiveChallenge(cstate, inp, id, len);\r
+               break;\r
+       \r
+       case CHAP_RESPONSE:\r
+               ChapReceiveResponse(cstate, inp, id, len);\r
+               break;\r
+       \r
+       case CHAP_FAILURE:\r
+               ChapReceiveFailure(cstate, inp, id, len);\r
+               break;\r
+       \r
+       case CHAP_SUCCESS:\r
+               ChapReceiveSuccess(cstate, inp, id, len);\r
+               break;\r
+       \r
+       default:                                /* Need code reject? */\r
+               CHAPDEBUG((LOG_WARNING, "Unknown CHAP code (%d) received.\n", code));\r
+               break;\r
+       }\r
+}\r
+\r
+\r
+/*\r
+ * ChapReceiveChallenge - Receive Challenge and send Response.\r
+ */\r
+static void ChapReceiveChallenge(chap_state *cstate, u_char *inp, int id, int len)\r
+{\r
+       int rchallenge_len;\r
+       u_char *rchallenge;\r
+       int secret_len;\r
+       char secret[MAXSECRETLEN];\r
+       char rhostname[256];\r
+       MD5_CTX mdContext;\r
+       u_char hash[MD5_SIGNATURE_SIZE];\r
+       \r
+       CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: Rcvd id %d.\n", id));\r
+       if (cstate->clientstate == CHAPCS_CLOSED ||\r
+               cstate->clientstate == CHAPCS_PENDING) {\r
+               CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: in state %d\n",\r
+                          cstate->clientstate));\r
+               return;\r
+       }\r
+       \r
+       if (len < 2) {\r
+               CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: rcvd short packet.\n"));\r
+               return;\r
+       }\r
+       \r
+       GETCHAR(rchallenge_len, inp);\r
+       len -= sizeof (u_char) + rchallenge_len;        /* now name field length */\r
+       if (len < 0) {\r
+               CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: rcvd short packet.\n"));\r
+               return;\r
+       }\r
+       rchallenge = inp;\r
+       INCPTR(rchallenge_len, inp);\r
+       \r
+       if (len >= sizeof(rhostname))\r
+               len = sizeof(rhostname) - 1;\r
+       BCOPY(inp, rhostname, len);\r
+       rhostname[len] = '\000';\r
+       \r
+       CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: received name field '%s'\n",\r
+              rhostname));\r
+       \r
+       /* Microsoft doesn't send their name back in the PPP packet */\r
+       if (ppp_settings.remote_name[0] != 0 && (ppp_settings.explicit_remote || rhostname[0] == 0)) {\r
+               strncpy(rhostname, ppp_settings.remote_name, sizeof(rhostname));\r
+               rhostname[sizeof(rhostname) - 1] = 0;\r
+               CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: using '%s' as remote name\n",\r
+                          rhostname));\r
+       }\r
+       \r
+       /* get secret for authenticating ourselves with the specified host */\r
+       if (!get_secret(cstate->unit, cstate->resp_name, rhostname,\r
+                           secret, &secret_len, 0)) {\r
+               secret_len = 0;         /* assume null secret if can't find one */\r
+               CHAPDEBUG((LOG_WARNING, "No CHAP secret found for authenticating us to %s\n", rhostname));\r
+       }\r
+       \r
+       /* cancel response send timeout if necessary */\r
+       if (cstate->clientstate == CHAPCS_RESPONSE)\r
+               UNTIMEOUT(ChapResponseTimeout, cstate);\r
+       \r
+       cstate->resp_id = id;\r
+       cstate->resp_transmits = 0;\r
+       \r
+       /*  generate MD based on negotiated type */\r
+       switch (cstate->resp_type) { \r
+       \r
+       case CHAP_DIGEST_MD5:\r
+               MD5Init(&mdContext);\r
+               MD5Update(&mdContext, &cstate->resp_id, 1);\r
+               MD5Update(&mdContext, (u_char*)secret, secret_len);\r
+               MD5Update(&mdContext, rchallenge, rchallenge_len);\r
+               MD5Final(hash, &mdContext);\r
+               BCOPY(hash, cstate->response, MD5_SIGNATURE_SIZE);\r
+               cstate->resp_length = MD5_SIGNATURE_SIZE;\r
+               break;\r
+       \r
+#ifdef CHAPMS\r
+       case CHAP_MICROSOFT:\r
+               ChapMS(cstate, rchallenge, rchallenge_len, secret, secret_len);\r
+               break;\r
+#endif\r
+       \r
+       default:\r
+               CHAPDEBUG((LOG_INFO, "unknown digest type %d\n", cstate->resp_type));\r
+               return;\r
+       }\r
+       \r
+       BZERO(secret, sizeof(secret));\r
+       ChapSendResponse(cstate);\r
+}\r
+\r
+\r
+/*\r
+ * ChapReceiveResponse - Receive and process response.\r
+ */\r
+static void ChapReceiveResponse(chap_state *cstate, u_char *inp, int id, int len)\r
+{\r
+       u_char *remmd, remmd_len;\r
+       int secret_len, old_state;\r
+       int code;\r
+       char rhostname[256];\r
+       MD5_CTX mdContext;\r
+       char secret[MAXSECRETLEN];\r
+       u_char hash[MD5_SIGNATURE_SIZE];\r
+       \r
+       CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: Rcvd id %d.\n", id));\r
+       \r
+       if (cstate->serverstate == CHAPSS_CLOSED ||\r
+                       cstate->serverstate == CHAPSS_PENDING) {\r
+               CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: in state %d\n",\r
+               cstate->serverstate));\r
+               return;\r
+       }\r
+       \r
+       if (id != cstate->chal_id)\r
+               return;                 /* doesn't match ID of last challenge */\r
+       \r
+       /*\r
+       * If we have received a duplicate or bogus Response,\r
+       * we have to send the same answer (Success/Failure)\r
+       * as we did for the first Response we saw.\r
+       */\r
+       if (cstate->serverstate == CHAPSS_OPEN) {\r
+               ChapSendStatus(cstate, CHAP_SUCCESS);\r
+               return;\r
+       }\r
+       if (cstate->serverstate == CHAPSS_BADAUTH) {\r
+               ChapSendStatus(cstate, CHAP_FAILURE);\r
+               return;\r
+       }\r
+       \r
+       if (len < 2) {\r
+               CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: rcvd short packet.\n"));\r
+               return;\r
+       }\r
+       GETCHAR(remmd_len, inp);                /* get length of MD */\r
+       remmd = inp;                    /* get pointer to MD */\r
+       INCPTR(remmd_len, inp);\r
+       \r
+       len -= sizeof (u_char) + remmd_len;\r
+       if (len < 0) {\r
+               CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: rcvd short packet.\n"));\r
+               return;\r
+       }\r
+       \r
+       UNTIMEOUT(ChapChallengeTimeout, cstate);\r
+       \r
+       if (len >= sizeof(rhostname))\r
+               len = sizeof(rhostname) - 1;\r
+       BCOPY(inp, rhostname, len);\r
+       rhostname[len] = '\000';\r
+       \r
+       CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: received name field: %s\n",\r
+                               rhostname));\r
+       \r
+       /*\r
+       * Get secret for authenticating them with us,\r
+       * do the hash ourselves, and compare the result.\r
+       */\r
+       code = CHAP_FAILURE;\r
+       if (!get_secret(cstate->unit, rhostname, cstate->chal_name,\r
+       secret, &secret_len, 1)) {\r
+/*        CHAPDEBUG((LOG_WARNING, TL_CHAP, "No CHAP secret found for authenticating %s\n", rhostname)); */\r
+               CHAPDEBUG((LOG_WARNING, "No CHAP secret found for authenticating %s\n",\r
+               rhostname));\r
+       } else {\r
+       \r
+               /*  generate MD based on negotiated type */\r
+               switch (cstate->chal_type) { \r
+               \r
+               case CHAP_DIGEST_MD5:           /* only MD5 is defined for now */\r
+                       if (remmd_len != MD5_SIGNATURE_SIZE)\r
+                               break;                  /* it's not even the right length */\r
+                       MD5Init(&mdContext);\r
+                       MD5Update(&mdContext, &cstate->chal_id, 1);\r
+                       MD5Update(&mdContext, (u_char*)secret, secret_len);\r
+                       MD5Update(&mdContext, cstate->challenge, cstate->chal_len);\r
+                       MD5Final(hash, &mdContext); \r
+                       \r
+                       /* compare local and remote MDs and send the appropriate status */\r
+                       if (memcmp (hash, remmd, MD5_SIGNATURE_SIZE) == 0)\r
+                               code = CHAP_SUCCESS;    /* they are the same! */\r
+                       break;\r
+               \r
+               default:\r
+                       CHAPDEBUG((LOG_INFO, "unknown digest type %d\n", cstate->chal_type));\r
+               }\r
+       }\r
+       \r
+       BZERO(secret, sizeof(secret));\r
+       ChapSendStatus(cstate, code);\r
+       \r
+       if (code == CHAP_SUCCESS) {\r
+               old_state = cstate->serverstate;\r
+               cstate->serverstate = CHAPSS_OPEN;\r
+               if (old_state == CHAPSS_INITIAL_CHAL) {\r
+                       auth_peer_success(cstate->unit, PPP_CHAP, rhostname, len);\r
+               }\r
+               if (cstate->chal_interval != 0)\r
+                       TIMEOUT(ChapRechallenge, cstate, cstate->chal_interval);\r
+       } else {\r
+               CHAPDEBUG((LOG_ERR, "CHAP peer authentication failed\n"));\r
+               cstate->serverstate = CHAPSS_BADAUTH;\r
+               auth_peer_fail(cstate->unit, PPP_CHAP);\r
+       }\r
+}\r
+\r
+/*\r
+ * ChapReceiveSuccess - Receive Success\r
+ */\r
+static void ChapReceiveSuccess(chap_state *cstate, u_char *inp, u_char id, int len)\r
+{\r
+\r
+       CHAPDEBUG((LOG_INFO, "ChapReceiveSuccess: Rcvd id %d.\n", id));\r
+       \r
+       if (cstate->clientstate == CHAPCS_OPEN)\r
+               /* presumably an answer to a duplicate response */\r
+               return;\r
+       \r
+       if (cstate->clientstate != CHAPCS_RESPONSE) {\r
+               /* don't know what this is */\r
+               CHAPDEBUG((LOG_INFO, "ChapReceiveSuccess: in state %d\n",\r
+                          cstate->clientstate));\r
+               return;\r
+       }\r
+       \r
+       UNTIMEOUT(ChapResponseTimeout, cstate);\r
+       \r
+       /*\r
+        * Print message.\r
+        */\r
+       if (len > 0)\r
+               PRINTMSG(inp, len);\r
+       \r
+       cstate->clientstate = CHAPCS_OPEN;\r
+       \r
+       auth_withpeer_success(cstate->unit, PPP_CHAP);\r
+}\r
+\r
+\r
+/*\r
+ * ChapReceiveFailure - Receive failure.\r
+ */\r
+static void ChapReceiveFailure(chap_state *cstate, u_char *inp, u_char id, int len)\r
+{\r
+       CHAPDEBUG((LOG_INFO, "ChapReceiveFailure: Rcvd id %d.\n", id));\r
+       \r
+       if (cstate->clientstate != CHAPCS_RESPONSE) {\r
+               /* don't know what this is */\r
+               CHAPDEBUG((LOG_INFO, "ChapReceiveFailure: in state %d\n",\r
+                          cstate->clientstate));\r
+               return;\r
+       }\r
+       \r
+       UNTIMEOUT(ChapResponseTimeout, cstate);\r
+       \r
+       /*\r
+        * Print message.\r
+        */\r
+       if (len > 0)\r
+               PRINTMSG(inp, len);\r
+       \r
+       CHAPDEBUG((LOG_ERR, "CHAP authentication failed\n"));\r
+       auth_withpeer_fail(cstate->unit, PPP_CHAP);\r
+}\r
+\r
+\r
+/*\r
+ * ChapSendChallenge - Send an Authenticate challenge.\r
+ */\r
+static void ChapSendChallenge(chap_state *cstate)\r
+{\r
+       u_char *outp;\r
+       int chal_len, name_len;\r
+       int outlen;\r
+       \r
+       chal_len = cstate->chal_len;\r
+       name_len = strlen(cstate->chal_name);\r
+       outlen = CHAP_HEADERLEN + sizeof (u_char) + chal_len + name_len;\r
+       outp = outpacket_buf[cstate->unit];\r
+       \r
+       MAKEHEADER(outp, PPP_CHAP);             /* paste in a CHAP header */\r
+       \r
+       PUTCHAR(CHAP_CHALLENGE, outp);\r
+       PUTCHAR(cstate->chal_id, outp);\r
+       PUTSHORT(outlen, outp);\r
+       \r
+       PUTCHAR(chal_len, outp);                /* put length of challenge */\r
+       BCOPY(cstate->challenge, outp, chal_len);\r
+       INCPTR(chal_len, outp);\r
+       \r
+       BCOPY(cstate->chal_name, outp, name_len);       /* append hostname */\r
+       \r
+       pppWrite(cstate->unit, outpacket_buf[cstate->unit], outlen + PPP_HDRLEN);\r
+       \r
+       CHAPDEBUG((LOG_INFO, "ChapSendChallenge: Sent id %d.\n", cstate->chal_id));\r
+       \r
+       TIMEOUT(ChapChallengeTimeout, cstate, cstate->timeouttime);\r
+       ++cstate->chal_transmits;\r
+}\r
+\r
+\r
+/*\r
+ * ChapSendStatus - Send a status response (ack or nak).\r
+ */\r
+static void ChapSendStatus(chap_state *cstate, int code)\r
+{\r
+       u_char *outp;\r
+       int outlen, msglen;\r
+       char msg[256];\r
+       \r
+       if (code == CHAP_SUCCESS)\r
+               strcpy(msg, "Welcome!");\r
+       else\r
+               strcpy(msg, "I don't like you.  Go 'way.");\r
+       msglen = strlen(msg);\r
+       \r
+       outlen = CHAP_HEADERLEN + msglen;\r
+       outp = outpacket_buf[cstate->unit];\r
+       \r
+       MAKEHEADER(outp, PPP_CHAP);             /* paste in a header */\r
+       \r
+       PUTCHAR(code, outp);\r
+       PUTCHAR(cstate->chal_id, outp);\r
+       PUTSHORT(outlen, outp);\r
+       BCOPY(msg, outp, msglen);\r
+       pppWrite(cstate->unit, outpacket_buf[cstate->unit], outlen + PPP_HDRLEN);\r
+       \r
+       CHAPDEBUG((LOG_INFO, "ChapSendStatus: Sent code %d, id %d.\n", code,\r
+              cstate->chal_id));\r
+}\r
+\r
+/*\r
+ * ChapGenChallenge is used to generate a pseudo-random challenge string of\r
+ * a pseudo-random length between min_len and max_len.  The challenge\r
+ * string and its length are stored in *cstate, and various other fields of\r
+ * *cstate are initialized.\r
+ */\r
+\r
+static void ChapGenChallenge(chap_state *cstate)\r
+{\r
+       int chal_len;\r
+       u_char *ptr = cstate->challenge;\r
+       int i;\r
+       \r
+       /* pick a random challenge length between MIN_CHALLENGE_LENGTH and \r
+          MAX_CHALLENGE_LENGTH */  \r
+       chal_len = (unsigned)\r
+                               ((((magic() >> 16) *\r
+                               (MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH)) >> 16)\r
+                            + MIN_CHALLENGE_LENGTH);\r
+       cstate->chal_len = chal_len;\r
+       cstate->chal_id = ++cstate->id;\r
+       cstate->chal_transmits = 0;\r
+       \r
+       /* generate a random string */\r
+       for (i = 0; i < chal_len; i++ )\r
+               *ptr++ = (char) (magic() & 0xff);\r
+}\r
+\r
+/*\r
+ * ChapSendResponse - send a response packet with values as specified\r
+ * in *cstate.\r
+ */\r
+/* ARGSUSED */\r
+static void ChapSendResponse(chap_state *cstate)\r
+{\r
+       u_char *outp;\r
+       int outlen, md_len, name_len;\r
+       \r
+       md_len = cstate->resp_length;\r
+       name_len = strlen(cstate->resp_name);\r
+       outlen = CHAP_HEADERLEN + sizeof (u_char) + md_len + name_len;\r
+       outp = outpacket_buf[cstate->unit];\r
+       \r
+       MAKEHEADER(outp, PPP_CHAP);\r
+       \r
+       PUTCHAR(CHAP_RESPONSE, outp);   /* we are a response */\r
+       PUTCHAR(cstate->resp_id, outp); /* copy id from challenge packet */\r
+       PUTSHORT(outlen, outp);                 /* packet length */\r
+       \r
+       PUTCHAR(md_len, outp);                  /* length of MD */\r
+       BCOPY(cstate->response, outp, md_len);          /* copy MD to buffer */\r
+       INCPTR(md_len, outp);\r
+       \r
+       BCOPY(cstate->resp_name, outp, name_len);       /* append our name */\r
+       \r
+       /* send the packet */\r
+       pppWrite(cstate->unit, outpacket_buf[cstate->unit], outlen + PPP_HDRLEN);\r
+       \r
+       cstate->clientstate = CHAPCS_RESPONSE;\r
+       TIMEOUT(ChapResponseTimeout, cstate, cstate->timeouttime);\r
+       ++cstate->resp_transmits;\r
+}\r
+\r
+/*\r
+ * ChapPrintPkt - print the contents of a CHAP packet.\r
+ */\r
+static int ChapPrintPkt(\r
+       u_char *p,\r
+       int plen,\r
+       void (*printer) (void *, char *, ...),\r
+       void *arg\r
+)\r
+{\r
+       int code, id, len;\r
+       int clen, nlen;\r
+       u_char x;\r
+       \r
+       if (plen < CHAP_HEADERLEN)\r
+               return 0;\r
+       GETCHAR(code, p);\r
+       GETCHAR(id, p);\r
+       GETSHORT(len, p);\r
+       if (len < CHAP_HEADERLEN || len > plen)\r
+               return 0;\r
+       \r
+       if (code >= 1 && code <= sizeof(ChapCodenames) / sizeof(char *))\r
+               printer(arg, " %s", ChapCodenames[code-1]);\r
+       else\r
+               printer(arg, " code=0x%x", code);\r
+       printer(arg, " id=0x%x", id);\r
+       len -= CHAP_HEADERLEN;\r
+       switch (code) {\r
+       case CHAP_CHALLENGE:\r
+       case CHAP_RESPONSE:\r
+               if (len < 1)\r
+                       break;\r
+               clen = p[0];\r
+               if (len < clen + 1)\r
+                       break;\r
+               ++p;\r
+               nlen = len - clen - 1;\r
+               printer(arg, " <");\r
+               for (; clen > 0; --clen) {\r
+                       GETCHAR(x, p);\r
+                       printer(arg, "%.2x", x);\r
+               }\r
+               printer(arg, ">, name = %.*Z", nlen, p);\r
+               break;\r
+       case CHAP_FAILURE:\r
+       case CHAP_SUCCESS:\r
+               printer(arg, " %.*Z", len, p);\r
+               break;\r
+       default:\r
+               for (clen = len; clen > 0; --clen) {\r
+                       GETCHAR(x, p);\r
+                       printer(arg, " %.2x", x);\r
+               }\r
+       }\r
+       \r
+       return len + CHAP_HEADERLEN;\r
+}\r
+\r
+#endif\r
+\r
+#endif /* PPP_SUPPORT */\r
index 5281fc01d41c26a184608c3a12735e7caaa15023..f20c1736ff9855e2692fbdff0f4c0b2b3f6adafd 100644 (file)
-/*****************************************************************************
-* chap.h - Network Challenge Handshake Authentication Protocol header file.
-*
-* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
-* portions Copyright (c) 1998 Global Election Systems Inc.
-*
-* The authors hereby grant permission to use, copy, modify, distribute,
-* and license this software and its documentation for any purpose, provided
-* that existing copyright notices are retained in all copies and that this
-* notice and the following disclaimer are included verbatim in any 
-* distributions. No written agreement, license, or royalty fee is required
-* for any of the authorized uses.
-*
-* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *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 CONTRIBUTORS 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.
-*
-******************************************************************************
-* REVISION HISTORY
-*
-* 03-01-01 Marc Boucher <marc@mbsi.ca>
-*   Ported to lwIP.
-* 97-12-03 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
-*      Original built from BSD network code.
-******************************************************************************/
-/*
- * chap.h - Challenge Handshake Authentication Protocol definitions.
- *
- * Copyright (c) 1993 The Australian National University.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the Australian National University.  The name of the University
- * may not be used to endorse or promote products derived from this
- * software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Copyright (c) 1991 Gregory M. Christy
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the author.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * $Id: chap.h,v 1.2 2006/08/29 18:53:47 wolti Exp $
- */
-
-#ifndef CHAP_H
-#define CHAP_H
-
-/*************************
-*** PUBLIC DEFINITIONS ***
-*************************/
-
-/* Code + ID + length */
-#define CHAP_HEADERLEN         4
-
-/*
- * CHAP codes.
- */
-
-#define CHAP_DIGEST_MD5                5       /* use MD5 algorithm */
-#define MD5_SIGNATURE_SIZE     16      /* 16 bytes in a MD5 message digest */
-#define CHAP_MICROSOFT         0x80    /* use Microsoft-compatible alg. */
-#define MS_CHAP_RESPONSE_LEN   49      /* Response length for MS-CHAP */
-
-#define CHAP_CHALLENGE         1
-#define CHAP_RESPONSE          2
-#define CHAP_SUCCESS           3
-#define CHAP_FAILURE           4
-
-/*
- *  Challenge lengths (for challenges we send) and other limits.
- */
-#define MIN_CHALLENGE_LENGTH   32
-#define MAX_CHALLENGE_LENGTH   64
-#define MAX_RESPONSE_LENGTH    64      /* sufficient for MD5 or MS-CHAP */
-
-/*
- * Client (peer) states.
- */
-#define CHAPCS_INITIAL         0       /* Lower layer down, not opened */
-#define CHAPCS_CLOSED          1       /* Lower layer up, not opened */
-#define CHAPCS_PENDING         2       /* Auth us to peer when lower up */
-#define CHAPCS_LISTEN          3       /* Listening for a challenge */
-#define CHAPCS_RESPONSE                4       /* Sent response, waiting for status */
-#define CHAPCS_OPEN            5       /* We've received Success */
-
-/*
- * Server (authenticator) states.
- */
-#define CHAPSS_INITIAL         0       /* Lower layer down, not opened */
-#define CHAPSS_CLOSED          1       /* Lower layer up, not opened */
-#define CHAPSS_PENDING         2       /* Auth peer when lower up */
-#define CHAPSS_INITIAL_CHAL    3       /* We've sent the first challenge */
-#define CHAPSS_OPEN            4       /* We've sent a Success msg */
-#define CHAPSS_RECHALLENGE     5       /* We've sent another challenge */
-#define CHAPSS_BADAUTH         6       /* We've sent a Failure msg */
-
-/************************
-*** PUBLIC DATA TYPES ***
-************************/
-
-/*
- * Each interface is described by a chap structure.
- */
-
-typedef struct chap_state {
-    int unit;                  /* Interface unit number */
-    int clientstate;           /* Client state */
-    int serverstate;           /* Server state */
-    u_char challenge[MAX_CHALLENGE_LENGTH]; /* last challenge string sent */
-    u_char chal_len;           /* challenge length */
-    u_char chal_id;            /* ID of last challenge */
-    u_char chal_type;          /* hash algorithm for challenges */
-    u_char id;                 /* Current id */
-    char *chal_name;           /* Our name to use with challenge */
-    int chal_interval;         /* Time until we challenge peer again */
-    int timeouttime;           /* Timeout time in seconds */
-    int max_transmits;         /* Maximum # of challenge transmissions */
-    int chal_transmits;                /* Number of transmissions of challenge */
-    int resp_transmits;                /* Number of transmissions of response */
-    u_char response[MAX_RESPONSE_LENGTH];      /* Response to send */
-    u_char resp_length;                /* length of response */
-    u_char resp_id;            /* ID for response messages */
-    u_char resp_type;          /* hash algorithm for responses */
-    char *resp_name;           /* Our name to send with response */
-} chap_state;
-
-
-/******************
-*** PUBLIC DATA ***
-******************/
-extern chap_state chap[];
-
-extern struct protent chap_protent;
-
-
-/***********************
-*** PUBLIC FUNCTIONS ***
-***********************/
-
-void ChapAuthWithPeer (int, char *, int);
-void ChapAuthPeer (int, char *, int);
-
-#endif /* CHAP_H */
-
+/*****************************************************************************\r
+* chap.h - Network Challenge Handshake Authentication Protocol header file.\r
+*\r
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.\r
+* portions Copyright (c) 1998 Global Election Systems Inc.\r
+*\r
+* The authors hereby grant permission to use, copy, modify, distribute,\r
+* and license this software and its documentation for any purpose, provided\r
+* that existing copyright notices are retained in all copies and that this\r
+* notice and the following disclaimer are included verbatim in any \r
+* distributions. No written agreement, license, or royalty fee is required\r
+* for any of the authorized uses.\r
+*\r
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR\r
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+*\r
+******************************************************************************\r
+* REVISION HISTORY\r
+*\r
+* 03-01-01 Marc Boucher <marc@mbsi.ca>\r
+*   Ported to lwIP.\r
+* 97-12-03 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.\r
+*      Original built from BSD network code.\r
+******************************************************************************/\r
+/*\r
+ * chap.h - Challenge Handshake Authentication Protocol definitions.\r
+ *\r
+ * Copyright (c) 1993 The Australian National University.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms are permitted\r
+ * provided that the above copyright notice and this paragraph are\r
+ * duplicated in all such forms and that any documentation,\r
+ * advertising materials, and other materials related to such\r
+ * distribution and use acknowledge that the software was developed\r
+ * by the Australian National University.  The name of the University\r
+ * may not be used to endorse or promote products derived from this\r
+ * software without specific prior written permission.\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR\r
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r
+ *\r
+ * Copyright (c) 1991 Gregory M. Christy\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms are permitted\r
+ * provided that the above copyright notice and this paragraph are\r
+ * duplicated in all such forms and that any documentation,\r
+ * advertising materials, and other materials related to such\r
+ * distribution and use acknowledge that the software was developed\r
+ * by the author.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR\r
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r
+ *\r
+ * $Id: chap.h,v 1.2 2006/08/29 18:53:47 wolti Exp $\r
+ */\r
+\r
+#ifndef CHAP_H\r
+#define CHAP_H\r
+\r
+/*************************\r
+*** PUBLIC DEFINITIONS ***\r
+*************************/\r
+\r
+/* Code + ID + length */\r
+#define CHAP_HEADERLEN         4\r
+\r
+/*\r
+ * CHAP codes.\r
+ */\r
+\r
+#define CHAP_DIGEST_MD5                5       /* use MD5 algorithm */\r
+#define MD5_SIGNATURE_SIZE     16      /* 16 bytes in a MD5 message digest */\r
+#define CHAP_MICROSOFT         0x80    /* use Microsoft-compatible alg. */\r
+#define MS_CHAP_RESPONSE_LEN   49      /* Response length for MS-CHAP */\r
+\r
+#define CHAP_CHALLENGE         1\r
+#define CHAP_RESPONSE          2\r
+#define CHAP_SUCCESS           3\r
+#define CHAP_FAILURE           4\r
+\r
+/*\r
+ *  Challenge lengths (for challenges we send) and other limits.\r
+ */\r
+#define MIN_CHALLENGE_LENGTH   32\r
+#define MAX_CHALLENGE_LENGTH   64\r
+#define MAX_RESPONSE_LENGTH    64      /* sufficient for MD5 or MS-CHAP */\r
+\r
+/*\r
+ * Client (peer) states.\r
+ */\r
+#define CHAPCS_INITIAL         0       /* Lower layer down, not opened */\r
+#define CHAPCS_CLOSED          1       /* Lower layer up, not opened */\r
+#define CHAPCS_PENDING         2       /* Auth us to peer when lower up */\r
+#define CHAPCS_LISTEN          3       /* Listening for a challenge */\r
+#define CHAPCS_RESPONSE                4       /* Sent response, waiting for status */\r
+#define CHAPCS_OPEN            5       /* We've received Success */\r
+\r
+/*\r
+ * Server (authenticator) states.\r
+ */\r
+#define CHAPSS_INITIAL         0       /* Lower layer down, not opened */\r
+#define CHAPSS_CLOSED          1       /* Lower layer up, not opened */\r
+#define CHAPSS_PENDING         2       /* Auth peer when lower up */\r
+#define CHAPSS_INITIAL_CHAL    3       /* We've sent the first challenge */\r
+#define CHAPSS_OPEN            4       /* We've sent a Success msg */\r
+#define CHAPSS_RECHALLENGE     5       /* We've sent another challenge */\r
+#define CHAPSS_BADAUTH         6       /* We've sent a Failure msg */\r
+\r
+/************************\r
+*** PUBLIC DATA TYPES ***\r
+************************/\r
+\r
+/*\r
+ * Each interface is described by a chap structure.\r
+ */\r
+\r
+typedef struct chap_state {\r
+    int unit;                  /* Interface unit number */\r
+    int clientstate;           /* Client state */\r
+    int serverstate;           /* Server state */\r
+    u_char challenge[MAX_CHALLENGE_LENGTH]; /* last challenge string sent */\r
+    u_char chal_len;           /* challenge length */\r
+    u_char chal_id;            /* ID of last challenge */\r
+    u_char chal_type;          /* hash algorithm for challenges */\r
+    u_char id;                 /* Current id */\r
+    char *chal_name;           /* Our name to use with challenge */\r
+    int chal_interval;         /* Time until we challenge peer again */\r
+    int timeouttime;           /* Timeout time in seconds */\r
+    int max_transmits;         /* Maximum # of challenge transmissions */\r
+    int chal_transmits;                /* Number of transmissions of challenge */\r
+    int resp_transmits;                /* Number of transmissions of response */\r
+    u_char response[MAX_RESPONSE_LENGTH];      /* Response to send */\r
+    u_char resp_length;                /* length of response */\r
+    u_char resp_id;            /* ID for response messages */\r
+    u_char resp_type;          /* hash algorithm for responses */\r
+    char *resp_name;           /* Our name to send with response */\r
+} chap_state;\r
+\r
+\r
+/******************\r
+*** PUBLIC DATA ***\r
+******************/\r
+extern chap_state chap[];\r
+\r
+extern struct protent chap_protent;\r
+\r
+\r
+/***********************\r
+*** PUBLIC FUNCTIONS ***\r
+***********************/\r
+\r
+void ChapAuthWithPeer (int, char *, int);\r
+void ChapAuthPeer (int, char *, int);\r
+\r
+#endif /* CHAP_H */\r
+\r
index 01755ba39ca6e3afaeb58ca69870348a93da0ec8..30643446034382f722681c0f0f59d58a425a4fb7 100644 (file)
-/*** WARNING - THIS CODE HAS NOT BEEN FINISHED! ***/
-/*****************************************************************************
-* chpms.c - Network MicroSoft Challenge Handshake Authentication Protocol program file.
-*
-* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
-* Copyright (c) 1997 by Global Election Systems Inc.  All rights reserved.
-*
-* The authors hereby grant permission to use, copy, modify, distribute,
-* and license this software and its documentation for any purpose, provided
-* that existing copyright notices are retained in all copies and that this
-* notice and the following disclaimer are included verbatim in any 
-* distributions. No written agreement, license, or royalty fee is required
-* for any of the authorized uses.
-*
-* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *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 CONTRIBUTORS 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.
-*
-******************************************************************************
-* REVISION HISTORY
-*
-* 03-01-01 Marc Boucher <marc@mbsi.ca>
-*   Ported to lwIP.
-* 97-12-08 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
-*      Original based on BSD chap_ms.c.
-*****************************************************************************/
-/*
- * chap_ms.c - Microsoft MS-CHAP compatible implementation.
- *
- * Copyright (c) 1995 Eric Rosenquist, Strata Software Limited.
- * http://www.strataware.com/
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by Eric Rosenquist.  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 ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-/*
- * Modifications by Lauri Pesonen / lpesonen@clinet.fi, april 1997
- *
- *   Implemented LANManager type password response to MS-CHAP challenges.
- *   Now pppd provides both NT style and LANMan style blocks, and the
- *   prefered is set by option "ms-lanman". Default is to use NT.
- *   The hash text (StdText) was taken from Win95 RASAPI32.DLL.
- *
- *   You should also use DOMAIN\\USERNAME as described in README.MSCHAP80
- */
-
-#define USE_CRYPT
-
-
-#include "ppp.h"
-
-#if MSCHAP_SUPPORT > 0
-
-#include "md4.h"
-#ifndef USE_CRYPT
-#include "des.h"
-#endif
-#include "chap.h"
-#include "chpms.h"
-#include "pppdebug.h"
-
-
-/*************************/
-/*** LOCAL DEFINITIONS ***/
-/*************************/
-
-
-/************************/
-/*** LOCAL DATA TYPES ***/
-/************************/
-typedef struct {
-    u_char LANManResp[24];
-    u_char NTResp[24];
-    u_char UseNT;              /* If 1, ignore the LANMan response field */
-} MS_ChapResponse;
-/* We use MS_CHAP_RESPONSE_LEN, rather than sizeof(MS_ChapResponse),
-   in case this struct gets padded. */
-
-
-
-/***********************************/
-/*** LOCAL FUNCTION DECLARATIONS ***/
-/***********************************/
-
-/* XXX Don't know what to do with these. */
-extern void setkey(const char *);
-extern void encrypt(char *, int);
-
-static void    DesEncrypt (u_char *, u_char *, u_char *);
-static void    MakeKey (u_char *, u_char *);
-
-#ifdef USE_CRYPT
-static void    Expand (u_char *, u_char *);
-static void    Collapse (u_char *, u_char *);
-#endif
-
-static void ChallengeResponse(
-       u_char *challenge,      /* IN   8 octets */
-       u_char *pwHash,         /* IN  16 octets */
-       u_char *response        /* OUT 24 octets */
-);
-static void ChapMS_NT(
-       char *rchallenge,
-       int rchallenge_len,
-       char *secret,
-       int secret_len,
-       MS_ChapResponse *response
-);
-static u_char Get7Bits(
-       u_char *input,
-       int startBit
-);
-
-
-/***********************************/
-/*** PUBLIC FUNCTION DEFINITIONS ***/
-/***********************************/
-void ChapMS(
-       chap_state *cstate,
-       char *rchallenge,
-       int rchallenge_len,
-       char *secret,
-       int secret_len
-)
-{
-       MS_ChapResponse response;
-#ifdef MSLANMAN
-       extern int ms_lanman;
-#endif
-       
-#if 0
-       CHAPDEBUG((LOG_INFO, "ChapMS: secret is '%.*s'\n", secret_len, secret));
-#endif
-       BZERO(&response, sizeof(response));
-       
-       /* Calculate both always */
-       ChapMS_NT(rchallenge, rchallenge_len, secret, secret_len, &response);
-       
-#ifdef MSLANMAN
-       ChapMS_LANMan(rchallenge, rchallenge_len, secret, secret_len, &response);
-       
-       /* prefered method is set by option  */
-       response.UseNT = !ms_lanman;
-#else
-       response.UseNT = 1;
-#endif
-       
-       BCOPY(&response, cstate->response, MS_CHAP_RESPONSE_LEN);
-       cstate->resp_length = MS_CHAP_RESPONSE_LEN;
-}
-
-
-/**********************************/
-/*** LOCAL FUNCTION DEFINITIONS ***/
-/**********************************/
-static void ChallengeResponse(
-       u_char *challenge,      /* IN   8 octets */
-       u_char *pwHash,         /* IN  16 octets */
-       u_char *response        /* OUT 24 octets */
-)
-{
-       char    ZPasswordHash[21];
-       
-       BZERO(ZPasswordHash, sizeof(ZPasswordHash));
-       BCOPY(pwHash, ZPasswordHash, 16);
-       
-#if 0
-       log_packet(ZPasswordHash, sizeof(ZPasswordHash), "ChallengeResponse - ZPasswordHash", LOG_DEBUG);
-#endif
-       
-       DesEncrypt(challenge, ZPasswordHash +  0, response + 0);
-       DesEncrypt(challenge, ZPasswordHash +  7, response + 8);
-       DesEncrypt(challenge, ZPasswordHash + 14, response + 16);
-       
-#if 0
-       log_packet(response, 24, "ChallengeResponse - response", LOG_DEBUG);
-#endif
-}
-
-
-#ifdef USE_CRYPT
-static void DesEncrypt(
-       u_char *clear,  /* IN  8 octets */
-       u_char *key,    /* IN  7 octets */
-       u_char *cipher  /* OUT 8 octets */
-)
-{
-       u_char des_key[8];
-       u_char crypt_key[66];
-       u_char des_input[66];
-       
-       MakeKey(key, des_key);
-       
-       Expand(des_key, crypt_key);
-       setkey(crypt_key);
-       
-#if 0
-       CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet input : %02X%02X%02X%02X%02X%02X%02X%02X\n",
-              clear[0], clear[1], clear[2], clear[3], clear[4], clear[5], clear[6], clear[7]));
-#endif
-       
-       Expand(clear, des_input);
-       encrypt(des_input, 0);
-       Collapse(des_input, cipher);
-       
-#if 0
-       CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet output: %02X%02X%02X%02X%02X%02X%02X%02X\n",
-              cipher[0], cipher[1], cipher[2], cipher[3], cipher[4], cipher[5], cipher[6], cipher[7]));
-#endif
-}
-
-#else /* USE_CRYPT */
-
-static void DesEncrypt(
-       u_char *clear,  /* IN  8 octets */
-       u_char *key,    /* IN  7 octets */
-       u_char *cipher  /* OUT 8 octets */
-)
-{
-       des_cblock              des_key;
-       des_key_schedule        key_schedule;
-       
-       MakeKey(key, des_key);
-       
-       des_set_key(&des_key, key_schedule);
-       
-#if 0
-       CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet input : %02X%02X%02X%02X%02X%02X%02X%02X\n",
-              clear[0], clear[1], clear[2], clear[3], clear[4], clear[5], clear[6], clear[7]));
-#endif
-       
-       des_ecb_encrypt((des_cblock *)clear, (des_cblock *)cipher, key_schedule, 1);
-       
-#if 0
-       CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet output: %02X%02X%02X%02X%02X%02X%02X%02X\n",
-              cipher[0], cipher[1], cipher[2], cipher[3], cipher[4], cipher[5], cipher[6], cipher[7]));
-#endif
-}
-
-#endif /* USE_CRYPT */
-
-
-static u_char Get7Bits(
-       u_char *input,
-       int startBit
-)
-{
-       register unsigned int   word;
-       
-       word  = (unsigned)input[startBit / 8] << 8;
-       word |= (unsigned)input[startBit / 8 + 1];
-       
-       word >>= 15 - (startBit % 8 + 7);
-       
-       return word & 0xFE;
-}
-
-#ifdef USE_CRYPT
-
-/* in == 8-byte string (expanded version of the 56-bit key)
- * out == 64-byte string where each byte is either 1 or 0
- * Note that the low-order "bit" is always ignored by by setkey()
- */
-static void Expand(u_char *in, u_char *out)
-{
-       int j, c;
-       int i;
-       
-       for(i = 0; i < 64; in++){
-               c = *in;
-               for(j = 7; j >= 0; j--)
-                       *out++ = (c >> j) & 01;
-               i += 8;
-       }
-}
-
-/* The inverse of Expand
- */
-static void Collapse(u_char *in, u_char *out)
-{
-       int j;
-       int i;
-       unsigned int c;
-       
-       for (i = 0; i < 64; i += 8, out++) {
-               c = 0;
-               for (j = 7; j >= 0; j--, in++)
-                       c |= *in << j;
-               *out = c & 0xff;
-       }
-}
-#endif
-
-static void MakeKey(
-       u_char *key,            /* IN  56 bit DES key missing parity bits */
-       u_char *des_key         /* OUT 64 bit DES key with parity bits added */
-)
-{
-       des_key[0] = Get7Bits(key,  0);
-       des_key[1] = Get7Bits(key,  7);
-       des_key[2] = Get7Bits(key, 14);
-       des_key[3] = Get7Bits(key, 21);
-       des_key[4] = Get7Bits(key, 28);
-       des_key[5] = Get7Bits(key, 35);
-       des_key[6] = Get7Bits(key, 42);
-       des_key[7] = Get7Bits(key, 49);
-       
-#ifndef USE_CRYPT
-       des_set_odd_parity((des_cblock *)des_key);
-#endif
-       
-#if 0
-       CHAPDEBUG((LOG_INFO, "MakeKey: 56-bit input : %02X%02X%02X%02X%02X%02X%02X\n",
-              key[0], key[1], key[2], key[3], key[4], key[5], key[6]));
-       CHAPDEBUG((LOG_INFO, "MakeKey: 64-bit output: %02X%02X%02X%02X%02X%02X%02X%02X\n",
-              des_key[0], des_key[1], des_key[2], des_key[3], des_key[4], des_key[5], des_key[6], des_key[7]));
-#endif
-}
-
-static void ChapMS_NT(
-       char *rchallenge,
-       int rchallenge_len,
-       char *secret,
-       int secret_len,
-       MS_ChapResponse *response
-)
-{
-       int                     i;
-       MDstruct        md4Context;
-       u_char          unicodePassword[MAX_NT_PASSWORD * 2];
-       static int      low_byte_first = -1;
-       
-       /* Initialize the Unicode version of the secret (== password). */
-       /* This implicitly supports 8-bit ISO8859/1 characters. */
-       BZERO(unicodePassword, sizeof(unicodePassword));
-       for (i = 0; i < secret_len; i++)
-               unicodePassword[i * 2] = (u_char)secret[i];
-       
-       MDbegin(&md4Context);
-       MDupdate(&md4Context, unicodePassword, secret_len * 2 * 8);     /* Unicode is 2 bytes/char, *8 for bit count */
-       
-       if (low_byte_first == -1)
-               low_byte_first = (htons((unsigned short int)1) != 1);
-       if (low_byte_first == 0)
-               MDreverse((u_long *)&md4Context);  /*  sfb 961105 */
-       
-       MDupdate(&md4Context, NULL, 0); /* Tell MD4 we're done */
-       
-       ChallengeResponse(rchallenge, (char *)md4Context.buffer, response->NTResp);
-}
-
-#ifdef MSLANMAN
-static u_char *StdText = (u_char *)"KGS!@#$%"; /* key from rasapi32.dll */
-
-static ChapMS_LANMan(
-       char *rchallenge,
-       int rchallenge_len,
-       char *secret,
-       int secret_len,
-       MS_ChapResponse *response
-)
-{
-       int                     i;
-       u_char          UcasePassword[MAX_NT_PASSWORD]; /* max is actually 14 */
-       u_char          PasswordHash[16];
-       
-       /* LANMan password is case insensitive */
-       BZERO(UcasePassword, sizeof(UcasePassword));
-       for (i = 0; i < secret_len; i++)
-               UcasePassword[i] = (u_char)toupper(secret[i]);
-       DesEncrypt( StdText, UcasePassword + 0, PasswordHash + 0 );
-       DesEncrypt( StdText, UcasePassword + 7, PasswordHash + 8 );
-       ChallengeResponse(rchallenge, PasswordHash, response->LANManResp);
-}
-#endif
-
-#endif /* MSCHAP_SUPPORT */
-
+/*** WARNING - THIS CODE HAS NOT BEEN FINISHED! ***/\r
+/*****************************************************************************\r
+* chpms.c - Network MicroSoft Challenge Handshake Authentication Protocol program file.\r
+*\r
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.\r
+* Copyright (c) 1997 by Global Election Systems Inc.  All rights reserved.\r
+*\r
+* The authors hereby grant permission to use, copy, modify, distribute,\r
+* and license this software and its documentation for any purpose, provided\r
+* that existing copyright notices are retained in all copies and that this\r
+* notice and the following disclaimer are included verbatim in any \r
+* distributions. No written agreement, license, or royalty fee is required\r
+* for any of the authorized uses.\r
+*\r
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR\r
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+*\r
+******************************************************************************\r
+* REVISION HISTORY\r
+*\r
+* 03-01-01 Marc Boucher <marc@mbsi.ca>\r
+*   Ported to lwIP.\r
+* 97-12-08 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.\r
+*      Original based on BSD chap_ms.c.\r
+*****************************************************************************/\r
+/*\r
+ * chap_ms.c - Microsoft MS-CHAP compatible implementation.\r
+ *\r
+ * Copyright (c) 1995 Eric Rosenquist, Strata Software Limited.\r
+ * http://www.strataware.com/\r
+ *\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms are permitted\r
+ * provided that the above copyright notice and this paragraph are\r
+ * duplicated in all such forms and that any documentation,\r
+ * advertising materials, and other materials related to such\r
+ * distribution and use acknowledge that the software was developed\r
+ * by Eric Rosenquist.  The name of the author may not be used to\r
+ * endorse or promote products derived from this software without\r
+ * specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR\r
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r
+ */\r
+\r
+/*\r
+ * Modifications by Lauri Pesonen / lpesonen@clinet.fi, april 1997\r
+ *\r
+ *   Implemented LANManager type password response to MS-CHAP challenges.\r
+ *   Now pppd provides both NT style and LANMan style blocks, and the\r
+ *   prefered is set by option "ms-lanman". Default is to use NT.\r
+ *   The hash text (StdText) was taken from Win95 RASAPI32.DLL.\r
+ *\r
+ *   You should also use DOMAIN\\USERNAME as described in README.MSCHAP80\r
+ */\r
+\r
+#define USE_CRYPT\r
+\r
+\r
+#include "ppp.h"\r
+\r
+#if MSCHAP_SUPPORT > 0\r
+\r
+#include "md4.h"\r
+#ifndef USE_CRYPT\r
+#include "des.h"\r
+#endif\r
+#include "chap.h"\r
+#include "chpms.h"\r
+#include "pppdebug.h"\r
+\r
+\r
+/*************************/\r
+/*** LOCAL DEFINITIONS ***/\r
+/*************************/\r
+\r
+\r
+/************************/\r
+/*** LOCAL DATA TYPES ***/\r
+/************************/\r
+typedef struct {\r
+    u_char LANManResp[24];\r
+    u_char NTResp[24];\r
+    u_char UseNT;              /* If 1, ignore the LANMan response field */\r
+} MS_ChapResponse;\r
+/* We use MS_CHAP_RESPONSE_LEN, rather than sizeof(MS_ChapResponse),\r
+   in case this struct gets padded. */\r
+\r
+\r
+\r
+/***********************************/\r
+/*** LOCAL FUNCTION DECLARATIONS ***/\r
+/***********************************/\r
+\r
+/* XXX Don't know what to do with these. */\r
+extern void setkey(const char *);\r
+extern void encrypt(char *, int);\r
+\r
+static void    DesEncrypt (u_char *, u_char *, u_char *);\r
+static void    MakeKey (u_char *, u_char *);\r
+\r
+#ifdef USE_CRYPT\r
+static void    Expand (u_char *, u_char *);\r
+static void    Collapse (u_char *, u_char *);\r
+#endif\r
+\r
+static void ChallengeResponse(\r
+       u_char *challenge,      /* IN   8 octets */\r
+       u_char *pwHash,         /* IN  16 octets */\r
+       u_char *response        /* OUT 24 octets */\r
+);\r
+static void ChapMS_NT(\r
+       char *rchallenge,\r
+       int rchallenge_len,\r
+       char *secret,\r
+       int secret_len,\r
+       MS_ChapResponse *response\r
+);\r
+static u_char Get7Bits(\r
+       u_char *input,\r
+       int startBit\r
+);\r
+\r
+\r
+/***********************************/\r
+/*** PUBLIC FUNCTION DEFINITIONS ***/\r
+/***********************************/\r
+void ChapMS(\r
+       chap_state *cstate,\r
+       char *rchallenge,\r
+       int rchallenge_len,\r
+       char *secret,\r
+       int secret_len\r
+)\r
+{\r
+       MS_ChapResponse response;\r
+#ifdef MSLANMAN\r
+       extern int ms_lanman;\r
+#endif\r
+       \r
+#if 0\r
+       CHAPDEBUG((LOG_INFO, "ChapMS: secret is '%.*s'\n", secret_len, secret));\r
+#endif\r
+       BZERO(&response, sizeof(response));\r
+       \r
+       /* Calculate both always */\r
+       ChapMS_NT(rchallenge, rchallenge_len, secret, secret_len, &response);\r
+       \r
+#ifdef MSLANMAN\r
+       ChapMS_LANMan(rchallenge, rchallenge_len, secret, secret_len, &response);\r
+       \r
+       /* prefered method is set by option  */\r
+       response.UseNT = !ms_lanman;\r
+#else\r
+       response.UseNT = 1;\r
+#endif\r
+       \r
+       BCOPY(&response, cstate->response, MS_CHAP_RESPONSE_LEN);\r
+       cstate->resp_length = MS_CHAP_RESPONSE_LEN;\r
+}\r
+\r
+\r
+/**********************************/\r
+/*** LOCAL FUNCTION DEFINITIONS ***/\r
+/**********************************/\r
+static void ChallengeResponse(\r
+       u_char *challenge,      /* IN   8 octets */\r
+       u_char *pwHash,         /* IN  16 octets */\r
+       u_char *response        /* OUT 24 octets */\r
+)\r
+{\r
+       char    ZPasswordHash[21];\r
+       \r
+       BZERO(ZPasswordHash, sizeof(ZPasswordHash));\r
+       BCOPY(pwHash, ZPasswordHash, 16);\r
+       \r
+#if 0\r
+       log_packet(ZPasswordHash, sizeof(ZPasswordHash), "ChallengeResponse - ZPasswordHash", LOG_DEBUG);\r
+#endif\r
+       \r
+       DesEncrypt(challenge, ZPasswordHash +  0, response + 0);\r
+       DesEncrypt(challenge, ZPasswordHash +  7, response + 8);\r
+       DesEncrypt(challenge, ZPasswordHash + 14, response + 16);\r
+       \r
+#if 0\r
+       log_packet(response, 24, "ChallengeResponse - response", LOG_DEBUG);\r
+#endif\r
+}\r
+\r
+\r
+#ifdef USE_CRYPT\r
+static void DesEncrypt(\r
+       u_char *clear,  /* IN  8 octets */\r
+       u_char *key,    /* IN  7 octets */\r
+       u_char *cipher  /* OUT 8 octets */\r
+)\r
+{\r
+       u_char des_key[8];\r
+       u_char crypt_key[66];\r
+       u_char des_input[66];\r
+       \r
+       MakeKey(key, des_key);\r
+       \r
+       Expand(des_key, crypt_key);\r
+       setkey(crypt_key);\r
+       \r
+#if 0\r
+       CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet input : %02X%02X%02X%02X%02X%02X%02X%02X\n",\r
+              clear[0], clear[1], clear[2], clear[3], clear[4], clear[5], clear[6], clear[7]));\r
+#endif\r
+       \r
+       Expand(clear, des_input);\r
+       encrypt(des_input, 0);\r
+       Collapse(des_input, cipher);\r
+       \r
+#if 0\r
+       CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet output: %02X%02X%02X%02X%02X%02X%02X%02X\n",\r
+              cipher[0], cipher[1], cipher[2], cipher[3], cipher[4], cipher[5], cipher[6], cipher[7]));\r
+#endif\r
+}\r
+\r
+#else /* USE_CRYPT */\r
+\r
+static void DesEncrypt(\r
+       u_char *clear,  /* IN  8 octets */\r
+       u_char *key,    /* IN  7 octets */\r
+       u_char *cipher  /* OUT 8 octets */\r
+)\r
+{\r
+       des_cblock              des_key;\r
+       des_key_schedule        key_schedule;\r
+       \r
+       MakeKey(key, des_key);\r
+       \r
+       des_set_key(&des_key, key_schedule);\r
+       \r
+#if 0\r
+       CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet input : %02X%02X%02X%02X%02X%02X%02X%02X\n",\r
+              clear[0], clear[1], clear[2], clear[3], clear[4], clear[5], clear[6], clear[7]));\r
+#endif\r
+       \r
+       des_ecb_encrypt((des_cblock *)clear, (des_cblock *)cipher, key_schedule, 1);\r
+       \r
+#if 0\r
+       CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet output: %02X%02X%02X%02X%02X%02X%02X%02X\n",\r
+              cipher[0], cipher[1], cipher[2], cipher[3], cipher[4], cipher[5], cipher[6], cipher[7]));\r
+#endif\r
+}\r
+\r
+#endif /* USE_CRYPT */\r
+\r
+\r
+static u_char Get7Bits(\r
+       u_char *input,\r
+       int startBit\r
+)\r
+{\r
+       register unsigned int   word;\r
+       \r
+       word  = (unsigned)input[startBit / 8] << 8;\r
+       word |= (unsigned)input[startBit / 8 + 1];\r
+       \r
+       word >>= 15 - (startBit % 8 + 7);\r
+       \r
+       return word & 0xFE;\r
+}\r
+\r
+#ifdef USE_CRYPT\r
+\r
+/* in == 8-byte string (expanded version of the 56-bit key)\r
+ * out == 64-byte string where each byte is either 1 or 0\r
+ * Note that the low-order "bit" is always ignored by by setkey()\r
+ */\r
+static void Expand(u_char *in, u_char *out)\r
+{\r
+       int j, c;\r
+       int i;\r
+       \r
+       for(i = 0; i < 64; in++){\r
+               c = *in;\r
+               for(j = 7; j >= 0; j--)\r
+                       *out++ = (c >> j) & 01;\r
+               i += 8;\r
+       }\r
+}\r
+\r
+/* The inverse of Expand\r
+ */\r
+static void Collapse(u_char *in, u_char *out)\r
+{\r
+       int j;\r
+       int i;\r
+       unsigned int c;\r
+       \r
+       for (i = 0; i < 64; i += 8, out++) {\r
+               c = 0;\r
+               for (j = 7; j >= 0; j--, in++)\r
+                       c |= *in << j;\r
+               *out = c & 0xff;\r
+       }\r
+}\r
+#endif\r
+\r
+static void MakeKey(\r
+       u_char *key,            /* IN  56 bit DES key missing parity bits */\r
+       u_char *des_key         /* OUT 64 bit DES key with parity bits added */\r
+)\r
+{\r
+       des_key[0] = Get7Bits(key,  0);\r
+       des_key[1] = Get7Bits(key,  7);\r
+       des_key[2] = Get7Bits(key, 14);\r
+       des_key[3] = Get7Bits(key, 21);\r
+       des_key[4] = Get7Bits(key, 28);\r
+       des_key[5] = Get7Bits(key, 35);\r
+       des_key[6] = Get7Bits(key, 42);\r
+       des_key[7] = Get7Bits(key, 49);\r
+       \r
+#ifndef USE_CRYPT\r
+       des_set_odd_parity((des_cblock *)des_key);\r
+#endif\r
+       \r
+#if 0\r
+       CHAPDEBUG((LOG_INFO, "MakeKey: 56-bit input : %02X%02X%02X%02X%02X%02X%02X\n",\r
+              key[0], key[1], key[2], key[3], key[4], key[5], key[6]));\r
+       CHAPDEBUG((LOG_INFO, "MakeKey: 64-bit output: %02X%02X%02X%02X%02X%02X%02X%02X\n",\r
+              des_key[0], des_key[1], des_key[2], des_key[3], des_key[4], des_key[5], des_key[6], des_key[7]));\r
+#endif\r
+}\r
+\r
+static void ChapMS_NT(\r
+       char *rchallenge,\r
+       int rchallenge_len,\r
+       char *secret,\r
+       int secret_len,\r
+       MS_ChapResponse *response\r
+)\r
+{\r
+       int                     i;\r
+       MDstruct        md4Context;\r
+       u_char          unicodePassword[MAX_NT_PASSWORD * 2];\r
+       static int      low_byte_first = -1;\r
+       \r
+       /* Initialize the Unicode version of the secret (== password). */\r
+       /* This implicitly supports 8-bit ISO8859/1 characters. */\r
+       BZERO(unicodePassword, sizeof(unicodePassword));\r
+       for (i = 0; i < secret_len; i++)\r
+               unicodePassword[i * 2] = (u_char)secret[i];\r
+       \r
+       MDbegin(&md4Context);\r
+       MDupdate(&md4Context, unicodePassword, secret_len * 2 * 8);     /* Unicode is 2 bytes/char, *8 for bit count */\r
+       \r
+       if (low_byte_first == -1)\r
+               low_byte_first = (htons((unsigned short int)1) != 1);\r
+       if (low_byte_first == 0)\r
+               MDreverse((u_long *)&md4Context);  /*  sfb 961105 */\r
+       \r
+       MDupdate(&md4Context, NULL, 0); /* Tell MD4 we're done */\r
+       \r
+       ChallengeResponse(rchallenge, (char *)md4Context.buffer, response->NTResp);\r
+}\r
+\r
+#ifdef MSLANMAN\r
+static u_char *StdText = (u_char *)"KGS!@#$%"; /* key from rasapi32.dll */\r
+\r
+static ChapMS_LANMan(\r
+       char *rchallenge,\r
+       int rchallenge_len,\r
+       char *secret,\r
+       int secret_len,\r
+       MS_ChapResponse *response\r
+)\r
+{\r
+       int                     i;\r
+       u_char          UcasePassword[MAX_NT_PASSWORD]; /* max is actually 14 */\r
+       u_char          PasswordHash[16];\r
+       \r
+       /* LANMan password is case insensitive */\r
+       BZERO(UcasePassword, sizeof(UcasePassword));\r
+       for (i = 0; i < secret_len; i++)\r
+               UcasePassword[i] = (u_char)toupper(secret[i]);\r
+       DesEncrypt( StdText, UcasePassword + 0, PasswordHash + 0 );\r
+       DesEncrypt( StdText, UcasePassword + 7, PasswordHash + 8 );\r
+       ChallengeResponse(rchallenge, PasswordHash, response->LANManResp);\r
+}\r
+#endif\r
+\r
+#endif /* MSCHAP_SUPPORT */\r
+\r
index 9973ba0157cead240b7a081eedc4d4cfa217f4e5..ccc8b4882166b2473e4763a3484cdbd6a1181013 100644 (file)
@@ -1,64 +1,64 @@
-/*****************************************************************************
-* chpms.h - Network Microsoft Challenge Handshake Protocol header file.
-*
-* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
-* portions Copyright (c) 1998 Global Election Systems Inc.
-*
-* The authors hereby grant permission to use, copy, modify, distribute,
-* and license this software and its documentation for any purpose, provided
-* that existing copyright notices are retained in all copies and that this
-* notice and the following disclaimer are included verbatim in any 
-* distributions. No written agreement, license, or royalty fee is required
-* for any of the authorized uses.
-*
-* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *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 CONTRIBUTORS 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.
-*
-******************************************************************************
-* REVISION HISTORY
-*
-* 03-01-01 Marc Boucher <marc@mbsi.ca>
-*   Ported to lwIP.
-* 98-01-30 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
-*      Original built from BSD network code.
-******************************************************************************/
-/*
- * chap.h - Challenge Handshake Authentication Protocol definitions.
- *
- * Copyright (c) 1995 Eric Rosenquist, Strata Software Limited.
- * http://www.strataware.com/
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by Eric Rosenquist.  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 ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * $Id: chpms.h,v 1.2 2006/08/29 18:53:47 wolti Exp $
- */
-
-#ifndef CHPMS_H
-#define CHPMS_H
-
-#define MAX_NT_PASSWORD        256     /* Maximum number of (Unicode) chars in an NT password */
-
-void ChapMS (chap_state *, char *, int, char *, int);
-
-#endif /* CHPMS_H */
+/*****************************************************************************\r
+* chpms.h - Network Microsoft Challenge Handshake Protocol header file.\r
+*\r
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.\r
+* portions Copyright (c) 1998 Global Election Systems Inc.\r
+*\r
+* The authors hereby grant permission to use, copy, modify, distribute,\r
+* and license this software and its documentation for any purpose, provided\r
+* that existing copyright notices are retained in all copies and that this\r
+* notice and the following disclaimer are included verbatim in any \r
+* distributions. No written agreement, license, or royalty fee is required\r
+* for any of the authorized uses.\r
+*\r
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR\r
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+*\r
+******************************************************************************\r
+* REVISION HISTORY\r
+*\r
+* 03-01-01 Marc Boucher <marc@mbsi.ca>\r
+*   Ported to lwIP.\r
+* 98-01-30 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.\r
+*      Original built from BSD network code.\r
+******************************************************************************/\r
+/*\r
+ * chap.h - Challenge Handshake Authentication Protocol definitions.\r
+ *\r
+ * Copyright (c) 1995 Eric Rosenquist, Strata Software Limited.\r
+ * http://www.strataware.com/\r
+ *\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms are permitted\r
+ * provided that the above copyright notice and this paragraph are\r
+ * duplicated in all such forms and that any documentation,\r
+ * advertising materials, and other materials related to such\r
+ * distribution and use acknowledge that the software was developed\r
+ * by Eric Rosenquist.  The name of the author may not be used to\r
+ * endorse or promote products derived from this software without\r
+ * specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR\r
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r
+ *\r
+ * $Id: chpms.h,v 1.2 2006/08/29 18:53:47 wolti Exp $\r
+ */\r
+\r
+#ifndef CHPMS_H\r
+#define CHPMS_H\r
+\r
+#define MAX_NT_PASSWORD        256     /* Maximum number of (Unicode) chars in an NT password */\r
+\r
+void ChapMS (chap_state *, char *, int, char *, int);\r
+\r
+#endif /* CHPMS_H */\r
index fe8b38a93596226f2f71f563461786b42b54da37..6cad71525e004e0bac5a94d99b8eb3617d2ab5ee 100644 (file)
-/*****************************************************************************
-* fsm.c - Network Control Protocol Finite State Machine program file.
-*
-* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
-* portions Copyright (c) 1997 by Global Election Systems Inc.
-*
-* The authors hereby grant permission to use, copy, modify, distribute,
-* and license this software and its documentation for any purpose, provided
-* that existing copyright notices are retained in all copies and that this
-* notice and the following disclaimer are included verbatim in any 
-* distributions. No written agreement, license, or royalty fee is required
-* for any of the authorized uses.
-*
-* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *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 CONTRIBUTORS 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.
-*
-******************************************************************************
-* REVISION HISTORY
-*
-* 03-01-01 Marc Boucher <marc@mbsi.ca>
-*   Ported to lwIP.
-* 97-12-01 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
-*      Original based on BSD fsm.c.
-*****************************************************************************/
-/*
- * fsm.c - {Link, IP} Control Protocol Finite State Machine.
- *
- * Copyright (c) 1989 Carnegie Mellon University.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by Carnegie Mellon University.  The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-
-/*
- * TODO:
- * Randomize fsm id on link/init.
- * Deal with variable outgoing MTU.
- */
-
-#include "ppp.h"
-#if PPP_SUPPORT > 0
-#include "fsm.h"
-#include "pppdebug.h"
-
-
-/*************************/
-/*** LOCAL DEFINITIONS ***/
-/*************************/
-
-
-/************************/
-/*** LOCAL DATA TYPES ***/
-/************************/
-
-
-/***********************************/
-/*** LOCAL FUNCTION DECLARATIONS ***/
-/***********************************/
-static void fsm_timeout (void *);
-static void fsm_rconfreq (fsm *, u_char, u_char *, int);
-static void fsm_rconfack (fsm *, int, u_char *, int);
-static void fsm_rconfnakrej (fsm *, int, int, u_char *, int);
-static void fsm_rtermreq (fsm *, int, u_char *, int);
-static void fsm_rtermack (fsm *);
-static void fsm_rcoderej (fsm *, u_char *, int);
-static void fsm_sconfreq (fsm *, int);
-
-#define PROTO_NAME(f)  ((f)->callbacks->proto_name)
-
-
-/******************************/
-/*** PUBLIC DATA STRUCTURES ***/
-/******************************/
-
-
-/*****************************/
-/*** LOCAL DATA STRUCTURES ***/
-/*****************************/
-int peer_mru[NUM_PPP];
-
-
-/***********************************/
-/*** PUBLIC FUNCTION DEFINITIONS ***/
-/***********************************/
-
-/*
- * fsm_init - Initialize fsm.
- *
- * Initialize fsm state.
- */
-void fsm_init(fsm *f)
-{
-       f->state = INITIAL;
-       f->flags = 0;
-       f->id = 0;                              /* XXX Start with random id? */
-       f->timeouttime = FSM_DEFTIMEOUT;
-       f->maxconfreqtransmits = FSM_DEFMAXCONFREQS;
-       f->maxtermtransmits = FSM_DEFMAXTERMREQS;
-       f->maxnakloops = FSM_DEFMAXNAKLOOPS;
-       f->term_reason_len = 0;
-}
-
-
-/*
- * fsm_lowerup - The lower layer is up.
- */
-void fsm_lowerup(fsm *f)
-{
-       int oldState = f->state;
-
-       switch( f->state ){
-       case INITIAL:
-               f->state = CLOSED;
-               break;
-       
-       case STARTING:
-               if( f->flags & OPT_SILENT )
-                       f->state = STOPPED;
-               else {
-                       /* Send an initial configure-request */
-                       fsm_sconfreq(f, 0);
-                       f->state = REQSENT;
-               }
-       break;
-       
-       default:
-               FSMDEBUG((LOG_INFO, "%s: Up event in state %d!\n",
-                               PROTO_NAME(f), f->state));
-       }
-       
-       FSMDEBUG((LOG_INFO, "%s: lowerup state %d -> %d\n",
-                       PROTO_NAME(f), oldState, f->state));
-}
-
-
-/*
- * fsm_lowerdown - The lower layer is down.
- *
- * Cancel all timeouts and inform upper layers.
- */
-void fsm_lowerdown(fsm *f)
-{
-       int oldState = f->state;
-       
-       switch( f->state ){
-       case CLOSED:
-               f->state = INITIAL;
-               break;
-       
-       case STOPPED:
-               f->state = STARTING;
-               if( f->callbacks->starting )
-                       (*f->callbacks->starting)(f);
-               break;
-       
-       case CLOSING:
-               f->state = INITIAL;
-               UNTIMEOUT(fsm_timeout, f);      /* Cancel timeout */
-               break;
-       
-       case STOPPING:
-       case REQSENT:
-       case ACKRCVD:
-       case ACKSENT:
-               f->state = STARTING;
-               UNTIMEOUT(fsm_timeout, f);      /* Cancel timeout */
-               break;
-       
-       case OPENED:
-               if( f->callbacks->down )
-                       (*f->callbacks->down)(f);
-               f->state = STARTING;
-               break;
-       
-       default:
-               FSMDEBUG((LOG_INFO, "%s: Down event in state %d!\n",
-                               PROTO_NAME(f), f->state));
-       }
-       
-       FSMDEBUG((LOG_INFO, "%s: lowerdown state %d -> %d\n",
-                       PROTO_NAME(f), oldState, f->state));
-}
-
-
-/*
- * fsm_open - Link is allowed to come up.
- */
-void fsm_open(fsm *f)
-{
-       int oldState = f->state;
-       
-       switch( f->state ){
-               case INITIAL:
-                       f->state = STARTING;
-                       if( f->callbacks->starting )
-                               (*f->callbacks->starting)(f);
-                       break;
-               
-               case CLOSED:
-               if( f->flags & OPT_SILENT )
-                       f->state = STOPPED;
-               else {
-                       /* Send an initial configure-request */
-                       fsm_sconfreq(f, 0);
-                       f->state = REQSENT;
-               }
-               break;
-       
-       case CLOSING:
-               f->state = STOPPING;
-               /* fall through */
-       case STOPPED:
-       case OPENED:
-               if( f->flags & OPT_RESTART ){
-                       fsm_lowerdown(f);
-                       fsm_lowerup(f);
-               }
-               break;
-       }
-       
-       FSMDEBUG((LOG_INFO, "%s: open state %d -> %d\n",
-                       PROTO_NAME(f), oldState, f->state));
-}
-
-
-/*
- * fsm_close - Start closing connection.
- *
- * Cancel timeouts and either initiate close or possibly go directly to
- * the CLOSED state.
- */
-void fsm_close(fsm *f, char *reason)
-{
-       int oldState = f->state;
-       
-       f->term_reason = reason;
-       f->term_reason_len = (reason == NULL? 0: strlen(reason));
-       switch( f->state ){
-       case STARTING:
-               f->state = INITIAL;
-               break;
-       case STOPPED:
-               f->state = CLOSED;
-               break;
-       case STOPPING:
-               f->state = CLOSING;
-               break;
-       
-       case REQSENT:
-       case ACKRCVD:
-       case ACKSENT:
-       case OPENED:
-               if( f->state != OPENED )
-                       UNTIMEOUT(fsm_timeout, f);      /* Cancel timeout */
-               else if( f->callbacks->down )
-                       (*f->callbacks->down)(f);       /* Inform upper layers we're down */
-               
-               /* Init restart counter, send Terminate-Request */
-               f->retransmits = f->maxtermtransmits;
-               fsm_sdata(f, TERMREQ, f->reqid = ++f->id,
-                                       (u_char *) f->term_reason, f->term_reason_len);
-               TIMEOUT(fsm_timeout, f, f->timeouttime);
-               --f->retransmits;
-               
-               f->state = CLOSING;
-               break;
-       }
-       
-       FSMDEBUG((LOG_INFO, "%s: close reason=%s state %d -> %d\n",
-                       PROTO_NAME(f), reason, oldState, f->state));
-}
-
-
-/*
- * fsm_sdata - Send some data.
- *
- * Used for all packets sent to our peer by this module.
- */
-void fsm_sdata(
-       fsm *f,
-       u_char code, 
-       u_char id,
-       u_char *data,
-       int datalen
-)
-{
-       u_char *outp;
-       int outlen;
-       
-       /* Adjust length to be smaller than MTU */
-       outp = outpacket_buf[f->unit];
-       if (datalen > peer_mru[f->unit] - (int)HEADERLEN)
-               datalen = peer_mru[f->unit] - HEADERLEN;
-       if (datalen && data != outp + PPP_HDRLEN + HEADERLEN)
-               BCOPY(data, outp + PPP_HDRLEN + HEADERLEN, datalen);
-       outlen = datalen + HEADERLEN;
-       MAKEHEADER(outp, f->protocol);
-       PUTCHAR(code, outp);
-       PUTCHAR(id, outp);
-       PUTSHORT(outlen, outp);
-       pppWrite(f->unit, outpacket_buf[f->unit], outlen + PPP_HDRLEN);
-       FSMDEBUG((LOG_INFO, "fsm_sdata(%s): Sent code %d,%d,%d.\n",
-                               PROTO_NAME(f), code, id, outlen));
-}
-
-
-/*
- * fsm_input - Input packet.
- */
-void fsm_input(fsm *f, u_char *inpacket, int l)
-{
-       u_char *inp = inpacket;
-       u_char code, id;
-       int len;
-       
-       /*
-       * Parse header (code, id and length).
-       * If packet too short, drop it.
-       */
-       if (l < HEADERLEN) {
-               FSMDEBUG((LOG_WARNING, "fsm_input(%x): Rcvd short header.\n",
-                                       f->protocol));
-               return;
-       }
-       GETCHAR(code, inp);
-       GETCHAR(id, inp);
-       GETSHORT(len, inp);
-       if (len < HEADERLEN) {
-               FSMDEBUG((LOG_INFO, "fsm_input(%x): Rcvd illegal length.\n",
-                               f->protocol));
-               return;
-       }
-       if (len > l) {
-               FSMDEBUG((LOG_INFO, "fsm_input(%x): Rcvd short packet.\n",
-                               f->protocol));
-               return;
-       }
-       len -= HEADERLEN;               /* subtract header length */
-       
-       if( f->state == INITIAL || f->state == STARTING ){
-               FSMDEBUG((LOG_INFO, "fsm_input(%x): Rcvd packet in state %d.\n",
-                               f->protocol, f->state));
-               return;
-       }
-       FSMDEBUG((LOG_INFO, "fsm_input(%s):%d,%d,%d\n", PROTO_NAME(f), code, id, l));
-       /*
-        * Action depends on code.
-        */
-       switch (code) {
-       case CONFREQ:
-               fsm_rconfreq(f, id, inp, len);
-               break;
-       
-       case CONFACK:
-               fsm_rconfack(f, id, inp, len);
-               break;
-       
-       case CONFNAK:
-       case CONFREJ:
-               fsm_rconfnakrej(f, code, id, inp, len);
-               break;
-       
-       case TERMREQ:
-               fsm_rtermreq(f, id, inp, len);
-               break;
-       
-       case TERMACK:
-               fsm_rtermack(f);
-               break;
-       
-       case CODEREJ:
-               fsm_rcoderej(f, inp, len);
-               break;
-       
-       default:
-               if( !f->callbacks->extcode
-                               || !(*f->callbacks->extcode)(f, code, id, inp, len) )
-                       fsm_sdata(f, CODEREJ, ++f->id, inpacket, len + HEADERLEN);
-               break;
-       }
-}
-
-
-/*
- * fsm_protreject - Peer doesn't speak this protocol.
- *
- * Treat this as a catastrophic error (RXJ-).
- */
-void fsm_protreject(fsm *f)
-{
-       switch( f->state ){
-       case CLOSING:
-               UNTIMEOUT(fsm_timeout, f);      /* Cancel timeout */
-               /* fall through */
-       case CLOSED:
-               f->state = CLOSED;
-               if( f->callbacks->finished )
-                       (*f->callbacks->finished)(f);
-               break;
-       
-       case STOPPING:
-       case REQSENT:
-       case ACKRCVD:
-       case ACKSENT:
-               UNTIMEOUT(fsm_timeout, f);      /* Cancel timeout */
-               /* fall through */
-       case STOPPED:
-               f->state = STOPPED;
-               if( f->callbacks->finished )
-                       (*f->callbacks->finished)(f);
-               break;
-       
-       case OPENED:
-               if( f->callbacks->down )
-                       (*f->callbacks->down)(f);
-               
-               /* Init restart counter, send Terminate-Request */
-               f->retransmits = f->maxtermtransmits;
-               fsm_sdata(f, TERMREQ, f->reqid = ++f->id,
-                                       (u_char *) f->term_reason, f->term_reason_len);
-               TIMEOUT(fsm_timeout, f, f->timeouttime);
-               --f->retransmits;
-               
-               f->state = STOPPING;
-               break;
-       
-       default:
-               FSMDEBUG((LOG_INFO, "%s: Protocol-reject event in state %d!\n",
-                                       PROTO_NAME(f), f->state));
-       }
-}
-
-
-
-
-
-/**********************************/
-/*** LOCAL FUNCTION DEFINITIONS ***/
-/**********************************/
-
-/*
- * fsm_timeout - Timeout expired.
- */
-static void fsm_timeout(void *arg)
-{
-    fsm *f = (fsm *) arg;
-
-    switch (f->state) {
-    case CLOSING:
-    case STOPPING:
-               if( f->retransmits <= 0 ){
-                   FSMDEBUG((LOG_WARNING, "%s: timeout sending Terminate-Request state=%d\n",
-                                          PROTO_NAME(f), f->state));
-                   /*
-                    * We've waited for an ack long enough.  Peer probably heard us.
-                    */
-                   f->state = (f->state == CLOSING)? CLOSED: STOPPED;
-                   if( f->callbacks->finished )
-                       (*f->callbacks->finished)(f);
-               } else {
-                   FSMDEBUG((LOG_WARNING, "%s: timeout resending Terminate-Requests state=%d\n",
-                                          PROTO_NAME(f), f->state));
-                   /* Send Terminate-Request */
-                   fsm_sdata(f, TERMREQ, f->reqid = ++f->id,
-                             (u_char *) f->term_reason, f->term_reason_len);
-                   TIMEOUT(fsm_timeout, f, f->timeouttime);
-                   --f->retransmits;
-               }
-               break;
-
-    case REQSENT:
-    case ACKRCVD:
-    case ACKSENT:
-               if (f->retransmits <= 0) {
-                   FSMDEBUG((LOG_WARNING, "%s: timeout sending Config-Requests state=%d\n",
-                          PROTO_NAME(f), f->state));
-                   f->state = STOPPED;
-                   if( (f->flags & OPT_PASSIVE) == 0 && f->callbacks->finished )
-                               (*f->callbacks->finished)(f);
-       
-               } else {
-                   FSMDEBUG((LOG_WARNING, "%s: timeout resending Config-Request state=%d\n",
-                          PROTO_NAME(f), f->state));
-                   /* Retransmit the configure-request */
-                   if (f->callbacks->retransmit)
-                               (*f->callbacks->retransmit)(f);
-                   fsm_sconfreq(f, 1);         /* Re-send Configure-Request */
-                   if( f->state == ACKRCVD )
-                               f->state = REQSENT;
-               }
-               break;
-
-    default:
-               FSMDEBUG((LOG_INFO, "%s: Timeout event in state %d!\n",
-                                 PROTO_NAME(f), f->state));
-           }
-}
-
-
-/*
- * fsm_rconfreq - Receive Configure-Request.
- */
-static void fsm_rconfreq(fsm *f, u_char id, u_char *inp, int len)
-{
-       int code, reject_if_disagree;
-       
-       FSMDEBUG((LOG_INFO, "fsm_rconfreq(%s): Rcvd id %d state=%d\n", 
-                               PROTO_NAME(f), id, f->state));
-       switch( f->state ){
-       case CLOSED:
-               /* Go away, we're closed */
-               fsm_sdata(f, TERMACK, id, NULL, 0);
-               return;
-       case CLOSING:
-       case STOPPING:
-               return;
-       
-       case OPENED:
-               /* Go down and restart negotiation */
-               if( f->callbacks->down )
-                       (*f->callbacks->down)(f);       /* Inform upper layers */
-               fsm_sconfreq(f, 0);             /* Send initial Configure-Request */
-               break;
-       
-       case STOPPED:
-               /* Negotiation started by our peer */
-               fsm_sconfreq(f, 0);             /* Send initial Configure-Request */
-               f->state = REQSENT;
-               break;
-       }
-       
-       /*
-       * Pass the requested configuration options
-       * to protocol-specific code for checking.
-       */
-       if (f->callbacks->reqci){               /* Check CI */
-               reject_if_disagree = (f->nakloops >= f->maxnakloops);
-               code = (*f->callbacks->reqci)(f, inp, &len, reject_if_disagree);
-       } 
-       else if (len)
-               code = CONFREJ;                 /* Reject all CI */
-       else
-               code = CONFACK;
-       
-       /* send the Ack, Nak or Rej to the peer */
-       fsm_sdata(f, (u_char)code, id, inp, len);
-       
-       if (code == CONFACK) {
-               if (f->state == ACKRCVD) {
-                       UNTIMEOUT(fsm_timeout, f);      /* Cancel timeout */
-                       f->state = OPENED;
-                       if (f->callbacks->up)
-                               (*f->callbacks->up)(f); /* Inform upper layers */
-               } 
-               else
-                       f->state = ACKSENT;
-               f->nakloops = 0;
-       } 
-       else {
-               /* we sent CONFACK or CONFREJ */
-               if (f->state != ACKRCVD)
-                       f->state = REQSENT;
-               if( code == CONFNAK )
-                       ++f->nakloops;
-       }
-}
-
-
-/*
- * fsm_rconfack - Receive Configure-Ack.
- */
-static void fsm_rconfack(fsm *f, int id, u_char *inp, int len)
-{
-       FSMDEBUG((LOG_INFO, "fsm_rconfack(%s): Rcvd id %d state=%d\n",
-                               PROTO_NAME(f), id, f->state));
-       
-       if (id != f->reqid || f->seen_ack)              /* Expected id? */
-               return;                                 /* Nope, toss... */
-       if( !(f->callbacks->ackci? (*f->callbacks->ackci)(f, inp, len):
-                                                               (len == 0)) ){
-               /* Ack is bad - ignore it */
-               FSMDEBUG((LOG_INFO, "%s: received bad Ack (length %d)\n",
-                                       PROTO_NAME(f), len));
-               return;
-       }
-       f->seen_ack = 1;
-       
-       switch (f->state) {
-       case CLOSED:
-       case STOPPED:
-               fsm_sdata(f, TERMACK, (u_char)id, NULL, 0);
-               break;
-       
-       case REQSENT:
-               f->state = ACKRCVD;
-               f->retransmits = f->maxconfreqtransmits;
-               break;
-       
-       case ACKRCVD:
-               /* Huh? an extra valid Ack? oh well... */
-               UNTIMEOUT(fsm_timeout, f);      /* Cancel timeout */
-               fsm_sconfreq(f, 0);
-               f->state = REQSENT;
-               break;
-       
-       case ACKSENT:
-               UNTIMEOUT(fsm_timeout, f);      /* Cancel timeout */
-               f->state = OPENED;
-               f->retransmits = f->maxconfreqtransmits;
-               if (f->callbacks->up)
-                       (*f->callbacks->up)(f); /* Inform upper layers */
-               break;
-       
-       case OPENED:
-               /* Go down and restart negotiation */
-               if (f->callbacks->down)
-                       (*f->callbacks->down)(f);       /* Inform upper layers */
-               fsm_sconfreq(f, 0);             /* Send initial Configure-Request */
-               f->state = REQSENT;
-               break;
-       }
-}
-
-
-/*
- * fsm_rconfnakrej - Receive Configure-Nak or Configure-Reject.
- */
-static void fsm_rconfnakrej(fsm *f, int code, int id, u_char *inp, int len)
-{
-       int (*proc) (fsm *, u_char *, int);
-       int ret;
-       
-       FSMDEBUG((LOG_INFO, "fsm_rconfnakrej(%s): Rcvd id %d state=%d\n",
-                               PROTO_NAME(f), id, f->state));
-       
-       if (id != f->reqid || f->seen_ack)      /* Expected id? */
-               return;                         /* Nope, toss... */
-       proc = (code == CONFNAK)? f->callbacks->nakci: f->callbacks->rejci;
-       if (!proc || !(ret = proc(f, inp, len))) {
-               /* Nak/reject is bad - ignore it */
-               FSMDEBUG((LOG_INFO, "%s: received bad %s (length %d)\n",
-                                       PROTO_NAME(f), (code==CONFNAK? "Nak": "reject"), len));
-               return;
-       }
-       f->seen_ack = 1;
-       
-       switch (f->state) {
-       case CLOSED:
-       case STOPPED:
-               fsm_sdata(f, TERMACK, (u_char)id, NULL, 0);
-               break;
-       
-       case REQSENT:
-       case ACKSENT:
-               /* They didn't agree to what we wanted - try another request */
-               UNTIMEOUT(fsm_timeout, f);      /* Cancel timeout */
-               if (ret < 0)
-                       f->state = STOPPED;             /* kludge for stopping CCP */
-               else
-                       fsm_sconfreq(f, 0);             /* Send Configure-Request */
-               break;
-       
-       case ACKRCVD:
-               /* Got a Nak/reject when we had already had an Ack?? oh well... */
-               UNTIMEOUT(fsm_timeout, f);      /* Cancel timeout */
-               fsm_sconfreq(f, 0);
-               f->state = REQSENT;
-               break;
-       
-       case OPENED:
-               /* Go down and restart negotiation */
-               if (f->callbacks->down)
-                       (*f->callbacks->down)(f);       /* Inform upper layers */
-               fsm_sconfreq(f, 0);             /* Send initial Configure-Request */
-               f->state = REQSENT;
-               break;
-       }
-}
-
-
-/*
- * fsm_rtermreq - Receive Terminate-Req.
- */
-static void fsm_rtermreq(fsm *f, int id, u_char *p, int len)
-{
-       FSMDEBUG((LOG_INFO, "fsm_rtermreq(%s): Rcvd id %d state=%d\n",
-                               PROTO_NAME(f), id, f->state));
-       
-       switch (f->state) {
-       case ACKRCVD:
-       case ACKSENT:
-               f->state = REQSENT;             /* Start over but keep trying */
-               break;
-       
-       case OPENED:
-               if (len > 0) {
-                       FSMDEBUG((LOG_INFO, "%s terminated by peer (%x)\n", PROTO_NAME(f), p));
-               } else {
-                       FSMDEBUG((LOG_INFO, "%s terminated by peer\n", PROTO_NAME(f)));
-               }
-               if (f->callbacks->down)
-                       (*f->callbacks->down)(f);       /* Inform upper layers */
-               f->retransmits = 0;
-               f->state = STOPPING;
-               TIMEOUT(fsm_timeout, f, f->timeouttime);
-               break;
-       }
-       
-       fsm_sdata(f, TERMACK, (u_char)id, NULL, 0);
-}
-
-
-/*
- * fsm_rtermack - Receive Terminate-Ack.
- */
-static void fsm_rtermack(fsm *f)
-{
-       FSMDEBUG((LOG_INFO, "fsm_rtermack(%s): state=%d\n", 
-                               PROTO_NAME(f), f->state));
-       
-       switch (f->state) {
-       case CLOSING:
-               UNTIMEOUT(fsm_timeout, f);
-               f->state = CLOSED;
-               if( f->callbacks->finished )
-                       (*f->callbacks->finished)(f);
-               break;
-       case STOPPING:
-               UNTIMEOUT(fsm_timeout, f);
-               f->state = STOPPED;
-               if( f->callbacks->finished )
-                       (*f->callbacks->finished)(f);
-               break;
-       
-       case ACKRCVD:
-               f->state = REQSENT;
-               break;
-       
-       case OPENED:
-               if (f->callbacks->down)
-                       (*f->callbacks->down)(f);       /* Inform upper layers */
-               fsm_sconfreq(f, 0);
-               break;
-       }
-}
-
-
-/*
- * fsm_rcoderej - Receive an Code-Reject.
- */
-static void fsm_rcoderej(fsm *f, u_char *inp, int len)
-{
-       u_char code, id;
-       
-       FSMDEBUG((LOG_INFO, "fsm_rcoderej(%s): state=%d\n", 
-                               PROTO_NAME(f), f->state));
-       
-       if (len < HEADERLEN) {
-               FSMDEBUG((LOG_INFO, "fsm_rcoderej: Rcvd short Code-Reject packet!\n"));
-               return;
-       }
-       GETCHAR(code, inp);
-       GETCHAR(id, inp);
-       FSMDEBUG((LOG_WARNING, "%s: Rcvd Code-Reject for code %d, id %d\n",
-                               PROTO_NAME(f), code, id));
-       
-       if( f->state == ACKRCVD )
-               f->state = REQSENT;
-}
-
-
-/*
- * fsm_sconfreq - Send a Configure-Request.
- */
-static void fsm_sconfreq(fsm *f, int retransmit)
-{
-       u_char *outp;
-       int cilen;
-       
-       if( f->state != REQSENT && f->state != ACKRCVD && f->state != ACKSENT ){
-               /* Not currently negotiating - reset options */
-               if( f->callbacks->resetci )
-                       (*f->callbacks->resetci)(f);
-               f->nakloops = 0;
-               }
-       
-       if( !retransmit ){
-               /* New request - reset retransmission counter, use new ID */
-               f->retransmits = f->maxconfreqtransmits;
-               f->reqid = ++f->id;
-       }
-       
-       f->seen_ack = 0;
-       
-       /*
-        * Make up the request packet
-        */
-       outp = outpacket_buf[f->unit] + PPP_HDRLEN + HEADERLEN;
-       if( f->callbacks->cilen && f->callbacks->addci ){
-               cilen = (*f->callbacks->cilen)(f);
-               if( cilen > peer_mru[f->unit] - (int)HEADERLEN )
-                       cilen = peer_mru[f->unit] - HEADERLEN;
-               if (f->callbacks->addci)
-                       (*f->callbacks->addci)(f, outp, &cilen);
-       } else
-               cilen = 0;
-       
-       /* send the request to our peer */
-       fsm_sdata(f, CONFREQ, f->reqid, outp, cilen);
-       
-       /* start the retransmit timer */
-       --f->retransmits;
-       TIMEOUT(fsm_timeout, f, f->timeouttime);
-       
-       FSMDEBUG((LOG_INFO, "%s: sending Configure-Request, id %d\n",
-                               PROTO_NAME(f), f->reqid));
-}
-
-#endif /* PPP_SUPPORT */
+/*****************************************************************************\r
+* fsm.c - Network Control Protocol Finite State Machine program file.\r
+*\r
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.\r
+* portions Copyright (c) 1997 by Global Election Systems Inc.\r
+*\r
+* The authors hereby grant permission to use, copy, modify, distribute,\r
+* and license this software and its documentation for any purpose, provided\r
+* that existing copyright notices are retained in all copies and that this\r
+* notice and the following disclaimer are included verbatim in any \r
+* distributions. No written agreement, license, or royalty fee is required\r
+* for any of the authorized uses.\r
+*\r
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR\r
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+*\r
+******************************************************************************\r
+* REVISION HISTORY\r
+*\r
+* 03-01-01 Marc Boucher <marc@mbsi.ca>\r
+*   Ported to lwIP.\r
+* 97-12-01 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.\r
+*      Original based on BSD fsm.c.\r
+*****************************************************************************/\r
+/*\r
+ * fsm.c - {Link, IP} Control Protocol Finite State Machine.\r
+ *\r
+ * Copyright (c) 1989 Carnegie Mellon University.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms are permitted\r
+ * provided that the above copyright notice and this paragraph are\r
+ * duplicated in all such forms and that any documentation,\r
+ * advertising materials, and other materials related to such\r
+ * distribution and use acknowledge that the software was developed\r
+ * by Carnegie Mellon University.  The name of the\r
+ * University may not be used to endorse or promote products derived\r
+ * from this software without specific prior written permission.\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR\r
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r
+ */\r
+\r
+\r
+/*\r
+ * TODO:\r
+ * Randomize fsm id on link/init.\r
+ * Deal with variable outgoing MTU.\r
+ */\r
+\r
+#include "ppp.h"\r
+#if PPP_SUPPORT > 0\r
+#include "fsm.h"\r
+#include "pppdebug.h"\r
+\r
+\r
+/*************************/\r
+/*** LOCAL DEFINITIONS ***/\r
+/*************************/\r
+\r
+\r
+/************************/\r
+/*** LOCAL DATA TYPES ***/\r
+/************************/\r
+\r
+\r
+/***********************************/\r
+/*** LOCAL FUNCTION DECLARATIONS ***/\r
+/***********************************/\r
+static void fsm_timeout (void *);\r
+static void fsm_rconfreq (fsm *, u_char, u_char *, int);\r
+static void fsm_rconfack (fsm *, int, u_char *, int);\r
+static void fsm_rconfnakrej (fsm *, int, int, u_char *, int);\r
+static void fsm_rtermreq (fsm *, int, u_char *, int);\r
+static void fsm_rtermack (fsm *);\r
+static void fsm_rcoderej (fsm *, u_char *, int);\r
+static void fsm_sconfreq (fsm *, int);\r
+\r
+#define PROTO_NAME(f)  ((f)->callbacks->proto_name)\r
+\r
+\r
+/******************************/\r
+/*** PUBLIC DATA STRUCTURES ***/\r
+/******************************/\r
+\r
+\r
+/*****************************/\r
+/*** LOCAL DATA STRUCTURES ***/\r
+/*****************************/\r
+int peer_mru[NUM_PPP];\r
+\r
+\r
+/***********************************/\r
+/*** PUBLIC FUNCTION DEFINITIONS ***/\r
+/***********************************/\r
+\r
+/*\r
+ * fsm_init - Initialize fsm.\r
+ *\r
+ * Initialize fsm state.\r
+ */\r
+void fsm_init(fsm *f)\r
+{\r
+       f->state = INITIAL;\r
+       f->flags = 0;\r
+       f->id = 0;                              /* XXX Start with random id? */\r
+       f->timeouttime = FSM_DEFTIMEOUT;\r
+       f->maxconfreqtransmits = FSM_DEFMAXCONFREQS;\r
+       f->maxtermtransmits = FSM_DEFMAXTERMREQS;\r
+       f->maxnakloops = FSM_DEFMAXNAKLOOPS;\r
+       f->term_reason_len = 0;\r
+}\r
+\r
+\r
+/*\r
+ * fsm_lowerup - The lower layer is up.\r
+ */\r
+void fsm_lowerup(fsm *f)\r
+{\r
+       int oldState = f->state;\r
+\r
+       switch( f->state ){\r
+       case INITIAL:\r
+               f->state = CLOSED;\r
+               break;\r
+       \r
+       case STARTING:\r
+               if( f->flags & OPT_SILENT )\r
+                       f->state = STOPPED;\r
+               else {\r
+                       /* Send an initial configure-request */\r
+                       fsm_sconfreq(f, 0);\r
+                       f->state = REQSENT;\r
+               }\r
+       break;\r
+       \r
+       default:\r
+               FSMDEBUG((LOG_INFO, "%s: Up event in state %d!\n",\r
+                               PROTO_NAME(f), f->state));\r
+       }\r
+       \r
+       FSMDEBUG((LOG_INFO, "%s: lowerup state %d -> %d\n",\r
+                       PROTO_NAME(f), oldState, f->state));\r
+}\r
+\r
+\r
+/*\r
+ * fsm_lowerdown - The lower layer is down.\r
+ *\r
+ * Cancel all timeouts and inform upper layers.\r
+ */\r
+void fsm_lowerdown(fsm *f)\r
+{\r
+       int oldState = f->state;\r
+       \r
+       switch( f->state ){\r
+       case CLOSED:\r
+               f->state = INITIAL;\r
+               break;\r
+       \r
+       case STOPPED:\r
+               f->state = STARTING;\r
+               if( f->callbacks->starting )\r
+                       (*f->callbacks->starting)(f);\r
+               break;\r
+       \r
+       case CLOSING:\r
+               f->state = INITIAL;\r
+               UNTIMEOUT(fsm_timeout, f);      /* Cancel timeout */\r
+               break;\r
+       \r
+       case STOPPING:\r
+       case REQSENT:\r
+       case ACKRCVD:\r
+       case ACKSENT:\r
+               f->state = STARTING;\r
+               UNTIMEOUT(fsm_timeout, f);      /* Cancel timeout */\r
+               break;\r
+       \r
+       case OPENED:\r
+               if( f->callbacks->down )\r
+                       (*f->callbacks->down)(f);\r
+               f->state = STARTING;\r
+               break;\r
+       \r
+       default:\r
+               FSMDEBUG((LOG_INFO, "%s: Down event in state %d!\n",\r
+                               PROTO_NAME(f), f->state));\r
+       }\r
+       \r
+       FSMDEBUG((LOG_INFO, "%s: lowerdown state %d -> %d\n",\r
+                       PROTO_NAME(f), oldState, f->state));\r
+}\r
+\r
+\r
+/*\r
+ * fsm_open - Link is allowed to come up.\r
+ */\r
+void fsm_open(fsm *f)\r
+{\r
+       int oldState = f->state;\r
+       \r
+       switch( f->state ){\r
+               case INITIAL:\r
+                       f->state = STARTING;\r
+                       if( f->callbacks->starting )\r
+                               (*f->callbacks->starting)(f);\r
+                       break;\r
+               \r
+               case CLOSED:\r
+               if( f->flags & OPT_SILENT )\r
+                       f->state = STOPPED;\r
+               else {\r
+                       /* Send an initial configure-request */\r
+                       fsm_sconfreq(f, 0);\r
+                       f->state = REQSENT;\r
+               }\r
+               break;\r
+       \r
+       case CLOSING:\r
+               f->state = STOPPING;\r
+               /* fall through */\r
+       case STOPPED:\r
+       case OPENED:\r
+               if( f->flags & OPT_RESTART ){\r
+                       fsm_lowerdown(f);\r
+                       fsm_lowerup(f);\r
+               }\r
+               break;\r
+       }\r
+       \r
+       FSMDEBUG((LOG_INFO, "%s: open state %d -> %d\n",\r
+                       PROTO_NAME(f), oldState, f->state));\r
+}\r
+\r
+\r
+/*\r
+ * fsm_close - Start closing connection.\r
+ *\r
+ * Cancel timeouts and either initiate close or possibly go directly to\r
+ * the CLOSED state.\r
+ */\r
+void fsm_close(fsm *f, char *reason)\r
+{\r
+       int oldState = f->state;\r
+       \r
+       f->term_reason = reason;\r
+       f->term_reason_len = (reason == NULL? 0: strlen(reason));\r
+       switch( f->state ){\r
+       case STARTING:\r
+               f->state = INITIAL;\r
+               break;\r
+       case STOPPED:\r
+               f->state = CLOSED;\r
+               break;\r
+       case STOPPING:\r
+               f->state = CLOSING;\r
+               break;\r
+       \r
+       case REQSENT:\r
+       case ACKRCVD:\r
+       case ACKSENT:\r
+       case OPENED:\r
+               if( f->state != OPENED )\r
+                       UNTIMEOUT(fsm_timeout, f);      /* Cancel timeout */\r
+               else if( f->callbacks->down )\r
+                       (*f->callbacks->down)(f);       /* Inform upper layers we're down */\r
+               \r
+               /* Init restart counter, send Terminate-Request */\r
+               f->retransmits = f->maxtermtransmits;\r
+               fsm_sdata(f, TERMREQ, f->reqid = ++f->id,\r
+                                       (u_char *) f->term_reason, f->term_reason_len);\r
+               TIMEOUT(fsm_timeout, f, f->timeouttime);\r
+               --f->retransmits;\r
+               \r
+               f->state = CLOSING;\r
+               break;\r
+       }\r
+       \r
+       FSMDEBUG((LOG_INFO, "%s: close reason=%s state %d -> %d\n",\r
+                       PROTO_NAME(f), reason, oldState, f->state));\r
+}\r
+\r
+\r
+/*\r
+ * fsm_sdata - Send some data.\r
+ *\r
+ * Used for all packets sent to our peer by this module.\r
+ */\r
+void fsm_sdata(\r
+       fsm *f,\r
+       u_char code, \r
+       u_char id,\r
+       u_char *data,\r
+       int datalen\r
+)\r
+{\r
+       u_char *outp;\r
+       int outlen;\r
+       \r
+       /* Adjust length to be smaller than MTU */\r
+       outp = outpacket_buf[f->unit];\r
+       if (datalen > peer_mru[f->unit] - (int)HEADERLEN)\r
+               datalen = peer_mru[f->unit] - HEADERLEN;\r
+       if (datalen && data != outp + PPP_HDRLEN + HEADERLEN)\r
+               BCOPY(data, outp + PPP_HDRLEN + HEADERLEN, datalen);\r
+       outlen = datalen + HEADERLEN;\r
+       MAKEHEADER(outp, f->protocol);\r
+       PUTCHAR(code, outp);\r
+       PUTCHAR(id, outp);\r
+       PUTSHORT(outlen, outp);\r
+       pppWrite(f->unit, outpacket_buf[f->unit], outlen + PPP_HDRLEN);\r
+       FSMDEBUG((LOG_INFO, "fsm_sdata(%s): Sent code %d,%d,%d.\n",\r
+                               PROTO_NAME(f), code, id, outlen));\r
+}\r
+\r
+\r
+/*\r
+ * fsm_input - Input packet.\r
+ */\r
+void fsm_input(fsm *f, u_char *inpacket, int l)\r
+{\r
+       u_char *inp = inpacket;\r
+       u_char code, id;\r
+       int len;\r
+       \r
+       /*\r
+       * Parse header (code, id and length).\r
+       * If packet too short, drop it.\r
+       */\r
+       if (l < HEADERLEN) {\r
+               FSMDEBUG((LOG_WARNING, "fsm_input(%x): Rcvd short header.\n",\r
+                                       f->protocol));\r
+               return;\r
+       }\r
+       GETCHAR(code, inp);\r
+       GETCHAR(id, inp);\r
+       GETSHORT(len, inp);\r
+       if (len < HEADERLEN) {\r
+               FSMDEBUG((LOG_INFO, "fsm_input(%x): Rcvd illegal length.\n",\r
+                               f->protocol));\r
+               return;\r
+       }\r
+       if (len > l) {\r
+               FSMDEBUG((LOG_INFO, "fsm_input(%x): Rcvd short packet.\n",\r
+                               f->protocol));\r
+               return;\r
+       }\r
+       len -= HEADERLEN;               /* subtract header length */\r
+       \r
+       if( f->state == INITIAL || f->state == STARTING ){\r
+               FSMDEBUG((LOG_INFO, "fsm_input(%x): Rcvd packet in state %d.\n",\r
+                               f->protocol, f->state));\r
+               return;\r
+       }\r
+       FSMDEBUG((LOG_INFO, "fsm_input(%s):%d,%d,%d\n", PROTO_NAME(f), code, id, l));\r
+       /*\r
+        * Action depends on code.\r
+        */\r
+       switch (code) {\r
+       case CONFREQ:\r
+               fsm_rconfreq(f, id, inp, len);\r
+               break;\r
+       \r
+       case CONFACK:\r
+               fsm_rconfack(f, id, inp, len);\r
+               break;\r
+       \r
+       case CONFNAK:\r
+       case CONFREJ:\r
+               fsm_rconfnakrej(f, code, id, inp, len);\r
+               break;\r
+       \r
+       case TERMREQ:\r
+               fsm_rtermreq(f, id, inp, len);\r
+               break;\r
+       \r
+       case TERMACK:\r
+               fsm_rtermack(f);\r
+               break;\r
+       \r
+       case CODEREJ:\r
+               fsm_rcoderej(f, inp, len);\r
+               break;\r
+       \r
+       default:\r
+               if( !f->callbacks->extcode\r
+                               || !(*f->callbacks->extcode)(f, code, id, inp, len) )\r
+                       fsm_sdata(f, CODEREJ, ++f->id, inpacket, len + HEADERLEN);\r
+               break;\r
+       }\r
+}\r
+\r
+\r
+/*\r
+ * fsm_protreject - Peer doesn't speak this protocol.\r
+ *\r
+ * Treat this as a catastrophic error (RXJ-).\r
+ */\r
+void fsm_protreject(fsm *f)\r
+{\r
+       switch( f->state ){\r
+       case CLOSING:\r
+               UNTIMEOUT(fsm_timeout, f);      /* Cancel timeout */\r
+               /* fall through */\r
+       case CLOSED:\r
+               f->state = CLOSED;\r
+               if( f->callbacks->finished )\r
+                       (*f->callbacks->finished)(f);\r
+               break;\r
+       \r
+       case STOPPING:\r
+       case REQSENT:\r
+       case ACKRCVD:\r
+       case ACKSENT:\r
+               UNTIMEOUT(fsm_timeout, f);      /* Cancel timeout */\r
+               /* fall through */\r
+       case STOPPED:\r
+               f->state = STOPPED;\r
+               if( f->callbacks->finished )\r
+                       (*f->callbacks->finished)(f);\r
+               break;\r
+       \r
+       case OPENED:\r
+               if( f->callbacks->down )\r
+                       (*f->callbacks->down)(f);\r
+               \r
+               /* Init restart counter, send Terminate-Request */\r
+               f->retransmits = f->maxtermtransmits;\r
+               fsm_sdata(f, TERMREQ, f->reqid = ++f->id,\r
+                                       (u_char *) f->term_reason, f->term_reason_len);\r
+               TIMEOUT(fsm_timeout, f, f->timeouttime);\r
+               --f->retransmits;\r
+               \r
+               f->state = STOPPING;\r
+               break;\r
+       \r
+       default:\r
+               FSMDEBUG((LOG_INFO, "%s: Protocol-reject event in state %d!\n",\r
+                                       PROTO_NAME(f), f->state));\r
+       }\r
+}\r
+\r
+\r
+\r
+\r
+\r
+/**********************************/\r
+/*** LOCAL FUNCTION DEFINITIONS ***/\r
+/**********************************/\r
+\r
+/*\r
+ * fsm_timeout - Timeout expired.\r
+ */\r
+static void fsm_timeout(void *arg)\r
+{\r
+    fsm *f = (fsm *) arg;\r
+\r
+    switch (f->state) {\r
+    case CLOSING:\r
+    case STOPPING:\r
+               if( f->retransmits <= 0 ){\r
+                   FSMDEBUG((LOG_WARNING, "%s: timeout sending Terminate-Request state=%d\n",\r
+                                          PROTO_NAME(f), f->state));\r
+                   /*\r
+                    * We've waited for an ack long enough.  Peer probably heard us.\r
+                    */\r
+                   f->state = (f->state == CLOSING)? CLOSED: STOPPED;\r
+                   if( f->callbacks->finished )\r
+                       (*f->callbacks->finished)(f);\r
+               } else {\r
+                   FSMDEBUG((LOG_WARNING, "%s: timeout resending Terminate-Requests state=%d\n",\r
+                                          PROTO_NAME(f), f->state));\r
+                   /* Send Terminate-Request */\r
+                   fsm_sdata(f, TERMREQ, f->reqid = ++f->id,\r
+                             (u_char *) f->term_reason, f->term_reason_len);\r
+                   TIMEOUT(fsm_timeout, f, f->timeouttime);\r
+                   --f->retransmits;\r
+               }\r
+               break;\r
+\r
+    case REQSENT:\r
+    case ACKRCVD:\r
+    case ACKSENT:\r
+               if (f->retransmits <= 0) {\r
+                   FSMDEBUG((LOG_WARNING, "%s: timeout sending Config-Requests state=%d\n",\r
+                          PROTO_NAME(f), f->state));\r
+                   f->state = STOPPED;\r
+                   if( (f->flags & OPT_PASSIVE) == 0 && f->callbacks->finished )\r
+                               (*f->callbacks->finished)(f);\r
+       \r
+               } else {\r
+                   FSMDEBUG((LOG_WARNING, "%s: timeout resending Config-Request state=%d\n",\r
+                          PROTO_NAME(f), f->state));\r
+                   /* Retransmit the configure-request */\r
+                   if (f->callbacks->retransmit)\r
+                               (*f->callbacks->retransmit)(f);\r
+                   fsm_sconfreq(f, 1);         /* Re-send Configure-Request */\r
+                   if( f->state == ACKRCVD )\r
+                               f->state = REQSENT;\r
+               }\r
+               break;\r
+\r
+    default:\r
+               FSMDEBUG((LOG_INFO, "%s: Timeout event in state %d!\n",\r
+                                 PROTO_NAME(f), f->state));\r
+           }\r
+}\r
+\r
+\r
+/*\r
+ * fsm_rconfreq - Receive Configure-Request.\r
+ */\r
+static void fsm_rconfreq(fsm *f, u_char id, u_char *inp, int len)\r
+{\r
+       int code, reject_if_disagree;\r
+       \r
+       FSMDEBUG((LOG_INFO, "fsm_rconfreq(%s): Rcvd id %d state=%d\n", \r
+                               PROTO_NAME(f), id, f->state));\r
+       switch( f->state ){\r
+       case CLOSED:\r
+               /* Go away, we're closed */\r
+               fsm_sdata(f, TERMACK, id, NULL, 0);\r
+               return;\r
+       case CLOSING:\r
+       case STOPPING:\r
+               return;\r
+       \r
+       case OPENED:\r
+               /* Go down and restart negotiation */\r
+               if( f->callbacks->down )\r
+                       (*f->callbacks->down)(f);       /* Inform upper layers */\r
+               fsm_sconfreq(f, 0);             /* Send initial Configure-Request */\r
+               break;\r
+       \r
+       case STOPPED:\r
+               /* Negotiation started by our peer */\r
+               fsm_sconfreq(f, 0);             /* Send initial Configure-Request */\r
+               f->state = REQSENT;\r
+               break;\r
+       }\r
+       \r
+       /*\r
+       * Pass the requested configuration options\r
+       * to protocol-specific code for checking.\r
+       */\r
+       if (f->callbacks->reqci){               /* Check CI */\r
+               reject_if_disagree = (f->nakloops >= f->maxnakloops);\r
+               code = (*f->callbacks->reqci)(f, inp, &len, reject_if_disagree);\r
+       } \r
+       else if (len)\r
+               code = CONFREJ;                 /* Reject all CI */\r
+       else\r
+               code = CONFACK;\r
+       \r
+       /* send the Ack, Nak or Rej to the peer */\r
+       fsm_sdata(f, (u_char)code, id, inp, len);\r
+       \r
+       if (code == CONFACK) {\r
+               if (f->state == ACKRCVD) {\r
+                       UNTIMEOUT(fsm_timeout, f);      /* Cancel timeout */\r
+                       f->state = OPENED;\r
+                       if (f->callbacks->up)\r
+                               (*f->callbacks->up)(f); /* Inform upper layers */\r
+               } \r
+               else\r
+                       f->state = ACKSENT;\r
+               f->nakloops = 0;\r
+       } \r
+       else {\r
+               /* we sent CONFACK or CONFREJ */\r
+               if (f->state != ACKRCVD)\r
+                       f->state = REQSENT;\r
+               if( code == CONFNAK )\r
+                       ++f->nakloops;\r
+       }\r
+}\r
+\r
+\r
+/*\r
+ * fsm_rconfack - Receive Configure-Ack.\r
+ */\r
+static void fsm_rconfack(fsm *f, int id, u_char *inp, int len)\r
+{\r
+       FSMDEBUG((LOG_INFO, "fsm_rconfack(%s): Rcvd id %d state=%d\n",\r
+                               PROTO_NAME(f), id, f->state));\r
+       \r
+       if (id != f->reqid || f->seen_ack)              /* Expected id? */\r
+               return;                                 /* Nope, toss... */\r
+       if( !(f->callbacks->ackci? (*f->callbacks->ackci)(f, inp, len):\r
+                                                               (len == 0)) ){\r
+               /* Ack is bad - ignore it */\r
+               FSMDEBUG((LOG_INFO, "%s: received bad Ack (length %d)\n",\r
+                                       PROTO_NAME(f), len));\r
+               return;\r
+       }\r
+       f->seen_ack = 1;\r
+       \r
+       switch (f->state) {\r
+       case CLOSED:\r
+       case STOPPED:\r
+               fsm_sdata(f, TERMACK, (u_char)id, NULL, 0);\r
+               break;\r
+       \r
+       case REQSENT:\r
+               f->state = ACKRCVD;\r
+               f->retransmits = f->maxconfreqtransmits;\r
+               break;\r
+       \r
+       case ACKRCVD:\r
+               /* Huh? an extra valid Ack? oh well... */\r
+               UNTIMEOUT(fsm_timeout, f);      /* Cancel timeout */\r
+               fsm_sconfreq(f, 0);\r
+               f->state = REQSENT;\r
+               break;\r
+       \r
+       case ACKSENT:\r
+               UNTIMEOUT(fsm_timeout, f);      /* Cancel timeout */\r
+               f->state = OPENED;\r
+               f->retransmits = f->maxconfreqtransmits;\r
+               if (f->callbacks->up)\r
+                       (*f->callbacks->up)(f); /* Inform upper layers */\r
+               break;\r
+       \r
+       case OPENED:\r
+               /* Go down and restart negotiation */\r
+               if (f->callbacks->down)\r
+                       (*f->callbacks->down)(f);       /* Inform upper layers */\r
+               fsm_sconfreq(f, 0);             /* Send initial Configure-Request */\r
+               f->state = REQSENT;\r
+               break;\r
+       }\r
+}\r
+\r
+\r
+/*\r
+ * fsm_rconfnakrej - Receive Configure-Nak or Configure-Reject.\r
+ */\r
+static void fsm_rconfnakrej(fsm *f, int code, int id, u_char *inp, int len)\r
+{\r
+       int (*proc) (fsm *, u_char *, int);\r
+       int ret;\r
+       \r
+       FSMDEBUG((LOG_INFO, "fsm_rconfnakrej(%s): Rcvd id %d state=%d\n",\r
+                               PROTO_NAME(f), id, f->state));\r
+       \r
+       if (id != f->reqid || f->seen_ack)      /* Expected id? */\r
+               return;                         /* Nope, toss... */\r
+       proc = (code == CONFNAK)? f->callbacks->nakci: f->callbacks->rejci;\r
+       if (!proc || !(ret = proc(f, inp, len))) {\r
+               /* Nak/reject is bad - ignore it */\r
+               FSMDEBUG((LOG_INFO, "%s: received bad %s (length %d)\n",\r
+                                       PROTO_NAME(f), (code==CONFNAK? "Nak": "reject"), len));\r
+               return;\r
+       }\r
+       f->seen_ack = 1;\r
+       \r
+       switch (f->state) {\r
+       case CLOSED:\r
+       case STOPPED:\r
+               fsm_sdata(f, TERMACK, (u_char)id, NULL, 0);\r
+               break;\r
+       \r
+       case REQSENT:\r
+       case ACKSENT:\r
+               /* They didn't agree to what we wanted - try another request */\r
+               UNTIMEOUT(fsm_timeout, f);      /* Cancel timeout */\r
+               if (ret < 0)\r
+                       f->state = STOPPED;             /* kludge for stopping CCP */\r
+               else\r
+                       fsm_sconfreq(f, 0);             /* Send Configure-Request */\r
+               break;\r
+       \r
+       case ACKRCVD:\r
+               /* Got a Nak/reject when we had already had an Ack?? oh well... */\r
+               UNTIMEOUT(fsm_timeout, f);      /* Cancel timeout */\r
+               fsm_sconfreq(f, 0);\r
+               f->state = REQSENT;\r
+               break;\r
+       \r
+       case OPENED:\r
+               /* Go down and restart negotiation */\r
+               if (f->callbacks->down)\r
+                       (*f->callbacks->down)(f);       /* Inform upper layers */\r
+               fsm_sconfreq(f, 0);             /* Send initial Configure-Request */\r
+               f->state = REQSENT;\r
+               break;\r
+       }\r
+}\r
+\r
+\r
+/*\r
+ * fsm_rtermreq - Receive Terminate-Req.\r
+ */\r
+static void fsm_rtermreq(fsm *f, int id, u_char *p, int len)\r
+{\r
+       FSMDEBUG((LOG_INFO, "fsm_rtermreq(%s): Rcvd id %d state=%d\n",\r
+                               PROTO_NAME(f), id, f->state));\r
+       \r
+       switch (f->state) {\r
+       case ACKRCVD:\r
+       case ACKSENT:\r
+               f->state = REQSENT;             /* Start over but keep trying */\r
+               break;\r
+       \r
+       case OPENED:\r
+               if (len > 0) {\r
+                       FSMDEBUG((LOG_INFO, "%s terminated by peer (%x)\n", PROTO_NAME(f), p));\r
+               } else {\r
+                       FSMDEBUG((LOG_INFO, "%s terminated by peer\n", PROTO_NAME(f)));\r
+               }\r
+               if (f->callbacks->down)\r
+                       (*f->callbacks->down)(f);       /* Inform upper layers */\r
+               f->retransmits = 0;\r
+               f->state = STOPPING;\r
+               TIMEOUT(fsm_timeout, f, f->timeouttime);\r
+               break;\r
+       }\r
+       \r
+       fsm_sdata(f, TERMACK, (u_char)id, NULL, 0);\r
+}\r
+\r
+\r
+/*\r
+ * fsm_rtermack - Receive Terminate-Ack.\r
+ */\r
+static void fsm_rtermack(fsm *f)\r
+{\r
+       FSMDEBUG((LOG_INFO, "fsm_rtermack(%s): state=%d\n", \r
+                               PROTO_NAME(f), f->state));\r
+       \r
+       switch (f->state) {\r
+       case CLOSING:\r
+               UNTIMEOUT(fsm_timeout, f);\r
+               f->state = CLOSED;\r
+               if( f->callbacks->finished )\r
+                       (*f->callbacks->finished)(f);\r
+               break;\r
+       case STOPPING:\r
+               UNTIMEOUT(fsm_timeout, f);\r
+               f->state = STOPPED;\r
+               if( f->callbacks->finished )\r
+                       (*f->callbacks->finished)(f);\r
+               break;\r
+       \r
+       case ACKRCVD:\r
+               f->state = REQSENT;\r
+               break;\r
+       \r
+       case OPENED:\r
+               if (f->callbacks->down)\r
+                       (*f->callbacks->down)(f);       /* Inform upper layers */\r
+               fsm_sconfreq(f, 0);\r
+               break;\r
+       }\r
+}\r
+\r
+\r
+/*\r
+ * fsm_rcoderej - Receive an Code-Reject.\r
+ */\r
+static void fsm_rcoderej(fsm *f, u_char *inp, int len)\r
+{\r
+       u_char code, id;\r
+       \r
+       FSMDEBUG((LOG_INFO, "fsm_rcoderej(%s): state=%d\n", \r
+                               PROTO_NAME(f), f->state));\r
+       \r
+       if (len < HEADERLEN) {\r
+               FSMDEBUG((LOG_INFO, "fsm_rcoderej: Rcvd short Code-Reject packet!\n"));\r
+               return;\r
+       }\r
+       GETCHAR(code, inp);\r
+       GETCHAR(id, inp);\r
+       FSMDEBUG((LOG_WARNING, "%s: Rcvd Code-Reject for code %d, id %d\n",\r
+                               PROTO_NAME(f), code, id));\r
+       \r
+       if( f->state == ACKRCVD )\r
+               f->state = REQSENT;\r
+}\r
+\r
+\r
+/*\r
+ * fsm_sconfreq - Send a Configure-Request.\r
+ */\r
+static void fsm_sconfreq(fsm *f, int retransmit)\r
+{\r
+       u_char *outp;\r
+       int cilen;\r
+       \r
+       if( f->state != REQSENT && f->state != ACKRCVD && f->state != ACKSENT ){\r
+               /* Not currently negotiating - reset options */\r
+               if( f->callbacks->resetci )\r
+                       (*f->callbacks->resetci)(f);\r
+               f->nakloops = 0;\r
+               }\r
+       \r
+       if( !retransmit ){\r
+               /* New request - reset retransmission counter, use new ID */\r
+               f->retransmits = f->maxconfreqtransmits;\r
+               f->reqid = ++f->id;\r
+       }\r
+       \r
+       f->seen_ack = 0;\r
+       \r
+       /*\r
+        * Make up the request packet\r
+        */\r
+       outp = outpacket_buf[f->unit] + PPP_HDRLEN + HEADERLEN;\r
+       if( f->callbacks->cilen && f->callbacks->addci ){\r
+               cilen = (*f->callbacks->cilen)(f);\r
+               if( cilen > peer_mru[f->unit] - (int)HEADERLEN )\r
+                       cilen = peer_mru[f->unit] - HEADERLEN;\r
+               if (f->callbacks->addci)\r
+                       (*f->callbacks->addci)(f, outp, &cilen);\r
+       } else\r
+               cilen = 0;\r
+       \r
+       /* send the request to our peer */\r
+       fsm_sdata(f, CONFREQ, f->reqid, outp, cilen);\r
+       \r
+       /* start the retransmit timer */\r
+       --f->retransmits;\r
+       TIMEOUT(fsm_timeout, f, f->timeouttime);\r
+       \r
+       FSMDEBUG((LOG_INFO, "%s: sending Configure-Request, id %d\n",\r
+                               PROTO_NAME(f), f->reqid));\r
+}\r
+\r
+#endif /* PPP_SUPPORT */\r
index 6b9b7fed3a7de9e10ccb873991bdeab48cfc73d4..9edd4d29ec2bbe6d7add647493761535cecb6f6a 100644 (file)
-/*****************************************************************************
-* fsm.h - Network Control Protocol Finite State Machine header file.
-*
-* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
-* Copyright (c) 1997 Global Election Systems Inc.
-*
-* The authors hereby grant permission to use, copy, modify, distribute,
-* and license this software and its documentation for any purpose, provided
-* that existing copyright notices are retained in all copies and that this
-* notice and the following disclaimer are included verbatim in any 
-* distributions. No written agreement, license, or royalty fee is required
-* for any of the authorized uses.
-*
-* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *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 CONTRIBUTORS 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.
-*
-******************************************************************************
-* REVISION HISTORY
-*
-* 03-01-01 Marc Boucher <marc@mbsi.ca>
-*   Ported to lwIP.
-* 97-11-05 Guy Lancaster <glanca@gesn.com>, Global Election Systems Inc.
-*      Original based on BSD code.
-*****************************************************************************/
-/*
- * fsm.h - {Link, IP} Control Protocol Finite State Machine definitions.
- *
- * Copyright (c) 1989 Carnegie Mellon University.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by Carnegie Mellon University.  The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * $Id: fsm.h,v 1.2 2006/08/29 18:53:47 wolti Exp $
- */
-
-#ifndef FSM_H
-#define FSM_H
-
-
-/*****************************************************************************
-************************* PUBLIC DEFINITIONS *********************************
-*****************************************************************************/
-/*
- * LCP Packet header = Code, id, length.
- */
-#define HEADERLEN      (sizeof (u_char) + sizeof (u_char) + sizeof (u_short))
-
-
-/*
- *  CP (LCP, IPCP, etc.) codes.
- */
-#define CONFREQ                1               /* Configuration Request */
-#define CONFACK                2               /* Configuration Ack */
-#define CONFNAK                3               /* Configuration Nak */
-#define CONFREJ                4               /* Configuration Reject */
-#define TERMREQ                5               /* Termination Request */
-#define TERMACK                6               /* Termination Ack */
-#define CODEREJ                7               /* Code Reject */
-
-/*
- * Link states.
- */
-#define INITIAL                0               /* Down, hasn't been opened */
-#define STARTING       1               /* Down, been opened */
-#define CLOSED         2               /* Up, hasn't been opened */
-#define STOPPED                3               /* Open, waiting for down event */
-#define CLOSING                4               /* Terminating the connection, not open */
-#define STOPPING       5               /* Terminating, but open */
-#define REQSENT                6               /* We've sent a Config Request */
-#define ACKRCVD                7               /* We've received a Config Ack */
-#define ACKSENT                8               /* We've sent a Config Ack */
-#define OPENED         9               /* Connection available */
-
-
-/*
- * Flags - indicate options controlling FSM operation
- */
-#define OPT_PASSIVE    1               /* Don't die if we don't get a response */
-#define OPT_RESTART    2               /* Treat 2nd OPEN as DOWN, UP */
-#define OPT_SILENT     4               /* Wait for peer to speak first */
-
-
-/*****************************************************************************
-************************* PUBLIC DATA TYPES **********************************
-*****************************************************************************/
-/*
- * Each FSM is described by an fsm structure and fsm callbacks.
- */
-typedef struct fsm {
-    int unit;                          /* Interface unit number */
-    u_short protocol;          /* Data Link Layer Protocol field value */
-    int state;                         /* State */
-    int flags;                         /* Contains option bits */
-    u_char id;                         /* Current id */
-    u_char reqid;                      /* Current request id */
-    u_char seen_ack;           /* Have received valid Ack/Nak/Rej to Req */
-    int timeouttime;           /* Timeout time in milliseconds */
-    int maxconfreqtransmits;/* Maximum Configure-Request transmissions */
-    int retransmits;           /* Number of retransmissions left */
-    int maxtermtransmits;      /* Maximum Terminate-Request transmissions */
-    int nakloops;                      /* Number of nak loops since last ack */
-    int maxnakloops;           /* Maximum number of nak loops tolerated */
-    struct fsm_callbacks* callbacks;/* Callback routines */
-    char* term_reason;         /* Reason for closing protocol */
-    int term_reason_len;       /* Length of term_reason */
-} fsm;
-
-
-typedef struct fsm_callbacks {
-    void (*resetci)                    /* Reset our Configuration Information */
-               (fsm*);
-    int  (*cilen)                      /* Length of our Configuration Information */
-               (fsm*);
-    void (*addci)                      /* Add our Configuration Information */
-               (fsm*, u_char*, int*);
-    int  (*ackci)                      /* ACK our Configuration Information */
-               (fsm*, u_char*, int);
-    int  (*nakci)                      /* NAK our Configuration Information */
-               (fsm*, u_char*, int);
-    int  (*rejci)                      /* Reject our Configuration Information */
-               (fsm*, u_char*, int);
-    int  (*reqci)                      /* Request peer's Configuration Information */
-               (fsm*, u_char*, int*, int);
-    void (*up)                         /* Called when fsm reaches OPENED state */
-               (fsm*);
-    void (*down)                       /* Called when fsm leaves OPENED state */
-               (fsm*);
-    void (*starting)           /* Called when we want the lower layer */
-               (fsm*);
-    void (*finished)           /* Called when we don't want the lower layer */
-               (fsm*);
-    void (*protreject)         /* Called when Protocol-Reject received */
-               (int);
-    void (*retransmit)         /* Retransmission is necessary */
-               (fsm*);
-    int  (*extcode)                    /* Called when unknown code received */
-               (fsm*, int, u_char, u_char*, int);
-    char *proto_name;          /* String name for protocol (for messages) */
-} fsm_callbacks;
-
-
-/*****************************************************************************
-*********************** PUBLIC DATA STRUCTURES *******************************
-*****************************************************************************/
-/*
- * Variables
- */
-extern int peer_mru[];         /* currently negotiated peer MRU (per unit) */
-
-
-/*****************************************************************************
-************************** PUBLIC FUNCTIONS **********************************
-*****************************************************************************/
-
-/*
- * Prototypes
- */
-void fsm_init (fsm*);
-void fsm_lowerup (fsm*);
-void fsm_lowerdown (fsm*);
-void fsm_open (fsm*);
-void fsm_close (fsm*, char*);
-void fsm_input (fsm*, u_char*, int);
-void fsm_protreject (fsm*);
-void fsm_sdata (fsm*, u_char, u_char, u_char*, int);
-
-
-#endif /* FSM_H */
-
+/*****************************************************************************\r
+* fsm.h - Network Control Protocol Finite State Machine header file.\r
+*\r
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.\r
+* Copyright (c) 1997 Global Election Systems Inc.\r
+*\r
+* The authors hereby grant permission to use, copy, modify, distribute,\r
+* and license this software and its documentation for any purpose, provided\r
+* that existing copyright notices are retained in all copies and that this\r
+* notice and the following disclaimer are included verbatim in any \r
+* distributions. No written agreement, license, or royalty fee is required\r
+* for any of the authorized uses.\r
+*\r
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR\r
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+*\r
+******************************************************************************\r
+* REVISION HISTORY\r
+*\r
+* 03-01-01 Marc Boucher <marc@mbsi.ca>\r
+*   Ported to lwIP.\r
+* 97-11-05 Guy Lancaster <glanca@gesn.com>, Global Election Systems Inc.\r
+*      Original based on BSD code.\r
+*****************************************************************************/\r
+/*\r
+ * fsm.h - {Link, IP} Control Protocol Finite State Machine definitions.\r
+ *\r
+ * Copyright (c) 1989 Carnegie Mellon University.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms are permitted\r
+ * provided that the above copyright notice and this paragraph are\r
+ * duplicated in all such forms and that any documentation,\r
+ * advertising materials, and other materials related to such\r
+ * distribution and use acknowledge that the software was developed\r
+ * by Carnegie Mellon University.  The name of the\r
+ * University may not be used to endorse or promote products derived\r
+ * from this software without specific prior written permission.\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR\r
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r
+ *\r
+ * $Id: fsm.h,v 1.2 2006/08/29 18:53:47 wolti Exp $\r
+ */\r
+\r
+#ifndef FSM_H\r
+#define FSM_H\r
+\r
+\r
+/*****************************************************************************\r
+************************* PUBLIC DEFINITIONS *********************************\r
+*****************************************************************************/\r
+/*\r
+ * LCP Packet header = Code, id, length.\r
+ */\r
+#define HEADERLEN      (sizeof (u_char) + sizeof (u_char) + sizeof (u_short))\r
+\r
+\r
+/*\r
+ *  CP (LCP, IPCP, etc.) codes.\r
+ */\r
+#define CONFREQ                1               /* Configuration Request */\r
+#define CONFACK                2               /* Configuration Ack */\r
+#define CONFNAK                3               /* Configuration Nak */\r
+#define CONFREJ                4               /* Configuration Reject */\r
+#define TERMREQ                5               /* Termination Request */\r
+#define TERMACK                6               /* Termination Ack */\r
+#define CODEREJ                7               /* Code Reject */\r
+\r
+/*\r
+ * Link states.\r
+ */\r
+#define INITIAL                0               /* Down, hasn't been opened */\r
+#define STARTING       1               /* Down, been opened */\r
+#define CLOSED         2               /* Up, hasn't been opened */\r
+#define STOPPED                3               /* Open, waiting for down event */\r
+#define CLOSING                4               /* Terminating the connection, not open */\r
+#define STOPPING       5               /* Terminating, but open */\r
+#define REQSENT                6               /* We've sent a Config Request */\r
+#define ACKRCVD                7               /* We've received a Config Ack */\r
+#define ACKSENT                8               /* We've sent a Config Ack */\r
+#define OPENED         9               /* Connection available */\r
+\r
+\r
+/*\r
+ * Flags - indicate options controlling FSM operation\r
+ */\r
+#define OPT_PASSIVE    1               /* Don't die if we don't get a response */\r
+#define OPT_RESTART    2               /* Treat 2nd OPEN as DOWN, UP */\r
+#define OPT_SILENT     4               /* Wait for peer to speak first */\r
+\r
+\r
+/*****************************************************************************\r
+************************* PUBLIC DATA TYPES **********************************\r
+*****************************************************************************/\r
+/*\r
+ * Each FSM is described by an fsm structure and fsm callbacks.\r
+ */\r
+typedef struct fsm {\r
+    int unit;                          /* Interface unit number */\r
+    u_short protocol;          /* Data Link Layer Protocol field value */\r
+    int state;                         /* State */\r
+    int flags;                         /* Contains option bits */\r
+    u_char id;                         /* Current id */\r
+    u_char reqid;                      /* Current request id */\r
+    u_char seen_ack;           /* Have received valid Ack/Nak/Rej to Req */\r
+    int timeouttime;           /* Timeout time in milliseconds */\r
+    int maxconfreqtransmits;/* Maximum Configure-Request transmissions */\r
+    int retransmits;           /* Number of retransmissions left */\r
+    int maxtermtransmits;      /* Maximum Terminate-Request transmissions */\r
+    int nakloops;                      /* Number of nak loops since last ack */\r
+    int maxnakloops;           /* Maximum number of nak loops tolerated */\r
+    struct fsm_callbacks* callbacks;/* Callback routines */\r
+    char* term_reason;         /* Reason for closing protocol */\r
+    int term_reason_len;       /* Length of term_reason */\r
+} fsm;\r
+\r
+\r
+typedef struct fsm_callbacks {\r
+    void (*resetci)                    /* Reset our Configuration Information */\r
+               (fsm*);\r
+    int  (*cilen)                      /* Length of our Configuration Information */\r
+               (fsm*);\r
+    void (*addci)                      /* Add our Configuration Information */\r
+               (fsm*, u_char*, int*);\r
+    int  (*ackci)                      /* ACK our Configuration Information */\r
+               (fsm*, u_char*, int);\r
+    int  (*nakci)                      /* NAK our Configuration Information */\r
+               (fsm*, u_char*, int);\r
+    int  (*rejci)                      /* Reject our Configuration Information */\r
+               (fsm*, u_char*, int);\r
+    int  (*reqci)                      /* Request peer's Configuration Information */\r
+               (fsm*, u_char*, int*, int);\r
+    void (*up)                         /* Called when fsm reaches OPENED state */\r
+               (fsm*);\r
+    void (*down)                       /* Called when fsm leaves OPENED state */\r
+               (fsm*);\r
+    void (*starting)           /* Called when we want the lower layer */\r
+               (fsm*);\r
+    void (*finished)           /* Called when we don't want the lower layer */\r
+               (fsm*);\r
+    void (*protreject)         /* Called when Protocol-Reject received */\r
+               (int);\r
+    void (*retransmit)         /* Retransmission is necessary */\r
+               (fsm*);\r
+    int  (*extcode)                    /* Called when unknown code received */\r
+               (fsm*, int, u_char, u_char*, int);\r
+    char *proto_name;          /* String name for protocol (for messages) */\r
+} fsm_callbacks;\r
+\r
+\r
+/*****************************************************************************\r
+*********************** PUBLIC DATA STRUCTURES *******************************\r
+*****************************************************************************/\r
+/*\r
+ * Variables\r
+ */\r
+extern int peer_mru[];         /* currently negotiated peer MRU (per unit) */\r
+\r
+\r
+/*****************************************************************************\r
+************************** PUBLIC FUNCTIONS **********************************\r
+*****************************************************************************/\r
+\r
+/*\r
+ * Prototypes\r
+ */\r
+void fsm_init (fsm*);\r
+void fsm_lowerup (fsm*);\r
+void fsm_lowerdown (fsm*);\r
+void fsm_open (fsm*);\r
+void fsm_close (fsm*, char*);\r
+void fsm_input (fsm*, u_char*, int);\r
+void fsm_protreject (fsm*);\r
+void fsm_sdata (fsm*, u_char, u_char, u_char*, int);\r
+\r
+\r
+#endif /* FSM_H */\r
+\r
index d5b251880997bba95b0036f161107d8c246af9da..ec3207a0c43fd9f39f135f4b95437e425eb375ec 100644 (file)
-/*****************************************************************************
-* ipcp.c - Network PPP IP Control Protocol program file.
-*
-* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
-* portions Copyright (c) 1997 by Global Election Systems Inc.
-*
-* The authors hereby grant permission to use, copy, modify, distribute,
-* and license this software and its documentation for any purpose, provided
-* that existing copyright notices are retained in all copies and that this
-* notice and the following disclaimer are included verbatim in any 
-* distributions. No written agreement, license, or royalty fee is required
-* for any of the authorized uses.
-*
-* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *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 CONTRIBUTORS 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.
-*
-******************************************************************************
-* REVISION HISTORY
-*
-* 03-01-01 Marc Boucher <marc@mbsi.ca>
-*   Ported to lwIP.
-* 97-12-08 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
-*      Original.
-*****************************************************************************/
-/*
- * ipcp.c - PPP IP Control Protocol.
- *
- * Copyright (c) 1989 Carnegie Mellon University.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by Carnegie Mellon University.  The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include <string.h>
-
-#include "ppp.h"
-#if PPP_SUPPORT > 0
-#include "auth.h"
-#include "fsm.h"
-#include "vj.h"
-#include "ipcp.h"
-#include "pppdebug.h"
-
-
-/*************************/
-/*** LOCAL DEFINITIONS ***/
-/*************************/
-/* #define OLD_CI_ADDRS 1 */   /* Support deprecated address negotiation. */
-
-/*
- * Lengths of configuration options.
- */
-#define CILEN_VOID     2
-#define CILEN_COMPRESS 4       /* min length for compression protocol opt. */
-#define CILEN_VJ       6       /* length for RFC1332 Van-Jacobson opt. */
-#define CILEN_ADDR     6       /* new-style single address option */
-#define CILEN_ADDRS    10      /* old-style dual address option */
-
-
-
-/***********************************/
-/*** LOCAL FUNCTION DECLARATIONS ***/
-/***********************************/
-/*
- * Callbacks for fsm code.  (CI = Configuration Information)
- */
-static void ipcp_resetci (fsm *);      /* Reset our CI */
-static int  ipcp_cilen (fsm *);                /* Return length of our CI */
-static void ipcp_addci (fsm *, u_char *, int *); /* Add our CI */
-static int  ipcp_ackci (fsm *, u_char *, int); /* Peer ack'd our CI */
-static int  ipcp_nakci (fsm *, u_char *, int); /* Peer nak'd our CI */
-static int  ipcp_rejci (fsm *, u_char *, int); /* Peer rej'd our CI */
-static int  ipcp_reqci (fsm *, u_char *, int *, int); /* Rcv CI */
-static void ipcp_up (fsm *);           /* We're UP */
-static void ipcp_down (fsm *);         /* We're DOWN */
-#if 0
-static void ipcp_script (fsm *, char *); /* Run an up/down script */
-#endif
-static void ipcp_finished (fsm *);     /* Don't need lower layer */
-
-/*
- * Protocol entry points from main code.
- */
-static void ipcp_init (int);
-static void ipcp_open (int);
-static void ipcp_close (int, char *);
-static void ipcp_lowerup (int);
-static void ipcp_lowerdown (int);
-static void ipcp_input (int, u_char *, int);
-static void ipcp_protrej (int);
-
-static void ipcp_clear_addrs (int);
-
-#define CODENAME(x)    ((x) == CONFACK ? "ACK" : \
-                        (x) == CONFNAK ? "NAK" : "REJ")
-
-
-
-/******************************/
-/*** PUBLIC DATA STRUCTURES ***/
-/******************************/
-/* global vars */
-ipcp_options ipcp_wantoptions[NUM_PPP];        /* Options that we want to request */
-ipcp_options ipcp_gotoptions[NUM_PPP]; /* Options that peer ack'd */
-ipcp_options ipcp_allowoptions[NUM_PPP];       /* Options we allow peer to request */
-ipcp_options ipcp_hisoptions[NUM_PPP]; /* Options that we ack'd */
-
-fsm ipcp_fsm[NUM_PPP];         /* IPCP fsm structure */
-
-struct protent ipcp_protent = {
-    PPP_IPCP,
-    ipcp_init,
-    ipcp_input,
-    ipcp_protrej,
-    ipcp_lowerup,
-    ipcp_lowerdown,
-    ipcp_open,
-    ipcp_close,
-#if 0
-    ipcp_printpkt,
-    NULL,
-#endif
-    1,
-    "IPCP",
-#if 0
-    ip_check_options,
-    NULL,
-    ip_active_pkt
-#endif
-};
-
-
-
-/*****************************/
-/*** LOCAL DATA STRUCTURES ***/
-/*****************************/
-/* local vars */
-static int cis_received[NUM_PPP];              /* # Conf-Reqs received */
-static int default_route_set[NUM_PPP]; /* Have set up a default route */
-
-static fsm_callbacks ipcp_callbacks = { /* IPCP callback routines */
-    ipcp_resetci,              /* Reset our Configuration Information */
-    ipcp_cilen,                        /* Length of our Configuration Information */
-    ipcp_addci,                        /* Add our Configuration Information */
-    ipcp_ackci,                        /* ACK our Configuration Information */
-    ipcp_nakci,                        /* NAK our Configuration Information */
-    ipcp_rejci,                        /* Reject our Configuration Information */
-    ipcp_reqci,                        /* Request peer's Configuration Information */
-    ipcp_up,                   /* Called when fsm reaches OPENED state */
-    ipcp_down,                 /* Called when fsm leaves OPENED state */
-    NULL,                              /* Called when we want the lower layer up */
-    ipcp_finished,             /* Called when we want the lower layer down */
-    NULL,                              /* Called when Protocol-Reject received */
-    NULL,                              /* Retransmission is necessary */
-    NULL,                              /* Called to handle protocol-specific codes */
-    "IPCP"                             /* String name of protocol */
-};
-
-
-
-/**********************************/
-/*** LOCAL FUNCTION DEFINITIONS ***/
-/**********************************/
-
-/*
- * Non-standard inet_ntoa left here for compat with original ppp
- * sources. Assumes u32_t instead of struct in_addr.
- */ 
-
-char * _inet_ntoa(u32_t n)
-{
-       struct in_addr ia;
-       ia.s_addr = n;
-       return inet_ntoa(ia);
-}
-
-#define inet_ntoa _inet_ntoa
-
-/*
- * ipcp_init - Initialize IPCP.
- */
-static void ipcp_init(int unit)
-{
-       fsm *f = &ipcp_fsm[unit];
-       ipcp_options *wo = &ipcp_wantoptions[unit];
-       ipcp_options *ao = &ipcp_allowoptions[unit];
-       
-       f->unit = unit;
-       f->protocol = PPP_IPCP;
-       f->callbacks = &ipcp_callbacks;
-       fsm_init(&ipcp_fsm[unit]);
-       
-       memset(wo, 0, sizeof(*wo));
-       memset(ao, 0, sizeof(*ao));
-       
-       wo->neg_addr = 1;
-       wo->ouraddr = 0;
-#if VJ_SUPPORT > 0
-       wo->neg_vj = 1;
-#else
-       wo->neg_vj = 0;
-#endif
-       wo->vj_protocol = IPCP_VJ_COMP;
-       wo->maxslotindex = MAX_SLOTS - 1;
-       wo->cflag = 0;
-       
-       wo->default_route = 1;
-       
-       ao->neg_addr = 1;
-#if VJ_SUPPORT > 0
-       ao->neg_vj = 1;
-#else
-       ao->neg_vj = 0;
-#endif
-       ao->maxslotindex = MAX_SLOTS - 1;
-       ao->cflag = 1;
-       
-       ao->default_route = 1;
-}
-
-
-/*
- * ipcp_open - IPCP is allowed to come up.
- */
-static void ipcp_open(int unit)
-{
-       fsm_open(&ipcp_fsm[unit]);
-}
-
-
-/*
- * ipcp_close - Take IPCP down.
- */
-static void ipcp_close(int unit, char *reason)
-{
-       fsm_close(&ipcp_fsm[unit], reason);
-}
-
-
-/*
- * ipcp_lowerup - The lower layer is up.
- */
-static void ipcp_lowerup(int unit)
-{
-       fsm_lowerup(&ipcp_fsm[unit]);
-}
-
-
-/*
- * ipcp_lowerdown - The lower layer is down.
- */
-static void ipcp_lowerdown(int unit)
-{
-       fsm_lowerdown(&ipcp_fsm[unit]);
-}
-
-
-/*
- * ipcp_input - Input IPCP packet.
- */
-static void ipcp_input(int unit, u_char *p, int len)
-{
-       fsm_input(&ipcp_fsm[unit], p, len);
-}
-
-
-/*
- * ipcp_protrej - A Protocol-Reject was received for IPCP.
- *
- * Pretend the lower layer went down, so we shut up.
- */
-static void ipcp_protrej(int unit)
-{
-       fsm_lowerdown(&ipcp_fsm[unit]);
-}
-
-
-/*
- * ipcp_resetci - Reset our CI.
- */
-static void ipcp_resetci(fsm *f)
-{
-       ipcp_options *wo = &ipcp_wantoptions[f->unit];
-       
-       wo->req_addr = wo->neg_addr && ipcp_allowoptions[f->unit].neg_addr;
-       if (wo->ouraddr == 0)
-               wo->accept_local = 1;
-       if (wo->hisaddr == 0)
-               wo->accept_remote = 1;
-       /* Request DNS addresses from the peer */
-       wo->req_dns1 = ppp_settings.usepeerdns;
-       wo->req_dns2 = ppp_settings.usepeerdns;
-       ipcp_gotoptions[f->unit] = *wo;
-       cis_received[f->unit] = 0;
-}
-
-
-/*
- * ipcp_cilen - Return length of our CI.
- */
-static int ipcp_cilen(fsm *f)
-{
-       ipcp_options *go = &ipcp_gotoptions[f->unit];
-       ipcp_options *wo = &ipcp_wantoptions[f->unit];
-       ipcp_options *ho = &ipcp_hisoptions[f->unit];
-       
-#define LENCIVJ(neg, old)      (neg ? (old? CILEN_COMPRESS : CILEN_VJ) : 0)
-#define LENCIADDR(neg, old)    (neg ? (old? CILEN_ADDRS : CILEN_ADDR) : 0)
-#define LENCIDNS(neg)          (neg ? (CILEN_ADDR) : 0)
-       
-       /*
-        * First see if we want to change our options to the old
-        * forms because we have received old forms from the peer.
-        */
-       if (wo->neg_addr && !go->neg_addr && !go->old_addrs) {
-               /* use the old style of address negotiation */
-               go->neg_addr = 1;
-               go->old_addrs = 1;
-       }
-       if (wo->neg_vj && !go->neg_vj && !go->old_vj) {
-               /* try an older style of VJ negotiation */
-               if (cis_received[f->unit] == 0) {
-                       /* keep trying the new style until we see some CI from the peer */
-                       go->neg_vj = 1;
-               } else {
-                       /* use the old style only if the peer did */
-                       if (ho->neg_vj && ho->old_vj) {
-                               go->neg_vj = 1;
-                               go->old_vj = 1;
-                               go->vj_protocol = ho->vj_protocol;
-                       }
-               }
-       }
-       
-       return (LENCIADDR(go->neg_addr, go->old_addrs)
-                       + LENCIVJ(go->neg_vj, go->old_vj) +
-                       LENCIDNS(go->req_dns1) +
-                       LENCIDNS(go->req_dns2));
-}
-
-
-/*
- * ipcp_addci - Add our desired CIs to a packet.
- */
-static void ipcp_addci(fsm *f, u_char *ucp, int *lenp)
-{
-       ipcp_options *go = &ipcp_gotoptions[f->unit];
-       int len = *lenp;
-       
-#define ADDCIVJ(opt, neg, val, old, maxslotindex, cflag) \
-       if (neg) { \
-               int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \
-               if (len >= vjlen) { \
-                       PUTCHAR(opt, ucp); \
-                       PUTCHAR(vjlen, ucp); \
-                       PUTSHORT(val, ucp); \
-                       if (!old) { \
-                               PUTCHAR(maxslotindex, ucp); \
-                               PUTCHAR(cflag, ucp); \
-                       } \
-                       len -= vjlen; \
-               } else \
-                       neg = 0; \
-       }
-       
-#define ADDCIADDR(opt, neg, old, val1, val2) \
-       if (neg) { \
-               int addrlen = (old? CILEN_ADDRS: CILEN_ADDR); \
-               if (len >= addrlen) { \
-                       u32_t l; \
-                       PUTCHAR(opt, ucp); \
-                       PUTCHAR(addrlen, ucp); \
-                       l = ntohl(val1); \
-                       PUTLONG(l, ucp); \
-                       if (old) { \
-                               l = ntohl(val2); \
-                               PUTLONG(l, ucp); \
-                       } \
-                       len -= addrlen; \
-               } else \
-                       neg = 0; \
-       }
-
-#define ADDCIDNS(opt, neg, addr) \
-       if (neg) { \
-               if (len >= CILEN_ADDR) { \
-                       u32_t l; \
-                       PUTCHAR(opt, ucp); \
-                       PUTCHAR(CILEN_ADDR, ucp); \
-                       l = ntohl(addr); \
-                       PUTLONG(l, ucp); \
-                       len -= CILEN_ADDR; \
-               } else \
-                       neg = 0; \
-       }
-       
-       ADDCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), go->neg_addr,
-                         go->old_addrs, go->ouraddr, go->hisaddr);
-       
-       ADDCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj,
-                       go->maxslotindex, go->cflag);
-       
-       ADDCIDNS(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]);
-
-       ADDCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]);
-
-       *lenp -= len;
-}
-
-
-/*
- * ipcp_ackci - Ack our CIs.
- *
- * Returns:
- *     0 - Ack was bad.
- *     1 - Ack was good.
- */
-static int ipcp_ackci(fsm *f, u_char *p, int len)
-{
-       ipcp_options *go = &ipcp_gotoptions[f->unit];
-       u_short cilen, citype, cishort;
-       u32_t cilong;
-       u_char cimaxslotindex, cicflag;
-       
-       /*
-        * CIs must be in exactly the same order that we sent...
-        * Check packet length and CI length at each step.
-        * If we find any deviations, then this packet is bad.
-        */
-       
-#define ACKCIVJ(opt, neg, val, old, maxslotindex, cflag) \
-       if (neg) { \
-               int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \
-               if ((len -= vjlen) < 0) \
-                       goto bad; \
-               GETCHAR(citype, p); \
-               GETCHAR(cilen, p); \
-               if (cilen != vjlen || \
-                               citype != opt)  \
-                       goto bad; \
-               GETSHORT(cishort, p); \
-               if (cishort != val) \
-                       goto bad; \
-               if (!old) { \
-                       GETCHAR(cimaxslotindex, p); \
-                       if (cimaxslotindex != maxslotindex) \
-                               goto bad; \
-                       GETCHAR(cicflag, p); \
-                       if (cicflag != cflag) \
-                               goto bad; \
-               } \
-       }
-       
-#define ACKCIADDR(opt, neg, old, val1, val2) \
-       if (neg) { \
-               int addrlen = (old? CILEN_ADDRS: CILEN_ADDR); \
-               u32_t l; \
-               if ((len -= addrlen) < 0) \
-                       goto bad; \
-               GETCHAR(citype, p); \
-               GETCHAR(cilen, p); \
-               if (cilen != addrlen || \
-                               citype != opt) \
-                       goto bad; \
-               GETLONG(l, p); \
-               cilong = htonl(l); \
-               if (val1 != cilong) \
-                       goto bad; \
-               if (old) { \
-                       GETLONG(l, p); \
-                       cilong = htonl(l); \
-                       if (val2 != cilong) \
-                               goto bad; \
-               } \
-       }
-
-#define ACKCIDNS(opt, neg, addr) \
-       if (neg) { \
-               u32_t l; \
-               if ((len -= CILEN_ADDR) < 0) \
-                       goto bad; \
-               GETCHAR(citype, p); \
-               GETCHAR(cilen, p); \
-               if (cilen != CILEN_ADDR || \
-                               citype != opt) \
-                       goto bad; \
-               GETLONG(l, p); \
-               cilong = htonl(l); \
-               if (addr != cilong) \
-                       goto bad; \
-       }
-       
-       ACKCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), go->neg_addr,
-                         go->old_addrs, go->ouraddr, go->hisaddr);
-       
-       ACKCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj,
-                       go->maxslotindex, go->cflag);
-       
-       ACKCIDNS(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]);
-
-       ACKCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]);
-
-       /*
-        * If there are any remaining CIs, then this packet is bad.
-        */
-       if (len != 0)
-               goto bad;
-       return (1);
-       
-bad:
-       IPCPDEBUG((LOG_INFO, "ipcp_ackci: received bad Ack!\n"));
-       return (0);
-}
-
-/*
- * ipcp_nakci - Peer has sent a NAK for some of our CIs.
- * This should not modify any state if the Nak is bad
- * or if IPCP is in the OPENED state.
- *
- * Returns:
- *     0 - Nak was bad.
- *     1 - Nak was good.
- */
-static int ipcp_nakci(fsm *f, u_char *p, int len)
-{
-       ipcp_options *go = &ipcp_gotoptions[f->unit];
-       u_char cimaxslotindex, cicflag;
-       u_char citype, cilen, *next;
-       u_short cishort;
-       u32_t ciaddr1, ciaddr2, l, cidnsaddr;
-       ipcp_options no;                /* options we've seen Naks for */
-       ipcp_options try;               /* options to request next time */
-       
-       BZERO(&no, sizeof(no));
-       try = *go;
-       
-       /*
-        * Any Nak'd CIs must be in exactly the same order that we sent.
-        * Check packet length and CI length at each step.
-        * If we find any deviations, then this packet is bad.
-        */
-#define NAKCIADDR(opt, neg, old, code) \
-       if (go->neg && \
-                       len >= (cilen = (old? CILEN_ADDRS: CILEN_ADDR)) && \
-                       p[1] == cilen && \
-                       p[0] == opt) { \
-               len -= cilen; \
-               INCPTR(2, p); \
-               GETLONG(l, p); \
-               ciaddr1 = htonl(l); \
-               if (old) { \
-                       GETLONG(l, p); \
-                       ciaddr2 = htonl(l); \
-                       no.old_addrs = 1; \
-               } else \
-                       ciaddr2 = 0; \
-               no.neg = 1; \
-               code \
-       }
-       
-#define NAKCIVJ(opt, neg, code) \
-       if (go->neg && \
-                       ((cilen = p[1]) == CILEN_COMPRESS || cilen == CILEN_VJ) && \
-                       len >= cilen && \
-                       p[0] == opt) { \
-               len -= cilen; \
-               INCPTR(2, p); \
-               GETSHORT(cishort, p); \
-               no.neg = 1; \
-               code \
-       }
-       
-#define NAKCIDNS(opt, neg, code) \
-       if (go->neg && \
-                       ((cilen = p[1]) == CILEN_ADDR) && \
-                       len >= cilen && \
-                       p[0] == opt) { \
-               len -= cilen; \
-               INCPTR(2, p); \
-               GETLONG(l, p); \
-               cidnsaddr = htonl(l); \
-               no.neg = 1; \
-               code \
-       }
-       
-       /*
-        * Accept the peer's idea of {our,his} address, if different
-        * from our idea, only if the accept_{local,remote} flag is set.
-        */
-       NAKCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), neg_addr, go->old_addrs,
-         if (go->accept_local && ciaddr1) { /* Do we know our address? */
-                 try.ouraddr = ciaddr1;
-                 IPCPDEBUG((LOG_INFO, "local IP address %s\n",
-                            inet_ntoa(ciaddr1)));
-         }
-         if (go->accept_remote && ciaddr2) { /* Does he know his? */
-                 try.hisaddr = ciaddr2;
-                 IPCPDEBUG((LOG_INFO, "remote IP address %s\n",
-                            inet_ntoa(ciaddr2)));
-         }
-       );
-       
-       /*
-        * Accept the peer's value of maxslotindex provided that it
-        * is less than what we asked for.  Turn off slot-ID compression
-        * if the peer wants.  Send old-style compress-type option if
-        * the peer wants.
-        */
-       NAKCIVJ(CI_COMPRESSTYPE, neg_vj,
-               if (cilen == CILEN_VJ) {
-                       GETCHAR(cimaxslotindex, p);
-                       GETCHAR(cicflag, p);
-                       if (cishort == IPCP_VJ_COMP) {
-                               try.old_vj = 0;
-                               if (cimaxslotindex < go->maxslotindex)
-                                       try.maxslotindex = cimaxslotindex;
-                               if (!cicflag)
-                                       try.cflag = 0;
-                       } else {
-                               try.neg_vj = 0;
-                       }
-               } else {
-                       if (cishort == IPCP_VJ_COMP || cishort == IPCP_VJ_COMP_OLD) {
-                               try.old_vj = 1;
-                               try.vj_protocol = cishort;
-                       } else {
-                               try.neg_vj = 0;
-                       }
-               }
-       );
-       
-       NAKCIDNS(CI_MS_DNS1, req_dns1,
-                       try.dnsaddr[0] = cidnsaddr;
-                       IPCPDEBUG((LOG_INFO, "primary DNS address %s\n", inet_ntoa(cidnsaddr)));
-                       );
-
-       NAKCIDNS(CI_MS_DNS2, req_dns2,
-                       try.dnsaddr[1] = cidnsaddr;
-                       IPCPDEBUG((LOG_INFO, "secondary DNS address %s\n", inet_ntoa(cidnsaddr)));
-                       );
-
-       /*
-       * There may be remaining CIs, if the peer is requesting negotiation
-       * on an option that we didn't include in our request packet.
-       * If they want to negotiate about IP addresses, we comply.
-       * If they want us to ask for compression, we refuse.
-       */
-       while (len > CILEN_VOID) {
-               GETCHAR(citype, p);
-               GETCHAR(cilen, p);
-               if( (len -= cilen) < 0 )
-                       goto bad;
-               next = p + cilen - 2;
-               
-               switch (citype) {
-               case CI_COMPRESSTYPE:
-                       if (go->neg_vj || no.neg_vj ||
-                                       (cilen != CILEN_VJ && cilen != CILEN_COMPRESS))
-                               goto bad;
-                       no.neg_vj = 1;
-                       break;
-               case CI_ADDRS:
-                       if ((go->neg_addr && go->old_addrs) || no.old_addrs
-                                       || cilen != CILEN_ADDRS)
-                               goto bad;
-                       try.neg_addr = 1;
-                       try.old_addrs = 1;
-                       GETLONG(l, p);
-                       ciaddr1 = htonl(l);
-                       if (ciaddr1 && go->accept_local)
-                               try.ouraddr = ciaddr1;
-                       GETLONG(l, p);
-                       ciaddr2 = htonl(l);
-                       if (ciaddr2 && go->accept_remote)
-                               try.hisaddr = ciaddr2;
-                       no.old_addrs = 1;
-                       break;
-               case CI_ADDR:
-                       if (go->neg_addr || no.neg_addr || cilen != CILEN_ADDR)
-                               goto bad;
-                       try.old_addrs = 0;
-                       GETLONG(l, p);
-                       ciaddr1 = htonl(l);
-                       if (ciaddr1 && go->accept_local)
-                               try.ouraddr = ciaddr1;
-                       if (try.ouraddr != 0)
-                               try.neg_addr = 1;
-                       no.neg_addr = 1;
-                       break;
-               }
-               p = next;
-       }
-       
-       /* If there is still anything left, this packet is bad. */
-       if (len != 0)
-               goto bad;
-       
-       /*
-        * OK, the Nak is good.  Now we can update state.
-        */
-       if (f->state != OPENED)
-               *go = try;
-       
-       return 1;
-       
-bad:
-       IPCPDEBUG((LOG_INFO, "ipcp_nakci: received bad Nak!\n"));
-       return 0;
-}
-
-
-/*
- * ipcp_rejci - Reject some of our CIs.
- */
-static int ipcp_rejci(fsm *f, u_char *p, int len)
-{
-       ipcp_options *go = &ipcp_gotoptions[f->unit];
-       u_char cimaxslotindex, ciflag, cilen;
-       u_short cishort;
-       u32_t cilong;
-       ipcp_options try;               /* options to request next time */
-       
-       try = *go;
-       /*
-        * Any Rejected CIs must be in exactly the same order that we sent.
-        * Check packet length and CI length at each step.
-        * If we find any deviations, then this packet is bad.
-        */
-#define REJCIADDR(opt, neg, old, val1, val2) \
-       if (go->neg && \
-                       len >= (cilen = old? CILEN_ADDRS: CILEN_ADDR) && \
-                       p[1] == cilen && \
-                       p[0] == opt) { \
-               u32_t l; \
-               len -= cilen; \
-               INCPTR(2, p); \
-               GETLONG(l, p); \
-               cilong = htonl(l); \
-               /* Check rejected value. */ \
-               if (cilong != val1) \
-                       goto bad; \
-               if (old) { \
-                       GETLONG(l, p); \
-                       cilong = htonl(l); \
-                       /* Check rejected value. */ \
-                       if (cilong != val2) \
-                               goto bad; \
-               } \
-               try.neg = 0; \
-       }
-       
-#define REJCIVJ(opt, neg, val, old, maxslot, cflag) \
-       if (go->neg && \
-                       p[1] == (old? CILEN_COMPRESS : CILEN_VJ) && \
-                       len >= p[1] && \
-                       p[0] == opt) { \
-               len -= p[1]; \
-               INCPTR(2, p); \
-               GETSHORT(cishort, p); \
-               /* Check rejected value. */  \
-               if (cishort != val) \
-                       goto bad; \
-               if (!old) { \
-                       GETCHAR(cimaxslotindex, p); \
-                       if (cimaxslotindex != maxslot) \
-                               goto bad; \
-                       GETCHAR(ciflag, p); \
-                       if (ciflag != cflag) \
-                               goto bad; \
-               } \
-               try.neg = 0; \
-       }
-       
-#define REJCIDNS(opt, neg, dnsaddr) \
-       if (go->neg && \
-                       ((cilen = p[1]) == CILEN_ADDR) && \
-                       len >= cilen && \
-                       p[0] == opt) { \
-               u32_t l; \
-               len -= cilen; \
-               INCPTR(2, p); \
-               GETLONG(l, p); \
-               cilong = htonl(l); \
-               /* Check rejected value. */ \
-               if (cilong != dnsaddr) \
-                       goto bad; \
-               try.neg = 0; \
-       }
-
-       REJCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), neg_addr,
-                         go->old_addrs, go->ouraddr, go->hisaddr);
-       
-       REJCIVJ(CI_COMPRESSTYPE, neg_vj, go->vj_protocol, go->old_vj,
-                       go->maxslotindex, go->cflag);
-       
-       REJCIDNS(CI_MS_DNS1, req_dns1, go->dnsaddr[0]);
-
-       REJCIDNS(CI_MS_DNS2, req_dns2, go->dnsaddr[1]);
-
-       /*
-        * If there are any remaining CIs, then this packet is bad.
-        */
-       if (len != 0)
-               goto bad;
-       /*
-        * Now we can update state.
-        */
-       if (f->state != OPENED)
-               *go = try;
-       return 1;
-       
-bad:
-       IPCPDEBUG((LOG_INFO, "ipcp_rejci: received bad Reject!\n"));
-       return 0;
-}
-
-
-/*
- * ipcp_reqci - Check the peer's requested CIs and send appropriate response.
- *
- * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified
- * appropriately.  If reject_if_disagree is non-zero, doesn't return
- * CONFNAK; returns CONFREJ if it can't return CONFACK.
- */
-static int ipcp_reqci(
-       fsm *f,
-       u_char *inp,            /* Requested CIs */
-       int *len,                       /* Length of requested CIs */
-       int reject_if_disagree
-)
-{
-       ipcp_options *wo = &ipcp_wantoptions[f->unit];
-       ipcp_options *ho = &ipcp_hisoptions[f->unit];
-       ipcp_options *ao = &ipcp_allowoptions[f->unit];
-#ifdef OLD_CI_ADDRS
-       ipcp_options *go = &ipcp_gotoptions[f->unit];
-#endif
-       u_char *cip, *next;                             /* Pointer to current and next CIs */
-       u_short cilen, citype;                  /* Parsed len, type */
-       u_short cishort;                                /* Parsed short value */
-       u32_t tl, ciaddr1;                      /* Parsed address values */
-#ifdef OLD_CI_ADDRS
-       u32_t ciaddr2;                          /* Parsed address values */
-#endif
-       int rc = CONFACK;                               /* Final packet return code */
-       int orc;                                                /* Individual option return code */
-       u_char *p;                                              /* Pointer to next char to parse */
-       u_char *ucp = inp;                              /* Pointer to current output char */
-       int l = *len;                                   /* Length left */
-       u_char maxslotindex, cflag;
-       int d;
-       
-       cis_received[f->unit] = 1;
-       
-       /*
-        * Reset all his options.
-        */
-       BZERO(ho, sizeof(*ho));
-       
-       /*
-        * Process all his options.
-        */
-       next = inp;
-       while (l) {
-               orc = CONFACK;                          /* Assume success */
-               cip = p = next;                         /* Remember begining of CI */
-               if (l < 2 ||                            /* Not enough data for CI header or */
-                               p[1] < 2 ||                     /*  CI length too small or */
-                               p[1] > l) {                     /*  CI length too big? */
-                       IPCPDEBUG((LOG_INFO, "ipcp_reqci: bad CI length!\n"));
-                       orc = CONFREJ;                  /* Reject bad CI */
-                       cilen = l;                              /* Reject till end of packet */
-                       l = 0;                                  /* Don't loop again */
-                       goto endswitch;
-               }
-               GETCHAR(citype, p);                     /* Parse CI type */
-               GETCHAR(cilen, p);                      /* Parse CI length */
-               l -= cilen;                                     /* Adjust remaining length */
-               next += cilen;                          /* Step to next CI */
-
-               switch (citype) {                       /* Check CI type */
-#ifdef OLD_CI_ADDRS /* Need to save space... */
-               case CI_ADDRS:
-                       IPCPDEBUG((LOG_INFO, "ipcp_reqci: received ADDRS\n"));
-                       if (!ao->neg_addr ||
-                                       cilen != CILEN_ADDRS) { /* Check CI length */
-                               orc = CONFREJ;          /* Reject CI */
-                               break;
-                       }
-                       
-                       /*
-                        * If he has no address, or if we both have his address but
-                        * disagree about it, then NAK it with our idea.
-                        * In particular, if we don't know his address, but he does,
-                        * then accept it.
-                        */
-                       GETLONG(tl, p);         /* Parse source address (his) */
-                       ciaddr1 = htonl(tl);
-                       IPCPDEBUG((LOG_INFO, "his addr %s\n", inet_ntoa(ciaddr1)));
-                       if (ciaddr1 != wo->hisaddr
-                                       && (ciaddr1 == 0 || !wo->accept_remote)) {
-                               orc = CONFNAK;
-                               if (!reject_if_disagree) {
-                                       DECPTR(sizeof(u32_t), p);
-                                       tl = ntohl(wo->hisaddr);
-                                       PUTLONG(tl, p);
-                               }
-                       } else if (ciaddr1 == 0 && wo->hisaddr == 0) {
-                               /*
-                                * If neither we nor he knows his address, reject the option.
-                                */
-                               orc = CONFREJ;
-                               wo->req_addr = 0;       /* don't NAK with 0.0.0.0 later */
-                               break;
-                       }
-                       
-                       /*
-                        * If he doesn't know our address, or if we both have our address
-                        * but disagree about it, then NAK it with our idea.
-                        */
-                       GETLONG(tl, p);         /* Parse desination address (ours) */
-                       ciaddr2 = htonl(tl);
-                       IPCPDEBUG((LOG_INFO, "our addr %s\n", inet_ntoa(ciaddr2)));
-                       if (ciaddr2 != wo->ouraddr) {
-                               if (ciaddr2 == 0 || !wo->accept_local) {
-                                       orc = CONFNAK;
-                                       if (!reject_if_disagree) {
-                                               DECPTR(sizeof(u32_t), p);
-                                               tl = ntohl(wo->ouraddr);
-                                               PUTLONG(tl, p);
-                                       }
-                               } else {
-                                       go->ouraddr = ciaddr2;  /* accept peer's idea */
-                               }
-                       }
-                       
-                       ho->neg_addr = 1;
-                       ho->old_addrs = 1;
-                       ho->hisaddr = ciaddr1;
-                       ho->ouraddr = ciaddr2;
-                       break;
-#endif
-               
-               case CI_ADDR:
-                       if (!ao->neg_addr) {
-                               IPCPDEBUG((LOG_INFO, "ipcp_reqci: Reject ADDR not allowed\n"));
-                               orc = CONFREJ;                          /* Reject CI */
-                               break;
-                       } else if (cilen != CILEN_ADDR) {       /* Check CI length */
-                               IPCPDEBUG((LOG_INFO, "ipcp_reqci: Reject ADDR bad len\n"));
-                               orc = CONFREJ;                          /* Reject CI */
-                               break;
-                       }
-                       
-                       /*
-                        * If he has no address, or if we both have his address but
-                        * disagree about it, then NAK it with our idea.
-                        * In particular, if we don't know his address, but he does,
-                        * then accept it.
-                        */
-                       GETLONG(tl, p); /* Parse source address (his) */
-                       ciaddr1 = htonl(tl);
-                       if (ciaddr1 != wo->hisaddr
-                                       && (ciaddr1 == 0 || !wo->accept_remote)) {
-                               orc = CONFNAK;
-                               if (!reject_if_disagree) {
-                                       DECPTR(sizeof(u32_t), p);
-                                       tl = ntohl(wo->hisaddr);
-                                       PUTLONG(tl, p);
-                               }
-                               IPCPDEBUG((LOG_INFO, "ipcp_reqci: Nak ADDR %s\n", inet_ntoa(ciaddr1)));
-                       } else if (ciaddr1 == 0 && wo->hisaddr == 0) {
-                               /*
-                                * Don't ACK an address of 0.0.0.0 - reject it instead.
-                                */
-                               IPCPDEBUG((LOG_INFO, "ipcp_reqci: Reject ADDR %s\n", inet_ntoa(ciaddr1)));
-                               orc = CONFREJ;
-                               wo->req_addr = 0;       /* don't NAK with 0.0.0.0 later */
-                               break;
-                       }
-                       
-                       ho->neg_addr = 1;
-                       ho->hisaddr = ciaddr1;
-                       IPCPDEBUG((LOG_INFO, "ipcp_reqci: ADDR %s\n", inet_ntoa(ciaddr1)));
-                       break;
-               
-               case CI_MS_DNS1:
-               case CI_MS_DNS2:
-                       /* Microsoft primary or secondary DNS request */
-                       d = citype == CI_MS_DNS2;
-                       
-                       /* If we do not have a DNS address then we cannot send it */
-                       if (ao->dnsaddr[d] == 0 ||
-                                       cilen != CILEN_ADDR) {  /* Check CI length */
-                               IPCPDEBUG((LOG_INFO, "ipcp_reqci: Rejecting DNS%d Request\n", d+1));
-                               orc = CONFREJ;                          /* Reject CI */
-                               break;
-                       }
-                       GETLONG(tl, p);
-                       if (htonl(tl) != ao->dnsaddr[d]) {
-                               IPCPDEBUG((LOG_INFO, "ipcp_reqci: Naking DNS%d Request %d\n",
-                                                       d+1, inet_ntoa(tl)));
-                               DECPTR(sizeof(u32_t), p);
-                               tl = ntohl(ao->dnsaddr[d]);
-                               PUTLONG(tl, p);
-                               orc = CONFNAK;
-                       }
-                       IPCPDEBUG((LOG_INFO, "ipcp_reqci: received DNS%d Request\n", d+1));
-                       break;
-               
-               case CI_MS_WINS1:
-               case CI_MS_WINS2:
-                       /* Microsoft primary or secondary WINS request */
-                       d = citype == CI_MS_WINS2;
-                       IPCPDEBUG((LOG_INFO, "ipcp_reqci: received WINS%d Request\n", d+1));
-                       
-                       /* If we do not have a DNS address then we cannot send it */
-                       if (ao->winsaddr[d] == 0 ||
-                               cilen != CILEN_ADDR) {  /* Check CI length */
-                               orc = CONFREJ;                  /* Reject CI */
-                               break;
-                       }
-                       GETLONG(tl, p);
-                       if (htonl(tl) != ao->winsaddr[d]) {
-                               DECPTR(sizeof(u32_t), p);
-                               tl = ntohl(ao->winsaddr[d]);
-                               PUTLONG(tl, p);
-                               orc = CONFNAK;
-                       }
-                       break;
-               
-               case CI_COMPRESSTYPE:
-                       if (!ao->neg_vj) {
-                               IPCPDEBUG((LOG_INFO, "ipcp_reqci: Rejecting COMPRESSTYPE not allowed\n"));
-                               orc = CONFREJ;
-                               break;
-                       } else if (cilen != CILEN_VJ && cilen != CILEN_COMPRESS) {
-                               IPCPDEBUG((LOG_INFO, "ipcp_reqci: Rejecting COMPRESSTYPE len=%d\n", cilen));
-                               orc = CONFREJ;
-                               break;
-                       }
-                       GETSHORT(cishort, p);
-                       
-                       if (!(cishort == IPCP_VJ_COMP ||
-                                       (cishort == IPCP_VJ_COMP_OLD && cilen == CILEN_COMPRESS))) {
-                               IPCPDEBUG((LOG_INFO, "ipcp_reqci: Rejecting COMPRESSTYPE %d\n", cishort));
-                               orc = CONFREJ;
-                               break;
-                       }
-                       
-                       ho->neg_vj = 1;
-                       ho->vj_protocol = cishort;
-                       if (cilen == CILEN_VJ) {
-                               GETCHAR(maxslotindex, p);
-                               if (maxslotindex > ao->maxslotindex) { 
-                                       IPCPDEBUG((LOG_INFO, "ipcp_reqci: Naking VJ max slot %d\n", maxslotindex));
-                                       orc = CONFNAK;
-                                       if (!reject_if_disagree){
-                                               DECPTR(1, p);
-                                               PUTCHAR(ao->maxslotindex, p);
-                                       }
-                               }
-                               GETCHAR(cflag, p);
-                               if (cflag && !ao->cflag) {
-                                       IPCPDEBUG((LOG_INFO, "ipcp_reqci: Naking VJ cflag %d\n", cflag));
-                                       orc = CONFNAK;
-                                       if (!reject_if_disagree){
-                                               DECPTR(1, p);
-                                               PUTCHAR(wo->cflag, p);
-                                       }
-                               }
-                               ho->maxslotindex = maxslotindex;
-                               ho->cflag = cflag;
-                       } else {
-                               ho->old_vj = 1;
-                               ho->maxslotindex = MAX_SLOTS - 1;
-                               ho->cflag = 1;
-                       }
-                       IPCPDEBUG((LOG_INFO, 
-                                               "ipcp_reqci: received COMPRESSTYPE p=%d old=%d maxslot=%d cflag=%d\n",
-                                               ho->vj_protocol, ho->old_vj, ho->maxslotindex, ho->cflag));
-                       break;
-                       
-               default:
-                       IPCPDEBUG((LOG_INFO, "ipcp_reqci: Rejecting unknown CI type %d\n", citype));
-                       orc = CONFREJ;
-                       break;
-               }
-               
-endswitch:
-               if (orc == CONFACK &&           /* Good CI */
-                               rc != CONFACK)          /*  but prior CI wasnt? */
-                       continue;                               /* Don't send this one */
-               
-               if (orc == CONFNAK) {           /* Nak this CI? */
-                       if (reject_if_disagree) {       /* Getting fed up with sending NAKs? */
-                               IPCPDEBUG((LOG_INFO, "ipcp_reqci: Rejecting too many naks\n"));
-                               orc = CONFREJ;          /* Get tough if so */
-                       } else {
-                               if (rc == CONFREJ)      /* Rejecting prior CI? */
-                                       continue;               /* Don't send this one */
-                               if (rc == CONFACK) {    /* Ack'd all prior CIs? */
-                                       rc = CONFNAK;   /* Not anymore... */
-                                       ucp = inp;              /* Backup */
-                               }
-                       }
-               }
-               
-               if (orc == CONFREJ &&           /* Reject this CI */
-                               rc != CONFREJ) {        /*  but no prior ones? */
-                       rc = CONFREJ;
-                       ucp = inp;                              /* Backup */
-               }
-               
-               /* Need to move CI? */
-               if (ucp != cip)
-                       BCOPY(cip, ucp, cilen); /* Move it */
-               
-               /* Update output pointer */
-               INCPTR(cilen, ucp);
-       }
-       
-       /*
-        * If we aren't rejecting this packet, and we want to negotiate
-        * their address, and they didn't send their address, then we
-        * send a NAK with a CI_ADDR option appended.  We assume the
-        * input buffer is long enough that we can append the extra
-        * option safely.
-        */
-       if (rc != CONFREJ && !ho->neg_addr &&
-                       wo->req_addr && !reject_if_disagree) {
-               IPCPDEBUG((LOG_INFO, "ipcp_reqci: Requesting peer address\n"));
-               if (rc == CONFACK) {
-                       rc = CONFNAK;
-                       ucp = inp;                              /* reset pointer */
-                       wo->req_addr = 0;               /* don't ask again */
-               }
-               PUTCHAR(CI_ADDR, ucp);
-               PUTCHAR(CILEN_ADDR, ucp);
-               tl = ntohl(wo->hisaddr);
-               PUTLONG(tl, ucp);
-       }
-       
-       *len = (int)(ucp - inp);                /* Compute output length */
-       IPCPDEBUG((LOG_INFO, "ipcp_reqci: returning Configure-%s\n", CODENAME(rc)));
-       return (rc);                    /* Return final code */
-}
-
-
-#if 0
-/*
- * ip_check_options - check that any IP-related options are OK,
- * and assign appropriate defaults.
- */
-static void ip_check_options(u_long localAddr)
-{
-       ipcp_options *wo = &ipcp_wantoptions[0];
-
-       /*
-        * Load our default IP address but allow the remote host to give us
-        * a new address.
-        */
-       if (wo->ouraddr == 0 && !ppp_settings.disable_defaultip) {
-               wo->accept_local = 1;   /* don't insist on this default value */
-               wo->ouraddr = htonl(localAddr);
-       }
-}
-#endif
-
-
-/*
- * ipcp_up - IPCP has come UP.
- *
- * Configure the IP network interface appropriately and bring it up.
- */
-static void ipcp_up(fsm *f)
-{
-       u32_t mask;
-       ipcp_options *ho = &ipcp_hisoptions[f->unit];
-       ipcp_options *go = &ipcp_gotoptions[f->unit];
-       ipcp_options *wo = &ipcp_wantoptions[f->unit];
-       
-       np_up(f->unit, PPP_IP);
-       IPCPDEBUG((LOG_INFO, "ipcp: up\n"));
-       
-       /*
-        * We must have a non-zero IP address for both ends of the link.
-        */
-       if (!ho->neg_addr)
-               ho->hisaddr = wo->hisaddr;
-       
-       if (ho->hisaddr == 0) {
-               IPCPDEBUG((LOG_ERR, "Could not determine remote IP address\n"));
-               ipcp_close(f->unit, "Could not determine remote IP address");
-               return;
-       }
-       if (go->ouraddr == 0) {
-               IPCPDEBUG((LOG_ERR, "Could not determine local IP address\n"));
-               ipcp_close(f->unit, "Could not determine local IP address");
-               return;
-       }
-       
-       if (ppp_settings.usepeerdns && (go->dnsaddr[0] || go->dnsaddr[1])) {
-               /*pppGotDNSAddrs(go->dnsaddr[0], go->dnsaddr[1]);*/
-       }
-
-       /*
-        * Check that the peer is allowed to use the IP address it wants.
-        */
-       if (!auth_ip_addr(f->unit, ho->hisaddr)) {
-               IPCPDEBUG((LOG_ERR, "Peer is not authorized to use remote address %s\n",
-                               inet_ntoa(ho->hisaddr)));
-               ipcp_close(f->unit, "Unauthorized remote IP address");
-               return;
-       }
-       
-       /* set tcp compression */
-       sifvjcomp(f->unit, ho->neg_vj, ho->cflag, ho->maxslotindex);
-       
-       /*
-        * Set IP addresses and (if specified) netmask.
-        */
-       mask = GetMask(go->ouraddr);
-       
-       if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask, go->dnsaddr[0], go->dnsaddr[1])) {
-               IPCPDEBUG((LOG_WARNING, "sifaddr failed\n"));
-               ipcp_close(f->unit, "Interface configuration failed");
-               return;
-       }
-       
-       /* bring the interface up for IP */
-       if (!sifup(f->unit)) {
-               IPCPDEBUG((LOG_WARNING, "sifup failed\n"));
-               ipcp_close(f->unit, "Interface configuration failed");
-               return;
-       }
-       
-       sifnpmode(f->unit, PPP_IP, NPMODE_PASS);
-       
-       /* assign a default route through the interface if required */
-       if (ipcp_wantoptions[f->unit].default_route) 
-               if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr))
-                       default_route_set[f->unit] = 1;
-       
-       IPCPDEBUG((LOG_NOTICE, "local  IP address %s\n", inet_ntoa(go->ouraddr)));
-       IPCPDEBUG((LOG_NOTICE, "remote IP address %s\n", inet_ntoa(ho->hisaddr)));
-       if (go->dnsaddr[0]) {
-               IPCPDEBUG((LOG_NOTICE, "primary   DNS address %s\n", inet_ntoa(go->dnsaddr[0])));
-       }
-       if (go->dnsaddr[1]) {
-               IPCPDEBUG((LOG_NOTICE, "secondary DNS address %s\n", inet_ntoa(go->dnsaddr[1])));
-       }
-}
-
-
-/*
- * ipcp_down - IPCP has gone DOWN.
- *
- * Take the IP network interface down, clear its addresses
- * and delete routes through it.
- */
-static void ipcp_down(fsm *f)
-{
-       IPCPDEBUG((LOG_INFO, "ipcp: down\n"));
-       np_down(f->unit, PPP_IP);
-       sifvjcomp(f->unit, 0, 0, 0);
-       
-       sifdown(f->unit);
-       ipcp_clear_addrs(f->unit);
-}
-
-
-/*
- * ipcp_clear_addrs() - clear the interface addresses, routes, etc.
- */
-static void ipcp_clear_addrs(int unit)
-{
-       u32_t ouraddr, hisaddr;
-       
-       ouraddr = ipcp_gotoptions[unit].ouraddr;
-       hisaddr = ipcp_hisoptions[unit].hisaddr;
-       if (default_route_set[unit]) {
-               cifdefaultroute(unit, ouraddr, hisaddr);
-               default_route_set[unit] = 0;
-       }
-       cifaddr(unit, ouraddr, hisaddr);
-}
-
-
-/*
- * ipcp_finished - possibly shut down the lower layers.
- */
-static void ipcp_finished(fsm *f)
-{
-       np_finished(f->unit, PPP_IP);
-}
-
-#if 0
-static int ipcp_printpkt(
-       u_char *p,
-       int plen,
-       void (*printer) (void *, char *, ...),
-       void *arg
-)
-{
-       (void)p;
-       (void)plen;
-       (void)printer;
-       (void)arg;
-       return 0;
-}
-
-/*
- * ip_active_pkt - see if this IP packet is worth bringing the link up for.
- * We don't bring the link up for IP fragments or for TCP FIN packets
- * with no data.
- */
-#define IP_HDRLEN      20      /* bytes */
-#define IP_OFFMASK     0x1fff
-#define IPPROTO_TCP    6
-#define TCP_HDRLEN     20
-#define TH_FIN         0x01
-
-/*
- * We use these macros because the IP header may be at an odd address,
- * and some compilers might use word loads to get th_off or ip_hl.
- */
-
-#define net_short(x)   (((x)[0] << 8) + (x)[1])
-#define get_iphl(x)    (((unsigned char *)(x))[0] & 0xF)
-#define get_ipoff(x)   net_short((unsigned char *)(x) + 6)
-#define get_ipproto(x) (((unsigned char *)(x))[9])
-#define get_tcpoff(x)  (((unsigned char *)(x))[12] >> 4)
-#define get_tcpflags(x)        (((unsigned char *)(x))[13])
-
-static int ip_active_pkt(u_char *pkt, int len)
-{
-       u_char *tcp;
-       int hlen;
-       
-       len -= PPP_HDRLEN;
-       pkt += PPP_HDRLEN;
-       if (len < IP_HDRLEN)
-               return 0;
-       if ((get_ipoff(pkt) & IP_OFFMASK) != 0)
-               return 0;
-       if (get_ipproto(pkt) != IPPROTO_TCP)
-               return 1;
-       hlen = get_iphl(pkt) * 4;
-       if (len < hlen + TCP_HDRLEN)
-               return 0;
-       tcp = pkt + hlen;
-       if ((get_tcpflags(tcp) & TH_FIN) != 0 && len == hlen + get_tcpoff(tcp) * 4)
-               return 0;
-       return 1;
-}
-#endif
-
-#endif /* PPP_SUPPORT */
+/*****************************************************************************\r
+* ipcp.c - Network PPP IP Control Protocol program file.\r
+*\r
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.\r
+* portions Copyright (c) 1997 by Global Election Systems Inc.\r
+*\r
+* The authors hereby grant permission to use, copy, modify, distribute,\r
+* and license this software and its documentation for any purpose, provided\r
+* that existing copyright notices are retained in all copies and that this\r
+* notice and the following disclaimer are included verbatim in any \r
+* distributions. No written agreement, license, or royalty fee is required\r
+* for any of the authorized uses.\r
+*\r
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR\r
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+*\r
+******************************************************************************\r
+* REVISION HISTORY\r
+*\r
+* 03-01-01 Marc Boucher <marc@mbsi.ca>\r
+*   Ported to lwIP.\r
+* 97-12-08 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.\r
+*      Original.\r
+*****************************************************************************/\r
+/*\r
+ * ipcp.c - PPP IP Control Protocol.\r
+ *\r
+ * Copyright (c) 1989 Carnegie Mellon University.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms are permitted\r
+ * provided that the above copyright notice and this paragraph are\r
+ * duplicated in all such forms and that any documentation,\r
+ * advertising materials, and other materials related to such\r
+ * distribution and use acknowledge that the software was developed\r
+ * by Carnegie Mellon University.  The name of the\r
+ * University may not be used to endorse or promote products derived\r
+ * from this software without specific prior written permission.\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR\r
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r
+ */\r
+\r
+#include <string.h>\r
+\r
+#include "ppp.h"\r
+#if PPP_SUPPORT > 0\r
+#include "auth.h"\r
+#include "fsm.h"\r
+#include "vj.h"\r
+#include "ipcp.h"\r
+#include "pppdebug.h"\r
+\r
+\r
+/*************************/\r
+/*** LOCAL DEFINITIONS ***/\r
+/*************************/\r
+/* #define OLD_CI_ADDRS 1 */   /* Support deprecated address negotiation. */\r
+\r
+/*\r
+ * Lengths of configuration options.\r
+ */\r
+#define CILEN_VOID     2\r
+#define CILEN_COMPRESS 4       /* min length for compression protocol opt. */\r
+#define CILEN_VJ       6       /* length for RFC1332 Van-Jacobson opt. */\r
+#define CILEN_ADDR     6       /* new-style single address option */\r
+#define CILEN_ADDRS    10      /* old-style dual address option */\r
+\r
+\r
+\r
+/***********************************/\r
+/*** LOCAL FUNCTION DECLARATIONS ***/\r
+/***********************************/\r
+/*\r
+ * Callbacks for fsm code.  (CI = Configuration Information)\r
+ */\r
+static void ipcp_resetci (fsm *);      /* Reset our CI */\r
+static int  ipcp_cilen (fsm *);                /* Return length of our CI */\r
+static void ipcp_addci (fsm *, u_char *, int *); /* Add our CI */\r
+static int  ipcp_ackci (fsm *, u_char *, int); /* Peer ack'd our CI */\r
+static int  ipcp_nakci (fsm *, u_char *, int); /* Peer nak'd our CI */\r
+static int  ipcp_rejci (fsm *, u_char *, int); /* Peer rej'd our CI */\r
+static int  ipcp_reqci (fsm *, u_char *, int *, int); /* Rcv CI */\r
+static void ipcp_up (fsm *);           /* We're UP */\r
+static void ipcp_down (fsm *);         /* We're DOWN */\r
+#if 0\r
+static void ipcp_script (fsm *, char *); /* Run an up/down script */\r
+#endif\r
+static void ipcp_finished (fsm *);     /* Don't need lower layer */\r
+\r
+/*\r
+ * Protocol entry points from main code.\r
+ */\r
+static void ipcp_init (int);\r
+static void ipcp_open (int);\r
+static void ipcp_close (int, char *);\r
+static void ipcp_lowerup (int);\r
+static void ipcp_lowerdown (int);\r
+static void ipcp_input (int, u_char *, int);\r
+static void ipcp_protrej (int);\r
+\r
+static void ipcp_clear_addrs (int);\r
+\r
+#define CODENAME(x)    ((x) == CONFACK ? "ACK" : \\r
+                        (x) == CONFNAK ? "NAK" : "REJ")\r
+\r
+\r
+\r
+/******************************/\r
+/*** PUBLIC DATA STRUCTURES ***/\r
+/******************************/\r
+/* global vars */\r
+ipcp_options ipcp_wantoptions[NUM_PPP];        /* Options that we want to request */\r
+ipcp_options ipcp_gotoptions[NUM_PPP]; /* Options that peer ack'd */\r
+ipcp_options ipcp_allowoptions[NUM_PPP];       /* Options we allow peer to request */\r
+ipcp_options ipcp_hisoptions[NUM_PPP]; /* Options that we ack'd */\r
+\r
+fsm ipcp_fsm[NUM_PPP];         /* IPCP fsm structure */\r
+\r
+struct protent ipcp_protent = {\r
+    PPP_IPCP,\r
+    ipcp_init,\r
+    ipcp_input,\r
+    ipcp_protrej,\r
+    ipcp_lowerup,\r
+    ipcp_lowerdown,\r
+    ipcp_open,\r
+    ipcp_close,\r
+#if 0\r
+    ipcp_printpkt,\r
+    NULL,\r
+#endif\r
+    1,\r
+    "IPCP",\r
+#if 0\r
+    ip_check_options,\r
+    NULL,\r
+    ip_active_pkt\r
+#endif\r
+};\r
+\r
+\r
+\r
+/*****************************/\r
+/*** LOCAL DATA STRUCTURES ***/\r
+/*****************************/\r
+/* local vars */\r
+static int cis_received[NUM_PPP];              /* # Conf-Reqs received */\r
+static int default_route_set[NUM_PPP]; /* Have set up a default route */\r
+\r
+static fsm_callbacks ipcp_callbacks = { /* IPCP callback routines */\r
+    ipcp_resetci,              /* Reset our Configuration Information */\r
+    ipcp_cilen,                        /* Length of our Configuration Information */\r
+    ipcp_addci,                        /* Add our Configuration Information */\r
+    ipcp_ackci,                        /* ACK our Configuration Information */\r
+    ipcp_nakci,                        /* NAK our Configuration Information */\r
+    ipcp_rejci,                        /* Reject our Configuration Information */\r
+    ipcp_reqci,                        /* Request peer's Configuration Information */\r
+    ipcp_up,                   /* Called when fsm reaches OPENED state */\r
+    ipcp_down,                 /* Called when fsm leaves OPENED state */\r
+    NULL,                              /* Called when we want the lower layer up */\r
+    ipcp_finished,             /* Called when we want the lower layer down */\r
+    NULL,                              /* Called when Protocol-Reject received */\r
+    NULL,                              /* Retransmission is necessary */\r
+    NULL,                              /* Called to handle protocol-specific codes */\r
+    "IPCP"                             /* String name of protocol */\r
+};\r
+\r
+\r
+\r
+/**********************************/\r
+/*** LOCAL FUNCTION DEFINITIONS ***/\r
+/**********************************/\r
+\r
+/*\r
+ * Non-standard inet_ntoa left here for compat with original ppp\r
+ * sources. Assumes u32_t instead of struct in_addr.\r
+ */ \r
+\r
+char * _inet_ntoa(u32_t n)\r
+{\r
+       struct in_addr ia;\r
+       ia.s_addr = n;\r
+       return inet_ntoa(ia);\r
+}\r
+\r
+#define inet_ntoa _inet_ntoa\r
+\r
+/*\r
+ * ipcp_init - Initialize IPCP.\r
+ */\r
+static void ipcp_init(int unit)\r
+{\r
+       fsm *f = &ipcp_fsm[unit];\r
+       ipcp_options *wo = &ipcp_wantoptions[unit];\r
+       ipcp_options *ao = &ipcp_allowoptions[unit];\r
+       \r
+       f->unit = unit;\r
+       f->protocol = PPP_IPCP;\r
+       f->callbacks = &ipcp_callbacks;\r
+       fsm_init(&ipcp_fsm[unit]);\r
+       \r
+       memset(wo, 0, sizeof(*wo));\r
+       memset(ao, 0, sizeof(*ao));\r
+       \r
+       wo->neg_addr = 1;\r
+       wo->ouraddr = 0;\r
+#if VJ_SUPPORT > 0\r
+       wo->neg_vj = 1;\r
+#else\r
+       wo->neg_vj = 0;\r
+#endif\r
+       wo->vj_protocol = IPCP_VJ_COMP;\r
+       wo->maxslotindex = MAX_SLOTS - 1;\r
+       wo->cflag = 0;\r
+       \r
+       wo->default_route = 1;\r
+       \r
+       ao->neg_addr = 1;\r
+#if VJ_SUPPORT > 0\r
+       ao->neg_vj = 1;\r
+#else\r
+       ao->neg_vj = 0;\r
+#endif\r
+       ao->maxslotindex = MAX_SLOTS - 1;\r
+       ao->cflag = 1;\r
+       \r
+       ao->default_route = 1;\r
+}\r
+\r
+\r
+/*\r
+ * ipcp_open - IPCP is allowed to come up.\r
+ */\r
+static void ipcp_open(int unit)\r
+{\r
+       fsm_open(&ipcp_fsm[unit]);\r
+}\r
+\r
+\r
+/*\r
+ * ipcp_close - Take IPCP down.\r
+ */\r
+static void ipcp_close(int unit, char *reason)\r
+{\r
+       fsm_close(&ipcp_fsm[unit], reason);\r
+}\r
+\r
+\r
+/*\r
+ * ipcp_lowerup - The lower layer is up.\r
+ */\r
+static void ipcp_lowerup(int unit)\r
+{\r
+       fsm_lowerup(&ipcp_fsm[unit]);\r
+}\r
+\r
+\r
+/*\r
+ * ipcp_lowerdown - The lower layer is down.\r
+ */\r
+static void ipcp_lowerdown(int unit)\r
+{\r
+       fsm_lowerdown(&ipcp_fsm[unit]);\r
+}\r
+\r
+\r
+/*\r
+ * ipcp_input - Input IPCP packet.\r
+ */\r
+static void ipcp_input(int unit, u_char *p, int len)\r
+{\r
+       fsm_input(&ipcp_fsm[unit], p, len);\r
+}\r
+\r
+\r
+/*\r
+ * ipcp_protrej - A Protocol-Reject was received for IPCP.\r
+ *\r
+ * Pretend the lower layer went down, so we shut up.\r
+ */\r
+static void ipcp_protrej(int unit)\r
+{\r
+       fsm_lowerdown(&ipcp_fsm[unit]);\r
+}\r
+\r
+\r
+/*\r
+ * ipcp_resetci - Reset our CI.\r
+ */\r
+static void ipcp_resetci(fsm *f)\r
+{\r
+       ipcp_options *wo = &ipcp_wantoptions[f->unit];\r
+       \r
+       wo->req_addr = wo->neg_addr && ipcp_allowoptions[f->unit].neg_addr;\r
+       if (wo->ouraddr == 0)\r
+               wo->accept_local = 1;\r
+       if (wo->hisaddr == 0)\r
+               wo->accept_remote = 1;\r
+       /* Request DNS addresses from the peer */\r
+       wo->req_dns1 = ppp_settings.usepeerdns;\r
+       wo->req_dns2 = ppp_settings.usepeerdns;\r
+       ipcp_gotoptions[f->unit] = *wo;\r
+       cis_received[f->unit] = 0;\r
+}\r
+\r
+\r
+/*\r
+ * ipcp_cilen - Return length of our CI.\r
+ */\r
+static int ipcp_cilen(fsm *f)\r
+{\r
+       ipcp_options *go = &ipcp_gotoptions[f->unit];\r
+       ipcp_options *wo = &ipcp_wantoptions[f->unit];\r
+       ipcp_options *ho = &ipcp_hisoptions[f->unit];\r
+       \r
+#define LENCIVJ(neg, old)      (neg ? (old? CILEN_COMPRESS : CILEN_VJ) : 0)\r
+#define LENCIADDR(neg, old)    (neg ? (old? CILEN_ADDRS : CILEN_ADDR) : 0)\r
+#define LENCIDNS(neg)          (neg ? (CILEN_ADDR) : 0)\r
+       \r
+       /*\r
+        * First see if we want to change our options to the old\r
+        * forms because we have received old forms from the peer.\r
+        */\r
+       if (wo->neg_addr && !go->neg_addr && !go->old_addrs) {\r
+               /* use the old style of address negotiation */\r
+               go->neg_addr = 1;\r
+               go->old_addrs = 1;\r
+       }\r
+       if (wo->neg_vj && !go->neg_vj && !go->old_vj) {\r
+               /* try an older style of VJ negotiation */\r
+               if (cis_received[f->unit] == 0) {\r
+                       /* keep trying the new style until we see some CI from the peer */\r
+                       go->neg_vj = 1;\r
+               } else {\r
+                       /* use the old style only if the peer did */\r
+                       if (ho->neg_vj && ho->old_vj) {\r
+                               go->neg_vj = 1;\r
+                               go->old_vj = 1;\r
+                               go->vj_protocol = ho->vj_protocol;\r
+                       }\r
+               }\r
+       }\r
+       \r
+       return (LENCIADDR(go->neg_addr, go->old_addrs)\r
+                       + LENCIVJ(go->neg_vj, go->old_vj) +\r
+                       LENCIDNS(go->req_dns1) +\r
+                       LENCIDNS(go->req_dns2));\r
+}\r
+\r
+\r
+/*\r
+ * ipcp_addci - Add our desired CIs to a packet.\r
+ */\r
+static void ipcp_addci(fsm *f, u_char *ucp, int *lenp)\r
+{\r
+       ipcp_options *go = &ipcp_gotoptions[f->unit];\r
+       int len = *lenp;\r
+       \r
+#define ADDCIVJ(opt, neg, val, old, maxslotindex, cflag) \\r
+       if (neg) { \\r
+               int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \\r
+               if (len >= vjlen) { \\r
+                       PUTCHAR(opt, ucp); \\r
+                       PUTCHAR(vjlen, ucp); \\r
+                       PUTSHORT(val, ucp); \\r
+                       if (!old) { \\r
+                               PUTCHAR(maxslotindex, ucp); \\r
+                               PUTCHAR(cflag, ucp); \\r
+                       } \\r
+                       len -= vjlen; \\r
+               } else \\r
+                       neg = 0; \\r
+       }\r
+       \r
+#define ADDCIADDR(opt, neg, old, val1, val2) \\r
+       if (neg) { \\r
+               int addrlen = (old? CILEN_ADDRS: CILEN_ADDR); \\r
+               if (len >= addrlen) { \\r
+                       u32_t l; \\r
+                       PUTCHAR(opt, ucp); \\r
+                       PUTCHAR(addrlen, ucp); \\r
+                       l = ntohl(val1); \\r
+                       PUTLONG(l, ucp); \\r
+                       if (old) { \\r
+                               l = ntohl(val2); \\r
+                               PUTLONG(l, ucp); \\r
+                       } \\r
+                       len -= addrlen; \\r
+               } else \\r
+                       neg = 0; \\r
+       }\r
+\r
+#define ADDCIDNS(opt, neg, addr) \\r
+       if (neg) { \\r
+               if (len >= CILEN_ADDR) { \\r
+                       u32_t l; \\r
+                       PUTCHAR(opt, ucp); \\r
+                       PUTCHAR(CILEN_ADDR, ucp); \\r
+                       l = ntohl(addr); \\r
+                       PUTLONG(l, ucp); \\r
+                       len -= CILEN_ADDR; \\r
+               } else \\r
+                       neg = 0; \\r
+       }\r
+       \r
+       ADDCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), go->neg_addr,\r
+                         go->old_addrs, go->ouraddr, go->hisaddr);\r
+       \r
+       ADDCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj,\r
+                       go->maxslotindex, go->cflag);\r
+       \r
+       ADDCIDNS(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]);\r
+\r
+       ADDCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]);\r
+\r
+       *lenp -= len;\r
+}\r
+\r
+\r
+/*\r
+ * ipcp_ackci - Ack our CIs.\r
+ *\r
+ * Returns:\r
+ *     0 - Ack was bad.\r
+ *     1 - Ack was good.\r
+ */\r
+static int ipcp_ackci(fsm *f, u_char *p, int len)\r
+{\r
+       ipcp_options *go = &ipcp_gotoptions[f->unit];\r
+       u_short cilen, citype, cishort;\r
+       u32_t cilong;\r
+       u_char cimaxslotindex, cicflag;\r
+       \r
+       /*\r
+        * CIs must be in exactly the same order that we sent...\r
+        * Check packet length and CI length at each step.\r
+        * If we find any deviations, then this packet is bad.\r
+        */\r
+       \r
+#define ACKCIVJ(opt, neg, val, old, maxslotindex, cflag) \\r
+       if (neg) { \\r
+               int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \\r
+               if ((len -= vjlen) < 0) \\r
+                       goto bad; \\r
+               GETCHAR(citype, p); \\r
+               GETCHAR(cilen, p); \\r
+               if (cilen != vjlen || \\r
+                               citype != opt)  \\r
+                       goto bad; \\r
+               GETSHORT(cishort, p); \\r
+               if (cishort != val) \\r
+                       goto bad; \\r
+               if (!old) { \\r
+                       GETCHAR(cimaxslotindex, p); \\r
+                       if (cimaxslotindex != maxslotindex) \\r
+                               goto bad; \\r
+                       GETCHAR(cicflag, p); \\r
+                       if (cicflag != cflag) \\r
+                               goto bad; \\r
+               } \\r
+       }\r
+       \r
+#define ACKCIADDR(opt, neg, old, val1, val2) \\r
+       if (neg) { \\r
+               int addrlen = (old? CILEN_ADDRS: CILEN_ADDR); \\r
+               u32_t l; \\r
+               if ((len -= addrlen) < 0) \\r
+                       goto bad; \\r
+               GETCHAR(citype, p); \\r
+               GETCHAR(cilen, p); \\r
+               if (cilen != addrlen || \\r
+                               citype != opt) \\r
+                       goto bad; \\r
+               GETLONG(l, p); \\r
+               cilong = htonl(l); \\r
+               if (val1 != cilong) \\r
+                       goto bad; \\r
+               if (old) { \\r
+                       GETLONG(l, p); \\r
+                       cilong = htonl(l); \\r
+                       if (val2 != cilong) \\r
+                               goto bad; \\r
+               } \\r
+       }\r
+\r
+#define ACKCIDNS(opt, neg, addr) \\r
+       if (neg) { \\r
+               u32_t l; \\r
+               if ((len -= CILEN_ADDR) < 0) \\r
+                       goto bad; \\r
+               GETCHAR(citype, p); \\r
+               GETCHAR(cilen, p); \\r
+               if (cilen != CILEN_ADDR || \\r
+                               citype != opt) \\r
+                       goto bad; \\r
+               GETLONG(l, p); \\r
+               cilong = htonl(l); \\r
+               if (addr != cilong) \\r
+                       goto bad; \\r
+       }\r
+       \r
+       ACKCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), go->neg_addr,\r
+                         go->old_addrs, go->ouraddr, go->hisaddr);\r
+       \r
+       ACKCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj,\r
+                       go->maxslotindex, go->cflag);\r
+       \r
+       ACKCIDNS(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]);\r
+\r
+       ACKCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]);\r
+\r
+       /*\r
+        * If there are any remaining CIs, then this packet is bad.\r
+        */\r
+       if (len != 0)\r
+               goto bad;\r
+       return (1);\r
+       \r
+bad:\r
+       IPCPDEBUG((LOG_INFO, "ipcp_ackci: received bad Ack!\n"));\r
+       return (0);\r
+}\r
+\r
+/*\r
+ * ipcp_nakci - Peer has sent a NAK for some of our CIs.\r
+ * This should not modify any state if the Nak is bad\r
+ * or if IPCP is in the OPENED state.\r
+ *\r
+ * Returns:\r
+ *     0 - Nak was bad.\r
+ *     1 - Nak was good.\r
+ */\r
+static int ipcp_nakci(fsm *f, u_char *p, int len)\r
+{\r
+       ipcp_options *go = &ipcp_gotoptions[f->unit];\r
+       u_char cimaxslotindex, cicflag;\r
+       u_char citype, cilen, *next;\r
+       u_short cishort;\r
+       u32_t ciaddr1, ciaddr2, l, cidnsaddr;\r
+       ipcp_options no;                /* options we've seen Naks for */\r
+       ipcp_options try;               /* options to request next time */\r
+       \r
+       BZERO(&no, sizeof(no));\r
+       try = *go;\r
+       \r
+       /*\r
+        * Any Nak'd CIs must be in exactly the same order that we sent.\r
+        * Check packet length and CI length at each step.\r
+        * If we find any deviations, then this packet is bad.\r
+        */\r
+#define NAKCIADDR(opt, neg, old, code) \\r
+       if (go->neg && \\r
+                       len >= (cilen = (old? CILEN_ADDRS: CILEN_ADDR)) && \\r
+                       p[1] == cilen && \\r
+                       p[0] == opt) { \\r
+               len -= cilen; \\r
+               INCPTR(2, p); \\r
+               GETLONG(l, p); \\r
+               ciaddr1 = htonl(l); \\r
+               if (old) { \\r
+                       GETLONG(l, p); \\r
+                       ciaddr2 = htonl(l); \\r
+                       no.old_addrs = 1; \\r
+               } else \\r
+                       ciaddr2 = 0; \\r
+               no.neg = 1; \\r
+               code \\r
+       }\r
+       \r
+#define NAKCIVJ(opt, neg, code) \\r
+       if (go->neg && \\r
+                       ((cilen = p[1]) == CILEN_COMPRESS || cilen == CILEN_VJ) && \\r
+                       len >= cilen && \\r
+                       p[0] == opt) { \\r
+               len -= cilen; \\r
+               INCPTR(2, p); \\r
+               GETSHORT(cishort, p); \\r
+               no.neg = 1; \\r
+               code \\r
+       }\r
+       \r
+#define NAKCIDNS(opt, neg, code) \\r
+       if (go->neg && \\r
+                       ((cilen = p[1]) == CILEN_ADDR) && \\r
+                       len >= cilen && \\r
+                       p[0] == opt) { \\r
+               len -= cilen; \\r
+               INCPTR(2, p); \\r
+               GETLONG(l, p); \\r
+               cidnsaddr = htonl(l); \\r
+               no.neg = 1; \\r
+               code \\r
+       }\r
+       \r
+       /*\r
+        * Accept the peer's idea of {our,his} address, if different\r
+        * from our idea, only if the accept_{local,remote} flag is set.\r
+        */\r
+       NAKCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), neg_addr, go->old_addrs,\r
+         if (go->accept_local && ciaddr1) { /* Do we know our address? */\r
+                 try.ouraddr = ciaddr1;\r
+                 IPCPDEBUG((LOG_INFO, "local IP address %s\n",\r
+                            inet_ntoa(ciaddr1)));\r
+         }\r
+         if (go->accept_remote && ciaddr2) { /* Does he know his? */\r
+                 try.hisaddr = ciaddr2;\r
+                 IPCPDEBUG((LOG_INFO, "remote IP address %s\n",\r
+                            inet_ntoa(ciaddr2)));\r
+         }\r
+       );\r
+       \r
+       /*\r
+        * Accept the peer's value of maxslotindex provided that it\r
+        * is less than what we asked for.  Turn off slot-ID compression\r
+        * if the peer wants.  Send old-style compress-type option if\r
+        * the peer wants.\r
+        */\r
+       NAKCIVJ(CI_COMPRESSTYPE, neg_vj,\r
+               if (cilen == CILEN_VJ) {\r
+                       GETCHAR(cimaxslotindex, p);\r
+                       GETCHAR(cicflag, p);\r
+                       if (cishort == IPCP_VJ_COMP) {\r
+                               try.old_vj = 0;\r
+                               if (cimaxslotindex < go->maxslotindex)\r
+                                       try.maxslotindex = cimaxslotindex;\r
+                               if (!cicflag)\r
+                                       try.cflag = 0;\r
+                       } else {\r
+                               try.neg_vj = 0;\r
+                       }\r
+               } else {\r
+                       if (cishort == IPCP_VJ_COMP || cishort == IPCP_VJ_COMP_OLD) {\r
+                               try.old_vj = 1;\r
+                               try.vj_protocol = cishort;\r
+                       } else {\r
+                               try.neg_vj = 0;\r
+                       }\r
+               }\r
+       );\r
+       \r
+       NAKCIDNS(CI_MS_DNS1, req_dns1,\r
+                       try.dnsaddr[0] = cidnsaddr;\r
+                       IPCPDEBUG((LOG_INFO, "primary DNS address %s\n", inet_ntoa(cidnsaddr)));\r
+                       );\r
+\r
+       NAKCIDNS(CI_MS_DNS2, req_dns2,\r
+                       try.dnsaddr[1] = cidnsaddr;\r
+                       IPCPDEBUG((LOG_INFO, "secondary DNS address %s\n", inet_ntoa(cidnsaddr)));\r
+                       );\r
+\r
+       /*\r
+       * There may be remaining CIs, if the peer is requesting negotiation\r
+       * on an option that we didn't include in our request packet.\r
+       * If they want to negotiate about IP addresses, we comply.\r
+       * If they want us to ask for compression, we refuse.\r
+       */\r
+       while (len > CILEN_VOID) {\r
+               GETCHAR(citype, p);\r
+               GETCHAR(cilen, p);\r
+               if( (len -= cilen) < 0 )\r
+                       goto bad;\r
+               next = p + cilen - 2;\r
+               \r
+               switch (citype) {\r
+               case CI_COMPRESSTYPE:\r
+                       if (go->neg_vj || no.neg_vj ||\r
+                                       (cilen != CILEN_VJ && cilen != CILEN_COMPRESS))\r
+                               goto bad;\r
+                       no.neg_vj = 1;\r
+                       break;\r
+               case CI_ADDRS:\r
+                       if ((go->neg_addr && go->old_addrs) || no.old_addrs\r
+                                       || cilen != CILEN_ADDRS)\r
+                               goto bad;\r
+                       try.neg_addr = 1;\r
+                       try.old_addrs = 1;\r
+                       GETLONG(l, p);\r
+                       ciaddr1 = htonl(l);\r
+                       if (ciaddr1 && go->accept_local)\r
+                               try.ouraddr = ciaddr1;\r
+                       GETLONG(l, p);\r
+                       ciaddr2 = htonl(l);\r
+                       if (ciaddr2 && go->accept_remote)\r
+                               try.hisaddr = ciaddr2;\r
+                       no.old_addrs = 1;\r
+                       break;\r
+               case CI_ADDR:\r
+                       if (go->neg_addr || no.neg_addr || cilen != CILEN_ADDR)\r
+                               goto bad;\r
+                       try.old_addrs = 0;\r
+                       GETLONG(l, p);\r
+                       ciaddr1 = htonl(l);\r
+                       if (ciaddr1 && go->accept_local)\r
+                               try.ouraddr = ciaddr1;\r
+                       if (try.ouraddr != 0)\r
+                               try.neg_addr = 1;\r
+                       no.neg_addr = 1;\r
+                       break;\r
+               }\r
+               p = next;\r
+       }\r
+       \r
+       /* If there is still anything left, this packet is bad. */\r
+       if (len != 0)\r
+               goto bad;\r
+       \r
+       /*\r
+        * OK, the Nak is good.  Now we can update state.\r
+        */\r
+       if (f->state != OPENED)\r
+               *go = try;\r
+       \r
+       return 1;\r
+       \r
+bad:\r
+       IPCPDEBUG((LOG_INFO, "ipcp_nakci: received bad Nak!\n"));\r
+       return 0;\r
+}\r
+\r
+\r
+/*\r
+ * ipcp_rejci - Reject some of our CIs.\r
+ */\r
+static int ipcp_rejci(fsm *f, u_char *p, int len)\r
+{\r
+       ipcp_options *go = &ipcp_gotoptions[f->unit];\r
+       u_char cimaxslotindex, ciflag, cilen;\r
+       u_short cishort;\r
+       u32_t cilong;\r
+       ipcp_options try;               /* options to request next time */\r
+       \r
+       try = *go;\r
+       /*\r
+        * Any Rejected CIs must be in exactly the same order that we sent.\r
+        * Check packet length and CI length at each step.\r
+        * If we find any deviations, then this packet is bad.\r
+        */\r
+#define REJCIADDR(opt, neg, old, val1, val2) \\r
+       if (go->neg && \\r
+                       len >= (cilen = old? CILEN_ADDRS: CILEN_ADDR) && \\r
+                       p[1] == cilen && \\r
+                       p[0] == opt) { \\r
+               u32_t l; \\r
+               len -= cilen; \\r
+               INCPTR(2, p); \\r
+               GETLONG(l, p); \\r
+               cilong = htonl(l); \\r
+               /* Check rejected value. */ \\r
+               if (cilong != val1) \\r
+                       goto bad; \\r
+               if (old) { \\r
+                       GETLONG(l, p); \\r
+                       cilong = htonl(l); \\r
+                       /* Check rejected value. */ \\r
+                       if (cilong != val2) \\r
+                               goto bad; \\r
+               } \\r
+               try.neg = 0; \\r
+       }\r
+       \r
+#define REJCIVJ(opt, neg, val, old, maxslot, cflag) \\r
+       if (go->neg && \\r
+                       p[1] == (old? CILEN_COMPRESS : CILEN_VJ) && \\r
+                       len >= p[1] && \\r
+                       p[0] == opt) { \\r
+               len -= p[1]; \\r
+               INCPTR(2, p); \\r
+               GETSHORT(cishort, p); \\r
+               /* Check rejected value. */  \\r
+               if (cishort != val) \\r
+                       goto bad; \\r
+               if (!old) { \\r
+                       GETCHAR(cimaxslotindex, p); \\r
+                       if (cimaxslotindex != maxslot) \\r
+                               goto bad; \\r
+                       GETCHAR(ciflag, p); \\r
+                       if (ciflag != cflag) \\r
+                               goto bad; \\r
+               } \\r
+               try.neg = 0; \\r
+       }\r
+       \r
+#define REJCIDNS(opt, neg, dnsaddr) \\r
+       if (go->neg && \\r
+                       ((cilen = p[1]) == CILEN_ADDR) && \\r
+                       len >= cilen && \\r
+                       p[0] == opt) { \\r
+               u32_t l; \\r
+               len -= cilen; \\r
+               INCPTR(2, p); \\r
+               GETLONG(l, p); \\r
+               cilong = htonl(l); \\r
+               /* Check rejected value. */ \\r
+               if (cilong != dnsaddr) \\r
+                       goto bad; \\r
+               try.neg = 0; \\r
+       }\r
+\r
+       REJCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), neg_addr,\r
+                         go->old_addrs, go->ouraddr, go->hisaddr);\r
+       \r
+       REJCIVJ(CI_COMPRESSTYPE, neg_vj, go->vj_protocol, go->old_vj,\r
+                       go->maxslotindex, go->cflag);\r
+       \r
+       REJCIDNS(CI_MS_DNS1, req_dns1, go->dnsaddr[0]);\r
+\r
+       REJCIDNS(CI_MS_DNS2, req_dns2, go->dnsaddr[1]);\r
+\r
+       /*\r
+        * If there are any remaining CIs, then this packet is bad.\r
+        */\r
+       if (len != 0)\r
+               goto bad;\r
+       /*\r
+        * Now we can update state.\r
+        */\r
+       if (f->state != OPENED)\r
+               *go = try;\r
+       return 1;\r
+       \r
+bad:\r
+       IPCPDEBUG((LOG_INFO, "ipcp_rejci: received bad Reject!\n"));\r
+       return 0;\r
+}\r
+\r
+\r
+/*\r
+ * ipcp_reqci - Check the peer's requested CIs and send appropriate response.\r
+ *\r
+ * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified\r
+ * appropriately.  If reject_if_disagree is non-zero, doesn't return\r
+ * CONFNAK; returns CONFREJ if it can't return CONFACK.\r
+ */\r
+static int ipcp_reqci(\r
+       fsm *f,\r
+       u_char *inp,            /* Requested CIs */\r
+       int *len,                       /* Length of requested CIs */\r
+       int reject_if_disagree\r
+)\r
+{\r
+       ipcp_options *wo = &ipcp_wantoptions[f->unit];\r
+       ipcp_options *ho = &ipcp_hisoptions[f->unit];\r
+       ipcp_options *ao = &ipcp_allowoptions[f->unit];\r
+#ifdef OLD_CI_ADDRS\r
+       ipcp_options *go = &ipcp_gotoptions[f->unit];\r
+#endif\r
+       u_char *cip, *next;                             /* Pointer to current and next CIs */\r
+       u_short cilen, citype;                  /* Parsed len, type */\r
+       u_short cishort;                                /* Parsed short value */\r
+       u32_t tl, ciaddr1;                      /* Parsed address values */\r
+#ifdef OLD_CI_ADDRS\r
+       u32_t ciaddr2;                          /* Parsed address values */\r
+#endif\r
+       int rc = CONFACK;                               /* Final packet return code */\r
+       int orc;                                                /* Individual option return code */\r
+       u_char *p;                                              /* Pointer to next char to parse */\r
+       u_char *ucp = inp;                              /* Pointer to current output char */\r
+       int l = *len;                                   /* Length left */\r
+       u_char maxslotindex, cflag;\r
+       int d;\r
+       \r
+       cis_received[f->unit] = 1;\r
+       \r
+       /*\r
+        * Reset all his options.\r
+        */\r
+       BZERO(ho, sizeof(*ho));\r
+       \r
+       /*\r
+        * Process all his options.\r
+        */\r
+       next = inp;\r
+       while (l) {\r
+               orc = CONFACK;                          /* Assume success */\r
+               cip = p = next;                         /* Remember begining of CI */\r
+               if (l < 2 ||                            /* Not enough data for CI header or */\r
+                               p[1] < 2 ||                     /*  CI length too small or */\r
+                               p[1] > l) {                     /*  CI length too big? */\r
+                       IPCPDEBUG((LOG_INFO, "ipcp_reqci: bad CI length!\n"));\r
+                       orc = CONFREJ;                  /* Reject bad CI */\r
+                       cilen = l;                              /* Reject till end of packet */\r
+                       l = 0;                                  /* Don't loop again */\r
+                       goto endswitch;\r
+               }\r
+               GETCHAR(citype, p);                     /* Parse CI type */\r
+               GETCHAR(cilen, p);                      /* Parse CI length */\r
+               l -= cilen;                                     /* Adjust remaining length */\r
+               next += cilen;                          /* Step to next CI */\r
+\r
+               switch (citype) {                       /* Check CI type */\r
+#ifdef OLD_CI_ADDRS /* Need to save space... */\r
+               case CI_ADDRS:\r
+                       IPCPDEBUG((LOG_INFO, "ipcp_reqci: received ADDRS\n"));\r
+                       if (!ao->neg_addr ||\r
+                                       cilen != CILEN_ADDRS) { /* Check CI length */\r
+                               orc = CONFREJ;          /* Reject CI */\r
+                               break;\r
+                       }\r
+                       \r
+                       /*\r
+                        * If he has no address, or if we both have his address but\r
+                        * disagree about it, then NAK it with our idea.\r
+                        * In particular, if we don't know his address, but he does,\r
+                        * then accept it.\r
+                        */\r
+                       GETLONG(tl, p);         /* Parse source address (his) */\r
+                       ciaddr1 = htonl(tl);\r
+                       IPCPDEBUG((LOG_INFO, "his addr %s\n", inet_ntoa(ciaddr1)));\r
+                       if (ciaddr1 != wo->hisaddr\r
+                                       && (ciaddr1 == 0 || !wo->accept_remote)) {\r
+                               orc = CONFNAK;\r
+                               if (!reject_if_disagree) {\r
+                                       DECPTR(sizeof(u32_t), p);\r
+                                       tl = ntohl(wo->hisaddr);\r
+                                       PUTLONG(tl, p);\r
+                               }\r
+                       } else if (ciaddr1 == 0 && wo->hisaddr == 0) {\r
+                               /*\r
+                                * If neither we nor he knows his address, reject the option.\r
+                                */\r
+                               orc = CONFREJ;\r
+                               wo->req_addr = 0;       /* don't NAK with 0.0.0.0 later */\r
+                               break;\r
+                       }\r
+                       \r
+                       /*\r
+                        * If he doesn't know our address, or if we both have our address\r
+                        * but disagree about it, then NAK it with our idea.\r
+                        */\r
+                       GETLONG(tl, p);         /* Parse desination address (ours) */\r
+                       ciaddr2 = htonl(tl);\r
+                       IPCPDEBUG((LOG_INFO, "our addr %s\n", inet_ntoa(ciaddr2)));\r
+                       if (ciaddr2 != wo->ouraddr) {\r
+                               if (ciaddr2 == 0 || !wo->accept_local) {\r
+                                       orc = CONFNAK;\r
+                                       if (!reject_if_disagree) {\r
+                                               DECPTR(sizeof(u32_t), p);\r
+                                               tl = ntohl(wo->ouraddr);\r
+                                               PUTLONG(tl, p);\r
+                                       }\r
+                               } else {\r
+                                       go->ouraddr = ciaddr2;  /* accept peer's idea */\r
+                               }\r
+                       }\r
+                       \r
+                       ho->neg_addr = 1;\r
+                       ho->old_addrs = 1;\r
+                       ho->hisaddr = ciaddr1;\r
+                       ho->ouraddr = ciaddr2;\r
+                       break;\r
+#endif\r
+               \r
+               case CI_ADDR:\r
+                       if (!ao->neg_addr) {\r
+                               IPCPDEBUG((LOG_INFO, "ipcp_reqci: Reject ADDR not allowed\n"));\r
+                               orc = CONFREJ;                          /* Reject CI */\r
+                               break;\r
+                       } else if (cilen != CILEN_ADDR) {       /* Check CI length */\r
+                               IPCPDEBUG((LOG_INFO, "ipcp_reqci: Reject ADDR bad len\n"));\r
+                               orc = CONFREJ;                          /* Reject CI */\r
+                               break;\r
+                       }\r
+                       \r
+                       /*\r
+                        * If he has no address, or if we both have his address but\r
+                        * disagree about it, then NAK it with our idea.\r
+                        * In particular, if we don't know his address, but he does,\r
+                        * then accept it.\r
+                        */\r
+                       GETLONG(tl, p); /* Parse source address (his) */\r
+                       ciaddr1 = htonl(tl);\r
+                       if (ciaddr1 != wo->hisaddr\r
+                                       && (ciaddr1 == 0 || !wo->accept_remote)) {\r
+                               orc = CONFNAK;\r
+                               if (!reject_if_disagree) {\r
+                                       DECPTR(sizeof(u32_t), p);\r
+                                       tl = ntohl(wo->hisaddr);\r
+                                       PUTLONG(tl, p);\r
+                               }\r
+                               IPCPDEBUG((LOG_INFO, "ipcp_reqci: Nak ADDR %s\n", inet_ntoa(ciaddr1)));\r
+                       } else if (ciaddr1 == 0 && wo->hisaddr == 0) {\r
+                               /*\r
+                                * Don't ACK an address of 0.0.0.0 - reject it instead.\r
+                                */\r
+                               IPCPDEBUG((LOG_INFO, "ipcp_reqci: Reject ADDR %s\n", inet_ntoa(ciaddr1)));\r
+                               orc = CONFREJ;\r
+                               wo->req_addr = 0;       /* don't NAK with 0.0.0.0 later */\r
+                               break;\r
+                       }\r
+                       \r
+                       ho->neg_addr = 1;\r
+                       ho->hisaddr = ciaddr1;\r
+                       IPCPDEBUG((LOG_INFO, "ipcp_reqci: ADDR %s\n", inet_ntoa(ciaddr1)));\r
+                       break;\r
+               \r
+               case CI_MS_DNS1:\r
+               case CI_MS_DNS2:\r
+                       /* Microsoft primary or secondary DNS request */\r
+                       d = citype == CI_MS_DNS2;\r
+                       \r
+                       /* If we do not have a DNS address then we cannot send it */\r
+                       if (ao->dnsaddr[d] == 0 ||\r
+                                       cilen != CILEN_ADDR) {  /* Check CI length */\r
+                               IPCPDEBUG((LOG_INFO, "ipcp_reqci: Rejecting DNS%d Request\n", d+1));\r
+                               orc = CONFREJ;                          /* Reject CI */\r
+                               break;\r
+                       }\r
+                       GETLONG(tl, p);\r
+                       if (htonl(tl) != ao->dnsaddr[d]) {\r
+                               IPCPDEBUG((LOG_INFO, "ipcp_reqci: Naking DNS%d Request %d\n",\r
+                                                       d+1, inet_ntoa(tl)));\r
+                               DECPTR(sizeof(u32_t), p);\r
+                               tl = ntohl(ao->dnsaddr[d]);\r
+                               PUTLONG(tl, p);\r
+                               orc = CONFNAK;\r
+                       }\r
+                       IPCPDEBUG((LOG_INFO, "ipcp_reqci: received DNS%d Request\n", d+1));\r
+                       break;\r
+               \r
+               case CI_MS_WINS1:\r
+               case CI_MS_WINS2:\r
+                       /* Microsoft primary or secondary WINS request */\r
+                       d = citype == CI_MS_WINS2;\r
+                       IPCPDEBUG((LOG_INFO, "ipcp_reqci: received WINS%d Request\n", d+1));\r
+                       \r
+                       /* If we do not have a DNS address then we cannot send it */\r
+                       if (ao->winsaddr[d] == 0 ||\r
+                               cilen != CILEN_ADDR) {  /* Check CI length */\r
+                               orc = CONFREJ;                  /* Reject CI */\r
+                               break;\r
+                       }\r
+                       GETLONG(tl, p);\r
+                       if (htonl(tl) != ao->winsaddr[d]) {\r
+                               DECPTR(sizeof(u32_t), p);\r
+                               tl = ntohl(ao->winsaddr[d]);\r
+                               PUTLONG(tl, p);\r
+                               orc = CONFNAK;\r
+                       }\r
+                       break;\r
+               \r
+               case CI_COMPRESSTYPE:\r
+                       if (!ao->neg_vj) {\r
+                               IPCPDEBUG((LOG_INFO, "ipcp_reqci: Rejecting COMPRESSTYPE not allowed\n"));\r
+                               orc = CONFREJ;\r
+                               break;\r
+                       } else if (cilen != CILEN_VJ && cilen != CILEN_COMPRESS) {\r
+                               IPCPDEBUG((LOG_INFO, "ipcp_reqci: Rejecting COMPRESSTYPE len=%d\n", cilen));\r
+                               orc = CONFREJ;\r
+                               break;\r
+                       }\r
+                       GETSHORT(cishort, p);\r
+                       \r
+                       if (!(cishort == IPCP_VJ_COMP ||\r
+                                       (cishort == IPCP_VJ_COMP_OLD && cilen == CILEN_COMPRESS))) {\r
+                               IPCPDEBUG((LOG_INFO, "ipcp_reqci: Rejecting COMPRESSTYPE %d\n", cishort));\r
+                               orc = CONFREJ;\r
+                               break;\r
+                       }\r
+                       \r
+                       ho->neg_vj = 1;\r
+                       ho->vj_protocol = cishort;\r
+                       if (cilen == CILEN_VJ) {\r
+                               GETCHAR(maxslotindex, p);\r
+                               if (maxslotindex > ao->maxslotindex) { \r
+                                       IPCPDEBUG((LOG_INFO, "ipcp_reqci: Naking VJ max slot %d\n", maxslotindex));\r
+                                       orc = CONFNAK;\r
+                                       if (!reject_if_disagree){\r
+                                               DECPTR(1, p);\r
+                                               PUTCHAR(ao->maxslotindex, p);\r
+                                       }\r
+                               }\r
+                               GETCHAR(cflag, p);\r
+                               if (cflag && !ao->cflag) {\r
+                                       IPCPDEBUG((LOG_INFO, "ipcp_reqci: Naking VJ cflag %d\n", cflag));\r
+                                       orc = CONFNAK;\r
+                                       if (!reject_if_disagree){\r
+                                               DECPTR(1, p);\r
+                                               PUTCHAR(wo->cflag, p);\r
+                                       }\r
+                               }\r
+                               ho->maxslotindex = maxslotindex;\r
+                               ho->cflag = cflag;\r
+                       } else {\r
+                               ho->old_vj = 1;\r
+                               ho->maxslotindex = MAX_SLOTS - 1;\r
+                               ho->cflag = 1;\r
+                       }\r
+                       IPCPDEBUG((LOG_INFO, \r
+                                               "ipcp_reqci: received COMPRESSTYPE p=%d old=%d maxslot=%d cflag=%d\n",\r
+                                               ho->vj_protocol, ho->old_vj, ho->maxslotindex, ho->cflag));\r
+                       break;\r
+                       \r
+               default:\r
+                       IPCPDEBUG((LOG_INFO, "ipcp_reqci: Rejecting unknown CI type %d\n", citype));\r
+                       orc = CONFREJ;\r
+                       break;\r
+               }\r
+               \r
+endswitch:\r
+               if (orc == CONFACK &&           /* Good CI */\r
+                               rc != CONFACK)          /*  but prior CI wasnt? */\r
+                       continue;                               /* Don't send this one */\r
+               \r
+               if (orc == CONFNAK) {           /* Nak this CI? */\r
+                       if (reject_if_disagree) {       /* Getting fed up with sending NAKs? */\r
+                               IPCPDEBUG((LOG_INFO, "ipcp_reqci: Rejecting too many naks\n"));\r
+                               orc = CONFREJ;          /* Get tough if so */\r
+                       } else {\r
+                               if (rc == CONFREJ)      /* Rejecting prior CI? */\r
+                                       continue;               /* Don't send this one */\r
+                               if (rc == CONFACK) {    /* Ack'd all prior CIs? */\r
+                                       rc = CONFNAK;   /* Not anymore... */\r
+                                       ucp = inp;              /* Backup */\r
+                               }\r
+                       }\r
+               }\r
+               \r
+               if (orc == CONFREJ &&           /* Reject this CI */\r
+                               rc != CONFREJ) {        /*  but no prior ones? */\r
+                       rc = CONFREJ;\r
+                       ucp = inp;                              /* Backup */\r
+               }\r
+               \r
+               /* Need to move CI? */\r
+               if (ucp != cip)\r
+                       BCOPY(cip, ucp, cilen); /* Move it */\r
+               \r
+               /* Update output pointer */\r
+               INCPTR(cilen, ucp);\r
+       }\r
+       \r
+       /*\r
+        * If we aren't rejecting this packet, and we want to negotiate\r
+        * their address, and they didn't send their address, then we\r
+        * send a NAK with a CI_ADDR option appended.  We assume the\r
+        * input buffer is long enough that we can append the extra\r
+        * option safely.\r
+        */\r
+       if (rc != CONFREJ && !ho->neg_addr &&\r
+                       wo->req_addr && !reject_if_disagree) {\r
+               IPCPDEBUG((LOG_INFO, "ipcp_reqci: Requesting peer address\n"));\r
+               if (rc == CONFACK) {\r
+                       rc = CONFNAK;\r
+                       ucp = inp;                              /* reset pointer */\r
+                       wo->req_addr = 0;               /* don't ask again */\r
+               }\r
+               PUTCHAR(CI_ADDR, ucp);\r
+               PUTCHAR(CILEN_ADDR, ucp);\r
+               tl = ntohl(wo->hisaddr);\r
+               PUTLONG(tl, ucp);\r
+       }\r
+       \r
+       *len = (int)(ucp - inp);                /* Compute output length */\r
+       IPCPDEBUG((LOG_INFO, "ipcp_reqci: returning Configure-%s\n", CODENAME(rc)));\r
+       return (rc);                    /* Return final code */\r
+}\r
+\r
+\r
+#if 0\r
+/*\r
+ * ip_check_options - check that any IP-related options are OK,\r
+ * and assign appropriate defaults.\r
+ */\r
+static void ip_check_options(u_long localAddr)\r
+{\r
+       ipcp_options *wo = &ipcp_wantoptions[0];\r
+\r
+       /*\r
+        * Load our default IP address but allow the remote host to give us\r
+        * a new address.\r
+        */\r
+       if (wo->ouraddr == 0 && !ppp_settings.disable_defaultip) {\r
+               wo->accept_local = 1;   /* don't insist on this default value */\r
+               wo->ouraddr = htonl(localAddr);\r
+       }\r
+}\r
+#endif\r
+\r
+\r
+/*\r
+ * ipcp_up - IPCP has come UP.\r
+ *\r
+ * Configure the IP network interface appropriately and bring it up.\r
+ */\r
+static void ipcp_up(fsm *f)\r
+{\r
+       u32_t mask;\r
+       ipcp_options *ho = &ipcp_hisoptions[f->unit];\r
+       ipcp_options *go = &ipcp_gotoptions[f->unit];\r
+       ipcp_options *wo = &ipcp_wantoptions[f->unit];\r
+       \r
+       np_up(f->unit, PPP_IP);\r
+       IPCPDEBUG((LOG_INFO, "ipcp: up\n"));\r
+       \r
+       /*\r
+        * We must have a non-zero IP address for both ends of the link.\r
+        */\r
+       if (!ho->neg_addr)\r
+               ho->hisaddr = wo->hisaddr;\r
+       \r
+       if (ho->hisaddr == 0) {\r
+               IPCPDEBUG((LOG_ERR, "Could not determine remote IP address\n"));\r
+               ipcp_close(f->unit, "Could not determine remote IP address");\r
+               return;\r
+       }\r
+       if (go->ouraddr == 0) {\r
+               IPCPDEBUG((LOG_ERR, "Could not determine local IP address\n"));\r
+               ipcp_close(f->unit, "Could not determine local IP address");\r
+               return;\r
+       }\r
+       \r
+       if (ppp_settings.usepeerdns && (go->dnsaddr[0] || go->dnsaddr[1])) {\r
+               /*pppGotDNSAddrs(go->dnsaddr[0], go->dnsaddr[1]);*/\r
+       }\r
+\r
+       /*\r
+        * Check that the peer is allowed to use the IP address it wants.\r
+        */\r
+       if (!auth_ip_addr(f->unit, ho->hisaddr)) {\r
+               IPCPDEBUG((LOG_ERR, "Peer is not authorized to use remote address %s\n",\r
+                               inet_ntoa(ho->hisaddr)));\r
+               ipcp_close(f->unit, "Unauthorized remote IP address");\r
+               return;\r
+       }\r
+       \r
+       /* set tcp compression */\r
+       sifvjcomp(f->unit, ho->neg_vj, ho->cflag, ho->maxslotindex);\r
+       \r
+       /*\r
+        * Set IP addresses and (if specified) netmask.\r
+        */\r
+       mask = GetMask(go->ouraddr);\r
+       \r
+       if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask, go->dnsaddr[0], go->dnsaddr[1])) {\r
+               IPCPDEBUG((LOG_WARNING, "sifaddr failed\n"));\r
+               ipcp_close(f->unit, "Interface configuration failed");\r
+               return;\r
+       }\r
+       \r
+       /* bring the interface up for IP */\r
+       if (!sifup(f->unit)) {\r
+               IPCPDEBUG((LOG_WARNING, "sifup failed\n"));\r
+               ipcp_close(f->unit, "Interface configuration failed");\r
+               return;\r
+       }\r
+       \r
+       sifnpmode(f->unit, PPP_IP, NPMODE_PASS);\r
+       \r
+       /* assign a default route through the interface if required */\r
+       if (ipcp_wantoptions[f->unit].default_route) \r
+               if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr))\r
+                       default_route_set[f->unit] = 1;\r
+       \r
+       IPCPDEBUG((LOG_NOTICE, "local  IP address %s\n", inet_ntoa(go->ouraddr)));\r
+       IPCPDEBUG((LOG_NOTICE, "remote IP address %s\n", inet_ntoa(ho->hisaddr)));\r
+       if (go->dnsaddr[0]) {\r
+               IPCPDEBUG((LOG_NOTICE, "primary   DNS address %s\n", inet_ntoa(go->dnsaddr[0])));\r
+       }\r
+       if (go->dnsaddr[1]) {\r
+               IPCPDEBUG((LOG_NOTICE, "secondary DNS address %s\n", inet_ntoa(go->dnsaddr[1])));\r
+       }\r
+}\r
+\r
+\r
+/*\r
+ * ipcp_down - IPCP has gone DOWN.\r
+ *\r
+ * Take the IP network interface down, clear its addresses\r
+ * and delete routes through it.\r
+ */\r
+static void ipcp_down(fsm *f)\r
+{\r
+       IPCPDEBUG((LOG_INFO, "ipcp: down\n"));\r
+       np_down(f->unit, PPP_IP);\r
+       sifvjcomp(f->unit, 0, 0, 0);\r
+       \r
+       sifdown(f->unit);\r
+       ipcp_clear_addrs(f->unit);\r
+}\r
+\r
+\r
+/*\r
+ * ipcp_clear_addrs() - clear the interface addresses, routes, etc.\r
+ */\r
+static void ipcp_clear_addrs(int unit)\r
+{\r
+       u32_t ouraddr, hisaddr;\r
+       \r
+       ouraddr = ipcp_gotoptions[unit].ouraddr;\r
+       hisaddr = ipcp_hisoptions[unit].hisaddr;\r
+       if (default_route_set[unit]) {\r
+               cifdefaultroute(unit, ouraddr, hisaddr);\r
+               default_route_set[unit] = 0;\r
+       }\r
+       cifaddr(unit, ouraddr, hisaddr);\r
+}\r
+\r
+\r
+/*\r
+ * ipcp_finished - possibly shut down the lower layers.\r
+ */\r
+static void ipcp_finished(fsm *f)\r
+{\r
+       np_finished(f->unit, PPP_IP);\r
+}\r
+\r
+#if 0\r
+static int ipcp_printpkt(\r
+       u_char *p,\r
+       int plen,\r
+       void (*printer) (void *, char *, ...),\r
+       void *arg\r
+)\r
+{\r
+       (void)p;\r
+       (void)plen;\r
+       (void)printer;\r
+       (void)arg;\r
+       return 0;\r
+}\r
+\r
+/*\r
+ * ip_active_pkt - see if this IP packet is worth bringing the link up for.\r
+ * We don't bring the link up for IP fragments or for TCP FIN packets\r
+ * with no data.\r
+ */\r
+#define IP_HDRLEN      20      /* bytes */\r
+#define IP_OFFMASK     0x1fff\r
+#define IPPROTO_TCP    6\r
+#define TCP_HDRLEN     20\r
+#define TH_FIN         0x01\r
+\r
+/*\r
+ * We use these macros because the IP header may be at an odd address,\r
+ * and some compilers might use word loads to get th_off or ip_hl.\r
+ */\r
+\r
+#define net_short(x)   (((x)[0] << 8) + (x)[1])\r
+#define get_iphl(x)    (((unsigned char *)(x))[0] & 0xF)\r
+#define get_ipoff(x)   net_short((unsigned char *)(x) + 6)\r
+#define get_ipproto(x) (((unsigned char *)(x))[9])\r
+#define get_tcpoff(x)  (((unsigned char *)(x))[12] >> 4)\r
+#define get_tcpflags(x)        (((unsigned char *)(x))[13])\r
+\r
+static int ip_active_pkt(u_char *pkt, int len)\r
+{\r
+       u_char *tcp;\r
+       int hlen;\r
+       \r
+       len -= PPP_HDRLEN;\r
+       pkt += PPP_HDRLEN;\r
+       if (len < IP_HDRLEN)\r
+               return 0;\r
+       if ((get_ipoff(pkt) & IP_OFFMASK) != 0)\r
+               return 0;\r
+       if (get_ipproto(pkt) != IPPROTO_TCP)\r
+               return 1;\r
+       hlen = get_iphl(pkt) * 4;\r
+       if (len < hlen + TCP_HDRLEN)\r
+               return 0;\r
+       tcp = pkt + hlen;\r
+       if ((get_tcpflags(tcp) & TH_FIN) != 0 && len == hlen + get_tcpoff(tcp) * 4)\r
+               return 0;\r
+       return 1;\r
+}\r
+#endif\r
+\r
+#endif /* PPP_SUPPORT */\r
index e907bdfcec5405925d9a31ca3254876895478783..0ee2edbbd798490a4c11b85d65449e79d93aa94b 100644 (file)
-/*****************************************************************************
-* ipcp.h -  PPP IP NCP: Internet Protocol Network Control Protocol header file.
-*
-* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
-* portions Copyright (c) 1997 Global Election Systems Inc.
-*
-* The authors hereby grant permission to use, copy, modify, distribute,
-* and license this software and its documentation for any purpose, provided
-* that existing copyright notices are retained in all copies and that this
-* notice and the following disclaimer are included verbatim in any 
-* distributions. No written agreement, license, or royalty fee is required
-* for any of the authorized uses.
-*
-* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *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 CONTRIBUTORS 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.
-*
-******************************************************************************
-* REVISION HISTORY
-*
-* 03-01-01 Marc Boucher <marc@mbsi.ca>
-*   Ported to lwIP.
-* 97-12-04 Guy Lancaster <glanca@gesn.com>, Global Election Systems Inc.
-*      Original derived from BSD codes.
-*****************************************************************************/
-/*
- * ipcp.h - IP Control Protocol definitions.
- *
- * Copyright (c) 1989 Carnegie Mellon University.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by Carnegie Mellon University.  The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * $Id: ipcp.h,v 1.2 2006/08/29 18:53:47 wolti Exp $
- */
-
-#ifndef IPCP_H
-#define IPCP_H
-
-/*************************
-*** PUBLIC DEFINITIONS ***
-*************************/
-/*
- * Options.
- */
-#define CI_ADDRS       1                       /* IP Addresses */
-#define CI_COMPRESSTYPE        2               /* Compression Type */
-#define        CI_ADDR         3
-
-#define CI_MS_WINS1    128                     /* Primary WINS value */
-#define CI_MS_DNS1     129                     /* Primary DNS value */
-#define CI_MS_WINS2    130                     /* Secondary WINS value */
-#define CI_MS_DNS2     131                     /* Secondary DNS value */
-
-#define IPCP_VJMODE_OLD 1              /* "old" mode (option # = 0x0037) */
-#define IPCP_VJMODE_RFC1172 2  /* "old-rfc"mode (option # = 0x002d) */
-#define IPCP_VJMODE_RFC1332 3  /* "new-rfc"mode (option # = 0x002d, */
-                                /*  maxslot and slot number compression) */
-
-#define IPCP_VJ_COMP 0x002d            /* current value for VJ compression option*/
-#define IPCP_VJ_COMP_OLD 0x0037        /* "old" (i.e, broken) value for VJ */
-                                                               /* compression option*/ 
-
-
-/************************
-*** PUBLIC DATA TYPES ***
-************************/
-
-typedef struct ipcp_options {
-    u_int neg_addr : 1;                        /* Negotiate IP Address? */
-    u_int old_addrs : 1;                       /* Use old (IP-Addresses) option? */
-    u_int req_addr : 1;                        /* Ask peer to send IP address? */
-    u_int default_route : 1;           /* Assign default route through interface? */
-    u_int proxy_arp : 1;                       /* Make proxy ARP entry for peer? */
-    u_int neg_vj : 1;                          /* Van Jacobson Compression? */
-    u_int old_vj : 1;                          /* use old (short) form of VJ option? */
-    u_int accept_local : 1;            /* accept peer's value for ouraddr */
-    u_int accept_remote : 1;           /* accept peer's value for hisaddr */
-    u_int req_dns1 : 1;                        /* Ask peer to send primary DNS address? */
-    u_int req_dns2 : 1;                        /* Ask peer to send secondary DNS address? */
-    u_short vj_protocol;               /* protocol value to use in VJ option */
-    u_char maxslotindex;               /* VJ slots - 1. */
-    u_char cflag;                              /* VJ slot compression flag. */
-    u32_t ouraddr, hisaddr;    /* Addresses in NETWORK BYTE ORDER */
-    u32_t dnsaddr[2];          /* Primary and secondary MS DNS entries */
-    u32_t winsaddr[2];         /* Primary and secondary MS WINS entries */
-} ipcp_options;
-
-
-/*****************************
-*** PUBLIC DATA STRUCTURES ***
-*****************************/
-
-extern fsm ipcp_fsm[];
-extern ipcp_options ipcp_wantoptions[];
-extern ipcp_options ipcp_gotoptions[];
-extern ipcp_options ipcp_allowoptions[];
-extern ipcp_options ipcp_hisoptions[];
-
-extern struct protent ipcp_protent;
-
-
-/***********************
-*** PUBLIC FUNCTIONS ***
-***********************/
-
-
-#endif /* IPCP_H */
-
+/*****************************************************************************\r
+* ipcp.h -  PPP IP NCP: Internet Protocol Network Control Protocol header file.\r
+*\r
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.\r
+* portions Copyright (c) 1997 Global Election Systems Inc.\r
+*\r
+* The authors hereby grant permission to use, copy, modify, distribute,\r
+* and license this software and its documentation for any purpose, provided\r
+* that existing copyright notices are retained in all copies and that this\r
+* notice and the following disclaimer are included verbatim in any \r
+* distributions. No written agreement, license, or royalty fee is required\r
+* for any of the authorized uses.\r
+*\r
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR\r
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+*\r
+******************************************************************************\r
+* REVISION HISTORY\r
+*\r
+* 03-01-01 Marc Boucher <marc@mbsi.ca>\r
+*   Ported to lwIP.\r
+* 97-12-04 Guy Lancaster <glanca@gesn.com>, Global Election Systems Inc.\r
+*      Original derived from BSD codes.\r
+*****************************************************************************/\r
+/*\r
+ * ipcp.h - IP Control Protocol definitions.\r
+ *\r
+ * Copyright (c) 1989 Carnegie Mellon University.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms are permitted\r
+ * provided that the above copyright notice and this paragraph are\r
+ * duplicated in all such forms and that any documentation,\r
+ * advertising materials, and other materials related to such\r
+ * distribution and use acknowledge that the software was developed\r
+ * by Carnegie Mellon University.  The name of the\r
+ * University may not be used to endorse or promote products derived\r
+ * from this software without specific prior written permission.\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR\r
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r
+ *\r
+ * $Id: ipcp.h,v 1.2 2006/08/29 18:53:47 wolti Exp $\r
+ */\r
+\r
+#ifndef IPCP_H\r
+#define IPCP_H\r
+\r
+/*************************\r
+*** PUBLIC DEFINITIONS ***\r
+*************************/\r
+/*\r
+ * Options.\r
+ */\r
+#define CI_ADDRS       1                       /* IP Addresses */\r
+#define CI_COMPRESSTYPE        2               /* Compression Type */\r
+#define        CI_ADDR         3\r
+\r
+#define CI_MS_WINS1    128                     /* Primary WINS value */\r
+#define CI_MS_DNS1     129                     /* Primary DNS value */\r
+#define CI_MS_WINS2    130                     /* Secondary WINS value */\r
+#define CI_MS_DNS2     131                     /* Secondary DNS value */\r
+\r
+#define IPCP_VJMODE_OLD 1              /* "old" mode (option # = 0x0037) */\r
+#define IPCP_VJMODE_RFC1172 2  /* "old-rfc"mode (option # = 0x002d) */\r
+#define IPCP_VJMODE_RFC1332 3  /* "new-rfc"mode (option # = 0x002d, */\r
+                                /*  maxslot and slot number compression) */\r
+\r
+#define IPCP_VJ_COMP 0x002d            /* current value for VJ compression option*/\r
+#define IPCP_VJ_COMP_OLD 0x0037        /* "old" (i.e, broken) value for VJ */\r
+                                                               /* compression option*/ \r
+\r
+\r
+/************************\r
+*** PUBLIC DATA TYPES ***\r
+************************/\r
+\r
+typedef struct ipcp_options {\r
+    u_int neg_addr : 1;                        /* Negotiate IP Address? */\r
+    u_int old_addrs : 1;                       /* Use old (IP-Addresses) option? */\r
+    u_int req_addr : 1;                        /* Ask peer to send IP address? */\r
+    u_int default_route : 1;           /* Assign default route through interface? */\r
+    u_int proxy_arp : 1;                       /* Make proxy ARP entry for peer? */\r
+    u_int neg_vj : 1;                          /* Van Jacobson Compression? */\r
+    u_int old_vj : 1;                          /* use old (short) form of VJ option? */\r
+    u_int accept_local : 1;            /* accept peer's value for ouraddr */\r
+    u_int accept_remote : 1;           /* accept peer's value for hisaddr */\r
+    u_int req_dns1 : 1;                        /* Ask peer to send primary DNS address? */\r
+    u_int req_dns2 : 1;                        /* Ask peer to send secondary DNS address? */\r
+    u_short vj_protocol;               /* protocol value to use in VJ option */\r
+    u_char maxslotindex;               /* VJ slots - 1. */\r
+    u_char cflag;                              /* VJ slot compression flag. */\r
+    u32_t ouraddr, hisaddr;    /* Addresses in NETWORK BYTE ORDER */\r
+    u32_t dnsaddr[2];          /* Primary and secondary MS DNS entries */\r
+    u32_t winsaddr[2];         /* Primary and secondary MS WINS entries */\r
+} ipcp_options;\r
+\r
+\r
+/*****************************\r
+*** PUBLIC DATA STRUCTURES ***\r
+*****************************/\r
+\r
+extern fsm ipcp_fsm[];\r
+extern ipcp_options ipcp_wantoptions[];\r
+extern ipcp_options ipcp_gotoptions[];\r
+extern ipcp_options ipcp_allowoptions[];\r
+extern ipcp_options ipcp_hisoptions[];\r
+\r
+extern struct protent ipcp_protent;\r
+\r
+\r
+/***********************\r
+*** PUBLIC FUNCTIONS ***\r
+***********************/\r
+\r
+\r
+#endif /* IPCP_H */\r
+\r
index 6a988d6df6e16784a3351984e34255b3aaa24e48..41dbc5dd21b9ad19177c1bd033334f0986fe349e 100644 (file)
-/*****************************************************************************
-* lcp.c - Network Link Control Protocol program file.
-*
-* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
-* portions Copyright (c) 1997 by Global Election Systems Inc.
-*
-* The authors hereby grant permission to use, copy, modify, distribute,
-* and license this software and its documentation for any purpose, provided
-* that existing copyright notices are retained in all copies and that this
-* notice and the following disclaimer are included verbatim in any 
-* distributions. No written agreement, license, or royalty fee is required
-* for any of the authorized uses.
-*
-* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *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 CONTRIBUTORS 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.
-*
-******************************************************************************
-* REVISION HISTORY
-*
-* 03-01-01 Marc Boucher <marc@mbsi.ca>
-*   Ported to lwIP.
-* 97-12-01 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
-*      Original.
-*****************************************************************************/
-
-/*
- * lcp.c - PPP Link Control Protocol.
- *
- * Copyright (c) 1989 Carnegie Mellon University.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by Carnegie Mellon University.  The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-#include <string.h>
-#include "ppp.h"
-#if PPP_SUPPORT > 0
-#include "fsm.h"
-#include "chap.h"
-#include "magic.h"
-#include "auth.h"
-#include "lcp.h"
-#include "pppdebug.h"
-
-
-/*************************/
-/*** LOCAL DEFINITIONS ***/
-/*************************/
-/*
- * Length of each type of configuration option (in octets)
- */
-#define CILEN_VOID     2
-#define CILEN_CHAR     3
-#define CILEN_SHORT    4       /* CILEN_VOID + sizeof(short) */
-#define CILEN_CHAP     5       /* CILEN_VOID + sizeof(short) + 1 */
-#define CILEN_LONG     6       /* CILEN_VOID + sizeof(long) */
-#define CILEN_LQR      8       /* CILEN_VOID + sizeof(short) + sizeof(long) */
-#define CILEN_CBCP     3
-
-
-/***********************************/
-/*** LOCAL FUNCTION DECLARATIONS ***/
-/***********************************/
-/*
- * Callbacks for fsm code.  (CI = Configuration Information)
- */
-static void lcp_resetci (fsm*);                /* Reset our CI */
-static int  lcp_cilen (fsm*);                  /* Return length of our CI */
-static void lcp_addci (fsm*, u_char*, int*);       /* Add our CI to pkt */
-static int  lcp_ackci (fsm*, u_char*, int);/* Peer ack'd our CI */
-static int  lcp_nakci (fsm*, u_char*, int);/* Peer nak'd our CI */
-static int  lcp_rejci (fsm*, u_char*, int);/* Peer rej'd our CI */
-static int  lcp_reqci (fsm*, u_char*, int*, int);  /* Rcv peer CI */
-static void lcp_up (fsm*);                         /* We're UP */
-static void lcp_down (fsm*);               /* We're DOWN */
-static void lcp_starting (fsm*);           /* We need lower layer up */
-static void lcp_finished (fsm*);               /* We need lower layer down */
-static int  lcp_extcode (fsm*, int, u_char, u_char*, int);
-
-static void lcp_rprotrej (fsm*, u_char*, int);
-
-/*
- * routines to send LCP echos to peer
- */
-static void lcp_echo_lowerup (int);
-static void lcp_echo_lowerdown (int);
-static void LcpEchoTimeout (void*);
-static void lcp_received_echo_reply (fsm*, int, u_char*, int);
-static void LcpSendEchoRequest (fsm*);
-static void LcpLinkFailure (fsm*);
-static void LcpEchoCheck (fsm*);
-
-/*
- * Protocol entry points.
- * Some of these are called directly.
- */
-static void lcp_input (int, u_char *, int);
-static void lcp_protrej (int);
-
-#define CODENAME(x)    ((x) == CONFACK ? "ACK" : \
-                        (x) == CONFNAK ? "NAK" : "REJ")
-
-
-/******************************/
-/*** PUBLIC DATA STRUCTURES ***/
-/******************************/
-/* global vars */
-LinkPhase lcp_phase[NUM_PPP];                  /* Phase of link session (RFC 1661) */
-lcp_options lcp_wantoptions[NUM_PPP];  /* Options that we want to request */
-lcp_options lcp_gotoptions[NUM_PPP];   /* Options that peer ack'd */
-lcp_options lcp_allowoptions[NUM_PPP]; /* Options we allow peer to request */
-lcp_options lcp_hisoptions[NUM_PPP];   /* Options that we ack'd */
-ext_accm xmit_accm[NUM_PPP];                   /* extended transmit ACCM */
-
-
-
-/*****************************/
-/*** LOCAL DATA STRUCTURES ***/
-/*****************************/
-static fsm lcp_fsm[NUM_PPP];                   /* LCP fsm structure (global)*/
-static u_int    lcp_echo_interval = LCP_ECHOINTERVAL; /* Interval between LCP echo-requests */
-static u_int    lcp_echo_fails = LCP_MAXECHOFAILS; /* Tolerance to unanswered echo-requests */
-static u32_t lcp_echos_pending = 0;    /* Number of outstanding echo msgs */
-static u32_t lcp_echo_number   = 0;    /* ID number of next echo frame */
-static u32_t lcp_echo_timer_running = 0;  /* TRUE if a timer is running */
-
-static u_char nak_buffer[PPP_MRU];     /* where we construct a nak packet */
-
-static fsm_callbacks lcp_callbacks = { /* LCP callback routines */
-    lcp_resetci,               /* Reset our Configuration Information */
-    lcp_cilen,                 /* Length of our Configuration Information */
-    lcp_addci,                 /* Add our Configuration Information */
-    lcp_ackci,                 /* ACK our Configuration Information */
-    lcp_nakci,                 /* NAK our Configuration Information */
-    lcp_rejci,                 /* Reject our Configuration Information */
-    lcp_reqci,                 /* Request peer's Configuration Information */
-    lcp_up,                            /* Called when fsm reaches OPENED state */
-    lcp_down,                  /* Called when fsm leaves OPENED state */
-    lcp_starting,              /* Called when we want the lower layer up */
-    lcp_finished,              /* Called when we want the lower layer down */
-    NULL,                              /* Called when Protocol-Reject received */
-    NULL,                              /* Retransmission is necessary */
-    lcp_extcode,               /* Called to handle LCP-specific codes */
-    "LCP"                              /* String name of protocol */
-};
-
-struct protent lcp_protent = {
-    PPP_LCP,
-    lcp_init,
-    lcp_input,
-    lcp_protrej,
-    lcp_lowerup,
-    lcp_lowerdown,
-    lcp_open,
-    lcp_close,
-#if 0
-    lcp_printpkt,
-    NULL,
-#endif
-    1,
-    "LCP",
-#if 0
-    NULL,
-    NULL,
-    NULL
-#endif
-};
-
-int lcp_loopbackfail = DEFLOOPBACKFAIL;
-
-
-
-/***********************************/
-/*** PUBLIC FUNCTION DEFINITIONS ***/
-/***********************************/
-/*
- * lcp_init - Initialize LCP.
- */
-void lcp_init(int unit)
-{
-       fsm *f = &lcp_fsm[unit];
-       lcp_options *wo = &lcp_wantoptions[unit];
-       lcp_options *ao = &lcp_allowoptions[unit];
-       
-       f->unit = unit;
-       f->protocol = PPP_LCP;
-       f->callbacks = &lcp_callbacks;
-       
-       fsm_init(f);
-       
-       wo->passive = 0;
-       wo->silent = 0;
-       wo->restart = 0;                        /* Set to 1 in kernels or multi-line
-                                                                * implementations */
-       wo->neg_mru = 1;
-       wo->mru = PPP_DEFMRU;
-       wo->neg_asyncmap = 1;
-       wo->asyncmap = 0x00000000l;     /* Assume don't need to escape any ctl chars. */
-       wo->neg_chap = 0;                       /* Set to 1 on server */
-       wo->neg_upap = 0;                       /* Set to 1 on server */
-       wo->chap_mdtype = CHAP_DIGEST_MD5;
-       wo->neg_magicnumber = 1;
-       wo->neg_pcompression = 1;
-       wo->neg_accompression = 1;
-       wo->neg_lqr = 0;                        /* no LQR implementation yet */
-       wo->neg_cbcp = 0;
-       
-       ao->neg_mru = 1;
-       ao->mru = PPP_MAXMRU;
-       ao->neg_asyncmap = 1;
-       ao->asyncmap = 0x00000000l;     /* Assume don't need to escape any ctl chars. */
-       ao->neg_chap = (CHAP_SUPPORT != 0);
-       ao->chap_mdtype = CHAP_DIGEST_MD5;
-       ao->neg_upap = (PAP_SUPPORT != 0);
-       ao->neg_magicnumber = 1;
-       ao->neg_pcompression = 1;
-       ao->neg_accompression = 1;
-       ao->neg_lqr = 0;                        /* no LQR implementation yet */
-       ao->neg_cbcp = (CBCP_SUPPORT != 0);
-
-       /* 
-        * Set transmit escape for the flag and escape characters plus anything
-        * set for the allowable options.
-        */
-       memset(xmit_accm[unit], 0, sizeof(xmit_accm[0]));
-       xmit_accm[unit][15] = 0x60;
-       xmit_accm[unit][0] = (u_char)(ao->asyncmap & 0xFF);
-       xmit_accm[unit][1] = (u_char)((ao->asyncmap >> 8) & 0xFF);
-       xmit_accm[unit][2] = (u_char)((ao->asyncmap >> 16) & 0xFF);
-       xmit_accm[unit][3] = (u_char)((ao->asyncmap >> 24) & 0xFF);
-       LCPDEBUG((LOG_INFO, "lcp_init: xmit_accm=%X %X %X %X\n",
-                               xmit_accm[unit][0],
-                               xmit_accm[unit][1],
-                               xmit_accm[unit][2],
-                               xmit_accm[unit][3]));
-       
-       lcp_phase[unit] = PHASE_INITIALIZE;
-}
-
-
-/*
- * lcp_open - LCP is allowed to come up.
- */
-void lcp_open(int unit)
-{
-       fsm *f = &lcp_fsm[unit];
-       lcp_options *wo = &lcp_wantoptions[unit];
-       
-       f->flags = 0;
-       if (wo->passive)
-               f->flags |= OPT_PASSIVE;
-       if (wo->silent)
-               f->flags |= OPT_SILENT;
-       fsm_open(f);
-       
-       lcp_phase[unit] = PHASE_ESTABLISH; 
-}
-
-
-/*
- * lcp_close - Take LCP down.
- */
-void lcp_close(int unit, char *reason)
-{
-       fsm *f = &lcp_fsm[unit];
-       
-       if (lcp_phase[unit] != PHASE_DEAD)
-               lcp_phase[unit] = PHASE_TERMINATE;
-       if (f->state == STOPPED && f->flags & (OPT_PASSIVE|OPT_SILENT)) {
-               /*
-                * This action is not strictly according to the FSM in RFC1548,
-                * but it does mean that the program terminates if you do an
-                * lcp_close() in passive/silent mode when a connection hasn't
-                * been established.
-                */
-               f->state = CLOSED;
-               lcp_finished(f);
-       }
-       else
-               fsm_close(&lcp_fsm[unit], reason);
-}
-
-
-/*
- * lcp_lowerup - The lower layer is up.
- */
-void lcp_lowerup(int unit)
-{
-       lcp_options *wo = &lcp_wantoptions[unit];
-       
-       /*
-       * Don't use A/C or protocol compression on transmission,
-       * but accept A/C and protocol compressed packets
-       * if we are going to ask for A/C and protocol compression.
-       */
-       ppp_set_xaccm(unit, &xmit_accm[unit]);
-       ppp_send_config(unit, PPP_MRU, 0xffffffffl, 0, 0);
-       ppp_recv_config(unit, PPP_MRU, 0x00000000l,
-                                       wo->neg_pcompression, wo->neg_accompression);
-       peer_mru[unit] = PPP_MRU;
-       lcp_allowoptions[unit].asyncmap 
-               = (u_long)xmit_accm[unit][0]
-                       | ((u_long)xmit_accm[unit][1] << 8)
-                       | ((u_long)xmit_accm[unit][2] << 16)
-                       | ((u_long)xmit_accm[unit][3] << 24);
-       LCPDEBUG((LOG_INFO, "lcp_lowerup: asyncmap=%X %X %X %X\n",
-                               xmit_accm[unit][3],
-                               xmit_accm[unit][2],
-                               xmit_accm[unit][1],
-                               xmit_accm[unit][0]));
-       
-       fsm_lowerup(&lcp_fsm[unit]);
-}
-
-
-/*
- * lcp_lowerdown - The lower layer is down.
- */
-void lcp_lowerdown(int unit)
-{
-       fsm_lowerdown(&lcp_fsm[unit]);
-}
-
-/*
- * lcp_sprotrej - Send a Protocol-Reject for some protocol.
- */
-void lcp_sprotrej(int unit, u_char *p, int len)
-{
-       /*
-       * Send back the protocol and the information field of the
-       * rejected packet.  We only get here if LCP is in the OPENED state.
-       */
-
-       fsm_sdata(&lcp_fsm[unit], PROTREJ, ++lcp_fsm[unit].id,
-                               p, len);
-}
-
-
-
-/**********************************/
-/*** LOCAL FUNCTION DEFINITIONS ***/
-/**********************************/
-/*
- * lcp_input - Input LCP packet.
- */
-static void lcp_input(int unit, u_char *p, int len)
-{
-       fsm *f = &lcp_fsm[unit];
-       
-       fsm_input(f, p, len);
-}
-
-
-/*
- * lcp_extcode - Handle a LCP-specific code.
- */
-static int lcp_extcode(fsm *f, int code, u_char id, u_char *inp, int len)
-{
-       u_char *magp;
-       
-       switch( code ){
-       case PROTREJ:
-               lcp_rprotrej(f, inp, len);
-               break;
-       
-       case ECHOREQ:
-               if (f->state != OPENED)
-                       break;
-               LCPDEBUG((LOG_INFO, "lcp: Echo-Request, Rcvd id %d\n", id));
-               magp = inp;
-               PUTLONG(lcp_gotoptions[f->unit].magicnumber, magp);
-               fsm_sdata(f, ECHOREP, id, inp, len);
-               break;
-       
-       case ECHOREP:
-               lcp_received_echo_reply(f, id, inp, len);
-               break;
-       
-       case DISCREQ:
-               break;
-       
-       default:
-               return 0;
-       }
-       return 1;
-}
-
-    
-/*
- * lcp_rprotrej - Receive an Protocol-Reject.
- *
- * Figure out which protocol is rejected and inform it.
- */
-static void lcp_rprotrej(fsm *f, u_char *inp, int len)
-{
-       int i;
-       struct protent *protp;
-       u_short prot;
-       
-       if (len < sizeof (u_short)) {
-               LCPDEBUG((LOG_INFO,
-                               "lcp_rprotrej: Rcvd short Protocol-Reject packet!\n"));
-               return;
-       }
-       
-       GETSHORT(prot, inp);
-       
-       LCPDEBUG((LOG_INFO,
-                       "lcp_rprotrej: Rcvd Protocol-Reject packet for %x!\n",
-                       prot));
-       
-       /*
-       * Protocol-Reject packets received in any state other than the LCP
-       * OPENED state SHOULD be silently discarded.
-       */
-       if( f->state != OPENED ){
-               LCPDEBUG((LOG_INFO, "Protocol-Reject discarded: LCP in state %d\n",
-                               f->state));
-               return;
-       }
-       
-       /*
-       * Upcall the proper Protocol-Reject routine.
-       */
-       for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i)
-               if (protp->protocol == prot && protp->enabled_flag) {
-                       (*protp->protrej)(f->unit);
-                       return;
-               }
-       
-       LCPDEBUG((LOG_WARNING, "Protocol-Reject for unsupported protocol 0x%x\n",
-                       prot));
-}
-
-
-/*
- * lcp_protrej - A Protocol-Reject was received.
- */
-static void lcp_protrej(int unit)
-{
-       (void)unit;
-       /*
-       * Can't reject LCP!
-       */
-       LCPDEBUG((LOG_WARNING,
-                       "lcp_protrej: Received Protocol-Reject for LCP!\n"));
-       fsm_protreject(&lcp_fsm[unit]);
-}
-
-
-/*
- * lcp_resetci - Reset our CI.
- */
-static void lcp_resetci(fsm *f)
-{
-       lcp_wantoptions[f->unit].magicnumber = magic();
-       lcp_wantoptions[f->unit].numloops = 0;
-       lcp_gotoptions[f->unit] = lcp_wantoptions[f->unit];
-       peer_mru[f->unit] = PPP_MRU;
-       auth_reset(f->unit);
-}
-
-
-/*
- * lcp_cilen - Return length of our CI.
- */
-static int lcp_cilen(fsm *f)
-{
-       lcp_options *go = &lcp_gotoptions[f->unit];
-
-#define LENCIVOID(neg) ((neg) ? CILEN_VOID : 0)
-#define LENCICHAP(neg) ((neg) ? CILEN_CHAP : 0)
-#define LENCISHORT(neg)        ((neg) ? CILEN_SHORT : 0)
-#define LENCILONG(neg) ((neg) ? CILEN_LONG : 0)
-#define LENCILQR(neg)  ((neg) ? CILEN_LQR: 0)
-#define LENCICBCP(neg) ((neg) ? CILEN_CBCP: 0)
-       /*
-       * NB: we only ask for one of CHAP and UPAP, even if we will
-       * accept either.
-       */
-       return (LENCISHORT(go->neg_mru && go->mru != PPP_DEFMRU) +
-               LENCILONG(go->neg_asyncmap && go->asyncmap != 0xFFFFFFFFl) +
-               LENCICHAP(go->neg_chap) +
-               LENCISHORT(!go->neg_chap && go->neg_upap) +
-               LENCILQR(go->neg_lqr) +
-               LENCICBCP(go->neg_cbcp) +
-               LENCILONG(go->neg_magicnumber) +
-               LENCIVOID(go->neg_pcompression) +
-               LENCIVOID(go->neg_accompression));
-}
-
-
-/*
- * lcp_addci - Add our desired CIs to a packet.
- */
-static void lcp_addci(fsm *f, u_char *ucp, int *lenp)
-{
-       lcp_options *go = &lcp_gotoptions[f->unit];
-       u_char *start_ucp = ucp;
-       
-#define ADDCIVOID(opt, neg) \
-       if (neg) { \
-           LCPDEBUG((LOG_INFO, "lcp_addci: opt=%d\n", opt)); \
-               PUTCHAR(opt, ucp); \
-               PUTCHAR(CILEN_VOID, ucp); \
-       }
-#define ADDCISHORT(opt, neg, val) \
-       if (neg) { \
-           LCPDEBUG((LOG_INFO, "lcp_addci: INT opt=%d %X\n", opt, val)); \
-               PUTCHAR(opt, ucp); \
-               PUTCHAR(CILEN_SHORT, ucp); \
-               PUTSHORT(val, ucp); \
-       }
-#define ADDCICHAP(opt, neg, val, digest) \
-       if (neg) { \
-           LCPDEBUG((LOG_INFO, "lcp_addci: CHAP opt=%d %X\n", opt, val)); \
-               PUTCHAR(opt, ucp); \
-               PUTCHAR(CILEN_CHAP, ucp); \
-               PUTSHORT(val, ucp); \
-               PUTCHAR(digest, ucp); \
-       }
-#define ADDCILONG(opt, neg, val) \
-       if (neg) { \
-           LCPDEBUG((LOG_INFO, "lcp_addci: L opt=%d %lX\n", opt, val)); \
-               PUTCHAR(opt, ucp); \
-               PUTCHAR(CILEN_LONG, ucp); \
-               PUTLONG(val, ucp); \
-       }
-#define ADDCILQR(opt, neg, val) \
-       if (neg) { \
-           LCPDEBUG((LOG_INFO, "lcp_addci: LQR opt=%d %lX\n", opt, val)); \
-               PUTCHAR(opt, ucp); \
-               PUTCHAR(CILEN_LQR, ucp); \
-               PUTSHORT(PPP_LQR, ucp); \
-               PUTLONG(val, ucp); \
-       }
-#define ADDCICHAR(opt, neg, val) \
-       if (neg) { \
-           LCPDEBUG((LOG_INFO, "lcp_addci: CHAR opt=%d %X '%z'\n", opt, val, val)); \
-               PUTCHAR(opt, ucp); \
-               PUTCHAR(CILEN_CHAR, ucp); \
-               PUTCHAR(val, ucp); \
-       }
-       
-       ADDCISHORT(CI_MRU, go->neg_mru && go->mru != PPP_DEFMRU, go->mru);
-       ADDCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFFl,
-                       go->asyncmap);
-       ADDCICHAP(CI_AUTHTYPE, go->neg_chap, PPP_CHAP, go->chap_mdtype);
-       ADDCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, PPP_PAP);
-       ADDCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period);
-       ADDCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT);
-       ADDCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber);
-       ADDCIVOID(CI_PCOMPRESSION, go->neg_pcompression);
-       ADDCIVOID(CI_ACCOMPRESSION, go->neg_accompression);
-       
-       if (ucp - start_ucp != *lenp) {
-               /* this should never happen, because peer_mtu should be 1500 */
-               LCPDEBUG((LOG_ERR, "Bug in lcp_addci: wrong length\n"));
-       }
-}
-
-
-/*
- * lcp_ackci - Ack our CIs.
- * This should not modify any state if the Ack is bad.
- *
- * Returns:
- *     0 - Ack was bad.
- *     1 - Ack was good.
- */
-static int lcp_ackci(fsm *f, u_char *p, int len)
-{
-       lcp_options *go = &lcp_gotoptions[f->unit];
-       u_char cilen, citype, cichar;
-       u_short cishort;
-       u32_t cilong;
-       
-       /*
-       * CIs must be in exactly the same order that we sent.
-       * Check packet length and CI length at each step.
-       * If we find any deviations, then this packet is bad.
-       */
-#define ACKCIVOID(opt, neg) \
-       if (neg) { \
-               if ((len -= CILEN_VOID) < 0) \
-                       goto bad; \
-               GETCHAR(citype, p); \
-               GETCHAR(cilen, p); \
-               if (cilen != CILEN_VOID || \
-                               citype != opt) \
-                       goto bad; \
-       }
-#define ACKCISHORT(opt, neg, val) \
-       if (neg) { \
-               if ((len -= CILEN_SHORT) < 0) \
-                       goto bad; \
-               GETCHAR(citype, p); \
-               GETCHAR(cilen, p); \
-               if (cilen != CILEN_SHORT || \
-                               citype != opt) \
-                       goto bad; \
-               GETSHORT(cishort, p); \
-               if (cishort != val) \
-                       goto bad; \
-       }
-#define ACKCICHAR(opt, neg, val) \
-       if (neg) { \
-               if ((len -= CILEN_CHAR) < 0) \
-                       goto bad; \
-               GETCHAR(citype, p); \
-               GETCHAR(cilen, p); \
-               if (cilen != CILEN_CHAR || \
-                               citype != opt) \
-                       goto bad; \
-               GETCHAR(cichar, p); \
-               if (cichar != val) \
-                       goto bad; \
-       }
-#define ACKCICHAP(opt, neg, val, digest) \
-       if (neg) { \
-               if ((len -= CILEN_CHAP) < 0) \
-                       goto bad; \
-               GETCHAR(citype, p); \
-               GETCHAR(cilen, p); \
-               if (cilen != CILEN_CHAP || \
-                               citype != opt) \
-                       goto bad; \
-               GETSHORT(cishort, p); \
-               if (cishort != val) \
-                       goto bad; \
-               GETCHAR(cichar, p); \
-               if (cichar != digest) \
-                       goto bad; \
-       }
-#define ACKCILONG(opt, neg, val) \
-       if (neg) { \
-               if ((len -= CILEN_LONG) < 0) \
-                       goto bad; \
-               GETCHAR(citype, p); \
-               GETCHAR(cilen, p); \
-               if (cilen != CILEN_LONG || \
-                               citype != opt) \
-                       goto bad; \
-               GETLONG(cilong, p); \
-               if (cilong != val) \
-                       goto bad; \
-       }
-#define ACKCILQR(opt, neg, val) \
-       if (neg) { \
-               if ((len -= CILEN_LQR) < 0) \
-                       goto bad; \
-               GETCHAR(citype, p); \
-               GETCHAR(cilen, p); \
-               if (cilen != CILEN_LQR || \
-                               citype != opt) \
-                       goto bad; \
-               GETSHORT(cishort, p); \
-               if (cishort != PPP_LQR) \
-                       goto bad; \
-               GETLONG(cilong, p); \
-               if (cilong != val) \
-                       goto bad; \
-       }
-       
-       ACKCISHORT(CI_MRU, go->neg_mru && go->mru != PPP_DEFMRU, go->mru);
-       ACKCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFFl,
-                       go->asyncmap);
-       ACKCICHAP(CI_AUTHTYPE, go->neg_chap, PPP_CHAP, go->chap_mdtype);
-       ACKCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, PPP_PAP);
-       ACKCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period);
-       ACKCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT);
-       ACKCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber);
-       ACKCIVOID(CI_PCOMPRESSION, go->neg_pcompression);
-       ACKCIVOID(CI_ACCOMPRESSION, go->neg_accompression);
-       
-       /*
-        * If there are any remaining CIs, then this packet is bad.
-        */
-       if (len != 0)
-               goto bad;
-       LCPDEBUG((LOG_INFO, "lcp_acki: Ack\n"));
-       return (1);
-bad:
-       LCPDEBUG((LOG_WARNING, "lcp_acki: received bad Ack!\n"));
-       return (0);
-}
-
-
-/*
- * lcp_nakci - Peer has sent a NAK for some of our CIs.
- * This should not modify any state if the Nak is bad
- * or if LCP is in the OPENED state.
- *
- * Returns:
- *     0 - Nak was bad.
- *     1 - Nak was good.
- */
-static int lcp_nakci(fsm *f, u_char *p, int len)
-{
-       lcp_options *go = &lcp_gotoptions[f->unit];
-       lcp_options *wo = &lcp_wantoptions[f->unit];
-       u_char citype, cichar, *next;
-       u_short cishort;
-       u32_t cilong;
-       lcp_options no;         /* options we've seen Naks for */
-       lcp_options try;                /* options to request next time */
-       int looped_back = 0;
-       int cilen;
-       
-       BZERO(&no, sizeof(no));
-       try = *go;
-       
-       /*
-       * Any Nak'd CIs must be in exactly the same order that we sent.
-       * Check packet length and CI length at each step.
-       * If we find any deviations, then this packet is bad.
-       */
-#define NAKCIVOID(opt, neg, code) \
-       if (go->neg && \
-                       len >= CILEN_VOID && \
-                       p[1] == CILEN_VOID && \
-                       p[0] == opt) { \
-               len -= CILEN_VOID; \
-               INCPTR(CILEN_VOID, p); \
-               no.neg = 1; \
-               code \
-       }
-#define NAKCICHAP(opt, neg, code) \
-       if (go->neg && \
-                       len >= CILEN_CHAP && \
-                       p[1] == CILEN_CHAP && \
-                       p[0] == opt) { \
-               len -= CILEN_CHAP; \
-               INCPTR(2, p); \
-               GETSHORT(cishort, p); \
-               GETCHAR(cichar, p); \
-               no.neg = 1; \
-               code \
-       }
-#define NAKCICHAR(opt, neg, code) \
-       if (go->neg && \
-                       len >= CILEN_CHAR && \
-                       p[1] == CILEN_CHAR && \
-                       p[0] == opt) { \
-               len -= CILEN_CHAR; \
-               INCPTR(2, p); \
-               GETCHAR(cichar, p); \
-               no.neg = 1; \
-               code \
-       }
-#define NAKCISHORT(opt, neg, code) \
-       if (go->neg && \
-                       len >= CILEN_SHORT && \
-                       p[1] == CILEN_SHORT && \
-                       p[0] == opt) { \
-               len -= CILEN_SHORT; \
-               INCPTR(2, p); \
-               GETSHORT(cishort, p); \
-               no.neg = 1; \
-               code \
-       }
-#define NAKCILONG(opt, neg, code) \
-       if (go->neg && \
-                       len >= CILEN_LONG && \
-                       p[1] == CILEN_LONG && \
-                       p[0] == opt) { \
-               len -= CILEN_LONG; \
-               INCPTR(2, p); \
-               GETLONG(cilong, p); \
-               no.neg = 1; \
-               code \
-       }
-#define NAKCILQR(opt, neg, code) \
-       if (go->neg && \
-                       len >= CILEN_LQR && \
-                       p[1] == CILEN_LQR && \
-                       p[0] == opt) { \
-               len -= CILEN_LQR; \
-               INCPTR(2, p); \
-               GETSHORT(cishort, p); \
-               GETLONG(cilong, p); \
-               no.neg = 1; \
-               code \
-       }
-       
-       /*
-       * We don't care if they want to send us smaller packets than
-       * we want.  Therefore, accept any MRU less than what we asked for,
-       * but then ignore the new value when setting the MRU in the kernel.
-       * If they send us a bigger MRU than what we asked, accept it, up to
-       * the limit of the default MRU we'd get if we didn't negotiate.
-       */
-       if (go->neg_mru && go->mru != PPP_DEFMRU) {
-               NAKCISHORT(CI_MRU, neg_mru,
-                       if (cishort <= wo->mru || cishort < PPP_DEFMRU)
-                               try.mru = cishort;
-               );
-       }
-       
-       /*
-       * Add any characters they want to our (receive-side) asyncmap.
-       */
-       if (go->neg_asyncmap && go->asyncmap != 0xFFFFFFFFl) {
-               NAKCILONG(CI_ASYNCMAP, neg_asyncmap,
-                       try.asyncmap = go->asyncmap | cilong;
-               );
-       }
-       
-       /*
-       * If they've nak'd our authentication-protocol, check whether
-       * they are proposing a different protocol, or a different
-       * hash algorithm for CHAP.
-       */
-       if ((go->neg_chap || go->neg_upap)
-                       && len >= CILEN_SHORT
-                       && p[0] == CI_AUTHTYPE && p[1] >= CILEN_SHORT && p[1] <= len) {
-               cilen = p[1];
-       len -= cilen;
-       no.neg_chap = go->neg_chap;
-       no.neg_upap = go->neg_upap;
-       INCPTR(2, p);
-       GETSHORT(cishort, p);
-       if (cishort == PPP_PAP && cilen == CILEN_SHORT) {
-               /*
-                * If we were asking for CHAP, they obviously don't want to do it.
-                * If we weren't asking for CHAP, then we were asking for PAP,
-                * in which case this Nak is bad.
-                */
-               if (!go->neg_chap)
-                       goto bad;
-               try.neg_chap = 0;
-       
-       } else if (cishort == PPP_CHAP && cilen == CILEN_CHAP) {
-               GETCHAR(cichar, p);
-               if (go->neg_chap) {
-                       /*
-                        * We were asking for CHAP/MD5; they must want a different
-                        * algorithm.  If they can't do MD5, we'll have to stop
-                        * asking for CHAP.
-                        */
-                       if (cichar != go->chap_mdtype)
-                               try.neg_chap = 0;
-               } else {
-                       /*
-                        * Stop asking for PAP if we were asking for it.
-                        */
-                       try.neg_upap = 0;
-               }
-       
-       } else {
-               /*
-                * We don't recognize what they're suggesting.
-                * Stop asking for what we were asking for.
-                */
-               if (go->neg_chap)
-                       try.neg_chap = 0;
-               else
-                       try.neg_upap = 0;
-               p += cilen - CILEN_SHORT;
-       }
-       }
-       
-       /*
-       * If they can't cope with our link quality protocol, we'll have
-       * to stop asking for LQR.  We haven't got any other protocol.
-       * If they Nak the reporting period, take their value XXX ?
-       */
-       NAKCILQR(CI_QUALITY, neg_lqr,
-               if (cishort != PPP_LQR)
-                       try.neg_lqr = 0;
-               else
-                       try.lqr_period = cilong;
-       );
-       
-       /*
-       * Only implementing CBCP...not the rest of the callback options
-       */
-       NAKCICHAR(CI_CALLBACK, neg_cbcp,
-               try.neg_cbcp = 0;
-       );
-       
-       /*
-       * Check for a looped-back line.
-       */
-       NAKCILONG(CI_MAGICNUMBER, neg_magicnumber,
-               try.magicnumber = magic();
-               looped_back = 1;
-       );
-       
-       /*
-       * Peer shouldn't send Nak for protocol compression or
-       * address/control compression requests; they should send
-       * a Reject instead.  If they send a Nak, treat it as a Reject.
-       */
-       NAKCIVOID(CI_PCOMPRESSION, neg_pcompression,
-               try.neg_pcompression = 0;
-       );
-       NAKCIVOID(CI_ACCOMPRESSION, neg_accompression,
-               try.neg_accompression = 0;
-       );
-       
-       /*
-       * There may be remaining CIs, if the peer is requesting negotiation
-       * on an option that we didn't include in our request packet.
-       * If we see an option that we requested, or one we've already seen
-       * in this packet, then this packet is bad.
-       * If we wanted to respond by starting to negotiate on the requested
-       * option(s), we could, but we don't, because except for the
-       * authentication type and quality protocol, if we are not negotiating
-       * an option, it is because we were told not to.
-       * For the authentication type, the Nak from the peer means
-       * `let me authenticate myself with you' which is a bit pointless.
-       * For the quality protocol, the Nak means `ask me to send you quality
-       * reports', but if we didn't ask for them, we don't want them.
-       * An option we don't recognize represents the peer asking to
-       * negotiate some option we don't support, so ignore it.
-       */
-       while (len > CILEN_VOID) {
-               GETCHAR(citype, p);
-               GETCHAR(cilen, p);
-               if (cilen < CILEN_VOID || (len -= cilen) < 0)
-                       goto bad;
-               next = p + cilen - 2;
-               
-               switch (citype) {
-               case CI_MRU:
-                       if ((go->neg_mru && go->mru != PPP_DEFMRU)
-                                       || no.neg_mru || cilen != CILEN_SHORT)
-                               goto bad;
-                       GETSHORT(cishort, p);
-                       if (cishort < PPP_DEFMRU)
-                               try.mru = cishort;
-                       break;
-               case CI_ASYNCMAP:
-                       if ((go->neg_asyncmap && go->asyncmap != 0xFFFFFFFFl)
-                                       || no.neg_asyncmap || cilen != CILEN_LONG)
-                               goto bad;
-                       break;
-               case CI_AUTHTYPE:
-                       if (go->neg_chap || no.neg_chap || go->neg_upap || no.neg_upap)
-                               goto bad;
-                       break;
-               case CI_MAGICNUMBER:
-                       if (go->neg_magicnumber || no.neg_magicnumber ||
-                                       cilen != CILEN_LONG)
-                               goto bad;
-                       break;
-               case CI_PCOMPRESSION:
-                       if (go->neg_pcompression || no.neg_pcompression
-                                       || cilen != CILEN_VOID)
-                               goto bad;
-                       break;
-               case CI_ACCOMPRESSION:
-                       if (go->neg_accompression || no.neg_accompression
-                                       || cilen != CILEN_VOID)
-                               goto bad;
-                       break;
-               case CI_QUALITY:
-                       if (go->neg_lqr || no.neg_lqr || cilen != CILEN_LQR)
-                               goto bad;
-                       break;
-               }
-               p = next;
-       }
-       
-       /* If there is still anything left, this packet is bad. */
-       if (len != 0)
-               goto bad;
-       
-       /*
-       * OK, the Nak is good.  Now we can update state.
-       */
-       if (f->state != OPENED) {
-               if (looped_back) {
-                       if (++try.numloops >= lcp_loopbackfail) {
-                               LCPDEBUG((LOG_NOTICE, "Serial line is looped back.\n"));
-                               lcp_close(f->unit, "Loopback detected");
-                       }
-               } 
-               else
-                       try.numloops = 0;
-               *go = try;
-       }
-       
-       return 1;
-       
-bad:
-       LCPDEBUG((LOG_WARNING, "lcp_nakci: received bad Nak!\n"));
-       return 0;
-}
-
-
-/*
- * lcp_rejci - Peer has Rejected some of our CIs.
- * This should not modify any state if the Reject is bad
- * or if LCP is in the OPENED state.
- *
- * Returns:
- *     0 - Reject was bad.
- *     1 - Reject was good.
- */
-static int lcp_rejci(fsm *f, u_char *p, int len)
-{
-       lcp_options *go = &lcp_gotoptions[f->unit];
-       u_char cichar;
-       u_short cishort;
-       u32_t cilong;
-       lcp_options try;                /* options to request next time */
-       
-       try = *go;
-       
-       /*
-       * Any Rejected CIs must be in exactly the same order that we sent.
-       * Check packet length and CI length at each step.
-       * If we find any deviations, then this packet is bad.
-       */
-#define REJCIVOID(opt, neg) \
-       if (go->neg && \
-                       len >= CILEN_VOID && \
-                       p[1] == CILEN_VOID && \
-                       p[0] == opt) { \
-               len -= CILEN_VOID; \
-               INCPTR(CILEN_VOID, p); \
-               try.neg = 0; \
-               LCPDEBUG((LOG_INFO, "lcp_rejci: void opt %d rejected\n", opt)); \
-       }
-#define REJCISHORT(opt, neg, val) \
-       if (go->neg && \
-                       len >= CILEN_SHORT && \
-                       p[1] == CILEN_SHORT && \
-                       p[0] == opt) { \
-               len -= CILEN_SHORT; \
-               INCPTR(2, p); \
-               GETSHORT(cishort, p); \
-               /* Check rejected value. */ \
-               if (cishort != val) \
-                       goto bad; \
-               try.neg = 0; \
-               LCPDEBUG((LOG_INFO,"lcp_rejci: short opt %d rejected\n", opt)); \
-       }
-#define REJCICHAP(opt, neg, val, digest) \
-       if (go->neg && \
-                       len >= CILEN_CHAP && \
-                       p[1] == CILEN_CHAP && \
-                       p[0] == opt) { \
-               len -= CILEN_CHAP; \
-               INCPTR(2, p); \
-               GETSHORT(cishort, p); \
-               GETCHAR(cichar, p); \
-               /* Check rejected value. */ \
-               if (cishort != val || cichar != digest) \
-                       goto bad; \
-               try.neg = 0; \
-               try.neg_upap = 0; \
-               LCPDEBUG((LOG_INFO,"lcp_rejci: chap opt %d rejected\n", opt)); \
-       }
-#define REJCILONG(opt, neg, val) \
-       if (go->neg && \
-                       len >= CILEN_LONG && \
-                       p[1] == CILEN_LONG && \
-                       p[0] == opt) { \
-               len -= CILEN_LONG; \
-               INCPTR(2, p); \
-               GETLONG(cilong, p); \
-               /* Check rejected value. */ \
-               if (cilong != val) \
-                       goto bad; \
-               try.neg = 0; \
-               LCPDEBUG((LOG_INFO,"lcp_rejci: long opt %d rejected\n", opt)); \
-       }
-#define REJCILQR(opt, neg, val) \
-       if (go->neg && \
-                       len >= CILEN_LQR && \
-                       p[1] == CILEN_LQR && \
-                       p[0] == opt) { \
-               len -= CILEN_LQR; \
-               INCPTR(2, p); \
-               GETSHORT(cishort, p); \
-               GETLONG(cilong, p); \
-               /* Check rejected value. */ \
-               if (cishort != PPP_LQR || cilong != val) \
-                       goto bad; \
-               try.neg = 0; \
-               LCPDEBUG((LOG_INFO,"lcp_rejci: LQR opt %d rejected\n", opt)); \
-       }
-#define REJCICBCP(opt, neg, val) \
-       if (go->neg && \
-                       len >= CILEN_CBCP && \
-                       p[1] == CILEN_CBCP && \
-                       p[0] == opt) { \
-               len -= CILEN_CBCP; \
-               INCPTR(2, p); \
-               GETCHAR(cichar, p); \
-               /* Check rejected value. */ \
-               if (cichar != val) \
-                       goto bad; \
-               try.neg = 0; \
-               LCPDEBUG((LOG_INFO,"lcp_rejci: Callback opt %d rejected\n", opt)); \
-       }
-       
-       REJCISHORT(CI_MRU, neg_mru, go->mru);
-       REJCILONG(CI_ASYNCMAP, neg_asyncmap, go->asyncmap);
-       REJCICHAP(CI_AUTHTYPE, neg_chap, PPP_CHAP, go->chap_mdtype);
-       if (!go->neg_chap) {
-               REJCISHORT(CI_AUTHTYPE, neg_upap, PPP_PAP);
-       }
-       REJCILQR(CI_QUALITY, neg_lqr, go->lqr_period);
-       REJCICBCP(CI_CALLBACK, neg_cbcp, CBCP_OPT);
-       REJCILONG(CI_MAGICNUMBER, neg_magicnumber, go->magicnumber);
-       REJCIVOID(CI_PCOMPRESSION, neg_pcompression);
-       REJCIVOID(CI_ACCOMPRESSION, neg_accompression);
-       
-       /*
-       * If there are any remaining CIs, then this packet is bad.
-       */
-       if (len != 0)
-               goto bad;
-       /*
-       * Now we can update state.
-       */
-       if (f->state != OPENED)
-               *go = try;
-       return 1;
-       
-bad:
-       LCPDEBUG((LOG_WARNING, "lcp_rejci: received bad Reject!\n"));
-       return 0;
-}
-
-
-/*
- * lcp_reqci - Check the peer's requested CIs and send appropriate response.
- *
- * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified
- * appropriately.  If reject_if_disagree is non-zero, doesn't return
- * CONFNAK; returns CONFREJ if it can't return CONFACK.
- */
-static int lcp_reqci(fsm *f, 
-                                               u_char *inp,            /* Requested CIs */
-                                               int *lenp,                      /* Length of requested CIs */
-                                               int reject_if_disagree)
-{
-       lcp_options *go = &lcp_gotoptions[f->unit];
-       lcp_options *ho = &lcp_hisoptions[f->unit];
-       lcp_options *ao = &lcp_allowoptions[f->unit];
-       u_char *cip, *next;                     /* Pointer to current and next CIs */
-       int cilen, citype, cichar;      /* Parsed len, type, char value */
-       u_short cishort;                        /* Parsed short value */
-       u32_t cilong;                   /* Parse long value */
-       int rc = CONFACK;                       /* Final packet return code */
-       int orc;                                        /* Individual option return code */
-       u_char *p;                                      /* Pointer to next char to parse */
-       u_char *rejp;                           /* Pointer to next char in reject frame */
-       u_char *nakp;                           /* Pointer to next char in Nak frame */
-       int l = *lenp;                          /* Length left */
-#if TRACELCP > 0
-       char traceBuf[80];
-       int traceNdx = 0;
-#endif
-       
-       /*
-        * Reset all his options.
-        */
-       BZERO(ho, sizeof(*ho));
-       
-       /*
-        * Process all his options.
-        */
-       next = inp;
-       nakp = nak_buffer;
-       rejp = inp;
-       while (l) {
-               orc = CONFACK;                  /* Assume success */
-               cip = p = next;                 /* Remember begining of CI */
-               if (l < 2 ||                    /* Not enough data for CI header or */
-                               p[1] < 2 ||                     /*  CI length too small or */
-                               p[1] > l) {                     /*  CI length too big? */
-                       LCPDEBUG((LOG_WARNING, "lcp_reqci: bad CI length!\n"));
-                       orc = CONFREJ;          /* Reject bad CI */
-                       cilen = l;                      /* Reject till end of packet */
-                       l = 0;                  /* Don't loop again */
-                       citype = 0;
-                       goto endswitch;
-               }
-               GETCHAR(citype, p);             /* Parse CI type */
-               GETCHAR(cilen, p);              /* Parse CI length */
-               l -= cilen;                     /* Adjust remaining length */
-               next += cilen;                  /* Step to next CI */
-               
-               switch (citype) {               /* Check CI type */
-               case CI_MRU:
-                       if (!ao->neg_mru) {             /* Allow option? */
-                               LCPDEBUG((LOG_INFO, "lcp_reqci: Reject MRU - not allowed\n"));
-                               orc = CONFREJ;          /* Reject CI */
-                               break;
-                       } else if (cilen != CILEN_SHORT) {      /* Check CI length */
-                               LCPDEBUG((LOG_INFO, "lcp_reqci: Reject MRU - bad length\n"));
-                               orc = CONFREJ;          /* Reject CI */
-                               break;
-                       }
-                       GETSHORT(cishort, p);   /* Parse MRU */
-                       
-                       /*
-                        * He must be able to receive at least our minimum.
-                        * No need to check a maximum.  If he sends a large number,
-                        * we'll just ignore it.
-                        */
-                       if (cishort < PPP_MINMRU) {
-                               LCPDEBUG((LOG_INFO, "lcp_reqci: Nak - MRU too small\n"));
-                               orc = CONFNAK;          /* Nak CI */
-                               PUTCHAR(CI_MRU, nakp);
-                               PUTCHAR(CILEN_SHORT, nakp);
-                               PUTSHORT(PPP_MINMRU, nakp);     /* Give him a hint */
-                               break;
-                       }
-                       ho->neg_mru = 1;                /* Remember he sent MRU */
-                       ho->mru = cishort;              /* And remember value */
-#if TRACELCP > 0
-                       snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " MRU %d", cishort);
-                       traceNdx = strlen(traceBuf);
-#endif
-                       break;
-               
-               case CI_ASYNCMAP:
-                       if (!ao->neg_asyncmap) {
-                               LCPDEBUG((LOG_INFO, "lcp_reqci: Reject ASYNCMAP not allowed\n"));
-                               orc = CONFREJ;
-                               break;
-                       } else if (cilen != CILEN_LONG) {
-                               LCPDEBUG((LOG_INFO, "lcp_reqci: Reject ASYNCMAP bad length\n"));
-                               orc = CONFREJ;
-                               break;
-                       }
-                       GETLONG(cilong, p);
-                       
-                       /*
-                        * Asyncmap must have set at least the bits
-                        * which are set in lcp_allowoptions[unit].asyncmap.
-                        */
-                       if ((ao->asyncmap & ~cilong) != 0) {
-                               LCPDEBUG((LOG_INFO, "lcp_reqci: Nak ASYNCMAP %lX missing %lX\n", 
-                                                       cilong, ao->asyncmap));
-                               orc = CONFNAK;
-                               PUTCHAR(CI_ASYNCMAP, nakp);
-                               PUTCHAR(CILEN_LONG, nakp);
-                               PUTLONG(ao->asyncmap | cilong, nakp);
-                               break;
-                       }
-                       ho->neg_asyncmap = 1;
-                       ho->asyncmap = cilong;
-#if TRACELCP > 0
-                       snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " ASYNCMAP=%lX", cilong);
-                       traceNdx = strlen(traceBuf);
-#endif
-                       break;
-               
-               case CI_AUTHTYPE:
-                       if (cilen < CILEN_SHORT) {
-                               LCPDEBUG((LOG_INFO, "lcp_reqci: Reject AUTHTYPE missing arg\n"));
-                               orc = CONFREJ;
-                               break;
-                       } else if (!(ao->neg_upap || ao->neg_chap)) {
-                               /*
-                                * Reject the option if we're not willing to authenticate.
-                                */
-                               LCPDEBUG((LOG_INFO, "lcp_reqci: Reject AUTHTYPE not allowed\n"));
-                               orc = CONFREJ;
-                               break;
-                       }
-                       GETSHORT(cishort, p);
-                       
-                       /*
-                        * Authtype must be UPAP or CHAP.
-                        *
-                        * Note: if both ao->neg_upap and ao->neg_chap are set,
-                        * and the peer sends a Configure-Request with two
-                        * authenticate-protocol requests, one for CHAP and one
-                        * for UPAP, then we will reject the second request.
-                        * Whether we end up doing CHAP or UPAP depends then on
-                        * the ordering of the CIs in the peer's Configure-Request.
-                        */
-                       
-                       if (cishort == PPP_PAP) {
-                               if (ho->neg_chap) {     /* we've already accepted CHAP */
-                                       LCPDEBUG((LOG_WARNING, "lcp_reqci: Reject AUTHTYPE PAP already accepted\n"));
-                                       orc = CONFREJ;
-                                       break;
-                               } else if (cilen != CILEN_SHORT) {
-                                       LCPDEBUG((LOG_WARNING, "lcp_reqci: Reject AUTHTYPE PAP bad len\n"));
-                                       orc = CONFREJ;
-                                       break;
-                               }
-                               if (!ao->neg_upap) {    /* we don't want to do PAP */
-                                       LCPDEBUG((LOG_WARNING, "lcp_reqci: Nak AUTHTYPE PAP not allowed\n"));
-                                       orc = CONFNAK;  /* NAK it and suggest CHAP */
-                                       PUTCHAR(CI_AUTHTYPE, nakp);
-                                       PUTCHAR(CILEN_CHAP, nakp);
-                                       PUTSHORT(PPP_CHAP, nakp);
-                                       PUTCHAR(ao->chap_mdtype, nakp);
-                                       break;
-                               }
-                               ho->neg_upap = 1;
-#if TRACELCP > 0
-                               snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " PAP (%X)", cishort);
-                               traceNdx = strlen(traceBuf);
-#endif
-                               break;
-                       }
-                       if (cishort == PPP_CHAP) {
-                               if (ho->neg_upap) {     /* we've already accepted PAP */
-                                       LCPDEBUG((LOG_WARNING, "lcp_reqci: Reject AUTHTYPE CHAP accepted PAP\n"));
-                                       orc = CONFREJ;
-                                       break;
-                               } else if (cilen != CILEN_CHAP) {
-                                       LCPDEBUG((LOG_WARNING, "lcp_reqci: Reject AUTHTYPE CHAP bad len\n"));
-                                       orc = CONFREJ;
-                                       break;
-                               }
-                               if (!ao->neg_chap) {    /* we don't want to do CHAP */
-                                       LCPDEBUG((LOG_WARNING, "lcp_reqci: Nak AUTHTYPE CHAP not allowed\n"));
-                                       orc = CONFNAK;  /* NAK it and suggest PAP */
-                                       PUTCHAR(CI_AUTHTYPE, nakp);
-                                       PUTCHAR(CILEN_SHORT, nakp);
-                                       PUTSHORT(PPP_PAP, nakp);
-                                       break;
-                               }
-                               GETCHAR(cichar, p);     /* get digest type*/
-                               if (cichar != CHAP_DIGEST_MD5
-#ifdef CHAPMS
-                                               && cichar != CHAP_MICROSOFT
-#endif
-                               ) {
-                                       LCPDEBUG((LOG_WARNING, "lcp_reqci: Nak AUTHTYPE CHAP digest=%d\n", cichar));
-                                       orc = CONFNAK;
-                                       PUTCHAR(CI_AUTHTYPE, nakp);
-                                       PUTCHAR(CILEN_CHAP, nakp);
-                                       PUTSHORT(PPP_CHAP, nakp);
-                                       PUTCHAR(ao->chap_mdtype, nakp);
-                                       break;
-                               }
-#if TRACELCP > 0
-                               snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " CHAP %X,%d", cishort, cichar);
-                               traceNdx = strlen(traceBuf);
-#endif
-                               ho->chap_mdtype = cichar; /* save md type */
-                               ho->neg_chap = 1;
-                               break;
-                       }
-                       
-                       /*
-                        * We don't recognize the protocol they're asking for.
-                        * Nak it with something we're willing to do.
-                        * (At this point we know ao->neg_upap || ao->neg_chap.)
-                        */
-                       orc = CONFNAK;
-                       PUTCHAR(CI_AUTHTYPE, nakp);
-                       if (ao->neg_chap) {
-                               LCPDEBUG((LOG_WARNING, "lcp_reqci: Nak AUTHTYPE %d req CHAP\n", cishort));
-                               PUTCHAR(CILEN_CHAP, nakp);
-                               PUTSHORT(PPP_CHAP, nakp);
-                               PUTCHAR(ao->chap_mdtype, nakp);
-                       } 
-                       else {
-                               LCPDEBUG((LOG_WARNING, "lcp_reqci: Nak AUTHTYPE %d req PAP\n", cishort));
-                               PUTCHAR(CILEN_SHORT, nakp);
-                               PUTSHORT(PPP_PAP, nakp);
-                       }
-                       break;
-               
-               case CI_QUALITY:
-                       GETSHORT(cishort, p);
-                       GETLONG(cilong, p);
-#if TRACELCP > 0
-                       snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " QUALITY (%x %x)", cishort, (unsigned int) cilong);
-                       traceNdx = strlen(traceBuf);
-#endif
-
-                       if (!ao->neg_lqr ||
-                                       cilen != CILEN_LQR) {
-                               orc = CONFREJ;
-                               break;
-                       }
-                       
-                       /*
-                        * Check the protocol and the reporting period.
-                        * XXX When should we Nak this, and what with?
-                        */
-                       if (cishort != PPP_LQR) {
-                               orc = CONFNAK;
-                               PUTCHAR(CI_QUALITY, nakp);
-                               PUTCHAR(CILEN_LQR, nakp);
-                               PUTSHORT(PPP_LQR, nakp);
-                               PUTLONG(ao->lqr_period, nakp);
-                               break;
-                       }
-                       break;
-               
-               case CI_MAGICNUMBER:
-                       if (!(ao->neg_magicnumber || go->neg_magicnumber) ||
-                                       cilen != CILEN_LONG) {
-                               orc = CONFREJ;
-                               break;
-                       }
-                       GETLONG(cilong, p);
-#if TRACELCP > 0
-                       snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " MAGICNUMBER (%lX)", cilong);
-                       traceNdx = strlen(traceBuf);
-#endif
-
-                       /*
-                        * He must have a different magic number.
-                        */
-                       if (go->neg_magicnumber &&
-                                       cilong == go->magicnumber) {
-                               cilong = magic();       /* Don't put magic() inside macro! */
-                               orc = CONFNAK;
-                               PUTCHAR(CI_MAGICNUMBER, nakp);
-                               PUTCHAR(CILEN_LONG, nakp);
-                               PUTLONG(cilong, nakp);
-                               break;
-                       }
-                       ho->neg_magicnumber = 1;
-                       ho->magicnumber = cilong;
-                       break;
-               
-               
-               case CI_PCOMPRESSION:
-#if TRACELCP > 0
-                       snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " PCOMPRESSION");
-                       traceNdx = strlen(traceBuf);
-#endif
-                       if (!ao->neg_pcompression ||
-                                       cilen != CILEN_VOID) {
-                               orc = CONFREJ;
-                               break;
-                       }
-                       ho->neg_pcompression = 1;
-                       break;
-               
-               case CI_ACCOMPRESSION:
-#if TRACELCP > 0
-                       snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " ACCOMPRESSION");
-                       traceNdx = strlen(traceBuf);
-#endif
-                       if (!ao->neg_accompression ||
-                                       cilen != CILEN_VOID) {
-                               orc = CONFREJ;
-                               break;
-                       }
-                       ho->neg_accompression = 1;
-                       break;
-               
-               case CI_MRRU:
-#if TRACELCP > 0
-                       snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " CI_MRRU");
-                       traceNdx = strlen(traceBuf);
-#endif
-                       orc = CONFREJ;
-                       break;
-               
-               case CI_SSNHF:
-#if TRACELCP > 0
-                       snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " CI_SSNHF");
-                       traceNdx = strlen(traceBuf);
-#endif
-                       orc = CONFREJ;
-                       break;
-               
-               case CI_EPDISC:
-#if TRACELCP > 0
-                       snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " CI_EPDISC");
-                       traceNdx = strlen(traceBuf);
-#endif
-                       orc = CONFREJ;
-                       break;
-               
-               default:
-#if TRACELCP
-                       snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " unknown %d", citype);
-                       traceNdx = strlen(traceBuf);
-#endif
-                       orc = CONFREJ;
-                       break;
-               }
-               
-       endswitch:
-#if TRACELCP
-               if (traceNdx >= 80 - 32) {
-                       LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd%s\n", traceBuf));
-                       traceNdx = 0;
-               }
-#endif
-               if (orc == CONFACK &&           /* Good CI */
-                               rc != CONFACK)          /*  but prior CI wasnt? */
-                       continue;                       /* Don't send this one */
-               
-               if (orc == CONFNAK) {           /* Nak this CI? */
-                       if (reject_if_disagree  /* Getting fed up with sending NAKs? */
-                                       && citype != CI_MAGICNUMBER) {
-                               orc = CONFREJ;          /* Get tough if so */
-                       } 
-                       else {
-                               if (rc == CONFREJ)      /* Rejecting prior CI? */
-                                       continue;               /* Don't send this one */
-                               rc = CONFNAK;
-                       }
-               }
-               if (orc == CONFREJ) {           /* Reject this CI */
-                       rc = CONFREJ;
-                       if (cip != rejp)                /* Need to move rejected CI? */
-                               BCOPY(cip, rejp, cilen); /* Move it */
-                       INCPTR(cilen, rejp);    /* Update output pointer */
-               }
-       }
-       
-       /*
-        * If we wanted to send additional NAKs (for unsent CIs), the
-        * code would go here.  The extra NAKs would go at *nakp.
-        * At present there are no cases where we want to ask the
-        * peer to negotiate an option.
-        */
-       
-       switch (rc) {
-       case CONFACK:
-               *lenp = (int)(next - inp);
-               break;
-       case CONFNAK:
-               /*
-                * Copy the Nak'd options from the nak_buffer to the caller's buffer.
-                */
-               *lenp = (int)(nakp - nak_buffer);
-               BCOPY(nak_buffer, inp, *lenp);
-               break;
-       case CONFREJ:
-               *lenp = (int)(rejp - inp);
-               break;
-       }
-       
-#if TRACELCP > 0
-       if (traceNdx > 0) {
-               LCPDEBUG((LOG_INFO, "lcp_reqci: %s\n", traceBuf));
-       }
-#endif
-       LCPDEBUG((LOG_INFO, "lcp_reqci: returning CONF%s.\n", CODENAME(rc)));
-       return (rc);                    /* Return final code */
-}
-
-
-/*
- * lcp_up - LCP has come UP.
- */
-static void lcp_up(fsm *f)
-{
-       lcp_options *wo = &lcp_wantoptions[f->unit];
-       lcp_options *ho = &lcp_hisoptions[f->unit];
-       lcp_options *go = &lcp_gotoptions[f->unit];
-       lcp_options *ao = &lcp_allowoptions[f->unit];
-       
-       if (!go->neg_magicnumber)
-               go->magicnumber = 0;
-       if (!ho->neg_magicnumber)
-               ho->magicnumber = 0;
-       
-       /*
-       * Set our MTU to the smaller of the MTU we wanted and
-       * the MRU our peer wanted.  If we negotiated an MRU,
-       * set our MRU to the larger of value we wanted and
-       * the value we got in the negotiation.
-       */
-       ppp_send_config(f->unit, LWIP_MIN(ao->mru, (ho->neg_mru? ho->mru: PPP_MRU)),
-                               (ho->neg_asyncmap? ho->asyncmap: 0xffffffffl),
-                               ho->neg_pcompression, ho->neg_accompression);
-       /*
-       * If the asyncmap hasn't been negotiated, we really should
-       * set the receive asyncmap to ffffffff, but we set it to 0
-       * for backwards contemptibility.
-       */
-       ppp_recv_config(f->unit, (go->neg_mru? LWIP_MAX(wo->mru, go->mru): PPP_MRU),
-                               (go->neg_asyncmap? go->asyncmap: 0x00000000),
-                               go->neg_pcompression, go->neg_accompression);
-       
-       if (ho->neg_mru)
-               peer_mru[f->unit] = ho->mru;
-       
-       lcp_echo_lowerup(f->unit);  /* Enable echo messages */
-       
-       link_established(f->unit);
-}
-
-
-/*
- * lcp_down - LCP has gone DOWN.
- *
- * Alert other protocols.
- */
-static void lcp_down(fsm *f)
-{
-       lcp_options *go = &lcp_gotoptions[f->unit];
-       
-       lcp_echo_lowerdown(f->unit);
-       
-       link_down(f->unit);
-       
-       ppp_send_config(f->unit, PPP_MRU, 0xffffffffl, 0, 0);
-       ppp_recv_config(f->unit, PPP_MRU,
-                               (go->neg_asyncmap? go->asyncmap: 0x00000000),
-                               go->neg_pcompression, go->neg_accompression);
-       peer_mru[f->unit] = PPP_MRU;
-}
-
-
-/*
- * lcp_starting - LCP needs the lower layer up.
- */
-static void lcp_starting(fsm *f)
-{
-       link_required(f->unit);
-}
-
-
-/*
- * lcp_finished - LCP has finished with the lower layer.
- */
-static void lcp_finished(fsm *f)
-{
-       link_terminated(f->unit);
-}
-
-
-#if 0
-/*
- * print_string - print a readable representation of a string using
- * printer.
- */
-static void print_string(
-    char *p,
-    int len,
-    void (*printer) (void *, char *, ...),
-    void *arg
-)
-{
-    int c;
-    
-    printer(arg, "\"");
-    for (; len > 0; --len) {
-        c = *p++;
-        if (' ' <= c && c <= '~') {
-            if (c == '\\' || c == '"')
-                printer(arg, "\\");
-            printer(arg, "%c", c);
-        } else {
-            switch (c) {
-            case '\n':
-                printer(arg, "\\n");
-                break;
-            case '\r':
-                printer(arg, "\\r");
-                break;
-            case '\t':
-                printer(arg, "\\t");
-                break;
-            default:
-                printer(arg, "\\%.3o", c);
-            }
-        }
-    }
-    printer(arg, "\"");
-}
-
-
-/*
- * lcp_printpkt - print the contents of an LCP packet.
- */
-static char *lcp_codenames[] = {
-       "ConfReq", "ConfAck", "ConfNak", "ConfRej",
-       "TermReq", "TermAck", "CodeRej", "ProtRej",
-       "EchoReq", "EchoRep", "DiscReq"
-};
-
-static int lcp_printpkt(
-       u_char *p,
-       int plen,
-       void (*printer) (void *, char *, ...),
-       void *arg
-)
-{
-       int code, id, len, olen;
-       u_char *pstart, *optend;
-       u_short cishort;
-       u32_t cilong;
-       
-       if (plen < HEADERLEN)
-               return 0;
-       pstart = p;
-       GETCHAR(code, p);
-       GETCHAR(id, p);
-       GETSHORT(len, p);
-       if (len < HEADERLEN || len > plen)
-               return 0;
-       
-       if (code >= 1 && code <= sizeof(lcp_codenames) / sizeof(char *))
-               printer(arg, " %s", lcp_codenames[code-1]);
-       else
-               printer(arg, " code=0x%x", code);
-       printer(arg, " id=0x%x", id);
-       len -= HEADERLEN;
-       switch (code) {
-       case CONFREQ:
-       case CONFACK:
-       case CONFNAK:
-       case CONFREJ:
-               /* print option list */
-               while (len >= 2) {
-                       GETCHAR(code, p);
-                       GETCHAR(olen, p);
-                       p -= 2;
-                       if (olen < 2 || olen > len) {
-                               break;
-                       }
-                       printer(arg, " <");
-                       len -= olen;
-                       optend = p + olen;
-                       switch (code) {
-                       case CI_MRU:
-                               if (olen == CILEN_SHORT) {
-                                       p += 2;
-                                       GETSHORT(cishort, p);
-                                       printer(arg, "mru %d", cishort);
-                               }
-                               break;
-                       case CI_ASYNCMAP:
-                               if (olen == CILEN_LONG) {
-                                       p += 2;
-                                       GETLONG(cilong, p);
-                                       printer(arg, "asyncmap 0x%lx", cilong);
-                               }
-                               break;
-                       case CI_AUTHTYPE:
-                               if (olen >= CILEN_SHORT) {
-                                       p += 2;
-                                       printer(arg, "auth ");
-                                       GETSHORT(cishort, p);
-                                       switch (cishort) {
-                                       case PPP_PAP:
-                                               printer(arg, "pap");
-                                               break;
-                                       case PPP_CHAP:
-                                               printer(arg, "chap");
-                                               break;
-                                       default:
-                                               printer(arg, "0x%x", cishort);
-                                       }
-                               }
-                               break;
-                       case CI_QUALITY:
-                               if (olen >= CILEN_SHORT) {
-                                       p += 2;
-                                       printer(arg, "quality ");
-                                       GETSHORT(cishort, p);
-                                       switch (cishort) {
-                                       case PPP_LQR:
-                                               printer(arg, "lqr");
-                                               break;
-                                       default:
-                                               printer(arg, "0x%x", cishort);
-                                       }
-                               }
-                               break;
-                       case CI_CALLBACK:
-                               if (olen >= CILEN_CHAR) {
-                                       p += 2;
-                                       printer(arg, "callback ");
-                                       GETSHORT(cishort, p);
-                                       switch (cishort) {
-                                       case CBCP_OPT:
-                                               printer(arg, "CBCP");
-                                               break;
-                                       default:
-                                               printer(arg, "0x%x", cishort);
-                                       }
-                               }
-                               break;
-                       case CI_MAGICNUMBER:
-                               if (olen == CILEN_LONG) {
-                                       p += 2;
-                                       GETLONG(cilong, p);
-                                       printer(arg, "magic 0x%x", cilong);
-                               }
-                               break;
-                       case CI_PCOMPRESSION:
-                               if (olen == CILEN_VOID) {
-                                       p += 2;
-                                       printer(arg, "pcomp");
-                               }
-                               break;
-                       case CI_ACCOMPRESSION:
-                               if (olen == CILEN_VOID) {
-                                       p += 2;
-                                       printer(arg, "accomp");
-                               }
-                               break;
-                       }
-                       while (p < optend) {
-                               GETCHAR(code, p);
-                               printer(arg, " %.2x", code);
-                       }
-                       printer(arg, ">");
-               }
-               break;
-       
-       case TERMACK:
-       case TERMREQ:
-               if (len > 0 && *p >= ' ' && *p < 0x7f) {
-                       printer(arg, " ");
-                       print_string((char*)p, len, printer, arg);
-                       p += len;
-                       len = 0;
-               }
-               break;
-       
-       case ECHOREQ:
-       case ECHOREP:
-       case DISCREQ:
-               if (len >= 4) {
-                       GETLONG(cilong, p);
-                       printer(arg, " magic=0x%x", cilong);
-                       p += 4;
-                       len -= 4;
-               }
-               break;
-       }
-       
-       /* print the rest of the bytes in the packet */
-       for (; len > 0; --len) {
-               GETCHAR(code, p);
-               printer(arg, " %.2x", code);
-       }
-       
-       return (int)(p - pstart);
-}
-#endif
-
-/*
- * Time to shut down the link because there is nothing out there.
- */
-
-static void LcpLinkFailure (fsm *f)
-{
-       if (f->state == OPENED) {
-               LCPDEBUG((LOG_INFO, "No response to %d echo-requests\n", lcp_echos_pending));
-               LCPDEBUG((LOG_NOTICE, "Serial link appears to be disconnected.\n"));
-               lcp_close(f->unit, "Peer not responding");
-       }
-}
-
-/*
- * Timer expired for the LCP echo requests from this process.
- */
-
-static void LcpEchoCheck (fsm *f)
-{
-       LcpSendEchoRequest (f);
-       
-       /*
-        * Start the timer for the next interval.
-        */
-       LWIP_ASSERT("lcp_echo_timer_running == 0", lcp_echo_timer_running == 0);
-
-       TIMEOUT (LcpEchoTimeout, f, lcp_echo_interval);
-       lcp_echo_timer_running = 1;
-}
-
-/*
- * LcpEchoTimeout - Timer expired on the LCP echo
- */
-
-static void LcpEchoTimeout (void *arg)
-{
-       if (lcp_echo_timer_running != 0) {
-               lcp_echo_timer_running = 0;
-               LcpEchoCheck ((fsm *) arg);
-       }
-}
-
-/*
- * LcpEchoReply - LCP has received a reply to the echo
- */
-static void lcp_received_echo_reply (fsm *f, int id, u_char *inp, int len)
-{
-       u32_t magic;
-       
-       (void)id;
-
-       /* Check the magic number - don't count replies from ourselves. */
-       if (len < 4) {
-               LCPDEBUG((LOG_WARNING, "lcp: received short Echo-Reply, length %d\n", len));
-               return;
-       }
-       GETLONG(magic, inp);
-       if (lcp_gotoptions[f->unit].neg_magicnumber
-                       && magic == lcp_gotoptions[f->unit].magicnumber) {
-               LCPDEBUG((LOG_WARNING, "appear to have received our own echo-reply!\n"));
-               return;
-       }
-       
-       /* Reset the number of outstanding echo frames */
-       lcp_echos_pending = 0;
-}
-
-/*
- * LcpSendEchoRequest - Send an echo request frame to the peer
- */
-
-static void LcpSendEchoRequest (fsm *f)
-{
-       u32_t lcp_magic;
-       u_char pkt[4], *pktp;
-       
-       /*
-       * Detect the failure of the peer at this point.
-       */
-       if (lcp_echo_fails != 0) {
-               if (lcp_echos_pending++ >= lcp_echo_fails) {
-                       LcpLinkFailure(f);
-                       lcp_echos_pending = 0;
-               }
-       }
-       
-       /*
-       * Make and send the echo request frame.
-       */
-       if (f->state == OPENED) {
-               lcp_magic = lcp_gotoptions[f->unit].magicnumber;
-               pktp = pkt;
-               PUTLONG(lcp_magic, pktp);
-               fsm_sdata(f, ECHOREQ, (u_char)(lcp_echo_number++ & 0xFF), pkt, (int)(pktp - pkt));
-       }
-}
-
-/*
- * lcp_echo_lowerup - Start the timer for the LCP frame
- */
-
-static void lcp_echo_lowerup (int unit)
-{
-       fsm *f = &lcp_fsm[unit];
-       
-       /* Clear the parameters for generating echo frames */
-       lcp_echos_pending      = 0;
-       lcp_echo_number        = 0;
-       lcp_echo_timer_running = 0;
-       
-       /* If a timeout interval is specified then start the timer */
-       if (lcp_echo_interval != 0)
-               LcpEchoCheck (f);
-}
-
-/*
- * lcp_echo_lowerdown - Stop the timer for the LCP frame
- */
-
-static void lcp_echo_lowerdown (int unit)
-{
-       fsm *f = &lcp_fsm[unit];
-       
-       if (lcp_echo_timer_running != 0) {
-               UNTIMEOUT (LcpEchoTimeout, f);
-               lcp_echo_timer_running = 0;
-       }
-}
-
-#endif /* PPP_SUPPORT */
+/*****************************************************************************\r
+* lcp.c - Network Link Control Protocol program file.\r
+*\r
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.\r
+* portions Copyright (c) 1997 by Global Election Systems Inc.\r
+*\r
+* The authors hereby grant permission to use, copy, modify, distribute,\r
+* and license this software and its documentation for any purpose, provided\r
+* that existing copyright notices are retained in all copies and that this\r
+* notice and the following disclaimer are included verbatim in any \r
+* distributions. No written agreement, license, or royalty fee is required\r
+* for any of the authorized uses.\r
+*\r
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR\r
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+*\r
+******************************************************************************\r
+* REVISION HISTORY\r
+*\r
+* 03-01-01 Marc Boucher <marc@mbsi.ca>\r
+*   Ported to lwIP.\r
+* 97-12-01 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.\r
+*      Original.\r
+*****************************************************************************/\r
+\r
+/*\r
+ * lcp.c - PPP Link Control Protocol.\r
+ *\r
+ * Copyright (c) 1989 Carnegie Mellon University.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms are permitted\r
+ * provided that the above copyright notice and this paragraph are\r
+ * duplicated in all such forms and that any documentation,\r
+ * advertising materials, and other materials related to such\r
+ * distribution and use acknowledge that the software was developed\r
+ * by Carnegie Mellon University.  The name of the\r
+ * University may not be used to endorse or promote products derived\r
+ * from this software without specific prior written permission.\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR\r
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r
+ */\r
\r
+#include <string.h>\r
\r
+#include "ppp.h"\r
+#if PPP_SUPPORT > 0\r
+#include "fsm.h"\r
+#include "chap.h"\r
+#include "magic.h"\r
+#include "auth.h"\r
+#include "lcp.h"\r
+#include "pppdebug.h"\r
+\r
+\r
+/*************************/\r
+/*** LOCAL DEFINITIONS ***/\r
+/*************************/\r
+/*\r
+ * Length of each type of configuration option (in octets)\r
+ */\r
+#define CILEN_VOID     2\r
+#define CILEN_CHAR     3\r
+#define CILEN_SHORT    4       /* CILEN_VOID + sizeof(short) */\r
+#define CILEN_CHAP     5       /* CILEN_VOID + sizeof(short) + 1 */\r
+#define CILEN_LONG     6       /* CILEN_VOID + sizeof(long) */\r
+#define CILEN_LQR      8       /* CILEN_VOID + sizeof(short) + sizeof(long) */\r
+#define CILEN_CBCP     3\r
+\r
+\r
+/***********************************/\r
+/*** LOCAL FUNCTION DECLARATIONS ***/\r
+/***********************************/\r
+/*\r
+ * Callbacks for fsm code.  (CI = Configuration Information)\r
+ */\r
+static void lcp_resetci (fsm*);                /* Reset our CI */\r
+static int  lcp_cilen (fsm*);                  /* Return length of our CI */\r
+static void lcp_addci (fsm*, u_char*, int*);       /* Add our CI to pkt */\r
+static int  lcp_ackci (fsm*, u_char*, int);/* Peer ack'd our CI */\r
+static int  lcp_nakci (fsm*, u_char*, int);/* Peer nak'd our CI */\r
+static int  lcp_rejci (fsm*, u_char*, int);/* Peer rej'd our CI */\r
+static int  lcp_reqci (fsm*, u_char*, int*, int);  /* Rcv peer CI */\r
+static void lcp_up (fsm*);                         /* We're UP */\r
+static void lcp_down (fsm*);               /* We're DOWN */\r
+static void lcp_starting (fsm*);           /* We need lower layer up */\r
+static void lcp_finished (fsm*);               /* We need lower layer down */\r
+static int  lcp_extcode (fsm*, int, u_char, u_char*, int);\r
+\r
+static void lcp_rprotrej (fsm*, u_char*, int);\r
+\r
+/*\r
+ * routines to send LCP echos to peer\r
+ */\r
+static void lcp_echo_lowerup (int);\r
+static void lcp_echo_lowerdown (int);\r
+static void LcpEchoTimeout (void*);\r
+static void lcp_received_echo_reply (fsm*, int, u_char*, int);\r
+static void LcpSendEchoRequest (fsm*);\r
+static void LcpLinkFailure (fsm*);\r
+static void LcpEchoCheck (fsm*);\r
+\r
+/*\r
+ * Protocol entry points.\r
+ * Some of these are called directly.\r
+ */\r
+static void lcp_input (int, u_char *, int);\r
+static void lcp_protrej (int);\r
+\r
+#define CODENAME(x)    ((x) == CONFACK ? "ACK" : \\r
+                        (x) == CONFNAK ? "NAK" : "REJ")\r
+\r
+\r
+/******************************/\r
+/*** PUBLIC DATA STRUCTURES ***/\r
+/******************************/\r
+/* global vars */\r
+LinkPhase lcp_phase[NUM_PPP];                  /* Phase of link session (RFC 1661) */\r
+lcp_options lcp_wantoptions[NUM_PPP];  /* Options that we want to request */\r
+lcp_options lcp_gotoptions[NUM_PPP];   /* Options that peer ack'd */\r
+lcp_options lcp_allowoptions[NUM_PPP]; /* Options we allow peer to request */\r
+lcp_options lcp_hisoptions[NUM_PPP];   /* Options that we ack'd */\r
+ext_accm xmit_accm[NUM_PPP];                   /* extended transmit ACCM */\r
+\r
+\r
+\r
+/*****************************/\r
+/*** LOCAL DATA STRUCTURES ***/\r
+/*****************************/\r
+static fsm lcp_fsm[NUM_PPP];                   /* LCP fsm structure (global)*/\r
+static u_int    lcp_echo_interval = LCP_ECHOINTERVAL; /* Interval between LCP echo-requests */\r
+static u_int    lcp_echo_fails = LCP_MAXECHOFAILS; /* Tolerance to unanswered echo-requests */\r
+static u32_t lcp_echos_pending = 0;    /* Number of outstanding echo msgs */\r
+static u32_t lcp_echo_number   = 0;    /* ID number of next echo frame */\r
+static u32_t lcp_echo_timer_running = 0;  /* TRUE if a timer is running */\r
+\r
+static u_char nak_buffer[PPP_MRU];     /* where we construct a nak packet */\r
+\r
+static fsm_callbacks lcp_callbacks = { /* LCP callback routines */\r
+    lcp_resetci,               /* Reset our Configuration Information */\r
+    lcp_cilen,                 /* Length of our Configuration Information */\r
+    lcp_addci,                 /* Add our Configuration Information */\r
+    lcp_ackci,                 /* ACK our Configuration Information */\r
+    lcp_nakci,                 /* NAK our Configuration Information */\r
+    lcp_rejci,                 /* Reject our Configuration Information */\r
+    lcp_reqci,                 /* Request peer's Configuration Information */\r
+    lcp_up,                            /* Called when fsm reaches OPENED state */\r
+    lcp_down,                  /* Called when fsm leaves OPENED state */\r
+    lcp_starting,              /* Called when we want the lower layer up */\r
+    lcp_finished,              /* Called when we want the lower layer down */\r
+    NULL,                              /* Called when Protocol-Reject received */\r
+    NULL,                              /* Retransmission is necessary */\r
+    lcp_extcode,               /* Called to handle LCP-specific codes */\r
+    "LCP"                              /* String name of protocol */\r
+};\r
+\r
+struct protent lcp_protent = {\r
+    PPP_LCP,\r
+    lcp_init,\r
+    lcp_input,\r
+    lcp_protrej,\r
+    lcp_lowerup,\r
+    lcp_lowerdown,\r
+    lcp_open,\r
+    lcp_close,\r
+#if 0\r
+    lcp_printpkt,\r
+    NULL,\r
+#endif\r
+    1,\r
+    "LCP",\r
+#if 0\r
+    NULL,\r
+    NULL,\r
+    NULL\r
+#endif\r
+};\r
+\r
+int lcp_loopbackfail = DEFLOOPBACKFAIL;\r
+\r
+\r
+\r
+/***********************************/\r
+/*** PUBLIC FUNCTION DEFINITIONS ***/\r
+/***********************************/\r
+/*\r
+ * lcp_init - Initialize LCP.\r
+ */\r
+void lcp_init(int unit)\r
+{\r
+       fsm *f = &lcp_fsm[unit];\r
+       lcp_options *wo = &lcp_wantoptions[unit];\r
+       lcp_options *ao = &lcp_allowoptions[unit];\r
+       \r
+       f->unit = unit;\r
+       f->protocol = PPP_LCP;\r
+       f->callbacks = &lcp_callbacks;\r
+       \r
+       fsm_init(f);\r
+       \r
+       wo->passive = 0;\r
+       wo->silent = 0;\r
+       wo->restart = 0;                        /* Set to 1 in kernels or multi-line\r
+                                                                * implementations */\r
+       wo->neg_mru = 1;\r
+       wo->mru = PPP_DEFMRU;\r
+       wo->neg_asyncmap = 1;\r
+       wo->asyncmap = 0x00000000l;     /* Assume don't need to escape any ctl chars. */\r
+       wo->neg_chap = 0;                       /* Set to 1 on server */\r
+       wo->neg_upap = 0;                       /* Set to 1 on server */\r
+       wo->chap_mdtype = CHAP_DIGEST_MD5;\r
+       wo->neg_magicnumber = 1;\r
+       wo->neg_pcompression = 1;\r
+       wo->neg_accompression = 1;\r
+       wo->neg_lqr = 0;                        /* no LQR implementation yet */\r
+       wo->neg_cbcp = 0;\r
+       \r
+       ao->neg_mru = 1;\r
+       ao->mru = PPP_MAXMRU;\r
+       ao->neg_asyncmap = 1;\r
+       ao->asyncmap = 0x00000000l;     /* Assume don't need to escape any ctl chars. */\r
+       ao->neg_chap = (CHAP_SUPPORT != 0);\r
+       ao->chap_mdtype = CHAP_DIGEST_MD5;\r
+       ao->neg_upap = (PAP_SUPPORT != 0);\r
+       ao->neg_magicnumber = 1;\r
+       ao->neg_pcompression = 1;\r
+       ao->neg_accompression = 1;\r
+       ao->neg_lqr = 0;                        /* no LQR implementation yet */\r
+       ao->neg_cbcp = (CBCP_SUPPORT != 0);\r
+\r
+       /* \r
+        * Set transmit escape for the flag and escape characters plus anything\r
+        * set for the allowable options.\r
+        */\r
+       memset(xmit_accm[unit], 0, sizeof(xmit_accm[0]));\r
+       xmit_accm[unit][15] = 0x60;\r
+       xmit_accm[unit][0] = (u_char)(ao->asyncmap & 0xFF);\r
+       xmit_accm[unit][1] = (u_char)((ao->asyncmap >> 8) & 0xFF);\r
+       xmit_accm[unit][2] = (u_char)((ao->asyncmap >> 16) & 0xFF);\r
+       xmit_accm[unit][3] = (u_char)((ao->asyncmap >> 24) & 0xFF);\r
+       LCPDEBUG((LOG_INFO, "lcp_init: xmit_accm=%X %X %X %X\n",\r
+                               xmit_accm[unit][0],\r
+                               xmit_accm[unit][1],\r
+                               xmit_accm[unit][2],\r
+                               xmit_accm[unit][3]));\r
+       \r
+       lcp_phase[unit] = PHASE_INITIALIZE;\r
+}\r
+\r
+\r
+/*\r
+ * lcp_open - LCP is allowed to come up.\r
+ */\r
+void lcp_open(int unit)\r
+{\r
+       fsm *f = &lcp_fsm[unit];\r
+       lcp_options *wo = &lcp_wantoptions[unit];\r
+       \r
+       f->flags = 0;\r
+       if (wo->passive)\r
+               f->flags |= OPT_PASSIVE;\r
+       if (wo->silent)\r
+               f->flags |= OPT_SILENT;\r
+       fsm_open(f);\r
+       \r
+       lcp_phase[unit] = PHASE_ESTABLISH; \r
+}\r
+\r
+\r
+/*\r
+ * lcp_close - Take LCP down.\r
+ */\r
+void lcp_close(int unit, char *reason)\r
+{\r
+       fsm *f = &lcp_fsm[unit];\r
+       \r
+       if (lcp_phase[unit] != PHASE_DEAD)\r
+               lcp_phase[unit] = PHASE_TERMINATE;\r
+       if (f->state == STOPPED && f->flags & (OPT_PASSIVE|OPT_SILENT)) {\r
+               /*\r
+                * This action is not strictly according to the FSM in RFC1548,\r
+                * but it does mean that the program terminates if you do an\r
+                * lcp_close() in passive/silent mode when a connection hasn't\r
+                * been established.\r
+                */\r
+               f->state = CLOSED;\r
+               lcp_finished(f);\r
+       }\r
+       else\r
+               fsm_close(&lcp_fsm[unit], reason);\r
+}\r
+\r
+\r
+/*\r
+ * lcp_lowerup - The lower layer is up.\r
+ */\r
+void lcp_lowerup(int unit)\r
+{\r
+       lcp_options *wo = &lcp_wantoptions[unit];\r
+       \r
+       /*\r
+       * Don't use A/C or protocol compression on transmission,\r
+       * but accept A/C and protocol compressed packets\r
+       * if we are going to ask for A/C and protocol compression.\r
+       */\r
+       ppp_set_xaccm(unit, &xmit_accm[unit]);\r
+       ppp_send_config(unit, PPP_MRU, 0xffffffffl, 0, 0);\r
+       ppp_recv_config(unit, PPP_MRU, 0x00000000l,\r
+                                       wo->neg_pcompression, wo->neg_accompression);\r
+       peer_mru[unit] = PPP_MRU;\r
+       lcp_allowoptions[unit].asyncmap \r
+               = (u_long)xmit_accm[unit][0]\r
+                       | ((u_long)xmit_accm[unit][1] << 8)\r
+                       | ((u_long)xmit_accm[unit][2] << 16)\r
+                       | ((u_long)xmit_accm[unit][3] << 24);\r
+       LCPDEBUG((LOG_INFO, "lcp_lowerup: asyncmap=%X %X %X %X\n",\r
+                               xmit_accm[unit][3],\r
+                               xmit_accm[unit][2],\r
+                               xmit_accm[unit][1],\r
+                               xmit_accm[unit][0]));\r
+       \r
+       fsm_lowerup(&lcp_fsm[unit]);\r
+}\r
+\r
+\r
+/*\r
+ * lcp_lowerdown - The lower layer is down.\r
+ */\r
+void lcp_lowerdown(int unit)\r
+{\r
+       fsm_lowerdown(&lcp_fsm[unit]);\r
+}\r
+\r
+/*\r
+ * lcp_sprotrej - Send a Protocol-Reject for some protocol.\r
+ */\r
+void lcp_sprotrej(int unit, u_char *p, int len)\r
+{\r
+       /*\r
+       * Send back the protocol and the information field of the\r
+       * rejected packet.  We only get here if LCP is in the OPENED state.\r
+       */\r
+\r
+       fsm_sdata(&lcp_fsm[unit], PROTREJ, ++lcp_fsm[unit].id,\r
+                               p, len);\r
+}\r
+\r
+\r
+\r
+/**********************************/\r
+/*** LOCAL FUNCTION DEFINITIONS ***/\r
+/**********************************/\r
+/*\r
+ * lcp_input - Input LCP packet.\r
+ */\r
+static void lcp_input(int unit, u_char *p, int len)\r
+{\r
+       fsm *f = &lcp_fsm[unit];\r
+       \r
+       fsm_input(f, p, len);\r
+}\r
+\r
+\r
+/*\r
+ * lcp_extcode - Handle a LCP-specific code.\r
+ */\r
+static int lcp_extcode(fsm *f, int code, u_char id, u_char *inp, int len)\r
+{\r
+       u_char *magp;\r
+       \r
+       switch( code ){\r
+       case PROTREJ:\r
+               lcp_rprotrej(f, inp, len);\r
+               break;\r
+       \r
+       case ECHOREQ:\r
+               if (f->state != OPENED)\r
+                       break;\r
+               LCPDEBUG((LOG_INFO, "lcp: Echo-Request, Rcvd id %d\n", id));\r
+               magp = inp;\r
+               PUTLONG(lcp_gotoptions[f->unit].magicnumber, magp);\r
+               fsm_sdata(f, ECHOREP, id, inp, len);\r
+               break;\r
+       \r
+       case ECHOREP:\r
+               lcp_received_echo_reply(f, id, inp, len);\r
+               break;\r
+       \r
+       case DISCREQ:\r
+               break;\r
+       \r
+       default:\r
+               return 0;\r
+       }\r
+       return 1;\r
+}\r
+\r
+    \r
+/*\r
+ * lcp_rprotrej - Receive an Protocol-Reject.\r
+ *\r
+ * Figure out which protocol is rejected and inform it.\r
+ */\r
+static void lcp_rprotrej(fsm *f, u_char *inp, int len)\r
+{\r
+       int i;\r
+       struct protent *protp;\r
+       u_short prot;\r
+       \r
+       if (len < sizeof (u_short)) {\r
+               LCPDEBUG((LOG_INFO,\r
+                               "lcp_rprotrej: Rcvd short Protocol-Reject packet!\n"));\r
+               return;\r
+       }\r
+       \r
+       GETSHORT(prot, inp);\r
+       \r
+       LCPDEBUG((LOG_INFO,\r
+                       "lcp_rprotrej: Rcvd Protocol-Reject packet for %x!\n",\r
+                       prot));\r
+       \r
+       /*\r
+       * Protocol-Reject packets received in any state other than the LCP\r
+       * OPENED state SHOULD be silently discarded.\r
+       */\r
+       if( f->state != OPENED ){\r
+               LCPDEBUG((LOG_INFO, "Protocol-Reject discarded: LCP in state %d\n",\r
+                               f->state));\r
+               return;\r
+       }\r
+       \r
+       /*\r
+       * Upcall the proper Protocol-Reject routine.\r
+       */\r
+       for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i)\r
+               if (protp->protocol == prot && protp->enabled_flag) {\r
+                       (*protp->protrej)(f->unit);\r
+                       return;\r
+               }\r
+       \r
+       LCPDEBUG((LOG_WARNING, "Protocol-Reject for unsupported protocol 0x%x\n",\r
+                       prot));\r
+}\r
+\r
+\r
+/*\r
+ * lcp_protrej - A Protocol-Reject was received.\r
+ */\r
+static void lcp_protrej(int unit)\r
+{\r
+       (void)unit;\r
+       /*\r
+       * Can't reject LCP!\r
+       */\r
+       LCPDEBUG((LOG_WARNING,\r
+                       "lcp_protrej: Received Protocol-Reject for LCP!\n"));\r
+       fsm_protreject(&lcp_fsm[unit]);\r
+}\r
+\r
+\r
+/*\r
+ * lcp_resetci - Reset our CI.\r
+ */\r
+static void lcp_resetci(fsm *f)\r
+{\r
+       lcp_wantoptions[f->unit].magicnumber = magic();\r
+       lcp_wantoptions[f->unit].numloops = 0;\r
+       lcp_gotoptions[f->unit] = lcp_wantoptions[f->unit];\r
+       peer_mru[f->unit] = PPP_MRU;\r
+       auth_reset(f->unit);\r
+}\r
+\r
+\r
+/*\r
+ * lcp_cilen - Return length of our CI.\r
+ */\r
+static int lcp_cilen(fsm *f)\r
+{\r
+       lcp_options *go = &lcp_gotoptions[f->unit];\r
+\r
+#define LENCIVOID(neg) ((neg) ? CILEN_VOID : 0)\r
+#define LENCICHAP(neg) ((neg) ? CILEN_CHAP : 0)\r
+#define LENCISHORT(neg)        ((neg) ? CILEN_SHORT : 0)\r
+#define LENCILONG(neg) ((neg) ? CILEN_LONG : 0)\r
+#define LENCILQR(neg)  ((neg) ? CILEN_LQR: 0)\r
+#define LENCICBCP(neg) ((neg) ? CILEN_CBCP: 0)\r
+       /*\r
+       * NB: we only ask for one of CHAP and UPAP, even if we will\r
+       * accept either.\r
+       */\r
+       return (LENCISHORT(go->neg_mru && go->mru != PPP_DEFMRU) +\r
+               LENCILONG(go->neg_asyncmap && go->asyncmap != 0xFFFFFFFFl) +\r
+               LENCICHAP(go->neg_chap) +\r
+               LENCISHORT(!go->neg_chap && go->neg_upap) +\r
+               LENCILQR(go->neg_lqr) +\r
+               LENCICBCP(go->neg_cbcp) +\r
+               LENCILONG(go->neg_magicnumber) +\r
+               LENCIVOID(go->neg_pcompression) +\r
+               LENCIVOID(go->neg_accompression));\r
+}\r
+\r
+\r
+/*\r
+ * lcp_addci - Add our desired CIs to a packet.\r
+ */\r
+static void lcp_addci(fsm *f, u_char *ucp, int *lenp)\r
+{\r
+       lcp_options *go = &lcp_gotoptions[f->unit];\r
+       u_char *start_ucp = ucp;\r
+       \r
+#define ADDCIVOID(opt, neg) \\r
+       if (neg) { \\r
+           LCPDEBUG((LOG_INFO, "lcp_addci: opt=%d\n", opt)); \\r
+               PUTCHAR(opt, ucp); \\r
+               PUTCHAR(CILEN_VOID, ucp); \\r
+       }\r
+#define ADDCISHORT(opt, neg, val) \\r
+       if (neg) { \\r
+           LCPDEBUG((LOG_INFO, "lcp_addci: INT opt=%d %X\n", opt, val)); \\r
+               PUTCHAR(opt, ucp); \\r
+               PUTCHAR(CILEN_SHORT, ucp); \\r
+               PUTSHORT(val, ucp); \\r
+       }\r
+#define ADDCICHAP(opt, neg, val, digest) \\r
+       if (neg) { \\r
+           LCPDEBUG((LOG_INFO, "lcp_addci: CHAP opt=%d %X\n", opt, val)); \\r
+               PUTCHAR(opt, ucp); \\r
+               PUTCHAR(CILEN_CHAP, ucp); \\r
+               PUTSHORT(val, ucp); \\r
+               PUTCHAR(digest, ucp); \\r
+       }\r
+#define ADDCILONG(opt, neg, val) \\r
+       if (neg) { \\r
+           LCPDEBUG((LOG_INFO, "lcp_addci: L opt=%d %lX\n", opt, val)); \\r
+               PUTCHAR(opt, ucp); \\r
+               PUTCHAR(CILEN_LONG, ucp); \\r
+               PUTLONG(val, ucp); \\r
+       }\r
+#define ADDCILQR(opt, neg, val) \\r
+       if (neg) { \\r
+           LCPDEBUG((LOG_INFO, "lcp_addci: LQR opt=%d %lX\n", opt, val)); \\r
+               PUTCHAR(opt, ucp); \\r
+               PUTCHAR(CILEN_LQR, ucp); \\r
+               PUTSHORT(PPP_LQR, ucp); \\r
+               PUTLONG(val, ucp); \\r
+       }\r
+#define ADDCICHAR(opt, neg, val) \\r
+       if (neg) { \\r
+           LCPDEBUG((LOG_INFO, "lcp_addci: CHAR opt=%d %X '%z'\n", opt, val, val)); \\r
+               PUTCHAR(opt, ucp); \\r
+               PUTCHAR(CILEN_CHAR, ucp); \\r
+               PUTCHAR(val, ucp); \\r
+       }\r
+       \r
+       ADDCISHORT(CI_MRU, go->neg_mru && go->mru != PPP_DEFMRU, go->mru);\r
+       ADDCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFFl,\r
+                       go->asyncmap);\r
+       ADDCICHAP(CI_AUTHTYPE, go->neg_chap, PPP_CHAP, go->chap_mdtype);\r
+       ADDCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, PPP_PAP);\r
+       ADDCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period);\r
+       ADDCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT);\r
+       ADDCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber);\r
+       ADDCIVOID(CI_PCOMPRESSION, go->neg_pcompression);\r
+       ADDCIVOID(CI_ACCOMPRESSION, go->neg_accompression);\r
+       \r
+       if (ucp - start_ucp != *lenp) {\r
+               /* this should never happen, because peer_mtu should be 1500 */\r
+               LCPDEBUG((LOG_ERR, "Bug in lcp_addci: wrong length\n"));\r
+       }\r
+}\r
+\r
+\r
+/*\r
+ * lcp_ackci - Ack our CIs.\r
+ * This should not modify any state if the Ack is bad.\r
+ *\r
+ * Returns:\r
+ *     0 - Ack was bad.\r
+ *     1 - Ack was good.\r
+ */\r
+static int lcp_ackci(fsm *f, u_char *p, int len)\r
+{\r
+       lcp_options *go = &lcp_gotoptions[f->unit];\r
+       u_char cilen, citype, cichar;\r
+       u_short cishort;\r
+       u32_t cilong;\r
+       \r
+       /*\r
+       * CIs must be in exactly the same order that we sent.\r
+       * Check packet length and CI length at each step.\r
+       * If we find any deviations, then this packet is bad.\r
+       */\r
+#define ACKCIVOID(opt, neg) \\r
+       if (neg) { \\r
+               if ((len -= CILEN_VOID) < 0) \\r
+                       goto bad; \\r
+               GETCHAR(citype, p); \\r
+               GETCHAR(cilen, p); \\r
+               if (cilen != CILEN_VOID || \\r
+                               citype != opt) \\r
+                       goto bad; \\r
+       }\r
+#define ACKCISHORT(opt, neg, val) \\r
+       if (neg) { \\r
+               if ((len -= CILEN_SHORT) < 0) \\r
+                       goto bad; \\r
+               GETCHAR(citype, p); \\r
+               GETCHAR(cilen, p); \\r
+               if (cilen != CILEN_SHORT || \\r
+                               citype != opt) \\r
+                       goto bad; \\r
+               GETSHORT(cishort, p); \\r
+               if (cishort != val) \\r
+                       goto bad; \\r
+       }\r
+#define ACKCICHAR(opt, neg, val) \\r
+       if (neg) { \\r
+               if ((len -= CILEN_CHAR) < 0) \\r
+                       goto bad; \\r
+               GETCHAR(citype, p); \\r
+               GETCHAR(cilen, p); \\r
+               if (cilen != CILEN_CHAR || \\r
+                               citype != opt) \\r
+                       goto bad; \\r
+               GETCHAR(cichar, p); \\r
+               if (cichar != val) \\r
+                       goto bad; \\r
+       }\r
+#define ACKCICHAP(opt, neg, val, digest) \\r
+       if (neg) { \\r
+               if ((len -= CILEN_CHAP) < 0) \\r
+                       goto bad; \\r
+               GETCHAR(citype, p); \\r
+               GETCHAR(cilen, p); \\r
+               if (cilen != CILEN_CHAP || \\r
+                               citype != opt) \\r
+                       goto bad; \\r
+               GETSHORT(cishort, p); \\r
+               if (cishort != val) \\r
+                       goto bad; \\r
+               GETCHAR(cichar, p); \\r
+               if (cichar != digest) \\r
+                       goto bad; \\r
+       }\r
+#define ACKCILONG(opt, neg, val) \\r
+       if (neg) { \\r
+               if ((len -= CILEN_LONG) < 0) \\r
+                       goto bad; \\r
+               GETCHAR(citype, p); \\r
+               GETCHAR(cilen, p); \\r
+               if (cilen != CILEN_LONG || \\r
+                               citype != opt) \\r
+                       goto bad; \\r
+               GETLONG(cilong, p); \\r
+               if (cilong != val) \\r
+                       goto bad; \\r
+       }\r
+#define ACKCILQR(opt, neg, val) \\r
+       if (neg) { \\r
+               if ((len -= CILEN_LQR) < 0) \\r
+                       goto bad; \\r
+               GETCHAR(citype, p); \\r
+               GETCHAR(cilen, p); \\r
+               if (cilen != CILEN_LQR || \\r
+                               citype != opt) \\r
+                       goto bad; \\r
+               GETSHORT(cishort, p); \\r
+               if (cishort != PPP_LQR) \\r
+                       goto bad; \\r
+               GETLONG(cilong, p); \\r
+               if (cilong != val) \\r
+                       goto bad; \\r
+       }\r
+       \r
+       ACKCISHORT(CI_MRU, go->neg_mru && go->mru != PPP_DEFMRU, go->mru);\r
+       ACKCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFFl,\r
+                       go->asyncmap);\r
+       ACKCICHAP(CI_AUTHTYPE, go->neg_chap, PPP_CHAP, go->chap_mdtype);\r
+       ACKCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, PPP_PAP);\r
+       ACKCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period);\r
+       ACKCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT);\r
+       ACKCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber);\r
+       ACKCIVOID(CI_PCOMPRESSION, go->neg_pcompression);\r
+       ACKCIVOID(CI_ACCOMPRESSION, go->neg_accompression);\r
+       \r
+       /*\r
+        * If there are any remaining CIs, then this packet is bad.\r
+        */\r
+       if (len != 0)\r
+               goto bad;\r
+       LCPDEBUG((LOG_INFO, "lcp_acki: Ack\n"));\r
+       return (1);\r
+bad:\r
+       LCPDEBUG((LOG_WARNING, "lcp_acki: received bad Ack!\n"));\r
+       return (0);\r
+}\r
+\r
+\r
+/*\r
+ * lcp_nakci - Peer has sent a NAK for some of our CIs.\r
+ * This should not modify any state if the Nak is bad\r
+ * or if LCP is in the OPENED state.\r
+ *\r
+ * Returns:\r
+ *     0 - Nak was bad.\r
+ *     1 - Nak was good.\r
+ */\r
+static int lcp_nakci(fsm *f, u_char *p, int len)\r
+{\r
+       lcp_options *go = &lcp_gotoptions[f->unit];\r
+       lcp_options *wo = &lcp_wantoptions[f->unit];\r
+       u_char citype, cichar, *next;\r
+       u_short cishort;\r
+       u32_t cilong;\r
+       lcp_options no;         /* options we've seen Naks for */\r
+       lcp_options try;                /* options to request next time */\r
+       int looped_back = 0;\r
+       int cilen;\r
+       \r
+       BZERO(&no, sizeof(no));\r
+       try = *go;\r
+       \r
+       /*\r
+       * Any Nak'd CIs must be in exactly the same order that we sent.\r
+       * Check packet length and CI length at each step.\r
+       * If we find any deviations, then this packet is bad.\r
+       */\r
+#define NAKCIVOID(opt, neg, code) \\r
+       if (go->neg && \\r
+                       len >= CILEN_VOID && \\r
+                       p[1] == CILEN_VOID && \\r
+                       p[0] == opt) { \\r
+               len -= CILEN_VOID; \\r
+               INCPTR(CILEN_VOID, p); \\r
+               no.neg = 1; \\r
+               code \\r
+       }\r
+#define NAKCICHAP(opt, neg, code) \\r
+       if (go->neg && \\r
+                       len >= CILEN_CHAP && \\r
+                       p[1] == CILEN_CHAP && \\r
+                       p[0] == opt) { \\r
+               len -= CILEN_CHAP; \\r
+               INCPTR(2, p); \\r
+               GETSHORT(cishort, p); \\r
+               GETCHAR(cichar, p); \\r
+               no.neg = 1; \\r
+               code \\r
+       }\r
+#define NAKCICHAR(opt, neg, code) \\r
+       if (go->neg && \\r
+                       len >= CILEN_CHAR && \\r
+                       p[1] == CILEN_CHAR && \\r
+                       p[0] == opt) { \\r
+               len -= CILEN_CHAR; \\r
+               INCPTR(2, p); \\r
+               GETCHAR(cichar, p); \\r
+               no.neg = 1; \\r
+               code \\r
+       }\r
+#define NAKCISHORT(opt, neg, code) \\r
+       if (go->neg && \\r
+                       len >= CILEN_SHORT && \\r
+                       p[1] == CILEN_SHORT && \\r
+                       p[0] == opt) { \\r
+               len -= CILEN_SHORT; \\r
+               INCPTR(2, p); \\r
+               GETSHORT(cishort, p); \\r
+               no.neg = 1; \\r
+               code \\r
+       }\r
+#define NAKCILONG(opt, neg, code) \\r
+       if (go->neg && \\r
+                       len >= CILEN_LONG && \\r
+                       p[1] == CILEN_LONG && \\r
+                       p[0] == opt) { \\r
+               len -= CILEN_LONG; \\r
+               INCPTR(2, p); \\r
+               GETLONG(cilong, p); \\r
+               no.neg = 1; \\r
+               code \\r
+       }\r
+#define NAKCILQR(opt, neg, code) \\r
+       if (go->neg && \\r
+                       len >= CILEN_LQR && \\r
+                       p[1] == CILEN_LQR && \\r
+                       p[0] == opt) { \\r
+               len -= CILEN_LQR; \\r
+               INCPTR(2, p); \\r
+               GETSHORT(cishort, p); \\r
+               GETLONG(cilong, p); \\r
+               no.neg = 1; \\r
+               code \\r
+       }\r
+       \r
+       /*\r
+       * We don't care if they want to send us smaller packets than\r
+       * we want.  Therefore, accept any MRU less than what we asked for,\r
+       * but then ignore the new value when setting the MRU in the kernel.\r
+       * If they send us a bigger MRU than what we asked, accept it, up to\r
+       * the limit of the default MRU we'd get if we didn't negotiate.\r
+       */\r
+       if (go->neg_mru && go->mru != PPP_DEFMRU) {\r
+               NAKCISHORT(CI_MRU, neg_mru,\r
+                       if (cishort <= wo->mru || cishort < PPP_DEFMRU)\r
+                               try.mru = cishort;\r
+               );\r
+       }\r
+       \r
+       /*\r
+       * Add any characters they want to our (receive-side) asyncmap.\r
+       */\r
+       if (go->neg_asyncmap && go->asyncmap != 0xFFFFFFFFl) {\r
+               NAKCILONG(CI_ASYNCMAP, neg_asyncmap,\r
+                       try.asyncmap = go->asyncmap | cilong;\r
+               );\r
+       }\r
+       \r
+       /*\r
+       * If they've nak'd our authentication-protocol, check whether\r
+       * they are proposing a different protocol, or a different\r
+       * hash algorithm for CHAP.\r
+       */\r
+       if ((go->neg_chap || go->neg_upap)\r
+                       && len >= CILEN_SHORT\r
+                       && p[0] == CI_AUTHTYPE && p[1] >= CILEN_SHORT && p[1] <= len) {\r
+               cilen = p[1];\r
+       len -= cilen;\r
+       no.neg_chap = go->neg_chap;\r
+       no.neg_upap = go->neg_upap;\r
+       INCPTR(2, p);\r
+       GETSHORT(cishort, p);\r
+       if (cishort == PPP_PAP && cilen == CILEN_SHORT) {\r
+               /*\r
+                * If we were asking for CHAP, they obviously don't want to do it.\r
+                * If we weren't asking for CHAP, then we were asking for PAP,\r
+                * in which case this Nak is bad.\r
+                */\r
+               if (!go->neg_chap)\r
+                       goto bad;\r
+               try.neg_chap = 0;\r
+       \r
+       } else if (cishort == PPP_CHAP && cilen == CILEN_CHAP) {\r
+               GETCHAR(cichar, p);\r
+               if (go->neg_chap) {\r
+                       /*\r
+                        * We were asking for CHAP/MD5; they must want a different\r
+                        * algorithm.  If they can't do MD5, we'll have to stop\r
+                        * asking for CHAP.\r
+                        */\r
+                       if (cichar != go->chap_mdtype)\r
+                               try.neg_chap = 0;\r
+               } else {\r
+                       /*\r
+                        * Stop asking for PAP if we were asking for it.\r
+                        */\r
+                       try.neg_upap = 0;\r
+               }\r
+       \r
+       } else {\r
+               /*\r
+                * We don't recognize what they're suggesting.\r
+                * Stop asking for what we were asking for.\r
+                */\r
+               if (go->neg_chap)\r
+                       try.neg_chap = 0;\r
+               else\r
+                       try.neg_upap = 0;\r
+               p += cilen - CILEN_SHORT;\r
+       }\r
+       }\r
+       \r
+       /*\r
+       * If they can't cope with our link quality protocol, we'll have\r
+       * to stop asking for LQR.  We haven't got any other protocol.\r
+       * If they Nak the reporting period, take their value XXX ?\r
+       */\r
+       NAKCILQR(CI_QUALITY, neg_lqr,\r
+               if (cishort != PPP_LQR)\r
+                       try.neg_lqr = 0;\r
+               else\r
+                       try.lqr_period = cilong;\r
+       );\r
+       \r
+       /*\r
+       * Only implementing CBCP...not the rest of the callback options\r
+       */\r
+       NAKCICHAR(CI_CALLBACK, neg_cbcp,\r
+               try.neg_cbcp = 0;\r
+       );\r
+       \r
+       /*\r
+       * Check for a looped-back line.\r
+       */\r
+       NAKCILONG(CI_MAGICNUMBER, neg_magicnumber,\r
+               try.magicnumber = magic();\r
+               looped_back = 1;\r
+       );\r
+       \r
+       /*\r
+       * Peer shouldn't send Nak for protocol compression or\r
+       * address/control compression requests; they should send\r
+       * a Reject instead.  If they send a Nak, treat it as a Reject.\r
+       */\r
+       NAKCIVOID(CI_PCOMPRESSION, neg_pcompression,\r
+               try.neg_pcompression = 0;\r
+       );\r
+       NAKCIVOID(CI_ACCOMPRESSION, neg_accompression,\r
+               try.neg_accompression = 0;\r
+       );\r
+       \r
+       /*\r
+       * There may be remaining CIs, if the peer is requesting negotiation\r
+       * on an option that we didn't include in our request packet.\r
+       * If we see an option that we requested, or one we've already seen\r
+       * in this packet, then this packet is bad.\r
+       * If we wanted to respond by starting to negotiate on the requested\r
+       * option(s), we could, but we don't, because except for the\r
+       * authentication type and quality protocol, if we are not negotiating\r
+       * an option, it is because we were told not to.\r
+       * For the authentication type, the Nak from the peer means\r
+       * `let me authenticate myself with you' which is a bit pointless.\r
+       * For the quality protocol, the Nak means `ask me to send you quality\r
+       * reports', but if we didn't ask for them, we don't want them.\r
+       * An option we don't recognize represents the peer asking to\r
+       * negotiate some option we don't support, so ignore it.\r
+       */\r
+       while (len > CILEN_VOID) {\r
+               GETCHAR(citype, p);\r
+               GETCHAR(cilen, p);\r
+               if (cilen < CILEN_VOID || (len -= cilen) < 0)\r
+                       goto bad;\r
+               next = p + cilen - 2;\r
+               \r
+               switch (citype) {\r
+               case CI_MRU:\r
+                       if ((go->neg_mru && go->mru != PPP_DEFMRU)\r
+                                       || no.neg_mru || cilen != CILEN_SHORT)\r
+                               goto bad;\r
+                       GETSHORT(cishort, p);\r
+                       if (cishort < PPP_DEFMRU)\r
+                               try.mru = cishort;\r
+                       break;\r
+               case CI_ASYNCMAP:\r
+                       if ((go->neg_asyncmap && go->asyncmap != 0xFFFFFFFFl)\r
+                                       || no.neg_asyncmap || cilen != CILEN_LONG)\r
+                               goto bad;\r
+                       break;\r
+               case CI_AUTHTYPE:\r
+                       if (go->neg_chap || no.neg_chap || go->neg_upap || no.neg_upap)\r
+                               goto bad;\r
+                       break;\r
+               case CI_MAGICNUMBER:\r
+                       if (go->neg_magicnumber || no.neg_magicnumber ||\r
+                                       cilen != CILEN_LONG)\r
+                               goto bad;\r
+                       break;\r
+               case CI_PCOMPRESSION:\r
+                       if (go->neg_pcompression || no.neg_pcompression\r
+                                       || cilen != CILEN_VOID)\r
+                               goto bad;\r
+                       break;\r
+               case CI_ACCOMPRESSION:\r
+                       if (go->neg_accompression || no.neg_accompression\r
+                                       || cilen != CILEN_VOID)\r
+                               goto bad;\r
+                       break;\r
+               case CI_QUALITY:\r
+                       if (go->neg_lqr || no.neg_lqr || cilen != CILEN_LQR)\r
+                               goto bad;\r
+                       break;\r
+               }\r
+               p = next;\r
+       }\r
+       \r
+       /* If there is still anything left, this packet is bad. */\r
+       if (len != 0)\r
+               goto bad;\r
+       \r
+       /*\r
+       * OK, the Nak is good.  Now we can update state.\r
+       */\r
+       if (f->state != OPENED) {\r
+               if (looped_back) {\r
+                       if (++try.numloops >= lcp_loopbackfail) {\r
+                               LCPDEBUG((LOG_NOTICE, "Serial line is looped back.\n"));\r
+                               lcp_close(f->unit, "Loopback detected");\r
+                       }\r
+               } \r
+               else\r
+                       try.numloops = 0;\r
+               *go = try;\r
+       }\r
+       \r
+       return 1;\r
+       \r
+bad:\r
+       LCPDEBUG((LOG_WARNING, "lcp_nakci: received bad Nak!\n"));\r
+       return 0;\r
+}\r
+\r
+\r
+/*\r
+ * lcp_rejci - Peer has Rejected some of our CIs.\r
+ * This should not modify any state if the Reject is bad\r
+ * or if LCP is in the OPENED state.\r
+ *\r
+ * Returns:\r
+ *     0 - Reject was bad.\r
+ *     1 - Reject was good.\r
+ */\r
+static int lcp_rejci(fsm *f, u_char *p, int len)\r
+{\r
+       lcp_options *go = &lcp_gotoptions[f->unit];\r
+       u_char cichar;\r
+       u_short cishort;\r
+       u32_t cilong;\r
+       lcp_options try;                /* options to request next time */\r
+       \r
+       try = *go;\r
+       \r
+       /*\r
+       * Any Rejected CIs must be in exactly the same order that we sent.\r
+       * Check packet length and CI length at each step.\r
+       * If we find any deviations, then this packet is bad.\r
+       */\r
+#define REJCIVOID(opt, neg) \\r
+       if (go->neg && \\r
+                       len >= CILEN_VOID && \\r
+                       p[1] == CILEN_VOID && \\r
+                       p[0] == opt) { \\r
+               len -= CILEN_VOID; \\r
+               INCPTR(CILEN_VOID, p); \\r
+               try.neg = 0; \\r
+               LCPDEBUG((LOG_INFO, "lcp_rejci: void opt %d rejected\n", opt)); \\r
+       }\r
+#define REJCISHORT(opt, neg, val) \\r
+       if (go->neg && \\r
+                       len >= CILEN_SHORT && \\r
+                       p[1] == CILEN_SHORT && \\r
+                       p[0] == opt) { \\r
+               len -= CILEN_SHORT; \\r
+               INCPTR(2, p); \\r
+               GETSHORT(cishort, p); \\r
+               /* Check rejected value. */ \\r
+               if (cishort != val) \\r
+                       goto bad; \\r
+               try.neg = 0; \\r
+               LCPDEBUG((LOG_INFO,"lcp_rejci: short opt %d rejected\n", opt)); \\r
+       }\r
+#define REJCICHAP(opt, neg, val, digest) \\r
+       if (go->neg && \\r
+                       len >= CILEN_CHAP && \\r
+                       p[1] == CILEN_CHAP && \\r
+                       p[0] == opt) { \\r
+               len -= CILEN_CHAP; \\r
+               INCPTR(2, p); \\r
+               GETSHORT(cishort, p); \\r
+               GETCHAR(cichar, p); \\r
+               /* Check rejected value. */ \\r
+               if (cishort != val || cichar != digest) \\r
+                       goto bad; \\r
+               try.neg = 0; \\r
+               try.neg_upap = 0; \\r
+               LCPDEBUG((LOG_INFO,"lcp_rejci: chap opt %d rejected\n", opt)); \\r
+       }\r
+#define REJCILONG(opt, neg, val) \\r
+       if (go->neg && \\r
+                       len >= CILEN_LONG && \\r
+                       p[1] == CILEN_LONG && \\r
+                       p[0] == opt) { \\r
+               len -= CILEN_LONG; \\r
+               INCPTR(2, p); \\r
+               GETLONG(cilong, p); \\r
+               /* Check rejected value. */ \\r
+               if (cilong != val) \\r
+                       goto bad; \\r
+               try.neg = 0; \\r
+               LCPDEBUG((LOG_INFO,"lcp_rejci: long opt %d rejected\n", opt)); \\r
+       }\r
+#define REJCILQR(opt, neg, val) \\r
+       if (go->neg && \\r
+                       len >= CILEN_LQR && \\r
+                       p[1] == CILEN_LQR && \\r
+                       p[0] == opt) { \\r
+               len -= CILEN_LQR; \\r
+               INCPTR(2, p); \\r
+               GETSHORT(cishort, p); \\r
+               GETLONG(cilong, p); \\r
+               /* Check rejected value. */ \\r
+               if (cishort != PPP_LQR || cilong != val) \\r
+                       goto bad; \\r
+               try.neg = 0; \\r
+               LCPDEBUG((LOG_INFO,"lcp_rejci: LQR opt %d rejected\n", opt)); \\r
+       }\r
+#define REJCICBCP(opt, neg, val) \\r
+       if (go->neg && \\r
+                       len >= CILEN_CBCP && \\r
+                       p[1] == CILEN_CBCP && \\r
+                       p[0] == opt) { \\r
+               len -= CILEN_CBCP; \\r
+               INCPTR(2, p); \\r
+               GETCHAR(cichar, p); \\r
+               /* Check rejected value. */ \\r
+               if (cichar != val) \\r
+                       goto bad; \\r
+               try.neg = 0; \\r
+               LCPDEBUG((LOG_INFO,"lcp_rejci: Callback opt %d rejected\n", opt)); \\r
+       }\r
+       \r
+       REJCISHORT(CI_MRU, neg_mru, go->mru);\r
+       REJCILONG(CI_ASYNCMAP, neg_asyncmap, go->asyncmap);\r
+       REJCICHAP(CI_AUTHTYPE, neg_chap, PPP_CHAP, go->chap_mdtype);\r
+       if (!go->neg_chap) {\r
+               REJCISHORT(CI_AUTHTYPE, neg_upap, PPP_PAP);\r
+       }\r
+       REJCILQR(CI_QUALITY, neg_lqr, go->lqr_period);\r
+       REJCICBCP(CI_CALLBACK, neg_cbcp, CBCP_OPT);\r
+       REJCILONG(CI_MAGICNUMBER, neg_magicnumber, go->magicnumber);\r
+       REJCIVOID(CI_PCOMPRESSION, neg_pcompression);\r
+       REJCIVOID(CI_ACCOMPRESSION, neg_accompression);\r
+       \r
+       /*\r
+       * If there are any remaining CIs, then this packet is bad.\r
+       */\r
+       if (len != 0)\r
+               goto bad;\r
+       /*\r
+       * Now we can update state.\r
+       */\r
+       if (f->state != OPENED)\r
+               *go = try;\r
+       return 1;\r
+       \r
+bad:\r
+       LCPDEBUG((LOG_WARNING, "lcp_rejci: received bad Reject!\n"));\r
+       return 0;\r
+}\r
+\r
+\r
+/*\r
+ * lcp_reqci - Check the peer's requested CIs and send appropriate response.\r
+ *\r
+ * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified\r
+ * appropriately.  If reject_if_disagree is non-zero, doesn't return\r
+ * CONFNAK; returns CONFREJ if it can't return CONFACK.\r
+ */\r
+static int lcp_reqci(fsm *f, \r
+                                               u_char *inp,            /* Requested CIs */\r
+                                               int *lenp,                      /* Length of requested CIs */\r
+                                               int reject_if_disagree)\r
+{\r
+       lcp_options *go = &lcp_gotoptions[f->unit];\r
+       lcp_options *ho = &lcp_hisoptions[f->unit];\r
+       lcp_options *ao = &lcp_allowoptions[f->unit];\r
+       u_char *cip, *next;                     /* Pointer to current and next CIs */\r
+       int cilen, citype, cichar;      /* Parsed len, type, char value */\r
+       u_short cishort;                        /* Parsed short value */\r
+       u32_t cilong;                   /* Parse long value */\r
+       int rc = CONFACK;                       /* Final packet return code */\r
+       int orc;                                        /* Individual option return code */\r
+       u_char *p;                                      /* Pointer to next char to parse */\r
+       u_char *rejp;                           /* Pointer to next char in reject frame */\r
+       u_char *nakp;                           /* Pointer to next char in Nak frame */\r
+       int l = *lenp;                          /* Length left */\r
+#if TRACELCP > 0\r
+       char traceBuf[80];\r
+       int traceNdx = 0;\r
+#endif\r
+       \r
+       /*\r
+        * Reset all his options.\r
+        */\r
+       BZERO(ho, sizeof(*ho));\r
+       \r
+       /*\r
+        * Process all his options.\r
+        */\r
+       next = inp;\r
+       nakp = nak_buffer;\r
+       rejp = inp;\r
+       while (l) {\r
+               orc = CONFACK;                  /* Assume success */\r
+               cip = p = next;                 /* Remember begining of CI */\r
+               if (l < 2 ||                    /* Not enough data for CI header or */\r
+                               p[1] < 2 ||                     /*  CI length too small or */\r
+                               p[1] > l) {                     /*  CI length too big? */\r
+                       LCPDEBUG((LOG_WARNING, "lcp_reqci: bad CI length!\n"));\r
+                       orc = CONFREJ;          /* Reject bad CI */\r
+                       cilen = l;                      /* Reject till end of packet */\r
+                       l = 0;                  /* Don't loop again */\r
+                       citype = 0;\r
+                       goto endswitch;\r
+               }\r
+               GETCHAR(citype, p);             /* Parse CI type */\r
+               GETCHAR(cilen, p);              /* Parse CI length */\r
+               l -= cilen;                     /* Adjust remaining length */\r
+               next += cilen;                  /* Step to next CI */\r
+               \r
+               switch (citype) {               /* Check CI type */\r
+               case CI_MRU:\r
+                       if (!ao->neg_mru) {             /* Allow option? */\r
+                               LCPDEBUG((LOG_INFO, "lcp_reqci: Reject MRU - not allowed\n"));\r
+                               orc = CONFREJ;          /* Reject CI */\r
+                               break;\r
+                       } else if (cilen != CILEN_SHORT) {      /* Check CI length */\r
+                               LCPDEBUG((LOG_INFO, "lcp_reqci: Reject MRU - bad length\n"));\r
+                               orc = CONFREJ;          /* Reject CI */\r
+                               break;\r
+                       }\r
+                       GETSHORT(cishort, p);   /* Parse MRU */\r
+                       \r
+                       /*\r
+                        * He must be able to receive at least our minimum.\r
+                        * No need to check a maximum.  If he sends a large number,\r
+                        * we'll just ignore it.\r
+                        */\r
+                       if (cishort < PPP_MINMRU) {\r
+                               LCPDEBUG((LOG_INFO, "lcp_reqci: Nak - MRU too small\n"));\r
+                               orc = CONFNAK;          /* Nak CI */\r
+                               PUTCHAR(CI_MRU, nakp);\r
+                               PUTCHAR(CILEN_SHORT, nakp);\r
+                               PUTSHORT(PPP_MINMRU, nakp);     /* Give him a hint */\r
+                               break;\r
+                       }\r
+                       ho->neg_mru = 1;                /* Remember he sent MRU */\r
+                       ho->mru = cishort;              /* And remember value */\r
+#if TRACELCP > 0\r
+                       snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " MRU %d", cishort);\r
+                       traceNdx = strlen(traceBuf);\r
+#endif\r
+                       break;\r
+               \r
+               case CI_ASYNCMAP:\r
+                       if (!ao->neg_asyncmap) {\r
+                               LCPDEBUG((LOG_INFO, "lcp_reqci: Reject ASYNCMAP not allowed\n"));\r
+                               orc = CONFREJ;\r
+                               break;\r
+                       } else if (cilen != CILEN_LONG) {\r
+                               LCPDEBUG((LOG_INFO, "lcp_reqci: Reject ASYNCMAP bad length\n"));\r
+                               orc = CONFREJ;\r
+                               break;\r
+                       }\r
+                       GETLONG(cilong, p);\r
+                       \r
+                       /*\r
+                        * Asyncmap must have set at least the bits\r
+                        * which are set in lcp_allowoptions[unit].asyncmap.\r
+                        */\r
+                       if ((ao->asyncmap & ~cilong) != 0) {\r
+                               LCPDEBUG((LOG_INFO, "lcp_reqci: Nak ASYNCMAP %lX missing %lX\n", \r
+                                                       cilong, ao->asyncmap));\r
+                               orc = CONFNAK;\r
+                               PUTCHAR(CI_ASYNCMAP, nakp);\r
+                               PUTCHAR(CILEN_LONG, nakp);\r
+                               PUTLONG(ao->asyncmap | cilong, nakp);\r
+                               break;\r
+                       }\r
+                       ho->neg_asyncmap = 1;\r
+                       ho->asyncmap = cilong;\r
+#if TRACELCP > 0\r
+                       snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " ASYNCMAP=%lX", cilong);\r
+                       traceNdx = strlen(traceBuf);\r
+#endif\r
+                       break;\r
+               \r
+               case CI_AUTHTYPE:\r
+                       if (cilen < CILEN_SHORT) {\r
+                               LCPDEBUG((LOG_INFO, "lcp_reqci: Reject AUTHTYPE missing arg\n"));\r
+                               orc = CONFREJ;\r
+                               break;\r
+                       } else if (!(ao->neg_upap || ao->neg_chap)) {\r
+                               /*\r
+                                * Reject the option if we're not willing to authenticate.\r
+                                */\r
+                               LCPDEBUG((LOG_INFO, "lcp_reqci: Reject AUTHTYPE not allowed\n"));\r
+                               orc = CONFREJ;\r
+                               break;\r
+                       }\r
+                       GETSHORT(cishort, p);\r
+                       \r
+                       /*\r
+                        * Authtype must be UPAP or CHAP.\r
+                        *\r
+                        * Note: if both ao->neg_upap and ao->neg_chap are set,\r
+                        * and the peer sends a Configure-Request with two\r
+                        * authenticate-protocol requests, one for CHAP and one\r
+                        * for UPAP, then we will reject the second request.\r
+                        * Whether we end up doing CHAP or UPAP depends then on\r
+                        * the ordering of the CIs in the peer's Configure-Request.\r
+                        */\r
+                       \r
+                       if (cishort == PPP_PAP) {\r
+                               if (ho->neg_chap) {     /* we've already accepted CHAP */\r
+                                       LCPDEBUG((LOG_WARNING, "lcp_reqci: Reject AUTHTYPE PAP already accepted\n"));\r
+                                       orc = CONFREJ;\r
+                                       break;\r
+                               } else if (cilen != CILEN_SHORT) {\r
+                                       LCPDEBUG((LOG_WARNING, "lcp_reqci: Reject AUTHTYPE PAP bad len\n"));\r
+                                       orc = CONFREJ;\r
+                                       break;\r
+                               }\r
+                               if (!ao->neg_upap) {    /* we don't want to do PAP */\r
+                                       LCPDEBUG((LOG_WARNING, "lcp_reqci: Nak AUTHTYPE PAP not allowed\n"));\r
+                                       orc = CONFNAK;  /* NAK it and suggest CHAP */\r
+                                       PUTCHAR(CI_AUTHTYPE, nakp);\r
+                                       PUTCHAR(CILEN_CHAP, nakp);\r
+                                       PUTSHORT(PPP_CHAP, nakp);\r
+                                       PUTCHAR(ao->chap_mdtype, nakp);\r
+                                       break;\r
+                               }\r
+                               ho->neg_upap = 1;\r
+#if TRACELCP > 0\r
+                               snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " PAP (%X)", cishort);\r
+                               traceNdx = strlen(traceBuf);\r
+#endif\r
+                               break;\r
+                       }\r
+                       if (cishort == PPP_CHAP) {\r
+                               if (ho->neg_upap) {     /* we've already accepted PAP */\r
+                                       LCPDEBUG((LOG_WARNING, "lcp_reqci: Reject AUTHTYPE CHAP accepted PAP\n"));\r
+                                       orc = CONFREJ;\r
+                                       break;\r
+                               } else if (cilen != CILEN_CHAP) {\r
+                                       LCPDEBUG((LOG_WARNING, "lcp_reqci: Reject AUTHTYPE CHAP bad len\n"));\r
+                                       orc = CONFREJ;\r
+                                       break;\r
+                               }\r
+                               if (!ao->neg_chap) {    /* we don't want to do CHAP */\r
+                                       LCPDEBUG((LOG_WARNING, "lcp_reqci: Nak AUTHTYPE CHAP not allowed\n"));\r
+                                       orc = CONFNAK;  /* NAK it and suggest PAP */\r
+                                       PUTCHAR(CI_AUTHTYPE, nakp);\r
+                                       PUTCHAR(CILEN_SHORT, nakp);\r
+                                       PUTSHORT(PPP_PAP, nakp);\r
+                                       break;\r
+                               }\r
+                               GETCHAR(cichar, p);     /* get digest type*/\r
+                               if (cichar != CHAP_DIGEST_MD5\r
+#ifdef CHAPMS\r
+                                               && cichar != CHAP_MICROSOFT\r
+#endif\r
+                               ) {\r
+                                       LCPDEBUG((LOG_WARNING, "lcp_reqci: Nak AUTHTYPE CHAP digest=%d\n", cichar));\r
+                                       orc = CONFNAK;\r
+                                       PUTCHAR(CI_AUTHTYPE, nakp);\r
+                                       PUTCHAR(CILEN_CHAP, nakp);\r
+                                       PUTSHORT(PPP_CHAP, nakp);\r
+                                       PUTCHAR(ao->chap_mdtype, nakp);\r
+                                       break;\r
+                               }\r
+#if TRACELCP > 0\r
+                               snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " CHAP %X,%d", cishort, cichar);\r
+                               traceNdx = strlen(traceBuf);\r
+#endif\r
+                               ho->chap_mdtype = cichar; /* save md type */\r
+                               ho->neg_chap = 1;\r
+                               break;\r
+                       }\r
+                       \r
+                       /*\r
+                        * We don't recognize the protocol they're asking for.\r
+                        * Nak it with something we're willing to do.\r
+                        * (At this point we know ao->neg_upap || ao->neg_chap.)\r
+                        */\r
+                       orc = CONFNAK;\r
+                       PUTCHAR(CI_AUTHTYPE, nakp);\r
+                       if (ao->neg_chap) {\r
+                               LCPDEBUG((LOG_WARNING, "lcp_reqci: Nak AUTHTYPE %d req CHAP\n", cishort));\r
+                               PUTCHAR(CILEN_CHAP, nakp);\r
+                               PUTSHORT(PPP_CHAP, nakp);\r
+                               PUTCHAR(ao->chap_mdtype, nakp);\r
+                       } \r
+                       else {\r
+                               LCPDEBUG((LOG_WARNING, "lcp_reqci: Nak AUTHTYPE %d req PAP\n", cishort));\r
+                               PUTCHAR(CILEN_SHORT, nakp);\r
+                               PUTSHORT(PPP_PAP, nakp);\r
+                       }\r
+                       break;\r
+               \r
+               case CI_QUALITY:\r
+                       GETSHORT(cishort, p);\r
+                       GETLONG(cilong, p);\r
+#if TRACELCP > 0\r
+                       snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " QUALITY (%x %x)", cishort, (unsigned int) cilong);\r
+                       traceNdx = strlen(traceBuf);\r
+#endif\r
+\r
+                       if (!ao->neg_lqr ||\r
+                                       cilen != CILEN_LQR) {\r
+                               orc = CONFREJ;\r
+                               break;\r
+                       }\r
+                       \r
+                       /*\r
+                        * Check the protocol and the reporting period.\r
+                        * XXX When should we Nak this, and what with?\r
+                        */\r
+                       if (cishort != PPP_LQR) {\r
+                               orc = CONFNAK;\r
+                               PUTCHAR(CI_QUALITY, nakp);\r
+                               PUTCHAR(CILEN_LQR, nakp);\r
+                               PUTSHORT(PPP_LQR, nakp);\r
+                               PUTLONG(ao->lqr_period, nakp);\r
+                               break;\r
+                       }\r
+                       break;\r
+               \r
+               case CI_MAGICNUMBER:\r
+                       if (!(ao->neg_magicnumber || go->neg_magicnumber) ||\r
+                                       cilen != CILEN_LONG) {\r
+                               orc = CONFREJ;\r
+                               break;\r
+                       }\r
+                       GETLONG(cilong, p);\r
+#if TRACELCP > 0\r
+                       snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " MAGICNUMBER (%lX)", cilong);\r
+                       traceNdx = strlen(traceBuf);\r
+#endif\r
+\r
+                       /*\r
+                        * He must have a different magic number.\r
+                        */\r
+                       if (go->neg_magicnumber &&\r
+                                       cilong == go->magicnumber) {\r
+                               cilong = magic();       /* Don't put magic() inside macro! */\r
+                               orc = CONFNAK;\r
+                               PUTCHAR(CI_MAGICNUMBER, nakp);\r
+                               PUTCHAR(CILEN_LONG, nakp);\r
+                               PUTLONG(cilong, nakp);\r
+                               break;\r
+                       }\r
+                       ho->neg_magicnumber = 1;\r
+                       ho->magicnumber = cilong;\r
+                       break;\r
+               \r
+               \r
+               case CI_PCOMPRESSION:\r
+#if TRACELCP > 0\r
+                       snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " PCOMPRESSION");\r
+                       traceNdx = strlen(traceBuf);\r
+#endif\r
+                       if (!ao->neg_pcompression ||\r
+                                       cilen != CILEN_VOID) {\r
+                               orc = CONFREJ;\r
+                               break;\r
+                       }\r
+                       ho->neg_pcompression = 1;\r
+                       break;\r
+               \r
+               case CI_ACCOMPRESSION:\r
+#if TRACELCP > 0\r
+                       snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " ACCOMPRESSION");\r
+                       traceNdx = strlen(traceBuf);\r
+#endif\r
+                       if (!ao->neg_accompression ||\r
+                                       cilen != CILEN_VOID) {\r
+                               orc = CONFREJ;\r
+                               break;\r
+                       }\r
+                       ho->neg_accompression = 1;\r
+                       break;\r
+               \r
+               case CI_MRRU:\r
+#if TRACELCP > 0\r
+                       snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " CI_MRRU");\r
+                       traceNdx = strlen(traceBuf);\r
+#endif\r
+                       orc = CONFREJ;\r
+                       break;\r
+               \r
+               case CI_SSNHF:\r
+#if TRACELCP > 0\r
+                       snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " CI_SSNHF");\r
+                       traceNdx = strlen(traceBuf);\r
+#endif\r
+                       orc = CONFREJ;\r
+                       break;\r
+               \r
+               case CI_EPDISC:\r
+#if TRACELCP > 0\r
+                       snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " CI_EPDISC");\r
+                       traceNdx = strlen(traceBuf);\r
+#endif\r
+                       orc = CONFREJ;\r
+                       break;\r
+               \r
+               default:\r
+#if TRACELCP\r
+                       snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " unknown %d", citype);\r
+                       traceNdx = strlen(traceBuf);\r
+#endif\r
+                       orc = CONFREJ;\r
+                       break;\r
+               }\r
+               \r
+       endswitch:\r
+#if TRACELCP\r
+               if (traceNdx >= 80 - 32) {\r
+                       LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd%s\n", traceBuf));\r
+                       traceNdx = 0;\r
+               }\r
+#endif\r
+               if (orc == CONFACK &&           /* Good CI */\r
+                               rc != CONFACK)          /*  but prior CI wasnt? */\r
+                       continue;                       /* Don't send this one */\r
+               \r
+               if (orc == CONFNAK) {           /* Nak this CI? */\r
+                       if (reject_if_disagree  /* Getting fed up with sending NAKs? */\r
+                                       && citype != CI_MAGICNUMBER) {\r
+                               orc = CONFREJ;          /* Get tough if so */\r
+                       } \r
+                       else {\r
+                               if (rc == CONFREJ)      /* Rejecting prior CI? */\r
+                                       continue;               /* Don't send this one */\r
+                               rc = CONFNAK;\r
+                       }\r
+               }\r
+               if (orc == CONFREJ) {           /* Reject this CI */\r
+                       rc = CONFREJ;\r
+                       if (cip != rejp)                /* Need to move rejected CI? */\r
+                               BCOPY(cip, rejp, cilen); /* Move it */\r
+                       INCPTR(cilen, rejp);    /* Update output pointer */\r
+               }\r
+       }\r
+       \r
+       /*\r
+        * If we wanted to send additional NAKs (for unsent CIs), the\r
+        * code would go here.  The extra NAKs would go at *nakp.\r
+        * At present there are no cases where we want to ask the\r
+        * peer to negotiate an option.\r
+        */\r
+       \r
+       switch (rc) {\r
+       case CONFACK:\r
+               *lenp = (int)(next - inp);\r
+               break;\r
+       case CONFNAK:\r
+               /*\r
+                * Copy the Nak'd options from the nak_buffer to the caller's buffer.\r
+                */\r
+               *lenp = (int)(nakp - nak_buffer);\r
+               BCOPY(nak_buffer, inp, *lenp);\r
+               break;\r
+       case CONFREJ:\r
+               *lenp = (int)(rejp - inp);\r
+               break;\r
+       }\r
+       \r
+#if TRACELCP > 0\r
+       if (traceNdx > 0) {\r
+               LCPDEBUG((LOG_INFO, "lcp_reqci: %s\n", traceBuf));\r
+       }\r
+#endif\r
+       LCPDEBUG((LOG_INFO, "lcp_reqci: returning CONF%s.\n", CODENAME(rc)));\r
+       return (rc);                    /* Return final code */\r
+}\r
+\r
+\r
+/*\r
+ * lcp_up - LCP has come UP.\r
+ */\r
+static void lcp_up(fsm *f)\r
+{\r
+       lcp_options *wo = &lcp_wantoptions[f->unit];\r
+       lcp_options *ho = &lcp_hisoptions[f->unit];\r
+       lcp_options *go = &lcp_gotoptions[f->unit];\r
+       lcp_options *ao = &lcp_allowoptions[f->unit];\r
+       \r
+       if (!go->neg_magicnumber)\r
+               go->magicnumber = 0;\r
+       if (!ho->neg_magicnumber)\r
+               ho->magicnumber = 0;\r
+       \r
+       /*\r
+       * Set our MTU to the smaller of the MTU we wanted and\r
+       * the MRU our peer wanted.  If we negotiated an MRU,\r
+       * set our MRU to the larger of value we wanted and\r
+       * the value we got in the negotiation.\r
+       */\r
+       ppp_send_config(f->unit, LWIP_MIN(ao->mru, (ho->neg_mru? ho->mru: PPP_MRU)),\r
+                               (ho->neg_asyncmap? ho->asyncmap: 0xffffffffl),\r
+                               ho->neg_pcompression, ho->neg_accompression);\r
+       /*\r
+       * If the asyncmap hasn't been negotiated, we really should\r
+       * set the receive asyncmap to ffffffff, but we set it to 0\r
+       * for backwards contemptibility.\r
+       */\r
+       ppp_recv_config(f->unit, (go->neg_mru? LWIP_MAX(wo->mru, go->mru): PPP_MRU),\r
+                               (go->neg_asyncmap? go->asyncmap: 0x00000000),\r
+                               go->neg_pcompression, go->neg_accompression);\r
+       \r
+       if (ho->neg_mru)\r
+               peer_mru[f->unit] = ho->mru;\r
+       \r
+       lcp_echo_lowerup(f->unit);  /* Enable echo messages */\r
+       \r
+       link_established(f->unit);\r
+}\r
+\r
+\r
+/*\r
+ * lcp_down - LCP has gone DOWN.\r
+ *\r
+ * Alert other protocols.\r
+ */\r
+static void lcp_down(fsm *f)\r
+{\r
+       lcp_options *go = &lcp_gotoptions[f->unit];\r
+       \r
+       lcp_echo_lowerdown(f->unit);\r
+       \r
+       link_down(f->unit);\r
+       \r
+       ppp_send_config(f->unit, PPP_MRU, 0xffffffffl, 0, 0);\r
+       ppp_recv_config(f->unit, PPP_MRU,\r
+                               (go->neg_asyncmap? go->asyncmap: 0x00000000),\r
+                               go->neg_pcompression, go->neg_accompression);\r
+       peer_mru[f->unit] = PPP_MRU;\r
+}\r
+\r
+\r
+/*\r
+ * lcp_starting - LCP needs the lower layer up.\r
+ */\r
+static void lcp_starting(fsm *f)\r
+{\r
+       link_required(f->unit);\r
+}\r
+\r
+\r
+/*\r
+ * lcp_finished - LCP has finished with the lower layer.\r
+ */\r
+static void lcp_finished(fsm *f)\r
+{\r
+       link_terminated(f->unit);\r
+}\r
+\r
+\r
+#if 0\r
+/*\r
+ * print_string - print a readable representation of a string using\r
+ * printer.\r
+ */\r
+static void print_string(\r
+    char *p,\r
+    int len,\r
+    void (*printer) (void *, char *, ...),\r
+    void *arg\r
+)\r
+{\r
+    int c;\r
+    \r
+    printer(arg, "\"");\r
+    for (; len > 0; --len) {\r
+        c = *p++;\r
+        if (' ' <= c && c <= '~') {\r
+            if (c == '\\' || c == '"')\r
+                printer(arg, "\\");\r
+            printer(arg, "%c", c);\r
+        } else {\r
+            switch (c) {\r
+            case '\n':\r
+                printer(arg, "\\n");\r
+                break;\r
+            case '\r':\r
+                printer(arg, "\\r");\r
+                break;\r
+            case '\t':\r
+                printer(arg, "\\t");\r
+                break;\r
+            default:\r
+                printer(arg, "\\%.3o", c);\r
+            }\r
+        }\r
+    }\r
+    printer(arg, "\"");\r
+}\r
+\r
+\r
+/*\r
+ * lcp_printpkt - print the contents of an LCP packet.\r
+ */\r
+static char *lcp_codenames[] = {\r
+       "ConfReq", "ConfAck", "ConfNak", "ConfRej",\r
+       "TermReq", "TermAck", "CodeRej", "ProtRej",\r
+       "EchoReq", "EchoRep", "DiscReq"\r
+};\r
+\r
+static int lcp_printpkt(\r
+       u_char *p,\r
+       int plen,\r
+       void (*printer) (void *, char *, ...),\r
+       void *arg\r
+)\r
+{\r
+       int code, id, len, olen;\r
+       u_char *pstart, *optend;\r
+       u_short cishort;\r
+       u32_t cilong;\r
+       \r
+       if (plen < HEADERLEN)\r
+               return 0;\r
+       pstart = p;\r
+       GETCHAR(code, p);\r
+       GETCHAR(id, p);\r
+       GETSHORT(len, p);\r
+       if (len < HEADERLEN || len > plen)\r
+               return 0;\r
+       \r
+       if (code >= 1 && code <= sizeof(lcp_codenames) / sizeof(char *))\r
+               printer(arg, " %s", lcp_codenames[code-1]);\r
+       else\r
+               printer(arg, " code=0x%x", code);\r
+       printer(arg, " id=0x%x", id);\r
+       len -= HEADERLEN;\r
+       switch (code) {\r
+       case CONFREQ:\r
+       case CONFACK:\r
+       case CONFNAK:\r
+       case CONFREJ:\r
+               /* print option list */\r
+               while (len >= 2) {\r
+                       GETCHAR(code, p);\r
+                       GETCHAR(olen, p);\r
+                       p -= 2;\r
+                       if (olen < 2 || olen > len) {\r
+                               break;\r
+                       }\r
+                       printer(arg, " <");\r
+                       len -= olen;\r
+                       optend = p + olen;\r
+                       switch (code) {\r
+                       case CI_MRU:\r
+                               if (olen == CILEN_SHORT) {\r
+                                       p += 2;\r
+                                       GETSHORT(cishort, p);\r
+                                       printer(arg, "mru %d", cishort);\r
+                               }\r
+                               break;\r
+                       case CI_ASYNCMAP:\r
+                               if (olen == CILEN_LONG) {\r
+                                       p += 2;\r
+                                       GETLONG(cilong, p);\r
+                                       printer(arg, "asyncmap 0x%lx", cilong);\r
+                               }\r
+                               break;\r
+                       case CI_AUTHTYPE:\r
+                               if (olen >= CILEN_SHORT) {\r
+                                       p += 2;\r
+                                       printer(arg, "auth ");\r
+                                       GETSHORT(cishort, p);\r
+                                       switch (cishort) {\r
+                                       case PPP_PAP:\r
+                                               printer(arg, "pap");\r
+                                               break;\r
+                                       case PPP_CHAP:\r
+                                               printer(arg, "chap");\r
+                                               break;\r
+                                       default:\r
+                                               printer(arg, "0x%x", cishort);\r
+                                       }\r
+                               }\r
+                               break;\r
+                       case CI_QUALITY:\r
+                               if (olen >= CILEN_SHORT) {\r
+                                       p += 2;\r
+                                       printer(arg, "quality ");\r
+                                       GETSHORT(cishort, p);\r
+                                       switch (cishort) {\r
+                                       case PPP_LQR:\r
+                                               printer(arg, "lqr");\r
+                                               break;\r
+                                       default:\r
+                                               printer(arg, "0x%x", cishort);\r
+                                       }\r
+                               }\r
+                               break;\r
+                       case CI_CALLBACK:\r
+                               if (olen >= CILEN_CHAR) {\r
+                                       p += 2;\r
+                                       printer(arg, "callback ");\r
+                                       GETSHORT(cishort, p);\r
+                                       switch (cishort) {\r
+                                       case CBCP_OPT:\r
+                                               printer(arg, "CBCP");\r
+                                               break;\r
+                                       default:\r
+                                               printer(arg, "0x%x", cishort);\r
+                                       }\r
+                               }\r
+                               break;\r
+                       case CI_MAGICNUMBER:\r
+                               if (olen == CILEN_LONG) {\r
+                                       p += 2;\r
+                                       GETLONG(cilong, p);\r
+                                       printer(arg, "magic 0x%x", cilong);\r
+                               }\r
+                               break;\r
+                       case CI_PCOMPRESSION:\r
+                               if (olen == CILEN_VOID) {\r
+                                       p += 2;\r
+                                       printer(arg, "pcomp");\r
+                               }\r
+                               break;\r
+                       case CI_ACCOMPRESSION:\r
+                               if (olen == CILEN_VOID) {\r
+                                       p += 2;\r
+                                       printer(arg, "accomp");\r
+                               }\r
+                               break;\r
+                       }\r
+                       while (p < optend) {\r
+                               GETCHAR(code, p);\r
+                               printer(arg, " %.2x", code);\r
+                       }\r
+                       printer(arg, ">");\r
+               }\r
+               break;\r
+       \r
+       case TERMACK:\r
+       case TERMREQ:\r
+               if (len > 0 && *p >= ' ' && *p < 0x7f) {\r
+                       printer(arg, " ");\r
+                       print_string((char*)p, len, printer, arg);\r
+                       p += len;\r
+                       len = 0;\r
+               }\r
+               break;\r
+       \r
+       case ECHOREQ:\r
+       case ECHOREP:\r
+       case DISCREQ:\r
+               if (len >= 4) {\r
+                       GETLONG(cilong, p);\r
+                       printer(arg, " magic=0x%x", cilong);\r
+                       p += 4;\r
+                       len -= 4;\r
+               }\r
+               break;\r
+       }\r
+       \r
+       /* print the rest of the bytes in the packet */\r
+       for (; len > 0; --len) {\r
+               GETCHAR(code, p);\r
+               printer(arg, " %.2x", code);\r
+       }\r
+       \r
+       return (int)(p - pstart);\r
+}\r
+#endif\r
+\r
+/*\r
+ * Time to shut down the link because there is nothing out there.\r
+ */\r
+\r
+static void LcpLinkFailure (fsm *f)\r
+{\r
+       if (f->state == OPENED) {\r
+               LCPDEBUG((LOG_INFO, "No response to %d echo-requests\n", lcp_echos_pending));\r
+               LCPDEBUG((LOG_NOTICE, "Serial link appears to be disconnected.\n"));\r
+               lcp_close(f->unit, "Peer not responding");\r
+       }\r
+}\r
+\r
+/*\r
+ * Timer expired for the LCP echo requests from this process.\r
+ */\r
+\r
+static void LcpEchoCheck (fsm *f)\r
+{\r
+       LcpSendEchoRequest (f);\r
+       \r
+       /*\r
+        * Start the timer for the next interval.\r
+        */\r
+       LWIP_ASSERT("lcp_echo_timer_running == 0", lcp_echo_timer_running == 0);\r
+\r
+       TIMEOUT (LcpEchoTimeout, f, lcp_echo_interval);\r
+       lcp_echo_timer_running = 1;\r
+}\r
+\r
+/*\r
+ * LcpEchoTimeout - Timer expired on the LCP echo\r
+ */\r
+\r
+static void LcpEchoTimeout (void *arg)\r
+{\r
+       if (lcp_echo_timer_running != 0) {\r
+               lcp_echo_timer_running = 0;\r
+               LcpEchoCheck ((fsm *) arg);\r
+       }\r
+}\r
+\r
+/*\r
+ * LcpEchoReply - LCP has received a reply to the echo\r
+ */\r
+static void lcp_received_echo_reply (fsm *f, int id, u_char *inp, int len)\r
+{\r
+       u32_t magic;\r
+       \r
+       (void)id;\r
+\r
+       /* Check the magic number - don't count replies from ourselves. */\r
+       if (len < 4) {\r
+               LCPDEBUG((LOG_WARNING, "lcp: received short Echo-Reply, length %d\n", len));\r
+               return;\r
+       }\r
+       GETLONG(magic, inp);\r
+       if (lcp_gotoptions[f->unit].neg_magicnumber\r
+                       && magic == lcp_gotoptions[f->unit].magicnumber) {\r
+               LCPDEBUG((LOG_WARNING, "appear to have received our own echo-reply!\n"));\r
+               return;\r
+       }\r
+       \r
+       /* Reset the number of outstanding echo frames */\r
+       lcp_echos_pending = 0;\r
+}\r
+\r
+/*\r
+ * LcpSendEchoRequest - Send an echo request frame to the peer\r
+ */\r
+\r
+static void LcpSendEchoRequest (fsm *f)\r
+{\r
+       u32_t lcp_magic;\r
+       u_char pkt[4], *pktp;\r
+       \r
+       /*\r
+       * Detect the failure of the peer at this point.\r
+       */\r
+       if (lcp_echo_fails != 0) {\r
+               if (lcp_echos_pending++ >= lcp_echo_fails) {\r
+                       LcpLinkFailure(f);\r
+                       lcp_echos_pending = 0;\r
+               }\r
+       }\r
+       \r
+       /*\r
+       * Make and send the echo request frame.\r
+       */\r
+       if (f->state == OPENED) {\r
+               lcp_magic = lcp_gotoptions[f->unit].magicnumber;\r
+               pktp = pkt;\r
+               PUTLONG(lcp_magic, pktp);\r
+               fsm_sdata(f, ECHOREQ, (u_char)(lcp_echo_number++ & 0xFF), pkt, (int)(pktp - pkt));\r
+       }\r
+}\r
+\r
+/*\r
+ * lcp_echo_lowerup - Start the timer for the LCP frame\r
+ */\r
+\r
+static void lcp_echo_lowerup (int unit)\r
+{\r
+       fsm *f = &lcp_fsm[unit];\r
+       \r
+       /* Clear the parameters for generating echo frames */\r
+       lcp_echos_pending      = 0;\r
+       lcp_echo_number        = 0;\r
+       lcp_echo_timer_running = 0;\r
+       \r
+       /* If a timeout interval is specified then start the timer */\r
+       if (lcp_echo_interval != 0)\r
+               LcpEchoCheck (f);\r
+}\r
+\r
+/*\r
+ * lcp_echo_lowerdown - Stop the timer for the LCP frame\r
+ */\r
+\r
+static void lcp_echo_lowerdown (int unit)\r
+{\r
+       fsm *f = &lcp_fsm[unit];\r
+       \r
+       if (lcp_echo_timer_running != 0) {\r
+               UNTIMEOUT (LcpEchoTimeout, f);\r
+               lcp_echo_timer_running = 0;\r
+       }\r
+}\r
+\r
+#endif /* PPP_SUPPORT */\r
index 2944d81927b20f56e067e41478eb99e9c3e37f8d..a8877086e7d7f2948804a673da1681fec0452af8 100644 (file)
-/*****************************************************************************
-* lcp.h - Network Link Control Protocol header file.
-*
-* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
-* portions Copyright (c) 1997 Global Election Systems Inc.
-*
-* The authors hereby grant permission to use, copy, modify, distribute,
-* and license this software and its documentation for any purpose, provided
-* that existing copyright notices are retained in all copies and that this
-* notice and the following disclaimer are included verbatim in any 
-* distributions. No written agreement, license, or royalty fee is required
-* for any of the authorized uses.
-*
-* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *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 CONTRIBUTORS 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.
-*
-******************************************************************************
-* REVISION HISTORY
-*
-* 03-01-01 Marc Boucher <marc@mbsi.ca>
-*   Ported to lwIP.
-* 97-11-05 Guy Lancaster <glanca@gesn.com>, Global Election Systems Inc.
-*      Original derived from BSD codes.
-*****************************************************************************/
-/*
- * lcp.h - Link Control Protocol definitions.
- *
- * Copyright (c) 1989 Carnegie Mellon University.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by Carnegie Mellon University.  The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * $Id: lcp.h,v 1.2 2006/08/29 18:53:47 wolti Exp $
- */
-
-#ifndef LCP_H
-#define LCP_H
-
-
-/*************************
-*** PUBLIC DEFINITIONS ***
-*************************/
-/*
- * Options.
- */
-#define CI_MRU         1       /* Maximum Receive Unit */
-#define CI_ASYNCMAP    2       /* Async Control Character Map */
-#define CI_AUTHTYPE    3       /* Authentication Type */
-#define CI_QUALITY     4       /* Quality Protocol */
-#define CI_MAGICNUMBER 5       /* Magic Number */
-#define CI_PCOMPRESSION        7       /* Protocol Field Compression */
-#define CI_ACCOMPRESSION 8     /* Address/Control Field Compression */
-#define CI_CALLBACK    13      /* callback */
-#define CI_MRRU                17      /* max reconstructed receive unit; multilink */
-#define CI_SSNHF       18      /* short sequence numbers for multilink */
-#define CI_EPDISC      19      /* endpoint discriminator */
-
-/*
- * LCP-specific packet types.
- */
-#define PROTREJ                8       /* Protocol Reject */
-#define ECHOREQ                9       /* Echo Request */
-#define ECHOREP                10      /* Echo Reply */
-#define DISCREQ                11      /* Discard Request */
-#define CBCP_OPT       6       /* Use callback control protocol */
-
-
-/************************
-*** PUBLIC DATA TYPES ***
-************************/
-
-/*
- * The state of options is described by an lcp_options structure.
- */
-typedef struct lcp_options {
-    u_int passive : 1;                 /* Don't die if we don't get a response */
-    u_int silent : 1;                          /* Wait for the other end to start first */
-    u_int restart : 1;                 /* Restart vs. exit after close */
-    u_int neg_mru : 1;                 /* Negotiate the MRU? */
-    u_int neg_asyncmap : 1;            /* Negotiate the async map? */
-    u_int neg_upap : 1;                        /* Ask for UPAP authentication? */
-    u_int neg_chap : 1;                        /* Ask for CHAP authentication? */
-    u_int neg_magicnumber : 1; /* Ask for magic number? */
-    u_int neg_pcompression : 1;        /* HDLC Protocol Field Compression? */
-    u_int neg_accompression : 1;       /* HDLC Address/Control Field Compression? */
-    u_int neg_lqr : 1;                 /* Negotiate use of Link Quality Reports */
-    u_int neg_cbcp : 1;                        /* Negotiate use of CBCP */
-#ifdef PPP_MULTILINK
-    u_int neg_mrru : 1;                        /* Negotiate multilink MRRU */
-    u_int neg_ssnhf : 1;               /* Negotiate short sequence numbers */
-    u_int neg_endpoint : 1;            /* Negotiate endpoint discriminator */
-#endif
-    u_short mru;                       /* Value of MRU */
-#ifdef PPP_MULTILINK
-    u_short mrru;                      /* Value of MRRU, and multilink enable */
-#endif
-    u_char chap_mdtype;                        /* which MD type (hashing algorithm) */
-    u32_t asyncmap;                    /* Value of async map */
-    u32_t magicnumber;
-    int numloops;                              /* Number of loops during magic number neg. */
-    u32_t lqr_period;          /* Reporting period for LQR 1/100ths second */
-#ifdef PPP_MULTILINK
-    struct epdisc endpoint;    /* endpoint discriminator */
-#endif
-} lcp_options;
-
-/*
- * Values for phase from BSD pppd.h based on RFC 1661.
- */
-typedef enum {
-       PHASE_DEAD = 0,
-       PHASE_INITIALIZE,
-       PHASE_ESTABLISH,
-       PHASE_AUTHENTICATE,
-       PHASE_CALLBACK,
-       PHASE_NETWORK,
-       PHASE_TERMINATE
-} LinkPhase;
-
-
-/*****************************
-*** PUBLIC DATA STRUCTURES ***
-*****************************/
-
-extern LinkPhase lcp_phase[NUM_PPP];   /* Phase of link session (RFC 1661) */
-extern lcp_options lcp_wantoptions[];
-extern lcp_options lcp_gotoptions[];
-extern lcp_options lcp_allowoptions[];
-extern lcp_options lcp_hisoptions[];
-extern ext_accm xmit_accm[];
-
-
-/***********************
-*** PUBLIC FUNCTIONS ***
-***********************/
-
-void lcp_init (int);
-void lcp_open (int);
-void lcp_close (int, char *);
-void lcp_lowerup (int);
-void lcp_lowerdown (int);
-void lcp_sprotrej (int, u_char *, int);        /* send protocol reject */
-
-extern struct protent lcp_protent;
-
-/* Default number of times we receive our magic number from the peer
-   before deciding the link is looped-back. */
-#define DEFLOOPBACKFAIL        10
-
-#endif /* LCP_H */
-
+/*****************************************************************************\r
+* lcp.h - Network Link Control Protocol header file.\r
+*\r
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.\r
+* portions Copyright (c) 1997 Global Election Systems Inc.\r
+*\r
+* The authors hereby grant permission to use, copy, modify, distribute,\r
+* and license this software and its documentation for any purpose, provided\r
+* that existing copyright notices are retained in all copies and that this\r
+* notice and the following disclaimer are included verbatim in any \r
+* distributions. No written agreement, license, or royalty fee is required\r
+* for any of the authorized uses.\r
+*\r
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR\r
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+*\r
+******************************************************************************\r
+* REVISION HISTORY\r
+*\r
+* 03-01-01 Marc Boucher <marc@mbsi.ca>\r
+*   Ported to lwIP.\r
+* 97-11-05 Guy Lancaster <glanca@gesn.com>, Global Election Systems Inc.\r
+*      Original derived from BSD codes.\r
+*****************************************************************************/\r
+/*\r
+ * lcp.h - Link Control Protocol definitions.\r
+ *\r
+ * Copyright (c) 1989 Carnegie Mellon University.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms are permitted\r
+ * provided that the above copyright notice and this paragraph are\r
+ * duplicated in all such forms and that any documentation,\r
+ * advertising materials, and other materials related to such\r
+ * distribution and use acknowledge that the software was developed\r
+ * by Carnegie Mellon University.  The name of the\r
+ * University may not be used to endorse or promote products derived\r
+ * from this software without specific prior written permission.\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR\r
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r
+ *\r
+ * $Id: lcp.h,v 1.2 2006/08/29 18:53:47 wolti Exp $\r
+ */\r
+\r
+#ifndef LCP_H\r
+#define LCP_H\r
+\r
+\r
+/*************************\r
+*** PUBLIC DEFINITIONS ***\r
+*************************/\r
+/*\r
+ * Options.\r
+ */\r
+#define CI_MRU         1       /* Maximum Receive Unit */\r
+#define CI_ASYNCMAP    2       /* Async Control Character Map */\r
+#define CI_AUTHTYPE    3       /* Authentication Type */\r
+#define CI_QUALITY     4       /* Quality Protocol */\r
+#define CI_MAGICNUMBER 5       /* Magic Number */\r
+#define CI_PCOMPRESSION        7       /* Protocol Field Compression */\r
+#define CI_ACCOMPRESSION 8     /* Address/Control Field Compression */\r
+#define CI_CALLBACK    13      /* callback */\r
+#define CI_MRRU                17      /* max reconstructed receive unit; multilink */\r
+#define CI_SSNHF       18      /* short sequence numbers for multilink */\r
+#define CI_EPDISC      19      /* endpoint discriminator */\r
+\r
+/*\r
+ * LCP-specific packet types.\r
+ */\r
+#define PROTREJ                8       /* Protocol Reject */\r
+#define ECHOREQ                9       /* Echo Request */\r
+#define ECHOREP                10      /* Echo Reply */\r
+#define DISCREQ                11      /* Discard Request */\r
+#define CBCP_OPT       6       /* Use callback control protocol */\r
+\r
+\r
+/************************\r
+*** PUBLIC DATA TYPES ***\r
+************************/\r
+\r
+/*\r
+ * The state of options is described by an lcp_options structure.\r
+ */\r
+typedef struct lcp_options {\r
+    u_int passive : 1;                 /* Don't die if we don't get a response */\r
+    u_int silent : 1;                          /* Wait for the other end to start first */\r
+    u_int restart : 1;                 /* Restart vs. exit after close */\r
+    u_int neg_mru : 1;                 /* Negotiate the MRU? */\r
+    u_int neg_asyncmap : 1;            /* Negotiate the async map? */\r
+    u_int neg_upap : 1;                        /* Ask for UPAP authentication? */\r
+    u_int neg_chap : 1;                        /* Ask for CHAP authentication? */\r
+    u_int neg_magicnumber : 1; /* Ask for magic number? */\r
+    u_int neg_pcompression : 1;        /* HDLC Protocol Field Compression? */\r
+    u_int neg_accompression : 1;       /* HDLC Address/Control Field Compression? */\r
+    u_int neg_lqr : 1;                 /* Negotiate use of Link Quality Reports */\r
+    u_int neg_cbcp : 1;                        /* Negotiate use of CBCP */\r
+#ifdef PPP_MULTILINK\r
+    u_int neg_mrru : 1;                        /* Negotiate multilink MRRU */\r
+    u_int neg_ssnhf : 1;               /* Negotiate short sequence numbers */\r
+    u_int neg_endpoint : 1;            /* Negotiate endpoint discriminator */\r
+#endif\r
+    u_short mru;                       /* Value of MRU */\r
+#ifdef PPP_MULTILINK\r
+    u_short mrru;                      /* Value of MRRU, and multilink enable */\r
+#endif\r
+    u_char chap_mdtype;                        /* which MD type (hashing algorithm) */\r
+    u32_t asyncmap;                    /* Value of async map */\r
+    u32_t magicnumber;\r
+    int numloops;                              /* Number of loops during magic number neg. */\r
+    u32_t lqr_period;          /* Reporting period for LQR 1/100ths second */\r
+#ifdef PPP_MULTILINK\r
+    struct epdisc endpoint;    /* endpoint discriminator */\r
+#endif\r
+} lcp_options;\r
+\r
+/*\r
+ * Values for phase from BSD pppd.h based on RFC 1661.\r
+ */\r
+typedef enum {\r
+       PHASE_DEAD = 0,\r
+       PHASE_INITIALIZE,\r
+       PHASE_ESTABLISH,\r
+       PHASE_AUTHENTICATE,\r
+       PHASE_CALLBACK,\r
+       PHASE_NETWORK,\r
+       PHASE_TERMINATE\r
+} LinkPhase;\r
+\r
+\r
+/*****************************\r
+*** PUBLIC DATA STRUCTURES ***\r
+*****************************/\r
+\r
+extern LinkPhase lcp_phase[NUM_PPP];   /* Phase of link session (RFC 1661) */\r
+extern lcp_options lcp_wantoptions[];\r
+extern lcp_options lcp_gotoptions[];\r
+extern lcp_options lcp_allowoptions[];\r
+extern lcp_options lcp_hisoptions[];\r
+extern ext_accm xmit_accm[];\r
+\r
+\r
+/***********************\r
+*** PUBLIC FUNCTIONS ***\r
+***********************/\r
+\r
+void lcp_init (int);\r
+void lcp_open (int);\r
+void lcp_close (int, char *);\r
+void lcp_lowerup (int);\r
+void lcp_lowerdown (int);\r
+void lcp_sprotrej (int, u_char *, int);        /* send protocol reject */\r
+\r
+extern struct protent lcp_protent;\r
+\r
+/* Default number of times we receive our magic number from the peer\r
+   before deciding the link is looped-back. */\r
+#define DEFLOOPBACKFAIL        10\r
+\r
+#endif /* LCP_H */\r
+\r
index 427401691296a2bf56926fde59faf768e2127bf8..6e9d4753867a89cee2b0682ec0f549d8429410f4 100644 (file)
@@ -1,79 +1,79 @@
-/*****************************************************************************
-* magic.c - Network Random Number Generator program file.
-*
-* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
-* portions Copyright (c) 1997 by Global Election Systems Inc.
-*
-* The authors hereby grant permission to use, copy, modify, distribute,
-* and license this software and its documentation for any purpose, provided
-* that existing copyright notices are retained in all copies and that this
-* notice and the following disclaimer are included verbatim in any 
-* distributions. No written agreement, license, or royalty fee is required
-* for any of the authorized uses.
-*
-* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *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 CONTRIBUTORS 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.
-*
-******************************************************************************
-* REVISION HISTORY
-*
-* 03-01-01 Marc Boucher <marc@mbsi.ca>
-*   Ported to lwIP.
-* 97-12-04 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
-*      Original based on BSD magic.c.
-*****************************************************************************/
-/*
- * magic.c - PPP Magic Number routines.
- *
- * Copyright (c) 1989 Carnegie Mellon University.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by Carnegie Mellon University.  The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include "ppp.h"
-#include "randm.h"
-#include "magic.h"
-
-
-/***********************************/
-/*** PUBLIC FUNCTION DEFINITIONS ***/
-/***********************************/
-/*
- * magicInit - Initialize the magic number generator.
- *
- * Since we use another random number generator that has its own
- * initialization, we do nothing here.
- */
-void magicInit()
-{
-       return;
-}
-
-/*
- * magic - Returns the next magic number.
- */
-u32_t magic()
-{
-    return avRandom();
-}
-
-
+/*****************************************************************************\r
+* magic.c - Network Random Number Generator program file.\r
+*\r
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.\r
+* portions Copyright (c) 1997 by Global Election Systems Inc.\r
+*\r
+* The authors hereby grant permission to use, copy, modify, distribute,\r
+* and license this software and its documentation for any purpose, provided\r
+* that existing copyright notices are retained in all copies and that this\r
+* notice and the following disclaimer are included verbatim in any \r
+* distributions. No written agreement, license, or royalty fee is required\r
+* for any of the authorized uses.\r
+*\r
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR\r
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+*\r
+******************************************************************************\r
+* REVISION HISTORY\r
+*\r
+* 03-01-01 Marc Boucher <marc@mbsi.ca>\r
+*   Ported to lwIP.\r
+* 97-12-04 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.\r
+*      Original based on BSD magic.c.\r
+*****************************************************************************/\r
+/*\r
+ * magic.c - PPP Magic Number routines.\r
+ *\r
+ * Copyright (c) 1989 Carnegie Mellon University.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms are permitted\r
+ * provided that the above copyright notice and this paragraph are\r
+ * duplicated in all such forms and that any documentation,\r
+ * advertising materials, and other materials related to such\r
+ * distribution and use acknowledge that the software was developed\r
+ * by Carnegie Mellon University.  The name of the\r
+ * University may not be used to endorse or promote products derived\r
+ * from this software without specific prior written permission.\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR\r
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r
+ */\r
+\r
+#include "ppp.h"\r
+#include "randm.h"\r
+#include "magic.h"\r
+\r
+\r
+/***********************************/\r
+/*** PUBLIC FUNCTION DEFINITIONS ***/\r
+/***********************************/\r
+/*\r
+ * magicInit - Initialize the magic number generator.\r
+ *\r
+ * Since we use another random number generator that has its own\r
+ * initialization, we do nothing here.\r
+ */\r
+void magicInit()\r
+{\r
+       return;\r
+}\r
+\r
+/*\r
+ * magic - Returns the next magic number.\r
+ */\r
+u32_t magic()\r
+{\r
+    return avRandom();\r
+}\r
+\r
+\r
index f8a981728f5e35c181d1ea1e5a3a96c4699576d2..067235eae223ed2014d2babd59b20a1d005a6e62 100644 (file)
@@ -1,64 +1,64 @@
-/*****************************************************************************
-* magic.h - Network Random Number Generator header file.
-*
-* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
-* portions Copyright (c) 1997 Global Election Systems Inc.
-*
-* The authors hereby grant permission to use, copy, modify, distribute,
-* and license this software and its documentation for any purpose, provided
-* that existing copyright notices are retained in all copies and that this
-* notice and the following disclaimer are included verbatim in any 
-* distributions. No written agreement, license, or royalty fee is required
-* for any of the authorized uses.
-*
-* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *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 CONTRIBUTORS 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.
-*
-******************************************************************************
-* REVISION HISTORY
-*
-* 03-01-01 Marc Boucher <marc@mbsi.ca>
-*   Ported to lwIP.
-* 97-12-04 Guy Lancaster <glanca@gesn.com>, Global Election Systems Inc.
-*   Original derived from BSD codes.
-*****************************************************************************/
-/*
- * magic.h - PPP Magic Number definitions.
- *
- * Copyright (c) 1989 Carnegie Mellon University.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by Carnegie Mellon University.  The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * $Id: magic.h,v 1.2 2006/08/29 18:53:47 wolti Exp $
- */
-
-#ifndef MAGIC_H
-#define MAGIC_H
-
-/*****************************************************************************
-************************** PUBLIC FUNCTIONS **********************************
-*****************************************************************************/
-
-void magicInit(void);   /* Initialize the magic number generator */
-u32_t magic(void);  /* Returns the next magic number */
-
-#endif /* MAGIC_H */
+/*****************************************************************************\r
+* magic.h - Network Random Number Generator header file.\r
+*\r
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.\r
+* portions Copyright (c) 1997 Global Election Systems Inc.\r
+*\r
+* The authors hereby grant permission to use, copy, modify, distribute,\r
+* and license this software and its documentation for any purpose, provided\r
+* that existing copyright notices are retained in all copies and that this\r
+* notice and the following disclaimer are included verbatim in any \r
+* distributions. No written agreement, license, or royalty fee is required\r
+* for any of the authorized uses.\r
+*\r
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR\r
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+*\r
+******************************************************************************\r
+* REVISION HISTORY\r
+*\r
+* 03-01-01 Marc Boucher <marc@mbsi.ca>\r
+*   Ported to lwIP.\r
+* 97-12-04 Guy Lancaster <glanca@gesn.com>, Global Election Systems Inc.\r
+*   Original derived from BSD codes.\r
+*****************************************************************************/\r
+/*\r
+ * magic.h - PPP Magic Number definitions.\r
+ *\r
+ * Copyright (c) 1989 Carnegie Mellon University.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms are permitted\r
+ * provided that the above copyright notice and this paragraph are\r
+ * duplicated in all such forms and that any documentation,\r
+ * advertising materials, and other materials related to such\r
+ * distribution and use acknowledge that the software was developed\r
+ * by Carnegie Mellon University.  The name of the\r
+ * University may not be used to endorse or promote products derived\r
+ * from this software without specific prior written permission.\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR\r
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r
+ *\r
+ * $Id: magic.h,v 1.2 2006/08/29 18:53:47 wolti Exp $\r
+ */\r
+\r
+#ifndef MAGIC_H\r
+#define MAGIC_H\r
+\r
+/*****************************************************************************\r
+************************** PUBLIC FUNCTIONS **********************************\r
+*****************************************************************************/\r
+\r
+void magicInit(void);   /* Initialize the magic number generator */\r
+u32_t magic(void);  /* Returns the next magic number */\r
+\r
+#endif /* MAGIC_H */\r
index e077cdea5f922dd3a5ba8aa8d2f84abaeb65bb55..488d64af56d57900b263e183150ececd739d0e93 100644 (file)
-/*
- ***********************************************************************
- ** md5.c -- the source code for MD5 routines                         **
- ** RSA Data Security, Inc. MD5 Message-Digest Algorithm              **
- ** Created: 2/17/90 RLR                                              **
- ** Revised: 1/91 SRD,AJ,BSK,JT Reference C ver., 7/10 constant corr. **
- ***********************************************************************
- */
-
-/*
- ***********************************************************************
- ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved.  **
- **                                                                   **
- ** License to copy and use this software is granted provided that    **
- ** it is identified as the "RSA Data Security, Inc. MD5 Message-     **
- ** Digest Algorithm" in all material mentioning or referencing this  **
- ** software or this function.                                        **
- **                                                                   **
- ** License is also granted to make and use derivative works          **
- ** provided that such works are identified as "derived from the RSA  **
- ** Data Security, Inc. MD5 Message-Digest Algorithm" in all          **
- ** material mentioning or referencing the derived work.              **
- **                                                                   **
- ** RSA Data Security, Inc. makes no representations concerning       **
- ** either the merchantability of this software or the suitability    **
- ** of this software for any particular purpose.  It is provided "as  **
- ** is" without express or implied warranty of any kind.              **
- **                                                                   **
- ** These notices must be retained in any copies of any part of this  **
- ** documentation and/or software.                                    **
- ***********************************************************************
- */
-
-#include "ppp.h"
-#include "md5.h"
-#include "pppdebug.h"
-
-#if CHAP_SUPPORT > 0 || MD5_SUPPORT > 0
-
-/*
- ***********************************************************************
- **  Message-digest routines:                                         **
- **  To form the message digest for a message M                       **
- **    (1) Initialize a context buffer mdContext using MD5Init        **
- **    (2) Call MD5Update on mdContext and M                          **
- **    (3) Call MD5Final on mdContext                                 **
- **  The message digest is now in mdContext->digest[0...15]           **
- ***********************************************************************
- */
-
-/* forward declaration */
-static void Transform (u32_t *buf, u32_t *in);
-
-static unsigned char PADDING[64] = {
-  0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-/* F, G, H and I are basic MD5 functions */
-#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
-#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
-#define H(x, y, z) ((x) ^ (y) ^ (z))
-#define I(x, y, z) ((y) ^ ((x) | (~z)))
-
-/* ROTATE_LEFT rotates x left n bits */
-#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
-
-/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */
-/* Rotation is separate from addition to prevent recomputation */
-#define FF(a, b, c, d, x, s, ac) \
-  {(a) += F ((b), (c), (d)) + (x) + (u32_t)(ac); \
-   (a) = ROTATE_LEFT ((a), (s)); \
-   (a) += (b); \
-  }
-#define GG(a, b, c, d, x, s, ac) \
-  {(a) += G ((b), (c), (d)) + (x) + (u32_t)(ac); \
-   (a) = ROTATE_LEFT ((a), (s)); \
-   (a) += (b); \
-  }
-#define HH(a, b, c, d, x, s, ac) \
-  {(a) += H ((b), (c), (d)) + (x) + (u32_t)(ac); \
-   (a) = ROTATE_LEFT ((a), (s)); \
-   (a) += (b); \
-  }
-#define II(a, b, c, d, x, s, ac) \
-  {(a) += I ((b), (c), (d)) + (x) + (u32_t)(ac); \
-   (a) = ROTATE_LEFT ((a), (s)); \
-   (a) += (b); \
-  }
-
-#ifdef __STDC__
-#define UL(x)  x##UL
-#else
-#ifdef WIN32
-#define UL(x)  x##UL
-#else
-#define UL(x)  x
-#endif
-#endif
-
-/* The routine MD5Init initializes the message-digest context
-   mdContext. All fields are set to zero.
- */
-void MD5Init (MD5_CTX *mdContext)
-{
-  mdContext->i[0] = mdContext->i[1] = (u32_t)0;
-
-  /* Load magic initialization constants.
-   */
-  mdContext->buf[0] = (u32_t)0x67452301UL;
-  mdContext->buf[1] = (u32_t)0xefcdab89UL;
-  mdContext->buf[2] = (u32_t)0x98badcfeUL;
-  mdContext->buf[3] = (u32_t)0x10325476UL;
-}
-
-/* The routine MD5Update updates the message-digest context to
-   account for the presence of each of the characters inBuf[0..inLen-1]
-   in the message whose digest is being computed.
- */
-void MD5Update(MD5_CTX *mdContext, unsigned char *inBuf, unsigned int inLen)
-{
-  u32_t in[16];
-  int mdi;
-  unsigned int i, ii;
-
-#if 0
-  ppp_trace(LOG_INFO, "MD5Update: %u:%.*H\n", inLen, MIN(inLen, 20) * 2, inBuf);
-  ppp_trace(LOG_INFO, "MD5Update: %u:%s\n", inLen, inBuf);
-#endif
-  
-  /* compute number of bytes mod 64 */
-  mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
-
-  /* update number of bits */
-  if ((mdContext->i[0] + ((u32_t)inLen << 3)) < mdContext->i[0])
-    mdContext->i[1]++;
-  mdContext->i[0] += ((u32_t)inLen << 3);
-  mdContext->i[1] += ((u32_t)inLen >> 29);
-
-  while (inLen--) {
-    /* add new character to buffer, increment mdi */
-    mdContext->in[mdi++] = *inBuf++;
-
-    /* transform if necessary */
-    if (mdi == 0x40) {
-      for (i = 0, ii = 0; i < 16; i++, ii += 4)
-        in[i] = (((u32_t)mdContext->in[ii+3]) << 24) |
-                (((u32_t)mdContext->in[ii+2]) << 16) |
-                               (((u32_t)mdContext->in[ii+1]) << 8) |
-                ((u32_t)mdContext->in[ii]);
-      Transform (mdContext->buf, in);
-      mdi = 0;
-    }
-  }
-}
-
-/* The routine MD5Final terminates the message-digest computation and
-   ends with the desired message digest in mdContext->digest[0...15].
- */
-void MD5Final (unsigned char hash[], MD5_CTX *mdContext)
-{
-  u32_t in[16];
-  int mdi;
-  unsigned int i, ii;
-  unsigned int padLen;
-
-  /* save number of bits */
-  in[14] = mdContext->i[0];
-  in[15] = mdContext->i[1];
-
-  /* compute number of bytes mod 64 */
-  mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
-
-  /* pad out to 56 mod 64 */
-  padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi);
-  MD5Update (mdContext, PADDING, padLen);
-
-  /* append length in bits and transform */
-  for (i = 0, ii = 0; i < 14; i++, ii += 4)
-    in[i] = (((u32_t)mdContext->in[ii+3]) << 24) |
-            (((u32_t)mdContext->in[ii+2]) << 16) |
-            (((u32_t)mdContext->in[ii+1]) << 8) |
-            ((u32_t)mdContext->in[ii]);
-  Transform (mdContext->buf, in);
-
-  /* store buffer in digest */
-  for (i = 0, ii = 0; i < 4; i++, ii += 4) {
-    mdContext->digest[ii] = (unsigned char)(mdContext->buf[i] & 0xFF);
-       mdContext->digest[ii+1] =
-      (unsigned char)((mdContext->buf[i] >> 8) & 0xFF);
-    mdContext->digest[ii+2] =
-      (unsigned char)((mdContext->buf[i] >> 16) & 0xFF);
-    mdContext->digest[ii+3] =
-      (unsigned char)((mdContext->buf[i] >> 24) & 0xFF);
-  }
-  memcpy(hash, mdContext->digest, 16);
-}
-
-/* Basic MD5 step. Transforms buf based on in.
- */
-static void Transform (u32_t *buf, u32_t *in)
-{
-  u32_t a = buf[0], b = buf[1], c = buf[2], d = buf[3];
-
-  /* Round 1 */
-#define S11 7
-#define S12 12
-#define S13 17
-#define S14 22
-  FF ( a, b, c, d, in[ 0], S11, UL(3614090360)); /* 1 */
-  FF ( d, a, b, c, in[ 1], S12, UL(3905402710)); /* 2 */
-  FF ( c, d, a, b, in[ 2], S13, UL( 606105819)); /* 3 */
-  FF ( b, c, d, a, in[ 3], S14, UL(3250441966)); /* 4 */
-  FF ( a, b, c, d, in[ 4], S11, UL(4118548399)); /* 5 */
-  FF ( d, a, b, c, in[ 5], S12, UL(1200080426)); /* 6 */
-  FF ( c, d, a, b, in[ 6], S13, UL(2821735955)); /* 7 */
-  FF ( b, c, d, a, in[ 7], S14, UL(4249261313)); /* 8 */
-  FF ( a, b, c, d, in[ 8], S11, UL(1770035416)); /* 9 */
-  FF ( d, a, b, c, in[ 9], S12, UL(2336552879)); /* 10 */
-  FF ( c, d, a, b, in[10], S13, UL(4294925233)); /* 11 */
-  FF ( b, c, d, a, in[11], S14, UL(2304563134)); /* 12 */
-  FF ( a, b, c, d, in[12], S11, UL(1804603682)); /* 13 */
-  FF ( d, a, b, c, in[13], S12, UL(4254626195)); /* 14 */
-  FF ( c, d, a, b, in[14], S13, UL(2792965006)); /* 15 */
-  FF ( b, c, d, a, in[15], S14, UL(1236535329)); /* 16 */
-
-  /* Round 2 */
-#define S21 5
-#define S22 9
-#define S23 14
-#define S24 20
-  GG ( a, b, c, d, in[ 1], S21, UL(4129170786)); /* 17 */
-  GG ( d, a, b, c, in[ 6], S22, UL(3225465664)); /* 18 */
-  GG ( c, d, a, b, in[11], S23, UL( 643717713)); /* 19 */
-  GG ( b, c, d, a, in[ 0], S24, UL(3921069994)); /* 20 */
-  GG ( a, b, c, d, in[ 5], S21, UL(3593408605)); /* 21 */
-  GG ( d, a, b, c, in[10], S22, UL(  38016083)); /* 22 */
-  GG ( c, d, a, b, in[15], S23, UL(3634488961)); /* 23 */
-  GG ( b, c, d, a, in[ 4], S24, UL(3889429448)); /* 24 */
-  GG ( a, b, c, d, in[ 9], S21, UL( 568446438)); /* 25 */
-  GG ( d, a, b, c, in[14], S22, UL(3275163606)); /* 26 */
-  GG ( c, d, a, b, in[ 3], S23, UL(4107603335)); /* 27 */
-  GG ( b, c, d, a, in[ 8], S24, UL(1163531501)); /* 28 */
-  GG ( a, b, c, d, in[13], S21, UL(2850285829)); /* 29 */
-  GG ( d, a, b, c, in[ 2], S22, UL(4243563512)); /* 30 */
-  GG ( c, d, a, b, in[ 7], S23, UL(1735328473)); /* 31 */
-  GG ( b, c, d, a, in[12], S24, UL(2368359562)); /* 32 */
-
-  /* Round 3 */
-#define S31 4
-#define S32 11
-#define S33 16
-#define S34 23
-  HH ( a, b, c, d, in[ 5], S31, UL(4294588738)); /* 33 */
-  HH ( d, a, b, c, in[ 8], S32, UL(2272392833)); /* 34 */
-  HH ( c, d, a, b, in[11], S33, UL(1839030562)); /* 35 */
-  HH ( b, c, d, a, in[14], S34, UL(4259657740)); /* 36 */
-  HH ( a, b, c, d, in[ 1], S31, UL(2763975236)); /* 37 */
-  HH ( d, a, b, c, in[ 4], S32, UL(1272893353)); /* 38 */
-  HH ( c, d, a, b, in[ 7], S33, UL(4139469664)); /* 39 */
-  HH ( b, c, d, a, in[10], S34, UL(3200236656)); /* 40 */
-  HH ( a, b, c, d, in[13], S31, UL( 681279174)); /* 41 */
-  HH ( d, a, b, c, in[ 0], S32, UL(3936430074)); /* 42 */
-  HH ( c, d, a, b, in[ 3], S33, UL(3572445317)); /* 43 */
-  HH ( b, c, d, a, in[ 6], S34, UL(  76029189)); /* 44 */
-  HH ( a, b, c, d, in[ 9], S31, UL(3654602809)); /* 45 */
-  HH ( d, a, b, c, in[12], S32, UL(3873151461)); /* 46 */
-  HH ( c, d, a, b, in[15], S33, UL( 530742520)); /* 47 */
-  HH ( b, c, d, a, in[ 2], S34, UL(3299628645)); /* 48 */
-
-  /* Round 4 */
-#define S41 6
-#define S42 10
-#define S43 15
-#define S44 21
-  II ( a, b, c, d, in[ 0], S41, UL(4096336452)); /* 49 */
-  II ( d, a, b, c, in[ 7], S42, UL(1126891415)); /* 50 */
-  II ( c, d, a, b, in[14], S43, UL(2878612391)); /* 51 */
-  II ( b, c, d, a, in[ 5], S44, UL(4237533241)); /* 52 */
-  II ( a, b, c, d, in[12], S41, UL(1700485571)); /* 53 */
-  II ( d, a, b, c, in[ 3], S42, UL(2399980690)); /* 54 */
-  II ( c, d, a, b, in[10], S43, UL(4293915773)); /* 55 */
-  II ( b, c, d, a, in[ 1], S44, UL(2240044497)); /* 56 */
-  II ( a, b, c, d, in[ 8], S41, UL(1873313359)); /* 57 */
-  II ( d, a, b, c, in[15], S42, UL(4264355552)); /* 58 */
-  II ( c, d, a, b, in[ 6], S43, UL(2734768916)); /* 59 */
-  II ( b, c, d, a, in[13], S44, UL(1309151649)); /* 60 */
-  II ( a, b, c, d, in[ 4], S41, UL(4149444226)); /* 61 */
-  II ( d, a, b, c, in[11], S42, UL(3174756917)); /* 62 */
-  II ( c, d, a, b, in[ 2], S43, UL( 718787259)); /* 63 */
-  II ( b, c, d, a, in[ 9], S44, UL(3951481745)); /* 64 */
-
-  buf[0] += a;
-  buf[1] += b;
-  buf[2] += c;
-  buf[3] += d;
-}
-
-#endif
-
+/*\r
+ ***********************************************************************\r
+ ** md5.c -- the source code for MD5 routines                         **\r
+ ** RSA Data Security, Inc. MD5 Message-Digest Algorithm              **\r
+ ** Created: 2/17/90 RLR                                              **\r
+ ** Revised: 1/91 SRD,AJ,BSK,JT Reference C ver., 7/10 constant corr. **\r
+ ***********************************************************************\r
+ */\r
+\r
+/*\r
+ ***********************************************************************\r
+ ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved.  **\r
+ **                                                                   **\r
+ ** License to copy and use this software is granted provided that    **\r
+ ** it is identified as the "RSA Data Security, Inc. MD5 Message-     **\r
+ ** Digest Algorithm" in all material mentioning or referencing this  **\r
+ ** software or this function.                                        **\r
+ **                                                                   **\r
+ ** License is also granted to make and use derivative works          **\r
+ ** provided that such works are identified as "derived from the RSA  **\r
+ ** Data Security, Inc. MD5 Message-Digest Algorithm" in all          **\r
+ ** material mentioning or referencing the derived work.              **\r
+ **                                                                   **\r
+ ** RSA Data Security, Inc. makes no representations concerning       **\r
+ ** either the merchantability of this software or the suitability    **\r
+ ** of this software for any particular purpose.  It is provided "as  **\r
+ ** is" without express or implied warranty of any kind.              **\r
+ **                                                                   **\r
+ ** These notices must be retained in any copies of any part of this  **\r
+ ** documentation and/or software.                                    **\r
+ ***********************************************************************\r
+ */\r
+\r
+#include "ppp.h"\r
+#include "md5.h"\r
+#include "pppdebug.h"\r
+\r
+#if CHAP_SUPPORT > 0 || MD5_SUPPORT > 0\r
+\r
+/*\r
+ ***********************************************************************\r
+ **  Message-digest routines:                                         **\r
+ **  To form the message digest for a message M                       **\r
+ **    (1) Initialize a context buffer mdContext using MD5Init        **\r
+ **    (2) Call MD5Update on mdContext and M                          **\r
+ **    (3) Call MD5Final on mdContext                                 **\r
+ **  The message digest is now in mdContext->digest[0...15]           **\r
+ ***********************************************************************\r
+ */\r
+\r
+/* forward declaration */\r
+static void Transform (u32_t *buf, u32_t *in);\r
+\r
+static unsigned char PADDING[64] = {\r
+  0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\r
+};\r
+\r
+/* F, G, H and I are basic MD5 functions */\r
+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))\r
+#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))\r
+#define H(x, y, z) ((x) ^ (y) ^ (z))\r
+#define I(x, y, z) ((y) ^ ((x) | (~z)))\r
+\r
+/* ROTATE_LEFT rotates x left n bits */\r
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))\r
+\r
+/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */\r
+/* Rotation is separate from addition to prevent recomputation */\r
+#define FF(a, b, c, d, x, s, ac) \\r
+  {(a) += F ((b), (c), (d)) + (x) + (u32_t)(ac); \\r
+   (a) = ROTATE_LEFT ((a), (s)); \\r
+   (a) += (b); \\r
+  }\r
+#define GG(a, b, c, d, x, s, ac) \\r
+  {(a) += G ((b), (c), (d)) + (x) + (u32_t)(ac); \\r
+   (a) = ROTATE_LEFT ((a), (s)); \\r
+   (a) += (b); \\r
+  }\r
+#define HH(a, b, c, d, x, s, ac) \\r
+  {(a) += H ((b), (c), (d)) + (x) + (u32_t)(ac); \\r
+   (a) = ROTATE_LEFT ((a), (s)); \\r
+   (a) += (b); \\r
+  }\r
+#define II(a, b, c, d, x, s, ac) \\r
+  {(a) += I ((b), (c), (d)) + (x) + (u32_t)(ac); \\r
+   (a) = ROTATE_LEFT ((a), (s)); \\r
+   (a) += (b); \\r
+  }\r
+\r
+#ifdef __STDC__\r
+#define UL(x)  x##UL\r
+#else\r
+#ifdef WIN32\r
+#define UL(x)  x##UL\r
+#else\r
+#define UL(x)  x\r
+#endif\r
+#endif\r
+\r
+/* The routine MD5Init initializes the message-digest context\r
+   mdContext. All fields are set to zero.\r
+ */\r
+void MD5Init (MD5_CTX *mdContext)\r
+{\r
+  mdContext->i[0] = mdContext->i[1] = (u32_t)0;\r
+\r
+  /* Load magic initialization constants.\r
+   */\r
+  mdContext->buf[0] = (u32_t)0x67452301UL;\r
+  mdContext->buf[1] = (u32_t)0xefcdab89UL;\r
+  mdContext->buf[2] = (u32_t)0x98badcfeUL;\r
+  mdContext->buf[3] = (u32_t)0x10325476UL;\r
+}\r
+\r
+/* The routine MD5Update updates the message-digest context to\r
+   account for the presence of each of the characters inBuf[0..inLen-1]\r
+   in the message whose digest is being computed.\r
+ */\r
+void MD5Update(MD5_CTX *mdContext, unsigned char *inBuf, unsigned int inLen)\r
+{\r
+  u32_t in[16];\r
+  int mdi;\r
+  unsigned int i, ii;\r
+\r
+#if 0\r
+  ppp_trace(LOG_INFO, "MD5Update: %u:%.*H\n", inLen, MIN(inLen, 20) * 2, inBuf);\r
+  ppp_trace(LOG_INFO, "MD5Update: %u:%s\n", inLen, inBuf);\r
+#endif\r
+  \r
+  /* compute number of bytes mod 64 */\r
+  mdi = (int)((mdContext->i[0] >> 3) & 0x3F);\r
+\r
+  /* update number of bits */\r
+  if ((mdContext->i[0] + ((u32_t)inLen << 3)) < mdContext->i[0])\r
+    mdContext->i[1]++;\r
+  mdContext->i[0] += ((u32_t)inLen << 3);\r
+  mdContext->i[1] += ((u32_t)inLen >> 29);\r
+\r
+  while (inLen--) {\r
+    /* add new character to buffer, increment mdi */\r
+    mdContext->in[mdi++] = *inBuf++;\r
+\r
+    /* transform if necessary */\r
+    if (mdi == 0x40) {\r
+      for (i = 0, ii = 0; i < 16; i++, ii += 4)\r
+        in[i] = (((u32_t)mdContext->in[ii+3]) << 24) |\r
+                (((u32_t)mdContext->in[ii+2]) << 16) |\r
+                               (((u32_t)mdContext->in[ii+1]) << 8) |\r
+                ((u32_t)mdContext->in[ii]);\r
+      Transform (mdContext->buf, in);\r
+      mdi = 0;\r
+    }\r
+  }\r
+}\r
+\r
+/* The routine MD5Final terminates the message-digest computation and\r
+   ends with the desired message digest in mdContext->digest[0...15].\r
+ */\r
+void MD5Final (unsigned char hash[], MD5_CTX *mdContext)\r
+{\r
+  u32_t in[16];\r
+  int mdi;\r
+  unsigned int i, ii;\r
+  unsigned int padLen;\r
+\r
+  /* save number of bits */\r
+  in[14] = mdContext->i[0];\r
+  in[15] = mdContext->i[1];\r
+\r
+  /* compute number of bytes mod 64 */\r
+  mdi = (int)((mdContext->i[0] >> 3) & 0x3F);\r
+\r
+  /* pad out to 56 mod 64 */\r
+  padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi);\r
+  MD5Update (mdContext, PADDING, padLen);\r
+\r
+  /* append length in bits and transform */\r
+  for (i = 0, ii = 0; i < 14; i++, ii += 4)\r
+    in[i] = (((u32_t)mdContext->in[ii+3]) << 24) |\r
+            (((u32_t)mdContext->in[ii+2]) << 16) |\r
+            (((u32_t)mdContext->in[ii+1]) << 8) |\r
+            ((u32_t)mdContext->in[ii]);\r
+  Transform (mdContext->buf, in);\r
+\r
+  /* store buffer in digest */\r
+  for (i = 0, ii = 0; i < 4; i++, ii += 4) {\r
+    mdContext->digest[ii] = (unsigned char)(mdContext->buf[i] & 0xFF);\r
+       mdContext->digest[ii+1] =\r
+      (unsigned char)((mdContext->buf[i] >> 8) & 0xFF);\r
+    mdContext->digest[ii+2] =\r
+      (unsigned char)((mdContext->buf[i] >> 16) & 0xFF);\r
+    mdContext->digest[ii+3] =\r
+      (unsigned char)((mdContext->buf[i] >> 24) & 0xFF);\r
+  }\r
+  memcpy(hash, mdContext->digest, 16);\r
+}\r
+\r
+/* Basic MD5 step. Transforms buf based on in.\r
+ */\r
+static void Transform (u32_t *buf, u32_t *in)\r
+{\r
+  u32_t a = buf[0], b = buf[1], c = buf[2], d = buf[3];\r
+\r
+  /* Round 1 */\r
+#define S11 7\r
+#define S12 12\r
+#define S13 17\r
+#define S14 22\r
+  FF ( a, b, c, d, in[ 0], S11, UL(3614090360)); /* 1 */\r
+  FF ( d, a, b, c, in[ 1], S12, UL(3905402710)); /* 2 */\r
+  FF ( c, d, a, b, in[ 2], S13, UL( 606105819)); /* 3 */\r
+  FF ( b, c, d, a, in[ 3], S14, UL(3250441966)); /* 4 */\r
+  FF ( a, b, c, d, in[ 4], S11, UL(4118548399)); /* 5 */\r
+  FF ( d, a, b, c, in[ 5], S12, UL(1200080426)); /* 6 */\r
+  FF ( c, d, a, b, in[ 6], S13, UL(2821735955)); /* 7 */\r
+  FF ( b, c, d, a, in[ 7], S14, UL(4249261313)); /* 8 */\r
+  FF ( a, b, c, d, in[ 8], S11, UL(1770035416)); /* 9 */\r
+  FF ( d, a, b, c, in[ 9], S12, UL(2336552879)); /* 10 */\r
+  FF ( c, d, a, b, in[10], S13, UL(4294925233)); /* 11 */\r
+  FF ( b, c, d, a, in[11], S14, UL(2304563134)); /* 12 */\r
+  FF ( a, b, c, d, in[12], S11, UL(1804603682)); /* 13 */\r
+  FF ( d, a, b, c, in[13], S12, UL(4254626195)); /* 14 */\r
+  FF ( c, d, a, b, in[14], S13, UL(2792965006)); /* 15 */\r
+  FF ( b, c, d, a, in[15], S14, UL(1236535329)); /* 16 */\r
+\r
+  /* Round 2 */\r
+#define S21 5\r
+#define S22 9\r
+#define S23 14\r
+#define S24 20\r
+  GG ( a, b, c, d, in[ 1], S21, UL(4129170786)); /* 17 */\r
+  GG ( d, a, b, c, in[ 6], S22, UL(3225465664)); /* 18 */\r
+  GG ( c, d, a, b, in[11], S23, UL( 643717713)); /* 19 */\r
+  GG ( b, c, d, a, in[ 0], S24, UL(3921069994)); /* 20 */\r
+  GG ( a, b, c, d, in[ 5], S21, UL(3593408605)); /* 21 */\r
+  GG ( d, a, b, c, in[10], S22, UL(  38016083)); /* 22 */\r
+  GG ( c, d, a, b, in[15], S23, UL(3634488961)); /* 23 */\r
+  GG ( b, c, d, a, in[ 4], S24, UL(3889429448)); /* 24 */\r
+  GG ( a, b, c, d, in[ 9], S21, UL( 568446438)); /* 25 */\r
+  GG ( d, a, b, c, in[14], S22, UL(3275163606)); /* 26 */\r
+  GG ( c, d, a, b, in[ 3], S23, UL(4107603335)); /* 27 */\r
+  GG ( b, c, d, a, in[ 8], S24, UL(1163531501)); /* 28 */\r
+  GG ( a, b, c, d, in[13], S21, UL(2850285829)); /* 29 */\r
+  GG ( d, a, b, c, in[ 2], S22, UL(4243563512)); /* 30 */\r
+  GG ( c, d, a, b, in[ 7], S23, UL(1735328473)); /* 31 */\r
+  GG ( b, c, d, a, in[12], S24, UL(2368359562)); /* 32 */\r
+\r
+  /* Round 3 */\r
+#define S31 4\r
+#define S32 11\r
+#define S33 16\r
+#define S34 23\r
+  HH ( a, b, c, d, in[ 5], S31, UL(4294588738)); /* 33 */\r
+  HH ( d, a, b, c, in[ 8], S32, UL(2272392833)); /* 34 */\r
+  HH ( c, d, a, b, in[11], S33, UL(1839030562)); /* 35 */\r
+  HH ( b, c, d, a, in[14], S34, UL(4259657740)); /* 36 */\r
+  HH ( a, b, c, d, in[ 1], S31, UL(2763975236)); /* 37 */\r
+  HH ( d, a, b, c, in[ 4], S32, UL(1272893353)); /* 38 */\r
+  HH ( c, d, a, b, in[ 7], S33, UL(4139469664)); /* 39 */\r
+  HH ( b, c, d, a, in[10], S34, UL(3200236656)); /* 40 */\r
+  HH ( a, b, c, d, in[13], S31, UL( 681279174)); /* 41 */\r
+  HH ( d, a, b, c, in[ 0], S32, UL(3936430074)); /* 42 */\r
+  HH ( c, d, a, b, in[ 3], S33, UL(3572445317)); /* 43 */\r
+  HH ( b, c, d, a, in[ 6], S34, UL(  76029189)); /* 44 */\r
+  HH ( a, b, c, d, in[ 9], S31, UL(3654602809)); /* 45 */\r
+  HH ( d, a, b, c, in[12], S32, UL(3873151461)); /* 46 */\r
+  HH ( c, d, a, b, in[15], S33, UL( 530742520)); /* 47 */\r
+  HH ( b, c, d, a, in[ 2], S34, UL(3299628645)); /* 48 */\r
+\r
+  /* Round 4 */\r
+#define S41 6\r
+#define S42 10\r
+#define S43 15\r
+#define S44 21\r
+  II ( a, b, c, d, in[ 0], S41, UL(4096336452)); /* 49 */\r
+  II ( d, a, b, c, in[ 7], S42, UL(1126891415)); /* 50 */\r
+  II ( c, d, a, b, in[14], S43, UL(2878612391)); /* 51 */\r
+  II ( b, c, d, a, in[ 5], S44, UL(4237533241)); /* 52 */\r
+  II ( a, b, c, d, in[12], S41, UL(1700485571)); /* 53 */\r
+  II ( d, a, b, c, in[ 3], S42, UL(2399980690)); /* 54 */\r
+  II ( c, d, a, b, in[10], S43, UL(4293915773)); /* 55 */\r
+  II ( b, c, d, a, in[ 1], S44, UL(2240044497)); /* 56 */\r
+  II ( a, b, c, d, in[ 8], S41, UL(1873313359)); /* 57 */\r
+  II ( d, a, b, c, in[15], S42, UL(4264355552)); /* 58 */\r
+  II ( c, d, a, b, in[ 6], S43, UL(2734768916)); /* 59 */\r
+  II ( b, c, d, a, in[13], S44, UL(1309151649)); /* 60 */\r
+  II ( a, b, c, d, in[ 4], S41, UL(4149444226)); /* 61 */\r
+  II ( d, a, b, c, in[11], S42, UL(3174756917)); /* 62 */\r
+  II ( c, d, a, b, in[ 2], S43, UL( 718787259)); /* 63 */\r
+  II ( b, c, d, a, in[ 9], S44, UL(3951481745)); /* 64 */\r
+\r
+  buf[0] += a;\r
+  buf[1] += b;\r
+  buf[2] += c;\r
+  buf[3] += d;\r
+}\r
+\r
+#endif\r
+\r
index 0e81cdc34bd8e7d6874fd853ade7e61a92871432..83d318cfba42f35ca6332d17cd3d9d5f9cf542b9 100644 (file)
@@ -1,55 +1,55 @@
-/*
- ***********************************************************************
- ** md5.h -- header file for implementation of MD5                    **
- ** RSA Data Security, Inc. MD5 Message-Digest Algorithm              **
- ** Created: 2/17/90 RLR                                              **
- ** Revised: 12/27/90 SRD,AJ,BSK,JT Reference C version               **
- ** Revised (for MD5): RLR 4/27/91                                    **
- **   -- G modified to have y&~z instead of y&z                       **
- **   -- FF, GG, HH modified to add in last register done             **
- **   -- Access pattern: round 2 works mod 5, round 3 works mod 3     **
- **   -- distinct additive constant for each step                     **
- **   -- round 4 added, working mod 7                                 **
- ***********************************************************************
- */
-
-/*
- ***********************************************************************
- ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved.  **
- **                                                                   **
- ** License to copy and use this software is granted provided that    **
- ** it is identified as the "RSA Data Security, Inc. MD5 Message-     **
- ** Digest Algorithm" in all material mentioning or referencing this  **
- ** software or this function.                                        **
- **                                                                   **
- ** License is also granted to make and use derivative works          **
- ** provided that such works are identified as "derived from the RSA  **
- ** Data Security, Inc. MD5 Message-Digest Algorithm" in all          **
- ** material mentioning or referencing the derived work.              **
- **                                                                   **
- ** RSA Data Security, Inc. makes no representations concerning       **
- ** either the merchantability of this software or the suitability    **
- ** of this software for any particular purpose.  It is provided "as  **
- ** is" without express or implied warranty of any kind.              **
- **                                                                   **
- ** These notices must be retained in any copies of any part of this  **
- ** documentation and/or software.                                    **
- ***********************************************************************
- */
-
-#ifndef MD5_H
-#define MD5_H
-
-/* Data structure for MD5 (Message-Digest) computation */
-typedef struct {
-  u32_t i[2];                   /* number of _bits_ handled mod 2^64 */
-  u32_t buf[4];                                    /* scratch buffer */
-  unsigned char in[64];                              /* input buffer */
-  unsigned char digest[16];     /* actual digest after MD5Final call */
-} MD5_CTX;
-
-void MD5Init (MD5_CTX *mdContext);
-void MD5Update (MD5_CTX *mdContext, unsigned char *inBuf, unsigned int inLen);
-void MD5Final (unsigned char hash[], MD5_CTX *mdContext);
-
-#endif /* MD5_H */
+/*\r
+ ***********************************************************************\r
+ ** md5.h -- header file for implementation of MD5                    **\r
+ ** RSA Data Security, Inc. MD5 Message-Digest Algorithm              **\r
+ ** Created: 2/17/90 RLR                                              **\r
+ ** Revised: 12/27/90 SRD,AJ,BSK,JT Reference C version               **\r
+ ** Revised (for MD5): RLR 4/27/91                                    **\r
+ **   -- G modified to have y&~z instead of y&z                       **\r
+ **   -- FF, GG, HH modified to add in last register done             **\r
+ **   -- Access pattern: round 2 works mod 5, round 3 works mod 3     **\r
+ **   -- distinct additive constant for each step                     **\r
+ **   -- round 4 added, working mod 7                                 **\r
+ ***********************************************************************\r
+ */\r
+\r
+/*\r
+ ***********************************************************************\r
+ ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved.  **\r
+ **                                                                   **\r
+ ** License to copy and use this software is granted provided that    **\r
+ ** it is identified as the "RSA Data Security, Inc. MD5 Message-     **\r
+ ** Digest Algorithm" in all material mentioning or referencing this  **\r
+ ** software or this function.                                        **\r
+ **                                                                   **\r
+ ** License is also granted to make and use derivative works          **\r
+ ** provided that such works are identified as "derived from the RSA  **\r
+ ** Data Security, Inc. MD5 Message-Digest Algorithm" in all          **\r
+ ** material mentioning or referencing the derived work.              **\r
+ **                                                                   **\r
+ ** RSA Data Security, Inc. makes no representations concerning       **\r
+ ** either the merchantability of this software or the suitability    **\r
+ ** of this software for any particular purpose.  It is provided "as  **\r
+ ** is" without express or implied warranty of any kind.              **\r
+ **                                                                   **\r
+ ** These notices must be retained in any copies of any part of this  **\r
+ ** documentation and/or software.                                    **\r
+ ***********************************************************************\r
+ */\r
+\r
+#ifndef MD5_H\r
+#define MD5_H\r
+\r
+/* Data structure for MD5 (Message-Digest) computation */\r
+typedef struct {\r
+  u32_t i[2];                   /* number of _bits_ handled mod 2^64 */\r
+  u32_t buf[4];                                    /* scratch buffer */\r
+  unsigned char in[64];                              /* input buffer */\r
+  unsigned char digest[16];     /* actual digest after MD5Final call */\r
+} MD5_CTX;\r
+\r
+void MD5Init (MD5_CTX *mdContext);\r
+void MD5Update (MD5_CTX *mdContext, unsigned char *inBuf, unsigned int inLen);\r
+void MD5Final (unsigned char hash[], MD5_CTX *mdContext);\r
+\r
+#endif /* MD5_H */\r
index 23e438ff2901b6b5cd397d44f3cdb06801875396..4b105ef3ecb5f55e28e774ed5e0bf850ad50cec9 100644 (file)
-/*****************************************************************************
-* pap.c - Network Password Authentication Protocol program file.
-*
-* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
-* portions Copyright (c) 1997 by Global Election Systems Inc.
-*
-* The authors hereby grant permission to use, copy, modify, distribute,
-* and license this software and its documentation for any purpose, provided
-* that existing copyright notices are retained in all copies and that this
-* notice and the following disclaimer are included verbatim in any 
-* distributions. No written agreement, license, or royalty fee is required
-* for any of the authorized uses.
-*
-* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *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 CONTRIBUTORS 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.
-*
-******************************************************************************
-* REVISION HISTORY
-*
-* 03-01-01 Marc Boucher <marc@mbsi.ca>
-*   Ported to lwIP.
-* 97-12-12 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
-*      Original.
-*****************************************************************************/
-/*
- * upap.c - User/Password Authentication Protocol.
- *
- * Copyright (c) 1989 Carnegie Mellon University.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by Carnegie Mellon University.  The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include "ppp.h"
-#include "auth.h"
-#include "pap.h"
-#include "pppdebug.h"
-
-
-#if PAP_SUPPORT > 0
-
-/***********************************/
-/*** LOCAL FUNCTION DECLARATIONS ***/
-/***********************************/
-/*
- * Protocol entry points.
- */
-static void upap_init (int);
-static void upap_lowerup (int);
-static void upap_lowerdown (int);
-static void upap_input (int, u_char *, int);
-static void upap_protrej (int);
-
-static void upap_timeout (void *);
-static void upap_reqtimeout (void *);
-static void upap_rauthreq (upap_state *, u_char *, int, int);
-static void upap_rauthack (upap_state *, u_char *, int, int);
-static void upap_rauthnak (upap_state *, u_char *, int, int);
-static void upap_sauthreq (upap_state *);
-static void upap_sresp (upap_state *, u_char, u_char, char *, int);
-
-
-
-
-/******************************/
-/*** PUBLIC DATA STRUCTURES ***/
-/******************************/
-struct protent pap_protent = {
-    PPP_PAP,
-    upap_init,
-    upap_input,
-    upap_protrej,
-    upap_lowerup,
-    upap_lowerdown,
-    NULL,
-    NULL,
-#if 0
-    upap_printpkt,
-    NULL,
-#endif
-    1,
-    "PAP",
-#if 0
-    NULL,
-    NULL,
-    NULL
-#endif
-};
-
-upap_state upap[NUM_PPP];              /* UPAP state; one for each unit */
-
-
-
-/***********************************/
-/*** PUBLIC FUNCTION DEFINITIONS ***/
-/***********************************/
-/*
- *  Set the default login name and password for the pap sessions
- */
-void upap_setloginpasswd(int unit, const char *luser, const char *lpassword)
-{
-       upap_state *u = &upap[unit];
-       
-       /* Save the username and password we're given */
-       u->us_user = luser;
-       u->us_userlen = strlen(luser);
-       u->us_passwd = lpassword;
-       u->us_passwdlen = strlen(lpassword);
-}
-
-
-/*
- * upap_authwithpeer - Authenticate us with our peer (start client).
- *
- * Set new state and send authenticate's.
- */
-void upap_authwithpeer(int unit, char *user, char *password)
-{
-       upap_state *u = &upap[unit];
-       
-       UPAPDEBUG((LOG_INFO, "upap_authwithpeer: %d user=%s password=%s s=%d\n",
-                               unit, user, password, u->us_clientstate));
-       
-       upap_setloginpasswd(unit, user, password);
-
-       u->us_transmits = 0;
-       
-       /* Lower layer up yet? */
-       if (u->us_clientstate == UPAPCS_INITIAL ||
-                       u->us_clientstate == UPAPCS_PENDING) {
-               u->us_clientstate = UPAPCS_PENDING;
-               return;
-       }
-       
-       upap_sauthreq(u);                       /* Start protocol */
-}
-
-
-/*
- * upap_authpeer - Authenticate our peer (start server).
- *
- * Set new state.
- */
-void upap_authpeer(int unit)
-{
-       upap_state *u = &upap[unit];
-       
-       /* Lower layer up yet? */
-       if (u->us_serverstate == UPAPSS_INITIAL ||
-                       u->us_serverstate == UPAPSS_PENDING) {
-               u->us_serverstate = UPAPSS_PENDING;
-               return;
-       }
-       
-       u->us_serverstate = UPAPSS_LISTEN;
-       if (u->us_reqtimeout > 0)
-               TIMEOUT(upap_reqtimeout, u, u->us_reqtimeout);
-}
-
-
-
-/**********************************/
-/*** LOCAL FUNCTION DEFINITIONS ***/
-/**********************************/
-/*
- * upap_init - Initialize a UPAP unit.
- */
-static void upap_init(int unit)
-{
-       upap_state *u = &upap[unit];
-
-       UPAPDEBUG((LOG_INFO, "upap_init: %d\n", unit)); 
-       u->us_unit = unit;
-       u->us_user = NULL;
-       u->us_userlen = 0;
-       u->us_passwd = NULL;
-       u->us_passwdlen = 0;
-       u->us_clientstate = UPAPCS_INITIAL;
-       u->us_serverstate = UPAPSS_INITIAL;
-       u->us_id = 0;
-       u->us_timeouttime = UPAP_DEFTIMEOUT;
-       u->us_maxtransmits = 10;
-       u->us_reqtimeout = UPAP_DEFREQTIME;
-}
-
-/*
- * upap_timeout - Retransmission timer for sending auth-reqs expired.
- */
-static void upap_timeout(void *arg)
-{
-       upap_state *u = (upap_state *) arg;
-       
-       UPAPDEBUG((LOG_INFO, "upap_timeout: %d timeout %d expired s=%d\n", 
-                               u->us_unit, u->us_timeouttime, u->us_clientstate));
-       
-       if (u->us_clientstate != UPAPCS_AUTHREQ)
-               return;
-       
-       if (u->us_transmits >= u->us_maxtransmits) {
-               /* give up in disgust */
-               UPAPDEBUG((LOG_ERR, "No response to PAP authenticate-requests\n"));
-               u->us_clientstate = UPAPCS_BADAUTH;
-               auth_withpeer_fail(u->us_unit, PPP_PAP);
-               return;
-       }
-       
-       upap_sauthreq(u);               /* Send Authenticate-Request */
-}
-
-
-/*
- * upap_reqtimeout - Give up waiting for the peer to send an auth-req.
- */
-static void upap_reqtimeout(void *arg)
-{
-       upap_state *u = (upap_state *) arg;
-       
-       if (u->us_serverstate != UPAPSS_LISTEN)
-               return;                 /* huh?? */
-       
-       auth_peer_fail(u->us_unit, PPP_PAP);
-       u->us_serverstate = UPAPSS_BADAUTH;
-}
-
-
-/*
- * upap_lowerup - The lower layer is up.
- *
- * Start authenticating if pending.
- */
-static void upap_lowerup(int unit)
-{
-       upap_state *u = &upap[unit];
-       
-       UPAPDEBUG((LOG_INFO, "upap_lowerup: %d s=%d\n", unit, u->us_clientstate));
-       
-       if (u->us_clientstate == UPAPCS_INITIAL)
-               u->us_clientstate = UPAPCS_CLOSED;
-       else if (u->us_clientstate == UPAPCS_PENDING) {
-               upap_sauthreq(u);       /* send an auth-request */
-       }
-       
-       if (u->us_serverstate == UPAPSS_INITIAL)
-               u->us_serverstate = UPAPSS_CLOSED;
-       else if (u->us_serverstate == UPAPSS_PENDING) {
-               u->us_serverstate = UPAPSS_LISTEN;
-               if (u->us_reqtimeout > 0)
-                       TIMEOUT(upap_reqtimeout, u, u->us_reqtimeout);
-       }
-}
-
-
-/*
- * upap_lowerdown - The lower layer is down.
- *
- * Cancel all timeouts.
- */
-static void upap_lowerdown(int unit)
-{
-       upap_state *u = &upap[unit];
-       
-       UPAPDEBUG((LOG_INFO, "upap_lowerdown: %d s=%d\n", unit, u->us_clientstate));
-       
-       if (u->us_clientstate == UPAPCS_AUTHREQ)        /* Timeout pending? */
-               UNTIMEOUT(upap_timeout, u);             /* Cancel timeout */
-       if (u->us_serverstate == UPAPSS_LISTEN && u->us_reqtimeout > 0)
-               UNTIMEOUT(upap_reqtimeout, u);
-       
-       u->us_clientstate = UPAPCS_INITIAL;
-       u->us_serverstate = UPAPSS_INITIAL;
-}
-
-
-/*
- * upap_protrej - Peer doesn't speak this protocol.
- *
- * This shouldn't happen.  In any case, pretend lower layer went down.
- */
-static void upap_protrej(int unit)
-{
-       upap_state *u = &upap[unit];
-       
-       if (u->us_clientstate == UPAPCS_AUTHREQ) {
-               UPAPDEBUG((LOG_ERR, "PAP authentication failed due to protocol-reject\n"));
-               auth_withpeer_fail(unit, PPP_PAP);
-       }
-       if (u->us_serverstate == UPAPSS_LISTEN) {
-               UPAPDEBUG((LOG_ERR, "PAP authentication of peer failed (protocol-reject)\n"));
-               auth_peer_fail(unit, PPP_PAP);
-       }
-       upap_lowerdown(unit);
-}
-
-
-/*
- * upap_input - Input UPAP packet.
- */
-static void upap_input(int unit, u_char *inpacket, int l)
-{
-       upap_state *u = &upap[unit];
-       u_char *inp;
-       u_char code, id;
-       int len;
-       
-       /*
-        * Parse header (code, id and length).
-        * If packet too short, drop it.
-        */
-       inp = inpacket;
-       if (l < UPAP_HEADERLEN) {
-               UPAPDEBUG((LOG_INFO, "pap_input: rcvd short header.\n"));
-               return;
-       }
-       GETCHAR(code, inp);
-       GETCHAR(id, inp);
-       GETSHORT(len, inp);
-       if (len < UPAP_HEADERLEN) {
-               UPAPDEBUG((LOG_INFO, "pap_input: rcvd illegal length.\n"));
-               return;
-       }
-       if (len > l) {
-               UPAPDEBUG((LOG_INFO, "pap_input: rcvd short packet.\n"));
-               return;
-       }
-       len -= UPAP_HEADERLEN;
-       
-       /*
-        * Action depends on code.
-        */
-       switch (code) {
-       case UPAP_AUTHREQ:
-               upap_rauthreq(u, inp, id, len);
-               break;
-       
-       case UPAP_AUTHACK:
-               upap_rauthack(u, inp, id, len);
-               break;
-       
-       case UPAP_AUTHNAK:
-               upap_rauthnak(u, inp, id, len);
-               break;
-       
-       default:                                /* XXX Need code reject */
-               break;
-       }
-}
-
-
-/*
- * upap_rauth - Receive Authenticate.
- */
-static void upap_rauthreq(
-       upap_state *u, 
-       u_char *inp, 
-       int id,
-       int len
-)
-{
-       u_char ruserlen, rpasswdlen;
-       char *ruser, *rpasswd;
-       int retcode;
-       char *msg;
-       int msglen;
-       
-       UPAPDEBUG((LOG_INFO, "pap_rauth: Rcvd id %d.\n", id));
-       
-       if (u->us_serverstate < UPAPSS_LISTEN)
-               return;
-       
-       /*
-        * If we receive a duplicate authenticate-request, we are
-        * supposed to return the same status as for the first request.
-        */
-       if (u->us_serverstate == UPAPSS_OPEN) {
-               upap_sresp(u, UPAP_AUTHACK, id, "", 0); /* return auth-ack */
-               return;
-       }
-       if (u->us_serverstate == UPAPSS_BADAUTH) {
-               upap_sresp(u, UPAP_AUTHNAK, id, "", 0); /* return auth-nak */
-               return;
-       }
-       
-       /*
-        * Parse user/passwd.
-        */
-       if (len < sizeof (u_char)) {
-               UPAPDEBUG((LOG_INFO, "pap_rauth: rcvd short packet.\n"));
-               return;
-       }
-       GETCHAR(ruserlen, inp);
-       len -= sizeof (u_char) + ruserlen + sizeof (u_char);
-       if (len < 0) {
-               UPAPDEBUG((LOG_INFO, "pap_rauth: rcvd short packet.\n"));
-               return;
-       }
-       ruser = (char *) inp;
-       INCPTR(ruserlen, inp);
-       GETCHAR(rpasswdlen, inp);
-       if (len < rpasswdlen) {
-               UPAPDEBUG((LOG_INFO, "pap_rauth: rcvd short packet.\n"));
-               return;
-       }
-       rpasswd = (char *) inp;
-       
-       /*
-        * Check the username and password given.
-        */
-       retcode = check_passwd(u->us_unit, ruser, ruserlen, rpasswd,
-                          rpasswdlen, &msg, &msglen);
-       BZERO(rpasswd, rpasswdlen);
-       
-       upap_sresp(u, retcode, id, msg, msglen);
-       
-       if (retcode == UPAP_AUTHACK) {
-               u->us_serverstate = UPAPSS_OPEN;
-               auth_peer_success(u->us_unit, PPP_PAP, ruser, ruserlen);
-       } else {
-               u->us_serverstate = UPAPSS_BADAUTH;
-               auth_peer_fail(u->us_unit, PPP_PAP);
-       }
-       
-       if (u->us_reqtimeout > 0)
-               UNTIMEOUT(upap_reqtimeout, u);
-}
-
-
-/*
- * upap_rauthack - Receive Authenticate-Ack.
- */
-static void upap_rauthack(
-       upap_state *u,
-       u_char *inp,
-       int id,
-       int len
-)
-{
-       u_char msglen;
-       char *msg;
-       
-       UPAPDEBUG((LOG_INFO, "pap_rauthack: Rcvd id %d s=%d\n", id, u->us_clientstate));
-       
-       if (u->us_clientstate != UPAPCS_AUTHREQ) /* XXX */
-               return;
-       
-       /*
-        * Parse message.
-        */
-       if (len < sizeof (u_char)) {
-               UPAPDEBUG((LOG_INFO, "pap_rauthack: rcvd short packet.\n"));
-               return;
-       }
-       GETCHAR(msglen, inp);
-       len -= sizeof (u_char);
-       if (len < msglen) {
-               UPAPDEBUG((LOG_INFO, "pap_rauthack: rcvd short packet.\n"));
-               return;
-       }
-       msg = (char *) inp;
-       PRINTMSG(msg, msglen);
-       
-       u->us_clientstate = UPAPCS_OPEN;
-       
-       auth_withpeer_success(u->us_unit, PPP_PAP);
-}
-
-
-/*
- * upap_rauthnak - Receive Authenticate-Nakk.
- */
-static void upap_rauthnak(
-       upap_state *u,
-       u_char *inp,
-       int id,
-       int len
-)
-{
-       u_char msglen;
-       char *msg;
-       
-       UPAPDEBUG((LOG_INFO, "pap_rauthnak: Rcvd id %d s=%d\n", id, u->us_clientstate));
-       
-       if (u->us_clientstate != UPAPCS_AUTHREQ) /* XXX */
-               return;
-       
-       /*
-        * Parse message.
-        */
-       if (len < sizeof (u_char)) {
-               UPAPDEBUG((LOG_INFO, "pap_rauthnak: rcvd short packet.\n"));
-               return;
-       }
-       GETCHAR(msglen, inp);
-       len -= sizeof (u_char);
-       if (len < msglen) {
-               UPAPDEBUG((LOG_INFO, "pap_rauthnak: rcvd short packet.\n"));
-               return;
-       }
-       msg = (char *) inp;
-       PRINTMSG(msg, msglen);
-       
-       u->us_clientstate = UPAPCS_BADAUTH;
-       
-       UPAPDEBUG((LOG_ERR, "PAP authentication failed\n"));
-       auth_withpeer_fail(u->us_unit, PPP_PAP);
-}
-
-
-/*
- * upap_sauthreq - Send an Authenticate-Request.
- */
-static void upap_sauthreq(upap_state *u)
-{
-       u_char *outp;
-       int outlen;
-       
-       outlen = UPAP_HEADERLEN + 2 * sizeof (u_char) 
-                       + u->us_userlen + u->us_passwdlen;
-       outp = outpacket_buf[u->us_unit];
-       
-       MAKEHEADER(outp, PPP_PAP);
-       
-       PUTCHAR(UPAP_AUTHREQ, outp);
-       PUTCHAR(++u->us_id, outp);
-       PUTSHORT(outlen, outp);
-       PUTCHAR(u->us_userlen, outp);
-       BCOPY(u->us_user, outp, u->us_userlen);
-       INCPTR(u->us_userlen, outp);
-       PUTCHAR(u->us_passwdlen, outp);
-       BCOPY(u->us_passwd, outp, u->us_passwdlen);
-       
-       pppWrite(u->us_unit, outpacket_buf[u->us_unit], outlen + PPP_HDRLEN);
-       
-       UPAPDEBUG((LOG_INFO, "pap_sauth: Sent id %d\n", u->us_id));
-       
-       TIMEOUT(upap_timeout, u, u->us_timeouttime);
-       ++u->us_transmits;
-       u->us_clientstate = UPAPCS_AUTHREQ;
-}
-
-
-/*
- * upap_sresp - Send a response (ack or nak).
- */
-static void upap_sresp(
-       upap_state *u,
-       u_char code, 
-       u_char id,
-       char *msg,
-       int msglen
-)
-{
-       u_char *outp;
-       int outlen;
-       
-       outlen = UPAP_HEADERLEN + sizeof (u_char) + msglen;
-       outp = outpacket_buf[u->us_unit];
-       MAKEHEADER(outp, PPP_PAP);
-       
-       PUTCHAR(code, outp);
-       PUTCHAR(id, outp);
-       PUTSHORT(outlen, outp);
-       PUTCHAR(msglen, outp);
-       BCOPY(msg, outp, msglen);
-       pppWrite(u->us_unit, outpacket_buf[u->us_unit], outlen + PPP_HDRLEN);
-       
-       UPAPDEBUG((LOG_INFO, "pap_sresp: Sent code %d, id %d s=%d\n", 
-                               code, id, u->us_clientstate));
-}
-
-#if 0
-/*
- * upap_printpkt - print the contents of a PAP packet.
- */
-static int upap_printpkt(
-       u_char *p,
-       int plen,
-       void (*printer) (void *, char *, ...),
-       void *arg
-)
-{
-       (void)p;
-       (void)plen;
-       (void)printer;
-       (void)arg;
-       return 0;
-}
-#endif
-
-#endif /* PAP_SUPPORT */
-
+/*****************************************************************************\r
+* pap.c - Network Password Authentication Protocol program file.\r
+*\r
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.\r
+* portions Copyright (c) 1997 by Global Election Systems Inc.\r
+*\r
+* The authors hereby grant permission to use, copy, modify, distribute,\r
+* and license this software and its documentation for any purpose, provided\r
+* that existing copyright notices are retained in all copies and that this\r
+* notice and the following disclaimer are included verbatim in any \r
+* distributions. No written agreement, license, or royalty fee is required\r
+* for any of the authorized uses.\r
+*\r
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR\r
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+*\r
+******************************************************************************\r
+* REVISION HISTORY\r
+*\r
+* 03-01-01 Marc Boucher <marc@mbsi.ca>\r
+*   Ported to lwIP.\r
+* 97-12-12 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.\r
+*      Original.\r
+*****************************************************************************/\r
+/*\r
+ * upap.c - User/Password Authentication Protocol.\r
+ *\r
+ * Copyright (c) 1989 Carnegie Mellon University.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms are permitted\r
+ * provided that the above copyright notice and this paragraph are\r
+ * duplicated in all such forms and that any documentation,\r
+ * advertising materials, and other materials related to such\r
+ * distribution and use acknowledge that the software was developed\r
+ * by Carnegie Mellon University.  The name of the\r
+ * University may not be used to endorse or promote products derived\r
+ * from this software without specific prior written permission.\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR\r
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r
+ */\r
+\r
+#include "ppp.h"\r
+#include "auth.h"\r
+#include "pap.h"\r
+#include "pppdebug.h"\r
+\r
+\r
+#if PAP_SUPPORT > 0\r
+\r
+/***********************************/\r
+/*** LOCAL FUNCTION DECLARATIONS ***/\r
+/***********************************/\r
+/*\r
+ * Protocol entry points.\r
+ */\r
+static void upap_init (int);\r
+static void upap_lowerup (int);\r
+static void upap_lowerdown (int);\r
+static void upap_input (int, u_char *, int);\r
+static void upap_protrej (int);\r
+\r
+static void upap_timeout (void *);\r
+static void upap_reqtimeout (void *);\r
+static void upap_rauthreq (upap_state *, u_char *, int, int);\r
+static void upap_rauthack (upap_state *, u_char *, int, int);\r
+static void upap_rauthnak (upap_state *, u_char *, int, int);\r
+static void upap_sauthreq (upap_state *);\r
+static void upap_sresp (upap_state *, u_char, u_char, char *, int);\r
+\r
+\r
+\r
+\r
+/******************************/\r
+/*** PUBLIC DATA STRUCTURES ***/\r
+/******************************/\r
+struct protent pap_protent = {\r
+    PPP_PAP,\r
+    upap_init,\r
+    upap_input,\r
+    upap_protrej,\r
+    upap_lowerup,\r
+    upap_lowerdown,\r
+    NULL,\r
+    NULL,\r
+#if 0\r
+    upap_printpkt,\r
+    NULL,\r
+#endif\r
+    1,\r
+    "PAP",\r
+#if 0\r
+    NULL,\r
+    NULL,\r
+    NULL\r
+#endif\r
+};\r
+\r
+upap_state upap[NUM_PPP];              /* UPAP state; one for each unit */\r
+\r
+\r
+\r
+/***********************************/\r
+/*** PUBLIC FUNCTION DEFINITIONS ***/\r
+/***********************************/\r
+/*\r
+ *  Set the default login name and password for the pap sessions\r
+ */\r
+void upap_setloginpasswd(int unit, const char *luser, const char *lpassword)\r
+{\r
+       upap_state *u = &upap[unit];\r
+       \r
+       /* Save the username and password we're given */\r
+       u->us_user = luser;\r
+       u->us_userlen = strlen(luser);\r
+       u->us_passwd = lpassword;\r
+       u->us_passwdlen = strlen(lpassword);\r
+}\r
+\r
+\r
+/*\r
+ * upap_authwithpeer - Authenticate us with our peer (start client).\r
+ *\r
+ * Set new state and send authenticate's.\r
+ */\r
+void upap_authwithpeer(int unit, char *user, char *password)\r
+{\r
+       upap_state *u = &upap[unit];\r
+       \r
+       UPAPDEBUG((LOG_INFO, "upap_authwithpeer: %d user=%s password=%s s=%d\n",\r
+                               unit, user, password, u->us_clientstate));\r
+       \r
+       upap_setloginpasswd(unit, user, password);\r
+\r
+       u->us_transmits = 0;\r
+       \r
+       /* Lower layer up yet? */\r
+       if (u->us_clientstate == UPAPCS_INITIAL ||\r
+                       u->us_clientstate == UPAPCS_PENDING) {\r
+               u->us_clientstate = UPAPCS_PENDING;\r
+               return;\r
+       }\r
+       \r
+       upap_sauthreq(u);                       /* Start protocol */\r
+}\r
+\r
+\r
+/*\r
+ * upap_authpeer - Authenticate our peer (start server).\r
+ *\r
+ * Set new state.\r
+ */\r
+void upap_authpeer(int unit)\r
+{\r
+       upap_state *u = &upap[unit];\r
+       \r
+       /* Lower layer up yet? */\r
+       if (u->us_serverstate == UPAPSS_INITIAL ||\r
+                       u->us_serverstate == UPAPSS_PENDING) {\r
+               u->us_serverstate = UPAPSS_PENDING;\r
+               return;\r
+       }\r
+       \r
+       u->us_serverstate = UPAPSS_LISTEN;\r
+       if (u->us_reqtimeout > 0)\r
+               TIMEOUT(upap_reqtimeout, u, u->us_reqtimeout);\r
+}\r
+\r
+\r
+\r
+/**********************************/\r
+/*** LOCAL FUNCTION DEFINITIONS ***/\r
+/**********************************/\r
+/*\r
+ * upap_init - Initialize a UPAP unit.\r
+ */\r
+static void upap_init(int unit)\r
+{\r
+       upap_state *u = &upap[unit];\r
+\r
+       UPAPDEBUG((LOG_INFO, "upap_init: %d\n", unit)); \r
+       u->us_unit = unit;\r
+       u->us_user = NULL;\r
+       u->us_userlen = 0;\r
+       u->us_passwd = NULL;\r
+       u->us_passwdlen = 0;\r
+       u->us_clientstate = UPAPCS_INITIAL;\r
+       u->us_serverstate = UPAPSS_INITIAL;\r
+       u->us_id = 0;\r
+       u->us_timeouttime = UPAP_DEFTIMEOUT;\r
+       u->us_maxtransmits = 10;\r
+       u->us_reqtimeout = UPAP_DEFREQTIME;\r
+}\r
+\r
+/*\r
+ * upap_timeout - Retransmission timer for sending auth-reqs expired.\r
+ */\r
+static void upap_timeout(void *arg)\r
+{\r
+       upap_state *u = (upap_state *) arg;\r
+       \r
+       UPAPDEBUG((LOG_INFO, "upap_timeout: %d timeout %d expired s=%d\n", \r
+                               u->us_unit, u->us_timeouttime, u->us_clientstate));\r
+       \r
+       if (u->us_clientstate != UPAPCS_AUTHREQ)\r
+               return;\r
+       \r
+       if (u->us_transmits >= u->us_maxtransmits) {\r
+               /* give up in disgust */\r
+               UPAPDEBUG((LOG_ERR, "No response to PAP authenticate-requests\n"));\r
+               u->us_clientstate = UPAPCS_BADAUTH;\r
+               auth_withpeer_fail(u->us_unit, PPP_PAP);\r
+               return;\r
+       }\r
+       \r
+       upap_sauthreq(u);               /* Send Authenticate-Request */\r
+}\r
+\r
+\r
+/*\r
+ * upap_reqtimeout - Give up waiting for the peer to send an auth-req.\r
+ */\r
+static void upap_reqtimeout(void *arg)\r
+{\r
+       upap_state *u = (upap_state *) arg;\r
+       \r
+       if (u->us_serverstate != UPAPSS_LISTEN)\r
+               return;                 /* huh?? */\r
+       \r
+       auth_peer_fail(u->us_unit, PPP_PAP);\r
+       u->us_serverstate = UPAPSS_BADAUTH;\r
+}\r
+\r
+\r
+/*\r
+ * upap_lowerup - The lower layer is up.\r
+ *\r
+ * Start authenticating if pending.\r
+ */\r
+static void upap_lowerup(int unit)\r
+{\r
+       upap_state *u = &upap[unit];\r
+       \r
+       UPAPDEBUG((LOG_INFO, "upap_lowerup: %d s=%d\n", unit, u->us_clientstate));\r
+       \r
+       if (u->us_clientstate == UPAPCS_INITIAL)\r
+               u->us_clientstate = UPAPCS_CLOSED;\r
+       else if (u->us_clientstate == UPAPCS_PENDING) {\r
+               upap_sauthreq(u);       /* send an auth-request */\r
+       }\r
+       \r
+       if (u->us_serverstate == UPAPSS_INITIAL)\r
+               u->us_serverstate = UPAPSS_CLOSED;\r
+       else if (u->us_serverstate == UPAPSS_PENDING) {\r
+               u->us_serverstate = UPAPSS_LISTEN;\r
+               if (u->us_reqtimeout > 0)\r
+                       TIMEOUT(upap_reqtimeout, u, u->us_reqtimeout);\r
+       }\r
+}\r
+\r
+\r
+/*\r
+ * upap_lowerdown - The lower layer is down.\r
+ *\r
+ * Cancel all timeouts.\r
+ */\r
+static void upap_lowerdown(int unit)\r
+{\r
+       upap_state *u = &upap[unit];\r
+       \r
+       UPAPDEBUG((LOG_INFO, "upap_lowerdown: %d s=%d\n", unit, u->us_clientstate));\r
+       \r
+       if (u->us_clientstate == UPAPCS_AUTHREQ)        /* Timeout pending? */\r
+               UNTIMEOUT(upap_timeout, u);             /* Cancel timeout */\r
+       if (u->us_serverstate == UPAPSS_LISTEN && u->us_reqtimeout > 0)\r
+               UNTIMEOUT(upap_reqtimeout, u);\r
+       \r
+       u->us_clientstate = UPAPCS_INITIAL;\r
+       u->us_serverstate = UPAPSS_INITIAL;\r
+}\r
+\r
+\r
+/*\r
+ * upap_protrej - Peer doesn't speak this protocol.\r
+ *\r
+ * This shouldn't happen.  In any case, pretend lower layer went down.\r
+ */\r
+static void upap_protrej(int unit)\r
+{\r
+       upap_state *u = &upap[unit];\r
+       \r
+       if (u->us_clientstate == UPAPCS_AUTHREQ) {\r
+               UPAPDEBUG((LOG_ERR, "PAP authentication failed due to protocol-reject\n"));\r
+               auth_withpeer_fail(unit, PPP_PAP);\r
+       }\r
+       if (u->us_serverstate == UPAPSS_LISTEN) {\r
+               UPAPDEBUG((LOG_ERR, "PAP authentication of peer failed (protocol-reject)\n"));\r
+               auth_peer_fail(unit, PPP_PAP);\r
+       }\r
+       upap_lowerdown(unit);\r
+}\r
+\r
+\r
+/*\r
+ * upap_input - Input UPAP packet.\r
+ */\r
+static void upap_input(int unit, u_char *inpacket, int l)\r
+{\r
+       upap_state *u = &upap[unit];\r
+       u_char *inp;\r
+       u_char code, id;\r
+       int len;\r
+       \r
+       /*\r
+        * Parse header (code, id and length).\r
+        * If packet too short, drop it.\r
+        */\r
+       inp = inpacket;\r
+       if (l < UPAP_HEADERLEN) {\r
+               UPAPDEBUG((LOG_INFO, "pap_input: rcvd short header.\n"));\r
+               return;\r
+       }\r
+       GETCHAR(code, inp);\r
+       GETCHAR(id, inp);\r
+       GETSHORT(len, inp);\r
+       if (len < UPAP_HEADERLEN) {\r
+               UPAPDEBUG((LOG_INFO, "pap_input: rcvd illegal length.\n"));\r
+               return;\r
+       }\r
+       if (len > l) {\r
+               UPAPDEBUG((LOG_INFO, "pap_input: rcvd short packet.\n"));\r
+               return;\r
+       }\r
+       len -= UPAP_HEADERLEN;\r
+       \r
+       /*\r
+        * Action depends on code.\r
+        */\r
+       switch (code) {\r
+       case UPAP_AUTHREQ:\r
+               upap_rauthreq(u, inp, id, len);\r
+               break;\r
+       \r
+       case UPAP_AUTHACK:\r
+               upap_rauthack(u, inp, id, len);\r
+               break;\r
+       \r
+       case UPAP_AUTHNAK:\r
+               upap_rauthnak(u, inp, id, len);\r
+               break;\r
+       \r
+       default:                                /* XXX Need code reject */\r
+               break;\r
+       }\r
+}\r
+\r
+\r
+/*\r
+ * upap_rauth - Receive Authenticate.\r
+ */\r
+static void upap_rauthreq(\r
+       upap_state *u, \r
+       u_char *inp, \r
+       int id,\r
+       int len\r
+)\r
+{\r
+       u_char ruserlen, rpasswdlen;\r
+       char *ruser, *rpasswd;\r
+       int retcode;\r
+       char *msg;\r
+       int msglen;\r
+       \r
+       UPAPDEBUG((LOG_INFO, "pap_rauth: Rcvd id %d.\n", id));\r
+       \r
+       if (u->us_serverstate < UPAPSS_LISTEN)\r
+               return;\r
+       \r
+       /*\r
+        * If we receive a duplicate authenticate-request, we are\r
+        * supposed to return the same status as for the first request.\r
+        */\r
+       if (u->us_serverstate == UPAPSS_OPEN) {\r
+               upap_sresp(u, UPAP_AUTHACK, id, "", 0); /* return auth-ack */\r
+               return;\r
+       }\r
+       if (u->us_serverstate == UPAPSS_BADAUTH) {\r
+               upap_sresp(u, UPAP_AUTHNAK, id, "", 0); /* return auth-nak */\r
+               return;\r
+       }\r
+       \r
+       /*\r
+        * Parse user/passwd.\r
+        */\r
+       if (len < sizeof (u_char)) {\r
+               UPAPDEBUG((LOG_INFO, "pap_rauth: rcvd short packet.\n"));\r
+               return;\r
+       }\r
+       GETCHAR(ruserlen, inp);\r
+       len -= sizeof (u_char) + ruserlen + sizeof (u_char);\r
+       if (len < 0) {\r
+               UPAPDEBUG((LOG_INFO, "pap_rauth: rcvd short packet.\n"));\r
+               return;\r
+       }\r
+       ruser = (char *) inp;\r
+       INCPTR(ruserlen, inp);\r
+       GETCHAR(rpasswdlen, inp);\r
+       if (len < rpasswdlen) {\r
+               UPAPDEBUG((LOG_INFO, "pap_rauth: rcvd short packet.\n"));\r
+               return;\r
+       }\r
+       rpasswd = (char *) inp;\r
+       \r
+       /*\r
+        * Check the username and password given.\r
+        */\r
+       retcode = check_passwd(u->us_unit, ruser, ruserlen, rpasswd,\r
+                          rpasswdlen, &msg, &msglen);\r
+       BZERO(rpasswd, rpasswdlen);\r
+       \r
+       upap_sresp(u, retcode, id, msg, msglen);\r
+       \r
+       if (retcode == UPAP_AUTHACK) {\r
+               u->us_serverstate = UPAPSS_OPEN;\r
+               auth_peer_success(u->us_unit, PPP_PAP, ruser, ruserlen);\r
+       } else {\r
+               u->us_serverstate = UPAPSS_BADAUTH;\r
+               auth_peer_fail(u->us_unit, PPP_PAP);\r
+       }\r
+       \r
+       if (u->us_reqtimeout > 0)\r
+               UNTIMEOUT(upap_reqtimeout, u);\r
+}\r
+\r
+\r
+/*\r
+ * upap_rauthack - Receive Authenticate-Ack.\r
+ */\r
+static void upap_rauthack(\r
+       upap_state *u,\r
+       u_char *inp,\r
+       int id,\r
+       int len\r
+)\r
+{\r
+       u_char msglen;\r
+       char *msg;\r
+       \r
+       UPAPDEBUG((LOG_INFO, "pap_rauthack: Rcvd id %d s=%d\n", id, u->us_clientstate));\r
+       \r
+       if (u->us_clientstate != UPAPCS_AUTHREQ) /* XXX */\r
+               return;\r
+       \r
+       /*\r
+        * Parse message.\r
+        */\r
+       if (len < sizeof (u_char)) {\r
+               UPAPDEBUG((LOG_INFO, "pap_rauthack: rcvd short packet.\n"));\r
+               return;\r
+       }\r
+       GETCHAR(msglen, inp);\r
+       len -= sizeof (u_char);\r
+       if (len < msglen) {\r
+               UPAPDEBUG((LOG_INFO, "pap_rauthack: rcvd short packet.\n"));\r
+               return;\r
+       }\r
+       msg = (char *) inp;\r
+       PRINTMSG(msg, msglen);\r
+       \r
+       u->us_clientstate = UPAPCS_OPEN;\r
+       \r
+       auth_withpeer_success(u->us_unit, PPP_PAP);\r
+}\r
+\r
+\r
+/*\r
+ * upap_rauthnak - Receive Authenticate-Nakk.\r
+ */\r
+static void upap_rauthnak(\r
+       upap_state *u,\r
+       u_char *inp,\r
+       int id,\r
+       int len\r
+)\r
+{\r
+       u_char msglen;\r
+       char *msg;\r
+       \r
+       UPAPDEBUG((LOG_INFO, "pap_rauthnak: Rcvd id %d s=%d\n", id, u->us_clientstate));\r
+       \r
+       if (u->us_clientstate != UPAPCS_AUTHREQ) /* XXX */\r
+               return;\r
+       \r
+       /*\r
+        * Parse message.\r
+        */\r
+       if (len < sizeof (u_char)) {\r
+               UPAPDEBUG((LOG_INFO, "pap_rauthnak: rcvd short packet.\n"));\r
+               return;\r
+       }\r
+       GETCHAR(msglen, inp);\r
+       len -= sizeof (u_char);\r
+       if (len < msglen) {\r
+               UPAPDEBUG((LOG_INFO, "pap_rauthnak: rcvd short packet.\n"));\r
+               return;\r
+       }\r
+       msg = (char *) inp;\r
+       PRINTMSG(msg, msglen);\r
+       \r
+       u->us_clientstate = UPAPCS_BADAUTH;\r
+       \r
+       UPAPDEBUG((LOG_ERR, "PAP authentication failed\n"));\r
+       auth_withpeer_fail(u->us_unit, PPP_PAP);\r
+}\r
+\r
+\r
+/*\r
+ * upap_sauthreq - Send an Authenticate-Request.\r
+ */\r
+static void upap_sauthreq(upap_state *u)\r
+{\r
+       u_char *outp;\r
+       int outlen;\r
+       \r
+       outlen = UPAP_HEADERLEN + 2 * sizeof (u_char) \r
+                       + u->us_userlen + u->us_passwdlen;\r
+       outp = outpacket_buf[u->us_unit];\r
+       \r
+       MAKEHEADER(outp, PPP_PAP);\r
+       \r
+       PUTCHAR(UPAP_AUTHREQ, outp);\r
+       PUTCHAR(++u->us_id, outp);\r
+       PUTSHORT(outlen, outp);\r
+       PUTCHAR(u->us_userlen, outp);\r
+       BCOPY(u->us_user, outp, u->us_userlen);\r
+       INCPTR(u->us_userlen, outp);\r
+       PUTCHAR(u->us_passwdlen, outp);\r
+       BCOPY(u->us_passwd, outp, u->us_passwdlen);\r
+       \r
+       pppWrite(u->us_unit, outpacket_buf[u->us_unit], outlen + PPP_HDRLEN);\r
+       \r
+       UPAPDEBUG((LOG_INFO, "pap_sauth: Sent id %d\n", u->us_id));\r
+       \r
+       TIMEOUT(upap_timeout, u, u->us_timeouttime);\r
+       ++u->us_transmits;\r
+       u->us_clientstate = UPAPCS_AUTHREQ;\r
+}\r
+\r
+\r
+/*\r
+ * upap_sresp - Send a response (ack or nak).\r
+ */\r
+static void upap_sresp(\r
+       upap_state *u,\r
+       u_char code, \r
+       u_char id,\r
+       char *msg,\r
+       int msglen\r
+)\r
+{\r
+       u_char *outp;\r
+       int outlen;\r
+       \r
+       outlen = UPAP_HEADERLEN + sizeof (u_char) + msglen;\r
+       outp = outpacket_buf[u->us_unit];\r
+       MAKEHEADER(outp, PPP_PAP);\r
+       \r
+       PUTCHAR(code, outp);\r
+       PUTCHAR(id, outp);\r
+       PUTSHORT(outlen, outp);\r
+       PUTCHAR(msglen, outp);\r
+       BCOPY(msg, outp, msglen);\r
+       pppWrite(u->us_unit, outpacket_buf[u->us_unit], outlen + PPP_HDRLEN);\r
+       \r
+       UPAPDEBUG((LOG_INFO, "pap_sresp: Sent code %d, id %d s=%d\n", \r
+                               code, id, u->us_clientstate));\r
+}\r
+\r
+#if 0\r
+/*\r
+ * upap_printpkt - print the contents of a PAP packet.\r
+ */\r
+static int upap_printpkt(\r
+       u_char *p,\r
+       int plen,\r
+       void (*printer) (void *, char *, ...),\r
+       void *arg\r
+)\r
+{\r
+       (void)p;\r
+       (void)plen;\r
+       (void)printer;\r
+       (void)arg;\r
+       return 0;\r
+}\r
+#endif\r
+\r
+#endif /* PAP_SUPPORT */\r
+\r
index 215c8a4f2eac502b0fdcdfe086985f260b2c19f8..59eb2c71e9241a384f2d7d97d253c4a829c56745 100644 (file)
-/*****************************************************************************
-* pap.h -  PPP Password Authentication Protocol header file.
-*
-* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
-* portions Copyright (c) 1997 Global Election Systems Inc.
-*
-* The authors hereby grant permission to use, copy, modify, distribute,
-* and license this software and its documentation for any purpose, provided
-* that existing copyright notices are retained in all copies and that this
-* notice and the following disclaimer are included verbatim in any 
-* distributions. No written agreement, license, or royalty fee is required
-* for any of the authorized uses.
-*
-* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *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 CONTRIBUTORS 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.
-*
-******************************************************************************
-* REVISION HISTORY
-*
-* 03-01-01 Marc Boucher <marc@mbsi.ca>
-*   Ported to lwIP.
-* 97-12-04 Guy Lancaster <glanca@gesn.com>, Global Election Systems Inc.
-*      Original derived from BSD codes.
-*****************************************************************************/
-/*
- * upap.h - User/Password Authentication Protocol definitions.
- *
- * Copyright (c) 1989 Carnegie Mellon University.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by Carnegie Mellon University.  The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-
-#ifndef PAP_H
-#define PAP_H
-
-/*************************
-*** PUBLIC DEFINITIONS ***
-*************************/
-/*
- * Packet header = Code, id, length.
- */
-#define UPAP_HEADERLEN (sizeof (u_char) + sizeof (u_char) + sizeof (u_short))
-
-
-/*
- * UPAP codes.
- */
-#define UPAP_AUTHREQ   1       /* Authenticate-Request */
-#define UPAP_AUTHACK   2       /* Authenticate-Ack */
-#define UPAP_AUTHNAK   3       /* Authenticate-Nak */
-
-/*
- * Client states.
- */
-#define UPAPCS_INITIAL 0       /* Connection down */
-#define UPAPCS_CLOSED  1       /* Connection up, haven't requested auth */
-#define UPAPCS_PENDING 2       /* Connection down, have requested auth */
-#define UPAPCS_AUTHREQ 3       /* We've sent an Authenticate-Request */
-#define UPAPCS_OPEN            4       /* We've received an Ack */
-#define UPAPCS_BADAUTH 5       /* We've received a Nak */
-
-/*
- * Server states.
- */
-#define UPAPSS_INITIAL 0       /* Connection down */
-#define UPAPSS_CLOSED  1       /* Connection up, haven't requested auth */
-#define UPAPSS_PENDING 2       /* Connection down, have requested auth */
-#define UPAPSS_LISTEN  3       /* Listening for an Authenticate */
-#define UPAPSS_OPEN            4       /* We've sent an Ack */
-#define UPAPSS_BADAUTH 5       /* We've sent a Nak */
-
-
-/************************
-*** PUBLIC DATA TYPES ***
-************************/
-
-/*
- * Each interface is described by upap structure.
- */
-typedef struct upap_state {
-    int us_unit;                       /* Interface unit number */
-    const char *us_user;       /* User */
-    int us_userlen;                    /* User length */
-    const char *us_passwd;     /* Password */
-    int us_passwdlen;          /* Password length */
-    int us_clientstate;                /* Client state */
-    int us_serverstate;                /* Server state */
-    u_char us_id;                      /* Current id */
-    int us_timeouttime;                /* Timeout (seconds) for auth-req retrans. */
-    int us_transmits;          /* Number of auth-reqs sent */
-    int us_maxtransmits;       /* Maximum number of auth-reqs to send */
-    int us_reqtimeout;         /* Time to wait for auth-req from peer */
-} upap_state;
-
-
-/***********************
-*** PUBLIC FUNCTIONS ***
-***********************/
-
-extern upap_state upap[];
-
-void upap_setloginpasswd(int unit, const char *luser, const char *lpassword);
-void upap_authwithpeer (int, char *, char *);
-void upap_authpeer (int);
-
-extern struct protent pap_protent;
-
-#endif /* PAP_H */
-
+/*****************************************************************************\r
+* pap.h -  PPP Password Authentication Protocol header file.\r
+*\r
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.\r
+* portions Copyright (c) 1997 Global Election Systems Inc.\r
+*\r
+* The authors hereby grant permission to use, copy, modify, distribute,\r
+* and license this software and its documentation for any purpose, provided\r
+* that existing copyright notices are retained in all copies and that this\r
+* notice and the following disclaimer are included verbatim in any \r
+* distributions. No written agreement, license, or royalty fee is required\r
+* for any of the authorized uses.\r
+*\r
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR\r
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+*\r
+******************************************************************************\r
+* REVISION HISTORY\r
+*\r
+* 03-01-01 Marc Boucher <marc@mbsi.ca>\r
+*   Ported to lwIP.\r
+* 97-12-04 Guy Lancaster <glanca@gesn.com>, Global Election Systems Inc.\r
+*      Original derived from BSD codes.\r
+*****************************************************************************/\r
+/*\r
+ * upap.h - User/Password Authentication Protocol definitions.\r
+ *\r
+ * Copyright (c) 1989 Carnegie Mellon University.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms are permitted\r
+ * provided that the above copyright notice and this paragraph are\r
+ * duplicated in all such forms and that any documentation,\r
+ * advertising materials, and other materials related to such\r
+ * distribution and use acknowledge that the software was developed\r
+ * by Carnegie Mellon University.  The name of the\r
+ * University may not be used to endorse or promote products derived\r
+ * from this software without specific prior written permission.\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR\r
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r
+ */\r
+\r
+\r
+#ifndef PAP_H\r
+#define PAP_H\r
+\r
+/*************************\r
+*** PUBLIC DEFINITIONS ***\r
+*************************/\r
+/*\r
+ * Packet header = Code, id, length.\r
+ */\r
+#define UPAP_HEADERLEN (sizeof (u_char) + sizeof (u_char) + sizeof (u_short))\r
+\r
+\r
+/*\r
+ * UPAP codes.\r
+ */\r
+#define UPAP_AUTHREQ   1       /* Authenticate-Request */\r
+#define UPAP_AUTHACK   2       /* Authenticate-Ack */\r
+#define UPAP_AUTHNAK   3       /* Authenticate-Nak */\r
+\r
+/*\r
+ * Client states.\r
+ */\r
+#define UPAPCS_INITIAL 0       /* Connection down */\r
+#define UPAPCS_CLOSED  1       /* Connection up, haven't requested auth */\r
+#define UPAPCS_PENDING 2       /* Connection down, have requested auth */\r
+#define UPAPCS_AUTHREQ 3       /* We've sent an Authenticate-Request */\r
+#define UPAPCS_OPEN            4       /* We've received an Ack */\r
+#define UPAPCS_BADAUTH 5       /* We've received a Nak */\r
+\r
+/*\r
+ * Server states.\r
+ */\r
+#define UPAPSS_INITIAL 0       /* Connection down */\r
+#define UPAPSS_CLOSED  1       /* Connection up, haven't requested auth */\r
+#define UPAPSS_PENDING 2       /* Connection down, have requested auth */\r
+#define UPAPSS_LISTEN  3       /* Listening for an Authenticate */\r
+#define UPAPSS_OPEN            4       /* We've sent an Ack */\r
+#define UPAPSS_BADAUTH 5       /* We've sent a Nak */\r
+\r
+\r
+/************************\r
+*** PUBLIC DATA TYPES ***\r
+************************/\r
+\r
+/*\r
+ * Each interface is described by upap structure.\r
+ */\r
+typedef struct upap_state {\r
+    int us_unit;                       /* Interface unit number */\r
+    const char *us_user;       /* User */\r
+    int us_userlen;                    /* User length */\r
+    const char *us_passwd;     /* Password */\r
+    int us_passwdlen;          /* Password length */\r
+    int us_clientstate;                /* Client state */\r
+    int us_serverstate;                /* Server state */\r
+    u_char us_id;                      /* Current id */\r
+    int us_timeouttime;                /* Timeout (seconds) for auth-req retrans. */\r
+    int us_transmits;          /* Number of auth-reqs sent */\r
+    int us_maxtransmits;       /* Maximum number of auth-reqs to send */\r
+    int us_reqtimeout;         /* Time to wait for auth-req from peer */\r
+} upap_state;\r
+\r
+\r
+/***********************\r
+*** PUBLIC FUNCTIONS ***\r
+***********************/\r
+\r
+extern upap_state upap[];\r
+\r
+void upap_setloginpasswd(int unit, const char *luser, const char *lpassword);\r
+void upap_authwithpeer (int, char *, char *);\r
+void upap_authpeer (int);\r
+\r
+extern struct protent pap_protent;\r
+\r
+#endif /* PAP_H */\r
+\r
index df402189e9710f10566af9c775888ae26b026baa..00a7956df9bf64e2f89e5f9306427cb85b300dbb 100644 (file)
-/*****************************************************************************
-* ppp.c - Network Point to Point Protocol program file.
-*
-* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
-* portions Copyright (c) 1997 by Global Election Systems Inc.
-*
-* The authors hereby grant permission to use, copy, modify, distribute,
-* and license this software and its documentation for any purpose, provided
-* that existing copyright notices are retained in all copies and that this
-* notice and the following disclaimer are included verbatim in any 
-* distributions. No written agreement, license, or royalty fee is required
-* for any of the authorized uses.
-*
-* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *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 CONTRIBUTORS 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.
-*
-******************************************************************************
-* REVISION HISTORY
-*
-* 03-01-01 Marc Boucher <marc@mbsi.ca>
-*   Ported to lwIP.
-* 97-11-05 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
-*   Original.
-*****************************************************************************/
-
-/*
- * ppp_defs.h - PPP definitions.
- *
- * if_pppvar.h - private structures and declarations for PPP.
- *
- * Copyright (c) 1994 The Australian National University.
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation is hereby granted, provided that the above copyright
- * notice appears in all copies.  This software is provided without any
- * warranty, express or implied. The Australian National University
- * makes no representations about the suitability of this software for
- * any purpose.
- *
- * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY
- * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
- * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY
- * OF SUCH DAMAGE.
- *
- * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO
- * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
- * OR MODIFICATIONS.
- */
-
-/*
- * if_ppp.h - Point-to-Point Protocol definitions.
- *
- * Copyright (c) 1989 Carnegie Mellon University.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by Carnegie Mellon University.  The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-#include <string.h>
-#include "ppp.h"
-#if PPP_SUPPORT > 0
-#include "randm.h"
-#include "fsm.h"
-#if PAP_SUPPORT > 0
-#include "pap.h"
-#endif
-#if CHAP_SUPPORT > 0
-#include "chap.h"
-#endif
-#include "ipcp.h"
-#include "lcp.h"
-#include "magic.h"
-#include "auth.h"
-#if VJ_SUPPORT > 0
-#include "vj.h"
-#endif
-
-#include "pppdebug.h"
-
-/*************************/
-/*** LOCAL DEFINITIONS ***/
-/*************************/
-
-/*
- * The basic PPP frame.
- */
-#define PPP_ADDRESS(p)  (((u_char *)(p))[0])
-#define PPP_CONTROL(p)  (((u_char *)(p))[1])
-#define PPP_PROTOCOL(p) ((((u_char *)(p))[2] << 8) + ((u_char *)(p))[3])
-
-/* PPP packet parser states.  Current state indicates operation yet to be
- * completed. */
-typedef enum {
-    PDIDLE = 0,                 /* Idle state - waiting. */
-    PDSTART,                    /* Process start flag. */
-    PDADDRESS,                  /* Process address field. */
-    PDCONTROL,                  /* Process control field. */
-    PDPROTOCOL1,                /* Process protocol field 1. */
-    PDPROTOCOL2,                /* Process protocol field 2. */
-    PDDATA                      /* Process data byte. */
-} PPPDevStates;
-
-#define ESCAPE_P(accm, c) ((accm)[(c) >> 3] & pppACCMMask[c & 0x07])
-
-/************************/
-/*** LOCAL DATA TYPES ***/
-/************************/
-/*
- * PPP interface control block.
- */
-typedef struct PPPControl_s {
-    char openFlag;                      /* True when in use. */
-    char oldFrame;                      /* Old framing character for fd. */
-    sio_fd_t fd;                    /* File device ID of port. */
-    int  kill_link;                     /* Shut the link down. */
-    int  sig_hup;                       /* Carrier lost. */
-    int  if_up;                         /* True when the interface is up. */
-    int  errCode;                       /* Code indicating why interface is down. */
-    struct pbuf *inHead, *inTail;       /* The input packet. */
-    PPPDevStates inState;               /* The input process state. */
-    char inEscaped;                     /* Escape next character. */
-    u16_t inProtocol;                   /* The input protocol code. */
-    u16_t inFCS;                        /* Input Frame Check Sequence value. */
-    int  mtu;                           /* Peer's mru */
-    int  pcomp;                         /* Does peer accept protocol compression? */
-    int  accomp;                        /* Does peer accept addr/ctl compression? */
-    u_long lastXMit;                    /* Time of last transmission. */
-    ext_accm inACCM;                    /* Async-Ctl-Char-Map for input. */
-    ext_accm outACCM;                   /* Async-Ctl-Char-Map for output. */
-#if VJ_SUPPORT > 0
-    int  vjEnabled;                     /* Flag indicating VJ compression enabled. */
-    struct vjcompress vjComp;           /* Van Jabobsen compression header. */
-#endif
-
-    struct netif netif;
-
-    struct ppp_addrs addrs;
-
-    void (*linkStatusCB)(void *ctx, int errCode, void *arg);
-    void *linkStatusCtx;
-
-} PPPControl;
-
-
-/*
- * Ioctl definitions.
- */
-
-struct npioctl {
-    int     protocol;           /* PPP procotol, e.g. PPP_IP */
-    enum NPmode mode;
-};
-
-
-
-/***********************************/
-/*** LOCAL FUNCTION DECLARATIONS ***/
-/***********************************/
-static void pppMain(void *pd);
-static void pppDrop(PPPControl *pc);
-static void pppInProc(int pd, u_char *s, int l);
-
-
-/******************************/
-/*** PUBLIC DATA STRUCTURES ***/
-/******************************/
-u_long subnetMask;
-
-static PPPControl pppControl[NUM_PPP]; /* The PPP interface control blocks. */
-
-/*
- * PPP Data Link Layer "protocol" table.
- * One entry per supported protocol.
- * The last entry must be NULL.
- */
-struct protent *ppp_protocols[] = {
-    &lcp_protent,
-#if PAP_SUPPORT > 0
-    &pap_protent,
-#endif
-#if CHAP_SUPPORT > 0
-    &chap_protent,
-#endif
-#if CBCP_SUPPORT > 0
-    &cbcp_protent,
-#endif
-    &ipcp_protent,
-#if CCP_SUPPORT > 0
-    &ccp_protent,
-#endif
-    NULL
-};
-
-
-/*
- * Buffers for outgoing packets.  This must be accessed only from the appropriate
- * PPP task so that it doesn't need to be protected to avoid collisions.
- */
-u_char outpacket_buf[NUM_PPP][PPP_MRU+PPP_HDRLEN];  
-
-
-/*****************************/
-/*** LOCAL DATA STRUCTURES ***/
-/*****************************/
-
-/*
- * FCS lookup table as calculated by genfcstab.
- */
-static const u_short fcstab[256] = {
-    0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
-    0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
-    0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
-    0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
-    0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
-    0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
-    0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
-    0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
-    0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
-    0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
-    0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
-    0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
-    0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
-    0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
-    0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
-    0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
-    0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
-    0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
-    0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
-    0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
-    0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
-    0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
-    0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
-    0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
-    0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
-    0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
-    0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
-    0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
-    0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
-    0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
-    0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
-    0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
-};
-
-/* PPP's Asynchronous-Control-Character-Map.  The mask array is used
- * to select the specific bit for a character. */
-static u_char pppACCMMask[] = {
-    0x01,
-    0x02,
-    0x04,
-    0x08,
-    0x10,
-    0x20,
-    0x40,
-    0x80
-};
-
-
-/***********************************/
-/*** PUBLIC FUNCTION DEFINITIONS ***/
-/***********************************/
-/* Initialize the PPP subsystem. */
-
-struct ppp_settings ppp_settings;
-
-void pppInit(void)
-{
-    struct protent *protp;
-    int i, j;
-    
-       memset(&ppp_settings, 0, sizeof(ppp_settings));
-       ppp_settings.usepeerdns = 1;
-       pppSetAuth(PPPAUTHTYPE_NONE, NULL, NULL);
-
-       magicInit();
-
-    for (i = 0; i < NUM_PPP; i++) {
-        pppControl[i].openFlag = 0;
-
-               subnetMask = htonl(0xffffff00);
-    
-        /*
-         * Initialize to the standard option set.
-         */
-        for (j = 0; (protp = ppp_protocols[j]) != NULL; ++j)
-            (*protp->init)(i);
-    }
-
-#if LINK_STATS
-    /* Clear the statistics. */
-    memset(&lwip_stats.link, 0, sizeof(lwip_stats.link));
-#endif
-}
-
-void pppSetAuth(enum pppAuthType authType, const char *user, const char *passwd)
-{
-    switch(authType) {
-       case PPPAUTHTYPE_NONE:
-       default:
-#ifdef LWIP_PPP_STRICT_PAP_REJECT
-           ppp_settings.refuse_pap = 1;
-#else
-           /* some providers request pap and accept an empty login/pw */
-           ppp_settings.refuse_pap = 0;
-#endif
-           ppp_settings.refuse_chap = 1;
-           break;
-       case PPPAUTHTYPE_ANY:
-/* Warning: Using PPPAUTHTYPE_ANY might have security consequences.
- * RFC 1994 says:
- *
- * In practice, within or associated with each PPP server, there is a
- * database which associates "user" names with authentication
- * information ("secrets").  It is not anticipated that a particular
- * named user would be authenticated by multiple methods.  This would
- * make the user vulnerable to attacks which negotiate the least secure
- * method from among a set (such as PAP rather than CHAP).  If the same
- * secret was used, PAP would reveal the secret to be used later with
- * CHAP.
- *
- * Instead, for each user name there should be an indication of exactly
- * one method used to authenticate that user name.  If a user needs to
- * make use of different authentication methods under different
- * circumstances, then distinct user names SHOULD be employed, each of
- * which identifies exactly one authentication method.
- *
- */
-           ppp_settings.refuse_pap = 0;
-           ppp_settings.refuse_chap = 0;
-           break;
-       case PPPAUTHTYPE_PAP:
-           ppp_settings.refuse_pap = 0;
-           ppp_settings.refuse_chap = 1;
-           break;
-       case PPPAUTHTYPE_CHAP:
-           ppp_settings.refuse_pap = 1;
-           ppp_settings.refuse_chap = 0;
-           break;
-    }
-
-    if(user) {
-       strncpy(ppp_settings.user, user, sizeof(ppp_settings.user)-1);
-       ppp_settings.user[sizeof(ppp_settings.user)-1] = '\0';
-    } else
-       ppp_settings.user[0] = '\0';
-
-    if(passwd) {
-       strncpy(ppp_settings.passwd, passwd, sizeof(ppp_settings.passwd)-1);
-       ppp_settings.passwd[sizeof(ppp_settings.passwd)-1] = '\0';
-    } else
-       ppp_settings.passwd[0] = '\0';
-}
-
-/* Open a new PPP connection using the given I/O device.
- * This initializes the PPP control block but does not
- * attempt to negotiate the LCP session.  If this port
- * connects to a modem, the modem connection must be
- * established before calling this.
- * Return a new PPP connection descriptor on success or
- * an error code (negative) on failure. */
-int pppOpen(sio_fd_t fd, void (*linkStatusCB)(void *ctx, int errCode, void *arg), void *linkStatusCtx)
-{
-    PPPControl *pc;
-    int pd;
-
-    /* Find a free PPP session descriptor. Critical region? */
-    for (pd = 0; pd < NUM_PPP && pppControl[pd].openFlag != 0; pd++);
-    if (pd >= NUM_PPP)
-        pd = PPPERR_OPEN;
-    else
-        pppControl[pd].openFlag = !0;
-
-    /* Launch a deamon thread. */
-    if (pd >= 0) {
-
-        pppControl[pd].openFlag = 1;
-
-        lcp_init(pd);
-        pc = &pppControl[pd];
-        pc->fd = fd;
-        pc->kill_link = 0;
-        pc->sig_hup = 0;
-        pc->if_up = 0;
-        pc->errCode = 0;
-        pc->inState = PDIDLE;
-        pc->inHead = NULL;
-        pc->inTail = NULL;
-        pc->inEscaped = 0;
-        pc->lastXMit = 0;
-
-#if VJ_SUPPORT > 0
-        pc->vjEnabled = 0;
-        vj_compress_init(&pc->vjComp);
-#endif
-
-        /* 
-         * Default the in and out accm so that escape and flag characters
-         * are always escaped. 
-         */
-        memset(pc->inACCM, 0, sizeof(ext_accm));
-        pc->inACCM[15] = 0x60;
-        memset(pc->outACCM, 0, sizeof(ext_accm));
-        pc->outACCM[15] = 0x60;
-
-       pc->linkStatusCB = linkStatusCB;
-       pc->linkStatusCtx = linkStatusCtx;
-
-       sys_thread_new(pppMain, (void*)pd, PPP_THREAD_PRIO);
-       if(!linkStatusCB) {
-               while(pd >= 0 && !pc->if_up) {
-                       sys_msleep(500);
-                       if (lcp_phase[pd] == PHASE_DEAD) {
-                               pppClose(pd);
-                               if (pc->errCode)
-                                       pd = pc->errCode;
-                               else
-                                       pd = PPPERR_CONNECT;
-                       }
-               }
-       }
-    }
-    return pd;
-}
-
-/* Close a PPP connection and release the descriptor. 
- * Any outstanding packets in the queues are dropped.
- * Return 0 on success, an error code on failure. */
-int pppClose(int pd)
-{
-    PPPControl *pc = &pppControl[pd];
-    int st = 0;
-
-    /* Disconnect */
-    pc->kill_link = !0;
-    pppMainWakeup(pd);
-    
-    if(!pc->linkStatusCB) {
-           while(st >= 0 && lcp_phase[pd] != PHASE_DEAD) {
-                   sys_msleep(500);
-                   break;
-           }
-    }
-    return st;
-}
-
-/* This function is called when carrier is lost on the PPP channel. */
-void pppSigHUP(int pd)
-{
-    PPPControl *pc = &pppControl[pd];
-
-    pc->sig_hup = 1;
-    pppMainWakeup(pd);
-}
-
-static void nPut(PPPControl *pc, struct pbuf *nb)
-{
-       struct pbuf *b;
-       int c;
-
-       for(b = nb; b != NULL; b = b->next) {
-           if((c = sio_write(pc->fd, b->payload, b->len)) != b->len) {
-               PPPDEBUG((LOG_WARNING,
-                           "PPP nPut: incomplete sio_write(%d,, %u) = %d\n", pc->fd, b->len, c));
-#if LINK_STATS
-               lwip_stats.link.err++;
-#endif /* LINK_STATS */
-               pc->lastXMit = 0; /* prepend PPP_FLAG to next packet */
-               break;
-           }
-       }
-       pbuf_free(nb);
-
-#if LINK_STATS
-       lwip_stats.link.xmit++;
-#endif /* LINK_STATS */
-}
-
-/* 
- * pppAppend - append given character to end of given pbuf.  If outACCM
- * is not NULL and the character needs to be escaped, do so.
- * If pbuf is full, append another.
- * Return the current pbuf.
- */
-static struct pbuf *pppAppend(u_char c, struct pbuf *nb, ext_accm *outACCM)
-{
-    struct pbuf *tb = nb;
-    
-    /* Make sure there is room for the character and an escape code.
-     * Sure we don't quite fill the buffer if the character doesn't
-     * get escaped but is one character worth complicating this? */
-    /* Note: We assume no packet header. */
-    if (nb && (PBUF_POOL_BUFSIZE - nb->len) < 2) {
-       tb = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL);
-       if (tb) {
-           nb->next = tb;
-        }
-#if LINK_STATS
-       else {
-           lwip_stats.link.memerr++;
-       }
-#endif /* LINK_STATS */
-       nb = tb;
-    }
-    if (nb) {
-       if (outACCM && ESCAPE_P(*outACCM, c)) {
-            *((u_char*)nb->payload + nb->len++) = PPP_ESCAPE;
-            *((u_char*)nb->payload + nb->len++) = c ^ PPP_TRANS;
-        }
-        else
-            *((u_char*)nb->payload + nb->len++) = c;
-    }
-        
-    return tb;
-}
-
-/* Send a packet on the given connection. */
-static err_t pppifOutput(struct netif *netif, struct pbuf *pb, struct ip_addr *ipaddr)
-{
-    int pd = (int)netif->state;
-    u_short protocol = PPP_IP;
-    PPPControl *pc = &pppControl[pd];
-    u_int fcsOut = PPP_INITFCS;
-    struct pbuf *headMB = NULL, *tailMB = NULL, *p;
-    u_char c;
-
-    (void)ipaddr;
-
-    /* Validate parameters. */
-    /* We let any protocol value go through - it can't hurt us
-     * and the peer will just drop it if it's not accepting it. */
-       if (pd < 0 || pd >= NUM_PPP || !pc->openFlag || !pb) {
-        PPPDEBUG((LOG_WARNING, "pppifOutput[%d]: bad parms prot=%d pb=%p\n",
-                    pd, protocol, pb));
-#if LINK_STATS
-               lwip_stats.link.opterr++;
-               lwip_stats.link.drop++;
-#endif
-               return ERR_ARG;
-       }
-
-    /* Check that the link is up. */
-       if (lcp_phase[pd] == PHASE_DEAD) {
-        PPPDEBUG((LOG_ERR, "pppifOutput[%d]: link not up\n", pd));
-#if LINK_STATS
-               lwip_stats.link.rterr++;
-               lwip_stats.link.drop++;
-#endif
-               return ERR_RTE;
-       }
-
-    /* Grab an output buffer. */
-       headMB = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL);
-    if (headMB == NULL) {
-        PPPDEBUG((LOG_WARNING, "pppifOutput[%d]: first alloc fail\n", pd));
-#if LINK_STATS
-               lwip_stats.link.memerr++;
-               lwip_stats.link.drop++;
-#endif /* LINK_STATS */
-        return ERR_MEM;
-    }
-        
-#if VJ_SUPPORT > 0
-    /* 
-     * Attempt Van Jacobson header compression if VJ is configured and
-     * this is an IP packet. 
-     */
-    if (protocol == PPP_IP && pc->vjEnabled) {
-        switch (vj_compress_tcp(&pc->vjComp, pb)) {
-        case TYPE_IP:
-            /* No change...
-            protocol = PPP_IP_PROTOCOL;
-             */
-            break;
-        case TYPE_COMPRESSED_TCP:
-            protocol = PPP_VJC_COMP;
-            break;
-        case TYPE_UNCOMPRESSED_TCP:
-            protocol = PPP_VJC_UNCOMP;
-            break;
-        default:
-            PPPDEBUG((LOG_WARNING, "pppifOutput[%d]: bad IP packet\n", pd));
-#if LINK_STATS
-                       lwip_stats.link.proterr++;
-                       lwip_stats.link.drop++;
-#endif
-               pbuf_free(headMB);
-            return ERR_VAL;
-        }
-    }
-#endif
-        
-    tailMB = headMB;
-        
-    /* Build the PPP header. */
-    if ((sys_jiffies() - pc->lastXMit) >= PPP_MAXIDLEFLAG)
-        tailMB = pppAppend(PPP_FLAG, tailMB, NULL);
-    pc->lastXMit = sys_jiffies();
-    if (!pc->accomp) {
-        fcsOut = PPP_FCS(fcsOut, PPP_ALLSTATIONS);
-        tailMB = pppAppend(PPP_ALLSTATIONS, tailMB, &pc->outACCM);
-        fcsOut = PPP_FCS(fcsOut, PPP_UI);
-        tailMB = pppAppend(PPP_UI, tailMB, &pc->outACCM);
-    }
-    if (!pc->pcomp || protocol > 0xFF) {
-        c = (protocol >> 8) & 0xFF;
-        fcsOut = PPP_FCS(fcsOut, c);
-        tailMB = pppAppend(c, tailMB, &pc->outACCM);
-    }
-    c = protocol & 0xFF;
-    fcsOut = PPP_FCS(fcsOut, c);
-    tailMB = pppAppend(c, tailMB, &pc->outACCM);
-    
-    /* Load packet. */
-       for(p = pb; p; p = p->next) {
-       int n;
-       u_char *sPtr;
-
-        sPtr = (u_char*)p->payload;
-        n = p->len;
-        while (n-- > 0) {
-            c = *sPtr++;
-            
-            /* Update FCS before checking for special characters. */
-            fcsOut = PPP_FCS(fcsOut, c);
-            
-            /* Copy to output buffer escaping special characters. */
-            tailMB = pppAppend(c, tailMB, &pc->outACCM);
-        }
-    }
-
-    /* Add FCS and trailing flag. */
-    c = ~fcsOut & 0xFF;
-    tailMB = pppAppend(c, tailMB, &pc->outACCM);
-    c = (~fcsOut >> 8) & 0xFF;
-    tailMB = pppAppend(c, tailMB, &pc->outACCM);
-    tailMB = pppAppend(PPP_FLAG, tailMB, NULL);
-        
-    /* If we failed to complete the packet, throw it away. */
-    if (!tailMB) {
-        PPPDEBUG((LOG_WARNING,
-                    "pppifOutput[%d]: Alloc err - dropping proto=%d\n", 
-                    pd, protocol));
-        pbuf_free(headMB);
-#if LINK_STATS
-               lwip_stats.link.memerr++;
-               lwip_stats.link.drop++;
-#endif
-        return ERR_MEM;
-    }
-
-       /* Send it. */
-    PPPDEBUG((LOG_INFO, "pppifOutput[%d]: proto=0x%04X\n", pd, protocol));
-
-    nPut(pc, headMB);
-
-    return ERR_OK;
-}
-
-/* Get and set parameters for the given connection.
- * Return 0 on success, an error code on failure. */
-int  pppIOCtl(int pd, int cmd, void *arg)
-{
-    PPPControl *pc = &pppControl[pd];
-    int st = 0;
-
-    if (pd < 0 || pd >= NUM_PPP)
-        st = PPPERR_PARAM;
-    else {
-        switch(cmd) {
-        case PPPCTLG_UPSTATUS:      /* Get the PPP up status. */
-            if (arg) 
-                *(int *)arg = (int)(pc->if_up);
-            else
-                st = PPPERR_PARAM;
-            break;
-        case PPPCTLS_ERRCODE:       /* Set the PPP error code. */
-            if (arg) 
-                pc->errCode = *(int *)arg;
-            else
-                st = PPPERR_PARAM;
-            break;
-        case PPPCTLG_ERRCODE:       /* Get the PPP error code. */
-            if (arg) 
-                *(int *)arg = (int)(pc->errCode);
-            else
-                st = PPPERR_PARAM;
-            break;
-        case PPPCTLG_FD:
-            if (arg) 
-                *(sio_fd_t *)arg = pc->fd;
-            else
-                st = PPPERR_PARAM;
-            break;
-        default:
-            st = PPPERR_PARAM;
-            break;
-        }
-    }
-    
-    return st;
-}
-
-/*
- * Return the Maximum Transmission Unit for the given PPP connection.
- */
-u_int pppMTU(int pd)
-{
-    PPPControl *pc = &pppControl[pd];
-    u_int st;
-    
-    /* Validate parameters. */
-    if (pd < 0 || pd >= NUM_PPP || !pc->openFlag)
-        st = 0;
-    else
-        st = pc->mtu;
-        
-    return st;
-}
-
-/*
- * Write n characters to a ppp link.
- *  RETURN: >= 0 Number of characters written
- *           -1 Failed to write to device
- */
-int pppWrite(int pd, const u_char *s, int n)
-{
-    PPPControl *pc = &pppControl[pd];
-    u_char c;
-    u_int fcsOut = PPP_INITFCS;
-    struct pbuf *headMB = NULL, *tailMB;
-       headMB = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL);
-    if (headMB == NULL) {
-#if LINK_STATS
-               lwip_stats.link.memerr++;
-               lwip_stats.link.proterr++;
-#endif /* LINK_STATS */
-               return PPPERR_ALLOC;
-    }
-
-    tailMB = headMB;
-        
-    /* If the link has been idle, we'll send a fresh flag character to
-     * flush any noise. */
-    if ((sys_jiffies() - pc->lastXMit) >= PPP_MAXIDLEFLAG)
-        tailMB = pppAppend(PPP_FLAG, tailMB, NULL);
-    pc->lastXMit = sys_jiffies();
-     
-    /* Load output buffer. */
-    while (n-- > 0) {
-        c = *s++;
-        
-        /* Update FCS before checking for special characters. */
-        fcsOut = PPP_FCS(fcsOut, c);
-        
-        /* Copy to output buffer escaping special characters. */
-        tailMB = pppAppend(c, tailMB, &pc->outACCM);
-    }
-    
-    /* Add FCS and trailing flag. */
-    c = ~fcsOut & 0xFF;
-    tailMB = pppAppend(c, tailMB, &pc->outACCM);
-    c = (~fcsOut >> 8) & 0xFF;
-    tailMB = pppAppend(c, tailMB, &pc->outACCM);
-    tailMB = pppAppend(PPP_FLAG, tailMB, NULL);
-        
-    /* If we failed to complete the packet, throw it away.
-     * Otherwise send it. */
-    if (!tailMB) {
-               PPPDEBUG((LOG_WARNING,
-                "pppWrite[%d]: Alloc err - dropping pbuf len=%d\n", pd, headMB->len));
-/*                "pppWrite[%d]: Alloc err - dropping %d:%.*H", pd, headMB->len, LWIP_MIN(headMB->len * 2, 40), headMB->payload)); */
-               pbuf_free(headMB);
-#if LINK_STATS
-               lwip_stats.link.memerr++;
-               lwip_stats.link.proterr++;
-#endif /* LINK_STATS */
-               return PPPERR_ALLOC;
-       }
-
-    PPPDEBUG((LOG_INFO, "pppWrite[%d]: len=%d\n", pd, headMB->len));
-/*     "pppWrite[%d]: %d:%.*H", pd, headMB->len, LWIP_MIN(headMB->len * 2, 40), headMB->payload)); */
-    nPut(pc, headMB);
-
-    return PPPERR_NONE;
-}
-
-/*
- * ppp_send_config - configure the transmit characteristics of
- * the ppp interface.
- */
-void ppp_send_config(
-    int unit, 
-    int mtu,
-    u32_t asyncmap,
-    int pcomp, 
-    int accomp
-)
-{
-    PPPControl *pc = &pppControl[unit];
-    int i;
-    
-    pc->mtu = mtu;
-    pc->pcomp = pcomp;
-    pc->accomp = accomp;
-    
-    /* Load the ACCM bits for the 32 control codes. */
-    for (i = 0; i < 32/8; i++)
-        pc->outACCM[i] = (u_char)((asyncmap >> (8 * i)) & 0xFF);
-    PPPDEBUG((LOG_INFO, "ppp_send_config[%d]: outACCM=%X %X %X %X\n",
-                unit,
-                pc->outACCM[0], pc->outACCM[1], pc->outACCM[2], pc->outACCM[3]));
-}
-
-
-/*
- * ppp_set_xaccm - set the extended transmit ACCM for the interface.
- */
-void ppp_set_xaccm(int unit, ext_accm *accm)
-{
-    memcpy(pppControl[unit].outACCM, accm, sizeof(ext_accm));
-    PPPDEBUG((LOG_INFO, "ppp_set_xaccm[%d]: outACCM=%X %X %X %X\n",
-                unit,
-                pppControl[unit].outACCM[0],
-                pppControl[unit].outACCM[1],
-                pppControl[unit].outACCM[2],
-                pppControl[unit].outACCM[3]));
-}
-
-
-/*
- * ppp_recv_config - configure the receive-side characteristics of
- * the ppp interface.
- */
-void ppp_recv_config(
-    int unit, 
-    int mru,
-    u32_t asyncmap,
-    int pcomp, 
-    int accomp
-)
-{
-    PPPControl *pc = &pppControl[unit];
-    int i;
-    
-       (void)accomp;
-       (void)pcomp;
-       (void)mru;
-
-    /* Load the ACCM bits for the 32 control codes. */
-    for (i = 0; i < 32 / 8; i++)
-        pc->inACCM[i] = (u_char)(asyncmap >> (i * 8));
-    PPPDEBUG((LOG_INFO, "ppp_recv_config[%d]: inACCM=%X %X %X %X\n",
-                unit,
-                pc->inACCM[0], pc->inACCM[1], pc->inACCM[2], pc->inACCM[3]));
-}
-
-#if 0
-/*
- * ccp_test - ask kernel whether a given compression method
- * is acceptable for use.  Returns 1 if the method and parameters
- * are OK, 0 if the method is known but the parameters are not OK
- * (e.g. code size should be reduced), or -1 if the method is unknown.
- */
-int ccp_test(
-    int unit, 
-    int opt_len, 
-    int for_transmit,
-    u_char *opt_ptr
-)
-{
-    return 0;   /* XXX Currently no compression. */
-}
-
-/*
- * ccp_flags_set - inform kernel about the current state of CCP.
- */
-void ccp_flags_set(int unit, int isopen, int isup)
-{
-    /* XXX */
-}
-
-/*
- * ccp_fatal_error - returns 1 if decompression was disabled as a
- * result of an error detected after decompression of a packet,
- * 0 otherwise.  This is necessary because of patent nonsense.
- */
-int ccp_fatal_error(int unit)
-{
-    /* XXX */
-    return 0;
-}
-#endif
-
-/*
- * get_idle_time - return how long the link has been idle.
- */
-int get_idle_time(int u, struct ppp_idle *ip)
-{   
-    /* XXX */
-       (void)u;
-       (void)ip;
-
-    return 0;
-}
-
-
-/*
- * Return user specified netmask, modified by any mask we might determine
- * for address `addr' (in network byte order).
- * Here we scan through the system's list of interfaces, looking for
- * any non-point-to-point interfaces which might appear to be on the same
- * network as `addr'.  If we find any, we OR in their netmask to the
- * user-specified netmask.
- */
-u32_t GetMask(u32_t addr)
-{
-    u32_t mask, nmask;
-    
-    htonl(addr);
-    if (IN_CLASSA(addr))    /* determine network mask for address class */
-        nmask = IN_CLASSA_NET;
-    else if (IN_CLASSB(addr))
-        nmask = IN_CLASSB_NET;
-    else
-        nmask = IN_CLASSC_NET;
-    /* class D nets are disallowed by bad_ip_adrs */
-    mask = subnetMask | htonl(nmask);
-    
-    /* XXX
-     * Scan through the system's network interfaces.
-     * Get each netmask and OR them into our mask.
-     */
-    
-    return mask;
-}
-
-/*
- * sifvjcomp - config tcp header compression
- */
-int sifvjcomp(
-    int pd, 
-    int vjcomp, 
-    int cidcomp, 
-    int maxcid
-)
-{
-#if VJ_SUPPORT > 0
-    PPPControl *pc = &pppControl[pd];
-    
-    pc->vjEnabled = vjcomp;
-    pc->vjComp.compressSlot = cidcomp;
-    pc->vjComp.maxSlotIndex = maxcid;
-    PPPDEBUG((LOG_INFO, "sifvjcomp: VJ compress enable=%d slot=%d max slot=%d\n",
-                vjcomp, cidcomp, maxcid));
-#endif
-
-    return 0;
-}
-
-/*
- * pppifNetifInit - netif init callback
- */
-static err_t pppifNetifInit(struct netif *netif)
-{
-       netif->name[0] = 'p';
-       netif->name[1] = 'p';
-       netif->output = pppifOutput;
-       netif->mtu = pppMTU((int)netif->state);
-       return ERR_OK;
-}
-
-
-/*
- * sifup - Config the interface up and enable IP packets to pass.
- */
-int sifup(int pd)
-{
-    PPPControl *pc = &pppControl[pd];
-    int st = 1;
-    
-    if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) {
-        st = 0;
-        PPPDEBUG((LOG_WARNING, "sifup[%d]: bad parms\n", pd));
-    } else {
-               netif_remove(&pc->netif);
-               if (netif_add(&pc->netif, &pc->addrs.our_ipaddr, &pc->addrs.netmask, &pc->addrs.his_ipaddr, (void *)pd, pppifNetifInit, ip_input)) {
-                       pc->if_up = 1;
-                       pc->errCode = PPPERR_NONE;
-
-                       PPPDEBUG((LOG_DEBUG, "sifup: unit %d: linkStatusCB=%lx errCode=%d\n", pd, pc->linkStatusCB, pc->errCode));
-                       if(pc->linkStatusCB)
-                               pc->linkStatusCB(pc->linkStatusCtx, pc->errCode, &pc->addrs);
-               } else {
-               st = 0;
-               PPPDEBUG((LOG_ERR, "sifup[%d]: netif_add failed\n", pd));
-               }
-    }
-
-    return st;
-}
-
-/*
- * sifnpmode - Set the mode for handling packets for a given NP.
- */
-int sifnpmode(int u, int proto, enum NPmode mode)
-{
-       (void)u;
-       (void)proto;
-       (void)mode;
-    return 0;
-}
-
-/*
- * sifdown - Config the interface down and disable IP.
- */
-int sifdown(int pd)
-{
-    PPPControl *pc = &pppControl[pd];
-    int st = 1;
-    
-    if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) {
-        st = 0;
-        PPPDEBUG((LOG_WARNING, "sifdown[%d]: bad parms\n", pd));
-    } else {
-        pc->if_up = 0;
-       netif_remove(&pc->netif);
-       PPPDEBUG((LOG_DEBUG, "sifdown: unit %d: linkStatusCB=%lx errCode=%d\n", pd, pc->linkStatusCB, pc->errCode));
-       if(pc->linkStatusCB)
-               pc->linkStatusCB(pc->linkStatusCtx, PPPERR_CONNECT, NULL);
-       }
-    return st;
-}
-
-/*
- * sifaddr - Config the interface IP addresses and netmask.
- */
-int sifaddr(
-    int pd,             /* Interface unit ??? */
-    u32_t o,        /* Our IP address ??? */
-    u32_t h,        /* His IP address ??? */
-    u32_t m,        /* IP subnet mask ??? */
-    u32_t ns1,      /* Primary DNS */
-    u32_t ns2       /* Secondary DNS */
-)
-{
-    PPPControl *pc = &pppControl[pd];
-    int st = 1;
-    
-    if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) {
-        st = 0;
-        PPPDEBUG((LOG_WARNING, "sifup[%d]: bad parms\n", pd));
-    } else {
-               memcpy(&pc->addrs.our_ipaddr, &o, sizeof(o));
-               memcpy(&pc->addrs.his_ipaddr, &h, sizeof(h));
-               memcpy(&pc->addrs.netmask, &m, sizeof(m));
-               memcpy(&pc->addrs.dns1, &ns1, sizeof(ns1));
-               memcpy(&pc->addrs.dns2, &ns2, sizeof(ns2));
-    }
-    return st;
-}
-
-/*
- * cifaddr - Clear the interface IP addresses, and delete routes
- * through the interface if possible.
- */
-int cifaddr(
-    int pd,         /* Interface unit ??? */
-    u32_t o,    /* Our IP address ??? */
-    u32_t h     /* IP broadcast address ??? */
-)
-{
-    PPPControl *pc = &pppControl[pd];
-    int st = 1;
-    
-       (void)o;
-       (void)h;
-    if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) {
-        st = 0;
-        PPPDEBUG((LOG_WARNING, "sifup[%d]: bad parms\n", pd));
-    } else {
-               IP4_ADDR(&pc->addrs.our_ipaddr, 0,0,0,0);
-               IP4_ADDR(&pc->addrs.his_ipaddr, 0,0,0,0);
-               IP4_ADDR(&pc->addrs.netmask, 255,255,255,0);
-               IP4_ADDR(&pc->addrs.dns1, 0,0,0,0);
-               IP4_ADDR(&pc->addrs.dns2, 0,0,0,0);
-    }
-    return st;
-}
-
-/*
- * sifdefaultroute - assign a default route through the address given.
- */
-int sifdefaultroute(int pd, u32_t l, u32_t g)
-{
-    PPPControl *pc = &pppControl[pd];
-    int st = 1;
-    
-       (void)l;
-       (void)g;
-    if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) {
-        st = 0;
-        PPPDEBUG((LOG_WARNING, "sifup[%d]: bad parms\n", pd));
-    } else {
-               netif_set_default(&pc->netif);
-    }
-
-    /* TODO: check how PPP handled the netMask, previously not set by ipSetDefault */
-
-    return st;
-}
-
-/*
- * cifdefaultroute - delete a default route through the address given.
- */
-int cifdefaultroute(int pd, u32_t l, u32_t g)
-{
-    PPPControl *pc = &pppControl[pd];
-    int st = 1;
-    
-       (void)l;
-       (void)g;
-    if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) {
-        st = 0;
-        PPPDEBUG((LOG_WARNING, "sifup[%d]: bad parms\n", pd));
-    } else {
-               netif_set_default(NULL);
-    }
-
-    return st;
-}
-
-void
-pppMainWakeup(int pd)
-{
-       PPPDEBUG((LOG_DEBUG, "pppMainWakeup: unit %d\n", pd));
-       sio_read_abort(pppControl[pd].fd);
-}
-
-/* these callbacks are necessary because lcp_* functions
-   must be called in the same context as pppInput(),
-   namely the tcpip_thread(), essentially because
-   they manipulate timeouts which are thread-private
-*/
-
-static void
-pppStartCB(void *arg)
-{
-    int pd = (int)arg;
-
-       PPPDEBUG((LOG_DEBUG, "pppStartCB: unit %d\n", pd));
-    lcp_lowerup(pd);
-    lcp_open(pd);      /* Start protocol */
-}
-
-static void
-pppStopCB(void *arg)
-{
-    int pd = (int)arg;
-
-       PPPDEBUG((LOG_DEBUG, "pppStopCB: unit %d\n", pd));
-    lcp_close(pd, "User request");
-}
-
-static void
-pppHupCB(void *arg)
-{
-    int pd = (int)arg;
-
-       PPPDEBUG((LOG_DEBUG, "pppHupCB: unit %d\n", pd));
-    lcp_lowerdown(pd);
-    link_terminated(pd);
-}
-/**********************************/
-/*** LOCAL FUNCTION DEFINITIONS ***/
-/**********************************/
-/* The main PPP process function.  This implements the state machine according
- * to section 4 of RFC 1661: The Point-To-Point Protocol. */
-static void pppMain(void *arg)
-{
-    int pd = (int)arg;
-    struct pbuf *p;
-    PPPControl* pc;
-
-    pc = &pppControl[pd];
-
-    p = pbuf_alloc(PBUF_RAW, PPP_MRU+PPP_HDRLEN, PBUF_RAM);
-    if(!p) {
-               LWIP_ASSERT("p != NULL", p);
-               pc->errCode = PPPERR_ALLOC;
-               goto out;
-    }
-
-    /*
-     * Start the connection and handle incoming events (packet or timeout).
-     */
-       PPPDEBUG((LOG_INFO, "pppMain: unit %d: Connecting\n", pd));
-    tcpip_callback(pppStartCB, arg);
-    while (lcp_phase[pd] != PHASE_DEAD) {
-        if (pc->kill_link) {
-               PPPDEBUG((LOG_DEBUG, "pppMainWakeup: unit %d kill_link -> pppStopCB\n", pd));
-               pc->errCode = PPPERR_USER;
-               /* This will leave us at PHASE_DEAD. */
-               tcpip_callback(pppStopCB, arg);
-               pc->kill_link = 0;
-        }
-        else if (pc->sig_hup) {
-               PPPDEBUG((LOG_DEBUG, "pppMainWakeup: unit %d sig_hup -> pppHupCB\n", pd));
-               pc->sig_hup = 0;
-               tcpip_callback(pppHupCB, arg);
-        } else {
-               int c = sio_read(pc->fd, p->payload, p->len);
-               if(c > 0) {
-                       pppInProc(pd, p->payload, c);
-               } else {
-                   PPPDEBUG((LOG_DEBUG, "pppMainWakeup: unit %d sio_read len=%d returned %d\n", pd, p->len, c));
-                   sys_msleep(1); /* give other tasks a chance to run */
-               }
-        }
-    }
-       PPPDEBUG((LOG_INFO, "pppMain: unit %d: PHASE_DEAD\n", pd));
-    pbuf_free(p);
-
-out:
-       PPPDEBUG((LOG_DEBUG, "pppMain: unit %d: linkStatusCB=%lx errCode=%d\n", pd, pc->linkStatusCB, pc->errCode));
-    if(pc->linkStatusCB)
-           pc->linkStatusCB(pc->linkStatusCtx, pc->errCode ? pc->errCode : PPPERR_PROTOCOL, NULL);
-
-    pc->openFlag = 0;
-}
-
-static struct pbuf *pppSingleBuf(struct pbuf *p)
-{
-       struct pbuf *q, *b;
-       u_char *pl;
-
-       if(p->tot_len == p->len)
-               return p;
-
-       q = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM);
-       if(!q) {
-               PPPDEBUG((LOG_ERR,
-                        "pppSingleBuf: unable to alloc new buf (%d)\n", p->tot_len));
-               return p; /* live dangerously */
-       }
-
-       for(b = p, pl = q->payload; b != NULL; b = b->next) {
-               memcpy(pl, b->payload, b->len);
-               pl += b->len;
-       }
-
-       pbuf_free(p);
-
-       return q;
-}
-
-struct pppInputHeader {
-       int unit;
-       u16_t proto;
-};
-
-/*
- * Pass the processed input packet to the appropriate handler.
- * This function and all handlers run in the context of the tcpip_thread
- */
-static void pppInput(void *arg)
-{
-       struct pbuf *nb = (struct pbuf *)arg;
-    u16_t protocol;
-    int pd;
-
-       pd = ((struct pppInputHeader *)nb->payload)->unit;
-       protocol = ((struct pppInputHeader *)nb->payload)->proto;
-
-    pbuf_header(nb, -(int)sizeof(struct pppInputHeader));
-
-#if LINK_STATS
-    lwip_stats.link.recv++;
-#endif /* LINK_STATS */
-
-    /*
-     * Toss all non-LCP packets unless LCP is OPEN.
-     * Until we get past the authentication phase, toss all packets
-     * except LCP, LQR and authentication packets.
-     */
-    if((lcp_phase[pd] <= PHASE_AUTHENTICATE) && (protocol != PPP_LCP)) {
-           if(!((protocol == PPP_LQR) || (protocol == PPP_PAP) || (protocol == PPP_CHAP)) ||
-                       (lcp_phase[pd] != PHASE_AUTHENTICATE)) {
-               PPPDEBUG((LOG_INFO, "pppInput: discarding proto 0x%04X in phase %d\n", protocol, lcp_phase[pd]));
-               goto drop;
-           }
-    }
-
-    switch(protocol) {
-    case PPP_VJC_COMP:      /* VJ compressed TCP */
-#if VJ_SUPPORT > 0
-        PPPDEBUG((LOG_INFO, "pppInput[%d]: vj_comp in pbuf len=%d\n", pd, nb->len));
-        /*
-         * Clip off the VJ header and prepend the rebuilt TCP/IP header and
-         * pass the result to IP.
-         */
-        if (vj_uncompress_tcp(&nb, &pppControl[pd].vjComp) >= 0) {
-            pppControl[pd].netif.input(nb, &pppControl[pd].netif);
-                       return;
-        }
-       /* Something's wrong so drop it. */
-       PPPDEBUG((LOG_WARNING, "pppInput[%d]: Dropping VJ compressed\n", pd));
-#else
-        /* No handler for this protocol so drop the packet. */
-        PPPDEBUG((LOG_INFO, "pppInput[%d]: drop VJ Comp in %d:%s\n", pd, nb->len, nb->payload));
-#endif /* VJ_SUPPORT > 0 */
-       break;
-    case PPP_VJC_UNCOMP:    /* VJ uncompressed TCP */
-#if VJ_SUPPORT > 0
-        PPPDEBUG((LOG_INFO, "pppInput[%d]: vj_un in pbuf len=%d\n", pd, nb->len));
-        /*
-         * Process the TCP/IP header for VJ header compression and then pass
-         * the packet to IP.
-         */
-        if (vj_uncompress_uncomp(nb, &pppControl[pd].vjComp) >= 0) {
-            pppControl[pd].netif.input(nb, &pppControl[pd].netif);
-                       return;
-        }
-       /* Something's wrong so drop it. */
-       PPPDEBUG((LOG_WARNING, "pppInput[%d]: Dropping VJ uncompressed\n", pd));
-#else
-        /* No handler for this protocol so drop the packet. */
-        PPPDEBUG((LOG_INFO,
-                    "pppInput[%d]: drop VJ UnComp in %d:.*H\n", 
-                    pd, nb->len, LWIP_MIN(nb->len * 2, 40), nb->payload));
-#endif /* VJ_SUPPORT > 0 */
-       break;
-    case PPP_IP:            /* Internet Protocol */
-        PPPDEBUG((LOG_INFO, "pppInput[%d]: ip in pbuf len=%d\n", pd, nb->len));
-        pppControl[pd].netif.input(nb, &pppControl[pd].netif);
-               return;
-    default:
-       {
-               struct protent *protp;
-               int i;
-
-               /*
-                * Upcall the proper protocol input routine.
-                */
-               for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i) {
-                       if (protp->protocol == protocol && protp->enabled_flag) {
-                               PPPDEBUG((LOG_INFO, "pppInput[%d]: %s len=%d\n", pd, protp->name, nb->len));
-                               nb = pppSingleBuf(nb);
-                               (*protp->input)(pd, nb->payload, nb->len);
-                               goto out;
-                       }
-               }
-
-               /* No handler for this protocol so reject the packet. */
-               PPPDEBUG((LOG_INFO, "pppInput[%d]: rejecting unsupported proto 0x%04X len=%d\n", pd, protocol, nb->len));
-               pbuf_header(nb, sizeof(protocol));
-#if BYTE_ORDER == LITTLE_ENDIAN
-               protocol = htons(protocol);
-               memcpy(nb->payload, &protocol, sizeof(protocol));
-#endif
-               lcp_sprotrej(pd, nb->payload, nb->len);
-       }
-       break;
-    }
-
-drop:
-#if LINK_STATS
-    lwip_stats.link.drop++;
-#endif
-
-out:
-    pbuf_free(nb);
-    return;
-}
-
-
-/*
- * Drop the input packet.
- */
-static void pppDrop(PPPControl *pc)
-{
-    if (pc->inHead != NULL) {
-#if 0      
-        PPPDEBUG((LOG_INFO, "pppDrop: %d:%.*H\n", pc->inHead->len, min(60, pc->inHead->len * 2), pc->inHead->payload));
-#endif 
-        PPPDEBUG((LOG_INFO, "pppDrop: pbuf len=%d\n", pc->inHead->len));
-       if (pc->inTail && (pc->inTail != pc->inHead))
-           pbuf_free(pc->inTail);
-        pbuf_free(pc->inHead);
-        pc->inHead = NULL;
-        pc->inTail = NULL;
-    }
-#if VJ_SUPPORT > 0
-    vj_uncompress_err(&pc->vjComp);
-#endif
-
-#if LINK_STATS
-    lwip_stats.link.drop++;
-#endif /* LINK_STATS */
-}
-
-
-/*
- * Process a received octet string.
- */
-static void pppInProc(int pd, u_char *s, int l)
-{
-    PPPControl *pc = &pppControl[pd];
-    struct pbuf *nextNBuf;
-    u_char curChar;
-
-    PPPDEBUG((LOG_DEBUG, "pppInProc[%d]: got %d bytes\n", pd, l));
-    while (l-- > 0) {
-        curChar = *s++;
-        
-        /* Handle special characters. */
-        if (ESCAPE_P(pc->inACCM, curChar)) {
-            /* Check for escape sequences. */
-            /* XXX Note that this does not handle an escaped 0x5d character which
-             * would appear as an escape character.  Since this is an ASCII ']'
-             * and there is no reason that I know of to escape it, I won't complicate
-             * the code to handle this case. GLL */
-            if (curChar == PPP_ESCAPE)
-                pc->inEscaped = 1;
-            /* Check for the flag character. */
-            else if (curChar == PPP_FLAG) {
-                /* If this is just an extra flag character, ignore it. */
-                if (pc->inState <= PDADDRESS)
-                    ;
-                /* If we haven't received the packet header, drop what has come in. */
-                else if (pc->inState < PDDATA) {
-                    PPPDEBUG((LOG_WARNING,
-                                "pppInProc[%d]: Dropping incomplete packet %d\n", 
-                                pd, pc->inState));
-#if LINK_STATS
-                                       lwip_stats.link.lenerr++;
-#endif
-                    pppDrop(pc);
-                }
-                /* If the fcs is invalid, drop the packet. */
-                else if (pc->inFCS != PPP_GOODFCS) {
-                    PPPDEBUG((LOG_INFO,
-                                "pppInProc[%d]: Dropping bad fcs 0x%04X proto=0x%04X\n", 
-                                pd, pc->inFCS, pc->inProtocol));
-#if LINK_STATS
-                                       lwip_stats.link.chkerr++;
-#endif
-                    pppDrop(pc);
-                }
-                /* Otherwise it's a good packet so pass it on. */
-                else {
-                    
-                    /* Trim off the checksum. */
-                   if(pc->inTail->len >= 2) {
-                       pc->inTail->len -= 2;
-
-                       pc->inTail->tot_len = pc->inTail->len;
-                       if (pc->inTail != pc->inHead) {
-                           pbuf_cat(pc->inHead, pc->inTail);
-                       }
-                   } else {
-                       pc->inTail->tot_len = pc->inTail->len;
-                       if (pc->inTail != pc->inHead) {
-                           pbuf_cat(pc->inHead, pc->inTail);
-                       }
-
-                       pbuf_realloc(pc->inHead, pc->inHead->tot_len - 2);
-                   }
-
-                    /* Dispatch the packet thereby consuming it. */
-                   if(tcpip_callback(pppInput, pc->inHead) != ERR_OK) {
-                       PPPDEBUG((LOG_ERR,
-                                   "pppInProc[%d]: tcpip_callback() failed, dropping packet\n", pd));
-                       pbuf_free(pc->inHead);
-#if LINK_STATS
-                       lwip_stats.link.drop++;
-#endif
-                   }
-                    pc->inHead = NULL;
-                    pc->inTail = NULL;
-                }
-                    
-                /* Prepare for a new packet. */
-                pc->inFCS = PPP_INITFCS;
-                pc->inState = PDADDRESS;
-                pc->inEscaped = 0;
-            }
-            /* Other characters are usually control characters that may have
-             * been inserted by the physical layer so here we just drop them. */
-            else {
-                PPPDEBUG((LOG_WARNING,
-                            "pppInProc[%d]: Dropping ACCM char <%d>\n", pd, curChar));
-            }
-        }
-        /* Process other characters. */
-        else {
-            /* Unencode escaped characters. */
-            if (pc->inEscaped) {
-                pc->inEscaped = 0;
-                curChar ^= PPP_TRANS;
-            }
-            
-            /* Process character relative to current state. */
-            switch(pc->inState) {
-            case PDIDLE:                    /* Idle state - waiting. */
-                /* Drop the character if it's not 0xff
-                 * we would have processed a flag character above. */
-                if (curChar != PPP_ALLSTATIONS) {
-                       break;
-                               }
-
-                               /* Fall through */
-            case PDSTART:                   /* Process start flag. */
-                /* Prepare for a new packet. */
-                pc->inFCS = PPP_INITFCS;
-
-                               /* Fall through */
-            case PDADDRESS:                 /* Process address field. */
-                if (curChar == PPP_ALLSTATIONS) {
-                    pc->inState = PDCONTROL;
-                    break;
-                }
-                /* Else assume compressed address and control fields so
-                 * fall through to get the protocol... */
-            case PDCONTROL:                 /* Process control field. */
-                /* If we don't get a valid control code, restart. */
-                if (curChar == PPP_UI) {
-                    pc->inState = PDPROTOCOL1;
-                       break;
-                }
-#if 0
-                else {
-                    PPPDEBUG((LOG_WARNING,
-                                "pppInProc[%d]: Invalid control <%d>\n", pd, curChar));
-                    pc->inState = PDSTART;
-                }
-#endif
-            case PDPROTOCOL1:               /* Process protocol field 1. */
-                /* If the lower bit is set, this is the end of the protocol
-                 * field. */
-                if (curChar & 1) {
-                    pc->inProtocol = curChar;
-                    pc->inState = PDDATA;
-                }
-                else {
-                    pc->inProtocol = (u_int)curChar << 8;
-                    pc->inState = PDPROTOCOL2;
-                }
-                break;
-            case PDPROTOCOL2:               /* Process protocol field 2. */
-                pc->inProtocol |= curChar;
-                pc->inState = PDDATA;
-                break;
-            case PDDATA:                    /* Process data byte. */
-                /* Make space to receive processed data. */
-                if (pc->inTail == NULL || pc->inTail->len == PBUF_POOL_BUFSIZE) {
-                   if(pc->inTail) {
-                       pc->inTail->tot_len = pc->inTail->len;
-                       if (pc->inTail != pc->inHead) {
-                           pbuf_cat(pc->inHead, pc->inTail);
-                       }
-                   }
-                    /* If we haven't started a packet, we need a packet header. */
-                    nextNBuf = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL);
-                    if (nextNBuf == NULL) {
-                        /* No free buffers.  Drop the input packet and let the
-                         * higher layers deal with it.  Continue processing
-                         * the received pbuf chain in case a new packet starts. */
-                        PPPDEBUG((LOG_ERR, "pppInProc[%d]: NO FREE MBUFS!\n", pd));
-#if LINK_STATS
-                                               lwip_stats.link.memerr++;
-#endif /* LINK_STATS */
-                        pppDrop(pc);
-                        pc->inState = PDSTART;  /* Wait for flag sequence. */
-                       break;
-                    }
-                   if (pc->inHead == NULL) {
-                       struct pppInputHeader *pih = nextNBuf->payload;
-
-                       pih->unit = pd;
-                       pih->proto = pc->inProtocol;
-
-                       nextNBuf->len += sizeof(*pih);
-
-                       pc->inHead = nextNBuf;
-                   }
-                   pc->inTail = nextNBuf;
-                }
-                /* Load character into buffer. */
-                ((u_char*)pc->inTail->payload)[pc->inTail->len++] = curChar;
-                break;
-            }
-
-            /* update the frame check sequence number. */
-            pc->inFCS = PPP_FCS(pc->inFCS, curChar);
-        }
-    }
-       avRandomize();
-}
-
-#endif /* PPP_SUPPORT */
+/*****************************************************************************\r
+* ppp.c - Network Point to Point Protocol program file.\r
+*\r
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.\r
+* portions Copyright (c) 1997 by Global Election Systems Inc.\r
+*\r
+* The authors hereby grant permission to use, copy, modify, distribute,\r
+* and license this software and its documentation for any purpose, provided\r
+* that existing copyright notices are retained in all copies and that this\r
+* notice and the following disclaimer are included verbatim in any \r
+* distributions. No written agreement, license, or royalty fee is required\r
+* for any of the authorized uses.\r
+*\r
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR\r
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+*\r
+******************************************************************************\r
+* REVISION HISTORY\r
+*\r
+* 03-01-01 Marc Boucher <marc@mbsi.ca>\r
+*   Ported to lwIP.\r
+* 97-11-05 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.\r
+*   Original.\r
+*****************************************************************************/\r
+\r
+/*\r
+ * ppp_defs.h - PPP definitions.\r
+ *\r
+ * if_pppvar.h - private structures and declarations for PPP.\r
+ *\r
+ * Copyright (c) 1994 The Australian National University.\r
+ * All rights reserved.\r
+ *\r
+ * Permission to use, copy, modify, and distribute this software and its\r
+ * documentation is hereby granted, provided that the above copyright\r
+ * notice appears in all copies.  This software is provided without any\r
+ * warranty, express or implied. The Australian National University\r
+ * makes no representations about the suitability of this software for\r
+ * any purpose.\r
+ *\r
+ * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY\r
+ * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES\r
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF\r
+ * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY\r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,\r
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY\r
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS\r
+ * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO\r
+ * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,\r
+ * OR MODIFICATIONS.\r
+ */\r
+\r
+/*\r
+ * if_ppp.h - Point-to-Point Protocol definitions.\r
+ *\r
+ * Copyright (c) 1989 Carnegie Mellon University.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms are permitted\r
+ * provided that the above copyright notice and this paragraph are\r
+ * duplicated in all such forms and that any documentation,\r
+ * advertising materials, and other materials related to such\r
+ * distribution and use acknowledge that the software was developed\r
+ * by Carnegie Mellon University.  The name of the\r
+ * University may not be used to endorse or promote products derived\r
+ * from this software without specific prior written permission.\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR\r
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r
+ */\r
\r
+#include <string.h>\r
\r
+#include "ppp.h"\r
+#if PPP_SUPPORT > 0\r
+#include "randm.h"\r
+#include "fsm.h"\r
+#if PAP_SUPPORT > 0\r
+#include "pap.h"\r
+#endif\r
+#if CHAP_SUPPORT > 0\r
+#include "chap.h"\r
+#endif\r
+#include "ipcp.h"\r
+#include "lcp.h"\r
+#include "magic.h"\r
+#include "auth.h"\r
+#if VJ_SUPPORT > 0\r
+#include "vj.h"\r
+#endif\r
+\r
+#include "pppdebug.h"\r
+\r
+/*************************/\r
+/*** LOCAL DEFINITIONS ***/\r
+/*************************/\r
+\r
+/*\r
+ * The basic PPP frame.\r
+ */\r
+#define PPP_ADDRESS(p)  (((u_char *)(p))[0])\r
+#define PPP_CONTROL(p)  (((u_char *)(p))[1])\r
+#define PPP_PROTOCOL(p) ((((u_char *)(p))[2] << 8) + ((u_char *)(p))[3])\r
+\r
+/* PPP packet parser states.  Current state indicates operation yet to be\r
+ * completed. */\r
+typedef enum {\r
+    PDIDLE = 0,                 /* Idle state - waiting. */\r
+    PDSTART,                    /* Process start flag. */\r
+    PDADDRESS,                  /* Process address field. */\r
+    PDCONTROL,                  /* Process control field. */\r
+    PDPROTOCOL1,                /* Process protocol field 1. */\r
+    PDPROTOCOL2,                /* Process protocol field 2. */\r
+    PDDATA                      /* Process data byte. */\r
+} PPPDevStates;\r
+\r
+#define ESCAPE_P(accm, c) ((accm)[(c) >> 3] & pppACCMMask[c & 0x07])\r
+\r
+/************************/\r
+/*** LOCAL DATA TYPES ***/\r
+/************************/\r
+/*\r
+ * PPP interface control block.\r
+ */\r
+typedef struct PPPControl_s {\r
+    char openFlag;                      /* True when in use. */\r
+    char oldFrame;                      /* Old framing character for fd. */\r
+    sio_fd_t fd;                    /* File device ID of port. */\r
+    int  kill_link;                     /* Shut the link down. */\r
+    int  sig_hup;                       /* Carrier lost. */\r
+    int  if_up;                         /* True when the interface is up. */\r
+    int  errCode;                       /* Code indicating why interface is down. */\r
+    struct pbuf *inHead, *inTail;       /* The input packet. */\r
+    PPPDevStates inState;               /* The input process state. */\r
+    char inEscaped;                     /* Escape next character. */\r
+    u16_t inProtocol;                   /* The input protocol code. */\r
+    u16_t inFCS;                        /* Input Frame Check Sequence value. */\r
+    int  mtu;                           /* Peer's mru */\r
+    int  pcomp;                         /* Does peer accept protocol compression? */\r
+    int  accomp;                        /* Does peer accept addr/ctl compression? */\r
+    u_long lastXMit;                    /* Time of last transmission. */\r
+    ext_accm inACCM;                    /* Async-Ctl-Char-Map for input. */\r
+    ext_accm outACCM;                   /* Async-Ctl-Char-Map for output. */\r
+#if VJ_SUPPORT > 0\r
+    int  vjEnabled;                     /* Flag indicating VJ compression enabled. */\r
+    struct vjcompress vjComp;           /* Van Jabobsen compression header. */\r
+#endif\r
+\r
+    struct netif netif;\r
+\r
+    struct ppp_addrs addrs;\r
+\r
+    void (*linkStatusCB)(void *ctx, int errCode, void *arg);\r
+    void *linkStatusCtx;\r
+\r
+} PPPControl;\r
+\r
+\r
+/*\r
+ * Ioctl definitions.\r
+ */\r
+\r
+struct npioctl {\r
+    int     protocol;           /* PPP procotol, e.g. PPP_IP */\r
+    enum NPmode mode;\r
+};\r
+\r
+\r
+\r
+/***********************************/\r
+/*** LOCAL FUNCTION DECLARATIONS ***/\r
+/***********************************/\r
+static void pppMain(void *pd);\r
+static void pppDrop(PPPControl *pc);\r
+static void pppInProc(int pd, u_char *s, int l);\r
+\r
+\r
+/******************************/\r
+/*** PUBLIC DATA STRUCTURES ***/\r
+/******************************/\r
+u_long subnetMask;\r
+\r
+static PPPControl pppControl[NUM_PPP]; /* The PPP interface control blocks. */\r
+\r
+/*\r
+ * PPP Data Link Layer "protocol" table.\r
+ * One entry per supported protocol.\r
+ * The last entry must be NULL.\r
+ */\r
+struct protent *ppp_protocols[] = {\r
+    &lcp_protent,\r
+#if PAP_SUPPORT > 0\r
+    &pap_protent,\r
+#endif\r
+#if CHAP_SUPPORT > 0\r
+    &chap_protent,\r
+#endif\r
+#if CBCP_SUPPORT > 0\r
+    &cbcp_protent,\r
+#endif\r
+    &ipcp_protent,\r
+#if CCP_SUPPORT > 0\r
+    &ccp_protent,\r
+#endif\r
+    NULL\r
+};\r
+\r
+\r
+/*\r
+ * Buffers for outgoing packets.  This must be accessed only from the appropriate\r
+ * PPP task so that it doesn't need to be protected to avoid collisions.\r
+ */\r
+u_char outpacket_buf[NUM_PPP][PPP_MRU+PPP_HDRLEN];  \r
+\r
+\r
+/*****************************/\r
+/*** LOCAL DATA STRUCTURES ***/\r
+/*****************************/\r
+\r
+/*\r
+ * FCS lookup table as calculated by genfcstab.\r
+ */\r
+static const u_short fcstab[256] = {\r
+    0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,\r
+    0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,\r
+    0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,\r
+    0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,\r
+    0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,\r
+    0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,\r
+    0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,\r
+    0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,\r
+    0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,\r
+    0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,\r
+    0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,\r
+    0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,\r
+    0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,\r
+    0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,\r
+    0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,\r
+    0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,\r
+    0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,\r
+    0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,\r
+    0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,\r
+    0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,\r
+    0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,\r
+    0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,\r
+    0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,\r
+    0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,\r
+    0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,\r
+    0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,\r
+    0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,\r
+    0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,\r
+    0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,\r
+    0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,\r
+    0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,\r
+    0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78\r
+};\r
+\r
+/* PPP's Asynchronous-Control-Character-Map.  The mask array is used\r
+ * to select the specific bit for a character. */\r
+static u_char pppACCMMask[] = {\r
+    0x01,\r
+    0x02,\r
+    0x04,\r
+    0x08,\r
+    0x10,\r
+    0x20,\r
+    0x40,\r
+    0x80\r
+};\r
+\r
+\r
+/***********************************/\r
+/*** PUBLIC FUNCTION DEFINITIONS ***/\r
+/***********************************/\r
+/* Initialize the PPP subsystem. */\r
+\r
+struct ppp_settings ppp_settings;\r
+\r
+void pppInit(void)\r
+{\r
+    struct protent *protp;\r
+    int i, j;\r
+    \r
+       memset(&ppp_settings, 0, sizeof(ppp_settings));\r
+       ppp_settings.usepeerdns = 1;\r
+       pppSetAuth(PPPAUTHTYPE_NONE, NULL, NULL);\r
+\r
+       magicInit();\r
+\r
+    for (i = 0; i < NUM_PPP; i++) {\r
+        pppControl[i].openFlag = 0;\r
+\r
+               subnetMask = htonl(0xffffff00);\r
+    \r
+        /*\r
+         * Initialize to the standard option set.\r
+         */\r
+        for (j = 0; (protp = ppp_protocols[j]) != NULL; ++j)\r
+            (*protp->init)(i);\r
+    }\r
+\r
+#if LINK_STATS\r
+    /* Clear the statistics. */\r
+    memset(&lwip_stats.link, 0, sizeof(lwip_stats.link));\r
+#endif\r
+}\r
+\r
+void pppSetAuth(enum pppAuthType authType, const char *user, const char *passwd)\r
+{\r
+    switch(authType) {\r
+       case PPPAUTHTYPE_NONE:\r
+       default:\r
+#ifdef LWIP_PPP_STRICT_PAP_REJECT\r
+           ppp_settings.refuse_pap = 1;\r
+#else\r
+           /* some providers request pap and accept an empty login/pw */\r
+           ppp_settings.refuse_pap = 0;\r
+#endif\r
+           ppp_settings.refuse_chap = 1;\r
+           break;\r
+       case PPPAUTHTYPE_ANY:\r
+/* Warning: Using PPPAUTHTYPE_ANY might have security consequences.\r
+ * RFC 1994 says:\r
+ *\r
+ * In practice, within or associated with each PPP server, there is a\r
+ * database which associates "user" names with authentication\r
+ * information ("secrets").  It is not anticipated that a particular\r
+ * named user would be authenticated by multiple methods.  This would\r
+ * make the user vulnerable to attacks which negotiate the least secure\r
+ * method from among a set (such as PAP rather than CHAP).  If the same\r
+ * secret was used, PAP would reveal the secret to be used later with\r
+ * CHAP.\r
+ *\r
+ * Instead, for each user name there should be an indication of exactly\r
+ * one method used to authenticate that user name.  If a user needs to\r
+ * make use of different authentication methods under different\r
+ * circumstances, then distinct user names SHOULD be employed, each of\r
+ * which identifies exactly one authentication method.\r
+ *\r
+ */\r
+           ppp_settings.refuse_pap = 0;\r
+           ppp_settings.refuse_chap = 0;\r
+           break;\r
+       case PPPAUTHTYPE_PAP:\r
+           ppp_settings.refuse_pap = 0;\r
+           ppp_settings.refuse_chap = 1;\r
+           break;\r
+       case PPPAUTHTYPE_CHAP:\r
+           ppp_settings.refuse_pap = 1;\r
+           ppp_settings.refuse_chap = 0;\r
+           break;\r
+    }\r
+\r
+    if(user) {\r
+       strncpy(ppp_settings.user, user, sizeof(ppp_settings.user)-1);\r
+       ppp_settings.user[sizeof(ppp_settings.user)-1] = '\0';\r
+    } else\r
+       ppp_settings.user[0] = '\0';\r
+\r
+    if(passwd) {\r
+       strncpy(ppp_settings.passwd, passwd, sizeof(ppp_settings.passwd)-1);\r
+       ppp_settings.passwd[sizeof(ppp_settings.passwd)-1] = '\0';\r
+    } else\r
+       ppp_settings.passwd[0] = '\0';\r
+}\r
+\r
+/* Open a new PPP connection using the given I/O device.\r
+ * This initializes the PPP control block but does not\r
+ * attempt to negotiate the LCP session.  If this port\r
+ * connects to a modem, the modem connection must be\r
+ * established before calling this.\r
+ * Return a new PPP connection descriptor on success or\r
+ * an error code (negative) on failure. */\r
+int pppOpen(sio_fd_t fd, void (*linkStatusCB)(void *ctx, int errCode, void *arg), void *linkStatusCtx)\r
+{\r
+    PPPControl *pc;\r
+    int pd;\r
+\r
+    /* Find a free PPP session descriptor. Critical region? */\r
+    for (pd = 0; pd < NUM_PPP && pppControl[pd].openFlag != 0; pd++);\r
+    if (pd >= NUM_PPP)\r
+        pd = PPPERR_OPEN;\r
+    else\r
+        pppControl[pd].openFlag = !0;\r
+\r
+    /* Launch a deamon thread. */\r
+    if (pd >= 0) {\r
+\r
+        pppControl[pd].openFlag = 1;\r
+\r
+        lcp_init(pd);\r
+        pc = &pppControl[pd];\r
+        pc->fd = fd;\r
+        pc->kill_link = 0;\r
+        pc->sig_hup = 0;\r
+        pc->if_up = 0;\r
+        pc->errCode = 0;\r
+        pc->inState = PDIDLE;\r
+        pc->inHead = NULL;\r
+        pc->inTail = NULL;\r
+        pc->inEscaped = 0;\r
+        pc->lastXMit = 0;\r
+\r
+#if VJ_SUPPORT > 0\r
+        pc->vjEnabled = 0;\r
+        vj_compress_init(&pc->vjComp);\r
+#endif\r
+\r
+        /* \r
+         * Default the in and out accm so that escape and flag characters\r
+         * are always escaped. \r
+         */\r
+        memset(pc->inACCM, 0, sizeof(ext_accm));\r
+        pc->inACCM[15] = 0x60;\r
+        memset(pc->outACCM, 0, sizeof(ext_accm));\r
+        pc->outACCM[15] = 0x60;\r
+\r
+       pc->linkStatusCB = linkStatusCB;\r
+       pc->linkStatusCtx = linkStatusCtx;\r
+\r
+       sys_thread_new(pppMain, (void*)pd, PPP_THREAD_PRIO);\r
+       if(!linkStatusCB) {\r
+               while(pd >= 0 && !pc->if_up) {\r
+                       sys_msleep(500);\r
+                       if (lcp_phase[pd] == PHASE_DEAD) {\r
+                               pppClose(pd);\r
+                               if (pc->errCode)\r
+                                       pd = pc->errCode;\r
+                               else\r
+                                       pd = PPPERR_CONNECT;\r
+                       }\r
+               }\r
+       }\r
+    }\r
+    return pd;\r
+}\r
+\r
+/* Close a PPP connection and release the descriptor. \r
+ * Any outstanding packets in the queues are dropped.\r
+ * Return 0 on success, an error code on failure. */\r
+int pppClose(int pd)\r
+{\r
+    PPPControl *pc = &pppControl[pd];\r
+    int st = 0;\r
+\r
+    /* Disconnect */\r
+    pc->kill_link = !0;\r
+    pppMainWakeup(pd);\r
+    \r
+    if(!pc->linkStatusCB) {\r
+           while(st >= 0 && lcp_phase[pd] != PHASE_DEAD) {\r
+                   sys_msleep(500);\r
+                   break;\r
+           }\r
+    }\r
+    return st;\r
+}\r
+\r
+/* This function is called when carrier is lost on the PPP channel. */\r
+void pppSigHUP(int pd)\r
+{\r
+    PPPControl *pc = &pppControl[pd];\r
+\r
+    pc->sig_hup = 1;\r
+    pppMainWakeup(pd);\r
+}\r
+\r
+static void nPut(PPPControl *pc, struct pbuf *nb)\r
+{\r
+       struct pbuf *b;\r
+       int c;\r
+\r
+       for(b = nb; b != NULL; b = b->next) {\r
+           if((c = sio_write(pc->fd, b->payload, b->len)) != b->len) {\r
+               PPPDEBUG((LOG_WARNING,\r
+                           "PPP nPut: incomplete sio_write(%d,, %u) = %d\n", pc->fd, b->len, c));\r
+#if LINK_STATS\r
+               lwip_stats.link.err++;\r
+#endif /* LINK_STATS */\r
+               pc->lastXMit = 0; /* prepend PPP_FLAG to next packet */\r
+               break;\r
+           }\r
+       }\r
+       pbuf_free(nb);\r
+\r
+#if LINK_STATS\r
+       lwip_stats.link.xmit++;\r
+#endif /* LINK_STATS */\r
+}\r
+\r
+/* \r
+ * pppAppend - append given character to end of given pbuf.  If outACCM\r
+ * is not NULL and the character needs to be escaped, do so.\r
+ * If pbuf is full, append another.\r
+ * Return the current pbuf.\r
+ */\r
+static struct pbuf *pppAppend(u_char c, struct pbuf *nb, ext_accm *outACCM)\r
+{\r
+    struct pbuf *tb = nb;\r
+    \r
+    /* Make sure there is room for the character and an escape code.\r
+     * Sure we don't quite fill the buffer if the character doesn't\r
+     * get escaped but is one character worth complicating this? */\r
+    /* Note: We assume no packet header. */\r
+    if (nb && (PBUF_POOL_BUFSIZE - nb->len) < 2) {\r
+       tb = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL);\r
+       if (tb) {\r
+           nb->next = tb;\r
+        }\r
+#if LINK_STATS\r
+       else {\r
+           lwip_stats.link.memerr++;\r
+       }\r
+#endif /* LINK_STATS */\r
+       nb = tb;\r
+    }\r
+    if (nb) {\r
+       if (outACCM && ESCAPE_P(*outACCM, c)) {\r
+            *((u_char*)nb->payload + nb->len++) = PPP_ESCAPE;\r
+            *((u_char*)nb->payload + nb->len++) = c ^ PPP_TRANS;\r
+        }\r
+        else\r
+            *((u_char*)nb->payload + nb->len++) = c;\r
+    }\r
+        \r
+    return tb;\r
+}\r
+\r
+/* Send a packet on the given connection. */\r
+static err_t pppifOutput(struct netif *netif, struct pbuf *pb, struct ip_addr *ipaddr)\r
+{\r
+    int pd = (int)netif->state;\r
+    u_short protocol = PPP_IP;\r
+    PPPControl *pc = &pppControl[pd];\r
+    u_int fcsOut = PPP_INITFCS;\r
+    struct pbuf *headMB = NULL, *tailMB = NULL, *p;\r
+    u_char c;\r
+\r
+    (void)ipaddr;\r
+\r
+    /* Validate parameters. */\r
+    /* We let any protocol value go through - it can't hurt us\r
+     * and the peer will just drop it if it's not accepting it. */\r
+       if (pd < 0 || pd >= NUM_PPP || !pc->openFlag || !pb) {\r
+        PPPDEBUG((LOG_WARNING, "pppifOutput[%d]: bad parms prot=%d pb=%p\n",\r
+                    pd, protocol, pb));\r
+#if LINK_STATS\r
+               lwip_stats.link.opterr++;\r
+               lwip_stats.link.drop++;\r
+#endif\r
+               return ERR_ARG;\r
+       }\r
+\r
+    /* Check that the link is up. */\r
+       if (lcp_phase[pd] == PHASE_DEAD) {\r
+        PPPDEBUG((LOG_ERR, "pppifOutput[%d]: link not up\n", pd));\r
+#if LINK_STATS\r
+               lwip_stats.link.rterr++;\r
+               lwip_stats.link.drop++;\r
+#endif\r
+               return ERR_RTE;\r
+       }\r
+\r
+    /* Grab an output buffer. */\r
+       headMB = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL);\r
+    if (headMB == NULL) {\r
+        PPPDEBUG((LOG_WARNING, "pppifOutput[%d]: first alloc fail\n", pd));\r
+#if LINK_STATS\r
+               lwip_stats.link.memerr++;\r
+               lwip_stats.link.drop++;\r
+#endif /* LINK_STATS */\r
+        return ERR_MEM;\r
+    }\r
+        \r
+#if VJ_SUPPORT > 0\r
+    /* \r
+     * Attempt Van Jacobson header compression if VJ is configured and\r
+     * this is an IP packet. \r
+     */\r
+    if (protocol == PPP_IP && pc->vjEnabled) {\r
+        switch (vj_compress_tcp(&pc->vjComp, pb)) {\r
+        case TYPE_IP:\r
+            /* No change...\r
+            protocol = PPP_IP_PROTOCOL;\r
+             */\r
+            break;\r
+        case TYPE_COMPRESSED_TCP:\r
+            protocol = PPP_VJC_COMP;\r
+            break;\r
+        case TYPE_UNCOMPRESSED_TCP:\r
+            protocol = PPP_VJC_UNCOMP;\r
+            break;\r
+        default:\r
+            PPPDEBUG((LOG_WARNING, "pppifOutput[%d]: bad IP packet\n", pd));\r
+#if LINK_STATS\r
+                       lwip_stats.link.proterr++;\r
+                       lwip_stats.link.drop++;\r
+#endif\r
+               pbuf_free(headMB);\r
+            return ERR_VAL;\r
+        }\r
+    }\r
+#endif\r
+        \r
+    tailMB = headMB;\r
+        \r
+    /* Build the PPP header. */\r
+    if ((sys_jiffies() - pc->lastXMit) >= PPP_MAXIDLEFLAG)\r
+        tailMB = pppAppend(PPP_FLAG, tailMB, NULL);\r
+    pc->lastXMit = sys_jiffies();\r
+    if (!pc->accomp) {\r
+        fcsOut = PPP_FCS(fcsOut, PPP_ALLSTATIONS);\r
+        tailMB = pppAppend(PPP_ALLSTATIONS, tailMB, &pc->outACCM);\r
+        fcsOut = PPP_FCS(fcsOut, PPP_UI);\r
+        tailMB = pppAppend(PPP_UI, tailMB, &pc->outACCM);\r
+    }\r
+    if (!pc->pcomp || protocol > 0xFF) {\r
+        c = (protocol >> 8) & 0xFF;\r
+        fcsOut = PPP_FCS(fcsOut, c);\r
+        tailMB = pppAppend(c, tailMB, &pc->outACCM);\r
+    }\r
+    c = protocol & 0xFF;\r
+    fcsOut = PPP_FCS(fcsOut, c);\r
+    tailMB = pppAppend(c, tailMB, &pc->outACCM);\r
+    \r
+    /* Load packet. */\r
+       for(p = pb; p; p = p->next) {\r
+       int n;\r
+       u_char *sPtr;\r
+\r
+        sPtr = (u_char*)p->payload;\r
+        n = p->len;\r
+        while (n-- > 0) {\r
+            c = *sPtr++;\r
+            \r
+            /* Update FCS before checking for special characters. */\r
+            fcsOut = PPP_FCS(fcsOut, c);\r
+            \r
+            /* Copy to output buffer escaping special characters. */\r
+            tailMB = pppAppend(c, tailMB, &pc->outACCM);\r
+        }\r
+    }\r
+\r
+    /* Add FCS and trailing flag. */\r
+    c = ~fcsOut & 0xFF;\r
+    tailMB = pppAppend(c, tailMB, &pc->outACCM);\r
+    c = (~fcsOut >> 8) & 0xFF;\r
+    tailMB = pppAppend(c, tailMB, &pc->outACCM);\r
+    tailMB = pppAppend(PPP_FLAG, tailMB, NULL);\r
+        \r
+    /* If we failed to complete the packet, throw it away. */\r
+    if (!tailMB) {\r
+        PPPDEBUG((LOG_WARNING,\r
+                    "pppifOutput[%d]: Alloc err - dropping proto=%d\n", \r
+                    pd, protocol));\r
+        pbuf_free(headMB);\r
+#if LINK_STATS\r
+               lwip_stats.link.memerr++;\r
+               lwip_stats.link.drop++;\r
+#endif\r
+        return ERR_MEM;\r
+    }\r
+\r
+       /* Send it. */\r
+    PPPDEBUG((LOG_INFO, "pppifOutput[%d]: proto=0x%04X\n", pd, protocol));\r
+\r
+    nPut(pc, headMB);\r
+\r
+    return ERR_OK;\r
+}\r
+\r
+/* Get and set parameters for the given connection.\r
+ * Return 0 on success, an error code on failure. */\r
+int  pppIOCtl(int pd, int cmd, void *arg)\r
+{\r
+    PPPControl *pc = &pppControl[pd];\r
+    int st = 0;\r
+\r
+    if (pd < 0 || pd >= NUM_PPP)\r
+        st = PPPERR_PARAM;\r
+    else {\r
+        switch(cmd) {\r
+        case PPPCTLG_UPSTATUS:      /* Get the PPP up status. */\r
+            if (arg) \r
+                *(int *)arg = (int)(pc->if_up);\r
+            else\r
+                st = PPPERR_PARAM;\r
+            break;\r
+        case PPPCTLS_ERRCODE:       /* Set the PPP error code. */\r
+            if (arg) \r
+                pc->errCode = *(int *)arg;\r
+            else\r
+                st = PPPERR_PARAM;\r
+            break;\r
+        case PPPCTLG_ERRCODE:       /* Get the PPP error code. */\r
+            if (arg) \r
+                *(int *)arg = (int)(pc->errCode);\r
+            else\r
+                st = PPPERR_PARAM;\r
+            break;\r
+        case PPPCTLG_FD:\r
+            if (arg) \r
+                *(sio_fd_t *)arg = pc->fd;\r
+            else\r
+                st = PPPERR_PARAM;\r
+            break;\r
+        default:\r
+            st = PPPERR_PARAM;\r
+            break;\r
+        }\r
+    }\r
+    \r
+    return st;\r
+}\r
+\r
+/*\r
+ * Return the Maximum Transmission Unit for the given PPP connection.\r
+ */\r
+u_int pppMTU(int pd)\r
+{\r
+    PPPControl *pc = &pppControl[pd];\r
+    u_int st;\r
+    \r
+    /* Validate parameters. */\r
+    if (pd < 0 || pd >= NUM_PPP || !pc->openFlag)\r
+        st = 0;\r
+    else\r
+        st = pc->mtu;\r
+        \r
+    return st;\r
+}\r
+\r
+/*\r
+ * Write n characters to a ppp link.\r
+ *  RETURN: >= 0 Number of characters written\r
+ *           -1 Failed to write to device\r
+ */\r
+int pppWrite(int pd, const u_char *s, int n)\r
+{\r
+    PPPControl *pc = &pppControl[pd];\r
+    u_char c;\r
+    u_int fcsOut = PPP_INITFCS;\r
+    struct pbuf *headMB = NULL, *tailMB;\r
+       headMB = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL);\r
+    if (headMB == NULL) {\r
+#if LINK_STATS\r
+               lwip_stats.link.memerr++;\r
+               lwip_stats.link.proterr++;\r
+#endif /* LINK_STATS */\r
+               return PPPERR_ALLOC;\r
+    }\r
+\r
+    tailMB = headMB;\r
+        \r
+    /* If the link has been idle, we'll send a fresh flag character to\r
+     * flush any noise. */\r
+    if ((sys_jiffies() - pc->lastXMit) >= PPP_MAXIDLEFLAG)\r
+        tailMB = pppAppend(PPP_FLAG, tailMB, NULL);\r
+    pc->lastXMit = sys_jiffies();\r
+     \r
+    /* Load output buffer. */\r
+    while (n-- > 0) {\r
+        c = *s++;\r
+        \r
+        /* Update FCS before checking for special characters. */\r
+        fcsOut = PPP_FCS(fcsOut, c);\r
+        \r
+        /* Copy to output buffer escaping special characters. */\r
+        tailMB = pppAppend(c, tailMB, &pc->outACCM);\r
+    }\r
+    \r
+    /* Add FCS and trailing flag. */\r
+    c = ~fcsOut & 0xFF;\r
+    tailMB = pppAppend(c, tailMB, &pc->outACCM);\r
+    c = (~fcsOut >> 8) & 0xFF;\r
+    tailMB = pppAppend(c, tailMB, &pc->outACCM);\r
+    tailMB = pppAppend(PPP_FLAG, tailMB, NULL);\r
+        \r
+    /* If we failed to complete the packet, throw it away.\r
+     * Otherwise send it. */\r
+    if (!tailMB) {\r
+               PPPDEBUG((LOG_WARNING,\r
+                "pppWrite[%d]: Alloc err - dropping pbuf len=%d\n", pd, headMB->len));\r
+/*                "pppWrite[%d]: Alloc err - dropping %d:%.*H", pd, headMB->len, LWIP_MIN(headMB->len * 2, 40), headMB->payload)); */\r
+               pbuf_free(headMB);\r
+#if LINK_STATS\r
+               lwip_stats.link.memerr++;\r
+               lwip_stats.link.proterr++;\r
+#endif /* LINK_STATS */\r
+               return PPPERR_ALLOC;\r
+       }\r
+\r
+    PPPDEBUG((LOG_INFO, "pppWrite[%d]: len=%d\n", pd, headMB->len));\r
+/*     "pppWrite[%d]: %d:%.*H", pd, headMB->len, LWIP_MIN(headMB->len * 2, 40), headMB->payload)); */\r
+    nPut(pc, headMB);\r
+\r
+    return PPPERR_NONE;\r
+}\r
+\r
+/*\r
+ * ppp_send_config - configure the transmit characteristics of\r
+ * the ppp interface.\r
+ */\r
+void ppp_send_config(\r
+    int unit, \r
+    int mtu,\r
+    u32_t asyncmap,\r
+    int pcomp, \r
+    int accomp\r
+)\r
+{\r
+    PPPControl *pc = &pppControl[unit];\r
+    int i;\r
+    \r
+    pc->mtu = mtu;\r
+    pc->pcomp = pcomp;\r
+    pc->accomp = accomp;\r
+    \r
+    /* Load the ACCM bits for the 32 control codes. */\r
+    for (i = 0; i < 32/8; i++)\r
+        pc->outACCM[i] = (u_char)((asyncmap >> (8 * i)) & 0xFF);\r
+    PPPDEBUG((LOG_INFO, "ppp_send_config[%d]: outACCM=%X %X %X %X\n",\r
+                unit,\r
+                pc->outACCM[0], pc->outACCM[1], pc->outACCM[2], pc->outACCM[3]));\r
+}\r
+\r
+\r
+/*\r
+ * ppp_set_xaccm - set the extended transmit ACCM for the interface.\r
+ */\r
+void ppp_set_xaccm(int unit, ext_accm *accm)\r
+{\r
+    memcpy(pppControl[unit].outACCM, accm, sizeof(ext_accm));\r
+    PPPDEBUG((LOG_INFO, "ppp_set_xaccm[%d]: outACCM=%X %X %X %X\n",\r
+                unit,\r
+                pppControl[unit].outACCM[0],\r
+                pppControl[unit].outACCM[1],\r
+                pppControl[unit].outACCM[2],\r
+                pppControl[unit].outACCM[3]));\r
+}\r
+\r
+\r
+/*\r
+ * ppp_recv_config - configure the receive-side characteristics of\r
+ * the ppp interface.\r
+ */\r
+void ppp_recv_config(\r
+    int unit, \r
+    int mru,\r
+    u32_t asyncmap,\r
+    int pcomp, \r
+    int accomp\r
+)\r
+{\r
+    PPPControl *pc = &pppControl[unit];\r
+    int i;\r
+    \r
+       (void)accomp;\r
+       (void)pcomp;\r
+       (void)mru;\r
+\r
+    /* Load the ACCM bits for the 32 control codes. */\r
+    for (i = 0; i < 32 / 8; i++)\r
+        pc->inACCM[i] = (u_char)(asyncmap >> (i * 8));\r
+    PPPDEBUG((LOG_INFO, "ppp_recv_config[%d]: inACCM=%X %X %X %X\n",\r
+                unit,\r
+                pc->inACCM[0], pc->inACCM[1], pc->inACCM[2], pc->inACCM[3]));\r
+}\r
+\r
+#if 0\r
+/*\r
+ * ccp_test - ask kernel whether a given compression method\r
+ * is acceptable for use.  Returns 1 if the method and parameters\r
+ * are OK, 0 if the method is known but the parameters are not OK\r
+ * (e.g. code size should be reduced), or -1 if the method is unknown.\r
+ */\r
+int ccp_test(\r
+    int unit, \r
+    int opt_len, \r
+    int for_transmit,\r
+    u_char *opt_ptr\r
+)\r
+{\r
+    return 0;   /* XXX Currently no compression. */\r
+}\r
+\r
+/*\r
+ * ccp_flags_set - inform kernel about the current state of CCP.\r
+ */\r
+void ccp_flags_set(int unit, int isopen, int isup)\r
+{\r
+    /* XXX */\r
+}\r
+\r
+/*\r
+ * ccp_fatal_error - returns 1 if decompression was disabled as a\r
+ * result of an error detected after decompression of a packet,\r
+ * 0 otherwise.  This is necessary because of patent nonsense.\r
+ */\r
+int ccp_fatal_error(int unit)\r
+{\r
+    /* XXX */\r
+    return 0;\r
+}\r
+#endif\r
+\r
+/*\r
+ * get_idle_time - return how long the link has been idle.\r
+ */\r
+int get_idle_time(int u, struct ppp_idle *ip)\r
+{   \r
+    /* XXX */\r
+       (void)u;\r
+       (void)ip;\r
+\r
+    return 0;\r
+}\r
+\r
+\r
+/*\r
+ * Return user specified netmask, modified by any mask we might determine\r
+ * for address `addr' (in network byte order).\r
+ * Here we scan through the system's list of interfaces, looking for\r
+ * any non-point-to-point interfaces which might appear to be on the same\r
+ * network as `addr'.  If we find any, we OR in their netmask to the\r
+ * user-specified netmask.\r
+ */\r
+u32_t GetMask(u32_t addr)\r
+{\r
+    u32_t mask, nmask;\r
+    \r
+    htonl(addr);\r
+    if (IN_CLASSA(addr))    /* determine network mask for address class */\r
+        nmask = IN_CLASSA_NET;\r
+    else if (IN_CLASSB(addr))\r
+        nmask = IN_CLASSB_NET;\r
+    else\r
+        nmask = IN_CLASSC_NET;\r
+    /* class D nets are disallowed by bad_ip_adrs */\r
+    mask = subnetMask | htonl(nmask);\r
+    \r
+    /* XXX\r
+     * Scan through the system's network interfaces.\r
+     * Get each netmask and OR them into our mask.\r
+     */\r
+    \r
+    return mask;\r
+}\r
+\r
+/*\r
+ * sifvjcomp - config tcp header compression\r
+ */\r
+int sifvjcomp(\r
+    int pd, \r
+    int vjcomp, \r
+    int cidcomp, \r
+    int maxcid\r
+)\r
+{\r
+#if VJ_SUPPORT > 0\r
+    PPPControl *pc = &pppControl[pd];\r
+    \r
+    pc->vjEnabled = vjcomp;\r
+    pc->vjComp.compressSlot = cidcomp;\r
+    pc->vjComp.maxSlotIndex = maxcid;\r
+    PPPDEBUG((LOG_INFO, "sifvjcomp: VJ compress enable=%d slot=%d max slot=%d\n",\r
+                vjcomp, cidcomp, maxcid));\r
+#endif\r
+\r
+    return 0;\r
+}\r
+\r
+/*\r
+ * pppifNetifInit - netif init callback\r
+ */\r
+static err_t pppifNetifInit(struct netif *netif)\r
+{\r
+       netif->name[0] = 'p';\r
+       netif->name[1] = 'p';\r
+       netif->output = pppifOutput;\r
+       netif->mtu = pppMTU((int)netif->state);\r
+       return ERR_OK;\r
+}\r
+\r
+\r
+/*\r
+ * sifup - Config the interface up and enable IP packets to pass.\r
+ */\r
+int sifup(int pd)\r
+{\r
+    PPPControl *pc = &pppControl[pd];\r
+    int st = 1;\r
+    \r
+    if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) {\r
+        st = 0;\r
+        PPPDEBUG((LOG_WARNING, "sifup[%d]: bad parms\n", pd));\r
+    } else {\r
+               netif_remove(&pc->netif);\r
+               if (netif_add(&pc->netif, &pc->addrs.our_ipaddr, &pc->addrs.netmask, &pc->addrs.his_ipaddr, (void *)pd, pppifNetifInit, ip_input)) {\r
+                       pc->if_up = 1;\r
+                       pc->errCode = PPPERR_NONE;\r
+\r
+                       PPPDEBUG((LOG_DEBUG, "sifup: unit %d: linkStatusCB=%lx errCode=%d\n", pd, pc->linkStatusCB, pc->errCode));\r
+                       if(pc->linkStatusCB)\r
+                               pc->linkStatusCB(pc->linkStatusCtx, pc->errCode, &pc->addrs);\r
+               } else {\r
+               st = 0;\r
+               PPPDEBUG((LOG_ERR, "sifup[%d]: netif_add failed\n", pd));\r
+               }\r
+    }\r
+\r
+    return st;\r
+}\r
+\r
+/*\r
+ * sifnpmode - Set the mode for handling packets for a given NP.\r
+ */\r
+int sifnpmode(int u, int proto, enum NPmode mode)\r
+{\r
+       (void)u;\r
+       (void)proto;\r
+       (void)mode;\r
+    return 0;\r
+}\r
+\r
+/*\r
+ * sifdown - Config the interface down and disable IP.\r
+ */\r
+int sifdown(int pd)\r
+{\r
+    PPPControl *pc = &pppControl[pd];\r
+    int st = 1;\r
+    \r
+    if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) {\r
+        st = 0;\r
+        PPPDEBUG((LOG_WARNING, "sifdown[%d]: bad parms\n", pd));\r
+    } else {\r
+        pc->if_up = 0;\r
+       netif_remove(&pc->netif);\r
+       PPPDEBUG((LOG_DEBUG, "sifdown: unit %d: linkStatusCB=%lx errCode=%d\n", pd, pc->linkStatusCB, pc->errCode));\r
+       if(pc->linkStatusCB)\r
+               pc->linkStatusCB(pc->linkStatusCtx, PPPERR_CONNECT, NULL);\r
+       }\r
+    return st;\r
+}\r
+\r
+/*\r
+ * sifaddr - Config the interface IP addresses and netmask.\r
+ */\r
+int sifaddr(\r
+    int pd,             /* Interface unit ??? */\r
+    u32_t o,        /* Our IP address ??? */\r
+    u32_t h,        /* His IP address ??? */\r
+    u32_t m,        /* IP subnet mask ??? */\r
+    u32_t ns1,      /* Primary DNS */\r
+    u32_t ns2       /* Secondary DNS */\r
+)\r
+{\r
+    PPPControl *pc = &pppControl[pd];\r
+    int st = 1;\r
+    \r
+    if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) {\r
+        st = 0;\r
+        PPPDEBUG((LOG_WARNING, "sifup[%d]: bad parms\n", pd));\r
+    } else {\r
+               memcpy(&pc->addrs.our_ipaddr, &o, sizeof(o));\r
+               memcpy(&pc->addrs.his_ipaddr, &h, sizeof(h));\r
+               memcpy(&pc->addrs.netmask, &m, sizeof(m));\r
+               memcpy(&pc->addrs.dns1, &ns1, sizeof(ns1));\r
+               memcpy(&pc->addrs.dns2, &ns2, sizeof(ns2));\r
+    }\r
+    return st;\r
+}\r
+\r
+/*\r
+ * cifaddr - Clear the interface IP addresses, and delete routes\r
+ * through the interface if possible.\r
+ */\r
+int cifaddr(\r
+    int pd,         /* Interface unit ??? */\r
+    u32_t o,    /* Our IP address ??? */\r
+    u32_t h     /* IP broadcast address ??? */\r
+)\r
+{\r
+    PPPControl *pc = &pppControl[pd];\r
+    int st = 1;\r
+    \r
+       (void)o;\r
+       (void)h;\r
+    if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) {\r
+        st = 0;\r
+        PPPDEBUG((LOG_WARNING, "sifup[%d]: bad parms\n", pd));\r
+    } else {\r
+               IP4_ADDR(&pc->addrs.our_ipaddr, 0,0,0,0);\r
+               IP4_ADDR(&pc->addrs.his_ipaddr, 0,0,0,0);\r
+               IP4_ADDR(&pc->addrs.netmask, 255,255,255,0);\r
+               IP4_ADDR(&pc->addrs.dns1, 0,0,0,0);\r
+               IP4_ADDR(&pc->addrs.dns2, 0,0,0,0);\r
+    }\r
+    return st;\r
+}\r
+\r
+/*\r
+ * sifdefaultroute - assign a default route through the address given.\r
+ */\r
+int sifdefaultroute(int pd, u32_t l, u32_t g)\r
+{\r
+    PPPControl *pc = &pppControl[pd];\r
+    int st = 1;\r
+    \r
+       (void)l;\r
+       (void)g;\r
+    if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) {\r
+        st = 0;\r
+        PPPDEBUG((LOG_WARNING, "sifup[%d]: bad parms\n", pd));\r
+    } else {\r
+               netif_set_default(&pc->netif);\r
+    }\r
+\r
+    /* TODO: check how PPP handled the netMask, previously not set by ipSetDefault */\r
+\r
+    return st;\r
+}\r
+\r
+/*\r
+ * cifdefaultroute - delete a default route through the address given.\r
+ */\r
+int cifdefaultroute(int pd, u32_t l, u32_t g)\r
+{\r
+    PPPControl *pc = &pppControl[pd];\r
+    int st = 1;\r
+    \r
+       (void)l;\r
+       (void)g;\r
+    if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) {\r
+        st = 0;\r
+        PPPDEBUG((LOG_WARNING, "sifup[%d]: bad parms\n", pd));\r
+    } else {\r
+               netif_set_default(NULL);\r
+    }\r
+\r
+    return st;\r
+}\r
+\r
+void\r
+pppMainWakeup(int pd)\r
+{\r
+       PPPDEBUG((LOG_DEBUG, "pppMainWakeup: unit %d\n", pd));\r
+       sio_read_abort(pppControl[pd].fd);\r
+}\r
+\r
+/* these callbacks are necessary because lcp_* functions\r
+   must be called in the same context as pppInput(),\r
+   namely the tcpip_thread(), essentially because\r
+   they manipulate timeouts which are thread-private\r
+*/\r
+\r
+static void\r
+pppStartCB(void *arg)\r
+{\r
+    int pd = (int)arg;\r
+\r
+       PPPDEBUG((LOG_DEBUG, "pppStartCB: unit %d\n", pd));\r
+    lcp_lowerup(pd);\r
+    lcp_open(pd);      /* Start protocol */\r
+}\r
+\r
+static void\r
+pppStopCB(void *arg)\r
+{\r
+    int pd = (int)arg;\r
+\r
+       PPPDEBUG((LOG_DEBUG, "pppStopCB: unit %d\n", pd));\r
+    lcp_close(pd, "User request");\r
+}\r
+\r
+static void\r
+pppHupCB(void *arg)\r
+{\r
+    int pd = (int)arg;\r
+\r
+       PPPDEBUG((LOG_DEBUG, "pppHupCB: unit %d\n", pd));\r
+    lcp_lowerdown(pd);\r
+    link_terminated(pd);\r
+}\r
+/**********************************/\r
+/*** LOCAL FUNCTION DEFINITIONS ***/\r
+/**********************************/\r
+/* The main PPP process function.  This implements the state machine according\r
+ * to section 4 of RFC 1661: The Point-To-Point Protocol. */\r
+static void pppMain(void *arg)\r
+{\r
+    int pd = (int)arg;\r
+    struct pbuf *p;\r
+    PPPControl* pc;\r
+\r
+    pc = &pppControl[pd];\r
+\r
+    p = pbuf_alloc(PBUF_RAW, PPP_MRU+PPP_HDRLEN, PBUF_RAM);\r
+    if(!p) {\r
+               LWIP_ASSERT("p != NULL", p);\r
+               pc->errCode = PPPERR_ALLOC;\r
+               goto out;\r
+    }\r
+\r
+    /*\r
+     * Start the connection and handle incoming events (packet or timeout).\r
+     */\r
+       PPPDEBUG((LOG_INFO, "pppMain: unit %d: Connecting\n", pd));\r
+    tcpip_callback(pppStartCB, arg);\r
+    while (lcp_phase[pd] != PHASE_DEAD) {\r
+        if (pc->kill_link) {\r
+               PPPDEBUG((LOG_DEBUG, "pppMainWakeup: unit %d kill_link -> pppStopCB\n", pd));\r
+               pc->errCode = PPPERR_USER;\r
+               /* This will leave us at PHASE_DEAD. */\r
+               tcpip_callback(pppStopCB, arg);\r
+               pc->kill_link = 0;\r
+        }\r
+        else if (pc->sig_hup) {\r
+               PPPDEBUG((LOG_DEBUG, "pppMainWakeup: unit %d sig_hup -> pppHupCB\n", pd));\r
+               pc->sig_hup = 0;\r
+               tcpip_callback(pppHupCB, arg);\r
+        } else {\r
+               int c = sio_read(pc->fd, p->payload, p->len);\r
+               if(c > 0) {\r
+                       pppInProc(pd, p->payload, c);\r
+               } else {\r
+                   PPPDEBUG((LOG_DEBUG, "pppMainWakeup: unit %d sio_read len=%d returned %d\n", pd, p->len, c));\r
+                   sys_msleep(1); /* give other tasks a chance to run */\r
+               }\r
+        }\r
+    }\r
+       PPPDEBUG((LOG_INFO, "pppMain: unit %d: PHASE_DEAD\n", pd));\r
+    pbuf_free(p);\r
+\r
+out:\r
+       PPPDEBUG((LOG_DEBUG, "pppMain: unit %d: linkStatusCB=%lx errCode=%d\n", pd, pc->linkStatusCB, pc->errCode));\r
+    if(pc->linkStatusCB)\r
+           pc->linkStatusCB(pc->linkStatusCtx, pc->errCode ? pc->errCode : PPPERR_PROTOCOL, NULL);\r
+\r
+    pc->openFlag = 0;\r
+}\r
+\r
+static struct pbuf *pppSingleBuf(struct pbuf *p)\r
+{\r
+       struct pbuf *q, *b;\r
+       u_char *pl;\r
+\r
+       if(p->tot_len == p->len)\r
+               return p;\r
+\r
+       q = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM);\r
+       if(!q) {\r
+               PPPDEBUG((LOG_ERR,\r
+                        "pppSingleBuf: unable to alloc new buf (%d)\n", p->tot_len));\r
+               return p; /* live dangerously */\r
+       }\r
+\r
+       for(b = p, pl = q->payload; b != NULL; b = b->next) {\r
+               memcpy(pl, b->payload, b->len);\r
+               pl += b->len;\r
+       }\r
+\r
+       pbuf_free(p);\r
+\r
+       return q;\r
+}\r
+\r
+struct pppInputHeader {\r
+       int unit;\r
+       u16_t proto;\r
+};\r
+\r
+/*\r
+ * Pass the processed input packet to the appropriate handler.\r
+ * This function and all handlers run in the context of the tcpip_thread\r
+ */\r
+static void pppInput(void *arg)\r
+{\r
+       struct pbuf *nb = (struct pbuf *)arg;\r
+    u16_t protocol;\r
+    int pd;\r
+\r
+       pd = ((struct pppInputHeader *)nb->payload)->unit;\r
+       protocol = ((struct pppInputHeader *)nb->payload)->proto;\r
+\r
+    pbuf_header(nb, -(int)sizeof(struct pppInputHeader));\r
+\r
+#if LINK_STATS\r
+    lwip_stats.link.recv++;\r
+#endif /* LINK_STATS */\r
+\r
+    /*\r
+     * Toss all non-LCP packets unless LCP is OPEN.\r
+     * Until we get past the authentication phase, toss all packets\r
+     * except LCP, LQR and authentication packets.\r
+     */\r
+    if((lcp_phase[pd] <= PHASE_AUTHENTICATE) && (protocol != PPP_LCP)) {\r
+           if(!((protocol == PPP_LQR) || (protocol == PPP_PAP) || (protocol == PPP_CHAP)) ||\r
+                       (lcp_phase[pd] != PHASE_AUTHENTICATE)) {\r
+               PPPDEBUG((LOG_INFO, "pppInput: discarding proto 0x%04X in phase %d\n", protocol, lcp_phase[pd]));\r
+               goto drop;\r
+           }\r
+    }\r
+\r
+    switch(protocol) {\r
+    case PPP_VJC_COMP:      /* VJ compressed TCP */\r
+#if VJ_SUPPORT > 0\r
+        PPPDEBUG((LOG_INFO, "pppInput[%d]: vj_comp in pbuf len=%d\n", pd, nb->len));\r
+        /*\r
+         * Clip off the VJ header and prepend the rebuilt TCP/IP header and\r
+         * pass the result to IP.\r
+         */\r
+        if (vj_uncompress_tcp(&nb, &pppControl[pd].vjComp) >= 0) {\r
+            pppControl[pd].netif.input(nb, &pppControl[pd].netif);\r
+                       return;\r
+        }\r
+       /* Something's wrong so drop it. */\r
+       PPPDEBUG((LOG_WARNING, "pppInput[%d]: Dropping VJ compressed\n", pd));\r
+#else\r
+        /* No handler for this protocol so drop the packet. */\r
+        PPPDEBUG((LOG_INFO, "pppInput[%d]: drop VJ Comp in %d:%s\n", pd, nb->len, nb->payload));\r
+#endif /* VJ_SUPPORT > 0 */\r
+       break;\r
+    case PPP_VJC_UNCOMP:    /* VJ uncompressed TCP */\r
+#if VJ_SUPPORT > 0\r
+        PPPDEBUG((LOG_INFO, "pppInput[%d]: vj_un in pbuf len=%d\n", pd, nb->len));\r
+        /*\r
+         * Process the TCP/IP header for VJ header compression and then pass\r
+         * the packet to IP.\r
+         */\r
+        if (vj_uncompress_uncomp(nb, &pppControl[pd].vjComp) >= 0) {\r
+            pppControl[pd].netif.input(nb, &pppControl[pd].netif);\r
+                       return;\r
+        }\r
+       /* Something's wrong so drop it. */\r
+       PPPDEBUG((LOG_WARNING, "pppInput[%d]: Dropping VJ uncompressed\n", pd));\r
+#else\r
+        /* No handler for this protocol so drop the packet. */\r
+        PPPDEBUG((LOG_INFO,\r
+                    "pppInput[%d]: drop VJ UnComp in %d:.*H\n", \r
+                    pd, nb->len, LWIP_MIN(nb->len * 2, 40), nb->payload));\r
+#endif /* VJ_SUPPORT > 0 */\r
+       break;\r
+    case PPP_IP:            /* Internet Protocol */\r
+        PPPDEBUG((LOG_INFO, "pppInput[%d]: ip in pbuf len=%d\n", pd, nb->len));\r
+        pppControl[pd].netif.input(nb, &pppControl[pd].netif);\r
+               return;\r
+    default:\r
+       {\r
+               struct protent *protp;\r
+               int i;\r
+\r
+               /*\r
+                * Upcall the proper protocol input routine.\r
+                */\r
+               for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i) {\r
+                       if (protp->protocol == protocol && protp->enabled_flag) {\r
+                               PPPDEBUG((LOG_INFO, "pppInput[%d]: %s len=%d\n", pd, protp->name, nb->len));\r
+                               nb = pppSingleBuf(nb);\r
+                               (*protp->input)(pd, nb->payload, nb->len);\r
+                               goto out;\r
+                       }\r
+               }\r
+\r
+               /* No handler for this protocol so reject the packet. */\r
+               PPPDEBUG((LOG_INFO, "pppInput[%d]: rejecting unsupported proto 0x%04X len=%d\n", pd, protocol, nb->len));\r
+               pbuf_header(nb, sizeof(protocol));\r
+#if BYTE_ORDER == LITTLE_ENDIAN\r
+               protocol = htons(protocol);\r
+               memcpy(nb->payload, &protocol, sizeof(protocol));\r
+#endif\r
+               lcp_sprotrej(pd, nb->payload, nb->len);\r
+       }\r
+       break;\r
+    }\r
+\r
+drop:\r
+#if LINK_STATS\r
+    lwip_stats.link.drop++;\r
+#endif\r
+\r
+out:\r
+    pbuf_free(nb);\r
+    return;\r
+}\r
+\r
+\r
+/*\r
+ * Drop the input packet.\r
+ */\r
+static void pppDrop(PPPControl *pc)\r
+{\r
+    if (pc->inHead != NULL) {\r
+#if 0      \r
+        PPPDEBUG((LOG_INFO, "pppDrop: %d:%.*H\n", pc->inHead->len, min(60, pc->inHead->len * 2), pc->inHead->payload));\r
+#endif \r
+        PPPDEBUG((LOG_INFO, "pppDrop: pbuf len=%d\n", pc->inHead->len));\r
+       if (pc->inTail && (pc->inTail != pc->inHead))\r
+           pbuf_free(pc->inTail);\r
+        pbuf_free(pc->inHead);\r
+        pc->inHead = NULL;\r
+        pc->inTail = NULL;\r
+    }\r
+#if VJ_SUPPORT > 0\r
+    vj_uncompress_err(&pc->vjComp);\r
+#endif\r
+\r
+#if LINK_STATS\r
+    lwip_stats.link.drop++;\r
+#endif /* LINK_STATS */\r
+}\r
+\r
+\r
+/*\r
+ * Process a received octet string.\r
+ */\r
+static void pppInProc(int pd, u_char *s, int l)\r
+{\r
+    PPPControl *pc = &pppControl[pd];\r
+    struct pbuf *nextNBuf;\r
+    u_char curChar;\r
+\r
+    PPPDEBUG((LOG_DEBUG, "pppInProc[%d]: got %d bytes\n", pd, l));\r
+    while (l-- > 0) {\r
+        curChar = *s++;\r
+        \r
+        /* Handle special characters. */\r
+        if (ESCAPE_P(pc->inACCM, curChar)) {\r
+            /* Check for escape sequences. */\r
+            /* XXX Note that this does not handle an escaped 0x5d character which\r
+             * would appear as an escape character.  Since this is an ASCII ']'\r
+             * and there is no reason that I know of to escape it, I won't complicate\r
+             * the code to handle this case. GLL */\r
+            if (curChar == PPP_ESCAPE)\r
+                pc->inEscaped = 1;\r
+            /* Check for the flag character. */\r
+            else if (curChar == PPP_FLAG) {\r
+                /* If this is just an extra flag character, ignore it. */\r
+                if (pc->inState <= PDADDRESS)\r
+                    ;\r
+                /* If we haven't received the packet header, drop what has come in. */\r
+                else if (pc->inState < PDDATA) {\r
+                    PPPDEBUG((LOG_WARNING,\r
+                                "pppInProc[%d]: Dropping incomplete packet %d\n", \r
+                                pd, pc->inState));\r
+#if LINK_STATS\r
+                                       lwip_stats.link.lenerr++;\r
+#endif\r
+                    pppDrop(pc);\r
+                }\r
+                /* If the fcs is invalid, drop the packet. */\r
+                else if (pc->inFCS != PPP_GOODFCS) {\r
+                    PPPDEBUG((LOG_INFO,\r
+                                "pppInProc[%d]: Dropping bad fcs 0x%04X proto=0x%04X\n", \r
+                                pd, pc->inFCS, pc->inProtocol));\r
+#if LINK_STATS\r
+                                       lwip_stats.link.chkerr++;\r
+#endif\r
+                    pppDrop(pc);\r
+                }\r
+                /* Otherwise it's a good packet so pass it on. */\r
+                else {\r
+                    \r
+                    /* Trim off the checksum. */\r
+                   if(pc->inTail->len >= 2) {\r
+                       pc->inTail->len -= 2;\r
+\r
+                       pc->inTail->tot_len = pc->inTail->len;\r
+                       if (pc->inTail != pc->inHead) {\r
+                           pbuf_cat(pc->inHead, pc->inTail);\r
+                       }\r
+                   } else {\r
+                       pc->inTail->tot_len = pc->inTail->len;\r
+                       if (pc->inTail != pc->inHead) {\r
+                           pbuf_cat(pc->inHead, pc->inTail);\r
+                       }\r
+\r
+                       pbuf_realloc(pc->inHead, pc->inHead->tot_len - 2);\r
+                   }\r
+\r
+                    /* Dispatch the packet thereby consuming it. */\r
+                   if(tcpip_callback(pppInput, pc->inHead) != ERR_OK) {\r
+                       PPPDEBUG((LOG_ERR,\r
+                                   "pppInProc[%d]: tcpip_callback() failed, dropping packet\n", pd));\r
+                       pbuf_free(pc->inHead);\r
+#if LINK_STATS\r
+                       lwip_stats.link.drop++;\r
+#endif\r
+                   }\r
+                    pc->inHead = NULL;\r
+                    pc->inTail = NULL;\r
+                }\r
+                    \r
+                /* Prepare for a new packet. */\r
+                pc->inFCS = PPP_INITFCS;\r
+                pc->inState = PDADDRESS;\r
+                pc->inEscaped = 0;\r
+            }\r
+            /* Other characters are usually control characters that may have\r
+             * been inserted by the physical layer so here we just drop them. */\r
+            else {\r
+                PPPDEBUG((LOG_WARNING,\r
+                            "pppInProc[%d]: Dropping ACCM char <%d>\n", pd, curChar));\r
+            }\r
+        }\r
+        /* Process other characters. */\r
+        else {\r
+            /* Unencode escaped characters. */\r
+            if (pc->inEscaped) {\r
+                pc->inEscaped = 0;\r
+                curChar ^= PPP_TRANS;\r
+            }\r
+            \r
+            /* Process character relative to current state. */\r
+            switch(pc->inState) {\r
+            case PDIDLE:                    /* Idle state - waiting. */\r
+                /* Drop the character if it's not 0xff\r
+                 * we would have processed a flag character above. */\r
+                if (curChar != PPP_ALLSTATIONS) {\r
+                       break;\r
+                               }\r
+\r
+                               /* Fall through */\r
+            case PDSTART:                   /* Process start flag. */\r
+                /* Prepare for a new packet. */\r
+                pc->inFCS = PPP_INITFCS;\r
+\r
+                               /* Fall through */\r
+            case PDADDRESS:                 /* Process address field. */\r
+                if (curChar == PPP_ALLSTATIONS) {\r
+                    pc->inState = PDCONTROL;\r
+                    break;\r
+                }\r
+                /* Else assume compressed address and control fields so\r
+                 * fall through to get the protocol... */\r
+            case PDCONTROL:                 /* Process control field. */\r
+                /* If we don't get a valid control code, restart. */\r
+                if (curChar == PPP_UI) {\r
+                    pc->inState = PDPROTOCOL1;\r
+                       break;\r
+                }\r
+#if 0\r
+                else {\r
+                    PPPDEBUG((LOG_WARNING,\r
+                                "pppInProc[%d]: Invalid control <%d>\n", pd, curChar));\r
+                    pc->inState = PDSTART;\r
+                }\r
+#endif\r
+            case PDPROTOCOL1:               /* Process protocol field 1. */\r
+                /* If the lower bit is set, this is the end of the protocol\r
+                 * field. */\r
+                if (curChar & 1) {\r
+                    pc->inProtocol = curChar;\r
+                    pc->inState = PDDATA;\r
+                }\r
+                else {\r
+                    pc->inProtocol = (u_int)curChar << 8;\r
+                    pc->inState = PDPROTOCOL2;\r
+                }\r
+                break;\r
+            case PDPROTOCOL2:               /* Process protocol field 2. */\r
+                pc->inProtocol |= curChar;\r
+                pc->inState = PDDATA;\r
+                break;\r
+            case PDDATA:                    /* Process data byte. */\r
+                /* Make space to receive processed data. */\r
+                if (pc->inTail == NULL || pc->inTail->len == PBUF_POOL_BUFSIZE) {\r
+                   if(pc->inTail) {\r
+                       pc->inTail->tot_len = pc->inTail->len;\r
+                       if (pc->inTail != pc->inHead) {\r
+                           pbuf_cat(pc->inHead, pc->inTail);\r
+                       }\r
+                   }\r
+                    /* If we haven't started a packet, we need a packet header. */\r
+                    nextNBuf = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL);\r
+                    if (nextNBuf == NULL) {\r
+                        /* No free buffers.  Drop the input packet and let the\r
+                         * higher layers deal with it.  Continue processing\r
+                         * the received pbuf chain in case a new packet starts. */\r
+                        PPPDEBUG((LOG_ERR, "pppInProc[%d]: NO FREE MBUFS!\n", pd));\r
+#if LINK_STATS\r
+                                               lwip_stats.link.memerr++;\r
+#endif /* LINK_STATS */\r
+                        pppDrop(pc);\r
+                        pc->inState = PDSTART;  /* Wait for flag sequence. */\r
+                       break;\r
+                    }\r
+                   if (pc->inHead == NULL) {\r
+                       struct pppInputHeader *pih = nextNBuf->payload;\r
+\r
+                       pih->unit = pd;\r
+                       pih->proto = pc->inProtocol;\r
+\r
+                       nextNBuf->len += sizeof(*pih);\r
+\r
+                       pc->inHead = nextNBuf;\r
+                   }\r
+                   pc->inTail = nextNBuf;\r
+                }\r
+                /* Load character into buffer. */\r
+                ((u_char*)pc->inTail->payload)[pc->inTail->len++] = curChar;\r
+                break;\r
+            }\r
+\r
+            /* update the frame check sequence number. */\r
+            pc->inFCS = PPP_FCS(pc->inFCS, curChar);\r
+        }\r
+    }\r
+       avRandomize();\r
+}\r
+\r
+#endif /* PPP_SUPPORT */\r
index dbe12171e83beca26818af78a2bd526975a0888a..bd45a3c1d4136877232f3622e7aadb04640e64e4 100644 (file)
-/*****************************************************************************
-* ppp.h - Network Point to Point Protocol header file.
-*
-* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
-* portions Copyright (c) 1997 Global Election Systems Inc.
-*
-* The authors hereby grant permission to use, copy, modify, distribute,
-* and license this software and its documentation for any purpose, provided
-* that existing copyright notices are retained in all copies and that this
-* notice and the following disclaimer are included verbatim in any 
-* distributions. No written agreement, license, or royalty fee is required
-* for any of the authorized uses.
-*
-* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *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 CONTRIBUTORS 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.
-*
-******************************************************************************
-* REVISION HISTORY
-*
-* 03-01-01 Marc Boucher <marc@mbsi.ca>
-*   Ported to lwIP.
-* 97-11-05 Guy Lancaster <glanca@gesn.com>, Global Election Systems Inc.
-*      Original derived from BSD codes.
-*****************************************************************************/
-
-#ifndef PPP_H
-#define PPP_H
-
-#include "lwip/opt.h"
-
-#if PPP_SUPPORT > 0
-#include "lwip/sio.h"
-#include "lwip/api.h"
-#include "lwip/sockets.h"
-#include "lwip/stats.h"
-#include "lwip/mem.h"
-#include "lwip/tcpip.h"
-#include "lwip/netif.h"
-
-/*
- * pppd.h - PPP daemon global declarations.
- *
- * Copyright (c) 1989 Carnegie Mellon University.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by Carnegie Mellon University.  The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- */
-/*
- * ppp_defs.h - PPP definitions.
- *
- * Copyright (c) 1994 The Australian National University.
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation is hereby granted, provided that the above copyright
- * notice appears in all copies.  This software is provided without any
- * warranty, express or implied. The Australian National University
- * makes no representations about the suitability of this software for
- * any purpose.
- *
- * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY
- * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
- * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY
- * OF SUCH DAMAGE.
- *
- * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO
- * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
- * OR MODIFICATIONS.
- */
-
-#define TIMEOUT(f, a, t)    sys_untimeout((f), (a)), sys_timeout((t)*1000, (f), (a))
-#define UNTIMEOUT(f, a)     sys_untimeout((f), (a))
-
-
-# ifndef __u_char_defined
-
-/* Type definitions for BSD code. */
-typedef unsigned long u_long;
-typedef unsigned int u_int;
-typedef unsigned short u_short;
-typedef unsigned char u_char;
-
-#endif
-
-/*
- * Constants and structures defined by the internet system,
- * Per RFC 790, September 1981, and numerous additions.
- */
-
-/*
- * The basic PPP frame.
- */
-#define PPP_HDRLEN  4       /* octets for standard ppp header */
-#define PPP_FCSLEN  2       /* octets for FCS */
-
-
-/*
- * Significant octet values.
- */
-#define PPP_ALLSTATIONS 0xff    /* All-Stations broadcast address */
-#define PPP_UI          0x03    /* Unnumbered Information */
-#define PPP_FLAG        0x7e    /* Flag Sequence */
-#define PPP_ESCAPE      0x7d    /* Asynchronous Control Escape */
-#define PPP_TRANS       0x20    /* Asynchronous transparency modifier */
-
-/*
- * Protocol field values.
- */
-#define PPP_IP          0x21    /* Internet Protocol */
-#define PPP_AT          0x29    /* AppleTalk Protocol */
-#define PPP_VJC_COMP    0x2d    /* VJ compressed TCP */
-#define PPP_VJC_UNCOMP  0x2f    /* VJ uncompressed TCP */
-#define PPP_COMP        0xfd    /* compressed packet */
-#define PPP_IPCP        0x8021  /* IP Control Protocol */
-#define PPP_ATCP        0x8029  /* AppleTalk Control Protocol */
-#define PPP_CCP         0x80fd  /* Compression Control Protocol */
-#define PPP_LCP         0xc021  /* Link Control Protocol */
-#define PPP_PAP         0xc023  /* Password Authentication Protocol */
-#define PPP_LQR         0xc025  /* Link Quality Report protocol */
-#define PPP_CHAP        0xc223  /* Cryptographic Handshake Auth. Protocol */
-#define PPP_CBCP        0xc029  /* Callback Control Protocol */
-
-/*
- * Values for FCS calculations.
- */
-#define PPP_INITFCS 0xffff  /* Initial FCS value */
-#define PPP_GOODFCS 0xf0b8  /* Good final FCS value */
-#define PPP_FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
-
-/*
- * Extended asyncmap - allows any character to be escaped.
- */
-typedef u_char  ext_accm[32];
-
-/*
- * What to do with network protocol (NP) packets.
- */
-enum NPmode {
-    NPMODE_PASS,        /* pass the packet through */
-    NPMODE_DROP,        /* silently drop the packet */
-    NPMODE_ERROR,       /* return an error */
-    NPMODE_QUEUE        /* save it up for later. */
-};
-
-/*
- * Inline versions of get/put char/short/long.
- * Pointer is advanced; we assume that both arguments
- * are lvalues and will already be in registers.
- * cp MUST be u_char *.
- */
-#define GETCHAR(c, cp) { \
-    (c) = *(cp)++; \
-}
-#define PUTCHAR(c, cp) { \
-    *(cp)++ = (u_char) (c); \
-}
-
-
-#define GETSHORT(s, cp) { \
-    (s) = *(cp)++ << 8; \
-    (s) |= *(cp)++; \
-}
-#define PUTSHORT(s, cp) { \
-    *(cp)++ = (u_char) ((s) >> 8); \
-    *(cp)++ = (u_char) (s); \
-}
-
-#define GETLONG(l, cp) { \
-    (l) = *(cp)++ << 8; \
-    (l) |= *(cp)++; (l) <<= 8; \
-    (l) |= *(cp)++; (l) <<= 8; \
-    (l) |= *(cp)++; \
-}
-#define PUTLONG(l, cp) { \
-    *(cp)++ = (u_char) ((l) >> 24); \
-    *(cp)++ = (u_char) ((l) >> 16); \
-    *(cp)++ = (u_char) ((l) >> 8); \
-    *(cp)++ = (u_char) (l); \
-}
-
-
-#define INCPTR(n, cp)   ((cp) += (n))
-#define DECPTR(n, cp)   ((cp) -= (n))
-
-#define BCMP(s0, s1, l)     memcmp((u_char *)(s0), (u_char *)(s1), (l))
-#define BCOPY(s, d, l)      memcpy((d), (s), (l))
-#define BZERO(s, n)         memset(s, 0, n)
-#if PPP_DEBUG
-#define PRINTMSG(m, l)  { m[l] = '\0'; ppp_trace(LOG_INFO, "Remote message: %s\n", m); }
-#else
-#define PRINTMSG(m, l)
-#endif
-
-/*
- * MAKEHEADER - Add PPP Header fields to a packet.
- */
-#define MAKEHEADER(p, t) { \
-    PUTCHAR(PPP_ALLSTATIONS, p); \
-    PUTCHAR(PPP_UI, p); \
-    PUTSHORT(t, p); }
-
-/*************************
-*** PUBLIC DEFINITIONS ***
-*************************/
-
-/* Error codes. */
-#define PPPERR_NONE 0                          /* No error. */
-#define PPPERR_PARAM -1                                /* Invalid parameter. */
-#define PPPERR_OPEN -2                         /* Unable to open PPP session. */
-#define PPPERR_DEVICE -3                       /* Invalid I/O device for PPP. */
-#define PPPERR_ALLOC -4                                /* Unable to allocate resources. */
-#define PPPERR_USER -5                         /* User interrupt. */
-#define PPPERR_CONNECT -6                      /* Connection lost. */
-#define PPPERR_AUTHFAIL -7                     /* Failed authentication challenge. */
-#define PPPERR_PROTOCOL -8                     /* Failed to meet protocol. */
-
-/*
- * PPP IOCTL commands.
- */
-/*
- * Get the up status - 0 for down, non-zero for up.  The argument must
- * point to an int.
- */
-#define PPPCTLG_UPSTATUS 100   /* Get the up status - 0 down else up */
-#define PPPCTLS_ERRCODE 101            /* Set the error code */
-#define PPPCTLG_ERRCODE 102            /* Get the error code */
-#define        PPPCTLG_FD              103             /* Get the fd associated with the ppp */
-
-/************************
-*** PUBLIC DATA TYPES ***
-************************/
-
-/*
- * The following struct gives the addresses of procedures to call
- * for a particular protocol.
- */
-struct protent {
-    u_short protocol;       /* PPP protocol number */
-    /* Initialization procedure */
-    void (*init) (int unit);
-    /* Process a received packet */
-    void (*input) (int unit, u_char *pkt, int len);
-    /* Process a received protocol-reject */
-    void (*protrej) (int unit);
-    /* Lower layer has come up */
-    void (*lowerup) (int unit);
-    /* Lower layer has gone down */
-    void (*lowerdown) (int unit);
-    /* Open the protocol */
-    void (*open) (int unit);
-    /* Close the protocol */
-    void (*close) (int unit, char *reason);
-#if 0
-    /* Print a packet in readable form */
-    int  (*printpkt) (u_char *pkt, int len,
-              void (*printer) (void *, char *, ...),
-              void *arg);
-    /* Process a received data packet */
-    void (*datainput) (int unit, u_char *pkt, int len);
-#endif
-    int  enabled_flag;      /* 0 iff protocol is disabled */
-    char *name;         /* Text name of protocol */
-#if 0
-    /* Check requested options, assign defaults */
-    void (*check_options) (u_long);
-    /* Configure interface for demand-dial */
-    int  (*demand_conf) (int unit);
-    /* Say whether to bring up link for this pkt */
-    int  (*active_pkt) (u_char *pkt, int len);
-#endif
-};
-
-/*
- * The following structure records the time in seconds since
- * the last NP packet was sent or received.
- */
-struct ppp_idle {
-    u_short xmit_idle;      /* seconds since last NP packet sent */
-    u_short recv_idle;      /* seconds since last NP packet received */
-};
-
-struct ppp_settings {
-
-       u_int  disable_defaultip : 1;   /* Don't use hostname for default IP addrs */
-       u_int  auth_required : 1;      /* Peer is required to authenticate */
-       u_int  explicit_remote : 1;    /* remote_name specified with remotename opt */
-       u_int  refuse_pap : 1;         /* Don't wanna auth. ourselves with PAP */
-       u_int  refuse_chap : 1;        /* Don't wanna auth. ourselves with CHAP */
-       u_int  usehostname : 1;        /* Use hostname for our_name */
-       u_int  usepeerdns : 1;         /* Ask peer for DNS adds */
-
-       u_short idle_time_limit; /* Shut down link if idle for this long */
-       int  maxconnect;         /* Maximum connect time (seconds) */
-
-       char user[MAXNAMELEN + 1];/* Username for PAP */
-       char passwd[MAXSECRETLEN + 1];           /* Password for PAP, secret for CHAP */
-       char our_name[MAXNAMELEN + 1];         /* Our name for authentication purposes */
-       char remote_name[MAXNAMELEN + 1];      /* Peer's name for authentication */
-};
-
-struct ppp_addrs {
-    struct ip_addr our_ipaddr, his_ipaddr, netmask, dns1, dns2;
-};
-
-/*****************************
-*** PUBLIC DATA STRUCTURES ***
-*****************************/
-/* Buffers for outgoing packets. */
-extern u_char outpacket_buf[NUM_PPP][PPP_MRU+PPP_HDRLEN];
-
-extern struct ppp_settings ppp_settings;
-
-extern struct protent *ppp_protocols[];/* Table of pointers to supported protocols */
-
-
-/***********************
-*** PUBLIC FUNCTIONS ***
-***********************/
-
-/* Initialize the PPP subsystem. */
-void pppInit(void);
-
-/* Warning: Using PPPAUTHTYPE_ANY might have security consequences.
- * RFC 1994 says:
- *
- * In practice, within or associated with each PPP server, there is a
- * database which associates "user" names with authentication
- * information ("secrets").  It is not anticipated that a particular
- * named user would be authenticated by multiple methods.  This would
- * make the user vulnerable to attacks which negotiate the least secure
- * method from among a set (such as PAP rather than CHAP).  If the same
- * secret was used, PAP would reveal the secret to be used later with
- * CHAP.
- *
- * Instead, for each user name there should be an indication of exactly
- * one method used to authenticate that user name.  If a user needs to
- * make use of different authentication methods under different
- * circumstances, then distinct user names SHOULD be employed, each of
- * which identifies exactly one authentication method.
- *
- */
-enum pppAuthType {
-    PPPAUTHTYPE_NONE,
-    PPPAUTHTYPE_ANY,
-    PPPAUTHTYPE_PAP,
-    PPPAUTHTYPE_CHAP
-};
-
-void pppSetAuth(enum pppAuthType authType, const char *user, const char *passwd);
-
-/*
- * Open a new PPP connection using the given I/O device.
- * This initializes the PPP control block but does not
- * attempt to negotiate the LCP session.
- * Return a new PPP connection descriptor on success or
- * an error code (negative) on failure. 
- */
-int pppOpen(sio_fd_t fd, void (*linkStatusCB)(void *ctx, int errCode, void *arg), void *linkStatusCtx);
-
-/*
- * Close a PPP connection and release the descriptor. 
- * Any outstanding packets in the queues are dropped.
- * Return 0 on success, an error code on failure. 
- */
-int pppClose(int pd);
-
-/*
- * Indicate to the PPP process that the line has disconnected.
- */
-void pppSigHUP(int pd);
-
-/*
- * Get and set parameters for the given connection.
- * Return 0 on success, an error code on failure. 
- */
-int  pppIOCtl(int pd, int cmd, void *arg);
-
-/*
- * Return the Maximum Transmission Unit for the given PPP connection.
- */
-u_int pppMTU(int pd);
-
-/*
- * Write n characters to a ppp link.
- *     RETURN: >= 0 Number of characters written
- *                      -1 Failed to write to device
- */
-int pppWrite(int pd, const u_char *s, int n);
-
-void pppMainWakeup(int pd);
-
-/* Configure i/f transmit parameters */
-void ppp_send_config (int, int, u32_t, int, int);
-/* Set extended transmit ACCM */
-void ppp_set_xaccm (int, ext_accm *);
-/* Configure i/f receive parameters */
-void ppp_recv_config (int, int, u32_t, int, int);
-/* Find out how long link has been idle */
-int  get_idle_time (int, struct ppp_idle *);
-
-/* Configure VJ TCP header compression */
-int  sifvjcomp (int, int, int, int);
-/* Configure i/f down (for IP) */
-int  sifup (int);              
-/* Set mode for handling packets for proto */
-int  sifnpmode (int u, int proto, enum NPmode mode);
-/* Configure i/f down (for IP) */
-int  sifdown (int);    
-/* Configure IP addresses for i/f */
-int  sifaddr (int, u32_t, u32_t, u32_t, u32_t, u32_t);
-/* Reset i/f IP addresses */
-int  cifaddr (int, u32_t, u32_t);
-/* Create default route through i/f */
-int  sifdefaultroute (int, u32_t, u32_t);
-/* Delete default route through i/f */
-int  cifdefaultroute (int, u32_t, u32_t);
-
-/* Get appropriate netmask for address */
-u32_t GetMask (u32_t); 
-
-#endif /* PPP_SUPPORT */
-
-#endif /* PPP_H */
+/*****************************************************************************\r
+* ppp.h - Network Point to Point Protocol header file.\r
+*\r
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.\r
+* portions Copyright (c) 1997 Global Election Systems Inc.\r
+*\r
+* The authors hereby grant permission to use, copy, modify, distribute,\r
+* and license this software and its documentation for any purpose, provided\r
+* that existing copyright notices are retained in all copies and that this\r
+* notice and the following disclaimer are included verbatim in any \r
+* distributions. No written agreement, license, or royalty fee is required\r
+* for any of the authorized uses.\r
+*\r
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR\r
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+*\r
+******************************************************************************\r
+* REVISION HISTORY\r
+*\r
+* 03-01-01 Marc Boucher <marc@mbsi.ca>\r
+*   Ported to lwIP.\r
+* 97-11-05 Guy Lancaster <glanca@gesn.com>, Global Election Systems Inc.\r
+*      Original derived from BSD codes.\r
+*****************************************************************************/\r
+\r
+#ifndef PPP_H\r
+#define PPP_H\r
+\r
+#include "lwip/opt.h"\r
+\r
+#if PPP_SUPPORT > 0\r
+#include "lwip/sio.h"\r
+#include "lwip/api.h"\r
+#include "lwip/sockets.h"\r
+#include "lwip/stats.h"\r
+#include "lwip/mem.h"\r
+#include "lwip/tcpip.h"\r
+#include "lwip/netif.h"\r
+\r
+/*\r
+ * pppd.h - PPP daemon global declarations.\r
+ *\r
+ * Copyright (c) 1989 Carnegie Mellon University.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms are permitted\r
+ * provided that the above copyright notice and this paragraph are\r
+ * duplicated in all such forms and that any documentation,\r
+ * advertising materials, and other materials related to such\r
+ * distribution and use acknowledge that the software was developed\r
+ * by Carnegie Mellon University.  The name of the\r
+ * University may not be used to endorse or promote products derived\r
+ * from this software without specific prior written permission.\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR\r
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r
+ *\r
+ */\r
+/*\r
+ * ppp_defs.h - PPP definitions.\r
+ *\r
+ * Copyright (c) 1994 The Australian National University.\r
+ * All rights reserved.\r
+ *\r
+ * Permission to use, copy, modify, and distribute this software and its\r
+ * documentation is hereby granted, provided that the above copyright\r
+ * notice appears in all copies.  This software is provided without any\r
+ * warranty, express or implied. The Australian National University\r
+ * makes no representations about the suitability of this software for\r
+ * any purpose.\r
+ *\r
+ * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY\r
+ * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES\r
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF\r
+ * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY\r
+ * OF SUCH DAMAGE.\r
+ *\r
+ * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,\r
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY\r
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS\r
+ * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO\r
+ * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,\r
+ * OR MODIFICATIONS.\r
+ */\r
+\r
+#define TIMEOUT(f, a, t)    sys_untimeout((f), (a)), sys_timeout((t)*1000, (f), (a))\r
+#define UNTIMEOUT(f, a)     sys_untimeout((f), (a))\r
+\r
+\r
+# ifndef __u_char_defined\r
+\r
+/* Type definitions for BSD code. */\r
+typedef unsigned long u_long;\r
+typedef unsigned int u_int;\r
+typedef unsigned short u_short;\r
+typedef unsigned char u_char;\r
+\r
+#endif\r
+\r
+/*\r
+ * Constants and structures defined by the internet system,\r
+ * Per RFC 790, September 1981, and numerous additions.\r
+ */\r
+\r
+/*\r
+ * The basic PPP frame.\r
+ */\r
+#define PPP_HDRLEN  4       /* octets for standard ppp header */\r
+#define PPP_FCSLEN  2       /* octets for FCS */\r
+\r
+\r
+/*\r
+ * Significant octet values.\r
+ */\r
+#define PPP_ALLSTATIONS 0xff    /* All-Stations broadcast address */\r
+#define PPP_UI          0x03    /* Unnumbered Information */\r
+#define PPP_FLAG        0x7e    /* Flag Sequence */\r
+#define PPP_ESCAPE      0x7d    /* Asynchronous Control Escape */\r
+#define PPP_TRANS       0x20    /* Asynchronous transparency modifier */\r
+\r
+/*\r
+ * Protocol field values.\r
+ */\r
+#define PPP_IP          0x21    /* Internet Protocol */\r
+#define PPP_AT          0x29    /* AppleTalk Protocol */\r
+#define PPP_VJC_COMP    0x2d    /* VJ compressed TCP */\r
+#define PPP_VJC_UNCOMP  0x2f    /* VJ uncompressed TCP */\r
+#define PPP_COMP        0xfd    /* compressed packet */\r
+#define PPP_IPCP        0x8021  /* IP Control Protocol */\r
+#define PPP_ATCP        0x8029  /* AppleTalk Control Protocol */\r
+#define PPP_CCP         0x80fd  /* Compression Control Protocol */\r
+#define PPP_LCP         0xc021  /* Link Control Protocol */\r
+#define PPP_PAP         0xc023  /* Password Authentication Protocol */\r
+#define PPP_LQR         0xc025  /* Link Quality Report protocol */\r
+#define PPP_CHAP        0xc223  /* Cryptographic Handshake Auth. Protocol */\r
+#define PPP_CBCP        0xc029  /* Callback Control Protocol */\r
+\r
+/*\r
+ * Values for FCS calculations.\r
+ */\r
+#define PPP_INITFCS 0xffff  /* Initial FCS value */\r
+#define PPP_GOODFCS 0xf0b8  /* Good final FCS value */\r
+#define PPP_FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])\r
+\r
+/*\r
+ * Extended asyncmap - allows any character to be escaped.\r
+ */\r
+typedef u_char  ext_accm[32];\r
+\r
+/*\r
+ * What to do with network protocol (NP) packets.\r
+ */\r
+enum NPmode {\r
+    NPMODE_PASS,        /* pass the packet through */\r
+    NPMODE_DROP,        /* silently drop the packet */\r
+    NPMODE_ERROR,       /* return an error */\r
+    NPMODE_QUEUE        /* save it up for later. */\r
+};\r
+\r
+/*\r
+ * Inline versions of get/put char/short/long.\r
+ * Pointer is advanced; we assume that both arguments\r
+ * are lvalues and will already be in registers.\r
+ * cp MUST be u_char *.\r
+ */\r
+#define GETCHAR(c, cp) { \\r
+    (c) = *(cp)++; \\r
+}\r
+#define PUTCHAR(c, cp) { \\r
+    *(cp)++ = (u_char) (c); \\r
+}\r
+\r
+\r
+#define GETSHORT(s, cp) { \\r
+    (s) = *(cp)++ << 8; \\r
+    (s) |= *(cp)++; \\r
+}\r
+#define PUTSHORT(s, cp) { \\r
+    *(cp)++ = (u_char) ((s) >> 8); \\r
+    *(cp)++ = (u_char) (s); \\r
+}\r
+\r
+#define GETLONG(l, cp) { \\r
+    (l) = *(cp)++ << 8; \\r
+    (l) |= *(cp)++; (l) <<= 8; \\r
+    (l) |= *(cp)++; (l) <<= 8; \\r
+    (l) |= *(cp)++; \\r
+}\r
+#define PUTLONG(l, cp) { \\r
+    *(cp)++ = (u_char) ((l) >> 24); \\r
+    *(cp)++ = (u_char) ((l) >> 16); \\r
+    *(cp)++ = (u_char) ((l) >> 8); \\r
+    *(cp)++ = (u_char) (l); \\r
+}\r
+\r
+\r
+#define INCPTR(n, cp)   ((cp) += (n))\r
+#define DECPTR(n, cp)   ((cp) -= (n))\r
+\r
+#define BCMP(s0, s1, l)     memcmp((u_char *)(s0), (u_char *)(s1), (l))\r
+#define BCOPY(s, d, l)      memcpy((d), (s), (l))\r
+#define BZERO(s, n)         memset(s, 0, n)\r
+#if PPP_DEBUG\r
+#define PRINTMSG(m, l)  { m[l] = '\0'; ppp_trace(LOG_INFO, "Remote message: %s\n", m); }\r
+#else\r
+#define PRINTMSG(m, l)\r
+#endif\r
+\r
+/*\r
+ * MAKEHEADER - Add PPP Header fields to a packet.\r
+ */\r
+#define MAKEHEADER(p, t) { \\r
+    PUTCHAR(PPP_ALLSTATIONS, p); \\r
+    PUTCHAR(PPP_UI, p); \\r
+    PUTSHORT(t, p); }\r
+\r
+/*************************\r
+*** PUBLIC DEFINITIONS ***\r
+*************************/\r
+\r
+/* Error codes. */\r
+#define PPPERR_NONE 0                          /* No error. */\r
+#define PPPERR_PARAM -1                                /* Invalid parameter. */\r
+#define PPPERR_OPEN -2                         /* Unable to open PPP session. */\r
+#define PPPERR_DEVICE -3                       /* Invalid I/O device for PPP. */\r
+#define PPPERR_ALLOC -4                                /* Unable to allocate resources. */\r
+#define PPPERR_USER -5                         /* User interrupt. */\r
+#define PPPERR_CONNECT -6                      /* Connection lost. */\r
+#define PPPERR_AUTHFAIL -7                     /* Failed authentication challenge. */\r
+#define PPPERR_PROTOCOL -8                     /* Failed to meet protocol. */\r
+\r
+/*\r
+ * PPP IOCTL commands.\r
+ */\r
+/*\r
+ * Get the up status - 0 for down, non-zero for up.  The argument must\r
+ * point to an int.\r
+ */\r
+#define PPPCTLG_UPSTATUS 100   /* Get the up status - 0 down else up */\r
+#define PPPCTLS_ERRCODE 101            /* Set the error code */\r
+#define PPPCTLG_ERRCODE 102            /* Get the error code */\r
+#define        PPPCTLG_FD              103             /* Get the fd associated with the ppp */\r
+\r
+/************************\r
+*** PUBLIC DATA TYPES ***\r
+************************/\r
+\r
+/*\r
+ * The following struct gives the addresses of procedures to call\r
+ * for a particular protocol.\r
+ */\r
+struct protent {\r
+    u_short protocol;       /* PPP protocol number */\r
+    /* Initialization procedure */\r
+    void (*init) (int unit);\r
+    /* Process a received packet */\r
+    void (*input) (int unit, u_char *pkt, int len);\r
+    /* Process a received protocol-reject */\r
+    void (*protrej) (int unit);\r
+    /* Lower layer has come up */\r
+    void (*lowerup) (int unit);\r
+    /* Lower layer has gone down */\r
+    void (*lowerdown) (int unit);\r
+    /* Open the protocol */\r
+    void (*open) (int unit);\r
+    /* Close the protocol */\r
+    void (*close) (int unit, char *reason);\r
+#if 0\r
+    /* Print a packet in readable form */\r
+    int  (*printpkt) (u_char *pkt, int len,\r
+              void (*printer) (void *, char *, ...),\r
+              void *arg);\r
+    /* Process a received data packet */\r
+    void (*datainput) (int unit, u_char *pkt, int len);\r
+#endif\r
+    int  enabled_flag;      /* 0 iff protocol is disabled */\r
+    char *name;         /* Text name of protocol */\r
+#if 0\r
+    /* Check requested options, assign defaults */\r
+    void (*check_options) (u_long);\r
+    /* Configure interface for demand-dial */\r
+    int  (*demand_conf) (int unit);\r
+    /* Say whether to bring up link for this pkt */\r
+    int  (*active_pkt) (u_char *pkt, int len);\r
+#endif\r
+};\r
+\r
+/*\r
+ * The following structure records the time in seconds since\r
+ * the last NP packet was sent or received.\r
+ */\r
+struct ppp_idle {\r
+    u_short xmit_idle;      /* seconds since last NP packet sent */\r
+    u_short recv_idle;      /* seconds since last NP packet received */\r
+};\r
+\r
+struct ppp_settings {\r
+\r
+       u_int  disable_defaultip : 1;   /* Don't use hostname for default IP addrs */\r
+       u_int  auth_required : 1;      /* Peer is required to authenticate */\r
+       u_int  explicit_remote : 1;    /* remote_name specified with remotename opt */\r
+       u_int  refuse_pap : 1;         /* Don't wanna auth. ourselves with PAP */\r
+       u_int  refuse_chap : 1;        /* Don't wanna auth. ourselves with CHAP */\r
+       u_int  usehostname : 1;        /* Use hostname for our_name */\r
+       u_int  usepeerdns : 1;         /* Ask peer for DNS adds */\r
+\r
+       u_short idle_time_limit; /* Shut down link if idle for this long */\r
+       int  maxconnect;         /* Maximum connect time (seconds) */\r
+\r
+       char user[MAXNAMELEN + 1];/* Username for PAP */\r
+       char passwd[MAXSECRETLEN + 1];           /* Password for PAP, secret for CHAP */\r
+       char our_name[MAXNAMELEN + 1];         /* Our name for authentication purposes */\r
+       char remote_name[MAXNAMELEN + 1];      /* Peer's name for authentication */\r
+};\r
+\r
+struct ppp_addrs {\r
+    struct ip_addr our_ipaddr, his_ipaddr, netmask, dns1, dns2;\r
+};\r
+\r
+/*****************************\r
+*** PUBLIC DATA STRUCTURES ***\r
+*****************************/\r
+/* Buffers for outgoing packets. */\r
+extern u_char outpacket_buf[NUM_PPP][PPP_MRU+PPP_HDRLEN];\r
+\r
+extern struct ppp_settings ppp_settings;\r
+\r
+extern struct protent *ppp_protocols[];/* Table of pointers to supported protocols */\r
+\r
+\r
+/***********************\r
+*** PUBLIC FUNCTIONS ***\r
+***********************/\r
+\r
+/* Initialize the PPP subsystem. */\r
+void pppInit(void);\r
+\r
+/* Warning: Using PPPAUTHTYPE_ANY might have security consequences.\r
+ * RFC 1994 says:\r
+ *\r
+ * In practice, within or associated with each PPP server, there is a\r
+ * database which associates "user" names with authentication\r
+ * information ("secrets").  It is not anticipated that a particular\r
+ * named user would be authenticated by multiple methods.  This would\r
+ * make the user vulnerable to attacks which negotiate the least secure\r
+ * method from among a set (such as PAP rather than CHAP).  If the same\r
+ * secret was used, PAP would reveal the secret to be used later with\r
+ * CHAP.\r
+ *\r
+ * Instead, for each user name there should be an indication of exactly\r
+ * one method used to authenticate that user name.  If a user needs to\r
+ * make use of different authentication methods under different\r
+ * circumstances, then distinct user names SHOULD be employed, each of\r
+ * which identifies exactly one authentication method.\r
+ *\r
+ */\r
+enum pppAuthType {\r
+    PPPAUTHTYPE_NONE,\r
+    PPPAUTHTYPE_ANY,\r
+    PPPAUTHTYPE_PAP,\r
+    PPPAUTHTYPE_CHAP\r
+};\r
+\r
+void pppSetAuth(enum pppAuthType authType, const char *user, const char *passwd);\r
+\r
+/*\r
+ * Open a new PPP connection using the given I/O device.\r
+ * This initializes the PPP control block but does not\r
+ * attempt to negotiate the LCP session.\r
+ * Return a new PPP connection descriptor on success or\r
+ * an error code (negative) on failure. \r
+ */\r
+int pppOpen(sio_fd_t fd, void (*linkStatusCB)(void *ctx, int errCode, void *arg), void *linkStatusCtx);\r
+\r
+/*\r
+ * Close a PPP connection and release the descriptor. \r
+ * Any outstanding packets in the queues are dropped.\r
+ * Return 0 on success, an error code on failure. \r
+ */\r
+int pppClose(int pd);\r
+\r
+/*\r
+ * Indicate to the PPP process that the line has disconnected.\r
+ */\r
+void pppSigHUP(int pd);\r
+\r
+/*\r
+ * Get and set parameters for the given connection.\r
+ * Return 0 on success, an error code on failure. \r
+ */\r
+int  pppIOCtl(int pd, int cmd, void *arg);\r
+\r
+/*\r
+ * Return the Maximum Transmission Unit for the given PPP connection.\r
+ */\r
+u_int pppMTU(int pd);\r
+\r
+/*\r
+ * Write n characters to a ppp link.\r
+ *     RETURN: >= 0 Number of characters written\r
+ *                      -1 Failed to write to device\r
+ */\r
+int pppWrite(int pd, const u_char *s, int n);\r
+\r
+void pppMainWakeup(int pd);\r
+\r
+/* Configure i/f transmit parameters */\r
+void ppp_send_config (int, int, u32_t, int, int);\r
+/* Set extended transmit ACCM */\r
+void ppp_set_xaccm (int, ext_accm *);\r
+/* Configure i/f receive parameters */\r
+void ppp_recv_config (int, int, u32_t, int, int);\r
+/* Find out how long link has been idle */\r
+int  get_idle_time (int, struct ppp_idle *);\r
+\r
+/* Configure VJ TCP header compression */\r
+int  sifvjcomp (int, int, int, int);\r
+/* Configure i/f down (for IP) */\r
+int  sifup (int);              \r
+/* Set mode for handling packets for proto */\r
+int  sifnpmode (int u, int proto, enum NPmode mode);\r
+/* Configure i/f down (for IP) */\r
+int  sifdown (int);    \r
+/* Configure IP addresses for i/f */\r
+int  sifaddr (int, u32_t, u32_t, u32_t, u32_t, u32_t);\r
+/* Reset i/f IP addresses */\r
+int  cifaddr (int, u32_t, u32_t);\r
+/* Create default route through i/f */\r
+int  sifdefaultroute (int, u32_t, u32_t);\r
+/* Delete default route through i/f */\r
+int  cifdefaultroute (int, u32_t, u32_t);\r
+\r
+/* Get appropriate netmask for address */\r
+u32_t GetMask (u32_t); \r
+\r
+#endif /* PPP_SUPPORT */\r
+\r
+#endif /* PPP_H */\r
index de1478cee832505541b76f2c49f7174209661f33..e4cf25a393c56306ebbb6863827b9e9a8f5fc897 100644 (file)
@@ -1,89 +1,89 @@
-/*****************************************************************************
-* pppdebug.h - System debugging utilities.
-*
-* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
-* portions Copyright (c) 1998 Global Election Systems Inc.
-* portions Copyright (c) 2001 by Cognizant Pty Ltd.
-*
-* The authors hereby grant permission to use, copy, modify, distribute,
-* and license this software and its documentation for any purpose, provided
-* that existing copyright notices are retained in all copies and that this
-* notice and the following disclaimer are included verbatim in any 
-* distributions. No written agreement, license, or royalty fee is required
-* for any of the authorized uses.
-*
-* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *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 CONTRIBUTORS 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.
-*
-******************************************************************************
-* REVISION HISTORY (please don't use tabs!)
-*
-* 03-01-01 Marc Boucher <marc@mbsi.ca>
-*   Ported to lwIP.
-* 98-07-29 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
-*      Original.
-*
-*****************************************************************************
-*/
-#ifndef PPPDEBUG_H
-#define PPPDEBUG_H
-
-/************************
-*** PUBLIC DATA TYPES ***
-************************/
-/* Trace levels. */
-typedef enum {
-       LOG_CRITICAL = 0,
-       LOG_ERR = 1,
-       LOG_NOTICE = 2,
-       LOG_WARNING = 3,
-       LOG_INFO = 5,
-       LOG_DETAIL = 6,
-       LOG_DEBUG = 7
-} LogCodes;
-
-
-/***********************
-*** PUBLIC FUNCTIONS ***
-***********************/
-/*
- *     ppp_trace - a form of printf to send tracing information to stderr
- */
-void ppp_trace(int level, const char *format,...);
-
-#if PPP_DEBUG > 0
-
-#define AUTHDEBUG(a) ppp_trace a
-#define IPCPDEBUG(a) ppp_trace a
-#define UPAPDEBUG(a) ppp_trace a
-#define LCPDEBUG(a) ppp_trace a
-#define FSMDEBUG(a) ppp_trace a
-#define CHAPDEBUG(a) ppp_trace a
-#define PPPDEBUG(a) ppp_trace a
-
-#define TRACELCP 1
-
-#else
-
-#define AUTHDEBUG(a)
-#define IPCPDEBUG(a)
-#define UPAPDEBUG(a)
-#define LCPDEBUG(a)
-#define FSMDEBUG(a)
-#define CHAPDEBUG(a)
-
-#define PPPDEBUG(a)
-
-#define TRACELCP 0
-
-#endif
-
-#endif /* PPPDEBUG_H */
+/*****************************************************************************\r
+* pppdebug.h - System debugging utilities.\r
+*\r
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.\r
+* portions Copyright (c) 1998 Global Election Systems Inc.\r
+* portions Copyright (c) 2001 by Cognizant Pty Ltd.\r
+*\r
+* The authors hereby grant permission to use, copy, modify, distribute,\r
+* and license this software and its documentation for any purpose, provided\r
+* that existing copyright notices are retained in all copies and that this\r
+* notice and the following disclaimer are included verbatim in any \r
+* distributions. No written agreement, license, or royalty fee is required\r
+* for any of the authorized uses.\r
+*\r
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR\r
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+*\r
+******************************************************************************\r
+* REVISION HISTORY (please don't use tabs!)\r
+*\r
+* 03-01-01 Marc Boucher <marc@mbsi.ca>\r
+*   Ported to lwIP.\r
+* 98-07-29 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.\r
+*      Original.\r
+*\r
+*****************************************************************************\r
+*/\r
+#ifndef PPPDEBUG_H\r
+#define PPPDEBUG_H\r
+\r
+/************************\r
+*** PUBLIC DATA TYPES ***\r
+************************/\r
+/* Trace levels. */\r
+typedef enum {\r
+       LOG_CRITICAL = 0,\r
+       LOG_ERR = 1,\r
+       LOG_NOTICE = 2,\r
+       LOG_WARNING = 3,\r
+       LOG_INFO = 5,\r
+       LOG_DETAIL = 6,\r
+       LOG_DEBUG = 7\r
+} LogCodes;\r
+\r
+\r
+/***********************\r
+*** PUBLIC FUNCTIONS ***\r
+***********************/\r
+/*\r
+ *     ppp_trace - a form of printf to send tracing information to stderr\r
+ */\r
+void ppp_trace(int level, const char *format,...);\r
+\r
+#if PPP_DEBUG > 0\r
+\r
+#define AUTHDEBUG(a) ppp_trace a\r
+#define IPCPDEBUG(a) ppp_trace a\r
+#define UPAPDEBUG(a) ppp_trace a\r
+#define LCPDEBUG(a) ppp_trace a\r
+#define FSMDEBUG(a) ppp_trace a\r
+#define CHAPDEBUG(a) ppp_trace a\r
+#define PPPDEBUG(a) ppp_trace a\r
+\r
+#define TRACELCP 1\r
+\r
+#else\r
+\r
+#define AUTHDEBUG(a)\r
+#define IPCPDEBUG(a)\r
+#define UPAPDEBUG(a)\r
+#define LCPDEBUG(a)\r
+#define FSMDEBUG(a)\r
+#define CHAPDEBUG(a)\r
+\r
+#define PPPDEBUG(a)\r
+\r
+#define TRACELCP 0\r
+\r
+#endif\r
+\r
+#endif /* PPPDEBUG_H */\r
index 05eeb4410d7ca60ca2be5dc6d5077e1d214f1c1e..d4431dd8ec104e1fba076ead68e71830aab33122 100644 (file)
-/*****************************************************************************
-* randm.c - Random number generator program file.
-*
-* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
-* Copyright (c) 1998 by Global Election Systems Inc.
-*
-* The authors hereby grant permission to use, copy, modify, distribute,
-* and license this software and its documentation for any purpose, provided
-* that existing copyright notices are retained in all copies and that this
-* notice and the following disclaimer are included verbatim in any 
-* distributions. No written agreement, license, or royalty fee is required
-* for any of the authorized uses.
-*
-* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *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 CONTRIBUTORS 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.
-*
-******************************************************************************
-* REVISION HISTORY
-*
-* 03-01-01 Marc Boucher <marc@mbsi.ca>
-*   Ported to lwIP.
-* 98-06-03 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
-*   Extracted from avos.
-*****************************************************************************/
-
-#include "ppp.h"
-#if PPP_SUPPORT > 0
-#include "md5.h"
-#include "randm.h"
-
-#include "pppdebug.h"
-
-
-#if MD5_SUPPORT>0   /* this module depends on MD5 */
-#define RANDPOOLSZ 16   /* Bytes stored in the pool of randomness. */
-
-/*****************************/
-/*** LOCAL DATA STRUCTURES ***/
-/*****************************/
-static char randPool[RANDPOOLSZ];   /* Pool of randomness. */
-static long randCount = 0;      /* Pseudo-random incrementer */
-
-
-/***********************************/
-/*** PUBLIC FUNCTION DEFINITIONS ***/
-/***********************************/
-/*
- * Initialize the random number generator.
- *
- * Since this is to be called on power up, we don't have much
- *  system randomess to work with.  Here all we use is the
- *  real-time clock.  We'll accumulate more randomness as soon
- *  as things start happening.
- */
-void avRandomInit()
-{
-    avChurnRand(NULL, 0);
-}
-
-/*
- * Churn the randomness pool on a random event.  Call this early and often
- *  on random and semi-random system events to build randomness in time for
- *  usage.  For randomly timed events, pass a null pointer and a zero length
- *  and this will use the system timer and other sources to add randomness.
- *  If new random data is available, pass a pointer to that and it will be
- *  included.
- *
- * Ref: Applied Cryptography 2nd Ed. by Bruce Schneier p. 427
- */
-void avChurnRand(char *randData, u32_t randLen)
-{
-    MD5_CTX md5;
-
-/*  ppp_trace(LOG_INFO, "churnRand: %u@%P\n", randLen, randData); */
-    MD5Init(&md5);
-    MD5Update(&md5, (u_char *)randPool, sizeof(randPool));
-    if (randData)
-        MD5Update(&md5, (u_char *)randData, randLen);
-    else {
-        struct {
-            /* INCLUDE fields for any system sources of randomness */
-            char foobar;
-        } sysData;
-
-        /* Load sysData fields here. */
-        ;
-        MD5Update(&md5, (u_char *)&sysData, sizeof(sysData));
-    }
-    MD5Final((u_char *)randPool, &md5);
-/*  ppp_trace(LOG_INFO, "churnRand: -> 0\n"); */
-}
-
-/*
- * Use the random pool to generate random data.  This degrades to pseudo
- *  random when used faster than randomness is supplied using churnRand().
- * Note: It's important that there be sufficient randomness in randPool
- *  before this is called for otherwise the range of the result may be
- *  narrow enough to make a search feasible.
- *
- * Ref: Applied Cryptography 2nd Ed. by Bruce Schneier p. 427
- *
- * XXX Why does he not just call churnRand() for each block?  Probably
- *  so that you don't ever publish the seed which could possibly help
- *  predict future values.
- * XXX Why don't we preserve md5 between blocks and just update it with
- *  randCount each time?  Probably there is a weakness but I wish that
- *  it was documented.
- */
-void avGenRand(char *buf, u32_t bufLen)
-{
-    MD5_CTX md5;
-    u_char tmp[16];
-    u32_t n;
-
-    while (bufLen > 0) {
-        n = LWIP_MIN(bufLen, RANDPOOLSZ);
-        MD5Init(&md5);
-        MD5Update(&md5, (u_char *)randPool, sizeof(randPool));
-        MD5Update(&md5, (u_char *)&randCount, sizeof(randCount));
-        MD5Final(tmp, &md5);
-        randCount++;
-        memcpy(buf, tmp, n);
-        buf += n;
-        bufLen -= n;
-    }
-}
-
-/*
- * Return a new random number.
- */
-u32_t avRandom()
-{
-    u32_t newRand;
-
-    avGenRand((char *)&newRand, sizeof(newRand));
-
-    return newRand;
-}
-
-#else /* MD5_SUPPORT */
-
-
-/*****************************/
-/*** LOCAL DATA STRUCTURES ***/
-/*****************************/
-static int  avRandomized = 0;       /* Set when truely randomized. */
-static u32_t avRandomSeed = 0;      /* Seed used for random number generation. */
-
-
-/***********************************/
-/*** PUBLIC FUNCTION DEFINITIONS ***/
-/***********************************/
-/*
- * Initialize the random number generator.
- *
- * Here we attempt to compute a random number seed but even if
- * it isn't random, we'll randomize it later.
- *
- * The current method uses the fields from the real time clock,
- * the idle process counter, the millisecond counter, and the
- * hardware timer tick counter.  When this is invoked
- * in startup(), then the idle counter and timer values may
- * repeat after each boot and the real time clock may not be
- * operational.  Thus we call it again on the first random
- * event.
- */
-void avRandomInit()
-{
-#if 0
-    /* Get a pointer into the last 4 bytes of clockBuf. */
-    u32_t *lptr1 = (u32_t *)((char *)&clockBuf[3]);
-
-    /*
-     * Initialize our seed using the real-time clock, the idle
-     * counter, the millisecond timer, and the hardware timer
-     * tick counter.  The real-time clock and the hardware
-     * tick counter are the best sources of randomness but
-     * since the tick counter is only 16 bit (and truncated
-     * at that), the idle counter and millisecond timer
-     * (which may be small values) are added to help
-     * randomize the lower 16 bits of the seed.
-     */
-    readClk();
-    avRandomSeed += *(u32_t *)clockBuf + *lptr1 + OSIdleCtr
-             + ppp_mtime() + ((u32_t)TM1 << 16) + TM1;
-#else
-    avRandomSeed += sys_jiffies(); /* XXX */
-#endif
-        
-    /* Initialize the Borland random number generator. */
-    srand((unsigned)avRandomSeed);
-}
-
-/*
- * Randomize our random seed value.  Here we use the fact that
- * this function is called at *truely random* times by the polling
- * and network functions.  Here we only get 16 bits of new random
- * value but we use the previous value to randomize the other 16
- * bits.
- */
-void avRandomize(void)
-{
-    static u32_t last_jiffies;
-
-    if (!avRandomized) {
-        avRandomized = !0;
-        avRandomInit();
-        /* The initialization function also updates the seed. */
-    } else {
-/*        avRandomSeed += (avRandomSeed << 16) + TM1; */
-       avRandomSeed += (sys_jiffies() - last_jiffies); /* XXX */
-    }
-    last_jiffies = sys_jiffies();
-}
-
-/*
- * Return a new random number.
- * Here we use the Borland rand() function to supply a pseudo random
- * number which we make truely random by combining it with our own
- * seed which is randomized by truely random events. 
- * Thus the numbers will be truely random unless there have been no
- * operator or network events in which case it will be pseudo random
- * seeded by the real time clock.
- */
-u32_t avRandom()
-{
-    return ((((u32_t)rand() << 16) + rand()) + avRandomSeed);
-}
-
-
-
-#endif /* MD5_SUPPORT */
-#endif /* PPP_SUPPORT */
-
+/*****************************************************************************\r
+* randm.c - Random number generator program file.\r
+*\r
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.\r
+* Copyright (c) 1998 by Global Election Systems Inc.\r
+*\r
+* The authors hereby grant permission to use, copy, modify, distribute,\r
+* and license this software and its documentation for any purpose, provided\r
+* that existing copyright notices are retained in all copies and that this\r
+* notice and the following disclaimer are included verbatim in any \r
+* distributions. No written agreement, license, or royalty fee is required\r
+* for any of the authorized uses.\r
+*\r
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR\r
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+*\r
+******************************************************************************\r
+* REVISION HISTORY\r
+*\r
+* 03-01-01 Marc Boucher <marc@mbsi.ca>\r
+*   Ported to lwIP.\r
+* 98-06-03 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.\r
+*   Extracted from avos.\r
+*****************************************************************************/\r
+\r
+#include "ppp.h"\r
+#if PPP_SUPPORT > 0\r
+#include "md5.h"\r
+#include "randm.h"\r
+\r
+#include "pppdebug.h"\r
+\r
+\r
+#if MD5_SUPPORT>0   /* this module depends on MD5 */\r
+#define RANDPOOLSZ 16   /* Bytes stored in the pool of randomness. */\r
+\r
+/*****************************/\r
+/*** LOCAL DATA STRUCTURES ***/\r
+/*****************************/\r
+static char randPool[RANDPOOLSZ];   /* Pool of randomness. */\r
+static long randCount = 0;      /* Pseudo-random incrementer */\r
+\r
+\r
+/***********************************/\r
+/*** PUBLIC FUNCTION DEFINITIONS ***/\r
+/***********************************/\r
+/*\r
+ * Initialize the random number generator.\r
+ *\r
+ * Since this is to be called on power up, we don't have much\r
+ *  system randomess to work with.  Here all we use is the\r
+ *  real-time clock.  We'll accumulate more randomness as soon\r
+ *  as things start happening.\r
+ */\r
+void avRandomInit()\r
+{\r
+    avChurnRand(NULL, 0);\r
+}\r
+\r
+/*\r
+ * Churn the randomness pool on a random event.  Call this early and often\r
+ *  on random and semi-random system events to build randomness in time for\r
+ *  usage.  For randomly timed events, pass a null pointer and a zero length\r
+ *  and this will use the system timer and other sources to add randomness.\r
+ *  If new random data is available, pass a pointer to that and it will be\r
+ *  included.\r
+ *\r
+ * Ref: Applied Cryptography 2nd Ed. by Bruce Schneier p. 427\r
+ */\r
+void avChurnRand(char *randData, u32_t randLen)\r
+{\r
+    MD5_CTX md5;\r
+\r
+/*  ppp_trace(LOG_INFO, "churnRand: %u@%P\n", randLen, randData); */\r
+    MD5Init(&md5);\r
+    MD5Update(&md5, (u_char *)randPool, sizeof(randPool));\r
+    if (randData)\r
+        MD5Update(&md5, (u_char *)randData, randLen);\r
+    else {\r
+        struct {\r
+            /* INCLUDE fields for any system sources of randomness */\r
+            char foobar;\r
+        } sysData;\r
+\r
+        /* Load sysData fields here. */\r
+        ;\r
+        MD5Update(&md5, (u_char *)&sysData, sizeof(sysData));\r
+    }\r
+    MD5Final((u_char *)randPool, &md5);\r
+/*  ppp_trace(LOG_INFO, "churnRand: -> 0\n"); */\r
+}\r
+\r
+/*\r
+ * Use the random pool to generate random data.  This degrades to pseudo\r
+ *  random when used faster than randomness is supplied using churnRand().\r
+ * Note: It's important that there be sufficient randomness in randPool\r
+ *  before this is called for otherwise the range of the result may be\r
+ *  narrow enough to make a search feasible.\r
+ *\r
+ * Ref: Applied Cryptography 2nd Ed. by Bruce Schneier p. 427\r
+ *\r
+ * XXX Why does he not just call churnRand() for each block?  Probably\r
+ *  so that you don't ever publish the seed which could possibly help\r
+ *  predict future values.\r
+ * XXX Why don't we preserve md5 between blocks and just update it with\r
+ *  randCount each time?  Probably there is a weakness but I wish that\r
+ *  it was documented.\r
+ */\r
+void avGenRand(char *buf, u32_t bufLen)\r
+{\r
+    MD5_CTX md5;\r
+    u_char tmp[16];\r
+    u32_t n;\r
+\r
+    while (bufLen > 0) {\r
+        n = LWIP_MIN(bufLen, RANDPOOLSZ);\r
+        MD5Init(&md5);\r
+        MD5Update(&md5, (u_char *)randPool, sizeof(randPool));\r
+        MD5Update(&md5, (u_char *)&randCount, sizeof(randCount));\r
+        MD5Final(tmp, &md5);\r
+        randCount++;\r
+        memcpy(buf, tmp, n);\r
+        buf += n;\r
+        bufLen -= n;\r
+    }\r
+}\r
+\r
+/*\r
+ * Return a new random number.\r
+ */\r
+u32_t avRandom()\r
+{\r
+    u32_t newRand;\r
+\r
+    avGenRand((char *)&newRand, sizeof(newRand));\r
+\r
+    return newRand;\r
+}\r
+\r
+#else /* MD5_SUPPORT */\r
+\r
+\r
+/*****************************/\r
+/*** LOCAL DATA STRUCTURES ***/\r
+/*****************************/\r
+static int  avRandomized = 0;       /* Set when truely randomized. */\r
+static u32_t avRandomSeed = 0;      /* Seed used for random number generation. */\r
+\r
+\r
+/***********************************/\r
+/*** PUBLIC FUNCTION DEFINITIONS ***/\r
+/***********************************/\r
+/*\r
+ * Initialize the random number generator.\r
+ *\r
+ * Here we attempt to compute a random number seed but even if\r
+ * it isn't random, we'll randomize it later.\r
+ *\r
+ * The current method uses the fields from the real time clock,\r
+ * the idle process counter, the millisecond counter, and the\r
+ * hardware timer tick counter.  When this is invoked\r
+ * in startup(), then the idle counter and timer values may\r
+ * repeat after each boot and the real time clock may not be\r
+ * operational.  Thus we call it again on the first random\r
+ * event.\r
+ */\r
+void avRandomInit()\r
+{\r
+#if 0\r
+    /* Get a pointer into the last 4 bytes of clockBuf. */\r
+    u32_t *lptr1 = (u32_t *)((char *)&clockBuf[3]);\r
+\r
+    /*\r
+     * Initialize our seed using the real-time clock, the idle\r
+     * counter, the millisecond timer, and the hardware timer\r
+     * tick counter.  The real-time clock and the hardware\r
+     * tick counter are the best sources of randomness but\r
+     * since the tick counter is only 16 bit (and truncated\r
+     * at that), the idle counter and millisecond timer\r
+     * (which may be small values) are added to help\r
+     * randomize the lower 16 bits of the seed.\r
+     */\r
+    readClk();\r
+    avRandomSeed += *(u32_t *)clockBuf + *lptr1 + OSIdleCtr\r
+             + ppp_mtime() + ((u32_t)TM1 << 16) + TM1;\r
+#else\r
+    avRandomSeed += sys_jiffies(); /* XXX */\r
+#endif\r
+        \r
+    /* Initialize the Borland random number generator. */\r
+    srand((unsigned)avRandomSeed);\r
+}\r
+\r
+/*\r
+ * Randomize our random seed value.  Here we use the fact that\r
+ * this function is called at *truely random* times by the polling\r
+ * and network functions.  Here we only get 16 bits of new random\r
+ * value but we use the previous value to randomize the other 16\r
+ * bits.\r
+ */\r
+void avRandomize(void)\r
+{\r
+    static u32_t last_jiffies;\r
+\r
+    if (!avRandomized) {\r
+        avRandomized = !0;\r
+        avRandomInit();\r
+        /* The initialization function also updates the seed. */\r
+    } else {\r
+/*        avRandomSeed += (avRandomSeed << 16) + TM1; */\r
+       avRandomSeed += (sys_jiffies() - last_jiffies); /* XXX */\r
+    }\r
+    last_jiffies = sys_jiffies();\r
+}\r
+\r
+/*\r
+ * Return a new random number.\r
+ * Here we use the Borland rand() function to supply a pseudo random\r
+ * number which we make truely random by combining it with our own\r
+ * seed which is randomized by truely random events. \r
+ * Thus the numbers will be truely random unless there have been no\r
+ * operator or network events in which case it will be pseudo random\r
+ * seeded by the real time clock.\r
+ */\r
+u32_t avRandom()\r
+{\r
+    return ((((u32_t)rand() << 16) + rand()) + avRandomSeed);\r
+}\r
+\r
+\r
+\r
+#endif /* MD5_SUPPORT */\r
+#endif /* PPP_SUPPORT */\r
+\r
index baa42f0c2cdfe3f82a0f3a7483f48b43b6419e84..2563d8976719a8332d38df26879cf6a38f395a37 100644 (file)
@@ -1,81 +1,81 @@
-/*****************************************************************************
-* randm.h - Random number generator header file.
-*
-* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
-* Copyright (c) 1998 Global Election Systems Inc.
-*
-* The authors hereby grant permission to use, copy, modify, distribute,
-* and license this software and its documentation for any purpose, provided
-* that existing copyright notices are retained in all copies and that this
-* notice and the following disclaimer are included verbatim in any 
-* distributions. No written agreement, license, or royalty fee is required
-* for any of the authorized uses.
-*
-* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *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 CONTRIBUTORS 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.
-*
-******************************************************************************
-* REVISION HISTORY
-*
-* 03-01-01 Marc Boucher <marc@mbsi.ca>
-*   Ported to lwIP.
-* 98-05-29 Guy Lancaster <glanca@gesn.com>, Global Election Systems Inc.
-*      Extracted from avos.
-*****************************************************************************/
-
-#ifndef RANDM_H
-#define RANDM_H
-
-/***********************
-*** PUBLIC FUNCTIONS ***
-***********************/
-/*
- * Initialize the random number generator.
- */
-void avRandomInit(void);
-
-/*
- * Churn the randomness pool on a random event.  Call this early and often
- *     on random and semi-random system events to build randomness in time for
- *     usage.  For randomly timed events, pass a null pointer and a zero length
- *     and this will use the system timer and other sources to add randomness.
- *     If new random data is available, pass a pointer to that and it will be
- *     included.
- */
-void avChurnRand(char *randData, u32_t randLen);
-
-/*
- * Randomize our random seed value.  To be called for truely random events
- * such as user operations and network traffic.
- */
-#if MD5_SUPPORT
-#define avRandomize()  avChurnRand(NULL, 0)
-#else
-void avRandomize(void);
-#endif
-
-/*
- * Use the random pool to generate random data.  This degrades to pseudo
- *     random when used faster than randomness is supplied using churnRand().
- *     Thus it's important to make sure that the results of this are not
- *     published directly because one could predict the next result to at
- *     least some degree.  Also, it's important to get a good seed before
- *     the first use.
- */
-void avGenRand(char *buf, u32_t bufLen);
-
-/*
- * Return a new random number.
- */
-u32_t avRandom(void);
-
-
-#endif /* RANDM_H */
+/*****************************************************************************\r
+* randm.h - Random number generator header file.\r
+*\r
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.\r
+* Copyright (c) 1998 Global Election Systems Inc.\r
+*\r
+* The authors hereby grant permission to use, copy, modify, distribute,\r
+* and license this software and its documentation for any purpose, provided\r
+* that existing copyright notices are retained in all copies and that this\r
+* notice and the following disclaimer are included verbatim in any \r
+* distributions. No written agreement, license, or royalty fee is required\r
+* for any of the authorized uses.\r
+*\r
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR\r
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+*\r
+******************************************************************************\r
+* REVISION HISTORY\r
+*\r
+* 03-01-01 Marc Boucher <marc@mbsi.ca>\r
+*   Ported to lwIP.\r
+* 98-05-29 Guy Lancaster <glanca@gesn.com>, Global Election Systems Inc.\r
+*      Extracted from avos.\r
+*****************************************************************************/\r
+\r
+#ifndef RANDM_H\r
+#define RANDM_H\r
+\r
+/***********************\r
+*** PUBLIC FUNCTIONS ***\r
+***********************/\r
+/*\r
+ * Initialize the random number generator.\r
+ */\r
+void avRandomInit(void);\r
+\r
+/*\r
+ * Churn the randomness pool on a random event.  Call this early and often\r
+ *     on random and semi-random system events to build randomness in time for\r
+ *     usage.  For randomly timed events, pass a null pointer and a zero length\r
+ *     and this will use the system timer and other sources to add randomness.\r
+ *     If new random data is available, pass a pointer to that and it will be\r
+ *     included.\r
+ */\r
+void avChurnRand(char *randData, u32_t randLen);\r
+\r
+/*\r
+ * Randomize our random seed value.  To be called for truely random events\r
+ * such as user operations and network traffic.\r
+ */\r
+#if MD5_SUPPORT\r
+#define avRandomize()  avChurnRand(NULL, 0)\r
+#else\r
+void avRandomize(void);\r
+#endif\r
+\r
+/*\r
+ * Use the random pool to generate random data.  This degrades to pseudo\r
+ *     random when used faster than randomness is supplied using churnRand().\r
+ *     Thus it's important to make sure that the results of this are not\r
+ *     published directly because one could predict the next result to at\r
+ *     least some degree.  Also, it's important to get a good seed before\r
+ *     the first use.\r
+ */\r
+void avGenRand(char *buf, u32_t bufLen);\r
+\r
+/*\r
+ * Return a new random number.\r
+ */\r
+u32_t avRandom(void);\r
+\r
+\r
+#endif /* RANDM_H */\r
index 0636ee11bd89afc885a57dd467f2b0fc67800592..2c11affe35821fd4774a66d45c72c8841664589c 100644 (file)
-/*
- * Routines to compress and uncompess tcp packets (for transmission
- * over low speed serial lines.
- *
- * Copyright (c) 1989 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley.  The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- *     Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989:
- *     - Initial distribution.
- *
- * Modified June 1993 by Paul Mackerras, paulus@cs.anu.edu.au,
- * so that the entire packet being decompressed doesn't have
- * to be in contiguous memory (just the compressed header).
- *
- * Modified March 1998 by Guy Lancaster, glanca@gesn.com,
- * for a 16 bit processor.
- */
-
-#include <string.h>
-
-#include "ppp.h"
-#include "vj.h"
-#include "pppdebug.h"
-
-#if VJ_SUPPORT > 0
-
-#if LINK_STATS
-#define INCR(counter) ++comp->stats.counter
-#else
-#define INCR(counter)
-#endif
-
-#if defined(NO_CHAR_BITFIELDS)
-#define getip_hl(base) ((base).ip_hl_v&0xf)
-#define getth_off(base)        (((base).th_x2_off&0xf0)>>4)
-#else
-#define getip_hl(base) ((base).ip_hl)
-#define getth_off(base)        ((base).th_off)
-#endif
-
-void vj_compress_init(struct vjcompress *comp)
-{
-       register u_int i;
-       register struct cstate *tstate = comp->tstate;
-       
-#if MAX_SLOTS == 0
-       memset((char *)comp, 0, sizeof(*comp));
-#endif
-       comp->maxSlotIndex = MAX_SLOTS - 1;
-       comp->compressSlot = 0;         /* Disable slot ID compression by default. */
-       for (i = MAX_SLOTS - 1; i > 0; --i) {
-               tstate[i].cs_id = i;
-               tstate[i].cs_next = &tstate[i - 1];
-       }
-       tstate[0].cs_next = &tstate[MAX_SLOTS - 1];
-       tstate[0].cs_id = 0;
-       comp->last_cs = &tstate[0];
-       comp->last_recv = 255;
-       comp->last_xmit = 255;
-       comp->flags = VJF_TOSS;
-}
-
-
-/* ENCODE encodes a number that is known to be non-zero.  ENCODEZ
- * checks for zero (since zero has to be encoded in the long, 3 byte
- * form).
- */
-#define ENCODE(n) { \
-       if ((u_short)(n) >= 256) { \
-               *cp++ = 0; \
-               cp[1] = (n); \
-               cp[0] = (n) >> 8; \
-               cp += 2; \
-       } else { \
-               *cp++ = (n); \
-       } \
-}
-#define ENCODEZ(n) { \
-       if ((u_short)(n) >= 256 || (u_short)(n) == 0) { \
-               *cp++ = 0; \
-               cp[1] = (n); \
-               cp[0] = (n) >> 8; \
-               cp += 2; \
-       } else { \
-               *cp++ = (n); \
-       } \
-}
-
-#define DECODEL(f) { \
-       if (*cp == 0) {\
-               u32_t tmp = ntohl(f) + ((cp[1] << 8) | cp[2]); \
-               (f) = htonl(tmp); \
-               cp += 3; \
-       } else { \
-               u32_t tmp = ntohl(f) + (u32_t)*cp++; \
-               (f) = htonl(tmp); \
-       } \
-}
-
-#define DECODES(f) { \
-       if (*cp == 0) {\
-               u_short tmp = ntohs(f) + (((u_short)cp[1] << 8) | cp[2]); \
-               (f) = htons(tmp); \
-               cp += 3; \
-       } else { \
-               u_short tmp = ntohs(f) + (u_short)*cp++; \
-               (f) = htons(tmp); \
-       } \
-}
-
-#define DECODEU(f) { \
-       if (*cp == 0) {\
-               (f) = htons(((u_short)cp[1] << 8) | cp[2]); \
-               cp += 3; \
-       } else { \
-               (f) = htons((u_short)*cp++); \
-       } \
-}
-
-/*
- * vj_compress_tcp - Attempt to do Van Jacobsen header compression on a
- * packet.  This assumes that nb and comp are not null and that the first
- * buffer of the chain contains a valid IP header.
- * Return the VJ type code indicating whether or not the packet was
- * compressed.
- */
-u_int vj_compress_tcp(
-       struct vjcompress *comp,
-       struct pbuf *pb
-)
-{
-       register struct ip *ip = (struct ip *)pb->payload;
-       register struct cstate *cs = comp->last_cs->cs_next;
-       register u_short hlen = getip_hl(*ip);
-       register struct tcphdr *oth;
-       register struct tcphdr *th;
-       register u_short deltaS, deltaA;
-       register u_long deltaL;
-       register u_int changes = 0;
-       u_char new_seq[16];
-       register u_char *cp = new_seq;
-
-       /*      
-        * Check that the packet is IP proto TCP.
-        */
-       if (ip->ip_p != IPPROTO_TCP)
-               return (TYPE_IP);
-               
-       /*
-        * Bail if this is an IP fragment or if the TCP packet isn't
-        * `compressible' (i.e., ACK isn't set or some other control bit is
-        * set).  
-        */
-       if ((ip->ip_off & htons(0x3fff)) || pb->tot_len < 40)
-               return (TYPE_IP);
-       th = (struct tcphdr *)&((long *)ip)[hlen];
-       if ((th->th_flags & (TCP_SYN|TCP_FIN|TCP_RST|TCP_ACK)) != TCP_ACK)
-               return (TYPE_IP);
-               
-       /*
-        * Packet is compressible -- we're going to send either a
-        * COMPRESSED_TCP or UNCOMPRESSED_TCP packet.  Either way we need
-        * to locate (or create) the connection state.  Special case the
-        * most recently used connection since it's most likely to be used
-        * again & we don't have to do any reordering if it's used.
-        */
-       INCR(vjs_packets);
-       if (ip->ip_src.s_addr != cs->cs_ip.ip_src.s_addr 
-                       || ip->ip_dst.s_addr != cs->cs_ip.ip_dst.s_addr 
-                       || *(long *)th != ((long *)&cs->cs_ip)[getip_hl(cs->cs_ip)]) {
-               /*
-                * Wasn't the first -- search for it.
-                *
-                * States are kept in a circularly linked list with
-                * last_cs pointing to the end of the list.  The
-                * list is kept in lru order by moving a state to the
-                * head of the list whenever it is referenced.  Since
-                * the list is short and, empirically, the connection
-                * we want is almost always near the front, we locate
-                * states via linear search.  If we don't find a state
-                * for the datagram, the oldest state is (re-)used.
-                */
-               register struct cstate *lcs;
-               register struct cstate *lastcs = comp->last_cs;
-               
-               do {
-                       lcs = cs; cs = cs->cs_next;
-                       INCR(vjs_searches);
-                       if (ip->ip_src.s_addr == cs->cs_ip.ip_src.s_addr
-                                       && ip->ip_dst.s_addr == cs->cs_ip.ip_dst.s_addr
-                                       && *(long *)th == ((long *)&cs->cs_ip)[getip_hl(cs->cs_ip)])
-                               goto found;
-               } while (cs != lastcs);
-               
-               /*
-                * Didn't find it -- re-use oldest cstate.  Send an
-                * uncompressed packet that tells the other side what
-                * connection number we're using for this conversation.
-                * Note that since the state list is circular, the oldest
-                * state points to the newest and we only need to set
-                * last_cs to update the lru linkage.
-                */
-               INCR(vjs_misses);
-               comp->last_cs = lcs;
-               hlen += getth_off(*th);
-               hlen <<= 2;
-               /* Check that the IP/TCP headers are contained in the first buffer. */
-               if (hlen > pb->len)
-                       return (TYPE_IP);
-               goto uncompressed;
-               
-               found:
-               /*
-                * Found it -- move to the front on the connection list.
-                */
-               if (cs == lastcs)
-                       comp->last_cs = lcs;
-               else {
-                       lcs->cs_next = cs->cs_next;
-                       cs->cs_next = lastcs->cs_next;
-                       lastcs->cs_next = cs;
-               }
-       }
-       
-       oth = (struct tcphdr *)&((long *)&cs->cs_ip)[hlen];
-       deltaS = hlen;
-       hlen += getth_off(*th);
-       hlen <<= 2;
-       /* Check that the IP/TCP headers are contained in the first buffer. */
-       if (hlen > pb->len) {
-               PPPDEBUG((LOG_INFO, "vj_compress_tcp: header len %d spans buffers\n", 
-                                       hlen));
-               return (TYPE_IP);
-       }
-       
-       /*
-        * Make sure that only what we expect to change changed. The first
-        * line of the `if' checks the IP protocol version, header length &
-        * type of service.  The 2nd line checks the "Don't fragment" bit.
-        * The 3rd line checks the time-to-live and protocol (the protocol
-        * check is unnecessary but costless).  The 4th line checks the TCP
-        * header length.  The 5th line checks IP options, if any.  The 6th
-        * line checks TCP options, if any.  If any of these things are
-        * different between the previous & current datagram, we send the
-        * current datagram `uncompressed'.
-        */
-       if (((u_short *)ip)[0] != ((u_short *)&cs->cs_ip)[0] 
-                       || ((u_short *)ip)[3] != ((u_short *)&cs->cs_ip)[3] 
-                       || ((u_short *)ip)[4] != ((u_short *)&cs->cs_ip)[4] 
-                       || getth_off(*th) != getth_off(*oth) 
-                       || (deltaS > 5 && BCMP(ip + 1, &cs->cs_ip + 1, (deltaS - 5) << 2)) 
-                       || (getth_off(*th) > 5 && BCMP(th + 1, oth + 1, (getth_off(*th) - 5) << 2)))
-               goto uncompressed;
-       
-       /*
-        * Figure out which of the changing fields changed.  The
-        * receiver expects changes in the order: urgent, window,
-        * ack, seq (the order minimizes the number of temporaries
-        * needed in this section of code).
-        */
-       if (th->th_flags & TCP_URG) {
-               deltaS = ntohs(th->th_urp);
-               ENCODEZ(deltaS);
-               changes |= NEW_U;
-       } else if (th->th_urp != oth->th_urp)
-               /* argh! URG not set but urp changed -- a sensible
-                * implementation should never do this but RFC793
-                * doesn't prohibit the change so we have to deal
-                * with it. */
-               goto uncompressed;
-       
-       if ((deltaS = (u_short)(ntohs(th->th_win) - ntohs(oth->th_win))) != 0) {
-               ENCODE(deltaS);
-               changes |= NEW_W;
-       }
-       
-       if ((deltaL = ntohl(th->th_ack) - ntohl(oth->th_ack)) != 0) {
-               if (deltaL > 0xffff)
-                       goto uncompressed;
-               deltaA = (u_short)deltaL;
-               ENCODE(deltaA);
-               changes |= NEW_A;
-       }
-       
-       if ((deltaL = ntohl(th->th_seq) - ntohl(oth->th_seq)) != 0) {
-               if (deltaL > 0xffff)
-                       goto uncompressed;
-               deltaS = (u_short)deltaL;
-               ENCODE(deltaS);
-               changes |= NEW_S;
-       }
-       
-       switch(changes) {
-       
-       case 0:
-               /*
-                * Nothing changed. If this packet contains data and the
-                * last one didn't, this is probably a data packet following
-                * an ack (normal on an interactive connection) and we send
-                * it compressed.  Otherwise it's probably a retransmit,
-                * retransmitted ack or window probe.  Send it uncompressed
-                * in case the other side missed the compressed version.
-                */
-               if (ip->ip_len != cs->cs_ip.ip_len &&
-                       ntohs(cs->cs_ip.ip_len) == hlen)
-               break;
-       
-       /* (fall through) */
-       
-       case SPECIAL_I:
-       case SPECIAL_D:
-               /*
-                * actual changes match one of our special case encodings --
-                * send packet uncompressed.
-                */
-               goto uncompressed;
-       
-       case NEW_S|NEW_A:
-               if (deltaS == deltaA && deltaS == ntohs(cs->cs_ip.ip_len) - hlen) {
-                       /* special case for echoed terminal traffic */
-                       changes = SPECIAL_I;
-                       cp = new_seq;
-               }
-               break;
-       
-       case NEW_S:
-               if (deltaS == ntohs(cs->cs_ip.ip_len) - hlen) {
-                       /* special case for data xfer */
-                       changes = SPECIAL_D;
-                       cp = new_seq;
-               }
-               break;
-       }
-       
-       deltaS = (u_short)(ntohs(ip->ip_id) - ntohs(cs->cs_ip.ip_id));
-       if (deltaS != 1) {
-               ENCODEZ(deltaS);
-               changes |= NEW_I;
-       }
-       if (th->th_flags & TCP_PSH)
-       changes |= TCP_PUSH_BIT;
-       /*
-        * Grab the cksum before we overwrite it below.  Then update our
-        * state with this packet's header.
-        */
-       deltaA = ntohs(th->th_sum);
-       BCOPY(ip, &cs->cs_ip, hlen);
-       
-       /*
-        * We want to use the original packet as our compressed packet.
-        * (cp - new_seq) is the number of bytes we need for compressed
-        * sequence numbers.  In addition we need one byte for the change
-        * mask, one for the connection id and two for the tcp checksum.
-        * So, (cp - new_seq) + 4 bytes of header are needed.  hlen is how
-        * many bytes of the original packet to toss so subtract the two to
-        * get the new packet size.
-        */
-       deltaS = (u_short)(cp - new_seq);
-       if (!comp->compressSlot || comp->last_xmit != cs->cs_id) {
-               comp->last_xmit = cs->cs_id;
-               hlen -= deltaS + 4;
-               pbuf_header(pb, -hlen);
-               cp = (u_char *)pb->payload;
-               *cp++ = changes | NEW_C;
-               *cp++ = cs->cs_id;
-       } else {
-               hlen -= deltaS + 3;
-               pbuf_header(pb, -hlen);
-               cp = (u_char *)pb->payload;
-               *cp++ = changes;
-       }
-       *cp++ = deltaA >> 8;
-       *cp++ = deltaA;
-       BCOPY(new_seq, cp, deltaS);
-       INCR(vjs_compressed);
-       return (TYPE_COMPRESSED_TCP);
-
-       /*
-        * Update connection state cs & send uncompressed packet (that is,
-        * a regular ip/tcp packet but with the 'conversation id' we hope
-        * to use on future compressed packets in the protocol field).
-        */
-uncompressed:
-       BCOPY(ip, &cs->cs_ip, hlen);
-       ip->ip_p = cs->cs_id;
-       comp->last_xmit = cs->cs_id;
-       return (TYPE_UNCOMPRESSED_TCP);
-}
-
-/*
- * Called when we may have missed a packet.
- */
-void vj_uncompress_err(struct vjcompress *comp)
-{
-    comp->flags |= VJF_TOSS;
-       INCR(vjs_errorin);
-}
-
-/*
- * "Uncompress" a packet of type TYPE_UNCOMPRESSED_TCP.
- * Return 0 on success, -1 on failure.
- */
-int vj_uncompress_uncomp(
-       struct pbuf *nb,
-       struct vjcompress *comp
-)
-{
-       register u_int hlen;
-       register struct cstate *cs;
-       register struct ip *ip;
-       
-       ip = (struct ip *)nb->payload;
-       hlen = getip_hl(*ip) << 2;
-       if (ip->ip_p >= MAX_SLOTS
-                       || hlen + sizeof(struct tcphdr) > nb->len
-                       || (hlen += getth_off(*((struct tcphdr *)&((char *)ip)[hlen])) << 2)
-                           > nb->len
-                       || hlen > MAX_HDR) {
-               PPPDEBUG((LOG_INFO, "vj_uncompress_uncomp: bad cid=%d, hlen=%d buflen=%d\n", 
-                                       ip->ip_p, hlen, nb->len));
-               comp->flags |= VJF_TOSS;
-               INCR(vjs_errorin);
-               return -1;
-       }
-       cs = &comp->rstate[comp->last_recv = ip->ip_p];
-       comp->flags &=~ VJF_TOSS;
-       ip->ip_p = IPPROTO_TCP;
-       BCOPY(ip, &cs->cs_ip, hlen);
-       cs->cs_hlen = hlen;
-       INCR(vjs_uncompressedin);
-       return 0;
-}
-
-/*
- * Uncompress a packet of type TYPE_COMPRESSED_TCP.
- * The packet is composed of a buffer chain and the first buffer
- * must contain an accurate chain length.
- * The first buffer must include the entire compressed TCP/IP header. 
- * This procedure replaces the compressed header with the uncompressed
- * header and returns the length of the VJ header.
- */
-int vj_uncompress_tcp(
-       struct pbuf **nb,
-       struct vjcompress *comp
-)
-{
-       u_char *cp;
-       struct tcphdr *th;
-       struct cstate *cs;
-       u_short *bp;
-       struct pbuf *n0 = *nb;
-       u32_t tmp;
-       u_int vjlen, hlen, changes;
-       
-       INCR(vjs_compressedin);
-       cp = (u_char *)n0->payload;
-       changes = *cp++;
-       if (changes & NEW_C) {
-               /* 
-                * Make sure the state index is in range, then grab the state.
-                * If we have a good state index, clear the 'discard' flag. 
-                */
-               if (*cp >= MAX_SLOTS) {
-                       PPPDEBUG((LOG_INFO, "vj_uncompress_tcp: bad cid=%d\n", *cp));
-                       goto bad;
-               }
-               
-               comp->flags &=~ VJF_TOSS;
-               comp->last_recv = *cp++;
-       } else {
-               /* 
-                * this packet has an implicit state index.  If we've
-                * had a line error since the last time we got an
-                * explicit state index, we have to toss the packet. 
-                */
-               if (comp->flags & VJF_TOSS) {
-                       PPPDEBUG((LOG_INFO, "vj_uncompress_tcp: tossing\n"));
-                       INCR(vjs_tossed);
-                       return (-1);
-               }
-       }
-       cs = &comp->rstate[comp->last_recv];
-       hlen = getip_hl(cs->cs_ip) << 2;
-       th = (struct tcphdr *)&((u_char *)&cs->cs_ip)[hlen];
-       th->th_sum = htons((*cp << 8) | cp[1]);
-       cp += 2;
-       if (changes & TCP_PUSH_BIT)
-               th->th_flags |= TCP_PSH;
-       else
-               th->th_flags &=~ TCP_PSH;
-       
-       switch (changes & SPECIALS_MASK) {
-       case SPECIAL_I:
-               {
-                       register u32_t i = ntohs(cs->cs_ip.ip_len) - cs->cs_hlen;
-                       /* some compilers can't nest inline assembler.. */
-                       tmp = ntohl(th->th_ack) + i;
-                       th->th_ack = htonl(tmp);
-                       tmp = ntohl(th->th_seq) + i;
-                       th->th_seq = htonl(tmp);
-               }
-               break;
-       
-       case SPECIAL_D:
-               /* some compilers can't nest inline assembler.. */
-               tmp = ntohl(th->th_seq) + ntohs(cs->cs_ip.ip_len) - cs->cs_hlen;
-               th->th_seq = htonl(tmp);
-               break;
-       
-       default:
-               if (changes & NEW_U) {
-                       th->th_flags |= TCP_URG;
-                       DECODEU(th->th_urp);
-               } else
-                       th->th_flags &=~ TCP_URG;
-               if (changes & NEW_W)
-                       DECODES(th->th_win);
-               if (changes & NEW_A)
-                       DECODEL(th->th_ack);
-               if (changes & NEW_S)
-                       DECODEL(th->th_seq);
-               break;
-       }
-       if (changes & NEW_I) {
-               DECODES(cs->cs_ip.ip_id);
-       } else {
-               cs->cs_ip.ip_id = ntohs(cs->cs_ip.ip_id) + 1;
-               cs->cs_ip.ip_id = htons(cs->cs_ip.ip_id);
-       }
-       
-       /*
-        * At this point, cp points to the first byte of data in the
-        * packet.  Fill in the IP total length and update the IP
-        * header checksum.
-        */
-       vjlen = (u_short)(cp - (u_char*)n0->payload);
-       if (n0->len < vjlen) {
-               /* 
-                * We must have dropped some characters (crc should detect
-                * this but the old slip framing won't) 
-                */
-               PPPDEBUG((LOG_INFO, "vj_uncompress_tcp: head buffer %d too short %d\n", 
-                                 n0->len, vjlen));
-               goto bad;
-       }
-       
-#if BYTE_ORDER == LITTLE_ENDIAN
-       tmp = n0->tot_len - vjlen + cs->cs_hlen;
-       cs->cs_ip.ip_len = htons(tmp);
-#else
-       cs->cs_ip.ip_len = htons(n0->tot_len - vjlen + cs->cs_hlen);
-#endif
-       
-       /* recompute the ip header checksum */
-       bp = (u_short *) &cs->cs_ip;
-       cs->cs_ip.ip_sum = 0;
-       for (tmp = 0; hlen > 0; hlen -= 2)
-               tmp += *bp++;
-       tmp = (tmp & 0xffff) + (tmp >> 16);
-       tmp = (tmp & 0xffff) + (tmp >> 16);
-       cs->cs_ip.ip_sum = (u_short)(~tmp);
-       
-       /* Remove the compressed header and prepend the uncompressed header. */
-       pbuf_header(n0, -vjlen);
-
-       if(MEM_ALIGN(n0->payload) != n0->payload) {
-               struct pbuf *np, *q;
-               u8_t *bufptr;
-
-               np = pbuf_alloc(PBUF_RAW, n0->len + cs->cs_hlen, PBUF_POOL);
-               if(!np) {
-                       PPPDEBUG((LOG_WARNING, "vj_uncompress_tcp: realign failed\n"));
-                       *nb = NULL;
-                       goto bad;
-               }
-
-               pbuf_header(np, -cs->cs_hlen);
-
-               bufptr = n0->payload;
-               for(q = np; q != NULL; q = q->next) {
-                       memcpy(q->payload, bufptr, q->len);
-                       bufptr += q->len;
-               }
-
-               if(n0->next) {
-                       pbuf_chain(np, n0->next);
-                       pbuf_dechain(n0);
-               }
-               pbuf_free(n0);
-               n0 = np;
-       }
-
-       if(pbuf_header(n0, cs->cs_hlen)) {
-               struct pbuf *np;
-
-               LWIP_ASSERT("vj_uncompress_tcp: cs->cs_hlen <= PBUF_POOL_BUFSIZE", cs->cs_hlen <= PBUF_POOL_BUFSIZE);
-               np = pbuf_alloc(PBUF_RAW, cs->cs_hlen, PBUF_POOL);
-               if(!np) {
-                       PPPDEBUG((LOG_WARNING, "vj_uncompress_tcp: prepend failed\n"));
-                       *nb = NULL;
-                       goto bad;
-               }
-               pbuf_cat(np, n0);
-               n0 = np;
-       }
-       LWIP_ASSERT("n0->len >= cs->cs_hlen", n0->len >= cs->cs_hlen);
-       memcpy(n0->payload, &cs->cs_ip, cs->cs_hlen);
-
-       *nb = n0;
-
-       return vjlen;
-       
-bad:
-       comp->flags |= VJF_TOSS;
-       INCR(vjs_errorin);
-       return (-1);
-}
-
-#endif
-
-
+/*\r
+ * Routines to compress and uncompess tcp packets (for transmission\r
+ * over low speed serial lines.\r
+ *\r
+ * Copyright (c) 1989 Regents of the University of California.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms are permitted\r
+ * provided that the above copyright notice and this paragraph are\r
+ * duplicated in all such forms and that any documentation,\r
+ * advertising materials, and other materials related to such\r
+ * distribution and use acknowledge that the software was developed\r
+ * by the University of California, Berkeley.  The name of the\r
+ * University may not be used to endorse or promote products derived\r
+ * from this software without specific prior written permission.\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR\r
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r
+ *\r
+ *     Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989:\r
+ *     - Initial distribution.\r
+ *\r
+ * Modified June 1993 by Paul Mackerras, paulus@cs.anu.edu.au,\r
+ * so that the entire packet being decompressed doesn't have\r
+ * to be in contiguous memory (just the compressed header).\r
+ *\r
+ * Modified March 1998 by Guy Lancaster, glanca@gesn.com,\r
+ * for a 16 bit processor.\r
+ */\r
+\r
+#include <string.h>\r
+\r
+#include "ppp.h"\r
+#include "vj.h"\r
+#include "pppdebug.h"\r
+\r
+#if VJ_SUPPORT > 0\r
+\r
+#if LINK_STATS\r
+#define INCR(counter) ++comp->stats.counter\r
+#else\r
+#define INCR(counter)\r
+#endif\r
+\r
+#if defined(NO_CHAR_BITFIELDS)\r
+#define getip_hl(base) ((base).ip_hl_v&0xf)\r
+#define getth_off(base)        (((base).th_x2_off&0xf0)>>4)\r
+#else\r
+#define getip_hl(base) ((base).ip_hl)\r
+#define getth_off(base)        ((base).th_off)\r
+#endif\r
+\r
+void vj_compress_init(struct vjcompress *comp)\r
+{\r
+       register u_int i;\r
+       register struct cstate *tstate = comp->tstate;\r
+       \r
+#if MAX_SLOTS == 0\r
+       memset((char *)comp, 0, sizeof(*comp));\r
+#endif\r
+       comp->maxSlotIndex = MAX_SLOTS - 1;\r
+       comp->compressSlot = 0;         /* Disable slot ID compression by default. */\r
+       for (i = MAX_SLOTS - 1; i > 0; --i) {\r
+               tstate[i].cs_id = i;\r
+               tstate[i].cs_next = &tstate[i - 1];\r
+       }\r
+       tstate[0].cs_next = &tstate[MAX_SLOTS - 1];\r
+       tstate[0].cs_id = 0;\r
+       comp->last_cs = &tstate[0];\r
+       comp->last_recv = 255;\r
+       comp->last_xmit = 255;\r
+       comp->flags = VJF_TOSS;\r
+}\r
+\r
+\r
+/* ENCODE encodes a number that is known to be non-zero.  ENCODEZ\r
+ * checks for zero (since zero has to be encoded in the long, 3 byte\r
+ * form).\r
+ */\r
+#define ENCODE(n) { \\r
+       if ((u_short)(n) >= 256) { \\r
+               *cp++ = 0; \\r
+               cp[1] = (n); \\r
+               cp[0] = (n) >> 8; \\r
+               cp += 2; \\r
+       } else { \\r
+               *cp++ = (n); \\r
+       } \\r
+}\r
+#define ENCODEZ(n) { \\r
+       if ((u_short)(n) >= 256 || (u_short)(n) == 0) { \\r
+               *cp++ = 0; \\r
+               cp[1] = (n); \\r
+               cp[0] = (n) >> 8; \\r
+               cp += 2; \\r
+       } else { \\r
+               *cp++ = (n); \\r
+       } \\r
+}\r
+\r
+#define DECODEL(f) { \\r
+       if (*cp == 0) {\\r
+               u32_t tmp = ntohl(f) + ((cp[1] << 8) | cp[2]); \\r
+               (f) = htonl(tmp); \\r
+               cp += 3; \\r
+       } else { \\r
+               u32_t tmp = ntohl(f) + (u32_t)*cp++; \\r
+               (f) = htonl(tmp); \\r
+       } \\r
+}\r
+\r
+#define DECODES(f) { \\r
+       if (*cp == 0) {\\r
+               u_short tmp = ntohs(f) + (((u_short)cp[1] << 8) | cp[2]); \\r
+               (f) = htons(tmp); \\r
+               cp += 3; \\r
+       } else { \\r
+               u_short tmp = ntohs(f) + (u_short)*cp++; \\r
+               (f) = htons(tmp); \\r
+       } \\r
+}\r
+\r
+#define DECODEU(f) { \\r
+       if (*cp == 0) {\\r
+               (f) = htons(((u_short)cp[1] << 8) | cp[2]); \\r
+               cp += 3; \\r
+       } else { \\r
+               (f) = htons((u_short)*cp++); \\r
+       } \\r
+}\r
+\r
+/*\r
+ * vj_compress_tcp - Attempt to do Van Jacobsen header compression on a\r
+ * packet.  This assumes that nb and comp are not null and that the first\r
+ * buffer of the chain contains a valid IP header.\r
+ * Return the VJ type code indicating whether or not the packet was\r
+ * compressed.\r
+ */\r
+u_int vj_compress_tcp(\r
+       struct vjcompress *comp,\r
+       struct pbuf *pb\r
+)\r
+{\r
+       register struct ip *ip = (struct ip *)pb->payload;\r
+       register struct cstate *cs = comp->last_cs->cs_next;\r
+       register u_short hlen = getip_hl(*ip);\r
+       register struct tcphdr *oth;\r
+       register struct tcphdr *th;\r
+       register u_short deltaS, deltaA;\r
+       register u_long deltaL;\r
+       register u_int changes = 0;\r
+       u_char new_seq[16];\r
+       register u_char *cp = new_seq;\r
+\r
+       /*      \r
+        * Check that the packet is IP proto TCP.\r
+        */\r
+       if (ip->ip_p != IPPROTO_TCP)\r
+               return (TYPE_IP);\r
+               \r
+       /*\r
+        * Bail if this is an IP fragment or if the TCP packet isn't\r
+        * `compressible' (i.e., ACK isn't set or some other control bit is\r
+        * set).  \r
+        */\r
+       if ((ip->ip_off & htons(0x3fff)) || pb->tot_len < 40)\r
+               return (TYPE_IP);\r
+       th = (struct tcphdr *)&((long *)ip)[hlen];\r
+       if ((th->th_flags & (TCP_SYN|TCP_FIN|TCP_RST|TCP_ACK)) != TCP_ACK)\r
+               return (TYPE_IP);\r
+               \r
+       /*\r
+        * Packet is compressible -- we're going to send either a\r
+        * COMPRESSED_TCP or UNCOMPRESSED_TCP packet.  Either way we need\r
+        * to locate (or create) the connection state.  Special case the\r
+        * most recently used connection since it's most likely to be used\r
+        * again & we don't have to do any reordering if it's used.\r
+        */\r
+       INCR(vjs_packets);\r
+       if (ip->ip_src.s_addr != cs->cs_ip.ip_src.s_addr \r
+                       || ip->ip_dst.s_addr != cs->cs_ip.ip_dst.s_addr \r
+                       || *(long *)th != ((long *)&cs->cs_ip)[getip_hl(cs->cs_ip)]) {\r
+               /*\r
+                * Wasn't the first -- search for it.\r
+                *\r
+                * States are kept in a circularly linked list with\r
+                * last_cs pointing to the end of the list.  The\r
+                * list is kept in lru order by moving a state to the\r
+                * head of the list whenever it is referenced.  Since\r
+                * the list is short and, empirically, the connection\r
+                * we want is almost always near the front, we locate\r
+                * states via linear search.  If we don't find a state\r
+                * for the datagram, the oldest state is (re-)used.\r
+                */\r
+               register struct cstate *lcs;\r
+               register struct cstate *lastcs = comp->last_cs;\r
+               \r
+               do {\r
+                       lcs = cs; cs = cs->cs_next;\r
+                       INCR(vjs_searches);\r
+                       if (ip->ip_src.s_addr == cs->cs_ip.ip_src.s_addr\r
+                                       && ip->ip_dst.s_addr == cs->cs_ip.ip_dst.s_addr\r
+                                       && *(long *)th == ((long *)&cs->cs_ip)[getip_hl(cs->cs_ip)])\r
+                               goto found;\r
+               } while (cs != lastcs);\r
+               \r
+               /*\r
+                * Didn't find it -- re-use oldest cstate.  Send an\r
+                * uncompressed packet that tells the other side what\r
+                * connection number we're using for this conversation.\r
+                * Note that since the state list is circular, the oldest\r
+                * state points to the newest and we only need to set\r
+                * last_cs to update the lru linkage.\r
+                */\r
+               INCR(vjs_misses);\r
+               comp->last_cs = lcs;\r
+               hlen += getth_off(*th);\r
+               hlen <<= 2;\r
+               /* Check that the IP/TCP headers are contained in the first buffer. */\r
+               if (hlen > pb->len)\r
+                       return (TYPE_IP);\r
+               goto uncompressed;\r
+               \r
+               found:\r
+               /*\r
+                * Found it -- move to the front on the connection list.\r
+                */\r
+               if (cs == lastcs)\r
+                       comp->last_cs = lcs;\r
+               else {\r
+                       lcs->cs_next = cs->cs_next;\r
+                       cs->cs_next = lastcs->cs_next;\r
+                       lastcs->cs_next = cs;\r
+               }\r
+       }\r
+       \r
+       oth = (struct tcphdr *)&((long *)&cs->cs_ip)[hlen];\r
+       deltaS = hlen;\r
+       hlen += getth_off(*th);\r
+       hlen <<= 2;\r
+       /* Check that the IP/TCP headers are contained in the first buffer. */\r
+       if (hlen > pb->len) {\r
+               PPPDEBUG((LOG_INFO, "vj_compress_tcp: header len %d spans buffers\n", \r
+                                       hlen));\r
+               return (TYPE_IP);\r
+       }\r
+       \r
+       /*\r
+        * Make sure that only what we expect to change changed. The first\r
+        * line of the `if' checks the IP protocol version, header length &\r
+        * type of service.  The 2nd line checks the "Don't fragment" bit.\r
+        * The 3rd line checks the time-to-live and protocol (the protocol\r
+        * check is unnecessary but costless).  The 4th line checks the TCP\r
+        * header length.  The 5th line checks IP options, if any.  The 6th\r
+        * line checks TCP options, if any.  If any of these things are\r
+        * different between the previous & current datagram, we send the\r
+        * current datagram `uncompressed'.\r
+        */\r
+       if (((u_short *)ip)[0] != ((u_short *)&cs->cs_ip)[0] \r
+                       || ((u_short *)ip)[3] != ((u_short *)&cs->cs_ip)[3] \r
+                       || ((u_short *)ip)[4] != ((u_short *)&cs->cs_ip)[4] \r
+                       || getth_off(*th) != getth_off(*oth) \r
+                       || (deltaS > 5 && BCMP(ip + 1, &cs->cs_ip + 1, (deltaS - 5) << 2)) \r
+                       || (getth_off(*th) > 5 && BCMP(th + 1, oth + 1, (getth_off(*th) - 5) << 2)))\r
+               goto uncompressed;\r
+       \r
+       /*\r
+        * Figure out which of the changing fields changed.  The\r
+        * receiver expects changes in the order: urgent, window,\r
+        * ack, seq (the order minimizes the number of temporaries\r
+        * needed in this section of code).\r
+        */\r
+       if (th->th_flags & TCP_URG) {\r
+               deltaS = ntohs(th->th_urp);\r
+               ENCODEZ(deltaS);\r
+               changes |= NEW_U;\r
+       } else if (th->th_urp != oth->th_urp)\r
+               /* argh! URG not set but urp changed -- a sensible\r
+                * implementation should never do this but RFC793\r
+                * doesn't prohibit the change so we have to deal\r
+                * with it. */\r
+               goto uncompressed;\r
+       \r
+       if ((deltaS = (u_short)(ntohs(th->th_win) - ntohs(oth->th_win))) != 0) {\r
+               ENCODE(deltaS);\r
+               changes |= NEW_W;\r
+       }\r
+       \r
+       if ((deltaL = ntohl(th->th_ack) - ntohl(oth->th_ack)) != 0) {\r
+               if (deltaL > 0xffff)\r
+                       goto uncompressed;\r
+               deltaA = (u_short)deltaL;\r
+               ENCODE(deltaA);\r
+               changes |= NEW_A;\r
+       }\r
+       \r
+       if ((deltaL = ntohl(th->th_seq) - ntohl(oth->th_seq)) != 0) {\r
+               if (deltaL > 0xffff)\r
+                       goto uncompressed;\r
+               deltaS = (u_short)deltaL;\r
+               ENCODE(deltaS);\r
+               changes |= NEW_S;\r
+       }\r
+       \r
+       switch(changes) {\r
+       \r
+       case 0:\r
+               /*\r
+                * Nothing changed. If this packet contains data and the\r
+                * last one didn't, this is probably a data packet following\r
+                * an ack (normal on an interactive connection) and we send\r
+                * it compressed.  Otherwise it's probably a retransmit,\r
+                * retransmitted ack or window probe.  Send it uncompressed\r
+                * in case the other side missed the compressed version.\r
+                */\r
+               if (ip->ip_len != cs->cs_ip.ip_len &&\r
+                       ntohs(cs->cs_ip.ip_len) == hlen)\r
+               break;\r
+       \r
+       /* (fall through) */\r
+       \r
+       case SPECIAL_I:\r
+       case SPECIAL_D:\r
+               /*\r
+                * actual changes match one of our special case encodings --\r
+                * send packet uncompressed.\r
+                */\r
+               goto uncompressed;\r
+       \r
+       case NEW_S|NEW_A:\r
+               if (deltaS == deltaA && deltaS == ntohs(cs->cs_ip.ip_len) - hlen) {\r
+                       /* special case for echoed terminal traffic */\r
+                       changes = SPECIAL_I;\r
+                       cp = new_seq;\r
+               }\r
+               break;\r
+       \r
+       case NEW_S:\r
+               if (deltaS == ntohs(cs->cs_ip.ip_len) - hlen) {\r
+                       /* special case for data xfer */\r
+                       changes = SPECIAL_D;\r
+                       cp = new_seq;\r
+               }\r
+               break;\r
+       }\r
+       \r
+       deltaS = (u_short)(ntohs(ip->ip_id) - ntohs(cs->cs_ip.ip_id));\r
+       if (deltaS != 1) {\r
+               ENCODEZ(deltaS);\r
+               changes |= NEW_I;\r
+       }\r
+       if (th->th_flags & TCP_PSH)\r
+       changes |= TCP_PUSH_BIT;\r
+       /*\r
+        * Grab the cksum before we overwrite it below.  Then update our\r
+        * state with this packet's header.\r
+        */\r
+       deltaA = ntohs(th->th_sum);\r
+       BCOPY(ip, &cs->cs_ip, hlen);\r
+       \r
+       /*\r
+        * We want to use the original packet as our compressed packet.\r
+        * (cp - new_seq) is the number of bytes we need for compressed\r
+        * sequence numbers.  In addition we need one byte for the change\r
+        * mask, one for the connection id and two for the tcp checksum.\r
+        * So, (cp - new_seq) + 4 bytes of header are needed.  hlen is how\r
+        * many bytes of the original packet to toss so subtract the two to\r
+        * get the new packet size.\r
+        */\r
+       deltaS = (u_short)(cp - new_seq);\r
+       if (!comp->compressSlot || comp->last_xmit != cs->cs_id) {\r
+               comp->last_xmit = cs->cs_id;\r
+               hlen -= deltaS + 4;\r
+               pbuf_header(pb, -hlen);\r
+               cp = (u_char *)pb->payload;\r
+               *cp++ = changes | NEW_C;\r
+               *cp++ = cs->cs_id;\r
+       } else {\r
+               hlen -= deltaS + 3;\r
+               pbuf_header(pb, -hlen);\r
+               cp = (u_char *)pb->payload;\r
+               *cp++ = changes;\r
+       }\r
+       *cp++ = deltaA >> 8;\r
+       *cp++ = deltaA;\r
+       BCOPY(new_seq, cp, deltaS);\r
+       INCR(vjs_compressed);\r
+       return (TYPE_COMPRESSED_TCP);\r
+\r
+       /*\r
+        * Update connection state cs & send uncompressed packet (that is,\r
+        * a regular ip/tcp packet but with the 'conversation id' we hope\r
+        * to use on future compressed packets in the protocol field).\r
+        */\r
+uncompressed:\r
+       BCOPY(ip, &cs->cs_ip, hlen);\r
+       ip->ip_p = cs->cs_id;\r
+       comp->last_xmit = cs->cs_id;\r
+       return (TYPE_UNCOMPRESSED_TCP);\r
+}\r
+\r
+/*\r
+ * Called when we may have missed a packet.\r
+ */\r
+void vj_uncompress_err(struct vjcompress *comp)\r
+{\r
+    comp->flags |= VJF_TOSS;\r
+       INCR(vjs_errorin);\r
+}\r
+\r
+/*\r
+ * "Uncompress" a packet of type TYPE_UNCOMPRESSED_TCP.\r
+ * Return 0 on success, -1 on failure.\r
+ */\r
+int vj_uncompress_uncomp(\r
+       struct pbuf *nb,\r
+       struct vjcompress *comp\r
+)\r
+{\r
+       register u_int hlen;\r
+       register struct cstate *cs;\r
+       register struct ip *ip;\r
+       \r
+       ip = (struct ip *)nb->payload;\r
+       hlen = getip_hl(*ip) << 2;\r
+       if (ip->ip_p >= MAX_SLOTS\r
+                       || hlen + sizeof(struct tcphdr) > nb->len\r
+                       || (hlen += getth_off(*((struct tcphdr *)&((char *)ip)[hlen])) << 2)\r
+                           > nb->len\r
+                       || hlen > MAX_HDR) {\r
+               PPPDEBUG((LOG_INFO, "vj_uncompress_uncomp: bad cid=%d, hlen=%d buflen=%d\n", \r
+                                       ip->ip_p, hlen, nb->len));\r
+               comp->flags |= VJF_TOSS;\r
+               INCR(vjs_errorin);\r
+               return -1;\r
+       }\r
+       cs = &comp->rstate[comp->last_recv = ip->ip_p];\r
+       comp->flags &=~ VJF_TOSS;\r
+       ip->ip_p = IPPROTO_TCP;\r
+       BCOPY(ip, &cs->cs_ip, hlen);\r
+       cs->cs_hlen = hlen;\r
+       INCR(vjs_uncompressedin);\r
+       return 0;\r
+}\r
+\r
+/*\r
+ * Uncompress a packet of type TYPE_COMPRESSED_TCP.\r
+ * The packet is composed of a buffer chain and the first buffer\r
+ * must contain an accurate chain length.\r
+ * The first buffer must include the entire compressed TCP/IP header. \r
+ * This procedure replaces the compressed header with the uncompressed\r
+ * header and returns the length of the VJ header.\r
+ */\r
+int vj_uncompress_tcp(\r
+       struct pbuf **nb,\r
+       struct vjcompress *comp\r
+)\r
+{\r
+       u_char *cp;\r
+       struct tcphdr *th;\r
+       struct cstate *cs;\r
+       u_short *bp;\r
+       struct pbuf *n0 = *nb;\r
+       u32_t tmp;\r
+       u_int vjlen, hlen, changes;\r
+       \r
+       INCR(vjs_compressedin);\r
+       cp = (u_char *)n0->payload;\r
+       changes = *cp++;\r
+       if (changes & NEW_C) {\r
+               /* \r
+                * Make sure the state index is in range, then grab the state.\r
+                * If we have a good state index, clear the 'discard' flag. \r
+                */\r
+               if (*cp >= MAX_SLOTS) {\r
+                       PPPDEBUG((LOG_INFO, "vj_uncompress_tcp: bad cid=%d\n", *cp));\r
+                       goto bad;\r
+               }\r
+               \r
+               comp->flags &=~ VJF_TOSS;\r
+               comp->last_recv = *cp++;\r
+       } else {\r
+               /* \r
+                * this packet has an implicit state index.  If we've\r
+                * had a line error since the last time we got an\r
+                * explicit state index, we have to toss the packet. \r
+                */\r
+               if (comp->flags & VJF_TOSS) {\r
+                       PPPDEBUG((LOG_INFO, "vj_uncompress_tcp: tossing\n"));\r
+                       INCR(vjs_tossed);\r
+                       return (-1);\r
+               }\r
+       }\r
+       cs = &comp->rstate[comp->last_recv];\r
+       hlen = getip_hl(cs->cs_ip) << 2;\r
+       th = (struct tcphdr *)&((u_char *)&cs->cs_ip)[hlen];\r
+       th->th_sum = htons((*cp << 8) | cp[1]);\r
+       cp += 2;\r
+       if (changes & TCP_PUSH_BIT)\r
+               th->th_flags |= TCP_PSH;\r
+       else\r
+               th->th_flags &=~ TCP_PSH;\r
+       \r
+       switch (changes & SPECIALS_MASK) {\r
+       case SPECIAL_I:\r
+               {\r
+                       register u32_t i = ntohs(cs->cs_ip.ip_len) - cs->cs_hlen;\r
+                       /* some compilers can't nest inline assembler.. */\r
+                       tmp = ntohl(th->th_ack) + i;\r
+                       th->th_ack = htonl(tmp);\r
+                       tmp = ntohl(th->th_seq) + i;\r
+                       th->th_seq = htonl(tmp);\r
+               }\r
+               break;\r
+       \r
+       case SPECIAL_D:\r
+               /* some compilers can't nest inline assembler.. */\r
+               tmp = ntohl(th->th_seq) + ntohs(cs->cs_ip.ip_len) - cs->cs_hlen;\r
+               th->th_seq = htonl(tmp);\r
+               break;\r
+       \r
+       default:\r
+               if (changes & NEW_U) {\r
+                       th->th_flags |= TCP_URG;\r
+                       DECODEU(th->th_urp);\r
+               } else\r
+                       th->th_flags &=~ TCP_URG;\r
+               if (changes & NEW_W)\r
+                       DECODES(th->th_win);\r
+               if (changes & NEW_A)\r
+                       DECODEL(th->th_ack);\r
+               if (changes & NEW_S)\r
+                       DECODEL(th->th_seq);\r
+               break;\r
+       }\r
+       if (changes & NEW_I) {\r
+               DECODES(cs->cs_ip.ip_id);\r
+       } else {\r
+               cs->cs_ip.ip_id = ntohs(cs->cs_ip.ip_id) + 1;\r
+               cs->cs_ip.ip_id = htons(cs->cs_ip.ip_id);\r
+       }\r
+       \r
+       /*\r
+        * At this point, cp points to the first byte of data in the\r
+        * packet.  Fill in the IP total length and update the IP\r
+        * header checksum.\r
+        */\r
+       vjlen = (u_short)(cp - (u_char*)n0->payload);\r
+       if (n0->len < vjlen) {\r
+               /* \r
+                * We must have dropped some characters (crc should detect\r
+                * this but the old slip framing won't) \r
+                */\r
+               PPPDEBUG((LOG_INFO, "vj_uncompress_tcp: head buffer %d too short %d\n", \r
+                                 n0->len, vjlen));\r
+               goto bad;\r
+       }\r
+       \r
+#if BYTE_ORDER == LITTLE_ENDIAN\r
+       tmp = n0->tot_len - vjlen + cs->cs_hlen;\r
+       cs->cs_ip.ip_len = htons(tmp);\r
+#else\r
+       cs->cs_ip.ip_len = htons(n0->tot_len - vjlen + cs->cs_hlen);\r
+#endif\r
+       \r
+       /* recompute the ip header checksum */\r
+       bp = (u_short *) &cs->cs_ip;\r
+       cs->cs_ip.ip_sum = 0;\r
+       for (tmp = 0; hlen > 0; hlen -= 2)\r
+               tmp += *bp++;\r
+       tmp = (tmp & 0xffff) + (tmp >> 16);\r
+       tmp = (tmp & 0xffff) + (tmp >> 16);\r
+       cs->cs_ip.ip_sum = (u_short)(~tmp);\r
+       \r
+       /* Remove the compressed header and prepend the uncompressed header. */\r
+       pbuf_header(n0, -vjlen);\r
+\r
+       if(MEM_ALIGN(n0->payload) != n0->payload) {\r
+               struct pbuf *np, *q;\r
+               u8_t *bufptr;\r
+\r
+               np = pbuf_alloc(PBUF_RAW, n0->len + cs->cs_hlen, PBUF_POOL);\r
+               if(!np) {\r
+                       PPPDEBUG((LOG_WARNING, "vj_uncompress_tcp: realign failed\n"));\r
+                       *nb = NULL;\r
+                       goto bad;\r
+               }\r
+\r
+               pbuf_header(np, -cs->cs_hlen);\r
+\r
+               bufptr = n0->payload;\r
+               for(q = np; q != NULL; q = q->next) {\r
+                       memcpy(q->payload, bufptr, q->len);\r
+                       bufptr += q->len;\r
+               }\r
+\r
+               if(n0->next) {\r
+                       pbuf_chain(np, n0->next);\r
+                       pbuf_dechain(n0);\r
+               }\r
+               pbuf_free(n0);\r
+               n0 = np;\r
+       }\r
+\r
+       if(pbuf_header(n0, cs->cs_hlen)) {\r
+               struct pbuf *np;\r
+\r
+               LWIP_ASSERT("vj_uncompress_tcp: cs->cs_hlen <= PBUF_POOL_BUFSIZE", cs->cs_hlen <= PBUF_POOL_BUFSIZE);\r
+               np = pbuf_alloc(PBUF_RAW, cs->cs_hlen, PBUF_POOL);\r
+               if(!np) {\r
+                       PPPDEBUG((LOG_WARNING, "vj_uncompress_tcp: prepend failed\n"));\r
+                       *nb = NULL;\r
+                       goto bad;\r
+               }\r
+               pbuf_cat(np, n0);\r
+               n0 = np;\r
+       }\r
+       LWIP_ASSERT("n0->len >= cs->cs_hlen", n0->len >= cs->cs_hlen);\r
+       memcpy(n0->payload, &cs->cs_ip, cs->cs_hlen);\r
+\r
+       *nb = n0;\r
+\r
+       return vjlen;\r
+       \r
+bad:\r
+       comp->flags |= VJF_TOSS;\r
+       INCR(vjs_errorin);\r
+       return (-1);\r
+}\r
+\r
+#endif\r
+\r
+\r
index bcad00ea4b397bc975134e2c86f98e71c08b132f..3765aa6aa3184db70cf05d4da6371f40f727453e 100644 (file)
-/*
- * Definitions for tcp compression routines.
- *
- * $Id: vj.h,v 1.2 2006/08/29 18:53:47 wolti Exp $
- *
- * Copyright (c) 1989 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley.  The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- *     Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989:
- *     - Initial distribution.
- */
-
-#ifndef VJ_H
-#define VJ_H
-
-#include "vjbsdhdr.h"
-
-#define MAX_SLOTS      16                      /* must be > 2 and < 256 */
-#define MAX_HDR                128
-
-/*
- * Compressed packet format:
- *
- * The first octet contains the packet type (top 3 bits), TCP
- * 'push' bit, and flags that indicate which of the 4 TCP sequence
- * numbers have changed (bottom 5 bits).  The next octet is a
- * conversation number that associates a saved IP/TCP header with
- * the compressed packet.  The next two octets are the TCP checksum
- * from the original datagram.  The next 0 to 15 octets are
- * sequence number changes, one change per bit set in the header
- * (there may be no changes and there are two special cases where
- * the receiver implicitly knows what changed -- see below).
- * 
- * There are 5 numbers which can change (they are always inserted
- * in the following order): TCP urgent pointer, window,
- * acknowlegement, sequence number and IP ID.  (The urgent pointer
- * is different from the others in that its value is sent, not the
- * change in value.)  Since typical use of SLIP links is biased
- * toward small packets (see comments on MTU/MSS below), changes
- * use a variable length coding with one octet for numbers in the
- * range 1 - 255 and 3 octets (0, MSB, LSB) for numbers in the
- * range 256 - 65535 or 0.  (If the change in sequence number or
- * ack is more than 65535, an uncompressed packet is sent.)
- */
-
-/*
- * Packet types (must not conflict with IP protocol version)
- *
- * The top nibble of the first octet is the packet type.  There are
- * three possible types: IP (not proto TCP or tcp with one of the
- * control flags set); uncompressed TCP (a normal IP/TCP packet but
- * with the 8-bit protocol field replaced by an 8-bit connection id --
- * this type of packet syncs the sender & receiver); and compressed
- * TCP (described above).
- *
- * LSB of 4-bit field is TCP "PUSH" bit (a worthless anachronism) and
- * is logically part of the 4-bit "changes" field that follows.  Top
- * three bits are actual packet type.  For backward compatibility
- * and in the interest of conserving bits, numbers are chosen so the
- * IP protocol version number (4) which normally appears in this nibble
- * means "IP packet".
- */
-
-/* packet types */
-#define TYPE_IP 0x40
-#define TYPE_UNCOMPRESSED_TCP 0x70
-#define TYPE_COMPRESSED_TCP 0x80
-#define TYPE_ERROR 0x00
-
-/* Bits in first octet of compressed packet */
-#define NEW_C  0x40    /* flag bits for what changed in a packet */
-#define NEW_I  0x20
-#define NEW_S  0x08
-#define NEW_A  0x04
-#define NEW_W  0x02
-#define NEW_U  0x01
-
-/* reserved, special-case values of above */
-#define SPECIAL_I (NEW_S|NEW_W|NEW_U)          /* echoed interactive traffic */
-#define SPECIAL_D (NEW_S|NEW_A|NEW_W|NEW_U)    /* unidirectional data */
-#define SPECIALS_MASK (NEW_S|NEW_A|NEW_W|NEW_U)
-
-#define TCP_PUSH_BIT 0x10
-
-
-/*
- * "state" data for each active tcp conversation on the wire.  This is
- * basically a copy of the entire IP/TCP header from the last packet
- * we saw from the conversation together with a small identifier
- * the transmit & receive ends of the line use to locate saved header.
- */
-struct cstate {
-    struct cstate *cs_next;    /* next most recently used state (xmit only) */
-    u_short cs_hlen;           /* size of hdr (receive only) */
-    u_char cs_id;                      /* connection # associated with this state */
-    u_char cs_filler;
-    union {
-               char csu_hdr[MAX_HDR];
-               struct ip csu_ip;       /* ip/tcp hdr from most recent packet */
-    } vjcs_u;
-};
-#define cs_ip vjcs_u.csu_ip
-#define cs_hdr vjcs_u.csu_hdr
-
-
-struct vjstat {
-    unsigned long vjs_packets;                 /* outbound packets */
-    unsigned long vjs_compressed;              /* outbound compressed packets */
-    unsigned long vjs_searches;                        /* searches for connection state */
-    unsigned long vjs_misses;                  /* times couldn't find conn. state */
-    unsigned long vjs_uncompressedin;  /* inbound uncompressed packets */
-    unsigned long vjs_compressedin;            /* inbound compressed packets */
-    unsigned long vjs_errorin;                 /* inbound unknown type packets */
-    unsigned long vjs_tossed;                  /* inbound packets tossed because of error */
-};
-
-/*
- * all the state data for one serial line (we need one of these per line).
- */
-struct vjcompress {
-    struct cstate *last_cs;    /* most recently used tstate */
-    u_char last_recv;          /* last rcvd conn. id */
-    u_char last_xmit;          /* last sent conn. id */
-    u_short flags;
-    u_char maxSlotIndex;
-    u_char compressSlot;       /* Flag indicating OK to compress slot ID. */
-#if LINK_STATS
-    struct vjstat stats;
-#endif
-    struct cstate tstate[MAX_SLOTS];   /* xmit connection states */
-    struct cstate rstate[MAX_SLOTS];   /* receive connection states */
-};
-
-/* flag values */
-#define VJF_TOSS 1U            /* tossing rcvd frames because of input err */
-
-extern void  vj_compress_init (struct vjcompress *comp);
-extern u_int vj_compress_tcp (struct vjcompress *comp, struct pbuf *pb);
-extern void  vj_uncompress_err (struct vjcompress *comp);
-extern int vj_uncompress_uncomp(struct pbuf *nb, struct vjcompress *comp);
-extern int vj_uncompress_tcp(struct pbuf **nb, struct vjcompress *comp);
-
-#endif /* VJ_H */
+/*\r
+ * Definitions for tcp compression routines.\r
+ *\r
+ * $Id: vj.h,v 1.2 2006/08/29 18:53:47 wolti Exp $\r
+ *\r
+ * Copyright (c) 1989 Regents of the University of California.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms are permitted\r
+ * provided that the above copyright notice and this paragraph are\r
+ * duplicated in all such forms and that any documentation,\r
+ * advertising materials, and other materials related to such\r
+ * distribution and use acknowledge that the software was developed\r
+ * by the University of California, Berkeley.  The name of the\r
+ * University may not be used to endorse or promote products derived\r
+ * from this software without specific prior written permission.\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR\r
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r
+ *\r
+ *     Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989:\r
+ *     - Initial distribution.\r
+ */\r
+\r
+#ifndef VJ_H\r
+#define VJ_H\r
+\r
+#include "vjbsdhdr.h"\r
+\r
+#define MAX_SLOTS      16                      /* must be > 2 and < 256 */\r
+#define MAX_HDR                128\r
+\r
+/*\r
+ * Compressed packet format:\r
+ *\r
+ * The first octet contains the packet type (top 3 bits), TCP\r
+ * 'push' bit, and flags that indicate which of the 4 TCP sequence\r
+ * numbers have changed (bottom 5 bits).  The next octet is a\r
+ * conversation number that associates a saved IP/TCP header with\r
+ * the compressed packet.  The next two octets are the TCP checksum\r
+ * from the original datagram.  The next 0 to 15 octets are\r
+ * sequence number changes, one change per bit set in the header\r
+ * (there may be no changes and there are two special cases where\r
+ * the receiver implicitly knows what changed -- see below).\r
+ * \r
+ * There are 5 numbers which can change (they are always inserted\r
+ * in the following order): TCP urgent pointer, window,\r
+ * acknowlegement, sequence number and IP ID.  (The urgent pointer\r
+ * is different from the others in that its value is sent, not the\r
+ * change in value.)  Since typical use of SLIP links is biased\r
+ * toward small packets (see comments on MTU/MSS below), changes\r
+ * use a variable length coding with one octet for numbers in the\r
+ * range 1 - 255 and 3 octets (0, MSB, LSB) for numbers in the\r
+ * range 256 - 65535 or 0.  (If the change in sequence number or\r
+ * ack is more than 65535, an uncompressed packet is sent.)\r
+ */\r
+\r
+/*\r
+ * Packet types (must not conflict with IP protocol version)\r
+ *\r
+ * The top nibble of the first octet is the packet type.  There are\r
+ * three possible types: IP (not proto TCP or tcp with one of the\r
+ * control flags set); uncompressed TCP (a normal IP/TCP packet but\r
+ * with the 8-bit protocol field replaced by an 8-bit connection id --\r
+ * this type of packet syncs the sender & receiver); and compressed\r
+ * TCP (described above).\r
+ *\r
+ * LSB of 4-bit field is TCP "PUSH" bit (a worthless anachronism) and\r
+ * is logically part of the 4-bit "changes" field that follows.  Top\r
+ * three bits are actual packet type.  For backward compatibility\r
+ * and in the interest of conserving bits, numbers are chosen so the\r
+ * IP protocol version number (4) which normally appears in this nibble\r
+ * means "IP packet".\r
+ */\r
+\r
+/* packet types */\r
+#define TYPE_IP 0x40\r
+#define TYPE_UNCOMPRESSED_TCP 0x70\r
+#define TYPE_COMPRESSED_TCP 0x80\r
+#define TYPE_ERROR 0x00\r
+\r
+/* Bits in first octet of compressed packet */\r
+#define NEW_C  0x40    /* flag bits for what changed in a packet */\r
+#define NEW_I  0x20\r
+#define NEW_S  0x08\r
+#define NEW_A  0x04\r
+#define NEW_W  0x02\r
+#define NEW_U  0x01\r
+\r
+/* reserved, special-case values of above */\r
+#define SPECIAL_I (NEW_S|NEW_W|NEW_U)          /* echoed interactive traffic */\r
+#define SPECIAL_D (NEW_S|NEW_A|NEW_W|NEW_U)    /* unidirectional data */\r
+#define SPECIALS_MASK (NEW_S|NEW_A|NEW_W|NEW_U)\r
+\r
+#define TCP_PUSH_BIT 0x10\r
+\r
+\r
+/*\r
+ * "state" data for each active tcp conversation on the wire.  This is\r
+ * basically a copy of the entire IP/TCP header from the last packet\r
+ * we saw from the conversation together with a small identifier\r
+ * the transmit & receive ends of the line use to locate saved header.\r
+ */\r
+struct cstate {\r
+    struct cstate *cs_next;    /* next most recently used state (xmit only) */\r
+    u_short cs_hlen;           /* size of hdr (receive only) */\r
+    u_char cs_id;                      /* connection # associated with this state */\r
+    u_char cs_filler;\r
+    union {\r
+               char csu_hdr[MAX_HDR];\r
+               struct ip csu_ip;       /* ip/tcp hdr from most recent packet */\r
+    } vjcs_u;\r
+};\r
+#define cs_ip vjcs_u.csu_ip\r
+#define cs_hdr vjcs_u.csu_hdr\r
+\r
+\r
+struct vjstat {\r
+    unsigned long vjs_packets;                 /* outbound packets */\r
+    unsigned long vjs_compressed;              /* outbound compressed packets */\r
+    unsigned long vjs_searches;                        /* searches for connection state */\r
+    unsigned long vjs_misses;                  /* times couldn't find conn. state */\r
+    unsigned long vjs_uncompressedin;  /* inbound uncompressed packets */\r
+    unsigned long vjs_compressedin;            /* inbound compressed packets */\r
+    unsigned long vjs_errorin;                 /* inbound unknown type packets */\r
+    unsigned long vjs_tossed;                  /* inbound packets tossed because of error */\r
+};\r
+\r
+/*\r
+ * all the state data for one serial line (we need one of these per line).\r
+ */\r
+struct vjcompress {\r
+    struct cstate *last_cs;    /* most recently used tstate */\r
+    u_char last_recv;          /* last rcvd conn. id */\r
+    u_char last_xmit;          /* last sent conn. id */\r
+    u_short flags;\r
+    u_char maxSlotIndex;\r
+    u_char compressSlot;       /* Flag indicating OK to compress slot ID. */\r
+#if LINK_STATS\r
+    struct vjstat stats;\r
+#endif\r
+    struct cstate tstate[MAX_SLOTS];   /* xmit connection states */\r
+    struct cstate rstate[MAX_SLOTS];   /* receive connection states */\r
+};\r
+\r
+/* flag values */\r
+#define VJF_TOSS 1U            /* tossing rcvd frames because of input err */\r
+\r
+extern void  vj_compress_init (struct vjcompress *comp);\r
+extern u_int vj_compress_tcp (struct vjcompress *comp, struct pbuf *pb);\r
+extern void  vj_uncompress_err (struct vjcompress *comp);\r
+extern int vj_uncompress_uncomp(struct pbuf *nb, struct vjcompress *comp);\r
+extern int vj_uncompress_tcp(struct pbuf **nb, struct vjcompress *comp);\r
+\r
+#endif /* VJ_H */\r
index a089352ade270e0f6b7d7f427696b7fd97193eb3..a7d180c16c80de16b992d13a8037ee210178557c 100644 (file)
@@ -1,76 +1,76 @@
-#ifndef VJBSDHDR_H
-#define VJBSDHDR_H
-
-#include "lwip/tcp.h"
-
-
-/*
- * Structure of an internet header, naked of options.
- *
- * We declare ip_len and ip_off to be short, rather than u_short
- * pragmatically since otherwise unsigned comparisons can result
- * against negative integers quite easily, and fail in subtle ways.
- */
-PACK_STRUCT_BEGIN
-struct ip
-{
-#if defined(NO_CHAR_BITFIELDS)
-       u_char ip_hl_v; /* bug in GCC for mips means the bitfield stuff will sometimes break - so we use a char for both and get round it with macro's instead... */
-#else
-#if BYTE_ORDER == LITTLE_ENDIAN
-       unsigned ip_hl:4,                               /* header length */
-               ip_v:4;                                         /* version */
-#elif BYTE_ORDER == BIG_ENDIAN 
-       unsigned ip_v:4,                                        /* version */
-               ip_hl:4;                                        /* header length */
-#else
-       COMPLAIN - NO BYTE ORDER SELECTED!
-#endif
-#endif
-       u_char  ip_tos;                                 /* type of service */
-       u_short ip_len;                                 /* total length */
-       u_short ip_id;                                  /* identification */
-       u_short ip_off;                                 /* fragment offset field */
-#define        IP_DF 0x4000                            /* dont fragment flag */
-#define        IP_MF 0x2000                            /* more fragments flag */
-#define        IP_OFFMASK 0x1fff                       /* mask for fragmenting bits */
-       u_char  ip_ttl;                                 /* time to live */
-       u_char  ip_p;                                   /* protocol */
-       u_short ip_sum;                                 /* checksum */
-       struct  in_addr ip_src,ip_dst;  /* source and dest address */
-};
-PACK_STRUCT_END
-
-typedef u32_t tcp_seq;
-
-/*
- * TCP header.
- * Per RFC 793, September, 1981.
- */
-PACK_STRUCT_BEGIN
-struct tcphdr  
-{
-       u_short th_sport;               /* source port */
-       u_short th_dport;               /* destination port */
-       tcp_seq th_seq;                 /* sequence number */
-       tcp_seq th_ack;                 /* acknowledgement number */
-#if defined(NO_CHAR_BITFIELDS)
-       u_char th_x2_off;
-#else
-#if BYTE_ORDER == LITTLE_ENDIAN
-       unsigned        th_x2:4,                /* (unused) */
-                       th_off:4;               /* data offset */
-#endif
-#if BYTE_ORDER == BIG_ENDIAN 
-       unsigned        th_off:4,               /* data offset */
-                       th_x2:4;                /* (unused) */
-#endif
-#endif
-       u_char  th_flags;
-       u_short th_win;                 /* window */
-       u_short th_sum;                 /* checksum */
-       u_short th_urp;                 /* urgent pointer */
-};
-PACK_STRUCT_END
-
-#endif /* VJBSDHDR_H */
+#ifndef VJBSDHDR_H\r
+#define VJBSDHDR_H\r
+\r
+#include "lwip/tcp.h"\r
+\r
+\r
+/*\r
+ * Structure of an internet header, naked of options.\r
+ *\r
+ * We declare ip_len and ip_off to be short, rather than u_short\r
+ * pragmatically since otherwise unsigned comparisons can result\r
+ * against negative integers quite easily, and fail in subtle ways.\r
+ */\r
+PACK_STRUCT_BEGIN\r
+struct ip\r
+{\r
+#if defined(NO_CHAR_BITFIELDS)\r
+       u_char ip_hl_v; /* bug in GCC for mips means the bitfield stuff will sometimes break - so we use a char for both and get round it with macro's instead... */\r
+#else\r
+#if BYTE_ORDER == LITTLE_ENDIAN\r
+       unsigned ip_hl:4,                               /* header length */\r
+               ip_v:4;                                         /* version */\r
+#elif BYTE_ORDER == BIG_ENDIAN \r
+       unsigned ip_v:4,                                        /* version */\r
+               ip_hl:4;                                        /* header length */\r
+#else\r
+       COMPLAIN - NO BYTE ORDER SELECTED!\r
+#endif\r
+#endif\r
+       u_char  ip_tos;                                 /* type of service */\r
+       u_short ip_len;                                 /* total length */\r
+       u_short ip_id;                                  /* identification */\r
+       u_short ip_off;                                 /* fragment offset field */\r
+#define        IP_DF 0x4000                            /* dont fragment flag */\r
+#define        IP_MF 0x2000                            /* more fragments flag */\r
+#define        IP_OFFMASK 0x1fff                       /* mask for fragmenting bits */\r
+       u_char  ip_ttl;                                 /* time to live */\r
+       u_char  ip_p;                                   /* protocol */\r
+       u_short ip_sum;                                 /* checksum */\r
+       struct  in_addr ip_src,ip_dst;  /* source and dest address */\r
+};\r
+PACK_STRUCT_END\r
+\r
+typedef u32_t tcp_seq;\r
+\r
+/*\r
+ * TCP header.\r
+ * Per RFC 793, September, 1981.\r
+ */\r
+PACK_STRUCT_BEGIN\r
+struct tcphdr  \r
+{\r
+       u_short th_sport;               /* source port */\r
+       u_short th_dport;               /* destination port */\r
+       tcp_seq th_seq;                 /* sequence number */\r
+       tcp_seq th_ack;                 /* acknowledgement number */\r
+#if defined(NO_CHAR_BITFIELDS)\r
+       u_char th_x2_off;\r
+#else\r
+#if BYTE_ORDER == LITTLE_ENDIAN\r
+       unsigned        th_x2:4,                /* (unused) */\r
+                       th_off:4;               /* data offset */\r
+#endif\r
+#if BYTE_ORDER == BIG_ENDIAN \r
+       unsigned        th_off:4,               /* data offset */\r
+                       th_x2:4;                /* (unused) */\r
+#endif\r
+#endif\r
+       u_char  th_flags;\r
+       u_short th_win;                 /* window */\r
+       u_short th_sum;                 /* checksum */\r
+       u_short th_urp;                 /* urgent pointer */\r
+};\r
+PACK_STRUCT_END\r
+\r
+#endif /* VJBSDHDR_H */\r
index dd8db208cce04301151b1b7805b6dac6fe8be1b7..ba8510b0dbdcdcf8d92781ab7370d719627227e5 100644 (file)
-/*
- * 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. Neither the name of the Institute nor the names of its contributors 
- *    may be used to endorse or promote products derived from this software 
- *    without specific prior written permission. 
- *
- * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE OR CONTRIBUTORS 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 built upon the file: src/arch/rtxc/netif/sioslip.c
- *
- * Author: Magnus Ivarsson <magnus.ivarsson(at)volvo.com> 
- */
-
-/* 
- * This is an arch independent SLIP netif. The specific serial hooks must be
- * provided by another file. They are sio_open, sio_recv and sio_send
- */
-
-#include "netif/slipif.h"
-#include "lwip/opt.h"
-#include "lwip/def.h"
-#include "lwip/pbuf.h"
-#include "lwip/sys.h"
-#include "lwip/stats.h"
-#include "lwip/sio.h"
-
-#define SLIP_END     0300
-#define SLIP_ESC     0333
-#define SLIP_ESC_END 0334
-#define SLIP_ESC_ESC 0335
-
-#define MAX_SIZE     1500
-
-/**
- * Send a pbuf doing the necessary SLIP encapsulation
- *
- * Uses the serial layer's sio_send() 
- */
-err_t
-slipif_output(struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr)
-{
-  struct pbuf *q;
-  u16_t i;
-  u8_t c;
-
-  /* Send pbuf out on the serial I/O device. */
-  sio_send(SLIP_END, netif->state);
-
-  for (q = p; q != NULL; q = q->next) {
-    for (i = 0; i < q->len; i++) {
-      c = ((u8_t *)q->payload)[i];
-      switch (c) {
-      case SLIP_END:
-        sio_send(SLIP_ESC, netif->state);
-        sio_send(SLIP_ESC_END, netif->state);
-        break;
-      case SLIP_ESC:
-        sio_send(SLIP_ESC, netif->state);
-        sio_send(SLIP_ESC_ESC, netif->state);
-        break;
-      default:
-        sio_send(c, netif->state);
-        break;
-      }
-    }
-  }
-  sio_send(SLIP_END, netif->state);
-  return 0;
-}
-
-/**
- * Handle the incoming SLIP stream character by character
- *
- * Poll the serial layer by calling sio_recv()
- * 
- * @return The IP packet when SLIP_END is received 
- */
-static struct pbuf *
-slipif_input(struct netif *netif)
-{
-  u8_t c;
-  struct pbuf *p, *q;
-  u16_t recved;
-  u16_t i;
-
-  q = p = NULL;
-  recved = i = 0;
-  c = 0;
-
-  while (1) {
-    c = sio_recv(netif->state);
-    switch (c) {
-    case SLIP_END:
-      if (recved > 0) {
-        /* Received whole packet. */
-        pbuf_realloc(q, recved);
-        
-        LINK_STATS_INC(link.recv);
-        
-        LWIP_DEBUGF(SLIP_DEBUG, ("slipif: Got packet\n"));
-        return q;
-      }
-      break;
-
-    case SLIP_ESC:
-      c = sio_recv(netif->state);
-      switch (c) {
-      case SLIP_ESC_END:
-        c = SLIP_END;
-        break;
-      case SLIP_ESC_ESC:
-        c = SLIP_ESC;
-        break;
-      }
-      /* FALLTHROUGH */
-
-    default:
-      if (p == NULL) {
-        LWIP_DEBUGF(SLIP_DEBUG, ("slipif_input: alloc\n"));
-        p = pbuf_alloc(PBUF_LINK, PBUF_POOL_BUFSIZE, PBUF_POOL);
-
-        if (p == NULL) {
-          LINK_STATS_INC(link.drop);
-          LWIP_DEBUGF(SLIP_DEBUG, ("slipif_input: no new pbuf! (DROP)\n"));
-        }
-
-        if (q != NULL) {
-          pbuf_cat(q, p);
-        } else {
-          q = p;
-        }
-      }
-      if (p != NULL && recved < MAX_SIZE) {
-        ((u8_t *)p->payload)[i] = c;
-        recved++;
-        i++;
-        if (i >= p->len) {
-          i = 0;
-          if (p->next != NULL && p->next->len > 0)
-            p = p->next;
-          else
-            p = NULL;
-        }
-      }
-      break;
-    }
-
-  }
-  return NULL;
-}
-
-/**
- * The SLIP input thread.
- *
- * Feed the IP layer with incoming packets
- */
-static void
-slipif_loop(void *nf)
-{
-  struct pbuf *p;
-  struct netif *netif = (struct netif *)nf;
-
-  while (1) {
-    p = slipif_input(netif);
-    netif->input(p, netif);
-  }
-}
-
-/**
- * SLIP netif initialization
- *
- * Call the arch specific sio_open and remember
- * the opened device in the state field of the netif.
- */
-err_t
-slipif_init(struct netif *netif)
-{
-
-  LWIP_DEBUGF(SLIP_DEBUG, ("slipif_init: netif->num=%"U16_F"\n", (u16_t)netif->num));
-
-  netif->name[0] = 's';
-  netif->name[1] = 'l';
-  netif->output = slipif_output;
-  netif->mtu = 1500;
-  netif->flags = NETIF_FLAG_POINTTOPOINT;
-
-  netif->state = sio_open(netif->num);
-  if (!netif->state)
-    return ERR_IF;
-
-  sys_thread_new(slipif_loop, netif, SLIPIF_THREAD_PRIO);
-  return ERR_OK;
-}
+/*\r
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
+ * All rights reserved. \r
+ *\r
+ * Redistribution and use in source and binary forms, with or without \r
+ * modification, are permitted provided that the following conditions \r
+ * are met: \r
+ * 1. Redistributions of source code must retain the above copyright \r
+ *    notice, this list of conditions and the following disclaimer. \r
+ * 2. Redistributions in binary form must reproduce the above copyright \r
+ *    notice, this list of conditions and the following disclaimer in the \r
+ *    documentation and/or other materials provided with the distribution. \r
+ * 3. Neither the name of the Institute nor the names of its contributors \r
+ *    may be used to endorse or promote products derived from this software \r
+ *    without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND \r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE \r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE \r
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE \r
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL \r
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS \r
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) \r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT \r
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY \r
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF \r
+ * SUCH DAMAGE. \r
+ *\r
+ * This file is built upon the file: src/arch/rtxc/netif/sioslip.c\r
+ *\r
+ * Author: Magnus Ivarsson <magnus.ivarsson(at)volvo.com> \r
+ */\r
+\r
+/* \r
+ * This is an arch independent SLIP netif. The specific serial hooks must be\r
+ * provided by another file. They are sio_open, sio_recv and sio_send\r
+ */\r
+\r
+#include "netif/slipif.h"\r
+#include "lwip/opt.h"\r
+#include "lwip/def.h"\r
+#include "lwip/pbuf.h"\r
+#include "lwip/sys.h"\r
+#include "lwip/stats.h"\r
+#include "lwip/sio.h"\r
+\r
+#define SLIP_END     0300\r
+#define SLIP_ESC     0333\r
+#define SLIP_ESC_END 0334\r
+#define SLIP_ESC_ESC 0335\r
+\r
+#define MAX_SIZE     1500\r
+\r
+/**\r
+ * Send a pbuf doing the necessary SLIP encapsulation\r
+ *\r
+ * Uses the serial layer's sio_send() \r
+ */\r
+err_t\r
+slipif_output(struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr)\r
+{\r
+  struct pbuf *q;\r
+  u16_t i;\r
+  u8_t c;\r
+\r
+  /* Send pbuf out on the serial I/O device. */\r
+  sio_send(SLIP_END, netif->state);\r
+\r
+  for (q = p; q != NULL; q = q->next) {\r
+    for (i = 0; i < q->len; i++) {\r
+      c = ((u8_t *)q->payload)[i];\r
+      switch (c) {\r
+      case SLIP_END:\r
+        sio_send(SLIP_ESC, netif->state);\r
+        sio_send(SLIP_ESC_END, netif->state);\r
+        break;\r
+      case SLIP_ESC:\r
+        sio_send(SLIP_ESC, netif->state);\r
+        sio_send(SLIP_ESC_ESC, netif->state);\r
+        break;\r
+      default:\r
+        sio_send(c, netif->state);\r
+        break;\r
+      }\r
+    }\r
+  }\r
+  sio_send(SLIP_END, netif->state);\r
+  return 0;\r
+}\r
+\r
+/**\r
+ * Handle the incoming SLIP stream character by character\r
+ *\r
+ * Poll the serial layer by calling sio_recv()\r
+ * \r
+ * @return The IP packet when SLIP_END is received \r
+ */\r
+static struct pbuf *\r
+slipif_input(struct netif *netif)\r
+{\r
+  u8_t c;\r
+  struct pbuf *p, *q;\r
+  u16_t recved;\r
+  u16_t i;\r
+\r
+  q = p = NULL;\r
+  recved = i = 0;\r
+  c = 0;\r
+\r
+  while (1) {\r
+    c = sio_recv(netif->state);\r
+    switch (c) {\r
+    case SLIP_END:\r
+      if (recved > 0) {\r
+        /* Received whole packet. */\r
+        pbuf_realloc(q, recved);\r
+        \r
+        LINK_STATS_INC(link.recv);\r
+        \r
+        LWIP_DEBUGF(SLIP_DEBUG, ("slipif: Got packet\n"));\r
+        return q;\r
+      }\r
+      break;\r
+\r
+    case SLIP_ESC:\r
+      c = sio_recv(netif->state);\r
+      switch (c) {\r
+      case SLIP_ESC_END:\r
+        c = SLIP_END;\r
+        break;\r
+      case SLIP_ESC_ESC:\r
+        c = SLIP_ESC;\r
+        break;\r
+      }\r
+      /* FALLTHROUGH */\r
+\r
+    default:\r
+      if (p == NULL) {\r
+        LWIP_DEBUGF(SLIP_DEBUG, ("slipif_input: alloc\n"));\r
+        p = pbuf_alloc(PBUF_LINK, PBUF_POOL_BUFSIZE, PBUF_POOL);\r
+\r
+        if (p == NULL) {\r
+          LINK_STATS_INC(link.drop);\r
+          LWIP_DEBUGF(SLIP_DEBUG, ("slipif_input: no new pbuf! (DROP)\n"));\r
+        }\r
+\r
+        if (q != NULL) {\r
+          pbuf_cat(q, p);\r
+        } else {\r
+          q = p;\r
+        }\r
+      }\r
+      if (p != NULL && recved < MAX_SIZE) {\r
+        ((u8_t *)p->payload)[i] = c;\r
+        recved++;\r
+        i++;\r
+        if (i >= p->len) {\r
+          i = 0;\r
+          if (p->next != NULL && p->next->len > 0)\r
+            p = p->next;\r
+          else\r
+            p = NULL;\r
+        }\r
+      }\r
+      break;\r
+    }\r
+\r
+  }\r
+  return NULL;\r
+}\r
+\r
+/**\r
+ * The SLIP input thread.\r
+ *\r
+ * Feed the IP layer with incoming packets\r
+ */\r
+static void\r
+slipif_loop(void *nf)\r
+{\r
+  struct pbuf *p;\r
+  struct netif *netif = (struct netif *)nf;\r
+\r
+  while (1) {\r
+    p = slipif_input(netif);\r
+    netif->input(p, netif);\r
+  }\r
+}\r
+\r
+/**\r
+ * SLIP netif initialization\r
+ *\r
+ * Call the arch specific sio_open and remember\r
+ * the opened device in the state field of the netif.\r
+ */\r
+err_t\r
+slipif_init(struct netif *netif)\r
+{\r
+\r
+  LWIP_DEBUGF(SLIP_DEBUG, ("slipif_init: netif->num=%"U16_F"\n", (u16_t)netif->num));\r
+\r
+  netif->name[0] = 's';\r
+  netif->name[1] = 'l';\r
+  netif->output = slipif_output;\r
+  netif->mtu = 1500;\r
+  netif->flags = NETIF_FLAG_POINTTOPOINT;\r
+\r
+  netif->state = sio_open(netif->num);\r
+  if (!netif->state)\r
+    return ERR_IF;\r
+\r
+  sys_thread_new(slipif_loop, netif, SLIPIF_THREAD_PRIO);\r
+  return ERR_OK;\r
+}\r
index 8ebf30a5d004f86bec570ef228e701e46e0486c1..f923c982cad69457545bfdf6742c10f17208fae5 100644 (file)
-/*
-    FreeRTOS MCF5235 port - Copyright (C) 2006 Christian Walter.
-
-    This file is part of the FreeRTOS distribution.
-
-    FreeRTOS is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    FreeRTOS is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with FreeRTOS; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-    A special exception to the GPL can be applied should you wish to distribute
-    a combined work that includes FreeRTOS, without being obliged to provide
-    the source code for any proprietary components.  See the licensing section
-    of http://www.FreeRTOS.org for full details of how and when the exception
-    can be applied.
-
-    ***************************************************************************
-    See http://www.FreeRTOS.org for documentation, latest information, license
-    and contact details.  Please ensure to read the configuration and relevant
+/*\r
+    FreeRTOS MCF5235 port - Copyright (C) 2006 Christian Walter.\r
+\r
+    This file is part of the FreeRTOS distribution.\r
+\r
+    FreeRTOS is free software; you can redistribute it and/or modify\r
+    it under the terms of the GNU General Public License as published by\r
+    the Free Software Foundation; either version 2 of the License, or\r
+    (at your option) any later version.\r
+\r
+    FreeRTOS is distributed in the hope that it will be useful,\r
+    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+    GNU General Public License for more details.\r
+\r
+    You should have received a copy of the GNU General Public License\r
+    along with FreeRTOS; if not, write to the Free Software\r
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+\r
+    A special exception to the GPL can be applied should you wish to distribute\r
+    a combined work that includes FreeRTOS, without being obliged to provide\r
+    the source code for any proprietary components.  See the licensing section\r
+    of http://www.FreeRTOS.org for full details of how and when the exception\r
+    can be applied.\r
+\r
+    ***************************************************************************\r
+    See http://www.FreeRTOS.org for documentation, latest information, license\r
+    and contact details.  Please ensure to read the configuration and relevant\r
     port sections of the online documentation.\r
 \r
        Also see http://www.SafeRTOS.com for an IEC 61508 compliant version along\r
-       with commercial development and support options.
-    ***************************************************************************
-*/
-
-#include "mcf5xxx.h"
-#include "mcf523x.h"
-
-/* Function prototypes */
-void            init_main( void );
-static void     disable_interrupts( void );
-static void     disable_watchdog_timer( void );
-static void     disable_cache( void );
-static void     init_ipsbar( void );
-static void     init_basics( void );
-static void     init_clock_config( void );
-static void     init_chip_selects( void );
-static void     init_bus_config( void );
-static void     init_cache( void );
-static void     init_eport( void );
-static void     init_flexcan( void );
-static void     init_power_management( void );
-static void     init_dma_timers( void );
-static void     init_interrupt_timers( void );
-static void     init_watchdog_timers( void );
-static void     init_pin_assignments( void );
-static void     init_sdram_controller( void );
-static void     init_interrupt_controller( void );
-
-
-/*********************************************************************
-* init_main - Main entry point for initialisation code               *
-**********************************************************************/
-void
-init_main( void )
-{
-
-    /* Initialise base address of peripherals, VBR, etc */
-    init_ipsbar(  );
-    init_basics(  );
-    init_clock_config(  );
-
-    /* Disable interrupts, watchdog timer, cache */
-    disable_interrupts(  );
-    disable_watchdog_timer(  );
-    disable_cache(  );
-
-    /* Initialise individual modules */
-    init_chip_selects(  );
-    init_bus_config(  );
-    init_cache(  );
-    init_eport(  );
-    init_flexcan(  );
-    init_power_management(  );
-    init_dma_timers(  );
-    init_interrupt_timers(  );
-    init_watchdog_timers(  );
-    init_pin_assignments(  );
-    init_sdram_controller(  );
-
-    /* Initialise interrupt controller */
-    init_interrupt_controller(  );
-}
-
-/*********************************************************************
-* disable_interrupts - Disable all interrupt sources                 *
-**********************************************************************/
-static void
-disable_interrupts( void )
-{
-    vuint8         *p;
-    int             i;
-
-
-    /* Set ICR008-ICR063 to 0x0 */
-    p = ( vuint8 * ) & MCF_INTC0_ICR8;
-    for( i = 8; i <= 63; i++ )
-        *p++ = 0x0;
-
-    /* Set ICR108-ICR163 to 0x0 */
-    p = ( vuint8 * ) & MCF_INTC1_ICR8;
-    for( i = 108; i <= 163; i++ )
-        *p++ = 0x0;
-}
-
-
-/*********************************************************************
-* disable_watchdog_timer - Disable system watchdog timer             *
-**********************************************************************/
-static void
-disable_watchdog_timer( void )
-{
-
-    /* Disable Core Watchdog Timer */
-    MCF_SCM_CWCR = 0;
-}
-
-/*********************************************************************
-* disable_cache - Disable and invalidate cache                       *
-**********************************************************************/
-static void
-disable_cache( void )
-{
-    asm ( "move.l   #0x01000000, %d0" );
-    asm ( "movec    %d0, %CACR" );
-}
-
-/*********************************************************************
-* init_basics - Configuration Information & VBR                      *
-**********************************************************************/
-static void
-init_basics( void )
-{
-    int             i;
-    extern uint32   __RAMVEC[];
-    extern uint32   __ROMVEC[];
-
-    /* Transfer size not driven on SIZ[1:0] pins during external cycles
-       Processor Status (PST) and Debug Data (DDATA) functions disabled
-       Bus monitor disabled
-       Output pads configured for full strength
-     */
-    MCF_CCM_CCR = ( 0x1 << 15 ) | MCF_CCM_CCR_BME;
-
-    /* Set up RAM vectors */
-    for( i = 0; i < 256; i++ )
-
-    {
-        __RAMVEC[i] = __ROMVEC[i];
-    }
-    asm( "move.l   %0,%%d0": :"i"( __RAMVEC ) );
-    asm( "movec    %d0,%vbr" );
-}
-
-
-/*********************************************************************
-* init_clock_config - Clock Module                                   *
-**********************************************************************/
-static void
-init_clock_config( void )
-{
-    /* Clock module uses normal PLL mode with 25.0000 MHz external reference (Fref)
-       MFD = 0, RFD = 1
-       Bus clock frequency = 25.00 MHz
-       Processor clock frequency = 2 x bus clock = 50.00 MHz
-       Frequency Modulation disabled
-       Loss of clock detection disabled
-       Reset/Interrupt on loss of lock disabled
-     */
-    MCF_FMPLL_SYNCR = 0x00100000;       /* Set RFD=RFD+1 to avoid frequency overshoot */
-    while( ( MCF_FMPLL_SYNSR & 0x08 ) == 0 )    /* Wait for PLL to lock */
-        ;
-    MCF_FMPLL_SYNCR = 0x00080000;       /* Set desired RFD */
-    while( ( MCF_FMPLL_SYNSR & 0x08 ) == 0 )    /* Wait for PLL to lock */
-        ;
-}
-
-
-/*********************************************************************
-* init_ipsbar - Internal Peripheral System Base Address (IPSBAR)     *
-**********************************************************************/
-static void
-init_ipsbar( void )
-{
-    extern int  __SRAM;
-
-    /* Base address of internal peripherals (IPSBAR) = 0x40000000
-
-       Note: Processor powers up with IPS base address = 0x40000000
-       Write to IPS base + 0x00000000 to set new value
-     */
-    *( vuint32 * ) 0x40000000 = ( vuint32 ) __IPSBAR + 1;
-
-    /* Configure RAMBAR in SCM module and allow dual-ported access. */
-    MCF_SCM_RAMBAR = ( uint32 ) &__SRAM | MCF_SCM_RAMBAR_BDE;
-}
-
-/*********************************************************************
-* init_chip_selects - Chip Select Module                             *
-**********************************************************************/
-static void
-init_chip_selects( void )
-{
-    extern void __FLASH;
-    uint32 FLASH_ADDR = (uint32)&__FLASH;
-
-    /* Chip Select 0 - External Flash */
-    MCF_CS_CSAR0 = MCF_CS_CSAR_BA( FLASH_ADDR );
-    MCF_CS_CSCR0 = ( 0
-                     | MCF_CS_CSCR_IWS( 6 )
-                     | MCF_CS_CSCR_AA | MCF_CS_CSCR_PS_16 );
-    MCF_CS_CSMR0 = MCF_CS_CSMR_BAM_2M | MCF_CS_CSMR_V;
-
-    /* Chip Select 1 disabled (CSMR1[V] = 0) */
-    MCF_CS_CSAR1 = 0;
-    MCF_CS_CSMR1 = 0;
-    MCF_CS_CSCR1 = 0;
-
-    /* Chip Select 2 disabled (CSMR2[V] = 0) */
-    MCF_CS_CSAR2 = 0;
-    MCF_CS_CSMR2 = 0;
-    MCF_CS_CSCR2 = 0;
-
-    /* Chip Select 3 disabled (CSMR3[V] = 0) */
-    MCF_CS_CSAR3 = 0;
-    MCF_CS_CSMR3 = 0;
-    MCF_CS_CSCR3 = 0;
-
-    /* Chip Select 4 disabled (CSMR4[V] = 0) */
-    MCF_CS_CSAR4 = 0;
-    MCF_CS_CSMR4 = 0;
-    MCF_CS_CSCR4 = 0;
-
-    /* Chip Select 5 disabled (CSMR5[V] = 0) */
-    MCF_CS_CSAR5 = 0;
-    MCF_CS_CSMR5 = 0;
-    MCF_CS_CSCR5 = 0;
-
-    /* Chip Select 6 disabled (CSMR6[V] = 0) */
-    MCF_CS_CSAR6 = 0;
-    MCF_CS_CSMR6 = 0;
-    MCF_CS_CSCR6 = 0;
-
-    /* Chip Select 7 disabled (CSMR7[V] = 0) */
-    MCF_CS_CSAR7 = 0;
-    MCF_CS_CSMR7 = 0;
-    MCF_CS_CSCR7 = 0;
-}
-
-/*********************************************************************
-* init_bus_config - Internal Bus Arbitration                         *
-**********************************************************************/
-static void
-init_bus_config( void )
-{
-
-    /* Use round robin arbitration scheme
-       Assigned priorities (highest first):
-       Ethernet
-       DMA Controller
-       ColdFire Core
-       DMA bandwidth control disabled
-       Park on last active bus master
-     */
-    MCF_SCM_MPARK =
-        MCF_SCM_MPARK_M3_PRTY( 0x3 ) | MCF_SCM_MPARK_M2_PRTY( 0x2 ) |
-        MCF_SCM_MPARK_M1_PRTY( 0x1 );
-}
-
-/*********************************************************************
-* init_cache - Instruction/Data Cache                                *
-**********************************************************************/
-static void
-init_cache( void )
-{
-    /* Configured as split cache: 4 KByte instruction cache and 4 Kbyte data cache
-       ACR0: Don't cache accesses to 16 MB memory region at address $20000000
-       ACR1: Don't cache accesses to 1 GB memory region at address $40000000
-       CACR: Cache accesses to the rest of memory
-    */
-    asm("move.l   #0x80000000,%d0");
-    asm("movec    %d0,%CACR");
-    asm("move.l   #0x2000c040,%d0");
-    asm("movec    %d0,%ACR0");
-    asm("move.l   #0x403fc040,%d0");
-    asm("movec    %d0,%ACR1");
-
-    /* Instruction/Data cache disabled. */
-    //asm( "move.l   #0x00000000, %d0" );
-    //asm( "movec    %d0,%cacr" );
-}
-
-/*********************************************************************
-* init_eport - Edge Port Module (EPORT)                              *
-**********************************************************************/
-static void
-init_eport( void )
-{
-
-    /* Pins 1-7 configured as GPIO inputs */
-    MCF_EPORT_EPPAR = 0;
-    MCF_EPORT_EPDDR = 0;
-    MCF_EPORT_EPIER = 0;
-}
-
-/*********************************************************************
-* init_flexcan - FlexCAN Module                                      *
-**********************************************************************/
-static void
-init_flexcan( void )
-{
-
-    /* FlexCAN controller 0 disabled (CANMCR0[MDIS]=1) */
-    MCF_CAN_IMASK0 = 0;
-    MCF_CAN_RXGMASK0 = MCF_CAN_RXGMASK_MI( 0x1fffffff );
-    MCF_CAN_RX14MASK0 = MCF_CAN_RX14MASK_MI( 0x1fffffff );
-    MCF_CAN_RX15MASK0 = MCF_CAN_RX15MASK_MI( 0x1fffffff );
-    MCF_CAN_CANCTRL0 = 0;
-    MCF_CAN_CANMCR0 =
-        MCF_CAN_CANMCR_MDIS | MCF_CAN_CANMCR_FRZ | MCF_CAN_CANMCR_HALT |
-        MCF_CAN_CANMCR_SUPV | MCF_CAN_CANMCR_MAXMB( 0xf );
-
-    /* FlexCAN controller 1 disabled (CANMCR1[MDIS]=1) */
-    MCF_CAN_IMASK1 = 0;
-    MCF_CAN_RXGMASK1 = MCF_CAN_RXGMASK_MI( 0x1fffffff );
-    MCF_CAN_RX14MASK1 = MCF_CAN_RX14MASK_MI( 0x1fffffff );
-    MCF_CAN_RX15MASK1 = MCF_CAN_RX15MASK_MI( 0x1fffffff );
-    MCF_CAN_CANCTRL1 = 0;
-    MCF_CAN_CANMCR1 =
-        MCF_CAN_CANMCR_MDIS | MCF_CAN_CANMCR_FRZ | MCF_CAN_CANMCR_HALT |
-        MCF_CAN_CANMCR_SUPV | MCF_CAN_CANMCR_MAXMB( 0xf );
-}
-
-/*********************************************************************
-* init_power_management - Power Management                           *
-**********************************************************************/
-static void
-init_power_management( void )
-{
-
-    /* On executing STOP instruction, processor enters RUN mode
-       Mode is exited when an interrupt of level 1 or higher is received
-     */
-    MCF_SCM_LPICR = MCF_SCM_LPICR_ENBSTOP;
-    MCF_CCM_LPCR = 0;
-}
-
-/*********************************************************************
-* init_sdram_controller - SDRAM Controller                           *
-**********************************************************************/
-static void
-init_sdram_controller( void )
-{
-    extern void __SDRAM;
-    uint32 SDRAM_ADDR = (uint32)&__SDRAM;
-    int             i;
-
-
-    /*
-     * Check to see if the SDRAM has already been initialized
-     * by a run control tool
-     */
-    if( !( MCF_SDRAMC_DACR0 & MCF_SDRAMC_DACR0_RE ) )
-    {
-        /* Initialize DRAM Control Register: DCR */
-        MCF_SDRAMC_DCR = ( MCF_SDRAMC_DCR_RTIM( 1 ) |
-                           MCF_SDRAMC_DCR_RC( ( 15 * FSYS_2 ) >> 4 ) );
-
-        /* Initialize DACR0 */
-        MCF_SDRAMC_DACR0 = ( MCF_SDRAMC_DACR0_BA( SDRAM_ADDR >> 18UL ) |
-                             MCF_SDRAMC_DACR0_CASL( 1 ) |
-                             MCF_SDRAMC_DACR0_CBM( 3 ) |
-                             MCF_SDRAMC_DACR0_PS( 0 ) );
-
-        /* Initialize DMR0 */
-        MCF_SDRAMC_DMR0 = ( MCF_SDRAMC_DMR_BAM_16M | MCF_SDRAMC_DMR0_V );
-
-        /* Set IP (bit 3) in DACR */
-        MCF_SDRAMC_DACR0 |= MCF_SDRAMC_DACR0_IP;
-
-        /* Wait 30ns to allow banks to precharge */
-        for( i = 0; i < 5; i++ )
-        {
-            asm volatile    ( " nop" );
-        }
-        /* Write to this block to initiate precharge */
-        *( uint32 * ) ( SDRAM_ADDR ) = 0xA5A59696;
-
-        /* Set RE (bit 15) in DACR */
-        MCF_SDRAMC_DACR0 |= MCF_SDRAMC_DACR0_RE;
-
-        /* Wait for at least 8 auto refresh cycles to occur */
-        for( i = 0; i < 2000; i++ )
-        {
-            asm volatile    ( "nop" );
-        }
-        /* Finish the configuration by issuing the IMRS. */
-        MCF_SDRAMC_DACR0 |= MCF_SDRAMC_DACR0_MRS;
-
-        /* Write to the SDRAM Mode Register */
-        *( uint32 * ) ( SDRAM_ADDR + 0x400 ) = 0xA5A59696;
-    }
-}
-
-/*********************************************************************
-* init_dma_timers - DMA Timer Modules                                *
-**********************************************************************/
-static void
-init_dma_timers( void )
-{
-
-    /* DMA Timer 0 disabled (DTMR0[RST] = 0) */
-    MCF_TIMER_DTMR0 = 0;
-    MCF_TIMER_DTXMR0 = 0;
-    MCF_TIMER_DTRR0 = 0xffffffff;
-
-    /* DMA Timer 1 disabled (DTMR1[RST] = 0) */
-    MCF_TIMER_DTMR1 = 0;
-    MCF_TIMER_DTXMR1 = 0;
-    MCF_TIMER_DTRR1 = 0xffffffff;
-
-    /* DMA Timer 2 disabled (DTMR2[RST] = 0) */
-    MCF_TIMER_DTMR2 = 0;
-    MCF_TIMER_DTXMR2 = 0;
-    MCF_TIMER_DTRR2 = 0xffffffff;
-
-    /* DMA Timer 3 disabled (DTMR3[RST] = 0) */
-    MCF_TIMER_DTMR3 = 0;
-    MCF_TIMER_DTXMR3 = 0;
-    MCF_TIMER_DTRR3 = 0xffffffff;
-}
-
-/**********************************************************************
-* init_interrupt_timers - Programmable Interrupt Timer (PIT) Modules  *
-***********************************************************************/
-static void
-init_interrupt_timers( void )
-{
-
-    /* PIT0 disabled (PCSR0[EN]=0) */
-    MCF_PIT_PCSR0 = 0;
-
-    /* PIT1 disabled (PCSR1[EN]=0) */
-    MCF_PIT_PCSR1 = 0;
-
-    /* PIT2 disabled (PCSR2[EN]=0) */
-    MCF_PIT_PCSR2 = 0;
-
-    /* PIT3 disabled (PCSR3[EN]=0) */
-    MCF_PIT_PCSR3 = 0;
-}
-
-/*********************************************************************
-* init_watchdog_timers - Watchdog Timer Modules                      *
-**********************************************************************/
-static void
-init_watchdog_timers( void )
-{
-
-    /* Watchdog Timer disabled (WCR[EN]=0)
-       NOTE: WCR and WMR cannot be written again until after the
-       processor is reset.
-     */
-    MCF_WTM_WCR = MCF_WTM_WCR_WAIT | MCF_WTM_WCR_DOZE | MCF_WTM_WCR_HALTED;
-    MCF_WTM_WMR = 0xffff;
-
-    /* Core Watchdog Timer disabled (CWCR[CWE]=0) */
-    MCF_SCM_CWCR = 0;
-}
-
-/*********************************************************************
-* init_interrupt_controller - Interrupt Controller                   *
-**********************************************************************/
-static void
-init_interrupt_controller( void )
-{
-
-    /* Configured interrupt sources in order of priority...
-       Level 7:  External interrupt /IRQ7, (initially masked)
-       Level 6:  External interrupt /IRQ6, (initially masked)
-       Level 5:  External interrupt /IRQ5, (initially masked)
-       Level 4:  External interrupt /IRQ4, (initially masked)
-       Level 3:  External interrupt /IRQ3, (initially masked)
-       Level 2:  External interrupt /IRQ2, (initially masked)
-       Level 1:  External interrupt /IRQ1, (initially masked)
-     */
-    MCF_INTC0_ICR1 = 0;
-    MCF_INTC0_ICR2 = 0;
-    MCF_INTC0_ICR3 = 0;
-    MCF_INTC0_ICR4 = 0;
-    MCF_INTC0_ICR5 = 0;
-    MCF_INTC0_ICR6 = 0;
-    MCF_INTC0_ICR7 = 0;
-    MCF_INTC0_ICR8 = 0;
-    MCF_INTC0_ICR9 = 0;
-    MCF_INTC0_ICR10 = 0;
-    MCF_INTC0_ICR11 = 0;
-    MCF_INTC0_ICR12 = 0;
-    MCF_INTC0_ICR13 = 0;
-    MCF_INTC0_ICR14 = 0;
-    MCF_INTC0_ICR15 = 0;
-    MCF_INTC0_ICR17 = 0;
-    MCF_INTC0_ICR18 = 0;
-    MCF_INTC0_ICR19 = 0;
-    MCF_INTC0_ICR20 = 0;
-    MCF_INTC0_ICR21 = 0;
-    MCF_INTC0_ICR22 = 0;
-    MCF_INTC0_ICR23 = 0;
-    MCF_INTC0_ICR24 = 0;
-    MCF_INTC0_ICR25 = 0;
-    MCF_INTC0_ICR26 = 0;
-    MCF_INTC0_ICR27 = 0;
-    MCF_INTC0_ICR28 = 0;
-    MCF_INTC0_ICR29 = 0;
-    MCF_INTC0_ICR30 = 0;
-    MCF_INTC0_ICR31 = 0;
-    MCF_INTC0_ICR32 = 0;
-    MCF_INTC0_ICR33 = 0;
-    MCF_INTC0_ICR34 = 0;
-    MCF_INTC0_ICR35 = 0;
-    MCF_INTC0_ICR36 = 0;
-    MCF_INTC0_ICR37 = 0;
-    MCF_INTC0_ICR38 = 0;
-    MCF_INTC0_ICR39 = 0;
-    MCF_INTC0_ICR40 = 0;
-    MCF_INTC0_ICR41 = 0;
-    MCF_INTC0_ICR42 = 0;
-    MCF_INTC0_ICR43 = 0;
-    MCF_INTC0_ICR44 = 0;
-    MCF_INTC0_ICR45 = 0;
-    MCF_INTC0_ICR46 = 0;
-    MCF_INTC0_ICR47 = 0;
-    MCF_INTC0_ICR48 = 0;
-    MCF_INTC0_ICR49 = 0;
-    MCF_INTC0_ICR50 = 0;
-    MCF_INTC0_ICR51 = 0;
-    MCF_INTC0_ICR52 = 0;
-    MCF_INTC0_ICR53 = 0;
-    MCF_INTC0_ICR54 = 0;
-    MCF_INTC0_ICR55 = 0;
-    MCF_INTC0_ICR56 = 0;
-    MCF_INTC0_ICR57 = 0;
-    MCF_INTC0_ICR58 = 0;
-    MCF_INTC0_ICR59 = 0;
-    MCF_INTC0_ICR60 = 0;
-    MCF_INTC1_ICR8 = 0;
-    MCF_INTC1_ICR9 = 0;
-    MCF_INTC1_ICR10 = 0;
-    MCF_INTC1_ICR11 = 0;
-    MCF_INTC1_ICR12 = 0;
-    MCF_INTC1_ICR13 = 0;
-    MCF_INTC1_ICR14 = 0;
-    MCF_INTC1_ICR15 = 0;
-    MCF_INTC1_ICR16 = 0;
-    MCF_INTC1_ICR17 = 0;
-    MCF_INTC1_ICR18 = 0;
-    MCF_INTC1_ICR19 = 0;
-    MCF_INTC1_ICR20 = 0;
-    MCF_INTC1_ICR21 = 0;
-    MCF_INTC1_ICR22 = 0;
-    MCF_INTC1_ICR23 = 0;
-    MCF_INTC1_ICR24 = 0;
-    MCF_INTC1_ICR25 = 0;
-    MCF_INTC1_ICR27 = 0;
-    MCF_INTC1_ICR28 = 0;
-    MCF_INTC1_ICR29 = 0;
-    MCF_INTC1_ICR30 = 0;
-    MCF_INTC1_ICR31 = 0;
-    MCF_INTC1_ICR32 = 0;
-    MCF_INTC1_ICR33 = 0;
-    MCF_INTC1_ICR34 = 0;
-    MCF_INTC1_ICR35 = 0;
-    MCF_INTC1_ICR36 = 0;
-    MCF_INTC1_ICR37 = 0;
-    MCF_INTC1_ICR38 = 0;
-    MCF_INTC1_ICR39 = 0;
-    MCF_INTC1_ICR40 = 0;
-    MCF_INTC1_ICR41 = 0;
-    MCF_INTC1_ICR42 = 0;
-    MCF_INTC1_ICR59 = 0;
-    MCF_INTC0_IMRH = 0xffffffff;
-    MCF_INTC0_IMRL =
-        MCF_INTC0_IMRL_INT_MASK31 | MCF_INTC0_IMRL_INT_MASK30 |
-        MCF_INTC0_IMRL_INT_MASK29 | MCF_INTC0_IMRL_INT_MASK28 |
-        MCF_INTC0_IMRL_INT_MASK27 | MCF_INTC0_IMRL_INT_MASK26 |
-        MCF_INTC0_IMRL_INT_MASK25 | MCF_INTC0_IMRL_INT_MASK24 |
-        MCF_INTC0_IMRL_INT_MASK23 | MCF_INTC0_IMRL_INT_MASK22 |
-        MCF_INTC0_IMRL_INT_MASK21 | MCF_INTC0_IMRL_INT_MASK20 |
-        MCF_INTC0_IMRL_INT_MASK19 | MCF_INTC0_IMRL_INT_MASK18 |
-        MCF_INTC0_IMRL_INT_MASK17 | MCF_INTC0_IMRL_INT_MASK16 |
-        MCF_INTC0_IMRL_INT_MASK15 | MCF_INTC0_IMRL_INT_MASK14 |
-        MCF_INTC0_IMRL_INT_MASK13 | MCF_INTC0_IMRL_INT_MASK12 |
-        MCF_INTC0_IMRL_INT_MASK11 | MCF_INTC0_IMRL_INT_MASK10 |
-        MCF_INTC0_IMRL_INT_MASK9 | MCF_INTC0_IMRL_INT_MASK8 |
-        MCF_INTC0_IMRL_INT_MASK7 | MCF_INTC0_IMRL_INT_MASK6 |
-        MCF_INTC0_IMRL_INT_MASK5 | MCF_INTC0_IMRL_INT_MASK4 |
-        MCF_INTC0_IMRL_INT_MASK3 | MCF_INTC0_IMRL_INT_MASK2 |
-        MCF_INTC0_IMRL_INT_MASK1;
-    MCF_INTC1_IMRH = 0xffffffff;
-    MCF_INTC1_IMRL =
-        MCF_INTC1_IMRL_INT_MASK31 | MCF_INTC1_IMRL_INT_MASK30 |
-        MCF_INTC1_IMRL_INT_MASK29 | MCF_INTC1_IMRL_INT_MASK28 |
-        MCF_INTC1_IMRL_INT_MASK27 | MCF_INTC1_IMRL_INT_MASK26 |
-        MCF_INTC1_IMRL_INT_MASK25 | MCF_INTC1_IMRL_INT_MASK24 |
-        MCF_INTC1_IMRL_INT_MASK23 | MCF_INTC1_IMRL_INT_MASK22 |
-        MCF_INTC1_IMRL_INT_MASK21 | MCF_INTC1_IMRL_INT_MASK20 |
-        MCF_INTC1_IMRL_INT_MASK19 | MCF_INTC1_IMRL_INT_MASK18 |
-        MCF_INTC1_IMRL_INT_MASK17 | MCF_INTC1_IMRL_INT_MASK16 |
-        MCF_INTC1_IMRL_INT_MASK15 | MCF_INTC1_IMRL_INT_MASK14 |
-        MCF_INTC1_IMRL_INT_MASK13 | MCF_INTC1_IMRL_INT_MASK12 |
-        MCF_INTC1_IMRL_INT_MASK11 | MCF_INTC1_IMRL_INT_MASK10 |
-        MCF_INTC1_IMRL_INT_MASK9 | MCF_INTC1_IMRL_INT_MASK8 |
-        MCF_INTC1_IMRL_INT_MASK7 | MCF_INTC1_IMRL_INT_MASK6 |
-        MCF_INTC1_IMRL_INT_MASK5 | MCF_INTC1_IMRL_INT_MASK4 |
-        MCF_INTC1_IMRL_INT_MASK3 | MCF_INTC1_IMRL_INT_MASK2 |
-        MCF_INTC1_IMRL_INT_MASK1;
-}
-
-/*********************************************************************
-* init_pin_assignments - Pin Assignment and General Purpose I/O      *
-**********************************************************************/
-static void
-init_pin_assignments( void )
-{
-
-    /* Pin assignments for port ADDR
-       Pins are all GPIO inputs
-     */
-    MCF_GPIO_PDDR_APDDR = 0;
-    MCF_GPIO_PAR_AD = MCF_GPIO_PAR_AD_PAR_ADDR23
-        | MCF_GPIO_PAR_AD_PAR_ADDR22
-        | MCF_GPIO_PAR_AD_PAR_ADDR21 | MCF_GPIO_PAR_AD_PAR_DATAL;
-
-    /* Pin assignments for ports DATAH and DATAL
-       Pins are all GPIO inputs
-     */
-    MCF_GPIO_PDDR_DATAH = 0;
-    MCF_GPIO_PDDR_DATAL = 0;
-
-    /* Pin assignments for port BUSCTL
-       Pin /OE        : External bus output enable, /OE
-       Pin /TA        : External bus transfer acknowledge, /TA
-       Pin /TEA       : External bus transfer error acknowledge, /TEA
-       Pin R/W        : External bus read/write indication, R/W
-       Pin TSIZ1      : External bus transfer size TSIZ1 or DMA acknowledge /DACK1
-       Pin TSIZ0      : External bus transfer size TSIZ0 or DMA acknowledge /DACK0
-       Pin /TS        : External bus transfer start, /TS
-       Pin /TIP       : External bus transfer in progess, /TIP
-     */
-    MCF_GPIO_PDDR_BUSCTL = 0;
-    MCF_GPIO_PAR_BUSCTL =
-        MCF_GPIO_PAR_BUSCTL_PAR_OE | MCF_GPIO_PAR_BUSCTL_PAR_TA |
-        MCF_GPIO_PAR_BUSCTL_PAR_TEA( 0x3 ) | MCF_GPIO_PAR_BUSCTL_PAR_RWB |
-        MCF_GPIO_PAR_BUSCTL_PAR_TSIZ1 | MCF_GPIO_PAR_BUSCTL_PAR_TSIZ0 |
-        MCF_GPIO_PAR_BUSCTL_PAR_TS( 0x3 ) |
-        MCF_GPIO_PAR_BUSCTL_PAR_TIP( 0x3 );
-
-    /* Pin assignments for port BS
-       Pin /BS3       : External byte strobe /BS3
-       Pin /BS2       : External byte strobe /BS2
-       Pin /BS1       : External byte strobe /BS1
-       Pin /BS0       : External byte strobe /BS0
-     */
-    MCF_GPIO_PDDR_BS = 0;
-    MCF_GPIO_PAR_BS =
-        MCF_GPIO_PAR_BS_PAR_BS3 | MCF_GPIO_PAR_BS_PAR_BS2 |
-        MCF_GPIO_PAR_BS_PAR_BS1 | MCF_GPIO_PAR_BS_PAR_BS0;
-
-    /* Pin assignments for port CS
-       Pin /CS7       : Chip select /CS7
-       Pin /CS6       : Chip select /CS6
-       Pin /CS5       : Chip select /CS5
-       Pin /CS4       : Chip select /CS4
-       Pin /CS3       : Chip select /CS3
-       Pin /CS2       : Chip select /CS2
-       Pin /CS1       : Chip select /CS1
-     */
-    MCF_GPIO_PDDR_CS = 0;
-    MCF_GPIO_PAR_CS =
-        MCF_GPIO_PAR_CS_PAR_CS7 | MCF_GPIO_PAR_CS_PAR_CS6 |
-        MCF_GPIO_PAR_CS_PAR_CS5 | MCF_GPIO_PAR_CS_PAR_CS4 |
-        MCF_GPIO_PAR_CS_PAR_CS3 | MCF_GPIO_PAR_CS_PAR_CS2 |
-        MCF_GPIO_PAR_CS_PAR_CS1;
-
-    /* Pin assignments for port SDRAM
-       Pin /SD_WE     : SDRAM controller /SD_WE
-       Pin /SD_SCAS   : SDRAM controller /SD_SCAS
-       Pin /SD_SRAS   : SDRAM controller /SD_SRAS
-       Pin /SD_SCKE   : SDRAM controller /SD_SCKE
-       Pin /SD_CS1    : SDRAM controller /SD_CS1
-       Pin /SD_CS0    : SDRAM controller /SD_CS0
-     */
-    MCF_GPIO_PDDR_SDRAM = 0;
-    MCF_GPIO_PAR_SDRAM =
-        MCF_GPIO_PAR_SDRAM_PAR_SDWE | MCF_GPIO_PAR_SDRAM_PAR_SCAS |
-        MCF_GPIO_PAR_SDRAM_PAR_SRAS | MCF_GPIO_PAR_SDRAM_PAR_SCKE |
-        MCF_GPIO_PAR_SDRAM_PAR_SDCS1 | MCF_GPIO_PAR_SDRAM_PAR_SDCS0;
-
-    /* Pin assignments for port FECI2C
-       Pins are all GPIO inputs
-     */
-    MCF_GPIO_PDDR_FECI2C = 0;
-    MCF_GPIO_PAR_FECI2C =
-        MCF_GPIO_PAR_FECI2C_PAR_EMDC_FEC | MCF_GPIO_PAR_FECI2C_PAR_EMDIO_FEC;
-
-    /* Pin assignments for port UARTL
-       Pins are all GPIO inputs
-     */
-    MCF_GPIO_PDDR_UARTL = 0;
-    MCF_GPIO_PAR_UART = 0;
-
-    /* Pin assignments for port UARTH
-       Pin U2TXD      : GPIO input
-       Pin U2RXD      : GPIO input
-       Pin /IRQ2      : Interrupt request /IRQ2 or GPIO
-     */
-    MCF_GPIO_PDDR_UARTH = 0;
-
-    /* Pin assignments for port QSPI
-       Pins are all GPIO inputs
-     */
-    MCF_GPIO_PDDR_QSPI = 0;
-    MCF_GPIO_PAR_QSPI = 0;
-
-    /* Pin assignments for port TIMER
-       Pins are all GPIO inputs
-     */
-    MCF_GPIO_PDDR_TIMER = 0;
-    MCF_GPIO_PAR_TIMER = 0;
-
-    /* Pin assignments for port ETPU
-       Pins are all GPIO inputs
-     */
-    MCF_GPIO_PDDR_ETPU = 0;
-    MCF_GPIO_PAR_ETPU = 0;
-}
+       with commercial development and support options.\r
+    ***************************************************************************\r
+*/\r
+\r
+#include "mcf5xxx.h"\r
+#include "mcf523x.h"\r
+\r
+/* Function prototypes */\r
+void            init_main( void );\r
+static void     disable_interrupts( void );\r
+static void     disable_watchdog_timer( void );\r
+static void     disable_cache( void );\r
+static void     init_ipsbar( void );\r
+static void     init_basics( void );\r
+static void     init_clock_config( void );\r
+static void     init_chip_selects( void );\r
+static void     init_bus_config( void );\r
+static void     init_cache( void );\r
+static void     init_eport( void );\r
+static void     init_flexcan( void );\r
+static void     init_power_management( void );\r
+static void     init_dma_timers( void );\r
+static void     init_interrupt_timers( void );\r
+static void     init_watchdog_timers( void );\r
+static void     init_pin_assignments( void );\r
+static void     init_sdram_controller( void );\r
+static void     init_interrupt_controller( void );\r
+\r
+\r
+/*********************************************************************\r
+* init_main - Main entry point for initialisation code               *\r
+**********************************************************************/\r
+void\r
+init_main( void )\r
+{\r
+\r
+    /* Initialise base address of peripherals, VBR, etc */\r
+    init_ipsbar(  );\r
+    init_basics(  );\r
+    init_clock_config(  );\r
+\r
+    /* Disable interrupts, watchdog timer, cache */\r
+    disable_interrupts(  );\r
+    disable_watchdog_timer(  );\r
+    disable_cache(  );\r
+\r
+    /* Initialise individual modules */\r
+    init_chip_selects(  );\r
+    init_bus_config(  );\r
+    init_cache(  );\r
+    init_eport(  );\r
+    init_flexcan(  );\r
+    init_power_management(  );\r
+    init_dma_timers(  );\r
+    init_interrupt_timers(  );\r
+    init_watchdog_timers(  );\r
+    init_pin_assignments(  );\r
+    init_sdram_controller(  );\r
+\r
+    /* Initialise interrupt controller */\r
+    init_interrupt_controller(  );\r
+}\r
+\r
+/*********************************************************************\r
+* disable_interrupts - Disable all interrupt sources                 *\r
+**********************************************************************/\r
+static void\r
+disable_interrupts( void )\r
+{\r
+    vuint8         *p;\r
+    int             i;\r
+\r
+\r
+    /* Set ICR008-ICR063 to 0x0 */\r
+    p = ( vuint8 * ) & MCF_INTC0_ICR8;\r
+    for( i = 8; i <= 63; i++ )\r
+        *p++ = 0x0;\r
+\r
+    /* Set ICR108-ICR163 to 0x0 */\r
+    p = ( vuint8 * ) & MCF_INTC1_ICR8;\r
+    for( i = 108; i <= 163; i++ )\r
+        *p++ = 0x0;\r
+}\r
+\r
+\r
+/*********************************************************************\r
+* disable_watchdog_timer - Disable system watchdog timer             *\r
+**********************************************************************/\r
+static void\r
+disable_watchdog_timer( void )\r
+{\r
+\r
+    /* Disable Core Watchdog Timer */\r
+    MCF_SCM_CWCR = 0;\r
+}\r
+\r
+/*********************************************************************\r
+* disable_cache - Disable and invalidate cache                       *\r
+**********************************************************************/\r
+static void\r
+disable_cache( void )\r
+{\r
+    asm ( "move.l   #0x01000000, %d0" );\r
+    asm ( "movec    %d0, %CACR" );\r
+}\r
+\r
+/*********************************************************************\r
+* init_basics - Configuration Information & VBR                      *\r
+**********************************************************************/\r
+static void\r
+init_basics( void )\r
+{\r
+    int             i;\r
+    extern uint32   __RAMVEC[];\r
+    extern uint32   __ROMVEC[];\r
+\r
+    /* Transfer size not driven on SIZ[1:0] pins during external cycles\r
+       Processor Status (PST) and Debug Data (DDATA) functions disabled\r
+       Bus monitor disabled\r
+       Output pads configured for full strength\r
+     */\r
+    MCF_CCM_CCR = ( 0x1 << 15 ) | MCF_CCM_CCR_BME;\r
+\r
+    /* Set up RAM vectors */\r
+    for( i = 0; i < 256; i++ )\r
+\r
+    {\r
+        __RAMVEC[i] = __ROMVEC[i];\r
+    }\r
+    asm( "move.l   %0,%%d0": :"i"( __RAMVEC ) );\r
+    asm( "movec    %d0,%vbr" );\r
+}\r
+\r
+\r
+/*********************************************************************\r
+* init_clock_config - Clock Module                                   *\r
+**********************************************************************/\r
+static void\r
+init_clock_config( void )\r
+{\r
+    /* Clock module uses normal PLL mode with 25.0000 MHz external reference (Fref)\r
+       MFD = 0, RFD = 1\r
+       Bus clock frequency = 25.00 MHz\r
+       Processor clock frequency = 2 x bus clock = 50.00 MHz\r
+       Frequency Modulation disabled\r
+       Loss of clock detection disabled\r
+       Reset/Interrupt on loss of lock disabled\r
+     */\r
+    MCF_FMPLL_SYNCR = 0x00100000;       /* Set RFD=RFD+1 to avoid frequency overshoot */\r
+    while( ( MCF_FMPLL_SYNSR & 0x08 ) == 0 )    /* Wait for PLL to lock */\r
+        ;\r
+    MCF_FMPLL_SYNCR = 0x00080000;       /* Set desired RFD */\r
+    while( ( MCF_FMPLL_SYNSR & 0x08 ) == 0 )    /* Wait for PLL to lock */\r
+        ;\r
+}\r
+\r
+\r
+/*********************************************************************\r
+* init_ipsbar - Internal Peripheral System Base Address (IPSBAR)     *\r
+**********************************************************************/\r
+static void\r
+init_ipsbar( void )\r
+{\r
+    extern int  __SRAM;\r
+\r
+    /* Base address of internal peripherals (IPSBAR) = 0x40000000\r
+\r
+       Note: Processor powers up with IPS base address = 0x40000000\r
+       Write to IPS base + 0x00000000 to set new value\r
+     */\r
+    *( vuint32 * ) 0x40000000 = ( vuint32 ) __IPSBAR + 1;\r
+\r
+    /* Configure RAMBAR in SCM module and allow dual-ported access. */\r
+    MCF_SCM_RAMBAR = ( uint32 ) &__SRAM | MCF_SCM_RAMBAR_BDE;\r
+}\r
+\r
+/*********************************************************************\r
+* init_chip_selects - Chip Select Module                             *\r
+**********************************************************************/\r
+static void\r
+init_chip_selects( void )\r
+{\r
+    extern void __FLASH;\r
+    uint32 FLASH_ADDR = (uint32)&__FLASH;\r
+\r
+    /* Chip Select 0 - External Flash */\r
+    MCF_CS_CSAR0 = MCF_CS_CSAR_BA( FLASH_ADDR );\r
+    MCF_CS_CSCR0 = ( 0\r
+                     | MCF_CS_CSCR_IWS( 6 )\r
+                     | MCF_CS_CSCR_AA | MCF_CS_CSCR_PS_16 );\r
+    MCF_CS_CSMR0 = MCF_CS_CSMR_BAM_2M | MCF_CS_CSMR_V;\r
+\r
+    /* Chip Select 1 disabled (CSMR1[V] = 0) */\r
+    MCF_CS_CSAR1 = 0;\r
+    MCF_CS_CSMR1 = 0;\r
+    MCF_CS_CSCR1 = 0;\r
+\r
+    /* Chip Select 2 disabled (CSMR2[V] = 0) */\r
+    MCF_CS_CSAR2 = 0;\r
+    MCF_CS_CSMR2 = 0;\r
+    MCF_CS_CSCR2 = 0;\r
+\r
+    /* Chip Select 3 disabled (CSMR3[V] = 0) */\r
+    MCF_CS_CSAR3 = 0;\r
+    MCF_CS_CSMR3 = 0;\r
+    MCF_CS_CSCR3 = 0;\r
+\r
+    /* Chip Select 4 disabled (CSMR4[V] = 0) */\r
+    MCF_CS_CSAR4 = 0;\r
+    MCF_CS_CSMR4 = 0;\r
+    MCF_CS_CSCR4 = 0;\r
+\r
+    /* Chip Select 5 disabled (CSMR5[V] = 0) */\r
+    MCF_CS_CSAR5 = 0;\r
+    MCF_CS_CSMR5 = 0;\r
+    MCF_CS_CSCR5 = 0;\r
+\r
+    /* Chip Select 6 disabled (CSMR6[V] = 0) */\r
+    MCF_CS_CSAR6 = 0;\r
+    MCF_CS_CSMR6 = 0;\r
+    MCF_CS_CSCR6 = 0;\r
+\r
+    /* Chip Select 7 disabled (CSMR7[V] = 0) */\r
+    MCF_CS_CSAR7 = 0;\r
+    MCF_CS_CSMR7 = 0;\r
+    MCF_CS_CSCR7 = 0;\r
+}\r
+\r
+/*********************************************************************\r
+* init_bus_config - Internal Bus Arbitration                         *\r
+**********************************************************************/\r
+static void\r
+init_bus_config( void )\r
+{\r
+\r
+    /* Use round robin arbitration scheme\r
+       Assigned priorities (highest first):\r
+       Ethernet\r
+       DMA Controller\r
+       ColdFire Core\r
+       DMA bandwidth control disabled\r
+       Park on last active bus master\r
+     */\r
+    MCF_SCM_MPARK =\r
+        MCF_SCM_MPARK_M3_PRTY( 0x3 ) | MCF_SCM_MPARK_M2_PRTY( 0x2 ) |\r
+        MCF_SCM_MPARK_M1_PRTY( 0x1 );\r
+}\r
+\r
+/*********************************************************************\r
+* init_cache - Instruction/Data Cache                                *\r
+**********************************************************************/\r
+static void\r
+init_cache( void )\r
+{\r
+    /* Configured as split cache: 4 KByte instruction cache and 4 Kbyte data cache\r
+       ACR0: Don't cache accesses to 16 MB memory region at address $20000000\r
+       ACR1: Don't cache accesses to 1 GB memory region at address $40000000\r
+       CACR: Cache accesses to the rest of memory\r
+    */\r
+    asm("move.l   #0x80000000,%d0");\r
+    asm("movec    %d0,%CACR");\r
+    asm("move.l   #0x2000c040,%d0");\r
+    asm("movec    %d0,%ACR0");\r
+    asm("move.l   #0x403fc040,%d0");\r
+    asm("movec    %d0,%ACR1");\r
+\r
+    /* Instruction/Data cache disabled. */\r
+    //asm( "move.l   #0x00000000, %d0" );\r
+    //asm( "movec    %d0,%cacr" );\r
+}\r
+\r
+/*********************************************************************\r
+* init_eport - Edge Port Module (EPORT)                              *\r
+**********************************************************************/\r
+static void\r
+init_eport( void )\r
+{\r
+\r
+    /* Pins 1-7 configured as GPIO inputs */\r
+    MCF_EPORT_EPPAR = 0;\r
+    MCF_EPORT_EPDDR = 0;\r
+    MCF_EPORT_EPIER = 0;\r
+}\r
+\r
+/*********************************************************************\r
+* init_flexcan - FlexCAN Module                                      *\r
+**********************************************************************/\r
+static void\r
+init_flexcan( void )\r
+{\r
+\r
+    /* FlexCAN controller 0 disabled (CANMCR0[MDIS]=1) */\r
+    MCF_CAN_IMASK0 = 0;\r
+    MCF_CAN_RXGMASK0 = MCF_CAN_RXGMASK_MI( 0x1fffffff );\r
+    MCF_CAN_RX14MASK0 = MCF_CAN_RX14MASK_MI( 0x1fffffff );\r
+    MCF_CAN_RX15MASK0 = MCF_CAN_RX15MASK_MI( 0x1fffffff );\r
+    MCF_CAN_CANCTRL0 = 0;\r
+    MCF_CAN_CANMCR0 =\r
+        MCF_CAN_CANMCR_MDIS | MCF_CAN_CANMCR_FRZ | MCF_CAN_CANMCR_HALT |\r
+        MCF_CAN_CANMCR_SUPV | MCF_CAN_CANMCR_MAXMB( 0xf );\r
+\r
+    /* FlexCAN controller 1 disabled (CANMCR1[MDIS]=1) */\r
+    MCF_CAN_IMASK1 = 0;\r
+    MCF_CAN_RXGMASK1 = MCF_CAN_RXGMASK_MI( 0x1fffffff );\r
+    MCF_CAN_RX14MASK1 = MCF_CAN_RX14MASK_MI( 0x1fffffff );\r
+    MCF_CAN_RX15MASK1 = MCF_CAN_RX15MASK_MI( 0x1fffffff );\r
+    MCF_CAN_CANCTRL1 = 0;\r
+    MCF_CAN_CANMCR1 =\r
+        MCF_CAN_CANMCR_MDIS | MCF_CAN_CANMCR_FRZ | MCF_CAN_CANMCR_HALT |\r
+        MCF_CAN_CANMCR_SUPV | MCF_CAN_CANMCR_MAXMB( 0xf );\r
+}\r
+\r
+/*********************************************************************\r
+* init_power_management - Power Management                           *\r
+**********************************************************************/\r
+static void\r
+init_power_management( void )\r
+{\r
+\r
+    /* On executing STOP instruction, processor enters RUN mode\r
+       Mode is exited when an interrupt of level 1 or higher is received\r
+     */\r
+    MCF_SCM_LPICR = MCF_SCM_LPICR_ENBSTOP;\r
+    MCF_CCM_LPCR = 0;\r
+}\r
+\r
+/*********************************************************************\r
+* init_sdram_controller - SDRAM Controller                           *\r
+**********************************************************************/\r
+static void\r
+init_sdram_controller( void )\r
+{\r
+    extern void __SDRAM;\r
+    uint32 SDRAM_ADDR = (uint32)&__SDRAM;\r
+    int             i;\r
+\r
+\r
+    /*\r
+     * Check to see if the SDRAM has already been initialized\r
+     * by a run control tool\r
+     */\r
+    if( !( MCF_SDRAMC_DACR0 & MCF_SDRAMC_DACR0_RE ) )\r
+    {\r
+        /* Initialize DRAM Control Register: DCR */\r
+        MCF_SDRAMC_DCR = ( MCF_SDRAMC_DCR_RTIM( 1 ) |\r
+                           MCF_SDRAMC_DCR_RC( ( 15 * FSYS_2 ) >> 4 ) );\r
+\r
+        /* Initialize DACR0 */\r
+        MCF_SDRAMC_DACR0 = ( MCF_SDRAMC_DACR0_BA( SDRAM_ADDR >> 18UL ) |\r
+                             MCF_SDRAMC_DACR0_CASL( 1 ) |\r
+                             MCF_SDRAMC_DACR0_CBM( 3 ) |\r
+                             MCF_SDRAMC_DACR0_PS( 0 ) );\r
+\r
+        /* Initialize DMR0 */\r
+        MCF_SDRAMC_DMR0 = ( MCF_SDRAMC_DMR_BAM_16M | MCF_SDRAMC_DMR0_V );\r
+\r
+        /* Set IP (bit 3) in DACR */\r
+        MCF_SDRAMC_DACR0 |= MCF_SDRAMC_DACR0_IP;\r
+\r
+        /* Wait 30ns to allow banks to precharge */\r
+        for( i = 0; i < 5; i++ )\r
+        {\r
+            asm volatile    ( " nop" );\r
+        }\r
+        /* Write to this block to initiate precharge */\r
+        *( uint32 * ) ( SDRAM_ADDR ) = 0xA5A59696;\r
+\r
+        /* Set RE (bit 15) in DACR */\r
+        MCF_SDRAMC_DACR0 |= MCF_SDRAMC_DACR0_RE;\r
+\r
+        /* Wait for at least 8 auto refresh cycles to occur */\r
+        for( i = 0; i < 2000; i++ )\r
+        {\r
+            asm volatile    ( "nop" );\r
+        }\r
+        /* Finish the configuration by issuing the IMRS. */\r
+        MCF_SDRAMC_DACR0 |= MCF_SDRAMC_DACR0_MRS;\r
+\r
+        /* Write to the SDRAM Mode Register */\r
+        *( uint32 * ) ( SDRAM_ADDR + 0x400 ) = 0xA5A59696;\r
+    }\r
+}\r
+\r
+/*********************************************************************\r
+* init_dma_timers - DMA Timer Modules                                *\r
+**********************************************************************/\r
+static void\r
+init_dma_timers( void )\r
+{\r
+\r
+    /* DMA Timer 0 disabled (DTMR0[RST] = 0) */\r
+    MCF_TIMER_DTMR0 = 0;\r
+    MCF_TIMER_DTXMR0 = 0;\r
+    MCF_TIMER_DTRR0 = 0xffffffff;\r
+\r
+    /* DMA Timer 1 disabled (DTMR1[RST] = 0) */\r
+    MCF_TIMER_DTMR1 = 0;\r
+    MCF_TIMER_DTXMR1 = 0;\r
+    MCF_TIMER_DTRR1 = 0xffffffff;\r
+\r
+    /* DMA Timer 2 disabled (DTMR2[RST] = 0) */\r
+    MCF_TIMER_DTMR2 = 0;\r
+    MCF_TIMER_DTXMR2 = 0;\r
+    MCF_TIMER_DTRR2 = 0xffffffff;\r
+\r
+    /* DMA Timer 3 disabled (DTMR3[RST] = 0) */\r
+    MCF_TIMER_DTMR3 = 0;\r
+    MCF_TIMER_DTXMR3 = 0;\r
+    MCF_TIMER_DTRR3 = 0xffffffff;\r
+}\r
+\r
+/**********************************************************************\r
+* init_interrupt_timers - Programmable Interrupt Timer (PIT) Modules  *\r
+***********************************************************************/\r
+static void\r
+init_interrupt_timers( void )\r
+{\r
+\r
+    /* PIT0 disabled (PCSR0[EN]=0) */\r
+    MCF_PIT_PCSR0 = 0;\r
+\r
+    /* PIT1 disabled (PCSR1[EN]=0) */\r
+    MCF_PIT_PCSR1 = 0;\r
+\r
+    /* PIT2 disabled (PCSR2[EN]=0) */\r
+    MCF_PIT_PCSR2 = 0;\r
+\r
+    /* PIT3 disabled (PCSR3[EN]=0) */\r
+    MCF_PIT_PCSR3 = 0;\r
+}\r
+\r
+/*********************************************************************\r
+* init_watchdog_timers - Watchdog Timer Modules                      *\r
+**********************************************************************/\r
+static void\r
+init_watchdog_timers( void )\r
+{\r
+\r
+    /* Watchdog Timer disabled (WCR[EN]=0)\r
+       NOTE: WCR and WMR cannot be written again until after the\r
+       processor is reset.\r
+     */\r
+    MCF_WTM_WCR = MCF_WTM_WCR_WAIT | MCF_WTM_WCR_DOZE | MCF_WTM_WCR_HALTED;\r
+    MCF_WTM_WMR = 0xffff;\r
+\r
+    /* Core Watchdog Timer disabled (CWCR[CWE]=0) */\r
+    MCF_SCM_CWCR = 0;\r
+}\r
+\r
+/*********************************************************************\r
+* init_interrupt_controller - Interrupt Controller                   *\r
+**********************************************************************/\r
+static void\r
+init_interrupt_controller( void )\r
+{\r
+\r
+    /* Configured interrupt sources in order of priority...\r
+       Level 7:  External interrupt /IRQ7, (initially masked)\r
+       Level 6:  External interrupt /IRQ6, (initially masked)\r
+       Level 5:  External interrupt /IRQ5, (initially masked)\r
+       Level 4:  External interrupt /IRQ4, (initially masked)\r
+       Level 3:  External interrupt /IRQ3, (initially masked)\r
+       Level 2:  External interrupt /IRQ2, (initially masked)\r
+       Level 1:  External interrupt /IRQ1, (initially masked)\r
+     */\r
+    MCF_INTC0_ICR1 = 0;\r
+    MCF_INTC0_ICR2 = 0;\r
+    MCF_INTC0_ICR3 = 0;\r
+    MCF_INTC0_ICR4 = 0;\r
+    MCF_INTC0_ICR5 = 0;\r
+    MCF_INTC0_ICR6 = 0;\r
+    MCF_INTC0_ICR7 = 0;\r
+    MCF_INTC0_ICR8 = 0;\r
+    MCF_INTC0_ICR9 = 0;\r
+    MCF_INTC0_ICR10 = 0;\r
+    MCF_INTC0_ICR11 = 0;\r
+    MCF_INTC0_ICR12 = 0;\r
+    MCF_INTC0_ICR13 = 0;\r
+    MCF_INTC0_ICR14 = 0;\r
+    MCF_INTC0_ICR15 = 0;\r
+    MCF_INTC0_ICR17 = 0;\r
+    MCF_INTC0_ICR18 = 0;\r
+    MCF_INTC0_ICR19 = 0;\r
+    MCF_INTC0_ICR20 = 0;\r
+    MCF_INTC0_ICR21 = 0;\r
+    MCF_INTC0_ICR22 = 0;\r
+    MCF_INTC0_ICR23 = 0;\r
+    MCF_INTC0_ICR24 = 0;\r
+    MCF_INTC0_ICR25 = 0;\r
+    MCF_INTC0_ICR26 = 0;\r
+    MCF_INTC0_ICR27 = 0;\r
+    MCF_INTC0_ICR28 = 0;\r
+    MCF_INTC0_ICR29 = 0;\r
+    MCF_INTC0_ICR30 = 0;\r
+    MCF_INTC0_ICR31 = 0;\r
+    MCF_INTC0_ICR32 = 0;\r
+    MCF_INTC0_ICR33 = 0;\r
+    MCF_INTC0_ICR34 = 0;\r
+    MCF_INTC0_ICR35 = 0;\r
+    MCF_INTC0_ICR36 = 0;\r
+    MCF_INTC0_ICR37 = 0;\r
+    MCF_INTC0_ICR38 = 0;\r
+    MCF_INTC0_ICR39 = 0;\r
+    MCF_INTC0_ICR40 = 0;\r
+    MCF_INTC0_ICR41 = 0;\r
+    MCF_INTC0_ICR42 = 0;\r
+    MCF_INTC0_ICR43 = 0;\r
+    MCF_INTC0_ICR44 = 0;\r
+    MCF_INTC0_ICR45 = 0;\r
+    MCF_INTC0_ICR46 = 0;\r
+    MCF_INTC0_ICR47 = 0;\r
+    MCF_INTC0_ICR48 = 0;\r
+    MCF_INTC0_ICR49 = 0;\r
+    MCF_INTC0_ICR50 = 0;\r
+    MCF_INTC0_ICR51 = 0;\r
+    MCF_INTC0_ICR52 = 0;\r
+    MCF_INTC0_ICR53 = 0;\r
+    MCF_INTC0_ICR54 = 0;\r
+    MCF_INTC0_ICR55 = 0;\r
+    MCF_INTC0_ICR56 = 0;\r
+    MCF_INTC0_ICR57 = 0;\r
+    MCF_INTC0_ICR58 = 0;\r
+    MCF_INTC0_ICR59 = 0;\r
+    MCF_INTC0_ICR60 = 0;\r
+    MCF_INTC1_ICR8 = 0;\r
+    MCF_INTC1_ICR9 = 0;\r
+    MCF_INTC1_ICR10 = 0;\r
+    MCF_INTC1_ICR11 = 0;\r
+    MCF_INTC1_ICR12 = 0;\r
+    MCF_INTC1_ICR13 = 0;\r
+    MCF_INTC1_ICR14 = 0;\r
+    MCF_INTC1_ICR15 = 0;\r
+    MCF_INTC1_ICR16 = 0;\r
+    MCF_INTC1_ICR17 = 0;\r
+    MCF_INTC1_ICR18 = 0;\r
+    MCF_INTC1_ICR19 = 0;\r
+    MCF_INTC1_ICR20 = 0;\r
+    MCF_INTC1_ICR21 = 0;\r
+    MCF_INTC1_ICR22 = 0;\r
+    MCF_INTC1_ICR23 = 0;\r
+    MCF_INTC1_ICR24 = 0;\r
+    MCF_INTC1_ICR25 = 0;\r
+    MCF_INTC1_ICR27 = 0;\r
+    MCF_INTC1_ICR28 = 0;\r
+    MCF_INTC1_ICR29 = 0;\r
+    MCF_INTC1_ICR30 = 0;\r
+    MCF_INTC1_ICR31 = 0;\r
+    MCF_INTC1_ICR32 = 0;\r
+    MCF_INTC1_ICR33 = 0;\r
+    MCF_INTC1_ICR34 = 0;\r
+    MCF_INTC1_ICR35 = 0;\r
+    MCF_INTC1_ICR36 = 0;\r
+    MCF_INTC1_ICR37 = 0;\r
+    MCF_INTC1_ICR38 = 0;\r
+    MCF_INTC1_ICR39 = 0;\r
+    MCF_INTC1_ICR40 = 0;\r
+    MCF_INTC1_ICR41 = 0;\r
+    MCF_INTC1_ICR42 = 0;\r
+    MCF_INTC1_ICR59 = 0;\r
+    MCF_INTC0_IMRH = 0xffffffff;\r
+    MCF_INTC0_IMRL =\r
+        MCF_INTC0_IMRL_INT_MASK31 | MCF_INTC0_IMRL_INT_MASK30 |\r
+        MCF_INTC0_IMRL_INT_MASK29 | MCF_INTC0_IMRL_INT_MASK28 |\r
+        MCF_INTC0_IMRL_INT_MASK27 | MCF_INTC0_IMRL_INT_MASK26 |\r
+        MCF_INTC0_IMRL_INT_MASK25 | MCF_INTC0_IMRL_INT_MASK24 |\r
+        MCF_INTC0_IMRL_INT_MASK23 | MCF_INTC0_IMRL_INT_MASK22 |\r
+        MCF_INTC0_IMRL_INT_MASK21 | MCF_INTC0_IMRL_INT_MASK20 |\r
+        MCF_INTC0_IMRL_INT_MASK19 | MCF_INTC0_IMRL_INT_MASK18 |\r
+        MCF_INTC0_IMRL_INT_MASK17 | MCF_INTC0_IMRL_INT_MASK16 |\r
+        MCF_INTC0_IMRL_INT_MASK15 | MCF_INTC0_IMRL_INT_MASK14 |\r
+        MCF_INTC0_IMRL_INT_MASK13 | MCF_INTC0_IMRL_INT_MASK12 |\r
+        MCF_INTC0_IMRL_INT_MASK11 | MCF_INTC0_IMRL_INT_MASK10 |\r
+        MCF_INTC0_IMRL_INT_MASK9 | MCF_INTC0_IMRL_INT_MASK8 |\r
+        MCF_INTC0_IMRL_INT_MASK7 | MCF_INTC0_IMRL_INT_MASK6 |\r
+        MCF_INTC0_IMRL_INT_MASK5 | MCF_INTC0_IMRL_INT_MASK4 |\r
+        MCF_INTC0_IMRL_INT_MASK3 | MCF_INTC0_IMRL_INT_MASK2 |\r
+        MCF_INTC0_IMRL_INT_MASK1;\r
+    MCF_INTC1_IMRH = 0xffffffff;\r
+    MCF_INTC1_IMRL =\r
+        MCF_INTC1_IMRL_INT_MASK31 | MCF_INTC1_IMRL_INT_MASK30 |\r
+        MCF_INTC1_IMRL_INT_MASK29 | MCF_INTC1_IMRL_INT_MASK28 |\r
+        MCF_INTC1_IMRL_INT_MASK27 | MCF_INTC1_IMRL_INT_MASK26 |\r
+        MCF_INTC1_IMRL_INT_MASK25 | MCF_INTC1_IMRL_INT_MASK24 |\r
+        MCF_INTC1_IMRL_INT_MASK23 | MCF_INTC1_IMRL_INT_MASK22 |\r
+        MCF_INTC1_IMRL_INT_MASK21 | MCF_INTC1_IMRL_INT_MASK20 |\r
+        MCF_INTC1_IMRL_INT_MASK19 | MCF_INTC1_IMRL_INT_MASK18 |\r
+        MCF_INTC1_IMRL_INT_MASK17 | MCF_INTC1_IMRL_INT_MASK16 |\r
+        MCF_INTC1_IMRL_INT_MASK15 | MCF_INTC1_IMRL_INT_MASK14 |\r
+        MCF_INTC1_IMRL_INT_MASK13 | MCF_INTC1_IMRL_INT_MASK12 |\r
+        MCF_INTC1_IMRL_INT_MASK11 | MCF_INTC1_IMRL_INT_MASK10 |\r
+        MCF_INTC1_IMRL_INT_MASK9 | MCF_INTC1_IMRL_INT_MASK8 |\r
+        MCF_INTC1_IMRL_INT_MASK7 | MCF_INTC1_IMRL_INT_MASK6 |\r
+        MCF_INTC1_IMRL_INT_MASK5 | MCF_INTC1_IMRL_INT_MASK4 |\r
+        MCF_INTC1_IMRL_INT_MASK3 | MCF_INTC1_IMRL_INT_MASK2 |\r
+        MCF_INTC1_IMRL_INT_MASK1;\r
+}\r
+\r
+/*********************************************************************\r
+* init_pin_assignments - Pin Assignment and General Purpose I/O      *\r
+**********************************************************************/\r
+static void\r
+init_pin_assignments( void )\r
+{\r
+\r
+    /* Pin assignments for port ADDR\r
+       Pins are all GPIO inputs\r
+     */\r
+    MCF_GPIO_PDDR_APDDR = 0;\r
+    MCF_GPIO_PAR_AD = MCF_GPIO_PAR_AD_PAR_ADDR23\r
+        | MCF_GPIO_PAR_AD_PAR_ADDR22\r
+        | MCF_GPIO_PAR_AD_PAR_ADDR21 | MCF_GPIO_PAR_AD_PAR_DATAL;\r
+\r
+    /* Pin assignments for ports DATAH and DATAL\r
+       Pins are all GPIO inputs\r
+     */\r
+    MCF_GPIO_PDDR_DATAH = 0;\r
+    MCF_GPIO_PDDR_DATAL = 0;\r
+\r
+    /* Pin assignments for port BUSCTL\r
+       Pin /OE        : External bus output enable, /OE\r
+       Pin /TA        : External bus transfer acknowledge, /TA\r
+       Pin /TEA       : External bus transfer error acknowledge, /TEA\r
+       Pin R/W        : External bus read/write indication, R/W\r
+       Pin TSIZ1      : External bus transfer size TSIZ1 or DMA acknowledge /DACK1\r
+       Pin TSIZ0      : External bus transfer size TSIZ0 or DMA acknowledge /DACK0\r
+       Pin /TS        : External bus transfer start, /TS\r
+       Pin /TIP       : External bus transfer in progess, /TIP\r
+     */\r
+    MCF_GPIO_PDDR_BUSCTL = 0;\r
+    MCF_GPIO_PAR_BUSCTL =\r
+        MCF_GPIO_PAR_BUSCTL_PAR_OE | MCF_GPIO_PAR_BUSCTL_PAR_TA |\r
+        MCF_GPIO_PAR_BUSCTL_PAR_TEA( 0x3 ) | MCF_GPIO_PAR_BUSCTL_PAR_RWB |\r
+        MCF_GPIO_PAR_BUSCTL_PAR_TSIZ1 | MCF_GPIO_PAR_BUSCTL_PAR_TSIZ0 |\r
+        MCF_GPIO_PAR_BUSCTL_PAR_TS( 0x3 ) |\r
+        MCF_GPIO_PAR_BUSCTL_PAR_TIP( 0x3 );\r
+\r
+    /* Pin assignments for port BS\r
+       Pin /BS3       : External byte strobe /BS3\r
+       Pin /BS2       : External byte strobe /BS2\r
+       Pin /BS1       : External byte strobe /BS1\r
+       Pin /BS0       : External byte strobe /BS0\r
+     */\r
+    MCF_GPIO_PDDR_BS = 0;\r
+    MCF_GPIO_PAR_BS =\r
+        MCF_GPIO_PAR_BS_PAR_BS3 | MCF_GPIO_PAR_BS_PAR_BS2 |\r
+        MCF_GPIO_PAR_BS_PAR_BS1 | MCF_GPIO_PAR_BS_PAR_BS0;\r
+\r
+    /* Pin assignments for port CS\r
+       Pin /CS7       : Chip select /CS7\r
+       Pin /CS6       : Chip select /CS6\r
+       Pin /CS5       : Chip select /CS5\r
+       Pin /CS4       : Chip select /CS4\r
+       Pin /CS3       : Chip select /CS3\r
+       Pin /CS2       : Chip select /CS2\r
+       Pin /CS1       : Chip select /CS1\r
+     */\r
+    MCF_GPIO_PDDR_CS = 0;\r
+    MCF_GPIO_PAR_CS =\r
+        MCF_GPIO_PAR_CS_PAR_CS7 | MCF_GPIO_PAR_CS_PAR_CS6 |\r
+        MCF_GPIO_PAR_CS_PAR_CS5 | MCF_GPIO_PAR_CS_PAR_CS4 |\r
+        MCF_GPIO_PAR_CS_PAR_CS3 | MCF_GPIO_PAR_CS_PAR_CS2 |\r
+        MCF_GPIO_PAR_CS_PAR_CS1;\r
+\r
+    /* Pin assignments for port SDRAM\r
+       Pin /SD_WE     : SDRAM controller /SD_WE\r
+       Pin /SD_SCAS   : SDRAM controller /SD_SCAS\r
+       Pin /SD_SRAS   : SDRAM controller /SD_SRAS\r
+       Pin /SD_SCKE   : SDRAM controller /SD_SCKE\r
+       Pin /SD_CS1    : SDRAM controller /SD_CS1\r
+       Pin /SD_CS0    : SDRAM controller /SD_CS0\r
+     */\r
+    MCF_GPIO_PDDR_SDRAM = 0;\r
+    MCF_GPIO_PAR_SDRAM =\r
+        MCF_GPIO_PAR_SDRAM_PAR_SDWE | MCF_GPIO_PAR_SDRAM_PAR_SCAS |\r
+        MCF_GPIO_PAR_SDRAM_PAR_SRAS | MCF_GPIO_PAR_SDRAM_PAR_SCKE |\r
+        MCF_GPIO_PAR_SDRAM_PAR_SDCS1 | MCF_GPIO_PAR_SDRAM_PAR_SDCS0;\r
+\r
+    /* Pin assignments for port FECI2C\r
+       Pins are all GPIO inputs\r
+     */\r
+    MCF_GPIO_PDDR_FECI2C = 0;\r
+    MCF_GPIO_PAR_FECI2C =\r
+        MCF_GPIO_PAR_FECI2C_PAR_EMDC_FEC | MCF_GPIO_PAR_FECI2C_PAR_EMDIO_FEC;\r
+\r
+    /* Pin assignments for port UARTL\r
+       Pins are all GPIO inputs\r
+     */\r
+    MCF_GPIO_PDDR_UARTL = 0;\r
+    MCF_GPIO_PAR_UART = 0;\r
+\r
+    /* Pin assignments for port UARTH\r
+       Pin U2TXD      : GPIO input\r
+       Pin U2RXD      : GPIO input\r
+       Pin /IRQ2      : Interrupt request /IRQ2 or GPIO\r
+     */\r
+    MCF_GPIO_PDDR_UARTH = 0;\r
+\r
+    /* Pin assignments for port QSPI\r
+       Pins are all GPIO inputs\r
+     */\r
+    MCF_GPIO_PDDR_QSPI = 0;\r
+    MCF_GPIO_PAR_QSPI = 0;\r
+\r
+    /* Pin assignments for port TIMER\r
+       Pins are all GPIO inputs\r
+     */\r
+    MCF_GPIO_PDDR_TIMER = 0;\r
+    MCF_GPIO_PAR_TIMER = 0;\r
+\r
+    /* Pin assignments for port ETPU\r
+       Pins are all GPIO inputs\r
+     */\r
+    MCF_GPIO_PDDR_ETPU = 0;\r
+    MCF_GPIO_PAR_ETPU = 0;\r
+}\r
index a31e8c918bf2c7a735a7f923a762e550063c6159..1626a9d600b7578da9a2b06f8a5c7989f85cf6e2 100644 (file)
-/*
-    FreeRTOS MCF5235 port - Copyright (C) 2006 Christian Walter.
-
-    This file is part of the FreeRTOS distribution.
-
-    FreeRTOS is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    FreeRTOS is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with FreeRTOS; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-    A special exception to the GPL can be applied should you wish to distribute
-    a combined work that includes FreeRTOS, without being obliged to provide
-    the source code for any proprietary components.  See the licensing section
-    of http://www.FreeRTOS.org for full details of how and when the exception
-    can be applied.
-
-    ***************************************************************************
-    See http://www.FreeRTOS.org for documentation, latest information, license
-    and contact details.  Please ensure to read the configuration and relevant
+/*\r
+    FreeRTOS MCF5235 port - Copyright (C) 2006 Christian Walter.\r
+\r
+    This file is part of the FreeRTOS distribution.\r
+\r
+    FreeRTOS is free software; you can redistribute it and/or modify\r
+    it under the terms of the GNU General Public License as published by\r
+    the Free Software Foundation; either version 2 of the License, or\r
+    (at your option) any later version.\r
+\r
+    FreeRTOS is distributed in the hope that it will be useful,\r
+    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+    GNU General Public License for more details.\r
+\r
+    You should have received a copy of the GNU General Public License\r
+    along with FreeRTOS; if not, write to the Free Software\r
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+\r
+    A special exception to the GPL can be applied should you wish to distribute\r
+    a combined work that includes FreeRTOS, without being obliged to provide\r
+    the source code for any proprietary components.  See the licensing section\r
+    of http://www.FreeRTOS.org for full details of how and when the exception\r
+    can be applied.\r
+\r
+    ***************************************************************************\r
+    See http://www.FreeRTOS.org for documentation, latest information, license\r
+    and contact details.  Please ensure to read the configuration and relevant\r
     port sections of the online documentation.\r
 \r
        Also see http://www.SafeRTOS.com for an IEC 61508 compliant version along\r
-       with commercial development and support options.
-    ***************************************************************************
-*/
-
-/* ------------------------ System includes ------------------------------- */
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <errno.h>
-
-/* ------------------------ FreeRTOS includes ----------------------------- */
-#include <FreeRTOS.h>
-#include <serial.h>
-
-/* ------------------------ Prototypes ------------------------------------ */
-void vSerialPutStringNOISR( xComPortHandle pxPort,
-                            const signed portCHAR * const pcString,
-                            unsigned portSHORT usStringLength );
-
-/* ------------------------ Start implementation -------------------------- */
-void
-_exit( int status )
-{
-    asm volatile    ( "halt" );
-
-    for( ;; );
-}
-
-pid_t
-getpid( void )
-{
-    return 0;
-}
-
-int
-kill( pid_t pid, int sig )
-{
-    _exit( 0 );
-}
-
-int
-close( int fd )
-{
-    return 0;
-}
-
-int
-fstat( int fd, struct stat *buf )
-{
-    buf->st_mode = S_IFCHR;
-    buf->st_blksize = 0;
-    return 0;
-}
-
-ssize_t
-write( int fd, const void *buf, size_t nbytes )
-{
-    ssize_t res = nbytes;
-    extern xComPortHandle xSTDComPort;
-    switch ( fd )
-    {
-        case STDERR_FILENO:
-            vSerialPutStringNOISR( xSTDComPort,
-                                   ( const signed portCHAR * const )buf,
-                                   ( unsigned portSHORT )nbytes );
-            break;
-        case STDOUT_FILENO:
-            vSerialPutString( xSTDComPort,
-                              ( const signed portCHAR * const)buf,
-                              ( unsigned portSHORT )nbytes );
-            break;
-        default:
-            errno = EIO;
-            res = -1;
-            break;
-    }
-    return res;
-}
-
-int
-read( int fd, void *buf, size_t nbytes )
-{
-    switch ( fd )
-    {
-        default:
-            errno = EIO;
-            return -1;
-    }
-}
-
-int
-isatty( int fd )
-{
-    return 0;
-}
-
-off_t
-lseek( int fd, off_t offset, int whence )
-{
-    errno = EIO;
-    return ( off_t ) - 1;
-}
-
-extern char     _end[];
-char           *heap_ptr;
-
-void           *
-sbrk( ptrdiff_t nbytes )
-{
-    char           *base;
-
-    if( !heap_ptr )
-        heap_ptr = ( char * )&_end;
-    base = heap_ptr;
-    heap_ptr += nbytes;
-
-    return base;
-}
+       with commercial development and support options.\r
+    ***************************************************************************\r
+*/\r
+\r
+/* ------------------------ System includes ------------------------------- */\r
+#include <sys/types.h>\r
+#include <sys/stat.h>\r
+#include <unistd.h>\r
+#include <errno.h>\r
+\r
+/* ------------------------ FreeRTOS includes ----------------------------- */\r
+#include <FreeRTOS.h>\r
+#include <serial.h>\r
+\r
+/* ------------------------ Prototypes ------------------------------------ */\r
+void vSerialPutStringNOISR( xComPortHandle pxPort,\r
+                            const signed portCHAR * const pcString,\r
+                            unsigned portSHORT usStringLength );\r
+\r
+/* ------------------------ Start implementation -------------------------- */\r
+void\r
+_exit( int status )\r
+{\r
+    asm volatile    ( "halt" );\r
+\r
+    for( ;; );\r
+}\r
+\r
+pid_t\r
+getpid( void )\r
+{\r
+    return 0;\r
+}\r
+\r
+int\r
+kill( pid_t pid, int sig )\r
+{\r
+    _exit( 0 );\r
+}\r
+\r
+int\r
+close( int fd )\r
+{\r
+    return 0;\r
+}\r
+\r
+int\r
+fstat( int fd, struct stat *buf )\r
+{\r
+    buf->st_mode = S_IFCHR;\r
+    buf->st_blksize = 0;\r
+    return 0;\r
+}\r
+\r
+ssize_t\r
+write( int fd, const void *buf, size_t nbytes )\r
+{\r
+    ssize_t res = nbytes;\r
+    extern xComPortHandle xSTDComPort;\r
+    switch ( fd )\r
+    {\r
+        case STDERR_FILENO:\r
+            vSerialPutStringNOISR( xSTDComPort,\r
+                                   ( const signed portCHAR * const )buf,\r
+                                   ( unsigned portSHORT )nbytes );\r
+            break;\r
+        case STDOUT_FILENO:\r
+            vSerialPutString( xSTDComPort,\r
+                              ( const signed portCHAR * const)buf,\r
+                              ( unsigned portSHORT )nbytes );\r
+            break;\r
+        default:\r
+            errno = EIO;\r
+            res = -1;\r
+            break;\r
+    }\r
+    return res;\r
+}\r
+\r
+int\r
+read( int fd, void *buf, size_t nbytes )\r
+{\r
+    switch ( fd )\r
+    {\r
+        default:\r
+            errno = EIO;\r
+            return -1;\r
+    }\r
+}\r
+\r
+int\r
+isatty( int fd )\r
+{\r
+    return 0;\r
+}\r
+\r
+off_t\r
+lseek( int fd, off_t offset, int whence )\r
+{\r
+    errno = EIO;\r
+    return ( off_t ) - 1;\r
+}\r
+\r
+extern char     _end[];\r
+char           *heap_ptr;\r
+\r
+void           *\r
+sbrk( ptrdiff_t nbytes )\r
+{\r
+    char           *base;\r
+\r
+    if( !heap_ptr )\r
+        heap_ptr = ( char * )&_end;\r
+    base = heap_ptr;\r
+    heap_ptr += nbytes;\r
+\r
+    return base;\r
+}\r
index de74f81efd19893901cdd98b435c1e5ff76ff27d..ef10d7aa90f2dfc3eef5597795839153662582f5 100644 (file)
-/*
-    FreeRTOS MCF5235 port - Copyright (C) 2006 Christian Walter.
-
-    This file is part of the FreeRTOS distribution.
-
-    FreeRTOS is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    FreeRTOS is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with FreeRTOS; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-    A special exception to the GPL can be applied should you wish to distribute
-    a combined work that includes FreeRTOS, without being obliged to provide
-    the source code for any proprietary components.  See the licensing section
-    of http://www.FreeRTOS.org for full details of how and when the exception
-    can be applied.
-
-    ***************************************************************************
-    See http://www.FreeRTOS.org for documentation, latest information, license
-    and contact details.  Please ensure to read the configuration and relevant
+/*\r
+    FreeRTOS MCF5235 port - Copyright (C) 2006 Christian Walter.\r
+\r
+    This file is part of the FreeRTOS distribution.\r
+\r
+    FreeRTOS is free software; you can redistribute it and/or modify\r
+    it under the terms of the GNU General Public License as published by\r
+    the Free Software Foundation; either version 2 of the License, or\r
+    (at your option) any later version.\r
+\r
+    FreeRTOS is distributed in the hope that it will be useful,\r
+    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+    GNU General Public License for more details.\r
+\r
+    You should have received a copy of the GNU General Public License\r
+    along with FreeRTOS; if not, write to the Free Software\r
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+\r
+    A special exception to the GPL can be applied should you wish to distribute\r
+    a combined work that includes FreeRTOS, without being obliged to provide\r
+    the source code for any proprietary components.  See the licensing section\r
+    of http://www.FreeRTOS.org for full details of how and when the exception\r
+    can be applied.\r
+\r
+    ***************************************************************************\r
+    See http://www.FreeRTOS.org for documentation, latest information, license\r
+    and contact details.  Please ensure to read the configuration and relevant\r
     port sections of the online documentation.\r
 \r
        Also see http://www.SafeRTOS.com for an IEC 61508 compliant version along\r
-       with commercial development and support options.
-    ***************************************************************************
-*/
-
-/* ------------------------ MCF523x includes ------------------------------ */
-#include "mcf5xxx.h"
-#include "mcf523x.h"
-
-/* ------------------------ FreeRTOS includes ----------------------------- */
-#include "FreeRTOS.h"
-#include "queue.h"
-#include "task.h"
-
-#include "serial.h"
-
-/* ----------------------- Defines ----------------------------------------- */
-#define BAUDRATE_VALUE(fsys, baud)      ( ( fsys )/(32UL * baud) )
-#define MCF_UART_VECTOR                 ( 64 + 13 )
-#define COM_NIFACE                      1
-#define COM_BLOCK_RETRYTIME             10
-
-/* ------------------------ Static functions ------------------------------ */
-static void     prvSerialISR( void );
-
-/* ------------------------ Static variables ------------------------------ */
-typedef struct
-{
-    portBASE_TYPE xInitialized;
-    xQueueHandle xRXChars;
-    xQueueHandle xTXChars;
-} xComPortIF_t;
-
-static xComPortIF_t xComPortIF[ COM_NIFACE ];
-
-/* ------------------------ Begin implementation -------------------------- */
-xComPortHandle
-xSerialPortInitMinimal( unsigned portLONG ulWantedBaud,
-                        unsigned portBASE_TYPE uxQueueLength )
-{
-    extern void     ( *__RAMVEC[] ) (  );
-    xComPortHandle xReturn;
-    portBASE_TYPE xOldIPL;
-
-    /* Create the queues used to hold Rx and Tx characters. */
-    xComPortIF[ 0 ].xRXChars =
-        xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE )sizeof( signed portCHAR ) );
-    xComPortIF[ 0 ].xTXChars =
-        xQueueCreate( uxQueueLength + 1, ( unsigned portBASE_TYPE )sizeof( signed portCHAR ) );
-
-    /* If the queues were created correctly then setup the serial port hardware. */
-    if( ( xComPortIF[ 0 ].xRXChars != 0 ) && ( xComPortIF[ 0 ].xTXChars != 0 ) )
-    {
-        xOldIPL = portSET_IPL( portIPL_MAX );
-
-        /* UART 0: Reset transmitter, receiver and mode register pointer */
-        MCF_UART_UCR0 = MCF_UART_UCR_MISC( 0x3 );
-        MCF_UART_UCR0 = MCF_UART_UCR_MISC( 0x2 );
-        MCF_UART_UCR0 = MCF_UART_UCR_MISC( 0x1 );
-
-        /* Enable receive interrupts. */
-        MCF_UART_UIMR0 = MCF_UART_UIMR_RXRDY_FU;
-
-        /* 8 Databits, 1 Stopbit and no parity */
-        MCF_UART_UMR0 = MCF_UART_UMR_PM( 0x3 ) | MCF_UART_UMR_SB( 0x7 ) | MCF_UART_UMR_BC( 0x3 );
-
-        /* UART 0 Clocking */
-        MCF_UART_UCSR0 = MCF_UART_UCSR_RCS( 0xd ) | MCF_UART_UCSR_TCS( 0xd );
-        MCF_UART_UBG10 = BAUDRATE_VALUE( FSYS_2, ulWantedBaud ) >> 8U;
-        MCF_UART_UBG20 = BAUDRATE_VALUE( FSYS_2, ulWantedBaud ) & 0xFFU;
-
-        /* UART 0: Enable interrupts */
-        __RAMVEC[MCF_UART_VECTOR] = prvSerialISR;
-        MCF_INTC0_ICR13 = MCF_INTC0_ICRn_IL( 0x2 ) | MCF_INTC0_ICRn_IP( 0x1 );
-        MCF_INTC0_IMRL &= ~MCF_INTC0_IMRL_INT_MASK13;
-
-        /* UART 0 Miscellaneous */
-        MCF_UART_UACR0 = 0;
-
-        /* UART 0: Enable pins */
-        MCF_GPIO_PAR_UART = MCF_GPIO_PAR_UART_PAR_U0RXD | MCF_GPIO_PAR_UART_PAR_U0TXD;
-
-        /* Enable the UART. */
-        MCF_UART_UCR0 = MCF_UART_UCR_RXC( 0x1 ) | MCF_UART_UCR_TXC( 0x1 );
-
-        xComPortIF[ 0 ].xInitialized = TRUE;
-        xReturn = ( xComPortHandle ) &xComPortIF[ 0 ];
-
-        ( void )portSET_IPL( xOldIPL );
-    }
-    else
-    {
-        xReturn = ( xComPortHandle ) 0;
-    }
-
-    return xReturn;
-}
-
-signed          portBASE_TYPE
-xSerialGetChar( xComPortHandle pxPort, signed portCHAR * pcRxedChar,
-                portTickType xBlockTime )
-{
-    int i;
-    portBASE_TYPE xResult = pdFALSE;
-    /* Lookup the correct interface. */
-    for( i = 0; i < COM_NIFACE; i++ )
-    {
-        if( pxPort == ( xComPortHandle ) &xComPortIF[ i ] )
-        {
-            break;
-        }
-    }
-    /* This COM port is available. */
-    if( ( i != COM_NIFACE ) && xComPortIF[ i ].xInitialized )
-    {
-        /* Get the next character from the buffer.  Return false if no characters
-         * are available, or arrive before xBlockTime expires.
-         */
-        if( xQueueReceive( xComPortIF[ i ].xRXChars, pcRxedChar, xBlockTime ) )
-        {
-            xResult = pdTRUE;
-        }
-    }
-    return xResult;
-}
-
-void
-vSerialPutString( xComPortHandle pxPort, const signed portCHAR *
-                  const pcString, unsigned portSHORT usStringLength )
-{
-    int i;
-    signed portCHAR *pChNext;
-
-    /* Send each character in the string, one at a time. */
-    pChNext = ( signed portCHAR * )pcString;
-    for( i = 0; i < usStringLength; i++ )
-    {
-        /* Block until character has been transmitted. */
-        while( xSerialPutChar( pxPort, *pChNext, COM_BLOCK_RETRYTIME ) != pdTRUE ); pChNext++;
-    }
-}
-
-signed          portBASE_TYPE
-xSerialPutChar( xComPortHandle pxPort, signed portCHAR cOutChar,
-                portTickType xBlockTime )
-{
-    int i;
-    portBASE_TYPE xResult = pdFALSE;
-    portBASE_TYPE xOldIPL;
-    /* Lookup the correct interface. */
-    for( i = 0; i < COM_NIFACE; i++ )
-    {
-        if( pxPort == ( xComPortHandle ) &xComPortIF[ i ] )
-        {
-            break;
-        }
-    }
-    /* This COM port is available. */
-    if( ( i != COM_NIFACE ) && xComPortIF[ i ].xInitialized )
-    {
-        /* Place the character in the queue of characters to be transmitted. */
-        if( xQueueSend( xComPortIF[ i ].xTXChars, &cOutChar, xBlockTime ) == pdPASS )
-        {
-            /* Turn on the Tx interrupt so the ISR will remove the character from the
-             * queue and send it. */
-            MCF_UART_UIMR0 = MCF_UART_UIMR_TXRDY | MCF_UART_UIMR_RXRDY_FU;
-            xResult = pdTRUE;
-        }
-    }
-    return xResult;
-}
-
-signed          portBASE_TYPE
-xSerialPutCharNOISR( xComPortHandle pxPort, signed portCHAR cOutChar )
-{
-    int i;
-    portBASE_TYPE xResult = pdFALSE;
-    portBASE_TYPE xOldIPL = portSET_IPL( portIPL_MAX );
-    /* Lookup the correct interface. */
-    for( i = 0; i < COM_NIFACE; i++ )
-    {
-        if( pxPort == ( xComPortHandle ) &xComPortIF[ i ] )
-        {
-            break;
-        }
-    }
-    /* This COM port is available. Support for this only available for COM1 right now. */
-    if( ( i != COM_NIFACE ) && ( i == 0 ) )
-    {
-        /* Wait until the transmit buffer is ready. */
-        while( !( MCF_UART_USR0 & MCF_UART_USR_TXRDY ) );
-        /* Place the character in the transmit buffer. */
-        MCF_UART_UTB0 = cOutChar;
-        xResult = pdTRUE;
-    }
-    ( void )portSET_IPL( xOldIPL );
-    return xResult;
-}
-
-void
-vSerialPutStringNOISR( xComPortHandle pxPort, const signed portCHAR *
-                       const pcString, unsigned portSHORT usStringLength )
-{
-    int i;
-    signed portCHAR *pChNext;
-    portBASE_TYPE xOldIPL = portSET_IPL( portIPL_MAX );
-
-    /* Send each character in the string, one at a time. */
-    pChNext = ( signed portCHAR * )pcString;
-    for( i = 0; i < usStringLength; i++ )
-    {
-        /* Block until character has been transmitted. */
-        while( xSerialPutCharNOISR( pxPort, *pChNext ) != pdTRUE );
-        pChNext++;
-    }
-    ( void )portSET_IPL( xOldIPL );
-}
-
-void
-vSerialClose( xComPortHandle xPort )
-{
-    /* Not supported as not required by the demo application. */
-}
-
-void
-prvSerialISR( void )
-{
-    static signed portCHAR cChar;
-    static portBASE_TYPE xTaskWokenByTx = pdFALSE, xTaskWokenByRx = pdFALSE;
-
-    /* We have to remvoe the effect of the GCC. Please note that the
-     * __attribute__ ((interrupt_handler)) does not work here because we
-     * have to do the storing of the registers ourself. Another problem
-     * is the usage of a frame pointer which is unlinked on entry.
-     */
-#if _GCC_USES_FP == 1
-    asm volatile ( "unlk %fp\n\t" );
-#endif
-    /* This ISR can cause a context switch, so the first statement must be
-     * a call to the portENTER_SWITCHING_ISR() macro. This must be BEFORE any
-     * variable declarations.
-     */
-    portENTER_SWITCHING_ISR();
-
-    /* Ready to send a character from the buffer. */
-    if( MCF_UART_USR0 & MCF_UART_USR_TXRDY )
-    {
-        /* Transmit buffer is ready. Test if there are characters available. */
-        if( xQueueReceiveFromISR( xComPortIF[ 0 ].xTXChars, &cChar, &xTaskWokenByTx ) ==
-            pdTRUE )
-        {
-            /* A character was retrieved from the queue so can be sent. */
-            MCF_UART_UTB0 = cChar;
-        }
-        else
-        {
-            /* Leave only receiver enabled. */
-            MCF_UART_UIMR0 = MCF_UART_UIMR_RXRDY_FU;
-        }
-    }
-    if( MCF_UART_USR0 & MCF_UART_USR_RXRDY )
-    {
-        cChar = MCF_UART_URB0;
-        xTaskWokenByRx =
-            xQueueSendFromISR( xComPortIF[ 0].xRXChars, &cChar, xTaskWokenByRx );
-    }
-    /* Exit the ISR.  If a task was woken by either a character being
-     * or transmitted then a context switch will occur.
-     */
-    portEXIT_SWITCHING_ISR( ( xTaskWokenByTx || xTaskWokenByRx ) );
-}
+       with commercial development and support options.\r
+    ***************************************************************************\r
+*/\r
+\r
+/* ------------------------ MCF523x includes ------------------------------ */\r
+#include "mcf5xxx.h"\r
+#include "mcf523x.h"\r
+\r
+/* ------------------------ FreeRTOS includes ----------------------------- */\r
+#include "FreeRTOS.h"\r
+#include "queue.h"\r
+#include "task.h"\r
+\r
+#include "serial.h"\r
+\r
+/* ----------------------- Defines ----------------------------------------- */\r
+#define BAUDRATE_VALUE(fsys, baud)      ( ( fsys )/(32UL * baud) )\r
+#define MCF_UART_VECTOR                 ( 64 + 13 )\r
+#define COM_NIFACE                      1\r
+#define COM_BLOCK_RETRYTIME             10\r
+\r
+/* ------------------------ Static functions ------------------------------ */\r
+static void     prvSerialISR( void );\r
+\r
+/* ------------------------ Static variables ------------------------------ */\r
+typedef struct\r
+{\r
+    portBASE_TYPE xInitialized;\r
+    xQueueHandle xRXChars;\r
+    xQueueHandle xTXChars;\r
+} xComPortIF_t;\r
+\r
+static xComPortIF_t xComPortIF[ COM_NIFACE ];\r
+\r
+/* ------------------------ Begin implementation -------------------------- */\r
+xComPortHandle\r
+xSerialPortInitMinimal( unsigned portLONG ulWantedBaud,\r
+                        unsigned portBASE_TYPE uxQueueLength )\r
+{\r
+    extern void     ( *__RAMVEC[] ) (  );\r
+    xComPortHandle xReturn;\r
+    portBASE_TYPE xOldIPL;\r
+\r
+    /* Create the queues used to hold Rx and Tx characters. */\r
+    xComPortIF[ 0 ].xRXChars =\r
+        xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE )sizeof( signed portCHAR ) );\r
+    xComPortIF[ 0 ].xTXChars =\r
+        xQueueCreate( uxQueueLength + 1, ( unsigned portBASE_TYPE )sizeof( signed portCHAR ) );\r
+\r
+    /* If the queues were created correctly then setup the serial port hardware. */\r
+    if( ( xComPortIF[ 0 ].xRXChars != 0 ) && ( xComPortIF[ 0 ].xTXChars != 0 ) )\r
+    {\r
+        xOldIPL = portSET_IPL( portIPL_MAX );\r
+\r
+        /* UART 0: Reset transmitter, receiver and mode register pointer */\r
+        MCF_UART_UCR0 = MCF_UART_UCR_MISC( 0x3 );\r
+        MCF_UART_UCR0 = MCF_UART_UCR_MISC( 0x2 );\r
+        MCF_UART_UCR0 = MCF_UART_UCR_MISC( 0x1 );\r
+\r
+        /* Enable receive interrupts. */\r
+        MCF_UART_UIMR0 = MCF_UART_UIMR_RXRDY_FU;\r
+\r
+        /* 8 Databits, 1 Stopbit and no parity */\r
+        MCF_UART_UMR0 = MCF_UART_UMR_PM( 0x3 ) | MCF_UART_UMR_SB( 0x7 ) | MCF_UART_UMR_BC( 0x3 );\r
+\r
+        /* UART 0 Clocking */\r
+        MCF_UART_UCSR0 = MCF_UART_UCSR_RCS( 0xd ) | MCF_UART_UCSR_TCS( 0xd );\r
+        MCF_UART_UBG10 = BAUDRATE_VALUE( FSYS_2, ulWantedBaud ) >> 8U;\r
+        MCF_UART_UBG20 = BAUDRATE_VALUE( FSYS_2, ulWantedBaud ) & 0xFFU;\r
+\r
+        /* UART 0: Enable interrupts */\r
+        __RAMVEC[MCF_UART_VECTOR] = prvSerialISR;\r
+        MCF_INTC0_ICR13 = MCF_INTC0_ICRn_IL( 0x2 ) | MCF_INTC0_ICRn_IP( 0x1 );\r
+        MCF_INTC0_IMRL &= ~MCF_INTC0_IMRL_INT_MASK13;\r
+\r
+        /* UART 0 Miscellaneous */\r
+        MCF_UART_UACR0 = 0;\r
+\r
+        /* UART 0: Enable pins */\r
+        MCF_GPIO_PAR_UART = MCF_GPIO_PAR_UART_PAR_U0RXD | MCF_GPIO_PAR_UART_PAR_U0TXD;\r
+\r
+        /* Enable the UART. */\r
+        MCF_UART_UCR0 = MCF_UART_UCR_RXC( 0x1 ) | MCF_UART_UCR_TXC( 0x1 );\r
+\r
+        xComPortIF[ 0 ].xInitialized = TRUE;\r
+        xReturn = ( xComPortHandle ) &xComPortIF[ 0 ];\r
+\r
+        ( void )portSET_IPL( xOldIPL );\r
+    }\r
+    else\r
+    {\r
+        xReturn = ( xComPortHandle ) 0;\r
+    }\r
+\r
+    return xReturn;\r
+}\r
+\r
+signed          portBASE_TYPE\r
+xSerialGetChar( xComPortHandle pxPort, signed portCHAR * pcRxedChar,\r
+                portTickType xBlockTime )\r
+{\r
+    int i;\r
+    portBASE_TYPE xResult = pdFALSE;\r
+    /* Lookup the correct interface. */\r
+    for( i = 0; i < COM_NIFACE; i++ )\r
+    {\r
+        if( pxPort == ( xComPortHandle ) &xComPortIF[ i ] )\r
+        {\r
+            break;\r
+        }\r
+    }\r
+    /* This COM port is available. */\r
+    if( ( i != COM_NIFACE ) && xComPortIF[ i ].xInitialized )\r
+    {\r
+        /* Get the next character from the buffer.  Return false if no characters\r
+         * are available, or arrive before xBlockTime expires.\r
+         */\r
+        if( xQueueReceive( xComPortIF[ i ].xRXChars, pcRxedChar, xBlockTime ) )\r
+        {\r
+            xResult = pdTRUE;\r
+        }\r
+    }\r
+    return xResult;\r
+}\r
+\r
+void\r
+vSerialPutString( xComPortHandle pxPort, const signed portCHAR *\r
+                  const pcString, unsigned portSHORT usStringLength )\r
+{\r
+    int i;\r
+    signed portCHAR *pChNext;\r
+\r
+    /* Send each character in the string, one at a time. */\r
+    pChNext = ( signed portCHAR * )pcString;\r
+    for( i = 0; i < usStringLength; i++ )\r
+    {\r
+        /* Block until character has been transmitted. */\r
+        while( xSerialPutChar( pxPort, *pChNext, COM_BLOCK_RETRYTIME ) != pdTRUE ); pChNext++;\r
+    }\r
+}\r
+\r
+signed          portBASE_TYPE\r
+xSerialPutChar( xComPortHandle pxPort, signed portCHAR cOutChar,\r
+                portTickType xBlockTime )\r
+{\r
+    int i;\r
+    portBASE_TYPE xResult = pdFALSE;\r
+    portBASE_TYPE xOldIPL;\r
+    /* Lookup the correct interface. */\r
+    for( i = 0; i < COM_NIFACE; i++ )\r
+    {\r
+        if( pxPort == ( xComPortHandle ) &xComPortIF[ i ] )\r
+        {\r
+            break;\r
+        }\r
+    }\r
+    /* This COM port is available. */\r
+    if( ( i != COM_NIFACE ) && xComPortIF[ i ].xInitialized )\r
+    {\r
+        /* Place the character in the queue of characters to be transmitted. */\r
+        if( xQueueSend( xComPortIF[ i ].xTXChars, &cOutChar, xBlockTime ) == pdPASS )\r
+        {\r
+            /* Turn on the Tx interrupt so the ISR will remove the character from the\r
+             * queue and send it. */\r
+            MCF_UART_UIMR0 = MCF_UART_UIMR_TXRDY | MCF_UART_UIMR_RXRDY_FU;\r
+            xResult = pdTRUE;\r
+        }\r
+    }\r
+    return xResult;\r
+}\r
+\r
+signed          portBASE_TYPE\r
+xSerialPutCharNOISR( xComPortHandle pxPort, signed portCHAR cOutChar )\r
+{\r
+    int i;\r
+    portBASE_TYPE xResult = pdFALSE;\r
+    portBASE_TYPE xOldIPL = portSET_IPL( portIPL_MAX );\r
+    /* Lookup the correct interface. */\r
+    for( i = 0; i < COM_NIFACE; i++ )\r
+    {\r
+        if( pxPort == ( xComPortHandle ) &xComPortIF[ i ] )\r
+        {\r
+            break;\r
+        }\r
+    }\r
+    /* This COM port is available. Support for this only available for COM1 right now. */\r
+    if( ( i != COM_NIFACE ) && ( i == 0 ) )\r
+    {\r
+        /* Wait until the transmit buffer is ready. */\r
+        while( !( MCF_UART_USR0 & MCF_UART_USR_TXRDY ) );\r
+        /* Place the character in the transmit buffer. */\r
+        MCF_UART_UTB0 = cOutChar;\r
+        xResult = pdTRUE;\r
+    }\r
+    ( void )portSET_IPL( xOldIPL );\r
+    return xResult;\r
+}\r
+\r
+void\r
+vSerialPutStringNOISR( xComPortHandle pxPort, const signed portCHAR *\r
+                       const pcString, unsigned portSHORT usStringLength )\r
+{\r
+    int i;\r
+    signed portCHAR *pChNext;\r
+    portBASE_TYPE xOldIPL = portSET_IPL( portIPL_MAX );\r
+\r
+    /* Send each character in the string, one at a time. */\r
+    pChNext = ( signed portCHAR * )pcString;\r
+    for( i = 0; i < usStringLength; i++ )\r
+    {\r
+        /* Block until character has been transmitted. */\r
+        while( xSerialPutCharNOISR( pxPort, *pChNext ) != pdTRUE );\r
+        pChNext++;\r
+    }\r
+    ( void )portSET_IPL( xOldIPL );\r
+}\r
+\r
+void\r
+vSerialClose( xComPortHandle xPort )\r
+{\r
+    /* Not supported as not required by the demo application. */\r
+}\r
+\r
+void\r
+prvSerialISR( void )\r
+{\r
+    static signed portCHAR cChar;\r
+    static portBASE_TYPE xTaskWokenByTx = pdFALSE, xTaskWokenByRx = pdFALSE;\r
+\r
+    /* We have to remvoe the effect of the GCC. Please note that the\r
+     * __attribute__ ((interrupt_handler)) does not work here because we\r
+     * have to do the storing of the registers ourself. Another problem\r
+     * is the usage of a frame pointer which is unlinked on entry.\r
+     */\r
+#if _GCC_USES_FP == 1\r
+    asm volatile ( "unlk %fp\n\t" );\r
+#endif\r
+    /* This ISR can cause a context switch, so the first statement must be\r
+     * a call to the portENTER_SWITCHING_ISR() macro. This must be BEFORE any\r
+     * variable declarations.\r
+     */\r
+    portENTER_SWITCHING_ISR();\r
+\r
+    /* Ready to send a character from the buffer. */\r
+    if( MCF_UART_USR0 & MCF_UART_USR_TXRDY )\r
+    {\r
+        /* Transmit buffer is ready. Test if there are characters available. */\r
+        if( xQueueReceiveFromISR( xComPortIF[ 0 ].xTXChars, &cChar, &xTaskWokenByTx ) ==\r
+            pdTRUE )\r
+        {\r
+            /* A character was retrieved from the queue so can be sent. */\r
+            MCF_UART_UTB0 = cChar;\r
+        }\r
+        else\r
+        {\r
+            /* Leave only receiver enabled. */\r
+            MCF_UART_UIMR0 = MCF_UART_UIMR_RXRDY_FU;\r
+        }\r
+    }\r
+    if( MCF_UART_USR0 & MCF_UART_USR_RXRDY )\r
+    {\r
+        cChar = MCF_UART_URB0;\r
+        xTaskWokenByRx =\r
+            xQueueSendFromISR( xComPortIF[ 0].xRXChars, &cChar, xTaskWokenByRx );\r
+    }\r
+    /* Exit the ISR.  If a task was woken by either a character being\r
+     * or transmitted then a context switch will occur.\r
+     */\r
+    portEXIT_SWITCHING_ISR( ( xTaskWokenByTx || xTaskWokenByRx ) );\r
+}\r
index fbc57db60e4df93a859ea88543d759a83d752db6..292c38657966ef77c175cbdbb8c533f0ef75aeae 100644 (file)
-/*
-    FreeRTOS V4.1.0 - copyright (C) 2003-2006 Richard Barry.
-
-    This file is part of the FreeRTOS distribution.
-
-    FreeRTOS is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    FreeRTOS is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with FreeRTOS; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-    A special exception to the GPL can be applied should you wish to distribute
-    a combined work that includes FreeRTOS, without being obliged to provide
-    the source code for any proprietary components.  See the licensing section
-    of http://www.FreeRTOS.org for full details of how and when the exception
-    can be applied.
-
-    ***************************************************************************
-    See http://www.FreeRTOS.org for documentation, latest information, license
-    and contact details.  Please ensure to read the configuration and relevant
+/*\r
+    FreeRTOS V4.1.0 - copyright (C) 2003-2006 Richard Barry.\r
+\r
+    This file is part of the FreeRTOS distribution.\r
+\r
+    FreeRTOS is free software; you can redistribute it and/or modify\r
+    it under the terms of the GNU General Public License as published by\r
+    the Free Software Foundation; either version 2 of the License, or\r
+    (at your option) any later version.\r
+\r
+    FreeRTOS is distributed in the hope that it will be useful,\r
+    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+    GNU General Public License for more details.\r
+\r
+    You should have received a copy of the GNU General Public License\r
+    along with FreeRTOS; if not, write to the Free Software\r
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+\r
+    A special exception to the GPL can be applied should you wish to distribute\r
+    a combined work that includes FreeRTOS, without being obliged to provide\r
+    the source code for any proprietary components.  See the licensing section\r
+    of http://www.FreeRTOS.org for full details of how and when the exception\r
+    can be applied.\r
+\r
+    ***************************************************************************\r
+    See http://www.FreeRTOS.org for documentation, latest information, license\r
+    and contact details.  Please ensure to read the configuration and relevant\r
     port sections of the online documentation.\r
 \r
        Also see http://www.SafeRTOS.com for an IEC 61508 compliant version along\r
-       with commercial development and support options.
-    ***************************************************************************
-*/
-
-/*
-    Implements a simplistic WEB server.  Every time a connection is made and
-    data is received a dynamic page that shows the current TCP/IP statistics
-    is generated and returned.  The connection is then closed.
-
-    This file was adapted from a FreeRTOS lwIP slip demo supplied by a third
-    party.
-*/
-
-/* ------------------------ System includes ------------------------------- */
-#include <stdio.h>
-#include <string.h>
-
-/* ------------------------ FreeRTOS includes ----------------------------- */
-#include "FreeRTOS.h"
-#include "task.h"
-#include "semphr.h"
-
-/* ------------------------ lwIP includes --------------------------------- */
-#include "lwip/api.h"
-#include "lwip/tcpip.h"
-#include "lwip/memp.h"
-#include "lwip/stats.h"
-#include "netif/loopif.h"
-
-/* ------------------------ Project includes ------------------------------ */
-#include "mcf5xxx.h"
-#include "mcf523x.h"
-#include "netif/fec.h"
-
-#include "web.h"
-
-/* ------------------------ Defines --------------------------------------- */
-/* The size of the buffer in which the dynamic WEB page is created. */
-#define webMAX_PAGE_SIZE        ( 2048 )
-
-/* Standard GET response. */
-#define webHTTP_OK  "HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n"
-
-/* The port on which we listen. */
-#define webHTTP_PORT            ( 80 )
-
-/* Delay on close error. */
-#define webSHORT_DELAY          ( 10 )
-
-/* Format of the dynamic page that is returned on each connection. */
-#define webHTML_START \
-"<html>\
-<head>\
-</head>\
-<BODY onLoad=\"window.setTimeout(&quot;location.href='index.html'&quot;,1000)\"bgcolor=\"#CCCCff\">\
-\r\nPage Hits = "
-
-#define webHTML_END \
-"\r\n" \
-"FreeRTOS MCF5235 port (c) 2006 by Christian Walter &lt;wolti@sil.at&gt;\r\n" \
-"</pre>\r\n" \
-"</BODY>\r\n" \
-"</html>"
-
-/* ------------------------ Prototypes ------------------------------------ */
-static void     vProcessConnection( struct netconn *pxNetCon );
-
-/*------------------------------------------------------------*/
-
-/*
- * Process an incoming connection on port 80.
- *
- * This simply checks to see if the incoming data contains a GET request, and
- * if so sends back a single dynamically created page.  The connection is then
- * closed.  A more complete implementation could create a task for each
- * connection.
- */
-static void
-vProcessConnection( struct netconn *pxNetCon )
-{
-    static portCHAR cDynamicPage[webMAX_PAGE_SIZE], cPageHits[11];
-    struct netbuf  *pxRxBuffer;
-    portCHAR       *pcRxString;
-    unsigned portSHORT usLength;
-    static unsigned portLONG ulPageHits = 0;
-
-    /* We expect to immediately get data. */
-    pxRxBuffer = netconn_recv( pxNetCon );
-
-    if( pxRxBuffer != NULL )
-    {
-        /* Where is the data? */
-        netbuf_data( pxRxBuffer, ( void * )&pcRxString, &usLength );
-
-        /* Is this a GET?  We don't handle anything else. */
-        if( !strncmp( pcRxString, "GET", 3 ) )
-        {
-            pcRxString = cDynamicPage;
-
-            /* Update the hit count. */
-            ulPageHits++;
-            sprintf( cPageHits, "%lu", ulPageHits );
-
-            /* Write out the HTTP OK header. */
-            netconn_write( pxNetCon, webHTTP_OK, ( u16_t ) strlen( webHTTP_OK ), NETCONN_COPY );
-
-            /* Generate the dynamic page...
-
-               ... First the page header. */
-            strcpy( cDynamicPage, webHTML_START );
-            /* ... Then the hit count... */
-            strcat( cDynamicPage, cPageHits );
-            strcat( cDynamicPage,
-                    "<p><pre>Task          State  Priority  Stack #<br>************************************************<br>" );
-            /* ... Then the list of tasks and their status... */
-            vTaskList( ( signed portCHAR * )cDynamicPage + strlen( cDynamicPage ) );
-            /* ... Finally the page footer. */
-            strcat( cDynamicPage, webHTML_END );
-
-            /* Write out the dynamically generated page. */
-            netconn_write( pxNetCon, cDynamicPage, ( u16_t ) strlen( cDynamicPage ), NETCONN_COPY );
-        }
-
-        netbuf_delete( pxRxBuffer );
-    }
-
-    netconn_close( pxNetCon );
-}
-
-/*------------------------------------------------------------*/
-
-void
-vlwIPInit( void )
-{
-    /* Initialize lwIP and its interface layer. */
-    sys_init(  );
-    mem_init(  );
-    memp_init(  );
-    pbuf_init(  );
-    netif_init(  );
-    ip_init(  );
-    tcpip_init( NULL, NULL );
-}
-
-/*------------------------------------------------------------*/
-
-void
-vBasicWEBServer( void *pvParameters )
-{
-    struct netconn *pxHTTPListener, *pxNewConnection;
-    struct ip_addr  xIpAddr, xNetMast, xGateway;
-    static struct netif fec523x_if;
-
-    /* Parameters are not used - suppress compiler error. */
-    ( void )pvParameters;
-
-    /* Create and configure the EMAC interface. */
-    IP4_ADDR( &xIpAddr, 10, 0, 10, 2 );
-    IP4_ADDR( &xNetMast, 255, 255, 255, 0 );
-    IP4_ADDR( &xGateway, 10, 0, 10, 1 );
-    netif_add( &fec523x_if, &xIpAddr, &xNetMast, &xGateway, NULL, mcf523xfec_init, tcpip_input );
-
-    /* make it the default interface */
-    netif_set_default( &fec523x_if );
-
-    /* bring it up */
-    netif_set_up( &fec523x_if );
-
-    /* Create a new tcp connection handle */
-    pxHTTPListener = netconn_new( NETCONN_TCP );
-    netconn_bind( pxHTTPListener, NULL, webHTTP_PORT );
-    netconn_listen( pxHTTPListener );
-
-    /* Loop forever */
-    for( ;; )
-    {
-        /* Wait for connection. */
-        pxNewConnection = netconn_accept( pxHTTPListener );
-
-        if( pxNewConnection != NULL )
-        {
-            /* Service connection. */
-            vProcessConnection( pxNewConnection );
-            while( netconn_delete( pxNewConnection ) != ERR_OK )
-            {
-                vTaskDelay( webSHORT_DELAY );
-            }
-        }
-    }
-}
+       with commercial development and support options.\r
+    ***************************************************************************\r
+*/\r
+\r
+/*\r
+    Implements a simplistic WEB server.  Every time a connection is made and\r
+    data is received a dynamic page that shows the current TCP/IP statistics\r
+    is generated and returned.  The connection is then closed.\r
+\r
+    This file was adapted from a FreeRTOS lwIP slip demo supplied by a third\r
+    party.\r
+*/\r
+\r
+/* ------------------------ System includes ------------------------------- */\r
+#include <stdio.h>\r
+#include <string.h>\r
+\r
+/* ------------------------ FreeRTOS includes ----------------------------- */\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+#include "semphr.h"\r
+\r
+/* ------------------------ lwIP includes --------------------------------- */\r
+#include "lwip/api.h"\r
+#include "lwip/tcpip.h"\r
+#include "lwip/memp.h"\r
+#include "lwip/stats.h"\r
+#include "netif/loopif.h"\r
+\r
+/* ------------------------ Project includes ------------------------------ */\r
+#include "mcf5xxx.h"\r
+#include "mcf523x.h"\r
+#include "netif/fec.h"\r
+\r
+#include "web.h"\r
+\r
+/* ------------------------ Defines --------------------------------------- */\r
+/* The size of the buffer in which the dynamic WEB page is created. */\r
+#define webMAX_PAGE_SIZE        ( 2048 )\r
+\r
+/* Standard GET response. */\r
+#define webHTTP_OK  "HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n"\r
+\r
+/* The port on which we listen. */\r
+#define webHTTP_PORT            ( 80 )\r
+\r
+/* Delay on close error. */\r
+#define webSHORT_DELAY          ( 10 )\r
+\r
+/* Format of the dynamic page that is returned on each connection. */\r
+#define webHTML_START \\r
+"<html>\\r
+<head>\\r
+</head>\\r
+<BODY onLoad=\"window.setTimeout(&quot;location.href='index.html'&quot;,1000)\"bgcolor=\"#CCCCff\">\\r
+\r\nPage Hits = "\r
+\r
+#define webHTML_END \\r
+"\r\n" \\r
+"FreeRTOS MCF5235 port (c) 2006 by Christian Walter &lt;wolti@sil.at&gt;\r\n" \\r
+"</pre>\r\n" \\r
+"</BODY>\r\n" \\r
+"</html>"\r
+\r
+/* ------------------------ Prototypes ------------------------------------ */\r
+static void     vProcessConnection( struct netconn *pxNetCon );\r
+\r
+/*------------------------------------------------------------*/\r
+\r
+/*\r
+ * Process an incoming connection on port 80.\r
+ *\r
+ * This simply checks to see if the incoming data contains a GET request, and\r
+ * if so sends back a single dynamically created page.  The connection is then\r
+ * closed.  A more complete implementation could create a task for each\r
+ * connection.\r
+ */\r
+static void\r
+vProcessConnection( struct netconn *pxNetCon )\r
+{\r
+    static portCHAR cDynamicPage[webMAX_PAGE_SIZE], cPageHits[11];\r
+    struct netbuf  *pxRxBuffer;\r
+    portCHAR       *pcRxString;\r
+    unsigned portSHORT usLength;\r
+    static unsigned portLONG ulPageHits = 0;\r
+\r
+    /* We expect to immediately get data. */\r
+    pxRxBuffer = netconn_recv( pxNetCon );\r
+\r
+    if( pxRxBuffer != NULL )\r
+    {\r
+        /* Where is the data? */\r
+        netbuf_data( pxRxBuffer, ( void * )&pcRxString, &usLength );\r
+\r
+        /* Is this a GET?  We don't handle anything else. */\r
+        if( !strncmp( pcRxString, "GET", 3 ) )\r
+        {\r
+            pcRxString = cDynamicPage;\r
+\r
+            /* Update the hit count. */\r
+            ulPageHits++;\r
+            sprintf( cPageHits, "%lu", ulPageHits );\r
+\r
+            /* Write out the HTTP OK header. */\r
+            netconn_write( pxNetCon, webHTTP_OK, ( u16_t ) strlen( webHTTP_OK ), NETCONN_COPY );\r
+\r
+            /* Generate the dynamic page...\r
+\r
+               ... First the page header. */\r
+            strcpy( cDynamicPage, webHTML_START );\r
+            /* ... Then the hit count... */\r
+            strcat( cDynamicPage, cPageHits );\r
+            strcat( cDynamicPage,\r
+                    "<p><pre>Task          State  Priority  Stack #<br>************************************************<br>" );\r
+            /* ... Then the list of tasks and their status... */\r
+            vTaskList( ( signed portCHAR * )cDynamicPage + strlen( cDynamicPage ) );\r
+            /* ... Finally the page footer. */\r
+            strcat( cDynamicPage, webHTML_END );\r
+\r
+            /* Write out the dynamically generated page. */\r
+            netconn_write( pxNetCon, cDynamicPage, ( u16_t ) strlen( cDynamicPage ), NETCONN_COPY );\r
+        }\r
+\r
+        netbuf_delete( pxRxBuffer );\r
+    }\r
+\r
+    netconn_close( pxNetCon );\r
+}\r
+\r
+/*------------------------------------------------------------*/\r
+\r
+void\r
+vlwIPInit( void )\r
+{\r
+    /* Initialize lwIP and its interface layer. */\r
+    sys_init(  );\r
+    mem_init(  );\r
+    memp_init(  );\r
+    pbuf_init(  );\r
+    netif_init(  );\r
+    ip_init(  );\r
+    tcpip_init( NULL, NULL );\r
+}\r
+\r
+/*------------------------------------------------------------*/\r
+\r
+void\r
+vBasicWEBServer( void *pvParameters )\r
+{\r
+    struct netconn *pxHTTPListener, *pxNewConnection;\r
+    struct ip_addr  xIpAddr, xNetMast, xGateway;\r
+    static struct netif fec523x_if;\r
+\r
+    /* Parameters are not used - suppress compiler error. */\r
+    ( void )pvParameters;\r
+\r
+    /* Create and configure the EMAC interface. */\r
+    IP4_ADDR( &xIpAddr, 10, 0, 10, 2 );\r
+    IP4_ADDR( &xNetMast, 255, 255, 255, 0 );\r
+    IP4_ADDR( &xGateway, 10, 0, 10, 1 );\r
+    netif_add( &fec523x_if, &xIpAddr, &xNetMast, &xGateway, NULL, mcf523xfec_init, tcpip_input );\r
+\r
+    /* make it the default interface */\r
+    netif_set_default( &fec523x_if );\r
+\r
+    /* bring it up */\r
+    netif_set_up( &fec523x_if );\r
+\r
+    /* Create a new tcp connection handle */\r
+    pxHTTPListener = netconn_new( NETCONN_TCP );\r
+    netconn_bind( pxHTTPListener, NULL, webHTTP_PORT );\r
+    netconn_listen( pxHTTPListener );\r
+\r
+    /* Loop forever */\r
+    for( ;; )\r
+    {\r
+        /* Wait for connection. */\r
+        pxNewConnection = netconn_accept( pxHTTPListener );\r
+\r
+        if( pxNewConnection != NULL )\r
+        {\r
+            /* Service connection. */\r
+            vProcessConnection( pxNewConnection );\r
+            while( netconn_delete( pxNewConnection ) != ERR_OK )\r
+            {\r
+                vTaskDelay( webSHORT_DELAY );\r
+            }\r
+        }\r
+    }\r
+}\r
index 29abc5d00e656374e607a9c4499db8ebfb5e262e..cb380e3d805b9ad7f30adc2ac2820f3381296ebd 100644 (file)
@@ -1,49 +1,49 @@
-/*
-    FreeRTOS V4.1.0 - copyright (C) 2003-2006 Richard Barry.
-
-    This file is part of the FreeRTOS distribution.
-
-    FreeRTOS is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    FreeRTOS is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with FreeRTOS; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-    A special exception to the GPL can be applied should you wish to distribute
-    a combined work that includes FreeRTOS, without being obliged to provide
-    the source code for any proprietary components.  See the licensing section
-    of http://www.FreeRTOS.org for full details of how and when the exception
-    can be applied.
-
-    ***************************************************************************
-    See http://www.FreeRTOS.org for documentation, latest information, license
-    and contact details.  Please ensure to read the configuration and relevant
+/*\r
+    FreeRTOS V4.1.0 - copyright (C) 2003-2006 Richard Barry.\r
+\r
+    This file is part of the FreeRTOS distribution.\r
+\r
+    FreeRTOS is free software; you can redistribute it and/or modify\r
+    it under the terms of the GNU General Public License as published by\r
+    the Free Software Foundation; either version 2 of the License, or\r
+    (at your option) any later version.\r
+\r
+    FreeRTOS is distributed in the hope that it will be useful,\r
+    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+    GNU General Public License for more details.\r
+\r
+    You should have received a copy of the GNU General Public License\r
+    along with FreeRTOS; if not, write to the Free Software\r
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+\r
+    A special exception to the GPL can be applied should you wish to distribute\r
+    a combined work that includes FreeRTOS, without being obliged to provide\r
+    the source code for any proprietary components.  See the licensing section\r
+    of http://www.FreeRTOS.org for full details of how and when the exception\r
+    can be applied.\r
+\r
+    ***************************************************************************\r
+    See http://www.FreeRTOS.org for documentation, latest information, license\r
+    and contact details.  Please ensure to read the configuration and relevant\r
     port sections of the online documentation.\r
 \r
        Also see http://www.SafeRTOS.com for an IEC 61508 compliant version along\r
-       with commercial development and support options.
-    ***************************************************************************
-*/
-
-#ifndef BASIC_WEB_SERVER_H
-#define BASIC_WEB_SERVER_H
-
-/* The function that implements the WEB server task. */
-void            vBasicWEBServer( void *pvParameters );
-
-/* Initialisation required by lwIP. */
-void            vlwIPInit( void );
-
-#endif  /* 
- */
-
+       with commercial development and support options.\r
+    ***************************************************************************\r
+*/\r
+\r
+#ifndef BASIC_WEB_SERVER_H\r
+#define BASIC_WEB_SERVER_H\r
+\r
+/* The function that implements the WEB server task. */\r
+void            vBasicWEBServer( void *pvParameters );\r
+\r
\r
+/* Initialisation required by lwIP. */\r
+void            vlwIPInit( void );\r
+\r
\r
+#endif  /* \r
+ */\r
+\r
index 69f497efc17536d34bf4f4c811fb4117224d4439..e3d91b9bc11284d97e97cfcff9229d0932d24da6 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index 89dd887b987bad927f1e8459591fb3cc7dc081de..932ed20ba81814ff1abfef87b8fe7f668da25dc4 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index 42ad5a6ccff7132ecbcfc23fa63cc521b309d14a..54d9fd182d85cc0095d4a5187a053af188903790 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index 07c34c5899d7c4d7e3f9975c90ec3e4d2b79325a..3c28325e664cbbe550693a0ec80b8d8f94a58035 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index a36894da5a67b910ef45d54c33560b1933b83025..0c267bd29f42c337ed037293508dd503297ea835 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index 725ef3439a8ccafd0ea0cd2294738df8bfb7d650..7d9280e6881b9ec041f88b9943145a6536364723 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index f78dac08669323970afc6991f0f61c42afa5e646..165fddd71c322ea3ee15ff94d5fc841d5afbfbcd 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index 9866ad316b72e35d4d64a3204d5921f7c4d843be..68ffdea126d7c81c88fbadf2092ab98246a8df8b 100644 (file)
@@ -1,4 +1,4 @@
-#      FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+#      FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 #\r
 #      This file is part of the FreeRTOS.org distribution.\r
 #\r
index f90961fb956f7e19de860d79ee3541c63b97d918..89b6c86d954f247dfff853bcc7ff4eb8203280e2 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index cc42639a8c2754414a04827d21dbfd4f407ceb09..7c4b494b4091f9b1f090dc6a4fa29bc50b2b9192 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index 5f619b5c405303972e50c2515fbc6e4fd919efa2..1d975e69da5b9486e1dbaa51409046026c3fe003 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
@@ -298,9 +298,7 @@ portCHAR *pcBuffer;
                /* Copy the headers into the Tx buffer.  These will be in the uIP buffer. */\r
                pcBuffer = ( portCHAR * ) xTxDescriptors[ uxTxBufferIndex ].addr;\r
                memcpy( ( void * ) pcBuffer, ( void * ) uip_buf, emacTOTAL_FRAME_HEADER_SIZE );\r
-\r
-               /* If there is room, also copy in the application data if any. */\r
-               if( ( uip_len > emacTOTAL_FRAME_HEADER_SIZE ) && ( uip_len <= ( ETH_TX_BUFFER_SIZE - emacTOTAL_FRAME_HEADER_SIZE ) ) )\r
+               if( uip_len > emacTOTAL_FRAME_HEADER_SIZE )\r
                {\r
                        memcpy( ( void * ) &( pcBuffer[ emacTOTAL_FRAME_HEADER_SIZE ] ), ( void * ) uip_appdata, ( uip_len - emacTOTAL_FRAME_HEADER_SIZE ) );\r
                }\r
index 7926e1c11d99c37d20154cf396c51688dfaaa99a..6c6724b4473f05a832cc93dae8f7f69690efb040 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index 3cd274be2295d5bca936bb0e30de7b24eb9ef9eb..9837a7877d4e9b6805759984d086d8c4c04033c1 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index 6aab13cd747e37b94f689d0ebc39b719791b78fd..93592748b3cb29647a879a21a04aaac8e7cc6c2c 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index 6a3c5140a7402ffb7966122ccbf3ce44e87d8811..7679960eb058a1673c697da6d9d9e4ff5752ffce 100644 (file)
-static const char data_404_html[] = {
-       /* /404.html */
-       0x2f, 0x34, 0x30, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
-       0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x34, 
-       0x30, 0x34, 0x20, 0x46, 0x69, 0x6c, 0x65, 0x20, 0x6e, 0x6f, 
-       0x74, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0xd, 0xa, 0x53, 
-       0x65, 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 
-       0x2f, 0x30, 0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 
-       0x3a, 0x2f, 0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 
-       0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 
-       0x75, 0x69, 0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 
-       0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 
-       0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 
-       0xd, 0xa, 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 
-       0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x62, 0x67, 0x63, 0x6f, 
-       0x6c, 0x6f, 0x72, 0x3d, 0x22, 0x77, 0x68, 0x69, 0x74, 0x65, 
-       0x22, 0x3e, 0x3c, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3e, 
-       0x3c, 0x68, 0x31, 0x3e, 0x34, 0x30, 0x34, 0x20, 0x2d, 0x20, 
-       0x66, 0x69, 0x6c, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x66, 
-       0x6f, 0x75, 0x6e, 0x64, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0x3c, 
-       0x2f, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3e, 0x3c, 0x2f, 
-       0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 
-       0x6c, 0x3e, };
-
-static const char data_control_html[] = {
-       /* /control.html */
-       0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
-       0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, 
-       0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72, 
-       0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30, 
-       0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 
-       0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63, 
-       0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69, 
-       0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65, 
-       0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 
-       0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa, 
-       0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xd, 0xa, 
-       0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xd, 0xa, 0x3c, 0x74, 
-       0x69, 0x74, 0x6c, 0x65, 0x3e, 0x41, 0x54, 0x39, 0x31, 0x53, 
-       0x41, 0x4d, 0x37, 0x58, 0x20, 0x45, 0x6d, 0x62, 0x65, 0x64, 
-       0x64, 0x65, 0x64, 0x20, 0x57, 0x45, 0x42, 0x20, 0x53, 0x65, 
-       0x72, 0x76, 0x65, 0x72, 0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, 
-       0x20, 0x75, 0x49, 0x50, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x46, 
-       0x72, 0x65, 0x65, 0x52, 0x54, 0x4f, 0x53, 0x3c, 0x2f, 0x74, 
-       0x69, 0x74, 0x6c, 0x65, 0x3e, 0xd, 0xa, 0x3c, 0x2f, 0x68, 
-       0x65, 0x61, 0x64, 0x3e, 0xd, 0xa, 0x3c, 0x62, 0x6f, 0x64, 
-       0x79, 0x20, 0x62, 0x67, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3d, 
-       0x22, 0x23, 0x63, 0x63, 0x63, 0x63, 0x66, 0x66, 0x22, 0x3e, 
-       0xd, 0xa, 0x3c, 0x66, 0x6f, 0x6e, 0x74, 0x20, 0x66, 0x61, 
-       0x63, 0x65, 0x3d, 0x22, 0x61, 0x72, 0x69, 0x61, 0x6c, 0x22, 
-       0x3e, 0xd, 0xa, 0x3c, 0x69, 0x6d, 0x67, 0x20, 0x73, 0x72, 
-       0x63, 0x3d, 0x22, 0x2f, 0x69, 0x6d, 0x67, 0x2f, 0x6c, 0x6f, 
-       0x67, 0x6f, 0x2e, 0x70, 0x6e, 0x67, 0x22, 0x20, 0x61, 0x6c, 
-       0x69, 0x67, 0x6e, 0x3d, 0x22, 0x72, 0x69, 0x67, 0x68, 0x74, 
-       0x22, 0x3e, 0xd, 0xa, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 
-       0x66, 0x3d, 0x22, 0x2f, 0x63, 0x67, 0x69, 0x2f, 0x72, 0x74, 
-       0x6f, 0x73, 0x22, 0x20, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 
-       0x3d, 0x22, 0x6d, 0x61, 0x69, 0x6e, 0x22, 0x3e, 0x54, 0x61, 
-       0x73, 0x6b, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x7c, 0xd, 
-       0xa, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 
-       0x2f, 0x63, 0x67, 0x69, 0x2f, 0x74, 0x63, 0x70, 0x22, 0x20, 
-       0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x3d, 0x22, 0x6d, 0x61, 
-       0x69, 0x6e, 0x22, 0x3e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 
-       0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 
-       0x7c, 0xd, 0xa, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 
-       0x3d, 0x22, 0x2f, 0x63, 0x67, 0x69, 0x2f, 0x66, 0x69, 0x6c, 
-       0x65, 0x73, 0x22, 0x20, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 
-       0x3d, 0x22, 0x6d, 0x61, 0x69, 0x6e, 0x22, 0x3e, 0x46, 0x69, 
-       0x6c, 0x65, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x7c, 0xd, 
-       0xa, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 
-       0x2f, 0x63, 0x67, 0x69, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x73, 
-       0x22, 0x20, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x3d, 0x22, 
-       0x6d, 0x61, 0x69, 0x6e, 0x22, 0x3e, 0x53, 0x74, 0x61, 0x74, 
-       0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 
-       0x3c, 0x62, 0x72, 0x3e, 0xd, 0xa, 0x3c, 0x62, 0x72, 0x3e, 
-       0xd, 0xa, 0x3c, 0x2f, 0x66, 0x6f, 0x6e, 0x74, 0x3e, 0xd, 
-       0xa, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xd, 0xa, 
-       0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xd, 0xa, 0xd, 
-       0xa, 0xd, 0xa, 0xd, 0xa, 0xd, 0xa, 0xd, 0xa, };
-
-static const char data_files_footer_plain[] = {
-       /* /files_footer.plain */
-       0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x5f, 0x66, 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x2e, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0,
-       0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 
-       0x3c, 0x2f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, 0xd, 0xa, 
-       0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xd, 0xa, 0x3c, 
-       0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xd, 0xa, };
-
-static const char data_files_header_html[] = {
-       /* /files_header.html */
-       0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
-       0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, 
-       0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72, 
-       0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30, 
-       0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 
-       0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63, 
-       0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69, 
-       0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65, 
-       0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 
-       0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa, 
-       0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xd, 0xa, 
-       0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x62, 0x67, 0x63, 0x6f, 
-       0x6c, 0x6f, 0x72, 0x3d, 0x22, 0x23, 0x43, 0x43, 0x43, 0x43, 
-       0x46, 0x46, 0x22, 0x3e, 0xd, 0xa, 0x3c, 0x63, 0x65, 0x6e, 
-       0x74, 0x65, 0x72, 0x3e, 0xd, 0xa, 0x3c, 0x74, 0x61, 0x62, 
-       0x6c, 0x65, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, 0x22, 
-       0x36, 0x30, 0x30, 0x22, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 
-       0x72, 0x3d, 0x22, 0x30, 0x22, 0x3e, 0xd, 0xa, };
-
-static const char data_stats_footer_plain[] = {
-       /* /stats_footer.plain */
-       0x2f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x5f, 0x66, 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x2e, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0,
-       0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 
-       0x3c, 0x2f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, 0xd, 0xa, 
-       0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xd, 0xa, 0x3c, 
-       0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xd, 0xa, };
-
-static const char data_stats_header_html[] = {
-       /* /stats_header.html */
-       0x2f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
-       0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, 
-       0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72, 
-       0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30, 
-       0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 
-       0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63, 
-       0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69, 
-       0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65, 
-       0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 
-       0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa, 
-       0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xd, 0xa, 
-       0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x62, 0x67, 0x63, 0x6f, 
-       0x6c, 0x6f, 0x72, 0x3d, 0x22, 0x23, 0x63, 0x63, 0x63, 0x63, 
-       0x66, 0x66, 0x22, 0x3e, 0xd, 0xa, 0x3c, 0x63, 0x65, 0x6e, 
-       0x74, 0x65, 0x72, 0x3e, 0xd, 0xa, 0x3c, 0x74, 0x61, 0x62, 
-       0x6c, 0x65, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, 0x22, 
-       0x36, 0x30, 0x30, 0x22, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 
-       0x72, 0x3d, 0x22, 0x30, 0x22, 0x3e, 0xd, 0xa, 0x3c, 0x74, 
-       0x72, 0x3e, 0x3c, 0x74, 0x64, 0x3e, 0xd, 0xa, 0x3c, 0x70, 
-       0x72, 0x65, 0x3e, 0xd, 0xa, 0x49, 0x50, 0x20, 0x20, 0x20, 
-       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 
-       0x63, 0x6b, 0x65, 0x74, 0x73, 0x20, 0x64, 0x72, 0x6f, 0x70, 
-       0x70, 0x65, 0x64, 0xd, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 
-       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 
-       0x63, 0x6b, 0x65, 0x74, 0x73, 0x20, 0x72, 0x65, 0x63, 0x65, 
-       0x69, 0x76, 0x65, 0x64, 0xd, 0xa, 0x20, 0x20, 0x20, 0x20, 
-       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 
-       0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x20, 0x73, 0x65, 0x6e, 
-       0x74, 0xd, 0xa, 0x49, 0x50, 0x20, 0x65, 0x72, 0x72, 0x6f, 
-       0x72, 0x73, 0x20, 0x20, 0x20, 0x20, 0x49, 0x50, 0x20, 0x76, 
-       0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x2f, 0x68, 0x65, 0x61, 
-       0x64, 0x65, 0x72, 0x20, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 
-       0xd, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
-       0x20, 0x20, 0x20, 0x20, 0x20, 0x49, 0x50, 0x20, 0x6c, 0x65, 
-       0x6e, 0x67, 0x74, 0x68, 0x2c, 0x20, 0x68, 0x69, 0x67, 0x68, 
-       0x20, 0x62, 0x79, 0x74, 0x65, 0xd, 0xa, 0x20, 0x20, 0x20, 
-       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
-       0x49, 0x50, 0x20, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2c, 
-       0x20, 0x6c, 0x6f, 0x77, 0x20, 0x62, 0x79, 0x74, 0x65, 0xd, 
-       0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
-       0x20, 0x20, 0x20, 0x20, 0x49, 0x50, 0x20, 0x66, 0x72, 0x61, 
-       0x67, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0xd, 0xa, 0x20, 0x20, 
-       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
-       0x20, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x63, 0x68, 
-       0x65, 0x63, 0x6b, 0x73, 0x75, 0x6d, 0xd, 0xa, 0x20, 0x20, 
-       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
-       0x20, 0x57, 0x72, 0x6f, 0x6e, 0x67, 0x20, 0x70, 0x72, 0x6f, 
-       0x74, 0x6f, 0x63, 0x6f, 0x6c, 0xd, 0xa, 0x49, 0x43, 0x4d, 
-       0x50, 0x9, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 0x63, 
-       0x6b, 0x65, 0x74, 0x73, 0x20, 0x64, 0x72, 0x6f, 0x70, 0x70, 
-       0x65, 0x64, 0xd, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
-       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 0x63, 
-       0x6b, 0x65, 0x74, 0x73, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 
-       0x76, 0x65, 0x64, 0xd, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 
-       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 
-       0x63, 0x6b, 0x65, 0x74, 0x73, 0x20, 0x73, 0x65, 0x6e, 0x74, 
-       0xd, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
-       0x20, 0x20, 0x20, 0x20, 0x20, 0x54, 0x79, 0x70, 0x65, 0x20, 
-       0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0xd, 0xa, 0x54, 0x43, 
-       0x50, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
-       0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x20, 0x64, 
-       0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0xd, 0xa, 0x20, 0x20, 
-       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
-       0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x20, 0x72, 
-       0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0xd, 0xa, 0x20, 
-       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
-       0x20, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x20, 
-       0x73, 0x65, 0x6e, 0x74, 0xd, 0xa, 0x20, 0x20, 0x20, 0x20, 
-       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, 
-       0x68, 0x65, 0x63, 0x6b, 0x73, 0x75, 0x6d, 0x20, 0x65, 0x72, 
-       0x72, 0x6f, 0x72, 0x73, 0xd, 0xa, 0x20, 0x20, 0x20, 0x20, 
-       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x44, 
-       0x61, 0x74, 0x61, 0x20, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 
-       0x73, 0x20, 0x77, 0x69, 0x74, 0x68, 0x6f, 0x75, 0x74, 0x20, 
-       0x41, 0x43, 0x4b, 0x73, 0xd, 0xa, 0x20, 0x20, 0x20, 0x20, 
-       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x52, 
-       0x65, 0x73, 0x65, 0x74, 0x73, 0xd, 0xa, 0x20, 0x20, 0x20, 
-       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
-       0x52, 0x65, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6d, 0x69, 0x73, 
-       0x73, 0x69, 0x6f, 0x6e, 0x73, 0xd, 0xa, 0x9, 0x20, 0x20, 
-       0x20, 0x20, 0x20, 0x4e, 0x6f, 0x20, 0x63, 0x6f, 0x6e, 0x6e, 
-       0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x76, 0x61, 
-       0x6c, 0x69, 0x61, 0x62, 0x6c, 0x65, 0xd, 0xa, 0x9, 0x20, 
-       0x20, 0x20, 0x20, 0x20, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 
-       0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x74, 0x74, 0x65, 0x6d, 
-       0x70, 0x74, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x63, 0x6c, 0x6f, 
-       0x73, 0x65, 0x64, 0x20, 0x70, 0x6f, 0x72, 0x74, 0x73, 0xd, 
-       0xa, 0x3c, 0x2f, 0x70, 0x72, 0x65, 0x3e, 0x9, 0x20, 0x20, 
-       0x20, 0x20, 0x20, 0xd, 0xa, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 
-       0x3c, 0x74, 0x64, 0x3e, 0x3c, 0x70, 0x72, 0x65, 0x3e, };
-
-static const char data_tcp_footer_plain[] = {
-       /* /tcp_footer.plain */
-       0x2f, 0x74, 0x63, 0x70, 0x5f, 0x66, 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x2e, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0,
-       0xd, 0xa, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x2f, 0x74, 
-       0x72, 0x3e, 0x3c, 0x2f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, 
-       0xd, 0xa, 0x3c, 0x2f, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 
-       0x3e, 0xd, 0xa, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 
-       0xd, 0xa, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, };
-
-static const char data_tcp_header_html[] = {
-       /* /tcp_header.html */
-       0x2f, 0x74, 0x63, 0x70, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
-       0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, 
-       0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72, 
-       0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30, 
-       0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 
-       0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63, 
-       0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69, 
-       0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65, 
-       0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 
-       0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa, 
-       0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xd, 0xa, 
-       0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x62, 0x67, 0x63, 0x6f, 
-       0x6c, 0x6f, 0x72, 0x3d, 0x22, 0x23, 0x63, 0x63, 0x63, 0x63, 
-       0x66, 0x66, 0x22, 0x3e, 0xd, 0xa, 0x3c, 0x63, 0x65, 0x6e, 
-       0x74, 0x65, 0x72, 0x3e, 0xd, 0xa, 0x3c, 0x74, 0x61, 0x62, 
-       0x6c, 0x65, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, 0x22, 
-       0x36, 0x30, 0x30, 0x22, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 
-       0x72, 0x3d, 0x22, 0x30, 0x22, 0x3e, 0xd, 0xa, 0x3c, 0x74, 
-       0x72, 0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x52, 0x65, 0x6d, 0x6f, 
-       0x74, 0x65, 0x3c, 0x2f, 0x74, 0x68, 0x3e, 0x3c, 0x74, 0x68, 
-       0x3e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x3c, 0x2f, 0x74, 0x68, 
-       0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x52, 0x65, 0x74, 0x72, 0x61, 
-       0x6e, 0x73, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 
-       0x3c, 0x2f, 0x74, 0x68, 0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x54, 
-       0x69, 0x6d, 0x65, 0x72, 0x3c, 0x2f, 0x74, 0x68, 0x3e, 0x3c, 
-       0x74, 0x68, 0x3e, 0x46, 0x6c, 0x61, 0x67, 0x73, 0x3c, 0x2f, 
-       0x74, 0x68, 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0xd, 0xa, 
-       0xd, 0xa, };
-
-static const char data_img_logo_png[] = {
-       /* /img/logo.png */
-       0x2f, 0x69, 0x6d, 0x67, 0x2f, 0x6c, 0x6f, 0x67, 0x6f, 0x2e, 0x70, 0x6e, 0x67, 0,
-       0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, 
-       0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72, 
-       0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30, 
-       0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 
-       0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63, 
-       0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69, 
-       0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65, 
-       0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x69, 
-       0x6d, 0x61, 0x67, 0x65, 0x2f, 0x70, 0x6e, 0x67, 0xd, 0xa, 
-       0xd, 0xa, 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 
-       00, 00, 00, 0xd, 0x49, 0x48, 0x44, 0x52, 00, 00, 
-       00, 0xec, 00, 00, 00, 0x5c, 0x8, 0x3, 00, 00, 
-       00, 0x5a, 0xc7, 0xa9, 0x53, 00, 00, 0x3, 00, 0x50, 
-       0x4c, 0x54, 0x45, 00, 00, 00, 0x3, 0x3, 0x3, 0x4, 
-       0x4, 0x4, 0x6, 0x6, 0x6, 0x8, 0x8, 0x8, 0xa, 0xa, 
-       0xa, 0xc, 0xc, 0xc, 0xe, 0xe, 0xe, 0x10, 0x10, 0x10, 
-       0x12, 0x12, 0x12, 0x14, 0x14, 0x14, 0x16, 0x16, 0x16, 0x18, 
-       0x18, 0x18, 0x1a, 0x1a, 0x1a, 0x1c, 0x1c, 0x1c, 0x21, 0x21, 
-       0x21, 0x25, 0x25, 0x25, 0x28, 0x28, 0x28, 0x2c, 0x2c, 0x2c, 
-       0x2e, 0x2e, 0x2e, 0x30, 0x30, 0x30, 0x32, 0x32, 0x32, 0x34, 
-       0x34, 0x34, 0x36, 0x36, 0x36, 0x38, 0x38, 0x38, 0x3a, 0x3a, 
-       0x3a, 0x3e, 0x3e, 0x3e, 0x40, 0x40, 0x40, 0x43, 0x43, 0x43, 
-       0x45, 0x45, 0x45, 0x46, 0x46, 0x46, 0x4a, 0x4a, 0x4a, 0x4d, 
-       0x4d, 0x4d, 0x50, 0x50, 0x50, 0x52, 0x52, 0x52, 0x55, 0x55, 
-       0x55, 0x58, 0x58, 0x58, 0x5c, 0x5c, 0x5c, 0x60, 0x60, 0x60, 
-       0x62, 0x62, 0x62, 0x66, 0x66, 0x66, 0x69, 0x69, 0x69, 0x6b, 
-       0x6b, 0x6b, 0x6e, 0x6e, 0x6e, 0x71, 0x71, 0x71, 0x73, 0x73, 
-       0x73, 0x74, 0x74, 0x74, 0x77, 0x77, 0x77, 0x78, 0x78, 0x78, 
-       0x7a, 0x7a, 0x7a, 0x7c, 0x7c, 0x7c, 0x7e, 0x7e, 0x7e, 00, 
-       0xd9, 00, 0x4, 0xd8, 0x4, 0x6, 0xda, 0x6, 0x8, 0xda, 
-       0x8, 0xc, 0xda, 0xc, 0x15, 0xdc, 0x15, 0x18, 0xdc, 0x18, 
-       0x1a, 0xdc, 0x1a, 0x1d, 0xdd, 0x1d, 0x20, 0xde, 0x20, 0x22, 
-       0xde, 0x22, 0x24, 0xde, 0x24, 0x28, 0xde, 0x28, 0x2d, 0xe0, 
-       0x2d, 0x2f, 0xe0, 0x2f, 0x3b, 0xe2, 0x3b, 0x3d, 0xe2, 0x3d, 
-       0x41, 0xe2, 0x41, 0x45, 0xe2, 0x45, 0x49, 0xe3, 0x49, 0x49, 
-       0xe4, 0x49, 0x4b, 0xe4, 0x4b, 0x4d, 0xe5, 0x4d, 0x51, 0xe5, 
-       0x51, 0x56, 0xe6, 0x56, 0x58, 0xe6, 0x58, 0x60, 0xe6, 0x60, 
-       0x64, 0xe8, 0x64, 0x69, 0xe9, 0x69, 0x6a, 0xe9, 0x6a, 0x6c, 
-       0xe9, 0x6c, 0x6e, 0xe9, 0x6e, 0x6f, 0xea, 0x6f, 0x66, 0xff, 
-       0x66, 0x68, 0xff, 0x68, 0x6a, 0xff, 0x6a, 0x6c, 0xff, 0x6c, 
-       0x6e, 0xff, 0x6e, 0x73, 0xea, 0x73, 0x78, 0xeb, 0x78, 0x7a, 
-       0xea, 0x7a, 0x70, 0xff, 0x70, 0x72, 0xff, 0x72, 0x74, 0xff, 
-       0x74, 0x76, 0xff, 0x76, 0x78, 0xff, 0x78, 0x7a, 0xff, 0x7a, 
-       0x7c, 0xff, 0x7c, 0x7e, 0xff, 0x7e, 0x80, 0x80, 0x80, 0x83, 
-       0x83, 0x83, 0x86, 0x86, 0x86, 0x89, 0x89, 0x89, 0x8b, 0x8b, 
-       0x8b, 0x8e, 0x8e, 0x8e, 0x90, 0x90, 0x90, 0x93, 0x93, 0x93, 
-       0x96, 0x96, 0x96, 0x99, 0x99, 0x99, 0x9a, 0x9a, 0x9a, 0x9e, 
-       0x9e, 0x9e, 0xa0, 0xa0, 0xa0, 0xa5, 0xa5, 0xa5, 0xa6, 0xa6, 
-       0xa6, 0xa9, 0xa9, 0xa9, 0xab, 0xab, 0xab, 0xac, 0xac, 0xac, 
-       0xae, 0xae, 0xae, 0xb1, 0xb1, 0xb1, 0xb5, 0xb5, 0xb5, 0xb8, 
-       0xb8, 0xb8, 0xba, 0xba, 0xba, 0xbc, 0xbc, 0xbc, 0xbe, 0xbe, 
-       0xbe, 0x81, 0xeb, 0x81, 0x80, 0xec, 0x80, 0x85, 0xec, 0x85, 
-       0x88, 0xed, 0x88, 0x88, 0xee, 0x88, 0x8d, 0xee, 0x8d, 0x80, 
-       0xff, 0x80, 0x82, 0xff, 0x82, 0x84, 0xff, 0x84, 0x86, 0xff, 
-       0x86, 0x88, 0xff, 0x88, 0x8a, 0xff, 0x8a, 0x8c, 0xff, 0x8c, 
-       0x8e, 0xff, 0x8e, 0x97, 0xf0, 0x97, 0x90, 0xff, 0x90, 0x92, 
-       0xff, 0x92, 0x94, 0xff, 0x94, 0x96, 0xff, 0x96, 0x9c, 0xf0, 
-       0x9c, 0x98, 0xff, 0x98, 0x9a, 0xff, 0x9a, 0x9c, 0xff, 0x9c, 
-       0x9e, 0xff, 0x9e, 0xa2, 0xf1, 0xa2, 0xa2, 0xf2, 0xa2, 0xa4, 
-       0xf1, 0xa4, 0xa6, 0xf1, 0xa6, 0xa6, 0xf2, 0xa6, 0xa0, 0xff, 
-       0xa0, 0xa2, 0xff, 0xa2, 0xa4, 0xff, 0xa4, 0xa6, 0xff, 0xa6, 
-       0xa8, 0xf2, 0xa8, 0xac, 0xf3, 0xac, 0xae, 0xf3, 0xae, 0xa8, 
-       0xff, 0xa8, 0xaa, 0xff, 0xaa, 0xac, 0xff, 0xac, 0xae, 0xff, 
-       0xae, 0xb3, 0xf4, 0xb3, 0xb4, 0xf4, 0xb4, 0xb6, 0xf4, 0xb6, 
-       0xb0, 0xff, 0xb0, 0xb2, 0xff, 0xb2, 0xb4, 0xff, 0xb4, 0xb6, 
-       0xff, 0xb6, 0xbb, 0xf5, 0xbb, 0xb8, 0xff, 0xb8, 0xba, 0xff, 
-       0xba, 0xbc, 0xff, 0xbc, 0xbe, 0xff, 0xbe, 0xc0, 0xc0, 0xc0, 
-       0xc3, 0xc3, 0xc3, 0xc4, 0xc4, 0xc4, 0xc6, 0xc6, 0xc6, 0xc8, 
-       0xc8, 0xc8, 0xca, 0xca, 0xca, 0xcc, 0xcc, 0xcc, 0xcf, 0xcf, 
-       0xcf, 0xd0, 0xd0, 0xd0, 0xd2, 0xd2, 0xd2, 0xd4, 0xd4, 0xd4, 
-       0xd6, 0xd6, 0xd6, 0xd8, 0xd8, 0xd8, 0xda, 0xda, 0xda, 0xdc, 
-       0xdc, 0xdc, 0xdf, 0xdf, 0xdf, 0xc0, 0xff, 0xc0, 0xc2, 0xff, 
-       0xc2, 0xc4, 0xff, 0xc4, 0xc6, 0xff, 0xc6, 0xc8, 0xff, 0xc8, 
-       0xca, 0xff, 0xca, 0xcc, 0xf8, 0xcc, 0xce, 0xf8, 0xce, 0xcc, 
-       0xff, 0xcc, 0xce, 0xff, 0xce, 0xd0, 0xf8, 0xd0, 0xd0, 0xff, 
-       0xd0, 0xd2, 0xff, 0xd2, 0xd6, 0xf9, 0xd6, 0xd4, 0xff, 0xd4, 
-       0xd6, 0xff, 0xd6, 0xd9, 0xf9, 0xd9, 0xd8, 0xff, 0xd8, 0xda, 
-       0xff, 0xda, 0xdc, 0xfa, 0xdc, 0xdc, 0xff, 0xdc, 0xde, 0xff, 
-       0xde, 0xe0, 0xe0, 0xe0, 0xe2, 0xe2, 0xe2, 0xe4, 0xe4, 0xe4, 
-       0xe6, 0xe6, 0xe6, 0xe8, 0xe8, 0xe8, 0xea, 0xea, 0xea, 0xec, 
-       0xec, 0xec, 0xee, 0xee, 0xee, 0xe1, 0xfa, 0xe1, 0xe3, 0xfb, 
-       0xe3, 0xe0, 0xff, 0xe0, 0xe2, 0xff, 0xe2, 0xe5, 0xfb, 0xe5, 
-       0xe4, 0xff, 0xe4, 0xe6, 0xff, 0xe6, 0xe8, 0xfc, 0xe8, 0xe8, 
-       0xff, 0xe8, 0xea, 0xfc, 0xea, 0xea, 0xff, 0xea, 0xec, 0xff, 
-       0xec, 0xee, 0xfd, 0xee, 0xee, 0xff, 0xee, 0xf0, 0xf0, 0xf0, 
-       0xf2, 0xf2, 0xf2, 0xf4, 0xf4, 0xf4, 0xf6, 0xf6, 0xf6, 0xf1, 
-       0xfd, 0xf1, 0xf0, 0xff, 0xf0, 0xf3, 0xfd, 0xf3, 0xf2, 0xff, 
-       0xf2, 0xf5, 0xfd, 0xf5, 0xf4, 0xfe, 0xf4, 0xf6, 0xfe, 0xf6, 
-       0xf8, 0xf8, 0xf8, 0xfa, 0xfa, 0xfa, 0xf8, 0xfe, 0xf8, 0xfa, 
-       0xfe, 0xfa, 0xff, 00, 00, 0xfc, 0xfe, 0xfc, 0xfe, 0xfe, 
-       0xfe, 0xd7, 0xd6, 0xbe, 0x1c, 00, 00, 00, 0xfe, 0x74, 
-       0x52, 0x4e, 0x53, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 00, 0xd8, 0xd9, 0xc, 
-       0x71, 00, 00, 0xc, 0xc6, 0x49, 0x44, 0x41, 0x54, 0x78, 
-       0xda, 0xed, 0x9c, 0xf, 0x50, 0x14, 0xd7, 0x19, 0xc0, 0xdf, 
-       0xc2, 0x21, 0x2c, 0x77, 0x27, 0xa0, 0x1, 0x3d, 0x15, 0x10, 
-       0x4, 0x39, 0x23, 0xe3, 0x14, 0x1, 0xeb, 0x1f, 0xc0, 0x51, 
-       0x87, 0x88, 0x81, 0x91, 0x92, 0xa8, 0x41, 0x32, 0x49, 0xac, 
-       0xb6, 0x8e, 0xa5, 0xa6, 0x8e, 0x1d, 0x3b, 0x6d, 0x9c, 0xce, 
-       0x64, 0x3a, 0xda, 0xd8, 0x4e, 0xda, 0x4e, 0x67, 0x9c, 0x74, 
-       0x92, 0x36, 0xa, 0xb6, 0x62, 0xac, 0xa6, 0x15, 0xdb, 0x10, 
-       0xe8, 0x58, 0xb4, 0xa, 0x6, 0x14, 0x73, 0x54, 0x73, 0x53, 
-       0x8e, 0x62, 0x4c, 0xf8, 0x93, 0x9c, 0x60, 0x10, 0xc9, 0x82, 
-       0x87, 0x1c, 0xb0, 0x7d, 0xbb, 0xcb, 0xdd, 0xbd, 0xb7, 0xfb, 
-       0xde, 0xde, 0xae, 0x98, 0x94, 0x23, 0x99, 0xdf, 0xcc, 0xed, 
-       0xbd, 0xdd, 0xf7, 0xde, 0xed, 0xb7, 0xef, 0xbd, 0xef, 0x7d, 
-       0xdf, 0xf7, 0xde, 0x1e, 0x33, 0xa, 00, 0xb8, 0x76, 0xf0, 
-       0x36, 0xfc, 0x9c, 0xd2, 0xa4, 0x1c, 0x83, 0x1f, 0x50, 0xd8, 
-       0x53, 0x7f, 0xfc, 0x6c, 0x82, 0x35, 0x5, 0x2, 0xec, 0xd6, 
-       0x9d, 0x50, 0xd8, 0x3f, 0xbd, 0x36, 0xe1, 0x8a, 0x2, 0x83, 
-       0xef, 0x3f, 0xc7, 0x8c, 0xe6, 0x72, 0x13, 0xae, 0x26, 0x30, 
-       0x30, 0x9f, 0x33, 0xbc, 0x20, 0xc9, 0x6a, 0x88, 0xc, 0x9e, 
-       0x50, 0x4d, 0x93, 0x92, 0xa0, 0x69, 0xd2, 0x71, 0xb0, 0x4f, 
-       0xd0, 0x4c, 0xdc, 0x29, 0x26, 0x53, 0x48, 0xb1, 0x31, 0xd9, 
-       0x39, 0x33, 0x1e, 0xb2, 0xc6, 0x49, 0x4c, 0x58, 0x8c, 0x74, 
-       0xfc, 0xe0, 0x17, 0x1f, 0xbb, 0xe1, 0x61, 0xba, 0x24, 0x6c, 
-       0xfc, 0x6b, 0xe3, 0xa7, 0xa7, 0x28, 0x1d, 0x3f, 0xf8, 0x54, 
-       0x38, 0x4, 0x9, 0x1f, 0x21, 0xeb, 0xa6, 0xb6, 0xac, 0x20, 
-       0x6e, 0xad, 0x41, 0x38, 0x88, 0xc2, 0x1a, 0xd8, 0x9, 0x54, 
-       0x14, 0x10, 0x44, 0x84, 0x8, 0x9f, 0xa2, 0xb0, 0x5f, 0x15, 
-       0xbe, 0x16, 0x76, 0xaa, 0x22, 0xe, 0x5c, 0x1a, 0xfd, 0x63, 
-       0x7d, 0x1f, 0xa7, 0x47, 0x68, 0xab, 0xe8, 0x91, 0xe2, 0xe2, 
-       0x84, 0x89, 0x11, 0x12, 0x6c, 0xd6, 0xaa, 0x4e, 0xc4, 0x22, 
-       0xfd, 0xc2, 0xcd, 0xd2, 0xcb, 0xd0, 0x85, 0xed, 0x7b, 0xef, 
-       0x82, 0xcb, 0xdd, 0x78, 0xaf, 0x7c, 0xad, 0xef, 0x94, 0xb3, 
-       0x8b, 0x92, 0xd7, 0xc, 0x40, 0xbc, 0xfc, 0x17, 0xa8, 0x99, 
-       0x51, 0x82, 0xe7, 0x29, 0xe6, 0x81, 0x9e, 0xae, 0xd1, 0xa1, 
-       0xee, 0xdb, 0x3, 00, 0xb4, 0xa6, 00, 0x60, 0x9a, 0x61, 
-       0xb2, 0x4, 0x5b, 0x2c, 0xea, 0x95, 0xb8, 0xda, 0xb9, 0xa1, 
-       0xbe, 0xde, 0xde, 0x11, 0xa9, 0x88, 0x61, 0xa6, 0x79, 0x56, 
-       0x18, 0x30, 0x2b, 0xee, 0x7, 0x42, 0x13, 0xd6, 0xfd, 0xaf, 
-       0xd3, 0x67, 0x7a, 0xe1, 0x91, 0x75, 0xf7, 0xd7, 0xd7, 00, 
-       0xb0, 0x1b, 0xd6, 0x2, 0x5c, 0x17, 0x2a, 0x29, 0xb9, 0xcd, 
-       0xc9, 0x20, 0xce, 0x14, 0x15, 0x6d, 0x45, 0xcf, 0x5d, 0xae, 
-       0x1a, 0xa4, 0xe4, 0x46, 0x30, 0x6e, 0xc7, 0x85, 0x75, 0xd9, 
-       0x9d, 0x1d, 0xef, 0x7b, 0xca, 0xd9, 0xc6, 0xf3, 0x2c, 0x89, 
-       0x9d, 0x95, 0x42, 0x9f, 0x1b, 0x6d, 0x5d, 0x3, 0xb5, 0x5e, 
-       0x8b, 0x77, 0xbc, 0x8, 0x60, 0xd2, 0xe2, 0x62, 0x93, 0x14, 
-       0xcf, 0x88, 0x26, 0x6c, 0xed, 0x4e, 0x6f, 0xc3, 0x54, 0xbd, 
-       0xe, 0x40, 0xe8, 0x21, 0x51, 0x77, 0xd3, 0xe0, 0x6c, 0xf0, 
-       0x67, 0xe0, 0xf, 0x58, 0x97, 0xaa, 0xe5, 0xf2, 0x8b, 0xeb, 
-       0xda, 0xcd, 0x4b, 0xca, 0x27, 0x34, 0xd8, 0xd0, 0x60, 0x5c, 
-       0xb2, 0x60, 0x39, 0x51, 0x5c, 0x97, 0xbd, 0xad, 0xc3, 0x23, 
-       0x20, 0xa, 0x6f, 0xb3, 0x19, 0x4b, 0xb5, 0xa, 0x7b, 0xd1, 
-       0x27, 0x6b, 0xc4, 0x74, 0xd6, 0x5, 0xde, 0x2d, 0x4d, 0x24, 
-       0x67, 0x44, 0x80, 0x3f, 0xb0, 0xf4, 0x7a, 0xfe, 0x4, 0xcc, 
-       0x13, 0xdb, 0x75, 0x82, 0xa8, 0x22, 0x83, 0xd, 0x37, 0x3e, 
-       0xcc, 0xc8, 0x50, 0x76, 0x4c, 0x47, 0x43, 0x3d, 0xd5, 0x8d, 
-       0x9, 0x9a, 0xa7, 0x38, 0x45, 0x16, 0xd6, 0xfd, 0x77, 0x64, 
-       0xc0, 0xad, 0x3f, 0xfd, 0x11, 0xe8, 0x6e, 0xf7, 0x2f, 0x2c, 
-       0xc4, 0xc6, 0xf4, 0x3e, 0xeb, 0x67, 0x80, 0xd1, 0xa9, 0x2b, 
-       0x1f, 0xe0, 0xa9, 0x17, 0xa1, 0xb8, 0x37, 0x15, 0xf, 0xb2, 
-       0xa9, 0xb6, 0x99, 0x5e, 0x82, 00, 0x59, 0xd8, 0xf6, 0xa, 
-       0xf8, 0x31, 0xa7, 0x78, 0xec, 0xd, 0x17, 0x3c, 0xc6, 0x42, 
-       0xdf, 0xa1, 0x1f, 0x8e, 0x7e, 0x2d, 0xf0, 0x57, 0x5b, 0xe, 
-       0x3e, 0x9c, 0xb4, 0xae, 0x2a, 0x3f, 0x63, 0x7c, 0xb0, 0xa6, 
-       0xf7, 0x79, 0x5c, 0x5a, 0xdb, 0xef, 0xd4, 0x4a, 0x24, 0x47, 
-       0x2a, 0x4e, 0x91, 0xe7, 0xd9, 0x4f, 0xee, 00, 0x90, 0x50, 
-       0x76, 0x68, 0xbd, 0xf8, 0x28, 0xe2, 0xb3, 0x1, 0x18, 0xa3, 
-       0x55, 0xa9, 0x80, 0xfb, 0xa9, 0xe6, 0xac, 0x28, 0xae, 0x33, 
-       0xa7, 0xfd, 0xe9, 0x33, 0xfe, 0xea, 0x4b, 0x3d, 0x68, 0xda, 
-       0x79, 0x58, 0xbd, 0x84, 0xb2, 0xd7, 0x93, 0x85, 0x1d, 0x83, 
-       0xc2, 0x45, 0xe4, 0x8e, 0xeb, 0xa4, 0xae, 0xf7, 0x28, 0xb5, 
-       0x91, 0xe1, 0xca, 0x74, 0x65, 0x97, 0x70, 0x9d, 0x39, 0xab, 
-       0xa1, 0x43, 0x72, 0x2f, 0x9, 0x3d, 0x6d, 0x9c, 0x9e, 0xfd, 
-       0x1a, 0xb4, 0x3d, 0xe, 0x59, 0x58, 0xe1, 0x87, 0x19, 0x4f, 
-       0x62, 0x78, 0x58, 0x4b, 0x45, 0x3e, 0x2e, 0xe9, 0xcb, 0x2e, 
-       0x62, 0xaf, 0x54, 0xca, 0xea, 0xbd, 0x1, 0x1f, 0x1c, 0x9c, 
-       0x18, 0x3c, 0x10, 0x95, 0x19, 0x52, 0x86, 0x30, 0x40, 0xc9, 
-       0x63, 0x56, 0x28, 0xe3, 0x16, 0xcd, 0x11, 0x48, 0x19, 0xc, 
-       0x3d, 0x1a, 0x94, 0x71, 0xc, 0x63, 0x50, 0x32, 0x30, 0x8c, 
-       0x80, 0xb6, 0xb1, 0xfb, 0xb2, 0xfb, 0xbc, 0xdf, 0x24, 0xfa, 
-       0xc8, 0x7a, 0x70, 0xfe, 0x4a, 0x76, 0xc2, 0x98, 0x62, 00, 
-       0x33, 0x7b, 0xc1, 0x48, 0xab, 0xac, 0xf2, 0xc6, 0x3a, 0x38, 
-       0xa6, 0x44, 0x5c, 0xa7, 0x95, 0x25, 0x80, 0x50, 0x6, 0xc0, 
-       0x7b, 0xa2, 0x68, 0x3a, 0xb2, 0xb0, 0x42, 0x7b, 0x3b, 0xf, 
-       0xee, 0x17, 0xbe, 0xba, 0xcf, 0x9f, 0x85, 0xd6, 0xcc, 0x9c, 
-       0xb9, 0x8a, 0x3c, 0xb9, 0x6b, 00, 0xb0, 0x38, 0x41, 0xbf, 
-       0xfd, 0xf6, 0x50, 0x13, 0x56, 0x37, 0x5f, 0x2f, 0x5, 0x4, 
-       0xd2, 0x85, 0xe8, 0x80, 0xc4, 0x28, 0x9a, 0x83, 0x59, 0xee, 
-       0xfb, 0x1e, 0x69, 0x14, 0xf, 0x7f, 0xc1, 0x6f, 0xce, 0xb8, 
-       0x78, 0x61, 0xae, 0x38, 0xe2, 0x5c, 0xf6, 0x2b, 0x5e, 0x13, 
-       0x43, 0xaa, 0xbb, 0xdc, 0x63, 0x5e, 0xd8, 0xb1, 0x22, 0x4c, 
-       0xe6, 0x42, 0xdf, 0x44, 0xec, 0x6a, 0xb7, 0x77, 0x3e, 0x68, 
-       0x26, 0x84, 0x99, 0xc8, 0xc2, 0xce, 0x85, 0x4f, 0xa8, 0xf7, 
-       0xe8, 0x79, 0xde, 0xd, 0xdc, 0x3f, 0x1a, 0x6e, 0x87, 0x27, 
-       0x36, 0xce, 0x56, 0xe4, 0x31, 0x9, 0x5a, 0xd7, 0x2, 0x2c, 
-       0x56, 0xe0, 0x9c, 0x8f, 0x2b, 0xd2, 0x7, 0xe2, 0x67, 0x26, 
-       0xd2, 0xbe, 0x8e, 0x26, 0xe4, 0x72, 0xda, 0x5e, 0x79, 0x55, 
-       0x8e, 0x3a, 0x2c, 0x69, 0xde, 0x90, 0x33, 0x7e, 0xe3, 0x6c, 
-       0x66, 0x66, 0x5d, 0x39, 0x36, 0x93, 0xe, 0xfc, 0xb3, 0x44, 
-       0xfa, 0x52, 0x8f, 0x9e, 0x65, 0xf2, 0xd0, 0x69, 0x89, 0xb5, 
-       0xc2, 0x7b, 0x4a, 0x8a, 0xc7, 0xea, 0x14, 0x21, 0xb, 0x1b, 
-       0x5d, 0x72, 0x18, 0x80, 0xbe, 0x3e, 0xf8, 0x6d, 0xa4, 0x55, 
-       0x48, 0x9b, 0x9e, 0x50, 0x73, 0x7, 0x2c, 0x9b, 0x66, 0x1d, 
-       0xd5, 0xad, 0x2c, 0x50, 0xaa, 0xb1, 0x56, 0x32, 0x6f, 0xf3, 
-       0x74, 0x55, 0x81, 0xec, 0xb0, 0xd7, 0x51, 0x69, 0xf9, 0x8e, 
-       0x1e, 0x49, 0xac, 0x1b, 0x68, 0x91, 0xb4, 0x3c, 0xf9, 0x14, 
-       0x6c, 0xd9, 0x24, 0x3b, 0x21, 0x40, 0x56, 0x50, 0x11, 0xdf, 
-       0x9a, 0x83, 0xa5, 0x13, 0x1e, 0x27, 0x66, 0xf3, 0x92, 0xbd, 
-       0x18, 0x4d, 0xb5, 0xa9, 0x67, 0x56, 0xe0, 0xc0, 0x6e, 0xdc, 
-       0xb8, 0x1, 0x95, 0x15, 0x80, 0xcc, 0x5d, 0x98, 0xa6, 0x6a, 
-       0x25, 0xe9, 0x3f, 0x83, 0xb6, 0xb9, 0x9d, 0xe2, 0xcf, 0x66, 
-       0x6d, 0x35, 0x21, 0xa9, 0x84, 0xdf, 0xfa, 0xb3, 0x9f, 0xe6, 
-       0x13, 0x54, 0xa7, 0x66, 0x1a, 0xee, 0xa3, 0xa9, 0x94, 0x1c, 
-       0xd9, 0xe5, 0xcc, 0x3c, 0x34, 0x35, 0xd8, 0x29, 0x1d, 0xb1, 
-       0x32, 0x1a, 0xa1, 0x8, 0x1b, 0xb2, 0x7f, 0x67, 0xb4, 0x37, 
-       0xcb, 0x82, 0x3f, 0x40, 0x5d, 0xa4, 0x4e, 0x2a, 0x9a, 0x48, 
-       0xf6, 0x97, 0x5b, 0x46, 0x37, 0xda, 0x8b, 0x99, 0x55, 0xa, 
-       0xeb, 0x3a, 0x1f, 0x7b, 0x92, 0x76, 0x92, 0xe1, 0xaf, 0xd, 
-       0x5a, 0xa4, 0x22, 0xea, 0xd0, 0xa9, 0x5d, 0xd0, 0x4b, 0x85, 
-       0xcc, 0xdc, 0xf7, 0xf, 0xc4, 0xa5, 0xa5, 0x60, 0x47, 0xbe, 
-       0x33, 0x68, 0xa7, 0xd0, 0x80, 0x13, 0xeb, 0xf6, 0x26, 0xbc, 
-       0x13, 0xb, 0xc4, 0x20, 0xea, 0x1b, 0x80, 0x1, 0x87, 0xb2, 
-       0x8a, 0xa6, 0xb7, 0x95, 0xe7, 0x8, 0x50, 0x9d, 0xf7, 0x90, 
-       0xd5, 0x2b, 0x7f, 0x2e, 0x68, 0x28, 0x66, 0x86, 0x96, 0x50, 
-       0x45, 0x27, 0xda, 0x38, 0x2b, 0x35, 0x14, 0x40, 0xb8, 0x8c, 
-       0xd9, 0xa2, 0x69, 0x84, 0x1c, 0xc5, 0xd, 0x48, 0x82, 0x97, 
-       0x94, 0x3d, 0x6, 0x7f, 0x7a, 0xb8, 0x48, 0x43, 0x48, 0x43, 
-       0x25, 0x2c, 0x13, 0x12, 0x15, 0xe5, 0xbf, 0xbc, 0x84, 0x13, 
-       0x6d, 0xd9, 0x70, 0x9d, 0x4e, 0x6d, 0x27, 0xaa, 0xc9, 0x99, 
-       0x2d, 0x84, 0x1c, 0x91, 0xc, 0xfa, 0x2c, 0xef, 0xb9, 0x4, 
-       0xb9, 0x32, 0xaf, 0xa2, 0x39, 0xf8, 0xca, 0x73, 0xf9, 0xab, 
-       0x22, 0xfd, 0xc9, 0x2b, 0x76, 0xe3, 0x11, 0xc4, 0xe4, 0xc4, 
-       0xe9, 0x17, 0x1a, 0xd7, 0x2f, 0xce, 0xa, 0x74, 0x76, 0x48, 
-       0xd7, 0x52, 0x84, 0xa, 0xc9, 0x1f, 0x66, 0xb1, 0x7e, 0x3c, 
-       0x7a, 0x4f, 0xf8, 0x5c, 0x2d, 0xcb, 0x33, 0x78, 0x6a, 0xcf, 
-       0xee, 0x3a, 0x87, 0x93, 0x2a, 0x89, 0x80, 0xd8, 0xb2, 0x6e, 
-       0xd2, 0x2, 0xad, 0xfb, 0xd6, 0x71, 0x37, 0x18, 0x4, 0x7b, 
-       0x92, 0x28, 0x25, 0x87, 0xa5, 0x7a, 0xb9, 0xd1, 0xfe, 0x3b, 
-       0x97, 0x51, 0x9d, 0x61, 0xde, 0x41, 0x29, 0x40, 0x1, 0xbf, 
-       0xbd, 0x70, 0x62, 0x9e, 0xc, 0xb4, 0x1f, 0xb7, 0x74, 0x9, 
-       0x13, 0x4d, 0x2a, 0xd6, 0xda, 0x22, 0xdc, 0x61, 0x60, 0x5e, 
-       0x97, 0x6c, 0x9e, 0x41, 0x8d, 0x1f, 0x50, 0xbb, 0x71, 0xeb, 
-       0x1b, 0x55, 0x5d, 0xf0, 0x3e, 0xd8, 0x82, 0xe8, 0xf7, 0xcf, 
-       0x3, 0xb0, 0x23, 0x41, 0x91, 0xe1, 0xe3, 0x33, 0xe2, 0xe1, 
-       0x41, 0x77, 0x2b, 0x66, 0x50, 0x18, 0x77, 0xe9, 0x5c, 0x5e, 
-       0xf0, 0x4, 0x12, 0x25, 0x96, 0x10, 0xf3, 0x48, 0x46, 0xe5, 
-       0x38, 0x3, 0x4e, 0xe1, 0x93, 0xcd, 0xab, 0x26, 0x55, 0x56, 
-       0x9, 0x8c, 0x39, 0x49, 0xca, 0xe8, 0x93, 0x4, 0x4d, 0xd8, 
-       0xb, 0xbb, 0x3a, 0x87, 0xc6, 0xbf, 0x56, 0x1e, 0x7, 0x80, 
-       0x39, 0xa0, 0xc8, 0x81, 0x8d, 0x19, 0x2f, 0xc6, 0x7c, 0xbd, 
-       0x5e, 0xc0, 0x28, 0x16, 0x17, 0x50, 0x7a, 0xdc, 0x2, 0xd8, 
-       0xcd, 0xf3, 0x92, 0x17, 0x96, 0x4f, 0x89, 0xc8, 0xc, 0x56, 
-       0x33, 0xcb, 0x63, 0x57, 0x11, 0xc5, 0xa5, 0x8, 0x7b, 0xb3, 
-       0xf4, 0x43, 0x8f, 0x8e, 0x8c, 0x98, 0x36, 0xe8, 0x6, 0xdd, 
-       0x7d, 0x9a, 0x94, 0x15, 0xb3, 0x3c, 0x23, 0x43, 0x4b, 0x3e, 
-       0x94, 0x2e, 0x6c, 0xe6, 0xa1, 0xd, 0x1a, 0x25, 0x31, 0x85, 
-       0x15, 0x14, 0x17, 0x98, 0x6f, 0x68, 0xec, 0x5c, 0xb0, 0x91, 
-       0x70, 0x81, 0x32, 0xcf, 0x1e, 0x6b, 0xf7, 0xcd, 0x7, 0xeb, 
-       0x67, 0x1, 0xf0, 0x2e, 0x16, 0x23, 0xa0, 0xc0, 0xac, 0xd8, 
-       0x5d, 0x9c, 0xad, 0x7b, 0x8d, 0xcc, 0x89, 0xcd, 0x3c, 0x58, 
-       0x87, 0x55, 0x27, 0xb7, 0x90, 0x6a, 0xb6, 0xf1, 0xd, 0x15, 
-       0x65, 0x4, 0x55, 0x45, 0x6e, 0xd9, 0x5b, 0x27, 0x60, 0x1f, 
-       0x36, 0x25, 0x7c, 0xb3, 0x42, 0x28, 0x91, 00, 0xef, 0xff, 
-       0xce, 0x27, 0x42, 0xe0, 0x58, 0x9d, 0xa5, 0x4f, 0x28, 0x23, 
-       0xde, 0x5f, 0x24, 0x6c, 0x91, 0xe9, 0x2c, 0x35, 0xb6, 0xc8, 
-       0xd7, 0xc, 0xee, 0x50, 0x3c, 0x77, 0x72, 0xcb, 0x76, 0x42, 
-       0x3, 0x34, 0xba, 0xb4, 0xf2, 0x29, 0xf1, 0x51, 0x44, 0x43, 
-       0x8b, 0xc8, 0x8d, 0x69, 0x11, 0x32, 0xcd, 0x17, 0xef, 0xfa, 
-       0xcf, 0xf4, 0x28, 0x61, 0x37, 0x1e, 0xcc, 0xa1, 0x37, 0x6e, 
-       0x9d, 0xa4, 0x40, 0x51, 0x28, 0x31, 0x28, 0xa8, 0x34, 0x66, 
-       0x1f, 0x48, 0x18, 0xaf, 0x49, 0x63, 0xb8, 0x92, 0x6f, 0xac, 
-       0x44, 0xdd, 0x56, 0xad, 0xcc, 0xc3, 0x6e, 0x41, 0xc3, 0x43, 
-       0x45, 0xb0, 0xec, 0xfe, 0xd9, 0x32, 0x9a, 0xb8, 0x7c, 0x2d, 
-       0xee, 0x25, 0x43, 0xe8, 0x31, 0x28, 0x83, 0x67, 0xd, 0xe0, 
-       0xb6, 0x56, 0x5f, 0x95, 0xb7, 0xd5, 0x12, 0xec, 0x56, 0x7f, 
-       0xcc, 0x5b, 0x84, 0xa6, 0x30, 0x9f, 0x5c, 0x3, 0xd6, 0x7d, 
-       0xe5, 0x5b, 0x8c, 0x46, 0xa2, 0xc0, 0xdc, 0x75, 0xf9, 0x19, 
-       0x7a, 0xc, 0xca, 0xdb, 0x9e, 0xc7, 0xa1, 0xc9, 0xa1, 0x71, 
-       0x65, 0xd3, 0xf6, 0x38, 0xb6, 0xdc, 0xf3, 0x10, 0x90, 0x5b, 
-       0x16, 0x5b, 0x23, 0x33, 0x42, 0x85, 0x89, 0xc0, 0x6e, 0xda, 
-       0xe4, 0xac, 0xe9, 0x26, 0x85, 0x9d, 0x9a, 0xe5, 0xc1, 0x30, 
-       0x95, 0x55, 0x3c, 0xc9, 0xd9, 0xe1, 0x6f, 0xfd, 0xd, 0x9a, 
-       0x8c, 0x51, 0xe3, 0x9b, 0x6c, 0x10, 0xcc, 0x82, 0x5b, 0x37, 
-       0x3a, 0x82, 0xc7, 0xe4, 0xcf, 0x66, 0xea, 0xe, 0x91, 0x4b, 
-       0xbe, 0x95, 0x7, 0xf2, 0x40, 0x10, 0x22, 0x43, 0x5e, 0x82, 
-       0xc2, 0xe4, 0x97, 0x2d, 0xdf, 0x6, 0xce, 0xcb, 0x30, 0xec, 
-       0x24, 0x93, 0x97, 0x6b, 0xd3, 0x24, 0xec, 0x1c, 0x33, 0x7, 
-       0xda, 0x4b, 0xb, 0xdc, 0x23, 0x60, 0xe4, 0xaf, 0x8d, 0xff, 
-       0x81, 0x27, 0x8a, 0x94, 0x96, 0x4d, 0xa1, 0x38, 0x93, 0x39, 
-       0x67, 0x61, 0x73, 0x3b, 0x27, 0x9a, 0x72, 0xba, 0x60, 0xf1, 
-       0xc8, 0x98, 0x68, 0xe5, 0xcb, 0x70, 0x61, 0xc6, 0xd2, 0x22, 
-       0xe5, 0x22, 0xe, 0x10, 0xc2, 0x30, 0x8e, 0xb8, 0x4f, 0xc9, 
-       0x86, 0x8e, 0x17, 0x72, 0xff, 0x9c, 0xfd, 0xc, 0xfc, 0xf8, 
-       0xe8, 0xf0, 0x11, 0x17, 0x70, 0xbf, 0x69, 0x87, 0xf3, 0x60, 
-       0x48, 0xc, 0xcd, 0xa6, 0xb0, 0x14, 0x17, 0x62, 0x4d, 0x53, 
-       0xaf, 0x6a, 0x89, 0x13, 0x89, 0xc4, 0x7d, 0x73, 0x52, 0x16, 
-       0x6c, 0x86, 0x9, 0x23, 0x5b, 0x59, 0xc0, 0x5a, 0x52, 0xb0, 
-       0x1, 0x1f, 0xbc, 0x77, 0x65, 0xd6, 0x1, 0x25, 0x6, 0xf5, 
-       0xf4, 0x74, 0xe1, 0xe0, 0x8d, 0x85, 0xc6, 0x3f, 0x47, 0xcc, 
-       0x26, 0xc0, 0xe6, 0x66, 0xa1, 0xc9, 0x46, 0xd1, 0x25, 0xd1, 
-       0x45, 0x12, 0x6a, 0xfc, 0xf3, 0x24, 0xd, 0x85, 0x3f, 00, 
-       0x23, 0xd5, 0x6e, 0xb1, 0x16, 0x63, 0x11, 0x1c, 0x30, 0x24, 
-       0xd3, 00, 0x14, 0xcd, 0xb3, 0xac, 0x4, 0xbd, 0x10, 0xfd, 
-       0x1b, 0x15, 0x93, 0x82, 0x5d, 0xb1, 0xc, 0x49, 0xf1, 0xfa, 
-       0x67, 0x9f, 0x24, 0xec, 0x1e, 0x6e, 0x10, 0x6c, 0xb5, 0x5a, 
-       0x34, 0xc1, 0xe0, 0x83, 0x1c, 0x83, 0xcd, 0xc3, 0x2c, 0xb0, 
-       0x16, 0xd1, 0x65, 0xf0, 0x41, 0x11, 0x36, 0x6a, 0xdf, 0x76, 
-       0x5f, 0x70, 0x25, 0x7a, 0xbb, 0x32, 0x54, 0x82, 0x60, 0xc5, 
-       0x22, 0x91, 0x67, 0x75, 0xf7, 0x63, 0xb, 0x16, 0xb3, 0xba, 
-       0x5f, 0xa5, 0xc8, 0xe0, 0x68, 0x46, 0x53, 0x69, 0xab, 0x54, 
-       0xea, 0x8a, 0x94, 0x47, 0xeb, 0x30, 0x68, 0x73, 0x4a, 0xe2, 
-       0x2f, 0xf7, 0x24, 0x4a, 0xca, 0x8b, 0xfd, 0xc6, 0xc9, 0x9f, 
-       0xa8, 0x47, 0x66, 0x96, 0xa2, 0xa1, 0x9, 0x4e, 0x7f, 0x3f, 
-       0x8e, 0x43, 0x47, 0x1a, 0x5f, 0xaf, 0x98, 0xab, 0xf1, 0x75, 
-       0xa0, 0x50, 0x35, 0x15, 0xc8, 0xce, 0x44, 0x53, 0x69, 0x32, 
-       0x55, 0x46, 0x9d, 0x7a, 0xa2, 0xe, 0xfc, 0xb0, 0xa7, 0xad, 
-       0x1e, 0xc6, 0xda, 0x63, 0x67, 0xfa, 0xb, 0x42, 0x59, 0xb1, 
-       0x8, 0xdb, 0x49, 0x45, 0xc0, 0xdf, 0x1f, 0x45, 0xe7, 0x50, 
-       0xb3, 0x65, 0xa0, 0x5a, 0xb6, 0xf7, 0xe3, 0x4, 0xd6, 0xb0, 
-       0xc6, 0x5, 0x6a, 0x55, 0xb9, 0x3a, 0xd4, 0xae, 0x92, 0x85, 
-       0xbd, 0xb8, 0x26, 0x24, 0x92, 0x7d, 0xea, 0xe5, 0x94, 0x2, 
-       0xb5, 0xa2, 0x3e, 0xe2, 0x8c, 0xc8, 0xdd, 0x36, 0xe8, 0x16, 
-       0x96, 0x5d, 0x82, 0x5, 0xd4, 0x1a, 0x23, 0x8b, 0x51, 0x69, 
-       0x4f, 0xe0, 0x8b, 0x99, 0x8b, 0x3d, 0xbe, 0x9b, 0xcd, 0x41, 
-       0x88, 0xb1, 0xdd, 0xc3, 0x4c, 0x44, 0x79, 0xcc, 0x82, 0xdc, 
-       0x8d, 0x47, 0x81, 0xfb, 0x4e, 0xc7, 0x3, 0xcd, 0x3b, 0xa0, 
-       0x72, 0xb1, 0x5, 0x1, 0xfd, 0x2a, 0xa, 0x8f, 0xf9, 0xf3, 
-       0x35, 0x47, 0x7c, 0x8a, 0xa5, 0x47, 0x26, 0x2b, 0xb3, 0xd0, 
-       0xf3, 0xad, 0xab, 0x72, 0x5b, 0x99, 0xa3, 0x7, 0xd7, 0x10, 
-       0xce, 0x63, 0x58, 0x8, 0x5a, 0x6e, 0x9, 0xd1, 0xcd, 0x45, 
-       0xc0, 0xbb, 0x55, 0x77, 0xc8, 0x20, 0xe0, 0x76, 0x41, 0xad, 
-       0xee, 0x15, 0x4b, 0xb6, 0x10, 0xdb, 0x73, 0xc4, 0x5f, 0x6a, 
-       0x2e, 0x5c, 0x18, 0x11, 0x6c, 0x6, 0xf7, 0xfa, 0xb9, 0x8b, 
-       0x32, 0x3b, 0x21, 0xd3, 0xeb, 0x94, 0xff, 0x17, 0xf0, 0xd5, 
-       0xd5, 0xc6, 0x9c, 0xd4, 0xe0, 0xf0, 0x8, 0x31, 0xbe, 0x1, 
-       0x83, 0x61, 0x1c, 0xb6, 0x2c, 0x4, 0x4c, 0xf2, 0x75, 0xc, 
-       0x8a, 0x5, 0x5, 0x37, 0xc8, 0x80, 0xb, 0xed, 0x9a, 0xc3, 
-       0x6, 0x19, 0x37, 0x90, 0x7e, 0xdc, 0x4a, 0x32, 0x82, 0xd4, 
-       0x29, 0x92, 0xd9, 0x3e, 0xdc, 0x71, 0x26, 0xcd, 0x30, 0x47, 
-       0x1e, 0xde, 0x82, 0x18, 0x7d, 0x3, 0x4b, 0x8c, 0xe6, 0xc, 
-       0x56, 0x57, 0xc3, 0x2d, 0x49, 0x70, 0x9f, 0x17, 0x18, 0xee, 
-       0x56, 0x98, 0x8b, 0x59, 0xf2, 0x98, 0x2e, 0x59, 0xd8, 0x18, 
-       0xeb, 0xf5, 0x31, 0xf0, 0xe9, 0x91, 0x43, 0xc4, 0x8b, 0x4, 
-       0x32, 0xca, 0x91, 0xc4, 0xfd, 0x2a, 0xd2, 0xa, 0x9a, 0x2a, 
-       0x6c, 0x41, 0x8b, 0xcc, 0xd, 0xe7, 0x89, 0x8b, 0x1c, 0x4c, 
-       0xbe, 0xcf, 0xd1, 0xf0, 0x66, 0x20, 0x67, 0x5, 0x92, 0xf1, 
-       0x8e, 0x41, 0x1e, 0xb3, 0x51, 0x7f, 0x5e, 0x10, 0x4, 0xb8, 
-       0x8a, 0x3d, 0x1f, 0x91, 0xab, 0x51, 0xc0, 0xa2, 0x6e, 0x1a, 
-       0x7f, 0x53, 0x63, 0x29, 0x4, 0x6b, 0xa1, 0xa6, 0x78, 0x4c, 
-       0x9e, 0x8e, 0xc7, 0xc8, 0x64, 0x29, 0x86, 0x13, 0x65, 0x1f, 
-       0xd4, 0xe8, 0xe6, 0xb7, 0x3a, 0x47, 0xba, 0xca, 0xde, 0xf1, 
-       0x5c, 0x5e, 0xf3, 0x63, 0x65, 0x2c, 0x15, 0x65, 0x35, 0xba, 
-       0xb4, 0xde, 0xe6, 0xd0, 0xef, 0xe8, 0xe5, 0x82, 0x33, 0xfe, 
-       0xdd, 0xe6, 0xd, 0xf9, 0x7e, 0xb3, 0x78, 0x61, 0x96, 0xe3, 
-       0xa6, 0xa3, 00, 0x59, 0xd8, 0xae, 0xa2, 0xbe, 0x21, 0x68, 
-       0xff, 0xf, 0xc0, 0xd, 0x6, 0x12, 0x9f, 0x6f, 0x55, 0x17, 
-       0x36, 0x35, 0x1c, 0xb9, 0xd5, 0x81, 0x6, 0xfd, 0xc2, 0xb2, 
-       0xb9, 0x51, 0x58, 0xa8, 0x9d, 00, 0xb3, 0x39, 0x1f, 0x51, 
-       0x6, 0xfe, 0xc, 0xb5, 0xcc, 0x62, 0xa5, 0xf1, 0x21, 0x9, 
-       0x2b, 0x77, 0x99, 0xf9, 0xfe, 0x6e, 0x3f, 0x75, 0xc9, 0x60, 
-       0x53, 0x90, 0x3b, 0xe5, 0x7b, 0xf5, 0xab, 0x28, 0xc0, 0x66, 
-       0x47, 0x1b, 0x54, 0x3d, 0x34, 0xf3, 0x36, 0x6c, 0x3f, 0x1f, 
-       0xe6, 0xe2, 0x2a, 0x59, 0xf1, 0x2c, 0x21, 0xf8, 0xa7, 0xba, 
-       0xdf, 0x58, 0x7, 0xeb, 0xd0, 0x66, 0x69, 0xb1, 0xeb, 0x9e, 
-       0x7d, 0x20, 0xd6, 0x78, 0xd9, 0xde, 0xc, 0x14, 0x26, 0x7b, 
-       0x8b, 0x8e, 0xd0, 0x25, 0xb3, 0x2f, 0x95, 0xf4, 0xb8, 0x1f, 
-       0x95, 0xb0, 0x98, 0x74, 0xdc, 0x95, 0x87, 0x11, 0x56, 0x8, 
-       0xb0, 0x9c, 0x38, 0x27, 0xdf, 0x68, 0x24, 0xc0, 0x84, 0xa7, 
-       0x3f, 0x2d, 0xef, 0x94, 0x36, 0x86, 0x16, 0x8, 0x64, 0xc2, 
-       0x8b, 0xa4, 0xbd, 0x36, 0xa, 0x28, 0xc2, 0xb2, 0x26, 0xdc, 
-       0xd, 0xe, 0x17, 0x77, 0xcb, 0x98, 0x50, 0xef, 0x4a, 0xe6, 
-       0xce, 0x2f, 0x6b, 0x41, 0x53, 0xe3, 0xbb, 0x3c, 0x3c, 0x44, 
-       0xa0, 0xd6, 0x73, 0x28, 0x5e, 0x10, 0xa3, 0xa4, 0xa4, 0xe9, 
-       0x62, 0xb, 0x40, 0xb6, 0x56, 0x31, 0x20, 0x3c, 0x28, 0x39, 
-       0x89, 0xa0, 0x84, 0x4b, 0x8a, 0xec, 0x57, 0xa0, 0xd1, 0xc, 
-       0xb5, 0xa, 0xba, 0xeb, 0x28, 0x3c, 0x8, 0xa4, 0xae, 0xa6, 
-       0x2e, 0x99, 0x4a, 0x2f, 0x31, 0xe5, 0xbf, 0x2c, 0xa5, 0xfa, 
-       0xff, 0xd, 0x47, 0x6f, 0x42, 0x2, 0x70, 0xd7, 0xcb, 0x76, 
-       0xb5, 0x4d, 0xcb, 0x12, 0xac, 0x29, 0x17, 0xea, 0xd1, 0xc8, 
-       0x56, 0x43, 0x7b, 0xb0, 0x71, 0x2f, 0x5f, 0x2a, 0xc5, 0x1c, 
-       0x4b, 0x7f, 0x91, 0x9b, 0x9e, 0xd6, 0xeb, 0x9e, 0x75, 0x26, 
-       0x10, 0x36, 0x3b, 0x71, 0x11, 0x5d, 0x1, 0xb8, 0xb8, 0xd6, 
-       0xce, 0x6e, 0xdf, 0xf, 0x7, 0xc7, 0x26, 0x52, 0xe2, 0xf4, 
-       0xc7, 0x8e, 0xa, 0xa, 0xd, 0x6f, 0xd9, 0xab, 0xa5, 0x9f, 
-       0x3, 0xf0, 0xfc, 0x2b, 0x21, 0x21, 0xe4, 0x4d, 0x14, 0xac, 
-       0x8a, 0xde, 0x51, 0x1f, 0x51, 0xba, 0x22, 0x53, 0x31, 0x31, 
-       0xaa, 0xfe, 0x33, 0x2, 0xcb, 0xea, 0x5a, 0x83, 0xc0, 0x85, 
-       0x1d, 0xbe, 0xb, 0x23, 0x89, 0x43, 0xf7, 0xff, 0x1f, 0xef, 
-       0x40, 0x7c, 0x19, 0x90, 0x2d, 0xa8, 0xbe, 0xbd, 0xe9, 0xe9, 
-       0x2f, 0x5e, 0xd0, 0x55, 0x51, 0x20, 0x40, 0x56, 0x50, 0x7d, 
-       0xa7, 0x9c, 0xe0, 0x96, 0xd9, 0xef, 0x86, 0xa0, 0x40, 0xe3, 
-       0xab, 0xfe, 0xc6, 0x56, 0xf5, 0x97, 0xbc, 0x18, 0xf7, 0xe5, 
-       0x81, 0x77, 0x63, 0x76, 0x3a, 0x54, 0x50, 0x1d, 0x59, 0x2f, 
-       0xf0, 0x70, 0xb3, 0xdc, 0xf0, 0x5d, 0xf8, 0x3e, 0x8f, 0x87, 
-       0x69, 0xd9, 0x70, 0xea, 0x71, 0xdf, 0xd2, 0xea, 0x5, 0x4d, 
-       0x12, 0x82, 0x93, 0x70, 0x8b, 0x1e, 0x17, 0x76, 0xbe, 0xe0, 
-       0x68, 0x8d, 0xc0, 0xad, 0xce, 0xd0, 0x33, 0x76, 0xbd, 0x79, 
-       0xd4, 0x77, 0x21, 0xa6, 0x16, 0x46, 0x8e, 0xbb, 0x7e, 0x8d, 
-       0xba, 0xad, 0x1, 0x80, 0xf9, 0x7b, 0x7, 0xb1, 0x34, 0x2e, 
-       0x6c, 0xe2, 0x5a, 0x87, 0xb0, 0xe8, 0x2f, 0x6d, 0xe9, 0x10, 
-       0x5e, 0x14, 0xf0, 0x30, 0x7a, 0x5b, 0x8, 0x93, 0x5f, 0xd3, 
-       0xf8, 0xe, 0xc8, 0x64, 0x1, 0x95, 0x40, 0x40, 0x36, 0x66, 
-       0x9f, 0xc4, 0x97, 0x3, 0xa7, 0x18, 0x32, 0x61, 0xf3, 0x4a, 
-       0xa2, 0x1f, 0x95, 0x6b, 0x30, 0x9, 0x91, 0x6b, 0xe3, 0x57, 
-       0x8f, 0x2c, 0x4a, 0x8c, 0xa7, 0x2c, 0x93, 0x5, 0x3c, 0x8a, 
-       0x76, 0x2c, 0x28, 0xb8, 0xd5, 0x59, 0x53, 0xd5, 0xce, 0x81, 
-       0xb0, 0xb9, 0xe2, 0x4a, 0x9e, 0x44, 0x56, 0x1c, 0xfc, 0x98, 
-       0x81, 0x6f, 0xfc, 0x9d, 0xfc, 0xac, 0xcc, 0xc5, 0xd3, 0x84, 
-       0x4e, 0x9b, 0x98, 0xb8, 0xfa, 0xbb, 0xd9, 0x1c, 0x8, 0xdd, 
-       0xfc, 0x8a, 0xec, 0x42, 0xc4, 0x1, 0xe5, 0x3e, 0xb7, 0x80, 
-       0xe2, 0xeb, 0xd7, 0xc0, 0x1, 0x13, 0x1, 0xc6, 0x4c, 0x6a, 
-       0x4b, 0x83, 0x81, 0x9, 0x59, 0xd8, 0x84, 0x77, 0xdc, 0x20, 
-       0x4, 0x5b, 0xfd, 0x9b, 0x12, 0x50, 0x26, 0x1a, 0x4d, 0x6f, 
-       0xcb, 0x6, 0x1c, 0x5f, 0x2d, 0xaf, 0x67, 0xa, 0xfe, 0x33, 
-       0x12, 0x81, 0x50, 0xb1, 0x51, 0x83, 0xc4, 0xc9, 0xf4, 0xfd, 
-       0xf, 0x26, 0x50, 0x51, 0x40, 0x20, 0x9, 0x2b, 0xbe, 0x6b, 
-       0xf0, 0xd9, 0xc3, 0xbf, 0x18, 0x14, 0x8, 0xf4, 0x9c, 0x94, 
-       0xde, 0xd8, 0x30, 0x14, 0x9, 0xbb, 0xc7, 0x46, 0xde, 0xe, 
-       0x5d, 0xec, 0xc2, 0x2, 0xbf, 0x13, 0xc1, 0xf5, 0xe8, 0xfe, 
-       00, 0x4f, 0xdf, 0x26, 0x55, 0x1a, 0x76, 0x69, 0x81, 0x3e, 
-       0x84, 0x19, 0xcd, 0x16, 0xb7, 0x76, 0x99, 0xc3, 0x87, 0xbd, 
-       0xb1, 0xda, 0x89, 0x32, 0xe2, 0x7b, 0x71, 0x76, 0x52, 0xf1, 
-       0x8c, 0x1, 0x24, 0x8a, 0x2f, 0x8d, 0x72, 0x53, 0xff, 0x6f, 
-       0xeb, 0x1e, 0xdb, 0x1b, 0x4, 0x5e, 0x9c, 0xf2, 0xff, 0x7c, 
-       0x25, 0x11, 0xfc, 0x1d, 0xe1, 0x4f, 0x26, 0xaf, 0xbd, 0xea, 
-       0x67, 0xf9, 0x6f, 0x2a, 0x60, 0x7e, 0x32, 0x3b, 0x43, 0x10, 
-       0x16, 0x80, 0xdf, 0xbf, 0xa5, 0x7f, 0x2f, 0xe9, 0x17, 0xcd, 
-       0xf4, 0x47, 0x15, 0x44, 0x8, 0xda, 0xc8, 0x7e, 0x36, 0x50, 
-       0x28, 0x6e, 0x21, 0xfe, 0x1f, 0xd2, 0xa8, 0xa2, 0x91, 0xdc, 
-       0x83, 0x90, 0x3, 00, 00, 00, 00, 0x49, 0x45, 0x4e, 
-       0x44, 0xae, 0x42, 0x60, 0x82, };
-
-static const char data_cgi_files[] = {
-       /* /cgi/files */
-       0x2f, 0x63, 0x67, 0x69, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0,
-       0x23, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x73, 0x63, 0x72, 
-       0x69, 0x70, 0x74, 0x20, 0x73, 0x68, 0x6f, 0x77, 0x73, 0x20, 
-       0x74, 0x68, 0x65, 0x20, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 
-       0x20, 0x73, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 
-       0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x64, 0x69, 0x66, 0x66, 
-       0x65, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x66, 0x69, 0x6c, 0x65, 
-       0x73, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0xd, 0xa, 
-       0x23, 0x20, 0x77, 0x65, 0x62, 0x20, 0x73, 0x65, 0x72, 0x76, 
-       0x65, 0x72, 0x2e, 0xd, 0xa, 0x23, 0xd, 0xa, 0x23, 0x20, 
-       0x46, 0x69, 0x72, 0x73, 0x74, 0x2c, 0x20, 0x77, 0x65, 0x20, 
-       0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x20, 0x74, 0x68, 
-       0x65, 0x20, 0x48, 0x54, 0x4d, 0x4c, 0x20, 0x68, 0x65, 0x61, 
-       0x64, 0x65, 0x72, 0x2e, 0xd, 0xa, 0x69, 0x20, 0x2f, 0x66, 
-       0x69, 0x6c, 0x65, 0x73, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65, 
-       0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa, 0x23, 0x20, 
-       0x50, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x6f, 0x75, 0x74, 0x20, 
-       0x74, 0x68, 0x65, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x6f, 
-       0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x6c, 0x65, 
-       0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x61, 0x6c, 0x6c, 
-       0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 
-       0x69, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x70, 
-       0x72, 0x69, 0x6e, 0x74, 0x73, 0xd, 0xa, 0x23, 0x20, 0x74, 
-       0x68, 0x65, 0x20, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 
-       0x73, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 
-       0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x66, 
-       0x69, 0x6c, 0x65, 0x2e, 0xd, 0xa, 0x74, 0x20, 0x3c, 0x74, 
-       0x72, 0x3e, 0x3c, 0x74, 0x64, 0x3e, 0x3c, 0x61, 0x20, 0x68, 
-       0x72, 0x65, 0x66, 0x3d, 0x22, 0x2f, 0x69, 0x6e, 0x64, 0x65, 
-       0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x2f, 0x69, 
-       0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x3c, 
-       0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x74, 
-       0x64, 0x3e, 0xd, 0xa, 0x63, 0x20, 0x62, 0x20, 0x2f, 0x69, 
-       0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0xd, 
-       0xa, 0x74, 0x20, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x2f, 
-       0x74, 0x72, 0x3e, 0x20, 0x3c, 0x74, 0x72, 0x3e, 0x3c, 0x74, 
-       0x64, 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 
-       0x22, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 
-       0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x2f, 0x63, 0x6f, 0x6e, 
-       0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x3c, 
-       0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x74, 
-       0x64, 0x3e, 0xd, 0xa, 0x63, 0x20, 0x62, 0x20, 0x2f, 0x63, 
-       0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x68, 0x74, 0x6d, 
-       0x6c, 0xd, 0xa, 0x74, 0x20, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 
-       0x3c, 0x2f, 0x74, 0x72, 0x3e, 0x20, 0x3c, 0x74, 0x72, 0x3e, 
-       0x3c, 0x74, 0x64, 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 
-       0x66, 0x3d, 0x22, 0x2f, 0x69, 0x6d, 0x67, 0x2f, 0x6c, 0x6f, 
-       0x67, 0x6f, 0x2e, 0x70, 0x6e, 0x67, 0x22, 0x3e, 0x2f, 0x69, 
-       0x6d, 0x67, 0x2f, 0x6c, 0x6f, 0x67, 0x6f, 0x2e, 0x70, 0x6e, 
-       0x67, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 
-       0x3c, 0x74, 0x64, 0x3e, 0xd, 0xa, 0x63, 0x20, 0x62, 0x20, 
-       0x2f, 0x69, 0x6d, 0x67, 0x2f, 0x6c, 0x6f, 0x67, 0x6f, 0x2e, 
-       0x70, 0x6e, 0x67, 0xd, 0xa, 0x74, 0x20, 0x3c, 0x2f, 0x74, 
-       0x64, 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0x20, 0x3c, 0x74, 
-       0x72, 0x3e, 0x3c, 0x74, 0x64, 0x3e, 0x3c, 0x61, 0x20, 0x68, 
-       0x72, 0x65, 0x66, 0x3d, 0x22, 0x2f, 0x34, 0x30, 0x34, 0x2e, 
-       0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x2f, 0x34, 0x30, 0x34, 
-       0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 
-       0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x74, 0x64, 0x3e, 0xd, 0xa, 
-       0x63, 0x20, 0x62, 0x20, 0x2f, 0x34, 0x30, 0x34, 0x2e, 0x68, 
-       0x74, 0x6d, 0x6c, 0xd, 0xa, 0x74, 0x20, 0x3c, 0x2f, 0x74, 
-       0x64, 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0x20, 0x3c, 0x74, 
-       0x72, 0x3e, 0x3c, 0x74, 0x64, 0x3e, 0x3c, 0x61, 0x20, 0x68, 
-       0x72, 0x65, 0x66, 0x3d, 0x22, 0x2f, 0x63, 0x67, 0x69, 0x2f, 
-       0x66, 0x69, 0x6c, 0x65, 0x73, 0x22, 0x3e, 0x2f, 0x63, 0x67, 
-       0x69, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x3c, 0x2f, 0x61, 
-       0x3e, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x74, 0x64, 0x3e, 
-       0xd, 0xa, 0x63, 0x20, 0x62, 0x20, 0x2f, 0x63, 0x67, 0x69, 
-       0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0xd, 0xa, 0x74, 0x20, 
-       0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 
-       0x20, 0x3c, 0x74, 0x72, 0x3e, 0x3c, 0x74, 0x64, 0x3e, 0x3c, 
-       0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x2f, 0x63, 
-       0x67, 0x69, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x22, 0x3e, 
-       0x2f, 0x63, 0x67, 0x69, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x73, 
-       0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 
-       0x74, 0x64, 0x3e, 0xd, 0xa, 0x63, 0x20, 0x62, 0x20, 0x2f, 
-       0x63, 0x67, 0x69, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x73, 0xd, 
-       0xa, 0x74, 0x20, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x2f, 
-       0x74, 0x72, 0x3e, 0x20, 0x3c, 0x74, 0x72, 0x3e, 0x3c, 0x74, 
-       0x64, 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 
-       0x22, 0x2f, 0x63, 0x67, 0x69, 0x2f, 0x74, 0x63, 0x70, 0x22, 
-       0x3e, 0x2f, 0x63, 0x67, 0x69, 0x2f, 0x74, 0x63, 0x70, 0x3c, 
-       0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x74, 
-       0x64, 0x3e, 0xd, 0xa, 0x63, 0x20, 0x62, 0x20, 0x2f, 0x63, 
-       0x67, 0x69, 0x2f, 0x74, 0x63, 0x70, 0xd, 0xa, 0x74, 0x20, 
-       0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 
-       0xd, 0xa, 0x23, 0x20, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x64, 
-       0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x48, 0x54, 0x4d, 0x4c, 
-       0x20, 0x66, 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x2e, 0xd, 0xa, 
-       0x69, 0x20, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x5f, 0x66, 
-       0x6f, 0x6f, 0x74, 0x65, 0x72, 0x2e, 0x70, 0x6c, 0x61, 0x69, 
-       0x6e, 0xd, 0xa, 0x23, 0x20, 0x45, 0x6e, 0x64, 0x20, 0x6f, 
-       0x66, 0x20, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x2e, 0xd, 
-       0xa, 0x2e, };
-
-static const char data_cgi_stats[] = {
-       /* /cgi/stats */
-       0x2f, 0x63, 0x67, 0x69, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x73, 0,
-       0x69, 0x20, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x5f, 0x68, 
-       0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 
-       0xd, 0xa, 0x63, 0x20, 0x61, 0xd, 0xa, 0x69, 0x20, 0x2f, 
-       0x73, 0x74, 0x61, 0x74, 0x73, 0x5f, 0x66, 0x6f, 0x6f, 0x74, 
-       0x65, 0x72, 0x2e, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0xd, 0xa, 
-       0x2e, 0xd, 0xa, };
-
-static const char data_cgi_tcp[] = {
-       /* /cgi/tcp */
-       0x2f, 0x63, 0x67, 0x69, 0x2f, 0x74, 0x63, 0x70, 0,
-       0x69, 0x20, 0x2f, 0x74, 0x63, 0x70, 0x5f, 0x68, 0x65, 0x61, 
-       0x64, 0x65, 0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa, 
-       0x63, 0x20, 0x63, 0xd, 0xa, 0x69, 0x20, 0x2f, 0x74, 0x63, 
-       0x70, 0x5f, 0x66, 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x2e, 0x70, 
-       0x6c, 0x61, 0x69, 0x6e, 0xd, 0xa, 0x2e, };
-
-static const char data_cgi_rtos[] = {
-       /* /cgi/rtos */
-       0x2f, 0x63, 0x67, 0x69, 0x2f, 0x72, 0x74, 0x6f, 0x73, 0,
-       0x74, 0x20, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x3c, 0x68, 
-       0x65, 0x61, 0x64, 0x3e, 0x3c, 0x74, 0x69, 0x74, 0x6c, 0x65, 
-       0x3e, 0x75, 0x49, 0x50, 0x20, 0x4f, 0x70, 0x65, 0x6e, 0x20, 
-       0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x20, 0x45, 0x6d, 0x62, 
-       0x65, 0x64, 0x64, 0x65, 0x64, 0x20, 0x54, 0x43, 0x50, 0x2f, 
-       0x49, 0x50, 0x20, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x20, 0x4f, 
-       0x6e, 0x20, 0x46, 0x72, 0x65, 0x65, 0x52, 0x54, 0x4f, 0x53, 
-       0x20, 0x4b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x3c, 0x2f, 0x74, 
-       0x69, 0x74, 0x6c, 0x65, 0x3e, 0x3c, 0x2f, 0x68, 0x65, 0x61, 
-       0x64, 0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x42, 0x47, 
-       0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x3d, 0x22, 0x23, 0x43, 0x43, 
-       0x43, 0x43, 0x46, 0x46, 0x22, 0x3e, 0x3c, 0x66, 0x6f, 0x6e, 
-       0x74, 0x20, 0x66, 0x61, 0x63, 0x65, 0x3d, 0x22, 0x61, 0x72, 
-       0x69, 0x61, 0x6c, 0x22, 0x3e, 0x3c, 0x73, 0x6d, 0x61, 0x6c, 
-       0x6c, 0x3e, 0x3c, 0x62, 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72, 
-       0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 
-       0x2f, 0x77, 0x77, 0x77, 0x2e, 0x66, 0x72, 0x65, 0x65, 0x72, 
-       0x74, 0x6f, 0x73, 0x2e, 0x6f, 0x72, 0x67, 0x22, 0x20, 0x74, 
-       0x61, 0x72, 0x67, 0x65, 0x74, 0x3d, 0x22, 0x5f, 0x74, 0x6f, 
-       0x70, 0x22, 0x3e, 0x46, 0x72, 0x65, 0x65, 0x52, 0x54, 0x4f, 
-       0x53, 0x20, 0x48, 0x6f, 0x6d, 0x65, 0x70, 0x61, 0x67, 0x65, 
-       0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x62, 0x3e, 0x3c, 0x2f, 
-       0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x3e, 0x3c, 0x70, 0x3e, 0x3c, 
-       0x48, 0x31, 0x3e, 0x41, 0x54, 0x39, 0x31, 0x53, 0x41, 0x4d, 
-       0x37, 0x58, 0x20, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 
-       0x64, 0x20, 0x57, 0x45, 0x42, 0x20, 0x53, 0x65, 0x72, 0x76, 
-       0x65, 0x72, 0x20, 0x44, 0x65, 0x6d, 0x6f, 0x3c, 0x62, 0x72, 
-       0x3e, 0x3c, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x3e, 0x55, 0x73, 
-       0x69, 0x6e, 0x67, 0x20, 0x75, 0x49, 0x50, 0x20, 0x61, 0x6e, 
-       0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x46, 0x72, 0x65, 0x65, 
-       0x52, 0x54, 0x4f, 0x53, 0x20, 0x72, 0x65, 0x61, 0x6c, 0x20, 
-       0x74, 0x69, 0x6d, 0x65, 0x20, 0x6b, 0x65, 0x72, 0x6e, 0x65, 
-       0x6c, 0x3c, 0x2f, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x3e, 0x3c, 
-       0x2f, 0x68, 0x31, 0x3e, 0x3c, 0x70, 0x3e, 0x54, 0x68, 0x65, 
-       0x73, 0x65, 0x20, 0x70, 0x61, 0x67, 0x65, 0x73, 0x20, 0x61, 
-       0x72, 0x65, 0x20, 0x62, 0x65, 0x69, 0x6e, 0x67, 0x20, 0x73, 
-       0x65, 0x72, 0x76, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x61, 
-       0x6e, 0x20, 0x41, 0x74, 0x6d, 0x65, 0x6c, 0x20, 0x41, 0x54, 
-       0x39, 0x31, 0x53, 0x41, 0x4d, 0x37, 0x58, 0x32, 0x35, 0x36, 
-       0x20, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x63, 0x6f, 0x6e, 0x74, 
-       0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2c, 0x20, 0x75, 0x73, 
-       0x69, 0x6e, 0x67, 0x20, 0x41, 0x64, 0x61, 0x6d, 0x20, 0x44, 
-       0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x20, 0x6f, 0x70, 0x65, 
-       0x6e, 0x20, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x20, 0x75, 
-       0x49, 0x50, 0x20, 0x54, 0x43, 0x50, 0x2f, 0x49, 0x50, 0x20, 
-       0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x3c, 0x70, 0x3e, 0x54, 
-       0x68, 0x65, 0x20, 0x75, 0x49, 0x50, 0x20, 0x73, 0x74, 0x61, 
-       0x63, 0x6b, 0x20, 0x69, 0x73, 0x20, 0x65, 0x78, 0x65, 0x63, 
-       0x75, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x66, 0x72, 0x6f, 0x6d, 
-       0x20, 0x61, 0x20, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x20, 
-       0x74, 0x61, 0x73, 0x6b, 0x20, 0x75, 0x6e, 0x64, 0x65, 0x72, 
-       0x20, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x20, 0x6f, 
-       0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x46, 0x72, 0x65, 0x65, 
-       0x52, 0x54, 0x4f, 0x53, 0x20, 0x72, 0x65, 0x61, 0x6c, 0x20, 
-       0x74, 0x69, 0x6d, 0x65, 0x20, 0x6b, 0x65, 0x72, 0x6e, 0x65, 
-       0x6c, 0x2e, 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 0x74, 0x61, 
-       0x62, 0x6c, 0x65, 0x20, 0x62, 0x65, 0x6c, 0x6f, 0x77, 0x20, 
-       0x73, 0x68, 0x6f, 0x77, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 
-       0x73, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 
-       0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, 
-       0x68, 0x65, 0x20, 0x74, 0x61, 0x73, 0x6b, 0x73, 0x20, 0x69, 
-       0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x65, 0x6d, 0x6f, 
-       0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x69, 0x74, 
-       0x6f, 0x6e, 0x2e, 0x3c, 0x70, 0x3e, 0x3c, 0x70, 0x72, 0x65, 
-       0x3e, 0x54, 0x61, 0x73, 0x6b, 0x20, 0x20, 0x20, 0x20, 0x20, 
-       0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x74, 0x61, 0x74, 0x65, 
-       0x20, 0x20, 0x50, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 
-       0x20, 0x20, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x9, 0x23, 0x3c, 
-       0x62, 0x72, 0x3e, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 
-       0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 
-       0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 
-       0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 
-       0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 
-       0x2a, 0x3c, 0x62, 0x72, 0x3e, 0xa, 0x63, 0x20, 0x64, 0xa, 
-       0x74, 0x20, 0x3c, 0x2f, 0x70, 0x72, 0x65, 0x3e, 0x3c, 0x2f, 
-       0x66, 0x6f, 0x6e, 0x74, 0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 
-       0x79, 0x3e, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 
-       0x2e, 0xa, 0xa, 0xa, };
-
-static const char data_index_html[] = {
-       /* /index.html */
-       0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
-       0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, 
-       0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72, 
-       0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30, 
-       0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 
-       0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63, 
-       0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69, 
-       0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65, 
-       0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 
-       0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa, 
-       0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xd, 0xa, 
-       0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xd, 0xa, 0x3c, 0x2f, 
-       0x68, 0x65, 0x61, 0x64, 0x3e, 0xd, 0xa, 0xd, 0xa, 0x3c, 
-       0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x65, 0x74, 0x20, 0x63, 
-       0x6f, 0x6c, 0x73, 0x3d, 0x22, 0x2a, 0x22, 0x20, 0x72, 0x6f, 
-       0x77, 0x73, 0x3d, 0x22, 0x31, 0x32, 0x30, 0x2c, 0x2a, 0x22, 
-       0x20, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x62, 0x6f, 0x72, 0x64, 
-       0x65, 0x72, 0x3d, 0x22, 0x6e, 0x6f, 0x22, 0x3e, 0x20, 0xd, 
-       0xa, 0x20, 0x20, 0x3c, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x20, 
-       0x73, 0x72, 0x63, 0x3d, 0x22, 0x63, 0x6f, 0x6e, 0x74, 0x72, 
-       0x6f, 0x6c, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0xd, 
-       0xa, 0x20, 0x20, 0x3c, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x20, 
-       0x73, 0x72, 0x63, 0x3d, 0x22, 0x2f, 0x63, 0x67, 0x69, 0x2f, 
-       0x72, 0x74, 0x6f, 0x73, 0x22, 0x20, 0x6e, 0x61, 0x6d, 0x65, 
-       0x3d, 0x22, 0x6d, 0x61, 0x69, 0x6e, 0x22, 0x3e, 0xd, 0xa, 
-       0x3c, 0x2f, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x65, 0x74, 
-       0x3e, 0xd, 0xa, 0xd, 0xa, 0x3c, 0x6e, 0x6f, 0x66, 0x72, 
-       0x61, 0x6d, 0x65, 0x73, 0x3e, 0xd, 0xa, 0x3c, 0x62, 0x6f, 
-       0x64, 0x79, 0x3e, 0xd, 0xa, 0x59, 0x6f, 0x75, 0x72, 0x20, 
-       0x62, 0x72, 0x6f, 0x77, 0x73, 0x65, 0x72, 0x20, 0x6d, 0x75, 
-       0x73, 0x74, 0x20, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 
-       0x20, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, 0xd, 0xa, 0x3c, 
-       0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xd, 0xa, 0x3c, 0x2f, 
-       0x6e, 0x6f, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x3e, 0xd, 
-       0xa, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, };
-
-const struct fsdata_file file_404_html[] = {{NULL, data_404_html, data_404_html + 10, sizeof(data_404_html) - 10}};
-
-const struct fsdata_file file_control_html[] = {{file_404_html, data_control_html, data_control_html + 14, sizeof(data_control_html) - 14}};
-
-const struct fsdata_file file_files_footer_plain[] = {{file_control_html, data_files_footer_plain, data_files_footer_plain + 20, sizeof(data_files_footer_plain) - 20}};
-
-const struct fsdata_file file_files_header_html[] = {{file_files_footer_plain, data_files_header_html, data_files_header_html + 19, sizeof(data_files_header_html) - 19}};
-
-const struct fsdata_file file_stats_footer_plain[] = {{file_files_header_html, data_stats_footer_plain, data_stats_footer_plain + 20, sizeof(data_stats_footer_plain) - 20}};
-
-const struct fsdata_file file_stats_header_html[] = {{file_stats_footer_plain, data_stats_header_html, data_stats_header_html + 19, sizeof(data_stats_header_html) - 19}};
-
-const struct fsdata_file file_tcp_footer_plain[] = {{file_stats_header_html, data_tcp_footer_plain, data_tcp_footer_plain + 18, sizeof(data_tcp_footer_plain) - 18}};
-
-const struct fsdata_file file_tcp_header_html[] = {{file_tcp_footer_plain, data_tcp_header_html, data_tcp_header_html + 17, sizeof(data_tcp_header_html) - 17}};
-
-const struct fsdata_file file_img_logo_png[] = {{file_tcp_header_html, data_img_logo_png, data_img_logo_png + 14, sizeof(data_img_logo_png) - 14}};
-
-const struct fsdata_file file_cgi_files[] = {{file_img_logo_png, data_cgi_files, data_cgi_files + 11, sizeof(data_cgi_files) - 11}};
-
-const struct fsdata_file file_cgi_stats[] = {{file_cgi_files, data_cgi_stats, data_cgi_stats + 11, sizeof(data_cgi_stats) - 11}};
-
-const struct fsdata_file file_cgi_tcp[] = {{file_cgi_stats, data_cgi_tcp, data_cgi_tcp + 9, sizeof(data_cgi_tcp) - 9}};
-
-const struct fsdata_file file_cgi_rtos[] = {{file_cgi_tcp, data_cgi_rtos, data_cgi_rtos + 10, sizeof(data_cgi_rtos) - 10}};
-
-const struct fsdata_file file_index_html[] = {{file_cgi_rtos, data_index_html, data_index_html + 12, sizeof(data_index_html) - 12}};
-
-#define FS_ROOT file_index_html
-
+static const char data_404_html[] = {\r
+       /* /404.html */\r
+       0x2f, 0x34, 0x30, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,\r
+       0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x34, \r
+       0x30, 0x34, 0x20, 0x46, 0x69, 0x6c, 0x65, 0x20, 0x6e, 0x6f, \r
+       0x74, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0xd, 0xa, 0x53, \r
+       0x65, 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, \r
+       0x2f, 0x30, 0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, \r
+       0x3a, 0x2f, 0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, \r
+       0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, \r
+       0x75, 0x69, 0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, \r
+       0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, \r
+       0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, \r
+       0xd, 0xa, 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, \r
+       0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x62, 0x67, 0x63, 0x6f, \r
+       0x6c, 0x6f, 0x72, 0x3d, 0x22, 0x77, 0x68, 0x69, 0x74, 0x65, \r
+       0x22, 0x3e, 0x3c, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3e, \r
+       0x3c, 0x68, 0x31, 0x3e, 0x34, 0x30, 0x34, 0x20, 0x2d, 0x20, \r
+       0x66, 0x69, 0x6c, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x66, \r
+       0x6f, 0x75, 0x6e, 0x64, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0x3c, \r
+       0x2f, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3e, 0x3c, 0x2f, \r
+       0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f, 0x68, 0x74, 0x6d, \r
+       0x6c, 0x3e, };\r
+\r
+static const char data_control_html[] = {\r
+       /* /control.html */\r
+       0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,\r
+       0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, \r
+       0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72, \r
+       0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30, \r
+       0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, \r
+       0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63, \r
+       0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69, \r
+       0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65, \r
+       0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, \r
+       0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa, \r
+       0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xd, 0xa, \r
+       0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xd, 0xa, 0x3c, 0x74, \r
+       0x69, 0x74, 0x6c, 0x65, 0x3e, 0x41, 0x54, 0x39, 0x31, 0x53, \r
+       0x41, 0x4d, 0x37, 0x58, 0x20, 0x45, 0x6d, 0x62, 0x65, 0x64, \r
+       0x64, 0x65, 0x64, 0x20, 0x57, 0x45, 0x42, 0x20, 0x53, 0x65, \r
+       0x72, 0x76, 0x65, 0x72, 0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, \r
+       0x20, 0x75, 0x49, 0x50, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x46, \r
+       0x72, 0x65, 0x65, 0x52, 0x54, 0x4f, 0x53, 0x3c, 0x2f, 0x74, \r
+       0x69, 0x74, 0x6c, 0x65, 0x3e, 0xd, 0xa, 0x3c, 0x2f, 0x68, \r
+       0x65, 0x61, 0x64, 0x3e, 0xd, 0xa, 0x3c, 0x62, 0x6f, 0x64, \r
+       0x79, 0x20, 0x62, 0x67, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3d, \r
+       0x22, 0x23, 0x63, 0x63, 0x63, 0x63, 0x66, 0x66, 0x22, 0x3e, \r
+       0xd, 0xa, 0x3c, 0x66, 0x6f, 0x6e, 0x74, 0x20, 0x66, 0x61, \r
+       0x63, 0x65, 0x3d, 0x22, 0x61, 0x72, 0x69, 0x61, 0x6c, 0x22, \r
+       0x3e, 0xd, 0xa, 0x3c, 0x69, 0x6d, 0x67, 0x20, 0x73, 0x72, \r
+       0x63, 0x3d, 0x22, 0x2f, 0x69, 0x6d, 0x67, 0x2f, 0x6c, 0x6f, \r
+       0x67, 0x6f, 0x2e, 0x70, 0x6e, 0x67, 0x22, 0x20, 0x61, 0x6c, \r
+       0x69, 0x67, 0x6e, 0x3d, 0x22, 0x72, 0x69, 0x67, 0x68, 0x74, \r
+       0x22, 0x3e, 0xd, 0xa, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, \r
+       0x66, 0x3d, 0x22, 0x2f, 0x63, 0x67, 0x69, 0x2f, 0x72, 0x74, \r
+       0x6f, 0x73, 0x22, 0x20, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, \r
+       0x3d, 0x22, 0x6d, 0x61, 0x69, 0x6e, 0x22, 0x3e, 0x54, 0x61, \r
+       0x73, 0x6b, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x7c, 0xd, \r
+       0xa, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, \r
+       0x2f, 0x63, 0x67, 0x69, 0x2f, 0x74, 0x63, 0x70, 0x22, 0x20, \r
+       0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x3d, 0x22, 0x6d, 0x61, \r
+       0x69, 0x6e, 0x22, 0x3e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, \r
+       0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x20, \r
+       0x7c, 0xd, 0xa, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, \r
+       0x3d, 0x22, 0x2f, 0x63, 0x67, 0x69, 0x2f, 0x66, 0x69, 0x6c, \r
+       0x65, 0x73, 0x22, 0x20, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, \r
+       0x3d, 0x22, 0x6d, 0x61, 0x69, 0x6e, 0x22, 0x3e, 0x46, 0x69, \r
+       0x6c, 0x65, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x7c, 0xd, \r
+       0xa, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, \r
+       0x2f, 0x63, 0x67, 0x69, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x73, \r
+       0x22, 0x20, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x3d, 0x22, \r
+       0x6d, 0x61, 0x69, 0x6e, 0x22, 0x3e, 0x53, 0x74, 0x61, 0x74, \r
+       0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 0x3c, 0x2f, 0x61, 0x3e, \r
+       0x3c, 0x62, 0x72, 0x3e, 0xd, 0xa, 0x3c, 0x62, 0x72, 0x3e, \r
+       0xd, 0xa, 0x3c, 0x2f, 0x66, 0x6f, 0x6e, 0x74, 0x3e, 0xd, \r
+       0xa, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xd, 0xa, \r
+       0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xd, 0xa, 0xd, \r
+       0xa, 0xd, 0xa, 0xd, 0xa, 0xd, 0xa, 0xd, 0xa, };\r
+\r
+static const char data_files_footer_plain[] = {\r
+       /* /files_footer.plain */\r
+       0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x5f, 0x66, 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x2e, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0,\r
+       0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, \r
+       0x3c, 0x2f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, 0xd, 0xa, \r
+       0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xd, 0xa, 0x3c, \r
+       0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xd, 0xa, };\r
+\r
+static const char data_files_header_html[] = {\r
+       /* /files_header.html */\r
+       0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,\r
+       0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, \r
+       0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72, \r
+       0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30, \r
+       0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, \r
+       0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63, \r
+       0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69, \r
+       0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65, \r
+       0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, \r
+       0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa, \r
+       0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xd, 0xa, \r
+       0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x62, 0x67, 0x63, 0x6f, \r
+       0x6c, 0x6f, 0x72, 0x3d, 0x22, 0x23, 0x43, 0x43, 0x43, 0x43, \r
+       0x46, 0x46, 0x22, 0x3e, 0xd, 0xa, 0x3c, 0x63, 0x65, 0x6e, \r
+       0x74, 0x65, 0x72, 0x3e, 0xd, 0xa, 0x3c, 0x74, 0x61, 0x62, \r
+       0x6c, 0x65, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, 0x22, \r
+       0x36, 0x30, 0x30, 0x22, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, \r
+       0x72, 0x3d, 0x22, 0x30, 0x22, 0x3e, 0xd, 0xa, };\r
+\r
+static const char data_stats_footer_plain[] = {\r
+       /* /stats_footer.plain */\r
+       0x2f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x5f, 0x66, 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x2e, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0,\r
+       0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, \r
+       0x3c, 0x2f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, 0xd, 0xa, \r
+       0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xd, 0xa, 0x3c, \r
+       0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xd, 0xa, };\r
+\r
+static const char data_stats_header_html[] = {\r
+       /* /stats_header.html */\r
+       0x2f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,\r
+       0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, \r
+       0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72, \r
+       0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30, \r
+       0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, \r
+       0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63, \r
+       0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69, \r
+       0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65, \r
+       0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, \r
+       0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa, \r
+       0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xd, 0xa, \r
+       0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x62, 0x67, 0x63, 0x6f, \r
+       0x6c, 0x6f, 0x72, 0x3d, 0x22, 0x23, 0x63, 0x63, 0x63, 0x63, \r
+       0x66, 0x66, 0x22, 0x3e, 0xd, 0xa, 0x3c, 0x63, 0x65, 0x6e, \r
+       0x74, 0x65, 0x72, 0x3e, 0xd, 0xa, 0x3c, 0x74, 0x61, 0x62, \r
+       0x6c, 0x65, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, 0x22, \r
+       0x36, 0x30, 0x30, 0x22, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, \r
+       0x72, 0x3d, 0x22, 0x30, 0x22, 0x3e, 0xd, 0xa, 0x3c, 0x74, \r
+       0x72, 0x3e, 0x3c, 0x74, 0x64, 0x3e, 0xd, 0xa, 0x3c, 0x70, \r
+       0x72, 0x65, 0x3e, 0xd, 0xa, 0x49, 0x50, 0x20, 0x20, 0x20, \r
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x61, \r
+       0x63, 0x6b, 0x65, 0x74, 0x73, 0x20, 0x64, 0x72, 0x6f, 0x70, \r
+       0x70, 0x65, 0x64, 0xd, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, \r
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x61, \r
+       0x63, 0x6b, 0x65, 0x74, 0x73, 0x20, 0x72, 0x65, 0x63, 0x65, \r
+       0x69, 0x76, 0x65, 0x64, 0xd, 0xa, 0x20, 0x20, 0x20, 0x20, \r
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, \r
+       0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x20, 0x73, 0x65, 0x6e, \r
+       0x74, 0xd, 0xa, 0x49, 0x50, 0x20, 0x65, 0x72, 0x72, 0x6f, \r
+       0x72, 0x73, 0x20, 0x20, 0x20, 0x20, 0x49, 0x50, 0x20, 0x76, \r
+       0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x2f, 0x68, 0x65, 0x61, \r
+       0x64, 0x65, 0x72, 0x20, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, \r
+       0xd, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, \r
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x49, 0x50, 0x20, 0x6c, 0x65, \r
+       0x6e, 0x67, 0x74, 0x68, 0x2c, 0x20, 0x68, 0x69, 0x67, 0x68, \r
+       0x20, 0x62, 0x79, 0x74, 0x65, 0xd, 0xa, 0x20, 0x20, 0x20, \r
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, \r
+       0x49, 0x50, 0x20, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2c, \r
+       0x20, 0x6c, 0x6f, 0x77, 0x20, 0x62, 0x79, 0x74, 0x65, 0xd, \r
+       0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, \r
+       0x20, 0x20, 0x20, 0x20, 0x49, 0x50, 0x20, 0x66, 0x72, 0x61, \r
+       0x67, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0xd, 0xa, 0x20, 0x20, \r
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, \r
+       0x20, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x63, 0x68, \r
+       0x65, 0x63, 0x6b, 0x73, 0x75, 0x6d, 0xd, 0xa, 0x20, 0x20, \r
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, \r
+       0x20, 0x57, 0x72, 0x6f, 0x6e, 0x67, 0x20, 0x70, 0x72, 0x6f, \r
+       0x74, 0x6f, 0x63, 0x6f, 0x6c, 0xd, 0xa, 0x49, 0x43, 0x4d, \r
+       0x50, 0x9, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 0x63, \r
+       0x6b, 0x65, 0x74, 0x73, 0x20, 0x64, 0x72, 0x6f, 0x70, 0x70, \r
+       0x65, 0x64, 0xd, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, \r
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 0x63, \r
+       0x6b, 0x65, 0x74, 0x73, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, \r
+       0x76, 0x65, 0x64, 0xd, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, \r
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x61, \r
+       0x63, 0x6b, 0x65, 0x74, 0x73, 0x20, 0x73, 0x65, 0x6e, 0x74, \r
+       0xd, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, \r
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x54, 0x79, 0x70, 0x65, 0x20, \r
+       0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0xd, 0xa, 0x54, 0x43, \r
+       0x50, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, \r
+       0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x20, 0x64, \r
+       0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0xd, 0xa, 0x20, 0x20, \r
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, \r
+       0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x20, 0x72, \r
+       0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0xd, 0xa, 0x20, \r
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, \r
+       0x20, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x20, \r
+       0x73, 0x65, 0x6e, 0x74, 0xd, 0xa, 0x20, 0x20, 0x20, 0x20, \r
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, \r
+       0x68, 0x65, 0x63, 0x6b, 0x73, 0x75, 0x6d, 0x20, 0x65, 0x72, \r
+       0x72, 0x6f, 0x72, 0x73, 0xd, 0xa, 0x20, 0x20, 0x20, 0x20, \r
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x44, \r
+       0x61, 0x74, 0x61, 0x20, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, \r
+       0x73, 0x20, 0x77, 0x69, 0x74, 0x68, 0x6f, 0x75, 0x74, 0x20, \r
+       0x41, 0x43, 0x4b, 0x73, 0xd, 0xa, 0x20, 0x20, 0x20, 0x20, \r
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x52, \r
+       0x65, 0x73, 0x65, 0x74, 0x73, 0xd, 0xa, 0x20, 0x20, 0x20, \r
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, \r
+       0x52, 0x65, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6d, 0x69, 0x73, \r
+       0x73, 0x69, 0x6f, 0x6e, 0x73, 0xd, 0xa, 0x9, 0x20, 0x20, \r
+       0x20, 0x20, 0x20, 0x4e, 0x6f, 0x20, 0x63, 0x6f, 0x6e, 0x6e, \r
+       0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x76, 0x61, \r
+       0x6c, 0x69, 0x61, 0x62, 0x6c, 0x65, 0xd, 0xa, 0x9, 0x20, \r
+       0x20, 0x20, 0x20, 0x20, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, \r
+       0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x74, 0x74, 0x65, 0x6d, \r
+       0x70, 0x74, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x63, 0x6c, 0x6f, \r
+       0x73, 0x65, 0x64, 0x20, 0x70, 0x6f, 0x72, 0x74, 0x73, 0xd, \r
+       0xa, 0x3c, 0x2f, 0x70, 0x72, 0x65, 0x3e, 0x9, 0x20, 0x20, \r
+       0x20, 0x20, 0x20, 0xd, 0xa, 0x3c, 0x2f, 0x74, 0x64, 0x3e, \r
+       0x3c, 0x74, 0x64, 0x3e, 0x3c, 0x70, 0x72, 0x65, 0x3e, };\r
+\r
+static const char data_tcp_footer_plain[] = {\r
+       /* /tcp_footer.plain */\r
+       0x2f, 0x74, 0x63, 0x70, 0x5f, 0x66, 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x2e, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0,\r
+       0xd, 0xa, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x2f, 0x74, \r
+       0x72, 0x3e, 0x3c, 0x2f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, \r
+       0xd, 0xa, 0x3c, 0x2f, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, \r
+       0x3e, 0xd, 0xa, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, \r
+       0xd, 0xa, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, };\r
+\r
+static const char data_tcp_header_html[] = {\r
+       /* /tcp_header.html */\r
+       0x2f, 0x74, 0x63, 0x70, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,\r
+       0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, \r
+       0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72, \r
+       0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30, \r
+       0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, \r
+       0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63, \r
+       0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69, \r
+       0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65, \r
+       0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, \r
+       0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa, \r
+       0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xd, 0xa, \r
+       0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x62, 0x67, 0x63, 0x6f, \r
+       0x6c, 0x6f, 0x72, 0x3d, 0x22, 0x23, 0x63, 0x63, 0x63, 0x63, \r
+       0x66, 0x66, 0x22, 0x3e, 0xd, 0xa, 0x3c, 0x63, 0x65, 0x6e, \r
+       0x74, 0x65, 0x72, 0x3e, 0xd, 0xa, 0x3c, 0x74, 0x61, 0x62, \r
+       0x6c, 0x65, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, 0x22, \r
+       0x36, 0x30, 0x30, 0x22, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, \r
+       0x72, 0x3d, 0x22, 0x30, 0x22, 0x3e, 0xd, 0xa, 0x3c, 0x74, \r
+       0x72, 0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x52, 0x65, 0x6d, 0x6f, \r
+       0x74, 0x65, 0x3c, 0x2f, 0x74, 0x68, 0x3e, 0x3c, 0x74, 0x68, \r
+       0x3e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x3c, 0x2f, 0x74, 0x68, \r
+       0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x52, 0x65, 0x74, 0x72, 0x61, \r
+       0x6e, 0x73, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, \r
+       0x3c, 0x2f, 0x74, 0x68, 0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x54, \r
+       0x69, 0x6d, 0x65, 0x72, 0x3c, 0x2f, 0x74, 0x68, 0x3e, 0x3c, \r
+       0x74, 0x68, 0x3e, 0x46, 0x6c, 0x61, 0x67, 0x73, 0x3c, 0x2f, \r
+       0x74, 0x68, 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0xd, 0xa, \r
+       0xd, 0xa, };\r
+\r
+static const char data_img_logo_png[] = {\r
+       /* /img/logo.png */\r
+       0x2f, 0x69, 0x6d, 0x67, 0x2f, 0x6c, 0x6f, 0x67, 0x6f, 0x2e, 0x70, 0x6e, 0x67, 0,\r
+       0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, \r
+       0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72, \r
+       0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30, \r
+       0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, \r
+       0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63, \r
+       0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69, \r
+       0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65, \r
+       0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x69, \r
+       0x6d, 0x61, 0x67, 0x65, 0x2f, 0x70, 0x6e, 0x67, 0xd, 0xa, \r
+       0xd, 0xa, 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, \r
+       00, 00, 00, 0xd, 0x49, 0x48, 0x44, 0x52, 00, 00, \r
+       00, 0xec, 00, 00, 00, 0x5c, 0x8, 0x3, 00, 00, \r
+       00, 0x5a, 0xc7, 0xa9, 0x53, 00, 00, 0x3, 00, 0x50, \r
+       0x4c, 0x54, 0x45, 00, 00, 00, 0x3, 0x3, 0x3, 0x4, \r
+       0x4, 0x4, 0x6, 0x6, 0x6, 0x8, 0x8, 0x8, 0xa, 0xa, \r
+       0xa, 0xc, 0xc, 0xc, 0xe, 0xe, 0xe, 0x10, 0x10, 0x10, \r
+       0x12, 0x12, 0x12, 0x14, 0x14, 0x14, 0x16, 0x16, 0x16, 0x18, \r
+       0x18, 0x18, 0x1a, 0x1a, 0x1a, 0x1c, 0x1c, 0x1c, 0x21, 0x21, \r
+       0x21, 0x25, 0x25, 0x25, 0x28, 0x28, 0x28, 0x2c, 0x2c, 0x2c, \r
+       0x2e, 0x2e, 0x2e, 0x30, 0x30, 0x30, 0x32, 0x32, 0x32, 0x34, \r
+       0x34, 0x34, 0x36, 0x36, 0x36, 0x38, 0x38, 0x38, 0x3a, 0x3a, \r
+       0x3a, 0x3e, 0x3e, 0x3e, 0x40, 0x40, 0x40, 0x43, 0x43, 0x43, \r
+       0x45, 0x45, 0x45, 0x46, 0x46, 0x46, 0x4a, 0x4a, 0x4a, 0x4d, \r
+       0x4d, 0x4d, 0x50, 0x50, 0x50, 0x52, 0x52, 0x52, 0x55, 0x55, \r
+       0x55, 0x58, 0x58, 0x58, 0x5c, 0x5c, 0x5c, 0x60, 0x60, 0x60, \r
+       0x62, 0x62, 0x62, 0x66, 0x66, 0x66, 0x69, 0x69, 0x69, 0x6b, \r
+       0x6b, 0x6b, 0x6e, 0x6e, 0x6e, 0x71, 0x71, 0x71, 0x73, 0x73, \r
+       0x73, 0x74, 0x74, 0x74, 0x77, 0x77, 0x77, 0x78, 0x78, 0x78, \r
+       0x7a, 0x7a, 0x7a, 0x7c, 0x7c, 0x7c, 0x7e, 0x7e, 0x7e, 00, \r
+       0xd9, 00, 0x4, 0xd8, 0x4, 0x6, 0xda, 0x6, 0x8, 0xda, \r
+       0x8, 0xc, 0xda, 0xc, 0x15, 0xdc, 0x15, 0x18, 0xdc, 0x18, \r
+       0x1a, 0xdc, 0x1a, 0x1d, 0xdd, 0x1d, 0x20, 0xde, 0x20, 0x22, \r
+       0xde, 0x22, 0x24, 0xde, 0x24, 0x28, 0xde, 0x28, 0x2d, 0xe0, \r
+       0x2d, 0x2f, 0xe0, 0x2f, 0x3b, 0xe2, 0x3b, 0x3d, 0xe2, 0x3d, \r
+       0x41, 0xe2, 0x41, 0x45, 0xe2, 0x45, 0x49, 0xe3, 0x49, 0x49, \r
+       0xe4, 0x49, 0x4b, 0xe4, 0x4b, 0x4d, 0xe5, 0x4d, 0x51, 0xe5, \r
+       0x51, 0x56, 0xe6, 0x56, 0x58, 0xe6, 0x58, 0x60, 0xe6, 0x60, \r
+       0x64, 0xe8, 0x64, 0x69, 0xe9, 0x69, 0x6a, 0xe9, 0x6a, 0x6c, \r
+       0xe9, 0x6c, 0x6e, 0xe9, 0x6e, 0x6f, 0xea, 0x6f, 0x66, 0xff, \r
+       0x66, 0x68, 0xff, 0x68, 0x6a, 0xff, 0x6a, 0x6c, 0xff, 0x6c, \r
+       0x6e, 0xff, 0x6e, 0x73, 0xea, 0x73, 0x78, 0xeb, 0x78, 0x7a, \r
+       0xea, 0x7a, 0x70, 0xff, 0x70, 0x72, 0xff, 0x72, 0x74, 0xff, \r
+       0x74, 0x76, 0xff, 0x76, 0x78, 0xff, 0x78, 0x7a, 0xff, 0x7a, \r
+       0x7c, 0xff, 0x7c, 0x7e, 0xff, 0x7e, 0x80, 0x80, 0x80, 0x83, \r
+       0x83, 0x83, 0x86, 0x86, 0x86, 0x89, 0x89, 0x89, 0x8b, 0x8b, \r
+       0x8b, 0x8e, 0x8e, 0x8e, 0x90, 0x90, 0x90, 0x93, 0x93, 0x93, \r
+       0x96, 0x96, 0x96, 0x99, 0x99, 0x99, 0x9a, 0x9a, 0x9a, 0x9e, \r
+       0x9e, 0x9e, 0xa0, 0xa0, 0xa0, 0xa5, 0xa5, 0xa5, 0xa6, 0xa6, \r
+       0xa6, 0xa9, 0xa9, 0xa9, 0xab, 0xab, 0xab, 0xac, 0xac, 0xac, \r
+       0xae, 0xae, 0xae, 0xb1, 0xb1, 0xb1, 0xb5, 0xb5, 0xb5, 0xb8, \r
+       0xb8, 0xb8, 0xba, 0xba, 0xba, 0xbc, 0xbc, 0xbc, 0xbe, 0xbe, \r
+       0xbe, 0x81, 0xeb, 0x81, 0x80, 0xec, 0x80, 0x85, 0xec, 0x85, \r
+       0x88, 0xed, 0x88, 0x88, 0xee, 0x88, 0x8d, 0xee, 0x8d, 0x80, \r
+       0xff, 0x80, 0x82, 0xff, 0x82, 0x84, 0xff, 0x84, 0x86, 0xff, \r
+       0x86, 0x88, 0xff, 0x88, 0x8a, 0xff, 0x8a, 0x8c, 0xff, 0x8c, \r
+       0x8e, 0xff, 0x8e, 0x97, 0xf0, 0x97, 0x90, 0xff, 0x90, 0x92, \r
+       0xff, 0x92, 0x94, 0xff, 0x94, 0x96, 0xff, 0x96, 0x9c, 0xf0, \r
+       0x9c, 0x98, 0xff, 0x98, 0x9a, 0xff, 0x9a, 0x9c, 0xff, 0x9c, \r
+       0x9e, 0xff, 0x9e, 0xa2, 0xf1, 0xa2, 0xa2, 0xf2, 0xa2, 0xa4, \r
+       0xf1, 0xa4, 0xa6, 0xf1, 0xa6, 0xa6, 0xf2, 0xa6, 0xa0, 0xff, \r
+       0xa0, 0xa2, 0xff, 0xa2, 0xa4, 0xff, 0xa4, 0xa6, 0xff, 0xa6, \r
+       0xa8, 0xf2, 0xa8, 0xac, 0xf3, 0xac, 0xae, 0xf3, 0xae, 0xa8, \r
+       0xff, 0xa8, 0xaa, 0xff, 0xaa, 0xac, 0xff, 0xac, 0xae, 0xff, \r
+       0xae, 0xb3, 0xf4, 0xb3, 0xb4, 0xf4, 0xb4, 0xb6, 0xf4, 0xb6, \r
+       0xb0, 0xff, 0xb0, 0xb2, 0xff, 0xb2, 0xb4, 0xff, 0xb4, 0xb6, \r
+       0xff, 0xb6, 0xbb, 0xf5, 0xbb, 0xb8, 0xff, 0xb8, 0xba, 0xff, \r
+       0xba, 0xbc, 0xff, 0xbc, 0xbe, 0xff, 0xbe, 0xc0, 0xc0, 0xc0, \r
+       0xc3, 0xc3, 0xc3, 0xc4, 0xc4, 0xc4, 0xc6, 0xc6, 0xc6, 0xc8, \r
+       0xc8, 0xc8, 0xca, 0xca, 0xca, 0xcc, 0xcc, 0xcc, 0xcf, 0xcf, \r
+       0xcf, 0xd0, 0xd0, 0xd0, 0xd2, 0xd2, 0xd2, 0xd4, 0xd4, 0xd4, \r
+       0xd6, 0xd6, 0xd6, 0xd8, 0xd8, 0xd8, 0xda, 0xda, 0xda, 0xdc, \r
+       0xdc, 0xdc, 0xdf, 0xdf, 0xdf, 0xc0, 0xff, 0xc0, 0xc2, 0xff, \r
+       0xc2, 0xc4, 0xff, 0xc4, 0xc6, 0xff, 0xc6, 0xc8, 0xff, 0xc8, \r
+       0xca, 0xff, 0xca, 0xcc, 0xf8, 0xcc, 0xce, 0xf8, 0xce, 0xcc, \r
+       0xff, 0xcc, 0xce, 0xff, 0xce, 0xd0, 0xf8, 0xd0, 0xd0, 0xff, \r
+       0xd0, 0xd2, 0xff, 0xd2, 0xd6, 0xf9, 0xd6, 0xd4, 0xff, 0xd4, \r
+       0xd6, 0xff, 0xd6, 0xd9, 0xf9, 0xd9, 0xd8, 0xff, 0xd8, 0xda, \r
+       0xff, 0xda, 0xdc, 0xfa, 0xdc, 0xdc, 0xff, 0xdc, 0xde, 0xff, \r
+       0xde, 0xe0, 0xe0, 0xe0, 0xe2, 0xe2, 0xe2, 0xe4, 0xe4, 0xe4, \r
+       0xe6, 0xe6, 0xe6, 0xe8, 0xe8, 0xe8, 0xea, 0xea, 0xea, 0xec, \r
+       0xec, 0xec, 0xee, 0xee, 0xee, 0xe1, 0xfa, 0xe1, 0xe3, 0xfb, \r
+       0xe3, 0xe0, 0xff, 0xe0, 0xe2, 0xff, 0xe2, 0xe5, 0xfb, 0xe5, \r
+       0xe4, 0xff, 0xe4, 0xe6, 0xff, 0xe6, 0xe8, 0xfc, 0xe8, 0xe8, \r
+       0xff, 0xe8, 0xea, 0xfc, 0xea, 0xea, 0xff, 0xea, 0xec, 0xff, \r
+       0xec, 0xee, 0xfd, 0xee, 0xee, 0xff, 0xee, 0xf0, 0xf0, 0xf0, \r
+       0xf2, 0xf2, 0xf2, 0xf4, 0xf4, 0xf4, 0xf6, 0xf6, 0xf6, 0xf1, \r
+       0xfd, 0xf1, 0xf0, 0xff, 0xf0, 0xf3, 0xfd, 0xf3, 0xf2, 0xff, \r
+       0xf2, 0xf5, 0xfd, 0xf5, 0xf4, 0xfe, 0xf4, 0xf6, 0xfe, 0xf6, \r
+       0xf8, 0xf8, 0xf8, 0xfa, 0xfa, 0xfa, 0xf8, 0xfe, 0xf8, 0xfa, \r
+       0xfe, 0xfa, 0xff, 00, 00, 0xfc, 0xfe, 0xfc, 0xfe, 0xfe, \r
+       0xfe, 0xd7, 0xd6, 0xbe, 0x1c, 00, 00, 00, 0xfe, 0x74, \r
+       0x52, 0x4e, 0x53, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \r
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \r
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \r
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \r
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \r
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \r
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \r
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \r
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \r
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \r
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \r
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \r
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \r
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \r
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \r
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \r
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \r
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \r
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \r
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \r
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \r
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \r
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \r
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \r
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \r
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 00, 0xd8, 0xd9, 0xc, \r
+       0x71, 00, 00, 0xc, 0xc6, 0x49, 0x44, 0x41, 0x54, 0x78, \r
+       0xda, 0xed, 0x9c, 0xf, 0x50, 0x14, 0xd7, 0x19, 0xc0, 0xdf, \r
+       0xc2, 0x21, 0x2c, 0x77, 0x27, 0xa0, 0x1, 0x3d, 0x15, 0x10, \r
+       0x4, 0x39, 0x23, 0xe3, 0x14, 0x1, 0xeb, 0x1f, 0xc0, 0x51, \r
+       0x87, 0x88, 0x81, 0x91, 0x92, 0xa8, 0x41, 0x32, 0x49, 0xac, \r
+       0xb6, 0x8e, 0xa5, 0xa6, 0x8e, 0x1d, 0x3b, 0x6d, 0x9c, 0xce, \r
+       0x64, 0x3a, 0xda, 0xd8, 0x4e, 0xda, 0x4e, 0x67, 0x9c, 0x74, \r
+       0x92, 0x36, 0xa, 0xb6, 0x62, 0xac, 0xa6, 0x15, 0xdb, 0x10, \r
+       0xe8, 0x58, 0xb4, 0xa, 0x6, 0x14, 0x73, 0x54, 0x73, 0x53, \r
+       0x8e, 0x62, 0x4c, 0xf8, 0x93, 0x9c, 0x60, 0x10, 0xc9, 0x82, \r
+       0x87, 0x1c, 0xb0, 0x7d, 0xbb, 0xcb, 0xdd, 0xbd, 0xb7, 0xfb, \r
+       0xde, 0xde, 0xae, 0x98, 0x94, 0x23, 0x99, 0xdf, 0xcc, 0xed, \r
+       0xbd, 0xdd, 0xf7, 0xde, 0xed, 0xb7, 0xef, 0xbd, 0xef, 0x7d, \r
+       0xdf, 0xf7, 0xde, 0x1e, 0x33, 0xa, 00, 0xb8, 0x76, 0xf0, \r
+       0x36, 0xfc, 0x9c, 0xd2, 0xa4, 0x1c, 0x83, 0x1f, 0x50, 0xd8, \r
+       0x53, 0x7f, 0xfc, 0x6c, 0x82, 0x35, 0x5, 0x2, 0xec, 0xd6, \r
+       0x9d, 0x50, 0xd8, 0x3f, 0xbd, 0x36, 0xe1, 0x8a, 0x2, 0x83, \r
+       0xef, 0x3f, 0xc7, 0x8c, 0xe6, 0x72, 0x13, 0xae, 0x26, 0x30, \r
+       0x30, 0x9f, 0x33, 0xbc, 0x20, 0xc9, 0x6a, 0x88, 0xc, 0x9e, \r
+       0x50, 0x4d, 0x93, 0x92, 0xa0, 0x69, 0xd2, 0x71, 0xb0, 0x4f, \r
+       0xd0, 0x4c, 0xdc, 0x29, 0x26, 0x53, 0x48, 0xb1, 0x31, 0xd9, \r
+       0x39, 0x33, 0x1e, 0xb2, 0xc6, 0x49, 0x4c, 0x58, 0x8c, 0x74, \r
+       0xfc, 0xe0, 0x17, 0x1f, 0xbb, 0xe1, 0x61, 0xba, 0x24, 0x6c, \r
+       0xfc, 0x6b, 0xe3, 0xa7, 0xa7, 0x28, 0x1d, 0x3f, 0xf8, 0x54, \r
+       0x38, 0x4, 0x9, 0x1f, 0x21, 0xeb, 0xa6, 0xb6, 0xac, 0x20, \r
+       0x6e, 0xad, 0x41, 0x38, 0x88, 0xc2, 0x1a, 0xd8, 0x9, 0x54, \r
+       0x14, 0x10, 0x44, 0x84, 0x8, 0x9f, 0xa2, 0xb0, 0x5f, 0x15, \r
+       0xbe, 0x16, 0x76, 0xaa, 0x22, 0xe, 0x5c, 0x1a, 0xfd, 0x63, \r
+       0x7d, 0x1f, 0xa7, 0x47, 0x68, 0xab, 0xe8, 0x91, 0xe2, 0xe2, \r
+       0x84, 0x89, 0x11, 0x12, 0x6c, 0xd6, 0xaa, 0x4e, 0xc4, 0x22, \r
+       0xfd, 0xc2, 0xcd, 0xd2, 0xcb, 0xd0, 0x85, 0xed, 0x7b, 0xef, \r
+       0x82, 0xcb, 0xdd, 0x78, 0xaf, 0x7c, 0xad, 0xef, 0x94, 0xb3, \r
+       0x8b, 0x92, 0xd7, 0xc, 0x40, 0xbc, 0xfc, 0x17, 0xa8, 0x99, \r
+       0x51, 0x82, 0xe7, 0x29, 0xe6, 0x81, 0x9e, 0xae, 0xd1, 0xa1, \r
+       0xee, 0xdb, 0x3, 00, 0xb4, 0xa6, 00, 0x60, 0x9a, 0x61, \r
+       0xb2, 0x4, 0x5b, 0x2c, 0xea, 0x95, 0xb8, 0xda, 0xb9, 0xa1, \r
+       0xbe, 0xde, 0xde, 0x11, 0xa9, 0x88, 0x61, 0xa6, 0x79, 0x56, \r
+       0x18, 0x30, 0x2b, 0xee, 0x7, 0x42, 0x13, 0xd6, 0xfd, 0xaf, \r
+       0xd3, 0x67, 0x7a, 0xe1, 0x91, 0x75, 0xf7, 0xd7, 0xd7, 00, \r
+       0xb0, 0x1b, 0xd6, 0x2, 0x5c, 0x17, 0x2a, 0x29, 0xb9, 0xcd, \r
+       0xc9, 0x20, 0xce, 0x14, 0x15, 0x6d, 0x45, 0xcf, 0x5d, 0xae, \r
+       0x1a, 0xa4, 0xe4, 0x46, 0x30, 0x6e, 0xc7, 0x85, 0x75, 0xd9, \r
+       0x9d, 0x1d, 0xef, 0x7b, 0xca, 0xd9, 0xc6, 0xf3, 0x2c, 0x89, \r
+       0x9d, 0x95, 0x42, 0x9f, 0x1b, 0x6d, 0x5d, 0x3, 0xb5, 0x5e, \r
+       0x8b, 0x77, 0xbc, 0x8, 0x60, 0xd2, 0xe2, 0x62, 0x93, 0x14, \r
+       0xcf, 0x88, 0x26, 0x6c, 0xed, 0x4e, 0x6f, 0xc3, 0x54, 0xbd, \r
+       0xe, 0x40, 0xe8, 0x21, 0x51, 0x77, 0xd3, 0xe0, 0x6c, 0xf0, \r
+       0x67, 0xe0, 0xf, 0x58, 0x97, 0xaa, 0xe5, 0xf2, 0x8b, 0xeb, \r
+       0xda, 0xcd, 0x4b, 0xca, 0x27, 0x34, 0xd8, 0xd0, 0x60, 0x5c, \r
+       0xb2, 0x60, 0x39, 0x51, 0x5c, 0x97, 0xbd, 0xad, 0xc3, 0x23, \r
+       0x20, 0xa, 0x6f, 0xb3, 0x19, 0x4b, 0xb5, 0xa, 0x7b, 0xd1, \r
+       0x27, 0x6b, 0xc4, 0x74, 0xd6, 0x5, 0xde, 0x2d, 0x4d, 0x24, \r
+       0x67, 0x44, 0x80, 0x3f, 0xb0, 0xf4, 0x7a, 0xfe, 0x4, 0xcc, \r
+       0x13, 0xdb, 0x75, 0x82, 0xa8, 0x22, 0x83, 0xd, 0x37, 0x3e, \r
+       0xcc, 0xc8, 0x50, 0x76, 0x4c, 0x47, 0x43, 0x3d, 0xd5, 0x8d, \r
+       0x9, 0x9a, 0xa7, 0x38, 0x45, 0x16, 0xd6, 0xfd, 0x77, 0x64, \r
+       0xc0, 0xad, 0x3f, 0xfd, 0x11, 0xe8, 0x6e, 0xf7, 0x2f, 0x2c, \r
+       0xc4, 0xc6, 0xf4, 0x3e, 0xeb, 0x67, 0x80, 0xd1, 0xa9, 0x2b, \r
+       0x1f, 0xe0, 0xa9, 0x17, 0xa1, 0xb8, 0x37, 0x15, 0xf, 0xb2, \r
+       0xa9, 0xb6, 0x99, 0x5e, 0x82, 00, 0x59, 0xd8, 0xf6, 0xa, \r
+       0xf8, 0x31, 0xa7, 0x78, 0xec, 0xd, 0x17, 0x3c, 0xc6, 0x42, \r
+       0xdf, 0xa1, 0x1f, 0x8e, 0x7e, 0x2d, 0xf0, 0x57, 0x5b, 0xe, \r
+       0x3e, 0x9c, 0xb4, 0xae, 0x2a, 0x3f, 0x63, 0x7c, 0xb0, 0xa6, \r
+       0xf7, 0x79, 0x5c, 0x5a, 0xdb, 0xef, 0xd4, 0x4a, 0x24, 0x47, \r
+       0x2a, 0x4e, 0x91, 0xe7, 0xd9, 0x4f, 0xee, 00, 0x90, 0x50, \r
+       0x76, 0x68, 0xbd, 0xf8, 0x28, 0xe2, 0xb3, 0x1, 0x18, 0xa3, \r
+       0x55, 0xa9, 0x80, 0xfb, 0xa9, 0xe6, 0xac, 0x28, 0xae, 0x33, \r
+       0xa7, 0xfd, 0xe9, 0x33, 0xfe, 0xea, 0x4b, 0x3d, 0x68, 0xda, \r
+       0x79, 0x58, 0xbd, 0x84, 0xb2, 0xd7, 0x93, 0x85, 0x1d, 0x83, \r
+       0xc2, 0x45, 0xe4, 0x8e, 0xeb, 0xa4, 0xae, 0xf7, 0x28, 0xb5, \r
+       0x91, 0xe1, 0xca, 0x74, 0x65, 0x97, 0x70, 0x9d, 0x39, 0xab, \r
+       0xa1, 0x43, 0x72, 0x2f, 0x9, 0x3d, 0x6d, 0x9c, 0x9e, 0xfd, \r
+       0x1a, 0xb4, 0x3d, 0xe, 0x59, 0x58, 0xe1, 0x87, 0x19, 0x4f, \r
+       0x62, 0x78, 0x58, 0x4b, 0x45, 0x3e, 0x2e, 0xe9, 0xcb, 0x2e, \r
+       0x62, 0xaf, 0x54, 0xca, 0xea, 0xbd, 0x1, 0x1f, 0x1c, 0x9c, \r
+       0x18, 0x3c, 0x10, 0x95, 0x19, 0x52, 0x86, 0x30, 0x40, 0xc9, \r
+       0x63, 0x56, 0x28, 0xe3, 0x16, 0xcd, 0x11, 0x48, 0x19, 0xc, \r
+       0x3d, 0x1a, 0x94, 0x71, 0xc, 0x63, 0x50, 0x32, 0x30, 0x8c, \r
+       0x80, 0xb6, 0xb1, 0xfb, 0xb2, 0xfb, 0xbc, 0xdf, 0x24, 0xfa, \r
+       0xc8, 0x7a, 0x70, 0xfe, 0x4a, 0x76, 0xc2, 0x98, 0x62, 00, \r
+       0x33, 0x7b, 0xc1, 0x48, 0xab, 0xac, 0xf2, 0xc6, 0x3a, 0x38, \r
+       0xa6, 0x44, 0x5c, 0xa7, 0x95, 0x25, 0x80, 0x50, 0x6, 0xc0, \r
+       0x7b, 0xa2, 0x68, 0x3a, 0xb2, 0xb0, 0x42, 0x7b, 0x3b, 0xf, \r
+       0xee, 0x17, 0xbe, 0xba, 0xcf, 0x9f, 0x85, 0xd6, 0xcc, 0x9c, \r
+       0xb9, 0x8a, 0x3c, 0xb9, 0x6b, 00, 0xb0, 0x38, 0x41, 0xbf, \r
+       0xfd, 0xf6, 0x50, 0x13, 0x56, 0x37, 0x5f, 0x2f, 0x5, 0x4, \r
+       0xd2, 0x85, 0xe8, 0x80, 0xc4, 0x28, 0x9a, 0x83, 0x59, 0xee, \r
+       0xfb, 0x1e, 0x69, 0x14, 0xf, 0x7f, 0xc1, 0x6f, 0xce, 0xb8, \r
+       0x78, 0x61, 0xae, 0x38, 0xe2, 0x5c, 0xf6, 0x2b, 0x5e, 0x13, \r
+       0x43, 0xaa, 0xbb, 0xdc, 0x63, 0x5e, 0xd8, 0xb1, 0x22, 0x4c, \r
+       0xe6, 0x42, 0xdf, 0x44, 0xec, 0x6a, 0xb7, 0x77, 0x3e, 0x68, \r
+       0x26, 0x84, 0x99, 0xc8, 0xc2, 0xce, 0x85, 0x4f, 0xa8, 0xf7, \r
+       0xe8, 0x79, 0xde, 0xd, 0xdc, 0x3f, 0x1a, 0x6e, 0x87, 0x27, \r
+       0x36, 0xce, 0x56, 0xe4, 0x31, 0x9, 0x5a, 0xd7, 0x2, 0x2c, \r
+       0x56, 0xe0, 0x9c, 0x8f, 0x2b, 0xd2, 0x7, 0xe2, 0x67, 0x26, \r
+       0xd2, 0xbe, 0x8e, 0x26, 0xe4, 0x72, 0xda, 0x5e, 0x79, 0x55, \r
+       0x8e, 0x3a, 0x2c, 0x69, 0xde, 0x90, 0x33, 0x7e, 0xe3, 0x6c, \r
+       0x66, 0x66, 0x5d, 0x39, 0x36, 0x93, 0xe, 0xfc, 0xb3, 0x44, \r
+       0xfa, 0x52, 0x8f, 0x9e, 0x65, 0xf2, 0xd0, 0x69, 0x89, 0xb5, \r
+       0xc2, 0x7b, 0x4a, 0x8a, 0xc7, 0xea, 0x14, 0x21, 0xb, 0x1b, \r
+       0x5d, 0x72, 0x18, 0x80, 0xbe, 0x3e, 0xf8, 0x6d, 0xa4, 0x55, \r
+       0x48, 0x9b, 0x9e, 0x50, 0x73, 0x7, 0x2c, 0x9b, 0x66, 0x1d, \r
+       0xd5, 0xad, 0x2c, 0x50, 0xaa, 0xb1, 0x56, 0x32, 0x6f, 0xf3, \r
+       0x74, 0x55, 0x81, 0xec, 0xb0, 0xd7, 0x51, 0x69, 0xf9, 0x8e, \r
+       0x1e, 0x49, 0xac, 0x1b, 0x68, 0x91, 0xb4, 0x3c, 0xf9, 0x14, \r
+       0x6c, 0xd9, 0x24, 0x3b, 0x21, 0x40, 0x56, 0x50, 0x11, 0xdf, \r
+       0x9a, 0x83, 0xa5, 0x13, 0x1e, 0x27, 0x66, 0xf3, 0x92, 0xbd, \r
+       0x18, 0x4d, 0xb5, 0xa9, 0x67, 0x56, 0xe0, 0xc0, 0x6e, 0xdc, \r
+       0xb8, 0x1, 0x95, 0x15, 0x80, 0xcc, 0x5d, 0x98, 0xa6, 0x6a, \r
+       0x25, 0xe9, 0x3f, 0x83, 0xb6, 0xb9, 0x9d, 0xe2, 0xcf, 0x66, \r
+       0x6d, 0x35, 0x21, 0xa9, 0x84, 0xdf, 0xfa, 0xb3, 0x9f, 0xe6, \r
+       0x13, 0x54, 0xa7, 0x66, 0x1a, 0xee, 0xa3, 0xa9, 0x94, 0x1c, \r
+       0xd9, 0xe5, 0xcc, 0x3c, 0x34, 0x35, 0xd8, 0x29, 0x1d, 0xb1, \r
+       0x32, 0x1a, 0xa1, 0x8, 0x1b, 0xb2, 0x7f, 0x67, 0xb4, 0x37, \r
+       0xcb, 0x82, 0x3f, 0x40, 0x5d, 0xa4, 0x4e, 0x2a, 0x9a, 0x48, \r
+       0xf6, 0x97, 0x5b, 0x46, 0x37, 0xda, 0x8b, 0x99, 0x55, 0xa, \r
+       0xeb, 0x3a, 0x1f, 0x7b, 0x92, 0x76, 0x92, 0xe1, 0xaf, 0xd, \r
+       0x5a, 0xa4, 0x22, 0xea, 0xd0, 0xa9, 0x5d, 0xd0, 0x4b, 0x85, \r
+       0xcc, 0xdc, 0xf7, 0xf, 0xc4, 0xa5, 0xa5, 0x60, 0x47, 0xbe, \r
+       0x33, 0x68, 0xa7, 0xd0, 0x80, 0x13, 0xeb, 0xf6, 0x26, 0xbc, \r
+       0x13, 0xb, 0xc4, 0x20, 0xea, 0x1b, 0x80, 0x1, 0x87, 0xb2, \r
+       0x8a, 0xa6, 0xb7, 0x95, 0xe7, 0x8, 0x50, 0x9d, 0xf7, 0x90, \r
+       0xd5, 0x2b, 0x7f, 0x2e, 0x68, 0x28, 0x66, 0x86, 0x96, 0x50, \r
+       0x45, 0x27, 0xda, 0x38, 0x2b, 0x35, 0x14, 0x40, 0xb8, 0x8c, \r
+       0xd9, 0xa2, 0x69, 0x84, 0x1c, 0xc5, 0xd, 0x48, 0x82, 0x97, \r
+       0x94, 0x3d, 0x6, 0x7f, 0x7a, 0xb8, 0x48, 0x43, 0x48, 0x43, \r
+       0x25, 0x2c, 0x13, 0x12, 0x15, 0xe5, 0xbf, 0xbc, 0x84, 0x13, \r
+       0x6d, 0xd9, 0x70, 0x9d, 0x4e, 0x6d, 0x27, 0xaa, 0xc9, 0x99, \r
+       0x2d, 0x84, 0x1c, 0x91, 0xc, 0xfa, 0x2c, 0xef, 0xb9, 0x4, \r
+       0xb9, 0x32, 0xaf, 0xa2, 0x39, 0xf8, 0xca, 0x73, 0xf9, 0xab, \r
+       0x22, 0xfd, 0xc9, 0x2b, 0x76, 0xe3, 0x11, 0xc4, 0xe4, 0xc4, \r
+       0xe9, 0x17, 0x1a, 0xd7, 0x2f, 0xce, 0xa, 0x74, 0x76, 0x48, \r
+       0xd7, 0x52, 0x84, 0xa, 0xc9, 0x1f, 0x66, 0xb1, 0x7e, 0x3c, \r
+       0x7a, 0x4f, 0xf8, 0x5c, 0x2d, 0xcb, 0x33, 0x78, 0x6a, 0xcf, \r
+       0xee, 0x3a, 0x87, 0x93, 0x2a, 0x89, 0x80, 0xd8, 0xb2, 0x6e, \r
+       0xd2, 0x2, 0xad, 0xfb, 0xd6, 0x71, 0x37, 0x18, 0x4, 0x7b, \r
+       0x92, 0x28, 0x25, 0x87, 0xa5, 0x7a, 0xb9, 0xd1, 0xfe, 0x3b, \r
+       0x97, 0x51, 0x9d, 0x61, 0xde, 0x41, 0x29, 0x40, 0x1, 0xbf, \r
+       0xbd, 0x70, 0x62, 0x9e, 0xc, 0xb4, 0x1f, 0xb7, 0x74, 0x9, \r
+       0x13, 0x4d, 0x2a, 0xd6, 0xda, 0x22, 0xdc, 0x61, 0x60, 0x5e, \r
+       0x97, 0x6c, 0x9e, 0x41, 0x8d, 0x1f, 0x50, 0xbb, 0x71, 0xeb, \r
+       0x1b, 0x55, 0x5d, 0xf0, 0x3e, 0xd8, 0x82, 0xe8, 0xf7, 0xcf, \r
+       0x3, 0xb0, 0x23, 0x41, 0x91, 0xe1, 0xe3, 0x33, 0xe2, 0xe1, \r
+       0x41, 0x77, 0x2b, 0x66, 0x50, 0x18, 0x77, 0xe9, 0x5c, 0x5e, \r
+       0xf0, 0x4, 0x12, 0x25, 0x96, 0x10, 0xf3, 0x48, 0x46, 0xe5, \r
+       0x38, 0x3, 0x4e, 0xe1, 0x93, 0xcd, 0xab, 0x26, 0x55, 0x56, \r
+       0x9, 0x8c, 0x39, 0x49, 0xca, 0xe8, 0x93, 0x4, 0x4d, 0xd8, \r
+       0xb, 0xbb, 0x3a, 0x87, 0xc6, 0xbf, 0x56, 0x1e, 0x7, 0x80, \r
+       0x39, 0xa0, 0xc8, 0x81, 0x8d, 0x19, 0x2f, 0xc6, 0x7c, 0xbd, \r
+       0x5e, 0xc0, 0x28, 0x16, 0x17, 0x50, 0x7a, 0xdc, 0x2, 0xd8, \r
+       0xcd, 0xf3, 0x92, 0x17, 0x96, 0x4f, 0x89, 0xc8, 0xc, 0x56, \r
+       0x33, 0xcb, 0x63, 0x57, 0x11, 0xc5, 0xa5, 0x8, 0x7b, 0xb3, \r
+       0xf4, 0x43, 0x8f, 0x8e, 0x8c, 0x98, 0x36, 0xe8, 0x6, 0xdd, \r
+       0x7d, 0x9a, 0x94, 0x15, 0xb3, 0x3c, 0x23, 0x43, 0x4b, 0x3e, \r
+       0x94, 0x2e, 0x6c, 0xe6, 0xa1, 0xd, 0x1a, 0x25, 0x31, 0x85, \r
+       0x15, 0x14, 0x17, 0x98, 0x6f, 0x68, 0xec, 0x5c, 0xb0, 0x91, \r
+       0x70, 0x81, 0x32, 0xcf, 0x1e, 0x6b, 0xf7, 0xcd, 0x7, 0xeb, \r
+       0x67, 0x1, 0xf0, 0x2e, 0x16, 0x23, 0xa0, 0xc0, 0xac, 0xd8, \r
+       0x5d, 0x9c, 0xad, 0x7b, 0x8d, 0xcc, 0x89, 0xcd, 0x3c, 0x58, \r
+       0x87, 0x55, 0x27, 0xb7, 0x90, 0x6a, 0xb6, 0xf1, 0xd, 0x15, \r
+       0x65, 0x4, 0x55, 0x45, 0x6e, 0xd9, 0x5b, 0x27, 0x60, 0x1f, \r
+       0x36, 0x25, 0x7c, 0xb3, 0x42, 0x28, 0x91, 00, 0xef, 0xff, \r
+       0xce, 0x27, 0x42, 0xe0, 0x58, 0x9d, 0xa5, 0x4f, 0x28, 0x23, \r
+       0xde, 0x5f, 0x24, 0x6c, 0x91, 0xe9, 0x2c, 0x35, 0xb6, 0xc8, \r
+       0xd7, 0xc, 0xee, 0x50, 0x3c, 0x77, 0x72, 0xcb, 0x76, 0x42, \r
+       0x3, 0x34, 0xba, 0xb4, 0xf2, 0x29, 0xf1, 0x51, 0x44, 0x43, \r
+       0x8b, 0xc8, 0x8d, 0x69, 0x11, 0x32, 0xcd, 0x17, 0xef, 0xfa, \r
+       0xcf, 0xf4, 0x28, 0x61, 0x37, 0x1e, 0xcc, 0xa1, 0x37, 0x6e, \r
+       0x9d, 0xa4, 0x40, 0x51, 0x28, 0x31, 0x28, 0xa8, 0x34, 0x66, \r
+       0x1f, 0x48, 0x18, 0xaf, 0x49, 0x63, 0xb8, 0x92, 0x6f, 0xac, \r
+       0x44, 0xdd, 0x56, 0xad, 0xcc, 0xc3, 0x6e, 0x41, 0xc3, 0x43, \r
+       0x45, 0xb0, 0xec, 0xfe, 0xd9, 0x32, 0x9a, 0xb8, 0x7c, 0x2d, \r
+       0xee, 0x25, 0x43, 0xe8, 0x31, 0x28, 0x83, 0x67, 0xd, 0xe0, \r
+       0xb6, 0x56, 0x5f, 0x95, 0xb7, 0xd5, 0x12, 0xec, 0x56, 0x7f, \r
+       0xcc, 0x5b, 0x84, 0xa6, 0x30, 0x9f, 0x5c, 0x3, 0xd6, 0x7d, \r
+       0xe5, 0x5b, 0x8c, 0x46, 0xa2, 0xc0, 0xdc, 0x75, 0xf9, 0x19, \r
+       0x7a, 0xc, 0xca, 0xdb, 0x9e, 0xc7, 0xa1, 0xc9, 0xa1, 0x71, \r
+       0x65, 0xd3, 0xf6, 0x38, 0xb6, 0xdc, 0xf3, 0x10, 0x90, 0x5b, \r
+       0x16, 0x5b, 0x23, 0x33, 0x42, 0x85, 0x89, 0xc0, 0x6e, 0xda, \r
+       0xe4, 0xac, 0xe9, 0x26, 0x85, 0x9d, 0x9a, 0xe5, 0xc1, 0x30, \r
+       0x95, 0x55, 0x3c, 0xc9, 0xd9, 0xe1, 0x6f, 0xfd, 0xd, 0x9a, \r
+       0x8c, 0x51, 0xe3, 0x9b, 0x6c, 0x10, 0xcc, 0x82, 0x5b, 0x37, \r
+       0x3a, 0x82, 0xc7, 0xe4, 0xcf, 0x66, 0xea, 0xe, 0x91, 0x4b, \r
+       0xbe, 0x95, 0x7, 0xf2, 0x40, 0x10, 0x22, 0x43, 0x5e, 0x82, \r
+       0xc2, 0xe4, 0x97, 0x2d, 0xdf, 0x6, 0xce, 0xcb, 0x30, 0xec, \r
+       0x24, 0x93, 0x97, 0x6b, 0xd3, 0x24, 0xec, 0x1c, 0x33, 0x7, \r
+       0xda, 0x4b, 0xb, 0xdc, 0x23, 0x60, 0xe4, 0xaf, 0x8d, 0xff, \r
+       0x81, 0x27, 0x8a, 0x94, 0x96, 0x4d, 0xa1, 0x38, 0x93, 0x39, \r
+       0x67, 0x61, 0x73, 0x3b, 0x27, 0x9a, 0x72, 0xba, 0x60, 0xf1, \r
+       0xc8, 0x98, 0x68, 0xe5, 0xcb, 0x70, 0x61, 0xc6, 0xd2, 0x22, \r
+       0xe5, 0x22, 0xe, 0x10, 0xc2, 0x30, 0x8e, 0xb8, 0x4f, 0xc9, \r
+       0x86, 0x8e, 0x17, 0x72, 0xff, 0x9c, 0xfd, 0xc, 0xfc, 0xf8, \r
+       0xe8, 0xf0, 0x11, 0x17, 0x70, 0xbf, 0x69, 0x87, 0xf3, 0x60, \r
+       0x48, 0xc, 0xcd, 0xa6, 0xb0, 0x14, 0x17, 0x62, 0x4d, 0x53, \r
+       0xaf, 0x6a, 0x89, 0x13, 0x89, 0xc4, 0x7d, 0x73, 0x52, 0x16, \r
+       0x6c, 0x86, 0x9, 0x23, 0x5b, 0x59, 0xc0, 0x5a, 0x52, 0xb0, \r
+       0x1, 0x1f, 0xbc, 0x77, 0x65, 0xd6, 0x1, 0x25, 0x6, 0xf5, \r
+       0xf4, 0x74, 0xe1, 0xe0, 0x8d, 0x85, 0xc6, 0x3f, 0x47, 0xcc, \r
+       0x26, 0xc0, 0xe6, 0x66, 0xa1, 0xc9, 0x46, 0xd1, 0x25, 0xd1, \r
+       0x45, 0x12, 0x6a, 0xfc, 0xf3, 0x24, 0xd, 0x85, 0x3f, 00, \r
+       0x23, 0xd5, 0x6e, 0xb1, 0x16, 0x63, 0x11, 0x1c, 0x30, 0x24, \r
+       0xd3, 00, 0x14, 0xcd, 0xb3, 0xac, 0x4, 0xbd, 0x10, 0xfd, \r
+       0x1b, 0x15, 0x93, 0x82, 0x5d, 0xb1, 0xc, 0x49, 0xf1, 0xfa, \r
+       0x67, 0x9f, 0x24, 0xec, 0x1e, 0x6e, 0x10, 0x6c, 0xb5, 0x5a, \r
+       0x34, 0xc1, 0xe0, 0x83, 0x1c, 0x83, 0xcd, 0xc3, 0x2c, 0xb0, \r
+       0x16, 0xd1, 0x65, 0xf0, 0x41, 0x11, 0x36, 0x6a, 0xdf, 0x76, \r
+       0x5f, 0x70, 0x25, 0x7a, 0xbb, 0x32, 0x54, 0x82, 0x60, 0xc5, \r
+       0x22, 0x91, 0x67, 0x75, 0xf7, 0x63, 0xb, 0x16, 0xb3, 0xba, \r
+       0x5f, 0xa5, 0xc8, 0xe0, 0x68, 0x46, 0x53, 0x69, 0xab, 0x54, \r
+       0xea, 0x8a, 0x94, 0x47, 0xeb, 0x30, 0x68, 0x73, 0x4a, 0xe2, \r
+       0x2f, 0xf7, 0x24, 0x4a, 0xca, 0x8b, 0xfd, 0xc6, 0xc9, 0x9f, \r
+       0xa8, 0x47, 0x66, 0x96, 0xa2, 0xa1, 0x9, 0x4e, 0x7f, 0x3f, \r
+       0x8e, 0x43, 0x47, 0x1a, 0x5f, 0xaf, 0x98, 0xab, 0xf1, 0x75, \r
+       0xa0, 0x50, 0x35, 0x15, 0xc8, 0xce, 0x44, 0x53, 0x69, 0x32, \r
+       0x55, 0x46, 0x9d, 0x7a, 0xa2, 0xe, 0xfc, 0xb0, 0xa7, 0xad, \r
+       0x1e, 0xc6, 0xda, 0x63, 0x67, 0xfa, 0xb, 0x42, 0x59, 0xb1, \r
+       0x8, 0xdb, 0x49, 0x45, 0xc0, 0xdf, 0x1f, 0x45, 0xe7, 0x50, \r
+       0xb3, 0x65, 0xa0, 0x5a, 0xb6, 0xf7, 0xe3, 0x4, 0xd6, 0xb0, \r
+       0xc6, 0x5, 0x6a, 0x55, 0xb9, 0x3a, 0xd4, 0xae, 0x92, 0x85, \r
+       0xbd, 0xb8, 0x26, 0x24, 0x92, 0x7d, 0xea, 0xe5, 0x94, 0x2, \r
+       0xb5, 0xa2, 0x3e, 0xe2, 0x8c, 0xc8, 0xdd, 0x36, 0xe8, 0x16, \r
+       0x96, 0x5d, 0x82, 0x5, 0xd4, 0x1a, 0x23, 0x8b, 0x51, 0x69, \r
+       0x4f, 0xe0, 0x8b, 0x99, 0x8b, 0x3d, 0xbe, 0x9b, 0xcd, 0x41, \r
+       0x88, 0xb1, 0xdd, 0xc3, 0x4c, 0x44, 0x79, 0xcc, 0x82, 0xdc, \r
+       0x8d, 0x47, 0x81, 0xfb, 0x4e, 0xc7, 0x3, 0xcd, 0x3b, 0xa0, \r
+       0x72, 0xb1, 0x5, 0x1, 0xfd, 0x2a, 0xa, 0x8f, 0xf9, 0xf3, \r
+       0x35, 0x47, 0x7c, 0x8a, 0xa5, 0x47, 0x26, 0x2b, 0xb3, 0xd0, \r
+       0xf3, 0xad, 0xab, 0x72, 0x5b, 0x99, 0xa3, 0x7, 0xd7, 0x10, \r
+       0xce, 0x63, 0x58, 0x8, 0x5a, 0x6e, 0x9, 0xd1, 0xcd, 0x45, \r
+       0xc0, 0xbb, 0x55, 0x77, 0xc8, 0x20, 0xe0, 0x76, 0x41, 0xad, \r
+       0xee, 0x15, 0x4b, 0xb6, 0x10, 0xdb, 0x73, 0xc4, 0x5f, 0x6a, \r
+       0x2e, 0x5c, 0x18, 0x11, 0x6c, 0x6, 0xf7, 0xfa, 0xb9, 0x8b, \r
+       0x32, 0x3b, 0x21, 0xd3, 0xeb, 0x94, 0xff, 0x17, 0xf0, 0xd5, \r
+       0xd5, 0xc6, 0x9c, 0xd4, 0xe0, 0xf0, 0x8, 0x31, 0xbe, 0x1, \r
+       0x83, 0x61, 0x1c, 0xb6, 0x2c, 0x4, 0x4c, 0xf2, 0x75, 0xc, \r
+       0x8a, 0x5, 0x5, 0x37, 0xc8, 0x80, 0xb, 0xed, 0x9a, 0xc3, \r
+       0x6, 0x19, 0x37, 0x90, 0x7e, 0xdc, 0x4a, 0x32, 0x82, 0xd4, \r
+       0x29, 0x92, 0xd9, 0x3e, 0xdc, 0x71, 0x26, 0xcd, 0x30, 0x47, \r
+       0x1e, 0xde, 0x82, 0x18, 0x7d, 0x3, 0x4b, 0x8c, 0xe6, 0xc, \r
+       0x56, 0x57, 0xc3, 0x2d, 0x49, 0x70, 0x9f, 0x17, 0x18, 0xee, \r
+       0x56, 0x98, 0x8b, 0x59, 0xf2, 0x98, 0x2e, 0x59, 0xd8, 0x18, \r
+       0xeb, 0xf5, 0x31, 0xf0, 0xe9, 0x91, 0x43, 0xc4, 0x8b, 0x4, \r
+       0x32, 0xca, 0x91, 0xc4, 0xfd, 0x2a, 0xd2, 0xa, 0x9a, 0x2a, \r
+       0x6c, 0x41, 0x8b, 0xcc, 0xd, 0xe7, 0x89, 0x8b, 0x1c, 0x4c, \r
+       0xbe, 0xcf, 0xd1, 0xf0, 0x66, 0x20, 0x67, 0x5, 0x92, 0xf1, \r
+       0x8e, 0x41, 0x1e, 0xb3, 0x51, 0x7f, 0x5e, 0x10, 0x4, 0xb8, \r
+       0x8a, 0x3d, 0x1f, 0x91, 0xab, 0x51, 0xc0, 0xa2, 0x6e, 0x1a, \r
+       0x7f, 0x53, 0x63, 0x29, 0x4, 0x6b, 0xa1, 0xa6, 0x78, 0x4c, \r
+       0x9e, 0x8e, 0xc7, 0xc8, 0x64, 0x29, 0x86, 0x13, 0x65, 0x1f, \r
+       0xd4, 0xe8, 0xe6, 0xb7, 0x3a, 0x47, 0xba, 0xca, 0xde, 0xf1, \r
+       0x5c, 0x5e, 0xf3, 0x63, 0x65, 0x2c, 0x15, 0x65, 0x35, 0xba, \r
+       0xb4, 0xde, 0xe6, 0xd0, 0xef, 0xe8, 0xe5, 0x82, 0x33, 0xfe, \r
+       0xdd, 0xe6, 0xd, 0xf9, 0x7e, 0xb3, 0x78, 0x61, 0x96, 0xe3, \r
+       0xa6, 0xa3, 00, 0x59, 0xd8, 0xae, 0xa2, 0xbe, 0x21, 0x68, \r
+       0xff, 0xf, 0xc0, 0xd, 0x6, 0x12, 0x9f, 0x6f, 0x55, 0x17, \r
+       0x36, 0x35, 0x1c, 0xb9, 0xd5, 0x81, 0x6, 0xfd, 0xc2, 0xb2, \r
+       0xb9, 0x51, 0x58, 0xa8, 0x9d, 00, 0xb3, 0x39, 0x1f, 0x51, \r
+       0x6, 0xfe, 0xc, 0xb5, 0xcc, 0x62, 0xa5, 0xf1, 0x21, 0x9, \r
+       0x2b, 0x77, 0x99, 0xf9, 0xfe, 0x6e, 0x3f, 0x75, 0xc9, 0x60, \r
+       0x53, 0x90, 0x3b, 0xe5, 0x7b, 0xf5, 0xab, 0x28, 0xc0, 0x66, \r
+       0x47, 0x1b, 0x54, 0x3d, 0x34, 0xf3, 0x36, 0x6c, 0x3f, 0x1f, \r
+       0xe6, 0xe2, 0x2a, 0x59, 0xf1, 0x2c, 0x21, 0xf8, 0xa7, 0xba, \r
+       0xdf, 0x58, 0x7, 0xeb, 0xd0, 0x66, 0x69, 0xb1, 0xeb, 0x9e, \r
+       0x7d, 0x20, 0xd6, 0x78, 0xd9, 0xde, 0xc, 0x14, 0x26, 0x7b, \r
+       0x8b, 0x8e, 0xd0, 0x25, 0xb3, 0x2f, 0x95, 0xf4, 0xb8, 0x1f, \r
+       0x95, 0xb0, 0x98, 0x74, 0xdc, 0x95, 0x87, 0x11, 0x56, 0x8, \r
+       0xb0, 0x9c, 0x38, 0x27, 0xdf, 0x68, 0x24, 0xc0, 0x84, 0xa7, \r
+       0x3f, 0x2d, 0xef, 0x94, 0x36, 0x86, 0x16, 0x8, 0x64, 0xc2, \r
+       0x8b, 0xa4, 0xbd, 0x36, 0xa, 0x28, 0xc2, 0xb2, 0x26, 0xdc, \r
+       0xd, 0xe, 0x17, 0x77, 0xcb, 0x98, 0x50, 0xef, 0x4a, 0xe6, \r
+       0xce, 0x2f, 0x6b, 0x41, 0x53, 0xe3, 0xbb, 0x3c, 0x3c, 0x44, \r
+       0xa0, 0xd6, 0x73, 0x28, 0x5e, 0x10, 0xa3, 0xa4, 0xa4, 0xe9, \r
+       0x62, 0xb, 0x40, 0xb6, 0x56, 0x31, 0x20, 0x3c, 0x28, 0x39, \r
+       0x89, 0xa0, 0x84, 0x4b, 0x8a, 0xec, 0x57, 0xa0, 0xd1, 0xc, \r
+       0xb5, 0xa, 0xba, 0xeb, 0x28, 0x3c, 0x8, 0xa4, 0xae, 0xa6, \r
+       0x2e, 0x99, 0x4a, 0x2f, 0x31, 0xe5, 0xbf, 0x2c, 0xa5, 0xfa, \r
+       0xff, 0xd, 0x47, 0x6f, 0x42, 0x2, 0x70, 0xd7, 0xcb, 0x76, \r
+       0xb5, 0x4d, 0xcb, 0x12, 0xac, 0x29, 0x17, 0xea, 0xd1, 0xc8, \r
+       0x56, 0x43, 0x7b, 0xb0, 0x71, 0x2f, 0x5f, 0x2a, 0xc5, 0x1c, \r
+       0x4b, 0x7f, 0x91, 0x9b, 0x9e, 0xd6, 0xeb, 0x9e, 0x75, 0x26, \r
+       0x10, 0x36, 0x3b, 0x71, 0x11, 0x5d, 0x1, 0xb8, 0xb8, 0xd6, \r
+       0xce, 0x6e, 0xdf, 0xf, 0x7, 0xc7, 0x26, 0x52, 0xe2, 0xf4, \r
+       0xc7, 0x8e, 0xa, 0xa, 0xd, 0x6f, 0xd9, 0xab, 0xa5, 0x9f, \r
+       0x3, 0xf0, 0xfc, 0x2b, 0x21, 0x21, 0xe4, 0x4d, 0x14, 0xac, \r
+       0x8a, 0xde, 0x51, 0x1f, 0x51, 0xba, 0x22, 0x53, 0x31, 0x31, \r
+       0xaa, 0xfe, 0x33, 0x2, 0xcb, 0xea, 0x5a, 0x83, 0xc0, 0x85, \r
+       0x1d, 0xbe, 0xb, 0x23, 0x89, 0x43, 0xf7, 0xff, 0x1f, 0xef, \r
+       0x40, 0x7c, 0x19, 0x90, 0x2d, 0xa8, 0xbe, 0xbd, 0xe9, 0xe9, \r
+       0x2f, 0x5e, 0xd0, 0x55, 0x51, 0x20, 0x40, 0x56, 0x50, 0x7d, \r
+       0xa7, 0x9c, 0xe0, 0x96, 0xd9, 0xef, 0x86, 0xa0, 0x40, 0xe3, \r
+       0xab, 0xfe, 0xc6, 0x56, 0xf5, 0x97, 0xbc, 0x18, 0xf7, 0xe5, \r
+       0x81, 0x77, 0x63, 0x76, 0x3a, 0x54, 0x50, 0x1d, 0x59, 0x2f, \r
+       0xf0, 0x70, 0xb3, 0xdc, 0xf0, 0x5d, 0xf8, 0x3e, 0x8f, 0x87, \r
+       0x69, 0xd9, 0x70, 0xea, 0x71, 0xdf, 0xd2, 0xea, 0x5, 0x4d, \r
+       0x12, 0x82, 0x93, 0x70, 0x8b, 0x1e, 0x17, 0x76, 0xbe, 0xe0, \r
+       0x68, 0x8d, 0xc0, 0xad, 0xce, 0xd0, 0x33, 0x76, 0xbd, 0x79, \r
+       0xd4, 0x77, 0x21, 0xa6, 0x16, 0x46, 0x8e, 0xbb, 0x7e, 0x8d, \r
+       0xba, 0xad, 0x1, 0x80, 0xf9, 0x7b, 0x7, 0xb1, 0x34, 0x2e, \r
+       0x6c, 0xe2, 0x5a, 0x87, 0xb0, 0xe8, 0x2f, 0x6d, 0xe9, 0x10, \r
+       0x5e, 0x14, 0xf0, 0x30, 0x7a, 0x5b, 0x8, 0x93, 0x5f, 0xd3, \r
+       0xf8, 0xe, 0xc8, 0x64, 0x1, 0x95, 0x40, 0x40, 0x36, 0x66, \r
+       0x9f, 0xc4, 0x97, 0x3, 0xa7, 0x18, 0x32, 0x61, 0xf3, 0x4a, \r
+       0xa2, 0x1f, 0x95, 0x6b, 0x30, 0x9, 0x91, 0x6b, 0xe3, 0x57, \r
+       0x8f, 0x2c, 0x4a, 0x8c, 0xa7, 0x2c, 0x93, 0x5, 0x3c, 0x8a, \r
+       0x76, 0x2c, 0x28, 0xb8, 0xd5, 0x59, 0x53, 0xd5, 0xce, 0x81, \r
+       0xb0, 0xb9, 0xe2, 0x4a, 0x9e, 0x44, 0x56, 0x1c, 0xfc, 0x98, \r
+       0x81, 0x6f, 0xfc, 0x9d, 0xfc, 0xac, 0xcc, 0xc5, 0xd3, 0x84, \r
+       0x4e, 0x9b, 0x98, 0xb8, 0xfa, 0xbb, 0xd9, 0x1c, 0x8, 0xdd, \r
+       0xfc, 0x8a, 0xec, 0x42, 0xc4, 0x1, 0xe5, 0x3e, 0xb7, 0x80, \r
+       0xe2, 0xeb, 0xd7, 0xc0, 0x1, 0x13, 0x1, 0xc6, 0x4c, 0x6a, \r
+       0x4b, 0x83, 0x81, 0x9, 0x59, 0xd8, 0x84, 0x77, 0xdc, 0x20, \r
+       0x4, 0x5b, 0xfd, 0x9b, 0x12, 0x50, 0x26, 0x1a, 0x4d, 0x6f, \r
+       0xcb, 0x6, 0x1c, 0x5f, 0x2d, 0xaf, 0x67, 0xa, 0xfe, 0x33, \r
+       0x12, 0x81, 0x50, 0xb1, 0x51, 0x83, 0xc4, 0xc9, 0xf4, 0xfd, \r
+       0xf, 0x26, 0x50, 0x51, 0x40, 0x20, 0x9, 0x2b, 0xbe, 0x6b, \r
+       0xf0, 0xd9, 0xc3, 0xbf, 0x18, 0x14, 0x8, 0xf4, 0x9c, 0x94, \r
+       0xde, 0xd8, 0x30, 0x14, 0x9, 0xbb, 0xc7, 0x46, 0xde, 0xe, \r
+       0x5d, 0xec, 0xc2, 0x2, 0xbf, 0x13, 0xc1, 0xf5, 0xe8, 0xfe, \r
+       00, 0x4f, 0xdf, 0x26, 0x55, 0x1a, 0x76, 0x69, 0x81, 0x3e, \r
+       0x84, 0x19, 0xcd, 0x16, 0xb7, 0x76, 0x99, 0xc3, 0x87, 0xbd, \r
+       0xb1, 0xda, 0x89, 0x32, 0xe2, 0x7b, 0x71, 0x76, 0x52, 0xf1, \r
+       0x8c, 0x1, 0x24, 0x8a, 0x2f, 0x8d, 0x72, 0x53, 0xff, 0x6f, \r
+       0xeb, 0x1e, 0xdb, 0x1b, 0x4, 0x5e, 0x9c, 0xf2, 0xff, 0x7c, \r
+       0x25, 0x11, 0xfc, 0x1d, 0xe1, 0x4f, 0x26, 0xaf, 0xbd, 0xea, \r
+       0x67, 0xf9, 0x6f, 0x2a, 0x60, 0x7e, 0x32, 0x3b, 0x43, 0x10, \r
+       0x16, 0x80, 0xdf, 0xbf, 0xa5, 0x7f, 0x2f, 0xe9, 0x17, 0xcd, \r
+       0xf4, 0x47, 0x15, 0x44, 0x8, 0xda, 0xc8, 0x7e, 0x36, 0x50, \r
+       0x28, 0x6e, 0x21, 0xfe, 0x1f, 0xd2, 0xa8, 0xa2, 0x91, 0xdc, \r
+       0x83, 0x90, 0x3, 00, 00, 00, 00, 0x49, 0x45, 0x4e, \r
+       0x44, 0xae, 0x42, 0x60, 0x82, };\r
+\r
+static const char data_cgi_files[] = {\r
+       /* /cgi/files */\r
+       0x2f, 0x63, 0x67, 0x69, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0,\r
+       0x23, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x73, 0x63, 0x72, \r
+       0x69, 0x70, 0x74, 0x20, 0x73, 0x68, 0x6f, 0x77, 0x73, 0x20, \r
+       0x74, 0x68, 0x65, 0x20, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, \r
+       0x20, 0x73, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, \r
+       0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x64, 0x69, 0x66, 0x66, \r
+       0x65, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x66, 0x69, 0x6c, 0x65, \r
+       0x73, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0xd, 0xa, \r
+       0x23, 0x20, 0x77, 0x65, 0x62, 0x20, 0x73, 0x65, 0x72, 0x76, \r
+       0x65, 0x72, 0x2e, 0xd, 0xa, 0x23, 0xd, 0xa, 0x23, 0x20, \r
+       0x46, 0x69, 0x72, 0x73, 0x74, 0x2c, 0x20, 0x77, 0x65, 0x20, \r
+       0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x20, 0x74, 0x68, \r
+       0x65, 0x20, 0x48, 0x54, 0x4d, 0x4c, 0x20, 0x68, 0x65, 0x61, \r
+       0x64, 0x65, 0x72, 0x2e, 0xd, 0xa, 0x69, 0x20, 0x2f, 0x66, \r
+       0x69, 0x6c, 0x65, 0x73, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65, \r
+       0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa, 0x23, 0x20, \r
+       0x50, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x6f, 0x75, 0x74, 0x20, \r
+       0x74, 0x68, 0x65, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x6f, \r
+       0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x6c, 0x65, \r
+       0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x61, 0x6c, 0x6c, \r
+       0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, \r
+       0x69, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x70, \r
+       0x72, 0x69, 0x6e, 0x74, 0x73, 0xd, 0xa, 0x23, 0x20, 0x74, \r
+       0x68, 0x65, 0x20, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, \r
+       0x73, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, \r
+       0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x66, \r
+       0x69, 0x6c, 0x65, 0x2e, 0xd, 0xa, 0x74, 0x20, 0x3c, 0x74, \r
+       0x72, 0x3e, 0x3c, 0x74, 0x64, 0x3e, 0x3c, 0x61, 0x20, 0x68, \r
+       0x72, 0x65, 0x66, 0x3d, 0x22, 0x2f, 0x69, 0x6e, 0x64, 0x65, \r
+       0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x2f, 0x69, \r
+       0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x3c, \r
+       0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x74, \r
+       0x64, 0x3e, 0xd, 0xa, 0x63, 0x20, 0x62, 0x20, 0x2f, 0x69, \r
+       0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0xd, \r
+       0xa, 0x74, 0x20, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x2f, \r
+       0x74, 0x72, 0x3e, 0x20, 0x3c, 0x74, 0x72, 0x3e, 0x3c, 0x74, \r
+       0x64, 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, \r
+       0x22, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, \r
+       0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x2f, 0x63, 0x6f, 0x6e, \r
+       0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x3c, \r
+       0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x74, \r
+       0x64, 0x3e, 0xd, 0xa, 0x63, 0x20, 0x62, 0x20, 0x2f, 0x63, \r
+       0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x68, 0x74, 0x6d, \r
+       0x6c, 0xd, 0xa, 0x74, 0x20, 0x3c, 0x2f, 0x74, 0x64, 0x3e, \r
+       0x3c, 0x2f, 0x74, 0x72, 0x3e, 0x20, 0x3c, 0x74, 0x72, 0x3e, \r
+       0x3c, 0x74, 0x64, 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, \r
+       0x66, 0x3d, 0x22, 0x2f, 0x69, 0x6d, 0x67, 0x2f, 0x6c, 0x6f, \r
+       0x67, 0x6f, 0x2e, 0x70, 0x6e, 0x67, 0x22, 0x3e, 0x2f, 0x69, \r
+       0x6d, 0x67, 0x2f, 0x6c, 0x6f, 0x67, 0x6f, 0x2e, 0x70, 0x6e, \r
+       0x67, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x74, 0x64, 0x3e, \r
+       0x3c, 0x74, 0x64, 0x3e, 0xd, 0xa, 0x63, 0x20, 0x62, 0x20, \r
+       0x2f, 0x69, 0x6d, 0x67, 0x2f, 0x6c, 0x6f, 0x67, 0x6f, 0x2e, \r
+       0x70, 0x6e, 0x67, 0xd, 0xa, 0x74, 0x20, 0x3c, 0x2f, 0x74, \r
+       0x64, 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0x20, 0x3c, 0x74, \r
+       0x72, 0x3e, 0x3c, 0x74, 0x64, 0x3e, 0x3c, 0x61, 0x20, 0x68, \r
+       0x72, 0x65, 0x66, 0x3d, 0x22, 0x2f, 0x34, 0x30, 0x34, 0x2e, \r
+       0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x2f, 0x34, 0x30, 0x34, \r
+       0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, \r
+       0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x74, 0x64, 0x3e, 0xd, 0xa, \r
+       0x63, 0x20, 0x62, 0x20, 0x2f, 0x34, 0x30, 0x34, 0x2e, 0x68, \r
+       0x74, 0x6d, 0x6c, 0xd, 0xa, 0x74, 0x20, 0x3c, 0x2f, 0x74, \r
+       0x64, 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0x20, 0x3c, 0x74, \r
+       0x72, 0x3e, 0x3c, 0x74, 0x64, 0x3e, 0x3c, 0x61, 0x20, 0x68, \r
+       0x72, 0x65, 0x66, 0x3d, 0x22, 0x2f, 0x63, 0x67, 0x69, 0x2f, \r
+       0x66, 0x69, 0x6c, 0x65, 0x73, 0x22, 0x3e, 0x2f, 0x63, 0x67, \r
+       0x69, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x3c, 0x2f, 0x61, \r
+       0x3e, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x74, 0x64, 0x3e, \r
+       0xd, 0xa, 0x63, 0x20, 0x62, 0x20, 0x2f, 0x63, 0x67, 0x69, \r
+       0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0xd, 0xa, 0x74, 0x20, \r
+       0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, \r
+       0x20, 0x3c, 0x74, 0x72, 0x3e, 0x3c, 0x74, 0x64, 0x3e, 0x3c, \r
+       0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x2f, 0x63, \r
+       0x67, 0x69, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x22, 0x3e, \r
+       0x2f, 0x63, 0x67, 0x69, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x73, \r
+       0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, \r
+       0x74, 0x64, 0x3e, 0xd, 0xa, 0x63, 0x20, 0x62, 0x20, 0x2f, \r
+       0x63, 0x67, 0x69, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x73, 0xd, \r
+       0xa, 0x74, 0x20, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x2f, \r
+       0x74, 0x72, 0x3e, 0x20, 0x3c, 0x74, 0x72, 0x3e, 0x3c, 0x74, \r
+       0x64, 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, \r
+       0x22, 0x2f, 0x63, 0x67, 0x69, 0x2f, 0x74, 0x63, 0x70, 0x22, \r
+       0x3e, 0x2f, 0x63, 0x67, 0x69, 0x2f, 0x74, 0x63, 0x70, 0x3c, \r
+       0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x74, \r
+       0x64, 0x3e, 0xd, 0xa, 0x63, 0x20, 0x62, 0x20, 0x2f, 0x63, \r
+       0x67, 0x69, 0x2f, 0x74, 0x63, 0x70, 0xd, 0xa, 0x74, 0x20, \r
+       0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, \r
+       0xd, 0xa, 0x23, 0x20, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x64, \r
+       0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x48, 0x54, 0x4d, 0x4c, \r
+       0x20, 0x66, 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x2e, 0xd, 0xa, \r
+       0x69, 0x20, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x5f, 0x66, \r
+       0x6f, 0x6f, 0x74, 0x65, 0x72, 0x2e, 0x70, 0x6c, 0x61, 0x69, \r
+       0x6e, 0xd, 0xa, 0x23, 0x20, 0x45, 0x6e, 0x64, 0x20, 0x6f, \r
+       0x66, 0x20, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x2e, 0xd, \r
+       0xa, 0x2e, };\r
+\r
+static const char data_cgi_stats[] = {\r
+       /* /cgi/stats */\r
+       0x2f, 0x63, 0x67, 0x69, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x73, 0,\r
+       0x69, 0x20, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x5f, 0x68, \r
+       0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c, \r
+       0xd, 0xa, 0x63, 0x20, 0x61, 0xd, 0xa, 0x69, 0x20, 0x2f, \r
+       0x73, 0x74, 0x61, 0x74, 0x73, 0x5f, 0x66, 0x6f, 0x6f, 0x74, \r
+       0x65, 0x72, 0x2e, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0xd, 0xa, \r
+       0x2e, 0xd, 0xa, };\r
+\r
+static const char data_cgi_tcp[] = {\r
+       /* /cgi/tcp */\r
+       0x2f, 0x63, 0x67, 0x69, 0x2f, 0x74, 0x63, 0x70, 0,\r
+       0x69, 0x20, 0x2f, 0x74, 0x63, 0x70, 0x5f, 0x68, 0x65, 0x61, \r
+       0x64, 0x65, 0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa, \r
+       0x63, 0x20, 0x63, 0xd, 0xa, 0x69, 0x20, 0x2f, 0x74, 0x63, \r
+       0x70, 0x5f, 0x66, 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x2e, 0x70, \r
+       0x6c, 0x61, 0x69, 0x6e, 0xd, 0xa, 0x2e, };\r
+\r
+static const char data_cgi_rtos[] = {\r
+       /* /cgi/rtos */\r
+       0x2f, 0x63, 0x67, 0x69, 0x2f, 0x72, 0x74, 0x6f, 0x73, 0,\r
+       0x74, 0x20, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x3c, 0x68, \r
+       0x65, 0x61, 0x64, 0x3e, 0x3c, 0x74, 0x69, 0x74, 0x6c, 0x65, \r
+       0x3e, 0x75, 0x49, 0x50, 0x20, 0x4f, 0x70, 0x65, 0x6e, 0x20, \r
+       0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x20, 0x45, 0x6d, 0x62, \r
+       0x65, 0x64, 0x64, 0x65, 0x64, 0x20, 0x54, 0x43, 0x50, 0x2f, \r
+       0x49, 0x50, 0x20, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x20, 0x4f, \r
+       0x6e, 0x20, 0x46, 0x72, 0x65, 0x65, 0x52, 0x54, 0x4f, 0x53, \r
+       0x20, 0x4b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x3c, 0x2f, 0x74, \r
+       0x69, 0x74, 0x6c, 0x65, 0x3e, 0x3c, 0x2f, 0x68, 0x65, 0x61, \r
+       0x64, 0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x42, 0x47, \r
+       0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x3d, 0x22, 0x23, 0x43, 0x43, \r
+       0x43, 0x43, 0x46, 0x46, 0x22, 0x3e, 0x3c, 0x66, 0x6f, 0x6e, \r
+       0x74, 0x20, 0x66, 0x61, 0x63, 0x65, 0x3d, 0x22, 0x61, 0x72, \r
+       0x69, 0x61, 0x6c, 0x22, 0x3e, 0x3c, 0x73, 0x6d, 0x61, 0x6c, \r
+       0x6c, 0x3e, 0x3c, 0x62, 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72, \r
+       0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, \r
+       0x2f, 0x77, 0x77, 0x77, 0x2e, 0x66, 0x72, 0x65, 0x65, 0x72, \r
+       0x74, 0x6f, 0x73, 0x2e, 0x6f, 0x72, 0x67, 0x22, 0x20, 0x74, \r
+       0x61, 0x72, 0x67, 0x65, 0x74, 0x3d, 0x22, 0x5f, 0x74, 0x6f, \r
+       0x70, 0x22, 0x3e, 0x46, 0x72, 0x65, 0x65, 0x52, 0x54, 0x4f, \r
+       0x53, 0x20, 0x48, 0x6f, 0x6d, 0x65, 0x70, 0x61, 0x67, 0x65, \r
+       0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x62, 0x3e, 0x3c, 0x2f, \r
+       0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x3e, 0x3c, 0x70, 0x3e, 0x3c, \r
+       0x48, 0x31, 0x3e, 0x41, 0x54, 0x39, 0x31, 0x53, 0x41, 0x4d, \r
+       0x37, 0x58, 0x20, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, \r
+       0x64, 0x20, 0x57, 0x45, 0x42, 0x20, 0x53, 0x65, 0x72, 0x76, \r
+       0x65, 0x72, 0x20, 0x44, 0x65, 0x6d, 0x6f, 0x3c, 0x62, 0x72, \r
+       0x3e, 0x3c, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x3e, 0x55, 0x73, \r
+       0x69, 0x6e, 0x67, 0x20, 0x75, 0x49, 0x50, 0x20, 0x61, 0x6e, \r
+       0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x46, 0x72, 0x65, 0x65, \r
+       0x52, 0x54, 0x4f, 0x53, 0x20, 0x72, 0x65, 0x61, 0x6c, 0x20, \r
+       0x74, 0x69, 0x6d, 0x65, 0x20, 0x6b, 0x65, 0x72, 0x6e, 0x65, \r
+       0x6c, 0x3c, 0x2f, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x3e, 0x3c, \r
+       0x2f, 0x68, 0x31, 0x3e, 0x3c, 0x70, 0x3e, 0x54, 0x68, 0x65, \r
+       0x73, 0x65, 0x20, 0x70, 0x61, 0x67, 0x65, 0x73, 0x20, 0x61, \r
+       0x72, 0x65, 0x20, 0x62, 0x65, 0x69, 0x6e, 0x67, 0x20, 0x73, \r
+       0x65, 0x72, 0x76, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x61, \r
+       0x6e, 0x20, 0x41, 0x74, 0x6d, 0x65, 0x6c, 0x20, 0x41, 0x54, \r
+       0x39, 0x31, 0x53, 0x41, 0x4d, 0x37, 0x58, 0x32, 0x35, 0x36, \r
+       0x20, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x63, 0x6f, 0x6e, 0x74, \r
+       0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2c, 0x20, 0x75, 0x73, \r
+       0x69, 0x6e, 0x67, 0x20, 0x41, 0x64, 0x61, 0x6d, 0x20, 0x44, \r
+       0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x20, 0x6f, 0x70, 0x65, \r
+       0x6e, 0x20, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x20, 0x75, \r
+       0x49, 0x50, 0x20, 0x54, 0x43, 0x50, 0x2f, 0x49, 0x50, 0x20, \r
+       0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x3c, 0x70, 0x3e, 0x54, \r
+       0x68, 0x65, 0x20, 0x75, 0x49, 0x50, 0x20, 0x73, 0x74, 0x61, \r
+       0x63, 0x6b, 0x20, 0x69, 0x73, 0x20, 0x65, 0x78, 0x65, 0x63, \r
+       0x75, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x66, 0x72, 0x6f, 0x6d, \r
+       0x20, 0x61, 0x20, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x20, \r
+       0x74, 0x61, 0x73, 0x6b, 0x20, 0x75, 0x6e, 0x64, 0x65, 0x72, \r
+       0x20, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x20, 0x6f, \r
+       0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x46, 0x72, 0x65, 0x65, \r
+       0x52, 0x54, 0x4f, 0x53, 0x20, 0x72, 0x65, 0x61, 0x6c, 0x20, \r
+       0x74, 0x69, 0x6d, 0x65, 0x20, 0x6b, 0x65, 0x72, 0x6e, 0x65, \r
+       0x6c, 0x2e, 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 0x74, 0x61, \r
+       0x62, 0x6c, 0x65, 0x20, 0x62, 0x65, 0x6c, 0x6f, 0x77, 0x20, \r
+       0x73, 0x68, 0x6f, 0x77, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, \r
+       0x73, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, \r
+       0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, \r
+       0x68, 0x65, 0x20, 0x74, 0x61, 0x73, 0x6b, 0x73, 0x20, 0x69, \r
+       0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x65, 0x6d, 0x6f, \r
+       0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x69, 0x74, \r
+       0x6f, 0x6e, 0x2e, 0x3c, 0x70, 0x3e, 0x3c, 0x70, 0x72, 0x65, \r
+       0x3e, 0x54, 0x61, 0x73, 0x6b, 0x20, 0x20, 0x20, 0x20, 0x20, \r
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x74, 0x61, 0x74, 0x65, \r
+       0x20, 0x20, 0x50, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, \r
+       0x20, 0x20, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x9, 0x23, 0x3c, \r
+       0x62, 0x72, 0x3e, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, \r
+       0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, \r
+       0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, \r
+       0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, \r
+       0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, \r
+       0x2a, 0x3c, 0x62, 0x72, 0x3e, 0xa, 0x63, 0x20, 0x64, 0xa, \r
+       0x74, 0x20, 0x3c, 0x2f, 0x70, 0x72, 0x65, 0x3e, 0x3c, 0x2f, \r
+       0x66, 0x6f, 0x6e, 0x74, 0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, \r
+       0x79, 0x3e, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, \r
+       0x2e, 0xa, 0xa, 0xa, };\r
+\r
+static const char data_index_html[] = {\r
+       /* /index.html */\r
+       0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,\r
+       0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, \r
+       0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72, \r
+       0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30, \r
+       0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, \r
+       0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63, \r
+       0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69, \r
+       0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65, \r
+       0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, \r
+       0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa, \r
+       0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xd, 0xa, \r
+       0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xd, 0xa, 0x3c, 0x2f, \r
+       0x68, 0x65, 0x61, 0x64, 0x3e, 0xd, 0xa, 0xd, 0xa, 0x3c, \r
+       0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x65, 0x74, 0x20, 0x63, \r
+       0x6f, 0x6c, 0x73, 0x3d, 0x22, 0x2a, 0x22, 0x20, 0x72, 0x6f, \r
+       0x77, 0x73, 0x3d, 0x22, 0x31, 0x32, 0x30, 0x2c, 0x2a, 0x22, \r
+       0x20, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x62, 0x6f, 0x72, 0x64, \r
+       0x65, 0x72, 0x3d, 0x22, 0x6e, 0x6f, 0x22, 0x3e, 0x20, 0xd, \r
+       0xa, 0x20, 0x20, 0x3c, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x20, \r
+       0x73, 0x72, 0x63, 0x3d, 0x22, 0x63, 0x6f, 0x6e, 0x74, 0x72, \r
+       0x6f, 0x6c, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0xd, \r
+       0xa, 0x20, 0x20, 0x3c, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x20, \r
+       0x73, 0x72, 0x63, 0x3d, 0x22, 0x2f, 0x63, 0x67, 0x69, 0x2f, \r
+       0x72, 0x74, 0x6f, 0x73, 0x22, 0x20, 0x6e, 0x61, 0x6d, 0x65, \r
+       0x3d, 0x22, 0x6d, 0x61, 0x69, 0x6e, 0x22, 0x3e, 0xd, 0xa, \r
+       0x3c, 0x2f, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x65, 0x74, \r
+       0x3e, 0xd, 0xa, 0xd, 0xa, 0x3c, 0x6e, 0x6f, 0x66, 0x72, \r
+       0x61, 0x6d, 0x65, 0x73, 0x3e, 0xd, 0xa, 0x3c, 0x62, 0x6f, \r
+       0x64, 0x79, 0x3e, 0xd, 0xa, 0x59, 0x6f, 0x75, 0x72, 0x20, \r
+       0x62, 0x72, 0x6f, 0x77, 0x73, 0x65, 0x72, 0x20, 0x6d, 0x75, \r
+       0x73, 0x74, 0x20, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, \r
+       0x20, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, 0xd, 0xa, 0x3c, \r
+       0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xd, 0xa, 0x3c, 0x2f, \r
+       0x6e, 0x6f, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x3e, 0xd, \r
+       0xa, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, };\r
+\r
+const struct fsdata_file file_404_html[] = {{NULL, data_404_html, data_404_html + 10, sizeof(data_404_html) - 10}};\r
+\r
+const struct fsdata_file file_control_html[] = {{file_404_html, data_control_html, data_control_html + 14, sizeof(data_control_html) - 14}};\r
+\r
+const struct fsdata_file file_files_footer_plain[] = {{file_control_html, data_files_footer_plain, data_files_footer_plain + 20, sizeof(data_files_footer_plain) - 20}};\r
+\r
+const struct fsdata_file file_files_header_html[] = {{file_files_footer_plain, data_files_header_html, data_files_header_html + 19, sizeof(data_files_header_html) - 19}};\r
+\r
+const struct fsdata_file file_stats_footer_plain[] = {{file_files_header_html, data_stats_footer_plain, data_stats_footer_plain + 20, sizeof(data_stats_footer_plain) - 20}};\r
+\r
+const struct fsdata_file file_stats_header_html[] = {{file_stats_footer_plain, data_stats_header_html, data_stats_header_html + 19, sizeof(data_stats_header_html) - 19}};\r
+\r
+const struct fsdata_file file_tcp_footer_plain[] = {{file_stats_header_html, data_tcp_footer_plain, data_tcp_footer_plain + 18, sizeof(data_tcp_footer_plain) - 18}};\r
+\r
+const struct fsdata_file file_tcp_header_html[] = {{file_tcp_footer_plain, data_tcp_header_html, data_tcp_header_html + 17, sizeof(data_tcp_header_html) - 17}};\r
+\r
+const struct fsdata_file file_img_logo_png[] = {{file_tcp_header_html, data_img_logo_png, data_img_logo_png + 14, sizeof(data_img_logo_png) - 14}};\r
+\r
+const struct fsdata_file file_cgi_files[] = {{file_img_logo_png, data_cgi_files, data_cgi_files + 11, sizeof(data_cgi_files) - 11}};\r
+\r
+const struct fsdata_file file_cgi_stats[] = {{file_cgi_files, data_cgi_stats, data_cgi_stats + 11, sizeof(data_cgi_stats) - 11}};\r
+\r
+const struct fsdata_file file_cgi_tcp[] = {{file_cgi_stats, data_cgi_tcp, data_cgi_tcp + 9, sizeof(data_cgi_tcp) - 9}};\r
+\r
+const struct fsdata_file file_cgi_rtos[] = {{file_cgi_tcp, data_cgi_rtos, data_cgi_rtos + 10, sizeof(data_cgi_rtos) - 10}};\r
+\r
+const struct fsdata_file file_index_html[] = {{file_cgi_rtos, data_index_html, data_index_html + 12, sizeof(data_index_html) - 12}};\r
+\r
+#define FS_ROOT file_index_html\r
+\r
 #define FS_NUMFILES 14\r
index 3701f6294aaeb635018138fd2f1750748403c236..18a578bd2495e72798f7716ea83178c159db54af 100644 (file)
@@ -140,7 +140,7 @@ typedef unsigned short uip_stats_t;
 #define UIP_IPADDR2     218U   /**< The third octet of the IP address of\r
                               this uIP node, if UIP_FIXEDADDR is\r
                               1. \hideinitializer */\r
-#define UIP_IPADDR3     204U  /**< The fourth octet of the IP address of\r
+#define UIP_IPADDR3     11U  /**< The fourth octet of the IP address of\r
                               this uIP node, if UIP_FIXEDADDR is\r
                               1. \hideinitializer */\r
 \r
@@ -426,7 +426,7 @@ typedef unsigned short uip_stats_t;
  *\r
  * \hideinitializer\r
  */\r
-#define UIP_BUFSIZE     2048\r
+#define UIP_BUFSIZE     1480\r
 \r
 \r
 /**\r
index 5215c627222e140088f427c5c05d9fc91cd26c67..4ea164efc00ec1867f54fe40b2709d88d409657b 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
index a9964bcebe687e7fa902a14430d229a8ccc20655..80fffaab820efef9545475b46ea43e1c50c51e81 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r