static int hf_quic_version = -1;
static int hf_quic_supported_version = -1;
static int hf_quic_vn_unused = -1;
-static int hf_quic_short_ocid_flag = -1;
-static int hf_quic_short_kp_flag_draft10 = -1;
static int hf_quic_short_kp_flag = -1;
-static int hf_quic_short_packet_type_draft10 = -1;
static int hf_quic_short_packet_type = -1;
static int hf_quic_initial_payload = -1;
static int hf_quic_handshake_payload = -1;
}
return 0;
}
+#if 0
static inline gboolean is_quic_draft_max(guint32 version, guint8 max_version) {
guint8 draft_version = quic_draft_version(version);
return draft_version && draft_version <= max_version;
}
+#endif
const value_string quic_version_vals[] = {
{ 0x00000000, "Version Negotiation" },
{ 0, NULL }
};
-#define SH_OCID 0x40 /* until draft -10 */
-#define SH_KP_10 0x20 /* until draft -10 */
-#define SH_PT_10 0x07 /* until draft -10 */
#define SH_KP 0x40 /* since draft -11 */
#define SH_PT 0x03 /* since draft -11 */
conn->server_port = pinfo->destport;
// Key connection by Client CID (if provided).
- if (!is_quic_draft_max(version, 10) && scid->len) {
+ if (scid->len) {
memcpy(&conn->client_cids.data, scid, sizeof(quic_cid_t));
wmem_map_insert(quic_client_connections, &conn->client_cids.data, conn);
}
if (scid->len) {
wmem_map_insert(quic_server_connections, &conn->server_cids.data, conn);
}
-
- // in draft -10, the Initial Packet CID is useless for tracking,
- // instead the CID from this Handshake message is used.
- if (is_quic_draft_max(version, 10)) {
- DISSECTOR_ASSERT(scid->len);
- memcpy(&conn->client_cids.data, scid, sizeof(quic_cid_t));
- wmem_map_insert(quic_client_connections, &conn->client_cids.data, conn);
- }
}
break;
}
#ifdef HAVE_LIBGCRYPT_AEAD
static int
-dissect_quic_frame_type(tvbuff_t *tvb, packet_info *pinfo, proto_tree *quic_tree, guint offset, quic_packet_info_t *quic_packet)
+dissect_quic_frame_type(tvbuff_t *tvb, packet_info *pinfo, proto_tree *quic_tree, guint offset, quic_packet_info_t *quic_packet _U_)
{
proto_item *ti_ft, *ti_ftflags, *ti;
proto_tree *ft_tree, *ftflags_tree;
guint32 frame_type;
- quic_info_data_t *conn = quic_packet->conn;
- guint32 version = conn ? conn->version : 0;
ti_ft = proto_tree_add_item(quic_tree, hf_quic_frame, tvb, offset, 1, ENC_NA);
ft_tree = proto_item_add_subtree(ti_ft, ett_quic_ft);
proto_tree_add_item_ret_varint(ft_tree, hf_quic_frame_type_nci_sequence, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &len_sequence);
offset += len_sequence;
- if (is_quic_draft_max(version, 10)) {
- nci_length = 8;
- } else {
- ti = proto_tree_add_item_ret_uint(ft_tree, hf_quic_frame_type_nci_connection_id_length, tvb, offset, 1, ENC_BIG_ENDIAN, &nci_length);
- offset++;
+ ti = proto_tree_add_item_ret_uint(ft_tree, hf_quic_frame_type_nci_connection_id_length, tvb, offset, 1, ENC_BIG_ENDIAN, &nci_length);
+ offset++;
- valid_cid = nci_length >= 4 && nci_length <= 18;
- if (!valid_cid) {
- expert_add_info_format(pinfo, ti, &ei_quic_protocol_violation,
+ valid_cid = nci_length >= 4 && nci_length <= 18;
+ if (!valid_cid) {
+ expert_add_info_format(pinfo, ti, &ei_quic_protocol_violation,
"Connection ID Length must be between 4 and 18 bytes");
- }
}
proto_tree_add_item(ft_tree, hf_quic_frame_type_nci_connection_id, tvb, offset, nci_length, ENC_NA);
guint32 *version_out, quic_cid_t *dcid, quic_cid_t *scid)
{
guint32 version;
- gboolean is_draft10 = FALSE;
guint32 dcil, scil;
version = tvb_get_ntohl(tvb, offset);
- if (!(version == 0 || quic_draft_version(version) >= 11)) {
- // not a draft -11 version negotiation packet nor draft -11 version,
- // assume draft -10 or older. Its version comes after CID.
- guint32 version10 = tvb_get_ntohl(tvb, offset + 8);
- is_draft10 = is_quic_draft_max(version10, 10);
- if (is_draft10) {
- version = version10;
- }
- }
if (version_out) {
*version_out = version;
}
- if (is_draft10) {
- proto_tree_add_item(quic_tree, hf_quic_dcid, tvb, offset, 8, ENC_NA);
- tvb_memcpy(tvb, dcid->cid, offset, 8);
- dcid->len = 8;
- offset += 8;
-
- proto_tree_add_item(quic_tree, hf_quic_version, tvb, offset, 4, ENC_BIG_ENDIAN);
- offset += 4;
- } else {
- // draft -11 and up.
- proto_tree_add_item(quic_tree, hf_quic_version, tvb, offset, 4, ENC_BIG_ENDIAN);
- offset += 4;
+ proto_tree_add_item(quic_tree, hf_quic_version, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
- proto_tree_add_item_ret_uint(quic_tree, hf_quic_dcil, tvb, offset, 1, ENC_BIG_ENDIAN, &dcil);
- proto_tree_add_item_ret_uint(quic_tree, hf_quic_scil, tvb, offset, 1, ENC_BIG_ENDIAN, &scil);
- offset++;
+ proto_tree_add_item_ret_uint(quic_tree, hf_quic_dcil, tvb, offset, 1, ENC_BIG_ENDIAN, &dcil);
+ proto_tree_add_item_ret_uint(quic_tree, hf_quic_scil, tvb, offset, 1, ENC_BIG_ENDIAN, &scil);
+ offset++;
- if (dcil) {
- dcil += 3;
- proto_tree_add_item(quic_tree, hf_quic_dcid, tvb, offset, dcil, ENC_NA);
- // TODO expert info on CID mismatch with connection
- tvb_memcpy(tvb, dcid->cid, offset, dcil);
- dcid->len = dcil;
- offset += dcil;
- }
+ if (dcil) {
+ dcil += 3;
+ proto_tree_add_item(quic_tree, hf_quic_dcid, tvb, offset, dcil, ENC_NA);
+ // TODO expert info on CID mismatch with connection
+ tvb_memcpy(tvb, dcid->cid, offset, dcil);
+ dcid->len = dcil;
+ offset += dcil;
+ }
- if (scil) {
- scil += 3;
- proto_tree_add_item(quic_tree, hf_quic_scid, tvb, offset, scil, ENC_NA);
- // TODO expert info on CID mismatch with connection
- tvb_memcpy(tvb, scid->cid, offset, scil);
- scid->len = scil;
- offset += scil;
- }
+ if (scil) {
+ scil += 3;
+ proto_tree_add_item(quic_tree, hf_quic_scid, tvb, offset, scil, ENC_NA);
+ // TODO expert info on CID mismatch with connection
+ tvb_memcpy(tvb, scid->cid, offset, scil);
+ scid->len = scil;
+ offset += scil;
}
+
if (dcid->len > 0) {
col_append_fstr(pinfo->cinfo, COL_INFO, ", DCID=%s", cid_to_string(dcid));
}
offset = dissect_quic_long_header_common(tvb, pinfo, quic_tree, offset, quic_packet, &version, &dcid, &scid);
- if (!is_quic_draft_max(version, 10)) {
- proto_tree_add_item_ret_varint(quic_tree, hf_quic_payload_length, tvb, offset, -1, ENC_VARINT_QUIC, &payload_length, &len_payload_length);
- offset += len_payload_length;
- }
+ proto_tree_add_item_ret_varint(quic_tree, hf_quic_payload_length, tvb, offset, -1, ENC_VARINT_QUIC, &payload_length, &len_payload_length);
+ offset += len_payload_length;
pkn = dissect_quic_packet_number(tvb, pinfo, quic_tree, offset, conn, quic_packet, 4);
offset += 4;
gboolean key_phase = FALSE;
tls13_cipher *cipher = NULL;
quic_info_data_t *conn = quic_packet->conn;
- // Best-effort guess: if no connection is known, assume newer draft version.
- gboolean is_draft10 = conn && is_quic_draft_max(conn->version, 10);
short_flags = tvb_get_guint8(tvb, offset);
- if (is_draft10) {
- gboolean omit_cid;
- proto_tree_add_item_ret_boolean(quic_tree, hf_quic_short_ocid_flag, tvb, offset, 1, ENC_NA, &omit_cid);
- dcid.len = omit_cid ? 0 : 8;
- proto_tree_add_item_ret_boolean(quic_tree, hf_quic_short_kp_flag_draft10, tvb, offset, 1, ENC_NA, &key_phase);
- ti = proto_tree_add_item(quic_tree, hf_quic_short_packet_type_draft10, tvb, offset, 1, ENC_NA);
- if ((short_flags & 0x18) != 0x10) {
- expert_add_info_format(pinfo, ti, &ei_quic_protocol_violation,
- "Fourth bit (0x10) must be 1, fifth bit (0x8) must be set to 0.");
- }
- } else {
- proto_tree_add_item_ret_boolean(quic_tree, hf_quic_short_kp_flag, tvb, offset, 1, ENC_NA, &key_phase);
- proto_tree_add_item(quic_tree, hf_quic_short_packet_type, tvb, offset, 1, ENC_NA);
- if (conn) {
- dcid.len = quic_packet->from_server ? conn->client_cids.data.len : conn->server_cids.data.len;
- }
+
+ proto_tree_add_item_ret_boolean(quic_tree, hf_quic_short_kp_flag, tvb, offset, 1, ENC_NA, &key_phase);
+ proto_tree_add_item(quic_tree, hf_quic_short_packet_type, tvb, offset, 1, ENC_NA);
+ if (conn) {
+ dcid.len = quic_packet->from_server ? conn->client_cids.data.len : conn->server_cids.data.len;
}
offset += 1;
}
offset++;
- guint32 maybe_version = tvb_get_ntohl(tvb, offset);
- gboolean is_draft10 = FALSE;
- if (!(maybe_version == 0 || quic_draft_version(maybe_version) >= 11)) {
- // not a draft -11 version negotiation packet nor draft -11 version,
- // assume draft -10 or older. Its version comes after CID.
- guint32 version10 = tvb_get_ntohl(tvb, offset + 8);
- is_draft10 = is_quic_draft_max(version10, 10);
- if (is_draft10) {
- maybe_version = version10;
- }
- }
- *version = maybe_version;
+ *version = tvb_get_ntohl(tvb, offset);
- if (is_draft10) {
- tvb_memcpy(tvb, dcid->cid, offset, 8);
- dcid->len = 8;
- } else if (is_long_header) {
+ if (is_long_header) {
// skip version
offset += 4;
quic_extract_header(tvb, &long_packet_type, &version, &dcid, &scid);
conn = quic_connection_find(pinfo, long_packet_type, &dcid, &from_server);
- if (is_quic_draft_max(version, 10)) {
- // In draft -10 and before, there is only a single CID.
- if (long_packet_type == QUIC_LPT_HANDSHAKE && !conn) {
- // the first handshake packet from server sets CID, only after
- // that it will be possible to match by CID.
- conn = quic_connection_find_dcid(pinfo, NULL, &from_server);
- }
- quic_connection_create_or_update(&conn, pinfo, long_packet_type, version, &dcid, &dcid, from_server);
- } else {
- quic_connection_create_or_update(&conn, pinfo, long_packet_type, version, &scid, &dcid, from_server);
- }
+ quic_connection_create_or_update(&conn, pinfo, long_packet_type, version, &scid, &dcid, from_server);
quic_packet->conn = conn;
quic_packet->from_server = from_server;
#if 0
proto_tree_add_item_ret_uint(quic_tree, hf_quic_header_form, tvb, offset, 1, ENC_NA, &header_form);
if(header_form) {
gboolean is_vn = tvb_get_ntohl(tvb, offset + 1) == 0;
- is_vn = is_vn || tvb_get_ntohl(tvb, offset + 1 + 8) == 0; // before draft -11
if (is_vn) {
offset = dissect_quic_version_negotiation(tvb, pinfo, quic_tree, offset, quic_packet);
return offset;
* (absolute minimum: 11 + payload)
* (for Version Negotiation, payload len + PKN + payload is replaced by
* Supported Version (multiple of 4 bytes.)
- *
- * Draft -10 and before:
- * Flag (1 byte) + Connection ID (8 bytes) + Version (4 bytes) + packet
- * number (4 bytes) + Payload.
- * (absolute minimum: 17 + payload)
*/
conversation_t *conversation = NULL;
int offset = 0;
// check for draft QUIC version (for draft -11 and newer)
is_quic = quic_draft_version(tvb_get_ntohl(tvb, offset)) >= 11;
- // check for draft QUIC version (after 8 byte CID) for draft -10 and older
- if (!is_quic && tvb_bytes_exist(tvb, offset + 8, 4)) {
- is_quic = is_quic_draft_max(tvb_get_ntohl(tvb, offset + 8), 10);
- }
-
if (is_quic) {
conversation = find_or_create_conversation(pinfo);
conversation_set_dissector(conversation, quic_handle);
FT_UINT8, BASE_HEX, NULL, 0x7F,
NULL, HFILL }
},
- { &hf_quic_short_ocid_flag,
- { "Omit Connection ID Flag", "quic.short.ocid_flag",
- FT_BOOLEAN, 8, NULL, SH_OCID,
- NULL, HFILL }
- },
- { &hf_quic_short_kp_flag_draft10,
- { "Key Phase Bit", "quic.short.kp_flag_draft10",
- FT_BOOLEAN, 8, NULL, SH_KP_10,
- NULL, HFILL }
- },
{ &hf_quic_short_kp_flag,
{ "Key Phase Bit", "quic.short.kp_flag",
FT_BOOLEAN, 8, NULL, SH_KP,
NULL, HFILL }
},
- { &hf_quic_short_packet_type_draft10,
- { "Packet Type", "quic.short.packet_type_draft10",
- FT_UINT8, BASE_DEC, VALS(quic_short_packet_type_vals), SH_PT_10,
- "Short Header Packet Type", HFILL }
- },
{ &hf_quic_short_packet_type,
{ "Packet Type", "quic.short.packet_type",
FT_UINT8, BASE_DEC, VALS(quic_short_packet_type_vals), SH_PT,