Los saltos rastrean ttl reciveform en ios

Estoy tratando de implementar traceroute simple para iOS. Todo parece funcionar bien, excepto que de alguna manera, cuando ejecuto mi aplicación en el simulador o en el dispositivo, encuentra solo unos pocos (6-7) primeros enrutadores en path cuando el traceroute de CLI encuentra los 14 enrutadores.

const char *c="www.gmail.com"; struct hostent *host_entry = gethostbyname(c); char *ip_addr; ip_addr = inet_ntoa(*((struct in_addr *)host_entry->h_addr_list[0])); struct sockaddr_in destination,fromAddr; int recv_sock; int send_sock; //Creting Sockets/// if ((recv_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP)) < 0) //using UDP socket. { NSLog(@"Could not cretae recv_sock.\n"); } if((send_sock = socket(AF_INET , SOCK_DGRAM,0))<0){ NSLog(@"Could not cretae send_sock.\n"); } memset(&destination, 0, sizeof(destination)); destination.sin_family = AF_INET; destination.sin_addr.s_addr = inet_addr(ip_addr); destination.sin_port = htons(80); struct timeval tv; tv.tv_sec = 0; tv.tv_usec = 10000; setsockopt(recv_sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv,sizeof(struct timeval)); char *cmsg = "GET / HTTP/1.1\r\n\r\n"; int max_ttl=20; int num_attempts=5; socklen_t n= sizeof(fromAddr); char buf[100]; for(int ttl=1;ttl<=max_ttl;ttl++) { memset(&fromAddr, 0, sizeof(fromAddr)); if(setsockopt(send_sock, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl))<0) NSLog(@"error in setsockopt\n"); for (int try=0; try<num_attempts; try++){ if (sendto(send_sock,cmsg,sizeof(cmsg),0,(struct sockaddr *) &destination,sizeof(destination)) != sizeof(cmsg) ) NSLog (@"error in send to...\n@"); int res = 0; if( (res = recvfrom(recv_sock, buf, 100, 0, (struct sockaddr *)&fromAddr,&n))<0) { NSLog(@"an error: %s; recvfrom returned %d\n", strerror(errno), res); }else { char display[16]={0}; inet_ntop(AF_INET, &fromAddr.sin_addr.s_addr, display, sizeof (display)); NSLog(@"Received packet from%s for TTL=%d\n",display,ttl); break; } } } 

He intentado vincular el socket de envío pero tengo los mismos resultados y no puedo usar Sock_raw en iOS. Traté de ejecutarlo en mi Mac y obtuve los mismos resultados. El error que obtengo es "Recurso no disponible temporalmente"; para el recvfrom() . ¿Porqué es eso? ¿Cómo puedo arreglarlo?

El error de EAGAIN (produciendo "Recurso no disponible temporalmente") podría incrementarse por el time de espera del zócalo receptor.

Dado que configuró solo 10000 microsegundos como time de espera de lectura (eso es muy breve en mi humilde opinión) con esta línea …

 struct timeval tv; tv.tv_sec = 0; tv.tv_usec = 10000; setsockopt(recv_sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv,sizeof(struct timeval)); 

… es posible que cuanto más largo sea el path (me refiero a la cantidad de enrutadores que tiene que pasar), más posibilidades hay de que incurran en esta situación.

Intente boost el valor de time de espera y háganos saber si mejoró.

EDITAR

Probé el código fuente bajo Linux y noté dos types de problemas.

  • Como se mencionó anteriormente: time de espera
  • Problema con el puerto 80

Acabo de boost el time de espera y usé un puerto diferente de 80 (en mi caso envié un post de udp al puerto de 40000) y recuperé todos los saltos como el command traceroute .

No estoy seguro de por qué ocurre este comportamiento. Quizás algún tipo de "posible alarma maliciosa de packages" sea ​​activado por el enrutador que lo descarta

EDICION ADICIONAL

Mira este enlace: man traceroute

En la sección Lista de methods disponibles , puede encontrar muchas maneras de lograr lo que necesita. Su método es similar al pnetworkingeterminado, indicando:

Los packages de sondeos son datagtwigs udp con puertos de destino llamados "poco probables". El puerto "improbable" de la primera sonda es 33434, luego para cada próxima sonda se incrementa en uno. Dado que se espera que los puertos no se usen, el host de destino normalmente devuelve "icmp unreach port" como respuesta final. ( Nadie sabe qué sucede cuando alguna aplicación escucha estos puertos, sin embargo ).

Por lo tanto, si necesita emular completamente el comportamiento del traceroute común de Linux, debe boost el puerto de destino en 1, cada vez que aumente el TTL (o cada vez que no pueda get una respuesta en mi humilde opinión)

QUIZÁ, a veces su command no funciona en ciertos puertos porque el enrutador está escuchando el último (como lo sugiere el manual de Linux y subrayado en negrita por mí).