X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=KernelLand%2FModules%2FIPStack%2Flink.c;h=da5931292bb9da8dbe9fdab82b9b5d3770fd168b;hb=2a49f5a6be4fd478ae4249115ff2a3bf0e34d7e5;hp=37b72608cff98f9c54d3d33ae73cb1d3e75dc5e6;hpb=849329d50395b44ac97c5b5145fc2df0749eace2;p=tpg%2Facess2.git diff --git a/KernelLand/Modules/IPStack/link.c b/KernelLand/Modules/IPStack/link.c index 37b72608..da593129 100644 --- a/KernelLand/Modules/IPStack/link.c +++ b/KernelLand/Modules/IPStack/link.c @@ -1,18 +1,25 @@ /* - * Acess2 IP Stack - * - Link/Media Layer Interface + * Acess2 Networking Stack + * - By John Hodge (thePowersGang) + * + * link.c + * - Ethernet/802.3 Handling code + * TODO: Rename file */ #include "ipstack.h" #include "link.h" #include "include/buffer.h" +#include "include/adapters_int.h" // === CONSTANTS === +#define LINK_LOGPACKETS 0 +#define VALIDATE_CHECKSUM 0 #define MAX_PACKET_SIZE 2048 // === PROTOTYPES === void Link_RegisterType(Uint16 Type, tPacketCallback Callback); void Link_SendPacket(tAdapter *Adapter, Uint16 Type, tMacAddr To, tIPStackBuffer *Buffer); -void Link_WatchDevice(tAdapter *Adapter); + int Link_HandlePacket(tAdapter *Adapter, tIPStackBuffer *Buffer); // --- CRC --- void Link_InitCRC(void); Uint32 Link_CalculateCRC(tIPStackBuffer *Buffer); @@ -77,128 +84,106 @@ void Link_RegisterType(Uint16 Type, tPacketCallback Callback) 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; - hdr->Src = Adapter->MacAddr; + 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) ); - - size_t outlen = 0; - void *data = IPStack_Buffer_CompactBuffer(Buffer, &outlen); - VFS_Write(Adapter->DeviceFD, outlen, data); - free(data); + memset(hdr+1, 0, ofs+4); // zero padding and checksum + + //if( (Adapter->Type->Flags & ADAPTERFLAG_OFFLOAD_MAC) ) + IPStack_Buffer_AppendSubBuffer(Buffer, sizeof(tEthernetHeader), ofs, hdr, NULL, NULL); + //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)); + //} + + Log_Log("Net Link", " from %02x:%02x:%02x:%02x:%02x:%02x", + hdr->Src.B[0], hdr->Src.B[1], hdr->Src.B[2], + hdr->Src.B[3], hdr->Src.B[4], hdr->Src.B[5] + ); + + Adapter_SendPacket(Adapter, Buffer); } -void Link_WorkerThread(void *Ptr) +int Link_HandlePacket(tAdapter *Adapter, tIPStackBuffer *Buffer) { - tAdapter *Adapter = Ptr; + size_t len = 0; + void *data = IPStack_Buffer_CompactBuffer(Buffer, &len); - Threads_SetName(Adapter->Device); - Log_Log("Net Link", "Thread %i watching '%s'", Threads_GetTID(), Adapter->Device); + tEthernetHeader *hdr = (void*)data; - // Child Thread - while(Adapter->DeviceFD != -1) - { - Uint8 buf[MAX_PACKET_SIZE]; - tEthernetHeader *hdr = (void*)buf; - int ret, i; - Uint32 checksum; - - // Wait for a packet (Read on a network device is blocking) - //Log_Debug("NET", "Waiting on adapter FD#0x%x", Adapter->DeviceFD); - ret = VFS_Read(Adapter->DeviceFD, MAX_PACKET_SIZE, buf); - if(ret == -1) break; - - if(ret < sizeof(tEthernetHeader)) { - Log_Log("Net Link", "Recieved an undersized packet (%i < %i)", - ret, sizeof(tEthernetHeader)); - continue; - } - - Log_Log("Net Link", - "Packet from %02x:%02x:%02x:%02x:%02x:%02x" - " to %02x:%02x:%02x:%02x:%02x:%02x (Type=%04x)", - 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) - ); - checksum = *(Uint32*)&hdr->Data[ret-sizeof(tEthernetHeader)-4]; - //Log_Log("NET", "Checksum 0x%08x", checksum); - // TODO: Check checksum - - // Check if there is a registered callback for this packet type - for( i = giRegisteredTypes; i--; ) - { - if(gaRegisteredTypes[i].Type == ntohs(hdr->Type)) break; - } - // No? Ignore it - if( i == -1 ) { - Log_Log("Net Link", "Unregistered type 0x%x", ntohs(hdr->Type)); - continue; - } - - // Call the callback - gaRegisteredTypes[i].Callback( - Adapter, - hdr->Src, - ret - sizeof(tEthernetHeader), - hdr->Data - ); + if(len < sizeof(tEthernetHeader)) { + Log_Log("Net Link", "Recieved an undersized packet (%i < %i)", + len, sizeof(tEthernetHeader)); + free(data); + return 1; } - Log_Log("Net Link", "Watcher terminated (file closed)"); + #if LINK_LOGPACKETS + Log_Log("Net Link", + "Packet from %02x:%02x:%02x:%02x:%02x:%02x" + " to %02x:%02x:%02x:%02x:%02x:%02x (Type=%04x)", + 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) + ); + #endif - Threads_Exit(0, 0); -} - -/** - * \fn void Link_WatchDevice(tAdapter *Adapter) - * \brief Spawns a worker thread to watch the specified adapter - */ -void Link_WatchDevice(tAdapter *Adapter) -{ - int tid; - - if( !gbLink_CRCTableGenerated ) - Link_InitCRC(); + #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 - tid = Proc_SpawnWorker(Link_WorkerThread, Adapter); // Create a new worker thread - - if(tid < 0) { - Log_Warning("Net Link", "Unable to create watcher thread for '%s'", Adapter->Device); - return ; + // Check if there is a registered callback for this packet type + int i; + for( i = giRegisteredTypes; i--; ) + { + if(gaRegisteredTypes[i].Type == ntohs(hdr->Type)) break; + } + // 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", "Watching '%s' using tid %i", Adapter->Device, tid); + // Call the callback + gaRegisteredTypes[i].Callback( + Adapter, + hdr->Src, + len - sizeof(tEthernetHeader), + hdr->Data + ); + + free(data); + + return 0; } // 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;