#include <stdlib.h>
#include <stdio.h>

#include <pcap.h>
#include <assert.h>

/* 4 bytes IP address */
typedef struct ip_address{
    u_char byte1;
    u_char byte2;
    u_char byte3;
    u_char byte4;
}ip_address;

typedef struct mac_address{
	u_char byte1;
    u_char byte2;
    u_char byte3;
	u_char byte4;
    u_char byte5;
    u_char byte6;
}mac_address;

/* IPv4 header */
typedef struct ip_header{
    u_char  ver_ihl;        // Version (4 bits) + Internet header length (4 bits)
    u_char  tos;            // Type of service 
    u_short tlen;           // Total length 
    u_short identification; // Identification
    u_short flags_fo;       // Flags (3 bits) + Fragment offset (13 bits)
    u_char  ttl;            // Time to live
    u_char  proto;          // Protocol
    u_short crc;            // Header checksum
    ip_address  saddr;      // Source address
    ip_address  daddr;      // Destination address
}ip_header;

/* UDP header*/
typedef struct udp_header{
    u_short sport;          // Source port
    u_short dport;          // Destination port
    u_short len;            // Datagram length
    u_short crc;            // Checksum
}udp_header;

//WLAN header with WEP
typedef struct wlan_header_wep{
	u_short fcontrol;		// Frame control
	u_short nav;			// Navigation allocation vector
	mac_address transmitt;	// MAC address transmitter
	mac_address source;		// MAC address sender
	mac_address recieve;	// MAC address reciever
	u_short scontrol;		// Sequence control
	mac_address destination;// MAC address destination
	u_int wep;				// WEP IV header
}wlan_header_wep;

//WLAN header without WEP
typedef struct wlan_header{
	u_short fcontrol;		// Frame control
	u_short nav;			// Navigation allocation vector
	mac_address transmitt;	// MAC address transmitter
	mac_address source;		// MAC address sender
	mac_address recieve;	// MAC address reciever
	u_short scontrol;		// Sequence control
	mac_address destination;// MAC address destination
}wlan_header;

//WLAN trailer with WEP
typedef struct wlan_trailer_wep{
	u_int wep;				// WEP trailer CRC
	u_int fcs;				// Frame control sequence
}wlan_trailer_wep;

//WLAN trailer without wep
typedef struct wlan_trailer{
	u_int fcs;				// Frame control sequence
}wlan_trailer;


void usage();

int main(void) {
    int pcounter=0;
	pcap_if_t *alldevs;
    pcap_if_t *d;
    int inum;
	pcap_t *fp;
    char error[PCAP_ERRBUF_SIZE];
	char errbuf[PCAP_ERRBUF_SIZE];
    u_char packet[105];
    int i=0;
	u_char MACSource[6];
	wlan_header *wh;
	ip_header *ih;
    udp_header *uh;
	wlan_trailer *wt;
    u_int ip_len;
	u_int wlan_len = sizeof(wlan_header);
	u_int end = sizeof(wlan_trailer);
    u_short sport,dport;

	// allocate space for the headers
	wh = (wlan_header *) malloc(sizeof(wlan_header));
	assert(wh);
	ih=(ip_header *) malloc(20);
	assert(ih);
	uh = (udp_header *) malloc(8);
	assert(uh);
	wt=(wlan_trailer *) malloc(sizeof(wlan_trailer));
	assert(wt);

	/* Retrieve the device list */
    if (pcap_findalldevs(&alldevs, errbuf) == -1)
    {
        fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);
        exit(1);
    }
    
    /* Print the list */
    for(d=alldevs; d; d=d->next)
    {        
        if (d->description)
            printf("%d (%s)\n",++i, d->description);
        else
            printf("%d. %s", ++i, d->name);
    }

    if(i==0)
    {
        printf("\nNo interfaces found! Make sure WinPcap is installed.\n");
        return -1;
    }
    
    printf("Enter the interface number (1-%d):",i);
    scanf("%d", &inum);
    
    if(inum < 1 || inum > i)
    {
        printf("\nInterface number out of range.\n");
        /* Free the device list */
        pcap_freealldevs(alldevs);
        return -1;
    }

	/* Jump to the selected adapter */
    for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++);
	MACSource[5] = 0x00;
	MACSource[4] = 0x90;
	MACSource[3] = 0x4B;
	MACSource[2] = 0xB2;
	MACSource[1] = 0x23;
	MACSource[0] = 0x50;

    /* Open the output adapter */
    if((fp = pcap_open_live(d->name, 100, 1, 1000, error) ) == NULL)
    {
        fprintf(stderr,"\nError opening adapter: %s\n", error);
        return 0;
    }

	//WLAN Header

	//Frame Control
	packet[pcounter++]=0x2D;
	packet[pcounter++]=0x00;

	//Duration/ID
	packet[pcounter++]=0x4F;
	packet[pcounter++]=0xFF;

	//MAC AP
	packet[pcounter++]=0x00;
	packet[pcounter++]=0x00;
	packet[pcounter++]=0x00;
	packet[pcounter++]=0x00;
	packet[pcounter++]=0x00;
	packet[pcounter++]=0x00;
	//MAC source
	packet[pcounter++] =MACSource[0];
	packet[pcounter++] =MACSource[1];
	packet[pcounter++] =MACSource[2];
	packet[pcounter++] =MACSource[3];
	packet[pcounter++] =MACSource[4];
	packet[pcounter++] =MACSource[5];
	//MAC reciever
	packet[pcounter++] =MACSource[0];
	packet[pcounter++] =MACSource[1];
	packet[pcounter++] =MACSource[2];
	packet[pcounter++] =MACSource[3];
	packet[pcounter++] =MACSource[4];
	packet[pcounter++] =MACSource[5];

	//Sequence Control
	packet[pcounter++] =0x00;
	packet[pcounter++] =0xBA;

	//Destination address
	packet[pcounter++] =MACSource[0];
	packet[pcounter++] =MACSource[1];
	packet[pcounter++] =MACSource[2];
	packet[pcounter++] =MACSource[3];
	packet[pcounter++] =MACSource[4];
	packet[pcounter++] =MACSource[5];
	

	//IP Header

	packet[pcounter++] =0x45;//Version+IP Header length
	packet[pcounter++] =0x00;	//ToS
	
	//total length
	packet[pcounter++] =0x00;
	packet[pcounter++] =0x48;

	//Fragments
	packet[pcounter++] =0x00;
	packet[pcounter++] =0x00;

	//TTL
	packet[pcounter++] =0x0A;
	//protocol
	packet[pcounter++] =0x11;	//UDP

	//Header Checksum
	packet[pcounter++] =0x00;
	packet[pcounter++] =0x00;

	//Source IP
	packet[pcounter++] =4;
	packet[pcounter++] =1;
	packet[pcounter++] =168;
	packet[pcounter++] =192;

	//Destination IP
	packet[pcounter++] =4;
	packet[pcounter++] =1;
	packet[pcounter++] =168;
	packet[pcounter++] =192;

	//UDP HEADER

	//Source Port
	packet[pcounter++] =0;
	packet[pcounter++] =1024;
	//Destination Port
	packet[pcounter++] =0;
	packet[pcounter++] =1024;
	//Length
	packet[pcounter++] =0;
	packet[pcounter++] =8+44;
	//Checksum
	packet[pcounter++] =0;
	packet[pcounter++] =0;



	//Data
	strcpy(&packet[pcounter],"The quick brown fox jumps over the lazy dog.");
	// Here might occure a buffer overflow
	pcounter+=44;

	//WLAN Trailer

	packet[pcounter++]=0;
	packet[pcounter++]=0;
	packet[pcounter++]=0;
	packet[pcounter++]=0;


        
//	for(i=0;i<100;i++)

		/* Send down the packet */
		pcap_sendpacket(fp,packet,pcounter);

    return 0;
}