1/* 2 * libebtc.c, January 2004 3 * 4 * Contains the functions with which to make a table in userspace. 5 * 6 * Author: Bart De Schuymer 7 * 8 * This code is stongly inspired on the iptables code which is 9 * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling 10 * 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. 15 * 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. 20 * 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. 24 */ 25 26#include <string.h> 27#include <stdio.h> 28#include <stdlib.h> 29#include <stdarg.h> 30#include "include/ebtables_u.h" 31#include "include/ethernetdb.h" 32#include <unistd.h> 33#include <fcntl.h> 34#include <sys/wait.h> 35 36static void decrease_chain_jumps(struct ebt_u_replace *replace); 37static int iterate_entries(struct ebt_u_replace *replace, int type); 38 39/* The standard names */ 40const char *ebt_hooknames[NF_BR_NUMHOOKS] = 41{ 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" 48}; 49 50/* The four target names */ 51const char* ebt_standard_targets[NUM_STANDARD_TARGETS] = 52{ 53 "ACCEPT", 54 "DROP", 55 "CONTINUE", 56 "RETURN", 57}; 58 59/* The lists of supported tables, matches, watchers and targets */ 60struct ebt_u_table *ebt_tables; 61struct ebt_u_match *ebt_matches; 62struct ebt_u_watcher *ebt_watchers; 63struct ebt_u_target *ebt_targets; 64 65/* Find the right structure belonging to a name */ 66struct ebt_u_target *ebt_find_target(const char *name) 67{ 68 struct ebt_u_target *t = ebt_targets; 69 70 while (t && strcmp(t->name, name)) 71 t = t->next; 72 return t; 73} 74 75struct ebt_u_match *ebt_find_match(const char *name) 76{ 77 struct ebt_u_match *m = ebt_matches; 78 79 while (m && strcmp(m->name, name)) 80 m = m->next; 81 return m; 82} 83 84struct ebt_u_watcher *ebt_find_watcher(const char *name) 85{ 86 struct ebt_u_watcher *w = ebt_watchers; 87 88 while (w && strcmp(w->name, name)) 89 w = w->next; 90 return w; 91} 92 93struct ebt_u_table *ebt_find_table(const char *name) 94{ 95 struct ebt_u_table *t = ebt_tables; 96 97 while (t && strcmp(t->name, name)) 98 t = t->next; 99 return t; 100} 101 102/* Prints all registered extensions */ 103void ebt_list_extensions() 104{ 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; 109 110 PRINT_VERSION; 111 printf("Loaded userspace extensions:\n\nLoaded tables:\n"); 112 while (tbl) { 113 printf("%s\n", tbl->name); 114 tbl = tbl->next; 115 } 116 printf("\nLoaded targets:\n"); 117 while (t) { 118 printf("%s\n", t->name); 119 t = t->next; 120 } 121 printf("\nLoaded matches:\n"); 122 while (m) { 123 printf("%s\n", m->name); 124 m = m->next; 125 } 126 printf("\nLoaded watchers:\n"); 127 while (w) { 128 printf("%s\n", w->name); 129 w = w->next; 130 } 131} 132 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 */ 137int ebt_get_kernel_table(struct ebt_u_replace *replace, int init) 138{ 139 if (!ebt_find_table(replace->name)) { 140 ebt_print_error("Bad table name '%s'", replace->name); 141 return -1; 142 } 143 /* Get the kernel's information */ 144 if (ebt_get_table(replace, init)) { 145 if (ebt_errormsg[0] != '\0') 146 return -1; 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); 150 return -1; 151 } 152 } 153 return 0; 154} 155 156/* Put sane values into a new entry */ 157void ebt_initialize_entry(struct ebt_u_entry *e) 158{ 159 e->bitmask = EBT_NOPROTO; 160 e->invflags = 0; 161 e->ethproto = 0; 162 strcpy(e->in, ""); 163 strcpy(e->out, ""); 164 strcpy(e->logical_in, ""); 165 strcpy(e->logical_out, ""); 166 e->m_list = NULL; 167 e->w_list = NULL; 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; 171 172 if (!e->t) 173 ebt_print_bug("Couldn't load standard target"); 174 ((struct ebt_standard_target *)((struct ebt_u_target *)e->t)->t)->verdict = EBT_CONTINUE; 175} 176 177/* Free up the memory of the table held in userspace, *replace can be reused */ 178void ebt_cleanup_replace(struct ebt_u_replace *replace) 179{ 180 int i; 181 struct ebt_u_entries *entries; 182 struct ebt_cntchanges *cc1, *cc2; 183 struct ebt_u_entry *u_e1, *u_e2; 184 185 replace->name[0] = '\0'; 186 replace->valid_hooks = 0; 187 replace->nentries = 0; 188 replace->num_counters = 0; 189 replace->flags = 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; 196 197 for (i = 0; i < replace->num_chains; i++) { 198 if (!(entries = replace->chains[i])) 199 continue; 200 u_e1 = entries->entries->next; 201 while (u_e1 != entries->entries) { 202 ebt_free_u_entry(u_e1); 203 u_e2 = u_e1->next; 204 free(u_e1); 205 u_e1 = u_e2; 206 } 207 free(entries->entries); 208 free(entries); 209 replace->chains[i] = NULL; 210 } 211 cc1 = replace->cc->next; 212 while (cc1 != replace->cc) { 213 cc2 = cc1->next; 214 free(cc1); 215 cc1 = cc2; 216 } 217 replace->cc->next = replace->cc->prev = replace->cc; 218} 219 220/* Should be called, e.g., between 2 rule adds */ 221void ebt_reinit_extensions() 222{ 223 struct ebt_u_match *m; 224 struct ebt_u_watcher *w; 225 struct ebt_u_target *t; 226 int size; 227 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) { 231 if (m->used) { 232 size = EBT_ALIGN(m->size) + sizeof(struct ebt_entry_match); 233 m->m = (struct ebt_entry_match *)malloc(size); 234 if (!m->m) 235 ebt_print_memory(); 236 strcpy(m->m->u.name, m->name); 237 m->m->match_size = EBT_ALIGN(m->size); 238 m->used = 0; 239 } 240 m->flags = 0; /* An error can occur before used is set, while flags is changed. */ 241 m->init(m->m); 242 } 243 for (w = ebt_watchers; w; w = w->next) { 244 if (w->used) { 245 size = EBT_ALIGN(w->size) + sizeof(struct ebt_entry_watcher); 246 w->w = (struct ebt_entry_watcher *)malloc(size); 247 if (!w->w) 248 ebt_print_memory(); 249 strcpy(w->w->u.name, w->name); 250 w->w->watcher_size = EBT_ALIGN(w->size); 251 w->used = 0; 252 } 253 w->flags = 0; 254 w->init(w->w); 255 } 256 for (t = ebt_targets; t; t = t->next) { 257 if (t->used) { 258 size = EBT_ALIGN(t->size) + sizeof(struct ebt_entry_target); 259 t->t = (struct ebt_entry_target *)malloc(size); 260 if (!t->t) 261 ebt_print_memory(); 262 strcpy(t->t->u.name, t->name); 263 t->t->target_size = EBT_ALIGN(t->size); 264 t->used = 0; 265 } 266 t->flags = 0; 267 t->init(t->t); 268 } 269} 270 271/* This doesn't free e, because the calling function might need e->next */ 272void ebt_free_u_entry(struct ebt_u_entry *e) 273{ 274 struct ebt_u_match_list *m_l, *m_l2; 275 struct ebt_u_watcher_list *w_l, *w_l2; 276 277 m_l = e->m_list; 278 while (m_l) { 279 m_l2 = m_l->next; 280 free(m_l->m); 281 free(m_l); 282 m_l = m_l2; 283 } 284 w_l = e->w_list; 285 while (w_l) { 286 w_l2 = w_l->next; 287 free(w_l->w); 288 free(w_l); 289 w_l = w_l2; 290 } 291 free(e->t); 292} 293 294static char *get_modprobe(void) 295{ 296 int procfile; 297 char *ret; 298 299 procfile = open(PROC_SYS_MODPROBE, O_RDONLY); 300 if (procfile < 0) 301 return NULL; 302 303 ret = malloc(1024); 304 if (ret) { 305 if (read(procfile, ret, 1024) == -1) 306 goto fail; 307 /* The kernel adds a '\n' */ 308 ret[1023] = '\n'; 309 *strchr(ret, '\n') = '\0'; 310 close(procfile); 311 return ret; 312 } 313 fail: 314 free(ret); 315 close(procfile); 316 return NULL; 317} 318 319char *ebt_modprobe; 320/* Try to load the kernel module, analogous to ip_tables.c */ 321int ebtables_insmod(const char *modname) 322{ 323 char *buf = NULL; 324 char *argv[3]; 325 326 /* If they don't explicitly set it, read out of /proc */ 327 if (!ebt_modprobe) { 328 buf = get_modprobe(); 329 if (!buf) 330 return -1; 331 ebt_modprobe = buf; /* Keep the value for possible later use */ 332 } 333 334 switch (fork()) { 335 case 0: 336 argv[0] = (char *)ebt_modprobe; 337 argv[1] = (char *)modname; 338 argv[2] = NULL; 339 execv(argv[0], argv); 340 341 /* Not usually reached */ 342 exit(0); 343 case -1: 344 return -1; 345 346 default: /* Parent */ 347 wait(NULL); 348 } 349 350 return 0; 351} 352 353/* Parse the chain name and return a pointer to the chain base. 354 * Returns NULL on failure. */ 355struct ebt_u_entries *ebt_name_to_chain(const struct ebt_u_replace *replace, const char* arg) 356{ 357 int i; 358 struct ebt_u_entries *chain; 359 360 for (i = 0; i < replace->num_chains; i++) { 361 if (!(chain = replace->chains[i])) 362 continue; 363 if (!strcmp(arg, chain->name)) 364 return chain; 365 } 366 return NULL; 367} 368 369/* Parse the chain name and return the corresponding chain nr 370 * returns -1 on failure */ 371int ebt_get_chainnr(const struct ebt_u_replace *replace, const char* arg) 372{ 373 int i; 374 375 for (i = 0; i < replace->num_chains; i++) { 376 if (!replace->chains[i]) 377 continue; 378 if (!strcmp(arg, replace->chains[i]->name)) 379 return i; 380 } 381 return -1; 382} 383 384 /* 385************ 386************ 387**COMMANDS** 388************ 389************ 390 */ 391 392/* Change the policy of selected_chain. 393 * Handing a bad policy to this function is a bug. */ 394void ebt_change_policy(struct ebt_u_replace *replace, int policy) 395{ 396 struct ebt_u_entries *entries = ebt_to_chain(replace); 397 398 if (policy < -NUM_STANDARD_TARGETS || policy == EBT_CONTINUE) 399 ebt_print_bug("Wrong policy: %d", policy); 400 entries->policy = policy; 401} 402 403void ebt_delete_cc(struct ebt_cntchanges *cc) 404{ 405 if (cc->type == CNT_ADD) { 406 cc->prev->next = cc->next; 407 cc->next->prev = cc->prev; 408 free(cc); 409 } 410 cc->type = CNT_DEL; 411} 412 413void ebt_empty_chain(struct ebt_u_entries *entries) 414{ 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); 419 tmp = u_e->next; 420 free(u_e); 421 u_e = tmp; 422 } 423 entries->entries->next = entries->entries->prev = entries->entries; 424 entries->nentries = 0; 425} 426 427/* Flush one chain or the complete table 428 * If selected_chain == -1 then flush the complete table */ 429void ebt_flush_chains(struct ebt_u_replace *replace) 430{ 431 int i, numdel; 432 struct ebt_u_entries *entries = ebt_to_chain(replace); 433 434 /* Flush whole table */ 435 if (!entries) { 436 if (replace->nentries == 0) 437 return; 438 replace->nentries = 0; 439 440 /* Free everything and zero (n)entries */ 441 for (i = 0; i < replace->num_chains; i++) { 442 if (!(entries = replace->chains[i])) 443 continue; 444 entries->counter_offset = 0; 445 ebt_empty_chain(entries); 446 } 447 return; 448 } 449 450 if (entries->nentries == 0) 451 return; 452 replace->nentries -= entries->nentries; 453 numdel = entries->nentries; 454 455 /* Update counter_offset */ 456 for (i = replace->selected_chain+1; i < replace->num_chains; i++) { 457 if (!(entries = replace->chains[i])) 458 continue; 459 entries->counter_offset -= numdel; 460 } 461 462 entries = ebt_to_chain(replace); 463 ebt_empty_chain(entries); 464} 465 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 468 * 469 * This function expects the ebt_{match,watcher,target} members of new_entry 470 * to contain pointers to ebt_u_{match,watcher,target} */ 471int ebt_check_rule_exists(struct ebt_u_replace *replace, 472 struct ebt_u_entry *new_entry) 473{ 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); 481 int i, j, k; 482 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) 488 continue; 489 if (strcmp(u_e->in, new_entry->in)) 490 continue; 491 if (strcmp(u_e->out, new_entry->out)) 492 continue; 493 if (strcmp(u_e->logical_in, new_entry->logical_in)) 494 continue; 495 if (strcmp(u_e->logical_out, new_entry->logical_out)) 496 continue; 497 if (new_entry->bitmask & EBT_SOURCEMAC && 498 memcmp(u_e->sourcemac, new_entry->sourcemac, ETH_ALEN)) 499 continue; 500 if (new_entry->bitmask & EBT_DESTMAC && 501 memcmp(u_e->destmac, new_entry->destmac, ETH_ALEN)) 502 continue; 503 if (new_entry->bitmask != u_e->bitmask || 504 new_entry->invflags != u_e->invflags) 505 continue; 506 if (replace->flags & OPT_COUNT && (new_entry->cnt.pcnt != 507 u_e->cnt.pcnt || new_entry->cnt.bcnt != u_e->cnt.bcnt)) 508 continue; 509 /* Compare all matches */ 510 m_l = new_entry->m_list; 511 j = 0; 512 while (m_l) { 513 m = (struct ebt_u_match *)(m_l->m); 514 m_l2 = u_e->m_list; 515 while (m_l2 && strcmp(m_l2->m->u.name, m->m->u.name)) 516 m_l2 = m_l2->next; 517 if (!m_l2 || !m->compare(m->m, m_l2->m)) 518 goto letscontinue; 519 j++; 520 m_l = m_l->next; 521 } 522 /* Now be sure they have the same nr of matches */ 523 k = 0; 524 m_l = u_e->m_list; 525 while (m_l) { 526 k++; 527 m_l = m_l->next; 528 } 529 if (j != k) 530 continue; 531 532 /* Compare all watchers */ 533 w_l = new_entry->w_list; 534 j = 0; 535 while (w_l) { 536 w = (struct ebt_u_watcher *)(w_l->w); 537 w_l2 = u_e->w_list; 538 while (w_l2 && strcmp(w_l2->w->u.name, w->w->u.name)) 539 w_l2 = w_l2->next; 540 if (!w_l2 || !w->compare(w->w, w_l2->w)) 541 goto letscontinue; 542 j++; 543 w_l = w_l->next; 544 } 545 k = 0; 546 w_l = u_e->w_list; 547 while (w_l) { 548 k++; 549 w_l = w_l->next; 550 } 551 if (j != k) 552 continue; 553 if (strcmp(t->t->u.name, u_e->t->u.name)) 554 continue; 555 if (!t->compare(t->t, u_e->t)) 556 continue; 557 return i; 558letscontinue:; 559 } 560 return -1; 561} 562 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 570 * 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() */ 576void ebt_add_rule(struct ebt_u_replace *replace, struct ebt_u_entry *new_entry, int rule_nr) 577{ 578 int i; 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; 584 585 if (rule_nr <= 0) 586 rule_nr += entries->nentries; 587 else 588 rule_nr--; 589 if (rule_nr > entries->nentries || rule_nr < 0) { 590 ebt_print_error("The specified rule number is incorrect"); 591 return; 592 } 593 /* Go to the right position in the chain */ 594 if (rule_nr == entries->nentries) 595 u_e = entries->entries; 596 else { 597 u_e = entries->entries->next; 598 for (i = 0; i < rule_nr; i++) 599 u_e = u_e->next; 600 } 601 /* We're adding one rule */ 602 replace->nentries++; 603 entries->nentries++; 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)); 610 if (!new_cc) 611 ebt_print_memory(); 612 new_cc->type = CNT_ADD; 613 new_cc->change = 0; 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) 617 continue; 618 else 619 break; 620 if (i == replace->num_chains) 621 cc = replace->cc; 622 else 623 cc = replace->chains[i]->entries->next->cc; 624 } else 625 cc = new_entry->next->cc; 626 new_cc->next = cc; 627 new_cc->prev = cc->prev; 628 cc->prev->next = new_cc; 629 cc->prev = new_cc; 630 new_entry->cc = new_cc; 631 632 /* Put the ebt_{match, watcher, target} pointers in place */ 633 m_l = new_entry->m_list; 634 while (m_l) { 635 m_l->m = ((struct ebt_u_match *)m_l->m)->m; 636 m_l = m_l->next; 637 } 638 w_l = new_entry->w_list; 639 while (w_l) { 640 w_l->w = ((struct ebt_u_watcher *)w_l->w)->w; 641 w_l = w_l->next; 642 } 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])) 648 continue; 649 entries->counter_offset++; 650 } 651} 652 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. */ 656static int check_and_change_rule_number(struct ebt_u_replace *replace, 657 struct ebt_u_entry *new_entry, int *begin, int *end) 658{ 659 struct ebt_u_entries *entries = ebt_to_chain(replace); 660 661 if (*begin < 0) 662 *begin += entries->nentries + 1; 663 if (*end < 0) 664 *end += entries->nentries + 1; 665 666 if (*begin < 0 || *begin > *end || *end > entries->nentries) { 667 ebt_print_error("Sorry, wrong rule numbers"); 668 return -1; 669 } 670 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"); 674 if (*begin != 0) { 675 (*begin)--; 676 (*end)--; 677 } else { 678 *begin = ebt_check_rule_exists(replace, new_entry); 679 *end = *begin; 680 if (*begin == -1) { 681 ebt_print_error("Sorry, rule does not exist"); 682 return -1; 683 } 684 } 685 return 0; 686} 687 688/* Delete a rule or rules 689 * begin == end == 0: delete the rule corresponding to new_entry 690 * 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}. */ 694void ebt_delete_rule(struct ebt_u_replace *replace, 695 struct ebt_u_entry *new_entry, int begin, int end) 696{ 697 int i, nr_deletes; 698 struct ebt_u_entry *u_e, *u_e2, *u_e3; 699 struct ebt_u_entries *entries = ebt_to_chain(replace); 700 701 if (check_and_change_rule_number(replace, new_entry, &begin, &end)) 702 return; 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++) 710 u_e = u_e->next; 711 u_e3 = u_e->prev; 712 /* Remove the rules */ 713 for (i = 0; i < nr_deletes; i++) { 714 u_e2 = u_e; 715 ebt_delete_cc(u_e2->cc); 716 u_e = u_e->next; 717 /* Free everything */ 718 ebt_free_u_entry(u_e2); 719 free(u_e2); 720 } 721 u_e3->next = u_e; 722 u_e->prev = u_e3; 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])) 726 continue; 727 entries->counter_offset -= nr_deletes; 728 } 729} 730 731/* Change the counters of a rule or rules 732 * begin == end == 0: change counters of the rule corresponding to new_entry 733 * 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 */ 741void 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) 744{ 745 int i; 746 struct ebt_u_entry *u_e; 747 struct ebt_u_entries *entries = ebt_to_chain(replace); 748 749 if (check_and_change_rule_number(replace, new_entry, &begin, &end)) 750 return; 751 u_e = entries->entries->next; 752 for (i = 0; i < begin; i++) 753 u_e = u_e->next; 754 for (i = end-begin+1; i > 0; i--) { 755 if (mask % 3 == 0) { 756 u_e->cnt.pcnt = (*cnt).pcnt; 757 u_e->cnt_surplus.pcnt = 0; 758 } else { 759#ifdef EBT_DEBUG 760 if (u_e->cc->type != CNT_NORM) 761 ebt_print_bug("cc->type != CNT_NORM"); 762#endif 763 u_e->cnt_surplus.pcnt = (*cnt).pcnt; 764 } 765 766 if (mask / 3 == 0) { 767 u_e->cnt.bcnt = (*cnt).bcnt; 768 u_e->cnt_surplus.bcnt = 0; 769 } else { 770#ifdef EBT_DEBUG 771 if (u_e->cc->type != CNT_NORM) 772 ebt_print_bug("cc->type != CNT_NORM"); 773#endif 774 u_e->cnt_surplus.bcnt = (*cnt).bcnt; 775 } 776 if (u_e->cc->type != CNT_ADD) 777 u_e->cc->type = CNT_CHANGE; 778 u_e->cc->change = mask; 779 u_e = u_e->next; 780 } 781} 782 783/* If selected_chain == -1 then zero all counters, 784 * otherwise, zero the counters of selected_chain */ 785void ebt_zero_counters(struct ebt_u_replace *replace) 786{ 787 struct ebt_u_entries *entries = ebt_to_chain(replace); 788 struct ebt_u_entry *next; 789 int i; 790 791 if (!entries) { 792 for (i = 0; i < replace->num_chains; i++) { 793 if (!(entries = replace->chains[i])) 794 continue; 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; 801 next = next->next; 802 } 803 } 804 } else { 805 if (entries->nentries == 0) 806 return; 807 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; 813 next = next->next; 814 } 815 } 816} 817 818/* Add a new chain and specify its policy */ 819void ebt_new_chain(struct ebt_u_replace *replace, const char *name, int policy) 820{ 821 struct ebt_u_entries *new; 822 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)); 826 if (!new) 827 ebt_print_memory(); 828 replace->chains[replace->num_chains++] = new; 829 new->nentries = 0; 830 new->policy = policy; 831 new->counter_offset = replace->nentries; 832 new->hook_mask = 0; 833 strcpy(new->name, name); 834 new->entries = (struct ebt_u_entry *)malloc(sizeof(struct ebt_u_entry)); 835 if (!new->entries) 836 ebt_print_memory(); 837 new->entries->next = new->entries->prev = new->entries; 838 new->kernel_start = NULL; 839} 840 841/* returns -1 if the chain is referenced, 0 on success */ 842static int ebt_delete_a_chain(struct ebt_u_replace *replace, int chain, int print_err) 843{ 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)) 850 return -1; 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--; 858 return 0; 859} 860 861/* Selected_chain == -1: delete all non-referenced udc 862 * selected_chain < NF_BR_NUMHOOKS is illegal */ 863void ebt_delete_chain(struct ebt_u_replace *replace) 864{ 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; 869 870 while (i < replace->num_chains) 871 if (ebt_delete_a_chain(replace, i, 0)) 872 i++; 873 } else 874 ebt_delete_a_chain(replace, replace->selected_chain, 1); 875} 876 877/* Rename an existing chain. */ 878void ebt_rename_chain(struct ebt_u_replace *replace, const char *name) 879{ 880 struct ebt_u_entries *entries = ebt_to_chain(replace); 881 882 if (!entries) 883 ebt_print_bug("ebt_rename_chain: entries == NULL"); 884 strcpy(entries->name, name); 885} 886 887 888 /* 889************************* 890************************* 891**SPECIALIZED*FUNCTIONS** 892************************* 893************************* 894 */ 895 896 897void ebt_double_chains(struct ebt_u_replace *replace) 898{ 899 struct ebt_u_entries **new; 900 901 replace->max_chains *= 2; 902 new = (struct ebt_u_entries **)malloc(replace->max_chains*sizeof(void *)); 903 if (!new) 904 ebt_print_memory(); 905 memcpy(new, replace->chains, replace->max_chains/2*sizeof(void *)); 906 free(replace->chains); 907 replace->chains = new; 908} 909 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. */ 914void ebt_do_final_checks(struct ebt_u_replace *replace, struct ebt_u_entry *e, 915 struct ebt_u_entries *entries) 916{ 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; 922 923 m_l = e->m_list; 924 w_l = e->w_list; 925 while (m_l) { 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') 930 return; 931 m_l = m_l->next; 932 } 933 while (w_l) { 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') 938 return; 939 w_l = w_l->next; 940 } 941 t = ebt_find_target(e->t->u.name); 942 t->final_check(e, e->t, replace->name, 943 entries->hook_mask, 1); 944} 945 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 */ 948int ebt_check_for_references(struct ebt_u_replace *replace, int print_err) 949{ 950 if (print_err) 951 return iterate_entries(replace, 1); 952 else 953 return iterate_entries(replace, 2); 954} 955 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 */ 959int ebt_check_for_references2(struct ebt_u_replace *replace, int chain_nr, 960 int print_err) 961{ 962 int tmp = replace->selected_chain, ret; 963 964 replace->selected_chain = chain_nr; 965 if (print_err) 966 ret = iterate_entries(replace, 1); 967 else 968 ret = iterate_entries(replace, 2); 969 replace->selected_chain = tmp; 970 return ret; 971} 972 973struct ebt_u_stack 974{ 975 int chain_nr; 976 int n; 977 struct ebt_u_entry *e; 978 struct ebt_u_entries *entries; 979}; 980 981/* Checks for loops 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. */ 985void ebt_check_for_loops(struct ebt_u_replace *replace) 986{ 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; 991 992 /* Initialize hook_mask to 0 */ 993 for (i = 0; i < replace->num_chains; i++) { 994 if (!(entries = replace->chains[i])) 995 continue; 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); 1000 else 1001 entries->hook_mask = 0; 1002 } 1003 if (replace->num_chains == NF_BR_NUMHOOKS) 1004 return; 1005 stack = (struct ebt_u_stack *)malloc((replace->num_chains - NF_BR_NUMHOOKS) * sizeof(struct ebt_u_stack)); 1006 if (!stack) 1007 ebt_print_memory(); 1008 1009 /* Check for loops, starting from every base chain */ 1010 for (i = 0; i < NF_BR_NUMHOOKS; i++) { 1011 if (!(entries = replace->chains[i])) 1012 continue; 1013 chain_nr = i; 1014 1015 e = entries->entries->next; 1016 for (j = 0; j < entries->nentries; j++) { 1017 if (strcmp(e->t->u.name, EBT_STANDARD_TARGET)) 1018 goto letscontinue; 1019 verdict = ((struct ebt_standard_target *)(e->t))->verdict; 1020 if (verdict < 0) 1021 goto letscontinue; 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); 1028 goto free_stack; 1029 } 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)) 1033 goto letscontinue; 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; 1037 stack[sp].n = j; 1038 stack[sp].entries = entries; 1039 stack[sp].e = e; 1040 sp++; 1041 j = -1; 1042 e = entries2->entries->next; 1043 chain_nr = verdict + NF_BR_NUMHOOKS; 1044 entries = entries2; 1045 continue; 1046letscontinue: 1047 e = e->next; 1048 } 1049 /* We are at the end of a standard chain */ 1050 if (sp == 0) 1051 continue; 1052 /* Go back to the chain one level higher */ 1053 sp--; 1054 j = stack[sp].n; 1055 chain_nr = stack[sp].chain_nr; 1056 e = stack[sp].e; 1057 entries = stack[sp].entries; 1058 goto letscontinue; 1059 } 1060free_stack: 1061 free(stack); 1062 return; 1063} 1064 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... */ 1070void ebt_add_match(struct ebt_u_entry *new_entry, struct ebt_u_match *m) 1071{ 1072 struct ebt_u_match_list **m_list, *new; 1073 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)); 1077 if (!new) 1078 ebt_print_memory(); 1079 *m_list = new; 1080 new->next = NULL; 1081 new->m = (struct ebt_entry_match *)m; 1082} 1083 1084void ebt_add_watcher(struct ebt_u_entry *new_entry, struct ebt_u_watcher *w) 1085{ 1086 struct ebt_u_watcher_list **w_list; 1087 struct ebt_u_watcher_list *new; 1088 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)); 1092 if (!new) 1093 ebt_print_memory(); 1094 *w_list = new; 1095 new->next = NULL; 1096 new->w = (struct ebt_entry_watcher *)w; 1097} 1098 1099 1100 /* 1101******************* 1102******************* 1103**OTHER*FUNCTIONS** 1104******************* 1105******************* 1106 */ 1107 1108 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 1112 * 1113 * Returns 1 when type == 1 and the chain is referenced 1114 * returns 0 otherwise */ 1115static int iterate_entries(struct ebt_u_replace *replace, int type) 1116{ 1117 int i, j, chain_nr = replace->selected_chain - NF_BR_NUMHOOKS; 1118 struct ebt_u_entries *entries; 1119 struct ebt_u_entry *e; 1120 1121 if (chain_nr < 0) 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])) 1125 continue; 1126 e = entries->entries->next; 1127 for (j = 0; j < entries->nentries; j++) { 1128 int chain_jmp; 1129 1130 if (strcmp(e->t->u.name, EBT_STANDARD_TARGET)) { 1131 e = e->next; 1132 continue; 1133 } 1134 chain_jmp = ((struct ebt_standard_target *)e->t)-> 1135 verdict; 1136 switch (type) { 1137 case 1: 1138 case 2: 1139 if (chain_jmp == chain_nr) { 1140 if (type == 2) 1141 return 1; 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); 1144 return 1; 1145 } 1146 break; 1147 case 0: 1148 /* Adjust the chain jumps when necessary */ 1149 if (chain_jmp > chain_nr) 1150 ((struct ebt_standard_target *)e->t)->verdict--; 1151 break; 1152 } /* End switch */ 1153 e = e->next; 1154 } 1155 } 1156 return 0; 1157} 1158 1159static void decrease_chain_jumps(struct ebt_u_replace *replace) 1160{ 1161 iterate_entries(replace, 0); 1162} 1163 1164/* Used in initialization code of modules */ 1165void ebt_register_match(struct ebt_u_match *m) 1166{ 1167 int size = EBT_ALIGN(m->size) + sizeof(struct ebt_entry_match); 1168 struct ebt_u_match **i; 1169 1170 m->m = (struct ebt_entry_match *)malloc(size); 1171 if (!m->m) 1172 ebt_print_memory(); 1173 strcpy(m->m->u.name, m->name); 1174 m->m->match_size = EBT_ALIGN(m->size); 1175 m->init(m->m); 1176 1177 for (i = &ebt_matches; *i; i = &((*i)->next)); 1178 m->next = NULL; 1179 *i = m; 1180} 1181 1182void ebt_register_watcher(struct ebt_u_watcher *w) 1183{ 1184 int size = EBT_ALIGN(w->size) + sizeof(struct ebt_entry_watcher); 1185 struct ebt_u_watcher **i; 1186 1187 w->w = (struct ebt_entry_watcher *)malloc(size); 1188 if (!w->w) 1189 ebt_print_memory(); 1190 strcpy(w->w->u.name, w->name); 1191 w->w->watcher_size = EBT_ALIGN(w->size); 1192 w->init(w->w); 1193 1194 for (i = &ebt_watchers; *i; i = &((*i)->next)); 1195 w->next = NULL; 1196 *i = w; 1197} 1198 1199void ebt_register_target(struct ebt_u_target *t) 1200{ 1201 int size = EBT_ALIGN(t->size) + sizeof(struct ebt_entry_target); 1202 struct ebt_u_target **i; 1203 1204 t->t = (struct ebt_entry_target *)malloc(size); 1205 if (!t->t) 1206 ebt_print_memory(); 1207 strcpy(t->t->u.name, t->name); 1208 t->t->target_size = EBT_ALIGN(t->size); 1209 t->init(t->t); 1210 1211 for (i = &ebt_targets; *i; i = &((*i)->next)); 1212 t->next = NULL; 1213 *i = t; 1214} 1215 1216void ebt_register_table(struct ebt_u_table *t) 1217{ 1218 t->next = ebt_tables; 1219 ebt_tables = t; 1220} 1221 1222void ebt_iterate_matches(void (*f)(struct ebt_u_match *)) 1223{ 1224 struct ebt_u_match *i; 1225 1226 for (i = ebt_matches; i; i = i->next) 1227 f(i); 1228} 1229 1230void ebt_iterate_watchers(void (*f)(struct ebt_u_watcher *)) 1231{ 1232 struct ebt_u_watcher *i; 1233 1234 for (i = ebt_watchers; i; i = i->next) 1235 f(i); 1236} 1237 1238void ebt_iterate_targets(void (*f)(struct ebt_u_target *)) 1239{ 1240 struct ebt_u_target *i; 1241 1242 for (i = ebt_targets; i; i = i->next) 1243 f(i); 1244} 1245 1246/* Don't use this function, use ebt_print_bug() */ 1247void __ebt_print_bug(char *file, int line, char *format, ...) 1248{ 1249 va_list l; 1250 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"); 1255 va_end(l); 1256 exit (-1); 1257} 1258 1259/* The error messages are put in here when ebt_silent == 1 1260 * ebt_errormsg[0] == '\0' implies there was no error */ 1261char 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. */ 1264int ebt_silent; 1265/* Don't use this function, use ebt_print_error() */ 1266void __ebt_print_error(char *format, ...) 1267{ 1268 va_list l; 1269 1270 va_start(l, format); 1271 if (ebt_silent && ebt_errormsg[0] == '\0') { 1272 vsnprintf(ebt_errormsg, ERRORMSG_MAXLEN, format, l); 1273 va_end(l); 1274 } else { 1275 vfprintf(stderr, format, l); 1276 fprintf(stderr, ".\n"); 1277 va_end(l); 1278 exit (-1); 1279 } 1280} 1281