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