2 * libebtc.c, January 2004
4 * Contains the functions with which to make a table in userspace.
6 * Author: Bart De Schuymer
8 * This code is stongly inspired on the iptables code which is
9 * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation; either version 2 of the
14 * License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
30 #include "include/ebtables_u.h"
31 #include "include/ethernetdb.h"
36 static void decrease_chain_jumps(struct ebt_u_replace
*replace
);
37 static int iterate_entries(struct ebt_u_replace
*replace
, int type
);
39 /* The standard names */
40 const char *ebt_hooknames
[NF_BR_NUMHOOKS
] =
42 [NF_BR_PRE_ROUTING
]"PREROUTING",
43 [NF_BR_LOCAL_IN
]"INPUT",
44 [NF_BR_FORWARD
]"FORWARD",
45 [NF_BR_LOCAL_OUT
]"OUTPUT",
46 [NF_BR_POST_ROUTING
]"POSTROUTING",
47 [NF_BR_BROUTING
]"BROUTING"
50 /* The four target names */
51 const char* ebt_standard_targets
[NUM_STANDARD_TARGETS
] =
59 /* The lists of supported tables, matches, watchers and targets */
60 struct ebt_u_table
*ebt_tables
;
61 struct ebt_u_match
*ebt_matches
;
62 struct ebt_u_watcher
*ebt_watchers
;
63 struct ebt_u_target
*ebt_targets
;
65 /* Find the right structure belonging to a name */
66 struct ebt_u_target
*ebt_find_target(const char *name
)
68 struct ebt_u_target
*t
= ebt_targets
;
70 while (t
&& strcmp(t
->name
, name
))
75 struct ebt_u_match
*ebt_find_match(const char *name
)
77 struct ebt_u_match
*m
= ebt_matches
;
79 while (m
&& strcmp(m
->name
, name
))
84 struct ebt_u_watcher
*ebt_find_watcher(const char *name
)
86 struct ebt_u_watcher
*w
= ebt_watchers
;
88 while (w
&& strcmp(w
->name
, name
))
93 struct ebt_u_table
*ebt_find_table(const char *name
)
95 struct ebt_u_table
*t
= ebt_tables
;
97 while (t
&& strcmp(t
->name
, name
))
102 /* Prints all registered extensions */
103 void ebt_list_extensions()
105 struct ebt_u_table
*tbl
= ebt_tables
;
106 struct ebt_u_target
*t
= ebt_targets
;
107 struct ebt_u_match
*m
= ebt_matches
;
108 struct ebt_u_watcher
*w
= ebt_watchers
;
111 printf("Loaded userspace extensions:\n\nLoaded tables:\n");
113 printf("%s\n", tbl
->name
);
116 printf("\nLoaded targets:\n");
118 printf("%s\n", t
->name
);
121 printf("\nLoaded matches:\n");
123 printf("%s\n", m
->name
);
126 printf("\nLoaded watchers:\n");
128 printf("%s\n", w
->name
);
133 /* Get the table from the kernel or from a binary file
134 * init: 1 = ask the kernel for the initial contents of a table, i.e. the
135 * way it looks when the table is insmod'ed
136 * 0 = get the current data in the table */
137 int ebt_get_kernel_table(struct ebt_u_replace
*replace
, int init
)
139 if (!ebt_find_table(replace
->name
)) {
140 ebt_print_error("Bad table name '%s'", replace
->name
);
143 /* Get the kernel's information */
144 if (ebt_get_table(replace
, init
)) {
145 if (ebt_errormsg
[0] != '\0')
147 ebtables_insmod("ebtables");
148 if (ebt_get_table(replace
, init
)) {
149 ebt_print_error("The kernel doesn't support the ebtables '%s' table", replace
->name
);
156 /* Put sane values into a new entry */
157 void ebt_initialize_entry(struct ebt_u_entry
*e
)
159 e
->bitmask
= EBT_NOPROTO
;
164 strcpy(e
->logical_in
, "");
165 strcpy(e
->logical_out
, "");
168 e
->t
= (struct ebt_entry_target
*)ebt_find_target(EBT_STANDARD_TARGET
);
169 ebt_find_target(EBT_STANDARD_TARGET
)->used
= 1;
170 e
->cnt
.pcnt
= e
->cnt
.bcnt
= e
->cnt_surplus
.pcnt
= e
->cnt_surplus
.bcnt
= 0;
173 ebt_print_bug("Couldn't load standard target");
174 ((struct ebt_standard_target
*)((struct ebt_u_target
*)e
->t
)->t
)->verdict
= EBT_CONTINUE
;
177 /* Free up the memory of the table held in userspace, *replace can be reused */
178 void ebt_cleanup_replace(struct ebt_u_replace
*replace
)
181 struct ebt_u_entries
*entries
;
182 struct ebt_cntchanges
*cc1
, *cc2
;
183 struct ebt_u_entry
*u_e1
, *u_e2
;
185 replace
->name
[0] = '\0';
186 replace
->valid_hooks
= 0;
187 replace
->nentries
= 0;
188 replace
->num_counters
= 0;
190 replace
->command
= 0;
191 replace
->selected_chain
= -1;
192 free(replace
->filename
);
193 replace
->filename
= NULL
;
194 free(replace
->counters
);
195 replace
->counters
= NULL
;
197 for (i
= 0; i
< replace
->num_chains
; i
++) {
198 if (!(entries
= replace
->chains
[i
]))
200 u_e1
= entries
->entries
->next
;
201 while (u_e1
!= entries
->entries
) {
202 ebt_free_u_entry(u_e1
);
207 free(entries
->entries
);
209 replace
->chains
[i
] = NULL
;
211 cc1
= replace
->cc
->next
;
212 while (cc1
!= replace
->cc
) {
217 replace
->cc
->next
= replace
->cc
->prev
= replace
->cc
;
220 /* Should be called, e.g., between 2 rule adds */
221 void ebt_reinit_extensions()
223 struct ebt_u_match
*m
;
224 struct ebt_u_watcher
*w
;
225 struct ebt_u_target
*t
;
228 /* The init functions should determine by themselves whether they are
229 * called for the first time or not (when necessary). */
230 for (m
= ebt_matches
; m
; m
= m
->next
) {
232 size
= EBT_ALIGN(m
->size
) + sizeof(struct ebt_entry_match
);
233 m
->m
= (struct ebt_entry_match
*)malloc(size
);
236 strcpy(m
->m
->u
.name
, m
->name
);
237 m
->m
->match_size
= EBT_ALIGN(m
->size
);
240 m
->flags
= 0; /* An error can occur before used is set, while flags is changed. */
243 for (w
= ebt_watchers
; w
; w
= w
->next
) {
245 size
= EBT_ALIGN(w
->size
) + sizeof(struct ebt_entry_watcher
);
246 w
->w
= (struct ebt_entry_watcher
*)malloc(size
);
249 strcpy(w
->w
->u
.name
, w
->name
);
250 w
->w
->watcher_size
= EBT_ALIGN(w
->size
);
256 for (t
= ebt_targets
; t
; t
= t
->next
) {
258 size
= EBT_ALIGN(t
->size
) + sizeof(struct ebt_entry_target
);
259 t
->t
= (struct ebt_entry_target
*)malloc(size
);
262 strcpy(t
->t
->u
.name
, t
->name
);
263 t
->t
->target_size
= EBT_ALIGN(t
->size
);
271 /* This doesn't free e, because the calling function might need e->next */
272 void ebt_free_u_entry(struct ebt_u_entry
*e
)
274 struct ebt_u_match_list
*m_l
, *m_l2
;
275 struct ebt_u_watcher_list
*w_l
, *w_l2
;
294 static char *get_modprobe(void)
299 procfile
= open(PROC_SYS_MODPROBE
, O_RDONLY
);
305 if (read(procfile
, ret
, 1024) == -1)
307 /* The kernel adds a '\n' */
309 *strchr(ret
, '\n') = '\0';
320 /* Try to load the kernel module, analogous to ip_tables.c */
321 int ebtables_insmod(const char *modname
)
326 /* If they don't explicitly set it, read out of /proc */
328 buf
= get_modprobe();
331 ebt_modprobe
= buf
; /* Keep the value for possible later use */
336 argv
[0] = (char *)ebt_modprobe
;
337 argv
[1] = (char *)modname
;
339 execv(argv
[0], argv
);
341 /* Not usually reached */
346 default: /* Parent */
353 /* Parse the chain name and return a pointer to the chain base.
354 * Returns NULL on failure. */
355 struct ebt_u_entries
*ebt_name_to_chain(const struct ebt_u_replace
*replace
, const char* arg
)
358 struct ebt_u_entries
*chain
;
360 for (i
= 0; i
< replace
->num_chains
; i
++) {
361 if (!(chain
= replace
->chains
[i
]))
363 if (!strcmp(arg
, chain
->name
))
369 /* Parse the chain name and return the corresponding chain nr
370 * returns -1 on failure */
371 int ebt_get_chainnr(const struct ebt_u_replace
*replace
, const char* arg
)
375 for (i
= 0; i
< replace
->num_chains
; i
++) {
376 if (!replace
->chains
[i
])
378 if (!strcmp(arg
, replace
->chains
[i
]->name
))
392 /* Change the policy of selected_chain.
393 * Handing a bad policy to this function is a bug. */
394 void ebt_change_policy(struct ebt_u_replace
*replace
, int policy
)
396 struct ebt_u_entries
*entries
= ebt_to_chain(replace
);
398 if (policy
< -NUM_STANDARD_TARGETS
|| policy
== EBT_CONTINUE
)
399 ebt_print_bug("Wrong policy: %d", policy
);
400 entries
->policy
= policy
;
403 void ebt_delete_cc(struct ebt_cntchanges
*cc
)
405 if (cc
->type
== CNT_ADD
) {
406 cc
->prev
->next
= cc
->next
;
407 cc
->next
->prev
= cc
->prev
;
413 void ebt_empty_chain(struct ebt_u_entries
*entries
)
415 struct ebt_u_entry
*u_e
= entries
->entries
->next
, *tmp
;
416 while (u_e
!= entries
->entries
) {
417 ebt_delete_cc(u_e
->cc
);
418 ebt_free_u_entry(u_e
);
423 entries
->entries
->next
= entries
->entries
->prev
= entries
->entries
;
424 entries
->nentries
= 0;
427 /* Flush one chain or the complete table
428 * If selected_chain == -1 then flush the complete table */
429 void ebt_flush_chains(struct ebt_u_replace
*replace
)
432 struct ebt_u_entries
*entries
= ebt_to_chain(replace
);
434 /* Flush whole table */
436 if (replace
->nentries
== 0)
438 replace
->nentries
= 0;
440 /* Free everything and zero (n)entries */
441 for (i
= 0; i
< replace
->num_chains
; i
++) {
442 if (!(entries
= replace
->chains
[i
]))
444 entries
->counter_offset
= 0;
445 ebt_empty_chain(entries
);
450 if (entries
->nentries
== 0)
452 replace
->nentries
-= entries
->nentries
;
453 numdel
= entries
->nentries
;
455 /* Update counter_offset */
456 for (i
= replace
->selected_chain
+1; i
< replace
->num_chains
; i
++) {
457 if (!(entries
= replace
->chains
[i
]))
459 entries
->counter_offset
-= numdel
;
462 entries
= ebt_to_chain(replace
);
463 ebt_empty_chain(entries
);
466 #define OPT_COUNT 0x1000 /* This value is also defined in ebtables.c */
467 /* Returns the rule number on success (starting from 0), -1 on failure
469 * This function expects the ebt_{match,watcher,target} members of new_entry
470 * to contain pointers to ebt_u_{match,watcher,target} */
471 int ebt_check_rule_exists(struct ebt_u_replace
*replace
,
472 struct ebt_u_entry
*new_entry
)
474 struct ebt_u_entry
*u_e
;
475 struct ebt_u_match_list
*m_l
, *m_l2
;
476 struct ebt_u_match
*m
;
477 struct ebt_u_watcher_list
*w_l
, *w_l2
;
478 struct ebt_u_watcher
*w
;
479 struct ebt_u_target
*t
= (struct ebt_u_target
*)new_entry
->t
;
480 struct ebt_u_entries
*entries
= ebt_to_chain(replace
);
483 u_e
= entries
->entries
->next
;
484 /* Check for an existing rule (if there are duplicate rules,
485 * take the first occurance) */
486 for (i
= 0; i
< entries
->nentries
; i
++, u_e
= u_e
->next
) {
487 if (u_e
->ethproto
!= new_entry
->ethproto
)
489 if (strcmp(u_e
->in
, new_entry
->in
))
491 if (strcmp(u_e
->out
, new_entry
->out
))
493 if (strcmp(u_e
->logical_in
, new_entry
->logical_in
))
495 if (strcmp(u_e
->logical_out
, new_entry
->logical_out
))
497 if (new_entry
->bitmask
& EBT_SOURCEMAC
&&
498 memcmp(u_e
->sourcemac
, new_entry
->sourcemac
, ETH_ALEN
))
500 if (new_entry
->bitmask
& EBT_DESTMAC
&&
501 memcmp(u_e
->destmac
, new_entry
->destmac
, ETH_ALEN
))
503 if (new_entry
->bitmask
!= u_e
->bitmask
||
504 new_entry
->invflags
!= u_e
->invflags
)
506 if (replace
->flags
& OPT_COUNT
&& (new_entry
->cnt
.pcnt
!=
507 u_e
->cnt
.pcnt
|| new_entry
->cnt
.bcnt
!= u_e
->cnt
.bcnt
))
509 /* Compare all matches */
510 m_l
= new_entry
->m_list
;
513 m
= (struct ebt_u_match
*)(m_l
->m
);
515 while (m_l2
&& strcmp(m_l2
->m
->u
.name
, m
->m
->u
.name
))
517 if (!m_l2
|| !m
->compare(m
->m
, m_l2
->m
))
522 /* Now be sure they have the same nr of matches */
532 /* Compare all watchers */
533 w_l
= new_entry
->w_list
;
536 w
= (struct ebt_u_watcher
*)(w_l
->w
);
538 while (w_l2
&& strcmp(w_l2
->w
->u
.name
, w
->w
->u
.name
))
540 if (!w_l2
|| !w
->compare(w
->w
, w_l2
->w
))
553 if (strcmp(t
->t
->u
.name
, u_e
->t
->u
.name
))
555 if (!t
->compare(t
->t
, u_e
->t
))
563 /* Add a rule, rule_nr is the rule to update
564 * rule_nr specifies where the rule should be inserted
565 * rule_nr > 0 : insert the rule right before the rule_nr'th rule
566 * (the first rule is rule 1)
567 * rule_nr < 0 : insert the rule right before the (n+rule_nr+1)'th rule,
568 * where n denotes the number of rules in the chain
569 * rule_nr == 0: add a new rule at the end of the chain
571 * This function expects the ebt_{match,watcher,target} members of new_entry
572 * to contain pointers to ebt_u_{match,watcher,target} and updates these
573 * pointers so that they point to ebt_{match,watcher,target}, before adding
574 * the rule to the chain. Don't free() the ebt_{match,watcher,target} and
575 * don't reuse the new_entry after a successful call to ebt_add_rule() */
576 void ebt_add_rule(struct ebt_u_replace
*replace
, struct ebt_u_entry
*new_entry
, int rule_nr
)
579 struct ebt_u_entry
*u_e
;
580 struct ebt_u_match_list
*m_l
;
581 struct ebt_u_watcher_list
*w_l
;
582 struct ebt_u_entries
*entries
= ebt_to_chain(replace
);
583 struct ebt_cntchanges
*cc
, *new_cc
;
586 rule_nr
+= entries
->nentries
;
589 if (rule_nr
> entries
->nentries
|| rule_nr
< 0) {
590 ebt_print_error("The specified rule number is incorrect");
593 /* Go to the right position in the chain */
594 if (rule_nr
== entries
->nentries
)
595 u_e
= entries
->entries
;
597 u_e
= entries
->entries
->next
;
598 for (i
= 0; i
< rule_nr
; i
++)
601 /* We're adding one rule */
604 /* Insert the rule */
605 new_entry
->next
= u_e
;
606 new_entry
->prev
= u_e
->prev
;
607 u_e
->prev
->next
= new_entry
;
608 u_e
->prev
= new_entry
;
609 new_cc
= (struct ebt_cntchanges
*)malloc(sizeof(struct ebt_cntchanges
));
612 new_cc
->type
= CNT_ADD
;
614 if (new_entry
->next
== entries
->entries
) {
615 for (i
= replace
->selected_chain
+1; i
< replace
->num_chains
; i
++)
616 if (!replace
->chains
[i
] || replace
->chains
[i
]->nentries
== 0)
620 if (i
== replace
->num_chains
)
623 cc
= replace
->chains
[i
]->entries
->next
->cc
;
625 cc
= new_entry
->next
->cc
;
627 new_cc
->prev
= cc
->prev
;
628 cc
->prev
->next
= new_cc
;
630 new_entry
->cc
= new_cc
;
632 /* Put the ebt_{match, watcher, target} pointers in place */
633 m_l
= new_entry
->m_list
;
635 m_l
->m
= ((struct ebt_u_match
*)m_l
->m
)->m
;
638 w_l
= new_entry
->w_list
;
640 w_l
->w
= ((struct ebt_u_watcher
*)w_l
->w
)->w
;
643 new_entry
->t
= ((struct ebt_u_target
*)new_entry
->t
)->t
;
644 /* Update the counter_offset of chains behind this one */
645 for (i
= replace
->selected_chain
+1; i
< replace
->num_chains
; i
++) {
646 entries
= replace
->chains
[i
];
647 if (!(entries
= replace
->chains
[i
]))
649 entries
->counter_offset
++;
653 /* If *begin==*end==0 then find the rule corresponding to new_entry,
654 * else make the rule numbers positive (starting from 0) and check
655 * for bad rule numbers. */
656 static int check_and_change_rule_number(struct ebt_u_replace
*replace
,
657 struct ebt_u_entry
*new_entry
, int *begin
, int *end
)
659 struct ebt_u_entries
*entries
= ebt_to_chain(replace
);
662 *begin
+= entries
->nentries
+ 1;
664 *end
+= entries
->nentries
+ 1;
666 if (*begin
< 0 || *begin
> *end
|| *end
> entries
->nentries
) {
667 ebt_print_error("Sorry, wrong rule numbers");
671 if ((*begin
* *end
== 0) && (*begin
+ *end
!= 0))
672 ebt_print_bug("begin and end should be either both zero, "
673 "either both non-zero");
678 *begin
= ebt_check_rule_exists(replace
, new_entry
);
681 ebt_print_error("Sorry, rule does not exist");
688 /* Delete a rule or rules
689 * begin == end == 0: delete the rule corresponding to new_entry
691 * The first rule has rule nr 1, the last rule has rule nr -1, etc.
692 * This function expects the ebt_{match,watcher,target} members of new_entry
693 * to contain pointers to ebt_u_{match,watcher,target}. */
694 void ebt_delete_rule(struct ebt_u_replace
*replace
,
695 struct ebt_u_entry
*new_entry
, int begin
, int end
)
698 struct ebt_u_entry
*u_e
, *u_e2
, *u_e3
;
699 struct ebt_u_entries
*entries
= ebt_to_chain(replace
);
701 if (check_and_change_rule_number(replace
, new_entry
, &begin
, &end
))
703 /* We're deleting rules */
704 nr_deletes
= end
- begin
+ 1;
705 replace
->nentries
-= nr_deletes
;
706 entries
->nentries
-= nr_deletes
;
707 /* Go to the right position in the chain */
708 u_e
= entries
->entries
->next
;
709 for (i
= 0; i
< begin
; i
++)
712 /* Remove the rules */
713 for (i
= 0; i
< nr_deletes
; i
++) {
715 ebt_delete_cc(u_e2
->cc
);
717 /* Free everything */
718 ebt_free_u_entry(u_e2
);
723 /* Update the counter_offset of chains behind this one */
724 for (i
= replace
->selected_chain
+1; i
< replace
->num_chains
; i
++) {
725 if (!(entries
= replace
->chains
[i
]))
727 entries
->counter_offset
-= nr_deletes
;
731 /* Change the counters of a rule or rules
732 * begin == end == 0: change counters of the rule corresponding to new_entry
734 * The first rule has rule nr 1, the last rule has rule nr -1, etc.
735 * This function expects the ebt_{match,watcher,target} members of new_entry
736 * to contain pointers to ebt_u_{match,watcher,target}.
737 * The mask denotes the following:
738 * pcnt: mask % 3 = 0 : change; = 1: increment; = 2: decrement
739 * bcnt: mask / 3 = 0 : change; = 1: increment = 2: increment
740 * In daemon mode, mask==0 must hold */
741 void ebt_change_counters(struct ebt_u_replace
*replace
,
742 struct ebt_u_entry
*new_entry
, int begin
, int end
,
743 struct ebt_counter
*cnt
, int mask
)
746 struct ebt_u_entry
*u_e
;
747 struct ebt_u_entries
*entries
= ebt_to_chain(replace
);
749 if (check_and_change_rule_number(replace
, new_entry
, &begin
, &end
))
751 u_e
= entries
->entries
->next
;
752 for (i
= 0; i
< begin
; i
++)
754 for (i
= end
-begin
+1; i
> 0; i
--) {
756 u_e
->cnt
.pcnt
= (*cnt
).pcnt
;
757 u_e
->cnt_surplus
.pcnt
= 0;
760 if (u_e
->cc
->type
!= CNT_NORM
)
761 ebt_print_bug("cc->type != CNT_NORM");
763 u_e
->cnt_surplus
.pcnt
= (*cnt
).pcnt
;
767 u_e
->cnt
.bcnt
= (*cnt
).bcnt
;
768 u_e
->cnt_surplus
.bcnt
= 0;
771 if (u_e
->cc
->type
!= CNT_NORM
)
772 ebt_print_bug("cc->type != CNT_NORM");
774 u_e
->cnt_surplus
.bcnt
= (*cnt
).bcnt
;
776 if (u_e
->cc
->type
!= CNT_ADD
)
777 u_e
->cc
->type
= CNT_CHANGE
;
778 u_e
->cc
->change
= mask
;
783 /* If selected_chain == -1 then zero all counters,
784 * otherwise, zero the counters of selected_chain */
785 void ebt_zero_counters(struct ebt_u_replace
*replace
)
787 struct ebt_u_entries
*entries
= ebt_to_chain(replace
);
788 struct ebt_u_entry
*next
;
792 for (i
= 0; i
< replace
->num_chains
; i
++) {
793 if (!(entries
= replace
->chains
[i
]))
795 next
= entries
->entries
->next
;
796 while (next
!= entries
->entries
) {
797 if (next
->cc
->type
== CNT_NORM
)
798 next
->cc
->type
= CNT_CHANGE
;
799 next
->cnt
.bcnt
= next
->cnt
.pcnt
= 0;
800 next
->cc
->change
= 0;
805 if (entries
->nentries
== 0)
808 next
= entries
->entries
->next
;
809 while (next
!= entries
->entries
) {
810 if (next
->cc
->type
== CNT_NORM
)
811 next
->cc
->type
= CNT_CHANGE
;
812 next
->cnt
.bcnt
= next
->cnt
.pcnt
= 0;
818 /* Add a new chain and specify its policy */
819 void ebt_new_chain(struct ebt_u_replace
*replace
, const char *name
, int policy
)
821 struct ebt_u_entries
*new;
823 if (replace
->num_chains
== replace
->max_chains
)
824 ebt_double_chains(replace
);
825 new = (struct ebt_u_entries
*)malloc(sizeof(struct ebt_u_entries
));
828 replace
->chains
[replace
->num_chains
++] = new;
830 new->policy
= policy
;
831 new->counter_offset
= replace
->nentries
;
833 strcpy(new->name
, name
);
834 new->entries
= (struct ebt_u_entry
*)malloc(sizeof(struct ebt_u_entry
));
837 new->entries
->next
= new->entries
->prev
= new->entries
;
838 new->kernel_start
= NULL
;
841 /* returns -1 if the chain is referenced, 0 on success */
842 static int ebt_delete_a_chain(struct ebt_u_replace
*replace
, int chain
, int print_err
)
844 int tmp
= replace
->selected_chain
;
845 /* If the chain is referenced, don't delete it,
846 * also decrement jumps to a chain behind the
847 * one we're deleting */
848 replace
->selected_chain
= chain
;
849 if (ebt_check_for_references(replace
, print_err
))
851 decrease_chain_jumps(replace
);
852 ebt_flush_chains(replace
);
853 replace
->selected_chain
= tmp
;
854 free(replace
->chains
[chain
]->entries
);
855 free(replace
->chains
[chain
]);
856 memmove(replace
->chains
+chain
, replace
->chains
+chain
+1, (replace
->num_chains
-chain
-1)*sizeof(void *));
857 replace
->num_chains
--;
861 /* Selected_chain == -1: delete all non-referenced udc
862 * selected_chain < NF_BR_NUMHOOKS is illegal */
863 void ebt_delete_chain(struct ebt_u_replace
*replace
)
865 if (replace
->selected_chain
!= -1 && replace
->selected_chain
< NF_BR_NUMHOOKS
)
866 ebt_print_bug("You can't remove a standard chain");
867 if (replace
->selected_chain
== -1) {
868 int i
= NF_BR_NUMHOOKS
;
870 while (i
< replace
->num_chains
)
871 if (ebt_delete_a_chain(replace
, i
, 0))
874 ebt_delete_a_chain(replace
, replace
->selected_chain
, 1);
877 /* Rename an existing chain. */
878 void ebt_rename_chain(struct ebt_u_replace
*replace
, const char *name
)
880 struct ebt_u_entries
*entries
= ebt_to_chain(replace
);
883 ebt_print_bug("ebt_rename_chain: entries == NULL");
884 strcpy(entries
->name
, name
);
889 *************************
890 *************************
891 **SPECIALIZED*FUNCTIONS**
892 *************************
893 *************************
897 void ebt_double_chains(struct ebt_u_replace
*replace
)
899 struct ebt_u_entries
**new;
901 replace
->max_chains
*= 2;
902 new = (struct ebt_u_entries
**)malloc(replace
->max_chains
*sizeof(void *));
905 memcpy(new, replace
->chains
, replace
->max_chains
/2*sizeof(void *));
906 free(replace
->chains
);
907 replace
->chains
= new;
910 /* Executes the final_check() function for all extensions used by the rule
911 * ebt_check_for_loops should have been executed earlier, to make sure the
912 * hook_mask is correct. The time argument to final_check() is set to 1,
913 * meaning it's the second time the final_check() function is executed. */
914 void ebt_do_final_checks(struct ebt_u_replace
*replace
, struct ebt_u_entry
*e
,
915 struct ebt_u_entries
*entries
)
917 struct ebt_u_match_list
*m_l
;
918 struct ebt_u_watcher_list
*w_l
;
919 struct ebt_u_target
*t
;
920 struct ebt_u_match
*m
;
921 struct ebt_u_watcher
*w
;
926 m
= ebt_find_match(m_l
->m
->u
.name
);
927 m
->final_check(e
, m_l
->m
, replace
->name
,
928 entries
->hook_mask
, 1);
929 if (ebt_errormsg
[0] != '\0')
934 w
= ebt_find_watcher(w_l
->w
->u
.name
);
935 w
->final_check(e
, w_l
->w
, replace
->name
,
936 entries
->hook_mask
, 1);
937 if (ebt_errormsg
[0] != '\0')
941 t
= ebt_find_target(e
->t
->u
.name
);
942 t
->final_check(e
, e
->t
, replace
->name
,
943 entries
->hook_mask
, 1);
946 /* Returns 1 (if it returns) when the chain is referenced, 0 when it isn't.
947 * print_err: 0 (resp. 1) = don't (resp. do) print error when referenced */
948 int ebt_check_for_references(struct ebt_u_replace
*replace
, int print_err
)
951 return iterate_entries(replace
, 1);
953 return iterate_entries(replace
, 2);
956 /* chain_nr: nr of the udc (>= NF_BR_NUMHOOKS)
957 * Returns 1 (if it returns) when the chain is referenced, 0 when it isn't.
958 * print_err: 0 (resp. 1) = don't (resp. do) print error when referenced */
959 int ebt_check_for_references2(struct ebt_u_replace
*replace
, int chain_nr
,
962 int tmp
= replace
->selected_chain
, ret
;
964 replace
->selected_chain
= chain_nr
;
966 ret
= iterate_entries(replace
, 1);
968 ret
= iterate_entries(replace
, 2);
969 replace
->selected_chain
= tmp
;
977 struct ebt_u_entry
*e
;
978 struct ebt_u_entries
*entries
;
982 * As a by-product, the hook_mask member of each chain is filled in
983 * correctly. The check functions of the extensions need this hook_mask
984 * to know from which standard chains they can be called. */
985 void ebt_check_for_loops(struct ebt_u_replace
*replace
)
987 int chain_nr
, i
, j
, k
, sp
= 0, verdict
;
988 struct ebt_u_entries
*entries
, *entries2
;
989 struct ebt_u_stack
*stack
= NULL
;
990 struct ebt_u_entry
*e
;
992 /* Initialize hook_mask to 0 */
993 for (i
= 0; i
< replace
->num_chains
; i
++) {
994 if (!(entries
= replace
->chains
[i
]))
996 if (i
< NF_BR_NUMHOOKS
)
997 /* (1 << NF_BR_NUMHOOKS) implies it's a standard chain
998 * (usefull in the final_check() funtions) */
999 entries
->hook_mask
= (1 << i
) | (1 << NF_BR_NUMHOOKS
);
1001 entries
->hook_mask
= 0;
1003 if (replace
->num_chains
== NF_BR_NUMHOOKS
)
1005 stack
= (struct ebt_u_stack
*)malloc((replace
->num_chains
- NF_BR_NUMHOOKS
) * sizeof(struct ebt_u_stack
));
1009 /* Check for loops, starting from every base chain */
1010 for (i
= 0; i
< NF_BR_NUMHOOKS
; i
++) {
1011 if (!(entries
= replace
->chains
[i
]))
1015 e
= entries
->entries
->next
;
1016 for (j
= 0; j
< entries
->nentries
; j
++) {
1017 if (strcmp(e
->t
->u
.name
, EBT_STANDARD_TARGET
))
1019 verdict
= ((struct ebt_standard_target
*)(e
->t
))->verdict
;
1022 /* Now see if we've been here before */
1023 for (k
= 0; k
< sp
; k
++)
1024 if (stack
[k
].chain_nr
== verdict
+ NF_BR_NUMHOOKS
) {
1025 ebt_print_error("Loop from chain '%s' to chain '%s'",
1026 replace
->chains
[chain_nr
]->name
,
1027 replace
->chains
[stack
[k
].chain_nr
]->name
);
1030 entries2
= replace
->chains
[verdict
+ NF_BR_NUMHOOKS
];
1031 /* check if we've dealt with this chain already */
1032 if (entries2
->hook_mask
& (1<<i
))
1034 entries2
->hook_mask
|= entries
->hook_mask
;
1035 /* Jump to the chain, make sure we know how to get back */
1036 stack
[sp
].chain_nr
= chain_nr
;
1038 stack
[sp
].entries
= entries
;
1042 e
= entries2
->entries
->next
;
1043 chain_nr
= verdict
+ NF_BR_NUMHOOKS
;
1049 /* We are at the end of a standard chain */
1052 /* Go back to the chain one level higher */
1055 chain_nr
= stack
[sp
].chain_nr
;
1057 entries
= stack
[sp
].entries
;
1065 /* The user will use the match, so put it in new_entry. The ebt_u_match
1066 * pointer is put in the ebt_entry_match pointer. ebt_add_rule will
1067 * fill in the final value for new->m. Unless the rule is added to a chain,
1068 * the pointer will keep pointing to the ebt_u_match (until the new_entry
1069 * is freed). I know, I should use a union for these 2 pointer types... */
1070 void ebt_add_match(struct ebt_u_entry
*new_entry
, struct ebt_u_match
*m
)
1072 struct ebt_u_match_list
**m_list
, *new;
1074 for (m_list
= &new_entry
->m_list
; *m_list
; m_list
= &(*m_list
)->next
);
1075 new = (struct ebt_u_match_list
*)
1076 malloc(sizeof(struct ebt_u_match_list
));
1081 new->m
= (struct ebt_entry_match
*)m
;
1084 void ebt_add_watcher(struct ebt_u_entry
*new_entry
, struct ebt_u_watcher
*w
)
1086 struct ebt_u_watcher_list
**w_list
;
1087 struct ebt_u_watcher_list
*new;
1089 for (w_list
= &new_entry
->w_list
; *w_list
; w_list
= &(*w_list
)->next
);
1090 new = (struct ebt_u_watcher_list
*)
1091 malloc(sizeof(struct ebt_u_watcher_list
));
1096 new->w
= (struct ebt_entry_watcher
*)w
;
1109 /* type = 0 => update chain jumps
1110 * type = 1 => check for reference, print error when referenced
1111 * type = 2 => check for reference, don't print error when referenced
1113 * Returns 1 when type == 1 and the chain is referenced
1114 * returns 0 otherwise */
1115 static int iterate_entries(struct ebt_u_replace
*replace
, int type
)
1117 int i
, j
, chain_nr
= replace
->selected_chain
- NF_BR_NUMHOOKS
;
1118 struct ebt_u_entries
*entries
;
1119 struct ebt_u_entry
*e
;
1122 ebt_print_bug("iterate_entries: udc = %d < 0", chain_nr
);
1123 for (i
= 0; i
< replace
->num_chains
; i
++) {
1124 if (!(entries
= replace
->chains
[i
]))
1126 e
= entries
->entries
->next
;
1127 for (j
= 0; j
< entries
->nentries
; j
++) {
1130 if (strcmp(e
->t
->u
.name
, EBT_STANDARD_TARGET
)) {
1134 chain_jmp
= ((struct ebt_standard_target
*)e
->t
)->
1139 if (chain_jmp
== chain_nr
) {
1142 ebt_print_error("Can't delete the chain '%s', it's referenced in chain '%s', rule %d",
1143 replace
->chains
[chain_nr
+ NF_BR_NUMHOOKS
]->name
, entries
->name
, j
);
1148 /* Adjust the chain jumps when necessary */
1149 if (chain_jmp
> chain_nr
)
1150 ((struct ebt_standard_target
*)e
->t
)->verdict
--;
1159 static void decrease_chain_jumps(struct ebt_u_replace
*replace
)
1161 iterate_entries(replace
, 0);
1164 /* Used in initialization code of modules */
1165 void ebt_register_match(struct ebt_u_match
*m
)
1167 int size
= EBT_ALIGN(m
->size
) + sizeof(struct ebt_entry_match
);
1168 struct ebt_u_match
**i
;
1170 m
->m
= (struct ebt_entry_match
*)malloc(size
);
1173 strcpy(m
->m
->u
.name
, m
->name
);
1174 m
->m
->match_size
= EBT_ALIGN(m
->size
);
1177 for (i
= &ebt_matches
; *i
; i
= &((*i
)->next
));
1182 void ebt_register_watcher(struct ebt_u_watcher
*w
)
1184 int size
= EBT_ALIGN(w
->size
) + sizeof(struct ebt_entry_watcher
);
1185 struct ebt_u_watcher
**i
;
1187 w
->w
= (struct ebt_entry_watcher
*)malloc(size
);
1190 strcpy(w
->w
->u
.name
, w
->name
);
1191 w
->w
->watcher_size
= EBT_ALIGN(w
->size
);
1194 for (i
= &ebt_watchers
; *i
; i
= &((*i
)->next
));
1199 void ebt_register_target(struct ebt_u_target
*t
)
1201 int size
= EBT_ALIGN(t
->size
) + sizeof(struct ebt_entry_target
);
1202 struct ebt_u_target
**i
;
1204 t
->t
= (struct ebt_entry_target
*)malloc(size
);
1207 strcpy(t
->t
->u
.name
, t
->name
);
1208 t
->t
->target_size
= EBT_ALIGN(t
->size
);
1211 for (i
= &ebt_targets
; *i
; i
= &((*i
)->next
));
1216 void ebt_register_table(struct ebt_u_table
*t
)
1218 t
->next
= ebt_tables
;
1222 void ebt_iterate_matches(void (*f
)(struct ebt_u_match
*))
1224 struct ebt_u_match
*i
;
1226 for (i
= ebt_matches
; i
; i
= i
->next
)
1230 void ebt_iterate_watchers(void (*f
)(struct ebt_u_watcher
*))
1232 struct ebt_u_watcher
*i
;
1234 for (i
= ebt_watchers
; i
; i
= i
->next
)
1238 void ebt_iterate_targets(void (*f
)(struct ebt_u_target
*))
1240 struct ebt_u_target
*i
;
1242 for (i
= ebt_targets
; i
; i
= i
->next
)
1246 /* Don't use this function, use ebt_print_bug() */
1247 void __ebt_print_bug(char *file
, int line
, char *format
, ...)
1251 va_start(l
, format
);
1252 fprintf(stderr
, PROGNAME
" v"PROGVERSION
":%s:%d:--BUG--: \n", file
, line
);
1253 vfprintf(stderr
, format
, l
);
1254 fprintf(stderr
, "\n");
1259 /* The error messages are put in here when ebt_silent == 1
1260 * ebt_errormsg[0] == '\0' implies there was no error */
1261 char ebt_errormsg
[ERRORMSG_MAXLEN
];
1262 /* When error messages should not be printed on the screen, after which
1263 * the program exit()s, set ebt_silent to 1. */
1265 /* Don't use this function, use ebt_print_error() */
1266 void __ebt_print_error(char *format
, ...)
1270 va_start(l
, format
);
1271 if (ebt_silent
&& ebt_errormsg
[0] == '\0') {
1272 vsnprintf(ebt_errormsg
, ERRORMSG_MAXLEN
, format
, l
);
1275 vfprintf(stderr
, format
, l
);
1276 fprintf(stderr
, ".\n");