?? print-icmp6.c
字號:
printf(", tgt is %s", ip6addr_string(&p->nd_na_target)); if (vflag) { printf(", Flags [%s]", bittok2str(icmp6_nd_na_flag_values, "none", EXTRACT_32BITS(&p->nd_na_flags_reserved)));#define NDADVLEN 24 icmp6_opt_print((const u_char *)dp + NDADVLEN, length - NDADVLEN);#undef NDADVLEN } } break; case ND_REDIRECT:#define RDR(i) ((struct nd_redirect *)(i)) TCHECK(RDR(dp)->nd_rd_dst); printf(", %s", getname6((const u_char *)&RDR(dp)->nd_rd_dst)); TCHECK(RDR(dp)->nd_rd_target); printf(" to %s", getname6((const u_char*)&RDR(dp)->nd_rd_target));#define REDIRECTLEN 40 if (vflag) { icmp6_opt_print((const u_char *)dp + REDIRECTLEN, length - REDIRECTLEN); } break;#undef REDIRECTLEN#undef RDR case ICMP6_ROUTER_RENUMBERING: icmp6_rrenum_print(bp, ep); break; case ICMP6_NI_QUERY: case ICMP6_NI_REPLY: icmp6_nodeinfo_print(length, bp, ep); break; case IND_SOLICIT: case IND_ADVERT: break; case ICMP6_V2_MEMBERSHIP_REPORT: mldv2_report_print((const u_char *) dp, length); break; case ICMP6_MOBILEPREFIX_SOLICIT: /* fall through */ case ICMP6_HADISCOV_REQUEST: TCHECK(dp->icmp6_data16[0]); printf(", id 0x%04x", EXTRACT_16BITS(&dp->icmp6_data16[0])); break; case ICMP6_HADISCOV_REPLY: if (vflag) { struct in6_addr *in6; u_char *cp; TCHECK(dp->icmp6_data16[0]); printf(", id 0x%04x", EXTRACT_16BITS(&dp->icmp6_data16[0])); cp = (u_char *)dp + length; in6 = (struct in6_addr *)(dp + 1); for (; (u_char *)in6 < cp; in6++) { TCHECK(*in6); printf(", %s", ip6addr_string(in6)); } } break; case ICMP6_MOBILEPREFIX_ADVERT: if (vflag) { TCHECK(dp->icmp6_data16[0]); printf(", id 0x%04x", EXTRACT_16BITS(&dp->icmp6_data16[0])); if (dp->icmp6_data16[1] & 0xc0) printf(" "); if (dp->icmp6_data16[1] & 0x80) printf("M"); if (dp->icmp6_data16[1] & 0x40) printf("O");#define MPADVLEN 8 icmp6_opt_print((const u_char *)dp + MPADVLEN, length - MPADVLEN); } break; default: printf(", length %u", length); if (vflag <= 1) print_unknown_data(bp,"\n\t", length); return; } if (!vflag) printf(", length %u", length); return;trunc: fputs("[|icmp6]", stdout);}static struct udphdr *get_upperlayer(u_char *bp, u_int *prot){ const u_char *ep; struct ip6_hdr *ip6 = (struct ip6_hdr *)bp; struct udphdr *uh; struct ip6_hbh *hbh; struct ip6_frag *fragh; struct ah *ah; u_int nh; int hlen; /* 'ep' points to the end of available data. */ ep = snapend; if (!TTEST(ip6->ip6_nxt)) return NULL; nh = ip6->ip6_nxt; hlen = sizeof(struct ip6_hdr); while (bp < ep) { bp += hlen; switch(nh) { case IPPROTO_UDP: case IPPROTO_TCP: uh = (struct udphdr *)bp; if (TTEST(uh->uh_dport)) { *prot = nh; return(uh); } else return(NULL); /* NOTREACHED */ case IPPROTO_HOPOPTS: case IPPROTO_DSTOPTS: case IPPROTO_ROUTING: hbh = (struct ip6_hbh *)bp; if (!TTEST(hbh->ip6h_len)) return(NULL); nh = hbh->ip6h_nxt; hlen = (hbh->ip6h_len + 1) << 3; break; case IPPROTO_FRAGMENT: /* this should be odd, but try anyway */ fragh = (struct ip6_frag *)bp; if (!TTEST(fragh->ip6f_offlg)) return(NULL); /* fragments with non-zero offset are meaningless */ if ((EXTRACT_16BITS(&fragh->ip6f_offlg) & IP6F_OFF_MASK) != 0) return(NULL); nh = fragh->ip6f_nxt; hlen = sizeof(struct ip6_frag); break; case IPPROTO_AH: ah = (struct ah *)bp; if (!TTEST(ah->ah_len)) return(NULL); nh = ah->ah_nxt; hlen = (ah->ah_len + 2) << 2; break; default: /* unknown or undecodable header */ *prot = nh; /* meaningless, but set here anyway */ return(NULL); } } return(NULL); /* should be notreached, though */}static voidicmp6_opt_print(const u_char *bp, int resid){ const struct nd_opt_hdr *op; const struct nd_opt_hdr *opl; /* why there's no struct? */ const struct nd_opt_prefix_info *opp; const struct icmp6_opts_redirect *opr; const struct nd_opt_mtu *opm; const struct nd_opt_advinterval *opa; const struct nd_opt_homeagent_info *oph; const struct nd_opt_route_info *opri; const u_char *cp, *ep; struct in6_addr in6, *in6p; size_t l;#define ECHECK(var) if ((u_char *)&(var) > ep - sizeof(var)) return cp = bp; /* 'ep' points to the end of available data. */ ep = snapend; while (cp < ep) { op = (struct nd_opt_hdr *)cp; ECHECK(op->nd_opt_len); if (resid <= 0) return; if (op->nd_opt_len == 0) goto trunc; if (cp + (op->nd_opt_len << 3) > ep) goto trunc; printf("\n\t %s option (%u), length %u (%u): ", tok2str(icmp6_opt_values, "unknown", op->nd_opt_type), op->nd_opt_type, op->nd_opt_len << 3, op->nd_opt_len); switch (op->nd_opt_type) { case ND_OPT_SOURCE_LINKADDR: opl = (struct nd_opt_hdr *)op; l = (op->nd_opt_len << 3) - 2; print_lladdr(cp + 2, l); break; case ND_OPT_TARGET_LINKADDR: opl = (struct nd_opt_hdr *)op; l = (op->nd_opt_len << 3) - 2; print_lladdr(cp + 2, l); break; case ND_OPT_PREFIX_INFORMATION: opp = (struct nd_opt_prefix_info *)op; TCHECK(opp->nd_opt_pi_prefix); printf("%s/%u%s, Flags [%s], valid time %ss", ip6addr_string(&opp->nd_opt_pi_prefix), opp->nd_opt_pi_prefix_len, (op->nd_opt_len != 4) ? "badlen" : "", bittok2str(icmp6_opt_pi_flag_values, "none", opp->nd_opt_pi_flags_reserved), get_lifetime(EXTRACT_32BITS(&opp->nd_opt_pi_valid_time))); printf(", pref. time %ss", get_lifetime(EXTRACT_32BITS(&opp->nd_opt_pi_preferred_time))); break; case ND_OPT_REDIRECTED_HEADER: opr = (struct icmp6_opts_redirect *)op; print_unknown_data(bp,"\n\t ",op->nd_opt_len<<3); /* xxx */ break; case ND_OPT_MTU: opm = (struct nd_opt_mtu *)op; TCHECK(opm->nd_opt_mtu_mtu); printf(" %u%s", EXTRACT_32BITS(&opm->nd_opt_mtu_mtu), (op->nd_opt_len != 1) ? "bad option length" : "" ); break; case ND_OPT_ADVINTERVAL: opa = (struct nd_opt_advinterval *)op; TCHECK(opa->nd_opt_adv_interval); printf(" %us", EXTRACT_32BITS(&opa->nd_opt_adv_interval)); break; case ND_OPT_HOMEAGENT_INFO: oph = (struct nd_opt_homeagent_info *)op; TCHECK(oph->nd_opt_hai_lifetime); printf(" preference %u, lifetime %u", EXTRACT_16BITS(&oph->nd_opt_hai_preference), EXTRACT_16BITS(&oph->nd_opt_hai_lifetime)); break; case ND_OPT_ROUTE_INFO: opri = (struct nd_opt_route_info *)op; TCHECK(opri->nd_opt_rti_lifetime); memset(&in6, 0, sizeof(in6)); in6p = (struct in6_addr *)(opri + 1); switch (op->nd_opt_len) { case 1: break; case 2: TCHECK2(*in6p, 8); memcpy(&in6, opri + 1, 8); break; case 3: TCHECK(*in6p); memcpy(&in6, opri + 1, sizeof(in6)); break; default: goto trunc; } printf(" %s/%u", ip6addr_string(&in6), opri->nd_opt_rti_prefixlen); printf(", pref=%s", get_rtpref(opri->nd_opt_rti_flags)); printf(", lifetime=%s", get_lifetime(EXTRACT_32BITS(&opri->nd_opt_rti_lifetime))); break; default: if (vflag <= 1) { print_unknown_data(cp+2,"\n\t ", (op->nd_opt_len << 3) - 2); /* skip option header */ return; } break; } /* do we want to see an additional hexdump ? */ if (vflag> 1) print_unknown_data(cp+2,"\n\t ", (op->nd_opt_len << 3) - 2); /* skip option header */ cp += op->nd_opt_len << 3; resid -= op->nd_opt_len << 3; } return; trunc: fputs("[ndp opt]", stdout); return;#undef ECHECK}static voidmld6_print(const u_char *bp){ struct mld6_hdr *mp = (struct mld6_hdr *)bp; const u_char *ep; /* 'ep' points to the end of available data. */ ep = snapend; if ((u_char *)mp + sizeof(*mp) > ep) return; printf("max resp delay: %d ", EXTRACT_16BITS(&mp->mld6_maxdelay)); printf("addr: %s", ip6addr_string(&mp->mld6_addr));}static voidmldv2_report_print(const u_char *bp, u_int len){ struct icmp6_hdr *icp = (struct icmp6_hdr *) bp; u_int group, nsrcs, ngroups; u_int i, j; /* Minimum len is 8 */ if (len < 8) { printf(" [invalid len %d]", len); return; } TCHECK(icp->icmp6_data16[1]); ngroups = ntohs(icp->icmp6_data16[1]); printf(", %d group record(s)", ngroups); if (vflag > 0) { /* Print the group records */ group = 8; for (i = 0; i < ngroups; i++) { /* type(1) + auxlen(1) + numsrc(2) + grp(16) */ if (len < group + 20) { printf(" [invalid number of groups]"); return; } TCHECK2(bp[group + 4], sizeof(struct in6_addr)); printf(" [gaddr %s", ip6addr_string(&bp[group + 4])); printf(" %s", tok2str(mldv2report2str, " [v2-report-#%d]", bp[group])); nsrcs = (bp[group + 2] << 8) + bp[group + 3]; /* Check the number of sources and print them */ if (len < group + 20 + (nsrcs * sizeof(struct in6_addr))) { printf(" [invalid number of sources %d]", nsrcs); return; } if (vflag == 1) printf(", %d source(s)", nsrcs); else { /* Print the sources */ (void)printf(" {"); for (j = 0; j < nsrcs; j++) { TCHECK2(bp[group + 20 + j * sizeof(struct in6_addr)], sizeof(struct in6_addr)); printf(" %s", ip6addr_string(&bp[group + 20 + j * sizeof(struct in6_addr)])); } (void)printf(" }"); } /* Next group record */ group += 20 + nsrcs * sizeof(struct in6_addr); printf("]"); } } return;trunc: (void)printf("[|icmp6]"); return;}static voidmldv2_query_print(const u_char *bp, u_int len){ struct icmp6_hdr *icp = (struct icmp6_hdr *) bp; u_int mrc; int mrt, qqi; u_int nsrcs; register u_int i; /* Minimum len is 28 */ if (len < 28) { printf(" [invalid len %d]", len); return; } TCHECK(icp->icmp6_data16[0]); mrc = ntohs(icp->icmp6_data16[0]); if (mrc < 32768) { mrt = mrc; } else { mrt = ((mrc & 0x0fff) | 0x1000) << (((mrc & 0x7000) >> 12) + 3); } if (vflag) { (void)printf(" [max resp delay=%d]", mrt); } TCHECK2(bp[8], sizeof(struct in6_addr)); printf(" [gaddr %s", ip6addr_string(&bp[8])); if (vflag) { TCHECK(bp[25]); if (bp[24] & 0x08) { printf(" sflag"); } if (bp[24] & 0x07) { printf(" robustness=%d", bp[24] & 0x07); } if (bp[25] < 128) { qqi = bp[25]; } else { qqi = ((bp[25] & 0x0f) | 0x10) << (((bp[25] & 0x70) >> 4) + 3); } printf(" qqi=%d", qqi); } TCHECK2(bp[26], 2); nsrcs = ntohs(*(u_short *)&bp[26]); if (nsrcs > 0) { if (len < 28 + nsrcs * sizeof(struct in6_addr)) printf(" [invalid number of sources]"); else if (vflag > 1) { printf(" {"); for (i = 0; i < nsrcs; i++) { TCHECK2(bp[28 + i * sizeof(struct in6_addr)], sizeof(struct in6_addr)); printf(" %s", ip6addr_string(&bp[28 + i * sizeof(struct in6_addr)])); } printf(" }"); } else printf(", %d source(s)", nsrcs); } printf("]"); return;
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -