/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Assorted dump routines.
*/
:1#include "V.h"
#include "sys_types.h"
#include "sys_in.h"
#include "sys_ip.h"
#include "icmp.h"
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
dumpIPpkt(pp,n,m)
	IPKT *pp;	/* IP packet */
	int   n;	/* IP packet size */
	char *m;	/* Message for labeling output */
{	int   h, t;
	int   savelevel;
	U8    *cp;
	U16   *sp;
	U32   *lp;

:5	V5 "dumpIPpkt(pp=%08lX,n=%d,`%s')",pp,n,m D;
:4	H4(pp,n,m);
	cp = (U8 *)pp;
	sp = (U16*)pp;
	lp = (U32*)pp;
	savelevel = Vflvl;
	Vflvl = 0;	/* Suppress function names */
	t = cp[1];
	h = (cp[0])&0xF;
:1	P3 "IPpkt version=%d hdrlen=%d prec=%d type=%c%c%c%d totallen=%d"
:1		,(cp[0]>>4)&0xF
:1		,h
:1		,t>>5
:1		,t&0x10?'D':'-'
:1		,t&0x10?'T':'-'
:1		,t&0x10?'T':'-'
:1		,t&0x03
:1		,sp[1]
:1	 D;
:1	P3 "IPpkt ident=%04X=%d flags=%d off=%d"
:1		,sp[2],sp[2]
:1		,cp[6]>>5
:1		,sp[3]&0x1FFF
:1	 D;
:1	P3 "IPpkt time=%d proto=%d=%s chksum=%04X=%d"
:1		,cp[8]
:1		,cp[9],IPproto(cp[9])
:1		,sp[5],sp[5]
:1	 D;
:1	P2 "IPpkt src=%08lX=%d.%d.%d.%d dst=%08lX=%d.%d.%d.%d"
:1		,lp[3],cp[12],cp[13],cp[14],cp[15]
:1		,lp[4],cp[16],cp[17],cp[18],cp[19]
:1	 D;
	switch (cp[9]) {		/* PROTO field */
	  case IPPROTO_ICMP:	/* control message protocol */
		dumpICMPpkt(pp,cp+4*h,sp[1]-4*h,m);
		break;
#ifdef IPPROTO_GGP
	  case IPPROTO_GGP:		/* gateway^2 (deprecated) */
#endif
	  case IPPROTO_TCP:		/* tcp */
	  case IPPROTO_EGP:		/* exterior gateway protocol */
	  case IPPROTO_PUP:		/* pup */
	  case IPPROTO_UDP:		/* user datagram protocol */
#ifdef IPPROTO_IP
	  case IPPROTO_IP:		/* dummy for IP */
#endif
	  default:
:3		P3 "No further dump routine for this type packet." D;
		break;
	}
	Vflvl = savelevel;
	return(0);
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
dumpICMPpkt(ph,pp,n,m)
	U8   *ph;	/* IP header */
	U8   *pp;	/* ICMP packet */
	int   n;	/* Size of ICMP packet */
	char *m;	/* Message */
{	U8   *cp, *ch;
	U16  *sp, *sh;
	U32  *lp, *lh;

:4	H4(pp,n,"ICMPpkt");
:5	V5 "dumpICMPpkt(ph=%08lX,pp=%08lX,n=%d,`%s')",ph,pp,n,m D;
	ch = (U8 *)ph;
	sh = (U16*)ph;
	lh = (U32*)ph;	/* Pointers into IP header */
	cp = (U8 *)pp;
	sp = (U16*)pp;
	lp = (U32*)pp;	/* Pointers into ICMP packet */

:1	P3 "ICMP size=%d type=%d=%s code=%d chksum=%04X=%d %s"
:1		,n
:1		,cp[0],ICMPtype(cp[0])
:1		,cp[1]
:1		,sp[1],sp[1]
:1		,m
:1	 D;
	switch (cp[0]) {	/* The rest depends on the type */
	  case ICMP_ECHOREPLY:				/*  0  echo reply */
:1		P3 "ICMP Echo Reply: id=%04X=%d seq=%04X=%d from %08lX=%d.%d.%d.%d"
:1			,sp[2],sp[2]
:1			,sp[3],sp[3]
:1			,lh[3],ch[12],ch[13],ch[14],ch[15]
:1		 D;
		break;
	  case ICMP_UNREACH:				/*  3  dest unreachable, codes: */
		switch (cp[1]) {
	  	  case ICMP_UNREACH_NET:		/*  0  bad net */
	  	  case ICMP_UNREACH_HOST:		/*  1  bad host */
:1			P3 "ICMP %08lX=%d.%d.%d.%d unreachable from %08lX=%d.%d.%d.%d."
:1				,lp[5],cp[20],cp[21],cp[22],cp[23]
:1				,lp[6],cp[24],cp[25],cp[26],cp[27]
:1			 D;
			break;
	  	  case ICMP_UNREACH_PROTOCOL:	/*  2  bad protocol */
			break;
	  	  case ICMP_UNREACH_PORT:		/*  3  bad port */
			break;
	  	  case ICMP_UNREACH_NEEDFRAG:	/*  4  IP_DF caused drop */
			break;
	  	  case ICMP_UNREACH_SRCFAIL:	/*  5  src route failed */
			break;
		}
	  case ICMP_SOURCEQUENCH:			/*  4  packet lost, slow down */
		break;
	  case ICMP_REDIRECT:				/*  5  shorter route, codes: */
		switch (cp[1]) {
	  	  case ICMP_REDIRECT_NET:		/*  0  for network */
	  	  case ICMP_REDIRECT_HOST:		/*  1  for host */
	  	  case ICMP_REDIRECT_TOSNET:	/*  2  for tos and net */
	  	  case ICMP_REDIRECT_TOSHOST:	/*  3  for tos and host */
:1			P2 "ICMP_REDIRECT id=%04X=%d seq=%04X=%d gateway=%08lX=%d.%d.%d.%d"
:1				,sp[2],sp[2]
:1				,sp[3],sp[3]
:1				,lp[1],cp[4],cp[5],cp[6],cp[7]
:1			 D;
			break;
		}
		break;
	  case ICMP_ECHO:					/*  8  echo service */
		break	;
	  case ICMP_TIMXCEED:				/* 11  time exceeded, code: */
		switch (cp[1]) {
	  	  case ICMP_TIMXCEED_INTRANS:	/*  0  ttl==0 in transit */
			break;
	  	  case ICMP_TIMXCEED_REASS:		/*  1  ttl==0 in reass */
			break;
		}
		break;
	  case ICMP_PARAMPROB:				/* 12  ip header bad */
		break;
	  case ICMP_TSTAMP:					/* 13  timestamp request */
		break;
	  case ICMP_TSTAMPREPLY:			/* 14  timestamp reply */
		break;
	  case ICMP_IREQ:					/* 15  information request */
		break;
	  case ICMP_IREQREPLY:				/* 16  information reply */
		break;
#ifdef ICMP_MASKREQ
	  case ICMP_MASKREQ:				/* 17  address mask request */
		break;
#endif
#ifdef ICMP_MASKREPLY
	  case ICMP_MASKREPLY:				/* 18  address mask reply */
		break;
#endif
	  default:
:3		P3 "ICMP packet of unknown type %d code %d.",cp[0],cp[1] D;
		break;
	}
:3	H3(cp+8,n-8,"ICMPdata");
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * Convert an ICMP "code" field to a printable string.
 */
char *
ICMPcode(t)
{	static char *ctab[] = {
		"Network Unreachable",
		"Host Unreachable",
		"Protocol Unreachable",
		"Port Unreachable",
		"Fragmentation Needed",
		"Source Route Failed",
	};
	if (t < 0 || t > 5)
		return("OUT-OF-RANGE");
	return(ctab[t]);
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * Convert an ICMP "type" field to a printable string.
 */
char *
ICMPtype(t)
{	static char *ttab[] = {
		"Echo Reply",
		"ICMP_1",
		"ICMP_2",
		"Dest Unreachable",
		"Source Quence",
		"Redirect",
		"ICMP_6",
		"ICMP_7",
		"Echo",
		"ICMP_9",
		"ICMP_10",
		"Time Exceeded",
		"Parameter Problem",
		"Timestamp",
		"Timestamp Reply",
		"Info Request",
		"Info Reply"
	};
	if (t < 0 || t > 16)
		return("OUT-OF-RANGE");
	return(ttab[t]);
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * Convert an IP "type" field to a printable string.
 */
char *
IPproto(t)
{	static char *ttab[] = {
		"IP",	/*  0 dummy for IP */
		"ICMP",	/*  1 control message protocol */
		"GGP",	/*  2 gateway^2 (deprecated) */
		"?",	/*  3 UNUSED */
		"?",	/*  4 UNUSED */
		"?",	/*  5 UNUSED */
		"TCP",	/*  6 tcp */
		"?",	/*  7 UNUSED */
		"EGP",	/*  8 exterior gateway protocol */
		"?",	/*  9 UNUSED */
		"?",	/* 10 UNUSED */
		"?",	/* 11 UNUSED */
		"PUP",	/* 12 pup */
		"?",	/* 13 UNUSED */
		"?",	/* 14 UNUSED */
		"?",	/* 15 UNUSED */
		"?",	/* 16 UNUSED */
		"UDP",	/* 17 user datagram protocol */
	};
	if (t < 0 || t > 17)
		return("OUT-OF-RANGE");
	return(ttab[t]);
}
