xref: /minix3/external/bsd/tcpdump/dist/print-rx.c (revision b636d99d91c3d54204248f643c14627405d4afd1)
1*b636d99dSDavid van Moolenbroek /*
2*b636d99dSDavid van Moolenbroek  * Copyright: (c) 2000 United States Government as represented by the
3*b636d99dSDavid van Moolenbroek  *	Secretary of the Navy. All rights reserved.
4*b636d99dSDavid van Moolenbroek  *
5*b636d99dSDavid van Moolenbroek  * Redistribution and use in source and binary forms, with or without
6*b636d99dSDavid van Moolenbroek  * modification, are permitted provided that the following conditions
7*b636d99dSDavid van Moolenbroek  * are met:
8*b636d99dSDavid van Moolenbroek  *
9*b636d99dSDavid van Moolenbroek  *   1. Redistributions of source code must retain the above copyright
10*b636d99dSDavid van Moolenbroek  *      notice, this list of conditions and the following disclaimer.
11*b636d99dSDavid van Moolenbroek  *   2. Redistributions in binary form must reproduce the above copyright
12*b636d99dSDavid van Moolenbroek  *      notice, this list of conditions and the following disclaimer in
13*b636d99dSDavid van Moolenbroek  *      the documentation and/or other materials provided with the
14*b636d99dSDavid van Moolenbroek  *      distribution.
15*b636d99dSDavid van Moolenbroek  *   3. The names of the authors may not be used to endorse or promote
16*b636d99dSDavid van Moolenbroek  *      products derived from this software without specific prior
17*b636d99dSDavid van Moolenbroek  *      written permission.
18*b636d99dSDavid van Moolenbroek  *
19*b636d99dSDavid van Moolenbroek  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
20*b636d99dSDavid van Moolenbroek  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
21*b636d99dSDavid van Moolenbroek  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22*b636d99dSDavid van Moolenbroek  */
23*b636d99dSDavid van Moolenbroek /*
24*b636d99dSDavid van Moolenbroek  * This code unmangles RX packets.  RX is the mutant form of RPC that AFS
25*b636d99dSDavid van Moolenbroek  * uses to communicate between clients and servers.
26*b636d99dSDavid van Moolenbroek  *
27*b636d99dSDavid van Moolenbroek  * In this code, I mainly concern myself with decoding the AFS calls, not
28*b636d99dSDavid van Moolenbroek  * with the guts of RX, per se.
29*b636d99dSDavid van Moolenbroek  *
30*b636d99dSDavid van Moolenbroek  * Bah.  If I never look at rx_packet.h again, it will be too soon.
31*b636d99dSDavid van Moolenbroek  *
32*b636d99dSDavid van Moolenbroek  * Ken Hornstein <kenh@cmf.nrl.navy.mil>
33*b636d99dSDavid van Moolenbroek  */
34*b636d99dSDavid van Moolenbroek 
35*b636d99dSDavid van Moolenbroek #include <sys/cdefs.h>
36*b636d99dSDavid van Moolenbroek #ifndef lint
37*b636d99dSDavid van Moolenbroek __RCSID("$NetBSD: print-rx.c,v 1.5 2014/11/20 03:05:03 christos Exp $");
38*b636d99dSDavid van Moolenbroek #endif
39*b636d99dSDavid van Moolenbroek 
40*b636d99dSDavid van Moolenbroek #define NETDISSECT_REWORKED
41*b636d99dSDavid van Moolenbroek #ifdef HAVE_CONFIG_H
42*b636d99dSDavid van Moolenbroek #include "config.h"
43*b636d99dSDavid van Moolenbroek #endif
44*b636d99dSDavid van Moolenbroek 
45*b636d99dSDavid van Moolenbroek #include <stdio.h>
46*b636d99dSDavid van Moolenbroek #include <stdlib.h>
47*b636d99dSDavid van Moolenbroek #include <string.h>
48*b636d99dSDavid van Moolenbroek #include <tcpdump-stdinc.h>
49*b636d99dSDavid van Moolenbroek 
50*b636d99dSDavid van Moolenbroek #include "interface.h"
51*b636d99dSDavid van Moolenbroek #include "addrtoname.h"
52*b636d99dSDavid van Moolenbroek #include "extract.h"
53*b636d99dSDavid van Moolenbroek 
54*b636d99dSDavid van Moolenbroek #include "ip.h"
55*b636d99dSDavid van Moolenbroek 
56*b636d99dSDavid van Moolenbroek #define FS_RX_PORT	7000
57*b636d99dSDavid van Moolenbroek #define CB_RX_PORT	7001
58*b636d99dSDavid van Moolenbroek #define PROT_RX_PORT	7002
59*b636d99dSDavid van Moolenbroek #define VLDB_RX_PORT	7003
60*b636d99dSDavid van Moolenbroek #define KAUTH_RX_PORT	7004
61*b636d99dSDavid van Moolenbroek #define VOL_RX_PORT	7005
62*b636d99dSDavid van Moolenbroek #define ERROR_RX_PORT	7006		/* Doesn't seem to be used */
63*b636d99dSDavid van Moolenbroek #define BOS_RX_PORT	7007
64*b636d99dSDavid van Moolenbroek 
65*b636d99dSDavid van Moolenbroek #define AFSNAMEMAX 256
66*b636d99dSDavid van Moolenbroek #define AFSOPAQUEMAX 1024
67*b636d99dSDavid van Moolenbroek #define PRNAMEMAX 64
68*b636d99dSDavid van Moolenbroek #define VLNAMEMAX 65
69*b636d99dSDavid van Moolenbroek #define KANAMEMAX 64
70*b636d99dSDavid van Moolenbroek #define BOSNAMEMAX 256
71*b636d99dSDavid van Moolenbroek 
72*b636d99dSDavid van Moolenbroek #define	PRSFS_READ		1 /* Read files */
73*b636d99dSDavid van Moolenbroek #define	PRSFS_WRITE		2 /* Write files */
74*b636d99dSDavid van Moolenbroek #define	PRSFS_INSERT		4 /* Insert files into a directory */
75*b636d99dSDavid van Moolenbroek #define	PRSFS_LOOKUP		8 /* Lookup files into a directory */
76*b636d99dSDavid van Moolenbroek #define	PRSFS_DELETE		16 /* Delete files */
77*b636d99dSDavid van Moolenbroek #define	PRSFS_LOCK		32 /* Lock files */
78*b636d99dSDavid van Moolenbroek #define	PRSFS_ADMINISTER	64 /* Change ACL's */
79*b636d99dSDavid van Moolenbroek 
80*b636d99dSDavid van Moolenbroek struct rx_header {
81*b636d99dSDavid van Moolenbroek 	uint32_t epoch;
82*b636d99dSDavid van Moolenbroek 	uint32_t cid;
83*b636d99dSDavid van Moolenbroek 	uint32_t callNumber;
84*b636d99dSDavid van Moolenbroek 	uint32_t seq;
85*b636d99dSDavid van Moolenbroek 	uint32_t serial;
86*b636d99dSDavid van Moolenbroek 	uint8_t type;
87*b636d99dSDavid van Moolenbroek #define RX_PACKET_TYPE_DATA		1
88*b636d99dSDavid van Moolenbroek #define RX_PACKET_TYPE_ACK		2
89*b636d99dSDavid van Moolenbroek #define RX_PACKET_TYPE_BUSY		3
90*b636d99dSDavid van Moolenbroek #define RX_PACKET_TYPE_ABORT		4
91*b636d99dSDavid van Moolenbroek #define RX_PACKET_TYPE_ACKALL		5
92*b636d99dSDavid van Moolenbroek #define RX_PACKET_TYPE_CHALLENGE	6
93*b636d99dSDavid van Moolenbroek #define RX_PACKET_TYPE_RESPONSE		7
94*b636d99dSDavid van Moolenbroek #define RX_PACKET_TYPE_DEBUG		8
95*b636d99dSDavid van Moolenbroek #define RX_PACKET_TYPE_PARAMS		9
96*b636d99dSDavid van Moolenbroek #define RX_PACKET_TYPE_VERSION		13
97*b636d99dSDavid van Moolenbroek 	uint8_t flags;
98*b636d99dSDavid van Moolenbroek #define RX_CLIENT_INITIATED	1
99*b636d99dSDavid van Moolenbroek #define RX_REQUEST_ACK		2
100*b636d99dSDavid van Moolenbroek #define RX_LAST_PACKET		4
101*b636d99dSDavid van Moolenbroek #define RX_MORE_PACKETS		8
102*b636d99dSDavid van Moolenbroek #define RX_FREE_PACKET		16
103*b636d99dSDavid van Moolenbroek #define RX_SLOW_START_OK	32
104*b636d99dSDavid van Moolenbroek #define RX_JUMBO_PACKET		32
105*b636d99dSDavid van Moolenbroek 	uint8_t userStatus;
106*b636d99dSDavid van Moolenbroek 	uint8_t securityIndex;
107*b636d99dSDavid van Moolenbroek 	uint16_t spare;		/* How clever: even though the AFS */
108*b636d99dSDavid van Moolenbroek 	uint16_t serviceId;		/* header files indicate that the */
109*b636d99dSDavid van Moolenbroek };					/* serviceId is first, it's really */
110*b636d99dSDavid van Moolenbroek 					/* encoded _after_ the spare field */
111*b636d99dSDavid van Moolenbroek 					/* I wasted a day figuring that out! */
112*b636d99dSDavid van Moolenbroek 
113*b636d99dSDavid van Moolenbroek #define NUM_RX_FLAGS 7
114*b636d99dSDavid van Moolenbroek 
115*b636d99dSDavid van Moolenbroek #define RX_MAXACKS 255
116*b636d99dSDavid van Moolenbroek 
117*b636d99dSDavid van Moolenbroek struct rx_ackPacket {
118*b636d99dSDavid van Moolenbroek 	uint16_t bufferSpace;		/* Number of packet buffers available */
119*b636d99dSDavid van Moolenbroek 	uint16_t maxSkew;		/* Max diff between ack'd packet and */
120*b636d99dSDavid van Moolenbroek 					/* highest packet received */
121*b636d99dSDavid van Moolenbroek 	uint32_t firstPacket;		/* The first packet in ack list */
122*b636d99dSDavid van Moolenbroek 	uint32_t previousPacket;	/* Previous packet recv'd (obsolete) */
123*b636d99dSDavid van Moolenbroek 	uint32_t serial;		/* # of packet that prompted the ack */
124*b636d99dSDavid van Moolenbroek 	uint8_t reason;		/* Reason for acknowledgement */
125*b636d99dSDavid van Moolenbroek 	uint8_t nAcks;			/* Number of acknowledgements */
126*b636d99dSDavid van Moolenbroek 	uint8_t acks[RX_MAXACKS];	/* Up to RX_MAXACKS acknowledgements */
127*b636d99dSDavid van Moolenbroek };
128*b636d99dSDavid van Moolenbroek 
129*b636d99dSDavid van Moolenbroek /*
130*b636d99dSDavid van Moolenbroek  * Values for the acks array
131*b636d99dSDavid van Moolenbroek  */
132*b636d99dSDavid van Moolenbroek 
133*b636d99dSDavid van Moolenbroek #define RX_ACK_TYPE_NACK	0	/* Don't have this packet */
134*b636d99dSDavid van Moolenbroek #define RX_ACK_TYPE_ACK		1	/* I have this packet */
135*b636d99dSDavid van Moolenbroek 
136*b636d99dSDavid van Moolenbroek static const struct tok rx_types[] = {
137*b636d99dSDavid van Moolenbroek 	{ RX_PACKET_TYPE_DATA,		"data" },
138*b636d99dSDavid van Moolenbroek 	{ RX_PACKET_TYPE_ACK,		"ack" },
139*b636d99dSDavid van Moolenbroek 	{ RX_PACKET_TYPE_BUSY,		"busy" },
140*b636d99dSDavid van Moolenbroek 	{ RX_PACKET_TYPE_ABORT,		"abort" },
141*b636d99dSDavid van Moolenbroek 	{ RX_PACKET_TYPE_ACKALL,	"ackall" },
142*b636d99dSDavid van Moolenbroek 	{ RX_PACKET_TYPE_CHALLENGE,	"challenge" },
143*b636d99dSDavid van Moolenbroek 	{ RX_PACKET_TYPE_RESPONSE,	"response" },
144*b636d99dSDavid van Moolenbroek 	{ RX_PACKET_TYPE_DEBUG,		"debug" },
145*b636d99dSDavid van Moolenbroek 	{ RX_PACKET_TYPE_PARAMS,	"params" },
146*b636d99dSDavid van Moolenbroek 	{ RX_PACKET_TYPE_VERSION,	"version" },
147*b636d99dSDavid van Moolenbroek 	{ 0,				NULL },
148*b636d99dSDavid van Moolenbroek };
149*b636d99dSDavid van Moolenbroek 
150*b636d99dSDavid van Moolenbroek static const struct double_tok {
151*b636d99dSDavid van Moolenbroek 	int flag;		/* Rx flag */
152*b636d99dSDavid van Moolenbroek 	int packetType;		/* Packet type */
153*b636d99dSDavid van Moolenbroek 	const char *s;		/* Flag string */
154*b636d99dSDavid van Moolenbroek } rx_flags[] = {
155*b636d99dSDavid van Moolenbroek 	{ RX_CLIENT_INITIATED,	0,			"client-init" },
156*b636d99dSDavid van Moolenbroek 	{ RX_REQUEST_ACK,	0,			"req-ack" },
157*b636d99dSDavid van Moolenbroek 	{ RX_LAST_PACKET,	0,			"last-pckt" },
158*b636d99dSDavid van Moolenbroek 	{ RX_MORE_PACKETS,	0,			"more-pckts" },
159*b636d99dSDavid van Moolenbroek 	{ RX_FREE_PACKET,	0,			"free-pckt" },
160*b636d99dSDavid van Moolenbroek 	{ RX_SLOW_START_OK,	RX_PACKET_TYPE_ACK,	"slow-start" },
161*b636d99dSDavid van Moolenbroek 	{ RX_JUMBO_PACKET,	RX_PACKET_TYPE_DATA,	"jumbogram" }
162*b636d99dSDavid van Moolenbroek };
163*b636d99dSDavid van Moolenbroek 
164*b636d99dSDavid van Moolenbroek static const struct tok fs_req[] = {
165*b636d99dSDavid van Moolenbroek 	{ 130,		"fetch-data" },
166*b636d99dSDavid van Moolenbroek 	{ 131,		"fetch-acl" },
167*b636d99dSDavid van Moolenbroek 	{ 132,		"fetch-status" },
168*b636d99dSDavid van Moolenbroek 	{ 133,		"store-data" },
169*b636d99dSDavid van Moolenbroek 	{ 134,		"store-acl" },
170*b636d99dSDavid van Moolenbroek 	{ 135,		"store-status" },
171*b636d99dSDavid van Moolenbroek 	{ 136,		"remove-file" },
172*b636d99dSDavid van Moolenbroek 	{ 137,		"create-file" },
173*b636d99dSDavid van Moolenbroek 	{ 138,		"rename" },
174*b636d99dSDavid van Moolenbroek 	{ 139,		"symlink" },
175*b636d99dSDavid van Moolenbroek 	{ 140,		"link" },
176*b636d99dSDavid van Moolenbroek 	{ 141,		"makedir" },
177*b636d99dSDavid van Moolenbroek 	{ 142,		"rmdir" },
178*b636d99dSDavid van Moolenbroek 	{ 143,		"oldsetlock" },
179*b636d99dSDavid van Moolenbroek 	{ 144,		"oldextlock" },
180*b636d99dSDavid van Moolenbroek 	{ 145,		"oldrellock" },
181*b636d99dSDavid van Moolenbroek 	{ 146,		"get-stats" },
182*b636d99dSDavid van Moolenbroek 	{ 147,		"give-cbs" },
183*b636d99dSDavid van Moolenbroek 	{ 148,		"get-vlinfo" },
184*b636d99dSDavid van Moolenbroek 	{ 149,		"get-vlstats" },
185*b636d99dSDavid van Moolenbroek 	{ 150,		"set-vlstats" },
186*b636d99dSDavid van Moolenbroek 	{ 151,		"get-rootvl" },
187*b636d99dSDavid van Moolenbroek 	{ 152,		"check-token" },
188*b636d99dSDavid van Moolenbroek 	{ 153,		"get-time" },
189*b636d99dSDavid van Moolenbroek 	{ 154,		"nget-vlinfo" },
190*b636d99dSDavid van Moolenbroek 	{ 155,		"bulk-stat" },
191*b636d99dSDavid van Moolenbroek 	{ 156,		"setlock" },
192*b636d99dSDavid van Moolenbroek 	{ 157,		"extlock" },
193*b636d99dSDavid van Moolenbroek 	{ 158,		"rellock" },
194*b636d99dSDavid van Moolenbroek 	{ 159,		"xstat-ver" },
195*b636d99dSDavid van Moolenbroek 	{ 160,		"get-xstat" },
196*b636d99dSDavid van Moolenbroek 	{ 161,		"dfs-lookup" },
197*b636d99dSDavid van Moolenbroek 	{ 162,		"dfs-flushcps" },
198*b636d99dSDavid van Moolenbroek 	{ 163,		"dfs-symlink" },
199*b636d99dSDavid van Moolenbroek 	{ 220,		"residency" },
200*b636d99dSDavid van Moolenbroek 	{ 65536,        "inline-bulk-status" },
201*b636d99dSDavid van Moolenbroek 	{ 65537,        "fetch-data-64" },
202*b636d99dSDavid van Moolenbroek 	{ 65538,        "store-data-64" },
203*b636d99dSDavid van Moolenbroek 	{ 65539,        "give-up-all-cbs" },
204*b636d99dSDavid van Moolenbroek 	{ 65540,        "get-caps" },
205*b636d99dSDavid van Moolenbroek 	{ 65541,        "cb-rx-conn-addr" },
206*b636d99dSDavid van Moolenbroek 	{ 0,		NULL },
207*b636d99dSDavid van Moolenbroek };
208*b636d99dSDavid van Moolenbroek 
209*b636d99dSDavid van Moolenbroek static const struct tok cb_req[] = {
210*b636d99dSDavid van Moolenbroek 	{ 204,		"callback" },
211*b636d99dSDavid van Moolenbroek 	{ 205,		"initcb" },
212*b636d99dSDavid van Moolenbroek 	{ 206,		"probe" },
213*b636d99dSDavid van Moolenbroek 	{ 207,		"getlock" },
214*b636d99dSDavid van Moolenbroek 	{ 208,		"getce" },
215*b636d99dSDavid van Moolenbroek 	{ 209,		"xstatver" },
216*b636d99dSDavid van Moolenbroek 	{ 210,		"getxstat" },
217*b636d99dSDavid van Moolenbroek 	{ 211,		"initcb2" },
218*b636d99dSDavid van Moolenbroek 	{ 212,		"whoareyou" },
219*b636d99dSDavid van Moolenbroek 	{ 213,		"initcb3" },
220*b636d99dSDavid van Moolenbroek 	{ 214,		"probeuuid" },
221*b636d99dSDavid van Moolenbroek 	{ 215,		"getsrvprefs" },
222*b636d99dSDavid van Moolenbroek 	{ 216,		"getcellservdb" },
223*b636d99dSDavid van Moolenbroek 	{ 217,		"getlocalcell" },
224*b636d99dSDavid van Moolenbroek 	{ 218,		"getcacheconf" },
225*b636d99dSDavid van Moolenbroek 	{ 65536,        "getce64" },
226*b636d99dSDavid van Moolenbroek 	{ 65537,        "getcellbynum" },
227*b636d99dSDavid van Moolenbroek 	{ 65538,        "tellmeaboutyourself" },
228*b636d99dSDavid van Moolenbroek 	{ 0,		NULL },
229*b636d99dSDavid van Moolenbroek };
230*b636d99dSDavid van Moolenbroek 
231*b636d99dSDavid van Moolenbroek static const struct tok pt_req[] = {
232*b636d99dSDavid van Moolenbroek 	{ 500,		"new-user" },
233*b636d99dSDavid van Moolenbroek 	{ 501,		"where-is-it" },
234*b636d99dSDavid van Moolenbroek 	{ 502,		"dump-entry" },
235*b636d99dSDavid van Moolenbroek 	{ 503,		"add-to-group" },
236*b636d99dSDavid van Moolenbroek 	{ 504,		"name-to-id" },
237*b636d99dSDavid van Moolenbroek 	{ 505,		"id-to-name" },
238*b636d99dSDavid van Moolenbroek 	{ 506,		"delete" },
239*b636d99dSDavid van Moolenbroek 	{ 507,		"remove-from-group" },
240*b636d99dSDavid van Moolenbroek 	{ 508,		"get-cps" },
241*b636d99dSDavid van Moolenbroek 	{ 509,		"new-entry" },
242*b636d99dSDavid van Moolenbroek 	{ 510,		"list-max" },
243*b636d99dSDavid van Moolenbroek 	{ 511,		"set-max" },
244*b636d99dSDavid van Moolenbroek 	{ 512,		"list-entry" },
245*b636d99dSDavid van Moolenbroek 	{ 513,		"change-entry" },
246*b636d99dSDavid van Moolenbroek 	{ 514,		"list-elements" },
247*b636d99dSDavid van Moolenbroek 	{ 515,		"same-mbr-of" },
248*b636d99dSDavid van Moolenbroek 	{ 516,		"set-fld-sentry" },
249*b636d99dSDavid van Moolenbroek 	{ 517,		"list-owned" },
250*b636d99dSDavid van Moolenbroek 	{ 518,		"get-cps2" },
251*b636d99dSDavid van Moolenbroek 	{ 519,		"get-host-cps" },
252*b636d99dSDavid van Moolenbroek 	{ 520,		"update-entry" },
253*b636d99dSDavid van Moolenbroek 	{ 521,		"list-entries" },
254*b636d99dSDavid van Moolenbroek 	{ 530,		"list-super-groups" },
255*b636d99dSDavid van Moolenbroek 	{ 0,		NULL },
256*b636d99dSDavid van Moolenbroek };
257*b636d99dSDavid van Moolenbroek 
258*b636d99dSDavid van Moolenbroek static const struct tok vldb_req[] = {
259*b636d99dSDavid van Moolenbroek 	{ 501,		"create-entry" },
260*b636d99dSDavid van Moolenbroek 	{ 502,		"delete-entry" },
261*b636d99dSDavid van Moolenbroek 	{ 503,		"get-entry-by-id" },
262*b636d99dSDavid van Moolenbroek 	{ 504,		"get-entry-by-name" },
263*b636d99dSDavid van Moolenbroek 	{ 505,		"get-new-volume-id" },
264*b636d99dSDavid van Moolenbroek 	{ 506,		"replace-entry" },
265*b636d99dSDavid van Moolenbroek 	{ 507,		"update-entry" },
266*b636d99dSDavid van Moolenbroek 	{ 508,		"setlock" },
267*b636d99dSDavid van Moolenbroek 	{ 509,		"releaselock" },
268*b636d99dSDavid van Moolenbroek 	{ 510,		"list-entry" },
269*b636d99dSDavid van Moolenbroek 	{ 511,		"list-attrib" },
270*b636d99dSDavid van Moolenbroek 	{ 512,		"linked-list" },
271*b636d99dSDavid van Moolenbroek 	{ 513,		"get-stats" },
272*b636d99dSDavid van Moolenbroek 	{ 514,		"probe" },
273*b636d99dSDavid van Moolenbroek 	{ 515,		"get-addrs" },
274*b636d99dSDavid van Moolenbroek 	{ 516,		"change-addr" },
275*b636d99dSDavid van Moolenbroek 	{ 517,		"create-entry-n" },
276*b636d99dSDavid van Moolenbroek 	{ 518,		"get-entry-by-id-n" },
277*b636d99dSDavid van Moolenbroek 	{ 519,		"get-entry-by-name-n" },
278*b636d99dSDavid van Moolenbroek 	{ 520,		"replace-entry-n" },
279*b636d99dSDavid van Moolenbroek 	{ 521,		"list-entry-n" },
280*b636d99dSDavid van Moolenbroek 	{ 522,		"list-attrib-n" },
281*b636d99dSDavid van Moolenbroek 	{ 523,		"linked-list-n" },
282*b636d99dSDavid van Moolenbroek 	{ 524,		"update-entry-by-name" },
283*b636d99dSDavid van Moolenbroek 	{ 525,		"create-entry-u" },
284*b636d99dSDavid van Moolenbroek 	{ 526,		"get-entry-by-id-u" },
285*b636d99dSDavid van Moolenbroek 	{ 527,		"get-entry-by-name-u" },
286*b636d99dSDavid van Moolenbroek 	{ 528,		"replace-entry-u" },
287*b636d99dSDavid van Moolenbroek 	{ 529,		"list-entry-u" },
288*b636d99dSDavid van Moolenbroek 	{ 530,		"list-attrib-u" },
289*b636d99dSDavid van Moolenbroek 	{ 531,		"linked-list-u" },
290*b636d99dSDavid van Moolenbroek 	{ 532,		"regaddr" },
291*b636d99dSDavid van Moolenbroek 	{ 533,		"get-addrs-u" },
292*b636d99dSDavid van Moolenbroek 	{ 534,		"list-attrib-n2" },
293*b636d99dSDavid van Moolenbroek 	{ 0,		NULL },
294*b636d99dSDavid van Moolenbroek };
295*b636d99dSDavid van Moolenbroek 
296*b636d99dSDavid van Moolenbroek static const struct tok kauth_req[] = {
297*b636d99dSDavid van Moolenbroek 	{ 1,		"auth-old" },
298*b636d99dSDavid van Moolenbroek 	{ 21,		"authenticate" },
299*b636d99dSDavid van Moolenbroek 	{ 22,		"authenticate-v2" },
300*b636d99dSDavid van Moolenbroek 	{ 2,		"change-pw" },
301*b636d99dSDavid van Moolenbroek 	{ 3,		"get-ticket-old" },
302*b636d99dSDavid van Moolenbroek 	{ 23,		"get-ticket" },
303*b636d99dSDavid van Moolenbroek 	{ 4,		"set-pw" },
304*b636d99dSDavid van Moolenbroek 	{ 5,		"set-fields" },
305*b636d99dSDavid van Moolenbroek 	{ 6,		"create-user" },
306*b636d99dSDavid van Moolenbroek 	{ 7,		"delete-user" },
307*b636d99dSDavid van Moolenbroek 	{ 8,		"get-entry" },
308*b636d99dSDavid van Moolenbroek 	{ 9,		"list-entry" },
309*b636d99dSDavid van Moolenbroek 	{ 10,		"get-stats" },
310*b636d99dSDavid van Moolenbroek 	{ 11,		"debug" },
311*b636d99dSDavid van Moolenbroek 	{ 12,		"get-pw" },
312*b636d99dSDavid van Moolenbroek 	{ 13,		"get-random-key" },
313*b636d99dSDavid van Moolenbroek 	{ 14,		"unlock" },
314*b636d99dSDavid van Moolenbroek 	{ 15,		"lock-status" },
315*b636d99dSDavid van Moolenbroek 	{ 0,		NULL },
316*b636d99dSDavid van Moolenbroek };
317*b636d99dSDavid van Moolenbroek 
318*b636d99dSDavid van Moolenbroek static const struct tok vol_req[] = {
319*b636d99dSDavid van Moolenbroek 	{ 100,		"create-volume" },
320*b636d99dSDavid van Moolenbroek 	{ 101,		"delete-volume" },
321*b636d99dSDavid van Moolenbroek 	{ 102,		"restore" },
322*b636d99dSDavid van Moolenbroek 	{ 103,		"forward" },
323*b636d99dSDavid van Moolenbroek 	{ 104,		"end-trans" },
324*b636d99dSDavid van Moolenbroek 	{ 105,		"clone" },
325*b636d99dSDavid van Moolenbroek 	{ 106,		"set-flags" },
326*b636d99dSDavid van Moolenbroek 	{ 107,		"get-flags" },
327*b636d99dSDavid van Moolenbroek 	{ 108,		"trans-create" },
328*b636d99dSDavid van Moolenbroek 	{ 109,		"dump" },
329*b636d99dSDavid van Moolenbroek 	{ 110,		"get-nth-volume" },
330*b636d99dSDavid van Moolenbroek 	{ 111,		"set-forwarding" },
331*b636d99dSDavid van Moolenbroek 	{ 112,		"get-name" },
332*b636d99dSDavid van Moolenbroek 	{ 113,		"get-status" },
333*b636d99dSDavid van Moolenbroek 	{ 114,		"sig-restore" },
334*b636d99dSDavid van Moolenbroek 	{ 115,		"list-partitions" },
335*b636d99dSDavid van Moolenbroek 	{ 116,		"list-volumes" },
336*b636d99dSDavid van Moolenbroek 	{ 117,		"set-id-types" },
337*b636d99dSDavid van Moolenbroek 	{ 118,		"monitor" },
338*b636d99dSDavid van Moolenbroek 	{ 119,		"partition-info" },
339*b636d99dSDavid van Moolenbroek 	{ 120,		"reclone" },
340*b636d99dSDavid van Moolenbroek 	{ 121,		"list-one-volume" },
341*b636d99dSDavid van Moolenbroek 	{ 122,		"nuke" },
342*b636d99dSDavid van Moolenbroek 	{ 123,		"set-date" },
343*b636d99dSDavid van Moolenbroek 	{ 124,		"x-list-volumes" },
344*b636d99dSDavid van Moolenbroek 	{ 125,		"x-list-one-volume" },
345*b636d99dSDavid van Moolenbroek 	{ 126,		"set-info" },
346*b636d99dSDavid van Moolenbroek 	{ 127,		"x-list-partitions" },
347*b636d99dSDavid van Moolenbroek 	{ 128,		"forward-multiple" },
348*b636d99dSDavid van Moolenbroek 	{ 65536,	"convert-ro" },
349*b636d99dSDavid van Moolenbroek 	{ 65537,	"get-size" },
350*b636d99dSDavid van Moolenbroek 	{ 65538,	"dump-v2" },
351*b636d99dSDavid van Moolenbroek 	{ 0,		NULL },
352*b636d99dSDavid van Moolenbroek };
353*b636d99dSDavid van Moolenbroek 
354*b636d99dSDavid van Moolenbroek static const struct tok bos_req[] = {
355*b636d99dSDavid van Moolenbroek 	{ 80,		"create-bnode" },
356*b636d99dSDavid van Moolenbroek 	{ 81,		"delete-bnode" },
357*b636d99dSDavid van Moolenbroek 	{ 82,		"set-status" },
358*b636d99dSDavid van Moolenbroek 	{ 83,		"get-status" },
359*b636d99dSDavid van Moolenbroek 	{ 84,		"enumerate-instance" },
360*b636d99dSDavid van Moolenbroek 	{ 85,		"get-instance-info" },
361*b636d99dSDavid van Moolenbroek 	{ 86,		"get-instance-parm" },
362*b636d99dSDavid van Moolenbroek 	{ 87,		"add-superuser" },
363*b636d99dSDavid van Moolenbroek 	{ 88,		"delete-superuser" },
364*b636d99dSDavid van Moolenbroek 	{ 89,		"list-superusers" },
365*b636d99dSDavid van Moolenbroek 	{ 90,		"list-keys" },
366*b636d99dSDavid van Moolenbroek 	{ 91,		"add-key" },
367*b636d99dSDavid van Moolenbroek 	{ 92,		"delete-key" },
368*b636d99dSDavid van Moolenbroek 	{ 93,		"set-cell-name" },
369*b636d99dSDavid van Moolenbroek 	{ 94,		"get-cell-name" },
370*b636d99dSDavid van Moolenbroek 	{ 95,		"get-cell-host" },
371*b636d99dSDavid van Moolenbroek 	{ 96,		"add-cell-host" },
372*b636d99dSDavid van Moolenbroek 	{ 97,		"delete-cell-host" },
373*b636d99dSDavid van Moolenbroek 	{ 98,		"set-t-status" },
374*b636d99dSDavid van Moolenbroek 	{ 99,		"shutdown-all" },
375*b636d99dSDavid van Moolenbroek 	{ 100,		"restart-all" },
376*b636d99dSDavid van Moolenbroek 	{ 101,		"startup-all" },
377*b636d99dSDavid van Moolenbroek 	{ 102,		"set-noauth-flag" },
378*b636d99dSDavid van Moolenbroek 	{ 103,		"re-bozo" },
379*b636d99dSDavid van Moolenbroek 	{ 104,		"restart" },
380*b636d99dSDavid van Moolenbroek 	{ 105,		"start-bozo-install" },
381*b636d99dSDavid van Moolenbroek 	{ 106,		"uninstall" },
382*b636d99dSDavid van Moolenbroek 	{ 107,		"get-dates" },
383*b636d99dSDavid van Moolenbroek 	{ 108,		"exec" },
384*b636d99dSDavid van Moolenbroek 	{ 109,		"prune" },
385*b636d99dSDavid van Moolenbroek 	{ 110,		"set-restart-time" },
386*b636d99dSDavid van Moolenbroek 	{ 111,		"get-restart-time" },
387*b636d99dSDavid van Moolenbroek 	{ 112,		"start-bozo-log" },
388*b636d99dSDavid van Moolenbroek 	{ 113,		"wait-all" },
389*b636d99dSDavid van Moolenbroek 	{ 114,		"get-instance-strings" },
390*b636d99dSDavid van Moolenbroek 	{ 115,		"get-restricted" },
391*b636d99dSDavid van Moolenbroek 	{ 116,		"set-restricted" },
392*b636d99dSDavid van Moolenbroek 	{ 0,		NULL },
393*b636d99dSDavid van Moolenbroek };
394*b636d99dSDavid van Moolenbroek 
395*b636d99dSDavid van Moolenbroek static const struct tok ubik_req[] = {
396*b636d99dSDavid van Moolenbroek 	{ 10000,	"vote-beacon" },
397*b636d99dSDavid van Moolenbroek 	{ 10001,	"vote-debug-old" },
398*b636d99dSDavid van Moolenbroek 	{ 10002,	"vote-sdebug-old" },
399*b636d99dSDavid van Moolenbroek 	{ 10003,	"vote-getsyncsite" },
400*b636d99dSDavid van Moolenbroek 	{ 10004,	"vote-debug" },
401*b636d99dSDavid van Moolenbroek 	{ 10005,	"vote-sdebug" },
402*b636d99dSDavid van Moolenbroek 	{ 10006,	"vote-xdebug" },
403*b636d99dSDavid van Moolenbroek 	{ 10007,	"vote-xsdebug" },
404*b636d99dSDavid van Moolenbroek 	{ 20000,	"disk-begin" },
405*b636d99dSDavid van Moolenbroek 	{ 20001,	"disk-commit" },
406*b636d99dSDavid van Moolenbroek 	{ 20002,	"disk-lock" },
407*b636d99dSDavid van Moolenbroek 	{ 20003,	"disk-write" },
408*b636d99dSDavid van Moolenbroek 	{ 20004,	"disk-getversion" },
409*b636d99dSDavid van Moolenbroek 	{ 20005,	"disk-getfile" },
410*b636d99dSDavid van Moolenbroek 	{ 20006,	"disk-sendfile" },
411*b636d99dSDavid van Moolenbroek 	{ 20007,	"disk-abort" },
412*b636d99dSDavid van Moolenbroek 	{ 20008,	"disk-releaselocks" },
413*b636d99dSDavid van Moolenbroek 	{ 20009,	"disk-truncate" },
414*b636d99dSDavid van Moolenbroek 	{ 20010,	"disk-probe" },
415*b636d99dSDavid van Moolenbroek 	{ 20011,	"disk-writev" },
416*b636d99dSDavid van Moolenbroek 	{ 20012,	"disk-interfaceaddr" },
417*b636d99dSDavid van Moolenbroek 	{ 20013,	"disk-setversion" },
418*b636d99dSDavid van Moolenbroek 	{ 0,		NULL },
419*b636d99dSDavid van Moolenbroek };
420*b636d99dSDavid van Moolenbroek 
421*b636d99dSDavid van Moolenbroek #define VOTE_LOW	10000
422*b636d99dSDavid van Moolenbroek #define VOTE_HIGH	10007
423*b636d99dSDavid van Moolenbroek #define DISK_LOW	20000
424*b636d99dSDavid van Moolenbroek #define DISK_HIGH	20013
425*b636d99dSDavid van Moolenbroek 
426*b636d99dSDavid van Moolenbroek static const struct tok cb_types[] = {
427*b636d99dSDavid van Moolenbroek 	{ 1,		"exclusive" },
428*b636d99dSDavid van Moolenbroek 	{ 2,		"shared" },
429*b636d99dSDavid van Moolenbroek 	{ 3,		"dropped" },
430*b636d99dSDavid van Moolenbroek 	{ 0,		NULL },
431*b636d99dSDavid van Moolenbroek };
432*b636d99dSDavid van Moolenbroek 
433*b636d99dSDavid van Moolenbroek static const struct tok ubik_lock_types[] = {
434*b636d99dSDavid van Moolenbroek 	{ 1,		"read" },
435*b636d99dSDavid van Moolenbroek 	{ 2,		"write" },
436*b636d99dSDavid van Moolenbroek 	{ 3,		"wait" },
437*b636d99dSDavid van Moolenbroek 	{ 0,		NULL },
438*b636d99dSDavid van Moolenbroek };
439*b636d99dSDavid van Moolenbroek 
440*b636d99dSDavid van Moolenbroek static const char *voltype[] = { "read-write", "read-only", "backup" };
441*b636d99dSDavid van Moolenbroek 
442*b636d99dSDavid van Moolenbroek static const struct tok afs_fs_errors[] = {
443*b636d99dSDavid van Moolenbroek 	{ 101,		"salvage volume" },
444*b636d99dSDavid van Moolenbroek 	{ 102, 		"no such vnode" },
445*b636d99dSDavid van Moolenbroek 	{ 103, 		"no such volume" },
446*b636d99dSDavid van Moolenbroek 	{ 104, 		"volume exist" },
447*b636d99dSDavid van Moolenbroek 	{ 105, 		"no service" },
448*b636d99dSDavid van Moolenbroek 	{ 106, 		"volume offline" },
449*b636d99dSDavid van Moolenbroek 	{ 107, 		"voline online" },
450*b636d99dSDavid van Moolenbroek 	{ 108, 		"diskfull" },
451*b636d99dSDavid van Moolenbroek 	{ 109, 		"diskquota exceeded" },
452*b636d99dSDavid van Moolenbroek 	{ 110, 		"volume busy" },
453*b636d99dSDavid van Moolenbroek 	{ 111, 		"volume moved" },
454*b636d99dSDavid van Moolenbroek 	{ 112, 		"AFS IO error" },
455*b636d99dSDavid van Moolenbroek 	{ 0xffffff9c,	"restarting fileserver" }, /* -100, sic! */
456*b636d99dSDavid van Moolenbroek 	{ 0,		NULL }
457*b636d99dSDavid van Moolenbroek };
458*b636d99dSDavid van Moolenbroek 
459*b636d99dSDavid van Moolenbroek /*
460*b636d99dSDavid van Moolenbroek  * Reasons for acknowledging a packet
461*b636d99dSDavid van Moolenbroek  */
462*b636d99dSDavid van Moolenbroek 
463*b636d99dSDavid van Moolenbroek static const struct tok rx_ack_reasons[] = {
464*b636d99dSDavid van Moolenbroek 	{ 1,		"ack requested" },
465*b636d99dSDavid van Moolenbroek 	{ 2,		"duplicate packet" },
466*b636d99dSDavid van Moolenbroek 	{ 3,		"out of sequence" },
467*b636d99dSDavid van Moolenbroek 	{ 4,		"exceeds window" },
468*b636d99dSDavid van Moolenbroek 	{ 5,		"no buffer space" },
469*b636d99dSDavid van Moolenbroek 	{ 6,		"ping" },
470*b636d99dSDavid van Moolenbroek 	{ 7,		"ping response" },
471*b636d99dSDavid van Moolenbroek 	{ 8,		"delay" },
472*b636d99dSDavid van Moolenbroek 	{ 9,		"idle" },
473*b636d99dSDavid van Moolenbroek 	{ 0,		NULL },
474*b636d99dSDavid van Moolenbroek };
475*b636d99dSDavid van Moolenbroek 
476*b636d99dSDavid van Moolenbroek /*
477*b636d99dSDavid van Moolenbroek  * Cache entries we keep around so we can figure out the RX opcode
478*b636d99dSDavid van Moolenbroek  * numbers for replies.  This allows us to make sense of RX reply packets.
479*b636d99dSDavid van Moolenbroek  */
480*b636d99dSDavid van Moolenbroek 
481*b636d99dSDavid van Moolenbroek struct rx_cache_entry {
482*b636d99dSDavid van Moolenbroek 	uint32_t	callnum;	/* Call number (net order) */
483*b636d99dSDavid van Moolenbroek 	struct in_addr	client;		/* client IP address (net order) */
484*b636d99dSDavid van Moolenbroek 	struct in_addr	server;		/* server IP address (net order) */
485*b636d99dSDavid van Moolenbroek 	int		dport;		/* server port (host order) */
486*b636d99dSDavid van Moolenbroek 	u_short		serviceId;	/* Service identifier (net order) */
487*b636d99dSDavid van Moolenbroek 	uint32_t	opcode;		/* RX opcode (host order) */
488*b636d99dSDavid van Moolenbroek };
489*b636d99dSDavid van Moolenbroek 
490*b636d99dSDavid van Moolenbroek #define RX_CACHE_SIZE	64
491*b636d99dSDavid van Moolenbroek 
492*b636d99dSDavid van Moolenbroek static struct rx_cache_entry	rx_cache[RX_CACHE_SIZE];
493*b636d99dSDavid van Moolenbroek 
494*b636d99dSDavid van Moolenbroek static int	rx_cache_next = 0;
495*b636d99dSDavid van Moolenbroek static int	rx_cache_hint = 0;
496*b636d99dSDavid van Moolenbroek static void	rx_cache_insert(netdissect_options *, const u_char *, const struct ip *, int);
497*b636d99dSDavid van Moolenbroek static int	rx_cache_find(const struct rx_header *, const struct ip *,
498*b636d99dSDavid van Moolenbroek 			      int, int32_t *);
499*b636d99dSDavid van Moolenbroek 
500*b636d99dSDavid van Moolenbroek static void fs_print(netdissect_options *, const u_char *, int);
501*b636d99dSDavid van Moolenbroek static void fs_reply_print(netdissect_options *, const u_char *, int, int32_t);
502*b636d99dSDavid van Moolenbroek static void acl_print(netdissect_options *, u_char *, int, u_char *);
503*b636d99dSDavid van Moolenbroek static void cb_print(netdissect_options *, const u_char *, int);
504*b636d99dSDavid van Moolenbroek static void cb_reply_print(netdissect_options *, const u_char *, int, int32_t);
505*b636d99dSDavid van Moolenbroek static void prot_print(netdissect_options *, const u_char *, int);
506*b636d99dSDavid van Moolenbroek static void prot_reply_print(netdissect_options *, const u_char *, int, int32_t);
507*b636d99dSDavid van Moolenbroek static void vldb_print(netdissect_options *, const u_char *, int);
508*b636d99dSDavid van Moolenbroek static void vldb_reply_print(netdissect_options *, const u_char *, int, int32_t);
509*b636d99dSDavid van Moolenbroek static void kauth_print(netdissect_options *, const u_char *, int);
510*b636d99dSDavid van Moolenbroek static void kauth_reply_print(netdissect_options *, const u_char *, int, int32_t);
511*b636d99dSDavid van Moolenbroek static void vol_print(netdissect_options *, const u_char *, int);
512*b636d99dSDavid van Moolenbroek static void vol_reply_print(netdissect_options *, const u_char *, int, int32_t);
513*b636d99dSDavid van Moolenbroek static void bos_print(netdissect_options *, const u_char *, int);
514*b636d99dSDavid van Moolenbroek static void bos_reply_print(netdissect_options *, const u_char *, int, int32_t);
515*b636d99dSDavid van Moolenbroek static void ubik_print(netdissect_options *, const u_char *);
516*b636d99dSDavid van Moolenbroek static void ubik_reply_print(netdissect_options *, const u_char *, int, int32_t);
517*b636d99dSDavid van Moolenbroek 
518*b636d99dSDavid van Moolenbroek static void rx_ack_print(netdissect_options *, const u_char *, int);
519*b636d99dSDavid van Moolenbroek 
520*b636d99dSDavid van Moolenbroek static int is_ubik(uint32_t);
521*b636d99dSDavid van Moolenbroek 
522*b636d99dSDavid van Moolenbroek /*
523*b636d99dSDavid van Moolenbroek  * Handle the rx-level packet.  See if we know what port it's going to so
524*b636d99dSDavid van Moolenbroek  * we can peek at the afs call inside
525*b636d99dSDavid van Moolenbroek  */
526*b636d99dSDavid van Moolenbroek 
527*b636d99dSDavid van Moolenbroek void
rx_print(netdissect_options * ndo,register const u_char * bp,int length,int sport,int dport,u_char * bp2)528*b636d99dSDavid van Moolenbroek rx_print(netdissect_options *ndo,
529*b636d99dSDavid van Moolenbroek          register const u_char *bp, int length, int sport, int dport,
530*b636d99dSDavid van Moolenbroek          u_char *bp2)
531*b636d99dSDavid van Moolenbroek {
532*b636d99dSDavid van Moolenbroek 	register struct rx_header *rxh;
533*b636d99dSDavid van Moolenbroek 	int i;
534*b636d99dSDavid van Moolenbroek 	int32_t opcode;
535*b636d99dSDavid van Moolenbroek 
536*b636d99dSDavid van Moolenbroek 	if (ndo->ndo_snapend - bp < (int)sizeof (struct rx_header)) {
537*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, " [|rx] (%d)", length));
538*b636d99dSDavid van Moolenbroek 		return;
539*b636d99dSDavid van Moolenbroek 	}
540*b636d99dSDavid van Moolenbroek 
541*b636d99dSDavid van Moolenbroek 	rxh = (struct rx_header *) bp;
542*b636d99dSDavid van Moolenbroek 
543*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, " rx %s", tok2str(rx_types, "type %d", rxh->type)));
544*b636d99dSDavid van Moolenbroek 
545*b636d99dSDavid van Moolenbroek 	if (ndo->ndo_vflag) {
546*b636d99dSDavid van Moolenbroek 		int firstflag = 0;
547*b636d99dSDavid van Moolenbroek 
548*b636d99dSDavid van Moolenbroek 		if (ndo->ndo_vflag > 1)
549*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " cid %08x call# %d",
550*b636d99dSDavid van Moolenbroek 			       (int) EXTRACT_32BITS(&rxh->cid),
551*b636d99dSDavid van Moolenbroek 			       (int) EXTRACT_32BITS(&rxh->callNumber)));
552*b636d99dSDavid van Moolenbroek 
553*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, " seq %d ser %d",
554*b636d99dSDavid van Moolenbroek 		       (int) EXTRACT_32BITS(&rxh->seq),
555*b636d99dSDavid van Moolenbroek 		       (int) EXTRACT_32BITS(&rxh->serial)));
556*b636d99dSDavid van Moolenbroek 
557*b636d99dSDavid van Moolenbroek 		if (ndo->ndo_vflag > 2)
558*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " secindex %d serviceid %hu",
559*b636d99dSDavid van Moolenbroek 				(int) rxh->securityIndex,
560*b636d99dSDavid van Moolenbroek 				EXTRACT_16BITS(&rxh->serviceId)));
561*b636d99dSDavid van Moolenbroek 
562*b636d99dSDavid van Moolenbroek 		if (ndo->ndo_vflag > 1)
563*b636d99dSDavid van Moolenbroek 			for (i = 0; i < NUM_RX_FLAGS; i++) {
564*b636d99dSDavid van Moolenbroek 				if (rxh->flags & rx_flags[i].flag &&
565*b636d99dSDavid van Moolenbroek 				    (!rx_flags[i].packetType ||
566*b636d99dSDavid van Moolenbroek 				     rxh->type == rx_flags[i].packetType)) {
567*b636d99dSDavid van Moolenbroek 					if (!firstflag) {
568*b636d99dSDavid van Moolenbroek 						firstflag = 1;
569*b636d99dSDavid van Moolenbroek 						ND_PRINT((ndo, " "));
570*b636d99dSDavid van Moolenbroek 					} else {
571*b636d99dSDavid van Moolenbroek 						ND_PRINT((ndo, ","));
572*b636d99dSDavid van Moolenbroek 					}
573*b636d99dSDavid van Moolenbroek 					ND_PRINT((ndo, "<%s>", rx_flags[i].s));
574*b636d99dSDavid van Moolenbroek 				}
575*b636d99dSDavid van Moolenbroek 			}
576*b636d99dSDavid van Moolenbroek 	}
577*b636d99dSDavid van Moolenbroek 
578*b636d99dSDavid van Moolenbroek 	/*
579*b636d99dSDavid van Moolenbroek 	 * Try to handle AFS calls that we know about.  Check the destination
580*b636d99dSDavid van Moolenbroek 	 * port and make sure it's a data packet.  Also, make sure the
581*b636d99dSDavid van Moolenbroek 	 * seq number is 1 (because otherwise it's a continuation packet,
582*b636d99dSDavid van Moolenbroek 	 * and we can't interpret that).  Also, seems that reply packets
583*b636d99dSDavid van Moolenbroek 	 * do not have the client-init flag set, so we check for that
584*b636d99dSDavid van Moolenbroek 	 * as well.
585*b636d99dSDavid van Moolenbroek 	 */
586*b636d99dSDavid van Moolenbroek 
587*b636d99dSDavid van Moolenbroek 	if (rxh->type == RX_PACKET_TYPE_DATA &&
588*b636d99dSDavid van Moolenbroek 	    EXTRACT_32BITS(&rxh->seq) == 1 &&
589*b636d99dSDavid van Moolenbroek 	    rxh->flags & RX_CLIENT_INITIATED) {
590*b636d99dSDavid van Moolenbroek 
591*b636d99dSDavid van Moolenbroek 		/*
592*b636d99dSDavid van Moolenbroek 		 * Insert this call into the call cache table, so we
593*b636d99dSDavid van Moolenbroek 		 * have a chance to print out replies
594*b636d99dSDavid van Moolenbroek 		 */
595*b636d99dSDavid van Moolenbroek 
596*b636d99dSDavid van Moolenbroek 		rx_cache_insert(ndo, bp, (const struct ip *) bp2, dport);
597*b636d99dSDavid van Moolenbroek 
598*b636d99dSDavid van Moolenbroek 		switch (dport) {
599*b636d99dSDavid van Moolenbroek 			case FS_RX_PORT:	/* AFS file service */
600*b636d99dSDavid van Moolenbroek 				fs_print(ndo, bp, length);
601*b636d99dSDavid van Moolenbroek 				break;
602*b636d99dSDavid van Moolenbroek 			case CB_RX_PORT:	/* AFS callback service */
603*b636d99dSDavid van Moolenbroek 				cb_print(ndo, bp, length);
604*b636d99dSDavid van Moolenbroek 				break;
605*b636d99dSDavid van Moolenbroek 			case PROT_RX_PORT:	/* AFS protection service */
606*b636d99dSDavid van Moolenbroek 				prot_print(ndo, bp, length);
607*b636d99dSDavid van Moolenbroek 				break;
608*b636d99dSDavid van Moolenbroek 			case VLDB_RX_PORT:	/* AFS VLDB service */
609*b636d99dSDavid van Moolenbroek 				vldb_print(ndo, bp, length);
610*b636d99dSDavid van Moolenbroek 				break;
611*b636d99dSDavid van Moolenbroek 			case KAUTH_RX_PORT:	/* AFS Kerberos auth service */
612*b636d99dSDavid van Moolenbroek 				kauth_print(ndo, bp, length);
613*b636d99dSDavid van Moolenbroek 				break;
614*b636d99dSDavid van Moolenbroek 			case VOL_RX_PORT:	/* AFS Volume service */
615*b636d99dSDavid van Moolenbroek 				vol_print(ndo, bp, length);
616*b636d99dSDavid van Moolenbroek 				break;
617*b636d99dSDavid van Moolenbroek 			case BOS_RX_PORT:	/* AFS BOS service */
618*b636d99dSDavid van Moolenbroek 				bos_print(ndo, bp, length);
619*b636d99dSDavid van Moolenbroek 				break;
620*b636d99dSDavid van Moolenbroek 			default:
621*b636d99dSDavid van Moolenbroek 				;
622*b636d99dSDavid van Moolenbroek 		}
623*b636d99dSDavid van Moolenbroek 
624*b636d99dSDavid van Moolenbroek 	/*
625*b636d99dSDavid van Moolenbroek 	 * If it's a reply (client-init is _not_ set, but seq is one)
626*b636d99dSDavid van Moolenbroek 	 * then look it up in the cache.  If we find it, call the reply
627*b636d99dSDavid van Moolenbroek 	 * printing functions  Note that we handle abort packets here,
628*b636d99dSDavid van Moolenbroek 	 * because printing out the return code can be useful at times.
629*b636d99dSDavid van Moolenbroek 	 */
630*b636d99dSDavid van Moolenbroek 
631*b636d99dSDavid van Moolenbroek 	} else if (((rxh->type == RX_PACKET_TYPE_DATA &&
632*b636d99dSDavid van Moolenbroek 					EXTRACT_32BITS(&rxh->seq) == 1) ||
633*b636d99dSDavid van Moolenbroek 		    rxh->type == RX_PACKET_TYPE_ABORT) &&
634*b636d99dSDavid van Moolenbroek 		   (rxh->flags & RX_CLIENT_INITIATED) == 0 &&
635*b636d99dSDavid van Moolenbroek 		   rx_cache_find(rxh, (const struct ip *) bp2,
636*b636d99dSDavid van Moolenbroek 				 sport, &opcode)) {
637*b636d99dSDavid van Moolenbroek 
638*b636d99dSDavid van Moolenbroek 		switch (sport) {
639*b636d99dSDavid van Moolenbroek 			case FS_RX_PORT:	/* AFS file service */
640*b636d99dSDavid van Moolenbroek 				fs_reply_print(ndo, bp, length, opcode);
641*b636d99dSDavid van Moolenbroek 				break;
642*b636d99dSDavid van Moolenbroek 			case CB_RX_PORT:	/* AFS callback service */
643*b636d99dSDavid van Moolenbroek 				cb_reply_print(ndo, bp, length, opcode);
644*b636d99dSDavid van Moolenbroek 				break;
645*b636d99dSDavid van Moolenbroek 			case PROT_RX_PORT:	/* AFS PT service */
646*b636d99dSDavid van Moolenbroek 				prot_reply_print(ndo, bp, length, opcode);
647*b636d99dSDavid van Moolenbroek 				break;
648*b636d99dSDavid van Moolenbroek 			case VLDB_RX_PORT:	/* AFS VLDB service */
649*b636d99dSDavid van Moolenbroek 				vldb_reply_print(ndo, bp, length, opcode);
650*b636d99dSDavid van Moolenbroek 				break;
651*b636d99dSDavid van Moolenbroek 			case KAUTH_RX_PORT:	/* AFS Kerberos auth service */
652*b636d99dSDavid van Moolenbroek 				kauth_reply_print(ndo, bp, length, opcode);
653*b636d99dSDavid van Moolenbroek 				break;
654*b636d99dSDavid van Moolenbroek 			case VOL_RX_PORT:	/* AFS Volume service */
655*b636d99dSDavid van Moolenbroek 				vol_reply_print(ndo, bp, length, opcode);
656*b636d99dSDavid van Moolenbroek 				break;
657*b636d99dSDavid van Moolenbroek 			case BOS_RX_PORT:	/* AFS BOS service */
658*b636d99dSDavid van Moolenbroek 				bos_reply_print(ndo, bp, length, opcode);
659*b636d99dSDavid van Moolenbroek 				break;
660*b636d99dSDavid van Moolenbroek 			default:
661*b636d99dSDavid van Moolenbroek 				;
662*b636d99dSDavid van Moolenbroek 		}
663*b636d99dSDavid van Moolenbroek 
664*b636d99dSDavid van Moolenbroek 	/*
665*b636d99dSDavid van Moolenbroek 	 * If it's an RX ack packet, then use the appropriate ack decoding
666*b636d99dSDavid van Moolenbroek 	 * function (there isn't any service-specific information in the
667*b636d99dSDavid van Moolenbroek 	 * ack packet, so we can use one for all AFS services)
668*b636d99dSDavid van Moolenbroek 	 */
669*b636d99dSDavid van Moolenbroek 
670*b636d99dSDavid van Moolenbroek 	} else if (rxh->type == RX_PACKET_TYPE_ACK)
671*b636d99dSDavid van Moolenbroek 		rx_ack_print(ndo, bp, length);
672*b636d99dSDavid van Moolenbroek 
673*b636d99dSDavid van Moolenbroek 
674*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, " (%d)", length));
675*b636d99dSDavid van Moolenbroek }
676*b636d99dSDavid van Moolenbroek 
677*b636d99dSDavid van Moolenbroek /*
678*b636d99dSDavid van Moolenbroek  * Insert an entry into the cache.  Taken from print-nfs.c
679*b636d99dSDavid van Moolenbroek  */
680*b636d99dSDavid van Moolenbroek 
681*b636d99dSDavid van Moolenbroek static void
rx_cache_insert(netdissect_options * ndo,const u_char * bp,const struct ip * ip,int dport)682*b636d99dSDavid van Moolenbroek rx_cache_insert(netdissect_options *ndo,
683*b636d99dSDavid van Moolenbroek                 const u_char *bp, const struct ip *ip, int dport)
684*b636d99dSDavid van Moolenbroek {
685*b636d99dSDavid van Moolenbroek 	struct rx_cache_entry *rxent;
686*b636d99dSDavid van Moolenbroek 	const struct rx_header *rxh = (const struct rx_header *) bp;
687*b636d99dSDavid van Moolenbroek 
688*b636d99dSDavid van Moolenbroek 	if (ndo->ndo_snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t)))
689*b636d99dSDavid van Moolenbroek 		return;
690*b636d99dSDavid van Moolenbroek 
691*b636d99dSDavid van Moolenbroek 	rxent = &rx_cache[rx_cache_next];
692*b636d99dSDavid van Moolenbroek 
693*b636d99dSDavid van Moolenbroek 	if (++rx_cache_next >= RX_CACHE_SIZE)
694*b636d99dSDavid van Moolenbroek 		rx_cache_next = 0;
695*b636d99dSDavid van Moolenbroek 
696*b636d99dSDavid van Moolenbroek 	rxent->callnum = rxh->callNumber;
697*b636d99dSDavid van Moolenbroek 	rxent->client = ip->ip_src;
698*b636d99dSDavid van Moolenbroek 	rxent->server = ip->ip_dst;
699*b636d99dSDavid van Moolenbroek 	rxent->dport = dport;
700*b636d99dSDavid van Moolenbroek 	rxent->serviceId = rxh->serviceId;
701*b636d99dSDavid van Moolenbroek 	rxent->opcode = EXTRACT_32BITS(bp + sizeof(struct rx_header));
702*b636d99dSDavid van Moolenbroek }
703*b636d99dSDavid van Moolenbroek 
704*b636d99dSDavid van Moolenbroek /*
705*b636d99dSDavid van Moolenbroek  * Lookup an entry in the cache.  Also taken from print-nfs.c
706*b636d99dSDavid van Moolenbroek  *
707*b636d99dSDavid van Moolenbroek  * Note that because this is a reply, we're looking at the _source_
708*b636d99dSDavid van Moolenbroek  * port.
709*b636d99dSDavid van Moolenbroek  */
710*b636d99dSDavid van Moolenbroek 
711*b636d99dSDavid van Moolenbroek static int
rx_cache_find(const struct rx_header * rxh,const struct ip * ip,int sport,int32_t * opcode)712*b636d99dSDavid van Moolenbroek rx_cache_find(const struct rx_header *rxh, const struct ip *ip, int sport,
713*b636d99dSDavid van Moolenbroek 	      int32_t *opcode)
714*b636d99dSDavid van Moolenbroek {
715*b636d99dSDavid van Moolenbroek 	int i;
716*b636d99dSDavid van Moolenbroek 	struct rx_cache_entry *rxent;
717*b636d99dSDavid van Moolenbroek 	uint32_t clip = ip->ip_dst.s_addr;
718*b636d99dSDavid van Moolenbroek 	uint32_t sip = ip->ip_src.s_addr;
719*b636d99dSDavid van Moolenbroek 
720*b636d99dSDavid van Moolenbroek 	/* Start the search where we last left off */
721*b636d99dSDavid van Moolenbroek 
722*b636d99dSDavid van Moolenbroek 	i = rx_cache_hint;
723*b636d99dSDavid van Moolenbroek 	do {
724*b636d99dSDavid van Moolenbroek 		rxent = &rx_cache[i];
725*b636d99dSDavid van Moolenbroek 		if (rxent->callnum == rxh->callNumber &&
726*b636d99dSDavid van Moolenbroek 		    rxent->client.s_addr == clip &&
727*b636d99dSDavid van Moolenbroek 		    rxent->server.s_addr == sip &&
728*b636d99dSDavid van Moolenbroek 		    rxent->serviceId == rxh->serviceId &&
729*b636d99dSDavid van Moolenbroek 		    rxent->dport == sport) {
730*b636d99dSDavid van Moolenbroek 
731*b636d99dSDavid van Moolenbroek 			/* We got a match! */
732*b636d99dSDavid van Moolenbroek 
733*b636d99dSDavid van Moolenbroek 			rx_cache_hint = i;
734*b636d99dSDavid van Moolenbroek 			*opcode = rxent->opcode;
735*b636d99dSDavid van Moolenbroek 			return(1);
736*b636d99dSDavid van Moolenbroek 		}
737*b636d99dSDavid van Moolenbroek 		if (++i >= RX_CACHE_SIZE)
738*b636d99dSDavid van Moolenbroek 			i = 0;
739*b636d99dSDavid van Moolenbroek 	} while (i != rx_cache_hint);
740*b636d99dSDavid van Moolenbroek 
741*b636d99dSDavid van Moolenbroek 	/* Our search failed */
742*b636d99dSDavid van Moolenbroek 	return(0);
743*b636d99dSDavid van Moolenbroek }
744*b636d99dSDavid van Moolenbroek 
745*b636d99dSDavid van Moolenbroek /*
746*b636d99dSDavid van Moolenbroek  * These extrememly grody macros handle the printing of various AFS stuff.
747*b636d99dSDavid van Moolenbroek  */
748*b636d99dSDavid van Moolenbroek 
749*b636d99dSDavid van Moolenbroek #define FIDOUT() { unsigned long n1, n2, n3; \
750*b636d99dSDavid van Moolenbroek 			ND_TCHECK2(bp[0], sizeof(int32_t) * 3); \
751*b636d99dSDavid van Moolenbroek 			n1 = EXTRACT_32BITS(bp); \
752*b636d99dSDavid van Moolenbroek 			bp += sizeof(int32_t); \
753*b636d99dSDavid van Moolenbroek 			n2 = EXTRACT_32BITS(bp); \
754*b636d99dSDavid van Moolenbroek 			bp += sizeof(int32_t); \
755*b636d99dSDavid van Moolenbroek 			n3 = EXTRACT_32BITS(bp); \
756*b636d99dSDavid van Moolenbroek 			bp += sizeof(int32_t); \
757*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " fid %d/%d/%d", (int) n1, (int) n2, (int) n3)); \
758*b636d99dSDavid van Moolenbroek 		}
759*b636d99dSDavid van Moolenbroek 
760*b636d99dSDavid van Moolenbroek #define STROUT(MAX) { unsigned int i; \
761*b636d99dSDavid van Moolenbroek 			ND_TCHECK2(bp[0], sizeof(int32_t)); \
762*b636d99dSDavid van Moolenbroek 			i = EXTRACT_32BITS(bp); \
763*b636d99dSDavid van Moolenbroek 			if (i > (MAX)) \
764*b636d99dSDavid van Moolenbroek 				goto trunc; \
765*b636d99dSDavid van Moolenbroek 			bp += sizeof(int32_t); \
766*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " \"")); \
767*b636d99dSDavid van Moolenbroek 			if (fn_printn(ndo, bp, i, ndo->ndo_snapend)) \
768*b636d99dSDavid van Moolenbroek 				goto trunc; \
769*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, "\"")); \
770*b636d99dSDavid van Moolenbroek 			bp += ((i + sizeof(int32_t) - 1) / sizeof(int32_t)) * sizeof(int32_t); \
771*b636d99dSDavid van Moolenbroek 		}
772*b636d99dSDavid van Moolenbroek 
773*b636d99dSDavid van Moolenbroek #define INTOUT() { int i; \
774*b636d99dSDavid van Moolenbroek 			ND_TCHECK2(bp[0], sizeof(int32_t)); \
775*b636d99dSDavid van Moolenbroek 			i = (int) EXTRACT_32BITS(bp); \
776*b636d99dSDavid van Moolenbroek 			bp += sizeof(int32_t); \
777*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " %d", i)); \
778*b636d99dSDavid van Moolenbroek 		}
779*b636d99dSDavid van Moolenbroek 
780*b636d99dSDavid van Moolenbroek #define UINTOUT() { unsigned long i; \
781*b636d99dSDavid van Moolenbroek 			ND_TCHECK2(bp[0], sizeof(int32_t)); \
782*b636d99dSDavid van Moolenbroek 			i = EXTRACT_32BITS(bp); \
783*b636d99dSDavid van Moolenbroek 			bp += sizeof(int32_t); \
784*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " %lu", i)); \
785*b636d99dSDavid van Moolenbroek 		}
786*b636d99dSDavid van Moolenbroek 
787*b636d99dSDavid van Moolenbroek #define UINT64OUT() { uint64_t i; \
788*b636d99dSDavid van Moolenbroek 			ND_TCHECK2(bp[0], sizeof(uint64_t)); \
789*b636d99dSDavid van Moolenbroek 			i = EXTRACT_64BITS(bp); \
790*b636d99dSDavid van Moolenbroek 			bp += sizeof(uint64_t); \
791*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " %" PRIu64, i)); \
792*b636d99dSDavid van Moolenbroek 		}
793*b636d99dSDavid van Moolenbroek 
794*b636d99dSDavid van Moolenbroek #define DATEOUT() { time_t t; struct tm *tm; char str[256]; \
795*b636d99dSDavid van Moolenbroek 			ND_TCHECK2(bp[0], sizeof(int32_t)); \
796*b636d99dSDavid van Moolenbroek 			t = (time_t) EXTRACT_32BITS(bp); \
797*b636d99dSDavid van Moolenbroek 			bp += sizeof(int32_t); \
798*b636d99dSDavid van Moolenbroek 			tm = localtime(&t); \
799*b636d99dSDavid van Moolenbroek 			strftime(str, 256, "%Y/%m/%d %T", tm); \
800*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " %s", str)); \
801*b636d99dSDavid van Moolenbroek 		}
802*b636d99dSDavid van Moolenbroek 
803*b636d99dSDavid van Moolenbroek #define STOREATTROUT() { unsigned long mask, i; \
804*b636d99dSDavid van Moolenbroek 			ND_TCHECK2(bp[0], (sizeof(int32_t)*6)); \
805*b636d99dSDavid van Moolenbroek 			mask = EXTRACT_32BITS(bp); bp += sizeof(int32_t); \
806*b636d99dSDavid van Moolenbroek 			if (mask) ND_PRINT((ndo, " StoreStatus")); \
807*b636d99dSDavid van Moolenbroek 		        if (mask & 1) { ND_PRINT((ndo, " date")); DATEOUT(); } \
808*b636d99dSDavid van Moolenbroek 			else bp += sizeof(int32_t); \
809*b636d99dSDavid van Moolenbroek 			i = EXTRACT_32BITS(bp); bp += sizeof(int32_t); \
810*b636d99dSDavid van Moolenbroek 		        if (mask & 2) ND_PRINT((ndo, " owner %lu", i));  \
811*b636d99dSDavid van Moolenbroek 			i = EXTRACT_32BITS(bp); bp += sizeof(int32_t); \
812*b636d99dSDavid van Moolenbroek 		        if (mask & 4) ND_PRINT((ndo, " group %lu", i)); \
813*b636d99dSDavid van Moolenbroek 			i = EXTRACT_32BITS(bp); bp += sizeof(int32_t); \
814*b636d99dSDavid van Moolenbroek 		        if (mask & 8) ND_PRINT((ndo, " mode %lo", i & 07777)); \
815*b636d99dSDavid van Moolenbroek 			i = EXTRACT_32BITS(bp); bp += sizeof(int32_t); \
816*b636d99dSDavid van Moolenbroek 		        if (mask & 16) ND_PRINT((ndo, " segsize %lu", i)); \
817*b636d99dSDavid van Moolenbroek 			/* undocumented in 3.3 docu */ \
818*b636d99dSDavid van Moolenbroek 		        if (mask & 1024) ND_PRINT((ndo, " fsync"));  \
819*b636d99dSDavid van Moolenbroek 		}
820*b636d99dSDavid van Moolenbroek 
821*b636d99dSDavid van Moolenbroek #define UBIK_VERSIONOUT() {int32_t epoch; int32_t counter; \
822*b636d99dSDavid van Moolenbroek 			ND_TCHECK2(bp[0], sizeof(int32_t) * 2); \
823*b636d99dSDavid van Moolenbroek 			epoch = EXTRACT_32BITS(bp); \
824*b636d99dSDavid van Moolenbroek 			bp += sizeof(int32_t); \
825*b636d99dSDavid van Moolenbroek 			counter = EXTRACT_32BITS(bp); \
826*b636d99dSDavid van Moolenbroek 			bp += sizeof(int32_t); \
827*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " %d.%d", epoch, counter)); \
828*b636d99dSDavid van Moolenbroek 		}
829*b636d99dSDavid van Moolenbroek 
830*b636d99dSDavid van Moolenbroek #define AFSUUIDOUT() {uint32_t temp; int i; \
831*b636d99dSDavid van Moolenbroek 			ND_TCHECK2(bp[0], 11*sizeof(uint32_t)); \
832*b636d99dSDavid van Moolenbroek 			temp = EXTRACT_32BITS(bp); \
833*b636d99dSDavid van Moolenbroek 			bp += sizeof(uint32_t); \
834*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " %08x", temp)); \
835*b636d99dSDavid van Moolenbroek 			temp = EXTRACT_32BITS(bp); \
836*b636d99dSDavid van Moolenbroek 			bp += sizeof(uint32_t); \
837*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, "%04x", temp)); \
838*b636d99dSDavid van Moolenbroek 			temp = EXTRACT_32BITS(bp); \
839*b636d99dSDavid van Moolenbroek 			bp += sizeof(uint32_t); \
840*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, "%04x", temp)); \
841*b636d99dSDavid van Moolenbroek 			for (i = 0; i < 8; i++) { \
842*b636d99dSDavid van Moolenbroek 				temp = EXTRACT_32BITS(bp); \
843*b636d99dSDavid van Moolenbroek 				bp += sizeof(uint32_t); \
844*b636d99dSDavid van Moolenbroek 				ND_PRINT((ndo, "%02x", (unsigned char) temp)); \
845*b636d99dSDavid van Moolenbroek 			} \
846*b636d99dSDavid van Moolenbroek 		}
847*b636d99dSDavid van Moolenbroek 
848*b636d99dSDavid van Moolenbroek /*
849*b636d99dSDavid van Moolenbroek  * This is the sickest one of all
850*b636d99dSDavid van Moolenbroek  */
851*b636d99dSDavid van Moolenbroek 
852*b636d99dSDavid van Moolenbroek #define VECOUT(MAX) { u_char *sp; \
853*b636d99dSDavid van Moolenbroek 			u_char s[AFSNAMEMAX]; \
854*b636d99dSDavid van Moolenbroek 			int k; \
855*b636d99dSDavid van Moolenbroek 			if ((MAX) + 1 > sizeof(s)) \
856*b636d99dSDavid van Moolenbroek 				goto trunc; \
857*b636d99dSDavid van Moolenbroek 			ND_TCHECK2(bp[0], (MAX) * sizeof(int32_t)); \
858*b636d99dSDavid van Moolenbroek 			sp = s; \
859*b636d99dSDavid van Moolenbroek 			for (k = 0; k < (MAX); k++) { \
860*b636d99dSDavid van Moolenbroek 				*sp++ = (u_char) EXTRACT_32BITS(bp); \
861*b636d99dSDavid van Moolenbroek 				bp += sizeof(int32_t); \
862*b636d99dSDavid van Moolenbroek 			} \
863*b636d99dSDavid van Moolenbroek 			s[(MAX)] = '\0'; \
864*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " \"")); \
865*b636d99dSDavid van Moolenbroek 			fn_print(ndo, s, NULL); \
866*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, "\"")); \
867*b636d99dSDavid van Moolenbroek 		}
868*b636d99dSDavid van Moolenbroek 
869*b636d99dSDavid van Moolenbroek #define DESTSERVEROUT() { unsigned long n1, n2, n3; \
870*b636d99dSDavid van Moolenbroek 			ND_TCHECK2(bp[0], sizeof(int32_t) * 3); \
871*b636d99dSDavid van Moolenbroek 			n1 = EXTRACT_32BITS(bp); \
872*b636d99dSDavid van Moolenbroek 			bp += sizeof(int32_t); \
873*b636d99dSDavid van Moolenbroek 			n2 = EXTRACT_32BITS(bp); \
874*b636d99dSDavid van Moolenbroek 			bp += sizeof(int32_t); \
875*b636d99dSDavid van Moolenbroek 			n3 = EXTRACT_32BITS(bp); \
876*b636d99dSDavid van Moolenbroek 			bp += sizeof(int32_t); \
877*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " server %d:%d:%d", (int) n1, (int) n2, (int) n3)); \
878*b636d99dSDavid van Moolenbroek 		}
879*b636d99dSDavid van Moolenbroek 
880*b636d99dSDavid van Moolenbroek /*
881*b636d99dSDavid van Moolenbroek  * Handle calls to the AFS file service (fs)
882*b636d99dSDavid van Moolenbroek  */
883*b636d99dSDavid van Moolenbroek 
884*b636d99dSDavid van Moolenbroek static void
fs_print(netdissect_options * ndo,register const u_char * bp,int length)885*b636d99dSDavid van Moolenbroek fs_print(netdissect_options *ndo,
886*b636d99dSDavid van Moolenbroek          register const u_char *bp, int length)
887*b636d99dSDavid van Moolenbroek {
888*b636d99dSDavid van Moolenbroek 	int fs_op;
889*b636d99dSDavid van Moolenbroek 	unsigned long i;
890*b636d99dSDavid van Moolenbroek 
891*b636d99dSDavid van Moolenbroek 	if (length <= (int)sizeof(struct rx_header))
892*b636d99dSDavid van Moolenbroek 		return;
893*b636d99dSDavid van Moolenbroek 
894*b636d99dSDavid van Moolenbroek 	if (ndo->ndo_snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) {
895*b636d99dSDavid van Moolenbroek 		goto trunc;
896*b636d99dSDavid van Moolenbroek 	}
897*b636d99dSDavid van Moolenbroek 
898*b636d99dSDavid van Moolenbroek 	/*
899*b636d99dSDavid van Moolenbroek 	 * Print out the afs call we're invoking.  The table used here was
900*b636d99dSDavid van Moolenbroek 	 * gleaned from fsint/afsint.xg
901*b636d99dSDavid van Moolenbroek 	 */
902*b636d99dSDavid van Moolenbroek 
903*b636d99dSDavid van Moolenbroek 	fs_op = EXTRACT_32BITS(bp + sizeof(struct rx_header));
904*b636d99dSDavid van Moolenbroek 
905*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, " fs call %s", tok2str(fs_req, "op#%d", fs_op)));
906*b636d99dSDavid van Moolenbroek 
907*b636d99dSDavid van Moolenbroek 	/*
908*b636d99dSDavid van Moolenbroek 	 * Print out arguments to some of the AFS calls.  This stuff is
909*b636d99dSDavid van Moolenbroek 	 * all from afsint.xg
910*b636d99dSDavid van Moolenbroek 	 */
911*b636d99dSDavid van Moolenbroek 
912*b636d99dSDavid van Moolenbroek 	bp += sizeof(struct rx_header) + 4;
913*b636d99dSDavid van Moolenbroek 
914*b636d99dSDavid van Moolenbroek 	/*
915*b636d99dSDavid van Moolenbroek 	 * Sigh.  This is gross.  Ritchie forgive me.
916*b636d99dSDavid van Moolenbroek 	 */
917*b636d99dSDavid van Moolenbroek 
918*b636d99dSDavid van Moolenbroek 	switch (fs_op) {
919*b636d99dSDavid van Moolenbroek 		case 130:	/* Fetch data */
920*b636d99dSDavid van Moolenbroek 			FIDOUT();
921*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " offset"));
922*b636d99dSDavid van Moolenbroek 			UINTOUT();
923*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " length"));
924*b636d99dSDavid van Moolenbroek 			UINTOUT();
925*b636d99dSDavid van Moolenbroek 			break;
926*b636d99dSDavid van Moolenbroek 		case 131:	/* Fetch ACL */
927*b636d99dSDavid van Moolenbroek 		case 132:	/* Fetch Status */
928*b636d99dSDavid van Moolenbroek 		case 143:	/* Old set lock */
929*b636d99dSDavid van Moolenbroek 		case 144:	/* Old extend lock */
930*b636d99dSDavid van Moolenbroek 		case 145:	/* Old release lock */
931*b636d99dSDavid van Moolenbroek 		case 156:	/* Set lock */
932*b636d99dSDavid van Moolenbroek 		case 157:	/* Extend lock */
933*b636d99dSDavid van Moolenbroek 		case 158:	/* Release lock */
934*b636d99dSDavid van Moolenbroek 			FIDOUT();
935*b636d99dSDavid van Moolenbroek 			break;
936*b636d99dSDavid van Moolenbroek 		case 135:	/* Store status */
937*b636d99dSDavid van Moolenbroek 			FIDOUT();
938*b636d99dSDavid van Moolenbroek 			STOREATTROUT();
939*b636d99dSDavid van Moolenbroek 			break;
940*b636d99dSDavid van Moolenbroek 		case 133:	/* Store data */
941*b636d99dSDavid van Moolenbroek 			FIDOUT();
942*b636d99dSDavid van Moolenbroek 			STOREATTROUT();
943*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " offset"));
944*b636d99dSDavid van Moolenbroek 			UINTOUT();
945*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " length"));
946*b636d99dSDavid van Moolenbroek 			UINTOUT();
947*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " flen"));
948*b636d99dSDavid van Moolenbroek 			UINTOUT();
949*b636d99dSDavid van Moolenbroek 			break;
950*b636d99dSDavid van Moolenbroek 		case 134:	/* Store ACL */
951*b636d99dSDavid van Moolenbroek 		{
952*b636d99dSDavid van Moolenbroek 			char a[AFSOPAQUEMAX+1];
953*b636d99dSDavid van Moolenbroek 			FIDOUT();
954*b636d99dSDavid van Moolenbroek 			ND_TCHECK2(bp[0], 4);
955*b636d99dSDavid van Moolenbroek 			i = EXTRACT_32BITS(bp);
956*b636d99dSDavid van Moolenbroek 			bp += sizeof(int32_t);
957*b636d99dSDavid van Moolenbroek 			ND_TCHECK2(bp[0], i);
958*b636d99dSDavid van Moolenbroek 			i = min(AFSOPAQUEMAX, i);
959*b636d99dSDavid van Moolenbroek 			strncpy(a, (char *) bp, i);
960*b636d99dSDavid van Moolenbroek 			a[i] = '\0';
961*b636d99dSDavid van Moolenbroek 			acl_print(ndo, (u_char *) a, sizeof(a), (u_char *) a + i);
962*b636d99dSDavid van Moolenbroek 			break;
963*b636d99dSDavid van Moolenbroek 		}
964*b636d99dSDavid van Moolenbroek 		case 137:	/* Create file */
965*b636d99dSDavid van Moolenbroek 		case 141:	/* MakeDir */
966*b636d99dSDavid van Moolenbroek 			FIDOUT();
967*b636d99dSDavid van Moolenbroek 			STROUT(AFSNAMEMAX);
968*b636d99dSDavid van Moolenbroek 			STOREATTROUT();
969*b636d99dSDavid van Moolenbroek 			break;
970*b636d99dSDavid van Moolenbroek 		case 136:	/* Remove file */
971*b636d99dSDavid van Moolenbroek 		case 142:	/* Remove directory */
972*b636d99dSDavid van Moolenbroek 			FIDOUT();
973*b636d99dSDavid van Moolenbroek 			STROUT(AFSNAMEMAX);
974*b636d99dSDavid van Moolenbroek 			break;
975*b636d99dSDavid van Moolenbroek 		case 138:	/* Rename file */
976*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " old"));
977*b636d99dSDavid van Moolenbroek 			FIDOUT();
978*b636d99dSDavid van Moolenbroek 			STROUT(AFSNAMEMAX);
979*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " new"));
980*b636d99dSDavid van Moolenbroek 			FIDOUT();
981*b636d99dSDavid van Moolenbroek 			STROUT(AFSNAMEMAX);
982*b636d99dSDavid van Moolenbroek 			break;
983*b636d99dSDavid van Moolenbroek 		case 139:	/* Symlink */
984*b636d99dSDavid van Moolenbroek 			FIDOUT();
985*b636d99dSDavid van Moolenbroek 			STROUT(AFSNAMEMAX);
986*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " link to"));
987*b636d99dSDavid van Moolenbroek 			STROUT(AFSNAMEMAX);
988*b636d99dSDavid van Moolenbroek 			break;
989*b636d99dSDavid van Moolenbroek 		case 140:	/* Link */
990*b636d99dSDavid van Moolenbroek 			FIDOUT();
991*b636d99dSDavid van Moolenbroek 			STROUT(AFSNAMEMAX);
992*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " link to"));
993*b636d99dSDavid van Moolenbroek 			FIDOUT();
994*b636d99dSDavid van Moolenbroek 			break;
995*b636d99dSDavid van Moolenbroek 		case 148:	/* Get volume info */
996*b636d99dSDavid van Moolenbroek 			STROUT(AFSNAMEMAX);
997*b636d99dSDavid van Moolenbroek 			break;
998*b636d99dSDavid van Moolenbroek 		case 149:	/* Get volume stats */
999*b636d99dSDavid van Moolenbroek 		case 150:	/* Set volume stats */
1000*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " volid"));
1001*b636d99dSDavid van Moolenbroek 			UINTOUT();
1002*b636d99dSDavid van Moolenbroek 			break;
1003*b636d99dSDavid van Moolenbroek 		case 154:	/* New get volume info */
1004*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " volname"));
1005*b636d99dSDavid van Moolenbroek 			STROUT(AFSNAMEMAX);
1006*b636d99dSDavid van Moolenbroek 			break;
1007*b636d99dSDavid van Moolenbroek 		case 155:	/* Bulk stat */
1008*b636d99dSDavid van Moolenbroek 		case 65536:     /* Inline bulk stat */
1009*b636d99dSDavid van Moolenbroek 		{
1010*b636d99dSDavid van Moolenbroek 			unsigned long j;
1011*b636d99dSDavid van Moolenbroek 			ND_TCHECK2(bp[0], 4);
1012*b636d99dSDavid van Moolenbroek 			j = EXTRACT_32BITS(bp);
1013*b636d99dSDavid van Moolenbroek 			bp += sizeof(int32_t);
1014*b636d99dSDavid van Moolenbroek 
1015*b636d99dSDavid van Moolenbroek 			for (i = 0; i < j; i++) {
1016*b636d99dSDavid van Moolenbroek 				FIDOUT();
1017*b636d99dSDavid van Moolenbroek 				if (i != j - 1)
1018*b636d99dSDavid van Moolenbroek 					ND_PRINT((ndo, ","));
1019*b636d99dSDavid van Moolenbroek 			}
1020*b636d99dSDavid van Moolenbroek 			if (j == 0)
1021*b636d99dSDavid van Moolenbroek 				ND_PRINT((ndo, " <none!>"));
1022*b636d99dSDavid van Moolenbroek 		}
1023*b636d99dSDavid van Moolenbroek 		case 65537:	/* Fetch data 64 */
1024*b636d99dSDavid van Moolenbroek 			FIDOUT();
1025*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " offset"));
1026*b636d99dSDavid van Moolenbroek 			UINT64OUT();
1027*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " length"));
1028*b636d99dSDavid van Moolenbroek 			UINT64OUT();
1029*b636d99dSDavid van Moolenbroek 			break;
1030*b636d99dSDavid van Moolenbroek 		case 65538:	/* Store data 64 */
1031*b636d99dSDavid van Moolenbroek 			FIDOUT();
1032*b636d99dSDavid van Moolenbroek 			STOREATTROUT();
1033*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " offset"));
1034*b636d99dSDavid van Moolenbroek 			UINT64OUT();
1035*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " length"));
1036*b636d99dSDavid van Moolenbroek 			UINT64OUT();
1037*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " flen"));
1038*b636d99dSDavid van Moolenbroek 			UINT64OUT();
1039*b636d99dSDavid van Moolenbroek 			break;
1040*b636d99dSDavid van Moolenbroek 		case 65541:    /* CallBack rx conn address */
1041*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " addr"));
1042*b636d99dSDavid van Moolenbroek 			UINTOUT();
1043*b636d99dSDavid van Moolenbroek 		default:
1044*b636d99dSDavid van Moolenbroek 			;
1045*b636d99dSDavid van Moolenbroek 	}
1046*b636d99dSDavid van Moolenbroek 
1047*b636d99dSDavid van Moolenbroek 	return;
1048*b636d99dSDavid van Moolenbroek 
1049*b636d99dSDavid van Moolenbroek trunc:
1050*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, " [|fs]"));
1051*b636d99dSDavid van Moolenbroek }
1052*b636d99dSDavid van Moolenbroek 
1053*b636d99dSDavid van Moolenbroek /*
1054*b636d99dSDavid van Moolenbroek  * Handle replies to the AFS file service
1055*b636d99dSDavid van Moolenbroek  */
1056*b636d99dSDavid van Moolenbroek 
1057*b636d99dSDavid van Moolenbroek static void
fs_reply_print(netdissect_options * ndo,register const u_char * bp,int length,int32_t opcode)1058*b636d99dSDavid van Moolenbroek fs_reply_print(netdissect_options *ndo,
1059*b636d99dSDavid van Moolenbroek                register const u_char *bp, int length, int32_t opcode)
1060*b636d99dSDavid van Moolenbroek {
1061*b636d99dSDavid van Moolenbroek 	unsigned long i;
1062*b636d99dSDavid van Moolenbroek 	struct rx_header *rxh;
1063*b636d99dSDavid van Moolenbroek 
1064*b636d99dSDavid van Moolenbroek 	if (length <= (int)sizeof(struct rx_header))
1065*b636d99dSDavid van Moolenbroek 		return;
1066*b636d99dSDavid van Moolenbroek 
1067*b636d99dSDavid van Moolenbroek 	rxh = (struct rx_header *) bp;
1068*b636d99dSDavid van Moolenbroek 
1069*b636d99dSDavid van Moolenbroek 	/*
1070*b636d99dSDavid van Moolenbroek 	 * Print out the afs call we're invoking.  The table used here was
1071*b636d99dSDavid van Moolenbroek 	 * gleaned from fsint/afsint.xg
1072*b636d99dSDavid van Moolenbroek 	 */
1073*b636d99dSDavid van Moolenbroek 
1074*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, " fs reply %s", tok2str(fs_req, "op#%d", opcode)));
1075*b636d99dSDavid van Moolenbroek 
1076*b636d99dSDavid van Moolenbroek 	bp += sizeof(struct rx_header);
1077*b636d99dSDavid van Moolenbroek 
1078*b636d99dSDavid van Moolenbroek 	/*
1079*b636d99dSDavid van Moolenbroek 	 * If it was a data packet, interpret the response
1080*b636d99dSDavid van Moolenbroek 	 */
1081*b636d99dSDavid van Moolenbroek 
1082*b636d99dSDavid van Moolenbroek 	if (rxh->type == RX_PACKET_TYPE_DATA) {
1083*b636d99dSDavid van Moolenbroek 		switch (opcode) {
1084*b636d99dSDavid van Moolenbroek 		case 131:	/* Fetch ACL */
1085*b636d99dSDavid van Moolenbroek 		{
1086*b636d99dSDavid van Moolenbroek 			char a[AFSOPAQUEMAX+1];
1087*b636d99dSDavid van Moolenbroek 			ND_TCHECK2(bp[0], 4);
1088*b636d99dSDavid van Moolenbroek 			i = EXTRACT_32BITS(bp);
1089*b636d99dSDavid van Moolenbroek 			bp += sizeof(int32_t);
1090*b636d99dSDavid van Moolenbroek 			ND_TCHECK2(bp[0], i);
1091*b636d99dSDavid van Moolenbroek 			i = min(AFSOPAQUEMAX, i);
1092*b636d99dSDavid van Moolenbroek 			strncpy(a, (char *) bp, i);
1093*b636d99dSDavid van Moolenbroek 			a[i] = '\0';
1094*b636d99dSDavid van Moolenbroek 			acl_print(ndo, (u_char *) a, sizeof(a), (u_char *) a + i);
1095*b636d99dSDavid van Moolenbroek 			break;
1096*b636d99dSDavid van Moolenbroek 		}
1097*b636d99dSDavid van Moolenbroek 		case 137:	/* Create file */
1098*b636d99dSDavid van Moolenbroek 		case 141:	/* MakeDir */
1099*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " new"));
1100*b636d99dSDavid van Moolenbroek 			FIDOUT();
1101*b636d99dSDavid van Moolenbroek 			break;
1102*b636d99dSDavid van Moolenbroek 		case 151:	/* Get root volume */
1103*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " root volume"));
1104*b636d99dSDavid van Moolenbroek 			STROUT(AFSNAMEMAX);
1105*b636d99dSDavid van Moolenbroek 			break;
1106*b636d99dSDavid van Moolenbroek 		case 153:	/* Get time */
1107*b636d99dSDavid van Moolenbroek 			DATEOUT();
1108*b636d99dSDavid van Moolenbroek 			break;
1109*b636d99dSDavid van Moolenbroek 		default:
1110*b636d99dSDavid van Moolenbroek 			;
1111*b636d99dSDavid van Moolenbroek 		}
1112*b636d99dSDavid van Moolenbroek 	} else if (rxh->type == RX_PACKET_TYPE_ABORT) {
1113*b636d99dSDavid van Moolenbroek 		int i;
1114*b636d99dSDavid van Moolenbroek 
1115*b636d99dSDavid van Moolenbroek 		/*
1116*b636d99dSDavid van Moolenbroek 		 * Otherwise, just print out the return code
1117*b636d99dSDavid van Moolenbroek 		 */
1118*b636d99dSDavid van Moolenbroek 		ND_TCHECK2(bp[0], sizeof(int32_t));
1119*b636d99dSDavid van Moolenbroek 		i = (int) EXTRACT_32BITS(bp);
1120*b636d99dSDavid van Moolenbroek 		bp += sizeof(int32_t);
1121*b636d99dSDavid van Moolenbroek 
1122*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, " error %s", tok2str(afs_fs_errors, "#%d", i)));
1123*b636d99dSDavid van Moolenbroek 	} else {
1124*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, " strange fs reply of type %d", rxh->type));
1125*b636d99dSDavid van Moolenbroek 	}
1126*b636d99dSDavid van Moolenbroek 
1127*b636d99dSDavid van Moolenbroek 	return;
1128*b636d99dSDavid van Moolenbroek 
1129*b636d99dSDavid van Moolenbroek trunc:
1130*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, " [|fs]"));
1131*b636d99dSDavid van Moolenbroek }
1132*b636d99dSDavid van Moolenbroek 
1133*b636d99dSDavid van Moolenbroek /*
1134*b636d99dSDavid van Moolenbroek  * Print out an AFS ACL string.  An AFS ACL is a string that has the
1135*b636d99dSDavid van Moolenbroek  * following format:
1136*b636d99dSDavid van Moolenbroek  *
1137*b636d99dSDavid van Moolenbroek  * <positive> <negative>
1138*b636d99dSDavid van Moolenbroek  * <uid1> <aclbits1>
1139*b636d99dSDavid van Moolenbroek  * ....
1140*b636d99dSDavid van Moolenbroek  *
1141*b636d99dSDavid van Moolenbroek  * "positive" and "negative" are integers which contain the number of
1142*b636d99dSDavid van Moolenbroek  * positive and negative ACL's in the string.  The uid/aclbits pair are
1143*b636d99dSDavid van Moolenbroek  * ASCII strings containing the UID/PTS record and and a ascii number
1144*b636d99dSDavid van Moolenbroek  * representing a logical OR of all the ACL permission bits
1145*b636d99dSDavid van Moolenbroek  */
1146*b636d99dSDavid van Moolenbroek 
1147*b636d99dSDavid van Moolenbroek static void
acl_print(netdissect_options * ndo,u_char * s,int maxsize,u_char * end)1148*b636d99dSDavid van Moolenbroek acl_print(netdissect_options *ndo,
1149*b636d99dSDavid van Moolenbroek           u_char *s, int maxsize, u_char *end)
1150*b636d99dSDavid van Moolenbroek {
1151*b636d99dSDavid van Moolenbroek 	int pos, neg, acl;
1152*b636d99dSDavid van Moolenbroek 	int n, i;
1153*b636d99dSDavid van Moolenbroek 	char *user;
1154*b636d99dSDavid van Moolenbroek 	char fmt[1024];
1155*b636d99dSDavid van Moolenbroek 
1156*b636d99dSDavid van Moolenbroek 	if ((user = (char *)malloc(maxsize)) == NULL)
1157*b636d99dSDavid van Moolenbroek 		return;
1158*b636d99dSDavid van Moolenbroek 
1159*b636d99dSDavid van Moolenbroek 	if (sscanf((char *) s, "%d %d\n%n", &pos, &neg, &n) != 2)
1160*b636d99dSDavid van Moolenbroek 		goto finish;
1161*b636d99dSDavid van Moolenbroek 
1162*b636d99dSDavid van Moolenbroek 	s += n;
1163*b636d99dSDavid van Moolenbroek 
1164*b636d99dSDavid van Moolenbroek 	if (s > end)
1165*b636d99dSDavid van Moolenbroek 		goto finish;
1166*b636d99dSDavid van Moolenbroek 
1167*b636d99dSDavid van Moolenbroek 	/*
1168*b636d99dSDavid van Moolenbroek 	 * This wacky order preserves the order used by the "fs" command
1169*b636d99dSDavid van Moolenbroek 	 */
1170*b636d99dSDavid van Moolenbroek 
1171*b636d99dSDavid van Moolenbroek #define ACLOUT(acl) \
1172*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, "%s%s%s%s%s%s%s", \
1173*b636d99dSDavid van Moolenbroek 	          acl & PRSFS_READ       ? "r" : "", \
1174*b636d99dSDavid van Moolenbroek 	          acl & PRSFS_LOOKUP     ? "l" : "", \
1175*b636d99dSDavid van Moolenbroek 	          acl & PRSFS_INSERT     ? "i" : "", \
1176*b636d99dSDavid van Moolenbroek 	          acl & PRSFS_DELETE     ? "d" : "", \
1177*b636d99dSDavid van Moolenbroek 	          acl & PRSFS_WRITE      ? "w" : "", \
1178*b636d99dSDavid van Moolenbroek 	          acl & PRSFS_LOCK       ? "k" : "", \
1179*b636d99dSDavid van Moolenbroek 	          acl & PRSFS_ADMINISTER ? "a" : ""));
1180*b636d99dSDavid van Moolenbroek 
1181*b636d99dSDavid van Moolenbroek 	for (i = 0; i < pos; i++) {
1182*b636d99dSDavid van Moolenbroek 		snprintf(fmt, sizeof(fmt), "%%%ds %%d\n%%n", maxsize - 1);
1183*b636d99dSDavid van Moolenbroek 		if (sscanf((char *) s, fmt, user, &acl, &n) != 2)
1184*b636d99dSDavid van Moolenbroek 			goto finish;
1185*b636d99dSDavid van Moolenbroek 		s += n;
1186*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, " +{"));
1187*b636d99dSDavid van Moolenbroek 		fn_print(ndo, (u_char *)user, NULL);
1188*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, " "));
1189*b636d99dSDavid van Moolenbroek 		ACLOUT(acl);
1190*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "}"));
1191*b636d99dSDavid van Moolenbroek 		if (s > end)
1192*b636d99dSDavid van Moolenbroek 			goto finish;
1193*b636d99dSDavid van Moolenbroek 	}
1194*b636d99dSDavid van Moolenbroek 
1195*b636d99dSDavid van Moolenbroek 	for (i = 0; i < neg; i++) {
1196*b636d99dSDavid van Moolenbroek 		snprintf(fmt, sizeof(fmt), "%%%ds %%d\n%%n", maxsize - 1);
1197*b636d99dSDavid van Moolenbroek 		if (sscanf((char *) s, fmt, user, &acl, &n) != 2)
1198*b636d99dSDavid van Moolenbroek 			goto finish;
1199*b636d99dSDavid van Moolenbroek 		s += n;
1200*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, " -{"));
1201*b636d99dSDavid van Moolenbroek 		fn_print(ndo, (u_char *)user, NULL);
1202*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, " "));
1203*b636d99dSDavid van Moolenbroek 		ACLOUT(acl);
1204*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "}"));
1205*b636d99dSDavid van Moolenbroek 		if (s > end)
1206*b636d99dSDavid van Moolenbroek 			goto finish;
1207*b636d99dSDavid van Moolenbroek 	}
1208*b636d99dSDavid van Moolenbroek 
1209*b636d99dSDavid van Moolenbroek finish:
1210*b636d99dSDavid van Moolenbroek 	free(user);
1211*b636d99dSDavid van Moolenbroek 	return;
1212*b636d99dSDavid van Moolenbroek }
1213*b636d99dSDavid van Moolenbroek 
1214*b636d99dSDavid van Moolenbroek #undef ACLOUT
1215*b636d99dSDavid van Moolenbroek 
1216*b636d99dSDavid van Moolenbroek /*
1217*b636d99dSDavid van Moolenbroek  * Handle calls to the AFS callback service
1218*b636d99dSDavid van Moolenbroek  */
1219*b636d99dSDavid van Moolenbroek 
1220*b636d99dSDavid van Moolenbroek static void
cb_print(netdissect_options * ndo,register const u_char * bp,int length)1221*b636d99dSDavid van Moolenbroek cb_print(netdissect_options *ndo,
1222*b636d99dSDavid van Moolenbroek          register const u_char *bp, int length)
1223*b636d99dSDavid van Moolenbroek {
1224*b636d99dSDavid van Moolenbroek 	int cb_op;
1225*b636d99dSDavid van Moolenbroek 	unsigned long i;
1226*b636d99dSDavid van Moolenbroek 
1227*b636d99dSDavid van Moolenbroek 	if (length <= (int)sizeof(struct rx_header))
1228*b636d99dSDavid van Moolenbroek 		return;
1229*b636d99dSDavid van Moolenbroek 
1230*b636d99dSDavid van Moolenbroek 	if (ndo->ndo_snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) {
1231*b636d99dSDavid van Moolenbroek 		goto trunc;
1232*b636d99dSDavid van Moolenbroek 	}
1233*b636d99dSDavid van Moolenbroek 
1234*b636d99dSDavid van Moolenbroek 	/*
1235*b636d99dSDavid van Moolenbroek 	 * Print out the afs call we're invoking.  The table used here was
1236*b636d99dSDavid van Moolenbroek 	 * gleaned from fsint/afscbint.xg
1237*b636d99dSDavid van Moolenbroek 	 */
1238*b636d99dSDavid van Moolenbroek 
1239*b636d99dSDavid van Moolenbroek 	cb_op = EXTRACT_32BITS(bp + sizeof(struct rx_header));
1240*b636d99dSDavid van Moolenbroek 
1241*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, " cb call %s", tok2str(cb_req, "op#%d", cb_op)));
1242*b636d99dSDavid van Moolenbroek 
1243*b636d99dSDavid van Moolenbroek 	bp += sizeof(struct rx_header) + 4;
1244*b636d99dSDavid van Moolenbroek 
1245*b636d99dSDavid van Moolenbroek 	/*
1246*b636d99dSDavid van Moolenbroek 	 * Print out the afs call we're invoking.  The table used here was
1247*b636d99dSDavid van Moolenbroek 	 * gleaned from fsint/afscbint.xg
1248*b636d99dSDavid van Moolenbroek 	 */
1249*b636d99dSDavid van Moolenbroek 
1250*b636d99dSDavid van Moolenbroek 	switch (cb_op) {
1251*b636d99dSDavid van Moolenbroek 		case 204:		/* Callback */
1252*b636d99dSDavid van Moolenbroek 		{
1253*b636d99dSDavid van Moolenbroek 			unsigned long j, t;
1254*b636d99dSDavid van Moolenbroek 			ND_TCHECK2(bp[0], 4);
1255*b636d99dSDavid van Moolenbroek 			j = EXTRACT_32BITS(bp);
1256*b636d99dSDavid van Moolenbroek 			bp += sizeof(int32_t);
1257*b636d99dSDavid van Moolenbroek 
1258*b636d99dSDavid van Moolenbroek 			for (i = 0; i < j; i++) {
1259*b636d99dSDavid van Moolenbroek 				FIDOUT();
1260*b636d99dSDavid van Moolenbroek 				if (i != j - 1)
1261*b636d99dSDavid van Moolenbroek 					ND_PRINT((ndo, ","));
1262*b636d99dSDavid van Moolenbroek 			}
1263*b636d99dSDavid van Moolenbroek 
1264*b636d99dSDavid van Moolenbroek 			if (j == 0)
1265*b636d99dSDavid van Moolenbroek 				ND_PRINT((ndo, " <none!>"));
1266*b636d99dSDavid van Moolenbroek 
1267*b636d99dSDavid van Moolenbroek 			j = EXTRACT_32BITS(bp);
1268*b636d99dSDavid van Moolenbroek 			bp += sizeof(int32_t);
1269*b636d99dSDavid van Moolenbroek 
1270*b636d99dSDavid van Moolenbroek 			if (j != 0)
1271*b636d99dSDavid van Moolenbroek 				ND_PRINT((ndo, ";"));
1272*b636d99dSDavid van Moolenbroek 
1273*b636d99dSDavid van Moolenbroek 			for (i = 0; i < j; i++) {
1274*b636d99dSDavid van Moolenbroek 				ND_PRINT((ndo, " ver"));
1275*b636d99dSDavid van Moolenbroek 				INTOUT();
1276*b636d99dSDavid van Moolenbroek 				ND_PRINT((ndo, " expires"));
1277*b636d99dSDavid van Moolenbroek 				DATEOUT();
1278*b636d99dSDavid van Moolenbroek 				ND_TCHECK2(bp[0], 4);
1279*b636d99dSDavid van Moolenbroek 				t = EXTRACT_32BITS(bp);
1280*b636d99dSDavid van Moolenbroek 				bp += sizeof(int32_t);
1281*b636d99dSDavid van Moolenbroek 				tok2str(cb_types, "type %d", t);
1282*b636d99dSDavid van Moolenbroek 			}
1283*b636d99dSDavid van Moolenbroek 		}
1284*b636d99dSDavid van Moolenbroek 		case 214: {
1285*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " afsuuid"));
1286*b636d99dSDavid van Moolenbroek 			AFSUUIDOUT();
1287*b636d99dSDavid van Moolenbroek 			break;
1288*b636d99dSDavid van Moolenbroek 		}
1289*b636d99dSDavid van Moolenbroek 		default:
1290*b636d99dSDavid van Moolenbroek 			;
1291*b636d99dSDavid van Moolenbroek 	}
1292*b636d99dSDavid van Moolenbroek 
1293*b636d99dSDavid van Moolenbroek 	return;
1294*b636d99dSDavid van Moolenbroek 
1295*b636d99dSDavid van Moolenbroek trunc:
1296*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, " [|cb]"));
1297*b636d99dSDavid van Moolenbroek }
1298*b636d99dSDavid van Moolenbroek 
1299*b636d99dSDavid van Moolenbroek /*
1300*b636d99dSDavid van Moolenbroek  * Handle replies to the AFS Callback Service
1301*b636d99dSDavid van Moolenbroek  */
1302*b636d99dSDavid van Moolenbroek 
1303*b636d99dSDavid van Moolenbroek static void
cb_reply_print(netdissect_options * ndo,register const u_char * bp,int length,int32_t opcode)1304*b636d99dSDavid van Moolenbroek cb_reply_print(netdissect_options *ndo,
1305*b636d99dSDavid van Moolenbroek                register const u_char *bp, int length, int32_t opcode)
1306*b636d99dSDavid van Moolenbroek {
1307*b636d99dSDavid van Moolenbroek 	struct rx_header *rxh;
1308*b636d99dSDavid van Moolenbroek 
1309*b636d99dSDavid van Moolenbroek 	if (length <= (int)sizeof(struct rx_header))
1310*b636d99dSDavid van Moolenbroek 		return;
1311*b636d99dSDavid van Moolenbroek 
1312*b636d99dSDavid van Moolenbroek 	rxh = (struct rx_header *) bp;
1313*b636d99dSDavid van Moolenbroek 
1314*b636d99dSDavid van Moolenbroek 	/*
1315*b636d99dSDavid van Moolenbroek 	 * Print out the afs call we're invoking.  The table used here was
1316*b636d99dSDavid van Moolenbroek 	 * gleaned from fsint/afscbint.xg
1317*b636d99dSDavid van Moolenbroek 	 */
1318*b636d99dSDavid van Moolenbroek 
1319*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, " cb reply %s", tok2str(cb_req, "op#%d", opcode)));
1320*b636d99dSDavid van Moolenbroek 
1321*b636d99dSDavid van Moolenbroek 	bp += sizeof(struct rx_header);
1322*b636d99dSDavid van Moolenbroek 
1323*b636d99dSDavid van Moolenbroek 	/*
1324*b636d99dSDavid van Moolenbroek 	 * If it was a data packet, interpret the response.
1325*b636d99dSDavid van Moolenbroek 	 */
1326*b636d99dSDavid van Moolenbroek 
1327*b636d99dSDavid van Moolenbroek 	if (rxh->type == RX_PACKET_TYPE_DATA)
1328*b636d99dSDavid van Moolenbroek 		switch (opcode) {
1329*b636d99dSDavid van Moolenbroek 		case 213:	/* InitCallBackState3 */
1330*b636d99dSDavid van Moolenbroek 			AFSUUIDOUT();
1331*b636d99dSDavid van Moolenbroek 			break;
1332*b636d99dSDavid van Moolenbroek 		default:
1333*b636d99dSDavid van Moolenbroek 		;
1334*b636d99dSDavid van Moolenbroek 		}
1335*b636d99dSDavid van Moolenbroek 	else {
1336*b636d99dSDavid van Moolenbroek 		/*
1337*b636d99dSDavid van Moolenbroek 		 * Otherwise, just print out the return code
1338*b636d99dSDavid van Moolenbroek 		 */
1339*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, " errcode"));
1340*b636d99dSDavid van Moolenbroek 		INTOUT();
1341*b636d99dSDavid van Moolenbroek 	}
1342*b636d99dSDavid van Moolenbroek 
1343*b636d99dSDavid van Moolenbroek 	return;
1344*b636d99dSDavid van Moolenbroek 
1345*b636d99dSDavid van Moolenbroek trunc:
1346*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, " [|cb]"));
1347*b636d99dSDavid van Moolenbroek }
1348*b636d99dSDavid van Moolenbroek 
1349*b636d99dSDavid van Moolenbroek /*
1350*b636d99dSDavid van Moolenbroek  * Handle calls to the AFS protection database server
1351*b636d99dSDavid van Moolenbroek  */
1352*b636d99dSDavid van Moolenbroek 
1353*b636d99dSDavid van Moolenbroek static void
prot_print(netdissect_options * ndo,register const u_char * bp,int length)1354*b636d99dSDavid van Moolenbroek prot_print(netdissect_options *ndo,
1355*b636d99dSDavid van Moolenbroek            register const u_char *bp, int length)
1356*b636d99dSDavid van Moolenbroek {
1357*b636d99dSDavid van Moolenbroek 	unsigned long i;
1358*b636d99dSDavid van Moolenbroek 	int pt_op;
1359*b636d99dSDavid van Moolenbroek 
1360*b636d99dSDavid van Moolenbroek 	if (length <= (int)sizeof(struct rx_header))
1361*b636d99dSDavid van Moolenbroek 		return;
1362*b636d99dSDavid van Moolenbroek 
1363*b636d99dSDavid van Moolenbroek 	if (ndo->ndo_snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) {
1364*b636d99dSDavid van Moolenbroek 		goto trunc;
1365*b636d99dSDavid van Moolenbroek 	}
1366*b636d99dSDavid van Moolenbroek 
1367*b636d99dSDavid van Moolenbroek 	/*
1368*b636d99dSDavid van Moolenbroek 	 * Print out the afs call we're invoking.  The table used here was
1369*b636d99dSDavid van Moolenbroek 	 * gleaned from ptserver/ptint.xg
1370*b636d99dSDavid van Moolenbroek 	 */
1371*b636d99dSDavid van Moolenbroek 
1372*b636d99dSDavid van Moolenbroek 	pt_op = EXTRACT_32BITS(bp + sizeof(struct rx_header));
1373*b636d99dSDavid van Moolenbroek 
1374*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, " pt"));
1375*b636d99dSDavid van Moolenbroek 
1376*b636d99dSDavid van Moolenbroek 	if (is_ubik(pt_op)) {
1377*b636d99dSDavid van Moolenbroek 		ubik_print(ndo, bp);
1378*b636d99dSDavid van Moolenbroek 		return;
1379*b636d99dSDavid van Moolenbroek 	}
1380*b636d99dSDavid van Moolenbroek 
1381*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, " call %s", tok2str(pt_req, "op#%d", pt_op)));
1382*b636d99dSDavid van Moolenbroek 
1383*b636d99dSDavid van Moolenbroek 	/*
1384*b636d99dSDavid van Moolenbroek 	 * Decode some of the arguments to the PT calls
1385*b636d99dSDavid van Moolenbroek 	 */
1386*b636d99dSDavid van Moolenbroek 
1387*b636d99dSDavid van Moolenbroek 	bp += sizeof(struct rx_header) + 4;
1388*b636d99dSDavid van Moolenbroek 
1389*b636d99dSDavid van Moolenbroek 	switch (pt_op) {
1390*b636d99dSDavid van Moolenbroek 		case 500:	/* I New User */
1391*b636d99dSDavid van Moolenbroek 			STROUT(PRNAMEMAX);
1392*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " id"));
1393*b636d99dSDavid van Moolenbroek 			INTOUT();
1394*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " oldid"));
1395*b636d99dSDavid van Moolenbroek 			INTOUT();
1396*b636d99dSDavid van Moolenbroek 			break;
1397*b636d99dSDavid van Moolenbroek 		case 501:	/* Where is it */
1398*b636d99dSDavid van Moolenbroek 		case 506:	/* Delete */
1399*b636d99dSDavid van Moolenbroek 		case 508:	/* Get CPS */
1400*b636d99dSDavid van Moolenbroek 		case 512:	/* List entry */
1401*b636d99dSDavid van Moolenbroek 		case 514:	/* List elements */
1402*b636d99dSDavid van Moolenbroek 		case 517:	/* List owned */
1403*b636d99dSDavid van Moolenbroek 		case 518:	/* Get CPS2 */
1404*b636d99dSDavid van Moolenbroek 		case 519:	/* Get host CPS */
1405*b636d99dSDavid van Moolenbroek 		case 530:	/* List super groups */
1406*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " id"));
1407*b636d99dSDavid van Moolenbroek 			INTOUT();
1408*b636d99dSDavid van Moolenbroek 			break;
1409*b636d99dSDavid van Moolenbroek 		case 502:	/* Dump entry */
1410*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " pos"));
1411*b636d99dSDavid van Moolenbroek 			INTOUT();
1412*b636d99dSDavid van Moolenbroek 			break;
1413*b636d99dSDavid van Moolenbroek 		case 503:	/* Add to group */
1414*b636d99dSDavid van Moolenbroek 		case 507:	/* Remove from group */
1415*b636d99dSDavid van Moolenbroek 		case 515:	/* Is a member of? */
1416*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " uid"));
1417*b636d99dSDavid van Moolenbroek 			INTOUT();
1418*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " gid"));
1419*b636d99dSDavid van Moolenbroek 			INTOUT();
1420*b636d99dSDavid van Moolenbroek 			break;
1421*b636d99dSDavid van Moolenbroek 		case 504:	/* Name to ID */
1422*b636d99dSDavid van Moolenbroek 		{
1423*b636d99dSDavid van Moolenbroek 			unsigned long j;
1424*b636d99dSDavid van Moolenbroek 			ND_TCHECK2(bp[0], 4);
1425*b636d99dSDavid van Moolenbroek 			j = EXTRACT_32BITS(bp);
1426*b636d99dSDavid van Moolenbroek 			bp += sizeof(int32_t);
1427*b636d99dSDavid van Moolenbroek 
1428*b636d99dSDavid van Moolenbroek 			/*
1429*b636d99dSDavid van Moolenbroek 			 * Who designed this chicken-shit protocol?
1430*b636d99dSDavid van Moolenbroek 			 *
1431*b636d99dSDavid van Moolenbroek 			 * Each character is stored as a 32-bit
1432*b636d99dSDavid van Moolenbroek 			 * integer!
1433*b636d99dSDavid van Moolenbroek 			 */
1434*b636d99dSDavid van Moolenbroek 
1435*b636d99dSDavid van Moolenbroek 			for (i = 0; i < j; i++) {
1436*b636d99dSDavid van Moolenbroek 				VECOUT(PRNAMEMAX);
1437*b636d99dSDavid van Moolenbroek 			}
1438*b636d99dSDavid van Moolenbroek 			if (j == 0)
1439*b636d99dSDavid van Moolenbroek 				ND_PRINT((ndo, " <none!>"));
1440*b636d99dSDavid van Moolenbroek 		}
1441*b636d99dSDavid van Moolenbroek 			break;
1442*b636d99dSDavid van Moolenbroek 		case 505:	/* Id to name */
1443*b636d99dSDavid van Moolenbroek 		{
1444*b636d99dSDavid van Moolenbroek 			unsigned long j;
1445*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " ids:"));
1446*b636d99dSDavid van Moolenbroek 			ND_TCHECK2(bp[0], 4);
1447*b636d99dSDavid van Moolenbroek 			i = EXTRACT_32BITS(bp);
1448*b636d99dSDavid van Moolenbroek 			bp += sizeof(int32_t);
1449*b636d99dSDavid van Moolenbroek 			for (j = 0; j < i; j++)
1450*b636d99dSDavid van Moolenbroek 				INTOUT();
1451*b636d99dSDavid van Moolenbroek 			if (j == 0)
1452*b636d99dSDavid van Moolenbroek 				ND_PRINT((ndo, " <none!>"));
1453*b636d99dSDavid van Moolenbroek 		}
1454*b636d99dSDavid van Moolenbroek 			break;
1455*b636d99dSDavid van Moolenbroek 		case 509:	/* New entry */
1456*b636d99dSDavid van Moolenbroek 			STROUT(PRNAMEMAX);
1457*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " flag"));
1458*b636d99dSDavid van Moolenbroek 			INTOUT();
1459*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " oid"));
1460*b636d99dSDavid van Moolenbroek 			INTOUT();
1461*b636d99dSDavid van Moolenbroek 			break;
1462*b636d99dSDavid van Moolenbroek 		case 511:	/* Set max */
1463*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " id"));
1464*b636d99dSDavid van Moolenbroek 			INTOUT();
1465*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " gflag"));
1466*b636d99dSDavid van Moolenbroek 			INTOUT();
1467*b636d99dSDavid van Moolenbroek 			break;
1468*b636d99dSDavid van Moolenbroek 		case 513:	/* Change entry */
1469*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " id"));
1470*b636d99dSDavid van Moolenbroek 			INTOUT();
1471*b636d99dSDavid van Moolenbroek 			STROUT(PRNAMEMAX);
1472*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " oldid"));
1473*b636d99dSDavid van Moolenbroek 			INTOUT();
1474*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " newid"));
1475*b636d99dSDavid van Moolenbroek 			INTOUT();
1476*b636d99dSDavid van Moolenbroek 			break;
1477*b636d99dSDavid van Moolenbroek 		case 520:	/* Update entry */
1478*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " id"));
1479*b636d99dSDavid van Moolenbroek 			INTOUT();
1480*b636d99dSDavid van Moolenbroek 			STROUT(PRNAMEMAX);
1481*b636d99dSDavid van Moolenbroek 			break;
1482*b636d99dSDavid van Moolenbroek 		default:
1483*b636d99dSDavid van Moolenbroek 			;
1484*b636d99dSDavid van Moolenbroek 	}
1485*b636d99dSDavid van Moolenbroek 
1486*b636d99dSDavid van Moolenbroek 
1487*b636d99dSDavid van Moolenbroek 	return;
1488*b636d99dSDavid van Moolenbroek 
1489*b636d99dSDavid van Moolenbroek trunc:
1490*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, " [|pt]"));
1491*b636d99dSDavid van Moolenbroek }
1492*b636d99dSDavid van Moolenbroek 
1493*b636d99dSDavid van Moolenbroek /*
1494*b636d99dSDavid van Moolenbroek  * Handle replies to the AFS protection service
1495*b636d99dSDavid van Moolenbroek  */
1496*b636d99dSDavid van Moolenbroek 
1497*b636d99dSDavid van Moolenbroek static void
prot_reply_print(netdissect_options * ndo,register const u_char * bp,int length,int32_t opcode)1498*b636d99dSDavid van Moolenbroek prot_reply_print(netdissect_options *ndo,
1499*b636d99dSDavid van Moolenbroek                  register const u_char *bp, int length, int32_t opcode)
1500*b636d99dSDavid van Moolenbroek {
1501*b636d99dSDavid van Moolenbroek 	struct rx_header *rxh;
1502*b636d99dSDavid van Moolenbroek 	unsigned long i;
1503*b636d99dSDavid van Moolenbroek 
1504*b636d99dSDavid van Moolenbroek 	if (length < (int)sizeof(struct rx_header))
1505*b636d99dSDavid van Moolenbroek 		return;
1506*b636d99dSDavid van Moolenbroek 
1507*b636d99dSDavid van Moolenbroek 	rxh = (struct rx_header *) bp;
1508*b636d99dSDavid van Moolenbroek 
1509*b636d99dSDavid van Moolenbroek 	/*
1510*b636d99dSDavid van Moolenbroek 	 * Print out the afs call we're invoking.  The table used here was
1511*b636d99dSDavid van Moolenbroek 	 * gleaned from ptserver/ptint.xg.  Check to see if it's a
1512*b636d99dSDavid van Moolenbroek 	 * Ubik call, however.
1513*b636d99dSDavid van Moolenbroek 	 */
1514*b636d99dSDavid van Moolenbroek 
1515*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, " pt"));
1516*b636d99dSDavid van Moolenbroek 
1517*b636d99dSDavid van Moolenbroek 	if (is_ubik(opcode)) {
1518*b636d99dSDavid van Moolenbroek 		ubik_reply_print(ndo, bp, length, opcode);
1519*b636d99dSDavid van Moolenbroek 		return;
1520*b636d99dSDavid van Moolenbroek 	}
1521*b636d99dSDavid van Moolenbroek 
1522*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, " reply %s", tok2str(pt_req, "op#%d", opcode)));
1523*b636d99dSDavid van Moolenbroek 
1524*b636d99dSDavid van Moolenbroek 	bp += sizeof(struct rx_header);
1525*b636d99dSDavid van Moolenbroek 
1526*b636d99dSDavid van Moolenbroek 	/*
1527*b636d99dSDavid van Moolenbroek 	 * If it was a data packet, interpret the response
1528*b636d99dSDavid van Moolenbroek 	 */
1529*b636d99dSDavid van Moolenbroek 
1530*b636d99dSDavid van Moolenbroek 	if (rxh->type == RX_PACKET_TYPE_DATA)
1531*b636d99dSDavid van Moolenbroek 		switch (opcode) {
1532*b636d99dSDavid van Moolenbroek 		case 504:		/* Name to ID */
1533*b636d99dSDavid van Moolenbroek 		{
1534*b636d99dSDavid van Moolenbroek 			unsigned long j;
1535*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " ids:"));
1536*b636d99dSDavid van Moolenbroek 			ND_TCHECK2(bp[0], 4);
1537*b636d99dSDavid van Moolenbroek 			i = EXTRACT_32BITS(bp);
1538*b636d99dSDavid van Moolenbroek 			bp += sizeof(int32_t);
1539*b636d99dSDavid van Moolenbroek 			for (j = 0; j < i; j++)
1540*b636d99dSDavid van Moolenbroek 				INTOUT();
1541*b636d99dSDavid van Moolenbroek 			if (j == 0)
1542*b636d99dSDavid van Moolenbroek 				ND_PRINT((ndo, " <none!>"));
1543*b636d99dSDavid van Moolenbroek 		}
1544*b636d99dSDavid van Moolenbroek 			break;
1545*b636d99dSDavid van Moolenbroek 		case 505:		/* ID to name */
1546*b636d99dSDavid van Moolenbroek 		{
1547*b636d99dSDavid van Moolenbroek 			unsigned long j;
1548*b636d99dSDavid van Moolenbroek 			ND_TCHECK2(bp[0], 4);
1549*b636d99dSDavid van Moolenbroek 			j = EXTRACT_32BITS(bp);
1550*b636d99dSDavid van Moolenbroek 			bp += sizeof(int32_t);
1551*b636d99dSDavid van Moolenbroek 
1552*b636d99dSDavid van Moolenbroek 			/*
1553*b636d99dSDavid van Moolenbroek 			 * Who designed this chicken-shit protocol?
1554*b636d99dSDavid van Moolenbroek 			 *
1555*b636d99dSDavid van Moolenbroek 			 * Each character is stored as a 32-bit
1556*b636d99dSDavid van Moolenbroek 			 * integer!
1557*b636d99dSDavid van Moolenbroek 			 */
1558*b636d99dSDavid van Moolenbroek 
1559*b636d99dSDavid van Moolenbroek 			for (i = 0; i < j; i++) {
1560*b636d99dSDavid van Moolenbroek 				VECOUT(PRNAMEMAX);
1561*b636d99dSDavid van Moolenbroek 			}
1562*b636d99dSDavid van Moolenbroek 			if (j == 0)
1563*b636d99dSDavid van Moolenbroek 				ND_PRINT((ndo, " <none!>"));
1564*b636d99dSDavid van Moolenbroek 		}
1565*b636d99dSDavid van Moolenbroek 			break;
1566*b636d99dSDavid van Moolenbroek 		case 508:		/* Get CPS */
1567*b636d99dSDavid van Moolenbroek 		case 514:		/* List elements */
1568*b636d99dSDavid van Moolenbroek 		case 517:		/* List owned */
1569*b636d99dSDavid van Moolenbroek 		case 518:		/* Get CPS2 */
1570*b636d99dSDavid van Moolenbroek 		case 519:		/* Get host CPS */
1571*b636d99dSDavid van Moolenbroek 		{
1572*b636d99dSDavid van Moolenbroek 			unsigned long j;
1573*b636d99dSDavid van Moolenbroek 			ND_TCHECK2(bp[0], 4);
1574*b636d99dSDavid van Moolenbroek 			j = EXTRACT_32BITS(bp);
1575*b636d99dSDavid van Moolenbroek 			bp += sizeof(int32_t);
1576*b636d99dSDavid van Moolenbroek 			for (i = 0; i < j; i++) {
1577*b636d99dSDavid van Moolenbroek 				INTOUT();
1578*b636d99dSDavid van Moolenbroek 			}
1579*b636d99dSDavid van Moolenbroek 			if (j == 0)
1580*b636d99dSDavid van Moolenbroek 				ND_PRINT((ndo, " <none!>"));
1581*b636d99dSDavid van Moolenbroek 		}
1582*b636d99dSDavid van Moolenbroek 			break;
1583*b636d99dSDavid van Moolenbroek 		case 510:		/* List max */
1584*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " maxuid"));
1585*b636d99dSDavid van Moolenbroek 			INTOUT();
1586*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " maxgid"));
1587*b636d99dSDavid van Moolenbroek 			INTOUT();
1588*b636d99dSDavid van Moolenbroek 			break;
1589*b636d99dSDavid van Moolenbroek 		default:
1590*b636d99dSDavid van Moolenbroek 			;
1591*b636d99dSDavid van Moolenbroek 		}
1592*b636d99dSDavid van Moolenbroek 	else {
1593*b636d99dSDavid van Moolenbroek 		/*
1594*b636d99dSDavid van Moolenbroek 		 * Otherwise, just print out the return code
1595*b636d99dSDavid van Moolenbroek 		 */
1596*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, " errcode"));
1597*b636d99dSDavid van Moolenbroek 		INTOUT();
1598*b636d99dSDavid van Moolenbroek 	}
1599*b636d99dSDavid van Moolenbroek 
1600*b636d99dSDavid van Moolenbroek 	return;
1601*b636d99dSDavid van Moolenbroek 
1602*b636d99dSDavid van Moolenbroek trunc:
1603*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, " [|pt]"));
1604*b636d99dSDavid van Moolenbroek }
1605*b636d99dSDavid van Moolenbroek 
1606*b636d99dSDavid van Moolenbroek /*
1607*b636d99dSDavid van Moolenbroek  * Handle calls to the AFS volume location database service
1608*b636d99dSDavid van Moolenbroek  */
1609*b636d99dSDavid van Moolenbroek 
1610*b636d99dSDavid van Moolenbroek static void
vldb_print(netdissect_options * ndo,register const u_char * bp,int length)1611*b636d99dSDavid van Moolenbroek vldb_print(netdissect_options *ndo,
1612*b636d99dSDavid van Moolenbroek            register const u_char *bp, int length)
1613*b636d99dSDavid van Moolenbroek {
1614*b636d99dSDavid van Moolenbroek 	int vldb_op;
1615*b636d99dSDavid van Moolenbroek 	unsigned long i;
1616*b636d99dSDavid van Moolenbroek 
1617*b636d99dSDavid van Moolenbroek 	if (length <= (int)sizeof(struct rx_header))
1618*b636d99dSDavid van Moolenbroek 		return;
1619*b636d99dSDavid van Moolenbroek 
1620*b636d99dSDavid van Moolenbroek 	if (ndo->ndo_snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) {
1621*b636d99dSDavid van Moolenbroek 		goto trunc;
1622*b636d99dSDavid van Moolenbroek 	}
1623*b636d99dSDavid van Moolenbroek 
1624*b636d99dSDavid van Moolenbroek 	/*
1625*b636d99dSDavid van Moolenbroek 	 * Print out the afs call we're invoking.  The table used here was
1626*b636d99dSDavid van Moolenbroek 	 * gleaned from vlserver/vldbint.xg
1627*b636d99dSDavid van Moolenbroek 	 */
1628*b636d99dSDavid van Moolenbroek 
1629*b636d99dSDavid van Moolenbroek 	vldb_op = EXTRACT_32BITS(bp + sizeof(struct rx_header));
1630*b636d99dSDavid van Moolenbroek 
1631*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, " vldb"));
1632*b636d99dSDavid van Moolenbroek 
1633*b636d99dSDavid van Moolenbroek 	if (is_ubik(vldb_op)) {
1634*b636d99dSDavid van Moolenbroek 		ubik_print(ndo, bp);
1635*b636d99dSDavid van Moolenbroek 		return;
1636*b636d99dSDavid van Moolenbroek 	}
1637*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, " call %s", tok2str(vldb_req, "op#%d", vldb_op)));
1638*b636d99dSDavid van Moolenbroek 
1639*b636d99dSDavid van Moolenbroek 	/*
1640*b636d99dSDavid van Moolenbroek 	 * Decode some of the arguments to the VLDB calls
1641*b636d99dSDavid van Moolenbroek 	 */
1642*b636d99dSDavid van Moolenbroek 
1643*b636d99dSDavid van Moolenbroek 	bp += sizeof(struct rx_header) + 4;
1644*b636d99dSDavid van Moolenbroek 
1645*b636d99dSDavid van Moolenbroek 	switch (vldb_op) {
1646*b636d99dSDavid van Moolenbroek 		case 501:	/* Create new volume */
1647*b636d99dSDavid van Moolenbroek 		case 517:	/* Create entry N */
1648*b636d99dSDavid van Moolenbroek 			VECOUT(VLNAMEMAX);
1649*b636d99dSDavid van Moolenbroek 			break;
1650*b636d99dSDavid van Moolenbroek 		case 502:	/* Delete entry */
1651*b636d99dSDavid van Moolenbroek 		case 503:	/* Get entry by ID */
1652*b636d99dSDavid van Moolenbroek 		case 507:	/* Update entry */
1653*b636d99dSDavid van Moolenbroek 		case 508:	/* Set lock */
1654*b636d99dSDavid van Moolenbroek 		case 509:	/* Release lock */
1655*b636d99dSDavid van Moolenbroek 		case 518:	/* Get entry by ID N */
1656*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " volid"));
1657*b636d99dSDavid van Moolenbroek 			INTOUT();
1658*b636d99dSDavid van Moolenbroek 			ND_TCHECK2(bp[0], sizeof(int32_t));
1659*b636d99dSDavid van Moolenbroek 			i = EXTRACT_32BITS(bp);
1660*b636d99dSDavid van Moolenbroek 			bp += sizeof(int32_t);
1661*b636d99dSDavid van Moolenbroek 			if (i <= 2)
1662*b636d99dSDavid van Moolenbroek 				ND_PRINT((ndo, " type %s", voltype[i]));
1663*b636d99dSDavid van Moolenbroek 			break;
1664*b636d99dSDavid van Moolenbroek 		case 504:	/* Get entry by name */
1665*b636d99dSDavid van Moolenbroek 		case 519:	/* Get entry by name N */
1666*b636d99dSDavid van Moolenbroek 		case 524:	/* Update entry by name */
1667*b636d99dSDavid van Moolenbroek 		case 527:	/* Get entry by name U */
1668*b636d99dSDavid van Moolenbroek 			STROUT(VLNAMEMAX);
1669*b636d99dSDavid van Moolenbroek 			break;
1670*b636d99dSDavid van Moolenbroek 		case 505:	/* Get new vol id */
1671*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " bump"));
1672*b636d99dSDavid van Moolenbroek 			INTOUT();
1673*b636d99dSDavid van Moolenbroek 			break;
1674*b636d99dSDavid van Moolenbroek 		case 506:	/* Replace entry */
1675*b636d99dSDavid van Moolenbroek 		case 520:	/* Replace entry N */
1676*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " volid"));
1677*b636d99dSDavid van Moolenbroek 			INTOUT();
1678*b636d99dSDavid van Moolenbroek 			ND_TCHECK2(bp[0], sizeof(int32_t));
1679*b636d99dSDavid van Moolenbroek 			i = EXTRACT_32BITS(bp);
1680*b636d99dSDavid van Moolenbroek 			bp += sizeof(int32_t);
1681*b636d99dSDavid van Moolenbroek 			if (i <= 2)
1682*b636d99dSDavid van Moolenbroek 				ND_PRINT((ndo, " type %s", voltype[i]));
1683*b636d99dSDavid van Moolenbroek 			VECOUT(VLNAMEMAX);
1684*b636d99dSDavid van Moolenbroek 			break;
1685*b636d99dSDavid van Moolenbroek 		case 510:	/* List entry */
1686*b636d99dSDavid van Moolenbroek 		case 521:	/* List entry N */
1687*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " index"));
1688*b636d99dSDavid van Moolenbroek 			INTOUT();
1689*b636d99dSDavid van Moolenbroek 			break;
1690*b636d99dSDavid van Moolenbroek 		default:
1691*b636d99dSDavid van Moolenbroek 			;
1692*b636d99dSDavid van Moolenbroek 	}
1693*b636d99dSDavid van Moolenbroek 
1694*b636d99dSDavid van Moolenbroek 	return;
1695*b636d99dSDavid van Moolenbroek 
1696*b636d99dSDavid van Moolenbroek trunc:
1697*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, " [|vldb]"));
1698*b636d99dSDavid van Moolenbroek }
1699*b636d99dSDavid van Moolenbroek 
1700*b636d99dSDavid van Moolenbroek /*
1701*b636d99dSDavid van Moolenbroek  * Handle replies to the AFS volume location database service
1702*b636d99dSDavid van Moolenbroek  */
1703*b636d99dSDavid van Moolenbroek 
1704*b636d99dSDavid van Moolenbroek static void
vldb_reply_print(netdissect_options * ndo,register const u_char * bp,int length,int32_t opcode)1705*b636d99dSDavid van Moolenbroek vldb_reply_print(netdissect_options *ndo,
1706*b636d99dSDavid van Moolenbroek                  register const u_char *bp, int length, int32_t opcode)
1707*b636d99dSDavid van Moolenbroek {
1708*b636d99dSDavid van Moolenbroek 	struct rx_header *rxh;
1709*b636d99dSDavid van Moolenbroek 	unsigned long i;
1710*b636d99dSDavid van Moolenbroek 
1711*b636d99dSDavid van Moolenbroek 	if (length < (int)sizeof(struct rx_header))
1712*b636d99dSDavid van Moolenbroek 		return;
1713*b636d99dSDavid van Moolenbroek 
1714*b636d99dSDavid van Moolenbroek 	rxh = (struct rx_header *) bp;
1715*b636d99dSDavid van Moolenbroek 
1716*b636d99dSDavid van Moolenbroek 	/*
1717*b636d99dSDavid van Moolenbroek 	 * Print out the afs call we're invoking.  The table used here was
1718*b636d99dSDavid van Moolenbroek 	 * gleaned from vlserver/vldbint.xg.  Check to see if it's a
1719*b636d99dSDavid van Moolenbroek 	 * Ubik call, however.
1720*b636d99dSDavid van Moolenbroek 	 */
1721*b636d99dSDavid van Moolenbroek 
1722*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, " vldb"));
1723*b636d99dSDavid van Moolenbroek 
1724*b636d99dSDavid van Moolenbroek 	if (is_ubik(opcode)) {
1725*b636d99dSDavid van Moolenbroek 		ubik_reply_print(ndo, bp, length, opcode);
1726*b636d99dSDavid van Moolenbroek 		return;
1727*b636d99dSDavid van Moolenbroek 	}
1728*b636d99dSDavid van Moolenbroek 
1729*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, " reply %s", tok2str(vldb_req, "op#%d", opcode)));
1730*b636d99dSDavid van Moolenbroek 
1731*b636d99dSDavid van Moolenbroek 	bp += sizeof(struct rx_header);
1732*b636d99dSDavid van Moolenbroek 
1733*b636d99dSDavid van Moolenbroek 	/*
1734*b636d99dSDavid van Moolenbroek 	 * If it was a data packet, interpret the response
1735*b636d99dSDavid van Moolenbroek 	 */
1736*b636d99dSDavid van Moolenbroek 
1737*b636d99dSDavid van Moolenbroek 	if (rxh->type == RX_PACKET_TYPE_DATA)
1738*b636d99dSDavid van Moolenbroek 		switch (opcode) {
1739*b636d99dSDavid van Moolenbroek 		case 510:	/* List entry */
1740*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " count"));
1741*b636d99dSDavid van Moolenbroek 			INTOUT();
1742*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " nextindex"));
1743*b636d99dSDavid van Moolenbroek 			INTOUT();
1744*b636d99dSDavid van Moolenbroek 		case 503:	/* Get entry by id */
1745*b636d99dSDavid van Moolenbroek 		case 504:	/* Get entry by name */
1746*b636d99dSDavid van Moolenbroek 		{	unsigned long nservers, j;
1747*b636d99dSDavid van Moolenbroek 			VECOUT(VLNAMEMAX);
1748*b636d99dSDavid van Moolenbroek 			ND_TCHECK2(bp[0], sizeof(int32_t));
1749*b636d99dSDavid van Moolenbroek 			bp += sizeof(int32_t);
1750*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " numservers"));
1751*b636d99dSDavid van Moolenbroek 			ND_TCHECK2(bp[0], sizeof(int32_t));
1752*b636d99dSDavid van Moolenbroek 			nservers = EXTRACT_32BITS(bp);
1753*b636d99dSDavid van Moolenbroek 			bp += sizeof(int32_t);
1754*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " %lu", nservers));
1755*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " servers"));
1756*b636d99dSDavid van Moolenbroek 			for (i = 0; i < 8; i++) {
1757*b636d99dSDavid van Moolenbroek 				ND_TCHECK2(bp[0], sizeof(int32_t));
1758*b636d99dSDavid van Moolenbroek 				if (i < nservers)
1759*b636d99dSDavid van Moolenbroek 					ND_PRINT((ndo, " %s",
1760*b636d99dSDavid van Moolenbroek 					   intoa(((struct in_addr *) bp)->s_addr)));
1761*b636d99dSDavid van Moolenbroek 				bp += sizeof(int32_t);
1762*b636d99dSDavid van Moolenbroek 			}
1763*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " partitions"));
1764*b636d99dSDavid van Moolenbroek 			for (i = 0; i < 8; i++) {
1765*b636d99dSDavid van Moolenbroek 				ND_TCHECK2(bp[0], sizeof(int32_t));
1766*b636d99dSDavid van Moolenbroek 				j = EXTRACT_32BITS(bp);
1767*b636d99dSDavid van Moolenbroek 				if (i < nservers && j <= 26)
1768*b636d99dSDavid van Moolenbroek 					ND_PRINT((ndo, " %c", 'a' + (int)j));
1769*b636d99dSDavid van Moolenbroek 				else if (i < nservers)
1770*b636d99dSDavid van Moolenbroek 					ND_PRINT((ndo, " %lu", j));
1771*b636d99dSDavid van Moolenbroek 				bp += sizeof(int32_t);
1772*b636d99dSDavid van Moolenbroek 			}
1773*b636d99dSDavid van Moolenbroek 			ND_TCHECK2(bp[0], 8 * sizeof(int32_t));
1774*b636d99dSDavid van Moolenbroek 			bp += 8 * sizeof(int32_t);
1775*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " rwvol"));
1776*b636d99dSDavid van Moolenbroek 			UINTOUT();
1777*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " rovol"));
1778*b636d99dSDavid van Moolenbroek 			UINTOUT();
1779*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " backup"));
1780*b636d99dSDavid van Moolenbroek 			UINTOUT();
1781*b636d99dSDavid van Moolenbroek 		}
1782*b636d99dSDavid van Moolenbroek 			break;
1783*b636d99dSDavid van Moolenbroek 		case 505:	/* Get new volume ID */
1784*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " newvol"));
1785*b636d99dSDavid van Moolenbroek 			UINTOUT();
1786*b636d99dSDavid van Moolenbroek 			break;
1787*b636d99dSDavid van Moolenbroek 		case 521:	/* List entry */
1788*b636d99dSDavid van Moolenbroek 		case 529:	/* List entry U */
1789*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " count"));
1790*b636d99dSDavid van Moolenbroek 			INTOUT();
1791*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " nextindex"));
1792*b636d99dSDavid van Moolenbroek 			INTOUT();
1793*b636d99dSDavid van Moolenbroek 		case 518:	/* Get entry by ID N */
1794*b636d99dSDavid van Moolenbroek 		case 519:	/* Get entry by name N */
1795*b636d99dSDavid van Moolenbroek 		{	unsigned long nservers, j;
1796*b636d99dSDavid van Moolenbroek 			VECOUT(VLNAMEMAX);
1797*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " numservers"));
1798*b636d99dSDavid van Moolenbroek 			ND_TCHECK2(bp[0], sizeof(int32_t));
1799*b636d99dSDavid van Moolenbroek 			nservers = EXTRACT_32BITS(bp);
1800*b636d99dSDavid van Moolenbroek 			bp += sizeof(int32_t);
1801*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " %lu", nservers));
1802*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " servers"));
1803*b636d99dSDavid van Moolenbroek 			for (i = 0; i < 13; i++) {
1804*b636d99dSDavid van Moolenbroek 				ND_TCHECK2(bp[0], sizeof(int32_t));
1805*b636d99dSDavid van Moolenbroek 				if (i < nservers)
1806*b636d99dSDavid van Moolenbroek 					ND_PRINT((ndo, " %s",
1807*b636d99dSDavid van Moolenbroek 					   intoa(((struct in_addr *) bp)->s_addr)));
1808*b636d99dSDavid van Moolenbroek 				bp += sizeof(int32_t);
1809*b636d99dSDavid van Moolenbroek 			}
1810*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " partitions"));
1811*b636d99dSDavid van Moolenbroek 			for (i = 0; i < 13; i++) {
1812*b636d99dSDavid van Moolenbroek 				ND_TCHECK2(bp[0], sizeof(int32_t));
1813*b636d99dSDavid van Moolenbroek 				j = EXTRACT_32BITS(bp);
1814*b636d99dSDavid van Moolenbroek 				if (i < nservers && j <= 26)
1815*b636d99dSDavid van Moolenbroek 					ND_PRINT((ndo, " %c", 'a' + (int)j));
1816*b636d99dSDavid van Moolenbroek 				else if (i < nservers)
1817*b636d99dSDavid van Moolenbroek 					ND_PRINT((ndo, " %lu", j));
1818*b636d99dSDavid van Moolenbroek 				bp += sizeof(int32_t);
1819*b636d99dSDavid van Moolenbroek 			}
1820*b636d99dSDavid van Moolenbroek 			ND_TCHECK2(bp[0], 13 * sizeof(int32_t));
1821*b636d99dSDavid van Moolenbroek 			bp += 13 * sizeof(int32_t);
1822*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " rwvol"));
1823*b636d99dSDavid van Moolenbroek 			UINTOUT();
1824*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " rovol"));
1825*b636d99dSDavid van Moolenbroek 			UINTOUT();
1826*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " backup"));
1827*b636d99dSDavid van Moolenbroek 			UINTOUT();
1828*b636d99dSDavid van Moolenbroek 		}
1829*b636d99dSDavid van Moolenbroek 			break;
1830*b636d99dSDavid van Moolenbroek 		case 526:	/* Get entry by ID U */
1831*b636d99dSDavid van Moolenbroek 		case 527:	/* Get entry by name U */
1832*b636d99dSDavid van Moolenbroek 		{	unsigned long nservers, j;
1833*b636d99dSDavid van Moolenbroek 			VECOUT(VLNAMEMAX);
1834*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " numservers"));
1835*b636d99dSDavid van Moolenbroek 			ND_TCHECK2(bp[0], sizeof(int32_t));
1836*b636d99dSDavid van Moolenbroek 			nservers = EXTRACT_32BITS(bp);
1837*b636d99dSDavid van Moolenbroek 			bp += sizeof(int32_t);
1838*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " %lu", nservers));
1839*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " servers"));
1840*b636d99dSDavid van Moolenbroek 			for (i = 0; i < 13; i++) {
1841*b636d99dSDavid van Moolenbroek 				if (i < nservers) {
1842*b636d99dSDavid van Moolenbroek 					ND_PRINT((ndo, " afsuuid"));
1843*b636d99dSDavid van Moolenbroek 					AFSUUIDOUT();
1844*b636d99dSDavid van Moolenbroek 				} else {
1845*b636d99dSDavid van Moolenbroek 					ND_TCHECK2(bp[0], 44);
1846*b636d99dSDavid van Moolenbroek 					bp += 44;
1847*b636d99dSDavid van Moolenbroek 				}
1848*b636d99dSDavid van Moolenbroek 			}
1849*b636d99dSDavid van Moolenbroek 			ND_TCHECK2(bp[0], 4 * 13);
1850*b636d99dSDavid van Moolenbroek 			bp += 4 * 13;
1851*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " partitions"));
1852*b636d99dSDavid van Moolenbroek 			for (i = 0; i < 13; i++) {
1853*b636d99dSDavid van Moolenbroek 				ND_TCHECK2(bp[0], sizeof(int32_t));
1854*b636d99dSDavid van Moolenbroek 				j = EXTRACT_32BITS(bp);
1855*b636d99dSDavid van Moolenbroek 				if (i < nservers && j <= 26)
1856*b636d99dSDavid van Moolenbroek 					ND_PRINT((ndo, " %c", 'a' + (int)j));
1857*b636d99dSDavid van Moolenbroek 				else if (i < nservers)
1858*b636d99dSDavid van Moolenbroek 					ND_PRINT((ndo, " %lu", j));
1859*b636d99dSDavid van Moolenbroek 				bp += sizeof(int32_t);
1860*b636d99dSDavid van Moolenbroek 			}
1861*b636d99dSDavid van Moolenbroek 			ND_TCHECK2(bp[0], 13 * sizeof(int32_t));
1862*b636d99dSDavid van Moolenbroek 			bp += 13 * sizeof(int32_t);
1863*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " rwvol"));
1864*b636d99dSDavid van Moolenbroek 			UINTOUT();
1865*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " rovol"));
1866*b636d99dSDavid van Moolenbroek 			UINTOUT();
1867*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " backup"));
1868*b636d99dSDavid van Moolenbroek 			UINTOUT();
1869*b636d99dSDavid van Moolenbroek 		}
1870*b636d99dSDavid van Moolenbroek 		default:
1871*b636d99dSDavid van Moolenbroek 			;
1872*b636d99dSDavid van Moolenbroek 		}
1873*b636d99dSDavid van Moolenbroek 
1874*b636d99dSDavid van Moolenbroek 	else {
1875*b636d99dSDavid van Moolenbroek 		/*
1876*b636d99dSDavid van Moolenbroek 		 * Otherwise, just print out the return code
1877*b636d99dSDavid van Moolenbroek 		 */
1878*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, " errcode"));
1879*b636d99dSDavid van Moolenbroek 		INTOUT();
1880*b636d99dSDavid van Moolenbroek 	}
1881*b636d99dSDavid van Moolenbroek 
1882*b636d99dSDavid van Moolenbroek 	return;
1883*b636d99dSDavid van Moolenbroek 
1884*b636d99dSDavid van Moolenbroek trunc:
1885*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, " [|vldb]"));
1886*b636d99dSDavid van Moolenbroek }
1887*b636d99dSDavid van Moolenbroek 
1888*b636d99dSDavid van Moolenbroek /*
1889*b636d99dSDavid van Moolenbroek  * Handle calls to the AFS Kerberos Authentication service
1890*b636d99dSDavid van Moolenbroek  */
1891*b636d99dSDavid van Moolenbroek 
1892*b636d99dSDavid van Moolenbroek static void
kauth_print(netdissect_options * ndo,register const u_char * bp,int length)1893*b636d99dSDavid van Moolenbroek kauth_print(netdissect_options *ndo,
1894*b636d99dSDavid van Moolenbroek             register const u_char *bp, int length)
1895*b636d99dSDavid van Moolenbroek {
1896*b636d99dSDavid van Moolenbroek 	int kauth_op;
1897*b636d99dSDavid van Moolenbroek 
1898*b636d99dSDavid van Moolenbroek 	if (length <= (int)sizeof(struct rx_header))
1899*b636d99dSDavid van Moolenbroek 		return;
1900*b636d99dSDavid van Moolenbroek 
1901*b636d99dSDavid van Moolenbroek 	if (ndo->ndo_snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) {
1902*b636d99dSDavid van Moolenbroek 		goto trunc;
1903*b636d99dSDavid van Moolenbroek 	}
1904*b636d99dSDavid van Moolenbroek 
1905*b636d99dSDavid van Moolenbroek 	/*
1906*b636d99dSDavid van Moolenbroek 	 * Print out the afs call we're invoking.  The table used here was
1907*b636d99dSDavid van Moolenbroek 	 * gleaned from kauth/kauth.rg
1908*b636d99dSDavid van Moolenbroek 	 */
1909*b636d99dSDavid van Moolenbroek 
1910*b636d99dSDavid van Moolenbroek 	kauth_op = EXTRACT_32BITS(bp + sizeof(struct rx_header));
1911*b636d99dSDavid van Moolenbroek 
1912*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, " kauth"));
1913*b636d99dSDavid van Moolenbroek 
1914*b636d99dSDavid van Moolenbroek 	if (is_ubik(kauth_op)) {
1915*b636d99dSDavid van Moolenbroek 		ubik_print(ndo, bp);
1916*b636d99dSDavid van Moolenbroek 		return;
1917*b636d99dSDavid van Moolenbroek 	}
1918*b636d99dSDavid van Moolenbroek 
1919*b636d99dSDavid van Moolenbroek 
1920*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, " call %s", tok2str(kauth_req, "op#%d", kauth_op)));
1921*b636d99dSDavid van Moolenbroek 
1922*b636d99dSDavid van Moolenbroek 	/*
1923*b636d99dSDavid van Moolenbroek 	 * Decode some of the arguments to the KA calls
1924*b636d99dSDavid van Moolenbroek 	 */
1925*b636d99dSDavid van Moolenbroek 
1926*b636d99dSDavid van Moolenbroek 	bp += sizeof(struct rx_header) + 4;
1927*b636d99dSDavid van Moolenbroek 
1928*b636d99dSDavid van Moolenbroek 	switch (kauth_op) {
1929*b636d99dSDavid van Moolenbroek 		case 1:		/* Authenticate old */;
1930*b636d99dSDavid van Moolenbroek 		case 21:	/* Authenticate */
1931*b636d99dSDavid van Moolenbroek 		case 22:	/* Authenticate-V2 */
1932*b636d99dSDavid van Moolenbroek 		case 2:		/* Change PW */
1933*b636d99dSDavid van Moolenbroek 		case 5:		/* Set fields */
1934*b636d99dSDavid van Moolenbroek 		case 6:		/* Create user */
1935*b636d99dSDavid van Moolenbroek 		case 7:		/* Delete user */
1936*b636d99dSDavid van Moolenbroek 		case 8:		/* Get entry */
1937*b636d99dSDavid van Moolenbroek 		case 14:	/* Unlock */
1938*b636d99dSDavid van Moolenbroek 		case 15:	/* Lock status */
1939*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " principal"));
1940*b636d99dSDavid van Moolenbroek 			STROUT(KANAMEMAX);
1941*b636d99dSDavid van Moolenbroek 			STROUT(KANAMEMAX);
1942*b636d99dSDavid van Moolenbroek 			break;
1943*b636d99dSDavid van Moolenbroek 		case 3:		/* GetTicket-old */
1944*b636d99dSDavid van Moolenbroek 		case 23:	/* GetTicket */
1945*b636d99dSDavid van Moolenbroek 		{
1946*b636d99dSDavid van Moolenbroek 			int i;
1947*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " kvno"));
1948*b636d99dSDavid van Moolenbroek 			INTOUT();
1949*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " domain"));
1950*b636d99dSDavid van Moolenbroek 			STROUT(KANAMEMAX);
1951*b636d99dSDavid van Moolenbroek 			ND_TCHECK2(bp[0], sizeof(int32_t));
1952*b636d99dSDavid van Moolenbroek 			i = (int) EXTRACT_32BITS(bp);
1953*b636d99dSDavid van Moolenbroek 			bp += sizeof(int32_t);
1954*b636d99dSDavid van Moolenbroek 			ND_TCHECK2(bp[0], i);
1955*b636d99dSDavid van Moolenbroek 			bp += i;
1956*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " principal"));
1957*b636d99dSDavid van Moolenbroek 			STROUT(KANAMEMAX);
1958*b636d99dSDavid van Moolenbroek 			STROUT(KANAMEMAX);
1959*b636d99dSDavid van Moolenbroek 			break;
1960*b636d99dSDavid van Moolenbroek 		}
1961*b636d99dSDavid van Moolenbroek 		case 4:		/* Set Password */
1962*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " principal"));
1963*b636d99dSDavid van Moolenbroek 			STROUT(KANAMEMAX);
1964*b636d99dSDavid van Moolenbroek 			STROUT(KANAMEMAX);
1965*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " kvno"));
1966*b636d99dSDavid van Moolenbroek 			INTOUT();
1967*b636d99dSDavid van Moolenbroek 			break;
1968*b636d99dSDavid van Moolenbroek 		case 12:	/* Get password */
1969*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " name"));
1970*b636d99dSDavid van Moolenbroek 			STROUT(KANAMEMAX);
1971*b636d99dSDavid van Moolenbroek 			break;
1972*b636d99dSDavid van Moolenbroek 		default:
1973*b636d99dSDavid van Moolenbroek 			;
1974*b636d99dSDavid van Moolenbroek 	}
1975*b636d99dSDavid van Moolenbroek 
1976*b636d99dSDavid van Moolenbroek 	return;
1977*b636d99dSDavid van Moolenbroek 
1978*b636d99dSDavid van Moolenbroek trunc:
1979*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, " [|kauth]"));
1980*b636d99dSDavid van Moolenbroek }
1981*b636d99dSDavid van Moolenbroek 
1982*b636d99dSDavid van Moolenbroek /*
1983*b636d99dSDavid van Moolenbroek  * Handle replies to the AFS Kerberos Authentication Service
1984*b636d99dSDavid van Moolenbroek  */
1985*b636d99dSDavid van Moolenbroek 
1986*b636d99dSDavid van Moolenbroek static void
kauth_reply_print(netdissect_options * ndo,register const u_char * bp,int length,int32_t opcode)1987*b636d99dSDavid van Moolenbroek kauth_reply_print(netdissect_options *ndo,
1988*b636d99dSDavid van Moolenbroek                   register const u_char *bp, int length, int32_t opcode)
1989*b636d99dSDavid van Moolenbroek {
1990*b636d99dSDavid van Moolenbroek 	struct rx_header *rxh;
1991*b636d99dSDavid van Moolenbroek 
1992*b636d99dSDavid van Moolenbroek 	if (length <= (int)sizeof(struct rx_header))
1993*b636d99dSDavid van Moolenbroek 		return;
1994*b636d99dSDavid van Moolenbroek 
1995*b636d99dSDavid van Moolenbroek 	rxh = (struct rx_header *) bp;
1996*b636d99dSDavid van Moolenbroek 
1997*b636d99dSDavid van Moolenbroek 	/*
1998*b636d99dSDavid van Moolenbroek 	 * Print out the afs call we're invoking.  The table used here was
1999*b636d99dSDavid van Moolenbroek 	 * gleaned from kauth/kauth.rg
2000*b636d99dSDavid van Moolenbroek 	 */
2001*b636d99dSDavid van Moolenbroek 
2002*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, " kauth"));
2003*b636d99dSDavid van Moolenbroek 
2004*b636d99dSDavid van Moolenbroek 	if (is_ubik(opcode)) {
2005*b636d99dSDavid van Moolenbroek 		ubik_reply_print(ndo, bp, length, opcode);
2006*b636d99dSDavid van Moolenbroek 		return;
2007*b636d99dSDavid van Moolenbroek 	}
2008*b636d99dSDavid van Moolenbroek 
2009*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, " reply %s", tok2str(kauth_req, "op#%d", opcode)));
2010*b636d99dSDavid van Moolenbroek 
2011*b636d99dSDavid van Moolenbroek 	bp += sizeof(struct rx_header);
2012*b636d99dSDavid van Moolenbroek 
2013*b636d99dSDavid van Moolenbroek 	/*
2014*b636d99dSDavid van Moolenbroek 	 * If it was a data packet, interpret the response.
2015*b636d99dSDavid van Moolenbroek 	 */
2016*b636d99dSDavid van Moolenbroek 
2017*b636d99dSDavid van Moolenbroek 	if (rxh->type == RX_PACKET_TYPE_DATA)
2018*b636d99dSDavid van Moolenbroek 		/* Well, no, not really.  Leave this for later */
2019*b636d99dSDavid van Moolenbroek 		;
2020*b636d99dSDavid van Moolenbroek 	else {
2021*b636d99dSDavid van Moolenbroek 		/*
2022*b636d99dSDavid van Moolenbroek 		 * Otherwise, just print out the return code
2023*b636d99dSDavid van Moolenbroek 		 */
2024*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, " errcode"));
2025*b636d99dSDavid van Moolenbroek 		INTOUT();
2026*b636d99dSDavid van Moolenbroek 	}
2027*b636d99dSDavid van Moolenbroek 
2028*b636d99dSDavid van Moolenbroek 	return;
2029*b636d99dSDavid van Moolenbroek 
2030*b636d99dSDavid van Moolenbroek trunc:
2031*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, " [|kauth]"));
2032*b636d99dSDavid van Moolenbroek }
2033*b636d99dSDavid van Moolenbroek 
2034*b636d99dSDavid van Moolenbroek /*
2035*b636d99dSDavid van Moolenbroek  * Handle calls to the AFS Volume location service
2036*b636d99dSDavid van Moolenbroek  */
2037*b636d99dSDavid van Moolenbroek 
2038*b636d99dSDavid van Moolenbroek static void
vol_print(netdissect_options * ndo,register const u_char * bp,int length)2039*b636d99dSDavid van Moolenbroek vol_print(netdissect_options *ndo,
2040*b636d99dSDavid van Moolenbroek           register const u_char *bp, int length)
2041*b636d99dSDavid van Moolenbroek {
2042*b636d99dSDavid van Moolenbroek 	int vol_op;
2043*b636d99dSDavid van Moolenbroek 
2044*b636d99dSDavid van Moolenbroek 	if (length <= (int)sizeof(struct rx_header))
2045*b636d99dSDavid van Moolenbroek 		return;
2046*b636d99dSDavid van Moolenbroek 
2047*b636d99dSDavid van Moolenbroek 	if (ndo->ndo_snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) {
2048*b636d99dSDavid van Moolenbroek 		goto trunc;
2049*b636d99dSDavid van Moolenbroek 	}
2050*b636d99dSDavid van Moolenbroek 
2051*b636d99dSDavid van Moolenbroek 	/*
2052*b636d99dSDavid van Moolenbroek 	 * Print out the afs call we're invoking.  The table used here was
2053*b636d99dSDavid van Moolenbroek 	 * gleaned from volser/volint.xg
2054*b636d99dSDavid van Moolenbroek 	 */
2055*b636d99dSDavid van Moolenbroek 
2056*b636d99dSDavid van Moolenbroek 	vol_op = EXTRACT_32BITS(bp + sizeof(struct rx_header));
2057*b636d99dSDavid van Moolenbroek 
2058*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, " vol call %s", tok2str(vol_req, "op#%d", vol_op)));
2059*b636d99dSDavid van Moolenbroek 
2060*b636d99dSDavid van Moolenbroek 	bp += sizeof(struct rx_header) + 4;
2061*b636d99dSDavid van Moolenbroek 
2062*b636d99dSDavid van Moolenbroek 	switch (vol_op) {
2063*b636d99dSDavid van Moolenbroek 		case 100:	/* Create volume */
2064*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " partition"));
2065*b636d99dSDavid van Moolenbroek 			UINTOUT();
2066*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " name"));
2067*b636d99dSDavid van Moolenbroek 			STROUT(AFSNAMEMAX);
2068*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " type"));
2069*b636d99dSDavid van Moolenbroek 			UINTOUT();
2070*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " parent"));
2071*b636d99dSDavid van Moolenbroek 			UINTOUT();
2072*b636d99dSDavid van Moolenbroek 			break;
2073*b636d99dSDavid van Moolenbroek 		case 101:	/* Delete volume */
2074*b636d99dSDavid van Moolenbroek 		case 107:	/* Get flags */
2075*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " trans"));
2076*b636d99dSDavid van Moolenbroek 			UINTOUT();
2077*b636d99dSDavid van Moolenbroek 			break;
2078*b636d99dSDavid van Moolenbroek 		case 102:	/* Restore */
2079*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " totrans"));
2080*b636d99dSDavid van Moolenbroek 			UINTOUT();
2081*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " flags"));
2082*b636d99dSDavid van Moolenbroek 			UINTOUT();
2083*b636d99dSDavid van Moolenbroek 			break;
2084*b636d99dSDavid van Moolenbroek 		case 103:	/* Forward */
2085*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " fromtrans"));
2086*b636d99dSDavid van Moolenbroek 			UINTOUT();
2087*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " fromdate"));
2088*b636d99dSDavid van Moolenbroek 			DATEOUT();
2089*b636d99dSDavid van Moolenbroek 			DESTSERVEROUT();
2090*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " desttrans"));
2091*b636d99dSDavid van Moolenbroek 			INTOUT();
2092*b636d99dSDavid van Moolenbroek 			break;
2093*b636d99dSDavid van Moolenbroek 		case 104:	/* End trans */
2094*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " trans"));
2095*b636d99dSDavid van Moolenbroek 			UINTOUT();
2096*b636d99dSDavid van Moolenbroek 			break;
2097*b636d99dSDavid van Moolenbroek 		case 105:	/* Clone */
2098*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " trans"));
2099*b636d99dSDavid van Moolenbroek 			UINTOUT();
2100*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " purgevol"));
2101*b636d99dSDavid van Moolenbroek 			UINTOUT();
2102*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " newtype"));
2103*b636d99dSDavid van Moolenbroek 			UINTOUT();
2104*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " newname"));
2105*b636d99dSDavid van Moolenbroek 			STROUT(AFSNAMEMAX);
2106*b636d99dSDavid van Moolenbroek 			break;
2107*b636d99dSDavid van Moolenbroek 		case 106:	/* Set flags */
2108*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " trans"));
2109*b636d99dSDavid van Moolenbroek 			UINTOUT();
2110*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " flags"));
2111*b636d99dSDavid van Moolenbroek 			UINTOUT();
2112*b636d99dSDavid van Moolenbroek 			break;
2113*b636d99dSDavid van Moolenbroek 		case 108:	/* Trans create */
2114*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " vol"));
2115*b636d99dSDavid van Moolenbroek 			UINTOUT();
2116*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " partition"));
2117*b636d99dSDavid van Moolenbroek 			UINTOUT();
2118*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " flags"));
2119*b636d99dSDavid van Moolenbroek 			UINTOUT();
2120*b636d99dSDavid van Moolenbroek 			break;
2121*b636d99dSDavid van Moolenbroek 		case 109:	/* Dump */
2122*b636d99dSDavid van Moolenbroek 		case 655537:	/* Get size */
2123*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " fromtrans"));
2124*b636d99dSDavid van Moolenbroek 			UINTOUT();
2125*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " fromdate"));
2126*b636d99dSDavid van Moolenbroek 			DATEOUT();
2127*b636d99dSDavid van Moolenbroek 			break;
2128*b636d99dSDavid van Moolenbroek 		case 110:	/* Get n-th volume */
2129*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " index"));
2130*b636d99dSDavid van Moolenbroek 			UINTOUT();
2131*b636d99dSDavid van Moolenbroek 			break;
2132*b636d99dSDavid van Moolenbroek 		case 111:	/* Set forwarding */
2133*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " tid"));
2134*b636d99dSDavid van Moolenbroek 			UINTOUT();
2135*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " newsite"));
2136*b636d99dSDavid van Moolenbroek 			UINTOUT();
2137*b636d99dSDavid van Moolenbroek 			break;
2138*b636d99dSDavid van Moolenbroek 		case 112:	/* Get name */
2139*b636d99dSDavid van Moolenbroek 		case 113:	/* Get status */
2140*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " tid"));
2141*b636d99dSDavid van Moolenbroek 			break;
2142*b636d99dSDavid van Moolenbroek 		case 114:	/* Signal restore */
2143*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " name"));
2144*b636d99dSDavid van Moolenbroek 			STROUT(AFSNAMEMAX);
2145*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " type"));
2146*b636d99dSDavid van Moolenbroek 			UINTOUT();
2147*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " pid"));
2148*b636d99dSDavid van Moolenbroek 			UINTOUT();
2149*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " cloneid"));
2150*b636d99dSDavid van Moolenbroek 			UINTOUT();
2151*b636d99dSDavid van Moolenbroek 			break;
2152*b636d99dSDavid van Moolenbroek 		case 116:	/* List volumes */
2153*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " partition"));
2154*b636d99dSDavid van Moolenbroek 			UINTOUT();
2155*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " flags"));
2156*b636d99dSDavid van Moolenbroek 			UINTOUT();
2157*b636d99dSDavid van Moolenbroek 			break;
2158*b636d99dSDavid van Moolenbroek 		case 117:	/* Set id types */
2159*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " tid"));
2160*b636d99dSDavid van Moolenbroek 			UINTOUT();
2161*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " name"));
2162*b636d99dSDavid van Moolenbroek 			STROUT(AFSNAMEMAX);
2163*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " type"));
2164*b636d99dSDavid van Moolenbroek 			UINTOUT();
2165*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " pid"));
2166*b636d99dSDavid van Moolenbroek 			UINTOUT();
2167*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " clone"));
2168*b636d99dSDavid van Moolenbroek 			UINTOUT();
2169*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " backup"));
2170*b636d99dSDavid van Moolenbroek 			UINTOUT();
2171*b636d99dSDavid van Moolenbroek 			break;
2172*b636d99dSDavid van Moolenbroek 		case 119:	/* Partition info */
2173*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " name"));
2174*b636d99dSDavid van Moolenbroek 			STROUT(AFSNAMEMAX);
2175*b636d99dSDavid van Moolenbroek 			break;
2176*b636d99dSDavid van Moolenbroek 		case 120:	/* Reclone */
2177*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " tid"));
2178*b636d99dSDavid van Moolenbroek 			UINTOUT();
2179*b636d99dSDavid van Moolenbroek 			break;
2180*b636d99dSDavid van Moolenbroek 		case 121:	/* List one volume */
2181*b636d99dSDavid van Moolenbroek 		case 122:	/* Nuke volume */
2182*b636d99dSDavid van Moolenbroek 		case 124:	/* Extended List volumes */
2183*b636d99dSDavid van Moolenbroek 		case 125:	/* Extended List one volume */
2184*b636d99dSDavid van Moolenbroek 		case 65536:	/* Convert RO to RW volume */
2185*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " partid"));
2186*b636d99dSDavid van Moolenbroek 			UINTOUT();
2187*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " volid"));
2188*b636d99dSDavid van Moolenbroek 			UINTOUT();
2189*b636d99dSDavid van Moolenbroek 			break;
2190*b636d99dSDavid van Moolenbroek 		case 123:	/* Set date */
2191*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " tid"));
2192*b636d99dSDavid van Moolenbroek 			UINTOUT();
2193*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " date"));
2194*b636d99dSDavid van Moolenbroek 			DATEOUT();
2195*b636d99dSDavid van Moolenbroek 			break;
2196*b636d99dSDavid van Moolenbroek 		case 126:	/* Set info */
2197*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " tid"));
2198*b636d99dSDavid van Moolenbroek 			UINTOUT();
2199*b636d99dSDavid van Moolenbroek 			break;
2200*b636d99dSDavid van Moolenbroek 		case 128:	/* Forward multiple */
2201*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " fromtrans"));
2202*b636d99dSDavid van Moolenbroek 			UINTOUT();
2203*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " fromdate"));
2204*b636d99dSDavid van Moolenbroek 			DATEOUT();
2205*b636d99dSDavid van Moolenbroek 			{
2206*b636d99dSDavid van Moolenbroek 				unsigned long i, j;
2207*b636d99dSDavid van Moolenbroek 				ND_TCHECK2(bp[0], 4);
2208*b636d99dSDavid van Moolenbroek 				j = EXTRACT_32BITS(bp);
2209*b636d99dSDavid van Moolenbroek 				bp += sizeof(int32_t);
2210*b636d99dSDavid van Moolenbroek 				for (i = 0; i < j; i++) {
2211*b636d99dSDavid van Moolenbroek 					DESTSERVEROUT();
2212*b636d99dSDavid van Moolenbroek 					if (i != j - 1)
2213*b636d99dSDavid van Moolenbroek 						ND_PRINT((ndo, ","));
2214*b636d99dSDavid van Moolenbroek 				}
2215*b636d99dSDavid van Moolenbroek 				if (j == 0)
2216*b636d99dSDavid van Moolenbroek 					ND_PRINT((ndo, " <none!>"));
2217*b636d99dSDavid van Moolenbroek 			}
2218*b636d99dSDavid van Moolenbroek 			break;
2219*b636d99dSDavid van Moolenbroek 		case 65538:	/* Dump version 2 */
2220*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " fromtrans"));
2221*b636d99dSDavid van Moolenbroek 			UINTOUT();
2222*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " fromdate"));
2223*b636d99dSDavid van Moolenbroek 			DATEOUT();
2224*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " flags"));
2225*b636d99dSDavid van Moolenbroek 			UINTOUT();
2226*b636d99dSDavid van Moolenbroek 			break;
2227*b636d99dSDavid van Moolenbroek 		default:
2228*b636d99dSDavid van Moolenbroek 			;
2229*b636d99dSDavid van Moolenbroek 	}
2230*b636d99dSDavid van Moolenbroek 	return;
2231*b636d99dSDavid van Moolenbroek 
2232*b636d99dSDavid van Moolenbroek trunc:
2233*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, " [|vol]"));
2234*b636d99dSDavid van Moolenbroek }
2235*b636d99dSDavid van Moolenbroek 
2236*b636d99dSDavid van Moolenbroek /*
2237*b636d99dSDavid van Moolenbroek  * Handle replies to the AFS Volume Service
2238*b636d99dSDavid van Moolenbroek  */
2239*b636d99dSDavid van Moolenbroek 
2240*b636d99dSDavid van Moolenbroek static void
vol_reply_print(netdissect_options * ndo,register const u_char * bp,int length,int32_t opcode)2241*b636d99dSDavid van Moolenbroek vol_reply_print(netdissect_options *ndo,
2242*b636d99dSDavid van Moolenbroek                 register const u_char *bp, int length, int32_t opcode)
2243*b636d99dSDavid van Moolenbroek {
2244*b636d99dSDavid van Moolenbroek 	struct rx_header *rxh;
2245*b636d99dSDavid van Moolenbroek 
2246*b636d99dSDavid van Moolenbroek 	if (length <= (int)sizeof(struct rx_header))
2247*b636d99dSDavid van Moolenbroek 		return;
2248*b636d99dSDavid van Moolenbroek 
2249*b636d99dSDavid van Moolenbroek 	rxh = (struct rx_header *) bp;
2250*b636d99dSDavid van Moolenbroek 
2251*b636d99dSDavid van Moolenbroek 	/*
2252*b636d99dSDavid van Moolenbroek 	 * Print out the afs call we're invoking.  The table used here was
2253*b636d99dSDavid van Moolenbroek 	 * gleaned from volser/volint.xg
2254*b636d99dSDavid van Moolenbroek 	 */
2255*b636d99dSDavid van Moolenbroek 
2256*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, " vol reply %s", tok2str(vol_req, "op#%d", opcode)));
2257*b636d99dSDavid van Moolenbroek 
2258*b636d99dSDavid van Moolenbroek 	bp += sizeof(struct rx_header);
2259*b636d99dSDavid van Moolenbroek 
2260*b636d99dSDavid van Moolenbroek 	/*
2261*b636d99dSDavid van Moolenbroek 	 * If it was a data packet, interpret the response.
2262*b636d99dSDavid van Moolenbroek 	 */
2263*b636d99dSDavid van Moolenbroek 
2264*b636d99dSDavid van Moolenbroek 	if (rxh->type == RX_PACKET_TYPE_DATA) {
2265*b636d99dSDavid van Moolenbroek 		switch (opcode) {
2266*b636d99dSDavid van Moolenbroek 			case 100:	/* Create volume */
2267*b636d99dSDavid van Moolenbroek 				ND_PRINT((ndo, " volid"));
2268*b636d99dSDavid van Moolenbroek 				UINTOUT();
2269*b636d99dSDavid van Moolenbroek 				ND_PRINT((ndo, " trans"));
2270*b636d99dSDavid van Moolenbroek 				UINTOUT();
2271*b636d99dSDavid van Moolenbroek 				break;
2272*b636d99dSDavid van Moolenbroek 			case 104:	/* End transaction */
2273*b636d99dSDavid van Moolenbroek 				UINTOUT();
2274*b636d99dSDavid van Moolenbroek 				break;
2275*b636d99dSDavid van Moolenbroek 			case 105:	/* Clone */
2276*b636d99dSDavid van Moolenbroek 				ND_PRINT((ndo, " newvol"));
2277*b636d99dSDavid van Moolenbroek 				UINTOUT();
2278*b636d99dSDavid van Moolenbroek 				break;
2279*b636d99dSDavid van Moolenbroek 			case 107:	/* Get flags */
2280*b636d99dSDavid van Moolenbroek 				UINTOUT();
2281*b636d99dSDavid van Moolenbroek 				break;
2282*b636d99dSDavid van Moolenbroek 			case 108:	/* Transaction create */
2283*b636d99dSDavid van Moolenbroek 				ND_PRINT((ndo, " trans"));
2284*b636d99dSDavid van Moolenbroek 				UINTOUT();
2285*b636d99dSDavid van Moolenbroek 				break;
2286*b636d99dSDavid van Moolenbroek 			case 110:	/* Get n-th volume */
2287*b636d99dSDavid van Moolenbroek 				ND_PRINT((ndo, " volume"));
2288*b636d99dSDavid van Moolenbroek 				UINTOUT();
2289*b636d99dSDavid van Moolenbroek 				ND_PRINT((ndo, " partition"));
2290*b636d99dSDavid van Moolenbroek 				UINTOUT();
2291*b636d99dSDavid van Moolenbroek 				break;
2292*b636d99dSDavid van Moolenbroek 			case 112:	/* Get name */
2293*b636d99dSDavid van Moolenbroek 				STROUT(AFSNAMEMAX);
2294*b636d99dSDavid van Moolenbroek 				break;
2295*b636d99dSDavid van Moolenbroek 			case 113:	/* Get status */
2296*b636d99dSDavid van Moolenbroek 				ND_PRINT((ndo, " volid"));
2297*b636d99dSDavid van Moolenbroek 				UINTOUT();
2298*b636d99dSDavid van Moolenbroek 				ND_PRINT((ndo, " nextuniq"));
2299*b636d99dSDavid van Moolenbroek 				UINTOUT();
2300*b636d99dSDavid van Moolenbroek 				ND_PRINT((ndo, " type"));
2301*b636d99dSDavid van Moolenbroek 				UINTOUT();
2302*b636d99dSDavid van Moolenbroek 				ND_PRINT((ndo, " parentid"));
2303*b636d99dSDavid van Moolenbroek 				UINTOUT();
2304*b636d99dSDavid van Moolenbroek 				ND_PRINT((ndo, " clone"));
2305*b636d99dSDavid van Moolenbroek 				UINTOUT();
2306*b636d99dSDavid van Moolenbroek 				ND_PRINT((ndo, " backup"));
2307*b636d99dSDavid van Moolenbroek 				UINTOUT();
2308*b636d99dSDavid van Moolenbroek 				ND_PRINT((ndo, " restore"));
2309*b636d99dSDavid van Moolenbroek 				UINTOUT();
2310*b636d99dSDavid van Moolenbroek 				ND_PRINT((ndo, " maxquota"));
2311*b636d99dSDavid van Moolenbroek 				UINTOUT();
2312*b636d99dSDavid van Moolenbroek 				ND_PRINT((ndo, " minquota"));
2313*b636d99dSDavid van Moolenbroek 				UINTOUT();
2314*b636d99dSDavid van Moolenbroek 				ND_PRINT((ndo, " owner"));
2315*b636d99dSDavid van Moolenbroek 				UINTOUT();
2316*b636d99dSDavid van Moolenbroek 				ND_PRINT((ndo, " create"));
2317*b636d99dSDavid van Moolenbroek 				DATEOUT();
2318*b636d99dSDavid van Moolenbroek 				ND_PRINT((ndo, " access"));
2319*b636d99dSDavid van Moolenbroek 				DATEOUT();
2320*b636d99dSDavid van Moolenbroek 				ND_PRINT((ndo, " update"));
2321*b636d99dSDavid van Moolenbroek 				DATEOUT();
2322*b636d99dSDavid van Moolenbroek 				ND_PRINT((ndo, " expire"));
2323*b636d99dSDavid van Moolenbroek 				DATEOUT();
2324*b636d99dSDavid van Moolenbroek 				ND_PRINT((ndo, " backup"));
2325*b636d99dSDavid van Moolenbroek 				DATEOUT();
2326*b636d99dSDavid van Moolenbroek 				ND_PRINT((ndo, " copy"));
2327*b636d99dSDavid van Moolenbroek 				DATEOUT();
2328*b636d99dSDavid van Moolenbroek 				break;
2329*b636d99dSDavid van Moolenbroek 			case 115:	/* Old list partitions */
2330*b636d99dSDavid van Moolenbroek 				break;
2331*b636d99dSDavid van Moolenbroek 			case 116:	/* List volumes */
2332*b636d99dSDavid van Moolenbroek 			case 121:	/* List one volume */
2333*b636d99dSDavid van Moolenbroek 				{
2334*b636d99dSDavid van Moolenbroek 					unsigned long i, j;
2335*b636d99dSDavid van Moolenbroek 					ND_TCHECK2(bp[0], 4);
2336*b636d99dSDavid van Moolenbroek 					j = EXTRACT_32BITS(bp);
2337*b636d99dSDavid van Moolenbroek 					bp += sizeof(int32_t);
2338*b636d99dSDavid van Moolenbroek 					for (i = 0; i < j; i++) {
2339*b636d99dSDavid van Moolenbroek 						ND_PRINT((ndo, " name"));
2340*b636d99dSDavid van Moolenbroek 						VECOUT(32);
2341*b636d99dSDavid van Moolenbroek 						ND_PRINT((ndo, " volid"));
2342*b636d99dSDavid van Moolenbroek 						UINTOUT();
2343*b636d99dSDavid van Moolenbroek 						ND_PRINT((ndo, " type"));
2344*b636d99dSDavid van Moolenbroek 						bp += sizeof(int32_t) * 21;
2345*b636d99dSDavid van Moolenbroek 						if (i != j - 1)
2346*b636d99dSDavid van Moolenbroek 							ND_PRINT((ndo, ","));
2347*b636d99dSDavid van Moolenbroek 					}
2348*b636d99dSDavid van Moolenbroek 					if (j == 0)
2349*b636d99dSDavid van Moolenbroek 						ND_PRINT((ndo, " <none!>"));
2350*b636d99dSDavid van Moolenbroek 				}
2351*b636d99dSDavid van Moolenbroek 				break;
2352*b636d99dSDavid van Moolenbroek 
2353*b636d99dSDavid van Moolenbroek 
2354*b636d99dSDavid van Moolenbroek 			default:
2355*b636d99dSDavid van Moolenbroek 				;
2356*b636d99dSDavid van Moolenbroek 		}
2357*b636d99dSDavid van Moolenbroek 	} else {
2358*b636d99dSDavid van Moolenbroek 		/*
2359*b636d99dSDavid van Moolenbroek 		 * Otherwise, just print out the return code
2360*b636d99dSDavid van Moolenbroek 		 */
2361*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, " errcode"));
2362*b636d99dSDavid van Moolenbroek 		INTOUT();
2363*b636d99dSDavid van Moolenbroek 	}
2364*b636d99dSDavid van Moolenbroek 
2365*b636d99dSDavid van Moolenbroek 	return;
2366*b636d99dSDavid van Moolenbroek 
2367*b636d99dSDavid van Moolenbroek trunc:
2368*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, " [|vol]"));
2369*b636d99dSDavid van Moolenbroek }
2370*b636d99dSDavid van Moolenbroek 
2371*b636d99dSDavid van Moolenbroek /*
2372*b636d99dSDavid van Moolenbroek  * Handle calls to the AFS BOS service
2373*b636d99dSDavid van Moolenbroek  */
2374*b636d99dSDavid van Moolenbroek 
2375*b636d99dSDavid van Moolenbroek static void
bos_print(netdissect_options * ndo,register const u_char * bp,int length)2376*b636d99dSDavid van Moolenbroek bos_print(netdissect_options *ndo,
2377*b636d99dSDavid van Moolenbroek           register const u_char *bp, int length)
2378*b636d99dSDavid van Moolenbroek {
2379*b636d99dSDavid van Moolenbroek 	int bos_op;
2380*b636d99dSDavid van Moolenbroek 
2381*b636d99dSDavid van Moolenbroek 	if (length <= (int)sizeof(struct rx_header))
2382*b636d99dSDavid van Moolenbroek 		return;
2383*b636d99dSDavid van Moolenbroek 
2384*b636d99dSDavid van Moolenbroek 	if (ndo->ndo_snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) {
2385*b636d99dSDavid van Moolenbroek 		goto trunc;
2386*b636d99dSDavid van Moolenbroek 	}
2387*b636d99dSDavid van Moolenbroek 
2388*b636d99dSDavid van Moolenbroek 	/*
2389*b636d99dSDavid van Moolenbroek 	 * Print out the afs call we're invoking.  The table used here was
2390*b636d99dSDavid van Moolenbroek 	 * gleaned from bozo/bosint.xg
2391*b636d99dSDavid van Moolenbroek 	 */
2392*b636d99dSDavid van Moolenbroek 
2393*b636d99dSDavid van Moolenbroek 	bos_op = EXTRACT_32BITS(bp + sizeof(struct rx_header));
2394*b636d99dSDavid van Moolenbroek 
2395*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, " bos call %s", tok2str(bos_req, "op#%d", bos_op)));
2396*b636d99dSDavid van Moolenbroek 
2397*b636d99dSDavid van Moolenbroek 	/*
2398*b636d99dSDavid van Moolenbroek 	 * Decode some of the arguments to the BOS calls
2399*b636d99dSDavid van Moolenbroek 	 */
2400*b636d99dSDavid van Moolenbroek 
2401*b636d99dSDavid van Moolenbroek 	bp += sizeof(struct rx_header) + 4;
2402*b636d99dSDavid van Moolenbroek 
2403*b636d99dSDavid van Moolenbroek 	switch (bos_op) {
2404*b636d99dSDavid van Moolenbroek 		case 80:	/* Create B node */
2405*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " type"));
2406*b636d99dSDavid van Moolenbroek 			STROUT(BOSNAMEMAX);
2407*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " instance"));
2408*b636d99dSDavid van Moolenbroek 			STROUT(BOSNAMEMAX);
2409*b636d99dSDavid van Moolenbroek 			break;
2410*b636d99dSDavid van Moolenbroek 		case 81:	/* Delete B node */
2411*b636d99dSDavid van Moolenbroek 		case 83:	/* Get status */
2412*b636d99dSDavid van Moolenbroek 		case 85:	/* Get instance info */
2413*b636d99dSDavid van Moolenbroek 		case 87:	/* Add super user */
2414*b636d99dSDavid van Moolenbroek 		case 88:	/* Delete super user */
2415*b636d99dSDavid van Moolenbroek 		case 93:	/* Set cell name */
2416*b636d99dSDavid van Moolenbroek 		case 96:	/* Add cell host */
2417*b636d99dSDavid van Moolenbroek 		case 97:	/* Delete cell host */
2418*b636d99dSDavid van Moolenbroek 		case 104:	/* Restart */
2419*b636d99dSDavid van Moolenbroek 		case 106:	/* Uninstall */
2420*b636d99dSDavid van Moolenbroek 		case 108:	/* Exec */
2421*b636d99dSDavid van Moolenbroek 		case 112:	/* Getlog */
2422*b636d99dSDavid van Moolenbroek 		case 114:	/* Get instance strings */
2423*b636d99dSDavid van Moolenbroek 			STROUT(BOSNAMEMAX);
2424*b636d99dSDavid van Moolenbroek 			break;
2425*b636d99dSDavid van Moolenbroek 		case 82:	/* Set status */
2426*b636d99dSDavid van Moolenbroek 		case 98:	/* Set T status */
2427*b636d99dSDavid van Moolenbroek 			STROUT(BOSNAMEMAX);
2428*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " status"));
2429*b636d99dSDavid van Moolenbroek 			INTOUT();
2430*b636d99dSDavid van Moolenbroek 			break;
2431*b636d99dSDavid van Moolenbroek 		case 86:	/* Get instance parm */
2432*b636d99dSDavid van Moolenbroek 			STROUT(BOSNAMEMAX);
2433*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " num"));
2434*b636d99dSDavid van Moolenbroek 			INTOUT();
2435*b636d99dSDavid van Moolenbroek 			break;
2436*b636d99dSDavid van Moolenbroek 		case 84:	/* Enumerate instance */
2437*b636d99dSDavid van Moolenbroek 		case 89:	/* List super users */
2438*b636d99dSDavid van Moolenbroek 		case 90:	/* List keys */
2439*b636d99dSDavid van Moolenbroek 		case 91:	/* Add key */
2440*b636d99dSDavid van Moolenbroek 		case 92:	/* Delete key */
2441*b636d99dSDavid van Moolenbroek 		case 95:	/* Get cell host */
2442*b636d99dSDavid van Moolenbroek 			INTOUT();
2443*b636d99dSDavid van Moolenbroek 			break;
2444*b636d99dSDavid van Moolenbroek 		case 105:	/* Install */
2445*b636d99dSDavid van Moolenbroek 			STROUT(BOSNAMEMAX);
2446*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " size"));
2447*b636d99dSDavid van Moolenbroek 			INTOUT();
2448*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " flags"));
2449*b636d99dSDavid van Moolenbroek 			INTOUT();
2450*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " date"));
2451*b636d99dSDavid van Moolenbroek 			INTOUT();
2452*b636d99dSDavid van Moolenbroek 			break;
2453*b636d99dSDavid van Moolenbroek 		default:
2454*b636d99dSDavid van Moolenbroek 			;
2455*b636d99dSDavid van Moolenbroek 	}
2456*b636d99dSDavid van Moolenbroek 
2457*b636d99dSDavid van Moolenbroek 	return;
2458*b636d99dSDavid van Moolenbroek 
2459*b636d99dSDavid van Moolenbroek trunc:
2460*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, " [|bos]"));
2461*b636d99dSDavid van Moolenbroek }
2462*b636d99dSDavid van Moolenbroek 
2463*b636d99dSDavid van Moolenbroek /*
2464*b636d99dSDavid van Moolenbroek  * Handle replies to the AFS BOS Service
2465*b636d99dSDavid van Moolenbroek  */
2466*b636d99dSDavid van Moolenbroek 
2467*b636d99dSDavid van Moolenbroek static void
bos_reply_print(netdissect_options * ndo,register const u_char * bp,int length,int32_t opcode)2468*b636d99dSDavid van Moolenbroek bos_reply_print(netdissect_options *ndo,
2469*b636d99dSDavid van Moolenbroek                 register const u_char *bp, int length, int32_t opcode)
2470*b636d99dSDavid van Moolenbroek {
2471*b636d99dSDavid van Moolenbroek 	struct rx_header *rxh;
2472*b636d99dSDavid van Moolenbroek 
2473*b636d99dSDavid van Moolenbroek 	if (length <= (int)sizeof(struct rx_header))
2474*b636d99dSDavid van Moolenbroek 		return;
2475*b636d99dSDavid van Moolenbroek 
2476*b636d99dSDavid van Moolenbroek 	rxh = (struct rx_header *) bp;
2477*b636d99dSDavid van Moolenbroek 
2478*b636d99dSDavid van Moolenbroek 	/*
2479*b636d99dSDavid van Moolenbroek 	 * Print out the afs call we're invoking.  The table used here was
2480*b636d99dSDavid van Moolenbroek 	 * gleaned from volser/volint.xg
2481*b636d99dSDavid van Moolenbroek 	 */
2482*b636d99dSDavid van Moolenbroek 
2483*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, " bos reply %s", tok2str(bos_req, "op#%d", opcode)));
2484*b636d99dSDavid van Moolenbroek 
2485*b636d99dSDavid van Moolenbroek 	bp += sizeof(struct rx_header);
2486*b636d99dSDavid van Moolenbroek 
2487*b636d99dSDavid van Moolenbroek 	/*
2488*b636d99dSDavid van Moolenbroek 	 * If it was a data packet, interpret the response.
2489*b636d99dSDavid van Moolenbroek 	 */
2490*b636d99dSDavid van Moolenbroek 
2491*b636d99dSDavid van Moolenbroek 	if (rxh->type == RX_PACKET_TYPE_DATA)
2492*b636d99dSDavid van Moolenbroek 		/* Well, no, not really.  Leave this for later */
2493*b636d99dSDavid van Moolenbroek 		;
2494*b636d99dSDavid van Moolenbroek 	else {
2495*b636d99dSDavid van Moolenbroek 		/*
2496*b636d99dSDavid van Moolenbroek 		 * Otherwise, just print out the return code
2497*b636d99dSDavid van Moolenbroek 		 */
2498*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, " errcode"));
2499*b636d99dSDavid van Moolenbroek 		INTOUT();
2500*b636d99dSDavid van Moolenbroek 	}
2501*b636d99dSDavid van Moolenbroek 
2502*b636d99dSDavid van Moolenbroek 	return;
2503*b636d99dSDavid van Moolenbroek 
2504*b636d99dSDavid van Moolenbroek trunc:
2505*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, " [|bos]"));
2506*b636d99dSDavid van Moolenbroek }
2507*b636d99dSDavid van Moolenbroek 
2508*b636d99dSDavid van Moolenbroek /*
2509*b636d99dSDavid van Moolenbroek  * Check to see if this is a Ubik opcode.
2510*b636d99dSDavid van Moolenbroek  */
2511*b636d99dSDavid van Moolenbroek 
2512*b636d99dSDavid van Moolenbroek static int
is_ubik(uint32_t opcode)2513*b636d99dSDavid van Moolenbroek is_ubik(uint32_t opcode)
2514*b636d99dSDavid van Moolenbroek {
2515*b636d99dSDavid van Moolenbroek 	if ((opcode >= VOTE_LOW && opcode <= VOTE_HIGH) ||
2516*b636d99dSDavid van Moolenbroek 	    (opcode >= DISK_LOW && opcode <= DISK_HIGH))
2517*b636d99dSDavid van Moolenbroek 		return(1);
2518*b636d99dSDavid van Moolenbroek 	else
2519*b636d99dSDavid van Moolenbroek 		return(0);
2520*b636d99dSDavid van Moolenbroek }
2521*b636d99dSDavid van Moolenbroek 
2522*b636d99dSDavid van Moolenbroek /*
2523*b636d99dSDavid van Moolenbroek  * Handle Ubik opcodes to any one of the replicated database services
2524*b636d99dSDavid van Moolenbroek  */
2525*b636d99dSDavid van Moolenbroek 
2526*b636d99dSDavid van Moolenbroek static void
ubik_print(netdissect_options * ndo,register const u_char * bp)2527*b636d99dSDavid van Moolenbroek ubik_print(netdissect_options *ndo,
2528*b636d99dSDavid van Moolenbroek            register const u_char *bp)
2529*b636d99dSDavid van Moolenbroek {
2530*b636d99dSDavid van Moolenbroek 	int ubik_op;
2531*b636d99dSDavid van Moolenbroek 	int32_t temp;
2532*b636d99dSDavid van Moolenbroek 
2533*b636d99dSDavid van Moolenbroek 	/*
2534*b636d99dSDavid van Moolenbroek 	 * Print out the afs call we're invoking.  The table used here was
2535*b636d99dSDavid van Moolenbroek 	 * gleaned from ubik/ubik_int.xg
2536*b636d99dSDavid van Moolenbroek 	 */
2537*b636d99dSDavid van Moolenbroek 
2538*b636d99dSDavid van Moolenbroek 	ubik_op = EXTRACT_32BITS(bp + sizeof(struct rx_header));
2539*b636d99dSDavid van Moolenbroek 
2540*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, " ubik call %s", tok2str(ubik_req, "op#%d", ubik_op)));
2541*b636d99dSDavid van Moolenbroek 
2542*b636d99dSDavid van Moolenbroek 	/*
2543*b636d99dSDavid van Moolenbroek 	 * Decode some of the arguments to the Ubik calls
2544*b636d99dSDavid van Moolenbroek 	 */
2545*b636d99dSDavid van Moolenbroek 
2546*b636d99dSDavid van Moolenbroek 	bp += sizeof(struct rx_header) + 4;
2547*b636d99dSDavid van Moolenbroek 
2548*b636d99dSDavid van Moolenbroek 	switch (ubik_op) {
2549*b636d99dSDavid van Moolenbroek 		case 10000:		/* Beacon */
2550*b636d99dSDavid van Moolenbroek 			ND_TCHECK2(bp[0], 4);
2551*b636d99dSDavid van Moolenbroek 			temp = EXTRACT_32BITS(bp);
2552*b636d99dSDavid van Moolenbroek 			bp += sizeof(int32_t);
2553*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " syncsite %s", temp ? "yes" : "no"));
2554*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " votestart"));
2555*b636d99dSDavid van Moolenbroek 			DATEOUT();
2556*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " dbversion"));
2557*b636d99dSDavid van Moolenbroek 			UBIK_VERSIONOUT();
2558*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " tid"));
2559*b636d99dSDavid van Moolenbroek 			UBIK_VERSIONOUT();
2560*b636d99dSDavid van Moolenbroek 			break;
2561*b636d99dSDavid van Moolenbroek 		case 10003:		/* Get sync site */
2562*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " site"));
2563*b636d99dSDavid van Moolenbroek 			UINTOUT();
2564*b636d99dSDavid van Moolenbroek 			break;
2565*b636d99dSDavid van Moolenbroek 		case 20000:		/* Begin */
2566*b636d99dSDavid van Moolenbroek 		case 20001:		/* Commit */
2567*b636d99dSDavid van Moolenbroek 		case 20007:		/* Abort */
2568*b636d99dSDavid van Moolenbroek 		case 20008:		/* Release locks */
2569*b636d99dSDavid van Moolenbroek 		case 20010:		/* Writev */
2570*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " tid"));
2571*b636d99dSDavid van Moolenbroek 			UBIK_VERSIONOUT();
2572*b636d99dSDavid van Moolenbroek 			break;
2573*b636d99dSDavid van Moolenbroek 		case 20002:		/* Lock */
2574*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " tid"));
2575*b636d99dSDavid van Moolenbroek 			UBIK_VERSIONOUT();
2576*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " file"));
2577*b636d99dSDavid van Moolenbroek 			INTOUT();
2578*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " pos"));
2579*b636d99dSDavid van Moolenbroek 			INTOUT();
2580*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " length"));
2581*b636d99dSDavid van Moolenbroek 			INTOUT();
2582*b636d99dSDavid van Moolenbroek 			temp = EXTRACT_32BITS(bp);
2583*b636d99dSDavid van Moolenbroek 			bp += sizeof(int32_t);
2584*b636d99dSDavid van Moolenbroek 			tok2str(ubik_lock_types, "type %d", temp);
2585*b636d99dSDavid van Moolenbroek 			break;
2586*b636d99dSDavid van Moolenbroek 		case 20003:		/* Write */
2587*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " tid"));
2588*b636d99dSDavid van Moolenbroek 			UBIK_VERSIONOUT();
2589*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " file"));
2590*b636d99dSDavid van Moolenbroek 			INTOUT();
2591*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " pos"));
2592*b636d99dSDavid van Moolenbroek 			INTOUT();
2593*b636d99dSDavid van Moolenbroek 			break;
2594*b636d99dSDavid van Moolenbroek 		case 20005:		/* Get file */
2595*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " file"));
2596*b636d99dSDavid van Moolenbroek 			INTOUT();
2597*b636d99dSDavid van Moolenbroek 			break;
2598*b636d99dSDavid van Moolenbroek 		case 20006:		/* Send file */
2599*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " file"));
2600*b636d99dSDavid van Moolenbroek 			INTOUT();
2601*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " length"));
2602*b636d99dSDavid van Moolenbroek 			INTOUT();
2603*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " dbversion"));
2604*b636d99dSDavid van Moolenbroek 			UBIK_VERSIONOUT();
2605*b636d99dSDavid van Moolenbroek 			break;
2606*b636d99dSDavid van Moolenbroek 		case 20009:		/* Truncate */
2607*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " tid"));
2608*b636d99dSDavid van Moolenbroek 			UBIK_VERSIONOUT();
2609*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " file"));
2610*b636d99dSDavid van Moolenbroek 			INTOUT();
2611*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " length"));
2612*b636d99dSDavid van Moolenbroek 			INTOUT();
2613*b636d99dSDavid van Moolenbroek 			break;
2614*b636d99dSDavid van Moolenbroek 		case 20012:		/* Set version */
2615*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " tid"));
2616*b636d99dSDavid van Moolenbroek 			UBIK_VERSIONOUT();
2617*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " oldversion"));
2618*b636d99dSDavid van Moolenbroek 			UBIK_VERSIONOUT();
2619*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " newversion"));
2620*b636d99dSDavid van Moolenbroek 			UBIK_VERSIONOUT();
2621*b636d99dSDavid van Moolenbroek 			break;
2622*b636d99dSDavid van Moolenbroek 		default:
2623*b636d99dSDavid van Moolenbroek 			;
2624*b636d99dSDavid van Moolenbroek 	}
2625*b636d99dSDavid van Moolenbroek 
2626*b636d99dSDavid van Moolenbroek 	return;
2627*b636d99dSDavid van Moolenbroek 
2628*b636d99dSDavid van Moolenbroek trunc:
2629*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, " [|ubik]"));
2630*b636d99dSDavid van Moolenbroek }
2631*b636d99dSDavid van Moolenbroek 
2632*b636d99dSDavid van Moolenbroek /*
2633*b636d99dSDavid van Moolenbroek  * Handle Ubik replies to any one of the replicated database services
2634*b636d99dSDavid van Moolenbroek  */
2635*b636d99dSDavid van Moolenbroek 
2636*b636d99dSDavid van Moolenbroek static void
ubik_reply_print(netdissect_options * ndo,register const u_char * bp,int length,int32_t opcode)2637*b636d99dSDavid van Moolenbroek ubik_reply_print(netdissect_options *ndo,
2638*b636d99dSDavid van Moolenbroek                  register const u_char *bp, int length, int32_t opcode)
2639*b636d99dSDavid van Moolenbroek {
2640*b636d99dSDavid van Moolenbroek 	struct rx_header *rxh;
2641*b636d99dSDavid van Moolenbroek 
2642*b636d99dSDavid van Moolenbroek 	if (length < (int)sizeof(struct rx_header))
2643*b636d99dSDavid van Moolenbroek 		return;
2644*b636d99dSDavid van Moolenbroek 
2645*b636d99dSDavid van Moolenbroek 	rxh = (struct rx_header *) bp;
2646*b636d99dSDavid van Moolenbroek 
2647*b636d99dSDavid van Moolenbroek 	/*
2648*b636d99dSDavid van Moolenbroek 	 * Print out the ubik call we're invoking.  This table was gleaned
2649*b636d99dSDavid van Moolenbroek 	 * from ubik/ubik_int.xg
2650*b636d99dSDavid van Moolenbroek 	 */
2651*b636d99dSDavid van Moolenbroek 
2652*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, " ubik reply %s", tok2str(ubik_req, "op#%d", opcode)));
2653*b636d99dSDavid van Moolenbroek 
2654*b636d99dSDavid van Moolenbroek 	bp += sizeof(struct rx_header);
2655*b636d99dSDavid van Moolenbroek 
2656*b636d99dSDavid van Moolenbroek 	/*
2657*b636d99dSDavid van Moolenbroek 	 * If it was a data packet, print out the arguments to the Ubik calls
2658*b636d99dSDavid van Moolenbroek 	 */
2659*b636d99dSDavid van Moolenbroek 
2660*b636d99dSDavid van Moolenbroek 	if (rxh->type == RX_PACKET_TYPE_DATA)
2661*b636d99dSDavid van Moolenbroek 		switch (opcode) {
2662*b636d99dSDavid van Moolenbroek 		case 10000:		/* Beacon */
2663*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " vote no"));
2664*b636d99dSDavid van Moolenbroek 			break;
2665*b636d99dSDavid van Moolenbroek 		case 20004:		/* Get version */
2666*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " dbversion"));
2667*b636d99dSDavid van Moolenbroek 			UBIK_VERSIONOUT();
2668*b636d99dSDavid van Moolenbroek 			break;
2669*b636d99dSDavid van Moolenbroek 		default:
2670*b636d99dSDavid van Moolenbroek 			;
2671*b636d99dSDavid van Moolenbroek 		}
2672*b636d99dSDavid van Moolenbroek 
2673*b636d99dSDavid van Moolenbroek 	/*
2674*b636d99dSDavid van Moolenbroek 	 * Otherwise, print out "yes" it it was a beacon packet (because
2675*b636d99dSDavid van Moolenbroek 	 * that's how yes votes are returned, go figure), otherwise
2676*b636d99dSDavid van Moolenbroek 	 * just print out the error code.
2677*b636d99dSDavid van Moolenbroek 	 */
2678*b636d99dSDavid van Moolenbroek 
2679*b636d99dSDavid van Moolenbroek 	else
2680*b636d99dSDavid van Moolenbroek 		switch (opcode) {
2681*b636d99dSDavid van Moolenbroek 		case 10000:		/* Beacon */
2682*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " vote yes until"));
2683*b636d99dSDavid van Moolenbroek 			DATEOUT();
2684*b636d99dSDavid van Moolenbroek 			break;
2685*b636d99dSDavid van Moolenbroek 		default:
2686*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " errcode"));
2687*b636d99dSDavid van Moolenbroek 			INTOUT();
2688*b636d99dSDavid van Moolenbroek 		}
2689*b636d99dSDavid van Moolenbroek 
2690*b636d99dSDavid van Moolenbroek 	return;
2691*b636d99dSDavid van Moolenbroek 
2692*b636d99dSDavid van Moolenbroek trunc:
2693*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, " [|ubik]"));
2694*b636d99dSDavid van Moolenbroek }
2695*b636d99dSDavid van Moolenbroek 
2696*b636d99dSDavid van Moolenbroek /*
2697*b636d99dSDavid van Moolenbroek  * Handle RX ACK packets.
2698*b636d99dSDavid van Moolenbroek  */
2699*b636d99dSDavid van Moolenbroek 
2700*b636d99dSDavid van Moolenbroek static void
rx_ack_print(netdissect_options * ndo,register const u_char * bp,int length)2701*b636d99dSDavid van Moolenbroek rx_ack_print(netdissect_options *ndo,
2702*b636d99dSDavid van Moolenbroek              register const u_char *bp, int length)
2703*b636d99dSDavid van Moolenbroek {
2704*b636d99dSDavid van Moolenbroek 	struct rx_ackPacket *rxa;
2705*b636d99dSDavid van Moolenbroek 	int i, start, last;
2706*b636d99dSDavid van Moolenbroek 	uint32_t firstPacket;
2707*b636d99dSDavid van Moolenbroek 
2708*b636d99dSDavid van Moolenbroek 	if (length < (int)sizeof(struct rx_header))
2709*b636d99dSDavid van Moolenbroek 		return;
2710*b636d99dSDavid van Moolenbroek 
2711*b636d99dSDavid van Moolenbroek 	bp += sizeof(struct rx_header);
2712*b636d99dSDavid van Moolenbroek 
2713*b636d99dSDavid van Moolenbroek 	/*
2714*b636d99dSDavid van Moolenbroek 	 * This may seem a little odd .... the rx_ackPacket structure
2715*b636d99dSDavid van Moolenbroek 	 * contains an array of individual packet acknowledgements
2716*b636d99dSDavid van Moolenbroek 	 * (used for selective ack/nack), but since it's variable in size,
2717*b636d99dSDavid van Moolenbroek 	 * we don't want to truncate based on the size of the whole
2718*b636d99dSDavid van Moolenbroek 	 * rx_ackPacket structure.
2719*b636d99dSDavid van Moolenbroek 	 */
2720*b636d99dSDavid van Moolenbroek 
2721*b636d99dSDavid van Moolenbroek 	ND_TCHECK2(bp[0], sizeof(struct rx_ackPacket) - RX_MAXACKS);
2722*b636d99dSDavid van Moolenbroek 
2723*b636d99dSDavid van Moolenbroek 	rxa = (struct rx_ackPacket *) bp;
2724*b636d99dSDavid van Moolenbroek 	bp += (sizeof(struct rx_ackPacket) - RX_MAXACKS);
2725*b636d99dSDavid van Moolenbroek 
2726*b636d99dSDavid van Moolenbroek 	/*
2727*b636d99dSDavid van Moolenbroek 	 * Print out a few useful things from the ack packet structure
2728*b636d99dSDavid van Moolenbroek 	 */
2729*b636d99dSDavid van Moolenbroek 
2730*b636d99dSDavid van Moolenbroek 	if (ndo->ndo_vflag > 2)
2731*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, " bufspace %d maxskew %d",
2732*b636d99dSDavid van Moolenbroek 		       (int) EXTRACT_16BITS(&rxa->bufferSpace),
2733*b636d99dSDavid van Moolenbroek 		       (int) EXTRACT_16BITS(&rxa->maxSkew)));
2734*b636d99dSDavid van Moolenbroek 
2735*b636d99dSDavid van Moolenbroek 	firstPacket = EXTRACT_32BITS(&rxa->firstPacket);
2736*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, " first %d serial %d reason %s",
2737*b636d99dSDavid van Moolenbroek 	       firstPacket, EXTRACT_32BITS(&rxa->serial),
2738*b636d99dSDavid van Moolenbroek 	       tok2str(rx_ack_reasons, "#%d", (int) rxa->reason)));
2739*b636d99dSDavid van Moolenbroek 
2740*b636d99dSDavid van Moolenbroek 	/*
2741*b636d99dSDavid van Moolenbroek 	 * Okay, now we print out the ack array.  The way _this_ works
2742*b636d99dSDavid van Moolenbroek 	 * is that we start at "first", and step through the ack array.
2743*b636d99dSDavid van Moolenbroek 	 * If we have a contiguous range of acks/nacks, try to
2744*b636d99dSDavid van Moolenbroek 	 * collapse them into a range.
2745*b636d99dSDavid van Moolenbroek 	 *
2746*b636d99dSDavid van Moolenbroek 	 * If you're really clever, you might have noticed that this
2747*b636d99dSDavid van Moolenbroek 	 * doesn't seem quite correct.  Specifically, due to structure
2748*b636d99dSDavid van Moolenbroek 	 * padding, sizeof(struct rx_ackPacket) - RX_MAXACKS won't actually
2749*b636d99dSDavid van Moolenbroek 	 * yield the start of the ack array (because RX_MAXACKS is 255
2750*b636d99dSDavid van Moolenbroek 	 * and the structure will likely get padded to a 2 or 4 byte
2751*b636d99dSDavid van Moolenbroek 	 * boundary).  However, this is the way it's implemented inside
2752*b636d99dSDavid van Moolenbroek 	 * of AFS - the start of the extra fields are at
2753*b636d99dSDavid van Moolenbroek 	 * sizeof(struct rx_ackPacket) - RX_MAXACKS + nAcks, which _isn't_
2754*b636d99dSDavid van Moolenbroek 	 * the exact start of the ack array.  Sigh.  That's why we aren't
2755*b636d99dSDavid van Moolenbroek 	 * using bp, but instead use rxa->acks[].  But nAcks gets added
2756*b636d99dSDavid van Moolenbroek 	 * to bp after this, so bp ends up at the right spot.  Go figure.
2757*b636d99dSDavid van Moolenbroek 	 */
2758*b636d99dSDavid van Moolenbroek 
2759*b636d99dSDavid van Moolenbroek 	if (rxa->nAcks != 0) {
2760*b636d99dSDavid van Moolenbroek 
2761*b636d99dSDavid van Moolenbroek 		ND_TCHECK2(bp[0], rxa->nAcks);
2762*b636d99dSDavid van Moolenbroek 
2763*b636d99dSDavid van Moolenbroek 		/*
2764*b636d99dSDavid van Moolenbroek 		 * Sigh, this is gross, but it seems to work to collapse
2765*b636d99dSDavid van Moolenbroek 		 * ranges correctly.
2766*b636d99dSDavid van Moolenbroek 		 */
2767*b636d99dSDavid van Moolenbroek 
2768*b636d99dSDavid van Moolenbroek 		for (i = 0, start = last = -2; i < rxa->nAcks; i++)
2769*b636d99dSDavid van Moolenbroek 			if (rxa->acks[i] == RX_ACK_TYPE_ACK) {
2770*b636d99dSDavid van Moolenbroek 
2771*b636d99dSDavid van Moolenbroek 				/*
2772*b636d99dSDavid van Moolenbroek 				 * I figured this deserved _some_ explanation.
2773*b636d99dSDavid van Moolenbroek 				 * First, print "acked" and the packet seq
2774*b636d99dSDavid van Moolenbroek 				 * number if this is the first time we've
2775*b636d99dSDavid van Moolenbroek 				 * seen an acked packet.
2776*b636d99dSDavid van Moolenbroek 				 */
2777*b636d99dSDavid van Moolenbroek 
2778*b636d99dSDavid van Moolenbroek 				if (last == -2) {
2779*b636d99dSDavid van Moolenbroek 					ND_PRINT((ndo, " acked %d", firstPacket + i));
2780*b636d99dSDavid van Moolenbroek 					start = i;
2781*b636d99dSDavid van Moolenbroek 				}
2782*b636d99dSDavid van Moolenbroek 
2783*b636d99dSDavid van Moolenbroek 				/*
2784*b636d99dSDavid van Moolenbroek 				 * Otherwise, if there is a skip in
2785*b636d99dSDavid van Moolenbroek 				 * the range (such as an nacked packet in
2786*b636d99dSDavid van Moolenbroek 				 * the middle of some acked packets),
2787*b636d99dSDavid van Moolenbroek 				 * then print the current packet number
2788*b636d99dSDavid van Moolenbroek 				 * seperated from the last number by
2789*b636d99dSDavid van Moolenbroek 				 * a comma.
2790*b636d99dSDavid van Moolenbroek 				 */
2791*b636d99dSDavid van Moolenbroek 
2792*b636d99dSDavid van Moolenbroek 				else if (last != i - 1) {
2793*b636d99dSDavid van Moolenbroek 					ND_PRINT((ndo, ",%d", firstPacket + i));
2794*b636d99dSDavid van Moolenbroek 					start = i;
2795*b636d99dSDavid van Moolenbroek 				}
2796*b636d99dSDavid van Moolenbroek 
2797*b636d99dSDavid van Moolenbroek 				/*
2798*b636d99dSDavid van Moolenbroek 				 * We always set last to the value of
2799*b636d99dSDavid van Moolenbroek 				 * the last ack we saw.  Conversely, start
2800*b636d99dSDavid van Moolenbroek 				 * is set to the value of the first ack
2801*b636d99dSDavid van Moolenbroek 				 * we saw in a range.
2802*b636d99dSDavid van Moolenbroek 				 */
2803*b636d99dSDavid van Moolenbroek 
2804*b636d99dSDavid van Moolenbroek 				last = i;
2805*b636d99dSDavid van Moolenbroek 
2806*b636d99dSDavid van Moolenbroek 				/*
2807*b636d99dSDavid van Moolenbroek 				 * Okay, this bit a code gets executed when
2808*b636d99dSDavid van Moolenbroek 				 * we hit a nack ... in _this_ case we
2809*b636d99dSDavid van Moolenbroek 				 * want to print out the range of packets
2810*b636d99dSDavid van Moolenbroek 				 * that were acked, so we need to print
2811*b636d99dSDavid van Moolenbroek 				 * the _previous_ packet number seperated
2812*b636d99dSDavid van Moolenbroek 				 * from the first by a dash (-).  Since we
2813*b636d99dSDavid van Moolenbroek 				 * already printed the first packet above,
2814*b636d99dSDavid van Moolenbroek 				 * just print the final packet.  Don't
2815*b636d99dSDavid van Moolenbroek 				 * do this if there will be a single-length
2816*b636d99dSDavid van Moolenbroek 				 * range.
2817*b636d99dSDavid van Moolenbroek 				 */
2818*b636d99dSDavid van Moolenbroek 			} else if (last == i - 1 && start != last)
2819*b636d99dSDavid van Moolenbroek 				ND_PRINT((ndo, "-%d", firstPacket + i - 1));
2820*b636d99dSDavid van Moolenbroek 
2821*b636d99dSDavid van Moolenbroek 		/*
2822*b636d99dSDavid van Moolenbroek 		 * So, what's going on here?  We ran off the end of the
2823*b636d99dSDavid van Moolenbroek 		 * ack list, and if we got a range we need to finish it up.
2824*b636d99dSDavid van Moolenbroek 		 * So we need to determine if the last packet in the list
2825*b636d99dSDavid van Moolenbroek 		 * was an ack (if so, then last will be set to it) and
2826*b636d99dSDavid van Moolenbroek 		 * we need to see if the last range didn't start with the
2827*b636d99dSDavid van Moolenbroek 		 * last packet (because if it _did_, then that would mean
2828*b636d99dSDavid van Moolenbroek 		 * that the packet number has already been printed and
2829*b636d99dSDavid van Moolenbroek 		 * we don't need to print it again).
2830*b636d99dSDavid van Moolenbroek 		 */
2831*b636d99dSDavid van Moolenbroek 
2832*b636d99dSDavid van Moolenbroek 		if (last == i - 1 && start != last)
2833*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, "-%d", firstPacket + i - 1));
2834*b636d99dSDavid van Moolenbroek 
2835*b636d99dSDavid van Moolenbroek 		/*
2836*b636d99dSDavid van Moolenbroek 		 * Same as above, just without comments
2837*b636d99dSDavid van Moolenbroek 		 */
2838*b636d99dSDavid van Moolenbroek 
2839*b636d99dSDavid van Moolenbroek 		for (i = 0, start = last = -2; i < rxa->nAcks; i++)
2840*b636d99dSDavid van Moolenbroek 			if (rxa->acks[i] == RX_ACK_TYPE_NACK) {
2841*b636d99dSDavid van Moolenbroek 				if (last == -2) {
2842*b636d99dSDavid van Moolenbroek 					ND_PRINT((ndo, " nacked %d", firstPacket + i));
2843*b636d99dSDavid van Moolenbroek 					start = i;
2844*b636d99dSDavid van Moolenbroek 				} else if (last != i - 1) {
2845*b636d99dSDavid van Moolenbroek 					ND_PRINT((ndo, ",%d", firstPacket + i));
2846*b636d99dSDavid van Moolenbroek 					start = i;
2847*b636d99dSDavid van Moolenbroek 				}
2848*b636d99dSDavid van Moolenbroek 				last = i;
2849*b636d99dSDavid van Moolenbroek 			} else if (last == i - 1 && start != last)
2850*b636d99dSDavid van Moolenbroek 				ND_PRINT((ndo, "-%d", firstPacket + i - 1));
2851*b636d99dSDavid van Moolenbroek 
2852*b636d99dSDavid van Moolenbroek 		if (last == i - 1 && start != last)
2853*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, "-%d", firstPacket + i - 1));
2854*b636d99dSDavid van Moolenbroek 
2855*b636d99dSDavid van Moolenbroek 		bp += rxa->nAcks;
2856*b636d99dSDavid van Moolenbroek 	}
2857*b636d99dSDavid van Moolenbroek 
2858*b636d99dSDavid van Moolenbroek 
2859*b636d99dSDavid van Moolenbroek 	/*
2860*b636d99dSDavid van Moolenbroek 	 * These are optional fields; depending on your version of AFS,
2861*b636d99dSDavid van Moolenbroek 	 * you may or may not see them
2862*b636d99dSDavid van Moolenbroek 	 */
2863*b636d99dSDavid van Moolenbroek 
2864*b636d99dSDavid van Moolenbroek #define TRUNCRET(n)	if (ndo->ndo_snapend - bp + 1 <= n) return;
2865*b636d99dSDavid van Moolenbroek 
2866*b636d99dSDavid van Moolenbroek 	if (ndo->ndo_vflag > 1) {
2867*b636d99dSDavid van Moolenbroek 		TRUNCRET(4);
2868*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, " ifmtu"));
2869*b636d99dSDavid van Moolenbroek 		INTOUT();
2870*b636d99dSDavid van Moolenbroek 
2871*b636d99dSDavid van Moolenbroek 		TRUNCRET(4);
2872*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, " maxmtu"));
2873*b636d99dSDavid van Moolenbroek 		INTOUT();
2874*b636d99dSDavid van Moolenbroek 
2875*b636d99dSDavid van Moolenbroek 		TRUNCRET(4);
2876*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, " rwind"));
2877*b636d99dSDavid van Moolenbroek 		INTOUT();
2878*b636d99dSDavid van Moolenbroek 
2879*b636d99dSDavid van Moolenbroek 		TRUNCRET(4);
2880*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, " maxpackets"));
2881*b636d99dSDavid van Moolenbroek 		INTOUT();
2882*b636d99dSDavid van Moolenbroek 	}
2883*b636d99dSDavid van Moolenbroek 
2884*b636d99dSDavid van Moolenbroek 	return;
2885*b636d99dSDavid van Moolenbroek 
2886*b636d99dSDavid van Moolenbroek trunc:
2887*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, " [|ack]"));
2888*b636d99dSDavid van Moolenbroek }
2889*b636d99dSDavid van Moolenbroek #undef TRUNCRET
2890