Sending and capturing with libnet & pcap

<[email protected]> 30 Mar 2004 06:55:31 -0000
Newsgroups gmane.comp.security.libnet
Message-ID <[email protected]>

Hello guys,

Kindly help me with this problem.
I am writing two programs - one client which makes TCP/IP/Ethernet traffic and sends it to another host connected back to back using 100Mbps ethernet. The second program (runs in the second host)is a server which captures this traffic from client and sends it back. It sometimes work perfectly. And in the next run, the server might not capture anything. Sometimes it captures but does not sends anything back. SOmetimes it works fine for 20 or 30 repeatitions and then stops. SO the result is very unpredictable. Please take a look at this piece of code and tell me what you find wrong.

Initially the client sends the size of the 'message' (payload) that will be sent and and then the number of times this will be iterated; so that server will be prepared to receive accordingly. The code is just slight modification over the sample code that came in the package. I tried all the packet capturing functions : pcap_loop, pcap_next,etc in both client and server but the result is the same. Increasing to_ms in pcap_openlive() does not seem to have any affect on pcap_dispatch.

CLIENT CODE:

void my_callback(...){/*just checking TCP ACK or not */};

main(int argc,char *argv[]){

/* opens a stream socket, sends payload size (bufsize)and iterate number (repeat)and close the socket*/

  payload = malloc(bufsize);
   
   for(i=0;i<bufsize;i++)
     {
       payload[i]=character;
     }
   payload[i]='\0';   
   payload_s = strlen(payload);


l = libnet_init(LIBNET_LINK,                      NULL,                                  		   errbuf);                                
   
    dev = pcap_lookupdev(errbuf);
       
   pcap_lookupnet(dev,&netp,&maskp,errbuf);
       
    descr = pcap_open_live(dev,BUFSIZ,1,-1,errbuf);
           
   if(pcap_compile(descr,&fp,filter,0,netp) == -1)
   if(pcap_setfilter(descr,&fp) == -1)
      { fprintf(stderr,"Error setting filter\n"); exit(1); }
    
   /* read src_ip , dst_ip, src_prt and dst_prt from command line */     
        
    if (!src_ip || !src_prt || !dst_ip || !dst_prt)
      {
        usage(argv[0]);
        exit(EXIT_FAILURE);
      }

    	    tcpt = libnet_build_tcp_options(
					 "\003\003\012\001\002\004\001\011\010\012\077\077\077\077\000\000\000\000\000\000",
					 20,
					 l,
					 0);
	   	    
	    tcpt = libnet_build_tcp(
			src_prt,                                    
			 dst_prt,                                    				 0x01010101,                                				 0x02020202,                                 
			 TH_SYN,                                  			 32767,                                      				 0,                                          				 0,                                          				 LIBNET_TCP_H + 20 + payload_s,              				 payload,                                    				 payload_s,                                  				 l,                                          				 0);                                         	    
	   
	    
	    	    
	    ipt = libnet_build_ipv4(
				  LIBNET_IPV4_H + LIBNET_TCP_H + 20 + payload_s,
	0,                                          
	242,                                        
	0,                                         
	64,                                         
	IPPROTO_TCP,                                				 0,                                          
	 src_ip,                                     				 dst_ip,                                     
	 NULL,                                       				  0,                                          
	 l,                                          
	 0);   
                                      
	    do    
	      {
		
		if(r<repeat)
		  {
		    err = gettimeofday(&sendTime, &timeZone);
		    etht = libnet_build_ethernet(  enet_dst,                                 
 enet_src,                                   				 ETHERTYPE_IP,                               				 NULL,                                      				 0,                                         				 l,                                          				 etht);                                         		    
		    
		    if (etht == -1)
		      {
			fprintf(stderr, "Can't build ethernet header: %s\n", libnet_geterror(l));
			
			goto bad;
		      }
		    
                      /*
		     *  Write it to the wire.
		     */
		     c = libnet_write(l);
		     if (c == -1)
		      {
			fprintf(stderr, "Write error: %s\n",libnet_geterror(l));
			libnet_clear_packet(l);
			goto bad;
		      }
		    else
		      {
			fprintf(stderr, "Wrote %d byte TCP packet; check the wire.\n", c);
			r++;
		      }
		   
		  }
				
		captured = pcap_dispatch(descr,1,my_callback,args);
		
		if(captured>=1)
		  {
		    rcvdno++;
		    printf("\n got %d bytes",captured);
		  }
		 else if(captured==0)
		  {
		    printf("\n got nothing");
		    fprintf(stderr, "capture error: %s\n", pcap_geterr(descr));                      
                  }	
		else if(captured==-1)	
		  {
		    printf("\n error");
		    fprintf(stderr, "capture error: %s\n", pcap_geterr(descr));                      
                  }	
		}while(r<repeat || rcvdno<repeat);
	    
	    err = gettimeofday(&receivedTime, &timeZone);
	    if(!err)
	      {
		
		timersub(&receivedTime,&sendTime,&subTime);
	      }
			   	   	    
	    libnet_destroy(l); 
	    return (EXIT_SUCCESS);
 bad:
	    libnet_destroy(l);
	    return (EXIT_FAILURE);

}

/***********************************************************************/
SERVER SOURCE CODE:

int main(int argc, char *argv[])
{
  
/* open a stream socket to get ‘bufsize’ and iterate times ‘repeat’ */

/* close the socket */

	/* pcap initialization  just like in client with same paramters*/	
	dev = pcap_lookupdev(errbuf);
	
	pcap_lookupnet(dev,&netp,&maskp,errbuf);
	
	descr = pcap_open_live(dev,BUFSIZ,1,-1,errbuf);
	
	if(pcap_compile(descr,&fp,filter,0,netp) == -1)
	
	if(pcap_setfilter(descr,&fp) == -1)
	

	 l = libnet_init(
		  LIBNET_LINK, NULL,errnetbuf);                       
  			 
	/* read src ip, dst ip , src port and dst port from command line just like in client */ 
	 
	 rcvbytes = pcap_loop(descr,repeat,send_back,(u_char *)l);	
        
    libnet_destroy(l);
    return (0);
}

void send_back(u_char *args, const struct pcap_pkthdr *pkt_header,const u_char *rcvdpacket)
{
   
  l = (libnet_t *)args;
  payload = malloc(bufsize);
 
  strcpy(payload,&rcvdpacket[HEADER_SIZE]);
  payload_s = strlen(payload);

  tcpot = libnet_build_tcp_options(/* same parameters as in clinet */  );         

    tcpt = libnet_build_tcp(….,payload ….);
	
    ipt = libnet_build_ipv4();
  
    etht = libnet_build_ethernet();

     err = libnet_write(l);
    if (err == -1)
      {
	fprintf(stderr, "Write error: %s\n", libnet_geterror(l));
	goto bad;
      }
    else
      {
	fprintf(stderr, "Wrote %d byte TCP packet; check the wire.\n", err);
	printf("\n sent %d",r++);
      }
    
   
 bad:
    return ;  		
}