/*- * Copyright (c) 2001-2005 Christian S.J. Peron * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef lint static const char rcsid[] = "@(#) $Header: /usr/cvs/ipex/icmp_print.c,v 1.7 2005/02/25 08:46:11 modulus Exp $"; #endif #include "ipex_includes.h" struct icmp_types { unsigned char type; char *section_text; }; static struct icmp_types p_types[]= { { ICMP_ECHOREPLY, "echo rep" }, { ICMP_UNREACH, "unreach" }, { ICMP_SOURCEQUENCH, "source quench" }, { ICMP_REDIRECT, "redirect" }, { ICMP_ECHO, "echo req" }, { ICMP_ROUTERADVERT, "router-advert" }, { ICMP_ROUTERSOLICIT, "router-solici" }, { ICMP_TIMXCEED, "time exceed" }, { ICMP_PARAMPROB, "smashed ip head" }, { ICMP_TSTAMP, "time stamp req" }, { ICMP_TSTAMPREPLY, "time stamp rep" }, { ICMP_IREQ, "info req" }, { ICMP_IREQREPLY, "info rep" }, { ICMP_MASKREQ, "mask req" }, { ICMP_MASKREPLY, "mask rep" }, { 0, NULL }, }; char * get_icmp_type(unsigned char icmp_t) { struct icmp_types *p; for(p = p_types; p->section_text; ++p) if (icmp_t == p->type) return (p->section_text); return (NULL); } int print_icmp(u_char *b, struct pcap_pkthdr *h, u_char *p) { struct cmdopts *x = &opts; char *d; int len; struct ip *ip = (struct ip *)(p + x->loffset); unsigned ip_hl = (ip->ip_hl * 0x4); unsigned ip_off = ntohs(ip->ip_off); unsigned frag = ip_off & (IP_MF|IP_OFFMASK); unsigned frag_off = frag ? (ip_off & IP_OFFMASK) * 8:0; struct icmp *icmp = (struct icmp *)(((char *)ip) + ip_hl); unsigned icmp_off = frag ? 0 : 4; u_32_t *sa, *da; struct ehdr *mhdr; mhdr = NULL; d = ((char *)icmp) + (icmp_off); len = (ntohs(ip->ip_len) - ip_hl - icmp_off); sa = (u_32_t *)&ip->ip_src; da = (u_32_t *)&ip->ip_dst; if (opts.Lflag) mhdr = process_link_headers(b, h, p); printf("%s %s%s > ", time_stamp(&h->ts, x->thiszone), (opts.Lflag ? mhdr->smac : "" ), hostname(4, sa)); printf( "%s%s icmp %s pattern: 0x%02x", (opts.Lflag ? mhdr->smac : "" ), hostname(4, da), get_icmp_type(icmp->icmp_type), d[13]); if (frag) { printf(" %d:%d@%d%s\n", ntohs(ip->ip_id), len, frag_off, frag_off ? "" : "+"); } else { printf( " (DF)\n"); } return (1); }