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