Deleted Added
full compact
rpc.prog.ms (106143) rpc.prog.ms (108533)
1.\"
2.\" Must use -- tbl and pic -- with this one
3.\"
4.\" @(#)rpc.prog.ms 2.3 88/08/11 4.0 RPCSRC
1.\"
2.\" Must use -- tbl and pic -- with this one
3.\"
4.\" @(#)rpc.prog.ms 2.3 88/08/11 4.0 RPCSRC
5.\" $FreeBSD: head/lib/libc/rpc/PSD.doc/rpc.prog.ms 106143 2002-10-29 14:56:09Z ru $
5.\" $FreeBSD: head/lib/libc/rpc/PSD.doc/rpc.prog.ms 108533 2003-01-01 18:49:04Z schweikh $
6.\"
7.de BT
8.if \\n%=1 .tl ''- % -''
9..
10.nr OF 0
11.ND
12.\" prevent excess underlining in nroff
13.if n .fp 2 R

--- 4 unchanged lines hidden (view full) ---

18.nr OF 1
19.IX "Network Programming" "" "" "" PAGE MAJOR
20.IX "RPC Programming Guide"
21.LP
22This document assumes a working knowledge of network theory. It is
23intended for programmers who wish to write network applications using
24remote procedure calls (explained below), and who want to understand
25the RPC mechanisms usually hidden by the
6.\"
7.de BT
8.if \\n%=1 .tl ''- % -''
9..
10.nr OF 0
11.ND
12.\" prevent excess underlining in nroff
13.if n .fp 2 R

--- 4 unchanged lines hidden (view full) ---

18.nr OF 1
19.IX "Network Programming" "" "" "" PAGE MAJOR
20.IX "RPC Programming Guide"
21.LP
22This document assumes a working knowledge of network theory. It is
23intended for programmers who wish to write network applications using
24remote procedure calls (explained below), and who want to understand
25the RPC mechanisms usually hidden by the
26.I rpcgen(1)
26.I rpcgen(1)
27protocol compiler.
27protocol compiler.
28.I rpcgen
28.I rpcgen
29is described in detail in the previous chapter, the
30.I "\fBrpcgen\fP \fIProgramming Guide\fP".
31.SH
32Note:
33.I
34.IX rpcgen "" \fIrpcgen\fP
35Before attempting to write a network application, or to convert an
36existing non-network application to run over the network, you may want to
37understand the material in this chapter. However, for most applications,
38you can circumvent the need to cope with the details presented here by using
39.I rpcgen .
40The
41.I "Generating XDR Routines"
42section of that chapter contains the complete source for a working RPC
43service\(ema remote directory listing service which uses
29is described in detail in the previous chapter, the
30.I "\fBrpcgen\fP \fIProgramming Guide\fP".
31.SH
32Note:
33.I
34.IX rpcgen "" \fIrpcgen\fP
35Before attempting to write a network application, or to convert an
36existing non-network application to run over the network, you may want to
37understand the material in this chapter. However, for most applications,
38you can circumvent the need to cope with the details presented here by using
39.I rpcgen .
40The
41.I "Generating XDR Routines"
42section of that chapter contains the complete source for a working RPC
43service\(ema remote directory listing service which uses
44.I rpcgen
44.I rpcgen
45to generate XDR routines as well as client and server stubs.
46.LP
47.LP
48What are remote procedure calls? Simply put, they are the high-level
49communications paradigm used in the operating system.
50RPC presumes the existence of
51low-level networking mechanisms (such as TCP/IP and UDP/IP), and upon them
52it implements a logical client to server communications system designed

--- 6 unchanged lines hidden (view full) ---

59\&Layers of RPC
60.IX "layers of RPC"
61.IX "RPC" "layers"
62.LP
63The RPC interface can be seen as being divided into three layers.\**
64.FS
65For a complete specification of the routines in the remote procedure
66call Library, see the
45to generate XDR routines as well as client and server stubs.
46.LP
47.LP
48What are remote procedure calls? Simply put, they are the high-level
49communications paradigm used in the operating system.
50RPC presumes the existence of
51low-level networking mechanisms (such as TCP/IP and UDP/IP), and upon them
52it implements a logical client to server communications system designed

--- 6 unchanged lines hidden (view full) ---

59\&Layers of RPC
60.IX "layers of RPC"
61.IX "RPC" "layers"
62.LP
63The RPC interface can be seen as being divided into three layers.\**
64.FS
65For a complete specification of the routines in the remote procedure
66call Library, see the
67.I rpc(3N)
67.I rpc(3N)
68manual page.
69.FE
70.LP
71.I "The Highest Layer:"
72.IX RPC "The Highest Layer"
68manual page.
69.FE
70.LP
71.I "The Highest Layer:"
72.IX RPC "The Highest Layer"
73The highest layer is totally transparent to the operating system,
74machine and network upon which is is run. It's probably best to
73The highest layer is totally transparent to the operating system,
74machine and network upon which is is run. It's probably best to
75think of this level as a way of
76.I using
77RPC, rather than as
75think of this level as a way of
76.I using
77RPC, rather than as
78a \fIpart of\fP RPC proper. Programmers who write RPC routines
79should (almost) always make this layer available to others by way
78a \fIpart of\fP RPC proper. Programmers who write RPC routines
79should (almost) always make this layer available to others by way
80of a simple C front end that entirely hides the networking.
80of a simple C front end that entirely hides the networking.
81.LP
81.LP
82To illustrate, at this level a program can simply make a call to
83.I rnusers (),
84a C routine which returns the number of users on a remote machine.
82To illustrate, at this level a program can simply make a call to
83.I rnusers (),
84a C routine which returns the number of users on a remote machine.
85The user is not explicitly aware of using RPC \(em they simply
85The user is not explicitly aware of using RPC \(em they simply
86call a procedure, just as they would call
87.I malloc() .
88.LP
89.I "The Middle Layer:"
90.IX RPC "The Middle Layer"
91The middle layer is really \*QRPC proper.\*U Here, the user doesn't
86call a procedure, just as they would call
87.I malloc() .
88.LP
89.I "The Middle Layer:"
90.IX RPC "The Middle Layer"
91The middle layer is really \*QRPC proper.\*U Here, the user doesn't
92need to consider details about sockets, the UNIX system, or other low-level
92need to consider details about sockets, the UNIX system, or other low-level
93implementation mechanisms. They simply make remote procedure calls
93implementation mechanisms. They simply make remote procedure calls
94to routines on other machines. The selling point here is simplicity.
94to routines on other machines. The selling point here is simplicity.
95It's this layer that allows RPC to pass the \*Qhello world\*U test \(em
95It's this layer that allows RPC to pass the \*Qhello world\*U test \(em
96simple things should be simple. The middle-layer routines are used
96simple things should be simple. The middle-layer routines are used
97for most applications.
98.LP
99RPC calls are made with the system routines
100.I registerrpc()
101.I callrpc()
102and
103.I svc_run ().
104The first two of these are the most fundamental:
97for most applications.
98.LP
99RPC calls are made with the system routines
100.I registerrpc()
101.I callrpc()
102and
103.I svc_run ().
104The first two of these are the most fundamental:
105.I registerrpc()
105.I registerrpc()
106obtains a unique system-wide procedure-identification number, and
106obtains a unique system-wide procedure-identification number, and
107.I callrpc()
108actually executes a remote procedure call. At the middle level, a
109call to
107.I callrpc()
108actually executes a remote procedure call. At the middle level, a
109call to
110.I rnusers()
111is implemented by way of these two routines.
112.LP
110.I rnusers()
111is implemented by way of these two routines.
112.LP
113The middle layer is unfortunately rarely used in serious programming
114due to its inflexibility (simplicity). It does not allow timeout
113The middle layer is unfortunately rarely used in serious programming
114due to its inflexibility (simplicity). It does not allow timeout
115specifications or the choice of transport. It allows no UNIX
116process control or flexibility in case of errors. It doesn't support
115specifications or the choice of transport. It allows no UNIX
116process control or flexibility in case of errors. It doesn't support
117multiple kinds of call authentication. The programmer rarely needs
117multiple kinds of call authentication. The programmer rarely needs
118all these kinds of control, but one or two of them is often necessary.
119.LP
120.I "The Lowest Layer:"
121.IX RPC "The Lowest Layer"
118all these kinds of control, but one or two of them is often necessary.
119.LP
120.I "The Lowest Layer:"
121.IX RPC "The Lowest Layer"
122The lowest layer does allow these details to be controlled by the
123programmer, and for that reason it is often necessary. Programs
122The lowest layer does allow these details to be controlled by the
123programmer, and for that reason it is often necessary. Programs
124written at this level are also most efficient, but this is rarely a
124written at this level are also most efficient, but this is rarely a
125real issue \(em since RPC clients and servers rarely generate
125real issue \(em since RPC clients and servers rarely generate
126heavy network loads.
127.LP
128Although this document only discusses the interface to C,
129remote procedure calls can be made from any language.
130Even though this document discusses RPC
131when it is used to communicate
132between processes on different machines,
133it works just as well for communication

--- 64 unchanged lines hidden (view full) ---

198 exit(-1);
199 }
200 printf("%d users on %s\en", num, argv[1]);
201 exit(0);
202}
203.DE
204.KE
205RPC library routines such as
126heavy network loads.
127.LP
128Although this document only discusses the interface to C,
129remote procedure calls can be made from any language.
130Even though this document discusses RPC
131when it is used to communicate
132between processes on different machines,
133it works just as well for communication

--- 64 unchanged lines hidden (view full) ---

198 exit(-1);
199 }
200 printf("%d users on %s\en", num, argv[1]);
201 exit(0);
202}
203.DE
204.KE
205RPC library routines such as
206.I rnusers()
206.I rnusers()
207are in the RPC services library
208.I librpcsvc.a
209Thus, the program above should be compiled with
210.DS
211.ft CW
212% cc \fIprogram.c -lrpcsvc\fP
213.DE
214.I rnusers (),
207are in the RPC services library
208.I librpcsvc.a
209Thus, the program above should be compiled with
210.DS
211.ft CW
212% cc \fIprogram.c -lrpcsvc\fP
213.DE
214.I rnusers (),
215like the other RPC library routines, is documented in section 3R
215like the other RPC library routines, is documented in section 3R
216of the
217.I "System Interface Manual for the Sun Workstation" ,
216of the
217.I "System Interface Manual for the Sun Workstation" ,
218the same section which documents the standard Sun RPC services.
218the same section which documents the standard Sun RPC services.
219.IX "RPC Services"
219.IX "RPC Services"
220See the
221.I intro(3R)
222manual page for an explanation of the documentation strategy
220See the
221.I intro(3R)
222manual page for an explanation of the documentation strategy
223for these services and their RPC protocols.
224.LP
223for these services and their RPC protocols.
224.LP
225Here are some of the RPC service library routines available to the
225Here are some of the RPC service library routines available to the
226C programmer:
227.LP
228\fBTable 3-3\fI RPC Service Library Routines\fR
229.TS
230box tab (&) ;
231cfI cfI
232lfL l .
233Routine&Description

--- 12 unchanged lines hidden (view full) ---

246.I mount
247.I rquota()
248and
249.I spray
250\(em are not available to the C programmer as library routines.
251They do, however,
252have RPC program numbers so they can be invoked with
253.I callrpc()
226C programmer:
227.LP
228\fBTable 3-3\fI RPC Service Library Routines\fR
229.TS
230box tab (&) ;
231cfI cfI
232lfL l .
233Routine&Description

--- 12 unchanged lines hidden (view full) ---

246.I mount
247.I rquota()
248and
249.I spray
250\(em are not available to the C programmer as library routines.
251They do, however,
252have RPC program numbers so they can be invoked with
253.I callrpc()
254which will be discussed in the next section. Most of them also
255have compilable
256.I rpcgen(1)
254which will be discussed in the next section. Most of them also
255have compilable
256.I rpcgen(1)
257protocol description files. (The
258.I rpcgen
259protocol compiler radically simplifies the process of developing
257protocol description files. (The
258.I rpcgen
259protocol compiler radically simplifies the process of developing
260network applications.
260network applications.
261See the \fBrpcgen\fI Programming Guide\fR
261See the \fBrpcgen\fI Programming Guide\fR
262for detailed information about
263.I rpcgen
264and
265.I rpcgen
262for detailed information about
263.I rpcgen
264and
265.I rpcgen
266protocol description files).
267.KS
268.NH 2
269\&Intermediate Layer
270.IX "intermediate layer of RPC"
271.IX "RPC" "intermediate layer"
272.LP
266protocol description files).
267.KS
268.NH 2
269\&Intermediate Layer
270.IX "intermediate layer of RPC"
271.IX "RPC" "intermediate layer"
272.LP
273The simplest interface, which explicitly makes RPC calls, uses the
273The simplest interface, which explicitly makes RPC calls, uses the
274functions
275.I callrpc()
276and
277.I registerrpc()
278Using this method, the number of remote users can be gotten as follows:
279.ie t .DS
280.el .DS L
281#include <stdio.h>

--- 18 unchanged lines hidden (view full) ---

300 clnt_perrno(stat);
301 exit(1);
302 }
303 printf("%d users on %s\en", nusers, argv[1]);
304 exit(0);
305}
306.DE
307.KE
274functions
275.I callrpc()
276and
277.I registerrpc()
278Using this method, the number of remote users can be gotten as follows:
279.ie t .DS
280.el .DS L
281#include <stdio.h>

--- 18 unchanged lines hidden (view full) ---

300 clnt_perrno(stat);
301 exit(1);
302 }
303 printf("%d users on %s\en", nusers, argv[1]);
304 exit(0);
305}
306.DE
307.KE
308Each RPC procedure is uniquely defined by a program number,
309version number, and procedure number. The program number
310specifies a group of related remote procedures, each of
311which has a different procedure number. Each program also
312has a version number, so when a minor change is made to a
313remote service (adding a new procedure, for example), a new
314program number doesn't have to be assigned. When you want
315to call a procedure to find the number of remote users, you
308Each RPC procedure is uniquely defined by a program number,
309version number, and procedure number. The program number
310specifies a group of related remote procedures, each of
311which has a different procedure number. Each program also
312has a version number, so when a minor change is made to a
313remote service (adding a new procedure, for example), a new
314program number doesn't have to be assigned. When you want
315to call a procedure to find the number of remote users, you
316look up the appropriate program, version and procedure numbers
316look up the appropriate program, version and procedure numbers
317in a manual, just as you look up the name of a memory allocator
317in a manual, just as you look up the name of a memory allocator
318when you want to allocate memory.
319.LP
318when you want to allocate memory.
319.LP
320The simplest way of making remote procedure calls is with the the RPC
320The simplest way of making remote procedure calls is with the the RPC
321library routine
322.I callrpc()
321library routine
322.I callrpc()
323It has eight parameters. The first is the name of the remote server
324machine. The next three parameters are the program, version, and procedure
323It has eight parameters. The first is the name of the remote server
324machine. The next three parameters are the program, version, and procedure
325numbers\(emtogether they identify the procedure to be called.
326The fifth and sixth parameters are an XDR filter and an argument to
325numbers\(emtogether they identify the procedure to be called.
326The fifth and sixth parameters are an XDR filter and an argument to
327be encoded and passed to the remote procedure.
328The final two parameters are a filter for decoding the results
329returned by the remote procedure and a pointer to the place where
327be encoded and passed to the remote procedure.
328The final two parameters are a filter for decoding the results
329returned by the remote procedure and a pointer to the place where
330the procedure's results are to be stored. Multiple arguments and
330the procedure's results are to be stored. Multiple arguments and
331results are handled by embedding them in structures. If
332.I callrpc()
333completes successfully, it returns zero; else it returns a nonzero
331results are handled by embedding them in structures. If
332.I callrpc()
333completes successfully, it returns zero; else it returns a nonzero
334value. The return codes (of type
335.IX "enum clnt_stat (in RPC programming)" "" "\fIenum clnt_stat\fP (in RPC programming)"
334value. The return codes (of type
335.IX "enum clnt_stat (in RPC programming)" "" "\fIenum clnt_stat\fP (in RPC programming)"
336cast into an integer) are found in
336cast into an integer) are found in
337.I <rpc/clnt.h> .
338.LP
339Since data types may be represented differently on different machines,
337.I <rpc/clnt.h> .
338.LP
339Since data types may be represented differently on different machines,
340.I callrpc()
340.I callrpc()
341needs both the type of the RPC argument, as well as
342a pointer to the argument itself (and similarly for the result). For
343.I RUSERSPROC_NUM ,
344the return value is an
345.I "unsigned long"
346so
341needs both the type of the RPC argument, as well as
342a pointer to the argument itself (and similarly for the result). For
343.I RUSERSPROC_NUM ,
344the return value is an
345.I "unsigned long"
346so
347.I callrpc()
347.I callrpc()
348has
348has
349.I xdr_u_long()
349.I xdr_u_long()
350as its first return parameter, which says
351that the result is of type
352.I "unsigned long"
353and
350as its first return parameter, which says
351that the result is of type
352.I "unsigned long"
353and
354.I &nusers
354.I &nusers
355as its second return parameter,
356which is a pointer to where the long result will be placed. Since
355as its second return parameter,
356which is a pointer to where the long result will be placed. Since
357.I RUSERSPROC_NUM
357.I RUSERSPROC_NUM
358takes no argument, the argument parameter of
358takes no argument, the argument parameter of
359.I callrpc()
359.I callrpc()
360is
361.I xdr_void ().
362.LP
363After trying several times to deliver a message, if
360is
361.I xdr_void ().
362.LP
363After trying several times to deliver a message, if
364.I callrpc()
364.I callrpc()
365gets no answer, it returns with an error code.
366The delivery mechanism is UDP,
367which stands for User Datagram Protocol.
368Methods for adjusting the number of retries
369or for using a different protocol require you to use the lower
370layer of the RPC library, discussed later in this document.
371The remote server procedure
372corresponding to the above might look like this:

--- 51 unchanged lines hidden (view full) ---

424.LP
425The
426.I registerrpc()
427routine registers a C procedure as corresponding to a
428given RPC procedure number. The first three parameters,
429.I RUSERPROG ,
430.I RUSERSVERS ,
431and
365gets no answer, it returns with an error code.
366The delivery mechanism is UDP,
367which stands for User Datagram Protocol.
368Methods for adjusting the number of retries
369or for using a different protocol require you to use the lower
370layer of the RPC library, discussed later in this document.
371The remote server procedure
372corresponding to the above might look like this:

--- 51 unchanged lines hidden (view full) ---

424.LP
425The
426.I registerrpc()
427routine registers a C procedure as corresponding to a
428given RPC procedure number. The first three parameters,
429.I RUSERPROG ,
430.I RUSERSVERS ,
431and
432.I RUSERSPROC_NUM
432.I RUSERSPROC_NUM
433are the program, version, and procedure numbers
434of the remote procedure to be registered;
433are the program, version, and procedure numbers
434of the remote procedure to be registered;
435.I nuser()
435.I nuser()
436is the name of the local procedure that implements the remote
437procedure; and
436is the name of the local procedure that implements the remote
437procedure; and
438.I xdr_void()
438.I xdr_void()
439and
439and
440.I xdr_u_long()
440.I xdr_u_long()
441are the XDR filters for the remote procedure's arguments and
442results, respectively. (Multiple arguments or multiple results
443are passed as structures).
444.LP
445Only the UDP transport mechanism can use
446.I registerrpc()
447thus, it is always safe in conjunction with calls generated by
448.I callrpc() .
449.SH
450.IX "UDP 8K warning"
451Warning: the UDP transport mechanism can only deal with
452arguments and results less than 8K bytes in length.
453.LP
454.LP
455After registering the local procedure, the server program's
456main procedure calls
457.I svc_run (),
441are the XDR filters for the remote procedure's arguments and
442results, respectively. (Multiple arguments or multiple results
443are passed as structures).
444.LP
445Only the UDP transport mechanism can use
446.I registerrpc()
447thus, it is always safe in conjunction with calls generated by
448.I callrpc() .
449.SH
450.IX "UDP 8K warning"
451Warning: the UDP transport mechanism can only deal with
452arguments and results less than 8K bytes in length.
453.LP
454.LP
455After registering the local procedure, the server program's
456main procedure calls
457.I svc_run (),
458the RPC library's remote procedure dispatcher. It is this
458the RPC library's remote procedure dispatcher. It is this
459function that calls the remote procedures in response to RPC
460call messages. Note that the dispatcher takes care of decoding
461remote procedure arguments and encoding results, using the XDR
462filters specified when the remote procedure was registered.
463.NH 2
464\&Assigning Program Numbers
465.IX "program number assignment"
466.IX "assigning program numbers"
467.LP
459function that calls the remote procedures in response to RPC
460call messages. Note that the dispatcher takes care of decoding
461remote procedure arguments and encoding results, using the XDR
462filters specified when the remote procedure was registered.
463.NH 2
464\&Assigning Program Numbers
465.IX "program number assignment"
466.IX "assigning program numbers"
467.LP
468Program numbers are assigned in groups of
469.I 0x20000000
468Program numbers are assigned in groups of
469.I 0x20000000
470according to the following chart:
471.DS
472.ft CW
473 0x0 - 0x1fffffff \fRDefined by Sun\fP
4740x20000000 - 0x3fffffff \fRDefined by user\fP
4750x40000000 - 0x5fffffff \fRTransient\fP
4760x60000000 - 0x7fffffff \fRReserved\fP
4770x80000000 - 0x9fffffff \fRReserved\fP

--- 8 unchanged lines hidden (view full) ---

486application should be given an assigned number in the first
487range. The second group of numbers is reserved for specific
488customer applications. This range is intended primarily for
489debugging new programs. The third group is reserved for
490applications that generate program numbers dynamically. The
491final groups are reserved for future use, and should not be
492used.
493.LP
470according to the following chart:
471.DS
472.ft CW
473 0x0 - 0x1fffffff \fRDefined by Sun\fP
4740x20000000 - 0x3fffffff \fRDefined by user\fP
4750x40000000 - 0x5fffffff \fRTransient\fP
4760x60000000 - 0x7fffffff \fRReserved\fP
4770x80000000 - 0x9fffffff \fRReserved\fP

--- 8 unchanged lines hidden (view full) ---

486application should be given an assigned number in the first
487range. The second group of numbers is reserved for specific
488customer applications. This range is intended primarily for
489debugging new programs. The third group is reserved for
490applications that generate program numbers dynamically. The
491final groups are reserved for future use, and should not be
492used.
493.LP
494To register a protocol specification, send a request by network
494To register a protocol specification, send a request by network
495mail to
496.I rpc@sun
497or write to:
498.DS
499RPC Administrator
500Sun Microsystems
5012550 Garcia Ave.
502Mountain View, CA 94043
503.DE
495mail to
496.I rpc@sun
497or write to:
498.DS
499RPC Administrator
500Sun Microsystems
5012550 Garcia Ave.
502Mountain View, CA 94043
503.DE
504Please include a compilable
505.I rpcgen
504Please include a compilable
505.I rpcgen
506\*Q.x\*U file describing your protocol.
507You will be given a unique program number in return.
508.IX RPC administration
509.IX administration "of RPC"
510.LP
506\*Q.x\*U file describing your protocol.
507You will be given a unique program number in return.
508.IX RPC administration
509.IX administration "of RPC"
510.LP
511The RPC program numbers and protocol specifications
511The RPC program numbers and protocol specifications
512of standard Sun RPC services can be
512of standard Sun RPC services can be
513found in the include files in
513found in the include files in
514.I "/usr/include/rpcsvc" .
514.I "/usr/include/rpcsvc" .
515These services, however, constitute only a small subset
516of those which have been registered. The complete list of
517registered programs, as of the time when this manual was
515These services, however, constitute only a small subset
516of those which have been registered. The complete list of
517registered programs, as of the time when this manual was
518printed, is:
519.LP
520\fBTable 3-2\fI RPC Registered Programs\fR
521.TS H
522box tab (&) ;
523lfBI lfBI lfBI
524lfL lfL lfI .
525RPC Number&Program&Description
526_
527.TH
528.sp .5
529100000&PMAPPROG&portmapper
518printed, is:
519.LP
520\fBTable 3-2\fI RPC Registered Programs\fR
521.TS H
522box tab (&) ;
523lfBI lfBI lfBI
524lfL lfL lfI .
525RPC Number&Program&Description
526_
527.TH
528.sp .5
529100000&PMAPPROG&portmapper
530100001&RSTATPROG&remote stats
531100002&RUSERSPROG&remote users
532100003&NFSPROG&nfs
533100004&YPPROG&Yellow Pages
534100005&MOUNTPROG&mount daemon
535100006&DBXPROG&remote dbx
536100007&YPBINDPROG&yp binder
537100008&WALLPROG&shutdown msg
538100009&YPPASSWDPROG&yppasswd server
539100010&ETHERSTATPROG&ether stats
540100011&RQUOTAPROG&disk quotas
541100012&SPRAYPROG&spray packets
542100013&IBM3270PROG&3270 mapper
543100014&IBMRJEPROG&RJE mapper
544100015&SELNSVCPROG&selection service
545100016&RDATABASEPROG&remote database access
546100017&REXECPROG&remote execution
547100018&ALICEPROG&Alice Office Automation
548100019&SCHEDPROG&scheduling service
549100020&LOCKPROG&local lock manager
550100021&NETLOCKPROG&network lock manager
551100022&X25PROG&x.25 inr protocol
552100023&STATMON1PROG&status monitor 1
553100024&STATMON2PROG&status monitor 2
554100025&SELNLIBPROG&selection library
555100026&BOOTPARAMPROG&boot parameters service
556100027&MAZEPROG&mazewars game
557100028&YPUPDATEPROG&yp update
558100029&KEYSERVEPROG&key server
559100030&SECURECMDPROG&secure login
560100031&NETFWDIPROG&nfs net forwarder init
561100032&NETFWDTPROG&nfs net forwarder trans
562100033&SUNLINKMAP_PROG&sunlink MAP
563100034&NETMONPROG&network monitor
564100035&DBASEPROG&lightweight database
565100036&PWDAUTHPROG&password authorization
566100037&TFSPROG&translucent file svc
567100038&NSEPROG&nse server
568100039&NSE_ACTIVATE_PROG&nse activate daemon
530100001&RSTATPROG&remote stats
531100002&RUSERSPROG&remote users
532100003&NFSPROG&nfs
533100004&YPPROG&Yellow Pages
534100005&MOUNTPROG&mount daemon
535100006&DBXPROG&remote dbx
536100007&YPBINDPROG&yp binder
537100008&WALLPROG&shutdown msg
538100009&YPPASSWDPROG&yppasswd server
539100010ÐERSTATPROGðer stats
540100011&RQUOTAPROG&disk quotas
541100012&SPRAYPROG&spray packets
542100013&IBM3270PROG&3270 mapper
543100014&IBMRJEPROG&RJE mapper
544100015&SELNSVCPROG&selection service
545100016&RDATABASEPROG&remote database access
546100017&REXECPROG&remote execution
547100018&ALICEPROG&Alice Office Automation
548100019&SCHEDPROG&scheduling service
549100020&LOCKPROG&local lock manager
550100021&NETLOCKPROG&network lock manager
551100022&X25PROG&x.25 inr protocol
552100023&STATMON1PROG&status monitor 1
553100024&STATMON2PROG&status monitor 2
554100025&SELNLIBPROG&selection library
555100026&BOOTPARAMPROG&boot parameters service
556100027&MAZEPROG&mazewars game
557100028&YPUPDATEPROG&yp update
558100029&KEYSERVEPROG&key server
559100030&SECURECMDPROG&secure login
560100031&NETFWDIPROG&nfs net forwarder init
561100032&NETFWDTPROG&nfs net forwarder trans
562100033&SUNLINKMAP_PROG&sunlink MAP
563100034&NETMONPROG&network monitor
564100035&DBASEPROG&lightweight database
565100036&PWDAUTHPROG&password authorization
566100037&TFSPROG&translucent file svc
567100038&NSEPROG&nse server
568100039&NSE_ACTIVATE_PROG&nse activate daemon
569.sp .2i
569.sp .2i
570150001&PCNFSDPROG&pc passwd authorization
570150001&PCNFSDPROG&pc passwd authorization
571.sp .2i
571.sp .2i
572200000&PYRAMIDLOCKINGPROG&Pyramid-locking
573200001&PYRAMIDSYS5&Pyramid-sys5
574200002&CADDS_IMAGE&CV cadds_image
572200000&PYRAMIDLOCKINGPROG&Pyramid-locking
573200001&PYRAMIDSYS5&Pyramid-sys5
574200002&CADDS_IMAGE&CV cadds_image
575.sp .2i
575.sp .2i
576300001&ADT_RFLOCKPROG&ADT file locking
576300001&ADT_RFLOCKPROG&ADT file locking
577.TE
578.NH 2
579\&Passing Arbitrary Data Types
580.IX "arbitrary data types"
581.LP
582In the previous example, the RPC call passes a single
583.I "unsigned long"
584RPC can handle arbitrary data structures, regardless of
585different machines' byte orders or structure layout conventions,
586by always converting them to a network standard called
587.I "External Data Representation"
588(XDR) before
589sending them over the wire.
590The process of converting from a particular machine representation
591to XDR format is called
592.I serializing ,
593and the reverse process is called
594.I deserializing .
595The type field parameters of
577.TE
578.NH 2
579\&Passing Arbitrary Data Types
580.IX "arbitrary data types"
581.LP
582In the previous example, the RPC call passes a single
583.I "unsigned long"
584RPC can handle arbitrary data structures, regardless of
585different machines' byte orders or structure layout conventions,
586by always converting them to a network standard called
587.I "External Data Representation"
588(XDR) before
589sending them over the wire.
590The process of converting from a particular machine representation
591to XDR format is called
592.I serializing ,
593and the reverse process is called
594.I deserializing .
595The type field parameters of
596.I callrpc()
596.I callrpc()
597and
597and
598.I registerrpc()
598.I registerrpc()
599can be a built-in procedure like
599can be a built-in procedure like
600.I xdr_u_long()
600.I xdr_u_long()
601in the previous example, or a user supplied one.
602XDR has these built-in type routines:
603.IX RPC "built-in routines"
604.DS
605.ft CW
606xdr_int() xdr_u_int() xdr_enum()
607xdr_long() xdr_u_long() xdr_bool()
608xdr_short() xdr_u_short() xdr_wrapstring()
609xdr_char() xdr_u_char()
610.DE
611Note that the routine
601in the previous example, or a user supplied one.
602XDR has these built-in type routines:
603.IX RPC "built-in routines"
604.DS
605.ft CW
606xdr_int() xdr_u_int() xdr_enum()
607xdr_long() xdr_u_long() xdr_bool()
608xdr_short() xdr_u_short() xdr_wrapstring()
609xdr_char() xdr_u_char()
610.DE
611Note that the routine
612.I xdr_string()
613exists, but cannot be used with
614.I callrpc()
612.I xdr_string()
613exists, but cannot be used with
614.I callrpc()
615and
616.I registerrpc (),
617which only pass two parameters to their XDR routines.
615and
616.I registerrpc (),
617which only pass two parameters to their XDR routines.
618.I xdr_wrapstring()
619has only two parameters, and is thus OK. It calls
618.I xdr_wrapstring()
619has only two parameters, and is thus OK. It calls
620.I xdr_string ().
621.LP
622As an example of a user-defined type routine,
623if you wanted to send the structure
624.DS
625.ft CW
626struct simple {
627 int a;
628 short b;
629} simple;
630.DE
631then you would call
620.I xdr_string ().
621.LP
622As an example of a user-defined type routine,
623if you wanted to send the structure
624.DS
625.ft CW
626struct simple {
627 int a;
628 short b;
629} simple;
630.DE
631then you would call
632.I callrpc()
632.I callrpc()
633as
634.DS
635.ft CW
636callrpc(hostname, PROGNUM, VERSNUM, PROCNUM,
637 xdr_simple, &simple ...);
638.DE
639where
633as
634.DS
635.ft CW
636callrpc(hostname, PROGNUM, VERSNUM, PROCNUM,
637 xdr_simple, &simple ...);
638.DE
639where
640.I xdr_simple()
640.I xdr_simple()
641is written as:
642.ie t .DS
643.el .DS L
644.ft CW
645#include <rpc/rpc.h>
646
647xdr_simple(xdrsp, simplep)
648 XDR *xdrsp;
649 struct simple *simplep;
650{
651 if (!xdr_int(xdrsp, &simplep->a))
652 return (0);
653 if (!xdr_short(xdrsp, &simplep->b))
654 return (0);
655 return (1);
656}
657.DE
658.LP
641is written as:
642.ie t .DS
643.el .DS L
644.ft CW
645#include <rpc/rpc.h>
646
647xdr_simple(xdrsp, simplep)
648 XDR *xdrsp;
649 struct simple *simplep;
650{
651 if (!xdr_int(xdrsp, &simplep->a))
652 return (0);
653 if (!xdr_short(xdrsp, &simplep->b))
654 return (0);
655 return (1);
656}
657.DE
658.LP
659An XDR routine returns nonzero (true in the sense of C) if it
659An XDR routine returns nonzero (true in the sense of C) if it
660completes successfully, and zero otherwise.
661A complete description of XDR is in the
660completes successfully, and zero otherwise.
661A complete description of XDR is in the
662.I "XDR Protocol Specification"
663section of this manual, only few implementation examples are
662.I "XDR Protocol Specification"
663section of this manual, only few implementation examples are
664given here.
665.LP
666In addition to the built-in primitives,
667there are also the prefabricated building blocks:
668.DS
669.ft CW
670xdr_array() xdr_bytes() xdr_reference()
671xdr_vector() xdr_union() xdr_pointer()

--- 10 unchanged lines hidden (view full) ---

682.DE
683and make an RPC call such as
684.DS
685.ft CW
686callrpc(hostname, PROGNUM, VERSNUM, PROCNUM,
687 xdr_varintarr, &arr...);
688.DE
689with
664given here.
665.LP
666In addition to the built-in primitives,
667there are also the prefabricated building blocks:
668.DS
669.ft CW
670xdr_array() xdr_bytes() xdr_reference()
671xdr_vector() xdr_union() xdr_pointer()

--- 10 unchanged lines hidden (view full) ---

682.DE
683and make an RPC call such as
684.DS
685.ft CW
686callrpc(hostname, PROGNUM, VERSNUM, PROCNUM,
687 xdr_varintarr, &arr...);
688.DE
689with
690.I xdr_varintarr()
690.I xdr_varintarr()
691defined as:
692.ie t .DS
693.el .DS L
694.ft CW
695xdr_varintarr(xdrsp, arrp)
696 XDR *xdrsp;
697 struct varintarr *arrp;
698{
691defined as:
692.ie t .DS
693.el .DS L
694.ft CW
695xdr_varintarr(xdrsp, arrp)
696 XDR *xdrsp;
697 struct varintarr *arrp;
698{
699 return (xdr_array(xdrsp, &arrp->data, &arrp->arrlnth,
699 return (xdr_array(xdrsp, &arrp->data, &arrp->arrlnth,
700 MAXLEN, sizeof(int), xdr_int));
701}
702.DE
703This routine takes as parameters the XDR handle,
704a pointer to the array, a pointer to the size of the array,
705the maximum allowable array size,
706the size of each array element,
707and an XDR routine for handling each array element.

--- 22 unchanged lines hidden (view full) ---

730XDR always converts quantities to 4-byte multiples when serializing.
731Thus, if either of the examples above involved characters
732instead of integers, each character would occupy 32 bits.
733That is the reason for the XDR routine
734.I xdr_bytes()
735which is like
736.I xdr_array()
737except that it packs characters;
700 MAXLEN, sizeof(int), xdr_int));
701}
702.DE
703This routine takes as parameters the XDR handle,
704a pointer to the array, a pointer to the size of the array,
705the maximum allowable array size,
706the size of each array element,
707and an XDR routine for handling each array element.

--- 22 unchanged lines hidden (view full) ---

730XDR always converts quantities to 4-byte multiples when serializing.
731Thus, if either of the examples above involved characters
732instead of integers, each character would occupy 32 bits.
733That is the reason for the XDR routine
734.I xdr_bytes()
735which is like
736.I xdr_array()
737except that it packs characters;
738.I xdr_bytes()
738.I xdr_bytes()
739has four parameters, similar to the first four parameters of
740.I xdr_array ().
741For null-terminated strings, there is also the
742.I xdr_string()
743routine, which is the same as
739has four parameters, similar to the first four parameters of
740.I xdr_array ().
741For null-terminated strings, there is also the
742.I xdr_string()
743routine, which is the same as
744.I xdr_bytes()
744.I xdr_bytes()
745without the length parameter.
746On serializing it gets the string length from
747.I strlen (),
748and on deserializing it creates a null-terminated string.
749.LP
750Here is a final example that calls the previously written
745without the length parameter.
746On serializing it gets the string length from
747.I strlen (),
748and on deserializing it creates a null-terminated string.
749.LP
750Here is a final example that calls the previously written
751.I xdr_simple()
751.I xdr_simple()
752as well as the built-in functions
752as well as the built-in functions
753.I xdr_string()
753.I xdr_string()
754and
755.I xdr_reference (),
756which chases pointers:
757.ie t .DS
758.el .DS L
759.ft CW
760struct finalexample {
761 char *string;

--- 9 unchanged lines hidden (view full) ---

771 return (0);
772 if (!xdr_reference(xdrsp, &finalp->simplep,
773 sizeof(struct simple), xdr_simple);
774 return (0);
775 return (1);
776}
777.DE
778Note that we could as easily call
754and
755.I xdr_reference (),
756which chases pointers:
757.ie t .DS
758.el .DS L
759.ft CW
760struct finalexample {
761 char *string;

--- 9 unchanged lines hidden (view full) ---

771 return (0);
772 if (!xdr_reference(xdrsp, &finalp->simplep,
773 sizeof(struct simple), xdr_simple);
774 return (0);
775 return (1);
776}
777.DE
778Note that we could as easily call
779.I xdr_simple()
779.I xdr_simple()
780here instead of
781.I xdr_reference ().
782.NH 1
783\&Lowest Layer of RPC
784.IX "lowest layer of RPC"
785.IX "RPC" "lowest layer"
786.LP
787In the examples given so far,
788RPC takes care of many details automatically for you.
789In this section, we'll show you how you can change the defaults
790by using lower layers of the RPC library.
791It is assumed that you are familiar with sockets
792and the system calls for dealing with them.
793.LP
780here instead of
781.I xdr_reference ().
782.NH 1
783\&Lowest Layer of RPC
784.IX "lowest layer of RPC"
785.IX "RPC" "lowest layer"
786.LP
787In the examples given so far,
788RPC takes care of many details automatically for you.
789In this section, we'll show you how you can change the defaults
790by using lower layers of the RPC library.
791It is assumed that you are familiar with sockets
792and the system calls for dealing with them.
793.LP
794There are several occasions when you may need to use lower layers of
795RPC. First, you may need to use TCP, since the higher layer uses UDP,
796which restricts RPC calls to 8K bytes of data. Using TCP permits calls
797to send long streams of data.
794There are several occasions when you may need to use lower layers of
795RPC. First, you may need to use TCP, since the higher layer uses UDP,
796which restricts RPC calls to 8K bytes of data. Using TCP permits calls
797to send long streams of data.
798For an example, see the
799.I TCP
800section below. Second, you may want to allocate and free memory
798For an example, see the
799.I TCP
800section below. Second, you may want to allocate and free memory
801while serializing or deserializing with XDR routines.
802There is no call at the higher level to let
803you free memory explicitly.
801while serializing or deserializing with XDR routines.
802There is no call at the higher level to let
803you free memory explicitly.
804For more explanation, see the
805.I "Memory Allocation with XDR"
804For more explanation, see the
805.I "Memory Allocation with XDR"
806section below.
807Third, you may need to perform authentication
808on either the client or server side, by supplying
806section below.
807Third, you may need to perform authentication
808on either the client or server side, by supplying
809credentials or verifying them.
809credentials or verifying them.
810See the explanation in the
810See the explanation in the
811.I Authentication
812section below.
813.NH 2
814\&More on the Server Side
815.IX RPC "server side"
816.LP
817The server for the
811.I Authentication
812section below.
813.NH 2
814\&More on the Server Side
815.IX RPC "server side"
816.LP
817The server for the
818.I nusers()
818.I nusers()
819program shown below does the same thing as the one using
819program shown below does the same thing as the one using
820.I registerrpc()
820.I registerrpc()
821above, but is written using a lower layer of the RPC package:
822.ie t .DS
823.el .DS L
824.ft CW
825#include <stdio.h>
826#include <rpc/rpc.h>
827#include <utmp.h>
828#include <rpcsvc/rusers.h>

--- 31 unchanged lines hidden (view full) ---

860 return;
861 case RUSERSPROC_NUM:
862.ft I
863 /*
864 * Code here to compute the number of users
865 * and assign it to the variable \fInusers\fP
866 */
867.ft CW
821above, but is written using a lower layer of the RPC package:
822.ie t .DS
823.el .DS L
824.ft CW
825#include <stdio.h>
826#include <rpc/rpc.h>
827#include <utmp.h>
828#include <rpcsvc/rusers.h>

--- 31 unchanged lines hidden (view full) ---

860 return;
861 case RUSERSPROC_NUM:
862.ft I
863 /*
864 * Code here to compute the number of users
865 * and assign it to the variable \fInusers\fP
866 */
867.ft CW
868 if (!svc_sendreply(transp, xdr_u_long, &nusers))
868 if (!svc_sendreply(transp, xdr_u_long, &nusers))
869 fprintf(stderr, "can't reply to RPC call\en");
870 return;
871 default:
872 svcerr_noproc(transp);
873 return;
874 }
875}
876.DE
877.LP
878First, the server gets a transport handle, which is used
879for receiving and replying to RPC messages.
869 fprintf(stderr, "can't reply to RPC call\en");
870 return;
871 default:
872 svcerr_noproc(transp);
873 return;
874 }
875}
876.DE
877.LP
878First, the server gets a transport handle, which is used
879for receiving and replying to RPC messages.
880.I registerrpc()
880.I registerrpc()
881uses
882.I svcudp_create()
883to get a UDP handle.
884If you require a more reliable protocol, call
885.I svctcp_create()
886instead.
887If the argument to
881uses
882.I svcudp_create()
883to get a UDP handle.
884If you require a more reliable protocol, call
885.I svctcp_create()
886instead.
887If the argument to
888.I svcudp_create()
888.I svcudp_create()
889is
890.I RPC_ANYSOCK
891the RPC library creates a socket
892on which to receive and reply to RPC calls. Otherwise,
889is
890.I RPC_ANYSOCK
891the RPC library creates a socket
892on which to receive and reply to RPC calls. Otherwise,
893.I svcudp_create()
893.I svcudp_create()
894expects its argument to be a valid socket number.
895If you specify your own socket, it can be bound or unbound.
896If it is bound to a port by the user, the port numbers of
894expects its argument to be a valid socket number.
895If you specify your own socket, it can be bound or unbound.
896If it is bound to a port by the user, the port numbers of
897.I svcudp_create()
897.I svcudp_create()
898and
899.I clnttcp_create()
900(the low-level client routine) must match.
901.LP
902If the user specifies the
898and
899.I clnttcp_create()
900(the low-level client routine) must match.
901.LP
902If the user specifies the
903.I RPC_ANYSOCK
903.I RPC_ANYSOCK
904argument, the RPC library routines will open sockets.
905Otherwise they will expect the user to do so. The routines
904argument, the RPC library routines will open sockets.
905Otherwise they will expect the user to do so. The routines
906.I svcudp_create()
907and
906.I svcudp_create()
907and
908.I clntudp_create()
909will cause the RPC library routines to
908.I clntudp_create()
909will cause the RPC library routines to
910.I bind()
910.I bind()
911their socket if it is not bound already.
912.LP
913A service may choose to register its port number with the
914local portmapper service. This is done is done by specifying
915a non-zero protocol number in
916.I svc_register ().
911their socket if it is not bound already.
912.LP
913A service may choose to register its port number with the
914local portmapper service. This is done is done by specifying
915a non-zero protocol number in
916.I svc_register ().
917Incidently, a client can discover the server's port number by
918consulting the portmapper on their server's machine. This can
919be done automatically by specifying a zero port number in
920.I clntudp_create()
917Incidently, a client can discover the server's port number by
918consulting the portmapper on their server's machine. This can
919be done automatically by specifying a zero port number in
920.I clntudp_create()
921or
922.I clnttcp_create ().
923.LP
924After creating an
925.I SVCXPRT ,
926the next step is to call
927.I pmap_unset()
928so that if the
921or
922.I clnttcp_create ().
923.LP
924After creating an
925.I SVCXPRT ,
926the next step is to call
927.I pmap_unset()
928so that if the
929.I nusers()
929.I nusers()
930server crashed earlier,
931any previous trace of it is erased before restarting.
932More precisely,
930server crashed earlier,
931any previous trace of it is erased before restarting.
932More precisely,
933.I pmap_unset()
933.I pmap_unset()
934erases the entry for
935.I RUSERSPROG
936from the port mapper's tables.
937.LP
938Finally, we associate the program number for
934erases the entry for
935.I RUSERSPROG
936from the port mapper's tables.
937.LP
938Finally, we associate the program number for
939.I nusers()
939.I nusers()
940with the procedure
941.I nuser ().
942The final argument to
940with the procedure
941.I nuser ().
942The final argument to
943.I svc_register()
943.I svc_register()
944is normally the protocol being used,
945which, in this case, is
946.I IPPROTO_UDP
947Notice that unlike
948.I registerrpc (),
949there are no XDR routines involved
950in the registration process.
951Also, registration is done on the program,
952rather than procedure, level.
953.LP
954The user routine
944is normally the protocol being used,
945which, in this case, is
946.I IPPROTO_UDP
947Notice that unlike
948.I registerrpc (),
949there are no XDR routines involved
950in the registration process.
951Also, registration is done on the program,
952rather than procedure, level.
953.LP
954The user routine
955.I nuser()
955.I nuser()
956must call and dispatch the appropriate XDR routines
957based on the procedure number.
958Note that
959two things are handled by
956must call and dispatch the appropriate XDR routines
957based on the procedure number.
958Note that
959two things are handled by
960.I nuser()
960.I nuser()
961that
961that
962.I registerrpc()
962.I registerrpc()
963handles automatically.
964The first is that procedure
965.I NULLPROC
966(currently zero) returns with no results.
967This can be used as a simple test
968for detecting if a remote program is running.
969Second, there is a check for invalid procedure numbers.
970If one is detected,

--- 10 unchanged lines hidden (view full) ---

981and the third is a pointer to the data to be returned.
982Not illustrated above is how a server
983handles an RPC program that receives data.
984As an example, we can add a procedure
985.I RUSERSPROC_BOOL
986which has an argument
987.I nusers (),
988and returns
963handles automatically.
964The first is that procedure
965.I NULLPROC
966(currently zero) returns with no results.
967This can be used as a simple test
968for detecting if a remote program is running.
969Second, there is a check for invalid procedure numbers.
970If one is detected,

--- 10 unchanged lines hidden (view full) ---

981and the third is a pointer to the data to be returned.
982Not illustrated above is how a server
983handles an RPC program that receives data.
984As an example, we can add a procedure
985.I RUSERSPROC_BOOL
986which has an argument
987.I nusers (),
988and returns
989.I TRUE
989.I TRUE
990or
990or
991.I FALSE
991.I FALSE
992depending on whether there are nusers logged on.
993It would look like this:
994.ie t .DS
995.el .DS L
996.ft CW
997case RUSERSPROC_BOOL: {
998 int bool;
999 unsigned nuserquery;

--- 98 unchanged lines hidden (view full) ---

1098/*
1099 * Use the result here
1100 */
1101.ft CW
1102svc_freeargs(transp, xdr_chararr2, &arrptr);
1103.DE
1104Note that, after being used, the character array can be freed with
1105.I svc_freeargs()
992depending on whether there are nusers logged on.
993It would look like this:
994.ie t .DS
995.el .DS L
996.ft CW
997case RUSERSPROC_BOOL: {
998 int bool;
999 unsigned nuserquery;

--- 98 unchanged lines hidden (view full) ---

1098/*
1099 * Use the result here
1100 */
1101.ft CW
1102svc_freeargs(transp, xdr_chararr2, &arrptr);
1103.DE
1104Note that, after being used, the character array can be freed with
1105.I svc_freeargs()
1106.I svc_freeargs()
1107will not attempt to free any memory if the variable indicating it
1108is NULL. For example, in the the routine
1106.I svc_freeargs()
1107will not attempt to free any memory if the variable indicating it
1108is NULL. For example, in the the routine
1109.I xdr_finalexample (),
1110given earlier, if
1109.I xdr_finalexample (),
1110given earlier, if
1111.I finalp->string
1112was NULL, then it would not be freed. The same is true for
1111.I finalp->string
1112was NULL, then it would not be freed. The same is true for
1113.I finalp->simplep .
1114.LP
1115To summarize, each XDR routine is responsible
1116for serializing, deserializing, and freeing memory.
1117When an XDR routine is called from
1118.I callrpc()
1119the serializing part is used.
1120When called from
1121.I svc_getargs()
1122the deserializer is used.
1123And when called from
1124.I svc_freeargs()
1125the memory deallocator is used. When building simple examples like those
1113.I finalp->simplep .
1114.LP
1115To summarize, each XDR routine is responsible
1116for serializing, deserializing, and freeing memory.
1117When an XDR routine is called from
1118.I callrpc()
1119the serializing part is used.
1120When called from
1121.I svc_getargs()
1122the deserializer is used.
1123And when called from
1124.I svc_freeargs()
1125the memory deallocator is used. When building simple examples like those
1126in this section, a user doesn't have to worry
1127about the three modes.
1126in this section, a user doesn't have to worry
1127about the three modes.
1128See the
1129.I "External Data Representation: Sun Technical Notes"
1128See the
1129.I "External Data Representation: Sun Technical Notes"
1130for examples of more sophisticated XDR routines that determine
1130for examples of more sophisticated XDR routines that determine
1131which of the three modes they are in and adjust their behavior accordingly.
1132.KS
1133.NH 2
1134\&The Calling Side
1135.IX RPC "calling side"
1136.LP
1137When you use
1138.I callrpc()

--- 63 unchanged lines hidden (view full) ---

1202.KE
1203The low-level version of
1204.I callrpc()
1205is
1206.I clnt_call()
1207which takes a
1208.I CLIENT
1209pointer rather than a host name. The parameters to
1131which of the three modes they are in and adjust their behavior accordingly.
1132.KS
1133.NH 2
1134\&The Calling Side
1135.IX RPC "calling side"
1136.LP
1137When you use
1138.I callrpc()

--- 63 unchanged lines hidden (view full) ---

1202.KE
1203The low-level version of
1204.I callrpc()
1205is
1206.I clnt_call()
1207which takes a
1208.I CLIENT
1209pointer rather than a host name. The parameters to
1210.I clnt_call()
1210.I clnt_call()
1211are a
1211are a
1212.I CLIENT
1212.I CLIENT
1213pointer, the procedure number,
1214the XDR routine for serializing the argument,
1215a pointer to the argument,
1216the XDR routine for deserializing the return value,
1217a pointer to where the return value will be placed,
1218and the time in seconds to wait for a reply.
1219.LP
1220The
1213pointer, the procedure number,
1214the XDR routine for serializing the argument,
1215a pointer to the argument,
1216the XDR routine for deserializing the return value,
1217a pointer to where the return value will be placed,
1218and the time in seconds to wait for a reply.
1219.LP
1220The
1221.I CLIENT
1221.I CLIENT
1222pointer is encoded with the transport mechanism.
1223.I callrpc()
1224uses UDP, thus it calls
1222pointer is encoded with the transport mechanism.
1223.I callrpc()
1224uses UDP, thus it calls
1225.I clntudp_create()
1225.I clntudp_create()
1226to get a
1226to get a
1227.I CLIENT
1227.I CLIENT
1228pointer. To get TCP (Transmission Control Protocol), you would use
1229.I clnttcp_create() .
1230.LP
1231The parameters to
1228pointer. To get TCP (Transmission Control Protocol), you would use
1229.I clnttcp_create() .
1230.LP
1231The parameters to
1232.I clntudp_create()
1232.I clntudp_create()
1233are the server address, the program number, the version number,
1234a timeout value (between tries), and a pointer to a socket.
1235The final argument to
1233are the server address, the program number, the version number,
1234a timeout value (between tries), and a pointer to a socket.
1235The final argument to
1236.I clnt_call()
1236.I clnt_call()
1237is the total time to wait for a response.
1238Thus, the number of tries is the
1237is the total time to wait for a response.
1238Thus, the number of tries is the
1239.I clnt_call()
1239.I clnt_call()
1240timeout divided by the
1240timeout divided by the
1241.I clntudp_create()
1241.I clntudp_create()
1242timeout.
1243.LP
1244Note that the
1245.I clnt_destroy()
1246call
1247always deallocates the space associated with the
1242timeout.
1243.LP
1244Note that the
1245.I clnt_destroy()
1246call
1247always deallocates the space associated with the
1248.I CLIENT
1248.I CLIENT
1249handle. It closes the socket associated with the
1249handle. It closes the socket associated with the
1250.I CLIENT
1250.I CLIENT
1251handle, however, only if the RPC library opened it. It the
1252socket was opened by the user, it stays open. This makes it
1253possible, in cases where there are multiple client handles
1254using the same socket, to destroy one handle without closing
1255the socket that other handles are using.
1256.LP
1257To make a stream connection, the call to
1251handle, however, only if the RPC library opened it. It the
1252socket was opened by the user, it stays open. This makes it
1253possible, in cases where there are multiple client handles
1254using the same socket, to destroy one handle without closing
1255the socket that other handles are using.
1256.LP
1257To make a stream connection, the call to
1258.I clntudp_create()
1258.I clntudp_create()
1259is replaced with a call to
1260.I clnttcp_create() .
1261.DS
1262.ft CW
1263clnttcp_create(&server_addr, prognum, versnum, &sock,
1264 inputsize, outputsize);
1265.DE
1266There is no timeout argument; instead, the receive and send buffer
1267sizes must be specified. When the
1259is replaced with a call to
1260.I clnttcp_create() .
1261.DS
1262.ft CW
1263clnttcp_create(&server_addr, prognum, versnum, &sock,
1264 inputsize, outputsize);
1265.DE
1266There is no timeout argument; instead, the receive and send buffer
1267sizes must be specified. When the
1268.I clnttcp_create()
1268.I clnttcp_create()
1269call is made, a TCP connection is established.
1270All RPC calls using that
1269call is made, a TCP connection is established.
1270All RPC calls using that
1271.I CLIENT
1271.I CLIENT
1272handle would use this connection.
1273The server side of an RPC call using TCP has
1274.I svcudp_create()
1275replaced by
1276.I svctcp_create() .
1277.DS
1278.ft CW
1279transp = svctcp_create(RPC_ANYSOCK, 0, 0);
1280.DE
1272handle would use this connection.
1273The server side of an RPC call using TCP has
1274.I svcudp_create()
1275replaced by
1276.I svctcp_create() .
1277.DS
1278.ft CW
1279transp = svctcp_create(RPC_ANYSOCK, 0, 0);
1280.DE
1281The last two arguments to
1282.I svctcp_create()
1283are send and receive sizes respectively. If `0' is specified for
1281The last two arguments to
1282.I svctcp_create()
1283are send and receive sizes respectively. If `0' is specified for
1284either of these, the system chooses a reasonable default.
1285.KS
1286.NH 1
1287\&Other RPC Features
1288.IX "RPC" "miscellaneous features"
1289.IX "miscellaneous RPC features"
1290.LP
1291This section discusses some other aspects of RPC

--- 4 unchanged lines hidden (view full) ---

1296.IX select() "" \fIselect()\fP "on the server side"
1297.LP
1298Suppose a process is processing RPC requests
1299while performing some other activity.
1300If the other activity involves periodically updating a data structure,
1301the process can set an alarm signal before calling
1302.I svc_run()
1303But if the other activity
1284either of these, the system chooses a reasonable default.
1285.KS
1286.NH 1
1287\&Other RPC Features
1288.IX "RPC" "miscellaneous features"
1289.IX "miscellaneous RPC features"
1290.LP
1291This section discusses some other aspects of RPC

--- 4 unchanged lines hidden (view full) ---

1296.IX select() "" \fIselect()\fP "on the server side"
1297.LP
1298Suppose a process is processing RPC requests
1299while performing some other activity.
1300If the other activity involves periodically updating a data structure,
1301the process can set an alarm signal before calling
1302.I svc_run()
1303But if the other activity
1304involves waiting on a a file descriptor, the
1304involves waiting on a file descriptor, the
1305.I svc_run()
1306call won't work.
1307The code for
1308.I svc_run()
1309is as follows:
1310.ie t .DS
1311.el .DS L
1312.ft CW

--- 27 unchanged lines hidden (view full) ---

1340You can bypass
1341.I svc_run()
1342and call
1343.I svc_getreqset()
1344yourself.
1345All you need to know are the file descriptors
1346of the socket(s) associated with the programs you are waiting on.
1347Thus you can have your own
1305.I svc_run()
1306call won't work.
1307The code for
1308.I svc_run()
1309is as follows:
1310.ie t .DS
1311.el .DS L
1312.ft CW

--- 27 unchanged lines hidden (view full) ---

1340You can bypass
1341.I svc_run()
1342and call
1343.I svc_getreqset()
1344yourself.
1345All you need to know are the file descriptors
1346of the socket(s) associated with the programs you are waiting on.
1347Thus you can have your own
1348.I select()
1348.I select()
1349.IX select() "" \fIselect()\fP
1350that waits on both the RPC socket,
1351and your own descriptors. Note that
1349.IX select() "" \fIselect()\fP
1350that waits on both the RPC socket,
1351and your own descriptors. Note that
1352.I svc_fds()
1353is a bit mask of all the file descriptors that RPC is using for
1352.I svc_fds()
1353is a bit mask of all the file descriptors that RPC is using for
1354services. It can change everytime that
1355.I any
1354services. It can change everytime that
1355.I any
1356RPC library routine is called, because descriptors are constantly
1356RPC library routine is called, because descriptors are constantly
1357being opened and closed, for example for TCP connections.
1358.NH 2
1359\&Broadcast RPC
1360.IX "broadcast RPC"
1361.IX RPC "broadcast"
1362.LP
1363The
1364.I portmapper
1365is a daemon that converts RPC program numbers
1366into DARPA protocol port numbers; see the
1357being opened and closed, for example for TCP connections.
1358.NH 2
1359\&Broadcast RPC
1360.IX "broadcast RPC"
1361.IX RPC "broadcast"
1362.LP
1363The
1364.I portmapper
1365is a daemon that converts RPC program numbers
1366into DARPA protocol port numbers; see the
1367.I portmap
1367.I portmap
1368man page. You can't do broadcast RPC without the portmapper.
1369Here are the main differences between
1370broadcast RPC and normal RPC calls:
1371.IP 1.
1372Normal RPC expects one answer, whereas
1373broadcast RPC expects many answers
1374(one or more answer from each responding machine).
1375.IP 2.

--- 40 unchanged lines hidden (view full) ---

1416.I eachresult()
1417is called each time a valid result is obtained.
1418It returns a boolean that indicates
1419whether or not the user wants more responses.
1420.ie t .DS
1421.el .DS L
1422.ft CW
1423bool_t done;
1368man page. You can't do broadcast RPC without the portmapper.
1369Here are the main differences between
1370broadcast RPC and normal RPC calls:
1371.IP 1.
1372Normal RPC expects one answer, whereas
1373broadcast RPC expects many answers
1374(one or more answer from each responding machine).
1375.IP 2.

--- 40 unchanged lines hidden (view full) ---

1416.I eachresult()
1417is called each time a valid result is obtained.
1418It returns a boolean that indicates
1419whether or not the user wants more responses.
1420.ie t .DS
1421.el .DS L
1422.ft CW
1423bool_t done;
1424 . . .
1424 . . .
1425done = eachresult(resultsp, raddr)
1426 caddr_t resultsp;
1427 struct sockaddr_in *raddr; /* \fIAddr of responding machine\fP */
1428.DE
1429If
1430.I done
1431is
1432.I TRUE ,

--- 80 unchanged lines hidden (view full) ---

1513windowdispatch(rqstp, transp)
1514 struct svc_req *rqstp;
1515 SVCXPRT *transp;
1516{
1517 char *s = NULL;
1518
1519 switch (rqstp->rq_proc) {
1520 case NULLPROC:
1425done = eachresult(resultsp, raddr)
1426 caddr_t resultsp;
1427 struct sockaddr_in *raddr; /* \fIAddr of responding machine\fP */
1428.DE
1429If
1430.I done
1431is
1432.I TRUE ,

--- 80 unchanged lines hidden (view full) ---

1513windowdispatch(rqstp, transp)
1514 struct svc_req *rqstp;
1515 SVCXPRT *transp;
1516{
1517 char *s = NULL;
1518
1519 switch (rqstp->rq_proc) {
1520 case NULLPROC:
1521 if (!svc_sendreply(transp, xdr_void, 0))
1521 if (!svc_sendreply(transp, xdr_void, 0))
1522 fprintf(stderr, "can't reply to RPC call\en");
1523 return;
1524 case RENDERSTRING:
1525 if (!svc_getargs(transp, xdr_wrapstring, &s)) {
1526 fprintf(stderr, "can't decode arguments\en");
1527.ft I
1528 /*
1529 * Tell caller he screwed up
1530 */
1531.ft CW
1532 svcerr_decode(transp);
1533 break;
1534 }
1535.ft I
1536 /*
1537 * Code here to render the string \fIs\fP
1538 */
1539.ft CW
1522 fprintf(stderr, "can't reply to RPC call\en");
1523 return;
1524 case RENDERSTRING:
1525 if (!svc_getargs(transp, xdr_wrapstring, &s)) {
1526 fprintf(stderr, "can't decode arguments\en");
1527.ft I
1528 /*
1529 * Tell caller he screwed up
1530 */
1531.ft CW
1532 svcerr_decode(transp);
1533 break;
1534 }
1535.ft I
1536 /*
1537 * Code here to render the string \fIs\fP
1538 */
1539.ft CW
1540 if (!svc_sendreply(transp, xdr_void, NULL))
1540 if (!svc_sendreply(transp, xdr_void, NULL))
1541 fprintf(stderr, "can't reply to RPC call\en");
1542 break;
1543 case RENDERSTRING_BATCHED:
1544 if (!svc_getargs(transp, xdr_wrapstring, &s)) {
1545 fprintf(stderr, "can't decode arguments\en");
1546.ft I
1547 /*
1548 * We are silent in the face of protocol errors

--- 241 unchanged lines hidden (view full) ---

1790to determine which style of authentication the caller used.
1791The service implementor may also wish to inspect the other fields of
1792.I rq_cred
1793if the style is not one of the styles supported by the RPC package.
1794.IP 2.
1795That the request's
1796.I rq_clntcred
1797field is either
1541 fprintf(stderr, "can't reply to RPC call\en");
1542 break;
1543 case RENDERSTRING_BATCHED:
1544 if (!svc_getargs(transp, xdr_wrapstring, &s)) {
1545 fprintf(stderr, "can't decode arguments\en");
1546.ft I
1547 /*
1548 * We are silent in the face of protocol errors

--- 241 unchanged lines hidden (view full) ---

1790to determine which style of authentication the caller used.
1791The service implementor may also wish to inspect the other fields of
1792.I rq_cred
1793if the style is not one of the styles supported by the RPC package.
1794.IP 2.
1795That the request's
1796.I rq_clntcred
1797field is either
1798.I NULL
1798.I NULL
1799or points to a well formed structure
1800that corresponds to a supported style of authentication credentials.
1801Remember that only
1802.I unix
1803style is currently supported, so (currently)
1804.I rq_clntcred
1805could be cast to a pointer to an
1806.I authunix_parms

--- 34 unchanged lines hidden (view full) ---

1841 }
1842.ft I
1843 /*
1844 * now get the uid
1845 */
1846.ft CW
1847 switch (rqstp->rq_cred.oa_flavor) {
1848 case AUTH_UNIX:
1799or points to a well formed structure
1800that corresponds to a supported style of authentication credentials.
1801Remember that only
1802.I unix
1803style is currently supported, so (currently)
1804.I rq_clntcred
1805could be cast to a pointer to an
1806.I authunix_parms

--- 34 unchanged lines hidden (view full) ---

1841 }
1842.ft I
1843 /*
1844 * now get the uid
1845 */
1846.ft CW
1847 switch (rqstp->rq_cred.oa_flavor) {
1848 case AUTH_UNIX:
1849 unix_cred =
1849 unix_cred =
1850 (struct authunix_parms *)rqstp->rq_clntcred;
1851 uid = unix_cred->aup_uid;
1852 break;
1853 case AUTH_NULL:
1854 default:
1855 svcerr_weakauth(transp);
1856 return;
1857 }

--- 37 unchanged lines hidden (view full) ---

1895And finally, the service protocol itself should return status
1896for access denied; in the case of our example, the protocol
1897does not have such a status, so we call the service primitive
1898.I svcerr_systemerr()
1899instead.
1900.LP
1901The last point underscores the relation between
1902the RPC authentication package and the services;
1850 (struct authunix_parms *)rqstp->rq_clntcred;
1851 uid = unix_cred->aup_uid;
1852 break;
1853 case AUTH_NULL:
1854 default:
1855 svcerr_weakauth(transp);
1856 return;
1857 }

--- 37 unchanged lines hidden (view full) ---

1895And finally, the service protocol itself should return status
1896for access denied; in the case of our example, the protocol
1897does not have such a status, so we call the service primitive
1898.I svcerr_systemerr()
1899instead.
1900.LP
1901The last point underscores the relation between
1902the RPC authentication package and the services;
1903RPC deals only with
1904.I authentication
1905and not with individual services'
1903RPC deals only with
1904.I authentication
1905and not with individual services'
1906.I "access control" .
1907The services themselves must implement their own access control policies
1908and reflect these policies as return statuses in their protocols.
1909.NH 2
1910\&DES Authentication
1911.IX RPC DES
1912.IX RPC authentication
1913.LP
1914UNIX authentication is quite easy to defeat. Instead of using
1915.I authunix_create_default (),
1916one can call
1906.I "access control" .
1907The services themselves must implement their own access control policies
1908and reflect these policies as return statuses in their protocols.
1909.NH 2
1910\&DES Authentication
1911.IX RPC DES
1912.IX RPC authentication
1913.LP
1914UNIX authentication is quite easy to defeat. Instead of using
1915.I authunix_create_default (),
1916one can call
1917.I authunix_create()
1917.I authunix_create()
1918and then modify the RPC authentication handle it returns by filling in
1919whatever user ID and hostname they wish the server to think they have.
1920DES authentication is thus recommended for people who want more security
1921than UNIX authentication offers.
1922.LP
1923The details of the DES authentication protocol are complicated and
1918and then modify the RPC authentication handle it returns by filling in
1919whatever user ID and hostname they wish the server to think they have.
1920DES authentication is thus recommended for people who want more security
1921than UNIX authentication offers.
1922.LP
1923The details of the DES authentication protocol are complicated and
1924are not explained here.
1924are not explained here.
1925See
1926.I "Remote Procedure Calls: Protocol Specification"
1927for the details.
1928.LP
1929In order for DES authentication to work, the
1925See
1926.I "Remote Procedure Calls: Protocol Specification"
1927for the details.
1928.LP
1929In order for DES authentication to work, the
1930.I keyserv(8c)
1930.I keyserv(8c)
1931daemon must be running on both the server and client machines. The
1932users on these machines need public keys assigned by the network
1933administrator in the
1931daemon must be running on both the server and client machines. The
1932users on these machines need public keys assigned by the network
1933administrator in the
1934.I publickey(5)
1934.I publickey(5)
1935database. And, they need to have decrypted their secret keys
1936using their login password. This automatically happens when one
1937logs in using
1938.I login(1) ,
1939or can be done manually using
1940.I keylogin(1) .
1941The
1942.I "Network Services"

--- 15 unchanged lines hidden (view full) ---

1958.DS
1959char servername[MAXNETNAMELEN];
1960
1961host2netname(servername, rhostname, NULL);
1962.DE
1963Here,
1964.I rhostname
1965is the hostname of the machine the server process is running on.
1935database. And, they need to have decrypted their secret keys
1936using their login password. This automatically happens when one
1937logs in using
1938.I login(1) ,
1939or can be done manually using
1940.I keylogin(1) .
1941The
1942.I "Network Services"

--- 15 unchanged lines hidden (view full) ---

1958.DS
1959char servername[MAXNETNAMELEN];
1960
1961host2netname(servername, rhostname, NULL);
1962.DE
1963Here,
1964.I rhostname
1965is the hostname of the machine the server process is running on.
1966.I host2netname()
1966.I host2netname()
1967fills in
1968.I servername
1969to contain this root process's netname. If the
1970server process was run by a regular user, one could use the call
1967fills in
1968.I servername
1969to contain this root process's netname. If the
1970server process was run by a regular user, one could use the call
1971.I user2netname()
1971.I user2netname()
1972instead. Here is an example for a server process with the same user
1973ID as the client:
1974.DS
1975char servername[MAXNETNAMELEN];
1976
1977user2netname(servername, getuid(), NULL);
1978.DE
1979The last argument to both of these calls,
1972instead. Here is an example for a server process with the same user
1973ID as the client:
1974.DS
1975char servername[MAXNETNAMELEN];
1976
1977user2netname(servername, getuid(), NULL);
1978.DE
1979The last argument to both of these calls,
1980.I user2netname()
1980.I user2netname()
1981and
1982.I host2netname (),
1983is the name of the naming domain where the server is located. The
1981and
1982.I host2netname (),
1983is the name of the naming domain where the server is located. The
1984.I NULL
1984.I NULL
1985used here means \*Quse the local domain name.\*U
1986.LP
1987The second argument to
1985used here means \*Quse the local domain name.\*U
1986.LP
1987The second argument to
1988.I authdes_create()
1988.I authdes_create()
1989is a lifetime for the credential. Here it is set to sixty
1990seconds. What that means is that the credential will expire 60
1991seconds from now. If some mischievous user tries to reuse the
1992credential, the server RPC subsystem will recognize that it has
1993expired and not grant any requests. If the same mischievous user
1994tries to reuse the credential within the sixty second lifetime,
1995he will still be rejected because the server RPC subsystem
1996remembers which credentials it has already seen in the near past,
1997and will not grant requests to duplicates.
1998.LP
1999The third argument to
1989is a lifetime for the credential. Here it is set to sixty
1990seconds. What that means is that the credential will expire 60
1991seconds from now. If some mischievous user tries to reuse the
1992credential, the server RPC subsystem will recognize that it has
1993expired and not grant any requests. If the same mischievous user
1994tries to reuse the credential within the sixty second lifetime,
1995he will still be rejected because the server RPC subsystem
1996remembers which credentials it has already seen in the near past,
1997and will not grant requests to duplicates.
1998.LP
1999The third argument to
2000.I authdes_create()
2000.I authdes_create()
2001is the address of the host to synchronize with. In order for DES
2002authentication to work, the server and client must agree upon the
2003time. Here we pass the address of the server itself, so the
2004client and server will both be using the same time: the server's
2005time. The argument can be
2006.I NULL ,
2007which means \*Qdon't bother synchronizing.\*U You should only do this
2008if you are sure the client and server are already synchronized.
2009.LP
2010The final argument to
2001is the address of the host to synchronize with. In order for DES
2002authentication to work, the server and client must agree upon the
2003time. Here we pass the address of the server itself, so the
2004client and server will both be using the same time: the server's
2005time. The argument can be
2006.I NULL ,
2007which means \*Qdon't bother synchronizing.\*U You should only do this
2008if you are sure the client and server are already synchronized.
2009.LP
2010The final argument to
2011.I authdes_create()
2011.I authdes_create()
2012is the address of a DES encryption key to use for encrypting
2013timestamps and data. If this argument is
2014.I NULL ,
2015as it is in this example, a random key will be chosen. The client
2016may find out the encryption key being used by consulting the
2012is the address of a DES encryption key to use for encrypting
2013timestamps and data. If this argument is
2014.I NULL ,
2015as it is in this example, a random key will be chosen. The client
2016may find out the encryption key being used by consulting the
2017.I ah_key
2017.I ah_key
2018field of the authentication handle.
2019.sp
2020.IP "\fIServer Side\fP"
2021.LP
2022The server side is a lot simpler than the client side. Here is the
2023previous example rewritten to use
2024.I AUTH_DES
2025instead of

--- 16 unchanged lines hidden (view full) ---

2042 int gidlen;
2043 int gidlist[10];
2044.ft I
2045 /*
2046 * we don't care about authentication for null proc
2047 */
2048.ft CW
2049
2018field of the authentication handle.
2019.sp
2020.IP "\fIServer Side\fP"
2021.LP
2022The server side is a lot simpler than the client side. Here is the
2023previous example rewritten to use
2024.I AUTH_DES
2025instead of

--- 16 unchanged lines hidden (view full) ---

2042 int gidlen;
2043 int gidlist[10];
2044.ft I
2045 /*
2046 * we don't care about authentication for null proc
2047 */
2048.ft CW
2049
2050 if (rqstp->rq_proc == NULLPROC) {
2050 if (rqstp->rq_proc == NULLPROC) {
2051 /* \fIsame as before\fP */
2052 }
2053
2054.ft I
2055 /*
2056 * now get the uid
2057 */
2058.ft CW

--- 14 unchanged lines hidden (view full) ---

2073 default:
2074 svcerr_weakauth(transp);
2075 return;
2076 }
2077
2078.ft I
2079 /*
2080 * The rest is the same as before
2051 /* \fIsame as before\fP */
2052 }
2053
2054.ft I
2055 /*
2056 * now get the uid
2057 */
2058.ft CW

--- 14 unchanged lines hidden (view full) ---

2073 default:
2074 svcerr_weakauth(transp);
2075 return;
2076 }
2077
2078.ft I
2079 /*
2080 * The rest is the same as before
2081 */
2081 */
2082.ft CW
2083.vs
2084.DE
2085Note the use of the routine
2086.I netname2user (),
2087the inverse of
2088.I user2netname ():
2089it takes a network ID and converts to a unix ID.
2082.ft CW
2083.vs
2084.DE
2085Note the use of the routine
2086.I netname2user (),
2087the inverse of
2088.I user2netname ():
2089it takes a network ID and converts to a unix ID.
2090.I netname2user ()
2090.I netname2user ()
2091also supplies the group IDs which we don't use in this example,
2092but which may be useful to other UNIX programs.
2093.NH 2
2094\&Using Inetd
2095.IX inetd "" "using \fIinetd\fP"
2096.LP
2097An RPC server can be started from
2098.I inetd

--- 22 unchanged lines hidden (view full) ---

2121.I inetd
2122Remember that if you want to exit
2123from the server process and return control to
2124.I inet
2125you need to explicitly exit, since
2126.I svc_run()
2127never returns.
2128.LP
2091also supplies the group IDs which we don't use in this example,
2092but which may be useful to other UNIX programs.
2093.NH 2
2094\&Using Inetd
2095.IX inetd "" "using \fIinetd\fP"
2096.LP
2097An RPC server can be started from
2098.I inetd

--- 22 unchanged lines hidden (view full) ---

2121.I inetd
2122Remember that if you want to exit
2123from the server process and return control to
2124.I inet
2125you need to explicitly exit, since
2126.I svc_run()
2127never returns.
2128.LP
2129The format of entries in
2130.I /etc/inetd.conf
2129The format of entries in
2130.I /etc/inetd.conf
2131for RPC services is in one of the following two forms:
2132.ie t .DS
2133.el .DS L
2134.ft CW
2135p_name/version dgram rpc/udp wait/nowait user server args
2136p_name/version stream rpc/tcp wait/nowait user server args
2137.DE
2138where

--- 80 unchanged lines hidden (view full) ---

2219 /*
2220 * Code here to compute the number of users
2221 * and assign it to the variable \fInusers\fP
2222 */
2223.ft CW
2224 nusers2 = nusers;
2225 switch (rqstp->rq_vers) {
2226 case RUSERSVERS_ORIG:
2131for RPC services is in one of the following two forms:
2132.ie t .DS
2133.el .DS L
2134.ft CW
2135p_name/version dgram rpc/udp wait/nowait user server args
2136p_name/version stream rpc/tcp wait/nowait user server args
2137.DE
2138where

--- 80 unchanged lines hidden (view full) ---

2219 /*
2220 * Code here to compute the number of users
2221 * and assign it to the variable \fInusers\fP
2222 */
2223.ft CW
2224 nusers2 = nusers;
2225 switch (rqstp->rq_vers) {
2226 case RUSERSVERS_ORIG:
2227 if (!svc_sendreply(transp, xdr_u_long,
2227 if (!svc_sendreply(transp, xdr_u_long,
2228 &nusers)) {
2229 fprintf(stderr,"can't reply to RPC call\en");
2230 }
2231 break;
2232 case RUSERSVERS_SHORT:
2228 &nusers)) {
2229 fprintf(stderr,"can't reply to RPC call\en");
2230 }
2231 break;
2232 case RUSERSVERS_SHORT:
2233 if (!svc_sendreply(transp, xdr_u_short,
2233 if (!svc_sendreply(transp, xdr_u_short,
2234 &nusers2)) {
2235 fprintf(stderr,"can't reply to RPC call\en");
2236 }
2237 break;
2238 }
2239 default:
2240 svcerr_noproc(transp);
2241 return;

--- 140 unchanged lines hidden (view full) ---

2382 */
2383.ft CW
2384#include <stdio.h>
2385#include <rpc/rpc.h>
2386
2387main()
2388{
2389 register SVCXPRT *transp;
2234 &nusers2)) {
2235 fprintf(stderr,"can't reply to RPC call\en");
2236 }
2237 break;
2238 }
2239 default:
2240 svcerr_noproc(transp);
2241 return;

--- 140 unchanged lines hidden (view full) ---

2382 */
2383.ft CW
2384#include <stdio.h>
2385#include <rpc/rpc.h>
2386
2387main()
2388{
2389 register SVCXPRT *transp;
2390 int rcp_service(), xdr_rcp();
2390 int rcp_service(), xdr_rcp();
2391
2392 if ((transp = svctcp_create(RPC_ANYSOCK,
2393 BUFSIZ, BUFSIZ)) == NULL) {
2394 fprintf("svctcp_create: error\en");
2395 exit(1);
2396 }
2397 pmap_unset(RCPPROG, RCPVERS);
2398 if (!svc_register(transp,

--- 120 unchanged lines hidden (view full) ---

2519 * may be already bound, so don't check for error
2520 */
2521.ft CW
2522 bind(s, &addr, len);
2523 if (getsockname(s, &addr, &len)< 0) {
2524 perror("getsockname");
2525 return (0);
2526 }
2391
2392 if ((transp = svctcp_create(RPC_ANYSOCK,
2393 BUFSIZ, BUFSIZ)) == NULL) {
2394 fprintf("svctcp_create: error\en");
2395 exit(1);
2396 }
2397 pmap_unset(RCPPROG, RCPVERS);
2398 if (!svc_register(transp,

--- 120 unchanged lines hidden (view full) ---

2519 * may be already bound, so don't check for error
2520 */
2521.ft CW
2522 bind(s, &addr, len);
2523 if (getsockname(s, &addr, &len)< 0) {
2524 perror("getsockname");
2525 return (0);
2526 }
2527 while (!pmap_set(prognum++, vers, proto,
2527 while (!pmap_set(prognum++, vers, proto,
2528 ntohs(addr.sin_port))) continue;
2529 return (prognum-1);
2530}
2531.vs
2532.DE
2533.SH
2534Note:
2535.I
2536The call to
2528 ntohs(addr.sin_port))) continue;
2529 return (prognum-1);
2530}
2531.vs
2532.DE
2533.SH
2534Note:
2535.I
2536The call to
2537.I ntohs()
2537.I ntohs()
2538is necessary to ensure that the port number in
2539.I "addr.sin_port" ,
2538is necessary to ensure that the port number in
2539.I "addr.sin_port" ,
2540which is in
2541.I network
2542byte order, is passed in
2540which is in
2541.I network
2542byte order, is passed in
2543.I host
2544byte order (as
2543.I host
2544byte order (as
2545.I pmap_set()
2545.I pmap_set()
2546expects). See the
2546expects). See the
2547.I byteorder(3N)
2547.I byteorder(3N)
2548man page for more details on the conversion of network
2549addresses from network to host byte order.
2550.KS
2551.LP
2552The following pair of programs illustrate how to use the
2553.I gettransient()
2554routine.
2555The client makes an RPC call to the server,

--- 131 unchanged lines hidden ---
2548man page for more details on the conversion of network
2549addresses from network to host byte order.
2550.KS
2551.LP
2552The following pair of programs illustrate how to use the
2553.I gettransient()
2554routine.
2555The client makes an RPC call to the server,

--- 131 unchanged lines hidden ---