X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/e048961ec1e1b1d9b44ab6315fd87e826edc04c6..c0af6af3011d4c55bdadf3dd76cd5fc1115c50d0:/print-icmp6.c diff --git a/print-icmp6.c b/print-icmp6.c index 9bbd5c81..042e5072 100644 --- a/print-icmp6.c +++ b/print-icmp6.c @@ -139,7 +139,7 @@ struct icmp6_hdr { #define ICMP6_MAXTYPE 201 #define ICMP6_DST_UNREACH_NOROUTE 0 /* no route to destination */ -#define ICMP6_DST_UNREACH_ADMIN 1 /* administratively prohibited */ +#define ICMP6_DST_UNREACH_ADMIN 1 /* administratively prohibited */ #define ICMP6_DST_UNREACH_NOTNEIGHBOR 2 /* not a neighbor(obsolete) */ #define ICMP6_DST_UNREACH_BEYONDSCOPE 2 /* beyond scope of source address */ #define ICMP6_DST_UNREACH_ADDR 3 /* address unreachable */ @@ -148,7 +148,7 @@ struct icmp6_hdr { #define ICMP6_TIME_EXCEED_TRANSIT 0 /* ttl==0 in transit */ #define ICMP6_TIME_EXCEED_REASSEMBLY 1 /* ttl==0 in reass */ -#define ICMP6_PARAMPROB_HEADER 0 /* erroneous header field */ +#define ICMP6_PARAMPROB_HEADER 0 /* erroneous header field */ #define ICMP6_PARAMPROB_NEXTHEADER 1 /* unrecognized next header */ #define ICMP6_PARAMPROB_OPTION 2 /* unrecognized option */ @@ -320,7 +320,7 @@ struct nd_opt_rdnss { /* RDNSS RFC 6106 5.1 */ nd_uint8_t nd_opt_rdnss_len; nd_uint16_t nd_opt_rdnss_reserved; nd_uint32_t nd_opt_rdnss_lifetime; - nd_ipv6 nd_opt_rdnss_addr[1]; /* variable-length */ + nd_ipv6 nd_opt_rdnss_addr[1]; /* variable-length */ }; struct nd_opt_dnssl { /* DNSSL RFC 6106 5.2 */ @@ -479,7 +479,7 @@ struct rr_result { /* router renumbering result message */ static const char *get_rtpref(u_int); static const char *get_lifetime(uint32_t); static void print_lladdr(netdissect_options *ndo, const u_char *, size_t); -static void icmp6_opt_print(netdissect_options *ndo, const u_char *, int); +static int icmp6_opt_print(netdissect_options *ndo, const u_char *, int); static void mld6_print(netdissect_options *ndo, const u_char *); static void mldv2_report_print(netdissect_options *ndo, const u_char *, u_int); static void mldv2_query_print(netdissect_options *ndo, const u_char *, u_int); @@ -776,7 +776,7 @@ print_lladdr(netdissect_options *ndo, const uint8_t *p, size_t l) } } -static int icmp6_cksum(netdissect_options *ndo, const struct ip6_hdr *ip6, +static uint16_t icmp6_cksum(netdissect_options *ndo, const struct ip6_hdr *ip6, const struct icmp6_hdr *icp, u_int len) { return nextproto6_cksum(ndo, ip6, (const uint8_t *)(const void *)icp, len, len, @@ -840,7 +840,7 @@ rpl_printopts(netdissect_options *ndo, const uint8_t *opts, u_int length) } return; trunc: - ND_PRINT(" [|truncated]"); + nd_print_trunc(ndo); return; } @@ -869,7 +869,7 @@ rpl_dio_print(netdissect_options *ndo, } return; trunc: - ND_PRINT(" [|truncated]"); + nd_print_trunc(ndo); return; } @@ -883,7 +883,7 @@ rpl_dao_print(netdissect_options *ndo, ND_TCHECK_SIZE(dao); if (length < ND_RPL_DAO_MIN_LEN) - goto tooshort; + goto tooshort; bp += ND_RPL_DAO_MIN_LEN; length -= ND_RPL_DAO_MIN_LEN; @@ -911,7 +911,7 @@ rpl_dao_print(netdissect_options *ndo, return; trunc: - ND_PRINT(" [|truncated]"); + nd_print_trunc(ndo); return; tooshort: @@ -928,7 +928,7 @@ rpl_daoack_print(netdissect_options *ndo, ND_TCHECK_LEN(daoack, ND_RPL_DAOACK_MIN_LEN); if (length < ND_RPL_DAOACK_MIN_LEN) - goto tooshort; + goto tooshort; bp += ND_RPL_DAOACK_MIN_LEN; length -= ND_RPL_DAOACK_MIN_LEN; @@ -954,7 +954,7 @@ rpl_daoack_print(netdissect_options *ndo, return; trunc: - ND_PRINT(" [|dao-truncated]"); + nd_print_trunc(ndo); return; tooshort: @@ -1013,7 +1013,7 @@ rpl_print(netdissect_options *ndo, #if 0 trunc: - ND_PRINT(" [|truncated]"); + nd_print_trunc(ndo); return; #endif @@ -1033,11 +1033,17 @@ icmp6_print(netdissect_options *ndo, const u_char *ep; u_int prot; + ndo->ndo_protocol = "icmp6"; dp = (const struct icmp6_hdr *)bp; ip = (const struct ip6_hdr *)bp2; oip = (const struct ip6_hdr *)(dp + 1); /* 'ep' points to the end of available data. */ ep = ndo->ndo_snapend; + if (length == 0) { + ND_PRINT("ICMP6, length 0"); + nd_print_invalid(ndo); + return; + } if (ndo->ndo_vflag && !fragmented) { uint16_t sum, udp_sum; @@ -1159,8 +1165,9 @@ icmp6_print(netdissect_options *ndo, break; case ICMP6_ECHO_REQUEST: case ICMP6_ECHO_REPLY: + /* The check below covers both icmp6_id and icmp6_seq. */ ND_TCHECK_2(dp->icmp6_seq); - ND_PRINT(", seq %u", EXTRACT_BE_U_2(dp->icmp6_seq)); + ND_PRINT(", id %u, seq %u", EXTRACT_BE_U_2(dp->icmp6_id), EXTRACT_BE_U_2(dp->icmp6_seq)); break; case ICMP6_MEMBERSHIP_QUERY: if (length == MLD_MINLEN) { @@ -1181,8 +1188,9 @@ icmp6_print(netdissect_options *ndo, case ND_ROUTER_SOLICIT: #define RTSOLLEN 8 if (ndo->ndo_vflag) { - icmp6_opt_print(ndo, (const u_char *)dp + RTSOLLEN, - length - RTSOLLEN); + if (icmp6_opt_print(ndo, (const u_char *)dp + RTSOLLEN, + length - RTSOLLEN) == -1) + goto trunc; } break; case ND_ROUTER_ADVERT: @@ -1193,7 +1201,7 @@ icmp6_print(netdissect_options *ndo, p = (const struct nd_router_advert *)dp; ND_TCHECK_4(p->nd_ra_retransmit); ND_PRINT("\n\thop limit %u, Flags [%s]" - ", pref %s, router lifetime %us, reachable time %us, retrans time %us", + ", pref %s, router lifetime %us, reachable time %ums, retrans timer %ums", EXTRACT_U_1(p->nd_ra_curhoplimit), bittok2str(icmp6_opt_ra_flag_values,"none",EXTRACT_U_1(p->nd_ra_flags_reserved)), get_rtpref(EXTRACT_U_1(p->nd_ra_flags_reserved)), @@ -1201,8 +1209,9 @@ icmp6_print(netdissect_options *ndo, EXTRACT_BE_U_4(p->nd_ra_reachable), EXTRACT_BE_U_4(p->nd_ra_retransmit)); - icmp6_opt_print(ndo, (const u_char *)dp + RTADVLEN, - length - RTADVLEN); + if (icmp6_opt_print(ndo, (const u_char *)dp + RTADVLEN, + length - RTADVLEN) == -1) + goto trunc; } break; case ND_NEIGHBOR_SOLICIT: @@ -1213,8 +1222,9 @@ icmp6_print(netdissect_options *ndo, ND_PRINT(", who has %s", ip6addr_string(ndo, p->nd_ns_target)); if (ndo->ndo_vflag) { #define NDSOLLEN 24 - icmp6_opt_print(ndo, (const u_char *)dp + NDSOLLEN, - length - NDSOLLEN); + if (icmp6_opt_print(ndo, (const u_char *)dp + NDSOLLEN, + length - NDSOLLEN) == -1) + goto trunc; } } break; @@ -1232,8 +1242,9 @@ icmp6_print(netdissect_options *ndo, "none", EXTRACT_BE_U_4(p->nd_na_flags_reserved))); #define NDADVLEN 24 - icmp6_opt_print(ndo, (const u_char *)dp + NDADVLEN, - length - NDADVLEN); + if (icmp6_opt_print(ndo, (const u_char *)dp + NDADVLEN, + length - NDADVLEN) == -1) + goto trunc; #undef NDADVLEN } } @@ -1249,8 +1260,9 @@ icmp6_print(netdissect_options *ndo, ND_PRINT(" to %s", ip6addr_string(ndo, p->nd_rd_target)); #define REDIRECTLEN 40 if (ndo->ndo_vflag) { - icmp6_opt_print(ndo, (const u_char *)dp + REDIRECTLEN, - length - REDIRECTLEN); + if (icmp6_opt_print(ndo, (const u_char *)dp + REDIRECTLEN, + length - REDIRECTLEN) == -1) + goto trunc; #undef REDIRECTLEN } } @@ -1304,8 +1316,9 @@ icmp6_print(netdissect_options *ndo, if (flags & 0x4000) ND_PRINT("O"); #define MPADVLEN 8 - icmp6_opt_print(ndo, (const u_char *)dp + MPADVLEN, - length - MPADVLEN); + if (icmp6_opt_print(ndo, (const u_char *)dp + MPADVLEN, + length - MPADVLEN) == -1) + goto trunc; } break; case ND_RPL_MESSAGE: @@ -1322,7 +1335,7 @@ icmp6_print(netdissect_options *ndo, ND_PRINT(", length %u", length); return; trunc: - ND_PRINT("[|icmp6]"); + nd_print_trunc(ndo); } static const struct udphdr * @@ -1399,7 +1412,7 @@ get_upperlayer(netdissect_options *ndo, const u_char *bp, u_int *prot) return(NULL); /* should be notreached, though */ } -static void +static int icmp6_opt_print(netdissect_options *ndo, const u_char *bp, int resid) { const struct nd_opt_hdr *op; @@ -1416,8 +1429,6 @@ icmp6_opt_print(netdissect_options *ndo, const u_char *bp, int resid) size_t l; u_int i; -#define ECHECK(var) if ((const u_char *)&(var) > ep - sizeof(var)) return - cp = bp; /* 'ep' points to the end of available data. */ ep = ndo->ndo_snapend; @@ -1425,9 +1436,9 @@ icmp6_opt_print(netdissect_options *ndo, const u_char *bp, int resid) while (cp < ep) { op = (const struct nd_opt_hdr *)cp; - ECHECK(op->nd_opt_len); + ND_TCHECK_1(op->nd_opt_len); if (resid <= 0) - return; + return 0; opt_type = EXTRACT_U_1(op->nd_opt_type); opt_len = EXTRACT_U_1(op->nd_opt_len); if (opt_len == 0) @@ -1491,7 +1502,7 @@ icmp6_opt_print(netdissect_options *ndo, const u_char *bp, int resid) while (domp < cp + (opt_len << 3) && EXTRACT_U_1(domp) != '\0') { ND_PRINT(" "); - if ((domp = ns_nprint (ndo, domp, bp)) == NULL) + if ((domp = ns_nprint(ndo, domp, bp)) == NULL) goto trunc; } break; @@ -1534,7 +1545,7 @@ icmp6_opt_print(netdissect_options *ndo, const u_char *bp, int resid) default: if (ndo->ndo_vflag <= 1) { print_unknown_data(ndo,cp+2,"\n\t ", (opt_len << 3) - 2); /* skip option header */ - return; + return 0; } break; } @@ -1545,12 +1556,10 @@ icmp6_opt_print(netdissect_options *ndo, const u_char *bp, int resid) cp += opt_len << 3; resid -= opt_len << 3; } - return; + return 0; - trunc: - ND_PRINT("[ndp opt]"); - return; -#undef ECHECK +trunc: + return -1; } static void @@ -1623,7 +1632,7 @@ mldv2_report_print(netdissect_options *ndo, const u_char *bp, u_int len) } return; trunc: - ND_PRINT("[|icmp6]"); + nd_print_trunc(ndo); return; } @@ -1690,7 +1699,7 @@ mldv2_query_print(netdissect_options *ndo, const u_char *bp, u_int len) ND_PRINT("]"); return; trunc: - ND_PRINT("[|icmp6]"); + nd_print_trunc(ndo); return; } @@ -1710,7 +1719,7 @@ dnsname_print(netdissect_options *ndo, const u_char *cp, const u_char *ep) break; } while (i-- && cp < ep) { - safeputchar(ndo, EXTRACT_U_1(cp)); + fn_print_char(ndo, EXTRACT_U_1(cp)); cp++; } if (cp + 1 < ep && EXTRACT_U_1(cp)) @@ -1831,7 +1840,7 @@ icmp6_nodeinfo_print(netdissect_options *ndo, u_int icmp6len, const u_char *bp, cp++; ND_PRINT(", \""); while (cp < ep) { - safeputchar(ndo, EXTRACT_U_1(cp)); + fn_print_char(ndo, EXTRACT_U_1(cp)); cp++; } ND_PRINT("\""); @@ -1859,10 +1868,8 @@ icmp6_nodeinfo_print(netdissect_options *ndo, u_int icmp6len, const u_char *bp, break; case ICMP6_NI_REPLY: - if (icmp6len > siz) { - ND_PRINT("[|icmp6: node information reply]"); - break; - } + if (icmp6len > siz) + goto trunc; needcomma = 0; @@ -1929,7 +1936,7 @@ icmp6_nodeinfo_print(netdissect_options *ndo, u_int icmp6len, const u_char *bp, cp++; ND_PRINT(", \""); while (cp < ep) { - safeputchar(ndo, EXTRACT_U_1(cp)); + fn_print_char(ndo, EXTRACT_U_1(cp)); cp++; } ND_PRINT("\""); @@ -1977,7 +1984,7 @@ icmp6_nodeinfo_print(netdissect_options *ndo, u_int icmp6len, const u_char *bp, return; trunc: - ND_PRINT("[|icmp6]"); + nd_print_trunc(ndo); } static void @@ -2113,12 +2120,5 @@ icmp6_rrenum_print(netdissect_options *ndo, const u_char *bp, const u_char *ep) return; trunc: - ND_PRINT("[|icmp6]"); + nd_print_trunc(ndo); } - -/* - * Local Variables: - * c-style: whitesmith - * c-basic-offset: 8 - * End: - */