🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.protocols.appletalk
Article #4292

IP specification (narrow)

#4292
From: saf
Date: Fri, 23 Oct 1987 19:20
537 lines
18953 bytes

IP DRIVER INTERFACE SPECIFICATION
Final Draft

MacIP project
University of Michigan, CITI
2901 Hubbard
Ann Arbor, MI 48103

macip@citi.umich.edu


ABOUT THE IP DRIVER

The IP driver layer, one of the CITI MacIP drivers, implements the Internet 
Protocol [RFC 791].  This document describes the interface to IP.

IP 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.

Clients are given the option of writing data from a character array or from a 
Write Data Structure (WDS).  The WDS is a "gather write" structure.  It 
specifies a list and ordering of  buffers to write in a single operation.

Within the WDS, wds_index is an index into an array of buffer descriptors, 
pointing to the first buffer to write.  IP clients must pass wds_index as 2 or 
more, and allocate the corresponding buffer descriptors.  The first two buffer 
descriptors will be used by lower level protocols for protocol headers.  
Terminate the buffer descriptor array with a descriptor specifying length zero.

	typedef struct bd {	/* Buffer descriptor */
		unsigned short	bl;	/* Buffer length */
		Ptr				bp;	/* Buffer pointer */
	} bd_t, *bd_p;

	typedef struct wds {	/* Write data structure */
		unsigned long	wds_index;		/* Descriptor index */
		bd_t 			wds_buffer[];	/* List of descriptors */
	} wds_t, *wds_p;

The following is a sample WDS.  wds_index is 2, so the first buffer 
descriptor is wds_buffer[2].  Descriptors wds_buffer[0] and 
wds_buffer[1] will be used for lower layer protocol headers.  DATA LEN 
and DATA PTR are the length of and a pointer to the client's buffer.  This 
example shows the minimal WDS for IP clients.

		+-----------------------+
		|            2          |	wds_index (long)
		+-----------------------+
		|                       |	buffer length #0 (word)
		+-----------------------+
		|                       |	buffer pointer #0 (pointer)
		+-----------------------+
		|                       |	buffer length #1 (word)
		+-----------------------+
		|                       |	buffer pointer #1 (pointer)
		+-----------------------+
		|        DATA LEN       |	buffer length #2 (word)
		+-----------------------+
		|        DATA PTR       |	buffer pointer #2 (pointer)
		+-----------------------+
		|           0           |	buffer length #3 (word)
		+-----------------------+
		|         UNUSED        |	buffer pointer #3 (pointer)
		+-----------------------+
		            .
		            .
		            .


All IP datagrams are described by an IP header [RFC 791], described below :

	typedef struct ip_header {
		unsigned char	ip_ver:4;
		unsigned char	ip_ihl:4;
		unsigned char	ip_tsrv;
		unsigned short	ip_len;
		unsigned short	ip_id;
		unsigned short	ip_flgs:3;
		unsigned short	ip_foff:13;
		unsigned char	ip_time;
		unsigned char	ip_prot;
		unsigned short	ip_chksum;
		unsigned long	ip_src;
		unsigned long	ip_dst
		unsigned long	ip_options;
	} ip_header_t, *ip_header_p;


IP can  return a list of all active local IP addresses.  The list is a zero-
terminated array of the following structure:

	typedef struct ip_addr {
		unsigned long	addr;	/* IP address */
		unsigned long	mask;	/* Net mask for addr */
	} ip_addr_t, *ip_addr_p;


Information on maximum segment size is handled with the following structure:

	typedef struct ip_mss {
		unsigned long	addr;	/* IP address */
		unsigned long	ob_maxpaksz;	/* Max outbound IP 	
										   packet, assuming no 
										   IP options */
		unsigned long	ib_maxpaksz;	/* Max inbound packet */
		unsigned long	maxfragsz;		/* Maximum fragment size 
										   on network, assuming 
										   no IP options */
	} ip_mss_t, *ip_mss_p;


Version information on the IP driver is returned in the following structure:

	typedef struct ip_version {
		unsigned char	version[32];	/* Version number */
		unsigned char	specdesc[32];	/* Spec description */
		unsigned char	site[32];		/* Originating site */
	} ip_version_t, *ip_version_p;


If IP is configured to collect statistics, that information is returned in the 
following structure (NOTE: this structure is not finalized!):

	typedef struct ip_stats {
		short	st_drop;	/* # dropped */
		short	st_xsum;	/* # with bad cksum */
		short	st_len;		/* # with bad lengths */
		short	st_dest;	/* # bad io_fhost*/
		short	st_ttl;		/* # 0 time to live */
		short	st_prot;	/* # protocol unavailable */
		short	st_ver;		/* Bad ip version number */
		short	st_snd;		/* # of ip datagrams sent */
		short	st_rcv;		/* # of datagrams received */
		short	st_frag;	/* # of fragments received */
		short	st_multi;	/* # times >1 packet in Q */
		short	st_retry;	/* # of retransmissions */
		short	st_retry_fail;/* Number of retry failures */ 
	} ip_stats_t, *ip_stats_p;


IP 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.

IP may notify clients of asynchronous events by executing a client-supplied 
notification routine.  Execution of the notification routine is called delivery of 
notification.  Clients are notified of an event if and only if they have 
specifically requested notification of that event.  Clients request  and cancel 
notification of events by setting a mask and passing it to ip_request and 
ip_cancel, respectively.

Some functions accept io_timeout as a parameter.  For these routines, if 
io_timeout is NULL, the function blocks forever, or until the call can be 
completed.  If io_timeout is not NULL, the function blocks until the timeout 
value expires or the call can be completed.  Implementation-dependent 
restrictions may apply as to when a client can block.  If it is illegal for a call to 
block, the error E_CANTBLOCK is returned.

Some functions accept (and in certain cases return) io_flags as a parameter.  
io_flags is a long-word bitmask of control flags.  A list of all flags is given 
in "IP CONSTANTS."

Right and left arrows indicate values passed to and from the driver functions, 
respectively.

ip_create (io_stream, io_prot)
	<-	Ptr				*io_stream	IP stream descriptor	
	->	unsigned short	io_prot		Internet protocol number

ip_create creates an IP stream.  On success, ip_create prepares 
io_stream, which carries the private, protocol-specific description of the 
stream.  io_prot is a protocol number as defined in [RFC 997].

Errors returned are:
	E_NOMEM
	E_PROTOINUSE

ip_delete (io_stream)
	->	Ptr				io_stream	IP stream descriptor

ip_delete destroys an IP stream.  Outstanding datagram buffers are freed and 
pending events are flushed.

Errors returned are:
	E_BADSTREAM

ip_request (io_stream, io_nclass, io_notify, io_userdata, 	
		       io_flags)
	->	Ptr				io_stream	IP stream descriptor
	->	unsigned long	io_nclass	Set of events to notify on
	->	ProcPtr			io_notify	Notification routine
	->	unsigned long	io_userdata	Passed to notification routine
	->	unsigned long	io_flags	Control flags

ip_request sets up notification for a stream.  io_notify is a pointer to the 
client's notification routine.  io_userdata is passed to the client's notification 
routine.

io_nclass is the bitwise or of the notification identifiers to notify on.  So that 
clients may request to add to current notifications, io_nclass is bitwise-ored 
to the existing bits.  Values for io_nclass are defined in the section 
"IP NOTIFICATION."  When an IP stream is created, the default value for 
io_nclass is IP_NT_NONE (i.e., no notification).

Special behavior can be specified with io_flags.  The following flags are 
defined:

IP_FLAG_NEWNOTIFY	io_notify should replace the previous 
					io_notify.  Clients may disable notification by 
					passing NULL for io_notify and setting this 
					flag.  Notification may be re-enabled later by 
					setting IP_FLAG_NEWNOTIFY and io_notify .

IP_FLAG_NEWUDATA	io_userdata should replace the previous 
					io_userdata.

Errors returned are:
	E_BADSTREAM
	E_BADNOTIFICATION
	E_BADFLAG

ip_cancel (io_stream, io_nclass)
	->	Ptr				io_stream	IP stream descriptor
	->	unsigned long	io_nclass	Events not to notify on

ip_cancel subtracts from the set of events for which the client accepts 
notification.  io_nclass is the bitwise or of the notification identifiers to 
subtract, specified under "IP NOTIFICATION."

Errors returned are:
	E_BADSTREAM
	E_BADNOTIFICATION

ip_alloc (io_stream, io_buffer, io_buflen)
	->	Ptr				io_stream	IP stream descriptor
	<-	Ptr				*io_buffer	Pointer to a datagram buffer
	->	unsigned long	io_buflen	Requested buffer length

ip_alloc allocates an IP datagram buffer of length io_buflen.

Errors returned are:
	E_BADSTREAM
	E_NOMEM

ip_free (io_stream, io_buffer)
	->	Ptr	io_stream	IP stream descriptor
	->	Ptr	io_buffer	Pointer to a datagram buffer

ip_free releases an IP datagram buffer.  io_buffer must point to a datagram 
buffer allocated by ip_alloc or ip_get.

Errors returned are:
	E_BADSTREAM
	E_BADPTR

ip_put (io_stream, io_buffer, io_buflen, io_fhost, io_lhost, 
		    io_options, io_optlen, io_flags)
	->	Ptr				io_stream	IP stream descriptor
	->	Ptr				io_buffer	Output buffer
	->	unsigned long	io_buflen	Buffer length (bytes)
	->	unsigned long	io_fhost	Destination host
	->	unsigned long	io_lhost	Local host
	->	Ptr				io_options	IP options
	->	unsigned long	io_optlen	Length of options (bytes)
	->	unsigned long	io_flags	Control flags

ip_put sends data to the address specified by io_fhost.  io_buffer and 
io_buflen specify the data to send.  If the flag IP_FLAG_USEWDS is not set 
(see below), clients must allocate io_buffer by calling ip_alloc and free 
them by calling ip_free.

If io_lhost is zero IP will route the packet and use the IP address of the 
selected interface as the source address.  If io_lhost is a valid IP address 
(one of the interfaces) IP will use io_lhost as the source address for the 
packet.  Routing will still be done as above.

io_options is a pointer to an array of ip_options, as specified in 
[RFC 791].  io_optlen specifies the length of the options, in bytes 
(maximum 44).  To specify no options, pass io_options as NULL.

Special behavior can be specified with io_flags.  The following flags are 
defined:

IP_FLAG_USEWDS	If set, io_buffer is a pointer into a client-
				allocated WDS (i.e., type wds_p).  The client 
				must allocate the structure, leaving room for 
				lower layer protocol headers, as specified in the 
				section "IP DATA STRUCTURES."

				Note that if IP_FLAG_USEWDS is set, datagram 
				buffers need not be allocated and freed with 
				ip_alloc and ip_free.  Also, io_buflen is 
				ignored.

Errors returned are:
	E_BADSTREAM
	E_BADWDS
	E_BADFLAG
	E_BADIPADDR
	E_NOMEM
	E_DTGTOOBIG
	E_CANTRESOLVEADDR
	E_HWWRITEERR

ip_get (io_stream, io_buffer, io_buflen, io_fhost, io_lhost, 
		    io_iph, io_options, io_timeout, io_flags)
	->	Ptr				io_stream	IP stream descriptor
	<-	Pt			r	*io_buffer	Datagram from foreign host
	<>	unsigned long	*io_buflen	Length of datagram 
	<-	unsigned long	*io_fhost	Foreign host
	<-	unsigned long	*io_lhost	Local host
	<-	ip_header_p		*io_iph	Pointer to raw IP header
	<-	Ptr				io_options	IP options
	->	struct timeval	*io_timeout	Timeout value
	<>	unsigned long	*io_flags	Flags

ip_get requests a buffer from an IP stream.  Note that io_buffer is allocated 
by the driver, but should be freed by the client (see ip_free).

If io_timeout is NULL, ip_get blocks until a datagram arrives.  If 
io_timeout is not NULL and a datagram is not available within the timeout 
period, ip_get returns an error.

If io_iph is not NULL, a pointer is returned to the IP header for the datagram.  
However, after io_buffer is deallocated (with ip_free), *io_iph is no 
longer guaranteed to be valid.  io_options must either be a NULL pointer or 
be preallocated by the client.  If NULL, no options are returned.

For the parameters io_fhost, io_lhost, and io_flags, the client may pass 
NULL if it does not need the returned values.

No values are currently defined for io_flags.

Errors returned are:
	E_BADSTREAM
	E_TIMEDOUT
	E_CANTBLOCK

ip_control (io_stream, io_buffer, io_buflen,io_control)
	->	Ptr				io_stream	IP stream descriptor
	<>	Ptr				io_buffer	Data used by control call
	<>	unsigned long	*io_buflen	Size of io_buffer (bytes)
	->	unsigned long	io_control	Specifies control operation

ip_control performs various operations for IP.  io_control selects an 
operation and is the only mandatory parameter.  Parameters that are not 
required by individual control operations may be passed as NULL.

General errors returned by ip_control are:
	E_BADSTREAM
	E_BADCONTROL

Currently defined control operations are:

IP_CTL_VERSION
		<>	io_buffer	Pointer to ip_version_t structure
		->	io_control	Control operation

Returns version information.  Clients pass a pointer to a 
preallocated structure of type ip_version_t, as defined in the 
section "IP DATA STRUCTURES."

No specific errors are returned for this control.


IP_CTL_STATS
		<>	io_buffer	Pointer to ip_stats_t structure
		->	io_control	Control operation

Returns statistics for IP.  Clients pass a pointer to a preallocated 
structure of type ip_stats_t, as defined in the section 
"IP DATA STRUCTURES."  This is a preliminary version of the 
final structure, and is subject to change in the near future.

No specific errors are returned for this control.


IP_CTL_GETADDR
		<>	io_buffer	Ptr to array of ip_addr_t structures
		->	*io_buflen	Size of array (bytes)
		->	io_control	Control operation

Returns a zero-terminated list of local IP addresses (net numbers 
and net masks).  Clients pass a pointer to a preallocated array of 
elements of type ip_addr_t, as defined in the section 
"IP DATA STRUCTURES."

No specific errors are returned for this control.


IP_CTL_LHOST
		<>	io_buffer	Points to IP address
		->	io_control	Control operation

Returns, through io_buffer, the local IP address that leads to the 
foreign IP address specified at input.

Specific errors returned by this control are:
	E_BADIPADDR


IP_CTL_MSS
		<>	io_buffer	Pointer to ip_mss_t structure
		->	io_control	Control operation

Returns the maximum segment size for an IP address.  Clients pass 
a pointer to a preallocated structure of type ip_mss_t, as defined in 
the section "IP DATA STRUCTURES."  Clients should specify 
an IP address in the addr field of the ip_mss_t structure.  If it is 
local, IP will return maximum segment size information for the 
network interface on that local address.  If it is foreign, IP first 
determines the appropriate local IP address.

Specific errors returned by this control are:
	E_BADIPADDR


ip_task ()

Clients should call ip_task periodically to allow IP time for asynchronous 
processing (e.g., to process incoming datagrams).

Errors returned are:
	E_CANTBLOCK


IP NOTIFICATION

Clients may request and cancel notification of asynchronous events by calling 
ip_request and ip_cancel, respectively.  As asynchronous events occur, 
the notification routine io_notify is called with the following parameters:

(*io_notify) (io_stream, io_buffer, io_buflen, io_fhost, 	
			  io_lhost, io_prot, io_nclass, io_ndata, 	
			  io_userdata)
	->	Ptr				io_stream
	->	Ptr				io_buffer
	->	unsigned long	io_buflen
	->	unsigned long	io_fhost
	->	unsigned long	io_lhost
	->	unsigned long	io_nclass
	->	unsigned long	io_ndata
	->	unsigned long	io_userdata

io_nclass is the type of event that caused this notification.  io_userdata 
was passed to ip_request by the client.  io_ndata contains additional 
specification for the event.

The following describes the valid notification classes (io_nclass):

IP_NT_DATA:  Data Arrival Notification
	->	io_stream
	->	io_fhost
	->	io_lhost
	->	io_nclass
	->	io_userdata

Data arrival notification is delivered when a datagram arrives from io_fhost 
on io_stream.

IP_NT_DELIVERY:  Data Delivery Notification
	->	io_stream
	->	io_buffer
	->	io_buflen
	->	io_fhost
	->	io_lhost
	->	io_nclass
	->	io_userdata

The client is notified of delivery of data from io_fhost on io_stream.  
io_buffer points to a datagram of length io_buflen.  This enables the client 
to immediately capture the data without calling ip_get.  The client is still 
responsible for calling ip_free when it no longer requires the delivered 
datagram.

IP_NT_ERROR:  Error Notification
	->	io_stream
	->	io_buffer
	->	io_buflen
	->	io_fhost
	->	io_lhost
	->	io_nclass
	->	io_ndata
	->	io_userdata

The client is notified when an asynchronous error occurs, (e.g., destination 
unreachable messages).  io_ndata identifies the error.  For all errors, an 
ICMP destination unreachable datagram is returned in io_buffer.  
io_buflen is the length of that datagram.  For more information on ICMP, 
refer to [RFC 792].

Errors delivered are:
	E_NETUN
	E_HOSTUN
	E_PROTOUN
	E_PORTUN


IP ERROR CODES

Following is a description of all possible error codes returned by IP:

	E_NOMEM
		Not enough memory to perform operation.
	E_PROTOINUSE
		Protocol number is already in use by another client.
	E_BADSTREAM
		Stream descriptor was not found in this driver's list of streams.
	E_BADNOTIFICATION
		Invalid notification class.
	E_BADFLAG
		Invalid control flag bit is set in io_flags.
	E_BADCONTROL
		Invalid control identifier.
	E_BADPTR
		Invalid pointer; could not verify that pointer points to valid data.
	E_BADWDS
		Invalid WDS structure or pointer.
	E_BADIPADDR
		Either destination IP address is invalid, or source IP address is 
		not on one of the interfaces.
	E_DTGTOOBIG
		Datagram is too long to be handled by this driver.
	E_CANTRESOLVEADDR
		Unable to determine the next destination IP address that leads to 
		the requested destination IP address.
	E_HWWRITEERR
		Hardware failed in writing datagram to network.
	E_CANTBLOCK
		Current context does not allow a blocking call.
Technical Details
Message-ID: <8710232228.AA10747@ucbvax.Berkeley.EDU>
Path: arc1-ca.pugleaf.net!utzoo!mnetor!uunet!husc6!hao!ames!ucbcad!ucbvax!CITI.UMICH.EDU!saf

Show Full Headers
Complete Article Headers
Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Path: arc1-ca.pugleaf.net!utzoo!mnetor!uunet!husc6!hao!ames!ucbcad!ucbvax!CITI.UMICH.EDU!saf
From: saf@CITI.UMICH.EDU
Newsgroups: comp.protocols.appletalk
Subject: IP specification (narrow)
Message-ID: <8710232228.AA10747@ucbvax.Berkeley.EDU>
Date: Fri, 23-Oct-87 14:20:00 EST
Article-I.D.: ucbvax.8710232228.AA10747
Posted: Fri Oct 23 14:20:00 1987
Date-Received: Sun, 25-Oct-87 18:45:43 EST
Sender: usenet@ucbvax.BERKELEY.EDU
Organization: The ARPA Internet
Lines: 537