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