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.