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#include <arpa/inet.h>
2179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell
2279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#ifdef DEBUG_CONNTRACK
2379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define inline
2479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#endif
2579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell
2616bd81be22ba2753e26f6a9ee6cb291e1e707d0dJP Abgrall#if !defined(__ANDROID__) && (!defined(__GLIBC__) || (__GLIBC__ < 2))
2779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russelltypedef unsigned int socklen_t;
2879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#endif
2979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell
3079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#include "libiptc/libip6tc.h"
3179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell
3279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define HOOK_PRE_ROUTING	NF_IP6_PRE_ROUTING
3379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define HOOK_LOCAL_IN		NF_IP6_LOCAL_IN
3479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define HOOK_FORWARD		NF_IP6_FORWARD
3579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define HOOK_LOCAL_OUT		NF_IP6_LOCAL_OUT
3679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define HOOK_POST_ROUTING	NF_IP6_POST_ROUTING
3779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell
3879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define STRUCT_ENTRY_TARGET	struct ip6t_entry_target
3979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define STRUCT_ENTRY		struct ip6t_entry
4079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define STRUCT_ENTRY_MATCH	struct ip6t_entry_match
4179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define STRUCT_GETINFO		struct ip6t_getinfo
4279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define STRUCT_GET_ENTRIES	struct ip6t_get_entries
4379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define STRUCT_COUNTERS		struct ip6t_counters
4479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define STRUCT_COUNTERS_INFO	struct ip6t_counters_info
4579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define STRUCT_STANDARD_TARGET	struct ip6t_standard_target
4679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define STRUCT_REPLACE		struct ip6t_replace
4779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell
4879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define STRUCT_TC_HANDLE	struct ip6tc_handle
49fd1873110f8e57be578df17fc9d03536b10f4f73Jan Engelhardt#define xtc_handle		ip6tc_handle
5079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell
5179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define ENTRY_ITERATE		IP6T_ENTRY_ITERATE
5279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TABLE_MAXNAMELEN	IP6T_TABLE_MAXNAMELEN
5379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define FUNCTION_MAXNAMELEN	IP6T_FUNCTION_MAXNAMELEN
5479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell
5579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define GET_TARGET		ip6t_get_target
5679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell
5779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define ERROR_TARGET		IP6T_ERROR_TARGET
5879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define NUMHOOKS		NF_IP6_NUMHOOKS
5979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell
6079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define IPT_CHAINLABEL		ip6t_chainlabel
6179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell
6279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_DUMP_ENTRIES		dump_entries6
6379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_IS_CHAIN		ip6tc_is_chain
648c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell#define TC_FIRST_CHAIN		ip6tc_first_chain
6579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_NEXT_CHAIN		ip6tc_next_chain
668c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell#define TC_FIRST_RULE		ip6tc_first_rule
678c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell#define TC_NEXT_RULE		ip6tc_next_rule
6879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_GET_TARGET		ip6tc_get_target
6979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_BUILTIN		ip6tc_builtin
7079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_GET_POLICY		ip6tc_get_policy
7179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_INSERT_ENTRY		ip6tc_insert_entry
7279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_REPLACE_ENTRY	ip6tc_replace_entry
7379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_APPEND_ENTRY		ip6tc_append_entry
74d59b9db031abee37a9aa9776662dd15370faabf4Stefan Tomanek#define TC_CHECK_ENTRY		ip6tc_check_entry
7579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_DELETE_ENTRY		ip6tc_delete_entry
7679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_DELETE_NUM_ENTRY	ip6tc_delete_num_entry
7779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_FLUSH_ENTRIES	ip6tc_flush_entries
7879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_ZERO_ENTRIES		ip6tc_zero_entries
791cef74d943055668b5e356eebea877fdaa1ce3e0Harald Welte#define TC_ZERO_COUNTER		ip6tc_zero_counter
801cef74d943055668b5e356eebea877fdaa1ce3e0Harald Welte#define TC_READ_COUNTER		ip6tc_read_counter
811cef74d943055668b5e356eebea877fdaa1ce3e0Harald Welte#define TC_SET_COUNTER		ip6tc_set_counter
8279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_CREATE_CHAIN		ip6tc_create_chain
8379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_GET_REFERENCES	ip6tc_get_references
8479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_DELETE_CHAIN		ip6tc_delete_chain
8579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_RENAME_CHAIN		ip6tc_rename_chain
8679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_SET_POLICY		ip6tc_set_policy
8779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_GET_RAW_SOCKET	ip6tc_get_raw_socket
8879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_INIT			ip6tc_init
89841e4aed2349046eb2c0b1375139c06569a93bd0Martin Josefsson#define TC_FREE			ip6tc_free
9079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_COMMIT		ip6tc_commit
9179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_STRERROR		ip6tc_strerror
9270067291528bb949fac8a584e782f2b4c38e4c16Phil Oester#define TC_NUM_RULES		ip6tc_num_rules
9370067291528bb949fac8a584e782f2b4c38e4c16Phil Oester#define TC_GET_RULE		ip6tc_get_rule
9479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell
9579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_AF			AF_INET6
9679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define TC_IPPROTO		IPPROTO_IPV6
9779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell
9879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define SO_SET_REPLACE		IP6T_SO_SET_REPLACE
9979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define SO_SET_ADD_COUNTERS	IP6T_SO_SET_ADD_COUNTERS
10079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define SO_GET_INFO		IP6T_SO_GET_INFO
10179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define SO_GET_ENTRIES		IP6T_SO_GET_ENTRIES
10279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define SO_GET_VERSION		IP6T_SO_GET_VERSION
10379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell
10479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define STANDARD_TARGET		IP6T_STANDARD_TARGET
10579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define LABEL_RETURN		IP6TC_LABEL_RETURN
10679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define LABEL_ACCEPT		IP6TC_LABEL_ACCEPT
10779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define LABEL_DROP		IP6TC_LABEL_DROP
10888eb835ad207f579ae4ce21cd46f0b564ebd4748Philip Blundell#define LABEL_QUEUE		IP6TC_LABEL_QUEUE
10979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell
110dcd1ad89105faf1f3a9a3febdb970b70c5466518Jan Engelhardt#define ALIGN			XT_ALIGN
11179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define RETURN			IP6T_RETURN
11279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell
11379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#include "libiptc.c"
11479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell
11579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell#define BIT6(a, l) \
1165a2208c3e62a150e6f6297abbfa63056ab4a8066Yasuyuki Kozakai ((ntohl(a->s6_addr32[(l) / 32]) >> (31 - ((l) & 31))) & 1)
11779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell
11879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russellint
11979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russellipv6_prefix_length(const struct in6_addr *a)
12079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell{
12179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell	int l, i;
12279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell	for (l = 0; l < 128; l++) {
12379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell		if (BIT6(a, l) == 0)
12479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell			break;
12579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell	}
12679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell	for (i = l + 1; i < 128; i++) {
12779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell		if (BIT6(a, i) == 1)
12879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell			return -1;
12979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell	}
13079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell	return l;
13179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell}
13279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell
13379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russellstatic int
134fd1873110f8e57be578df17fc9d03536b10f4f73Jan Engelhardtdump_entry(struct ip6t_entry *e, struct ip6tc_handle *const handle)
13579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell{
13679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell	size_t i;
13779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell	char buf[40];
13879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell	int len;
13979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell	struct ip6t_entry_target *t;
14079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell
141aae69bed019826ddec93f761514652a93d871e49Harald Welte	printf("Entry %u (%lu):\n", iptcb_entry2index(handle, e),
142aae69bed019826ddec93f761514652a93d871e49Harald Welte	       iptcb_entry2offset(handle, e));
14379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell	puts("SRC IP: ");
14479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell	inet_ntop(AF_INET6, &e->ipv6.src, buf, sizeof buf);
14579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell	puts(buf);
14679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell	putchar('/');
14779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell	len = ipv6_prefix_length(&e->ipv6.smsk);
14879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell	if (len != -1)
14979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell		printf("%d", len);
15079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell	else {
15179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell		inet_ntop(AF_INET6, &e->ipv6.smsk, buf, sizeof buf);
15279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell		puts(buf);
15379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell	}
15479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell	putchar('\n');
15579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell
15679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell	puts("DST IP: ");
15779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell	inet_ntop(AF_INET6, &e->ipv6.dst, buf, sizeof buf);
15879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell	puts(buf);
15979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell	putchar('/');
16079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell	len = ipv6_prefix_length(&e->ipv6.dmsk);
16179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell	if (len != -1)
16279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell		printf("%d", len);
16379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell	else {
16479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell		inet_ntop(AF_INET6, &e->ipv6.dmsk, buf, sizeof buf);
16579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell		puts(buf);
16679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell	}
16779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell	putchar('\n');
16879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell
16979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell	printf("Interface: `%s'/", e->ipv6.iniface);
17079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell	for (i = 0; i < IFNAMSIZ; i++)
17179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell		printf("%c", e->ipv6.iniface_mask[i] ? 'X' : '.');
17279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell	printf("to `%s'/", e->ipv6.outiface);
17379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell	for (i = 0; i < IFNAMSIZ; i++)
17479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell		printf("%c", e->ipv6.outiface_mask[i] ? 'X' : '.');
17579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell	printf("\nProtocol: %u\n", e->ipv6.proto);
17679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell	if (e->ipv6.flags & IP6T_F_TOS)
17779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell		printf("TOS: %u\n", e->ipv6.tos);
17879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell	printf("Flags: %02X\n", e->ipv6.flags);
17979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell	printf("Invflags: %02X\n", e->ipv6.invflags);
18079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell	printf("Counters: %llu packets, %llu bytes\n",
181a28d495285ad7dd9f286d63958cf20d74eec6bcbMartin Josefsson	       (unsigned long long)e->counters.pcnt, (unsigned long long)e->counters.bcnt);
182ea146a982e26c42f9954f140276f8deeb2edbe98Peter Riley	printf("Cache: %08X\n", e->nfcache);
18379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell
18479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell	IP6T_MATCH_ITERATE(e, print_match);
18579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell
18679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell	t = ip6t_get_target(e);
18788eb835ad207f579ae4ce21cd46f0b564ebd4748Philip Blundell	printf("Target name: `%s' [%u]\n", t->u.user.name, t->u.target_size);
18888eb835ad207f579ae4ce21cd46f0b564ebd4748Philip Blundell	if (strcmp(t->u.user.name, IP6T_STANDARD_TARGET) == 0) {
18951651b64fffc58d4f58d005fa7dc0d9669147c57Jan Engelhardt		const unsigned char *data = t->data;
19051651b64fffc58d4f58d005fa7dc0d9669147c57Jan Engelhardt		int pos = *(const int *)data;
19179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell		if (pos < 0)
19279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell			printf("verdict=%s\n",
19379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell			       pos == -NF_ACCEPT-1 ? "NF_ACCEPT"
19479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell			       : pos == -NF_DROP-1 ? "NF_DROP"
19579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell			       : pos == IP6T_RETURN ? "RETURN"
19679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell			       : "UNKNOWN");
19779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell		else
19879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell			printf("verdict=%u\n", pos);
19988eb835ad207f579ae4ce21cd46f0b564ebd4748Philip Blundell	} else if (strcmp(t->u.user.name, IP6T_ERROR_TARGET) == 0)
20079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell		printf("error=`%s'\n", t->data);
20179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell
20279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell	printf("\n");
20379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell	return 0;
20479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell}
20579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell
206733e54b8250576d6a1e0ab5621ef5b144abdf018Rusty Russellstatic unsigned char *
20788eb835ad207f579ae4ce21cd46f0b564ebd4748Philip Blundellis_same(const STRUCT_ENTRY *a, const STRUCT_ENTRY *b,
20879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell	unsigned char *matchmask)
20979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell{
21079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell	unsigned int i;
21179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell	unsigned char *mptr;
21279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell
21379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell	/* Always compare head structures: ignore mask here. */
21479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell	if (memcmp(&a->ipv6.src, &b->ipv6.src, sizeof(struct in6_addr))
21579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell	    || memcmp(&a->ipv6.dst, &b->ipv6.dst, sizeof(struct in6_addr))
21679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell	    || memcmp(&a->ipv6.smsk, &b->ipv6.smsk, sizeof(struct in6_addr))
21779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell	    || memcmp(&a->ipv6.dmsk, &b->ipv6.dmsk, sizeof(struct in6_addr))
21879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell	    || a->ipv6.proto != b->ipv6.proto
21979dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell	    || a->ipv6.tos != b->ipv6.tos
22079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell	    || a->ipv6.flags != b->ipv6.flags
22179dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell	    || a->ipv6.invflags != b->ipv6.invflags)
222733e54b8250576d6a1e0ab5621ef5b144abdf018Rusty Russell		return NULL;
22379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell
22479dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell	for (i = 0; i < IFNAMSIZ; i++) {
22579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell		if (a->ipv6.iniface_mask[i] != b->ipv6.iniface_mask[i])
226733e54b8250576d6a1e0ab5621ef5b144abdf018Rusty Russell			return NULL;
22779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell		if ((a->ipv6.iniface[i] & a->ipv6.iniface_mask[i])
22879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell		    != (b->ipv6.iniface[i] & b->ipv6.iniface_mask[i]))
229733e54b8250576d6a1e0ab5621ef5b144abdf018Rusty Russell			return NULL;
23079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell		if (a->ipv6.outiface_mask[i] != b->ipv6.outiface_mask[i])
231733e54b8250576d6a1e0ab5621ef5b144abdf018Rusty Russell			return NULL;
23279dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell		if ((a->ipv6.outiface[i] & a->ipv6.outiface_mask[i])
23379dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell		    != (b->ipv6.outiface[i] & b->ipv6.outiface_mask[i]))
234733e54b8250576d6a1e0ab5621ef5b144abdf018Rusty Russell			return NULL;
23579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell	}
23679dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell
237ea146a982e26c42f9954f140276f8deeb2edbe98Peter Riley	if (a->target_offset != b->target_offset
23879dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell	    || a->next_offset != b->next_offset)
239733e54b8250576d6a1e0ab5621ef5b144abdf018Rusty Russell		return NULL;
24079dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell
24188eb835ad207f579ae4ce21cd46f0b564ebd4748Philip Blundell	mptr = matchmask + sizeof(STRUCT_ENTRY);
24288eb835ad207f579ae4ce21cd46f0b564ebd4748Philip Blundell	if (IP6T_MATCH_ITERATE(a, match_different, a->elems, b->elems, &mptr))
243733e54b8250576d6a1e0ab5621ef5b144abdf018Rusty Russell		return NULL;
244dcd1ad89105faf1f3a9a3febdb970b70c5466518Jan Engelhardt	mptr += XT_ALIGN(sizeof(struct ip6t_entry_target));
24579dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell
246733e54b8250576d6a1e0ab5621ef5b144abdf018Rusty Russell	return mptr;
24779dee0702b18c8ea1d1f7a2b1f6b29349466986bRusty Russell}
2488c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell
2495eed48af2516ebce0412121713d285bc30edb10dRusty Russell/* All zeroes == unconditional rule. */
2505eed48af2516ebce0412121713d285bc30edb10dRusty Russellstatic inline int
2515eed48af2516ebce0412121713d285bc30edb10dRusty Russellunconditional(const struct ip6t_ip6 *ipv6)
2525eed48af2516ebce0412121713d285bc30edb10dRusty Russell{
2535eed48af2516ebce0412121713d285bc30edb10dRusty Russell	unsigned int i;
2545eed48af2516ebce0412121713d285bc30edb10dRusty Russell
2555eed48af2516ebce0412121713d285bc30edb10dRusty Russell	for (i = 0; i < sizeof(*ipv6); i++)
2565eed48af2516ebce0412121713d285bc30edb10dRusty Russell		if (((char *)ipv6)[i])
2575eed48af2516ebce0412121713d285bc30edb10dRusty Russell			break;
2585eed48af2516ebce0412121713d285bc30edb10dRusty Russell
2595eed48af2516ebce0412121713d285bc30edb10dRusty Russell	return (i == sizeof(*ipv6));
2605eed48af2516ebce0412121713d285bc30edb10dRusty Russell}
2615eed48af2516ebce0412121713d285bc30edb10dRusty Russell
262380ba5f3074a16fbaa8869d9594962d58b5f8608Harald Welte#ifdef IPTC_DEBUG
2638c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell/* Do every conceivable sanity check on the handle */
2648c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundellstatic void
265fd1873110f8e57be578df17fc9d03536b10f4f73Jan Engelhardtdo_check(struct xtc_handle *h, unsigned int line)
2668c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell{
2678c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell	unsigned int i, n;
2688c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell	unsigned int user_offset; /* Offset of first user chain */
2698c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell	int was_return;
2708c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell
2718c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell	assert(h->changed == 0 || h->changed == 1);
2728c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell	if (strcmp(h->info.name, "filter") == 0) {
2738c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell		assert(h->info.valid_hooks
2748c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell		       == (1 << NF_IP6_LOCAL_IN
2758c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell			   | 1 << NF_IP6_FORWARD
2768c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell			   | 1 << NF_IP6_LOCAL_OUT));
2778c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell
2788c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell		/* Hooks should be first three */
2798c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell		assert(h->info.hook_entry[NF_IP6_LOCAL_IN] == 0);
2808c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell
2818c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell		n = get_chain_end(h, 0);
2828c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell		n += get_entry(h, n)->next_offset;
2838c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell		assert(h->info.hook_entry[NF_IP6_FORWARD] == n);
2848c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell
2858c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell		n = get_chain_end(h, n);
2868c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell		n += get_entry(h, n)->next_offset;
2878c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell		assert(h->info.hook_entry[NF_IP6_LOCAL_OUT] == n);
2888c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell
2898c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell		user_offset = h->info.hook_entry[NF_IP6_LOCAL_OUT];
2908c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell	} else if (strcmp(h->info.name, "nat") == 0) {
29195df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte		assert((h->info.valid_hooks
29295df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte			== (1 << NF_IP6_PRE_ROUTING
29395df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte			    | 1 << NF_IP6_LOCAL_OUT
29495df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte			    | 1 << NF_IP6_POST_ROUTING)) ||
29595df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte		       (h->info.valid_hooks
29695df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte			== (1 << NF_IP6_PRE_ROUTING
29795df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte			    | 1 << NF_IP6_LOCAL_IN
29895df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte			    | 1 << NF_IP6_LOCAL_OUT
29995df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte			    | 1 << NF_IP6_POST_ROUTING)));
3008c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell
3018c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell		assert(h->info.hook_entry[NF_IP6_PRE_ROUTING] == 0);
3028c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell
3038c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell		n = get_chain_end(h, 0);
30495df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte
3058c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell		n += get_entry(h, n)->next_offset;
3068c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell		assert(h->info.hook_entry[NF_IP6_POST_ROUTING] == n);
3078c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell		n = get_chain_end(h, n);
30895df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte
3098c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell		n += get_entry(h, n)->next_offset;
3108c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell		assert(h->info.hook_entry[NF_IP6_LOCAL_OUT] == n);
3118c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell		user_offset = h->info.hook_entry[NF_IP6_LOCAL_OUT];
31295df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte
31395df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte		if (h->info.valid_hooks & (1 << NF_IP6_LOCAL_IN)) {
31495df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte			n = get_chain_end(h, n);
31595df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte			n += get_entry(h, n)->next_offset;
31695df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte			assert(h->info.hook_entry[NF_IP6_LOCAL_IN] == n);
31795df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte			user_offset = h->info.hook_entry[NF_IP6_LOCAL_IN];
31895df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte		}
31995df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte
3208c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell	} else if (strcmp(h->info.name, "mangle") == 0) {
321596707cf8374dba73535bc77bae76fe8770c0028Harald Welte		/* This code is getting ugly because linux < 2.4.18-pre6 had
322596707cf8374dba73535bc77bae76fe8770c0028Harald Welte		 * two mangle hooks, linux >= 2.4.18-pre6 has five mangle hooks
323596707cf8374dba73535bc77bae76fe8770c0028Harald Welte		 * */
32495df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte		assert((h->info.valid_hooks
32595df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte			== (1 << NF_IP6_PRE_ROUTING
32695df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte			    | 1 << NF_IP6_LOCAL_OUT)) ||
32795df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte		       (h->info.valid_hooks
32895df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte			== (1 << NF_IP6_PRE_ROUTING
32995df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte			    | 1 << NF_IP6_LOCAL_IN
33095df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte			    | 1 << NF_IP6_FORWARD
33195df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte			    | 1 << NF_IP6_LOCAL_OUT
33295df8e79d018f2e214d24a72237abac8e57bb3cfHarald Welte			    | 1 << NF_IP6_POST_ROUTING)));
3338c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell
334380ba5f3074a16fbaa8869d9594962d58b5f8608Harald Welte		/* Hooks should be first five */
3358c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell		assert(h->info.hook_entry[NF_IP6_PRE_ROUTING] == 0);
3368c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell
3378c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell		n = get_chain_end(h, 0);
338380ba5f3074a16fbaa8869d9594962d58b5f8608Harald Welte
339a540b1b15e0d63ab10555502fcd569b40eec8145Harald Welte		if (h->info.valid_hooks & (1 << NF_IP6_LOCAL_IN)) {
340596707cf8374dba73535bc77bae76fe8770c0028Harald Welte			n += get_entry(h, n)->next_offset;
341596707cf8374dba73535bc77bae76fe8770c0028Harald Welte			assert(h->info.hook_entry[NF_IP6_LOCAL_IN] == n);
342596707cf8374dba73535bc77bae76fe8770c0028Harald Welte			n = get_chain_end(h, n);
343596707cf8374dba73535bc77bae76fe8770c0028Harald Welte		}
344380ba5f3074a16fbaa8869d9594962d58b5f8608Harald Welte
345a540b1b15e0d63ab10555502fcd569b40eec8145Harald Welte		if (h->info.valid_hooks & (1 << NF_IP6_FORWARD)) {
346596707cf8374dba73535bc77bae76fe8770c0028Harald Welte			n += get_entry(h, n)->next_offset;
347596707cf8374dba73535bc77bae76fe8770c0028Harald Welte			assert(h->info.hook_entry[NF_IP6_FORWARD] == n);
348596707cf8374dba73535bc77bae76fe8770c0028Harald Welte			n = get_chain_end(h, n);
349596707cf8374dba73535bc77bae76fe8770c0028Harald Welte		}
3508c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell
351380ba5f3074a16fbaa8869d9594962d58b5f8608Harald Welte		n += get_entry(h, n)->next_offset;
352596707cf8374dba73535bc77bae76fe8770c0028Harald Welte		assert(h->info.hook_entry[NF_IP6_LOCAL_OUT] == n);
353596707cf8374dba73535bc77bae76fe8770c0028Harald Welte		user_offset = h->info.hook_entry[NF_IP6_LOCAL_OUT];
354380ba5f3074a16fbaa8869d9594962d58b5f8608Harald Welte
355a540b1b15e0d63ab10555502fcd569b40eec8145Harald Welte		if (h->info.valid_hooks & (1 << NF_IP6_POST_ROUTING)) {
356596707cf8374dba73535bc77bae76fe8770c0028Harald Welte			n = get_chain_end(h, n);
357596707cf8374dba73535bc77bae76fe8770c0028Harald Welte			n += get_entry(h, n)->next_offset;
358596707cf8374dba73535bc77bae76fe8770c0028Harald Welte			assert(h->info.hook_entry[NF_IP6_POST_ROUTING] == n);
359596707cf8374dba73535bc77bae76fe8770c0028Harald Welte			user_offset = h->info.hook_entry[NF_IP6_POST_ROUTING];
360596707cf8374dba73535bc77bae76fe8770c0028Harald Welte		}
36150fceae8f9b25bbe4effed74321e51916c1ce8b6Harald Welte	} else if (strcmp(h->info.name, "raw") == 0) {
36250fceae8f9b25bbe4effed74321e51916c1ce8b6Harald Welte		assert(h->info.valid_hooks
36350fceae8f9b25bbe4effed74321e51916c1ce8b6Harald Welte		       == (1 << NF_IP6_PRE_ROUTING
36450fceae8f9b25bbe4effed74321e51916c1ce8b6Harald Welte			   | 1 << NF_IP6_LOCAL_OUT));
36550fceae8f9b25bbe4effed74321e51916c1ce8b6Harald Welte
36650fceae8f9b25bbe4effed74321e51916c1ce8b6Harald Welte		/* Hooks should be first three */
36750fceae8f9b25bbe4effed74321e51916c1ce8b6Harald Welte		assert(h->info.hook_entry[NF_IP6_PRE_ROUTING] == 0);
36850fceae8f9b25bbe4effed74321e51916c1ce8b6Harald Welte
36950fceae8f9b25bbe4effed74321e51916c1ce8b6Harald Welte		n = get_chain_end(h, n);
37050fceae8f9b25bbe4effed74321e51916c1ce8b6Harald Welte		n += get_entry(h, n)->next_offset;
37150fceae8f9b25bbe4effed74321e51916c1ce8b6Harald Welte		assert(h->info.hook_entry[NF_IP6_LOCAL_OUT] == n);
37250fceae8f9b25bbe4effed74321e51916c1ce8b6Harald Welte
37350fceae8f9b25bbe4effed74321e51916c1ce8b6Harald Welte		user_offset = h->info.hook_entry[NF_IP6_LOCAL_OUT];
374a540b1b15e0d63ab10555502fcd569b40eec8145Harald Welte	} else {
375a540b1b15e0d63ab10555502fcd569b40eec8145Harald Welte                fprintf(stderr, "Unknown table `%s'\n", h->info.name);
3768c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell		abort();
377a540b1b15e0d63ab10555502fcd569b40eec8145Harald Welte	}
3788c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell
3798c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell	/* User chain == end of last builtin + policy entry */
3808c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell	user_offset = get_chain_end(h, user_offset);
3818c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell	user_offset += get_entry(h, user_offset)->next_offset;
3828c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell
3838c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell	/* Overflows should be end of entry chains, and unconditional
3848c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell           policy nodes. */
3858c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell	for (i = 0; i < NUMHOOKS; i++) {
3868c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell		STRUCT_ENTRY *e;
3878c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell		STRUCT_STANDARD_TARGET *t;
3888c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell
3898c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell		if (!(h->info.valid_hooks & (1 << i)))
3908c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell			continue;
3918c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell		assert(h->info.underflow[i]
3928c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell		       == get_chain_end(h, h->info.hook_entry[i]));
3938c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell
3948c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell		e = get_entry(h, get_chain_end(h, h->info.hook_entry[i]));
3955eed48af2516ebce0412121713d285bc30edb10dRusty Russell		assert(unconditional(&e->ipv6));
3968c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell		assert(e->target_offset == sizeof(*e));
3978c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell		t = (STRUCT_STANDARD_TARGET *)GET_TARGET(e);
398a540b1b15e0d63ab10555502fcd569b40eec8145Harald Welte		printf("target_size=%u, align=%u\n",
399a540b1b15e0d63ab10555502fcd569b40eec8145Harald Welte			t->target.u.target_size, ALIGN(sizeof(*t)));
4008c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell		assert(t->target.u.target_size == ALIGN(sizeof(*t)));
4018c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell		assert(e->next_offset == sizeof(*e) + ALIGN(sizeof(*t)));
4028c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell
4038c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell		assert(strcmp(t->target.u.user.name, STANDARD_TARGET)==0);
4048c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell		assert(t->verdict == -NF_DROP-1 || t->verdict == -NF_ACCEPT-1);
4058c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell
4068c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell		/* Hooks and underflows must be valid entries */
407aae69bed019826ddec93f761514652a93d871e49Harald Welte		iptcb_entry2index(h, get_entry(h, h->info.hook_entry[i]));
408aae69bed019826ddec93f761514652a93d871e49Harald Welte		iptcb_entry2index(h, get_entry(h, h->info.underflow[i]));
4098c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell	}
4108c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell
4118c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell	assert(h->info.size
4128c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell	       >= h->info.num_entries * (sizeof(STRUCT_ENTRY)
4138c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell					 +sizeof(STRUCT_STANDARD_TARGET)));
4148c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell
4158c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell	assert(h->entries.size
4168c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell	       >= (h->new_number
4178c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell		   * (sizeof(STRUCT_ENTRY)
4188c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell		      + sizeof(STRUCT_STANDARD_TARGET))));
4198c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell	assert(strcmp(h->info.name, h->entries.name) == 0);
4208c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell
4218c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell	i = 0; n = 0;
4228c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell	was_return = 0;
4238c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell
4245eed48af2516ebce0412121713d285bc30edb10dRusty Russell#if 0
4258c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell	/* Check all the entries. */
426a540b1b15e0d63ab10555502fcd569b40eec8145Harald Welte	ENTRY_ITERATE(h->entries.entrytable, h->entries.size,
4275eed48af2516ebce0412121713d285bc30edb10dRusty Russell		      check_entry, &i, &n, user_offset, &was_return, h);
4288c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell
4298c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell	assert(i == h->new_number);
4308c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell	assert(n == h->entries.size);
4318c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell
4328c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell	/* Final entry must be error node */
4338c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell	assert(strcmp(GET_TARGET(index2entry(h, h->new_number-1))
4348c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell		      ->u.user.name,
4358c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell		      ERROR_TARGET) == 0);
4365eed48af2516ebce0412121713d285bc30edb10dRusty Russell#endif
4378c700900e2a0cf87d7917cb62578583a60ad1210Philip Blundell}
438380ba5f3074a16fbaa8869d9594962d58b5f8608Harald Welte#endif /*IPTC_DEBUG*/
439