improving dissector_fuzz
[netsniff-ng.git] / src / proto_ipv6_routing.h
blobf8d0b56bcb2c325e3d7c70ad56ba3c3aea2d156e
1 /*
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
7 */
9 #ifndef PROTO_IPV6_ROUTING_H
10 #define PROTO_IPV6_ROUTING_H
12 #include <stdio.h>
13 #include <stdint.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"
19 #include "built_in.h"
21 #define ROUTING_HEADER_TYPE_0 0x00
23 struct routinghdr {
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;
28 } __packed;
30 struct routinghdr_0 {
31 uint32_t reserved;
32 uint32_t addresses[0];
33 } __packed;
35 static inline void dissect_routinghdr_type_0(struct pkt_buff *pkt,
36 size_t *data_len, int less)
38 uint8_t num_addr;
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))
46 return;
48 if (less) {
49 tprintf("Addresses (%u)", *data_len / sizeof(struct in6_addr));
50 return;
53 tprintf("Res (0x%x)", routing_0->reserved);
55 num_addr = *data_len / sizeof(*addr);
57 while (num_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))
61 return;
63 tprintf("\n\t Address: %s",
64 inet_ntop(AF_INET6, addr, address,
65 sizeof(address)));
69 static inline void dissect_routinghdr_type_0_norm(struct pkt_buff *pkt,
70 size_t *data_len)
72 dissect_routinghdr_type_0(pkt, data_len, 0);
75 static inline void dissect_routinghdr_type_0_less(struct pkt_buff *pkt,
76 size_t *data_len)
78 dissect_routinghdr_type_0(pkt, data_len, 1);
81 static inline void routing(struct pkt_buff *pkt)
83 uint8_t hdr_ext_len;
84 size_t data_len;
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))
94 return;
96 tprintf("\t [ Routing ");
97 tprintf("NextHdr (%u), ", routing->h_next_header);
98 tprintf("HdrExtLen (%u, %u Bytes), ", routing->h_hdr_ext_len,
99 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);
106 break;
107 default:
108 tprintf("Type %u is unknown", routing->h_routing_type);
111 tprintf(" ]\n");
113 pkt_pull(pkt, data_len);
114 pkt_set_proto(pkt, &eth_lay3, routing->h_next_header);
117 static inline void routing_less(struct pkt_buff *pkt)
119 uint8_t hdr_ext_len;
120 size_t data_len;
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))
130 return;
132 tprintf(" Routing ");
134 switch (routing->h_routing_type) {
135 case ROUTING_HEADER_TYPE_0:
136 dissect_routinghdr_type_0_less(pkt, &data_len);
137 break;
138 default:
139 tprintf("Type %u is unknown", routing->h_routing_type);
142 pkt_pull(pkt, data_len);
143 pkt_set_proto(pkt, &eth_lay3, routing->h_next_header);
146 struct protocol ipv6_routing_ops = {
147 .key = 0x2B,
148 .print_full = routing,
149 .print_less = routing_less,
152 #endif /* PROTO_IPV6_ROUTING_H */