aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-nat-pmp.c
diff options
context:
space:
mode:
authorMichael Mann <mmann78@netscape.net>2013-02-01 01:29:58 +0000
committerMichael Mann <mmann78@netscape.net>2013-02-01 01:29:58 +0000
commit73d339a5a469b18c7d222a93c252c1f1568e4f19 (patch)
tree0ad3315f66a3a78900f6764df7c3b213e50b89a5 /epan/dissectors/packet-nat-pmp.c
parent52baba10a2393440c2f2af7fb7814def8ced2cbf (diff)
Add Port Control Protocol dissector and convert NAT-PMP dissector to "new" style.
The Port Control Protocol overtakes the NAT-PMP IANA UDP ports, but is backwards compatible enough to trigger off of the version number (NAT-PMP is version 0). NAT-PMP can still use Decode As. Left the two dissectors with their own unique display filters despite a few overlapping fields. Didn't want it to turn into a BOOTP/DHCP situation. svn path=/trunk/; revision=47405
Diffstat (limited to 'epan/dissectors/packet-nat-pmp.c')
-rw-r--r--epan/dissectors/packet-nat-pmp.c503
1 files changed, 488 insertions, 15 deletions
diff --git a/epan/dissectors/packet-nat-pmp.c b/epan/dissectors/packet-nat-pmp.c
index ed435a96c7..473446e0b8 100644
--- a/epan/dissectors/packet-nat-pmp.c
+++ b/epan/dissectors/packet-nat-pmp.c
@@ -5,6 +5,14 @@
*
* Copyright 2009, Stig Bjorlykke <stig@bjorlykke.org>
*
+ * Routines for Port Control Protocol packet disassembly
+ * (backwards compatible with NAT Port Mapping protocol)
+ * http://tools.ietf.org/html/draft-ietf-pcp-base-24
+ * http://tools.ietf.org/html/draft-ietf-pcp-base-29
+ *
+ * Copyright 2012, Michael Mann
+ *
+ *
* $Id$
*
* Wireshark - Network traffic analyzer
@@ -31,14 +39,10 @@
#include <epan/packet.h>
#include <epan/expert.h>
-#define PNAME "NAT Port Mapping Protocol"
-#define PSNAME "NAT-PMP"
-#define PFNAME "nat-pmp"
-
-#define NAT_PMP_STATUS_PORT 5350
-#define NAT_PMP_PORT 5351
+#define PCP_STATUS_PORT 5350
+#define PCP_PORT 5351
-/* opcodes */
+/* NAT Port opcodes */
#define EXTERNAL_ADDRESS_REQUEST 0
#define MAP_UDP_REQUEST 1
#define MAP_TCP_REQUEST 2
@@ -46,7 +50,21 @@
#define MAP_UDP_RESPONSE 129
#define MAP_TCP_RESPONSE 130
+/* Port Control opcodes */
+#define ANNOUNCE_REQUEST 0
+#define MAP_REQUEST 1
+#define PEER_REQUEST 2
+#define ANNOUNCE_RESPONSE 128
+#define MAP_RESPONSE 129
+#define PEER_RESPONSE 130
+
+/* Port Control options */
+#define OPT_THIRD_PARTY 1
+#define OPT_PREFER_FAILURE 2
+#define OPT_FILTER 3
+
static int proto_nat_pmp = -1;
+static int proto_pcp = -1;
static int hf_version = -1;
static int hf_opcode = -1;
@@ -62,6 +80,53 @@ static int hf_pmlis = -1;
static gint ett_nat_pmp = -1;
+/* Port Control Protocol */
+static int hf_pcp_version = -1;
+static int hf_request = -1;
+static int hf_response = -1;
+static int hf_pcp_opcode = -1;
+static int hf_pcp_result_code = -1;
+static int hf_reserved1 = -1;
+static int hf_reserved2 = -1;
+static int hf_reserved8 = -1;
+static int hf_req_lifetime = -1;
+static int hf_rsp_lifetime = -1;
+static int hf_client_ip = -1;
+static int hf_epoch_time = -1;
+static int hf_map_nonce = -1;
+static int hf_map_protocol = -1;
+static int hf_map_reserved1 = -1;
+static int hf_map_internal_port = -1;
+static int hf_map_req_sug_external_port = -1;
+static int hf_map_req_sug_ext_ip = -1;
+static int hf_map_rsp_assigned_external_port = -1;
+static int hf_map_rsp_assigned_ext_ip = -1;
+static int hf_peer_nonce = -1;
+static int hf_peer_protocol = -1;
+static int hf_peer_reserved1 = -1;
+static int hf_peer_internal_port = -1;
+static int hf_peer_req_sug_external_port = -1;
+static int hf_peer_req_sug_ext_ip = -1;
+static int hf_peer_remote_peer_port = -1;
+static int hf_peer_reserved2 = -1;
+static int hf_peer_remote_peer_ip = -1;
+static int hf_peer_rsp_assigned_external_port = -1;
+static int hf_peer_rsp_assigned_ext_ip = -1;
+static int hf_option_code = -1;
+static int hf_option_reserved = -1;
+static int hf_option_length = -1;
+static int hf_option_third_party_internal_ip = -1;
+static int hf_option_filter_reserved = -1;
+static int hf_option_filter_prefix_length = -1;
+static int hf_option_filter_remote_peer_port = -1;
+static int hf_option_filter_remote_peer_ip = -1;
+
+static gint ett_pcp = -1;
+static gint ett_opcode = -1;
+static gint ett_option = -1;
+static gint ett_suboption = -1;
+
+
static const value_string opcode_vals[] = {
{ EXTERNAL_ADDRESS_REQUEST, "External Address Request" },
{ EXTERNAL_ADDRESS_RESPONSE, "External Address Response" },
@@ -82,16 +147,54 @@ static const value_string result_vals[] = {
{ 0, NULL }
};
-static void dissect_nat_pmp (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+static const value_string pcp_opcode_vals[] = {
+ { ANNOUNCE_REQUEST, "Announce Request" },
+ { MAP_REQUEST, "Map Request" },
+ { PEER_REQUEST, "Peer Request" },
+ { ANNOUNCE_RESPONSE, "Announce Response" },
+ { MAP_RESPONSE, "Map Response" },
+ { PEER_RESPONSE, "Peer Response" },
+ { 0, NULL }
+};
+
+static const value_string pcp_result_vals[] = {
+ { 0, "Success" },
+ { 1, "Unsupported Version" },
+ { 2, "Not Authorized/Refused" },
+ { 3, "Malformed Request" },
+ { 4, "Unsupported opcode" },
+ { 5, "Unsupported option" },
+ { 6, "Malformed option" },
+ { 7, "Network failure" },
+ { 8, "No resources" },
+ { 9, "Unsupported protocol" },
+ { 10, "User exceeds quota" },
+ { 11, "Cannot provide external port" },
+ { 12, "Address mismatch" },
+ { 13, "Excessive remote peers" },
+ { 0, NULL }
+};
+
+static const value_string pcp_option_vals[] = {
+ { 0, "Reserved" },
+ { OPT_THIRD_PARTY, "Third Party" },
+ { OPT_PREFER_FAILURE, "Prefer Failure" },
+ { OPT_FILTER, "Filter" },
+ { 0, NULL }
+};
+
+static int
+dissect_nat_pmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
{
proto_tree *nat_pmp_tree;
proto_item *ti, *op_ti;
- gint offset = 0;
+ gint start_offset, offset = 0;
guint8 opcode;
- col_set_str (pinfo->cinfo, COL_PROTOCOL, PSNAME);
+ col_set_str (pinfo->cinfo, COL_PROTOCOL, "NAT-PMP");
col_clear (pinfo->cinfo, COL_INFO);
+ start_offset = offset;
ti = proto_tree_add_item (tree, proto_nat_pmp, tvb, offset, -1, ENC_NA);
nat_pmp_tree = proto_item_add_subtree (ti, ett_nat_pmp);
@@ -160,6 +263,235 @@ static void dissect_nat_pmp (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
expert_add_info_format (pinfo, op_ti, PI_RESPONSE_CODE, PI_WARN, "Unknown opcode: %d", opcode);
break;
}
+
+ return (offset-start_offset);
+}
+
+static int
+dissect_portcontrol_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint8 version)
+{
+ proto_tree *pcp_tree, *opcode_tree = NULL, *option_tree, *option_sub_tree;
+ proto_item *ti, *opcode_ti, *option_ti, *suboption_ti;
+ gint offset = 0, start_offset, start_opcode_offset, start_option_offset;
+ guint8 opcode, option;
+ guint16 option_length;
+ gboolean is_response;
+ const gchar* op_str;
+
+ if (version == 1)
+ col_set_str (pinfo->cinfo, COL_PROTOCOL, "PCP v1");
+ else
+ col_set_str (pinfo->cinfo, COL_PROTOCOL, "PCP v2");
+ col_clear (pinfo->cinfo, COL_INFO);
+
+ start_offset = offset;
+ ti = proto_tree_add_item (tree, proto_pcp, tvb, offset, -1, ENC_NA);
+ pcp_tree = proto_item_add_subtree (ti, ett_pcp);
+
+ proto_tree_add_item (pcp_tree, hf_pcp_version, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset++;
+
+ opcode = tvb_get_guint8 (tvb, offset);
+ is_response = opcode & 0x80;
+ op_str = val_to_str (opcode, opcode_vals, "Unknown opcode: %d");
+ proto_item_append_text (ti, ", %s", op_str);
+ opcode_ti = proto_tree_add_item (pcp_tree, hf_pcp_opcode, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset++;
+ col_add_str (pinfo->cinfo, COL_INFO, op_str);
+
+ if (!is_response)
+ {
+ ti = proto_tree_add_boolean(pcp_tree, hf_request, tvb, offset-1, 1, is_response == FALSE);
+ PROTO_ITEM_SET_HIDDEN(ti);
+
+ proto_tree_add_item (pcp_tree, hf_reserved2, tvb, offset, 2, ENC_BIG_ENDIAN);
+ offset+=2;
+
+ proto_tree_add_item (pcp_tree, hf_req_lifetime, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset+=4;
+
+ proto_tree_add_item (pcp_tree, hf_client_ip, tvb, offset, 16, ENC_NA);
+ offset+=16;
+ }
+ else
+ {
+ ti = proto_tree_add_boolean(pcp_tree, hf_response, tvb, offset-1, 1, is_response == TRUE);
+ PROTO_ITEM_SET_HIDDEN(ti);
+
+ proto_tree_add_item (pcp_tree, hf_reserved1, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset++;
+
+ proto_tree_add_item (pcp_tree, hf_pcp_result_code, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset++;
+
+ proto_tree_add_item (pcp_tree, hf_rsp_lifetime, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset+=4;
+
+ proto_tree_add_item (pcp_tree, hf_epoch_time, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset+=4;
+
+ proto_tree_add_item (pcp_tree, hf_reserved8, tvb, offset, 8, ENC_NA);
+ offset+=8;
+ }
+
+ start_opcode_offset = offset;
+ if (match_strval(opcode, opcode_vals) != NULL)
+ {
+ opcode_ti = proto_tree_add_text(pcp_tree, tvb, offset, 0, op_str);
+ opcode_tree = proto_item_add_subtree (opcode_ti, ett_opcode);
+ }
+
+ switch(opcode) {
+
+ case ANNOUNCE_REQUEST:
+ case ANNOUNCE_RESPONSE:
+ /* No data */
+ break;
+ case MAP_REQUEST:
+ case MAP_RESPONSE:
+ if (version > 1)
+ {
+ proto_tree_add_item (opcode_tree, hf_map_nonce, tvb, offset, 12, ENC_NA);
+ offset+=12;
+ }
+
+ proto_tree_add_item (opcode_tree, hf_map_protocol, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset++;
+ proto_tree_add_item (opcode_tree, hf_map_reserved1, tvb, offset, 3, ENC_BIG_ENDIAN);
+ offset+=3;
+ proto_tree_add_item (opcode_tree, hf_map_internal_port, tvb, offset, 2, ENC_BIG_ENDIAN);
+ offset+=2;
+ if (opcode == MAP_REQUEST)
+ {
+ proto_tree_add_item (opcode_tree, hf_map_req_sug_external_port, tvb, offset, 2, ENC_BIG_ENDIAN);
+ offset+=2;
+ proto_tree_add_item (opcode_tree, hf_map_req_sug_ext_ip, tvb, offset, 16, ENC_NA);
+ offset+=16;
+ }
+ else
+ {
+ proto_tree_add_item (opcode_tree, hf_map_rsp_assigned_external_port, tvb, offset, 2, ENC_BIG_ENDIAN);
+ offset+=2;
+ proto_tree_add_item (opcode_tree, hf_map_rsp_assigned_ext_ip, tvb, offset, 16, ENC_NA);
+ offset+=16;
+ }
+ break;
+ case PEER_REQUEST:
+ case PEER_RESPONSE:
+ if (version > 1)
+ {
+ proto_tree_add_item (opcode_tree, hf_peer_nonce, tvb, offset, 12, ENC_NA);
+ offset+=12;
+ }
+
+ proto_tree_add_item (opcode_tree, hf_peer_protocol, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset++;
+ proto_tree_add_item (opcode_tree, hf_peer_reserved1, tvb, offset, 3, ENC_BIG_ENDIAN);
+ offset+=3;
+ proto_tree_add_item (opcode_tree, hf_peer_internal_port, tvb, offset, 2, ENC_BIG_ENDIAN);
+ offset+=2;
+ if (opcode == PEER_REQUEST)
+ {
+ proto_tree_add_item (opcode_tree, hf_peer_req_sug_external_port, tvb, offset, 2, ENC_BIG_ENDIAN);
+ offset+=2;
+ proto_tree_add_item (opcode_tree, hf_peer_req_sug_ext_ip, tvb, offset, 16, ENC_NA);
+ offset+=16;
+ }
+ else
+ {
+ proto_tree_add_item (opcode_tree, hf_peer_rsp_assigned_external_port, tvb, offset, 2, ENC_BIG_ENDIAN);
+ offset+=2;
+ proto_tree_add_item (opcode_tree, hf_peer_rsp_assigned_ext_ip, tvb, offset, 16, ENC_NA);
+ offset+=16;
+ }
+
+ proto_tree_add_item (opcode_tree, hf_peer_remote_peer_port, tvb, offset, 2, ENC_BIG_ENDIAN);
+ offset+=2;
+ proto_tree_add_item (opcode_tree, hf_peer_reserved2, tvb, offset, 2, ENC_BIG_ENDIAN);
+ offset+=2;
+ proto_tree_add_item (opcode_tree, hf_peer_remote_peer_ip, tvb, offset, 16, ENC_NA);
+ offset+=16;
+ break;
+ default:
+ /* Unknown OP */
+ expert_add_info_format (pinfo, opcode_ti, PI_RESPONSE_CODE, PI_WARN, "Unknown opcode: %d", opcode);
+ break;
+ }
+
+ /* Now see if there are any options for the supported opcodes */
+ if ((tvb_reported_length_remaining(tvb, offset) > 0) &&
+ (match_strval(opcode, opcode_vals) != NULL))
+ {
+ start_option_offset = offset;
+ option_ti = proto_tree_add_text(opcode_tree, tvb, offset, 0, "Options");
+ option_tree = proto_item_add_subtree (option_ti, ett_option);
+
+ while (tvb_reported_length_remaining(tvb, offset) > 0)
+ {
+ option = tvb_get_guint8(tvb, offset);
+ suboption_ti = proto_tree_add_item (option_tree, hf_option_code, tvb, offset, 1, ENC_BIG_ENDIAN);
+ option_sub_tree = proto_item_add_subtree (suboption_ti, ett_suboption);
+ offset++;
+ proto_tree_add_item (option_sub_tree, hf_option_reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset++;
+ option_length = tvb_get_ntohs(tvb, offset);
+ proto_tree_add_item (option_sub_tree, hf_option_length, tvb, offset, 2, ENC_BIG_ENDIAN);
+ offset+=2;
+ proto_item_set_len(suboption_ti, option_length+4);
+
+ if (option_length > 0)
+ {
+ switch(option) {
+
+ case OPT_THIRD_PARTY:
+ proto_tree_add_item (option_sub_tree, hf_option_third_party_internal_ip, tvb, offset, 16, ENC_NA);
+ break;
+
+ case OPT_PREFER_FAILURE:
+ /* No data */
+ break;
+
+ case OPT_FILTER:
+ proto_tree_add_item (option_sub_tree, hf_option_filter_reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item (option_sub_tree, hf_option_filter_prefix_length, tvb, offset+1, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item (option_sub_tree, hf_option_filter_remote_peer_port, tvb, offset+2, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item (option_sub_tree, hf_option_filter_remote_peer_ip, tvb, offset+4, 16, ENC_BIG_ENDIAN);
+ break;
+
+ default:
+ /* Unknown option */
+ expert_add_info_format (pinfo, option_ti, PI_RESPONSE_CODE, PI_WARN, "Unknown option: %d", option);
+ break;
+ }
+ }
+
+ offset+=option_length;
+ }
+
+ proto_item_set_len(option_ti, offset-start_option_offset);
+ }
+
+ proto_item_set_len(opcode_ti, offset-start_opcode_offset);
+
+ return (offset-start_offset);
+}
+
+static int
+dissect_portcontrol(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
+{
+ guint8 version = tvb_get_guint8 (tvb, 0);
+
+ switch(version)
+ {
+ case 0:
+ /* NAT-PMP protocol */
+ return dissect_nat_pmp(tvb, pinfo, tree, data);
+ case 1:
+ case 2:
+ return dissect_portcontrol_pdu(tvb, pinfo, tree, version);
+ }
+
+ return 0;
}
void proto_register_nat_pmp (void)
@@ -200,24 +532,165 @@ void proto_register_nat_pmp (void)
NULL, 0x0, "Port Mapping Lifetime in Seconds", HFILL } },
};
+ static hf_register_info pcp_hf[] = {
+ { &hf_pcp_version,
+ { "Version", "portcontrol.version", FT_UINT8, BASE_DEC,
+ NULL, 0x0, NULL, HFILL } },
+ { &hf_request,
+ { "Request", "portcontrol.request", FT_BOOLEAN, 8,
+ NULL, 0x01, NULL, HFILL } },
+ { &hf_response,
+ { "Response", "portcontrol.response", FT_BOOLEAN, 8,
+ NULL, 0x01, NULL, HFILL } },
+ { &hf_pcp_opcode,
+ { "Opcode", "portcontrol.opcode", FT_UINT8, BASE_DEC,
+ VALS(pcp_opcode_vals), 0x0, NULL, HFILL } },
+ { &hf_pcp_result_code,
+ { "Result Code", "portcontrol.result_code", FT_UINT16, BASE_DEC,
+ VALS(pcp_result_vals), 0x0, NULL, HFILL } },
+ { &hf_reserved1,
+ { "Reserved", "portcontrol.reserved", FT_UINT8, BASE_DEC,
+ NULL, 0x0, NULL, HFILL } },
+ { &hf_reserved2,
+ { "Reserved", "portcontrol.reserved", FT_UINT16, BASE_DEC,
+ NULL, 0x0, NULL, HFILL } },
+ { &hf_reserved8,
+ { "Reserved", "portcontrol.rsp_reserved", FT_BYTES, BASE_NONE,
+ NULL, 0x0, NULL, HFILL } },
+ { &hf_req_lifetime,
+ { "Requested Lifetime", "portcontrol.lifetime_req", FT_UINT32, BASE_DEC,
+ NULL, 0x0, NULL, HFILL } },
+ { &hf_rsp_lifetime,
+ { "Lifetime", "portcontrol.lifetime_rsp", FT_UINT32, BASE_DEC,
+ NULL, 0x0, NULL, HFILL } },
+ { &hf_client_ip,
+ { "Client IP Address", "portcontrol.client_ip", FT_IPv6, BASE_NONE,
+ NULL, 0x0, NULL, HFILL } },
+ { &hf_epoch_time,
+ { "Epoch Time", "portcontrol.epoch_time", FT_UINT32, BASE_DEC,
+ NULL, 0x0, NULL, HFILL } },
+ { &hf_map_nonce,
+ { "Mapping Nonce", "portcontrol.map.nonce", FT_BYTES, BASE_NONE,
+ NULL, 0x0, NULL, HFILL } },
+ { &hf_map_protocol,
+ { "Protocol", "portcontrol.map.protocol", FT_UINT8, BASE_DEC,
+ NULL, 0x0, NULL, HFILL } },
+ { &hf_map_reserved1,
+ { "Reserved", "portcontrol.map.reserved", FT_UINT24, BASE_DEC,
+ NULL, 0x0, NULL, HFILL } },
+ { &hf_map_internal_port,
+ { "Internal Port", "portcontrol.map.internal_port", FT_UINT16, BASE_DEC,
+ NULL, 0x0, NULL, HFILL } },
+ { &hf_map_req_sug_external_port,
+ { "Suggested External Port", "portcontrol.map.req_sug_external_port", FT_UINT16, BASE_DEC,
+ NULL, 0x0, NULL, HFILL } },
+ { &hf_map_req_sug_ext_ip,
+ { "Suggested External IP Address", "portcontrol.map.req_sug_external_ip", FT_IPv6, BASE_NONE,
+ NULL, 0x0, NULL, HFILL } },
+ { &hf_map_rsp_assigned_external_port,
+ { "Assigned External Port", "portcontrol.map.rsp_assigned_external_port", FT_UINT16, BASE_DEC,
+ NULL, 0x0, NULL, HFILL } },
+ { &hf_map_rsp_assigned_ext_ip,
+ { "Assigned External IP Address", "portcontrol.map.rsp_assigned_ext_ip", FT_IPv6, BASE_NONE,
+ NULL, 0x0, NULL, HFILL } },
+ { &hf_peer_nonce,
+ { "Mapping Nonce", "portcontrol.peer.nonce", FT_BYTES, BASE_NONE,
+ NULL, 0x0, NULL, HFILL } },
+ { &hf_peer_protocol,
+ { "Protocol", "portcontrol.peer.protocol", FT_UINT8, BASE_DEC,
+ NULL, 0x0, NULL, HFILL } },
+ { &hf_peer_reserved1,
+ { "Reserved", "portcontrol.peer.reserved", FT_UINT24, BASE_DEC,
+ NULL, 0x0, NULL, HFILL } },
+ { &hf_peer_internal_port,
+ { "Internal Port", "portcontrol.peer.internal_port", FT_UINT16, BASE_DEC,
+ NULL, 0x0, NULL, HFILL } },
+ { &hf_peer_req_sug_external_port,
+ { "Suggested External Port", "portcontrol.peer.req_sug_external_port", FT_UINT16, BASE_DEC,
+ NULL, 0x0, NULL, HFILL } },
+ { &hf_peer_req_sug_ext_ip,
+ { "Suggested External IP Address", "portcontrol.peer.req_sug_external_ip", FT_IPv6, BASE_NONE,
+ NULL, 0x0, NULL, HFILL } },
+ { &hf_peer_remote_peer_port,
+ { "Remote Peer Port", "portcontrol.peer.remote_peer_port", FT_UINT16, BASE_DEC,
+ NULL, 0x0, NULL, HFILL } },
+ { &hf_peer_reserved2,
+ { "Reserved", "portcontrol.peer.reserved", FT_UINT16, BASE_DEC,
+ NULL, 0x0, NULL, HFILL } },
+ { &hf_peer_remote_peer_ip,
+ { "Remote Peer IP Address", "portcontrol.peer.remote_peer_ip", FT_IPv6, BASE_NONE,
+ NULL, 0x0, NULL, HFILL } },
+ { &hf_peer_rsp_assigned_external_port,
+ { "Assigned External Port", "portcontrol.peer.rsp_assigned_external_port", FT_UINT16, BASE_DEC,
+ NULL, 0x0, NULL, HFILL } },
+ { &hf_peer_rsp_assigned_ext_ip,
+ { "Assigned External IP Address", "portcontrol.peer.rsp_assigned_ext_ip", FT_IPv6, BASE_NONE,
+ NULL, 0x0, NULL, HFILL } },
+ { &hf_option_code,
+ { "Option", "portcontrol.option", FT_UINT8, BASE_DEC,
+ VALS(pcp_option_vals), 0x0, NULL, HFILL } },
+ { &hf_option_reserved,
+ { "Reserved", "portcontrol.option.reserved", FT_UINT8, BASE_DEC,
+ NULL, 0x0, NULL, HFILL } },
+ { &hf_option_length,
+ { "Option Length", "portcontrol.option.length", FT_UINT16, BASE_DEC,
+ NULL, 0x0, NULL, HFILL } },
+ { &hf_option_third_party_internal_ip,
+ { "Internal IP Address", "portcontrol.option.third_party.internal_ip", FT_IPv6, BASE_NONE,
+ NULL, 0x0, NULL, HFILL } },
+ { &hf_option_filter_reserved,
+ { "Reserved", "portcontrol.option.filter.reserved", FT_UINT8, BASE_DEC,
+ NULL, 0x0, NULL, HFILL } },
+ { &hf_option_filter_prefix_length,
+ { "Prefix Length", "portcontrol.option.filter.prefix_length", FT_UINT8, BASE_DEC,
+ NULL, 0x0, NULL, HFILL } },
+ { &hf_option_filter_remote_peer_port,
+ { "Remote Peer Port", "portcontrol.option.filter.remote_peer_port", FT_UINT16, BASE_DEC,
+ NULL, 0x0, NULL, HFILL } },
+ { &hf_option_filter_remote_peer_ip,
+ { "Remote Peer IP Address", "portcontrol.option.filter.remote_peer_ip", FT_IPv6, BASE_NONE,
+ NULL, 0x0, NULL, HFILL } },
+ };
+
+ static gint *pcp_ett[] = {
+ &ett_pcp,
+ &ett_opcode,
+ &ett_option,
+ &ett_suboption
+ };
+
static gint *ett[] = {
&ett_nat_pmp,
};
- proto_nat_pmp = proto_register_protocol (PNAME, PSNAME, PFNAME);
- register_dissector (PFNAME, dissect_nat_pmp, proto_nat_pmp);
+ proto_nat_pmp = proto_register_protocol ("NAT Port Mapping Protocol", "NAT-PMP", "nat-pmp");
proto_register_field_array (proto_nat_pmp, hf, array_length (hf));
proto_register_subtree_array (ett, array_length (ett));
+
+ proto_pcp = proto_register_protocol ("Port Control Protocol", "Port Control", "portcontrol");
+
+ proto_register_field_array (proto_pcp, pcp_hf, array_length (pcp_hf));
+ proto_register_subtree_array (pcp_ett, array_length (pcp_ett));
+
}
void proto_reg_handoff_nat_pmp (void)
{
dissector_handle_t nat_pmp_handle;
+ dissector_handle_t pcp_handle;
+
+
+ pcp_handle = new_create_dissector_handle(dissect_portcontrol, proto_pcp);
+ dissector_add_uint ("udp.port", PCP_STATUS_PORT, pcp_handle);
+ dissector_add_uint ("udp.port", PCP_PORT, pcp_handle);
- nat_pmp_handle = find_dissector (PFNAME);
- dissector_add_uint ("udp.port", NAT_PMP_STATUS_PORT, nat_pmp_handle);
- dissector_add_uint ("udp.port", NAT_PMP_PORT, nat_pmp_handle);
+ nat_pmp_handle = new_create_dissector_handle(dissect_nat_pmp, proto_nat_pmp);
+ /* Port Control Protocol (packet-portcontrol.c) shares the same UDP ports as
+ NAT-PMP, but it backwards compatible. However, still let NAT-PMP
+ use Decode As
+ */
+ dissector_add_handle("udp.port", nat_pmp_handle);
}
/*