在机器人的iptables [英] iptables in android

查看:250
本文介绍了在机器人的iptables的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

现的IPtables在Android的内核内置的?如果是,如何利用他们在我们的Andr​​oid应用程序?

Are IPtables inbuilt in android kernel? If they are, how to use them in our android application?

推荐答案

iptables的是AOSP默认模块,可以使用netfilter的c写code来处理。

iptables is a default module in AOSP, you can use netfilter to write c code to handle that.

例如,您可以创建一个Android项目,并编写JNI文件,请使用NDK建造,以编译,然后亚行可执行文件推送到Android文件系统执行。而在移动端,您可以ADB命令行中给它,直接用iptables命令作为根用户,就像在linux下做的。

For example, you can create an android project, and write a JNI file, use ndk-build to compile that, and then adb push the executable to the android file system to execute. And in the mobile end, you can adb shell to it, directly use iptables command as a root user, just like in linux do.

附件:

#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);
}

这篇关于在机器人的iptables的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆