?? print-icmp6.c
字號(hào):
/* * Copyright (c) 1988, 1989, 1990, 1991, 1993, 1994 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code distributions * retain the above copyright notice and this paragraph in its entirety, (2) * distributions including binary code include the above copyright notice and * this paragraph in its entirety in the documentation or other materials * provided with the distribution, and (3) all advertising materials mentioning * features or use of this software display the following acknowledgement: * ``This product includes software developed by the University of California, * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of * the University nor the names of its contributors may be used to endorse * or promote products derived from this software without specific prior * written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */#ifndef lintstatic const char rcsid[] _U_ = "@(#) $Header: /tcpdump/master/tcpdump/print-icmp6.c,v 1.85.2.1 2008-02-05 19:36:58 guy Exp $";#endif#ifdef HAVE_CONFIG_H#include "config.h"#endif#ifdef INET6#include <tcpdump-stdinc.h>#include <stdio.h>#include <string.h>#include "interface.h"#include "addrtoname.h"#include "extract.h"#include "ip6.h"#include "icmp6.h"#include "ipproto.h"#include "udp.h"#include "ah.h"static const char *get_rtpref(u_int);static const char *get_lifetime(u_int32_t);static void print_lladdr(const u_char *, size_t);static void icmp6_opt_print(const u_char *, int);static void mld6_print(const u_char *);static void mldv2_report_print(const u_char *, u_int);static void mldv2_query_print(const u_char *, u_int);static struct udphdr *get_upperlayer(u_char *, u_int *);static void dnsname_print(const u_char *, const u_char *);static void icmp6_nodeinfo_print(u_int, const u_char *, const u_char *);static void icmp6_rrenum_print(const u_char *, const u_char *);#ifndef abs#define abs(a) ((0 < (a)) ? (a) : -(a))#endifstatic struct tok icmp6_type_values[] = { { ICMP6_DST_UNREACH, "destination unreachable"}, { ICMP6_PACKET_TOO_BIG, "packet too big"}, { ICMP6_TIME_EXCEEDED, "time exceeded in-transit"}, { ICMP6_PARAM_PROB, "parameter problem"}, { ICMP6_ECHO_REQUEST, "echo request"}, { ICMP6_ECHO_REPLY, "echo reply"}, { MLD6_LISTENER_QUERY, "multicast listener query"}, { MLD6_LISTENER_REPORT, "multicast listener report"}, { MLD6_LISTENER_DONE, "multicast listener done"}, { ND_ROUTER_SOLICIT, "router solicitation"}, { ND_ROUTER_ADVERT, "router advertisement"}, { ND_NEIGHBOR_SOLICIT, "neighbor solicitation"}, { ND_NEIGHBOR_ADVERT, "neighbor advertisement"}, { ND_REDIRECT, "redirect"}, { ICMP6_ROUTER_RENUMBERING, "router renumbering"}, { IND_SOLICIT, "inverse neighbor solicitation"}, { IND_ADVERT, "inverse neighbor advertisement"}, { MLDV2_LISTENER_REPORT, "multicast listener report v2"}, { ICMP6_HADISCOV_REQUEST, "ha discovery request"}, { ICMP6_HADISCOV_REPLY, "ha discovery reply"}, { ICMP6_MOBILEPREFIX_SOLICIT, "mobile router solicitation"}, { ICMP6_MOBILEPREFIX_ADVERT, "mobile router advertisement"}, { ICMP6_WRUREQUEST, "who-are-you request"}, { ICMP6_WRUREPLY, "who-are-you reply"}, { ICMP6_NI_QUERY, "node information query"}, { ICMP6_NI_REPLY, "node information reply"}, { MLD6_MTRACE, "mtrace message"}, { MLD6_MTRACE_RESP, "mtrace response"}, { 0, NULL }};static struct tok icmp6_dst_unreach_code_values[] = { { ICMP6_DST_UNREACH_NOROUTE, "unreachable route" }, { ICMP6_DST_UNREACH_ADMIN, " unreachable prohibited"}, { ICMP6_DST_UNREACH_BEYONDSCOPE, "beyond scope"}, { ICMP6_DST_UNREACH_ADDR, "unreachable address"}, { ICMP6_DST_UNREACH_NOPORT, "unreachable port"}, { 0, NULL }};static struct tok icmp6_opt_pi_flag_values[] = { { ND_OPT_PI_FLAG_ONLINK, "onlink" }, { ND_OPT_PI_FLAG_AUTO, "auto" }, { ND_OPT_PI_FLAG_ROUTER, "router" }, { 0, NULL }};static struct tok icmp6_opt_ra_flag_values[] = { { ND_RA_FLAG_MANAGED, "managed" }, { ND_RA_FLAG_OTHER, "other stateful"}, { ND_RA_FLAG_HOME_AGENT, "home agent"}, { 0, NULL }};static struct tok icmp6_nd_na_flag_values[] = { { ND_NA_FLAG_ROUTER, "router" }, { ND_NA_FLAG_SOLICITED, "solicited" }, { ND_NA_FLAG_OVERRIDE, "override" }, { 0, NULL }};static struct tok icmp6_opt_values[] = { { ND_OPT_SOURCE_LINKADDR, "source link-address"}, { ND_OPT_TARGET_LINKADDR, "destination link-address"}, { ND_OPT_PREFIX_INFORMATION, "prefix info"}, { ND_OPT_REDIRECTED_HEADER, "redirected header"}, { ND_OPT_MTU, "mtu"}, { ND_OPT_ADVINTERVAL, "advertisement interval"}, { ND_OPT_HOMEAGENT_INFO, "homeagent information"}, { ND_OPT_ROUTE_INFO, "route info"}, { 0, NULL }};/* mldv2 report types */static struct tok mldv2report2str[] = { { 1, "is_in" }, { 2, "is_ex" }, { 3, "to_in" }, { 4, "to_ex" }, { 5, "allow" }, { 6, "block" }, { 0, NULL }};static const char *get_rtpref(u_int v){ static const char *rtpref_str[] = { "medium", /* 00 */ "high", /* 01 */ "rsv", /* 10 */ "low" /* 11 */ }; return rtpref_str[((v & ND_RA_FLAG_RTPREF_MASK) >> 3) & 0xff];}static const char *get_lifetime(u_int32_t v){ static char buf[20]; if (v == (u_int32_t)~0UL) return "infinity"; else { snprintf(buf, sizeof(buf), "%u", v); return buf; }}static voidprint_lladdr(const u_int8_t *p, size_t l){ const u_int8_t *ep, *q; q = p; ep = p + l; while (l > 0 && q < ep) { if (q > p) printf(":"); printf("%02x", *q++); l--; }}static int icmp6_cksum(const struct ip6_hdr *ip6, const struct icmp6_hdr *icp, u_int len){ size_t i; register const u_int16_t *sp; u_int32_t sum; union { struct { struct in6_addr ph_src; struct in6_addr ph_dst; u_int32_t ph_len; u_int8_t ph_zero[3]; u_int8_t ph_nxt; } ph; u_int16_t pa[20]; } phu; /* pseudo-header */ memset(&phu, 0, sizeof(phu)); phu.ph.ph_src = ip6->ip6_src; phu.ph.ph_dst = ip6->ip6_dst; phu.ph.ph_len = htonl(len); phu.ph.ph_nxt = IPPROTO_ICMPV6; sum = 0; for (i = 0; i < sizeof(phu.pa) / sizeof(phu.pa[0]); i++) sum += phu.pa[i]; sp = (const u_int16_t *)icp; for (i = 0; i < (len & ~1); i += 2) sum += *sp++; if (len & 1) sum += htons((*(const u_int8_t *)sp) << 8); while (sum > 0xffff) sum = (sum & 0xffff) + (sum >> 16); sum = ~sum & 0xffff; return (sum);}voidicmp6_print(const u_char *bp, u_int length, const u_char *bp2, int fragmented){ const struct icmp6_hdr *dp; const struct ip6_hdr *ip; const struct ip6_hdr *oip; const struct udphdr *ouh; int dport; const u_char *ep; u_int prot; dp = (struct icmp6_hdr *)bp; ip = (struct ip6_hdr *)bp2; oip = (struct ip6_hdr *)(dp + 1); /* 'ep' points to the end of available data. */ ep = snapend; TCHECK(dp->icmp6_cksum); if (vflag && !fragmented) { int sum = dp->icmp6_cksum; if (TTEST2(bp[0], length)) { sum = icmp6_cksum(ip, dp, length); if (sum != 0) (void)printf("[bad icmp6 cksum %x!] ", sum); else (void)printf("[icmp6 sum ok] "); } } printf("ICMP6, %s", tok2str(icmp6_type_values,"unknown icmp6 type (%u)",dp->icmp6_type)); /* display cosmetics: print the packet length for printer that use the vflag now */ if (vflag && (dp->icmp6_type == ND_ROUTER_SOLICIT || ND_ROUTER_ADVERT || ND_NEIGHBOR_ADVERT || ND_NEIGHBOR_SOLICIT || ND_REDIRECT || ICMP6_HADISCOV_REPLY || ICMP6_MOBILEPREFIX_ADVERT )) printf(", length %u", length); switch (dp->icmp6_type) { case ICMP6_DST_UNREACH: TCHECK(oip->ip6_dst); printf(", %s", tok2str(icmp6_dst_unreach_code_values,"unknown unreach code (%u)",dp->icmp6_code)); switch (dp->icmp6_code) { case ICMP6_DST_UNREACH_NOROUTE: /* fall through */ case ICMP6_DST_UNREACH_ADMIN: case ICMP6_DST_UNREACH_ADDR: printf(" %s",ip6addr_string(&oip->ip6_dst)); break; case ICMP6_DST_UNREACH_BEYONDSCOPE: printf(" %s, source address %s", ip6addr_string(&oip->ip6_dst), ip6addr_string(&oip->ip6_src)); break; case ICMP6_DST_UNREACH_NOPORT: if ((ouh = get_upperlayer((u_char *)oip, &prot)) == NULL) goto trunc; dport = EXTRACT_16BITS(&ouh->uh_dport); switch (prot) { case IPPROTO_TCP: printf(", %s tcp port %s", ip6addr_string(&oip->ip6_dst), tcpport_string(dport)); break; case IPPROTO_UDP: printf(", %s udp port %s", ip6addr_string(&oip->ip6_dst), udpport_string(dport)); break; default: printf(", %s protocol %d port %d unreachable", ip6addr_string(&oip->ip6_dst), oip->ip6_nxt, dport); break; } break; default: if (vflag <= 1) { print_unknown_data(bp,"\n\t",length); return; } break; } break; case ICMP6_PACKET_TOO_BIG: TCHECK(dp->icmp6_mtu); printf(", mtu %u", EXTRACT_32BITS(&dp->icmp6_mtu)); break; case ICMP6_TIME_EXCEEDED: TCHECK(oip->ip6_dst); switch (dp->icmp6_code) { case ICMP6_TIME_EXCEED_TRANSIT: printf(" for %s", ip6addr_string(&oip->ip6_dst)); break; case ICMP6_TIME_EXCEED_REASSEMBLY: printf(" (reassembly)"); break; default: printf(", unknown code (%u)", dp->icmp6_code); break; } break; case ICMP6_PARAM_PROB: TCHECK(oip->ip6_dst); switch (dp->icmp6_code) { case ICMP6_PARAMPROB_HEADER: printf(", errorneous - octet %u", EXTRACT_32BITS(&dp->icmp6_pptr)); break; case ICMP6_PARAMPROB_NEXTHEADER: printf(", next header - octet %u", EXTRACT_32BITS(&dp->icmp6_pptr)); break; case ICMP6_PARAMPROB_OPTION: printf(", option - octet %u", EXTRACT_32BITS(&dp->icmp6_pptr)); break; default: printf(", code-#%d", dp->icmp6_code); break; } break; case ICMP6_ECHO_REQUEST: case ICMP6_ECHO_REPLY: TCHECK(dp->icmp6_seq); printf(", seq %u", EXTRACT_16BITS(&dp->icmp6_seq)); break; case ICMP6_MEMBERSHIP_QUERY: if (length == MLD_MINLEN) { mld6_print((const u_char *)dp); } else if (length >= MLDV2_MINLEN) { printf("v2 "); mldv2_query_print((const u_char *)dp, length); } else { printf(" unknown-version (len %u) ", length); } break; case ICMP6_MEMBERSHIP_REPORT: mld6_print((const u_char *)dp); break; case ICMP6_MEMBERSHIP_REDUCTION: mld6_print((const u_char *)dp); break; case ND_ROUTER_SOLICIT:#define RTSOLLEN 8 if (vflag) { icmp6_opt_print((const u_char *)dp + RTSOLLEN, length - RTSOLLEN); } break; case ND_ROUTER_ADVERT:#define RTADVLEN 16 if (vflag) { struct nd_router_advert *p; p = (struct nd_router_advert *)dp; TCHECK(p->nd_ra_retransmit); printf("\n\thop limit %u, Flags [%s]" \ ", pref %s, router lifetime %us, reachable time %us, retrans time %us", (u_int)p->nd_ra_curhoplimit, bittok2str(icmp6_opt_ra_flag_values,"none",(p->nd_ra_flags_reserved)), get_rtpref(p->nd_ra_flags_reserved), EXTRACT_16BITS(&p->nd_ra_router_lifetime), EXTRACT_32BITS(&p->nd_ra_reachable), EXTRACT_32BITS(&p->nd_ra_retransmit)); icmp6_opt_print((const u_char *)dp + RTADVLEN, length - RTADVLEN); } break; case ND_NEIGHBOR_SOLICIT: { struct nd_neighbor_solicit *p; p = (struct nd_neighbor_solicit *)dp; TCHECK(p->nd_ns_target); printf(", who has %s", ip6addr_string(&p->nd_ns_target)); if (vflag) {#define NDSOLLEN 24 icmp6_opt_print((const u_char *)dp + NDSOLLEN, length - NDSOLLEN); } } break; case ND_NEIGHBOR_ADVERT: { struct nd_neighbor_advert *p; p = (struct nd_neighbor_advert *)dp; TCHECK(p->nd_na_target);
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -