From 6bc21db109c4d8d3219ad58fc5cc76ec76e6c6b7 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Wed, 3 Feb 2010 10:10:45 +0800 Subject: [PATCH] More work on the IP Stack, now responds to pings - Also fixed bug in NE2000 driver that resent the first packet on each subsequent send. --- Kernel/Makefile.BuildNum | 2 +- Modules/IPStack/arp.c | 165 +++++++++++++++++++++++--------- Modules/IPStack/icmp.c | 18 +++- Modules/IPStack/icmp.h | 2 +- Modules/IPStack/ipv4.c | 12 ++- Modules/IPStack/link.c | 1 - Modules/Network/NE2000/ne2000.c | 13 ++- 7 files changed, 154 insertions(+), 59 deletions(-) diff --git a/Kernel/Makefile.BuildNum b/Kernel/Makefile.BuildNum index d38d7b9c..62bf9325 100644 --- a/Kernel/Makefile.BuildNum +++ b/Kernel/Makefile.BuildNum @@ -1 +1 @@ -BUILD_NUM = 1408 +BUILD_NUM = 1422 diff --git a/Modules/IPStack/arp.c b/Modules/IPStack/arp.c index 0ba0fd35..3f919399 100644 --- a/Modules/IPStack/arp.c +++ b/Modules/IPStack/arp.c @@ -2,6 +2,7 @@ * Acess2 IP Stack * - Address Resolution Protocol */ +#define DEBUG 0 #include "ipstack.h" #include "arp.h" #include "link.h" @@ -19,16 +20,23 @@ extern tInterface *IPv6_GetInterface(tAdapter *Adapter, tIPv6 Address, int Broad void ARP_int_GetPacket(tAdapter *Adapter, tMacAddr From, int Length, void *Buffer); // === GLOBALS === -struct sARP_Cache { +struct sARP_Cache4 { + tIPv4 IP; tMacAddr MAC; - tIPv4 IP4; - tIPv6 IP6; Sint64 LastUpdate; Sint64 LastUsed; -} *gaARP_Cache; - int giARP_CacheSpace; +} *gaARP_Cache4; + int giARP_Cache4Space; +tSpinlock glARP_Cache4; +struct sARP_Cache6 { + tIPv6 IP; + tMacAddr MAC; + Sint64 LastUpdate; + Sint64 LastUsed; +} *gaARP_Cache6; + int giARP_Cache6Space; +tSpinlock glARP_Cache6; int giARP_LastUpdateID = 0; -tSpinlock glARP_Cache; // === CODE === /** @@ -37,9 +45,13 @@ tSpinlock glARP_Cache; */ int ARP_Initialise() { - gaARP_Cache = malloc( ARP_CACHE_SIZE * sizeof(*gaARP_Cache) ); - memset( gaARP_Cache, 0, ARP_CACHE_SIZE * sizeof(*gaARP_Cache) ); - giARP_CacheSpace = ARP_CACHE_SIZE; + gaARP_Cache4 = malloc( ARP_CACHE_SIZE * sizeof(struct sARP_Cache4) ); + memset( gaARP_Cache4, 0, ARP_CACHE_SIZE * sizeof(struct sARP_Cache4) ); + giARP_Cache4Space = ARP_CACHE_SIZE; + + gaARP_Cache6 = malloc( ARP_CACHE_SIZE * sizeof(struct sARP_Cache6) ); + memset( gaARP_Cache6, 0, ARP_CACHE_SIZE * sizeof(struct sARP_Cache6) ); + giARP_Cache6Space = ARP_CACHE_SIZE; Link_RegisterType(0x0806, ARP_int_GetPacket); return 1; @@ -53,34 +65,43 @@ tMacAddr ARP_Resolve4(tInterface *Interface, tIPv4 Address) int lastID; int i; - LOCK( &glARP_Cache ); - for( i = 0; i < giARP_CacheSpace; i++ ) + ENTER("pInterface xAddress", Interface, Address); + + LOCK( &glARP_Cache4 ); + for( i = 0; i < giARP_Cache4Space; i++ ) { - if(gaARP_Cache[i].IP4.L != Address.L) continue; + if(gaARP_Cache4[i].IP.L != Address.L) continue; // Check if the entry needs to be refreshed - if( now() - gaARP_Cache[i].LastUpdate > ARP_MAX_AGE ) break; + if( now() - gaARP_Cache4[i].LastUpdate > ARP_MAX_AGE ) break; - RELEASE( &glARP_Cache ); - return gaARP_Cache[i].MAC; + RELEASE( &glARP_Cache4 ); + LOG("Return %x:%x:%x:%x:%x:%x", + gaARP_Cache4[i].MAC.B[0], gaARP_Cache4[i].MAC.B[1], + gaARP_Cache4[i].MAC.B[2], gaARP_Cache4[i].MAC.B[3], + gaARP_Cache4[i].MAC.B[4], gaARP_Cache4[i].MAC.B[5] + ); + LEAVE('-'); + return gaARP_Cache4[i].MAC; } - RELEASE( &glARP_Cache ); + RELEASE( &glARP_Cache4 ); lastID = giARP_LastUpdateID; ARP_int_Resolve4(Interface, Address); for(;;) { while(lastID == giARP_LastUpdateID) Threads_Yield(); + lastID = giARP_LastUpdateID; - LOCK( &glARP_Cache ); - for( i = 0; i < giARP_CacheSpace; i++ ) + LOCK( &glARP_Cache4 ); + for( i = 0; i < giARP_Cache4Space; i++ ) { - if(gaARP_Cache[i].IP4.L != Address.L) continue; + if(gaARP_Cache4[i].IP.L != Address.L) continue; - RELEASE( &glARP_Cache ); - return gaARP_Cache[i].MAC; + RELEASE( &glARP_Cache4 ); + return gaARP_Cache4[i].MAC; } - RELEASE( &glARP_Cache ); + RELEASE( &glARP_Cache4 ); } } @@ -93,6 +114,9 @@ int ARP_int_Resolve4(tInterface *Interface, tIPv4 Address) { struct sArpRequest4 req; + Log("[ARP4 ] Asking for address %i.%i.%i.%i", + Address.B[0], Address.B[1], Address.B[2], Address.B[3] + ); req.HWType = htons(0x100); // Ethernet req.Type = htons(0x0800); req.HWSize = 6; @@ -108,14 +132,78 @@ int ARP_int_Resolve4(tInterface *Interface, tIPv4 Address) return 0; } +/** + * \brief Updates the ARP Cache entry for an IPv4 Address + */ +void ARP_UpdateCache4(tIPv4 SWAddr, tMacAddr HWAddr) +{ + int i; + int free = -1; + int oldest = 0; + + // Find an entry for the IP address in the cache + LOCK(&glARP_Cache4); + for( i = giARP_Cache4Space; i--; ) + { + if(gaARP_Cache4[oldest].LastUpdate > gaARP_Cache4[i].LastUpdate) { + oldest = i; + } + if( gaARP_Cache4[i].IP.L == SWAddr.L ) break; + if( gaARP_Cache4[i].LastUpdate == 0 && free == -1 ) free = i; + } + // If there was no match, we need to make one + if(i == -1) { + if(free != -1) + i = free; + else + i = oldest; + gaARP_Cache4[i].IP = SWAddr; + } + + gaARP_Cache4[i].MAC = HWAddr; + gaARP_Cache4[i].LastUpdate = now(); + RELEASE(&glARP_Cache4); +} + +/** + * \brief Updates the ARP Cache entry for an IPv6 Address + */ +void ARP_UpdateCache6(tIPv6 SWAddr, tMacAddr HWAddr) +{ + int i; + int free = -1; + int oldest = 0; + + // Find an entry for the MAC address in the cache + LOCK(&glARP_Cache6); + for( i = giARP_Cache6Space; i--; ) + { + if(gaARP_Cache6[oldest].LastUpdate > gaARP_Cache6[i].LastUpdate) { + oldest = i; + } + if( MAC_EQU(gaARP_Cache6[i].MAC, HWAddr) ) break; + if( gaARP_Cache6[i].LastUpdate == 0 && free == -1 ) free = i; + } + // If there was no match, we need to make one + if(i == -1) { + if(free != -1) + i = free; + else + i = oldest; + gaARP_Cache6[i].MAC = HWAddr; + } + + gaARP_Cache6[i].IP = SWAddr; + gaARP_Cache6[i].LastUpdate = now(); + RELEASE(&glARP_Cache6); +} + /** * \fn void ARP_int_GetPacket(tAdapter *Adapter, tMacAddr From, int Length, void *Buffer) * \brief Called when an ARP packet is recieved */ void ARP_int_GetPacket(tAdapter *Adapter, tMacAddr From, int Length, void *Buffer) { - int i, free = -1; - int oldest = 0; tArpRequest4 *req4 = Buffer; tArpRequest6 *req6 = Buffer; tInterface *iface; @@ -165,6 +253,9 @@ void ARP_int_GetPacket(tAdapter *Adapter, tMacAddr From, int Length, void *Buffe iface = IPv4_GetInterface(Adapter, req4->DestIP, 0); if( iface ) { + Log("[ARP ] Caching sender's IP Address"); + ARP_UpdateCache4(req4->SourceIP, req4->SourceMac); + req4->DestIP = req4->SourceIP; req4->DestMac = req4->SourceMac; req4->SourceIP = iface->IP4.Address; @@ -201,45 +292,25 @@ void ARP_int_GetPacket(tAdapter *Adapter, tMacAddr From, int Length, void *Buffe break; - case 2: // Ooh! A response! - // Find an entry for the MAC address in the cache - LOCK(&glARP_Cache); - for( i = giARP_CacheSpace; i--; ) - { - if(gaARP_Cache[oldest].LastUpdate > gaARP_Cache[i].LastUpdate) { - oldest = i; - } - if( MAC_EQU(gaARP_Cache[i].MAC, From) ) break; - if( gaARP_Cache[i].LastUpdate == 0 && free==-1 ) free = i; - } - if(i + 1 == 0) { - if(free != -1) - i = free; - else - i = oldest; - } - + case 2: // Ooh! A response! // Check what type of IP it is switch( req4->SWSize ) { case 4: - gaARP_Cache[i].IP4 = req4->SourceIP; + ARP_UpdateCache4( req4->SourceIP, From ); break; case 6: if( Length < sizeof(tArpRequest6) ) { Log("[ARP ] Recieved undersized packet (IPv6)"); return ; } - gaARP_Cache[i].IP6 = req6->SourceIP; + ARP_UpdateCache6( req6->SourceIP, From ); break; default: Log("[ARP ] Unknown Protocol Address size (%i)", req4->SWSize); - RELEASE(&glARP_Cache); return ; } - gaARP_Cache[i].LastUpdate = now(); - RELEASE(&glARP_Cache); break; } } diff --git a/Modules/IPStack/icmp.c b/Modules/IPStack/icmp.c index 3f82f878..90ef7cbf 100644 --- a/Modules/IPStack/icmp.c +++ b/Modules/IPStack/icmp.c @@ -37,6 +37,7 @@ void ICMP_GetPacket(tInterface *Interface, void *Address, int Length, void *Buff { tICMPHeader *hdr = Buffer; + Log("[ICMP ] Length = %i", Length); Log("[ICMP ] hdr->Type = %i", hdr->Type); Log("[ICMP ] hdr->Code = %i", hdr->Code); Log("[ICMP ] hdr->Checksum = 0x%x", ntohs(hdr->Checksum)); @@ -45,6 +46,7 @@ void ICMP_GetPacket(tInterface *Interface, void *Address, int Length, void *Buff switch(hdr->Type) { + // -- 0: Echo Reply case ICMP_ECHOREPLY: if(hdr->Code != 0) { Warning("[ICMP ] Code == %i for ICMP Echo Reply, should be 0", hdr->Code); @@ -56,6 +58,20 @@ void ICMP_GetPacket(tInterface *Interface, void *Address, int Length, void *Buff } gICMP_PingSlots[hdr->ID].bArrived = 1; break; + + // -- 8: Echo Request + case ICMP_ECHOREQ: + if(hdr->Code != 0) { + Warning("[ICMP ] Code == %i for ICMP Echo Request, should be 0", hdr->Code); + return ; + } + Log("[ICMP ] Replying"); + hdr->Type = ICMP_ECHOREPLY; + hdr->Checksum = 0; + hdr->Checksum = htons( IPv4_Checksum(hdr, Length) ); + Log("[ICMP ] Checksum = 0x%04x", hdr->Checksum); + IPv4_SendPacket(Interface, *(tIPv4*)Address, 1, ntohs(hdr->Sequence), Length, hdr); + break; } } @@ -86,7 +102,7 @@ int ICMP_Ping(tInterface *Interface, tIPv4 Addr) hdr->ID = i; hdr->Sequence = ~i; hdr->Checksum = htons( IPv4_Checksum(hdr, sizeof(buf)) ); - IPv4_SendPacket(Interface, Addr, 1, i, 32, buf); + IPv4_SendPacket(Interface, Addr, 1, i, sizeof(buf), buf); return -1; } diff --git a/Modules/IPStack/icmp.h b/Modules/IPStack/icmp.h index abd19cbd..a9594f8e 100644 --- a/Modules/IPStack/icmp.h +++ b/Modules/IPStack/icmp.h @@ -21,7 +21,7 @@ struct sICMPHeader // === CONSTANTS === enum eICMPTypes { - ICMP_ECHOREPLY = 1, + ICMP_ECHOREPLY = 0, ICMP_UNREACHABLE = 3, ICMP_QUENCH = 4, ICMP_REDIRECT = 5, diff --git a/Modules/IPStack/ipv4.c b/Modules/IPStack/ipv4.c index 933b90ba..3a1a893b 100644 --- a/Modules/IPStack/ipv4.c +++ b/Modules/IPStack/ipv4.c @@ -63,7 +63,7 @@ int IPv4_SendPacket(tInterface *Iface, tIPv4 Address, int Protocol, int ID, int memcpy(&hdr->Options[0], Data, Length); hdr->Version = 4; - hdr->HeaderLength = htons( sizeof(tIPv4Header) ); + hdr->HeaderLength = sizeof(tIPv4Header)/4; hdr->DiffServices = 0; // TODO: Check hdr->TotalLength = htons( bufSize ); hdr->Identifcation = htons( ID ); // TODO: Check @@ -95,7 +95,7 @@ void IPv4_int_GetPacket(tAdapter *Adapter, tMacAddr From, int Length, void *Buff //Log("[IPv4 ] Version = %i", hdr->Version); Log("[IPv4 ] HeaderLength = %i", hdr->HeaderLength); Log("[IPv4 ] DiffServices = %i", hdr->DiffServices); - //Log("[IPv4 ] TotalLength = %i", ntohs(hdr->TotalLength) ); + Log("[IPv4 ] TotalLength = %i", ntohs(hdr->TotalLength) ); //Log("[IPv4 ] Identifcation = %i", ntohs(hdr->Identifcation) ); //Log("[IPv4 ] TTL = %i", hdr->TTL ); Log("[IPv4 ] Protocol = %i", hdr->Protocol ); @@ -117,7 +117,7 @@ void IPv4_int_GetPacket(tAdapter *Adapter, tMacAddr From, int Length, void *Buff // Check Packet length if( ntohs(hdr->TotalLength) > Length) { - Log("[IPv4 ] hdr->TotalLength(%i) > Length(%i)", hdr->TotalLength, Length); + Log("[IPv4 ] hdr->TotalLength(%i) > Length(%i)", ntohs(hdr->TotalLength), Length); return; } @@ -131,7 +131,7 @@ void IPv4_int_GetPacket(tAdapter *Adapter, tMacAddr From, int Length, void *Buff // Defragment //TODO - dataLength = hdr->TotalLength - sizeof(tIPv4Header); + dataLength = ntohs(hdr->TotalLength) - sizeof(tIPv4Header); data = &hdr->Options[0]; // Send it on @@ -201,6 +201,8 @@ Uint16 IPv4_Checksum(void *Buf, int Size) Uint16 *arr = Buf; int i; + Log("IPv4_Checksum: (%p, %i)", Buf, Size); + Size = (Size + 1) >> 1; for(i = 0; i < Size; i++ ) { @@ -208,7 +210,7 @@ Uint16 IPv4_Checksum(void *Buf, int Size) sum ++; // Simulate 1's complement sum += arr[i]; } - return ~sum; + return htons( ~sum ); } /** diff --git a/Modules/IPStack/link.c b/Modules/IPStack/link.c index cb59f0f1..86cde858 100644 --- a/Modules/IPStack/link.c +++ b/Modules/IPStack/link.c @@ -86,7 +86,6 @@ void Link_SendPacket(tAdapter *Adapter, Uint16 Type, tMacAddr To, int Length, vo *(Uint32*) &hdr->Data[Length] = 0; *(Uint32*) &hdr->Data[Length] = htonl( Link_CalculateCRC(buf, bufSize) ); - VFS_Write(Adapter->DeviceFD, bufSize, buf); } diff --git a/Modules/Network/NE2000/ne2000.c b/Modules/Network/NE2000/ne2000.c index 76e4379f..24d82782 100644 --- a/Modules/Network/NE2000/ne2000.c +++ b/Modules/Network/NE2000/ne2000.c @@ -75,7 +75,7 @@ typedef struct sNe2k_Card { int NextMemPage; //!< Next Card Memory page to use - Uint8 Buffer[RX_BUF_SIZE]; + Uint8 Buffer[RX_BUF_SIZE*256]; char Name[2]; // "0" tVFS_Node Node; @@ -302,11 +302,16 @@ Uint64 Ne2k_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) tCard *Card = (tCard*)Node->ImplPtr; Uint16 *buf = Buffer; int rem = Length; + int page; ENTER("pNode XOffset XLength pBuffer", Node, Offset, Length, Buffer); // Sanity Check Length - if(Length > TX_BUF_SIZE) { + if(Length > TX_BUF_SIZE*256) { + Warning( + "Ne2k_Write - Attempting to send over TX_BUF_SIZE(%i) bytes (%i)", + TX_BUF_SIZE*256, Length + ); LEAVE('i', 0); return 0; } @@ -327,7 +332,8 @@ Uint64 Ne2k_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) // Set up transfer outb(Card->IOBase + RSAR0, 0x00); // Page Offset - outb(Card->IOBase + RSAR1, Ne2k_int_GetWritePage(Card, Length)); // Page Offset + page = Ne2k_int_GetWritePage(Card, Length); + outb(Card->IOBase + RSAR1, page); // Page Offset // Start //outb(Card->IOBase + CMD, 0|0x18|0x4|0x2); // Page 0, Transmit Packet, TXP, Start outb(Card->IOBase + CMD, 0|0x10|0x2); // Page 0, Remote Write, Start @@ -342,6 +348,7 @@ Uint64 Ne2k_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) outb( Card->IOBase + ISR, 0x40 ); // ACK Interrupt // Send Packet + outb(Card->IOBase + TPSR, page); outb(Card->IOBase + CMD, 0|0x10|0x4|0x2); // Complete DMA -- 2.20.1