From 7536e8afcc3018c4ca2a4aa8f8422cf86a6c188c Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sun, 5 Feb 2012 17:58:52 +0800 Subject: [PATCH] Networking - Reworked route table management - Changed to using meaningful file names instead of indexes - DHCP client now registers a default route, traffic passes --- Kernel/include/acess.h | 2 + Kernel/include/errno.h | 1 + Kernel/include/vfs_ext.h | 17 +- Kernel/include/vfs_int.h | 2 + Kernel/lib.c | 24 +- Kernel/vfs/open.c | 28 +- Modules/IPStack/main.c | 4 +- Modules/IPStack/routing.c | 392 ++++++++++++++------ Notes/20120204-RoutingNames.txt | 19 + Usermode/Applications/dhcpclient_src/main.c | 17 +- Usermode/Applications/ifconfig_src/main.c | 87 ++--- Usermode/Applications/ping_src/main.c | 36 +- Usermode/Libraries/ld-acess.so_src/common.h | 2 +- Usermode/Libraries/libc.so_src/rand.c | 41 ++ Usermode/Libraries/libnet.so_src/address.c | 21 +- Usermode/Libraries/libnet.so_src/main.c | 18 +- Usermode/include/acess/sys.h | 2 +- 17 files changed, 514 insertions(+), 199 deletions(-) create mode 100644 Notes/20120204-RoutingNames.txt create mode 100644 Usermode/Libraries/libc.so_src/rand.c diff --git a/Kernel/include/acess.h b/Kernel/include/acess.h index de758043..1c645c25 100644 --- a/Kernel/include/acess.h +++ b/Kernel/include/acess.h @@ -417,12 +417,14 @@ extern int strpos(const char *Str, char Ch); extern int strpos8(const char *str, Uint32 search); extern void itoa(char *buf, Uint64 num, int base, int minLength, char pad); extern int atoi(const char *string); +extern int ParseInt(const char *string, int *Val); extern int ReadUTF8(const Uint8 *str, Uint32 *Val); extern int WriteUTF8(Uint8 *str, Uint32 Val); extern int ModUtil_SetIdent(char *Dest, const char *Value); extern int ModUtil_LookupString(const char **Array, const char *Needle); extern Uint8 ByteSum(const void *Ptr, int Size); +extern int Hex(char *Dest, size_t Size, const Uint8 *SourceData); extern int UnHex(Uint8 *Dest, size_t DestSize, const char *SourceString); /** * \} diff --git a/Kernel/include/errno.h b/Kernel/include/errno.h index a1a95820..3652f19f 100644 --- a/Kernel/include/errno.h +++ b/Kernel/include/errno.h @@ -17,6 +17,7 @@ enum eErrorNums EREADONLY, // Read only ENOTIMPL, // Not implemented ENOENT, // No entry? + EEXIST, // Already exists ENFILE, // Too many open files ENOTDIR, // Not a directory diff --git a/Kernel/include/vfs_ext.h b/Kernel/include/vfs_ext.h index a56d4557..b4d5e2ad 100644 --- a/Kernel/include/vfs_ext.h +++ b/Kernel/include/vfs_ext.h @@ -27,8 +27,10 @@ typedef Uint32 tMount; #define VFS_OPENFLAG_WRITE 0x04 //! Do not resolve the final symbolic link #define VFS_OPENFLAG_NOLINK 0x40 +//! Create the file if it doesn't exist +#define VFS_OPENFLAG_CREATE 0x80 //! Open as a user -#define VFS_OPENFLAG_USER 0x80 +#define VFS_OPENFLAG_USER 0x8000 /** * \} */ @@ -176,10 +178,19 @@ extern int VFS_Init(void); /** * \brief Open a file * \param Path Absolute or relative path to the file - * \param Mode Flags defining how to open the file + * \param Flags Flags defining how to open the file * \return VFS Handle (an integer) or -1 if an error occured + * \note Calls VFS_OpenEx(Path, Flags, 0) */ -extern int VFS_Open(const char *Path, Uint Mode); +extern int VFS_Open(const char *Path, Uint Flags); +/** + * \brief Open a file + * \param Path Absolute or relative path to the file + * \param Flags Flags defining how to open the file + * \param Mode Mode for newly created file (POSIX compatability) + * \return VFS Handle (an integer) or -1 if an error occured + */ +extern int VFS_OpenEx(const char *Path, Uint Flags, Uint Mode); /** * \brief Opens a file via an open directory * \note The file to open must be a direct child of the parent diff --git a/Kernel/include/vfs_int.h b/Kernel/include/vfs_int.h index 75de88bf..a8eadb6d 100644 --- a/Kernel/include/vfs_int.h +++ b/Kernel/include/vfs_int.h @@ -53,6 +53,8 @@ extern tVFS_Handle *VFS_GetHandle(int FD); extern int VFS_CheckACL(tVFS_Node *Node, Uint Permissions); // --- mount.c --- extern tVFS_Mount *VFS_GetMountByIdent(Uint32 MountID); +// --- dir.c --- +extern int VFS_MkNod(const char *Path, Uint Flags); // --- VFS Helpers --- diff --git a/Kernel/lib.c b/Kernel/lib.c index ca37433f..8612638c 100644 --- a/Kernel/lib.c +++ b/Kernel/lib.c @@ -50,6 +50,7 @@ void format_date(tTime TS, int *year, int *month, int *day, int *hrs, int *mins, int ModUtil_LookupString(char **Array, char *Needle); int ModUtil_SetIdent(char *Dest, char *Value); + int Hex(char *Dest, size_t Size, const Uint8 *SourceData); int UnHex(Uint8 *Dest, size_t DestSize, const char *SourceString); #endif @@ -92,9 +93,16 @@ EXPORT(memmove); * \brief Convert a string into an integer */ int atoi(const char *string) +{ + int ret = 0; + ParseInt(string, &ret); + return ret; +} +int ParseInt(const char *string, int *Val) { int ret = 0; int bNeg = 0; + const char *orig_string = string; //Log("atoi: (string='%s')", string); @@ -146,13 +154,17 @@ int atoi(const char *string) ret *= 10; ret += *string - '0'; } + // Error check + if( ret == 0 ) return 0; } if(bNeg) ret = -ret; //Log("atoi: RETURN %i", ret); - return ret; + if(Val) *Val = ret; + + return string - orig_string; } static const char cUCDIGITS[] = "0123456789ABCDEF"; @@ -981,6 +993,16 @@ int ModUtil_SetIdent(char *Dest, const char *Value) return 1; } +int Hex(char *Dest, size_t Size, const Uint8 *SourceData) +{ + int i; + for( i = 0; i < Size; i ++ ) + { + sprintf(Dest + i*2, "%02x", SourceData[i]); + } + return i*2; +} + /** * \brief Convert a string of hexadecimal digits into a byte stream */ diff --git a/Kernel/vfs/open.c b/Kernel/vfs/open.c index 8f01ef74..1536d1a0 100644 --- a/Kernel/vfs/open.c +++ b/Kernel/vfs/open.c @@ -453,13 +453,18 @@ int VFS_int_CreateHandle( tVFS_Node *Node, tVFS_Mount *Mount, int Mode ) * \fn int VFS_Open(const char *Path, Uint Mode) * \brief Open a file */ -int VFS_Open(const char *Path, Uint Mode) +int VFS_Open(const char *Path, Uint Flags) +{ + return VFS_OpenEx(Path, Flags, 0); +} + +int VFS_OpenEx(const char *Path, Uint Flags, Uint Mode) { tVFS_Node *node; tVFS_Mount *mnt; char *absPath; - ENTER("sPath xMode", Path, Mode); + ENTER("sPath xFlags oMode", Path, Flags); // Get absolute path absPath = VFS_GetAbsPath(Path); @@ -468,19 +473,32 @@ int VFS_Open(const char *Path, Uint Mode) LEAVE_RET('i', -1); } LOG("absPath = \"%s\"", absPath); + // Parse path and get mount point node = VFS_ParsePath(absPath, NULL, &mnt); + + // Create file if requested and it doesn't exist + if( !node && (Flags & VFS_OPENFLAG_CREATE) ) + { + // TODO: Translate `Mode` into ACL and node flags + // Get parent, create node + VFS_MkNod(absPath, 0); + node = VFS_ParsePath(absPath, NULL, &mnt); + } + // Free generated path free(absPath); - if(!node) { + // Check for error + if(!node) + { LOG("Cannot find node"); errno = ENOENT; LEAVE_RET('i', -1); } // Check for symlinks - if( !(Mode & VFS_OPENFLAG_NOLINK) && (node->Flags & VFS_FFLAG_SYMLINK) ) + if( !(Flags & VFS_OPENFLAG_NOLINK) && (node->Flags & VFS_FFLAG_SYMLINK) ) { char tmppath[node->Size+1]; if( node->Size > MAX_PATH_LEN ) { @@ -504,7 +522,7 @@ int VFS_Open(const char *Path, Uint Mode) } } - LEAVE_RET('x', VFS_int_CreateHandle(node, mnt, Mode)); + LEAVE_RET('x', VFS_int_CreateHandle(node, mnt, Flags)); } diff --git a/Modules/IPStack/main.c b/Modules/IPStack/main.c index 9b9930e3..d5d1ebc2 100644 --- a/Modules/IPStack/main.c +++ b/Modules/IPStack/main.c @@ -266,8 +266,8 @@ const char *IPStack_PrintAddress(int AddressType, const void *Address) static char ret[8*4+7+1]; const Uint16 *addr = Address; sprintf(ret, "%x:%x:%x:%x:%x:%x:%x:%x", - addr[0], addr[1], addr[2], addr[3], - addr[4], addr[5], addr[6], addr[7] + ntohs(addr[0]), ntohs(addr[1]), ntohs(addr[2]), ntohs(addr[3]), + ntohs(addr[4]), ntohs(addr[5]), ntohs(addr[6]), ntohs(addr[7]) ); return ret; } diff --git a/Modules/IPStack/routing.c b/Modules/IPStack/routing.c index 0145f215..7173d1f3 100644 --- a/Modules/IPStack/routing.c +++ b/Modules/IPStack/routing.c @@ -19,9 +19,13 @@ extern tVFS_Node *IPStack_Root_FindDir(tVFS_Node *Node, const char *Filename); // - Routes directory char *IPStack_RouteDir_ReadDir(tVFS_Node *Node, int Pos); tVFS_Node *IPStack_RouteDir_FindDir(tVFS_Node *Node, const char *Name); + int IPStack_RouteDir_MkNod(tVFS_Node *Node, const char *Name, Uint Flags); + int IPStack_RouteDir_Relink(tVFS_Node *Node, const char *OldName, const char *NewName); +tRoute *_Route_FindExactRoute(int Type, void *Network, int Subnet, int Metric); + int _Route_ParseRouteName(const char *Name, void *Addr, int *SubnetBits, int *Metric); int IPStack_RouteDir_IOCtl(tVFS_Node *Node, int ID, void *Data); // - Route Management -tRoute *IPStack_Route_Create(const char *InterfaceName); +tRoute *IPStack_Route_Create(int AddrType, void *Network, int SubnetBits, int Metric); tRoute *IPStack_AddRoute(const char *Interface, void *Network, int SubnetBits, void *NextHop, int Metric); tRoute *IPStack_FindRoute(int AddressType, tInterface *Interface, void *Address); // - Individual Routes @@ -37,6 +41,8 @@ tVFS_NodeType gIP_RouteNodeType = { tVFS_NodeType gIP_RouteDirNodeType = { .ReadDir = IPStack_RouteDir_ReadDir, .FindDir = IPStack_RouteDir_FindDir, + .MkNod = IPStack_RouteDir_MkNod, + .Relink = IPStack_RouteDir_Relink, .IOCtl = IPStack_RouteDir_IOCtl }; tVFS_Node gIP_RouteNode = { @@ -56,15 +62,16 @@ char *IPStack_RouteDir_ReadDir(tVFS_Node *Node, int Pos) tRoute *rt; for(rt = gIP_Routes; rt && Pos --; rt = rt->Next); - - if( !rt ) { - return NULL; - } + if( !rt ) return NULL; { - int len = sprintf(NULL, "%i", (int)rt->Node.Inode); + int addrlen = IPStack_GetAddressSize(rt->AddressType); + int len = sprintf(NULL, "%i::%i:%i", rt->AddressType, rt->SubnetBits, rt->Metric) + addrlen*2; char buf[len+1]; - sprintf(buf, "%i", (int)rt->Node.Inode); + int ofs; + ofs = sprintf(buf, "%i:", rt->AddressType); + ofs += Hex(buf+ofs, addrlen, rt->Network); + sprintf(buf+ofs, ":%i:%i", rt->SubnetBits, rt->Metric); return strdup(buf); } } @@ -74,48 +81,217 @@ char *IPStack_RouteDir_ReadDir(tVFS_Node *Node, int Pos) */ tVFS_Node *IPStack_RouteDir_FindDir(tVFS_Node *Node, const char *Name) { - int num = atoi(Name); - tRoute *rt; - - // Zero is invalid, sorry :) - if( !num ) return NULL; - // Interpret the name as :, returning the interface for // needed to access that address. - // E.g. '4:0A02000A' - 10.2.0.10 + // E.g. '@4:0A02000A' - 10.2.0.10 // Hm... It could do with a way to have a better address type representation - if( Name[1] == ':' ) // TODO: Allow variable length type codes + if( Name[0] == '@' ) { - int addrSize = IPStack_GetAddressSize(num); - Uint8 addrData[addrSize]; + tRoute *rt; + int ofs = 1; + int type; - // Errof if the size is invalid - if( strlen(Name) != 2 + addrSize*2 ) + ofs += ParseInt(Name+ofs, &type); + int addrSize = IPStack_GetAddressSize(type); + Uint8 addrData[addrSize]; + + // Separator + if( Name[ofs] != ':' ) return NULL; + ofs ++; + + // Error if the size is invalid + if( strlen(Name+ofs) != addrSize*2 ) return NULL; // Parse the address // - Error if the address data is not fully hex - if( UnHex(addrData, addrSize, Name + 2) != addrSize ) + if( UnHex(addrData, addrSize, Name + ofs) != addrSize ) return NULL; // Find the route - rt = IPStack_FindRoute(num, NULL, addrData); + rt = IPStack_FindRoute(type, NULL, addrData); if(!rt) return NULL; + + if( rt->Interface ) + { + // Return the interface node + // - Sure it's hijacking it from inteface.c's area, but it's + // simpler this way + return &rt->Interface->Node; + } + else + { + return NULL; + } + } + else if( Name[0] == '#' ) + { + int num, ofs = 1; - // Return the interface node - // - Sure it's hijacking it from inteface.c's area, but it's - // simpler this way - return &rt->Interface->Node; + ofs = ParseInt(Name+ofs, &num); + if( ofs == 1 ) return NULL; + if( Name[ofs] != '\0' ) return NULL; + if( num < 0) return NULL; + + for( tRoute *rt = gIP_Routes; rt; rt = rt->Next ) + { + if( rt->Node.Inode > num ) return NULL; + if( rt->Node.Inode == num ) return &rt->Node; + } + return NULL; } + else + { + int type = _Route_ParseRouteName(Name, NULL, NULL, NULL); + if( type <= 0 ) return NULL; + + int addrSize = IPStack_GetAddressSize(type); + Uint8 addrData[addrSize]; + int subnet_bits, metric; + + _Route_ParseRouteName(Name, addrData, &subnet_bits, &metric); + + tRoute *rt = _Route_FindExactRoute(type, addrData, subnet_bits, metric); + if(rt) return &rt->Node; + return NULL; + } +} + +/** + * \brief Create a new route node + */ +int IPStack_RouteDir_MkNod(tVFS_Node *Node, const char *Name, Uint Flags) +{ + if( Flags ) return -EINVAL; + if( Threads_GetUID() != 0 ) return -EACCES; + + int type = _Route_ParseRouteName(Name, NULL, NULL, NULL); + if( type <= 0 ) return -EINVAL; + + int size = IPStack_GetAddressSize(type); + Uint8 addrdata[size]; + int subnet, metric; + + _Route_ParseRouteName(Name, addrdata, &subnet, &metric); + + // Check for duplicates + if( _Route_FindExactRoute(type, addrdata, subnet, metric) ) + return -EEXIST; + + IPStack_Route_Create(type, addrdata, subnet, metric); + + return 0; +} + +/** + * \brief Rename / Delete a route + */ +int IPStack_RouteDir_Relink(tVFS_Node *Node, const char *OldName, const char *NewName) +{ + tRoute *rt; - // The list is inherently sorted, so we can do a quick search - for(rt = gIP_Routes; rt && rt->Node.Inode < num; rt = rt->Next); + if( Threads_GetUID() != 0 ) return -EACCES; + + // Get the original route entry + { + int type = _Route_ParseRouteName(OldName, NULL, NULL, NULL); + if(type <= 0) return -EINVAL; + Uint8 addr[IPStack_GetAddressSize(type)]; + int subnet, metric; + _Route_ParseRouteName(OldName, addr, &subnet, &metric); + + rt = _Route_FindExactRoute(type, addr, subnet, metric); + } + + if( NewName == NULL ) + { + // Delete the route + tRoute *prev = NULL; + for(tRoute *r = gIP_Routes; r && r != rt; prev = r, r = r->Next); + + if(prev) + prev->Next = rt->Next; + else + gIP_Routes = rt->Next; + free(rt); + } + else + { + // Change the route + int type = _Route_ParseRouteName(NewName, NULL, NULL, NULL); + if(type <= 0) return -EINVAL; + Uint8 addr[IPStack_GetAddressSize(type)]; + int subnet, metric; + _Route_ParseRouteName(NewName, addr, &subnet, &metric); + + return -ENOTIMPL; + } + return 0; +} + +tRoute *_Route_FindExactRoute(int Type, void *Network, int Subnet, int Metric) +{ + for(tRoute *rt = gIP_Routes; rt; rt = rt->Next) + { + if( rt->AddressType != Type ) continue; + if( rt->Metric != Metric ) continue; + if( rt->SubnetBits != Subnet ) continue; + if( IPStack_CompareAddress(Type, rt->Network, Network, -1) == 0 ) + continue ; + return rt; + } + return NULL; +} + +int _Route_ParseRouteName(const char *Name, void *Addr, int *SubnetBits, int *Metric) +{ + int type, addrlen; + int ofs = 0, ilen; - // Fast fail end of list / larger number - if( !rt || rt->Node.Inode > num ) - return NULL; + ENTER("sName pAddr pSubnetBits pMetric", Name, Addr, SubnetBits, Metric); + + ilen = ParseInt(Name, &type); + if(ilen == 0) { + LOG("Type failed to parse"); + LEAVE_RET('i', -1); + } + ofs += ilen; - return &rt->Node; + if(Name[ofs] != ':') LEAVE_RET('i', -1); + ofs ++; + + addrlen = IPStack_GetAddressSize(type); + if( Addr ) + { + if( UnHex(Addr, addrlen, Name + ofs) != addrlen ) + return -1; + } + ofs += addrlen*2; + + if(Name[ofs] != ':') LEAVE_RET('i', -1); + ofs ++; + + ilen = ParseInt(Name+ofs, SubnetBits); + if(ilen == 0) { + LOG("Subnet failed to parse"); + LEAVE_RET('i', -1); + } + ofs += ilen; + + if(Name[ofs] != ':') LEAVE_RET('i', -1); + ofs ++; + + ilen = ParseInt(Name+ofs, Metric); + if(ilen == 0) { + LOG("Metric failed to parse"); + LEAVE_RET('i', -1); + } + ofs += ilen; + + if(Name[ofs] != '\0') LEAVE_RET('i', -1); + + LEAVE('i', type); + return type; } /** @@ -123,7 +299,6 @@ tVFS_Node *IPStack_RouteDir_FindDir(tVFS_Node *Node, const char *Name) */ static const char *casIOCtls_RouteDir[] = { DRV_IOCTLNAMES, - "add_route", // Add a route - char *InterfaceName "locate_route", // Find the best route for an address - struct {int Type, char Address[]} * NULL }; @@ -133,7 +308,6 @@ static const char *casIOCtls_RouteDir[] = { */ int IPStack_RouteDir_IOCtl(tVFS_Node *Node, int ID, void *Data) { - int tmp; tRoute *rt; ENTER("pNode iID pData", Node, ID, Data); switch(ID) @@ -141,17 +315,7 @@ int IPStack_RouteDir_IOCtl(tVFS_Node *Node, int ID, void *Data) // --- Standard IOCtls (0-3) --- BASE_IOCTLS(DRV_TYPE_MISC, STR(IDENT), VERSION, casIOCtls_RouteDir) - case 4: // Add Route - if( !CheckString(Data) ) LEAVE_RET('i', -1); - rt = IPStack_Route_Create(Data); - if( !rt ) - tmp = -1; - else - tmp = rt->Node.Inode; - LEAVE('i', tmp); - return tmp; - - case 5: // Locate Route + case 4: // Locate Route { struct { int Type; @@ -183,26 +347,13 @@ int IPStack_RouteDir_IOCtl(tVFS_Node *Node, int ID, void *Data) * \brief Create a new route entry * \param InterfaceName Name of the interface using this route */ -tRoute *IPStack_Route_Create(const char *InterfaceName) +tRoute *IPStack_Route_Create(int AddrType, void *Network, int SubnetBits, int Metric) { tRoute *rt; - tInterface *iface; int size; - // Get interface - // Note: Oh man! This is such a hack - { - tVFS_Node *node = IPStack_Root_FindDir(NULL, InterfaceName); - if( !node ) { - Log_Debug("IPStack", "IPStack_Route_Create - Unknown interface '%s'\n", InterfaceName); - return NULL; - } - iface = node->ImplPtr; - if(node->Type->Close) node->Type->Close(node); - } - // Get the size of the specified address type - size = IPStack_GetAddressSize(iface->Type); + size = IPStack_GetAddressSize(AddrType); if( size == 0 ) { return NULL; } @@ -219,15 +370,28 @@ tRoute *IPStack_Route_Create(const char *InterfaceName) rt->Node.Type = &gIP_RouteNodeType; // Set up state - rt->AddressType = iface->Type; + rt->AddressType = AddrType; rt->Network = (void *)( (tVAddr)rt + sizeof(tRoute) ); - rt->SubnetBits = 0; + rt->SubnetBits = SubnetBits; rt->NextHop = (void *)( (tVAddr)rt + sizeof(tRoute) + size ); - rt->Interface = iface; - rt->Metric = DEFAUTL_METRIC; - memset(rt->Network, 0, size); + rt->Interface = NULL; + rt->Metric = Metric; + memcpy(rt->Network, Network, size); memset(rt->NextHop, 0, size); + // Clear non-fixed bits + { + Uint8 *data = rt->Network; + int i; + i = SubnetBits / 8; + if( SubnetBits % 8 ) { + data[i] &= ~((1 << (8 - SubnetBits % 8)) - 1); + i ++; + } + memset(data + i, 0, size - i); + } + + // Add to list if( gIP_RoutesEnd ) { gIP_RoutesEnd->Next = rt; @@ -237,7 +401,7 @@ tRoute *IPStack_Route_Create(const char *InterfaceName) gIP_Routes = gIP_RoutesEnd = rt; } - Log_Log("IPStack", "Route entry for '%s' created", InterfaceName); +// Log_Log("IPStack", "Route entry for '%s' created", InterfaceName); return rt; } @@ -247,19 +411,26 @@ tRoute *IPStack_Route_Create(const char *InterfaceName) */ tRoute *IPStack_AddRoute(const char *Interface, void *Network, int SubnetBits, void *NextHop, int Metric) { - tRoute *rt = IPStack_Route_Create(Interface); + tInterface *iface; + tRoute *rt; int addrSize; + { + tVFS_Node *tmp; + tmp = IPStack_Root_FindDir(NULL, Interface); + if(!tmp) return NULL; + iface = tmp->ImplPtr; + if(tmp->Type->Close) tmp->Type->Close(tmp); + } + + rt = IPStack_Route_Create(iface->Type, Network, SubnetBits, Metric); if( !rt ) return NULL; - addrSize = IPStack_GetAddressSize(rt->Interface->Type); + addrSize = IPStack_GetAddressSize(iface->Type); + rt->Interface = iface; - memcpy(rt->Network, Network, addrSize); if( NextHop ) memcpy(rt->NextHop, NextHop, addrSize); - rt->SubnetBits = SubnetBits; - if( Metric ) - rt->Metric = Metric; return rt; } @@ -374,14 +545,10 @@ tRoute *IPStack_FindRoute(int AddressType, tInterface *Interface, void *Address) */ static const char *casIOCtls_Route[] = { DRV_IOCTLNAMES, - "get_type", // Get address type - (void), returns integer type - "get_network", // Get network - (void *Data), returns boolean success - "set_network", // Set network - (void *Data), returns boolean success "get_nexthop", // Get next hop - (void *Data), returns boolean success "set_nexthop", // Set next hop - (void *Data), returns boolean success - "getset_subnetbits", // Get/Set subnet bits - (int *Bits), returns current value - "getset_metric", // Get/Set metric - (int *Metric), returns current value "get_interface", // Get interface name - (char *Name), returns name length, NULL OK + "set_interface", // Set interface - (const char *Name) NULL }; @@ -390,7 +557,6 @@ static const char *casIOCtls_Route[] = { */ int IPStack_Route_IOCtl(tVFS_Node *Node, int ID, void *Data) { - int *iData = Data; tRoute *rt = Node->ImplPtr; int addrSize = IPStack_GetAddressSize(rt->AddressType); @@ -399,60 +565,58 @@ int IPStack_Route_IOCtl(tVFS_Node *Node, int ID, void *Data) // --- Standard IOCtls (0-3) --- BASE_IOCTLS(DRV_TYPE_MISC, STR(IDENT), VERSION, casIOCtls_Route) - // Get address type - case 4: - return rt->AddressType; - - // Get Network - case 5: - if( !CheckMem(Data, addrSize) ) return -1; - memcpy(Data, rt->Network, addrSize); - return 1; - // Set Network - case 6: - if( !CheckMem(Data, addrSize) ) return -1; - memcpy(rt->Network, Data, addrSize); - return 1; - // Get Next Hop - case 7: + case 4: if( !CheckMem(Data, addrSize) ) return -1; memcpy(Data, rt->NextHop, addrSize); return 1; // Set Next Hop - case 8: + case 5: + if( Threads_GetUID() != 0 ) return -1; if( !CheckMem(Data, addrSize) ) return -1; memcpy(rt->NextHop, Data, addrSize); return 1; - - // Get/Set Subnet Bits - case 9: - if( Data ) { - if( !CheckMem(Data, sizeof(int)) ) return -1; - if( *iData < 0 || *iData > addrSize*8 ) + + // Get interface name + case 6: + if( !rt->Interface ) { + if(Data && !CheckMem(Data, 1) ) return -1; - rt->SubnetBits = *iData; - } - return rt->SubnetBits; - - // Get/Set Metric - case 10: - if( Data ) { - if( !CheckMem(Data, sizeof(int)) ) return -1; - if( *iData < 0 ) return -1; - rt->Metric = *iData; + if(Data) + *(char*)Data = 0; + return 0; } - return rt->Metric; - - // Get interface name - case 11: if( Data ) { if( !CheckMem(Data, strlen(rt->Interface->Name) + 1) ) return -1; strcpy(Data, rt->Interface->Name); } return strlen(rt->Interface->Name); + // Set interface name + case 7: + if( Threads_GetUID() != 0 ) + return -1; + if( !CheckString(Data) ) + return -1; + else + { + tInterface *iface; + tVFS_Node *tmp; + tmp = IPStack_Root_FindDir(NULL, Data); + if(!tmp) + return -1; + iface = tmp->ImplPtr; + if(tmp->Type->Close) tmp->Type->Close(tmp); + + if( iface->Type != rt->AddressType ) + return -1; + + // TODO: Other checks? + rt->Interface = iface; + } + return 0; + default: return -1; } diff --git a/Notes/20120204-RoutingNames.txt b/Notes/20120204-RoutingNames.txt new file mode 100644 index 00000000..b07d0331 --- /dev/null +++ b/Notes/20120204-RoutingNames.txt @@ -0,0 +1,19 @@ +Network only? +- "/Devices/ip/routes/4:0A000200:24" +Network and Metric? +- "/Devices/ip/routes/4:0A000200:24:10" + +Would it need the interface? +- "/Devices/ip/routes/0:4:0A000200:24:10" + + +Current model +- num = "/Devices/ip/routes"->CreateRoute("interface") +- "/Devices/ip/routes/{num}"->SetNetwork() +- "/Devices/ip/routes/{num}"->SetSubnetBits() +- "/Devices/ip/routes/{num}"->SetMetric() +- "/Devices/ip/routes/{num}"->SetNextHop() + +New Model +- "/Devices/ip/routes/{type}:{network}:{subnet}:{metric}"->SetNextHop() +- "/Devices/ip/routes/{type}:{network}:{subnet}:{metric}"->SetInterface()? diff --git a/Usermode/Applications/dhcpclient_src/main.c b/Usermode/Applications/dhcpclient_src/main.c index ad071db7..695f0952 100644 --- a/Usermode/Applications/dhcpclient_src/main.c +++ b/Usermode/Applications/dhcpclient_src/main.c @@ -21,6 +21,7 @@ static inline uint16_t htons(uint16_t v) } #define htonb(v) v #define ntohl(v) htonl(v) +#define ntohs(v) htons(v) // === CONSTANTS === enum eStates @@ -357,8 +358,20 @@ void SetAddress(tInterface *Iface, void *Addr, void *Mask, void *Router) { uint8_t *addr = Router; _SysDebug("Router %i.%i.%i.%i", addr[0], addr[1], addr[2], addr[3]); -// ioctl(Iface->IfaceFD, 8, addr); - // TODO: Default route + + // Set default route + int fd; + fd = open("/Devices/ip/routes/4:00000000:0:0", OPENFLAG_CREATE); + if(fd == -1) { + fprintf(stderr, "ERROR: Unable to open default route\n"); + } + else { + char ifname[snprintf(NULL,0,"%i",Iface->Num)+1]; + sprintf(ifname, "%i", Iface->Num); + ioctl(fd, ioctl(fd, 3, "set_nexthop"), Router); + ioctl(fd, ioctl(fd, 3, "set_interface"), ifname); + close(fd); + } } } diff --git a/Usermode/Applications/ifconfig_src/main.c b/Usermode/Applications/ifconfig_src/main.c index e2db088f..334ea137 100644 --- a/Usermode/Applications/ifconfig_src/main.c +++ b/Usermode/Applications/ifconfig_src/main.c @@ -227,7 +227,7 @@ void DumpRoutes(void) dp = open(IPSTACK_ROOT"/routes", OPENFLAG_READ); - printf("ID\tType\tNetwork \tGateway \tMetric\tIFace\n"); + printf("Type\tNetwork \tGateway \tMetric\tIFace\n"); while( readdir(dp, filename) ) { @@ -327,15 +327,24 @@ void DumpRoute(const char *Name) return ; } - type = ioctl(fd, 4, NULL); - - // Ignore -1 values - if( type == -1 ) { - return ; + int ofs = 2; + type = atoi(Name); + + int i; + int len = Net_GetAddressSize(type); + uint8_t net[len], gw[len]; + int subnet, metric; + for( i = 0; i < len; i ++ ) { + char tmp[5] = "0x00"; + tmp[2] = Name[ofs++]; + tmp[3] = Name[ofs++]; + net[i] = atoi(tmp); } - - // Number - printf("%s\t", Name); + ofs ++; + subnet = atoi(Name+ofs); + ofs ++; + metric = atoi(Name+ofs); + ioctl(fd, ioctl(fd, 3, "get_nexthop"), gw); // Get Gateway/NextHop // Get the address type switch(type) @@ -344,37 +353,18 @@ void DumpRoute(const char *Name) printf("DISABLED\n"); break; case 4: // IPv4 - { - uint8_t net[4], addr[4]; - int subnet, metric; printf("IPv4\t"); - ioctl(fd, ioctl(fd, 3, "get_network"), net); // Get Network - ioctl(fd, ioctl(fd, 3, "get_nexthop"), addr); // Get Gateway/NextHop - subnet = ioctl(fd, ioctl(fd, 3, "getset_subnetbits"), NULL); // Get Subnet Bits - metric = ioctl(fd, ioctl(fd, 3, "getset_metric"), NULL); // Get Subnet Bits - printf("%s/%i\t", Net_PrintAddress(4, net), subnet); - printf("%s \t", Net_PrintAddress(4, addr)); - printf("%i\t", metric); - } break; case 6: // IPv6 - { - uint16_t net[8], addr[8]; - int subnet, metric; printf("IPv6\t"); - ioctl(fd, ioctl(fd, 3, "get_network"), net); // Get Network - ioctl(fd, ioctl(fd, 3, "get_nexthop"), addr); // Get Gateway/NextHop - subnet = ioctl(fd, ioctl(fd, 3, "getset_subnetbits"), NULL); // Get Subnet Bits - metric = ioctl(fd, ioctl(fd, 3, "getset_metric"), NULL); // Get Subnet Bits - printf("%s/%i\t", Net_PrintAddress(6, net), subnet); - printf("%s\t", Net_PrintAddress(6, addr)); - printf("%i\t", metric); - } break; default: // Unknow printf("UNKNOWN (%i)\n", type); break; } + printf("%s/%i\t", Net_PrintAddress(type, net), subnet); + printf("%s \t", Net_PrintAddress(type, gw)); + printf("%i\t", metric); // Interface { @@ -417,7 +407,6 @@ void AddRoute(const char *Interface, int AddressType, void *Dest, int MaskBits, { int fd; int num; - char tmp[sizeof(IPSTACK_ROOT"/routes/") + 5]; // enough for 4 digits char *ifaceToFree = NULL; // Get interface name @@ -460,19 +449,33 @@ void AddRoute(const char *Interface, int AddressType, void *Dest, int MaskBits, } // Create route - fd = open(IPSTACK_ROOT"/routes", 0); - num = ioctl(fd, ioctl(fd, 3, "add_route"), (char*)Interface); - close(fd); - - // Open route - sprintf(tmp, IPSTACK_ROOT"/routes/%i", num); - fd = open(tmp, 0); + int addrsize = Net_GetAddressSize(AddressType); + int len = snprintf(NULL, 0, "/Devices/ip/routes/%i::%i:%i", AddressType, MaskBits, Metric) + addrsize*2; + char path[len+1]; + { + int i, ofs; + ofs = sprintf(path, "/Devices/ip/routes/%i:", AddressType); + for( i = 0; i < addrsize; i ++ ) + sprintf(path+ofs+i*2, "%02x", ((uint8_t*)Dest)[i]); + ofs += addrsize*2; + sprintf(path+ofs, ":%i:%i", MaskBits, Metric); + } + + fd = open(path, 0); + if( fd != -1 ) { + close(fd); + fprintf(stderr, "Unable to create route '%s', already exists\n", path); + return ; + } + fd = open(path, OPENFLAG_CREATE, 0); + if( fd == -1 ) { + fprintf(stderr, "Unable to create '%s'\n", path); + return ; + } - ioctl(fd, ioctl(fd, 3, "set_network"), Dest); if( NextHop ) ioctl(fd, ioctl(fd, 3, "set_nexthop"), NextHop); - ioctl(fd, ioctl(fd, 3, "getset_subnetbits"), &MaskBits); - ioctl(fd, ioctl(fd, 3, "getset_metric"), &Metric); + ioctl(fd, ioctl(fd, 3, "set_interface"), (void*)Interface); close(fd); diff --git a/Usermode/Applications/ping_src/main.c b/Usermode/Applications/ping_src/main.c index 4be3306c..33113c8d 100644 --- a/Usermode/Applications/ping_src/main.c +++ b/Usermode/Applications/ping_src/main.c @@ -80,19 +80,7 @@ int main(int argc, char *argv[]) return 1; } - if( !iface ) - { - iface = Net_GetInterface(type, addr); - if( !iface ) { - fprintf(stderr, "Unable to find a route to '%s'\n", - Net_PrintAddress(type, addr) - ); - return -1; - } - - printf("iface = '%s'\n", iface); - } - + if( iface ) { char *_iface = malloc( sizeof("/Devices/ip/") + strlen(iface) + 1 ); strcpy(_iface, "/Devices/ip/"); @@ -100,14 +88,24 @@ int main(int argc, char *argv[]) free(iface); // TODO: Handle when this is not heap iface = _iface; printf("iface = '%s'\n", iface); + fd = open(iface, OPENFLAG_EXEC); + if(fd == -1) { + fprintf(stderr, "ERROR: Unable to open interface '%s'\n", iface); + return 1; + } + } - - fd = open(iface, OPENFLAG_EXEC); - if(fd == -1) { - fprintf(stderr, "ERROR: Unable to open interface '%s'\n", iface); - return 1; + else + { + fd = Net_OpenSocket(type, addr, NULL); + if( fd == -1 ) { + fprintf(stderr, "Unable to find a route to '%s'\n", + Net_PrintAddress(type, addr) + ); + return -1; + } } - + call = ioctl(fd, 3, "ping"); if(call == 0) { fprintf(stderr, "ERROR: '%s' does not have a 'ping' call\n", iface); diff --git a/Usermode/Libraries/ld-acess.so_src/common.h b/Usermode/Libraries/ld-acess.so_src/common.h index 379efc11..6f67811a 100644 --- a/Usermode/Libraries/ld-acess.so_src/common.h +++ b/Usermode/Libraries/ld-acess.so_src/common.h @@ -57,7 +57,7 @@ extern void SysDebugV(const char *fmt, ...); extern void *SysLoadBin(const char *path, void **entry); extern int SysUnloadBin(void *Base); extern void SysSetFaultHandler(int (*Hanlder)(int)); -extern int open(const char *filename, int flags); +extern int open(const char *filename, int flags, ...); extern int close(int fd); // === ELF Loader === diff --git a/Usermode/Libraries/libc.so_src/rand.c b/Usermode/Libraries/libc.so_src/rand.c new file mode 100644 index 00000000..acdfddfe --- /dev/null +++ b/Usermode/Libraries/libc.so_src/rand.c @@ -0,0 +1,41 @@ +/* + * Acess2 Lib C + * - By John Hodge (thePowersGang) + * + * rand.c + * - srand/rand/rand_p functions + */ +#include + +// === GLOBALS === +unsigned int _rand_state_x = 123456789; +unsigned int _rand_state_y = 362436069; +unsigned int _rand_state_z = 521288629; +unsigned int _rand_state_w = 88675123; + +// === FUNCTIONS === +int rand_p(unsigned int *seedp) +{ + const int const_a = 0x731ADE, const_c = 12345; + // Linear Congruency + *seedp = *seedp * const_a + const_c; + return *seedp; +} + +void srand(unsigned int seed) +{ + _rand_state_x = rand_p( &seed ); + _rand_state_y = rand_p( &seed ); + _rand_state_z = rand_p( &seed ); + _rand_state_w = rand_p( &seed ); +} + +int rand(void) +{ + unsigned int t; + + t = _rand_state_x ^ (_rand_state_x << 11); + _rand_state_x = _rand_state_y; _rand_state_y = _rand_state_z; _rand_state_z = _rand_state_w; + return _rand_state_w = _rand_state_w ^ (_rand_state_w >> 19) ^ t ^ (t >> 8); +} + diff --git a/Usermode/Libraries/libnet.so_src/address.c b/Usermode/Libraries/libnet.so_src/address.c index 31b23e51..0430c84d 100644 --- a/Usermode/Libraries/libnet.so_src/address.c +++ b/Usermode/Libraries/libnet.so_src/address.c @@ -10,6 +10,23 @@ #include #define DEBUG 0 +static inline uint32_t htonl(uint32_t v) +{ + return (((v >> 24) & 0xFF) << 0) + | (((v >> 16) & 0xFF) << 8) + | (((v >> 8) & 0xFF) << 16) + | (((v >> 0) & 0xFF) << 24); +} +static inline uint16_t htons(uint16_t v) +{ + return (((v >> 8) & 0xFF) << 0) + | (((v >> 0) & 0xFF) << 8); +} +#define htonb(v) v +#define ntohl(v) htonl(v) +#define ntohs(v) htons(v) +#define ntohb(v) v + #define __thread // Disable TLS /** @@ -191,8 +208,8 @@ static const char *Net_PrintIPv6Address(uint16_t *Address) #endif sprintf(ret, "%x:%x:%x:%x:%x:%x:%x:%x", - Address[0], Address[1], Address[2], Address[3], - Address[4], Address[5], Address[6], Address[7] + ntohs(Address[0]), ntohs(Address[1]), ntohs(Address[2]), ntohs(Address[3]), + ntohs(Address[4]), ntohs(Address[5]), ntohs(Address[6]), ntohs(Address[7]) ); return ret; diff --git a/Usermode/Libraries/libnet.so_src/main.c b/Usermode/Libraries/libnet.so_src/main.c index b39d7548..403a3394 100644 --- a/Usermode/Libraries/libnet.so_src/main.c +++ b/Usermode/Libraries/libnet.so_src/main.c @@ -11,6 +11,7 @@ #include #include + // === CODE === int SoMain(void) { @@ -40,16 +41,16 @@ int Net_OpenSocket(int AddrType, void *Addr, const char *Filename) if(Filename) { - int len = snprintf(NULL, 100, "/Devices/ip/routes/%i:%s/%s", AddrType, hexAddr, Filename); + int len = snprintf(NULL, 100, "/Devices/ip/routes/@%i:%s/%s", AddrType, hexAddr, Filename); char path[len+1]; - snprintf(path, 100, "/Devices/ip/routes/%i:%s/%s", AddrType, hexAddr, Filename); + snprintf(path, 100, "/Devices/ip/routes/@%i:%s/%s", AddrType, hexAddr, Filename); return open(path, OPENFLAG_READ|OPENFLAG_WRITE); } else { - int len = snprintf(NULL, 100, "/Devices/ip/routes/%i:%s", AddrType, hexAddr); + int len = snprintf(NULL, 100, "/Devices/ip/routes/@%i:%s", AddrType, hexAddr); char path[len+1]; - snprintf(path, 100, "/Devices/ip/routes/%i:%s", AddrType, hexAddr); + snprintf(path, 100, "/Devices/ip/routes/@%i:%s", AddrType, hexAddr); return open(path, OPENFLAG_READ); } } @@ -89,15 +90,18 @@ char *Net_GetInterface(int AddressType, void *Address) // Check answer validity if( routeNum > 0 ) { - int len = sprintf(NULL, "/Devices/ip/routes/%i", routeNum); + int len = sprintf(NULL, "/Devices/ip/routes/#%i", routeNum); char buf[len+1]; char *ret; - sprintf(buf, "/Devices/ip/routes/%i", routeNum); + sprintf(buf, "/Devices/ip/routes/#%i", routeNum); // Open route fd = open(buf, 0); - if( !fd ) return NULL; // Shouldn't happen :/ + if( fd == -1 ) { + fprintf(stderr, "Net_GetInterface - ERROR: Unabel to open %s\n", buf); + return NULL; // Shouldn't happen :/ + } // Allocate space for name ret = malloc( ioctl(fd, ioctl(fd, 3, "get_interface"), NULL) + 1 ); diff --git a/Usermode/include/acess/sys.h b/Usermode/include/acess/sys.h index 2d2b4291..cdd01879 100644 --- a/Usermode/include/acess/sys.h +++ b/Usermode/include/acess/sys.h @@ -62,7 +62,7 @@ extern void setgid(int id); // --- VFS --- extern int chdir(const char *dir); -extern int open(const char *path, int flags); +extern int open(const char *path, int flags, ...); extern int reopen(int fd, const char *path, int flags); extern int close(int fd); extern uint read(int fd, void *buffer, uint length); -- 2.20.1