xref: /haiku/src/tests/system/network/icmp/icmp_dumper.cpp (revision 02354704729d38c3b078c696adc1bbbd33cbcf72)
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