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Ð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 | 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 --- |