+/**
+ * \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)
+{
+ 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 != 0) return rv; // No match / action
+ }
+
+ // Update statistics
+ Rule->PacketCount ++;
+ Rule->ByteCount += Length;
+
+ return IPTables_TestChain(Rule->Target, AddrType, Src, Dest, Type, Flags, Length, Data);
+}
+