else
i = oldest;
}
-
- Log_Log("ARP4", "Caching %i.%i.%i.%i (%02x:%02x:%02x:%02x:%02x:%02x) in %i",
- SWAddr.B[0], SWAddr.B[1], SWAddr.B[2], SWAddr.B[3],
- HWAddr.B[0], HWAddr.B[1], HWAddr.B[2], HWAddr.B[3], HWAddr.B[4], HWAddr.B[5],
- i
- );
+
+ if( memcmp(&gaARP_Cache4[i].MAC, &HWAddr, sizeof(HWAddr)) != 0 )
+ {
+ Log_Log("ARP4", "Caching %i.%i.%i.%i (%02x:%02x:%02x:%02x:%02x:%02x) in %i",
+ SWAddr.B[0], SWAddr.B[1], SWAddr.B[2], SWAddr.B[3],
+ HWAddr.B[0], HWAddr.B[1], HWAddr.B[2], HWAddr.B[3], HWAddr.B[4], HWAddr.B[5],
+ i
+ );
- gaARP_Cache4[i].IP = SWAddr;
- gaARP_Cache4[i].MAC = HWAddr;
- gaARP_Cache4[i].LastUpdate = now();
- Semaphore_Signal(&gARP_Cache4Semaphore, giARP_WaitingThreads);
+ gaARP_Cache4[i].IP = SWAddr;
+ gaARP_Cache4[i].MAC = HWAddr;
+ gaARP_Cache4[i].LastUpdate = now();
+ Semaphore_Signal(&gARP_Cache4Semaphore, giARP_WaitingThreads);
+ }
Mutex_Release(&glARP_Cache4);
}
#include "ipv4.h"
#include "firewall.h"
+// === CONSTANTS ===
#define DEFAULT_TTL 32
+#define IPV4_TRACE 0 // set to 1 to enable packet tracing
// === IMPORTS ===
extern tInterface *gIP_Interfaces;
IPStack_Buffer_AppendSubBuffer(Buffer, sizeof(tIPv4Header), 0, &hdr, NULL, NULL);
+ #if IPV4_TRACE
Log_Log("IPv4", "Sending packet to %i.%i.%i.%i",
Address.B[0], Address.B[1], Address.B[2], Address.B[3]);
+ #endif
Link_SendPacket(Iface->Adapter, IPV4_ETHERNET_ID, to, Buffer);
return 1;
}
// TODO: Handle packet fragmentation
+ #if IPV4_TRACE
Log_Debug("IPv4", " From %i.%i.%i.%i to %i.%i.%i.%i",
hdr->Source.B[0], hdr->Source.B[1], hdr->Source.B[2], hdr->Source.B[3],
hdr->Destination.B[0], hdr->Destination.B[1], hdr->Destination.B[2], hdr->Destination.B[3]
);
+ #endif
- // TODO: Tell ARP?
+ // TODO: Should ARP sniffing be used?
+ // - If we get a packet, cache the source MAC
ARP_UpdateCache4(hdr->Source, From);
// Get Data and Data Length
#include "include/adapters_int.h"
// === CONSTANTS ===
+#define LINK_LOGPACKETS 0
+#define VALIDATE_CHECKSUM 0
#define MAX_PACKET_SIZE 2048
// === PROTOTYPES ===
int length = IPStack_Buffer_GetLength(Buffer);
int ofs = (4 - (length & 3)) & 3;
Uint8 buf[sizeof(tEthernetHeader) + ofs + 4];
- Uint32 *checksum = (void*)(buf + sizeof(tEthernetHeader) + ofs);
+ //Uint32 *checksum = (void*)(buf + sizeof(tEthernetHeader) + ofs);
tEthernetHeader *hdr = (void*)buf;
Log_Log("Net Link", "Sending %i bytes to %02x:%02x:%02x:%02x:%02x:%02x (Type 0x%x)",
hdr->Type = htons(Type);
memset(hdr+1, 0, ofs+4); // zero padding and checksum
- if( (Adapter->Type->Flags & ADAPTERFLAG_OFFLOAD_MAC) )
+ //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));
- }
+ //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],
free(data);
return 1;
}
-
+
+ #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->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
// Check if there is a registered callback for this packet type
int i;
#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;
#define TCP_DACK_THRESHOLD 4096
#define TCP_DACK_TIMEOUT 500
+#define TCP_DEBUG 0 // Set to non-0 to enable TCP packet logging
+
// === PROTOTYPES ===
void TCP_Initialise(void);
void TCP_StartConnection(tTCPConnection *Conn);
void TCP_INT_HandleConnectionPacket(tTCPConnection *Connection, tTCPHeader *Header, int Length);
int TCP_INT_AppendRecieved(tTCPConnection *Connection, const void *Data, size_t Length);
void TCP_INT_UpdateRecievedFromFuture(tTCPConnection *Connection);
-void TCP_INT_SendACK(tTCPConnection *Connection);
+void TCP_int_SendDelayedACK(void *ConnPtr);
+void TCP_INT_SendACK(tTCPConnection *Connection, const char *Reason);
Uint16 TCP_GetUnusedPort();
int TCP_AllocatePort(Uint16 Port);
int TCP_DeallocatePort(Uint16 Port);
tTCPListener *srv;
tTCPConnection *conn;
+ #if TCP_DEBUG
Log_Log("TCP", "TCP_GetPacket: <Local>:%i from [%s]:%i, Flags = %s%s%s%s%s%s%s%s",
ntohs(hdr->DestPort),
IPStack_PrintAddress(Interface->Type, Address),
(hdr->Flags & TCP_FLAG_SYN) ? "SYN " : "",
(hdr->Flags & TCP_FLAG_FIN) ? "FIN " : ""
);
+ #endif
if( Length > (hdr->DataOffset >> 4)*4 )
{
if(Header->Flags & TCP_FLAG_SYN) {
// TODO: What if the packet also has data?
if( Connection->LastACKSequence != Connection->NextSequenceRcv )
- TCP_INT_SendACK(Connection);
+ TCP_INT_SendACK(Connection, "SYN");
Connection->NextSequenceRcv = ntohl(Header->SequenceNumber);
Connection->LastACKSequence = Connection->NextSequenceRcv;
}
// Get length of data
dataLen = Length - (Header->DataOffset>>4)*4;
LOG("dataLen = %i", dataLen);
+ #if TCP_DEBUG
Log_Debug("TCP", "State %i, dataLen = %x", Connection->State, dataLen);
+ #endif
//
// State Machine
}
Connection->NextSequenceRcv ++; // TODO: Is this right? (empty packet counts as one byte)
Log_Log("TCP", "Empty Packet, inc and ACK the current sequence number");
- TCP_INT_SendACK(Connection);
+ TCP_INT_SendACK(Connection, "Empty");
#if 0
Header->DestPort = Header->SourcePort;
Header->SourcePort = htons(Connection->LocalPort);
// - Only send an ACK if we've had a burst
if( Connection->NextSequenceRcv > (Uint32)(TCP_DACK_THRESHOLD + Connection->LastACKSequence) )
{
- TCP_INT_SendACK(Connection);
+ TCP_INT_SendACK(Connection, "DACK Burst");
// - Extend TCP deferred ACK timer
Time_RemoveTimer(Connection->DeferredACKTimer);
}
// - Schedule the deferred ACK timer (if already scheduled, this is a NOP)
Time_ScheduleTimer(Connection->DeferredACKTimer, TCP_DACK_TIMEOUT);
#else
- TCP_INT_SendACK(Connection);
+ TCP_INT_SendACK(Connection, "RX");
#endif
}
// Check if the packet is in window
Log_Log("TCP", "Fully out of sequence packet (0x%08x not between 0x%08x and 0x%08x), dropped",
sequence_num, Connection->NextSequenceRcv, Connection->NextSequenceRcv+TCP_WINDOW_SIZE);
// Spec says we should send an empty ACK with the current state
- TCP_INT_SendACK(Connection);
+ TCP_INT_SendACK(Connection, "Bad Seq");
}
break;
#endif
}
-void TCP_INT_SendACK(tTCPConnection *Connection)
+void TCP_int_SendDelayedACK(void *ConnPtr)
+{
+ TCP_INT_SendACK(ConnPtr, "DACK Timeout");
+}
+
+void TCP_INT_SendACK(tTCPConnection *Connection, const char *Reason)
{
tTCPHeader hdr;
// ACK Packet
hdr.Flags = TCP_FLAG_ACK; // TODO: Determine if SYN is wanted too
hdr.Checksum = 0; // TODO: Checksum
hdr.UrgentPointer = 0;
- Log_Debug("TCP", "Sending ACK for 0x%08x", Connection->NextSequenceRcv);
+ Log_Debug("TCP", "Sending ACK for 0x%08x (%s)", Connection->NextSequenceRcv, Reason);
TCP_SendPacket( Connection, &hdr, 0, NULL );
//Connection->NextSequenceSend ++;
Connection->LastACKSequence = Connection->NextSequenceRcv;
conn->FuturePacketValidBytes = conn->FuturePacketData + TCP_WINDOW_SIZE;
#endif
- conn->DeferredACKTimer = Time_AllocateTimer( (void(*)(void*)) TCP_INT_SendACK, conn);
+ conn->DeferredACKTimer = Time_AllocateTimer( TCP_int_SendDelayedACK, conn);
SHORTLOCK(&glTCP_OutbountCons);
conn->Next = gTCP_OutbountCons;