libpcap and analyzing tcpdumps.
Results 1 to 3 of 3

Thread: libpcap and analyzing tcpdumps.

  1. #1
    Senior Member
    Join Date
    May 2003
    Posts
    472

    libpcap and analyzing tcpdumps.

    We all need to analyze packet dumps one time or the other. Sometimes
    you dont find a tool to do the manipluations you are looking for. The
    one solution is those cases is to do it youself. Code your proggie to
    get the job done.
    Here is one demostartion program which takes tcpdump files and works
    on them. This code checks for fault checksums in the tcpdumps and
    fiexes them. This should serve as introductory text or say the first
    step towards working it out. It is an old code that was lying on my
    disk, just thought some1 may be intersted in it.

    Even though I have commented the code inline so that it is sufficient
    for the person who knows moderate c to understand it, here comes more
    for it.

    man pcap for more. Still missing something drop me a mail.
    ======================================================
    code follows
    ======================================================

    Code:
    /***************************************************************************
    *   CopyLeft                                                              *
    *       nulldevice83_at_ gmail                                            *
    *                                                                         *
    *   This program is free software; you can redistribute it and/or modify  *
    *   it under the terms of the GNU General Public License as published by  *
    *   the Free Software Foundation; either version 2 of the License, or     *
    *   (at your option) any later version.                                   *
    *                                                                         *
    *   This program is distributed in the hope that it will be useful,       *
    *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
    *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
    *   GNU General Public License for more details.                          *
    *                                                                         *
    *   You should have received a copy of the GNU General Public License     *
    *   along with this program; if not, write to the                         *
    *   Free Software Foundation, Inc.,                                       *
    *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
    ***************************************************************************/
    
    /***************************************************************************
    Compile :
           $gcc -lpcap -o fixchecks fix_tcpdump.c
    PREREQUISITIVE:
           libpcap installion
    ***************************************************************************/
    
    #include <pcap.h> /* Header File for libpcap */
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <netinet/in.h>
    #include <netinet/ip.h> /* IP Header Here */
    #include <netinet/tcp.h>/*TCP header*/
    #include <netinet/udp.h>/*UDP Header*/
    #include <net/ethernet.h>/*Etherenet Header*/
    #include <sys/types.h>
    
    #define IP  0x008
    
    int o_in, o_out, o_ver;
    static unsigned int fixed = 0;
    
    /* Usage opf the code*/
    void usage( char *proggie )
    {
     printf( "\nUsage: %s <options> [-v]", proggie );
     printf( "\n-i : Input File Name" );
     printf( "\n-o : Output File Name" );
     printf( "\n-v : verbose" );
     printf( "\n" );
     exit( 0 );
    }
    
    /* This routine calculates the checksums, generously taken from the
    net. Google helps*/
    u_short csum( unsigned short *ptr, int nbytes )
    {
     register long sum;
     u_short oddbyte;
     register u_short answer;
    
     sum = 0;
    
     while ( nbytes > 1 ) {
       sum += *ptr++;
       nbytes -= 2;
     }
    
     if ( nbytes == 1 ) {
       oddbyte = 0;
       *( ( u_char * ) & oddbyte ) = *( u_char * ) ptr;
       sum += oddbyte;
     }
    
     sum = ( sum >> 16 ) + ( sum & 0xffff );
     sum += ( sum >> 16 );
     answer = ~sum;
     return ( answer );
    }
    
    /* This routine gets the pointer to raw packet data and checks the
    checksum and fixes it, if required */
    check_and_fix( unsigned char * pkt )
    {
     struct ether_header * ether;
     struct iphdr *iph;
     struct tcphdr *tcph, *temp_tcph;
     struct udphdr *udph;
    
     /* Pseudo Header used for calculating checksums
           If this worries u read a good book on TCP/IP */
     struct pseudo_header {
       u_int32_t saddr;
       u_int32_t daddr;
       u_int8_t zero;
       u_int8_t proto;
       u_int16_t tcp_length;
     }
     pseudo_header;
    
     char *data;
     u_short new_check;
     unsigned char *dump_pkt;
     u_int32_t tcphdr_and_data_size, udphdr_and_data_size;
     static unsigned int i;
     char *options_ptr;
    
     tcphdr_and_data_size = new_check = udphdr_and_data_size = 0;
     i++;
     ether = ( struct ether_header * ) pkt; /*Ether now points to the
    ethernet header in pkt*/
     /* Check if this is an IP packet, if not we wont do anything to it*/
     if ( ether->ether_type != IP ) {
       if ( o_ver ) {
         printf( "Packet ID :%u :Is not an IP packet. Skipping...\n", i );
       }
       return ;
     }
    
     if ( o_ver ) {
       printf( "Processing Packet ID :%u\n", i );
     }
    
     iph = ( struct iphdr * ) ( pkt + 14 ); /*iph points to IP header*/
    
     /* If a TCP packet*/
     if ( iph->protocol == IPPROTO_TCP ) {
       if ( o_ver ) {
         printf( "\tPacket is TCP packet\n" );
       }
    
       tcph = ( struct tcphdr * ) ( ( char * ) ( pkt + 14 ) + iph->ihl * 4 );
    
       tcphdr_and_data_size = ntohs( iph->tot_len ) - ( iph->ihl * 4 );
    
       dump_pkt = ( char * ) malloc( sizeof( struct pseudo_header ) +
    tcphdr_and_data_size );
       bzero( dump_pkt, sizeof( dump_pkt ) );
    
       pseudo_header.saddr = ( u_int32_t ) iph->saddr;
       pseudo_header.daddr = ( u_int32_t ) iph->daddr;
       pseudo_header.zero = ( u_int8_t ) 0;
       pseudo_header.proto = ( u_int8_t ) IPPROTO_TCP;
       pseudo_header.tcp_length = ( u_int16_t ) htons( tcphdr_and_data_size ) ;
    
       memcpy( dump_pkt, ( char * ) & pseudo_header, sizeof( struct
    pseudo_header ) );
    
       temp_tcph = ( struct tcphdr * ) ( dump_pkt + sizeof( struct
    pseudo_header ) );
       memcpy( temp_tcph, tcph, tcphdr_and_data_size );
       temp_tcph->check = 0x00;
    
       new_check = csum( ( unsigned short * ) dump_pkt, sizeof( struct
    pseudo_header ) + tcphdr_and_data_size );
    
       if ( new_check != tcph->check ) {
         printf( "\tInvalid Checksum : Present 0x%02X  Should Be :
    0x%02X..", ntohs( tcph->check ), ntohs( new_check ) );
         tcph->check = new_check;
         fixed ++;
       printf( "\tFixed\n" )
         ;
       } else {
         printf( "\t Checksum OK\n" );
       }
       free( dump_pkt );
     } else if ( iph->protocol == IPPROTO_UDP ) { /*IF PKT IS UDP PACKET */
       struct udphdr * temp_udph;
       if ( o_ver ) {
         printf( "\tPacket is UDP packet\n" );
       }
    
       udph = ( struct udphdr * ) ( ( char * ) iph + iph->ihl * 4 );
    
       udphdr_and_data_size = ntohs( iph->tot_len ) - ( iph->ihl * 4 );
    
       dump_pkt = ( char * ) malloc( sizeof( struct pseudo_header ) +
    udphdr_and_data_size );
       bzero( dump_pkt, sizeof( dump_pkt ) ); /* always zero fill */
    
       pseudo_header.saddr = ( u_int32_t ) iph->saddr;
       pseudo_header.daddr = ( u_int32_t ) iph->daddr;
       pseudo_header.zero = ( u_int8_t ) 0;
       pseudo_header.proto = ( u_int8_t ) IPPROTO_UDP;
       pseudo_header.tcp_length = ( u_int16_t ) htons( udphdr_and_data_size ) ;
    
       memcpy( dump_pkt, ( char * ) & pseudo_header, sizeof( struct
    pseudo_header ) );
    
       temp_udph = ( struct udphdr * ) ( dump_pkt + sizeof( struct
    pseudo_header ) );
       memcpy( temp_udph, udph, udphdr_and_data_size );
       temp_udph->check = 0x00;
    
       new_check = csum( ( unsigned short * ) dump_pkt, sizeof( struct
    pseudo_header ) + udphdr_and_data_size );
    
       if ( new_check != udph->check ) {
         printf( "\tInvalid Checksum : Present 0x%02X  Should Be :
    0x%02X..", ntohs( udph->check ), ntohs( new_check ) );
         udph->check = new_check;
         fixed ++;
       printf( "\tFixed\n" )
         ;
       } else {
         printf( "\t Checksum OK\n" );
       }
       free( dump_pkt );
     } else {
       printf( "\tNON TCP/UDP Packet...Not Analyzing\n" );
     }
    }
    
    int main( int argc, char *argv[] )
    {
    
     extern char * optarg;
     extern int optind;
     char ch;
    
     struct pcap_pkthdr hdr; /*Pcap Header*/
     pcap_t *p;
    
     char errbuf[ PCAP_ERRBUF_SIZE ]; /*Error returned by libpcap will be
    present here*/
     int snaplen;
    
     pcap_dumper_t *dumper = 0;
     int packets_written = 0;
     const u_char *pkt;
    
     char *infile, *outfile; /*Input and output file*/
    
     o_in = o_out = o_ver = 0;
    
     /*Pasre and check for options*/
     while ( ( ch = getopt( argc, argv, "i:o:v" ) ) != -1 ) {
       switch ( ch ) {
           case 'i':
           infile = optarg;
           o_in++;
           break;
           case 'o':
           outfile = optarg;
           o_out++;
           break;
           case 'v':
           o_ver++;
           break;
           default:
           usage( argv[ 0 ] );
       }
     }
    
     if ( ( !o_in ) || ( !o_out ) )
       usage( argv[ 0 ] );
    
      /* Open the input file, get a pointer to it and tell it where to
    store the err string */
     p = pcap_open_offline( infile, errbuf );
    
     if ( ! p ) {
       printf( "[-]Input TCPDump file %s: %s", infile, errbuf );
       exit( -1 );
     } else if ( o_ver ) {
       printf( "[+]Input File : %s : Opened Successfully\n", infile );
     }
    
     /* Dumper is the save file pointer. man pcap to get more pcap_dump_open */
     dumper = pcap_dump_open( p, outfile );
    
     if ( ! dumper ) {
       printf( "[-]error creating output file %s: ",
               outfile, pcap_geterr( p ) );
    
       pcap_close( p );
       exit( 0 );
     } else if ( o_ver ) {
       printf( "[+]Output File : %s : Opened Successfully\n", outfile );
     }
    
     /*pcap_next gives u the pointer to next packet alongwith the info on
    its header(reffered as hdr here)*/
     while ( ( pkt = pcap_next( p, &hdr ) ) != NULL ) {
       /*check, if wrong fix it, pkt is the pointer to whole raw packet*/
       check_and_fix( ( unsigned char * ) pkt );
       /*now that we have fixed the csums (if tehy were to be) save the
    packet in new file*/
       pcap_dump( ( u_char * ) dumper, &hdr, pkt );
       //sleep( 3 );
     }
     /*close everything and bail out*/
     pcap_dump_close( dumper );
     pcap_close( p );
    
     if ( o_ver ) {
       printf( "[+]Done...Fixed %d Checksums\n", outfile, fixed )
         ;
     }
    }
    ==============================================

    an inteersting idea wud be to vary any of the forur feilds (src ip, src port, dst ip, dst port). The practicle application of this is when you are to sent the tcpdumps to someone for analysis and you dont want to reveal the real ip adresses.
    there are some apps which do this.


    For Mods : I can see similies in the code (getopt), even thogh i have uses the code tags
    guru@linux:~> who I grep -i blonde I talk; cd ~; wine; talk; touch; unzip; touch; strip; gasp; finger; mount; fsck; more; yes; gasp; umount; make clean; sleep;

  2. #2
    AO übergeek phishphreek's Avatar
    Join Date
    Jan 2002
    Posts
    4,325
    Not a mod: There is a little tic option in your reply where you can "disable smiles in this post". :)
    Quitmzilla is a firefox extension that gives you stats on how long you have quit smoking, how much money you\'ve saved, how much you haven\'t smoked and recent milestones. Very helpful for people who quit smoking and used to smoke at their computers... Helps out with the urges.

  3. #3
    Senior Member
    Join Date
    May 2003
    Posts
    1,199
    lol I thought the smiley made a nice extra to the code. lol, besides it will work when you copy and paste it.
    Everyone is going to die, I am just as good of a reason as any.

    http://think-smarter.blogspot.com

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •