libiptc.c revision 1a7732f965c2b09e526eeca8a551538fbdc099ef
1/* Library which manipulates firewall rules.  Version $Revision$ */
2
3/* Architecture of firewall rules is as follows:
4 *
5 * Chains go INPUT, FORWARD, OUTPUT then user chains.
6 * Each user chain starts with an ERROR node.
7 * Every chain ends with an unconditional jump: a RETURN for user chains,
8 * and a POLICY for built-ins.
9 */
10
11/* (C) 1999 Paul ``Rusty'' Russell - Placed under the GNU GPL (See
12 * COPYING for details).
13 * (C) 2000-2004 by the Netfilter Core Team <coreteam@netfilter.org>
14 *
15 * 2003-Jun-20: Harald Welte <laforge@netfilter.org>:
16 *	- Reimplementation of chain cache to use offsets instead of entries
17 * 2003-Jun-23: Harald Welte <laforge@netfilter.org>:
18 * 	- performance optimization, sponsored by Astaro AG (http://www.astaro.com/)
19 * 	  don't rebuild the chain cache after every operation, instead fix it
20 * 	  up after a ruleset change.
21 * 2004-Aug-18: Harald Welte <laforge@netfilter.org>:
22 * 	- further performance work: total reimplementation of libiptc.
23 * 	- libiptc now has a real internal (linked-list) represntation of the
24 * 	  ruleset and a parser/compiler from/to this internal representation
25 * 	- again sponsored by Astaro AG (http://www.astaro.com/)
26 *
27 * 2008-Jan+Jul: Jesper Dangaard Brouer <hawk@comx.dk>
28 * 	- performance work: speedup chain list "name" searching.
29 * 	- performance work: speedup initial ruleset parsing.
30 * 	- sponsored by ComX Networks A/S (http://www.comx.dk/)
31 */
32#include <sys/types.h>
33#include <sys/socket.h>
34#include <stdbool.h>
35#include <xtables.h>
36#include <libiptc/xtcshared.h>
37
38#include "linux_list.h"
39
40//#define IPTC_DEBUG2 1
41
42#ifdef IPTC_DEBUG2
43#include <fcntl.h>
44#define DEBUGP(x, args...)	fprintf(stderr, "%s: " x, __FUNCTION__, ## args)
45#define DEBUGP_C(x, args...)	fprintf(stderr, x, ## args)
46#else
47#define DEBUGP(x, args...)
48#define DEBUGP_C(x, args...)
49#endif
50
51#ifdef DEBUG
52#define debug(x, args...)	fprintf(stderr, x, ## args)
53#else
54#define debug(x, args...)
55#endif
56
57static void *iptc_fn = NULL;
58
59static const char *hooknames[] = {
60	[HOOK_PRE_ROUTING]	= "PREROUTING",
61	[HOOK_LOCAL_IN]		= "INPUT",
62	[HOOK_FORWARD]		= "FORWARD",
63	[HOOK_LOCAL_OUT]	= "OUTPUT",
64	[HOOK_POST_ROUTING]	= "POSTROUTING",
65};
66
67/* Convenience structures */
68struct chain_head;
69struct rule_head;
70
71struct counter_map
72{
73	enum {
74		COUNTER_MAP_NOMAP,
75		COUNTER_MAP_NORMAL_MAP,
76		COUNTER_MAP_ZEROED,
77		COUNTER_MAP_SET
78	} maptype;
79	unsigned int mappos;
80};
81
82enum iptcc_rule_type {
83	IPTCC_R_STANDARD,		/* standard target (ACCEPT, ...) */
84	IPTCC_R_MODULE,			/* extension module (SNAT, ...) */
85	IPTCC_R_FALLTHROUGH,		/* fallthrough rule */
86	IPTCC_R_JUMP,			/* jump to other chain */
87};
88
89struct rule_head
90{
91	struct list_head list;
92	struct chain_head *chain;
93	struct counter_map counter_map;
94
95	unsigned int index;		/* index (needed for counter_map) */
96	unsigned int offset;		/* offset in rule blob */
97
98	enum iptcc_rule_type type;
99	struct chain_head *jump;	/* jump target, if IPTCC_R_JUMP */
100
101	unsigned int size;		/* size of entry data */
102	STRUCT_ENTRY entry[0];
103};
104
105struct chain_head
106{
107	struct list_head list;
108	char name[TABLE_MAXNAMELEN];
109	unsigned int hooknum;		/* hook number+1 if builtin */
110	unsigned int references;	/* how many jumps reference us */
111	int verdict;			/* verdict if builtin */
112
113	STRUCT_COUNTERS counters;	/* per-chain counters */
114	struct counter_map counter_map;
115
116	unsigned int num_rules;		/* number of rules in list */
117	struct list_head rules;		/* list of rules */
118
119	unsigned int index;		/* index (needed for jump resolval) */
120	unsigned int head_offset;	/* offset in rule blob */
121	unsigned int foot_index;	/* index (needed for counter_map) */
122	unsigned int foot_offset;	/* offset in rule blob */
123};
124
125struct xtc_handle {
126	int sockfd;
127	int changed;			 /* Have changes been made? */
128
129	struct list_head chains;
130
131	struct chain_head *chain_iterator_cur;
132	struct rule_head *rule_iterator_cur;
133
134	unsigned int num_chains;         /* number of user defined chains */
135
136	struct chain_head **chain_index;   /* array for fast chain list access*/
137	unsigned int        chain_index_sz;/* size of chain index array */
138
139	int sorted_offsets; /* if chains are received sorted from kernel,
140			     * then the offsets are also sorted. Says if its
141			     * possible to bsearch offsets using chain_index.
142			     */
143
144	STRUCT_GETINFO info;
145	STRUCT_GET_ENTRIES *entries;
146};
147
148enum bsearch_type {
149	BSEARCH_NAME,	/* Binary search after chain name */
150	BSEARCH_OFFSET,	/* Binary search based on offset */
151};
152
153/* allocate a new chain head for the cache */
154static struct chain_head *iptcc_alloc_chain_head(const char *name, int hooknum)
155{
156	struct chain_head *c = malloc(sizeof(*c));
157	if (!c)
158		return NULL;
159	memset(c, 0, sizeof(*c));
160
161	strncpy(c->name, name, TABLE_MAXNAMELEN);
162	c->hooknum = hooknum;
163	INIT_LIST_HEAD(&c->rules);
164
165	return c;
166}
167
168/* allocate and initialize a new rule for the cache */
169static struct rule_head *iptcc_alloc_rule(struct chain_head *c, unsigned int size)
170{
171	struct rule_head *r = malloc(sizeof(*r)+size);
172	if (!r)
173		return NULL;
174	memset(r, 0, sizeof(*r));
175
176	r->chain = c;
177	r->size = size;
178
179	return r;
180}
181
182/* notify us that the ruleset has been modified by the user */
183static inline void
184set_changed(struct xtc_handle *h)
185{
186	h->changed = 1;
187}
188
189#ifdef IPTC_DEBUG
190static void do_check(struct xtc_handle *h, unsigned int line);
191#define CHECK(h) do { if (!getenv("IPTC_NO_CHECK")) do_check((h), __LINE__); } while(0)
192#else
193#define CHECK(h)
194#endif
195
196
197/**********************************************************************
198 * iptc blob utility functions (iptcb_*)
199 **********************************************************************/
200
201static inline int
202iptcb_get_number(const STRUCT_ENTRY *i,
203	   const STRUCT_ENTRY *seek,
204	   unsigned int *pos)
205{
206	if (i == seek)
207		return 1;
208	(*pos)++;
209	return 0;
210}
211
212static inline int
213iptcb_get_entry_n(STRUCT_ENTRY *i,
214	    unsigned int number,
215	    unsigned int *pos,
216	    STRUCT_ENTRY **pe)
217{
218	if (*pos == number) {
219		*pe = i;
220		return 1;
221	}
222	(*pos)++;
223	return 0;
224}
225
226static inline STRUCT_ENTRY *
227iptcb_get_entry(struct xtc_handle *h, unsigned int offset)
228{
229	return (STRUCT_ENTRY *)((char *)h->entries->entrytable + offset);
230}
231
232static unsigned int
233iptcb_entry2index(struct xtc_handle *const h, const STRUCT_ENTRY *seek)
234{
235	unsigned int pos = 0;
236
237	if (ENTRY_ITERATE(h->entries->entrytable, h->entries->size,
238			  iptcb_get_number, seek, &pos) == 0) {
239		fprintf(stderr, "ERROR: offset %u not an entry!\n",
240			(unsigned int)((char *)seek - (char *)h->entries->entrytable));
241		abort();
242	}
243	return pos;
244}
245
246static inline STRUCT_ENTRY *
247iptcb_offset2entry(struct xtc_handle *h, unsigned int offset)
248{
249	return (STRUCT_ENTRY *) ((void *)h->entries->entrytable+offset);
250}
251
252
253static inline unsigned long
254iptcb_entry2offset(struct xtc_handle *const h, const STRUCT_ENTRY *e)
255{
256	return (void *)e - (void *)h->entries->entrytable;
257}
258
259static inline unsigned int
260iptcb_offset2index(struct xtc_handle *const h, unsigned int offset)
261{
262	return iptcb_entry2index(h, iptcb_offset2entry(h, offset));
263}
264
265/* Returns 0 if not hook entry, else hooknumber + 1 */
266static inline unsigned int
267iptcb_ent_is_hook_entry(STRUCT_ENTRY *e, struct xtc_handle *h)
268{
269	unsigned int i;
270
271	for (i = 0; i < NUMHOOKS; i++) {
272		if ((h->info.valid_hooks & (1 << i))
273		    && iptcb_get_entry(h, h->info.hook_entry[i]) == e)
274			return i+1;
275	}
276	return 0;
277}
278
279
280/**********************************************************************
281 * Chain index (cache utility) functions
282 **********************************************************************
283 * The chain index is an array with pointers into the chain list, with
284 * CHAIN_INDEX_BUCKET_LEN spacing.  This facilitates the ability to
285 * speedup chain list searching, by find a more optimal starting
286 * points when searching the linked list.
287 *
288 * The starting point can be found fast by using a binary search of
289 * the chain index. Thus, reducing the previous search complexity of
290 * O(n) to O(log(n/k) + k) where k is CHAIN_INDEX_BUCKET_LEN.
291 *
292 * A nice property of the chain index, is that the "bucket" list
293 * length is max CHAIN_INDEX_BUCKET_LEN (when just build, inserts will
294 * change this). Oppose to hashing, where the "bucket" list length can
295 * vary a lot.
296 */
297#ifndef CHAIN_INDEX_BUCKET_LEN
298#define CHAIN_INDEX_BUCKET_LEN 40
299#endif
300
301/* Another nice property of the chain index is that inserting/creating
302 * chains in chain list don't change the correctness of the chain
303 * index, it only causes longer lists in the buckets.
304 *
305 * To mitigate the performance penalty of longer bucket lists and the
306 * penalty of rebuilding, the chain index is rebuild only when
307 * CHAIN_INDEX_INSERT_MAX chains has been added.
308 */
309#ifndef CHAIN_INDEX_INSERT_MAX
310#define CHAIN_INDEX_INSERT_MAX 355
311#endif
312
313static inline unsigned int iptcc_is_builtin(struct chain_head *c);
314
315/* Use binary search in the chain index array, to find a chain_head
316 * pointer closest to the place of the searched name element.
317 *
318 * Notes that, binary search (obviously) requires that the chain list
319 * is sorted by name.
320 *
321 * The not so obvious: The chain index array, is actually both sorted
322 * by name and offset, at the same time!.  This is only true because,
323 * chain are stored sorted in the kernel (as we pushed it in sorted).
324 *
325 */
326static struct list_head *
327__iptcc_bsearch_chain_index(const char *name, unsigned int offset,
328			    unsigned int *idx, struct xtc_handle *handle,
329			    enum bsearch_type type)
330{
331	unsigned int pos, end;
332	int res;
333
334	struct list_head *list_pos;
335	list_pos=&handle->chains;
336
337	/* Check for empty array, e.g. no user defined chains */
338	if (handle->chain_index_sz == 0) {
339		debug("WARNING: handle->chain_index_sz == 0\n");
340		return list_pos;
341	}
342
343	/* Init */
344	end = handle->chain_index_sz;
345	pos = end / 2;
346
347	debug("bsearch Find chain:%s (pos:%d end:%d) (offset:%d)\n",
348	      name, pos, end, offset);
349
350	/* Loop */
351 loop:
352	if (!handle->chain_index[pos]) {
353		fprintf(stderr, "ERROR: NULL pointer chain_index[%d]\n", pos);
354		return &handle->chains; /* Be safe, return orig start pos */
355	}
356
357	debug("bsearch Index[%d] name:%s ",
358	      pos, handle->chain_index[pos]->name);
359
360	/* Support for different compare functions */
361	switch (type) {
362	case BSEARCH_NAME:
363		res = strcmp(name, handle->chain_index[pos]->name);
364		break;
365	case BSEARCH_OFFSET:
366		debug("head_offset:[%d] foot_offset:[%d] ",
367		      handle->chain_index[pos]->head_offset,
368		      handle->chain_index[pos]->foot_offset);
369		res = offset - handle->chain_index[pos]->head_offset;
370		break;
371	default:
372		fprintf(stderr, "ERROR: %d not a valid bsearch type\n",
373			type);
374		abort();
375		break;
376	}
377	debug("res:%d ", res);
378
379
380	list_pos = &handle->chain_index[pos]->list;
381	*idx = pos;
382
383	if (res == 0) { /* Found element, by direct hit */
384		debug("[found] Direct hit pos:%d end:%d\n", pos, end);
385		return list_pos;
386	} else if (res < 0) { /* Too far, jump back */
387		end = pos;
388		pos = pos / 2;
389
390		/* Exit case: First element of array */
391		if (end == 0) {
392			debug("[found] Reached first array elem (end%d)\n",end);
393			return list_pos;
394		}
395		debug("jump back to pos:%d (end:%d)\n", pos, end);
396		goto loop;
397	} else { /* res > 0; Not far enough, jump forward */
398
399		/* Exit case: Last element of array */
400		if (pos == handle->chain_index_sz-1) {
401			debug("[found] Last array elem (end:%d)\n", end);
402			return list_pos;
403		}
404
405		/* Exit case: Next index less, thus elem in this list section */
406		switch (type) {
407		case BSEARCH_NAME:
408			res = strcmp(name, handle->chain_index[pos+1]->name);
409			break;
410		case BSEARCH_OFFSET:
411			res = offset - handle->chain_index[pos+1]->head_offset;
412			break;
413		}
414
415		if (res < 0) {
416			debug("[found] closest list (end:%d)\n", end);
417			return list_pos;
418		}
419
420		pos = (pos+end)/2;
421		debug("jump forward to pos:%d (end:%d)\n", pos, end);
422		goto loop;
423	}
424}
425
426/* Wrapper for string chain name based bsearch */
427static struct list_head *
428iptcc_bsearch_chain_index(const char *name, unsigned int *idx,
429			  struct xtc_handle *handle)
430{
431	return __iptcc_bsearch_chain_index(name, 0, idx, handle, BSEARCH_NAME);
432}
433
434
435/* Wrapper for offset chain based bsearch */
436static struct list_head *
437iptcc_bsearch_chain_offset(unsigned int offset, unsigned int *idx,
438			  struct xtc_handle *handle)
439{
440	struct list_head *pos;
441
442	/* If chains were not received sorted from kernel, then the
443	 * offset bsearch is not possible.
444	 */
445	if (!handle->sorted_offsets)
446		pos = handle->chains.next;
447	else
448		pos = __iptcc_bsearch_chain_index(NULL, offset, idx, handle,
449						  BSEARCH_OFFSET);
450	return pos;
451}
452
453
454#ifdef DEBUG
455/* Trivial linear search of chain index. Function used for verifying
456   the output of bsearch function */
457static struct list_head *
458iptcc_linearly_search_chain_index(const char *name, struct xtc_handle *handle)
459{
460	unsigned int i=0;
461	int res=0;
462
463	struct list_head *list_pos;
464	list_pos = &handle->chains;
465
466	if (handle->chain_index_sz)
467		list_pos = &handle->chain_index[0]->list;
468
469	/* Linearly walk of chain index array */
470
471	for (i=0; i < handle->chain_index_sz; i++) {
472		if (handle->chain_index[i]) {
473			res = strcmp(handle->chain_index[i]->name, name);
474			if (res > 0)
475				break; // One step too far
476			list_pos = &handle->chain_index[i]->list;
477			if (res == 0)
478				break; // Direct hit
479		}
480	}
481
482	return list_pos;
483}
484#endif
485
486static int iptcc_chain_index_alloc(struct xtc_handle *h)
487{
488	unsigned int list_length = CHAIN_INDEX_BUCKET_LEN;
489	unsigned int array_elems;
490	unsigned int array_mem;
491
492	/* Allocate memory for the chain index array */
493	array_elems = (h->num_chains / list_length) +
494                      (h->num_chains % list_length ? 1 : 0);
495	array_mem   = sizeof(h->chain_index) * array_elems;
496
497	debug("Alloc Chain index, elems:%d mem:%d bytes\n",
498	      array_elems, array_mem);
499
500	h->chain_index = malloc(array_mem);
501	if (h->chain_index == NULL && array_mem > 0) {
502		h->chain_index_sz = 0;
503		return -ENOMEM;
504	}
505	memset(h->chain_index, 0, array_mem);
506	h->chain_index_sz = array_elems;
507
508	return 1;
509}
510
511static void iptcc_chain_index_free(struct xtc_handle *h)
512{
513	h->chain_index_sz = 0;
514	free(h->chain_index);
515}
516
517
518#ifdef DEBUG
519static void iptcc_chain_index_dump(struct xtc_handle *h)
520{
521	unsigned int i = 0;
522
523	/* Dump: contents of chain index array */
524	for (i=0; i < h->chain_index_sz; i++) {
525		if (h->chain_index[i]) {
526			fprintf(stderr, "Chain index[%d].name: %s\n",
527				i, h->chain_index[i]->name);
528		}
529	}
530}
531#endif
532
533/* Build the chain index */
534static int iptcc_chain_index_build(struct xtc_handle *h)
535{
536	unsigned int list_length = CHAIN_INDEX_BUCKET_LEN;
537	unsigned int chains = 0;
538	unsigned int cindex = 0;
539	struct chain_head *c;
540
541	/* Build up the chain index array here */
542	debug("Building chain index\n");
543
544	debug("Number of user defined chains:%d bucket_sz:%d array_sz:%d\n",
545		h->num_chains, list_length, h->chain_index_sz);
546
547	if (h->chain_index_sz == 0)
548		return 0;
549
550	list_for_each_entry(c, &h->chains, list) {
551
552		/* Issue: The index array needs to start after the
553		 * builtin chains, as they are not sorted */
554		if (!iptcc_is_builtin(c)) {
555			cindex=chains / list_length;
556
557			/* Safe guard, break out on array limit, this
558			 * is useful if chains are added and array is
559			 * rebuild, without realloc of memory. */
560			if (cindex >= h->chain_index_sz)
561				break;
562
563			if ((chains % list_length)== 0) {
564				debug("\nIndex[%d] Chains:", cindex);
565				h->chain_index[cindex] = c;
566			}
567			chains++;
568		}
569		debug("%s, ", c->name);
570	}
571	debug("\n");
572
573	return 1;
574}
575
576static int iptcc_chain_index_rebuild(struct xtc_handle *h)
577{
578	debug("REBUILD chain index array\n");
579	iptcc_chain_index_free(h);
580	if ((iptcc_chain_index_alloc(h)) < 0)
581		return -ENOMEM;
582	iptcc_chain_index_build(h);
583	return 1;
584}
585
586/* Delete chain (pointer) from index array.  Removing an element from
587 * the chain list only affects the chain index array, if the chain
588 * index points-to/uses that list pointer.
589 *
590 * There are different strategies, the simple and safe is to rebuild
591 * the chain index every time.  The more advanced is to update the
592 * array index to point to the next element, but that requires some
593 * house keeping and boundry checks.  The advanced is implemented, as
594 * the simple approach behaves badly when all chains are deleted
595 * because list_for_each processing will always hit the first chain
596 * index, thus causing a rebuild for every chain.
597 */
598static int iptcc_chain_index_delete_chain(struct chain_head *c, struct xtc_handle *h)
599{
600	struct list_head *index_ptr, *next;
601	struct chain_head *c2;
602	unsigned int idx, idx2;
603
604	index_ptr = iptcc_bsearch_chain_index(c->name, &idx, h);
605
606	debug("Del chain[%s] c->list:%p index_ptr:%p\n",
607	      c->name, &c->list, index_ptr);
608
609	/* Save the next pointer */
610	next = c->list.next;
611	list_del(&c->list);
612
613	if (index_ptr == &c->list) { /* Chain used as index ptr */
614
615		/* See if its possible to avoid a rebuild, by shifting
616		 * to next pointer.  Its possible if the next pointer
617		 * is located in the same index bucket.
618		 */
619		c2         = list_entry(next, struct chain_head, list);
620		iptcc_bsearch_chain_index(c2->name, &idx2, h);
621		if (idx != idx2) {
622			/* Rebuild needed */
623			return iptcc_chain_index_rebuild(h);
624		} else {
625			/* Avoiding rebuild */
626			debug("Update cindex[%d] with next ptr name:[%s]\n",
627			      idx, c2->name);
628			h->chain_index[idx]=c2;
629			return 0;
630		}
631	}
632	return 0;
633}
634
635
636/**********************************************************************
637 * iptc cache utility functions (iptcc_*)
638 **********************************************************************/
639
640/* Is the given chain builtin (1) or user-defined (0) */
641static inline unsigned int iptcc_is_builtin(struct chain_head *c)
642{
643	return (c->hooknum ? 1 : 0);
644}
645
646/* Get a specific rule within a chain */
647static struct rule_head *iptcc_get_rule_num(struct chain_head *c,
648					    unsigned int rulenum)
649{
650	struct rule_head *r;
651	unsigned int num = 0;
652
653	list_for_each_entry(r, &c->rules, list) {
654		num++;
655		if (num == rulenum)
656			return r;
657	}
658	return NULL;
659}
660
661/* Get a specific rule within a chain backwards */
662static struct rule_head *iptcc_get_rule_num_reverse(struct chain_head *c,
663					    unsigned int rulenum)
664{
665	struct rule_head *r;
666	unsigned int num = 0;
667
668	list_for_each_entry_reverse(r, &c->rules, list) {
669		num++;
670		if (num == rulenum)
671			return r;
672	}
673	return NULL;
674}
675
676/* Returns chain head if found, otherwise NULL. */
677static struct chain_head *
678iptcc_find_chain_by_offset(struct xtc_handle *handle, unsigned int offset)
679{
680	struct list_head *pos;
681	struct list_head *list_start_pos;
682	unsigned int i;
683
684	if (list_empty(&handle->chains))
685		return NULL;
686
687	/* Find a smart place to start the search */
688  	list_start_pos = iptcc_bsearch_chain_offset(offset, &i, handle);
689
690	/* Note that iptcc_bsearch_chain_offset() skips builtin
691	 * chains, but this function is only used for finding jump
692	 * targets, and a buildin chain is not a valid jump target */
693
694	debug("Offset:[%u] starting search at index:[%u]\n", offset, i);
695//	list_for_each(pos, &handle->chains) {
696	list_for_each(pos, list_start_pos->prev) {
697		struct chain_head *c = list_entry(pos, struct chain_head, list);
698		debug(".");
699		if (offset >= c->head_offset && offset <= c->foot_offset) {
700			debug("Offset search found chain:[%s]\n", c->name);
701			return c;
702		}
703	}
704
705	return NULL;
706}
707
708/* Returns chain head if found, otherwise NULL. */
709static struct chain_head *
710iptcc_find_label(const char *name, struct xtc_handle *handle)
711{
712	struct list_head *pos;
713	struct list_head *list_start_pos;
714	unsigned int i=0;
715	int res;
716
717	if (list_empty(&handle->chains))
718		return NULL;
719
720	/* First look at builtin chains */
721	list_for_each(pos, &handle->chains) {
722		struct chain_head *c = list_entry(pos, struct chain_head, list);
723		if (!iptcc_is_builtin(c))
724			break;
725		if (!strcmp(c->name, name))
726			return c;
727	}
728
729	/* Find a smart place to start the search via chain index */
730  	//list_start_pos = iptcc_linearly_search_chain_index(name, handle);
731  	list_start_pos = iptcc_bsearch_chain_index(name, &i, handle);
732
733	/* Handel if bsearch bails out early */
734	if (list_start_pos == &handle->chains) {
735		list_start_pos = pos;
736	}
737#ifdef DEBUG
738	else {
739		/* Verify result of bsearch against linearly index search */
740		struct list_head *test_pos;
741		struct chain_head *test_c, *tmp_c;
742		test_pos = iptcc_linearly_search_chain_index(name, handle);
743		if (list_start_pos != test_pos) {
744			debug("BUG in chain_index search\n");
745			test_c=list_entry(test_pos,      struct chain_head,list);
746			tmp_c =list_entry(list_start_pos,struct chain_head,list);
747			debug("Verify search found:\n");
748			debug(" Chain:%s\n", test_c->name);
749			debug("BSearch found:\n");
750			debug(" Chain:%s\n", tmp_c->name);
751			exit(42);
752		}
753	}
754#endif
755
756	/* Initial/special case, no user defined chains */
757	if (handle->num_chains == 0)
758		return NULL;
759
760	/* Start searching through the chain list */
761	list_for_each(pos, list_start_pos->prev) {
762		struct chain_head *c = list_entry(pos, struct chain_head, list);
763		res = strcmp(c->name, name);
764		debug("List search name:%s == %s res:%d\n", name, c->name, res);
765		if (res==0)
766			return c;
767
768		/* We can stop earlier as we know list is sorted */
769		if (res>0 && !iptcc_is_builtin(c)) { /* Walked too far*/
770			debug(" Not in list, walked too far, sorted list\n");
771			return NULL;
772		}
773
774		/* Stop on wrap around, if list head is reached */
775		if (pos == &handle->chains) {
776			debug("Stop, list head reached\n");
777			return NULL;
778		}
779	}
780
781	debug("List search NOT found name:%s\n", name);
782	return NULL;
783}
784
785/* called when rule is to be removed from cache */
786static void iptcc_delete_rule(struct rule_head *r)
787{
788	DEBUGP("deleting rule %p (offset %u)\n", r, r->offset);
789	/* clean up reference count of called chain */
790	if (r->type == IPTCC_R_JUMP
791	    && r->jump)
792		r->jump->references--;
793
794	list_del(&r->list);
795	free(r);
796}
797
798
799/**********************************************************************
800 * RULESET PARSER (blob -> cache)
801 **********************************************************************/
802
803/* Delete policy rule of previous chain, since cache doesn't contain
804 * chain policy rules.
805 * WARNING: This function has ugly design and relies on a lot of context, only
806 * to be called from specific places within the parser */
807static int __iptcc_p_del_policy(struct xtc_handle *h, unsigned int num)
808{
809	const unsigned char *data;
810
811	if (h->chain_iterator_cur) {
812		/* policy rule is last rule */
813		struct rule_head *pr = (struct rule_head *)
814			h->chain_iterator_cur->rules.prev;
815
816		/* save verdict */
817		data = GET_TARGET(pr->entry)->data;
818		h->chain_iterator_cur->verdict = *(const int *)data;
819
820		/* save counter and counter_map information */
821		h->chain_iterator_cur->counter_map.maptype =
822						COUNTER_MAP_ZEROED;
823		h->chain_iterator_cur->counter_map.mappos = num-1;
824		memcpy(&h->chain_iterator_cur->counters, &pr->entry->counters,
825			sizeof(h->chain_iterator_cur->counters));
826
827		/* foot_offset points to verdict rule */
828		h->chain_iterator_cur->foot_index = num;
829		h->chain_iterator_cur->foot_offset = pr->offset;
830
831		/* delete rule from cache */
832		iptcc_delete_rule(pr);
833		h->chain_iterator_cur->num_rules--;
834
835		return 1;
836	}
837	return 0;
838}
839
840/* alphabetically insert a chain into the list */
841static void iptc_insert_chain(struct xtc_handle *h, struct chain_head *c)
842{
843	struct chain_head *tmp;
844	struct list_head  *list_start_pos;
845	unsigned int i=1;
846
847	/* Find a smart place to start the insert search */
848  	list_start_pos = iptcc_bsearch_chain_index(c->name, &i, h);
849
850	/* Handle the case, where chain.name is smaller than index[0] */
851	if (i==0 && strcmp(c->name, h->chain_index[0]->name) <= 0) {
852		h->chain_index[0] = c; /* Update chain index head */
853		list_start_pos = h->chains.next;
854		debug("Update chain_index[0] with %s\n", c->name);
855	}
856
857	/* Handel if bsearch bails out early */
858	if (list_start_pos == &h->chains) {
859		list_start_pos = h->chains.next;
860	}
861
862	/* sort only user defined chains */
863	if (!c->hooknum) {
864		list_for_each_entry(tmp, list_start_pos->prev, list) {
865			if (!tmp->hooknum && strcmp(c->name, tmp->name) <= 0) {
866				list_add(&c->list, tmp->list.prev);
867				return;
868			}
869
870			/* Stop if list head is reached */
871			if (&tmp->list == &h->chains) {
872				debug("Insert, list head reached add to tail\n");
873				break;
874			}
875		}
876	}
877
878	/* survived till end of list: add at tail */
879	list_add_tail(&c->list, &h->chains);
880}
881
882/* Another ugly helper function split out of cache_add_entry to make it less
883 * spaghetti code */
884static void __iptcc_p_add_chain(struct xtc_handle *h, struct chain_head *c,
885				unsigned int offset, unsigned int *num)
886{
887	struct list_head  *tail = h->chains.prev;
888	struct chain_head *ctail;
889
890	__iptcc_p_del_policy(h, *num);
891
892	c->head_offset = offset;
893	c->index = *num;
894
895	/* Chains from kernel are already sorted, as they are inserted
896	 * sorted. But there exists an issue when shifting to 1.4.0
897	 * from an older version, as old versions allow last created
898	 * chain to be unsorted.
899	 */
900	if (iptcc_is_builtin(c)) /* Only user defined chains are sorted*/
901		list_add_tail(&c->list, &h->chains);
902	else {
903		ctail = list_entry(tail, struct chain_head, list);
904
905		if (strcmp(c->name, ctail->name) > 0 ||
906		    iptcc_is_builtin(ctail))
907			list_add_tail(&c->list, &h->chains);/* Already sorted*/
908		else {
909			iptc_insert_chain(h, c);/* Was not sorted */
910
911			/* Notice, if chains were not received sorted
912			 * from kernel, then an offset bsearch is no
913			 * longer valid.
914			 */
915			h->sorted_offsets = 0;
916
917			debug("NOTICE: chain:[%s] was NOT sorted(ctail:%s)\n",
918			      c->name, ctail->name);
919		}
920	}
921
922	h->chain_iterator_cur = c;
923}
924
925/* main parser function: add an entry from the blob to the cache */
926static int cache_add_entry(STRUCT_ENTRY *e,
927			   struct xtc_handle *h,
928			   STRUCT_ENTRY **prev,
929			   unsigned int *num)
930{
931	unsigned int builtin;
932	unsigned int offset = (char *)e - (char *)h->entries->entrytable;
933
934	DEBUGP("entering...");
935
936	/* Last entry ("policy rule"). End it.*/
937	if (iptcb_entry2offset(h,e) + e->next_offset == h->entries->size) {
938		/* This is the ERROR node at the end of the chain */
939		DEBUGP_C("%u:%u: end of table:\n", *num, offset);
940
941		__iptcc_p_del_policy(h, *num);
942
943		h->chain_iterator_cur = NULL;
944		goto out_inc;
945	}
946
947	/* We know this is the start of a new chain if it's an ERROR
948	 * target, or a hook entry point */
949
950	if (strcmp(GET_TARGET(e)->u.user.name, ERROR_TARGET) == 0) {
951		struct chain_head *c =
952			iptcc_alloc_chain_head((const char *)GET_TARGET(e)->data, 0);
953		DEBUGP_C("%u:%u:new userdefined chain %s: %p\n", *num, offset,
954			(char *)c->name, c);
955		if (!c) {
956			errno = -ENOMEM;
957			return -1;
958		}
959		h->num_chains++; /* New user defined chain */
960
961		__iptcc_p_add_chain(h, c, offset, num);
962
963	} else if ((builtin = iptcb_ent_is_hook_entry(e, h)) != 0) {
964		struct chain_head *c =
965			iptcc_alloc_chain_head((char *)hooknames[builtin-1],
966						builtin);
967		DEBUGP_C("%u:%u new builtin chain: %p (rules=%p)\n",
968			*num, offset, c, &c->rules);
969		if (!c) {
970			errno = -ENOMEM;
971			return -1;
972		}
973
974		c->hooknum = builtin;
975
976		__iptcc_p_add_chain(h, c, offset, num);
977
978		/* FIXME: this is ugly. */
979		goto new_rule;
980	} else {
981		/* has to be normal rule */
982		struct rule_head *r;
983new_rule:
984
985		if (!(r = iptcc_alloc_rule(h->chain_iterator_cur,
986					   e->next_offset))) {
987			errno = ENOMEM;
988			return -1;
989		}
990		DEBUGP_C("%u:%u normal rule: %p: ", *num, offset, r);
991
992		r->index = *num;
993		r->offset = offset;
994		memcpy(r->entry, e, e->next_offset);
995		r->counter_map.maptype = COUNTER_MAP_NORMAL_MAP;
996		r->counter_map.mappos = r->index;
997
998		/* handling of jumps, etc. */
999		if (!strcmp(GET_TARGET(e)->u.user.name, STANDARD_TARGET)) {
1000			STRUCT_STANDARD_TARGET *t;
1001
1002			t = (STRUCT_STANDARD_TARGET *)GET_TARGET(e);
1003			if (t->target.u.target_size
1004			    != ALIGN(sizeof(STRUCT_STANDARD_TARGET))) {
1005				errno = EINVAL;
1006				free(r);
1007				return -1;
1008			}
1009
1010			if (t->verdict < 0) {
1011				DEBUGP_C("standard, verdict=%d\n", t->verdict);
1012				r->type = IPTCC_R_STANDARD;
1013			} else if (t->verdict == r->offset+e->next_offset) {
1014				DEBUGP_C("fallthrough\n");
1015				r->type = IPTCC_R_FALLTHROUGH;
1016			} else {
1017				DEBUGP_C("jump, target=%u\n", t->verdict);
1018				r->type = IPTCC_R_JUMP;
1019				/* Jump target fixup has to be deferred
1020				 * until second pass, since we migh not
1021				 * yet have parsed the target */
1022			}
1023		} else {
1024			DEBUGP_C("module, target=%s\n", GET_TARGET(e)->u.user.name);
1025			r->type = IPTCC_R_MODULE;
1026		}
1027
1028		list_add_tail(&r->list, &h->chain_iterator_cur->rules);
1029		h->chain_iterator_cur->num_rules++;
1030	}
1031out_inc:
1032	(*num)++;
1033	return 0;
1034}
1035
1036
1037/* parse an iptables blob into it's pieces */
1038static int parse_table(struct xtc_handle *h)
1039{
1040	STRUCT_ENTRY *prev;
1041	unsigned int num = 0;
1042	struct chain_head *c;
1043
1044	/* Assume that chains offsets are sorted, this verified during
1045	   parsing of ruleset (in __iptcc_p_add_chain())*/
1046	h->sorted_offsets = 1;
1047
1048	/* First pass: over ruleset blob */
1049	ENTRY_ITERATE(h->entries->entrytable, h->entries->size,
1050			cache_add_entry, h, &prev, &num);
1051
1052	/* Build the chain index, used for chain list search speedup */
1053	if ((iptcc_chain_index_alloc(h)) < 0)
1054		return -ENOMEM;
1055	iptcc_chain_index_build(h);
1056
1057	/* Second pass: fixup parsed data from first pass */
1058	list_for_each_entry(c, &h->chains, list) {
1059		struct rule_head *r;
1060		list_for_each_entry(r, &c->rules, list) {
1061			struct chain_head *lc;
1062			STRUCT_STANDARD_TARGET *t;
1063
1064			if (r->type != IPTCC_R_JUMP)
1065				continue;
1066
1067			t = (STRUCT_STANDARD_TARGET *)GET_TARGET(r->entry);
1068			lc = iptcc_find_chain_by_offset(h, t->verdict);
1069			if (!lc)
1070				return -1;
1071			r->jump = lc;
1072			lc->references++;
1073		}
1074	}
1075
1076	return 1;
1077}
1078
1079
1080/**********************************************************************
1081 * RULESET COMPILATION (cache -> blob)
1082 **********************************************************************/
1083
1084/* Convenience structures */
1085struct iptcb_chain_start{
1086	STRUCT_ENTRY e;
1087	struct xt_error_target name;
1088};
1089#define IPTCB_CHAIN_START_SIZE	(sizeof(STRUCT_ENTRY) +			\
1090				 ALIGN(sizeof(struct xt_error_target)))
1091
1092struct iptcb_chain_foot {
1093	STRUCT_ENTRY e;
1094	STRUCT_STANDARD_TARGET target;
1095};
1096#define IPTCB_CHAIN_FOOT_SIZE	(sizeof(STRUCT_ENTRY) +			\
1097				 ALIGN(sizeof(STRUCT_STANDARD_TARGET)))
1098
1099struct iptcb_chain_error {
1100	STRUCT_ENTRY entry;
1101	struct xt_error_target target;
1102};
1103#define IPTCB_CHAIN_ERROR_SIZE	(sizeof(STRUCT_ENTRY) +			\
1104				 ALIGN(sizeof(struct xt_error_target)))
1105
1106
1107
1108/* compile rule from cache into blob */
1109static inline int iptcc_compile_rule (struct xtc_handle *h, STRUCT_REPLACE *repl, struct rule_head *r)
1110{
1111	/* handle jumps */
1112	if (r->type == IPTCC_R_JUMP) {
1113		STRUCT_STANDARD_TARGET *t;
1114		t = (STRUCT_STANDARD_TARGET *)GET_TARGET(r->entry);
1115		/* memset for memcmp convenience on delete/replace */
1116		memset(t->target.u.user.name, 0, FUNCTION_MAXNAMELEN);
1117		strcpy(t->target.u.user.name, STANDARD_TARGET);
1118		/* Jumps can only happen to builtin chains, so we
1119		 * can safely assume that they always have a header */
1120		t->verdict = r->jump->head_offset + IPTCB_CHAIN_START_SIZE;
1121	} else if (r->type == IPTCC_R_FALLTHROUGH) {
1122		STRUCT_STANDARD_TARGET *t;
1123		t = (STRUCT_STANDARD_TARGET *)GET_TARGET(r->entry);
1124		t->verdict = r->offset + r->size;
1125	}
1126
1127	/* copy entry from cache to blob */
1128	memcpy((char *)repl->entries+r->offset, r->entry, r->size);
1129
1130	return 1;
1131}
1132
1133/* compile chain from cache into blob */
1134static int iptcc_compile_chain(struct xtc_handle *h, STRUCT_REPLACE *repl, struct chain_head *c)
1135{
1136	int ret;
1137	struct rule_head *r;
1138	struct iptcb_chain_start *head;
1139	struct iptcb_chain_foot *foot;
1140
1141	/* only user-defined chains have heaer */
1142	if (!iptcc_is_builtin(c)) {
1143		/* put chain header in place */
1144		head = (void *)repl->entries + c->head_offset;
1145		head->e.target_offset = sizeof(STRUCT_ENTRY);
1146		head->e.next_offset = IPTCB_CHAIN_START_SIZE;
1147		strcpy(head->name.target.u.user.name, ERROR_TARGET);
1148		head->name.target.u.target_size =
1149				ALIGN(sizeof(struct xt_error_target));
1150		strcpy(head->name.errorname, c->name);
1151	} else {
1152		repl->hook_entry[c->hooknum-1] = c->head_offset;
1153		repl->underflow[c->hooknum-1] = c->foot_offset;
1154	}
1155
1156	/* iterate over rules */
1157	list_for_each_entry(r, &c->rules, list) {
1158		ret = iptcc_compile_rule(h, repl, r);
1159		if (ret < 0)
1160			return ret;
1161	}
1162
1163	/* put chain footer in place */
1164	foot = (void *)repl->entries + c->foot_offset;
1165	foot->e.target_offset = sizeof(STRUCT_ENTRY);
1166	foot->e.next_offset = IPTCB_CHAIN_FOOT_SIZE;
1167	strcpy(foot->target.target.u.user.name, STANDARD_TARGET);
1168	foot->target.target.u.target_size =
1169				ALIGN(sizeof(STRUCT_STANDARD_TARGET));
1170	/* builtin targets have verdict, others return */
1171	if (iptcc_is_builtin(c))
1172		foot->target.verdict = c->verdict;
1173	else
1174		foot->target.verdict = RETURN;
1175	/* set policy-counters */
1176	memcpy(&foot->e.counters, &c->counters, sizeof(STRUCT_COUNTERS));
1177
1178	return 0;
1179}
1180
1181/* calculate offset and number for every rule in the cache */
1182static int iptcc_compile_chain_offsets(struct xtc_handle *h, struct chain_head *c,
1183				       unsigned int *offset, unsigned int *num)
1184{
1185	struct rule_head *r;
1186
1187	c->head_offset = *offset;
1188	DEBUGP("%s: chain_head %u, offset=%u\n", c->name, *num, *offset);
1189
1190	if (!iptcc_is_builtin(c))  {
1191		/* Chain has header */
1192		*offset += sizeof(STRUCT_ENTRY)
1193			     + ALIGN(sizeof(struct xt_error_target));
1194		(*num)++;
1195	}
1196
1197	list_for_each_entry(r, &c->rules, list) {
1198		DEBUGP("rule %u, offset=%u, index=%u\n", *num, *offset, *num);
1199		r->offset = *offset;
1200		r->index = *num;
1201		*offset += r->size;
1202		(*num)++;
1203	}
1204
1205	DEBUGP("%s; chain_foot %u, offset=%u, index=%u\n", c->name, *num,
1206		*offset, *num);
1207	c->foot_offset = *offset;
1208	c->foot_index = *num;
1209	*offset += sizeof(STRUCT_ENTRY)
1210		   + ALIGN(sizeof(STRUCT_STANDARD_TARGET));
1211	(*num)++;
1212
1213	return 1;
1214}
1215
1216/* put the pieces back together again */
1217static int iptcc_compile_table_prep(struct xtc_handle *h, unsigned int *size)
1218{
1219	struct chain_head *c;
1220	unsigned int offset = 0, num = 0;
1221	int ret = 0;
1222
1223	/* First pass: calculate offset for every rule */
1224	list_for_each_entry(c, &h->chains, list) {
1225		ret = iptcc_compile_chain_offsets(h, c, &offset, &num);
1226		if (ret < 0)
1227			return ret;
1228	}
1229
1230	/* Append one error rule at end of chain */
1231	num++;
1232	offset += sizeof(STRUCT_ENTRY)
1233		  + ALIGN(sizeof(struct xt_error_target));
1234
1235	/* ruleset size is now in offset */
1236	*size = offset;
1237	return num;
1238}
1239
1240static int iptcc_compile_table(struct xtc_handle *h, STRUCT_REPLACE *repl)
1241{
1242	struct chain_head *c;
1243	struct iptcb_chain_error *error;
1244
1245	/* Second pass: copy from cache to offsets, fill in jumps */
1246	list_for_each_entry(c, &h->chains, list) {
1247		int ret = iptcc_compile_chain(h, repl, c);
1248		if (ret < 0)
1249			return ret;
1250	}
1251
1252	/* Append error rule at end of chain */
1253	error = (void *)repl->entries + repl->size - IPTCB_CHAIN_ERROR_SIZE;
1254	error->entry.target_offset = sizeof(STRUCT_ENTRY);
1255	error->entry.next_offset = IPTCB_CHAIN_ERROR_SIZE;
1256	error->target.target.u.user.target_size =
1257		ALIGN(sizeof(struct xt_error_target));
1258	strcpy((char *)&error->target.target.u.user.name, ERROR_TARGET);
1259	strcpy((char *)&error->target.errorname, "ERROR");
1260
1261	return 1;
1262}
1263
1264/**********************************************************************
1265 * EXTERNAL API (operates on cache only)
1266 **********************************************************************/
1267
1268/* Allocate handle of given size */
1269static struct xtc_handle *
1270alloc_handle(const char *tablename, unsigned int size, unsigned int num_rules)
1271{
1272	struct xtc_handle *h;
1273
1274	h = malloc(sizeof(*h));
1275	if (!h) {
1276		errno = ENOMEM;
1277		return NULL;
1278	}
1279	memset(h, 0, sizeof(*h));
1280	INIT_LIST_HEAD(&h->chains);
1281	strcpy(h->info.name, tablename);
1282
1283	h->entries = malloc(sizeof(STRUCT_GET_ENTRIES) + size);
1284	if (!h->entries)
1285		goto out_free_handle;
1286
1287	strcpy(h->entries->name, tablename);
1288	h->entries->size = size;
1289
1290	return h;
1291
1292out_free_handle:
1293	free(h);
1294
1295	return NULL;
1296}
1297
1298
1299struct xtc_handle *
1300TC_INIT(const char *tablename)
1301{
1302	struct xtc_handle *h;
1303	STRUCT_GETINFO info;
1304	unsigned int tmp;
1305	socklen_t s;
1306	int sockfd;
1307
1308	iptc_fn = TC_INIT;
1309
1310	if (strlen(tablename) >= TABLE_MAXNAMELEN) {
1311		errno = EINVAL;
1312		return NULL;
1313	}
1314
1315	sockfd = socket(TC_AF, SOCK_RAW, IPPROTO_RAW);
1316	if (sockfd < 0)
1317		return NULL;
1318
1319retry:
1320	s = sizeof(info);
1321
1322	strcpy(info.name, tablename);
1323	if (getsockopt(sockfd, TC_IPPROTO, SO_GET_INFO, &info, &s) < 0) {
1324		close(sockfd);
1325		return NULL;
1326	}
1327
1328	DEBUGP("valid_hooks=0x%08x, num_entries=%u, size=%u\n",
1329		info.valid_hooks, info.num_entries, info.size);
1330
1331	if ((h = alloc_handle(info.name, info.size, info.num_entries))
1332	    == NULL) {
1333		close(sockfd);
1334		return NULL;
1335	}
1336
1337	/* Initialize current state */
1338	h->sockfd = sockfd;
1339	h->info = info;
1340
1341	h->entries->size = h->info.size;
1342
1343	tmp = sizeof(STRUCT_GET_ENTRIES) + h->info.size;
1344
1345	if (getsockopt(h->sockfd, TC_IPPROTO, SO_GET_ENTRIES, h->entries,
1346		       &tmp) < 0)
1347		goto error;
1348
1349#ifdef IPTC_DEBUG2
1350	{
1351		int fd = open("/tmp/libiptc-so_get_entries.blob",
1352				O_CREAT|O_WRONLY);
1353		if (fd >= 0) {
1354			write(fd, h->entries, tmp);
1355			close(fd);
1356		}
1357	}
1358#endif
1359
1360	if (parse_table(h) < 0)
1361		goto error;
1362
1363	CHECK(h);
1364	return h;
1365error:
1366	TC_FREE(h);
1367	/* A different process changed the ruleset size, retry */
1368	if (errno == EAGAIN)
1369		goto retry;
1370	return NULL;
1371}
1372
1373void
1374TC_FREE(struct xtc_handle *h)
1375{
1376	struct chain_head *c, *tmp;
1377
1378	iptc_fn = TC_FREE;
1379	close(h->sockfd);
1380
1381	list_for_each_entry_safe(c, tmp, &h->chains, list) {
1382		struct rule_head *r, *rtmp;
1383
1384		list_for_each_entry_safe(r, rtmp, &c->rules, list) {
1385			free(r);
1386		}
1387
1388		free(c);
1389	}
1390
1391	iptcc_chain_index_free(h);
1392
1393	free(h->entries);
1394	free(h);
1395}
1396
1397static inline int
1398print_match(const STRUCT_ENTRY_MATCH *m)
1399{
1400	printf("Match name: `%s'\n", m->u.user.name);
1401	return 0;
1402}
1403
1404static int dump_entry(STRUCT_ENTRY *e, struct xtc_handle *const handle);
1405
1406void
1407TC_DUMP_ENTRIES(struct xtc_handle *const handle)
1408{
1409	iptc_fn = TC_DUMP_ENTRIES;
1410	CHECK(handle);
1411
1412	printf("libiptc v%s. %u bytes.\n",
1413	       XTABLES_VERSION, handle->entries->size);
1414	printf("Table `%s'\n", handle->info.name);
1415	printf("Hooks: pre/in/fwd/out/post = %x/%x/%x/%x/%x\n",
1416	       handle->info.hook_entry[HOOK_PRE_ROUTING],
1417	       handle->info.hook_entry[HOOK_LOCAL_IN],
1418	       handle->info.hook_entry[HOOK_FORWARD],
1419	       handle->info.hook_entry[HOOK_LOCAL_OUT],
1420	       handle->info.hook_entry[HOOK_POST_ROUTING]);
1421	printf("Underflows: pre/in/fwd/out/post = %x/%x/%x/%x/%x\n",
1422	       handle->info.underflow[HOOK_PRE_ROUTING],
1423	       handle->info.underflow[HOOK_LOCAL_IN],
1424	       handle->info.underflow[HOOK_FORWARD],
1425	       handle->info.underflow[HOOK_LOCAL_OUT],
1426	       handle->info.underflow[HOOK_POST_ROUTING]);
1427
1428	ENTRY_ITERATE(handle->entries->entrytable, handle->entries->size,
1429		      dump_entry, handle);
1430}
1431
1432/* Does this chain exist? */
1433int TC_IS_CHAIN(const char *chain, struct xtc_handle *const handle)
1434{
1435	iptc_fn = TC_IS_CHAIN;
1436	return iptcc_find_label(chain, handle) != NULL;
1437}
1438
1439static void iptcc_chain_iterator_advance(struct xtc_handle *handle)
1440{
1441	struct chain_head *c = handle->chain_iterator_cur;
1442
1443	if (c->list.next == &handle->chains)
1444		handle->chain_iterator_cur = NULL;
1445	else
1446		handle->chain_iterator_cur =
1447			list_entry(c->list.next, struct chain_head, list);
1448}
1449
1450/* Iterator functions to run through the chains. */
1451const char *
1452TC_FIRST_CHAIN(struct xtc_handle *handle)
1453{
1454	struct chain_head *c = list_entry(handle->chains.next,
1455					  struct chain_head, list);
1456
1457	iptc_fn = TC_FIRST_CHAIN;
1458
1459
1460	if (list_empty(&handle->chains)) {
1461		DEBUGP(": no chains\n");
1462		return NULL;
1463	}
1464
1465	handle->chain_iterator_cur = c;
1466	iptcc_chain_iterator_advance(handle);
1467
1468	DEBUGP(": returning `%s'\n", c->name);
1469	return c->name;
1470}
1471
1472/* Iterator functions to run through the chains.  Returns NULL at end. */
1473const char *
1474TC_NEXT_CHAIN(struct xtc_handle *handle)
1475{
1476	struct chain_head *c = handle->chain_iterator_cur;
1477
1478	iptc_fn = TC_NEXT_CHAIN;
1479
1480	if (!c) {
1481		DEBUGP(": no more chains\n");
1482		return NULL;
1483	}
1484
1485	iptcc_chain_iterator_advance(handle);
1486
1487	DEBUGP(": returning `%s'\n", c->name);
1488	return c->name;
1489}
1490
1491/* Get first rule in the given chain: NULL for empty chain. */
1492const STRUCT_ENTRY *
1493TC_FIRST_RULE(const char *chain, struct xtc_handle *handle)
1494{
1495	struct chain_head *c;
1496	struct rule_head *r;
1497
1498	iptc_fn = TC_FIRST_RULE;
1499
1500	DEBUGP("first rule(%s): ", chain);
1501
1502	c = iptcc_find_label(chain, handle);
1503	if (!c) {
1504		errno = ENOENT;
1505		return NULL;
1506	}
1507
1508	/* Empty chain: single return/policy rule */
1509	if (list_empty(&c->rules)) {
1510		DEBUGP_C("no rules, returning NULL\n");
1511		return NULL;
1512	}
1513
1514	r = list_entry(c->rules.next, struct rule_head, list);
1515	handle->rule_iterator_cur = r;
1516	DEBUGP_C("%p\n", r);
1517
1518	return r->entry;
1519}
1520
1521/* Returns NULL when rules run out. */
1522const STRUCT_ENTRY *
1523TC_NEXT_RULE(const STRUCT_ENTRY *prev, struct xtc_handle *handle)
1524{
1525	struct rule_head *r;
1526
1527	iptc_fn = TC_NEXT_RULE;
1528	DEBUGP("rule_iterator_cur=%p...", handle->rule_iterator_cur);
1529
1530	if (handle->rule_iterator_cur == NULL) {
1531		DEBUGP_C("returning NULL\n");
1532		return NULL;
1533	}
1534
1535	r = list_entry(handle->rule_iterator_cur->list.next,
1536			struct rule_head, list);
1537
1538	iptc_fn = TC_NEXT_RULE;
1539
1540	DEBUGP_C("next=%p, head=%p...", &r->list,
1541		&handle->rule_iterator_cur->chain->rules);
1542
1543	if (&r->list == &handle->rule_iterator_cur->chain->rules) {
1544		handle->rule_iterator_cur = NULL;
1545		DEBUGP_C("finished, returning NULL\n");
1546		return NULL;
1547	}
1548
1549	handle->rule_iterator_cur = r;
1550
1551	/* NOTE: prev is without any influence ! */
1552	DEBUGP_C("returning rule %p\n", r);
1553	return r->entry;
1554}
1555
1556/* Returns a pointer to the target name of this position. */
1557static const char *standard_target_map(int verdict)
1558{
1559	switch (verdict) {
1560		case RETURN:
1561			return LABEL_RETURN;
1562			break;
1563		case -NF_ACCEPT-1:
1564			return LABEL_ACCEPT;
1565			break;
1566		case -NF_DROP-1:
1567			return LABEL_DROP;
1568			break;
1569		case -NF_QUEUE-1:
1570			return LABEL_QUEUE;
1571			break;
1572		default:
1573			fprintf(stderr, "ERROR: %d not a valid target)\n",
1574				verdict);
1575			abort();
1576			break;
1577	}
1578	/* not reached */
1579	return NULL;
1580}
1581
1582/* Returns a pointer to the target name of this position. */
1583const char *TC_GET_TARGET(const STRUCT_ENTRY *ce,
1584			  struct xtc_handle *handle)
1585{
1586	STRUCT_ENTRY *e = (STRUCT_ENTRY *)ce;
1587	struct rule_head *r = container_of(e, struct rule_head, entry[0]);
1588	const unsigned char *data;
1589
1590	iptc_fn = TC_GET_TARGET;
1591
1592	switch(r->type) {
1593		int spos;
1594		case IPTCC_R_FALLTHROUGH:
1595			return "";
1596			break;
1597		case IPTCC_R_JUMP:
1598			DEBUGP("r=%p, jump=%p, name=`%s'\n", r, r->jump, r->jump->name);
1599			return r->jump->name;
1600			break;
1601		case IPTCC_R_STANDARD:
1602			data = GET_TARGET(e)->data;
1603			spos = *(const int *)data;
1604			DEBUGP("r=%p, spos=%d'\n", r, spos);
1605			return standard_target_map(spos);
1606			break;
1607		case IPTCC_R_MODULE:
1608			return GET_TARGET(e)->u.user.name;
1609			break;
1610	}
1611	return NULL;
1612}
1613/* Is this a built-in chain?  Actually returns hook + 1. */
1614int
1615TC_BUILTIN(const char *chain, struct xtc_handle *const handle)
1616{
1617	struct chain_head *c;
1618
1619	iptc_fn = TC_BUILTIN;
1620
1621	c = iptcc_find_label(chain, handle);
1622	if (!c) {
1623		errno = ENOENT;
1624		return 0;
1625	}
1626
1627	return iptcc_is_builtin(c);
1628}
1629
1630/* Get the policy of a given built-in chain */
1631const char *
1632TC_GET_POLICY(const char *chain,
1633	      STRUCT_COUNTERS *counters,
1634	      struct xtc_handle *handle)
1635{
1636	struct chain_head *c;
1637
1638	iptc_fn = TC_GET_POLICY;
1639
1640	DEBUGP("called for chain %s\n", chain);
1641
1642	c = iptcc_find_label(chain, handle);
1643	if (!c) {
1644		errno = ENOENT;
1645		return NULL;
1646	}
1647
1648	if (!iptcc_is_builtin(c))
1649		return NULL;
1650
1651	*counters = c->counters;
1652
1653	return standard_target_map(c->verdict);
1654}
1655
1656static int
1657iptcc_standard_map(struct rule_head *r, int verdict)
1658{
1659	STRUCT_ENTRY *e = r->entry;
1660	STRUCT_STANDARD_TARGET *t;
1661
1662	t = (STRUCT_STANDARD_TARGET *)GET_TARGET(e);
1663
1664	if (t->target.u.target_size
1665	    != ALIGN(sizeof(STRUCT_STANDARD_TARGET))) {
1666		errno = EINVAL;
1667		return 0;
1668	}
1669	/* memset for memcmp convenience on delete/replace */
1670	memset(t->target.u.user.name, 0, FUNCTION_MAXNAMELEN);
1671	strcpy(t->target.u.user.name, STANDARD_TARGET);
1672	t->verdict = verdict;
1673
1674	r->type = IPTCC_R_STANDARD;
1675
1676	return 1;
1677}
1678
1679static int
1680iptcc_map_target(struct xtc_handle *const handle,
1681	   struct rule_head *r)
1682{
1683	STRUCT_ENTRY *e = r->entry;
1684	STRUCT_ENTRY_TARGET *t = GET_TARGET(e);
1685
1686	/* Maybe it's empty (=> fall through) */
1687	if (strcmp(t->u.user.name, "") == 0) {
1688		r->type = IPTCC_R_FALLTHROUGH;
1689		return 1;
1690	}
1691	/* Maybe it's a standard target name... */
1692	else if (strcmp(t->u.user.name, LABEL_ACCEPT) == 0)
1693		return iptcc_standard_map(r, -NF_ACCEPT - 1);
1694	else if (strcmp(t->u.user.name, LABEL_DROP) == 0)
1695		return iptcc_standard_map(r, -NF_DROP - 1);
1696	else if (strcmp(t->u.user.name, LABEL_QUEUE) == 0)
1697		return iptcc_standard_map(r, -NF_QUEUE - 1);
1698	else if (strcmp(t->u.user.name, LABEL_RETURN) == 0)
1699		return iptcc_standard_map(r, RETURN);
1700	else if (TC_BUILTIN(t->u.user.name, handle)) {
1701		/* Can't jump to builtins. */
1702		errno = EINVAL;
1703		return 0;
1704	} else {
1705		/* Maybe it's an existing chain name. */
1706		struct chain_head *c;
1707		DEBUGP("trying to find chain `%s': ", t->u.user.name);
1708
1709		c = iptcc_find_label(t->u.user.name, handle);
1710		if (c) {
1711			DEBUGP_C("found!\n");
1712			r->type = IPTCC_R_JUMP;
1713			r->jump = c;
1714			c->references++;
1715			return 1;
1716		}
1717		DEBUGP_C("not found :(\n");
1718	}
1719
1720	/* Must be a module?  If not, kernel will reject... */
1721	/* memset to all 0 for your memcmp convenience: don't clear version */
1722	memset(t->u.user.name + strlen(t->u.user.name),
1723	       0,
1724	       FUNCTION_MAXNAMELEN - 1 - strlen(t->u.user.name));
1725	r->type = IPTCC_R_MODULE;
1726	set_changed(handle);
1727	return 1;
1728}
1729
1730/* Insert the entry `fw' in chain `chain' into position `rulenum'. */
1731int
1732TC_INSERT_ENTRY(const IPT_CHAINLABEL chain,
1733		const STRUCT_ENTRY *e,
1734		unsigned int rulenum,
1735		struct xtc_handle *handle)
1736{
1737	struct chain_head *c;
1738	struct rule_head *r;
1739	struct list_head *prev;
1740
1741	iptc_fn = TC_INSERT_ENTRY;
1742
1743	if (!(c = iptcc_find_label(chain, handle))) {
1744		errno = ENOENT;
1745		return 0;
1746	}
1747
1748	/* first rulenum index = 0
1749	   first c->num_rules index = 1 */
1750	if (rulenum > c->num_rules) {
1751		errno = E2BIG;
1752		return 0;
1753	}
1754
1755	/* If we are inserting at the end just take advantage of the
1756	   double linked list, insert will happen before the entry
1757	   prev points to. */
1758	if (rulenum == c->num_rules) {
1759		prev = &c->rules;
1760	} else if (rulenum + 1 <= c->num_rules/2) {
1761		r = iptcc_get_rule_num(c, rulenum + 1);
1762		prev = &r->list;
1763	} else {
1764		r = iptcc_get_rule_num_reverse(c, c->num_rules - rulenum);
1765		prev = &r->list;
1766	}
1767
1768	if (!(r = iptcc_alloc_rule(c, e->next_offset))) {
1769		errno = ENOMEM;
1770		return 0;
1771	}
1772
1773	memcpy(r->entry, e, e->next_offset);
1774	r->counter_map.maptype = COUNTER_MAP_SET;
1775
1776	if (!iptcc_map_target(handle, r)) {
1777		free(r);
1778		return 0;
1779	}
1780
1781	list_add_tail(&r->list, prev);
1782	c->num_rules++;
1783
1784	set_changed(handle);
1785
1786	return 1;
1787}
1788
1789/* Atomically replace rule `rulenum' in `chain' with `fw'. */
1790int
1791TC_REPLACE_ENTRY(const IPT_CHAINLABEL chain,
1792		 const STRUCT_ENTRY *e,
1793		 unsigned int rulenum,
1794		 struct xtc_handle *handle)
1795{
1796	struct chain_head *c;
1797	struct rule_head *r, *old;
1798
1799	iptc_fn = TC_REPLACE_ENTRY;
1800
1801	if (!(c = iptcc_find_label(chain, handle))) {
1802		errno = ENOENT;
1803		return 0;
1804	}
1805
1806	if (rulenum >= c->num_rules) {
1807		errno = E2BIG;
1808		return 0;
1809	}
1810
1811	/* Take advantage of the double linked list if possible. */
1812	if (rulenum + 1 <= c->num_rules/2) {
1813		old = iptcc_get_rule_num(c, rulenum + 1);
1814	} else {
1815		old = iptcc_get_rule_num_reverse(c, c->num_rules - rulenum);
1816	}
1817
1818	if (!(r = iptcc_alloc_rule(c, e->next_offset))) {
1819		errno = ENOMEM;
1820		return 0;
1821	}
1822
1823	memcpy(r->entry, e, e->next_offset);
1824	r->counter_map.maptype = COUNTER_MAP_SET;
1825
1826	if (!iptcc_map_target(handle, r)) {
1827		free(r);
1828		return 0;
1829	}
1830
1831	list_add(&r->list, &old->list);
1832	iptcc_delete_rule(old);
1833
1834	set_changed(handle);
1835
1836	return 1;
1837}
1838
1839/* Append entry `fw' to chain `chain'.  Equivalent to insert with
1840   rulenum = length of chain. */
1841int
1842TC_APPEND_ENTRY(const IPT_CHAINLABEL chain,
1843		const STRUCT_ENTRY *e,
1844		struct xtc_handle *handle)
1845{
1846	struct chain_head *c;
1847	struct rule_head *r;
1848
1849	iptc_fn = TC_APPEND_ENTRY;
1850	if (!(c = iptcc_find_label(chain, handle))) {
1851		DEBUGP("unable to find chain `%s'\n", chain);
1852		errno = ENOENT;
1853		return 0;
1854	}
1855
1856	if (!(r = iptcc_alloc_rule(c, e->next_offset))) {
1857		DEBUGP("unable to allocate rule for chain `%s'\n", chain);
1858		errno = ENOMEM;
1859		return 0;
1860	}
1861
1862	memcpy(r->entry, e, e->next_offset);
1863	r->counter_map.maptype = COUNTER_MAP_SET;
1864
1865	if (!iptcc_map_target(handle, r)) {
1866		DEBUGP("unable to map target of rule for chain `%s'\n", chain);
1867		free(r);
1868		return 0;
1869	}
1870
1871	list_add_tail(&r->list, &c->rules);
1872	c->num_rules++;
1873
1874	set_changed(handle);
1875
1876	return 1;
1877}
1878
1879static inline int
1880match_different(const STRUCT_ENTRY_MATCH *a,
1881		const unsigned char *a_elems,
1882		const unsigned char *b_elems,
1883		unsigned char **maskptr)
1884{
1885	const STRUCT_ENTRY_MATCH *b;
1886	unsigned int i;
1887
1888	/* Offset of b is the same as a. */
1889	b = (void *)b_elems + ((unsigned char *)a - a_elems);
1890
1891	if (a->u.match_size != b->u.match_size)
1892		return 1;
1893
1894	if (strcmp(a->u.user.name, b->u.user.name) != 0)
1895		return 1;
1896
1897	*maskptr += ALIGN(sizeof(*a));
1898
1899	for (i = 0; i < a->u.match_size - ALIGN(sizeof(*a)); i++)
1900		if (((a->data[i] ^ b->data[i]) & (*maskptr)[i]) != 0)
1901			return 1;
1902	*maskptr += i;
1903	return 0;
1904}
1905
1906static inline int
1907target_same(struct rule_head *a, struct rule_head *b,const unsigned char *mask)
1908{
1909	unsigned int i;
1910	STRUCT_ENTRY_TARGET *ta, *tb;
1911
1912	if (a->type != b->type)
1913		return 0;
1914
1915	ta = GET_TARGET(a->entry);
1916	tb = GET_TARGET(b->entry);
1917
1918	switch (a->type) {
1919	case IPTCC_R_FALLTHROUGH:
1920		return 1;
1921	case IPTCC_R_JUMP:
1922		return a->jump == b->jump;
1923	case IPTCC_R_STANDARD:
1924		return ((STRUCT_STANDARD_TARGET *)ta)->verdict
1925			== ((STRUCT_STANDARD_TARGET *)tb)->verdict;
1926	case IPTCC_R_MODULE:
1927		if (ta->u.target_size != tb->u.target_size)
1928			return 0;
1929		if (strcmp(ta->u.user.name, tb->u.user.name) != 0)
1930			return 0;
1931
1932		for (i = 0; i < ta->u.target_size - sizeof(*ta); i++)
1933			if (((ta->data[i] ^ tb->data[i]) & mask[i]) != 0)
1934				return 0;
1935		return 1;
1936	default:
1937		fprintf(stderr, "ERROR: bad type %i\n", a->type);
1938		abort();
1939	}
1940}
1941
1942static unsigned char *
1943is_same(const STRUCT_ENTRY *a,
1944	const STRUCT_ENTRY *b,
1945	unsigned char *matchmask);
1946
1947
1948/* find the first rule in `chain' which matches `fw' and remove it unless dry_run is set */
1949static int delete_entry(const IPT_CHAINLABEL chain, const STRUCT_ENTRY *origfw,
1950			unsigned char *matchmask, struct xtc_handle *handle,
1951			bool dry_run)
1952{
1953	struct chain_head *c;
1954	struct rule_head *r, *i;
1955
1956	iptc_fn = TC_DELETE_ENTRY;
1957	if (!(c = iptcc_find_label(chain, handle))) {
1958		errno = ENOENT;
1959		return 0;
1960	}
1961
1962	/* Create a rule_head from origfw. */
1963	r = iptcc_alloc_rule(c, origfw->next_offset);
1964	if (!r) {
1965		errno = ENOMEM;
1966		return 0;
1967	}
1968
1969	memcpy(r->entry, origfw, origfw->next_offset);
1970	r->counter_map.maptype = COUNTER_MAP_NOMAP;
1971	if (!iptcc_map_target(handle, r)) {
1972		DEBUGP("unable to map target of rule for chain `%s'\n", chain);
1973		free(r);
1974		return 0;
1975	} else {
1976		/* iptcc_map_target increment target chain references
1977		 * since this is a fake rule only used for matching
1978		 * the chain references count is decremented again.
1979		 */
1980		if (r->type == IPTCC_R_JUMP
1981		    && r->jump)
1982			r->jump->references--;
1983	}
1984
1985	list_for_each_entry(i, &c->rules, list) {
1986		unsigned char *mask;
1987
1988		mask = is_same(r->entry, i->entry, matchmask);
1989		if (!mask)
1990			continue;
1991
1992		if (!target_same(r, i, mask))
1993			continue;
1994
1995		/* if we are just doing a dry run, we simply skip the rest */
1996		if (dry_run)
1997			return 1;
1998
1999		/* If we are about to delete the rule that is the
2000		 * current iterator, move rule iterator back.  next
2001		 * pointer will then point to real next node */
2002		if (i == handle->rule_iterator_cur) {
2003			handle->rule_iterator_cur =
2004				list_entry(handle->rule_iterator_cur->list.prev,
2005					   struct rule_head, list);
2006		}
2007
2008		c->num_rules--;
2009		iptcc_delete_rule(i);
2010
2011		set_changed(handle);
2012		free(r);
2013		return 1;
2014	}
2015
2016	free(r);
2017	errno = ENOENT;
2018	return 0;
2019}
2020
2021/* check whether a specified rule is present */
2022int TC_CHECK_ENTRY(const IPT_CHAINLABEL chain, const STRUCT_ENTRY *origfw,
2023		   unsigned char *matchmask, struct xtc_handle *handle)
2024{
2025	/* do a dry-run delete to find out whether a matching rule exists */
2026	return delete_entry(chain, origfw, matchmask, handle, true);
2027}
2028
2029/* Delete the first rule in `chain' which matches `fw'. */
2030int TC_DELETE_ENTRY(const IPT_CHAINLABEL chain,	const STRUCT_ENTRY *origfw,
2031		    unsigned char *matchmask, struct xtc_handle *handle)
2032{
2033	return delete_entry(chain, origfw, matchmask, handle, false);
2034}
2035
2036/* Delete the rule in position `rulenum' in `chain'. */
2037int
2038TC_DELETE_NUM_ENTRY(const IPT_CHAINLABEL chain,
2039		    unsigned int rulenum,
2040		    struct xtc_handle *handle)
2041{
2042	struct chain_head *c;
2043	struct rule_head *r;
2044
2045	iptc_fn = TC_DELETE_NUM_ENTRY;
2046
2047	if (!(c = iptcc_find_label(chain, handle))) {
2048		errno = ENOENT;
2049		return 0;
2050	}
2051
2052	if (rulenum >= c->num_rules) {
2053		errno = E2BIG;
2054		return 0;
2055	}
2056
2057	/* Take advantage of the double linked list if possible. */
2058	if (rulenum + 1 <= c->num_rules/2) {
2059		r = iptcc_get_rule_num(c, rulenum + 1);
2060	} else {
2061		r = iptcc_get_rule_num_reverse(c, c->num_rules - rulenum);
2062	}
2063
2064	/* If we are about to delete the rule that is the current
2065	 * iterator, move rule iterator back.  next pointer will then
2066	 * point to real next node */
2067	if (r == handle->rule_iterator_cur) {
2068		handle->rule_iterator_cur =
2069			list_entry(handle->rule_iterator_cur->list.prev,
2070				   struct rule_head, list);
2071	}
2072
2073	c->num_rules--;
2074	iptcc_delete_rule(r);
2075
2076	set_changed(handle);
2077
2078	return 1;
2079}
2080
2081/* Flushes the entries in the given chain (ie. empties chain). */
2082int
2083TC_FLUSH_ENTRIES(const IPT_CHAINLABEL chain, struct xtc_handle *handle)
2084{
2085	struct chain_head *c;
2086	struct rule_head *r, *tmp;
2087
2088	iptc_fn = TC_FLUSH_ENTRIES;
2089	if (!(c = iptcc_find_label(chain, handle))) {
2090		errno = ENOENT;
2091		return 0;
2092	}
2093
2094	list_for_each_entry_safe(r, tmp, &c->rules, list) {
2095		iptcc_delete_rule(r);
2096	}
2097
2098	c->num_rules = 0;
2099
2100	set_changed(handle);
2101
2102	return 1;
2103}
2104
2105/* Zeroes the counters in a chain. */
2106int
2107TC_ZERO_ENTRIES(const IPT_CHAINLABEL chain, struct xtc_handle *handle)
2108{
2109	struct chain_head *c;
2110	struct rule_head *r;
2111
2112	iptc_fn = TC_ZERO_ENTRIES;
2113	if (!(c = iptcc_find_label(chain, handle))) {
2114		errno = ENOENT;
2115		return 0;
2116	}
2117
2118	if (c->counter_map.maptype == COUNTER_MAP_NORMAL_MAP)
2119		c->counter_map.maptype = COUNTER_MAP_ZEROED;
2120
2121	list_for_each_entry(r, &c->rules, list) {
2122		if (r->counter_map.maptype == COUNTER_MAP_NORMAL_MAP)
2123			r->counter_map.maptype = COUNTER_MAP_ZEROED;
2124	}
2125
2126	set_changed(handle);
2127
2128	return 1;
2129}
2130
2131STRUCT_COUNTERS *
2132TC_READ_COUNTER(const IPT_CHAINLABEL chain,
2133		unsigned int rulenum,
2134		struct xtc_handle *handle)
2135{
2136	struct chain_head *c;
2137	struct rule_head *r;
2138
2139	iptc_fn = TC_READ_COUNTER;
2140	CHECK(*handle);
2141
2142	if (!(c = iptcc_find_label(chain, handle))) {
2143		errno = ENOENT;
2144		return NULL;
2145	}
2146
2147	if (!(r = iptcc_get_rule_num(c, rulenum))) {
2148		errno = E2BIG;
2149		return NULL;
2150	}
2151
2152	return &r->entry[0].counters;
2153}
2154
2155int
2156TC_ZERO_COUNTER(const IPT_CHAINLABEL chain,
2157		unsigned int rulenum,
2158		struct xtc_handle *handle)
2159{
2160	struct chain_head *c;
2161	struct rule_head *r;
2162
2163	iptc_fn = TC_ZERO_COUNTER;
2164	CHECK(handle);
2165
2166	if (!(c = iptcc_find_label(chain, handle))) {
2167		errno = ENOENT;
2168		return 0;
2169	}
2170
2171	if (!(r = iptcc_get_rule_num(c, rulenum))) {
2172		errno = E2BIG;
2173		return 0;
2174	}
2175
2176	if (r->counter_map.maptype == COUNTER_MAP_NORMAL_MAP)
2177		r->counter_map.maptype = COUNTER_MAP_ZEROED;
2178
2179	set_changed(handle);
2180
2181	return 1;
2182}
2183
2184int
2185TC_SET_COUNTER(const IPT_CHAINLABEL chain,
2186	       unsigned int rulenum,
2187	       STRUCT_COUNTERS *counters,
2188	       struct xtc_handle *handle)
2189{
2190	struct chain_head *c;
2191	struct rule_head *r;
2192	STRUCT_ENTRY *e;
2193
2194	iptc_fn = TC_SET_COUNTER;
2195	CHECK(handle);
2196
2197	if (!(c = iptcc_find_label(chain, handle))) {
2198		errno = ENOENT;
2199		return 0;
2200	}
2201
2202	if (!(r = iptcc_get_rule_num(c, rulenum))) {
2203		errno = E2BIG;
2204		return 0;
2205	}
2206
2207	e = r->entry;
2208	r->counter_map.maptype = COUNTER_MAP_SET;
2209
2210	memcpy(&e->counters, counters, sizeof(STRUCT_COUNTERS));
2211
2212	set_changed(handle);
2213
2214	return 1;
2215}
2216
2217/* Creates a new chain. */
2218/* To create a chain, create two rules: error node and unconditional
2219 * return. */
2220int
2221TC_CREATE_CHAIN(const IPT_CHAINLABEL chain, struct xtc_handle *handle)
2222{
2223	static struct chain_head *c;
2224	int capacity;
2225	int exceeded;
2226
2227	iptc_fn = TC_CREATE_CHAIN;
2228
2229	/* find_label doesn't cover built-in targets: DROP, ACCEPT,
2230           QUEUE, RETURN. */
2231	if (iptcc_find_label(chain, handle)
2232	    || strcmp(chain, LABEL_DROP) == 0
2233	    || strcmp(chain, LABEL_ACCEPT) == 0
2234	    || strcmp(chain, LABEL_QUEUE) == 0
2235	    || strcmp(chain, LABEL_RETURN) == 0) {
2236		DEBUGP("Chain `%s' already exists\n", chain);
2237		errno = EEXIST;
2238		return 0;
2239	}
2240
2241	if (strlen(chain)+1 > sizeof(IPT_CHAINLABEL)) {
2242		DEBUGP("Chain name `%s' too long\n", chain);
2243		errno = EINVAL;
2244		return 0;
2245	}
2246
2247	c = iptcc_alloc_chain_head(chain, 0);
2248	if (!c) {
2249		DEBUGP("Cannot allocate memory for chain `%s'\n", chain);
2250		errno = ENOMEM;
2251		return 0;
2252
2253	}
2254	handle->num_chains++; /* New user defined chain */
2255
2256	DEBUGP("Creating chain `%s'\n", chain);
2257	iptc_insert_chain(handle, c); /* Insert sorted */
2258
2259	/* Inserting chains don't change the correctness of the chain
2260	 * index (except if its smaller than index[0], but that
2261	 * handled by iptc_insert_chain).  It only causes longer lists
2262	 * in the buckets. Thus, only rebuild chain index when the
2263	 * capacity is exceed with CHAIN_INDEX_INSERT_MAX chains.
2264	 */
2265	capacity = handle->chain_index_sz * CHAIN_INDEX_BUCKET_LEN;
2266	exceeded = handle->num_chains - capacity;
2267	if (exceeded > CHAIN_INDEX_INSERT_MAX) {
2268		debug("Capacity(%d) exceeded(%d) rebuild (chains:%d)\n",
2269		      capacity, exceeded, handle->num_chains);
2270		iptcc_chain_index_rebuild(handle);
2271	}
2272
2273	set_changed(handle);
2274
2275	return 1;
2276}
2277
2278/* Get the number of references to this chain. */
2279int
2280TC_GET_REFERENCES(unsigned int *ref, const IPT_CHAINLABEL chain,
2281		  struct xtc_handle *handle)
2282{
2283	struct chain_head *c;
2284
2285	iptc_fn = TC_GET_REFERENCES;
2286	if (!(c = iptcc_find_label(chain, handle))) {
2287		errno = ENOENT;
2288		return 0;
2289	}
2290
2291	*ref = c->references;
2292
2293	return 1;
2294}
2295
2296/* Deletes a chain. */
2297int
2298TC_DELETE_CHAIN(const IPT_CHAINLABEL chain, struct xtc_handle *handle)
2299{
2300	unsigned int references;
2301	struct chain_head *c;
2302
2303	iptc_fn = TC_DELETE_CHAIN;
2304
2305	if (!(c = iptcc_find_label(chain, handle))) {
2306		DEBUGP("cannot find chain `%s'\n", chain);
2307		errno = ENOENT;
2308		return 0;
2309	}
2310
2311	if (TC_BUILTIN(chain, handle)) {
2312		DEBUGP("cannot remove builtin chain `%s'\n", chain);
2313		errno = EINVAL;
2314		return 0;
2315	}
2316
2317	if (!TC_GET_REFERENCES(&references, chain, handle)) {
2318		DEBUGP("cannot get references on chain `%s'\n", chain);
2319		return 0;
2320	}
2321
2322	if (references > 0) {
2323		DEBUGP("chain `%s' still has references\n", chain);
2324		errno = EMLINK;
2325		return 0;
2326	}
2327
2328	if (c->num_rules) {
2329		DEBUGP("chain `%s' is not empty\n", chain);
2330		errno = ENOTEMPTY;
2331		return 0;
2332	}
2333
2334	/* If we are about to delete the chain that is the current
2335	 * iterator, move chain iterator forward. */
2336	if (c == handle->chain_iterator_cur)
2337		iptcc_chain_iterator_advance(handle);
2338
2339	handle->num_chains--; /* One user defined chain deleted */
2340
2341	//list_del(&c->list); /* Done in iptcc_chain_index_delete_chain() */
2342	iptcc_chain_index_delete_chain(c, handle);
2343	free(c);
2344
2345	DEBUGP("chain `%s' deleted\n", chain);
2346
2347	set_changed(handle);
2348
2349	return 1;
2350}
2351
2352/* Renames a chain. */
2353int TC_RENAME_CHAIN(const IPT_CHAINLABEL oldname,
2354		    const IPT_CHAINLABEL newname,
2355		    struct xtc_handle *handle)
2356{
2357	struct chain_head *c;
2358	iptc_fn = TC_RENAME_CHAIN;
2359
2360	/* find_label doesn't cover built-in targets: DROP, ACCEPT,
2361           QUEUE, RETURN. */
2362	if (iptcc_find_label(newname, handle)
2363	    || strcmp(newname, LABEL_DROP) == 0
2364	    || strcmp(newname, LABEL_ACCEPT) == 0
2365	    || strcmp(newname, LABEL_QUEUE) == 0
2366	    || strcmp(newname, LABEL_RETURN) == 0) {
2367		errno = EEXIST;
2368		return 0;
2369	}
2370
2371	if (!(c = iptcc_find_label(oldname, handle))
2372	    || TC_BUILTIN(oldname, handle)) {
2373		errno = ENOENT;
2374		return 0;
2375	}
2376
2377	if (strlen(newname)+1 > sizeof(IPT_CHAINLABEL)) {
2378		errno = EINVAL;
2379		return 0;
2380	}
2381
2382	/* This only unlinks "c" from the list, thus no free(c) */
2383	iptcc_chain_index_delete_chain(c, handle);
2384
2385	/* Change the name of the chain */
2386	strncpy(c->name, newname, sizeof(IPT_CHAINLABEL));
2387
2388	/* Insert sorted into to list again */
2389	iptc_insert_chain(handle, c);
2390
2391	set_changed(handle);
2392
2393	return 1;
2394}
2395
2396/* Sets the policy on a built-in chain. */
2397int
2398TC_SET_POLICY(const IPT_CHAINLABEL chain,
2399	      const IPT_CHAINLABEL policy,
2400	      STRUCT_COUNTERS *counters,
2401	      struct xtc_handle *handle)
2402{
2403	struct chain_head *c;
2404
2405	iptc_fn = TC_SET_POLICY;
2406
2407	if (!(c = iptcc_find_label(chain, handle))) {
2408		DEBUGP("cannot find chain `%s'\n", chain);
2409		errno = ENOENT;
2410		return 0;
2411	}
2412
2413	if (!iptcc_is_builtin(c)) {
2414		DEBUGP("cannot set policy of userdefinedchain `%s'\n", chain);
2415		errno = ENOENT;
2416		return 0;
2417	}
2418
2419	if (strcmp(policy, LABEL_ACCEPT) == 0)
2420		c->verdict = -NF_ACCEPT - 1;
2421	else if (strcmp(policy, LABEL_DROP) == 0)
2422		c->verdict = -NF_DROP - 1;
2423	else {
2424		errno = EINVAL;
2425		return 0;
2426	}
2427
2428	if (counters) {
2429		/* set byte and packet counters */
2430		memcpy(&c->counters, counters, sizeof(STRUCT_COUNTERS));
2431		c->counter_map.maptype = COUNTER_MAP_SET;
2432	} else {
2433		c->counter_map.maptype = COUNTER_MAP_NOMAP;
2434	}
2435
2436	set_changed(handle);
2437
2438	return 1;
2439}
2440
2441/* Without this, on gcc 2.7.2.3, we get:
2442   libiptc.c: In function `TC_COMMIT':
2443   libiptc.c:833: fixed or forbidden register was spilled.
2444   This may be due to a compiler bug or to impossible asm
2445   statements or clauses.
2446*/
2447static void
2448subtract_counters(STRUCT_COUNTERS *answer,
2449		  const STRUCT_COUNTERS *a,
2450		  const STRUCT_COUNTERS *b)
2451{
2452	answer->pcnt = a->pcnt - b->pcnt;
2453	answer->bcnt = a->bcnt - b->bcnt;
2454}
2455
2456
2457static void counters_nomap(STRUCT_COUNTERS_INFO *newcounters, unsigned int idx)
2458{
2459	newcounters->counters[idx] = ((STRUCT_COUNTERS) { 0, 0});
2460	DEBUGP_C("NOMAP => zero\n");
2461}
2462
2463static void counters_normal_map(STRUCT_COUNTERS_INFO *newcounters,
2464				STRUCT_REPLACE *repl, unsigned int idx,
2465				unsigned int mappos)
2466{
2467	/* Original read: X.
2468	 * Atomic read on replacement: X + Y.
2469	 * Currently in kernel: Z.
2470	 * Want in kernel: X + Y + Z.
2471	 * => Add in X + Y
2472	 * => Add in replacement read.
2473	 */
2474	newcounters->counters[idx] = repl->counters[mappos];
2475	DEBUGP_C("NORMAL_MAP => mappos %u \n", mappos);
2476}
2477
2478static void counters_map_zeroed(STRUCT_COUNTERS_INFO *newcounters,
2479				STRUCT_REPLACE *repl, unsigned int idx,
2480				unsigned int mappos, STRUCT_COUNTERS *counters)
2481{
2482	/* Original read: X.
2483	 * Atomic read on replacement: X + Y.
2484	 * Currently in kernel: Z.
2485	 * Want in kernel: Y + Z.
2486	 * => Add in Y.
2487	 * => Add in (replacement read - original read).
2488	 */
2489	subtract_counters(&newcounters->counters[idx],
2490			  &repl->counters[mappos],
2491			  counters);
2492	DEBUGP_C("ZEROED => mappos %u\n", mappos);
2493}
2494
2495static void counters_map_set(STRUCT_COUNTERS_INFO *newcounters,
2496                             unsigned int idx, STRUCT_COUNTERS *counters)
2497{
2498	/* Want to set counter (iptables-restore) */
2499
2500	memcpy(&newcounters->counters[idx], counters,
2501		sizeof(STRUCT_COUNTERS));
2502
2503	DEBUGP_C("SET\n");
2504}
2505
2506
2507int
2508TC_COMMIT(struct xtc_handle *handle)
2509{
2510	/* Replace, then map back the counters. */
2511	STRUCT_REPLACE *repl;
2512	STRUCT_COUNTERS_INFO *newcounters;
2513	struct chain_head *c;
2514	int ret;
2515	size_t counterlen;
2516	int new_number;
2517	unsigned int new_size;
2518
2519	iptc_fn = TC_COMMIT;
2520	CHECK(*handle);
2521
2522	/* Don't commit if nothing changed. */
2523	if (!handle->changed)
2524		goto finished;
2525
2526	new_number = iptcc_compile_table_prep(handle, &new_size);
2527	if (new_number < 0) {
2528		errno = ENOMEM;
2529		goto out_zero;
2530	}
2531
2532	repl = malloc(sizeof(*repl) + new_size);
2533	if (!repl) {
2534		errno = ENOMEM;
2535		goto out_zero;
2536	}
2537	memset(repl, 0, sizeof(*repl) + new_size);
2538
2539#if 0
2540	TC_DUMP_ENTRIES(*handle);
2541#endif
2542
2543	counterlen = sizeof(STRUCT_COUNTERS_INFO)
2544			+ sizeof(STRUCT_COUNTERS) * new_number;
2545
2546	/* These are the old counters we will get from kernel */
2547	repl->counters = malloc(sizeof(STRUCT_COUNTERS)
2548				* handle->info.num_entries);
2549	if (!repl->counters) {
2550		errno = ENOMEM;
2551		goto out_free_repl;
2552	}
2553	/* These are the counters we're going to put back, later. */
2554	newcounters = malloc(counterlen);
2555	if (!newcounters) {
2556		errno = ENOMEM;
2557		goto out_free_repl_counters;
2558	}
2559	memset(newcounters, 0, counterlen);
2560
2561	strcpy(repl->name, handle->info.name);
2562	repl->num_entries = new_number;
2563	repl->size = new_size;
2564
2565	repl->num_counters = handle->info.num_entries;
2566	repl->valid_hooks  = handle->info.valid_hooks;
2567
2568	DEBUGP("num_entries=%u, size=%u, num_counters=%u\n",
2569		repl->num_entries, repl->size, repl->num_counters);
2570
2571	ret = iptcc_compile_table(handle, repl);
2572	if (ret < 0) {
2573		errno = ret;
2574		goto out_free_newcounters;
2575	}
2576
2577
2578#ifdef IPTC_DEBUG2
2579	{
2580		int fd = open("/tmp/libiptc-so_set_replace.blob",
2581				O_CREAT|O_WRONLY);
2582		if (fd >= 0) {
2583			write(fd, repl, sizeof(*repl) + repl->size);
2584			close(fd);
2585		}
2586	}
2587#endif
2588
2589	ret = setsockopt(handle->sockfd, TC_IPPROTO, SO_SET_REPLACE, repl,
2590			 sizeof(*repl) + repl->size);
2591	if (ret < 0)
2592		goto out_free_newcounters;
2593
2594	/* Put counters back. */
2595	strcpy(newcounters->name, handle->info.name);
2596	newcounters->num_counters = new_number;
2597
2598	list_for_each_entry(c, &handle->chains, list) {
2599		struct rule_head *r;
2600
2601		/* Builtin chains have their own counters */
2602		if (iptcc_is_builtin(c)) {
2603			DEBUGP("counter for chain-index %u: ", c->foot_index);
2604			switch(c->counter_map.maptype) {
2605			case COUNTER_MAP_NOMAP:
2606				counters_nomap(newcounters, c->foot_index);
2607				break;
2608			case COUNTER_MAP_NORMAL_MAP:
2609				counters_normal_map(newcounters, repl,
2610						    c->foot_index,
2611						    c->counter_map.mappos);
2612				break;
2613			case COUNTER_MAP_ZEROED:
2614				counters_map_zeroed(newcounters, repl,
2615						    c->foot_index,
2616						    c->counter_map.mappos,
2617						    &c->counters);
2618				break;
2619			case COUNTER_MAP_SET:
2620				counters_map_set(newcounters, c->foot_index,
2621						 &c->counters);
2622				break;
2623			}
2624		}
2625
2626		list_for_each_entry(r, &c->rules, list) {
2627			DEBUGP("counter for index %u: ", r->index);
2628			switch (r->counter_map.maptype) {
2629			case COUNTER_MAP_NOMAP:
2630				counters_nomap(newcounters, r->index);
2631				break;
2632
2633			case COUNTER_MAP_NORMAL_MAP:
2634				counters_normal_map(newcounters, repl,
2635						    r->index,
2636						    r->counter_map.mappos);
2637				break;
2638
2639			case COUNTER_MAP_ZEROED:
2640				counters_map_zeroed(newcounters, repl,
2641						    r->index,
2642						    r->counter_map.mappos,
2643						    &r->entry->counters);
2644				break;
2645
2646			case COUNTER_MAP_SET:
2647				counters_map_set(newcounters, r->index,
2648						 &r->entry->counters);
2649				break;
2650			}
2651		}
2652	}
2653
2654#ifdef IPTC_DEBUG2
2655	{
2656		int fd = open("/tmp/libiptc-so_set_add_counters.blob",
2657				O_CREAT|O_WRONLY);
2658		if (fd >= 0) {
2659			write(fd, newcounters, counterlen);
2660			close(fd);
2661		}
2662	}
2663#endif
2664
2665	ret = setsockopt(handle->sockfd, TC_IPPROTO, SO_SET_ADD_COUNTERS,
2666			 newcounters, counterlen);
2667	if (ret < 0)
2668		goto out_free_newcounters;
2669
2670	free(repl->counters);
2671	free(repl);
2672	free(newcounters);
2673
2674finished:
2675	return 1;
2676
2677out_free_newcounters:
2678	free(newcounters);
2679out_free_repl_counters:
2680	free(repl->counters);
2681out_free_repl:
2682	free(repl);
2683out_zero:
2684	return 0;
2685}
2686
2687/* Translates errno numbers into more human-readable form than strerror. */
2688const char *
2689TC_STRERROR(int err)
2690{
2691	unsigned int i;
2692	struct table_struct {
2693		void *fn;
2694		int err;
2695		const char *message;
2696	} table [] =
2697	  { { TC_INIT, EPERM, "Permission denied (you must be root)" },
2698	    { TC_INIT, EINVAL, "Module is wrong version" },
2699	    { TC_INIT, ENOENT,
2700		    "Table does not exist (do you need to insmod?)" },
2701	    { TC_DELETE_CHAIN, ENOTEMPTY, "Chain is not empty" },
2702	    { TC_DELETE_CHAIN, EINVAL, "Can't delete built-in chain" },
2703	    { TC_DELETE_CHAIN, EMLINK,
2704	      "Can't delete chain with references left" },
2705	    { TC_CREATE_CHAIN, EEXIST, "Chain already exists" },
2706	    { TC_INSERT_ENTRY, E2BIG, "Index of insertion too big" },
2707	    { TC_REPLACE_ENTRY, E2BIG, "Index of replacement too big" },
2708	    { TC_DELETE_NUM_ENTRY, E2BIG, "Index of deletion too big" },
2709	    { TC_READ_COUNTER, E2BIG, "Index of counter too big" },
2710	    { TC_ZERO_COUNTER, E2BIG, "Index of counter too big" },
2711	    { TC_INSERT_ENTRY, ELOOP, "Loop found in table" },
2712	    { TC_INSERT_ENTRY, EINVAL, "Target problem" },
2713	    /* ENOENT for DELETE probably means no matching rule */
2714	    { TC_DELETE_ENTRY, ENOENT,
2715	      "Bad rule (does a matching rule exist in that chain?)" },
2716	    { TC_SET_POLICY, ENOENT,
2717	      "Bad built-in chain name" },
2718	    { TC_SET_POLICY, EINVAL,
2719	      "Bad policy name" },
2720
2721	    { NULL, 0, "Incompatible with this kernel" },
2722	    { NULL, ENOPROTOOPT, "iptables who? (do you need to insmod?)" },
2723	    { NULL, ENOSYS, "Will be implemented real soon.  I promise ;)" },
2724	    { NULL, ENOMEM, "Memory allocation problem" },
2725	    { NULL, ENOENT, "No chain/target/match by that name" },
2726	  };
2727
2728	for (i = 0; i < sizeof(table)/sizeof(struct table_struct); i++) {
2729		if ((!table[i].fn || table[i].fn == iptc_fn)
2730		    && table[i].err == err)
2731			return table[i].message;
2732	}
2733
2734	return strerror(err);
2735}
2736
2737const struct xtc_ops TC_OPS = {
2738	.commit        = TC_COMMIT,
2739	.free          = TC_FREE,
2740	.builtin       = TC_BUILTIN,
2741	.is_chain      = TC_IS_CHAIN,
2742	.flush_entries = TC_FLUSH_ENTRIES,
2743	.create_chain  = TC_CREATE_CHAIN,
2744	.set_policy    = TC_SET_POLICY,
2745	.strerror      = TC_STRERROR,
2746};
2747