diff options
author | Ryan Doyle <ryan@doylenet.net> | 2015-01-31 14:00:08 +1100 |
---|---|---|
committer | Alexis La Goutte <alexis.lagoutte@gmail.com> | 2015-02-17 16:57:46 +0000 |
commit | c621a7719757939a0b09f4be5ed9158e719c0c8f (patch) | |
tree | 4c4275b94dc404ed68af057be3f53ec56fcd9c03 /epan/dissectors/packet-pcp.c | |
parent | a355daf328d9c07947565a6f0f07a4407f4367c8 (diff) |
PCP: updated protocol dissection for new PDU types
Introduce basic dissection for AUTH PDU type as well as detecting if a
conversation is about to initiate a secure sockets connection (kind of
like STARTTLS) and then pass all packets through the SSL dissector
if that is the case. Also clean up some duplication with constants.
Change-Id: I66f663ca6ab4291f8d0321430e3e126a0be77a93
Reviewed-on: https://code.wireshark.org/review/7109
Petri-Dish: Pascal Quantin <pascal.quantin@gmail.com>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Alexis La Goutte <alexis.lagoutte@gmail.com>
Diffstat (limited to 'epan/dissectors/packet-pcp.c')
-rw-r--r-- | epan/dissectors/packet-pcp.c | 402 |
1 files changed, 278 insertions, 124 deletions
diff --git a/epan/dissectors/packet-pcp.c b/epan/dissectors/packet-pcp.c index 8f6654646c..95f31f173a 100644 --- a/epan/dissectors/packet-pcp.c +++ b/epan/dissectors/packet-pcp.c @@ -24,7 +24,9 @@ #include <epan/packet.h> #include <epan/expert.h> +#include <glib.h> #include "packet-tcp.h" +#include "packet-ssl-utils.h" void proto_register_pcp(void); void proto_reg_handoff_pcp(void); @@ -32,6 +34,7 @@ void proto_reg_handoff_pcp(void); #define PCP_PORT 44321 #define PCP_HEADER_LEN 12 +static dissector_handle_t pcp_handle; static int proto_pcp = -1; static int hf_pcp_pdu_length = -1; @@ -41,15 +44,20 @@ static int hf_pcp_pdu_error = -1; static int hf_pcp_pdu_padding = -1; static int hf_pcp_creds_number_of = -1; static int hf_pcp_creds_type = -1; -static int hf_pcp_creds_vala = -1; -static int hf_pcp_creds_valb = -1; -static int hf_pcp_creds_valc = -1; +static int hf_pcp_creds_version = -1; static int hf_pcp_start = -1; static int hf_pcp_start_status = -1; static int hf_pcp_start_zero = -1; static int hf_pcp_start_version = -1; static int hf_pcp_start_licensed = -1; -static int hf_pcp_start_authorize = -1; +static int hf_pcp_features_flags = -1; +static int hf_pcp_features_flags_secure = -1; +static int hf_pcp_features_flags_compress = -1; +static int hf_pcp_features_flags_auth = -1; +static int hf_pcp_features_flags_creds_reqd = -1; +static int hf_pcp_features_flags_secure_ack = -1; +static int hf_pcp_features_flags_no_nss_init = -1; +static int hf_pcp_features_flags_container = -1; static int hf_pcp_pmns_traverse = -1; static int hf_pcp_pmns_subtype = -1; static int hf_pcp_pmns_namelen = -1; @@ -126,7 +134,7 @@ static int hf_pcp_text = -1; static int hf_pcp_text_ident = -1; static int hf_pcp_text_buflen = -1; static int hf_pcp_text_buffer = -1; - +static int hf_pcp_user_auth_payload = -1; static gint ett_pcp = -1; static gint ett_pcp_pdu_length = -1; @@ -144,7 +152,7 @@ static gint ett_pcp_start_status = -1; static gint ett_pcp_start_zero = -1; static gint ett_pcp_start_version = -1; static gint ett_pcp_start_licensed = -1; -static gint ett_pcp_start_authorize = -1; +static gint ett_pcp_start_features = -1; static gint ett_pcp_pmns_traverse = -1; static gint ett_pcp_pmns_subtype = -1; static gint ett_pcp_pmns_namelen = -1; @@ -226,44 +234,69 @@ static expert_field ei_pcp_type_nosupport_unsupported = EI_INIT; static expert_field ei_pcp_type_unknown_unknown_value = EI_INIT; static expert_field ei_pcp_unimplemented_value = EI_INIT; static expert_field ei_pcp_unimplemented_packet_type = EI_INIT; +static expert_field ei_pcp_ssl_upgrade = EI_INIT; +static expert_field ei_pcp_ssl_upgrade_failed = EI_INIT; + +/* Magic numbers */ +#define PCP_SECURE_ACK_SUCCESSFUL 0 + +static const value_string pcp_feature_flags[] = { +#define PCP_PDU_FLAG_SECURE 0x1 + { PCP_PDU_FLAG_SECURE, "SECURE" }, +#define PCP_PDU_FLAG_COMPRESS 0x2 + { PCP_PDU_FLAG_COMPRESS, "COMPRESS" }, +#define PCP_PDU_FLAG_AUTH 0x4 + { PCP_PDU_FLAG_AUTH, "AUTH"}, +#define PCP_PDU_FLAG_CREDS_REQD 0x8 + { PCP_PDU_FLAG_CREDS_REQD, "CREDS_REQD" }, +#define PCP_PDU_FLAG_SECURE_ACK 0x10 + { PCP_PDU_FLAG_SECURE_ACK, "SECURE_ACK" }, +#define PCP_PDU_FLAG_NO_NSS_INIT 0x20 + { PCP_PDU_FLAG_NO_NSS_INIT, "NO_NSS_INIT" }, +#define PCP_PDU_FLAG_CONTAINER 0x40 + { PCP_PDU_FLAG_CONTAINER, "CONTAINER" }, + { 0, NULL } +}; /* packet types */ static const value_string packettypenames[] = { - #define START_OR_ERROR 0x7000 - { 0x7000, "START/ERROR" }, - #define RESULT 0x7001 - { 0x7001, "RESULT" }, - #define PROFILE 0x7002 - { 0x7002, "PROFILE"}, - #define FETCH 0x7003 - { 0x7003, "FETCH"}, - #define DESC_REQ 0x7004 - { 0x7004, "DESC_REQ"}, - #define DESC 0x7005 - { 0x7005, "DESC"}, - #define INSTANCE_REQ 0x7006 - { 0x7006, "INSTANCE_REQ" }, - #define INSTANCE 0x7007 - { 0x7007, "INSTANCE" }, - #define TEXT_REQ 0x7008 - { 0x7008, "TEXT_REQ" }, - #define TEXT 0x7009 - { 0x7009, "TEXT" }, - #define CONTROL_REQ 0x700a - { 0x700a, "CONTROL_REQ" }, /* unimplemented (pmlc/pmlogger only) */ - #define DATA_X 0x700b - { 0x700b, "DATA_X" }, /* unimplemented (pmlc/pmlogger only) */ - #define CREDS 0x700c - { 0x700c, "CREDS" }, - #define PMNS_IDS 0x700d - { 0x700d, "PMNS_IDS" }, - #define PMNS_NAMES 0x700e - { 0x700e, "PMNS_NAMES" }, - #define PMNS_CHILD 0x700f - { 0x700f, "PMNS_CHILD" }, - #define PMNS_TRAVERSE 0x7010 /*also type FINISH as per pcp headers, but I can not see it used */ - { 0x7010, "PMNS_TRAVERSE" }, - { 0, NULL } +#define PCP_PDU_START_OR_ERROR 0x7000 + {PCP_PDU_START_OR_ERROR, "START/ERROR" }, +#define PCP_PDU_RESULT 0x7001 + {PCP_PDU_RESULT, "RESULT" }, +#define PCP_PDU_PROFILE 0x7002 + {PCP_PDU_PROFILE, "PROFILE"}, +#define PCP_PDU_FETCH 0x7003 + {PCP_PDU_FETCH, "FETCH"}, +#define PCP_PDU_DESC_REQ 0x7004 + {PCP_PDU_DESC_REQ, "DESC_REQ"}, +#define PCP_PDU_DESC 0x7005 + {PCP_PDU_DESC, "DESC"}, +#define PCP_PDU_INSTANCE_REQ 0x7006 + {PCP_PDU_INSTANCE_REQ, "INSTANCE_REQ" }, +#define PCP_PDU_INSTANCE 0x7007 + {PCP_PDU_INSTANCE, "INSTANCE" }, +#define PCP_PDU_TEXT_REQ 0x7008 + {PCP_PDU_TEXT_REQ, "TEXT_REQ" }, +#define PCP_PDU_TEXT 0x7009 + {PCP_PDU_TEXT, "TEXT" }, +#define PCP_PDU_CONTROL_REQ 0x700a + {PCP_PDU_CONTROL_REQ, "CONTROL_REQ" }, /* unimplemented (pmlc/pmlogger only) */ +#define PCP_PDU_DATA_X 0x700b + {PCP_PDU_DATA_X, "DATA_X" }, /* unimplemented (pmlc/pmlogger only) */ +#define PCP_PDU_CREDS 0x700c + {PCP_PDU_CREDS, "CREDS" }, +#define PCP_PDU_PMNS_IDS 0x700d + {PCP_PDU_PMNS_IDS, "PMNS_IDS" }, +#define PCP_PDU_PMNS_NAMES 0x700e + {PCP_PDU_PMNS_NAMES, "PMNS_NAMES" }, +#define PCP_PDU_PMNS_CHILD 0x700f + {PCP_PDU_PMNS_CHILD, "PMNS_CHILD" }, +#define PCP_PDU_PMNS_TRAVERSE 0x7010 /*also type FINISH as per pcp headers, but I can not see it used */ + {PCP_PDU_PMNS_TRAVERSE, "PMNS_TRAVERSE" }, +#define PCP_PDU_USER_AUTH 0x7011 + {PCP_PDU_USER_AUTH, "USER_AUTH" }, + { 0, NULL } }; static const value_string packettypenames_pm_units_space[] = { @@ -415,6 +448,7 @@ static const value_string packettypenames_creds[]= { /* function prototypes */ static guint get_pcp_message_len(packet_info *pinfo, tvbuff_t *tvb, int offset, void *data); +static const gchar *get_pcp_features_to_string(guint16 feature_flags); static int dissect_pcp_message_creds(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset); static int dissect_pcp_message_error(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset); static int dissect_pcp_message_start(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset); @@ -431,8 +465,10 @@ static int dissect_pcp_message_instance_req(tvbuff_t *tvb, packet_info *pinfo, p static int dissect_pcp_message_instance(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset); static int dissect_pcp_message_text_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset); static int dissect_pcp_message_text(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset); +static int dissect_pcp_message_user_auth(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset); static int dissect_pcp_partial_pmid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset); static int dissect_pcp_partial_when(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset); +static int dissect_pcp_partial_features(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset); /* message length for dissect_tcp */ static guint get_pcp_message_len(packet_info *pinfo _U_, tvbuff_t *tvb, @@ -442,6 +478,32 @@ static guint get_pcp_message_len(packet_info *pinfo _U_, tvbuff_t *tvb, return (guint)tvb_get_ntohl(tvb, offset); } +static const gchar *get_pcp_features_to_string(guint16 feature_flags) +{ + const value_string *flag_under_test; + wmem_strbuf_t *string_buffer; + gsize string_length; + + string_buffer = wmem_strbuf_new(wmem_packet_scope(), ""); + + /* Build the comma-separated list of feature flags as a string. EG 'SECURE, COMPRESS, AUTH, ' */ + flag_under_test = &pcp_feature_flags[0]; + while (flag_under_test->value) { + if (feature_flags & flag_under_test->value) { + wmem_strbuf_append_printf(string_buffer, "%s, ", flag_under_test->strptr); + } + flag_under_test++; + } + + /* Cleanup the last remaining ', ' from the string */ + string_length = wmem_strbuf_get_len(string_buffer); + if (string_length > 2) { + wmem_strbuf_truncate(string_buffer, string_length - 2); + } + + return wmem_strbuf_get_str(string_buffer); +} + static int dissect_pcp_message_creds(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset) { guint32 creds_length; @@ -449,27 +511,23 @@ static int dissect_pcp_message_creds(tvbuff_t *tvb, packet_info *pinfo, proto_tr /* append the type of packet */ col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", - val_to_str(CREDS, packettypenames, "Unknown Type:0x%02x")); + val_to_str(PCP_PDU_CREDS, packettypenames, "Unknown Type:0x%02x")); /* first is the number of creds */ proto_tree_add_item(tree, hf_pcp_creds_number_of, tvb, offset, 4, ENC_BIG_ENDIAN); /* store the number of creds so we know how long to interate for */ creds_length = tvb_get_ntohl(tvb, offset); offset += 4; - /* go through each __pmCreds struct */ + /* go through each __pmVersionCred struct */ for (i = 0; i < creds_length; i++) { - /* __pmCred.c_type */ + /* __pmVersionCred.c_type */ proto_tree_add_item(tree, hf_pcp_creds_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; - /* __pmCred.c_vala - Usually the PDU version */ - proto_tree_add_item(tree, hf_pcp_creds_vala, tvb, offset, 1, ENC_BIG_ENDIAN); - offset += 1; - /* __pmCred.c_valb - Unused */ - proto_tree_add_item(tree, hf_pcp_creds_valb, tvb, offset, 1, ENC_BIG_ENDIAN); - offset += 1; - /* __pmCred.c_valc - Unused */ - proto_tree_add_item(tree, hf_pcp_creds_valc, tvb, offset, 1, ENC_BIG_ENDIAN); + /* __pmVersionCred.c_version */ + proto_tree_add_item(tree, hf_pcp_creds_version, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; + /* __pmVersionCred.c_flags */ + offset = dissect_pcp_partial_features(tvb, pinfo, tree, offset); } return offset; } @@ -500,38 +558,46 @@ static int dissect_pcp_message_error(tvbuff_t *tvb, packet_info *pinfo, proto_tr |> unsigned int zero : 1 bit unsigned int version : 7 bits unsigned int licensed : 8 bits - unsigned int authorize : 16 bits + unsigned int features : 16 bits */ static int dissect_pcp_message_start(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset) { /* create a start tree tree to hold the information*/ proto_item *pcp_start_item; proto_tree *pcp_start_tree; - guint32 bits_offset; + guint32 status; pcp_start_item = proto_tree_add_item(tree, hf_pcp_start, tvb, 0, -1, ENC_NA); pcp_start_tree = proto_item_add_subtree(pcp_start_item, ett_pcp); - bits_offset = offset*8; - /* append the type of packet, we can't look this up as it clashes with ERROR */ col_append_str(pinfo->cinfo, COL_INFO, "[START]"); /* status */ + status = tvb_get_ntohl(tvb, offset); proto_tree_add_item(pcp_start_tree, hf_pcp_start_status, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; - bits_offset += 32; /* 4 bytes */ - /* zero bit and version bits */ - proto_tree_add_bits_item(pcp_start_tree, hf_pcp_start_zero, tvb, bits_offset, 1, ENC_BIG_ENDIAN); - proto_tree_add_bits_item(pcp_start_tree, hf_pcp_start_version, tvb, bits_offset+1, 7, ENC_BIG_ENDIAN); - offset += 1; - /*bits_offset += 8;*/ - /* licensed */ - proto_tree_add_item(pcp_start_tree, hf_pcp_start_licensed, tvb, offset, 1, ENC_BIG_ENDIAN); - offset += 1; - /* authorize */ - proto_tree_add_item(pcp_start_tree, hf_pcp_start_authorize, tvb, offset, 2, ENC_BIG_ENDIAN); - offset += 2; + if(tvb_reported_length_remaining(tvb, offset) == 0){ + /* Most likely we're in a SSL upgrade if this is the end of the start packet */ + if(status == PCP_SECURE_ACK_SUCCESSFUL) { + expert_add_info(pinfo, tree, &ei_pcp_ssl_upgrade); + ssl_starttls_ack(find_dissector("ssl"), pinfo, pcp_handle); + } + else { + expert_add_info(pinfo, tree, &ei_pcp_ssl_upgrade_failed); + } + } + else { + /* zero bit and version bits */ + proto_tree_add_item(pcp_start_tree, hf_pcp_start_zero, tvb, offset, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(pcp_start_tree, hf_pcp_start_version, tvb, offset, 1, ENC_BIG_ENDIAN); + offset += 1; + /* licensed */ + proto_tree_add_item(pcp_start_tree, hf_pcp_start_licensed, tvb, offset, 1, ENC_BIG_ENDIAN); + offset += 1; + /* features */ + offset = dissect_pcp_partial_features(tvb, pinfo, pcp_start_tree, offset); + } return offset; } @@ -549,7 +615,7 @@ static int dissect_pcp_message_pmns_traverse(tvbuff_t *tvb, packet_info *pinfo, /* append the type of packet */ col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", - val_to_str(PMNS_TRAVERSE, packettypenames, "Unknown Type:0x%02x")); + val_to_str(PCP_PDU_PMNS_TRAVERSE, packettypenames, "Unknown Type:0x%02x")); pcp_pmns_traverse_item = proto_tree_add_item(tree, hf_pcp_pmns_traverse, tvb, offset, -1, ENC_NA); pcp_pmns_traverse_tree = proto_item_add_subtree(pcp_pmns_traverse_item, ett_pcp); @@ -605,7 +671,7 @@ static int dissect_pcp_message_pmns_names(tvbuff_t *tvb, packet_info *pinfo, pro guint32 i; /* append the type of packet */ - col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(PMNS_NAMES, packettypenames, "Unknown Type:0x%02x")); + col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(PCP_PDU_PMNS_NAMES, packettypenames, "Unknown Type:0x%02x")); pcp_pmns_names_item = proto_tree_add_item(tree, hf_pcp_pmns_names, tvb, offset, -1, ENC_NA); pcp_pmns_names_tree = proto_item_add_subtree(pcp_pmns_names_item, ett_pcp); @@ -680,7 +746,7 @@ static int dissect_pcp_message_pmns_child(tvbuff_t *tvb, packet_info *pinfo, pro pcp_pmns_child_tree = proto_item_add_subtree(pcp_pmns_child_item, ett_pcp); /* append the type of packet */ - col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(PMNS_CHILD, packettypenames, "Unknown Type:0x%02x")); + col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(PCP_PDU_PMNS_CHILD, packettypenames, "Unknown Type:0x%02x")); /* subtype */ proto_tree_add_item(pcp_pmns_child_tree, hf_pcp_pmns_subtype, tvb, offset, 4, ENC_BIG_ENDIAN); @@ -712,7 +778,7 @@ static int dissect_pcp_message_pmns_ids(tvbuff_t *tvb, packet_info *pinfo, proto /* append the type of packet */ col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", - val_to_str(PMNS_IDS, packettypenames, "Unknown Type:0x%02x")); + val_to_str(PCP_PDU_PMNS_IDS, packettypenames, "Unknown Type:0x%02x")); pcp_pmns_ids_item = proto_tree_add_item(tree, hf_pcp_pmns_ids, tvb, offset, -1, ENC_NA); pcp_pmns_ids_tree = proto_item_add_subtree(pcp_pmns_ids_item, ett_pcp); @@ -756,7 +822,7 @@ static int dissect_pcp_message_profile(tvbuff_t *tvb, packet_info *pinfo, proto_ guint32 i; /* append the type of packet */ - col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(PROFILE, packettypenames, "Unknown Type:0x%02x")); + col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(PCP_PDU_PROFILE, packettypenames, "Unknown Type:0x%02x")); pcp_profile_item = proto_tree_add_item(tree, hf_pcp_profile, tvb, offset, -1, ENC_NA); pcp_profile_tree = proto_item_add_subtree(pcp_profile_item, ett_pcp); @@ -818,7 +884,7 @@ static int dissect_pcp_message_fetch(tvbuff_t *tvb, packet_info *pinfo, proto_tr /* append the type of packet */ col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", - val_to_str(FETCH, packettypenames, "Unknown Type:0x%02x")); + val_to_str(PCP_PDU_FETCH, packettypenames, "Unknown Type:0x%02x")); pcp_fetch_item = proto_tree_add_item(tree, hf_pcp_fetch, tvb, offset, -1, ENC_NA); pcp_fetch_tree = proto_item_add_subtree(pcp_fetch_item, ett_pcp); @@ -880,7 +946,7 @@ static int dissect_pcp_message_result(tvbuff_t *tvb, packet_info *pinfo, proto_t guint32 j; /* append the type of packet */ - col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(RESULT, packettypenames, "Unknown Type:0x%02x")); + col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(PCP_PDU_RESULT, packettypenames, "Unknown Type:0x%02x")); pcp_results_item = proto_tree_add_item(tree, hf_pcp_results, tvb, offset, -1, ENC_NA); pcp_results_tree = proto_item_add_subtree(pcp_results_item, ett_pcp); @@ -1029,7 +1095,7 @@ static int dissect_pcp_message_desc_req(tvbuff_t *tvb, packet_info *pinfo, proto guint32 bits_offset; /* append the type of packet */ - col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(DESC_REQ, packettypenames, "Unknown Type:0x%02x")); + col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(PCP_PDU_DESC_REQ, packettypenames, "Unknown Type:0x%02x")); bits_offset = offset*8; /* subtree for packet type */ @@ -1082,7 +1148,7 @@ static int dissect_pcp_message_desc(tvbuff_t *tvb, packet_info *pinfo, proto_tre guint32 bits_offset; /* append the type of packet */ - col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(DESC, packettypenames, "Unknown Type:0x%02x")); + col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(PCP_PDU_DESC, packettypenames, "Unknown Type:0x%02x")); /* root desc tree */ pcp_desc_item = proto_tree_add_item(tree, hf_pcp_desc, tvb, offset, 4, ENC_NA); @@ -1149,7 +1215,7 @@ static int dissect_pcp_message_instance_req(tvbuff_t *tvb, packet_info *pinfo, p guint32 name_len; /* append the type of packet */ - col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(INSTANCE_REQ, packettypenames, "Unknown Type:0x%02x")); + col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(PCP_PDU_INSTANCE_REQ, packettypenames, "Unknown Type:0x%02x")); pcp_instance_req_item = proto_tree_add_item(tree, hf_pcp_instance_req, tvb, offset, -1, ENC_NA); pcp_instance_req_tree = proto_item_add_subtree(pcp_instance_req_item, ett_pcp); @@ -1192,7 +1258,7 @@ static int dissect_pcp_message_text_req(tvbuff_t *tvb, packet_info *pinfo, proto guint32 type; /* append the type of packet */ - col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(TEXT_REQ, packettypenames, "Unknown Type:0x%02x")); + col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(PCP_PDU_TEXT_REQ, packettypenames, "Unknown Type:0x%02x")); pcp_text_req_item = proto_tree_add_item(tree, hf_pcp_text_req, tvb, offset, -1, ENC_NA); pcp_text_req_tree = proto_item_add_subtree(pcp_text_req_item, ett_pcp); @@ -1232,7 +1298,7 @@ static int dissect_pcp_message_text(tvbuff_t *tvb, packet_info *pinfo, proto_tre guint32 buflen; /* append the type of packet */ - col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(TEXT, packettypenames, "Unknown Type:0x%02x")); + col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(PCP_PDU_TEXT, packettypenames, "Unknown Type:0x%02x")); pcp_text_item = proto_tree_add_item(tree, hf_pcp_text, tvb, offset, -1, ENC_NA); pcp_text_tree = proto_item_add_subtree(pcp_text_item, ett_pcp); @@ -1253,6 +1319,21 @@ static int dissect_pcp_message_text(tvbuff_t *tvb, packet_info *pinfo, proto_tre return offset; } +/* USER_AUTH packet format + int ident + int buflen + char buffer +*/ +static int dissect_pcp_message_user_auth(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset) +{ + /* append the type of packet */ + col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(PCP_PDU_USER_AUTH, packettypenames, "Unknown Type:0x%02x")); + + proto_tree_add_item(tree, hf_pcp_user_auth_payload, tvb, offset, -1, ENC_NA); + + return tvb_reported_length(tvb); +} + /* INSTANCE packet type pmInDom indom int numinst @@ -1274,7 +1355,7 @@ static int dissect_pcp_message_instance(tvbuff_t *tvb, packet_info *pinfo, proto guint32 padding; /* append the type of packet */ - col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(INSTANCE, packettypenames, "Unknown Type:0x%02x")); + col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(PCP_PDU_INSTANCE, packettypenames, "Unknown Type:0x%02x")); pcp_instances_item = proto_tree_add_item(tree, hf_pcp_instances, tvb, offset, -1, ENC_NA); pcp_instances_tree = proto_item_add_subtree(pcp_instances_item, ett_pcp); @@ -1373,7 +1454,34 @@ static int dissect_pcp_partial_when(tvbuff_t *tvb, packet_info *pinfo _U_, proto return offset; } -/* MAIN DISSECTING ROUTINE (after passed from dissect_tcp, all packets hit function) */ +static int dissect_pcp_partial_features(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset) +{ + guint16 feature_flags; + const gchar *feature_flags_string; + + static const int * pcp_feature_flags_header_fields[] = { + &hf_pcp_features_flags_container, + &hf_pcp_features_flags_no_nss_init, + &hf_pcp_features_flags_secure_ack, + &hf_pcp_features_flags_creds_reqd, + &hf_pcp_features_flags_auth, + &hf_pcp_features_flags_compress, + &hf_pcp_features_flags_secure, + NULL + }; + + feature_flags = tvb_get_ntohs(tvb, offset); + feature_flags_string = get_pcp_features_to_string(feature_flags); + + col_append_fstr(pinfo->cinfo, COL_INFO, " Features=[%s]", feature_flags_string); + + proto_tree_add_bitmask(tree, tvb, offset, hf_pcp_features_flags, ett_pcp_start_features, pcp_feature_flags_header_fields, ENC_BIG_ENDIAN); + offset += 2; + + return offset; +} + +/* MAIN DISSECTING ROUTINE (after passed from dissect_tcp, all non-ssl packets hit function) */ static int dissect_pcp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) { proto_item *root_pcp_item; @@ -1410,11 +1518,11 @@ static int dissect_pcp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr /* dissect the rest of the packet depending on the type */ switch (packet_type) { - case CREDS: + case PCP_PDU_CREDS: dissect_pcp_message_creds(tvb, pinfo, pcp_tree, offset); break; - case START_OR_ERROR: + case PCP_PDU_START_OR_ERROR: err_bytes = tvb_get_ntohl(tvb, offset); /* get the first 4 bytes, determine if this is an error or not */ /* errors are signed and are all negative so check for a negative number. It's the only way we can differentiate between start/error packets */ @@ -1425,58 +1533,62 @@ static int dissect_pcp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr } break; - case PMNS_TRAVERSE: + case PCP_PDU_PMNS_TRAVERSE: dissect_pcp_message_pmns_traverse(tvb, pinfo, pcp_tree, offset); break; - case PMNS_NAMES: + case PCP_PDU_PMNS_NAMES: dissect_pcp_message_pmns_names(tvb, pinfo, pcp_tree, offset); break; - case PMNS_CHILD: + case PCP_PDU_PMNS_CHILD: dissect_pcp_message_pmns_child(tvb, pinfo, pcp_tree, offset); break; - case PMNS_IDS: + case PCP_PDU_PMNS_IDS: dissect_pcp_message_pmns_ids(tvb, pinfo, pcp_tree, offset); break; - case PROFILE: + case PCP_PDU_PROFILE: dissect_pcp_message_profile(tvb, pinfo, pcp_tree, offset); break; - case FETCH: + case PCP_PDU_FETCH: dissect_pcp_message_fetch(tvb, pinfo, pcp_tree, offset); break; - case RESULT: + case PCP_PDU_RESULT: dissect_pcp_message_result(tvb, pinfo, pcp_tree, offset); break; - case DESC_REQ: + case PCP_PDU_DESC_REQ: dissect_pcp_message_desc_req(tvb, pinfo, pcp_tree, offset); break; - case DESC: + case PCP_PDU_DESC: dissect_pcp_message_desc(tvb, pinfo, pcp_tree, offset); break; - case INSTANCE_REQ: + case PCP_PDU_INSTANCE_REQ: dissect_pcp_message_instance_req(tvb, pinfo, pcp_tree, offset); break; - case INSTANCE: + case PCP_PDU_INSTANCE: dissect_pcp_message_instance(tvb, pinfo, pcp_tree, offset); break; - case TEXT_REQ: + case PCP_PDU_TEXT_REQ: dissect_pcp_message_text_req(tvb, pinfo, pcp_tree, offset); break; - case TEXT: + case PCP_PDU_TEXT: dissect_pcp_message_text(tvb, pinfo, pcp_tree, offset); break; + case PCP_PDU_USER_AUTH: + dissect_pcp_message_user_auth(tvb, pinfo, pcp_tree, offset); + break; + default: /* append the type of packet */ col_append_str(pinfo->cinfo, COL_INFO, "[UNIMPLEMENTED TYPE]"); @@ -1489,7 +1601,7 @@ static int dissect_pcp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr static int dissect_pcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data) { - /* pass all packets through TCP-reassembally */ + /* pass all packets through TCP-reassembly */ tcp_dissect_pdus(tvb, pinfo, tree, TRUE, PCP_HEADER_LEN, get_pcp_message_len, dissect_pcp_message, data); return tvb_length(tvb); } @@ -1547,22 +1659,8 @@ void proto_register_pcp(void) NULL, HFILL } }, - { &hf_pcp_creds_vala, - { "Credentials Value A", "pcp.creds.vala", - FT_UINT8, BASE_DEC, - NULL, 0x0, - NULL, HFILL - } - }, - { &hf_pcp_creds_valb, - { "Credentials Value B", "pcp.creds.valb", - FT_UINT8, BASE_DEC, - NULL, 0x0, - NULL, HFILL - } - }, - { &hf_pcp_creds_valc, - { "Credentials Value C", "pcp.creds.valc", + { &hf_pcp_creds_version, + { "Credentials Version", "pcp.creds.version", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL @@ -1576,16 +1674,16 @@ void proto_register_pcp(void) } }, { &hf_pcp_start_zero, - { "Start Compatibility Bit", "pcp.start.zero", - FT_BOOLEAN, BASE_NONE, - NULL, 0x0, + { "Start Bit", "pcp.start.zero", + FT_BOOLEAN, 8, + TFS(&tfs_set_notset), 0x80, NULL, HFILL } }, { &hf_pcp_start_version, { "Version", "pcp.start.version", FT_UINT8, BASE_DEC, /* not a real 8 bit int, only uses 7 bits */ - NULL, 0x0, + NULL, 0x7F, NULL, HFILL } }, @@ -1603,13 +1701,62 @@ void proto_register_pcp(void) NULL, HFILL } }, - { &hf_pcp_start_authorize, - { "Authorize", "pcp.start.authorize", - FT_UINT16, BASE_DEC, + { &hf_pcp_features_flags, + { "Features", "pcp.features.flags", + FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } }, + { &hf_pcp_features_flags_secure, + { "Secure", "pcp.features.flags.secure", + FT_BOOLEAN, 16, + TFS(&tfs_set_notset), PCP_PDU_FLAG_SECURE, + NULL, HFILL + } + }, + { &hf_pcp_features_flags_compress, + { "Compression", "pcp.features.flags.compression", + FT_BOOLEAN, 16, + TFS(&tfs_set_notset), PCP_PDU_FLAG_COMPRESS, + NULL, HFILL + } + }, + { &hf_pcp_features_flags_auth, + { "Authentication", "pcp.features.flags.auth", + FT_BOOLEAN, 16, + TFS(&tfs_set_notset), PCP_PDU_FLAG_AUTH, + NULL, HFILL + } + }, + { &hf_pcp_features_flags_creds_reqd, + { "Credentials Required", "pcp.features.flags.creds_reqd", + FT_BOOLEAN, 16, + TFS(&tfs_set_notset), PCP_PDU_FLAG_CREDS_REQD, + NULL, HFILL + } + }, + { &hf_pcp_features_flags_secure_ack, + { "Secure Acknowledgement", "pcp.features.flags.secure_ack", + FT_BOOLEAN, 16, + TFS(&tfs_set_notset), PCP_PDU_FLAG_SECURE_ACK, + NULL, HFILL + } + }, + { &hf_pcp_features_flags_no_nss_init, + { "No NSS Init", "pcp.features.flags.no_nss_init", + FT_BOOLEAN, 16, + TFS(&tfs_set_notset), PCP_PDU_FLAG_NO_NSS_INIT, + NULL, HFILL + } + }, + { &hf_pcp_features_flags_container, + { "Container", "pcp.features.flags.container", + FT_BOOLEAN, 16, + TFS(&tfs_set_notset), PCP_PDU_FLAG_CONTAINER, + NULL, HFILL + } + }, { &hf_pcp_pmns_traverse, { "PMNS Traverse", "pcp.pmns_traverse", FT_NONE, BASE_NONE, @@ -2142,6 +2289,13 @@ void proto_register_pcp(void) NULL, HFILL } }, + { &hf_pcp_user_auth_payload, + { "User Authentication Payload", "pcp.user_auth_payload", + FT_NONE, BASE_NONE, + NULL, 0x0, + NULL, HFILL + } + }, }; static gint *ett[] = { @@ -2161,7 +2315,7 @@ void proto_register_pcp(void) &ett_pcp_start_zero, &ett_pcp_start_version, &ett_pcp_start_licensed, - &ett_pcp_start_authorize, + &ett_pcp_start_features, &ett_pcp_pmns_traverse, &ett_pcp_pmns_subtype, &ett_pcp_pmns_namelen, @@ -2245,6 +2399,8 @@ void proto_register_pcp(void) { &ei_pcp_type_unknown_unknown_value, { "pcp.pmid.type.unknown.unknown_value", PI_UNDECODED, PI_WARN, "PM_TYPE_UNKNOWN: Unknown Value Type", EXPFILL }}, { &ei_pcp_unimplemented_value, { "pcp.pmid.type.unimplemented", PI_UNDECODED, PI_WARN, "Unimplemented Value Type", EXPFILL }}, { &ei_pcp_unimplemented_packet_type, { "pcp.type.unimplemented", PI_UNDECODED, PI_WARN, "Unimplemented Packet Type", EXPFILL }}, + { &ei_pcp_ssl_upgrade, { "pcp.ssl_upgrade", PI_COMMENTS_GROUP, PI_COMMENT, "SSL upgrade via SECURE_ACK", EXPFILL }}, + { &ei_pcp_ssl_upgrade_failed, { "pcp.ssl_upgrade_failed", PI_RESPONSE_CODE, PI_WARN, "SSL upgrade via SECURE_ACK failed", EXPFILL }}, }; expert_module_t* expert_pcp; @@ -2260,8 +2416,6 @@ void proto_register_pcp(void) void proto_reg_handoff_pcp(void) { - dissector_handle_t pcp_handle; - pcp_handle = new_create_dissector_handle(dissect_pcp, proto_pcp); dissector_add_uint("tcp.port", PCP_PORT, pcp_handle); } |