0 votos

Estoy intentando hacer un socket raw para, entre otras cosas, simular un ping (ICMP echo request), entonces intenté escribir un simple código en c (JNI) con ndk porque no tenia idea de cómo hacerlo en java.

Pero el problema es que me tira un error cuando construye el socket porque intenta conectarse al puerto 1024 y necesita permisos. La pregunta sería cómo le doy permisos de root al código que escribí en c. El código en c sería algo como esto:

 

#define DEFAULT_INIT_PORT 1 /* puerto inicial del escaneo por defecto */
#define DEFAULT_END_PORT 1024 /* puerto final del escaneo por defecto  */
#define DEFAULT_ICMP_PORT 8765 /* puerto por defecto para mandar los paquetes ICMP */

 extern "C" {
     JNIEXPORT jstring JNICALL
         Java_com_exadddmple_pingconc_MainActivity_InvokeNativeFunction(JNIEnv * env, jobject obj);
 };

 JNIEXPORT jstring JNICALL
      Java_com_exadddmple_pingconc_MainActivity_InvokeNativeFunction(JNIEnv * env, jobject obj)

{
int sockfd,numbytes,flags,listen;
int init_port, end_port;
int result,fromlen;
struct hostent *he;
struct sockaddr_in their_addr;
static u_char paquete_salida[64];
register struct icmp *cabecera_icmp = (struct icmp *) paquete_salida;
fd_set fd_leer,fd_escribir;
struct timeval tv;
char recv_ICMP[512],shost[100];
struct servent *bar;
int i,val,len=sizeof(val);

init_port= DEFAULT_INIT_PORT;
end_port= DEFAULT_END_PORT;

if (setuid(0))
{
    return env->NewStringUTF(" ERROR setuid");

 }

if ((sockfd = socket(AF_INET, SOCK_RAW,1)) < 0)
{

    return env->NewStringUTF("Error socket");
    //exit(1);
}

if ((he= gethostbyname("www.google.com")) == NULL)
{
    return env->NewStringUTF("Error gethostbyname");
    //exit(1);
}

 

their_addr.sin_family = AF_INET; // host byte order
their_addr.sin_port = htons(DEFAULT_ICMP_PORT); /* network byte order */
their_addr.sin_addr = *((struct in_addr *)he->h_addr); // dirección IP
bzero(&(their_addr.sin_zero), 8);
sprintf(shost,"%d.%d.%d.%d",(unsigned char)he->h_addr_list[0][0],(unsigned char)he->h_addr_list[0][1],(unsigned char)he->h_addr_list[0][2],\
(unsigned char)he->h_addr_list[0][3]);

/* configuración cabecera mensaje ICMP */
cabecera_icmp->icmp_type = ICMP_ECHO; // Tipo de mensajes ICMP
cabecera_icmp->icmp_code = 0; // Código de mensaje ICMP
cabecera_icmp->icmp_cksum = 0; // Checksum del paquete ICMP
cabecera_icmp->icmp_seq =1; // Numero de secuencia
cabecera_icmp->icmp_id = 0x1111; // ID de paquete

if ((numbytes=sendto(sockfd, &paquete_salida, 64, 0, (struct sockaddr *)&their_addr, sizeof(struct sockaddr))) == -1)
{
    return env->NewStringUTF("Error sendto");
 }

do {
   FD_ZERO(&fd_leer); // pone a 0 todos los bits de fd_var.
   FD_SET(sockfd, &fd_leer); //activa en fd_leer el bit correspondiente al descriptor sockfd
   tv.tv_sec=2; // 2 segundos de tiempo de espera para recibir la respuesta al ICMP
   tv.tv_usec=0;
   result = select(sockfd +1, &fd_leer, NULL, NULL, &tv);
} while (result == -1 && errno == EINTR);

if (result > 0) {
   if (FD_ISSET(sockfd, &fd_leer)) {
      /* El socket tiene datos para leer */
      result = recvfrom(sockfd, recv_ICMP, sizeof recv_ICMP, 0, NULL, &fromlen);
      if (result == 0) {
         /* Conexión cerrada por el host */
    close(sockfd);

    return env->NewStringUTF("El host ha cerrado la conexión.");
  
      }
      else {
  close(sockfd);

  return env->NewStringUTF("El host está activo,procederemos a chequear los servicios...");

}

}

}
}

 

preguntado por roberto16 Dic 29, 2015 en Android

Por favor, ingresa o regístrate para responder a esta pregunta.