Random thoughts shooting out of volatile mind
Parsing the Captured Packets : Packet Sniffer
In my previous post I had mentioned about how to use pcap utilities for capturing packets. Now in this post I'm going to tell about how to parse the packet and get information from it. Before I explain the code there are few basic data structure that you need to know.
struct ether_header
This structure is located in netinet/if_ether.h. The main fields in this structure that we need are ether_shosht ether_dhost, these are used to extract the source and destination mac addresses. You need to declare  a pointer of type struct ether_header, you can assign packet by simply assigning the type casted pointer which points to the packet as shown below.
struct ether_header *eptr;
eptr = (struct ether_header *)packet; // packet is of type u_char *
I had a lot of trouble in extracting the mac address from the packet and storing it in the form x:x:x:x:x:x . I found my own crude way of doing it and was succeeded in it also. I did as follows.
i = ETHER_ADDR_LEN; // i = 6 bytes
ptr = ethernet_header->ether_shost;
do
{
sprintf(src_mac,"%s%x",(i == ETHER_ADDR_LEN)?" ":":",*ptr ++);
strcat(pktinfo->eth_src,src_mac);
}while(--i > 0);
The expression (i == ETHER_ADDR_LEN)?" ":":",*ptr ++) I got it from one of the references from tcpdump.org. But they were simply printing the value on to screen and I want to store them into variable. I tried using sprintf to copy value into the variable directly from the expression. But each time the value was getting replaced by new value so what I did was to concatenate the value entered into the variable by sprintf into a new variable. After the loop finishes execution 2nd variable contains the mac address in the form x:x:x:x:x:x.
Below is the code for the function I used to parse the ethernet header of the packet I captured.

void Parse_Etherenet_Header(struct pkt_info *pktinfo,const struct pcap_pkthdr pkthdr,const u_char *packet)
{
char src_mac[50],dest_mac[50];
struct ether_header *ethernet_header;
int i;
u_char *ptr;

src_mac[0] = dest_mac[0] = '\0';
/* Initialise the Time stamp */
strcpy(pktinfo -> tm_stmp,(char *)ctime((const time_t*)&pkthdr.ts.tv_sec));
pktinfo->tm_stmp[strlen(pktinfo->tm_stmp) - 1] = '\0';
ethernet_header = (struct ether_header *)packet;
/* Extract the Source Mac Address */
i = ETHER_ADDR_LEN; // i = 6 bytes
ptr = ethernet_header->ether_shost;
do
{
sprintf(src_mac,"%s%x",(i == ETHER_ADDR_LEN)?" ":":",*ptr ++);
strcat(pktinfo->eth_src,src_mac);
}while(--i > 0);
/* Extract the Destination Mac Address */
i = ETHER_ADDR_LEN;
ptr = ethernet_header->ether_dhost;
do
{
sprintf(dest_mac,"%s%x",(i == ETHER_ADDR_LEN)?" ":":",*ptr ++);
strcat(pktinfo->eth_dest,dest_mac);
}while(--i > 0);

}
If you folks find out any mistake in the code above or if you have better way to implement the above function do comment. :)
In my next post I'll discuss about parsing the rest of the packet that is IP, TCP/UDP portions. 
Posted by: copyninja on Sunday, 26 April 2009

blog comments powered by Disqus
Fork me on GitHub