using BPF and rawsocket

Tobias Abrahamsson toba at etek.chalmers.se
Fri Oct 14 08:13:50 PDT 2005


Hi

I have a problem that i hope that someone can help me with. I'm trying to
make a computer running a webserver, reachable on a net wich it don't own
an address on. In order to let clients reach the server, I use BPF to
capture the packets to an address that i have chosen, ( not important wich
address, only that it's not on the right net),  and then redirect them to
my self to reach the webserver. To make the webserver respond to the
client I set a static route back to the client ( there is no routers
between the clients and the webserver so this works ). I'm using a raw
socket to send the capured packets to webserver and there is were I have
trouble. When I'm using sendto() it responds with error message: Invalid
argument. I can't figure out why that is, but this is the first time I use
rawsockets so maby it is easy to fix.

Thankful for all ideas.
Tobias Abrahamsson

PS. the code have testig status so it is not so neat.


#include <sys/types.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/uio.h>
#include <net/if.h>
#include <net/ethernet.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <pcap.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>



static void
print_pkt( char *pkt_ptr ) {

	int i, print;
	char ch;
	struct ip *ip_hdr;

	ip_hdr = (struct ip *)pkt_ptr;

	for( i = 0; i < ntohs(ip_hdr->ip_len); i++ ) {
		ch = 0x00;
		ch = *(pkt_ptr + i);

		if( i%8 == 0 )
			printf("\n");

		print = (int)ch & 0x000000ff;

		if( (print & 0x000000f0) == 0 )
			printf( "0%x:", print );
		else
			printf( "%x:", print );
	}

	printf( "\n" );

}

static void
send_pkt( int s, struct ip *ip_hdr )  {

	char *ptr;
	ssize_t ss;
	size_t len;

	struct sockaddr_in saddr;

	memset( &saddr, 0, sizeof(saddr) );

	saddr.sin_family = AF_INET;
	saddr.sin_port =  80;
	inet_aton( "10.0.0.0", saddr.sin_addr );

	len = ntohs(ip_hdr->ip_len);
	ptr = (char *)ip_hdr;


	if( (ss = sendto( s, ptr, len, 0, (const struct sockaddr *)&saddr,
sizeof(saddr) )) < 0 )
		perror( "sendto could not write" );


	printf( "ip_len: %d sent: %d bytes\n", len, ss );

}


int
main() {

	int s, snaplen = 1600;
	char *device, errbuf[ PCAP_ERRBUF_SIZE ];
	const int on = 1;
	const u_char *pkt_ptr;

	struct ip *ip_hdr;
	struct pcap_pkthdr pchdr;

	pcap_t *pd;


	if( (device = pcap_lookupdev( errbuf )) == NULL )
		fprintf( stderr, errbuf );

	pd = pcap_open_live( device, snaplen, 1, 1, errbuf);

	printf( "device %s\n", device );

	if( (s = socket( AF_INET, SOCK_RAW, 0 )) < 0 )
		perror( "socket" );


	if( setsockopt( s, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on) ) < 0 )
		perror( "setsockopt" );


	while( 1 ) {

		while( (pkt_ptr = (char *)pcap_next( pd, &pchdr )) == NULL );

		ip_hdr = (struct ip *)(pkt_ptr + ETHER_HDR_LEN);


		if( ntohs(ip_hdr->ip_len) < 100 )
			print_pkt( (char *)ip_hdr );

		send_pkt( s, ip_hdr );
	}

}




More information about the freebsd-net mailing list