Reworked the IPStack tInterface structure
authorJohn Hodge <[email protected]>
Sun, 14 Nov 2010 10:27:23 +0000 (18:27 +0800)
committerJohn Hodge <[email protected]>
Sun, 14 Nov 2010 10:27:23 +0000 (18:27 +0800)
- Now no longer explicitly mentions IPv4/IPv6
- Also allowed the cleaning up of a nice chunk of the interface code

Modules/IPStack/arp.c
Modules/IPStack/interface.c
Modules/IPStack/ipstack.h
Modules/IPStack/ipv4.c
Modules/IPStack/ipv6.c
Modules/IPStack/main.c
Modules/IPStack/routing.c
Modules/IPStack/tcp.c

index d84b918..fda1b2f 100644 (file)
@@ -75,6 +75,9 @@ tMacAddr ARP_Resolve4(tInterface *Interface, tIPv4 Address)
        
        ENTER("pInterface xAddress", Interface, Address);
        
+       // Check routing tables
+       // Replace address with gateway if needed
+       
        Mutex_Acquire( &glARP_Cache4 );
        for( i = 0; i < giARP_Cache4Space; i++ )
        {
@@ -106,7 +109,7 @@ tMacAddr ARP_Resolve4(tInterface *Interface, tIPv4 Address)
        req.SWSize = 4;
        req.Request = htons(1);
        req.SourceMac = Interface->Adapter->MacAddr;
-       req.SourceIP = Interface->IP4.Address;
+       req.SourceIP = *(tIPv4*)Interface->Address;
        req.DestMac = cMAC_BROADCAST;
        req.DestIP = Address;
        
@@ -276,7 +279,7 @@ void ARP_int_GetPacket(tAdapter *Adapter, tMacAddr From, int Length, void *Buffe
                                
                                req4->DestIP = req4->SourceIP;
                                req4->DestMac = req4->SourceMac;
-                               req4->SourceIP = iface->IP4.Address;
+                               req4->SourceIP = *(tIPv4*)iface->Address;;
                                req4->SourceMac = Adapter->MacAddr;
                                req4->Request = htons(2);
                                Log_Debug("ARP", "Sending back us (%02x:%02x:%02x:%02x:%02x:%02x)",
@@ -301,7 +304,7 @@ void ARP_int_GetPacket(tAdapter *Adapter, tMacAddr From, int Length, void *Buffe
                        {
                                req6->DestIP = req6->SourceIP;
                                req6->DestMac = req6->SourceMac;
-                               req6->SourceIP = iface->IP6.Address;
+                               req6->SourceIP = *(tIPv6*)iface->Address;
                                req6->SourceMac = Adapter->MacAddr;
                                req6->Request = htons(2);
                                Log_Debug("ARP", "Sending back us (%02x:%02x:%02x:%02x:%02x:%02x)",
index 9b11e5f..445e589 100644 (file)
@@ -230,12 +230,23 @@ int IPStack_AddInterface(const char *Device, const char *Name)
 {
        tInterface      *iface;
        tAdapter        *card;
+        int    nameLen;
        
        ENTER("sDevice", Device);
        
        card = IPStack_GetAdapter(Device);
+       if( !card ) {
+               LEAVE('i', -1);
+               return -1;      // ERR_YOURBAD
+       }
+       
+       nameLen = sprintf(NULL, "%i", giIP_NextIfaceId);
        
-       iface = malloc(sizeof(tInterface) + sprintf(NULL, "%i", giIP_NextIfaceId) + 1);
+       iface = malloc(
+               sizeof(tInterface)
+               + nameLen + 1
+               + IPStack_GetAddressSize(-1)
+               );
        if(!iface) {
                LEAVE('i', -2);
                return -2;      // Return ERR_MYBAD
@@ -243,6 +254,7 @@ int IPStack_AddInterface(const char *Device, const char *Name)
        
        iface->Next = NULL;
        iface->Type = 0;        // Unset type
+       iface->Address = iface->Name + nameLen + 1;     // Address
        
        // Create Node
        iface->Node.ImplPtr = iface;
@@ -348,7 +360,6 @@ static const char *casIOCtls_Iface[] = {
        "getset_type",
        "get_address", "set_address",
        "getset_subnet",
-       "get_gateway", "set_gateway",
        "get_device",
        "ping",
        NULL
@@ -358,7 +369,7 @@ static const char *casIOCtls_Iface[] = {
  */
 int IPStack_Iface_IOCtl(tVFS_Node *Node, int ID, void *Data)
 {
-        int    tmp;
+        int    tmp, size;
        tInterface      *iface = (tInterface*)Node->ImplPtr;
        ENTER("pNode iID pData", Node, ID, Data);
        
@@ -402,24 +413,19 @@ int IPStack_Iface_IOCtl(tVFS_Node *Node, int ID, void *Data)
                                LEAVE('i', -1);
                                return -1;
                        }
-                       switch( *(int*)Data )
-                       {
-                       case 0: // Disable
+                       
+                       // Set type
+                       iface->Type = *(int*)Data;
+                       size = IPStack_GetAddressSize(iface->Type);
+                       // Check it's actually valid
+                       if( iface->Type != 0 && size == 0 ) {
                                iface->Type = 0;
-                               memset(&iface->IP6, 0, sizeof(tIPv6));  // Clear address
-                               break;
-                       case 4: // IPv4
-                               iface->Type = 4;
-                               memset(&iface->IP4, 0, sizeof(tIPv4));
-                               break;
-                       case 6: // IPv6
-                               iface->Type = 6;
-                               memset(&iface->IP6, 0, sizeof(tIPv6));
-                               break;
-                       default:
                                LEAVE('i', -1);
                                return -1;
                        }
+                       
+                       // Clear address
+                       memset(iface->Address, 0, size);
                }
                LEAVE('i', iface->Type);
                return iface->Type;
@@ -429,129 +435,56 @@ int IPStack_Iface_IOCtl(tVFS_Node *Node, int ID, void *Data)
         * - Get the interface's address
         */
        case 5:
-               switch(iface->Type)
-               {
-               case 0: LEAVE_RET('i', 1);
-               case 4:
-                       if( !CheckMem( Data, sizeof(tIPv4) ) )  LEAVE_RET('i', -1);
-                       memcpy( Data, &iface->IP4.Address, sizeof(tIPv4) );
-                       LEAVE_RET('i', 1);
-               case 6:
-                       if( !CheckMem( Data, sizeof(tIPv6) ) )  LEAVE_RET('i', -1);
-                       memcpy( Data, &iface->IP6.Address, sizeof(tIPv6) );
-                       LEAVE_RET('i', 1);
-               }
-               LEAVE_RET('i', 0);
+               size = IPStack_GetAddressSize(iface->Type);
+               if( !CheckMem( Data, size ) )   LEAVE_RET('i', -1);
+               memcpy( Data, iface->Address, size );
+               LEAVE('i', 1);
+               return 1;
        
        /*
         * set_address
-        * - Get the interface's address
+        * - Set the interface's address
         */
        case 6:
                if( Threads_GetUID() != 0 )     LEAVE_RET('i', -1);
-               switch(iface->Type)
-               {
-               case 0: LEAVE_RET('i', 1);
-               case 4:
-                       if( !CheckMem( Data, sizeof(tIPv4) ) )  LEAVE_RET('i', -1);
-                       iface->Type = 0;        // One very hacky mutex/trash protector
-                       memcpy( &iface->IP4.Address, Data, sizeof(tIPv4) );
-                       iface->Type = 4;
-                       LEAVE_RET('i', 1);
-               case 6:
-                       if( !CheckMem( Data, sizeof(tIPv6) ) )  LEAVE_RET('i', -1);
-                       iface->Type = 0;
-                       memcpy( &iface->IP6.Address, Data, sizeof(tIPv6) );
-                       iface->Type = 6;
-                       LEAVE_RET('i', 1);
-               }
-               LEAVE_RET('i', 0);
+               
+               size = IPStack_GetAddressSize(iface->Type);
+               if( !CheckMem( Data, size ) )   LEAVE_RET('i', -1);
+               // TODO: Protect against trashing
+               memcpy( iface->Address, Data, size );
+               LEAVE('i', 1);
+               return 1;
        
        /*
         * getset_subnet
         * - Get/Set the bits in the address subnet
         */
        case 7:
-               // Get?
-               if( Data == NULL )
-               {
-                       switch( iface->Type )
-                       {
-                       case 4:         LEAVE_RET('i', iface->IP4.SubnetBits);
-                       case 6:         LEAVE_RET('i', iface->IP6.SubnetBits);
-                       default:        LEAVE_RET('i', 0);
-                       }
-               }
-               
-               // Ok, set.
-               if( Threads_GetUID() != 0 )     LEAVE_RET('i', -1);
-               if( !CheckMem(Data, sizeof(int)) )      LEAVE_RET('i', -1);
-               
-               // Check and set the subnet bits
-               switch( iface->Type )
-               {
-               case 4:
-                       if( *(int*)Data < 0 || *(int*)Data > 31 )       LEAVE_RET('i', -1);
-                       iface->IP4.SubnetBits = *(int*)Data;
-                       LEAVE_RET('i', iface->IP4.SubnetBits);
-               case 6:
-                       if( *(int*)Data < 0 || *(int*)Data > 127 )      LEAVE_RET('i', -1);
-                       iface->IP6.SubnetBits = *(int*)Data;
-                       LEAVE_RET('i', iface->IP6.SubnetBits);
-               default:
-                       break;
-               }
-               
-               LEAVE('i', 0);
-               return 0;
-               
-       /*
-        * get_gateway
-        * - Get the interface's IPv4 gateway
-        */
-       case 8:
-               switch(iface->Type)
-               {
-               case 0:
-                       LEAVE_RET('i', 1);
-               case 4:
-                       if( !CheckMem( Data, sizeof(tIPv4) ) )  LEAVE_RET('i', -1);
-                       memcpy( Data, &iface->IP4.Gateway, sizeof(tIPv4) );
-                       LEAVE_RET('i', 1);
-               case 6:
-                       LEAVE_RET('i', 1);
-               }
-               LEAVE('i', 0);
-               return 0;
-       
-       /*
-        * set_gateway
-        * - Get/Set the interface's IPv4 gateway
-        */
-       case 9:
-               if( Threads_GetUID() != 0 )     LEAVE_RET('i', -1);
-               switch(iface->Type)
+               // Do we want to set the value?
+               if( Data )
                {
-               case 0:
-                       LEAVE_RET('i', 1);
-               
-               case 4:
-                       if( !CheckMem( Data, sizeof(tIPv4) ) )  LEAVE_RET('i', -1);
-                       iface->Type = 0;        // One very hacky mutex/trash protector
-                       memcpy( &iface->IP4.Gateway, Data, sizeof(tIPv4) );
-                       iface->Type = 4;
-                       LEAVE_RET('i', 1);
+                       // Are we root? (TODO: Check Owner/Group)
+                       if( Threads_GetUID() != 0 )     LEAVE_RET('i', -1);
+                       // Is the memory valid
+                       if( !CheckMem(Data, sizeof(int)) )      LEAVE_RET('i', -1);
                        
-               case 6:
-                       LEAVE_RET('i', 1);
+                       // Is the mask sane?
+                       if( *(int*)Data < 0 || *(int*)Data > IPStack_GetAddressSize(iface->Type)*8-1 )
+                               LEAVE_RET('i', -1);
+                       
+                       // Ok, set it
+                       iface->SubnetBits = *(int*)Data;
                }
-               break;
+               LEAVE('i', iface->SubnetBits);
+               return iface->SubnetBits;
        
        /*
         * get_device
         * - Gets the name of the attached device
         */
-       case 10:
+       case 8:
+               if( iface->Adapter == NULL )
+                       LEAVE_RET('i', 0);
                if( Data == NULL )
                        LEAVE_RET('i', iface->Adapter->DeviceLen);
                if( !CheckMem( Data, iface->Adapter->DeviceLen+1 ) )
@@ -563,7 +496,7 @@ int IPStack_Iface_IOCtl(tVFS_Node *Node, int ID, void *Data)
         * ping
         * - Send an ICMP Echo
         */
-       case 11:
+       case 9:
                switch(iface->Type)
                {
                case 0:
index 885e048..db93328 100644 (file)
@@ -39,41 +39,48 @@ struct sMacAddr {
 } __attribute__((packed));
 
 struct sInterface {
-       struct sInterface       *Next;
-       tVFS_Node       Node;
-       tAdapter        *Adapter;
-        int    TimeoutDelay;   // Time in miliseconds before a packet times out
-        int    Type;   // 0 for disabled, 4 for IPv4 and 6 for IPv6
+       struct sInterface       *Next;  //!< Next interface in list
        
-       //TODO: Remove explicit mentions of IPv4/IPv6 and make more general
-       union {
-               struct  {
-                       tIPv6   Address;
-                        int    SubnetBits;     //Should this be outside the union?
-               }       IP6;
-               
-               struct {
-                       tIPv4   Address;
-                       tIPv4   Gateway;
-                        int    SubnetBits;
-               }       IP4;
-       };
+       tVFS_Node       Node;   //!< Node to use the interface
+       
+       tAdapter        *Adapter;       //!< Adapter the interface is associated with
+        int    TimeoutDelay;   //!< Time in miliseconds before a packet times out
+        int    Type;   //!< Interface type, see ::eInterfaceTypes
+       
+       void    *Address;       //!< IP address (stored after the Name)
+        int    SubnetBits;     //!< Number of bits that denote the address network
        
        char    Name[];
 };
 
+/**
+ * \brief Route definition structure
+ */
+typedef struct sRoute {
+       struct sRoute   *Next;
+       
+       tVFS_Node       Node;   //!< Node for route manipulation
+       
+       tInterface      *Interface;     //!< Interface for this route
+        int    AddressType;    //!< 0: Invalid, 4: IPv4, 6: IPv4
+       void    *Network;       //!< Network - Pointer to tIPv4/tIPv6/... at end of structure
+        int    SubnetBits;     //!< Number of bits in \a Network that are valid
+       void    *NextHop;       //!< Next Hop address - Pointer to tIPv4/tIPv6/... at end of structure
+        int    Metric; //!< Route priority
+}      tRoute;
+
 /**
  * \brief Represents a network adapter
  */
 struct sAdapter {
        struct sAdapter *Next;
        
-        int    DeviceFD;
-        int    NRef;
+        int    DeviceFD;       //!< File descriptor of the device
+        int    NRef;   //!< Number of times it's been referenced
        
-       tMacAddr        MacAddr;
-        int    DeviceLen;
-       char    Device[];
+       tMacAddr        MacAddr;        //!< Physical address of the adapter
+        int    DeviceLen;      //!< Device name length
+       char    Device[];       //!< Device name
 };
 
 /**
index e2f18f8..e37085b 100644 (file)
@@ -71,7 +71,7 @@ int IPv4_SendPacket(tInterface *Iface, tIPv4 Address, int Protocol, int ID, int
        
        // OUTPUT Firewall rule go here
        ret = IPTablesV4_TestChain("OUTPUT",
-               &Iface->IP4.Address, &Address,
+               (tIPv4*)Iface->Address, &Address,
                Protocol, 0,
                Length, Data);
        if(ret != 0) {
@@ -95,7 +95,7 @@ int IPv4_SendPacket(tInterface *Iface, tIPv4 Address, int Protocol, int ID, int
        hdr->TTL = DEFAULT_TTL;
        hdr->Protocol = Protocol;
        hdr->HeaderChecksum = 0;        // Will be set later
-       hdr->Source = Iface->IP4.Address;
+       hdr->Source = *(tIPv4*)Iface->Address;
        hdr->Destination = Address;
        hdr->HeaderChecksum = IPv4_Checksum(hdr, sizeof(tIPv4Header));
        
@@ -236,15 +236,15 @@ tInterface *IPv4_GetInterface(tAdapter *Adapter, tIPv4 Address, int Broadcast)
        {
                if( iface->Adapter != Adapter ) continue;
                if( iface->Type != 4 )  continue;
-               if( IP4_EQU(Address, iface->IP4.Address) )
+               if( IP4_EQU(Address, *(tIPv4*)iface->Address) )
                        return iface;
                
                if( !Broadcast )        continue;
                
-               this = ntohl( iface->IP4.Address.L );
+               this = ntohl( ((tIPv4*)iface->Address)->L );
                
                // Check for broadcast
-               netmask = IPv4_Netmask(iface->IP4.SubnetBits);
+               netmask = IPv4_Netmask(iface->SubnetBits);
                
                if( (addr & netmask) == (this & netmask)
                 && (addr & ~netmask) == (0xFFFFFFFF & ~netmask) )
index aac33de..561297d 100644 (file)
@@ -75,32 +75,34 @@ tInterface *IPv6_GetInterface(tAdapter *Adapter, tIPv6 Address, int Broadcast)
        
        for( iface = gIP_Interfaces; iface; iface = iface->Next)
        {
+               tIPv6   *thisAddr;
                // Check for this adapter
                if( iface->Adapter != Adapter ) continue;
                
                // Skip non-IPv6 Interfaces
                if( iface->Type != 6 )  continue;
                
+               thisAddr = (tIPv6*)iface->Address;
                // If the address is a perfect match, return this interface
-               if( IP6_EQU(Address, iface->IP6.Address) )      return iface;
+               if( IP6_EQU(Address, *thisAddr) )       return iface;
                
                // Check if we want to match broadcast addresses
                if( !Broadcast )        continue;
                
                // Check for broadcast
-               if( iface->IP6.SubnetBits > 32 && Address.L[0] != iface->IP6.Address.L[0] )
+               if( iface->SubnetBits > 32 && Address.L[0] != thisAddr->L[0] )
                        continue;
-               if( iface->IP6.SubnetBits > 64 && Address.L[1] != iface->IP6.Address.L[1] )
+               if( iface->SubnetBits > 64 && Address.L[1] != thisAddr->L[1] )
                        continue;
-               if( iface->IP6.SubnetBits > 96 && Address.L[2] != iface->IP6.Address.L[2] )
+               if( iface->SubnetBits > 96 && Address.L[2] != thisAddr->L[2] )
                        continue;
                
-               j = iface->IP6.SubnetBits / 32;
-               i = iface->IP6.SubnetBits % 32;
-               netmask = IPv4_Netmask( iface->IP6.SubnetBits % 32 );
+               j = iface->SubnetBits / 32;
+               i = iface->SubnetBits % 32;
+               netmask = IPv4_Netmask( iface->SubnetBits % 32 );
                
                // Check the last bit of the netmask
-               if( (Address.L[j] >> i) != (iface->IP6.Address.L[j] >> i) )     continue;
+               if( (Address.L[j] >> i) != (thisAddr->L[j] >> i) )      continue;
                
                // Check that the host portion is one
                if( (Address.L[j] & ~netmask) != (0xFFFFFFFF & ~netmask) )      continue;
index 577cd38..585f8c3 100644 (file)
@@ -88,13 +88,19 @@ int IPStack_GetAddressSize(int AddressType)
 {
        switch(AddressType)
        {
-       default:
+       case -1:        // -1 = maximum
+               return sizeof(tIPv6);
+       
        case AF_NULL:
                return 0;
+       
        case AF_INET4:
                return sizeof(tIPv4);
        case AF_INET6:
                return sizeof(tIPv6);
+               
+       default:
+               return 0;
        }
 }
 
index 643de1e..51eb6db 100644 (file)
 // === IMPORTS ===
 tVFS_Node      *IPStack_Root_FindDir(tVFS_Node *Node, const char *Filename);
 
-// === TYPES ===
-typedef struct sRoute {
-       struct sRoute   *Next;
-       
-       tVFS_Node       Node;
-       
-       tInterface      *Interface;     // Interface for this route
-        int    AddressType;    // 0: Invalid, 4: IPv4, 6: IPv4
-       void    *Network;       // Network - Pointer to tIPv4/tIPv6/... at end of structure
-        int    SubnetBits;     // Number of bits in \a Network that are valid
-       void    *NextHop;       // Next Hop address - Pointer to tIPv4/tIPv6/... at end of structure
-        int    Metric; // Route priority
-}      tRoute;
-
 // === PROTOTYPES ===
 // - Routes directory
 char   *IPStack_RouteDir_ReadDir(tVFS_Node *Node, int Pos);
index 99e6719..3741503 100644 (file)
@@ -79,7 +79,7 @@ void TCP_SendPacket( tTCPConnection *Conn, size_t Length, tTCPHeader *Data )
        case 4: // Append IPv4 Pseudo Header
                buflen = 4 + 4 + 4 + ((Length+1)&~1);
                buf = malloc( buflen );
-               buf[0] = Conn->Interface->IP4.Address.L;
+               buf[0] = ((tIPv4*)Conn->Interface->Address)->L;
                buf[1] = Conn->RemoteIP.v4.L;
                buf[2] = (htons(Length)<<16) | (6<<8) | 0;
                Data->Checksum = 0;

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