X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Modules%2FIPStack%2Ffirewall.c;h=9da14f61fd465d0255778da5701d2681f4f67bd1;hb=e7d0a33cc9b8bf0005799ab2fb5151f78a255772;hp=d279bf3ebb027ab03f5592a429c96ddc82d6d63e;hpb=73a1651e9888c1724fae7f923e73d30fd8e0dfb4;p=tpg%2Facess2.git diff --git a/Modules/IPStack/firewall.c b/Modules/IPStack/firewall.c index d279bf3e..9da14f61 100644 --- a/Modules/IPStack/firewall.c +++ b/Modules/IPStack/firewall.c @@ -5,14 +5,36 @@ #include "ipstack.h" #include "firewall.h" +#define MAX_ADDRTYPE 9 + // === IMPORTS === // === TYPES === +typedef struct sKeyValue tKeyValue; typedef struct sFirewallMod tFirewallMod; typedef struct sModuleRule tModuleRule; typedef struct sRule tRule; typedef struct sChain tChain; +// === STRUCTURES === +struct sKeyValue +{ + const char *Key; + const char *Value; +}; + +struct sFirewallMod +{ + const char *Name; + + int (*Match)(tModuleRule *Rule, int AddrType, + const void *Src, const void *Dest, + Uint8 Type, Uint32 Flags, + size_t Length, const void *Data); + + tModuleRule *(*Create)(tKeyValue *Params); +}; + struct sModuleRule { tModuleRule *Next; @@ -29,17 +51,17 @@ struct sRule int PacketCount; // Number of packets seen int ByteCount; // Number of bytes seen (IP Payload bytes) - int bInvertSource; - void *Source; - int SourceMask; + int bInvertSource; // Boolean NOT flag on source + void *Source; // Source address bytes + int SourceMask; // Source address mask bits - int bInvertDest; - void *Dest; - int DestMask; + int bInvertDest; // Boolean NOT flag on destination + void *Dest; // Destination address bytes + int DestMask; // Destination address mask bits - tModuleRule *Modules; + tModuleRule *Modules; // Modules loaded for this rule - char Action[]; // Target rule name + char Target[]; // Target rule name }; struct sChain @@ -62,19 +84,45 @@ struct sChain ); // === GLOBALS === -tChain *gapFirewall_Chains[10]; +tChain *gapFirewall_Chains[MAX_ADDRTYPE+1]; tChain gFirewall_DROP = {.Name="DROP"}; tChain gFirewall_ACCEPT = {.Name="ACCEPT"}; tChain gFirewall_RETURN = {.Name="RETURN"}; // === CODE === +/** + * \brief Apply a rule to a packet + * \return -1 for no match, -2 for RETURN, eFirewallAction otherwise + */ int IPTables_DoRule( tRule *Rule, int AddrType, const void *Src, const void *Dest, Uint8 Type, Uint32 Flags, size_t Length, const void *Data) { - return 0; + int rv; + // Check if source doesn't match + if( !IPStack_CompareAddress(AddrType, Src, Rule->Source, Rule->SourceMask) == !Rule->bInvertSource ) + return -1; + // Check if destination doesn't match + if( !IPStack_CompareAddress(AddrType, Dest, Rule->Dest, Rule->DestMask) == !Rule->bInvertDest ) + return -1; + + // TODO: Handle modules (UDP/TCP/etc) + tModuleRule *modrule; + for( modrule = Rule->Modules; modrule; modrule = modrule->Next ) + { + if( !modrule->Mod->Match ) continue; + rv = modrule->Mod->Match(modrule, AddrType, Src, Dest, Type, Flags, Length, Data); + if(rv == -1) return -1; // no match + // TODO: If != 0 maybe, allowing it to ask for a drop? + } + + // Update statistics + Rule->PacketCount ++; + Rule->ByteCount += Length; + + return IPTables_TestChain(Rule->Target, AddrType, Src, Dest, Type, Flags, Length, Data); } /** @@ -93,6 +141,15 @@ int IPTables_TestChain( tChain *chain; tRule *rule; + if( AddressType >= MAX_ADDRTYPE ) return -1; // Bad address type + + // Catch builtin targets + if(strcmp(RuleName, "") == 0) return -1; // No action + if(strcmp(RuleName, "ACCEPT") == 0) return 0; // Accept packet + if(strcmp(RuleName, "DROP") == 0) return 1; // Drop packet + if(strcmp(RuleName, "RETURN") == 0) return -2; // Return from rule + + // Find the rule for( chain = gapFirewall_Chains[AddressType]; chain; chain = chain->Next ) { if( strcmp(chain->Name, RuleName) == 0 ) @@ -106,6 +163,8 @@ int IPTables_TestChain( rv = IPTables_DoRule(rule, AddressType, Src, Dest, Type, Flags, Length, Data); if( rv == -1 ) continue ; + if( rv == -2 ) // -2 = Return from a chain/table, pretend no match + return -1; return rv; }