/* packet-lwm2mtlv.c
* Routines for LWM2M TLV dissection
* References:
- * OMA LWM2M Specification: OMA-TS-LightweightM2M-V1_0-20151214-C.pdf
+ * OMA LWM2M Specification: OMA-TS-LightweightM2M_Core-V1_1-20180710-A.pdf
* available from
- * http://technical.openmobilealliance.org/Technical/technical-information/release-program/current-releases/oma-lightweightm2m-v1-0
+ * http://openmobilealliance.org/release/LightweightM2M/V1_1-20180710-A/
*
* Copyright 2016, Christoph Burger-Scheidlin
+ * Copyright 2018, Stig Bjorlykke <stig@bjorlykke.org>
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
static int proto_lwm2mtlv = -1;
static int hf_lwm2mtlv_object_name = -1;
+static int hf_lwm2mtlv_resource_name = -1;
static int hf_lwm2mtlv_header = -1;
static int hf_lwm2mtlv_type_type = -1;
static int hf_lwm2mtlv_type_length_of_identifier = -1;
static int hf_lwm2mtlv_value = -1;
static int hf_lwm2mtlv_value_string = -1;
static int hf_lwm2mtlv_value_integer = -1;
+static int hf_lwm2mtlv_value_unsigned_integer = -1;
static int hf_lwm2mtlv_value_float = -1;
static int hf_lwm2mtlv_value_double = -1;
static int hf_lwm2mtlv_value_boolean = -1;
char *name;
guint data_type;
gint *hf_id;
+ gint *ett_id;
char *field_name;
} lwm2m_resource_t;
-#define DATA_TYPE_NONE 0
-#define DATA_TYPE_STRING 1
-#define DATA_TYPE_INTEGER 2
-#define DATA_TYPE_FLOAT 3
-#define DATA_TYPE_BOOLEAN 4
-#define DATA_TYPE_OPAQUE 5
-#define DATA_TYPE_TIME 6
-#define DATA_TYPE_OBJLNK 7
+/* RESOURCE_FILL initializes all the dynamic fields in a lwm2m_resource_t. */
+#define RESOURCE_FILL NULL, NULL, NULL
+
+#define DATA_TYPE_NONE 0
+#define DATA_TYPE_STRING 1
+#define DATA_TYPE_INTEGER 2
+#define DATA_TYPE_UNSIGNED_INTEGER 3
+#define DATA_TYPE_FLOAT 4
+#define DATA_TYPE_BOOLEAN 5
+#define DATA_TYPE_OPAQUE 6
+#define DATA_TYPE_TIME 7
+#define DATA_TYPE_OBJLNK 8
+#define DATA_TYPE_CORELNK 9
static const value_string data_types[] = {
- { DATA_TYPE_NONE, "None" },
- { DATA_TYPE_STRING, "String" },
- { DATA_TYPE_INTEGER, "Integer" },
- { DATA_TYPE_FLOAT, "Float" },
- { DATA_TYPE_BOOLEAN, "Boolean" },
- { DATA_TYPE_OPAQUE, "Opaque" },
- { DATA_TYPE_TIME, "Time" },
- { DATA_TYPE_OBJLNK, "Objlnk" },
+ { DATA_TYPE_NONE, "None" },
+ { DATA_TYPE_STRING, "String" },
+ { DATA_TYPE_INTEGER, "Integer" },
+ { DATA_TYPE_UNSIGNED_INTEGER, "Unsigned Integer" },
+ { DATA_TYPE_FLOAT, "Float" },
+ { DATA_TYPE_BOOLEAN, "Boolean" },
+ { DATA_TYPE_OPAQUE, "Opaque" },
+ { DATA_TYPE_TIME, "Time" },
+ { DATA_TYPE_OBJLNK, "Objlnk" },
+ { DATA_TYPE_CORELNK, "Corelnk" },
{ 0, NULL }
};
/* LwM2M Objects defined by OMA (Normative) */
static const value_string lwm2m_oma_objects[] = {
- { 0, "LwM2M Security" },
- { 1, "LwM2M Server" },
- { 2, "Access Control" },
- { 3, "Device" },
- { 4, "Connectivity Monitoring" },
- { 5, "Firmware Update" },
- { 6, "Location" },
- { 7, "Connectivity Statistics" },
+ { 0, "LwM2M Security" },
+ { 1, "LwM2M Server" },
+ { 2, "Access Control" },
+ { 3, "Device" },
+ { 4, "Connectivity Monitoring" },
+ { 5, "Firmware Update" },
+ { 6, "Location" },
+ { 7, "Connectivity Statistics" },
+ { 21, "OSCORE" },
{ 0, NULL }
};
static lwm2m_resource_t lwm2m_oma_resources[] =
{
/* LwM2M Security (0) */
- { 0, 0, "LwM2M Server URI", DATA_TYPE_STRING, NULL, NULL },
- { 0, 1, "Bootstrap-Server", DATA_TYPE_BOOLEAN, NULL, NULL },
- { 0, 2, "Security Mode", DATA_TYPE_INTEGER, NULL, NULL },
- { 0, 3, "Public Key or Identity", DATA_TYPE_OPAQUE, NULL, NULL },
- { 0, 4, "Server Public Key", DATA_TYPE_OPAQUE, NULL, NULL },
- { 0, 5, "Secret Key", DATA_TYPE_OPAQUE, NULL, NULL },
- { 0, 6, "SMS Security Mode", DATA_TYPE_INTEGER, NULL, NULL },
- { 0, 7, "SMS Binding Key Parameters", DATA_TYPE_OPAQUE, NULL, NULL },
- { 0, 8, "SMS Binding Secret Keys", DATA_TYPE_OPAQUE, NULL, NULL },
- { 0, 9, "LwM2M Server SMS Number", DATA_TYPE_STRING, NULL, NULL },
- { 0, 10, "Short Server ID", DATA_TYPE_INTEGER, NULL, NULL },
- { 0, 11, "Client Hold Off Time", DATA_TYPE_INTEGER, NULL, NULL },
- { 0, 12, "Bootstrap-Server Account Timeout", DATA_TYPE_INTEGER, NULL, NULL },
+ { 0, 0, "LwM2M Server URI", DATA_TYPE_STRING, RESOURCE_FILL },
+ { 0, 1, "Bootstrap-Server", DATA_TYPE_BOOLEAN, RESOURCE_FILL },
+ { 0, 2, "Security Mode", DATA_TYPE_INTEGER, RESOURCE_FILL },
+ { 0, 3, "Public Key or Identity", DATA_TYPE_OPAQUE, RESOURCE_FILL },
+ { 0, 4, "Server Public Key", DATA_TYPE_OPAQUE, RESOURCE_FILL },
+ { 0, 5, "Secret Key", DATA_TYPE_OPAQUE, RESOURCE_FILL },
+ { 0, 6, "SMS Security Mode", DATA_TYPE_INTEGER, RESOURCE_FILL },
+ { 0, 7, "SMS Binding Key Parameters", DATA_TYPE_OPAQUE, RESOURCE_FILL },
+ { 0, 8, "SMS Binding Secret Keys", DATA_TYPE_OPAQUE, RESOURCE_FILL },
+ { 0, 9, "LwM2M Server SMS Number", DATA_TYPE_STRING, RESOURCE_FILL },
+ { 0, 10, "Short Server ID", DATA_TYPE_INTEGER, RESOURCE_FILL },
+ { 0, 11, "Client Hold Off Time", DATA_TYPE_INTEGER, RESOURCE_FILL },
+ { 0, 12, "Bootstrap-Server Account Timeout", DATA_TYPE_INTEGER, RESOURCE_FILL },
+ { 0, 13, "Matching Type", DATA_TYPE_UNSIGNED_INTEGER, RESOURCE_FILL },
+ { 0, 14, "SNI", DATA_TYPE_STRING, RESOURCE_FILL },
+ { 0, 15, "Certificate Usage", DATA_TYPE_UNSIGNED_INTEGER, RESOURCE_FILL },
+ { 0, 16, "TLS DTLS Ciphersuite", DATA_TYPE_UNSIGNED_INTEGER, RESOURCE_FILL },
+ { 0, 17, "OSCORE Security Mode", DATA_TYPE_OBJLNK, RESOURCE_FILL },
/* LwM2M Server (1) */
- { 1, 0, "Short Server ID", DATA_TYPE_INTEGER, NULL, NULL },
- { 1, 1, "Lifetime", DATA_TYPE_INTEGER, NULL, NULL },
- { 1, 2, "Default Minimum Period", DATA_TYPE_INTEGER, NULL, NULL },
- { 1, 3, "Default Maximum Period", DATA_TYPE_INTEGER, NULL, NULL },
- { 1, 4, "Disable", DATA_TYPE_NONE, NULL, NULL },
- { 1, 5, "Disable Timeout", DATA_TYPE_INTEGER, NULL, NULL },
- { 1, 6, "Notification Storing When Disabled or Offline", DATA_TYPE_BOOLEAN, NULL, NULL },
- { 1, 7, "Binding", DATA_TYPE_STRING, NULL, NULL },
+ { 1, 0, "Short Server ID", DATA_TYPE_INTEGER, RESOURCE_FILL },
+ { 1, 1, "Lifetime", DATA_TYPE_INTEGER, RESOURCE_FILL },
+ { 1, 2, "Default Minimum Period", DATA_TYPE_INTEGER, RESOURCE_FILL },
+ { 1, 3, "Default Maximum Period", DATA_TYPE_INTEGER, RESOURCE_FILL },
+ { 1, 4, "Disable", DATA_TYPE_NONE, RESOURCE_FILL },
+ { 1, 5, "Disable Timeout", DATA_TYPE_INTEGER, RESOURCE_FILL },
+ { 1, 6, "Notification Storing When Disabled or Offline", DATA_TYPE_BOOLEAN, RESOURCE_FILL },
+ { 1, 7, "Binding", DATA_TYPE_STRING, RESOURCE_FILL },
+ { 1, 8, "Registration Update Trigger", DATA_TYPE_NONE, RESOURCE_FILL },
+ { 1, 9, "Bootstrap Request Trigger", DATA_TYPE_NONE, RESOURCE_FILL },
+ { 1, 10, "APN Link", DATA_TYPE_OBJLNK, RESOURCE_FILL },
+ { 1, 11, "TLS DTLS Alert Code", DATA_TYPE_UNSIGNED_INTEGER, RESOURCE_FILL },
+ { 1, 12, "Last Bootstrapped", DATA_TYPE_TIME, RESOURCE_FILL },
+ { 1, 13, "Registration Priority Order", DATA_TYPE_UNSIGNED_INTEGER, RESOURCE_FILL },
+ { 1, 14, "Initial Registration Delay Timer", DATA_TYPE_UNSIGNED_INTEGER, RESOURCE_FILL },
+ { 1, 15, "Registration Failure Block", DATA_TYPE_BOOLEAN, RESOURCE_FILL },
+ { 1, 16, "Bootstrap on Registration Failure", DATA_TYPE_BOOLEAN, RESOURCE_FILL },
+ { 1, 17, "Communication Retry Count", DATA_TYPE_UNSIGNED_INTEGER, RESOURCE_FILL },
+ { 1, 18, "Communication Retry Timer", DATA_TYPE_UNSIGNED_INTEGER, RESOURCE_FILL },
+ { 1, 19, "Communication Sequence Delay Timer", DATA_TYPE_UNSIGNED_INTEGER, RESOURCE_FILL },
+ { 1, 20, "Communication Sequence Retry Count", DATA_TYPE_UNSIGNED_INTEGER, RESOURCE_FILL },
+ { 1, 21, "Trigger", DATA_TYPE_BOOLEAN, RESOURCE_FILL },
+ { 1, 22, "Preferred Transport", DATA_TYPE_STRING, RESOURCE_FILL },
+ { 1, 23, "Mute Send", DATA_TYPE_BOOLEAN, RESOURCE_FILL },
/* Access Control (2) */
- { 2, 0, "Object ID", DATA_TYPE_INTEGER, NULL, NULL },
- { 2, 1, "Object Instance ID", DATA_TYPE_INTEGER, NULL, NULL },
- { 2, 2, "ACL", DATA_TYPE_INTEGER, NULL, NULL },
- { 2, 3, "Access Control Owner", DATA_TYPE_INTEGER, NULL, NULL },
+ { 2, 0, "Object ID", DATA_TYPE_INTEGER, RESOURCE_FILL },
+ { 2, 1, "Object Instance ID", DATA_TYPE_INTEGER, RESOURCE_FILL },
+ { 2, 2, "ACL", DATA_TYPE_INTEGER, RESOURCE_FILL },
+ { 2, 3, "Access Control Owner", DATA_TYPE_INTEGER, RESOURCE_FILL },
/* Device (3) */
- { 3, 0, "Manufacturer", DATA_TYPE_STRING, NULL, NULL },
- { 3, 1, "Model Number", DATA_TYPE_STRING, NULL, NULL },
- { 3, 2, "Serial Number", DATA_TYPE_STRING, NULL, NULL },
- { 3, 3, "Firmware Version", DATA_TYPE_STRING, NULL, NULL },
- { 3, 4, "Reboot", DATA_TYPE_NONE, NULL, NULL },
- { 3, 5, "Factory Reset", DATA_TYPE_NONE, NULL, NULL },
- { 3, 6, "Available Power Sources", DATA_TYPE_INTEGER, NULL, NULL },
- { 3, 7, "Power Source Voltage", DATA_TYPE_INTEGER, NULL, NULL },
- { 3, 8, "Power Source Current", DATA_TYPE_INTEGER, NULL, NULL },
- { 3, 9, "Battery Level", DATA_TYPE_INTEGER, NULL, NULL },
- { 3, 10, "Memory Free", DATA_TYPE_INTEGER, NULL, NULL },
- { 3, 11, "Error Code", DATA_TYPE_INTEGER, NULL, NULL },
- { 3, 12, "Reset Error Code", DATA_TYPE_NONE, NULL, NULL },
- { 3, 13, "Current Time", DATA_TYPE_TIME, NULL, NULL },
- { 3, 14, "UTC Offset", DATA_TYPE_STRING, NULL, NULL },
- { 3, 15, "Timezone", DATA_TYPE_STRING, NULL, NULL },
- { 3, 16, "Supported Binding and Modes", DATA_TYPE_STRING, NULL, NULL },
- { 3, 17, "Device Type", DATA_TYPE_STRING, NULL, NULL },
- { 3, 18, "Hardware Version", DATA_TYPE_STRING, NULL, NULL },
- { 3, 19, "Software Version", DATA_TYPE_STRING, NULL, NULL },
- { 3, 20, "Battery Status", DATA_TYPE_INTEGER, NULL, NULL },
- { 3, 21, "Memory Total", DATA_TYPE_INTEGER, NULL, NULL },
- { 3, 22, "ExtDevInfo", DATA_TYPE_OBJLNK, NULL, NULL },
+ { 3, 0, "Manufacturer", DATA_TYPE_STRING, RESOURCE_FILL },
+ { 3, 1, "Model Number", DATA_TYPE_STRING, RESOURCE_FILL },
+ { 3, 2, "Serial Number", DATA_TYPE_STRING, RESOURCE_FILL },
+ { 3, 3, "Firmware Version", DATA_TYPE_STRING, RESOURCE_FILL },
+ { 3, 4, "Reboot", DATA_TYPE_NONE, RESOURCE_FILL },
+ { 3, 5, "Factory Reset", DATA_TYPE_NONE, RESOURCE_FILL },
+ { 3, 6, "Available Power Sources", DATA_TYPE_INTEGER, RESOURCE_FILL },
+ { 3, 7, "Power Source Voltage", DATA_TYPE_INTEGER, RESOURCE_FILL },
+ { 3, 8, "Power Source Current", DATA_TYPE_INTEGER, RESOURCE_FILL },
+ { 3, 9, "Battery Level", DATA_TYPE_INTEGER, RESOURCE_FILL },
+ { 3, 10, "Memory Free", DATA_TYPE_INTEGER, RESOURCE_FILL },
+ { 3, 11, "Error Code", DATA_TYPE_INTEGER, RESOURCE_FILL },
+ { 3, 12, "Reset Error Code", DATA_TYPE_NONE, RESOURCE_FILL },
+ { 3, 13, "Current Time", DATA_TYPE_TIME, RESOURCE_FILL },
+ { 3, 14, "UTC Offset", DATA_TYPE_STRING, RESOURCE_FILL },
+ { 3, 15, "Timezone", DATA_TYPE_STRING, RESOURCE_FILL },
+ { 3, 16, "Supported Binding and Modes", DATA_TYPE_STRING, RESOURCE_FILL },
+ { 3, 17, "Device Type", DATA_TYPE_STRING, RESOURCE_FILL },
+ { 3, 18, "Hardware Version", DATA_TYPE_STRING, RESOURCE_FILL },
+ { 3, 19, "Software Version", DATA_TYPE_STRING, RESOURCE_FILL },
+ { 3, 20, "Battery Status", DATA_TYPE_INTEGER, RESOURCE_FILL },
+ { 3, 21, "Memory Total", DATA_TYPE_INTEGER, RESOURCE_FILL },
+ { 3, 22, "ExtDevInfo", DATA_TYPE_OBJLNK, RESOURCE_FILL },
/* Connectivity Monitoring (4) */
- { 4, 0, "Network Bearer", DATA_TYPE_INTEGER, NULL, NULL },
- { 4, 1, "Available Network Bearer", DATA_TYPE_INTEGER, NULL, NULL },
- { 4, 2, "Radio Signal Strength", DATA_TYPE_INTEGER, NULL, NULL },
- { 4, 3, "Link Quality", DATA_TYPE_INTEGER, NULL, NULL },
- { 4, 4, "IP Addresses", DATA_TYPE_STRING, NULL, NULL },
- { 4, 5, "Router IP Addresses", DATA_TYPE_STRING, NULL, NULL },
- { 4, 6, "Link Utilization", DATA_TYPE_INTEGER, NULL, NULL },
- { 4, 7, "APN", DATA_TYPE_STRING, NULL, NULL },
- { 4, 8, "Cell ID", DATA_TYPE_INTEGER, NULL, NULL },
- { 4, 9, "SMNC", DATA_TYPE_INTEGER, NULL, NULL },
- { 4, 10, "SMCC", DATA_TYPE_INTEGER, NULL, NULL },
+ { 4, 0, "Network Bearer", DATA_TYPE_INTEGER, RESOURCE_FILL },
+ { 4, 1, "Available Network Bearer", DATA_TYPE_INTEGER, RESOURCE_FILL },
+ { 4, 2, "Radio Signal Strength", DATA_TYPE_INTEGER, RESOURCE_FILL },
+ { 4, 3, "Link Quality", DATA_TYPE_INTEGER, RESOURCE_FILL },
+ { 4, 4, "IP Addresses", DATA_TYPE_STRING, RESOURCE_FILL },
+ { 4, 5, "Router IP Addresses", DATA_TYPE_STRING, RESOURCE_FILL },
+ { 4, 6, "Link Utilization", DATA_TYPE_INTEGER, RESOURCE_FILL },
+ { 4, 7, "APN", DATA_TYPE_STRING, RESOURCE_FILL },
+ { 4, 8, "Cell ID", DATA_TYPE_INTEGER, RESOURCE_FILL },
+ { 4, 9, "SMNC", DATA_TYPE_INTEGER, RESOURCE_FILL },
+ { 4, 10, "SMCC", DATA_TYPE_INTEGER, RESOURCE_FILL },
+ { 4, 11, "SignalSNR", DATA_TYPE_INTEGER, RESOURCE_FILL },
/* Firmware Update (5) */
- { 5, 0, "Package", DATA_TYPE_OPAQUE, NULL, NULL },
- { 5, 1, "Package URI", DATA_TYPE_STRING, NULL, NULL },
- { 5, 2, "Update", DATA_TYPE_NONE, NULL, NULL },
- { 5, 3, "State", DATA_TYPE_INTEGER, NULL, NULL },
- /* { 5, 4, "", DATA_TYPE_NONE, NULL, NULL }, */
- { 5, 5, "Update Result", DATA_TYPE_INTEGER, NULL, NULL },
- { 5, 6, "PkgName", DATA_TYPE_STRING, NULL, NULL },
- { 5, 7, "PkgVersion", DATA_TYPE_STRING, NULL, NULL },
- { 5, 8, "Firmware Update Protocol Support", DATA_TYPE_INTEGER, NULL, NULL },
- { 5, 9, "Firmware Update Delivery Method", DATA_TYPE_INTEGER, NULL, NULL },
+ { 5, 0, "Package", DATA_TYPE_OPAQUE, RESOURCE_FILL },
+ { 5, 1, "Package URI", DATA_TYPE_STRING, RESOURCE_FILL },
+ { 5, 2, "Update", DATA_TYPE_NONE, RESOURCE_FILL },
+ { 5, 3, "State", DATA_TYPE_INTEGER, RESOURCE_FILL },
+ /* { 5, 4, "", DATA_TYPE_NONE, RESOURCE_FILL }, */
+ { 5, 5, "Update Result", DATA_TYPE_INTEGER, RESOURCE_FILL },
+ { 5, 6, "PkgName", DATA_TYPE_STRING, RESOURCE_FILL },
+ { 5, 7, "PkgVersion", DATA_TYPE_STRING, RESOURCE_FILL },
+ { 5, 8, "Firmware Update Protocol Support", DATA_TYPE_INTEGER, RESOURCE_FILL },
+ { 5, 9, "Firmware Update Delivery Method", DATA_TYPE_INTEGER, RESOURCE_FILL },
/* Location (6) */
- { 6, 0, "Latitude", DATA_TYPE_FLOAT, NULL, NULL },
- { 6, 1, "Longitude", DATA_TYPE_FLOAT, NULL, NULL },
- { 6, 2, "Altitude", DATA_TYPE_FLOAT, NULL, NULL },
- { 6, 3, "Radius", DATA_TYPE_FLOAT, NULL, NULL },
- { 6, 4, "Velocity", DATA_TYPE_OPAQUE, NULL, NULL },
- { 6, 5, "Timestamp", DATA_TYPE_TIME, NULL, NULL },
- { 6, 6, "Speed", DATA_TYPE_FLOAT, NULL, NULL },
+ { 6, 0, "Latitude", DATA_TYPE_FLOAT, RESOURCE_FILL },
+ { 6, 1, "Longitude", DATA_TYPE_FLOAT, RESOURCE_FILL },
+ { 6, 2, "Altitude", DATA_TYPE_FLOAT, RESOURCE_FILL },
+ { 6, 3, "Radius", DATA_TYPE_FLOAT, RESOURCE_FILL },
+ { 6, 4, "Velocity", DATA_TYPE_OPAQUE, RESOURCE_FILL },
+ { 6, 5, "Timestamp", DATA_TYPE_TIME, RESOURCE_FILL },
+ { 6, 6, "Speed", DATA_TYPE_FLOAT, RESOURCE_FILL },
/* Connectivity Statistics (7) */
- { 7, 0, "SMS Tx Counter", DATA_TYPE_INTEGER, NULL, NULL },
- { 7, 1, "SMS Rx Counter", DATA_TYPE_INTEGER, NULL, NULL },
- { 7, 2, "Tx Data", DATA_TYPE_INTEGER, NULL, NULL },
- { 7, 3, "Rx Data", DATA_TYPE_INTEGER, NULL, NULL },
- { 7, 4, "Max Message Size", DATA_TYPE_INTEGER, NULL, NULL },
- { 7, 5, "Average Message Size", DATA_TYPE_INTEGER, NULL, NULL },
- { 7, 6, "Start", DATA_TYPE_NONE, NULL, NULL },
- { 7, 7, "Stop", DATA_TYPE_NONE, NULL, NULL },
- { 7, 8, "Collection Period", DATA_TYPE_INTEGER, NULL, NULL },
+ { 7, 0, "SMS Tx Counter", DATA_TYPE_INTEGER, RESOURCE_FILL },
+ { 7, 1, "SMS Rx Counter", DATA_TYPE_INTEGER, RESOURCE_FILL },
+ { 7, 2, "Tx Data", DATA_TYPE_INTEGER, RESOURCE_FILL },
+ { 7, 3, "Rx Data", DATA_TYPE_INTEGER, RESOURCE_FILL },
+ { 7, 4, "Max Message Size", DATA_TYPE_INTEGER, RESOURCE_FILL },
+ { 7, 5, "Average Message Size", DATA_TYPE_INTEGER, RESOURCE_FILL },
+ { 7, 6, "Start", DATA_TYPE_NONE, RESOURCE_FILL },
+ { 7, 7, "Stop", DATA_TYPE_NONE, RESOURCE_FILL },
+ { 7, 8, "Collection Period", DATA_TYPE_INTEGER, RESOURCE_FILL },
+
+ /* OSCORE (21) */
+ { 21, 0, "Master Secret", DATA_TYPE_STRING, RESOURCE_FILL },
+ { 21, 1, "Sender ID", DATA_TYPE_STRING, RESOURCE_FILL },
+ { 21, 2, "Recipient ID", DATA_TYPE_STRING, RESOURCE_FILL },
+ { 21, 3, "AEAD Algorithm", DATA_TYPE_INTEGER, RESOURCE_FILL },
+ { 21, 4, "HMAC Algorithm", DATA_TYPE_INTEGER, RESOURCE_FILL },
+ { 21, 5, "Master Salt", DATA_TYPE_STRING, RESOURCE_FILL },
};
+static hf_register_info *static_hf;
+static GArray *static_ett;
+
/* LwM2M Objects defined by User */
static lwm2m_object_name_t *lwm2m_uat_object_names;
static guint num_lwm2m_uat_object_names;
static hf_register_info *dynamic_hf;
static guint dynamic_hf_size;
-static hf_register_info *static_hf;
+static GArray *dynamic_ett;
static gboolean lwm2m_object_name_update_cb(void *record, char **error)
{
static void lwm2m_add_resource(lwm2m_resource_t *resource, hf_register_info *hf)
{
gchar *resource_abbrev;
- gint *hf_id;
+ gint *hf_id, *ett_id;
hf_id = g_new(gint,1);
*hf_id = -1;
+ ett_id = g_new(gint, 1);
+ *ett_id = -1;
+
if (resource->field_name) {
resource_abbrev = g_strdup(resource->field_name);
} else {
}
resource->hf_id = hf_id;
+ resource->ett_id = ett_id;
hf->p_id = hf_id;
hf->hfinfo.name = g_strdup(resource->name);
switch (resource->data_type) {
case DATA_TYPE_STRING:
+ case DATA_TYPE_CORELNK:
hf->hfinfo.display = BASE_NONE;
hf->hfinfo.type = FT_STRING;
break;
hf->hfinfo.display = BASE_DEC;
hf->hfinfo.type = FT_INT64;
break;
+ case DATA_TYPE_UNSIGNED_INTEGER:
+ hf->hfinfo.display = BASE_DEC;
+ hf->hfinfo.type = FT_UINT64;
+ break;
case DATA_TYPE_FLOAT:
hf->hfinfo.display = BASE_NONE;
hf->hfinfo.type = FT_FLOAT;
dynamic_hf = NULL;
dynamic_hf_size = 0;
}
+
+ if (dynamic_ett) {
+ proto_add_deregistered_data(g_array_free(dynamic_ett, TRUE));
+ dynamic_ett = NULL;
+ }
}
static void lwm2m_resource_post_update_cb(void)
if (num_lwm2m_uat_resources) {
dynamic_hf = g_new0(hf_register_info, num_lwm2m_uat_resources);
+ dynamic_ett = g_array_new(TRUE, TRUE, sizeof(gint*));
for (guint i = 0; i < num_lwm2m_uat_resources; i++) {
lwm2m_add_resource(&lwm2m_uat_resources[i], &dynamic_hf[dynamic_hf_size++]);
+ g_array_append_val(dynamic_ett, lwm2m_uat_resources[i].ett_id);
}
proto_register_field_array(proto_lwm2mtlv, dynamic_hf, dynamic_hf_size);
+ proto_register_subtree_array((gint**)(void*)dynamic_ett->data, dynamic_ett->len);
}
}
addElementTree(tvbuff_t *tvb, proto_tree *tlv_tree, lwm2mElement_t *element, const lwm2m_resource_t *resource)
{
gchar *identifier = NULL;
+ gint ett_id;
if (resource) {
identifier = wmem_strdup_printf(wmem_packet_scope(), "[%02u] %s", element->identifier, resource->name);
"%02u", element->identifier);
case RESOURCE_ARRAY:
- return proto_tree_add_subtree_format(tlv_tree, tvb, 0, element->totalLength, ett_lwm2mtlv_resourceArray, NULL,
+ ett_id = resource ? *resource->ett_id : ett_lwm2mtlv_resourceArray;
+ return proto_tree_add_subtree_format(tlv_tree, tvb, 0, element->totalLength, ett_id, NULL,
"%s", identifier);
case RESOURCE:
- return proto_tree_add_subtree_format(tlv_tree, tvb, 0, element->totalLength, ett_lwm2mtlv_resource, NULL,
+ ett_id = resource ? *resource->ett_id : ett_lwm2mtlv_resource;
+ return proto_tree_add_subtree_format(tlv_tree, tvb, 0, element->totalLength, ett_id, NULL,
"%s", identifier);
}
return NULL;
if (resource && resource->data_type != DATA_TYPE_NONE) {
switch (resource->data_type) {
case DATA_TYPE_STRING:
+ case DATA_TYPE_CORELNK:
{
const guint8 *strval;
proto_tree_add_item_ret_string(tlv_tree, *resource->hf_id, tvb, valueOffset, element->length_of_value, ENC_UTF_8, wmem_packet_scope(), &strval);
proto_tree_add_item(tlv_tree, *resource->hf_id, tvb, valueOffset, element->length_of_value, ENC_BIG_ENDIAN);
proto_item_append_text(tlv_tree, ": %" G_GINT64_FORMAT, decodeVariableInt(tvb, valueOffset, element->length_of_value));
break;
+ case DATA_TYPE_UNSIGNED_INTEGER:
+ {
+ guint64 value;
+ proto_tree_add_item_ret_uint64(tlv_tree, *resource->hf_id, tvb, valueOffset, element->length_of_value, ENC_BIG_ENDIAN, &value);
+ proto_item_append_text(tlv_tree, ": %" G_GUINT64_FORMAT, value);
+ break;
+ }
case DATA_TYPE_FLOAT:
proto_tree_add_item(tlv_tree, *resource->hf_id, tvb, valueOffset, element->length_of_value, ENC_BIG_ENDIAN);
proto_item_append_text(tlv_tree, ": %." G_STRINGIFY(FLT_DIG) "g", tvb_get_ieee_float(tvb, valueOffset, ENC_BIG_ENDIAN));
proto_item_append_text(tlv_tree, ": %s", abs_time_to_str(wmem_packet_scope(), &ts, ABSOLUTE_TIME_LOCAL, FALSE));
break;
}
- case DATA_TYPE_OPAQUE:
case DATA_TYPE_OBJLNK:
+ {
+ guint16 lnk1 = tvb_get_guint16(tvb, valueOffset, ENC_BIG_ENDIAN);
+ guint16 lnk2 = tvb_get_guint16(tvb, valueOffset + 2, ENC_BIG_ENDIAN);
+ proto_tree_add_bytes_format(tlv_tree, *resource->hf_id, tvb, valueOffset, element->length_of_value, NULL, "%u:%u", lnk1, lnk2);
+ proto_item_append_text(tlv_tree, ": %u:%u", lnk1, lnk2);
+ break;
+ }
+ case DATA_TYPE_OPAQUE:
default:
proto_tree_add_item(tlv_tree, *resource->hf_id, tvb, valueOffset, element->length_of_value, ENC_BIG_ENDIAN);
proto_item_append_text(tlv_tree, ": %s", tvb_bytes_to_str(wmem_packet_scope(), tvb, valueOffset, element->length_of_value));
switch(element->length_of_value) {
case 0x01:
proto_tree_add_item(tlv_tree, hf_lwm2mtlv_value_integer, tvb, valueOffset, element->length_of_value, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tlv_tree, hf_lwm2mtlv_value_unsigned_integer, tvb, valueOffset, element->length_of_value, ENC_BIG_ENDIAN);
if (tvb_get_guint8(tvb, valueOffset) < 2) {
proto_tree_add_item(tlv_tree, hf_lwm2mtlv_value_boolean, tvb, valueOffset, element->length_of_value, ENC_BIG_ENDIAN);
}
break;
case 0x02:
proto_tree_add_item(tlv_tree, hf_lwm2mtlv_value_integer, tvb, valueOffset, element->length_of_value, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tlv_tree, hf_lwm2mtlv_value_unsigned_integer, tvb, valueOffset, element->length_of_value, ENC_BIG_ENDIAN);
break;
case 0x04:
proto_tree_add_item(tlv_tree, hf_lwm2mtlv_value_integer, tvb, valueOffset, element->length_of_value, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tlv_tree, hf_lwm2mtlv_value_unsigned_integer, tvb, valueOffset, element->length_of_value, ENC_BIG_ENDIAN);
proto_tree_add_item(tlv_tree, hf_lwm2mtlv_value_float, tvb, valueOffset, element->length_of_value, ENC_BIG_ENDIAN);
proto_tree_add_item(tlv_tree, hf_lwm2mtlv_value_timestamp, tvb, valueOffset, element->length_of_value, ENC_BIG_ENDIAN);
break;
case 0x08:
proto_tree_add_item(tlv_tree, hf_lwm2mtlv_value_integer, tvb, valueOffset, element->length_of_value, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tlv_tree, hf_lwm2mtlv_value_unsigned_integer, tvb, valueOffset, element->length_of_value, ENC_BIG_ENDIAN);
proto_tree_add_item(tlv_tree, hf_lwm2mtlv_value_double, tvb, valueOffset, element->length_of_value, ENC_BIG_ENDIAN);
/* apparently, wireshark does not deal well with 8 bytes. */
proto_tree_add_item(tlv_tree, hf_lwm2mtlv_value_timestamp, tvb, valueOffset+4, element->length_of_value-4, ENC_BIG_ENDIAN);
{
guint valueOffset = 1 + element->length_of_identifier + element->length_of_length;
+ if (resource && (element->type == RESOURCE || element->type == RESOURCE_ARRAY)) {
+ proto_item *ti = proto_tree_add_string(tlv_tree, hf_lwm2mtlv_resource_name, tvb, 0, 0, resource->name);
+ PROTO_ITEM_SET_GENERATED(ti);
+ }
+
if ( element->type == RESOURCE || element->type == RESOURCE_INSTANCE ) {
proto_tree_add_item(tlv_tree, hf_lwm2mtlv_value, tvb, valueOffset, element->length_of_value, ENC_NA);
addValueInterpretations(tvb, tlv_tree, element, resource);
proto_add_deregistered_data(static_hf);
static_hf = NULL;
+
+ proto_add_deregistered_data(g_array_free(static_ett, TRUE));
+ static_ett = NULL;
}
void proto_register_lwm2mtlv(void)
FT_STRING, BASE_NONE, NULL, 0,
NULL, HFILL }
},
+ { &hf_lwm2mtlv_resource_name,
+ { "Resource Name", "lwm2mtlv.resource_name",
+ FT_STRING, BASE_NONE, NULL, 0,
+ NULL, HFILL }
+ },
{ &hf_lwm2mtlv_header,
{ "TLV header", "lwm2mtlv.header",
FT_NONE, BASE_NONE, NULL, 0x0,
FT_INT64, BASE_DEC, NULL, 0,
NULL, HFILL }
},
+ { &hf_lwm2mtlv_value_unsigned_integer,
+ { "As Unsigned Integer", "lwm2mtlv.value.unsigned_integer",
+ FT_UINT64, BASE_DEC, NULL, 0,
+ NULL, HFILL }
+ },
{ &hf_lwm2mtlv_value_float,
{ "As Float", "lwm2mtlv.value.float",
FT_FLOAT, BASE_NONE, NULL, 0,
resource_uat);
static_hf = g_new0(hf_register_info, array_length(lwm2m_oma_resources));
+ static_ett = g_array_new(TRUE, TRUE, sizeof(gint*));
+
for (guint i = 0; i < array_length(lwm2m_oma_resources); i++) {
lwm2m_add_resource(&lwm2m_oma_resources[i], &static_hf[i]);
+ g_array_append_val(static_ett, lwm2m_oma_resources[i].ett_id);
}
+
proto_register_field_array(proto_lwm2mtlv, static_hf, array_length(lwm2m_oma_resources));
+ proto_register_subtree_array((gint**)(void*)static_ett->data, static_ett->len);
}
void