Advertisement
romic96

pus-07-iptc

Apr 17th, 2018
229
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 9.60 KB | None | 0 0
  1. /*
  2.  * Data:                2009-04-15
  3.  * Autor:               Jakub Gasior <quebes@mars.iti.pk.edu.pl>
  4.  * Kompilacja:          $ gcc iptc.c -o iptc -liptc
  5.  * Uruchamianie:        $ ./iptc -h
  6.  */
  7.  
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <errno.h>
  11. #include <string.h>
  12. #include <limits.h>
  13. #include <net/if.h>
  14. #include <netinet/in.h>
  15. #include <arpa/inet.h>
  16. #include <libiptc/libiptc.h>
  17. /* Zdefiniowane operacje: */
  18. enum opcode {
  19.     NONE,
  20.     DELETE_RULE,
  21.     NEW_CHAIN
  22. };
  23.  
  24. /* Regula - zawiera argumenty wywolania programu: */
  25. struct rule {
  26.     enum opcode     operation; /* Rodzaj operacji, np. '-D' (DELETE_RULE) */
  27.     const char      *chain; /* Nazwa lancucha. */
  28.     const char      *table; /* Nazwa tablicy ('-t <table>') */
  29.     /*
  30.      * Numer reguly (numeracja od 0). W programie iptables
  31.      * reguly sa wyswietlane od 1. W celu zachowania spojnosci, od podanej
  32.      * w argumencie wywolania liczby zostanie odjete 1 (w funkcji parse()):
  33.      */
  34.     int             rule_num;
  35. };
  36.  
  37. /* Funkcja odpowiedzialna za zaalokowanie obszaru pamieci o rozmiarze 'size'. */
  38. void *s_malloc(size_t size) {
  39.  
  40.     void* ptr;
  41.  
  42.     ptr = malloc(size);
  43.     if (!ptr) {
  44.         fprintf(stderr, "malloc() failed!\n");
  45.         exit(EXIT_FAILURE);
  46.     }
  47.  
  48.     return ptr;
  49. }
  50.  
  51. /*
  52.  * Argumentem funkcji jest adres wskaznika na obszar pamieci.
  53.  * Funkcja zwalnia pamiec i ustawia wskaznik na NULL.
  54.  */
  55. void s_free(void** ptr) {
  56.  
  57.     if (*ptr) {
  58.         free(*ptr);
  59.         *ptr = NULL;
  60.     }
  61.  
  62. }
  63.  
  64. /*
  65.  * Argumentem funkcji jest adres wskaznika na strukture 'rule'.
  66.  * Funkcja zwalnia pamiec i ustawia wskaznik na NULL.
  67.  */
  68. void free_rule(struct rule** ptr) {
  69.  
  70.     struct rule* r = *ptr;
  71.     if (r) {
  72.         s_free((void*)&r->chain);
  73.         s_free((void*)&r->table);
  74.         free(r);
  75.         *ptr = NULL;
  76.     }
  77.  
  78. }
  79.  
  80. /* Funkcja wypisuje informacje o bledzie i ustawia flage bledu: */
  81. void parse_error(char* str, int* error) {
  82.     fprintf(stderr, "%s", str);
  83.     *error = 1;
  84. }
  85.  
  86. /*
  87.  * Funkcja przetwarza argumenty wywolania programu i w przypadku powodzenia
  88.  * zwraca wskaznik na strukture 'rule'. Funkcja alokuje pamiec dla struktury
  89.  * 'rule', nalezy pamietac o jej zwolnieniu.
  90.  */
  91. struct rule* parse(int argc, char ** argv) {
  92.  
  93.     int             error; /* Sygnalizuje wystapienie bledu. */
  94.     struct rule     *r; /* Wskaznik na strukture przechowujaca regule. */
  95.     void            *ptr;
  96.  
  97.     if (argc < 2) {
  98.         fprintf(stderr, "parse(): invalid arguments\nTry '%s -h'\n",
  99.                 argv[0]);
  100.  
  101.         return NULL;
  102.     }
  103.  
  104.     error = 0; /* Stan poczatkowy = brak bledu */
  105.  
  106.     /* Alokacja pamieci dla reguly: */
  107.     r = (struct rule*)s_malloc(sizeof(struct rule));
  108.     r->chain = NULL;
  109.     r->table = NULL;
  110.     r->operation = NONE;
  111.  
  112.     /* Parsowanie argumentow wywolania: */
  113.     argv++;
  114.     while (*argv) {
  115.  
  116.         if (!strcmp(*argv, "-t")) { /* Okreslenie nazwy tablicy. */
  117.  
  118.             argv++; /* Przejscie do argumentu po '-t'. */
  119.             if ((*argv == NULL) || (**argv == '-')) {
  120.                 parse_error("Expecting <table> after -t\n",
  121.                             &error);
  122.                 break;
  123.             }
  124.  
  125.             /* Opcja '-t' wystepuje wiecej niz 1 raz: */
  126.             if (r->table) {
  127.                 parse_error("Table can be specified "
  128.                             "only once.\n", &error);
  129.                 break;
  130.             }
  131.  
  132.             /*
  133.              * Alokacja pamieci dla nazwy tablicy i
  134.              * zapisanie nazwy w 'r->table'.
  135.              * 'ptr' pozwala zachowac const dla 'r->table':
  136.              */
  137.             ptr = s_malloc(strlen(*argv) + 1);
  138.             strcpy(ptr, *argv);
  139.             r->table = ptr;
  140.             ptr = NULL;
  141.  
  142.         } else if (!strcmp(*argv, "-N")) { /* Utworzenie lancucha */
  143.  
  144.             if (r->operation != NONE) {
  145.                 parse_error("Can't use -N with other option.\n",
  146.                             &error);
  147.                 break;
  148.             }
  149.  
  150.             argv++; /* Przejscie do argumentu po '-N'. */
  151.             if ((*argv == NULL) || (**argv == '-')) {
  152.                 parse_error("Expecting <chain> after -N\n",
  153.                             &error);
  154.                 break;
  155.             }
  156.  
  157.             /*
  158.              * Alokacja pamieci dla nazwy lancucha i
  159.              * zapisanie nazwy w 'r->chain'.
  160.              * 'ptr' pozwala zachowac const dla 'r->chain':
  161.              */
  162.             ptr = s_malloc(strlen(*argv) + 1);
  163.             strcpy(ptr, *argv);
  164.             r->chain = ptr;
  165.             ptr = NULL;
  166.  
  167.             /* Regula NEW_CHAIN poprawna: */
  168.             r->operation = NEW_CHAIN;
  169.  
  170.         } else if (!strcmp(*argv, "-D")) { /* Usuniecie reguly */
  171.  
  172.             if (r->operation != NONE) {
  173.                 parse_error("Can't use -D with other option.\n",
  174.                             &error);
  175.                 break;
  176.             }
  177.  
  178.             argv++; /* Przejscie do argumentu po '-D'. */
  179.             if ((*argv == NULL) || (**argv == '-')) {
  180.                 parse_error("Expecting <chain> after -D\n",
  181.                             &error);
  182.                 break;
  183.             }
  184.  
  185.             /*
  186.              * Alokacja pamieci dla nazwy lancucha i
  187.              * zapisanie nazwy w 'r->chain'.
  188.              * 'ptr' pozwala zachowac const dla 'r->chain':
  189.              */
  190.             ptr = s_malloc(strlen(*argv) + 1);
  191.             strcpy(ptr, *argv);
  192.             r->chain = ptr;
  193.             ptr = NULL;
  194.  
  195.             /*
  196.              * Przejscie do argumentu po '-D <chain>'
  197.              * (numeru reguly do usuniecia):
  198.              */
  199.             argv++;
  200.             if ((*argv == NULL) || (**argv == '-')) {
  201.                 parse_error("Expecting <rule number> after "
  202.                             "-D <chain>\n", &error);
  203.                 break;
  204.             }
  205.  
  206.             r->rule_num = atoi(*argv) - 1;
  207.             if (r->rule_num < 0) {
  208.                 parse_error("Invalid <rule number>\n", &error);
  209.                 break;
  210.             }
  211.  
  212.             /* Regula DELETE_RULE poprawna: */
  213.             r->operation = DELETE_RULE;
  214.  
  215.         } else if (!strcmp(*argv, "-h")) { /* Pomoc. */
  216.  
  217.             fprintf(stdout,
  218.                     "Options:\n"
  219.                     "-D <chain> <rule num> Delete rule from chain\n"
  220.                     "-N <chain> Create user-defined chain\n"
  221.                     "-t <table> Table to manipulate\n");
  222.  
  223.             free_rule(&r);
  224.             exit(EXIT_SUCCESS);
  225.  
  226.         } else {
  227.             fprintf(stderr, "Unknown option: %s\n", *argv);
  228.             error = 1;
  229.             break;
  230.         }
  231.  
  232.         argv++; /* Sprawdzamy kolejne argumenty wywolania. */
  233.     }
  234.  
  235.     /* W przypadku braku '-D' lub '-N': */
  236.     if ((!error) && (r->operation == NONE)) {
  237.         fprintf(stderr, "No option specified!\n");
  238.         error = 1;
  239.     }
  240.  
  241.     /* W przypadku braku '-t': */
  242.     if ((!error) && (r->table == NULL)) {
  243.         fprintf(stderr, "No table specified!\n");
  244.         error = 1;
  245.     }
  246.  
  247.     if (error) {
  248.         free_rule(&r); /* Ustawia 'r' na NULL. */
  249.     }
  250.  
  251.     return r;
  252. }
  253.  
  254.  
  255. void delete_rule(struct xtc_handle *h, struct rule* r) {
  256.  
  257.     int retval;
  258.  
  259.     /* Sprawdzenie czy podany lancuch wystepuje w tablicy: */
  260.     retval = iptc_is_chain(r->chain, h);
  261.     if (!retval) {
  262.         fprintf(stderr, "Chain '%s' does not exist in table '%s'!\n",
  263.                 r->chain, r->table);
  264.         exit(EXIT_FAILURE);
  265.     }
  266.  
  267.     /* Usuniecie reguly o okreslonym numerze: */
  268.     retval = iptc_delete_num_entry(r->chain, (unsigned int) r->rule_num, h);
  269.     if (!retval) {
  270.         fprintf(stderr, "iptc_delete_num_entry(): %s\n",
  271.                 iptc_strerror(errno));
  272.         exit(EXIT_FAILURE);
  273.     }
  274.  
  275.     /*
  276.      * Zatwierdzenie zmian. Funkcja zwalnia pamiec zaalokowana dla 'h' i
  277.      * ustawia uchwyt na NULL:
  278.      */
  279.     retval = iptc_commit(h);
  280.     if (!retval) {
  281.         fprintf(stderr, "iptc_commit(): %s!\n",
  282.                 iptc_strerror(errno));
  283.         exit(EXIT_FAILURE);
  284.     }
  285. }
  286.  
  287.  
  288. void create_chain(struct xtc_handle *h, struct rule* r) {
  289.  
  290.     int retval;
  291.  
  292.     /* Utworzenie nowego lancucha: */
  293.     retval = iptc_create_chain(r->chain, h);
  294.     if (!retval) {
  295.         fprintf(stderr, "iptc_delete_num_entry(): %s\n",
  296.                 iptc_strerror(errno));
  297.         exit(EXIT_FAILURE);
  298.     }
  299.  
  300.     /*
  301.      * Zatwierdzenie zmian. Funkcja zwalnia pamiec zaalokowana dla 'h' i
  302.      * ustawia uchwyt na NULL:
  303.      */
  304.     retval = iptc_commit(h);
  305.     if (!retval) {
  306.         fprintf(stderr, "iptc_commit(): %s!\n",
  307.                 iptc_strerror(errno));
  308.         exit(EXIT_FAILURE);
  309.     }
  310. }
  311.  
  312. int main(int argc, char **argv) {
  313.  
  314.     struct rule     *r; /* Wskaznik na regule. */
  315.     struct xtc_handle   *h; /* Uchwyt. */
  316.  
  317.     /* parse() zwraca regule na podstawie argumentow wywolania programu: */
  318.     r = parse(argc, argv);
  319.     if (!r) {
  320.         exit(EXIT_FAILURE);
  321.     }
  322.  
  323.     /* Inicjalizacja dla tablicy okreslonej przez parametr 'r->table': */
  324.     h = iptc_init(r->table);
  325.     if (!h) {
  326.         fprintf(stderr, "iptc_init(): %s\n", iptc_strerror(errno));
  327.         exit(EXIT_FAILURE);
  328.     }
  329.  
  330.  
  331.     /* Usuniecie reguly: */
  332.     if (r->operation == DELETE_RULE) {
  333.         delete_rule(h, r);
  334.     } else if (r->operation == NEW_CHAIN) { /* Utworzenie lancucha. */
  335.         create_chain(h, r);
  336.     }
  337.  
  338.     /* Zwolnienie pamieci zaalokowanej dla reguly w funkcji parse(): */
  339.     free_rule(&r);
  340.  
  341.     if (h) {
  342.         /* Zamkniecie uchwytu (funkcja nie powinna sie wywolac,
  343.          * poniewaz iptc_commit() zwolnila uchwyt 'h'): */
  344.         iptc_free(h);
  345.     }
  346.  
  347.     exit(EXIT_SUCCESS);
  348. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement