From 2023a18b48a2b1fd5a5bb46977e483624d46ac1c Mon Sep 17 00:00:00 2001 From: John Hodge Date: Tue, 17 Aug 2010 09:35:04 +0800 Subject: [PATCH] More work on IPv4/IPv6 firewalling support --- Modules/IPStack/firewall.c | 17 ++++++++++- Modules/IPStack/ipv4.c | 60 ++++++++++++++++++++++++++------------ Modules/IPStack/ipv6.c | 37 +++++++++++++++-------- Modules/IPStack/ipv6.h | 17 ++++++----- 4 files changed, 93 insertions(+), 38 deletions(-) diff --git a/Modules/IPStack/firewall.c b/Modules/IPStack/firewall.c index c250dd08..274066e3 100644 --- a/Modules/IPStack/firewall.c +++ b/Modules/IPStack/firewall.c @@ -27,7 +27,7 @@ * \brief Tests an IPv4 chain on a packet * \return Boolean Disallow (0: Packet Allowed, 1: Drop, 2: Reject) */ - int IPTablesV4_TestChain( +int IPTablesV4_TestChain( const char *RuleName, const tIPv4 *Src, const tIPv4 *Dest, Uint8 Type, Uint32 Flags, @@ -36,3 +36,18 @@ { return 0; // Accept all for now } + +/** + * \brief Tests an IPv6 chain on a packet + * \return Boolean Disallow (0: Packet Allowed, 1: Drop, 2: Reject) + */ +int IPTablesV6_TestChain( + const char *RuleName, + const tIPv6 *Src, const tIPv6 *Dest, + Uint8 Type, Uint32 Flags, + size_t Length, const void *Data + ) +{ + return 0; // Accept all for now +} + diff --git a/Modules/IPStack/ipv4.c b/Modules/IPStack/ipv4.c index b6c70858..672b4ec1 100644 --- a/Modules/IPStack/ipv4.c +++ b/Modules/IPStack/ipv4.c @@ -29,7 +29,7 @@ tIPCallback gaIPv4_Callbacks[256]; // === CODE === /** - * \fn int IPv4_Initialise() + * \brief Initialise the IPv4 Code */ int IPv4_Initialise() { @@ -39,8 +39,9 @@ int IPv4_Initialise() } /** - * \fn int IPv4_RegisterCallback( int ID, tIPCallback Callback ) * \brief Registers a callback + * \param ID 8-bit packet type ID + * \param Callback Callback function */ int IPv4_RegisterCallback(int ID, tIPCallback Callback) { @@ -58,6 +59,7 @@ int IPv4_RegisterCallback(int ID, tIPCallback Callback) * \param ID Some random ID number * \param Length Data Length * \param Data Packet Data + * \return Boolean Success */ int IPv4_SendPacket(tInterface *Iface, tIPv4 Address, int Protocol, int ID, int Length, const void *Data) { @@ -72,10 +74,8 @@ int IPv4_SendPacket(tInterface *Iface, tIPv4 Address, int Protocol, int ID, int &Iface->IP4.Address, &Address, Protocol, 0, Length, Data); - - if(ret != 0) - { - // Just drop it + if(ret != 0) { + // Just drop it (with an error) return 0; } @@ -123,14 +123,14 @@ void IPv4_int_GetPacket(tAdapter *Adapter, tMacAddr From, int Length, void *Buff //Log_Log("IPv4", "Version = %i", hdr->Version); //Log_Log("IPv4", "HeaderLength = %i", hdr->HeaderLength); //Log_Log("IPv4", "DiffServices = %i", hdr->DiffServices); - Log_Log("IPv4", "TotalLength = %i", ntohs(hdr->TotalLength) ); + Log_Debug("IPv4", "TotalLength = %i", ntohs(hdr->TotalLength) ); //Log_Log("IPv4", "Identifcation = %i", ntohs(hdr->Identifcation) ); //Log_Log("IPv4", "TTL = %i", hdr->TTL ); - Log_Log("IPv4", "Protocol = %i", hdr->Protocol ); + Log_Debug("IPv4", "Protocol = %i", hdr->Protocol ); //Log_Log("IPv4", "HeaderChecksum = 0x%x", ntohs(hdr->HeaderChecksum) ); - Log_Log("IPv4", "Source = %i.%i.%i.%i", + Log_Debug("IPv4", "Source = %i.%i.%i.%i", hdr->Source.B[0], hdr->Source.B[1], hdr->Source.B[2], hdr->Source.B[3] ); - Log_Log("IPv4", "Destination = %i.%i.%i.%i", + Log_Debug("IPv4", "Destination = %i.%i.%i.%i", hdr->Destination.B[0], hdr->Destination.B[1], hdr->Destination.B[2], hdr->Destination.B[3] ); #endif @@ -142,7 +142,17 @@ void IPv4_int_GetPacket(tAdapter *Adapter, tMacAddr From, int Length, void *Buff } // Check Header checksum - //TODO + { + Uint16 hdrVal, compVal; + hdrVal = hdr->HeaderChecksum; + hdr->HeaderChecksum = 0; + compVal = IPv4_Checksum(hdr, hdr->HeaderLength); + if(hdrVal != compVal) { + Log_Log("IPv4", "Header checksum fails (%04x != %04x)", hdrVal, compVal); + return ; + } + hdr->HeaderChecksum = hdrVal; + } // Check Packet length if( ntohs(hdr->TotalLength) > Length) { @@ -150,9 +160,9 @@ void IPv4_int_GetPacket(tAdapter *Adapter, tMacAddr From, int Length, void *Buff return; } - // TODO: Handle packet fragmentation + // Get Data and Data Length dataLength = ntohs(hdr->TotalLength) - sizeof(tIPv4Header); data = &hdr->Options[0]; @@ -160,8 +170,9 @@ void IPv4_int_GetPacket(tAdapter *Adapter, tMacAddr From, int Length, void *Buff // Get Interface (allowing broadcasts) iface = IPv4_GetInterface(Adapter, hdr->Destination, 1); - // TODO: INPUT Firewall Rule + // Firewall rules if( iface ) { + // Incoming Packets ret = IPTablesV4_TestChain("INPUT", &hdr->Source, &hdr->Destination, hdr->Protocol, 0, @@ -169,6 +180,7 @@ void IPv4_int_GetPacket(tAdapter *Adapter, tMacAddr From, int Length, void *Buff ); } else { + // Routed packets ret = IPTablesV4_TestChain("FORWARD", &hdr->Source, &hdr->Destination, hdr->Protocol, 0, @@ -180,7 +192,9 @@ void IPv4_int_GetPacket(tAdapter *Adapter, tMacAddr From, int Length, void *Buff // 0 - Allow case 0: break; // 1 - Silent Drop - case 1: return ; + case 1: + Log_Debug("IPv4", "Silently dropping packet"); + return ; // Unknown, silent drop default: return ; @@ -189,7 +203,7 @@ void IPv4_int_GetPacket(tAdapter *Adapter, tMacAddr From, int Length, void *Buff // Routing if(!iface) { - Log_Log("IPv4", "Route the packet"); + Log_Debug("IPv4", "Route the packet"); // TODO: Parse Routing tables and determine where to send it @@ -198,7 +212,7 @@ void IPv4_int_GetPacket(tAdapter *Adapter, tMacAddr From, int Length, void *Buff // Send it on if( gaIPv4_Callbacks[hdr->Protocol] ) - gaIPv4_Callbacks[hdr->Protocol] (iface, &hdr->Source, dataLength, data); + gaIPv4_Callbacks[hdr->Protocol]( iface, &hdr->Source, dataLength, data ); else Log_Log("IPv4", "Unknown Protocol %i", hdr->Protocol); } @@ -206,6 +220,9 @@ void IPv4_int_GetPacket(tAdapter *Adapter, tMacAddr From, int Length, void *Buff /** * \fn tInterface *IPv4_GetInterface(tAdapter *Adapter, tIPv4 Address) * \brief Searches an adapter for a matching address + * \param Adapter Incoming Adapter + * \param Address Destination Address + * \param Broadcast Allow broadcast packets */ tInterface *IPv4_GetInterface(tAdapter *Adapter, tIPv4 Address, int Broadcast) { @@ -238,6 +255,7 @@ tInterface *IPv4_GetInterface(tAdapter *Adapter, tIPv4 Address, int Broadcast) /** * \brief Convert a network prefix to a netmask + * \param FixedBits Netmask size (/n) * * For example /24 will become 255.255.255.0 */ @@ -252,6 +270,10 @@ Uint32 IPv4_Netmask(int FixedBits) /** * \brief Calculate the IPv4 Checksum + * \param Buf Input buffer + * \param Size Size of input + * + * One's complement sum of all 16-bit words (bitwise inverted) */ Uint16 IPv4_Checksum(const void *Buf, int Size) { @@ -271,8 +293,10 @@ Uint16 IPv4_Checksum(const void *Buf, int Size) /** * \brief Sends an ICMP Echo and waits for a reply + * \param IFace Interface + * \param Addr Destination address */ -int IPv4_Ping(tInterface *Iface, tIPv4 Addr) +int IPv4_Ping(tInterface *IFace, tIPv4 Addr) { - return ICMP_Ping(Iface, Addr); + return ICMP_Ping(IFace, Addr); } diff --git a/Modules/IPStack/ipv6.c b/Modules/IPStack/ipv6.c index 7ae927a4..aac33dea 100644 --- a/Modules/IPStack/ipv6.c +++ b/Modules/IPStack/ipv6.c @@ -17,7 +17,7 @@ tInterface *IPv6_GetInterface(tAdapter *Adapter, tIPv6 Address, int Broadcast); // === CODE === /** - * \fn int IPv6_Initialise() + * \brief Initialise the IPv6 handling code */ int IPv6_Initialise() { @@ -28,31 +28,44 @@ int IPv6_Initialise() /** * \fn void IPv6_int_GetPacket(tInterface *Interface, tMacAddr From, int Length, void *Buffer) * \brief Process an IPv6 Packet + * \param Interface Input interface + * \param From Source MAC address + * \param Length Packet length + * \param Buffer Packet data */ void IPv6_int_GetPacket(tAdapter *Interface, tMacAddr From, int Length, void *Buffer) { tIPv6Header *hdr = Buffer; if(Length < sizeof(tIPv6Header)) return; - if( ((hdr->Head >> (20+8)) & 0xF) != 6 ) + hdr->Head = ntohl(hdr->Head); + + //if( ((hdr->Head >> (20+8)) & 0xF) != 6 ) + if( hdr->Version != 6 ) return; - Log("[IPv6 ] hdr = {"); - Log("[IPv6 ] .Version = %i", (hdr->Head >> (20+8)) & 0xF ); - Log("[IPv6 ] .TrafficClass = %i", (hdr->Head >> (20)) & 0xFF ); - Log("[IPv6 ] .FlowLabel = %i", hdr->Head & 0xFFFFF ); - Log("[IPv6 ] .PayloadLength = 0x%04x", ntohs(hdr->PayloadLength) ); - Log("[IPv6 ] .NextHeader = 0x%02x", hdr->NextHeader ); - Log("[IPv6 ] .HopLimit = 0x%02x", hdr->HopLimit ); - Log("[IPv6 ] .Source = %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x", hdr->Source ); - Log("[IPv6 ] .Destination = %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x", hdr->Destination ); - Log("[IPv6 ] }"); + Log_Debug("IPv6", "hdr = {"); + //Log_Debug("IPv6", " .Version = %i", (hdr->Head >> (20+8)) & 0xF ); + //Log_Debug("IPv6", " .TrafficClass = %i", (hdr->Head >> (20)) & 0xFF ); + //Log_Debug("IPv6", " .FlowLabel = %i", hdr->Head & 0xFFFFF ); + Log_Debug("IPv6", " .Version = %i", hdr->Version ); + Log_Debug("IPv6", " .TrafficClass = %i", hdr->TrafficClass ); + Log_Debug("IPv6", " .FlowLabel = %i", hdr->FlowLabel ); + Log_Debug("IPv6", " .PayloadLength = 0x%04x", ntohs(hdr->PayloadLength) ); + Log_Debug("IPv6", " .NextHeader = 0x%02x", hdr->NextHeader ); + Log_Debug("IPv6", " .HopLimit = 0x%02x", hdr->HopLimit ); + Log_Debug("IPv6", " .Source = %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x", hdr->Source ); + Log_Debug("IPv6", " .Destination = %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x", hdr->Destination ); + Log_Debug("IPv6", "}"); } /** * \fn tInterface *IPv6_GetInterface(tAdapter *Adapter, tIPv6 Address) * \brief Searches an adapter for a matching address + * \param Adapter Source adapter + * \param Address Destination Address + * \param Broadcast Allow broadcast? */ tInterface *IPv6_GetInterface(tAdapter *Adapter, tIPv6 Address, int Broadcast) { diff --git a/Modules/IPStack/ipv6.h b/Modules/IPStack/ipv6.h index f2f14f44..7df0d0fe 100644 --- a/Modules/IPStack/ipv6.h +++ b/Modules/IPStack/ipv6.h @@ -11,17 +11,20 @@ typedef struct sIPv6Header tIPv6Header; struct sIPv6Header { - #if 1 + #if 0 // High 4: Version - // Next: Traffic Class + // Next 8: Traffic Class // Low 20: Flow Label Uint32 Head; #else - struct { - unsigned Version: 4; - unsigned TrafficClass: 8; - unsigned FlowLabel: 20; - } __attribute__((packed)); + union { + Uint32 Head; // Allow a ntohl to happen + struct { + unsigned Version: 4; + unsigned TrafficClass: 8; + unsigned FlowLabel: 20; + } PACKED; + } PACKED; #endif Uint16 PayloadLength; Uint8 NextHeader; // Type of payload data -- 2.20.1