179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell/* Library which manipulates firewall rules. Version 0.1. */ 279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell/* Architecture of firewall rules is as follows: 479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell * 579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell * Chains go INPUT, FORWARD, OUTPUT then user chains. 679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell * Each user chain starts with an ERROR node. 779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell * Every chain ends with an unconditional jump: a RETURN for user chains, 879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell * and a POLICY for built-ins. 979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell */ 1079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 1179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell/* (C)1999 Paul ``Rusty'' Russell - Placed under the GNU GPL (See 1279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell COPYING for details). */ 1379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 1479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#include <assert.h> 1579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#include <string.h> 1679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#include <errno.h> 1779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#include <stdlib.h> 1879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#include <stdio.h> 191afc3b67b53e40e5aace076c0b650348aa5f4936Marc Boucher#include <unistd.h> 2079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 2179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#ifdef DEBUG_CONNTRACK 2279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define inline 2379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#endif 2479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 2516bd81be22ba2753e26f6a9ee6cb291e1e707d0dJP Abgrall#if !defined(__ANDROID__) && (!defined(__GLIBC__) || (__GLIBC__ < 2)) 2679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russelltypedef unsigned int socklen_t; 2779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#endif 2879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 2979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#include "libiptc/libiptc.h" 3079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 3179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define IP_VERSION 4 3279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define IP_OFFSET 0x1FFF 3379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 3479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define HOOK_PRE_ROUTING NF_IP_PRE_ROUTING 3579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define HOOK_LOCAL_IN NF_IP_LOCAL_IN 3679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define HOOK_FORWARD NF_IP_FORWARD 3779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define HOOK_LOCAL_OUT NF_IP_LOCAL_OUT 3879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define HOOK_POST_ROUTING NF_IP_POST_ROUTING 3979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 4014da56743c6cdf25da35b7b5ca7a5d201771990dJan Engelhardt#define STRUCT_ENTRY_TARGET struct xt_entry_target 4179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define STRUCT_ENTRY struct ipt_entry 4214da56743c6cdf25da35b7b5ca7a5d201771990dJan Engelhardt#define STRUCT_ENTRY_MATCH struct xt_entry_match 4379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define STRUCT_GETINFO struct ipt_getinfo 4479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define STRUCT_GET_ENTRIES struct ipt_get_entries 4514da56743c6cdf25da35b7b5ca7a5d201771990dJan Engelhardt#define STRUCT_COUNTERS struct xt_counters 4614da56743c6cdf25da35b7b5ca7a5d201771990dJan Engelhardt#define STRUCT_COUNTERS_INFO struct xt_counters_info 4714da56743c6cdf25da35b7b5ca7a5d201771990dJan Engelhardt#define STRUCT_STANDARD_TARGET struct xt_standard_target 4879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define STRUCT_REPLACE struct ipt_replace 4979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 5079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define ENTRY_ITERATE IPT_ENTRY_ITERATE 5114da56743c6cdf25da35b7b5ca7a5d201771990dJan Engelhardt#define TABLE_MAXNAMELEN XT_TABLE_MAXNAMELEN 5214da56743c6cdf25da35b7b5ca7a5d201771990dJan Engelhardt#define FUNCTION_MAXNAMELEN XT_FUNCTION_MAXNAMELEN 5379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 5479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define GET_TARGET ipt_get_target 5579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 5614da56743c6cdf25da35b7b5ca7a5d201771990dJan Engelhardt#define ERROR_TARGET XT_ERROR_TARGET 5779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define NUMHOOKS NF_IP_NUMHOOKS 5879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 597e5e866a36a76c153e5903b8251f90cfe07a1d34Jan Engelhardt#define IPT_CHAINLABEL xt_chainlabel 6079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 6179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_DUMP_ENTRIES dump_entries 6279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_IS_CHAIN iptc_is_chain 638c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell#define TC_FIRST_CHAIN iptc_first_chain 6479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_NEXT_CHAIN iptc_next_chain 658c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell#define TC_FIRST_RULE iptc_first_rule 668c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell#define TC_NEXT_RULE iptc_next_rule 6779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_GET_TARGET iptc_get_target 6879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_BUILTIN iptc_builtin 6979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_GET_POLICY iptc_get_policy 7079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_INSERT_ENTRY iptc_insert_entry 7179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_REPLACE_ENTRY iptc_replace_entry 7279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_APPEND_ENTRY iptc_append_entry 73d59b9db031abee37a9aa9776662dd15370faabf4Stefan Tomanek#define TC_CHECK_ENTRY iptc_check_entry 7479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_DELETE_ENTRY iptc_delete_entry 7579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_DELETE_NUM_ENTRY iptc_delete_num_entry 7679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_FLUSH_ENTRIES iptc_flush_entries 7779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_ZERO_ENTRIES iptc_zero_entries 781cef74d943055668b5e356eebea877fdaa1ce3e0Harald Welte#define TC_READ_COUNTER iptc_read_counter 791cef74d943055668b5e356eebea877fdaa1ce3e0Harald Welte#define TC_ZERO_COUNTER iptc_zero_counter 801cef74d943055668b5e356eebea877fdaa1ce3e0Harald Welte#define TC_SET_COUNTER iptc_set_counter 8179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_CREATE_CHAIN iptc_create_chain 8279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_GET_REFERENCES iptc_get_references 8379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_DELETE_CHAIN iptc_delete_chain 8479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_RENAME_CHAIN iptc_rename_chain 8579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_SET_POLICY iptc_set_policy 8679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_GET_RAW_SOCKET iptc_get_raw_socket 8779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_INIT iptc_init 88841e4aed2349046eb2c0b1375139c06569a93bd0Martin Josefsson#define TC_FREE iptc_free 8979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_COMMIT iptc_commit 9079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_STRERROR iptc_strerror 9170067291528bb949fac8a584e782f2b4c38e4c16Phil Oester#define TC_NUM_RULES iptc_num_rules 9270067291528bb949fac8a584e782f2b4c38e4c16Phil Oester#define TC_GET_RULE iptc_get_rule 93de4d2d3b716d83a6d3831aaf902c5adb5d1d14c9Jan Engelhardt#define TC_OPS iptc_ops 9479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 9579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_AF AF_INET 9679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_IPPROTO IPPROTO_IP 9779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 9879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define SO_SET_REPLACE IPT_SO_SET_REPLACE 9979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define SO_SET_ADD_COUNTERS IPT_SO_SET_ADD_COUNTERS 10079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define SO_GET_INFO IPT_SO_GET_INFO 10179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define SO_GET_ENTRIES IPT_SO_GET_ENTRIES 10279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define SO_GET_VERSION IPT_SO_GET_VERSION 10379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 10414da56743c6cdf25da35b7b5ca7a5d201771990dJan Engelhardt#define STANDARD_TARGET XT_STANDARD_TARGET 10579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define LABEL_RETURN IPTC_LABEL_RETURN 10679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define LABEL_ACCEPT IPTC_LABEL_ACCEPT 10779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define LABEL_DROP IPTC_LABEL_DROP 1083eee010524ae02a3f0786b6d02bef16ab122e1c3Rusty Russell#define LABEL_QUEUE IPTC_LABEL_QUEUE 10979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 110dcd1ad89105faf1f3a9a3febdb970b70c5466518Jan Engelhardt#define ALIGN XT_ALIGN 11114da56743c6cdf25da35b7b5ca7a5d201771990dJan Engelhardt#define RETURN XT_RETURN 11279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 11379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#include "libiptc.c" 11479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 11579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define IP_PARTS_NATIVE(n) \ 11679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell(unsigned int)((n)>>24)&0xFF, \ 11779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell(unsigned int)((n)>>16)&0xFF, \ 11879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell(unsigned int)((n)>>8)&0xFF, \ 11979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell(unsigned int)((n)&0xFF) 12079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 12179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define IP_PARTS(n) IP_PARTS_NATIVE(ntohl(n)) 12279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 123390755ded5e4e8b0dcfa97443a95268bfa03e952Dmitry V. Levinstatic int 1241639fe86579f86f5f6a954a9b0adde2e16ad1980Jan Engelhardtdump_entry(struct ipt_entry *e, struct xtc_handle *const handle) 12579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell{ 12679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell size_t i; 12779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell STRUCT_ENTRY_TARGET *t; 12879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 129aae69bed019826ddec93f761514652a93d871e49Harald Welte printf("Entry %u (%lu):\n", iptcb_entry2index(handle, e), 130aae69bed019826ddec93f761514652a93d871e49Harald Welte iptcb_entry2offset(handle, e)); 13179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell printf("SRC IP: %u.%u.%u.%u/%u.%u.%u.%u\n", 13279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell IP_PARTS(e->ip.src.s_addr),IP_PARTS(e->ip.smsk.s_addr)); 13379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell printf("DST IP: %u.%u.%u.%u/%u.%u.%u.%u\n", 13479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell IP_PARTS(e->ip.dst.s_addr),IP_PARTS(e->ip.dmsk.s_addr)); 13579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell printf("Interface: `%s'/", e->ip.iniface); 13679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell for (i = 0; i < IFNAMSIZ; i++) 13779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell printf("%c", e->ip.iniface_mask[i] ? 'X' : '.'); 13879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell printf("to `%s'/", e->ip.outiface); 13979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell for (i = 0; i < IFNAMSIZ; i++) 14079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell printf("%c", e->ip.outiface_mask[i] ? 'X' : '.'); 14179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell printf("\nProtocol: %u\n", e->ip.proto); 14279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell printf("Flags: %02X\n", e->ip.flags); 14379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell printf("Invflags: %02X\n", e->ip.invflags); 14479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell printf("Counters: %llu packets, %llu bytes\n", 145a28d495285ad7dd9f286d63958cf20d74eec6bcbMartin Josefsson (unsigned long long)e->counters.pcnt, (unsigned long long)e->counters.bcnt); 146ea146a982e26c42f9954f140276f8deeb2edbe98Peter Riley printf("Cache: %08X\n", e->nfcache); 14779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 14879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell IPT_MATCH_ITERATE(e, print_match); 14979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 15079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell t = GET_TARGET(e); 15179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell printf("Target name: `%s' [%u]\n", t->u.user.name, t->u.target_size); 15279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell if (strcmp(t->u.user.name, STANDARD_TARGET) == 0) { 15351651b64fffc58d4f58d005fa7dc0d9669147c57Jan Engelhardt const unsigned char *data = t->data; 15451651b64fffc58d4f58d005fa7dc0d9669147c57Jan Engelhardt int pos = *(const int *)data; 15579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell if (pos < 0) 15679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell printf("verdict=%s\n", 15779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell pos == -NF_ACCEPT-1 ? "NF_ACCEPT" 15879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell : pos == -NF_DROP-1 ? "NF_DROP" 15979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell : pos == -NF_QUEUE-1 ? "NF_QUEUE" 16079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell : pos == RETURN ? "RETURN" 16179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell : "UNKNOWN"); 16279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell else 16379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell printf("verdict=%u\n", pos); 16414da56743c6cdf25da35b7b5ca7a5d201771990dJan Engelhardt } else if (strcmp(t->u.user.name, XT_ERROR_TARGET) == 0) 16579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell printf("error=`%s'\n", t->data); 16679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 16779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell printf("\n"); 16879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell return 0; 16979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell} 17079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 171733e54b8250576d6a1e0ab5621ef5b144abdf018Rusty Russellstatic unsigned char * 17279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russellis_same(const STRUCT_ENTRY *a, const STRUCT_ENTRY *b, unsigned char *matchmask) 17379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell{ 17479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell unsigned int i; 17579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell unsigned char *mptr; 17679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 17779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell /* Always compare head structures: ignore mask here. */ 17879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell if (a->ip.src.s_addr != b->ip.src.s_addr 17979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell || a->ip.dst.s_addr != b->ip.dst.s_addr 18079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell || a->ip.smsk.s_addr != b->ip.smsk.s_addr 1814f8d2d95056b50a2d05eff0245fe1ddd8c382b05Marc Boucher || a->ip.dmsk.s_addr != b->ip.dmsk.s_addr 18279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell || a->ip.proto != b->ip.proto 18379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell || a->ip.flags != b->ip.flags 18479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell || a->ip.invflags != b->ip.invflags) 185733e54b8250576d6a1e0ab5621ef5b144abdf018Rusty Russell return NULL; 18679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 18779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell for (i = 0; i < IFNAMSIZ; i++) { 18879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell if (a->ip.iniface_mask[i] != b->ip.iniface_mask[i]) 189733e54b8250576d6a1e0ab5621ef5b144abdf018Rusty Russell return NULL; 19079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell if ((a->ip.iniface[i] & a->ip.iniface_mask[i]) 19179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell != (b->ip.iniface[i] & b->ip.iniface_mask[i])) 192733e54b8250576d6a1e0ab5621ef5b144abdf018Rusty Russell return NULL; 19379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell if (a->ip.outiface_mask[i] != b->ip.outiface_mask[i]) 194733e54b8250576d6a1e0ab5621ef5b144abdf018Rusty Russell return NULL; 19579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell if ((a->ip.outiface[i] & a->ip.outiface_mask[i]) 19679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell != (b->ip.outiface[i] & b->ip.outiface_mask[i])) 197733e54b8250576d6a1e0ab5621ef5b144abdf018Rusty Russell return NULL; 19879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell } 19979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 200ea146a982e26c42f9954f140276f8deeb2edbe98Peter Riley if (a->target_offset != b->target_offset 20179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell || a->next_offset != b->next_offset) 202733e54b8250576d6a1e0ab5621ef5b144abdf018Rusty Russell return NULL; 20379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 20479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell mptr = matchmask + sizeof(STRUCT_ENTRY); 20579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell if (IPT_MATCH_ITERATE(a, match_different, a->elems, b->elems, &mptr)) 206733e54b8250576d6a1e0ab5621ef5b144abdf018Rusty Russell return NULL; 20714da56743c6cdf25da35b7b5ca7a5d201771990dJan Engelhardt mptr += XT_ALIGN(sizeof(struct xt_entry_target)); 20879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 209733e54b8250576d6a1e0ab5621ef5b144abdf018Rusty Russell return mptr; 21079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell} 21179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 212aae69bed019826ddec93f761514652a93d871e49Harald Welte#if 0 21379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell/***************************** DEBUGGING ********************************/ 21479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russellstatic inline int 21579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russellunconditional(const struct ipt_ip *ip) 21679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell{ 21779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell unsigned int i; 21879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 2197ac405297ec38449b30e3b05fd6bf2082fd3d803Jan Engelhardt for (i = 0; i < sizeof(*ip)/sizeof(uint32_t); i++) 2207ac405297ec38449b30e3b05fd6bf2082fd3d803Jan Engelhardt if (((uint32_t *)ip)[i]) 22179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell return 0; 22279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 22379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell return 1; 22479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell} 22579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 22679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russellstatic inline int 22779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russellcheck_match(const STRUCT_ENTRY_MATCH *m, unsigned int *off) 22879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell{ 22979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(m->u.match_size >= sizeof(STRUCT_ENTRY_MATCH)); 23079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(ALIGN(m->u.match_size) == m->u.match_size); 23179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 23279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell (*off) += m->u.match_size; 23379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell return 0; 23479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell} 23579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 23679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russellstatic inline int 23779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russellcheck_entry(const STRUCT_ENTRY *e, unsigned int *i, unsigned int *off, 23879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell unsigned int user_offset, int *was_return, 2391639fe86579f86f5f6a954a9b0adde2e16ad1980Jan Engelhardt struct xtc_handle *h) 24079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell{ 24179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell unsigned int toff; 24279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell STRUCT_STANDARD_TARGET *t; 24379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 24479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(e->target_offset >= sizeof(STRUCT_ENTRY)); 24579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(e->next_offset >= e->target_offset 24679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell + sizeof(STRUCT_ENTRY_TARGET)); 24779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell toff = sizeof(STRUCT_ENTRY); 24879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell IPT_MATCH_ITERATE(e, check_match, &toff); 24979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 25079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(toff == e->target_offset); 25179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 25279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell t = (STRUCT_STANDARD_TARGET *) 25379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell GET_TARGET((STRUCT_ENTRY *)e); 25479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell /* next_offset will have to be multiple of entry alignment. */ 25579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(e->next_offset == ALIGN(e->next_offset)); 25679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(e->target_offset == ALIGN(e->target_offset)); 25779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(t->target.u.target_size == ALIGN(t->target.u.target_size)); 25879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(!TC_IS_CHAIN(t->target.u.user.name, h)); 25979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 26079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell if (strcmp(t->target.u.user.name, STANDARD_TARGET) == 0) { 26179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(t->target.u.target_size 26279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell == ALIGN(sizeof(STRUCT_STANDARD_TARGET))); 26379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 26479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(t->verdict == -NF_DROP-1 26579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell || t->verdict == -NF_ACCEPT-1 26679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell || t->verdict == RETURN 267aae69bed019826ddec93f761514652a93d871e49Harald Welte || t->verdict < (int)h->entries->size); 26879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 26979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell if (t->verdict >= 0) { 27079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell STRUCT_ENTRY *te = get_entry(h, t->verdict); 27179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell int idx; 27279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 273aae69bed019826ddec93f761514652a93d871e49Harald Welte idx = iptcb_entry2index(h, te); 27479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(strcmp(GET_TARGET(te)->u.user.name, 27514da56743c6cdf25da35b7b5ca7a5d201771990dJan Engelhardt XT_ERROR_TARGET) 27679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell != 0); 27779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(te != e); 27879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 27979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell /* Prior node must be error node, or this node. */ 280aae69bed019826ddec93f761514652a93d871e49Harald Welte assert(t->verdict == iptcb_entry2offset(h, e)+e->next_offset 28179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell || strcmp(GET_TARGET(index2entry(h, idx-1)) 28214da56743c6cdf25da35b7b5ca7a5d201771990dJan Engelhardt ->u.user.name, XT_ERROR_TARGET) 28379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell == 0); 28479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell } 28579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 28679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell if (t->verdict == RETURN 28779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell && unconditional(&e->ip) 28879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell && e->target_offset == sizeof(*e)) 28979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell *was_return = 1; 29079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell else 29179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell *was_return = 0; 29214da56743c6cdf25da35b7b5ca7a5d201771990dJan Engelhardt } else if (strcmp(t->target.u.user.name, XT_ERROR_TARGET) == 0) { 29379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(t->target.u.target_size 29479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell == ALIGN(sizeof(struct ipt_error_target))); 29579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 29679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell /* If this is in user area, previous must have been return */ 29779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell if (*off > user_offset) 29879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(*was_return); 29979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 30079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell *was_return = 0; 30179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell } 30279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell else *was_return = 0; 30379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 30479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell if (*off == user_offset) 30514da56743c6cdf25da35b7b5ca7a5d201771990dJan Engelhardt assert(strcmp(t->target.u.user.name, XT_ERROR_TARGET) == 0); 30679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 30779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell (*off) += e->next_offset; 30879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell (*i)++; 30979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell return 0; 31079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell} 31179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 312380ba5f3074a16fbaa8869d9594962d58b5f8608Harald Welte#ifdef IPTC_DEBUG 31379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell/* Do every conceivable sanity check on the handle */ 31479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russellstatic void 3151639fe86579f86f5f6a954a9b0adde2e16ad1980Jan Engelhardtdo_check(struct xtc_handle *h, unsigned int line) 31679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell{ 31779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell unsigned int i, n; 31879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell unsigned int user_offset; /* Offset of first user chain */ 31979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell int was_return; 32079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 32179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(h->changed == 0 || h->changed == 1); 32279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell if (strcmp(h->info.name, "filter") == 0) { 32379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(h->info.valid_hooks 32479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell == (1 << NF_IP_LOCAL_IN 32579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell | 1 << NF_IP_FORWARD 32679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell | 1 << NF_IP_LOCAL_OUT)); 32779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 32879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell /* Hooks should be first three */ 32979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(h->info.hook_entry[NF_IP_LOCAL_IN] == 0); 33079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 33179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell n = get_chain_end(h, 0); 33279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell n += get_entry(h, n)->next_offset; 33379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(h->info.hook_entry[NF_IP_FORWARD] == n); 33479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 33579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell n = get_chain_end(h, n); 33679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell n += get_entry(h, n)->next_offset; 33779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(h->info.hook_entry[NF_IP_LOCAL_OUT] == n); 33879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 33979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell user_offset = h->info.hook_entry[NF_IP_LOCAL_OUT]; 34079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell } else if (strcmp(h->info.name, "nat") == 0) { 34195df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte assert((h->info.valid_hooks 34295df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte == (1 << NF_IP_PRE_ROUTING 34395df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte | 1 << NF_IP_POST_ROUTING 34495df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte | 1 << NF_IP_LOCAL_OUT)) || 34595df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte (h->info.valid_hooks 34695df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte == (1 << NF_IP_PRE_ROUTING 34795df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte | 1 << NF_IP_LOCAL_IN 34895df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte | 1 << NF_IP_POST_ROUTING 34995df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte | 1 << NF_IP_LOCAL_OUT))); 35079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 35179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(h->info.hook_entry[NF_IP_PRE_ROUTING] == 0); 35279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 35379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell n = get_chain_end(h, 0); 35495df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte 35579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell n += get_entry(h, n)->next_offset; 35679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(h->info.hook_entry[NF_IP_POST_ROUTING] == n); 35779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell n = get_chain_end(h, n); 35895df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte 35979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell n += get_entry(h, n)->next_offset; 36079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(h->info.hook_entry[NF_IP_LOCAL_OUT] == n); 36179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell user_offset = h->info.hook_entry[NF_IP_LOCAL_OUT]; 36295df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte 36395df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte if (h->info.valid_hooks & (1 << NF_IP_LOCAL_IN)) { 36495df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte n = get_chain_end(h, n); 36595df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte n += get_entry(h, n)->next_offset; 36695df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte assert(h->info.hook_entry[NF_IP_LOCAL_IN] == n); 36795df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte user_offset = h->info.hook_entry[NF_IP_LOCAL_IN]; 36895df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte } 36995df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte 37079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell } else if (strcmp(h->info.name, "mangle") == 0) { 371596707cf8374dba73535bc77bae76fe8770c0028Harald Welte /* This code is getting ugly because linux < 2.4.18-pre6 had 372596707cf8374dba73535bc77bae76fe8770c0028Harald Welte * two mangle hooks, linux >= 2.4.18-pre6 has five mangle hooks 373596707cf8374dba73535bc77bae76fe8770c0028Harald Welte * */ 37495df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte assert((h->info.valid_hooks 37595df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte == (1 << NF_IP_PRE_ROUTING 37695df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte | 1 << NF_IP_LOCAL_OUT)) || 37795df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte (h->info.valid_hooks 37895df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte == (1 << NF_IP_PRE_ROUTING 37995df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte | 1 << NF_IP_LOCAL_IN 38095df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte | 1 << NF_IP_FORWARD 38195df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte | 1 << NF_IP_LOCAL_OUT 38295df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte | 1 << NF_IP_POST_ROUTING))); 38379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 384380ba5f3074a16fbaa8869d9594962d58b5f8608Harald Welte /* Hooks should be first five */ 38579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(h->info.hook_entry[NF_IP_PRE_ROUTING] == 0); 38679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 38779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell n = get_chain_end(h, 0); 388380ba5f3074a16fbaa8869d9594962d58b5f8608Harald Welte 389a540b1b15e0d63ab10555502fcd569b40eec8145Harald Welte if (h->info.valid_hooks & (1 << NF_IP_LOCAL_IN)) { 390596707cf8374dba73535bc77bae76fe8770c0028Harald Welte n += get_entry(h, n)->next_offset; 391596707cf8374dba73535bc77bae76fe8770c0028Harald Welte assert(h->info.hook_entry[NF_IP_LOCAL_IN] == n); 392596707cf8374dba73535bc77bae76fe8770c0028Harald Welte n = get_chain_end(h, n); 393596707cf8374dba73535bc77bae76fe8770c0028Harald Welte } 394596707cf8374dba73535bc77bae76fe8770c0028Harald Welte 395a540b1b15e0d63ab10555502fcd569b40eec8145Harald Welte if (h->info.valid_hooks & (1 << NF_IP_FORWARD)) { 396596707cf8374dba73535bc77bae76fe8770c0028Harald Welte n += get_entry(h, n)->next_offset; 397596707cf8374dba73535bc77bae76fe8770c0028Harald Welte assert(h->info.hook_entry[NF_IP_FORWARD] == n); 398596707cf8374dba73535bc77bae76fe8770c0028Harald Welte n = get_chain_end(h, n); 399596707cf8374dba73535bc77bae76fe8770c0028Harald Welte } 400380ba5f3074a16fbaa8869d9594962d58b5f8608Harald Welte 401380ba5f3074a16fbaa8869d9594962d58b5f8608Harald Welte n += get_entry(h, n)->next_offset; 40279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(h->info.hook_entry[NF_IP_LOCAL_OUT] == n); 403596707cf8374dba73535bc77bae76fe8770c0028Harald Welte user_offset = h->info.hook_entry[NF_IP_LOCAL_OUT]; 40479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 405a540b1b15e0d63ab10555502fcd569b40eec8145Harald Welte if (h->info.valid_hooks & (1 << NF_IP_POST_ROUTING)) { 406596707cf8374dba73535bc77bae76fe8770c0028Harald Welte n = get_chain_end(h, n); 407596707cf8374dba73535bc77bae76fe8770c0028Harald Welte n += get_entry(h, n)->next_offset; 408596707cf8374dba73535bc77bae76fe8770c0028Harald Welte assert(h->info.hook_entry[NF_IP_POST_ROUTING] == n); 409596707cf8374dba73535bc77bae76fe8770c0028Harald Welte user_offset = h->info.hook_entry[NF_IP_POST_ROUTING]; 410596707cf8374dba73535bc77bae76fe8770c0028Harald Welte } 4114dc734c73cc4a0ff87c0ce3673544628b58c7e24Harald Welte } else if (strcmp(h->info.name, "raw") == 0) { 4124dc734c73cc4a0ff87c0ce3673544628b58c7e24Harald Welte assert(h->info.valid_hooks 4134dc734c73cc4a0ff87c0ce3673544628b58c7e24Harald Welte == (1 << NF_IP_PRE_ROUTING 4144dc734c73cc4a0ff87c0ce3673544628b58c7e24Harald Welte | 1 << NF_IP_LOCAL_OUT)); 4154dc734c73cc4a0ff87c0ce3673544628b58c7e24Harald Welte 4164dc734c73cc4a0ff87c0ce3673544628b58c7e24Harald Welte /* Hooks should be first three */ 4174dc734c73cc4a0ff87c0ce3673544628b58c7e24Harald Welte assert(h->info.hook_entry[NF_IP_PRE_ROUTING] == 0); 4184dc734c73cc4a0ff87c0ce3673544628b58c7e24Harald Welte 4194dc734c73cc4a0ff87c0ce3673544628b58c7e24Harald Welte n = get_chain_end(h, n); 4204dc734c73cc4a0ff87c0ce3673544628b58c7e24Harald Welte n += get_entry(h, n)->next_offset; 4214dc734c73cc4a0ff87c0ce3673544628b58c7e24Harald Welte assert(h->info.hook_entry[NF_IP_LOCAL_OUT] == n); 4224dc734c73cc4a0ff87c0ce3673544628b58c7e24Harald Welte 4234dc734c73cc4a0ff87c0ce3673544628b58c7e24Harald Welte user_offset = h->info.hook_entry[NF_IP_LOCAL_OUT]; 424f92ba9bd4e68659e3c98aa0164cac87540ab3a76Rusty Russell } else { 425e9b4853639bffb0e71d5f7da93736aa8ae34f79bRusty Russell fprintf(stderr, "Unknown table `%s'\n", h->info.name); 42679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell abort(); 427f92ba9bd4e68659e3c98aa0164cac87540ab3a76Rusty Russell } 42879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 42979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell /* User chain == end of last builtin + policy entry */ 43079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell user_offset = get_chain_end(h, user_offset); 43179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell user_offset += get_entry(h, user_offset)->next_offset; 43279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 43379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell /* Overflows should be end of entry chains, and unconditional 43479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell policy nodes. */ 43579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell for (i = 0; i < NUMHOOKS; i++) { 43679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell STRUCT_ENTRY *e; 43779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell STRUCT_STANDARD_TARGET *t; 43879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 43979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell if (!(h->info.valid_hooks & (1 << i))) 44079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell continue; 44179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(h->info.underflow[i] 44279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell == get_chain_end(h, h->info.hook_entry[i])); 44379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 44479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell e = get_entry(h, get_chain_end(h, h->info.hook_entry[i])); 44579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(unconditional(&e->ip)); 44679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(e->target_offset == sizeof(*e)); 44779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell t = (STRUCT_STANDARD_TARGET *)GET_TARGET(e); 448a540b1b15e0d63ab10555502fcd569b40eec8145Harald Welte assert(t->target.u.target_size == ALIGN(sizeof(*t))); 449a540b1b15e0d63ab10555502fcd569b40eec8145Harald Welte assert(e->next_offset == sizeof(*e) + ALIGN(sizeof(*t))); 45079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 45179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(strcmp(t->target.u.user.name, STANDARD_TARGET)==0); 45279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(t->verdict == -NF_DROP-1 || t->verdict == -NF_ACCEPT-1); 45379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 45479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell /* Hooks and underflows must be valid entries */ 45579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell entry2index(h, get_entry(h, h->info.hook_entry[i])); 45679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell entry2index(h, get_entry(h, h->info.underflow[i])); 45779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell } 45879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 45979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(h->info.size 46079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell >= h->info.num_entries * (sizeof(STRUCT_ENTRY) 46179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell +sizeof(STRUCT_STANDARD_TARGET))); 46279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 46379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(h->entries.size 46479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell >= (h->new_number 46579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell * (sizeof(STRUCT_ENTRY) 46679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell + sizeof(STRUCT_STANDARD_TARGET)))); 46779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(strcmp(h->info.name, h->entries.name) == 0); 46879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 46979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell i = 0; n = 0; 47079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell was_return = 0; 47179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell /* Check all the entries. */ 472725d97a79cf0b332ed45cb7d254915178328427dRusty Russell ENTRY_ITERATE(h->entries.entrytable, h->entries.size, 47379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell check_entry, &i, &n, user_offset, &was_return, h); 47479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 47579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(i == h->new_number); 47679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(n == h->entries.size); 47779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 47879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell /* Final entry must be error node */ 47979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(strcmp(GET_TARGET(index2entry(h, h->new_number-1)) 48079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell ->u.user.name, 481a540b1b15e0d63ab10555502fcd569b40eec8145Harald Welte ERROR_TARGET) == 0); 48279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell} 483380ba5f3074a16fbaa8869d9594962d58b5f8608Harald Welte#endif /*IPTC_DEBUG*/ 484aae69bed019826ddec93f761514652a93d871e49Harald Welte 485aae69bed019826ddec93f761514652a93d871e49Harald Welte#endif 486