ring_tx: user_may_pull_from_tx: fix check for user frame
[netsniff-ng.git] / proto_ipv6_hop_by_hop.c
blobb0c5a0d4fb5197c377d0faef50f0361586182c75
1 /*
2 * netsniff-ng - the packet sniffing beast
3 * Copyright 2012 Markus Amend <markus@netsniff-ng.org>, Deutsche Flugsicherung GmbH
4 * Subject to the GPL, version 2.
6 * IPv6 Hop-By-Hop Header described in RFC2460
7 */
9 #include <stdio.h>
10 #include <stdint.h>
11 #include <netinet/in.h> /* for ntohs() */
13 #include "proto.h"
14 #include "protos.h"
15 #include "dissector_eth.h"
16 #include "built_in.h"
17 #include "pkt_buff.h"
19 struct hop_by_hophdr {
20 uint8_t h_next_header;
21 uint8_t hdr_len;
22 } __packed;
24 static void dissect_opt_hop (struct pkt_buff *pkt, ssize_t *opt_len)
26 /* Have to been upgraded.
27 * http://tools.ietf.org/html/rfc2460#section-4.2
28 * Look also for proto_ipv6_dest_opts.h, it needs
29 * dissect_opt(), too.
31 if (*opt_len)
32 tprintf(", Option(s) recognized ");
34 /* If adding dissector reduce opt_len for each using of pkt_pull
35 * to the same size.
39 static void hop_by_hop(struct pkt_buff *pkt)
41 uint16_t hdr_ext_len;
42 ssize_t opt_len;
43 struct hop_by_hophdr *hop_ops;
45 hop_ops = (struct hop_by_hophdr *) pkt_pull(pkt, sizeof(*hop_ops));
46 if (hop_ops == NULL)
47 return;
49 /* Total Header Length in Bytes */
50 hdr_ext_len = (hop_ops->hdr_len + 1) * 8;
51 /* Options length in Bytes */
52 opt_len = hdr_ext_len - sizeof(*hop_ops);
54 tprintf("\t [ Hop-by-Hop Options ");
55 tprintf("NextHdr (%u), ", hop_ops->h_next_header);
56 if (opt_len > pkt_len(pkt) || opt_len < 0){
57 tprintf("HdrExtLen (%u, %u Bytes, %s)", hop_ops->hdr_len,
58 hdr_ext_len, colorize_start_full(black, red)
59 "invalid" colorize_end());
60 return;
62 tprintf("HdrExtLen (%u, %u Bytes)", hop_ops->hdr_len,
63 hdr_ext_len);
65 dissect_opt_hop(pkt, &opt_len);
67 tprintf(" ]\n");
69 pkt_pull(pkt, opt_len);
70 pkt_set_proto(pkt, &eth_lay3, hop_ops->h_next_header);
73 static void hop_by_hop_less(struct pkt_buff *pkt)
75 uint16_t hdr_ext_len;
76 ssize_t opt_len;
77 struct hop_by_hophdr *hop_ops;
79 hop_ops = (struct hop_by_hophdr *) pkt_pull(pkt, sizeof(*hop_ops));
80 if (hop_ops == NULL)
81 return;
83 /* Total Header Length in Bytes */
84 hdr_ext_len = (hop_ops->hdr_len + 1) * 8;
85 /* Options length in Bytes */
86 opt_len = hdr_ext_len - sizeof(*hop_ops);
87 if (opt_len > pkt_len(pkt) || opt_len < 0)
88 return;
90 tprintf(" Hop Ops");
92 pkt_pull(pkt, opt_len);
93 pkt_set_proto(pkt, &eth_lay3, hop_ops->h_next_header);
96 struct protocol ipv6_hop_by_hop_ops = {
97 .key = 0x0,
98 .print_full = hop_by_hop,
99 .print_less = hop_by_hop_less,