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 #ifndef FNTTYPE_PRINT_NORM
22 #define FNTTYPE_PRINT_NORM 0
24 #ifndef FNTTYPE_PRINT_LESS
25 #define FNTTYPE_PRINT_LESS 1
28 #define ROUTING_HEADER_TYPE_0 0x00
31 uint8_t h_next_header
;
32 uint8_t h_hdr_ext_len
;
33 uint8_t h_routing_type
;
34 uint8_t h_segments_left
;
39 uint32_t addresses
[0];
43 static inline void dissect_routinghdr_type_0(struct pkt_buff
*pkt
,
44 uint8_t *data_len
, int less
)
47 char address
[INET6_ADDRSTRLEN
];
48 struct in6_addr
*addr
;
49 struct routinghdr_0
*routing_0
;
51 routing_0
= (struct routinghdr_0
*) pkt_pull(pkt
, sizeof(*routing_0
));
52 *data_len
-= sizeof(*routing_0
);
53 if (routing_0
== NULL
|| *data_len
> pkt_len(pkt
))
57 tprintf("Addresses (%u)", *data_len
/ sizeof(struct in6_addr
));
61 tprintf("Res (0x%x)", routing_0
->reserved
);
63 num_addr
= *data_len
/ sizeof(*addr
);
66 addr
= (struct in6_addr
*) pkt_pull(pkt
, sizeof(*addr
));
67 *data_len
-= sizeof(*addr
);
68 if (addr
== NULL
|| *data_len
> pkt_len(pkt
))
71 tprintf("\n\t Address: %s",
72 inet_ntop(AF_INET6
, addr
, address
,
77 static inline void routing(struct pkt_buff
*pkt
)
79 uint8_t hdr_ext_len
, data_len
;
80 struct routinghdr
*routing
;
82 routing
= (struct routinghdr
*) pkt_pull(pkt
, sizeof(*routing
));
84 /* Total Header Length in Bytes */
85 hdr_ext_len
= (routing
->h_hdr_ext_len
+ 1) * 8;
86 /* Data length in Bytes */
87 data_len
= hdr_ext_len
- sizeof(*routing
);
88 if (routing
== NULL
|| data_len
> pkt_len(pkt
))
91 tprintf("\t [ Routing ");
92 tprintf("NextHdr (%u), ", routing
->h_next_header
);
93 tprintf("HdrExtLen (%u, %u Bytes), ", routing
->h_hdr_ext_len
,
95 tprintf("Type (%u), ", routing
->h_routing_type
);
96 tprintf("Left (%u), ", routing
->h_segments_left
);
98 switch (routing
->h_routing_type
) {
99 case ROUTING_HEADER_TYPE_0
:
100 dissect_routinghdr_type_0(pkt
, &data_len
, FNTTYPE_PRINT_NORM
);
103 tprintf("Type %u is unknown", routing
->h_routing_type
);
108 pkt_pull(pkt
, data_len
);
109 pkt_set_proto(pkt
, ð_lay3
, routing
->h_next_header
);
112 static inline void routing_less(struct pkt_buff
*pkt
)
114 uint8_t hdr_ext_len
, data_len
;
115 struct routinghdr
*routing
;
117 routing
= (struct routinghdr
*) pkt_pull(pkt
, sizeof(*routing
));
119 /* Total Header Length in Bytes */
120 hdr_ext_len
= (routing
->h_hdr_ext_len
+ 1) * 8;
121 /* Data length in Bytes */
122 data_len
= hdr_ext_len
- sizeof(*routing
);
123 if (routing
== NULL
|| data_len
> pkt_len(pkt
))
126 tprintf(" Routing ");
128 switch (routing
->h_routing_type
) {
129 case ROUTING_HEADER_TYPE_0
:
130 dissect_routinghdr_type_0(pkt
, &data_len
, FNTTYPE_PRINT_LESS
);
133 tprintf("Type %u is unknown", routing
->h_routing_type
);
136 pkt_pull(pkt
, data_len
);
137 pkt_set_proto(pkt
, ð_lay3
, routing
->h_next_header
);
140 struct protocol ipv6_routing_ops
= {
142 .print_full
= routing
,
143 .print_less
= routing_less
,
146 #endif /* PROTO_IPV6_ROUTING_H */