From 04b368645c34cc3853fc13f93e33ac7878be8479 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Wed, 18 Nov 2009 00:31:45 +0800 Subject: [PATCH] Cleanups & Implementations to allow IPStack to compile - IPStack module now compiles (still unusable) - Added Network Device spec file (tpl_drv_network.h) - Shuffled definitions between vfs.h and vfs_ext.h - Added thorough sanity checking to System calls (except IOCtl as the driver is the only code that knows what it means) - Cleaned up makefiles to delete Dumps and Disassemblies - Added USB core file to tree - Implemented DRV_IOCTL_LOOKUP and NET_IOCTL_GETMAC in NE2000 driver in prepararion for IPStack. --- Kernel/Makefile | 2 +- Kernel/arch/x86/mm_virt.c | 16 ++ Kernel/include/common.h | 13 +- Kernel/include/tpl_drv_common.h | 16 +- Kernel/include/tpl_drv_network.h | 25 +++ Kernel/include/vfs.h | 15 -- Kernel/include/vfs_ext.h | 27 +++ Kernel/lib.c | 86 ++++++++++ Kernel/syscalls.c | 100 +++++++---- Kernel/vfs/io.c | 12 -- Makefile | 23 +-- Modules/IPStack/icmp.c | 2 +- Modules/IPStack/ipstack.h | 6 +- Modules/IPStack/ipv4.c | 8 +- Modules/IPStack/ipv6.c | 6 +- Modules/IPStack/link.c | 10 +- Modules/IPStack/main.c | 178 +++++++++++++++++++- Modules/NE2000/ne2000.c | 40 ++++- Modules/USB/usb.c | 21 +++ Usermode/Applications/CLIShell_src/Makefile | 2 +- Usermode/Applications/cat_src/Makefile | 4 +- Usermode/Applications/login_src/Makefile | 2 +- Usermode/Applications/ls_src/Makefile | 2 +- Usermode/Applications/mount_src/Makefile | 2 +- Usermode/Libraries/ld-acess.so_src/Makefile | 2 +- Usermode/Libraries/libc.so_src/Makefile | 2 +- Usermode/Libraries/libgcc.so_src/Makefile | 2 +- 27 files changed, 511 insertions(+), 113 deletions(-) create mode 100644 Kernel/include/tpl_drv_network.h create mode 100644 Modules/USB/usb.c diff --git a/Kernel/Makefile b/Kernel/Makefile index 9bec8449..ee8c2452 100644 --- a/Kernel/Makefile +++ b/Kernel/Makefile @@ -38,7 +38,7 @@ SRCFILES := $(SRCFILES:%.ao.$(ARCH)=%.asm) all: $(BIN) clean: - @$(RM) $(BIN) $(OBJ) $(DEPFILES) + @$(RM) $(BIN) $(BIN).dsm ../Map.$(ARCH).txt LineCounts.$(ARCH).txt $(OBJ) $(DEPFILES) apidoc: doxygen Doxyfile.api diff --git a/Kernel/arch/x86/mm_virt.c b/Kernel/arch/x86/mm_virt.c index c8061b28..44e18651 100644 --- a/Kernel/arch/x86/mm_virt.c +++ b/Kernel/arch/x86/mm_virt.c @@ -327,6 +327,22 @@ tPAddr MM_GetPhysAddr(tVAddr Addr) return (gaPageTable[Addr >> 12] & ~0xFFF) | (Addr & 0xFFF); } + +/** + * \fn int MM_IsUser(tVAddr Addr) + * \brief Checks if a page is user accessable + */ +int MM_IsUser(tVAddr Addr) +{ + if( !(gaPageDir[Addr >> 22] & 1) ) + return 0; + if( !(gaPageTable[Addr >> 12] & 1) ) + return 0; + if( !(gaPageTable[Addr >> 12] & PF_USER) ) + return 0; + return 1; +} + /** * \fn void MM_SetCR3(tPAddr CR3) * \brief Sets the current process space diff --git a/Kernel/include/common.h b/Kernel/include/common.h index 22bf938e..7638b481 100644 --- a/Kernel/include/common.h +++ b/Kernel/include/common.h @@ -161,10 +161,9 @@ extern tPAddr MM_GetPhysAddr(tVAddr VAddr); /** * \brief Checks is a memory range is user accessable * \param VAddr Base address to check - * \param Length Number of bytes to check * \return 1 if the memory is all user-accessable, 0 otherwise */ -extern int MM_IsUser(tVAddr VAddr, int Length); +extern int MM_IsUser(tVAddr VAddr); /** * \brief Set the access flags on a page * \param VAddr Virtual address of the page @@ -239,6 +238,15 @@ extern void *memcpy(void *dest, const void *src, Uint count); extern void *memcpyd(void *dest, const void *src, Uint count); extern void *memset(void *dest, int val, Uint count); extern void *memsetd(void *dest, Uint val, Uint count); +/** + * \} + */ +/** + * \name Memory Validation + * \{ + */ +extern int CheckString(char *String); +extern int CheckMem(void *Mem, int Num); /** * \} */ @@ -272,6 +280,7 @@ extern int strpos8(const char *str, Uint32 search); extern void itoa(char *buf, Uint num, int base, int minLength, char pad); extern int ReadUTF8(Uint8 *str, Uint32 *Val); extern int WriteUTF8(Uint8 *str, Uint32 Val); +extern int LookupString(char **Array, char *Needle); /** * \} */ diff --git a/Kernel/include/tpl_drv_common.h b/Kernel/include/tpl_drv_common.h index 7608bc8a..e1bdd3e0 100644 --- a/Kernel/include/tpl_drv_common.h +++ b/Kernel/include/tpl_drv_common.h @@ -24,6 +24,8 @@ enum eTplDrv_IOCtl { DRV_IOCTL_LOOKUP }; +#define DRV_IOCTLNAMES "type", "ident", "version", "lookup" + /** * \enum eTplDrv_Type * \brief Driver Types returned by DRV_IOCTL_TYPE @@ -41,18 +43,4 @@ enum eTplDrv_Type { DRV_TYPE_NETWORK //!< Network Device }; -// === FUNCTIONS === -/** - * \fn int GetIOCtlId(int Class, char *Name) - * \brief Transforms a symbolic name into an ID - * \param Class ::eTplDrv_Type type to use - * \param Name Symbolic name to resolve - * - * This function is designed to be used by device drivers to implement - * ::eTplDrv_IOCtl.DRV_IOCTL_LOOKUP easily given that they conform to - * the standard interfaces (::eTplDrv_Type except DRV_TYPE_MISC) and do - * not add their own call numbers. - */ -extern int GetIOCtlId(int Class, char *Name); - #endif diff --git a/Kernel/include/tpl_drv_network.h b/Kernel/include/tpl_drv_network.h new file mode 100644 index 00000000..5a702a2e --- /dev/null +++ b/Kernel/include/tpl_drv_network.h @@ -0,0 +1,25 @@ +/** + * \file tpl_drv_network.h + * \brief Network Interface Driver Interface Definitions +*/ +#ifndef _TPL_NETWORK_H +#define _TPL_NETWORK_H + +#include + +/** + * \enum eTplNetwork_IOCtl + * \brief Common Network IOCtl Calls + * \extends eTplDrv_IOCtl + */ +enum eTplNetwork_IOCtl { + /** + * ioctl(..., Uint8 *MAC[6]) + * \brief Get the MAC address of the interface + */ + NET_IOCTL_GETMAC = 4 +}; + +#define DRV_NETWORK_IOCTLNAMES "get_mac_addr" + +#endif diff --git a/Kernel/include/vfs.h b/Kernel/include/vfs.h index 6fc2491d..7850600c 100644 --- a/Kernel/include/vfs.h +++ b/Kernel/include/vfs.h @@ -40,21 +40,6 @@ #define VFS_PERM_DENY 0x80000000 // Inverts permissions //! \} -/** - * \brief ACL Defintion Structure - */ -typedef struct sVFS_ACL -{ - struct { - unsigned Group: 1; //!< Group (as opposed to user) flag - unsigned ID: 31; //!< ID of Group/User (-1 for nobody/world) - }; - struct { - unsigned Inv: 1; //!< Invert Permissions - unsigned Perms: 31; //!< Permission Flags - }; -} tVFS_ACL; - /** * \name VFS Node Flags * \{ diff --git a/Kernel/include/vfs_ext.h b/Kernel/include/vfs_ext.h index f5219c0a..178eb544 100644 --- a/Kernel/include/vfs_ext.h +++ b/Kernel/include/vfs_ext.h @@ -19,6 +19,33 @@ #define SEEK_CUR 0 #define SEEK_END -1 +// -- System Call Structures --- +/** + * \brief ACL Defintion Structure + */ +typedef struct sVFS_ACL +{ + struct { + unsigned Group: 1; //!< Group (as opposed to user) flag + unsigned ID: 31; //!< ID of Group/User (-1 for nobody/world) + }; + struct { + unsigned Inv: 1; //!< Invert Permissions + unsigned Perms: 31; //!< Permission Flags + }; +} tVFS_ACL; + +struct s_sysFInfo { + Uint uid, gid; + Uint flags; + Uint64 size; + Sint64 atime; + Sint64 mtime; + Sint64 ctime; + int numacls; + tVFS_ACL acls[]; +}; + // === FUNCTIONS === extern int VFS_Init(); diff --git a/Kernel/lib.c b/Kernel/lib.c index 3d91c71c..70d116e0 100644 --- a/Kernel/lib.c +++ b/Kernel/lib.c @@ -341,5 +341,91 @@ Uint rand() return giRandomState; } +/// \name Memory Validation +/// \{ +/** + * \brief Checks if a string resides fully in valid memory + */ +int CheckString(char *String) +{ + // Check 1st page + if( MM_IsUser( (tVAddr)String ) ) + { + // Traverse String + while( *String ) + { + if( !MM_IsUser( (tVAddr)String ) ) + return 0; + // Increment string pointer + String ++; + } + return 1; + } + else if( MM_GetPhysAddr( (tVAddr)String ) ) + { + // Traverse String + while( *String ) + { + if( !MM_GetPhysAddr( (tVAddr)String ) ) + return 0; + // Increment string pointer + String ++; + } + return 1; + } + return 0; +} + +/** + * \brief Check if a sized memory region is valid memory + */ +int CheckMem(void *Mem, int NumBytes) +{ + tVAddr addr = (tVAddr)Mem; + + if( MM_IsUser( addr ) ) + { + while( NumBytes-- ) + { + if( !MM_IsUser( addr ) ) + return 0; + addr ++; + } + return 1; + } + else if( MM_GetPhysAddr( addr ) ) + { + while( NumBytes-- ) + { + if( !MM_GetPhysAddr( addr ) ) + return 0; + addr ++; + } + return 1; + } + return 0; +} +/// \} + +/** + * \brief Search a string array for \a Needle + * \note Helper function for eTplDrv_IOCtl::DRV_IOCTL_LOOKUP + */ +int LookupString(char **Array, char *Needle) +{ + int i; + for( i = 0; Array[i]; i++ ) + { + if(strcmp(Array[i], Needle) == 0) return i; + } + return -1; +} + +EXPORT(strdup); +EXPORT(strcmp); +EXPORT(strcpy); + EXPORT(timestamp); EXPORT(ReadUTF8); +EXPORT(CheckMem); +EXPORT(CheckString); diff --git a/Kernel/syscalls.c b/Kernel/syscalls.c index 8d17e74d..fb574ef2 100644 --- a/Kernel/syscalls.c +++ b/Kernel/syscalls.c @@ -9,6 +9,19 @@ #include #include +#define CHECK_NUM_NULLOK(v,size) do {\ + if((v)&&!Syscall_Valid((size),(Uint)(v))){ret=-1;err=-EINVAL;break;}\ + }while(0) +#define CHECK_STR_NULLOK(v) do {\ + if((v)&&!Syscall_ValidString((Uint)(v))){ret=-1;err=-EINVAL;break;}\ + }while(0) +#define CHECK_NUM_NONULL(v,size) do {\ + if(!(v)||!Syscall_Valid((size),(Uint)(v))){ret=-1;err=-EINVAL;break;}\ + }while(0) +#define CHECK_STR_NONULL(v) do {\ + if(!(v)||!Syscall_ValidString((Uint)(v))){ret=-1;err=-EINVAL;break;}\ + }while(0) + // === IMPORTS === extern int Proc_Clone(Uint *Err, Uint Flags); extern int Threads_WaitTID(int TID, int *status); @@ -70,6 +83,9 @@ void SyscallHandler(tSyscallRegs *Regs) // -- Wait for a thread case SYS_WAITTID: + // Sanity Check (Status can be NULL) + CHECK_NUM_NULLOK( Regs->Arg2, sizeof(int) ); + // TID, *Status ret = Threads_WaitTID(Regs->Arg1, (void*)Regs->Arg2); break; @@ -101,29 +117,52 @@ void SyscallHandler(tSyscallRegs *Regs) // -- Send Message case SYS_SENDMSG: + CHECK_NUM_NONULL(Regs->Arg3, Regs->Arg2); + // Destination, Size, *Data ret = Proc_SendMessage(&err, Regs->Arg1, Regs->Arg2, (void*)Regs->Arg3); break; // -- Check for messages case SYS_GETMSG: + CHECK_NUM_NULLOK(Regs->Arg1, sizeof(Uint)); + //NOTE: Uncertain due to length being unknown + // (Proc_GetMessage should check itself) + CHECK_NUM_NULLOK(Regs->Arg2, sizeof(Uint)*4); + // *Source, *Data ret = Proc_GetMessage(&err, (Uint*)Regs->Arg1, (void*)Regs->Arg2); break; // -- Set the thread's name case SYS_SETNAME: - // Sanity Check - if(!Regs->Arg1) { ret = -1; err = -EINVAL; break; } - Threads_SetName( (void*)Regs->Arg1 ); + CHECK_STR_NONULL(Regs->Arg1); + Threads_SetName( (char*)Regs->Arg1 ); break; // --- // Binary Control // --- case SYS_EXECVE: - if( !Syscall_ValidString(Regs->Arg1) ) { - err = -EINVAL; - ret = -1; - break; + CHECK_STR_NONULL(Regs->Arg1); + { + int i; + char **tmp = (char**)Regs->Arg2; + // Check ArgV (traverse array checking all string pointers) + CHECK_NUM_NONULL( tmp, sizeof(char**) ); + for(i=0;tmp[i];i++) { + CHECK_NUM_NULLOK( &tmp[i], sizeof(char*) ); + CHECK_STR_NONULL( tmp[i] ); + } + // Check EnvP also + // - EnvP can be NULL + if( Regs->Arg3 ) + { + tmp = (char**)Regs->Arg3; + for(i=0;tmp[i];i++) { + CHECK_NUM_NULLOK( &tmp[i], sizeof(char*) ); + CHECK_STR_NONULL( tmp[i] ); + } + } } + // Path, **Argv, **Envp ret = Proc_Execve((char*)Regs->Arg1, (char**)Regs->Arg2, (char**)Regs->Arg3); break; case SYS_LOADBIN: @@ -133,6 +172,7 @@ void SyscallHandler(tSyscallRegs *Regs) ret = -1; break; } + // Path, *Entrypoint ret = Binary_Load((char*)Regs->Arg1, (Uint*)Regs->Arg2); break; @@ -153,7 +193,7 @@ void SyscallHandler(tSyscallRegs *Regs) break; case SYS_SEEK: - ret = VFS_Seek( Regs->Arg1, Regs->Arg2, Regs->Arg3); + ret = VFS_Seek( Regs->Arg1, Regs->Arg2, Regs->Arg3 ); break; case SYS_TELL: @@ -161,28 +201,24 @@ void SyscallHandler(tSyscallRegs *Regs) break; case SYS_WRITE: - #if BITS < 64 - ret = VFS_Write( Regs->Arg1, Regs->Arg2|((Uint64)Regs->Arg3<<32), (void*)Regs->Arg4 ); - #else + CHECK_NUM_NONULL( Regs->Arg3, Regs->Arg2 ); ret = VFS_Write( Regs->Arg1, Regs->Arg2, (void*)Regs->Arg3 ); - #endif break; case SYS_READ: - #if BITS < 64 - ret = VFS_Read( Regs->Arg1, Regs->Arg2|((Uint64)Regs->Arg3<<32), (void*)Regs->Arg4 ); - #else + CHECK_NUM_NONULL( Regs->Arg3, Regs->Arg2 ); ret = VFS_Read( Regs->Arg1, Regs->Arg2, (void*)Regs->Arg3 ); - #endif break; case SYS_FINFO: + CHECK_NUM_NONULL( Regs->Arg2, sizeof(struct s_sysFInfo) + Regs->Arg3*sizeof(tVFS_ACL) ); + // FP, Dest, MaxACLs ret = VFS_FInfo( Regs->Arg1, (void*)Regs->Arg2, Regs->Arg3 ); break; // Get ACL Value case SYS_GETACL: - if( !Syscall_Valid(8, Regs->Arg1) ) { + if( !Syscall_Valid(sizeof(tVFS_ACL), Regs->Arg1) ) { err = -EINVAL; ret = -1; break; @@ -192,7 +228,7 @@ void SyscallHandler(tSyscallRegs *Regs) // Read Directory case SYS_READDIR: - if( !Syscall_ValidString(Regs->Arg2) ) { + if( !Syscall_Valid(8, Regs->Arg2) ) { err = -EINVAL; ret = -1; break; @@ -212,6 +248,7 @@ void SyscallHandler(tSyscallRegs *Regs) // IO Control case SYS_IOCTL: + // All sanity checking should be done by the driver ret = VFS_IOCtl( Regs->Arg1, Regs->Arg2, (void*)Regs->Arg3 ); break; @@ -241,10 +278,12 @@ void SyscallHandler(tSyscallRegs *Regs) break; // -- Debug + #if DEBUG_BUILD case SYS_DEBUG: Log((char*)Regs->Arg1, Regs->Arg2, Regs->Arg3, Regs->Arg4, Regs->Arg5, Regs->Arg6); break; + #endif // -- Default (Return Error) default: @@ -263,7 +302,7 @@ void SyscallHandler(tSyscallRegs *Regs) #endif Regs->Error = err; #if DEBUG - LOG("SyscallHandler: err = %i", err); + LOG("err = %i", err); LEAVE('x', ret); #endif } @@ -274,18 +313,10 @@ void SyscallHandler(tSyscallRegs *Regs) */ int Syscall_ValidString(Uint Addr) { - // Check 1st page - if(!MM_GetPhysAddr(Addr)) return 0; + // Check if the memory is user memory + if(!MM_IsUser(Addr)) return 0; - // Traverse String - while(*(char*)Addr) - { - if(!MM_GetPhysAddr(Addr)) return 0; - // Increment string pointer - Addr ++; - } - - return 1; + return CheckString( (char*)Addr ); } /** @@ -294,10 +325,7 @@ int Syscall_ValidString(Uint Addr) */ int Syscall_Valid(int Size, Uint Addr) { - while(Size--) - { - if(!MM_GetPhysAddr(Addr)) return 0; - Addr ++; - } - return 1; + if(!MM_IsUser(Addr)) return 0; + + return CheckMem( (void*)Addr, Size ); } diff --git a/Kernel/vfs/io.c b/Kernel/vfs/io.c index 4a44b40a..b27e7f09 100644 --- a/Kernel/vfs/io.c +++ b/Kernel/vfs/io.c @@ -182,18 +182,6 @@ int VFS_IOCtl(int FD, int ID, void *Buffer) return h->Node->IOCtl(h->Node, ID, Buffer); } -// -- System Call Structures --- -struct s_sysFInfo { - Uint uid, gid; - Uint flags; - Uint64 size; - Sint64 atime; - Sint64 mtime; - Sint64 ctime; - int numacls; - tVFS_ACL acls[]; -}; - /** * \fn int VFS_FInfo(int FD, struct s_sysFInfo *Dest, int MaxACLs) * \brief Retrieve file information diff --git a/Makefile b/Makefile index 392ab5de..27f4fa8c 100644 --- a/Makefile +++ b/Makefile @@ -25,15 +25,18 @@ all: @$(MAKE) all --no-print-directory -C Usermode/Applications/cat_src @echo === ls @$(MAKE) all --no-print-directory -C Usermode/Applications/ls_src + @echo === mount + @$(MAKE) all --no-print-directory -C Usermode/Applications/mount_src clean: - make clean --no-print-directory -C Kernel/ - make clean --no-print-directory -C Usermode/Libraries/ld-acess.so_src - make clean --no-print-directory -C Usermode/Libraries/libacess.so_src - make clean --no-print-directory -C Usermode/Libraries/libc.so_src - make clean --no-print-directory -C Usermode/Libraries/libgcc.so_src - make clean --no-print-directory -C Usermode/Applications/init_src - make clean --no-print-directory -C Usermode/Applications/login_src - make clean --no-print-directory -C Usermode/Applications/CLIShell_src - make clean --no-print-directory -C Usermode/Applications/cat_src - make clean --no-print-directory -C Usermode/Applications/ls_src + @make clean --no-print-directory -C Kernel/ + @make clean --no-print-directory -C Usermode/Libraries/ld-acess.so_src + @make clean --no-print-directory -C Usermode/Libraries/libacess.so_src + @make clean --no-print-directory -C Usermode/Libraries/libc.so_src + @make clean --no-print-directory -C Usermode/Libraries/libgcc.so_src + @make clean --no-print-directory -C Usermode/Applications/init_src + @make clean --no-print-directory -C Usermode/Applications/login_src + @make clean --no-print-directory -C Usermode/Applications/CLIShell_src + @make clean --no-print-directory -C Usermode/Applications/cat_src + @make clean --no-print-directory -C Usermode/Applications/ls_src + @make clean --no-print-directory -C Usermode/Applications/mount_src diff --git a/Modules/IPStack/icmp.c b/Modules/IPStack/icmp.c index bd9c05f4..4eb4fa40 100644 --- a/Modules/IPStack/icmp.c +++ b/Modules/IPStack/icmp.c @@ -27,6 +27,6 @@ void ICMP_Initialise() */ void ICMP_GetPacket(tInterface *Interface, void *Address, int Length, void *Buffer) { - tICMPHeader *hdr = Buffer; + //tICMPHeader *hdr = Buffer; } diff --git a/Modules/IPStack/ipstack.h b/Modules/IPStack/ipstack.h index 8b846ab3..526ff79c 100644 --- a/Modules/IPStack/ipstack.h +++ b/Modules/IPStack/ipstack.h @@ -54,12 +54,12 @@ struct sInterface { */ struct sAdapter { struct sAdapter *Next; - char *Device; + int DeviceFD; + int NRef; tMacAddr MacAddr; - - tInterface *Interfaces; + char Device[]; }; static const tMacAddr cMAC_BROADCAST = {{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}}; diff --git a/Modules/IPStack/ipv4.c b/Modules/IPStack/ipv4.c index d57b124d..9723d8d7 100644 --- a/Modules/IPStack/ipv4.c +++ b/Modules/IPStack/ipv4.c @@ -6,6 +6,9 @@ #include "link.h" #include "ipv4.h" +// === IMPORTS === +extern tInterface *gIP_Interfaces; + // === PROTOTYPES === int IPv4_Initialise(); void IPv4_int_GetPacket(tAdapter *Interface, tMacAddr From, int Length, void *Buffer); @@ -33,7 +36,7 @@ void IPv4_int_GetPacket(tAdapter *Adapter, tMacAddr From, int Length, void *Buff { tIPv4Header *hdr = Buffer; tInterface *iface; - char *data; + Uint8 *data; int dataLength; if(Length < sizeof(tIPv4Header)) return; @@ -69,8 +72,9 @@ tInterface *IPv4_GetInterface(tAdapter *Adapter, tIPv4 Address, int Broadcast) tInterface *iface = NULL; Uint32 netmask; - for( iface = Adapter->Interfaces; iface; iface = iface->Next) + for( iface = gIP_Interfaces; iface; iface = iface->Next) { + if( iface->Adapter != Adapter ) continue; if( iface->Type != 4 ) continue; if( IP4_EQU(Address, iface->IP4.Address) ) return iface; diff --git a/Modules/IPStack/ipv6.c b/Modules/IPStack/ipv6.c index 31aedcb3..16c9bbdc 100644 --- a/Modules/IPStack/ipv6.c +++ b/Modules/IPStack/ipv6.c @@ -7,6 +7,7 @@ #include "ipv6.h" // === IMPORTS === +extern tInterface *gIP_Interfaces; extern Uint32 IPv4_Netmask(int FixedBits); // === PROTOTYPES === @@ -46,8 +47,11 @@ tInterface *IPv6_GetInterface(tAdapter *Adapter, tIPv6 Address, int Broadcast) tInterface *iface = NULL; Uint32 netmask; - for( iface = Adapter->Interfaces; iface; iface = iface->Next) + for( iface = gIP_Interfaces; iface; iface = iface->Next) { + // Check for this adapter + if( iface->Adapter != Adapter ) continue; + // Skip non-IPv6 Interfaces if( iface->Type != 6 ) continue; diff --git a/Modules/IPStack/link.c b/Modules/IPStack/link.c index fb219847..9dee6e45 100644 --- a/Modules/IPStack/link.c +++ b/Modules/IPStack/link.c @@ -19,6 +19,8 @@ struct { /** * \fn void Link_RegisterType(Uint16 Type, tPacketCallback Callback) * \brief Registers a callback for a specific packet type + * + * \todo Make thread safe (place a mutex on the list) */ void Link_RegisterType(Uint16 Type, tPacketCallback Callback) { @@ -34,7 +36,7 @@ void Link_RegisterType(Uint16 Type, tPacketCallback Callback) if(gaRegisteredTypes[i].Callback == NULL) break; } - if(i + 1 == 0) + if(i == -1) { tmp = realloc(gaRegisteredTypes, (giRegisteredTypes+1)*sizeof(*gaRegisteredTypes)); if(!tmp) Panic("[NET ] Out of heap space!"); @@ -90,7 +92,7 @@ void Link_WatchDevice(tAdapter *Adapter) tEthernetHeader *hdr = (void*)buf; int ret, i; - // Wait for a packet + // Wait for a packet (Read on a network device is blocking) ret = VFS_Read(Adapter->DeviceFD, MAX_PACKET_SIZE, buf); if(ret == -1) break; @@ -105,7 +107,7 @@ void Link_WatchDevice(tAdapter *Adapter) if(gaRegisteredTypes[i].Type == hdr->Type) continue; } // No? Ignore it - if( i + 1 == 0 ) continue; + if( i == -1 ) continue; // Call the callback gaRegisteredTypes[i].Callback( @@ -115,4 +117,6 @@ void Link_WatchDevice(tAdapter *Adapter) hdr->Data ); } + + Log("[NET ] Watcher terminated (file closed)"); } diff --git a/Modules/IPStack/main.c b/Modules/IPStack/main.c index aaeeb9af..2a22d1e0 100644 --- a/Modules/IPStack/main.c +++ b/Modules/IPStack/main.c @@ -2,9 +2,13 @@ * Acess2 IP Stack * - Address Resolution Protocol */ +#define DEBUG 0 +#define VERSION ((0<<8)|10) #include "ipstack.h" #include #include +#include +#include // === IMPORTS === int ARP_Initialise(); @@ -13,12 +17,16 @@ int IPStack_Install(char **Arguments); char *IPStack_ReadDir(tVFS_Node *Node, int Pos); tVFS_Node *IPStack_FindDir(tVFS_Node *Node, char *Name); + int IPStack_IOCtl(tVFS_Node *Node, int ID, void *Data); + int IPStack_AddInterface(char *Device); +tAdapter *IPStack_GetAdapter(char *Path); // === GLOBALS === -MODULE_DEFINE(0, 0x000A, IPStack, IPStack_Install, NULL); +MODULE_DEFINE(0, VERSION, IPStack, IPStack_Install, NULL, NULL); tDevFS_Driver gIP_DriverInfo = { NULL, "ip", { + .Size = 0, // Number of interfaces .NumACLs = 1, .ACLs = &gVFS_ACL_EveryoneRX, .Flags = VFS_FFLAG_DIRECTORY, @@ -26,8 +34,11 @@ tDevFS_Driver gIP_DriverInfo = { .FindDir = IPStack_FindDir } }; - int giIP_NumInterfaces; + int glIP_Interfaces = 0; tInterface *gIP_Interfaces = NULL; +tInterface *gIP_Interfaces_Last = NULL; + int glIP_Adapters = 0; +tAdapter *gIP_Adapters = NULL; // === CODE === /** @@ -83,5 +94,166 @@ char *IPStack_ReadDir(tVFS_Node *Node, int Pos) */ tVFS_Node *IPStack_FindDir(tVFS_Node *Node, char *Name) { - return NULL; + int i; + tInterface *iface; + + if(Name[0] != 'i' || Name[1] != 'p') return NULL; + if(Name[2] < '0' || Name[2] > '9') return NULL; + + if(Name[3] == '\0') { + i = Name[2] - '0'; + for( iface = gIP_Interfaces; iface && i--; iface = iface->Next ) ; + if(!iface) return NULL; + return &iface->Node; + } + + if(Name[3] < '0' || Name[3] > '9') return NULL; + + i = (Name[2] - '0')*10; + i += Name[3] - '0'; + + for( iface = gIP_Interfaces; iface && i--; iface = iface->Next ) ; + if(!iface) return NULL; + return &iface->Node; +} + +static const char *casIOCtls[] = { DRV_IOCTLNAMES, "add_interface", NULL }; +/** + * \brief Handles IOCtls for the IPStack root + */ +int IPStack_IOCtl(tVFS_Node *Node, int ID, void *Data) +{ + switch(ID) + { + // --- Standard IOCtls (0-3) --- + case DRV_IOCTL_TYPE: + return DRV_TYPE_MISC; + + case DRV_IOCTL_IDENT: + if( !CheckMem( Data, 4 ) ) return -1; + memcpy(Data, "IP\0\0", 4); + return 1; + + case DRV_IOCTL_VERSION: + return VERSION; + + case DRV_IOCTL_LOOKUP: + if( !CheckString( Data ) ) return -1; + return LookupString( (char**)casIOCtls, (char*)Data ); + + // --- Non-Standard IOCtls --- + /* + * add_interface + * - Adds a new IP interface and binds it to a device + */ + case 4: + if( !CheckString( Data ) ) return -1; + return IPStack_AddInterface(Data); + } + return 0; +} + +// --- Internal --- +/** + * \fn int IPStack_AddInterface(char *Device) + * \brief Adds an interface to the list + */ +int IPStack_AddInterface(char *Device) +{ + tInterface *iface; + + iface = malloc(sizeof(tInterface)); + if(!iface) return -2; // Return ERR_MYBAD + + iface->Next = NULL; + iface->Type = 0; // Unset type + + // Create Node + iface->Node.Flags = VFS_FFLAG_DIRECTORY; + iface->Node.Size = 0; + iface->Node.NumACLs = 1; + iface->Node.ACLs = &gVFS_ACL_EveryoneRX; + iface->Node.ReadDir = NULL; + iface->Node.FindDir = NULL; + + // Get adapter handle + iface->Adapter = IPStack_GetAdapter(Device); + if( !iface->Adapter ) { + free( iface ); + return -1; // Return ERR_YOUFAIL + } + + // Append to list + LOCK( &glIP_Interfaces ); + if( gIP_Interfaces ) { + gIP_Interfaces_Last->Next = iface; + gIP_Interfaces_Last = iface; + } + else { + gIP_Interfaces = iface; + gIP_Interfaces_Last = iface; + } + RELEASE( &glIP_Interfaces ); + + // Success! + return 1; +} + +/** + * \fn tAdapter *IPStack_GetAdapter(char *Path) + * \brief Gets/opens an adapter given the path + */ +tAdapter *IPStack_GetAdapter(char *Path) +{ + tAdapter *dev; + + LOCK( &glIP_Adapters ); + + // Check if this adapter is already open + for( dev = gIP_Adapters; dev; dev = dev->Next ) + { + if( strcmp(dev->Device, Path) == 0 ) { + dev->NRef ++; + RELEASE( &glIP_Adapters ); + return dev; + } + } + + // Ok, so let's open it + dev = malloc( sizeof(tAdapter) + strlen(Path) + 1 ); + if(!dev) { + RELEASE( &glIP_Adapters ); + return NULL; + } + + // Fill Structure + strcpy( dev->Device, Path ); + dev->NRef = 1; + + // Open Device + dev->DeviceFD = VFS_Open( dev->Device, VFS_OPENFLAG_READ|VFS_OPENFLAG_WRITE ); + if( dev->DeviceFD == -1 ) { + free( dev ); + RELEASE( &glIP_Adapters ); + return NULL; + } + + // Check that it is a network interface + if( VFS_IOCtl(dev->DeviceFD, 0, NULL) != DRV_TYPE_NETWORK ) { + Warning("IPStack_GetAdapter: '%s' is not a network interface", dev->Device); + VFS_Close( dev->DeviceFD ); + free( dev ); + RELEASE( &glIP_Adapters ); + return NULL; + } + + // Get MAC Address + VFS_IOCtl(dev->DeviceFD, NET_IOCTL_GETMAC, &dev->MacAddr); + + // Add to list + dev->Next = gIP_Adapters; + gIP_Adapters = dev; + + RELEASE( &glIP_Adapters ); + return dev; } diff --git a/Modules/NE2000/ne2000.c b/Modules/NE2000/ne2000.c index a0321912..225a0219 100644 --- a/Modules/NE2000/ne2000.c +++ b/Modules/NE2000/ne2000.c @@ -4,6 +4,7 @@ * See: ~/Sources/bochs/bochs.../iodev/ne2k.cc */ #define DEBUG 1 +#define VERSION ((0<<8)|50) #include #include #include @@ -76,12 +77,13 @@ typedef struct sNe2k_Card { int Ne2k_Install(char **Arguments); char *Ne2k_ReadDir(tVFS_Node *Node, int Pos); tVFS_Node *Ne2k_FindDir(tVFS_Node *Node, char *Name); + int Ne2k_IOCtl(tVFS_Node *Node, int ID, void *Data); Uint64 Ne2k_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer); Uint8 Ne2k_int_GetWritePage(tCard *Card, Uint16 Length); void Ne2k_IRQHandler(int IntNum); // === GLOBALS === -MODULE_DEFINE(0, 0x0032, Ne2k, Ne2k_Install, NULL, NULL); +MODULE_DEFINE(0, VERSION, Ne2k, Ne2k_Install, NULL, NULL); tDevFS_Driver gNe2k_DriverInfo = { NULL, "ne2k", { @@ -193,6 +195,7 @@ int Ne2k_Install(char **Options) gpNe2k_Cards[ k ].Node.NumACLs = 0; // Root Only gpNe2k_Cards[ k ].Node.CTime = now(); gpNe2k_Cards[ k ].Node.Write = Ne2k_Write; + gpNe2k_Cards[ k ].Node.IOCtl = Ne2k_IOCtl; } } @@ -223,8 +226,43 @@ tVFS_Node *Ne2k_FindDir(tVFS_Node *Node, char *Name) return &gpNe2k_Cards[ Name[0]-'0' ].Node; } +static const char *casIOCtls[] = { DRV_IOCTLNAMES, DRV_NETWORK_IOCTLNAMES, NULL }; +/** + * \fn int Ne2k_IOCtl(tVFS_Node *Node, int ID, void *Data) + * \brief IOCtl calls for a network device + */ +int Ne2k_IOCtl(tVFS_Node *Node, int ID, void *Data) +{ + switch( ID ) + { + case DRV_IOCTL_TYPE: return DRV_TYPE_NETWORK; + case DRV_IOCTL_IDENT: + if(!CheckMem(Data, 4)) return -1; + memcpy(Data, "NE2K", 4); + return 1; + case DRV_IOCTL_VERSION: return VERSION; + case DRV_IOCTL_LOOKUP: + if(!CheckString(Data)) return -1; + return LookupString( casIOCtls, Data ); + } + + // If this is the root, return + if( Node == &gNe2k_DriverInfo.Node ) return 0; + + // Device specific settings + switch( ID ) + { + case NET_IOCTL_GETMAC: + if(!CheckMem(Data, 6)) return -1; + memcpy( Data, ((tCard*)Node->ImplPtr)->MacAddr, 6 ); + return 1; + } + return 0; +} + /** * \fn Uint64 Ne2k_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) + * \brief Send a packet from the network card */ Uint64 Ne2k_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) { diff --git a/Modules/USB/usb.c b/Modules/USB/usb.c new file mode 100644 index 00000000..99f905f8 --- /dev/null +++ b/Modules/USB/usb.c @@ -0,0 +1,21 @@ +/* + * Acess 2 USB Stack + * USB Packet Control + */ +#define DEBUG 1 +#include +#include +#include +#include "usb.h" + + +// === CODE === +void USB_MakeToken(void *Buf, int PID, int Addr, int EndP) +{ + Uint8 *tok = Buf; + int crc = 0; //USB_TokenCRC(); + + tok[0] = PID; + tok[1] = Addr | ((EndP&1)<<7); + tok[2] = (EndP >> 1) | crc; +} diff --git a/Usermode/Applications/CLIShell_src/Makefile b/Usermode/Applications/CLIShell_src/Makefile index a87f3298..93c58f72 100644 --- a/Usermode/Applications/CLIShell_src/Makefile +++ b/Usermode/Applications/CLIShell_src/Makefile @@ -14,7 +14,7 @@ COBJ = main.o lib.o all: $(BIN) clean: - $(RM) $(COBJ) $(BIN) + $(RM) $(COBJ) $(BIN) $(BIN).dsm Map.txt $(BIN): $(COBJ) @echo --- $(LD) -o $@ diff --git a/Usermode/Applications/cat_src/Makefile b/Usermode/Applications/cat_src/Makefile index 53b8edfe..bc57a4ca 100644 --- a/Usermode/Applications/cat_src/Makefile +++ b/Usermode/Applications/cat_src/Makefile @@ -16,10 +16,10 @@ $(BIN): $(COBJ) @echo --- $(LD) -o $@ @$(LD) $(LDFLAGS) -o $@ $(COBJ) -Map Map.txt objdump -d $(BIN) > $(BIN).dsm - cp $(BIN) $(DISTROOT)/Bin/ + cp $(BIN) $(DISTROOT)/Bin/ clean: - $(RM) $(COBJ) $(BIN) + $(RM) $(COBJ) $(BIN) $(BIN).dsm Map.txt $(COBJ): %.o: %.c @echo --- GCC -o $@ diff --git a/Usermode/Applications/login_src/Makefile b/Usermode/Applications/login_src/Makefile index c09a174a..bd932b98 100644 --- a/Usermode/Applications/login_src/Makefile +++ b/Usermode/Applications/login_src/Makefile @@ -16,7 +16,7 @@ BIN = ../login all: $(BIN) clean: - $(RM) $(BIN) $(OBJ) + $(RM) $(BIN) $(OBJ) login.dsm $(BIN): $(OBJ) @echo --- $(LD) -o $@ diff --git a/Usermode/Applications/ls_src/Makefile b/Usermode/Applications/ls_src/Makefile index 893dc556..efd8834c 100644 --- a/Usermode/Applications/ls_src/Makefile +++ b/Usermode/Applications/ls_src/Makefile @@ -19,7 +19,7 @@ $(BIN): $(COBJ) cp $(BIN) $(DISTROOT)/Bin/ clean: - $(RM) $(COBJ) $(BIN) + $(RM) $(COBJ) $(BIN) $(BIN).dsm Map.txt $(COBJ): %.o: %.c @echo --- GCC -o $@ diff --git a/Usermode/Applications/mount_src/Makefile b/Usermode/Applications/mount_src/Makefile index 276cc833..a5600172 100644 --- a/Usermode/Applications/mount_src/Makefile +++ b/Usermode/Applications/mount_src/Makefile @@ -19,7 +19,7 @@ $(BIN): $(COBJ) cp $(BIN) $(DISTROOT)/Bin/ clean: - $(RM) $(COBJ) $(BIN) + $(RM) $(COBJ) $(BIN) Map.txt $(BIN).dsm $(COBJ): %.o: %.c @echo --- GCC -o $@ diff --git a/Usermode/Libraries/ld-acess.so_src/Makefile b/Usermode/Libraries/ld-acess.so_src/Makefile index 63490916..3298402a 100644 --- a/Usermode/Libraries/ld-acess.so_src/Makefile +++ b/Usermode/Libraries/ld-acess.so_src/Makefile @@ -18,7 +18,7 @@ LDFLAGS = -T link.ld -Map map.txt -Bstatic all: $(BIN) clean: - $(RM) $(BIN) $(AOBJ) $(COBJ) + $(RM) $(BIN) $(AOBJ) $(COBJ) ld-acess.dmp ld-acess.dsm link.txt map.txt $(BIN): $(AOBJ) $(COBJ) @echo --- $(LD) -shared -o $@ diff --git a/Usermode/Libraries/libc.so_src/Makefile b/Usermode/Libraries/libc.so_src/Makefile index 32eb52b4..f9895a8f 100644 --- a/Usermode/Libraries/libc.so_src/Makefile +++ b/Usermode/Libraries/libc.so_src/Makefile @@ -17,7 +17,7 @@ BIN = ../libc.so.1 all: $(BIN) $(OBJ_LIBC) clean: - $(RM) $(BIN) $(OBJ_LIBC) + $(RM) $(BIN) ../libc.so $(OBJ_LIBC) libc.so.1.dsm libc.so.1.dmp map.txt # Core C Library $(BIN): $(OBJ_LIBC) diff --git a/Usermode/Libraries/libgcc.so_src/Makefile b/Usermode/Libraries/libgcc.so_src/Makefile index e57f3a20..f29038fe 100644 --- a/Usermode/Libraries/libgcc.so_src/Makefile +++ b/Usermode/Libraries/libgcc.so_src/Makefile @@ -15,7 +15,7 @@ LDFLAGS += -soname libgcc.so all: $(BIN) clean: - $(RM) $(BIN) $(OBJS) + $(RM) $(BIN) $(OBJS) libgcc.so.dsm $(BIN): $(OBJS) @echo -- ld -o $@ -- 2.20.1