print-rx.c revision 172683
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_ = 37172683Smlaier "@(#) $Header: /tcpdump/master/tcpdump/print-rx.c,v 1.37.2.2 2007/06/15 19:43:15 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" }, 12156893Sfenner { 0, NULL }, 12256893Sfenner}; 12356893Sfenner 12456893Sfennerstatic struct tok cb_req[] = { 12556893Sfenner { 204, "callback" }, 12656893Sfenner { 205, "initcb" }, 12756893Sfenner { 206, "probe" }, 12856893Sfenner { 207, "getlock" }, 12956893Sfenner { 208, "getce" }, 13056893Sfenner { 209, "xstatver" }, 13156893Sfenner { 210, "getxstat" }, 13256893Sfenner { 211, "initcb2" }, 13356893Sfenner { 212, "whoareyou" }, 13456893Sfenner { 213, "initcb3" }, 13556893Sfenner { 214, "probeuuid" }, 13698524Sfenner { 215, "getsrvprefs" }, 13798524Sfenner { 216, "getcellservdb" }, 13898524Sfenner { 217, "getlocalcell" }, 13998524Sfenner { 218, "getcacheconf" }, 14056893Sfenner { 0, NULL }, 14156893Sfenner}; 14256893Sfenner 14356893Sfennerstatic struct tok pt_req[] = { 14456893Sfenner { 500, "new-user" }, 14556893Sfenner { 501, "where-is-it" }, 14656893Sfenner { 502, "dump-entry" }, 14756893Sfenner { 503, "add-to-group" }, 14856893Sfenner { 504, "name-to-id" }, 14956893Sfenner { 505, "id-to-name" }, 15056893Sfenner { 506, "delete" }, 15156893Sfenner { 507, "remove-from-group" }, 15256893Sfenner { 508, "get-cps" }, 15356893Sfenner { 509, "new-entry" }, 15456893Sfenner { 510, "list-max" }, 15556893Sfenner { 511, "set-max" }, 15656893Sfenner { 512, "list-entry" }, 15756893Sfenner { 513, "change-entry" }, 15856893Sfenner { 514, "list-elements" }, 15956893Sfenner { 515, "same-mbr-of" }, 16056893Sfenner { 516, "set-fld-sentry" }, 16156893Sfenner { 517, "list-owned" }, 16256893Sfenner { 518, "get-cps2" }, 16356893Sfenner { 519, "get-host-cps" }, 16456893Sfenner { 520, "update-entry" }, 16598524Sfenner { 521, "list-entries" }, 16656893Sfenner { 0, NULL }, 16756893Sfenner}; 16856893Sfenner 16956893Sfennerstatic struct tok vldb_req[] = { 17056893Sfenner { 501, "create-entry" }, 17156893Sfenner { 502, "delete-entry" }, 17256893Sfenner { 503, "get-entry-by-id" }, 17356893Sfenner { 504, "get-entry-by-name" }, 17456893Sfenner { 505, "get-new-volume-id" }, 17556893Sfenner { 506, "replace-entry" }, 17656893Sfenner { 507, "update-entry" }, 17756893Sfenner { 508, "setlock" }, 17856893Sfenner { 509, "releaselock" }, 17956893Sfenner { 510, "list-entry" }, 18056893Sfenner { 511, "list-attrib" }, 18156893Sfenner { 512, "linked-list" }, 18256893Sfenner { 513, "get-stats" }, 18356893Sfenner { 514, "probe" }, 18456893Sfenner { 515, "get-addrs" }, 18556893Sfenner { 516, "change-addr" }, 18656893Sfenner { 517, "create-entry-n" }, 18756893Sfenner { 518, "get-entry-by-id-n" }, 18856893Sfenner { 519, "get-entry-by-name-n" }, 18956893Sfenner { 520, "replace-entry-n" }, 19056893Sfenner { 521, "list-entry-n" }, 19156893Sfenner { 522, "list-attrib-n" }, 19256893Sfenner { 523, "linked-list-n" }, 19356893Sfenner { 524, "update-entry-by-name" }, 19456893Sfenner { 525, "create-entry-u" }, 19556893Sfenner { 526, "get-entry-by-id-u" }, 19656893Sfenner { 527, "get-entry-by-name-u" }, 19756893Sfenner { 528, "replace-entry-u" }, 19856893Sfenner { 529, "list-entry-u" }, 19956893Sfenner { 530, "list-attrib-u" }, 20056893Sfenner { 531, "linked-list-u" }, 20156893Sfenner { 532, "regaddr" }, 20256893Sfenner { 533, "get-addrs-u" }, 20398524Sfenner { 534, "list-attrib-n2" }, 20456893Sfenner { 0, NULL }, 20556893Sfenner}; 20656893Sfenner 20756893Sfennerstatic struct tok kauth_req[] = { 20856893Sfenner { 1, "auth-old" }, 20956893Sfenner { 21, "authenticate" }, 21056893Sfenner { 22, "authenticate-v2" }, 21156893Sfenner { 2, "change-pw" }, 21256893Sfenner { 3, "get-ticket-old" }, 21356893Sfenner { 23, "get-ticket" }, 21456893Sfenner { 4, "set-pw" }, 21556893Sfenner { 5, "set-fields" }, 21656893Sfenner { 6, "create-user" }, 21756893Sfenner { 7, "delete-user" }, 21856893Sfenner { 8, "get-entry" }, 21956893Sfenner { 9, "list-entry" }, 22056893Sfenner { 10, "get-stats" }, 22156893Sfenner { 11, "debug" }, 22256893Sfenner { 12, "get-pw" }, 22356893Sfenner { 13, "get-random-key" }, 22456893Sfenner { 14, "unlock" }, 22556893Sfenner { 15, "lock-status" }, 22656893Sfenner { 0, NULL }, 22756893Sfenner}; 22856893Sfenner 22956893Sfennerstatic struct tok vol_req[] = { 23056893Sfenner { 100, "create-volume" }, 23156893Sfenner { 101, "delete-volume" }, 23256893Sfenner { 102, "restore" }, 23356893Sfenner { 103, "forward" }, 23456893Sfenner { 104, "end-trans" }, 23556893Sfenner { 105, "clone" }, 23656893Sfenner { 106, "set-flags" }, 23756893Sfenner { 107, "get-flags" }, 23856893Sfenner { 108, "trans-create" }, 23956893Sfenner { 109, "dump" }, 24056893Sfenner { 110, "get-nth-volume" }, 24156893Sfenner { 111, "set-forwarding" }, 24256893Sfenner { 112, "get-name" }, 24356893Sfenner { 113, "get-status" }, 24456893Sfenner { 114, "sig-restore" }, 24556893Sfenner { 115, "list-partitions" }, 24656893Sfenner { 116, "list-volumes" }, 24756893Sfenner { 117, "set-id-types" }, 24856893Sfenner { 118, "monitor" }, 24956893Sfenner { 119, "partition-info" }, 25056893Sfenner { 120, "reclone" }, 25156893Sfenner { 121, "list-one-volume" }, 25256893Sfenner { 122, "nuke" }, 25356893Sfenner { 123, "set-date" }, 25456893Sfenner { 124, "x-list-volumes" }, 25556893Sfenner { 125, "x-list-one-volume" }, 25656893Sfenner { 126, "set-info" }, 25756893Sfenner { 127, "x-list-partitions" }, 25856893Sfenner { 128, "forward-multiple" }, 25956893Sfenner { 0, NULL }, 26056893Sfenner}; 26156893Sfenner 26256893Sfennerstatic struct tok bos_req[] = { 26356893Sfenner { 80, "create-bnode" }, 26456893Sfenner { 81, "delete-bnode" }, 26556893Sfenner { 82, "set-status" }, 26656893Sfenner { 83, "get-status" }, 26756893Sfenner { 84, "enumerate-instance" }, 26856893Sfenner { 85, "get-instance-info" }, 26956893Sfenner { 86, "get-instance-parm" }, 27056893Sfenner { 87, "add-superuser" }, 27156893Sfenner { 88, "delete-superuser" }, 27256893Sfenner { 89, "list-superusers" }, 27356893Sfenner { 90, "list-keys" }, 27456893Sfenner { 91, "add-key" }, 27556893Sfenner { 92, "delete-key" }, 27656893Sfenner { 93, "set-cell-name" }, 27756893Sfenner { 94, "get-cell-name" }, 27856893Sfenner { 95, "get-cell-host" }, 27956893Sfenner { 96, "add-cell-host" }, 28056893Sfenner { 97, "delete-cell-host" }, 28156893Sfenner { 98, "set-t-status" }, 28256893Sfenner { 99, "shutdown-all" }, 28356893Sfenner { 100, "restart-all" }, 28456893Sfenner { 101, "startup-all" }, 28556893Sfenner { 102, "set-noauth-flag" }, 28656893Sfenner { 103, "re-bozo" }, 28756893Sfenner { 104, "restart" }, 28856893Sfenner { 105, "start-bozo-install" }, 28956893Sfenner { 106, "uninstall" }, 29056893Sfenner { 107, "get-dates" }, 29156893Sfenner { 108, "exec" }, 29256893Sfenner { 109, "prune" }, 29356893Sfenner { 110, "set-restart-time" }, 29456893Sfenner { 111, "get-restart-time" }, 29556893Sfenner { 112, "start-bozo-log" }, 29656893Sfenner { 113, "wait-all" }, 29756893Sfenner { 114, "get-instance-strings" }, 29898524Sfenner { 115, "get-restricted" }, 29998524Sfenner { 116, "set-restricted" }, 30056893Sfenner { 0, NULL }, 30156893Sfenner}; 30256893Sfenner 30356893Sfennerstatic struct tok ubik_req[] = { 30456893Sfenner { 10000, "vote-beacon" }, 30556893Sfenner { 10001, "vote-debug-old" }, 30656893Sfenner { 10002, "vote-sdebug-old" }, 30756893Sfenner { 10003, "vote-getsyncsite" }, 30856893Sfenner { 10004, "vote-debug" }, 30956893Sfenner { 10005, "vote-sdebug" }, 31056893Sfenner { 20000, "disk-begin" }, 31156893Sfenner { 20001, "disk-commit" }, 31256893Sfenner { 20002, "disk-lock" }, 31356893Sfenner { 20003, "disk-write" }, 31456893Sfenner { 20004, "disk-getversion" }, 31556893Sfenner { 20005, "disk-getfile" }, 31656893Sfenner { 20006, "disk-sendfile" }, 31756893Sfenner { 20007, "disk-abort" }, 31856893Sfenner { 20008, "disk-releaselocks" }, 31956893Sfenner { 20009, "disk-truncate" }, 32056893Sfenner { 20010, "disk-probe" }, 32156893Sfenner { 20011, "disk-writev" }, 32256893Sfenner { 20012, "disk-interfaceaddr" }, 32356893Sfenner { 20013, "disk-setversion" }, 32456893Sfenner { 0, NULL }, 32556893Sfenner}; 32656893Sfenner 32756893Sfenner#define VOTE_LOW 10000 32856893Sfenner#define VOTE_HIGH 10005 32956893Sfenner#define DISK_LOW 20000 33056893Sfenner#define DISK_HIGH 20013 33156893Sfenner 33256893Sfennerstatic struct tok cb_types[] = { 33356893Sfenner { 1, "exclusive" }, 33456893Sfenner { 2, "shared" }, 33556893Sfenner { 3, "dropped" }, 33656893Sfenner { 0, NULL }, 33756893Sfenner}; 33856893Sfenner 33956893Sfennerstatic struct tok ubik_lock_types[] = { 34056893Sfenner { 1, "read" }, 34156893Sfenner { 2, "write" }, 34256893Sfenner { 3, "wait" }, 34356893Sfenner { 0, NULL }, 34456893Sfenner}; 34556893Sfenner 346127668Sbmsstatic const char *voltype[] = { "read-write", "read-only", "backup" }; 34756893Sfenner 34875115Sfennerstatic struct tok afs_fs_errors[] = { 34975115Sfenner { 101, "salvage volume" }, 35075115Sfenner { 102, "no such vnode" }, 35175115Sfenner { 103, "no such volume" }, 35275115Sfenner { 104, "volume exist" }, 35375115Sfenner { 105, "no service" }, 35475115Sfenner { 106, "volume offline" }, 35575115Sfenner { 107, "voline online" }, 35675115Sfenner { 108, "diskfull" }, 35775115Sfenner { 109, "diskquota exceeded" }, 35875115Sfenner { 110, "volume busy" }, 35975115Sfenner { 111, "volume moved" }, 36075115Sfenner { 112, "AFS IO error" }, 36175115Sfenner { -100, "restarting fileserver" }, 36275115Sfenner { 0, NULL } 36375115Sfenner}; 36475115Sfenner 36556893Sfenner/* 36675115Sfenner * Reasons for acknowledging a packet 36775115Sfenner */ 36875115Sfenner 36975115Sfennerstatic struct tok rx_ack_reasons[] = { 37075115Sfenner { 1, "ack requested" }, 37175115Sfenner { 2, "duplicate packet" }, 37275115Sfenner { 3, "out of sequence" }, 37375115Sfenner { 4, "exceeds window" }, 37475115Sfenner { 5, "no buffer space" }, 37575115Sfenner { 6, "ping" }, 37675115Sfenner { 7, "ping response" }, 37775115Sfenner { 8, "delay" }, 378127668Sbms { 9, "idle" }, 37975115Sfenner { 0, NULL }, 38075115Sfenner}; 38175115Sfenner 38275115Sfenner/* 38356893Sfenner * Cache entries we keep around so we can figure out the RX opcode 38456893Sfenner * numbers for replies. This allows us to make sense of RX reply packets. 38556893Sfenner */ 38656893Sfenner 38756893Sfennerstruct rx_cache_entry { 38856893Sfenner u_int32_t callnum; /* Call number (net order) */ 38956893Sfenner struct in_addr client; /* client IP address (net order) */ 39056893Sfenner struct in_addr server; /* server IP address (net order) */ 39156893Sfenner int dport; /* server port (host order) */ 39256893Sfenner u_short serviceId; /* Service identifier (net order) */ 39356893Sfenner u_int32_t opcode; /* RX opcode (host order) */ 39456893Sfenner}; 39556893Sfenner 39656893Sfenner#define RX_CACHE_SIZE 64 39756893Sfenner 39856893Sfennerstatic struct rx_cache_entry rx_cache[RX_CACHE_SIZE]; 39956893Sfenner 40056893Sfennerstatic int rx_cache_next = 0; 40156893Sfennerstatic int rx_cache_hint = 0; 402127668Sbmsstatic void rx_cache_insert(const u_char *, const struct ip *, int); 40356893Sfennerstatic int rx_cache_find(const struct rx_header *, const struct ip *, 40456893Sfenner int, int32_t *); 40556893Sfenner 40656893Sfennerstatic void fs_print(const u_char *, int); 40756893Sfennerstatic void fs_reply_print(const u_char *, int, int32_t); 40875115Sfennerstatic void acl_print(u_char *, int, u_char *); 40956893Sfennerstatic void cb_print(const u_char *, int); 41056893Sfennerstatic void cb_reply_print(const u_char *, int, int32_t); 41156893Sfennerstatic void prot_print(const u_char *, int); 41256893Sfennerstatic void prot_reply_print(const u_char *, int, int32_t); 41356893Sfennerstatic void vldb_print(const u_char *, int); 41456893Sfennerstatic void vldb_reply_print(const u_char *, int, int32_t); 41556893Sfennerstatic void kauth_print(const u_char *, int); 41656893Sfennerstatic void kauth_reply_print(const u_char *, int, int32_t); 41756893Sfennerstatic void vol_print(const u_char *, int); 41856893Sfennerstatic void vol_reply_print(const u_char *, int, int32_t); 41956893Sfennerstatic void bos_print(const u_char *, int); 42056893Sfennerstatic void bos_reply_print(const u_char *, int, int32_t); 421127668Sbmsstatic void ubik_print(const u_char *); 42256893Sfennerstatic void ubik_reply_print(const u_char *, int, int32_t); 42356893Sfenner 42475115Sfennerstatic void rx_ack_print(const u_char *, int); 42575115Sfenner 42656893Sfennerstatic int is_ubik(u_int32_t); 42756893Sfenner 42856893Sfenner/* 42956893Sfenner * Handle the rx-level packet. See if we know what port it's going to so 43056893Sfenner * we can peek at the afs call inside 43156893Sfenner */ 43256893Sfenner 43356893Sfennervoid 43456893Sfennerrx_print(register const u_char *bp, int length, int sport, int dport, 43556893Sfenner u_char *bp2) 43656893Sfenner{ 43756893Sfenner register struct rx_header *rxh; 43856893Sfenner int i; 43956893Sfenner int32_t opcode; 44056893Sfenner 441127668Sbms if (snapend - bp < (int)sizeof (struct rx_header)) { 44256893Sfenner printf(" [|rx] (%d)", length); 44356893Sfenner return; 44456893Sfenner } 44556893Sfenner 44656893Sfenner rxh = (struct rx_header *) bp; 44756893Sfenner 44856893Sfenner printf(" rx %s", tok2str(rx_types, "type %d", rxh->type)); 44956893Sfenner 45075115Sfenner if (vflag) { 45156893Sfenner int firstflag = 0; 45275115Sfenner 45375115Sfenner if (vflag > 1) 45475115Sfenner printf(" cid %08x call# %d", 45575115Sfenner (int) EXTRACT_32BITS(&rxh->cid), 45675115Sfenner (int) EXTRACT_32BITS(&rxh->callNumber)); 45775115Sfenner 45875115Sfenner printf(" seq %d ser %d", 45975115Sfenner (int) EXTRACT_32BITS(&rxh->seq), 46075115Sfenner (int) EXTRACT_32BITS(&rxh->serial)); 46175115Sfenner 46256893Sfenner if (vflag > 2) 46356893Sfenner printf(" secindex %d serviceid %hu", 46456893Sfenner (int) rxh->securityIndex, 46575115Sfenner EXTRACT_16BITS(&rxh->serviceId)); 46675115Sfenner 46775115Sfenner if (vflag > 1) 46875115Sfenner for (i = 0; i < NUM_RX_FLAGS; i++) { 46998524Sfenner if (rxh->flags & rx_flags[i].flag && 47098524Sfenner (!rx_flags[i].packetType || 47198524Sfenner rxh->type == rx_flags[i].packetType)) { 47275115Sfenner if (!firstflag) { 47375115Sfenner firstflag = 1; 47475115Sfenner printf(" "); 47575115Sfenner } else { 47675115Sfenner printf(","); 47775115Sfenner } 47875115Sfenner printf("<%s>", rx_flags[i].s); 47956893Sfenner } 48056893Sfenner } 48156893Sfenner } 48256893Sfenner 48356893Sfenner /* 48456893Sfenner * Try to handle AFS calls that we know about. Check the destination 48556893Sfenner * port and make sure it's a data packet. Also, make sure the 48656893Sfenner * seq number is 1 (because otherwise it's a continuation packet, 48756893Sfenner * and we can't interpret that). Also, seems that reply packets 48856893Sfenner * do not have the client-init flag set, so we check for that 48956893Sfenner * as well. 49056893Sfenner */ 49156893Sfenner 492127668Sbms if (rxh->type == RX_PACKET_TYPE_DATA && 49375115Sfenner EXTRACT_32BITS(&rxh->seq) == 1 && 49456893Sfenner rxh->flags & RX_CLIENT_INITIATED) { 49556893Sfenner 49656893Sfenner /* 49756893Sfenner * Insert this call into the call cache table, so we 49856893Sfenner * have a chance to print out replies 49956893Sfenner */ 50056893Sfenner 501127668Sbms rx_cache_insert(bp, (const struct ip *) bp2, dport); 50256893Sfenner 50356893Sfenner switch (dport) { 50456893Sfenner case FS_RX_PORT: /* AFS file service */ 50556893Sfenner fs_print(bp, length); 50656893Sfenner break; 50756893Sfenner case CB_RX_PORT: /* AFS callback service */ 50856893Sfenner cb_print(bp, length); 50956893Sfenner break; 51056893Sfenner case PROT_RX_PORT: /* AFS protection service */ 51156893Sfenner prot_print(bp, length); 51256893Sfenner break; 51356893Sfenner case VLDB_RX_PORT: /* AFS VLDB service */ 51456893Sfenner vldb_print(bp, length); 51556893Sfenner break; 51656893Sfenner case KAUTH_RX_PORT: /* AFS Kerberos auth service */ 51756893Sfenner kauth_print(bp, length); 51856893Sfenner break; 51956893Sfenner case VOL_RX_PORT: /* AFS Volume service */ 52056893Sfenner vol_print(bp, length); 52156893Sfenner break; 52256893Sfenner case BOS_RX_PORT: /* AFS BOS service */ 52356893Sfenner bos_print(bp, length); 52456893Sfenner break; 52556893Sfenner default: 52656893Sfenner ; 52756893Sfenner } 528127668Sbms 52956893Sfenner /* 53056893Sfenner * If it's a reply (client-init is _not_ set, but seq is one) 53156893Sfenner * then look it up in the cache. If we find it, call the reply 53256893Sfenner * printing functions Note that we handle abort packets here, 53356893Sfenner * because printing out the return code can be useful at times. 53456893Sfenner */ 53556893Sfenner 53656893Sfenner } else if (((rxh->type == RX_PACKET_TYPE_DATA && 53775115Sfenner EXTRACT_32BITS(&rxh->seq) == 1) || 53856893Sfenner rxh->type == RX_PACKET_TYPE_ABORT) && 53956893Sfenner (rxh->flags & RX_CLIENT_INITIATED) == 0 && 54056893Sfenner rx_cache_find(rxh, (const struct ip *) bp2, 54156893Sfenner sport, &opcode)) { 54256893Sfenner 54356893Sfenner switch (sport) { 54456893Sfenner case FS_RX_PORT: /* AFS file service */ 54556893Sfenner fs_reply_print(bp, length, opcode); 54656893Sfenner break; 54756893Sfenner case CB_RX_PORT: /* AFS callback service */ 54856893Sfenner cb_reply_print(bp, length, opcode); 54956893Sfenner break; 55056893Sfenner case PROT_RX_PORT: /* AFS PT service */ 55156893Sfenner prot_reply_print(bp, length, opcode); 55256893Sfenner break; 55356893Sfenner case VLDB_RX_PORT: /* AFS VLDB service */ 55456893Sfenner vldb_reply_print(bp, length, opcode); 55556893Sfenner break; 55656893Sfenner case KAUTH_RX_PORT: /* AFS Kerberos auth service */ 55756893Sfenner kauth_reply_print(bp, length, opcode); 55856893Sfenner break; 55956893Sfenner case VOL_RX_PORT: /* AFS Volume service */ 56056893Sfenner vol_reply_print(bp, length, opcode); 56156893Sfenner break; 56256893Sfenner case BOS_RX_PORT: /* AFS BOS service */ 56356893Sfenner bos_reply_print(bp, length, opcode); 56456893Sfenner break; 56556893Sfenner default: 56656893Sfenner ; 56756893Sfenner } 56856893Sfenner 56975115Sfenner /* 57075115Sfenner * If it's an RX ack packet, then use the appropriate ack decoding 57175115Sfenner * function (there isn't any service-specific information in the 57275115Sfenner * ack packet, so we can use one for all AFS services) 57375115Sfenner */ 57456893Sfenner 57575115Sfenner } else if (rxh->type == RX_PACKET_TYPE_ACK) 57675115Sfenner rx_ack_print(bp, length); 57775115Sfenner 57875115Sfenner 57956893Sfenner printf(" (%d)", length); 58056893Sfenner} 58156893Sfenner 58256893Sfenner/* 58356893Sfenner * Insert an entry into the cache. Taken from print-nfs.c 58456893Sfenner */ 58556893Sfenner 58656893Sfennerstatic void 587127668Sbmsrx_cache_insert(const u_char *bp, const struct ip *ip, int dport) 58856893Sfenner{ 58956893Sfenner struct rx_cache_entry *rxent; 59056893Sfenner const struct rx_header *rxh = (const struct rx_header *) bp; 59156893Sfenner 592127668Sbms if (snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) 59356893Sfenner return; 59456893Sfenner 59556893Sfenner rxent = &rx_cache[rx_cache_next]; 59656893Sfenner 59756893Sfenner if (++rx_cache_next >= RX_CACHE_SIZE) 59856893Sfenner rx_cache_next = 0; 599127668Sbms 60056893Sfenner rxent->callnum = rxh->callNumber; 60156893Sfenner rxent->client = ip->ip_src; 60256893Sfenner rxent->server = ip->ip_dst; 60356893Sfenner rxent->dport = dport; 60456893Sfenner rxent->serviceId = rxh->serviceId; 60575115Sfenner rxent->opcode = EXTRACT_32BITS(bp + sizeof(struct rx_header)); 60656893Sfenner} 60756893Sfenner 60856893Sfenner/* 60956893Sfenner * Lookup an entry in the cache. Also taken from print-nfs.c 61056893Sfenner * 61156893Sfenner * Note that because this is a reply, we're looking at the _source_ 61256893Sfenner * port. 61356893Sfenner */ 61456893Sfenner 61556893Sfennerstatic int 61656893Sfennerrx_cache_find(const struct rx_header *rxh, const struct ip *ip, int sport, 61756893Sfenner int32_t *opcode) 61856893Sfenner{ 61956893Sfenner int i; 62056893Sfenner struct rx_cache_entry *rxent; 62156893Sfenner u_int32_t clip = ip->ip_dst.s_addr; 62256893Sfenner u_int32_t sip = ip->ip_src.s_addr; 62356893Sfenner 62456893Sfenner /* Start the search where we last left off */ 62556893Sfenner 62656893Sfenner i = rx_cache_hint; 62756893Sfenner do { 62856893Sfenner rxent = &rx_cache[i]; 62956893Sfenner if (rxent->callnum == rxh->callNumber && 63056893Sfenner rxent->client.s_addr == clip && 631127668Sbms rxent->server.s_addr == sip && 63256893Sfenner rxent->serviceId == rxh->serviceId && 63356893Sfenner rxent->dport == sport) { 63456893Sfenner 63556893Sfenner /* We got a match! */ 63656893Sfenner 63756893Sfenner rx_cache_hint = i; 63856893Sfenner *opcode = rxent->opcode; 63956893Sfenner return(1); 64056893Sfenner } 64156893Sfenner if (++i > RX_CACHE_SIZE) 64256893Sfenner i = 0; 64356893Sfenner } while (i != rx_cache_hint); 64456893Sfenner 64556893Sfenner /* Our search failed */ 64656893Sfenner return(0); 64756893Sfenner} 64856893Sfenner 64956893Sfenner/* 65056893Sfenner * These extrememly grody macros handle the printing of various AFS stuff. 65156893Sfenner */ 65256893Sfenner 65356893Sfenner#define FIDOUT() { unsigned long n1, n2, n3; \ 65475115Sfenner TCHECK2(bp[0], sizeof(int32_t) * 3); \ 65575115Sfenner n1 = EXTRACT_32BITS(bp); \ 65656893Sfenner bp += sizeof(int32_t); \ 65775115Sfenner n2 = EXTRACT_32BITS(bp); \ 65856893Sfenner bp += sizeof(int32_t); \ 65975115Sfenner n3 = EXTRACT_32BITS(bp); \ 66056893Sfenner bp += sizeof(int32_t); \ 66156893Sfenner printf(" fid %d/%d/%d", (int) n1, (int) n2, (int) n3); \ 66256893Sfenner } 66356893Sfenner 66480231Sfenner#define STROUT(MAX) { unsigned int i; \ 66575115Sfenner TCHECK2(bp[0], sizeof(int32_t)); \ 66680231Sfenner i = EXTRACT_32BITS(bp); \ 66798524Sfenner if (i > (MAX)) \ 66880231Sfenner goto trunc; \ 66956893Sfenner bp += sizeof(int32_t); \ 67080231Sfenner printf(" \""); \ 67180231Sfenner if (fn_printn(bp, i, snapend)) \ 67280231Sfenner goto trunc; \ 67380231Sfenner printf("\""); \ 67456893Sfenner bp += ((i + sizeof(int32_t) - 1) / sizeof(int32_t)) * sizeof(int32_t); \ 67556893Sfenner } 67656893Sfenner 67756893Sfenner#define INTOUT() { int i; \ 67875115Sfenner TCHECK2(bp[0], sizeof(int32_t)); \ 67975115Sfenner i = (int) EXTRACT_32BITS(bp); \ 68056893Sfenner bp += sizeof(int32_t); \ 68156893Sfenner printf(" %d", i); \ 68256893Sfenner } 68356893Sfenner 68456893Sfenner#define UINTOUT() { unsigned long i; \ 68575115Sfenner TCHECK2(bp[0], sizeof(int32_t)); \ 68675115Sfenner i = EXTRACT_32BITS(bp); \ 68756893Sfenner bp += sizeof(int32_t); \ 68856893Sfenner printf(" %lu", i); \ 68956893Sfenner } 69056893Sfenner 69156893Sfenner#define DATEOUT() { time_t t; struct tm *tm; char str[256]; \ 69275115Sfenner TCHECK2(bp[0], sizeof(int32_t)); \ 69375115Sfenner t = (time_t) EXTRACT_32BITS(bp); \ 69456893Sfenner bp += sizeof(int32_t); \ 69556893Sfenner tm = localtime(&t); \ 69656893Sfenner strftime(str, 256, "%Y/%m/%d %T", tm); \ 69756893Sfenner printf(" %s", str); \ 69856893Sfenner } 69956893Sfenner 70056893Sfenner#define STOREATTROUT() { unsigned long mask, i; \ 70175115Sfenner TCHECK2(bp[0], (sizeof(int32_t)*6)); \ 70275115Sfenner mask = EXTRACT_32BITS(bp); bp += sizeof(int32_t); \ 70356893Sfenner if (mask) printf (" StoreStatus"); \ 704127668Sbms if (mask & 1) { printf(" date"); DATEOUT(); } \ 70556893Sfenner else bp += sizeof(int32_t); \ 70675115Sfenner i = EXTRACT_32BITS(bp); bp += sizeof(int32_t); \ 707127668Sbms if (mask & 2) printf(" owner %lu", i); \ 70875115Sfenner i = EXTRACT_32BITS(bp); bp += sizeof(int32_t); \ 709127668Sbms if (mask & 4) printf(" group %lu", i); \ 71075115Sfenner i = EXTRACT_32BITS(bp); bp += sizeof(int32_t); \ 711127668Sbms if (mask & 8) printf(" mode %lo", i & 07777); \ 71275115Sfenner i = EXTRACT_32BITS(bp); bp += sizeof(int32_t); \ 713127668Sbms if (mask & 16) printf(" segsize %lu", i); \ 71456893Sfenner /* undocumented in 3.3 docu */ \ 715127668Sbms if (mask & 1024) printf(" fsync"); \ 71656893Sfenner } 71756893Sfenner 71856893Sfenner#define UBIK_VERSIONOUT() {int32_t epoch; int32_t counter; \ 71975115Sfenner TCHECK2(bp[0], sizeof(int32_t) * 2); \ 72075115Sfenner epoch = EXTRACT_32BITS(bp); \ 72156893Sfenner bp += sizeof(int32_t); \ 72275115Sfenner counter = EXTRACT_32BITS(bp); \ 72356893Sfenner bp += sizeof(int32_t); \ 72456893Sfenner printf(" %d.%d", epoch, counter); \ 72556893Sfenner } 72656893Sfenner 72756893Sfenner#define AFSUUIDOUT() {u_int32_t temp; int i; \ 72875115Sfenner TCHECK2(bp[0], 11*sizeof(u_int32_t)); \ 72975115Sfenner temp = EXTRACT_32BITS(bp); \ 73056893Sfenner bp += sizeof(u_int32_t); \ 73156893Sfenner printf(" %08x", temp); \ 73275115Sfenner temp = EXTRACT_32BITS(bp); \ 73356893Sfenner bp += sizeof(u_int32_t); \ 73456893Sfenner printf("%04x", temp); \ 73575115Sfenner temp = EXTRACT_32BITS(bp); \ 73656893Sfenner bp += sizeof(u_int32_t); \ 73756893Sfenner printf("%04x", temp); \ 73856893Sfenner for (i = 0; i < 8; i++) { \ 73975115Sfenner temp = EXTRACT_32BITS(bp); \ 74056893Sfenner bp += sizeof(u_int32_t); \ 74156893Sfenner printf("%02x", (unsigned char) temp); \ 74256893Sfenner } \ 74356893Sfenner } 74456893Sfenner 74556893Sfenner/* 74656893Sfenner * This is the sickest one of all 74756893Sfenner */ 74856893Sfenner 749111726Sfenner#define VECOUT(MAX) { u_char *sp; \ 750111726Sfenner u_char s[AFSNAMEMAX]; \ 75156893Sfenner int k; \ 75298524Sfenner if ((MAX) + 1 > sizeof(s)) \ 75398524Sfenner goto trunc; \ 75498524Sfenner TCHECK2(bp[0], (MAX) * sizeof(int32_t)); \ 75556893Sfenner sp = s; \ 75698524Sfenner for (k = 0; k < (MAX); k++) { \ 757111726Sfenner *sp++ = (u_char) EXTRACT_32BITS(bp); \ 75856893Sfenner bp += sizeof(int32_t); \ 75956893Sfenner } \ 76098524Sfenner s[(MAX)] = '\0'; \ 76180231Sfenner printf(" \""); \ 76280231Sfenner fn_print(s, NULL); \ 76380231Sfenner printf("\""); \ 76456893Sfenner } 76556893Sfenner 76656893Sfenner/* 76756893Sfenner * Handle calls to the AFS file service (fs) 76856893Sfenner */ 76956893Sfenner 77075115Sfennerstatic void 77156893Sfennerfs_print(register const u_char *bp, int length) 77256893Sfenner{ 77356893Sfenner int fs_op; 77456893Sfenner unsigned long i; 77556893Sfenner 776127668Sbms if (length <= (int)sizeof(struct rx_header)) 77756893Sfenner return; 77856893Sfenner 779127668Sbms if (snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) { 78056893Sfenner goto trunc; 78156893Sfenner } 78256893Sfenner 78356893Sfenner /* 78456893Sfenner * Print out the afs call we're invoking. The table used here was 78556893Sfenner * gleaned from fsint/afsint.xg 78656893Sfenner */ 78756893Sfenner 78875115Sfenner fs_op = EXTRACT_32BITS(bp + sizeof(struct rx_header)); 78956893Sfenner 79056893Sfenner printf(" fs call %s", tok2str(fs_req, "op#%d", fs_op)); 79156893Sfenner 79256893Sfenner /* 79356893Sfenner * Print out arguments to some of the AFS calls. This stuff is 79456893Sfenner * all from afsint.xg 79556893Sfenner */ 79656893Sfenner 79756893Sfenner bp += sizeof(struct rx_header) + 4; 79856893Sfenner 79956893Sfenner /* 80056893Sfenner * Sigh. This is gross. Ritchie forgive me. 80156893Sfenner */ 80256893Sfenner 80356893Sfenner switch (fs_op) { 80456893Sfenner case 130: /* Fetch data */ 80556893Sfenner FIDOUT(); 80656893Sfenner printf(" offset"); 80756893Sfenner UINTOUT(); 80856893Sfenner printf(" length"); 80956893Sfenner UINTOUT(); 81056893Sfenner break; 81156893Sfenner case 131: /* Fetch ACL */ 81256893Sfenner case 132: /* Fetch Status */ 81356893Sfenner case 143: /* Old set lock */ 81456893Sfenner case 144: /* Old extend lock */ 81556893Sfenner case 145: /* Old release lock */ 81656893Sfenner case 156: /* Set lock */ 81756893Sfenner case 157: /* Extend lock */ 81856893Sfenner case 158: /* Release lock */ 81956893Sfenner FIDOUT(); 82056893Sfenner break; 82156893Sfenner case 135: /* Store status */ 82256893Sfenner FIDOUT(); 82356893Sfenner STOREATTROUT(); 82456893Sfenner break; 82556893Sfenner case 133: /* Store data */ 82656893Sfenner FIDOUT(); 82756893Sfenner STOREATTROUT(); 82856893Sfenner printf(" offset"); 82956893Sfenner UINTOUT(); 83056893Sfenner printf(" length"); 83156893Sfenner UINTOUT(); 83256893Sfenner printf(" flen"); 83356893Sfenner UINTOUT(); 83456893Sfenner break; 83556893Sfenner case 134: /* Store ACL */ 83656893Sfenner { 83775115Sfenner char a[AFSOPAQUEMAX+1]; 83856893Sfenner FIDOUT(); 83975115Sfenner TCHECK2(bp[0], 4); 84075115Sfenner i = EXTRACT_32BITS(bp); 84156893Sfenner bp += sizeof(int32_t); 84275115Sfenner TCHECK2(bp[0], i); 84375115Sfenner i = min(AFSOPAQUEMAX, i); 84475115Sfenner strncpy(a, (char *) bp, i); 84556893Sfenner a[i] = '\0'; 84675115Sfenner acl_print((u_char *) a, sizeof(a), (u_char *) a + i); 84756893Sfenner break; 84856893Sfenner } 84956893Sfenner case 137: /* Create file */ 85056893Sfenner case 141: /* MakeDir */ 85156893Sfenner FIDOUT(); 85256893Sfenner STROUT(AFSNAMEMAX); 85356893Sfenner STOREATTROUT(); 85456893Sfenner break; 85556893Sfenner case 136: /* Remove file */ 85656893Sfenner case 142: /* Remove directory */ 85756893Sfenner FIDOUT(); 85856893Sfenner STROUT(AFSNAMEMAX); 85956893Sfenner break; 86056893Sfenner case 138: /* Rename file */ 86156893Sfenner printf(" old"); 86256893Sfenner FIDOUT(); 86356893Sfenner STROUT(AFSNAMEMAX); 86456893Sfenner printf(" new"); 86556893Sfenner FIDOUT(); 86656893Sfenner STROUT(AFSNAMEMAX); 86756893Sfenner break; 86856893Sfenner case 139: /* Symlink */ 86956893Sfenner FIDOUT(); 87056893Sfenner STROUT(AFSNAMEMAX); 87156893Sfenner printf(" link to"); 87256893Sfenner STROUT(AFSNAMEMAX); 87356893Sfenner break; 87456893Sfenner case 140: /* Link */ 87556893Sfenner FIDOUT(); 87656893Sfenner STROUT(AFSNAMEMAX); 87756893Sfenner printf(" link to"); 87856893Sfenner FIDOUT(); 87956893Sfenner break; 88056893Sfenner case 148: /* Get volume info */ 88156893Sfenner STROUT(AFSNAMEMAX); 88256893Sfenner break; 88356893Sfenner case 149: /* Get volume stats */ 88456893Sfenner case 150: /* Set volume stats */ 88556893Sfenner printf(" volid"); 88656893Sfenner UINTOUT(); 88756893Sfenner break; 88856893Sfenner case 154: /* New get volume info */ 88956893Sfenner printf(" volname"); 89056893Sfenner STROUT(AFSNAMEMAX); 89156893Sfenner break; 89256893Sfenner case 155: /* Bulk stat */ 89356893Sfenner { 89456893Sfenner unsigned long j; 89575115Sfenner TCHECK2(bp[0], 4); 89675115Sfenner j = EXTRACT_32BITS(bp); 89756893Sfenner bp += sizeof(int32_t); 89856893Sfenner 89956893Sfenner for (i = 0; i < j; i++) { 90056893Sfenner FIDOUT(); 90156893Sfenner if (i != j - 1) 90256893Sfenner printf(","); 90356893Sfenner } 90456893Sfenner if (j == 0) 90556893Sfenner printf(" <none!>"); 90656893Sfenner } 90756893Sfenner default: 90856893Sfenner ; 90956893Sfenner } 91056893Sfenner 91156893Sfenner return; 91256893Sfenner 91356893Sfennertrunc: 91456893Sfenner printf(" [|fs]"); 91556893Sfenner} 91656893Sfenner 91756893Sfenner/* 91856893Sfenner * Handle replies to the AFS file service 91956893Sfenner */ 92056893Sfenner 92156893Sfennerstatic void 92256893Sfennerfs_reply_print(register const u_char *bp, int length, int32_t opcode) 92356893Sfenner{ 92456893Sfenner unsigned long i; 92556893Sfenner struct rx_header *rxh; 92656893Sfenner 927127668Sbms if (length <= (int)sizeof(struct rx_header)) 92856893Sfenner return; 92956893Sfenner 93056893Sfenner rxh = (struct rx_header *) bp; 93156893Sfenner 93256893Sfenner /* 93356893Sfenner * Print out the afs call we're invoking. The table used here was 93456893Sfenner * gleaned from fsint/afsint.xg 93556893Sfenner */ 93656893Sfenner 93756893Sfenner printf(" fs reply %s", tok2str(fs_req, "op#%d", opcode)); 93856893Sfenner 93956893Sfenner bp += sizeof(struct rx_header); 94056893Sfenner 94156893Sfenner /* 94256893Sfenner * If it was a data packet, interpret the response 94356893Sfenner */ 94456893Sfenner 94575115Sfenner if (rxh->type == RX_PACKET_TYPE_DATA) { 94656893Sfenner switch (opcode) { 94756893Sfenner case 131: /* Fetch ACL */ 94856893Sfenner { 94975115Sfenner char a[AFSOPAQUEMAX+1]; 95075115Sfenner TCHECK2(bp[0], 4); 95175115Sfenner i = EXTRACT_32BITS(bp); 95256893Sfenner bp += sizeof(int32_t); 95375115Sfenner TCHECK2(bp[0], i); 95475115Sfenner i = min(AFSOPAQUEMAX, i); 95575115Sfenner strncpy(a, (char *) bp, i); 95656893Sfenner a[i] = '\0'; 95775115Sfenner acl_print((u_char *) a, sizeof(a), (u_char *) a + i); 95856893Sfenner break; 95956893Sfenner } 96056893Sfenner case 137: /* Create file */ 96156893Sfenner case 141: /* MakeDir */ 96256893Sfenner printf(" new"); 96356893Sfenner FIDOUT(); 96456893Sfenner break; 96556893Sfenner case 151: /* Get root volume */ 96656893Sfenner printf(" root volume"); 96756893Sfenner STROUT(AFSNAMEMAX); 96856893Sfenner break; 96956893Sfenner case 153: /* Get time */ 97056893Sfenner DATEOUT(); 97156893Sfenner break; 97256893Sfenner default: 97356893Sfenner ; 97456893Sfenner } 97575115Sfenner } else if (rxh->type == RX_PACKET_TYPE_ABORT) { 97675115Sfenner int i; 97775115Sfenner 978127668Sbms /* 979127668Sbms * Otherwise, just print out the return code 980127668Sbms */ 981127668Sbms TCHECK2(bp[0], sizeof(int32_t)); 982127668Sbms i = (int) EXTRACT_32BITS(bp); 983127668Sbms bp += sizeof(int32_t); 98475115Sfenner 98575115Sfenner printf(" error %s", tok2str(afs_fs_errors, "#%d", i)); 98675115Sfenner } else { 98775115Sfenner printf(" strange fs reply of type %d", rxh->type); 98856893Sfenner } 98956893Sfenner 99056893Sfenner return; 99156893Sfenner 99256893Sfennertrunc: 99356893Sfenner printf(" [|fs]"); 99456893Sfenner} 99556893Sfenner 99656893Sfenner/* 99756893Sfenner * Print out an AFS ACL string. An AFS ACL is a string that has the 99856893Sfenner * following format: 99956893Sfenner * 100056893Sfenner * <positive> <negative> 100156893Sfenner * <uid1> <aclbits1> 100256893Sfenner * .... 1003127668Sbms * 100456893Sfenner * "positive" and "negative" are integers which contain the number of 100556893Sfenner * positive and negative ACL's in the string. The uid/aclbits pair are 100656893Sfenner * ASCII strings containing the UID/PTS record and and a ascii number 100756893Sfenner * representing a logical OR of all the ACL permission bits 100856893Sfenner */ 100956893Sfenner 101056893Sfennerstatic void 101175115Sfenneracl_print(u_char *s, int maxsize, u_char *end) 101256893Sfenner{ 101356893Sfenner int pos, neg, acl; 101456893Sfenner int n, i; 101575115Sfenner char *user; 1016172683Smlaier char fmt[1024]; 101756893Sfenner 101875115Sfenner if ((user = (char *)malloc(maxsize)) == NULL) 101975115Sfenner return; 102075115Sfenner 102156893Sfenner if (sscanf((char *) s, "%d %d\n%n", &pos, &neg, &n) != 2) 102275115Sfenner goto finish; 1023127668Sbms 102456893Sfenner s += n; 102556893Sfenner 102656893Sfenner if (s > end) 102775115Sfenner goto finish; 102856893Sfenner 102956893Sfenner /* 103056893Sfenner * This wacky order preserves the order used by the "fs" command 103156893Sfenner */ 103256893Sfenner 103356893Sfenner#define ACLOUT(acl) \ 103456893Sfenner if (acl & PRSFS_READ) \ 103556893Sfenner printf("r"); \ 103656893Sfenner if (acl & PRSFS_LOOKUP) \ 103756893Sfenner printf("l"); \ 103856893Sfenner if (acl & PRSFS_INSERT) \ 103956893Sfenner printf("i"); \ 104056893Sfenner if (acl & PRSFS_DELETE) \ 104156893Sfenner printf("d"); \ 104256893Sfenner if (acl & PRSFS_WRITE) \ 104356893Sfenner printf("w"); \ 104456893Sfenner if (acl & PRSFS_LOCK) \ 104556893Sfenner printf("k"); \ 104656893Sfenner if (acl & PRSFS_ADMINISTER) \ 104756893Sfenner printf("a"); 104856893Sfenner 104956893Sfenner for (i = 0; i < pos; i++) { 1050172683Smlaier snprintf(fmt, sizeof(fmt), "%%%ds %%d\n%%n", maxsize - 1); 1051172683Smlaier if (sscanf((char *) s, fmt, user, &acl, &n) != 2) 105275115Sfenner goto finish; 105356893Sfenner s += n; 105480231Sfenner printf(" +{"); 1055111726Sfenner fn_print((u_char *)user, NULL); 105680231Sfenner printf(" "); 105756893Sfenner ACLOUT(acl); 105856893Sfenner printf("}"); 105956893Sfenner if (s > end) 106075115Sfenner goto finish; 106156893Sfenner } 106256893Sfenner 106356893Sfenner for (i = 0; i < neg; i++) { 1064172683Smlaier snprintf(fmt, sizeof(fmt), "%%%ds %%d\n%%n", maxsize - 1); 1065172683Smlaier if (sscanf((char *) s, fmt, user, &acl, &n) != 2) 106675115Sfenner goto finish; 106756893Sfenner s += n; 106880231Sfenner printf(" -{"); 1069111726Sfenner fn_print((u_char *)user, NULL); 107080231Sfenner printf(" "); 107156893Sfenner ACLOUT(acl); 107256893Sfenner printf("}"); 107356893Sfenner if (s > end) 107475115Sfenner goto finish; 107556893Sfenner } 107675115Sfenner 107775115Sfennerfinish: 107875115Sfenner free(user); 107975115Sfenner return; 108056893Sfenner} 108156893Sfenner 108256893Sfenner#undef ACLOUT 108356893Sfenner 108456893Sfenner/* 108556893Sfenner * Handle calls to the AFS callback service 108656893Sfenner */ 108756893Sfenner 108856893Sfennerstatic void 108956893Sfennercb_print(register const u_char *bp, int length) 109056893Sfenner{ 109156893Sfenner int cb_op; 109256893Sfenner unsigned long i; 109356893Sfenner 1094127668Sbms if (length <= (int)sizeof(struct rx_header)) 109556893Sfenner return; 109656893Sfenner 1097127668Sbms if (snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) { 109856893Sfenner goto trunc; 109956893Sfenner } 110056893Sfenner 110156893Sfenner /* 110256893Sfenner * Print out the afs call we're invoking. The table used here was 110356893Sfenner * gleaned from fsint/afscbint.xg 110456893Sfenner */ 110556893Sfenner 110675115Sfenner cb_op = EXTRACT_32BITS(bp + sizeof(struct rx_header)); 110756893Sfenner 110856893Sfenner printf(" cb call %s", tok2str(cb_req, "op#%d", cb_op)); 110956893Sfenner 111056893Sfenner bp += sizeof(struct rx_header) + 4; 111156893Sfenner 111256893Sfenner /* 111356893Sfenner * Print out the afs call we're invoking. The table used here was 111456893Sfenner * gleaned from fsint/afscbint.xg 111556893Sfenner */ 111656893Sfenner 111756893Sfenner switch (cb_op) { 111856893Sfenner case 204: /* Callback */ 111956893Sfenner { 112056893Sfenner unsigned long j, t; 112175115Sfenner TCHECK2(bp[0], 4); 112275115Sfenner j = EXTRACT_32BITS(bp); 112356893Sfenner bp += sizeof(int32_t); 112456893Sfenner 112556893Sfenner for (i = 0; i < j; i++) { 112656893Sfenner FIDOUT(); 112756893Sfenner if (i != j - 1) 112856893Sfenner printf(","); 112956893Sfenner } 113056893Sfenner 113156893Sfenner if (j == 0) 113256893Sfenner printf(" <none!>"); 113356893Sfenner 113475115Sfenner j = EXTRACT_32BITS(bp); 113556893Sfenner bp += sizeof(int32_t); 113656893Sfenner 113756893Sfenner if (j != 0) 113856893Sfenner printf(";"); 113956893Sfenner 114056893Sfenner for (i = 0; i < j; i++) { 114156893Sfenner printf(" ver"); 114256893Sfenner INTOUT(); 114356893Sfenner printf(" expires"); 114456893Sfenner DATEOUT(); 114575115Sfenner TCHECK2(bp[0], 4); 114675115Sfenner t = EXTRACT_32BITS(bp); 114756893Sfenner bp += sizeof(int32_t); 114856893Sfenner tok2str(cb_types, "type %d", t); 114956893Sfenner } 115056893Sfenner } 115156893Sfenner case 214: { 115256893Sfenner printf(" afsuuid"); 115356893Sfenner AFSUUIDOUT(); 115456893Sfenner break; 115556893Sfenner } 115656893Sfenner default: 115756893Sfenner ; 115856893Sfenner } 115956893Sfenner 116056893Sfenner return; 116156893Sfenner 116256893Sfennertrunc: 116356893Sfenner printf(" [|cb]"); 116456893Sfenner} 116556893Sfenner 116656893Sfenner/* 116756893Sfenner * Handle replies to the AFS Callback Service 116856893Sfenner */ 116956893Sfenner 117056893Sfennerstatic void 117156893Sfennercb_reply_print(register const u_char *bp, int length, int32_t opcode) 117256893Sfenner{ 117356893Sfenner struct rx_header *rxh; 117456893Sfenner 1175127668Sbms if (length <= (int)sizeof(struct rx_header)) 117656893Sfenner return; 117756893Sfenner 117856893Sfenner rxh = (struct rx_header *) bp; 117956893Sfenner 118056893Sfenner /* 118156893Sfenner * Print out the afs call we're invoking. The table used here was 118256893Sfenner * gleaned from fsint/afscbint.xg 118356893Sfenner */ 1184127668Sbms 118556893Sfenner printf(" cb reply %s", tok2str(cb_req, "op#%d", opcode)); 118656893Sfenner 118756893Sfenner bp += sizeof(struct rx_header); 118856893Sfenner 118956893Sfenner /* 119056893Sfenner * If it was a data packet, interpret the response. 119156893Sfenner */ 119256893Sfenner 119356893Sfenner if (rxh->type == RX_PACKET_TYPE_DATA) 119456893Sfenner switch (opcode) { 119556893Sfenner case 213: /* InitCallBackState3 */ 119656893Sfenner AFSUUIDOUT(); 119756893Sfenner break; 119856893Sfenner default: 119956893Sfenner ; 120056893Sfenner } 120156893Sfenner else { 120256893Sfenner /* 120356893Sfenner * Otherwise, just print out the return code 120456893Sfenner */ 120556893Sfenner printf(" errcode"); 120656893Sfenner INTOUT(); 120756893Sfenner } 120856893Sfenner 120956893Sfenner return; 121056893Sfenner 121156893Sfennertrunc: 121256893Sfenner printf(" [|cb]"); 121356893Sfenner} 121456893Sfenner 121556893Sfenner/* 121656893Sfenner * Handle calls to the AFS protection database server 121756893Sfenner */ 121856893Sfenner 121956893Sfennerstatic void 122056893Sfennerprot_print(register const u_char *bp, int length) 122156893Sfenner{ 122256893Sfenner unsigned long i; 122356893Sfenner int pt_op; 122456893Sfenner 1225127668Sbms if (length <= (int)sizeof(struct rx_header)) 122656893Sfenner return; 122756893Sfenner 1228127668Sbms if (snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) { 122956893Sfenner goto trunc; 123056893Sfenner } 123156893Sfenner 123256893Sfenner /* 123356893Sfenner * Print out the afs call we're invoking. The table used here was 123456893Sfenner * gleaned from ptserver/ptint.xg 123556893Sfenner */ 123656893Sfenner 123775115Sfenner pt_op = EXTRACT_32BITS(bp + sizeof(struct rx_header)); 123856893Sfenner 123956893Sfenner printf(" pt"); 124056893Sfenner 124156893Sfenner if (is_ubik(pt_op)) { 1242127668Sbms ubik_print(bp); 124356893Sfenner return; 124456893Sfenner } 124556893Sfenner 124656893Sfenner printf(" call %s", tok2str(pt_req, "op#%d", pt_op)); 124756893Sfenner 124856893Sfenner /* 124956893Sfenner * Decode some of the arguments to the PT calls 125056893Sfenner */ 125156893Sfenner 125256893Sfenner bp += sizeof(struct rx_header) + 4; 125356893Sfenner 125456893Sfenner switch (pt_op) { 125556893Sfenner case 500: /* I New User */ 125656893Sfenner STROUT(PRNAMEMAX); 125756893Sfenner printf(" id"); 125856893Sfenner INTOUT(); 125956893Sfenner printf(" oldid"); 126056893Sfenner INTOUT(); 126156893Sfenner break; 126256893Sfenner case 501: /* Where is it */ 126356893Sfenner case 506: /* Delete */ 126456893Sfenner case 508: /* Get CPS */ 126556893Sfenner case 512: /* List entry */ 126656893Sfenner case 514: /* List elements */ 126756893Sfenner case 517: /* List owned */ 126856893Sfenner case 518: /* Get CPS2 */ 126956893Sfenner case 519: /* Get host CPS */ 127056893Sfenner printf(" id"); 127156893Sfenner INTOUT(); 127256893Sfenner break; 127356893Sfenner case 502: /* Dump entry */ 127456893Sfenner printf(" pos"); 127556893Sfenner INTOUT(); 127656893Sfenner break; 127756893Sfenner case 503: /* Add to group */ 127856893Sfenner case 507: /* Remove from group */ 127956893Sfenner case 515: /* Is a member of? */ 128056893Sfenner printf(" uid"); 128156893Sfenner INTOUT(); 128256893Sfenner printf(" gid"); 128356893Sfenner INTOUT(); 128456893Sfenner break; 128556893Sfenner case 504: /* Name to ID */ 128656893Sfenner { 128756893Sfenner unsigned long j; 128875115Sfenner TCHECK2(bp[0], 4); 128975115Sfenner j = EXTRACT_32BITS(bp); 129056893Sfenner bp += sizeof(int32_t); 129156893Sfenner 129256893Sfenner /* 129356893Sfenner * Who designed this chicken-shit protocol? 129456893Sfenner * 129556893Sfenner * Each character is stored as a 32-bit 129656893Sfenner * integer! 129756893Sfenner */ 129856893Sfenner 129956893Sfenner for (i = 0; i < j; i++) { 130056893Sfenner VECOUT(PRNAMEMAX); 130156893Sfenner } 130256893Sfenner if (j == 0) 130356893Sfenner printf(" <none!>"); 130456893Sfenner } 130556893Sfenner break; 130656893Sfenner case 505: /* Id to name */ 130756893Sfenner { 130856893Sfenner unsigned long j; 130956893Sfenner printf(" ids:"); 131075115Sfenner TCHECK2(bp[0], 4); 131175115Sfenner i = EXTRACT_32BITS(bp); 131256893Sfenner bp += sizeof(int32_t); 131356893Sfenner for (j = 0; j < i; j++) 131456893Sfenner INTOUT(); 131556893Sfenner if (j == 0) 131656893Sfenner printf(" <none!>"); 131756893Sfenner } 131856893Sfenner break; 131956893Sfenner case 509: /* New entry */ 132056893Sfenner STROUT(PRNAMEMAX); 132156893Sfenner printf(" flag"); 132256893Sfenner INTOUT(); 132356893Sfenner printf(" oid"); 132456893Sfenner INTOUT(); 132556893Sfenner break; 132656893Sfenner case 511: /* Set max */ 132756893Sfenner printf(" id"); 132856893Sfenner INTOUT(); 132956893Sfenner printf(" gflag"); 133056893Sfenner INTOUT(); 133156893Sfenner break; 133256893Sfenner case 513: /* Change entry */ 133356893Sfenner printf(" id"); 133456893Sfenner INTOUT(); 133556893Sfenner STROUT(PRNAMEMAX); 133656893Sfenner printf(" oldid"); 133756893Sfenner INTOUT(); 133856893Sfenner printf(" newid"); 133956893Sfenner INTOUT(); 134056893Sfenner break; 134156893Sfenner case 520: /* Update entry */ 134256893Sfenner printf(" id"); 134356893Sfenner INTOUT(); 134456893Sfenner STROUT(PRNAMEMAX); 134556893Sfenner break; 134656893Sfenner default: 134756893Sfenner ; 134856893Sfenner } 134956893Sfenner 135056893Sfenner 135156893Sfenner return; 135256893Sfenner 135356893Sfennertrunc: 135456893Sfenner printf(" [|pt]"); 135556893Sfenner} 135656893Sfenner 135756893Sfenner/* 135856893Sfenner * Handle replies to the AFS protection service 135956893Sfenner */ 136056893Sfenner 136156893Sfennerstatic void 136256893Sfennerprot_reply_print(register const u_char *bp, int length, int32_t opcode) 136356893Sfenner{ 136456893Sfenner struct rx_header *rxh; 136556893Sfenner unsigned long i; 136656893Sfenner 1367127668Sbms if (length < (int)sizeof(struct rx_header)) 136856893Sfenner return; 136956893Sfenner 137056893Sfenner rxh = (struct rx_header *) bp; 137156893Sfenner 137256893Sfenner /* 137356893Sfenner * Print out the afs call we're invoking. The table used here was 137456893Sfenner * gleaned from ptserver/ptint.xg. Check to see if it's a 137556893Sfenner * Ubik call, however. 137656893Sfenner */ 137756893Sfenner 137856893Sfenner printf(" pt"); 137956893Sfenner 138056893Sfenner if (is_ubik(opcode)) { 138156893Sfenner ubik_reply_print(bp, length, opcode); 138256893Sfenner return; 138356893Sfenner } 138456893Sfenner 138556893Sfenner printf(" reply %s", tok2str(pt_req, "op#%d", opcode)); 138656893Sfenner 138756893Sfenner bp += sizeof(struct rx_header); 138856893Sfenner 138956893Sfenner /* 139056893Sfenner * If it was a data packet, interpret the response 139156893Sfenner */ 139256893Sfenner 139356893Sfenner if (rxh->type == RX_PACKET_TYPE_DATA) 139456893Sfenner switch (opcode) { 139556893Sfenner case 504: /* Name to ID */ 139656893Sfenner { 139756893Sfenner unsigned long j; 139856893Sfenner printf(" ids:"); 139975115Sfenner TCHECK2(bp[0], 4); 140075115Sfenner i = EXTRACT_32BITS(bp); 140156893Sfenner bp += sizeof(int32_t); 140256893Sfenner for (j = 0; j < i; j++) 140356893Sfenner INTOUT(); 140456893Sfenner if (j == 0) 140556893Sfenner printf(" <none!>"); 140656893Sfenner } 140756893Sfenner break; 140856893Sfenner case 505: /* ID to name */ 140956893Sfenner { 141056893Sfenner unsigned long j; 141175115Sfenner TCHECK2(bp[0], 4); 141275115Sfenner j = EXTRACT_32BITS(bp); 141356893Sfenner bp += sizeof(int32_t); 141456893Sfenner 141556893Sfenner /* 141656893Sfenner * Who designed this chicken-shit protocol? 141756893Sfenner * 141856893Sfenner * Each character is stored as a 32-bit 141956893Sfenner * integer! 142056893Sfenner */ 142156893Sfenner 142256893Sfenner for (i = 0; i < j; i++) { 142356893Sfenner VECOUT(PRNAMEMAX); 142456893Sfenner } 142556893Sfenner if (j == 0) 142656893Sfenner printf(" <none!>"); 142756893Sfenner } 142856893Sfenner break; 142956893Sfenner case 508: /* Get CPS */ 143056893Sfenner case 514: /* List elements */ 143156893Sfenner case 517: /* List owned */ 143256893Sfenner case 518: /* Get CPS2 */ 143356893Sfenner case 519: /* Get host CPS */ 143456893Sfenner { 143556893Sfenner unsigned long j; 143675115Sfenner TCHECK2(bp[0], 4); 143775115Sfenner j = EXTRACT_32BITS(bp); 143856893Sfenner bp += sizeof(int32_t); 143956893Sfenner for (i = 0; i < j; i++) { 144056893Sfenner INTOUT(); 144156893Sfenner } 144256893Sfenner if (j == 0) 144356893Sfenner printf(" <none!>"); 144456893Sfenner } 144556893Sfenner break; 144656893Sfenner case 510: /* List max */ 144756893Sfenner printf(" maxuid"); 144856893Sfenner INTOUT(); 144956893Sfenner printf(" maxgid"); 145056893Sfenner INTOUT(); 145156893Sfenner break; 145256893Sfenner default: 145356893Sfenner ; 145456893Sfenner } 145556893Sfenner else { 145656893Sfenner /* 145756893Sfenner * Otherwise, just print out the return code 145856893Sfenner */ 145956893Sfenner printf(" errcode"); 146056893Sfenner INTOUT(); 146156893Sfenner } 146256893Sfenner 146356893Sfenner return; 146456893Sfenner 146556893Sfennertrunc: 146656893Sfenner printf(" [|pt]"); 146756893Sfenner} 146856893Sfenner 146956893Sfenner/* 147056893Sfenner * Handle calls to the AFS volume location database service 147156893Sfenner */ 147256893Sfenner 147356893Sfennerstatic void 147456893Sfennervldb_print(register const u_char *bp, int length) 147556893Sfenner{ 147656893Sfenner int vldb_op; 147756893Sfenner unsigned long i; 147856893Sfenner 1479127668Sbms if (length <= (int)sizeof(struct rx_header)) 148056893Sfenner return; 148156893Sfenner 1482127668Sbms if (snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) { 148356893Sfenner goto trunc; 148456893Sfenner } 148556893Sfenner 148656893Sfenner /* 148756893Sfenner * Print out the afs call we're invoking. The table used here was 148856893Sfenner * gleaned from vlserver/vldbint.xg 148956893Sfenner */ 149056893Sfenner 149175115Sfenner vldb_op = EXTRACT_32BITS(bp + sizeof(struct rx_header)); 149256893Sfenner 149356893Sfenner printf(" vldb"); 149456893Sfenner 149556893Sfenner if (is_ubik(vldb_op)) { 1496127668Sbms ubik_print(bp); 149756893Sfenner return; 149856893Sfenner } 149956893Sfenner printf(" call %s", tok2str(vldb_req, "op#%d", vldb_op)); 150056893Sfenner 150156893Sfenner /* 150256893Sfenner * Decode some of the arguments to the VLDB calls 150356893Sfenner */ 150456893Sfenner 150556893Sfenner bp += sizeof(struct rx_header) + 4; 150656893Sfenner 150756893Sfenner switch (vldb_op) { 150856893Sfenner case 501: /* Create new volume */ 150956893Sfenner case 517: /* Create entry N */ 151056893Sfenner VECOUT(VLNAMEMAX); 151156893Sfenner break; 151256893Sfenner case 502: /* Delete entry */ 151356893Sfenner case 503: /* Get entry by ID */ 151456893Sfenner case 507: /* Update entry */ 151556893Sfenner case 508: /* Set lock */ 151656893Sfenner case 509: /* Release lock */ 151756893Sfenner case 518: /* Get entry by ID N */ 151856893Sfenner printf(" volid"); 151956893Sfenner INTOUT(); 152075115Sfenner TCHECK2(bp[0], sizeof(int32_t)); 152175115Sfenner i = EXTRACT_32BITS(bp); 152256893Sfenner bp += sizeof(int32_t); 152356893Sfenner if (i <= 2) 152456893Sfenner printf(" type %s", voltype[i]); 152556893Sfenner break; 152656893Sfenner case 504: /* Get entry by name */ 152756893Sfenner case 519: /* Get entry by name N */ 152856893Sfenner case 524: /* Update entry by name */ 152956893Sfenner case 527: /* Get entry by name U */ 153056893Sfenner STROUT(VLNAMEMAX); 153156893Sfenner break; 153256893Sfenner case 505: /* Get new vol id */ 153356893Sfenner printf(" bump"); 153456893Sfenner INTOUT(); 153556893Sfenner break; 153656893Sfenner case 506: /* Replace entry */ 153756893Sfenner case 520: /* Replace entry N */ 153856893Sfenner printf(" volid"); 153956893Sfenner INTOUT(); 154075115Sfenner TCHECK2(bp[0], sizeof(int32_t)); 154175115Sfenner i = EXTRACT_32BITS(bp); 154256893Sfenner bp += sizeof(int32_t); 154356893Sfenner if (i <= 2) 154456893Sfenner printf(" type %s", voltype[i]); 154556893Sfenner VECOUT(VLNAMEMAX); 154656893Sfenner break; 154756893Sfenner case 510: /* List entry */ 154856893Sfenner case 521: /* List entry N */ 154956893Sfenner printf(" index"); 155056893Sfenner INTOUT(); 155156893Sfenner break; 155256893Sfenner default: 155356893Sfenner ; 155456893Sfenner } 155556893Sfenner 155656893Sfenner return; 155756893Sfenner 155856893Sfennertrunc: 155956893Sfenner printf(" [|vldb]"); 156056893Sfenner} 156156893Sfenner 156256893Sfenner/* 156356893Sfenner * Handle replies to the AFS volume location database service 156456893Sfenner */ 156556893Sfenner 156656893Sfennerstatic void 156756893Sfennervldb_reply_print(register const u_char *bp, int length, int32_t opcode) 156856893Sfenner{ 156956893Sfenner struct rx_header *rxh; 157056893Sfenner unsigned long i; 157156893Sfenner 1572127668Sbms if (length < (int)sizeof(struct rx_header)) 157356893Sfenner return; 157456893Sfenner 157556893Sfenner rxh = (struct rx_header *) bp; 157656893Sfenner 157756893Sfenner /* 157856893Sfenner * Print out the afs call we're invoking. The table used here was 157956893Sfenner * gleaned from vlserver/vldbint.xg. Check to see if it's a 158056893Sfenner * Ubik call, however. 158156893Sfenner */ 158256893Sfenner 158356893Sfenner printf(" vldb"); 158456893Sfenner 158556893Sfenner if (is_ubik(opcode)) { 158656893Sfenner ubik_reply_print(bp, length, opcode); 158756893Sfenner return; 158856893Sfenner } 158956893Sfenner 159056893Sfenner printf(" reply %s", tok2str(vldb_req, "op#%d", opcode)); 159156893Sfenner 159256893Sfenner bp += sizeof(struct rx_header); 159356893Sfenner 159456893Sfenner /* 159556893Sfenner * If it was a data packet, interpret the response 159656893Sfenner */ 159756893Sfenner 159856893Sfenner if (rxh->type == RX_PACKET_TYPE_DATA) 159956893Sfenner switch (opcode) { 160056893Sfenner case 510: /* List entry */ 160156893Sfenner printf(" count"); 160256893Sfenner INTOUT(); 160356893Sfenner printf(" nextindex"); 160456893Sfenner INTOUT(); 160556893Sfenner case 503: /* Get entry by id */ 160656893Sfenner case 504: /* Get entry by name */ 160756893Sfenner { unsigned long nservers, j; 160856893Sfenner VECOUT(VLNAMEMAX); 160975115Sfenner TCHECK2(bp[0], sizeof(int32_t)); 161056893Sfenner bp += sizeof(int32_t); 161156893Sfenner printf(" numservers"); 161275115Sfenner TCHECK2(bp[0], sizeof(int32_t)); 161375115Sfenner nservers = EXTRACT_32BITS(bp); 161456893Sfenner bp += sizeof(int32_t); 161556893Sfenner printf(" %lu", nservers); 161656893Sfenner printf(" servers"); 161756893Sfenner for (i = 0; i < 8; i++) { 161875115Sfenner TCHECK2(bp[0], sizeof(int32_t)); 161956893Sfenner if (i < nservers) 162056893Sfenner printf(" %s", 1621127668Sbms intoa(((struct in_addr *) bp)->s_addr)); 162256893Sfenner bp += sizeof(int32_t); 162356893Sfenner } 162456893Sfenner printf(" partitions"); 162556893Sfenner for (i = 0; i < 8; i++) { 162675115Sfenner TCHECK2(bp[0], sizeof(int32_t)); 162775115Sfenner j = EXTRACT_32BITS(bp); 162856893Sfenner if (i < nservers && j <= 26) 162956893Sfenner printf(" %c", 'a' + (int)j); 163056893Sfenner else if (i < nservers) 163156893Sfenner printf(" %lu", j); 163256893Sfenner bp += sizeof(int32_t); 163356893Sfenner } 163475115Sfenner TCHECK2(bp[0], 8 * sizeof(int32_t)); 163556893Sfenner bp += 8 * sizeof(int32_t); 163656893Sfenner printf(" rwvol"); 163756893Sfenner UINTOUT(); 163856893Sfenner printf(" rovol"); 163956893Sfenner UINTOUT(); 164056893Sfenner printf(" backup"); 164156893Sfenner UINTOUT(); 164256893Sfenner } 164356893Sfenner break; 164456893Sfenner case 505: /* Get new volume ID */ 164556893Sfenner printf(" newvol"); 164656893Sfenner UINTOUT(); 164756893Sfenner break; 164856893Sfenner case 521: /* List entry */ 164956893Sfenner case 529: /* List entry U */ 165056893Sfenner printf(" count"); 165156893Sfenner INTOUT(); 165256893Sfenner printf(" nextindex"); 165356893Sfenner INTOUT(); 165456893Sfenner case 518: /* Get entry by ID N */ 165556893Sfenner case 519: /* Get entry by name N */ 165656893Sfenner { unsigned long nservers, j; 165756893Sfenner VECOUT(VLNAMEMAX); 165856893Sfenner printf(" numservers"); 165975115Sfenner TCHECK2(bp[0], sizeof(int32_t)); 166075115Sfenner nservers = EXTRACT_32BITS(bp); 166156893Sfenner bp += sizeof(int32_t); 166256893Sfenner printf(" %lu", nservers); 166356893Sfenner printf(" servers"); 166456893Sfenner for (i = 0; i < 13; i++) { 166575115Sfenner TCHECK2(bp[0], sizeof(int32_t)); 166656893Sfenner if (i < nservers) 166756893Sfenner printf(" %s", 1668127668Sbms intoa(((struct in_addr *) bp)->s_addr)); 166956893Sfenner bp += sizeof(int32_t); 167056893Sfenner } 167156893Sfenner printf(" partitions"); 167256893Sfenner for (i = 0; i < 13; i++) { 167375115Sfenner TCHECK2(bp[0], sizeof(int32_t)); 167475115Sfenner j = EXTRACT_32BITS(bp); 167556893Sfenner if (i < nservers && j <= 26) 167656893Sfenner printf(" %c", 'a' + (int)j); 167756893Sfenner else if (i < nservers) 167856893Sfenner printf(" %lu", j); 167956893Sfenner bp += sizeof(int32_t); 168056893Sfenner } 168175115Sfenner TCHECK2(bp[0], 13 * sizeof(int32_t)); 168256893Sfenner bp += 13 * sizeof(int32_t); 168356893Sfenner printf(" rwvol"); 168456893Sfenner UINTOUT(); 168556893Sfenner printf(" rovol"); 168656893Sfenner UINTOUT(); 168756893Sfenner printf(" backup"); 168856893Sfenner UINTOUT(); 168956893Sfenner } 169056893Sfenner break; 169156893Sfenner case 526: /* Get entry by ID U */ 169256893Sfenner case 527: /* Get entry by name U */ 169356893Sfenner { unsigned long nservers, j; 169456893Sfenner VECOUT(VLNAMEMAX); 169556893Sfenner printf(" numservers"); 169675115Sfenner TCHECK2(bp[0], sizeof(int32_t)); 169775115Sfenner nservers = EXTRACT_32BITS(bp); 169856893Sfenner bp += sizeof(int32_t); 169956893Sfenner printf(" %lu", nservers); 170056893Sfenner printf(" servers"); 170156893Sfenner for (i = 0; i < 13; i++) { 170256893Sfenner if (i < nservers) { 170356893Sfenner printf(" afsuuid"); 170456893Sfenner AFSUUIDOUT(); 170556893Sfenner } else { 170675115Sfenner TCHECK2(bp[0], 44); 170756893Sfenner bp += 44; 170856893Sfenner } 170956893Sfenner } 171075115Sfenner TCHECK2(bp[0], 4 * 13); 171156893Sfenner bp += 4 * 13; 171256893Sfenner printf(" partitions"); 171356893Sfenner for (i = 0; i < 13; i++) { 171475115Sfenner TCHECK2(bp[0], sizeof(int32_t)); 171575115Sfenner j = EXTRACT_32BITS(bp); 171656893Sfenner if (i < nservers && j <= 26) 171756893Sfenner printf(" %c", 'a' + (int)j); 171856893Sfenner else if (i < nservers) 171956893Sfenner printf(" %lu", j); 172056893Sfenner bp += sizeof(int32_t); 172156893Sfenner } 172275115Sfenner TCHECK2(bp[0], 13 * sizeof(int32_t)); 172356893Sfenner bp += 13 * sizeof(int32_t); 172456893Sfenner printf(" rwvol"); 172556893Sfenner UINTOUT(); 172656893Sfenner printf(" rovol"); 172756893Sfenner UINTOUT(); 172856893Sfenner printf(" backup"); 172956893Sfenner UINTOUT(); 173056893Sfenner } 173156893Sfenner default: 173256893Sfenner ; 173356893Sfenner } 1734127668Sbms 173556893Sfenner else { 173656893Sfenner /* 173756893Sfenner * Otherwise, just print out the return code 173856893Sfenner */ 173956893Sfenner printf(" errcode"); 174056893Sfenner INTOUT(); 174156893Sfenner } 174256893Sfenner 174356893Sfenner return; 174456893Sfenner 174556893Sfennertrunc: 174656893Sfenner printf(" [|vldb]"); 174756893Sfenner} 174856893Sfenner 174956893Sfenner/* 175056893Sfenner * Handle calls to the AFS Kerberos Authentication service 175156893Sfenner */ 175256893Sfenner 175356893Sfennerstatic void 175456893Sfennerkauth_print(register const u_char *bp, int length) 175556893Sfenner{ 175656893Sfenner int kauth_op; 175756893Sfenner 1758127668Sbms if (length <= (int)sizeof(struct rx_header)) 175956893Sfenner return; 176056893Sfenner 1761127668Sbms if (snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) { 176256893Sfenner goto trunc; 176356893Sfenner } 176456893Sfenner 176556893Sfenner /* 176656893Sfenner * Print out the afs call we're invoking. The table used here was 176756893Sfenner * gleaned from kauth/kauth.rg 176856893Sfenner */ 176956893Sfenner 177075115Sfenner kauth_op = EXTRACT_32BITS(bp + sizeof(struct rx_header)); 177156893Sfenner 177256893Sfenner printf(" kauth"); 177356893Sfenner 177456893Sfenner if (is_ubik(kauth_op)) { 1775127668Sbms ubik_print(bp); 177656893Sfenner return; 177756893Sfenner } 177856893Sfenner 177956893Sfenner 178056893Sfenner printf(" call %s", tok2str(kauth_req, "op#%d", kauth_op)); 178156893Sfenner 178256893Sfenner /* 178356893Sfenner * Decode some of the arguments to the KA calls 178456893Sfenner */ 178556893Sfenner 178656893Sfenner bp += sizeof(struct rx_header) + 4; 178756893Sfenner 178856893Sfenner switch (kauth_op) { 178956893Sfenner case 1: /* Authenticate old */; 179056893Sfenner case 21: /* Authenticate */ 179156893Sfenner case 22: /* Authenticate-V2 */ 179256893Sfenner case 2: /* Change PW */ 179356893Sfenner case 5: /* Set fields */ 179456893Sfenner case 6: /* Create user */ 179556893Sfenner case 7: /* Delete user */ 179656893Sfenner case 8: /* Get entry */ 179756893Sfenner case 14: /* Unlock */ 179856893Sfenner case 15: /* Lock status */ 179956893Sfenner printf(" principal"); 180056893Sfenner STROUT(KANAMEMAX); 180156893Sfenner STROUT(KANAMEMAX); 180256893Sfenner break; 180356893Sfenner case 3: /* GetTicket-old */ 180456893Sfenner case 23: /* GetTicket */ 180556893Sfenner { 180656893Sfenner int i; 180756893Sfenner printf(" kvno"); 180856893Sfenner INTOUT(); 180956893Sfenner printf(" domain"); 181056893Sfenner STROUT(KANAMEMAX); 181175115Sfenner TCHECK2(bp[0], sizeof(int32_t)); 181275115Sfenner i = (int) EXTRACT_32BITS(bp); 181356893Sfenner bp += sizeof(int32_t); 181475115Sfenner TCHECK2(bp[0], i); 181556893Sfenner bp += i; 181656893Sfenner printf(" principal"); 181756893Sfenner STROUT(KANAMEMAX); 181856893Sfenner STROUT(KANAMEMAX); 181956893Sfenner break; 182056893Sfenner } 182156893Sfenner case 4: /* Set Password */ 182256893Sfenner printf(" principal"); 182356893Sfenner STROUT(KANAMEMAX); 182456893Sfenner STROUT(KANAMEMAX); 182556893Sfenner printf(" kvno"); 182656893Sfenner INTOUT(); 182756893Sfenner break; 182856893Sfenner case 12: /* Get password */ 182956893Sfenner printf(" name"); 183056893Sfenner STROUT(KANAMEMAX); 183156893Sfenner break; 183256893Sfenner default: 183356893Sfenner ; 183456893Sfenner } 183556893Sfenner 183656893Sfenner return; 183756893Sfenner 183856893Sfennertrunc: 183956893Sfenner printf(" [|kauth]"); 184056893Sfenner} 184156893Sfenner 184256893Sfenner/* 184356893Sfenner * Handle replies to the AFS Kerberos Authentication Service 184456893Sfenner */ 184556893Sfenner 184656893Sfennerstatic void 184756893Sfennerkauth_reply_print(register const u_char *bp, int length, int32_t opcode) 184856893Sfenner{ 184956893Sfenner struct rx_header *rxh; 185056893Sfenner 1851127668Sbms if (length <= (int)sizeof(struct rx_header)) 185256893Sfenner return; 185356893Sfenner 185456893Sfenner rxh = (struct rx_header *) bp; 185556893Sfenner 185656893Sfenner /* 185756893Sfenner * Print out the afs call we're invoking. The table used here was 185856893Sfenner * gleaned from kauth/kauth.rg 185956893Sfenner */ 1860127668Sbms 186156893Sfenner printf(" kauth"); 186256893Sfenner 186356893Sfenner if (is_ubik(opcode)) { 186456893Sfenner ubik_reply_print(bp, length, opcode); 186556893Sfenner return; 186656893Sfenner } 186756893Sfenner 186856893Sfenner printf(" reply %s", tok2str(kauth_req, "op#%d", opcode)); 186956893Sfenner 187056893Sfenner bp += sizeof(struct rx_header); 187156893Sfenner 187256893Sfenner /* 187356893Sfenner * If it was a data packet, interpret the response. 187456893Sfenner */ 187556893Sfenner 187656893Sfenner if (rxh->type == RX_PACKET_TYPE_DATA) 187756893Sfenner /* Well, no, not really. Leave this for later */ 187856893Sfenner ; 187956893Sfenner else { 188056893Sfenner /* 188156893Sfenner * Otherwise, just print out the return code 188256893Sfenner */ 188356893Sfenner printf(" errcode"); 188456893Sfenner INTOUT(); 188556893Sfenner } 188656893Sfenner 188756893Sfenner return; 188856893Sfenner 188956893Sfennertrunc: 189056893Sfenner printf(" [|kauth]"); 189156893Sfenner} 189256893Sfenner 189356893Sfenner/* 189456893Sfenner * Handle calls to the AFS Volume location service 189556893Sfenner */ 189656893Sfenner 189756893Sfennerstatic void 189856893Sfennervol_print(register const u_char *bp, int length) 189956893Sfenner{ 190056893Sfenner int vol_op; 190156893Sfenner 1902127668Sbms if (length <= (int)sizeof(struct rx_header)) 190356893Sfenner return; 190456893Sfenner 1905127668Sbms if (snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) { 190656893Sfenner goto trunc; 190756893Sfenner } 190856893Sfenner 190956893Sfenner /* 191056893Sfenner * Print out the afs call we're invoking. The table used here was 191156893Sfenner * gleaned from volser/volint.xg 191256893Sfenner */ 191356893Sfenner 191475115Sfenner vol_op = EXTRACT_32BITS(bp + sizeof(struct rx_header)); 191556893Sfenner 191656893Sfenner printf(" vol call %s", tok2str(vol_req, "op#%d", vol_op)); 191756893Sfenner 191856893Sfenner /* 191956893Sfenner * Normally there would be a switch statement here to decode the 192056893Sfenner * arguments to the AFS call, but since I don't have access to 192156893Sfenner * an AFS server (yet) and I'm not an AFS admin, I can't 192256893Sfenner * test any of these calls. Leave this blank for now. 192356893Sfenner */ 192456893Sfenner 192556893Sfenner return; 192656893Sfenner 192756893Sfennertrunc: 192856893Sfenner printf(" [|vol]"); 192956893Sfenner} 193056893Sfenner 193156893Sfenner/* 193256893Sfenner * Handle replies to the AFS Volume Service 193356893Sfenner */ 193456893Sfenner 193556893Sfennerstatic void 193656893Sfennervol_reply_print(register const u_char *bp, int length, int32_t opcode) 193756893Sfenner{ 193856893Sfenner struct rx_header *rxh; 193956893Sfenner 1940127668Sbms if (length <= (int)sizeof(struct rx_header)) 194156893Sfenner return; 194256893Sfenner 194356893Sfenner rxh = (struct rx_header *) bp; 194456893Sfenner 194556893Sfenner /* 194656893Sfenner * Print out the afs call we're invoking. The table used here was 194756893Sfenner * gleaned from volser/volint.xg 194856893Sfenner */ 1949127668Sbms 195056893Sfenner printf(" vol reply %s", tok2str(vol_req, "op#%d", opcode)); 195156893Sfenner 195256893Sfenner bp += sizeof(struct rx_header); 195356893Sfenner 195456893Sfenner /* 195556893Sfenner * If it was a data packet, interpret the response. 195656893Sfenner */ 195756893Sfenner 195856893Sfenner if (rxh->type == RX_PACKET_TYPE_DATA) 195956893Sfenner /* Well, no, not really. Leave this for later */ 196056893Sfenner ; 196156893Sfenner else { 196256893Sfenner /* 196356893Sfenner * Otherwise, just print out the return code 196456893Sfenner */ 196556893Sfenner printf(" errcode"); 196656893Sfenner INTOUT(); 196756893Sfenner } 196856893Sfenner 196956893Sfenner return; 197056893Sfenner 197156893Sfennertrunc: 197256893Sfenner printf(" [|vol]"); 197356893Sfenner} 197456893Sfenner 197556893Sfenner/* 197656893Sfenner * Handle calls to the AFS BOS service 197756893Sfenner */ 197856893Sfenner 197956893Sfennerstatic void 198056893Sfennerbos_print(register const u_char *bp, int length) 198156893Sfenner{ 198256893Sfenner int bos_op; 198356893Sfenner 1984127668Sbms if (length <= (int)sizeof(struct rx_header)) 198556893Sfenner return; 198656893Sfenner 1987127668Sbms if (snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) { 198856893Sfenner goto trunc; 198956893Sfenner } 199056893Sfenner 199156893Sfenner /* 199256893Sfenner * Print out the afs call we're invoking. The table used here was 199356893Sfenner * gleaned from bozo/bosint.xg 199456893Sfenner */ 199556893Sfenner 199675115Sfenner bos_op = EXTRACT_32BITS(bp + sizeof(struct rx_header)); 199756893Sfenner 199856893Sfenner printf(" bos call %s", tok2str(bos_req, "op#%d", bos_op)); 199956893Sfenner 200056893Sfenner /* 200156893Sfenner * Decode some of the arguments to the BOS calls 200256893Sfenner */ 200356893Sfenner 200456893Sfenner bp += sizeof(struct rx_header) + 4; 200556893Sfenner 200656893Sfenner switch (bos_op) { 200756893Sfenner case 80: /* Create B node */ 200856893Sfenner printf(" type"); 200956893Sfenner STROUT(BOSNAMEMAX); 201056893Sfenner printf(" instance"); 201156893Sfenner STROUT(BOSNAMEMAX); 201256893Sfenner break; 201356893Sfenner case 81: /* Delete B node */ 201456893Sfenner case 83: /* Get status */ 201556893Sfenner case 85: /* Get instance info */ 201656893Sfenner case 87: /* Add super user */ 201756893Sfenner case 88: /* Delete super user */ 201856893Sfenner case 93: /* Set cell name */ 201956893Sfenner case 96: /* Add cell host */ 202056893Sfenner case 97: /* Delete cell host */ 202156893Sfenner case 104: /* Restart */ 202256893Sfenner case 106: /* Uninstall */ 202356893Sfenner case 108: /* Exec */ 202456893Sfenner case 112: /* Getlog */ 202556893Sfenner case 114: /* Get instance strings */ 202656893Sfenner STROUT(BOSNAMEMAX); 202756893Sfenner break; 202856893Sfenner case 82: /* Set status */ 202956893Sfenner case 98: /* Set T status */ 203056893Sfenner STROUT(BOSNAMEMAX); 203156893Sfenner printf(" status"); 203256893Sfenner INTOUT(); 203356893Sfenner break; 203456893Sfenner case 86: /* Get instance parm */ 203556893Sfenner STROUT(BOSNAMEMAX); 203656893Sfenner printf(" num"); 203756893Sfenner INTOUT(); 203856893Sfenner break; 203956893Sfenner case 84: /* Enumerate instance */ 204056893Sfenner case 89: /* List super users */ 204156893Sfenner case 90: /* List keys */ 204256893Sfenner case 91: /* Add key */ 204356893Sfenner case 92: /* Delete key */ 204456893Sfenner case 95: /* Get cell host */ 204556893Sfenner INTOUT(); 204656893Sfenner break; 204756893Sfenner case 105: /* Install */ 204856893Sfenner STROUT(BOSNAMEMAX); 204956893Sfenner printf(" size"); 205056893Sfenner INTOUT(); 205156893Sfenner printf(" flags"); 205256893Sfenner INTOUT(); 205356893Sfenner printf(" date"); 205456893Sfenner INTOUT(); 205556893Sfenner break; 205656893Sfenner default: 205756893Sfenner ; 205856893Sfenner } 205956893Sfenner 206056893Sfenner return; 206156893Sfenner 206256893Sfennertrunc: 206356893Sfenner printf(" [|bos]"); 206456893Sfenner} 206556893Sfenner 206656893Sfenner/* 206756893Sfenner * Handle replies to the AFS BOS Service 206856893Sfenner */ 206956893Sfenner 207056893Sfennerstatic void 207156893Sfennerbos_reply_print(register const u_char *bp, int length, int32_t opcode) 207256893Sfenner{ 207356893Sfenner struct rx_header *rxh; 207456893Sfenner 2075127668Sbms if (length <= (int)sizeof(struct rx_header)) 207656893Sfenner return; 207756893Sfenner 207856893Sfenner rxh = (struct rx_header *) bp; 207956893Sfenner 208056893Sfenner /* 208156893Sfenner * Print out the afs call we're invoking. The table used here was 208256893Sfenner * gleaned from volser/volint.xg 208356893Sfenner */ 2084127668Sbms 208556893Sfenner printf(" bos reply %s", tok2str(bos_req, "op#%d", opcode)); 208656893Sfenner 208756893Sfenner bp += sizeof(struct rx_header); 208856893Sfenner 208956893Sfenner /* 209056893Sfenner * If it was a data packet, interpret the response. 209156893Sfenner */ 209256893Sfenner 209356893Sfenner if (rxh->type == RX_PACKET_TYPE_DATA) 209456893Sfenner /* Well, no, not really. Leave this for later */ 209556893Sfenner ; 209656893Sfenner else { 209756893Sfenner /* 209856893Sfenner * Otherwise, just print out the return code 209956893Sfenner */ 210056893Sfenner printf(" errcode"); 210156893Sfenner INTOUT(); 210256893Sfenner } 210356893Sfenner 210456893Sfenner return; 210556893Sfenner 210656893Sfennertrunc: 210756893Sfenner printf(" [|bos]"); 210856893Sfenner} 210956893Sfenner 211056893Sfenner/* 211156893Sfenner * Check to see if this is a Ubik opcode. 211256893Sfenner */ 211356893Sfenner 211456893Sfennerstatic int 211556893Sfenneris_ubik(u_int32_t opcode) 211656893Sfenner{ 211756893Sfenner if ((opcode >= VOTE_LOW && opcode <= VOTE_HIGH) || 211856893Sfenner (opcode >= DISK_LOW && opcode <= DISK_HIGH)) 211956893Sfenner return(1); 212056893Sfenner else 212156893Sfenner return(0); 212256893Sfenner} 212356893Sfenner 212456893Sfenner/* 212556893Sfenner * Handle Ubik opcodes to any one of the replicated database services 212656893Sfenner */ 212756893Sfenner 212856893Sfennerstatic void 2129127668Sbmsubik_print(register const u_char *bp) 213056893Sfenner{ 213156893Sfenner int ubik_op; 213256893Sfenner int32_t temp; 213356893Sfenner 213456893Sfenner /* 213556893Sfenner * Print out the afs call we're invoking. The table used here was 213656893Sfenner * gleaned from ubik/ubik_int.xg 213756893Sfenner */ 213856893Sfenner 213975115Sfenner ubik_op = EXTRACT_32BITS(bp + sizeof(struct rx_header)); 214056893Sfenner 214156893Sfenner printf(" ubik call %s", tok2str(ubik_req, "op#%d", ubik_op)); 214256893Sfenner 214356893Sfenner /* 214456893Sfenner * Decode some of the arguments to the Ubik calls 214556893Sfenner */ 214656893Sfenner 214756893Sfenner bp += sizeof(struct rx_header) + 4; 214856893Sfenner 214956893Sfenner switch (ubik_op) { 215056893Sfenner case 10000: /* Beacon */ 215175115Sfenner TCHECK2(bp[0], 4); 215275115Sfenner temp = EXTRACT_32BITS(bp); 215356893Sfenner bp += sizeof(int32_t); 215456893Sfenner printf(" syncsite %s", temp ? "yes" : "no"); 215556893Sfenner printf(" votestart"); 215656893Sfenner DATEOUT(); 215756893Sfenner printf(" dbversion"); 215856893Sfenner UBIK_VERSIONOUT(); 215956893Sfenner printf(" tid"); 216056893Sfenner UBIK_VERSIONOUT(); 216156893Sfenner break; 216256893Sfenner case 10003: /* Get sync site */ 216356893Sfenner printf(" site"); 216456893Sfenner UINTOUT(); 216556893Sfenner break; 216656893Sfenner case 20000: /* Begin */ 216756893Sfenner case 20001: /* Commit */ 216856893Sfenner case 20007: /* Abort */ 216956893Sfenner case 20008: /* Release locks */ 217056893Sfenner case 20010: /* Writev */ 217156893Sfenner printf(" tid"); 217256893Sfenner UBIK_VERSIONOUT(); 217356893Sfenner break; 217456893Sfenner case 20002: /* Lock */ 217556893Sfenner printf(" tid"); 217656893Sfenner UBIK_VERSIONOUT(); 217756893Sfenner printf(" file"); 217856893Sfenner INTOUT(); 217956893Sfenner printf(" pos"); 218056893Sfenner INTOUT(); 218156893Sfenner printf(" length"); 218256893Sfenner INTOUT(); 218375115Sfenner temp = EXTRACT_32BITS(bp); 218456893Sfenner bp += sizeof(int32_t); 218556893Sfenner tok2str(ubik_lock_types, "type %d", temp); 218656893Sfenner break; 218756893Sfenner case 20003: /* Write */ 218856893Sfenner printf(" tid"); 218956893Sfenner UBIK_VERSIONOUT(); 219056893Sfenner printf(" file"); 219156893Sfenner INTOUT(); 219256893Sfenner printf(" pos"); 219356893Sfenner INTOUT(); 219456893Sfenner break; 219556893Sfenner case 20005: /* Get file */ 219656893Sfenner printf(" file"); 219756893Sfenner INTOUT(); 219856893Sfenner break; 219956893Sfenner case 20006: /* Send file */ 220056893Sfenner printf(" file"); 220156893Sfenner INTOUT(); 220256893Sfenner printf(" length"); 220356893Sfenner INTOUT(); 220456893Sfenner printf(" dbversion"); 220556893Sfenner UBIK_VERSIONOUT(); 220656893Sfenner break; 220756893Sfenner case 20009: /* Truncate */ 220856893Sfenner printf(" tid"); 220956893Sfenner UBIK_VERSIONOUT(); 221056893Sfenner printf(" file"); 221156893Sfenner INTOUT(); 221256893Sfenner printf(" length"); 221356893Sfenner INTOUT(); 221456893Sfenner break; 221556893Sfenner case 20012: /* Set version */ 221656893Sfenner printf(" tid"); 221756893Sfenner UBIK_VERSIONOUT(); 221856893Sfenner printf(" oldversion"); 221956893Sfenner UBIK_VERSIONOUT(); 222056893Sfenner printf(" newversion"); 222156893Sfenner UBIK_VERSIONOUT(); 222256893Sfenner break; 222356893Sfenner default: 222456893Sfenner ; 222556893Sfenner } 222656893Sfenner 222756893Sfenner return; 222856893Sfenner 222956893Sfennertrunc: 223056893Sfenner printf(" [|ubik]"); 223156893Sfenner} 223256893Sfenner 223356893Sfenner/* 223456893Sfenner * Handle Ubik replies to any one of the replicated database services 223556893Sfenner */ 223656893Sfenner 223756893Sfennerstatic void 223856893Sfennerubik_reply_print(register const u_char *bp, int length, int32_t opcode) 223956893Sfenner{ 224056893Sfenner struct rx_header *rxh; 224156893Sfenner 2242127668Sbms if (length < (int)sizeof(struct rx_header)) 224356893Sfenner return; 224456893Sfenner 224556893Sfenner rxh = (struct rx_header *) bp; 224656893Sfenner 224756893Sfenner /* 224856893Sfenner * Print out the ubik call we're invoking. This table was gleaned 224956893Sfenner * from ubik/ubik_int.xg 225056893Sfenner */ 225156893Sfenner 225256893Sfenner printf(" ubik reply %s", tok2str(ubik_req, "op#%d", opcode)); 225356893Sfenner 225456893Sfenner bp += sizeof(struct rx_header); 225556893Sfenner 225656893Sfenner /* 225756893Sfenner * If it was a data packet, print out the arguments to the Ubik calls 225856893Sfenner */ 2259127668Sbms 226056893Sfenner if (rxh->type == RX_PACKET_TYPE_DATA) 226156893Sfenner switch (opcode) { 226256893Sfenner case 10000: /* Beacon */ 226356893Sfenner printf(" vote no"); 226456893Sfenner break; 226556893Sfenner case 20004: /* Get version */ 226656893Sfenner printf(" dbversion"); 226756893Sfenner UBIK_VERSIONOUT(); 226856893Sfenner break; 226956893Sfenner default: 227056893Sfenner ; 227156893Sfenner } 2272127668Sbms 227356893Sfenner /* 227456893Sfenner * Otherwise, print out "yes" it it was a beacon packet (because 227556893Sfenner * that's how yes votes are returned, go figure), otherwise 227656893Sfenner * just print out the error code. 227756893Sfenner */ 227856893Sfenner 227956893Sfenner else 228056893Sfenner switch (opcode) { 228156893Sfenner case 10000: /* Beacon */ 228256893Sfenner printf(" vote yes until"); 228356893Sfenner DATEOUT(); 228456893Sfenner break; 228556893Sfenner default: 228656893Sfenner printf(" errcode"); 228756893Sfenner INTOUT(); 228856893Sfenner } 228956893Sfenner 229056893Sfenner return; 229156893Sfenner 229256893Sfennertrunc: 229356893Sfenner printf(" [|ubik]"); 229456893Sfenner} 229575115Sfenner 229675115Sfenner/* 229775115Sfenner * Handle RX ACK packets. 229875115Sfenner */ 229975115Sfenner 230075115Sfennerstatic void 230175115Sfennerrx_ack_print(register const u_char *bp, int length) 230275115Sfenner{ 230375115Sfenner struct rx_ackPacket *rxa; 230475115Sfenner int i, start, last; 2305172683Smlaier u_int32_t firstPacket; 230675115Sfenner 2307127668Sbms if (length < (int)sizeof(struct rx_header)) 230875115Sfenner return; 230975115Sfenner 231075115Sfenner bp += sizeof(struct rx_header); 231175115Sfenner 231275115Sfenner /* 231375115Sfenner * This may seem a little odd .... the rx_ackPacket structure 231475115Sfenner * contains an array of individual packet acknowledgements 231575115Sfenner * (used for selective ack/nack), but since it's variable in size, 231675115Sfenner * we don't want to truncate based on the size of the whole 231775115Sfenner * rx_ackPacket structure. 231875115Sfenner */ 231975115Sfenner 232075115Sfenner TCHECK2(bp[0], sizeof(struct rx_ackPacket) - RX_MAXACKS); 232175115Sfenner 232275115Sfenner rxa = (struct rx_ackPacket *) bp; 232375115Sfenner bp += (sizeof(struct rx_ackPacket) - RX_MAXACKS); 232475115Sfenner 232575115Sfenner /* 232675115Sfenner * Print out a few useful things from the ack packet structure 232775115Sfenner */ 232875115Sfenner 232975115Sfenner if (vflag > 2) 233075115Sfenner printf(" bufspace %d maxskew %d", 233175115Sfenner (int) EXTRACT_16BITS(&rxa->bufferSpace), 233275115Sfenner (int) EXTRACT_16BITS(&rxa->maxSkew)); 2333127668Sbms 2334172683Smlaier firstPacket = EXTRACT_32BITS(&rxa->firstPacket); 233575115Sfenner printf(" first %d serial %d reason %s", 2336172683Smlaier firstPacket, EXTRACT_32BITS(&rxa->serial), 233775115Sfenner tok2str(rx_ack_reasons, "#%d", (int) rxa->reason)); 2338127668Sbms 233975115Sfenner /* 234075115Sfenner * Okay, now we print out the ack array. The way _this_ works 234175115Sfenner * is that we start at "first", and step through the ack array. 234275115Sfenner * If we have a contiguous range of acks/nacks, try to 234375115Sfenner * collapse them into a range. 234475115Sfenner * 234575115Sfenner * If you're really clever, you might have noticed that this 234675115Sfenner * doesn't seem quite correct. Specifically, due to structure 234775115Sfenner * padding, sizeof(struct rx_ackPacket) - RX_MAXACKS won't actually 234875115Sfenner * yield the start of the ack array (because RX_MAXACKS is 255 234975115Sfenner * and the structure will likely get padded to a 2 or 4 byte 235075115Sfenner * boundary). However, this is the way it's implemented inside 2351127668Sbms * of AFS - the start of the extra fields are at 235275115Sfenner * sizeof(struct rx_ackPacket) - RX_MAXACKS + nAcks, which _isn't_ 235375115Sfenner * the exact start of the ack array. Sigh. That's why we aren't 235475115Sfenner * using bp, but instead use rxa->acks[]. But nAcks gets added 235575115Sfenner * to bp after this, so bp ends up at the right spot. Go figure. 235675115Sfenner */ 235775115Sfenner 235875115Sfenner if (rxa->nAcks != 0) { 235975115Sfenner 236075115Sfenner TCHECK2(bp[0], rxa->nAcks); 236175115Sfenner 236275115Sfenner /* 236375115Sfenner * Sigh, this is gross, but it seems to work to collapse 236475115Sfenner * ranges correctly. 236575115Sfenner */ 236675115Sfenner 236775115Sfenner for (i = 0, start = last = -2; i < rxa->nAcks; i++) 236875115Sfenner if (rxa->acks[i] == RX_ACK_TYPE_ACK) { 236975115Sfenner 237075115Sfenner /* 237175115Sfenner * I figured this deserved _some_ explanation. 237275115Sfenner * First, print "acked" and the packet seq 237375115Sfenner * number if this is the first time we've 237475115Sfenner * seen an acked packet. 237575115Sfenner */ 237675115Sfenner 237775115Sfenner if (last == -2) { 237875115Sfenner printf(" acked %d", 2379172683Smlaier firstPacket + i); 238075115Sfenner start = i; 238175115Sfenner } 238275115Sfenner 238375115Sfenner /* 238475115Sfenner * Otherwise, if the there is a skip in 238575115Sfenner * the range (such as an nacked packet in 238675115Sfenner * the middle of some acked packets), 238775115Sfenner * then print the current packet number 238875115Sfenner * seperated from the last number by 238975115Sfenner * a comma. 239075115Sfenner */ 239175115Sfenner 239275115Sfenner else if (last != i - 1) { 2393172683Smlaier printf(",%d", firstPacket + i); 239475115Sfenner start = i; 239575115Sfenner } 239675115Sfenner 239775115Sfenner /* 239875115Sfenner * We always set last to the value of 239975115Sfenner * the last ack we saw. Conversely, start 240075115Sfenner * is set to the value of the first ack 240175115Sfenner * we saw in a range. 240275115Sfenner */ 240375115Sfenner 240475115Sfenner last = i; 240575115Sfenner 240675115Sfenner /* 240775115Sfenner * Okay, this bit a code gets executed when 240875115Sfenner * we hit a nack ... in _this_ case we 240975115Sfenner * want to print out the range of packets 241075115Sfenner * that were acked, so we need to print 241175115Sfenner * the _previous_ packet number seperated 241275115Sfenner * from the first by a dash (-). Since we 241375115Sfenner * already printed the first packet above, 241475115Sfenner * just print the final packet. Don't 241575115Sfenner * do this if there will be a single-length 241675115Sfenner * range. 241775115Sfenner */ 241875115Sfenner } else if (last == i - 1 && start != last) 2419172683Smlaier printf("-%d", firstPacket + i - 1); 2420127668Sbms 242175115Sfenner /* 242275115Sfenner * So, what's going on here? We ran off the end of the 242375115Sfenner * ack list, and if we got a range we need to finish it up. 242475115Sfenner * So we need to determine if the last packet in the list 242575115Sfenner * was an ack (if so, then last will be set to it) and 242675115Sfenner * we need to see if the last range didn't start with the 242775115Sfenner * last packet (because if it _did_, then that would mean 242875115Sfenner * that the packet number has already been printed and 242975115Sfenner * we don't need to print it again). 243075115Sfenner */ 243175115Sfenner 243275115Sfenner if (last == i - 1 && start != last) 2433172683Smlaier printf("-%d", firstPacket + i - 1); 243475115Sfenner 243575115Sfenner /* 243675115Sfenner * Same as above, just without comments 243775115Sfenner */ 2438127668Sbms 243975115Sfenner for (i = 0, start = last = -2; i < rxa->nAcks; i++) 244075115Sfenner if (rxa->acks[i] == RX_ACK_TYPE_NACK) { 244175115Sfenner if (last == -2) { 244275115Sfenner printf(" nacked %d", 2443172683Smlaier firstPacket + i); 244475115Sfenner start = i; 244575115Sfenner } else if (last != i - 1) { 2446172683Smlaier printf(",%d", firstPacket + i); 244775115Sfenner start = i; 244875115Sfenner } 244975115Sfenner last = i; 245075115Sfenner } else if (last == i - 1 && start != last) 2451172683Smlaier printf("-%d", firstPacket + i - 1); 2452127668Sbms 245375115Sfenner if (last == i - 1 && start != last) 2454172683Smlaier printf("-%d", firstPacket + i - 1); 245575115Sfenner 245675115Sfenner bp += rxa->nAcks; 245775115Sfenner } 245875115Sfenner 245975115Sfenner 246075115Sfenner /* 246175115Sfenner * These are optional fields; depending on your version of AFS, 246275115Sfenner * you may or may not see them 246375115Sfenner */ 246475115Sfenner 246575115Sfenner#define TRUNCRET(n) if (snapend - bp + 1 <= n) return; 246675115Sfenner 246775115Sfenner if (vflag > 1) { 246875115Sfenner TRUNCRET(4); 246975115Sfenner printf(" ifmtu"); 247075115Sfenner INTOUT(); 247175115Sfenner 247275115Sfenner TRUNCRET(4); 247375115Sfenner printf(" maxmtu"); 247475115Sfenner INTOUT(); 247575115Sfenner 247675115Sfenner TRUNCRET(4); 247775115Sfenner printf(" rwind"); 247875115Sfenner INTOUT(); 247975115Sfenner 248075115Sfenner TRUNCRET(4); 248175115Sfenner printf(" maxpackets"); 248275115Sfenner INTOUT(); 248375115Sfenner } 248475115Sfenner 248575115Sfenner return; 248675115Sfenner 248775115Sfennertrunc: 248875115Sfenner printf(" [|ack]"); 248975115Sfenner} 249075115Sfenner#undef TRUNCRET 2491