dissector_80211: start of 80211 collection
[netsniff-ng.git] / src / proto_ipv6_dest_opts.h
blobc7562d3acaf21c23b73dfdbf1f7af4f653e539d4
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 Destination Options Header described in RFC2460
7 */
9 #ifndef PROTO_IPV6_DEST_OPTS_H
10 #define PROTO_IPV6_DEST_OPTS_H
12 #include <stdio.h>
13 #include <stdint.h>
14 #include <netinet/in.h> /* for ntohs() */
16 #include "proto_struct.h"
17 #include "dissector_eth.h"
18 #include "built_in.h"
20 struct dest_optshdr {
21 uint8_t h_next_header;
22 uint8_t hdr_len;
23 } __packed;
26 static inline void dissect_opt_dest(struct pkt_buff *pkt, ssize_t *opt_len)
28 /* Have to been upgraded.
29 * http://tools.ietf.org/html/rfc2460#section-4.2
30 * Look also for proto_ipv6_hop_by_hop.h, it needs
31 * dissect_opt(), too.
33 if (*opt_len)
34 tprintf(", Option(s) recognized ");
36 /* If adding dissector reduce opt_len for each using of pkt_pull
37 * to the same size.
41 static inline void dest_opts(struct pkt_buff *pkt)
43 uint16_t hdr_ext_len;
44 ssize_t opt_len;
45 struct dest_optshdr *dest_ops;
47 dest_ops = (struct dest_optshdr *) pkt_pull(pkt, sizeof(*dest_ops));
49 /* Total Header Length in Bytes */
50 hdr_ext_len = (dest_ops->hdr_len + 1) * 8;
51 /* Options length in Bytes */
52 opt_len = hdr_ext_len - sizeof(*dest_ops);
53 if (dest_ops == NULL)
54 return;
56 tprintf("\t [ Destination Options ");
57 tprintf("NextHdr (%u), ", dest_ops->h_next_header);
58 if (opt_len > pkt_len(pkt) || opt_len < 0) {
59 tprintf("HdrExtLen (%u, %u Bytes, %s)", dest_ops->hdr_len,
60 hdr_ext_len, colorize_start_full(black, red)
61 "invalid" colorize_end());
62 return;
64 tprintf("HdrExtLen (%u, %u Bytes)", dest_ops->hdr_len,
65 hdr_ext_len);
67 dissect_opt_dest(pkt, &opt_len);
69 tprintf(" ]\n");
71 pkt_pull(pkt, opt_len);
72 pkt_set_proto(pkt, &eth_lay3, dest_ops->h_next_header);
75 static inline void dest_opts_less(struct pkt_buff *pkt)
77 uint16_t hdr_ext_len;
78 ssize_t opt_len;
79 struct dest_optshdr *dest_ops;
81 dest_ops = (struct dest_optshdr *) pkt_pull(pkt, sizeof(*dest_ops));
83 /* Total Header Length in Bytes */
84 hdr_ext_len = (dest_ops->hdr_len + 1) * 8;
85 /* Options length in Bytes */
86 opt_len = hdr_ext_len - sizeof(*dest_ops);
87 if (dest_ops == NULL || opt_len > pkt_len(pkt) || opt_len < 0)
88 return;
90 tprintf(" Dest Ops");
92 pkt_pull(pkt, opt_len);
93 pkt_set_proto(pkt, &eth_lay3, dest_ops->h_next_header);
96 struct protocol ipv6_dest_opts_ops = {
97 .key = 0x3C,
98 .print_full = dest_opts,
99 .print_less = dest_opts_less,
102 #endif /* PROTO_IPV6_DEST_OPTS_H */