# include "config.h"
#endif
-#include <stdio.h>
-#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <glib.h>
-#include <time.h>
#include <epan/packet.h>
#include <epan/prefs.h>
*
* Several command codes were missing, causing the dissector to abort decoding
* on valid packets. Those commands have been added.
- *
- * The semantics of Variation 0 have been cleaned up. Variation 0 is the
+ *
+ * The semantics of Variation 0 have been cleaned up. Variation 0 is the
* "Default Variation". It is used only in Master -> Slave read commands
- * to request the data in whatever variation the Slave is configured to use by
- * default. Decoder strings have been added to the Binary Output and
- * Analog Output objects (10 and 40) so that group read commands will
+ * to request the data in whatever variation the Slave is configured to use by
+ * default. Decoder strings have been added to the Binary Output and
+ * Analog Output objects (10 and 40) so that group read commands will
* decode properly.
*
* Roy M. Silvernail <roy@rant-central.com> 01/05/2009
#define DNP3_CTL_DFC 0x10
#define DNP3_CTL_FUNC 0x0f
-#define DNP3_TR_FIR 0x40
-#define DNP3_TR_FIN 0x80
-#define DNP3_TR_SEQ 0x3f
+#define DNP3_TR_FIR 0x40
+#define DNP3_TR_FIN 0x80
+#define DNP3_TR_SEQ 0x3f
#define AL_MAX_CHUNK_SIZE 16
/***************************************************************************/
/* Application Layer Bit-Masks */
/***************************************************************************/
+#define DNP3_AL_UNS 0x10
#define DNP3_AL_CON 0x20
#define DNP3_AL_FIN 0x40
#define DNP3_AL_FIR 0x80
-#define DNP3_AL_SEQ 0x1f
+#define DNP3_AL_SEQ 0x0f
#define DNP3_AL_FUNC 0xff
/***************************************************************************/
/* Application Layer Data Object Qualifier */
/***************************************************************************/
/* Bit-Masks */
-#define AL_OBJQ_INDEX 0x70 /* x111xxxx Masks Index from Qualifier */
-#define AL_OBJQ_CODE 0x0F /* xxxx1111 Masks Code from Qualifier */
+#define AL_OBJQ_INDEX 0x70 /* x111xxxx Masks Index from Qualifier */
+#define AL_OBJQ_CODE 0x0F /* xxxx1111 Masks Code from Qualifier */
/* Index Size (3-bits x111xxxx) */
/* When Qualifier Code != 11 */
-#define AL_OBJQL_IDX_NI 0x00 /* Objects are Packed with no index */
-#define AL_OBJQL_IDX_1O 0x01 /* Objects are prefixed w/ 1-octet index */
-#define AL_OBJQL_IDX_2O 0x02 /* Objects are prefixed w/ 2-octet index */
-#define AL_OBJQL_IDX_4O 0x03 /* Objects are prefixed w/ 4-octet index */
-#define AL_OBJQL_IDX_1OS 0x04 /* Objects are prefixed w/ 1-octet object size */
-#define AL_OBJQL_IDX_2OS 0x05 /* Objects are prefixed w/ 2-octet object size */
-#define AL_OBJQL_IDX_4OS 0x06 /* Objects are prefixed w/ 4-octet object size */
+#define AL_OBJQL_IDX_NI 0x00 /* Objects are Packed with no index */
+#define AL_OBJQL_IDX_1O 0x01 /* Objects are prefixed w/ 1-octet index */
+#define AL_OBJQL_IDX_2O 0x02 /* Objects are prefixed w/ 2-octet index */
+#define AL_OBJQL_IDX_4O 0x03 /* Objects are prefixed w/ 4-octet index */
+#define AL_OBJQL_IDX_1OS 0x04 /* Objects are prefixed w/ 1-octet object size */
+#define AL_OBJQL_IDX_2OS 0x05 /* Objects are prefixed w/ 2-octet object size */
+#define AL_OBJQL_IDX_4OS 0x06 /* Objects are prefixed w/ 4-octet object size */
/* When Qualifier Code == 11 */
#define AL_OBJQL_IDX11_1OIS 0x01 /* 1 octet identifier size */
#define AL_OBJ_AIFC_FLTT 0x2107 /* 33 07 32-Bit Floating Point Frozen Change Event w/ Time*/
#define AL_OBJ_AIFC_DBLT 0x2108 /* 33 08 64-Bit Floating Point Frozen Change Event w/ Time*/
-
/* Analog Input Quality Flags */
#define AL_OBJ_AI_FLAG0 0x0001 /* Point Online (0=Offline; 1=Online) */
#define AL_OBJ_AI_FLAG1 0x0002 /* Restart (0=Normal; 1=Restart) */
#define AL_OBJ_AI_FLAG6 0x0040 /* Reference Check (0=Normal; 1=Error) */
#define AL_OBJ_AI_FLAG7 0x0080 /* Reserved */
+#define AL_OBJ_AIDB_ALL 0x2200 /* 34 00 Analog Input Deadband Default Variation */
+#define AL_OBJ_AIDB_16 0x2201 /* 34 01 16-Bit Analog Input Deadband */
+#define AL_OBJ_AIDB_32 0x2202 /* 34 02 32-Bit Analog Input Deadband */
+#define AL_OBJ_AIDB_FLT 0x2203 /* 34 03 Floating Point Analog Input Deadband */
+
/***************************************************************************/
/* Analog Output Objects */
#define AL_OBJ_AO_ALL 0x2800 /* 40 00 Analog Output Default Variation */
static int hf_dnp3_al_fir = -1;
static int hf_dnp3_al_fin = -1;
static int hf_dnp3_al_con = -1;
+static int hf_dnp3_al_uns = -1;
static int hf_dnp3_al_seq = -1;
static int hf_dnp3_al_func = -1;
/* Added for Application Layer Decoding */
{ AL_FUNC_AUTHRESP, "Authentication Response" },
{ 0, NULL }
};
+static value_string_ext dnp3_al_func_vals_ext = VALUE_STRING_EXT_INIT(dnp3_al_func_vals);
/* Application Layer Internal Indication (IIN) bit Values */
static const value_string dnp3_al_iin_vals[] _U_ = {
{ AL_OBJQL_IDX_4OS, "4-Octet Object Size" },
{ 0, NULL }
};
+static value_string_ext dnp3_al_objq_index_vals_ext = VALUE_STRING_EXT_INIT(dnp3_al_objq_index_vals);
/* Application Layer Object Qualifier Code Values */
static const value_string dnp3_al_objq_code_vals[] = {
{ AL_OBJQL_CODE_SF8, "8-bit Single Field Quantity" },
{ AL_OBJQL_CODE_SF16, "16-bit Single Field Quantity" },
{ AL_OBJQL_CODE_SF32, "32-bit Single Field Quantity" },
+ { 10, "Reserved" },
{ AL_OBJQL_CODE_FF, "Free-format Qualifier" },
{ 0, NULL }
};
+static value_string_ext dnp3_al_objq_code_vals_ext = VALUE_STRING_EXT_INIT(dnp3_al_objq_code_vals);
/* Application Layer Data Object Values */
static const value_string dnp3_al_obj_vals[] = {
{ AL_OBJ_AIFC_DBLNT, "64-Bit Floating Point Frozen Change Event w/o Time (Obj:33, Var:06)" },
{ AL_OBJ_AIFC_FLTT, "32-Bit Floating Point Frozen Change Event w/ Time (Obj:33, Var:07)" },
{ AL_OBJ_AIFC_DBLT, "64-Bit Floating Point Frozen Change Event w/ Time (Obj:33, Var:08)" },
+ { AL_OBJ_AIDB_ALL, "Analog Input Deadband Default Variation (Obj:34, Var:Default)" },
+ { AL_OBJ_AIDB_16, "16-Bit Analog Input Deadband (Obj:34, Var:01)" },
+ { AL_OBJ_AIDB_32, "32-Bit Analog Input Deadband (Obj:34, Var:02)" },
+ { AL_OBJ_AIDB_FLT, "32-Bit Floating Point Analog Input Deadband (Obj:34, Var:03)" },
{ AL_OBJ_AO_ALL, "Analog Output Default Variation (Obj:40, Var:Default)" },
{ AL_OBJ_AO_32, "32-Bit Analog Output Status (Obj:40, Var:01)" },
{ AL_OBJ_AO_16, "16-Bit Analog Output Status (Obj:40, Var:02)" },
{ AL_OBJ_OCT, "Octet String (Obj:110)" },
{ 0, NULL }
};
+static value_string_ext dnp3_al_obj_vals_ext = VALUE_STRING_EXT_INIT(dnp3_al_obj_vals);
/* Application Layer Control Code 'Code' Values */
static const value_string dnp3_al_ctlc_code_vals[] = {
{ AL_OBJCTL_STAT10, "Req. Not Accepted; Local automation proc active" },
{ 0, NULL }
};
+static value_string_ext dnp3_al_ctl_status_vals_ext = VALUE_STRING_EXT_INIT(dnp3_al_ctl_status_vals);
/* Application Layer Binary Input Quality Flag Values */
static const value_string dnp3_al_biflag_vals[] _U_ = {
static int hf_dnp3_fragment_too_long_fragment = -1;
static int hf_dnp3_fragment_error = -1;
static int hf_dnp3_fragment_reassembled_in = -1;
+static int hf_dnp3_fragment_reassembled_length = -1;
static gint ett_dnp3_fragment = -1;
static gint ett_dnp3_fragments = -1;
&hf_dnp3_fragment_too_long_fragment,
&hf_dnp3_fragment_error,
&hf_dnp3_fragment_reassembled_in,
+ &hf_dnp3_fragment_reassembled_length,
"DNP 3.0 fragments"
};
/* Create Data Objects Detail Tree */
object_item = proto_tree_add_uint_format(robj_tree, hf_dnp3_al_obj, tvb, offset, 2, al_obj,
- "Object(s): %s (0x%04x)", val_to_str(al_obj, dnp3_al_obj_vals, "Unknown Object - Abort Decoding..."), al_obj);
+ "Object(s): %s (0x%04x)",
+ val_to_str_ext_const(al_obj, &dnp3_al_obj_vals_ext, "Unknown Object - Abort Decoding..."),
+ al_obj);
object_tree = proto_item_add_subtree(object_item, ett_dnp3_al_obj);
offset += 2;
al_objq_code = al_objq & AL_OBJQ_CODE;
qualifier_item = proto_tree_add_text(object_tree, tvb, offset, 1, "Qualifier Field, Prefix: %s, Code: %s",
- val_to_str(al_objq_index, dnp3_al_objq_index_vals, "Unknown Index Type"),
- val_to_str(al_objq_code, dnp3_al_objq_code_vals, "Unknown Code Type"));
+ val_to_str_ext_const(al_objq_index, &dnp3_al_objq_index_vals_ext, "Unknown Index Type"),
+ val_to_str_ext_const(al_objq_code, &dnp3_al_objq_code_vals_ext, "Unknown Code Type"));
qualifier_tree = proto_item_add_subtree(qualifier_item, ett_dnp3_al_obj_qualifier);
proto_tree_add_item(qualifier_tree, hf_dnp3_al_objq_index, tvb, offset, 1, FALSE);
proto_tree_add_item(qualifier_tree, hf_dnp3_al_objq_code, tvb, offset, 1, FALSE);
case AL_OBJ_CTRC_ALL: /* Binary Counter Change Default Variation (Obj:22 Var:Default) */
case AL_OBJ_AI_ALL: /* Analog Input Default Variation (Obj:30, Var:Default) */
case AL_OBJ_AIC_ALL: /* Analog Input Change Default Variation (Obj:32 Var:Default) */
+ case AL_OBJ_AIDB_ALL: /* Analog Input Deadband Default Variation (Obj:34, Var:Default) */
offset = data_pos;
break;
data_pos += 6;
al_bit = (al_ptflags & AL_OBJ_BI_FLAG7) >> 7; /* bit shift 1xxxxxxx -> xxxxxxx1 */
- proto_item_append_text(point_item, ", Value: %u, Timestamp: %s", al_bit, abs_time_to_str(&al_abstime));
+ proto_item_append_text(point_item, ", Value: %u, Timestamp: %s", al_bit, abs_time_to_str(&al_abstime, ABSOLUTE_TIME_LOCAL, TRUE));
proto_item_set_len(point_item, data_pos - offset);
offset = data_pos;
data_pos += 6;
al_2bit = (al_ptflags >> 6) & 3; /* bit shift 11xxxxxx -> 00000011 */
- proto_item_append_text(point_item, ", Value: %u, Timestamp: %s", al_2bit, abs_time_to_str(&al_abstime));
+ proto_item_append_text(point_item, ", Value: %u, Timestamp: %s", al_2bit, abs_time_to_str(&al_abstime, ABSOLUTE_TIME_LOCAL, TRUE));
proto_item_set_len(point_item, data_pos - offset);
offset = data_pos;
data_pos += 2;
al_bit = (al_ptflags & AL_OBJ_BI_FLAG7) >> 7; /* bit shift 1xxxxxxx -> xxxxxxx1 */
- proto_item_append_text(point_item, ", Value: %u, Timestamp: %s", al_bit, abs_time_to_str(&al_abstime));
+ proto_item_append_text(point_item, ", Value: %u, Timestamp: %s", al_bit, abs_time_to_str(&al_abstime, ABSOLUTE_TIME_LOCAL, TRUE));
proto_item_set_len(point_item, data_pos - offset);
offset = data_pos;
/* Bit-Mask xx11xxxx for Control Code Misc Values */
al_ctlobj_code_m = al_ctlobj_code & AL_OBJCTLC_MISC;
- ctl_misc_str = val_to_str(al_ctlobj_code_m, dnp3_al_ctlc_misc_vals, "");
+ ctl_misc_str = val_to_str_const(al_ctlobj_code_m, dnp3_al_ctlc_misc_vals, "");
/* Bit-Mask 11xxxxxx for Control Code 'Trip/Close' */
al_ctlobj_code_tc = al_ctlobj_code & AL_OBJCTLC_TC;
- ctl_tc_str = val_to_str(al_ctlobj_code_tc, dnp3_al_ctlc_tc_vals, "");
+ ctl_tc_str = val_to_str_const(al_ctlobj_code_tc, dnp3_al_ctlc_tc_vals, "");
/* Get "Count" Field */
al_ctlobj_count = tvb_get_guint8(tvb, data_pos);
al_ctlobj_stat = tvb_get_guint8(tvb, data_pos);
proto_tree_add_item(point_item, hf_dnp3_al_ctrlstatus, tvb, data_pos, 1, TRUE);
- ctl_status_str = val_to_str(al_ctlobj_stat, dnp3_al_ctl_status_vals, "Invalid Status (0x%02x)");
+ ctl_status_str = val_to_str_ext(al_ctlobj_stat, &dnp3_al_ctl_status_vals_ext, "Invalid Status (0x%02x)");
data_pos += 1;
proto_item_append_text(point_item, ", Control Code: [%s,%s,%s (0x%02x)]",
break;
case AL_OBJ_AO_DBLOPB:
al_valdbl = tvb_get_letohieee_double(tvb, data_pos);
- proto_item_append_text(point_item, ", Value: %lg", al_valdbl);
+ proto_item_append_text(point_item, ", Value: %g", al_valdbl);
proto_tree_add_item(point_tree, hf_dnp3_al_anaoutdbl, tvb, data_pos, 8, TRUE);
data_pos += 8;
break;
/* Get control status */
al_ctlobj_stat = tvb_get_guint8(tvb, data_pos);
- ctl_status_str = val_to_str(al_ctlobj_stat, dnp3_al_ctl_status_vals, "Invalid Status (0x%02x)");
+ ctl_status_str = val_to_str_ext(al_ctlobj_stat, &dnp3_al_ctl_status_vals_ext, "Invalid Status (0x%02x)");
proto_item_append_text(point_item, " [Status: %s (0x%02x)]", ctl_status_str, al_ctlobj_stat);
proto_tree_add_item(point_tree, hf_dnp3_al_ctrlstatus, tvb, data_pos, 1, TRUE);
data_pos += 1;
case AL_OBJ_FDCTRC_32T:
case AL_OBJ_FDCTRC_16T:
dnp3_al_get_timestamp(&al_abstime, tvb, data_pos);
- proto_item_append_text(point_item, ", Timestamp: %s", abs_time_to_str(&al_abstime));
+ proto_item_append_text(point_item, ", Timestamp: %s", abs_time_to_str(&al_abstime, ABSOLUTE_TIME_LOCAL, TRUE));
proto_tree_add_time(point_tree, hf_dnp3_al_timestamp, tvb, data_pos, 6, &al_abstime);
data_pos += 6;
break;
case AL_OBJ_AIFC_DBLNT: /* 64-Bit Floating Point Frozen Change Event w/o Time (Obj:33, Var:06) */
case AL_OBJ_AIFC_FLTT: /* 32-Bit Floating Point Frozen Change Event w/ Time (Obj:33, Var:07) */
case AL_OBJ_AIFC_DBLT: /* 64-Bit Floating Point Frozen Change Event w/ Time (Obj:33, Var:08) */
+ case AL_OBJ_AIDB_16: /* 16-Bit Analog Input Deadband (Obj:34, Var:01) */
+ case AL_OBJ_AIDB_32: /* 32-Bit Analog Input Deadband (Obj:34, Var:02) */
+ case AL_OBJ_AIDB_FLT: /* 32-Bit Floating Point Analog Input Deadband (Obj:34, Var:03) */
/* Get Point Flags for those types that have them */
switch (al_obj)
{
case AL_OBJ_AI_32NF:
case AL_OBJ_AI_16NF:
+ case AL_OBJ_AIDB_16:
+ case AL_OBJ_AIDB_32:
+ case AL_OBJ_AIDB_FLT:
break;
default:
case AL_OBJ_AI_32NF:
case AL_OBJ_AIC_32NT:
case AL_OBJ_AIC_32T:
+ case AL_OBJ_AIDB_32:
al_val32 = tvb_get_letohl(tvb, data_pos);
proto_item_append_text(point_item, ", Value: %u", al_val32);
case AL_OBJ_AI_16NF:
case AL_OBJ_AIC_16NT:
case AL_OBJ_AIC_16T:
+ case AL_OBJ_AIDB_16:
al_val16 = tvb_get_letohs(tvb, data_pos);
proto_item_append_text(point_item, ", Value: %u", al_val16);
case AL_OBJ_AIC_FLTT:
case AL_OBJ_AIFC_FLTNT:
case AL_OBJ_AIFC_FLTT:
+ case AL_OBJ_AIDB_FLT:
al_valflt = tvb_get_letohieee_float(tvb, data_pos);
proto_item_append_text(point_item, ", Value: %g", al_valflt);
case AL_OBJ_AIFC_DBLT:
al_valdbl = tvb_get_letohieee_double(tvb, data_pos);
- proto_item_append_text(point_item, ", Value: %lg", al_valdbl);
+ proto_item_append_text(point_item, ", Value: %g", al_valdbl);
proto_tree_add_item(point_tree, hf_dnp3_al_anadbl, tvb, data_pos, 8, TRUE);
data_pos += 8;
break;
case AL_OBJ_AIFC_FLTT:
case AL_OBJ_AIFC_DBLT:
dnp3_al_get_timestamp(&al_abstime, tvb, data_pos);
- proto_item_append_text(point_item, ", Timestamp: %s", abs_time_to_str(&al_abstime));
+ proto_item_append_text(point_item, ", Timestamp: %s", abs_time_to_str(&al_abstime, ABSOLUTE_TIME_LOCAL, TRUE));
proto_tree_add_time(point_tree, hf_dnp3_al_timestamp, tvb, data_pos, 6, &al_abstime);
data_pos += 6;
break;
case AL_OBJ_AO_DBL: /* 64-Bit Floating Point Output Status (Obj:40, Var:04) */
al_valdbl = tvb_get_letohieee_double(tvb, data_pos);
- proto_item_append_text(point_item, ", Value: %lg", al_valdbl);
+ proto_item_append_text(point_item, ", Value: %g", al_valdbl);
proto_tree_add_item(point_tree, hf_dnp3_al_anaoutdbl, tvb, data_pos, 8, TRUE);
data_pos += 8;
break;
{
guint8 al_ctl, al_seq, al_func, al_class = 0, i;
guint16 bytes, obj_type;
- gboolean al_fir, al_fin, al_con;
+ gboolean al_fir, al_fin, al_con, al_uns;
guint data_len = 0, offset = 0;
proto_item *ti = NULL, *tc, *t_robj;
proto_tree *al_tree = NULL, *field_tree = NULL, *robj_tree = NULL;
al_fir = al_ctl & DNP3_AL_FIR;
al_fin = al_ctl & DNP3_AL_FIN;
al_con = al_ctl & DNP3_AL_CON;
+ al_uns = al_ctl & DNP3_AL_UNS;
al_func = tvb_get_guint8(tvb, (offset+1));
- func_code_str = val_to_str(al_func, dnp3_al_func_vals, "Unknown function (0x%02x)");
+ func_code_str = val_to_str_ext(al_func, &dnp3_al_func_vals_ext, "Unknown function (0x%02x)");
if (check_col(pinfo->cinfo, COL_INFO))
col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL, "%s", func_code_str);
if (al_ctl & DNP3_AL_FIR) proto_item_append_text(tc, "FIR, ");
if (al_ctl & DNP3_AL_FIN) proto_item_append_text(tc, "FIN, ");
if (al_ctl & DNP3_AL_CON) proto_item_append_text(tc, "CON, ");
+ if (al_ctl & DNP3_AL_UNS) proto_item_append_text(tc, "UNS, ");
proto_item_append_text(tc, "Sequence %u)", al_seq);
field_tree = proto_item_add_subtree(tc, ett_dnp3_al_ctl);
proto_tree_add_boolean(field_tree, hf_dnp3_al_fir, tvb, offset, 1, al_ctl);
proto_tree_add_boolean(field_tree, hf_dnp3_al_fin, tvb, offset, 1, al_ctl);
proto_tree_add_boolean(field_tree, hf_dnp3_al_con, tvb, offset, 1, al_ctl);
+ proto_tree_add_boolean(field_tree, hf_dnp3_al_uns, tvb, offset, 1, al_ctl);
proto_tree_add_item(field_tree, hf_dnp3_al_seq, tvb, offset, 1, FALSE);
offset += 1;
+#if 0
/* If this packet is NOT the final Application Layer Message, exit and continue
- processing the remaining data in the fragment.
+ processing the remaining data in the fragment. */
if (!al_fin)
{
t_robj = proto_tree_add_text(al_tree, tvb, offset, -1, "Buffering User Data Until Final Frame is Received..");
return 1;
- } */
+ }
+#endif
/* Application Layer Function Code Byte */
proto_tree_add_uint_format(al_tree, hf_dnp3_al_func, tvb, offset, 1, al_func,
/* Make entries in Protocol column and Info column on summary display */
- if (check_col(pinfo->cinfo, COL_PROTOCOL))
- col_set_str(pinfo->cinfo, COL_PROTOCOL, "DNP 3.0");
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "DNP 3.0");
- if (check_col(pinfo->cinfo, COL_INFO))
- col_clear(pinfo->cinfo, COL_INFO);
+ col_clear(pinfo->cinfo, COL_INFO);
/* Skip "0x0564" header bytes */
temp_offset += 2;
/* XXX - check for dl_len <= 5 */
data_len = dl_len - 5;
- tmp = ep_alloc(data_len);
+ tmp = g_malloc(data_len);
tmp_ptr = tmp;
i = 0;
data_offset = 1; /* skip the transport layer byte when assembling chunks */
/* if all crc OK, set up new tvb */
if (crc_OK)
{
- al_tvb = tvb_new_real_data(tmp, (guint) (tmp_ptr-tmp), (gint) (tmp_ptr-tmp));
- tvb_set_child_real_data_tvbuff(tvb, al_tvb);
+ al_tvb = tvb_new_child_real_data(tvb, tmp, (guint) (tmp_ptr-tmp), (gint) (tmp_ptr-tmp));
+ tvb_set_free_cb(al_tvb, g_free);
/* Check for fragmented packet */
save_fragmented = pinfo->fragmented;
pinfo->fragmented = TRUE;
/* Look up the conversation to get the fragment reassembly id */
- conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
- pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
-
- if (conversation == NULL) {
- /* No conversation yet, so make one */
- conversation = conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype,
- pinfo->srcport, pinfo->destport, 0);
- }
+ conversation = find_or_create_conversation(pinfo);
conv_data_ptr = (dnp3_conv_t*)conversation_get_proto_data(conversation, proto_dnp3);
if (next_tvb) { /* Reassembled */
/* We have the complete payload */
if (check_col (pinfo->cinfo, COL_INFO))
- col_add_str (pinfo->cinfo, COL_INFO,
- "Reassembled Application Layer");
+ col_set_str(pinfo->cinfo, COL_INFO, "Reassembled Application Layer");
col_set_fence(pinfo->cinfo, COL_INFO);
}
else
/* No reassembly required */
next_tvb = al_tvb;
add_new_data_source(pinfo, next_tvb, "DNP 3.0 Application Layer message");
- if (check_col (pinfo->cinfo, COL_INFO))
- col_clear (pinfo->cinfo, COL_INFO);
+ col_clear(pinfo->cinfo, COL_INFO);
}
pinfo->fragmented = save_fragmented;
}
{
/* CRC error - throw away the data. */
next_tvb = NULL;
+ g_free(tmp);
proto_tree_add_text(dnp3_tree, tvb, 11, -1, "CRC failed, %u chunks", i);
}
return length;
}
-static void
-dnp3_init(void)
-{
-}
-
static void
al_defragment_init(void)
{
/* Setup list of header fields */
static hf_register_info hf[] = {
{ &hf_dnp3_start,
- { "Start Bytes", "dnp3.start", FT_UINT16, BASE_HEX, NULL, 0x0, "Start Bytes", HFILL }},
+ { "Start Bytes", "dnp3.start", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
{ &hf_dnp3_len,
{ "Length", "dnp3.len", FT_UINT8, BASE_DEC, NULL, 0x0, "Frame Data Length", HFILL }},
VALS(dnp3_ctl_func_sec_vals), DNP3_CTL_FUNC, "Frame Control Function Code", HFILL }},
{ &hf_dnp3_ctl_dir,
- { "Direction", "dnp3.ctl.dir", FT_BOOLEAN, 8, TFS(&tfs_set_notset), DNP3_CTL_DIR, "", HFILL }},
+ { "Direction", "dnp3.ctl.dir", FT_BOOLEAN, 8, TFS(&tfs_set_notset), DNP3_CTL_DIR, NULL, HFILL }},
{ &hf_dnp3_ctl_prm,
- { "Primary", "dnp3.ctl.prm", FT_BOOLEAN, 8, TFS(&tfs_set_notset), DNP3_CTL_PRM, "", HFILL }},
+ { "Primary", "dnp3.ctl.prm", FT_BOOLEAN, 8, TFS(&tfs_set_notset), DNP3_CTL_PRM, NULL, HFILL }},
{ &hf_dnp3_ctl_fcb,
- { "Frame Count Bit", "dnp3.ctl.fcb", FT_BOOLEAN, 8, TFS(&tfs_set_notset), DNP3_CTL_FCB, "", HFILL }},
+ { "Frame Count Bit", "dnp3.ctl.fcb", FT_BOOLEAN, 8, TFS(&tfs_set_notset), DNP3_CTL_FCB, NULL, HFILL }},
{ &hf_dnp3_ctl_fcv,
- { "Frame Count Valid", "dnp3.ctl.fcv", FT_BOOLEAN, 8, TFS(&tfs_set_notset), DNP3_CTL_FCV, "", HFILL }},
+ { "Frame Count Valid", "dnp3.ctl.fcv", FT_BOOLEAN, 8, TFS(&tfs_set_notset), DNP3_CTL_FCV, NULL, HFILL }},
{ &hf_dnp3_ctl_dfc,
- { "Data Flow Control", "dnp3.ctl.dfc", FT_BOOLEAN, 8, TFS(&tfs_set_notset), DNP3_CTL_DFC, "", HFILL }},
+ { "Data Flow Control", "dnp3.ctl.dfc", FT_BOOLEAN, 8, TFS(&tfs_set_notset), DNP3_CTL_DFC, NULL, HFILL }},
{ &hf_dnp3_dst,
{ "Destination", "dnp3.dst", FT_UINT16, BASE_DEC, NULL, 0x0, "Destination Address", HFILL }},
{ "Source", "dnp3.src", FT_UINT16, BASE_DEC, NULL, 0x0, "Source Address", HFILL }},
{ &hf_dnp_hdr_CRC,
- { "CRC", "dnp3.hdr.CRC", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }},
+ { "CRC", "dnp3.hdr.CRC", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
{ &hf_dnp_hdr_CRC_bad,
- { "Bad CRC", "dnp3.hdr.CRC_bad", FT_BOOLEAN, BASE_NONE, NULL, 0x0, "", HFILL }},
+ { "Bad CRC", "dnp3.hdr.CRC_bad", FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL }},
{ &hf_dnp3_tr_ctl,
{ "Transport Control", "dnp3.tr.ctl", FT_UINT8, BASE_HEX, NULL, 0x0, "Transport Layer Control Byte", HFILL }},
{ &hf_dnp3_tr_fin,
- { "Final", "dnp3.tr.fin", FT_BOOLEAN, 8, TFS(&tfs_set_notset), DNP3_TR_FIN, "", HFILL }},
+ { "Final", "dnp3.tr.fin", FT_BOOLEAN, 8, TFS(&tfs_set_notset), DNP3_TR_FIN, NULL, HFILL }},
{ &hf_dnp3_tr_fir,
- { "First", "dnp3.tr.fir", FT_BOOLEAN, 8, TFS(&tfs_set_notset), DNP3_TR_FIR, "", HFILL }},
+ { "First", "dnp3.tr.fir", FT_BOOLEAN, 8, TFS(&tfs_set_notset), DNP3_TR_FIR, NULL, HFILL }},
{ &hf_dnp3_tr_seq,
{ "Sequence", "dnp3.tr.seq", FT_UINT8, BASE_DEC, NULL, DNP3_TR_SEQ, "Frame Sequence Number", HFILL }},
{ "Application Control", "dnp3.al.ctl", FT_UINT8, BASE_HEX, NULL, 0x0, "Application Layer Control Byte", HFILL }},
{ &hf_dnp3_al_fir,
- { "First", "dnp3.al.fir", FT_BOOLEAN, 8, TFS(&tfs_set_notset), DNP3_AL_FIR, "", HFILL }},
+ { "First", "dnp3.al.fir", FT_BOOLEAN, 8, TFS(&tfs_set_notset), DNP3_AL_FIR, NULL, HFILL }},
{ &hf_dnp3_al_fin,
- { "Final", "dnp3.al.fin", FT_BOOLEAN, 8, TFS(&tfs_set_notset), DNP3_AL_FIN, "", HFILL }},
+ { "Final", "dnp3.al.fin", FT_BOOLEAN, 8, TFS(&tfs_set_notset), DNP3_AL_FIN, NULL, HFILL }},
{ &hf_dnp3_al_con,
- { "Confirm", "dnp3.al.con", FT_BOOLEAN, 8, TFS(&tfs_set_notset), DNP3_AL_CON, "", HFILL }},
+ { "Confirm", "dnp3.al.con", FT_BOOLEAN, 8, TFS(&tfs_set_notset), DNP3_AL_CON, NULL, HFILL }},
+
+ { &hf_dnp3_al_uns,
+ { "Unsolicited", "dnp3.al.uns", FT_BOOLEAN, 8, TFS(&tfs_set_notset), DNP3_AL_UNS, NULL, HFILL }},
{ &hf_dnp3_al_seq,
{ "Sequence", "dnp3.al.seq", FT_UINT8, BASE_DEC, NULL, DNP3_AL_SEQ, "Frame Sequence Number", HFILL }},
{ &hf_dnp3_al_func,
- { "Application Layer Function Code", "dnp3.al.func", FT_UINT8, BASE_DEC,
- VALS(dnp3_al_func_vals), DNP3_AL_FUNC, "Application Function Code", HFILL }},
+ { "Application Layer Function Code", "dnp3.al.func", FT_UINT8, BASE_DEC|BASE_EXT_STRING,
+ &dnp3_al_func_vals_ext, DNP3_AL_FUNC, "Application Function Code", HFILL }},
{ &hf_dnp3_al_iin,
{ "Application Layer IIN bits", "dnp3.al.iin", FT_UINT16, BASE_DEC, NULL, 0x0, "Application Layer IIN", HFILL }},
{ &hf_dnp3_al_iin_bmsg,
- { "Broadcast Msg Rx", "dnp3.al.iin.bmsg", FT_BOOLEAN, 16, TFS(&tfs_set_notset), AL_IIN_BMSG, "", HFILL }},
+ { "Broadcast Msg Rx", "dnp3.al.iin.bmsg", FT_BOOLEAN, 16, TFS(&tfs_set_notset), AL_IIN_BMSG, NULL, HFILL }},
{ &hf_dnp3_al_iin_cls1d,
- { "Class 1 Data Available", "dnp3.al.iin.cls1d", FT_BOOLEAN, 16, TFS(&tfs_set_notset), AL_IIN_CLS1D, "", HFILL }},
+ { "Class 1 Data Available", "dnp3.al.iin.cls1d", FT_BOOLEAN, 16, TFS(&tfs_set_notset), AL_IIN_CLS1D, NULL, HFILL }},
{ &hf_dnp3_al_iin_cls2d,
- { "Class 2 Data Available", "dnp3.al.iin.cls2d", FT_BOOLEAN, 16, TFS(&tfs_set_notset), AL_IIN_CLS2D, "", HFILL }},
+ { "Class 2 Data Available", "dnp3.al.iin.cls2d", FT_BOOLEAN, 16, TFS(&tfs_set_notset), AL_IIN_CLS2D, NULL, HFILL }},
{ &hf_dnp3_al_iin_cls3d,
- { "Class 3 Data Available", "dnp3.al.iin.cls3d", FT_BOOLEAN, 16, TFS(&tfs_set_notset), AL_IIN_CLS3D, "", HFILL }},
+ { "Class 3 Data Available", "dnp3.al.iin.cls3d", FT_BOOLEAN, 16, TFS(&tfs_set_notset), AL_IIN_CLS3D, NULL, HFILL }},
{ &hf_dnp3_al_iin_tsr,
- { "Time Sync Required", "dnp3.al.iin.tsr", FT_BOOLEAN, 16, TFS(&tfs_set_notset), AL_IIN_TSR, "", HFILL }},
+ { "Time Sync Required", "dnp3.al.iin.tsr", FT_BOOLEAN, 16, TFS(&tfs_set_notset), AL_IIN_TSR, NULL, HFILL }},
{ &hf_dnp3_al_iin_dol,
- { "Digital Outputs in Local", "dnp3.al.iin.dol", FT_BOOLEAN, 16, TFS(&tfs_set_notset), AL_IIN_DOL, "", HFILL }},
+ { "Digital Outputs in Local", "dnp3.al.iin.dol", FT_BOOLEAN, 16, TFS(&tfs_set_notset), AL_IIN_DOL, NULL, HFILL }},
{ &hf_dnp3_al_iin_dt,
- { "Device Trouble", "dnp3.al.iin.dt", FT_BOOLEAN, 16, TFS(&tfs_set_notset), AL_IIN_DT, "", HFILL }},
+ { "Device Trouble", "dnp3.al.iin.dt", FT_BOOLEAN, 16, TFS(&tfs_set_notset), AL_IIN_DT, NULL, HFILL }},
{ &hf_dnp3_al_iin_rst,
- { "Device Restart", "dnp3.al.iin.rst", FT_BOOLEAN, 16, TFS(&tfs_set_notset), AL_IIN_RST, "", HFILL }},
+ { "Device Restart", "dnp3.al.iin.rst", FT_BOOLEAN, 16, TFS(&tfs_set_notset), AL_IIN_RST, NULL, HFILL }},
{ &hf_dnp3_al_iin_obju,
- { "Requested Objects Unknown", "dnp3.al.iin.obju", FT_BOOLEAN, 16, TFS(&tfs_set_notset), AL_IIN_OBJU, "", HFILL }},
+ { "Requested Objects Unknown", "dnp3.al.iin.obju", FT_BOOLEAN, 16, TFS(&tfs_set_notset), AL_IIN_OBJU, NULL, HFILL }},
{ &hf_dnp3_al_iin_pioor,
- { "Parameters Invalid or Out of Range", "dnp3.al.iin.pioor", FT_BOOLEAN, 16, TFS(&tfs_set_notset), AL_IIN_PIOOR, "", HFILL }},
+ { "Parameters Invalid or Out of Range", "dnp3.al.iin.pioor", FT_BOOLEAN, 16, TFS(&tfs_set_notset), AL_IIN_PIOOR, NULL, HFILL }},
{ &hf_dnp3_al_iin_ebo,
- { "Event Buffer Overflow", "dnp3.al.iin.ebo", FT_BOOLEAN, 16, TFS(&tfs_set_notset), AL_IIN_EBO, "", HFILL }},
+ { "Event Buffer Overflow", "dnp3.al.iin.ebo", FT_BOOLEAN, 16, TFS(&tfs_set_notset), AL_IIN_EBO, NULL, HFILL }},
{ &hf_dnp3_al_iin_oae,
- { "Operation Already Executing", "dnp3.al.iin.oae", FT_BOOLEAN, 16, TFS(&tfs_set_notset), AL_IIN_OAE, "", HFILL }},
+ { "Operation Already Executing", "dnp3.al.iin.oae", FT_BOOLEAN, 16, TFS(&tfs_set_notset), AL_IIN_OAE, NULL, HFILL }},
{ &hf_dnp3_al_iin_cc,
- { "Configuration Corrupt", "dnp3.al.iin.cc", FT_BOOLEAN, 16, TFS(&tfs_set_notset), AL_IIN_CC, "", HFILL }},
+ { "Configuration Corrupt", "dnp3.al.iin.cc", FT_BOOLEAN, 16, TFS(&tfs_set_notset), AL_IIN_CC, NULL, HFILL }},
{ &hf_dnp3_al_obj,
- { "Object", "dnp3.al.obj", FT_UINT16, BASE_HEX, VALS(dnp3_al_obj_vals), 0x0, "Application Layer Object", HFILL }},
+ { "Object", "dnp3.al.obj", FT_UINT16, BASE_HEX|BASE_EXT_STRING, &dnp3_al_obj_vals_ext, 0x0, "Application Layer Object", HFILL }},
{ &hf_dnp3_al_objq_index,
- { "Index Prefix", "dnp3.al.objq.index", FT_UINT8, BASE_DEC, VALS(dnp3_al_objq_index_vals), AL_OBJQ_INDEX, "Object Index Prefixing", HFILL }},
+ { "Index Prefix", "dnp3.al.objq.index", FT_UINT8, BASE_DEC|BASE_EXT_STRING, &dnp3_al_objq_index_vals_ext, AL_OBJQ_INDEX, "Object Index Prefixing", HFILL }},
{ &hf_dnp3_al_objq_code,
- { "Qualifier Code", "dnp3.al.objq.code", FT_UINT8, BASE_DEC, VALS(dnp3_al_objq_code_vals), AL_OBJQ_CODE, "Object Qualifier Code", HFILL }},
+ { "Qualifier Code", "dnp3.al.objq.code", FT_UINT8, BASE_DEC|BASE_EXT_STRING, &dnp3_al_objq_code_vals_ext, AL_OBJQ_CODE, "Object Qualifier Code", HFILL }},
{ &hf_dnp3_al_range_start8,
{ "Start (8 bit)", "dnp3.al.range.start", FT_UINT8, BASE_DEC, NULL, 0x0, "Object Start Index", HFILL }},
{ "Index (32 bit)", "dnp3.al.index", FT_UINT32, BASE_DEC, NULL, 0x0, "Object Index", HFILL }},
{ &hf_dnp3_al_ptnum,
- { "Object Point Number", "dnp3.al.ptnum", FT_UINT16, BASE_DEC, NULL, 0x0, "Object Point Number", HFILL }},
+ { "Object Point Number", "dnp3.al.ptnum", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
{ &hf_dnp3_al_bit,
- { "Value (bit)", "dnp3.al.bit", FT_BOOLEAN, BASE_NONE, TFS(&tfs_on_off), 0x1, "Digital Value (1 bit)", HFILL }},
+ { "Value (bit)", "dnp3.al.bit", FT_BOOLEAN, 8, TFS(&tfs_on_off), 0x1, "Digital Value (1 bit)", HFILL }},
{ &hf_dnp3_al_2bit,
{ "Value (two bit)", "dnp3.al.2bit", FT_UINT8, BASE_DEC, NULL, 0x0, "Digital Value (2 bit)", HFILL }},
{ "Value (32 bit)", "dnp3.al.ana", FT_UINT32, BASE_DEC, NULL, 0x0, "Analog Value (32 bit)", HFILL }},
{ &hf_dnp3_al_anaflt,
- { "Value (float)", "dnp3.al.ana", FT_FLOAT, BASE_DEC, NULL, 0x0, "Analog Value (float)", HFILL }},
+ { "Value (float)", "dnp3.al.ana", FT_FLOAT, BASE_NONE, NULL, 0x0, "Analog Value (float)", HFILL }},
{ &hf_dnp3_al_anadbl,
- { "Value (double)", "dnp3.al.ana", FT_DOUBLE, BASE_DEC, NULL, 0x0, "Analog Value (double)", HFILL }},
+ { "Value (double)", "dnp3.al.ana", FT_DOUBLE, BASE_NONE, NULL, 0x0, "Analog Value (double)", HFILL }},
{ &hf_dnp3_al_anaout16,
- { "Output Value (16 bit)", "dnp3.al.anaout", FT_UINT16, BASE_DEC, NULL, 0x0, "Output Value (16 bit)", HFILL }},
+ { "Output Value (16 bit)", "dnp3.al.anaout", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
{ &hf_dnp3_al_anaout32,
- { "Output Value (32 bit)", "dnp3.al.anaout", FT_UINT32, BASE_DEC, NULL, 0x0, "Output Value (32 bit)", HFILL }},
+ { "Output Value (32 bit)", "dnp3.al.anaout", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
{ &hf_dnp3_al_anaoutflt,
- { "Output Value (float)", "dnp3.al.anaout", FT_FLOAT, BASE_DEC, NULL, 0x0, "Output Value (float)", HFILL }},
+ { "Output Value (float)", "dnp3.al.anaout", FT_FLOAT, BASE_NONE, NULL, 0x0, NULL, HFILL }},
{ &hf_dnp3_al_anaoutdbl,
- { "Output (double)", "dnp3.al.anaout", FT_DOUBLE, BASE_DEC, NULL, 0x0, "Output Value (double)", HFILL }},
+ { "Output (double)", "dnp3.al.anaout", FT_DOUBLE, BASE_NONE, NULL, 0x0, "Output Value (double)", HFILL }},
{ &hf_dnp3_al_cnt16,
{ "Counter (16 bit)", "dnp3.al.cnt", FT_UINT16, BASE_DEC, NULL, 0x0, "Counter Value (16 bit)", HFILL }},
{ "Counter (32 bit)", "dnp3.al.cnt", FT_UINT32, BASE_DEC, NULL, 0x0, "Counter Value (32 bit)", HFILL }},
{ &hf_dnp3_al_ctrlstatus,
- { "Control Status", "dnp3.al.ctrlstatus", FT_UINT8, BASE_DEC, dnp3_al_ctl_status_vals, 0xff, "Control Status", HFILL }},
+ { "Control Status", "dnp3.al.ctrlstatus", FT_UINT8, BASE_DEC|BASE_EXT_STRING, &dnp3_al_ctl_status_vals_ext, 0xff, NULL, HFILL }},
{ &hf_dnp3_al_biq_b0,
- { "Online", "dnp3.al.biq.b0", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_BI_FLAG0, "", HFILL }},
+ { "Online", "dnp3.al.biq.b0", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_BI_FLAG0, NULL, HFILL }},
{ &hf_dnp3_al_biq_b1,
- { "Restart", "dnp3.al.biq.b1", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_BI_FLAG1, "", HFILL }},
+ { "Restart", "dnp3.al.biq.b1", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_BI_FLAG1, NULL, HFILL }},
{ &hf_dnp3_al_biq_b2,
- { "Comm Fail", "dnp3.al.biq.b2", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_BI_FLAG2, "", HFILL }},
+ { "Comm Fail", "dnp3.al.biq.b2", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_BI_FLAG2, NULL, HFILL }},
{ &hf_dnp3_al_biq_b3,
- { "Remote Force", "dnp3.al.biq.b3", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_BI_FLAG3, "", HFILL }},
+ { "Remote Force", "dnp3.al.biq.b3", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_BI_FLAG3, NULL, HFILL }},
{ &hf_dnp3_al_biq_b4,
- { "Local Force", "dnp3.al.biq.b4", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_BI_FLAG4, "", HFILL }},
+ { "Local Force", "dnp3.al.biq.b4", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_BI_FLAG4, NULL, HFILL }},
{ &hf_dnp3_al_biq_b5,
- { "Chatter Filter", "dnp3.al.biq.b5", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_BI_FLAG5, "", HFILL }},
+ { "Chatter Filter", "dnp3.al.biq.b5", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_BI_FLAG5, NULL, HFILL }},
{ &hf_dnp3_al_biq_b6,
- { "Reserved", "dnp3.al.biq.b6", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_BI_FLAG6, "", HFILL }},
+ { "Reserved", "dnp3.al.biq.b6", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_BI_FLAG6, NULL, HFILL }},
{ &hf_dnp3_al_biq_b7,
- { "Point Value", "dnp3.al.biq.b7", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_BI_FLAG7, "", HFILL }},
+ { "Point Value", "dnp3.al.biq.b7", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_BI_FLAG7, NULL, HFILL }},
{ &hf_dnp3_al_boq_b0,
- { "Online", "dnp3.al.boq.b0", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_BO_FLAG0, "", HFILL }},
+ { "Online", "dnp3.al.boq.b0", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_BO_FLAG0, NULL, HFILL }},
{ &hf_dnp3_al_boq_b1,
- { "Restart", "dnp3.al.boq.b1", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_BO_FLAG1, "", HFILL }},
+ { "Restart", "dnp3.al.boq.b1", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_BO_FLAG1, NULL, HFILL }},
{ &hf_dnp3_al_boq_b2,
- { "Comm Fail", "dnp3.al.boq.b2", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_BO_FLAG2, "", HFILL }},
+ { "Comm Fail", "dnp3.al.boq.b2", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_BO_FLAG2, NULL, HFILL }},
{ &hf_dnp3_al_boq_b3,
- { "Remote Force", "dnp3.al.boq.b3", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_BO_FLAG3, "", HFILL }},
+ { "Remote Force", "dnp3.al.boq.b3", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_BO_FLAG3, NULL, HFILL }},
{ &hf_dnp3_al_boq_b4,
- { "Local Force", "dnp3.al.boq.b4", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_BO_FLAG4, "", HFILL }},
+ { "Local Force", "dnp3.al.boq.b4", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_BO_FLAG4, NULL, HFILL }},
{ &hf_dnp3_al_boq_b5,
- { "Reserved", "dnp3.al.boq.b5", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_BO_FLAG5, "", HFILL }},
+ { "Reserved", "dnp3.al.boq.b5", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_BO_FLAG5, NULL, HFILL }},
{ &hf_dnp3_al_boq_b6,
- { "Reserved", "dnp3.al.boq.b6", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_BO_FLAG6, "", HFILL }},
+ { "Reserved", "dnp3.al.boq.b6", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_BO_FLAG6, NULL, HFILL }},
{ &hf_dnp3_al_boq_b7,
- { "Point Value", "dnp3.al.boq.b7", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_BO_FLAG7, "", HFILL }},
+ { "Point Value", "dnp3.al.boq.b7", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_BO_FLAG7, NULL, HFILL }},
{ &hf_dnp3_al_ctrq_b0,
- { "Online", "dnp3.al.ctrq.b0", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_CTR_FLAG0, "", HFILL }},
+ { "Online", "dnp3.al.ctrq.b0", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_CTR_FLAG0, NULL, HFILL }},
{ &hf_dnp3_al_ctrq_b1,
- { "Restart", "dnp3.al.ctrq.b1", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_CTR_FLAG1, "", HFILL }},
+ { "Restart", "dnp3.al.ctrq.b1", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_CTR_FLAG1, NULL, HFILL }},
{ &hf_dnp3_al_ctrq_b2,
- { "Comm Fail", "dnp3.al.ctrq.b2", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_CTR_FLAG2, "", HFILL }},
+ { "Comm Fail", "dnp3.al.ctrq.b2", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_CTR_FLAG2, NULL, HFILL }},
{ &hf_dnp3_al_ctrq_b3,
- { "Remote Force", "dnp3.al.ctrq.b3", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_CTR_FLAG3, "", HFILL }},
+ { "Remote Force", "dnp3.al.ctrq.b3", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_CTR_FLAG3, NULL, HFILL }},
{ &hf_dnp3_al_ctrq_b4,
- { "Local Force", "dnp3.al.ctrq.b4", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_CTR_FLAG4, "", HFILL }},
+ { "Local Force", "dnp3.al.ctrq.b4", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_CTR_FLAG4, NULL, HFILL }},
{ &hf_dnp3_al_ctrq_b5,
- { "Roll-Over", "dnp3.al.ctrq.b5", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_CTR_FLAG5, "", HFILL }},
+ { "Roll-Over", "dnp3.al.ctrq.b5", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_CTR_FLAG5, NULL, HFILL }},
{ &hf_dnp3_al_ctrq_b6,
- { "Discontinuity", "dnp3.al.ctrq.b6", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_CTR_FLAG6, "", HFILL }},
+ { "Discontinuity", "dnp3.al.ctrq.b6", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_CTR_FLAG6, NULL, HFILL }},
{ &hf_dnp3_al_ctrq_b7,
- { "Reserved", "dnp3.al.ctrq.b7", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_CTR_FLAG7, "", HFILL }},
+ { "Reserved", "dnp3.al.ctrq.b7", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_CTR_FLAG7, NULL, HFILL }},
{ &hf_dnp3_al_aiq_b0,
- { "Online", "dnp3.al.aiq.b0", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_AI_FLAG0, "", HFILL }},
+ { "Online", "dnp3.al.aiq.b0", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_AI_FLAG0, NULL, HFILL }},
{ &hf_dnp3_al_aiq_b1,
- { "Restart", "dnp3.al.aiq.b1", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_AI_FLAG1, "", HFILL }},
+ { "Restart", "dnp3.al.aiq.b1", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_AI_FLAG1, NULL, HFILL }},
{ &hf_dnp3_al_aiq_b2,
- { "Comm Fail", "dnp3.al.aiq.b2", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_AI_FLAG2, "", HFILL }},
+ { "Comm Fail", "dnp3.al.aiq.b2", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_AI_FLAG2, NULL, HFILL }},
{ &hf_dnp3_al_aiq_b3,
- { "Remote Force", "dnp3.al.aiq.b3", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_AI_FLAG3, "", HFILL }},
+ { "Remote Force", "dnp3.al.aiq.b3", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_AI_FLAG3, NULL, HFILL }},
{ &hf_dnp3_al_aiq_b4,
- { "Local Force", "dnp3.al.aiq.b4", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_AI_FLAG4, "", HFILL }},
+ { "Local Force", "dnp3.al.aiq.b4", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_AI_FLAG4, NULL, HFILL }},
{ &hf_dnp3_al_aiq_b5,
- { "Over-Range", "dnp3.al.aiq.b5", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_AI_FLAG5, "", HFILL }},
+ { "Over-Range", "dnp3.al.aiq.b5", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_AI_FLAG5, NULL, HFILL }},
{ &hf_dnp3_al_aiq_b6,
- { "Reference Check", "dnp3.al.aiq.b6", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_AI_FLAG6, "", HFILL }},
+ { "Reference Check", "dnp3.al.aiq.b6", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_AI_FLAG6, NULL, HFILL }},
{ &hf_dnp3_al_aiq_b7,
- { "Reserved", "dnp3.al.aiq.b7", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_AI_FLAG7, "", HFILL }},
+ { "Reserved", "dnp3.al.aiq.b7", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_AI_FLAG7, NULL, HFILL }},
{ &hf_dnp3_al_aoq_b0,
- { "Online", "dnp3.al.aoq.b0", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_AO_FLAG0, "", HFILL }},
+ { "Online", "dnp3.al.aoq.b0", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_AO_FLAG0, NULL, HFILL }},
{ &hf_dnp3_al_aoq_b1,
- { "Restart", "dnp3.al.aoq.b1", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_AO_FLAG1, "", HFILL }},
+ { "Restart", "dnp3.al.aoq.b1", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_AO_FLAG1, NULL, HFILL }},
{ &hf_dnp3_al_aoq_b2,
- { "Comm Fail", "dnp3.al.aoq.b2", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_AO_FLAG2, "", HFILL }},
+ { "Comm Fail", "dnp3.al.aoq.b2", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_AO_FLAG2, NULL, HFILL }},
{ &hf_dnp3_al_aoq_b3,
- { "Remote Force", "dnp3.al.aoq.b3", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_AO_FLAG3, "", HFILL }},
+ { "Remote Force", "dnp3.al.aoq.b3", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_AO_FLAG3, NULL, HFILL }},
{ &hf_dnp3_al_aoq_b4,
- { "Local Force", "dnp3.al.aoq.b4", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_AO_FLAG4, "", HFILL }},
+ { "Local Force", "dnp3.al.aoq.b4", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_AO_FLAG4, NULL, HFILL }},
{ &hf_dnp3_al_aoq_b5,
- { "Reserved", "dnp3.al.aoq.b5", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_AO_FLAG5, "", HFILL }},
+ { "Reserved", "dnp3.al.aoq.b5", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_AO_FLAG5, NULL, HFILL }},
{ &hf_dnp3_al_aoq_b6,
- { "Reserved", "dnp3.al.aoq.b6", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_AO_FLAG6, "", HFILL }},
+ { "Reserved", "dnp3.al.aoq.b6", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_AO_FLAG6, NULL, HFILL }},
{ &hf_dnp3_al_aoq_b7,
- { "Reserved", "dnp3.al.aoq.b7", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_AO_FLAG7, "", HFILL }},
+ { "Reserved", "dnp3.al.aoq.b7", FT_BOOLEAN, 8, TFS(&tfs_set_notset), AL_OBJ_AO_FLAG7, NULL, HFILL }},
{ &hf_dnp3_al_timestamp,
- { "Timestamp", "dnp3.al.timestamp", FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0, "Object Timestamp", HFILL }},
+ { "Timestamp", "dnp3.al.timestamp", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0, "Object Timestamp", HFILL }},
{ &hf_dnp3_al_rel_timestamp,
{ "Relative Timestamp", "dnp3.al.reltimestamp", FT_RELATIVE_TIME, BASE_NONE, NULL, 0, "Object Relative Timestamp", HFILL }},
{ &hf_dnp3_fragment_reassembled_in,
{ "Reassembled PDU In Frame", "dnp3.al.fragment.reassembled_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
- "This PDU is reassembled in this frame", HFILL }}
+ "This PDU is reassembled in this frame", HFILL }},
+
+ { &hf_dnp3_fragment_reassembled_length,
+ { "Reassembled DNP length", "dnp3.al.fragment.reassembled.length", FT_UINT32, BASE_DEC, NULL, 0x0,
+ "The total length of the reassembled payload", HFILL }}
};
/* Setup protocol subtree array */
module_t *dnp3_module;
/* Register protocol init routine */
- register_init_routine(&dnp3_init);
+ register_init_routine(&al_defragment_init);
/* Register the protocol name and description */
proto_dnp3 = proto_register_protocol("Distributed Network Protocol 3.0",
"Whether the DNP3 dissector should reassemble messages spanning multiple TCP segments."
" To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
&dnp3_desegment);
-
- al_defragment_init();
}
-/* If this dissector uses sub-dissector registration add a registration routine.
- This format is required because a script is used to find these routines and
- create the code that calls these routines.
-*/
void
proto_reg_handoff_dnp3(void)
{
* Local Variables:
* c-basic-offset: 2
* tab-width: 8
- * indent-tabs-mode: t
+ * indent-tabs-mode: nil
* End:
*
- * ex: set shiftwidth=2 tabstop=8 noexpandtab
- * :indentSize=2:tabSize=8:noTabs=false:
+ * ex: set shiftwidth=2 tabstop=8 expandtab
+ * :indentSize=2:tabSize=8:noTabs=true:
*/