Iptables en android

¿Están incorporados IPtables en el núcleo de android? Si lo son, ¿cómo usarlos en nuestra aplicación Android?

Iptables es un módulo predeterminado en AOSP, puede utilizar netfilter para escribir c código para manejar eso.

Por ejemplo, puede crear un proyecto android y escribir un archivo JNI, usar ndk-build para compilarlo y luego empujar el ejecutable al sistema de archivos android para ejecutarlo. Y en el extremo móvil, puede adb shell a él, el uso directo de iptables comando como un usuario root, al igual que en linux hacer.

adjunto archivo:

#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); } 
  1. Iptables está disponible en la distribución de fuentes de Android. Sin embargo, esa versión sólo funciona con dispositivos construidos con el kernel 2.6.29 de Linux.
  2. Los usuarios de dispositivos Android minoristas no pueden acceder a iptables binario. Incluso el sistema operativo Android no puede acceder a ese binario. Esto es difícil de codificar en Android. Muchos dispositivos tampoco tienen iptables en absoluto.
  3. La única forma de acceder a iptables binario es construir tus propias imágenes de Android. Echa un vistazo a http://randomizedsort.blogspot.com/2010/08/building-android-and-linux-kernel-for.html . Una vez que se sienta cómodo con ese proceso, echa un vistazo a http://randomizedsort.blogspot.com/2011/03/porting-iptables-1410-to-android.html .

Buena suerte.

No creo que iptables esté disponible en la distribución normal de Android. En un teléfono con raíz, sin embargo, puede agregar un binario iptables cruzado.

El ejecutable "itables" está presente en la fuente de Android. El Kernel también debe apoyarlo. Aunque probablemente necesitarás privilegios de root en tu dispositivo para jugar con él.

Esta es una solución de 5 años (raíz obligatoria):

Pero a medida que Google Code se convirtiera en sólo lectura continuará funcionando normalmente hasta "al menos enero de 2016", significa que el próximo mes esta respuesta podría ser inútil.

Con un teléfono enraizado, intente usar busybox y terminal para ejecutar "iptables -L" para listar las tablas actuales. Descubrí que todo lo que tenía que hacer era arraigar mi teléfono y tenía Iptables en mi android de otra manera al por menor. Una vez que el dispositivo haya confirmado iptables, puede utilizar la línea de comandos a través de su aplicación para ajustar las tablas.

  • ¿Por qué la recepción de multidifusión no funciona en algunos dispositivos Android?
  • Cómo administrar la conexión ssl cuando el servicio de red cambia
  • Temas y contribuciones para Volley
  • ¿Qué causa "java.io.IOException: se restableció el flujo: CANCELAR" con okhttp y spdy?
  • Android: NAT Traversal?
  • ServerSocket no acepta en el emulador droid
  • Conecte el androide al LAN local vía el teléfono (sobre wifi O vía la conexión del USB)
  • GetAllNetworkInterfaces () lanza la excepción
  • Capturar el tráfico del teléfono móvil en wireshark
  • ¿Cómo obtener la dirección MAC de la interfaz de red WiFi?
  • Android: Restablecer programaticamente la señal de red de radio del teléfono
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.