Hacer Ping en codigo C y que cree un txt con los resultados de cada IP

Iniciado por rubia28, 17 Noviembre 2020, 17:05 PM

0 Miembros y 1 Visitante están viendo este tema.

ThunderCls

Cita de: rubia28 en 18 Noviembre 2020, 11:39 AM
Buenos días,

Lo primero de todo, darte las gracias por tu ayuda, por más que busco y pruebo no soy capaz de dar con lo que se me pide..
He probado a añadir en el código lo que me indicas y me da error en la línea 9, está claro que es porque estoy haciendo algo mal, pero no consigo ver que es lo que está sin inicializar como me indica el programa.

Primero que todo, como te ha comentado Alberto, depender de llamadas al sistema (system) no es recomendable por varios motivos, uno de ellos es por la poca portabilidad que te brinda. La solucion mas "limpia" es implementar la peticion ICMP por ti misma, de esta forma te evitas dependencias y el codigo es mas portable. Sin embargo, implementar tu propia funcion ping no es una tarea trivial. Necesitas trabajar con raw sockets, DNS lookups y hacer toda la manipulacion del paquete ICMP por ti misma. Estamos hablando que necesitas tener conocimientos avanzados de sockets y nociones basicas de networking y/o del paquete ICMP, ademas de un conocimiento avanzado de C para poder implemetarlo todo. Una posible implementacion la puedes ver aqui:

https://www.geeksforgeeks.org/ping-in-c/amp/

En este caso, y dado tu nivel de C en estos momentos, yo diria que todo esto va muy por encima de ti. Si es algo que quieres aprender puedes empezar con todo lo que he comentado antes y crearte una version mejorada mas adelante, pero si por ahora necesitas el trabajo hecho, la opcion mas viable es depender de la utilidad del sistema, al menos es mi opinion.
En este caso si decides continuar usando la utilidad "ping", te vuelvo a comentar que lo mejor es el uso de la funcion "popen()" (pipes) en lugar de "system()" para manipular el resultado de la ejecucion del "ping" evitando el uso de ficheros

Referente a tu codigo, el uso de:

while (!feof(f))
    printf("%c", getc(f));


y

while (fgets(ip, MAX_IP_LEN, f))

deberian ser excluyentes, no debes usar ambos en este caso. Una posible variante a lo que tienes, usando popen() podria ser lo siguiente:

#include <stdio.h>
#include <stdlib.h>
#define MAX_IP_LEN 40
#define MAX_COMMAND_LEN 100
#define MAX_LINE_LEN 255
#define println() printf("\n")

void leerArchivo(const char *archivo);
void arrancarPing(const char *ip);

int main(void)
{
    char opcion;
    char archivo[MAX_LINE_LEN];

    printf("Seleccione la opción que desea realizar: \n\n"
        "a. Una función que lea el contenido de un archivo .txt con diferentes direcciones ip, en la que la ruta del archivo se solicitará al usuario por pantalla. La ruta y nombre del archivo tienen que ser preguntados al usuario y visualizados por pantalla. Por último, el programa debe lanzar un ping para cada una de las direcciones ip del archivo e informar cuales de ellas responden correctamente a este comando."
        "b. Sin desarrollar.\n\n"
        "c. Sin desarrollar.\n\n"
        "d. Salir del programa. \n\n");
    scanf("%c", &opcion);

    while (opcion != 'a' && opcion != 'A' && opcion != 'b' && opcion != 'B' && opcion != 'c' && opcion != 'C' && opcion != 'd' && opcion != 'D')
    {
        printf("Opción incorrecta, eliga una de las opciones disponibles. (a,b,c o d).\n");
        fflush(stdin);
        scanf("%c", &opcion);
    }

    switch (opcion)
    {
        case 'a':
        case 'A':
            printf("\n Introduce la ruta del archivo a leer: \n");
            println();
            scanf("%s", archivo);
            println();
            leerArchivo(archivo);
            break;
        case 'b':
        case 'B':
            printf("Prueba de funcionamiento opcion B\n");
            break;
        case 'c':
        case 'C':
            printf("Prueba de funcionamiento opcion C\n");
            break;
        case 'd':
        case 'D':
            break;
    }

    return 0;
}

void leerArchivo(const char *archivo)
{
    FILE * f;
    char ip[MAX_IP_LEN] = { 0 };

    f = fopen(archivo, "rt");
    if (f == NULL)
    {
        printf("Problemas de apertura del archivo\n");
    }
    else
    {
        while (fgets(ip, MAX_IP_LEN, f))
        {
            arrancarPing(ip);
        }

        fclose(f);
    }
}

void arrancarPing(const char *ip)
{
    char line[MAX_LINE_LEN] = { 0 };
    char command[MAX_COMMAND_LEN] = { 0 };
    FILE * fp;

    snprintf(command, MAX_COMMAND_LEN, "ping %s", ip);
    fp = popen(command, "r");
    if (fp == NULL)
    {
        /*Handle error */
        return;
    }

    while (fgets(line, MAX_LINE_LEN, fp) != NULL)
    {
        /*Execution output */
        /*Verifica aqui la respuesta del host */
        printf("%s", line);
    }

    pclose(fp);
}
-[ "...I can only show you the door. You're the one that has to walk through it." – Morpheus (The Matrix) ]-
http://reversec0de.wordpress.com
https://github.com/ThunderCls/

rubia28

Muchísimas gracias por la ayuda!

He estado probando el código y cumple con la funcionalidad! :)
Estudiaré ahora como puedo hacer para que informe cuando el ping es correcto y cuando la respuesta no es válida y lo muestre con un mensaje de este tipo en lugar de hacer el ping completo en pantalla (seguiré buscando más info), ya que como dices mi nivel en C ahora mismo para lo que se me pide se queda pequeño y hay muchas cosas que escapan a mis conocimientos...


PING INCORRECTO
No contesta 21.0.21.2
ping 21.0.21.2 > ping.txt

PING CORRECTO
Contesta 21.0.21.2
ping 27.3.22.18 > ping.txt


Nuevamente mil gracias por la ayuda, me ha sido de gran utilidad y sobre todo he podido aprender con lo que me habéis dicho y como realizar cierto tipo de funciones. Cruzo dedos para poder seguir con el desarrollo y poder obtener este tipo de avisos en la lectura por pantalla.

Saludos.