Fixed compilation issues in IPStack
[tpg/acess2.git] / Modules / IPStack / main.c
index 6b6f8a9..d36db98 100644 (file)
@@ -23,18 +23,21 @@ extern int  IPv4_Initialise();
 extern int     IPv4_Ping(tInterface *Iface, tIPv4 Addr);
 extern int     IPv6_Initialise();
 //extern int   IPv6_Ping(tInterface *Iface, tIPv6 Addr);
+extern tVFS_Node       gIP_RouteNode;
 
 // === PROTOTYPES ===
  int   IPStack_Install(char **Arguments);
  int   IPStack_IOCtlRoot(tVFS_Node *Node, int ID, void *Data);
 char   *IPStack_Root_ReadDir(tVFS_Node *Node, int Pos);
-tVFS_Node      *IPStack_Root_FindDir(tVFS_Node *Node, char *Name);
+tVFS_Node      *IPStack_Root_FindDir(tVFS_Node *Node, const char *Name);
  int   IPStack_Root_IOCtl(tVFS_Node *Node, int ID, void *Data);
- int   IPStack_AddInterface(char *Device);
-tAdapter       *IPStack_GetAdapter(char *Path);
 char   *IPStack_Iface_ReadDir(tVFS_Node *Node, int Pos);
-tVFS_Node      *IPStack_Iface_FindDir(tVFS_Node *Node, char *Name);
+tVFS_Node      *IPStack_Iface_FindDir(tVFS_Node *Node, const char *Name);
  int   IPStack_Iface_IOCtl(tVFS_Node *Node, int ID, void *Data);
+ int   IPStack_AddInterface(const char *Device, const char *Name);
+tAdapter       *IPStack_GetAdapter(const char *Path);
 
 // === GLOBALS ===
 MODULE_DEFINE(0, VERSION, IPStack, IPStack_Install, NULL, NULL);
@@ -50,11 +53,26 @@ tDevFS_Driver       gIP_DriverInfo = {
        .IOCtl = IPStack_Root_IOCtl
        }
 };
-tSpinlock      glIP_Interfaces = 0;
+tShortSpinlock glIP_Interfaces;
+//! Loopback (127.0.0.0/8, ::1) Pseudo-Interface
+tInterface     gIP_LoopInterface = {
+       Node: {
+               ImplPtr: &gIP_LoopInterface,
+               Flags: VFS_FFLAG_DIRECTORY,
+               Size: -1,
+               NumACLs: 1,
+               ACLs: &gVFS_ACL_EveryoneRX,
+               ReadDir: IPStack_Iface_ReadDir,
+               FindDir: IPStack_Iface_FindDir,
+               IOCtl: IPStack_Iface_IOCtl
+       },
+       Adapter: NULL,
+       Type: 0
+};
 tInterface     *gIP_Interfaces = NULL;
 tInterface     *gIP_Interfaces_Last = NULL;
  int   giIP_NextIfaceId = 1;
-tSpinlock      glIP_Adapters = 0;
+tMutex glIP_Adapters;
 tAdapter       *gIP_Adapters = NULL;
 tSocketFile    *gIP_FileTemplates;
 
@@ -67,12 +85,11 @@ int IPStack_Install(char **Arguments)
 {
         int    i = 0;
        
-       // Layer 2 - Data Link Layer
+       // Layer 3 - Network Layer Protocols
        ARP_Initialise();
-       // Layer 3 - Network Layer
        IPv4_Initialise();
        IPv6_Initialise();
-       // Layer 4 - Transport Layer
+       // Layer 4 - Transport Layer Protocols
        TCP_Initialise();
        UDP_Initialise();
        
@@ -81,15 +98,22 @@ int IPStack_Install(char **Arguments)
                // Parse module arguments
                for( i = 0; Arguments[i]; i++ )
                {
-                       //if(strcmp(Arguments[i], "Device") == '=') {
-                       //      
-                       //}
+                       // TODO:
+                       // Define interfaces by <Device>,<Type>,<HexStreamAddress>,<Bits>
+                       // Where:
+                       // - <Device> is the device path (E.g. /Devices/ne2k/0)
+                       // - <Type> is a number (e.g. 4) or symbol (e.g. AF_INET4)
+                       // - <HexStreamAddress> is a condensed hexadecimal stream (in big endian)
+                       //      (E.g. 0A000201 for 10.0.2.1 IPv4)
+                       // - <Bits> is the number of subnet bits (E.g. 24 for an IPv4 Class C)
                }
        }
        
+       gIP_LoopInterface.Adapter = IPStack_GetAdapter("/Devices/fifo/anon");
+       
        DevFS_AddDevice( &gIP_DriverInfo );
        
-       return 1;
+       return MODULE_ERR_OK;
 }
 
 /**
@@ -97,7 +121,7 @@ int IPStack_Install(char **Arguments)
  */
 int IPStack_AddFile(tSocketFile *File)
 {
-       Log("IPStack_AddFile: %s", File->Name);
+       Log_Log("IPStack", "Added file '%s'", File->Name);
        File->Next = gIP_FileTemplates;
        gIP_FileTemplates = File;
        return 0;
@@ -112,6 +136,17 @@ char *IPStack_Root_ReadDir(tVFS_Node *Node, int Pos)
        char    *name;
        ENTER("pNode iPos", Node, Pos);
        
+
+       // Routing Subdir
+       if( Pos == 0 ) {
+               return strdup("routes");
+       }
+       // Pseudo Interfaces
+       if( Pos == 1 ) {
+               return strdup("lo");
+       }
+       Pos -= 2;
+       
        // Traverse the list
        for( iface = gIP_Interfaces; iface && Pos--; iface = iface->Next ) ;
        
@@ -122,6 +157,11 @@ char *IPStack_Root_ReadDir(tVFS_Node *Node, int Pos)
        }
        
        name = malloc(4);
+       if(!name) {
+               Log_Warning("IPStack", "IPStack_Root_ReadDir - malloc error");
+               LEAVE('n');
+               return NULL;
+       }
        
        // Create the name
        Pos = iface->Node.ImplInt;
@@ -149,13 +189,23 @@ char *IPStack_Root_ReadDir(tVFS_Node *Node, int Pos)
 /**
  * \brief Get the node of an interface
  */
-tVFS_Node *IPStack_Root_FindDir(tVFS_Node *Node, char *Name)
+tVFS_Node *IPStack_Root_FindDir(tVFS_Node *Node, const char *Name)
 {
         int    i, num;
        tInterface      *iface;
        
        ENTER("pNode sName", Node, Name);
        
+       // Routing subdir
+       if( strcmp(Name, "routes") == 0 ) {
+               return &gIP_RouteNode;
+       }
+       
+       // Loopback
+       if( strcmp(Name, "lo") == 0 ) {
+               return &gIP_LoopInterface.Node;
+       }
+       
        i = 0;  num = 0;
        while('0' <= Name[i] && Name[i] <= '9')
        {
@@ -170,7 +220,7 @@ tVFS_Node *IPStack_Root_FindDir(tVFS_Node *Node, char *Name)
        
        for( iface = gIP_Interfaces; iface; iface = iface->Next )
        {
-               if( iface->Node.ImplInt == num )
+               if( (int)iface->Node.ImplInt == num )
                {
                        LEAVE('p', &iface->Node);
                        return &iface->Node;
@@ -217,7 +267,10 @@ int IPStack_Root_IOCtl(tVFS_Node *Node, int ID, void *Data)
        case 4:
                if( Threads_GetUID() != 0 )     LEAVE_RET('i', -1);
                if( !CheckString( Data ) )      LEAVE_RET('i', -1);
-               tmp = IPStack_AddInterface(Data);
+               {
+                       char    name[4] = "";
+                       tmp = IPStack_AddInterface(Data, name);
+               }
                LEAVE_RET('i', tmp);
        }
        LEAVE('i', 0);
@@ -231,7 +284,6 @@ char *IPStack_Iface_ReadDir(tVFS_Node *Node, int Pos)
 {
        tSocketFile     *file = gIP_FileTemplates;
        while(Pos-- && file) {
-               Log("IPStack_Iface_ReadDir: %s", file->Name);
                file = file->Next;
        }
        
@@ -243,7 +295,7 @@ char *IPStack_Iface_ReadDir(tVFS_Node *Node, int Pos)
 /**
  * \brief Gets a named node from an interface directory
  */
-tVFS_Node *IPStack_Iface_FindDir(tVFS_Node *Node, char *Name)
+tVFS_Node *IPStack_Iface_FindDir(tVFS_Node *Node, const char *Name)
 {
        tSocketFile     *file = gIP_FileTemplates;
        
@@ -251,7 +303,6 @@ tVFS_Node *IPStack_Iface_FindDir(tVFS_Node *Node, char *Name)
        for(;file;file = file->Next)
        {
                if( strcmp(file->Name, Name) == 0 )     break;
-               Log("IPStack_Iface_FindDir: strcmp('%s', '%s')", file->Name, Name);
        }
        if(!file)       return NULL;
        
@@ -268,6 +319,7 @@ static const char *casIOCtls_Iface[] = {
        "get_address", "set_address",
        "getset_subnet",
        "get_gateway", "set_gateway",
+       "get_device",
        "ping",
        NULL
        };
@@ -465,11 +517,23 @@ int IPStack_Iface_IOCtl(tVFS_Node *Node, int ID, void *Data)
                }
                break;
        
+       /*
+        * get_device
+        * - Gets the name of the attached device
+        */
+       case 10:
+               if( Data == NULL )
+                       LEAVE_RET('i', iface->Adapter->DeviceLen);
+               if( !CheckMem( Data, iface->Adapter->DeviceLen+1 ) )
+                       LEAVE_RET('i', -1);
+               strcpy( Data, iface->Adapter->Device );
+               return iface->Adapter->DeviceLen;
+       
        /*
         * ping
         * - Send an ICMP Echo
         */
-       case 10:
+       case 11:
                switch(iface->Type)
                {
                case 0:
@@ -497,13 +561,16 @@ int IPStack_Iface_IOCtl(tVFS_Node *Node, int ID, void *Data)
  * \fn int IPStack_AddInterface(char *Device)
  * \brief Adds an interface to the list
  */
-int IPStack_AddInterface(char *Device)
+int IPStack_AddInterface(const char *Device, const char *Name)
 {
        tInterface      *iface;
+       tAdapter        *card;
        
        ENTER("sDevice", Device);
        
-       iface = malloc(sizeof(tInterface));
+       card = IPStack_GetAdapter(Device);
+       
+       iface = malloc(sizeof(tInterface) + strlen(Name));
        if(!iface) {
                LEAVE('i', -2);
                return -2;      // Return ERR_MYBAD
@@ -514,7 +581,6 @@ int IPStack_AddInterface(char *Device)
        
        // Create Node
        iface->Node.ImplPtr = iface;
-       iface->Node.ImplInt = giIP_NextIfaceId++;
        iface->Node.Flags = VFS_FFLAG_DIRECTORY;
        iface->Node.Size = -1;
        iface->Node.NumACLs = 1;
@@ -522,6 +588,10 @@ int IPStack_AddInterface(char *Device)
        iface->Node.ReadDir = IPStack_Iface_ReadDir;
        iface->Node.FindDir = IPStack_Iface_FindDir;
        iface->Node.IOCtl = IPStack_Iface_IOCtl;
+       iface->Node.MkNod = NULL;
+       iface->Node.Link = NULL;
+       iface->Node.Relink = NULL;
+       iface->Node.Close = NULL;
        
        // Set Defaults
        iface->TimeoutDelay = DEFAULT_TIMEOUT;
@@ -534,8 +604,12 @@ int IPStack_AddInterface(char *Device)
                return -1;      // Return ERR_YOUFAIL
        }
        
+       // Delay setting ImplInt until after the adapter is opened
+       // Keeps things simple
+       iface->Node.ImplInt = giIP_NextIfaceId++;
+       
        // Append to list
-       LOCK( &glIP_Interfaces );
+       SHORTLOCK( &glIP_Interfaces );
        if( gIP_Interfaces ) {
                gIP_Interfaces_Last->Next = iface;
                gIP_Interfaces_Last = iface;
@@ -544,7 +618,7 @@ int IPStack_AddInterface(char *Device)
                gIP_Interfaces = iface;
                gIP_Interfaces_Last = iface;
        }
-       RELEASE( &glIP_Interfaces );
+       SHORTREL( &glIP_Interfaces );
        
        gIP_DriverInfo.RootNode.Size ++;
        
@@ -554,24 +628,24 @@ int IPStack_AddInterface(char *Device)
 }
 
 /**
- * \fn tAdapter *IPStack_GetAdapter(char *Path)
+ * \fn tAdapter *IPStack_GetAdapter(const char *Path)
  * \brief Gets/opens an adapter given the path
  */
-tAdapter *IPStack_GetAdapter(char *Path)
+tAdapter *IPStack_GetAdapter(const char *Path)
 {
        tAdapter        *dev;
         int    tmp;
        
        ENTER("sPath", Path);
        
-       LOCK( &glIP_Adapters );
+       Mutex_Acquire( &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 );
+                       Mutex_Release( &glIP_Adapters );
                        LEAVE('p', dev);
                        return dev;
                }
@@ -580,7 +654,7 @@ tAdapter *IPStack_GetAdapter(char *Path)
        // Ok, so let's open it
        dev = malloc( sizeof(tAdapter) + strlen(Path) + 1 );
        if(!dev) {
-               RELEASE( &glIP_Adapters );
+               Mutex_Release( &glIP_Adapters );
                LEAVE('n');
                return NULL;
        }
@@ -588,12 +662,13 @@ tAdapter *IPStack_GetAdapter(char *Path)
        // Fill Structure
        strcpy( dev->Device, Path );
        dev->NRef = 1;
+       dev->DeviceLen = strlen(Path);
        
        // Open Device
        dev->DeviceFD = VFS_Open( dev->Device, VFS_OPENFLAG_READ|VFS_OPENFLAG_WRITE );
        if( dev->DeviceFD == -1 ) {
                free( dev );
-               RELEASE( &glIP_Adapters );
+               Mutex_Release( &glIP_Adapters );
                LEAVE('n');
                return NULL;
        }
@@ -605,7 +680,7 @@ tAdapter *IPStack_GetAdapter(char *Path)
                Warning("IPStack_GetAdapter: '%s' is not a network interface", dev->Device);
                VFS_Close( dev->DeviceFD );
                free( dev );
-               RELEASE( &glIP_Adapters );
+               Mutex_Release( &glIP_Adapters );
                LEAVE('n');
                return NULL;
        }
@@ -617,7 +692,7 @@ tAdapter *IPStack_GetAdapter(char *Path)
        dev->Next = gIP_Adapters;
        gIP_Adapters = dev;
        
-       RELEASE( &glIP_Adapters );
+       Mutex_Release( &glIP_Adapters );
        
        // Start watcher
        Link_WatchDevice( dev );
@@ -625,3 +700,20 @@ tAdapter *IPStack_GetAdapter(char *Path)
        LEAVE('p', dev);
        return dev;
 }
+
+/**
+ * \brief Gets the size (in bytes) of a specified form of address
+ */
+int IPStack_GetAddressSize(int AddressType)
+{
+       switch(AddressType)
+       {
+       default:
+       case AF_NULL:
+               return 0;
+       case AF_INET4:
+               return sizeof(tIPv4);
+       case AF_INET6:
+               return sizeof(tIPv6);
+       }
+}

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