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