print-rx.c revision 98524
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: 898524Sfenner * 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. 1898524Sfenner * 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 3656893Sfennerstatic const char rcsid[] = 3798524Sfenner "@(#) $Header: /tcpdump/master/tcpdump/print-rx.c,v 1.27 2001/10/20 07:41:55 itojun 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> 4775115Sfenner#include <time.h> 4856893Sfenner#include <sys/param.h> 4956893Sfenner#include <sys/time.h> 5056893Sfenner#include <sys/types.h> 5156893Sfenner#include <sys/socket.h> 5256893Sfenner#include <netinet/in.h> 5356893Sfenner#include <arpa/inet.h> 5456893Sfenner 5556893Sfenner#include "interface.h" 5656893Sfenner#include "addrtoname.h" 5775115Sfenner#include "extract.h" 5856893Sfenner 5956893Sfenner#include "rx.h" 6056893Sfenner 6175115Sfenner#include "ip.h" 6275115Sfenner 6356893Sfennerstatic struct tok rx_types[] = { 6456893Sfenner { RX_PACKET_TYPE_DATA, "data" }, 6556893Sfenner { RX_PACKET_TYPE_ACK, "ack" }, 6656893Sfenner { RX_PACKET_TYPE_BUSY, "busy" }, 6756893Sfenner { RX_PACKET_TYPE_ABORT, "abort" }, 6856893Sfenner { RX_PACKET_TYPE_ACKALL, "ackall" }, 6956893Sfenner { RX_PACKET_TYPE_CHALLENGE, "challenge" }, 7056893Sfenner { RX_PACKET_TYPE_RESPONSE, "response" }, 7156893Sfenner { RX_PACKET_TYPE_DEBUG, "debug" }, 7256893Sfenner { RX_PACKET_TYPE_PARAMS, "params" }, 7356893Sfenner { RX_PACKET_TYPE_VERSION, "version" }, 7456893Sfenner { 0, NULL }, 7556893Sfenner}; 7656893Sfenner 7798524Sfennerstatic struct double_tok { 7898524Sfenner int flag; /* Rx flag */ 7998524Sfenner int packetType; /* Packet type */ 8098524Sfenner char *s; /* Flag string */ 8198524Sfenner} rx_flags[] = { 8298524Sfenner { RX_CLIENT_INITIATED, 0, "client-init" }, 8398524Sfenner { RX_REQUEST_ACK, 0, "req-ack" }, 8498524Sfenner { RX_LAST_PACKET, 0, "last-pckt" }, 8598524Sfenner { RX_MORE_PACKETS, 0, "more-pckts" }, 8698524Sfenner { RX_FREE_PACKET, 0, "free-pckt" }, 8798524Sfenner { RX_SLOW_START_OK, RX_PACKET_TYPE_ACK, "slow-start" }, 8898524Sfenner { RX_JUMBO_PACKET, RX_PACKET_TYPE_DATA, "jumbogram" } 8956893Sfenner}; 9056893Sfenner 9156893Sfennerstatic struct tok fs_req[] = { 9256893Sfenner { 130, "fetch-data" }, 9356893Sfenner { 131, "fetch-acl" }, 9456893Sfenner { 132, "fetch-status" }, 9556893Sfenner { 133, "store-data" }, 9656893Sfenner { 134, "store-acl" }, 9756893Sfenner { 135, "store-status" }, 9856893Sfenner { 136, "remove-file" }, 9956893Sfenner { 137, "create-file" }, 10056893Sfenner { 138, "rename" }, 10156893Sfenner { 139, "symlink" }, 10256893Sfenner { 140, "link" }, 10356893Sfenner { 141, "makedir" }, 10456893Sfenner { 142, "rmdir" }, 10556893Sfenner { 143, "oldsetlock" }, 10656893Sfenner { 144, "oldextlock" }, 10756893Sfenner { 145, "oldrellock" }, 10856893Sfenner { 146, "get-stats" }, 10956893Sfenner { 147, "give-cbs" }, 11056893Sfenner { 148, "get-vlinfo" }, 11156893Sfenner { 149, "get-vlstats" }, 11256893Sfenner { 150, "set-vlstats" }, 11356893Sfenner { 151, "get-rootvl" }, 11456893Sfenner { 152, "check-token" }, 11556893Sfenner { 153, "get-time" }, 11656893Sfenner { 154, "nget-vlinfo" }, 11756893Sfenner { 155, "bulk-stat" }, 11856893Sfenner { 156, "setlock" }, 11956893Sfenner { 157, "extlock" }, 12056893Sfenner { 158, "rellock" }, 12156893Sfenner { 159, "xstat-ver" }, 12256893Sfenner { 160, "get-xstat" }, 12356893Sfenner { 161, "dfs-lookup" }, 12456893Sfenner { 162, "dfs-flushcps" }, 12556893Sfenner { 163, "dfs-symlink" }, 12698524Sfenner { 220, "residency" }, 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" }, 14656893Sfenner { 0, NULL }, 14756893Sfenner}; 14856893Sfenner 14956893Sfennerstatic struct tok pt_req[] = { 15056893Sfenner { 500, "new-user" }, 15156893Sfenner { 501, "where-is-it" }, 15256893Sfenner { 502, "dump-entry" }, 15356893Sfenner { 503, "add-to-group" }, 15456893Sfenner { 504, "name-to-id" }, 15556893Sfenner { 505, "id-to-name" }, 15656893Sfenner { 506, "delete" }, 15756893Sfenner { 507, "remove-from-group" }, 15856893Sfenner { 508, "get-cps" }, 15956893Sfenner { 509, "new-entry" }, 16056893Sfenner { 510, "list-max" }, 16156893Sfenner { 511, "set-max" }, 16256893Sfenner { 512, "list-entry" }, 16356893Sfenner { 513, "change-entry" }, 16456893Sfenner { 514, "list-elements" }, 16556893Sfenner { 515, "same-mbr-of" }, 16656893Sfenner { 516, "set-fld-sentry" }, 16756893Sfenner { 517, "list-owned" }, 16856893Sfenner { 518, "get-cps2" }, 16956893Sfenner { 519, "get-host-cps" }, 17056893Sfenner { 520, "update-entry" }, 17198524Sfenner { 521, "list-entries" }, 17256893Sfenner { 0, NULL }, 17356893Sfenner}; 17456893Sfenner 17556893Sfennerstatic struct tok vldb_req[] = { 17656893Sfenner { 501, "create-entry" }, 17756893Sfenner { 502, "delete-entry" }, 17856893Sfenner { 503, "get-entry-by-id" }, 17956893Sfenner { 504, "get-entry-by-name" }, 18056893Sfenner { 505, "get-new-volume-id" }, 18156893Sfenner { 506, "replace-entry" }, 18256893Sfenner { 507, "update-entry" }, 18356893Sfenner { 508, "setlock" }, 18456893Sfenner { 509, "releaselock" }, 18556893Sfenner { 510, "list-entry" }, 18656893Sfenner { 511, "list-attrib" }, 18756893Sfenner { 512, "linked-list" }, 18856893Sfenner { 513, "get-stats" }, 18956893Sfenner { 514, "probe" }, 19056893Sfenner { 515, "get-addrs" }, 19156893Sfenner { 516, "change-addr" }, 19256893Sfenner { 517, "create-entry-n" }, 19356893Sfenner { 518, "get-entry-by-id-n" }, 19456893Sfenner { 519, "get-entry-by-name-n" }, 19556893Sfenner { 520, "replace-entry-n" }, 19656893Sfenner { 521, "list-entry-n" }, 19756893Sfenner { 522, "list-attrib-n" }, 19856893Sfenner { 523, "linked-list-n" }, 19956893Sfenner { 524, "update-entry-by-name" }, 20056893Sfenner { 525, "create-entry-u" }, 20156893Sfenner { 526, "get-entry-by-id-u" }, 20256893Sfenner { 527, "get-entry-by-name-u" }, 20356893Sfenner { 528, "replace-entry-u" }, 20456893Sfenner { 529, "list-entry-u" }, 20556893Sfenner { 530, "list-attrib-u" }, 20656893Sfenner { 531, "linked-list-u" }, 20756893Sfenner { 532, "regaddr" }, 20856893Sfenner { 533, "get-addrs-u" }, 20998524Sfenner { 534, "list-attrib-n2" }, 21056893Sfenner { 0, NULL }, 21156893Sfenner}; 21256893Sfenner 21356893Sfennerstatic struct tok kauth_req[] = { 21456893Sfenner { 1, "auth-old" }, 21556893Sfenner { 21, "authenticate" }, 21656893Sfenner { 22, "authenticate-v2" }, 21756893Sfenner { 2, "change-pw" }, 21856893Sfenner { 3, "get-ticket-old" }, 21956893Sfenner { 23, "get-ticket" }, 22056893Sfenner { 4, "set-pw" }, 22156893Sfenner { 5, "set-fields" }, 22256893Sfenner { 6, "create-user" }, 22356893Sfenner { 7, "delete-user" }, 22456893Sfenner { 8, "get-entry" }, 22556893Sfenner { 9, "list-entry" }, 22656893Sfenner { 10, "get-stats" }, 22756893Sfenner { 11, "debug" }, 22856893Sfenner { 12, "get-pw" }, 22956893Sfenner { 13, "get-random-key" }, 23056893Sfenner { 14, "unlock" }, 23156893Sfenner { 15, "lock-status" }, 23256893Sfenner { 0, NULL }, 23356893Sfenner}; 23456893Sfenner 23556893Sfennerstatic struct tok vol_req[] = { 23656893Sfenner { 100, "create-volume" }, 23756893Sfenner { 101, "delete-volume" }, 23856893Sfenner { 102, "restore" }, 23956893Sfenner { 103, "forward" }, 24056893Sfenner { 104, "end-trans" }, 24156893Sfenner { 105, "clone" }, 24256893Sfenner { 106, "set-flags" }, 24356893Sfenner { 107, "get-flags" }, 24456893Sfenner { 108, "trans-create" }, 24556893Sfenner { 109, "dump" }, 24656893Sfenner { 110, "get-nth-volume" }, 24756893Sfenner { 111, "set-forwarding" }, 24856893Sfenner { 112, "get-name" }, 24956893Sfenner { 113, "get-status" }, 25056893Sfenner { 114, "sig-restore" }, 25156893Sfenner { 115, "list-partitions" }, 25256893Sfenner { 116, "list-volumes" }, 25356893Sfenner { 117, "set-id-types" }, 25456893Sfenner { 118, "monitor" }, 25556893Sfenner { 119, "partition-info" }, 25656893Sfenner { 120, "reclone" }, 25756893Sfenner { 121, "list-one-volume" }, 25856893Sfenner { 122, "nuke" }, 25956893Sfenner { 123, "set-date" }, 26056893Sfenner { 124, "x-list-volumes" }, 26156893Sfenner { 125, "x-list-one-volume" }, 26256893Sfenner { 126, "set-info" }, 26356893Sfenner { 127, "x-list-partitions" }, 26456893Sfenner { 128, "forward-multiple" }, 26556893Sfenner { 0, NULL }, 26656893Sfenner}; 26756893Sfenner 26856893Sfennerstatic struct tok bos_req[] = { 26956893Sfenner { 80, "create-bnode" }, 27056893Sfenner { 81, "delete-bnode" }, 27156893Sfenner { 82, "set-status" }, 27256893Sfenner { 83, "get-status" }, 27356893Sfenner { 84, "enumerate-instance" }, 27456893Sfenner { 85, "get-instance-info" }, 27556893Sfenner { 86, "get-instance-parm" }, 27656893Sfenner { 87, "add-superuser" }, 27756893Sfenner { 88, "delete-superuser" }, 27856893Sfenner { 89, "list-superusers" }, 27956893Sfenner { 90, "list-keys" }, 28056893Sfenner { 91, "add-key" }, 28156893Sfenner { 92, "delete-key" }, 28256893Sfenner { 93, "set-cell-name" }, 28356893Sfenner { 94, "get-cell-name" }, 28456893Sfenner { 95, "get-cell-host" }, 28556893Sfenner { 96, "add-cell-host" }, 28656893Sfenner { 97, "delete-cell-host" }, 28756893Sfenner { 98, "set-t-status" }, 28856893Sfenner { 99, "shutdown-all" }, 28956893Sfenner { 100, "restart-all" }, 29056893Sfenner { 101, "startup-all" }, 29156893Sfenner { 102, "set-noauth-flag" }, 29256893Sfenner { 103, "re-bozo" }, 29356893Sfenner { 104, "restart" }, 29456893Sfenner { 105, "start-bozo-install" }, 29556893Sfenner { 106, "uninstall" }, 29656893Sfenner { 107, "get-dates" }, 29756893Sfenner { 108, "exec" }, 29856893Sfenner { 109, "prune" }, 29956893Sfenner { 110, "set-restart-time" }, 30056893Sfenner { 111, "get-restart-time" }, 30156893Sfenner { 112, "start-bozo-log" }, 30256893Sfenner { 113, "wait-all" }, 30356893Sfenner { 114, "get-instance-strings" }, 30498524Sfenner { 115, "get-restricted" }, 30598524Sfenner { 116, "set-restricted" }, 30656893Sfenner { 0, NULL }, 30756893Sfenner}; 30856893Sfenner 30956893Sfennerstatic struct tok ubik_req[] = { 31056893Sfenner { 10000, "vote-beacon" }, 31156893Sfenner { 10001, "vote-debug-old" }, 31256893Sfenner { 10002, "vote-sdebug-old" }, 31356893Sfenner { 10003, "vote-getsyncsite" }, 31456893Sfenner { 10004, "vote-debug" }, 31556893Sfenner { 10005, "vote-sdebug" }, 31656893Sfenner { 20000, "disk-begin" }, 31756893Sfenner { 20001, "disk-commit" }, 31856893Sfenner { 20002, "disk-lock" }, 31956893Sfenner { 20003, "disk-write" }, 32056893Sfenner { 20004, "disk-getversion" }, 32156893Sfenner { 20005, "disk-getfile" }, 32256893Sfenner { 20006, "disk-sendfile" }, 32356893Sfenner { 20007, "disk-abort" }, 32456893Sfenner { 20008, "disk-releaselocks" }, 32556893Sfenner { 20009, "disk-truncate" }, 32656893Sfenner { 20010, "disk-probe" }, 32756893Sfenner { 20011, "disk-writev" }, 32856893Sfenner { 20012, "disk-interfaceaddr" }, 32956893Sfenner { 20013, "disk-setversion" }, 33056893Sfenner { 0, NULL }, 33156893Sfenner}; 33256893Sfenner 33356893Sfenner#define VOTE_LOW 10000 33456893Sfenner#define VOTE_HIGH 10005 33556893Sfenner#define DISK_LOW 20000 33656893Sfenner#define DISK_HIGH 20013 33756893Sfenner 33856893Sfennerstatic struct tok cb_types[] = { 33956893Sfenner { 1, "exclusive" }, 34056893Sfenner { 2, "shared" }, 34156893Sfenner { 3, "dropped" }, 34256893Sfenner { 0, NULL }, 34356893Sfenner}; 34456893Sfenner 34556893Sfennerstatic struct tok ubik_lock_types[] = { 34656893Sfenner { 1, "read" }, 34756893Sfenner { 2, "write" }, 34856893Sfenner { 3, "wait" }, 34956893Sfenner { 0, NULL }, 35056893Sfenner}; 35156893Sfenner 35256893Sfennerstatic char *voltype[] = { "read-write", "read-only", "backup" }; 35356893Sfenner 35475115Sfennerstatic struct tok afs_fs_errors[] = { 35575115Sfenner { 101, "salvage volume" }, 35675115Sfenner { 102, "no such vnode" }, 35775115Sfenner { 103, "no such volume" }, 35875115Sfenner { 104, "volume exist" }, 35975115Sfenner { 105, "no service" }, 36075115Sfenner { 106, "volume offline" }, 36175115Sfenner { 107, "voline online" }, 36275115Sfenner { 108, "diskfull" }, 36375115Sfenner { 109, "diskquota exceeded" }, 36475115Sfenner { 110, "volume busy" }, 36575115Sfenner { 111, "volume moved" }, 36675115Sfenner { 112, "AFS IO error" }, 36775115Sfenner { -100, "restarting fileserver" }, 36875115Sfenner { 0, NULL } 36975115Sfenner}; 37075115Sfenner 37156893Sfenner/* 37275115Sfenner * Reasons for acknowledging a packet 37375115Sfenner */ 37475115Sfenner 37575115Sfennerstatic struct tok rx_ack_reasons[] = { 37675115Sfenner { 1, "ack requested" }, 37775115Sfenner { 2, "duplicate packet" }, 37875115Sfenner { 3, "out of sequence" }, 37975115Sfenner { 4, "exceeds window" }, 38075115Sfenner { 5, "no buffer space" }, 38175115Sfenner { 6, "ping" }, 38275115Sfenner { 7, "ping response" }, 38375115Sfenner { 8, "delay" }, 38475115Sfenner { 0, NULL }, 38575115Sfenner}; 38675115Sfenner 38775115Sfenner/* 38856893Sfenner * Cache entries we keep around so we can figure out the RX opcode 38956893Sfenner * numbers for replies. This allows us to make sense of RX reply packets. 39056893Sfenner */ 39156893Sfenner 39256893Sfennerstruct rx_cache_entry { 39356893Sfenner u_int32_t callnum; /* Call number (net order) */ 39456893Sfenner struct in_addr client; /* client IP address (net order) */ 39556893Sfenner struct in_addr server; /* server IP address (net order) */ 39656893Sfenner int dport; /* server port (host order) */ 39756893Sfenner u_short serviceId; /* Service identifier (net order) */ 39856893Sfenner u_int32_t opcode; /* RX opcode (host order) */ 39956893Sfenner}; 40056893Sfenner 40156893Sfenner#define RX_CACHE_SIZE 64 40256893Sfenner 40356893Sfennerstatic struct rx_cache_entry rx_cache[RX_CACHE_SIZE]; 40456893Sfenner 40556893Sfennerstatic int rx_cache_next = 0; 40656893Sfennerstatic int rx_cache_hint = 0; 40756893Sfennerstatic void rx_cache_insert(const u_char *, const struct ip *, int, int); 40856893Sfennerstatic int rx_cache_find(const struct rx_header *, const struct ip *, 40956893Sfenner int, int32_t *); 41056893Sfenner 41175115Sfennerstatic void ack_print(const u_char *, int); 41256893Sfennerstatic void fs_print(const u_char *, int); 41356893Sfennerstatic void fs_reply_print(const u_char *, int, int32_t); 41475115Sfennerstatic void acl_print(u_char *, int, u_char *); 41556893Sfennerstatic void cb_print(const u_char *, int); 41656893Sfennerstatic void cb_reply_print(const u_char *, int, int32_t); 41756893Sfennerstatic void prot_print(const u_char *, int); 41856893Sfennerstatic void prot_reply_print(const u_char *, int, int32_t); 41956893Sfennerstatic void vldb_print(const u_char *, int); 42056893Sfennerstatic void vldb_reply_print(const u_char *, int, int32_t); 42156893Sfennerstatic void kauth_print(const u_char *, int); 42256893Sfennerstatic void kauth_reply_print(const u_char *, int, int32_t); 42356893Sfennerstatic void vol_print(const u_char *, int); 42456893Sfennerstatic void vol_reply_print(const u_char *, int, int32_t); 42556893Sfennerstatic void bos_print(const u_char *, int); 42656893Sfennerstatic void bos_reply_print(const u_char *, int, int32_t); 42756893Sfennerstatic void ubik_print(const u_char *, int); 42856893Sfennerstatic void ubik_reply_print(const u_char *, int, int32_t); 42956893Sfenner 43075115Sfennerstatic void rx_ack_print(const u_char *, int); 43175115Sfenner 43256893Sfennerstatic int is_ubik(u_int32_t); 43356893Sfenner 43456893Sfenner/* 43556893Sfenner * Handle the rx-level packet. See if we know what port it's going to so 43656893Sfenner * we can peek at the afs call inside 43756893Sfenner */ 43856893Sfenner 43956893Sfennervoid 44056893Sfennerrx_print(register const u_char *bp, int length, int sport, int dport, 44156893Sfenner u_char *bp2) 44256893Sfenner{ 44356893Sfenner register struct rx_header *rxh; 44456893Sfenner int i; 44556893Sfenner int32_t opcode; 44656893Sfenner 44756893Sfenner if (snapend - bp < sizeof (struct rx_header)) { 44856893Sfenner printf(" [|rx] (%d)", length); 44956893Sfenner return; 45056893Sfenner } 45156893Sfenner 45256893Sfenner rxh = (struct rx_header *) bp; 45356893Sfenner 45456893Sfenner printf(" rx %s", tok2str(rx_types, "type %d", rxh->type)); 45556893Sfenner 45675115Sfenner if (vflag) { 45756893Sfenner int firstflag = 0; 45875115Sfenner 45975115Sfenner if (vflag > 1) 46075115Sfenner printf(" cid %08x call# %d", 46175115Sfenner (int) EXTRACT_32BITS(&rxh->cid), 46275115Sfenner (int) EXTRACT_32BITS(&rxh->callNumber)); 46375115Sfenner 46475115Sfenner printf(" seq %d ser %d", 46575115Sfenner (int) EXTRACT_32BITS(&rxh->seq), 46675115Sfenner (int) EXTRACT_32BITS(&rxh->serial)); 46775115Sfenner 46856893Sfenner if (vflag > 2) 46956893Sfenner printf(" secindex %d serviceid %hu", 47056893Sfenner (int) rxh->securityIndex, 47175115Sfenner EXTRACT_16BITS(&rxh->serviceId)); 47275115Sfenner 47375115Sfenner if (vflag > 1) 47475115Sfenner for (i = 0; i < NUM_RX_FLAGS; i++) { 47598524Sfenner if (rxh->flags & rx_flags[i].flag && 47698524Sfenner (!rx_flags[i].packetType || 47798524Sfenner rxh->type == rx_flags[i].packetType)) { 47875115Sfenner if (!firstflag) { 47975115Sfenner firstflag = 1; 48075115Sfenner printf(" "); 48175115Sfenner } else { 48275115Sfenner printf(","); 48375115Sfenner } 48475115Sfenner printf("<%s>", rx_flags[i].s); 48556893Sfenner } 48656893Sfenner } 48756893Sfenner } 48856893Sfenner 48956893Sfenner /* 49056893Sfenner * Try to handle AFS calls that we know about. Check the destination 49156893Sfenner * port and make sure it's a data packet. Also, make sure the 49256893Sfenner * seq number is 1 (because otherwise it's a continuation packet, 49356893Sfenner * and we can't interpret that). Also, seems that reply packets 49456893Sfenner * do not have the client-init flag set, so we check for that 49556893Sfenner * as well. 49656893Sfenner */ 49756893Sfenner 49875115Sfenner if (rxh->type == RX_PACKET_TYPE_ACK) 49975115Sfenner ack_print(bp, length); 50075115Sfenner else if (rxh->type == RX_PACKET_TYPE_DATA && 50175115Sfenner EXTRACT_32BITS(&rxh->seq) == 1 && 50256893Sfenner rxh->flags & RX_CLIENT_INITIATED) { 50356893Sfenner 50456893Sfenner /* 50556893Sfenner * Insert this call into the call cache table, so we 50656893Sfenner * have a chance to print out replies 50756893Sfenner */ 50856893Sfenner 50956893Sfenner rx_cache_insert(bp, (const struct ip *) bp2, dport, length); 51056893Sfenner 51156893Sfenner switch (dport) { 51256893Sfenner case FS_RX_PORT: /* AFS file service */ 51356893Sfenner fs_print(bp, length); 51456893Sfenner break; 51556893Sfenner case CB_RX_PORT: /* AFS callback service */ 51656893Sfenner cb_print(bp, length); 51756893Sfenner break; 51856893Sfenner case PROT_RX_PORT: /* AFS protection service */ 51956893Sfenner prot_print(bp, length); 52056893Sfenner break; 52156893Sfenner case VLDB_RX_PORT: /* AFS VLDB service */ 52256893Sfenner vldb_print(bp, length); 52356893Sfenner break; 52456893Sfenner case KAUTH_RX_PORT: /* AFS Kerberos auth service */ 52556893Sfenner kauth_print(bp, length); 52656893Sfenner break; 52756893Sfenner case VOL_RX_PORT: /* AFS Volume service */ 52856893Sfenner vol_print(bp, length); 52956893Sfenner break; 53056893Sfenner case BOS_RX_PORT: /* AFS BOS service */ 53156893Sfenner bos_print(bp, length); 53256893Sfenner break; 53356893Sfenner default: 53456893Sfenner ; 53556893Sfenner } 53656893Sfenner 53756893Sfenner /* 53856893Sfenner * If it's a reply (client-init is _not_ set, but seq is one) 53956893Sfenner * then look it up in the cache. If we find it, call the reply 54056893Sfenner * printing functions Note that we handle abort packets here, 54156893Sfenner * because printing out the return code can be useful at times. 54256893Sfenner */ 54356893Sfenner 54456893Sfenner } else if (((rxh->type == RX_PACKET_TYPE_DATA && 54575115Sfenner EXTRACT_32BITS(&rxh->seq) == 1) || 54656893Sfenner rxh->type == RX_PACKET_TYPE_ABORT) && 54756893Sfenner (rxh->flags & RX_CLIENT_INITIATED) == 0 && 54856893Sfenner rx_cache_find(rxh, (const struct ip *) bp2, 54956893Sfenner sport, &opcode)) { 55056893Sfenner 55156893Sfenner switch (sport) { 55256893Sfenner case FS_RX_PORT: /* AFS file service */ 55356893Sfenner fs_reply_print(bp, length, opcode); 55456893Sfenner break; 55556893Sfenner case CB_RX_PORT: /* AFS callback service */ 55656893Sfenner cb_reply_print(bp, length, opcode); 55756893Sfenner break; 55856893Sfenner case PROT_RX_PORT: /* AFS PT service */ 55956893Sfenner prot_reply_print(bp, length, opcode); 56056893Sfenner break; 56156893Sfenner case VLDB_RX_PORT: /* AFS VLDB service */ 56256893Sfenner vldb_reply_print(bp, length, opcode); 56356893Sfenner break; 56456893Sfenner case KAUTH_RX_PORT: /* AFS Kerberos auth service */ 56556893Sfenner kauth_reply_print(bp, length, opcode); 56656893Sfenner break; 56756893Sfenner case VOL_RX_PORT: /* AFS Volume service */ 56856893Sfenner vol_reply_print(bp, length, opcode); 56956893Sfenner break; 57056893Sfenner case BOS_RX_PORT: /* AFS BOS service */ 57156893Sfenner bos_reply_print(bp, length, opcode); 57256893Sfenner break; 57356893Sfenner default: 57456893Sfenner ; 57556893Sfenner } 57656893Sfenner 57775115Sfenner /* 57875115Sfenner * If it's an RX ack packet, then use the appropriate ack decoding 57975115Sfenner * function (there isn't any service-specific information in the 58075115Sfenner * ack packet, so we can use one for all AFS services) 58175115Sfenner */ 58256893Sfenner 58375115Sfenner } else if (rxh->type == RX_PACKET_TYPE_ACK) 58475115Sfenner rx_ack_print(bp, length); 58575115Sfenner 58675115Sfenner 58756893Sfenner printf(" (%d)", length); 58856893Sfenner} 58956893Sfenner 59056893Sfenner/* 59156893Sfenner * Insert an entry into the cache. Taken from print-nfs.c 59256893Sfenner */ 59356893Sfenner 59456893Sfennerstatic void 59556893Sfennerrx_cache_insert(const u_char *bp, const struct ip *ip, int dport, 59656893Sfenner int length) 59756893Sfenner{ 59856893Sfenner struct rx_cache_entry *rxent; 59956893Sfenner const struct rx_header *rxh = (const struct rx_header *) bp; 60056893Sfenner 60156893Sfenner if (snapend - bp + 1 <= sizeof(struct rx_header) + sizeof(int32_t)) 60256893Sfenner return; 60356893Sfenner 60456893Sfenner rxent = &rx_cache[rx_cache_next]; 60556893Sfenner 60656893Sfenner if (++rx_cache_next >= RX_CACHE_SIZE) 60756893Sfenner rx_cache_next = 0; 60856893Sfenner 60956893Sfenner rxent->callnum = rxh->callNumber; 61056893Sfenner rxent->client = ip->ip_src; 61156893Sfenner rxent->server = ip->ip_dst; 61256893Sfenner rxent->dport = dport; 61356893Sfenner rxent->serviceId = rxh->serviceId; 61475115Sfenner rxent->opcode = EXTRACT_32BITS(bp + sizeof(struct rx_header)); 61556893Sfenner} 61656893Sfenner 61756893Sfenner/* 61856893Sfenner * Lookup an entry in the cache. Also taken from print-nfs.c 61956893Sfenner * 62056893Sfenner * Note that because this is a reply, we're looking at the _source_ 62156893Sfenner * port. 62256893Sfenner */ 62356893Sfenner 62456893Sfennerstatic int 62556893Sfennerrx_cache_find(const struct rx_header *rxh, const struct ip *ip, int sport, 62656893Sfenner int32_t *opcode) 62756893Sfenner{ 62856893Sfenner int i; 62956893Sfenner struct rx_cache_entry *rxent; 63056893Sfenner u_int32_t clip = ip->ip_dst.s_addr; 63156893Sfenner u_int32_t sip = ip->ip_src.s_addr; 63256893Sfenner 63356893Sfenner /* Start the search where we last left off */ 63456893Sfenner 63556893Sfenner i = rx_cache_hint; 63656893Sfenner do { 63756893Sfenner rxent = &rx_cache[i]; 63856893Sfenner if (rxent->callnum == rxh->callNumber && 63956893Sfenner rxent->client.s_addr == clip && 64056893Sfenner rxent->server.s_addr == sip && 64156893Sfenner rxent->serviceId == rxh->serviceId && 64256893Sfenner rxent->dport == sport) { 64356893Sfenner 64456893Sfenner /* We got a match! */ 64556893Sfenner 64656893Sfenner rx_cache_hint = i; 64756893Sfenner *opcode = rxent->opcode; 64856893Sfenner return(1); 64956893Sfenner } 65056893Sfenner if (++i > RX_CACHE_SIZE) 65156893Sfenner i = 0; 65256893Sfenner } while (i != rx_cache_hint); 65356893Sfenner 65456893Sfenner /* Our search failed */ 65556893Sfenner return(0); 65656893Sfenner} 65756893Sfenner 65856893Sfenner/* 65956893Sfenner * These extrememly grody macros handle the printing of various AFS stuff. 66056893Sfenner */ 66156893Sfenner 66256893Sfenner#define FIDOUT() { unsigned long n1, n2, n3; \ 66375115Sfenner TCHECK2(bp[0], sizeof(int32_t) * 3); \ 66475115Sfenner n1 = EXTRACT_32BITS(bp); \ 66556893Sfenner bp += sizeof(int32_t); \ 66675115Sfenner n2 = EXTRACT_32BITS(bp); \ 66756893Sfenner bp += sizeof(int32_t); \ 66875115Sfenner n3 = EXTRACT_32BITS(bp); \ 66956893Sfenner bp += sizeof(int32_t); \ 67056893Sfenner printf(" fid %d/%d/%d", (int) n1, (int) n2, (int) n3); \ 67156893Sfenner } 67256893Sfenner 67380231Sfenner#define STROUT(MAX) { unsigned int i; \ 67475115Sfenner TCHECK2(bp[0], sizeof(int32_t)); \ 67580231Sfenner i = EXTRACT_32BITS(bp); \ 67698524Sfenner if (i > (MAX)) \ 67780231Sfenner goto trunc; \ 67856893Sfenner bp += sizeof(int32_t); \ 67980231Sfenner printf(" \""); \ 68080231Sfenner if (fn_printn(bp, i, snapend)) \ 68180231Sfenner goto trunc; \ 68280231Sfenner printf("\""); \ 68356893Sfenner bp += ((i + sizeof(int32_t) - 1) / sizeof(int32_t)) * sizeof(int32_t); \ 68456893Sfenner } 68556893Sfenner 68656893Sfenner#define INTOUT() { int i; \ 68775115Sfenner TCHECK2(bp[0], sizeof(int32_t)); \ 68875115Sfenner i = (int) EXTRACT_32BITS(bp); \ 68956893Sfenner bp += sizeof(int32_t); \ 69056893Sfenner printf(" %d", i); \ 69156893Sfenner } 69256893Sfenner 69356893Sfenner#define UINTOUT() { unsigned long i; \ 69475115Sfenner TCHECK2(bp[0], sizeof(int32_t)); \ 69575115Sfenner i = EXTRACT_32BITS(bp); \ 69656893Sfenner bp += sizeof(int32_t); \ 69756893Sfenner printf(" %lu", i); \ 69856893Sfenner } 69956893Sfenner 70056893Sfenner#define DATEOUT() { time_t t; struct tm *tm; char str[256]; \ 70175115Sfenner TCHECK2(bp[0], sizeof(int32_t)); \ 70275115Sfenner t = (time_t) EXTRACT_32BITS(bp); \ 70356893Sfenner bp += sizeof(int32_t); \ 70456893Sfenner tm = localtime(&t); \ 70556893Sfenner strftime(str, 256, "%Y/%m/%d %T", tm); \ 70656893Sfenner printf(" %s", str); \ 70756893Sfenner } 70856893Sfenner 70956893Sfenner#define STOREATTROUT() { unsigned long mask, i; \ 71075115Sfenner TCHECK2(bp[0], (sizeof(int32_t)*6)); \ 71175115Sfenner mask = EXTRACT_32BITS(bp); bp += sizeof(int32_t); \ 71256893Sfenner if (mask) printf (" StoreStatus"); \ 71356893Sfenner if (mask & 1) { printf(" date"); DATEOUT(); } \ 71456893Sfenner else bp += sizeof(int32_t); \ 71575115Sfenner i = EXTRACT_32BITS(bp); bp += sizeof(int32_t); \ 71656893Sfenner if (mask & 2) printf(" owner %lu", i); \ 71775115Sfenner i = EXTRACT_32BITS(bp); bp += sizeof(int32_t); \ 71856893Sfenner if (mask & 4) printf(" group %lu", i); \ 71975115Sfenner i = EXTRACT_32BITS(bp); bp += sizeof(int32_t); \ 72056893Sfenner if (mask & 8) printf(" mode %lo", i & 07777); \ 72175115Sfenner i = EXTRACT_32BITS(bp); bp += sizeof(int32_t); \ 72256893Sfenner if (mask & 16) printf(" segsize %lu", i); \ 72356893Sfenner /* undocumented in 3.3 docu */ \ 72456893Sfenner if (mask & 1024) printf(" fsync"); \ 72556893Sfenner } 72656893Sfenner 72756893Sfenner#define UBIK_VERSIONOUT() {int32_t epoch; int32_t counter; \ 72875115Sfenner TCHECK2(bp[0], sizeof(int32_t) * 2); \ 72975115Sfenner epoch = EXTRACT_32BITS(bp); \ 73056893Sfenner bp += sizeof(int32_t); \ 73175115Sfenner counter = EXTRACT_32BITS(bp); \ 73256893Sfenner bp += sizeof(int32_t); \ 73356893Sfenner printf(" %d.%d", epoch, counter); \ 73456893Sfenner } 73556893Sfenner 73656893Sfenner#define AFSUUIDOUT() {u_int32_t temp; int i; \ 73775115Sfenner TCHECK2(bp[0], 11*sizeof(u_int32_t)); \ 73875115Sfenner temp = EXTRACT_32BITS(bp); \ 73956893Sfenner bp += sizeof(u_int32_t); \ 74056893Sfenner printf(" %08x", temp); \ 74175115Sfenner temp = EXTRACT_32BITS(bp); \ 74256893Sfenner bp += sizeof(u_int32_t); \ 74356893Sfenner printf("%04x", temp); \ 74475115Sfenner temp = EXTRACT_32BITS(bp); \ 74556893Sfenner bp += sizeof(u_int32_t); \ 74656893Sfenner printf("%04x", temp); \ 74756893Sfenner for (i = 0; i < 8; i++) { \ 74875115Sfenner temp = EXTRACT_32BITS(bp); \ 74956893Sfenner bp += sizeof(u_int32_t); \ 75056893Sfenner printf("%02x", (unsigned char) temp); \ 75156893Sfenner } \ 75256893Sfenner } 75356893Sfenner 75456893Sfenner/* 75556893Sfenner * This is the sickest one of all 75656893Sfenner */ 75756893Sfenner 75856893Sfenner#define VECOUT(MAX) { char *sp; \ 75998524Sfenner char s[AFSNAMEMAX]; \ 76056893Sfenner int k; \ 76198524Sfenner if ((MAX) + 1 > sizeof(s)) \ 76298524Sfenner goto trunc; \ 76398524Sfenner TCHECK2(bp[0], (MAX) * sizeof(int32_t)); \ 76456893Sfenner sp = s; \ 76598524Sfenner for (k = 0; k < (MAX); k++) { \ 76675115Sfenner *sp++ = (char) EXTRACT_32BITS(bp); \ 76756893Sfenner bp += sizeof(int32_t); \ 76856893Sfenner } \ 76998524Sfenner s[(MAX)] = '\0'; \ 77080231Sfenner printf(" \""); \ 77180231Sfenner fn_print(s, NULL); \ 77280231Sfenner printf("\""); \ 77356893Sfenner } 77456893Sfenner 77575115Sfennerstatic void 77675115Sfennerack_print(register const u_char *bp, int length) 77775115Sfenner{ 77875115Sfenner u_char nAcks; 77975115Sfenner int i; 78075115Sfenner 78175115Sfenner if (vflag <= 1) 78275115Sfenner return; 78375115Sfenner 78475115Sfenner if (length <= sizeof(struct rx_header)) 78575115Sfenner return; 78675115Sfenner 78775115Sfenner bp += sizeof(struct rx_header); 78875115Sfenner 78975115Sfenner /* 79075115Sfenner * Packets < firstPacket are implicitly acknowledged and may 79175115Sfenner * be discarded by the sender. 79275115Sfenner * 79375115Sfenner * Packets >= firstPacket+nAcks are implicitly NOT acknowledged. 79475115Sfenner * 79575115Sfenner * No packets with sequence numbers >= firstPacket should be 79675115Sfenner * discarded by the sender (they may thrown out at any time by 79775115Sfenner * the receiver) 79875115Sfenner */ 79975115Sfenner#define RX_ACK_REASONS "RDOXSprn" 80075115Sfenner /* Requested, Duplicate, Out_of_sequence, eXceeds_window, no_Space, 80175115Sfenner * Ping, ping_Response, No_{progress, particular_reason}. 80275115Sfenner */ 80375115Sfenner#if 0 80475115Sfenner struct rx_ackPacket { 80575115Sfenner u_short bufferSpace; /* Skip! */ 80675115Sfenner u_short maxSkew; /* Skip! */ 80775115Sfenner u_long firstPacket; 80875115Sfenner u_long previousPacket; /* Obsolete! */ 80975115Sfenner u_long serial; /* Serial that prompted the ack, */ 81075115Sfenner u_char reason; /* and the reason why. */ 81175115Sfenner u_char nAcks; 81275115Sfenner u_char acks[RX_MAXACKS]; /* Selective acks (not a bitmap). */ 81375115Sfenner }; 81475115Sfenner#endif 81575115Sfenner#define RX_ACK_TYPE_NACK 0 81675115Sfenner 81775115Sfenner TCHECK2(bp[0], 8); /* bufferSpace and maxSkew */ 81875115Sfenner bp += 4; 81975115Sfenner printf(" fir %u", (unsigned)EXTRACT_32BITS(bp)); 82075115Sfenner bp += 4; 82175115Sfenner TCHECK2(bp[0], 8); /* previousPacket and serial */ 82275115Sfenner bp += 4; 82375115Sfenner printf(" %u", (unsigned)EXTRACT_32BITS(bp)); 82475115Sfenner bp += 4; 82575115Sfenner TCHECK2(bp[0], 1); 82675115Sfenner printf("%c", RX_ACK_REASONS[(*bp - 1) & 07u]); 82775115Sfenner bp += 1; /* reason */ 82875115Sfenner TCHECK2(bp[0], 1); 82975115Sfenner nAcks = *bp; 83075115Sfenner bp += 1; /* nAcks */ 83175115Sfenner 83275115Sfenner for (i = 0; i < nAcks; i++) { 83375115Sfenner TCHECK2(bp[0], 1); 83475115Sfenner putchar(*bp == RX_ACK_TYPE_NACK? '-' : '*'); 83575115Sfenner bp += 1; 83675115Sfenner } 83775115Sfenner 83875115Sfenner return; 83975115Sfenner 84075115Sfennertrunc: 84175115Sfenner printf(" [|ack]"); 84275115Sfenner} 84375115Sfenner 84456893Sfenner/* 84556893Sfenner * Handle calls to the AFS file service (fs) 84656893Sfenner */ 84756893Sfenner 84875115Sfennerstatic void 84956893Sfennerfs_print(register const u_char *bp, int length) 85056893Sfenner{ 85156893Sfenner int fs_op; 85256893Sfenner unsigned long i; 85356893Sfenner 85456893Sfenner if (length <= sizeof(struct rx_header)) 85556893Sfenner return; 85656893Sfenner 85756893Sfenner if (snapend - bp + 1 <= sizeof(struct rx_header) + sizeof(int32_t)) { 85856893Sfenner goto trunc; 85956893Sfenner } 86056893Sfenner 86156893Sfenner /* 86256893Sfenner * Print out the afs call we're invoking. The table used here was 86356893Sfenner * gleaned from fsint/afsint.xg 86456893Sfenner */ 86556893Sfenner 86675115Sfenner fs_op = EXTRACT_32BITS(bp + sizeof(struct rx_header)); 86756893Sfenner 86856893Sfenner printf(" fs call %s", tok2str(fs_req, "op#%d", fs_op)); 86956893Sfenner 87056893Sfenner /* 87156893Sfenner * Print out arguments to some of the AFS calls. This stuff is 87256893Sfenner * all from afsint.xg 87356893Sfenner */ 87456893Sfenner 87556893Sfenner bp += sizeof(struct rx_header) + 4; 87656893Sfenner 87756893Sfenner /* 87856893Sfenner * Sigh. This is gross. Ritchie forgive me. 87956893Sfenner */ 88056893Sfenner 88156893Sfenner switch (fs_op) { 88256893Sfenner case 130: /* Fetch data */ 88356893Sfenner FIDOUT(); 88456893Sfenner printf(" offset"); 88556893Sfenner UINTOUT(); 88656893Sfenner printf(" length"); 88756893Sfenner UINTOUT(); 88856893Sfenner break; 88956893Sfenner case 131: /* Fetch ACL */ 89056893Sfenner case 132: /* Fetch Status */ 89156893Sfenner case 143: /* Old set lock */ 89256893Sfenner case 144: /* Old extend lock */ 89356893Sfenner case 145: /* Old release lock */ 89456893Sfenner case 156: /* Set lock */ 89556893Sfenner case 157: /* Extend lock */ 89656893Sfenner case 158: /* Release lock */ 89756893Sfenner FIDOUT(); 89856893Sfenner break; 89956893Sfenner case 135: /* Store status */ 90056893Sfenner FIDOUT(); 90156893Sfenner STOREATTROUT(); 90256893Sfenner break; 90356893Sfenner case 133: /* Store data */ 90456893Sfenner FIDOUT(); 90556893Sfenner STOREATTROUT(); 90656893Sfenner printf(" offset"); 90756893Sfenner UINTOUT(); 90856893Sfenner printf(" length"); 90956893Sfenner UINTOUT(); 91056893Sfenner printf(" flen"); 91156893Sfenner UINTOUT(); 91256893Sfenner break; 91356893Sfenner case 134: /* Store ACL */ 91456893Sfenner { 91575115Sfenner char a[AFSOPAQUEMAX+1]; 91656893Sfenner FIDOUT(); 91775115Sfenner TCHECK2(bp[0], 4); 91875115Sfenner i = EXTRACT_32BITS(bp); 91956893Sfenner bp += sizeof(int32_t); 92075115Sfenner TCHECK2(bp[0], i); 92175115Sfenner i = min(AFSOPAQUEMAX, i); 92275115Sfenner strncpy(a, (char *) bp, i); 92356893Sfenner a[i] = '\0'; 92475115Sfenner acl_print((u_char *) a, sizeof(a), (u_char *) a + i); 92556893Sfenner break; 92656893Sfenner } 92756893Sfenner case 137: /* Create file */ 92856893Sfenner case 141: /* MakeDir */ 92956893Sfenner FIDOUT(); 93056893Sfenner STROUT(AFSNAMEMAX); 93156893Sfenner STOREATTROUT(); 93256893Sfenner break; 93356893Sfenner case 136: /* Remove file */ 93456893Sfenner case 142: /* Remove directory */ 93556893Sfenner FIDOUT(); 93656893Sfenner STROUT(AFSNAMEMAX); 93756893Sfenner break; 93856893Sfenner case 138: /* Rename file */ 93956893Sfenner printf(" old"); 94056893Sfenner FIDOUT(); 94156893Sfenner STROUT(AFSNAMEMAX); 94256893Sfenner printf(" new"); 94356893Sfenner FIDOUT(); 94456893Sfenner STROUT(AFSNAMEMAX); 94556893Sfenner break; 94656893Sfenner case 139: /* Symlink */ 94756893Sfenner FIDOUT(); 94856893Sfenner STROUT(AFSNAMEMAX); 94956893Sfenner printf(" link to"); 95056893Sfenner STROUT(AFSNAMEMAX); 95156893Sfenner break; 95256893Sfenner case 140: /* Link */ 95356893Sfenner FIDOUT(); 95456893Sfenner STROUT(AFSNAMEMAX); 95556893Sfenner printf(" link to"); 95656893Sfenner FIDOUT(); 95756893Sfenner break; 95856893Sfenner case 148: /* Get volume info */ 95956893Sfenner STROUT(AFSNAMEMAX); 96056893Sfenner break; 96156893Sfenner case 149: /* Get volume stats */ 96256893Sfenner case 150: /* Set volume stats */ 96356893Sfenner printf(" volid"); 96456893Sfenner UINTOUT(); 96556893Sfenner break; 96656893Sfenner case 154: /* New get volume info */ 96756893Sfenner printf(" volname"); 96856893Sfenner STROUT(AFSNAMEMAX); 96956893Sfenner break; 97056893Sfenner case 155: /* Bulk stat */ 97156893Sfenner { 97256893Sfenner unsigned long j; 97375115Sfenner TCHECK2(bp[0], 4); 97475115Sfenner j = EXTRACT_32BITS(bp); 97556893Sfenner bp += sizeof(int32_t); 97656893Sfenner 97756893Sfenner for (i = 0; i < j; i++) { 97856893Sfenner FIDOUT(); 97956893Sfenner if (i != j - 1) 98056893Sfenner printf(","); 98156893Sfenner } 98256893Sfenner if (j == 0) 98356893Sfenner printf(" <none!>"); 98456893Sfenner } 98556893Sfenner default: 98656893Sfenner ; 98756893Sfenner } 98856893Sfenner 98956893Sfenner return; 99056893Sfenner 99156893Sfennertrunc: 99256893Sfenner printf(" [|fs]"); 99356893Sfenner} 99456893Sfenner 99556893Sfenner/* 99656893Sfenner * Handle replies to the AFS file service 99756893Sfenner */ 99856893Sfenner 99956893Sfennerstatic void 100056893Sfennerfs_reply_print(register const u_char *bp, int length, int32_t opcode) 100156893Sfenner{ 100256893Sfenner unsigned long i; 100356893Sfenner struct rx_header *rxh; 100456893Sfenner 100556893Sfenner if (length <= sizeof(struct rx_header)) 100656893Sfenner return; 100756893Sfenner 100856893Sfenner rxh = (struct rx_header *) bp; 100956893Sfenner 101056893Sfenner /* 101156893Sfenner * Print out the afs call we're invoking. The table used here was 101256893Sfenner * gleaned from fsint/afsint.xg 101356893Sfenner */ 101456893Sfenner 101556893Sfenner printf(" fs reply %s", tok2str(fs_req, "op#%d", opcode)); 101656893Sfenner 101756893Sfenner bp += sizeof(struct rx_header); 101856893Sfenner 101956893Sfenner /* 102056893Sfenner * If it was a data packet, interpret the response 102156893Sfenner */ 102256893Sfenner 102375115Sfenner if (rxh->type == RX_PACKET_TYPE_DATA) { 102456893Sfenner switch (opcode) { 102556893Sfenner case 131: /* Fetch ACL */ 102656893Sfenner { 102775115Sfenner char a[AFSOPAQUEMAX+1]; 102875115Sfenner TCHECK2(bp[0], 4); 102975115Sfenner i = EXTRACT_32BITS(bp); 103056893Sfenner bp += sizeof(int32_t); 103175115Sfenner TCHECK2(bp[0], i); 103275115Sfenner i = min(AFSOPAQUEMAX, i); 103375115Sfenner strncpy(a, (char *) bp, i); 103456893Sfenner a[i] = '\0'; 103575115Sfenner acl_print((u_char *) a, sizeof(a), (u_char *) a + i); 103656893Sfenner break; 103756893Sfenner } 103856893Sfenner case 137: /* Create file */ 103956893Sfenner case 141: /* MakeDir */ 104056893Sfenner printf(" new"); 104156893Sfenner FIDOUT(); 104256893Sfenner break; 104356893Sfenner case 151: /* Get root volume */ 104456893Sfenner printf(" root volume"); 104556893Sfenner STROUT(AFSNAMEMAX); 104656893Sfenner break; 104756893Sfenner case 153: /* Get time */ 104856893Sfenner DATEOUT(); 104956893Sfenner break; 105056893Sfenner default: 105156893Sfenner ; 105256893Sfenner } 105375115Sfenner } else if (rxh->type == RX_PACKET_TYPE_ABORT) { 105475115Sfenner int i; 105575115Sfenner 105675115Sfenner /* 105775115Sfenner * Otherwise, just print out the return code 105875115Sfenner */ 105975115Sfenner TCHECK2(bp[0], sizeof(int32_t)); 106075115Sfenner i = (int) EXTRACT_32BITS(bp); 106175115Sfenner bp += sizeof(int32_t); 106275115Sfenner 106375115Sfenner printf(" error %s", tok2str(afs_fs_errors, "#%d", i)); 106475115Sfenner } else { 106575115Sfenner printf(" strange fs reply of type %d", rxh->type); 106656893Sfenner } 106756893Sfenner 106856893Sfenner return; 106956893Sfenner 107056893Sfennertrunc: 107156893Sfenner printf(" [|fs]"); 107256893Sfenner} 107356893Sfenner 107456893Sfenner/* 107556893Sfenner * Print out an AFS ACL string. An AFS ACL is a string that has the 107656893Sfenner * following format: 107756893Sfenner * 107856893Sfenner * <positive> <negative> 107956893Sfenner * <uid1> <aclbits1> 108056893Sfenner * .... 108156893Sfenner * 108256893Sfenner * "positive" and "negative" are integers which contain the number of 108356893Sfenner * positive and negative ACL's in the string. The uid/aclbits pair are 108456893Sfenner * ASCII strings containing the UID/PTS record and and a ascii number 108556893Sfenner * representing a logical OR of all the ACL permission bits 108656893Sfenner */ 108756893Sfenner 108856893Sfennerstatic void 108975115Sfenneracl_print(u_char *s, int maxsize, u_char *end) 109056893Sfenner{ 109156893Sfenner int pos, neg, acl; 109256893Sfenner int n, i; 109375115Sfenner char *user; 109456893Sfenner 109575115Sfenner if ((user = (char *)malloc(maxsize)) == NULL) 109675115Sfenner return; 109775115Sfenner 109856893Sfenner if (sscanf((char *) s, "%d %d\n%n", &pos, &neg, &n) != 2) 109975115Sfenner goto finish; 110056893Sfenner 110156893Sfenner s += n; 110256893Sfenner 110356893Sfenner if (s > end) 110475115Sfenner goto finish; 110556893Sfenner 110656893Sfenner /* 110756893Sfenner * This wacky order preserves the order used by the "fs" command 110856893Sfenner */ 110956893Sfenner 111056893Sfenner#define ACLOUT(acl) \ 111156893Sfenner if (acl & PRSFS_READ) \ 111256893Sfenner printf("r"); \ 111356893Sfenner if (acl & PRSFS_LOOKUP) \ 111456893Sfenner printf("l"); \ 111556893Sfenner if (acl & PRSFS_INSERT) \ 111656893Sfenner printf("i"); \ 111756893Sfenner if (acl & PRSFS_DELETE) \ 111856893Sfenner printf("d"); \ 111956893Sfenner if (acl & PRSFS_WRITE) \ 112056893Sfenner printf("w"); \ 112156893Sfenner if (acl & PRSFS_LOCK) \ 112256893Sfenner printf("k"); \ 112356893Sfenner if (acl & PRSFS_ADMINISTER) \ 112456893Sfenner printf("a"); 112556893Sfenner 112656893Sfenner for (i = 0; i < pos; i++) { 112756893Sfenner if (sscanf((char *) s, "%s %d\n%n", user, &acl, &n) != 2) 112875115Sfenner goto finish; 112956893Sfenner s += n; 113080231Sfenner printf(" +{"); 113180231Sfenner fn_print(user, NULL); 113280231Sfenner printf(" "); 113356893Sfenner ACLOUT(acl); 113456893Sfenner printf("}"); 113556893Sfenner if (s > end) 113675115Sfenner goto finish; 113756893Sfenner } 113856893Sfenner 113956893Sfenner for (i = 0; i < neg; i++) { 114056893Sfenner if (sscanf((char *) s, "%s %d\n%n", user, &acl, &n) != 2) 114175115Sfenner goto finish; 114256893Sfenner s += n; 114380231Sfenner printf(" -{"); 114480231Sfenner fn_print(user, NULL); 114580231Sfenner printf(" "); 114656893Sfenner ACLOUT(acl); 114756893Sfenner printf("}"); 114856893Sfenner if (s > end) 114975115Sfenner goto finish; 115056893Sfenner } 115175115Sfenner 115275115Sfennerfinish: 115375115Sfenner free(user); 115475115Sfenner return; 115556893Sfenner} 115656893Sfenner 115756893Sfenner#undef ACLOUT 115856893Sfenner 115956893Sfenner/* 116056893Sfenner * Handle calls to the AFS callback service 116156893Sfenner */ 116256893Sfenner 116356893Sfennerstatic void 116456893Sfennercb_print(register const u_char *bp, int length) 116556893Sfenner{ 116656893Sfenner int cb_op; 116756893Sfenner unsigned long i; 116856893Sfenner 116956893Sfenner if (length <= sizeof(struct rx_header)) 117056893Sfenner return; 117156893Sfenner 117256893Sfenner if (snapend - bp + 1 <= sizeof(struct rx_header) + sizeof(int32_t)) { 117356893Sfenner goto trunc; 117456893Sfenner } 117556893Sfenner 117656893Sfenner /* 117756893Sfenner * Print out the afs call we're invoking. The table used here was 117856893Sfenner * gleaned from fsint/afscbint.xg 117956893Sfenner */ 118056893Sfenner 118175115Sfenner cb_op = EXTRACT_32BITS(bp + sizeof(struct rx_header)); 118256893Sfenner 118356893Sfenner printf(" cb call %s", tok2str(cb_req, "op#%d", cb_op)); 118456893Sfenner 118556893Sfenner bp += sizeof(struct rx_header) + 4; 118656893Sfenner 118756893Sfenner /* 118856893Sfenner * Print out the afs call we're invoking. The table used here was 118956893Sfenner * gleaned from fsint/afscbint.xg 119056893Sfenner */ 119156893Sfenner 119256893Sfenner switch (cb_op) { 119356893Sfenner case 204: /* Callback */ 119456893Sfenner { 119556893Sfenner unsigned long j, t; 119675115Sfenner TCHECK2(bp[0], 4); 119775115Sfenner j = EXTRACT_32BITS(bp); 119856893Sfenner bp += sizeof(int32_t); 119956893Sfenner 120056893Sfenner for (i = 0; i < j; i++) { 120156893Sfenner FIDOUT(); 120256893Sfenner if (i != j - 1) 120356893Sfenner printf(","); 120456893Sfenner } 120556893Sfenner 120656893Sfenner if (j == 0) 120756893Sfenner printf(" <none!>"); 120856893Sfenner 120975115Sfenner j = EXTRACT_32BITS(bp); 121056893Sfenner bp += sizeof(int32_t); 121156893Sfenner 121256893Sfenner if (j != 0) 121356893Sfenner printf(";"); 121456893Sfenner 121556893Sfenner for (i = 0; i < j; i++) { 121656893Sfenner printf(" ver"); 121756893Sfenner INTOUT(); 121856893Sfenner printf(" expires"); 121956893Sfenner DATEOUT(); 122075115Sfenner TCHECK2(bp[0], 4); 122175115Sfenner t = EXTRACT_32BITS(bp); 122256893Sfenner bp += sizeof(int32_t); 122356893Sfenner tok2str(cb_types, "type %d", t); 122456893Sfenner } 122556893Sfenner } 122656893Sfenner case 214: { 122756893Sfenner printf(" afsuuid"); 122856893Sfenner AFSUUIDOUT(); 122956893Sfenner break; 123056893Sfenner } 123156893Sfenner default: 123256893Sfenner ; 123356893Sfenner } 123456893Sfenner 123556893Sfenner return; 123656893Sfenner 123756893Sfennertrunc: 123856893Sfenner printf(" [|cb]"); 123956893Sfenner} 124056893Sfenner 124156893Sfenner/* 124256893Sfenner * Handle replies to the AFS Callback Service 124356893Sfenner */ 124456893Sfenner 124556893Sfennerstatic void 124656893Sfennercb_reply_print(register const u_char *bp, int length, int32_t opcode) 124756893Sfenner{ 124856893Sfenner struct rx_header *rxh; 124956893Sfenner 125056893Sfenner if (length <= sizeof(struct rx_header)) 125156893Sfenner return; 125256893Sfenner 125356893Sfenner rxh = (struct rx_header *) bp; 125456893Sfenner 125556893Sfenner /* 125656893Sfenner * Print out the afs call we're invoking. The table used here was 125756893Sfenner * gleaned from fsint/afscbint.xg 125856893Sfenner */ 125956893Sfenner 126056893Sfenner printf(" cb reply %s", tok2str(cb_req, "op#%d", opcode)); 126156893Sfenner 126256893Sfenner bp += sizeof(struct rx_header); 126356893Sfenner 126456893Sfenner /* 126556893Sfenner * If it was a data packet, interpret the response. 126656893Sfenner */ 126756893Sfenner 126856893Sfenner if (rxh->type == RX_PACKET_TYPE_DATA) 126956893Sfenner switch (opcode) { 127056893Sfenner case 213: /* InitCallBackState3 */ 127156893Sfenner AFSUUIDOUT(); 127256893Sfenner break; 127356893Sfenner default: 127456893Sfenner ; 127556893Sfenner } 127656893Sfenner else { 127756893Sfenner /* 127856893Sfenner * Otherwise, just print out the return code 127956893Sfenner */ 128056893Sfenner printf(" errcode"); 128156893Sfenner INTOUT(); 128256893Sfenner } 128356893Sfenner 128456893Sfenner return; 128556893Sfenner 128656893Sfennertrunc: 128756893Sfenner printf(" [|cb]"); 128856893Sfenner} 128956893Sfenner 129056893Sfenner/* 129156893Sfenner * Handle calls to the AFS protection database server 129256893Sfenner */ 129356893Sfenner 129456893Sfennerstatic void 129556893Sfennerprot_print(register const u_char *bp, int length) 129656893Sfenner{ 129756893Sfenner unsigned long i; 129856893Sfenner int pt_op; 129956893Sfenner 130056893Sfenner if (length <= sizeof(struct rx_header)) 130156893Sfenner return; 130256893Sfenner 130356893Sfenner if (snapend - bp + 1 <= sizeof(struct rx_header) + sizeof(int32_t)) { 130456893Sfenner goto trunc; 130556893Sfenner } 130656893Sfenner 130756893Sfenner /* 130856893Sfenner * Print out the afs call we're invoking. The table used here was 130956893Sfenner * gleaned from ptserver/ptint.xg 131056893Sfenner */ 131156893Sfenner 131275115Sfenner pt_op = EXTRACT_32BITS(bp + sizeof(struct rx_header)); 131356893Sfenner 131456893Sfenner printf(" pt"); 131556893Sfenner 131656893Sfenner if (is_ubik(pt_op)) { 131756893Sfenner ubik_print(bp, length); 131856893Sfenner return; 131956893Sfenner } 132056893Sfenner 132156893Sfenner printf(" call %s", tok2str(pt_req, "op#%d", pt_op)); 132256893Sfenner 132356893Sfenner /* 132456893Sfenner * Decode some of the arguments to the PT calls 132556893Sfenner */ 132656893Sfenner 132756893Sfenner bp += sizeof(struct rx_header) + 4; 132856893Sfenner 132956893Sfenner switch (pt_op) { 133056893Sfenner case 500: /* I New User */ 133156893Sfenner STROUT(PRNAMEMAX); 133256893Sfenner printf(" id"); 133356893Sfenner INTOUT(); 133456893Sfenner printf(" oldid"); 133556893Sfenner INTOUT(); 133656893Sfenner break; 133756893Sfenner case 501: /* Where is it */ 133856893Sfenner case 506: /* Delete */ 133956893Sfenner case 508: /* Get CPS */ 134056893Sfenner case 512: /* List entry */ 134156893Sfenner case 514: /* List elements */ 134256893Sfenner case 517: /* List owned */ 134356893Sfenner case 518: /* Get CPS2 */ 134456893Sfenner case 519: /* Get host CPS */ 134556893Sfenner printf(" id"); 134656893Sfenner INTOUT(); 134756893Sfenner break; 134856893Sfenner case 502: /* Dump entry */ 134956893Sfenner printf(" pos"); 135056893Sfenner INTOUT(); 135156893Sfenner break; 135256893Sfenner case 503: /* Add to group */ 135356893Sfenner case 507: /* Remove from group */ 135456893Sfenner case 515: /* Is a member of? */ 135556893Sfenner printf(" uid"); 135656893Sfenner INTOUT(); 135756893Sfenner printf(" gid"); 135856893Sfenner INTOUT(); 135956893Sfenner break; 136056893Sfenner case 504: /* Name to ID */ 136156893Sfenner { 136256893Sfenner unsigned long j; 136375115Sfenner TCHECK2(bp[0], 4); 136475115Sfenner j = EXTRACT_32BITS(bp); 136556893Sfenner bp += sizeof(int32_t); 136656893Sfenner 136756893Sfenner /* 136856893Sfenner * Who designed this chicken-shit protocol? 136956893Sfenner * 137056893Sfenner * Each character is stored as a 32-bit 137156893Sfenner * integer! 137256893Sfenner */ 137356893Sfenner 137456893Sfenner for (i = 0; i < j; i++) { 137556893Sfenner VECOUT(PRNAMEMAX); 137656893Sfenner } 137756893Sfenner if (j == 0) 137856893Sfenner printf(" <none!>"); 137956893Sfenner } 138056893Sfenner break; 138156893Sfenner case 505: /* Id to name */ 138256893Sfenner { 138356893Sfenner unsigned long j; 138456893Sfenner printf(" ids:"); 138575115Sfenner TCHECK2(bp[0], 4); 138675115Sfenner i = EXTRACT_32BITS(bp); 138756893Sfenner bp += sizeof(int32_t); 138856893Sfenner for (j = 0; j < i; j++) 138956893Sfenner INTOUT(); 139056893Sfenner if (j == 0) 139156893Sfenner printf(" <none!>"); 139256893Sfenner } 139356893Sfenner break; 139456893Sfenner case 509: /* New entry */ 139556893Sfenner STROUT(PRNAMEMAX); 139656893Sfenner printf(" flag"); 139756893Sfenner INTOUT(); 139856893Sfenner printf(" oid"); 139956893Sfenner INTOUT(); 140056893Sfenner break; 140156893Sfenner case 511: /* Set max */ 140256893Sfenner printf(" id"); 140356893Sfenner INTOUT(); 140456893Sfenner printf(" gflag"); 140556893Sfenner INTOUT(); 140656893Sfenner break; 140756893Sfenner case 513: /* Change entry */ 140856893Sfenner printf(" id"); 140956893Sfenner INTOUT(); 141056893Sfenner STROUT(PRNAMEMAX); 141156893Sfenner printf(" oldid"); 141256893Sfenner INTOUT(); 141356893Sfenner printf(" newid"); 141456893Sfenner INTOUT(); 141556893Sfenner break; 141656893Sfenner case 520: /* Update entry */ 141756893Sfenner printf(" id"); 141856893Sfenner INTOUT(); 141956893Sfenner STROUT(PRNAMEMAX); 142056893Sfenner break; 142156893Sfenner default: 142256893Sfenner ; 142356893Sfenner } 142456893Sfenner 142556893Sfenner 142656893Sfenner return; 142756893Sfenner 142856893Sfennertrunc: 142956893Sfenner printf(" [|pt]"); 143056893Sfenner} 143156893Sfenner 143256893Sfenner/* 143356893Sfenner * Handle replies to the AFS protection service 143456893Sfenner */ 143556893Sfenner 143656893Sfennerstatic void 143756893Sfennerprot_reply_print(register const u_char *bp, int length, int32_t opcode) 143856893Sfenner{ 143956893Sfenner struct rx_header *rxh; 144056893Sfenner unsigned long i; 144156893Sfenner 144256893Sfenner if (length < sizeof(struct rx_header)) 144356893Sfenner return; 144456893Sfenner 144556893Sfenner rxh = (struct rx_header *) bp; 144656893Sfenner 144756893Sfenner /* 144856893Sfenner * Print out the afs call we're invoking. The table used here was 144956893Sfenner * gleaned from ptserver/ptint.xg. Check to see if it's a 145056893Sfenner * Ubik call, however. 145156893Sfenner */ 145256893Sfenner 145356893Sfenner printf(" pt"); 145456893Sfenner 145556893Sfenner if (is_ubik(opcode)) { 145656893Sfenner ubik_reply_print(bp, length, opcode); 145756893Sfenner return; 145856893Sfenner } 145956893Sfenner 146056893Sfenner printf(" reply %s", tok2str(pt_req, "op#%d", opcode)); 146156893Sfenner 146256893Sfenner bp += sizeof(struct rx_header); 146356893Sfenner 146456893Sfenner /* 146556893Sfenner * If it was a data packet, interpret the response 146656893Sfenner */ 146756893Sfenner 146856893Sfenner if (rxh->type == RX_PACKET_TYPE_DATA) 146956893Sfenner switch (opcode) { 147056893Sfenner case 504: /* Name to ID */ 147156893Sfenner { 147256893Sfenner unsigned long j; 147356893Sfenner printf(" ids:"); 147475115Sfenner TCHECK2(bp[0], 4); 147575115Sfenner i = EXTRACT_32BITS(bp); 147656893Sfenner bp += sizeof(int32_t); 147756893Sfenner for (j = 0; j < i; j++) 147856893Sfenner INTOUT(); 147956893Sfenner if (j == 0) 148056893Sfenner printf(" <none!>"); 148156893Sfenner } 148256893Sfenner break; 148356893Sfenner case 505: /* ID to name */ 148456893Sfenner { 148556893Sfenner unsigned long j; 148675115Sfenner TCHECK2(bp[0], 4); 148775115Sfenner j = EXTRACT_32BITS(bp); 148856893Sfenner bp += sizeof(int32_t); 148956893Sfenner 149056893Sfenner /* 149156893Sfenner * Who designed this chicken-shit protocol? 149256893Sfenner * 149356893Sfenner * Each character is stored as a 32-bit 149456893Sfenner * integer! 149556893Sfenner */ 149656893Sfenner 149756893Sfenner for (i = 0; i < j; i++) { 149856893Sfenner VECOUT(PRNAMEMAX); 149956893Sfenner } 150056893Sfenner if (j == 0) 150156893Sfenner printf(" <none!>"); 150256893Sfenner } 150356893Sfenner break; 150456893Sfenner case 508: /* Get CPS */ 150556893Sfenner case 514: /* List elements */ 150656893Sfenner case 517: /* List owned */ 150756893Sfenner case 518: /* Get CPS2 */ 150856893Sfenner case 519: /* Get host CPS */ 150956893Sfenner { 151056893Sfenner unsigned long j; 151175115Sfenner TCHECK2(bp[0], 4); 151275115Sfenner j = EXTRACT_32BITS(bp); 151356893Sfenner bp += sizeof(int32_t); 151456893Sfenner for (i = 0; i < j; i++) { 151556893Sfenner INTOUT(); 151656893Sfenner } 151756893Sfenner if (j == 0) 151856893Sfenner printf(" <none!>"); 151956893Sfenner } 152056893Sfenner break; 152156893Sfenner case 510: /* List max */ 152256893Sfenner printf(" maxuid"); 152356893Sfenner INTOUT(); 152456893Sfenner printf(" maxgid"); 152556893Sfenner INTOUT(); 152656893Sfenner break; 152756893Sfenner default: 152856893Sfenner ; 152956893Sfenner } 153056893Sfenner else { 153156893Sfenner /* 153256893Sfenner * Otherwise, just print out the return code 153356893Sfenner */ 153456893Sfenner printf(" errcode"); 153556893Sfenner INTOUT(); 153656893Sfenner } 153756893Sfenner 153856893Sfenner return; 153956893Sfenner 154056893Sfennertrunc: 154156893Sfenner printf(" [|pt]"); 154256893Sfenner} 154356893Sfenner 154456893Sfenner/* 154556893Sfenner * Handle calls to the AFS volume location database service 154656893Sfenner */ 154756893Sfenner 154856893Sfennerstatic void 154956893Sfennervldb_print(register const u_char *bp, int length) 155056893Sfenner{ 155156893Sfenner int vldb_op; 155256893Sfenner unsigned long i; 155356893Sfenner 155456893Sfenner if (length <= sizeof(struct rx_header)) 155556893Sfenner return; 155656893Sfenner 155756893Sfenner if (snapend - bp + 1 <= sizeof(struct rx_header) + sizeof(int32_t)) { 155856893Sfenner goto trunc; 155956893Sfenner } 156056893Sfenner 156156893Sfenner /* 156256893Sfenner * Print out the afs call we're invoking. The table used here was 156356893Sfenner * gleaned from vlserver/vldbint.xg 156456893Sfenner */ 156556893Sfenner 156675115Sfenner vldb_op = EXTRACT_32BITS(bp + sizeof(struct rx_header)); 156756893Sfenner 156856893Sfenner printf(" vldb"); 156956893Sfenner 157056893Sfenner if (is_ubik(vldb_op)) { 157156893Sfenner ubik_print(bp, length); 157256893Sfenner return; 157356893Sfenner } 157456893Sfenner printf(" call %s", tok2str(vldb_req, "op#%d", vldb_op)); 157556893Sfenner 157656893Sfenner /* 157756893Sfenner * Decode some of the arguments to the VLDB calls 157856893Sfenner */ 157956893Sfenner 158056893Sfenner bp += sizeof(struct rx_header) + 4; 158156893Sfenner 158256893Sfenner switch (vldb_op) { 158356893Sfenner case 501: /* Create new volume */ 158456893Sfenner case 517: /* Create entry N */ 158556893Sfenner VECOUT(VLNAMEMAX); 158656893Sfenner break; 158756893Sfenner case 502: /* Delete entry */ 158856893Sfenner case 503: /* Get entry by ID */ 158956893Sfenner case 507: /* Update entry */ 159056893Sfenner case 508: /* Set lock */ 159156893Sfenner case 509: /* Release lock */ 159256893Sfenner case 518: /* Get entry by ID 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 break; 160156893Sfenner case 504: /* Get entry by name */ 160256893Sfenner case 519: /* Get entry by name N */ 160356893Sfenner case 524: /* Update entry by name */ 160456893Sfenner case 527: /* Get entry by name U */ 160556893Sfenner STROUT(VLNAMEMAX); 160656893Sfenner break; 160756893Sfenner case 505: /* Get new vol id */ 160856893Sfenner printf(" bump"); 160956893Sfenner INTOUT(); 161056893Sfenner break; 161156893Sfenner case 506: /* Replace entry */ 161256893Sfenner case 520: /* Replace entry N */ 161356893Sfenner printf(" volid"); 161456893Sfenner INTOUT(); 161575115Sfenner TCHECK2(bp[0], sizeof(int32_t)); 161675115Sfenner i = EXTRACT_32BITS(bp); 161756893Sfenner bp += sizeof(int32_t); 161856893Sfenner if (i <= 2) 161956893Sfenner printf(" type %s", voltype[i]); 162056893Sfenner VECOUT(VLNAMEMAX); 162156893Sfenner break; 162256893Sfenner case 510: /* List entry */ 162356893Sfenner case 521: /* List entry N */ 162456893Sfenner printf(" index"); 162556893Sfenner INTOUT(); 162656893Sfenner break; 162756893Sfenner default: 162856893Sfenner ; 162956893Sfenner } 163056893Sfenner 163156893Sfenner return; 163256893Sfenner 163356893Sfennertrunc: 163456893Sfenner printf(" [|vldb]"); 163556893Sfenner} 163656893Sfenner 163756893Sfenner/* 163856893Sfenner * Handle replies to the AFS volume location database service 163956893Sfenner */ 164056893Sfenner 164156893Sfennerstatic void 164256893Sfennervldb_reply_print(register const u_char *bp, int length, int32_t opcode) 164356893Sfenner{ 164456893Sfenner struct rx_header *rxh; 164556893Sfenner unsigned long i; 164656893Sfenner 164756893Sfenner if (length < sizeof(struct rx_header)) 164856893Sfenner return; 164956893Sfenner 165056893Sfenner rxh = (struct rx_header *) bp; 165156893Sfenner 165256893Sfenner /* 165356893Sfenner * Print out the afs call we're invoking. The table used here was 165456893Sfenner * gleaned from vlserver/vldbint.xg. Check to see if it's a 165556893Sfenner * Ubik call, however. 165656893Sfenner */ 165756893Sfenner 165856893Sfenner printf(" vldb"); 165956893Sfenner 166056893Sfenner if (is_ubik(opcode)) { 166156893Sfenner ubik_reply_print(bp, length, opcode); 166256893Sfenner return; 166356893Sfenner } 166456893Sfenner 166556893Sfenner printf(" reply %s", tok2str(vldb_req, "op#%d", opcode)); 166656893Sfenner 166756893Sfenner bp += sizeof(struct rx_header); 166856893Sfenner 166956893Sfenner /* 167056893Sfenner * If it was a data packet, interpret the response 167156893Sfenner */ 167256893Sfenner 167356893Sfenner if (rxh->type == RX_PACKET_TYPE_DATA) 167456893Sfenner switch (opcode) { 167556893Sfenner case 510: /* List entry */ 167656893Sfenner printf(" count"); 167756893Sfenner INTOUT(); 167856893Sfenner printf(" nextindex"); 167956893Sfenner INTOUT(); 168056893Sfenner case 503: /* Get entry by id */ 168156893Sfenner case 504: /* Get entry by name */ 168256893Sfenner { unsigned long nservers, j; 168356893Sfenner VECOUT(VLNAMEMAX); 168475115Sfenner TCHECK2(bp[0], sizeof(int32_t)); 168556893Sfenner bp += sizeof(int32_t); 168656893Sfenner printf(" numservers"); 168775115Sfenner TCHECK2(bp[0], sizeof(int32_t)); 168875115Sfenner nservers = EXTRACT_32BITS(bp); 168956893Sfenner bp += sizeof(int32_t); 169056893Sfenner printf(" %lu", nservers); 169156893Sfenner printf(" servers"); 169256893Sfenner for (i = 0; i < 8; i++) { 169375115Sfenner TCHECK2(bp[0], sizeof(int32_t)); 169456893Sfenner if (i < nservers) 169556893Sfenner printf(" %s", 169656893Sfenner inet_ntoa(*((struct in_addr *) bp))); 169756893Sfenner bp += sizeof(int32_t); 169856893Sfenner } 169956893Sfenner printf(" partitions"); 170056893Sfenner for (i = 0; i < 8; i++) { 170175115Sfenner TCHECK2(bp[0], sizeof(int32_t)); 170275115Sfenner j = EXTRACT_32BITS(bp); 170356893Sfenner if (i < nservers && j <= 26) 170456893Sfenner printf(" %c", 'a' + (int)j); 170556893Sfenner else if (i < nservers) 170656893Sfenner printf(" %lu", j); 170756893Sfenner bp += sizeof(int32_t); 170856893Sfenner } 170975115Sfenner TCHECK2(bp[0], 8 * sizeof(int32_t)); 171056893Sfenner bp += 8 * sizeof(int32_t); 171156893Sfenner printf(" rwvol"); 171256893Sfenner UINTOUT(); 171356893Sfenner printf(" rovol"); 171456893Sfenner UINTOUT(); 171556893Sfenner printf(" backup"); 171656893Sfenner UINTOUT(); 171756893Sfenner } 171856893Sfenner break; 171956893Sfenner case 505: /* Get new volume ID */ 172056893Sfenner printf(" newvol"); 172156893Sfenner UINTOUT(); 172256893Sfenner break; 172356893Sfenner case 521: /* List entry */ 172456893Sfenner case 529: /* List entry U */ 172556893Sfenner printf(" count"); 172656893Sfenner INTOUT(); 172756893Sfenner printf(" nextindex"); 172856893Sfenner INTOUT(); 172956893Sfenner case 518: /* Get entry by ID N */ 173056893Sfenner case 519: /* Get entry by name N */ 173156893Sfenner { unsigned long nservers, j; 173256893Sfenner VECOUT(VLNAMEMAX); 173356893Sfenner printf(" numservers"); 173475115Sfenner TCHECK2(bp[0], sizeof(int32_t)); 173575115Sfenner nservers = EXTRACT_32BITS(bp); 173656893Sfenner bp += sizeof(int32_t); 173756893Sfenner printf(" %lu", nservers); 173856893Sfenner printf(" servers"); 173956893Sfenner for (i = 0; i < 13; i++) { 174075115Sfenner TCHECK2(bp[0], sizeof(int32_t)); 174156893Sfenner if (i < nservers) 174256893Sfenner printf(" %s", 174356893Sfenner inet_ntoa(*((struct in_addr *) bp))); 174456893Sfenner bp += sizeof(int32_t); 174556893Sfenner } 174656893Sfenner printf(" partitions"); 174756893Sfenner for (i = 0; i < 13; i++) { 174875115Sfenner TCHECK2(bp[0], sizeof(int32_t)); 174975115Sfenner j = EXTRACT_32BITS(bp); 175056893Sfenner if (i < nservers && j <= 26) 175156893Sfenner printf(" %c", 'a' + (int)j); 175256893Sfenner else if (i < nservers) 175356893Sfenner printf(" %lu", j); 175456893Sfenner bp += sizeof(int32_t); 175556893Sfenner } 175675115Sfenner TCHECK2(bp[0], 13 * sizeof(int32_t)); 175756893Sfenner bp += 13 * sizeof(int32_t); 175856893Sfenner printf(" rwvol"); 175956893Sfenner UINTOUT(); 176056893Sfenner printf(" rovol"); 176156893Sfenner UINTOUT(); 176256893Sfenner printf(" backup"); 176356893Sfenner UINTOUT(); 176456893Sfenner } 176556893Sfenner break; 176656893Sfenner case 526: /* Get entry by ID U */ 176756893Sfenner case 527: /* Get entry by name U */ 176856893Sfenner { unsigned long nservers, j; 176956893Sfenner VECOUT(VLNAMEMAX); 177056893Sfenner printf(" numservers"); 177175115Sfenner TCHECK2(bp[0], sizeof(int32_t)); 177275115Sfenner nservers = EXTRACT_32BITS(bp); 177356893Sfenner bp += sizeof(int32_t); 177456893Sfenner printf(" %lu", nservers); 177556893Sfenner printf(" servers"); 177656893Sfenner for (i = 0; i < 13; i++) { 177756893Sfenner if (i < nservers) { 177856893Sfenner printf(" afsuuid"); 177956893Sfenner AFSUUIDOUT(); 178056893Sfenner } else { 178175115Sfenner TCHECK2(bp[0], 44); 178256893Sfenner bp += 44; 178356893Sfenner } 178456893Sfenner } 178575115Sfenner TCHECK2(bp[0], 4 * 13); 178656893Sfenner bp += 4 * 13; 178756893Sfenner printf(" partitions"); 178856893Sfenner for (i = 0; i < 13; i++) { 178975115Sfenner TCHECK2(bp[0], sizeof(int32_t)); 179075115Sfenner j = EXTRACT_32BITS(bp); 179156893Sfenner if (i < nservers && j <= 26) 179256893Sfenner printf(" %c", 'a' + (int)j); 179356893Sfenner else if (i < nservers) 179456893Sfenner printf(" %lu", j); 179556893Sfenner bp += sizeof(int32_t); 179656893Sfenner } 179775115Sfenner TCHECK2(bp[0], 13 * sizeof(int32_t)); 179856893Sfenner bp += 13 * sizeof(int32_t); 179956893Sfenner printf(" rwvol"); 180056893Sfenner UINTOUT(); 180156893Sfenner printf(" rovol"); 180256893Sfenner UINTOUT(); 180356893Sfenner printf(" backup"); 180456893Sfenner UINTOUT(); 180556893Sfenner } 180656893Sfenner default: 180756893Sfenner ; 180856893Sfenner } 180956893Sfenner 181056893Sfenner else { 181156893Sfenner /* 181256893Sfenner * Otherwise, just print out the return code 181356893Sfenner */ 181456893Sfenner printf(" errcode"); 181556893Sfenner INTOUT(); 181656893Sfenner } 181756893Sfenner 181856893Sfenner return; 181956893Sfenner 182056893Sfennertrunc: 182156893Sfenner printf(" [|vldb]"); 182256893Sfenner} 182356893Sfenner 182456893Sfenner/* 182556893Sfenner * Handle calls to the AFS Kerberos Authentication service 182656893Sfenner */ 182756893Sfenner 182856893Sfennerstatic void 182956893Sfennerkauth_print(register const u_char *bp, int length) 183056893Sfenner{ 183156893Sfenner int kauth_op; 183256893Sfenner 183356893Sfenner if (length <= sizeof(struct rx_header)) 183456893Sfenner return; 183556893Sfenner 183656893Sfenner if (snapend - bp + 1 <= sizeof(struct rx_header) + sizeof(int32_t)) { 183756893Sfenner goto trunc; 183856893Sfenner } 183956893Sfenner 184056893Sfenner /* 184156893Sfenner * Print out the afs call we're invoking. The table used here was 184256893Sfenner * gleaned from kauth/kauth.rg 184356893Sfenner */ 184456893Sfenner 184575115Sfenner kauth_op = EXTRACT_32BITS(bp + sizeof(struct rx_header)); 184656893Sfenner 184756893Sfenner printf(" kauth"); 184856893Sfenner 184956893Sfenner if (is_ubik(kauth_op)) { 185056893Sfenner ubik_print(bp, length); 185156893Sfenner return; 185256893Sfenner } 185356893Sfenner 185456893Sfenner 185556893Sfenner printf(" call %s", tok2str(kauth_req, "op#%d", kauth_op)); 185656893Sfenner 185756893Sfenner /* 185856893Sfenner * Decode some of the arguments to the KA calls 185956893Sfenner */ 186056893Sfenner 186156893Sfenner bp += sizeof(struct rx_header) + 4; 186256893Sfenner 186356893Sfenner switch (kauth_op) { 186456893Sfenner case 1: /* Authenticate old */; 186556893Sfenner case 21: /* Authenticate */ 186656893Sfenner case 22: /* Authenticate-V2 */ 186756893Sfenner case 2: /* Change PW */ 186856893Sfenner case 5: /* Set fields */ 186956893Sfenner case 6: /* Create user */ 187056893Sfenner case 7: /* Delete user */ 187156893Sfenner case 8: /* Get entry */ 187256893Sfenner case 14: /* Unlock */ 187356893Sfenner case 15: /* Lock status */ 187456893Sfenner printf(" principal"); 187556893Sfenner STROUT(KANAMEMAX); 187656893Sfenner STROUT(KANAMEMAX); 187756893Sfenner break; 187856893Sfenner case 3: /* GetTicket-old */ 187956893Sfenner case 23: /* GetTicket */ 188056893Sfenner { 188156893Sfenner int i; 188256893Sfenner printf(" kvno"); 188356893Sfenner INTOUT(); 188456893Sfenner printf(" domain"); 188556893Sfenner STROUT(KANAMEMAX); 188675115Sfenner TCHECK2(bp[0], sizeof(int32_t)); 188775115Sfenner i = (int) EXTRACT_32BITS(bp); 188856893Sfenner bp += sizeof(int32_t); 188975115Sfenner TCHECK2(bp[0], i); 189056893Sfenner bp += i; 189156893Sfenner printf(" principal"); 189256893Sfenner STROUT(KANAMEMAX); 189356893Sfenner STROUT(KANAMEMAX); 189456893Sfenner break; 189556893Sfenner } 189656893Sfenner case 4: /* Set Password */ 189756893Sfenner printf(" principal"); 189856893Sfenner STROUT(KANAMEMAX); 189956893Sfenner STROUT(KANAMEMAX); 190056893Sfenner printf(" kvno"); 190156893Sfenner INTOUT(); 190256893Sfenner break; 190356893Sfenner case 12: /* Get password */ 190456893Sfenner printf(" name"); 190556893Sfenner STROUT(KANAMEMAX); 190656893Sfenner break; 190756893Sfenner default: 190856893Sfenner ; 190956893Sfenner } 191056893Sfenner 191156893Sfenner return; 191256893Sfenner 191356893Sfennertrunc: 191456893Sfenner printf(" [|kauth]"); 191556893Sfenner} 191656893Sfenner 191756893Sfenner/* 191856893Sfenner * Handle replies to the AFS Kerberos Authentication Service 191956893Sfenner */ 192056893Sfenner 192156893Sfennerstatic void 192256893Sfennerkauth_reply_print(register const u_char *bp, int length, int32_t opcode) 192356893Sfenner{ 192456893Sfenner struct rx_header *rxh; 192556893Sfenner 192656893Sfenner if (length <= sizeof(struct rx_header)) 192756893Sfenner return; 192856893Sfenner 192956893Sfenner rxh = (struct rx_header *) bp; 193056893Sfenner 193156893Sfenner /* 193256893Sfenner * Print out the afs call we're invoking. The table used here was 193356893Sfenner * gleaned from kauth/kauth.rg 193456893Sfenner */ 193556893Sfenner 193656893Sfenner printf(" kauth"); 193756893Sfenner 193856893Sfenner if (is_ubik(opcode)) { 193956893Sfenner ubik_reply_print(bp, length, opcode); 194056893Sfenner return; 194156893Sfenner } 194256893Sfenner 194356893Sfenner printf(" reply %s", tok2str(kauth_req, "op#%d", opcode)); 194456893Sfenner 194556893Sfenner bp += sizeof(struct rx_header); 194656893Sfenner 194756893Sfenner /* 194856893Sfenner * If it was a data packet, interpret the response. 194956893Sfenner */ 195056893Sfenner 195156893Sfenner if (rxh->type == RX_PACKET_TYPE_DATA) 195256893Sfenner /* Well, no, not really. Leave this for later */ 195356893Sfenner ; 195456893Sfenner else { 195556893Sfenner /* 195656893Sfenner * Otherwise, just print out the return code 195756893Sfenner */ 195856893Sfenner printf(" errcode"); 195956893Sfenner INTOUT(); 196056893Sfenner } 196156893Sfenner 196256893Sfenner return; 196356893Sfenner 196456893Sfennertrunc: 196556893Sfenner printf(" [|kauth]"); 196656893Sfenner} 196756893Sfenner 196856893Sfenner/* 196956893Sfenner * Handle calls to the AFS Volume location service 197056893Sfenner */ 197156893Sfenner 197256893Sfennerstatic void 197356893Sfennervol_print(register const u_char *bp, int length) 197456893Sfenner{ 197556893Sfenner int vol_op; 197656893Sfenner 197756893Sfenner if (length <= sizeof(struct rx_header)) 197856893Sfenner return; 197956893Sfenner 198056893Sfenner if (snapend - bp + 1 <= sizeof(struct rx_header) + sizeof(int32_t)) { 198156893Sfenner goto trunc; 198256893Sfenner } 198356893Sfenner 198456893Sfenner /* 198556893Sfenner * Print out the afs call we're invoking. The table used here was 198656893Sfenner * gleaned from volser/volint.xg 198756893Sfenner */ 198856893Sfenner 198975115Sfenner vol_op = EXTRACT_32BITS(bp + sizeof(struct rx_header)); 199056893Sfenner 199156893Sfenner printf(" vol call %s", tok2str(vol_req, "op#%d", vol_op)); 199256893Sfenner 199356893Sfenner /* 199456893Sfenner * Normally there would be a switch statement here to decode the 199556893Sfenner * arguments to the AFS call, but since I don't have access to 199656893Sfenner * an AFS server (yet) and I'm not an AFS admin, I can't 199756893Sfenner * test any of these calls. Leave this blank for now. 199856893Sfenner */ 199956893Sfenner 200056893Sfenner return; 200156893Sfenner 200256893Sfennertrunc: 200356893Sfenner printf(" [|vol]"); 200456893Sfenner} 200556893Sfenner 200656893Sfenner/* 200756893Sfenner * Handle replies to the AFS Volume Service 200856893Sfenner */ 200956893Sfenner 201056893Sfennerstatic void 201156893Sfennervol_reply_print(register const u_char *bp, int length, int32_t opcode) 201256893Sfenner{ 201356893Sfenner struct rx_header *rxh; 201456893Sfenner 201556893Sfenner if (length <= sizeof(struct rx_header)) 201656893Sfenner return; 201756893Sfenner 201856893Sfenner rxh = (struct rx_header *) bp; 201956893Sfenner 202056893Sfenner /* 202156893Sfenner * Print out the afs call we're invoking. The table used here was 202256893Sfenner * gleaned from volser/volint.xg 202356893Sfenner */ 202456893Sfenner 202556893Sfenner printf(" vol reply %s", tok2str(vol_req, "op#%d", opcode)); 202656893Sfenner 202756893Sfenner bp += sizeof(struct rx_header); 202856893Sfenner 202956893Sfenner /* 203056893Sfenner * If it was a data packet, interpret the response. 203156893Sfenner */ 203256893Sfenner 203356893Sfenner if (rxh->type == RX_PACKET_TYPE_DATA) 203456893Sfenner /* Well, no, not really. Leave this for later */ 203556893Sfenner ; 203656893Sfenner else { 203756893Sfenner /* 203856893Sfenner * Otherwise, just print out the return code 203956893Sfenner */ 204056893Sfenner printf(" errcode"); 204156893Sfenner INTOUT(); 204256893Sfenner } 204356893Sfenner 204456893Sfenner return; 204556893Sfenner 204656893Sfennertrunc: 204756893Sfenner printf(" [|vol]"); 204856893Sfenner} 204956893Sfenner 205056893Sfenner/* 205156893Sfenner * Handle calls to the AFS BOS service 205256893Sfenner */ 205356893Sfenner 205456893Sfennerstatic void 205556893Sfennerbos_print(register const u_char *bp, int length) 205656893Sfenner{ 205756893Sfenner int bos_op; 205856893Sfenner 205956893Sfenner if (length <= sizeof(struct rx_header)) 206056893Sfenner return; 206156893Sfenner 206256893Sfenner if (snapend - bp + 1 <= sizeof(struct rx_header) + sizeof(int32_t)) { 206356893Sfenner goto trunc; 206456893Sfenner } 206556893Sfenner 206656893Sfenner /* 206756893Sfenner * Print out the afs call we're invoking. The table used here was 206856893Sfenner * gleaned from bozo/bosint.xg 206956893Sfenner */ 207056893Sfenner 207175115Sfenner bos_op = EXTRACT_32BITS(bp + sizeof(struct rx_header)); 207256893Sfenner 207356893Sfenner printf(" bos call %s", tok2str(bos_req, "op#%d", bos_op)); 207456893Sfenner 207556893Sfenner /* 207656893Sfenner * Decode some of the arguments to the BOS calls 207756893Sfenner */ 207856893Sfenner 207956893Sfenner bp += sizeof(struct rx_header) + 4; 208056893Sfenner 208156893Sfenner switch (bos_op) { 208256893Sfenner case 80: /* Create B node */ 208356893Sfenner printf(" type"); 208456893Sfenner STROUT(BOSNAMEMAX); 208556893Sfenner printf(" instance"); 208656893Sfenner STROUT(BOSNAMEMAX); 208756893Sfenner break; 208856893Sfenner case 81: /* Delete B node */ 208956893Sfenner case 83: /* Get status */ 209056893Sfenner case 85: /* Get instance info */ 209156893Sfenner case 87: /* Add super user */ 209256893Sfenner case 88: /* Delete super user */ 209356893Sfenner case 93: /* Set cell name */ 209456893Sfenner case 96: /* Add cell host */ 209556893Sfenner case 97: /* Delete cell host */ 209656893Sfenner case 104: /* Restart */ 209756893Sfenner case 106: /* Uninstall */ 209856893Sfenner case 108: /* Exec */ 209956893Sfenner case 112: /* Getlog */ 210056893Sfenner case 114: /* Get instance strings */ 210156893Sfenner STROUT(BOSNAMEMAX); 210256893Sfenner break; 210356893Sfenner case 82: /* Set status */ 210456893Sfenner case 98: /* Set T status */ 210556893Sfenner STROUT(BOSNAMEMAX); 210656893Sfenner printf(" status"); 210756893Sfenner INTOUT(); 210856893Sfenner break; 210956893Sfenner case 86: /* Get instance parm */ 211056893Sfenner STROUT(BOSNAMEMAX); 211156893Sfenner printf(" num"); 211256893Sfenner INTOUT(); 211356893Sfenner break; 211456893Sfenner case 84: /* Enumerate instance */ 211556893Sfenner case 89: /* List super users */ 211656893Sfenner case 90: /* List keys */ 211756893Sfenner case 91: /* Add key */ 211856893Sfenner case 92: /* Delete key */ 211956893Sfenner case 95: /* Get cell host */ 212056893Sfenner INTOUT(); 212156893Sfenner break; 212256893Sfenner case 105: /* Install */ 212356893Sfenner STROUT(BOSNAMEMAX); 212456893Sfenner printf(" size"); 212556893Sfenner INTOUT(); 212656893Sfenner printf(" flags"); 212756893Sfenner INTOUT(); 212856893Sfenner printf(" date"); 212956893Sfenner INTOUT(); 213056893Sfenner break; 213156893Sfenner default: 213256893Sfenner ; 213356893Sfenner } 213456893Sfenner 213556893Sfenner return; 213656893Sfenner 213756893Sfennertrunc: 213856893Sfenner printf(" [|bos]"); 213956893Sfenner} 214056893Sfenner 214156893Sfenner/* 214256893Sfenner * Handle replies to the AFS BOS Service 214356893Sfenner */ 214456893Sfenner 214556893Sfennerstatic void 214656893Sfennerbos_reply_print(register const u_char *bp, int length, int32_t opcode) 214756893Sfenner{ 214856893Sfenner struct rx_header *rxh; 214956893Sfenner 215056893Sfenner if (length <= sizeof(struct rx_header)) 215156893Sfenner return; 215256893Sfenner 215356893Sfenner rxh = (struct rx_header *) bp; 215456893Sfenner 215556893Sfenner /* 215656893Sfenner * Print out the afs call we're invoking. The table used here was 215756893Sfenner * gleaned from volser/volint.xg 215856893Sfenner */ 215956893Sfenner 216056893Sfenner printf(" bos reply %s", tok2str(bos_req, "op#%d", opcode)); 216156893Sfenner 216256893Sfenner bp += sizeof(struct rx_header); 216356893Sfenner 216456893Sfenner /* 216556893Sfenner * If it was a data packet, interpret the response. 216656893Sfenner */ 216756893Sfenner 216856893Sfenner if (rxh->type == RX_PACKET_TYPE_DATA) 216956893Sfenner /* Well, no, not really. Leave this for later */ 217056893Sfenner ; 217156893Sfenner else { 217256893Sfenner /* 217356893Sfenner * Otherwise, just print out the return code 217456893Sfenner */ 217556893Sfenner printf(" errcode"); 217656893Sfenner INTOUT(); 217756893Sfenner } 217856893Sfenner 217956893Sfenner return; 218056893Sfenner 218156893Sfennertrunc: 218256893Sfenner printf(" [|bos]"); 218356893Sfenner} 218456893Sfenner 218556893Sfenner/* 218656893Sfenner * Check to see if this is a Ubik opcode. 218756893Sfenner */ 218856893Sfenner 218956893Sfennerstatic int 219056893Sfenneris_ubik(u_int32_t opcode) 219156893Sfenner{ 219256893Sfenner if ((opcode >= VOTE_LOW && opcode <= VOTE_HIGH) || 219356893Sfenner (opcode >= DISK_LOW && opcode <= DISK_HIGH)) 219456893Sfenner return(1); 219556893Sfenner else 219656893Sfenner return(0); 219756893Sfenner} 219856893Sfenner 219956893Sfenner/* 220056893Sfenner * Handle Ubik opcodes to any one of the replicated database services 220156893Sfenner */ 220256893Sfenner 220356893Sfennerstatic void 220456893Sfennerubik_print(register const u_char *bp, int length) 220556893Sfenner{ 220656893Sfenner int ubik_op; 220756893Sfenner int32_t temp; 220856893Sfenner 220956893Sfenner /* 221056893Sfenner * Print out the afs call we're invoking. The table used here was 221156893Sfenner * gleaned from ubik/ubik_int.xg 221256893Sfenner */ 221356893Sfenner 221475115Sfenner ubik_op = EXTRACT_32BITS(bp + sizeof(struct rx_header)); 221556893Sfenner 221656893Sfenner printf(" ubik call %s", tok2str(ubik_req, "op#%d", ubik_op)); 221756893Sfenner 221856893Sfenner /* 221956893Sfenner * Decode some of the arguments to the Ubik calls 222056893Sfenner */ 222156893Sfenner 222256893Sfenner bp += sizeof(struct rx_header) + 4; 222356893Sfenner 222456893Sfenner switch (ubik_op) { 222556893Sfenner case 10000: /* Beacon */ 222675115Sfenner TCHECK2(bp[0], 4); 222775115Sfenner temp = EXTRACT_32BITS(bp); 222856893Sfenner bp += sizeof(int32_t); 222956893Sfenner printf(" syncsite %s", temp ? "yes" : "no"); 223056893Sfenner printf(" votestart"); 223156893Sfenner DATEOUT(); 223256893Sfenner printf(" dbversion"); 223356893Sfenner UBIK_VERSIONOUT(); 223456893Sfenner printf(" tid"); 223556893Sfenner UBIK_VERSIONOUT(); 223656893Sfenner break; 223756893Sfenner case 10003: /* Get sync site */ 223856893Sfenner printf(" site"); 223956893Sfenner UINTOUT(); 224056893Sfenner break; 224156893Sfenner case 20000: /* Begin */ 224256893Sfenner case 20001: /* Commit */ 224356893Sfenner case 20007: /* Abort */ 224456893Sfenner case 20008: /* Release locks */ 224556893Sfenner case 20010: /* Writev */ 224656893Sfenner printf(" tid"); 224756893Sfenner UBIK_VERSIONOUT(); 224856893Sfenner break; 224956893Sfenner case 20002: /* Lock */ 225056893Sfenner printf(" tid"); 225156893Sfenner UBIK_VERSIONOUT(); 225256893Sfenner printf(" file"); 225356893Sfenner INTOUT(); 225456893Sfenner printf(" pos"); 225556893Sfenner INTOUT(); 225656893Sfenner printf(" length"); 225756893Sfenner INTOUT(); 225875115Sfenner temp = EXTRACT_32BITS(bp); 225956893Sfenner bp += sizeof(int32_t); 226056893Sfenner tok2str(ubik_lock_types, "type %d", temp); 226156893Sfenner break; 226256893Sfenner case 20003: /* Write */ 226356893Sfenner printf(" tid"); 226456893Sfenner UBIK_VERSIONOUT(); 226556893Sfenner printf(" file"); 226656893Sfenner INTOUT(); 226756893Sfenner printf(" pos"); 226856893Sfenner INTOUT(); 226956893Sfenner break; 227056893Sfenner case 20005: /* Get file */ 227156893Sfenner printf(" file"); 227256893Sfenner INTOUT(); 227356893Sfenner break; 227456893Sfenner case 20006: /* Send file */ 227556893Sfenner printf(" file"); 227656893Sfenner INTOUT(); 227756893Sfenner printf(" length"); 227856893Sfenner INTOUT(); 227956893Sfenner printf(" dbversion"); 228056893Sfenner UBIK_VERSIONOUT(); 228156893Sfenner break; 228256893Sfenner case 20009: /* Truncate */ 228356893Sfenner printf(" tid"); 228456893Sfenner UBIK_VERSIONOUT(); 228556893Sfenner printf(" file"); 228656893Sfenner INTOUT(); 228756893Sfenner printf(" length"); 228856893Sfenner INTOUT(); 228956893Sfenner break; 229056893Sfenner case 20012: /* Set version */ 229156893Sfenner printf(" tid"); 229256893Sfenner UBIK_VERSIONOUT(); 229356893Sfenner printf(" oldversion"); 229456893Sfenner UBIK_VERSIONOUT(); 229556893Sfenner printf(" newversion"); 229656893Sfenner UBIK_VERSIONOUT(); 229756893Sfenner break; 229856893Sfenner default: 229956893Sfenner ; 230056893Sfenner } 230156893Sfenner 230256893Sfenner return; 230356893Sfenner 230456893Sfennertrunc: 230556893Sfenner printf(" [|ubik]"); 230656893Sfenner} 230756893Sfenner 230856893Sfenner/* 230956893Sfenner * Handle Ubik replies to any one of the replicated database services 231056893Sfenner */ 231156893Sfenner 231256893Sfennerstatic void 231356893Sfennerubik_reply_print(register const u_char *bp, int length, int32_t opcode) 231456893Sfenner{ 231556893Sfenner struct rx_header *rxh; 231656893Sfenner 231756893Sfenner if (length < sizeof(struct rx_header)) 231856893Sfenner return; 231956893Sfenner 232056893Sfenner rxh = (struct rx_header *) bp; 232156893Sfenner 232256893Sfenner /* 232356893Sfenner * Print out the ubik call we're invoking. This table was gleaned 232456893Sfenner * from ubik/ubik_int.xg 232556893Sfenner */ 232656893Sfenner 232756893Sfenner printf(" ubik reply %s", tok2str(ubik_req, "op#%d", opcode)); 232856893Sfenner 232956893Sfenner bp += sizeof(struct rx_header); 233056893Sfenner 233156893Sfenner /* 233256893Sfenner * If it was a data packet, print out the arguments to the Ubik calls 233356893Sfenner */ 233456893Sfenner 233556893Sfenner if (rxh->type == RX_PACKET_TYPE_DATA) 233656893Sfenner switch (opcode) { 233756893Sfenner case 10000: /* Beacon */ 233856893Sfenner printf(" vote no"); 233956893Sfenner break; 234056893Sfenner case 20004: /* Get version */ 234156893Sfenner printf(" dbversion"); 234256893Sfenner UBIK_VERSIONOUT(); 234356893Sfenner break; 234456893Sfenner default: 234556893Sfenner ; 234656893Sfenner } 234756893Sfenner 234856893Sfenner /* 234956893Sfenner * Otherwise, print out "yes" it it was a beacon packet (because 235056893Sfenner * that's how yes votes are returned, go figure), otherwise 235156893Sfenner * just print out the error code. 235256893Sfenner */ 235356893Sfenner 235456893Sfenner else 235556893Sfenner switch (opcode) { 235656893Sfenner case 10000: /* Beacon */ 235756893Sfenner printf(" vote yes until"); 235856893Sfenner DATEOUT(); 235956893Sfenner break; 236056893Sfenner default: 236156893Sfenner printf(" errcode"); 236256893Sfenner INTOUT(); 236356893Sfenner } 236456893Sfenner 236556893Sfenner return; 236656893Sfenner 236756893Sfennertrunc: 236856893Sfenner printf(" [|ubik]"); 236956893Sfenner} 237075115Sfenner 237175115Sfenner/* 237275115Sfenner * Handle RX ACK packets. 237375115Sfenner */ 237475115Sfenner 237575115Sfennerstatic void 237675115Sfennerrx_ack_print(register const u_char *bp, int length) 237775115Sfenner{ 237875115Sfenner struct rx_ackPacket *rxa; 237975115Sfenner int i, start, last; 238075115Sfenner 238175115Sfenner if (length < sizeof(struct rx_header)) 238275115Sfenner return; 238375115Sfenner 238475115Sfenner bp += sizeof(struct rx_header); 238575115Sfenner 238675115Sfenner /* 238775115Sfenner * This may seem a little odd .... the rx_ackPacket structure 238875115Sfenner * contains an array of individual packet acknowledgements 238975115Sfenner * (used for selective ack/nack), but since it's variable in size, 239075115Sfenner * we don't want to truncate based on the size of the whole 239175115Sfenner * rx_ackPacket structure. 239275115Sfenner */ 239375115Sfenner 239475115Sfenner TCHECK2(bp[0], sizeof(struct rx_ackPacket) - RX_MAXACKS); 239575115Sfenner 239675115Sfenner rxa = (struct rx_ackPacket *) bp; 239775115Sfenner bp += (sizeof(struct rx_ackPacket) - RX_MAXACKS); 239875115Sfenner 239975115Sfenner /* 240075115Sfenner * Print out a few useful things from the ack packet structure 240175115Sfenner */ 240275115Sfenner 240375115Sfenner if (vflag > 2) 240475115Sfenner printf(" bufspace %d maxskew %d", 240575115Sfenner (int) EXTRACT_16BITS(&rxa->bufferSpace), 240675115Sfenner (int) EXTRACT_16BITS(&rxa->maxSkew)); 240775115Sfenner 240875115Sfenner printf(" first %d serial %d reason %s", 240975115Sfenner EXTRACT_32BITS(&rxa->firstPacket), EXTRACT_32BITS(&rxa->serial), 241075115Sfenner tok2str(rx_ack_reasons, "#%d", (int) rxa->reason)); 241175115Sfenner 241275115Sfenner /* 241375115Sfenner * Okay, now we print out the ack array. The way _this_ works 241475115Sfenner * is that we start at "first", and step through the ack array. 241575115Sfenner * If we have a contiguous range of acks/nacks, try to 241675115Sfenner * collapse them into a range. 241775115Sfenner * 241875115Sfenner * If you're really clever, you might have noticed that this 241975115Sfenner * doesn't seem quite correct. Specifically, due to structure 242075115Sfenner * padding, sizeof(struct rx_ackPacket) - RX_MAXACKS won't actually 242175115Sfenner * yield the start of the ack array (because RX_MAXACKS is 255 242275115Sfenner * and the structure will likely get padded to a 2 or 4 byte 242375115Sfenner * boundary). However, this is the way it's implemented inside 242475115Sfenner * of AFS - the start of the extra fields are at 242575115Sfenner * sizeof(struct rx_ackPacket) - RX_MAXACKS + nAcks, which _isn't_ 242675115Sfenner * the exact start of the ack array. Sigh. That's why we aren't 242775115Sfenner * using bp, but instead use rxa->acks[]. But nAcks gets added 242875115Sfenner * to bp after this, so bp ends up at the right spot. Go figure. 242975115Sfenner */ 243075115Sfenner 243175115Sfenner if (rxa->nAcks != 0) { 243275115Sfenner 243375115Sfenner TCHECK2(bp[0], rxa->nAcks); 243475115Sfenner 243575115Sfenner /* 243675115Sfenner * Sigh, this is gross, but it seems to work to collapse 243775115Sfenner * ranges correctly. 243875115Sfenner */ 243975115Sfenner 244075115Sfenner for (i = 0, start = last = -2; i < rxa->nAcks; i++) 244175115Sfenner if (rxa->acks[i] == RX_ACK_TYPE_ACK) { 244275115Sfenner 244375115Sfenner /* 244475115Sfenner * I figured this deserved _some_ explanation. 244575115Sfenner * First, print "acked" and the packet seq 244675115Sfenner * number if this is the first time we've 244775115Sfenner * seen an acked packet. 244875115Sfenner */ 244975115Sfenner 245075115Sfenner if (last == -2) { 245175115Sfenner printf(" acked %d", 245275115Sfenner rxa->firstPacket + i); 245375115Sfenner start = i; 245475115Sfenner } 245575115Sfenner 245675115Sfenner /* 245775115Sfenner * Otherwise, if the there is a skip in 245875115Sfenner * the range (such as an nacked packet in 245975115Sfenner * the middle of some acked packets), 246075115Sfenner * then print the current packet number 246175115Sfenner * seperated from the last number by 246275115Sfenner * a comma. 246375115Sfenner */ 246475115Sfenner 246575115Sfenner else if (last != i - 1) { 246675115Sfenner printf(",%d", rxa->firstPacket + i); 246775115Sfenner start = i; 246875115Sfenner } 246975115Sfenner 247075115Sfenner /* 247175115Sfenner * We always set last to the value of 247275115Sfenner * the last ack we saw. Conversely, start 247375115Sfenner * is set to the value of the first ack 247475115Sfenner * we saw in a range. 247575115Sfenner */ 247675115Sfenner 247775115Sfenner last = i; 247875115Sfenner 247975115Sfenner /* 248075115Sfenner * Okay, this bit a code gets executed when 248175115Sfenner * we hit a nack ... in _this_ case we 248275115Sfenner * want to print out the range of packets 248375115Sfenner * that were acked, so we need to print 248475115Sfenner * the _previous_ packet number seperated 248575115Sfenner * from the first by a dash (-). Since we 248675115Sfenner * already printed the first packet above, 248775115Sfenner * just print the final packet. Don't 248875115Sfenner * do this if there will be a single-length 248975115Sfenner * range. 249075115Sfenner */ 249175115Sfenner } else if (last == i - 1 && start != last) 249275115Sfenner printf("-%d", rxa->firstPacket + i - 1); 249375115Sfenner 249475115Sfenner /* 249575115Sfenner * So, what's going on here? We ran off the end of the 249675115Sfenner * ack list, and if we got a range we need to finish it up. 249775115Sfenner * So we need to determine if the last packet in the list 249875115Sfenner * was an ack (if so, then last will be set to it) and 249975115Sfenner * we need to see if the last range didn't start with the 250075115Sfenner * last packet (because if it _did_, then that would mean 250175115Sfenner * that the packet number has already been printed and 250275115Sfenner * we don't need to print it again). 250375115Sfenner */ 250475115Sfenner 250575115Sfenner if (last == i - 1 && start != last) 250675115Sfenner printf("-%d", rxa->firstPacket + i - 1); 250775115Sfenner 250875115Sfenner /* 250975115Sfenner * Same as above, just without comments 251075115Sfenner */ 251175115Sfenner 251275115Sfenner for (i = 0, start = last = -2; i < rxa->nAcks; i++) 251375115Sfenner if (rxa->acks[i] == RX_ACK_TYPE_NACK) { 251475115Sfenner if (last == -2) { 251575115Sfenner printf(" nacked %d", 251675115Sfenner rxa->firstPacket + i); 251775115Sfenner start = i; 251875115Sfenner } else if (last != i - 1) { 251975115Sfenner printf(",%d", rxa->firstPacket + i); 252075115Sfenner start = i; 252175115Sfenner } 252275115Sfenner last = i; 252375115Sfenner } else if (last == i - 1 && start != last) 252475115Sfenner printf("-%d", rxa->firstPacket + i - 1); 252575115Sfenner 252675115Sfenner if (last == i - 1 && start != last) 252775115Sfenner printf("-%d", rxa->firstPacket + i - 1); 252875115Sfenner 252975115Sfenner bp += rxa->nAcks; 253075115Sfenner } 253175115Sfenner 253275115Sfenner 253375115Sfenner /* 253475115Sfenner * These are optional fields; depending on your version of AFS, 253575115Sfenner * you may or may not see them 253675115Sfenner */ 253775115Sfenner 253875115Sfenner#define TRUNCRET(n) if (snapend - bp + 1 <= n) return; 253975115Sfenner 254075115Sfenner if (vflag > 1) { 254175115Sfenner TRUNCRET(4); 254275115Sfenner printf(" ifmtu"); 254375115Sfenner INTOUT(); 254475115Sfenner 254575115Sfenner TRUNCRET(4); 254675115Sfenner printf(" maxmtu"); 254775115Sfenner INTOUT(); 254875115Sfenner 254975115Sfenner TRUNCRET(4); 255075115Sfenner printf(" rwind"); 255175115Sfenner INTOUT(); 255275115Sfenner 255375115Sfenner TRUNCRET(4); 255475115Sfenner printf(" maxpackets"); 255575115Sfenner INTOUT(); 255675115Sfenner } 255775115Sfenner 255875115Sfenner return; 255975115Sfenner 256075115Sfennertrunc: 256175115Sfenner printf(" [|ack]"); 256275115Sfenner} 256375115Sfenner#undef TRUNCRET 2564