1 /* BLURB lgpl
2 
3                            Coda File System
4                               Release 5
5 
6           Copyright (c) 1987-2016 Carnegie Mellon University
7                   Additional copyrights listed below
8 
9 This  code  is  distributed "AS IS" without warranty of any kind under
10 the  terms of the  GNU  Library General Public Licence  Version 2,  as
11 shown in the file LICENSE. The technical and financial contributors to
12 Coda are listed in the file CREDITS.
13 
14                         Additional copyrights
15 
16 #*/
17 
18 /*
19                          IBM COPYRIGHT NOTICE
20 
21                           Copyright (C) 1986
22              International Business Machines Corporation
23                          All Rights Reserved
24 
25 This  file  contains  some  code identical to or derived from the 1986
26 version of the Andrew File System ("AFS"), which is owned by  the  IBM
27 Corporation.   This  code is provided "AS IS" and IBM does not warrant
28 that it is free of infringement of  any  intellectual  rights  of  any
29 third  party.    IBM  disclaims  liability of any kind for any damages
30 whatsoever resulting directly or indirectly from use of this  software
31 or  of  any  derivative work.  Carnegie Mellon University has obtained
32 permission to  modify,  distribute and sublicense this code,  which is
33 based on Version 2  of  AFS  and  does  not  contain  the features and
34 enhancements that are part of  Version 3 of  AFS.  Version 3 of AFS is
35 commercially   available   and  supported  by   Transarc  Corporation,
36 Pittsburgh, PA.
37 
38 */
39 
40 #ifndef _RPC2_
41 #define _RPC2_
42 
43 #ifdef HAVE_CONFIG_H
44 #include <config.h>
45 #endif
46 
47 #include <stdio.h>
48 #include <sys/time.h>
49 #include <netinet/in.h>
50 
51 #ifdef HAVE_ARPA_INET_H
52 #include <arpa/inet.h>
53 #endif
54 
55 /* This string is used in RPC initialization calls to ensure that the
56 runtime system and the header files are mutually consistent.  Also
57 passed across on RPC2_NewBinding for advisory information to other
58 side. Changes to this string may cause RPC2_OLDVERSION to be returned
59 on RPC2_NewBinding()s. */
60 /* #define RPC2_VERSION "Version 14.0: Satya, 6 May 1988, 10:00" */
61 #define RPC2_VERSION "Version 15.0: JH, 10 Dec 1998, 12:00"
62 
63 
64 /* Found as the first 4 bytes of EVERY packet.  Change this if you
65 change any aspect of the protocol sequence, or if you change the
66 packet header, or the body formats of the initialization packets.
67 Used in inital packet exchange to verify that the client and server
68 speak exactly the same protocol.  Orthogonal to RPC2_VERSION.  We need
69 this in the header at the very beginning, else we cannot change packet
70 formats in a detectable manner.  */
71 #define RPC2_PROTOVERSION 8
72 
73 
74 /*
75 The following constants are used to indicate the security-level of RPC connections.
76 */
77 #define RPC2_OPENKIMONO	98	/* Neither authenticated nor encrypted */
78 #define RPC2_AUTHONLY		12	/* Authenticated but not encrypted */
79 #define RPC2_HEADERSONLY	73	/* Authenticated but only headers encrypted */
80 #define RPC2_SECURE 		66	/* Authenticated and fully encrypted */
81 
82 /* RPC2 supports multiple encryption types; the key length is fixed,
83 and you must always supply a field of RPC2_KEYSIZE bytes wherever an
84 encryption key is called for.  However, individual algorithms can
85 choose to ignore excess bytes in the keys.
86 
87 The encryption types are specified as integer bit positions so that
88 the EncryptionTypesMask field of RPC2_GetRequest() can be a mask of
89 these types.  The required type must also be specified in
90 RPC2_NewBinding().
91 
92 To add support for other encryption types only the constants below and
93 the internal runtime procedures rpc2_Encrypt() and rpc2_Decrypt() have
94 to be modified.  */
95 #define RPC2_DES 1
96 #define RPC2_XOR 2
97 #define RPC2_ENCRYPTIONTYPES (RPC2_DES | RPC2_XOR)
98 				/* union of all supported types */
99 #define RPC2_KEYSIZE 8   /*Size in bytes of the encryption keys */
100 
101 /*
102 RPC procedure return codes:
103 
104 These may also  occur in the RPC2_ReturnCode field of reply headers:
105 Values of 0 and below in those fields are reserved for RPC stub use.
106 Codes greater than 0  are  assigned  and managed by subsystems.
107 
108 There are three levels of errors: Warning, Error, and Fatal Error.
109 RPC2_SUCCESS > RPC2_WLIMIT > warning codes > RPC2_ELIMIT > error codes
110 > RPC2_FLIMIT > fatal error codes
111 
112 The semantics of these codes are:
113 
114 RPC2_SUCCESS:	Everything was perfect.
115 
116 Warning: 	         Advisory information.
117 
118 Error:		Something went wrong, but the connection (if any)  is still usable.
119 
120 Fatal:		The connection (if any) has been marked unusable.
121 
122 Note that the routine RPC2_ErrorMsg() will translate return codes into
123 printable strings.  */
124 
125 #define RPC2_SUCCESS	0
126 
127 #define RPC2_WLIMIT	-1
128 #define RPC2_ELIMIT	-1000
129 #define RPC2_FLIMIT	-2000
130 
131 /*
132 Warnings
133 */
134 #define RPC2_OLDVERSION 	RPC2_WLIMIT-1
135 #define RPC2_INVALIDOPCODE	RPC2_WLIMIT-2
136 			/* Never returned by RPC2 itself; Used by higher levels, such as rp2gen */
137 #define RPC2_BADDATA		RPC2_WLIMIT-3
138 			/* Never used by RPC2 itself; used by rp2gen or higher levels to indicate bogus data */
139 #define RPC2_NOGREEDY		RPC2_WLIMIT-4
140 		        /* ioctl to allocate plenty of socket buffer space
141 			    failed; packet losses may be high especially on
142 			    bulk transfers */
143 #define	RPC2_ABANDONED		RPC2_WLIMIT-5
144 
145 /*
146 Errors
147 */
148 #define RPC2_CONNBUSY 		RPC2_ELIMIT-1
149 #define RPC2_SEFAIL1 		RPC2_ELIMIT-2
150 #define RPC2_TOOLONG 		RPC2_ELIMIT-3
151 #define	RPC2_NOMGROUP		RPC2_ELIMIT-4
152 #define RPC2_MGRPBUSY		RPC2_ELIMIT-5
153 #define	RPC2_NOTGROUPMEMBER	RPC2_ELIMIT-6
154 #define	RPC2_DUPLICATEMEMBER	RPC2_ELIMIT-7
155 #define	RPC2_BADMGROUP		RPC2_ELIMIT-8
156 
157 /*
158 Fatal Errors
159 */
160 #define RPC2_FAIL      		RPC2_FLIMIT-1
161 #define RPC2_NOCONNECTION 	RPC2_FLIMIT-2
162 #define RPC2_TIMEOUT   		RPC2_FLIMIT-3
163 #define RPC2_NOBINDING 		RPC2_FLIMIT-4
164 #define RPC2_DUPLICATESERVER 	RPC2_FLIMIT-5
165 #define RPC2_NOTWORKER 		RPC2_FLIMIT-6
166 #define RPC2_NOTCLIENT 		RPC2_FLIMIT-7
167 #define RPC2_WRONGVERSION 	RPC2_FLIMIT-8
168 #define RPC2_NOTAUTHENTICATED 	RPC2_FLIMIT-9
169 #define RPC2_CLOSECONNECTION 	RPC2_FLIMIT-10
170 #define RPC2_BADFILTER 		RPC2_FLIMIT-11
171 #define RPC2_LWPNOTINIT		RPC2_FLIMIT-12
172 #define RPC2_BADSERVER		RPC2_FLIMIT-13
173 #define RPC2_SEFAIL2		RPC2_FLIMIT-14
174 #define RPC2_DEAD		RPC2_FLIMIT-15
175 #define RPC2_NAKED		RPC2_FLIMIT-16
176 #define RPC2_SEFAIL3		RPC2_FLIMIT-17	/* More error codes for side effects */
177 #define RPC2_SEFAIL4		RPC2_FLIMIT-18	/* More error codes for side effects */
178 
179 #define	MGRPERROR(code)\
180     (code == RPC2_NOMGROUP ||\
181      code == RPC2_MGRPBUSY ||\
182      code == RPC2_NOTGROUPMEMBER ||\
183      code == RPC2_DUPLICATEMEMBER ||\
184      code == RPC2_BADMGROUP)
185 
186 
187 /*
188 Universal opcode values:  opcode values equal to or less than 0 are reserved.  Values greater than 0
189 are  usable by mutual agreement between clients and servers.
190 */
191 #define RPC2_INIT1OPENKIMONO	-2	/* Begin a new connection with security level RPC2_OPENKIMONO */
192 #define RPC2_INIT1AUTHONLY 	-3	/* Begin a new connection with security level RPC2_AUTHONLY */
193 #define RPC2_INIT1HEADERSONLY	-4	/* Begin a new connection with security level RPC2_HEADERSONLY */
194 #define RPC2_INIT1SECURE	-5	/* Begin a new connection with security level RPC2_SECURE */
195 #define RPC2_LASTACK		-6	/* Packet that acknowledges a reply */
196 #define RPC2_REPLY		-8	/* Reply packet */
197 #define RPC2_INIT2              -10	/* Phase 2 of bind handshake */
198 #define RPC2_INIT3		-11	/* Phase 3 of bind handshake */
199 #define RPC2_INIT4		-12	/* Phase 4 of bind handshake */
200 #define RPC2_NEWCONNECTION	-13	/* opcode of fake request generated by RPC2_GetRequest() on new connection */
201 #define RPC2_BUSY		-14	/* keep alive packet */
202 #define	RPC2_INITMULTICAST	-15	/* Establish a multicast connection */
203 
204 
205 /*
206 System Limits
207 */
208 #define RPC2_MAXPACKETSIZE	4500    /* size of the largest acceptable packet buffer in bytes (includes prefix and header) */
209 
210 
211 
212 /* Host, Mgrp, Port and Subsys Representations */
213 
214 typedef	enum {RPC2_HOSTBYNAME = 39, RPC2_HOSTBYINETADDR = 17,
215 	      RPC2_HOSTBYADDRINFO = 6, RPC2_DUMMYHOST=88888} HostTag;
216 typedef	enum {RPC2_PORTBYINETNUMBER = 53, RPC2_PORTBYNAME = 64,
217 	      RPC2_DUMMYPORT = 99999} PortTag;
218 typedef enum {RPC2_SUBSYSBYID = 71, RPC2_SUBSYSBYNAME = 84,
219 	      RPC2_DUMMYSUBSYS = 44444} SubsysTag;
220 typedef	enum {RPC2_MGRPBYINETADDR = 111, RPC2_MGRPBYADDRINFO = 121,
221 	      RPC2_MGRPBYNAME = 137, RPC2_DUMMYMGRP = 77777} MgrpTag;
222 
223 /*
224 Global variables for debugging:
225 
226 RPC2_DebugLevel controls the level of debugging output produced on stdout.
227 A value of 0  turns  off the  output  altogether;  values  of  1, 10, and 100 are currently meaningful.
228 The default value of this variable is 0.
229 
230 RPC2_Perror controls  the  printing  of  Unix error  messages on stdout.
231 A value of 1 turns on the printing, while 0 turns it off.  The default value for this variable is 1.
232 
233 RPC2_Trace controls the tracing of RPC calls, packet transmissions and packet reception.  Set it to 1
234 for tracing.  Set to zero for stopping tracing.  The internal circular trace  buffer can be printed out
235 by calling RPC2_DumpTrace().
236 
237 */
238 
239 extern long RPC2_DebugLevel;
240 extern long RPC2_Perror;
241 extern long RPC2_Trace;
242 
243 /* Misc. global variables
244  *
245  * RPC2_strict_ip_matching enables stricter matching of incoming packets on
246  * sender ip/port addresses. When this is enabled, multihomed or masqueraded
247  * hosts will get rejected when they send their packet from the wrong IP
248  * address. But connections are less likely to get spoofed.
249  */
250 extern long RPC2_strict_ip_matching;
251 
252 /* The application can request a preferred minimal encryption key length
253  * The value is in bytes.
254  *
255  * AES_CCM uses three bytes of salt + AES key length, so useful values would be,
256  *   19 (128-bit AES key), 27 (192-bit AES key), or 35 (256-bit AES key).
257  *
258  * You can also set the environment variable 'RPC2_KEYSIZE', which is evaluated
259  * when RPC2_Init() is called, the environment variable can be set either in
260  * bytes or in bits. (19/152, 27/216, 35/280)
261  */
262 extern size_t RPC2_Preferred_Keysize;
263 extern int    RPC2_secure_only;
264 
265 /*
266 ************************* Data Types known to RPGen ***********************
267 */
268 typedef int32_t RPC2_Integer;     /*32-bit,  2's  complement representation.  On other machines, an explicit
269                         conversion may be needed.*/
270 typedef uint32_t RPC2_Unsigned;     /* 32-bits.*/
271 
272 typedef uint8_t RPC2_Byte;      /*A single 8-bit byte.*/
273 
274 typedef double RPC2_Double;      /*A single 64-bit float.*/
275 
276 typedef RPC2_Byte *RPC2_ByteSeq;
277 /* A contiguous sequence of bytes. In the C implementation this is a
278 pointer.  RPC2Gen knows how to allocate and transform the pointer
279 values on transmission.  Beware if you are not dealing via RPC2Gen.
280 May be differently represented in other languages.  */
281 
282 typedef RPC2_ByteSeq RPC2_String; /*no nulls except last byte*/
283 /* A null-terminated sequence of characters.  Identical to the C
284 language string definition.  */
285 
286 
287 typedef
288     struct
289         {
290         RPC2_Unsigned SeqLen; /*length of SeqBody*/
291         RPC2_ByteSeq SeqBody; /*no restrictions on contents*/
292         }
293     RPC2_CountedBS;
294 /*
295 A means of transmitting binary data.
296 */
297 
298 typedef
299     struct
300          {
301          RPC2_Unsigned MaxSeqLen; /*max size of buffer represented by SeqBody*/
302          RPC2_Unsigned SeqLen; /*number of interesting bytes in SeqBody*/
303          RPC2_ByteSeq SeqBody; /*No restrictions on contents*/
304          }
305     RPC2_BoundedBS;
306 
307 /* RPC2_BoundedBS is intended to allow you to remotely play the game
308 that C programmers play all the time: allocate a large buffer, fill in
309 some bytes, then call a procedure which takes this buffer as a
310 parameter and replaces its contents by a possibly longer sequence of
311 bytes.  Example: strcat().  */
312 
313 typedef
314     RPC2_Byte RPC2_EncryptionKey[RPC2_KEYSIZE];
315 /*
316 Keys used for encryption are fixed length byte sequences
317 */
318 
319 
320 /*
321 ************************* Data Types used only in runtime calls ********************************
322 */
323 
324 typedef RPC2_Integer RPC2_Handle;	/* NOT a small integer!!! */
325 
326 /* Values for the Tag field of the following structures are defined above */
327 typedef
328     struct
329     	{
330 	HostTag Tag;
331 	union
332 	    {
333 	    struct RPC2_addrinfo *AddrInfo; /* includes sockaddr, which includes port */
334 	    struct in_addr InetAddress;	/* NOTE: in network order, not host order */
335 	    char Name[64];	/* minimum length for use with domain names */
336 	    }
337 	    Value;
338 	}
339     RPC2_HostIdent;
340 
341 typedef
342     struct
343     	{
344 	PortTag Tag;
345 	union
346 	    {
347 	    uint16_t InetPortNumber; /* NOTE: in network order, not host order */
348 	    char Name[20];	/* this is a pretty arbitrary length */
349 	    }
350 	    Value;
351 	}
352     RPC2_PortIdent;
353 
354 typedef
355     struct
356     	{
357 	SubsysTag Tag;
358 	union
359 	    {
360 	    long  SubsysId;
361 	    char Name[20];	/* this is a pretty arbitrary length */
362 	    }
363 	    Value;
364 	}
365     RPC2_SubsysIdent;
366 
367 
368 typedef
369     struct
370 	{
371 	MgrpTag Tag;
372 	union
373 	    {
374 	    struct RPC2_addrinfo *AddrInfo; /* includes sockaddr, which includes port */
375 	    struct in_addr InetAddress;	/* NOTE: in network order, not host order */
376 	    char	    Name[64];	    /* minimum length for use with domain names */
377 	    }
378 	    Value;
379 	}
380     RPC2_McastIdent;
381 
382 
383 typedef
384     struct		/* data structure filled by RPC2_GetPeerInfo() call */
385 	{
386 	RPC2_HostIdent 	 RemoteHost;
387 	RPC2_PortIdent   RemotePort;
388 	RPC2_SubsysIdent RemoteSubsys;
389 	RPC2_Handle	 RemoteHandle;
390 	RPC2_Integer	 SecurityLevel;
391 	RPC2_Integer	 EncryptionType;
392 	RPC2_Integer	 Uniquefier;
393 	RPC2_EncryptionKey	SessionKey;
394 	}
395     RPC2_PeerInfo;
396 
397 /* The RPC2_PacketBuffer definition below deals with both requests and
398 replies.  The runtime system provides efficient buffer storage
399 management routines --- use them!  */
400 
401 typedef struct RPC2_PacketBuffer {
402     struct RPC2_PacketBufferPrefix {
403 /*
404  * NOTE: The Prefix is only used by the runtime system on the local machine.
405  *	 Neither clients nor servers ever deal with it.
406  *	 It is never transmitted.
407  */
408 	/* these four elements are used by the list routines */
409 	struct RPC2_PacketBuffer *Next;   /* next element in buffer chain */
410 	struct RPC2_PacketBuffer *Prev;	  /* prev element in buffer chain */
411 	enum {OBJ_PACKETBUFFER = 3247517} MagicNumber;/* to detect corruption */
412 	struct RPC2_PacketBuffer **Qname; /* pointer to the queue this packet
413 					     is on */
414 
415 	long  BufferSize;		  /* Set at malloc() time; size of
416 					     entire packet, including prefix. */
417 	long  LengthOfPacket;		  /* size of data actually
418 					     transmitted, header+body */
419 	long File[3];
420 	long Line;
421 
422 	/* these fields are set when we receive the packet. */
423 	struct RPC2_addrinfo	*PeerAddr;
424 	struct security_association *sa;
425 	char   oldhostandport[84]; /* padding to keep the userspace interface
426 				      mostly identical (on a 32-bit machine..)*/
427 	struct timeval		RecvStamp;
428     } Prefix;
429 
430 /*
431 	The transmitted packet begins here.
432 */
433     struct RPC2_PacketHeader {
434 	/* The first four fields are never encrypted */
435 	RPC2_Integer  ProtoVersion;	/* Set by runtime system */
436 	RPC2_Integer  RemoteHandle;	/* Set by runtime system; -1 indicates
437 					   unencrypted error packet */
438 	RPC2_Integer  LocalHandle;	/* Set by runtime system */
439 	RPC2_Integer  Flags;	/* Used by runtime system only.  First byte
440 				   reserved for side effect use. Second byte
441 				   reserved for indicating color (see libfail
442 				   documentation). Last two bytes reserved for
443 				   RPC2 use. */
444 
445 	/* Everything below here can be encrypted */
446 	RPC2_Unsigned  BodyLength;   /* of the portion after the header. Set
447 					by client.*/
448 	RPC2_Unsigned  SeqNumber;    /* unique identifier for this message on
449 					this connection; set by runtime
450 					system; odd on packets from client to
451 					server; even on packets from server to
452 					client */
453 	RPC2_Integer  Opcode;        /* Values  greater than 0 are
454 					subsystem-specific: set by client.
455 					Values less than 0 reserved: set by
456 					runtime system. Type of packet
457 					determined by Opcode value: > 0 ==>
458 					request packet. Values of RPC2_REPLY
459 					==> reply packet, RPC2_ACK ==> ack
460 					packet, and so on */
461 	RPC2_Unsigned SEFlags;	    /* Bits for use by side effect routines */
462 	RPC2_Unsigned SEDataOffset; /* Offset of piggy-backed side effect
463 				       data, from the start of Body */
464 	RPC2_Unsigned SubsysId;     /* Subsystem identifier. Filled by runtime
465 				       system. */
466 	RPC2_Integer  ReturnCode;   /* Set by server on replies; meaningless
467 				       on request packets*/
468 	RPC2_Unsigned Lamport;	    /* For distributed clock mechanism */
469 	RPC2_Integer  Uniquefier;   /* Used only in Init1 packets; truly
470 				       unique random number */
471 	RPC2_Unsigned TimeStamp;    /* Used for rpc timing. */
472 	RPC2_Integer  BindTime;     /* Used to send the bind time to server.
473 				       Temporary, i hope. */
474     } Header;
475 
476     RPC2_Byte Body[1]; /* Arbitrary length body. For requests: IN and INOUT
477 			  parameters; For replies: OUT and INOUT parameters;
478 			  Header.BodyLength gives the length of this field */
479 } RPC2_PacketBuffer; /* The second and third fields actually get sent over
480 			  the wire */
481 
482 
483 /* Meaning of Flags field in RPC2 packet header.
484  * First (leftmost) byte of Flags field is reserved for use by side effect
485  * routines. This is in addition to the SEFlags field. Flags is not encrypted,
486  * but SEFLAGS is. Second byte of Flags field is reserved for indicating
487  * packet color by libfail. Third and fourth bytes are used as genuine RPC2
488  * flags */
489 #define RPC2_RETRY	0x01	/* set by runtime system */
490 #define RPC2_ENCRYPTED	0x02	/* set by runtime system */
491 /*      RPC2_MULTICAST  0x04	   Old multicast flag */
492 /*      RPC2SEC_CAPABLE 0x08	   Old rpc2sec flag */
493 #define RPC2SEC_CAPABLE	0x10	/* set on Init1 packet by new rpc2sec stack */
494 
495  /* Format of filter used in RPC2_GetRequest */
496 
497 enum E1 {ANY=12, ONECONN=37, ONESUBSYS=43};
498 enum E2 {OLD=27, NEW=38, OLDORNEW=69};
499 
500 typedef
501     struct
502 	{
503         enum E1 FromWhom;
504 	enum E2 OldOrNew;
505 	union
506 	    {
507 	    RPC2_Handle WhichConn;	/* if FromWhom  == ONECONN */
508 	    long SubsysId;		/* if FromWhom == ONESUBSYS */
509 	    }
510 	    ConnOrSubsys;
511 	}
512     RPC2_RequestFilter;		/* Type of Filter parameter in RPC2_GetRequest() */
513 
514 
515 /*
516 The following data structure is the body of the packet synthesised by the runtime system on a
517 new connection, and returned as the result of an RPC2_GetRequest().
518 */
519 typedef
520     struct
521 	{
522 	RPC2_Integer SideEffectType;
523 	RPC2_Integer SecurityLevel;
524 	RPC2_Integer EncryptionType;
525 	RPC2_Integer AuthenticationType;
526 	RPC2_Unsigned ClientIdent_SeqLen;
527 	RPC2_Unsigned ClientIdent_SeqBody;
528 	}
529     RPC2_NewConnectionBody;
530 
531 
532 /* Structure for passing various initialization options to RPC2_Init() */
533 typedef
534     struct
535         {
536 	    RPC2_Byte	Flags;
537 	}
538     RPC2_Options;
539 
540 #define RPC2_OPTION_IPV6	 0x1
541 #define RPC2_OPTION_VERBOSE_INIT 0x2
542 
543 /* Structure for passing parameters to RPC2_NewBinding() and its multi clone */
544 
545 typedef
546     struct
547 	{
548 	RPC2_Integer SecurityLevel;
549 	RPC2_Integer EncryptionType;
550 	RPC2_EncryptionKey *SharedSecret;
551 	RPC2_Integer AuthenticationType;
552 	RPC2_CountedBS *ClientIdent;
553 	RPC2_Integer SideEffectType;
554 	RPC2_Integer Color;
555 	}
556     RPC2_BindParms;
557 
558  /* enums used both in original RPC and for MultiRPC (was in rp2.h) */
559 
560 typedef enum{ RP2_CLIENT=0, RP2_SERVER=1, RP2_MULTI=2, RP2_DUMP=3, RP2_HELPER=4 } WHO;
561 typedef enum{ NO_MODE=0, IN_MODE=1, OUT_MODE=2, IN_OUT_MODE=3, C_END=4, MAX_BOUND=5 } MODE;
562 
563 typedef enum{ RPC2_INTEGER_TAG=0,	RPC2_UNSIGNED_TAG=1,	RPC2_BYTE_TAG=2,
564 	      RPC2_STRING_TAG=3,	RPC2_COUNTEDBS_TAG=4,	RPC2_BOUNDEDBS_TAG=5,
565 	      RPC2_BULKDESCRIPTOR_TAG=6,			RPC2_ENCRYPTIONKEY_TAG=7,
566 	      RPC2_STRUCT_TAG=8,	RPC2_ENUM_TAG=9, RPC2_DOUBLE_TAG=10 } TYPE_TAG;
567 
568 
569  /* struct for MakeMulti argument packing and unpacking */
570 
571 typedef
572     struct arg
573 	{
574 	MODE		mode;  /* IN, IN_OUT, OUT, NO_MODE */
575 	TYPE_TAG	type;  /* RPC2 type of argument */
576 	int		size;  /* NOTE: for structures, this is */
577 			    /* REAL size, not packed size */
578 	struct arg	*field;/* nested for structures only */
579 	int		bound; /* used for byte arrays only */
580 	void            (*startlog) (long); /* used for stub logging */
581 	void            (*endlog) (long, RPC2_Integer, RPC2_Handle *, RPC2_Integer *); /* used for stub logging */
582 	}
583     ARG;
584 
585 
586 /* Structure for passing multicast information */
587 typedef
588     struct
589 	{
590 	RPC2_Handle Mgroup;	/*  Multicast group handle*/
591 	RPC2_Integer ExpandHandle;  /* flag indicating whether Mgroup handle should be
592 				             expanded or not */
593 	RPC2_Integer StraySeen; /*  on output, total number of stray responses */
594 	RPC2_Integer StrayLen;  /*  size of array StraySites[]; */
595 	RPC2_HostIdent *StraySites; /* on output, stray hosts that responded;
596 				       some hosts are lost if StraySeen > StrayLen */
597 	}
598     RPC2_Multicast;
599 
600 
601 #define RPC2_MAXLOGLENGTH  32
602 #define RPC2_MAXQUANTUM  ((unsigned)-1)
603 
604 /*
605  * Information is exported via a log consisting of timestamped
606  * variable-length records.  The log entries reflect either
607  * static estimates or actual measurements of the network.  All
608  * connections to a service are coalesced in one log, but the
609  * entries contain the connection ID so they may be demultiplexed
610  * if desired.
611  */
612 typedef enum {RPC2_UNSET_NLE = 0, RPC2_MEASURED_NLE = 1,
613 		  RPC2_STATIC_NLE = 2} NetLogTag;
614 
615 typedef enum {RPC2_MEASUREMENT = 0, SE_MEASUREMENT = 1} NetLogEntryType;
616 
617 typedef
618     struct
619         {
620 	struct timeval TimeStamp;	/* time of log entry */
621 	NetLogTag Tag;			/* what kind of entry am I? */
622 	union
623 	    {
624 	    struct Measured_NLE			/* a measurement */
625 	        {
626 		RPC2_Handle Conn;		/* connection measured */
627 		RPC2_Unsigned Bytes;		/* data bytes involved */
628 		RPC2_Unsigned ElapsedTime;	/* in msec */
629 		}
630 	        Measured;			/* RPC and SFTP use this */
631 
632 	    struct Static_NLE			/* a static estimate */
633 	        {
634 		RPC2_Unsigned Bandwidth;	/* in Bytes/second */
635 	        }				/* latency, cost, ... */
636 	        Static;
637             }
638 	    Value;
639         }
640     RPC2_NetLogEntry;
641 
642 typedef
643     struct
644         {
645 	RPC2_Unsigned Quantum;		/* length of measurements, in msec */
646 	RPC2_Unsigned NumEntries;	/* number of entries requested */
647 	RPC2_Unsigned ValidEntries;	/* number of entries returned */
648 	RPC2_NetLogEntry *Entries;	/* preallocated storage for entries */
649         }
650     RPC2_NetLog;
651 
652 /* STUB predefined struct */
653 typedef struct {
654     RPC2_String name;
655     RPC2_Integer countent;
656     RPC2_Integer countexit;
657     RPC2_Integer tsec;
658     RPC2_Integer tusec;
659     RPC2_Integer counttime;
660 } CallCountEntry;
661 
662 
663 typedef struct {
664     RPC2_String name;
665     RPC2_Integer countent;
666     RPC2_Integer countexit;
667     RPC2_Integer tsec;
668     RPC2_Integer tusec;
669     RPC2_Integer counttime;
670     RPC2_Integer counthost;
671 } MultiCallEntry;
672 
673 
674 typedef struct {
675     RPC2_Integer opengate;
676     RPC2_Integer tsec;
677     RPC2_Integer tusec;
678 } MultiStubWork;
679 
680 /*
681 RPC2 runtime routines:
682 */
683 #include "se.h"
684 #include "multi.h"
685 
686 
687 extern long RPC2_Init (const char *VersionId, RPC2_Options *Options, RPC2_PortIdent *PortList, long RetryCount, struct timeval *KeepAliveInterval);
688 void RPC2_SetLog(FILE *, int);
689 extern long RPC2_Export (RPC2_SubsysIdent *Subsys);
690 extern long RPC2_DeExport (RPC2_SubsysIdent *Subsys);
691 #ifndef NONDEBUG
692 #define RPC2_AllocBuffer(x, y)  (rpc2_AllocBuffer((long) (x), y, __FILE__, (long) __LINE__))
693 #else
694 #define  RPC2_AllocBuffer(x, y)  (rpc2_AllocBuffer((long) (x), y, 0, (long) 0))
695 #endif /* NONDEBUG */
696 extern long rpc2_AllocBuffer (long MinBodySize, RPC2_PacketBuffer **BufferPtr, const char *SrcFile, long SrcLine);
697 extern long RPC2_FreeBuffer (RPC2_PacketBuffer **Buffer);
698 extern long RPC2_SendResponse (RPC2_Handle ConnHandle, RPC2_PacketBuffer *Reply);
699 
700 typedef long RPC2_GetKeys_func(RPC2_Integer *AuthenticationType,
701 			       RPC2_CountedBS *cident,
702 			       RPC2_EncryptionKey SharedSecret,
703 			       RPC2_EncryptionKey sessionkey);
704 typedef long RPC2_AuthFail_func(RPC2_Integer AuthenticationType,
705 				RPC2_CountedBS *cident,
706 				RPC2_Integer EncryptionType,
707 				RPC2_HostIdent *PeerHost,
708 				RPC2_PortIdent *PeerPort);
709 
710 extern long RPC2_GetRequest (RPC2_RequestFilter *Filter,
711 			     RPC2_Handle *ConnHandle,
712 			     RPC2_PacketBuffer **Request,
713 			     struct timeval *Patience, RPC2_GetKeys_func *,
714 			     long EncryptionTypeMask, RPC2_AuthFail_func *);
715 
716 extern long RPC2_MakeRPC (RPC2_Handle ConnHandle, RPC2_PacketBuffer *Request,
717 			  SE_Descriptor *SDesc, RPC2_PacketBuffer **Reply,
718 			  struct timeval *Patience, long EnqueueRequest);
719 
720 typedef long RPC2_UnpackMulti_func(int HowMany,
721 				   RPC2_Handle ConnHandleList[],
722 				   ARG_INFO *ArgInfo,
723 				   RPC2_PacketBuffer *Reply,
724 				   long errcode, long idx);
725 
726 extern long RPC2_MultiRPC (int HowMany, RPC2_Handle ConnHandleList[],
727 			   RPC2_Integer RCList[], RPC2_Multicast *MCast,
728 			   RPC2_PacketBuffer *Request,
729 			   SE_Descriptor SDescList[], RPC2_UnpackMulti_func *,
730 			   ARG_INFO *ArgInfo, struct timeval *BreathOfLife);
731 
732 extern long RPC2_NewBinding (RPC2_HostIdent *Host, RPC2_PortIdent *Port,
733 	 RPC2_SubsysIdent *Subsys, RPC2_BindParms *BParms, RPC2_Handle *ConnHandle);
734 extern long RPC2_InitSideEffect (RPC2_Handle ConnHandle, SE_Descriptor *SDesc);
735 extern long RPC2_CheckSideEffect (RPC2_Handle ConnHandle, SE_Descriptor *SDesc, long Flags);
736 extern long RPC2_Unbind (RPC2_Handle ConnHandle);
737 extern long RPC2_GetPrivatePointer (RPC2_Handle WhichConn, char **PrivatePtr);
738 extern long RPC2_SetPrivatePointer (RPC2_Handle WhichConn, char *PrivatePtr);
739 struct SFTP_Entry;
740 extern long RPC2_GetSEPointer (RPC2_Handle WhichConn, struct SFTP_Entry **SEPtr);
741 extern long RPC2_SetSEPointer (RPC2_Handle WhichConn, struct SFTP_Entry *SEPtr);
742 extern long RPC2_GetPeerInfo (RPC2_Handle WhichConn, RPC2_PeerInfo *PeerInfo);
743 extern char *RPC2_ErrorMsg (long rc);
744 extern long RPC2_DumpTrace (FILE *OutFile, long HowMany);
745 extern long RPC2_DumpState (FILE *OutFile, long Verbosity);
746 extern long RPC2_InitTraceBuffer (long HowMany);
747 extern long RPC2_LamportTime ();
748 extern long RPC2_Enable (RPC2_Handle ConnHandle);
749 extern long RPC2_CreateMgrp (RPC2_Handle *MgroupHandle, RPC2_McastIdent *MulticastHost, RPC2_PortIdent *MulticastPort, RPC2_SubsysIdent *Subsys, RPC2_Integer SecurityLevel, RPC2_EncryptionKey SessionKey, RPC2_Integer EncryptionType, long SideEffectType);
750 extern long RPC2_AddToMgrp (RPC2_Handle MgroupHandle, RPC2_Handle ConnHandle);
751 extern long RPC2_RemoveFromMgrp (RPC2_Handle MgroupHandle, RPC2_Handle ConnHandle);
752 extern long RPC2_DeleteMgrp (RPC2_Handle MgroupHandle);
753 extern long MRPC_MakeMulti (int ServerOp, ARG ArgTypes[], RPC2_Integer HowMany,
754 	RPC2_Handle CIDList[], RPC2_Integer RCList[], RPC2_Multicast *MCast,
755 	RPC2_HandleResult_func *, struct timeval *Timeout,  ...);
756 
757 extern long RPC2_SetColor (RPC2_Handle ConnHandle, RPC2_Integer Color);
758 extern long RPC2_GetColor (RPC2_Handle ConnHandle, RPC2_Integer *Color);
759 extern long RPC2_GetPeerLiveness (RPC2_Handle ConnHandle, struct timeval *Time, struct timeval *SETime);
760 extern long RPC2_GetNetInfo (RPC2_Handle ConnHandle, RPC2_NetLog *RPCLog, RPC2_NetLog *SELog);
761 extern long RPC2_PutNetInfo (RPC2_Handle ConnHandle, RPC2_NetLog *RPCLog, RPC2_NetLog *SELog);
762 extern long RPC2_ClearNetInfo (RPC2_Handle ConnHandle);
763 extern long getsubsysbyname (char *subsysName);
764 extern int RPC2_R2SError (int error);
765 extern int RPC2_S2RError (int error);
766 
767 int RPC2_GetRTT(RPC2_Handle handle, unsigned long *RTT, unsigned long *RTTvar);
768 int RPC2_GetBandwidth(RPC2_Handle handle, unsigned long *BWlow,
769 		      unsigned long *BWavg, unsigned long *BWhigh);
770 int RPC2_GetLastObs(RPC2_Handle handle, struct timeval *tv);
771 
772 int RPC2_SetTimeout(RPC2_Handle whichConn, struct timeval timeout);
773 
774 
775 int struct_len(ARG **a_types, PARM **args);
776 
777 /* These shouldn't really be here: they are internal RPC2 routines
778    But some applications (e.g. Coda auth server) use them */
779 
780 void rpc2_Encrypt (char *FromBuffer, char *ToBuffer, size_t HowManyBytes,
781 		   RPC2_EncryptionKey WhichKey, RPC2_Integer EncryptionType);
782 
783 void rpc2_Decrypt (char *FromBuffer, char *ToBuffer, size_t HowManyBytes,
784 		   RPC2_EncryptionKey WhichKey, RPC2_Integer EncryptionType);
785 
786 void rpc2_InitRandom(void);
787 unsigned int rpc2_NextRandom (char *StatePtr);
788 
789 /* hack until we can do something more sophisticated. */
790 extern long rpc2_Bandwidth;
791 
792 /* for multihomed servers */
793 struct in_addr RPC2_setip(struct in_addr *ip); /* deprecated */
794 void RPC2_setbindaddr(RPC2_HostIdent *host);
795 
796 
797 /*------- Transmission Statistics -------------*/
798 struct SStats
799     {
800     unsigned long
801 	Total,     /* PacketsSent */
802     	Retries,   /* PacketRetries */
803 	Cancelled, /* Packet Retries Cancelled (heard from side effect) */
804 	Multicasts,/* MulticastsSent */
805 	Busies,    /* BusiesSent */
806     	Naks,      /* NaksSent */
807 	Bytes;     /* BytesSent */
808     };
809 
810 
811 struct RStats
812     {
813     unsigned long
814 	Total,	       /* PacketsRecvd */
815 	Giant,	       /* GiantPacketsRecvd */
816 	Replies,       /* Replies */
817 	Requests,      /* Requests */
818 	GoodReplies,  /* GoodReplies */
819 	GoodRequests, /* GoodRequests */
820 	Multicasts,   /* MulticastRequests */
821 	GoodMulticasts, /* GoodMulticastRequests */
822 	Busies,       /* BusiesReceived */
823 	GoodBusies,   /* GoodBusies */
824 	Bogus,         /* BogusPackets */
825 	Naks,         /* NaksReceived */
826 	Bytes;	       /* BytesReceived */
827 
828     };
829 
830 extern struct SStats rpc2_Sent;
831 extern struct RStats rpc2_Recvd;
832 extern struct SStats rpc2_MSent;
833 extern struct RStats rpc2_MRecvd;
834 
835 extern int rpc2_43bsd;	/* TRUE  on 4.3BSD, FALSE on 4.2BSD */
836 
837 /* For debugging */
838 extern FILE *rpc2_logfile;
839 extern FILE *rpc2_tracefile;
840 extern int RPC2_enableReaping;
841 
842 /* What port are we listening on. */
843 extern RPC2_HostIdent   rpc2_LocalHost;
844 extern RPC2_PortIdent   rpc2_LocalPort;
845 
846 /* Allocation/destruction counters */
847 extern long rpc2_PBSmallCreationCount,  rpc2_PBSmallFreeCount;
848 extern long rpc2_PBMediumCreationCount, rpc2_PBMediumFreeCount;
849 extern long rpc2_PBLargeCreationCount,  rpc2_PBLargeFreeCount;
850 extern long rpc2_SLCreationCount,       rpc2_SLFreeCount;
851 extern long rpc2_ConnCreationCount,     rpc2_ConnCount,	rpc2_ConnFreeCount;
852 extern long rpc2_SSCreationCount,	rpc2_SSCount,   rpc2_SSFreeCount;
853 extern long rpc2_Unbinds, rpc2_FreeConns, rpc2_AllocConns, rpc2_GCConns;
854 extern long rpc2_PBCount, rpc2_PBHoldCount, rpc2_PBFreezeCount;
855 extern long rpc2_FreezeHWMark, rpc2_HoldHWMark;
856 
857 #endif /* _RPC2_ */
858