├── .gitattributes ├── .gitignore ├── LICENSE ├── Makefile ├── arm7 ├── Makefile └── source │ ├── wifi_arm7.c │ ├── wifi_arm7.h │ └── wifi_sdio.s ├── arm9 ├── Makefile └── source │ ├── sgIP.c │ ├── sgIP.h │ ├── sgIP_ARP.c │ ├── sgIP_ARP.h │ ├── sgIP_Config.h │ ├── sgIP_DHCP.c │ ├── sgIP_DHCP.h │ ├── sgIP_DNS.c │ ├── sgIP_DNS.h │ ├── sgIP_Hub.c │ ├── sgIP_Hub.h │ ├── sgIP_ICMP.c │ ├── sgIP_ICMP.h │ ├── sgIP_IP.c │ ├── sgIP_IP.h │ ├── sgIP_TCP.c │ ├── sgIP_TCP.h │ ├── sgIP_UDP.c │ ├── sgIP_UDP.h │ ├── sgIP_memblock.c │ ├── sgIP_memblock.h │ ├── sgIP_sockets.c │ ├── sgIP_sockets.h │ ├── template.c │ ├── wifi_arm9.c │ └── wifi_arm9.h ├── common └── source │ ├── dsregs.h │ ├── spinlock.h │ ├── spinlock.s │ └── wifi_shared.h ├── dswifi_license.txt ├── include ├── arpa │ └── inet.h ├── dswifi7.h ├── dswifi9.h ├── dswifi_version.h ├── netdb.h ├── netinet │ ├── in.h │ └── tcp.h └── sys │ └── socket.h └── nocash ├── DSLOADER.A22 ├── WIFIBOOT.A22 ├── WIFIBOOT.NDS ├── WIFIBOOT.SYM ├── WIFICORE.A22 ├── WIFICORE.~A2 └── WIFISDIO.A22 /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Object files 5 | *.o 6 | *.ko 7 | *.obj 8 | *.elf 9 | 10 | # Linker output 11 | *.ilk 12 | *.map 13 | *.exp 14 | 15 | # Precompiled Headers 16 | *.gch 17 | *.pch 18 | 19 | # Libraries 20 | *.lib 21 | *.a 22 | *.la 23 | *.lo 24 | 25 | # Shared objects (inc. Windows DLLs) 26 | *.dll 27 | *.so 28 | *.so.* 29 | *.dylib 30 | 31 | # Executables 32 | *.exe 33 | *.out 34 | *.app 35 | *.i*86 36 | *.x86_64 37 | *.hex 38 | 39 | # Debug files 40 | *.dSYM/ 41 | *.su 42 | *.idb 43 | *.pdb 44 | 45 | # Kernel Module Compile Results 46 | *.mod* 47 | *.cmd 48 | .tmp_versions/ 49 | modules.order 50 | Module.symvers 51 | Mkfile.old 52 | dkms.conf 53 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 ahezard 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ifeq ($(strip $(DEVKITPRO)),) 2 | $(error "Please set DEVKITPRO in your environment. export DEVKITPRO=devkitPro") 3 | endif 4 | 5 | export TOPDIR := $(CURDIR) 6 | 7 | export DSWIFI_MAJOR := 0 8 | export DSWIFI_MINOR := 1 9 | export DSWIFI_REVISION := 1 10 | 11 | VERSION := $(DSWIFI_MAJOR).$(DSWIFI_MINOR).$(DSWIFI_REVISION) 12 | 13 | .PHONY: release debug clean all 14 | 15 | all: include/dswifi_version.h release debug 16 | 17 | include/dswifi_version.h : Makefile 18 | @echo "#ifndef _dswifi_version_h_" > $@ 19 | @echo "#define _dswifi_version_h_" >> $@ 20 | @echo >> $@ 21 | @echo "#define DSWIFI_MAJOR $(DSWIFI_MAJOR)" >> $@ 22 | @echo "#define DSWIFI_MINOR $(DSWIFI_MINOR)" >> $@ 23 | @echo "#define DSWIFI_REVISION $(DSWIFI_REVISION)" >> $@ 24 | @echo >> $@ 25 | @echo '#define DSWIFI_VERSION "'$(DSWIFI_MAJOR).$(DSWIFI_MINOR).$(DSWIFI_REVISION)'"' >> $@ 26 | @echo >> $@ 27 | @echo "#endif // _dswifi_version_h_" >> $@ 28 | 29 | 30 | #------------------------------------------------------------------------------- 31 | release: lib 32 | #------------------------------------------------------------------------------- 33 | $(MAKE) -C arm9 BUILD=release 34 | $(MAKE) -C arm7 BUILD=release 35 | 36 | #------------------------------------------------------------------------------- 37 | debug: lib 38 | #------------------------------------------------------------------------------- 39 | $(MAKE) -C arm9 BUILD=debug 40 | $(MAKE) -C arm7 BUILD=debug 41 | 42 | #------------------------------------------------------------------------------- 43 | lib: 44 | #------------------------------------------------------------------------------- 45 | mkdir lib 46 | 47 | #------------------------------------------------------------------------------- 48 | clean: 49 | #------------------------------------------------------------------------------- 50 | @$(MAKE) -C arm9 clean 51 | @$(MAKE) -C arm7 clean 52 | @$(RM) -r dswifi-src-*.tar.bz2 dswifi-*.tar.bz2 include/dswifi_version.h lib 53 | 54 | #------------------------------------------------------------------------------- 55 | dist-src: 56 | #------------------------------------------------------------------------------- 57 | @tar --exclude=*CVS* --exclude=.svn -cjf dswifi-src-$(VERSION).tar.bz2 arm7/source arm7/Makefile arm9/source arm9/Makefile common include Makefile dswifi_license.txt 58 | 59 | #------------------------------------------------------------------------------- 60 | dist-bin: all 61 | #------------------------------------------------------------------------------- 62 | @tar --exclude=*CVS* --exclude=.svn -cjf dswifi-$(VERSION).tar.bz2 include lib dswifi_license.txt 63 | 64 | dist: dist-bin dist-src 65 | 66 | #------------------------------------------------------------------------------- 67 | install: dist-bin 68 | #------------------------------------------------------------------------------- 69 | bzip2 -cd dswifi-$(VERSION).tar.bz2 | tar -x -C $(DEVKITPRO)/libnds 70 | 71 | -------------------------------------------------------------------------------- /arm7/Makefile: -------------------------------------------------------------------------------- 1 | #--------------------------------------------------------------------------------- 2 | .SUFFIXES: 3 | #--------------------------------------------------------------------------------- 4 | ifeq ($(strip $(DEVKITARM)),) 5 | $(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM") 6 | endif 7 | 8 | include $(DEVKITARM)/ds_rules 9 | 10 | TOPDIR ?= $(CURDIR)/.. 11 | 12 | #--------------------------------------------------------------------------------- 13 | # BUILD is the directory where object files & intermediate files will be placed 14 | # SOURCES is a list of directories containing source code 15 | # INCLUDES is a list of directories containing extra header files 16 | # DATA is a list of directories containing binary files 17 | # all directories are relative to this makefile 18 | #--------------------------------------------------------------------------------- 19 | BUILD ?= release 20 | SOURCES := source ../common/source 21 | INCLUDES := include build ../common/source ../include 22 | DATA := 23 | 24 | #--------------------------------------------------------------------------------- 25 | # options for code generation 26 | #--------------------------------------------------------------------------------- 27 | ARCH := -mthumb-interwork 28 | 29 | CFLAGS := -g -Wall -Os\ 30 | -mcpu=arm7tdmi -mtune=arm7tdmi -fomit-frame-pointer\ 31 | -ffast-math \ 32 | $(ARCH) 33 | 34 | CFLAGS += $(INCLUDE) -DARM7 35 | CXXFLAGS := $(CFLAGS) 36 | 37 | 38 | ASFLAGS := -g $(ARCH) 39 | LDFLAGS = -specs=ds_arm7.specs -g $(ARCH) -Wl,-Map,$(notdir $*).map 40 | 41 | 42 | ifneq ($(BUILD),debug) 43 | export ARM7BIN := $(TOPDIR)/lib/libnodsiwifi7.a 44 | else 45 | export ARM7BIN := $(TOPDIR)/lib/libnodsiwifi7d.a 46 | CFLAGS += -DSGIP_DEBUG 47 | endif 48 | 49 | 50 | LIBS := 51 | #-lnds7 52 | 53 | #--------------------------------------------------------------------------------- 54 | # list of directories containing libraries, this must be the top level containing 55 | # include and lib 56 | #--------------------------------------------------------------------------------- 57 | LIBDIRS := $(LIBNDS) 58 | 59 | 60 | #--------------------------------------------------------------------------------- 61 | # no real need to edit anything past this point unless you need to add additional 62 | # rules for different file extensions 63 | #--------------------------------------------------------------------------------- 64 | ifneq ($(BUILD),$(notdir $(CURDIR))) 65 | #--------------------------------------------------------------------------------- 66 | 67 | export DEPSDIR := $(CURDIR)/$(BUILD) 68 | 69 | export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) 70 | 71 | export CC := $(PREFIX)gcc 72 | export CXX := $(PREFIX)g++ 73 | export AR := $(PREFIX)ar 74 | export OBJCOPY := $(PREFIX)objcopy 75 | 76 | CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) 77 | CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) 78 | SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) 79 | BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) 80 | 81 | export OFILES := $(addsuffix .o,$(BINFILES)) \ 82 | $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) 83 | 84 | export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ 85 | $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ 86 | -I$(CURDIR)/$(BUILD) 87 | 88 | export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) 89 | 90 | #--------------------------------------------------------------------------------- 91 | # use CXX for linking C++ projects, CC for standard C 92 | #--------------------------------------------------------------------------------- 93 | ifeq ($(strip $(CPPFILES)),) 94 | #--------------------------------------------------------------------------------- 95 | export LD := $(CC) 96 | #--------------------------------------------------------------------------------- 97 | else 98 | #--------------------------------------------------------------------------------- 99 | export LD := $(CXX) 100 | #--------------------------------------------------------------------------------- 101 | endif 102 | #--------------------------------------------------------------------------------- 103 | 104 | .PHONY: $(BUILD) clean 105 | 106 | #--------------------------------------------------------------------------------- 107 | $(BUILD): 108 | @[ -d $@ ] || mkdir -p $@ 109 | @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile 110 | 111 | #--------------------------------------------------------------------------------- 112 | clean: 113 | @echo clean ... 114 | @rm -fr debug release 115 | @rm -f $(TOPDIR)/lib/libdswifi7* 116 | 117 | all: $(ARM7BIN) 118 | 119 | #--------------------------------------------------------------------------------- 120 | else 121 | 122 | DEPENDS := $(OFILES:.o=.d) 123 | 124 | #--------------------------------------------------------------------------------- 125 | # main targets 126 | #--------------------------------------------------------------------------------- 127 | $(ARM7BIN) : $(OFILES) 128 | @rm -f "$(ARM7BIN)" 129 | @$(AR) rcs "$(ARM7BIN)" $(OFILES) 130 | @echo built ... $(notdir $@) 131 | 132 | 133 | #--------------------------------------------------------------------------------- 134 | # you need a rule like this for each extension you use as binary data 135 | #--------------------------------------------------------------------------------- 136 | %.bin.o : %.bin 137 | #--------------------------------------------------------------------------------- 138 | @echo $(notdir $<) 139 | @$(bin2o) 140 | 141 | -include $(DEPENDS) 142 | 143 | #--------------------------------------------------------------------------------------- 144 | endif 145 | #--------------------------------------------------------------------------------------- 146 | -------------------------------------------------------------------------------- /arm7/source/wifi_arm7.h: -------------------------------------------------------------------------------- 1 | // DS Wifi interface code 2 | // Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org 3 | // wifi_arm7.h - arm7 wifi interface header 4 | /****************************************************************************** 5 | DSWifi Lib and test materials are licenced under the MIT open source licence: 6 | Copyright (c) 2005-2006 Stephen Stair 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy of 9 | this software and associated documentation files (the "Software"), to deal in 10 | the Software without restriction, including without limitation the rights to 11 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 12 | of the Software, and to permit persons to whom the Software is furnished to do 13 | so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in all 16 | copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | SOFTWARE. 25 | ******************************************************************************/ 26 | 27 | #ifndef WIFI_ARM7_H 28 | #define WIFI_ARM7_H 29 | 30 | #ifndef ARM7 31 | #error Wifi is only accessible from the ARM7 32 | #endif 33 | 34 | // keepalive updated in the update handler, which should be called in vblank 35 | // keepalive set for 2 minutes. 36 | #define WIFI_KEEPALIVE_COUNT 60*128 // orig (60*60*2) keepalive set for about 2 minutes 37 | 38 | //#ifdef with_nds_wifi 39 | #define WIFI_REG(ofs) (*((volatile u16 *)(0x04800000+(ofs)))) 40 | // Wifi regs 41 | #define W_WEPKEY0 (((volatile u16 *)(0x04805F80))) 42 | #define W_WEPKEY1 (((volatile u16 *)(0x04805FA0))) 43 | #define W_WEPKEY2 (((volatile u16 *)(0x04805FC0))) 44 | #define W_WEPKEY3 (((volatile u16 *)(0x04805FE0))) 45 | 46 | //--- 47 | // note: original code used hardcoded hex numbers for the Wifi RAM addresses, 48 | // below constants should make it more clear how the Wifi RAM is mapped: 49 | #define WIFIRAM_TX_LOC3_START equ 0000h ;\TX packet (960h bytes, 2400 decimal) 50 | #define WIFIRAM_TX_LOC3_SIZE equ 0960h ;/ 51 | #define WIFIRAM_TX_BEACON_START equ 0960h ;\TX beacon (2A0h bytes, 672 decimal) 52 | #define WIFIRAM_TX_BEACON_SIZE equ 02A0h ;/ 53 | #define WIFIRAM_RX_BUFFER_START equ 0C00h ;\RX packets (1360h bytes, 4960 decimal) 54 | #define WIFIRAM_RX_BUFFER_SIZE equ 1360h-20h ;/ ;XXX "-20" for better align (for use as shifted 8bit ARM immediate) 55 | #define WIFIRAM_SOMETHING_START equ 1F60h ;-used for something (by hardware?) 56 | #define WIFIRAM_WEP_KEY_START equ 1F80h ;-used for WEP keys (by hardware) 57 | #define WIFIRAM_TOTAL_SIZE equ 2000h ;-end of 8Kbyte Wifi RAM 58 | #define WIFIRAM_BASE32 equ 4804000h ;\base address for Wifi RAM (as 32bit 59 | #define WIFIRAM_BASE16 equ 4000h ;/ARM address, and 16bit Wifi address) 60 | //#endif //with_nds_wifi 61 | //------------------ 62 | //------------------ 63 | // BUGGED: below uses wrong waitstate area (4800xxxh instead 4808xxxh) 64 | // and, below is totally INCOMPLETE, and doesn't comply with gbatek names 65 | // TODO : comment definition below 66 | #define W_MODE_RST (*((volatile u16 *)(0x04800004))) 67 | #define W_MODE_WEP (*((volatile u16 *)(0x04800006))) 68 | #define W_IF (*((volatile u16 *)(0x04800010))) 69 | #define W_IE (*((volatile u16 *)(0x04800012))) 70 | #define W_MACADDR (((volatile u16 *)(0x04800018))) 71 | #define W_BSSID (((volatile u16 *)(0x04800020))) 72 | #define W_AIDS (*((volatile u16 *)(0x04800028))) 73 | #define W_RETRLIMIT (*((volatile u16 *)(0x0480002C))) 74 | #define W_POWERSTATE (*((volatile u16 *)(0x0480003C))) 75 | #define W_RANDOM (*((volatile u16 *)(0x04800044))) 76 | 77 | #define W_BBSIOCNT (*((volatile u16 *)(0x04800158))) 78 | #define W_BBSIOWRITE (*((volatile u16 *)(0x0480015A))) 79 | #define W_BBSIOREAD (*((volatile u16 *)(0x0480015C))) 80 | #define W_BBSIOBUSY (*((volatile u16 *)(0x0480015E))) 81 | #define W_RFSIODATA2 (*((volatile u16 *)(0x0480017C))) 82 | #define W_RFSIODATA1 (*((volatile u16 *)(0x0480017E))) 83 | #define W_RFSIOBUSY (*((volatile u16 *)(0x04800180))) 84 | 85 | 86 | 87 | 88 | 89 | 90 | #include "wifi_shared.h" 91 | 92 | extern volatile Wifi_MainStruct * WifiData; 93 | 94 | // Wifi Sync Handler function: Callback function that is called when the arm9 needs to be told to synchronize with new fifo data. 95 | // If this callback is used (see Wifi_SetSyncHandler()), it should send a message via the fifo to the arm9, which will call Wifi_Sync() on arm9. 96 | typedef void (*WifiSyncHandler)(); 97 | 98 | 99 | #ifdef __cplusplus 100 | extern "C" { 101 | #endif 102 | 103 | 104 | 105 | extern void Read_Flash(int address, char * destination, int length); 106 | extern void InitFlashData(); 107 | extern int ReadFlashByte(int address); 108 | extern int ReadFlashHWord(int address); 109 | extern int ReadFlashBytes(int address, int numbytes); 110 | 111 | extern int Wifi_BBRead(int a); 112 | extern int Wifi_BBWrite(int a, int b); 113 | extern void Wifi_RFWrite(int writedata); 114 | 115 | extern void Wifi_RFInit(); 116 | extern void Wifi_BBInit(); 117 | extern void Wifi_WakeUp(); 118 | extern void Wifi_Shutdown(); 119 | extern void Wifi_MacInit(); 120 | extern void Wifi_Interrupt(); 121 | extern void Wifi_Update(); 122 | 123 | extern void Wifi_CopyMacAddr(volatile void * dest, volatile void * src); 124 | extern int Wifi_CmpMacAddr(volatile void * mac1, volatile void * mac2); 125 | 126 | extern void Wifi_Init(u32 WifiData); 127 | extern void Wifi_Deinit(); 128 | extern void Wifi_Start(); 129 | extern void Wifi_Stop(); 130 | extern void Wifi_SetChannel(int channel); 131 | extern void Wifi_SetWepKey(void * wepkey); 132 | extern void Wifi_SetWepMode(int wepmode); 133 | extern void Wifi_SetBeaconPeriod(int beacon_period); 134 | extern void Wifi_SetMode(int wifimode); 135 | extern void Wifi_SetPreambleType(int preamble_type); 136 | extern void Wifi_TxSetup(); 137 | extern void Wifi_RxSetup(); 138 | extern void Wifi_DisableTempPowerSave(); 139 | 140 | extern int Wifi_SendOpenSystemAuthPacket(); 141 | extern int Wifi_SendAssocPacket(); 142 | extern int Wifi_SendNullFrame(); 143 | extern int Wifi_SendPSPollFrame(); 144 | extern int Wifi_ProcessReceivedFrame(int macbase, int framelen); 145 | 146 | extern void Wifi_Sync(); 147 | extern void Wifi_SetSyncHandler(WifiSyncHandler sh); 148 | 149 | 150 | #ifdef __cplusplus 151 | }; 152 | #endif 153 | 154 | 155 | #endif 156 | -------------------------------------------------------------------------------- /arm9/Makefile: -------------------------------------------------------------------------------- 1 | #--------------------------------------------------------------------------------- 2 | .SUFFIXES: 3 | #--------------------------------------------------------------------------------- 4 | ifeq ($(strip $(DEVKITARM)),) 5 | $(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM") 6 | endif 7 | 8 | include $(DEVKITARM)/ds_rules 9 | 10 | TOPDIR ?= $(CURDIR)/.. 11 | 12 | #--------------------------------------------------------------------------------- 13 | # BUILD is the directory where object files & intermediate files will be placed 14 | # SOURCES is a list of directories containing source code 15 | # INCLUDES is a list of directories containing extra header files 16 | # DATA is a list of directories containing binary files 17 | # all directories are relative to this makefile 18 | #--------------------------------------------------------------------------------- 19 | BUILD ?= release 20 | SOURCES := source ../common/source 21 | INCLUDES := include ../common/source ../include 22 | DATA := data 23 | 24 | #--------------------------------------------------------------------------------- 25 | # options for code generation 26 | #--------------------------------------------------------------------------------- 27 | ARCH := -mthumb -mthumb-interwork 28 | 29 | CFLAGS := -g -Wall -Os\ 30 | -march=armv5te -mtune=arm946e-s -fomit-frame-pointer\ 31 | -ffast-math \ 32 | $(ARCH) 33 | 34 | CFLAGS += $(INCLUDE) -DARM9 35 | CXXFLAGS := $(CFLAGS) 36 | 37 | ASFLAGS := -g $(ARCH) 38 | LDFLAGS = -specs=ds_arm9.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) 39 | 40 | ifneq ($(BUILD),debug) 41 | export ARM9BIN := $(TOPDIR)/lib/libnodsiwifi9.a 42 | else 43 | export ARM9BIN := $(TOPDIR)/lib/libnodsiwifi9d.a 44 | CFLAGS += -DSGIP_DEBUG 45 | endif 46 | 47 | 48 | #--------------------------------------------------------------------------------- 49 | # any extra libraries we wish to link with the project 50 | #--------------------------------------------------------------------------------- 51 | LIBS := 52 | #-lnds9 53 | 54 | #--------------------------------------------------------------------------------- 55 | # list of directories containing libraries, this must be the top level containing 56 | # include and lib 57 | #--------------------------------------------------------------------------------- 58 | LIBDIRS := $(LIBNDS) 59 | 60 | #--------------------------------------------------------------------------------- 61 | # no real need to edit anything past this point unless you need to add additional 62 | # rules for different file extensions 63 | #--------------------------------------------------------------------------------- 64 | ifneq ($(BUILD),$(notdir $(CURDIR))) 65 | #--------------------------------------------------------------------------------- 66 | 67 | 68 | export DEPSDIR := $(CURDIR)/$(BUILD) 69 | 70 | export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ 71 | $(foreach dir,$(DATA),$(CURDIR)/$(dir)) 72 | 73 | export CC := $(PREFIX)gcc 74 | export CXX := $(PREFIX)g++ 75 | export AR := $(PREFIX)ar 76 | export OBJCOPY := $(PREFIX)objcopy 77 | 78 | CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) 79 | CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) 80 | SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) 81 | BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) 82 | 83 | #--------------------------------------------------------------------------------- 84 | # use CXX for linking C++ projects, CC for standard C 85 | #--------------------------------------------------------------------------------- 86 | ifeq ($(strip $(CPPFILES)),) 87 | #--------------------------------------------------------------------------------- 88 | export LD := $(CC) 89 | #--------------------------------------------------------------------------------- 90 | else 91 | #--------------------------------------------------------------------------------- 92 | export LD := $(CXX) 93 | #--------------------------------------------------------------------------------- 94 | endif 95 | #--------------------------------------------------------------------------------- 96 | 97 | export OFILES := $(addsuffix .o,$(BINFILES)) \ 98 | $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) 99 | 100 | export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ 101 | $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ 102 | $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ 103 | -I$(CURDIR)/$(BUILD) 104 | 105 | export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) 106 | 107 | .PHONY: $(BUILD) clean 108 | 109 | #--------------------------------------------------------------------------------- 110 | $(BUILD): 111 | @[ -d $@ ] || mkdir -p $@ 112 | @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile 113 | 114 | #--------------------------------------------------------------------------------- 115 | clean: 116 | @echo clean ... 117 | @rm -fr debug release 118 | @rm -f $(TOPDIR)/lib/libdswifi9* 119 | 120 | all: $(ARM9BIN) 121 | 122 | #--------------------------------------------------------------------------------- 123 | else 124 | 125 | DEPENDS := $(OFILES:.o=.d) 126 | 127 | #--------------------------------------------------------------------------------- 128 | # main targets 129 | #--------------------------------------------------------------------------------- 130 | $(ARM9BIN) : $(OFILES) 131 | @rm -f "$(ARM9BIN)" 132 | @$(AR) rcs "$(ARM9BIN)" $(OFILES) 133 | @echo built ... $(notdir $@) 134 | 135 | #--------------------------------------------------------------------------------- 136 | # you need a rule like this for each extension you use as binary data 137 | #--------------------------------------------------------------------------------- 138 | %.bin.o : %.bin 139 | #--------------------------------------------------------------------------------- 140 | @echo $(notdir $<) 141 | @$(bin2o) 142 | 143 | 144 | -include $(DEPENDS) 145 | 146 | #--------------------------------------------------------------------------------------- 147 | endif 148 | #--------------------------------------------------------------------------------------- 149 | -------------------------------------------------------------------------------- /arm9/source/sgIP.c: -------------------------------------------------------------------------------- 1 | // DSWifi Project - sgIP Internet Protocol Stack Implementation 2 | // Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org 3 | /****************************************************************************** 4 | DSWifi Lib and test materials are licenced under the MIT open source licence: 5 | Copyright (c) 2005-2006 Stephen Stair 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | this software and associated documentation files (the "Software"), to deal in 9 | the Software without restriction, including without limitation the rights to 10 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 11 | of the Software, and to permit persons to whom the Software is furnished to do 12 | so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | ******************************************************************************/ 25 | 26 | #include "sgIP.h" 27 | 28 | unsigned long volatile sgIP_timems; 29 | int sgIP_errno; 30 | 31 | // sgIP_Init(): Initializes sgIP hub and sets up a default surrounding interface (ARP and IP) 32 | void sgIP_Init() { 33 | sgIP_timems = 0; 34 | sgIP_memblock_Init(); 35 | sgIP_Hub_Init(); 36 | sgIP_sockets_Init(); 37 | sgIP_ARP_Init(); 38 | sgIP_TCP_Init(); 39 | sgIP_UDP_Init(); 40 | sgIP_DNS_Init(); 41 | sgIP_DHCP_Init(); 42 | sgIP_Hub_AddProtocolInterface(PROTOCOL_ETHER_IP,&sgIP_IP_ReceivePacket,0); 43 | } 44 | 45 | 46 | unsigned long count_100ms; 47 | unsigned long count_1000ms; 48 | void sgIP_Timer(int num_ms) { 49 | sgIP_timems+=num_ms; 50 | count_100ms+=num_ms; 51 | if(count_100ms>=100) { 52 | count_100ms-=100; 53 | if(count_100ms>=100) count_100ms=0; 54 | sgIP_ARP_Timer100ms(); 55 | } 56 | count_1000ms+=num_ms; 57 | if(count_1000ms>=1000) { 58 | count_1000ms-=1000; 59 | if(count_1000ms>=1000) count_1000ms=0; 60 | sgIP_DNS_Timer1000ms(); 61 | sgIP_sockets_Timer1000ms(); 62 | } 63 | sgIP_TCP_Timer(); 64 | } 65 | 66 | -------------------------------------------------------------------------------- /arm9/source/sgIP.h: -------------------------------------------------------------------------------- 1 | // DSWifi Project - sgIP Internet Protocol Stack Implementation 2 | // Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org 3 | /****************************************************************************** 4 | DSWifi Lib and test materials are licenced under the MIT open source licence: 5 | Copyright (c) 2005-2006 Stephen Stair 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | this software and associated documentation files (the "Software"), to deal in 9 | the Software without restriction, including without limitation the rights to 10 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 11 | of the Software, and to permit persons to whom the Software is furnished to do 12 | so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | ******************************************************************************/ 25 | 26 | 27 | #ifndef SGIP_H 28 | #define SGIP_H 29 | 30 | #include "sgIP_Config.h" 31 | #include "sgIP_memblock.h" 32 | #include "sgIP_sockets.h" 33 | #include "sgIP_Hub.h" 34 | #include "sgIP_IP.h" 35 | #include "sgIP_ARP.h" 36 | #include "sgIP_ICMP.h" 37 | #include "sgIP_TCP.h" 38 | #include "sgIP_UDP.h" 39 | #include "sgIP_DNS.h" 40 | #include "sgIP_DHCP.h" 41 | 42 | extern unsigned long volatile sgIP_timems; 43 | 44 | #ifdef __cplusplus 45 | extern "C" { 46 | #endif 47 | 48 | void sgIP_Init(); 49 | void sgIP_Timer(int num_ms); 50 | 51 | 52 | #ifdef __cplusplus 53 | }; 54 | #endif 55 | 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /arm9/source/sgIP_ARP.c: -------------------------------------------------------------------------------- 1 | // DSWifi Project - sgIP Internet Protocol Stack Implementation 2 | // Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org 3 | /****************************************************************************** 4 | DSWifi Lib and test materials are licenced under the MIT open source licence: 5 | Copyright (c) 2005-2006 Stephen Stair 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | this software and associated documentation files (the "Software"), to deal in 9 | the Software without restriction, including without limitation the rights to 10 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 11 | of the Software, and to permit persons to whom the Software is furnished to do 12 | so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | ******************************************************************************/ 25 | 26 | // BUGGED: original code doesn't disable IRQs in any ARP functions, so that ARP 27 | // functions called by user code could collide with ARP functions called from 28 | // IRQ handlers. That can cause several problems: Twice allocating the SAME 29 | // "unused" ARP record by different functions, or trying to process incompletely 30 | // initialized/modified ARP records. 31 | // sgIP_ARP_SendGratARP ;\were called with IRQs enabled 32 | // sgIP_ARP_FlushInterface ;/ 33 | // sgIP_ARP_ProcessARPFrame ;\were usually/always called with IRQs disabled 34 | // sgIP_ARP_SendProtocolFrame ;/ 35 | // just to be sure, it's best to disable IRQs in all of the above four functions 36 | //------------------ 37 | 38 | #include "sgIP_ARP.h" 39 | 40 | sgIP_ARP_Record ArpRecords[SGIP_ARP_MAXENTRIES]; 41 | 42 | int sgIP_FindArpSlot(sgIP_Hub_HWInterface * hw, unsigned long destip) { 43 | int i; 44 | for(i=0;iqueued_packet) sgIP_memblock_free(ArpRecord->queued_packet); 85 | ArpRecord->flags=0; 86 | ArpRecord->retrycount=0; 87 | ArpRecord->idletime=0; 88 | ArpRecord->queued_packet=0; 89 | } 90 | 91 | // differences to original library: 92 | //* renamed to "sgIP_ARP_GetUnusedArpSlot" (instead of "sgIP_GetArpSlot") 93 | int sgIP_ARP_GetUnusedArpSlot() { 94 | int i,m,midle; 95 | m=0; 96 | midle=0; 97 | for(i=0;i=midle) { 100 | midle=ArpRecords[i].idletime; m=i; 101 | } 102 | } else { 103 | return i; 104 | } 105 | } 106 | // this slot *was* in use, so let's fix that situation. 107 | sgIP_ARP_DiscardArpSlot(ArpRecords+m); 108 | return m; 109 | } 110 | 111 | int sgIP_is_broadcast_address(sgIP_Hub_HWInterface * hw, unsigned long ipaddr) { 112 | if((hw->snmask | ipaddr) == 0xFFFFFFFF) return 1; 113 | return 0; 114 | } 115 | 116 | // this function will protect against malformed packets that could cause internal problems. 117 | int sgIP_ARP_Check_isok(sgIP_Hub_HWInterface * hw, sgIP_memblock * mb, sgIP_Header_ARP * arp) { 118 | return 1; // doesn't do anything yet ;) 119 | } 120 | 121 | void sgIP_ARP_Init() { 122 | int i; 123 | for(i=0;i125) { // it's a lost cause. 138 | sgIP_ARP_DiscardArpSlot(ArpRecords+i); 139 | continue; 140 | } 141 | if((ArpRecords[i].retrycount&7)==7) { // attempt retransmit of ARP frame. 142 | sgIP_ARP_SendARPRequest(ArpRecords[i].linked_interface, ArpRecords[i].linked_protocol, ArpRecords[i].protocol_address); 143 | } 144 | } 145 | } 146 | } 147 | } 148 | 149 | void sgIP_ARP_FlushInterface(sgIP_Hub_HWInterface * hw) { 150 | int i; 151 | 152 | int oldIME = enterCriticalSection(); 153 | 154 | for(i=0;idatastart; 176 | 177 | if(!sgIP_ARP_Check_isok(hw,mb,arp)) { 178 | sgIP_memblock_free(mb); 179 | leaveCriticalSection(oldIME); 180 | return 0; // error - arp header incorrect somehow. 181 | } 182 | sgIP_memblock_exposeheader(mb,14); // re-expose 14 bytes at the start... 183 | 184 | if(htons(arp->opcode)==1) { // request 185 | // requested IP 186 | ip = arp->addresses[arp->hw_addr_len*2+4+0]+(arp->addresses[arp->hw_addr_len*2+4+1]<<8)+(arp->addresses[arp->hw_addr_len*2+4+2]<<16)+(arp->addresses[arp->hw_addr_len*2+4+3]<<24); 187 | SGIP_DEBUG_MESSAGE(("ARP: request IP %08X",ip)); 188 | if(ip==hw->ipaddr) {// someone's asking for our info, toss them a reply. 189 | sgIP_ARP_SendARPResponse(hw,mb); 190 | leaveCriticalSection(oldIME); 191 | return 0; 192 | } 193 | } 194 | if(htons(arp->opcode)==2) { // response 195 | // sender IP 196 | ip = arp->addresses[arp->hw_addr_len+0]+(arp->addresses[arp->hw_addr_len+1]<<8)+(arp->addresses[arp->hw_addr_len+2]<<16)+(arp->addresses[arp->hw_addr_len+3]<<24); 197 | i=sgIP_FindArpSlot(hw,ip); 198 | if(i!=-1) { // we've been waiting for you... 199 | for(j=0;jhw_addr_len;j++) ArpRecords[i].hw_address[j]=arp->addresses[j]; 200 | ArpRecords[i].flags|=SGIP_ARP_FLAG_HAVEHWADDR; 201 | sgIP_memblock * mb2; 202 | mb2=ArpRecords[i].queued_packet; 203 | ArpRecords[i].queued_packet=0; 204 | if(mb2) sgIP_ARP_SendProtocolFrame(hw,mb2,ArpRecords[i].linked_protocol,ip); 205 | } 206 | } 207 | 208 | sgIP_memblock_free(mb); 209 | 210 | leaveCriticalSection(oldIME); 211 | return 0; 212 | } 213 | int sgIP_ARP_SendProtocolFrame(sgIP_Hub_HWInterface * hw, sgIP_memblock * mb, unsigned short protocol, unsigned long destaddr) { 214 | int i,j; 215 | int m; 216 | sgIP_Header_Ethernet * ether; 217 | if(!hw || !mb) return 0; 218 | 219 | int oldIME = enterCriticalSection(); 220 | 221 | sgIP_memblock_exposeheader(mb,14); // add 14 bytes at the start for the header 222 | 223 | if(sgIP_is_broadcast_address(hw,destaddr)) { 224 | // construct ethernet header 225 | ether = (sgIP_Header_Ethernet *) mb->datastart; 226 | for(j=0;j<6;j++) { 227 | ether->src_mac[j] = hw->hwaddr[j]; 228 | ether->dest_mac[j]= 0xFF; // broadcast destination 229 | } 230 | ether->protocol=protocol; 231 | int ret = sgIP_Hub_SendRawPacket(hw,mb); // this function will free the memory block when it's done. 232 | leaveCriticalSection(oldIME); 233 | return ret; 234 | } 235 | 236 | i=sgIP_FindArpSlot(hw,destaddr); 237 | if(i!=-1) { 238 | if(ArpRecords[i].flags & SGIP_ARP_FLAG_HAVEHWADDR) { // we have the adddress 239 | ArpRecords[i].idletime=0; 240 | // construct ethernet header 241 | ether = (sgIP_Header_Ethernet *) mb->datastart; 242 | for(j=0;j<6;j++) { 243 | ether->src_mac[j] = hw->hwaddr[j]; 244 | ether->dest_mac[j]= ArpRecords[i].hw_address[j]; 245 | } 246 | ether->protocol=protocol; 247 | int ret = sgIP_Hub_SendRawPacket(hw,mb); // this function will free the memory block when it's done. 248 | leaveCriticalSection(oldIME); 249 | return ret; 250 | } else { // we don't have the address, but are looking for it. 251 | if(ArpRecords[i].queued_packet) { // if there is already a queued packet, reject the new one. 252 | sgIP_memblock_free(mb); 253 | leaveCriticalSection(oldIME); 254 | return 0; // couldn't send. 255 | } else { 256 | sgIP_memblock_exposeheader(mb,-14); // re-hide ethernet header. 257 | ArpRecords[i].queued_packet=mb; // queue packet. 258 | ArpRecords[i].linked_protocol=protocol; // queue packet. 259 | leaveCriticalSection(oldIME); 260 | return 0; 261 | } 262 | } 263 | } 264 | m=sgIP_GetArpSlot(); // gets and cleans out an arp slot for us 265 | // build new record 266 | ArpRecords[m].flags=SGIP_ARP_FLAG_ACTIVE; 267 | ArpRecords[m].idletime=0; 268 | ArpRecords[m].retrycount=0; 269 | ArpRecords[m].linked_interface=hw; 270 | ArpRecords[m].protocol_address=destaddr; 271 | sgIP_memblock_exposeheader(mb,-14); // re-hide ethernet header. 272 | ArpRecords[m].queued_packet=mb; 273 | ArpRecords[m].linked_protocol=protocol; 274 | sgIP_ARP_SendARPRequest(hw,protocol,destaddr); 275 | 276 | leaveCriticalSection(oldIME); 277 | 278 | return 0; // queued, but not sent yet. 279 | } 280 | 281 | int sgIP_ARP_SendARPResponse(sgIP_Hub_HWInterface * hw, sgIP_memblock * mb) { 282 | int i; 283 | if(!hw || !mb) return 0; 284 | sgIP_memblock_exposeheader(mb,-14); // hide 14 bytes at the start temporarily... 285 | 286 | // Repurpose existing ARP packet 287 | sgIP_Header_ARP * arp = (sgIP_Header_ARP *) mb->datastart; 288 | if(!sgIP_ARP_Check_isok(hw,mb,arp)) { 289 | sgIP_memblock_free(mb); 290 | return 0; // error - arp header incorrect somehow. 291 | } 292 | 293 | if(arp->hw_addr_len!=hw->hwaddrlen || arp->protocol_addr_len!=4) { 294 | // eek! can't send it back in this sorry state! 295 | sgIP_memblock_free(mb); 296 | return 0; 297 | } 298 | 299 | arp->opcode=htons(2); // response 300 | for(i=0;ihwaddrlen;i++) arp->addresses[i+4+hw->hwaddrlen]=arp->addresses[i]; // copy src hw addr 301 | for(i=0;i<4;i++) arp->addresses[i+(hw->hwaddrlen)*2+4]=arp->addresses[i+hw->hwaddrlen]; 302 | for(i=0;ihwaddrlen;i++) arp->addresses[i]=hw->hwaddr[i]; 303 | for(i=0;i<4;i++) arp->addresses[i+(hw->hwaddrlen)]=(hw->ipaddr>>(i*8))&255; 304 | 305 | // construct ethernet header 306 | sgIP_memblock_exposeheader(mb,14); // add 14 bytes at the start for the header 307 | sgIP_Header_Ethernet * ether = (sgIP_Header_Ethernet *) mb->datastart; 308 | for(i=0;i<6;i++) { 309 | ether->src_mac[i] = hw->hwaddr[i]; 310 | ether->dest_mac[i]= arp->addresses[i+4+hw->hwaddrlen]; // requesting party 311 | } 312 | ether->protocol=htons(0x0806); // ARP protocol 313 | 314 | // Send ethernet packet 315 | return sgIP_Hub_SendRawPacket(hw,mb); // this function will free the memory block when it's done. 316 | } 317 | int sgIP_ARP_SendGratARP(sgIP_Hub_HWInterface * hw) { 318 | int i; 319 | 320 | if(!hw) return 0; 321 | 322 | int oldIME = enterCriticalSection(); 323 | 324 | sgIP_memblock * mb = sgIP_memblock_alloc(SGIP_HEADER_ARP_BASESIZE+2*4 + 2*hw->hwaddrlen); 325 | 326 | if(!mb) { 327 | leaveCriticalSection(oldIME); 328 | return 0; 329 | } 330 | 331 | // Construct ARP packet 332 | sgIP_Header_ARP * arp = (sgIP_Header_ARP *) mb->datastart; 333 | arp->hwspace=htons(1); // ethernet 334 | arp->protocol=htons(0x0800); 335 | arp->opcode=htons(2); // response 336 | arp->hw_addr_len=hw->hwaddrlen; 337 | arp->protocol_addr_len= 4; 338 | for(i=0;ihwaddrlen;i++) arp->addresses[i]=hw->hwaddr[i]; 339 | for(i=0;i<4;i++) arp->addresses[i+hw->hwaddrlen]=(hw->ipaddr>>(i*8))&255; 340 | for(i=0;ihwaddrlen;i++) arp->addresses[i+4+hw->hwaddrlen]=hw->hwaddr[i]; 341 | for(i=0;i<4;i++) arp->addresses[i+hw->hwaddrlen*2+4]=(hw->ipaddr>>(i*8))&255; 342 | 343 | // construct ethernet header 344 | sgIP_memblock_exposeheader(mb,14); // add 14 bytes at the start for the header 345 | sgIP_Header_Ethernet * ether = (sgIP_Header_Ethernet *) mb->datastart; 346 | for(i=0;i<6;i++) { 347 | ether->src_mac[i] = hw->hwaddr[i]; 348 | ether->dest_mac[i]= 0xFF; // broadcast packet 349 | } 350 | ether->protocol=htons(0x0806); // ARP protocol 351 | int ret = sgIP_Hub_SendRawPacket(hw,mb); 352 | 353 | leaveCriticalSection(oldIME); 354 | 355 | // Send ethernet packet 356 | return ret; // this function will free the memory block when it's done. 357 | } 358 | int sgIP_ARP_SendARPRequest(sgIP_Hub_HWInterface * hw, int protocol, unsigned long protocol_addr) { 359 | int i; 360 | if(!hw) return 0; 361 | sgIP_memblock * mb = sgIP_memblock_alloc(SGIP_HEADER_ARP_BASESIZE+2*4 + 2*hw->hwaddrlen); 362 | if(!mb) return 0; 363 | 364 | // Construct ARP packet 365 | sgIP_Header_ARP * arp = (sgIP_Header_ARP *) mb->datastart; 366 | arp->hwspace=htons(1); // 1=ethernet 367 | arp->protocol=(protocol); 368 | arp->opcode=htons(1); // 1=request 369 | arp->hw_addr_len=hw->hwaddrlen; 370 | arp->protocol_addr_len= 4; 371 | for(i=0;ihwaddrlen;i++) arp->addresses[i]=hw->hwaddr[i]; 372 | for(i=0;i<4;i++) arp->addresses[i+hw->hwaddrlen]=(hw->ipaddr>>(i*8))&255; 373 | for(i=0;ihwaddrlen;i++) arp->addresses[i+4+hw->hwaddrlen]=0; 374 | for(i=0;i<4;i++) arp->addresses[i+hw->hwaddrlen*2+4]=(protocol_addr>>(i*8))&255; 375 | 376 | // construct ethernet header 377 | sgIP_memblock_exposeheader(mb,14); // add 14 bytes at the start for the header 378 | sgIP_Header_Ethernet * ether = (sgIP_Header_Ethernet *) mb->datastart; 379 | for(i=0;i<6;i++) { 380 | ether->src_mac[i] = hw->hwaddr[i]; 381 | ether->dest_mac[i]= 0xFF; // broadcast packet 382 | } 383 | ether->protocol=htons(0x0806); // ARP protocol 384 | 385 | // Send ethernet packet 386 | return sgIP_Hub_SendRawPacket(hw,mb); // this function will free the memory block when it's done. 387 | } 388 | -------------------------------------------------------------------------------- /arm9/source/sgIP_ARP.h: -------------------------------------------------------------------------------- 1 | // DSWifi Project - sgIP Internet Protocol Stack Implementation 2 | // Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org 3 | /****************************************************************************** 4 | DSWifi Lib and test materials are licenced under the MIT open source licence: 5 | Copyright (c) 2005-2006 Stephen Stair 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | this software and associated documentation files (the "Software"), to deal in 9 | the Software without restriction, including without limitation the rights to 10 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 11 | of the Software, and to permit persons to whom the Software is furnished to do 12 | so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | ******************************************************************************/ 25 | #ifndef SGIP_ARP_H 26 | #define SGIP_ARP_H 27 | 28 | #include "sgIP_Config.h" 29 | #include "sgIP_memblock.h" 30 | #include "sgIP_Hub.h" 31 | 32 | #define SGIP_ARP_FLAG_ACTIVE 0x0001 33 | #define SGIP_ARP_FLAG_HAVEHWADDR 0x0002 34 | 35 | typedef struct SGIP_ARP_RECORD { 36 | unsigned short flags, retrycount; 37 | unsigned long idletime; 38 | sgIP_Hub_HWInterface * linked_interface; 39 | sgIP_memblock * queued_packet; 40 | int linked_protocol; 41 | unsigned long protocol_address; 42 | char hw_address[SGIP_MAXHWADDRLEN]; 43 | } sgIP_ARP_Record; 44 | 45 | 46 | typedef struct SGIP_HEADER_ARP { 47 | unsigned short hwspace; // ethernet=1; 48 | unsigned short protocol; 49 | unsigned char hw_addr_len; 50 | unsigned char protocol_addr_len; 51 | unsigned short opcode; // request=1, reply=2 52 | unsigned char addresses[8+12]; // sender HW, sender Protocol, dest HW, dest Protocol 53 | } sgIP_Header_ARP; 54 | 55 | #define SGIP_HEADER_ARP_BASESIZE 8 56 | 57 | #ifdef __cplusplus 58 | extern "C" { 59 | #endif 60 | 61 | extern void sgIP_ARP_Init(); 62 | extern void sgIP_ARP_Timer100ms(); 63 | extern void sgIP_ARP_FlushInterface(sgIP_Hub_HWInterface * hw); 64 | 65 | extern int sgIP_ARP_ProcessIPFrame(sgIP_Hub_HWInterface * hw, sgIP_memblock * mb); 66 | extern int sgIP_ARP_ProcessARPFrame(sgIP_Hub_HWInterface * hw, sgIP_memblock * mb); 67 | extern int sgIP_ARP_SendProtocolFrame(sgIP_Hub_HWInterface * hw, sgIP_memblock * mb, unsigned short protocol, unsigned long destaddr); 68 | 69 | extern int sgIP_ARP_SendARPResponse(sgIP_Hub_HWInterface * hw, sgIP_memblock * mb); 70 | extern int sgIP_ARP_SendGratARP(sgIP_Hub_HWInterface * hw); 71 | extern int sgIP_ARP_SendARPRequest(sgIP_Hub_HWInterface * hw, int protocol, unsigned long protocol_addr); 72 | 73 | 74 | 75 | #ifdef __cplusplus 76 | }; 77 | #endif 78 | 79 | 80 | #endif 81 | -------------------------------------------------------------------------------- /arm9/source/sgIP_Config.h: -------------------------------------------------------------------------------- 1 | // DSWifi Project - sgIP Internet Protocol Stack Implementation 2 | // Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org 3 | /****************************************************************************** 4 | DSWifi Lib and test materials are licenced under the MIT open source licence: 5 | Copyright (c) 2005-2006 Stephen Stair 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | this software and associated documentation files (the "Software"), to deal in 9 | the Software without restriction, including without limitation the rights to 10 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 11 | of the Software, and to permit persons to whom the Software is furnished to do 12 | so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | ******************************************************************************/ 25 | 26 | 27 | #ifndef SGIP_CONFIG_H 28 | #define SGIP_CONFIG_H 29 | 30 | #define __LINUX_ERRNO_EXTENSIONS__ 31 | #include 32 | 33 | ////////////////////////////////////////////////////////////////////////// 34 | // General options - these control the core functionality of the stack. 35 | 36 | // SGIP_USEDYNAMICMEMORY: Allows the stack to use memory as it needs it, via malloc()/free() 37 | // This option is extremely useful in environments where it can be used, as it prevents the 38 | // overhead of allocating per-connection memory in advance, and allows an unlimited number 39 | // of connections, provided the memory space. This option requires the implementation of 40 | // two C functions, "void * sgIP_malloc(int)" and "void sgIP_free(void *)", which behave 41 | // similarly to the malloc and free functions commonly used in C. 42 | #define SGIP_USEDYNAMICMEMORY 43 | 44 | // SGIP_INTERRUPT_THREADING_MODEL: Provides memory protection in a system that can allow 45 | // multiple processing "threads" by way of interrupts. This is not required on single 46 | // threaded systems, and not adequate on multithreaded systems, but provides a way to 47 | // allow protection against contention on interrupt-driven systems. This option requires 48 | // the system to implement two C functions "int sgIP_DisableInterrupts()" and additionally 49 | // "void sgIP_RestoreInterrupts(int)" that takes as a parameter the value returned by 50 | // sgIP_DisableInterrupts(). Interrupts are disabled upon beginning work with sensitive 51 | // memory areas or allocation/deallocation of memory, and are restored afterwards. 52 | #define SGIP_INTERRUPT_THREADING_MODEL 53 | 54 | // SGIP_MULTITHREADED_THREADING_MODEL: Standard memory protection for large multithreaded 55 | // systems, such as operating systems and the like. This kind of memory protection is 56 | // useful for true multithreaded systems but useless in a single-threaded system and 57 | // harmful in an interrupt-based multiprocess system. 58 | //#define SGIP_MULTITHREADED_THREADING_MODEL 59 | 60 | #define SGIP_LITTLEENDIAN 61 | 62 | ////////////////////////////////////////////////////////////////////////// 63 | // Temporary memory system settings 64 | 65 | // SGIP_MEMBLOCK_DATASIZE: This is the maximum data size contained in a single sgIP_memblock. 66 | // for best performance ensure this value is larger than any packet that is expected to be 67 | // received, however, in a memory-tight situation, much smaller values can be used. 68 | #define SGIP_MEMBLOCK_DATASIZE 1600 69 | 70 | // SGIP_MEMBLOCK_BASENUM: The starting number of memblocks that will be allocated. This is 71 | // also the total number of memblocks that will be allocated if sgIP is not configured to use 72 | // dynamic memory allocation. 73 | #define SGIP_MEMBLOCK_BASENUM 12 74 | 75 | // SGIP_MEMBLOCK_STEPNUM: In the case that all memblocks are full, and dynamic memory is 76 | // enabled, this many additional memblocks will be allocated in an attempt to satasfy the 77 | // memory usage demands of the stack. 78 | #define SGIP_MEMBLOCK_STEPNUM 6 79 | 80 | // SGIP_MEMBLOCK_DYNAMIC_MALLOC_ALL: Who cares what the other memblock defines say, let's 81 | // Generate all memblocks by mallocing 'em. 82 | #define SGIP_MEMBLOCK_DYNAMIC_MALLOC_ALL 83 | 84 | ////////////////////////////////////////////////////////////////////////// 85 | // Hardware layer settings 86 | 87 | // SGIP_MAXHWADDRLEN: The maximum usable hardware address length. Ethernet is 6 bytes. 88 | #define SGIP_MAXHWADDRLEN 8 89 | 90 | // SGIP_MAXHWHEADER: The maximum allocated size for hardware headers. 91 | #define SGIP_MAXHWHEADER 16 92 | 93 | // SGIP_MTU_OVERRIDE: This is the maximum MTU that will be accepted. By default it is being 94 | // set to 1460 bytes in order to be courteous to Ethernet and it's ridiculously low MTU. 95 | // This value will allow you to prevent fragmentation of IP packets by not using the full 96 | // MTU available to your network interface when the IP packet will just be sliced and diced 97 | // at the next smaller MTU. (the stack will still use HW mtu if it's lower.) 98 | #define SGIP_MTU_OVERRIDE 1460 99 | 100 | 101 | ////////////////////////////////////////////////////////////////////////// 102 | // Connection settings - can be tuned to change memory usage and performance 103 | 104 | // SGIP_TCP_STATELESS_LISTEN: Uses a technique to prevent syn-flooding from blocking listen 105 | // ports by using all the connection blocks/memory. 106 | #define SGIP_TCP_STATELESS_LISTEN 107 | 108 | // SGIP_TCP_STEALTH: Only sends packets in response to connections to active ports. Doing so 109 | // causes ports to appear not as closed, but as if the deviced does not exist when probing 110 | // ports that are not in use. 111 | //#define SGIP_TCP_STEALTH 112 | 113 | // SGIP_TCP_TTL: Time-to-live value given to outgoing packets, in the absence of a reason to 114 | // manually override this value. 115 | #define SGIP_IP_TTL 128 116 | 117 | // SGIP_TCPRECEIVEBUFFERLENGTH: The size (in bytes) of the receive FIFO in a TCP connection 118 | #define SGIP_TCP_RECEIVEBUFFERLENGTH 8192 119 | 120 | // SGIP_TCPTRANSMITBUFFERLENGTH: The size (in bytes) of the transmit FIFO in a TCP connection 121 | #define SGIP_TCP_TRANSMITBUFFERLENGTH 8192 122 | 123 | // SGIP_TCPOOBBUFFERLENGTH: The size (in bytes) of the receive OOB data FIFO in a TCP connection 124 | #define SGIP_TCP_OOBBUFFERLENGTH 256 125 | 126 | // SGIP_ARP_MAXENTRIES: The maximum number of cached ARP entries - this is defined staticly 127 | // because it's somewhat impractical to dynamicly allocate memory for such a small structure 128 | // (at least on most smaller systems) 129 | #define SGIP_ARP_MAXENTRIES 32 130 | 131 | // SGIP_HUB_MAXHWINTERFACES: The maximum number of hardware interfaces the sgIP hub will 132 | // connect to. A hardware interface being some port (ethernet, wifi, etc) that will relay 133 | // packets to the outside world. 134 | #define SGIP_HUB_MAXHWINTERFACES 1 135 | 136 | // SGIP_HUB_MAXPROTOCOLINTERFACES: The maximum number of protocol interfaces the sgIP hub will 137 | // connect to. A protocol interface being a software handler for a certain protocol type 138 | // (such as IP) 139 | #define SGIP_HUB_MAXPROTOCOLINTERFACES 1 140 | 141 | // BUGGED: original code uses 40000-65000, but official numbering seems to be: 142 | // 0-1023 = System Ports (assigned by IANA) 143 | // 1024-49151 = User Ports (assigned by IANA) 144 | // 49152-65535 = Dynamic Ports (free) 145 | // so one should probably better use 49152-65535 instead of 40000-65000 here. 146 | // - - - 147 | 148 | #define SGIP_TCP_FIRSTOUTGOINGPORT 49152 // original: 40000 149 | #define SGIP_TCP_LASTOUTGOINGPORT 65535 // original: 65000 ;<-- up to INCLUDING this last value (?) (!!) 150 | #define SGIP_UDP_FIRSTOUTGOINGPORT 49152 // original: 40000 151 | #define SGIP_UDP_LASTOUTGOINGPORT 65535 // original: 65000 ;<-- up to INCLUDING this last value (?) (!!) 152 | 153 | #define SGIP_TCP_NUMPORTS SGIP_TCP_LASTOUTGOINGPORT+1-SGIP_TCP_FIRSTOUTGOINGPORT 154 | #define SGIP_UDP_NUMPORTS SGIP_UDP_LASTOUTGOINGPORT+1-SGIP_UDP_FIRSTOUTGOINGPORT 155 | 156 | #define SGIP_TCP_GENTIMEOUTMS 6000 157 | #define SGIP_TCP_TRANSMIT_DELAY 25 158 | #define SGIP_TCP_TRANSMIT_IMMTHRESH 40 159 | #define SGIP_TCP_TIMEMS_2MSL 1000*128 160 | // uh, what is a "MSL"? seems to mean "minutes"! (the value is counted in milliseconds (via "sgIP_timems"), so 1000*60*2 would mean 120 seconds aka "2 minutes") (in ASM code: use 128 seconds instead) 161 | 162 | #define SGIP_TCP_MAXRETRY 7 163 | #define SGIP_TCP_MAXSYNS 64 164 | #define SGIP_TCP_REACK_THRESH 1000 165 | 166 | #define SGIP_TCP_SYNRETRYMS 250 167 | #define SGIP_TCP_GENRETRYMS 500 168 | #define SGIP_TCP_BACKOFFMAX 1024*6 // original: 6000 169 | 170 | #define SGIP_SOCKET_MAXSOCKETS 32 // uh, caution: this must be same (or less) than "FD_SETSIZE" 171 | 172 | //#define SGIP_SOCKET_DEFAULT_NONBLOCK 1 173 | 174 | 175 | ////////////////////////////////////////////////////////////////////////// 176 | // DNS settings 177 | 178 | #define SGIP_DNS_MAXRECORDSCACHE 16 179 | #define SGIP_DNS_MAXRECORDADDRS 4 180 | #define SGIP_DNS_MAXALIASES 4 181 | #define SGIP_DNS_TIMEOUTMS 1024*5 // original: 5000 182 | #define SGIP_DNS_MAXRETRY 3 183 | #define SGIP_DNS_MAXSERVERRETRY 4 184 | 185 | ////////////////////////////////////////////////////////////////////////// 186 | 187 | #define SGIP_DHCP_ERRORTIMEOUT 1024*45 // original: 45000 188 | #define SGIP_DHCP_RESENDTIMEOUT 1024*3 //*1 ;;512 ;;;XNAY 1024*3 ;original: 3000 189 | // (uh, that would 3 seconds before retry, looks a bit too long) 190 | // ;XXX small value like "100" can overload fritzbox (causing to refuse wifi at all, even when resuming to use larger timeout values?!) 191 | #define SGIP_DHCP_DEFAULTHOSTNAME "NintendoDS" 192 | #define SGIP_DHCP_CLASSNAME "sgIP 0.3" 193 | 194 | ////////////////////////////////////////////////////////////////////////// 195 | // Static memory settings - only used if SGIP_USEDYNAMICMEMORY is NOT defined. 196 | 197 | // SGIP_TCP_MAXCONNECTIONS: In the case dynamic memory is not used, this value gives the max 198 | // number of TCP blocks available for inbound/outbound connections via TCP. 199 | #define SGIP_TCP_MAXCONNECTIONS 10 200 | 201 | 202 | 203 | 204 | ////////////////////////////////////////////////////////////////////////// 205 | // Debugging options 206 | 207 | 208 | // SGIP_DEBUG: Enable debug logging. 209 | // requires external function "void sgIP_dbgprint(char *, ...);" 210 | //#define SGIP_DEBUG 211 | 212 | #ifdef SGIP_DEBUG 213 | #define SGIP_DEBUG_MESSAGE(param) sgIP_dbgprint param 214 | #define SGIP_DEBUG_ERROR(param) sgIP_dbgprint param; while(1); 215 | #else 216 | #define SGIP_DEBUG_MESSAGE(param) 217 | #define SGIP_DEBUG_ERROR(param) 218 | #endif 219 | 220 | 221 | ////////////////////////////////////////////////////////////////////////// 222 | // Error handling 223 | extern int sgIP_errno; 224 | #define SGIP_ERROR(a) ((errno=(a)), -1) 225 | #define SGIP_ERROR0(a) ((errno=(a)), 0) 226 | 227 | ////////////////////////////////////////////////////////////////////////// 228 | // Error checking 229 | 230 | 231 | #ifdef SGIP_MULTITHREADED_THREADING_MODEL 232 | #ifdef SGIP_INTERRUPT_THREADING_MODEL 233 | #error SGIP_INTERRUPT_THREADING_MODEL and SGIP_MULTITHREADED_THREADING_MODEL cannot be used together! 234 | #endif 235 | #endif 236 | 237 | 238 | ////////////////////////////////////////////////////////////////////////// 239 | // External option-based dependencies 240 | #include 241 | 242 | #ifdef SGIP_INTERRUPT_THREADING_MODEL 243 | #ifdef __cplusplus 244 | extern "C" { 245 | #endif 246 | void sgIP_IntrWaitEvent(); 247 | #ifdef __cplusplus 248 | }; 249 | #endif 250 | #define SGIP_INTR_PROTECT() \ 251 | int tIME; \ 252 | tIME=enterCriticalSection() 253 | #define SGIP_INTR_REPROTECT() \ 254 | tIME=enterCriticalSection() 255 | #define SGIP_INTR_UNPROTECT() \ 256 | leaveCriticalSection(tIME) 257 | #define SGIP_WAITEVENT() \ 258 | sgIP_IntrWaitEvent() 259 | #else // !SGIP_INTERRUPT_THREADING_MODEL 260 | #define SGIP_INTR_PROTECT() 261 | #define SGIP_INTR_REPROTECT() 262 | #define SGIP_INTR_UNPROTECT() 263 | #define SGIP_WAITEVENT(); 264 | #endif // SGIP_INTERRUPT_THREADING_MODEL 265 | 266 | #ifdef SGIP_DEBUG 267 | #ifdef __cplusplus 268 | extern "C" { 269 | #endif 270 | extern void sgIP_dbgprint(char *, ...); 271 | #ifdef __cplusplus 272 | }; 273 | #endif 274 | #endif // SGIP_DEBUG 275 | 276 | #ifdef SGIP_USEDYNAMICMEMORY 277 | #ifdef __cplusplus 278 | extern "C" { 279 | #endif 280 | extern void * sgIP_malloc(int); 281 | extern void sgIP_free(void *); 282 | #ifdef __cplusplus 283 | }; 284 | #endif 285 | #endif // SGIP_USEDYNAMICMEMORY 286 | 287 | #endif 288 | -------------------------------------------------------------------------------- /arm9/source/sgIP_DHCP.c: -------------------------------------------------------------------------------- 1 | // DSWifi Project - sgIP Internet Protocol Stack Implementation 2 | // Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org 3 | /****************************************************************************** 4 | DSWifi Lib and test materials are licenced under the MIT open source licence: 5 | Copyright (c) 2005-2006 Stephen Stair 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | this software and associated documentation files (the "Software"), to deal in 9 | the Software without restriction, including without limitation the rights to 10 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 11 | of the Software, and to permit persons to whom the Software is furnished to do 12 | so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | ******************************************************************************/ 25 | 26 | #include "sgIP_DHCP.h" 27 | #include "sgIP_DNS.h" 28 | #include 29 | #include "sys/socket.h" 30 | #include "netinet/in.h" 31 | 32 | extern unsigned long volatile sgIP_timems; 33 | int dhcp_socket; 34 | char dhcp_hostname[64]; 35 | int dhcp_tid; 36 | unsigned long dhcp_timestart, dhcp_timelastaction; 37 | sgIP_DHCP_Packet * dhcp_p; 38 | sgIP_Hub_HWInterface * dhcp_int; 39 | int dhcp_optionptr; 40 | int dhcp_requestDNS; 41 | int dhcp_status; 42 | int dhcp_state; // 0== send DHCPDISCOVER wait for DHCPOFFER, 1== send DHCPREQUEST wait for DHCPACK 43 | unsigned long dhcp_rcvd_ip, dhcp_rcvd_gateway, dhcp_rcvd_snmask, dhcp_rcvd_dns[3], dhcp_serverip; 44 | 45 | 46 | void sgIP_DHCP_Init() { 47 | dhcp_socket=0; 48 | dhcp_p=0; 49 | dhcp_int=0; 50 | dhcp_rcvd_ip=0; 51 | strcpy(dhcp_hostname,SGIP_DHCP_DEFAULTHOSTNAME); 52 | dhcp_status=SGIP_DHCP_STATUS_IDLE; 53 | } 54 | void sgIP_DHCP_SetHostName(char * s) { 55 | strncpy(dhcp_hostname,s,63); 56 | dhcp_hostname[63]=0; 57 | } 58 | int sgIP_DHCP_IsDhcpIp(unsigned long ip) { // check if the IP address was assigned via dhcp. 59 | return ip==dhcp_rcvd_ip; 60 | } 61 | 62 | 63 | //note: original code did have this split into two functions: 64 | // "sgIP_DHCP_BeginDgram" and "sgIP_DHCP_SendDgram" 65 | //that would have allowed it to insert extra options between the two 66 | //function calls (the code didn't actually do that), or to modify some 67 | //settings between the calls (that was done for "ciaddr=ipaddr" upon 68 | //RELEASE, and that's done automatically in below code). 69 | //anyways, having the two functions merged into a single function is nicer. 70 | //- - - 71 | void sgIP_DHCP_CreateAndSendDgram(int dgramtype) { 72 | sgIP_DHCP_BeginDgram(dgramtype); 73 | 74 | if(dgramtype==DHCP_TYPE_RELEASE) { 75 | dhcp_p->ciaddr=dhcp_int->ipaddr; 76 | } 77 | 78 | sgIP_DHCP_SendDgram(); 79 | } 80 | 81 | void sgIP_DHCP_SendDgram() { 82 | struct sockaddr_in sain; 83 | int len_dhcp; 84 | sain.sin_port=htons(67); // bootp server port 85 | sain.sin_addr.s_addr=0xFFFFFFFF; // broadcast 86 | dhcp_p->options[dhcp_optionptr++]=0xFF; // terminate options list. 87 | //sendto(dhcp_socket,dhcp_p,sizeof(sgIP_DHCP_Packet)-312+dhcp_optionptr,0,(struct sockaddr *)&sain,sizeof(sain)); 88 | len_dhcp = sizeof(sgIP_DHCP_Packet)-312+dhcp_optionptr; 89 | if(len_dhcp<300) len_dhcp=300; 90 | sendto(dhcp_socket,dhcp_p,len_dhcp,0,(struct sockaddr *)&sain,sizeof(sain)); 91 | sgIP_free(dhcp_p); 92 | dhcp_p=0; 93 | dhcp_timelastaction=sgIP_timems; 94 | } 95 | 96 | void sgIP_DHCP_BeginDgram(int dgramtype) { 97 | int i; 98 | if(dhcp_p) sgIP_free(dhcp_p); 99 | dhcp_p = (sgIP_DHCP_Packet *) sgIP_malloc(sizeof(sgIP_DHCP_Packet)); 100 | if(!dhcp_p) return; 101 | 102 | // ensure packet is zero'd.. seems to pacify some routers. malloc doesn't initialise the memory returned. 103 | memset(dhcp_p,0,sizeof(sgIP_DHCP_Packet)); 104 | 105 | dhcp_p->op=1; // 1==BOOTREQUEST 106 | dhcp_p->htype=1; // 1== ethernet address type 107 | dhcp_p->hlen=6; // hardware address length 108 | dhcp_p->hops=0; // client sets to zero 109 | dhcp_p->xid=dhcp_tid; // DHCP transaction ID 110 | dhcp_p->secs=(sgIP_timems-dhcp_timestart)/1000; // seconds since DHCP start 111 | dhcp_p->flags=htons(0x0000); // top bit set = request broadcast response 112 | dhcp_p->ciaddr=0; 113 | dhcp_p->yiaddr=0; 114 | dhcp_p->siaddr=0; 115 | dhcp_p->giaddr=0; 116 | 117 | memcpy(dhcp_p->chaddr,dhcp_int->hwaddr,6); 118 | 119 | dhcp_optionptr=0; 120 | dhcp_p->options[dhcp_optionptr++]=0x63; 121 | dhcp_p->options[dhcp_optionptr++]=0x82; 122 | dhcp_p->options[dhcp_optionptr++]=0x53; 123 | dhcp_p->options[dhcp_optionptr++]=0x63; // 4-byte "magic cookie" (bleh!) 124 | // add some necessary options... - by default add the dhcp message type, host name, class id, and parameter request list 125 | dhcp_p->options[dhcp_optionptr++]=0x35; // DHCP Message type 126 | dhcp_p->options[dhcp_optionptr++]=0x01; 127 | dhcp_p->options[dhcp_optionptr++]=dgramtype; 128 | 129 | dhcp_p->options[dhcp_optionptr++]=0x3D; // DHCP client identifier 130 | dhcp_p->options[dhcp_optionptr++]=0x07; // length 131 | dhcp_p->options[dhcp_optionptr++]=0x01; // hw type 132 | for(i=0;i<6;i++) dhcp_p->options[dhcp_optionptr++]=dhcp_int->hwaddr[i]; 133 | 134 | dhcp_p->options[dhcp_optionptr++]=0x0C; // DHCP host name 135 | dhcp_p->options[dhcp_optionptr++]=strlen(dhcp_hostname); 136 | for(i=0;ioptions[dhcp_optionptr++]=dhcp_hostname[i]; 138 | } 139 | 140 | dhcp_p->options[dhcp_optionptr++]=0x37; // DHCP Parameter request list 141 | dhcp_p->options[dhcp_optionptr++]=2+dhcp_requestDNS; 142 | dhcp_p->options[dhcp_optionptr++]=1; // subnet mask 143 | dhcp_p->options[dhcp_optionptr++]=3; // router 144 | if(dhcp_requestDNS) dhcp_p->options[dhcp_optionptr++]=6; // dns server 145 | 146 | if(dgramtype==DHCP_TYPE_REQUEST) { 147 | dhcp_p->options[dhcp_optionptr++]=0x32; // DHCP Requested IP address 148 | dhcp_p->options[dhcp_optionptr++]=0x04; 149 | dhcp_p->options[dhcp_optionptr++]=(dhcp_rcvd_ip)&255; 150 | dhcp_p->options[dhcp_optionptr++]=(dhcp_rcvd_ip>>8)&255; 151 | dhcp_p->options[dhcp_optionptr++]=(dhcp_rcvd_ip>>16)&255; 152 | dhcp_p->options[dhcp_optionptr++]=(dhcp_rcvd_ip>>24)&255; 153 | 154 | dhcp_p->options[dhcp_optionptr++]=0x36; // DHCP Server identifier 155 | dhcp_p->options[dhcp_optionptr++]=0x04; 156 | dhcp_p->options[dhcp_optionptr++]=(dhcp_serverip)&255; 157 | dhcp_p->options[dhcp_optionptr++]=(dhcp_serverip>>8)&255; 158 | dhcp_p->options[dhcp_optionptr++]=(dhcp_serverip>>16)&255; 159 | dhcp_p->options[dhcp_optionptr++]=(dhcp_serverip>>24)&255; 160 | } 161 | 162 | dhcp_p->options[dhcp_optionptr++]=0x3C; // DHCP Vendor Class ID 163 | dhcp_p->options[dhcp_optionptr++]=strlen(SGIP_DHCP_CLASSNAME); 164 | for(i=0;ioptions[dhcp_optionptr++]=(SGIP_DHCP_CLASSNAME)[i]; 166 | } 167 | 168 | // reason we don't send it immediately is in case the calling code wants to modify some data or add some options. 169 | } 170 | 171 | 172 | 173 | void sgIP_DHCP_Start(sgIP_Hub_HWInterface * interface, int getDNS) { // begin dhcp transaction to get IP and maybe DNS data. 174 | struct sockaddr_in sain; 175 | int i; 176 | SGIP_DEBUG_MESSAGE(("sgIP_DHCP_Start()")); 177 | sgIP_DHCP_Terminate(); 178 | dhcp_requestDNS=getDNS?1:0; 179 | dhcp_int=interface; 180 | dhcp_timestart=sgIP_timems; 181 | dhcp_timelastaction=sgIP_timems; 182 | dhcp_tid=sgIP_timems; 183 | dhcp_status=SGIP_DHCP_STATUS_WORKING; 184 | dhcp_state=0; 185 | 186 | dhcp_rcvd_ip = 0; 187 | dhcp_rcvd_gateway=0; 188 | dhcp_rcvd_snmask=0; 189 | dhcp_rcvd_dns[0]=0; 190 | dhcp_rcvd_dns[1]=0; 191 | dhcp_rcvd_dns[2]=0; 192 | 193 | dhcp_socket=socket(AF_INET,SOCK_DGRAM,0); 194 | sain.sin_addr.s_addr=0; 195 | sain.sin_port=htons(68); // BOOTP client 196 | bind(dhcp_socket,(struct sockaddr *)&sain,sizeof(sain)); 197 | i=1; 198 | ioctl(dhcp_socket,FIONBIO,&i); 199 | 200 | sgIP_DHCP_BeginDgram(DHCP_TYPE_DISCOVER); 201 | sgIP_DHCP_SendDgram(); 202 | } 203 | void sgIP_DHCP_Release() { // call to dump our DHCP address and leave. 204 | if(dhcp_status==SGIP_DHCP_STATUS_WORKING) { 205 | sgIP_DHCP_Terminate(); 206 | } else { 207 | sgIP_DHCP_BeginDgram(DHCP_TYPE_RELEASE); 208 | dhcp_p->ciaddr=dhcp_int->ipaddr; 209 | sgIP_DHCP_SendDgram(); 210 | 211 | } 212 | } 213 | int sgIP_DHCP_Update() { // MUST be called periodicly; returns status - call until it returns SGIP_DHCP_STATUS_SUCCESS or _FAILED. 214 | sgIP_DHCP_Packet * p; 215 | struct sockaddr_in * sain; 216 | int i,j,n,l; 217 | if(dhcp_status!=SGIP_DHCP_STATUS_WORKING) return dhcp_status; 218 | int send = 0; 219 | 220 | p=(sgIP_DHCP_Packet *)sgIP_malloc(sizeof(sgIP_DHCP_Packet)); 221 | if(p) { 222 | 223 | while(1) { 224 | l=recvfrom(dhcp_socket,p,sizeof(sgIP_DHCP_Packet),0,(struct sockaddr *)&sain,&n); 225 | if(l==-1) break; 226 | if(p->op!=2 || p->htype!=1 || p->hlen!=6 || p->xid!=dhcp_tid ) continue; 227 | // check magic cookie 228 | if(p->options[0]!=0x63 || p->options[1]!=0x82 || p->options[2]!=0x53 || p->options[3]!=0x63) continue; 229 | i=4; // yay, the cookie is valid. 230 | l -= (sizeof(sgIP_DHCP_Packet)-312); // number of bytes remaining in the options 231 | while(ioptions[i++]; 233 | switch(n) { 234 | case 0: // ignore 235 | break; 236 | case 255: // end-of-options marker. 237 | l=0; 238 | break; 239 | case 53: // message type, variable length, 2+n 240 | j=p->options[i++]; 241 | if(dhcp_state==0) { 242 | if(p->options[i]!=DHCP_TYPE_OFFER) l=-1; 243 | } else { 244 | if(p->options[i]==DHCP_TYPE_ACK) { 245 | sgIP_free(p); 246 | sgIP_DHCP_Terminate(); 247 | dhcp_int->ipaddr=dhcp_rcvd_ip; 248 | dhcp_int->gateway=dhcp_rcvd_gateway; 249 | dhcp_int->snmask=dhcp_rcvd_snmask; 250 | SGIP_DEBUG_MESSAGE(("DHCP Configured!")); 251 | SGIP_DEBUG_MESSAGE(("IP%08X SM%08X GW%08X",dhcp_rcvd_ip,dhcp_rcvd_snmask,dhcp_rcvd_gateway)); 252 | if(dhcp_requestDNS) { 253 | dhcp_int->dns[0]=dhcp_rcvd_dns[0]; 254 | dhcp_int->dns[1]=dhcp_rcvd_dns[1]; 255 | dhcp_int->dns[2]=dhcp_rcvd_dns[2]; 256 | SGIP_DEBUG_MESSAGE(("DNS %08X %08X %08X",dhcp_rcvd_dns[0],dhcp_rcvd_dns[1],dhcp_rcvd_dns[2])); 257 | } 258 | 259 | dhcp_status=SGIP_DHCP_STATUS_SUCCESS; 260 | return dhcp_status; 261 | } else { 262 | l=-1; 263 | } 264 | } 265 | i+=j; 266 | 267 | break; 268 | case 1: // subnet mask field, variable length 2+n 269 | j=p->options[i++]; 270 | if(dhcp_state==1 || j<4) {i+=j; break; } 271 | dhcp_rcvd_snmask = (dhcp_rcvd_snmask>>8) | (p->options[i++]<<24); 272 | dhcp_rcvd_snmask = (dhcp_rcvd_snmask>>8) | (p->options[i++]<<24); 273 | dhcp_rcvd_snmask = (dhcp_rcvd_snmask>>8) | (p->options[i++]<<24); 274 | dhcp_rcvd_snmask = (dhcp_rcvd_snmask>>8) | (p->options[i++]<<24); 275 | i+=j-4; 276 | break; 277 | case 3: // gateway, variable length 2+n 278 | j=p->options[i++]; 279 | if(dhcp_state==1 || j<4) {i+=j; break; } 280 | dhcp_rcvd_gateway = (dhcp_rcvd_gateway>>8) | (p->options[i++]<<24); 281 | dhcp_rcvd_gateway = (dhcp_rcvd_gateway>>8) | (p->options[i++]<<24); 282 | dhcp_rcvd_gateway = (dhcp_rcvd_gateway>>8) | (p->options[i++]<<24); 283 | dhcp_rcvd_gateway = (dhcp_rcvd_gateway>>8) | (p->options[i++]<<24); 284 | i+=j-4; 285 | break; 286 | case 54: // server ID, variable length 2+n 287 | j=p->options[i++]; 288 | if(dhcp_state==1 || j<4) {i+=j; break; } 289 | dhcp_serverip = (dhcp_serverip>>8) | (p->options[i++]<<24); 290 | dhcp_serverip = (dhcp_serverip>>8) | (p->options[i++]<<24); 291 | dhcp_serverip = (dhcp_serverip>>8) | (p->options[i++]<<24); 292 | dhcp_serverip = (dhcp_serverip>>8) | (p->options[i++]<<24); 293 | i+=j-4; 294 | break; 295 | case 6: // dns servers, variable length 2+n 296 | if(dhcp_requestDNS && !dhcp_state) { 297 | j=p->options[i++]; 298 | n=0; 299 | while(n<3 && 4*n+3>8) | (p->options[i++]<<24); 301 | dhcp_rcvd_dns[n] = (dhcp_rcvd_dns[n]>>8) | (p->options[i++]<<24); 302 | dhcp_rcvd_dns[n] = (dhcp_rcvd_dns[n]>>8) | (p->options[i++]<<24); 303 | dhcp_rcvd_dns[n] = (dhcp_rcvd_dns[n]>>8) | (p->options[i++]<<24); 304 | n++; 305 | } 306 | i+=j-4*n; 307 | break; 308 | } 309 | default: 310 | j=p->options[i++]; 311 | i+=j; 312 | } 313 | } 314 | if(l==-1) continue; 315 | dhcp_rcvd_ip=(p->yiaddr); 316 | 317 | // discover succeeded. increment transaction id. force sending REQUEST message next. 318 | dhcp_state=1; 319 | dhcp_tid += ( sgIP_timems-dhcp_timestart ) + 1; 320 | send = 1; 321 | break; 322 | } 323 | 324 | sgIP_free(p); 325 | // has timeout expired? 326 | if( (sgIP_timems-dhcp_timestart) > SGIP_DHCP_ERRORTIMEOUT) { 327 | SGIP_DEBUG_MESSAGE(("sgIP DHCP error timeout!")); 328 | sgIP_DHCP_Terminate(); 329 | dhcp_status=SGIP_DHCP_STATUS_FAILED; 330 | return dhcp_status; 331 | } 332 | if( send || (sgIP_timems-dhcp_timelastaction) > SGIP_DHCP_RESENDTIMEOUT ) 333 | { 334 | if(dhcp_state==0) sgIP_DHCP_BeginDgram(DHCP_TYPE_DISCOVER); else sgIP_DHCP_BeginDgram(DHCP_TYPE_REQUEST); 335 | sgIP_DHCP_SendDgram(); 336 | } 337 | } else { 338 | SGIP_DEBUG_MESSAGE(("sgIP DHCP alloc failed!")); 339 | sgIP_DHCP_Terminate(); 340 | dhcp_status=SGIP_DHCP_STATUS_FAILED; 341 | } 342 | 343 | return dhcp_status; 344 | } 345 | void sgIP_DHCP_Terminate() { // kill the process where it stands; deallocate all DHCP resources. 346 | if(dhcp_socket) closesocket(dhcp_socket); 347 | dhcp_socket=0; 348 | if(dhcp_p) sgIP_free(dhcp_p); 349 | dhcp_p=0; 350 | dhcp_status=SGIP_DHCP_STATUS_IDLE; 351 | } 352 | 353 | int gethostname(char *name, size_t len) 354 | { 355 | int size = sizeof(dhcp_hostname); 356 | if (name == NULL) 357 | return SGIP_ERROR(EFAULT); 358 | 359 | if ( len <= size ) 360 | return SGIP_ERROR(EINVAL); 361 | 362 | strncpy(name, dhcp_hostname, size); 363 | name[size]=0; 364 | return 0; 365 | } 366 | 367 | int sethostname(const char *name, size_t len) 368 | { 369 | sgIP_DNS_Record *rec; 370 | 371 | int size = sizeof(dhcp_hostname); 372 | if (name == NULL) 373 | return SGIP_ERROR(EFAULT); 374 | 375 | if ( len > size - 1) 376 | return SGIP_ERROR(EINVAL); 377 | 378 | rec = sgIP_DNS_FindDNSRecord(dhcp_hostname); 379 | 380 | strncpy(dhcp_hostname, name, len); 381 | dhcp_hostname[len]=0; 382 | 383 | if(rec != NULL) 384 | { 385 | strncpy(rec->aliases[0], name, len); 386 | rec->aliases[0][len]=0; 387 | strncpy(rec->name, name, len); 388 | rec->name[len]=0; 389 | } 390 | 391 | return 0; 392 | } 393 | 394 | 395 | 396 | 397 | 398 | 399 | -------------------------------------------------------------------------------- /arm9/source/sgIP_DHCP.h: -------------------------------------------------------------------------------- 1 | // DSWifi Project - sgIP Internet Protocol Stack Implementation 2 | // Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org 3 | /****************************************************************************** 4 | DSWifi Lib and test materials are licenced under the MIT open source licence: 5 | Copyright (c) 2005-2006 Stephen Stair 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | this software and associated documentation files (the "Software"), to deal in 9 | the Software without restriction, including without limitation the rights to 10 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 11 | of the Software, and to permit persons to whom the Software is furnished to do 12 | so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | ******************************************************************************/ 25 | #ifndef SGIP_DHCP_H 26 | #define SGIP_DHCP_H 27 | 28 | #include "sgIP_Config.h" 29 | #include "sgIP_Hub.h" 30 | 31 | // "DHCP Server" port is 67, "DHCP Client" port is 68 32 | // DHCP messages broadcast by a client prior to that client obtaining its IP address must have the source address field in the IP header set to 0. 33 | 34 | #define DHCP_BOOTP_SERVER 0x4300 // aka htons(67) ;"DHCP Server" port 35 | #define DHCP_BOOTP_CLIENT 0x4400 // aka htons(68) ;"DHCP Client" port 36 | 37 | typedef struct SGIP_DHCP_PACKET { // yes, freaking big endian prevails here too. 38 | unsigned char op; // opcode/message type (1=BOOTREQUEST, 2=BOOTREPLY) 39 | unsigned char htype; // hardware address type 40 | unsigned char hlen; // Hardware address length (should be 6, for ethernet/wifi) 41 | unsigned char hops; // set to 0 42 | unsigned long xid; // 4-byte client specified transaction ID 43 | unsigned short secs; // seconds elapsed since client started trying to boot 44 | unsigned short flags; // flags 45 | unsigned long ciaddr; // client IP address, filled in by client if verifying previous params 46 | unsigned long yiaddr; // "your" (client) IP address 47 | unsigned long siaddr; // IP addr of next server to use in bootstrap. 48 | unsigned long giaddr; // Relay agent IP address 49 | unsigned char chaddr[16]; // client hardware address 50 | char sname[64]; // optional server hostname (null terminated string) 51 | char file[128]; // boot file name, null terminated string 52 | char options[312]; // optional parameters 53 | } sgIP_DHCP_Packet; 54 | 55 | enum SGIP_DHCP_STATUS { 56 | SGIP_DHCP_STATUS_IDLE, 57 | SGIP_DHCP_STATUS_WORKING, 58 | SGIP_DHCP_STATUS_FAILED, 59 | SGIP_DHCP_STATUS_SUCCESS 60 | }; 61 | 62 | #define DHCP_TYPE_DISCOVER 1 63 | #define DHCP_TYPE_OFFER 2 64 | #define DHCP_TYPE_REQUEST 3 65 | #define DHCP_TYPE_ACK 5 66 | #define DHCP_TYPE_RELEASE 7 67 | 68 | 69 | #ifdef __cplusplus 70 | extern "C" { 71 | #endif 72 | 73 | void sgIP_DHCP_Init(); 74 | 75 | void sgIP_DHCP_SetHostName(char * s); // just for the fun of it. 76 | int sgIP_DHCP_IsDhcpIp(unsigned long ip); // check if the IP address was assigned via dhcp. 77 | void sgIP_DHCP_Start(sgIP_Hub_HWInterface * interface, int getDNS); // begin dhcp transaction to get IP and maybe DNS data. 78 | void sgIP_DHCP_Release(); // call to dump our DHCP address and leave. 79 | int sgIP_DHCP_Update(); // MUST be called periodicly after _Start; returns status - call until it returns something other than SGIP_DHCP_STATUS_WORKING 80 | void sgIP_DHCP_Terminate(); // kill the process where it stands; deallocate all DHCP resources. 81 | 82 | #ifdef __cplusplus 83 | }; 84 | #endif 85 | 86 | 87 | #endif 88 | -------------------------------------------------------------------------------- /arm9/source/sgIP_DNS.c: -------------------------------------------------------------------------------- 1 | // DSWifi Project - sgIP Internet Protocol Stack Implementation 2 | // Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org 3 | /****************************************************************************** 4 | DSWifi Lib and test materials are licenced under the MIT open source licence: 5 | Copyright (c) 2005-2006 Stephen Stair 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | this software and associated documentation files (the "Software"), to deal in 9 | the Software without restriction, including without limitation the rights to 10 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 11 | of the Software, and to permit persons to whom the Software is furnished to do 12 | so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | ******************************************************************************/ 25 | 26 | #include "sgIP_DNS.h" 27 | #include "sgIP_Hub.h" 28 | #include "netinet/in.h" 29 | #include "sys/socket.h" 30 | 31 | int dns_sock; 32 | int time_count; 33 | int last_id; 34 | int query_time_start; 35 | extern unsigned long volatile sgIP_timems; 36 | 37 | // cache record data 38 | sgIP_DNS_Record dnsrecords[SGIP_DNS_MAXRECORDSCACHE]; 39 | 40 | // data to return via hostent 41 | volatile sgIP_DNS_Record dnsrecord_return; 42 | volatile char * alias_list[SGIP_DNS_MAXALIASES+1]; 43 | volatile char * addr_list[SGIP_DNS_MAXRECORDADDRS+1]; 44 | char ipaddr_alias[256]; 45 | unsigned long ipaddr_ip; 46 | volatile sgIP_DNS_Hostent dnsrecord_hostent; 47 | 48 | unsigned char querydata[512]; 49 | unsigned char responsedata[512]; 50 | 51 | void sgIP_DNS_Init() { 52 | int i; 53 | for(i=0;i='0' && *c<='9') || (*c>='A' && *c<='F') || (*c>='a' && *c<='f') || *c=='.' || *c=='x' || *c=='X')) return 0; 80 | if(*c=='.') ndot++; 81 | c++; 82 | } 83 | if(ndot>3) return 0; 84 | c=name; 85 | for(i=0;i<=ndot;i++) { 86 | g[i]=0; 87 | t=0; 88 | j=0; 89 | while(*c && *c!='.') { 90 | if(j==0 && *c=='0') { t++; } 91 | else if(j==1 && t==1 && (*c=='x' || *c=='X')) { t++; } 92 | else { 93 | switch(t) { 94 | case 0: // decimal 95 | if(*c=='x' || *c=='X' || (*c>='A' && *c<='F') || (*c>='a' && *c<='f')) return 0; 96 | g[i]=(g[i]*10)+(*c-'0'); 97 | break; 98 | case 1: // octal 99 | if(*c=='x' || *c=='X' || (*c>='A' && *c<='F') || (*c>='a' && *c<='f') || *c=='8' || *c=='9') return 0; 100 | g[i]=(g[i]<<3)+(*c-'0'); 101 | break; 102 | case 2: // hex 103 | if(*c=='x' || *c=='X') return 0; 104 | if(*c>='0' && *c<='9') { 105 | g[i]=(g[i]<<4)+(*c-'0'); 106 | } else { 107 | g[i]=(g[i]<<4)+(*c&0xDF)+9; 108 | } 109 | break; 110 | } 111 | } 112 | j++; c++; 113 | } 114 | if(*c) c++; else break; 115 | } 116 | out_addr=0; 117 | switch(ndot) { 118 | case 0: 119 | out_addr=g[0]; 120 | break; 121 | case 1: 122 | if(g[0]>=0x100 || g[1]>=0x1000000) return 0; 123 | out_addr= (g[0]<<24) | g[1]; 124 | break; 125 | case 2: 126 | if(g[0]>=0x100 || g[1]>=0x100 || g[2]>=0x10000) return 0; 127 | out_addr= (g[0]<<24) | (g[1]<<16) | g[2]; 128 | break; 129 | case 3: 130 | if(g[0]>=0x100 || g[1]>=0x100 || g[2]>=0x100 || g[3]>=0x100) return 0; 131 | out_addr= (g[0]<<24) | (g[1]<<16) | (g[2]<<8) | g[3]; 132 | break; 133 | } 134 | *ipdest=htonl(out_addr); 135 | return 1; 136 | } 137 | 138 | sgIP_DNS_Record * sgIP_DNS_FindDNSRecord(const char * name) { 139 | int i,j,k,n,c,c2; 140 | SGIP_INTR_PROTECT(); 141 | for(i=0;i='a' && c<='z') c+='A'-'a'; 149 | if(c2>='a' && c2<='z') c2+='A'-'a'; 150 | if(c==c2) { 151 | k++; 152 | } else { 153 | k=0; break; 154 | } 155 | } 156 | if(name[n] || dnsrecords[i].aliases[j][n]) k=0; 157 | if(k) { 158 | SGIP_INTR_UNPROTECT(); 159 | return dnsrecords+i; 160 | } 161 | } 162 | } 163 | } 164 | 165 | SGIP_INTR_UNPROTECT(); 166 | return 0; 167 | } 168 | 169 | //uh, using an idle-count would seem better than the TTL (time-to-live) here 170 | //(the TTL comes from the server, and if it's assigning different TTL's to 171 | //different IP's (?), then the IP's with bigger TTL's would dominate the world, 172 | //even when accessing the IP's with smaller TTL's much more frequently). 173 | //- - - 174 | sgIP_DNS_Record * sgIP_DNS_GetUnusedRecord() { 175 | int i,j,minttl; 176 | SGIP_INTR_PROTECT(); 177 | for(i=0;i>(j*8))&255; 202 | i=0; 203 | if(n>=100) { i=n/100; ipaddr_alias[c++]='0'+i; n-=i*100; } 204 | if(n>=10 || i) { i=n/10; ipaddr_alias[c++]='0'+i; n-=i*10; } 205 | ipaddr_alias[c++]='0'+n; 206 | } 207 | ipaddr_alias[c]=0; 208 | } 209 | 210 | static 211 | sgIP_DNS_Hostent * sgIP_DNS_GenerateHostentIP(unsigned long ipaddr) { 212 | 213 | sgIP_ntoa(ipaddr); 214 | 215 | alias_list[0]=ipaddr_alias; 216 | alias_list[1]=0; 217 | ipaddr_ip=ipaddr; 218 | addr_list[0]=(char *)&ipaddr_ip; 219 | addr_list[1]=0; 220 | 221 | dnsrecord_hostent.h_addr_list=(char **)addr_list; 222 | dnsrecord_hostent.h_addrtype=AF_INET; 223 | dnsrecord_hostent.h_aliases=(char **)alias_list; 224 | dnsrecord_hostent.h_length=4; 225 | dnsrecord_hostent.h_name=ipaddr_alias; 226 | return (sgIP_DNS_Hostent *)&dnsrecord_hostent; 227 | } 228 | 229 | sgIP_DNS_Hostent * sgIP_DNS_GenerateHostent(sgIP_DNS_Record * dnsrec) { 230 | volatile int i; 231 | dnsrecord_return = *dnsrec; // copy struct 232 | for(i=0;i=255) break; 276 | if(c==0) return 0; // this should never happen (unless there's really invalid input with 2 dots next to each other.) 277 | i++; 278 | } 279 | querydata_c[j++]=0; // terminating zero length 280 | // qtype 281 | querydata_c[j++]=0; 282 | querydata_c[j++]=1; // 00 01 "A" (address) 283 | // qclass 284 | querydata_c[j++]=0; 285 | querydata_c[j++]=1; // 00 01 "IN" (internet) 286 | 287 | return j+12; // length 288 | } 289 | 290 | void sgIP_DNS_CopyAliasAt(char * deststr,int offset) { 291 | char * c; 292 | int i,j; 293 | i=0; 294 | c=(char *)responsedata+offset; 295 | do { 296 | j=c[0]; 297 | if(j>63) { 298 | j=((j&63)<<8) | c[1]; 299 | c=(char *)responsedata+j; 300 | continue; 301 | } 302 | if(!j) break; 303 | c++; 304 | for(;j>0;j--) { 305 | deststr[i++]= *(c++); 306 | } 307 | deststr[i++]='.'; 308 | } while(1); 309 | if(i>0) i--; 310 | deststr[i]=0; 311 | } 312 | 313 | 314 | sgIP_DNS_Hostent * sgIP_DNS_gethostbyname(const char * name) { 315 | sgIP_DNS_Record * rec; 316 | sgIP_DNS_Hostent * he; 317 | sgIP_Hub_HWInterface * hw; 318 | int len,i,sainlen; 319 | int retries,dtime; 320 | unsigned long serverip; 321 | struct sockaddr_in sain; 322 | unsigned long IP; 323 | SGIP_INTR_PROTECT(); 324 | 325 | // is name an IP address? 326 | if(sgIP_DNS_isipaddress(name,&IP)) { 327 | SGIP_INTR_UNPROTECT(); 328 | return sgIP_DNS_GenerateHostentIP(IP); 329 | } 330 | 331 | // check cache, return if value required is in cache... 332 | rec=sgIP_DNS_FindDNSRecord(name); 333 | if(rec) { 334 | he=sgIP_DNS_GenerateHostent(rec); 335 | SGIP_INTR_UNPROTECT(); 336 | return he; 337 | } 338 | 339 | // not in cache? generate a query... 340 | len=sgIP_DNS_genquery(name); 341 | 342 | // send off the query, handle retransmit and trying other dns servers. 343 | if(dns_sock==-1) { 344 | hw=sgIP_Hub_GetDefaultInterface(); 345 | serverip=hw->dns[0]; 346 | 347 | dns_sock=socket(AF_INET,SOCK_DGRAM,0); 348 | i=1; 349 | i=ioctl(dns_sock,FIONBIO,&i); // set non-blocking 350 | 351 | retries=0; 352 | do { 353 | query_time_start=sgIP_timems; 354 | sain.sin_addr.s_addr=serverip; 355 | sain.sin_port=htons(53); 356 | i=sendto(dns_sock,querydata,len,0,(struct sockaddr *)&sain,sizeof(sain)); 357 | dns_listenonly: 358 | 359 | do { 360 | i=recvfrom(dns_sock,responsedata,512,0,(struct sockaddr *)&sain,&sainlen); 361 | if(i!=-1) break; 362 | dtime=sgIP_timems-query_time_start; 363 | if(dtime>SGIP_DNS_TIMEOUTMS) break; 364 | SGIP_INTR_UNPROTECT(); 365 | SGIP_WAITEVENT(); 366 | SGIP_INTR_REPROTECT(); 367 | } while(1); 368 | 369 | if(i==-1) { // no reply, retry 370 | retries++; 371 | if(retries>=SGIP_DNS_MAXRETRY) { // maybe try another server? for now just quit. 372 | closesocket(dns_sock); 373 | dns_sock=-1; 374 | SGIP_INTR_UNPROTECT(); 375 | 376 | return NULL; 377 | } 378 | continue; // send again 379 | } 380 | 381 | // got something, is it what we want? 382 | if(i<12 || sain.sin_addr.s_addr!=serverip || sain.sin_port!=htons(53)) { // suspicious. 383 | goto dns_listenonly; // yay! a goto! - go back and see if we can get a more official response. 384 | } 385 | 386 | // parse response. 387 | { 388 | const unsigned short * resdata_s = (unsigned short *) responsedata; 389 | const unsigned char * resdata_c = responsedata; 390 | const char * c; 391 | int j,q,a, nalias,naddr; 392 | if(last_id!=resdata_s[0]) { // bad. 393 | goto dns_listenonly; 394 | } 395 | q=htons(resdata_s[2]); 396 | a=htons(resdata_s[3]); 397 | // no answer. 398 | if (a == 0) 399 | { 400 | closesocket(dns_sock); 401 | dns_sock=-1; 402 | SGIP_INTR_UNPROTECT(); 403 | 404 | return NULL; 405 | } 406 | 407 | resdata_c+=12; 408 | while(q) { // ignore questions 409 | do { 410 | j=resdata_c[0]; 411 | if(j>63) { resdata_c+=2; break; } 412 | resdata_c += j+1; 413 | } while(j); 414 | resdata_c+=4; 415 | q--; 416 | } 417 | 418 | nalias=0; 419 | naddr=0; 420 | rec=sgIP_DNS_GetUnusedRecord(); 421 | rec->flags=SGIP_DNS_FLAG_ACTIVE | SGIP_DNS_FLAG_BUSY; 422 | while(a) { 423 | if(naliasaliases[nalias++],resdata_c-responsedata); 424 | do { 425 | j=resdata_c[0]; 426 | if(j>63) { resdata_c+=2; break; } 427 | resdata_c += j+1; 428 | } while(j); 429 | // CNAME=5, A=1 430 | j=resdata_c[1]; 431 | rec->addrclass=(resdata_c[2]<<8)|resdata_c[3]; 432 | rec->TTL = (resdata_c[4]<<24)|(resdata_c[5]<<16)|(resdata_c[6]<<8)|resdata_c[7]; 433 | if(j==1) { // A 434 | if(naddraddrdata[naddr*4] = resdata_c[10]; 436 | rec->addrdata[naddr*4+1] = resdata_c[11]; 437 | rec->addrdata[naddr*4+2] = resdata_c[12]; 438 | rec->addrdata[naddr*4+3] = resdata_c[13]; 439 | naddr++; 440 | } 441 | } 442 | j=(resdata_c[8]<<8)|resdata_c[9]; 443 | resdata_c+=10+j; 444 | a--; 445 | } 446 | 447 | // likely we have all the data we care for now. 448 | rec->addrlen=4; 449 | rec->numaddr=naddr; 450 | rec->numalias=nalias; 451 | for(c=name,i=0;*c;c++,i++) rec->name[i]=*c; 452 | rec->name[i]=0; 453 | rec->flags=SGIP_DNS_FLAG_ACTIVE | SGIP_DNS_FLAG_RESOLVED; 454 | break; // we got our answer, let's get out of here! 455 | } 456 | } while(1); 457 | 458 | closesocket(dns_sock); 459 | dns_sock=-1; 460 | } else { 461 | SGIP_INTR_UNPROTECT(); 462 | return NULL; 463 | } 464 | 465 | // received response, return data 466 | he=sgIP_DNS_GenerateHostent(rec); 467 | SGIP_INTR_UNPROTECT(); 468 | return he; 469 | } 470 | 471 | unsigned long inet_addr(const char *cp) { 472 | unsigned long IP; 473 | if(sgIP_DNS_isipaddress(cp,&IP)) { 474 | return IP; 475 | } 476 | return 0xFFFFFFFF; 477 | } 478 | 479 | int inet_aton(const char *cp, struct in_addr *inp) { 480 | unsigned long IP; 481 | 482 | if(sgIP_DNS_isipaddress(cp,&IP)) { 483 | inp->s_addr = IP; 484 | return 1; 485 | } 486 | 487 | return 0; 488 | } 489 | 490 | 491 | char *inet_ntoa(struct in_addr in) { 492 | sgIP_ntoa(in.s_addr); 493 | return (char *)ipaddr_alias; 494 | } 495 | 496 | 497 | 498 | -------------------------------------------------------------------------------- /arm9/source/sgIP_DNS.h: -------------------------------------------------------------------------------- 1 | // DSWifi Project - sgIP Internet Protocol Stack Implementation 2 | // Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org 3 | /****************************************************************************** 4 | DSWifi Lib and test materials are licenced under the MIT open source licence: 5 | Copyright (c) 2005-2006 Stephen Stair 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | this software and associated documentation files (the "Software"), to deal in 9 | the Software without restriction, including without limitation the rights to 10 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 11 | of the Software, and to permit persons to whom the Software is furnished to do 12 | so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | ******************************************************************************/ 25 | #ifndef SGIP_DNS_H 26 | #define SGIP_DNS_H 27 | 28 | #include "sgIP_Config.h" 29 | 30 | #define SGIP_DNS_FLAG_ACTIVE 1 31 | #define SGIP_DNS_FLAG_RESOLVED 2 32 | #define SGIP_DNS_FLAG_BUSY 4 33 | 34 | typedef struct SGIP_DNS_RECORD { 35 | char name [256]; 36 | char aliases[SGIP_DNS_MAXALIASES][256]; 37 | unsigned char addrdata[SGIP_DNS_MAXRECORDADDRS*4]; 38 | short addrlen; 39 | short addrclass; 40 | int numaddr,numalias; 41 | int TTL; 42 | int flags; 43 | } sgIP_DNS_Record; 44 | 45 | typedef struct SGIP_DNS_HOSTENT { 46 | char * h_name; 47 | char ** h_aliases; 48 | int h_addrtype; // class - 1=IN (internet) 49 | int h_length; 50 | char ** h_addr_list; 51 | } sgIP_DNS_Hostent; 52 | 53 | #ifdef __cplusplus 54 | extern "C" { 55 | #endif 56 | 57 | extern void sgIP_DNS_Init(); 58 | extern void sgIP_DNS_Timer1000ms(); 59 | 60 | extern sgIP_DNS_Hostent * sgIP_DNS_gethostbyname(const char * name); 61 | extern sgIP_DNS_Record * sgIP_DNS_GetUnusedRecord(); 62 | extern sgIP_DNS_Record * sgIP_DNS_FindDNSRecord(const char * name); 63 | 64 | #ifdef __cplusplus 65 | }; 66 | #endif 67 | 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /arm9/source/sgIP_Hub.c: -------------------------------------------------------------------------------- 1 | // DSWifi Project - sgIP Internet Protocol Stack Implementation 2 | // Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org 3 | /****************************************************************************** 4 | DSWifi Lib and test materials are licenced under the MIT open source licence: 5 | Copyright (c) 2005-2006 Stephen Stair 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | this software and associated documentation files (the "Software"), to deal in 9 | the Software without restriction, including without limitation the rights to 10 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 11 | of the Software, and to permit persons to whom the Software is furnished to do 12 | so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | ******************************************************************************/ 25 | #include "sgIP_Hub.h" 26 | #include "sgIP_ARP.h" 27 | 28 | // the "Hub" software layer would be useful ONLY when supporting 29 | // multiple hardware ports (eg. ethernet AND wifi) 30 | // however, the NDS uses ONLY wifi (and SGIP_HUB_MAXPROTOCOLINTERFACES 31 | // and SGIP_HUB_MAXHWINTERFACES are both set to "1"), so most of the 32 | // "Hub" code could be replaced by directly accessing wifi functions) 33 | //------------------ 34 | 35 | ////////////////////////////////////////////////////////////////////////// 36 | // Global vars 37 | 38 | int NumHWInterfaces; 39 | int NumProtocolInterfaces; 40 | sgIP_Hub_Protocol ProtocolInterfaces[SGIP_HUB_MAXPROTOCOLINTERFACES]; 41 | sgIP_Hub_HWInterface HWInterfaces[SGIP_HUB_MAXHWINTERFACES]; 42 | 43 | 44 | 45 | ////////////////////////////////////////////////////////////////////////// 46 | // Private functions 47 | 48 | 49 | 50 | 51 | 52 | 53 | ////////////////////////////////////////////////////////////////////////// 54 | // Public functions 55 | 56 | 57 | void sgIP_Hub_Init() { 58 | NumHWInterfaces=0; 59 | NumProtocolInterfaces=0; 60 | 61 | } 62 | 63 | sgIP_Hub_Protocol * sgIP_Hub_AddProtocolInterface(int protocolID, int (*ReceivePacket)(sgIP_memblock *), int (*InterfaceInit)(sgIP_Hub_Protocol *)) { 64 | int n; 65 | if(NumProtocolInterfaces>=SGIP_HUB_MAXPROTOCOLINTERFACES) return 0; 66 | for(n=0;n=SGIP_HUB_MAXHWINTERFACES) return 0; 83 | for(n=0;nflags=0; 102 | NumProtocolInterfaces--; 103 | } 104 | extern void sgIP_Hub_RemoveHardwareInterface(sgIP_Hub_HWInterface * hw) { 105 | int n; 106 | for(n=0;nflags=0; 111 | NumHWInterfaces--; 112 | } 113 | 114 | int sgIP_Hub_ReceiveHardwarePacket(sgIP_Hub_HWInterface * hw, sgIP_memblock * packet) { 115 | if(!hw || !packet) return 0; 116 | if(hw->flags & SGIP_FLAG_HWINTERFACE_ENABLED) { 117 | int n; 118 | int protocol; 119 | 120 | protocol = ((unsigned short *)packet->datastart)[6]; 121 | // SGIP_DEBUG_MESSAGE(("hub: rx packet %04X %X",protocol,packet->totallength)); 122 | if(protocol==PROTOCOL_ETHER_ARP) { // arp 123 | sgIP_ARP_ProcessARPFrame(hw,packet); 124 | return 0; 125 | } 126 | if(protocol==PROTOCOL_ETHER_IP) { // IP, forward to the ARP system. 127 | 128 | } 129 | 130 | // hide ethernet header for higher-level protocols 131 | sgIP_memblock_exposeheader(packet,-14); 132 | for(n=0;nsnmask) == (dest_address & hw->snmask) // on same network 156 | || dest_address == 0xFFFFFFFF ) // or broadcast address, send directly. 157 | { 158 | return sgIP_ARP_SendProtocolFrame(hw,packet,protocol,dest_address); 159 | } else { // eek, on different network. Send to gateway 160 | return sgIP_ARP_SendProtocolFrame(hw,packet,protocol,hw->gateway); 161 | } 162 | } 163 | // send packet on a hardware interface. 164 | int sgIP_Hub_SendRawPacket(sgIP_Hub_HWInterface * hw, sgIP_memblock * packet) { 165 | if(!hw || !packet) return 0; 166 | if(hw->flags&SGIP_FLAG_HWINTERFACE_ENABLED) { 167 | return hw->TransmitFunction(hw,packet); 168 | } 169 | sgIP_memblock_free(packet); 170 | return 0; 171 | } 172 | 173 | int sgIP_Hub_IPMaxMessageSize(unsigned long ipaddr) { 174 | return SGIP_MTU_OVERRIDE; // hack - make this more accurate soon! 175 | } 176 | 177 | unsigned long sgIP_Hub_GetCompatibleIP(unsigned long destIP) { 178 | int n; 179 | for(n=0;n>8); 206 | } 207 | unsigned long htonl(unsigned long num) { 208 | return (num<<24) | ((num&0xFF00)<<8) | ((num&0xFF0000)>>8) | (num>>24); 209 | } 210 | #else 211 | unsigned short htons(unsigned short num) { 212 | return num; 213 | } 214 | unsigned long htonl(unsigned long num) { 215 | return num; 216 | } 217 | #endif 218 | 219 | -------------------------------------------------------------------------------- /arm9/source/sgIP_Hub.h: -------------------------------------------------------------------------------- 1 | // DSWifi Project - sgIP Internet Protocol Stack Implementation 2 | // Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org 3 | /****************************************************************************** 4 | DSWifi Lib and test materials are licenced under the MIT open source licence: 5 | Copyright (c) 2005-2006 Stephen Stair 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | this software and associated documentation files (the "Software"), to deal in 9 | the Software without restriction, including without limitation the rights to 10 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 11 | of the Software, and to permit persons to whom the Software is furnished to do 12 | so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | ******************************************************************************/ 25 | #ifndef SGIP_HUB_H 26 | #define SGIP_HUB_H 27 | 28 | #include "sgIP_Config.h" 29 | #include "sgIP_memblock.h" 30 | 31 | 32 | 33 | #define SGIP_FLAG_PROTOCOL_IN_USE 0x0001 34 | #define SGIP_FLAG_PROTOCOL_ENABLED 0x8000 35 | 36 | #define SGIP_FLAG_HWINTERFACE_IN_USE 0x0001 37 | #define SGIP_FLAG_HWINTERFACE_CONNECTED 0x0002 38 | #define SGIP_FLAG_HWINTERFACE_USEDHCP 0x0004 39 | #define SGIP_FLAG_HWINTERFACE_CHANGENETWORK 0x0008 40 | #define SGIP_FLAG_HWINTERFACE_ENABLED 0x8000 41 | 42 | #ifdef SGIP_LITTLEENDIAN 43 | #define PROTOCOL_ETHER_ARP 0x0608 44 | #define PROTOCOL_ETHER_IP 0x0008 45 | #ifdef with_dsi_wifi 46 | #define PROTOCOL_ETHER_EAPOL 0x8e88 //=htons(888Eh) 47 | #endif 48 | #define HWSPACE_ETHERNET 0x0100 //=htons(0001h) 49 | #define ARP_OPCODE_REQUEST 0x0100 //=htons(0001h) 50 | #define ARP_OPCODE_RESPONSE 0x0200 //=htons(0002h) 51 | #define DNS_PORT 0x3500 //=htons(53) 52 | #else 53 | #define PROTOCOL_ETHER_ARP 0x0806 54 | #define PROTOCOL_ETHER_IP 0x0800 55 | #ifdef with_dsi_wifi 56 | #define PROTOCOL_ETHER_EAPOL 0x888e 57 | #endif 58 | #define HWSPACE_ETHERNET 0x0001 59 | #define ARP_OPCODE_REQUEST 0x0001 60 | #define ARP_OPCODE_RESPONSE 0x0002 61 | #endif 62 | 63 | 64 | // structure sgIP_Hub_Protocol: Used to record the interface between the sgIP Hub and a protocol handler 65 | typedef struct SGIP_HUB_PROTOCOL { 66 | unsigned short flags; 67 | unsigned short protocol; 68 | int (*ReceivePacket)(sgIP_memblock *); 69 | 70 | } sgIP_Hub_Protocol; 71 | 72 | typedef struct SGIP_HUB_HWINTERFACE { 73 | unsigned short flags; 74 | unsigned short hwaddrlen; 75 | int MTU; 76 | int (*TransmitFunction)(struct SGIP_HUB_HWINTERFACE *, sgIP_memblock *); 77 | void * userdata; 78 | unsigned long ipaddr, gateway, snmask, dns[3]; 79 | unsigned char hwaddr[SGIP_MAXHWADDRLEN]; 80 | } sgIP_Hub_HWInterface; 81 | 82 | typedef struct SGIP_HEADER_ETHERNET { 83 | unsigned char dest_mac[6]; 84 | unsigned char src_mac[6]; 85 | unsigned short protocol; 86 | } sgIP_Header_Ethernet; 87 | 88 | #define ntohs(num) htons(num) 89 | #define ntohl(num) htonl(num) 90 | 91 | 92 | #ifdef __cplusplus 93 | extern "C" { 94 | #endif 95 | 96 | 97 | extern void sgIP_Hub_Init(); 98 | 99 | 100 | extern sgIP_Hub_Protocol * sgIP_Hub_AddProtocolInterface(int protocolID, int (*ReceivePacket)(sgIP_memblock *), int (*InterfaceInit)(sgIP_Hub_Protocol *)); 101 | extern sgIP_Hub_HWInterface * sgIP_Hub_AddHardwareInterface(int (*TransmitFunction)(sgIP_Hub_HWInterface *, sgIP_memblock *), int (*InterfaceInit)(sgIP_Hub_HWInterface *)); 102 | extern void sgIP_Hub_RemoveProtocolInterface(sgIP_Hub_Protocol * protocol); 103 | extern void sgIP_Hub_RemoveHardwareInterface(sgIP_Hub_HWInterface * hw); 104 | 105 | extern int sgIP_Hub_ReceiveHardwarePacket(sgIP_Hub_HWInterface * hw, sgIP_memblock * packet); 106 | extern int sgIP_Hub_SendProtocolPacket(int protocol, sgIP_memblock * packet, unsigned long dest_address, unsigned long src_address); 107 | extern int sgIP_Hub_SendRawPacket(sgIP_Hub_HWInterface * hw, sgIP_memblock * packet); 108 | 109 | extern int sgIP_Hub_IPMaxMessageSize(unsigned long ipaddr); 110 | unsigned long sgIP_Hub_GetCompatibleIP(unsigned long destIP); 111 | 112 | extern sgIP_Hub_HWInterface * sgIP_Hub_GetDefaultInterface(); 113 | 114 | unsigned short htons(unsigned short num); 115 | unsigned long htonl(unsigned long num); 116 | 117 | #ifdef __cplusplus 118 | }; 119 | #endif 120 | 121 | 122 | #endif 123 | -------------------------------------------------------------------------------- /arm9/source/sgIP_ICMP.c: -------------------------------------------------------------------------------- 1 | // DSWifi Project - sgIP Internet Protocol Stack Implementation 2 | // Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org 3 | /****************************************************************************** 4 | DSWifi Lib and test materials are licenced under the MIT open source licence: 5 | Copyright (c) 2005-2006 Stephen Stair 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | this software and associated documentation files (the "Software"), to deal in 9 | the Software without restriction, including without limitation the rights to 10 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 11 | of the Software, and to permit persons to whom the Software is furnished to do 12 | so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | ******************************************************************************/ 25 | 26 | #include "sgIP_ICMP.h" 27 | #include "sgIP_IP.h" 28 | #include "sgIP_Hub.h" 29 | 30 | void sgIP_ICMP_Init() { 31 | 32 | } 33 | 34 | int sgIP_ICMP_ReceivePacket(sgIP_memblock * mb, unsigned long srcip, unsigned long destip) { 35 | if(!mb) return 0; 36 | sgIP_Header_ICMP * icmp; 37 | icmp = (sgIP_Header_ICMP *) mb->datastart; 38 | if(icmp->checksum!=0 && sgIP_memblock_IPChecksum(mb,0,mb->totallength)!=0xFFFF) { 39 | SGIP_DEBUG_MESSAGE(("ICMP receive checksum incorrect")); 40 | sgIP_memblock_free(mb); 41 | return 0; 42 | } 43 | switch(icmp->type) { 44 | case 8: // echo request 45 | icmp->type=0; // change to echo reply 46 | // mod checksum 47 | icmp->checksum=0; 48 | icmp->checksum=~sgIP_memblock_IPChecksum(mb,0,mb->totallength); 49 | return sgIP_IP_SendViaIP(mb,PROTOCOL_IP_ICMP,destip,srcip); 50 | case 0: // echo reply (ignore for now) 51 | default: // others (ignore for now) 52 | break; 53 | } 54 | sgIP_memblock_free(mb); 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /arm9/source/sgIP_ICMP.h: -------------------------------------------------------------------------------- 1 | // DSWifi Project - sgIP Internet Protocol Stack Implementation 2 | // Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org 3 | /****************************************************************************** 4 | DSWifi Lib and test materials are licenced under the MIT open source licence: 5 | Copyright (c) 2005-2006 Stephen Stair 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | this software and associated documentation files (the "Software"), to deal in 9 | the Software without restriction, including without limitation the rights to 10 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 11 | of the Software, and to permit persons to whom the Software is furnished to do 12 | so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | ******************************************************************************/ 25 | #ifndef SGIP_ICMP_H 26 | #define SGIP_ICMP_H 27 | 28 | #include "sgIP_Config.h" 29 | #include "sgIP_memblock.h" 30 | 31 | typedef struct SGIP_HEADER_ICMP { 32 | unsigned char type,code; 33 | unsigned short checksum; 34 | unsigned long xtra; 35 | } sgIP_Header_ICMP; 36 | 37 | #ifdef __cplusplus 38 | extern "C" { 39 | #endif 40 | 41 | extern void sgIP_ICMP_Init(); 42 | 43 | extern int sgIP_ICMP_ReceivePacket(sgIP_memblock * mb, unsigned long srcip, unsigned long destip); 44 | 45 | 46 | 47 | #ifdef __cplusplus 48 | }; 49 | #endif 50 | 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /arm9/source/sgIP_IP.c: -------------------------------------------------------------------------------- 1 | // DSWifi Project - sgIP Internet Protocol Stack Implementation 2 | // Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org 3 | /****************************************************************************** 4 | DSWifi Lib and test materials are licenced under the MIT open source licence: 5 | Copyright (c) 2005-2006 Stephen Stair 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | this software and associated documentation files (the "Software"), to deal in 9 | the Software without restriction, including without limitation the rights to 10 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 11 | of the Software, and to permit persons to whom the Software is furnished to do 12 | so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | ******************************************************************************/ 25 | 26 | #include "sgIP_IP.h" 27 | #include "sgIP_TCP.h" 28 | #include "sgIP_UDP.h" 29 | #include "sgIP_ICMP.h" 30 | #include "sgIP_Hub.h" 31 | 32 | int idnum_count; 33 | 34 | int sgIP_IP_ReceivePacket(sgIP_memblock * mb) { 35 | sgIP_Header_IP * iphdr; 36 | unsigned short * chksum_calc; 37 | int chksum_temp; 38 | int hdrlen; 39 | 40 | iphdr=(sgIP_Header_IP *)mb->datastart; 41 | chksum_calc=(unsigned short *)mb->datastart; 42 | // check that header is valid: 43 | hdrlen=iphdr->version_ihl&15; 44 | // check length... 45 | if(mb->totallengthtot_length)) { 46 | SGIP_DEBUG_MESSAGE(("IP: bad length!")); 47 | SGIP_DEBUG_MESSAGE(("-%i/%i",mb->totallength,htons(iphdr->tot_length))); 48 | sgIP_memblock_free(mb); 49 | return 0; // bad size. 50 | } 51 | sgIP_memblock_trimsize(mb,htons(iphdr->tot_length)); 52 | // check version 53 | if((iphdr->version_ihl>>4)!=4) { 54 | SGIP_DEBUG_MESSAGE(("IP: bad version!")); 55 | sgIP_memblock_free(mb); 56 | return 0; // bad version. 57 | } 58 | 59 | // check checksum 60 | chksum_temp=sgIP_memblock_IPChecksum(mb,0,hdrlen*4); 61 | if(chksum_temp!=0xFFFF) { // bad chksum! kill packet. 62 | SGIP_DEBUG_MESSAGE(("IP: bad checksum!")); 63 | sgIP_memblock_free(mb); 64 | return 0; // bad checksum. 65 | } 66 | if(htons(iphdr->fragment_offset)&0x3FFF) { // fragmented! oh noes! We can't deal with this! 67 | SGIP_DEBUG_MESSAGE(("IP: fragmented!")); 68 | sgIP_memblock_free(mb); 69 | return 0; // fragmented. 70 | } 71 | 72 | sgIP_memblock_exposeheader(mb,-hdrlen*4); 73 | switch(iphdr->protocol) { 74 | case PROTOCOL_IP_ICMP: // ICMP 75 | sgIP_ICMP_ReceivePacket(mb,iphdr->src_address,iphdr->dest_address); 76 | break; 77 | case PROTOCOL_IP_TCP: // TCP 78 | sgIP_TCP_ReceivePacket(mb,iphdr->src_address,iphdr->dest_address); 79 | break; 80 | case PROTOCOL_IP_UDP: // UDP 81 | sgIP_UDP_ReceivePacket(mb,iphdr->src_address,iphdr->dest_address); 82 | break; 83 | default: 84 | sgIP_memblock_free(mb); 85 | } 86 | 87 | return 0; 88 | } 89 | int sgIP_IP_MaxContentsSize(unsigned long destip) { 90 | return sgIP_Hub_IPMaxMessageSize(destip)-sgIP_IP_RequiredHeaderSize(); 91 | } 92 | int sgIP_IP_RequiredHeaderSize() { 93 | return 5*4; // we'll not include zeroed options. 94 | } 95 | int sgIP_IP_SendViaIP(sgIP_memblock * mb, int protocol, unsigned long srcip, unsigned long destip) { 96 | sgIP_Header_IP * iphdr; 97 | unsigned short * chksum_calc; 98 | int i; 99 | unsigned int chksum_temp; 100 | sgIP_memblock_exposeheader(mb,20); 101 | iphdr=(sgIP_Header_IP *)mb->datastart; 102 | chksum_calc=(unsigned short *)mb->datastart; 103 | iphdr->dest_address=destip; 104 | iphdr->fragment_offset=0; 105 | iphdr->header_checksum=0; 106 | iphdr->identification=idnum_count++; 107 | iphdr->protocol=protocol; 108 | iphdr->src_address=srcip; 109 | iphdr->tot_length=htons(mb->totallength); 110 | iphdr->TTL=SGIP_IP_TTL; 111 | iphdr->type_of_service=0; 112 | iphdr->version_ihl=0x45; 113 | 114 | //BUGGED: probably should add CY on CY (as done in other checksum funcs?) 115 | // and 'unclean' in original code: variable is named "chksum_temp" here 116 | // (whilst most other/similar functions have it named "checksum") 117 | // and a general issue for all those checksum functions: 118 | // the checksum is defined as (signed?) "int", so the right-shifting 119 | // would sign-extended "negative" checksums? (though the sign in bit31 120 | // will be probably usually zero, unless for very large packets) 121 | chksum_temp=0; 122 | for(i=0;i<10;i++) chksum_temp+=chksum_calc[i]; 123 | chksum_temp += chksum_temp>>16; 124 | chksum_temp &= 0xFFFF; 125 | chksum_temp = ~chksum_temp; 126 | 127 | // uh, so? (condition in original C code was BUGGED: set MSW=0, then MSW=(not 0), then checking if value=0... which cannot ever happen due to MSW=FFFFh) 128 | if(chksum_temp==0) chksum_temp=0xFFFF; 129 | 130 | iphdr->header_checksum=chksum_temp; 131 | 132 | return sgIP_Hub_SendProtocolPacket(htons(0x0800),mb,destip,srcip); 133 | } 134 | unsigned long sgIP_IP_GetLocalBindAddr(unsigned long srcip, unsigned long destip) { 135 | if(srcip) return srcip; 136 | return sgIP_Hub_GetCompatibleIP(destip); 137 | } 138 | -------------------------------------------------------------------------------- /arm9/source/sgIP_IP.h: -------------------------------------------------------------------------------- 1 | // DSWifi Project - sgIP Internet Protocol Stack Implementation 2 | // Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org 3 | /****************************************************************************** 4 | DSWifi Lib and test materials are licenced under the MIT open source licence: 5 | Copyright (c) 2005-2006 Stephen Stair 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | this software and associated documentation files (the "Software"), to deal in 9 | the Software without restriction, including without limitation the rights to 10 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 11 | of the Software, and to permit persons to whom the Software is furnished to do 12 | so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | ******************************************************************************/ 25 | #ifndef SGIP_IP_H 26 | #define SGIP_IP_H 27 | 28 | #include "sgIP_memblock.h" 29 | 30 | #define PROTOCOL_IP_ICMP 1 31 | #define PROTOCOL_IP_TCP 6 32 | #define PROTOCOL_IP_UDP 17 33 | 34 | typedef struct SGIP_HEADER_IP { 35 | unsigned char version_ihl; // version = top 4 bits == 4, IHL = header length in 32bit increments = bottom 4 bits 36 | unsigned char type_of_service; // [3bit prescidence][ D ][ T ][ R ][ 0 0 ] - D=low delya, T=high thoroughput, R= high reliability 37 | unsigned short tot_length; // total length of packet including header 38 | unsigned short identification; // value assigned by sender to aid in packet reassembly 39 | unsigned short fragment_offset; // top 3 bits are flags [0][DF][MF] (Don't Fragment / More Fragments Exist) - offset is in 8-byte chunks. 40 | unsigned char TTL; // time to live, measured in hops 41 | unsigned char protocol; // protocols: ICMP=1, TCP=6, UDP=17 42 | unsigned short header_checksum; // checksum: 43 | unsigned long src_address; // src address is 32bit IP address 44 | unsigned long dest_address; // dest address is 32bit IP address 45 | unsigned char options[4]; // optional options come here. 46 | } sgIP_Header_IP; 47 | 48 | 49 | #ifdef __cplusplus 50 | extern "C" { 51 | #endif 52 | 53 | extern int sgIP_IP_ReceivePacket(sgIP_memblock * mb); 54 | extern int sgIP_IP_MaxContentsSize(unsigned long destip); 55 | extern int sgIP_IP_RequiredHeaderSize(); 56 | extern int sgIP_IP_SendViaIP(sgIP_memblock * mb, int protocol, unsigned long srcip, unsigned long destip); 57 | extern unsigned long sgIP_IP_GetLocalBindAddr(unsigned long srcip, unsigned long destip); 58 | 59 | #ifdef __cplusplus 60 | }; 61 | #endif 62 | 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /arm9/source/sgIP_TCP.h: -------------------------------------------------------------------------------- 1 | // DSWifi Project - sgIP Internet Protocol Stack Implementation 2 | // Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org 3 | /****************************************************************************** 4 | DSWifi Lib and test materials are licenced under the MIT open source licence: 5 | Copyright (c) 2005-2006 Stephen Stair 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | this software and associated documentation files (the "Software"), to deal in 9 | the Software without restriction, including without limitation the rights to 10 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 11 | of the Software, and to permit persons to whom the Software is furnished to do 12 | so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | ******************************************************************************/ 25 | #ifndef SGIP_TCP_H 26 | #define SGIP_TCP_H 27 | 28 | #include "sgIP_Config.h" 29 | #include "sgIP_memblock.h" 30 | 31 | enum SGIP_TCP_STATE { 32 | SGIP_TCP_STATE_NODATA, // newly allocated 33 | SGIP_TCP_STATE_UNUSED, // allocated & BINDed 34 | SGIP_TCP_STATE_LISTEN, // listening 35 | SGIP_TCP_STATE_SYN_SENT, // connect initiated 36 | SGIP_TCP_STATE_SYN_RECEIVED, // spawned from listen socket; 37 | SGIP_TCP_STATE_ESTABLISHED, // syns have been exchanged 38 | SGIP_TCP_STATE_FIN_WAIT_1, // sent a FIN, haven't got FIN or ACK yet. 39 | SGIP_TCP_STATE_FIN_WAIT_2, // got ACK for our FIN, haven't got FIN yet. 40 | SGIP_TCP_STATE_CLOSE_WAIT, // got FIN, wait for user code to close socket & send FIN 41 | SGIP_TCP_STATE_CLOSING, // got FIN, waiting for ACK of our FIN 42 | SGIP_TCP_STATE_LAST_ACK, // wait for ACK of our last FIN 43 | SGIP_TCP_STATE_TIME_WAIT, // wait to ensure remote tcp knows it's been terminated. 44 | SGIP_TCP_STATE_CLOSED, // Block is unused. 45 | }; 46 | 47 | 48 | #define SGIP_TCP_FLAG_FIN 1 49 | #define SGIP_TCP_FLAG_SYN 2 50 | #define SGIP_TCP_FLAG_RST 4 51 | #define SGIP_TCP_FLAG_PSH 8 52 | #define SGIP_TCP_FLAG_ACK 16 53 | #define SGIP_TCP_FLAG_URG 32 54 | 55 | typedef struct SGIP_HEADER_TCP { 56 | unsigned short srcport,destport; 57 | unsigned long seqnum; 58 | unsigned long acknum; 59 | unsigned char dataofs_; 60 | unsigned char tcpflags; 61 | unsigned short window; 62 | unsigned short checksum; 63 | unsigned short urg_ptr; 64 | unsigned char options[4]; 65 | } sgIP_Header_TCP; 66 | 67 | 68 | // sgIP_Record_TCP - a TCP record, to store data for an active TCP connection. 69 | typedef struct SGIP_RECORD_TCP { 70 | struct SGIP_RECORD_TCP * next; // operate as a linked list 71 | // TCP state information 72 | int tcpstate; 73 | unsigned long sequence; // sequence number of first byte not acknowledged by remote system 74 | unsigned long ack; // external sequence number of next byte to receive 75 | unsigned long sequence_next; // sequence number of first unsent byte 76 | unsigned long rxwindow; // sequence of last byte in receive window 77 | unsigned long txwindow; // sequence of last byte allowed to send 78 | int time_last_action; // used for retransmission and etc. 79 | int time_backoff; 80 | int retrycount; 81 | unsigned long srcip; 82 | unsigned long destip; 83 | unsigned short srcport,destport; 84 | struct SGIP_RECORD_TCP ** listendata; 85 | int maxlisten; 86 | int errorcode; 87 | int want_shutdown; // 0= don't want shutdown, 1= want shutdown, 2= being shutdown 88 | int want_reack; 89 | // TCP buffer information: 90 | int buf_rx_in, buf_rx_out; 91 | int buf_tx_in, buf_tx_out; 92 | int buf_oob_in, buf_oob_out; 93 | unsigned char buf_rx[SGIP_TCP_RECEIVEBUFFERLENGTH]; 94 | unsigned char buf_tx[SGIP_TCP_TRANSMITBUFFERLENGTH]; 95 | unsigned char buf_oob[SGIP_TCP_OOBBUFFERLENGTH]; 96 | } sgIP_Record_TCP; 97 | 98 | typedef struct SGIP_TCP_SYNCOOKIE { 99 | unsigned long localseq, remoteseq; 100 | unsigned long localip, remoteip; 101 | unsigned short localport, remoteport; 102 | unsigned long timenext,timebackoff; 103 | sgIP_Record_TCP * linked; // parent listening connection 104 | } sgIP_TCP_SYNCookie; 105 | 106 | 107 | 108 | #ifdef __cplusplus 109 | extern "C" { 110 | #endif 111 | 112 | extern void sgIP_TCP_Init(); 113 | extern void sgIP_TCP_Timer(); 114 | 115 | extern int sgIP_TCP_ReceivePacket(sgIP_memblock * mb, unsigned long srcip, unsigned long destip); 116 | extern int sgIP_TCP_SendPacket(sgIP_Record_TCP * rec, int flags, int datalength); // data sent is taken directly from the TX fifo. 117 | extern int sgIP_TCP_SendSynReply(int flags,unsigned long seq, unsigned long ack, unsigned long srcip, unsigned long destip, int srcport, int destport, int windowlen); 118 | 119 | extern sgIP_Record_TCP * sgIP_TCP_AllocRecord(); 120 | extern void sgIP_TCP_FreeRecord(sgIP_Record_TCP * rec); 121 | extern int sgIP_TCP_Bind(sgIP_Record_TCP * rec, int srcport, unsigned long srcip); 122 | extern int sgIP_TCP_Listen(sgIP_Record_TCP * rec, int maxlisten); 123 | extern sgIP_Record_TCP * sgIP_TCP_Accept(sgIP_Record_TCP * rec); 124 | extern int sgIP_TCP_Close(sgIP_Record_TCP * rec); 125 | extern int sgIP_TCP_Connect(sgIP_Record_TCP * rec, unsigned long destip, int destport); 126 | extern int sgIP_TCP_Send(sgIP_Record_TCP * rec, const char * datatosend, int datalength, int flags); 127 | extern int sgIP_TCP_Recv(sgIP_Record_TCP * rec, char * databuf, int buflength, int flags); 128 | 129 | #ifdef __cplusplus 130 | }; 131 | #endif 132 | 133 | 134 | #endif 135 | -------------------------------------------------------------------------------- /arm9/source/sgIP_UDP.c: -------------------------------------------------------------------------------- 1 | // DSWifi Project - sgIP Internet Protocol Stack Implementation 2 | // Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org 3 | /****************************************************************************** 4 | DSWifi Lib and test materials are licenced under the MIT open source licence: 5 | Copyright (c) 2005-2006 Stephen Stair 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | this software and associated documentation files (the "Software"), to deal in 9 | the Software without restriction, including without limitation the rights to 10 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 11 | of the Software, and to permit persons to whom the Software is furnished to do 12 | so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | ******************************************************************************/ 25 | 26 | #include "sgIP_Hub.h" 27 | #include "sgIP_UDP.h" 28 | #include "sgIP_IP.h" 29 | 30 | sgIP_Record_UDP * udprecords; 31 | int udpport_counter; 32 | extern unsigned long volatile sgIP_timems; 33 | 34 | void sgIP_UDP_Init() { 35 | udprecords=0; 36 | udpport_counter=SGIP_UDP_FIRSTOUTGOINGPORT; 37 | } 38 | 39 | 40 | int sgIP_UDP_GetUnusedOutgoingPort() { 41 | int myport,clear; 42 | sgIP_Record_UDP * rec; 43 | udpport_counter+=(sgIP_timems&1023); // semi-random 44 | if(udpport_counter>SGIP_UDP_LASTOUTGOINGPORT) udpport_counter=SGIP_UDP_FIRSTOUTGOINGPORT; 45 | while(1) { 46 | rec = udprecords; 47 | myport=udpport_counter++; 48 | if(udpport_counter>SGIP_UDP_LASTOUTGOINGPORT) udpport_counter=SGIP_UDP_FIRSTOUTGOINGPORT; 49 | clear=1; 50 | while(rec) { 51 | if(rec->srcport==myport) { clear=0; break; } 52 | rec=rec->next; 53 | } 54 | if(clear) return myport; 55 | } 56 | } 57 | 58 | int sgIP_UDP_CalcChecksum(sgIP_memblock * mb, unsigned long srcip, unsigned long destip, int totallength) { 59 | int checksum; 60 | if(!mb) return 0; 61 | if(mb->totallength&1) mb->datastart[mb->totallength]=0; 62 | checksum=sgIP_memblock_IPChecksum(mb,0,mb->totallength); 63 | // add in checksum of "faux header" 64 | checksum+=(destip&0xFFFF); 65 | checksum+=(destip>>16); 66 | checksum+=(srcip&0xFFFF); 67 | checksum+=(srcip>>16); 68 | checksum+=htons(totallength); 69 | checksum+=(17)<<8; 70 | checksum=(checksum&0xFFFF) + (checksum>>16); 71 | checksum=(checksum&0xFFFF) + (checksum>>16); 72 | 73 | checksum = (~checksum)&0xFFFF; 74 | if(checksum==0) checksum=0xFFFF; 75 | return checksum; 76 | } 77 | 78 | int sgIP_UDP_ReceivePacket(sgIP_memblock * mb, unsigned long srcip, unsigned long destip) { 79 | if(!mb) return 0; 80 | int chk = sgIP_UDP_CalcChecksum(mb,srcip,destip,mb->totallength); 81 | sgIP_Header_UDP * udp; 82 | udp=(sgIP_Header_UDP *)mb->datastart; 83 | if(chk!=0xFFFF && udp->checksum != 0) { 84 | SGIP_DEBUG_MESSAGE(("UDP receive checksum incorrect")); 85 | sgIP_memblock_free(mb); 86 | return 0; // checksum error 87 | } 88 | sgIP_Record_UDP * rec; 89 | sgIP_memblock *tmb; 90 | SGIP_INTR_PROTECT(); 91 | rec=udprecords; 92 | 93 | while(rec) { 94 | if((rec->srcip==destip || rec->srcip==0) && rec->srcport==udp->destport && rec->state!=SGIP_UDP_STATE_UNUSED) break; // a match! 95 | rec=rec->next; 96 | } 97 | if(!rec) { // no matching records 98 | sgIP_memblock_free(mb); 99 | SGIP_INTR_UNPROTECT(); 100 | return 0; 101 | } 102 | // we have a record and a packet for it; add some data to the record and stuff it into the record queue. 103 | sgIP_memblock_exposeheader(mb,4); 104 | *((unsigned long *)mb->datastart)=srcip; // keep srcip around. 105 | if(rec->incoming_queue==0) { 106 | rec->incoming_queue=mb; 107 | } else { 108 | rec->incoming_queue_end->next=mb; 109 | } 110 | 111 | tmb=mb; 112 | while(tmb->next) tmb=tmb->next; 113 | rec->incoming_queue_end=tmb; 114 | // ok, data added to queue - yay! 115 | // that means... we're done. 116 | 117 | SGIP_INTR_UNPROTECT(); 118 | return 0; 119 | } 120 | 121 | int sgIP_UDP_SendPacket(sgIP_Record_UDP * rec, const char * data, int datalen, unsigned long destip, int destport) { 122 | if(!rec || !data) return SGIP_ERROR(EINVAL); 123 | if(rec->state!=SGIP_UDP_STATE_BOUND) { 124 | rec->srcip=0; 125 | rec->srcport=sgIP_UDP_GetUnusedOutgoingPort(); 126 | rec->state=SGIP_UDP_STATE_BOUND; 127 | } 128 | sgIP_memblock * mb = sgIP_memblock_alloc(sgIP_IP_RequiredHeaderSize()+8+datalen); 129 | if(!mb) return SGIP_ERROR(ENOMEM); 130 | sgIP_memblock_exposeheader(mb,-sgIP_IP_RequiredHeaderSize()); // hide IP header space for later 131 | 132 | SGIP_INTR_PROTECT(); 133 | unsigned long srcip = sgIP_IP_GetLocalBindAddr(rec->srcip,destip); 134 | sgIP_Header_UDP * udp = (sgIP_Header_UDP *) mb->datastart; 135 | udp->srcport=rec->srcport; 136 | udp->destport=destport; 137 | udp->length=htons(datalen+8); 138 | udp->checksum=0; 139 | int i; 140 | for(i=0;idatastart[i+8]=data[i]; 142 | } 143 | udp->checksum=sgIP_UDP_CalcChecksum(mb,srcip,destip,mb->totallength); 144 | sgIP_IP_SendViaIP(mb,17,srcip,destip); 145 | 146 | SGIP_INTR_UNPROTECT(); 147 | return datalen; 148 | } 149 | 150 | sgIP_Record_UDP * sgIP_UDP_AllocRecord() { 151 | SGIP_INTR_PROTECT(); 152 | sgIP_Record_UDP * rec; 153 | rec = (sgIP_Record_UDP *)sgIP_malloc(sizeof(sgIP_Record_UDP)); 154 | if(rec) { 155 | rec->destip=0; 156 | rec->destport=0; 157 | rec->incoming_queue=0; 158 | rec->incoming_queue_end=0; 159 | rec->srcip=0; 160 | rec->srcport=0; 161 | rec->state=0; 162 | rec->next=udprecords; 163 | udprecords=rec; 164 | } 165 | SGIP_INTR_UNPROTECT(); 166 | return rec; 167 | } 168 | void sgIP_UDP_FreeRecord(sgIP_Record_UDP * rec) { 169 | if(!rec) return; 170 | SGIP_INTR_PROTECT(); 171 | sgIP_Record_UDP * t; 172 | // incoming queue is all clumped together as a single memblock, so, time to free it all in one call :) 173 | if(rec->incoming_queue) sgIP_memblock_free(rec->incoming_queue); // woohoo! 174 | rec->state=0; 175 | if(udprecords==rec) { 176 | udprecords=rec->next; 177 | } else { 178 | t=udprecords; 179 | while(t) { 180 | if(t->next==rec) { 181 | t->next=rec->next; 182 | break; 183 | } 184 | t=t->next; 185 | } 186 | } 187 | sgIP_free(rec); 188 | 189 | SGIP_INTR_UNPROTECT(); 190 | } 191 | 192 | int sgIP_UDP_Bind(sgIP_Record_UDP * rec, int srcport, unsigned long srcip) { 193 | if(!rec) return SGIP_ERROR(EINVAL); 194 | SGIP_INTR_PROTECT(); 195 | if(rec->state!=SGIP_UDP_STATE_UNUSED) { 196 | rec->srcip=srcip; 197 | rec->srcport=srcport; 198 | if(rec->state==SGIP_UDP_STATE_UNBOUND) rec->state=SGIP_UDP_STATE_BOUND; 199 | } 200 | SGIP_INTR_UNPROTECT(); 201 | return 0; 202 | } 203 | 204 | int sgIP_UDP_RecvFrom(sgIP_Record_UDP * rec, char * destbuf, int buflength, int flags, unsigned long * sender_ip, unsigned short * sender_port) { 205 | if(!rec || !destbuf || !sender_ip || !sender_port || buflength==0) return SGIP_ERROR(EINVAL); 206 | SGIP_INTR_PROTECT(); 207 | if(rec->incoming_queue==0) { 208 | SGIP_INTR_UNPROTECT(); 209 | return SGIP_ERROR(EWOULDBLOCK); 210 | } 211 | int packetlen=rec->incoming_queue->totallength-12; 212 | if(packetlen>buflength) { 213 | SGIP_INTR_UNPROTECT(); 214 | return SGIP_ERROR(EMSGSIZE); 215 | } 216 | sgIP_memblock * mb; 217 | *sender_ip=*((unsigned long *)rec->incoming_queue->datastart); 218 | *sender_port=((unsigned short *)rec->incoming_queue->datastart)[2]; 219 | int totlen,first, buf_start,i; 220 | totlen=rec->incoming_queue->totallength; 221 | first=12; 222 | buf_start=0; 223 | 224 | while(totlen>0 && rec->incoming_queue) { 225 | totlen-=rec->incoming_queue->thislength; 226 | for(i=first;iincoming_queue->thislength;i++) { 227 | destbuf[buf_start+i-first]=rec->incoming_queue->datastart[i]; 228 | } 229 | buf_start+=rec->incoming_queue->thislength-first; 230 | first=0; 231 | mb=rec->incoming_queue; 232 | rec->incoming_queue=rec->incoming_queue->next; 233 | mb->next=0; 234 | sgIP_memblock_free(mb); 235 | } 236 | if(!(rec->incoming_queue)) rec->incoming_queue_end=0; 237 | 238 | SGIP_INTR_UNPROTECT(); 239 | return buf_start; 240 | } 241 | 242 | int sgIP_UDP_SendTo(sgIP_Record_UDP * rec, const char * buf, int buflength, int flags, unsigned long dest_ip, int dest_port) { 243 | return sgIP_UDP_SendPacket(rec,buf,buflength,dest_ip,dest_port); 244 | } 245 | 246 | -------------------------------------------------------------------------------- /arm9/source/sgIP_UDP.h: -------------------------------------------------------------------------------- 1 | // DSWifi Project - sgIP Internet Protocol Stack Implementation 2 | // Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org 3 | /****************************************************************************** 4 | DSWifi Lib and test materials are licenced under the MIT open source licence: 5 | Copyright (c) 2005-2006 Stephen Stair 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | this software and associated documentation files (the "Software"), to deal in 9 | the Software without restriction, including without limitation the rights to 10 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 11 | of the Software, and to permit persons to whom the Software is furnished to do 12 | so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | ******************************************************************************/ 25 | 26 | 27 | #ifndef SGIP_UDP_H 28 | #define SGIP_UDP_H 29 | 30 | #include "sgIP_Config.h" 31 | #include "sgIP_memblock.h" 32 | 33 | 34 | enum SGIP_UDP_STATE { 35 | SGIP_UDP_STATE_UNBOUND, // newly allocated 36 | SGIP_UDP_STATE_BOUND, // got a source address/port 37 | SGIP_UDP_STATE_UNUSED, // no longer in use. 38 | }; 39 | 40 | 41 | typedef struct SGIP_HEADER_UDP { 42 | unsigned short srcport,destport; 43 | unsigned short length,checksum; 44 | } sgIP_Header_UDP; 45 | 46 | typedef struct SGIP_RECORD_UDP { 47 | struct SGIP_RECORD_UDP * next; 48 | 49 | int state; 50 | unsigned long srcip; 51 | unsigned long destip; 52 | unsigned short srcport,destport; 53 | 54 | sgIP_memblock * incoming_queue; 55 | sgIP_memblock * incoming_queue_end; 56 | 57 | } sgIP_Record_UDP; 58 | 59 | #ifdef __cplusplus 60 | extern "C" { 61 | #endif 62 | 63 | void sgIP_UDP_Init(); 64 | 65 | int sgIP_UDP_CalcChecksum(sgIP_memblock * mb, unsigned long srcip, unsigned long destip, int totallength); 66 | int sgIP_UDP_ReceivePacket(sgIP_memblock * mb, unsigned long srcip, unsigned long destip); 67 | int sgIP_UDP_SendPacket(sgIP_Record_UDP * rec, const char * data, int datalen, unsigned long destip, int destport); 68 | 69 | sgIP_Record_UDP * sgIP_UDP_AllocRecord(); 70 | void sgIP_UDP_FreeRecord(sgIP_Record_UDP * rec); 71 | 72 | int sgIP_UDP_Bind(sgIP_Record_UDP * rec, int srcport, unsigned long srcip); 73 | int sgIP_UDP_RecvFrom(sgIP_Record_UDP * rec, char * destbuf, int buflength, int flags, unsigned long * sender_ip, unsigned short * sender_port); 74 | int sgIP_UDP_SendTo(sgIP_Record_UDP * rec, const char * buf, int buflength, int flags, unsigned long dest_ip, int dest_port); 75 | 76 | #ifdef __cplusplus 77 | }; 78 | #endif 79 | 80 | 81 | #endif 82 | -------------------------------------------------------------------------------- /arm9/source/sgIP_memblock.c: -------------------------------------------------------------------------------- 1 | // DSWifi Project - sgIP Internet Protocol Stack Implementation 2 | // Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org 3 | /****************************************************************************** 4 | DSWifi Lib and test materials are licenced under the MIT open source licence: 5 | Copyright (c) 2005-2006 Stephen Stair 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | this software and associated documentation files (the "Software"), to deal in 9 | the Software without restriction, including without limitation the rights to 10 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 11 | of the Software, and to permit persons to whom the Software is furnished to do 12 | so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | ******************************************************************************/ 25 | 26 | #include "sgIP_memblock.h" 27 | 28 | #include 29 | #include 30 | 31 | #ifndef SGIP_MEMBLOCK_DYNAMIC_MALLOC_ALL 32 | 33 | #ifndef SGIP_USEDYNAMICMEMORY 34 | sgIP_memblock memblock_pool[SGIP_MEMBLOCK_BASENUM]; 35 | #else 36 | sgIP_memblock * memblock_pool; 37 | #endif 38 | 39 | sgIP_memblock * memblock_poolfree; 40 | int numused, numfree; 41 | void * pool_link; 42 | 43 | 44 | sgIP_memblock * sgIP_memblock_getunused() { 45 | int i; 46 | sgIP_memblock * mb; 47 | SGIP_INTR_PROTECT(); 48 | if(memblock_poolfree) { // we still have free memblocks! 49 | mb=memblock_poolfree; 50 | memblock_poolfree=mb->next; 51 | numfree--; 52 | numused++; 53 | } else { // oh noes, we have no more free memblocks. 54 | mb = 0; // eventually alloc new blocks, but for now just stop. 55 | } 56 | 57 | SGIP_INTR_UNPROTECT(); 58 | return mb; 59 | } 60 | #endif //SGIP_MEMBLOCK_DYNAMIC_MALLOC_ALL 61 | 62 | void sgIP_memblock_Init() { 63 | #ifndef SGIP_MEMBLOCK_DYNAMIC_MALLOC_ALL 64 | int i; 65 | #ifdef SGIP_USEDYNAMICMEMORY 66 | pool_link = sgIP_malloc(sizeof(sgIP_memblock)*SGIP_MEMBLOCK_BASENUM+4); 67 | ((long *)pool_link)[0]=0; 68 | memblock_pool = (sgIP_memblock *) (((char *)pool_link)+4); 69 | #endif 70 | numused=numfree=0; 71 | memblock_poolfree=0; 72 | for(i=0;itotallength=headersize+packetsize; 88 | mb->thislength=mb->totallength; 89 | mb->datastart=mb->reserved+SGIP_MAXHWHEADER-headersize; 90 | mb->next=0; 91 | return mb; 92 | } 93 | 94 | #else //SGIP_MEMBLOCK_DYNAMIC_MALLOC_ALL 95 | 96 | sgIP_memblock * sgIP_memblock_allocHW(int headersize, int packetsize) { 97 | sgIP_memblock * mb, * tmb, *t; 98 | int totlen; 99 | mb = sgIP_memblock_getunused(); 100 | if(!mb) return 0; 101 | mb->totallength=headersize+packetsize; 102 | mb->datastart=mb->reserved+SGIP_MAXHWHEADER-headersize; 103 | mb->next=0; 104 | mb->thislength=headersize+SGIP_MEMBLOCK_FIRSTINTERNALSIZE; 105 | if(mb->thislength>=mb->totallength) { 106 | mb->thislength = mb->totallength; 107 | // SGIP_DEBUG_MESSAGE(("memblock_alloc: %i free, %i used",numfree,numused)); 108 | return mb; 109 | } else { // need more blocks 110 | totlen=mb->thislength; 111 | tmb=mb; 112 | while(totlentotallength) { 113 | t=sgIP_memblock_getunused(); 114 | if(!t) { // we're skrewed. 115 | sgIP_memblock_free(mb); 116 | return 0; 117 | } 118 | tmb->next=t; 119 | t->totallength=mb->totallength; 120 | 121 | //BUGGED: original code points "CURR memblk's datastart to FIRST memblk" 122 | //FIX: below bugfix points "CURR memblk's datastart to CURR memblk" 123 | t->datastart=t->reserved; // no header on blocks after the first. 124 | t->next=0; 125 | t->thislength=SGIP_MEMBLOCK_INTERNALSIZE; 126 | if(t->thislength+totlen>=mb->totallength) { 127 | t->thislength=mb->totallength-totlen; 128 | // SGIP_DEBUG_MESSAGE(("memblock_alloc: %i free, %i used",numfree,numused)); 129 | return mb; 130 | } else { // need YET more blocks. 131 | totlen+=t->thislength; 132 | tmb=t; 133 | } // the cycle contiues. 134 | } 135 | sgIP_memblock_free(mb); // should never get here. 136 | } 137 | return 0; 138 | } 139 | #endif //SGIP_MEMBLOCK_DYNAMIC_MALLOC_ALL 140 | 141 | sgIP_memblock * sgIP_memblock_alloc(int packetsize) { 142 | return sgIP_memblock_allocHW(0,packetsize); 143 | } 144 | 145 | #ifdef SGIP_MEMBLOCK_DYNAMIC_MALLOC_ALL 146 | 147 | void sgIP_memblock_free(sgIP_memblock * mb) { 148 | sgIP_memblock * f; 149 | 150 | SGIP_INTR_PROTECT(); 151 | while(mb) { 152 | mb->totallength=0; 153 | mb->thislength=0; 154 | f=mb; 155 | mb = mb->next; 156 | 157 | sgIP_free(f); 158 | } 159 | 160 | SGIP_INTR_UNPROTECT(); 161 | } 162 | 163 | #else //SGIP_MEMBLOCK_DYNAMIC_MALLOC_ALL 164 | 165 | void sgIP_memblock_free(sgIP_memblock * mb) { 166 | sgIP_memblock * f; 167 | 168 | SGIP_INTR_PROTECT(); 169 | while(mb) { 170 | mb->totallength=0; 171 | mb->thislength=0; 172 | f=mb; 173 | mb = mb->next; 174 | 175 | numfree++; // reinstate memblock into the pool! 176 | numused--; 177 | f->next=memblock_poolfree; 178 | memblock_poolfree=f; 179 | } 180 | // SGIP_DEBUG_MESSAGE(("memblock_free: %i free, %i used",numfree,numused)); 181 | 182 | SGIP_INTR_UNPROTECT(); 183 | 184 | } 185 | 186 | #endif //SGIP_MEMBLOCK_DYNAMIC_MALLOC_ALL 187 | 188 | // positive to expose, negative to hide. 189 | void sgIP_memblock_exposeheader(sgIP_memblock * mb, int change) { 190 | if(mb) { 191 | mb->thislength+=change; 192 | mb->totallength+=change; 193 | mb->datastart-=change; 194 | while(mb->next) { 195 | mb->next->totallength=mb->totallength; 196 | mb=mb->next; 197 | } 198 | } 199 | } 200 | void sgIP_memblock_trimsize(sgIP_memblock * mb, int newsize) { 201 | int lentot; 202 | if(mb) { 203 | mb->totallength=newsize; 204 | 205 | //BUGGED: should "sgMemBlk_totallength" be also adjusted in below @@lop entries? 206 | // (ie. similar as done in the "sgIP_memblock_exposeheader" function?) 207 | lentot=0; 208 | while(mb) { 209 | lentot+=mb->thislength; 210 | if(lentot>newsize) { 211 | mb->thislength-=(lentot-newsize); 212 | if(mb->next) sgIP_memblock_free(mb->next); 213 | mb->next=0; 214 | return; 215 | } else { 216 | mb=mb->next; 217 | } 218 | } 219 | } 220 | } 221 | 222 | 223 | int sgIP_memblock_IPChecksum(sgIP_memblock * mb, int startbyte, int chksum_length) { 224 | int chksum_temp,offset; 225 | // check checksum 226 | chksum_temp=0; 227 | offset=0; 228 | while(mb && startbyte>mb->thislength) { startbyte-=mb->thislength; mb=mb->next; } 229 | if(!mb) return 0; 230 | while(chksum_length) { 231 | while(startbyte+offset+1thislength && chksum_length>1) { 232 | chksum_temp+= ((unsigned char *)mb->datastart)[startbyte+offset] + (((unsigned char *)mb->datastart)[startbyte+offset+1]<<8); 233 | offset+=2; 234 | chksum_length-=2; 235 | } 236 | chksum_temp= (chksum_temp&0xFFFF) +(chksum_temp>>16); 237 | if(startbyte+offsetthislength && chksum_length>0) { 238 | chksum_temp+= ((unsigned char *)mb->datastart)[startbyte+offset]; 239 | if(chksum_length==1) break; 240 | chksum_length--; 241 | offset=0; 242 | startbyte=0; 243 | 244 | //BUGGED: original code DOES ONLY CONTINUE at next memblk (via "mb=mb->next") 245 | //in ODD cases (when a halfword wraps last/first bytes of two memblk's), 246 | //whilst NORMAL cases (without wrap) do simply ABORT checksumming, outc 247 | //- - - 248 | //below check MSW+LSW merging is done INSIDE of @@check_lop to avoid overflows, 249 | //(which could otherwise happen when checksumming more than 128Kbytes at once) 250 | // TODO : fix the bug 251 | mb=mb->next; 252 | if(!mb) break; 253 | if(mb->thislength==0) break; 254 | chksum_temp+= ((unsigned char *)mb->datastart)[startbyte+offset]<<8; 255 | if(chksum_length==1) break; 256 | offset++; 257 | chksum_length--; 258 | } 259 | } 260 | chksum_temp= (chksum_temp&0xFFFF) +(chksum_temp>>16); 261 | chksum_temp= (chksum_temp&0xFFFF) +(chksum_temp>>16); 262 | return chksum_temp; 263 | } 264 | 265 | int sgIP_memblock_CopyToLinear(sgIP_memblock * mb, void * dest_buf, int startbyte, int copy_length) { 266 | int copylen,ofs_src, tot_copy; 267 | ofs_src=startbyte; 268 | while(mb && ofs_src>=mb->thislength) { ofs_src-=mb->thislength; mb=mb->next; } 269 | if(!mb) return 0; 270 | if(startbyte+copy_length>mb->totallength) copy_length=mb->totallength-startbyte; 271 | if(copy_length<0) copy_length=0; 272 | tot_copy=0; 273 | while(copy_length>0) { 274 | copylen=copy_length; 275 | if(copylen>mb->thislength-ofs_src) copylen=mb->thislength-ofs_src; 276 | memcpy(((char *)dest_buf)+tot_copy,mb->datastart+ofs_src,copylen); 277 | copy_length-=copylen; 278 | tot_copy+=copylen; 279 | ofs_src=0; 280 | mb=mb->next; 281 | if(!mb) break; 282 | } 283 | return tot_copy; 284 | } 285 | int sgIP_memblock_CopyFromLinear(sgIP_memblock * mb, void * src_buf, int startbyte, int copy_length) { 286 | int copylen,ofs_src, tot_copy; 287 | ofs_src=startbyte; 288 | while(mb && ofs_src>=mb->thislength) { ofs_src-=mb->thislength; mb=mb->next; } 289 | if(!mb) return 0; 290 | if(startbyte+copy_length>mb->totallength) copy_length=mb->totallength-startbyte; 291 | if(copy_length<0) copy_length=0; 292 | tot_copy=0; 293 | while(copy_length>0) { 294 | copylen=copy_length; 295 | if(copylen>mb->thislength-ofs_src) copylen=mb->thislength-ofs_src; 296 | memcpy(mb->datastart+ofs_src,((char *)src_buf)+tot_copy,copylen); 297 | copy_length-=copylen; 298 | tot_copy+=copylen; 299 | ofs_src=0; 300 | mb=mb->next; 301 | if(!mb) break; 302 | } 303 | return tot_copy; 304 | 305 | } 306 | int sgIP_memblock_CopyBlock(sgIP_memblock * mb_src, sgIP_memblock * mb_dest, int start_src, int start_dest, int copy_length) { 307 | 308 | return 0; 309 | } 310 | 311 | -------------------------------------------------------------------------------- /arm9/source/sgIP_memblock.h: -------------------------------------------------------------------------------- 1 | // DSWifi Project - sgIP Internet Protocol Stack Implementation 2 | // Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org 3 | /****************************************************************************** 4 | DSWifi Lib and test materials are licenced under the MIT open source licence: 5 | Copyright (c) 2005-2006 Stephen Stair 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | this software and associated documentation files (the "Software"), to deal in 9 | the Software without restriction, including without limitation the rights to 10 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 11 | of the Software, and to permit persons to whom the Software is furnished to do 12 | so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | ******************************************************************************/ 25 | 26 | 27 | #ifndef SGIP_MEMBLOCK_H 28 | #define SGIP_MEMBLOCK_H 29 | 30 | #include "sgIP_Config.h" 31 | 32 | 33 | typedef struct SGIP_MEMBLOCK { 34 | int totallength; 35 | int thislength; 36 | struct SGIP_MEMBLOCK * next; 37 | char * datastart; 38 | char reserved[SGIP_MEMBLOCK_DATASIZE-16]; // assume the other 4 values are 16 bytes total in length. 39 | } sgIP_memblock; 40 | 41 | #define SGIP_MEMBLOCK_HEADERSIZE 16 42 | #define SGIP_MEMBLOCK_INTERNALSIZE (SGIP_MEMBLOCK_DATASIZE-16) 43 | #define SGIP_MEMBLOCK_FIRSTINTERNALSIZE (SGIP_MEMBLOCK_DATASIZE-16-SGIP_MAXHWHEADER) 44 | 45 | #ifdef __cplusplus 46 | extern "C" { 47 | #endif 48 | 49 | extern void sgIP_memblock_Init(); 50 | extern sgIP_memblock * sgIP_memblock_alloc(int packetsize); 51 | extern sgIP_memblock * sgIP_memblock_allocHW(int headersize, int packetsize); 52 | extern void sgIP_memblock_free(sgIP_memblock * mb); 53 | extern void sgIP_memblock_exposeheader(sgIP_memblock * mb, int change); 54 | extern void sgIP_memblock_trimsize(sgIP_memblock * mb, int newsize); 55 | 56 | extern int sgIP_memblock_IPChecksum(sgIP_memblock * mb, int startbyte, int chksum_length); 57 | extern int sgIP_memblock_CopyToLinear(sgIP_memblock * mb, void * dest_buf, int startbyte, int copy_length); 58 | extern int sgIP_memblock_CopyFromLinear(sgIP_memblock * mb, void * src_buf, int startbyte, int copy_length); 59 | extern int sgIP_memblock_CopyBlock(sgIP_memblock * mb_src, sgIP_memblock * mb_dest, int start_src, int start_dest, int copy_length); 60 | #ifdef __cplusplus 61 | }; 62 | #endif 63 | 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /arm9/source/sgIP_sockets.h: -------------------------------------------------------------------------------- 1 | // DSWifi Project - sgIP Internet Protocol Stack Implementation 2 | // Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org 3 | /****************************************************************************** 4 | DSWifi Lib and test materials are licenced under the MIT open source licence: 5 | Copyright (c) 2005-2006 Stephen Stair 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | this software and associated documentation files (the "Software"), to deal in 9 | the Software without restriction, including without limitation the rights to 10 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 11 | of the Software, and to permit persons to whom the Software is furnished to do 12 | so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | ******************************************************************************/ 25 | 26 | #ifndef SGIP_SOCKETS_H 27 | #define SGIP_SOCKETS_H 28 | 29 | #include "sgIP_Config.h" 30 | #include "sys/socket.h" 31 | #include "netinet/in.h" 32 | #include "netdb.h" 33 | 34 | #define SGIP_SOCKET_FLAG_ALLOCATED 0x8000 35 | #define SGIP_SOCKET_FLAG_NONBLOCKING 0x4000 36 | #define SGIP_SOCKET_FLAG_VALID 0x2000 37 | #define SGIP_SOCKET_FLAG_CLOSING 0x1000 38 | #define SGIP_SOCKET_FLAG_TYPEMASK 0x0001 39 | #define SGIP_SOCKET_FLAG_TYPE_TCP 0x0001 40 | #define SGIP_SOCKET_FLAG_TYPE_UDP 0x0000 41 | #define SGIP_SOCKET_MASK_CLOSE_COUNT 0xFFFF0000 42 | #define SGIP_SOCKET_SHIFT_CLOSE_COUNT 16 43 | 44 | // Maybe define a better value for this in the future. But 5 minutes sounds ok. 45 | // TCP specification disagrees on this point, but this is a limited platform. 46 | // 5 minutes assuming 1000ms ticks = 300 = 0x12c 47 | #define SGIP_SOCKET_VALUE_CLOSE_COUNT (0x12c << SGIP_SOCKET_SHIFT_CLOSE_COUNT) 48 | 49 | typedef struct SGIP_SOCKET_DATA { 50 | unsigned int flags; 51 | void * conn_ptr; 52 | } sgIP_socket_data; 53 | 54 | #ifdef __cplusplus 55 | extern "C" { 56 | #endif 57 | 58 | extern void sgIP_sockets_Init(); 59 | extern void sgIP_sockets_Timer1000ms(); 60 | 61 | // sys/socket.h 62 | extern int socket(int domain, int type, int protocol); 63 | extern int bind(int socket, const struct sockaddr * addr, int addr_len); 64 | extern int connect(int socket, const struct sockaddr * addr, int addr_len); 65 | extern int send(int socket, const void * data, int sendlength, int flags); 66 | extern int recv(int socket, void * data, int recvlength, int flags); 67 | extern int sendto(int socket, const void * data, int sendlength, int flags, const struct sockaddr * addr, int addr_len); 68 | extern int recvfrom(int socket, void * data, int recvlength, int flags, struct sockaddr * addr, int * addr_len); 69 | extern int listen(int socket, int max_connections); 70 | extern int accept(int socket, struct sockaddr * addr, int * addr_len); 71 | extern int shutdown(int socket, int shutdown_type); 72 | extern int closesocket(int socket); 73 | extern int forceclosesocket(int socket); 74 | 75 | extern int ioctl(int socket, long cmd, void * arg); 76 | 77 | extern int setsockopt(int socket, int level, int option_name, const void * data, int data_len); 78 | extern int getsockopt(int socket, int level, int option_name, void * data, int * data_len); 79 | 80 | extern int getpeername(int socket, struct sockaddr *addr, int * addr_len); 81 | extern int getsockname(int socket, struct sockaddr *addr, int * addr_len); 82 | 83 | // sys/time.h (actually intersects partly with libnds, so I'm letting libnds handle fd_set for the time being) 84 | extern int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *timeout); 85 | 86 | // arpa/inet.h 87 | extern unsigned long inet_addr(const char *cp); 88 | 89 | #ifdef __cplusplus 90 | }; 91 | #endif 92 | 93 | 94 | #endif 95 | -------------------------------------------------------------------------------- /arm9/source/template.c: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------------- 2 | 3 | Simple wifi demo to locate and connect to an ap 4 | -- dovoto 5 | 6 | ---------------------------------------------------------------------------------*/ 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | 14 | #include 15 | #include 16 | 17 | //--------------------------------------------------------------------------------- 18 | Wifi_AccessPoint* findAP(void){ 19 | //--------------------------------------------------------------------------------- 20 | 21 | int selected = 0; 22 | int i; 23 | int count = 0, displaytop = 0; 24 | 25 | static Wifi_AccessPoint ap; 26 | 27 | Wifi_ScanMode(); //this allows us to search for APs 28 | 29 | int pressed = 0; 30 | do { 31 | 32 | scanKeys(); 33 | pressed = keysDown(); 34 | 35 | if(pressed & KEY_START) exit(0); 36 | 37 | //find out how many APs there are in the area 38 | count = Wifi_GetNumAP(); 39 | 40 | 41 | consoleClear(); 42 | 43 | iprintf("%d APs detected\n\n", count); 44 | 45 | int displayend = displaytop + 10; 46 | if (displayend > count) displayend = count; 47 | 48 | //display the APs to the user 49 | for(i = displaytop; i < displayend; i++) { 50 | Wifi_AccessPoint ap; 51 | 52 | Wifi_GetAPData(i, &ap); 53 | 54 | // display the name of the AP 55 | iprintf("%s %.29s\n Wep:%s Sig:%i\n", 56 | i == selected ? "*" : " ", 57 | ap.ssid, 58 | ap.flags & WFLAG_APDATA_WEP ? "Yes " : "No ", 59 | ap.rssi * 100 / 0xD0); 60 | 61 | } 62 | 63 | //move the selection asterick 64 | if(pressed & KEY_UP) { 65 | selected--; 66 | if(selected < 0) { 67 | selected = 0; 68 | } 69 | if(selected= count) { 75 | selected = count - 1; 76 | } 77 | displaytop = selected - 9; 78 | if (displaytop<0) displaytop = 0; 79 | } 80 | swiWaitForVBlank(); 81 | } while(!(pressed & KEY_A)); 82 | 83 | //user has made a choice so grab the ap and return it 84 | Wifi_GetAPData(selected, &ap); 85 | 86 | return ≈ 87 | } 88 | 89 | //--------------------------------------------------------------------------------- 90 | void keyPressed(int c){ 91 | //--------------------------------------------------------------------------------- 92 | if(c > 0) iprintf("%c",c); 93 | } 94 | 95 | //--------------------------------------------------------------------------------- 96 | int main(void) { 97 | //--------------------------------------------------------------------------------- 98 | Wifi_InitDefault(false); 99 | 100 | consoleDemoInit(); 101 | 102 | Keyboard* kb = keyboardDemoInit(); 103 | kb->OnKeyPressed = keyPressed; 104 | 105 | while(1) { 106 | int status = ASSOCSTATUS_DISCONNECTED; 107 | 108 | consoleClear(); 109 | consoleSetWindow(NULL, 0,0,32,24); 110 | 111 | Wifi_AccessPoint* ap = findAP(); 112 | 113 | consoleClear(); 114 | consoleSetWindow(NULL, 0,0,32,10); 115 | 116 | iprintf("Connecting to %s\n", ap->ssid); 117 | 118 | //this tells the wifi lib to use dhcp for everything 119 | Wifi_SetIP(0,0,0,0,0); 120 | char wepkey[64]; 121 | int wepmode = WEPMODE_NONE; 122 | if (ap->flags & WFLAG_APDATA_WEP) { 123 | iprintf("Enter Wep Key\n"); 124 | while (wepmode == WEPMODE_NONE) { 125 | scanf("%s",wepkey); 126 | if (strlen(wepkey)==13) { 127 | wepmode = WEPMODE_128BIT; 128 | } else if (strlen(wepkey) == 5) { 129 | wepmode = WEPMODE_40BIT; 130 | } else { 131 | iprintf("Invalid key!\n"); 132 | } 133 | } 134 | Wifi_ConnectAP(ap, wepmode, 0, (u8*)wepkey); 135 | } else { 136 | Wifi_ConnectAP(ap, WEPMODE_NONE, 0, 0); 137 | } 138 | consoleClear(); 139 | while(status != ASSOCSTATUS_ASSOCIATED && status != ASSOCSTATUS_CANNOTCONNECT) { 140 | 141 | status = Wifi_AssocStatus(); 142 | int len = strlen(ASSOCSTATUS_STRINGS[status]); 143 | iprintf("\x1b[0;0H\x1b[K"); 144 | iprintf("\x1b[0;%dH%s", (32-len)/2,ASSOCSTATUS_STRINGS[status]); 145 | 146 | scanKeys(); 147 | 148 | if(keysDown() & KEY_B) break; 149 | 150 | swiWaitForVBlank(); 151 | } 152 | 153 | char url[256]; 154 | 155 | if(status == ASSOCSTATUS_ASSOCIATED) { 156 | u32 ip = Wifi_GetIP(); 157 | 158 | iprintf("\nip: [%li.%li.%li.%li]\n", (ip ) & 0xFF, (ip >> 8) & 0xFF, (ip >> 16) & 0xFF, (ip >> 24) & 0xFF); 159 | while(1) { 160 | 161 | scanf("%s", url); 162 | 163 | if ( 0 == strcmp(url,"quit")) break; 164 | 165 | struct hostent *host = gethostbyname(url); 166 | 167 | if(host) 168 | iprintf("IP (%s) : %s\n", url, inet_ntoa(*(struct in_addr *)host->h_addr_list[0])); 169 | else 170 | iprintf("Could not resolve\n"); 171 | 172 | swiWaitForVBlank(); 173 | } 174 | } else { 175 | iprintf("\nConnection failed!\n"); 176 | } 177 | 178 | int quit = 0; 179 | iprintf("Press A to try again, B to quit."); 180 | while(1) { 181 | swiWaitForVBlank(); 182 | scanKeys(); 183 | int pressed = keysDown(); 184 | if(pressed&KEY_B) quit = 1; 185 | if(pressed&(KEY_A|KEY_B)) break; 186 | } 187 | if(quit) break; 188 | } 189 | return 0; 190 | } 191 | -------------------------------------------------------------------------------- /arm9/source/wifi_arm9.h: -------------------------------------------------------------------------------- 1 | // DS Wifi interface code 2 | // Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org 3 | // wifi_arm9.c - arm9 wifi support header 4 | /****************************************************************************** 5 | DSWifi Lib and test materials are licenced under the MIT open source licence: 6 | Copyright (c) 2005-2006 Stephen Stair 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy of 9 | this software and associated documentation files (the "Software"), to deal in 10 | the Software without restriction, including without limitation the rights to 11 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 12 | of the Software, and to permit persons to whom the Software is furnished to do 13 | so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in all 16 | copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | SOFTWARE. 25 | ******************************************************************************/ 26 | 27 | 28 | #ifndef WIFI_ARM9_H 29 | #define WIFI_ARM9_H 30 | 31 | #include 32 | 33 | #include "wifi_shared.h" 34 | 35 | 36 | 37 | // default option is to use 128k heap 38 | #define WIFIINIT_OPTION_USEHEAP_128 0x0000 // default=128K ;\ ;<-- BUGGED: (unlike as in "include\dswifi9.h") 39 | #define WIFIINIT_OPTION_USEHEAP_64 0x1000 // ;<-- BUGGED: (unlike as in "include\dswifi9.h") 40 | #define WIFIINIT_OPTION_USEHEAP_256 0x2000 41 | #define WIFIINIT_OPTION_USEHEAP_512 0x3000 42 | #define WIFIINIT_OPTION_USECUSTOMALLOC 0x4000 43 | #define WIFIINIT_OPTION_HEAPMASK 0xF000 44 | 45 | #ifdef WIFI_USE_TCP_SGIP 46 | 47 | #ifdef __cplusplus 48 | extern "C" { 49 | #endif 50 | 51 | 52 | #ifdef __cplusplus 53 | }; 54 | #endif 55 | 56 | 57 | #endif 58 | 59 | extern volatile Wifi_MainStruct * WifiData; 60 | 61 | enum WIFIGETDATA { 62 | WIFIGETDATA_MACADDRESS, // MACADDRESS: returns data in the buffer, requires at least 6 bytes 63 | WIFIGETDATA_NUMWFCAPS, // NUM WFC APS: returns number between 0 and 3, doesn't use buffer. 64 | 65 | MAX_WIFIGETDATA 66 | }; 67 | 68 | // Wifi Packet Handler function: (int packetID, int packetlength) - packetID is only valid while the called function is executing. 69 | // call Wifi_RxRawReadPacket while in the packet handler function, to retreive the data to a local buffer. 70 | typedef void (*WifiPacketHandler)(int, int); 71 | 72 | // Wifi Sync Handler function: Callback function that is called when the arm7 needs to be told to synchronize with new fifo data. 73 | // If this callback is used (see Wifi_SetSyncHandler()), it should send a message via the fifo to the arm7, which will call Wifi_Sync() on arm7. 74 | typedef void (*WifiSyncHandler)(); 75 | 76 | 77 | #ifdef __cplusplus 78 | extern "C" { 79 | #endif 80 | 81 | extern void Wifi_CopyMacAddr(volatile void * dest, volatile void * src); 82 | extern int Wifi_CmpMacAddr(volatile void * mac1, volatile void * mac2); 83 | 84 | extern unsigned long Wifi_Init(int initflags); 85 | bool Wifi_InitDefault(bool useFirmwareSettings); 86 | extern int Wifi_CheckInit(); 87 | 88 | extern int Wifi_RawTxFrame(u16 datalen, u16 rate, u16 * data); 89 | extern void Wifi_SetSyncHandler(WifiSyncHandler wshfunc); 90 | extern void Wifi_RawSetPacketHandler(WifiPacketHandler wphfunc); 91 | extern int Wifi_RxRawReadPacket(s32 packetID, s32 readlength, u16 * data); 92 | 93 | extern void Wifi_DisableWifi(); 94 | extern void Wifi_EnableWifi(); 95 | extern void Wifi_SetPromiscuousMode(int enable); 96 | extern void Wifi_ScanMode(); 97 | extern void Wifi_SetChannel(int channel); 98 | 99 | extern int Wifi_GetNumAP(); 100 | extern int Wifi_GetAPData(int apnum, Wifi_AccessPoint * apdata); 101 | extern int Wifi_FindMatchingAP(int numaps, Wifi_AccessPoint * apdata, Wifi_AccessPoint * match_dest); 102 | extern int Wifi_ConnectAP(Wifi_AccessPoint * apdata, int wepmode, int wepkeyid, u8 * wepkey); 103 | extern void Wifi_AutoConnect(); 104 | 105 | extern int Wifi_AssocStatus(); 106 | extern int Wifi_DisconnectAP(); 107 | extern int Wifi_GetData(int datatype, int bufferlen, unsigned char * buffer); 108 | 109 | 110 | extern void Wifi_Update(); 111 | extern void Wifi_Sync(); 112 | 113 | 114 | #ifdef WIFI_USE_TCP_SGIP 115 | extern void Wifi_Timer(int num_ms); 116 | extern void Wifi_SetIP(u32 IPaddr, u32 gateway, u32 subnetmask, u32 dns1, u32 dns2); 117 | extern u32 Wifi_GetIP(); 118 | 119 | #endif 120 | 121 | #ifdef __cplusplus 122 | }; 123 | #endif 124 | 125 | 126 | #endif 127 | -------------------------------------------------------------------------------- /common/source/dsregs.h: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////// 2 | // DSRegs.h - (c) 2005-2006 Stephen Stair 3 | // General reference mumbo jumbo to give me easy access to the regs I like. 4 | ////////////////////////////////////////////////////////////////////////// 5 | /****************************************************************************** 6 | DSWifi Lib and test materials are licenced under the MIT open source licence: 7 | Copyright (c) 2005-2006 Stephen Stair 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy of 10 | this software and associated documentation files (the "Software"), to deal in 11 | the Software without restriction, including without limitation the rights to 12 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 13 | of the Software, and to permit persons to whom the Software is furnished to do 14 | so, subject to the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included in all 17 | copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | SOFTWARE. 26 | ******************************************************************************/ 27 | 28 | #ifndef DSREGS_H 29 | #define DSREGS_H 30 | 31 | #include 32 | 33 | 34 | ////////////////////////////////////////////////////////////////////////// 35 | // General registers 36 | 37 | 38 | // general memory range defines 39 | #define PAL ((u16 *) 0x05000000) 40 | #define VRAM1 ((u16 *) 0x06000000) 41 | #define VRAM2 ((u16 *) 0x06200000) 42 | 43 | //#define OAM ((u16 *) 0x07000000) 44 | #define CART ((u16 *) 0x08000000) 45 | 46 | 47 | // video registers 48 | #define DISPCNT (*((u32 volatile *) 0x04000000)) 49 | #define DISPSTAT (*((u16 volatile *) 0x04000004)) 50 | #define VCOUNT (*((u16 volatile *) 0x04000006)) 51 | #define BG0CNT (*((u16 volatile *) 0x04000008)) 52 | #define BG1CNT (*((u16 volatile *) 0x0400000A)) 53 | #define BG2CNT (*((u16 volatile *) 0x0400000C)) 54 | #define BG3CNT (*((u16 volatile *) 0x0400000E)) 55 | #define BG0HOFS (*((u16 volatile *) 0x04000010)) 56 | #define BG0VOFS (*((u16 volatile *) 0x04000012)) 57 | #define BG1HOFS (*((u16 volatile *) 0x04000014)) 58 | #define BG1VOFS (*((u16 volatile *) 0x04000016)) 59 | #define BG2HOFS (*((u16 volatile *) 0x04000018)) 60 | #define BG2VOFS (*((u16 volatile *) 0x0400001A)) 61 | #define BG3HOFS (*((u16 volatile *) 0x0400001C)) 62 | #define BG3VOFS (*((u16 volatile *) 0x0400001E)) 63 | #define BG2PA (*((u16 volatile *) 0x04000020)) 64 | #define BG2PB (*((u16 volatile *) 0x04000022)) 65 | #define BG2PC (*((u16 volatile *) 0x04000024)) 66 | #define BG2PD (*((u16 volatile *) 0x04000026)) 67 | #define BG2X (*((u32 volatile *) 0x04000028)) 68 | #define BG2Y (*((u32 volatile *) 0x0400002C)) 69 | #define BG3PA (*((u16 volatile *) 0x04000030)) 70 | #define BG3PB (*((u16 volatile *) 0x04000032)) 71 | #define BG3PC (*((u16 volatile *) 0x04000034)) 72 | #define BG3PD (*((u16 volatile *) 0x04000036)) 73 | #define BG3X (*((u32 volatile *) 0x04000038)) 74 | #define BG3Y (*((u32 volatile *) 0x0400003C)) 75 | #define WIN0H (*((u16 volatile *) 0x04000040)) 76 | #define WIN1H (*((u16 volatile *) 0x04000042)) 77 | #define WIN0V (*((u16 volatile *) 0x04000044)) 78 | #define WIN1V (*((u16 volatile *) 0x04000046)) 79 | #define WININ (*((u16 volatile *) 0x04000048)) 80 | #define WINOUT (*((u16 volatile *) 0x0400004A)) 81 | #define MOSAIC (*((u16 volatile *) 0x0400004C)) 82 | #define BLDCNT (*((u16 volatile *) 0x04000050)) 83 | #define BLDALPHA (*((u16 volatile *) 0x04000052)) 84 | #define BLDY (*((u16 volatile *) 0x04000054)) 85 | 86 | #define DISPCNT2 (*((u32 volatile *) 0x04001000)) 87 | #define DISPSTAT2 (*((u16 volatile *) 0x04001004)) 88 | #define VCOUNT2 (*((u16 volatile *) 0x04001006)) 89 | #define BG0CNT2 (*((u16 volatile *) 0x04001008)) 90 | #define BG1CNT2 (*((u16 volatile *) 0x0400100A)) 91 | #define BG2CNT2 (*((u16 volatile *) 0x0400100C)) 92 | #define BG3CNT2 (*((u16 volatile *) 0x0400100E)) 93 | #define BG0HOFS2 (*((u16 volatile *) 0x04001010)) 94 | #define BG0VOFS2 (*((u16 volatile *) 0x04001012)) 95 | #define BG1HOFS2 (*((u16 volatile *) 0x04001014)) 96 | #define BG1VOFS2 (*((u16 volatile *) 0x04001016)) 97 | #define BG2HOFS2 (*((u16 volatile *) 0x04001018)) 98 | #define BG2VOFS2 (*((u16 volatile *) 0x0400101A)) 99 | #define BG3HOFS2 (*((u16 volatile *) 0x0400101C)) 100 | #define BG3VOFS2 (*((u16 volatile *) 0x0400101E)) 101 | #define BG2PA2 (*((u16 volatile *) 0x04001020)) 102 | #define BG2PB2 (*((u16 volatile *) 0x04001022)) 103 | #define BG2PC2 (*((u16 volatile *) 0x04001024)) 104 | #define BG2PD2 (*((u16 volatile *) 0x04001026)) 105 | #define BG2X2 (*((u32 volatile *) 0x04001028)) 106 | #define BG2Y2 (*((u32 volatile *) 0x0400102C)) 107 | #define BG3PA2 (*((u16 volatile *) 0x04001030)) 108 | #define BG3PB2 (*((u16 volatile *) 0x04001032)) 109 | #define BG3PC2 (*((u16 volatile *) 0x04001034)) 110 | #define BG3PD2 (*((u16 volatile *) 0x04001036)) 111 | #define BG3X2 (*((u32 volatile *) 0x04001038)) 112 | #define BG3Y2 (*((u32 volatile *) 0x0400103C)) 113 | #define WIN0H2 (*((u16 volatile *) 0x04001040)) 114 | #define WIN1H2 (*((u16 volatile *) 0x04001042)) 115 | #define WIN0V2 (*((u16 volatile *) 0x04001044)) 116 | #define WIN1V2 (*((u16 volatile *) 0x04001046)) 117 | #define WININ2 (*((u16 volatile *) 0x04001048)) 118 | #define WINOUT2 (*((u16 volatile *) 0x0400104A)) 119 | #define MOSAIC2 (*((u16 volatile *) 0x0400104C)) 120 | #define BLDCNT2 (*((u16 volatile *) 0x04001050)) 121 | #define BLDALPHA2 (*((u16 volatile *) 0x04001052)) 122 | #define BLDY2 (*((u16 volatile *) 0x04001054)) 123 | 124 | // video memory defines 125 | #define PAL_BG1 ((u16 *) 0x05000000) 126 | #define PAL_FG1 ((u16 *) 0x05000200) 127 | #define PAL_BG2 ((u16 *) 0x05000400) 128 | #define PAL_FG2 ((u16 *) 0x05000600) 129 | 130 | // other video defines 131 | #define VRAMBANKCNT (((u16 volatile *) 0x04000240)) 132 | 133 | #define RGB(r,g,b) ( ((r)&31) | (((g)&31)<<5) | (((b)&31)<<10) ) 134 | #define VRAM_SETBANK(bank, set) \ 135 | if((bank)&1) { VRAMBANKCNT[(bank)>>1] = (VRAMBANKCNT[(bank)>>1]&0x00ff) | (((set)&0xff)<<8); } else \ 136 | { VRAMBANKCNT[(bank)>>1] = (VRAMBANKCNT[(bank)>>1]&0xff00) | ((set)&0xff); } 137 | 138 | // joypad input 139 | #define KEYINPUT (*((u16 volatile *) 0x04000130)) 140 | #define KEYCNT (*((u16 volatile *) 0x04000132)) 141 | 142 | 143 | // System registers 144 | #define WAITCNT (*((u16 volatile *) 0x04000204)) 145 | //#define IME (*((u16 volatile *) 0x04000208)) 146 | //#define IE (*((u32 volatile *) 0x04000210)) 147 | //#define IF (*((u32 volatile *) 0x04000214)) 148 | #define HALTCNT (*((u16 volatile *) 0x04000300)) 149 | 150 | 151 | 152 | 153 | 154 | 155 | ////////////////////////////////////////////////////////////////////////// 156 | // ARM7 specific registers 157 | #ifdef ARM7 158 | #define POWERCNT7 (*((u16 volatile *) 0x04000304)) 159 | 160 | #define SPI_CR (*((u16 volatile *) 0x040001C0)) 161 | #define SPI_DATA (*((u16 volatile *) 0x040001C2)) 162 | 163 | 164 | 165 | #endif 166 | 167 | ////////////////////////////////////////////////////////////////////////// 168 | // ARM9 specific registers 169 | #ifdef ARM9 170 | #define POWERCNT (*((u16 volatile *) 0x04000308)) 171 | 172 | 173 | 174 | #endif 175 | // End of file! 176 | #endif 177 | 178 | 179 | 180 | -------------------------------------------------------------------------------- /common/source/spinlock.h: -------------------------------------------------------------------------------- 1 | // DS Wifi interface code 2 | // Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org 3 | // spinlock.h - code for spinlocking for basic wifi structure memory protection 4 | /****************************************************************************** 5 | DSWifi Lib and test materials are licenced under the MIT open source licence: 6 | Copyright (c) 2005-2006 Stephen Stair 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy of 9 | this software and associated documentation files (the "Software"), to deal in 10 | the Software without restriction, including without limitation the rights to 11 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 12 | of the Software, and to permit persons to whom the Software is furnished to do 13 | so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in all 16 | copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | SOFTWARE. 25 | ******************************************************************************/ 26 | 27 | 28 | 29 | /* 30 | 31 | __asm ( 32 | ".GLOBL SLasm_Acquire, SLasm_Release \n" 33 | ".ARM \n" 34 | "SLasm_Acquire: \n" 35 | " ldr r2,[r0] \n" 36 | " cmp r2,#0 \n" 37 | " movne r0,#1 \n" 38 | " bxne lr \n" 39 | " mov r2,r1 \n" 40 | " swp r2,r2,[r0] \n" 41 | " cmp r2,#0 \n" 42 | " cmpne r2,r1 \n" 43 | " moveq r0,#0 \n" 44 | " bxeq lr \n" 45 | " swp r2,r2,[r0] \n" 46 | " mov r0,#1 \n" 47 | " bx lr \n" 48 | "\n\n" 49 | "SLasm_Release: \n" 50 | " ldr r2,[r0] \n" 51 | " cmp r2,r1 \n" 52 | " movne r0,#2 \n" 53 | " bxne lr \n" 54 | " mov r2,#0 \n" 55 | " swp r2,r2,[r0] \n" 56 | " cmp r2,r1 \n" 57 | " moveq r0,#0 \n" 58 | " movne r0,#2 \n" 59 | " bx lr \n" 60 | ); 61 | 62 | */ 63 | 64 | -------------------------------------------------------------------------------- /common/source/spinlock.s: -------------------------------------------------------------------------------- 1 | .arch armv5te @ BUGGED: that would be okay for ARM9, but the 2 | .cpu arm946e-s @ spinlock functions are ALSO used on ARM7 3 | 4 | .text 5 | .arm 6 | .global SLasm_Acquire 7 | .type SLasm_Acquire STT_FUNC 8 | @--------------------------------------------------------------------------------- 9 | SLasm_Acquire: @ in: r0=sgWifiAp, r1=SPINLOCK_VALUE, out: r0 10 | @--------------------------------------------------------------------------------- 11 | ldr r2,[r0] 12 | cmp r2,#0 13 | movne r0,#1 14 | bxne lr 15 | mov r2,r1 16 | swp r2,r2,[r0] 17 | cmp r2,#0 18 | cmpne r2,r1 19 | moveq r0,#0 20 | bxeq lr 21 | swp r2,r2,[r0] 22 | mov r0,#1 23 | bx lr 24 | 25 | .global SLasm_Release 26 | .type SLasm_Release STT_FUNC 27 | @--------------------------------------------------------------------------------- 28 | SLasm_Release: @ in: r0=ptr+sgWifiAp_spinlock, r1=SPINLOCK_VALUE, out: r0 29 | @--------------------------------------------------------------------------------- 30 | ldr r2,[r0] 31 | cmp r2,r1 32 | movne r0,#2 33 | bxne lr 34 | mov r2,#0 35 | swp r2,r2,[r0] 36 | cmp r2,r1 37 | moveq r0,#0 38 | movne r0,#2 39 | bx lr 40 | 41 | .pool 42 | .end 43 | 44 | -------------------------------------------------------------------------------- /common/source/wifi_shared.h: -------------------------------------------------------------------------------- 1 | // DS Wifi interface code 2 | // Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org 3 | // wifi_shared.h - Shared structures to be used by arm9 and arm7 4 | /****************************************************************************** 5 | DSWifi Lib and test materials are licenced under the MIT open source licence: 6 | Copyright (c) 2005-2006 Stephen Stair 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy of 9 | this software and associated documentation files (the "Software"), to deal in 10 | the Software without restriction, including without limitation the rights to 11 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 12 | of the Software, and to permit persons to whom the Software is furnished to do 13 | so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in all 16 | copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | SOFTWARE. 25 | ******************************************************************************/ 26 | 27 | #ifndef WIFI_SHARED_H 28 | #define WIFI_SHARED_H 29 | 30 | 31 | #include 32 | 33 | 34 | #define WIFIINIT_OPTION_USELED 0x0002 35 | 36 | // on spinlock contention, the side unsuccessfully attempting the lock reverts the lock. 37 | // if the unlocking side sees the lock incorrectly set, the unlocking side will delay until it has reverted to the correct value, then continue unlocking. 38 | // there should be a delay of at least about ~10-20 cycles between a lock and unlock, to prevent contention. 39 | #define SPINLOCK_NOBODY 0x0000 40 | #define SPINLOCK_ARM7 0x0001 41 | #define SPINLOCK_ARM9 0x0002 42 | 43 | #define SPINLOCK_OK 0x0000 44 | #define SPINLOCK_INUSE 0x0001 45 | #define SPINLOCK_ERROR 0x0002 46 | 47 | #ifdef ARM7 48 | #define SPINLOCK_VALUE SPINLOCK_ARM7 49 | #endif 50 | #ifdef ARM9 51 | #define SPINLOCK_VALUE SPINLOCK_ARM9 52 | #endif 53 | 54 | 55 | #define Spinlock_Acquire(structtolock) SLasm_Acquire(&((structtolock).spinlock),SPINLOCK_VALUE) 56 | #define Spinlock_Release(structtolock) SLasm_Release(&((structtolock).spinlock),SPINLOCK_VALUE) 57 | #define Spinlock_Check(structtolock) (((structtolock).spinlock)!=SPINLOCK_NOBODY) 58 | 59 | #ifdef __cplusplus 60 | extern "C" { 61 | #endif 62 | 63 | extern u32 SLasm_Acquire(volatile u32 * lockaddr, u32 lockvalue); 64 | extern u32 SLasm_Release(volatile u32 * lockaddr, u32 lockvalue); 65 | 66 | #ifdef __cplusplus 67 | }; 68 | #endif 69 | 70 | // If for whatever reason you want to ditch SGIP and use your own stack, comment out the following line. 71 | #define WIFI_USE_TCP_SGIP 1 72 | 73 | #define WIFI_RXBUFFER_SIZE (1024*12) 74 | #define WIFI_TXBUFFER_SIZE (1024*24) 75 | #define WIFI_MAX_AP 32 76 | #define WIFI_MAX_ASSOC_RETRY 30 77 | #define WIFI_PS_POLL_CONST 2 78 | 79 | #define WIFI_MAX_PROBE 4 80 | 81 | #define WIFI_AP_TIMEOUT 3 // old=40 (old=40 was for N channels, new=3 from 2018 is for ALL channels N times, ie. expire after scanning 3x14 channels) 82 | 83 | #define WFLAG_PACKET_DATA 0x0001 84 | #define WFLAG_PACKET_MGT 0x0002 85 | #define WFLAG_PACKET_BEACON 0x0004 86 | #define WFLAG_PACKET_CTRL 0x0008 87 | 88 | 89 | #define WFLAG_PACKET_ALL 0xFFFF 90 | 91 | #define WFLAG_ARM7_ACTIVE 0x0001 92 | #define WFLAG_ARM7_RUNNING 0x0002 93 | 94 | #define WFLAG_ARM9_ACTIVE 0x0001 95 | #define WFLAG_ARM9_USELED 0x0002 96 | #define WFLAG_ARM9_ARM7READY 0x0004 97 | #define WFLAG_ARM9_NETUP 0x0008 98 | #define WFLAG_ARM9_NETREADY 0x0010 99 | 100 | #define WFLAG_ARM9_INITFLAGMASK 0x0002 101 | 102 | #define WFLAG_IP_GOTDHCP 0x0001 103 | 104 | // request - request flags 105 | #define WFLAG_REQ_APCONNECT 0x0001 106 | #define WFLAG_REQ_APCOPYVALUES 0x0002 107 | #define WFLAG_REQ_APADHOC 0x0008 108 | #define WFLAG_REQ_PROMISC 0x0010 109 | #define WFLAG_REQ_USEWEP 0x0020 110 | 111 | // request - informational flags 112 | #define WFLAG_REQ_APCONNECTED 0x8000 113 | 114 | #define WFLAG_APDATA_ADHOC 0x0001 115 | #define WFLAG_APDATA_WEP 0x0002 116 | #define WFLAG_APDATA_WPA 0x0004 117 | #define WFLAG_APDATA_COMPATIBLE 0x0008 118 | #define WFLAG_APDATA_EXTCOMPATIBLE 0x0010 119 | #define WFLAG_APDATA_SHORTPREAMBLE 0x0020 120 | #define WFLAG_APDATA_ACTIVE 0x8000 121 | 122 | 123 | #define RSNIE_NULL 0x0000 124 | #define RSNIE_GRP_WEP40 0x0001 125 | #define RSNIE_GRP_WEP104 0x0002 126 | #define RSNIE_GRP_TKIP 0x0004 127 | #define RSNIE_GRP_AES 0x0008 128 | #define RSNIE_PAIR_WEPNONE 0x0010 129 | #define RSNIE_PAIR_TKIP 0x0020 130 | #define RSNIE_PAIR_AES 0x0040 131 | 132 | #define EAPOL_TYPE_NONE 0 133 | #define EAPOL_TYPE_WPA 1 134 | #define EAPOL_TYPE_WPA2 2 135 | #define EAPOL_TYPE_ERROR 3 136 | 137 | #define KEY_TYPE_ERROR 0 //-oops, no matching key 138 | #define KEY_TYPE_NONE 1 //\ 139 | #define KEY_TYPE_WEP 2 // these are SAME values as for dsi/atheros 140 | #define KEY_TYPE_TKIP 3 // (for use in CONNECT and ADD_CIPHER commands) 141 | #define KEY_TYPE_AES 4 /// 142 | 143 | 144 | enum WIFI_RETURN { 145 | WIFI_RETURN_OK = 0, // Everything went ok 146 | WIFI_RETURN_LOCKFAILED = 1, // the spinlock attempt failed (it wasn't retried cause that could lock both cpus- retry again after a delay. 147 | WIFI_RETURN_ERROR = 2, // There was an error in attempting to complete the requested task. 148 | WIFI_RETURN_PARAMERROR = 3, // There was an error in the parameters passed to the function. 149 | }; 150 | 151 | enum WIFI_STATS { 152 | // software stats 153 | WSTAT_RXQUEUEDPACKETS, // number of packets queued into the rx fifo 154 | WSTAT_TXQUEUEDPACKETS, // number of packets queued into the tx fifo 155 | WSTAT_RXQUEUEDBYTES, // number of bytes queued into the rx fifo 156 | WSTAT_TXQUEUEDBYTES, // number of bytes queued into the tx fifo 157 | WSTAT_RXQUEUEDLOST, // number of packets lost due to space limitations in queuing 158 | WSTAT_TXQUEUEDREJECTED, // number of packets rejected due to space limitations in queuing 159 | WSTAT_RXPACKETS, 160 | WSTAT_RXBYTES, 161 | WSTAT_RXDATABYTES, 162 | WSTAT_TXPACKETS, 163 | WSTAT_TXBYTES, 164 | WSTAT_TXDATABYTES, 165 | WSTAT_ARM7_UPDATES, 166 | WSTAT_DEBUG, 167 | // harware stats (function mostly unknown.) 168 | WSTAT_HW_1B0,WSTAT_HW_1B1,WSTAT_HW_1B2,WSTAT_HW_1B3,WSTAT_HW_1B4,WSTAT_HW_1B5,WSTAT_HW_1B6,WSTAT_HW_1B7, 169 | WSTAT_HW_1B8,WSTAT_HW_1B9,WSTAT_HW_1BA,WSTAT_HW_1BB,WSTAT_HW_1BC,WSTAT_HW_1BD,WSTAT_HW_1BE,WSTAT_HW_1BF, 170 | WSTAT_HW_1C0,WSTAT_HW_1C1,WSTAT_HW_1C4,WSTAT_HW_1C5, 171 | WSTAT_HW_1D0,WSTAT_HW_1D1,WSTAT_HW_1D2,WSTAT_HW_1D3,WSTAT_HW_1D4,WSTAT_HW_1D5,WSTAT_HW_1D6,WSTAT_HW_1D7, 172 | WSTAT_HW_1D8,WSTAT_HW_1D9,WSTAT_HW_1DA,WSTAT_HW_1DB,WSTAT_HW_1DC,WSTAT_HW_1DD,WSTAT_HW_1DE,WSTAT_HW_1DF, 173 | 174 | NUM_WIFI_STATS 175 | }; 176 | 177 | 178 | enum WIFI_MODE { 179 | WIFIMODE_DISABLED, 180 | WIFIMODE_NORMAL, 181 | WIFIMODE_SCAN, 182 | WIFIMODE_ASSOCIATE, 183 | WIFIMODE_ASSOCIATED, 184 | WIFIMODE_DISASSOCIATE, 185 | WIFIMODE_CANNOTASSOCIATE, 186 | }; 187 | enum WIFI_AUTHLEVEL { 188 | WIFI_AUTHLEVEL_DISCONNECTED, 189 | WIFI_AUTHLEVEL_AUTHENTICATED, 190 | WIFI_AUTHLEVEL_ASSOCIATED, 191 | WIFI_AUTHLEVEL_DEASSOCIATED, 192 | }; 193 | 194 | enum WEPMODES { 195 | WEPMODE_NONE = 0, 196 | WEPMODE_40BIT = 1, 197 | WEPMODE_128BIT = 2 198 | }; 199 | 200 | enum WIFI_ASSOCSTATUS { 201 | ASSOCSTATUS_DISCONNECTED, // not *trying* to connect 202 | ASSOCSTATUS_SEARCHING, // data given does not completely specify an AP, looking for AP that matches the data. 203 | ASSOCSTATUS_AUTHENTICATING, // connecting... 204 | ASSOCSTATUS_ASSOCIATING, // connecting... 205 | ASSOCSTATUS_ACQUIRINGDHCP, // connected to AP, but getting IP data from DHCP 206 | ASSOCSTATUS_ASSOCIATED, // Connected! (COMPLETE if Wifi_ConnectAP was called to start) 207 | ASSOCSTATUS_CANNOTCONNECT, // error in connecting... (COMPLETE if Wifi_ConnectAP was called to start) 208 | }; 209 | 210 | typedef struct WIFI_TXHEADER { 211 | u16 enable_flags; 212 | u16 unknown; 213 | u16 countup; 214 | u16 beaconfreq; 215 | u16 tx_rate; 216 | u16 tx_length; 217 | } Wifi_TxHeader; 218 | 219 | typedef struct WIFI_RXHEADER { 220 | u16 a; 221 | u16 b; 222 | u16 c; 223 | u16 d; 224 | u16 byteLength; 225 | u16 rssi_; 226 | } Wifi_RxHeader; 227 | 228 | typedef struct WIFI_ACCESSPOINT { 229 | char ssid[33]; // 0-32byte data, zero 230 | char ssid_len; 231 | u8 bssid[6]; 232 | u8 macaddr[6]; 233 | u16 maxrate; // max rate is measured in steps of 1/2Mbit - 5.5Mbit will be represented as 11, or 0x0B 234 | u32 timectr; 235 | u16 rssi; 236 | u16 flags; 237 | u32 spinlock; 238 | u8 channel; 239 | u8 rssi_past[8]; 240 | u8 base_rates[16]; // terminated by a 0 entry 241 | } Wifi_AccessPoint; 242 | 243 | //------------------ 244 | typedef struct SG_BEACON { //info from beacon's header 245 | // (new structure invented for "with_dsi_wifi", for passing some info) 246 | u8 sgBeacon_sa; // equ 00h ;6 247 | u8 sgBeacon_bssid; // equ 06h ;6 248 | u8 sgBeacon_strength; // equ 0Ch ;1 249 | u8 sgBeacon_reserved; // equ 0Dh ;3 250 | } sgBeacon; 251 | //------------------ 252 | 253 | 254 | //------------------ 255 | typedef struct SG_WIFI_WFC { 256 | // this structure combines the "sgWifiAp" structure (in first some bytes), 257 | // plus extra WFC data (WEP key and other stuff from wifi flash memory) 258 | // - - - 259 | // this structure doesn't exist in that form in original code (instead it used 260 | // several separate arrays (wfc_ap[3], wfc_enable[4], wfc_config[3][5], and 261 | // wfc_wepkey[3][16]) instead of a single structure 262 | // BUGGED: the comment for the "wfc_config[3][5]" array claims snmask to be 2nd 263 | // entry, and gateway to be 3rd entry (but actual code uses it vice-versa) 264 | //- - - 265 | u8 ap; // equ 00h ;sgWifiAp_xx ;.. ;-public WifiAp data (as for beacons) 266 | u8 wepkey[0x10]; // equ 00h+sgWifiAp_size ;10h ;\ 267 | u32 ip; // equ 10h+sgWifiAp_size ;4 ; 268 | u32 gateway; // equ 14h+sgWifiAp_size ;4 ; secret data (WEP key, 269 | u32 first_dns; // equ 18h+sgWifiAp_size ;4 ; and user-specified Non-DHCP 270 | u32 second_dns; // equ 1ch+sgWifiAp_size ;4 ; settings) 271 | u32 subnet; // equ 20h+sgWifiAp_size ;4 ; 272 | u8 enable; // equ 24h+sgWifiAp_size ;1 ; 273 | u8 wepmode; // equ 25h+sgWifiAp_size ;1 ; 274 | #ifdef with_dsi_wifi 275 | u8 wpamode; // equ 26h+sgWifiAp_size ;1 ; 276 | u8 eapol; // equ 27h+sgWifiAp_size ;1 ; ;-eapol type (none/wpa/wpa2/none/error) ;\these are not FLASH settings, 277 | u8 grp; // equ 28h+sgWifiAp_size ;1 ; ;-group key type (none/wep/tkip/aes) ;/(but, MATCHED to supported FLASH/CONSOLE capabilities) 278 | u8 pair; // equ 29h+sgWifiAp_size ;1 ; ;-pairwise key type (none/wep/tkip/aes) ; but rather detected ACCESS POINT capabilities from BEACON 279 | u16 padding; // equ 2Ah+sgWifiAp_size ;2 ; 280 | u8 psk[0x20]; // equ 2Ch+sgWifiAp_size ;20h ; 281 | #else 282 | u16 padding; // equ 26h+sgWifiAp_size ;2 ; 283 | #endif 284 | } sgWifiWfc; 285 | //----------------- 286 | 287 | //------------------ 288 | #ifdef with_dsi_wifi 289 | #define NUM_WFC_ENTRIES 6 // with three new entries for 4/5/6 with wpa/wpa2 290 | #else 291 | #define NUM_WFC_ENTRIES 3 // this was hardcoded in original code (ie. using "3" instead of the "NUM_WFC_ENTRIES" symbol) 292 | #endif 293 | //------------------ 294 | 295 | typedef struct WIFI_MAINSTRUCT { 296 | unsigned long dummy1[8]; 297 | // wifi status 298 | u16 curChannel, reqChannel; 299 | u16 curMode, reqMode; 300 | u16 authlevel,authctr; 301 | vu32 flags9, flags7; 302 | u32 reqPacketFlags; 303 | u16 curReqFlags, reqReqFlags; 304 | u32 counter7,bootcounter7; 305 | u16 MacAddr[3]; 306 | u16 authtype; 307 | u16 iptype,ipflags; 308 | u32 ip,snmask,gateway; 309 | 310 | // current AP data 311 | char ssid7[34],ssid9[34]; 312 | u16 bssid7[3], bssid9[3]; 313 | u8 apmac7[6], apmac9[6]; 314 | char wepmode7, wepmode9; 315 | char wepkeyid7, wepkeyid9; 316 | u8 wepkey7[20],wepkey9[20]; 317 | u8 baserates7[16], baserates9[16]; 318 | u8 apchannel7, apchannel9; 319 | u8 maxrate7; 320 | #ifdef with_dsi_wifi 321 | // char wpamode7; db 0 ; ..h ;1 322 | // char wpamode9; db 0 ; ..h ;1 323 | u8 eapol7; // db 0 324 | u8 eapol9; // db 0 325 | u8 grp7; // db 0 326 | u8 grp9; // db 0 327 | u8 pair7; // db 0 328 | u8 pair9; // db 0 329 | u8 gtk_index7; // db 0 330 | u8 4way_handshake_busy; // db 0 331 | u8 expected_handshake; // db 0 332 | u8 handshake_crypt; // db 0 ;1=WPA-TKIP or WPA2-TKIP, 2=WPA-AES or WPA2-AES or WPA2-AES+TKIP 333 | //.align 4 334 | u32 rsnie7_wpa; // dd 0 335 | u32 rsnie9_wpa; // dd 0 336 | u32 rsnie7_wpa2; // dd 0 337 | u32 rsnie9_wpa2; // dd 0 338 | u8 psk7[32]; // defs 32 ; ..h ;14h u8 psk7[32] 339 | u8 psk9[32]; // defs 32 ; ..h ;14h u8 psk9[32] 340 | u8 anonce7[32]; // defs 32 341 | u8 snonce7[32]; // defs 32 342 | u8 ptk7[64]; // defs 64 343 | u8 gtk7[32]; // defs 32 344 | u8 rsc7[8]; // defs 8 345 | u8 replay7[8]; // defs 8 346 | u32 reg_domain; // dd 0 347 | u32 reg_channels; // dd 0 348 | 349 | #endif 350 | u16 ap_rssi; 351 | u16 pspoll_period; 352 | 353 | // AP data 354 | Wifi_AccessPoint aplist[WIFI_MAX_AP]; 355 | 356 | // probe stuff 357 | u8 probe9_numprobe; 358 | u8 probe9_ssidlen[WIFI_MAX_PROBE]; 359 | char probe9_ssid[WIFI_MAX_PROBE][32]; 360 | 361 | // WFC data 362 | u8 wfc_enable[4]; // wep mode, or 0x80 for "enabled" 363 | Wifi_AccessPoint wfc_ap[3]; 364 | unsigned long wfc_config[3][5]; // ip, snmask, gateway, primarydns, 2nddns 365 | u8 wfc_wepkey[3][16]; 366 | 367 | 368 | // wifi data 369 | u32 rxbufIn, rxbufOut; // bufIn/bufOut have 2-byte granularity. 370 | u16 rxbufData[WIFI_RXBUFFER_SIZE/2]; // send raw 802.11 data through! rxbuffer is for rx'd data, arm7->arm9 transfer 371 | 372 | u32 txbufIn, txbufOut; 373 | u16 txbufData[WIFI_TXBUFFER_SIZE/2]; // tx buffer is for data to tx, arm9->arm7 transfer 374 | 375 | // stats data 376 | u32 stats[NUM_WIFI_STATS]; 377 | 378 | u16 debug[30]; 379 | 380 | u32 random; // semirandom number updated at the convenience of the arm7. use for initial seeds & such. 381 | 382 | unsigned long dummy2[8]; 383 | 384 | } Wifi_MainStruct; 385 | 386 | typedef struct XTRA_UNCACHED_MEM { // Xtra_uncached_mem_start: 387 | u32 arm9_call_addr; // dd 0 388 | u16 nds_wifi_chip_id; // dw 0 ;\ 389 | u16 nds_wifi_bb_rf_type; // dw 0 ;/ 390 | u32 sdio_chip_id; // dd 0 391 | #ifdef with_blowfish 392 | // keyinfo; 393 | u32 keyname; // dd 0 ;gamecode/idcode 394 | u32 keymode; // dd 0 ;00h=none, 08h=gamecart, 0Ch=firmware (upper bits always zero) 395 | u32 keylevel; // dd 0 ;apply_level (1..3 = once,twice,thrice) 396 | u32 keydsi; // dd 0 ;nds/dsi key 397 | u8 keycode[0x0c]; // defs 0ch 398 | u8 keybuf[0x1048]; // defs 1048h 399 | u8 nds_blowfish_key[0x1048]; // defs 1048h 400 | #endif 401 | // .align 100h ;XXXX maybe needed to ensure no cache-line boundary? 402 | u32 vblank_count; // dd 0 403 | u32 random_count; // dd 0 404 | u8 rtc_datetime[8]; // defs 8 405 | u32 recent_heartbeat; // dd 0 406 | u32 curr_wpa_tx_callback_list_ptr; // dd 0 407 | u8 dsi_wifi_flag; // db 0 408 | // .align 4 409 | } Xtra_uncached_mem; // Xtra_uncached_mem_end: 410 | 411 | #endif 412 | 413 | -------------------------------------------------------------------------------- /dswifi_license.txt: -------------------------------------------------------------------------------- 1 | DSWifi Project - sgIP Internet Protocol Stack Implementation 2 | 3 | Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org 4 | 5 | http://www.akkit.org 6 | 7 | 8 | DSWifi Lib and test materials are licenced under the MIT open source licence: 9 | Copyright (c) 2005-2006 Stephen Stair 10 | 11 | Permission is hereby granted, free of charge, to any person obtaining a copy of 12 | this software and associated documentation files (the "Software"), to deal in 13 | the Software without restriction, including without limitation the rights to 14 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 15 | of the Software, and to permit persons to whom the Software is furnished to do 16 | so, subject to the following conditions: 17 | 18 | The above copyright notice and this permission notice shall be included in all 19 | copies or substantial portions of the Software. 20 | 21 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 27 | SOFTWARE. 28 | -------------------------------------------------------------------------------- /include/arpa/inet.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ahezard/no-dsi-wifi/28ec5eb9248af9d4f49101733dace361acd92f0b/include/arpa/inet.h -------------------------------------------------------------------------------- /include/dswifi7.h: -------------------------------------------------------------------------------- 1 | // DSWifi Project - Arm7 Library Header file (dswifi7.h) 2 | // Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org 3 | /****************************************************************************** 4 | DSWifi Lib and test materials are licenced under the MIT open source licence: 5 | Copyright (c) 2005-2006 Stephen Stair 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | this software and associated documentation files (the "Software"), to deal in 9 | the Software without restriction, including without limitation the rights to 10 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 11 | of the Software, and to permit persons to whom the Software is furnished to do 12 | so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | ******************************************************************************/ 25 | 26 | #ifndef DSWIFI7_H 27 | #define DSWIFI7_H 28 | 29 | #include "dswifi_version.h" 30 | 31 | // Wifi Sync Handler function: Callback function that is called when the arm9 needs to be told to synchronize with new fifo data. 32 | // If this callback is used (see Wifi_SetSyncHandler()), it should send a message via the fifo to the arm9, which will call Wifi_Sync() on arm9. 33 | typedef void (*WifiSyncHandler)(); 34 | 35 | 36 | #ifdef __cplusplus 37 | extern "C" { 38 | #endif 39 | 40 | // Read_Flash: Reads an arbitrary amount of data from the firmware flash chip 41 | // int address: Offset to start reading from in the flash chip 42 | // char * destination: Pointer to a memory buffer to hold incoming data 43 | // int length: The number of bytes to read 44 | extern void Read_Flash(int address, char * destination, int length); 45 | 46 | // PowerChip_ReadWrite: Reads or writes a value to the DS's power chip 47 | // int cmp: The byte-long command to send to the chip (top bit 1=read, 0=write - other bits = register ID to read/write) 48 | // int data: The data to write to the chip (if sending a read command, this should be zero) 49 | // Returns: The data read returned by the serial connection; only really useful when reading. 50 | extern int PowerChip_ReadWrite(int cmd, int data); 51 | 52 | // Wifi_Interrupt: Handler for the arm7 wifi interrupt. Should be called by the 53 | // interrupt handler on arm7, and should *not* have multiple interrupts enabled. 54 | extern void Wifi_Interrupt(); 55 | 56 | // Wifi_Update: Sync function to ensure data continues to flow between the two 57 | // CPUs smoothly. Should be called at a periodic interval, such as in vblank. 58 | extern void Wifi_Update(); 59 | 60 | // Wifi_Init: Requires the data returned by the arm9 wifi init call. The arm9 61 | // init call's returned data must be passed to the arm7 and then given to this 62 | // function. (or else very bad things happen) 63 | // This function also enables power to the wifi system, which will shorten 64 | // battery life. 65 | // unsigned long WifiData: You must pass the 32bit value returned by the call to 66 | // Wifi_Init on the ARM9. 67 | extern void Wifi_Init(unsigned long WifiData); 68 | 69 | // Wifi_Deinit: In the case that it is necessary, this function cuts power to 70 | // the wifi system. After this the wifi will be unusable until Wifi_Init is 71 | // called again. 72 | extern void Wifi_Deinit(); 73 | 74 | // Wifi_Sync: Call this function when requested to sync by the arm9 side of the 75 | // wifi lib 76 | extern void Wifi_Sync(); 77 | 78 | // Wifi_SetSyncHandler: Call this function to request notification of when the 79 | // ARM9-side Wifi_Sync function should be called. 80 | // WifiSyncHandler sh: Pointer to the function to be called for notification. 81 | extern void Wifi_SetSyncHandler(WifiSyncHandler sh); 82 | 83 | extern void installWifiFIFO(); 84 | 85 | #ifdef __cplusplus 86 | }; 87 | #endif 88 | 89 | 90 | #endif // DSWIFI7_H 91 | -------------------------------------------------------------------------------- /include/dswifi_version.h: -------------------------------------------------------------------------------- 1 | #ifndef _dswifi_version_h_ 2 | #define _dswifi_version_h_ 3 | 4 | #define DSWIFI_MAJOR 0 5 | #define DSWIFI_MINOR 1 6 | #define DSWIFI_REVISION 1 7 | 8 | #define DSWIFI_VERSION "0.1.1" 9 | 10 | #endif // _dswifi_version_h_ 11 | -------------------------------------------------------------------------------- /include/netdb.h: -------------------------------------------------------------------------------- 1 | // DSWifi Project - socket emulation layer defines/prototypes (netdb.h) 2 | // Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org 3 | /****************************************************************************** 4 | DSWifi Lib and test materials are licenced under the MIT open source licence: 5 | Copyright (c) 2005-2006 Stephen Stair 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | this software and associated documentation files (the "Software"), to deal in 9 | the Software without restriction, including without limitation the rights to 10 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 11 | of the Software, and to permit persons to whom the Software is furnished to do 12 | so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | ******************************************************************************/ 25 | 26 | #ifndef NETDB_H 27 | #define NETDB_H 28 | 29 | struct hostent { 30 | char * h_name; 31 | char ** h_aliases; 32 | int h_addrtype; 33 | int h_length; 34 | char ** h_addr_list; 35 | }; 36 | 37 | 38 | #ifdef __cplusplus 39 | extern "C" { 40 | #endif 41 | 42 | extern struct hostent * gethostbyname(const char * name); 43 | 44 | #ifdef __cplusplus 45 | }; 46 | #endif 47 | 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /include/netinet/in.h: -------------------------------------------------------------------------------- 1 | // DSWifi Project - socket emulation layer defines/prototypes (netinet/in.h) 2 | // Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org 3 | /****************************************************************************** 4 | DSWifi Lib and test materials are licenced under the MIT open source licence: 5 | Copyright (c) 2005-2006 Stephen Stair 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | this software and associated documentation files (the "Software"), to deal in 9 | the Software without restriction, including without limitation the rights to 10 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 11 | of the Software, and to permit persons to whom the Software is furnished to do 12 | so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | ******************************************************************************/ 25 | 26 | #ifndef NETINET_IN_H 27 | #define NETINET_IN_H 28 | 29 | #include "sys/socket.h" 30 | 31 | #define INADDR_ANY 0x00000000 32 | #define INADDR_BROADCAST 0xFFFFFFFF 33 | #define INADDR_NONE 0xFFFFFFFF 34 | 35 | 36 | struct in_addr { 37 | unsigned long s_addr; 38 | }; 39 | 40 | struct sockaddr_in { 41 | unsigned short sin_family; 42 | unsigned short sin_port; 43 | struct in_addr sin_addr; 44 | unsigned char sin_zero[8]; 45 | }; 46 | 47 | #ifdef __cplusplus 48 | extern "C" { 49 | #endif 50 | 51 | // actually from arpa/inet.h - but is included through netinet/in.h 52 | unsigned long inet_addr(const char *cp); 53 | int inet_aton(const char *cp, struct in_addr *inp); 54 | char *inet_ntoa(struct in_addr in); 55 | 56 | #ifdef __cplusplus 57 | }; 58 | #endif 59 | 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /include/netinet/tcp.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ahezard/no-dsi-wifi/28ec5eb9248af9d4f49101733dace361acd92f0b/include/netinet/tcp.h -------------------------------------------------------------------------------- /include/sys/socket.h: -------------------------------------------------------------------------------- 1 | // DSWifi Project - socket emulation layer defines/prototypes (sys/socket.h) 2 | // Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org 3 | /****************************************************************************** 4 | DSWifi Lib and test materials are licenced under the MIT open source licence: 5 | Copyright (c) 2005-2006 Stephen Stair 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | this software and associated documentation files (the "Software"), to deal in 9 | the Software without restriction, including without limitation the rights to 10 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 11 | of the Software, and to permit persons to whom the Software is furnished to do 12 | so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | ******************************************************************************/ 25 | 26 | 27 | 28 | #ifndef SYS_SOCKET_H 29 | #define SYS_SOCKET_H 30 | 31 | #include 32 | 33 | /* 34 | * Level number for (get/set)sockopt() to apply to socket itself. 35 | */ 36 | #define SOL_SOCKET 0xfff /* options for socket level */ 37 | # define SOL_TCP 6 /* TCP level */ 38 | 39 | #define PF_UNSPEC 0 40 | #define PF_INET 2 41 | #define PF_INET6 10 42 | 43 | #define AF_UNSPEC PF_UNSPEC 44 | #define AF_INET PF_INET 45 | #define AF_INET6 PF_INET6 46 | 47 | #define SOCK_STREAM 1 48 | #define SOCK_DGRAM 2 49 | 50 | // need to sync FIO* values with commonly accepted ones sometime 51 | #define FIONBIO 1 52 | #define FIONREAD 2 53 | 54 | #define SOCKET_ERROR -1 55 | 56 | // send()/recv()/etc flags 57 | // at present, only MSG_PEEK is implemented though. 58 | #define MSG_WAITALL 0x40000000 59 | #define MSG_TRUNC 0x20000000 60 | #define MSG_PEEK 0x10000000 61 | #define MSG_OOB 0x08000000 62 | #define MSG_EOR 0x04000000 63 | #define MSG_DONTROUTE 0x02000000 64 | #define MSG_CTRUNC 0x01000000 65 | 66 | // shutdown() flags: 67 | #define SHUT_RD 1 68 | #define SHUT_WR 2 69 | #define SHUT_RDWR 3 70 | 71 | /* 72 | * Option flags per-socket. 73 | */ 74 | #define SO_DEBUG 0x0001 /* turn on debugging info recording */ 75 | #define SO_ACCEPTCONN 0x0002 /* socket has had listen() */ 76 | #define SO_REUSEADDR 0x0004 /* allow local address reuse */ 77 | #define SO_KEEPALIVE 0x0008 /* keep connections alive */ 78 | #define SO_DONTROUTE 0x0010 /* just use interface addresses */ 79 | #define SO_BROADCAST 0x0020 /* permit sending of broadcast msgs */ 80 | #define SO_USELOOPBACK 0x0040 /* bypass hardware when possible */ 81 | #define SO_LINGER 0x0080 /* linger on close if data present */ 82 | #define SO_OOBINLINE 0x0100 /* leave received OOB data in line */ 83 | #define SO_REUSEPORT 0x0200 /* allow local address & port reuse */ 84 | 85 | #define SO_DONTLINGER (int)(~SO_LINGER) 86 | 87 | /* 88 | * Additional options, not kept in so_options. 89 | */ 90 | #define SO_SNDBUF 0x1001 /* send buffer size */ 91 | #define SO_RCVBUF 0x1002 /* receive buffer size */ 92 | #define SO_SNDLOWAT 0x1003 /* send low-water mark */ 93 | #define SO_RCVLOWAT 0x1004 /* receive low-water mark */ 94 | #define SO_SNDTIMEO 0x1005 /* send timeout */ 95 | #define SO_RCVTIMEO 0x1006 /* receive timeout */ 96 | #define SO_ERROR 0x1007 /* get error status and clear */ 97 | #define SO_TYPE 0x1008 /* get socket type */ 98 | 99 | struct sockaddr { 100 | unsigned short sa_family; 101 | char sa_data[14]; 102 | }; 103 | 104 | #ifndef ntohs 105 | #define ntohs(num) htons(num) 106 | #define ntohl(num) htonl(num) 107 | #endif 108 | 109 | #ifdef __cplusplus 110 | extern "C" { 111 | #endif 112 | 113 | extern int socket(int domain, int type, int protocol); 114 | extern int bind(int socket, const struct sockaddr * addr, int addr_len); 115 | extern int connect(int socket, const struct sockaddr * addr, int addr_len); 116 | extern int send(int socket, const void * data, int sendlength, int flags); 117 | extern int recv(int socket, void * data, int recvlength, int flags); 118 | extern int sendto(int socket, const void * data, int sendlength, int flags, const struct sockaddr * addr, int addr_len); 119 | extern int recvfrom(int socket, void * data, int recvlength, int flags, struct sockaddr * addr, int * addr_len); 120 | extern int listen(int socket, int max_connections); 121 | extern int accept(int socket, struct sockaddr * addr, int * addr_len); 122 | extern int shutdown(int socket, int shutdown_type); 123 | extern int closesocket(int socket); 124 | 125 | extern int ioctl(int socket, long cmd, void * arg); 126 | 127 | extern int setsockopt(int socket, int level, int option_name, const void * data, int data_len); 128 | extern int getsockopt(int socket, int level, int option_name, void * data, int * data_len); 129 | 130 | extern int getpeername(int socket, struct sockaddr *addr, int * addr_len); 131 | extern int getsockname(int socket, struct sockaddr *addr, int * addr_len); 132 | 133 | extern int gethostname(char *name, size_t len); 134 | extern int sethostname(const char *name, size_t len); 135 | 136 | unsigned short htons(unsigned short num); 137 | unsigned long htonl(unsigned long num); 138 | 139 | 140 | extern int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *timeout); 141 | 142 | 143 | #ifdef __cplusplus 144 | }; 145 | #endif 146 | 147 | 148 | #endif 149 | -------------------------------------------------------------------------------- /nocash/WIFIBOOT.A22: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ahezard/no-dsi-wifi/28ec5eb9248af9d4f49101733dace361acd92f0b/nocash/WIFIBOOT.A22 -------------------------------------------------------------------------------- /nocash/WIFIBOOT.NDS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ahezard/no-dsi-wifi/28ec5eb9248af9d4f49101733dace361acd92f0b/nocash/WIFIBOOT.NDS -------------------------------------------------------------------------------- /nocash/WIFICORE.A22: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ahezard/no-dsi-wifi/28ec5eb9248af9d4f49101733dace361acd92f0b/nocash/WIFICORE.A22 -------------------------------------------------------------------------------- /nocash/WIFICORE.~A2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ahezard/no-dsi-wifi/28ec5eb9248af9d4f49101733dace361acd92f0b/nocash/WIFICORE.~A2 --------------------------------------------------------------------------------