Networking - Reworked route table management
authorJohn Hodge <[email protected]>
Sun, 5 Feb 2012 09:58:52 +0000 (17:58 +0800)
committerJohn Hodge <[email protected]>
Sun, 5 Feb 2012 09:58:52 +0000 (17:58 +0800)
- Changed to using meaningful file names instead of indexes
- DHCP client now registers a default route, traffic passes

17 files changed:
Kernel/include/acess.h
Kernel/include/errno.h
Kernel/include/vfs_ext.h
Kernel/include/vfs_int.h
Kernel/lib.c
Kernel/vfs/open.c
Modules/IPStack/main.c
Modules/IPStack/routing.c
Notes/20120204-RoutingNames.txt [new file with mode: 0644]
Usermode/Applications/dhcpclient_src/main.c
Usermode/Applications/ifconfig_src/main.c
Usermode/Applications/ping_src/main.c
Usermode/Libraries/ld-acess.so_src/common.h
Usermode/Libraries/libc.so_src/rand.c [new file with mode: 0644]
Usermode/Libraries/libnet.so_src/address.c
Usermode/Libraries/libnet.so_src/main.c
Usermode/include/acess/sys.h

index de75804..1c645c2 100644 (file)
@@ -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);
 /**
  * \}
index a1a9582..3652f19 100644 (file)
@@ -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
        
index a56d455..b4d5e2a 100644 (file)
@@ -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
index 75de88b..a8eadb6 100644 (file)
@@ -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 ---
index ca37433..8612638 100644 (file)
@@ -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
  */
index 8f01ef7..1536d1a 100644 (file)
@@ -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));
 }
 
 
index 9b9930e..d5d1ebc 100644 (file)
@@ -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;
                }
index 0145f21..7173d1f 100644 (file)
@@ -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 <type>:<addr>, 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 (file)
index 0000000..b07d033
--- /dev/null
@@ -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()?
index ad071db..695f095 100644 (file)
@@ -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);
+               }
        }
 }
 
index e2db088..334ea13 100644 (file)
@@ -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);
        
index 4be3306..33113c8 100644 (file)
@@ -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);
index 379efc1..6f67811 100644 (file)
@@ -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 (file)
index 0000000..acdfddf
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Acess2 Lib C
+ * - By John Hodge (thePowersGang)
+ *
+ * rand.c
+ * - srand/rand/rand_p functions
+ */
+#include <stdlib.h>
+
+// === 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); 
+}
+
index 31b23e5..0430c84 100644 (file)
 #include <stdio.h>
 #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;
index b39d754..403a339 100644 (file)
@@ -11,6 +11,7 @@
 #include <stdlib.h>
 #include <stdio.h>
 
+
 // === 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 );
index 2d2b429..cdd0187 100644 (file)
@@ -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);

UCC git Repository :: git.ucc.asn.au