libip4tc.c revision 51651b64fffc58d4f58d005fa7dc0d9669147c57
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 2579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#if !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 3910758b743d6aa076ebe2c3e8f855e73826841e71Rusty Russell#ifdef NF_IP_DROPPING 4010758b743d6aa076ebe2c3e8f855e73826841e71Rusty Russell#define HOOK_DROPPING NF_IP_DROPPING 4110758b743d6aa076ebe2c3e8f855e73826841e71Rusty Russell#endif 4279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 4379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define STRUCT_ENTRY_TARGET struct ipt_entry_target 4479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define STRUCT_ENTRY struct ipt_entry 4579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define STRUCT_ENTRY_MATCH struct ipt_entry_match 4679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define STRUCT_GETINFO struct ipt_getinfo 4779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define STRUCT_GET_ENTRIES struct ipt_get_entries 4879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define STRUCT_COUNTERS struct ipt_counters 4979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define STRUCT_COUNTERS_INFO struct ipt_counters_info 5079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define STRUCT_STANDARD_TARGET struct ipt_standard_target 5179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define STRUCT_REPLACE struct ipt_replace 5279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 5379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define STRUCT_TC_HANDLE struct iptc_handle 54fd1873110f8e57be578df17fc9d03536b10f4f73Jan Engelhardt#define xtc_handle iptc_handle 5579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 5679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define ENTRY_ITERATE IPT_ENTRY_ITERATE 5779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TABLE_MAXNAMELEN IPT_TABLE_MAXNAMELEN 5879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define FUNCTION_MAXNAMELEN IPT_FUNCTION_MAXNAMELEN 5979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 6079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define GET_TARGET ipt_get_target 6179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 6279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define ERROR_TARGET IPT_ERROR_TARGET 6379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define NUMHOOKS NF_IP_NUMHOOKS 6479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 6579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define IPT_CHAINLABEL ipt_chainlabel 6679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 6779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_DUMP_ENTRIES dump_entries 6879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_IS_CHAIN iptc_is_chain 698c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell#define TC_FIRST_CHAIN iptc_first_chain 7079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_NEXT_CHAIN iptc_next_chain 718c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell#define TC_FIRST_RULE iptc_first_rule 728c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell#define TC_NEXT_RULE iptc_next_rule 7379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_GET_TARGET iptc_get_target 7479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_BUILTIN iptc_builtin 7579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_GET_POLICY iptc_get_policy 7679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_INSERT_ENTRY iptc_insert_entry 7779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_REPLACE_ENTRY iptc_replace_entry 7879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_APPEND_ENTRY iptc_append_entry 7979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_DELETE_ENTRY iptc_delete_entry 8079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_DELETE_NUM_ENTRY iptc_delete_num_entry 8179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_FLUSH_ENTRIES iptc_flush_entries 8279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_ZERO_ENTRIES iptc_zero_entries 831cef74d943055668b5e356eebea877fdaa1ce3e0Harald Welte#define TC_READ_COUNTER iptc_read_counter 841cef74d943055668b5e356eebea877fdaa1ce3e0Harald Welte#define TC_ZERO_COUNTER iptc_zero_counter 851cef74d943055668b5e356eebea877fdaa1ce3e0Harald Welte#define TC_SET_COUNTER iptc_set_counter 8679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_CREATE_CHAIN iptc_create_chain 8779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_GET_REFERENCES iptc_get_references 8879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_DELETE_CHAIN iptc_delete_chain 8979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_RENAME_CHAIN iptc_rename_chain 9079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_SET_POLICY iptc_set_policy 9179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_GET_RAW_SOCKET iptc_get_raw_socket 9279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_INIT iptc_init 93841e4aed2349046eb2c0b1375139c06569a93bd0Martin Josefsson#define TC_FREE iptc_free 9479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_COMMIT iptc_commit 9579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_STRERROR iptc_strerror 9670067291528bb949fac8a584e782f2b4c38e4c16Phil Oester#define TC_NUM_RULES iptc_num_rules 9770067291528bb949fac8a584e782f2b4c38e4c16Phil Oester#define TC_GET_RULE iptc_get_rule 9879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 9979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_AF AF_INET 10079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_IPPROTO IPPROTO_IP 10179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 10279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define SO_SET_REPLACE IPT_SO_SET_REPLACE 10379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define SO_SET_ADD_COUNTERS IPT_SO_SET_ADD_COUNTERS 10479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define SO_GET_INFO IPT_SO_GET_INFO 10579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define SO_GET_ENTRIES IPT_SO_GET_ENTRIES 10679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define SO_GET_VERSION IPT_SO_GET_VERSION 10779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 10879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define STANDARD_TARGET IPT_STANDARD_TARGET 10979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define LABEL_RETURN IPTC_LABEL_RETURN 11079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define LABEL_ACCEPT IPTC_LABEL_ACCEPT 11179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define LABEL_DROP IPTC_LABEL_DROP 1123eee010524ae02a3f0786b6d02bef16ab122e1c3Rusty Russell#define LABEL_QUEUE IPTC_LABEL_QUEUE 11379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 11479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define ALIGN IPT_ALIGN 11579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define RETURN IPT_RETURN 11679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 11779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#include "libiptc.c" 11879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 11979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define IP_PARTS_NATIVE(n) \ 12079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell(unsigned int)((n)>>24)&0xFF, \ 12179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell(unsigned int)((n)>>16)&0xFF, \ 12279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell(unsigned int)((n)>>8)&0xFF, \ 12379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell(unsigned int)((n)&0xFF) 12479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 12579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define IP_PARTS(n) IP_PARTS_NATIVE(ntohl(n)) 12679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 12779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russellint 128fd1873110f8e57be578df17fc9d03536b10f4f73Jan Engelhardtdump_entry(STRUCT_ENTRY *e, struct iptc_handle *const handle) 12979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell{ 13079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell size_t i; 13179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell STRUCT_ENTRY_TARGET *t; 13279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 133aae69bed019826ddec93f761514652a93d871e49Harald Welte printf("Entry %u (%lu):\n", iptcb_entry2index(handle, e), 134aae69bed019826ddec93f761514652a93d871e49Harald Welte iptcb_entry2offset(handle, e)); 13579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell printf("SRC IP: %u.%u.%u.%u/%u.%u.%u.%u\n", 13679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell IP_PARTS(e->ip.src.s_addr),IP_PARTS(e->ip.smsk.s_addr)); 13779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell printf("DST IP: %u.%u.%u.%u/%u.%u.%u.%u\n", 13879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell IP_PARTS(e->ip.dst.s_addr),IP_PARTS(e->ip.dmsk.s_addr)); 13979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell printf("Interface: `%s'/", e->ip.iniface); 14079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell for (i = 0; i < IFNAMSIZ; i++) 14179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell printf("%c", e->ip.iniface_mask[i] ? 'X' : '.'); 14279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell printf("to `%s'/", e->ip.outiface); 14379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell for (i = 0; i < IFNAMSIZ; i++) 14479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell printf("%c", e->ip.outiface_mask[i] ? 'X' : '.'); 14579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell printf("\nProtocol: %u\n", e->ip.proto); 14679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell printf("Flags: %02X\n", e->ip.flags); 14779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell printf("Invflags: %02X\n", e->ip.invflags); 14879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell printf("Counters: %llu packets, %llu bytes\n", 149a28d495285ad7dd9f286d63958cf20d74eec6bcbMartin Josefsson (unsigned long long)e->counters.pcnt, (unsigned long long)e->counters.bcnt); 150ea146a982e26c42f9954f140276f8deeb2edbe98Peter Riley printf("Cache: %08X\n", e->nfcache); 15179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 15279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell IPT_MATCH_ITERATE(e, print_match); 15379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 15479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell t = GET_TARGET(e); 15579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell printf("Target name: `%s' [%u]\n", t->u.user.name, t->u.target_size); 15679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell if (strcmp(t->u.user.name, STANDARD_TARGET) == 0) { 15751651b64fffc58d4f58d005fa7dc0d9669147c57Jan Engelhardt const unsigned char *data = t->data; 15851651b64fffc58d4f58d005fa7dc0d9669147c57Jan Engelhardt int pos = *(const int *)data; 15979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell if (pos < 0) 16079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell printf("verdict=%s\n", 16179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell pos == -NF_ACCEPT-1 ? "NF_ACCEPT" 16279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell : pos == -NF_DROP-1 ? "NF_DROP" 16379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell : pos == -NF_QUEUE-1 ? "NF_QUEUE" 16479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell : pos == RETURN ? "RETURN" 16579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell : "UNKNOWN"); 16679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell else 16779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell printf("verdict=%u\n", pos); 16879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell } else if (strcmp(t->u.user.name, IPT_ERROR_TARGET) == 0) 16979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell printf("error=`%s'\n", t->data); 17079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 17179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell printf("\n"); 17279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell return 0; 17379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell} 17479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 175733e54b8250576d6a1e0ab5621ef5b144abdf018Rusty Russellstatic unsigned char * 17679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russellis_same(const STRUCT_ENTRY *a, const STRUCT_ENTRY *b, unsigned char *matchmask) 17779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell{ 17879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell unsigned int i; 17979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell unsigned char *mptr; 18079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 18179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell /* Always compare head structures: ignore mask here. */ 18279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell if (a->ip.src.s_addr != b->ip.src.s_addr 18379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell || a->ip.dst.s_addr != b->ip.dst.s_addr 18479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell || a->ip.smsk.s_addr != b->ip.smsk.s_addr 1854f8d2d95056b50a2d05eff0245fe1ddd8c382b05Marc Boucher || a->ip.dmsk.s_addr != b->ip.dmsk.s_addr 18679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell || a->ip.proto != b->ip.proto 18779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell || a->ip.flags != b->ip.flags 18879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell || a->ip.invflags != b->ip.invflags) 189733e54b8250576d6a1e0ab5621ef5b144abdf018Rusty Russell return NULL; 19079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 19179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell for (i = 0; i < IFNAMSIZ; i++) { 19279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell if (a->ip.iniface_mask[i] != b->ip.iniface_mask[i]) 193733e54b8250576d6a1e0ab5621ef5b144abdf018Rusty Russell return NULL; 19479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell if ((a->ip.iniface[i] & a->ip.iniface_mask[i]) 19579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell != (b->ip.iniface[i] & b->ip.iniface_mask[i])) 196733e54b8250576d6a1e0ab5621ef5b144abdf018Rusty Russell return NULL; 19779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell if (a->ip.outiface_mask[i] != b->ip.outiface_mask[i]) 198733e54b8250576d6a1e0ab5621ef5b144abdf018Rusty Russell return NULL; 19979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell if ((a->ip.outiface[i] & a->ip.outiface_mask[i]) 20079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell != (b->ip.outiface[i] & b->ip.outiface_mask[i])) 201733e54b8250576d6a1e0ab5621ef5b144abdf018Rusty Russell return NULL; 20279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell } 20379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 204ea146a982e26c42f9954f140276f8deeb2edbe98Peter Riley if (a->target_offset != b->target_offset 20579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell || a->next_offset != b->next_offset) 206733e54b8250576d6a1e0ab5621ef5b144abdf018Rusty Russell return NULL; 20779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 20879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell mptr = matchmask + sizeof(STRUCT_ENTRY); 20979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell if (IPT_MATCH_ITERATE(a, match_different, a->elems, b->elems, &mptr)) 210733e54b8250576d6a1e0ab5621ef5b144abdf018Rusty Russell return NULL; 2115ee88622ef8f38e5f6b6c60ca1ab61d8f93a0e82Pablo Neira mptr += IPT_ALIGN(sizeof(struct ipt_entry_target)); 21279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 213733e54b8250576d6a1e0ab5621ef5b144abdf018Rusty Russell return mptr; 21479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell} 21579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 216aae69bed019826ddec93f761514652a93d871e49Harald Welte#if 0 21779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell/***************************** DEBUGGING ********************************/ 21879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russellstatic inline int 21979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russellunconditional(const struct ipt_ip *ip) 22079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell{ 22179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell unsigned int i; 22279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 22379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell for (i = 0; i < sizeof(*ip)/sizeof(u_int32_t); i++) 22479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell if (((u_int32_t *)ip)[i]) 22579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell return 0; 22679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 22779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell return 1; 22879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell} 22979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 23079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russellstatic inline int 23179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russellcheck_match(const STRUCT_ENTRY_MATCH *m, unsigned int *off) 23279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell{ 23379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(m->u.match_size >= sizeof(STRUCT_ENTRY_MATCH)); 23479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(ALIGN(m->u.match_size) == m->u.match_size); 23579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 23679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell (*off) += m->u.match_size; 23779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell return 0; 23879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell} 23979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 24079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russellstatic inline int 24179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russellcheck_entry(const STRUCT_ENTRY *e, unsigned int *i, unsigned int *off, 24279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell unsigned int user_offset, int *was_return, 243fd1873110f8e57be578df17fc9d03536b10f4f73Jan Engelhardt struct iptc_handle *h) 24479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell{ 24579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell unsigned int toff; 24679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell STRUCT_STANDARD_TARGET *t; 24779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 24879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(e->target_offset >= sizeof(STRUCT_ENTRY)); 24979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(e->next_offset >= e->target_offset 25079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell + sizeof(STRUCT_ENTRY_TARGET)); 25179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell toff = sizeof(STRUCT_ENTRY); 25279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell IPT_MATCH_ITERATE(e, check_match, &toff); 25379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 25479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(toff == e->target_offset); 25579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 25679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell t = (STRUCT_STANDARD_TARGET *) 25779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell GET_TARGET((STRUCT_ENTRY *)e); 25879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell /* next_offset will have to be multiple of entry alignment. */ 25979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(e->next_offset == ALIGN(e->next_offset)); 26079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(e->target_offset == ALIGN(e->target_offset)); 26179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(t->target.u.target_size == ALIGN(t->target.u.target_size)); 26279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(!TC_IS_CHAIN(t->target.u.user.name, h)); 26379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 26479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell if (strcmp(t->target.u.user.name, STANDARD_TARGET) == 0) { 26579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(t->target.u.target_size 26679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell == ALIGN(sizeof(STRUCT_STANDARD_TARGET))); 26779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 26879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(t->verdict == -NF_DROP-1 26979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell || t->verdict == -NF_ACCEPT-1 27079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell || t->verdict == RETURN 271aae69bed019826ddec93f761514652a93d871e49Harald Welte || t->verdict < (int)h->entries->size); 27279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 27379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell if (t->verdict >= 0) { 27479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell STRUCT_ENTRY *te = get_entry(h, t->verdict); 27579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell int idx; 27679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 277aae69bed019826ddec93f761514652a93d871e49Harald Welte idx = iptcb_entry2index(h, te); 27879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(strcmp(GET_TARGET(te)->u.user.name, 27979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell IPT_ERROR_TARGET) 28079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell != 0); 28179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(te != e); 28279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 28379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell /* Prior node must be error node, or this node. */ 284aae69bed019826ddec93f761514652a93d871e49Harald Welte assert(t->verdict == iptcb_entry2offset(h, e)+e->next_offset 28579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell || strcmp(GET_TARGET(index2entry(h, idx-1)) 28679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell ->u.user.name, IPT_ERROR_TARGET) 28779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell == 0); 28879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell } 28979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 29079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell if (t->verdict == RETURN 29179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell && unconditional(&e->ip) 29279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell && e->target_offset == sizeof(*e)) 29379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell *was_return = 1; 29479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell else 29579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell *was_return = 0; 29679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell } else if (strcmp(t->target.u.user.name, IPT_ERROR_TARGET) == 0) { 29779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(t->target.u.target_size 29879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell == ALIGN(sizeof(struct ipt_error_target))); 29979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 30079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell /* If this is in user area, previous must have been return */ 30179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell if (*off > user_offset) 30279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(*was_return); 30379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 30479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell *was_return = 0; 30579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell } 30679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell else *was_return = 0; 30779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 30879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell if (*off == user_offset) 30979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(strcmp(t->target.u.user.name, IPT_ERROR_TARGET) == 0); 31079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 31179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell (*off) += e->next_offset; 31279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell (*i)++; 31379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell return 0; 31479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell} 31579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 316380ba5f3074a16fbaa8869d9594962d58b5f8608Harald Welte#ifdef IPTC_DEBUG 31779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell/* Do every conceivable sanity check on the handle */ 31879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russellstatic void 319fd1873110f8e57be578df17fc9d03536b10f4f73Jan Engelhardtdo_check(struct iptc_handle *h, unsigned int line) 32079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell{ 32179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell unsigned int i, n; 32279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell unsigned int user_offset; /* Offset of first user chain */ 32379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell int was_return; 32479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 32579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(h->changed == 0 || h->changed == 1); 32679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell if (strcmp(h->info.name, "filter") == 0) { 32779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(h->info.valid_hooks 32879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell == (1 << NF_IP_LOCAL_IN 32979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell | 1 << NF_IP_FORWARD 33079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell | 1 << NF_IP_LOCAL_OUT)); 33179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 33279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell /* Hooks should be first three */ 33379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(h->info.hook_entry[NF_IP_LOCAL_IN] == 0); 33479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 33579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell n = get_chain_end(h, 0); 33679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell n += get_entry(h, n)->next_offset; 33779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(h->info.hook_entry[NF_IP_FORWARD] == n); 33879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 33979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell n = get_chain_end(h, n); 34079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell n += get_entry(h, n)->next_offset; 34179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(h->info.hook_entry[NF_IP_LOCAL_OUT] == n); 34279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 34379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell user_offset = h->info.hook_entry[NF_IP_LOCAL_OUT]; 34479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell } else if (strcmp(h->info.name, "nat") == 0) { 34595df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte assert((h->info.valid_hooks 34695df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte == (1 << NF_IP_PRE_ROUTING 34795df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte | 1 << NF_IP_POST_ROUTING 34895df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte | 1 << NF_IP_LOCAL_OUT)) || 34995df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte (h->info.valid_hooks 35095df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte == (1 << NF_IP_PRE_ROUTING 35195df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte | 1 << NF_IP_LOCAL_IN 35295df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte | 1 << NF_IP_POST_ROUTING 35395df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte | 1 << NF_IP_LOCAL_OUT))); 35479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 35579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(h->info.hook_entry[NF_IP_PRE_ROUTING] == 0); 35679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 35779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell n = get_chain_end(h, 0); 35895df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte 35979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell n += get_entry(h, n)->next_offset; 36079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(h->info.hook_entry[NF_IP_POST_ROUTING] == n); 36179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell n = get_chain_end(h, n); 36295df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte 36379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell n += get_entry(h, n)->next_offset; 36479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(h->info.hook_entry[NF_IP_LOCAL_OUT] == n); 36579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell user_offset = h->info.hook_entry[NF_IP_LOCAL_OUT]; 36695df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte 36795df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte if (h->info.valid_hooks & (1 << NF_IP_LOCAL_IN)) { 36895df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte n = get_chain_end(h, n); 36995df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte n += get_entry(h, n)->next_offset; 37095df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte assert(h->info.hook_entry[NF_IP_LOCAL_IN] == n); 37195df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte user_offset = h->info.hook_entry[NF_IP_LOCAL_IN]; 37295df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte } 37395df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte 37479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell } else if (strcmp(h->info.name, "mangle") == 0) { 375596707cf8374dba73535bc77bae76fe8770c0028Harald Welte /* This code is getting ugly because linux < 2.4.18-pre6 had 376596707cf8374dba73535bc77bae76fe8770c0028Harald Welte * two mangle hooks, linux >= 2.4.18-pre6 has five mangle hooks 377596707cf8374dba73535bc77bae76fe8770c0028Harald Welte * */ 37895df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte assert((h->info.valid_hooks 37995df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte == (1 << NF_IP_PRE_ROUTING 38095df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte | 1 << NF_IP_LOCAL_OUT)) || 38195df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte (h->info.valid_hooks 38295df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte == (1 << NF_IP_PRE_ROUTING 38395df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte | 1 << NF_IP_LOCAL_IN 38495df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte | 1 << NF_IP_FORWARD 38595df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte | 1 << NF_IP_LOCAL_OUT 38695df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte | 1 << NF_IP_POST_ROUTING))); 38779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 388380ba5f3074a16fbaa8869d9594962d58b5f8608Harald Welte /* Hooks should be first five */ 38979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(h->info.hook_entry[NF_IP_PRE_ROUTING] == 0); 39079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 39179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell n = get_chain_end(h, 0); 392380ba5f3074a16fbaa8869d9594962d58b5f8608Harald Welte 393a540b1b15e0d63ab10555502fcd569b40eec8145Harald Welte if (h->info.valid_hooks & (1 << NF_IP_LOCAL_IN)) { 394596707cf8374dba73535bc77bae76fe8770c0028Harald Welte n += get_entry(h, n)->next_offset; 395596707cf8374dba73535bc77bae76fe8770c0028Harald Welte assert(h->info.hook_entry[NF_IP_LOCAL_IN] == n); 396596707cf8374dba73535bc77bae76fe8770c0028Harald Welte n = get_chain_end(h, n); 397596707cf8374dba73535bc77bae76fe8770c0028Harald Welte } 398596707cf8374dba73535bc77bae76fe8770c0028Harald Welte 399a540b1b15e0d63ab10555502fcd569b40eec8145Harald Welte if (h->info.valid_hooks & (1 << NF_IP_FORWARD)) { 400596707cf8374dba73535bc77bae76fe8770c0028Harald Welte n += get_entry(h, n)->next_offset; 401596707cf8374dba73535bc77bae76fe8770c0028Harald Welte assert(h->info.hook_entry[NF_IP_FORWARD] == n); 402596707cf8374dba73535bc77bae76fe8770c0028Harald Welte n = get_chain_end(h, n); 403596707cf8374dba73535bc77bae76fe8770c0028Harald Welte } 404380ba5f3074a16fbaa8869d9594962d58b5f8608Harald Welte 405380ba5f3074a16fbaa8869d9594962d58b5f8608Harald Welte n += get_entry(h, n)->next_offset; 40679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(h->info.hook_entry[NF_IP_LOCAL_OUT] == n); 407596707cf8374dba73535bc77bae76fe8770c0028Harald Welte user_offset = h->info.hook_entry[NF_IP_LOCAL_OUT]; 40879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 409a540b1b15e0d63ab10555502fcd569b40eec8145Harald Welte if (h->info.valid_hooks & (1 << NF_IP_POST_ROUTING)) { 410596707cf8374dba73535bc77bae76fe8770c0028Harald Welte n = get_chain_end(h, n); 411596707cf8374dba73535bc77bae76fe8770c0028Harald Welte n += get_entry(h, n)->next_offset; 412596707cf8374dba73535bc77bae76fe8770c0028Harald Welte assert(h->info.hook_entry[NF_IP_POST_ROUTING] == n); 413596707cf8374dba73535bc77bae76fe8770c0028Harald Welte user_offset = h->info.hook_entry[NF_IP_POST_ROUTING]; 414596707cf8374dba73535bc77bae76fe8770c0028Harald Welte } 4154dc734c73cc4a0ff87c0ce3673544628b58c7e24Harald Welte } else if (strcmp(h->info.name, "raw") == 0) { 4164dc734c73cc4a0ff87c0ce3673544628b58c7e24Harald Welte assert(h->info.valid_hooks 4174dc734c73cc4a0ff87c0ce3673544628b58c7e24Harald Welte == (1 << NF_IP_PRE_ROUTING 4184dc734c73cc4a0ff87c0ce3673544628b58c7e24Harald Welte | 1 << NF_IP_LOCAL_OUT)); 4194dc734c73cc4a0ff87c0ce3673544628b58c7e24Harald Welte 4204dc734c73cc4a0ff87c0ce3673544628b58c7e24Harald Welte /* Hooks should be first three */ 4214dc734c73cc4a0ff87c0ce3673544628b58c7e24Harald Welte assert(h->info.hook_entry[NF_IP_PRE_ROUTING] == 0); 4224dc734c73cc4a0ff87c0ce3673544628b58c7e24Harald Welte 4234dc734c73cc4a0ff87c0ce3673544628b58c7e24Harald Welte n = get_chain_end(h, n); 4244dc734c73cc4a0ff87c0ce3673544628b58c7e24Harald Welte n += get_entry(h, n)->next_offset; 4254dc734c73cc4a0ff87c0ce3673544628b58c7e24Harald Welte assert(h->info.hook_entry[NF_IP_LOCAL_OUT] == n); 4264dc734c73cc4a0ff87c0ce3673544628b58c7e24Harald Welte 4274dc734c73cc4a0ff87c0ce3673544628b58c7e24Harald Welte user_offset = h->info.hook_entry[NF_IP_LOCAL_OUT]; 428380ba5f3074a16fbaa8869d9594962d58b5f8608Harald Welte 429f92ba9bd4e68659e3c98aa0164cac87540ab3a76Rusty Russell#ifdef NF_IP_DROPPING 430f92ba9bd4e68659e3c98aa0164cac87540ab3a76Rusty Russell } else if (strcmp(h->info.name, "drop") == 0) { 431f92ba9bd4e68659e3c98aa0164cac87540ab3a76Rusty Russell assert(h->info.valid_hooks == (1 << NF_IP_DROPPING)); 432f92ba9bd4e68659e3c98aa0164cac87540ab3a76Rusty Russell 433f92ba9bd4e68659e3c98aa0164cac87540ab3a76Rusty Russell /* Hook should be first */ 434f92ba9bd4e68659e3c98aa0164cac87540ab3a76Rusty Russell assert(h->info.hook_entry[NF_IP_DROPPING] == 0); 435f92ba9bd4e68659e3c98aa0164cac87540ab3a76Rusty Russell user_offset = 0; 436f92ba9bd4e68659e3c98aa0164cac87540ab3a76Rusty Russell#endif 437f92ba9bd4e68659e3c98aa0164cac87540ab3a76Rusty Russell } else { 438e9b4853639bffb0e71d5f7da93736aa8ae34f79bRusty Russell fprintf(stderr, "Unknown table `%s'\n", h->info.name); 43979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell abort(); 440f92ba9bd4e68659e3c98aa0164cac87540ab3a76Rusty Russell } 44179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 44279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell /* User chain == end of last builtin + policy entry */ 44379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell user_offset = get_chain_end(h, user_offset); 44479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell user_offset += get_entry(h, user_offset)->next_offset; 44579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 44679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell /* Overflows should be end of entry chains, and unconditional 44779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell policy nodes. */ 44879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell for (i = 0; i < NUMHOOKS; i++) { 44979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell STRUCT_ENTRY *e; 45079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell STRUCT_STANDARD_TARGET *t; 45179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 45279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell if (!(h->info.valid_hooks & (1 << i))) 45379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell continue; 45479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(h->info.underflow[i] 45579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell == get_chain_end(h, h->info.hook_entry[i])); 45679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 45779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell e = get_entry(h, get_chain_end(h, h->info.hook_entry[i])); 45879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(unconditional(&e->ip)); 45979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(e->target_offset == sizeof(*e)); 46079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell t = (STRUCT_STANDARD_TARGET *)GET_TARGET(e); 461a540b1b15e0d63ab10555502fcd569b40eec8145Harald Welte assert(t->target.u.target_size == ALIGN(sizeof(*t))); 462a540b1b15e0d63ab10555502fcd569b40eec8145Harald Welte assert(e->next_offset == sizeof(*e) + ALIGN(sizeof(*t))); 46379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 46479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(strcmp(t->target.u.user.name, STANDARD_TARGET)==0); 46579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(t->verdict == -NF_DROP-1 || t->verdict == -NF_ACCEPT-1); 46679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 46779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell /* Hooks and underflows must be valid entries */ 46879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell entry2index(h, get_entry(h, h->info.hook_entry[i])); 46979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell entry2index(h, get_entry(h, h->info.underflow[i])); 47079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell } 47179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 47279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(h->info.size 47379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell >= h->info.num_entries * (sizeof(STRUCT_ENTRY) 47479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell +sizeof(STRUCT_STANDARD_TARGET))); 47579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 47679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(h->entries.size 47779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell >= (h->new_number 47879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell * (sizeof(STRUCT_ENTRY) 47979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell + sizeof(STRUCT_STANDARD_TARGET)))); 48079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(strcmp(h->info.name, h->entries.name) == 0); 48179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 48279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell i = 0; n = 0; 48379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell was_return = 0; 48479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell /* Check all the entries. */ 485725d97a79cf0b332ed45cb7d254915178328427dRusty Russell ENTRY_ITERATE(h->entries.entrytable, h->entries.size, 48679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell check_entry, &i, &n, user_offset, &was_return, h); 48779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 48879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(i == h->new_number); 48979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(n == h->entries.size); 49079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell 49179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell /* Final entry must be error node */ 49279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell assert(strcmp(GET_TARGET(index2entry(h, h->new_number-1)) 49379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell ->u.user.name, 494a540b1b15e0d63ab10555502fcd569b40eec8145Harald Welte ERROR_TARGET) == 0); 49579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell} 496380ba5f3074a16fbaa8869d9594962d58b5f8608Harald Welte#endif /*IPTC_DEBUG*/ 497aae69bed019826ddec93f761514652a93d871e49Harald Welte 498aae69bed019826ddec93f761514652a93d871e49Harald Welte#endif 499