proto_ipv6_routing.h: Add a comment
[netsniff-ng.git] / src / proto_ipv6_routing.h
blobc5b8f3542995cbc5305858822f92d997137a0ffb
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 #ifndef FNTTYPE_PRINT_NORM
22 #define FNTTYPE_PRINT_NORM 0
23 #endif
24 #ifndef FNTTYPE_PRINT_LESS
25 #define FNTTYPE_PRINT_LESS 1
26 #endif
28 #define ROUTING_HEADER_TYPE_0 0x00
30 struct routinghdr {
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;
35 } __packed;
37 struct routinghdr_0 {
38 uint32_t reserved;
39 uint32_t addresses[0];
40 } __packed;
43 static inline void dissect_routinghdr_type_0(struct pkt_buff *pkt,
44 uint8_t *data_len, int less)
46 uint8_t num_addr;
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))
54 return;
56 if (less) {
57 tprintf("Addresses (%u)", *data_len / sizeof(struct in6_addr));
58 return;
61 tprintf("Res (0x%x)", routing_0->reserved);
63 num_addr = *data_len / sizeof(*addr);
65 while (num_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))
69 return;
71 tprintf("\n\t Address: %s",
72 inet_ntop(AF_INET6, addr, address,
73 sizeof(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))
89 return;
91 tprintf("\t [ Routing ");
92 tprintf("NextHdr (%u), ", routing->h_next_header);
93 tprintf("HdrExtLen (%u, %u Bytes), ", routing->h_hdr_ext_len,
94 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);
101 break;
102 default:
103 tprintf("Type %u is unknown", routing->h_routing_type);
106 tprintf(" ]\n");
108 pkt_pull(pkt, data_len);
109 pkt_set_proto(pkt, &eth_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))
124 return;
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);
131 break;
132 default:
133 tprintf("Type %u is unknown", routing->h_routing_type);
136 pkt_pull(pkt, data_len);
137 pkt_set_proto(pkt, &eth_lay3, routing->h_next_header);
140 struct protocol ipv6_routing_ops = {
141 .key = 0x2B,
142 .print_full = routing,
143 .print_less = routing_less,
146 #endif /* PROTO_IPV6_ROUTING_H */