1 /* 2 * Copyright 2008-2010, Haiku, Inc. All Rights Reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Yin Qiu 7 */ 8 9 10 #include <arpa/inet.h> 11 #include <errno.h> 12 #include <netinet/in.h> 13 #include <netinet/ip.h> 14 #include <netinet/ip_icmp.h> 15 #include <stdio.h> 16 #include <stdlib.h> 17 #include <string.h> 18 #include <sys/socket.h> 19 #include <unistd.h> 20 21 22 #define MAXLEN 4096 23 24 25 int 26 main(void) 27 { 28 int sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); 29 if (sockfd < 0) { 30 fprintf(stderr, "Could not open raw socket: %s\n", strerror(errno)); 31 return 1; 32 } 33 34 struct sockaddr_in source; 35 socklen_t addrLen = sizeof(source); 36 char buf[MAXLEN]; 37 ssize_t nbytes; 38 39 while ((nbytes = recvfrom(sockfd, buf, MAXLEN, 0, 40 (struct sockaddr*)&source, &addrLen)) > 0) { 41 int ipLen, icmpLen; 42 43 char host[128]; 44 if (!inet_ntop(AF_INET, &source.sin_addr, host, sizeof(host))) 45 strcpy(host, "<unknown host>"); 46 47 printf("Received %zd bytes of ICMP message from %s\n", nbytes, host); 48 49 struct ip* ip = (struct ip*)buf; 50 ipLen = ip->ip_hl << 2; 51 if ((icmpLen = nbytes - ipLen) < 8) { 52 fprintf(stderr, "ICMP len (%d) < 8\n", icmpLen); 53 exit(1); 54 } 55 struct icmp* icmp = (struct icmp*)(buf + ipLen); 56 printf("Type: %u; Code: %u\n", icmp->icmp_type, icmp->icmp_code); 57 } 58 59 return 0; 60 } 61