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 size_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
))
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
))
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
);
93 if (routing
== NULL
|| data_len
> pkt_len(pkt
))
96 tprintf("\t [ Routing ");
97 tprintf("NextHdr (%u), ", routing
->h_next_header
);
98 tprintf("HdrExtLen (%u, %u Bytes), ", routing
->h_hdr_ext_len
,
100 tprintf("Type (%u), ", routing
->h_routing_type
);
101 tprintf("Left (%u), ", routing
->h_segments_left
);
103 switch (routing
->h_routing_type
) {
104 case ROUTING_HEADER_TYPE_0
:
105 dissect_routinghdr_type_0_norm(pkt
, &data_len
);
108 tprintf("Type %u is unknown", routing
->h_routing_type
);
113 pkt_pull(pkt
, data_len
);
114 pkt_set_proto(pkt
, ð_lay3
, routing
->h_next_header
);
117 static inline void routing_less(struct pkt_buff
*pkt
)
121 struct routinghdr
*routing
;
123 routing
= (struct routinghdr
*) pkt_pull(pkt
, sizeof(*routing
));
125 /* Total Header Length in Bytes */
126 hdr_ext_len
= (routing
->h_hdr_ext_len
+ 1) * 8;
127 /* Data length in Bytes */
128 data_len
= hdr_ext_len
- sizeof(*routing
);
129 if (routing
== NULL
|| data_len
> pkt_len(pkt
))
132 tprintf(" Routing ");
134 switch (routing
->h_routing_type
) {
135 case ROUTING_HEADER_TYPE_0
:
136 dissect_routinghdr_type_0_less(pkt
, &data_len
);
139 tprintf("Type %u is unknown", routing
->h_routing_type
);
142 pkt_pull(pkt
, data_len
);
143 pkt_set_proto(pkt
, ð_lay3
, routing
->h_next_header
);
146 struct protocol ipv6_routing_ops
= {
148 .print_full
= routing
,
149 .print_less
= routing_less
,
152 #endif /* PROTO_IPV6_ROUTING_H */