1 /* $OpenBSD: print-ip6.c,v 1.4 2003/01/27 10:00:40 henning Exp $ */ 2 3 /* 4 * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that: (1) source code distributions 9 * retain the above copyright notice and this paragraph in its entirety, (2) 10 * distributions including binary code include the above copyright notice and 11 * this paragraph in its entirety in the documentation or other materials 12 * provided with the distribution, and (3) all advertising materials mentioning 13 * features or use of this software display the following acknowledgement: 14 * ``This product includes software developed by the University of California, 15 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 16 * the University nor the names of its contributors may be used to endorse 17 * or promote products derived from this software without specific prior 18 * written permission. 19 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 20 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 22 */ 23 24 #ifndef lint 25 static const char rcsid[] = 26 "@(#) /master/usr.sbin/tcpdump/tcpdump/print-ip.c,v 2.1 1995/02/03 18:14:45 polk Exp (LBL)"; 27 #endif 28 29 #ifdef INET6 30 31 #include <sys/param.h> 32 #include <sys/time.h> 33 #include <sys/types.h> 34 #include <sys/socket.h> 35 36 #include <netinet/in.h> 37 #include <netinet/in_systm.h> 38 #include <netinet/ip.h> 39 #include <netinet/ip_var.h> 40 #include <netinet/udp.h> 41 #include <netinet/udp_var.h> 42 #include <netinet/tcp.h> 43 44 #include <stdio.h> 45 #include <stdlib.h> 46 #include <unistd.h> 47 48 #include "interface.h" 49 #include "addrtoname.h" 50 51 #include <netinet/ip6.h> 52 53 /* 54 * print an IP6 datagram. 55 */ 56 void 57 ip6_print(register const u_char *bp, register int length) 58 { 59 register const struct ip6_hdr *ip6; 60 register int hlen; 61 register int len; 62 register const u_char *cp; 63 int nh; 64 u_int flow; 65 66 ip6 = (const struct ip6_hdr *)bp; 67 68 #ifdef TCPDUMP_ALIGN 69 /* 70 * The IP header is not word aligned, so copy into abuf. 71 * This will never happen with BPF. It does happen with 72 * raw packet dumps from -r. 73 */ 74 if ((int)ip & (sizeof(long)-1)) { 75 static u_char *abuf; 76 77 if (abuf == NULL) 78 abuf = (u_char *)malloc(snaplen); 79 bcopy((char *)ip, (char *)abuf, min(length, snaplen)); 80 snapend += abuf - (u_char *)ip; 81 packetp = abuf; 82 ip = (struct ip6_hdr *)abuf; 83 } 84 #endif 85 if ((u_char *)(ip6 + 1) > snapend) { 86 printf("[|ip6]"); 87 return; 88 } 89 if (length < sizeof (struct ip6_hdr)) { 90 (void)printf("truncated-ip6 %d", length); 91 return; 92 } 93 hlen = sizeof(struct ip6_hdr); 94 95 len = ntohs(ip6->ip6_plen); 96 if (length < len + hlen) 97 (void)printf("truncated-ip6 - %d bytes missing!", 98 len + hlen - length); 99 100 cp = (const u_char *)ip6; 101 nh = ip6->ip6_nxt; 102 while (cp < snapend) { 103 cp += hlen; 104 105 if (cp == (u_char *)(ip6 + 1) 106 && nh != IPPROTO_TCP && nh != IPPROTO_UDP) { 107 (void)printf("%s > %s: ", ip6addr_string(&ip6->ip6_src), 108 ip6addr_string(&ip6->ip6_dst)); 109 } 110 111 switch (nh) { 112 case IPPROTO_HOPOPTS: 113 hlen = hbhopt_print(cp); 114 nh = *cp; 115 break; 116 case IPPROTO_DSTOPTS: 117 hlen = dstopt_print(cp); 118 nh = *cp; 119 break; 120 case IPPROTO_FRAGMENT: 121 hlen = frag6_print(cp, (const u_char *)ip6); 122 if (snapend <= cp + hlen) 123 goto end; 124 nh = *cp; 125 break; 126 case IPPROTO_ROUTING: 127 hlen = rt6_print(cp, (const u_char *)ip6); 128 nh = *cp; 129 break; 130 case IPPROTO_TCP: 131 tcp_print(cp, len + sizeof(struct ip6_hdr) - (cp - bp), 132 (const u_char *)ip6); 133 goto end; 134 case IPPROTO_UDP: 135 udp_print(cp, len + sizeof(struct ip6_hdr) - (cp - bp), 136 (const u_char *)ip6); 137 goto end; 138 case IPPROTO_ICMPV6: 139 icmp6_print(cp, (const u_char *)ip6); 140 goto end; 141 case IPPROTO_PIM: 142 (void)printf("PIM"); 143 pim_print(cp, len); 144 goto end; 145 #ifndef IPPROTO_OSPF 146 #define IPPROTO_OSPF 89 147 #endif 148 case IPPROTO_OSPF: 149 ospf6_print(cp, len); 150 goto end; 151 case IPPROTO_IPV6: 152 ip6_print(cp, len); 153 goto end; 154 #ifndef IPPROTO_IPV4 155 #define IPPROTO_IPV4 4 156 #endif 157 case IPPROTO_IPV4: 158 ip_print(cp, len); 159 goto end; 160 case IPPROTO_NONE: 161 (void)printf("no next header"); 162 goto end; 163 164 default: 165 (void)printf("ip-proto-%d %d", ip6->ip6_nxt, len); 166 goto end; 167 } 168 if (hlen == 0) 169 break; 170 } 171 172 end: 173 174 flow = ntohl(ip6->ip6_flow); 175 #if 0 176 /* rfc1883 */ 177 if (flow & 0x0f000000) 178 (void)printf(" [pri 0x%x]", (flow & 0x0f000000) >> 24); 179 if (flow & 0x00ffffff) 180 (void)printf(" [flowlabel 0x%x]", flow & 0x00ffffff); 181 #else 182 /* RFC 2460 */ 183 if (flow & 0x0ff00000) 184 (void)printf(" [class 0x%x]", (flow & 0x0ff00000) >> 20); 185 if (flow & 0x000fffff) 186 (void)printf(" [flowlabel 0x%x]", flow & 0x000fffff); 187 #endif 188 189 if (ip6->ip6_hlim <= 1) 190 (void)printf(" [hlim %d]", (int)ip6->ip6_hlim); 191 192 if (vflag) { 193 printf(" ("); 194 (void)printf("len %d", len); 195 if (ip6->ip6_hlim > 1) 196 (void)printf(", hlim %d", (int)ip6->ip6_hlim); 197 printf(")"); 198 } 199 } 200 201 #endif /* INET6 */ 202