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
25int
26main(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