- struct hostent *h;
- struct sockaddr_in pingaddr;
- struct icmp *pkt;
- int pingsock, c;
- char packet[DEFDATALEN + MAXIPLEN + MAXICMPLEN];
-
- if ((pingsock = socket(AF_INET, SOCK_RAW, 1)) < 0) { /* 1 == ICMP */
- perror("ping");
- exit(1);
- }
-
- /* drop root privs if running setuid */
- setuid(getuid());
-
- memset(&pingaddr, 0, sizeof(struct sockaddr_in));
- pingaddr.sin_family = AF_INET;
- if (!(h = gethostbyname(host))) {
- fprintf(stderr, "ping: unknown host %s\n", host);
- exit(1);
- }
- memcpy(&pingaddr.sin_addr, h->h_addr, sizeof(pingaddr.sin_addr));
- hostname = h->h_name;
-
- pkt = (struct icmp *)packet;
- memset(pkt, 0, sizeof(packet));
- pkt->icmp_type = ICMP_ECHO;
- pkt->icmp_cksum = in_cksum((unsigned short *)pkt, sizeof(packet));
-
- c = sendto(pingsock, packet, sizeof(packet), 0,
- (struct sockaddr *)&pingaddr, sizeof(struct sockaddr_in));
-
- if (c < 0 || c != sizeof(packet)) {
- if (c < 0) perror("ping");
- fprintf(stderr, "ping: write incomplete\n");
- exit(1);
- }
-
- signal(SIGALRM, noresp);
- alarm(5); /* give the host 5000ms to respond */
- /* listen for replies */
- while (1) {
- struct sockaddr_in from;
- size_t fromlen = sizeof(from);
-
- if ((c = recvfrom(pingsock, packet, sizeof(packet), 0,
- (struct sockaddr *)&from, &fromlen)) < 0) {
- if (errno == EINTR) continue;
- perror("ping");
- continue;
+ struct hostent *h;
+ struct sockaddr_in pingaddr;
+ struct icmp *pkt;
+ int pingsock, c;
+ char packet[DEFDATALEN + MAXIPLEN + MAXICMPLEN];
+
+ if ((pingsock = socket(AF_INET, SOCK_RAW, 1)) < 0) /* 1 == ICMP */
+ perror_msg_and_die("creating a raw socket");
+
+ /* drop root privs if running setuid */
+ setuid(getuid());
+
+ memset(&pingaddr, 0, sizeof(struct sockaddr_in));
+
+ pingaddr.sin_family = AF_INET;
+ if (!(h = gethostbyname(host))) {
+ error_msg("unknown host %s", host);
+ exit(1);
+ }
+ memcpy(&pingaddr.sin_addr, h->h_addr, sizeof(pingaddr.sin_addr));
+ hostname = h->h_name;
+
+ pkt = (struct icmp *) packet;
+ memset(pkt, 0, sizeof(packet));
+ pkt->icmp_type = ICMP_ECHO;
+ pkt->icmp_cksum = in_cksum((unsigned short *) pkt, sizeof(packet));
+
+ c = sendto(pingsock, packet, sizeof(packet), 0,
+ (struct sockaddr *) &pingaddr, sizeof(struct sockaddr_in));
+
+ if (c < 0 || c != sizeof(packet))
+ perror_msg_and_die("sendto");
+
+ signal(SIGALRM, noresp);
+ alarm(5); /* give the host 5000ms to respond */
+ /* listen for replies */
+ while (1) {
+ struct sockaddr_in from;
+ size_t fromlen = sizeof(from);
+
+ if ((c = recvfrom(pingsock, packet, sizeof(packet), 0,
+ (struct sockaddr *) &from, &fromlen)) < 0) {
+ if (errno == EINTR)
+ continue;
+ perror_msg("recvfrom");
+ continue;
+ }
+ if (c >= 76) { /* ip + icmp */
+ struct iphdr *iphdr = (struct iphdr *) packet;
+
+ pkt = (struct icmp *) (packet + (iphdr->ihl << 2)); /* skip ip hdr */
+ if (pkt->icmp_type == ICMP_ECHOREPLY)
+ break;
+ }