156893Sfenner/* 298524Sfenner * Copyright: (c) 2000 United States Government as represented by the 398524Sfenner * Secretary of the Navy. All rights reserved. 498524Sfenner * 598524Sfenner * Redistribution and use in source and binary forms, with or without 698524Sfenner * modification, are permitted provided that the following conditions 798524Sfenner * are met: 8127668Sbms * 998524Sfenner * 1. Redistributions of source code must retain the above copyright 1098524Sfenner * notice, this list of conditions and the following disclaimer. 1198524Sfenner * 2. Redistributions in binary form must reproduce the above copyright 1298524Sfenner * notice, this list of conditions and the following disclaimer in 1398524Sfenner * the documentation and/or other materials provided with the 1498524Sfenner * distribution. 1598524Sfenner * 3. The names of the authors may not be used to endorse or promote 1698524Sfenner * products derived from this software without specific prior 1798524Sfenner * written permission. 18127668Sbms * 1998524Sfenner * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 2098524Sfenner * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 2198524Sfenner * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 2298524Sfenner */ 2398524Sfenner/* 2456893Sfenner * This code unmangles RX packets. RX is the mutant form of RPC that AFS 2556893Sfenner * uses to communicate between clients and servers. 2656893Sfenner * 2756893Sfenner * In this code, I mainly concern myself with decoding the AFS calls, not 2856893Sfenner * with the guts of RX, per se. 2956893Sfenner * 3056893Sfenner * Bah. If I never look at rx_packet.h again, it will be too soon. 3156893Sfenner * 3256893Sfenner * Ken Hornstein <kenh@cmf.nrl.navy.mil> 3356893Sfenner */ 3456893Sfenner 3556893Sfenner#ifndef lint 36127668Sbmsstatic const char rcsid[] _U_ = 37214478Srpaulo "@(#) $Header: /tcpdump/master/tcpdump/print-rx.c,v 1.42 2008-07-01 07:44:50 guy Exp $"; 3856893Sfenner#endif 3956893Sfenner 4056893Sfenner#ifdef HAVE_CONFIG_H 4156893Sfenner#include "config.h" 4256893Sfenner#endif 4356893Sfenner 4456893Sfenner#include <stdio.h> 4575115Sfenner#include <stdlib.h> 4656893Sfenner#include <string.h> 47127668Sbms#include <tcpdump-stdinc.h> 4856893Sfenner 4956893Sfenner#include "interface.h" 5056893Sfenner#include "addrtoname.h" 5175115Sfenner#include "extract.h" 5256893Sfenner 5356893Sfenner#include "rx.h" 5456893Sfenner 5575115Sfenner#include "ip.h" 5675115Sfenner 5756893Sfennerstatic struct tok rx_types[] = { 5856893Sfenner { RX_PACKET_TYPE_DATA, "data" }, 5956893Sfenner { RX_PACKET_TYPE_ACK, "ack" }, 6056893Sfenner { RX_PACKET_TYPE_BUSY, "busy" }, 6156893Sfenner { RX_PACKET_TYPE_ABORT, "abort" }, 6256893Sfenner { RX_PACKET_TYPE_ACKALL, "ackall" }, 6356893Sfenner { RX_PACKET_TYPE_CHALLENGE, "challenge" }, 6456893Sfenner { RX_PACKET_TYPE_RESPONSE, "response" }, 6556893Sfenner { RX_PACKET_TYPE_DEBUG, "debug" }, 6656893Sfenner { RX_PACKET_TYPE_PARAMS, "params" }, 6756893Sfenner { RX_PACKET_TYPE_VERSION, "version" }, 6856893Sfenner { 0, NULL }, 6956893Sfenner}; 7056893Sfenner 7198524Sfennerstatic struct double_tok { 7298524Sfenner int flag; /* Rx flag */ 7398524Sfenner int packetType; /* Packet type */ 74127668Sbms const char *s; /* Flag string */ 7598524Sfenner} rx_flags[] = { 7698524Sfenner { RX_CLIENT_INITIATED, 0, "client-init" }, 7798524Sfenner { RX_REQUEST_ACK, 0, "req-ack" }, 7898524Sfenner { RX_LAST_PACKET, 0, "last-pckt" }, 7998524Sfenner { RX_MORE_PACKETS, 0, "more-pckts" }, 8098524Sfenner { RX_FREE_PACKET, 0, "free-pckt" }, 8198524Sfenner { RX_SLOW_START_OK, RX_PACKET_TYPE_ACK, "slow-start" }, 8298524Sfenner { RX_JUMBO_PACKET, RX_PACKET_TYPE_DATA, "jumbogram" } 8356893Sfenner}; 8456893Sfenner 8556893Sfennerstatic struct tok fs_req[] = { 8656893Sfenner { 130, "fetch-data" }, 8756893Sfenner { 131, "fetch-acl" }, 8856893Sfenner { 132, "fetch-status" }, 8956893Sfenner { 133, "store-data" }, 9056893Sfenner { 134, "store-acl" }, 9156893Sfenner { 135, "store-status" }, 9256893Sfenner { 136, "remove-file" }, 9356893Sfenner { 137, "create-file" }, 9456893Sfenner { 138, "rename" }, 9556893Sfenner { 139, "symlink" }, 9656893Sfenner { 140, "link" }, 9756893Sfenner { 141, "makedir" }, 9856893Sfenner { 142, "rmdir" }, 9956893Sfenner { 143, "oldsetlock" }, 10056893Sfenner { 144, "oldextlock" }, 10156893Sfenner { 145, "oldrellock" }, 10256893Sfenner { 146, "get-stats" }, 10356893Sfenner { 147, "give-cbs" }, 10456893Sfenner { 148, "get-vlinfo" }, 10556893Sfenner { 149, "get-vlstats" }, 10656893Sfenner { 150, "set-vlstats" }, 10756893Sfenner { 151, "get-rootvl" }, 10856893Sfenner { 152, "check-token" }, 10956893Sfenner { 153, "get-time" }, 11056893Sfenner { 154, "nget-vlinfo" }, 11156893Sfenner { 155, "bulk-stat" }, 11256893Sfenner { 156, "setlock" }, 11356893Sfenner { 157, "extlock" }, 11456893Sfenner { 158, "rellock" }, 11556893Sfenner { 159, "xstat-ver" }, 11656893Sfenner { 160, "get-xstat" }, 11756893Sfenner { 161, "dfs-lookup" }, 11856893Sfenner { 162, "dfs-flushcps" }, 11956893Sfenner { 163, "dfs-symlink" }, 12098524Sfenner { 220, "residency" }, 121190207Srpaulo { 65536, "inline-bulk-status" }, 122190207Srpaulo { 65537, "fetch-data-64" }, 123190207Srpaulo { 65538, "store-data-64" }, 124190207Srpaulo { 65539, "give-up-all-cbs" }, 125190207Srpaulo { 65540, "get-caps" }, 126190207Srpaulo { 65541, "cb-rx-conn-addr" }, 12756893Sfenner { 0, NULL }, 12856893Sfenner}; 12956893Sfenner 13056893Sfennerstatic struct tok cb_req[] = { 13156893Sfenner { 204, "callback" }, 13256893Sfenner { 205, "initcb" }, 13356893Sfenner { 206, "probe" }, 13456893Sfenner { 207, "getlock" }, 13556893Sfenner { 208, "getce" }, 13656893Sfenner { 209, "xstatver" }, 13756893Sfenner { 210, "getxstat" }, 13856893Sfenner { 211, "initcb2" }, 13956893Sfenner { 212, "whoareyou" }, 14056893Sfenner { 213, "initcb3" }, 14156893Sfenner { 214, "probeuuid" }, 14298524Sfenner { 215, "getsrvprefs" }, 14398524Sfenner { 216, "getcellservdb" }, 14498524Sfenner { 217, "getlocalcell" }, 14598524Sfenner { 218, "getcacheconf" }, 146190207Srpaulo { 65536, "getce64" }, 147190207Srpaulo { 65537, "getcellbynum" }, 148190207Srpaulo { 65538, "tellmeaboutyourself" }, 14956893Sfenner { 0, NULL }, 15056893Sfenner}; 15156893Sfenner 15256893Sfennerstatic struct tok pt_req[] = { 15356893Sfenner { 500, "new-user" }, 15456893Sfenner { 501, "where-is-it" }, 15556893Sfenner { 502, "dump-entry" }, 15656893Sfenner { 503, "add-to-group" }, 15756893Sfenner { 504, "name-to-id" }, 15856893Sfenner { 505, "id-to-name" }, 15956893Sfenner { 506, "delete" }, 16056893Sfenner { 507, "remove-from-group" }, 16156893Sfenner { 508, "get-cps" }, 16256893Sfenner { 509, "new-entry" }, 16356893Sfenner { 510, "list-max" }, 16456893Sfenner { 511, "set-max" }, 16556893Sfenner { 512, "list-entry" }, 16656893Sfenner { 513, "change-entry" }, 16756893Sfenner { 514, "list-elements" }, 16856893Sfenner { 515, "same-mbr-of" }, 16956893Sfenner { 516, "set-fld-sentry" }, 17056893Sfenner { 517, "list-owned" }, 17156893Sfenner { 518, "get-cps2" }, 17256893Sfenner { 519, "get-host-cps" }, 17356893Sfenner { 520, "update-entry" }, 17498524Sfenner { 521, "list-entries" }, 175190207Srpaulo { 530, "list-super-groups" }, 17656893Sfenner { 0, NULL }, 17756893Sfenner}; 17856893Sfenner 17956893Sfennerstatic struct tok vldb_req[] = { 18056893Sfenner { 501, "create-entry" }, 18156893Sfenner { 502, "delete-entry" }, 18256893Sfenner { 503, "get-entry-by-id" }, 18356893Sfenner { 504, "get-entry-by-name" }, 18456893Sfenner { 505, "get-new-volume-id" }, 18556893Sfenner { 506, "replace-entry" }, 18656893Sfenner { 507, "update-entry" }, 18756893Sfenner { 508, "setlock" }, 18856893Sfenner { 509, "releaselock" }, 18956893Sfenner { 510, "list-entry" }, 19056893Sfenner { 511, "list-attrib" }, 19156893Sfenner { 512, "linked-list" }, 19256893Sfenner { 513, "get-stats" }, 19356893Sfenner { 514, "probe" }, 19456893Sfenner { 515, "get-addrs" }, 19556893Sfenner { 516, "change-addr" }, 19656893Sfenner { 517, "create-entry-n" }, 19756893Sfenner { 518, "get-entry-by-id-n" }, 19856893Sfenner { 519, "get-entry-by-name-n" }, 19956893Sfenner { 520, "replace-entry-n" }, 20056893Sfenner { 521, "list-entry-n" }, 20156893Sfenner { 522, "list-attrib-n" }, 20256893Sfenner { 523, "linked-list-n" }, 20356893Sfenner { 524, "update-entry-by-name" }, 20456893Sfenner { 525, "create-entry-u" }, 20556893Sfenner { 526, "get-entry-by-id-u" }, 20656893Sfenner { 527, "get-entry-by-name-u" }, 20756893Sfenner { 528, "replace-entry-u" }, 20856893Sfenner { 529, "list-entry-u" }, 20956893Sfenner { 530, "list-attrib-u" }, 21056893Sfenner { 531, "linked-list-u" }, 21156893Sfenner { 532, "regaddr" }, 21256893Sfenner { 533, "get-addrs-u" }, 21398524Sfenner { 534, "list-attrib-n2" }, 21456893Sfenner { 0, NULL }, 21556893Sfenner}; 21656893Sfenner 21756893Sfennerstatic struct tok kauth_req[] = { 21856893Sfenner { 1, "auth-old" }, 21956893Sfenner { 21, "authenticate" }, 22056893Sfenner { 22, "authenticate-v2" }, 22156893Sfenner { 2, "change-pw" }, 22256893Sfenner { 3, "get-ticket-old" }, 22356893Sfenner { 23, "get-ticket" }, 22456893Sfenner { 4, "set-pw" }, 22556893Sfenner { 5, "set-fields" }, 22656893Sfenner { 6, "create-user" }, 22756893Sfenner { 7, "delete-user" }, 22856893Sfenner { 8, "get-entry" }, 22956893Sfenner { 9, "list-entry" }, 23056893Sfenner { 10, "get-stats" }, 23156893Sfenner { 11, "debug" }, 23256893Sfenner { 12, "get-pw" }, 23356893Sfenner { 13, "get-random-key" }, 23456893Sfenner { 14, "unlock" }, 23556893Sfenner { 15, "lock-status" }, 23656893Sfenner { 0, NULL }, 23756893Sfenner}; 23856893Sfenner 23956893Sfennerstatic struct tok vol_req[] = { 24056893Sfenner { 100, "create-volume" }, 24156893Sfenner { 101, "delete-volume" }, 24256893Sfenner { 102, "restore" }, 24356893Sfenner { 103, "forward" }, 24456893Sfenner { 104, "end-trans" }, 24556893Sfenner { 105, "clone" }, 24656893Sfenner { 106, "set-flags" }, 24756893Sfenner { 107, "get-flags" }, 24856893Sfenner { 108, "trans-create" }, 24956893Sfenner { 109, "dump" }, 25056893Sfenner { 110, "get-nth-volume" }, 25156893Sfenner { 111, "set-forwarding" }, 25256893Sfenner { 112, "get-name" }, 25356893Sfenner { 113, "get-status" }, 25456893Sfenner { 114, "sig-restore" }, 25556893Sfenner { 115, "list-partitions" }, 25656893Sfenner { 116, "list-volumes" }, 25756893Sfenner { 117, "set-id-types" }, 25856893Sfenner { 118, "monitor" }, 25956893Sfenner { 119, "partition-info" }, 26056893Sfenner { 120, "reclone" }, 26156893Sfenner { 121, "list-one-volume" }, 26256893Sfenner { 122, "nuke" }, 26356893Sfenner { 123, "set-date" }, 26456893Sfenner { 124, "x-list-volumes" }, 26556893Sfenner { 125, "x-list-one-volume" }, 26656893Sfenner { 126, "set-info" }, 26756893Sfenner { 127, "x-list-partitions" }, 26856893Sfenner { 128, "forward-multiple" }, 269190207Srpaulo { 65536, "convert-ro" }, 270190207Srpaulo { 65537, "get-size" }, 271190207Srpaulo { 65538, "dump-v2" }, 27256893Sfenner { 0, NULL }, 27356893Sfenner}; 27456893Sfenner 27556893Sfennerstatic struct tok bos_req[] = { 27656893Sfenner { 80, "create-bnode" }, 27756893Sfenner { 81, "delete-bnode" }, 27856893Sfenner { 82, "set-status" }, 27956893Sfenner { 83, "get-status" }, 28056893Sfenner { 84, "enumerate-instance" }, 28156893Sfenner { 85, "get-instance-info" }, 28256893Sfenner { 86, "get-instance-parm" }, 28356893Sfenner { 87, "add-superuser" }, 28456893Sfenner { 88, "delete-superuser" }, 28556893Sfenner { 89, "list-superusers" }, 28656893Sfenner { 90, "list-keys" }, 28756893Sfenner { 91, "add-key" }, 28856893Sfenner { 92, "delete-key" }, 28956893Sfenner { 93, "set-cell-name" }, 29056893Sfenner { 94, "get-cell-name" }, 29156893Sfenner { 95, "get-cell-host" }, 29256893Sfenner { 96, "add-cell-host" }, 29356893Sfenner { 97, "delete-cell-host" }, 29456893Sfenner { 98, "set-t-status" }, 29556893Sfenner { 99, "shutdown-all" }, 29656893Sfenner { 100, "restart-all" }, 29756893Sfenner { 101, "startup-all" }, 29856893Sfenner { 102, "set-noauth-flag" }, 29956893Sfenner { 103, "re-bozo" }, 30056893Sfenner { 104, "restart" }, 30156893Sfenner { 105, "start-bozo-install" }, 30256893Sfenner { 106, "uninstall" }, 30356893Sfenner { 107, "get-dates" }, 30456893Sfenner { 108, "exec" }, 30556893Sfenner { 109, "prune" }, 30656893Sfenner { 110, "set-restart-time" }, 30756893Sfenner { 111, "get-restart-time" }, 30856893Sfenner { 112, "start-bozo-log" }, 30956893Sfenner { 113, "wait-all" }, 31056893Sfenner { 114, "get-instance-strings" }, 31198524Sfenner { 115, "get-restricted" }, 31298524Sfenner { 116, "set-restricted" }, 31356893Sfenner { 0, NULL }, 31456893Sfenner}; 31556893Sfenner 31656893Sfennerstatic struct tok ubik_req[] = { 31756893Sfenner { 10000, "vote-beacon" }, 31856893Sfenner { 10001, "vote-debug-old" }, 31956893Sfenner { 10002, "vote-sdebug-old" }, 32056893Sfenner { 10003, "vote-getsyncsite" }, 32156893Sfenner { 10004, "vote-debug" }, 32256893Sfenner { 10005, "vote-sdebug" }, 323190207Srpaulo { 10006, "vote-xdebug" }, 324190207Srpaulo { 10007, "vote-xsdebug" }, 32556893Sfenner { 20000, "disk-begin" }, 32656893Sfenner { 20001, "disk-commit" }, 32756893Sfenner { 20002, "disk-lock" }, 32856893Sfenner { 20003, "disk-write" }, 32956893Sfenner { 20004, "disk-getversion" }, 33056893Sfenner { 20005, "disk-getfile" }, 33156893Sfenner { 20006, "disk-sendfile" }, 33256893Sfenner { 20007, "disk-abort" }, 33356893Sfenner { 20008, "disk-releaselocks" }, 33456893Sfenner { 20009, "disk-truncate" }, 33556893Sfenner { 20010, "disk-probe" }, 33656893Sfenner { 20011, "disk-writev" }, 33756893Sfenner { 20012, "disk-interfaceaddr" }, 33856893Sfenner { 20013, "disk-setversion" }, 33956893Sfenner { 0, NULL }, 34056893Sfenner}; 34156893Sfenner 34256893Sfenner#define VOTE_LOW 10000 343190207Srpaulo#define VOTE_HIGH 10007 34456893Sfenner#define DISK_LOW 20000 34556893Sfenner#define DISK_HIGH 20013 34656893Sfenner 34756893Sfennerstatic struct tok cb_types[] = { 34856893Sfenner { 1, "exclusive" }, 34956893Sfenner { 2, "shared" }, 35056893Sfenner { 3, "dropped" }, 35156893Sfenner { 0, NULL }, 35256893Sfenner}; 35356893Sfenner 35456893Sfennerstatic struct tok ubik_lock_types[] = { 35556893Sfenner { 1, "read" }, 35656893Sfenner { 2, "write" }, 35756893Sfenner { 3, "wait" }, 35856893Sfenner { 0, NULL }, 35956893Sfenner}; 36056893Sfenner 361127668Sbmsstatic const char *voltype[] = { "read-write", "read-only", "backup" }; 36256893Sfenner 36375115Sfennerstatic struct tok afs_fs_errors[] = { 36475115Sfenner { 101, "salvage volume" }, 36575115Sfenner { 102, "no such vnode" }, 36675115Sfenner { 103, "no such volume" }, 36775115Sfenner { 104, "volume exist" }, 36875115Sfenner { 105, "no service" }, 36975115Sfenner { 106, "volume offline" }, 37075115Sfenner { 107, "voline online" }, 37175115Sfenner { 108, "diskfull" }, 37275115Sfenner { 109, "diskquota exceeded" }, 37375115Sfenner { 110, "volume busy" }, 37475115Sfenner { 111, "volume moved" }, 37575115Sfenner { 112, "AFS IO error" }, 37675115Sfenner { -100, "restarting fileserver" }, 37775115Sfenner { 0, NULL } 37875115Sfenner}; 37975115Sfenner 38056893Sfenner/* 38175115Sfenner * Reasons for acknowledging a packet 38275115Sfenner */ 38375115Sfenner 38475115Sfennerstatic struct tok rx_ack_reasons[] = { 38575115Sfenner { 1, "ack requested" }, 38675115Sfenner { 2, "duplicate packet" }, 38775115Sfenner { 3, "out of sequence" }, 38875115Sfenner { 4, "exceeds window" }, 38975115Sfenner { 5, "no buffer space" }, 39075115Sfenner { 6, "ping" }, 39175115Sfenner { 7, "ping response" }, 39275115Sfenner { 8, "delay" }, 393127668Sbms { 9, "idle" }, 39475115Sfenner { 0, NULL }, 39575115Sfenner}; 39675115Sfenner 39775115Sfenner/* 39856893Sfenner * Cache entries we keep around so we can figure out the RX opcode 39956893Sfenner * numbers for replies. This allows us to make sense of RX reply packets. 40056893Sfenner */ 40156893Sfenner 40256893Sfennerstruct rx_cache_entry { 40356893Sfenner u_int32_t callnum; /* Call number (net order) */ 40456893Sfenner struct in_addr client; /* client IP address (net order) */ 40556893Sfenner struct in_addr server; /* server IP address (net order) */ 40656893Sfenner int dport; /* server port (host order) */ 40756893Sfenner u_short serviceId; /* Service identifier (net order) */ 40856893Sfenner u_int32_t opcode; /* RX opcode (host order) */ 40956893Sfenner}; 41056893Sfenner 41156893Sfenner#define RX_CACHE_SIZE 64 41256893Sfenner 41356893Sfennerstatic struct rx_cache_entry rx_cache[RX_CACHE_SIZE]; 41456893Sfenner 41556893Sfennerstatic int rx_cache_next = 0; 41656893Sfennerstatic int rx_cache_hint = 0; 417127668Sbmsstatic void rx_cache_insert(const u_char *, const struct ip *, int); 41856893Sfennerstatic int rx_cache_find(const struct rx_header *, const struct ip *, 41956893Sfenner int, int32_t *); 42056893Sfenner 42156893Sfennerstatic void fs_print(const u_char *, int); 42256893Sfennerstatic void fs_reply_print(const u_char *, int, int32_t); 42375115Sfennerstatic void acl_print(u_char *, int, u_char *); 42456893Sfennerstatic void cb_print(const u_char *, int); 42556893Sfennerstatic void cb_reply_print(const u_char *, int, int32_t); 42656893Sfennerstatic void prot_print(const u_char *, int); 42756893Sfennerstatic void prot_reply_print(const u_char *, int, int32_t); 42856893Sfennerstatic void vldb_print(const u_char *, int); 42956893Sfennerstatic void vldb_reply_print(const u_char *, int, int32_t); 43056893Sfennerstatic void kauth_print(const u_char *, int); 43156893Sfennerstatic void kauth_reply_print(const u_char *, int, int32_t); 43256893Sfennerstatic void vol_print(const u_char *, int); 43356893Sfennerstatic void vol_reply_print(const u_char *, int, int32_t); 43456893Sfennerstatic void bos_print(const u_char *, int); 43556893Sfennerstatic void bos_reply_print(const u_char *, int, int32_t); 436127668Sbmsstatic void ubik_print(const u_char *); 43756893Sfennerstatic void ubik_reply_print(const u_char *, int, int32_t); 43856893Sfenner 43975115Sfennerstatic void rx_ack_print(const u_char *, int); 44075115Sfenner 44156893Sfennerstatic int is_ubik(u_int32_t); 44256893Sfenner 44356893Sfenner/* 44456893Sfenner * Handle the rx-level packet. See if we know what port it's going to so 44556893Sfenner * we can peek at the afs call inside 44656893Sfenner */ 44756893Sfenner 44856893Sfennervoid 44956893Sfennerrx_print(register const u_char *bp, int length, int sport, int dport, 45056893Sfenner u_char *bp2) 45156893Sfenner{ 45256893Sfenner register struct rx_header *rxh; 45356893Sfenner int i; 45456893Sfenner int32_t opcode; 45556893Sfenner 456127668Sbms if (snapend - bp < (int)sizeof (struct rx_header)) { 45756893Sfenner printf(" [|rx] (%d)", length); 45856893Sfenner return; 45956893Sfenner } 46056893Sfenner 46156893Sfenner rxh = (struct rx_header *) bp; 46256893Sfenner 46356893Sfenner printf(" rx %s", tok2str(rx_types, "type %d", rxh->type)); 46456893Sfenner 46575115Sfenner if (vflag) { 46656893Sfenner int firstflag = 0; 46775115Sfenner 46875115Sfenner if (vflag > 1) 46975115Sfenner printf(" cid %08x call# %d", 47075115Sfenner (int) EXTRACT_32BITS(&rxh->cid), 47175115Sfenner (int) EXTRACT_32BITS(&rxh->callNumber)); 47275115Sfenner 47375115Sfenner printf(" seq %d ser %d", 47475115Sfenner (int) EXTRACT_32BITS(&rxh->seq), 47575115Sfenner (int) EXTRACT_32BITS(&rxh->serial)); 47675115Sfenner 47756893Sfenner if (vflag > 2) 47856893Sfenner printf(" secindex %d serviceid %hu", 47956893Sfenner (int) rxh->securityIndex, 48075115Sfenner EXTRACT_16BITS(&rxh->serviceId)); 48175115Sfenner 48275115Sfenner if (vflag > 1) 48375115Sfenner for (i = 0; i < NUM_RX_FLAGS; i++) { 48498524Sfenner if (rxh->flags & rx_flags[i].flag && 48598524Sfenner (!rx_flags[i].packetType || 48698524Sfenner rxh->type == rx_flags[i].packetType)) { 48775115Sfenner if (!firstflag) { 48875115Sfenner firstflag = 1; 48975115Sfenner printf(" "); 49075115Sfenner } else { 49175115Sfenner printf(","); 49275115Sfenner } 49375115Sfenner printf("<%s>", rx_flags[i].s); 49456893Sfenner } 49556893Sfenner } 49656893Sfenner } 49756893Sfenner 49856893Sfenner /* 49956893Sfenner * Try to handle AFS calls that we know about. Check the destination 50056893Sfenner * port and make sure it's a data packet. Also, make sure the 50156893Sfenner * seq number is 1 (because otherwise it's a continuation packet, 50256893Sfenner * and we can't interpret that). Also, seems that reply packets 50356893Sfenner * do not have the client-init flag set, so we check for that 50456893Sfenner * as well. 50556893Sfenner */ 50656893Sfenner 507127668Sbms if (rxh->type == RX_PACKET_TYPE_DATA && 50875115Sfenner EXTRACT_32BITS(&rxh->seq) == 1 && 50956893Sfenner rxh->flags & RX_CLIENT_INITIATED) { 51056893Sfenner 51156893Sfenner /* 51256893Sfenner * Insert this call into the call cache table, so we 51356893Sfenner * have a chance to print out replies 51456893Sfenner */ 51556893Sfenner 516127668Sbms rx_cache_insert(bp, (const struct ip *) bp2, dport); 51756893Sfenner 51856893Sfenner switch (dport) { 51956893Sfenner case FS_RX_PORT: /* AFS file service */ 52056893Sfenner fs_print(bp, length); 52156893Sfenner break; 52256893Sfenner case CB_RX_PORT: /* AFS callback service */ 52356893Sfenner cb_print(bp, length); 52456893Sfenner break; 52556893Sfenner case PROT_RX_PORT: /* AFS protection service */ 52656893Sfenner prot_print(bp, length); 52756893Sfenner break; 52856893Sfenner case VLDB_RX_PORT: /* AFS VLDB service */ 52956893Sfenner vldb_print(bp, length); 53056893Sfenner break; 53156893Sfenner case KAUTH_RX_PORT: /* AFS Kerberos auth service */ 53256893Sfenner kauth_print(bp, length); 53356893Sfenner break; 53456893Sfenner case VOL_RX_PORT: /* AFS Volume service */ 53556893Sfenner vol_print(bp, length); 53656893Sfenner break; 53756893Sfenner case BOS_RX_PORT: /* AFS BOS service */ 53856893Sfenner bos_print(bp, length); 53956893Sfenner break; 54056893Sfenner default: 54156893Sfenner ; 54256893Sfenner } 543127668Sbms 54456893Sfenner /* 54556893Sfenner * If it's a reply (client-init is _not_ set, but seq is one) 54656893Sfenner * then look it up in the cache. If we find it, call the reply 54756893Sfenner * printing functions Note that we handle abort packets here, 54856893Sfenner * because printing out the return code can be useful at times. 54956893Sfenner */ 55056893Sfenner 55156893Sfenner } else if (((rxh->type == RX_PACKET_TYPE_DATA && 55275115Sfenner EXTRACT_32BITS(&rxh->seq) == 1) || 55356893Sfenner rxh->type == RX_PACKET_TYPE_ABORT) && 55456893Sfenner (rxh->flags & RX_CLIENT_INITIATED) == 0 && 55556893Sfenner rx_cache_find(rxh, (const struct ip *) bp2, 55656893Sfenner sport, &opcode)) { 55756893Sfenner 55856893Sfenner switch (sport) { 55956893Sfenner case FS_RX_PORT: /* AFS file service */ 56056893Sfenner fs_reply_print(bp, length, opcode); 56156893Sfenner break; 56256893Sfenner case CB_RX_PORT: /* AFS callback service */ 56356893Sfenner cb_reply_print(bp, length, opcode); 56456893Sfenner break; 56556893Sfenner case PROT_RX_PORT: /* AFS PT service */ 56656893Sfenner prot_reply_print(bp, length, opcode); 56756893Sfenner break; 56856893Sfenner case VLDB_RX_PORT: /* AFS VLDB service */ 56956893Sfenner vldb_reply_print(bp, length, opcode); 57056893Sfenner break; 57156893Sfenner case KAUTH_RX_PORT: /* AFS Kerberos auth service */ 57256893Sfenner kauth_reply_print(bp, length, opcode); 57356893Sfenner break; 57456893Sfenner case VOL_RX_PORT: /* AFS Volume service */ 57556893Sfenner vol_reply_print(bp, length, opcode); 57656893Sfenner break; 57756893Sfenner case BOS_RX_PORT: /* AFS BOS service */ 57856893Sfenner bos_reply_print(bp, length, opcode); 57956893Sfenner break; 58056893Sfenner default: 58156893Sfenner ; 58256893Sfenner } 58356893Sfenner 58475115Sfenner /* 58575115Sfenner * If it's an RX ack packet, then use the appropriate ack decoding 58675115Sfenner * function (there isn't any service-specific information in the 58775115Sfenner * ack packet, so we can use one for all AFS services) 58875115Sfenner */ 58956893Sfenner 59075115Sfenner } else if (rxh->type == RX_PACKET_TYPE_ACK) 59175115Sfenner rx_ack_print(bp, length); 59275115Sfenner 59375115Sfenner 59456893Sfenner printf(" (%d)", length); 59556893Sfenner} 59656893Sfenner 59756893Sfenner/* 59856893Sfenner * Insert an entry into the cache. Taken from print-nfs.c 59956893Sfenner */ 60056893Sfenner 60156893Sfennerstatic void 602127668Sbmsrx_cache_insert(const u_char *bp, const struct ip *ip, int dport) 60356893Sfenner{ 60456893Sfenner struct rx_cache_entry *rxent; 60556893Sfenner const struct rx_header *rxh = (const struct rx_header *) bp; 60656893Sfenner 607127668Sbms if (snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) 60856893Sfenner return; 60956893Sfenner 61056893Sfenner rxent = &rx_cache[rx_cache_next]; 61156893Sfenner 61256893Sfenner if (++rx_cache_next >= RX_CACHE_SIZE) 61356893Sfenner rx_cache_next = 0; 614127668Sbms 61556893Sfenner rxent->callnum = rxh->callNumber; 61656893Sfenner rxent->client = ip->ip_src; 61756893Sfenner rxent->server = ip->ip_dst; 61856893Sfenner rxent->dport = dport; 61956893Sfenner rxent->serviceId = rxh->serviceId; 62075115Sfenner rxent->opcode = EXTRACT_32BITS(bp + sizeof(struct rx_header)); 62156893Sfenner} 62256893Sfenner 62356893Sfenner/* 62456893Sfenner * Lookup an entry in the cache. Also taken from print-nfs.c 62556893Sfenner * 62656893Sfenner * Note that because this is a reply, we're looking at the _source_ 62756893Sfenner * port. 62856893Sfenner */ 62956893Sfenner 63056893Sfennerstatic int 63156893Sfennerrx_cache_find(const struct rx_header *rxh, const struct ip *ip, int sport, 63256893Sfenner int32_t *opcode) 63356893Sfenner{ 63456893Sfenner int i; 63556893Sfenner struct rx_cache_entry *rxent; 63656893Sfenner u_int32_t clip = ip->ip_dst.s_addr; 63756893Sfenner u_int32_t sip = ip->ip_src.s_addr; 63856893Sfenner 63956893Sfenner /* Start the search where we last left off */ 64056893Sfenner 64156893Sfenner i = rx_cache_hint; 64256893Sfenner do { 64356893Sfenner rxent = &rx_cache[i]; 64456893Sfenner if (rxent->callnum == rxh->callNumber && 64556893Sfenner rxent->client.s_addr == clip && 646127668Sbms rxent->server.s_addr == sip && 64756893Sfenner rxent->serviceId == rxh->serviceId && 64856893Sfenner rxent->dport == sport) { 64956893Sfenner 65056893Sfenner /* We got a match! */ 65156893Sfenner 65256893Sfenner rx_cache_hint = i; 65356893Sfenner *opcode = rxent->opcode; 65456893Sfenner return(1); 65556893Sfenner } 65656893Sfenner if (++i > RX_CACHE_SIZE) 65756893Sfenner i = 0; 65856893Sfenner } while (i != rx_cache_hint); 65956893Sfenner 66056893Sfenner /* Our search failed */ 66156893Sfenner return(0); 66256893Sfenner} 66356893Sfenner 66456893Sfenner/* 66556893Sfenner * These extrememly grody macros handle the printing of various AFS stuff. 66656893Sfenner */ 66756893Sfenner 66856893Sfenner#define FIDOUT() { unsigned long n1, n2, n3; \ 66975115Sfenner TCHECK2(bp[0], sizeof(int32_t) * 3); \ 67075115Sfenner n1 = EXTRACT_32BITS(bp); \ 67156893Sfenner bp += sizeof(int32_t); \ 67275115Sfenner n2 = EXTRACT_32BITS(bp); \ 67356893Sfenner bp += sizeof(int32_t); \ 67475115Sfenner n3 = EXTRACT_32BITS(bp); \ 67556893Sfenner bp += sizeof(int32_t); \ 67656893Sfenner printf(" fid %d/%d/%d", (int) n1, (int) n2, (int) n3); \ 67756893Sfenner } 67856893Sfenner 67980231Sfenner#define STROUT(MAX) { unsigned int i; \ 68075115Sfenner TCHECK2(bp[0], sizeof(int32_t)); \ 68180231Sfenner i = EXTRACT_32BITS(bp); \ 68298524Sfenner if (i > (MAX)) \ 68380231Sfenner goto trunc; \ 68456893Sfenner bp += sizeof(int32_t); \ 68580231Sfenner printf(" \""); \ 68680231Sfenner if (fn_printn(bp, i, snapend)) \ 68780231Sfenner goto trunc; \ 68880231Sfenner printf("\""); \ 68956893Sfenner bp += ((i + sizeof(int32_t) - 1) / sizeof(int32_t)) * sizeof(int32_t); \ 69056893Sfenner } 69156893Sfenner 69256893Sfenner#define INTOUT() { int i; \ 69375115Sfenner TCHECK2(bp[0], sizeof(int32_t)); \ 69475115Sfenner i = (int) EXTRACT_32BITS(bp); \ 69556893Sfenner bp += sizeof(int32_t); \ 69656893Sfenner printf(" %d", i); \ 69756893Sfenner } 69856893Sfenner 69956893Sfenner#define UINTOUT() { unsigned long i; \ 70075115Sfenner TCHECK2(bp[0], sizeof(int32_t)); \ 70175115Sfenner i = EXTRACT_32BITS(bp); \ 70256893Sfenner bp += sizeof(int32_t); \ 70356893Sfenner printf(" %lu", i); \ 70456893Sfenner } 70556893Sfenner 706190207Srpaulo#define UINT64OUT() { u_int64_t i; \ 707190207Srpaulo TCHECK2(bp[0], sizeof(u_int64_t)); \ 708190207Srpaulo i = EXTRACT_64BITS(bp); \ 709190207Srpaulo bp += sizeof(u_int64_t); \ 710190207Srpaulo printf(" %" PRIu64, i); \ 711190207Srpaulo } 712190207Srpaulo 71356893Sfenner#define DATEOUT() { time_t t; struct tm *tm; char str[256]; \ 71475115Sfenner TCHECK2(bp[0], sizeof(int32_t)); \ 71575115Sfenner t = (time_t) EXTRACT_32BITS(bp); \ 71656893Sfenner bp += sizeof(int32_t); \ 71756893Sfenner tm = localtime(&t); \ 71856893Sfenner strftime(str, 256, "%Y/%m/%d %T", tm); \ 71956893Sfenner printf(" %s", str); \ 72056893Sfenner } 72156893Sfenner 72256893Sfenner#define STOREATTROUT() { unsigned long mask, i; \ 72375115Sfenner TCHECK2(bp[0], (sizeof(int32_t)*6)); \ 72475115Sfenner mask = EXTRACT_32BITS(bp); bp += sizeof(int32_t); \ 72556893Sfenner if (mask) printf (" StoreStatus"); \ 726127668Sbms if (mask & 1) { printf(" date"); DATEOUT(); } \ 72756893Sfenner else bp += sizeof(int32_t); \ 72875115Sfenner i = EXTRACT_32BITS(bp); bp += sizeof(int32_t); \ 729127668Sbms if (mask & 2) printf(" owner %lu", i); \ 73075115Sfenner i = EXTRACT_32BITS(bp); bp += sizeof(int32_t); \ 731127668Sbms if (mask & 4) printf(" group %lu", i); \ 73275115Sfenner i = EXTRACT_32BITS(bp); bp += sizeof(int32_t); \ 733127668Sbms if (mask & 8) printf(" mode %lo", i & 07777); \ 73475115Sfenner i = EXTRACT_32BITS(bp); bp += sizeof(int32_t); \ 735127668Sbms if (mask & 16) printf(" segsize %lu", i); \ 73656893Sfenner /* undocumented in 3.3 docu */ \ 737127668Sbms if (mask & 1024) printf(" fsync"); \ 73856893Sfenner } 73956893Sfenner 74056893Sfenner#define UBIK_VERSIONOUT() {int32_t epoch; int32_t counter; \ 74175115Sfenner TCHECK2(bp[0], sizeof(int32_t) * 2); \ 74275115Sfenner epoch = EXTRACT_32BITS(bp); \ 74356893Sfenner bp += sizeof(int32_t); \ 74475115Sfenner counter = EXTRACT_32BITS(bp); \ 74556893Sfenner bp += sizeof(int32_t); \ 74656893Sfenner printf(" %d.%d", epoch, counter); \ 74756893Sfenner } 74856893Sfenner 74956893Sfenner#define AFSUUIDOUT() {u_int32_t temp; int i; \ 75075115Sfenner TCHECK2(bp[0], 11*sizeof(u_int32_t)); \ 75175115Sfenner temp = EXTRACT_32BITS(bp); \ 75256893Sfenner bp += sizeof(u_int32_t); \ 75356893Sfenner printf(" %08x", temp); \ 75475115Sfenner temp = EXTRACT_32BITS(bp); \ 75556893Sfenner bp += sizeof(u_int32_t); \ 75656893Sfenner printf("%04x", temp); \ 75775115Sfenner temp = EXTRACT_32BITS(bp); \ 75856893Sfenner bp += sizeof(u_int32_t); \ 75956893Sfenner printf("%04x", temp); \ 76056893Sfenner for (i = 0; i < 8; i++) { \ 76175115Sfenner temp = EXTRACT_32BITS(bp); \ 76256893Sfenner bp += sizeof(u_int32_t); \ 76356893Sfenner printf("%02x", (unsigned char) temp); \ 76456893Sfenner } \ 76556893Sfenner } 76656893Sfenner 76756893Sfenner/* 76856893Sfenner * This is the sickest one of all 76956893Sfenner */ 77056893Sfenner 771111726Sfenner#define VECOUT(MAX) { u_char *sp; \ 772111726Sfenner u_char s[AFSNAMEMAX]; \ 77356893Sfenner int k; \ 77498524Sfenner if ((MAX) + 1 > sizeof(s)) \ 77598524Sfenner goto trunc; \ 77698524Sfenner TCHECK2(bp[0], (MAX) * sizeof(int32_t)); \ 77756893Sfenner sp = s; \ 77898524Sfenner for (k = 0; k < (MAX); k++) { \ 779111726Sfenner *sp++ = (u_char) EXTRACT_32BITS(bp); \ 78056893Sfenner bp += sizeof(int32_t); \ 78156893Sfenner } \ 78298524Sfenner s[(MAX)] = '\0'; \ 78380231Sfenner printf(" \""); \ 78480231Sfenner fn_print(s, NULL); \ 78580231Sfenner printf("\""); \ 78656893Sfenner } 78756893Sfenner 788190207Srpaulo#define DESTSERVEROUT() { unsigned long n1, n2, n3; \ 789190207Srpaulo TCHECK2(bp[0], sizeof(int32_t) * 3); \ 790190207Srpaulo n1 = EXTRACT_32BITS(bp); \ 791190207Srpaulo bp += sizeof(int32_t); \ 792190207Srpaulo n2 = EXTRACT_32BITS(bp); \ 793190207Srpaulo bp += sizeof(int32_t); \ 794190207Srpaulo n3 = EXTRACT_32BITS(bp); \ 795190207Srpaulo bp += sizeof(int32_t); \ 796190207Srpaulo printf(" server %d:%d:%d", (int) n1, (int) n2, (int) n3); \ 797190207Srpaulo } 798190207Srpaulo 79956893Sfenner/* 80056893Sfenner * Handle calls to the AFS file service (fs) 80156893Sfenner */ 80256893Sfenner 80375115Sfennerstatic void 80456893Sfennerfs_print(register const u_char *bp, int length) 80556893Sfenner{ 80656893Sfenner int fs_op; 80756893Sfenner unsigned long i; 80856893Sfenner 809127668Sbms if (length <= (int)sizeof(struct rx_header)) 81056893Sfenner return; 81156893Sfenner 812127668Sbms if (snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) { 81356893Sfenner goto trunc; 81456893Sfenner } 81556893Sfenner 81656893Sfenner /* 81756893Sfenner * Print out the afs call we're invoking. The table used here was 81856893Sfenner * gleaned from fsint/afsint.xg 81956893Sfenner */ 82056893Sfenner 82175115Sfenner fs_op = EXTRACT_32BITS(bp + sizeof(struct rx_header)); 82256893Sfenner 82356893Sfenner printf(" fs call %s", tok2str(fs_req, "op#%d", fs_op)); 82456893Sfenner 82556893Sfenner /* 82656893Sfenner * Print out arguments to some of the AFS calls. This stuff is 82756893Sfenner * all from afsint.xg 82856893Sfenner */ 82956893Sfenner 83056893Sfenner bp += sizeof(struct rx_header) + 4; 83156893Sfenner 83256893Sfenner /* 83356893Sfenner * Sigh. This is gross. Ritchie forgive me. 83456893Sfenner */ 83556893Sfenner 83656893Sfenner switch (fs_op) { 83756893Sfenner case 130: /* Fetch data */ 83856893Sfenner FIDOUT(); 83956893Sfenner printf(" offset"); 84056893Sfenner UINTOUT(); 84156893Sfenner printf(" length"); 84256893Sfenner UINTOUT(); 84356893Sfenner break; 84456893Sfenner case 131: /* Fetch ACL */ 84556893Sfenner case 132: /* Fetch Status */ 84656893Sfenner case 143: /* Old set lock */ 84756893Sfenner case 144: /* Old extend lock */ 84856893Sfenner case 145: /* Old release lock */ 84956893Sfenner case 156: /* Set lock */ 85056893Sfenner case 157: /* Extend lock */ 85156893Sfenner case 158: /* Release lock */ 85256893Sfenner FIDOUT(); 85356893Sfenner break; 85456893Sfenner case 135: /* Store status */ 85556893Sfenner FIDOUT(); 85656893Sfenner STOREATTROUT(); 85756893Sfenner break; 85856893Sfenner case 133: /* Store data */ 85956893Sfenner FIDOUT(); 86056893Sfenner STOREATTROUT(); 86156893Sfenner printf(" offset"); 86256893Sfenner UINTOUT(); 86356893Sfenner printf(" length"); 86456893Sfenner UINTOUT(); 86556893Sfenner printf(" flen"); 86656893Sfenner UINTOUT(); 86756893Sfenner break; 86856893Sfenner case 134: /* Store ACL */ 86956893Sfenner { 87075115Sfenner char a[AFSOPAQUEMAX+1]; 87156893Sfenner FIDOUT(); 87275115Sfenner TCHECK2(bp[0], 4); 87375115Sfenner i = EXTRACT_32BITS(bp); 87456893Sfenner bp += sizeof(int32_t); 87575115Sfenner TCHECK2(bp[0], i); 87675115Sfenner i = min(AFSOPAQUEMAX, i); 87775115Sfenner strncpy(a, (char *) bp, i); 87856893Sfenner a[i] = '\0'; 87975115Sfenner acl_print((u_char *) a, sizeof(a), (u_char *) a + i); 88056893Sfenner break; 88156893Sfenner } 88256893Sfenner case 137: /* Create file */ 88356893Sfenner case 141: /* MakeDir */ 88456893Sfenner FIDOUT(); 88556893Sfenner STROUT(AFSNAMEMAX); 88656893Sfenner STOREATTROUT(); 88756893Sfenner break; 88856893Sfenner case 136: /* Remove file */ 88956893Sfenner case 142: /* Remove directory */ 89056893Sfenner FIDOUT(); 89156893Sfenner STROUT(AFSNAMEMAX); 89256893Sfenner break; 89356893Sfenner case 138: /* Rename file */ 89456893Sfenner printf(" old"); 89556893Sfenner FIDOUT(); 89656893Sfenner STROUT(AFSNAMEMAX); 89756893Sfenner printf(" new"); 89856893Sfenner FIDOUT(); 89956893Sfenner STROUT(AFSNAMEMAX); 90056893Sfenner break; 90156893Sfenner case 139: /* Symlink */ 90256893Sfenner FIDOUT(); 90356893Sfenner STROUT(AFSNAMEMAX); 90456893Sfenner printf(" link to"); 90556893Sfenner STROUT(AFSNAMEMAX); 90656893Sfenner break; 90756893Sfenner case 140: /* Link */ 90856893Sfenner FIDOUT(); 90956893Sfenner STROUT(AFSNAMEMAX); 91056893Sfenner printf(" link to"); 91156893Sfenner FIDOUT(); 91256893Sfenner break; 91356893Sfenner case 148: /* Get volume info */ 91456893Sfenner STROUT(AFSNAMEMAX); 91556893Sfenner break; 91656893Sfenner case 149: /* Get volume stats */ 91756893Sfenner case 150: /* Set volume stats */ 91856893Sfenner printf(" volid"); 91956893Sfenner UINTOUT(); 92056893Sfenner break; 92156893Sfenner case 154: /* New get volume info */ 92256893Sfenner printf(" volname"); 92356893Sfenner STROUT(AFSNAMEMAX); 92456893Sfenner break; 92556893Sfenner case 155: /* Bulk stat */ 926190207Srpaulo case 65536: /* Inline bulk stat */ 92756893Sfenner { 92856893Sfenner unsigned long j; 92975115Sfenner TCHECK2(bp[0], 4); 93075115Sfenner j = EXTRACT_32BITS(bp); 93156893Sfenner bp += sizeof(int32_t); 93256893Sfenner 93356893Sfenner for (i = 0; i < j; i++) { 93456893Sfenner FIDOUT(); 93556893Sfenner if (i != j - 1) 93656893Sfenner printf(","); 93756893Sfenner } 93856893Sfenner if (j == 0) 93956893Sfenner printf(" <none!>"); 94056893Sfenner } 941190207Srpaulo case 65537: /* Fetch data 64 */ 942190207Srpaulo FIDOUT(); 943190207Srpaulo printf(" offset"); 944190207Srpaulo UINT64OUT(); 945190207Srpaulo printf(" length"); 946190207Srpaulo UINT64OUT(); 947190207Srpaulo break; 948190207Srpaulo case 65538: /* Store data 64 */ 949190207Srpaulo FIDOUT(); 950190207Srpaulo STOREATTROUT(); 951190207Srpaulo printf(" offset"); 952190207Srpaulo UINT64OUT(); 953190207Srpaulo printf(" length"); 954190207Srpaulo UINT64OUT(); 955190207Srpaulo printf(" flen"); 956190207Srpaulo UINT64OUT(); 957190207Srpaulo break; 958190207Srpaulo case 65541: /* CallBack rx conn address */ 959190207Srpaulo printf(" addr"); 960190207Srpaulo UINTOUT(); 96156893Sfenner default: 96256893Sfenner ; 96356893Sfenner } 96456893Sfenner 96556893Sfenner return; 96656893Sfenner 96756893Sfennertrunc: 96856893Sfenner printf(" [|fs]"); 96956893Sfenner} 97056893Sfenner 97156893Sfenner/* 97256893Sfenner * Handle replies to the AFS file service 97356893Sfenner */ 97456893Sfenner 97556893Sfennerstatic void 97656893Sfennerfs_reply_print(register const u_char *bp, int length, int32_t opcode) 97756893Sfenner{ 97856893Sfenner unsigned long i; 97956893Sfenner struct rx_header *rxh; 98056893Sfenner 981127668Sbms if (length <= (int)sizeof(struct rx_header)) 98256893Sfenner return; 98356893Sfenner 98456893Sfenner rxh = (struct rx_header *) bp; 98556893Sfenner 98656893Sfenner /* 98756893Sfenner * Print out the afs call we're invoking. The table used here was 98856893Sfenner * gleaned from fsint/afsint.xg 98956893Sfenner */ 99056893Sfenner 99156893Sfenner printf(" fs reply %s", tok2str(fs_req, "op#%d", opcode)); 99256893Sfenner 99356893Sfenner bp += sizeof(struct rx_header); 99456893Sfenner 99556893Sfenner /* 99656893Sfenner * If it was a data packet, interpret the response 99756893Sfenner */ 99856893Sfenner 99975115Sfenner if (rxh->type == RX_PACKET_TYPE_DATA) { 100056893Sfenner switch (opcode) { 100156893Sfenner case 131: /* Fetch ACL */ 100256893Sfenner { 100375115Sfenner char a[AFSOPAQUEMAX+1]; 100475115Sfenner TCHECK2(bp[0], 4); 100575115Sfenner i = EXTRACT_32BITS(bp); 100656893Sfenner bp += sizeof(int32_t); 100775115Sfenner TCHECK2(bp[0], i); 100875115Sfenner i = min(AFSOPAQUEMAX, i); 100975115Sfenner strncpy(a, (char *) bp, i); 101056893Sfenner a[i] = '\0'; 101175115Sfenner acl_print((u_char *) a, sizeof(a), (u_char *) a + i); 101256893Sfenner break; 101356893Sfenner } 101456893Sfenner case 137: /* Create file */ 101556893Sfenner case 141: /* MakeDir */ 101656893Sfenner printf(" new"); 101756893Sfenner FIDOUT(); 101856893Sfenner break; 101956893Sfenner case 151: /* Get root volume */ 102056893Sfenner printf(" root volume"); 102156893Sfenner STROUT(AFSNAMEMAX); 102256893Sfenner break; 102356893Sfenner case 153: /* Get time */ 102456893Sfenner DATEOUT(); 102556893Sfenner break; 102656893Sfenner default: 102756893Sfenner ; 102856893Sfenner } 102975115Sfenner } else if (rxh->type == RX_PACKET_TYPE_ABORT) { 103075115Sfenner int i; 103175115Sfenner 1032127668Sbms /* 1033127668Sbms * Otherwise, just print out the return code 1034127668Sbms */ 1035127668Sbms TCHECK2(bp[0], sizeof(int32_t)); 1036127668Sbms i = (int) EXTRACT_32BITS(bp); 1037127668Sbms bp += sizeof(int32_t); 103875115Sfenner 103975115Sfenner printf(" error %s", tok2str(afs_fs_errors, "#%d", i)); 104075115Sfenner } else { 104175115Sfenner printf(" strange fs reply of type %d", rxh->type); 104256893Sfenner } 104356893Sfenner 104456893Sfenner return; 104556893Sfenner 104656893Sfennertrunc: 104756893Sfenner printf(" [|fs]"); 104856893Sfenner} 104956893Sfenner 105056893Sfenner/* 105156893Sfenner * Print out an AFS ACL string. An AFS ACL is a string that has the 105256893Sfenner * following format: 105356893Sfenner * 105456893Sfenner * <positive> <negative> 105556893Sfenner * <uid1> <aclbits1> 105656893Sfenner * .... 1057127668Sbms * 105856893Sfenner * "positive" and "negative" are integers which contain the number of 105956893Sfenner * positive and negative ACL's in the string. The uid/aclbits pair are 106056893Sfenner * ASCII strings containing the UID/PTS record and and a ascii number 106156893Sfenner * representing a logical OR of all the ACL permission bits 106256893Sfenner */ 106356893Sfenner 106456893Sfennerstatic void 106575115Sfenneracl_print(u_char *s, int maxsize, u_char *end) 106656893Sfenner{ 106756893Sfenner int pos, neg, acl; 106856893Sfenner int n, i; 106975115Sfenner char *user; 1070172683Smlaier char fmt[1024]; 107156893Sfenner 107275115Sfenner if ((user = (char *)malloc(maxsize)) == NULL) 107375115Sfenner return; 107475115Sfenner 107556893Sfenner if (sscanf((char *) s, "%d %d\n%n", &pos, &neg, &n) != 2) 107675115Sfenner goto finish; 1077127668Sbms 107856893Sfenner s += n; 107956893Sfenner 108056893Sfenner if (s > end) 108175115Sfenner goto finish; 108256893Sfenner 108356893Sfenner /* 108456893Sfenner * This wacky order preserves the order used by the "fs" command 108556893Sfenner */ 108656893Sfenner 108756893Sfenner#define ACLOUT(acl) \ 108856893Sfenner if (acl & PRSFS_READ) \ 108956893Sfenner printf("r"); \ 109056893Sfenner if (acl & PRSFS_LOOKUP) \ 109156893Sfenner printf("l"); \ 109256893Sfenner if (acl & PRSFS_INSERT) \ 109356893Sfenner printf("i"); \ 109456893Sfenner if (acl & PRSFS_DELETE) \ 109556893Sfenner printf("d"); \ 109656893Sfenner if (acl & PRSFS_WRITE) \ 109756893Sfenner printf("w"); \ 109856893Sfenner if (acl & PRSFS_LOCK) \ 109956893Sfenner printf("k"); \ 110056893Sfenner if (acl & PRSFS_ADMINISTER) \ 110156893Sfenner printf("a"); 110256893Sfenner 110356893Sfenner for (i = 0; i < pos; i++) { 1104172683Smlaier snprintf(fmt, sizeof(fmt), "%%%ds %%d\n%%n", maxsize - 1); 1105172683Smlaier if (sscanf((char *) s, fmt, user, &acl, &n) != 2) 110675115Sfenner goto finish; 110756893Sfenner s += n; 110880231Sfenner printf(" +{"); 1109111726Sfenner fn_print((u_char *)user, NULL); 111080231Sfenner printf(" "); 111156893Sfenner ACLOUT(acl); 111256893Sfenner printf("}"); 111356893Sfenner if (s > end) 111475115Sfenner goto finish; 111556893Sfenner } 111656893Sfenner 111756893Sfenner for (i = 0; i < neg; i++) { 1118172683Smlaier snprintf(fmt, sizeof(fmt), "%%%ds %%d\n%%n", maxsize - 1); 1119172683Smlaier if (sscanf((char *) s, fmt, user, &acl, &n) != 2) 112075115Sfenner goto finish; 112156893Sfenner s += n; 112280231Sfenner printf(" -{"); 1123111726Sfenner fn_print((u_char *)user, NULL); 112480231Sfenner printf(" "); 112556893Sfenner ACLOUT(acl); 112656893Sfenner printf("}"); 112756893Sfenner if (s > end) 112875115Sfenner goto finish; 112956893Sfenner } 113075115Sfenner 113175115Sfennerfinish: 113275115Sfenner free(user); 113375115Sfenner return; 113456893Sfenner} 113556893Sfenner 113656893Sfenner#undef ACLOUT 113756893Sfenner 113856893Sfenner/* 113956893Sfenner * Handle calls to the AFS callback service 114056893Sfenner */ 114156893Sfenner 114256893Sfennerstatic void 114356893Sfennercb_print(register const u_char *bp, int length) 114456893Sfenner{ 114556893Sfenner int cb_op; 114656893Sfenner unsigned long i; 114756893Sfenner 1148127668Sbms if (length <= (int)sizeof(struct rx_header)) 114956893Sfenner return; 115056893Sfenner 1151127668Sbms if (snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) { 115256893Sfenner goto trunc; 115356893Sfenner } 115456893Sfenner 115556893Sfenner /* 115656893Sfenner * Print out the afs call we're invoking. The table used here was 115756893Sfenner * gleaned from fsint/afscbint.xg 115856893Sfenner */ 115956893Sfenner 116075115Sfenner cb_op = EXTRACT_32BITS(bp + sizeof(struct rx_header)); 116156893Sfenner 116256893Sfenner printf(" cb call %s", tok2str(cb_req, "op#%d", cb_op)); 116356893Sfenner 116456893Sfenner bp += sizeof(struct rx_header) + 4; 116556893Sfenner 116656893Sfenner /* 116756893Sfenner * Print out the afs call we're invoking. The table used here was 116856893Sfenner * gleaned from fsint/afscbint.xg 116956893Sfenner */ 117056893Sfenner 117156893Sfenner switch (cb_op) { 117256893Sfenner case 204: /* Callback */ 117356893Sfenner { 117456893Sfenner unsigned long j, t; 117575115Sfenner TCHECK2(bp[0], 4); 117675115Sfenner j = EXTRACT_32BITS(bp); 117756893Sfenner bp += sizeof(int32_t); 117856893Sfenner 117956893Sfenner for (i = 0; i < j; i++) { 118056893Sfenner FIDOUT(); 118156893Sfenner if (i != j - 1) 118256893Sfenner printf(","); 118356893Sfenner } 118456893Sfenner 118556893Sfenner if (j == 0) 118656893Sfenner printf(" <none!>"); 118756893Sfenner 118875115Sfenner j = EXTRACT_32BITS(bp); 118956893Sfenner bp += sizeof(int32_t); 119056893Sfenner 119156893Sfenner if (j != 0) 119256893Sfenner printf(";"); 119356893Sfenner 119456893Sfenner for (i = 0; i < j; i++) { 119556893Sfenner printf(" ver"); 119656893Sfenner INTOUT(); 119756893Sfenner printf(" expires"); 119856893Sfenner DATEOUT(); 119975115Sfenner TCHECK2(bp[0], 4); 120075115Sfenner t = EXTRACT_32BITS(bp); 120156893Sfenner bp += sizeof(int32_t); 120256893Sfenner tok2str(cb_types, "type %d", t); 120356893Sfenner } 120456893Sfenner } 120556893Sfenner case 214: { 120656893Sfenner printf(" afsuuid"); 120756893Sfenner AFSUUIDOUT(); 120856893Sfenner break; 120956893Sfenner } 121056893Sfenner default: 121156893Sfenner ; 121256893Sfenner } 121356893Sfenner 121456893Sfenner return; 121556893Sfenner 121656893Sfennertrunc: 121756893Sfenner printf(" [|cb]"); 121856893Sfenner} 121956893Sfenner 122056893Sfenner/* 122156893Sfenner * Handle replies to the AFS Callback Service 122256893Sfenner */ 122356893Sfenner 122456893Sfennerstatic void 122556893Sfennercb_reply_print(register const u_char *bp, int length, int32_t opcode) 122656893Sfenner{ 122756893Sfenner struct rx_header *rxh; 122856893Sfenner 1229127668Sbms if (length <= (int)sizeof(struct rx_header)) 123056893Sfenner return; 123156893Sfenner 123256893Sfenner rxh = (struct rx_header *) bp; 123356893Sfenner 123456893Sfenner /* 123556893Sfenner * Print out the afs call we're invoking. The table used here was 123656893Sfenner * gleaned from fsint/afscbint.xg 123756893Sfenner */ 1238127668Sbms 123956893Sfenner printf(" cb reply %s", tok2str(cb_req, "op#%d", opcode)); 124056893Sfenner 124156893Sfenner bp += sizeof(struct rx_header); 124256893Sfenner 124356893Sfenner /* 124456893Sfenner * If it was a data packet, interpret the response. 124556893Sfenner */ 124656893Sfenner 124756893Sfenner if (rxh->type == RX_PACKET_TYPE_DATA) 124856893Sfenner switch (opcode) { 124956893Sfenner case 213: /* InitCallBackState3 */ 125056893Sfenner AFSUUIDOUT(); 125156893Sfenner break; 125256893Sfenner default: 125356893Sfenner ; 125456893Sfenner } 125556893Sfenner else { 125656893Sfenner /* 125756893Sfenner * Otherwise, just print out the return code 125856893Sfenner */ 125956893Sfenner printf(" errcode"); 126056893Sfenner INTOUT(); 126156893Sfenner } 126256893Sfenner 126356893Sfenner return; 126456893Sfenner 126556893Sfennertrunc: 126656893Sfenner printf(" [|cb]"); 126756893Sfenner} 126856893Sfenner 126956893Sfenner/* 127056893Sfenner * Handle calls to the AFS protection database server 127156893Sfenner */ 127256893Sfenner 127356893Sfennerstatic void 127456893Sfennerprot_print(register const u_char *bp, int length) 127556893Sfenner{ 127656893Sfenner unsigned long i; 127756893Sfenner int pt_op; 127856893Sfenner 1279127668Sbms if (length <= (int)sizeof(struct rx_header)) 128056893Sfenner return; 128156893Sfenner 1282127668Sbms if (snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) { 128356893Sfenner goto trunc; 128456893Sfenner } 128556893Sfenner 128656893Sfenner /* 128756893Sfenner * Print out the afs call we're invoking. The table used here was 128856893Sfenner * gleaned from ptserver/ptint.xg 128956893Sfenner */ 129056893Sfenner 129175115Sfenner pt_op = EXTRACT_32BITS(bp + sizeof(struct rx_header)); 129256893Sfenner 129356893Sfenner printf(" pt"); 129456893Sfenner 129556893Sfenner if (is_ubik(pt_op)) { 1296127668Sbms ubik_print(bp); 129756893Sfenner return; 129856893Sfenner } 129956893Sfenner 130056893Sfenner printf(" call %s", tok2str(pt_req, "op#%d", pt_op)); 130156893Sfenner 130256893Sfenner /* 130356893Sfenner * Decode some of the arguments to the PT calls 130456893Sfenner */ 130556893Sfenner 130656893Sfenner bp += sizeof(struct rx_header) + 4; 130756893Sfenner 130856893Sfenner switch (pt_op) { 130956893Sfenner case 500: /* I New User */ 131056893Sfenner STROUT(PRNAMEMAX); 131156893Sfenner printf(" id"); 131256893Sfenner INTOUT(); 131356893Sfenner printf(" oldid"); 131456893Sfenner INTOUT(); 131556893Sfenner break; 131656893Sfenner case 501: /* Where is it */ 131756893Sfenner case 506: /* Delete */ 131856893Sfenner case 508: /* Get CPS */ 131956893Sfenner case 512: /* List entry */ 132056893Sfenner case 514: /* List elements */ 132156893Sfenner case 517: /* List owned */ 132256893Sfenner case 518: /* Get CPS2 */ 132356893Sfenner case 519: /* Get host CPS */ 1324190207Srpaulo case 530: /* List super groups */ 132556893Sfenner printf(" id"); 132656893Sfenner INTOUT(); 132756893Sfenner break; 132856893Sfenner case 502: /* Dump entry */ 132956893Sfenner printf(" pos"); 133056893Sfenner INTOUT(); 133156893Sfenner break; 133256893Sfenner case 503: /* Add to group */ 133356893Sfenner case 507: /* Remove from group */ 133456893Sfenner case 515: /* Is a member of? */ 133556893Sfenner printf(" uid"); 133656893Sfenner INTOUT(); 133756893Sfenner printf(" gid"); 133856893Sfenner INTOUT(); 133956893Sfenner break; 134056893Sfenner case 504: /* Name to ID */ 134156893Sfenner { 134256893Sfenner unsigned long j; 134375115Sfenner TCHECK2(bp[0], 4); 134475115Sfenner j = EXTRACT_32BITS(bp); 134556893Sfenner bp += sizeof(int32_t); 134656893Sfenner 134756893Sfenner /* 134856893Sfenner * Who designed this chicken-shit protocol? 134956893Sfenner * 135056893Sfenner * Each character is stored as a 32-bit 135156893Sfenner * integer! 135256893Sfenner */ 135356893Sfenner 135456893Sfenner for (i = 0; i < j; i++) { 135556893Sfenner VECOUT(PRNAMEMAX); 135656893Sfenner } 135756893Sfenner if (j == 0) 135856893Sfenner printf(" <none!>"); 135956893Sfenner } 136056893Sfenner break; 136156893Sfenner case 505: /* Id to name */ 136256893Sfenner { 136356893Sfenner unsigned long j; 136456893Sfenner printf(" ids:"); 136575115Sfenner TCHECK2(bp[0], 4); 136675115Sfenner i = EXTRACT_32BITS(bp); 136756893Sfenner bp += sizeof(int32_t); 136856893Sfenner for (j = 0; j < i; j++) 136956893Sfenner INTOUT(); 137056893Sfenner if (j == 0) 137156893Sfenner printf(" <none!>"); 137256893Sfenner } 137356893Sfenner break; 137456893Sfenner case 509: /* New entry */ 137556893Sfenner STROUT(PRNAMEMAX); 137656893Sfenner printf(" flag"); 137756893Sfenner INTOUT(); 137856893Sfenner printf(" oid"); 137956893Sfenner INTOUT(); 138056893Sfenner break; 138156893Sfenner case 511: /* Set max */ 138256893Sfenner printf(" id"); 138356893Sfenner INTOUT(); 138456893Sfenner printf(" gflag"); 138556893Sfenner INTOUT(); 138656893Sfenner break; 138756893Sfenner case 513: /* Change entry */ 138856893Sfenner printf(" id"); 138956893Sfenner INTOUT(); 139056893Sfenner STROUT(PRNAMEMAX); 139156893Sfenner printf(" oldid"); 139256893Sfenner INTOUT(); 139356893Sfenner printf(" newid"); 139456893Sfenner INTOUT(); 139556893Sfenner break; 139656893Sfenner case 520: /* Update entry */ 139756893Sfenner printf(" id"); 139856893Sfenner INTOUT(); 139956893Sfenner STROUT(PRNAMEMAX); 140056893Sfenner break; 140156893Sfenner default: 140256893Sfenner ; 140356893Sfenner } 140456893Sfenner 140556893Sfenner 140656893Sfenner return; 140756893Sfenner 140856893Sfennertrunc: 140956893Sfenner printf(" [|pt]"); 141056893Sfenner} 141156893Sfenner 141256893Sfenner/* 141356893Sfenner * Handle replies to the AFS protection service 141456893Sfenner */ 141556893Sfenner 141656893Sfennerstatic void 141756893Sfennerprot_reply_print(register const u_char *bp, int length, int32_t opcode) 141856893Sfenner{ 141956893Sfenner struct rx_header *rxh; 142056893Sfenner unsigned long i; 142156893Sfenner 1422127668Sbms if (length < (int)sizeof(struct rx_header)) 142356893Sfenner return; 142456893Sfenner 142556893Sfenner rxh = (struct rx_header *) bp; 142656893Sfenner 142756893Sfenner /* 142856893Sfenner * Print out the afs call we're invoking. The table used here was 142956893Sfenner * gleaned from ptserver/ptint.xg. Check to see if it's a 143056893Sfenner * Ubik call, however. 143156893Sfenner */ 143256893Sfenner 143356893Sfenner printf(" pt"); 143456893Sfenner 143556893Sfenner if (is_ubik(opcode)) { 143656893Sfenner ubik_reply_print(bp, length, opcode); 143756893Sfenner return; 143856893Sfenner } 143956893Sfenner 144056893Sfenner printf(" reply %s", tok2str(pt_req, "op#%d", opcode)); 144156893Sfenner 144256893Sfenner bp += sizeof(struct rx_header); 144356893Sfenner 144456893Sfenner /* 144556893Sfenner * If it was a data packet, interpret the response 144656893Sfenner */ 144756893Sfenner 144856893Sfenner if (rxh->type == RX_PACKET_TYPE_DATA) 144956893Sfenner switch (opcode) { 145056893Sfenner case 504: /* Name to ID */ 145156893Sfenner { 145256893Sfenner unsigned long j; 145356893Sfenner printf(" ids:"); 145475115Sfenner TCHECK2(bp[0], 4); 145575115Sfenner i = EXTRACT_32BITS(bp); 145656893Sfenner bp += sizeof(int32_t); 145756893Sfenner for (j = 0; j < i; j++) 145856893Sfenner INTOUT(); 145956893Sfenner if (j == 0) 146056893Sfenner printf(" <none!>"); 146156893Sfenner } 146256893Sfenner break; 146356893Sfenner case 505: /* ID to name */ 146456893Sfenner { 146556893Sfenner unsigned long j; 146675115Sfenner TCHECK2(bp[0], 4); 146775115Sfenner j = EXTRACT_32BITS(bp); 146856893Sfenner bp += sizeof(int32_t); 146956893Sfenner 147056893Sfenner /* 147156893Sfenner * Who designed this chicken-shit protocol? 147256893Sfenner * 147356893Sfenner * Each character is stored as a 32-bit 147456893Sfenner * integer! 147556893Sfenner */ 147656893Sfenner 147756893Sfenner for (i = 0; i < j; i++) { 147856893Sfenner VECOUT(PRNAMEMAX); 147956893Sfenner } 148056893Sfenner if (j == 0) 148156893Sfenner printf(" <none!>"); 148256893Sfenner } 148356893Sfenner break; 148456893Sfenner case 508: /* Get CPS */ 148556893Sfenner case 514: /* List elements */ 148656893Sfenner case 517: /* List owned */ 148756893Sfenner case 518: /* Get CPS2 */ 148856893Sfenner case 519: /* Get host CPS */ 148956893Sfenner { 149056893Sfenner unsigned long j; 149175115Sfenner TCHECK2(bp[0], 4); 149275115Sfenner j = EXTRACT_32BITS(bp); 149356893Sfenner bp += sizeof(int32_t); 149456893Sfenner for (i = 0; i < j; i++) { 149556893Sfenner INTOUT(); 149656893Sfenner } 149756893Sfenner if (j == 0) 149856893Sfenner printf(" <none!>"); 149956893Sfenner } 150056893Sfenner break; 150156893Sfenner case 510: /* List max */ 150256893Sfenner printf(" maxuid"); 150356893Sfenner INTOUT(); 150456893Sfenner printf(" maxgid"); 150556893Sfenner INTOUT(); 150656893Sfenner break; 150756893Sfenner default: 150856893Sfenner ; 150956893Sfenner } 151056893Sfenner else { 151156893Sfenner /* 151256893Sfenner * Otherwise, just print out the return code 151356893Sfenner */ 151456893Sfenner printf(" errcode"); 151556893Sfenner INTOUT(); 151656893Sfenner } 151756893Sfenner 151856893Sfenner return; 151956893Sfenner 152056893Sfennertrunc: 152156893Sfenner printf(" [|pt]"); 152256893Sfenner} 152356893Sfenner 152456893Sfenner/* 152556893Sfenner * Handle calls to the AFS volume location database service 152656893Sfenner */ 152756893Sfenner 152856893Sfennerstatic void 152956893Sfennervldb_print(register const u_char *bp, int length) 153056893Sfenner{ 153156893Sfenner int vldb_op; 153256893Sfenner unsigned long i; 153356893Sfenner 1534127668Sbms if (length <= (int)sizeof(struct rx_header)) 153556893Sfenner return; 153656893Sfenner 1537127668Sbms if (snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) { 153856893Sfenner goto trunc; 153956893Sfenner } 154056893Sfenner 154156893Sfenner /* 154256893Sfenner * Print out the afs call we're invoking. The table used here was 154356893Sfenner * gleaned from vlserver/vldbint.xg 154456893Sfenner */ 154556893Sfenner 154675115Sfenner vldb_op = EXTRACT_32BITS(bp + sizeof(struct rx_header)); 154756893Sfenner 154856893Sfenner printf(" vldb"); 154956893Sfenner 155056893Sfenner if (is_ubik(vldb_op)) { 1551127668Sbms ubik_print(bp); 155256893Sfenner return; 155356893Sfenner } 155456893Sfenner printf(" call %s", tok2str(vldb_req, "op#%d", vldb_op)); 155556893Sfenner 155656893Sfenner /* 155756893Sfenner * Decode some of the arguments to the VLDB calls 155856893Sfenner */ 155956893Sfenner 156056893Sfenner bp += sizeof(struct rx_header) + 4; 156156893Sfenner 156256893Sfenner switch (vldb_op) { 156356893Sfenner case 501: /* Create new volume */ 156456893Sfenner case 517: /* Create entry N */ 156556893Sfenner VECOUT(VLNAMEMAX); 156656893Sfenner break; 156756893Sfenner case 502: /* Delete entry */ 156856893Sfenner case 503: /* Get entry by ID */ 156956893Sfenner case 507: /* Update entry */ 157056893Sfenner case 508: /* Set lock */ 157156893Sfenner case 509: /* Release lock */ 157256893Sfenner case 518: /* Get entry by ID N */ 157356893Sfenner printf(" volid"); 157456893Sfenner INTOUT(); 157575115Sfenner TCHECK2(bp[0], sizeof(int32_t)); 157675115Sfenner i = EXTRACT_32BITS(bp); 157756893Sfenner bp += sizeof(int32_t); 157856893Sfenner if (i <= 2) 157956893Sfenner printf(" type %s", voltype[i]); 158056893Sfenner break; 158156893Sfenner case 504: /* Get entry by name */ 158256893Sfenner case 519: /* Get entry by name N */ 158356893Sfenner case 524: /* Update entry by name */ 158456893Sfenner case 527: /* Get entry by name U */ 158556893Sfenner STROUT(VLNAMEMAX); 158656893Sfenner break; 158756893Sfenner case 505: /* Get new vol id */ 158856893Sfenner printf(" bump"); 158956893Sfenner INTOUT(); 159056893Sfenner break; 159156893Sfenner case 506: /* Replace entry */ 159256893Sfenner case 520: /* Replace entry N */ 159356893Sfenner printf(" volid"); 159456893Sfenner INTOUT(); 159575115Sfenner TCHECK2(bp[0], sizeof(int32_t)); 159675115Sfenner i = EXTRACT_32BITS(bp); 159756893Sfenner bp += sizeof(int32_t); 159856893Sfenner if (i <= 2) 159956893Sfenner printf(" type %s", voltype[i]); 160056893Sfenner VECOUT(VLNAMEMAX); 160156893Sfenner break; 160256893Sfenner case 510: /* List entry */ 160356893Sfenner case 521: /* List entry N */ 160456893Sfenner printf(" index"); 160556893Sfenner INTOUT(); 160656893Sfenner break; 160756893Sfenner default: 160856893Sfenner ; 160956893Sfenner } 161056893Sfenner 161156893Sfenner return; 161256893Sfenner 161356893Sfennertrunc: 161456893Sfenner printf(" [|vldb]"); 161556893Sfenner} 161656893Sfenner 161756893Sfenner/* 161856893Sfenner * Handle replies to the AFS volume location database service 161956893Sfenner */ 162056893Sfenner 162156893Sfennerstatic void 162256893Sfennervldb_reply_print(register const u_char *bp, int length, int32_t opcode) 162356893Sfenner{ 162456893Sfenner struct rx_header *rxh; 162556893Sfenner unsigned long i; 162656893Sfenner 1627127668Sbms if (length < (int)sizeof(struct rx_header)) 162856893Sfenner return; 162956893Sfenner 163056893Sfenner rxh = (struct rx_header *) bp; 163156893Sfenner 163256893Sfenner /* 163356893Sfenner * Print out the afs call we're invoking. The table used here was 163456893Sfenner * gleaned from vlserver/vldbint.xg. Check to see if it's a 163556893Sfenner * Ubik call, however. 163656893Sfenner */ 163756893Sfenner 163856893Sfenner printf(" vldb"); 163956893Sfenner 164056893Sfenner if (is_ubik(opcode)) { 164156893Sfenner ubik_reply_print(bp, length, opcode); 164256893Sfenner return; 164356893Sfenner } 164456893Sfenner 164556893Sfenner printf(" reply %s", tok2str(vldb_req, "op#%d", opcode)); 164656893Sfenner 164756893Sfenner bp += sizeof(struct rx_header); 164856893Sfenner 164956893Sfenner /* 165056893Sfenner * If it was a data packet, interpret the response 165156893Sfenner */ 165256893Sfenner 165356893Sfenner if (rxh->type == RX_PACKET_TYPE_DATA) 165456893Sfenner switch (opcode) { 165556893Sfenner case 510: /* List entry */ 165656893Sfenner printf(" count"); 165756893Sfenner INTOUT(); 165856893Sfenner printf(" nextindex"); 165956893Sfenner INTOUT(); 166056893Sfenner case 503: /* Get entry by id */ 166156893Sfenner case 504: /* Get entry by name */ 166256893Sfenner { unsigned long nservers, j; 166356893Sfenner VECOUT(VLNAMEMAX); 166475115Sfenner TCHECK2(bp[0], sizeof(int32_t)); 166556893Sfenner bp += sizeof(int32_t); 166656893Sfenner printf(" numservers"); 166775115Sfenner TCHECK2(bp[0], sizeof(int32_t)); 166875115Sfenner nservers = EXTRACT_32BITS(bp); 166956893Sfenner bp += sizeof(int32_t); 167056893Sfenner printf(" %lu", nservers); 167156893Sfenner printf(" servers"); 167256893Sfenner for (i = 0; i < 8; i++) { 167375115Sfenner TCHECK2(bp[0], sizeof(int32_t)); 167456893Sfenner if (i < nservers) 167556893Sfenner printf(" %s", 1676127668Sbms intoa(((struct in_addr *) bp)->s_addr)); 167756893Sfenner bp += sizeof(int32_t); 167856893Sfenner } 167956893Sfenner printf(" partitions"); 168056893Sfenner for (i = 0; i < 8; i++) { 168175115Sfenner TCHECK2(bp[0], sizeof(int32_t)); 168275115Sfenner j = EXTRACT_32BITS(bp); 168356893Sfenner if (i < nservers && j <= 26) 168456893Sfenner printf(" %c", 'a' + (int)j); 168556893Sfenner else if (i < nservers) 168656893Sfenner printf(" %lu", j); 168756893Sfenner bp += sizeof(int32_t); 168856893Sfenner } 168975115Sfenner TCHECK2(bp[0], 8 * sizeof(int32_t)); 169056893Sfenner bp += 8 * sizeof(int32_t); 169156893Sfenner printf(" rwvol"); 169256893Sfenner UINTOUT(); 169356893Sfenner printf(" rovol"); 169456893Sfenner UINTOUT(); 169556893Sfenner printf(" backup"); 169656893Sfenner UINTOUT(); 169756893Sfenner } 169856893Sfenner break; 169956893Sfenner case 505: /* Get new volume ID */ 170056893Sfenner printf(" newvol"); 170156893Sfenner UINTOUT(); 170256893Sfenner break; 170356893Sfenner case 521: /* List entry */ 170456893Sfenner case 529: /* List entry U */ 170556893Sfenner printf(" count"); 170656893Sfenner INTOUT(); 170756893Sfenner printf(" nextindex"); 170856893Sfenner INTOUT(); 170956893Sfenner case 518: /* Get entry by ID N */ 171056893Sfenner case 519: /* Get entry by name N */ 171156893Sfenner { unsigned long nservers, j; 171256893Sfenner VECOUT(VLNAMEMAX); 171356893Sfenner printf(" numservers"); 171475115Sfenner TCHECK2(bp[0], sizeof(int32_t)); 171575115Sfenner nservers = EXTRACT_32BITS(bp); 171656893Sfenner bp += sizeof(int32_t); 171756893Sfenner printf(" %lu", nservers); 171856893Sfenner printf(" servers"); 171956893Sfenner for (i = 0; i < 13; i++) { 172075115Sfenner TCHECK2(bp[0], sizeof(int32_t)); 172156893Sfenner if (i < nservers) 172256893Sfenner printf(" %s", 1723127668Sbms intoa(((struct in_addr *) bp)->s_addr)); 172456893Sfenner bp += sizeof(int32_t); 172556893Sfenner } 172656893Sfenner printf(" partitions"); 172756893Sfenner for (i = 0; i < 13; i++) { 172875115Sfenner TCHECK2(bp[0], sizeof(int32_t)); 172975115Sfenner j = EXTRACT_32BITS(bp); 173056893Sfenner if (i < nservers && j <= 26) 173156893Sfenner printf(" %c", 'a' + (int)j); 173256893Sfenner else if (i < nservers) 173356893Sfenner printf(" %lu", j); 173456893Sfenner bp += sizeof(int32_t); 173556893Sfenner } 173675115Sfenner TCHECK2(bp[0], 13 * sizeof(int32_t)); 173756893Sfenner bp += 13 * sizeof(int32_t); 173856893Sfenner printf(" rwvol"); 173956893Sfenner UINTOUT(); 174056893Sfenner printf(" rovol"); 174156893Sfenner UINTOUT(); 174256893Sfenner printf(" backup"); 174356893Sfenner UINTOUT(); 174456893Sfenner } 174556893Sfenner break; 174656893Sfenner case 526: /* Get entry by ID U */ 174756893Sfenner case 527: /* Get entry by name U */ 174856893Sfenner { unsigned long nservers, j; 174956893Sfenner VECOUT(VLNAMEMAX); 175056893Sfenner printf(" numservers"); 175175115Sfenner TCHECK2(bp[0], sizeof(int32_t)); 175275115Sfenner nservers = EXTRACT_32BITS(bp); 175356893Sfenner bp += sizeof(int32_t); 175456893Sfenner printf(" %lu", nservers); 175556893Sfenner printf(" servers"); 175656893Sfenner for (i = 0; i < 13; i++) { 175756893Sfenner if (i < nservers) { 175856893Sfenner printf(" afsuuid"); 175956893Sfenner AFSUUIDOUT(); 176056893Sfenner } else { 176175115Sfenner TCHECK2(bp[0], 44); 176256893Sfenner bp += 44; 176356893Sfenner } 176456893Sfenner } 176575115Sfenner TCHECK2(bp[0], 4 * 13); 176656893Sfenner bp += 4 * 13; 176756893Sfenner printf(" partitions"); 176856893Sfenner for (i = 0; i < 13; i++) { 176975115Sfenner TCHECK2(bp[0], sizeof(int32_t)); 177075115Sfenner j = EXTRACT_32BITS(bp); 177156893Sfenner if (i < nservers && j <= 26) 177256893Sfenner printf(" %c", 'a' + (int)j); 177356893Sfenner else if (i < nservers) 177456893Sfenner printf(" %lu", j); 177556893Sfenner bp += sizeof(int32_t); 177656893Sfenner } 177775115Sfenner TCHECK2(bp[0], 13 * sizeof(int32_t)); 177856893Sfenner bp += 13 * sizeof(int32_t); 177956893Sfenner printf(" rwvol"); 178056893Sfenner UINTOUT(); 178156893Sfenner printf(" rovol"); 178256893Sfenner UINTOUT(); 178356893Sfenner printf(" backup"); 178456893Sfenner UINTOUT(); 178556893Sfenner } 178656893Sfenner default: 178756893Sfenner ; 178856893Sfenner } 1789127668Sbms 179056893Sfenner else { 179156893Sfenner /* 179256893Sfenner * Otherwise, just print out the return code 179356893Sfenner */ 179456893Sfenner printf(" errcode"); 179556893Sfenner INTOUT(); 179656893Sfenner } 179756893Sfenner 179856893Sfenner return; 179956893Sfenner 180056893Sfennertrunc: 180156893Sfenner printf(" [|vldb]"); 180256893Sfenner} 180356893Sfenner 180456893Sfenner/* 180556893Sfenner * Handle calls to the AFS Kerberos Authentication service 180656893Sfenner */ 180756893Sfenner 180856893Sfennerstatic void 180956893Sfennerkauth_print(register const u_char *bp, int length) 181056893Sfenner{ 181156893Sfenner int kauth_op; 181256893Sfenner 1813127668Sbms if (length <= (int)sizeof(struct rx_header)) 181456893Sfenner return; 181556893Sfenner 1816127668Sbms if (snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) { 181756893Sfenner goto trunc; 181856893Sfenner } 181956893Sfenner 182056893Sfenner /* 182156893Sfenner * Print out the afs call we're invoking. The table used here was 182256893Sfenner * gleaned from kauth/kauth.rg 182356893Sfenner */ 182456893Sfenner 182575115Sfenner kauth_op = EXTRACT_32BITS(bp + sizeof(struct rx_header)); 182656893Sfenner 182756893Sfenner printf(" kauth"); 182856893Sfenner 182956893Sfenner if (is_ubik(kauth_op)) { 1830127668Sbms ubik_print(bp); 183156893Sfenner return; 183256893Sfenner } 183356893Sfenner 183456893Sfenner 183556893Sfenner printf(" call %s", tok2str(kauth_req, "op#%d", kauth_op)); 183656893Sfenner 183756893Sfenner /* 183856893Sfenner * Decode some of the arguments to the KA calls 183956893Sfenner */ 184056893Sfenner 184156893Sfenner bp += sizeof(struct rx_header) + 4; 184256893Sfenner 184356893Sfenner switch (kauth_op) { 184456893Sfenner case 1: /* Authenticate old */; 184556893Sfenner case 21: /* Authenticate */ 184656893Sfenner case 22: /* Authenticate-V2 */ 184756893Sfenner case 2: /* Change PW */ 184856893Sfenner case 5: /* Set fields */ 184956893Sfenner case 6: /* Create user */ 185056893Sfenner case 7: /* Delete user */ 185156893Sfenner case 8: /* Get entry */ 185256893Sfenner case 14: /* Unlock */ 185356893Sfenner case 15: /* Lock status */ 185456893Sfenner printf(" principal"); 185556893Sfenner STROUT(KANAMEMAX); 185656893Sfenner STROUT(KANAMEMAX); 185756893Sfenner break; 185856893Sfenner case 3: /* GetTicket-old */ 185956893Sfenner case 23: /* GetTicket */ 186056893Sfenner { 186156893Sfenner int i; 186256893Sfenner printf(" kvno"); 186356893Sfenner INTOUT(); 186456893Sfenner printf(" domain"); 186556893Sfenner STROUT(KANAMEMAX); 186675115Sfenner TCHECK2(bp[0], sizeof(int32_t)); 186775115Sfenner i = (int) EXTRACT_32BITS(bp); 186856893Sfenner bp += sizeof(int32_t); 186975115Sfenner TCHECK2(bp[0], i); 187056893Sfenner bp += i; 187156893Sfenner printf(" principal"); 187256893Sfenner STROUT(KANAMEMAX); 187356893Sfenner STROUT(KANAMEMAX); 187456893Sfenner break; 187556893Sfenner } 187656893Sfenner case 4: /* Set Password */ 187756893Sfenner printf(" principal"); 187856893Sfenner STROUT(KANAMEMAX); 187956893Sfenner STROUT(KANAMEMAX); 188056893Sfenner printf(" kvno"); 188156893Sfenner INTOUT(); 188256893Sfenner break; 188356893Sfenner case 12: /* Get password */ 188456893Sfenner printf(" name"); 188556893Sfenner STROUT(KANAMEMAX); 188656893Sfenner break; 188756893Sfenner default: 188856893Sfenner ; 188956893Sfenner } 189056893Sfenner 189156893Sfenner return; 189256893Sfenner 189356893Sfennertrunc: 189456893Sfenner printf(" [|kauth]"); 189556893Sfenner} 189656893Sfenner 189756893Sfenner/* 189856893Sfenner * Handle replies to the AFS Kerberos Authentication Service 189956893Sfenner */ 190056893Sfenner 190156893Sfennerstatic void 190256893Sfennerkauth_reply_print(register const u_char *bp, int length, int32_t opcode) 190356893Sfenner{ 190456893Sfenner struct rx_header *rxh; 190556893Sfenner 1906127668Sbms if (length <= (int)sizeof(struct rx_header)) 190756893Sfenner return; 190856893Sfenner 190956893Sfenner rxh = (struct rx_header *) bp; 191056893Sfenner 191156893Sfenner /* 191256893Sfenner * Print out the afs call we're invoking. The table used here was 191356893Sfenner * gleaned from kauth/kauth.rg 191456893Sfenner */ 1915127668Sbms 191656893Sfenner printf(" kauth"); 191756893Sfenner 191856893Sfenner if (is_ubik(opcode)) { 191956893Sfenner ubik_reply_print(bp, length, opcode); 192056893Sfenner return; 192156893Sfenner } 192256893Sfenner 192356893Sfenner printf(" reply %s", tok2str(kauth_req, "op#%d", opcode)); 192456893Sfenner 192556893Sfenner bp += sizeof(struct rx_header); 192656893Sfenner 192756893Sfenner /* 192856893Sfenner * If it was a data packet, interpret the response. 192956893Sfenner */ 193056893Sfenner 193156893Sfenner if (rxh->type == RX_PACKET_TYPE_DATA) 193256893Sfenner /* Well, no, not really. Leave this for later */ 193356893Sfenner ; 193456893Sfenner else { 193556893Sfenner /* 193656893Sfenner * Otherwise, just print out the return code 193756893Sfenner */ 193856893Sfenner printf(" errcode"); 193956893Sfenner INTOUT(); 194056893Sfenner } 194156893Sfenner 194256893Sfenner return; 194356893Sfenner 194456893Sfennertrunc: 194556893Sfenner printf(" [|kauth]"); 194656893Sfenner} 194756893Sfenner 194856893Sfenner/* 194956893Sfenner * Handle calls to the AFS Volume location service 195056893Sfenner */ 195156893Sfenner 195256893Sfennerstatic void 195356893Sfennervol_print(register const u_char *bp, int length) 195456893Sfenner{ 195556893Sfenner int vol_op; 195656893Sfenner 1957127668Sbms if (length <= (int)sizeof(struct rx_header)) 195856893Sfenner return; 195956893Sfenner 1960127668Sbms if (snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) { 196156893Sfenner goto trunc; 196256893Sfenner } 196356893Sfenner 196456893Sfenner /* 196556893Sfenner * Print out the afs call we're invoking. The table used here was 196656893Sfenner * gleaned from volser/volint.xg 196756893Sfenner */ 196856893Sfenner 196975115Sfenner vol_op = EXTRACT_32BITS(bp + sizeof(struct rx_header)); 197056893Sfenner 197156893Sfenner printf(" vol call %s", tok2str(vol_req, "op#%d", vol_op)); 197256893Sfenner 1973190207Srpaulo bp += sizeof(struct rx_header) + 4; 197456893Sfenner 1975190207Srpaulo switch (vol_op) { 1976190207Srpaulo case 100: /* Create volume */ 1977190207Srpaulo printf(" partition"); 1978190207Srpaulo UINTOUT(); 1979190207Srpaulo printf(" name"); 1980190207Srpaulo STROUT(AFSNAMEMAX); 1981190207Srpaulo printf(" type"); 1982190207Srpaulo UINTOUT(); 1983190207Srpaulo printf(" parent"); 1984190207Srpaulo UINTOUT(); 1985190207Srpaulo break; 1986190207Srpaulo case 101: /* Delete volume */ 1987190207Srpaulo case 107: /* Get flags */ 1988190207Srpaulo printf(" trans"); 1989190207Srpaulo UINTOUT(); 1990190207Srpaulo break; 1991190207Srpaulo case 102: /* Restore */ 1992190207Srpaulo printf(" totrans"); 1993190207Srpaulo UINTOUT(); 1994190207Srpaulo printf(" flags"); 1995190207Srpaulo UINTOUT(); 1996190207Srpaulo break; 1997190207Srpaulo case 103: /* Forward */ 1998190207Srpaulo printf(" fromtrans"); 1999190207Srpaulo UINTOUT(); 2000190207Srpaulo printf(" fromdate"); 2001190207Srpaulo DATEOUT(); 2002190207Srpaulo DESTSERVEROUT(); 2003190207Srpaulo printf(" desttrans"); 2004190207Srpaulo INTOUT(); 2005190207Srpaulo break; 2006190207Srpaulo case 104: /* End trans */ 2007190207Srpaulo printf(" trans"); 2008190207Srpaulo UINTOUT(); 2009190207Srpaulo break; 2010190207Srpaulo case 105: /* Clone */ 2011190207Srpaulo printf(" trans"); 2012190207Srpaulo UINTOUT(); 2013190207Srpaulo printf(" purgevol"); 2014190207Srpaulo UINTOUT(); 2015190207Srpaulo printf(" newtype"); 2016190207Srpaulo UINTOUT(); 2017190207Srpaulo printf(" newname"); 2018190207Srpaulo STROUT(AFSNAMEMAX); 2019190207Srpaulo break; 2020190207Srpaulo case 106: /* Set flags */ 2021190207Srpaulo printf(" trans"); 2022190207Srpaulo UINTOUT(); 2023190207Srpaulo printf(" flags"); 2024190207Srpaulo UINTOUT(); 2025190207Srpaulo break; 2026190207Srpaulo case 108: /* Trans create */ 2027190207Srpaulo printf(" vol"); 2028190207Srpaulo UINTOUT(); 2029190207Srpaulo printf(" partition"); 2030190207Srpaulo UINTOUT(); 2031190207Srpaulo printf(" flags"); 2032190207Srpaulo UINTOUT(); 2033190207Srpaulo break; 2034190207Srpaulo case 109: /* Dump */ 2035190207Srpaulo case 655537: /* Get size */ 2036190207Srpaulo printf(" fromtrans"); 2037190207Srpaulo UINTOUT(); 2038190207Srpaulo printf(" fromdate"); 2039190207Srpaulo DATEOUT(); 2040190207Srpaulo break; 2041190207Srpaulo case 110: /* Get n-th volume */ 2042190207Srpaulo printf(" index"); 2043190207Srpaulo UINTOUT(); 2044190207Srpaulo break; 2045190207Srpaulo case 111: /* Set forwarding */ 2046190207Srpaulo printf(" tid"); 2047190207Srpaulo UINTOUT(); 2048190207Srpaulo printf(" newsite"); 2049190207Srpaulo UINTOUT(); 2050190207Srpaulo break; 2051190207Srpaulo case 112: /* Get name */ 2052190207Srpaulo case 113: /* Get status */ 2053190207Srpaulo printf(" tid"); 2054190207Srpaulo break; 2055190207Srpaulo case 114: /* Signal restore */ 2056190207Srpaulo printf(" name"); 2057190207Srpaulo STROUT(AFSNAMEMAX); 2058190207Srpaulo printf(" type"); 2059190207Srpaulo UINTOUT(); 2060190207Srpaulo printf(" pid"); 2061190207Srpaulo UINTOUT(); 2062190207Srpaulo printf(" cloneid"); 2063190207Srpaulo UINTOUT(); 2064190207Srpaulo break; 2065190207Srpaulo case 116: /* List volumes */ 2066190207Srpaulo printf(" partition"); 2067190207Srpaulo UINTOUT(); 2068190207Srpaulo printf(" flags"); 2069190207Srpaulo UINTOUT(); 2070190207Srpaulo break; 2071190207Srpaulo case 117: /* Set id types */ 2072190207Srpaulo printf(" tid"); 2073190207Srpaulo UINTOUT(); 2074190207Srpaulo printf(" name"); 2075190207Srpaulo STROUT(AFSNAMEMAX); 2076190207Srpaulo printf(" type"); 2077190207Srpaulo UINTOUT(); 2078190207Srpaulo printf(" pid"); 2079190207Srpaulo UINTOUT(); 2080190207Srpaulo printf(" clone"); 2081190207Srpaulo UINTOUT(); 2082190207Srpaulo printf(" backup"); 2083190207Srpaulo UINTOUT(); 2084190207Srpaulo break; 2085190207Srpaulo case 119: /* Partition info */ 2086190207Srpaulo printf(" name"); 2087190207Srpaulo STROUT(AFSNAMEMAX); 2088190207Srpaulo break; 2089190207Srpaulo case 120: /* Reclone */ 2090190207Srpaulo printf(" tid"); 2091190207Srpaulo UINTOUT(); 2092190207Srpaulo break; 2093190207Srpaulo case 121: /* List one volume */ 2094190207Srpaulo case 122: /* Nuke volume */ 2095190207Srpaulo case 124: /* Extended List volumes */ 2096190207Srpaulo case 125: /* Extended List one volume */ 2097190207Srpaulo case 65536: /* Convert RO to RW volume */ 2098190207Srpaulo printf(" partid"); 2099190207Srpaulo UINTOUT(); 2100190207Srpaulo printf(" volid"); 2101190207Srpaulo UINTOUT(); 2102190207Srpaulo break; 2103190207Srpaulo case 123: /* Set date */ 2104190207Srpaulo printf(" tid"); 2105190207Srpaulo UINTOUT(); 2106190207Srpaulo printf(" date"); 2107190207Srpaulo DATEOUT(); 2108190207Srpaulo break; 2109190207Srpaulo case 126: /* Set info */ 2110190207Srpaulo printf(" tid"); 2111190207Srpaulo UINTOUT(); 2112190207Srpaulo break; 2113190207Srpaulo case 128: /* Forward multiple */ 2114190207Srpaulo printf(" fromtrans"); 2115190207Srpaulo UINTOUT(); 2116190207Srpaulo printf(" fromdate"); 2117190207Srpaulo DATEOUT(); 2118190207Srpaulo { 2119190207Srpaulo unsigned long i, j; 2120190207Srpaulo TCHECK2(bp[0], 4); 2121190207Srpaulo j = EXTRACT_32BITS(bp); 2122190207Srpaulo bp += sizeof(int32_t); 2123190207Srpaulo for (i = 0; i < j; i++) { 2124190207Srpaulo DESTSERVEROUT(); 2125190207Srpaulo if (i != j - 1) 2126190207Srpaulo printf(","); 2127190207Srpaulo } 2128190207Srpaulo if (j == 0) 2129190207Srpaulo printf(" <none!>"); 2130190207Srpaulo } 2131190207Srpaulo break; 2132190207Srpaulo case 65538: /* Dump version 2 */ 2133190207Srpaulo printf(" fromtrans"); 2134190207Srpaulo UINTOUT(); 2135190207Srpaulo printf(" fromdate"); 2136190207Srpaulo DATEOUT(); 2137190207Srpaulo printf(" flags"); 2138190207Srpaulo UINTOUT(); 2139190207Srpaulo break; 2140190207Srpaulo default: 2141190207Srpaulo ; 2142190207Srpaulo } 214356893Sfenner return; 214456893Sfenner 214556893Sfennertrunc: 214656893Sfenner printf(" [|vol]"); 214756893Sfenner} 214856893Sfenner 214956893Sfenner/* 215056893Sfenner * Handle replies to the AFS Volume Service 215156893Sfenner */ 215256893Sfenner 215356893Sfennerstatic void 215456893Sfennervol_reply_print(register const u_char *bp, int length, int32_t opcode) 215556893Sfenner{ 215656893Sfenner struct rx_header *rxh; 215756893Sfenner 2158127668Sbms if (length <= (int)sizeof(struct rx_header)) 215956893Sfenner return; 216056893Sfenner 216156893Sfenner rxh = (struct rx_header *) bp; 216256893Sfenner 216356893Sfenner /* 216456893Sfenner * Print out the afs call we're invoking. The table used here was 216556893Sfenner * gleaned from volser/volint.xg 216656893Sfenner */ 2167127668Sbms 216856893Sfenner printf(" vol reply %s", tok2str(vol_req, "op#%d", opcode)); 216956893Sfenner 217056893Sfenner bp += sizeof(struct rx_header); 217156893Sfenner 217256893Sfenner /* 217356893Sfenner * If it was a data packet, interpret the response. 217456893Sfenner */ 217556893Sfenner 2176190207Srpaulo if (rxh->type == RX_PACKET_TYPE_DATA) { 2177190207Srpaulo switch (opcode) { 2178190207Srpaulo case 100: /* Create volume */ 2179190207Srpaulo printf(" volid"); 2180190207Srpaulo UINTOUT(); 2181190207Srpaulo printf(" trans"); 2182190207Srpaulo UINTOUT(); 2183190207Srpaulo break; 2184190207Srpaulo case 104: /* End transaction */ 2185190207Srpaulo UINTOUT(); 2186190207Srpaulo break; 2187190207Srpaulo case 105: /* Clone */ 2188190207Srpaulo printf(" newvol"); 2189190207Srpaulo UINTOUT(); 2190190207Srpaulo break; 2191190207Srpaulo case 107: /* Get flags */ 2192190207Srpaulo UINTOUT(); 2193190207Srpaulo break; 2194190207Srpaulo case 108: /* Transaction create */ 2195190207Srpaulo printf(" trans"); 2196190207Srpaulo UINTOUT(); 2197190207Srpaulo break; 2198190207Srpaulo case 110: /* Get n-th volume */ 2199190207Srpaulo printf(" volume"); 2200190207Srpaulo UINTOUT(); 2201190207Srpaulo printf(" partition"); 2202190207Srpaulo UINTOUT(); 2203190207Srpaulo break; 2204190207Srpaulo case 112: /* Get name */ 2205190207Srpaulo STROUT(AFSNAMEMAX); 2206190207Srpaulo break; 2207190207Srpaulo case 113: /* Get status */ 2208190207Srpaulo printf(" volid"); 2209190207Srpaulo UINTOUT(); 2210190207Srpaulo printf(" nextuniq"); 2211190207Srpaulo UINTOUT(); 2212190207Srpaulo printf(" type"); 2213190207Srpaulo UINTOUT(); 2214190207Srpaulo printf(" parentid"); 2215190207Srpaulo UINTOUT(); 2216190207Srpaulo printf(" clone"); 2217190207Srpaulo UINTOUT(); 2218190207Srpaulo printf(" backup"); 2219190207Srpaulo UINTOUT(); 2220190207Srpaulo printf(" restore"); 2221190207Srpaulo UINTOUT(); 2222190207Srpaulo printf(" maxquota"); 2223190207Srpaulo UINTOUT(); 2224190207Srpaulo printf(" minquota"); 2225190207Srpaulo UINTOUT(); 2226190207Srpaulo printf(" owner"); 2227190207Srpaulo UINTOUT(); 2228190207Srpaulo printf(" create"); 2229190207Srpaulo DATEOUT(); 2230190207Srpaulo printf(" access"); 2231190207Srpaulo DATEOUT(); 2232190207Srpaulo printf(" update"); 2233190207Srpaulo DATEOUT(); 2234190207Srpaulo printf(" expire"); 2235190207Srpaulo DATEOUT(); 2236190207Srpaulo printf(" backup"); 2237190207Srpaulo DATEOUT(); 2238190207Srpaulo printf(" copy"); 2239190207Srpaulo DATEOUT(); 2240190207Srpaulo break; 2241190207Srpaulo case 115: /* Old list partitions */ 2242190207Srpaulo break; 2243190207Srpaulo case 116: /* List volumes */ 2244190207Srpaulo case 121: /* List one volume */ 2245190207Srpaulo { 2246190207Srpaulo unsigned long i, j; 2247190207Srpaulo TCHECK2(bp[0], 4); 2248190207Srpaulo j = EXTRACT_32BITS(bp); 2249190207Srpaulo bp += sizeof(int32_t); 2250190207Srpaulo for (i = 0; i < j; i++) { 2251190207Srpaulo printf(" name"); 2252190207Srpaulo VECOUT(32); 2253190207Srpaulo printf(" volid"); 2254190207Srpaulo UINTOUT(); 2255190207Srpaulo printf(" type"); 2256190207Srpaulo bp += sizeof(int32_t) * 21; 2257190207Srpaulo if (i != j - 1) 2258190207Srpaulo printf(","); 2259190207Srpaulo } 2260190207Srpaulo if (j == 0) 2261190207Srpaulo printf(" <none!>"); 2262190207Srpaulo } 2263190207Srpaulo break; 2264190207Srpaulo 2265190207Srpaulo 2266190207Srpaulo default: 2267190207Srpaulo ; 2268190207Srpaulo } 2269190207Srpaulo } else { 227056893Sfenner /* 227156893Sfenner * Otherwise, just print out the return code 227256893Sfenner */ 227356893Sfenner printf(" errcode"); 227456893Sfenner INTOUT(); 227556893Sfenner } 227656893Sfenner 227756893Sfenner return; 227856893Sfenner 227956893Sfennertrunc: 228056893Sfenner printf(" [|vol]"); 228156893Sfenner} 228256893Sfenner 228356893Sfenner/* 228456893Sfenner * Handle calls to the AFS BOS service 228556893Sfenner */ 228656893Sfenner 228756893Sfennerstatic void 228856893Sfennerbos_print(register const u_char *bp, int length) 228956893Sfenner{ 229056893Sfenner int bos_op; 229156893Sfenner 2292127668Sbms if (length <= (int)sizeof(struct rx_header)) 229356893Sfenner return; 229456893Sfenner 2295127668Sbms if (snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) { 229656893Sfenner goto trunc; 229756893Sfenner } 229856893Sfenner 229956893Sfenner /* 230056893Sfenner * Print out the afs call we're invoking. The table used here was 230156893Sfenner * gleaned from bozo/bosint.xg 230256893Sfenner */ 230356893Sfenner 230475115Sfenner bos_op = EXTRACT_32BITS(bp + sizeof(struct rx_header)); 230556893Sfenner 230656893Sfenner printf(" bos call %s", tok2str(bos_req, "op#%d", bos_op)); 230756893Sfenner 230856893Sfenner /* 230956893Sfenner * Decode some of the arguments to the BOS calls 231056893Sfenner */ 231156893Sfenner 231256893Sfenner bp += sizeof(struct rx_header) + 4; 231356893Sfenner 231456893Sfenner switch (bos_op) { 231556893Sfenner case 80: /* Create B node */ 231656893Sfenner printf(" type"); 231756893Sfenner STROUT(BOSNAMEMAX); 231856893Sfenner printf(" instance"); 231956893Sfenner STROUT(BOSNAMEMAX); 232056893Sfenner break; 232156893Sfenner case 81: /* Delete B node */ 232256893Sfenner case 83: /* Get status */ 232356893Sfenner case 85: /* Get instance info */ 232456893Sfenner case 87: /* Add super user */ 232556893Sfenner case 88: /* Delete super user */ 232656893Sfenner case 93: /* Set cell name */ 232756893Sfenner case 96: /* Add cell host */ 232856893Sfenner case 97: /* Delete cell host */ 232956893Sfenner case 104: /* Restart */ 233056893Sfenner case 106: /* Uninstall */ 233156893Sfenner case 108: /* Exec */ 233256893Sfenner case 112: /* Getlog */ 233356893Sfenner case 114: /* Get instance strings */ 233456893Sfenner STROUT(BOSNAMEMAX); 233556893Sfenner break; 233656893Sfenner case 82: /* Set status */ 233756893Sfenner case 98: /* Set T status */ 233856893Sfenner STROUT(BOSNAMEMAX); 233956893Sfenner printf(" status"); 234056893Sfenner INTOUT(); 234156893Sfenner break; 234256893Sfenner case 86: /* Get instance parm */ 234356893Sfenner STROUT(BOSNAMEMAX); 234456893Sfenner printf(" num"); 234556893Sfenner INTOUT(); 234656893Sfenner break; 234756893Sfenner case 84: /* Enumerate instance */ 234856893Sfenner case 89: /* List super users */ 234956893Sfenner case 90: /* List keys */ 235056893Sfenner case 91: /* Add key */ 235156893Sfenner case 92: /* Delete key */ 235256893Sfenner case 95: /* Get cell host */ 235356893Sfenner INTOUT(); 235456893Sfenner break; 235556893Sfenner case 105: /* Install */ 235656893Sfenner STROUT(BOSNAMEMAX); 235756893Sfenner printf(" size"); 235856893Sfenner INTOUT(); 235956893Sfenner printf(" flags"); 236056893Sfenner INTOUT(); 236156893Sfenner printf(" date"); 236256893Sfenner INTOUT(); 236356893Sfenner break; 236456893Sfenner default: 236556893Sfenner ; 236656893Sfenner } 236756893Sfenner 236856893Sfenner return; 236956893Sfenner 237056893Sfennertrunc: 237156893Sfenner printf(" [|bos]"); 237256893Sfenner} 237356893Sfenner 237456893Sfenner/* 237556893Sfenner * Handle replies to the AFS BOS Service 237656893Sfenner */ 237756893Sfenner 237856893Sfennerstatic void 237956893Sfennerbos_reply_print(register const u_char *bp, int length, int32_t opcode) 238056893Sfenner{ 238156893Sfenner struct rx_header *rxh; 238256893Sfenner 2383127668Sbms if (length <= (int)sizeof(struct rx_header)) 238456893Sfenner return; 238556893Sfenner 238656893Sfenner rxh = (struct rx_header *) bp; 238756893Sfenner 238856893Sfenner /* 238956893Sfenner * Print out the afs call we're invoking. The table used here was 239056893Sfenner * gleaned from volser/volint.xg 239156893Sfenner */ 2392127668Sbms 239356893Sfenner printf(" bos reply %s", tok2str(bos_req, "op#%d", opcode)); 239456893Sfenner 239556893Sfenner bp += sizeof(struct rx_header); 239656893Sfenner 239756893Sfenner /* 239856893Sfenner * If it was a data packet, interpret the response. 239956893Sfenner */ 240056893Sfenner 240156893Sfenner if (rxh->type == RX_PACKET_TYPE_DATA) 240256893Sfenner /* Well, no, not really. Leave this for later */ 240356893Sfenner ; 240456893Sfenner else { 240556893Sfenner /* 240656893Sfenner * Otherwise, just print out the return code 240756893Sfenner */ 240856893Sfenner printf(" errcode"); 240956893Sfenner INTOUT(); 241056893Sfenner } 241156893Sfenner 241256893Sfenner return; 241356893Sfenner 241456893Sfennertrunc: 241556893Sfenner printf(" [|bos]"); 241656893Sfenner} 241756893Sfenner 241856893Sfenner/* 241956893Sfenner * Check to see if this is a Ubik opcode. 242056893Sfenner */ 242156893Sfenner 242256893Sfennerstatic int 242356893Sfenneris_ubik(u_int32_t opcode) 242456893Sfenner{ 242556893Sfenner if ((opcode >= VOTE_LOW && opcode <= VOTE_HIGH) || 242656893Sfenner (opcode >= DISK_LOW && opcode <= DISK_HIGH)) 242756893Sfenner return(1); 242856893Sfenner else 242956893Sfenner return(0); 243056893Sfenner} 243156893Sfenner 243256893Sfenner/* 243356893Sfenner * Handle Ubik opcodes to any one of the replicated database services 243456893Sfenner */ 243556893Sfenner 243656893Sfennerstatic void 2437127668Sbmsubik_print(register const u_char *bp) 243856893Sfenner{ 243956893Sfenner int ubik_op; 244056893Sfenner int32_t temp; 244156893Sfenner 244256893Sfenner /* 244356893Sfenner * Print out the afs call we're invoking. The table used here was 244456893Sfenner * gleaned from ubik/ubik_int.xg 244556893Sfenner */ 244656893Sfenner 244775115Sfenner ubik_op = EXTRACT_32BITS(bp + sizeof(struct rx_header)); 244856893Sfenner 244956893Sfenner printf(" ubik call %s", tok2str(ubik_req, "op#%d", ubik_op)); 245056893Sfenner 245156893Sfenner /* 245256893Sfenner * Decode some of the arguments to the Ubik calls 245356893Sfenner */ 245456893Sfenner 245556893Sfenner bp += sizeof(struct rx_header) + 4; 245656893Sfenner 245756893Sfenner switch (ubik_op) { 245856893Sfenner case 10000: /* Beacon */ 245975115Sfenner TCHECK2(bp[0], 4); 246075115Sfenner temp = EXTRACT_32BITS(bp); 246156893Sfenner bp += sizeof(int32_t); 246256893Sfenner printf(" syncsite %s", temp ? "yes" : "no"); 246356893Sfenner printf(" votestart"); 246456893Sfenner DATEOUT(); 246556893Sfenner printf(" dbversion"); 246656893Sfenner UBIK_VERSIONOUT(); 246756893Sfenner printf(" tid"); 246856893Sfenner UBIK_VERSIONOUT(); 246956893Sfenner break; 247056893Sfenner case 10003: /* Get sync site */ 247156893Sfenner printf(" site"); 247256893Sfenner UINTOUT(); 247356893Sfenner break; 247456893Sfenner case 20000: /* Begin */ 247556893Sfenner case 20001: /* Commit */ 247656893Sfenner case 20007: /* Abort */ 247756893Sfenner case 20008: /* Release locks */ 247856893Sfenner case 20010: /* Writev */ 247956893Sfenner printf(" tid"); 248056893Sfenner UBIK_VERSIONOUT(); 248156893Sfenner break; 248256893Sfenner case 20002: /* Lock */ 248356893Sfenner printf(" tid"); 248456893Sfenner UBIK_VERSIONOUT(); 248556893Sfenner printf(" file"); 248656893Sfenner INTOUT(); 248756893Sfenner printf(" pos"); 248856893Sfenner INTOUT(); 248956893Sfenner printf(" length"); 249056893Sfenner INTOUT(); 249175115Sfenner temp = EXTRACT_32BITS(bp); 249256893Sfenner bp += sizeof(int32_t); 249356893Sfenner tok2str(ubik_lock_types, "type %d", temp); 249456893Sfenner break; 249556893Sfenner case 20003: /* Write */ 249656893Sfenner printf(" tid"); 249756893Sfenner UBIK_VERSIONOUT(); 249856893Sfenner printf(" file"); 249956893Sfenner INTOUT(); 250056893Sfenner printf(" pos"); 250156893Sfenner INTOUT(); 250256893Sfenner break; 250356893Sfenner case 20005: /* Get file */ 250456893Sfenner printf(" file"); 250556893Sfenner INTOUT(); 250656893Sfenner break; 250756893Sfenner case 20006: /* Send file */ 250856893Sfenner printf(" file"); 250956893Sfenner INTOUT(); 251056893Sfenner printf(" length"); 251156893Sfenner INTOUT(); 251256893Sfenner printf(" dbversion"); 251356893Sfenner UBIK_VERSIONOUT(); 251456893Sfenner break; 251556893Sfenner case 20009: /* Truncate */ 251656893Sfenner printf(" tid"); 251756893Sfenner UBIK_VERSIONOUT(); 251856893Sfenner printf(" file"); 251956893Sfenner INTOUT(); 252056893Sfenner printf(" length"); 252156893Sfenner INTOUT(); 252256893Sfenner break; 252356893Sfenner case 20012: /* Set version */ 252456893Sfenner printf(" tid"); 252556893Sfenner UBIK_VERSIONOUT(); 252656893Sfenner printf(" oldversion"); 252756893Sfenner UBIK_VERSIONOUT(); 252856893Sfenner printf(" newversion"); 252956893Sfenner UBIK_VERSIONOUT(); 253056893Sfenner break; 253156893Sfenner default: 253256893Sfenner ; 253356893Sfenner } 253456893Sfenner 253556893Sfenner return; 253656893Sfenner 253756893Sfennertrunc: 253856893Sfenner printf(" [|ubik]"); 253956893Sfenner} 254056893Sfenner 254156893Sfenner/* 254256893Sfenner * Handle Ubik replies to any one of the replicated database services 254356893Sfenner */ 254456893Sfenner 254556893Sfennerstatic void 254656893Sfennerubik_reply_print(register const u_char *bp, int length, int32_t opcode) 254756893Sfenner{ 254856893Sfenner struct rx_header *rxh; 254956893Sfenner 2550127668Sbms if (length < (int)sizeof(struct rx_header)) 255156893Sfenner return; 255256893Sfenner 255356893Sfenner rxh = (struct rx_header *) bp; 255456893Sfenner 255556893Sfenner /* 255656893Sfenner * Print out the ubik call we're invoking. This table was gleaned 255756893Sfenner * from ubik/ubik_int.xg 255856893Sfenner */ 255956893Sfenner 256056893Sfenner printf(" ubik reply %s", tok2str(ubik_req, "op#%d", opcode)); 256156893Sfenner 256256893Sfenner bp += sizeof(struct rx_header); 256356893Sfenner 256456893Sfenner /* 256556893Sfenner * If it was a data packet, print out the arguments to the Ubik calls 256656893Sfenner */ 2567127668Sbms 256856893Sfenner if (rxh->type == RX_PACKET_TYPE_DATA) 256956893Sfenner switch (opcode) { 257056893Sfenner case 10000: /* Beacon */ 257156893Sfenner printf(" vote no"); 257256893Sfenner break; 257356893Sfenner case 20004: /* Get version */ 257456893Sfenner printf(" dbversion"); 257556893Sfenner UBIK_VERSIONOUT(); 257656893Sfenner break; 257756893Sfenner default: 257856893Sfenner ; 257956893Sfenner } 2580127668Sbms 258156893Sfenner /* 258256893Sfenner * Otherwise, print out "yes" it it was a beacon packet (because 258356893Sfenner * that's how yes votes are returned, go figure), otherwise 258456893Sfenner * just print out the error code. 258556893Sfenner */ 258656893Sfenner 258756893Sfenner else 258856893Sfenner switch (opcode) { 258956893Sfenner case 10000: /* Beacon */ 259056893Sfenner printf(" vote yes until"); 259156893Sfenner DATEOUT(); 259256893Sfenner break; 259356893Sfenner default: 259456893Sfenner printf(" errcode"); 259556893Sfenner INTOUT(); 259656893Sfenner } 259756893Sfenner 259856893Sfenner return; 259956893Sfenner 260056893Sfennertrunc: 260156893Sfenner printf(" [|ubik]"); 260256893Sfenner} 260375115Sfenner 260475115Sfenner/* 260575115Sfenner * Handle RX ACK packets. 260675115Sfenner */ 260775115Sfenner 260875115Sfennerstatic void 260975115Sfennerrx_ack_print(register const u_char *bp, int length) 261075115Sfenner{ 261175115Sfenner struct rx_ackPacket *rxa; 261275115Sfenner int i, start, last; 2613172683Smlaier u_int32_t firstPacket; 261475115Sfenner 2615127668Sbms if (length < (int)sizeof(struct rx_header)) 261675115Sfenner return; 261775115Sfenner 261875115Sfenner bp += sizeof(struct rx_header); 261975115Sfenner 262075115Sfenner /* 262175115Sfenner * This may seem a little odd .... the rx_ackPacket structure 262275115Sfenner * contains an array of individual packet acknowledgements 262375115Sfenner * (used for selective ack/nack), but since it's variable in size, 262475115Sfenner * we don't want to truncate based on the size of the whole 262575115Sfenner * rx_ackPacket structure. 262675115Sfenner */ 262775115Sfenner 262875115Sfenner TCHECK2(bp[0], sizeof(struct rx_ackPacket) - RX_MAXACKS); 262975115Sfenner 263075115Sfenner rxa = (struct rx_ackPacket *) bp; 263175115Sfenner bp += (sizeof(struct rx_ackPacket) - RX_MAXACKS); 263275115Sfenner 263375115Sfenner /* 263475115Sfenner * Print out a few useful things from the ack packet structure 263575115Sfenner */ 263675115Sfenner 263775115Sfenner if (vflag > 2) 263875115Sfenner printf(" bufspace %d maxskew %d", 263975115Sfenner (int) EXTRACT_16BITS(&rxa->bufferSpace), 264075115Sfenner (int) EXTRACT_16BITS(&rxa->maxSkew)); 2641127668Sbms 2642172683Smlaier firstPacket = EXTRACT_32BITS(&rxa->firstPacket); 264375115Sfenner printf(" first %d serial %d reason %s", 2644172683Smlaier firstPacket, EXTRACT_32BITS(&rxa->serial), 264575115Sfenner tok2str(rx_ack_reasons, "#%d", (int) rxa->reason)); 2646127668Sbms 264775115Sfenner /* 264875115Sfenner * Okay, now we print out the ack array. The way _this_ works 264975115Sfenner * is that we start at "first", and step through the ack array. 265075115Sfenner * If we have a contiguous range of acks/nacks, try to 265175115Sfenner * collapse them into a range. 265275115Sfenner * 265375115Sfenner * If you're really clever, you might have noticed that this 265475115Sfenner * doesn't seem quite correct. Specifically, due to structure 265575115Sfenner * padding, sizeof(struct rx_ackPacket) - RX_MAXACKS won't actually 265675115Sfenner * yield the start of the ack array (because RX_MAXACKS is 255 265775115Sfenner * and the structure will likely get padded to a 2 or 4 byte 265875115Sfenner * boundary). However, this is the way it's implemented inside 2659127668Sbms * of AFS - the start of the extra fields are at 266075115Sfenner * sizeof(struct rx_ackPacket) - RX_MAXACKS + nAcks, which _isn't_ 266175115Sfenner * the exact start of the ack array. Sigh. That's why we aren't 266275115Sfenner * using bp, but instead use rxa->acks[]. But nAcks gets added 266375115Sfenner * to bp after this, so bp ends up at the right spot. Go figure. 266475115Sfenner */ 266575115Sfenner 266675115Sfenner if (rxa->nAcks != 0) { 266775115Sfenner 266875115Sfenner TCHECK2(bp[0], rxa->nAcks); 266975115Sfenner 267075115Sfenner /* 267175115Sfenner * Sigh, this is gross, but it seems to work to collapse 267275115Sfenner * ranges correctly. 267375115Sfenner */ 267475115Sfenner 267575115Sfenner for (i = 0, start = last = -2; i < rxa->nAcks; i++) 267675115Sfenner if (rxa->acks[i] == RX_ACK_TYPE_ACK) { 267775115Sfenner 267875115Sfenner /* 267975115Sfenner * I figured this deserved _some_ explanation. 268075115Sfenner * First, print "acked" and the packet seq 268175115Sfenner * number if this is the first time we've 268275115Sfenner * seen an acked packet. 268375115Sfenner */ 268475115Sfenner 268575115Sfenner if (last == -2) { 268675115Sfenner printf(" acked %d", 2687172683Smlaier firstPacket + i); 268875115Sfenner start = i; 268975115Sfenner } 269075115Sfenner 269175115Sfenner /* 269275115Sfenner * Otherwise, if the there is a skip in 269375115Sfenner * the range (such as an nacked packet in 269475115Sfenner * the middle of some acked packets), 269575115Sfenner * then print the current packet number 269675115Sfenner * seperated from the last number by 269775115Sfenner * a comma. 269875115Sfenner */ 269975115Sfenner 270075115Sfenner else if (last != i - 1) { 2701172683Smlaier printf(",%d", firstPacket + i); 270275115Sfenner start = i; 270375115Sfenner } 270475115Sfenner 270575115Sfenner /* 270675115Sfenner * We always set last to the value of 270775115Sfenner * the last ack we saw. Conversely, start 270875115Sfenner * is set to the value of the first ack 270975115Sfenner * we saw in a range. 271075115Sfenner */ 271175115Sfenner 271275115Sfenner last = i; 271375115Sfenner 271475115Sfenner /* 271575115Sfenner * Okay, this bit a code gets executed when 271675115Sfenner * we hit a nack ... in _this_ case we 271775115Sfenner * want to print out the range of packets 271875115Sfenner * that were acked, so we need to print 271975115Sfenner * the _previous_ packet number seperated 272075115Sfenner * from the first by a dash (-). Since we 272175115Sfenner * already printed the first packet above, 272275115Sfenner * just print the final packet. Don't 272375115Sfenner * do this if there will be a single-length 272475115Sfenner * range. 272575115Sfenner */ 272675115Sfenner } else if (last == i - 1 && start != last) 2727172683Smlaier printf("-%d", firstPacket + i - 1); 2728127668Sbms 272975115Sfenner /* 273075115Sfenner * So, what's going on here? We ran off the end of the 273175115Sfenner * ack list, and if we got a range we need to finish it up. 273275115Sfenner * So we need to determine if the last packet in the list 273375115Sfenner * was an ack (if so, then last will be set to it) and 273475115Sfenner * we need to see if the last range didn't start with the 273575115Sfenner * last packet (because if it _did_, then that would mean 273675115Sfenner * that the packet number has already been printed and 273775115Sfenner * we don't need to print it again). 273875115Sfenner */ 273975115Sfenner 274075115Sfenner if (last == i - 1 && start != last) 2741172683Smlaier printf("-%d", firstPacket + i - 1); 274275115Sfenner 274375115Sfenner /* 274475115Sfenner * Same as above, just without comments 274575115Sfenner */ 2746127668Sbms 274775115Sfenner for (i = 0, start = last = -2; i < rxa->nAcks; i++) 274875115Sfenner if (rxa->acks[i] == RX_ACK_TYPE_NACK) { 274975115Sfenner if (last == -2) { 275075115Sfenner printf(" nacked %d", 2751172683Smlaier firstPacket + i); 275275115Sfenner start = i; 275375115Sfenner } else if (last != i - 1) { 2754172683Smlaier printf(",%d", firstPacket + i); 275575115Sfenner start = i; 275675115Sfenner } 275775115Sfenner last = i; 275875115Sfenner } else if (last == i - 1 && start != last) 2759172683Smlaier printf("-%d", firstPacket + i - 1); 2760127668Sbms 276175115Sfenner if (last == i - 1 && start != last) 2762172683Smlaier printf("-%d", firstPacket + i - 1); 276375115Sfenner 276475115Sfenner bp += rxa->nAcks; 276575115Sfenner } 276675115Sfenner 276775115Sfenner 276875115Sfenner /* 276975115Sfenner * These are optional fields; depending on your version of AFS, 277075115Sfenner * you may or may not see them 277175115Sfenner */ 277275115Sfenner 277375115Sfenner#define TRUNCRET(n) if (snapend - bp + 1 <= n) return; 277475115Sfenner 277575115Sfenner if (vflag > 1) { 277675115Sfenner TRUNCRET(4); 277775115Sfenner printf(" ifmtu"); 277875115Sfenner INTOUT(); 277975115Sfenner 278075115Sfenner TRUNCRET(4); 278175115Sfenner printf(" maxmtu"); 278275115Sfenner INTOUT(); 278375115Sfenner 278475115Sfenner TRUNCRET(4); 278575115Sfenner printf(" rwind"); 278675115Sfenner INTOUT(); 278775115Sfenner 278875115Sfenner TRUNCRET(4); 278975115Sfenner printf(" maxpackets"); 279075115Sfenner INTOUT(); 279175115Sfenner } 279275115Sfenner 279375115Sfenner return; 279475115Sfenner 279575115Sfennertrunc: 279675115Sfenner printf(" [|ack]"); 279775115Sfenner} 279875115Sfenner#undef TRUNCRET 2799