Il ya cette question que j'ai rencontrée, comment pouvons-nous trouver l'adresse IP du message de réponse ICMP dans GNU/Linux?Comment enregistrer chaque message de réponse ICMP
Répondre
Regardez dans libpcap - c'est une bibliothèque très efficace pour le reniflage de réseau, qui vous permet de capturer exactement le type de paquets que vous spécifiez (éventuellement filtré davantage par l'adresse source/destination, etc.). Vous pouvez ensuite analyser le paquet et extraire les adresses IP source et de destination. La page liée a une documentation et plusieurs tutoriels. Notez que vous devez faire la capture sur un ordinateur à travers lequel le trafic passe (source, destination ou n'importe quoi entre) comme dans les réseaux Ethernet modernes (connectés avec des commutateurs), vous ne voyez normalement pas tout le réseau circulation. See this Q&A de Wireshark (qui est essentiellement une interface graphique à libpcap) pour les solutions de contournement possibles.
Vous pouvez essayer IPTables logging.
Vous pouvez certainement ouvrir un socket avec
socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)
Et connectez-vous l'adresse source des paquets arrivant. Vous aurez besoin de connaître la structure d'un datagramme ICMP pour que cela fonctionne. Voir l'homme 7 premières
Ceci est une simple boucle (C Linux) pour intercepter toutes les demandes/réponse ICMP:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main(int argc, char **argv)
{
int sock;
int optval;
int ret;
int addrlen;
struct sockaddr_in sIn;
char *buffer;
char *sAddr;
char *dAddr;
int proto;
int type;
buffer = malloc(sizeof(char) * 32);
sAddr = malloc(sizeof(char) * 16);
dAddr = malloc(sizeof(char) * 16);
if ((sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) != -1) {
setsockopt(sock, IPPROTO_IP, IP_HDRINCL, &optval, sizeof(int));
sIn.sin_family = AF_INET;
sIn.sin_addr.s_addr = INADDR_ANY;
addrlen = sizeof(sIn);
memset(buffer, 0, 32);
while ((ret = recvfrom(sock, buffer, 31, 0, (struct sockaddr *)&sIn, &addrlen)) != -1) {
if (ret > 20) {
proto = (unsigned char)buffer[9];
type = (unsigned char)buffer[20];
if (proto == 1 && (type == 8 || type == 0)) {
memset(sAddr, 0, 16);
memset(dAddr, 0, 16);
sprintf(sAddr, "%d.%d.%d.%d",
(unsigned char)buffer[12],
(unsigned char)buffer[13],
(unsigned char)buffer[14],
(unsigned char)buffer[15]);
sprintf(dAddr, "%d.%d.%d.%d",
(unsigned char)buffer[16],
(unsigned char)buffer[17],
(unsigned char)buffer[18],
(unsigned char)buffer[19]);
if (type == 8)
fprintf(stdout, "-> ICMP REQUEST FROM %s TO %s\n", sAddr, dAddr);
else
fprintf(stdout, "<- ICMP REPLY FROM %s TO %s\n", sAddr, dAddr);
}
}
memset(buffer, 0, 32);
}
close(sock);
}
free(buffer);
free(sAddr);
free(dAddr);
return 0;
}
jouissions)
je dois parfois comprendre l'adresse IP externe d'un dispositif embarqué un routeur domestique derrière un NAT majeur. En général, seuls ping et traceroute sont disponibles en tant qu'outils de diagnostic. Maintenant, avec ce code s'exécutant sur un serveur distant, je peux en peu de temps voir quelle adresse IP est la source de la requête ICMP. Merci beaucoup! –