1. 程式人生 > >使用 libiptc 操作 iptables

使用 libiptc 操作 iptables

這些程式碼花了我三天才寫出來,filter表的操作沒問題,nat表操作不太對。在arm平臺也有點不對,懶得除錯了,分享出來吧。

#include <getopt.h> #include <sys/errno.h> #include <stdio.h> #include <fcntl.h> #include <stdlib.h> #include <string.h> #include <dlfcn.h> #include <time.h> #include <netdb.h> #include <libiptc/libiptc.h> //#include <ip_tables.h> #define MIN_PORT 0 #define MAX_PORT 65535 //linux/include/linux/netfilter_ipv4/ip_tables.h #define IPT_ALIGN(s) (((s) + (__alignof__(struct ipt_entry)-1)) & ~(__alignof__(struct ipt_entry)-1)) struct xtc_handle *t_handle;      void show_all_rule() {  const char *chain = NULL;     const char * policy = NULL;     struct ipt_counters counter;          for (chain = iptc_first_chain(t_handle); chain; chain = iptc_next_chain(t_handle))      {      printf("\nChain: %s\n", chain);      if (chain!=NULL && t_handle!=NULL)      {         policy = iptc_get_policy(chain,&counter,t_handle);          printf("policy: %s\n",policy);          printf("  packet count: %llu\t",counter.pcnt);          printf("  byte count: %llu\n",counter.bcnt);      }      else         printf("policy error !\n");            x_get_rule(chain,t_handle);            }//for }     //append rule int  x_append_rule(char *chain ,struct ipt_entry *e) { if (iptc_append_entry(chain,e,t_handle)!=1) { printf("Error x_append_rule: %s\n", iptc_strerror(errno)); return 0; } iptc_commit(t_handle); return 1; } //insert tule by num int x_insert_rule(char *chain ,struct ipt_entry *e,int num) { if (iptc_insert_entry(chain,e,num,t_handle)!=1) { printf("Error x_insert_rule: %s\n", iptc_strerror(errno)); return 0; } iptc_commit(t_handle); return 1; } //iptables -I OUTPUT -s 192.168.6.2 -d 192.168.3.4 -p UDP --dport 1933 -j DROP int demo_insert() {  struct ipt_entry_target *a_t ;  struct ipt_entry_match  *a_m;  struct ipt_entry  *a_e;  struct ipt_tcp *ptcp;  struct ipt_ip *pip;  size_t target_size,match_size,entry_size;        //init size      match_size = sizeof(struct ipt_entry_match) + sizeof(struct ipt_tcp);      target_size = IPT_ALIGN(sizeof(struct ipt_entry_target)) + IPT_ALIGN(sizeof(int));      entry_size = sizeof(*a_e) + target_size + match_size;           //full struct ipt_entry       a_e = malloc(entry_size);     memset(a_e,0,entry_size);          a_e->ip.src.s_addr = inet_addr("192.168.6.2");          a_e->ip.smsk.s_addr = -1;     //--- for --to--destination          a_e->ip.dst.s_addr = inet_addr("192.168.3.4");          a_e->ip.dmsk.s_addr = -1;               //---          a_e->ip.proto = 17;//udp          a_e->target_offset = sizeof(*a_e) + match_size;          a_e->next_offset = entry_size;         //full struct ip_entry_match         a_m = (struct ipt_entry_match*)a_e->elems;         a_m->u.user.match_size = match_size;         strcpy(a_m->u.user.name,"udp");     //full struct ipt_tcp     ptcp = (struct ipt_tcp*)a_m->data;       ptcp->spts[0] = -1;ptcp->spts[1] = -1;//any sport       ptcp->dpts[0] = 1933;ptcp->dpts[1] = 1933;//one port     //full struct ipt_entry_target     a_t = (struct ipt_entry_target*)(a_e->elems + match_size);     a_t->u.user.target_size = target_size;     strcpy(a_t->u.user.name,"DROP");          //do_command     x_insert_rule("OUTPUT",a_e,0);//num==1 can‘t add ??   return 1; } //get chain and policy list void x_get_rule(const char *chain,struct xtc_handle *handle) { const struct ipt_entry* rule; struct ipt_entry_match* a_m; struct ipt_tcp* ptcp; for(rule = iptc_first_rule(chain,handle); rule; rule = iptc_next_rule(rule,handle))       {             const char *target = NULL;             target= iptc_get_target(rule,handle);             //printf("rule name : %s\n",target);             //printf("rule count: %llu\n",rule->counters.pcnt);             //printf("rule strlen:%llu\n",rule->counters.bcnt);                          struct protoent *pro = NULL;             pro= getprotobynumber(rule->ip.proto);               if(pro != NULL )             {                  printf("  policy_id:%04d    proto_name:%s  \n",pro->p_proto, pro->p_name);             }               printf("  in_iface: ");             if(rule->ip.iniface[0] == ‘\0‘ )// -i param                 printf("any\t");             else                 printf("%s\t",rule->ip.iniface);               printf("  out_iface: ");             if(rule->ip.outiface[0] == ‘\0‘ )//-o param                 printf("any\n");             else                printf("%s\n",rule->ip.outiface);               char addr[32] = {0};             printf("  sip:%s/%s    \t",inet_ntop(AF_INET,&(rule->ip.src),addr,sizeof(addr)),inet_ntop(AF_INET,&(rule->ip.smsk),addr,sizeof(addr)) );             printf("dip:%s/%s\n",inet_ntop(AF_INET,&(rule->ip.dst),addr,sizeof(addr)),inet_ntop(AF_INET,&(rule->ip.dmsk),addr,sizeof(addr)) );                          //ip.dmsk.s_addr            //full struct ip_entry_match            a_m = (struct ipt_entry_match*)rule->elems;         //full struct ipt_tcp         ptcp = (struct ipt_tcp*)a_m->data;          if (ptcp->spts[0]<=0 || ptcp->spts[0]==0xffff)            printf("  sport : any \t");        else           printf("  sport range :  %d --- %d \t",ptcp->spts[0],ptcp->spts[1]);        if (ptcp->dpts[0]<=0 || ptcp->dpts[0]==0xffff)            printf("d_port : any \t");        else           printf("d_port range :  %d --- %d \n",ptcp->dpts[0],ptcp->dpts[1]);              } } //init libiptc int  x_init(int type) {   //if  "-t nat" tablename == "nat" ,it table can use PREROUTING      const char *default_tablename = "filter";   const char *nat_tablename = "nat";   const char *chain = NULL;      if (type==1)   {    t_handle = iptc_init(default_tablename);         printf("***** oepn nat table *****\n");   }   else   {         printf("***** open nat table *****\n");    t_handle = iptc_init(nat_tablename);   }        if ( t_handle == NULL )    {      printf("Error initializing: %s\n", iptc_strerror(errno));      return errno;   }  //del nat table all rule  for (chain = iptc_first_chain(t_handle); chain; chain = iptc_next_chain(t_handle))   {      iptc_flush_entries(chain,t_handle);      printf("Clean %s rule \n",chain);  }//for    return 1; } //---------------------------------------------------------------  //iptables -A INPUT -i eth0 -p icmp -j DROP   int demo_append1()   {    //***append route    struct ipt_entry_target *a_t = NULL;    struct ipt_entry  *a_e ;  int i;        size_t  target_size,entry_size;    //init size    target_size = IPT_ALIGN(sizeof(struct ipt_entry_target)) + IPT_ALIGN(sizeof(int));    entry_size = sizeof(*a_e) + target_size;        //full ipt_entry    a_e = malloc(entry_size);  memset(a_e,0,entry_size);    strcpy(a_e->ip.iniface,"eth0");  //a_e->ip.iniface[0] == ‘\0‘    for(i=0;i<(strlen("eth0")+1);i++) a_e->ip.iniface_mask[i] = 0xffff;    a_e->ip.proto = 1; //icmp    a_e->target_offset = sizeof(*a_e);    a_e->next_offset = entry_size;    //full ipt_entry_target    a_t = (struct ipt_entry_target *)a_e->elems;    a_t->u.user.target_size = target_size;         strcpy(a_t->u.user.name,"DROP");        //do_command    x_append_rule("INPUT",a_e);    return 1;      } /*  struct xt_tcp  { __u16 spts[2];                  //Source port range.  __u16 dpts[2];                  //Destination port range.  __u8 option;                   //TCP Option iff non-zero __u8 flg_mask;                  // TCP flags mask byte  __u8 flg_cmp;                  //TCP flags compare byte  __u8 invflags;                // Inverse flags  }; struct ipt_ip  { struct in_addr src, dst; struct in_addr smsk, dmsk; char iniface[IFNAMSIZ], outiface[IFNAMSIZ]; unsigned char iniface_mask[IFNAMSIZ], outiface_mask[IFNAMSIZ]; u_int16_t proto; u_int8_t flags; u_int8_t invflags; }; */ //iptables -A FORWARD -s 192.168.2.2 -d 192.168.3.4 -p tcp --dport 80 -j ACCEPT int demo_append2() {  struct ipt_entry_target *a_t ;  struct ipt_entry_match  *a_m;  struct ipt_entry  *a_e;  struct ipt_tcp *ptcp;  struct ipt_ip *pip;  size_t target_size,match_size,entry_size;      //init size    match_size = sizeof(struct ipt_entry_match) + sizeof(struct ipt_tcp);    target_size = IPT_ALIGN(sizeof(struct ipt_entry_target)) + IPT_ALIGN(sizeof(int));    entry_size = sizeof(*a_e) + target_size + match_size;        //full struct ipt_entry    a_e = malloc(entry_size);  memset(a_e,0,entry_size);       a_e->ip.src.s_addr = inet_addr("192.168.2.2");       a_e->ip.smsk.s_addr = -1;      a_e->ip.dst.s_addr = inet_addr("192.168.3.4");      a_e->ip.dmsk.s_addr = -1;      a_e->ip.proto = 6;//tcp      a_e->target_offset = sizeof(*a_e) + match_size;      a_e->next_offset = entry_size;      //full struct ip_entry_match      a_m = (struct ipt_entry_match*)a_e->elems;      a_m->u.user.match_size = match_size;      strcpy(a_m->u.user.name,"tcp");     //full struct ipt_tcp     ptcp = (struct ipt_tcp*)a_m->data;       ptcp->spts[0] = -1;ptcp->spts[1] = -1;//any sport       ptcp->dpts[0] = 80;ptcp->dpts[1] = 80;//one port     //full struct ipt_entry_target     a_t = (struct ipt_entry_target*)(a_e->elems + match_size);     a_t->u.user.target_size = target_size;     strcpy(a_t->u.user.name,"ACCEPT");          //do_command     x_append_rule("FORWARD",a_e);   return 1; } //iptables -A PREROUTING -d 0.0.0.0/0 -p tcp --dport 80 -j DNAT --to--destination 172.16.1.1 void demo_do_nat() {    struct ipt_entry_target *a_t ;  struct ipt_entry_match  *a_m;  struct ipt_entry  *a_e;  struct ipt_tcp *ptcp;  struct ipt_ip *pip;  size_t target_size,match_size,entry_size;       //init size     match_size = sizeof(struct ipt_entry_match) + sizeof(struct ipt_tcp);     target_size = IPT_ALIGN(sizeof(struct ipt_entry_target)) + IPT_ALIGN(sizeof(int));     entry_size = sizeof(*a_e) + target_size + match_size;         //full struct ipt_entry     a_e = malloc(entry_size);   memset(a_e,0,entry_size);        a_e->ip.src.s_addr = 0;        a_e->ip.dmsk.s_addr = -1;        a_e->ip.dst.s_addr = 0;        a_e->ip.dmsk.s_addr = -1;        a_e->ip.proto = 6;//tcp        a_e->target_offset = sizeof(*a_e) + match_size;        a_e->next_offset = entry_size;        //full struct ip_entry_match        a_m = (struct ipt_entry_match*)a_e->elems;        a_m->u.user.match_size = match_size;        strcpy(a_m->u.user.name,"tcp");     //full struct ipt_tcp     ptcp = (struct ipt_tcp*)a_m->data;       ptcp->spts[0] = -1;ptcp->spts[1] = -1;//any sport       ptcp->dpts[0] = 80;ptcp->dpts[1] = 80;//one port     //full struct ipt_entry_target     a_t = (struct ipt_entry_target*)(a_e->elems + match_size);     a_t->u.user.target_size = target_size;   strcpy(a_t->u.user.name,"DNAT");        //do_command     x_append_rule("PREROUTING",a_e); } //opt nat table void do_nat_table() {  //open nat table  if (x_init(2)!=1)  {   exit(0);  }  //iptables     //iptables -t nat -A PREROUTING -d 0.0.0.0/0 -p tcp --dport 80 -j DNAT --to--destination 172.16.1.1     demo_do_nat();//....  //show all nat table rule  printf("****************************************\n");    printf("SHOW ALL NAT TABLE RULE \n");  printf("****************************************\n");    show_all_rule();    } //opt to filter table void do_filter_table() {      //open filter table  if (x_init(1)!=1)  {   exit(0);  }          //iptables -A INPUT -i eth0 -p icmp -j DROP     demo_append1();     //iptables -A FORWARD -s 192.168.2.2 -d 192.168.3.4 -p tcp --dport 80 -j DROP     demo_append2();  //iptables -I OUTPUT 1 -s 192.168.6.2 -d 192.168.3.4 -p UDP --dport 1933 -j DROP     demo_insert();       //show all filter table rule  printf("****************************************\n");  printf("SHOW ALL FILTER TABLE RULE \n");  printf("****************************************\n");     show_all_rule();      } int main(void) {      //use default table filter to  : iptc_append_entry() iptc_insert_entry()      //note filter talbe can use policy is  FORWARD,INPUT ,OUTPUT      do_filter_table();            //user table nat to : iptc_append_entry()      //note -DNAT  only can use in nat talbe,and policy == PREROUTING and OUTPUT      do_nat_table();                  exit(0); } /* main */

執行結果:

***** oepn nat table ***** Clean INPUT rule  Clean FORWARD rule  Clean OUTPUT rule  **************************************** SHOW ALL FILTER TABLE RULE  **************************************** Chain: INPUT policy: ACCEPT   packet count: 821       byte count: 83028   policy_id:0001    proto_name:icmp     in_iface: eth0          out_iface: any   sip:0.0.0.0/0.0.0.0           dip:0.0.0.0/0.0.0.0   sport : any   d_port range :  17 --- 0  Chain: FORWARD policy: ACCEPT   packet count: 0         byte count: 0   policy_id:0006    proto_name:tcp     in_iface: any   out_iface: any   sip:192.168.2.2/192.168.2.2           dip:192.168.3.4/192.168.3.4   sport : any   d_port range :  80 --- 80  Chain: OUTPUT policy: ACCEPT   packet count: 282       byte count: 46662   policy_id:0017    proto_name:udp     in_iface: any   out_iface: any   sip:192.168.6.2/192.168.6.2           dip:192.168.3.4/192.168.3.4   sport : any   d_port range :  1933 --- 1933  ***** open nat table ***** Clean PREROUTING rule  Clean INPUT rule  Clean OUTPUT rule  Clean POSTROUTING rule  **************************************** SHOW ALL NAT TABLE RULE  **************************************** Chain: PREROUTING policy: ACCEPT   packet count: 7334      byte count: 384511   policy_id:0006    proto_name:tcp     in_iface: any   out_iface: any   sip:0.0.0.0/0.0.0.0           dip:0.0.0.0/0.0.0.0   sport : any   d_port range :  80 --- 80  Chain: INPUT policy: ACCEPT   packet count: 698       byte count: 105695 Chain: OUTPUT policy: ACCEPT   packet count: 714       byte count: 40988 Chain: POSTROUTING policy: ACCEPT   packet count: 714       byte count: 40988

轉之原文:http://blog.csdn.net/xjb2001/article/details/39579227