This will send an ICMP ping over network and wait for response.
#include <stdlib.h> #include <stdio.h> #include <string.h> #include <unistd.h> #include <stdint.h> #include <sys/socket.h> #include <linux/ip.h> #include <linux/icmp.h> #include <arpa/inet.h> #define PROTOCOL (IPPROTO_ICMP) #define ADDRESS "172.17.57.112" uint16_t chksum16(void* addr, int len) { register int sum = 0; uint16_t answer = 0; register uint16_t* w = (uint16_t*)addr; register int nleft = len; while (nleft > 1) { sum += *w++; nleft -= 2; } if (nleft == 1) { *(uint8_t *) (&answer) = *(uint8_t *) w; sum += answer; } sum = (sum >> 16) + (sum & 0xffff); sum += (sum >> 16); answer = ~sum; return (answer); } struct Packet { iphdr ip; icmphdr icmp; }; int main() { Packet outBuff; memset(&outBuff, 0, sizeof(Packet)); outBuff.ip.ihl = 5; outBuff.ip.version = 4; outBuff.ip.tot_len = sizeof(Packet); outBuff.ip.id = htons(getuid()); outBuff.ip.ttl = 255; outBuff.ip.protocol = PROTOCOL; outBuff.ip.saddr = inet_addr("172.17.57.112"); outBuff.ip.daddr = inet_addr(ADDRESS); outBuff.ip.check = chksum16(&outBuff.ip, sizeof(iphdr)); outBuff.icmp.type = ICMP_ECHO; outBuff.icmp.checksum = chksum16(&outBuff.icmp, sizeof(icmphdr)); struct sockaddr_in peer; peer.sin_family = AF_INET; peer.sin_addr.s_addr = inet_addr(ADDRESS); int sock = socket(AF_INET, SOCK_RAW, PROTOCOL); int optval; if (sock != -1 && setsockopt(sock, IPPROTO_IP, IP_HDRINCL, &optval, sizeof(int)) != -1) { if (sendto(sock, &outBuff, sizeof(Packet), 0, (sockaddr *)&peer, sizeof(sockaddr)) != -1) { printf("Echo sent\n"); Packet inBuff; memset(&inBuff, 0, sizeof(Packet)); while (recv(sock, &inBuff, sizeof(Packet), 0) != -1) { if (chksum16((unsigned short *)&inBuff.ip, sizeof(iphdr)) == 0) { } else { printf("IP CRC error\n"); } if (chksum16((unsigned short *)&inBuff.icmp, sizeof(icmphdr)) == 0) { switch (inBuff.icmp.type) { case ICMP_ECHO: { printf("Echo received\n"); continue; } break; case ICMP_ECHOREPLY: { printf("Got reply\n"); } break; case ICMP_DEST_UNREACH: { printf("Destination unreachable\n"); } break; case ICMP_HOST_UNKNOWN: { printf("Host unknown\n"); } break; default: { printf("Type: %d\n", inBuff.icmp.type); } break; } } else { printf("ICMP CRC error\n"); } break; } } close(sock); } else { printf("Cannot open socket\n"); } return 0; }
Немає коментарів:
Дописати коментар