⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 print-rx.c

📁 Windump3.6.2源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * This code unmangles RX packets.  RX is the mutant form of RPC that AFS * uses to communicate between clients and servers. * * In this code, I mainly concern myself with decoding the AFS calls, not * with the guts of RX, per se. * * Bah.  If I never look at rx_packet.h again, it will be too soon. * * Ken Hornstein <kenh@cmf.nrl.navy.mil> * */#ifndef lintstatic const char rcsid[] =    "@(#) $Header: /tcpdump/master/tcpdump/print-rx.c,v 1.20 2001/01/10 08:12:01 fenner Exp $";#endif#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <stdio.h>#include <stdlib.h>#include <string.h>#ifndef WIN32
#include <time.h>#include <sys/param.h>#include <sys/time.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>
#else
#include <winsock2.h>
#include "bittypes.h"
#endif /* WIN32 */
#include "interface.h"#include "addrtoname.h"#include "extract.h"#undef NOERROR					/* Solaris sucks */#include <arpa/nameser.h>#include "rx.h"#include "ip.h"static struct tok rx_types[] = {	{ RX_PACKET_TYPE_DATA,		"data" },	{ RX_PACKET_TYPE_ACK,		"ack" },	{ RX_PACKET_TYPE_BUSY,		"busy" },	{ RX_PACKET_TYPE_ABORT,		"abort" },	{ RX_PACKET_TYPE_ACKALL,	"ackall" },	{ RX_PACKET_TYPE_CHALLENGE,	"challenge" },	{ RX_PACKET_TYPE_RESPONSE,	"response" },	{ RX_PACKET_TYPE_DEBUG,		"debug" },	{ RX_PACKET_TYPE_PARAMS,	"params" },	{ RX_PACKET_TYPE_VERSION,	"version" },	{ 0,				NULL },};static struct tok rx_flags[] = {	{ RX_CLIENT_INITIATED,	"client-init" },	{ RX_REQUEST_ACK,	"req-ack" },	{ RX_LAST_PACKET,	"last-pckt" },	{ RX_MORE_PACKETS,	"more-pckts" },	{ RX_FREE_PACKET,	"free-pckt" }};static struct tok fs_req[] = {	{ 130,		"fetch-data" },	{ 131,		"fetch-acl" },	{ 132,		"fetch-status" },	{ 133,		"store-data" },	{ 134,		"store-acl" },	{ 135,		"store-status" },	{ 136,		"remove-file" },	{ 137,		"create-file" },	{ 138,		"rename" },	{ 139,		"symlink" },	{ 140,		"link" },	{ 141,		"makedir" },	{ 142,		"rmdir" },	{ 143,		"oldsetlock" },	{ 144,		"oldextlock" },	{ 145,		"oldrellock" },	{ 146,		"get-stats" },	{ 147,		"give-cbs" },	{ 148,		"get-vlinfo" },	{ 149,		"get-vlstats" },	{ 150,		"set-vlstats" },	{ 151,		"get-rootvl" },	{ 152,		"check-token" },	{ 153,		"get-time" },	{ 154,		"nget-vlinfo" },	{ 155,		"bulk-stat" },	{ 156,		"setlock" },	{ 157,		"extlock" },	{ 158,		"rellock" },	{ 159,		"xstat-ver" },	{ 160,		"get-xstat" },	{ 161,		"dfs-lookup" },	{ 162,		"dfs-flushcps" },	{ 163,		"dfs-symlink" },	{ 0,		NULL },};static struct tok cb_req[] = {	{ 204,		"callback" },	{ 205,		"initcb" },	{ 206,		"probe" },	{ 207,		"getlock" },	{ 208,		"getce" },	{ 209,		"xstatver" },	{ 210,		"getxstat" },	{ 211,		"initcb2" },	{ 212,		"whoareyou" },	{ 213,		"initcb3" },	{ 214,		"probeuuid" },	{ 0,		NULL },};static struct tok pt_req[] = {	{ 500,		"new-user" },	{ 501,		"where-is-it" },	{ 502,		"dump-entry" },	{ 503,		"add-to-group" },	{ 504,		"name-to-id" },	{ 505,		"id-to-name" },	{ 506,		"delete" },	{ 507,		"remove-from-group" },	{ 508,		"get-cps" },	{ 509,		"new-entry" },	{ 510,		"list-max" },	{ 511,		"set-max" },	{ 512,		"list-entry" },	{ 513,		"change-entry" },	{ 514,		"list-elements" },	{ 515,		"same-mbr-of" },	{ 516,		"set-fld-sentry" },	{ 517,		"list-owned" },	{ 518,		"get-cps2" },	{ 519,		"get-host-cps" },	{ 520,		"update-entry" },	{ 0,		NULL },};static struct tok vldb_req[] = {	{ 501,		"create-entry" },	{ 502,		"delete-entry" },	{ 503,		"get-entry-by-id" },	{ 504,		"get-entry-by-name" },	{ 505,		"get-new-volume-id" },	{ 506,		"replace-entry" },	{ 507,		"update-entry" },	{ 508,		"setlock" },	{ 509,		"releaselock" },	{ 510,		"list-entry" },	{ 511,		"list-attrib" },	{ 512,		"linked-list" },	{ 513,		"get-stats" },	{ 514,		"probe" },	{ 515,		"get-addrs" },	{ 516,		"change-addr" },	{ 517,		"create-entry-n" },	{ 518,		"get-entry-by-id-n" },	{ 519,		"get-entry-by-name-n" },	{ 520,		"replace-entry-n" },	{ 521,		"list-entry-n" },	{ 522,		"list-attrib-n" },	{ 523,		"linked-list-n" },	{ 524,		"update-entry-by-name" },	{ 525,		"create-entry-u" },	{ 526,		"get-entry-by-id-u" },	{ 527,		"get-entry-by-name-u" },	{ 528,		"replace-entry-u" },	{ 529,		"list-entry-u" },	{ 530,		"list-attrib-u" },	{ 531,		"linked-list-u" },	{ 532,		"regaddr" },	{ 533,		"get-addrs-u" },	{ 0,		NULL },};static struct tok kauth_req[] = {	{ 1,		"auth-old" },	{ 21,		"authenticate" },	{ 22,		"authenticate-v2" },	{ 2,		"change-pw" },	{ 3,		"get-ticket-old" },	{ 23,		"get-ticket" },	{ 4,		"set-pw" },	{ 5,		"set-fields" },	{ 6,		"create-user" },	{ 7,		"delete-user" },	{ 8,		"get-entry" },	{ 9,		"list-entry" },	{ 10,		"get-stats" },	{ 11,		"debug" },	{ 12,		"get-pw" },	{ 13,		"get-random-key" },	{ 14,		"unlock" },	{ 15,		"lock-status" },	{ 0,		NULL },};static struct tok vol_req[] = {	{ 100,		"create-volume" },	{ 101,		"delete-volume" },	{ 102,		"restore" },	{ 103,		"forward" },	{ 104,		"end-trans" },	{ 105,		"clone" },	{ 106,		"set-flags" },	{ 107,		"get-flags" },	{ 108,		"trans-create" },	{ 109,		"dump" },	{ 110,		"get-nth-volume" },	{ 111,		"set-forwarding" },	{ 112,		"get-name" },	{ 113,		"get-status" },	{ 114,		"sig-restore" },	{ 115,		"list-partitions" },	{ 116,		"list-volumes" },	{ 117,		"set-id-types" },	{ 118,		"monitor" },	{ 119,		"partition-info" },	{ 120,		"reclone" },	{ 121,		"list-one-volume" },	{ 122,		"nuke" },	{ 123,		"set-date" },	{ 124,		"x-list-volumes" },	{ 125,		"x-list-one-volume" },	{ 126,		"set-info" },	{ 127,		"x-list-partitions" },	{ 128,		"forward-multiple" },	{ 0,		NULL },};static struct tok bos_req[] = {	{ 80,		"create-bnode" },	{ 81,		"delete-bnode" },	{ 82,		"set-status" },	{ 83,		"get-status" },	{ 84,		"enumerate-instance" },	{ 85,		"get-instance-info" },	{ 86,		"get-instance-parm" },	{ 87,		"add-superuser" },	{ 88,		"delete-superuser" },	{ 89,		"list-superusers" },	{ 90,		"list-keys" },	{ 91,		"add-key" },	{ 92,		"delete-key" },	{ 93,		"set-cell-name" },	{ 94,		"get-cell-name" },	{ 95,		"get-cell-host" },	{ 96,		"add-cell-host" },	{ 97,		"delete-cell-host" },	{ 98,		"set-t-status" },	{ 99,		"shutdown-all" },	{ 100,		"restart-all" },	{ 101,		"startup-all" },	{ 102,		"set-noauth-flag" },	{ 103,		"re-bozo" },	{ 104,		"restart" },	{ 105,		"start-bozo-install" },	{ 106,		"uninstall" },	{ 107,		"get-dates" },	{ 108,		"exec" },	{ 109,		"prune" },	{ 110,		"set-restart-time" },	{ 111,		"get-restart-time" },	{ 112,		"start-bozo-log" },	{ 113,		"wait-all" },	{ 114,		"get-instance-strings" },	{ 0,		NULL },};static struct tok ubik_req[] = {	{ 10000,	"vote-beacon" },	{ 10001,	"vote-debug-old" },	{ 10002,	"vote-sdebug-old" },	{ 10003,	"vote-getsyncsite" },	{ 10004,	"vote-debug" },	{ 10005,	"vote-sdebug" },	{ 20000,	"disk-begin" },	{ 20001,	"disk-commit" },	{ 20002,	"disk-lock" },	{ 20003,	"disk-write" },	{ 20004,	"disk-getversion" },	{ 20005,	"disk-getfile" },	{ 20006,	"disk-sendfile" },	{ 20007,	"disk-abort" },	{ 20008,	"disk-releaselocks" },	{ 20009,	"disk-truncate" },	{ 20010,	"disk-probe" },	{ 20011,	"disk-writev" },	{ 20012,	"disk-interfaceaddr" },	{ 20013,	"disk-setversion" },	{ 0,		NULL },};#define VOTE_LOW	10000#define VOTE_HIGH	10005#define DISK_LOW	20000#define DISK_HIGH	20013static struct tok cb_types[] = {	{ 1,		"exclusive" },	{ 2,		"shared" },	{ 3,		"dropped" },	{ 0,		NULL },};static struct tok ubik_lock_types[] = {	{ 1,		"read" },	{ 2,		"write" },	{ 3,		"wait" },	{ 0,		NULL },};static char *voltype[] = { "read-write", "read-only", "backup" };static struct tok afs_fs_errors[] = {	{ 101,		"salvage volume" },	{ 102, 		"no such vnode" },	{ 103, 		"no such volume" },	{ 104, 		"volume exist" },	{ 105, 		"no service" },	{ 106, 		"volume offline" },	{ 107, 		"voline online" },	{ 108, 		"diskfull" },	{ 109, 		"diskquota exceeded" },	{ 110, 		"volume busy" },	{ 111, 		"volume moved" },	{ 112, 		"AFS IO error" },	{ -100,		"restarting fileserver" },	{ 0,		NULL }};/* * Reasons for acknowledging a packet */static struct tok rx_ack_reasons[] = {	{ 1,		"ack requested" },	{ 2,		"duplicate packet" },	{ 3,		"out of sequence" },	{ 4,		"exceeds window" },	{ 5,		"no buffer space" },	{ 6,		"ping" },	{ 7,		"ping response" },	{ 8,		"delay" },	{ 0,		NULL },};/* * Cache entries we keep around so we can figure out the RX opcode * numbers for replies.  This allows us to make sense of RX reply packets. */struct rx_cache_entry {	u_int32_t	callnum;	/* Call number (net order) */	struct in_addr	client;		/* client IP address (net order) */	struct in_addr	server;		/* server IP address (net order) */	int		dport;		/* server port (host order) */	u_short		serviceId;	/* Service identifier (net order) */	u_int32_t	opcode;		/* RX opcode (host order) */};#define RX_CACHE_SIZE	64static struct rx_cache_entry	rx_cache[RX_CACHE_SIZE];static int	rx_cache_next = 0;static int	rx_cache_hint = 0;static void	rx_cache_insert(const u_char *, const struct ip *, int, int);static int	rx_cache_find(const struct rx_header *, const struct ip *,			      int, int32_t *);static void ack_print(const u_char *, int);static void fs_print(const u_char *, int);static void fs_reply_print(const u_char *, int, int32_t);static void acl_print(u_char *, int, u_char *);static void cb_print(const u_char *, int);static void cb_reply_print(const u_char *, int, int32_t);static void prot_print(const u_char *, int);static void prot_reply_print(const u_char *, int, int32_t);static void vldb_print(const u_char *, int);static void vldb_reply_print(const u_char *, int, int32_t);static void kauth_print(const u_char *, int);static void kauth_reply_print(const u_char *, int, int32_t);static void vol_print(const u_char *, int);static void vol_reply_print(const u_char *, int, int32_t);static void bos_print(const u_char *, int);static void bos_reply_print(const u_char *, int, int32_t);static void ubik_print(const u_char *, int);static void ubik_reply_print(const u_char *, int, int32_t);static void rx_ack_print(const u_char *, int);static int is_ubik(u_int32_t);/* * Handle the rx-level packet.  See if we know what port it's going to so * we can peek at the afs call inside */voidrx_print(register const u_char *bp, int length, int sport, int dport,	 u_char *bp2){	register struct rx_header *rxh;	int i;	int32_t opcode;	if (snapend - bp < sizeof (struct rx_header)) {		printf(" [|rx] (%d)", length);		return;	}	rxh = (struct rx_header *) bp;	printf(" rx %s", tok2str(rx_types, "type %d", rxh->type));	if (vflag) {		int firstflag = 0;		if (vflag > 1)			printf(" cid %08x call# %d",			       (int) EXTRACT_32BITS(&rxh->cid),			       (int) EXTRACT_32BITS(&rxh->callNumber));		printf(" seq %d ser %d",		       (int) EXTRACT_32BITS(&rxh->seq),		       (int) EXTRACT_32BITS(&rxh->serial));		if (vflag > 2)			printf(" secindex %d serviceid %hu",				(int) rxh->securityIndex,				EXTRACT_16BITS(&rxh->serviceId));		if (vflag > 1)			for (i = 0; i < NUM_RX_FLAGS; i++) {				if (rxh->flags & rx_flags[i].v) {					if (!firstflag) {						firstflag = 1;						printf(" ");					} else {						printf(",");					}					printf("<%s>", rx_flags[i].s);				}			}	}	/*	 * Try to handle AFS calls that we know about.  Check the destination	 * port and make sure it's a data packet.  Also, make sure the	 * seq number is 1 (because otherwise it's a continuation packet,	 * and we can't interpret that).  Also, seems that reply packets	 * do not have the client-init flag set, so we check for that	 * as well.	 */ 	if (rxh->type == RX_PACKET_TYPE_ACK) 	    ack_print(bp, length);	else if (rxh->type == RX_PACKET_TYPE_DATA &&	    EXTRACT_32BITS(&rxh->seq) == 1 &&	    rxh->flags & RX_CLIENT_INITIATED) {		/*		 * Insert this call into the call cache table, so we		 * have a chance to print out replies		 */		rx_cache_insert(bp, (const struct ip *) bp2, dport, length);		switch (dport) {			case FS_RX_PORT:	/* AFS file service */				fs_print(bp, length);				break;			case CB_RX_PORT:	/* AFS callback service */				cb_print(bp, length);				break;			case PROT_RX_PORT:	/* AFS protection service */				prot_print(bp, length);				break;			case VLDB_RX_PORT:	/* AFS VLDB service */				vldb_print(bp, length);				break;			case KAUTH_RX_PORT:	/* AFS Kerberos auth service */				kauth_print(bp, length);				break;			case VOL_RX_PORT:	/* AFS Volume service */				vol_print(bp, length);				break;			case BOS_RX_PORT:	/* AFS BOS service */				bos_print(bp, length);				break;			default:				;		}		/*	 * If it's a reply (client-init is _not_ set, but seq is one)	 * then look it up in the cache.  If we find it, call the reply	 * printing functions  Note that we handle abort packets here,	 * because printing out the return code can be useful at times.	 */	} else if (((rxh->type == RX_PACKET_TYPE_DATA &&					EXTRACT_32BITS(&rxh->seq) == 1) ||		    rxh->type == RX_PACKET_TYPE_ABORT) &&		   (rxh->flags & RX_CLIENT_INITIATED) == 0 &&		   rx_cache_find(rxh, (const struct ip *) bp2,				 sport, &opcode)) {		switch (sport) {			case FS_RX_PORT:	/* AFS file service */				fs_reply_print(bp, length, opcode);				break;			case CB_RX_PORT:	/* AFS callback service */				cb_reply_print(bp, length, opcode);				break;			case PROT_RX_PORT:	/* AFS PT service */				prot_reply_print(bp, length, opcode);				break;			case VLDB_RX_PORT:	/* AFS VLDB service */				vldb_reply_print(bp, length, opcode);				break;			case KAUTH_RX_PORT:	/* AFS Kerberos auth service */				kauth_reply_print(bp, length, opcode);				break;			case VOL_RX_PORT:	/* AFS Volume service */				vol_reply_print(bp, length, opcode);				break;			case BOS_RX_PORT:	/* AFS BOS service */				bos_reply_print(bp, length, opcode);				break;			default:				;		}	/*	 * If it's an RX ack packet, then use the appropriate ack decoding	 * function (there isn't any service-specific information in the	 * ack packet, so we can use one for all AFS services)	 */	} else if (rxh->type == RX_PACKET_TYPE_ACK)		rx_ack_print(bp, length);	printf(" (%d)", length);}/* * Insert an entry into the cache.  Taken from print-nfs.c */static voidrx_cache_insert(const u_char *bp, const struct ip *ip, int dport,		int length){	struct rx_cache_entry *rxent;	const struct rx_header *rxh = (const struct rx_header *) bp;	if (snapend - bp + 1 <= sizeof(struct rx_header) + sizeof(int32_t))		return;	rxent = &rx_cache[rx_cache_next];	if (++rx_cache_next >= RX_CACHE_SIZE)		rx_cache_next = 0;		rxent->callnum = rxh->callNumber;	rxent->client = ip->ip_src;	rxent->server = ip->ip_dst;	rxent->dport = dport;	rxent->serviceId = rxh->serviceId;	rxent->opcode = EXTRACT_32BITS(bp + sizeof(struct rx_header));}/* * Lookup an entry in the cache.  Also taken from print-nfs.c * * Note that because this is a reply, we're looking at the _source_ * port. */static intrx_cache_find(const struct rx_header *rxh, const struct ip *ip, int sport,	      int32_t *opcode){	int i;	struct rx_cache_entry *rxent;	u_int32_t clip = ip->ip_dst.s_addr;	u_int32_t sip = ip->ip_src.s_addr;	/* Start the search where we last left off */	i = rx_cache_hint;	do {		rxent = &rx_cache[i];		if (rxent->callnum == rxh->callNumber &&		    rxent->client.s_addr == clip &&		    rxent->server.s_addr == sip && 		    rxent->serviceId == rxh->serviceId &&		    rxent->dport == sport) {			/* We got a match! */			rx_cache_hint = i;			*opcode = rxent->opcode;			return(1);		}		if (++i > RX_CACHE_SIZE)			i = 0;	} while (i != rx_cache_hint);	/* Our search failed */	return(0);}/* * These extrememly grody macros handle the printing of various AFS stuff. */#define FIDOUT() { unsigned long n1, n2, n3; \			TCHECK2(bp[0], sizeof(int32_t) * 3); \

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -