#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <pcap.h>
#include <netinet/in.h>
#include <arpa/inet.h>
//This code generates an ICMP packet
struct ETHER_HDR{
unsigned char d_mac[6]; // destination MAC address
unsigned char s_mac[6]; // source MAC address
unsigned char typecode[2]; // type code
};
struct IP_HDR{
unsigned char ip_ver_ihl; // 4-bit IPv4 version
// 4-bit header length (in 32-bit words)
// normally=5 Means 20 Bytes may be 24
unsigned char ip_tos; // IP type of service
unsigned short ip_total_length; // Total length
unsigned short ip_id; // Unique identifier
unsigned short ip_flag_frag_off; // Flags & Fragment offset field
unsigned char ip_ttl; // Time to live
unsigned char ip_protocol; // Protocol(TCP,UDP etc)
unsigned short ip_checksum; // IP checksum
unsigned int ip_srcaddr; // Source address
unsigned int ip_destaddr; // Source address
};
void prep_ip_hdr(unsigned char* pkt,struct IP_HDR *iph);
void prep_ether_hdr(unsigned char* pkt,struct ETHER_HDR *eh);
int main()
{
pcap_if_t *alldevs;
pcap_if_t *d;
int i=0;
char errbuf[PCAP_ERRBUF_SIZE];
pcap_t * fp;
/* Retrieve the device list from the local machine */
if (pcap_findalldevs(&alldevs, errbuf) == -1)
{
fprintf(stderr,"Error in pcap_findalldevs_ex: %s\n", errbuf);
exit(1);
}
/* Print the list of devices */
for(d= alldevs; d != NULL; d= d->next)
{
printf("%d. %s", ++i, d->name);
if (d->description)
printf(" (%s)\n", d->description);
else
printf(" (No description available)\n");
}
if (i == 0)
{
printf("\nNo interfaces found! Run the file as admin or use sudo.\n");
return 0;
}
printf("Enter the interface number (1-%d):",i);
int inum; scanf("%d", &inum);
if(inum < 1 || inum > i)
{
printf("\nInterface number out of range.\n");
/* Free the device list */
pcap_freealldevs(alldevs);
return 0;
}
for (d=alldevs, i=0; i< inum-1 ;d=d->next, i++);
fp = pcap_open_live(d->name, 65536,1,1000,errbuf); //open the device to enable sending the packet
// The packet to be sent is made here
unsigned char packet[100];
struct ETHER_HDR *eh;
struct IP_HDR *iph;
eh = (struct ETHER_HDR*) (packet); //we point the eh pointer to the first index of the character array packet
eh->d_mac[0]=255;
eh->d_mac[1]=255;
eh->d_mac[2]=255;
eh->d_mac[3]=255;
eh->d_mac[4]=255;
eh->d_mac[5]=255;
eh->s_mac[0]=2;
eh->s_mac[1]=2;
eh->s_mac[2]=2;
eh->s_mac[3]=2;
eh->s_mac[4]=2;
eh->s_mac[5]=2;
eh->typecode[0] = 0x08; //so that the payload is interpreted as an IP protocol packet,this is the Type Code for IP
eh->typecode[1] = 0x00;
prep_ether_hdr(packet, eh);
iph = (struct IP_HDR*) (packet + sizeof(struct ETHER_HDR)); //we need to point the iph pointer just below the ethernet header
iph->ip_ver_ihl = 0x45;
iph->ip_tos = 0;
iph->ip_total_length = 100 - sizeof(struct ETHER_HDR);
iph->ip_id = 2;
iph->ip_flag_frag_off = htons(0x4000); // 010 0000000000000 = 0 1000 0000 // see definition of htons, if not used the byte order
//in the packet will be changed
// 0000 0000 = 0x4000
iph->ip_ttl = 3;
iph->ip_protocol = 0x01;
iph->ip_checksum = 0;
iph->ip_srcaddr = inet_addr("192.168.1.3"); // change IP as needed
iph->ip_destaddr = inet_addr("192.168.1.2");// change IP as needed
//prep_ip_hdr(packet, iph);
/* Send down the packet */
if (pcap_sendpacket(fp, packet, 100 /* size */) != 0) //send the packet that we just made, the last parameter size is important
{ //it actually tells how many bytes are to be put out on the wire
fprintf(stderr,"\nError sending the packet: \n", pcap_geterr(fp));
return 0;
}
/* We don't need any more the device list. Free it */
pcap_freealldevs(alldevs);
return 1;
}
void prep_ether_hdr(unsigned char *pkt,struct ETHER_HDR *eh)
{
memcpy((pkt), eh->d_mac,6);
memcpy((pkt+6), eh->s_mac,6);
memcpy((pkt+12), &(eh->typecode),2);
}
void prep_ip_hdr (u_char* pkt, struct IP_HDR* iph)
{
// COMPLETE THIS FUNCTION
}