tcpdump  4.99.1
About: tcpdump is a tool for network monitoring and data acquisition.
  Fossies Dox: tcpdump-4.99.1.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

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