1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
|
int ping(char *AdresseAPinger)
{
char *Paquet; // Paquet que l'on enverra : le ping
char *Buffer; // Buffer de reception contenant la réponse
struct icmp *HeaderICMP; // Header contenant les paramètre IPs encapsulant l'header ICMP
struct ip *HeaderIP; // Header contenant les paramètres ICMP : ECHO_REQUEST etc...
struct sockaddr_in stMachineAPinger;
struct sockaddr_in stMachineQuiPing;
int Result = 0;
int Longueur = 0;
int Socket = 0;
int OptVal = 0;
// Allocation dynamique du paquet envoyé et du buffer de reception
Paquet = (char *)malloc(sizeof(struct icmp) + sizeof(struct ip));
Buffer = (char *)malloc(sizeof(struct icmp) + sizeof(struct ip));
// Association des headers dans le paquet que l'on enverra
HeaderIP = (struct ip *) Paquet;
HeaderICMP = (struct icmp *) (Paquet + sizeof(HeaderIP));
// Remplissage des structures qui gerent les machines : demandantes et répondantes
stMachineAPinger.sin_family = AF_INET;
stMachineAPinger.sin_addr.s_addr = inet_addr(AdresseAPinger);
stMachineQuiPing.sin_family = AF_INET;
stMachineQuiPing.sin_addr.s_addr = INADDR_ANY; // Adresse de la machine qui pingue
// Remplissage du header du protocole IP
rt_printk("Remplissage IP header...\n");
HeaderIP->ip_hl = 5; // Longueur de l'en-tête
HeaderIP->ip_v = 4; // IPv4
HeaderIP->ip_tos = 0; // Type de service
HeaderIP->ip_len = sizeof(HeaderIP) + sizeof(HeaderICMP);// Longueur total du paquet IP
HeaderIP->ip_id = htons(getuid()); // Identificateur
HeaderIP->ip_ttl = 255; // Temps de vie
HeaderIP->ip_src = stMachineQuiPing.sin_addr; // Adresse de la machine qui veut pinguer
HeaderIP->ip_dst = stMachineAPinger.sin_addr; // Adresse de la mahcine qui repondra... ou pas
// Ouverture du socket en mode RAW
rt_printk("Ouverture Socket...\n");
Socket = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
if(Socket == -1)
{
rt_printk("Ping : Erreur socket !!\n");
return -1;
}
// Changement des options du socket pour manipuler le datagramme IP
rt_printk("Changement options Socket...\n");
Result = setsockopt(Socket, IPPROTO_IP, IP_HDRINCL, &OptVal, sizeof(int));
if(Socket == -1)
{
rt_printk("Ping : Erreur setup socket !!\n");
return -1;
}
// Remplissage du header du protocole ICMP
rt_printk("Replissage ICMP header...\n");
HeaderICMP->icmp_type = ICMP_ECHO; // Type de message ICMP : Echo request
HeaderICMP->icmp_code = 0; // Code du message (0 pour nous)
HeaderICMP->icmp_cksum = 0;
// Calcul du checksum pour le datagramme ICMP
HeaderICMP->icmp_cksum = in_cksum((unsigned short *)HeaderICMP, sizeof(HeaderICMP));
// Calcul du checksum du datagramme IP précédent qui encapsule celui en ICMP
HeaderIP->ip_sum = in_cksum((unsigned short *)HeaderIP, sizeof(HeaderIP));
// Envois de la trame IP sur le reseau
rt_printk("Envois du ping...\n");
Result = sendto(Socket, Paquet, HeaderIP->ip_len, 0, (struct sockaddr*)&stMachineAPinger, sizeof(struct sockaddr));
if(Result != HeaderIP->ip_len)
{
rt_printk("Ping : Erreur envois -> longueur envoyee != longueur a envoyer");
return -1;
}
// Reception de la réponse... ou non
rt_printk("Reception du ping...");
Longueur = sizeof(struct sockaddr);
Result = recvfrom(Socket, Buffer, (sizeof(HeaderIP) + sizeof(HeaderICMP)), 0, (struct sockaddr*)&stMachineAPinger, &Longueur);
if(Result == HeaderIP->ip_len)
{
rt_printk("ok\n");
free(Paquet);
free(Buffer);
return 1; // Le ping c'est correctement passé, la machine distante à bien répondue
}
else
{
rt_printk("no\n");
free(Paquet);
free(Buffer);
return -1;
}
} |
Partager