add new counter scheme
diff --git a/communication.c b/communication.c
index 1035ae9..8216332 100644
--- a/communication.c
+++ b/communication.c
@@ -334,7 +334,9 @@
 	socklen_t optlen;
 	struct ebt_replace repl;
 	struct ebt_cntchanges *cc = u_repl->counterchanges, *cc2, **cc3;
-	int i;
+	struct ebt_u_entries *entries;
+	struct ebt_u_entry *next = NULL;
+	int i, chainnr = 0;
 
 	if (u_repl->nentries == 0)
 		return;
@@ -347,11 +349,15 @@
 	old = u_repl->counters;
 	new = newcounters;
 	while (cc) {
+		if (!next) {
+			while (!(entries = ebt_nr_to_chain(u_repl, chainnr++)));
+			if (!(next = entries->entries))
+				continue;
+		}
 		if (cc->type == CNT_NORM) {
 			/* 'Normal' rule, meaning we didn't do anything to it
 			 * So, we just copy */
-			new->pcnt = old->pcnt;
-			new->bcnt = old->bcnt;
+			*new = *old;
 			/* We've used an old counter */
 			old++;
 			/* We've set a new counter */
@@ -359,13 +365,14 @@
 		} else if (cc->type == CNT_DEL) {
 			/* Don't use this old counter */
 			old++;
-		} else if (cc->type == CNT_ADD) {
-			/* New counter, let it stay 0 */
-			new++;
 		} else {
-			/* Zero it (let it stay 0) */
-			old++;
-			new++;
+			*new = next->cnt;
+			if (cc->type == CNT_ADD)
+				new++;
+			else {
+				old++;
+				new++;
+			}
 		}
 		cc = cc->next;
 	}
@@ -490,6 +497,9 @@
 		memcpy(new->sourcemsk, e->sourcemsk, sizeof(new->sourcemsk));
 		memcpy(new->destmac, e->destmac, sizeof(new->destmac));
 		memcpy(new->destmsk, e->destmsk, sizeof(new->destmsk));
+		if (*totalcnt >= u_repl->nentries)
+			ebt_print_bug("*totalcnt >= u_repl->nentries");
+		new->cnt = u_repl->counters[*totalcnt];
 		new->m_list = NULL;
 		new->w_list = NULL;
 		new->next = NULL;
@@ -748,8 +758,7 @@
 	strcpy(repl.name, u_repl->name);
 	if (u_repl->filename != NULL) {
 		if (init)
-			ebt_print_bug("Getting initial table data from a "
-				  "file is impossible");
+			ebt_print_bug("Getting initial table data from a file is impossible");
 		if (retrieve_from_file(u_repl->filename, &repl, u_repl->command))
 			return -1;
 		/* -L with a wrong table name should be dealt with silently */
@@ -761,7 +770,7 @@
 	u_repl->valid_hooks = repl.valid_hooks;
 	u_repl->nentries = repl.nentries;
 	u_repl->num_counters = repl.num_counters;
-	u_repl->counters = (struct ebt_counter *)repl.counters;
+	u_repl->counters = repl.counters;
 	u_repl->udc = NULL;
 	u_repl->counterchanges = NULL;
 	for (i = 0; i < repl.nentries; i++) {
@@ -780,9 +789,7 @@
 	   &hook, u_repl, u_repl->valid_hooks);
 	i = 0; /* Holds the expected nr. of entries for the chain */
 	j = 0; /* Holds the up to now counted entries for the chain */
-	/* Holds the total nr. of entries,
-	 * should equal u_repl->nentries afterwards */
-	k = 0;
+	k = 0; /* Holds the total nr. of entries, should equal u_repl->nentries afterwards */
 	hook = -1;
 	EBT_ENTRY_ITERATE((char *)repl.entries, repl.entries_size,
 	   ebt_translate_entry, &hook, &i, &j, &k, &u_e, u_repl,
diff --git a/ebtables.c b/ebtables.c
index 62b6c21..f3ea7c6 100644
--- a/ebtables.c
+++ b/ebtables.c
@@ -300,8 +300,8 @@
 		t->print(hlp, hlp->t);
 		if (replace->flags & LIST_C)
 			printf(", pcnt = %llu -- bcnt = %llu",
-			   replace->counters[entries->counter_offset + i].pcnt,
-			   replace->counters[entries->counter_offset + i].bcnt);
+			   hlp->cnt.pcnt,
+			   hlp->cnt.bcnt);
 		printf("\n");
 		hlp = hlp->next;
 	}
@@ -366,7 +366,6 @@
 	printf("\n");
 	if (table->help)
 		table->help(ebt_hooknames);
-	exit(0);
 }
 
 /* Execute command L */
@@ -659,7 +658,7 @@
 			i = -1;
 			if (optind < argc && argv[optind][0] != '-') {
 				if ((i = ebt_get_chainnr(replace, argv[optind])) == -1)
-					ebt_print_error2("Bad chain");
+					ebt_print_error2("Chain %s doesn't exist", argv[optind]);
 				optind++;
 			}
 			if (i != -1) {
@@ -1020,8 +1019,11 @@
 	if (!(table = ebt_find_table(replace->name)))
 		ebt_print_error2("Bad table name");
 
-	if (replace->command == 'h' && !(replace->flags & OPT_ZERO))
+	if (replace->command == 'h' && !(replace->flags & OPT_ZERO)) {
 		print_help();
+		if (exec_style == EXEC_STYLE_PRG)
+			exit(0);
+	}
 
 	/* Do the final checks */
 	if (replace->command == 'A' || replace->command == 'I' ||
diff --git a/include/ebtables_u.h b/include/ebtables_u.h
index d5264e3..5632ec1 100644
--- a/include/ebtables_u.h
+++ b/include/ebtables_u.h
@@ -129,6 +129,7 @@
 	struct ebt_u_watcher_list *w_list;
 	struct ebt_entry_target *t;
 	struct ebt_u_entry *next;
+	struct ebt_counter cnt;
 	/* the standard target needs this to know the name of a udc when
 	 * printing out rules. */
 	struct ebt_u_replace *replace;
diff --git a/libebtc.c b/libebtc.c
index 0fef235..03b7bfe 100644
--- a/libebtc.c
+++ b/libebtc.c
@@ -171,6 +171,7 @@
 	e->w_list = NULL;
 	e->t = (struct ebt_entry_target *)ebt_find_target(EBT_STANDARD_TARGET);
 	ebt_find_target(EBT_STANDARD_TARGET)->used = 1;
+	e->cnt.pcnt = e->cnt.bcnt = 0;
 
 	if (!e->t)
 		ebt_print_bug("Couldn't load standard target");