saf@CITI.UMICH.EDU (10/07/87)
IF DRIVER INTERFACE SPECIFICATION (Beta Draft 10/6/87)
ABOUT THE IF DRIVER
-------------------
The IF driver provides IP with a standard interface to the services provided by a local
network. This document describes the program interface to the IF driver. Through this
interface IP receives network configuration information and sends and receive packets.
Driver requests are made by preparing a driver parameter block and a protocol parameter
block, and issuing a driver control call. The driver parameter block is described in [CITI
MacIP].
IF DRIVER NAMES
---------------
All IF Drivers have a name in the format: ".IF_*". IP finds the available interfaces by
searching the unit table for drivers with names beginning with IF_.
IF DATA STRUCTURES
------------------
The reader should be familiar with the common C derived types, such as those described in
<sys/types.h>, <sys/time.h>, MPW C, and Inside Macintosh
hwid is a pointer to a structure that identifies which hardware driver this interface module
should attach to. The length and format of a hardware identifier is particular to each
interface module and the hardware driver that it interfaces to. It is assumed that clients that
use hwid will know the format used by the IF they are calling.
Routing information is given in the following structures:
typedef union if_addrrange {
struct if_num_mask { /* Address range specified by */
unsigned long netnumber; /* Netnumber and */
unsigned long netmask; /* Netmask */
} nm;
struct if_start_end { /* Address range specified by */
unsigned long start; /* Start and */
unsigned long end; /* End */
} se;
} if_addrrange_t, *if_addrrange_p;
typedef struct if_redirect { /* IF redirect array element */
unsigned short rd_rtype; /* Range specification format */
if_addrrange_t rd_range; /* Address range */
unsigned long rd_to; /* New IP address */
} if_redirect_t, *if_redirect_p;
typedef struct if_routing { /* IF routing information */
unsigned long hr_lhost; /* Local IP address.*/
unsigned short hr_rtype; /* Range specification format */
if_addrrange_t hr_range; /* Address range */
unsigned long hr_broadaddr; /* Broadcast address */
unsigned long hr_default; /* Default route */
unsigned short hr_cost; /* Relative cost of network */
unsigned long hr_name[4]; /* IP address of 4 name servers */
unsigned long hr_spare[4]; /* 4 spare IP addresses.*/
if_redirect_t hr_redirect[10]; /* Variable array of redirects */
} if_routing_t, *if_routing_p;
hr_redirect is an array of redirect records. If there are fewer than 10 records, the
records are terminated by a zero record. hr_rtype selects the if_addrrange_t union,
either IF_R_NUMMASK, or IF_R_STARTEND.
IF FUNCTIONS
------------
The following functions provide a program interface to the IP driver layer. Each function
returns success (0) or an error code. Error code identifiers are defined in net_errno.h.
The return type for all functions is long.
Some IF routines take refnum as their first parameter. refnum is not actually passed to the
routine. Rather, it is used by the glue library to demultiplex on the available interface
modules. The parameters following refnum are passed to the IF following the conventions
described in CITI's Driver Calling Conventions.
Right and left arrows indicate values passed to and from the driver functions, respectively.
if_find (uproc, udata)
-> ProcPtr uproc; Address of client routine
-> long udata; User data
(*uproc) (name, refnum, udata)
-> long refnum; IF reference number
-> char *name; Interface's name
-> long udata; User data
if_find searches the unit table for interface modules, calling (*uproc) for each interface
found. This routine resides in the glue library, not the interface modules.
(*uproc) is called with the reference number (refnum) and the driver name (name) of each
interface module found. There are no restrictions on what (*uproc) can do. udata is a
long word of user data that if_find passes to (*uproc).
if_get_info (refnum, output, flags, headersz, trailersz,
obmaxpaksz, ibmaxpaksz, maxfragsz, connections, version)
-> long refnum; IF reference number
<- ProcPtr *output; Packet output routine
<- unsigned long *flags; Control flags
<- unsigned long *headersz; Header space requirements
<- unsigned long *trailersz; Trailer space requirements
<- unsigned long *obmaxpaksz; Maximum IP packet size
<- unsigned long *ibmaxpaksz; Maximum IP packet size
<- unsigned long *maxfragsz; Maximum lan packet size (IP fragment)
<- unsigned long *connections; Number of network connections
<> unsigned long *version; Interface versions
if_get_info returns global information about an interface module. refnum is the
reference number of the IF the client wants to call. hwindex is the hardware index of the
network connection the client wants information on.
output is the address of the packet output routine, defined below, that IP can call to write
packets. headersz and trailersz are the space that IP needs to preallocate for this IF's
headers an trailers. maxpaksz is the largest IP packet (possibly fragmented) that this
network can successfully transmit. maxfragsz is the largest packet (IP fragment) that this
network will transmit.
connections is the number of network connections (devices) that this interface is
controlling. IP should call if_get_hwinfo(conn_i) for each connection, where conn_i
is a connection index from 1 to connections.
version allows IP and the interface module to agree upon which version of this interface
they are using. On input, IP sets one or more bits in version indicating (bit 1 for version
1, bit 2 for version 2) which versions it will handle. On output IF clears all but one of the
bits in version, indicating which version of this interface will be used. If IP and the IF
have no common version, version will be zero and an error code is returned.
Special behavior can be specified with flags. The following flags are defined:
IF_FLAG_NOCOPY Indicates which buffer management scheme this interface
uses.
IF_FLAG_CANSETINFO Indicates that the routing information can be set with the
if_set_hwinfo routine.
if_get_hwinfo (refnum, hwindex, hwid, routing, flags)
-> long refnum; IF reference number
-> long hwindex; Hardware number
<- Ptr hwid; Hardware ID
<- if_routing_t *routing; Routing information
<- unsigned long *flags; Control flags
if_get_hwinfo returns information specific to a network connection. refnum is the
reference number of the IF the client wants to call. hwindex is the hardware index of the
network connection the client wants information on. The map from indexes to network
connections will be consistent during one boot of the machine.
routing is the address of a routing structure allocated by IP and filled with information
specific to this connection with IF.
hwid is a pointer to some memory that will hold this connection's hardware ID. The
format of the hardware ID is specific to the type of interface and is intended to be
meaningful to people. In general, the hwid will be used by chooser modules that control
the configuration information for network connections IP can ignore the hardware id by
passing a NULL pointer.
Special behavior can be specified with flags. The following flags are defined:
IF_FLAG_PROXARP Indicates that this network has a default host that does proxy
ARP for hosts on other networks.
IF_FLAG_RIP Indicates that IP should lookup the default host on this
network using the RIP protocol.
if_set_hwinfo (refnum, hwindex, routing)
-> long refnum; IF reference number
-> long hwindex; Hardware number
-> if_routing_t *routing; Routing information
if_set_hwinfo sets the local IP address and routing information for a network
connection. refnum is the reference number of the IF the client wants to call. hwindex is
the hardware index of the network connection the client wants to set information for.
routing points to an if_routing_t structure that contains the new information.
if_open (refnum, hwindex, input, nextbuf)
-> long refnum; IF reference number
-> long hwindex; Hardware number
-> ProcPtr input; Packet input routine
-> ProcPtr nextbuf; Buffer allocation routine
if_open opens a network connection for packet input/output. refnum is the reference
number of the IF the client wants to call. hwindex is the hardware index of the network
connection the client wants to open. input is the address of an IP routine that IF can call
to deliver packets. nextbuf is the address of an IP routine that IF can call to allocate
packets. The interfaces to (*input) and (*nextbuf) are defined below.
if_close (refnum, hwindex)
-> long refnum; IF reference number
-> long hwindex; Hardware number
if_close closes a network connection . refnum is the reference number of the IF the
client wants to call. hwindex is the hardware index of the network connection the client
wants to close.
if_control (refnum, hwindex, buffer, buflen, control)
-> long refnum; IF reference number
-> long hwindex; Hardware number
<> Ptr *buffer; Data used by control call
<> unsigned long *buflen; Size of buffer (bytes)
-> unsigned long control; Specifies control operation
if_control performs various operations for an IF. refnum is the reference number of the
IF the client wants to call. hwindex is the hardware index of the network connection the
client wants to control. control selects an operation and is the only mandatory parameter.
Parameters that are not required by individual control operations may be passed as NULL.
No control operations are currently defined for if_control.
(*output) (hwindex, buffer, buflen, lhost, flags)
-> long hwindex; Hardware number
-> Ptr buffer; Pointer to buffer
-> short buflen; Length of buffer
-> unsigned long lhost; IP address of network connection
-> long flags; Control flags
(*output) sends a datagram to the IP address specified by fhost. The address of this
routine is returned to the client by if_info. It can not be called through PBControl.
hwindex is the hardware index of the network connection the client wants send data on.
fhost is the IP address of the host this packet is sent to. If fhost matches the broadcast
address returned in routing the packet will be broadcast on the local network Unless this
network has a gateway that does proxy ARP, fhost must be on the local area network (or
the boadcast address). fhost does not have to be the final destination of the IP packet.
Special behavior can be specified with flags. The following flags are defined:
IF_FLAG_USEWDS If set, buffer points to a Write Data Structure and buflen is
ignored. If not set, buffer points to the beginning of the IP
packet and buflen contains the length of the packet. In this
case, IP must guarante that there will be at least headersz
bytes before *buffer and trailersz bytes after
*(buffer+buflen) for IF headers and trailers.
IF_FLAG_BROADCAST If set, the packet will be broadcast on the local network. In
this case fhost is ignored. Alternatly, if the broadcast
address is in fhost this flag is ignored.
CLIENT-SUPPLIED FUNCTIONS
-------------------------
(*nextbuf) (buffer, headersz, trailersz, maxfragsz)
<- Ptr *buffer; Data used by control call
-> unsigned long headersz; Header space requirements
-> unsigned long trailersz; Trailer space requirements
-> unsigned long maxfragsz; Maximum IP packet size
(*nextbuf) is the client supplied routine IF drivers call to allocate buffers. headersz,
trailersz and maxfragsz indicate how big the buffer should be. On output, buffer
points to a buffer of size maxfragsz + trailersz with at least headersz writeable bytes
before buffer.
If no buffer could be allocated (*nextbuf) should return NULL in buffer and the proper
error code as the function result. The IF will try again later. Packets will very likely be
lost.
(*nextbuf) executes in the IF module's context and should not rely on A5 for addressing
globals or the jump table. This routine may be called from an interrupt.
(*input) (buffer, buflen, lhost, headersz, flags)
-> Ptr *buffer; Data used by control call
-> unsigned long *buflen; Size of buffer (bytes)
-> unsigned long lhost; Header space requirements
-> unsigned long headersz; Trailer space requirements
-> long flags; Control flags
(*input) is the client supplied routine IF drivers call to deliver packets. buffer points to a
buffer containing an IP packet of length buflen.
If the IF_F_NOCOPY bit of flags is set buffer points to a buffer that was previously allocated
by IF via the nextbuf routine. IP keeps this buffer; IF will can nextbuf for another. IP
should back off from buffer by headersz bytes to find the beginning of the actual memory
block.
If the IF_F_NOCOPY bit of flags is clear (*input) must copy the packet into a local buffer.
lhost is the IP address of the network connection on which the packet arrived.
If this packet was broadcast IF_F_BROADCAST bit of flags is set.
(*input) executes in the IF module's context and should not rely on A5 for addressing
globals or the jump table. This routine may be called from an interrupt.
BUFFER MANAGEMENT
-----------------
On output (calls to (*output)), clients may pass the address of a buffer containing the
packet or the address of a Write Data Structure, indicating which with the flags parameter.
If the client is passing a buffer to (*output), the client must insure that there are at least
headersz writeable bytes before the location *buffer and trailersz writeable bytes after
the location *(buffer + buflen). The hardware protocols use these for their headers
and trailers.
If the client is passing a Write Data Structure to (*output), the client must insure that there
is at least xxx (one) empty entry at the beginning (wds.index >= 1) and one empty entry
at the end. The hardware protocols use this for their headers and trailers.
On input, the interface module may expect the client to provide buffers to it or the interface
module may have it's own internal buffer.
If the interface module expects the client to provide the buffers, the interface module must
provide nextbuf routine which the IF call to get buffers. The IF always keeps one buffer
ready for the next packet. When a packet arrives, the IF first allocates another buffer by
calling (*nextbuf), then delivers the packet to the client by calling (*input). Since the
packet is in a buffer that IF got from the client and IF has already allocated another buffer,
(*input) keeps the buffer that the packet is in.
If the interface module keeps it's own buffers (*input) must quickly copy the packet out
of the buffer so that the IF can prepare to receive the next packet. (*nextbuf) is never
called.
ADDRESS RESOLUTION
------------------
Address resolution is the translation of IP address to physical network addresses. All
Interface modules are responsible for address resolution .
BROADCASTS
----------
A packet will be broadcast on the local network if either the broadcast flag is set or fhost is
the broadcast address for ths network.
OUTSTANDING ISSUES
------------------
I have set the hr_redirect array to be 10 elements, no more. This is not expandable. If
you ever imagine having a network that requires more than 10 initial route statements,
speak now.
The buffer schemes, copy and no copy, need a clearer description.