/* packet-diameter.c
* Routines for Diameter packet disassembly
*
- * $Id: packet-diameter.c,v 1.38 2002/01/07 20:05:20 guy Exp $
+ * $Id: packet-diameter.c,v 1.51 2002/12/02 23:43:26 guy Exp $
*
* Copyright (c) 2001 by David Frascone <dave@frascone.com>
*
#include "config.h"
#endif
-#ifdef HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include <glib.h>
-#include <filesystem.h>
+#include <epan/filesystem.h>
#include "xmlstub.h"
-#include "packet.h"
-#include "resolv.h"
+#include <epan/packet.h>
+#include <epan/resolv.h>
#include "prefs.h"
+#ifdef NEED_SNPRINTF_H
+# include "snprintf.h"
+#endif
+
/* This must be defined before we include packet-diameter-defs.h */
/* Valid data types */
DIAMETER_MIP_REG_REQ, /* OctetString */
DIAMETER_VENDOR_ID, /* Integer32 */
DIAMETER_APPLICATION_ID
-
+
} diameterDataType;
static int hf_diameter_code = -1;
static int hf_diameter_hopbyhopid =-1;
static int hf_diameter_endtoendid =-1;
-static int hf_diameter_reserved = -1;
static int hf_diameter_version = -1;
static int hf_diameter_vendor_id = -1;
static int hf_diameter_flags = -1;
static int hf_diameter_avp_code = -1;
static int hf_diameter_avp_length = -1;
-static int hf_diameter_avp_reserved = -1;
static int hf_diameter_avp_flags = -1;
static int hf_diameter_avp_flags_vendor_specific = -1;
static int hf_diameter_avp_flags_mandatory = -1;
/* desegmentation of Diameter over TCP */
static gboolean gbl_diameter_desegment = TRUE;
-#define DIAMETER_DIR "diameter"
-#define DICT_FN "dictionary.xml"
+#define DICT_FN "diameter/dictionary.xml"
static gchar *gbl_diameterDictionary = NULL;
typedef struct _e_diameterhdr {
int res, size = 1024;
char chars[1024];
xmlParserCtxtPtr ctxt;
-
+
/* I wonder what kind of a performance hit this is? */
*XmlStub.xmlDoValidityCheckingDefaultValue = checkValid;
-
+
f = fopen(filename, "r");
if (f == NULL) {
g_warning("Diameter: Unable to open %s", filename);
valid=ctxt->valid;
XmlStub.xmlFreeParserCtxt(ctxt);
}
- fclose(f);
+ fclose(f);
/* Check valid */
if (!valid) {
if (values) {
for (i=0; values[i].strptr != NULL; i++) {
ValueName *ve = NULL;
-
+
ve = g_malloc(sizeof(ValueName));
ve->name = strdup(values[i].strptr);
ve->value = values[i].value;
avpListHead = entry;
return (0);
-
+
} /* addStaticAVP */
/*
* add them too.
*/
static int
-xmlParseAVP(xmlDocPtr doc, xmlNodePtr cur)
+xmlParseAVP(xmlNodePtr cur)
{
char *name=NULL, *description=NULL, *code=NULL, *mayEncrypt=NULL,
*mandatory=NULL, *protected=NULL, *vendorBit=NULL, *vendorName = NULL,
cur = cur->xmlChildrenNode;
while (cur != NULL ) {
- if (!strcasecmp((char *)cur->name, "type")) {
+ if (strcasecmp(cur->name, "type") == 0) {
type = XmlStub.xmlGetProp(cur, "type-name");
- }
- if (!strcasecmp((char *)cur->name, "enum")) {
+ } else if (strcasecmp(cur->name, "enum") == 0) {
char *valueName=NULL, *valueCode=NULL;
ValueName *ve = NULL;
valueName = XmlStub.xmlGetProp(cur, "name");
valueCode = XmlStub.xmlGetProp(cur, "code");
-
+
if (!valueName || !valueCode) {
g_warning( "Error, bad value on avp %s", name);
return (-1);
}
-
+
ve = g_malloc(sizeof(ValueName));
ve->name = strdup(valueName);
ve->value = atol(valueCode);
ve->next = vEntry;
vEntry = ve;
- }
- if (!strcasecmp((char *)cur->name, "grouped")) {
+ } else if (strcasecmp(cur->name, "grouped") == 0) {
/* WORK Recurse here for grouped AVPs */
type = "grouped";
}
}
/* WORK - Handle flags -- for validation later */
-
+
/* And, create the entry */
entry = (avpInfo *)g_malloc(sizeof(avpInfo));
entry->name = g_strdup(name);
entry->code = atol(code);
- if (vendorName)
+ if (vendorName)
entry->vendorName = g_strdup(vendorName);
else
entry->vendorName = NULL;
* list of commands.
*/
static int
-xmlParseCommand(xmlDocPtr doc, xmlNodePtr cur)
+xmlParseCommand(xmlNodePtr cur)
{
char *name, *code, *vendorIdString;
g_warning( "Unable to allocate memory");
return (-1);
}
-
+
entry->name = g_strdup(name);
entry->id = id;
-
+
/* Add it to the list */
entry->next = ApplicationIdHead;
ApplicationIdHead = entry;
* This routine will pars in a XML vendor entry.
*/
static int
-xmlParseVendor(xmlDocPtr doc, xmlNodePtr cur)
+xmlParseVendor(xmlNodePtr cur)
{
char *name=NULL, *code=NULL, *id=NULL;
* This routine will either parse in the base protocol, or an application.
*/
static int
-xmlDictionaryParseSegment(xmlDocPtr doc, xmlNodePtr cur, int base)
+xmlDictionaryParseSegment(xmlNodePtr cur, int base)
{
if (!base) {
char *name;
char *id;
-
+
/* Add our application */
id = XmlStub.xmlGetProp(cur, "id");
name = XmlStub.xmlGetProp(cur, "name");
-
+
if (!name || !id) {
/* ERROR!!! */
g_warning("Diameter: Invalid application!: name=\"%s\", id=\"%s\"",
name?name:"NULL", id?id:"NULL");
return -1;
}
-
+
/* Add the application */
if (dictionaryAddApplication(name, atol(id)) != 0) {
/* ERROR! */
}
}
-
+
/*
* Get segment values
*/
cur = cur->xmlChildrenNode;
while (cur != NULL) {
- if (!strcasecmp((char *)cur->name, "avp")) {
+ if (strcasecmp(cur->name, "avp") == 0) {
/* we have an avp!!! */
- xmlParseAVP(doc, cur);
- } else if (!strcasecmp((char *)cur->name, "vendor")) {
+ xmlParseAVP(cur);
+ } else if (strcasecmp(cur->name, "vendor") == 0) {
/* we have a vendor */
- xmlParseVendor(doc, cur);
+ xmlParseVendor(cur);
/* For now, ignore typedefn and text */
- } else if (!strcasecmp((char *)cur->name, "command")) {
+ } else if (strcasecmp(cur->name, "command") == 0) {
/* Found a command */
- xmlParseCommand(doc,cur);
- } else if (!strcasecmp((char *)cur->name, "text")) {
- } else if (!strcasecmp((char *)cur->name, "comment")) {
- } else if (!strcasecmp((char *)cur->name, "typedefn")) {
+ xmlParseCommand(cur);
+ } else if (strcasecmp(cur->name, "text") == 0) {
+ } else if (strcasecmp(cur->name, "comment") == 0) {
+ } else if (strcasecmp(cur->name, "typedefn") == 0) {
/* WORK -- parse in valid types . . . */
} else {
/* IF we got here, we're an error */
} /* xmlDictionaryParseSegment */
/*
- * The main xml parse routine. This will walk through an XML
+ * The main xml parse routine. This will walk through an XML
* dictionary that has been parsed by libxml.
*/
static int
-xmlDictionaryParse(xmlDocPtr doc, xmlNodePtr cur)
+xmlDictionaryParse(xmlNodePtr cur)
{
/* We should expect a base protocol, followed by multiple applicaitons */
while (cur != NULL) {
- if (!strcasecmp((char *)cur->name, "base")) {
+ if (strcasecmp(cur->name, "base") == 0) {
/* Base protocol. Descend and parse */
- xmlDictionaryParseSegment(doc, cur, 1);
- } else if (!strcasecmp((char *)cur->name, "application")) {
+ xmlDictionaryParseSegment(cur, 1);
+ } else if (strcasecmp(cur->name, "application") == 0) {
/* Application. Descend and parse */
- xmlDictionaryParseSegment(doc, cur, 0);
- } else if (!strcasecmp((char *)cur->name, "text")) {
+ xmlDictionaryParseSegment(cur, 0);
+ } else if (strcasecmp(cur->name, "text") == 0) {
/* Ignore text */
} else {
g_warning( "Diameter: XML Expecting a base or an application (got \"%s\")",
gbl_diameterDictionary);
return -1;
}
-
+
/*
* Check the document is of the right kind
*/
XmlStub.xmlFreeDoc(doc);
return -1;
}
-
+
/*
* Ok, the dictionary has been parsed by libxml, and is valid.
* All we have to do now is read in our information.
*/
- if (xmlDictionaryParse(doc, cur->xmlChildrenNode) != 0) {
+ if (xmlDictionaryParse(cur->xmlChildrenNode) != 0) {
/* Error has already been printed */
return -1;
}
} /* initializeDictionaryDefaults */
-/*
- * This routine will attempt to load the XML dictionary, and on
+/*
+ * This routine will attempt to load the XML dictionary, and on
* failure, will call initializeDictionaryDefaults to load in
* our static dictionary.
*/
initializeDictionary()
{
/*
- * Using ugly ordering here. If loadLibXML succeeds, then
+ * Using ugly ordering here. If loadLibXML succeeds, then
* loadXMLDictionary will be called. This is one of the few times when
* I think this is prettier than the nested if alternative.
*/
}
}
}
-
- g_warning("Diameter: Unable to find name for command code 0x%08x, Vendor \"%d\"!",
+
+ g_warning("Diameter: Unable to find name for command code 0x%08x, Vendor \"%u\"!",
commandCode, vendorId);
snprintf(buffer, sizeof(buffer),
"Cmd-0x%08x", commandCode);
} /*diameter_app_to_str */
/* return an avp type, based on the code */
-diameterDataType
+static diameterDataType
diameter_avp_get_type(guint32 avpCode, guint32 vendorId){
avpInfo *probe;
gchar *vendorName=NULL;
-
+
if (vendorId)
vendorName = diameter_vendor_to_str(vendorId, FALSE);
-
+
for (probe=avpListHead; probe; probe=probe->next) {
if (avpCode == probe->code) {
-
+
if (vendorId) {
/* g_warning("AvpType: Comparing \"%s\" to \"%s\"", */
/* vendorName?vendorName:"(null)", */
}
}
}
-
+
/* If we don't find it, assume it's data */
- g_warning("Diameter: Unable to find type for avpCode %d, Vendor %d!", avpCode,
+ g_warning("Diameter: Unable to find type for avpCode %u, Vendor %u!", avpCode,
vendorId);
return DIAMETER_OCTET_STRING;
} /* diameter_avp_get_type */
}
}
- g_warning("Diameter: Unable to find name for AVP 0x%08x, Vendor %d!",
+ g_warning("Diameter: Unable to find name for AVP 0x%08x, Vendor %u!",
avpCode, vendorId);
/* If we don't find it, build a name string */
return buffer;
} /* diameter_avp_get_value */
-static gchar *
-diameter_time_to_string(gchar *timeValue)
-{
- static gchar buffer[64];
- int intval;
- struct tm lt;
-
- intval=pntohl(*((guint32*)timeValue));
- intval -= NTP_TIME_DIFF;
- lt=*localtime((time_t *)&intval);
- strftime(buffer, 1024,
- "%a, %d %b %Y %H:%M:%S %z",<);
- return buffer;
-} /* diameter_time_to_string */
-
/* Code to actually dissect the packets */
initializeDictionary();
initialized=TRUE;
}
-
+
/* Make entries in Protocol column and Info column on summary display */
- if (check_col(pinfo->cinfo, COL_PROTOCOL))
- col_add_str(pinfo->cinfo, COL_PROTOCOL, "Diameter");
- if (check_col(pinfo->cinfo, COL_INFO))
+ if (check_col(pinfo->cinfo, COL_PROTOCOL))
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "Diameter");
+ if (check_col(pinfo->cinfo, COL_INFO))
col_clear(pinfo->cinfo, COL_INFO);
-
+
/* Copy our header */
tvb_memcpy(tvb, (guint8*) &dh, offset, sizeof(dh));
-
+
/* Fix byte ordering in our static structure */
- dh.versionLength = ntohl(dh.versionLength);
- dh.flagsCmdCode = ntohl(dh.flagsCmdCode);
- dh.vendorId = ntohl(dh.vendorId);
- dh.hopByHopId = ntohl(dh.hopByHopId);
- dh.endToEndId = ntohl(dh.endToEndId);
+ dh.versionLength = g_ntohl(dh.versionLength);
+ dh.flagsCmdCode = g_ntohl(dh.flagsCmdCode);
+ dh.vendorId = g_ntohl(dh.vendorId);
+ dh.hopByHopId = g_ntohl(dh.hopByHopId);
+ dh.endToEndId = g_ntohl(dh.endToEndId);
if (dh.vendorId) {
- strcpy(vendorName,
+ strcpy(vendorName,
diameter_vendor_to_str(dh.vendorId, TRUE));
} else {
strcpy(vendorName, "None");
commandCode = DIAM_GET_COMMAND(dh);
/* Set up our flags */
- if (check_col(pinfo->cinfo, COL_INFO) || tree) {
+ if (check_col(pinfo->cinfo, COL_INFO) || tree) {
flagstr[0]=0;
for (i = 0; i < 8; i++) {
bpos = 1 << i;
strcpy(flagstr,"<None>");
}
}
-
+
/* Set up our commandString */
strcpy(commandString, diameter_command_to_str(commandCode, dh.vendorId));
- if (flags & DIAM_FLAGS_R)
+ if (flags & DIAM_FLAGS_R)
strcat(commandString, "-Request");
else
strcat(commandString, "-Answer");
/* Short packet. Should have at LEAST one avp */
if (pktLength < MIN_DIAMETER_SIZE) {
- g_warning("Diameter: Packet too short: %d bytes less than min size (%d bytes))",
- pktLength, MIN_DIAMETER_SIZE);
+ g_warning("Diameter: Packet too short: %u bytes less than min size (%lu bytes))",
+ pktLength, (unsigned long)MIN_DIAMETER_SIZE);
BadPacket = TRUE;
}
if (check_col(pinfo->cinfo, COL_INFO)) {
col_add_fstr(pinfo->cinfo, COL_INFO,
- "%s%s%s%s%s vendor=%s (hop-id=%d) (end-id=%d) RPE=%d%d%d",
+ "%s%s%s%s%s vendor=%s (hop-id=%u) (end-id=%u) RPE=%d%d%d",
(BadPacket)?"***** Bad Packet!: ":"",
(flags & DIAM_FLAGS_P)?"Proxyable ":"",
(flags & DIAM_FLAGS_E)?" Error":"",
(flags & DIAM_FLAGS_P)?1:0,
(flags & DIAM_FLAGS_E)?1:0);
}
-
+
/* In the interest of speed, if "tree" is NULL, don't do any work not
necessary to generate protocol tree items. */
/* Update the lengths */
avplength= pktLength - sizeof(e_diameterhdr);
-
+
avp_tvb = tvb_new_subset(tvb, offset, avplength, avplength);
avptf = proto_tree_add_text(diameter_tree,
tvb, offset, avplength,
"Attribute Value Pairs");
-
+
avp_tree = proto_item_add_subtree(avptf,
ett_diameter_avp);
if (avp_tree != NULL) {
guint32 plen;
guint32 available_bytes;
/* guint32 noffset; */
-
+
/* Loop through the packet, dissecting multiple diameter messages */
do {
available_bytes = tvb_length_remaining(tvb, offset);
return;
}
}
-
+
/* Otherwise, dissect our packet */
offset = dissect_diameter_common(tvb, offset, pinfo, tree);
mip_tvb = tvb_new_subset(tvb, offset,
MIN(length, tvb_length(tvb)-offset),
length);
-
+
/* The contained packet is a MIP registration request;
dissect it with the MIP dissector. */
col_set_writable(pinfo->cinfo, FALSE);
int hdrLength;
int fixAmt;
proto_tree *avpi_tree;
- size_t offset = 0 ;
- char dataBuffer[4096];
+ size_t offset = 0;
tvbuff_t *group_tvb;
proto_tree *group_tree;
proto_item *grouptf;
guint8 flags;
proto_item *tf;
proto_tree *flags_tree;
-
+
gint32 packetLength;
size_t avpDataLength;
int avpType;
/* Check for short packet */
if (packetLength < (long)MIN_AVP_SIZE) {
- g_warning("Diameter: AVP Payload too short: %d bytes less than min size (%d bytes))",
- packetLength, MIN_AVP_SIZE);
+ g_warning("Diameter: AVP Payload too short: %d bytes less than min size (%ld bytes))",
+ packetLength, (long)MIN_AVP_SIZE);
BadPacket = TRUE;
/* Don't even bother trying to parse a short packet. */
return;
}
-
+
/* Copy our header */
tvb_memcpy(tvb, (guint8*) &avph, offset, MIN((long)sizeof(avph),packetLength));
-
+
/* Fix the byte ordering */
- avph.avp_code = ntohl(avph.avp_code);
- avph.avp_flagsLength = ntohl(avph.avp_flagsLength);
-
+ avph.avp_code = g_ntohl(avph.avp_code);
+ avph.avp_flagsLength = g_ntohl(avph.avp_flagsLength);
+
flags = (avph.avp_flagsLength & 0xff000000) >> 24;
avpLength = avph.avp_flagsLength & 0x00ffffff;
-
+
/* Set up our flags string */
- if (check_col(pinfo->cinfo, COL_INFO) || avp_tree) {
+ if (check_col(pinfo->cinfo, COL_INFO) || avp_tree) {
flagstr[0]=0;
for (i = 0; i < 8; i++) {
bpos = 1 << i;
/* Dissect our vendor id if it exists and set hdr length */
if (flags & AVP_FLAGS_V) {
- vendorId = ntohl(avph.avp_vendorId);
+ vendorId = g_ntohl(avph.avp_vendorId);
/* Vendor id */
hdrLength = sizeof(e_avphdr);
} else {
/* No vendor */
- hdrLength = sizeof(e_avphdr) -
+ hdrLength = sizeof(e_avphdr) -
sizeof(guint32);
vendorId = 0;
}
if (vendorId) {
- strcpy(vendorName,
+ strcpy(vendorName,
diameter_vendor_to_str(vendorId, TRUE));
} else {
vendorName[0]='\0';
}
/* Check for bad length */
- if (avpLength < MIN_AVP_SIZE ||
+ if (avpLength < MIN_AVP_SIZE ||
((long)avpLength > packetLength)) {
- g_warning("Diameter: AVP payload size invalid: avp_length: %d bytes, "
- "min: %d bytes, packetLen: %d",
- avpLength, MIN_AVP_SIZE, packetLength);
+ g_warning("Diameter: AVP payload size invalid: avp_length: %ld bytes, "
+ "min: %ld bytes, packetLen: %d",
+ (long)avpLength, (long)MIN_AVP_SIZE,
+ packetLength);
BadPacket = TRUE;
}
/* For now, don't set bad packet, since I'm accidentally setting a wrong bit */
/* BadPacket = TRUE; */
}
-
+
/*
* Compute amount of byte-alignment fix (Diameter AVPs are sent on 4 byte
* boundries)
*/
fixAmt = 4 - (avpLength % 4);
if (fixAmt == 4) fixAmt = 0;
-
+
/* shrink our packetLength */
packetLength = packetLength - (avpLength + fixAmt);
-
+
/* Check for out of bounds */
if (packetLength < 0) {
g_warning("Diameter: Bad AVP: Bad new length (%d bytes) ",
/* Make avp Name & type */
strcpy(avpTypeString, val_to_str(diameter_avp_get_type(avph.avp_code,vendorId),
- TypeValues,
+ TypeValues,
"Unknown-Type: 0x%08x"));
strcpy(avpNameString, diameter_avp_get_name(avph.avp_code, vendorId));
proto_tree_add_uint_format(avpi_tree, hf_diameter_avp_code,
tvb, offset, 4, avph.avp_code, "AVP Code: %s", avpNameString);
offset += 4;
-
+
tf = proto_tree_add_uint_format(avpi_tree, hf_diameter_avp_flags, tvb,
offset , 1, flags, "Flags: 0x%02x (%s)", flags,
flagstr);
if (BadPacket) {
offset -= hdrLength;
proto_tree_add_bytes_format(avpi_tree, hf_diameter_avp_data_bytes,
- tvb, offset, tvb_length(tvb) - offset, dataBuffer,
- "Bad AVP (Suspect Data Not Dissected)");
+ tvb, offset, tvb_length(tvb) - offset,
+ tvb_get_ptr(tvb, offset, tvb_length(tvb) - offset),
+ "Bad AVP (Suspect Data Not Dissected)");
return;
}
avpType=diameter_avp_get_type(avph.avp_code,vendorId);
- tvb_memcpy(tvb, (guint8*) dataBuffer, offset, MIN(4095,avpDataLength));
-
-
+
switch(avpType) {
case DIAMETER_GROUPED:
sprintf(buffer, "%s Grouped AVPs", avpNameString);
grouptf = proto_tree_add_text(avpi_tree,
tvb, offset, tvb_length(tvb),
buffer);
-
+
group_tree = proto_item_add_subtree(grouptf,
ett_diameter_avp);
break;
case DIAMETER_IDENTITY:
- proto_tree_add_string_format(avpi_tree, hf_diameter_avp_data_string,
- tvb, offset, avpDataLength, dataBuffer,
- "Identity: %*.*s", (int)avpDataLength, (int)avpDataLength,
- dataBuffer);
+ {
+ const guint8 *data;
+
+ data = tvb_get_ptr(tvb, offset, avpDataLength);
+ proto_tree_add_string_format(avpi_tree, hf_diameter_avp_data_string,
+ tvb, offset, avpDataLength, data,
+ "Identity: %*.*s",
+ (int)avpDataLength,
+ (int)avpDataLength, data);
+ }
break;
case DIAMETER_UTF8STRING:
- proto_tree_add_string_format(avpi_tree, hf_diameter_avp_data_string,
- tvb, offset, avpDataLength, dataBuffer,
- "UTF8String: %*.*s", (int)avpDataLength, (int)avpDataLength,
- dataBuffer);
+ {
+ const guint8 *data;
+
+ data = tvb_get_ptr(tvb, offset, avpDataLength);
+ proto_tree_add_string_format(avpi_tree, hf_diameter_avp_data_string,
+ tvb, offset, avpDataLength, data,
+ "UTF8String: %*.*s",
+ (int)avpDataLength,
+ (int)avpDataLength, data);
+ }
break;
case DIAMETER_IP_ADDRESS:
if (avpDataLength == 4) {
- guint32 ipv4Address = ntohl((*(guint32*)dataBuffer));
- proto_tree_add_ipv4_format(avpi_tree, hf_diameter_avp_data_v4addr,
- tvb, offset, avpDataLength, ipv4Address,
- "IPv4 Address: %u.%u.%u.%u",
- (ipv4Address&0xff000000)>>24,
- (ipv4Address&0xff0000)>>16,
- (ipv4Address&0xff00)>>8,
- (ipv4Address&0xff));
+ proto_tree_add_item(avpi_tree, hf_diameter_avp_data_v4addr,
+ tvb, offset, avpDataLength, FALSE);
} else if (avpDataLength == 16) {
- proto_tree_add_ipv6_format(avpi_tree, hf_diameter_avp_data_v6addr,
- tvb, offset, avpDataLength, dataBuffer,
- "IPv6 Address: %04x:%04x:%04x:%04x",
- *((guint32*)dataBuffer),
- *((guint32*)&dataBuffer[4]),
- *((guint32*)&dataBuffer[8]),
- *((guint32*)&dataBuffer[12]));
+ proto_tree_add_item(avpi_tree, hf_diameter_avp_data_v6addr,
+ tvb, offset, avpDataLength, FALSE);
} else {
proto_tree_add_bytes_format(avpi_tree, hf_diameter_avp_data_bytes,
- tvb, offset, avpDataLength, dataBuffer,
- "Error! Bad Address Length");
+ tvb, offset, avpDataLength,
+ tvb_get_ptr(tvb, offset, avpDataLength),
+ "Error! Bad Address Length");
}
break;
case DIAMETER_INTEGER32:
- {
- gint32 data;
- memcpy(&data, dataBuffer, 4);
- data = ntohl(data);
- proto_tree_add_int_format(avpi_tree, hf_diameter_avp_data_int32,
- tvb, offset, avpDataLength, data,
- "Value: %d", data );
+ if (avpDataLength == 4) {
+ proto_tree_add_item(avpi_tree, hf_diameter_avp_data_int32,
+ tvb, offset, avpDataLength, FALSE);
+ } else {
+ proto_tree_add_bytes_format(avpi_tree, hf_diameter_avp_data_bytes,
+ tvb, offset, avpDataLength,
+ tvb_get_ptr(tvb, offset, avpDataLength),
+ "Error! Bad Integer32 Length");
}
break;
case DIAMETER_UNSIGNED32:
- {
+ if (avpDataLength == 4) {
guint32 data;
- memcpy(&data, dataBuffer, 4);
- data=ntohl(data);
+ data = tvb_get_ntohl(tvb, offset);
proto_tree_add_uint_format(avpi_tree, hf_diameter_avp_data_uint32,
- tvb, offset, avpDataLength, data,
- "Value: 0x%08x (%u)", data,
- data );
+ tvb, offset, avpDataLength, data,
+ "Value: 0x%08x (%u)", data, data);
+ } else {
+ proto_tree_add_bytes_format(avpi_tree, hf_diameter_avp_data_bytes,
+ tvb, offset, avpDataLength,
+ tvb_get_ptr(tvb, offset, avpDataLength),
+ "Error! Bad Unsigned32 Length");
}
break;
case DIAMETER_INTEGER64:
- proto_tree_add_item(avpi_tree, hf_diameter_avp_data_int64, tvb, offset, 8, FALSE);
+ if (avpDataLength == 8) {
+ proto_tree_add_item(avpi_tree, hf_diameter_avp_data_int64,
+ tvb, offset, 8, FALSE);
+ } else {
+ proto_tree_add_bytes_format(avpi_tree, hf_diameter_avp_data_bytes,
+ tvb, offset, avpDataLength,
+ tvb_get_ptr(tvb, offset, avpDataLength),
+ "Error! Bad Integer64 Length");
+ }
break;
case DIAMETER_UNSIGNED64:
- proto_tree_add_item(avpi_tree, hf_diameter_avp_data_uint64, tvb, offset, 8, FALSE);
+ if (avpDataLength == 8) {
+ proto_tree_add_item(avpi_tree, hf_diameter_avp_data_uint64,
+ tvb, offset, 8, FALSE);
+ } else {
+ proto_tree_add_bytes_format(avpi_tree, hf_diameter_avp_data_bytes,
+ tvb, offset, avpDataLength,
+ tvb_get_ptr(tvb, offset, avpDataLength),
+ "Error! Bad Unsigned64 Length");
+ }
break;
case DIAMETER_TIME:
- valstr=diameter_time_to_string(dataBuffer);
+ if (avpDataLength == 4) {
+ nstime_t data;
+ gchar buffer[64];
+ struct tm *ltp;
- proto_tree_add_bytes_format(avpi_tree, hf_diameter_avp_data_bytes,
- tvb, offset, avpDataLength, dataBuffer, "Time: %s", valstr);
+ data.secs = tvb_get_ntohl(tvb, offset);
+ data.secs -= NTP_TIME_DIFF;
+ data.nsecs = 0;
+
+ ltp = localtime(&data.secs);
+ strftime(buffer, 64,
+ "%a, %d %b %Y %H:%M:%S %z", ltp);
+
+ proto_tree_add_time_format(avpi_tree, hf_diameter_avp_data_time,
+ tvb, offset, avpDataLength, &data,
+ "Time: %s", buffer);
+ } else {
+ proto_tree_add_bytes_format(avpi_tree, hf_diameter_avp_data_bytes,
+ tvb, offset, avpDataLength,
+ tvb_get_ptr(tvb, offset, avpDataLength),
+ "Error! Bad Time Length");
+ }
break;
case DIAMETER_ENUMERATED:
- {
+ if (avpDataLength == 4) {
guint32 data;
-
- memcpy(&data, dataBuffer, 4);
- data = ntohl(data);
+
+ data = tvb_get_ntohl(tvb, offset);
valstr = diameter_avp_get_value(avph.avp_code, vendorId, data);
proto_tree_add_uint_format(avpi_tree, hf_diameter_avp_data_uint32,
- tvb, offset, avpDataLength, data,
- "Value: 0x%08x (%u): %s", data, data, valstr);
+ tvb, offset, avpDataLength, data,
+ "Value: 0x%08x (%u): %s", data,
+ data, valstr);
+ } else {
+ proto_tree_add_bytes_format(avpi_tree, hf_diameter_avp_data_bytes,
+ tvb, offset, avpDataLength,
+ tvb_get_ptr(tvb, offset, avpDataLength),
+ "Error! Bad Enumerated Length");
}
break;
case DIAMETER_VENDOR_ID:
- {
+ if (avpDataLength == 4) {
guint32 data;
-
- memcpy(&data, dataBuffer, 4);
- data = ntohl(data);
+
+ data = tvb_get_ntohl(tvb, offset);
valstr = diameter_vendor_to_str(data, TRUE);
proto_tree_add_uint_format(avpi_tree, hf_diameter_avp_data_uint32,
- tvb, offset, avpDataLength, data,
- "%s (0x%08x)", valstr, data);
+ tvb, offset, avpDataLength, data,
+ "Vendor ID: %s (0x%08x)", valstr,
+ data);
+ } else {
+ proto_tree_add_bytes_format(avpi_tree, hf_diameter_avp_data_bytes,
+ tvb, offset, avpDataLength,
+ tvb_get_ptr(tvb, offset, avpDataLength),
+ "Error! Bad Vendor ID Length");
}
break;
case DIAMETER_APPLICATION_ID:
- {
+ if (avpDataLength == 4) {
guint32 data;
-
- memcpy(&data, dataBuffer, 4);
- data = ntohl(data);
+
+ data = tvb_get_ntohl(tvb, offset);
valstr = diameter_app_to_str(data);
proto_tree_add_uint_format(avpi_tree, hf_diameter_avp_data_uint32,
- tvb, offset, avpDataLength, data,
- "%s (0x%08x)", valstr, data);
+ tvb, offset, avpDataLength, data,
+ "Application ID: %s (0x%08x)",
+ valstr, data);
+ } else {
+ proto_tree_add_bytes_format(avpi_tree, hf_diameter_avp_data_bytes,
+ tvb, offset, avpDataLength,
+ tvb_get_ptr(tvb, offset, avpDataLength),
+ "Error! Bad Application ID Length");
}
break;
case DIAMETER_MIP_REG_REQ:
default:
case DIAMETER_OCTET_STRING:
proto_tree_add_bytes_format(avpi_tree, hf_diameter_avp_data_bytes,
- tvb, offset, avpDataLength, dataBuffer,
- "Hex Data Highlighted Below");
+ tvb, offset, avpDataLength,
+ tvb_get_ptr(tvb, offset, avpDataLength),
+ "Hex Data Highlighted Below");
break;
-
+
} /* switch type */
} /* avpi_tree != null */
offset += (avpLength - hdrLength);
{ &hf_diameter_length,
{ "Length","diameter.length", FT_UINT24, BASE_DEC, NULL, 0x0,
"", HFILL }},
-
+
{ &hf_diameter_flags,
{ "Flags", "diameter.flags", FT_UINT8, BASE_HEX, NULL, 0x0,
"", HFILL }},
{ "Hop-by-Hop Identifier", "diameter.hopbyhopid", FT_UINT32,
BASE_HEX, NULL, 0x0, "", HFILL }},
{ &hf_diameter_endtoendid,
- { "End-to-End Identifier", "diameter.endtoendid", FT_UINT32,
+ { "End-to-End Identifier", "diameter.endtoendid", FT_UINT32,
BASE_HEX, NULL, 0x0, "", HFILL }},
-
+
{ &hf_diameter_avp_code,
{ "AVP Code","diameter.avp.code", FT_UINT32, BASE_DEC,
NULL, 0x0, "", HFILL }},
{ "AVP Vendor Id","diameter.avp.vendorId", FT_UINT32, BASE_DEC,
NULL, 0x0, "", HFILL }},
{ &hf_diameter_avp_data_uint64,
- { "AVP Data","diameter.avp.data.uint64", FT_UINT64, BASE_DEC,
+ { "Value","diameter.avp.data.uint64", FT_UINT64, BASE_DEC,
NULL, 0x0, "", HFILL }},
{ &hf_diameter_avp_data_int64,
- { "AVP Data","diameter.avp.data.int64", FT_INT64, BASE_DEC,
+ { "Value","diameter.avp.data.int64", FT_INT64, BASE_DEC,
NULL, 0x0, "", HFILL }},
{ &hf_diameter_avp_data_uint32,
- { "AVP Data","diameter.avp.data.uint32", FT_UINT32, BASE_DEC,
+ { "Value","diameter.avp.data.uint32", FT_UINT32, BASE_DEC,
NULL, 0x0, "", HFILL }},
{ &hf_diameter_avp_data_int32,
- { "AVP Data","diameter.avp.data.int32", FT_INT32, BASE_DEC,
+ { "Value","diameter.avp.data.int32", FT_INT32, BASE_DEC,
NULL, 0x0, "", HFILL }},
{ &hf_diameter_avp_data_bytes,
- { "AVP Data","diameter.avp.data.bytes", FT_BYTES, BASE_NONE,
+ { "Value","diameter.avp.data.bytes", FT_BYTES, BASE_NONE,
NULL, 0x0, "", HFILL }},
-
{ &hf_diameter_avp_data_string,
- { "AVP Data","diameter.avp.data.string", FT_STRING, BASE_NONE,
+ { "Value","diameter.avp.data.string", FT_STRING, BASE_NONE,
NULL, 0x0, "", HFILL }},
{ &hf_diameter_avp_data_v4addr,
- { "AVP Data","diameter.avp.data.v4addr", FT_IPv4, BASE_NONE,
+ { "IPv4 Address","diameter.avp.data.v4addr", FT_IPv4, BASE_NONE,
NULL, 0x0, "", HFILL }},
{ &hf_diameter_avp_data_v6addr,
- { "AVP Data","diameter.avp.data.v6addr", FT_IPv6, BASE_NONE,
+ { "IPv6 Address","diameter.avp.data.v6addr", FT_IPv6, BASE_NONE,
NULL, 0x0, "", HFILL }},
{ &hf_diameter_avp_data_time,
- { "AVP Data","diameter.avp.data.time", FT_ABSOLUTE_TIME, BASE_NONE,
+ { "Time","diameter.avp.data.time", FT_ABSOLUTE_TIME, BASE_NONE,
NULL, 0x0, "", HFILL }},
};
&gbl_diameterDictionary);
/* Desegmentation */
- prefs_register_bool_preference(diameter_module, "diameter.desegment",
+ prefs_register_bool_preference(diameter_module, "desegment",
"Desegment all Diameter messages spanning multiple TCP segments",
"Whether the Diameter dissector should desegment all messages spanning multiple TCP segments",
&gbl_diameter_desegment);