add Berkeley specific copyright notice
[unix-history] / usr / src / share / doc / psd / 21.ipc / 3.t
CommitLineData
d60e8dff
MK
1.\" Copyright (c) 1986 Regents of the University of California.
2.\" All rights reserved. The Berkeley software License Agreement
3.\" specifies the terms and conditions for redistribution.
4.\"
6d89475b 5.\" @(#)3.t 1.4 (Berkeley) %G%
d60e8dff 6.\"
6d89475b 7.\".ds RH "Network Library Routines
200989e9
MK
8.bp
9.nr H1 3
10.nr H2 0
11.bp
12.LG
13.B
14.ce
153. NETWORK LIBRARY ROUTINES
16.sp 2
17.R
18.NL
19.PP
20The discussion in section 2 indicated the possible need to
21locate and construct network addresses when using the
22interprocess communication facilities in a distributed
23environment. To aid in this task a number of routines
24have been added to the standard C run-time library.
25In this section we will consider the new routines provided
d60e8dff
MK
26to manipulate network addresses. While the 4.3BSD networking
27facilities support both the DARPA standard Internet protocols
28and the Xerox NS protocols, most of the routines presented
29in this section do not apply to the NS domain. Unless otherwise
30stated, it should be assumed that the routines presented in this
31section do not apply to the NS domain.
200989e9
MK
32.PP
33Locating a service on a remote host requires many levels of
34mapping before client and server may
35communicate. A service is assigned a name which is intended
36for human consumption; e.g. \*(lqthe \fIlogin server\fP on host
37monet\*(rq.
38This name, and the name of the peer host, must then be translated
39into network \fIaddresses\fP which are not necessarily suitable
40for human consumption. Finally, the address must then used in locating
41a physical \fIlocation\fP and \fIroute\fP to the service. The
d60e8dff 42specifics of these three mappings are likely to vary between
200989e9 43network architectures. For instance, it is desirable for a network
d60e8dff 44to not require hosts to
200989e9
MK
45be named in such a way that their physical location is known by
46the client host. Instead, underlying services in the network
47may discover the actual location of the host at the time a client
48host wishes to communicate. This ability to have hosts named in
49a location independent manner may induce overhead in connection
50establishment, as a discovery process must take place,
51but allows a host to be physically mobile without requiring it to
52notify its clientele of its current location.
53.PP
54Standard routines are provided for: mapping host names
55to network addresses, network names to network numbers,
56protocol names to protocol numbers, and service names
57to port numbers and the appropriate protocol to
58use in communicating with the server process. The
59file <\fInetdb.h\fP> must be included when using any of these
60routines.
61.NH 2
62Host names
63.PP
d60e8dff 64An Internet host name to address mapping is represented by
200989e9
MK
65the \fIhostent\fP structure:
66.DS
d60e8dff 67.if t .ta 0.6i 1.1i 2.6i
200989e9
MK
68struct hostent {
69 char *h_name; /* official name of host */
70 char **h_aliases; /* alias list */
d60e8dff 71 int h_addrtype; /* host address type (e.g., AF_INET) */
200989e9 72 int h_length; /* length of address */
d60e8dff 73 char **h_addr_list; /* list of addresses, null terminated */
200989e9 74};
d60e8dff
MK
75
76#define h_addr h_addr_list[0] /* first address, network byte order */
200989e9 77.DE
d60e8dff 78The routine \fIgethostbyname\fP(3N) takes an Internet host name
200989e9
MK
79and returns a \fIhostent\fP structure,
80while the routine \fIgethostbyaddr\fP(3N)
d60e8dff
MK
81maps Internet host addresses into a \fIhostent\fP structure.
82.PP
83The official name of the host and its public aliases are
84returned by these routines,
85along with the address type (family) and a null terminated list of
86variable length address. This list of addresses is
87required because it is possible
200989e9 88for a host to have many addresses, all having the same name.
d60e8dff
MK
89The \fIh_addr\fP definition is provided for backward compatibility,
90and is defined to be the first address in the list of addresses
91in the \fIhostent\fP structure.
92.PP
93The database for these calls is provided either by the
6d89475b
MK
94file \fI/etc/hosts\fP (\fIhosts\fP\|(5)),
95or by use of a nameserver, \fInamed\fP\|(8).
96Because of the differences in these databases and their access protocols,
97the information returned may differ.
98When using the host table version of \fIgethostbyname\fP,
99only one address will be returned, but all listed aliases will be included.
100The nameserver version may return alternate addresses,
101but will not provide any aliases other than one given as argument.
d60e8dff
MK
102.PP
103Unlike Internet names, NS names are always mapped into host
104addresses by the use of a standard NS \fIClearinghouse service\fP,
105a distributed name and authentication server. The algorithms
106for mapping NS names to addresses via a Clearinghouse are
107rather complicated, and the routines are not part of the
108standard libraries. The user-contributed Courier (Xerox
109remote procedure call protocol) compiler contains routines
110to accomplish this mapping; see the documentation and
111examples provided therein for more information. It is
112expected that almost all software that has to communicate
113using NS will need to use the facilities of
114the Courier compiler.
115.PP
6d89475b 116An NS host address is represented by the following:
d60e8dff
MK
117.DS
118union ns_host {
119 u_char c_host[6];
120 u_short s_host[3];
121};
122
123union ns_net {
124 u_char c_net[4];
125 u_short s_net[2];
126};
127
128struct ns_addr {
129 union ns_net x_net;
130 union ns_host x_host;
131 u_short x_port;
132};
133.DE
134The following code fragment inserts a known NS address into
135a \fIns_addr\fP:
136.DS
137#include <sys/types.h>
138#include <sys/socket.h>
139#include <netns/ns.h>
140 ...
141u_long netnum;
142struct sockaddr_ns dst;
143 ...
144bzero((char *)&dst, sizeof(dst));
145
146/*
147 * There is no convenient way to assign a long
148 * integer to a ``union ns_net'' at present; in
149 * the future, something will hopefully be provided,
150 * but this is the portable way to go for now.
3c0dec46
MK
151 * The network number below is the one for the NS net
152 * that the desired host (gyre) is on.
d60e8dff
MK
153 */
154netnum = htonl(2266);
155dst.sns_addr.x_net = *(union ns_net *) &netnum;
156dst.sns_family = AF_NS;
157
158/*
159 * host 2.7.1.0.2a.18 == "gyre:Computer Science:UofMaryland"
160 */
161dst.sns_addr.x_host.c_host[0] = 0x02;
162dst.sns_addr.x_host.c_host[1] = 0x07;
163dst.sns_addr.x_host.c_host[2] = 0x01;
164dst.sns_addr.x_host.c_host[3] = 0x00;
165dst.sns_addr.x_host.c_host[4] = 0x2a;
166dst.sns_addr.x_host.c_host[5] = 0x18;
167dst.sns_addr.x_port = htons(75);
168.DE
200989e9
MK
169.NH 2
170Network names
171.PP
172As for host names, routines for mapping network names to numbers,
173and back, are provided. These routines return a \fInetent\fP
174structure:
175.DS
176.DT
177/*
178 * Assumption here is that a network number
179 * fits in 32 bits -- probably a poor one.
180 */
181struct netent {
182 char *n_name; /* official name of net */
183 char **n_aliases; /* alias list */
184 int n_addrtype; /* net address type */
d60e8dff 185 int n_net; /* network number, host byte order */
200989e9
MK
186};
187.DE
188The routines \fIgetnetbyname\fP(3N), \fIgetnetbynumber\fP(3N),
189and \fIgetnetent\fP(3N) are the network counterparts to the
d60e8dff
MK
190host routines described above. The routines extract their
191information from \fI/etc/networks\fP.
192.PP
193NS network numbers are determined either by asking your local
194Xerox Network Administrator (and hardcoding the information
195into your code), or by querying the Clearinghouse for addresses.
196The internetwork router is the only process
197that needs to manipulate network numbers on a regular basis; if
198a process wishes to communicate with a machine, it should ask the
199Clearinghouse for that machine's address (which will include
200the net number).
200989e9
MK
201.NH 2
202Protocol names
203.PP
d60e8dff
MK
204For protocols, which are defined in \fI/etc/protocols\fP,
205the \fIprotoent\fP structure defines the
200989e9
MK
206protocol-name mapping
207used with the routines \fIgetprotobyname\fP(3N),
208\fIgetprotobynumber\fP(3N),
209and \fIgetprotoent\fP(3N):
210.DS
211.DT
212struct protoent {
213 char *p_name; /* official protocol name */
214 char **p_aliases; /* alias list */
d60e8dff 215 int p_proto; /* protocol number */
200989e9
MK
216};
217.DE
d60e8dff
MK
218.PP
219In the NS domain, protocols are indicated by the "client type"
220field of a IDP header. No protocol database exists; see section
2215 for more information.
200989e9
MK
222.NH 2
223Service names
224.PP
225Information regarding services is a bit more complicated. A service
226is expected to reside at a specific \*(lqport\*(rq and employ
227a particular communication protocol. This view is consistent with
228the Internet domain, but inconsistent with other network architectures.
d60e8dff
MK
229Further, a service may reside on multiple ports.
230If this occurs, the higher level library routines
6d89475b 231will have to be bypassed or extended.
d60e8dff 232Services available are contained in the file \fI/etc/services\fP.
200989e9
MK
233A service mapping is described by the \fIservent\fP structure,
234.DS
235.DT
236struct servent {
237 char *s_name; /* official service name */
238 char **s_aliases; /* alias list */
d60e8dff 239 int s_port; /* port number, network byte order */
200989e9
MK
240 char *s_proto; /* protocol to use */
241};
242.DE
243The routine \fIgetservbyname\fP(3N) maps service
244names to a servent structure by specifying a service name and,
245optionally, a qualifying protocol. Thus the call
246.DS
d60e8dff 247sp = getservbyname("telnet", (char *) 0);
200989e9
MK
248.DE
249returns the service specification for a telnet server using
250any protocol, while the call
251.DS
252sp = getservbyname("telnet", "tcp");
253.DE
254returns only that telnet server which uses the TCP protocol.
255The routines \fIgetservbyport\fP(3N) and \fIgetservent\fP(3N) are
256also provided. The \fIgetservbyport\fP routine has an interface similar
257to that provided by \fIgetservbyname\fP; an optional protocol name may
258be specified to qualify lookups.
d60e8dff
MK
259.PP
260In the NS domain, services are handled by a central dispatcher
261provided as part of the Courier remote procedure call facilities.
262Again, the reader is referred to the Courier compiler documentation
263and to the Xerox standard*
264.FS
265* \fICourier: The Remote Procedure Call Protocol\fP, XSIS 038112.
266.FE
267for further details.
200989e9
MK
268.NH 2
269Miscellaneous
270.PP
d60e8dff 271With the support routines described above, an Internet application program
200989e9
MK
272should rarely have to deal directly
273with addresses. This allows
274services to be developed as much as possible in a network independent
275fashion. It is clear, however, that purging all network dependencies
276is very difficult. So long as the user is required to supply network
277addresses when naming services and sockets there will always some
278network dependency in a program. For example, the normal
279code included in client programs, such as the remote login program,
280is of the form shown in Figure 1.
200989e9
MK
281(This example will be considered in more detail in section 4.)
282.PP
283If we wanted to make the remote login program independent of the
284Internet protocols and addressing scheme we would be forced to add
285a layer of routines which masked the network dependent aspects from
286the mainstream login code. For the current facilities available in
d60e8dff 287the system this does not appear to be worthwhile.
200989e9
MK
288.PP
289Aside from the address-related data base routines, there are several
290other routines available in the run-time library which are of interest
291to users. These are intended mostly to simplify manipulation of
292names and addresses. Table 1 summarizes the routines
293for manipulating variable length byte strings and handling byte
294swapping of network addresses and values.
295.KF
296.DS B
297.TS
298box;
299l | l
300l | l.
301Call Synopsis
302_
303bcmp(s1, s2, n) compare byte-strings; 0 if same, not 0 otherwise
304bcopy(s1, s2, n) copy n bytes from s1 to s2
305bzero(base, n) zero-fill n bytes starting at base
306htonl(val) convert 32-bit quantity from host to network byte order
307htons(val) convert 16-bit quantity from host to network byte order
308ntohl(val) convert 32-bit quantity from network to host byte order
309ntohs(val) convert 16-bit quantity from network to host byte order
310.TE
311.DE
312.ce
313Table 1. C run-time routines.
314.KE
315.PP
316The byte swapping routines are provided because the operating
d60e8dff
MK
317system expects addresses to be supplied in network order. On
318some architectures, such as the VAX,
319host byte ordering is different than
320network byte ordering. Consequently,
200989e9
MK
321programs are sometimes required to byte swap quantities. The
322library routines which return network addresses provide them
323in network order so that they may simply be copied into the structures
324provided to the system. This implies users should encounter the
325byte swapping problem only when \fIinterpreting\fP network addresses.
326For example, if an Internet port is to be printed out the following
327code would be required:
328.DS
329printf("port number %d\en", ntohs(sp->s_port));
330.DE
d60e8dff 331On machines where unneeded these routines are defined as null
200989e9 332macros.
d60e8dff
MK
333.DS
334.if t .ta .5i 1.0i 1.5i 2.0i
335.if n .ta .7i 1.4i 2.1i 2.8i
336#include <sys/types.h>
337#include <sys/socket.h>
338#include <netinet/in.h>
339#include <stdio.h>
340#include <netdb.h>
341 ...
342main(argc, argv)
343 int argc;
344 char *argv[];
345{
346 struct sockaddr_in server;
347 struct servent *sp;
348 struct hostent *hp;
349 int s;
350 ...
351 sp = getservbyname("login", "tcp");
352 if (sp == NULL) {
353 fprintf(stderr, "rlogin: tcp/login: unknown service\en");
354 exit(1);
355 }
356 hp = gethostbyname(argv[1]);
357 if (hp == NULL) {
358 fprintf(stderr, "rlogin: %s: unknown host\en", argv[1]);
359 exit(2);
360 }
361 bzero((char *)&server, sizeof (server));
362 bcopy(hp->h_addr, (char *)&server.sin_addr, hp->h_length);
363 server.sin_family = hp->h_addrtype;
364 server.sin_port = sp->s_port;
365 s = socket(AF_INET, SOCK_STREAM, 0);
366 if (s < 0) {
367 perror("rlogin: socket");
368 exit(3);
369 }
370 ...
371 /* Connect does the bind() for us */
372
373 if (connect(s, (char *)&server, sizeof (server)) < 0) {
374 perror("rlogin: connect");
375 exit(5);
376 }
377 ...
378}
379.DE
380.ce
381Figure 1. Remote login client code.