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