wireshark/epan/dissectors/packet-uasip.c
Guy Harris 2c44a7f930 Clean up handling of enabled/disabled protocols/heuristic dissectors.
Add a "report a warning message" routine to the "report_err" code in
libwsutil, and rename files and routines appropriately, as they don't
only handle errors any more.

Have a routine read_enabled_and_disabled_protos() that reads all the
files that enable or disable protocols or heuristic dissectors, enables
and disables them based on the contents of those files, and reports
errors itself (as warnings) using the new "report a warning message"
routine.  Fix that error reporting to report separately on the disabled
protocols, enabled protocols, and heuristic dissectors files.

Have a routine to set up the enabled and disabled protocols and
heuristic dissectors from the command-line arguments, so it's done the
same way in all programs.

If we try to enable or disable an unknown heuristic dissector via a
command-line argument, report an error.

Update a bunch of comments.

Update the name of disabled_protos_cleanup(), as it cleans up
information for disabled *and* enabled protocols and for heuristic
dissectors.

Support the command-line flags to enable and disable protocols and
heuristic dissectors in tfshark.

Change-Id: I9b8bd29947cccdf6dc34a0540b5509ef941391df
Reviewed-on: https://code.wireshark.org/review/20966
Reviewed-by: Guy Harris <guy@alum.mit.edu>
2017-04-08 20:40:08 +00:00

505 lines
15 KiB
C

/* packet-uasip.c
* Routines for UA/UDP (Universal Alcatel over UDP) and NOE/SIP packet dissection.
* Copyright 2012, Alcatel-Lucent Enterprise <lars.ruoff@alcatel-lucent.com>
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "config.h"
#include "epan/packet.h"
#include "epan/prefs.h"
#if 0
#include <epan/tap.h>
#endif
#include <epan/addr_resolv.h>
#include <wsutil/report_message.h>
#include "packet-uaudp.h"
void proto_register_uasip(void);
void proto_reg_handoff_uasip(void);
static tap_struct_uaudp ua_tap_info;
#if 0
static int uasip_tap = -1;
#endif
static int proto_uasip = -1;
static int hf_uasip_opcode = -1;
static int hf_uasip_version = -1;
static int hf_uasip_window_size = -1;
static int hf_uasip_mtu = -1;
static int hf_uasip_udp_lost = -1;
static int hf_uasip_udp_lost_reinit = -1;
static int hf_uasip_keepalive = -1;
static int hf_uasip_qos_ip_tos = -1;
static int hf_uasip_qos_8021_vlid = -1;
static int hf_uasip_qos_8021_pri = -1;
static int hf_uasip_expseq = -1;
static int hf_uasip_sntseq = -1;
static gint ett_uasip = -1;
static guint8 proxy_ipaddr[4];
static const char *pref_proxy_ipaddr_s = NULL;
static gboolean uasip_enabled = FALSE;
static gboolean use_proxy_ipaddr = FALSE;
static gboolean noesip_enabled = FALSE;
static dissector_handle_t uasip_handle;
static dissector_handle_t ua_sys_to_term_handle;
static dissector_handle_t ua_term_to_sys_handle;
static void rTLV(proto_tree *tree, int *V, tvbuff_t *tvb, gint offset, gint8 L)
{
switch (L)
{
case 1:
proto_tree_add_uint(tree, *V, tvb, offset, L+2, tvb_get_guint8(tvb, offset+2));
break;
case 2:
proto_tree_add_uint(tree, *V, tvb, offset, L+2, tvb_get_ntohs(tvb, offset+2));
break;
case 3:
proto_tree_add_uint(tree, *V, tvb, offset, L+2, tvb_get_ntoh24(tvb, offset+2));
break;
case 4:
proto_tree_add_uint(tree, *V, tvb, offset, L+2, tvb_get_ntohl(tvb, offset+2));
break;
default:
break;
}
}
static void _dissect_uasip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, e_ua_direction direction)
{
proto_item *uasip_item;
proto_tree *uasip_tree;
guint8 opcode;
gint offset = 0;
if (noesip_enabled)
{
col_append_str(pinfo->cinfo, COL_PROTOCOL, "/NOE");
}
else
{
col_append_str(pinfo->cinfo, COL_PROTOCOL, "/DL");
}
opcode = tvb_get_guint8(tvb, offset);
offset++;
ua_tap_info.opcode = opcode;
ua_tap_info.expseq = 0;
ua_tap_info.sntseq = 0;
col_add_fstr(pinfo->cinfo, COL_INFO, "%s", val_to_str_ext(opcode, &uaudp_opcode_str_ext, "unknown (0x%02x)"));
uasip_item = proto_tree_add_protocol_format(tree, proto_uasip, tvb, 0, 5,
"SIP/NOE Protocol, %s",
val_to_str_ext(opcode, &uaudp_opcode_str_ext, "unknown (0x%02x)"));
uasip_tree = proto_item_add_subtree(uasip_item, ett_uasip);
proto_tree_add_uint(uasip_tree, hf_uasip_opcode, tvb, 0, 1, opcode);
switch(opcode)
{
case UAUDP_CONNECT:
{
if (!tree)
break;
while(tvb_offset_exists(tvb, offset))
{
guint8 T = tvb_get_guint8(tvb, offset+0);
guint8 L = tvb_get_guint8(tvb, offset+1);
switch(T)
{
case UAUDP_CONNECT_VERSION:
rTLV(uasip_tree, &hf_uasip_version, tvb, offset, L);
break;
case UAUDP_CONNECT_WINDOW_SIZE:
rTLV(uasip_tree, &hf_uasip_window_size, tvb, offset, L);
break;
case UAUDP_CONNECT_MTU:
rTLV(uasip_tree, &hf_uasip_mtu, tvb, offset, L);
break;
case UAUDP_CONNECT_UDP_LOST:
rTLV(uasip_tree, &hf_uasip_udp_lost, tvb, offset, L);
break;
case UAUDP_CONNECT_UDP_LOST_REINIT:
rTLV(uasip_tree, &hf_uasip_udp_lost_reinit, tvb, offset, L);
break;
case UAUDP_CONNECT_KEEPALIVE:
rTLV(uasip_tree, &hf_uasip_keepalive, tvb, offset, L);
break;
case UAUDP_CONNECT_QOS_IP_TOS:
rTLV(uasip_tree, &hf_uasip_qos_ip_tos, tvb, offset, L);
break;
case UAUDP_CONNECT_QOS_8021_VLID:
rTLV(uasip_tree, &hf_uasip_qos_8021_vlid, tvb, offset, L);
break;
case UAUDP_CONNECT_QOS_8021_PRI:
rTLV(uasip_tree, &hf_uasip_qos_8021_pri, tvb, offset, L);
break;
default:
break;
}
offset += (2 + L);
}
}
break;
case UAUDP_NACK:
{
proto_tree_add_uint(uasip_tree, hf_uasip_expseq, tvb, offset, 2, tvb_get_ntohs(tvb, offset));
ua_tap_info.expseq = tvb_get_ntohs(tvb, offset+0);
/*offset += 2;*/
if (noesip_enabled)
{
col_add_fstr(pinfo->cinfo, COL_INFO, "NACK");
}
else
{
col_add_fstr(pinfo->cinfo, COL_INFO, "NACK exp:%d", ua_tap_info.expseq);
}
}
break;
case UAUDP_DATA:
{
int datalen;
proto_tree_add_uint(uasip_tree, hf_uasip_expseq, tvb, offset+0, 2, tvb_get_ntohs(tvb, offset+0));
proto_tree_add_uint(uasip_tree, hf_uasip_sntseq, tvb, offset+2, 2, tvb_get_ntohs(tvb, offset+2));
ua_tap_info.expseq = tvb_get_ntohs(tvb, offset+0);
ua_tap_info.sntseq = tvb_get_ntohs(tvb, offset+2);
offset += 4;
datalen = (tvb_reported_length(tvb) - offset);
if (noesip_enabled)
{
if (datalen > 0)
{
if (direction == SYS_TO_TERM)
{
call_dissector(ua_sys_to_term_handle, tvb_new_subset_length(tvb, offset, datalen), pinfo, tree);
}
else if (direction == TERM_TO_SYS)
{
call_dissector(ua_term_to_sys_handle, tvb_new_subset_length(tvb, offset, datalen), pinfo, tree);
}
else
{
col_add_str(pinfo->cinfo, COL_INFO, "DATA - Couldn't resolve direction.");
}
}
else
{
col_add_str(pinfo->cinfo, COL_INFO, "ACK");
}
}
else
{
if (datalen > 0)
{
col_add_fstr(pinfo->cinfo, COL_INFO, "DATA exp:%d", ua_tap_info.expseq);
col_append_fstr(pinfo->cinfo, COL_INFO, " snt:%d", ua_tap_info.sntseq);
}
else
{
col_add_fstr(pinfo->cinfo, COL_INFO, "ACK exp:%d", ua_tap_info.expseq);
col_append_fstr(pinfo->cinfo, COL_INFO, " snt:%d", ua_tap_info.sntseq);
}
}
}
break;
default:
break;
}
#if 0
tap_queue_packet(uasip_tap, pinfo, &ua_tap_info);
#endif
}
static int dissect_uasip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
{
if (use_proxy_ipaddr)
{
if (memcmp((pinfo->src).data, proxy_ipaddr, sizeof(proxy_ipaddr)) == 0)
{
_dissect_uasip(tvb, pinfo, tree, SYS_TO_TERM);
return tvb_captured_length(tvb);
}
else if (memcmp((pinfo->dst).data, proxy_ipaddr, sizeof(proxy_ipaddr)) == 0)
{
_dissect_uasip(tvb, pinfo, tree, TERM_TO_SYS);
return tvb_captured_length(tvb);
}
}
_dissect_uasip(tvb, pinfo, tree, DIR_UNKNOWN);
return tvb_captured_length(tvb);
}
void proto_register_uasip(void)
{
module_t *uasip_module;
static hf_register_info hf_uasip[] = {
{
&hf_uasip_opcode,
{
"Opcode",
"uasip.opcode",
FT_UINT8,
BASE_DEC | BASE_EXT_STRING,
&uaudp_opcode_str_ext,
0x0,
"UA/SIP Opcode",
HFILL
}
},
{
&hf_uasip_version,
{
"Version",
"uasip.version",
FT_UINT8,
BASE_DEC,
NULL,
0x0,
"UA/SIP Version",
HFILL
}
},
{
&hf_uasip_window_size,
{
"Window Size",
"uasip.window_size",
FT_UINT8,
BASE_DEC,
NULL,
0x0,
"UA/SIP Window Size",
HFILL
}
},
{
&hf_uasip_mtu,
{
"MTU",
"uasip.mtu",
FT_UINT8,
BASE_DEC,
NULL,
0x0,
"UA/SIP MTU",
HFILL
}
},
{
&hf_uasip_udp_lost,
{
"UDP Lost",
"uasip.udp_lost",
FT_UINT8,
BASE_DEC,
NULL,
0x0,
"UA/SIP Lost",
HFILL
}
},
{
&hf_uasip_udp_lost_reinit,
{
"UDP lost reinit",
"uasip.udp_lost_reinit",
FT_UINT8,
BASE_DEC,
NULL,
0x0,
"UA/SIP Lost Re-Init",
HFILL
}
},
{
&hf_uasip_keepalive,
{
"Keepalive",
"uasip.keepalive",
FT_UINT8,
BASE_DEC,
NULL,
0x0,
"UA/SIP Keepalive",
HFILL
}
},
{
&hf_uasip_qos_ip_tos,
{
"QoS IP TOS",
"uasip.qos_ip_tos",
FT_UINT8,
BASE_DEC,
NULL,
0x0,
"UA/SIP QoS IP TOS",
HFILL
}
},
{
&hf_uasip_qos_8021_vlid,
{
"QoS 802.1 VLID",
"uasip.qos_8021_vlid",
FT_UINT8,
BASE_DEC,
NULL,
0x0,
"UA/SIP QoS 802.1 VLID",
HFILL
}
},
{
&hf_uasip_qos_8021_pri,
{
"QoS 802.1 PRI",
"uasip.qos_8021_pri",
FT_UINT8,
BASE_DEC,
NULL,
0x0,
"UA/SIP QoS 802.1 PRI",
HFILL
}
},
{
&hf_uasip_expseq,
{
"Sequence Number (expected)",
"uasip.expseq",
FT_UINT16,
BASE_DEC,
NULL,
0x0,
"UA/SIP Expected Sequence Number",
HFILL
}
},
{
&hf_uasip_sntseq,
{
"Sequence Number (sent)",
"uasip.sntseq",
FT_UINT16,
BASE_DEC,
NULL,
0x0,
"UA/SIP Sent Sequence Number",
HFILL
}
},
};
static gint *ett[] =
{
&ett_uasip,
};
proto_uasip = proto_register_protocol("UA/SIP Protocol", "UASIP", "uasip");
uasip_handle = register_dissector("uasip", dissect_uasip, proto_uasip);
proto_register_field_array(proto_uasip, hf_uasip, array_length(hf_uasip));
proto_register_subtree_array(ett, array_length(ett));
uasip_module = prefs_register_protocol(proto_uasip, proto_reg_handoff_uasip);
prefs_register_bool_preference(uasip_module, "aplication_octet_stream", "Try to decode application/octet-stream as UASIP", "UA SIP Protocol enabled", &uasip_enabled);
prefs_register_bool_preference(uasip_module, "noesip", "Try to decode SIP NOE", "NOE SIP Protocol", &noesip_enabled);
prefs_register_string_preference(uasip_module, "proxy_ipaddr", "Proxy IP Address",
"IPv4 address of the proxy (Invalid values will be ignored)",
&pref_proxy_ipaddr_s);
#if 0
uasip_tap = register_tap("uasip");
#endif
}
void proto_reg_handoff_uasip(void)
{
static gboolean prefs_initialized = FALSE;
if (!prefs_initialized)
{
ua_sys_to_term_handle = find_dissector_add_dependency("ua_sys_to_term", proto_uasip);
ua_term_to_sys_handle = find_dissector_add_dependency("ua_term_to_sys", proto_uasip);
prefs_initialized = TRUE;
}
use_proxy_ipaddr = FALSE;
memset(proxy_ipaddr, 0, sizeof(proxy_ipaddr));
if(uasip_enabled){
dissector_add_string("media_type", "application/octet-stream", uasip_handle);
}else{
dissector_delete_string("media_type", "application/octet-stream", uasip_handle);
}
if (strcmp(pref_proxy_ipaddr_s, "") != 0) {
if (str_to_ip(pref_proxy_ipaddr_s, proxy_ipaddr)) {
use_proxy_ipaddr = TRUE;
} else {
report_failure("uasip: Invalid 'Proxy IP Address': \"%s\"", pref_proxy_ipaddr_s);
}
}
}
/*
* Editor modelines - http://www.wireshark.org/tools/modelines.html
*
* Local variables:
* c-basic-offset: 4
* tab-width: 8
* indent-tabs-mode: nil
* End:
*
* vi: set shiftwidth=4 tabstop=8 expandtab:
* :indentSize=4:tabSize=8:noTabs=true:
*/