Thread: segmentation fault while writing a packet to a pacp file

  1. #1
    Registered User
    Join Date
    May 2009
    Posts
    3

    Thumbs down segmentation fault while writing a packet to a pacp file

    I have written a c program that reads a big tcpdump file and outputs packets of individual TCP connection from start to end into a seperate file. Each of these are pcap files. I have done most part of programming but somewhere i am getting segmentation fault with free() function with a pointer. I tried gdb to debug it but in vein, here goes my program


    Code:
    #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>
    
    
    /* default snap length (maximum bytes per packet to capture) */
    #define SNAP_LEN 65535
    
    /* ethernet headers are always exactly 14 bytes [1] */
    #define SIZE_ETHERNET 14
    
    /* Ethernet addresses are 6 bytes */
    #define ETHER_ADDR_LEN	6
    
    /* Ethernet header */
    struct sniff_ethernet {
            u_char  ether_dhost[ETHER_ADDR_LEN];    /* destination host address */
            u_char  ether_shost[ETHER_ADDR_LEN];    /* source host address */
            u_short ether_type;                     /* IP? ARP? RARP? etc */
    };
    
    /* IP header */
     struct sniff_ip {
              u_char  ip_vhl;                 /* version << 4 | header length >> 2 */
              u_char  ip_tos;                 /* type of service */
              u_short ip_len;                 /* total length */
              u_short ip_id;                  /* identification */
              u_short ip_off;                 /* fragment offset field */
              #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;                 /* time to live */
              u_char  ip_p;                   /* protocol */
              u_short ip_sum;                 /* checksum */
        struct  in_addr ip_src,ip_dst;  /* source and dest address */
    
          };
    
    struct sniff_icmp
    {
    	u_char icmp_type;
    	u_char icmp_code;
    	u_short icmp_checksum;
    };
    #define IP_HL(ip)               (((ip)->ip_vhl) & 0x0f)
    #define IP_V(ip)                (((ip)->ip_vhl) >> 4)
    #define IP_Flag(ip)                (((ip)->ip_off) & 0xD0)
    #define IP_off(ip)                (((ip)->ip_off) & 0x1F)
    /* TCP header */
    typedef u_int tcp_seq;
    
    struct sniff_tcp {
            u_short th_sport;               /* source port */
            u_short th_dport;               /* destination port */
            tcp_seq th_seq;                 /* sequence number */
            tcp_seq th_ack;                 /* acknowledgement number */
           // tcp_seq th_syn;
           // tcp_seq th_fin;
            //tcp_seq th_urg;
            u_char  th_offx2;               /* data offset, rsvd */
    	#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;                 /* window */
            u_short th_sum;                 /* checksum */
            u_short th_urp;                 /* urgent pointer */
    };
    struct sniff_udp {
            u_short udp_sport;               /* source port */
            u_short udp_dport;               /* destination port */
            u_short udp_hlen;		/* Udp header length*/
            u_short udp_chksum;		/* Udp Checksum */
    	};
    
    char ADDRESS_PAIR[100];char PAIR_ADDRESS[100];
    char TCP_ACTIVE_ONE[10000][100];
    char TCP_ACTIVE_TWO[10000][100];
    pcap_t * temp[10000];
    char UDP_ACTIVE[100][100];
    char SOURCE_IP[20];
    char DEST_IP[20];
    unsigned short SOURCE_PORT;
    unsigned short DEST_PORT;
    char buf[5];
    char str[32]; 
    int counter =1;
    char dummy[32];
    //char count_connections[10000];
    int tcp_active_count=0;
    int connet_count[10000];
    int num_count=0;
    pcap_dumper_t * pc[10000];
    int pcount;
    int closing_connection;
    int flag[10000];
    char file_prefix[6] = ".pcap";
    char filename[10];
    char active_filenames[10000][10];
    void got_packet(const struct pcap_pkthdr *header, const u_char *packet, pcap_t * p);
    char* convert_tostring( unsigned short val);
    char* convert_tostring1( void);
    
    
    FILE* outfile;
    
    void got_packet(const struct pcap_pkthdr *header, const u_char *packet, pcap_t * p)
    {
    	const struct sniff_ethernet *ethernet;  /* The ethernet header [1] */
    	const struct sniff_ip *ip;              /* The IP header */
    	const struct sniff_tcp *tcp;            /* The TCP header */
    //	const char *payload;                    /* Packet payload */
    	struct sniff_udp *udp;            /* The Udp header */
    	struct sniff_icmp *icmp;			/* The ICMP header*/
    	int size_ip;
    	int size_tcp;
    	int size_payload;
    	int size_udp;
    	
    		/* define ethernet header */
    	ethernet = (struct sniff_ethernet*)(packet);
    	printf("\npacket number  %d",num_count++);
    	/* define/compute ip header offset */
    	ip = (struct sniff_ip*)(packet + SIZE_ETHERNET);
    	//printf("\nip header starts at %d",ip);
        // printf("\ni m here %d",IP_HL(ip));
    	size_ip = IP_HL(ip)*4;
    	/*if (size_ip < 20) {
    		printf("   * Invalid IP header length: %u bytes\n", size_ip);
    		
    	}*/
    	/* print source and destination IP addresses */
    	//printf("source address %s \n", inet_ntoa(ip->ip_src));
    	//printf("dest address %s \n", inet_ntoa(ip->ip_dst));
    	//printf("dest IP  starts at %d",ip->ip_src);
    	strcpy(SOURCE_IP , inet_ntoa(ip->ip_src));
    	strcpy(DEST_IP ,inet_ntoa(ip->ip_dst));
    	//printf("\n%d\n",ip->ip_p);
    	switch(ip->ip_p) 
    	{
    				case 6: //printf("i m here %d",size_ip);
    					   tcp = (struct sniff_tcp*)(packet + SIZE_ETHERNET + size_ip);
    					  // printf("\n %d\n",(packet ));
    					  // printf("\n %d\n",(packet + SIZE_ETHERNET + size_ip));
    					   size_tcp = TH_OFF(tcp)*4;
    						if (size_tcp < 20)
    						 {
    							printf("   * Invalid TCP header length: %u bytes\n", size_tcp);
    							return;
    						}
    					   SOURCE_PORT = ntohs(tcp->th_sport);
    					  // printf("source port is %d\n",ntohs(tcp->th_sport));
    					   DEST_PORT = ntohs(tcp->th_dport);
    					  // printf("dest port is %d\n",ntohs(tcp->th_dport));
    					   ADDRESS_PAIR[0] ='\0';PAIR_ADDRESS[0]='\0';
    					  // printf("the sequence no is %u\n",tcp->th_seq);
    					   strcpy(ADDRESS_PAIR,SOURCE_IP);
    					   strcat(ADDRESS_PAIR,DEST_IP);
    					   strcpy(PAIR_ADDRESS,DEST_IP);
    					   strcat(PAIR_ADDRESS,SOURCE_IP);
    					   convert_tostring(SOURCE_PORT);
    					   strcat(ADDRESS_PAIR,str);
    					   convert_tostring(DEST_PORT);
    					   strcat(ADDRESS_PAIR,str);
    					   strcat(PAIR_ADDRESS,str);
    					   convert_tostring(SOURCE_PORT);
    					   strcat(PAIR_ADDRESS,str);
    					  // printf("the address line for this packet is %s\n",ADDRESS_PAIR);
    					  // printf("the address line for this packet is %s\n",PAIR_ADDRESS);
    					   if(((tcp->th_flags)&TH_SYN) == 2 )
    					   {
    							//printf("i m here 0");
    							int i;
    							for(i=0;i<=tcp_active_count;i++)
    					  		 {
    								if( strcmp(TCP_ACTIVE_ONE[i],ADDRESS_PAIR)==0 |strcmp(TCP_ACTIVE_ONE[i],PAIR_ADDRESS)==0 |strcmp(TCP_ACTIVE_TWO[i],ADDRESS_PAIR)==0 | strcmp(TCP_ACTIVE_TWO[i],PAIR_ADDRESS)==0 )
    								{
    										printf("i m here 1");
    										char c = getchar();
    										printf("\ni am printing this packet to %s", active_filenames[i]); 
    										pcap_dump(( u_char*)pc[i],	header, packet);//connet_count[i]++;	
    										return;
    								}
    										
    					   		 }
    							
    							//temp[tcp_active_count] = pcap_open(filename);
    							//printf("after the dead");
    							flag[tcp_active_count]=0;
    							filename[0]='\0';
    							convert_tostring1();
    							strcpy(filename, dummy);
    							//printf("\n dummy %s",dummy);
    							strcat(filename, file_prefix);
    							//printf("\n\n the filename is %s\n\n", filename);
    							strcpy(active_filenames[tcp_active_count],filename);
    							if ((pc[tcp_active_count] = pcap_dump_open( p,active_filenames[tcp_active_count])) == NULL)
    							{
                    	               	 printf("Error opening savefile  for writing: \n");
                    					 exit(7);
          						}
    							//printf("\ni am printing this packet to %s", active_filenames[tcp_active_count]); 
    							//printf("after the dump open");
    							//pc = pcap_dump_open(temp[tcp_active_count], "outfile.tcpdump");
    							pcap_dump(( u_char*)pc[tcp_active_count],	header, packet);
    							char c = getchar();	
    							//connet_count[tcp_active_count]++;	
    							/*if ((pcount = pcap_dispatch(temp[tcp_active_count], 1, &pcap_dump, (char *)pc)) < 0) 
    							{
                    	                	printf("Error reading packets from interface ");
                    					exit(8);
    							}*/
    							//printf("after the dumping a packet");						
    							//exit(10);
    							strcpy(TCP_ACTIVE_ONE[tcp_active_count],ADDRESS_PAIR);
    							strcpy(TCP_ACTIVE_TWO[tcp_active_count],PAIR_ADDRESS);
    							tcp_active_count++;
    							//printf("\n%s",TCP_ACTIVE_ONE[tcp_active_count-1]);
    							//printf("\n%s",TCP_ACTIVE_TWO[tcp_active_count-1]);
    							printf("it is a SYN packet");
    							//pcap_dump_close(pc);
    								//	exit(0); 
    							return;
    							
    					   }
    					   
    					   int i;
    					   for(i=0;i<tcp_active_count;i++)
    					   {
    								if( strcmp(TCP_ACTIVE_ONE[i],ADDRESS_PAIR)==0 |strcmp(TCP_ACTIVE_ONE[i],PAIR_ADDRESS)==0 |strcmp(TCP_ACTIVE_TWO[i],ADDRESS_PAIR)==0 | strcmp(TCP_ACTIVE_TWO[i],PAIR_ADDRESS)==0 )
    								{	//printf("\n i found a match for this packet %s and %s",ADDRESS_PAIR,PAIR_ADDRESS );
    									// printf("\ni am printing this packet to %s", active_filenames[i]); 
    					  				 pcap_dump(( u_char*)pc[i],	header, packet); //connet_count[i]++;
    									// printf("\n connect count %d",connet_count[i]);	
    								}
    								
    					   }
    				
    					   if(((tcp->th_flags)&TH_FIN) == 1 |((tcp->th_flags)&TH_RST) == 4 )
    					   {
    							if(((tcp->th_flags)&TH_FIN) == 1 )
    							{ printf("\n closing since it is a FIN packet");}
    							else if(((tcp->th_flags)&TH_RST) == 1 )
    							{ printf("\n closing since it is a RST packet");}
    							int i=0;
    							for(i=0;i<tcp_active_count;i++)
    							{
    								if(strcmp(TCP_ACTIVE_ONE[i],ADDRESS_PAIR)==0 |strcmp(TCP_ACTIVE_TWO[i],ADDRESS_PAIR)==0 )
    								{	
    									printf("\n i am in if part");
    									if(flag[i] ==0)
    									{
    										 flag[i]=1;
    									}
    									else if(flag[i] ==1)
    									{
    										flag[i] =2;closing_connection =i;
    									}
    									/*int j;
    									for(j=i;j<=tcp_active_count;j++)
    									{
    										strcpy(TCP_ACTIVE_ONE[j], TCP_ACTIVE_ONE[j+1]);
    									}*/
    								}
    								else if(strcmp(TCP_ACTIVE_TWO[i],PAIR_ADDRESS)==0 |strcmp(TCP_ACTIVE_TWO[i],ADDRESS_PAIR)==0)
    								{
    									int j;
    									if(flag[i] ==0)
    									{
    										 flag[i]=1;
    									}
    									else if(flag[i] ==1)
    									{
    										flag[i] =2;closing_connection=i;
    									}
    									printf("\n i am in else if part");
    									/*for(j=i;j<=tcp_active_count;j++)
    									{
    										strcpy(TCP_ACTIVE_TWO[j],TCP_ACTIVE_TWO[j+1]);
    									}*/
    									
    								}
    							}
    							for(i=0;i<tcp_active_count;i++)
    							{
    								if(flag[i] == 2)
    								{
    									printf("connection ending here");	
    									printf("total number of packets in this connection %d  ", i);
    									pcap_dump_close(pc[i]);int j;
    									for(j=i;j<=tcp_active_count;j++)
    									{
    										strcpy(TCP_ACTIVE_TWO[j],TCP_ACTIVE_TWO[j+1]);
    										strcpy(TCP_ACTIVE_ONE[j],TCP_ACTIVE_ONE[j+1]);
    										flag[j]=flag[j+1];
    										strcpy(active_filenames[j],active_filenames[j+1]);
    									}
    									tcp_active_count--;
    									//exit(0);	
    								}
    							}
    							for(i=0;i<tcp_active_count;i++)
    							{
    								
    									printf("connection with file %d is active %s",i, active_filenames[i]);
    								
    							}
    					   }
    					   
    					   break;
    		/*case IPPROTO_UDP: udp = (struct sniff_udp*)(packet + SIZE_ETHERNET + size_ip);
    					   SOURCE_PORT = udp->th_sport;
    					   DEST_PORT = udp->th_dport;
    					   break;	*/
    		default: break;
    	}
    	
    }
    char* convert_tostring( unsigned short val)
    {
    char revertedstr[32];
    int length=0;
    
    	while (val > 0)
    	{
     	 int a = val % 10;
     	 revertedstr[length++] = a | '0';
     	 val /= 10;pcap_t * p;
    	}
    
    	length--;
    	int rev = 0;
    	while (length >= 0)
    	{
     	 str[rev++] = revertedstr[length--];
    	}
    
    	str[rev] = '\0';
    
    	return str;
    }
    
    char* convert_tostring1( void)
    {
    char revertedstr[32];
    int val = counter;
    int length=0;
    
    	while (val > 0)
    	{
     	 int a = val % 10;
     	 revertedstr[length++] = a | '0';
     	 val /= 10;pcap_t * p;
    	}
    
    	length--;
    	int rev = 0;
    	while (length >= 0)
    	{
     	 dummy[rev++] = revertedstr[length--];
    	}
    
    	dummy[rev] = '\0';
    	counter++;
    	return dummy;
    }
    
    int main(int argc, char **argv)
    {	long int num_packets=0;
    	struct pcap_pkthdr h;
    	char filename[] = "/home/neminath/Desktop/1.tcpdump";
    	FILE *file ;
          file= fopen(filename,"r");
    	char *ebuf;
    	pcap_t * p = pcap_fopen_offline(file, ebuf);
    	const u_char *packet;
        while((packet = pcap_next(p, &h ))!=NULL)
    	{
    		got_packet(&h, packet, p);
    	}
    	if(packet == NULL)
    	{
    		printf("error");
    	}
    	
    	//num_packets = pcap_dispatch(p, num_packets, got_packet, NULL);
    	return 0;
    }


    can anybody help me

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    I have done most part of programming but somewhere i am getting segmentation fault with free() function with a pointer.
    You don't actually call free anywhere in your program.


    Quzah.
    Hope is the first step on the road to disappointment.

  3. #3
    Registered User
    Join Date
    May 2009
    Posts
    3
    i dont call explicitly but its internally through a library function

    this is how my gdb trace back look like

    #0 0xb7e28dec in free () from /lib/tls/i686/cmov/libc.so.6
    #1 0xb7e21c73 in _IO_free_backup_area () from /lib/tls/i686/cmov/libc.so.6
    #2 0xb7e1fd04 in _IO_file_overflow () from /lib/tls/i686/cmov/libc.so.6
    #3 0xb7e1f263 in _IO_file_xsputn () from /lib/tls/i686/cmov/libc.so.6
    #4 0xb7e15ccf in fwrite () from /lib/tls/i686/cmov/libc.so.6
    #5 0xb7f11ea6 in pcap_dump () from /usr/lib/libpcap.so.0.8
    #6 0x08048d24 in got_packet ()
    #7 0x080492b6 in main ()

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Sounds like you are calling pcap_dump() with bad parameters somewhere. You may want to add -g to your compile line (and the link line!) so that you get some more debug information in the executable and be able to see lines of code when you walk back up the stack (using the "up" command in gdb). That should at least get you to the line that goes wrong, even if it's not telling you exactly that on that line is actually wrong.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #5
    Registered User
    Join Date
    May 2009
    Posts
    3
    Thank u

    i found the answer

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Trouble writing to file using fwrite()
    By yougene in forum C Programming
    Replies: 4
    Last Post: 12-30-2008, 05:13 PM
  2. fscanf causes a SEGMENTATION FAULT
    By yougene in forum C Programming
    Replies: 15
    Last Post: 12-29-2008, 12:11 AM
  3. Formatting the contents of a text file
    By dagorsul in forum C++ Programming
    Replies: 2
    Last Post: 04-29-2008, 12:36 PM
  4. Encryption program
    By zeiffelz in forum C Programming
    Replies: 1
    Last Post: 06-15-2005, 03:39 AM
  5. Locating A Segmentation Fault
    By Stack Overflow in forum C Programming
    Replies: 12
    Last Post: 12-14-2004, 01:33 PM

Tags for this Thread