2 * Copyright (c) 2003 Markus Friedl. All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #include <epan/packet.h>
32 #include <epan/etypes.h>
33 #include <epan/addr_resolv.h>
34 #include "packet-enc.h"
35 #include "packet-ip.h"
36 #include "packet-ipv6.h"
39 /* Can't trust stddef.h to be there for us */
40 # define offsetof(type, member) ((size_t)(&((type *)0)->member))
43 /* The header in OpenBSD Encapsulating Interface files. */
50 #define ENC_HDRLEN sizeof(struct enchdr)
52 # define BSD_ENC_INET 2
53 # define BSD_ENC_INET6 24
55 # define BSD_ENC_M_CONF 0x0400 /* payload encrypted */
56 # define BSD_ENC_M_AUTH 0x0800 /* payload authenticated */
57 # define BSD_ENC_M_COMP 0x1000 /* payload compressed */
58 # define BSD_ENC_M_AUTH_AH 0x2000 /* header authenticated */
60 static dissector_handle_t data_handle, ip_handle, ipv6_handle;
63 static int proto_enc = -1;
64 static int hf_enc_af = -1;
65 static int hf_enc_spi = -1;
66 static int hf_enc_flags = -1;
68 static gint ett_enc = -1;
71 capture_enc(const guchar *pd, int len, packet_counts *ld)
75 if (!BYTES_ARE_IN_FRAME(0, len, (int)ENC_HDRLEN)) {
80 af = pntohl(pd + offsetof(struct enchdr, af));
84 capture_ip(pd, ENC_HDRLEN, len, ld);
88 capture_ipv6(pd, ENC_HDRLEN, len, ld);
97 static const value_string af_vals[] = {
98 { BSD_ENC_INET, "IPv4" },
99 { BSD_ENC_INET6, "IPv6" },
104 dissect_enc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
108 proto_tree *enc_tree;
111 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ENC");
113 /* Copy out the enc header to insure alignment */
114 tvb_memcpy(tvb, (guint8 *)&ench, 0, sizeof(ench));
116 /* Byteswap the header now */
117 ench.spi = g_ntohl(ench.spi);
118 /* ench.af = g_ntohl(ench.af); */
119 /* ench.flags = g_ntohl(ench.flags); */
122 ti = proto_tree_add_protocol_format(tree, proto_enc, tvb, 0,
124 "Enc %s, SPI 0x%8.8x, %s%s%s%s",
125 val_to_str(ench.af, af_vals, "unknown (%u)"),
127 ench.flags ? "" : "unprotected",
128 ench.flags & BSD_ENC_M_AUTH ? "authentic" : "",
129 (ench.flags & (BSD_ENC_M_AUTH|BSD_ENC_M_CONF)) ==
130 (BSD_ENC_M_AUTH|BSD_ENC_M_CONF) ? ", " : "",
131 ench.flags & BSD_ENC_M_CONF ? "confidential" : ""
133 enc_tree = proto_item_add_subtree(ti, ett_enc);
135 proto_tree_add_uint(enc_tree, hf_enc_af, tvb,
136 offsetof(struct enchdr, af), sizeof(ench.af),
138 proto_tree_add_uint(enc_tree, hf_enc_spi, tvb,
139 offsetof(struct enchdr, spi), sizeof(ench.spi),
141 proto_tree_add_uint(enc_tree, hf_enc_flags, tvb,
142 offsetof(struct enchdr, flags), sizeof(ench.flags),
146 /* Set the tvbuff for the payload after the header */
147 next_tvb = tvb_new_subset_remaining(tvb, ENC_HDRLEN);
152 call_dissector(ip_handle, next_tvb, pinfo, tree);
156 call_dissector(ipv6_handle, next_tvb, pinfo, tree);
160 call_dissector(data_handle, next_tvb, pinfo, tree);
166 proto_register_enc(void)
168 static hf_register_info hf[] = {
170 { "Address Family", "enc.af", FT_UINT32, BASE_DEC, VALS(af_vals), 0x0,
171 "Protocol (IPv4 vs IPv6)", HFILL }},
173 { "SPI", "enc.spi", FT_UINT32, BASE_HEX, NULL, 0x0,
174 "Security Parameter Index", HFILL }},
176 { "Flags", "enc.flags", FT_UINT32, BASE_HEX, NULL, 0x0,
177 "ENC flags", HFILL }},
179 static gint *ett[] = { &ett_enc };
181 proto_enc = proto_register_protocol("OpenBSD Encapsulating device",
183 proto_register_field_array(proto_enc, hf, array_length(hf));
184 proto_register_subtree_array(ett, array_length(ett));
188 proto_reg_handoff_enc(void)
190 dissector_handle_t enc_handle;
192 ip_handle = find_dissector("ip");
193 ipv6_handle = find_dissector("ipv6");
194 data_handle = find_dissector("data");
196 enc_handle = create_dissector_handle(dissect_enc, proto_enc);
197 dissector_add_uint("wtap_encap", WTAP_ENCAP_ENC, enc_handle);