summaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-ip.c
diff options
context:
space:
mode:
Diffstat (limited to 'epan/dissectors/packet-ip.c')
-rw-r--r--epan/dissectors/packet-ip.c798
1 files changed, 462 insertions, 336 deletions
diff --git a/epan/dissectors/packet-ip.c b/epan/dissectors/packet-ip.c
index 481d3725..6a633b7a 100644
--- a/epan/dissectors/packet-ip.c
+++ b/epan/dissectors/packet-ip.c
@@ -49,224 +49,234 @@
#include "packet-vxlan.h"
#include "packet-mpls.h"
#include "packet-nsh.h"
+#include "packet-eth.h"
void proto_register_ip(void);
void proto_reg_handoff_ip(void);
-static int ip_tap = -1;
+static int ip_tap;
-static int exported_pdu_tap = -1;
+static int exported_pdu_tap;
/* Decode the old IPv4 TOS field as the DiffServ DS Field (RFC2474/2475) */
-static gboolean g_ip_dscp_actif = TRUE;
+static bool g_ip_dscp_actif = true;
/* Defragment fragmented IP datagrams */
-static gboolean ip_defragment = TRUE;
+static bool ip_defragment = true;
/* Place IP summary in proto tree */
-static gboolean ip_summary_in_tree = TRUE;
+static bool ip_summary_in_tree = true;
/* Perform IP checksum */
-static gboolean ip_check_checksum = FALSE;
+static bool ip_check_checksum;
/* Assume TSO and correct zero-length IP packets */
-static gboolean ip_tso_supported = TRUE;
+static bool ip_tso_supported = true;
/* Use heuristics to determine subdissector */
-static gboolean try_heuristic_first = FALSE;
+static bool try_heuristic_first;
/* Interpret the reserved flag as security flag (RFC 3514) */
-static gboolean ip_security_flag = FALSE;
-
-static int proto_ip = -1;
-
-static int proto_ip_option_eol = -1;
-static int proto_ip_option_nop = -1;
-static int proto_ip_option_security = -1;
-static int proto_ip_option_route = -1;
-static int proto_ip_option_timestamp = -1;
-static int proto_ip_option_ext_security = -1;
-static int proto_ip_option_cipso = -1;
-static int proto_ip_option_record_route = -1;
-static int proto_ip_option_sid = -1;
-static int proto_ip_option_source_route = -1;
-static int proto_ip_option_mtu_probe = -1;
-static int proto_ip_option_mtu_reply = -1;
-static int proto_ip_option_traceroute = -1;
-static int proto_ip_option_routeralert = -1;
-static int proto_ip_option_sdb = -1;
-static int proto_ip_option_qs = -1;
-static int hf_ip_version = -1;
-static int hf_ip_hdr_len = -1;
-static int hf_ip_dsfield = -1;
-static int hf_ip_dsfield_dscp = -1;
-static int hf_ip_dsfield_ecn = -1;
-static int hf_ip_tos = -1;
-static int hf_ip_tos_precedence = -1;
-static int hf_ip_tos_delay = -1;
-static int hf_ip_tos_throughput = -1;
-static int hf_ip_tos_reliability = -1;
-static int hf_ip_tos_cost = -1;
-static int hf_ip_len = -1;
-static int hf_ip_id = -1;
-static int hf_ip_dst = -1;
-static int hf_ip_dst_host = -1;
-static int hf_ip_src = -1;
-static int hf_ip_src_host = -1;
-static int hf_ip_addr = -1;
-static int hf_ip_host = -1;
-static int hf_ip_flags = -1;
-static int hf_ip_flags_sf = -1;
-static int hf_ip_flags_rf = -1;
-static int hf_ip_flags_df = -1;
-static int hf_ip_flags_mf = -1;
-static int hf_ip_frag_offset = -1;
-static int hf_ip_ttl = -1;
-static int hf_ip_proto = -1;
-static int hf_ip_checksum = -1;
-static int hf_ip_checksum_calculated = -1;
-static int hf_ip_checksum_status = -1;
+static bool ip_security_flag;
+
+/* Aggregate subnets in Statistics Endpoints/Conversations Dialogs
+ * defaults to false to not impact resources
+ */
+static bool ip_conv_agg_flag = false;
+
+static int proto_ip;
+
+static int proto_ip_option_eol;
+static int proto_ip_option_nop;
+static int proto_ip_option_security;
+static int proto_ip_option_route;
+static int proto_ip_option_timestamp;
+static int proto_ip_option_ext_security;
+static int proto_ip_option_cipso;
+static int proto_ip_option_record_route;
+static int proto_ip_option_sid;
+static int proto_ip_option_source_route;
+static int proto_ip_option_mtu_probe;
+static int proto_ip_option_mtu_reply;
+static int proto_ip_option_traceroute;
+static int proto_ip_option_routeralert;
+static int proto_ip_option_sdb;
+static int proto_ip_option_qs;
+static int hf_ip_version;
+static int hf_ip_hdr_len;
+static int hf_ip_dsfield;
+static int hf_ip_dsfield_dscp;
+static int hf_ip_dsfield_ecn;
+static int hf_ip_tos;
+static int hf_ip_tos_precedence;
+static int hf_ip_tos_delay;
+static int hf_ip_tos_throughput;
+static int hf_ip_tos_reliability;
+static int hf_ip_tos_cost;
+static int hf_ip_len;
+static int hf_ip_id;
+static int hf_ip_dst;
+static int hf_ip_dst_host;
+static int hf_ip_src;
+static int hf_ip_src_host;
+static int hf_ip_addr;
+static int hf_ip_host;
+static int hf_ip_flags;
+static int hf_ip_flags_sf;
+static int hf_ip_flags_rf;
+static int hf_ip_flags_df;
+static int hf_ip_flags_mf;
+static int hf_ip_frag_offset;
+static int hf_ip_ttl;
+static int hf_ip_proto;
+static int hf_ip_checksum;
+static int hf_ip_checksum_calculated;
+static int hf_ip_checksum_status;
+static int hf_ip_stream;
/* IP option fields */
-static int hf_ip_opt_type = -1;
-static int hf_ip_opt_type_copy = -1;
-static int hf_ip_opt_type_class = -1;
-static int hf_ip_opt_type_number = -1;
-static int hf_ip_opt_len = -1;
-static int hf_ip_opt_ptr = -1;
-static int hf_ip_opt_sid = -1;
-static int hf_ip_opt_mtu = -1;
-static int hf_ip_opt_id_number = -1;
-static int hf_ip_opt_ohc = -1;
-static int hf_ip_opt_rhc = -1;
-static int hf_ip_opt_originator = -1;
-static int hf_ip_opt_ra = -1;
-static int hf_ip_opt_addr = -1;
-static int hf_ip_opt_padding = -1;
-static int hf_ip_opt_qs_func = -1;
-static int hf_ip_opt_qs_rate = -1;
-static int hf_ip_opt_qs_ttl = -1;
-static int hf_ip_opt_qs_ttl_diff = -1;
-static int hf_ip_opt_qs_unused = -1;
-static int hf_ip_opt_qs_nonce = -1;
-static int hf_ip_opt_qs_reserved = -1;
-static int hf_ip_opt_sec_rfc791_sec = -1;
-static int hf_ip_opt_sec_rfc791_comp = -1;
-static int hf_ip_opt_sec_rfc791_hr = -1;
-static int hf_ip_opt_sec_rfc791_tcc = -1;
-static int hf_ip_opt_sec_cl = -1;
-static int hf_ip_opt_sec_prot_auth_flags = -1;
-static int hf_ip_opt_sec_prot_auth_genser = -1;
-static int hf_ip_opt_sec_prot_auth_siop_esi = -1;
-static int hf_ip_opt_sec_prot_auth_sci = -1;
-static int hf_ip_opt_sec_prot_auth_nsa = -1;
-static int hf_ip_opt_sec_prot_auth_doe = -1;
-static int hf_ip_opt_sec_prot_auth_unassigned = -1;
-static int hf_ip_opt_sec_prot_auth_unassigned2 = -1;
-static int hf_ip_opt_sec_prot_auth_fti = -1;
-static int hf_ip_opt_ext_sec_add_sec_info_format_code = -1;
-static int hf_ip_opt_ext_sec_add_sec_info = -1;
-static int hf_ip_rec_rt = -1;
-static int hf_ip_rec_rt_host = -1;
-static int hf_ip_cur_rt = -1;
-static int hf_ip_cur_rt_host = -1;
-static int hf_ip_src_rt = -1;
-static int hf_ip_src_rt_host = -1;
-static int hf_ip_empty_rt = -1;
-static int hf_ip_empty_rt_host = -1;
-static int hf_ip_cipso_tag_type = -1;
-
-static int hf_ip_fragments = -1;
-static int hf_ip_fragment = -1;
-static int hf_ip_fragment_overlap = -1;
-static int hf_ip_fragment_overlap_conflict = -1;
-static int hf_ip_fragment_multiple_tails = -1;
-static int hf_ip_fragment_too_long_fragment = -1;
-static int hf_ip_fragment_error = -1;
-static int hf_ip_fragment_count = -1;
-static int hf_ip_reassembled_in = -1;
-static int hf_ip_reassembled_length = -1;
-static int hf_ip_reassembled_data = -1;
+static int hf_ip_opt_type;
+static int hf_ip_opt_type_copy;
+static int hf_ip_opt_type_class;
+static int hf_ip_opt_type_number;
+static int hf_ip_opt_len;
+static int hf_ip_opt_ptr;
+static int hf_ip_opt_sid;
+static int hf_ip_opt_mtu;
+static int hf_ip_opt_id_number;
+static int hf_ip_opt_ohc;
+static int hf_ip_opt_rhc;
+static int hf_ip_opt_originator;
+static int hf_ip_opt_ra;
+static int hf_ip_opt_addr;
+static int hf_ip_opt_padding;
+static int hf_ip_opt_qs_func;
+static int hf_ip_opt_qs_rate;
+static int hf_ip_opt_qs_ttl;
+static int hf_ip_opt_qs_ttl_diff;
+static int hf_ip_opt_qs_unused;
+static int hf_ip_opt_qs_nonce;
+static int hf_ip_opt_qs_reserved;
+static int hf_ip_opt_sec_rfc791_sec;
+static int hf_ip_opt_sec_rfc791_comp;
+static int hf_ip_opt_sec_rfc791_hr;
+static int hf_ip_opt_sec_rfc791_tcc;
+static int hf_ip_opt_sec_cl;
+static int hf_ip_opt_sec_prot_auth_flags;
+static int hf_ip_opt_sec_prot_auth_genser;
+static int hf_ip_opt_sec_prot_auth_siop_esi;
+static int hf_ip_opt_sec_prot_auth_sci;
+static int hf_ip_opt_sec_prot_auth_nsa;
+static int hf_ip_opt_sec_prot_auth_doe;
+static int hf_ip_opt_sec_prot_auth_unassigned;
+static int hf_ip_opt_sec_prot_auth_unassigned2;
+static int hf_ip_opt_sec_prot_auth_fti;
+static int hf_ip_opt_ext_sec_add_sec_info_format_code;
+static int hf_ip_opt_ext_sec_add_sec_info;
+static int hf_ip_rec_rt;
+static int hf_ip_rec_rt_host;
+static int hf_ip_cur_rt;
+static int hf_ip_cur_rt_host;
+static int hf_ip_src_rt;
+static int hf_ip_src_rt_host;
+static int hf_ip_empty_rt;
+static int hf_ip_empty_rt_host;
+static int hf_ip_cipso_tag_type;
+
+static int hf_ip_fragments;
+static int hf_ip_fragment;
+static int hf_ip_fragment_overlap;
+static int hf_ip_fragment_overlap_conflict;
+static int hf_ip_fragment_multiple_tails;
+static int hf_ip_fragment_too_long_fragment;
+static int hf_ip_fragment_error;
+static int hf_ip_fragment_count;
+static int hf_ip_reassembled_in;
+static int hf_ip_reassembled_length;
+static int hf_ip_reassembled_data;
/* Generated from convert_proto_tree_add_text.pl */
-static int hf_ip_opt_flag = -1;
-static int hf_ip_opt_overflow = -1;
-static int hf_ip_cipso_tag_data = -1;
-static int hf_ip_cipso_sensitivity_level = -1;
-static int hf_ip_cipso_categories = -1;
-static int hf_ip_cipso_doi = -1;
-static int hf_ip_opt_time_stamp = -1;
-static int hf_ip_opt_time_stamp_addr = -1;
-
-static int hf_geoip_country = -1;
-static int hf_geoip_country_iso = -1;
-static int hf_geoip_city = -1;
-static int hf_geoip_as_number = -1;
-static int hf_geoip_as_org = -1;
-static int hf_geoip_latitude = -1;
-static int hf_geoip_longitude = -1;
-static int hf_geoip_src_summary = -1;
-static int hf_geoip_src_country = -1;
-static int hf_geoip_src_country_iso = -1;
-static int hf_geoip_src_city = -1;
-static int hf_geoip_src_as_number = -1;
-static int hf_geoip_src_as_org = -1;
-static int hf_geoip_src_latitude = -1;
-static int hf_geoip_src_longitude = -1;
-static int hf_geoip_dst_summary = -1;
-static int hf_geoip_dst_country = -1;
-static int hf_geoip_dst_country_iso = -1;
-static int hf_geoip_dst_city = -1;
-static int hf_geoip_dst_as_number = -1;
-static int hf_geoip_dst_as_org = -1;
-static int hf_geoip_dst_latitude = -1;
-static int hf_geoip_dst_longitude = -1;
-
-static gint ett_ip = -1;
-static gint ett_ip_dsfield = -1;
-static gint ett_ip_tos = -1;
-static gint ett_ip_flags = -1;
-static gint ett_ip_options = -1;
-static gint ett_ip_option_eool = -1;
-static gint ett_ip_option_nop = -1;
-static gint ett_ip_option_sec = -1;
-static gint ett_ip_option_route = -1;
-static gint ett_ip_option_timestamp = -1;
-static gint ett_ip_option_ext_security = -1;
-static gint ett_ip_option_cipso = -1;
-static gint ett_ip_option_sid = -1;
-static gint ett_ip_option_mtu = -1;
-static gint ett_ip_option_tr = -1;
-static gint ett_ip_option_ra = -1;
-static gint ett_ip_option_sdb = -1;
-static gint ett_ip_option_qs = -1;
-static gint ett_ip_option_other = -1;
-static gint ett_ip_fragments = -1;
-static gint ett_ip_fragment = -1;
-static gint ett_ip_opt_type = -1;
-static gint ett_ip_opt_sec_prot_auth_flags = -1;
-static gint ett_ip_unknown_opt = -1;
-
-static expert_field ei_ip_opt_len_invalid = EI_INIT;
-static expert_field ei_ip_opt_sec_prot_auth_fti = EI_INIT;
-static expert_field ei_ip_extraneous_data = EI_INIT;
-static expert_field ei_ip_opt_ptr_before_address = EI_INIT;
-static expert_field ei_ip_opt_ptr_middle_address = EI_INIT;
-static expert_field ei_ip_subopt_too_long = EI_INIT;
-static expert_field ei_ip_nop = EI_INIT;
-static expert_field ei_ip_bogus_ip_length = EI_INIT;
-static expert_field ei_ip_evil_packet = EI_INIT;
-static expert_field ei_ip_checksum_bad = EI_INIT;
-static expert_field ei_ip_ttl_lncb = EI_INIT;
-static expert_field ei_ip_ttl_too_small = EI_INIT;
-static expert_field ei_ip_cipso_tag = EI_INIT;
-static expert_field ei_ip_bogus_ip_version = EI_INIT;
-static expert_field ei_ip_bogus_header_length = EI_INIT;
+static int hf_ip_opt_flag;
+static int hf_ip_opt_overflow;
+static int hf_ip_cipso_tag_data;
+static int hf_ip_cipso_sensitivity_level;
+static int hf_ip_cipso_categories;
+static int hf_ip_cipso_doi;
+static int hf_ip_opt_time_stamp;
+static int hf_ip_opt_time_stamp_addr;
+
+static int hf_geoip_country;
+static int hf_geoip_country_iso;
+static int hf_geoip_city;
+static int hf_geoip_as_number;
+static int hf_geoip_as_org;
+static int hf_geoip_latitude;
+static int hf_geoip_longitude;
+static int hf_geoip_src_summary;
+static int hf_geoip_src_country;
+static int hf_geoip_src_country_iso;
+static int hf_geoip_src_city;
+static int hf_geoip_src_as_number;
+static int hf_geoip_src_as_org;
+static int hf_geoip_src_latitude;
+static int hf_geoip_src_longitude;
+static int hf_geoip_dst_summary;
+static int hf_geoip_dst_country;
+static int hf_geoip_dst_country_iso;
+static int hf_geoip_dst_city;
+static int hf_geoip_dst_as_number;
+static int hf_geoip_dst_as_org;
+static int hf_geoip_dst_latitude;
+static int hf_geoip_dst_longitude;
+
+static int ett_ip;
+static int ett_ip_dsfield;
+static int ett_ip_tos;
+static int ett_ip_flags;
+static int ett_ip_options;
+static int ett_ip_option_eool;
+static int ett_ip_option_nop;
+static int ett_ip_option_sec;
+static int ett_ip_option_route;
+static int ett_ip_option_timestamp;
+static int ett_ip_option_ext_security;
+static int ett_ip_option_cipso;
+static int ett_ip_option_sid;
+static int ett_ip_option_mtu;
+static int ett_ip_option_tr;
+static int ett_ip_option_ra;
+static int ett_ip_option_sdb;
+static int ett_ip_option_qs;
+static int ett_ip_option_other;
+static int ett_ip_fragments;
+static int ett_ip_fragment;
+static int ett_ip_opt_type;
+static int ett_ip_opt_sec_prot_auth_flags;
+static int ett_ip_unknown_opt;
+
+static expert_field ei_ip_opt_len_invalid;
+static expert_field ei_ip_opt_deprecated;
+static expert_field ei_ip_opt_sec_prot_auth_fti;
+static expert_field ei_ip_extraneous_data;
+static expert_field ei_ip_opt_ptr_before_address;
+static expert_field ei_ip_opt_ptr_middle_address;
+static expert_field ei_ip_subopt_too_long;
+static expert_field ei_ip_nop;
+static expert_field ei_ip_bogus_ip_length;
+static expert_field ei_ip_evil_packet;
+static expert_field ei_ip_checksum_bad;
+static expert_field ei_ip_ttl_lncb;
+static expert_field ei_ip_ttl_too_small;
+static expert_field ei_ip_cipso_tag;
+static expert_field ei_ip_bogus_ip_version;
+static expert_field ei_ip_bogus_header_length;
static dissector_handle_t ip_handle;
static dissector_table_t ip_option_table;
-static gint ett_geoip_info = -1;
+static int ett_geoip_info;
+
+static uint32_t ip_stream_count;
static const fragment_items ip_frag_items = {
&ett_ip_fragment,
@@ -388,7 +398,8 @@ const value_string ip_version_vals[] = {
#define IPOPT_RESERVED2 0x60
/* REF: http://www.iana.org/assignments/ip-parameters */
-/* TODO: Not all of these are implemented. */
+/* TODO: Not all of these are implemented, especially those
+ * deprecated by RFC 6814. */
#define IPOPT_EOOL (0 |IPOPT_CONTROL)
#define IPOPT_NOP (1 |IPOPT_CONTROL)
#define IPOPT_SEC (2 |IPOPT_COPY|IPOPT_CONTROL) /* RFC 791/1108 */
@@ -397,23 +408,23 @@ const value_string ip_version_vals[] = {
#define IPOPT_ESEC (5 |IPOPT_COPY|IPOPT_CONTROL) /* RFC 1108 */
#define IPOPT_CIPSO (6 |IPOPT_COPY|IPOPT_CONTROL) /* draft-ietf-cipso-ipsecurity-01 */
#define IPOPT_RR (7 |IPOPT_CONTROL)
-#define IPOPT_SID (8 |IPOPT_COPY|IPOPT_CONTROL)
+#define IPOPT_SID (8 |IPOPT_COPY|IPOPT_CONTROL) /* Deprecated */
#define IPOPT_SSR (9 |IPOPT_COPY|IPOPT_CONTROL)
#define IPOPT_ZSU (10|IPOPT_CONTROL) /* Zsu */
#define IPOPT_MTUP (11|IPOPT_CONTROL) /* RFC 1063 */
#define IPOPT_MTUR (12|IPOPT_CONTROL) /* RFC 1063 */
#define IPOPT_FINN (13|IPOPT_COPY|IPOPT_MEASUREMENT) /* Finn */
-#define IPOPT_VISA (14|IPOPT_COPY|IPOPT_CONTROL) /* Estrin */
-#define IPOPT_ENCODE (15|IPOPT_CONTROL) /* VerSteeg */
+#define IPOPT_VISA (14|IPOPT_COPY|IPOPT_CONTROL) /* Estrin; Deprecated */
+#define IPOPT_ENCODE (15|IPOPT_CONTROL) /* VerSteeg; Deprecated */
#define IPOPT_IMITD (16|IPOPT_COPY|IPOPT_CONTROL) /* Lee */
-#define IPOPT_EIP (17|IPOPT_COPY|IPOPT_CONTROL) /* RFC 1385 */
-#define IPOPT_TR (18|IPOPT_MEASUREMENT) /* RFC 1393 */
-#define IPOPT_ADDEXT (19|IPOPT_COPY|IPOPT_CONTROL) /* Ullmann IPv7 */
+#define IPOPT_EIP (17|IPOPT_COPY|IPOPT_CONTROL) /* RFC 1385; Deprecated */
+#define IPOPT_TR (18|IPOPT_MEASUREMENT) /* RFC 1393; Deprecated */
+#define IPOPT_ADDEXT (19|IPOPT_COPY|IPOPT_CONTROL) /* Ullmann IPv7; Deprecated */
#define IPOPT_RTRALT (20|IPOPT_COPY|IPOPT_CONTROL) /* RFC 2113 */
-#define IPOPT_SDB (21|IPOPT_COPY|IPOPT_CONTROL) /* RFC 1770 Graff */
+#define IPOPT_SDB (21|IPOPT_COPY|IPOPT_CONTROL) /* RFC 1770 Graff; Deprecated */
#define IPOPT_UN (22|IPOPT_COPY|IPOPT_CONTROL) /* Released 18-Oct-2005 */
-#define IPOPT_DPS (23|IPOPT_COPY|IPOPT_CONTROL) /* Malis */
-#define IPOPT_UMP (24|IPOPT_COPY|IPOPT_CONTROL) /* Farinacci */
+#define IPOPT_DPS (23|IPOPT_COPY|IPOPT_CONTROL) /* Malis; Deprecated */
+#define IPOPT_UMP (24|IPOPT_COPY|IPOPT_CONTROL) /* Farinacci; Deprecated */
#define IPOPT_QS (25|IPOPT_CONTROL) /* RFC 4782 */
#define IPOPT_EXP (30|IPOPT_CONTROL) /* RFC 4727 */
@@ -475,26 +486,33 @@ const value_string ip_version_vals[] = {
#define IPLOCAL_NETWRK_CTRL_BLK_ANY_TTL 0x1000 /* larger than max ttl */
#define IPLOCAL_NETWRK_CTRL_BLK_DEFAULT_TTL 0X01
-static void ip_prompt(packet_info *pinfo, gchar* result)
+static void ip_prompt(packet_info *pinfo, char* result)
{
snprintf(result, MAX_DECODE_AS_PROMPT_LEN, "IP protocol %u as",
GPOINTER_TO_UINT(p_get_proto_data(pinfo->pool, pinfo, proto_ip, pinfo->curr_layer_num)));
}
-static gpointer ip_value(packet_info *pinfo)
+static void *ip_value(packet_info *pinfo)
{
return p_get_proto_data(pinfo->pool, pinfo, proto_ip, pinfo->curr_layer_num);
}
static const char* ip_conv_get_filter_type(conv_item_t* conv, conv_filter_type_e filter)
{
- if ((filter == CONV_FT_SRC_ADDRESS) && (conv->src_address.type == AT_IPv4))
+ /* addr type is AT_STRINGZ for subnets, as it is a very flexible format
+ * XXX - create a new type when required, at this moment it's only used in
+ * conversation tables and is not justifed. See #19481.
+ */
+ if ((filter == CONV_FT_SRC_ADDRESS) && ((conv->src_address.type == AT_IPv4) ||
+ (conv->src_address.type == AT_STRINGZ)))
return "ip.src";
- if ((filter == CONV_FT_DST_ADDRESS) && (conv->dst_address.type == AT_IPv4))
+ if ((filter == CONV_FT_DST_ADDRESS) && ((conv->dst_address.type == AT_IPv4) ||
+ (conv->dst_address.type == AT_STRINGZ)))
return "ip.dst";
- if ((filter == CONV_FT_ANY_ADDRESS) && (conv->src_address.type == AT_IPv4))
+ if ((filter == CONV_FT_ANY_ADDRESS) && ((conv->src_address.type == AT_IPv4) ||
+ (conv->src_address.type == AT_STRINGZ)))
return "ip.addr";
return CONV_FILTER_INVALID;
@@ -509,14 +527,26 @@ ip_conversation_packet(void *pct, packet_info *pinfo, epan_dissect_t *edt _U_, c
hash->flags = flags;
const ws_ip4 *iph=(const ws_ip4 *)vip;
- add_conversation_table_data(hash, &iph->ip_src, &iph->ip_dst, 0, 0, 1, pinfo->fd->pkt_len, &pinfo->rel_ts, &pinfo->abs_ts, &ip_ct_dissector_info, CONVERSATION_NONE);
+ /* Try aggregating into subnets if asked so,
+ * if no subnets are found it will still end in calling xxx_with_conv_id()
+ */
+ if(ip_conv_agg_flag) {
+ add_conversation_table_data_ipv4_subnet(hash, &iph->ip_src, &iph->ip_dst, 0, 0, (conv_id_t)iph->ip_stream, 1, pinfo->fd->pkt_len,
+ &pinfo->rel_ts, &pinfo->abs_ts, &ip_ct_dissector_info, CONVERSATION_IP);
+ }
+ else {
+ add_conversation_table_data_with_conv_id(hash, &iph->ip_src, &iph->ip_dst, 0, 0, (conv_id_t)iph->ip_stream, 1, pinfo->fd->pkt_len,
+ &pinfo->rel_ts, &pinfo->abs_ts, &ip_ct_dissector_info, CONVERSATION_IP);
+ }
return TAP_PACKET_REDRAW;
}
static const char* ip_endpoint_get_filter_type(endpoint_item_t* endpoint, conv_filter_type_e filter)
{
- if ((filter == CONV_FT_ANY_ADDRESS) && (endpoint->myaddress.type == AT_IPv4))
+ /* subnets: handled similarly to ip_conv_get_filter_type() */
+ if ((filter == CONV_FT_ANY_ADDRESS) && ((endpoint->myaddress.type == AT_IPv4) ||
+ (endpoint->myaddress.type == AT_STRINGZ)))
return "ip.addr";
return CONV_FILTER_INVALID;
@@ -534,18 +564,24 @@ ip_endpoint_packet(void *pit, packet_info *pinfo, epan_dissect_t *edt _U_, const
/* Take two "add" passes per packet, adding for each direction, ensures that all
packets are counted properly (even if address is sending to itself)
XXX - this could probably be done more efficiently inside endpoint_table */
- add_endpoint_table_data(hash, &iph->ip_src, 0, TRUE, 1, pinfo->fd->pkt_len, &ip_endpoint_dissector_info, ENDPOINT_NONE);
- add_endpoint_table_data(hash, &iph->ip_dst, 0, FALSE, 1, pinfo->fd->pkt_len, &ip_endpoint_dissector_info, ENDPOINT_NONE);
+ if(ip_conv_agg_flag) {
+ add_endpoint_table_data_ipv4_subnet(hash, &iph->ip_src, 0, true, 1, pinfo->fd->pkt_len, &ip_endpoint_dissector_info, ENDPOINT_NONE);
+ add_endpoint_table_data_ipv4_subnet(hash, &iph->ip_dst, 0, false, 1, pinfo->fd->pkt_len, &ip_endpoint_dissector_info, ENDPOINT_NONE);
+ }
+ else {
+ add_endpoint_table_data(hash, &iph->ip_src, 0, true, 1, pinfo->fd->pkt_len, &ip_endpoint_dissector_info, ENDPOINT_NONE);
+ add_endpoint_table_data(hash, &iph->ip_dst, 0, false, 1, pinfo->fd->pkt_len, &ip_endpoint_dissector_info, ENDPOINT_NONE);
+ }
return TAP_PACKET_REDRAW;
}
-static gboolean
+static bool
ip_filter_valid(packet_info *pinfo, void *user_data _U_)
{
return proto_is_frame_protocol(pinfo->layers, "ip");
}
-static gchar*
+static char*
ip_build_filter(packet_info *pinfo, void *user_data _U_)
{
return ws_strdup_printf("ip.addr eq %s and ip.addr eq %s",
@@ -558,17 +594,17 @@ ip_build_filter(packet_info *pinfo, void *user_data _U_)
*/
static reassembly_table ip_reassembly_table;
-static gboolean
-capture_ip(const guchar *pd, int offset, int len, capture_packet_info_t *cpinfo, const union wtap_pseudo_header *pseudo_header _U_) {
+static bool
+capture_ip(const unsigned char *pd, int offset, int len, capture_packet_info_t *cpinfo, const union wtap_pseudo_header *pseudo_header _U_) {
if (!BYTES_ARE_IN_FRAME(offset, len, IPH_MIN_LEN))
- return FALSE;
+ return false;
capture_dissector_increment_count(cpinfo, proto_ip);
return try_capture_dissector("ip.proto", pd[offset + 9], pd, offset+IPH_MIN_LEN, len, cpinfo, pseudo_header);
}
static void
-add_geoip_info_entry(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, gint offset, ws_in4_addr ip, gboolean isdst)
+add_geoip_info_entry(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset, ws_in4_addr ip, bool isdst)
{
const mmdb_lookup_t *lookup = maxmind_db_lookup_ipv4(&ip);
if (!lookup->found) return;
@@ -659,11 +695,11 @@ add_geoip_info_entry(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, gint o
}
static void
-add_geoip_info(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, gint offset, guint32 src32,
- guint32 dst32)
+add_geoip_info(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset, uint32_t src32,
+ uint32_t dst32)
{
- add_geoip_info_entry(tree, pinfo, tvb, offset, g_htonl(src32), FALSE);
- add_geoip_info_entry(tree, pinfo, tvb, offset, g_htonl(dst32), TRUE);
+ add_geoip_info_entry(tree, pinfo, tvb, offset, g_htonl(src32), false);
+ add_geoip_info_entry(tree, pinfo, tvb, offset, g_htonl(dst32), true);
}
const value_string ipopt_type_class_vals[] = {
@@ -719,7 +755,7 @@ dissect_ipopt_type(tvbuff_t *tvb, int offset, proto_tree *tree)
}
static proto_tree*
-ip_fixed_option_header(proto_tree* tree, packet_info *pinfo, tvbuff_t *tvb, int proto, int ett, proto_item** ti, guint len, guint optlen)
+ip_fixed_option_header(proto_tree* tree, packet_info *pinfo, tvbuff_t *tvb, int proto, int ett, proto_item** ti, unsigned len, unsigned optlen)
{
proto_tree *field_tree;
proto_item *tf;
@@ -743,7 +779,7 @@ ip_fixed_option_header(proto_tree* tree, packet_info *pinfo, tvbuff_t *tvb, int
}
static proto_tree*
-ip_var_option_header(proto_tree* tree, packet_info *pinfo, tvbuff_t *tvb, int proto, int ett, proto_item** ti, guint optlen)
+ip_var_option_header(proto_tree* tree, packet_info *pinfo, tvbuff_t *tvb, int proto, int ett, proto_item** ti, unsigned optlen)
{
proto_tree *field_tree;
proto_item *tf;
@@ -823,9 +859,9 @@ dissect_ipopt_security(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void
{
proto_tree *field_tree;
proto_item *tf;
- guint val;
- guint curr_offset = 2;
- guint optlen = tvb_reported_length(tvb);
+ unsigned val;
+ unsigned curr_offset = 2;
+ unsigned optlen = tvb_reported_length(tvb);
field_tree = ip_var_option_header(tree, pinfo, tvb, proto_ip_option_security, ett_ip_option_sec, &tf, optlen);
@@ -856,7 +892,7 @@ dissect_ipopt_security(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void
if (curr_offset >= optlen) {
return curr_offset;
}
- val = tvb_get_guint8(tvb, curr_offset);
+ val = tvb_get_uint8(tvb, curr_offset);
proto_tree_add_bitmask(field_tree, tvb, curr_offset, hf_ip_opt_sec_prot_auth_flags,
ett_ip_opt_sec_prot_auth_flags, ip_opt_sec_prot_auth_fields_byte_1,
ENC_BIG_ENDIAN);
@@ -866,7 +902,7 @@ dissect_ipopt_security(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void
expert_add_info(pinfo, tf, &ei_ip_opt_sec_prot_auth_fti);
break;
}
- val = tvb_get_guint8(tvb, curr_offset);
+ val = tvb_get_uint8(tvb, curr_offset);
proto_tree_add_bitmask(field_tree, tvb, curr_offset, hf_ip_opt_sec_prot_auth_flags,
ett_ip_opt_sec_prot_auth_flags, ip_opt_sec_prot_auth_fields_byte_n,
ENC_BIG_ENDIAN);
@@ -884,9 +920,9 @@ dissect_ipopt_ext_security(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
{
proto_tree *field_tree;
proto_item *tf;
- guint curr_offset = 2;
- gint remaining;
- gint optlen = tvb_reported_length(tvb);
+ unsigned curr_offset = 2;
+ int remaining;
+ int optlen = tvb_reported_length(tvb);
field_tree = ip_var_option_header(tree, pinfo, tvb, proto_ip_option_ext_security, ett_ip_option_ext_security, &tf, optlen);
@@ -927,8 +963,8 @@ dissect_ipopt_cipso(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *
{
proto_tree *field_tree;
proto_item *tf, *tag_item;
- guint tagtype, taglen;
- gint offset = 2,
+ unsigned tagtype, taglen;
+ int offset = 2,
optlen = tvb_reported_length(tvb);
int offset_max = optlen;
@@ -939,11 +975,11 @@ dissect_ipopt_cipso(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *
/* loop through all of the tags in the CIPSO option */
while (offset < offset_max) {
- tagtype = tvb_get_guint8(tvb, offset);
+ tagtype = tvb_get_uint8(tvb, offset);
tag_item = proto_tree_add_item(field_tree, hf_ip_cipso_tag_type, tvb, offset, 1, ENC_NA);
if ((offset + 1) < offset_max)
- taglen = tvb_get_guint8(tvb, offset + 1);
+ taglen = tvb_get_uint8(tvb, offset + 1);
else
taglen = 1;
@@ -967,13 +1003,13 @@ dissect_ipopt_cipso(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *
offset += 1;
if (taglen > 4) {
- guint bit_spot = 0;
- guint byte_spot = 0;
+ unsigned bit_spot = 0;
+ unsigned byte_spot = 0;
unsigned char bitmask;
char *cat_str;
char *cat_str_tmp = (char *)wmem_alloc(pinfo->pool, USHRT_MAX_STRLEN);
size_t cat_str_len;
- const guint8 *val_ptr = tvb_get_ptr(tvb, offset, taglen - 4);
+ const uint8_t *val_ptr = tvb_get_ptr(tvb, offset, taglen - 4);
/* this is just a guess regarding string size, but we grow it below
* if needed */
@@ -1064,7 +1100,7 @@ dissect_ipopt_cipso(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *
offset += 1;
if (taglen > 4) {
- guint16 cat_low, cat_high;
+ uint16_t cat_low, cat_high;
int offset_max_cat = offset + taglen - 4;
char *cat_str = (char *)wmem_alloc0(pinfo->pool, USHRT_MAX_STRLEN * 16);
char *cat_str_tmp = (char *)wmem_alloc(pinfo->pool, USHRT_MAX_STRLEN * 2);
@@ -1117,7 +1153,7 @@ dissect_ipopt_cipso(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *
default:
/* unknown tag - stop parsing this IPv4 option */
if ((offset + 1) <= offset_max) {
- taglen = tvb_get_guint8(tvb, offset + 1);
+ taglen = tvb_get_uint8(tvb, offset + 1);
proto_item_append_text(tag_item, " (%u bytes)", taglen);
return offset;
}
@@ -1129,17 +1165,17 @@ dissect_ipopt_cipso(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *
}
static void
-dissect_option_route(proto_tree *tree, tvbuff_t *tvb, int offset, int hf,
- int hf_host, gboolean next)
+dissect_option_route(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset, int hf,
+ int hf_host, bool next)
{
proto_item *ti;
- guint32 route;
+ uint32_t route;
route = tvb_get_ipv4(tvb, offset);
if (next)
proto_tree_add_ipv4_format_value(tree, hf, tvb, offset, 4, route,
"%s <- (next)",
- tvb_ip_to_str(wmem_packet_scope(), tvb, offset));
+ tvb_ip_to_str(pinfo->pool, tvb, offset));
else
proto_tree_add_ipv4(tree, hf, tvb, offset, 4, route);
ti = proto_tree_add_string(tree, hf_host, tvb, offset, 4, get_hostname(route));
@@ -1152,14 +1188,14 @@ dissect_ipopt_route(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int pro
{
proto_tree *field_tree;
proto_item *tf;
- guint8 len, ptr;
+ uint8_t len, ptr;
int optoffset = 0;
- gint offset = 0,
+ int offset = 0,
optlen = tvb_reported_length(tvb);
field_tree = ip_var_option_header(tree, pinfo, tvb, proto, ett_ip_option_route, &tf, optlen);
- ptr = tvb_get_guint8(tvb, offset + 2);
+ ptr = tvb_get_uint8(tvb, offset + 2);
tf = proto_tree_add_item(field_tree, hf_ip_opt_ptr, tvb, offset + 2, 1, ENC_NA);
if ((ptr < (optlen_min + 1)) || (ptr & 3)) {
if (ptr < (optlen_min + 1)) {
@@ -1181,12 +1217,12 @@ dissect_ipopt_route(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int pro
if (ptr > len) {
/* This is a recorded route */
- dissect_option_route(field_tree, tvb, offset + optoffset, hf_ip_rec_rt,
- hf_ip_rec_rt_host, FALSE);
+ dissect_option_route(field_tree, pinfo, tvb, offset + optoffset, hf_ip_rec_rt,
+ hf_ip_rec_rt_host, false);
} else if (optoffset == (len - 4)) {
/* This is the destination */
proto_item *item;
- guint32 addr;
+ uint32_t addr;
const char *dst_host;
addr = tvb_get_ipv4(tvb, offset + optoffset);
@@ -1206,18 +1242,18 @@ dissect_ipopt_route(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int pro
proto_item_set_hidden(item);
} else if ((optoffset + 1) < ptr) {
/* This is also a recorded route */
- dissect_option_route(field_tree, tvb, offset + optoffset, hf_ip_rec_rt,
- hf_ip_rec_rt_host, FALSE);
+ dissect_option_route(field_tree, pinfo, tvb, offset + optoffset, hf_ip_rec_rt,
+ hf_ip_rec_rt_host, false);
} else if ((optoffset + 1) == ptr) {
/* This is the next source route. TODO: Should we use separate hf's
* for this, such as hf_ip_next_rt and hf_ip_next_rt_host and avoid
- * having to pass TRUE/FALSE to dissect_option_route()? */
- dissect_option_route(field_tree, tvb, offset + optoffset, hf_ip_src_rt,
- hf_ip_src_rt_host, TRUE);
+ * having to pass true/false to dissect_option_route()? */
+ dissect_option_route(field_tree, pinfo, tvb, offset + optoffset, hf_ip_src_rt,
+ hf_ip_src_rt_host, true);
} else {
/* This must be a source route */
- dissect_option_route(field_tree, tvb, offset + optoffset, hf_ip_src_rt,
- hf_ip_src_rt_host, FALSE);
+ dissect_option_route(field_tree, pinfo, tvb, offset + optoffset, hf_ip_src_rt,
+ hf_ip_src_rt_host, false);
}
}
@@ -1242,14 +1278,14 @@ dissect_ipopt_record_route(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
{
proto_tree *field_tree;
proto_item *tf;
- guint8 len, ptr;
+ uint8_t len, ptr;
int optoffset = 0;
- gint offset = 0,
+ int offset = 0,
optlen = tvb_reported_length(tvb);
field_tree = ip_var_option_header(tree, pinfo, tvb, proto_ip_option_record_route, ett_ip_option_route, &tf, optlen);
- ptr = tvb_get_guint8(tvb, offset + 2);
+ ptr = tvb_get_uint8(tvb, offset + 2);
tf = proto_tree_add_item(field_tree, hf_ip_opt_ptr, tvb, offset + 2, 1, ENC_NA);
if ((ptr < (IPOLEN_RR_MIN + 1)) || (ptr & 3)) {
@@ -1272,22 +1308,22 @@ dissect_ipopt_record_route(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
if (ptr > len) {
/* The recorded route data area is full. */
- dissect_option_route(field_tree, tvb, offset + optoffset, hf_ip_rec_rt,
- hf_ip_rec_rt_host, FALSE);
+ dissect_option_route(field_tree, pinfo, tvb, offset + optoffset, hf_ip_rec_rt,
+ hf_ip_rec_rt_host, false);
} else if ((optoffset + 1) < ptr) {
/* This is a recorded route */
- dissect_option_route(field_tree, tvb, offset + optoffset, hf_ip_rec_rt,
- hf_ip_rec_rt_host, FALSE);
+ dissect_option_route(field_tree, pinfo, tvb, offset + optoffset, hf_ip_rec_rt,
+ hf_ip_rec_rt_host, false);
} else if ((optoffset + 1) == ptr) {
/* This is the next available slot. TODO: Should we use separate hf's
* for this, such as hf_ip_next_rt and hf_ip_next_rt_host and avoid
- * having to pass TRUE/FALSE to dissect_option_route()? */
- dissect_option_route(field_tree, tvb, offset + optoffset, hf_ip_empty_rt,
- hf_ip_empty_rt_host, TRUE);
+ * having to pass true/false to dissect_option_route()? */
+ dissect_option_route(field_tree, pinfo, tvb, offset + optoffset, hf_ip_empty_rt,
+ hf_ip_empty_rt_host, true);
} else {
/* This must be an available slot too. */
- dissect_option_route(field_tree, tvb, offset + optoffset, hf_ip_empty_rt,
- hf_ip_empty_rt_host, FALSE);
+ dissect_option_route(field_tree, pinfo, tvb, offset + optoffset, hf_ip_empty_rt,
+ hf_ip_empty_rt_host, false);
}
}
@@ -1302,6 +1338,7 @@ dissect_ipopt_sid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void * da
proto_item *tf;
field_tree = ip_fixed_option_header(tree, pinfo, tvb, proto_ip_option_sid, ett_ip_option_sid, &tf, IPOLEN_SID, tvb_reported_length(tvb));
+ expert_add_info(pinfo, tf, &ei_ip_opt_deprecated);
proto_tree_add_item(field_tree, hf_ip_opt_sid, tvb, 2, 2, ENC_BIG_ENDIAN);
return tvb_captured_length(tvb);
@@ -1338,9 +1375,10 @@ dissect_ipopt_tr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void * dat
{
proto_tree *field_tree;
proto_item *tf;
- gint offset = 2;
+ int offset = 2;
field_tree = ip_fixed_option_header(tree, pinfo, tvb, proto_ip_option_traceroute, ett_ip_option_tr, &tf, IPOLEN_TR, tvb_reported_length(tvb));
+ expert_add_info(pinfo, tf, &ei_ip_opt_deprecated);
proto_tree_add_item(field_tree, hf_ip_opt_id_number, tvb, offset, 2, ENC_BIG_ENDIAN);
proto_tree_add_item(field_tree, hf_ip_opt_ohc, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
@@ -1363,8 +1401,8 @@ dissect_ipopt_timestamp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, voi
int ptr;
int optoffset = 0;
int flg;
- guint32 addr;
- gint offset = 0,
+ uint32_t addr;
+ int offset = 0,
optlen = tvb_reported_length(tvb);
field_tree = ip_var_option_header(tree, pinfo, tvb, proto_ip_option_timestamp, ett_ip_option_timestamp, &tf, optlen);
@@ -1372,7 +1410,7 @@ dissect_ipopt_timestamp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, voi
optoffset += 2; /* skip past type and length */
optlen -= 2; /* subtract size of type and length */
- ptr = tvb_get_guint8(tvb, offset + optoffset);
+ ptr = tvb_get_uint8(tvb, offset + optoffset);
proto_tree_add_uint_format_value(field_tree, hf_ip_opt_ptr, tvb, offset + optoffset, 1, ptr, "%d%s",
ptr, ((ptr == 1) ? " (header is full)" :
(ptr < 5) ? " (points before first address)" :
@@ -1381,7 +1419,7 @@ dissect_ipopt_timestamp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, voi
optlen--;
ptr--; /* ptr is 1-origin */
- flg = tvb_get_guint8(tvb, offset + optoffset);
+ flg = tvb_get_uint8(tvb, offset + optoffset);
proto_tree_add_item(field_tree, hf_ip_opt_overflow, tvb, offset + optoffset, 1, ENC_NA);
flg &= 0xF;
proto_tree_add_item(field_tree, hf_ip_opt_flag, tvb, offset + optoffset, 1, ENC_NA);
@@ -1430,7 +1468,7 @@ dissect_ipopt_ra(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void * dat
/* Router-Alert, as defined by RFC2113 */
proto_tree *field_tree;
proto_item *tf;
- guint32 value;
+ uint32_t value;
field_tree = ip_fixed_option_header(tree, pinfo, tvb, proto_ip_option_routeralert, ett_ip_option_ra, &tf, IPOLEN_RA, tvb_reported_length(tvb));
@@ -1445,10 +1483,11 @@ dissect_ipopt_sdb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void * da
{
proto_tree *field_tree;
proto_item *tf;
- gint offset = 0,
+ int offset = 0,
optlen = tvb_reported_length(tvb);
field_tree = ip_var_option_header(tree, pinfo, tvb, proto_ip_option_sdb, ett_ip_option_sdb, &tf, optlen);
+ expert_add_info(pinfo, tf, &ei_ip_opt_deprecated);
for (offset += 2, optlen -= 2; optlen >= 4; offset += 4, optlen -= 4)
proto_tree_add_item(field_tree, hf_ip_opt_addr, tvb, offset, 4, ENC_BIG_ENDIAN);
@@ -1493,12 +1532,12 @@ dissect_ipopt_qs(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void * dat
proto_item *tf;
proto_item *ti;
ws_ip4 *iph = (ws_ip4 *)data;
- gint offset = 2;
+ int offset = 2;
- guint8 command = tvb_get_guint8(tvb, offset);
- guint8 function = command >> 4;
- guint8 rate = command & QS_RATE_MASK;
- guint8 ttl_diff;
+ uint8_t command = tvb_get_uint8(tvb, offset);
+ uint8_t function = command >> 4;
+ uint8_t rate = command & QS_RATE_MASK;
+ uint8_t ttl_diff;
field_tree = ip_fixed_option_header(tree, pinfo, tvb, proto_ip_option_qs, ett_ip_option_qs, &tf, IPOLEN_QS, tvb_reported_length(tvb));
proto_item_append_text(tf, ": %s (%u)", val_to_str(function, qs_func_vals, "Unknown (%u)"), function);
@@ -1508,13 +1547,13 @@ dissect_ipopt_qs(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void * dat
if (function == QS_RATE_REQUEST) {
proto_tree_add_item(field_tree, hf_ip_opt_qs_rate, tvb, offset, 1, ENC_NA);
proto_tree_add_item(field_tree, hf_ip_opt_qs_ttl, tvb, offset + 1, 1, ENC_NA);
- ttl_diff = (iph->ip_ttl - tvb_get_guint8(tvb, offset + 1) % 256);
+ ttl_diff = (iph->ip_ttl - tvb_get_uint8(tvb, offset + 1) % 256);
ti = proto_tree_add_uint(field_tree, hf_ip_opt_qs_ttl_diff,
tvb, offset + 1, 1, ttl_diff);
proto_item_set_generated(ti);
proto_item_append_text(tf, ", %s, QS TTL %u, QS TTL diff %u",
val_to_str_ext(rate, &qs_rate_vals_ext, "Unknown (%u)"),
- tvb_get_guint8(tvb, offset + 1), ttl_diff);
+ tvb_get_uint8(tvb, offset + 1), ttl_diff);
proto_tree_add_item(field_tree, hf_ip_opt_qs_nonce, tvb, offset + 2, 4, ENC_BIG_ENDIAN);
proto_tree_add_item(field_tree, hf_ip_opt_qs_reserved, tvb, offset + 2, 4, ENC_BIG_ENDIAN);
} else if (function == QS_RATE_REPORT) {
@@ -1530,20 +1569,20 @@ dissect_ipopt_qs(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void * dat
}
static void
-dissect_ip_options(tvbuff_t *tvb, int offset, guint length,
+dissect_ip_options(tvbuff_t *tvb, int offset, unsigned length,
packet_info *pinfo, proto_tree *opt_tree,
proto_item *opt_item, void * data)
{
- guchar opt;
+ unsigned char opt;
unsigned int optlen;
proto_tree *field_tree;
const char *name;
dissector_handle_t option_dissector;
- guint nop_count = 0;
+ unsigned nop_count = 0;
tvbuff_t *next_tvb;
while (length > 0) {
- opt = tvb_get_guint8(tvb, offset);
+ opt = tvb_get_uint8(tvb, offset);
--length; /* account for type byte */
if ((opt == IPOPT_EOOL) || (opt == IPOPT_NOP)) {
@@ -1595,7 +1634,7 @@ dissect_ip_options(tvbuff_t *tvb, int offset, guint length,
return;
}
- optlen = tvb_get_guint8(tvb, offset + 1); /* total including type, len */
+ optlen = tvb_get_uint8(tvb, offset + 1); /* total including type, len */
--length; /* account for length byte */
if (optlen < 2) {
@@ -1637,14 +1676,14 @@ dissect_ip_options(tvbuff_t *tvb, int offset, guint length,
* The guts of this function was taken from dissect_ip_tcp_options().
*/
static int
-get_dst_offset(tvbuff_t *tvb, int offset, guint length)
+get_dst_offset(tvbuff_t *tvb, int offset, unsigned length)
{
- guchar opt;
- guint len;
+ unsigned char opt;
+ unsigned len;
int orig_offset = offset;
while (length > 0) {
- opt = tvb_get_guint8(tvb, offset);
+ opt = tvb_get_uint8(tvb, offset);
--length; /* account for type byte */
if ((opt != IPOPT_EOOL) && (opt != IPOPT_NOP)) {
@@ -1654,7 +1693,7 @@ get_dst_offset(tvbuff_t *tvb, int offset, guint length)
length byte! */
return 0;
}
- len = tvb_get_guint8(tvb, offset + 1); /* total including type, len */
+ len = tvb_get_uint8(tvb, offset + 1); /* total including type, len */
--length; /* account for length byte */
if (len < 2) {
/* Bogus - option length is too short to include option code and
@@ -1667,9 +1706,9 @@ get_dst_offset(tvbuff_t *tvb, int offset, guint length)
if (opt == IPOPT_SSR || opt == IPOPT_LSR) {
/* Hmm, what if you have both options? */
- guint8 ptr;
+ uint8_t ptr;
- ptr = tvb_get_guint8(tvb, offset + 2);
+ ptr = tvb_get_uint8(tvb, offset + 2);
if (ptr < 4 || (ptr & 3) || (ptr > len)) {
return 0;
}
@@ -1689,8 +1728,8 @@ get_dst_offset(tvbuff_t *tvb, int offset, guint length)
}
/* Returns the valid ttl for the group address */
-static guint16
-local_network_control_block_addr_valid_ttl(guint32 addr)
+static uint16_t
+local_network_control_block_addr_valid_ttl(uint32_t addr)
{
/* An exception list, as some protocols seem to insist on
* doing differently:
@@ -1808,29 +1847,29 @@ static const true_false_string flags_sf_set_evil = {
"Not evil"
};
-gboolean
-ip_try_dissect(gboolean heur_first, guint nxt, tvbuff_t *tvb, packet_info *pinfo,
+bool
+ip_try_dissect(bool heur_first, unsigned nxt, tvbuff_t *tvb, packet_info *pinfo,
proto_tree *tree, void *iph)
{
heur_dtbl_entry_t *hdtbl_entry;
if ((heur_first) && (dissector_try_heuristic(heur_subdissector_list, tvb,
pinfo, tree, &hdtbl_entry, iph))) {
- return TRUE;
+ return true;
}
if (dissector_try_uint_new(ip_dissector_table, nxt, tvb, pinfo,
- tree, TRUE, iph)) {
- return TRUE;
+ tree, true, iph)) {
+ return true;
}
if ((!heur_first) && (dissector_try_heuristic(heur_subdissector_list, tvb,
pinfo, tree, &hdtbl_entry,
iph))) {
- return TRUE;
+ return true;
}
- return FALSE;
+ return false;
}
static void
@@ -1846,24 +1885,65 @@ export_pdu(tvbuff_t *tvb, packet_info *pinfo)
}
}
+static struct ip_analysis *
+init_ip_conversation_data(packet_info *pinfo)
+{
+ struct ip_analysis *ipd;
+
+ /* Initialize the ip protocol data structure to add to the ip conversation */
+ ipd=wmem_new0(wmem_file_scope(), struct ip_analysis);
+
+ ipd->initial_frame = pinfo->num;
+ ipd->stream = 0;
+ ipd->stream = ip_stream_count++;
+
+ return ipd;
+}
+
+struct ip_analysis *
+get_ip_conversation_data(conversation_t *conv, packet_info *pinfo)
+{
+ struct ip_analysis *ipd;
+
+ /* Did the caller supply the conversation pointer? */
+ if( conv==NULL ) {
+ return NULL;
+ }
+
+ /* Get the data for this conversation */
+ ipd=(struct ip_analysis *)conversation_get_proto_data(conv, proto_ip);
+
+ if (!ipd) {
+ ipd = init_ip_conversation_data(pinfo);
+ conversation_add_proto_data(conv, proto_ip, ipd);
+ }
+
+ if (!ipd) {
+ return NULL;
+ }
+
+ return ipd;
+}
+
static int
dissect_ip_v4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void* data _U_)
{
proto_tree *ip_tree, *field_tree = NULL;
proto_item *ti, *tf;
- guint32 addr;
+ uint32_t addr;
int offset = 0, dst_off;
- guint hlen, optlen;
- guint16 ipsum;
+ unsigned hlen, optlen;
+ uint16_t ipsum;
fragment_head *ipfd_head = NULL;
tvbuff_t *next_tvb;
- gboolean update_col_info = TRUE;
- gboolean save_fragmented;
+ bool update_col_info = true;
+ bool save_fragmented;
ws_ip4 *iph;
- guint32 src32, dst32;
+ uint32_t src32, dst32;
proto_tree *tree;
proto_item *item = NULL, *ttl_item;
- guint16 ttl_valid;
+ uint16_t ttl_valid;
+ struct ip_analysis *ipd=NULL;
tree = parent_tree;
iph = wmem_new0(pinfo->pool, ws_ip4);
@@ -1883,7 +1963,7 @@ dissect_ip_v4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void*
col_add_fstr(pinfo->cinfo, COL_INFO,
"Bogus IPv4 version (%u, must be 4)", iph->ip_ver);
expert_add_info_format(pinfo, tf, &ei_ip_bogus_ip_version, "Bogus IPv4 version");
- /* I have a Linux cooked capture with ethertype IPv4 containing an IPv6 packet, continnue dissection in that case*/
+ /* I have a Linux cooked capture with ethertype IPv4 containing an IPv6 packet, continue dissection in that case*/
if (iph->ip_ver == 6) {
call_dissector(ipv6_handle, tvb, pinfo, tree);
}
@@ -1917,7 +1997,7 @@ dissect_ip_v4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void*
proto_tree_add_uint_bits_format_value(ip_tree, hf_ip_hdr_len, tvb, (offset<<3)+4, 4, hlen,
ENC_BIG_ENDIAN, "%u bytes (%u)", hlen, hlen>>2);
- iph->ip_tos = tvb_get_guint8(tvb, offset + 1);
+ iph->ip_tos = tvb_get_uint8(tvb, offset + 1);
if (g_ip_dscp_actif) {
col_add_str(pinfo->cinfo, COL_DSCP_VALUE,
val_to_str_ext(IPDSFIELD_DSCP(iph->ip_tos), &dscp_short_vals_ext, "%u"));
@@ -2044,10 +2124,10 @@ dissect_ip_v4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void*
tf = proto_tree_add_uint_format_value(ip_tree, hf_ip_frag_offset, tvb, offset + 6, 2,
iph->ip_off, "%u", (iph->ip_off & IP_OFFSET) * 8);
- iph->ip_ttl = tvb_get_guint8(tvb, offset + 8);
+ iph->ip_ttl = tvb_get_uint8(tvb, offset + 8);
ttl_item = proto_tree_add_item(ip_tree, hf_ip_ttl, tvb, offset + 8, 1, ENC_BIG_ENDIAN);
- iph->ip_proto = tvb_get_guint8(tvb, offset + 9);
+ iph->ip_proto = tvb_get_uint8(tvb, offset + 9);
if (tree) {
proto_tree_add_item(ip_tree, hf_ip_proto, tvb, offset + 9, 1, ENC_BIG_ENDIAN);
}
@@ -2195,7 +2275,7 @@ dissect_ip_v4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void*
}
if (dst_off) {
- guint32 cur_rt;
+ uint32_t cur_rt;
cur_rt = tvb_get_ipv4(tvb, offset + 16);
if (ip_summary_in_tree) {
@@ -2237,7 +2317,7 @@ dissect_ip_v4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void*
dissect_ip_options(tvb, offset + 20, optlen, pinfo, field_tree, tf, iph);
}
- p_add_proto_data(pinfo->pool, pinfo, proto_ip, pinfo->curr_layer_num, GUINT_TO_POINTER((guint)iph->ip_proto));
+ p_add_proto_data(pinfo->pool, pinfo, proto_ip, pinfo->curr_layer_num, GUINT_TO_POINTER((unsigned)iph->ip_proto));
tap_queue_packet(ip_tap, pinfo, iph);
/* Skip over header + options */
@@ -2252,7 +2332,7 @@ dissect_ip_v4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void*
iph->ip_len > hlen &&
tvb_bytes_exist(tvb, offset, iph->ip_len - hlen) &&
ipsum == 0) {
- guint32 frag_id;
+ uint32_t frag_id;
frag_id = iph->ip_proto ^ iph->ip_id ^ src32 ^ dst32;
/* XXX: Should there be a way to force the VLAN ID not to
* be taken into account for reassembly even with non publicly
@@ -2294,12 +2374,40 @@ dissect_ip_v4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void*
* tell the next protocol that.
*/
if (iph->ip_off & IP_MF)
- pinfo->fragmented = TRUE;
+ pinfo->fragmented = true;
else
- pinfo->fragmented = FALSE;
+ pinfo->fragmented = false;
+ }
+ }
+
+ conversation_t *conv;
+
+ /* find (and extend) an existing conversation, or create a new one */
+ conv = find_conversation_strat(pinfo, CONVERSATION_IP, NO_PORT_X);
+ if(!conv) {
+ conv=conversation_new_strat(pinfo, CONVERSATION_IP, NO_PORTS);
+ }
+ else {
+ /*
+ * while not strictly necessary because there is only 1
+ * conversation between 2 IPs, we still move the last frame
+ * indicator as being a usual practice.
+ */
+ if (!(pinfo->fd->visited)) {
+ if (pinfo->num > conv->last_frame) {
+ conv->last_frame = pinfo->num;
+ }
}
}
+ ipd = get_ip_conversation_data(conv, pinfo);
+ if(ipd) {
+ iph->ip_stream = ipd->stream;
+
+ item = proto_tree_add_uint(ip_tree, hf_ip_stream, tvb, offset, 0, ipd->stream);
+ proto_item_set_generated(item);
+ }
+
if (next_tvb == NULL) {
/* Just show this as a fragment. */
col_add_fstr(pinfo->cinfo, COL_INFO,
@@ -2344,9 +2452,9 @@ dissect_ip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
{
proto_tree *ip_tree;
proto_item *ti, *tf;
- guint8 version;
+ uint8_t version;
- version = tvb_get_guint8(tvb, 0) >> 4;
+ version = tvb_get_uint8(tvb, 0) >> 4;
if(version == 4){
return dissect_ip_v4(tvb, pinfo, tree, data);
@@ -2366,11 +2474,11 @@ dissect_ip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
return 1;
}
-static gboolean
+static bool
dissect_ip_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
{
int length, tot_length;
- guint8 oct, version, ihl;
+ uint8_t oct, version, ihl;
/*
0 1 2 3
@@ -2383,9 +2491,9 @@ dissect_ip_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data
length = tvb_captured_length(tvb);
if(length<4){
/* Need at least 4 bytes to make some sort of decision */
- return FALSE;
+ return false;
}
- oct = tvb_get_guint8(tvb,0);
+ oct = tvb_get_uint8(tvb,0);
ihl = oct & 0x0f;
version = oct >> 4;
if(version == 6){
@@ -2433,18 +2541,18 @@ dissect_ip_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data
*/
if(length<8){
/* Need at least 8 bytes to make a decision */
- return FALSE;
+ return false;
}
tot_length = tvb_get_ntohs(tvb,4);
if((tot_length + 40) != (int)tvb_reported_length(tvb)){
- return FALSE;
+ return false;
}
call_dissector(ipv6_handle, tvb, pinfo, tree);
- return TRUE;
+ return true;
}
/* version == IPv4 , the minimum value for a correct header is 5 */
if((version != 4)|| (ihl < 5)){
- return FALSE;
+ return false;
}
/* Total Length is the length of the datagram, measured in octets,
* including internet header and data.
@@ -2452,11 +2560,17 @@ dissect_ip_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data
tot_length = tvb_get_ntohs(tvb,2);
if(tot_length != (int)tvb_reported_length(tvb)){
- return FALSE;
+ return false;
}
dissect_ip_v4(tvb, pinfo, tree, data);
- return TRUE;
+ return true;
+}
+
+static void
+ip_init(void)
+{
+ ip_stream_count = 0;
}
void
@@ -2541,6 +2655,10 @@ proto_register_ip(void)
{ "Source or Destination Host", "ip.host", FT_STRING, BASE_NONE,
NULL, 0x0, NULL, HFILL }},
+ { &hf_ip_stream,
+ { "Stream index", "ip.stream", FT_UINT32, BASE_DEC,
+ NULL, 0x0, NULL, HFILL }},
+
{ &hf_geoip_country,
{ "Source or Destination GeoIP Country", "ip.geoip.country",
FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
@@ -2613,7 +2731,7 @@ proto_register_ip(void)
{ &hf_ip_flags,
{ "Flags", "ip.flags", FT_UINT8, BASE_HEX,
- NULL, 0xE0, "Flags (3 bits)", HFILL }},
+ NULL, 0xE0, NULL, HFILL }},
{ &hf_ip_flags_sf,
{ "Security flag", "ip.flags.sf", FT_BOOLEAN, 8,
@@ -2633,7 +2751,7 @@ proto_register_ip(void)
{ &hf_ip_frag_offset,
{ "Fragment Offset", "ip.frag_offset", FT_UINT16, BASE_DEC,
- NULL, IP_OFFSET, "Fragment offset (13 bits)", HFILL }},
+ NULL, IP_OFFSET, NULL, HFILL }},
{ &hf_ip_ttl,
{ "Time to Live", "ip.ttl", FT_UINT8, BASE_DEC,
@@ -2904,7 +3022,7 @@ proto_register_ip(void)
};
- static gint *ett[] = {
+ static int *ett[] = {
&ett_ip,
&ett_ip_dsfield,
&ett_ip_tos,
@@ -2933,6 +3051,7 @@ proto_register_ip(void)
};
static ei_register_info ei[] = {
{ &ei_ip_opt_len_invalid, { "ip.opt.len.invalid", PI_PROTOCOL, PI_WARN, "Invalid length for option", EXPFILL }},
+ { &ei_ip_opt_deprecated, { "ip.opt.deprecated", PI_DEPRECATED, PI_NOTE, "Option type is deprecated", EXPFILL }},
{ &ei_ip_opt_sec_prot_auth_fti, { "ip.opt.len.invalid", PI_PROTOCOL, PI_WARN, "Field Termination Indicator set to 1 for last byte of option", EXPFILL }},
{ &ei_ip_extraneous_data, { "ip.opt.len.invalid", PI_PROTOCOL, PI_WARN, "Extraneous data in option", EXPFILL }},
{ &ei_ip_opt_ptr_before_address, { "ip.opt.ptr.before_address", PI_PROTOCOL, PI_WARN, "Pointer points before first address", EXPFILL }},
@@ -2969,7 +3088,7 @@ proto_register_ip(void)
proto_ip, FT_UINT8, BASE_DEC);
ip_option_table = register_dissector_table("ip.option", "IP Options",
proto_ip, FT_UINT8, BASE_DEC);
- heur_subdissector_list = register_heur_dissector_list("ip", proto_ip);
+ heur_subdissector_list = register_heur_dissector_list_with_description("ip", "IPv4 heuristic", proto_ip);
register_capture_dissector_table("ip.proto", "IP protocol");
/* Register configuration options */
@@ -3003,10 +3122,17 @@ proto_register_ip(void)
"Try to decode a packet using an heuristic sub-dissector before using a sub-dissector registered to a specific port",
&try_heuristic_first);
+ prefs_register_bool_preference(ip_module, "conv_agg_flag" ,
+ "Aggregate subnets in Statistics Dialogs",
+ "Whether to group conversations based on the subnets file",
+ &ip_conv_agg_flag);
+
prefs_register_static_text_preference(ip_module, "text_use_geoip",
"IP geolocation settings can be changed in the Name Resolution preferences",
"IP geolocation settings can be changed in the Name Resolution preferences");
+ register_init_routine(ip_init);
+
ip_handle = register_dissector("ip", dissect_ip, proto_ip);
reassembly_table_register(&ip_reassembly_table,
&addresses_reassembly_table_functions);
@@ -3016,7 +3142,7 @@ proto_register_ip(void)
exported_pdu_tap = register_export_pdu_tap_with_encap("IP", WTAP_ENCAP_RAW_IP);
register_decode_as(&ip_da);
- register_conversation_table(proto_ip, TRUE, ip_conversation_packet, ip_endpoint_packet);
+ register_conversation_table(proto_ip, true, ip_conversation_packet, ip_endpoint_packet);
register_conversation_filter("ip", "IPv4", ip_filter_valid, ip_build_filter, NULL);
ip_cap_handle = register_capture_dissector("ip", capture_ip, proto_ip);