156893Sfenner/* 256893Sfenner * Copyright (C) 1998 WIDE Project. 356893Sfenner * All rights reserved. 4127668Sbms * 556893Sfenner * Redistribution and use in source and binary forms, with or without 656893Sfenner * modification, are permitted provided that the following conditions 756893Sfenner * are met: 856893Sfenner * 1. Redistributions of source code must retain the above copyright 956893Sfenner * notice, this list of conditions and the following disclaimer. 1056893Sfenner * 2. Redistributions in binary form must reproduce the above copyright 1156893Sfenner * notice, this list of conditions and the following disclaimer in the 1256893Sfenner * documentation and/or other materials provided with the distribution. 1356893Sfenner * 3. Neither the name of the project nor the names of its contributors 1456893Sfenner * may be used to endorse or promote products derived from this software 1556893Sfenner * without specific prior written permission. 16127668Sbms * 1756893Sfenner * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 1856893Sfenner * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1956893Sfenner * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2056893Sfenner * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 2156893Sfenner * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2256893Sfenner * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2356893Sfenner * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2456893Sfenner * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2556893Sfenner * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2656893Sfenner * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2756893Sfenner * SUCH DAMAGE. 2856893Sfenner */ 2956893Sfenner 30276788Sdelphij#define NETDISSECT_REWORKED 3156893Sfenner#ifdef HAVE_CONFIG_H 3256893Sfenner#include "config.h" 3356893Sfenner#endif 3456893Sfenner 3556893Sfenner#ifdef INET6 36127668Sbms#include <tcpdump-stdinc.h> 3756893Sfenner 3875115Sfenner#include "ip6.h" 3975115Sfenner 4056893Sfenner#include "interface.h" 4156893Sfenner#include "addrtoname.h" 42127668Sbms#include "extract.h" 4356893Sfenner 4475115Sfennerstatic void 45276788Sdelphijip6_sopt_print(netdissect_options *ndo, const u_char *bp, int len) 4675115Sfenner{ 4775115Sfenner int i; 4875115Sfenner int optlen; 4975115Sfenner 5075115Sfenner for (i = 0; i < len; i += optlen) { 5198524Sfenner if (bp[i] == IP6OPT_PAD1) 5298524Sfenner optlen = 1; 5398524Sfenner else { 5498524Sfenner if (i + 1 < len) 5598524Sfenner optlen = bp[i + 1] + 2; 5698524Sfenner else 5798524Sfenner goto trunc; 5898524Sfenner } 5998524Sfenner if (i + optlen > len) 6098524Sfenner goto trunc; 6198524Sfenner 6275115Sfenner switch (bp[i]) { 6375115Sfenner case IP6OPT_PAD1: 64276788Sdelphij ND_PRINT((ndo, ", pad1")); 6575115Sfenner break; 6675115Sfenner case IP6OPT_PADN: 6775115Sfenner if (len - i < IP6OPT_MINLEN) { 68276788Sdelphij ND_PRINT((ndo, ", padn: trunc")); 6975115Sfenner goto trunc; 7075115Sfenner } 71276788Sdelphij ND_PRINT((ndo, ", padn")); 7275115Sfenner break; 7375115Sfenner default: 7475115Sfenner if (len - i < IP6OPT_MINLEN) { 75276788Sdelphij ND_PRINT((ndo, ", sopt_type %d: trunc)", bp[i])); 7675115Sfenner goto trunc; 7775115Sfenner } 78276788Sdelphij ND_PRINT((ndo, ", sopt_type 0x%02x: len=%d", bp[i], bp[i + 1])); 7975115Sfenner break; 8075115Sfenner } 8175115Sfenner } 8275115Sfenner return; 8375115Sfenner 8475115Sfennertrunc: 85276788Sdelphij ND_PRINT((ndo, "[trunc] ")); 8675115Sfenner} 8775115Sfenner 88276788Sdelphijstatic void 89276788Sdelphijip6_opt_print(netdissect_options *ndo, const u_char *bp, int len) 9056893Sfenner{ 9156893Sfenner int i; 92127668Sbms int optlen = 0; 9356893Sfenner 94241235Sdelphij if (len == 0) 95241235Sdelphij return; 9656893Sfenner for (i = 0; i < len; i += optlen) { 9798524Sfenner if (bp[i] == IP6OPT_PAD1) 9898524Sfenner optlen = 1; 9998524Sfenner else { 10098524Sfenner if (i + 1 < len) 10198524Sfenner optlen = bp[i + 1] + 2; 10298524Sfenner else 10398524Sfenner goto trunc; 10498524Sfenner } 10598524Sfenner if (i + optlen > len) 10698524Sfenner goto trunc; 10798524Sfenner 10856893Sfenner switch (bp[i]) { 10956893Sfenner case IP6OPT_PAD1: 110276788Sdelphij ND_PRINT((ndo, "(pad1)")); 11156893Sfenner break; 11256893Sfenner case IP6OPT_PADN: 11356893Sfenner if (len - i < IP6OPT_MINLEN) { 114276788Sdelphij ND_PRINT((ndo, "(padn: trunc)")); 11556893Sfenner goto trunc; 11656893Sfenner } 117276788Sdelphij ND_PRINT((ndo, "(padn)")); 11856893Sfenner break; 11975115Sfenner case IP6OPT_ROUTER_ALERT: 12056893Sfenner if (len - i < IP6OPT_RTALERT_LEN) { 121276788Sdelphij ND_PRINT((ndo, "(rtalert: trunc)")); 12256893Sfenner goto trunc; 12356893Sfenner } 12456893Sfenner if (bp[i + 1] != IP6OPT_RTALERT_LEN - 2) { 125276788Sdelphij ND_PRINT((ndo, "(rtalert: invalid len %d)", bp[i + 1])); 12656893Sfenner goto trunc; 12756893Sfenner } 128276788Sdelphij ND_PRINT((ndo, "(rtalert: 0x%04x) ", EXTRACT_16BITS(&bp[i + 2]))); 12956893Sfenner break; 13056893Sfenner case IP6OPT_JUMBO: 13156893Sfenner if (len - i < IP6OPT_JUMBO_LEN) { 132276788Sdelphij ND_PRINT((ndo, "(jumbo: trunc)")); 13356893Sfenner goto trunc; 13456893Sfenner } 13556893Sfenner if (bp[i + 1] != IP6OPT_JUMBO_LEN - 2) { 136276788Sdelphij ND_PRINT((ndo, "(jumbo: invalid len %d)", bp[i + 1])); 13756893Sfenner goto trunc; 13856893Sfenner } 139276788Sdelphij ND_PRINT((ndo, "(jumbo: %u) ", EXTRACT_32BITS(&bp[i + 2]))); 14056893Sfenner break; 14175115Sfenner case IP6OPT_HOME_ADDRESS: 14275115Sfenner if (len - i < IP6OPT_HOMEADDR_MINLEN) { 143276788Sdelphij ND_PRINT((ndo, "(homeaddr: trunc)")); 14475115Sfenner goto trunc; 14575115Sfenner } 14675115Sfenner if (bp[i + 1] < IP6OPT_HOMEADDR_MINLEN - 2) { 147276788Sdelphij ND_PRINT((ndo, "(homeaddr: invalid len %d)", bp[i + 1])); 14875115Sfenner goto trunc; 14975115Sfenner } 150276788Sdelphij ND_PRINT((ndo, "(homeaddr: %s", ip6addr_string(ndo, &bp[i + 2]))); 15175115Sfenner if (bp[i + 1] > IP6OPT_HOMEADDR_MINLEN - 2) { 152276788Sdelphij ip6_sopt_print(ndo, &bp[i + IP6OPT_HOMEADDR_MINLEN], 15398524Sfenner (optlen - IP6OPT_HOMEADDR_MINLEN)); 15475115Sfenner } 155276788Sdelphij ND_PRINT((ndo, ")")); 15675115Sfenner break; 15756893Sfenner default: 15856893Sfenner if (len - i < IP6OPT_MINLEN) { 159276788Sdelphij ND_PRINT((ndo, "(type %d: trunc)", bp[i])); 16056893Sfenner goto trunc; 16156893Sfenner } 162276788Sdelphij ND_PRINT((ndo, "(opt_type 0x%02x: len=%d)", bp[i], bp[i + 1])); 16356893Sfenner break; 16456893Sfenner } 16556893Sfenner } 166276788Sdelphij ND_PRINT((ndo, " ")); 16756893Sfenner return; 16856893Sfenner 16956893Sfennertrunc: 170276788Sdelphij ND_PRINT((ndo, "[trunc] ")); 17156893Sfenner} 17256893Sfenner 17356893Sfennerint 174276788Sdelphijhbhopt_print(netdissect_options *ndo, register const u_char *bp) 17556893Sfenner{ 17656893Sfenner const struct ip6_hbh *dp = (struct ip6_hbh *)bp; 17756893Sfenner int hbhlen = 0; 17856893Sfenner 179276788Sdelphij ND_TCHECK(dp->ip6h_len); 18056893Sfenner hbhlen = (int)((dp->ip6h_len + 1) << 3); 181276788Sdelphij ND_TCHECK2(*dp, hbhlen); 182276788Sdelphij ND_PRINT((ndo, "HBH ")); 183276788Sdelphij if (ndo->ndo_vflag) 184276788Sdelphij ip6_opt_print(ndo, (const u_char *)dp + sizeof(*dp), hbhlen - sizeof(*dp)); 18556893Sfenner 18656893Sfenner return(hbhlen); 18756893Sfenner 18856893Sfenner trunc: 189276788Sdelphij ND_PRINT((ndo, "[|HBH]")); 190127668Sbms return(-1); 19156893Sfenner} 19256893Sfenner 19356893Sfennerint 194276788Sdelphijdstopt_print(netdissect_options *ndo, register const u_char *bp) 19556893Sfenner{ 19656893Sfenner const struct ip6_dest *dp = (struct ip6_dest *)bp; 19756893Sfenner int dstoptlen = 0; 19856893Sfenner 199276788Sdelphij ND_TCHECK(dp->ip6d_len); 20056893Sfenner dstoptlen = (int)((dp->ip6d_len + 1) << 3); 201276788Sdelphij ND_TCHECK2(*dp, dstoptlen); 202276788Sdelphij ND_PRINT((ndo, "DSTOPT ")); 203276788Sdelphij if (ndo->ndo_vflag) { 204276788Sdelphij ip6_opt_print(ndo, (const u_char *)dp + sizeof(*dp), 20556893Sfenner dstoptlen - sizeof(*dp)); 20656893Sfenner } 20756893Sfenner 20856893Sfenner return(dstoptlen); 20956893Sfenner 21056893Sfenner trunc: 211276788Sdelphij ND_PRINT((ndo, "[|DSTOPT]")); 212127668Sbms return(-1); 21356893Sfenner} 21456893Sfenner#endif /* INET6 */ 215