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() */
15 #include "dissector_eth.h"
19 #define ROUTING_HEADER_TYPE_0 0x00
22 uint8_t h_next_header
;
23 uint8_t h_hdr_ext_len
;
24 uint8_t h_routing_type
;
25 uint8_t h_segments_left
;
30 uint32_t addresses
[0];
33 static void dissect_routinghdr_type_0(struct pkt_buff
*pkt
,
34 ssize_t
*data_len
, int less
)
37 char address
[INET6_ADDRSTRLEN
];
38 struct in6_addr
*addr
;
39 struct routinghdr_0
*routing_0
;
41 routing_0
= (struct routinghdr_0
*) pkt_pull(pkt
, sizeof(*routing_0
));
42 *data_len
-= sizeof(*routing_0
);
43 if (routing_0
== NULL
|| *data_len
> pkt_len(pkt
) || *data_len
< 0)
47 tprintf("Addresses (%zu)", *data_len
/ sizeof(struct in6_addr
));
51 tprintf("Res (0x%x)", routing_0
->reserved
);
53 num_addr
= *data_len
/ sizeof(*addr
);
56 addr
= (struct in6_addr
*) pkt_pull(pkt
, sizeof(*addr
));
57 *data_len
-= sizeof(*addr
);
58 if (addr
== NULL
|| *data_len
> pkt_len(pkt
) || *data_len
< 0)
61 tprintf("\n\t Address: %s",
62 inet_ntop(AF_INET6
, addr
, address
,
67 static inline void dissect_routinghdr_type_0_norm(struct pkt_buff
*pkt
,
70 dissect_routinghdr_type_0(pkt
, data_len
, 0);
73 static inline void dissect_routinghdr_type_0_less(struct pkt_buff
*pkt
,
76 dissect_routinghdr_type_0(pkt
, data_len
, 1);
79 static void routing(struct pkt_buff
*pkt
)
83 struct routinghdr
*routing
;
85 routing
= (struct routinghdr
*) pkt_pull(pkt
, sizeof(*routing
));
89 /* Total Header Length in Bytes */
90 hdr_ext_len
= (routing
->h_hdr_ext_len
+ 1) * 8;
91 /* Data length in Bytes */
92 data_len
= hdr_ext_len
- sizeof(*routing
);
94 tprintf("\t [ Routing ");
95 tprintf("NextHdr (%u), ", routing
->h_next_header
);
96 if (data_len
> pkt_len(pkt
) || data_len
< 0){
97 tprintf("HdrExtLen (%u, %u Bytes %s), ", routing
->h_hdr_ext_len
,
98 hdr_ext_len
, colorize_start_full(black
, red
)
99 "invalid" colorize_end());
102 tprintf("HdrExtLen (%u, %u Bytes), ", routing
->h_hdr_ext_len
,
104 tprintf("Type (%u), ", routing
->h_routing_type
);
105 tprintf("Left (%u), ", routing
->h_segments_left
);
107 switch (routing
->h_routing_type
) {
108 case ROUTING_HEADER_TYPE_0
:
109 dissect_routinghdr_type_0_norm(pkt
, &data_len
);
112 tprintf("Type %u is unknown", routing
->h_routing_type
);
117 if (data_len
> pkt_len(pkt
) || data_len
< 0)
120 pkt_pull(pkt
, data_len
);
121 pkt_set_dissector(pkt
, ð_lay3
, routing
->h_next_header
);
124 static void routing_less(struct pkt_buff
*pkt
)
126 uint16_t hdr_ext_len
;
128 struct routinghdr
*routing
;
130 routing
= (struct routinghdr
*) pkt_pull(pkt
, sizeof(*routing
));
134 /* Total Header Length in Bytes */
135 hdr_ext_len
= (routing
->h_hdr_ext_len
+ 1) * 8;
136 /* Data length in Bytes */
137 data_len
= hdr_ext_len
- sizeof(*routing
);
138 if (data_len
> pkt_len(pkt
) || data_len
< 0)
141 tprintf(" Routing ");
143 switch (routing
->h_routing_type
) {
144 case ROUTING_HEADER_TYPE_0
:
145 dissect_routinghdr_type_0_less(pkt
, &data_len
);
148 tprintf("Type %u is unknown", routing
->h_routing_type
);
151 if (data_len
> pkt_len(pkt
) || data_len
< 0)
154 pkt_pull(pkt
, data_len
);
155 pkt_set_dissector(pkt
, ð_lay3
, routing
->h_next_header
);
158 struct protocol ipv6_routing_ops
= {
160 .print_full
= routing
,
161 .print_less
= routing_less
,