TABLE OF CONTENTS miamibpf.library/--general information-- miamibpf.library/--packet format-- miamibpf.library/MiamiBPFClose miamibpf.library/MiamiBPFFilter miamibpf.library/MiamiBPFInit miamibpf.library/MiamiBPFIoctl miamibpf.library/MiamiBPFOpen miamibpf.library/MiamiBPFRead miamibpf.library/MiamiBPFSetAbortmask miamibpf.library/MiamiBPFSignalmask miamibpf.library/--general information-- Miami:libs/miamibpf.library is an implementation of the Berkeley Packet Filter, an efficient, portable packet filtering mechansim for BSD-derived protocol stack. MiamiBPF is implemented on top of the packet monitoring callback mechanism in Miami 1.9.3 and above, and because of that only works with the registered version of Miami. The main advantages of MiamiBPF over the standard packet monitoring callback are: - MiamiBPF provides a socket-like API for monitoring that may be easier to use in some situations than a callback hook. - MiamiBPF takes care of the necessary buffering, task switching and signalling, so you can run all your packet analysis/debugging code on your own task schedule. - MiamiBPF supports BPF programs, i.e. virtual machine code allowing you to very efficiently pre-filter packets. BPF virtual machine code is executed within the callback hook, so packets filtered out by the virtual machine code do not create task switching overhead. - MiamiBPF adjusts itself to the speed of Miami and your program. If your program gets behind in analyzing packets then MiamiBPF automatically drops packets so Miami does not get slowed down by your program. A detailed description of the BPF virtual machine language is beyond the scope of this document. If you want to write your own BPF programs then you should get the standard BPF documentation (for BSD) from the Internet or from other sources. miamibpf.library/--packet format-- miamibpf.library/--packet format-- The BPF standard by itself does not define the format of packets (e.g. the size and type of link-layer headers) BPF programs operate on. This can be a problem for the BPF programmer because a BPF program has to be adjusted to each interface individually. With MiamiBPF this is a bit different: MiamiBPF only operates on the packet payload, not on the link-layer header, so all packets processed by MiamiBPF have an identical format, regardless of which interface they came from. Before MiamiBPF passes a packet to a BPF program it prepends the following (virtual) header: - 1 byte: packet type (MIAMIPFBPT_...) - 1 byte: link type (always DLT_MIAMI) - 14 bytes: reserved: currently padded with zero. This means that your BPF program can identify the packet type (Arp, IP etc.) by reading byte zero. The actual packet contents are located starting at offset 16. The virtual packet header is automatically added by MiamiBPF to any packet arriving at MiamiBPF. This includes packets arriving from Miami and packets passed in through MiamiBPFFilter. Packets read by MiamiBPFRead include the virtual packet header. miamibpf.library/MiamiBPFClose miamibpf.library/MiamiBPFClose NAME MiamiBPFClose -- Closes a BPF channel SYNOPSIS MiamiBPFClose( channel ); D0 void MiamiBPFClose( ULONG channel ); FUNCTION Closes the specified BPF channel, detaches it from its current interface, and frees all related resources. INPUTS channel - BPF channel miamibpf.library/MiamiBPFFilter miamibpf.library/MiamiBPFFilter NAME MiamiBPFFilter -- Executes a BPF virtual machine program for a packet SYNOPSIS retval = MiamiBPFFilter( program, packet, length, ptype ); D0 A0 A1 D0 D1 unsigned long MiamiBPFFilter( struct bpf_insn *program, unsigned char *packet, unsigned long length, char ptype ); FUNCTION Executes a BPF virtual machine program on a packet. Both the BPF program and the packet have to be specified in the function call. The program is specified by a pointer to an array of (compiled) BPF instructions. The packet is specified by a pointer to the first byte in the packet and by the packet length. The value returned by MiamiBPFFilter is the value returned by a RET instruction in your program. The return value is undefined if your program is malformed. INPUTS program - First instruction of BPF program packet - Packet to filter length - Packet length ptype - Packet type (MIAMIPFBPT_...) RESULT retval (D0) - Return value NOTE The packet MAY NOT contain any link-layer header. The first byte of the packet has to be the first byte visible to the protocol stack. This function is NOT needed if you just want to listen for packets on one of Miami's interfaces. It can be useful though if you want a BPF filter to execute on packets arriving from some OTHER source, e.g. when reading packets from a file. miamibpf.library/MiamiBPFInit miamibpf.library/MiamiBPFInit NAME MiamiBPFInit -- initialize MiamiBPF SYNOPSIS MiamiBPFInit( MiamiBase, SocketBase ); A0 A0 void MiamiBPFInit( struct Library *MiamiBase, struct Library *SocketBase ); FUNCTION Initializes MiamiBPF for use. You MUST call this function before calling any other function in miamibpf.library. INPUTS MiamiBase - Library base of miami.library SocketBase - Library base of bsdsocket.library NOTE You need to open miami.library V6 or higher and bsdsocket.library V4 or higher before calling this function. Mind the version numbers ! Using miamimpf.library with older library versions will cause crashes. miamibpf.library/MiamiBPFIoctl miamibpf.library/MiamiBPFIoctl NAME MiamiBPFIoctl -- Reads or writes control information for a BPF channel SYNOPSIS error = MiamiBPFIoctl( channel, command, data ); D0 D0 D1 A0 LONG MiamiBPFIoctl( ULONG channel, ULONG command, UBYTE *data ); FUNCTION Reads or writes control or state information associated with a previously opened BPF channel. The following commands are valid: - FIONREAD: 'data' needs to point to a longword (at least word-aligned). When the call returns that longword contains the number of bytes ready for reading from this BPF channel. - SIOCGIFADDR: 'data' needs to point to a 'struct ifreq', with ifr_name initialized to a valid interface name. When the call returns the 'struct ifreq' has been filled with address information for AF_INET for the specified interface. - BIOCGBLEN: 'data' needs to point to a longword (at least word-aligned). When the call returns that longword contains the current size of a BPF packet buffer. - BIOCSBLEN: 'data' needs to point to a longword (at least word-aligned), that contains the desired size of the BPF packet buffer. - BIOCSETF: 'data' needs to point to a 'struct bpf_program' that contains a valid, compiled BPF virtual machine code program. When the call returns MiamiBPF has attached that program to the BPF channel, so all subsequent packets will be filtered using the new program. - BIOCFLUSH: all current read buffers are emptied. - BIOCGETIF: 'data' needs to point to a 'struct ifreq'. When the call returns ifr_name has been initialized with the name of the interface the BPF channel is currently attached to. - BIOCSETIF: 'data' needs to point to a 'struct ifreq', with ifr_name initialized to a valid interface name. When the call returns the BPF channel has been attached to the specified interface, i.e. packets arriving at that interface or sent through that interface are directed to the BPF channel. - BIOCSRTIMEOUT: 'data' needs to point to a 'struct timeval' that contains the new timeout for a call to MiamiBPFRead. - BIOCGRTIMEOUT: 'data' needs to point to a 'struct timeval'. When the call returns that 'struct timeval' contains the current timeout for a call to MiamiBPFRead. - BIOCGSTATS: 'data' needs to point to a 'struct bpf_stat'. When the call returns that 'struct bpf_stat' contains the current packet statistics for this BPF channel. - BIOCIMMEDIATE: 'data' needs to point to a 'unsigned int' defining the state of the 'immediate' flag (TRUE/FALSE). Usually MiamiBPF only completes a MiamiBPFRead call when a read buffer is full or when the read timeout is expired. However if the 'immediate' flag is set to TRUE then MiamiBPFRead completes after EACH packet received. - BIOCVERSION: 'data' needs to point to a 'struct bpf_version'. When the call returns that 'struct bpf_version' contains the major and minor version numbers for this implementation of the BPF code engine. The returned 'error' value is negative if an error has occured, and zero if the function completed successfully. INPUTS channel - BPF channel command - command (usually BIOC...) data - data for the command RESULT error (D0) - error condition miamibpf.library/MiamiBPFOpen miamibpf.library/MiamiBPFOpen NAME MiamiBPFOpen -- Opens a new BPF channel SYNOPSIS channel = MiamiBPFOpen( tags ); D0 A0 ULONG MiamiBPFOpen( struct TagList *tags ); FUNCTION Opens a new BPF channel. The channel is set to default settings, and not attached to any interface. The returned value is either 0 if the function has failed, or a valid BPF channel (a value different from 0). The taglist should be NULL for compatibility to future versions. All open BPF channels are automatically closed when miamibpf.library is closed. Note that BPF channels are quite different from socket numbers. You CANNOT use BPF channel numbers in an FD_SET (e.g. in a WaitSelect call). INPUTS tags - taglist (not used) RESULT channel (D0) - BPF channel miamibpf.library/MiamiBPFRead miamibpf.library/MiamiBPFRead NAME MiamiBPFRead -- Reads packets from a BPF channel SYNOPSIS length = MiamiBPFRead( channel, buffer, maxlen ); D0 D0 A0 D1 LONG MiamiBPFRead( ULONG channel, UBYTE *buffer, ULONG maxlen ); FUNCTION Reads one or more packets from a BPF channel. This function blocks until data is available for reading. Whether the function returns for EACH packet or only after several packets have been read depends on the state of the 'immediate' flag for this BPF channel (see MiamiBPFIoctl). 'maxlen' has to be EXACTLY IDENTICAL to the current buffer size for this channel, or MiamiBPFRead immediately returns -1. You can set/get the current buffer size through MiamiBPFIoctl. A 'length' value greater than zero indicates the number of bytes read (one or more packets). A value of zero indicates that a timeout has occured. A value less than zero indicates that an error has occured or that one or more signals in the current abort mask have arrived. In the latter case use SetSignal to find out which signal has arrived. INPUTS channel - BPF channel buffer - packet buffer maxlen - size of the packet buffer RESULT length (D0) - number of bytes returned miamibpf.library/MiamiBPFSetAbortmask miamibpf.library/MiamiBPFSetAbortmask NAME MiamiBPFSetAbortmask -- Defines the abort mask for a BPF channel SYNOPSIS MiamiBPFSetAbortmask( channel, signals ); D0 D0 void MiamiBPFSetAbortmask( ULONG channel, ULONG signals ); FUNCTION Usually a MiamiBPFRead command only returns when data is available for reading or when the read timeout (if any) has expired. This function allows you define an additional condition when you want MiamiBPFRead to return, e.g. when the user hits Ctrl-C. INPUTS channel - BPF channel signals - abort mask EXAMPLE MiamiBPFSetAbortmask(channel,SIGBREAKF_CTRL_C); miamibpf.library/MiamiBPFSignalmask miamibpf.library/MiamiBPFSignalmask NAME MiamiBPFSignalmask -- Returns the signal mask for a BPF channel SYNOPSIS signals = MiamiBPFSignalmask( channel ); D0 D0 ULONG MiamiBPFSignalmask( ULONG channel ); FUNCTION Each open BPF channel has an associated signal mask that is set whenever a MiamiBPFRead function would complete. That signal mask is returned by this function. If you want to ensure that MiamiBPFRead does not block then you need to first check if data is available for reading (FIONREAD). If not then wait for the signal(s) returned by MiamiBPFSignalmask to be set for your task, and check again (FIONREAD). Call MiamiBPFRead only if FIONREAD returns a non-zero number of bytes. INPUTS channel - BPF channel RESULT signals (D0) - signal mask .