2 * netsniff-ng - the packet sniffing beast
3 * Copyright 2012 Markus Amend <markus@netsniff-ng.org>, Deutsche Flugsicherung GmbH
4 * Subject to the GPL, version 2.
6 * IPv6 Routing Header described in RFC2460
11 #include <netinet/in.h> /* for ntohs() and "struct in6_addr" */
12 #include <arpa/inet.h> /* for inet_ntop() */
16 #include "dissector_eth.h"
20 #define ROUTING_HEADER_TYPE_0 0x00
23 uint8_t h_next_header
;
24 uint8_t h_hdr_ext_len
;
25 uint8_t h_routing_type
;
26 uint8_t h_segments_left
;
31 uint32_t addresses
[0];
34 static void dissect_routinghdr_type_0(struct pkt_buff
*pkt
,
35 ssize_t
*data_len
, int less
)
38 char address
[INET6_ADDRSTRLEN
];
39 struct in6_addr
*addr
;
40 struct routinghdr_0
*routing_0
;
42 routing_0
= (struct routinghdr_0
*) pkt_pull(pkt
, sizeof(*routing_0
));
43 *data_len
-= sizeof(*routing_0
);
44 if (routing_0
== NULL
|| *data_len
> pkt_len(pkt
) || *data_len
< 0)
48 tprintf("Addresses (%lu)", *data_len
/ sizeof(struct in6_addr
));
52 tprintf("Res (0x%x)", routing_0
->reserved
);
54 num_addr
= *data_len
/ sizeof(*addr
);
57 addr
= (struct in6_addr
*) pkt_pull(pkt
, sizeof(*addr
));
58 *data_len
-= sizeof(*addr
);
59 if (addr
== NULL
|| *data_len
> pkt_len(pkt
) || *data_len
< 0)
62 tprintf("\n\t Address: %s",
63 inet_ntop(AF_INET6
, addr
, address
,
68 static inline void dissect_routinghdr_type_0_norm(struct pkt_buff
*pkt
,
71 dissect_routinghdr_type_0(pkt
, data_len
, 0);
74 static inline void dissect_routinghdr_type_0_less(struct pkt_buff
*pkt
,
77 dissect_routinghdr_type_0(pkt
, data_len
, 1);
80 static void routing(struct pkt_buff
*pkt
)
84 struct routinghdr
*routing
;
86 routing
= (struct routinghdr
*) pkt_pull(pkt
, sizeof(*routing
));
90 /* Total Header Length in Bytes */
91 hdr_ext_len
= (routing
->h_hdr_ext_len
+ 1) * 8;
92 /* Data length in Bytes */
93 data_len
= hdr_ext_len
- sizeof(*routing
);
95 tprintf("\t [ Routing ");
96 tprintf("NextHdr (%u), ", routing
->h_next_header
);
97 if (data_len
> pkt_len(pkt
) || data_len
< 0){
98 tprintf("HdrExtLen (%u, %u Bytes %s), ", routing
->h_hdr_ext_len
,
99 hdr_ext_len
, colorize_start_full(black
, red
)
100 "invalid" colorize_end());
103 tprintf("HdrExtLen (%u, %u Bytes), ", routing
->h_hdr_ext_len
,
105 tprintf("Type (%u), ", routing
->h_routing_type
);
106 tprintf("Left (%u), ", routing
->h_segments_left
);
108 switch (routing
->h_routing_type
) {
109 case ROUTING_HEADER_TYPE_0
:
110 dissect_routinghdr_type_0_norm(pkt
, &data_len
);
113 tprintf("Type %u is unknown", routing
->h_routing_type
);
118 if (data_len
> pkt_len(pkt
) || data_len
< 0)
121 pkt_pull(pkt
, data_len
);
122 pkt_set_proto(pkt
, ð_lay3
, routing
->h_next_header
);
125 static void routing_less(struct pkt_buff
*pkt
)
127 uint16_t hdr_ext_len
;
129 struct routinghdr
*routing
;
131 routing
= (struct routinghdr
*) pkt_pull(pkt
, sizeof(*routing
));
135 /* Total Header Length in Bytes */
136 hdr_ext_len
= (routing
->h_hdr_ext_len
+ 1) * 8;
137 /* Data length in Bytes */
138 data_len
= hdr_ext_len
- sizeof(*routing
);
139 if (data_len
> pkt_len(pkt
) || data_len
< 0)
142 tprintf(" Routing ");
144 switch (routing
->h_routing_type
) {
145 case ROUTING_HEADER_TYPE_0
:
146 dissect_routinghdr_type_0_less(pkt
, &data_len
);
149 tprintf("Type %u is unknown", routing
->h_routing_type
);
152 if (data_len
> pkt_len(pkt
) || data_len
< 0)
155 pkt_pull(pkt
, data_len
);
156 pkt_set_proto(pkt
, ð_lay3
, routing
->h_next_header
);
159 struct protocol ipv6_routing_ops
= {
161 .print_full
= routing
,
162 .print_less
= routing_less
,
165 EXPORT_SYMBOL(ipv6_routing_ops
);