using BPF and rawsocket

Tobias Abrahamsson toba at
Mon Oct 17 04:14:15 PDT 2005


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 )

		print = (int)ch & 0x000000ff;

		if( (print & 0x000000f0) == 0 )
			printf( "0%x:", print );
			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( "", 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 );


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 );


freebsd-net at mailing list
To unsubscribe, send any mail to "freebsd-net-unsubscribe at"

More information about the freebsd-net mailing list