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 --- 4 unchanged lines hidden (view full) --- 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: head/contrib/tcpdump/print-ip6.c 127675 2004-03-31 14:57:24Z bms $ |
22 */ 23 24#ifndef lint |
25static const char rcsid[] _U_ = 26 "@(#) $Header: /tcpdump/master/tcpdump/print-ip6.c,v 1.32.2.8 2003/11/24 20:31:22 guy 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 */ 51void 52ip6_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 %d", length); 69 return; 70 } |
71 |
72 payload_len = EXTRACT_16BITS(&ip6->ip6_plen); 73 len = payload_len + sizeof(struct ip6_hdr); 74 if (length < len) |
75 (void)printf("truncated-ip6 - %d bytes missing!", |
76 len - length); |
77 |
78 /* 79 * Cut off the snapshot length to the end of the IP payload. 80 */ 81 ipend = bp + len; 82 if (ipend < snapend) 83 snapend = ipend; 84 |
85 cp = (const u_char *)ip6; |
86 advance = sizeof(struct ip6_hdr); |
87 nh = ip6->ip6_nxt; |
88 while (cp < snapend && advance > 0) { |
89 cp += advance; |
90 len -= advance; |
91 |
92 if (cp == (const u_char *)(ip6 + 1) && 93 nh != IPPROTO_TCP && nh != IPPROTO_UDP && 94 nh != IPPROTO_SCTP) { |
95 (void)printf("%s > %s: ", ip6addr_string(&ip6->ip6_src), 96 ip6addr_string(&ip6->ip6_dst)); 97 } 98 99 switch (nh) { 100 case IPPROTO_HOPOPTS: 101 advance = hbhopt_print(cp); 102 nh = *cp; --- 4 unchanged lines hidden (view full) --- 107 break; 108 case IPPROTO_FRAGMENT: 109 advance = frag6_print(cp, (const u_char *)ip6); 110 if (snapend <= cp + advance) 111 goto end; 112 nh = *cp; 113 fragmented = 1; 114 break; |
115 116 case IPPROTO_MOBILITY_OLD: 117 case IPPROTO_MOBILITY: 118 /* 119 * XXX - we don't use "advance"; the current 120 * "Mobility Support in IPv6" draft 121 * (draft-ietf-mobileip-ipv6-24) says that 122 * the next header field in a mobility header 123 * should be IPPROTO_NONE, but speaks of 124 * the possiblity of a future extension in 125 * which payload can be piggybacked atop a 126 * mobility header. 127 */ 128 advance = mobility_print(cp, (const u_char *)ip6); 129 nh = *cp; 130 goto end; |
131 case IPPROTO_ROUTING: 132 advance = rt6_print(cp, (const u_char *)ip6); 133 nh = *cp; 134 break; |
135 case IPPROTO_SCTP: 136 sctp_print(cp, (const u_char *)ip6, len); 137 goto end; |
138 case IPPROTO_TCP: |
139 tcp_print(cp, len, (const u_char *)ip6, fragmented); |
140 goto end; 141 case IPPROTO_UDP: |
142 udp_print(cp, len, (const u_char *)ip6, fragmented); |
143 goto end; 144 case IPPROTO_ICMPV6: |
145 icmp6_print(cp, len, (const u_char *)ip6, fragmented); |
146 goto end; 147 case IPPROTO_AH: |
148 advance = ah_print(cp); |
149 nh = *cp; 150 break; 151 case IPPROTO_ESP: 152 { 153 int enh, padlen; 154 advance = esp_print(cp, (const u_char *)ip6, &enh, &padlen); |
155 nh = enh & 0xff; 156 len -= padlen; 157 break; 158 } |
159 case IPPROTO_IPCOMP: 160 { 161 int enh; |
162 advance = ipcomp_print(cp, &enh); |
163 nh = enh & 0xff; 164 break; 165 } 166 |
167 case IPPROTO_PIM: 168 pim_print(cp, len); 169 goto end; |
170 case IPPROTO_OSPF: 171 ospf6_print(cp, len); 172 goto end; |
173 |
174 case IPPROTO_IPV6: 175 ip6_print(cp, len); 176 goto end; |
177 |
178 case IPPROTO_IPV4: 179 ip_print(cp, len); 180 goto end; |
181 |
182 case IPPROTO_NONE: 183 (void)printf("no next header"); 184 goto end; 185 186 default: 187 (void)printf("ip-proto-%d %d", ip6->ip6_nxt, len); 188 goto end; 189 } 190 } 191 192 end: |
193 194 flow = EXTRACT_32BITS(&ip6->ip6_flow); |
195#if 0 196 /* rfc1883 */ 197 if (flow & 0x0f000000) 198 (void)printf(" [pri 0x%x]", (flow & 0x0f000000) >> 24); 199 if (flow & 0x00ffffff) 200 (void)printf(" [flowlabel 0x%x]", flow & 0x00ffffff); 201#else 202 /* RFC 2460 */ 203 if (flow & 0x0ff00000) 204 (void)printf(" [class 0x%x]", (flow & 0x0ff00000) >> 20); 205 if (flow & 0x000fffff) 206 (void)printf(" [flowlabel 0x%x]", flow & 0x000fffff); 207#endif 208 209 if (ip6->ip6_hlim <= 1) |
210 (void)printf(" [hlim %u]", ip6->ip6_hlim); |
211 212 if (vflag) { 213 printf(" ("); |
214 (void)printf("len %u", payload_len); |
215 if (ip6->ip6_hlim > 1) 216 (void)printf(", hlim %d", (int)ip6->ip6_hlim); 217 printf(")"); 218 } 219 return; 220trunc: 221 (void)printf("[|ip6]"); 222} 223 224#endif /* INET6 */ |