trafgen: remove pointer fiddling, improve code
[netsniff-ng-old.git] / src / proto_ipv6_routing.h
blobadd75f7beb9cb8dab71a040f7aa30adaebe04702
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 uint16_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 uint16_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 uint16_t *data_len)
78 dissect_routinghdr_type_0(pkt, data_len, 1);
81 static inline void routing(struct pkt_buff *pkt)
83 uint16_t hdr_ext_len, data_len;
84 struct routinghdr *routing;
86 routing = (struct routinghdr *) pkt_pull(pkt, sizeof(*routing));
88 /* Total Header Length in Bytes */
89 hdr_ext_len = (routing->h_hdr_ext_len + 1) * 8;
90 /* Data length in Bytes */
91 data_len = hdr_ext_len - sizeof(*routing);
92 if (routing == NULL || data_len > pkt_len(pkt))
93 return;
95 tprintf("\t [ Routing ");
96 tprintf("NextHdr (%u), ", routing->h_next_header);
97 tprintf("HdrExtLen (%u, %u Bytes), ", routing->h_hdr_ext_len,
98 hdr_ext_len);
99 tprintf("Type (%u), ", routing->h_routing_type);
100 tprintf("Left (%u), ", routing->h_segments_left);
102 switch (routing->h_routing_type) {
103 case ROUTING_HEADER_TYPE_0:
104 dissect_routinghdr_type_0_norm(pkt, &data_len);
105 break;
106 default:
107 tprintf("Type %u is unknown", routing->h_routing_type);
110 tprintf(" ]\n");
112 pkt_pull(pkt, data_len);
113 pkt_set_proto(pkt, &eth_lay3, routing->h_next_header);
116 static inline void routing_less(struct pkt_buff *pkt)
118 uint16_t hdr_ext_len, data_len;
119 struct routinghdr *routing;
121 routing = (struct routinghdr *) pkt_pull(pkt, sizeof(*routing));
123 /* Total Header Length in Bytes */
124 hdr_ext_len = (routing->h_hdr_ext_len + 1) * 8;
125 /* Data length in Bytes */
126 data_len = hdr_ext_len - sizeof(*routing);
127 if (routing == NULL || data_len > pkt_len(pkt))
128 return;
130 tprintf(" Routing ");
132 switch (routing->h_routing_type) {
133 case ROUTING_HEADER_TYPE_0:
134 dissect_routinghdr_type_0_less(pkt, &data_len);
135 break;
136 default:
137 tprintf("Type %u is unknown", routing->h_routing_type);
140 pkt_pull(pkt, data_len);
141 pkt_set_proto(pkt, &eth_lay3, routing->h_next_header);
144 struct protocol ipv6_routing_ops = {
145 .key = 0x2B,
146 .print_full = routing,
147 .print_less = routing_less,
150 #endif /* PROTO_IPV6_ROUTING_H */