xref: /aosp_15_r20/external/tcpdump/print-rt6.c (revision 05b00f6010a2396e3db2409989fc67270046269f)
1*05b00f60SXin Li /*
2*05b00f60SXin Li  * Copyright (c) 1988, 1989, 1990, 1991, 1993, 1994
3*05b00f60SXin Li  *	The Regents of the University of California.  All rights reserved.
4*05b00f60SXin Li  *
5*05b00f60SXin Li  * Redistribution and use in source and binary forms, with or without
6*05b00f60SXin Li  * modification, are permitted provided that: (1) source code distributions
7*05b00f60SXin Li  * retain the above copyright notice and this paragraph in its entirety, (2)
8*05b00f60SXin Li  * distributions including binary code include the above copyright notice and
9*05b00f60SXin Li  * this paragraph in its entirety in the documentation or other materials
10*05b00f60SXin Li  * provided with the distribution, and (3) all advertising materials mentioning
11*05b00f60SXin Li  * features or use of this software display the following acknowledgement:
12*05b00f60SXin Li  * ``This product includes software developed by the University of California,
13*05b00f60SXin Li  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14*05b00f60SXin Li  * the University nor the names of its contributors may be used to endorse
15*05b00f60SXin Li  * or promote products derived from this software without specific prior
16*05b00f60SXin Li  * written permission.
17*05b00f60SXin Li  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18*05b00f60SXin Li  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19*05b00f60SXin Li  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20*05b00f60SXin Li  */
21*05b00f60SXin Li 
22*05b00f60SXin Li /* \summary: IPv6 routing header printer */
23*05b00f60SXin Li 
24*05b00f60SXin Li #ifdef HAVE_CONFIG_H
25*05b00f60SXin Li #include <config.h>
26*05b00f60SXin Li #endif
27*05b00f60SXin Li 
28*05b00f60SXin Li #include "netdissect-stdinc.h"
29*05b00f60SXin Li 
30*05b00f60SXin Li #include "netdissect.h"
31*05b00f60SXin Li #include "addrtoname.h"
32*05b00f60SXin Li #include "extract.h"
33*05b00f60SXin Li 
34*05b00f60SXin Li #include "ip6.h"
35*05b00f60SXin Li 
36*05b00f60SXin Li int
rt6_print(netdissect_options * ndo,const u_char * bp,const u_char * bp2 _U_)37*05b00f60SXin Li rt6_print(netdissect_options *ndo, const u_char *bp, const u_char *bp2 _U_)
38*05b00f60SXin Li {
39*05b00f60SXin Li 	const struct ip6_rthdr *dp;
40*05b00f60SXin Li 	const struct ip6_rthdr0 *dp0;
41*05b00f60SXin Li 	const struct ip6_srh *srh;
42*05b00f60SXin Li 	u_int i, len, type;
43*05b00f60SXin Li 	const u_char *p;
44*05b00f60SXin Li 
45*05b00f60SXin Li 	ndo->ndo_protocol = "rt6";
46*05b00f60SXin Li 
47*05b00f60SXin Li 	nd_print_protocol_caps(ndo);
48*05b00f60SXin Li 	dp = (const struct ip6_rthdr *)bp;
49*05b00f60SXin Li 
50*05b00f60SXin Li 	len = GET_U_1(dp->ip6r_len);
51*05b00f60SXin Li 	ND_PRINT(" (len=%u", len);	/*)*/
52*05b00f60SXin Li 	type = GET_U_1(dp->ip6r_type);
53*05b00f60SXin Li 	ND_PRINT(", type=%u", type);
54*05b00f60SXin Li 	if (type == IPV6_RTHDR_TYPE_0)
55*05b00f60SXin Li 		ND_PRINT(" [Deprecated]");
56*05b00f60SXin Li 	ND_PRINT(", segleft=%u", GET_U_1(dp->ip6r_segleft));
57*05b00f60SXin Li 
58*05b00f60SXin Li 	switch (type) {
59*05b00f60SXin Li 	case IPV6_RTHDR_TYPE_0:
60*05b00f60SXin Li 	case IPV6_RTHDR_TYPE_2:			/* Mobile IPv6 ID-20 */
61*05b00f60SXin Li 		dp0 = (const struct ip6_rthdr0 *)dp;
62*05b00f60SXin Li 
63*05b00f60SXin Li 		if (GET_BE_U_4(dp0->ip6r0_reserved) || ndo->ndo_vflag) {
64*05b00f60SXin Li 			ND_PRINT(", rsv=0x%0x",
65*05b00f60SXin Li 			    GET_BE_U_4(dp0->ip6r0_reserved));
66*05b00f60SXin Li 		}
67*05b00f60SXin Li 
68*05b00f60SXin Li 		if (len % 2 == 1) {
69*05b00f60SXin Li 			ND_PRINT(" (invalid length %u)", len);
70*05b00f60SXin Li 			goto invalid;
71*05b00f60SXin Li 		}
72*05b00f60SXin Li 		len >>= 1;
73*05b00f60SXin Li 		p = (const u_char *) dp0->ip6r0_addr;
74*05b00f60SXin Li 		for (i = 0; i < len; i++) {
75*05b00f60SXin Li 			ND_PRINT(", [%u]%s", i, GET_IP6ADDR_STRING(p));
76*05b00f60SXin Li 			p += 16;
77*05b00f60SXin Li 		}
78*05b00f60SXin Li 		/*(*/
79*05b00f60SXin Li 		ND_PRINT(") ");
80*05b00f60SXin Li 		return((GET_U_1(dp0->ip6r0_len) + 1) << 3);
81*05b00f60SXin Li 		break;
82*05b00f60SXin Li 	case IPV6_RTHDR_TYPE_4:
83*05b00f60SXin Li 		srh = (const struct ip6_srh *)dp;
84*05b00f60SXin Li 		ND_PRINT(", last-entry=%u", GET_U_1(srh->srh_last_ent));
85*05b00f60SXin Li 
86*05b00f60SXin Li 		if (GET_U_1(srh->srh_flags) || ndo->ndo_vflag) {
87*05b00f60SXin Li 			ND_PRINT(", flags=0x%0x",
88*05b00f60SXin Li 				GET_U_1(srh->srh_flags));
89*05b00f60SXin Li 		}
90*05b00f60SXin Li 
91*05b00f60SXin Li 		ND_PRINT(", tag=%x", GET_BE_U_2(srh->srh_tag));
92*05b00f60SXin Li 
93*05b00f60SXin Li 		if (len % 2 == 1) {
94*05b00f60SXin Li 			ND_PRINT(" (invalid length %u)", len);
95*05b00f60SXin Li 			goto invalid;
96*05b00f60SXin Li 		}
97*05b00f60SXin Li 		len >>= 1;
98*05b00f60SXin Li 		p  = (const u_char *) srh->srh_segments;
99*05b00f60SXin Li 		for (i = 0; i < len; i++) {
100*05b00f60SXin Li 			ND_PRINT(", [%u]%s", i, GET_IP6ADDR_STRING(p));
101*05b00f60SXin Li 			p += 16;
102*05b00f60SXin Li 		}
103*05b00f60SXin Li 		/*(*/
104*05b00f60SXin Li 		ND_PRINT(") ");
105*05b00f60SXin Li 		return((GET_U_1(srh->srh_len) + 1) << 3);
106*05b00f60SXin Li 		break;
107*05b00f60SXin Li 	default:
108*05b00f60SXin Li 		ND_PRINT(" (unknown type)");
109*05b00f60SXin Li 		goto invalid;
110*05b00f60SXin Li 	}
111*05b00f60SXin Li 
112*05b00f60SXin Li invalid:
113*05b00f60SXin Li 	nd_print_invalid(ndo);
114*05b00f60SXin Li 	return -1;
115*05b00f60SXin Li }
116