SIP API spec
Bob Gilligan <Bob.Gilligan@eng.sun.com> Tue, 26 January 1993 02:30 UTC
Received: from ietf.nri.reston.va.us by IETF.CNRI.Reston.VA.US id aa20405; 25 Jan 93 21:30 EST
Received: from CNRI.RESTON.VA.US by IETF.CNRI.Reston.VA.US id aa20401; 25 Jan 93 21:30 EST
Received: from Sun.COM by CNRI.Reston.VA.US id aa06897; 25 Jan 93 21:32 EST
Received: from Eng.Sun.COM (zigzag-bb.Corp.Sun.COM) by Sun.COM (4.1/SMI-4.1) id AA21025; Mon, 25 Jan 93 18:30:18 PST
Received: from sunroof.Eng.Sun.COM by Eng.Sun.COM (4.1/SMI-4.1) id AA17731; Mon, 25 Jan 93 18:31:05 PST
Received: from bigriver.Eng.Sun.COM (bigriver-248) by sunroof.Eng.Sun.COM (4.1/SMI-4.1) id AA15867; Mon, 25 Jan 93 18:29:52 PST
Received: from kandinsky.Eng.Sun.COM by bigriver.Eng.Sun.COM (4.1/SMI-4.1) id AA06471; Mon, 25 Jan 93 18:23:37 PST
Date: Mon, 25 Jan 1993 18:23:37 -0800
Sender: ietf-archive-request@IETF.CNRI.Reston.VA.US
From: Bob Gilligan <Bob.Gilligan@eng.sun.com>
Message-Id: <9301260223.AA06471@bigriver.Eng.Sun.COM>
To: ip-encaps@sunroof.eng.sun.com, sip@caldera.usc.edu
Subject: SIP API spec
Content-Length: 13373
Here's a first draft of a spec for changes to BSD APIs to support SIP and IPAE. Send comments and suggestions to me. Internet Engineering Task Force Robert E. Gilligan INTERNET-DRAFT Sun Microsystems, Inc. January 25, 1992 SIP Program Interfaces for BSD Systems Abstract In order to implement the Simple Internet Protocol (SIP) in a 4.x BSD based operating system, changes must be made to some of the application program interfaces (APIs). The API changes need to be specified concretely so that SIP implementations in all BSD-based systems can provide the same API and thus provide portability for application software that makes use of SIP. This memo proposes a set of changes to the BSD networking APIs. This changes include a new data structure to carry 64-bit SIP addresses, a new name to address translation library function, and some new setsockopt() options. Status of this Memo This a draft internet-draft. Since this memo specifies APIs only, and not protocols, it is not intended to ever get onto the Internet standards track. 1. Introduction. The most visible feature of SIP is its extension of the length of an IP address from 32 bits to 64 bits. The APIs that the BSD system provide make the length of an IP address quite visible to an application. Virtually all TCP/IP applications for BSD-based systems have the length of an IP address hard-coded throughout. Thus it is not possible to implement SIP in a BSD-based system without some changes to the APIs. Some of the API changes presented here are based loosely on those implemented in the Sun IPAE/SIP prototype. These APIs are expected to change as we gain more implementation experience. 2. Design considerations There are two important considerations in designing changes to these well-worn APIs. First, the modified API should provide both source and binary compatibility for programs written to the existing API. The API changes for SIP should not cause existing program binaries to break, nor should they cause programs written to the existing APIs to fail to compile or break when re-compiled. Second, the changes should be as minimal as possible and should make it as easy as possible to change an existing application to be SIP knowledgeable. 2.1 What needs to be changed Since their address arguments are all opaque pointers, none of the socket system calls need to changed directly. The inet_addr structure is 4-bytes long and can not be changed without breaking applications. The sockaddr_in structure, which is passed into and returned by the socket functions, contains 8 bytes of unused space and thus can be extended to hold a SIP address without incompatibility. The gethostbyaddr() function includes an address type argument, so this function does not need to be changed. However, the gethostbyname() function does not include a type argument, and most applications that use it assume that the address array that it returns consists of 4-byte IP addresses. Thus a new function similar to gethostbyname(), but knowledgeable of SIP addresses, must be defined. Finally, a new interface is needed in order to set the SIP flow ID. The most straightforward way to do this is to define new setsockopt() options at the IPPROTO_IP level. 2.2 Implementation experience The Sun IPAE/SIP prototype exposed some of the issues in designing a compatible interface. The Sun prototype passed SIP addresses between the kernel and applications using the sockaddr_in structure with the sin_family field set to AF_INET. The kernel distinguished between 8-byte SIP addresses and 4-byte IPv4 addresses passed in passed in by checking at the sin_zero field. If sin_zero was zero, the kernel would assume that the sin_addr field held a 4-byte IPv4 address. If sin_zero was non-zero, it would assume that an 8-byte SIP address was being passed in. It would determine what form of addresses to pass out to the application based on the form of address used in the bind() or connect() call. If a SIP address was used in the bind(), the kernel would pass SIP address out in the socket system calls that return addresses. While this technique works for most existing applications, we concluded that it would be unworkable in the general case when we discovered that some applications do not set the sin_zero field of the sockaddr_in structure to zero. 3. Interface specification 3.1. New address family We define a address family macro in <sys/socket.h>: #define AF_SIP 23 /* Simple Internet Protocol */ 3.2 Sockaddr_in structure We change the definition of the sockaddr_in structure in <netinet/in.h>: struct sockaddr_in { short sin_family; u_short sin_port; union { in_addr sin_sin_addr; u_long sin_sip_zero; } sin_un1; union { u_long sin_sip_addr[2]; char sin_sin_zero[8]; } sin_un2; } #define sin_addr sin_un1.sin_sin_addr #define sin_zero sin_un2.sin_sin_zero #define sip_addr sin_un2.sin_sip_addr #define sip_zero sin_un1.sin_sip_zero The sin_family field can have two values: AF_INET or AF_SIP. If the sin_family is AF_SIP, then the sip_addr field contains a 8-byte SIP address and the sip_zero field is zero. If the sin_family field is AF_INET, then the sin_addr field contains a 4-byte IPv4 address and the sin_zero field is zero. A 4-byte IPv4 address can be represented in a sockaddr_in structure with sin_family set to AF_SIP. To do this, the low-order four bytes of the sip_addr field should be set to the the 4-byte IPv4 address, and the high-order 4 bytes of the sip_addr field should be set to zero. The two layouts can be understood better when viewed graphically. This is the AF_INET form of the sockaddr_in structure: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | AF_INET | port number | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | IPv4 address | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | + all zero bits + | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ And this is the layout of the AF_SIP form of the sockaddr_in structure: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | AF_SIP | port number | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | all zero bits | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | + SIP address + | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ We considered an alternative form that overlays the high-order four bytes of the SIP addr with sin_addr. The form presented has a few advantages: - The SIP address is aligned on a 64-bit boundary within the structure. - The kernel can do some consistency checking on AF_SIP addresses passed in. Because the sip_zero field, which overlays the sin_addr field, must always zero, the kernel can detect cases where the application incorrectly treats an AF_SIP form sockaddr_in as an AF_INET form. - The union declaration is simpler than the alternative. 3.3 The socket functions AF_SIP can be used interchangeably with AF_INET in the "domain" argument (the first argument) of the socket() function, e.g: s = socket (AF_SIP, SOCK_STREAM, 0); Using AF_SIP informs the kernel that the application would like to receive SIP addresses rather than IPv4 addresses in all system calls that return addresses. The functions that return internet addresses in arguments are: accept() recvfrom() getpeername() getsockname() In all other ways, sockets obtained using a domain argument of AF_SIP behave the same as those obtained using AF_INET in the domain argument. In particular, addresses in either the SIP form or the IPv4 form can be passed in to either type of socket in the system calls that pass in addresses as arguments. The socket functions that pass in addresses are: bind() connect() sendto() This interchangeability is necessary because Unix allows sockets to be passed to child processes across an exec() call. Thus it is possible for a pre-SIP application to obtain a socket using AF_INET, and then pass this socket to a SIP knowledgeable child process which then might do a system call (e.g. connect(), sendto()) that passes in an address. Note that there is still a problem with SIP knowledgeable applications passing AF_SIP sockets to an non-SIP knowledgeable application that then does a system call that returns an address. We are proposing the SIP_ADDRFORM option to remedy this problem: SIP knowledgeable applications can use the SIP_ADDRFORM option to "downgrade" an AF_SIP socket to AF_INET before it is passed via exec to an unknown process. And a SIP knowledgeable application that is passed in a socket from an unknown process, can use the SIP_ADDRFORM option to "upgrade" the socket to AF_SIP before doing any system calls that return addresses. 3.4 Setsockopt options We define two options at the IPPROTO_IP level that can be used with AF_INET or AF_SIP sockets. They have the following definitions in <netinet/in.h>: #define SIP_FLOWID 0x15 /* get/set SIP flow ID */ #define SIP_ADDRFORM 0x16 /* get/set form of returned addrs */ Using the SIP_FLOWID option via setsockopt() sets the value of the flow ID (a.k.a the SIP reserved field) used in all outgoing SIP packets sent via that socket. Using SIP_FLOWID via getsockopt() returns the flow ID value given in the last setsockopt() call, not the flow ID in received packets. The value of the argument to the SIP_FLOWID option is a u_long type. Using the SIP_ADDRFORM option via setsockopt() tells the kernel the form of addresses (SIP or IPv4) that are to be returned in the system calls that return addresses. Using the SIP_ADDRFORM option via the getsockopt() call informs the application in what form the kernel will be returning addresses. The value of the argument to the SIP_ADDRFORM option is a u_long type. The only valid arguments that may be passed or returned by the SIP_ADDRFORM option are AF_INET and AF_SIP. 3.5 Name-to-address translation functions We create a new function call with the form: struct hostent *gethostbyname2(const char *name, int type); This interface looks the given host name up in the naming service and returns a list of addresses. The type argument is used to determine what form of address -- 4-byte IPv4 or 8-byte SIP address -- to return to the caller in the h_addr_list field of the hostent structure. If the type argument is AF_INET, gethostbyname2() behaves to the application exactly like gethostbyname(). That is, it returns an array of 4-byte IPv4 addresses. If AA records are found, then the low-order 4 bytes of each SIP address are returned. If only A records are found, then the associated 4-byte IP address is returned. If the type argument is AF_SIP, then the h_addr_list contains an array of 8-byte SIP addresses. If AA records are found, then the full SIP address of each record is returned. If only A records are found, then each 8-byte address returned is composed by copying the 4-byte IP address in the A record into the low-order 4 bytes, and setting the high-order 4-bytes to zero. This interface is adapted from one proposed by Christian Huitema in an email message to the SIP mailing list. Christian's proposal had the application determine the form of the returned address (4-byte IPv4 or 8-byte SIP) based on the return value of the function. This proposal allows the application to be simpler, since it can always unconditionally bcopy() an 8-byte address returned by gethostbyname2() into a sockaddr_in. Also, the semantics of the gethostbyname2() with type set to AF_INET lets us implement the existing gethostbyname() function in terms of the new function. The gethostbyaddr() function remains unchanged: struct hostent *gethostbyaddr(const char *addr, int len, int type); If type is AF_INET, then len must be 4 and addr points to a 4-byte IPv4 address. If type is AF_SIP, then len must be 8 and addr points to an 8-byte SIP address. 3.6 Open Issues The API changes described here are just the beginning. Among the other changes we might want to consider are: - There is a type defined (in_addr) to represent a 32-bit IPv4 address. Should we define a structure to hold the 64-bit SIP address? - There are a number of functions (inet_addr(), inet_ntoa()) for translating IPv4 addresses to and from printable form. Should we define similar functions for 64-bit SIP addresses? - The format of the "/etc/hosts" file currently supports only IPv4 addresses. Should we extend the format of the existing file to handle SIP addresses? Or should we invent a file with a new name for storing SIP host addresses. - The name of the function gethostbyname2() might confuse people. Should we pick a different name?
- SIP API spec Bob Gilligan
- Re: SIP API spec Christian Huitema
- re: SIP API spec Craig Partridge
- Re: SIP API spec Steve Deering
- Re: SIP API spec Craig Partridge
- Re: SIP API spec Christian Huitema
- Re: SIP API spec Bob Gilligan
- Re: SIP API spec Noel Chiappa
- Re: SIP API spec Bob Gilligan
- Re: SIP API spec Noel Chiappa
- Re: SIP API spec stev knowles