#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 */
#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 */
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 */
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);
}
return;
trunc:
- ND_PRINT(" [|truncated]");
+ nd_print_trunc(ndo);
return;
}
}
return;
trunc:
- ND_PRINT(" [|truncated]");
+ nd_print_trunc(ndo);
return;
}
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;
return;
trunc:
- ND_PRINT(" [|truncated]");
+ nd_print_trunc(ndo);
return;
tooshort:
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;
return;
trunc:
- ND_PRINT(" [|dao-truncated]");
+ nd_print_trunc(ndo);
return;
tooshort:
#if 0
trunc:
- ND_PRINT(" [|truncated]");
+ nd_print_trunc(ndo);
return;
#endif
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;
switch (icmp6_type) {
case ICMP6_DST_UNREACH:
- ND_TCHECK_16(&oip->ip6_dst);
+ ND_TCHECK_16(oip->ip6_dst);
ND_PRINT(", %s", tok2str(icmp6_dst_unreach_code_values,"unknown unreach code (%u)",icmp6_code));
switch (icmp6_code) {
case ICMP6_DST_UNREACH_NOROUTE: /* fall through */
case ICMP6_DST_UNREACH_ADMIN:
case ICMP6_DST_UNREACH_ADDR:
- ND_PRINT(" %s",ip6addr_string(ndo, &oip->ip6_dst));
+ ND_PRINT(" %s",ip6addr_string(ndo, oip->ip6_dst));
break;
case ICMP6_DST_UNREACH_BEYONDSCOPE:
ND_PRINT(" %s, source address %s",
- ip6addr_string(ndo, &oip->ip6_dst),
- ip6addr_string(ndo, &oip->ip6_src));
+ ip6addr_string(ndo, oip->ip6_dst),
+ ip6addr_string(ndo, oip->ip6_src));
break;
case ICMP6_DST_UNREACH_NOPORT:
if ((ouh = get_upperlayer(ndo, (const u_char *)oip, &prot))
switch (prot) {
case IPPROTO_TCP:
ND_PRINT(", %s tcp port %s",
- ip6addr_string(ndo, &oip->ip6_dst),
+ ip6addr_string(ndo, oip->ip6_dst),
tcpport_string(ndo, dport));
break;
case IPPROTO_UDP:
ND_PRINT(", %s udp port %s",
- ip6addr_string(ndo, &oip->ip6_dst),
+ ip6addr_string(ndo, oip->ip6_dst),
udpport_string(ndo, dport));
break;
default:
ND_PRINT(", %s protocol %u port %u unreachable",
- ip6addr_string(ndo, &oip->ip6_dst),
+ ip6addr_string(ndo, oip->ip6_dst),
prot, dport);
break;
}
ND_PRINT(", mtu %u", EXTRACT_BE_U_4(dp->icmp6_mtu));
break;
case ICMP6_TIME_EXCEEDED:
- ND_TCHECK_16(&oip->ip6_dst);
+ ND_TCHECK_16(oip->ip6_dst);
switch (icmp6_code) {
case ICMP6_TIME_EXCEED_TRANSIT:
ND_PRINT(" for %s",
- ip6addr_string(ndo, &oip->ip6_dst));
+ ip6addr_string(ndo, oip->ip6_dst));
break;
case ICMP6_TIME_EXCEED_REASSEMBLY:
ND_PRINT(" (reassembly)");
}
break;
case ICMP6_PARAM_PROB:
- ND_TCHECK_16(&oip->ip6_dst);
+ ND_TCHECK_16(oip->ip6_dst);
switch (icmp6_code) {
case ICMP6_PARAMPROB_HEADER:
ND_PRINT(", erroneous - octet %u", EXTRACT_BE_U_4(dp->icmp6_pptr));
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:
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)),
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:
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;
"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
}
}
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
}
}
break;
case ICMP6_HADISCOV_REPLY:
if (ndo->ndo_vflag) {
- const nd_ipv6 *in6;
const u_char *cp;
+ const u_char *p;
ND_TCHECK_2(dp->icmp6_data16[0]);
ND_PRINT(", id 0x%04x", EXTRACT_BE_U_2(dp->icmp6_data16[0]));
cp = (const u_char *)dp + length;
- in6 = (const nd_ipv6 *)(dp + 1);
- for (; (const u_char *)in6 < cp; in6++) {
- ND_TCHECK_SIZE(in6);
- ND_PRINT(", %s", ip6addr_string(ndo, in6));
+ p = (const u_char *)(dp + 1);
+ while (p < cp) {
+ ND_TCHECK_16(p);
+ ND_PRINT(", %s", ip6addr_string(ndo, p));
+ p += 16;
}
}
break;
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:
ND_PRINT(", length %u", length);
return;
trunc:
- ND_PRINT("[|icmp6]");
+ nd_print_trunc(ndo);
}
static const struct udphdr *
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;
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;
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)
break;
case ND_OPT_PREFIX_INFORMATION:
opp = (const struct nd_opt_prefix_info *)op;
- ND_TCHECK_16(&opp->nd_opt_pi_prefix);
+ ND_TCHECK_16(opp->nd_opt_pi_prefix);
ND_PRINT("%s/%u%s, Flags [%s], valid time %s",
- ip6addr_string(ndo, &opp->nd_opt_pi_prefix),
+ ip6addr_string(ndo, opp->nd_opt_pi_prefix),
EXTRACT_U_1(opp->nd_opt_pi_prefix_len),
(opt_len != 4) ? "badlen" : "",
bittok2str(icmp6_opt_pi_flag_values, "none", EXTRACT_U_1(opp->nd_opt_pi_flags_reserved)),
ND_PRINT(" lifetime %us,",
EXTRACT_BE_U_4(oprd->nd_opt_rdnss_lifetime));
for (i = 0; i < l; i++) {
- ND_TCHECK_16(&oprd->nd_opt_rdnss_addr[i]);
+ ND_TCHECK_16(oprd->nd_opt_rdnss_addr[i]);
ND_PRINT(" addr: %s",
- ip6addr_string(ndo, &oprd->nd_opt_rdnss_addr[i]));
+ ip6addr_string(ndo, oprd->nd_opt_rdnss_addr[i]));
}
break;
case ND_OPT_DNSSL:
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;
default:
goto trunc;
}
- ND_PRINT(" %s/%u", ip6addr_string(ndo, &in6),
+ ND_PRINT(" %s/%u", ip6addr_string(ndo, (const u_char *)&in6),
EXTRACT_U_1(opri->nd_opt_rti_prefixlen));
ND_PRINT(", pref=%s", get_rtpref(EXTRACT_U_1(opri->nd_opt_rti_flags)));
ND_PRINT(", lifetime=%s",
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;
}
cp += opt_len << 3;
resid -= opt_len << 3;
}
- return;
+ return 0;
- trunc:
- ND_PRINT("[ndp opt]");
- return;
-#undef ECHECK
+trunc:
+ return -1;
}
static void
}
return;
trunc:
- ND_PRINT("[|icmp6]");
+ nd_print_trunc(ndo);
return;
}
ND_PRINT("]");
return;
trunc:
- ND_PRINT("[|icmp6]");
+ nd_print_trunc(ndo);
return;
}
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))
break;
}
+ cp = (const u_char *)(ni6 + 1);
switch (EXTRACT_U_1(ni6->ni_code)) {
case ICMP6_NI_SUBJ_IPV6:
if (!ND_TTEST_LEN(dp, sizeof(*ni6) + sizeof(nd_ipv6)))
break;
}
ND_PRINT(", subject=%s",
- ip6addr_string(ndo, ni6 + 1));
+ ip6addr_string(ndo, cp));
break;
case ICMP6_NI_SUBJ_FQDN:
ND_PRINT(", subject=DNS name");
- cp = (const u_char *)(ni6 + 1);
if (EXTRACT_U_1(cp) == ep - cp - 1) {
/* icmp-name-lookup-03, pascal string */
if (ndo->ndo_vflag)
cp++;
ND_PRINT(", \"");
while (cp < ep) {
- safeputchar(ndo, EXTRACT_U_1(cp));
+ fn_print_char(ndo, EXTRACT_U_1(cp));
cp++;
}
ND_PRINT("\"");
break;
}
ND_PRINT(", subject=%s",
- ipaddr_string(ndo, ni6 + 1));
+ ipaddr_string(ndo, cp));
break;
default:
ND_PRINT(", unknown subject");
break;
case ICMP6_NI_REPLY:
- if (icmp6len > siz) {
- ND_PRINT("[|icmp6: node information reply]");
- break;
- }
+ if (icmp6len > siz)
+ goto trunc;
needcomma = 0;
cp++;
ND_PRINT(", \"");
while (cp < ep) {
- safeputchar(ndo, EXTRACT_U_1(cp));
+ fn_print_char(ndo, EXTRACT_U_1(cp));
cp++;
}
ND_PRINT("\"");
return;
trunc:
- ND_PRINT("[|icmp6]");
+ nd_print_trunc(ndo);
}
static void
ND_PRINT(",min=%u", EXTRACT_U_1(match->rpm_minlen));
ND_PRINT(",max=%u", EXTRACT_U_1(match->rpm_maxlen));
}
- if (addrtostr6(&match->rpm_prefix, hbuf, sizeof(hbuf)))
+ if (addrtostr6(match->rpm_prefix, hbuf, sizeof(hbuf)))
ND_PRINT(",%s/%u", hbuf, EXTRACT_U_1(match->rpm_matchlen));
else
ND_PRINT(",?/%u", EXTRACT_U_1(match->rpm_matchlen));
ND_PRINT("pltime=%u,",
EXTRACT_BE_U_4(use->rpu_pltime));
}
- if (addrtostr6(&use->rpu_prefix, hbuf, sizeof(hbuf)))
+ if (addrtostr6(use->rpu_prefix, hbuf, sizeof(hbuf)))
ND_PRINT("%s/%u/%u", hbuf, EXTRACT_U_1(use->rpu_uselen),
EXTRACT_U_1(use->rpu_keeplen));
else
return;
trunc:
- ND_PRINT("[|icmp6]");
+ nd_print_trunc(ndo);
}
-
-/*
- * Local Variables:
- * c-style: whitesmith
- * c-basic-offset: 8
- * End:
- */