#include #include #include "icmp.h" #include "ip.h" #include "util.h" #include "vars.h" void dump_icmp(void) { unsigned char icmp_type; unsigned char icmp_code; need(8,"minimum ICMP header"); printx(pkt,1); icmp_type = get8(0); printf("icmp_type"); switch (icmp_type) { case ICMP_ECHOREPLY: printf(" [ECHOREPLY]"); break; case ICMP_UNREACH: printf(" [UNREACH]"); break; case ICMP_SOURCEQUENCH: printf(" [SOURCEQUENCH]"); break; case ICMP_REDIRECT: printf(" [REDIRECT]"); break; case ICMP_ECHO: printf(" [ECHO]"); break; case ICMP_TIMXCEED: printf(" [TIMXCEED]"); break; case ICMP_PARAMPROB: printf(" [PARAMPROB]"); break; case ICMP_TSTAMP: printf(" [TSTAMP]"); break; case ICMP_TSTAMPREPLY: printf(" [TSTAMPREPLY]"); break; case ICMP_IREQ: printf(" [IREQ]"); break; case ICMP_IREQREPLY: printf(" [IREQREPLY]"); break; case ICMP_MASKREQ: printf(" [MASKREQ]"); break; case ICMP_MASKREPLY: printf(" [MASKREPLY]"); break; } printf("\n"); consume(1); printx(pkt,1); icmp_code = get8(0); consume(1); printf("icmp_code"); switch (icmp_type) { case ICMP_UNREACH: switch (icmp_code) { case ICMP_UNREACH_NET: printf(" [NET]"); break; case ICMP_UNREACH_HOST: printf(" [HOST]"); break; case ICMP_UNREACH_PROTOCOL: printf(" [PROTOCOL]"); break; case ICMP_UNREACH_PORT: printf(" [PORT]"); break; case ICMP_UNREACH_NEEDFRAG: printf(" [NEEDFRAG]"); break; case ICMP_UNREACH_SRCFAIL: printf(" [SRCFAIL]"); break; } break; case ICMP_REDIRECT: switch (icmp_code) { case ICMP_REDIRECT_NET: printf(" [NET]"); break; case ICMP_REDIRECT_HOST: printf(" [HOST]"); break; case ICMP_REDIRECT_TOSNET: printf(" [TOSNET]"); break; case ICMP_REDIRECT_TOSHOST: printf(" [TOSHOST]"); break; } break; case ICMP_TIMXCEED: switch (icmp_code) { case ICMP_TIMXCEED_INTRANS: printf(" [INTRANS]"); break; case ICMP_TIMXCEED_REASS: printf(" [REASS]"); break; } break; } printf("\n"); printx(pkt,2); printf("icmp_sum\n"); consume(2); switch (icmp_type) { /* ICMP_ECHOREPLY listed with ICMP_ECHO */ case ICMP_UNREACH: printx(pkt,4); printf("(unused)\n"); consume(4); print_ip_header("icmp_ip.",0); break; case ICMP_SOURCEQUENCH: printx(pkt,4); printf("(unused)\n"); consume(4); print_ip_header("icmp_ip.",0); break; case ICMP_REDIRECT: printx(pkt,4); printf("icmp_gateway [%d.%d.%d.%d]\n",get8(0),get8(1),get8(2),get8(3)); consume(4); print_ip_header("icmp_ip.",0); break; case ICMP_ECHO: case ICMP_ECHOREPLY: printx(pkt,2); printf("icmp_id\n"); consume(2); printx(pkt,2); printf("icmp_seq\n"); consume(2); break; case ICMP_TIMXCEED: printx(pkt,4); printf("(unused)\n"); consume(4); print_ip_header("icmp_ip.",0); break; case ICMP_PARAMPROB: { unsigned char ptr; printx(pkt,1); ptr = get8(0); printf("icmp_ptr [%d]\n",ptr); consume(1); printx(pkt,3); printf("(unused)\n"); consume(3); print_ip_header("icmp_ip.",0); } break; case ICMP_TSTAMP: case ICMP_TSTAMPREPLY: { unsigned long int t; static const char *tag[3] = { "Originate", "Receive", "Transmit" }; int i; printx(pkt,2); printf("icmp_id\n"); consume(2); printx(pkt,2); printf("icmp_seq\n"); consume(2); need(12,"ICMP Timestamp data"); for (i=0;i<3;i++) { printx(pkt,4); t = get32(0); consume(4); if (t & 0x80000000) { printf("ICMP %s Timestamp [nonstandard %ld]\n",tag[i],t&~0x80000000); } else { printf("ICMP %s Timestamp [%ld=%02d:%02d:%02d.%03d]\n",tag[i],t,(int)(t/(60*60*1000)),(int)((t/(60*1000))%60),(int)((t/1000)%60),(int)(t%1000)); } } } break; case ICMP_IREQ: case ICMP_IREQREPLY: printx(pkt,2); printf("icmp_id\n"); consume(2); printx(pkt,2); printf("icmp_seq\n"); consume(2); break; case ICMP_MASKREQ: case ICMP_MASKREPLY: printx(pkt,2); printf("icmp_id\n"); consume(2); printx(pkt,2); printf("icmp_seq\n"); consume(2); need(4,"ICMP Address Mask data"); printx(pkt,4); printf("icmp_mask [%d.%d.%d.%d]\n",get8(0),get8(1),get8(2),get8(3)); consume(4); break; } }