android中的iptables
IPtables内置在android内核中吗?如果是,如何在我们的android应用程序中使用它们 我不认为iptables在正常的Android发行版中可用。但是,在根手机上,您可以添加交叉编译的iptables二进制文件。Android源代码中有“itables”可执行文件。内核也应该支持它。尽管您可能需要在设备上拥有root权限才能使用它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是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/