android中的iptables

android中的iptables,android,networking,iptables,Android,Networking,Iptables,IPtables内置在android内核中吗?如果是,如何在我们的android应用程序中使用它们 我不认为iptables在正常的Android发行版中可用。但是,在根手机上,您可以添加交叉编译的iptables二进制文件。Android源代码中有“itables”可执行文件。内核也应该支持它。尽管您可能需要在设备上拥有root权限才能使用它 iptables在Android源代码分发版中可用。但是,该版本仅适用于使用Linux内核2.6.29构建的设备 零售Android设备的用户无法访问i

IPtables内置在android内核中吗?如果是,如何在我们的android应用程序中使用它们

我不认为iptables在正常的Android发行版中可用。但是,在根手机上,您可以添加交叉编译的iptables二进制文件。

Android源代码中有“itables”可执行文件。内核也应该支持它。尽管您可能需要在设备上拥有root权限才能使用它

  • iptables在Android源代码分发版中可用。但是,该版本仅适用于使用Linux内核2.6.29构建的设备
  • 零售Android设备的用户无法访问iptables二进制文件。甚至安卓操作系统本身也无法访问该二进制文件。这是用Android硬编码的。许多设备也根本没有iptable
  • 访问iptables二进制文件的唯一方法是构建自己的Android图像。退房一旦你对这个过程感到满意,就去看看吧

  • iptables是AOSP中的默认模块,您可以使用netfilter编写c代码来处理它

    例如,您可以创建一个android项目,编写一个JNI文件,使用ndk build编译该文件,然后将可执行文件推送到android文件系统执行。在移动端,您可以将adb shell添加到它,作为根用户直接使用iptables命令,就像在linux中一样

    附件:

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <linux/types.h>
    #include <linux/ip.h>
    #include <linux/tcp.h>
    #include <linux/netfilter.h>        /* for NF_ACCEPT */
    #include <errno.h>
    
    #include <libnetfilter_queue/libnetfilter_queue.h>
    
    #ifdef __LITTLE_ENDIAN
    #define IPQUAD(addr) \
        ((unsigned char *)&addr)[0], \
        ((unsigned char *)&addr)[1], \
        ((unsigned char *)&addr)[2], \
        ((unsigned char *)&addr)[3]
    #else
    #define IPQUAD(addr) \
        ((unsigned char *)&addr)[3], \
        ((unsigned char *)&addr)[2], \
        ((unsigned char *)&addr)[1], \
        ((unsigned char *)&addr)[0]
    #endif
    
    
    #define TO "192.168.191.129"
    #define NAT_TO "192.168.2.246"
    
    struct tcp_pseudo /*the tcp pseudo header*/
    {
        __u32 src_addr;
        __u32 dst_addr;
        __u8 zero;
        __u8 proto;
        __u16 length;
    } pseudohead;
    
    
    long checksum(unsigned short *addr, unsigned int count) {
        /* Compute Internet Checksum for "count" bytes
       * beginning at location "addr".
       */
        register long sum = 0;
    
        while( count > 1 ) {
            /* This is the inner loop */
            sum += * addr++;
            count -= 2;
        }
        /* Add left-over byte, if any */
        if( count > 0 )
            sum += * (unsigned char *) addr;
    
        /* Fold 32-bit sum to 16 bits */
        while (sum>>16)
            sum = (sum & 0xffff) + (sum >> 16);
    
        return ~sum;
    }
    
    
    
    /*************************tcp checksum**********************/
    long get_tcp_checksum(struct iphdr * myip, struct tcphdr * mytcp) {
    
        __u16 total_len = ntohs(myip->tot_len);
    
        int tcpopt_len = mytcp->doff*4 - 20;
        int tcpdatalen = total_len - (mytcp->doff*4) - (myip->ihl*4);
    
        pseudohead.src_addr=myip->saddr;
        pseudohead.dst_addr=myip->daddr;
        pseudohead.zero=0;
        pseudohead.proto=IPPROTO_TCP;
        pseudohead.length=htons(sizeof(struct tcphdr) + tcpopt_len + tcpdatalen);
    
        int totaltcp_len = sizeof(struct tcp_pseudo) + sizeof(struct tcphdr) + tcpopt_len +tcpdatalen;
        //unsigned short * tcp = new unsigned short[totaltcp_len];
    
        unsigned short * tcp = malloc(totaltcp_len);
    
    
        memcpy((unsigned char *)tcp,&pseudohead,sizeof(struct tcp_pseudo));
        memcpy((unsigned char *)tcp+sizeof(struct tcp_pseudo),(unsigned char*)mytcp,sizeof(struct tcphdr));
        memcpy((unsigned char *)tcp+sizeof(struct tcp_pseudo)+sizeof(struct tcphdr),(unsigned char *)myip+(myip->ihl*4)+(sizeof(struct tcphdr)), tcpopt_len);
        memcpy((unsigned char *)tcp+sizeof(struct tcp_pseudo)+sizeof(struct tcphdr)+tcpopt_len, (unsigned char *)mytcp+(mytcp->doff*4), tcpdatalen);
    
        /* printf("pseud length: %d\n",pseudohead.length);
              printf("tcp hdr length: %d\n",mytcp->doff*4);
              printf("tcp hdr struct length: %d\n",sizeof(struct tcphdr));
              printf("tcp opt length: %d\n",tcpopt_len);
              printf("tcp total+psuedo length: %d\n",totaltcp_len);
    
              fflush(stdout);
    
              printf("tcp data len: %d, data start %u\n", tcpdatalen,mytcp + (mytcp->doff*4));
       */
    
    
        return checksum(tcp,totaltcp_len);
    
    }
    
    
    static u_int16_t tcp_checksum(struct iphdr* iphdrp){
        struct tcphdr *tcphdrp =
                (struct tcphdr*)((u_int8_t*)iphdrp + (iphdrp->ihl<<2));
                return get_tcp_checksum(iphdrp, tcphdrp);
    }
    
    static void set_tcp_checksum(struct iphdr* iphdrp){
        struct tcphdr *tcphdrp =
                (struct tcphdr*)((u_int8_t*)iphdrp + (iphdrp->ihl<<2));
                tcphdrp->check = 0;
                tcphdrp->check = get_tcp_checksum(iphdrp, tcphdrp);
    }
    /****************************tcp checksum end****************************/
    
    
    /********************************Ip checksum*****************************/
    static u_int16_t ip_checksum(struct iphdr* iphdrp){
        return checksum((unsigned short*)iphdrp, iphdrp->ihl<<2);
    }
    
    static void set_ip_checksum(struct iphdr* iphdrp){
        iphdrp->check = 0;
        iphdrp->check = checksum((unsigned short*)iphdrp, iphdrp->ihl<<2);
    }
    /****************************Ip checksum end******************************/
    
    
    static int cb(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg,
              struct nfq_data *nfa, void *data)
    {
        int id = 0;
        struct nfqnl_msg_packet_hdr *ph;
        int pdata_len;
        unsigned char *payload;
    
        printf("entering callback\n");
        ph = nfq_get_msg_packet_hdr(nfa);
        if (ph) {
            id = ntohl(ph->packet_id);
        }
    
        pdata_len = nfq_get_payload(nfa, &payload);
        if (pdata_len >= 0) {
            struct iphdr *iphdrp = (struct iphdr*)payload;
            iphdrp->daddr = inet_addr(NAT_TO);
            set_ip_checksum(iphdrp);
            if(iphdrp->protocol == IPPROTO_TCP){
                set_tcp_checksum(iphdrp);
                printf(" ipsum+ %hu tcpsum+ %hu",
                       ip_checksum(iphdrp), tcp_checksum(iphdrp));
            }
            printf("len %d iphdr %d %u.%u.%u.%u ->",
                   pdata_len,
                   iphdrp->ihl<<2,
                   IPQUAD(iphdrp->saddr));
            printf(" %u.%u.%u.%u",
                   IPQUAD(iphdrp->daddr));
            printf(" ipsum %hu", ip_checksum(iphdrp));
            if(iphdrp->protocol == IPPROTO_TCP){
                printf(" tcpsum %hu", tcp_checksum(iphdrp));
            }
            printf("\n");
    
        }
        return nfq_set_verdict(qh, id, NF_ACCEPT, (u_int32_t)pdata_len, payload);
    }
    
    int main(int argc, char **argv)
    {
        struct nfq_handle *h;
        struct nfq_q_handle *qh;
        struct nfnl_handle *nh;
        int fd;
        int rv;
        char buf[4096] __attribute__ ((aligned));
    
        printf("opening library handle\n");
        h = nfq_open();
        if (!h) {
            fprintf(stderr, "error during nfq_open()\n");
            exit(1);
        }
    
        printf("unbinding existing nf_queue handler for AF_INET (if any)\n");
        if (nfq_unbind_pf(h, AF_INET) < 0) {
            fprintf(stderr, "error during nfq_unbind_pf()\n");
            exit(1);
        }
    
        printf("binding nfnetlink_queue as nf_queue handler for AF_INET\n");
        if (nfq_bind_pf(h, AF_INET) < 0) {
            fprintf(stderr, "error during nfq_bind_pf()\n");
            exit(1);
        }
    
        printf("binding this socket to queue '0'\n");
        qh = nfq_create_queue(h,  0, &cb, NULL);
        if (!qh) {
            fprintf(stderr, "error during nfq_create_queue()\n");
            exit(1);
        }
    
        printf("setting copy_packet mode\n");
        if (nfq_set_mode(qh, NFQNL_COPY_PACKET, 0xffff) < 0) {
            fprintf(stderr, "can't set packet_copy mode\n");
            exit(1);
        }
    
        fd = nfq_fd(h);
    
        for (;;) {
            if ((rv = recv(fd, buf, sizeof(buf), 0)) >= 0) {
                printf("pkt received\n");
                nfq_handle_packet(h, buf, rv);
                continue;
            }
            /* if your application is too slow to digest the packets that
             * are sent from kernel-space, the socket buffer that we use
             * to enqueue packets may fill up returning ENOBUFS. Depending
             * on your application, this error may be ignored. Please, see
             * the doxygen documentation of this library on how to improve
             * this situation.
             */
            if (rv < 0 && errno == ENOBUFS) {
                printf("losing packets!\n");
                continue;
            }
            perror("recv failed");
            break;
        }
    
        printf("unbinding from queue 0\n");
        nfq_destroy_queue(qh);
    
    #ifdef INSANE
        /* normally, applications SHOULD NOT issue this command, since
         * it detaches other programs/sockets from AF_INET, too ! */
        printf("unbinding from AF_INET\n");
        nfq_unbind_pf(h, AF_INET);
    #endif
    
        printf("closing library handle\n");
        nfq_close(h);
    
        exit(0);
    }
    
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括/*用于NF_验收*/
    #包括
    #包括
    #伊夫迪夫·利特尔·恩迪安
    #定义IPQUAD(addr)\
    ((无符号字符*)&addr)[0]\
    ((无符号字符*)&addr)[1]\
    ((无符号字符*)&addr)[2]\
    ((无符号字符*)&addr)[3]
    #否则
    #定义IPQUAD(addr)\
    ((无符号字符*)&addr)[3]\
    ((无符号字符*)&addr)[2]\
    ((无符号字符*)&addr)[1]\
    ((无符号字符*)&addr)[0]
    #恩迪夫
    #定义为“192.168.191.129”
    #将NAT_定义为“192.168.2.246”
    struct tcp_pseudo/*tcp伪头*/
    {
    __u32 src_地址;
    __u32 dst_地址;
    __u8零;
    __u8原型;
    __u16长度;
    }假头;
    长校验和(无符号短*地址,无符号整数计数){
    /*计算“计数”字节的Internet校验和
    *从“地址”位置开始。
    */
    寄存器长和=0;
    而(计数>1){
    /*这是内环*/
    总和+=*相加++;
    计数-=2;
    }
    /*添加剩余字节(如果有)*/
    如果(计数>0)
    sum+=*(无符号字符*)addr;
    /*将32位和折叠为16位*/
    而(总和>>16)
    总和=(总和&0xffff)+(总和>>16);
    返回~求和;
    }
    /*************************tcp校验和**********************/
    长获取\u tcp\u校验和(结构iphdr*myip,结构tcphdr*mytcp){
    __u16总计=ntohs(myip->总计);
    int tcpopt_len=mytcp->doff*4-20;
    int tcpdatalen=总长度-(mytcp->doff*4)-(myip->ihl*4);
    pseudohead.src_addr=myip->saddr;
    pseudohead.dst_addr=myip->daddr;
    伪头,0=0;
    pseudohead.proto=IPPROTO_TCP;
    伪头长度=htons(尺寸(结构tcphdr)+tcpopt_len+tcpdatalen);
    int totaltcp_len=sizeof(struct tcp_pseudo)+sizeof(struct tcphdr)+tcpopt_len+tcpdatalen;
    //unsigned short*tcp=新的unsigned short[totaltcp_len];
    无符号短*tcp=malloc(totaltcp_len);
    memcpy((unsigned char*)tcp和pseudohead,sizeof(struct tcp_pseudo));
    memcpy((unsigned char*)tcp+sizeof(struct tcp_pseudo),(unsigned char*)mytcp,sizeof(struct tcphdr));
    memcpy((无符号字符*)tcp+sizeof(struct tcp_pseudo)+sizeof(struct tcphdr),(无符号字符*)myip+(myip->ihl*4)+(sizeof(struct tcphdr)),tcpopt_len);
    memcpy((无符号字符*)tcp+sizeof(struct tcp_pseudo)+sizeof(struct tcphdr)+tcpopt_len,(无符号字符*)mytcp+(mytcp->doff*4),tcpdatalen);
    /*printf(“伪头长度:%d\n”,伪头.length);
    printf(“tcp hdr长度:%d\n”,mytcp->doff*4);
    printf(“tcp hdr结构长度:%d\n”,sizeof(struct tcphdr));
    printf(“tcp选项长度:%d\n”,tcpopt_len);
    printf(“tcp总长度+psuedo长度:%d\n”,总tcp长度);
    fflush(stdout);
    printf(“tcp数据长度:%d,数据开始%u\n”,tcpdatalen,mytcp+(mytcp->doff*4));
    */
    返回校验和(tcp、totaltcp_len);
    }
    静态u_int16_t tcp_校验和(结构iphdr*iphdrp){
    结构tcphdr*tcphdrp=
    (结构tcphdr*)((u_int8_t*)iphdrp+(iphdrp->ihlichcheck=校验和((无符号短*)iphdrp,iphdrp->ihl=0){
    结构iphdr*iphdrp=(结构iphdr*)有效负载;
    iphdrp->daddr=inet\u addr(NAT\u TO);
    设置ip校验和(iphdrp);
    如果(iphdrp->协议==IPPROTO_TCP){
    设置tcp校验和(iphdrp);
    printf(“ipsum+%hu tcpsum+%hu”,
    ip_校验和(iphdrp)、tcp_校验和(iphdrp));
    }
    printf(“len%d iphdr%d%u.%u.%u->”,
    pdata_len,
    iphdrp->ihldaddr);
    printf(“ipsum%hu”,ip_校验和(iphdrp));
    如果(iphdrp->协议==IPPROTO_TCP){
    printf(“tcpsum%hu”,tcp_校验和(iphdrp));
    }
    printf(“\n”);
    }
    返回nfq设置判决(qh,id,NF接受,(u int32 t)数据长度,有效载荷);
    }
    int main(int argc,字符**argv)
    {
    结构nfq_句柄*h;
    结构nfq_q_句柄*qh;
    结构nfnl_句柄*nh;
    int-fd;
    int-rv;
    char buf[4096]uuu属性_uuu((对齐));
    printf(“打开库句柄”);
    h=nfq_open();
    如果(!h){
    fprintf(标准,“nfq_打开时出错()\n”);
    出口(1);
    }
    printf(“为AF_INET(如果有)解除现有nf_队列处理程序的绑定)\n”);
    if(nfq_unbind_pf(h,AF_INET)<0){
    fprintf(标准,“nfq_unbind_pf()\n期间出错”);
    出口(1);
    }
    printf(“将nfnetlink_队列绑定为AF_INET的nf_队列处理程序\n”);
    if(nfq\u bind\u pf(h,AF\u INET)<0){
    fprintf(stderr,“nfq_bind_pf()\n期间出错”);
    出口(1);
    }
    printf(“将此套接字绑定到队列“0”\n”);
    qh=nfq_创建_队列(h,0,&cb,NULL);
    if(!qh){
    
    $ su -
    # mount -o remount,rw /system
    # cp /data/data/android.tether/bin/iptables /system/bin/