#include <stdio.h>
#include "global.h"
#include "mbuf.h"
#include "internet.h"
#include "icmp.h"
#include "trace.h"

/* Dump an ICMP header */
void
icmp_dump(bpp,source,dest,check)
struct mbuf **bpp;
int32 source,dest;
int check;		/* If 0, bypass checksum verify */
{
	struct icmp icmp;
	int16 csum;

	if(bpp == NULLBUFP || *bpp == NULLBUF)
		return;
	csum = cksum(NULLHEADER,*bpp,len_mbuf(*bpp));
	
	ntohicmp(&icmp,bpp);
	
	if(icmp.type <= 16 && icmptypes[icmp.type] != NULLCHAR)
		printf("ICMP: %s",icmptypes[icmp.type]);
	else
		printf("ICMP: type %u",icmp.type);

	switch(icmp.type){
	case DEST_UNREACH:
		if(icmp.code <= 5)
			printf(" %s",unreach[icmp.code]);
		else
			printf(" code %u",icmp.code);
		break;
	case REDIRECT:
		if(icmp.code <= 3)
			printf(" %s",redirect[icmp.code]);
		else
			printf(" code %u",icmp.code);
		break;
	case TIME_EXCEED:
		if(icmp.code <= 1)
			printf(" %s",exceed[icmp.code]);
		else
			printf(" code %u",icmp.code);
		break;
	case PARAM_PROB:
		printf(" pointer = %u",icmp.args.pointer);
		break;
	case ECHO:
	case ECHO_REPLY:
	case INFO_RQST:
	case INFO_REPLY:
	case TIMESTAMP:
	case TIME_REPLY:
		printf(" id %u seq %u",icmp.args.echo.id,icmp.args.echo.seq);
		break;
	}
	if(check && csum != 0){
		printf(" CHECKSUM ERROR (%u)",csum);
	}
	printf("\n");
	/* Dump the offending IP header, if any */
	switch(icmp.type){
	case DEST_UNREACH:
	case TIME_EXCEED:
	case PARAM_PROB:
	case QUENCH:
	case REDIRECT:
		printf("Returned ");
		ip_dump(bpp,0);
	}
}

