2 * netsniff-ng - the packet sniffing beast
3 * Copyright 2012 Markus Amend <markus@netsniff-ng.org>
4 * Subject to the GPL, version 2.
6 * IPv6 Routing Header described in RFC2460
9 #ifndef PROTO_IPV6_ROUTING_H
10 #define PROTO_IPV6_ROUTING_H
14 #include <netinet/in.h> /* for ntohs() and "struct in6_addr" */
15 #include <arpa/inet.h> /* for inet_ntop() */
17 #include "proto_struct.h"
18 #include "dissector_eth.h"
21 #define ROUTING_HEADER_TYPE_0 0x00
24 uint8_t h_next_header
;
25 uint8_t h_hdr_ext_len
;
26 uint8_t h_routing_type
;
27 uint8_t h_segments_left
;
32 uint32_t addresses
[0];
35 static inline void dissect_routinghdr_type_0(struct pkt_buff
*pkt
,
36 ssize_t
*data_len
, int less
)
39 char address
[INET6_ADDRSTRLEN
];
40 struct in6_addr
*addr
;
41 struct routinghdr_0
*routing_0
;
43 routing_0
= (struct routinghdr_0
*) pkt_pull(pkt
, sizeof(*routing_0
));
44 *data_len
-= sizeof(*routing_0
);
45 if (routing_0
== NULL
|| *data_len
> pkt_len(pkt
) || *data_len
< 0)
49 tprintf("Addresses (%u)", *data_len
/ sizeof(struct in6_addr
));
53 tprintf("Res (0x%x)", routing_0
->reserved
);
55 num_addr
= *data_len
/ sizeof(*addr
);
58 addr
= (struct in6_addr
*) pkt_pull(pkt
, sizeof(*addr
));
59 *data_len
-= sizeof(*addr
);
60 if (addr
== NULL
|| *data_len
> pkt_len(pkt
) || *data_len
< 0)
63 tprintf("\n\t Address: %s",
64 inet_ntop(AF_INET6
, addr
, address
,
69 static inline void dissect_routinghdr_type_0_norm(struct pkt_buff
*pkt
,
72 dissect_routinghdr_type_0(pkt
, data_len
, 0);
75 static inline void dissect_routinghdr_type_0_less(struct pkt_buff
*pkt
,
78 dissect_routinghdr_type_0(pkt
, data_len
, 1);
81 static inline void routing(struct pkt_buff
*pkt
)
85 struct routinghdr
*routing
;
87 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
);
96 tprintf("\t [ Routing ");
97 tprintf("NextHdr (%u), ", routing
->h_next_header
);
98 if (data_len
> pkt_len(pkt
) || data_len
< 0){
99 tprintf("HdrExtLen (%u, %u Bytes %s), ", routing
->h_hdr_ext_len
,
100 hdr_ext_len
, colorize_start_full(black
, red
)
101 "invalid" colorize_end());
104 tprintf("HdrExtLen (%u, %u Bytes), ", routing
->h_hdr_ext_len
,
106 tprintf("Type (%u), ", routing
->h_routing_type
);
107 tprintf("Left (%u), ", routing
->h_segments_left
);
109 switch (routing
->h_routing_type
) {
110 case ROUTING_HEADER_TYPE_0
:
111 dissect_routinghdr_type_0_norm(pkt
, &data_len
);
114 tprintf("Type %u is unknown", routing
->h_routing_type
);
119 if (data_len
> pkt_len(pkt
) || data_len
< 0)
122 pkt_pull(pkt
, data_len
);
123 pkt_set_proto(pkt
, ð_lay3
, routing
->h_next_header
);
126 static inline void routing_less(struct pkt_buff
*pkt
)
128 uint16_t hdr_ext_len
;
130 struct routinghdr
*routing
;
132 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 (routing
== NULL
|| 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_proto(pkt
, ð_lay3
, routing
->h_next_header
);
158 struct protocol ipv6_routing_ops
= {
160 .print_full
= routing
,
161 .print_less
= routing_less
,
164 #endif /* PROTO_IPV6_ROUTING_H */