2 * routines for openvpn packet dissasembly
3 * - http://www.openvpn.net
4 * - http://fengnet.com/book/vpns%20illustrated%20tunnels%20%20vpnsand%20ipsec/ch08lev1sec5.html
6 * Created as part of a semester project at the University of Applied Sciences Hagenberg
7 * (http://www.fh-ooe.at/en/hagenberg-campus/)
10 * Hofer Manuel (manuel@mnlhfr.at)
18 * This program is free software; you can redistribute it and/or
19 * modify it under the terms of the GNU General Public License
20 * as published by the Free Software Foundation; either version 2
21 * of the License, or (at your option) any later version.
23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
35 #include <epan/packet.h>
36 #include <epan/prefs.h>
37 #include <epan/reassemble.h>
38 #include <epan/wmem/wmem.h>
39 #include <epan/dissectors/packet-tcp.h>
40 #include <epan/ipproto.h>
42 #define PFNAME "openvpn"
43 #define PNAME "OpenVPN Protocol"
44 #define PSNAME "OpenVPN"
46 #define OPENVPN_PORT 1194
48 /* packet opcode and key-id are combined in one byte */
49 #define P_OPCODE_MASK 0xF8 /* packet opcode (high 5 bits) */
50 #define P_KEY_ID_MASK 0x07 /* key-id (low 3 bits) */
51 #define HMAC_KEY_LENGTH_MAX 64 /* 512 Bit HMAC is maximum */
54 #define P_CONTROL_HARD_RESET_CLIENT_V1 1
55 #define P_CONTROL_HARD_RESET_SERVER_V1 2
56 #define P_CONTROL_SOFT_RESET_V1 3
57 #define P_CONTROL_V1 4
60 #define P_CONTROL_HARD_RESET_CLIENT_V2 7
61 #define P_CONTROL_HARD_RESET_SERVER_V2 8
63 static gint ett_openvpn
= -1;
64 static gint ett_openvpn_data
= -1;
65 static gint ett_openvpn_packetarray
= -1;
66 static gint ett_openvpn_type
= -1;
67 static gint hf_openvpn_data
= -1;
68 static gint hf_openvpn_fragment_bytes
= -1;
69 static gint hf_openvpn_hmac
= -1;
70 static gint hf_openvpn_keyid
= -1;
71 static gint hf_openvpn_mpid
= -1;
72 static gint hf_openvpn_mpid_arrayelement
= -1;
73 static gint hf_openvpn_mpid_arraylength
= -1;
74 static gint hf_openvpn_net_time
= -1;
75 static gint hf_openvpn_opcode
= -1;
76 static gint hf_openvpn_pdu_type
= -1;
77 static gint hf_openvpn_pid
= -1;
78 static gint hf_openvpn_plen
= -1;
79 static gint hf_openvpn_rsessionid
= -1;
80 static gint hf_openvpn_sessionid
= -1;
81 static gint proto_openvpn
= -1;
83 static dissector_handle_t openvpn_udp_handle
;
84 static dissector_handle_t openvpn_tcp_handle
;
86 static dissector_handle_t ssl_handle
;
89 static gboolean pref_long_format
= TRUE
;
90 static gboolean pref_tls_auth
= FALSE
;
91 static gboolean pref_tls_auth_override
= FALSE
;
92 static guint pref_tcp_port
= OPENVPN_PORT
;
93 static guint pref_udp_port
= OPENVPN_PORT
;
94 static guint tls_auth_hmac_size
= 20; /* Default SHA-1 160 Bits */
96 void proto_reg_handoff_openvpn(void); /* forward declaration for use in preferences registration */
98 static const value_string openvpn_message_types
[] =
100 { P_CONTROL_HARD_RESET_CLIENT_V1
, "P_CONTROL_HARD_RESET_CLIENT_V1" },
101 { P_CONTROL_HARD_RESET_SERVER_V1
, "P_CONTROL_HARD_RESET_SERVER_V1" },
102 { P_CONTROL_SOFT_RESET_V1
, "P_CONTROL_SOFT_RESET_V1" },
103 { P_CONTROL_V1
, "P_CONTROL_V1" },
104 { P_ACK_V1
, "P_ACK_V1" },
105 { P_DATA_V1
, "P_DATA_V1" },
106 { P_CONTROL_HARD_RESET_CLIENT_V2
, "P_CONTROL_HARD_RESET_CLIENT_V2" },
107 { P_CONTROL_HARD_RESET_SERVER_V2
, "P_CONTROL_HARD_RESET_SERVER_V2" },
111 /* everything used during the reassembly process */
112 static reassembly_table msg_reassembly_table
;
114 static gint ett_openvpn_fragment
= -1;
115 static gint ett_openvpn_fragments
= -1;
116 static gint hf_openvpn_fragment
= -1;
117 static gint hf_openvpn_fragment_count
= -1;
118 static gint hf_openvpn_fragment_error
= -1;
119 static gint hf_openvpn_fragment_multiple_tails
= -1;
120 static gint hf_openvpn_fragment_overlap
= -1;
121 static gint hf_openvpn_fragment_overlap_conflicts
= -1;
122 static gint hf_openvpn_fragment_too_long_fragment
= -1;
123 static gint hf_openvpn_fragments
= -1;
124 static gint hf_openvpn_reassembled_in
= -1;
125 static gint hf_openvpn_reassembled_length
= -1;
127 static const fragment_items openvpn_frag_items
= {
128 /* Fragment subtrees */
129 &ett_openvpn_fragment
,
130 &ett_openvpn_fragments
,
131 /* Fragment fields */
132 &hf_openvpn_fragments
,
133 &hf_openvpn_fragment
,
134 &hf_openvpn_fragment_overlap
,
135 &hf_openvpn_fragment_overlap_conflicts
,
136 &hf_openvpn_fragment_multiple_tails
,
137 &hf_openvpn_fragment_too_long_fragment
,
138 &hf_openvpn_fragment_error
,
139 &hf_openvpn_fragment_count
,
140 /* Reassembled in field */
141 &hf_openvpn_reassembled_in
,
142 /* Reassembled length field */
143 &hf_openvpn_reassembled_length
,
144 /* Reassembled data field */
151 openvpn_reassemble_init(void)
153 reassembly_table_init(&msg_reassembly_table
,
154 &addresses_reassembly_table_functions
);
157 /* we check the leading 4 byte of a suspected hmac for 0x00 bytes,
158 if more than 1 byte out of the 4 provided contains 0x00, the
159 hmac is considered not valid, which suggests that no tls auth is used.
160 unfortunatly there is no other way to detect tls auth on the fly */
162 check_for_valid_hmac(guint32 hmac
)
165 if ((hmac
& 0x000000FF) == 0x00000000) {
168 if ((hmac
& 0x0000FF00) == 0x00000000) {
171 if ((hmac
& 0x00FF0000) == 0x00000000) {
174 if ((hmac
& 0xFF000000) == 0x00000000) {
185 dissect_openvpn_msg_common(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*openvpn_tree
, proto_tree
*parent_tree
, gint offset
)
189 guint openvpn_opcode
;
190 guint32 msg_mpid
= -1;
191 guint32 msg_sessionid
= -1;
192 guint8 openvpn_predict_tlsauth_arraylength
;
193 proto_item
*ti2
, *ti3
;
194 proto_tree
*packetarray_tree
, *type_tree
;
195 guint32 msg_length_remaining
;
196 gboolean msg_lastframe
;
197 fragment_head
*frag_msg
;
199 gboolean save_fragmented
;
201 /* Clear out stuff in the info column */
202 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, PSNAME
);
203 col_clear(pinfo
->cinfo
,COL_INFO
);
205 /* read opcode and write to info column */
206 openvpn_opcode
= tvb_get_bits8(tvb
, offset
*8, 5);
207 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "MessageType: %s",
208 val_to_str_const(openvpn_opcode
, openvpn_message_types
, "Unknown Messagetype"));
211 openvpn_keyid
= tvb_get_bits8(tvb
, offset
*8 + 5, 3);
212 proto_item_append_text(parent_tree
, ", Opcode: %s, Key ID: %d",
213 val_to_str(openvpn_opcode
, openvpn_message_types
, "Unknown (0x%02x)"),
216 ti2
= proto_tree_add_item(openvpn_tree
, hf_openvpn_pdu_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
217 proto_item_append_text(ti2
, " [opcode/key_id]");
219 type_tree
= proto_item_add_subtree(ti2
, ett_openvpn_type
);
220 proto_tree_add_item(type_tree
, hf_openvpn_opcode
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
221 proto_tree_add_item(type_tree
, hf_openvpn_keyid
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
224 /* if we have a P_CONTROL or P_ACK packet */
225 if (openvpn_opcode
!= P_DATA_V1
) {
227 msg_sessionid
= tvb_get_bits32(tvb
, offset
*8+32, 32, ENC_BIG_ENDIAN
);
228 proto_tree_add_item(openvpn_tree
, hf_openvpn_sessionid
, tvb
, offset
, 8, ENC_BIG_ENDIAN
);
231 /* tls-auth detection (this can be overridden by preferences */
232 openvpn_predict_tlsauth_arraylength
= tvb_get_guint8(tvb
, offset
);
233 /* if the first 4 bytes that would, if tls-auth is used, contain part of the hmac,
234 lack entropy, we asume no tls-auth is used */
235 if (pref_tls_auth_override
== FALSE
) {
236 if ((openvpn_opcode
!= P_DATA_V1
)
237 && (openvpn_predict_tlsauth_arraylength
> 0)
238 && check_for_valid_hmac(tvb_get_ntohl(tvb
, offset
))) {
244 tls_auth
= pref_tls_auth
;
247 if (tls_auth
== TRUE
) {
248 proto_tree_add_item(openvpn_tree
, hf_openvpn_hmac
, tvb
, offset
, tls_auth_hmac_size
, ENC_NA
);
249 offset
+= tls_auth_hmac_size
;
251 if (tvb_length_remaining(tvb
, offset
) >= 8) {
252 proto_tree_add_item(openvpn_tree
, hf_openvpn_pid
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
255 if (pref_long_format
) {
256 proto_tree_add_item(openvpn_tree
, hf_openvpn_net_time
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
262 if (tvb_length_remaining(tvb
, offset
) >= 1) {
263 /* read P_ACK packet-id array length */
264 gint pid_arraylength
= tvb_get_guint8(tvb
, offset
);
266 proto_tree_add_item(openvpn_tree
, hf_openvpn_mpid_arraylength
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
269 if (pid_arraylength
> 0) {
271 ti3
= proto_tree_add_text(openvpn_tree
, tvb
, offset
, 0, "Packet-ID Array");
272 packetarray_tree
= proto_item_add_subtree(ti3
, ett_openvpn_packetarray
);
273 for (i
= 0; i
< pid_arraylength
; i
++) {
274 proto_tree_add_item(packetarray_tree
, hf_openvpn_mpid_arrayelement
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
278 if (tvb_length_remaining(tvb
, offset
) >= 8) {
279 proto_tree_add_item(openvpn_tree
, hf_openvpn_rsessionid
, tvb
, offset
, 8, ENC_BIG_ENDIAN
);
285 /* if we have a P_CONTROL packet */
286 if (openvpn_opcode
!= P_ACK_V1
) {
287 /* read Message Packet-ID */
288 if (tvb_length_remaining(tvb
, offset
) >= 4) {
289 msg_mpid
= tvb_get_bits32(tvb
, offset
*8, 32, ENC_BIG_ENDIAN
);
290 proto_tree_add_item(openvpn_tree
, hf_openvpn_mpid
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
296 /* if we have more data left, determine what to do */
297 msg_length_remaining
= tvb_length_remaining(tvb
, offset
);
299 if (msg_length_remaining
== 0) {
300 return tvb_length(tvb
);
303 if (openvpn_opcode
!= P_CONTROL_V1
) {
304 proto_tree
*data_tree
;
305 ti2
= proto_tree_add_text(openvpn_tree
, tvb
, offset
, -1, "Data (%d bytes)",
306 tvb_length_remaining(tvb
, offset
));
308 data_tree
= proto_item_add_subtree(ti2
, ett_openvpn_data
);
309 proto_tree_add_item(data_tree
, hf_openvpn_data
, tvb
, offset
, -1, ENC_NA
);
310 return tvb_length(tvb
);
313 /* Try to reassemble */
315 /* an ordinary openvpn control packet contains 100 bytes only if it is part of a
316 fragmented message and is not the last fragment of the current transmission.
317 Note that the tvb contains exactly one openvpn PDU:
319 TCP: because of the use of tcp_dissect_pdus().
321 if (msg_length_remaining
== 100) {
322 msg_lastframe
= FALSE
;
324 msg_lastframe
= TRUE
;
327 save_fragmented
= pinfo
->fragmented
;
328 pinfo
->fragmented
= TRUE
;
330 frag_msg
= fragment_add_seq_next(
331 &msg_reassembly_table
,
335 msg_sessionid
, /* ID for fragments belonging together */
337 msg_length_remaining
, /* fragment length - to the end */
338 !(msg_lastframe
)); /* More fragments ? */
340 /* show "data" fragment on tree unless "reassembled" message has just one part. */
341 /* i.e., show if ("not reassembled") or ("reassembled" and "has multiple fragments") */
342 if ((frag_msg
== NULL
) || (frag_msg
->next
!= NULL
)) {
343 proto_tree
*data_tree
;
344 ti2
= proto_tree_add_text(openvpn_tree
, tvb
, offset
, -1, "Message fragment (%d bytes)",
345 tvb_length_remaining(tvb
, offset
));
347 data_tree
= proto_item_add_subtree(ti2
, ett_openvpn_data
);
348 proto_tree_add_item(data_tree
, hf_openvpn_fragment_bytes
, tvb
, offset
, -1, ENC_NA
);
353 if (msg_lastframe
) { /* Reassembled */
354 new_tvb
= process_reassembled_data(tvb
, offset
, pinfo
, "Reassembled Message",
355 frag_msg
, &openvpn_frag_items
, NULL
, openvpn_tree
);
356 if (frag_msg
->next
!= NULL
) { /* multiple frags ? */
357 col_append_str(pinfo
->cinfo
, COL_INFO
, " (Message Reassembled "); /* overwritten by next dissector */
360 } else { /* Not last packet of reassembled Short Message */
361 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " (Message fragment %d) ", msg_mpid
);
362 if (pinfo
->fd
->num
!= frag_msg
->reassembled_in
) {
363 /* Add a "Reassembled in" link if not reassembled in this frame */
364 proto_tree_add_uint(openvpn_tree
, hf_openvpn_reassembled_in
,
365 tvb
, 0, 0, frag_msg
->reassembled_in
);
368 } /* if (frag_msg) */
370 pinfo
->fragmented
= save_fragmented
;
372 /* Now see if we need to call subdissector.
373 new_tvb is non-null if we "reassembled* a message (even just one fragment) */
376 /* call SSL/TLS dissector if we just processed the last fragment */
377 call_dissector(ssl_handle
, new_tvb
, pinfo
, parent_tree
);
380 return tvb_length(tvb
);
384 get_msg_length(packet_info
*pinfo _U_
, tvbuff_t
*tvb
, gint offset
)
386 return (guint
)tvb_get_ntohs(tvb
, offset
) + 2; /* length field is at offset 0,
387 +2 to account for the length field itself */
391 dissect_openvpn_msg_tcp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
394 proto_tree
*openvpn_tree
;
396 ti
= proto_tree_add_item(tree
, proto_openvpn
, tvb
, 0, -1, ENC_NA
);
397 openvpn_tree
= proto_item_add_subtree(ti
, ett_openvpn
);
399 proto_tree_add_item(openvpn_tree
, hf_openvpn_plen
, tvb
, 0, 2, ENC_BIG_ENDIAN
);
401 return dissect_openvpn_msg_common(tvb
, pinfo
, openvpn_tree
, tree
, 2);
405 dissect_openvpn_tcp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data
)
407 tcp_dissect_pdus( tvb
, pinfo
, tree
,
408 TRUE
, /* should data be reassembled? */
409 2, /* how much bytes do we need for get_msg_length to be successful,
410 since the length is the first thing in an openvpn packet we choose 2 */
411 get_msg_length
, /* fptr for function to get the packetlength of current frame */
412 dissect_openvpn_msg_tcp
, data
);
413 return tvb_length(tvb
);
417 dissect_openvpn_udp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
420 proto_tree
*openvpn_tree
;
422 ti
= proto_tree_add_item(tree
, proto_openvpn
, tvb
, 0, -1, ENC_NA
);
423 openvpn_tree
= proto_item_add_subtree(ti
, ett_openvpn
);
425 return dissect_openvpn_msg_common(tvb
, pinfo
, openvpn_tree
, tree
, 0);
429 proto_register_openvpn(void)
431 static hf_register_info hf
[] = {
433 { "Packet Length", "openvpn.plen",
438 { &hf_openvpn_pdu_type
,
439 { "Type", "openvpn.type",
444 { &hf_openvpn_opcode
,
445 { "Opcode", "openvpn.opcode",
447 VALS(openvpn_message_types
), P_OPCODE_MASK
,
451 { "Key ID", "openvpn.keyid",
456 { &hf_openvpn_sessionid
,
457 { "Session ID", "openvpn.sessionid",
463 { "HMAC", "openvpn.hmac",
469 { "Packet-ID", "openvpn.pid",
474 { &hf_openvpn_net_time
,
475 { "Net Time", "openvpn.net_time",
476 FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_LOCAL
,
480 { &hf_openvpn_rsessionid
,
481 { "Remote Session ID", "openvpn.rsessionid",
487 { "Message Packet-ID", "openvpn.mpid",
492 { &hf_openvpn_mpid_arraylength
,
493 { "Message Packet-ID Array Length", "openvpn.mpidarraylength",
498 { &hf_openvpn_mpid_arrayelement
,
499 { "Message Packet-ID Array Element", "openvpn.mpidarrayelement",
505 { "Data", "openvpn.data",
510 { &hf_openvpn_fragment_bytes
,
511 { "Fragment bytes", "openvpn.fragment_bytes",
516 { &hf_openvpn_fragments
,
517 { "Message fragments", "openvpn.fragments",
522 { &hf_openvpn_fragment
,
523 { "Message fragment", "openvpn.fragment",
524 FT_FRAMENUM
, BASE_NONE
,
528 { &hf_openvpn_fragment_overlap
,
529 { "Message fragment overlap", "openvpn.fragment.overlap",
534 { &hf_openvpn_fragment_overlap_conflicts
,
535 { "Message fragment overlapping with conflicting data", "openvpn.fragment.overlap.conflicts",
540 { &hf_openvpn_fragment_multiple_tails
,
541 { "Message has multiple tail fragments", "openvpn.fragment.multiple_tails",
546 { &hf_openvpn_fragment_too_long_fragment
,
547 { "Message fragment too long", "openvpn.fragment.too_long_fragment",
552 { &hf_openvpn_fragment_error
,
553 { "Message defragmentation error", "openvpn.fragment.error",
554 FT_FRAMENUM
, BASE_NONE
,
558 { &hf_openvpn_fragment_count
,
559 { "Message fragment count", "openvpn.fragment.count",
564 { &hf_openvpn_reassembled_in
,
565 { "Reassembled message in frame", "openvpn.reassembled.in",
566 FT_FRAMENUM
, BASE_NONE
,
570 { &hf_openvpn_reassembled_length
,
571 {"Reassembled message length", "openvpn.reassembled.length",
578 /* Setup protocol subtree array */
579 static gint
*ett
[] = {
583 &ett_openvpn_packetarray
,
584 &ett_openvpn_fragment
,
585 &ett_openvpn_fragments
587 module_t
*openvpn_module
;
589 proto_openvpn
= proto_register_protocol (
591 PSNAME
, /* short name */
595 proto_register_field_array(proto_openvpn
, hf
, array_length(hf
));
596 proto_register_subtree_array(ett
, array_length(ett
));
598 openvpn_udp_handle
= new_register_dissector("openvpn.udp", dissect_openvpn_udp
, proto_openvpn
);
599 openvpn_tcp_handle
= new_register_dissector("openvpn.tcp", dissect_openvpn_tcp
, proto_openvpn
);
601 register_init_routine(&openvpn_reassemble_init
);
603 openvpn_module
= prefs_register_protocol(proto_openvpn
, proto_reg_handoff_openvpn
);
605 prefs_register_uint_preference(openvpn_module
,
608 "TCP Port of the OpenVPN tunnel",
610 prefs_register_uint_preference(openvpn_module
,
613 "UDP Port of the OpenVPN tunnel",
615 prefs_register_bool_preference(openvpn_module
,
616 "tls_auth_detection_override",
617 "override tls-auth detection",
618 "If tls-auth detection fails, you can choose to override detection and set tls-auth yourself",
619 &pref_tls_auth_override
);
620 prefs_register_bool_preference(openvpn_module
,
623 "If the parameter --tls-auth is used, the following preferences must also be defined.",
625 prefs_register_uint_preference(openvpn_module
,
626 "tls_auth_hmac_size",
627 "size of the HMAC header in bytes",
628 "If the parameter --tls-auth is used, a HMAC header is being inserted.\n"
629 "The default HMAC algorithm is SHA-1 which generates a 160 bit HMAC,"
630 " therefore 20 bytes should be ok.\n"
631 "The value must be between 20 (160 bits) and 64 (512 bits).",
632 10, &tls_auth_hmac_size
);
634 prefs_register_bool_preference(openvpn_module
,
636 "packet-id for replay protection includes optional time_t timestamp?",
637 "If the parameter --tls-auth is used, an additional packet-id for replay protection"
638 " is inserted after the HMAC signature."
639 " This field can either be 4 bytes or 8 bytes including an optional time_t timestamp long.\n"
640 " This option is only evaluated if tls_auth_hmac_size > 0.\n"
641 " The default value is TRUE.",
646 proto_reg_handoff_openvpn(void)
648 static guint tcp_port
;
649 static guint udp_port
;
650 static gboolean initialized
= FALSE
;
653 ssl_handle
= find_dissector("ssl");
657 dissector_delete_uint("tcp.port", tcp_port
, openvpn_tcp_handle
);
659 dissector_delete_uint("udp.port", udp_port
, openvpn_udp_handle
);
662 tcp_port
= pref_tcp_port
;
663 udp_port
= pref_udp_port
;
666 dissector_add_uint("tcp.port", tcp_port
, openvpn_tcp_handle
);
668 dissector_add_uint("udp.port", udp_port
, openvpn_udp_handle
);
672 * Editor modelines - http://www.wireshark.org/tools/modelines.html
677 * indent-tabs-mode: nil
680 * vi: set shiftwidth=2 tabstop=8 expandtab:
681 * :indentSize=2:tabSize=8:noTabs=true