hedrick@athos.rutgers.edu (Charles Hedrick) (07/25/90)
Since my message over the weekend, I've taken a closer look at support of Ethertalk on Suns. Both UAB and the code I described then depended upon /dev/nit. /dev/nit is an "Ethernet tap". It's really intended for network monitoring, but it has enough capabilities that you can use it to select packets of a specify type, and you can even set up filters that only accept Appletalk packets directed at a specific Appletalk socket. (I use that facility. UAB does not require it.) Both UAB and my code set up /dev/nit to pass Appletalk packets and Appletalk ARP's. However there's a problem with using /dev/nit in this way: It's fairly inefficient. When /dev/nit is open, every packet arriving in the system is copied. This includes not just packets we are interested in, but TCP/IP and any other packets. Streams messages are sent to every user of /dev/nit for every incoming packet. The filtering is done at a higher level. Those packets a given user isn't interested in are thrown away. Apparently the packets themselves are not copied for each user of /dev/nit. They are copied only once, and the copy is shared by all users of /dev/nit (at least if they are all looking at the same portion of each packet). Thus the first time anyone opens /dev/nit, it increases the overhead of processing TCP/IP substantially, and every additional user of /dev/nit increases the overhead somewhat. Most people feel that turning on Ethertalk should not increase the overhead for TCP/IP traffic. So I am rather hesitant to use this method. I have ported the Ethernet packet filter from the 4.3 contributed software. This is the code on which the /dev/nit protocol filter was based. It has three performance advantages over /dev/nit. - it is only activated for packets of types that are not normally handled. That is, it does not increase overhead for TCP/IP. - the packet is not copied at all. It stays in mbufs, which is where the device driver put it. - the filter is run at a low level, so that messages are not sent up to programs that are not interested in the packet. I did the port in such a way that the packet filter can be installed without needing source. It's a pure device driver. This works only because Sun has provided hooks in the Ethernet device level code to let people add new protocols without needing source. Presumably these hooks are intended for use by their DECnet product, and other similar things. You install it as you would any device driver, i.e. by adding an appropriate line in conf/files and your configuration file, and by putting a new entry for it in conf.c. So far I have been testing it on 4.0.3c. It appears that it will not work on 4.0.1, as the hooks do not pass all the necessary data. (However it happens that the Appletalk code doesn't need that data, so the driver could be made to fill in zeros.) The only change I've had to make to the interface is to add an ioctl to specify what Ethernet packet types should be handled by the packet filter. I'm considering adding specific support for Appletalk, though I'm not sure the extra CPU needed to run the packet filters is really enough to worry about.