1 /* 2 * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that: (1) source code distributions 7 * retain the above copyright notice and this paragraph in its entirety, (2) 8 * distributions including binary code include the above copyright notice and 9 * this paragraph in its entirety in the documentation or other materials 10 * provided with the distribution, and (3) all advertising materials mentioning 11 * features or use of this software display the following acknowledgement: 12 * ``This product includes software developed by the University of California, 13 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 14 * the University nor the names of its contributors may be used to endorse 15 * or promote products derived from this software without specific prior 16 * written permission. 17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 20 * 21 * $FreeBSD$ 22 */ 23 24 #ifndef lint 25 static const char rcsid[] _U_ = 26 "@(#) $Header: /tcpdump/master/tcpdump/print-ip6.c,v 1.47.2.5 2007/09/21 07:07:52 hannes Exp $"; 27 #endif 28 29 #ifdef HAVE_CONFIG_H 30 #include "config.h" 31 #endif 32 33 #ifdef INET6 34 35 #include <tcpdump-stdinc.h> 36 37 #include <stdio.h> 38 #include <stdlib.h> 39 #include <string.h> 40 41 #include "interface.h" 42 #include "addrtoname.h" 43 #include "extract.h" 44 45 #include "ip6.h" 46 #include "ipproto.h" 47 48 /* 49 * print an IP6 datagram. 50 */ 51 void 52 ip6_print(register const u_char *bp, register u_int length) 53 { 54 register const struct ip6_hdr *ip6; 55 register int advance; 56 u_int len; 57 const u_char *ipend; 58 register const u_char *cp; 59 register u_int payload_len; 60 int nh; 61 int fragmented = 0; 62 u_int flow; 63 64 ip6 = (const struct ip6_hdr *)bp; 65 66 TCHECK(*ip6); 67 if (length < sizeof (struct ip6_hdr)) { 68 (void)printf("truncated-ip6 %u", length); 69 return; 70 } 71 72 if (!eflag) 73 printf("IP6 "); 74 75 payload_len = EXTRACT_16BITS(&ip6->ip6_plen); 76 len = payload_len + sizeof(struct ip6_hdr); 77 if (length < len) 78 (void)printf("truncated-ip6 - %u bytes missing!", 79 len - length); 80 81 if (vflag) { 82 flow = EXTRACT_32BITS(&ip6->ip6_flow); 83 printf("("); 84 #if 0 85 /* rfc1883 */ 86 if (flow & 0x0f000000) 87 (void)printf("pri 0x%02x, ", (flow & 0x0f000000) >> 24); 88 if (flow & 0x00ffffff) 89 (void)printf("flowlabel 0x%06x, ", flow & 0x00ffffff); 90 #else 91 /* RFC 2460 */ 92 if (flow & 0x0ff00000) 93 (void)printf("class 0x%02x, ", (flow & 0x0ff00000) >> 20); 94 if (flow & 0x000fffff) 95 (void)printf("flowlabel 0x%05x, ", flow & 0x000fffff); 96 #endif 97 98 (void)printf("hlim %u, next-header %s (%u) payload length: %u) ", 99 ip6->ip6_hlim, 100 tok2str(ipproto_values,"unknown",ip6->ip6_nxt), 101 ip6->ip6_nxt, 102 payload_len); 103 } 104 105 /* 106 * Cut off the snapshot length to the end of the IP payload. 107 */ 108 ipend = bp + len; 109 if (ipend < snapend) 110 snapend = ipend; 111 112 cp = (const u_char *)ip6; 113 advance = sizeof(struct ip6_hdr); 114 nh = ip6->ip6_nxt; 115 while (cp < snapend && advance > 0) { 116 cp += advance; 117 len -= advance; 118 119 if (cp == (const u_char *)(ip6 + 1) && 120 nh != IPPROTO_TCP && nh != IPPROTO_UDP && 121 nh != IPPROTO_DCCP && nh != IPPROTO_SCTP) { 122 (void)printf("%s > %s: ", ip6addr_string(&ip6->ip6_src), 123 ip6addr_string(&ip6->ip6_dst)); 124 } 125 126 switch (nh) { 127 case IPPROTO_HOPOPTS: 128 advance = hbhopt_print(cp); 129 nh = *cp; 130 break; 131 case IPPROTO_DSTOPTS: 132 advance = dstopt_print(cp); 133 nh = *cp; 134 break; 135 case IPPROTO_FRAGMENT: 136 advance = frag6_print(cp, (const u_char *)ip6); 137 if (snapend <= cp + advance) 138 return; 139 nh = *cp; 140 fragmented = 1; 141 break; 142 143 case IPPROTO_MOBILITY_OLD: 144 case IPPROTO_MOBILITY: 145 /* 146 * XXX - we don't use "advance"; the current 147 * "Mobility Support in IPv6" draft 148 * (draft-ietf-mobileip-ipv6-24) says that 149 * the next header field in a mobility header 150 * should be IPPROTO_NONE, but speaks of 151 * the possiblity of a future extension in 152 * which payload can be piggybacked atop a 153 * mobility header. 154 */ 155 advance = mobility_print(cp, (const u_char *)ip6); 156 nh = *cp; 157 return; 158 case IPPROTO_ROUTING: 159 advance = rt6_print(cp, (const u_char *)ip6); 160 nh = *cp; 161 break; 162 case IPPROTO_SCTP: 163 sctp_print(cp, (const u_char *)ip6, len); 164 return; 165 case IPPROTO_DCCP: 166 dccp_print(cp, (const u_char *)ip6, len); 167 return; 168 case IPPROTO_TCP: 169 tcp_print(cp, len, (const u_char *)ip6, fragmented); 170 return; 171 case IPPROTO_UDP: 172 udp_print(cp, len, (const u_char *)ip6, fragmented); 173 return; 174 case IPPROTO_ICMPV6: 175 icmp6_print(cp, len, (const u_char *)ip6, fragmented); 176 return; 177 case IPPROTO_AH: 178 advance = ah_print(cp); 179 nh = *cp; 180 break; 181 case IPPROTO_ESP: 182 { 183 int enh, padlen; 184 advance = esp_print(gndo, cp, len, (const u_char *)ip6, &enh, &padlen); 185 nh = enh & 0xff; 186 len -= padlen; 187 break; 188 } 189 case IPPROTO_IPCOMP: 190 { 191 int enh; 192 advance = ipcomp_print(cp, &enh); 193 nh = enh & 0xff; 194 break; 195 } 196 197 case IPPROTO_PIM: 198 pim_print(cp, len); 199 return; 200 201 case IPPROTO_OSPF: 202 ospf6_print(cp, len); 203 return; 204 205 case IPPROTO_IPV6: 206 ip6_print(cp, len); 207 return; 208 209 case IPPROTO_IPV4: 210 ip_print(gndo, cp, len); 211 return; 212 213 case IPPROTO_PGM: 214 pgm_print(cp, len, (const u_char *)ip6); 215 return; 216 217 case IPPROTO_GRE: 218 gre_print(cp, len); 219 return; 220 221 case IPPROTO_RSVP: 222 rsvp_print(cp, len); 223 return; 224 225 case IPPROTO_NONE: 226 (void)printf("no next header"); 227 return; 228 229 default: 230 (void)printf("ip-proto-%d %d", nh, len); 231 return; 232 } 233 } 234 235 return; 236 trunc: 237 (void)printf("[|ip6]"); 238 } 239 240 #endif /* INET6 */ 241