*BSD News Article 12628


Return to BSD News archive

Xref: sserve comp.os.386bsd.apps:28 comp.os.386bsd.development:136
Newsgroups: comp.os.386bsd.apps,comp.os.386bsd.development
Path: sserve!newshost.anu.edu.au!munnari.oz.au!comp.vuw.ac.nz!duncan
From: duncan@comp.vuw.ac.nz (Duncan McEwan)
Subject: WD8003 Promiscuous mode, Berkeley Packet Filter, and tcpdump
Nntp-Posting-Host: bats.comp.vuw.ac.nz
Message-ID: <C3nqox.7MC@comp.vuw.ac.nz>
Organization: Dept. of Comp. Sci., Victoria Uni. of Wellington, New Zealand.
Sender: news@comp.vuw.ac.nz (News Admin)
Date: Wed, 10 Mar 1993 05:17:20 GMT
Lines: 91

I have built a kernel with the berkeley packet filter included, by following
the instructions in the bpf/README file of the tcpdump distribution.  Although
I've got tcpdump more-or-less working, there are some loose ends that need
tidying up.

The main problem is that I'm not sure how to put the WD8003 ethernet controller
into promiscuous mode, so tcpdump only prints packets sent from, or received by
that interface.  I don't have a programmers manual for the controller, but I
looked at the code in isa/if_we.c and isa/if_wereg.c, and guessed that changing
the line in weinit() that read

	outb(sc->we_io_nic_addr + WD_P0_RCR, WD_R_MON);

to

	outb(sc->we_io_nic_addr + WD_P0_RCR, WD_R_MON | WD_R_PRO);

might work.  It didn't :-(  The networking stuff still works quite happily
with that change, but the interface (or at least, tcpdump) only sees
packets sent to or from that interface.

A related problem is that I don't understand how the control flow that results
in the interface being put into promiscuous mode can work.  It looks something
like this.

	tcpdump does ioctl(..., BIOCPROMISC, ...) on the bpf device.

	bpfioctl calls ifpromisc() (both routines are in net/bpf.c).

	ifpromisc() sets the IFF_PROMISC flag in ifp->if_flags
		and calls (*ifp->if_ioctl)(), the device specific
		ioctl routine, in this case, weioctl(..., SIOCSIFFLAGS, ...).

	weioctl(), case SIOCSIFFLAGS looks like this:

	        case SIOCSIFFLAGS:
         	       if ((ifp->if_flags & IFF_UP) == 0 &&
                	    ifp->if_flags & IFF_RUNNING) {
                        	ifp->if_flags &= ~IFF_RUNNING;
                        	westop(ifp->if_unit);
                	} else if (ifp->if_flags & IFF_UP &&
                    	(ifp->if_flags & IFF_RUNNING) == 0)
                        	weinit(ifp->if_unit);
                	break;

	weinit() was modified as per the bpf installation instructions to
	contain the following...

		#if NBPFILTER > 0
        		if (sc->we_if.if_flags & IFF_PROMISC) {
                		/* set the promiscuous bit */
                		printf("promisc on\n");		/* DEBUG */
                		outb(sc->we_io_nic_addr + WD_P0_RCR,
					WD_R_MOD | WD_R_PRO);
        		}
        		else {
                		printf("promisc off\n");	/* DEBUG */
                		outb(sc->we_io_nic_addr + WD_P0_RCR, WD_R_MON);
        		}
		#endif


When I first tried tcpdump the message "promisc on" was not printed, even
though a modified ifconfig showed that the IFF_PROMISC flag was set on "we0".

On looking closer at the code in weioctl that calls weinit, it seemed to me
that whenever tcpdump tries to put the interface into promiscuous mode, both
IFF_UP and IFF_RUNNING will be set in if_flags (since up until that time the
interface has been working normally).  If that is the case, weinit() would
never be called.

To test this theory, I changed the "else" clause in weioctl() to make it call
weinit() unconditionally.

After that weinit() was called when tcpdump started up (the "promisc on"
message was written out).  There is still the problem that my method for
putting the interface into promiscuous mode is incorrect, but at least it's a
step closer!

The above is based on the code for the "we" driver, (after the modifications
for bpf have been made), and it is quite likely that I have made some mistake
making those modifications.  But the "le" (Lance driver) code distributed with
the BPF source has essentially identical code in it's leioctl(), so the
question of how it expects to put the interface into promiscuous mode applies
there as well.

Any suggestions as to what I am missing will be gratefully accepted...

Duncan.