Merge branch 'master' of git://git.ucc.asn.au/tpg/acess2
[tpg/acess2.git] / KernelLand / Modules / IPStack / link.c
index c4f716f..45311d0 100644 (file)
 #include "include/adapters_int.h"
 
 // === CONSTANTS ===
+#define LINK_LOGPACKETS        0
+#define VALIDATE_CHECKSUM      0
 #define        MAX_PACKET_SIZE 2048
 
+// === TYPES ===
+typedef struct {
+       Uint16  Type;
+       tPacketCallback Callback;
+} tLink_PktType;
+
+
 // === PROTOTYPES ===
 void   Link_RegisterType(Uint16 Type, tPacketCallback Callback);
 void   Link_SendPacket(tAdapter *Adapter, Uint16 Type, tMacAddr To, tIPStackBuffer *Buffer);
@@ -26,10 +35,7 @@ Uint32       Link_CalculatePartialCRC(Uint32 CRC, const void *Data, int Length);
 // === GLOBALS ===
  int   giRegisteredTypes = 0;
  int   giRegisteredTypeSpace = 0;
-struct {
-       Uint16  Type;
-       tPacketCallback Callback;
-}      *gaRegisteredTypes;
+tLink_PktType  *gaRegisteredTypes;
  int   gbLink_CRCTableGenerated = 0;
 Uint32 gaiLink_CRCTable[256];
 
@@ -42,69 +48,82 @@ Uint32      gaiLink_CRCTable[256];
  */
 void Link_RegisterType(Uint16 Type, tPacketCallback Callback)
 {
-        int    i;
-       void    *tmp;
+       tLink_PktType *typeslot = NULL;
        
-       for( i = giRegisteredTypes; i -- ; )
+       for( int i = 0; i < giRegisteredTypes; i ++)
        {
                if(gaRegisteredTypes[i].Type == Type) {
                        Log_Warning("Net Link", "Attempt to register 0x%x twice", Type);
                        return ;
                }
                // Ooh! Free slot!
-               if(gaRegisteredTypes[i].Callback == NULL)       break;
+               if(gaRegisteredTypes[i].Callback == NULL)
+               {
+                       typeslot = &gaRegisteredTypes[i];
+                       break;
+               }
        }
        
-       if(i == -1)
+       if(typeslot == NULL)
        {
-               giRegisteredTypeSpace += 5;
-               tmp = realloc(gaRegisteredTypes, giRegisteredTypeSpace*sizeof(*gaRegisteredTypes));
-               if(!tmp) {
-                       Log_Warning("Net Link",
-                               "Out of heap space! (Attempted to allocate %i)",
-                               giRegisteredTypeSpace*sizeof(*gaRegisteredTypes)
-                               );
-                       return ;
+               if( giRegisteredTypes == giRegisteredTypeSpace )
+               {
+                       giRegisteredTypeSpace += 5;
+                       void *tmp = realloc(gaRegisteredTypes, giRegisteredTypeSpace*sizeof(tLink_PktType));
+                       if(!tmp) {
+                               Log_Warning("Net Link",
+                                       "Out of heap space! (Attempted to allocate %i)",
+                                       giRegisteredTypeSpace*sizeof(tLink_PktType)
+                                       );
+                               return ;
+                       }
+                       gaRegisteredTypes = tmp;
                }
-               gaRegisteredTypes = tmp;
-               i = giRegisteredTypes;
-               giRegisteredTypes ++;
+               typeslot = &gaRegisteredTypes[giRegisteredTypes++];
        }
        
-       gaRegisteredTypes[i].Callback = Callback;
-       gaRegisteredTypes[i].Type = Type;
+       typeslot->Callback = Callback;
+       typeslot->Type = Type;
 }
 
 /**
- * \fn void Link_SendPacket(tAdapter *Adapter, Uint16 Type, tMacAddr To, int Length, void *Buffer)
  * \brief Formats and sends a packet on the specified interface
  */
 void Link_SendPacket(tAdapter *Adapter, Uint16 Type, tMacAddr To, tIPStackBuffer *Buffer)
 {
         int    length = IPStack_Buffer_GetLength(Buffer);
-        int    ofs = 4 - (length & 3);
+        int    ofs = (4 - (length & 3)) & 3;
        Uint8   buf[sizeof(tEthernetHeader) + ofs + 4];
+       //Uint32        *checksum = (void*)(buf + sizeof(tEthernetHeader) + ofs);
        tEthernetHeader *hdr = (void*)buf;
 
-       if( ofs == 4 )  ofs = 0;        
-
-       Log_Log("Net Link", "Sending %i bytes to %02x:%02x:%02x:%02x:%02x:%02x (Type 0x%x)",
-               length, To.B[0], To.B[1], To.B[2], To.B[3], To.B[4], To.B[5], Type);
-
        hdr->Dest = To;
        memcpy(&hdr->Src, Adapter->HWAddr, 6);  // TODO: Remove hard coded 6
        hdr->Type = htons(Type);
-       *(Uint32*)(buf + sizeof(tEthernetHeader) + ofs) = 0;
-
-       IPStack_Buffer_AppendSubBuffer(Buffer, sizeof(tEthernetHeader), ofs + 4, hdr, NULL, NULL);
-       
-       *(Uint32*)(buf + sizeof(tEthernetHeader) + ofs) = htonl( Link_CalculateCRC(Buffer) );
+       memset(hdr+1, 0, ofs+4);        // zero padding and checksum
 
-       Log_Log("Net Link", " from %02x:%02x:%02x:%02x:%02x:%02x",
+       Log_Log("Net Link", "Sending %i bytes (Type 0x%x)"
+               " to %02x:%02x:%02x:%02x:%02x:%02x"
+               " from %02x:%02x:%02x:%02x:%02x:%02x",
+               length, Type,
+               To.B[0], To.B[1], To.B[2], To.B[3], To.B[4], To.B[5],
                hdr->Src.B[0], hdr->Src.B[1], hdr->Src.B[2],
                hdr->Src.B[3], hdr->Src.B[4], hdr->Src.B[5]
                );
 
+       #if 0
+       if( (Adapter->Type->Flags & ADAPTERFLAG_OFFLOAD_MAC) )
+       #endif
+               IPStack_Buffer_AppendSubBuffer(Buffer, sizeof(tEthernetHeader), ofs, hdr, NULL, NULL);
+       #if 0
+       else
+       {
+               IPStack_Buffer_AppendSubBuffer(Buffer, sizeof(tEthernetHeader), ofs + 4, hdr, NULL, NULL);
+               *checksum = htonl( Link_CalculateCRC(Buffer) );
+               Log_Debug("Net Link", "Non-Offloaded: 0x%x, 0x%x", *checksum, ntohl(*checksum));
+       }
+       #endif
+
        Adapter_SendPacket(Adapter, Buffer);
 }
 
@@ -121,60 +140,61 @@ int Link_HandlePacket(tAdapter *Adapter, tIPStackBuffer *Buffer)
                free(data);
                return 1;
        }
-               
+       
+       #if LINK_LOGPACKETS
        Log_Log("Net Link",
-               "Packet from %02x:%02x:%02x:%02x:%02x:%02x"
+               "eth%i Packet from %02x:%02x:%02x:%02x:%02x:%02x"
                " to %02x:%02x:%02x:%02x:%02x:%02x (Type=%04x)",
+               Adapter->Index,
                hdr->Src.B[0], hdr->Src.B[1], hdr->Src.B[2],
                hdr->Src.B[3], hdr->Src.B[4], hdr->Src.B[5],
                hdr->Dest.B[0], hdr->Dest.B[1], hdr->Dest.B[2],
                hdr->Dest.B[3], hdr->Dest.B[4], hdr->Dest.B[5],
                ntohs(hdr->Type)
                );
-//     Uint32 checksum = *(Uint32*)(data + len + 4);
-       //Log_Log("NET", "Checksum 0x%08x", checksum);
+       #endif
+       
+       #if VALIDATE_CHECKSUM
+       Uint32 checksum = *(Uint32*)(data + len + 4);
+       Log_Log("NET Link", "Checksum 0x%08x", checksum);
+       Uint32  calculated = Link_CalculateCRC(Buffer);
        // TODO: Check checksum
+       #endif
        
+       Uint16  type = ntohs(hdr->Type);
        // Check if there is a registered callback for this packet type
-        int    i;
-       for( i = giRegisteredTypes; i--; )
+       for( int i = giRegisteredTypes; i--; )
        {
-               if(gaRegisteredTypes[i].Type == ntohs(hdr->Type))       break;
+               if(gaRegisteredTypes[i].Type == type)
+               {
+                       // Call the callback
+                       gaRegisteredTypes[i].Callback(
+                               Adapter,
+                               hdr->Src,
+                               len - sizeof(tEthernetHeader),
+                               hdr->Data
+                               );
+                       free(data);
+                       return 0;
+               }
        }
        // No? Ignore it
-       if( i == -1 ) {
-               Log_Log("Net Link", "Unregistered type 0x%x", ntohs(hdr->Type));
-               
-               free(data);     
-               return 1;
-       }
+       Log_Log("Net Link", "eth%i Unregistered type 0x%04x", Adapter->Index, type);
        
-       // Call the callback
-       gaRegisteredTypes[i].Callback(
-               Adapter,
-               hdr->Src,
-               len - sizeof(tEthernetHeader),
-               hdr->Data
-               );
-       
-       free(data);
-       
-       return 0;
+       free(data);     
+       return 1;
 }
 
 // From http://www.cl.cam.ac.uk/research/srg/bluebook/21/crc/node6.html
 #define        QUOTIENT        0x04c11db7
 void Link_InitCRC(void)
 {
-        int    i, j;
-       Uint32  crc;
-
-       for (i = 0; i < 256; i++)
+       for( int i = 0; i < 256; i++ )
        {
-               crc = i << 24;
-               for (j = 0; j < 8; j++)
+               Uint32 crc = i << 24;
+               for( int j = 0; j < 8; j++ )
                {
-                       if (crc & 0x80000000)
+                       if( crc >> 31 )
                                crc = (crc << 1) ^ QUOTIENT;
                        else
                                crc = crc << 1;

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