#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netdb.h>
#include <netinet/in.h>
//#include <netinet/ip_icmp.h>
//#include <netinet/ip.h>



typedef struct iphdr
{
    unsigned char  verlen;
    unsigned char  tos;
    unsigned short tot_len;
    unsigned short id;
    unsigned short offset;
    unsigned char  ttl;
    unsigned char  protocol;
    unsigned short checksum;
    unsigned int   saddr;
    unsigned int   daddr;
} IP_HDR;

typedef struct icmphdr
{
	unsigned char  type;
	unsigned char  code;
	unsigned short checksum;
	unsigned short id;
	unsigned short seq;
	unsigned long  timestamp;
} ICMP_HDR;

unsigned short in_cksum (u_short *addr, int len)
{
  register int nleft = len;
  register u_short *w = addr;
  register int sum = 0;
  u_short answer = 0;

  while (nleft > 1)
  {
      sum += *w++;
      nleft -= 2;
  }

  if (nleft == 1)
  {
      *(u_char *) (&answer) = *(u_char *) w;
      sum += answer;
  }

  sum = (sum >> 16) + (sum & 0xffff);
  sum += (sum >> 16);
  answer = ~sum;

  return (answer);
}


int main() {
	int sock;
	int optval;
	char packet[8192];
	struct sockaddr_in sin;
	struct iphdr *ip;
	struct icmphdr *icmp;

	sock=socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
	setsockopt(sock, IPPROTO_IP, 2, (char *)&optval, sizeof(optval));

	ip=(struct iphdr*)packet;
	icmp=(struct icmphdr*)(packet+sizeof(struct iphdr));



	ip->verlen=4;
	ip->tos=0;
	ip->id=1;
	ip->offset=0;
	ip->ttl=255;
	ip->protocol=1;
	ip->saddr=inet_addr("127.0.0.1");//ME.
	ip->daddr=inet_addr("127.0.0.1");//DEST
	ip->checksum =0;
	ip->checksum=in_cksum((unsigned short *)ip, sizeof(struct iphdr));

	icmp->id=2;
	icmp->type=0;
	icmp->code=8;
	icmp->seq=0;
	icmp->checksum=0;
	icmp->checksum=in_cksum((unsigned short *)icmp, sizeof(struct icmphdr));
	ip->tot_len=htons(sizeof(struct iphdr)+sizeof(struct icmphdr));

	sin.sin_family=AF_INET;

	int i = 0;
	while(i < 15) {
	if((sendto(sock,packet,sizeof(struct iphdr)+sizeof(struct icmphdr),0,(struct sockaddr*)&sin,sizeof(sin))) == -1) { perror("sendto"); }
	i++;
	}
	close(sock);
}