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