Changeset 12368
- Timestamp:
- 06/24/2009 07:07:47 PM (8 months ago)
- Files:
-
- ar5315_microredboot/microredboot/CHANGELOG (modified) (1 diff)
- ar5315_microredboot/microredboot/boot/src/misc_lzma.c (modified) (1 diff)
- ar5315_microredboot/microredboot/build_targets.sh (modified) (3 diffs)
- ar5315_microredboot/microredboot/ecos/packages/ecos.db (modified) (1 diff)
- ar5315_microredboot/microredboot/ecos/packages/hal/mips/mips64/current/cdl/hal_mips_mips64.cdl (modified) (1 diff)
- ar5315_microredboot/microredboot/ecos/packages/redboot/current/cdl/redboot.cdl (modified) (1 diff)
- ar5315_microredboot/microredboot/ecos/packages/redboot/current/src/flash.c (modified) (7 diffs)
- ar5315_microredboot/microredboot/ecos/packages/redboot/current/src/main.c (modified) (2 diffs)
- ar5315_microredboot/microredboot/ecos/packages/redboot/current/src/net/arp.c (modified) (4 diffs)
- ar5315_microredboot/microredboot/ecos/packages/redboot/current/src/net/bootp.c (modified) (2 diffs)
- ar5315_microredboot/microredboot/ecos/packages/redboot/current/src/net/cksum.c (modified) (1 diff)
- ar5315_microredboot/microredboot/ecos/packages/redboot/current/src/net/dns.c (modified) (5 diffs)
- ar5315_microredboot/microredboot/ecos/packages/redboot/current/src/net/enet.c (modified) (4 diffs)
- ar5315_microredboot/microredboot/ecos/packages/redboot/current/src/net/fwupgrade.c (added)
- ar5315_microredboot/microredboot/ecos/packages/redboot/current/src/net/fwupgrade.h (added)
- ar5315_microredboot/microredboot/ecos/packages/redboot/current/src/net/fwupgrade_ubnt.c (added)
- ar5315_microredboot/microredboot/ecos/packages/redboot/current/src/net/fwupgrade_ubnt.h (added)
- ar5315_microredboot/microredboot/ecos/packages/redboot/current/src/net/fwupgrade_wili.c (added)
- ar5315_microredboot/microredboot/ecos/packages/redboot/current/src/net/fwupgrade_wili.h (added)
- ar5315_microredboot/microredboot/ecos/packages/redboot/current/src/net/http_client.c (modified) (3 diffs)
- ar5315_microredboot/microredboot/ecos/packages/redboot/current/src/net/icmp.c (modified) (4 diffs)
- ar5315_microredboot/microredboot/ecos/packages/redboot/current/src/net/inet_addr.c (modified) (1 diff)
- ar5315_microredboot/microredboot/ecos/packages/redboot/current/src/net/ip.c (modified) (5 diffs)
- ar5315_microredboot/microredboot/ecos/packages/redboot/current/src/net/net_io.c (modified) (8 diffs)
- ar5315_microredboot/microredboot/ecos/packages/redboot/current/src/net/ping.c (modified) (1 diff)
- ar5315_microredboot/microredboot/ecos/packages/redboot/current/src/net/pktbuf.c (modified) (2 diffs)
- ar5315_microredboot/microredboot/ecos/packages/redboot/current/src/net/tcp.c (modified) (7 diffs)
- ar5315_microredboot/microredboot/ecos/packages/redboot/current/src/net/tftp_client.c (modified) (3 diffs)
- ar5315_microredboot/microredboot/ecos/packages/redboot/current/src/net/tftp_server.c (added)
- ar5315_microredboot/microredboot/ecos/packages/redboot/current/src/net/timers.c (modified) (1 diff)
- ar5315_microredboot/microredboot/ecos/packages/redboot/current/src/net/udp.c (modified) (2 diffs)
- ar5315_microredboot/microredboot/ecos/packages/templates/redboot/current.ect (modified) (1 diff)
- ar5315_microredboot/microredboot/images_default/redboot_ap48_32M_8M_kendin.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_default/redboot_ap51_16M_4M_admtek.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_default/redboot_ap51_16M_4M_icplus.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_default/redboot_ap51_16M_4M_kendin.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_default/redboot_ap51_16M_4M_marvell.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_default/redboot_ap51_16M_8M_admtek.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_default/redboot_ap51_16M_8M_icplus.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_default/redboot_ap51_16M_8M_kendin.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_default/redboot_ap51_16M_8M_marvell.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_default/redboot_ap51_32M_4M_admtek.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_default/redboot_ap51_32M_4M_icplus.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_default/redboot_ap51_32M_4M_kendin.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_default/redboot_ap51_32M_4M_marvell.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_default/redboot_ap51_32M_8M_admtek.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_default/redboot_ap51_32M_8M_icplus.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_default/redboot_ap51_32M_8M_kendin.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_default/redboot_ap51_32M_8M_marvell.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_default/redboot_ap61_16M_4M_admtek.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_default/redboot_ap61_16M_4M_icplus.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_default/redboot_ap61_16M_4M_kendin.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_default/redboot_ap61_16M_4M_marvell.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_default/redboot_ap61_16M_8M_admtek.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_default/redboot_ap61_16M_8M_icplus.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_default/redboot_ap61_16M_8M_kendin.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_default/redboot_ap61_16M_8M_marvell.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_default/redboot_ap61_32M_4M_admtek.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_default/redboot_ap61_32M_4M_icplus.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_default/redboot_ap61_32M_4M_kendin.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_default/redboot_ap61_32M_4M_marvell.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_default/redboot_ap61_32M_8M_admtek.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_default/redboot_ap61_32M_8M_icplus.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_default/redboot_ap61_32M_8M_kendin.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_default/redboot_ap61_32M_8M_marvell.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_dir300 (added)
- ar5315_microredboot/microredboot/images_dir300/redboot_ap61_16M_4M_admtek.rom (added)
- ar5315_microredboot/microredboot/images_dir300/redboot_ap61_16M_4M_icplus.rom (added)
- ar5315_microredboot/microredboot/images_dir300/redboot_ap61_16M_4M_kendin.rom (added)
- ar5315_microredboot/microredboot/images_dir300/redboot_ap61_16M_4M_marvell.rom (added)
- ar5315_microredboot/microredboot/images_dir300/redboot_ap61_16M_8M_admtek.rom (added)
- ar5315_microredboot/microredboot/images_dir300/redboot_ap61_16M_8M_icplus.rom (added)
- ar5315_microredboot/microredboot/images_dir300/redboot_ap61_16M_8M_kendin.rom (added)
- ar5315_microredboot/microredboot/images_dir300/redboot_ap61_16M_8M_marvell.rom (added)
- ar5315_microredboot/microredboot/images_dir300/redboot_ap61_32M_4M_admtek.rom (added)
- ar5315_microredboot/microredboot/images_dir300/redboot_ap61_32M_4M_icplus.rom (added)
- ar5315_microredboot/microredboot/images_dir300/redboot_ap61_32M_4M_kendin.rom (added)
- ar5315_microredboot/microredboot/images_dir300/redboot_ap61_32M_4M_marvell.rom (added)
- ar5315_microredboot/microredboot/images_dir300/redboot_ap61_32M_8M_admtek.rom (added)
- ar5315_microredboot/microredboot/images_dir300/redboot_ap61_32M_8M_icplus.rom (added)
- ar5315_microredboot/microredboot/images_dir300/redboot_ap61_32M_8M_kendin.rom (added)
- ar5315_microredboot/microredboot/images_dir300/redboot_ap61_32M_8M_marvell.rom (added)
- ar5315_microredboot/microredboot/images_senao/redboot_ap48_32M_8M_kendin.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_senao/redboot_ap51_16M_4M_admtek.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_senao/redboot_ap51_16M_4M_icplus.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_senao/redboot_ap51_16M_4M_kendin.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_senao/redboot_ap51_16M_4M_marvell.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_senao/redboot_ap51_16M_8M_admtek.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_senao/redboot_ap51_16M_8M_icplus.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_senao/redboot_ap51_16M_8M_kendin.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_senao/redboot_ap51_16M_8M_marvell.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_senao/redboot_ap51_32M_4M_admtek.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_senao/redboot_ap51_32M_4M_icplus.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_senao/redboot_ap51_32M_4M_kendin.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_senao/redboot_ap51_32M_4M_marvell.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_senao/redboot_ap51_32M_8M_admtek.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_senao/redboot_ap51_32M_8M_icplus.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_senao/redboot_ap51_32M_8M_kendin.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_senao/redboot_ap51_32M_8M_marvell.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_senao/redboot_ap61_16M_4M_admtek.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_senao/redboot_ap61_16M_4M_icplus.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_senao/redboot_ap61_16M_4M_kendin.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_senao/redboot_ap61_16M_4M_marvell.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_senao/redboot_ap61_16M_8M_admtek.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_senao/redboot_ap61_16M_8M_icplus.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_senao/redboot_ap61_16M_8M_kendin.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_senao/redboot_ap61_16M_8M_marvell.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_senao/redboot_ap61_32M_4M_admtek.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_senao/redboot_ap61_32M_4M_icplus.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_senao/redboot_ap61_32M_4M_kendin.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_senao/redboot_ap61_32M_4M_marvell.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_senao/redboot_ap61_32M_8M_admtek.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_senao/redboot_ap61_32M_8M_icplus.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_senao/redboot_ap61_32M_8M_kendin.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_senao/redboot_ap61_32M_8M_marvell.rom (modified) (previous)
- ar5315_microredboot/microredboot/images_wrt54g2/redboot_ap65_16M_4M.rom (modified) (previous)
- ar5315_microredboot/microredboot/makefile (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
ar5315_microredboot/microredboot/CHANGELOG
r12345 r12368 1 24.6.09 2 * added wiligear firmware format for tftp recovery (the whole code is rewritten to be readable and small) 3 23.6.09 4 * added ubnt firmware format for tftp recovery (format taken from fwsplit) 5 * added tftp recovery code (code was provided by wiligear) 6 - if reset button is keep pushed the tftp server will start, redboot will then accept tftp transfers in the common dd-wrt webflash format 7 - i will add wiligear GEOS format and ubnt format in future versions ,the provided code need to be rewritten first 8 22.6.09 9 * we invert the usage for resetbutton_enable here, so it will only boot redboot per default if the resetbutton feature is disabled from dd-wrt 10 otherwise, use trigger reset button to enter it 1 11 21.6.09 2 12 * implement dynamic uart clock for ap51/ap61 redboot (required for clean uart output with overclocked cpu's) ar5315_microredboot/microredboot/boot/src/misc_lzma.c
r12346 r12368 238 238 printf("Board: %s\n", ddboard); 239 239 char *resetbutton = nvram_get("resetbutton_enable"); 240 if (resetbutton && !strcmp(resetbutton, " 1"))241 puts("reset button manual override detected! (nvram var resetbutton_enable= 1)\n");242 if (resetTouched() || (resetbutton && !strcmp(resetbutton, " 1"))) {240 if (resetbutton && !strcmp(resetbutton, "0")) 241 puts("reset button manual override detected! (nvram var resetbutton_enable=0)\n"); 242 if (resetTouched() || (resetbutton && !strcmp(resetbutton, "0"))) { 243 243 puts("Reset Button triggered\nBooting Recovery RedBoot\n"); 244 244 ar5315_microredboot/microredboot/build_targets.sh
r12324 r12368 1 1 #default gpio 6 2 2 rm -f images/* 3 make ap51 ap61 RESETBUTTON=0x06 3 make ap51 ap61 RESETBUTTON=0x06 FIS=0 4 4 mkdir images_default 5 5 cp images/*.rom images_default 6 6 7 rm -f images/* 8 make ap61 RESETBUTTON=0x06 FIS=1 9 mkdir images_dir300 10 cp images/*.rom images_dir300 11 7 12 #senao like inverted gpio 5 8 make ap51 RESETBUTTON=0x15 13 make ap51 RESETBUTTON=0x15 FIS=2 9 14 mkdir images_senao 10 15 cp images/*.rom images_senao … … 17 22 18 23 rm -f images/* 19 make ap48 RESETBUTTON=0x16 24 make ap48 RESETBUTTON=0x16 FIS=0 20 25 mkdir images_senao 21 26 cp images/*.rom images_senao 22 27 23 28 rm -f images/* 24 make ap48 RESETBUTTON=0x06 29 make ap48 RESETBUTTON=0x06 FIS=0 25 30 mkdir images_default 26 31 cp images/*.rom images_default … … 29 34 cp -rv images_senao /GruppenLW/releases/images 30 35 cp -rv images_default /GruppenLW/releases/images 36 cp -rv images_dir300 /GruppenLW/releases/images 31 37 cp -rv images_wrt54g2 /GruppenLW/releases/images ar5315_microredboot/microredboot/ecos/packages/ecos.db
r12281 r12368 2104 2104 } 2105 2105 2106 package CYGPKG_CRC { 2107 alias { "CRC support" crc } 2108 directory services/crc 2109 script crc.cdl 2110 description " 2111 This package provides support for CRC functions, including the 2112 POSIX 1003 defined CRC algorithm." 2113 } 2114 2106 2115 2107 2116 package CYGPKG_CPULOAD { ar5315_microredboot/microredboot/ecos/packages/hal/mips/mips64/current/cdl/hal_mips_mips64.cdl
r12281 r12368 143 143 flavor data 144 144 no_define 145 default_value { "-mips64 -EL -msoft-float -Wall -Wpointer-arith -Wstrict-prototypes -Winline -Wundef -Woverloaded-virtual -g -O 2-ffunction-sections -fdata-sections -fno-rtti -fno-exceptions -fvtable-gc -finit-priority -G0" }145 default_value { "-mips64 -EL -msoft-float -Wall -Wpointer-arith -Wstrict-prototypes -Winline -Wundef -Woverloaded-virtual -g -Os -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions -fvtable-gc -finit-priority -G0" } 146 146 description " 147 147 This option controls the global compiler flags which ar5315_microredboot/microredboot/ecos/packages/redboot/current/cdl/redboot.cdl
r12281 r12368 335 335 This option enables the use of the TFTP protocol for download" 336 336 } 337 338 cdl_option CYGSEM_REDBOOT_NET_TFTP_SERVER { 339 display "Support TFTP server with WILIBOX fwupdate support" 340 flavor bool 341 default_value 1 342 compile -library=libextras.a net/tftp_server.c net/fwupgrade.c net/fwupgrade_ubnt.c net/fwupgrade_wili.c 343 description " 344 This option enables the use of the TFTP server" 345 } 346 347 cdl_option CYGSEM_REDBOOT_RESCUE_MODE { 348 display "Support rescue mode" 349 flavor bool 350 default_value 1 351 requires CYGSEM_REDBOOT_NET_TFTP_SERVER 352 description " 353 This option enables the rescue mode (start tftp server)" 354 } 337 355 338 356 cdl_option CYGSEM_REDBOOT_NET_HTTP_DOWNLOAD { ar5315_microredboot/microredboot/ecos/packages/redboot/current/src/flash.c
r12281 r12368 91 91 "Initialize FLASH Image System [FIS]", 92 92 "[-f]", 93 fis_init ,93 fis_init_comp, 94 94 FIS_cmds 95 95 ); … … 143 143 FIS_cmds 144 144 ); 145 #if defined(CYGPKG_HAL_MIPS_AR2316) 145 146 local_cmd_entry("create256", 146 147 "Create an image", … … 157 158 FIS_cmds 158 159 ); 160 #endif 159 161 #endif 160 162 … … 334 336 fis_endian_fixup(fis_work_block); 335 337 } 336 337 static void 338 fis_init(int argc, char *argv[]) 338 void fis_init(int argc, char *argv[],int force); 339 340 static void fis_init_comp(int argc, char *argv[]) 341 { 342 fis_init(argc, argv,0); 343 } 344 void fis_init(int argc, char *argv[],int force) 339 345 { 340 346 int stat; … … 353 359 } 354 360 355 if (! verify_action("About to initialize [format] FLASH image system")) {361 if (!force && !verify_action("About to initialize [format] FLASH image system")) { 356 362 diag_printf("** Aborted\n"); 357 363 return; … … 962 968 } 963 969 970 #if defined(CYGPKG_HAL_MIPS_AR2316) 964 971 965 972 static void … … 983 990 984 991 } 992 #endif 985 993 static void 986 994 fis_create(int argc, char *argv[]) ar5315_microredboot/microredboot/ecos/packages/redboot/current/src/main.c
r12281 r12368 156 156 void bist(void) CYGBLD_ATTRIB_WEAK; 157 157 158 #define RESCUE_SCRIPT "tftpd\n" 159 160 int in_rescue_mode = 0; 161 162 163 #include <ramconfig.h> 164 static int rescue_mode(void) 165 { 166 int b; 167 int inverse = (RESETBUTTON&0xf0); 168 int resetgpio = RESETBUTTON&0x0F; 169 #if defined(CYGPKG_HAL_MIPS_AR2316) 170 b = ((*(volatile unsigned int *)(AR2316_GPIO_DI)) >> 171 resetgpio) & 1; 172 #else 173 b = ((*(volatile unsigned int *)(AR531X_GPIO_DI)) >> 174 resetgpio) & 1; 175 #endif 176 if (inverse) 177 b=(1-b); 178 return b; 179 } 180 158 181 void 159 182 bist(void) 160 183 { 184 if (rescue_mode()) { 185 diag_printf("Reset button pressed - switching to rescue mode.\n"); 186 in_rescue_mode = 1; 187 } 188 161 189 } 162 190 … … 330 358 #endif 331 359 do_version(0,0); 360 361 if (in_rescue_mode) { 362 diag_printf("Starting RESCUE script...\n"); 363 script = RESCUE_SCRIPT; 364 } 332 365 333 366 #ifdef CYGFUN_REDBOOT_BOOT_SCRIPT ar5315_microredboot/microredboot/ecos/packages/redboot/current/src/net/arp.c
r12281 r12368 57 57 58 58 static struct { 59 intwaiting;60 char*eth;61 char*ip;59 int waiting; 60 char *eth; 61 char *ip; 62 62 } arp_req; 63 63 … … 65 65 * Handle incoming ARP packets. 66 66 */ 67 void 68 __arp_handler(pktbuf_t *pkt) 67 void __arp_handler(pktbuf_t * pkt) 69 68 { 70 arp_header_t *arp = pkt->arp_hdr; 71 int hw_type, protocol; 72 73 /* 74 * Only handle ethernet hardware and IP protocol. 75 */ 76 protocol = ntohs(arp->protocol); 77 hw_type = ntohs(arp->hw_type); 78 if ((hw_type == ARP_HW_ETHER) && (protocol == ETH_TYPE_IP)) { 69 arp_header_t *arp = pkt->arp_hdr; 70 int hw_type, protocol; 71 79 72 /* 80 * Handle requests for our ethernet address.73 * Only handle ethernet hardware and IP protocol. 81 74 */ 82 if (!memcmp(arp->target_ip, __local_ip_addr, 4)) { 83 if (ntohs(arp->opcode) == ARP_REQUEST) { 84 /* format response. */ 85 arp->opcode = htons(ARP_REPLY); 86 memcpy(arp->target_ip, arp->sender_ip, 87 sizeof(ip_addr_t)); 88 memcpy(arp->target_enet, arp->sender_enet, 89 sizeof(enet_addr_t)); 90 memcpy(arp->sender_ip, __local_ip_addr, 91 sizeof(ip_addr_t)); 92 memcpy(arp->sender_enet, __local_enet_addr, 93 sizeof(enet_addr_t)); 94 pkt->pkt_bytes = sizeof(arp_header_t); 95 __enet_send(pkt, &arp->target_enet, ETH_TYPE_ARP); 96 97 } else if (ntohs(arp->opcode) == ARP_REPLY && arp_req.waiting) { 98 if (!memcmp(arp_req.ip, arp->sender_ip, sizeof(ip_addr_t))) { 99 memcpy(arp_req.eth, arp->sender_enet, sizeof(enet_addr_t)); 100 arp_req.waiting = 0; 101 } 102 } 103 } 104 } 105 __pktbuf_free(pkt); 75 protocol = ntohs(arp->protocol); 76 hw_type = ntohs(arp->hw_type); 77 if ((hw_type == ARP_HW_ETHER) && (protocol == ETH_TYPE_IP)) { 78 /* 79 * Handle requests for our ethernet address. 80 */ 81 if (!memcmp(arp->target_ip, __local_ip_addr, 4)) { 82 if (ntohs(arp->opcode) == ARP_REQUEST) { 83 /* format response. */ 84 arp->opcode = htons(ARP_REPLY); 85 memcpy(arp->target_ip, arp->sender_ip, 86 sizeof(ip_addr_t)); 87 memcpy(arp->target_enet, arp->sender_enet, 88 sizeof(enet_addr_t)); 89 memcpy(arp->sender_ip, __local_ip_addr, 90 sizeof(ip_addr_t)); 91 memcpy(arp->sender_enet, __local_enet_addr, 92 sizeof(enet_addr_t)); 93 pkt->pkt_bytes = sizeof(arp_header_t); 94 __enet_send(pkt, &arp->target_enet, 95 ETH_TYPE_ARP); 96 97 } else if (ntohs(arp->opcode) == ARP_REPLY 98 && arp_req.waiting) { 99 if (!memcmp 100 (arp_req.ip, arp->sender_ip, 101 sizeof(ip_addr_t))) { 102 memcpy(arp_req.eth, arp->sender_enet, 103 sizeof(enet_addr_t)); 104 arp_req.waiting = 0; 105 } 106 } 107 } 108 } 109 __pktbuf_free(pkt); 106 110 } 107 108 111 109 112 /* … … 113 116 * -1 if unsuccessful. 114 117 */ 115 int 116 __arp_request(ip_addr_t *ip_addr, enet_addr_t *eth_addr, int allow_self) 118 int __arp_request(ip_addr_t * ip_addr, enet_addr_t * eth_addr, int allow_self) 117 119 { 118 pktbuf_t *pkt; 119 arp_header_t *arp; 120 unsigned long retry_start; 121 enet_addr_t bcast_addr; 122 int retry; 123 124 if (!allow_self) { 125 // Special case request for self 126 if (!memcmp(ip_addr, __local_ip_addr, 4)) { 127 memcpy(eth_addr, __local_enet_addr, sizeof(enet_addr_t)); 128 return 0; 129 } 130 } 131 132 /* just fail if can't get a buffer */ 133 if ((pkt = __pktbuf_alloc(ARP_PKT_SIZE)) == NULL) 120 pktbuf_t *pkt; 121 arp_header_t *arp; 122 unsigned long retry_start; 123 enet_addr_t bcast_addr; 124 int retry; 125 126 if (!allow_self) { 127 // Special case request for self 128 if (!memcmp(ip_addr, __local_ip_addr, 4)) { 129 memcpy(eth_addr, __local_enet_addr, 130 sizeof(enet_addr_t)); 131 return 0; 132 } 133 } 134 135 /* just fail if can't get a buffer */ 136 if ((pkt = __pktbuf_alloc(ARP_PKT_SIZE)) == NULL) 137 return -1; 138 139 arp = pkt->arp_hdr; 140 arp->opcode = htons(ARP_REQUEST); 141 arp->hw_type = htons(ARP_HW_ETHER); 142 arp->protocol = htons(0x800); 143 arp->hw_len = sizeof(enet_addr_t); 144 arp->proto_len = sizeof(ip_addr_t); 145 146 memcpy(arp->sender_ip, __local_ip_addr, sizeof(ip_addr_t)); 147 memcpy(arp->sender_enet, __local_enet_addr, sizeof(enet_addr_t)); 148 memcpy(arp->target_ip, ip_addr, sizeof(ip_addr_t)); 149 150 bcast_addr[0] = 255; 151 bcast_addr[1] = 255; 152 bcast_addr[2] = 255; 153 bcast_addr[3] = 255; 154 bcast_addr[4] = 255; 155 bcast_addr[5] = 255; 156 157 arp_req.eth = (char *)eth_addr; 158 arp_req.ip = (char *)ip_addr; 159 arp_req.waiting = 1; 160 161 retry = 8; 162 while (retry-- > 0) { 163 164 /* send the packet */ 165 pkt->pkt_bytes = sizeof(arp_header_t); 166 __enet_send(pkt, &bcast_addr, ETH_TYPE_ARP); 167 168 retry_start = MS_TICKS(); 169 while ((MS_TICKS_DELAY() - retry_start) < 250) { 170 __enet_poll(); 171 if (!arp_req.waiting) { 172 __pktbuf_free(pkt); 173 return 0; 174 } 175 } 176 } 177 __pktbuf_free(pkt); 134 178 return -1; 135 136 arp = pkt->arp_hdr;137 arp->opcode = htons(ARP_REQUEST);138 arp->hw_type = htons(ARP_HW_ETHER);139 arp->protocol = htons(0x800);140 arp->hw_len = sizeof(enet_addr_t);141 arp->proto_len = sizeof(ip_addr_t);142 143 memcpy(arp->sender_ip, __local_ip_addr, sizeof(ip_addr_t));144 memcpy(arp->sender_enet, __local_enet_addr, sizeof(enet_addr_t));145 memcpy(arp->target_ip, ip_addr, sizeof(ip_addr_t));146 147 bcast_addr[0] = 255;148 bcast_addr[1] = 255;149 bcast_addr[2] = 255;150 bcast_addr[3] = 255;151 bcast_addr[4] = 255;152 bcast_addr[5] = 255;153 154 arp_req.eth = (char *)eth_addr;155 arp_req.ip = (char *)ip_addr;156 arp_req.waiting = 1;157 158 retry = 8;159 while (retry-- > 0) {160 161 /* send the packet */162 pkt->pkt_bytes = sizeof(arp_header_t);163 __enet_send(pkt, &bcast_addr, ETH_TYPE_ARP);164 165 retry_start = MS_TICKS();166 while ((MS_TICKS_DELAY() - retry_start) < 250) {167 __enet_poll();168 if (!arp_req.waiting) {169 __pktbuf_free(pkt);170 return 0;171 }172 }173 }174 __pktbuf_free(pkt);175 return -1;176 179 } 177 180 … … 179 182 static ip_route_t routes[NUM_ARP]; 180 183 181 int 182 __arp_lookup(ip_addr_t *host, ip_route_t *rt) 184 int __arp_lookup(ip_addr_t * host, ip_route_t * rt) 183 185 { 184 int i; 185 static int next_arp = 0; 186 187 for (i = 0; i < NUM_ARP; i++) { 188 if (memcmp(host, &routes[i].ip_addr, sizeof(*host)) == 0) { 189 // This is a known host 190 memcpy(rt, &routes[i], sizeof(*rt)); 191 return 0; 192 } 193 } 194 memcpy(&rt->ip_addr, host, sizeof(*host)); 195 if (((*host)[0] == 0xFF) && ((*host)[1] == 0xFF) && ((*host)[2] == 0xFF)) { 196 memset(&rt->enet_addr, 0xFF, sizeof(&rt->enet_addr)); 197 return 0; 186 int i; 187 static int next_arp = 0; 188 189 for (i = 0; i < NUM_ARP; i++) { 190 if (memcmp(host, &routes[i].ip_addr, sizeof(*host)) == 0) { 191 // This is a known host 192 memcpy(rt, &routes[i], sizeof(*rt)); 193 return 0; 194 } 195 } 196 memcpy(&rt->ip_addr, host, sizeof(*host)); 197 if (((*host)[0] == 0xFF) && ((*host)[1] == 0xFF) 198 && ((*host)[2] == 0xFF)) { 199 memset(&rt->enet_addr, 0xFF, sizeof(&rt->enet_addr)); 200 return 0; 198 201 #ifdef CYGSEM_REDBOOT_NETWORKING_USE_GATEWAY 199 } else if (!__ip_addr_local(host)) {200 // non-local IP address -- look up Gateway's Ethernet address201 host = &__local_ip_gate;202 } else if (!__ip_addr_local(host)) { 203 // non-local IP address -- look up Gateway's Ethernet address 204 host = &__local_ip_gate; 202 205 #endif 203 } 204 if (__arp_request(host, &rt->enet_addr, 0) < 0) { 205 return -1; 206 } else { 207 memcpy(&routes[next_arp], rt, sizeof(*rt)); 208 if (++next_arp == NUM_ARP) next_arp = 0; 209 return 0; 210 } 206 } 207 if (__arp_request(host, &rt->enet_addr, 0) < 0) { 208 return -1; 209 } else { 210 memcpy(&routes[next_arp], rt, sizeof(*rt)); 211 if (++next_arp == NUM_ARP) 212 next_arp = 0; 213 return 0; 214 } 211 215 } 212 ar5315_microredboot/microredboot/ecos/packages/redboot/current/src/net/bootp.c
r12281 r12368 65 65 66 66 static bootp_header_t *bp_info; 67 68 #ifdef CYGSEM_REDBOOT_NETWORKING_DHCP 69 static const unsigned char dhcpCookie[] = {99,130,83,99}; 70 static const unsigned char dhcpEnd[] = {255}; 71 static const unsigned char dhcpDiscover[] = {53,1,1}; 72 static const unsigned char dhcpRequest[] = {53,1,3}; 73 static const unsigned char dhcpRequestIP[] = {50,4}; 74 static const unsigned char dhcpParamRequestList[] = {55,3,1,3,6}; 67 68 #ifdef CYGSEM_REDBOOT_NETWORKING_DHCP 69 static const unsigned char dhcpCookie[] = { 99, 130, 83, 99 }; 70 static const unsigned char dhcpEnd[] = { 255 }; 71 static const unsigned char dhcpDiscover[] = { 53, 1, 1 }; 72 static const unsigned char dhcpRequest[] = { 53, 1, 3 }; 73 static const unsigned char dhcpRequestIP[] = { 50, 4 }; 74 static const unsigned char dhcpParamRequestList[] = { 55, 3, 1, 3, 6 }; 75 75 76 static enum { 76 DHCP_NONE = 0,77 DHCP_DISCOVER,78 DHCP_OFFER,79 DHCP_REQUEST,80 DHCP_ACK77 DHCP_NONE = 0, 78 DHCP_DISCOVER, 79 DHCP_OFFER, 80 DHCP_REQUEST, 81 DHCP_ACK 81 82 } dhcpState; 82 83 #endif 83 84 84 85 static void 85 bootp_handler(udp_socket_t * skt, char *buf, int len,86 ip_route_t * src_route, word src_port)86 bootp_handler(udp_socket_t * skt, char *buf, int len, 87 ip_route_t * src_route, word src_port) 87 88 { 88 bootp_header_t *b; 89 #ifdef CYGSEM_REDBOOT_NETWORKING_DHCP 90 unsigned char *p, expected = 0; 91 #endif 92 93 b = (bootp_header_t *)buf; 94 if (bp_info) { 95 memset(bp_info,0,sizeof *bp_info); 96 if (len > sizeof *bp_info) 97 len = sizeof *bp_info; 98 memcpy(bp_info, b, len); 99 } 100 101 // Only accept pure REPLY responses 102 if (b->bp_op != BOOTREPLY) 103 return; 104 105 // Must be sent to me, as well! 106 if (memcmp(b->bp_chaddr, __local_enet_addr, 6)) 107 return; 108 109 #ifdef CYGSEM_REDBOOT_NETWORKING_DHCP 110 p = b->bp_vend; 111 if (memcmp(p, dhcpCookie, sizeof(dhcpCookie))) 112 return; 113 p += 4; 114 115 // Find the DHCP Message Type tag 116 while (*p != TAG_DHCP_MESS_TYPE) { 117 p += p[1] + 2; 118 if (p >= (unsigned char*)b + sizeof(*bp_info)) 119 return; 120 } 121 122 p += 2; 123 124 switch (dhcpState) { 125 case DHCP_DISCOVER: 126 // The discover message has been sent, only accept an offer reply 127 if (*p == DHCP_MESS_TYPE_OFFER) { 128 dhcpState = DHCP_OFFER; 129 return; 130 } else { 131 expected = DHCP_MESS_TYPE_OFFER; 132 } 133 break; 134 case DHCP_REQUEST: 135 // The request message has been sent, only accept an ack reply 136 if (*p == DHCP_MESS_TYPE_ACK) { 137 dhcpState = DHCP_ACK; 138 return; 139 } else { 140 expected = DHCP_MESS_TYPE_ACK; 141 } 142 break; 143 case DHCP_NONE: 144 case DHCP_OFFER: 145 case DHCP_ACK: 146 // Quitely ignore these - they indicate repeated message from server 147 return; 148 } 149 // See if we've been NAK'd - if so, give up and try again 150 if (*p == DHCP_MESS_TYPE_NAK) { 151 dhcpState = DHCP_NONE; 152 return; 153 } 154 diag_printf("DHCP reply: %d, not %d\n", (int)*p, (int)expected); 155 return; 89 bootp_header_t *b; 90 #ifdef CYGSEM_REDBOOT_NETWORKING_DHCP 91 unsigned char *p, expected = 0; 92 #endif 93 94 b = (bootp_header_t *) buf; 95 if (bp_info) { 96 memset(bp_info, 0, sizeof *bp_info); 97 if (len > sizeof *bp_info) 98 len = sizeof *bp_info; 99 memcpy(bp_info, b, len); 100 } 101 // Only accept pure REPLY responses 102 if (b->bp_op != BOOTREPLY) 103 return; 104 105 // Must be sent to me, as well! 106 if (memcmp(b->bp_chaddr, __local_enet_addr, 6)) 107 return; 108 109 #ifdef CYGSEM_REDBOOT_NETWORKING_DHCP 110 p = b->bp_vend; 111 if (memcmp(p, dhcpCookie, sizeof(dhcpCookie))) 112 return; 113 p += 4; 114 115 // Find the DHCP Message Type tag 116 while (*p != TAG_DHCP_MESS_TYPE) { 117 p += p[1] + 2; 118 if (p >= (unsigned char *)b + sizeof(*bp_info)) 119 return; 120 } 121 122 p += 2; 123 124 switch (dhcpState) { 125 case DHCP_DISCOVER: 126 // The discover message has been sent, only accept an offer reply 127 if (*p == DHCP_MESS_TYPE_OFFER) { 128 dhcpState = DHCP_OFFER; 129 return; 130 } else { 131 expected = DHCP_MESS_TYPE_OFFER; 132 } 133 break; 134 case DHCP_REQUEST: 135 // The request message has been sent, only accept an ack reply 136 if (*p == DHCP_MESS_TYPE_ACK) { 137 dhcpState = DHCP_ACK; 138 return; 139 } else { 140 expected = DHCP_MESS_TYPE_ACK; 141 } 142 break; 143 case DHCP_NONE: 144 case DHCP_OFFER: 145 case DHCP_ACK: 146 // Quitely ignore these - they indicate repeated message from server 147 return; 148 } 149 // See if we've been NAK'd - if so, give up and try again 150 if (*p == DHCP_MESS_TYPE_NAK) { 151 dhcpState = DHCP_NONE; 152 return; 153 } 154 diag_printf("DHCP reply: %d, not %d\n", (int)*p, (int)expected); 155 return; 156 156 #else 157 // Simple BOOTP - this is all there is!158 memcpy(__local_ip_addr, &b->bp_yiaddr, 4);157 // Simple BOOTP - this is all there is! 158 memcpy(__local_ip_addr, &b->bp_yiaddr, 4); 159 159 #endif 160 160 } … … 166 166 * Return zero if successful, -1 if not. 167 167 */ 168 int 169 __bootp_find_local_ip(bootp_header_t *info) 168 int __bootp_find_local_ip(bootp_header_t * info) 170 169 { 171 udp_socket_t udp_skt; 172 bootp_header_t b; 173 ip_route_t r; 174 int retry; 175 unsigned long start; 176 ip_addr_t saved_ip_addr; 177 #ifdef CYGSEM_REDBOOT_NETWORKING_DHCP 178 unsigned char *p; 179 int oldState; 180 #endif 181 int txSize; 182 bool abort = false; 183 static int xid = SHOULD_BE_RANDOM; 184 185 #ifdef CYGSEM_REDBOOT_NETWORKING_DHCP 186 dhcpState = DHCP_NONE; 187 #endif 188 189 // Where we want the results saved 190 bp_info = info; 191 // Preserve any IP address we currently have, just in case 192 memcpy(saved_ip_addr, __local_ip_addr, sizeof(__local_ip_addr)); 193 194 // fill out route for a broadcast 195 r.ip_addr[0] = 255; 196 r.ip_addr[1] = 255; 197 r.ip_addr[2] = 255; 198 r.ip_addr[3] = 255; 199 r.enet_addr[0] = 255; 200 r.enet_addr[1] = 255; 201 r.enet_addr[2] = 255; 202 r.enet_addr[3] = 255; 203 r.enet_addr[4] = 255; 204 r.enet_addr[5] = 255; 205 206 // setup a socket listener for bootp replies 207 __udp_install_listener(&udp_skt, IPPORT_BOOTPC, bootp_handler); 208 209 retry = MAX_RETRIES; 210 while (!abort && (retry-- > 0)) { 211 start = MS_TICKS(); 212 213 // Build up the BOOTP/DHCP request 214 memset(&b, 0, sizeof(b)); 215 b.bp_op = BOOTREQUEST; 216 b.bp_htype = HTYPE_ETHERNET; 217 b.bp_hlen = 6; 218 b.bp_xid = xid++; 219 memcpy(b.bp_chaddr, __local_enet_addr, 6); 220 memset(__local_ip_addr, 0, sizeof(__local_ip_addr)); 221 222 #ifdef CYGSEM_REDBOOT_NETWORKING_DHCP 223 p = b.bp_vend; 224 switch (dhcpState) { 225 case DHCP_NONE: 226 case DHCP_DISCOVER: 227 AddOption(p,dhcpCookie); 228 AddOption(p,dhcpDiscover); 229 AddOption(p,dhcpParamRequestList); 230 AddOption(p,dhcpEnd); 231 dhcpState = DHCP_DISCOVER; 232 break; 233 case DHCP_OFFER: 234 retry = MAX_RETRIES; 235 case DHCP_REQUEST: 236 b.bp_xid = bp_info->bp_xid; // Match what server sent 237 AddOption(p,dhcpCookie); 238 AddOption(p,dhcpRequest); 239 AddOption(p,dhcpRequestIP); 240 memcpy(p, &bp_info->bp_yiaddr, 4); p += 4; // Ask for the address just given 241 AddOption(p,dhcpParamRequestList); 242 AddOption(p,dhcpEnd); 243 dhcpState = DHCP_REQUEST; 244 memset(&b.bp_yiaddr, 0xFF, 4); 245 memset(&b.bp_siaddr, 0xFF, 4); 246 memset(&b.bp_yiaddr, 0x00, 4); 247 memset(&b.bp_siaddr, 0x00, 4); 248 break; 249 case DHCP_ACK: 250 // Ignore these states (they won't happen) 251 break; 252 } 253 254 // Some servers insist on a minimum amount of "vendor" data 255 if (p < &b.bp_vend[BP_MIN_VEND_SIZE]) p = &b.bp_vend[BP_MIN_VEND_SIZE]; 256 txSize = p - (unsigned char*)&b; 257 oldState = dhcpState; 170 udp_socket_t udp_skt; 171 bootp_header_t b; 172 ip_route_t r; 173 int retry; 174 unsigned long start; 175 ip_addr_t saved_ip_addr; 176 #ifdef CYGSEM_REDBOOT_NETWORKING_DHCP 177 unsigned char *p; 178 int oldState; 179 #endif 180 int txSize; 181 bool abort = false; 182 static int xid = SHOULD_BE_RANDOM; 183 184 #ifdef CYGSEM_REDBOOT_NETWORKING_DHCP 185 dhcpState = DHCP_NONE; 186 #endif 187 188 // Where we want the results saved 189 bp_info = info; 190 // Preserve any IP address we currently have, just in case 191 memcpy(saved_ip_addr, __local_ip_addr, sizeof(__local_ip_addr)); 192 193 // fill out route for a broadcast 194 r.ip_addr[0] = 255; 195 r.ip_addr[1] = 255; 196 r.ip_addr[2] = 255; 197 r.ip_addr[3] = 255; 198 r.enet_addr[0] = 255; 199 r.enet_addr[1] = 255; 200 r.enet_addr[2] = 255; 201 r.enet_addr[3] = 255; 202 r.enet_addr[4] = 255; 203 r.enet_addr[5] = 255; 204 205 // setup a socket listener for bootp replies 206 __udp_install_listener(&udp_skt, IPPORT_BOOTPC, bootp_handler); 207 208 retry = MAX_RETRIES; 209 while (!abort && (retry-- > 0)) { 210 start = MS_TICKS(); 211 212 // Build up the BOOTP/DHCP request 213 memset(&b, 0, sizeof(b)); 214 b.bp_op = BOOTREQUEST; 215 b.bp_htype = HTYPE_ETHERNET; 216 b.bp_hlen = 6; 217 b.bp_xid = xid++; 218 memcpy(b.bp_chaddr, __local_enet_addr, 6); 219 memset(__local_ip_addr, 0, sizeof(__local_ip_addr)); 220 221 #ifdef CYGSEM_REDBOOT_NETWORKING_DHCP 222 p = b.bp_vend; 223 switch (dhcpState) { 224 case DHCP_NONE: 225 case DHCP_DISCOVER: 226 AddOption(p, dhcpCookie); 227 AddOption(p, dhcpDiscover); 228 AddOption(p, dhcpParamRequestList); 229 AddOption(p, dhcpEnd); 230 dhcpState = DHCP_DISCOVER; 231 break; 232 case DHCP_OFFER: 233 retry = MAX_RETRIES; 234 case DHCP_REQUEST: 235 b.bp_xid = bp_info->bp_xid; // Match what server sent 236 AddOption(p, dhcpCookie); 237 AddOption(p, dhcpRequest); 238 AddOption(p, dhcpRequestIP); 239 memcpy(p, &bp_info->bp_yiaddr, 4); 240 p += 4; // Ask for the address just given 241 AddOption(p, dhcpParamRequestList); 242 AddOption(p, dhcpEnd); 243 dhcpState = DHCP_REQUEST; 244 memset(&b.bp_yiaddr, 0xFF, 4); 245 memset(&b.bp_siaddr, 0xFF, 4); 246 memset(&b.bp_yiaddr, 0x00, 4); 247 memset(&b.bp_siaddr, 0x00, 4); 248 break; 249 case DHCP_ACK: 250 // Ignore these states (they won't happen) 251 break; 252 } 253 254 // Some servers insist on a minimum amount of "vendor" data 255 if (p < &b.bp_vend[BP_MIN_VEND_SIZE]) 256 p = &b.bp_vend[BP_MIN_VEND_SIZE]; 257 txSize = p - (unsigned char *)&b; 258 oldState = dhcpState; 258 259 #else 259 txSize = sizeof(b); 260 #endif 261 262 __udp_send((char *)&b, txSize, &r, IPPORT_BOOTPS, IPPORT_BOOTPC); 263 264 do { 265 __enet_poll(); 266 #ifdef CYGSEM_REDBOOT_NETWORKING_DHCP 267 if (dhcpState != oldState) { 268 if (dhcpState == DHCP_ACK) { 269 unsigned char *end; 270 int optlen; 271 // Address information has now arrived! 272 memcpy(__local_ip_addr, &bp_info->bp_yiaddr, 4); 260 txSize = sizeof(b); 261 #endif 262 263 __udp_send((char *)&b, txSize, &r, IPPORT_BOOTPS, 264 IPPORT_BOOTPC); 265 266 do { 267 __enet_poll(); 268 #ifdef CYGSEM_REDBOOT_NETWORKING_DHCP 269 if (dhcpState != oldState) { 270 if (dhcpState == DHCP_ACK) { 271 unsigned char *end; 272 int optlen; 273 // Address information has now arrived! 274 memcpy(__local_ip_addr, 275 &bp_info->bp_yiaddr, 4); 273 276 #ifdef CYGSEM_REDBOOT_NETWORKING_USE_GATEWAY 274 memcpy(__local_ip_gate, &bp_info->bp_giaddr, 4); 275 #endif 276 p = bp_info->bp_vend+4; 277 end = (unsigned char *)bp_info+sizeof(*bp_info); 278 while (p < end) { 279 unsigned char tag = *p; 280 if (tag == TAG_END) 281 break; 282 if (tag == TAG_PAD) 283 optlen = 1; 284 else { 285 optlen = p[1]; 286 p += 2; 287 switch (tag) { 277 memcpy(__local_ip_gate, 278 &bp_info->bp_giaddr, 4); 279 #endif 280 p = bp_info->bp_vend + 4; 281 end = 282 (unsigned char *)bp_info + 283 sizeof(*bp_info); 284 while (p < end) { 285 unsigned char tag = *p; 286 if (tag == TAG_END) 287 break; 288 if (tag == TAG_PAD) 289 optlen = 1; 290 else { 291 optlen = p[1]; 292 p += 2; 293 switch (tag) { 288 294 #ifdef CYGSEM_REDBOOT_NETWORKING_USE_GATEWAY 289 case TAG_SUBNET_MASK: // subnet mask 290 memcpy(__local_ip_mask,p,4); 291 break; 292 case TAG_GATEWAY: // router 293 memcpy(__local_ip_gate,p,4); 294 break; 295 case TAG_SUBNET_MASK: // subnet mask 296 memcpy 297 (__local_ip_mask, 298 p, 4); 299 break; 300 case TAG_GATEWAY: // router 301 memcpy 302 (__local_ip_gate, 303 p, 4); 304 break; 295 305 #endif 296 306 #ifdef CYGPKG_REDBOOT_NETWORKING_DNS 297 case TAG_DOMAIN_SERVER: 298 // diag_printf(" DNS server found!\n"); 299 memcpy(&__bootp_dns_addr, p, 4); 300 __bootp_dns_set = 1; 307 case TAG_DOMAIN_SERVER: 308 // diag_printf(" DNS server found!\n"); 309 memcpy 310 (&__bootp_dns_addr, 311 p, 4); 312 __bootp_dns_set 313 = 1; 314 break; 315 #endif 316 default: 317 break; 318 } 319 } 320 p += optlen; 321 } 322 __udp_remove_listener(IPPORT_BOOTPC); 323 return 0; 324 } else { 325 break; // State changed, handle it 326 } 327 } 328 #else 329 // All done, if address response has arrived 330 if (__local_ip_addr[0] || __local_ip_addr[1] || 331 __local_ip_addr[2] || __local_ip_addr[3]) { 332 /* success */ 333 __udp_remove_listener(IPPORT_BOOTPC); 334 return 0; 335 } 336 #endif 337 if (_rb_break(1)) { 338 // The user typed ^C on the console 339 abort = true; 301 340 break; 302 #endif 303 default: 304 break; 305 } 306 } 307 p += optlen; 308 } 309 __udp_remove_listener(IPPORT_BOOTPC); 310 return 0; 311 } else { 312 break; // State changed, handle it 313 } 314 } 315 #else 316 // All done, if address response has arrived 317 if (__local_ip_addr[0] || __local_ip_addr[1] || 318 __local_ip_addr[2] || __local_ip_addr[3]) { 319 /* success */ 320 __udp_remove_listener(IPPORT_BOOTPC); 321 return 0; 322 } 323 #endif 324 if (_rb_break(1)) { 325 // The user typed ^C on the console 326 abort = true; 327 break; 328 } 329 MS_TICKS_DELAY(); // Count for ^C test 330 } while ((MS_TICKS_DELAY() - start) < RETRY_TIME); 331 332 // Warn the user that we're polling for BOOTP info 333 if (retry == (MAX_RETRIES-1)) { 334 diag_printf("... waiting for BOOTP information\n"); 335 } 336 } 337 338 // timed out 339 __udp_remove_listener(IPPORT_BOOTPC); 340 // Restore any previous IP address 341 memcpy(__local_ip_addr, saved_ip_addr, sizeof(__local_ip_addr)); 342 return -1; 341 } 342 MS_TICKS_DELAY(); // Count for ^C test 343 } while ((MS_TICKS_DELAY() - start) < RETRY_TIME); 344 345 // Warn the user that we're polling for BOOTP info 346 if (retry == (MAX_RETRIES - 1)) { 347 diag_printf("... waiting for BOOTP information\n"); 348 } 349 } 350 351 // timed out 352 __udp_remove_listener(IPPORT_BOOTPC); 353 // Restore any previous IP address 354 memcpy(__local_ip_addr, saved_ip_addr, sizeof(__local_ip_addr)); 355 return -1; 343 356 } 344 345 ar5315_microredboot/microredboot/ecos/packages/redboot/current/src/net/cksum.c
r12281 r12368 60 60 * The returned checksum is in network byte order. 61 61 */ 62 unsigned short 63 __sum(word *w, int len, int init_sum) 62 unsigned short __sum(word * w, int len, int init_sum) 64 63 { 65 int sum = init_sum;64 int sum = init_sum; 66 65 67 union {68 volatile unsigned char c[2];69 volatile unsigned short s;70 } su;66 union { 67 volatile unsigned char c[2]; 68 volatile unsigned short s; 69 } su; 71 70 72 union {73 volatile unsigned short s[2];74 volatile int i;75 } iu;71 union { 72 volatile unsigned short s[2]; 73 volatile int i; 74 } iu; 76 75 77 while ((len -= 2) >= 0)78 sum += *w++;76 while ((len -= 2) >= 0) 77 sum += *w++; 79 78 80 if (len == -1) {81 su.c[0] = *(char *)w;82 su.c[1] = 0;83 sum += su.s;84 }79 if (len == -1) { 80 su.c[0] = *(char *)w; 81 su.c[1] = 0; 82 sum += su.s; 83 } 85 84 86 iu.i = sum;87 sum = iu.s[0] + iu.s[1];88 if (sum > 65535)89 sum -= 65535;85 iu.i = sum; 86 sum = iu.s[0] + iu.s[1]; 87 if (sum > 65535) 88 sum -= 65535; 90 89 91 su.s = ~sum;90 su.s = ~sum; 92 91 93 return (su.c[0] << 8) | su.c[1];92 return (su.c[0] << 8) | su.c[1]; 94 93 } 95 96 94 97 95 /* 98 96 * Compute a partial checksum for the UDP/TCP pseudo header. 99 97 */ 100 int 101 __pseudo_sum(ip_header_t *ip) 98 int __pseudo_sum(ip_header_t * ip) 102 99 { 103 intsum;104 word*p;100 int sum; 101 word *p; 105 102 106 union { 107 volatile unsigned char c[2]; 108 volatile unsigned short s; 109 } su; 110 111 p = (word *)ip->source; 112 sum = *p++; 113 sum += *p++; 114 sum += *p++; 115 sum += *p++; 116 117 su.c[0] = 0; 118 su.c[1] = ip->protocol; 119 sum += su.s; 103 union { 104 volatile unsigned char c[2]; 105 volatile unsigned short s; 106 } su; 120 107 121 sum += ip->length; 122 123 return sum; 108 p = (word *) ip->source; 109 sum = *p++; 110 sum += *p++; 111 sum += *p++; 112 sum += *p++; 113 114 su.c[0] = 0; 115 su.c[1] = ip->protocol; 116 sum += su.s; 117 118 sum += ip->length; 119 120 return sum; 124 121 } ar5315_microredboot/microredboot/ecos/packages/redboot/current/src/net/dns.c
r12281 r12368 58 58 #include <cyg/hal/drv_api.h> 59 59 #include <cyg/infra/cyg_type.h> 60 #include <cyg/infra/cyg_trac.h> /* Tracing support */60 #include <cyg/infra/cyg_trac.h> /* Tracing support */ 61 61 62 62 #include <net/net.h> … … 69 69 70 70 RedBoot_config_option("DNS server IP address", 71 dns_ip, 72 ALWAYS_ENABLED, true, 73 CONFIG_IP, 74 0 75 ); 71 dns_ip, ALWAYS_ENABLED, true, CONFIG_IP, 0); 76 72 #endif 77 73 … … 92 88 /* static buffers so we can make do without malloc */ 93 89 static struct hostent _hent; 94 static char *_h_addr_list[2];90 static char *_h_addr_list[2]; 95 91 static struct in_addr _h_addr_list0; 96 92 static int _hent_alloc = 0; … … 102 98 103 99 /* as in dns.c proper */ 104 static short id = 0; /* ID of the last query */ 105 static int s = -1; /* Socket to the DNS server */ 106 static cyg_drv_mutex_t dns_mutex; /* Mutex to stop multiple queries as once */ 107 static char * domainname=NULL; /* Domain name used for queries */ 108 100 static short id = 0; /* ID of the last query */ 101 static int s = -1; /* Socket to the DNS server */ 102 static cyg_drv_mutex_t dns_mutex; /* Mutex to stop multiple queries as once */ 103 static char *domainname = NULL; /* Domain name used for queries */ 109 104 110 105 /* Allocate space for string of length (len). Return NULL on 111 106 failure. */ 112 static char* 113 alloc_string(int len) 114 { 115 int i; 116 117 if (len > _STRING_LENGTH) 118 return NULL; 119 120 for (i = 0; i < _STRING_COUNT; i++) { 121 if (_strings_alloc & (1 << i)) continue; 122 _strings_alloc |= (1<<i); 123 return _strings[i]; 124 } 125 return NULL; 126 } 127 128 static void 129 free_string(char* s) 130 { 131 int i; 132 for (i = 0; i < _STRING_COUNT; i++) { 133 if (_strings[i] == s) { 134 _strings_alloc &= ~(1<<i); 135 break; 136 } 137 } 107 static char *alloc_string(int len) 108 { 109 int i; 110 111 if (len > _STRING_LENGTH) 112 return NULL; 113 114 for (i = 0; i < _STRING_COUNT; i++) { 115 if (_strings_alloc & (1 << i)) 116 continue; 117 _strings_alloc |= (1 << i); 118 return _strings[i]; 119 } 120 return NULL; 121 } 122 123 static void free_string(char *s) 124 { 125 int i; 126 for (i = 0; i < _STRING_COUNT; i++) { 127 if (_strings[i] == s) { 128 _strings_alloc &= ~(1 << i); 129 break; 130 } 131 } 138 132 } 139 133 140 134 /* Deallocate the memory taken to hold a hent structure */ 141 static void 142 free_hent(struct hostent * hent) 143 { 144 if (hent->h_name) { 145 free_string(hent->h_name); 146 } 147 _hent_alloc = 0; 135 static void free_hent(struct hostent *hent) 136 { 137 if (hent->h_name) { 138 free_string(hent->h_name); 139 } 140 _hent_alloc = 0; 148 141 } 149 142 150 143 /* Allocate hent structure with room for one in_addr. Returns NULL on 151 144 failure. */ 152 static struct hostent* 153 alloc_hent(void) 154 { 155 struct hostent *hent; 156 157 if (_hent_alloc) return NULL; 158 159 hent = &_hent; 160 memset(hent, 0, sizeof(struct hostent)); 161 hent->h_addr_list = _h_addr_list; 162 hent->h_addr_list[0] = (char*)&_h_addr_list0; 163 hent->h_addr_list[1] = NULL; 164 _hent_alloc = 1; 165 166 return hent; 167 } 168 169 static __inline__ void 170 free_stored_hent(void) 171 { 172 free_hent( &_hent ); 173 } 174 175 static __inline__ void 176 store_hent(struct hostent *hent) 177 { 178 hent=hent; // avoid warning 145 static struct hostent *alloc_hent(void) 146 { 147 struct hostent *hent; 148 149 if (_hent_alloc) 150 return NULL; 151 152 hent = &_hent; 153 memset(hent, 0, sizeof(struct hostent)); 154 hent->h_addr_list = _h_addr_list; 155 hent->h_addr_list[0] = (char *)&_h_addr_list0; 156 hent->h_addr_list[1] = NULL; 157 _hent_alloc = 1; 158 159 return hent; 160 } 161 162 static __inline__ void free_stored_hent(void) 163 { 164 free_hent(&_hent); 165 } 166 167 static __inline__ void store_hent(struct hostent *hent) 168 { 169 hent = hent; // avoid warning 179 170 } 180 171 … … 182 173 if it fails, otherwise put the response back in msg and return the 183 174 length of the response. */ 184 static int 185 send_recv(char * msg, int len, int msglen) 186 { 187 struct dns_header *dns_hdr; 188 int finished = false; 189 int read = 0; 190 191 dns_hdr = (struct dns_header *) msg; 192 193 do { 194 int len_togo = len; 195 struct timeval timeout; 196 struct sockaddr_in local_addr, from_addr; 197 198 memset((char *)&local_addr, 0, sizeof(local_addr)); 199 local_addr.sin_family = AF_INET; 200 local_addr.sin_addr.s_addr = htonl(INADDR_ANY); 201 local_addr.sin_port = htons(get_port++); 202 203 if (__udp_sendto(msg, len_togo, &server, &local_addr) < 0) 204 return -1; 205 206 memset((char *)&from_addr, 0, sizeof(from_addr)); 207 208 timeout.tv_sec = CYGNUM_REDBOOT_NETWORKING_DNS_TIMEOUT; 209 timeout.tv_usec = 0; 210 211 read = __udp_recvfrom(msg, len, &from_addr, &local_addr, &timeout); 212 if (read < 0) 213 return -1; 214 215 /* Reply to an old query. Ignore it */ 216 if (ntohs(dns_hdr->id) != (id-1)) { 217 continue; 218 } 219 finished = true; 220 } while (!finished); 221 222 return read; 223 } 224 225 void 226 set_dns(char* new_ip) 227 { 228 in_addr_t dns_ip; 229 230 memset(&server.sin_addr, 0, sizeof(server.sin_addr)); 231 if (!inet_aton(new_ip, &dns_ip)) { 232 diag_printf("Bad DNS server address: %s\n", new_ip); 233 } else { 234 memcpy(&server.sin_addr, &dns_ip, sizeof(dns_ip)); 235 /* server config is valid */ 236 s = 0; 237 } 238 } 239 240 void 241 show_dns(void) 242 { 243 diag_printf(", DNS server IP: %s", inet_ntoa((in_addr_t *)&server.sin_addr)); 244 if (0 == server.sin_addr.s_addr) { 245 s = -1; 246 } 175 static int send_recv(char *msg, int len, int msglen) 176 { 177 struct dns_header *dns_hdr; 178 int finished = false; 179 int read = 0; 180 181 dns_hdr = (struct dns_header *)msg; 182 183 do { 184 int len_togo = len; 185 struct timeval timeout; 186 struct sockaddr_in local_addr, from_addr; 187 188 memset((char *)&local_addr, 0, sizeof(local_addr)); 189 local_addr.sin_family = AF_INET; 190 local_addr.sin_addr.s_addr = htonl(INADDR_ANY); 191 local_addr.sin_port = htons(get_port++); 192 193 if (__udp_sendto(msg, len_togo, &server, &local_addr) < 0) 194 return -1; 195 196 memset((char *)&from_addr, 0, sizeof(from_addr)); 197 198 timeout.tv_sec = CYGNUM_REDBOOT_NETWORKING_DNS_TIMEOUT; 199 timeout.tv_usec = 0; 200 201 read = 202 __udp_recvfrom(msg, len, &from_addr, &local_addr, &timeout); 203 if (read < 0) 204 return -1; 205 206 /* Reply to an old query. Ignore it */ 207 if (ntohs(dns_hdr->id) != (id - 1)) { 208 continue; 209 } 210 finished = true; 211 } while (!finished); 212 213 return read; 214 } 215 216 void set_dns(char *new_ip) 217 { 218 in_addr_t dns_ip; 219 220 memset(&server.sin_addr, 0, sizeof(server.sin_addr)); 221 if (!inet_aton(new_ip, &dns_ip)) { 222 diag_printf("Bad DNS server address: %s\n", new_ip); 223 } else { 224 memcpy(&server.sin_addr, &dns_ip, sizeof(dns_ip)); 225 /* server config is valid */ 226 s = 0; 227 } 228 } 229 230 void show_dns(void) 231 { 232 diag_printf(", DNS server IP: %s", 233 inet_ntoa((in_addr_t *) & server.sin_addr)); 234 if (0 == server.sin_addr.s_addr) { 235 s = -1; 236 } 247 237 } 248 238 249 239 /* Initialise the resolver. Open a socket and bind it to the address 250 240 of the server. return -1 if something goes wrong, otherwise 0 */ 251 int 252 redboot_dns_res_init(void) 253 { 254 memset((char *)&server, 0, sizeof(server)); 255 server.sin_len = sizeof(server); 256 server.sin_family = AF_INET; 257 server.sin_port = htons(DOMAIN_PORT); 258 cyg_drv_mutex_init(&dns_mutex); 259 260 /* If we got a DNS server address from the DHCP/BOOTP, then use that address */ 261 if ( __bootp_dns_set ) { 262 memcpy(&server.sin_addr, &__bootp_dns_addr, sizeof(__bootp_dns_addr) ); 263 s = 0; 264 } 265 else { 241 int redboot_dns_res_init(void) 242 { 243 memset((char *)&server, 0, sizeof(server)); 244 server.sin_len = sizeof(server); 245 server.sin_family = AF_INET; 246 server.sin_port = htons(DOMAIN_PORT); 247 cyg_drv_mutex_init(&dns_mutex); 248 249 /* If we got a DNS server address from the DHCP/BOOTP, then use that address */ 250 if (__bootp_dns_set) { 251 memcpy(&server.sin_addr, &__bootp_dns_addr, 252 sizeof(__bootp_dns_addr)); 253 s = 0; 254 } else { 266 255 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG 267 { 268 ip_addr_t dns_ip; 269 270 flash_get_config("dns_ip", &dns_ip, CONFIG_IP); 271 if (dns_ip[0] == 0 && dns_ip[1] == 0 && dns_ip[2] == 0 && dns_ip[3] == 0) 272 return -1; 273 memcpy(&server.sin_addr, &dns_ip, sizeof(dns_ip)); 274 /* server config is valid */ 275 s = 0; 276 } 256 { 257 ip_addr_t dns_ip; 258 259 flash_get_config("dns_ip", &dns_ip, CONFIG_IP); 260 if (dns_ip[0] == 0 && dns_ip[1] == 0 && dns_ip[2] == 0 261 && dns_ip[3] == 0) 262 return -1; 263 memcpy(&server.sin_addr, &dns_ip, sizeof(dns_ip)); 264 /* server config is valid */ 265 s = 0; 266 } 277 267 #else 278 // Use static configuration279 set_dns(__Xstr(CYGPKG_REDBOOT_NETWORKING_DNS_IP));268 // Use static configuration 269 set_dns(__Xstr(CYGPKG_REDBOOT_NETWORKING_DNS_IP)); 280 270 #endif 281 }282 283 return 0;271 } 272 273 return 0; 284 274 } 285 275 ar5315_microredboot/microredboot/ecos/packages/redboot/current/src/net/enet.c
r12281 r12368 55 55 #include <redboot.h> 56 56 #include <net/net.h> 57 #include <cyg/io/eth/eth_drv.h> // Logical driver interfaces57 #include <cyg/io/eth/eth_drv.h> // Logical driver interfaces 58 58 59 59 //#define ENET_STATS 1 … … 75 75 #define NUM_EXTRA_HANDLERS 4 76 76 static struct { 77 int type;78 pkt_handler_t handler;77 int type; 78 pkt_handler_t handler; 79 79 } eth_handlers[NUM_EXTRA_HANDLERS]; 80 80 81 pkt_handler_t 82 __eth_install_listener(int eth_type, pkt_handler_t handler) 83 { 84 int i, empty; 85 pkt_handler_t old; 86 87 if (eth_type > 0x800 || handler != (pkt_handler_t)0) { 88 empty = -1; 89 for (i = 0; i < NUM_EXTRA_HANDLERS; i++) { 90 if (eth_handlers[i].type == eth_type) { 91 // Replace existing handler 92 old = eth_handlers[i].handler; 93 eth_handlers[i].handler = handler; 94 return old; 95 } 96 if (eth_handlers[i].type == 0) { 97 empty = i; 98 } 81 pkt_handler_t __eth_install_listener(int eth_type, pkt_handler_t handler) 82 { 83 int i, empty; 84 pkt_handler_t old; 85 86 if (eth_type > 0x800 || handler != (pkt_handler_t) 0) { 87 empty = -1; 88 for (i = 0; i < NUM_EXTRA_HANDLERS; i++) { 89 if (eth_handlers[i].type == eth_type) { 90 // Replace existing handler 91 old = eth_handlers[i].handler; 92 eth_handlers[i].handler = handler; 93 return old; 94 } 95 if (eth_handlers[i].type == 0) { 96 empty = i; 97 } 98 } 99 if (empty >= 0) { 100 // Found a free slot 101 eth_handlers[empty].type = eth_type; 102 eth_handlers[empty].handler = handler; 103 return (pkt_handler_t) 0; 104 } 99 105 } 100 if (empty >= 0) { 101 // Found a free slot 102 eth_handlers[empty].type = eth_type; 103 eth_handlers[empty].handler = handler; 104 return (pkt_handler_t)0; 106 diag_printf 107 ("** Warning: can't install listener for ethernet type 0x%02x\n", 108 eth_type); 109 return (pkt_handler_t) 0; 110 } 111 112 void __eth_remove_listener(int eth_type) 113 { 114 int i; 115 116 for (i = 0; i < NUM_EXTRA_HANDLERS; i++) { 117 if (eth_handlers[i].type == eth_type) { 118 eth_handlers[i].type = 0; 119 } 105 120 } 106 }107 diag_printf("** Warning: can't install listener for ethernet type 0x%02x\n", eth_type);108 return (pkt_handler_t)0;109 }110 111 void112 __eth_remove_listener(int eth_type)113 {114 int i;115 116 for (i = 0; i < NUM_EXTRA_HANDLERS; i++) {117 if (eth_handlers[i].type == eth_type) {118 eth_handlers[i].type = 0;119 }120 }121 121 } 122 122 … … 125 125 * are available. 126 126 */ 127 void 128 __enet_poll(void) 129 { 130 pktbuf_t *pkt; 131 eth_header_t eth_hdr; 132 int i, type; 127 void __enet_poll(void) 128 { 129 pktbuf_t *pkt; 130 eth_header_t eth_hdr; 131 int i, type; 133 132 #ifdef DEBUG_PKT_EXHAUSTION 134 static bool was_exhausted = false;135 #endif 136 137 while (true) {138 /*139 * Try to get a free pktbuf and return if none140 * are available.141 */142 if ((pkt = __pktbuf_alloc(ETH_MAX_PKTLEN)) == NULL) {133 static bool was_exhausted = false; 134 #endif 135 136 while (true) { 137 /* 138 * Try to get a free pktbuf and return if none 139 * are available. 140 */ 141 if ((pkt = __pktbuf_alloc(ETH_MAX_PKTLEN)) == NULL) { 143 142 #ifdef DEBUG_PKT_EXHAUSTION 144 if (!was_exhausted) {145 int old = start_console();// Force output to standard port146 diag_printf("__enet_poll: no more buffers\n");147 __pktbuf_dump();148 was_exhausted = true;149 end_console(old);150 } 151 #endif 152 return;153 }143 if (!was_exhausted) { 144 int old = start_console(); // Force output to standard port 145 diag_printf("__enet_poll: no more buffers\n"); 146 __pktbuf_dump(); 147 was_exhausted = true; 148 end_console(old); 149 } 150 #endif 151 return; 152 } 154 153 #ifdef DEBUG_PKT_EXHAUSTION 155 was_exhausted = false; // Report the next time we're out of buffers 156 #endif 157 158 if ((pkt->pkt_bytes = eth_drv_read((char *)ð_hdr, (char *)pkt->buf, 159 ETH_MAX_PKTLEN)) > 0) { 160 #ifdef ENET_STATS 161 ++num_received; 162 #endif 163 switch (type = ntohs(eth_hdr.type)) { 164 165 case ETH_TYPE_IP: 166 #ifdef ENET_STATS 167 ++num_ip; 168 #endif 169 pkt->ip_hdr = (ip_header_t *)pkt->buf; 170 __ip_handler(pkt, ð_hdr.source); 171 break; 172 173 case ETH_TYPE_ARP: 174 #ifdef ENET_STATS 175 ++num_arp; 176 #endif 177 pkt->arp_hdr = (arp_header_t *)pkt->buf; 178 __arp_handler(pkt); 179 break; 154 was_exhausted = false; // Report the next time we're out of buffers 155 #endif 156 157 if ((pkt->pkt_bytes = 158 eth_drv_read((char *)ð_hdr, (char *)pkt->buf, 159 ETH_MAX_PKTLEN)) > 0) { 160 #ifdef ENET_STATS 161 ++num_received; 162 #endif 163 switch (type = ntohs(eth_hdr.type)) { 164 165 case ETH_TYPE_IP: 166 #ifdef ENET_STATS 167 ++num_ip; 168 #endif 169 pkt->ip_hdr = (ip_header_t *) pkt->buf; 170 __ip_handler(pkt, ð_hdr.source); 171 break; 172 173 case ETH_TYPE_ARP: 174 #ifdef ENET_STATS 175 ++num_arp; 176 #endif 177 pkt->arp_hdr = (arp_header_t *) pkt->buf; 178 __arp_handler(pkt); 179 break; 180 180 181 181 #ifdef NET_SUPPORT_RARP 182 case ETH_TYPE_RARP: 183 #ifdef ENET_STATS 184 ++num_rarp; 185 #endif 186 pkt->arp_hdr = (arp_header_t *)pkt->buf; 187 __rarp_handler(pkt); 188 break; 189 #endif 190 191 default: 192 if (type > 0x800) { 193 for (i = 0; i < NUM_EXTRA_HANDLERS; i++) { 194 if (eth_handlers[i].type == type) { 195 (eth_handlers[i].handler)(pkt, ð_hdr); 196 } 197 } 198 } 199 __pktbuf_free(pkt); 200 break; 201 } 202 } else { 203 __pktbuf_free(pkt); 204 break; 205 } 206 } 207 } 208 209 182 case ETH_TYPE_RARP: 183 #ifdef ENET_STATS 184 ++num_rarp; 185 #endif 186 pkt->arp_hdr = (arp_header_t *) pkt->buf; 187 __rarp_handler(pkt); 188 break; 189 #endif 190 191 default: 192 if (type > 0x800) { 193 for (i = 0; i < NUM_EXTRA_HANDLERS; i++) { 194 if (eth_handlers[i].type == 195 type) { 196 (eth_handlers 197 [i].handler) (pkt, 198 ð_hdr); 199 } 200 } 201 } 202 __pktbuf_free(pkt); 203 break; 204 } 205 } else { 206 __pktbuf_free(pkt); 207 break; 208 } 209 } 210 } 210 211 211 212 /* 212 213 * Send an ethernet packet. 213 214 */ 214 void 215 __enet_send(pktbuf_t *pkt, enet_addr_t *dest, int eth_type) 216 { 217 eth_header_t eth_hdr; 218 219 // Set up ethernet header 220 memcpy(ð_hdr.destination, dest, sizeof(enet_addr_t)); 221 memcpy(ð_hdr.source, __local_enet_addr, sizeof(enet_addr_t)); 222 eth_hdr.type = htons(eth_type); 223 224 eth_drv_write((char *)ð_hdr, (char *)pkt->buf, pkt->pkt_bytes); 225 #ifdef ENET_STATS 226 ++num_transmitted; 215 void __enet_send(pktbuf_t * pkt, enet_addr_t * dest, int eth_type) 216 { 217 eth_header_t eth_hdr; 218 219 // Set up ethernet header 220 memcpy(ð_hdr.destination, dest, sizeof(enet_addr_t)); 221 memcpy(ð_hdr.source, __local_enet_addr, sizeof(enet_addr_t)); 222 eth_hdr.type = htons(eth_type); 223 224 eth_drv_write((char *)ð_hdr, (char *)pkt->buf, pkt->pkt_bytes); 225 #ifdef ENET_STATS 226 ++num_transmitted; 227 227 #endif 228 228 } … … 230 230 #ifdef __LITTLE_ENDIAN__ 231 231 232 unsigned long 233 ntohl(unsigned long x) 234 { 235 return (((x & 0x000000FF) << 24) | 236 ((x & 0x0000FF00) << 8) | 237 ((x & 0x00FF0000) >> 8) | 238 ((x & 0xFF000000) >> 24)); 239 } 240 241 unsigned long 242 ntohs(unsigned short x) 243 { 244 return (((x & 0x00FF) << 8) | 245 ((x & 0xFF00) >> 8)); 246 } 247 248 #endif 232 unsigned long ntohl(unsigned long x) 233 { 234 return (((x & 0x000000FF) << 24) | 235 ((x & 0x0000FF00) << 8) | 236 ((x & 0x00FF0000) >> 8) | ((x & 0xFF000000) >> 24)); 237 } 238 239 unsigned long ntohs(unsigned short x) 240 { 241 return (((x & 0x00FF) << 8) | ((x & 0xFF00) >> 8)); 242 } 243 244 #endif ar5315_microredboot/microredboot/ecos/packages/redboot/current/src/net/http_client.c
r12281 r12368 56 56 // HTTP client support 57 57 58 #include <redboot.h> // have_net58 #include <redboot.h> // have_net 59 59 #include <net/net.h> 60 60 #include <net/http.h> … … 63 63 static int get_port = 7800; 64 64 65 static struct _stream {66 bool open;67 intavail, actual_len, pos, filelen;68 char data[4096];69 char *bufp;70 tcp_socket_t sock;65 static struct _stream { 66 bool open; 67 int avail, actual_len, pos, filelen; 68 char data[4096]; 69 char *bufp; 70 tcp_socket_t sock; 71 71 } http_stream; 72 72 73 static __inline__ int 74 min(int a, int b) 75 { 76 if (a < b) 77 return a; 78 else 79 return b; 80 } 81 82 int 83 http_stream_open(connection_info_t *info, int *err) 84 { 85 int res; 86 struct _stream *s = &http_stream; 87 88 if (!info->server->sin_port) 89 info->server->sin_port = 80; // HTTP port 90 if ((res = __tcp_open(&s->sock, info->server, get_port++, 5000, err)) < 0) { 91 *err = HTTP_OPEN; 92 return -1; 93 } 94 diag_sprintf(s->data, "GET %s HTTP/1.0\r\n\r\n", info->filename); 95 __tcp_write_block(&s->sock, s->data, strlen(s->data)); 96 s->avail = 0; 97 s->open = true; 98 s->pos = 0; 99 return 0; 100 } 101 102 void 103 http_stream_close(int *err) 104 { 105 struct _stream *s = &http_stream; 106 107 if (s->open) { 108 __tcp_abort(&s->sock,1); 109 s->open = false; 110 } 111 } 112 113 int 114 http_stream_read(char *buf, 115 int len, 116 int *err) 117 { 118 struct _stream *s = &http_stream; 119 int total = 0; 120 int cnt, code; 121 122 if (!s->open) { 123 return -1; // Shouldn't happen, but... 124 } 125 while (len) { 126 while (s->avail == 0) { 127 // Need to wait for some data to arrive 128 __tcp_poll(); 129 if (s->sock.state != _ESTABLISHED) { 130 if (s->sock.state == _CLOSE_WAIT) { 131 // This connection is breaking 132 if (s->sock.data_bytes == 0 && s->sock.rxcnt == 0) { 133 __tcp_close(&s->sock); 134 return total; 135 } 136 } else if (s->sock.state == _CLOSED) { 137 // The connection is gone 138 s->open = false; 139 return -1; 140 } else { 141 *err = HTTP_IO; 142 return -1; 73 static __inline__ int min(int a, int b) 74 { 75 if (a < b) 76 return a; 77 else 78 return b; 79 } 80 81 int http_stream_open(connection_info_t * info, int *err) 82 { 83 int res; 84 struct _stream *s = &http_stream; 85 86 if (!info->server->sin_port) 87 info->server->sin_port = 80; // HTTP port 88 if ((res = 89 __tcp_open(&s->sock, info->server, get_port++, 5000, err)) < 0) { 90 *err = HTTP_OPEN; 91 return -1; 92 } 93 diag_sprintf(s->data, "GET %s HTTP/1.0\r\n\r\n", info->filename); 94 __tcp_write_block(&s->sock, s->data, strlen(s->data)); 95 s->avail = 0; 96 s->open = true; 97 s->pos = 0; 98 return 0; 99 } 100 101 void http_stream_close(int *err) 102 { 103 struct _stream *s = &http_stream; 104 105 if (s->open) { 106 __tcp_abort(&s->sock, 1); 107 s->open = false; 108 } 109 } 110 111 int http_stream_read(char *buf, int len, int *err) 112 { 113 struct _stream *s = &http_stream; 114 int total = 0; 115 int cnt, code; 116 117 if (!s->open) { 118 return -1; // Shouldn't happen, but... 119 } 120 while (len) { 121 while (s->avail == 0) { 122 // Need to wait for some data to arrive 123 __tcp_poll(); 124 if (s->sock.state != _ESTABLISHED) { 125 if (s->sock.state == _CLOSE_WAIT) { 126 // This connection is breaking 127 if (s->sock.data_bytes == 0 128 && s->sock.rxcnt == 0) { 129 __tcp_close(&s->sock); 130 return total; 131 } 132 } else if (s->sock.state == _CLOSED) { 133 // The connection is gone 134 s->open = false; 135 return -1; 136 } else { 137 *err = HTTP_IO; 138 return -1; 139 } 140 } 141 s->actual_len = 142 __tcp_read(&s->sock, s->data, sizeof(s->data)); 143 if (s->actual_len > 0) { 144 s->bufp = s->data; 145 s->avail = s->actual_len; 146 if (s->pos == 0) { 147 // First data - need to scan HTTP response header 148 if (strncmp(s->bufp, "HTTP/", 5) == 0) { 149 // Should look like "HTTP/1.1 200 OK" 150 s->bufp += 5; 151 s->avail -= 5; 152 // Find first space 153 while ((s->avail > 0) 154 && (*s->bufp != ' ')) { 155 s->bufp++; 156 s->avail--; 157 } 158 // Now the integer response 159 code = 0; 160 while ((s->avail > 0) 161 && (*s->bufp == ' ')) { 162 s->bufp++; 163 s->avail--; 164 } 165 while ((s->avail > 0) 166 && isdigit(*s->bufp)) { 167 code = 168 (code * 10) + 169 (*s->bufp - '0'); 170 s->bufp++; 171 s->avail--; 172 } 173 // Make sure it says OK 174 while ((s->avail > 0) 175 && (*s->bufp == ' ')) { 176 s->bufp++; 177 s->avail--; 178 } 179 if (strncmp(s->bufp, "OK", 2)) { 180 switch (code) { 181 case 400: 182 *err = 183 HTTP_BADREQ; 184 break; 185 case 404: 186 *err = 187 HTTP_NOFILE; 188 break; 189 default: 190 *err = 191 HTTP_BADHDR; 192 break; 193 } 194 return -1; 195 } 196 // Find \r\n\r\n - end of HTTP preamble 197 while (s->avail >= 4) { 198 // This could be done faster, but not simpler 199 if (strncmp 200 (s->bufp, 201 "\r\n\r\n", 202 4) == 0) { 203 s->bufp += 4; 204 s->avail -= 4; 205 #if 0 // DEBUG - show header 206 *(s->bufp - 2) = 207 '\0'; 208 diag_printf 209 (s->data); 210 #endif 211 break; 212 } 213 s->avail--; 214 s->bufp++; 215 } 216 s->pos++; 217 } else { 218 // Unrecognized response 219 *err = HTTP_BADHDR; 220 return -1; 221 } 222 } 223 } else if (s->actual_len < 0) { 224 *err = HTTP_IO; 225 return -1; 226 } 143 227 } 144 } 145 s->actual_len = __tcp_read(&s->sock, s->data, sizeof(s->data)); 146 if (s->actual_len > 0) { 147 s->bufp = s->data; 148 s->avail = s->actual_len; 149 if (s->pos == 0) { 150 // First data - need to scan HTTP response header 151 if (strncmp(s->bufp, "HTTP/", 5) == 0) { 152 // Should look like "HTTP/1.1 200 OK" 153 s->bufp += 5; 154 s->avail -= 5; 155 // Find first space 156 while ((s->avail > 0) && (*s->bufp != ' ')) { 157 s->bufp++; 158 s->avail--; 159 } 160 // Now the integer response 161 code = 0; 162 while ((s->avail > 0) && (*s->bufp == ' ')) { 163 s->bufp++; 164 s->avail--; 165 } 166 while ((s->avail > 0) && isdigit(*s->bufp)) { 167 code = (code * 10) + (*s->bufp - '0'); 168 s->bufp++; 169 s->avail--; 170 } 171 // Make sure it says OK 172 while ((s->avail > 0) && (*s->bufp == ' ')) { 173 s->bufp++; 174 s->avail--; 175 } 176 if (strncmp(s->bufp, "OK", 2)) { 177 switch (code) { 178 case 400: 179 *err = HTTP_BADREQ; 180 break; 181 case 404: 182 *err = HTTP_NOFILE; 183 break; 184 default: 185 *err = HTTP_BADHDR; 186 break; 187 } 188 return -1; 189 } 190 // Find \r\n\r\n - end of HTTP preamble 191 while (s->avail >= 4) { 192 // This could be done faster, but not simpler 193 if (strncmp(s->bufp, "\r\n\r\n", 4) == 0) { 194 s->bufp += 4; 195 s->avail -= 4; 196 #if 0 // DEBUG - show header 197 *(s->bufp-2) = '\0'; 198 diag_printf(s->data); 199 #endif 200 break; 201 } 202 s->avail--; 203 s->bufp++; 204 } 205 s->pos++; 206 } else { 207 // Unrecognized response 208 *err = HTTP_BADHDR; 209 return -1; 210 } 211 } 212 } else if (s->actual_len < 0) { 213 *err = HTTP_IO; 214 return -1; 215 } 216 } 217 cnt = min(len, s->avail); 218 memcpy(buf, s->bufp, cnt); 219 s->avail -= cnt; 220 s->bufp += cnt; 221 buf += cnt; 222 total += cnt; 223 len -= cnt; 224 } 225 return total; 226 } 227 228 char * 229 http_error(int err) 230 { 231 char *errmsg = "Unknown error"; 232 233 switch (err) { 234 case HTTP_NOERR: 235 return ""; 236 case HTTP_BADHDR: 237 return "Unrecognized HTTP response"; 238 case HTTP_BADREQ: 239 return "Bad HTTP request (check file name)"; 240 case HTTP_NOFILE: 241 return "No such file"; 242 case HTTP_OPEN: 243 return "Can't connect to host"; 244 case HTTP_IO: 245 return "I/O error"; 246 } 247 return errmsg; 228 cnt = min(len, s->avail); 229 memcpy(buf, s->bufp, cnt); 230 s->avail -= cnt; 231 s->bufp += cnt; 232 buf += cnt; 233 total += cnt; 234 len -= cnt; 235 } 236 return total; 237 } 238 239 char *http_error(int err) 240 { 241 char *errmsg = "Unknown error"; 242 243 switch (err) { 244 case HTTP_NOERR: 245 return ""; 246 case HTTP_BADHDR: 247 return "Unrecognized HTTP response"; 248 case HTTP_BADREQ: 249 return "Bad HTTP request (check file name)"; 250 case HTTP_NOFILE: 251 return "No such file"; 252 case HTTP_OPEN: 253 return "Can't connect to host"; 254 case HTTP_IO: 255 return "I/O error"; 256 } 257 return errmsg; 248 258 } 249 259 … … 252 262 // 253 263 GETC_IO_FUNCS(http_io, http_stream_open, http_stream_close, 254 0, http_stream_read, http_error);264 0, http_stream_read, http_error); 255 265 RedBoot_load(http, http_io, true, true, 0); ar5315_microredboot/microredboot/ecos/packages/redboot/current/src/net/icmp.c
r12281 r12368 58 58 * Handle ICMP packets. 59 59 */ 60 static void default_icmp_handler(pktbuf_t * pkt, ip_route_t *dest);60 static void default_icmp_handler(pktbuf_t * pkt, ip_route_t * dest); 61 61 62 62 static icmp_handler_t icmp_handler = default_icmp_handler; … … 66 66 * Returns zero if successful, -1 if the user_handler is already used. 67 67 */ 68 int 69 __icmp_install_listener(icmp_handler_t user_handler) 68 int __icmp_install_listener(icmp_handler_t user_handler) 70 69 { 71 if (icmp_handler == user_handler) {72 return -1;73 }74 icmp_handler = user_handler;75 return 0;70 if (icmp_handler == user_handler) { 71 return -1; 72 } 73 icmp_handler = user_handler; 74 return 0; 76 75 } 77 78 76 79 77 /* 80 78 * Replace a user defined handler by the default handler. 81 79 */ 82 void 83 __icmp_remove_listener(void) 80 void __icmp_remove_listener(void) 84 81 { 85 if (icmp_handler != default_icmp_handler) {86 icmp_handler = default_icmp_handler;87 }82 if (icmp_handler != default_icmp_handler) { 83 icmp_handler = default_icmp_handler; 84 } 88 85 } 89 86 … … 92 89 * should be sent to. 93 90 */ 94 void 95 __icmp_handler(pktbuf_t *pkt, ip_route_t *dest) 91 void __icmp_handler(pktbuf_t * pkt, ip_route_t * dest) 96 92 { 97 (*icmp_handler)(pkt, dest);93 (*icmp_handler) (pkt, dest); 98 94 99 BSPLOG(bsp_log("icmp: dest[%s] type[%d] seq[%d]\n", 100 inet_ntoa(pkt->ip_hdr->destination), 101 pkt->icmp_hdr->type, 102 pkt->icmp_hdr->seqnum)); 103 __pktbuf_free(pkt); 95 BSPLOG(bsp_log("icmp: dest[%s] type[%d] seq[%d]\n", 96 inet_ntoa(pkt->ip_hdr->destination), 97 pkt->icmp_hdr->type, pkt->icmp_hdr->seqnum)); 98 __pktbuf_free(pkt); 104 99 } 105 106 100 107 101 /* … … 109 103 * outgoing echo reply. 110 104 */ 111 static void 112 default_icmp_handler(pktbuf_t *pkt, ip_route_t *dest) 105 static void default_icmp_handler(pktbuf_t * pkt, ip_route_t * dest) 113 106 { 114 word cksum;107 word cksum; 115 108 116 if (pkt->icmp_hdr->type == ICMP_TYPE_ECHOREQUEST117 && pkt->icmp_hdr->code == 0118 && __sum((word *)pkt->icmp_hdr, pkt->pkt_bytes, 0) == 0) {109 if (pkt->icmp_hdr->type == ICMP_TYPE_ECHOREQUEST 110 && pkt->icmp_hdr->code == 0 111 && __sum((word *) pkt->icmp_hdr, pkt->pkt_bytes, 0) == 0) { 119 112 120 pkt->icmp_hdr->type = ICMP_TYPE_ECHOREPLY;121 pkt->icmp_hdr->checksum = 0;122 cksum = __sum((word *)pkt->icmp_hdr, pkt->pkt_bytes, 0);123 pkt->icmp_hdr->checksum = htons(cksum);124 __ip_send(pkt, IP_PROTO_ICMP, dest);125 }113 pkt->icmp_hdr->type = ICMP_TYPE_ECHOREPLY; 114 pkt->icmp_hdr->checksum = 0; 115 cksum = __sum((word *) pkt->icmp_hdr, pkt->pkt_bytes, 0); 116 pkt->icmp_hdr->checksum = htons(cksum); 117 __ip_send(pkt, IP_PROTO_ICMP, dest); 118 } 126 119 } ar5315_microredboot/microredboot/ecos/packages/redboot/current/src/net/inet_addr.c
r12281 r12368 56 56 #include <net/net.h> 57 57 58 bool 59 inet_aton(const char *s, in_addr_t *addr) 58 bool inet_aton(const char *s, in_addr_t * addr) 60 59 { 61 int i, val, radix, digit;62 unsigned long res = 0;63 bool first;64 char c;65 66 for (i = 0; i < 4;i++) {67 // Parse next digit string68 first = true;69 val = 0;70 radix = 10;71 while ((c = *s++) != '\0') {72 if (first && (c == '0') && (_tolower(*s) == 'x')) {73 radix = 16;74 s++;// Skip over 0x75 c = *s++;76 }77 first = false;78 if (_is_hex(c) && ((digit = _from_hex(c)) < radix)) {79 // Valid digit80 val = (val * radix) + digit;81 } else if (c == '.' && i < 3) {// all but last terminate by '.'82 break;83 } else {84 return false;85 }86 }87 // merge result60 int i, val, radix, digit; 61 unsigned long res = 0; 62 bool first; 63 char c; 64 65 for (i = 0; i < 4; i++) { 66 // Parse next digit string 67 first = true; 68 val = 0; 69 radix = 10; 70 while ((c = *s++) != '\0') { 71 if (first && (c == '0') && (_tolower(*s) == 'x')) { 72 radix = 16; 73 s++; // Skip over 0x 74 c = *s++; 75 } 76 first = false; 77 if (_is_hex(c) && ((digit = _from_hex(c)) < radix)) { 78 // Valid digit 79 val = (val * radix) + digit; 80 } else if (c == '.' && i < 3) { // all but last terminate by '.' 81 break; 82 } else { 83 return false; 84 } 85 } 86 // merge result 88 87 #ifdef __LITTLE_ENDIAN__ 89 res |= val << ((3-i)*8);// 24, 16, 8, 088 res |= val << ((3 - i) * 8); // 24, 16, 8, 0 90 89 #else 91 res = (res << 8) | val;90 res = (res << 8) | val; 92 91 #endif 93 if ('\0' == c) { 94 if (0 == i) { // first field found end of string 95 res = val; // no shifting, use it as the whole thing 96 break; // permit entering a single number 97 } 98 if (3 > i) // we found end of string before getting 4 fields 99 return false; 100 } 101 // after that we check that it was 0..255 only 102 if (val &~0xff) return false; 103 } 104 addr->s_addr = htonl(res); 105 return true; 92 if ('\0' == c) { 93 if (0 == i) { // first field found end of string 94 res = val; // no shifting, use it as the whole thing 95 break; // permit entering a single number 96 } 97 if (3 > i) // we found end of string before getting 4 fields 98 return false; 99 } 100 // after that we check that it was 0..255 only 101 if (val & ~0xff) 102 return false; 103 } 104 addr->s_addr = htonl(res); 105 return true; 106 106 } 107 107 108 108 // Assumes address is in network byte order 109 char * 110 inet_ntoa(in_addr_t *addr) 109 char *inet_ntoa(in_addr_t * addr) 111 110 { 112 static char str[32];113 unsigned char *ap;111 static char str[32]; 112 unsigned char *ap; 114 113 115 ap = (unsigned char *)addr;116 diag_sprintf(str, "%d.%d.%d.%d", ap[0], ap[1], ap[2], ap[3]);117 return str;114 ap = (unsigned char *)addr; 115 diag_sprintf(str, "%d.%d.%d.%d", ap[0], ap[1], ap[2], ap[3]); 116 return str; 118 117 } ar5315_microredboot/microredboot/ecos/packages/redboot/current/src/net/ip.c
r12281 r12368 67 67 68 68 ip_addr_t __local_ip_addr = { CYGDAT_REDBOOT_DEFAULT_IP_ADDR }; 69 69 70 #ifdef CYGSEM_REDBOOT_NETWORKING_USE_GATEWAY 70 71 ip_addr_t __local_ip_mask = { CYGDAT_REDBOOT_DEFAULT_IP_ADDR_MASK }; … … 78 79 * See if an address is on the local network 79 80 */ 80 int 81 __ip_addr_local(ip_addr_t *addr) 82 { 83 return !( 84 ((__local_ip_addr[0] ^ (*addr)[0]) & __local_ip_mask[0]) | 85 ((__local_ip_addr[1] ^ (*addr)[1]) & __local_ip_mask[1]) | 86 ((__local_ip_addr[2] ^ (*addr)[2]) & __local_ip_mask[2]) | 87 ((__local_ip_addr[3] ^ (*addr)[3]) & __local_ip_mask[3])); 81 int __ip_addr_local(ip_addr_t * addr) 82 { 83 return !(((__local_ip_addr[0] ^ (*addr)[0]) & __local_ip_mask[0]) | 84 ((__local_ip_addr[1] ^ (*addr)[1]) & __local_ip_mask[1]) | 85 ((__local_ip_addr[2] ^ (*addr)[2]) & __local_ip_mask[2]) | 86 ((__local_ip_addr[3] ^ (*addr)[3]) & __local_ip_mask[3])); 88 87 } 89 88 #endif … … 93 92 * Check for broadcast matches as well. 94 93 */ 95 static int 96 ip_addr_match(ip_addr_t addr) 97 { 98 if (addr[0] == 255 && addr[1] == 255 && addr[2] == 255 && addr[3] == 255) 99 return 1; 100 101 if (!memcmp(addr, __local_ip_addr, sizeof(ip_addr_t))) 102 return 1; 103 104 /* 105 * Consider it an address match if we haven't gotten our IP address yet. 106 * Some DHCP servers will address IP packets to the assigned address 107 * instead of a IP broadcast address. 108 */ 109 if (__local_ip_addr[0] == 0 && __local_ip_addr[1] == 0 && 110 __local_ip_addr[2] == 0 && __local_ip_addr[3] == 0) 111 return 1; 112 113 return 0; 114 } 115 94 static int ip_addr_match(ip_addr_t addr) 95 { 96 if (addr[0] == 255 && addr[1] == 255 && addr[2] == 255 97 && addr[3] == 255) 98 return 1; 99 100 if (!memcmp(addr, __local_ip_addr, sizeof(ip_addr_t))) 101 return 1; 102 103 /* 104 * Consider it an address match if we haven't gotten our IP address yet. 105 * Some DHCP servers will address IP packets to the assigned address 106 * instead of a IP broadcast address. 107 */ 108 if (__local_ip_addr[0] == 0 && __local_ip_addr[1] == 0 && 109 __local_ip_addr[2] == 0 && __local_ip_addr[3] == 0) 110 return 1; 111 112 return 0; 113 } 116 114 117 115 extern void __tcp_handler(pktbuf_t *, ip_route_t *); … … 120 118 * Handle IP packets coming from the polled ethernet interface. 121 119 */ 122 void 123 __ip_handler(pktbuf_t *pkt, enet_addr_t *src_enet_addr) 124 { 125 ip_header_t *ip = pkt->ip_hdr; 126 ip_route_t r; 127 int hdr_bytes; 128 129 /* first make sure its ours and has a good checksum. */ 130 if (!ip_addr_match(ip->destination) || 131 __sum((word *)ip, ip->hdr_len << 2, 0) != 0) { 132 __pktbuf_free(pkt); 133 return; 134 } 135 136 memcpy(r.ip_addr, ip->source, sizeof(ip_addr_t)); 137 memcpy(r.enet_addr, src_enet_addr, sizeof(enet_addr_t)); 138 139 hdr_bytes = ip->hdr_len << 2; 140 pkt->pkt_bytes = ntohs(ip->length) - hdr_bytes; 141 142 switch (ip->protocol) { 120 void __ip_handler(pktbuf_t * pkt, enet_addr_t * src_enet_addr) 121 { 122 ip_header_t *ip = pkt->ip_hdr; 123 ip_route_t r; 124 int hdr_bytes; 125 126 /* first make sure its ours and has a good checksum. */ 127 if (!ip_addr_match(ip->destination) || 128 __sum((word *) ip, ip->hdr_len << 2, 0) != 0) { 129 __pktbuf_free(pkt); 130 return; 131 } 132 133 memcpy(r.ip_addr, ip->source, sizeof(ip_addr_t)); 134 memcpy(r.enet_addr, src_enet_addr, sizeof(enet_addr_t)); 135 136 hdr_bytes = ip->hdr_len << 2; 137 pkt->pkt_bytes = ntohs(ip->length) - hdr_bytes; 138 139 switch (ip->protocol) { 143 140 144 141 #if NET_SUPPORT_ICMP 145 case IP_PROTO_ICMP:146 pkt->icmp_hdr = (icmp_header_t *)(((char *)ip) + hdr_bytes);147 __icmp_handler(pkt, &r);148 break;142 case IP_PROTO_ICMP: 143 pkt->icmp_hdr = (icmp_header_t *) (((char *)ip) + hdr_bytes); 144 __icmp_handler(pkt, &r); 145 break; 149 146 #endif 150 147 151 148 #if NET_SUPPORT_TCP 152 case IP_PROTO_TCP:153 pkt->tcp_hdr = (tcp_header_t *)(((char *)ip) + hdr_bytes);154 __tcp_handler(pkt, &r);155 break;149 case IP_PROTO_TCP: 150 pkt->tcp_hdr = (tcp_header_t *) (((char *)ip) + hdr_bytes); 151 __tcp_handler(pkt, &r); 152 break; 156 153 #endif 157 154 158 155 #if NET_SUPPORT_UDP 159 case IP_PROTO_UDP: 160 pkt->udp_hdr = (udp_header_t *)(((char *)ip) + hdr_bytes); 161 __udp_handler(pkt, &r); 162 break; 163 #endif 164 165 default: 166 __pktbuf_free(pkt); 167 break; 168 } 169 } 170 156 case IP_PROTO_UDP: 157 pkt->udp_hdr = (udp_header_t *) (((char *)ip) + hdr_bytes); 158 __udp_handler(pkt, &r); 159 break; 160 #endif 161 162 default: 163 __pktbuf_free(pkt); 164 break; 165 } 166 } 171 167 172 168 /* … … 178 174 * options field. 179 175 */ 180 int 181 __ip_send(pktbuf_t *pkt, int protocol, ip_route_t *dest) 182 { 183 ip_header_t *ip = pkt->ip_hdr; 184 int hdr_bytes; 185 unsigned short cksum; 186 187 /* 188 * Figure out header length. The use udp_hdr is 189 * somewhat arbitrary, but works because it is 190 * a union with other IP protocol headers. 191 */ 192 hdr_bytes = (((char *)pkt->udp_hdr) - ((char *)ip)); 193 194 pkt->pkt_bytes += hdr_bytes; 195 196 ip->version = 4; 197 ip->hdr_len = hdr_bytes >> 2; 198 ip->tos = 0; 199 ip->length = htons(pkt->pkt_bytes); 200 ip->ident = htons(ip_ident); 201 ip_ident++; 202 ip->fragment = 0; 203 ip->ttl = 255; 204 ip->ttl = 64; 205 ip->protocol = protocol; 206 ip->checksum = 0; 207 memcpy(ip->source, __local_ip_addr, sizeof(ip_addr_t)); 208 memcpy(ip->destination, dest->ip_addr, sizeof(ip_addr_t)); 209 cksum = __sum((word *)ip, hdr_bytes, 0); 210 ip->checksum = htons(cksum); 211 212 __enet_send(pkt, &dest->enet_addr, ETH_TYPE_IP); 213 return 0; 214 } 215 216 176 int __ip_send(pktbuf_t * pkt, int protocol, ip_route_t * dest) 177 { 178 ip_header_t *ip = pkt->ip_hdr; 179 int hdr_bytes; 180 unsigned short cksum; 181 182 /* 183 * Figure out header length. The use udp_hdr is 184 * somewhat arbitrary, but works because it is 185 * a union with other IP protocol headers. 186 */ 187 hdr_bytes = (((char *)pkt->udp_hdr) - ((char *)ip)); 188 189 pkt->pkt_bytes += hdr_bytes; 190 191 ip->version = 4; 192 ip->hdr_len = hdr_bytes >> 2; 193 ip->tos = 0; 194 ip->length = htons(pkt->pkt_bytes); 195 ip->ident = htons(ip_ident); 196 ip_ident++; 197 ip->fragment = 0; 198 ip->ttl = 255; 199 ip->ttl = 64; 200 ip->protocol = protocol; 201 ip->checksum = 0; 202 memcpy(ip->source, __local_ip_addr, sizeof(ip_addr_t)); 203 memcpy(ip->destination, dest->ip_addr, sizeof(ip_addr_t)); 204 cksum = __sum((word *) ip, hdr_bytes, 0); 205 ip->checksum = htons(cksum); 206 207 __enet_send(pkt, &dest->enet_addr, ETH_TYPE_IP); 208 return 0; 209 } ar5315_microredboot/microredboot/ecos/packages/redboot/current/src/net/net_io.c
r12281 r12368 56 56 #include <redboot.h> 57 57 #include <net/net.h> 58 #include <cyg/hal/hal_misc.h> // Helper functions59 #include <cyg/hal/hal_if.h> // HAL I/O interfaces58 #include <cyg/hal/hal_misc.h> // Helper functions 59 #include <cyg/hal/hal_if.h> // HAL I/O interfaces 60 60 #include <cyg/hal/drv_api.h> 61 61 #include <cyg/hal/hal_intr.h> 62 #include <cyg/infra/cyg_ass.h> // assertion macros62 #include <cyg/infra/cyg_ass.h> // assertion macros 63 63 64 64 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG … … 66 66 67 67 RedBoot_config_option("GDB connection port", 68 gdb_port, 69 ALWAYS_ENABLED, true, 70 CONFIG_INT, 71 CYGNUM_REDBOOT_NETWORKING_TCP_PORT 72 ); 68 gdb_port, 69 ALWAYS_ENABLED, true, 70 CONFIG_INT, CYGNUM_REDBOOT_NETWORKING_TCP_PORT); 73 71 //RedBoot_config_option("Network debug at boot time", 74 72 // net_debug, … … 78 76 // ); 79 77 #if defined(CYGHWR_NET_DRIVERS) && (CYGHWR_NET_DRIVERS > 1) 80 RedBoot_config_option("Default network device", 81 net_device, 82 ALWAYS_ENABLED, true, 83 CONFIG_NETPORT, 84 "" 85 ); 78 RedBoot_config_option("Default network device", 79 net_device, ALWAYS_ENABLED, true, CONFIG_NETPORT, ""); 86 80 #endif 87 81 // Note: the following options are related. If 'bootp' is false, then … … 97 91 #endif 98 92 RedBoot_config_option("Use BOOTP for network configuration", 99 bootp, 100 ALWAYS_ENABLED, true, 101 CONFIG_BOOL, 102 !CYGSEM_REDBOOT_DEFAULT_NO_BOOTP 103 ); 93 bootp, 94 ALWAYS_ENABLED, true, 95 CONFIG_BOOL, !CYGSEM_REDBOOT_DEFAULT_NO_BOOTP); 104 96 RedBoot_config_option("Local IP address", 105 bootp_my_ip, 106 "bootp", false, 107 CONFIG_IP, 108 0 109 ); 97 bootp_my_ip, "bootp", false, CONFIG_IP, 0); 110 98 #ifdef CYGSEM_REDBOOT_NETWORKING_USE_GATEWAY 111 99 RedBoot_config_option("Local IP address mask", 112 bootp_my_ip_mask, 113 "bootp", false, 114 CONFIG_IP, 115 0 116 ); 100 bootp_my_ip_mask, "bootp", false, CONFIG_IP, 0); 117 101 RedBoot_config_option("Gateway IP address", 118 bootp_my_gateway_ip, 119 "bootp", false, 120 CONFIG_IP, 121 0 122 ); 102 bootp_my_gateway_ip, "bootp", false, CONFIG_IP, 0); 123 103 #endif 124 104 RedBoot_config_option("Default server IP address", 125 bootp_server_ip, 126 ALWAYS_ENABLED, true, 127 CONFIG_IP, 128 0 129 ); 105 bootp_server_ip, ALWAYS_ENABLED, true, CONFIG_IP, 0); 130 106 131 107 // Note: the following options are related too. 132 108 RedBoot_config_option("Force console for special debug messages", 133 info_console_force, 134 ALWAYS_ENABLED, true, 135 CONFIG_BOOL, 136 false 137 ); 109 info_console_force, 110 ALWAYS_ENABLED, true, CONFIG_BOOL, false); 138 111 RedBoot_config_option("Console number for special debug messages", 139 info_console_number, 140 "info_console_force", true, 141 CONFIG_INT, 142 0 143 ); 112 info_console_number, 113 "info_console_force", true, CONFIG_INT, 0); 144 114 #endif 145 115 … … 148 118 #ifdef DEBUG_TCP 149 119 int show_tcp = 0; 150 #endif 120 #endif 151 121 152 122 static tcp_socket_t tcp_sock; … … 166 136 static void net_io_flush(void); 167 137 static void net_io_revert_console(void); 168 static void net_io_putc(void *, cyg_uint8);138 static void net_io_putc(void *, cyg_uint8); 169 139 170 140 // Special characters used by Telnet - must be interpretted here 171 #define TELNET_IAC 0xFF // Interpret as command (escape) 172 #define TELNET_IP 0xF4 // Interrupt process 173 #define TELNET_WONT 0xFC // I Won't do it 174 #define TELNET_DO 0xFD // Will you XXX 175 #define TELNET_TM 0x06 // Time marker (special DO/WONT after IP) 176 177 static cyg_bool 178 _net_io_getc_nonblock(void* __ch_data, cyg_uint8* ch) 179 { 180 if (in_buflen == 0) { 181 __tcp_poll(); 182 if (tcp_sock.state == _CLOSE_WAIT) { 183 // This connection is breaking 184 if (tcp_sock.data_bytes == 0 && tcp_sock.rxcnt == 0) { 185 __tcp_close(&tcp_sock); 186 return false; 187 } 188 } 189 if (tcp_sock.state == _CLOSED) { 190 // The connection is gone 191 net_io_revert_console(); 192 *ch = '\n'; 193 return true; 194 } 195 in_buflen = __tcp_read(&tcp_sock, in_buf, sizeof(in_buf)); 196 in_bufp = in_buf; 141 #define TELNET_IAC 0xFF // Interpret as command (escape) 142 #define TELNET_IP 0xF4 // Interrupt process 143 #define TELNET_WONT 0xFC // I Won't do it 144 #define TELNET_DO 0xFD // Will you XXX 145 #define TELNET_TM 0x06 // Time marker (special DO/WONT after IP) 146 147 static cyg_bool _net_io_getc_nonblock(void *__ch_data, cyg_uint8 * ch) 148 { 149 if (in_buflen == 0) { 150 __tcp_poll(); 151 if (tcp_sock.state == _CLOSE_WAIT) { 152 // This connection is breaking 153 if (tcp_sock.data_bytes == 0 && tcp_sock.rxcnt == 0) { 154 __tcp_close(&tcp_sock); 155 return false; 156 } 157 } 158 if (tcp_sock.state == _CLOSED) { 159 // The connection is gone 160 net_io_revert_console(); 161 *ch = '\n'; 162 return true; 163 } 164 in_buflen = __tcp_read(&tcp_sock, in_buf, sizeof(in_buf)); 165 in_bufp = in_buf; 197 166 #ifdef DEBUG_TCP 198 if (show_tcp && (in_buflen > 0)) { 199 int old_console; 200 old_console = start_console(); 201 diag_printf("%s:%d\n", __FUNCTION__, __LINE__); 202 diag_dump_buf(in_buf, in_buflen); 203 end_console(old_console); 204 } 205 #endif // DEBUG_TCP 206 } 207 if (in_buflen) { 208 *ch = *in_bufp++; 209 in_buflen--; 210 return true; 211 } else { 212 return false; 213 } 214 } 215 216 static cyg_bool 217 net_io_getc_nonblock(void* __ch_data, cyg_uint8* ch) 218 { 219 cyg_uint8 esc; 220 221 if (!_net_io_getc_nonblock(__ch_data, ch)) 222 return false; 223 224 if (gdb_active || *ch != TELNET_IAC) 225 return true; 226 227 // Telnet escape - need to read/handle more 228 while (!_net_io_getc_nonblock(__ch_data, &esc)) ; 229 230 switch (esc) { 231 case TELNET_IAC: 232 // The other special case - escaped escape 233 return true; 234 case TELNET_IP: 235 // Special case for ^C == Interrupt Process 236 *ch = 0x03; 237 // Just in case the other end needs synchronizing 238 net_io_putc(__ch_data, TELNET_IAC); 239 net_io_putc(__ch_data, TELNET_WONT); 240 net_io_putc(__ch_data, TELNET_TM); 241 net_io_flush(); 242 return true; 243 case TELNET_DO: 244 // Telnet DO option 245 while (!_net_io_getc_nonblock(__ch_data, &esc)) ; 246 // Respond with WONT option 247 net_io_putc(__ch_data, TELNET_IAC); 248 net_io_putc(__ch_data, TELNET_WONT); 249 net_io_putc(__ch_data, esc); 250 return false; // Ignore this whole thing! 251 default: 252 return false; 253 } 254 } 255 256 static cyg_uint8 257 net_io_getc(void* __ch_data) 258 { 259 cyg_uint8 ch; 260 int idle_timeout = 10; // 10ms 261 262 CYGARC_HAL_SAVE_GP(); 263 while (true) { 264 if (net_io_getc_nonblock(__ch_data, &ch)) break; 265 if (--idle_timeout == 0) { 266 net_io_flush(); 267 idle_timeout = 10; 268 } 269 } 270 CYGARC_HAL_RESTORE_GP(); 271 return ch; 167 if (show_tcp && (in_buflen > 0)) { 168 int old_console; 169 old_console = start_console(); 170 diag_printf("%s:%d\n", __FUNCTION__, __LINE__); 171 diag_dump_buf(in_buf, in_buflen); 172 end_console(old_console); 173 } 174 #endif // DEBUG_TCP 175 } 176 if (in_buflen) { 177 *ch = *in_bufp++; 178 in_buflen--; 179 return true; 180 } else { 181 return false; 182 } 183 } 184 185 static cyg_bool net_io_getc_nonblock(void *__ch_data, cyg_uint8 * ch) 186 { 187 cyg_uint8 esc; 188 189 if (!_net_io_getc_nonblock(__ch_data, ch)) 190 return false; 191 192 if (gdb_active || *ch != TELNET_IAC) 193 return true; 194 195 // Telnet escape - need to read/handle more 196 while (!_net_io_getc_nonblock(__ch_data, &esc)) ; 197 198 switch (esc) { 199 case TELNET_IAC: 200 // The other special case - escaped escape 201 return true; 202 case TELNET_IP: 203 // Special case for ^C == Interrupt Process 204 *ch = 0x03; 205 // Just in case the other end needs synchronizing 206 net_io_putc(__ch_data, TELNET_IAC); 207 net_io_putc(__ch_data, TELNET_WONT); 208 net_io_putc(__ch_data, TELNET_TM); 209 net_io_flush(); 210 return true; 211 case TELNET_DO: 212 // Telnet DO option 213 while (!_net_io_getc_nonblock(__ch_data, &esc)) ; 214 // Respond with WONT option 215 net_io_putc(__ch_data, TELNET_IAC); 216 net_io_putc(__ch_data, TELNET_WONT); 217 net_io_putc(__ch_data, esc); 218 return false; // Ignore this whole thing! 219 default: 220 return false; 221 } 222 } 223 224 static cyg_uint8 net_io_getc(void *__ch_data) 225 { 226 cyg_uint8 ch; 227 int idle_timeout = 10; // 10ms 228 229 CYGARC_HAL_SAVE_GP(); 230 while (true) { 231 if (net_io_getc_nonblock(__ch_data, &ch)) 232 break; 233 if (--idle_timeout == 0) { 234 net_io_flush(); 235 idle_timeout = 10; 236 } 237 } 238 CYGARC_HAL_RESTORE_GP(); 239 return ch; 240 } 241 242 static void net_io_flush(void) 243 { 244 int n; 245 char *bp = out_buf; 246 247 #ifdef DEBUG_TCP 248 if (show_tcp) { 249 int old_console; 250 old_console = start_console(); 251 diag_printf("%s.%d\n", __FUNCTION__, __LINE__); 252 diag_dump_buf(out_buf, out_buflen); 253 end_console(old_console); 254 } 255 #endif // SHOW_TCP 256 n = __tcp_write_block(&tcp_sock, bp, out_buflen); 257 if (n < 0) { 258 // The connection is gone! 259 net_io_revert_console(); 260 } else { 261 out_buflen -= n; 262 bp += n; 263 } 264 out_bufp = out_buf; 265 out_buflen = 0; 266 // Check interrupt flag 267 if (CYGACC_CALL_IF_CONSOLE_INTERRUPT_FLAG()) { 268 CYGACC_CALL_IF_CONSOLE_INTERRUPT_FLAG_SET(0); 269 cyg_hal_user_break(0); 270 } 271 } 272 273 static void net_io_putc(void *__ch_data, cyg_uint8 c) 274 { 275 static bool have_dollar, have_hash; 276 static int hash_count; 277 278 CYGARC_HAL_SAVE_GP(); 279 *out_bufp++ = c; 280 if (c == '$') 281 have_dollar = true; 282 if (have_dollar && (c == '#')) { 283 have_hash = true; 284 hash_count = 0; 285 } 286 if ((++out_buflen == sizeof(out_buf)) || 287 (flush_output_lines && c == '\n') || 288 (have_hash && (++hash_count == 3))) { 289 net_io_flush(); 290 have_dollar = false; 291 } 292 CYGARC_HAL_RESTORE_GP(); 272 293 } 273 294 274 295 static void 275 net_io_flush(void) 276 { 277 int n; 278 char *bp = out_buf; 279 296 net_io_write(void *__ch_data, const cyg_uint8 * __buf, cyg_uint32 __len) 297 { 298 int old_console; 299 300 old_console = start_console(); 301 diag_printf("%s.%d\n", __FUNCTION__, __LINE__); 302 end_console(old_console); 303 #if 0 304 CYGARC_HAL_SAVE_GP(); 305 306 while (__len-- > 0) 307 net_io_putc(__ch_data, *__buf++); 308 309 CYGARC_HAL_RESTORE_GP(); 310 #endif 311 } 312 313 static void net_io_read(void *__ch_data, cyg_uint8 * __buf, cyg_uint32 __len) 314 { 315 int old_console; 316 317 old_console = start_console(); 318 diag_printf("%s.%d\n", __FUNCTION__, __LINE__); 319 end_console(old_console); 320 #if 0 321 CYGARC_HAL_SAVE_GP(); 322 323 while (__len-- > 0) 324 *__buf++ = net_io_getc(__ch_data); 325 326 CYGARC_HAL_RESTORE_GP(); 327 #endif 328 } 329 330 static cyg_bool net_io_getc_timeout(void *__ch_data, cyg_uint8 * ch) 331 { 332 int delay_count; 333 cyg_bool res; 334 335 CYGARC_HAL_SAVE_GP(); 336 net_io_flush(); // Make sure any output has been sent 337 delay_count = _timeout; 338 339 for (;;) { 340 res = net_io_getc_nonblock(__ch_data, ch); 341 if (res || 0 == delay_count--) 342 break; 343 } 344 345 CYGARC_HAL_RESTORE_GP(); 346 347 return res; 348 } 349 350 static int net_io_control(void *__ch_data, __comm_control_cmd_t __func, ...) 351 { 352 static int vector = 0; 353 int ret = 0; 354 static int irq_state = 0; 355 356 CYGARC_HAL_SAVE_GP(); 357 358 switch (__func) { 359 case __COMMCTL_IRQ_ENABLE: 360 irq_state = 1; 361 if (vector == 0) { 362 vector = eth_drv_int_vector(); 363 } 364 HAL_INTERRUPT_UNMASK(vector); 365 break; 366 case __COMMCTL_IRQ_DISABLE: 367 ret = irq_state; 368 irq_state = 0; 369 if (vector == 0) { 370 vector = eth_drv_int_vector(); 371 } 372 HAL_INTERRUPT_MASK(vector); 373 break; 374 case __COMMCTL_DBG_ISR_VECTOR: 375 ret = vector; 376 break; 377 case __COMMCTL_SET_TIMEOUT: 378 { 379 va_list ap; 380 381 va_start(ap, __func); 382 383 ret = _timeout; 384 _timeout = va_arg(ap, cyg_uint32); 385 386 va_end(ap); 387 break; 388 } 389 case __COMMCTL_FLUSH_OUTPUT: 390 net_io_flush(); 391 break; 392 case __COMMCTL_ENABLE_LINE_FLUSH: 393 flush_output_lines = true; 394 break; 395 case __COMMCTL_DISABLE_LINE_FLUSH: 396 flush_output_lines = false; 397 break; 398 default: 399 break; 400 } 401 CYGARC_HAL_RESTORE_GP(); 402 return ret; 403 } 404 405 static int 406 net_io_isr(void *__ch_data, int *__ctrlc, 407 CYG_ADDRWORD __vector, CYG_ADDRWORD __data) 408 { 409 char ch; 410 411 CYGARC_HAL_SAVE_GP(); 412 *__ctrlc = 0; 413 if (net_io_getc_nonblock(__ch_data, &ch)) { 414 if (ch == 0x03) { 415 *__ctrlc = 1; 416 } 417 } 418 CYGARC_HAL_RESTORE_GP(); 419 return CYG_ISR_HANDLED; 420 } 421 422 // TEMP 423 424 int start_console(void) 425 { 426 int cur_console = 427 CYGACC_CALL_IF_SET_CONSOLE_COMM 428 (CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); 429 430 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG 431 int i = 0; 432 if (flash_get_config("info_console_force", &i, CONFIG_BOOL)) 433 if (i) 434 if (!flash_get_config 435 ("info_console_number", &i, CONFIG_INT)) 436 i = 0; // the default, if that call failed. 437 if (i) 438 CYGACC_CALL_IF_SET_CONSOLE_COMM(i); 439 else 440 #endif 441 CYGACC_CALL_IF_SET_CONSOLE_COMM(0); 442 443 return cur_console; 444 } 445 446 void end_console(int old_console) 447 { 448 // Restore original console 449 CYGACC_CALL_IF_SET_CONSOLE_COMM(old_console); 450 } 451 452 // TEMP 453 454 static void net_io_revert_console(void) 455 { 456 #ifdef CYGPKG_REDBOOT_ANY_CONSOLE 457 console_selected = false; 458 #endif 459 CYGACC_CALL_IF_SET_CONSOLE_COMM(orig_console); 460 CYGACC_CALL_IF_SET_DEBUG_COMM(orig_debug); 461 console_echo = true; 462 } 463 464 static void net_io_assume_console(void) 465 { 466 #ifdef CYGPKG_REDBOOT_ANY_CONSOLE 467 console_selected = true; 468 #endif 469 console_echo = false; 470 orig_console = 471 CYGACC_CALL_IF_SET_CONSOLE_COMM 472 (CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); 473 CYGACC_CALL_IF_SET_CONSOLE_COMM(TCP_CHANNEL); 474 orig_debug = 475 CYGACC_CALL_IF_SET_DEBUG_COMM 476 (CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); 477 CYGACC_CALL_IF_SET_DEBUG_COMM(TCP_CHANNEL); 478 } 479 480 static void net_io_init(void) 481 { 482 static int init = 0; 483 if (!init) { 484 hal_virtual_comm_table_t *comm; 485 int cur = 486 CYGACC_CALL_IF_SET_CONSOLE_COMM 487 (CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); 488 489 // Setup procs in the vector table 490 CYGACC_CALL_IF_SET_CONSOLE_COMM(TCP_CHANNEL); 491 comm = CYGACC_CALL_IF_CONSOLE_PROCS(); 492 //CYGACC_COMM_IF_CH_DATA_SET(*comm, chan); 493 CYGACC_COMM_IF_WRITE_SET(*comm, net_io_write); 494 CYGACC_COMM_IF_READ_SET(*comm, net_io_read); 495 CYGACC_COMM_IF_PUTC_SET(*comm, net_io_putc); 496 CYGACC_COMM_IF_GETC_SET(*comm, net_io_getc); 497 CYGACC_COMM_IF_CONTROL_SET(*comm, net_io_control); 498 CYGACC_COMM_IF_DBG_ISR_SET(*comm, net_io_isr); 499 CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, net_io_getc_timeout); 500 501 // Disable interrupts via this interface to set static 502 // state into correct state. 503 net_io_control(comm, __COMMCTL_IRQ_DISABLE); 504 505 // Restore original console 506 CYGACC_CALL_IF_SET_CONSOLE_COMM(cur); 507 508 init = 1; 509 gdb_active = false; 510 } 511 __tcp_listen(&tcp_sock, gdb_port); 512 state = tcp_sock.state; 280 513 #ifdef DEBUG_TCP 281 if (show_tcp) { 282 int old_console; 283 old_console = start_console(); 284 diag_printf("%s.%d\n", __FUNCTION__, __LINE__); 285 diag_dump_buf(out_buf, out_buflen); 286 end_console(old_console); 287 } 288 #endif // SHOW_TCP 289 n = __tcp_write_block(&tcp_sock, bp, out_buflen); 290 if (n < 0) { 291 // The connection is gone! 292 net_io_revert_console(); 293 } else { 294 out_buflen -= n; 295 bp += n; 296 } 297 out_bufp = out_buf; out_buflen = 0; 298 // Check interrupt flag 299 if (CYGACC_CALL_IF_CONSOLE_INTERRUPT_FLAG()) { 300 CYGACC_CALL_IF_CONSOLE_INTERRUPT_FLAG_SET(0); 301 cyg_hal_user_break(0); 302 } 303 } 304 305 static void 306 net_io_putc(void* __ch_data, cyg_uint8 c) 307 { 308 static bool have_dollar, have_hash; 309 static int hash_count; 310 311 CYGARC_HAL_SAVE_GP(); 312 *out_bufp++ = c; 313 if (c == '$') have_dollar = true; 314 if (have_dollar && (c == '#')) { 315 have_hash = true; 316 hash_count = 0; 317 } 318 if ((++out_buflen == sizeof(out_buf)) || 319 (flush_output_lines && c == '\n') || 320 (have_hash && (++hash_count == 3))) { 321 net_io_flush(); 322 have_dollar = false; 323 } 324 CYGARC_HAL_RESTORE_GP(); 325 } 326 327 static void 328 net_io_write(void* __ch_data, const cyg_uint8* __buf, cyg_uint32 __len) 329 { 330 int old_console; 331 332 old_console = start_console(); 333 diag_printf("%s.%d\n", __FUNCTION__, __LINE__); 334 end_console(old_console); 335 #if 0 336 CYGARC_HAL_SAVE_GP(); 337 338 while(__len-- > 0) 339 net_io_putc(__ch_data, *__buf++); 340 341 CYGARC_HAL_RESTORE_GP(); 342 #endif 343 } 344 345 static void 346 net_io_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len) 347 { 348 int old_console; 349 350 old_console = start_console(); 351 diag_printf("%s.%d\n", __FUNCTION__, __LINE__); 352 end_console(old_console); 353 #if 0 354 CYGARC_HAL_SAVE_GP(); 355 356 while(__len-- > 0) 357 *__buf++ = net_io_getc(__ch_data); 358 359 CYGARC_HAL_RESTORE_GP(); 360 #endif 361 } 362 363 static cyg_bool 364 net_io_getc_timeout(void* __ch_data, cyg_uint8* ch) 365 { 366 int delay_count; 367 cyg_bool res; 368 369 CYGARC_HAL_SAVE_GP(); 370 net_io_flush(); // Make sure any output has been sent 371 delay_count = _timeout; 372 373 for(;;) { 374 res = net_io_getc_nonblock(__ch_data, ch); 375 if (res || 0 == delay_count--) 376 break; 377 } 378 379 CYGARC_HAL_RESTORE_GP(); 380 381 return res; 382 } 383 384 static int 385 net_io_control(void *__ch_data, __comm_control_cmd_t __func, ...) 386 { 387 static int vector = 0; 388 int ret = 0; 389 static int irq_state = 0; 390 391 CYGARC_HAL_SAVE_GP(); 392 393 switch (__func) { 394 case __COMMCTL_IRQ_ENABLE: 395 irq_state = 1; 396 if (vector == 0) { 397 vector = eth_drv_int_vector(); 398 } 399 HAL_INTERRUPT_UNMASK(vector); 400 break; 401 case __COMMCTL_IRQ_DISABLE: 402 ret = irq_state; 403 irq_state = 0; 404 if (vector == 0) { 405 vector = eth_drv_int_vector(); 406 } 407 HAL_INTERRUPT_MASK(vector); 408 break; 409 case __COMMCTL_DBG_ISR_VECTOR: 410 ret = vector; 411 break; 412 case __COMMCTL_SET_TIMEOUT: 413 { 414 va_list ap; 415 416 va_start(ap, __func); 417 418 ret = _timeout; 419 _timeout = va_arg(ap, cyg_uint32); 420 421 va_end(ap); 422 break; 423 } 424 case __COMMCTL_FLUSH_OUTPUT: 425 net_io_flush(); 426 break; 427 case __COMMCTL_ENABLE_LINE_FLUSH: 428 flush_output_lines = true; 429 break; 430 case __COMMCTL_DISABLE_LINE_FLUSH: 431 flush_output_lines = false; 432 break; 433 default: 434 break; 435 } 436 CYGARC_HAL_RESTORE_GP(); 437 return ret; 438 } 439 440 static int 441 net_io_isr(void *__ch_data, int* __ctrlc, 442 CYG_ADDRWORD __vector, CYG_ADDRWORD __data) 443 { 444 char ch; 445 446 CYGARC_HAL_SAVE_GP(); 447 *__ctrlc = 0; 448 if (net_io_getc_nonblock(__ch_data, &ch)) { 449 if (ch == 0x03) { 450 *__ctrlc = 1; 451 } 452 } 453 CYGARC_HAL_RESTORE_GP(); 454 return CYG_ISR_HANDLED; 455 } 456 457 // TEMP 458 459 int 460 start_console(void) 461 { 462 int cur_console = 463 CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); 464 465 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG 466 int i = 0; 467 if ( flash_get_config( "info_console_force", &i, CONFIG_BOOL) ) 468 if ( i ) 469 if ( ! flash_get_config( "info_console_number", &i, CONFIG_INT) ) 470 i = 0; // the default, if that call failed. 471 if ( i ) 472 CYGACC_CALL_IF_SET_CONSOLE_COMM(i); 473 else 474 #endif 475 CYGACC_CALL_IF_SET_CONSOLE_COMM(0); 476 477 return cur_console; 478 } 479 480 void 481 end_console(int old_console) 482 { 483 // Restore original console 484 CYGACC_CALL_IF_SET_CONSOLE_COMM(old_console); 485 } 486 // TEMP 487 488 static void 489 net_io_revert_console(void) 490 { 491 #ifdef CYGPKG_REDBOOT_ANY_CONSOLE 492 console_selected = false; 493 #endif 494 CYGACC_CALL_IF_SET_CONSOLE_COMM(orig_console); 495 CYGACC_CALL_IF_SET_DEBUG_COMM(orig_debug); 496 console_echo = true; 497 } 498 499 static void 500 net_io_assume_console(void) 501 { 502 #ifdef CYGPKG_REDBOOT_ANY_CONSOLE 503 console_selected = true; 504 #endif 505 console_echo = false; 506 orig_console = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); 507 CYGACC_CALL_IF_SET_CONSOLE_COMM(TCP_CHANNEL); 508 orig_debug = CYGACC_CALL_IF_SET_DEBUG_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); 509 CYGACC_CALL_IF_SET_DEBUG_COMM(TCP_CHANNEL); 510 } 511 512 static void 513 net_io_init(void) 514 { 515 static int init = 0; 516 if (!init) { 517 hal_virtual_comm_table_t* comm; 518 int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); 519 520 // Setup procs in the vector table 521 CYGACC_CALL_IF_SET_CONSOLE_COMM(TCP_CHANNEL); 522 comm = CYGACC_CALL_IF_CONSOLE_PROCS(); 523 //CYGACC_COMM_IF_CH_DATA_SET(*comm, chan); 524 CYGACC_COMM_IF_WRITE_SET(*comm, net_io_write); 525 CYGACC_COMM_IF_READ_SET(*comm, net_io_read); 526 CYGACC_COMM_IF_PUTC_SET(*comm, net_io_putc); 527 CYGACC_COMM_IF_GETC_SET(*comm, net_io_getc); 528 CYGACC_COMM_IF_CONTROL_SET(*comm, net_io_control); 529 CYGACC_COMM_IF_DBG_ISR_SET(*comm, net_io_isr); 530 CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, net_io_getc_timeout); 531 532 // Disable interrupts via this interface to set static 533 // state into correct state. 534 net_io_control( comm, __COMMCTL_IRQ_DISABLE ); 535 536 // Restore original console 537 CYGACC_CALL_IF_SET_CONSOLE_COMM(cur); 538 539 init = 1; 540 gdb_active = false; 541 } 542 __tcp_listen(&tcp_sock, gdb_port); 543 state = tcp_sock.state; 544 #ifdef DEBUG_TCP 545 diag_printf("show tcp = %p\n", (void *)&show_tcp); 514 diag_printf("show tcp = %p\n", (void *)&show_tcp); 546 515 #endif 547 516 } 548 517 549 518 // Check for incoming TCP debug connection 550 void 551 net_io_test(bool is_idle) 552 { 553 if (!is_idle) return; // Only care about idle case 554 if (!have_net) return; 555 __tcp_poll(); 556 if (state != tcp_sock.state) { 557 // Something has changed 558 if (tcp_sock.state == _ESTABLISHED) { 559 // A new connection has arrived 560 net_io_assume_console(); 561 in_bufp = in_buf; in_buflen = 1; *in_bufp = '\r'; 562 out_bufp = out_buf; out_buflen = 0; 563 } 564 if (tcp_sock.state == _CLOSED) { 565 net_io_init(); // Get ready for another connection 566 } 567 } 568 state = tcp_sock.state; 519 void net_io_test(bool is_idle) 520 { 521 if (!is_idle) 522 return; // Only care about idle case 523 if (!have_net) 524 return; 525 __tcp_poll(); 526 if (state != tcp_sock.state) { 527 // Something has changed 528 if (tcp_sock.state == _ESTABLISHED) { 529 // A new connection has arrived 530 net_io_assume_console(); 531 in_bufp = in_buf; 532 in_buflen = 1; 533 *in_bufp = '\r'; 534 out_bufp = out_buf; 535 out_buflen = 0; 536 } 537 if (tcp_sock.state == _CLOSED) { 538 net_io_init(); // Get ready for another connection 539 } 540 } 541 state = tcp_sock.state; 569 542 } 570 543 … … 582 555 583 556 // Define table boundaries 584 CYG_HAL_TABLE_BEGIN( __NETDEVTAB__, netdev);585 CYG_HAL_TABLE_END( __NETDEVTAB_END__, netdev);557 CYG_HAL_TABLE_BEGIN(__NETDEVTAB__, netdev); 558 CYG_HAL_TABLE_END(__NETDEVTAB_END__, netdev); 586 559 587 560 RedBoot_init(net_init, RedBoot_INIT_LAST); 588 561 589 static void 590 show_addrs(void) 591 { 592 diag_printf("IP: %s", inet_ntoa((in_addr_t *)&__local_ip_addr)); 562 static void show_addrs(void) 563 { 564 diag_printf("IP: %s", inet_ntoa((in_addr_t *) & __local_ip_addr)); 593 565 #ifdef CYGSEM_REDBOOT_NETWORKING_USE_GATEWAY 594 diag_printf("/%s", inet_ntoa((in_addr_t *)&__local_ip_mask)); 595 diag_printf(", Gateway: %s\n", inet_ntoa((in_addr_t *)&__local_ip_gate)); 566 diag_printf("/%s", inet_ntoa((in_addr_t *) & __local_ip_mask)); 567 diag_printf(", Gateway: %s\n", 568 inet_ntoa((in_addr_t *) & __local_ip_gate)); 596 569 #else 597 diag_printf(", ");598 #endif 599 diag_printf("Default server: %s", inet_ntoa(&my_bootp_info.bp_siaddr));570 diag_printf(", "); 571 #endif 572 diag_printf("Default server: %s", inet_ntoa(&my_bootp_info.bp_siaddr)); 600 573 #ifdef CYGPKG_REDBOOT_NETWORKING_DNS 601 show_dns();602 #endif 603 diag_printf("\n");574 show_dns(); 575 #endif 576 diag_printf("\n"); 604 577 } 605 578 606 579 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG 607 static void 608 flash_get_IP(char *id, ip_addr_t *val) 609 { 610 ip_addr_t my_ip; 611 int i; 612 613 if (flash_get_config(id, &my_ip, CONFIG_IP)) { 614 if (my_ip[0] != 0 || my_ip[1] != 0 || 615 my_ip[2] != 0 || my_ip[3] != 0) { 616 // 'id' is set to something so let it override any static IP 617 for (i=0; i<4; i++) 618 (*val)[i] = my_ip[i]; 619 } 620 } 621 } 622 #endif 623 624 static cyg_netdevtab_entry_t * 625 net_devtab_entry(unsigned index) 626 { 627 cyg_netdevtab_entry_t *t = &__NETDEVTAB__[index]; 628 629 if (t < &__NETDEVTAB__[0] || t >= &__NETDEVTAB_END__) 580 static void flash_get_IP(char *id, ip_addr_t * val) 581 { 582 ip_addr_t my_ip; 583 int i; 584 585 if (flash_get_config(id, &my_ip, CONFIG_IP)) { 586 if (my_ip[0] != 0 || my_ip[1] != 0 || 587 my_ip[2] != 0 || my_ip[3] != 0) { 588 // 'id' is set to something so let it override any static IP 589 for (i = 0; i < 4; i++) 590 (*val)[i] = my_ip[i]; 591 } 592 } 593 } 594 #endif 595 596 static cyg_netdevtab_entry_t *net_devtab_entry(unsigned index) 597 { 598 cyg_netdevtab_entry_t *t = &__NETDEVTAB__[index]; 599 600 if (t < &__NETDEVTAB__[0] || t >= &__NETDEVTAB_END__) 601 return NULL; 602 603 return t; 604 } 605 606 const char *net_devname(unsigned index) 607 { 608 cyg_netdevtab_entry_t *t = net_devtab_entry(index); 609 if (t) 610 return t->name; 630 611 return NULL; 631 632 return t; 633 } 634 635 const char * 636 net_devname(unsigned index) 637 { 638 cyg_netdevtab_entry_t *t = net_devtab_entry(index); 639 if (t) 640 return t->name; 641 return NULL; 642 } 643 644 int 645 net_devindex(char *name) 646 { 647 const char *devname; 648 int index; 649 650 for (index = 0; (devname = net_devname(index)) != NULL; index++) 651 if (!strcmp(name, devname)) 652 return index; 653 return -1; 654 }
