Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 17 Jun 2003 23:40:02 -0400 (EDT)
From:      Robert Watson <rwatson@freebsd.org>
To:        "akanwar@digitarchy.com" <akanwar@digitarchy.com>
Cc:        freebsd-net@freebsd.org
Subject:   RE: replacement for SOCK_PACKET
Message-ID:  <Pine.NEB.3.96L.1030617232525.1014A-100000@fledge.watson.org>
In-Reply-To: <184670-22003631813445521@M2W098.mail2web.com>

next in thread | previous in thread | raw e-mail | index | archive | help

On Tue, 17 Jun 2003, akanwar@digitarchy.com wrote:

> I am trying to write a small program to send out gratituous arps
> (because the em driver does not work) for a redundancy (via IP address
> take over)  scheme. 

Hmm.  If you're having if_em bugs and haven't already submitted a PR,
please do so.  Our if_em maintainer is Prafulle Deuskar
<pdeuskar@FreeBSD.org> at Intel.

> I do NOT want to use libpcap or libnet as these will not be available on
> prodution servers. I could probably statically link and make a huge
> executable...but then I think there ought to be a simpler way. 

If pcap is not available on your production FreeBSD servers, it's because
you've removed it.

BPF is the supported "link layer transmission"  mechanism in most
BSD-derived platforms.  libpcap provides a portable library interface to
BPF; pcap ports are available (and shipped with) many other OS
implementations, including Linux.  If you have tcpdump installed, which is
common for many production installations, you likely have pcap.

If you just want to bypass libpcap, open /dev/bpf%d directly, issue the
necessary ioctl() to bind the interface (BIOCSETIF), possibly change the
"header completion mode" (BIOCSHDRCMPLT), and write the packet to the BPF
device.  Here's a code fragment:

        do {
                sprintf(device, "/dev/bpf%d", n++);
                fd = open(device, O_RDWR);
        } while (fd < 0 && errno == EBUSY && n < 1000);

        if (fd < 0) {
                perror("open");
                return (-1);
        }

        strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
        if (ioctl(fd, BIOCSETIF, &ifr)) {
                perror("ioctl");
                close(fd);
                return (-1);
        }

        if (ioctl(fd, BIOCGDLT, &data)) {
                perror("ioctl");
                close(fd);
                return (-1);
        }

        if (data != DLT_EN10MB) {
                fprintf(stderr, "ioctl: invalid data link type\n");
                close(fd);
                return (-1);
        }

        data = 1;
        if (ioctl(fd, BIOCSHDRCMPLT, &data)) {
                perror("ioctl");
                close(fd);
                return (-1);
        }

...

	if (write(fd, pbuf, pbuflen) != pbuflen)
		...




Robert N M Watson             FreeBSD Core Team, TrustedBSD Projects
robert@fledge.watson.org      Network Associates Laboratories



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.NEB.3.96L.1030617232525.1014A-100000>