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 22 #ifndef lint 23 static const char rcsid[] _U_ = 24 "@(#) $Header: /tcpdump/master/tcpdump/print-ip6.c,v 1.47.2.5 2007/09/21 07:07:52 hannes Exp $"; 25 #endif 26 27 #ifdef HAVE_CONFIG_H 28 #include "config.h" 29 #endif 30 31 #ifdef INET6 32 33 #include <tcpdump-stdinc.h> 34 35 #include <stdio.h> 36 #include <stdlib.h> 37 #include <string.h> 38 39 #include "interface.h" 40 #include "addrtoname.h" 41 #include "extract.h" 42 43 #include "ip6.h" 44 #include "ipproto.h" 45 46 /* 47 * print an IP6 datagram. 48 */ 49 void 50 ip6_print(register const u_char *bp, register u_int length) 51 { 52 register const struct ip6_hdr *ip6; 53 register int advance; 54 u_int len; 55 const u_char *ipend; 56 register const u_char *cp; 57 register u_int payload_len; 58 int nh; 59 int fragmented = 0; 60 u_int flow; 61 62 ip6 = (const struct ip6_hdr *)bp; 63 64 TCHECK(*ip6); 65 if (length < sizeof (struct ip6_hdr)) { 66 (void)printf("truncated-ip6 %u", length); 67 return; 68 } 69 70 if (!eflag) 71 printf("IP6 "); 72 73 payload_len = EXTRACT_16BITS(&ip6->ip6_plen); 74 len = payload_len + sizeof(struct ip6_hdr); 75 if (length < len) 76 (void)printf("truncated-ip6 - %u bytes missing!", 77 len - length); 78 79 if (vflag) { 80 flow = EXTRACT_32BITS(&ip6->ip6_flow); 81 printf("("); 82 #if 0 83 /* rfc1883 */ 84 if (flow & 0x0f000000) 85 (void)printf("pri 0x%02x, ", (flow & 0x0f000000) >> 24); 86 if (flow & 0x00ffffff) 87 (void)printf("flowlabel 0x%06x, ", flow & 0x00ffffff); 88 #else 89 /* RFC 2460 */ 90 if (flow & 0x0ff00000) 91 (void)printf("class 0x%02x, ", (flow & 0x0ff00000) >> 20); 92 if (flow & 0x000fffff) 93 (void)printf("flowlabel 0x%05x, ", flow & 0x000fffff); 94 #endif 95 96 (void)printf("hlim %u, next-header %s (%u) payload length: %u) ", 97 ip6->ip6_hlim, 98 tok2str(ipproto_values,"unknown",ip6->ip6_nxt), 99 ip6->ip6_nxt, 100 payload_len); 101 } 102 103 /* 104 * Cut off the snapshot length to the end of the IP payload. 105 */ 106 ipend = bp + len; 107 if (ipend < snapend) 108 snapend = ipend; 109 110 cp = (const u_char *)ip6; 111 advance = sizeof(struct ip6_hdr); 112 nh = ip6->ip6_nxt; 113 while (cp < snapend && advance > 0) { 114 cp += advance; 115 len -= advance; 116 117 if (cp == (const u_char *)(ip6 + 1) && 118 nh != IPPROTO_TCP && nh != IPPROTO_UDP && 119 nh != IPPROTO_DCCP && nh != IPPROTO_SCTP) { 120 (void)printf("%s > %s: ", ip6addr_string(&ip6->ip6_src), 121 ip6addr_string(&ip6->ip6_dst)); 122 } 123 124 switch (nh) { 125 case IPPROTO_HOPOPTS: 126 advance = hbhopt_print(cp); 127 nh = *cp; 128 break; 129 case IPPROTO_DSTOPTS: 130 advance = dstopt_print(cp); 131 nh = *cp; 132 break; 133 case IPPROTO_FRAGMENT: 134 advance = frag6_print(cp, (const u_char *)ip6); 135 if (snapend <= cp + advance) 136 return; 137 nh = *cp; 138 fragmented = 1; 139 break; 140 141 case IPPROTO_MOBILITY_OLD: 142 case IPPROTO_MOBILITY: 143 /* 144 * XXX - we don't use "advance"; the current 145 * "Mobility Support in IPv6" draft 146 * (draft-ietf-mobileip-ipv6-24) says that 147 * the next header field in a mobility header 148 * should be IPPROTO_NONE, but speaks of 149 * the possiblity of a future extension in 150 * which payload can be piggybacked atop a 151 * mobility header. 152 */ 153 advance = mobility_print(cp, (const u_char *)ip6); 154 nh = *cp; 155 return; 156 case IPPROTO_ROUTING: 157 advance = rt6_print(cp, (const u_char *)ip6); 158 nh = *cp; 159 break; 160 case IPPROTO_SCTP: 161 sctp_print(cp, (const u_char *)ip6, len); 162 return; 163 case IPPROTO_DCCP: 164 dccp_print(cp, (const u_char *)ip6, len); 165 return; 166 case IPPROTO_TCP: 167 tcp_print(cp, len, (const u_char *)ip6, fragmented); 168 return; 169 case IPPROTO_UDP: 170 udp_print(cp, len, (const u_char *)ip6, fragmented); 171 return; 172 case IPPROTO_ICMPV6: 173 icmp6_print(cp, len, (const u_char *)ip6, fragmented); 174 return; 175 case IPPROTO_AH: 176 advance = ah_print(cp); 177 nh = *cp; 178 break; 179 case IPPROTO_ESP: 180 { 181 int enh, padlen; 182 advance = esp_print(gndo, cp, len, (const u_char *)ip6, &enh, &padlen); 183 nh = enh & 0xff; 184 len -= padlen; 185 break; 186 } 187 case IPPROTO_IPCOMP: 188 { 189 int enh; 190 advance = ipcomp_print(cp, &enh); 191 nh = enh & 0xff; 192 break; 193 } 194 195 case IPPROTO_PIM: 196 pim_print(cp, len); 197 return; 198 199 case IPPROTO_OSPF: 200 ospf6_print(cp, len); 201 return; 202 203 case IPPROTO_IPV6: 204 ip6_print(cp, len); 205 return; 206 207 case IPPROTO_IPV4: 208 ip_print(gndo, cp, len); 209 return; 210 211 case IPPROTO_PGM: 212 pgm_print(cp, len, (const u_char *)ip6); 213 return; 214 215 case IPPROTO_GRE: 216 gre_print(cp, len); 217 return; 218 219 case IPPROTO_RSVP: 220 rsvp_print(cp, len); 221 return; 222 223 case IPPROTO_NONE: 224 (void)printf("no next header"); 225 return; 226 227 default: 228 (void)printf("ip-proto-%d %d", nh, len); 229 return; 230 } 231 } 232 233 return; 234 trunc: 235 (void)printf("[|ip6]"); 236 } 237 238 #endif /* INET6 */ 239