Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 28 Feb 2000 05:18:29 -0800
From:      Rahul Dhesi <dhesi@rahul.net>
To:        freebsd-stable@freebsd.org
Subject:   divert(4) non-working code example
Message-ID:  <20000228131831.63A783FF09@bolero.rahul.net>

next in thread | raw e-mail | index | archive | help
The following is a relatively simple program that should read and write
divert-ed packets, without modifying them.  But it never returns from the
recvfrom() system call.  Any suggestions?

An extensive web search appears to indicate that only one existing
program, i.e., natd(8), uses divert(4).  I found no other examples of
anybody using divert(4).

Rahul

-- cut here --
/* TEST PROGRAM TO SEE IF divert(4) will work */

/*
FreeBSD 3.4-STABLE. Kernel currently include options 
DUMMYNET, IPDIVERT, IPFIREWALL, and IPFIREWALL_DEFAULT_TO_ACCEPT.

This code is based on information from the divert(4) man page
and also after examining the natd(8) source code.

To test:

    cc -o testdivert testdivert.c
    ./testdivert >& Log &
    ipfw add 1 divert 22222 all from 0.0.0.0/0 to xx.xx.xx.xx/32

where xx.xx.xx.xx is the IP address of some other host.  

Now ping xx.xx.xx.xx.  Each ping packet should result in an entry
being made into the file 'Log'.  But in fact I see no output into
'Log' and no traffic to xx.xx.xx.xx gets through.  Tracing with ktrace
shows that testdivert is waiting for recvfrom() to return.
*/
   
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
/* required by netinet/ip.h */
#include <netinet/in_systm.h>
/* to define IP_MAXPACKET */
#include <netinet/ip.h>
/* big enough to hold a network packet */
#define SZ_PACKET	IP_MAXPACKET

static char *myname = "testdivert";

int main(int argc, char **argv)
{
    unsigned port = 22222;
    int socket_fd = -1;
    char packetbuf[SZ_PACKET];
    struct sockaddr_in addr;

    /* make the socket */
    socket_fd = socket(PF_INET, SOCK_RAW, IPPROTO_DIVERT);
    if (socket_fd == -1) {
	(void) fprintf(stderr, "%s: error: can't make socket: %s\n",
		myname, strerror(errno));
	exit(1);
    }

    addr.sin_family         = AF_INET;
    addr.sin_addr.s_addr    = htonl(INADDR_ANY); /* will be ignored by bind() */
    addr.sin_port           = port;
    if (bind(socket_fd, (struct sockaddr *) &addr, sizeof addr) == -1) {
	(void) fprintf(stderr, 
	    "%s: error: can't bind socket to port %u: %s\n",
		myname, port, strerror(errno));
	exit(1);
    }

    (void) fprintf(stdout, "%s: note: socket_fd is %d, port is %d\n", 
		myname, socket_fd, port);

    /* make output unbufferd so we can print status dots */
    (void) setbuf(stdout, (char *) NULL);

    /* go into read/write loop */
    for ( ; ; ) {
	int incount;
	int addrlen;
	addrlen = sizeof addr;
	incount = recvfrom(socket_fd, packetbuf, sizeof packetbuf, 0, 
					(struct sockaddr *)  &addr, &addrlen);
	if (incount >= 0) {
	    int sendstatus;
	    (void) fprintf(stdout, "<");	/* < means got a packet */
	    sendstatus = sendto(socket_fd, packetbuf, incount, 0, 
					(struct sockaddr *)  &addr, sizeof addr);
	    if (sendstatus != -1) {
		(void) fprintf(stdout, ">");	/* > means sent a packet */
	    } else {
		(void) fprintf(stdout, "?");	/* ? = send error */
	    }
	} else {
	    (void) fprintf(stdout, ".");	/* . = receive error */
	}
    }
    /*NOTREACHED*/
    return 0;
}
-- cut here --


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-stable" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20000228131831.63A783FF09>