LQ Newbie
Registered: Oct 2005
Posts: 28
Rep:
|
problem with storing packets in a queue
hi,
This code is for capturing some packets and storing them in aqueue. Then retriving them one by one from the queue and decoding them.
This is my code .The problem is when inserting the packets into a buffer the last packet is overwritten in all the locations. Can anybody check the problem.
In header.h i have defined the various structures needed.
#include "pcap.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "header.h"
struct q *front1,*rear1;
// Function declarations
//void delbuff(struct q *front1);
void delbuff();
void DecodeIP(u_int8_t * pkt, const u_char *cap_pac,struct Packet * p);
void DecodeTCP(u_int8_t *pkt,int size_ip ,const u_char *cap_pac, struct Packet *p);
void DecodeUDP(u_int8_t *pkt,int size_ip, const u_char *cap_pac,struct Packet *p);
void DecodeICMP(u_int8_t * pkt, const u_char *cap_pac,struct Packet * p);
void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet);
void print_payload(const u_char *payload, int len);
void print_hex_ascii_line(const u_char *payload, int len, int offset);
// PRINTING THE HEX VALUE IN ASCII FORMAT
void print_hex_ascii_line(const u_char *payload, int len, int offset)
{
int i;
int gap;
const u_char *ch;
printf("%05d ", offset);
ch = payload;
for(i = 0; i < len; i++) {
printf("%02x ", *ch);
ch++;
if (i == 7)
printf(" ");
}
if (len < 8)
printf(" ");
if (len < 16) {
gap = 16 - len;
for (i = 0; i < gap; i++) {
printf(" ");
}
}
printf(" ");
ch = payload;
for(i = 0; i < len; i++) {
if (isprint(*ch))
printf("%c", *ch);
else
printf(".");
ch++;
}
printf("\n");
return;
}
// PRINTING PAYLOAD
void print_payload(const u_char *payload, int len)
{
int len_rem = len;
int line_width = 16;
int line_len;
int offset = 0;
const u_char *ch = payload;
if (len <= 0)
return;
if (len <= line_width)
{
print_hex_ascii_line(ch, len, offset);
return;
}
else
{
for ( ;; )
{
line_len = line_width % len_rem;
print_hex_ascii_line(ch, line_len, offset);
len_rem = len_rem - line_len;
ch = ch + line_len;
offset = offset + line_width;
if (len_rem <= line_width)
{
print_hex_ascii_line(ch, len_rem, offset);
break;
}
}
}
return;
}
// Decoding ICMP packet
void DecodeICMP(u_int8_t * pkt,const u_char *cap_pac, struct Packet * p)
{
const struct sniff_icmp *icmp;
struct Packet *castpac;
icmp=NULL;
castpac=NULL;
castpac=p;
//p->icmph=(struct sniff_icmp*)pkt;
icmp=(struct sniff_icmp*)p;
//printf("\nThe icmp type is %s",*(p->icmph->type));
}
// Decoding TCP packet
void DecodeTCP(u_int8_t *pkt,int size_ip ,const u_char *cap_pac, struct Packet *p)
{
const struct sniff_tcp *tcp;
struct Packet *castpac;
int size_tcp;
const char *payload;
int size_payload;
tcp=NULL;
castpac=NULL;
castpac=p;
tcp=(struct sniff_tcp*)(cap_pac + SIZE_ETHERNET +IP_HEADER_LEN);
//p->tcph=(struct sniff_tcp*)pkt;
size_tcp = TH_OFF(tcp)*4;
if (size_tcp < 20)
{
printf(" * Invalid TCP header length: %u bytes\n", size_tcp);
return;
}
printf("\n\n Transport layer :\n\n");
printf(" Src port: %d\n", ntohs(tcp->th_sport));
printf(" Dst port: %d\n", ntohs(tcp->th_dport));
payload = (u_char *)(cap_pac + SIZE_ETHERNET + IP_HEADER_LEN + TCP_HEADER_LEN);
size_payload = ntohs(size_ip) - (IP_HEADER_LEN + size_tcp);
if (size_payload > 0)
{
printf(" Payload (%d bytes):\n", size_payload);
print_payload(payload, size_payload);
}
}
// Decoding UDP packet
void DecodeUDP(u_int8_t *pkt,int size_ip,const u_char *cap_pac, struct Packet *p)
{
const struct sniff_udp *udp;
struct Packet *castpac;
int size_udp;
const char *payload;
int size_payload;
udp=NULL;
castpac=NULL;
castpac=p;
//p->udph=(struct sniff_udp*)pkt;
udp=(struct sniff_udp*)(cap_pac + SIZE_ETHERNET + IP_HEADER_LEN);
printf("\n\n Transport layer :\n\n");
printf(" Src port: %d\n", ntohs(udp->sport));
printf(" Dst port: %d\n", ntohs(udp->dport));
printf(" Len : %d \n",ntohs(udp->len));
//payload = (u_char *)(cap_pac + SIZE_ETHERNET + size_ip + ntohs(udp->len));
payload=(u_char *)(cap_pac + SIZE_ETHERNET + IP_HEADER_LEN + UDP_HEADER_LEN);
size_payload=ntohs(size_ip) - 8;
if (size_payload > 0)
{
printf( "\n\n Payload (%d bytes):\n",size_payload);
print_payload(payload,size_payload);
}
//printf("\n****************************************************************************************** **********************************************************************\n");
}
//Decoding IP packet
void DecodeIP(u_int8_t * pkt, const u_char *cap_pac,struct Packet * p)
{
const struct sniff_ip *ip;
struct Packet *castpac;
int size_ip;
ip=NULL;
castpac=NULL;
// p->iph=(struct sniff_ip*)cap_pac;
ip=(struct sniff_ip*)(cap_pac+SIZE_ETHERNET);
castpac=p;
//ip=(struct sniff_ip*)p;
//ip=p->iph;
printf("\n \nNetwork Layer :\n\n");
printf("\tFrom: %s\n", inet_ntoa(ip->ip_src));
printf("\tTo: %s\n", inet_ntoa(ip->ip_dst));
size_ip = IP_HL(ip)*4;
if (size_ip < 20)
{
printf(" * Invalid IP header length: %u bytes\n", size_ip);
return;
}
printf("\t Ip version header length: %x\n",ip->ip_vhl);
printf("\t Ip Type of Service: %x\n",ip->ip_tos);
printf("\t Ip datagram length: %d\n",ip->ip_len);
printf("\t Ip Identifier: %d\n",ip->ip_id);
printf("\t fragment offset: %d\n",ip->ip_off);
printf("\t Time to Live: %d\n",ip->ip_ttl);
switch(ip->ip_p)
{
case IPPROTO_TCP:
printf("\t Protocol: TCP\n");
DecodeTCP(castpac->pkt + SIZE_ETHERNET + size_ip,ip->ip_len,cap_pac,castpac);
break;
case IPPROTO_UDP:
printf("\t Protocol: UDP\n");
DecodeUDP(castpac->pkt + SIZE_ETHERNET+size_ip,ip->ip_len,cap_pac,castpac);
break;
/*case IPPROTO_ICMP:
printf("\t Protocol: ICMP\n");
DecodeICMP(castpac->pkt + SIZE_ETHERNET + size_ip,castpac);
break;*/
default:
printf("\n \t No further Decoding is provided");
break;
}
}
//Inserting the packet into the FIFO buffer
void insert_buffer(u_char *dumpfil, const struct pcap_pkthdr *header, const u_char *packet)
{
static int count = 1;
struct q *ptr1;
int size_ip,i;
//ptr1=NULL;
ptr1=malloc(sizeof(struct q));
ptr1->data=packet;
ptr1->no=count;
ptr1->next=NULL;
//If buffer is empty make this packet as the front and rear of the FIFO buffer
pcap_dump(dumpfil, header, packet);
if(front1 == NULL)
{
printf("\n Executing IF part");
front1 = rear1= ptr1;
}
// If packets are already present make this packet as the rear of the FIFO buffer
else
{
printf("\n Executing ELSE part");
rear1->next=ptr1;
rear1=ptr1;
}
printf("\nPacket number %d:\n", count);
count++;
if(count==3)
{
for(i=1;i<=count;i++)
{
delbuff();
}
}
}
//Taking packets from the buffer and Displaying Layer 2 information
void delbuff()
{
const u_char *cap_pac;
struct Packet *castpac;
struct q *ptr;
const struct sniff_ethernet *ethernet;
cap_pac=NULL;
castpac=NULL;
ethernet=NULL;
ptr=front1;
if(ptr==NULL)
{
printf("\nQUEUE EMPTY");
return;
}
cap_pac=ptr->data;
printf("\n packet no:%d",ptr->no);
castpac=(struct Packet*)(cap_pac);
ethernet=(struct sniff_ethernet*)(cap_pac);
front1=ptr->next;
free(ptr);
ptr=front1;
// Display datalink layer information
printf("\n \nDataLink Layer :\n\n");
printf("\tEthernet destination Address :%x\n",ethernet->ether_dhost);
printf("\tEthernet source Address :%x\n",ethernet->ether_shost);
printf("\tEthernet Type :%d\n",ethernet->ether_type);
// printf("\n%x",ntohs(castpac->eh->ether_type));
//Determining the network layer protocol
switch(ntohs(ethernet->ether_type))
{
case ETHERNET_TYPE_IP:
DecodeIP(castpac->pkt+SIZE_ETHERNET,cap_pac,castpac);
break;
default:
printf("\n No further decoding is provided");
break;
}
}
// MAIN MODULE
int main(int argc, char **argv)
{
char *dev = NULL;
char errbuf[PCAP_ERRBUF_SIZE];
char *fname;
pcap_t *handle;
bpf_u_int32 mask;
bpf_u_int32 net;
struct pcap_pkthdr *h;
const u_char *sp;
struct pcap_pkthdr hdr;
pcap_dumper_t *dumpfile;
int num_packets = 2;
front1=NULL;
rear1=NULL;
fname="dump";
// Search for an interface from which to capture the packet
dev = pcap_lookupdev(errbuf);
if (dev == NULL)
{
fprintf(stderr, "Couldn't find default device: %s\n",errbuf);
exit(EXIT_FAILURE);
}
if (pcap_lookupnet(dev, &net, &mask, errbuf) == -1)
{
fprintf(stderr, "Couldn't get netmask for device %s: %s\n",dev, errbuf);
net = 0;
mask = 0;
}
printf("Device: %s\n", dev);
printf("Number of packets: %d\n", num_packets);
//Open the interface in promiscuous mode for capturing packets
handle = pcap_open_live(dev, SNAP_LEN, 1, 1000, errbuf);
if (handle == NULL)
{
fprintf(stderr, "Couldn't open device %s: %s\n", dev, errbuf);
exit(EXIT_FAILURE);
}
// Capturing the packets and inserting them into a buffer
dumpfile=pcap_dump_open(handle,fname);
pcap_loop(handle, num_packets, insert_buffer, (unsigned char *)dumpfile);
pcap_close(handle);
printf("\nCapture complete.\n");
return 0;
}
// header.h
#include "pcap.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define APP_NAME "sniffex"
// MAXIMUM NO OF BYTES TO BE CAPTURED
#define SNAP_LEN 1518
// SIZE OF ETHERNET HEADER
#define SIZE_ETHERNET 14
// SIZE OF ETHERNET ADDRESS
#define ETHER_ADDR_LEN 6
// MAXIMUM BUFFER SIZE
#define MAXBUFF 5
// ETHERNET TYPES
#define ETHERNET_MTU 1500
#define ETHERNET_TYPE_IP 0x0800
#define ETHERNET_TYPE_ARP 0x0806
#define ETHERNET_TYPE_REVARP 0x8035
#define ETHERNET_TYPE_EAPOL 0x888e
#define ETHERNET_TYPE_IPV6 0x86dd
#define ETHERNET_TYPE_IPX 0x8137
#define ETHERNET_TYPE_PPPoE_DISC 0x8863 /* discovery stage */
#define ETHERNET_TYPE_PPPoE_SESS 0x8864 /* session stage */
#define ETHERNET_TYPE_8021Q 0x8100
#define ETHERNET_TYPE_LOOP 0x9000
// HEADER LENGTHS
#define IP_HEADER_LEN 20
#define TCP_HEADER_LEN 20
#define UDP_HEADER_LEN 8
#define ICMP_HEADER_LEN 4
// ETHERNET HEADER
struct sniff_ethernet {
u_char ether_dhost[ETHER_ADDR_LEN];
u_char ether_shost[ETHER_ADDR_LEN];
u_short ether_type;
};
// IP HEADER
struct sniff_ip {
u_char ip_vhl;
u_char ip_tos;
u_short ip_len;
u_short ip_id;
u_short ip_off;
#define IP_RF 0x8000 /* reserved fragment flag */
#define IP_DF 0x4000 /* dont fragment flag */
#define IP_MF 0x2000 /* more fragments flag */
#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
u_char ip_ttl;
u_char ip_p;
u_short ip_sum;
struct in_addr ip_src,ip_dst;
};
#define IP_HL(ip) (((ip)->ip_vhl) & 0x0f)
#define IP_V(ip) (((ip)->ip_vhl) >> 4)
// TCP HEADER
typedef u_int tcp_seq;
struct sniff_tcp {
u_short th_sport;
u_short th_dport;
tcp_seq th_seq;
tcp_seq th_ack;
u_char th_offx2;
#define TH_OFF(th) (((th)->th_offx2 & 0xf0) >> 4)
u_char th_flags;
#define TH_FIN 0x01
#define TH_SYN 0x02
#define TH_RST 0x04
#define TH_PUSH 0x08
#define TH_ACK 0x10
#define TH_URG 0x20
#define TH_ECE 0x40
#define TH_CWR 0x80
#define TH_FLAGS (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECE|TH_CWR)
u_short th_win;
u_short th_sum;
u_short th_urp;
};
// UDP HEADER
struct sniff_udp{
u_short sport;
u_short dport;
u_short len;
u_short crc;
};
// ICMP HEADER
struct sniff_icmp{
u_int8_t type;
u_int8_t code;
u_int16_t csum;
union
{
u_int8_t pptr;
struct in_addr gwaddr;
struct idseq
{
u_int16_t id;
u_int16_t seq;
} idseq;
int sih_void;
struct pmtu
{
u_int16_t ipm_void;
u_int16_t nextmtu;
} pmtu;
struct rtradv
{
u_int8_t num_addrs;
u_int8_t wpa;
u_int16_t lifetime;
} rtradv;
} icmp_hun;
#define s_icmp_pptr icmp_hun.pptr
#define s_icmp_gwaddr icmp_hun.gwaddr
#define s_icmp_id icmp_hun.idseq.id
#define s_icmp_seq icmp_hun.idseq.seq
#define s_icmp_void icmp_hun.sih_void
#define s_icmp_pmvoid icmp_hun.pmtu.ipm_void
#define s_icmp_nextmtu icmp_hun.pmtu.nextmtu
#define s_icmp_num_addrs icmp_hun.rtradv.num_addrs
#define s_icmp_wpa icmp_hun.rtradv.wpa
#define s_icmp_lifetime icmp_hun.rtradv.lifetime
union
{
/* timestamp */
struct ts
{
u_int32_t otime;
u_int32_t rtime;
u_int32_t ttime;
} ts;
/* IP header for unreach */
struct ih_ip
{
struct sniff_ip *ip;
/* options and then 64 bits of data */
}ip;
struct ra_addr
{
u_int32_t addr;
u_int32_t preference;
} radv;
u_int32_t mask;
char data[1];
} icmp_dun;
#define s_icmp_otime icmp_dun.ts.otime
#define s_icmp_rtime icmp_dun.ts.rtime
#define s_icmp_ttime icmp_dun.ts.ttime
#define s_icmp_ip icmp_dun.ih_ip
#define s_icmp_radv icmp_dun.radv
#define s_icmp_mask icmp_dun.mask
#define s_icmp_data icmp_dun.data
};
//ARP HEADER
struct ARPHdr
{
u_int16_t ar_hrd; /* format of hardware address */
u_int16_t ar_pro; /* format of protocol address */
u_int8_t ar_hln; /* length of hardware address */
u_int8_t ar_pln; /* length of protocol address */
u_int16_t ar_op; /* ARP opcode (command) */
};
typedef struct _EtherARP
{
struct ARPHdr ea_hdr; /* fixed-size header */
u_int8_t arp_sha[6]; /* sender hardware address */
u_int8_t arp_spa[4]; /* sender protocol address */
u_int8_t arp_tha[6]; /* target hardware address */
u_int8_t arp_tpa[4]; /* target protocol address */
} EtherARP;
// RAW DATA ( PACKET)
struct Packet{
struct pcap_pkthdr *pkth; /* BPF data */
u_int8_t *pkt; /* base pointer to the raw packet data */
// Fddi_hdr *fddihdr; /* FDDI support headers */
// Fddi_llc_saps *fddisaps;
// Fddi_llc_sna *fddisna;
// Fddi_llc_iparp *fddiiparp;
// Fddi_llc_other *fddiother;
// Trh_hdr *trh; /* Token Ring support headers */
// Trh_llc *trhllc;
// Trh_mr *trhmr;
// SLLHdr *sllh; /* Linux cooked sockets header */
// PflogHdr *pfh; /* OpenBSD pflog interface header */
// OldPflogHdr *opfh; /* Old OpenBSD pflog interface header */
struct sniff_ethernet *eh; /* standard TCP/IP/Ethernet/ARP headers */
// VlanTagHdr *vh;
// EthLlc *ehllc;
// EthLlcOther *ehllcother;
// WifiHdr *wifih; /* wireless LAN header */
EtherARP *ah;
// EtherEapol *eplh; /* 802.1x EAPOL header */
// EAPHdr *eaph;
// u_int8_t *eaptype;
// EapolKey *eapolk;
// PPPoEHdr *pppoeh; /* Encapsulated PPP of Ether header */
struct sniff_ip *iph, *orig_iph; /* and orig. headers for ICMP_*_UNREACH family */
u_int32_t ip_options_len;
u_int8_t *ip_options_data;
struct sniff_tcp *tcph, *orig_tcph;
u_int32_t tcp_options_len;
u_int8_t *tcp_options_data;
struct sniff_udp *udph, *orig_udph;
struct sniff_icmp *icmph, *orig_icmph;
u_int8_t *data; /* packet payload pointer */
u_int16_t dsize; /* packet payload size */
// u_int16_t alt_dsize; /* the dsize of a packet before munging (used for log)*/
// u_int16_t actual_ip_len;/* for logging truncated packets (usually by a small snaplen) */
u_int8_t frag_flag; /* flag to indicate a fragmented packet */
u_int16_t frag_offset; /* fragment offset number */
u_int8_t mf; /* more fragments flag */
u_int8_t df; /* don't fragment flag */
u_int8_t rf; /* IP reserved bit */
u_int16_t sp; /* source port (TCP/UDP) */
u_int16_t dp; /* dest port (TCP/UDP) */
u_int16_t orig_sp; /* source port (TCP/UDP) of original datagram */
u_int16_t orig_dp; /* dest port (TCP/UDP) of original datagram */
u_int32_t caplen;
u_int8_t uri_count; /* number of URIs in this packet */
void *ssnptr; /* for tcp session tracking info... */
void *fragtracker; /* for ip fragmentation tracking info... */
void *flow; /* for flow info */
void *streamptr; /* for tcp pkt dump */
//Options ip_options[IP_OPTMAX]; /* ip options decode structure */
// u_int32_t ip_option_count; /* number of options in this packet */
// u_char ip_lastopt_bad; /* flag to indicate that option decoding was halted due to a bad option */
// Options tcp_options[TCP_OPTLENMAX]; /* tcp options decode struct */
// u_int32_t tcp_option_count;
// u_char tcp_lastopt_bad; /* flag to indicate that option decoding was halted due to a bad option */
// u_int8_t csum_flags; /* checksum flags */
// u_int32_t packet_flags; /* special flags for the packet */
// u_int32_t bytes_to_inspect; /* Number of bytes to check against rules */
// int preprocessors; /* flags for preprocessors to check */
};
/*
struct node
{
struct Packet *pkt;
struct node *link;
} ;
*/
//const u_char *packet
struct q
{
const u_char *data;
int no;
struct q *next;
};
thanks and regards
cynthia thomas
|