*
* Copyright (c) 2003 by Matthijs Melchior <matthijs.melchior@xs4all.nl>
*
- * $Id: packet-asn1.c,v 1.9 2003/11/04 18:37:30 guy Exp $
+ * $Id$
*
* A plugin for:
*
#include <sys/stat.h>
#include <errno.h>
-#include "plugins/plugin_api.h"
-
#include "moduleinfo.h"
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <epan/packet.h>
-#include <epan/resolv.h>
-#include "prefs.h"
+#include <epan/addr_resolv.h>
+#include <epan/prefs.h>
#include <epan/strutil.h>
#include <epan/filesystem.h>
-#include "asn1.h"
-#include "simple_dialog.h"
-
-#include "plugins/plugin_api_defs.h"
+#include <epan/report_err.h>
+#include <epan/dissectors/packet-tcp.h>
+#include <epan/asn1.h>
+#include <wiretap/file_util.h>
#ifdef DISSECTOR_WITH_GUI
#include <gtk/gtk.h>
#endif
-#include <ipproto.h>
+#include <epan/ipproto.h>
/* Define version if we are not building ethereal statically */
-#ifndef __ETHEREAL_STATIC__
+#ifndef ENABLE_STATIC
G_MODULE_EXPORT const gchar version[] = VERSION;
#endif
#define TCP_PORT_ASN1 801
#define UDP_PORT_ASN1 801
+#define SCTP_PORT_ASN1 801
void proto_reg_handoff_asn1(void);
* Global variables associated with the preferences for asn1
*/
+#ifdef JUST_ONE_PORT
static guint global_tcp_port_asn1 = TCP_PORT_ASN1;
static guint global_udp_port_asn1 = UDP_PORT_ASN1;
+static guint global_sctp_port_asn1 = SCTP_PORT_ASN1;
static guint tcp_port_asn1 = TCP_PORT_ASN1;
static guint udp_port_asn1 = UDP_PORT_ASN1;
+static guint sctp_port_asn1 = SCTP_PORT_ASN1;
+#else
+static range_t *global_tcp_ports_asn1;
+static range_t *global_udp_ports_asn1;
+static range_t *global_sctp_ports_asn1;
+
+static range_t *tcp_ports_asn1;
+static range_t *udp_ports_asn1;
+static range_t *sctp_ports_asn1;
+#endif /* JUST_ONE_PORT */
static gboolean asn1_desegment = TRUE;
-static char *asn1_filename = 0;
-static char *default_asn1_filename = 0;
-#define ASN1FILE "asn1/default.tt"
-static char *current_asn1 = 0;
-static char *asn1_pduname = 0;
-static char *current_pduname = 0;
+static const char *asn1_filename = NULL;
+static char *old_default_asn1_filename = NULL;
+#define OLD_DEFAULT_ASN1FILE "asn1" G_DIR_SEPARATOR_S "default.tt"
+#ifdef _WIN32
+#define BAD_SEPARATOR_OLD_DEFAULT_ASN1FILE "asn1/default.tt"
+static char *bad_separator_old_default_asn1_filename = NULL;
+#endif
+static char *current_asn1 = NULL;
+static const char *asn1_pduname = NULL;
+static char *current_pduname = NULL;
static gboolean asn1_debug = FALSE;
static guint first_pdu_offset = 0;
static gboolean asn1_message_win = FALSE;
#define NEL(x) (sizeof(x)/sizeof(*x)) /* # elements in static array */
-char pabbrev[] = "asn1"; /* field prefix */
+static char pabbrev[] = "asn1"; /* field prefix */
-char fieldname[512]; /* for constructing full names */
-guint pabbrev_pdu_len; /* length initial part of fieldname with 'abbrev.asn1pdu.' */
+static char fieldname[512]; /* for constructing full names */
+static guint pabbrev_pdu_len; /* length initial part of fieldname with 'abbrev.asn1pdu.' */
/*
* Text strings describing the standard, universal, ASN.1 names.
#define ASN1_EOI 4 /* this is in the class number space... */
#define ASN1_BEG 2 /* to be merged with constructed flag, first entry in sequence */
-char tag_class[] = "UACPX";
+static const char tag_class[] = "UACPX";
-char *asn1_cls[] = { "Universal", "Application", "Context", "Private" };
+static const char *asn1_cls[] = { "Universal", "Application", "Context", "Private" };
-char *asn1_con[] = { "Primitive", "Constructed" };
+static const char *asn1_con[] = { "Primitive", "Constructed" };
-char *asn1_tag[] = {
+static const char *asn1_tag[] = {
/* 0 */ "EOC", "Boolean", "Integer", "BitString",
/* 4 */ "OctetString", "Null", "ObjectIdentifier", "ObjectDescriptor",
/* 8 */ "External", "Real", "Enumerated", "tag11",
};
/* type names used in the output of the snacc ASN.1 compiler, the TBLTypeId enum */
-gboolean tbl_types_verified = FALSE;
+static gboolean tbl_types_verified = FALSE;
typedef enum { /* copied from .../snacc/c-lib/boot/tbl.h */
TBL_BOOLEAN = 0,
TBL_reserved, /* this sequence has been visited */
TBL_CHOICE_immediate, /* immediate choice, no next */
- TBL_INVALID, /* incorrect value for this enum */
+ TBL_INVALID /* incorrect value for this enum */
} TBLTypeId;
/* Universal tags mapped to snacc ASN.1 table types */
-int asn1_uni_type[] = {
+static int asn1_uni_type[] = {
/* 0 */ TBL_INVALID, TBL_BOOLEAN, TBL_INTEGER, TBL_BITSTRING,
/* 4 */ TBL_OCTETSTRING, TBL_NULL, TBL_OID, TBL_INVALID,
/* 8 */ TBL_INVALID, TBL_REAL, TBL_ENUMERATED, TBL_INVALID,
#define TBLTYPE(x) (tbl_types[x&TBL_TYPEmask])
/* text tables for debugging and GUI */
-char *tbl_types[] = { /* 0 */ "tbl-boolean",
+static const char *tbl_types[] = {
+ /* 0 */ "tbl-boolean",
/* 1 */ "tbl-integer",
/* 2 */ "tbl-bitstring",
/* 2 */ "tbl-octetstring",
/* 19 */ "tbl-invalid",
};
-char *tbl_types_asn1[] = {
+static const char *tbl_types_asn1[] = {
/* 0 */ "BOOLEAN",
/* 1 */ "INTEGER",
/* 2 */ "BITSTRING",
/* 19 */ "INVALID entry",
};
/* conversion from snacc type to appropriate ethereal type */
-guint tbl_types_ethereal[] = {
+static guint tbl_types_ethereal[] = {
/* 0 */ FT_BOOLEAN, /* TBL_BOOLEAN */
/* 1 */ FT_UINT32, /* TBL_INTEGER */
/* 2 */ FT_UINT32, /* TBL_BITSTRING */
/* 19 */ FT_NONE, /* TBL_INVALID */
};
-char *tbl_types_ethereal_txt[] = {
+static const char *tbl_types_ethereal_txt[] = {
/* 0 */ "FT_BOOLEAN", /* TBL_BOOLEAN */
/* 1 */ "FT_UINT32", /* TBL_INTEGER */
/* 2 */ "FT_UINT32", /* TBL_BITSTRING */
/* 19 */ "FT_NONE", /* TBL_INVALID */
};
+typedef struct _PDUinfo PDUinfo;
+struct _PDUinfo {
+ guint type;
+ const char *name;
+ const char *typename;
+ const char *fullname;
+ guchar tclass;
+ guint tag;
+ guint flags;
+ GNode *reference;
+ gint typenum;
+ gint basetype; /* parent type */
+ gint mytype; /* original type number, typenum may have gone through a reference */
+ gint value_id; /* ethereal field id for the value in this PDU */
+ gint type_id; /* ethereal field id for the type of this PDU */
+ hf_register_info value_hf; /* ethereal field info for this value */
+};
+
+
+/* bits in the flags collection */
+#define PDU_OPTIONAL 1
+#define PDU_IMPLICIT 2
+#define PDU_NAMEDNUM 4
+#define PDU_REFERENCE 8
+#define PDU_TYPEDEF 0x10
+#define PDU_ANONYMOUS 0x20
+#define PDU_TYPETREE 0x40
+
+#define PDU_CHOICE 0x08000000 /* manipulated by the PDUname routine */
+
+static guint PDUinfo_initflags = 0; /* default flags for newly allocated PDUinfo structs */
+
/* description of PDU properties as passed from the matching routine
* to the decoder and GUI.
*/
typedef struct _PDUprops PDUprops;
struct _PDUprops {
guint type; /* value from enum TBLTypeId */
- char *name;
- char *typename;
- char *fullname;
+ const char *name;
+ const char *typename;
+ const char *fullname;
guint flags;
gpointer data;
gint value_id;
#define OUT_FLAG_noname 0x10
#define OUT_FLAG_constructed 0x20
-PDUprops *getPDUprops(PDUprops *out, guint offset, guint class, guint tag, guint cons);
-char *getPDUenum(PDUprops *props, guint offset, guint cls, guint tag, guint value);
+static PDUprops *getPDUprops(PDUprops *out, guint offset, guint class, guint tag, guint cons);
+static const char *getPDUenum(PDUprops *props, guint offset, guint cls, guint tag, guint value);
-char empty[] = ""; /* address of the empt string, avoids many tests for NULL */
+static const char empty[] = ""; /* address of the empt string, avoids many tests for NULL */
#define MAX_OTSLEN 256 /* max printed size for an octet string */
#ifdef NEST /* only for debugging */
/* show nesting, only for debugging... */
#define MAXTAGS MAX_NEST
-struct {
+static struct {
guchar cls;
guchar tag;
} taglist[MAXTAGS];
-char *showtaglist(guint level)
+static char *showtaglist(guint level)
{
static char tagtxt[BUFLM];
char *p = tagtxt;
return tagtxt;
}
-guint
+static guint
get_context(guint level)
{
guint ctx = 0;
/* Convert a bit string to an ascii representation for printing
* -- not thread safe ...
*/
-char *showbits(guchar *val, guint count)
+static const char *showbits(guchar *val, guint count)
{
static char str[BUFLM];
guint i;
}
/* get bitnames string for bits set */
-char * showbitnames(guchar *val, guint count, PDUprops *props, guint offset)
+static const char *
+showbitnames(guchar *val, guint count, PDUprops *props, guint offset)
{
static char str[BUFLL];
guint i;
/* Convert an oid to its conventional text representation
* -- not thread safe...
*/
-char *showoid(subid_t *oid, guint len)
+static char *showoid(subid_t *oid, guint len)
{
static char str[BUFLM];
guint i;
}
/* show octetstring, if all ascii, show that, else hex [returnrd string must be freed by caller] */
-char *showoctets(guchar *octets, guint len, guint hexlen) /* if len <= hexlen, always show hex */
+static char *
+showoctets(guchar *octets, guint len, guint hexlen) /* if len <= hexlen, always show hex */
{
guint dohex = 0;
guint i;
char *str, *p;
- char *endstr = empty;
+ const char *endstr = empty;
if (len == 0) {
str = g_malloc(1);
}
/* allow NULL pointers in strcmp, handle them as empty strings */
-int
+static int
g_strcmp(gconstpointer a, gconstpointer b)
{
if (a == 0) a = empty;
return strcmp(a, b);
}
-guint decode_asn1_sequence(tvbuff_t *tvb, guint offset, guint len, proto_tree *pt, int level);
-void PDUreset(int count, int counr2);
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+/* WARNING WARNING WARNING WARNING WARNING WARNING */
+/* */
+/* Most of the following routine is guesswork in order to */
+/* speed up resynchronisation if the dissector lost the */
+/* encoding due to incomplete captures, or a capture that */
+/* starts in the middle of a fragmented ip packet */
+/* If this poses to many problems, these settings can be */
+/* made part of the protocol settings in the user interface */
+/*************************************************************/
+
+/* check length for a reasonable value, return a corrected value */
+static int
+checklength(int len, int def, int cls, int tag, char *lenstr, int strmax)
+{
+ int newlen = len;
+
+ if ( ! def) {
+ g_snprintf(lenstr, strmax, "indefinite");
+ return len;
+ }
+
+ if (len < 0) /* negative ..... */
+ newlen = 4;
+
+ if (cls != ASN1_UNI) { /* don't know about the tags */
+ if (len > 131071)
+ newlen = 64;
+ } else {
+ switch (tag) {
+ case ASN1_EOC: /* End Of Contents */
+ case ASN1_NUL: /* Null */
+ newlen = 0;
+ break;
+ case ASN1_BOL: /* Boolean */
+ newlen = 1;
+ break;
+ case ASN1_INT: /* Integer */
+ case ASN1_ENUM: /* Enumerated */
+ if (len > 8)
+ newlen = 4;
+ break;
+ case ASN1_BTS: /* Bit String */
+ if (len > 8)
+ newlen = 4;
+ break;
+ case ASN1_OTS: /* Octet String */
+ case ASN1_NUMSTR: /* Numerical String */
+ case ASN1_PRNSTR: /* Printable String */
+ case ASN1_TEXSTR: /* Teletext String */
+ case ASN1_VIDSTR: /* Video String */
+ case ASN1_IA5STR: /* IA5 String */
+ case ASN1_GRASTR: /* Graphical String */
+ case ASN1_VISSTR: /* Visible String */
+ case ASN1_GENSTR: /* General String */
+ if (len > 65535)
+ newlen = 32;
+ break;
+ case ASN1_OJI: /* Object Identifier */
+ case ASN1_OJD: /* Description */
+ case ASN1_EXT: /* External */
+ if (len > 64)
+ newlen = 16;
+ break;
+ case ASN1_REAL: /* Real */
+ if (len >16)
+ newlen = 8;
+ break;
+ case ASN1_SEQ: /* Sequence */
+ case ASN1_SET: /* Set */
+ if (len > 65535)
+ newlen = 64;
+ break;
+ case ASN1_UNITIM: /* Universal Time */
+ case ASN1_GENTIM: /* General Time */
+ if (len > 32)
+ newlen = 15;
+ break;
+
+ default:
+ if (len > 131071)
+ newlen = 64;
+ break;
+ }
+ }
+
+ if (newlen != len) {
+ /* a change was needed.... */
+ g_snprintf(lenstr, strmax, "%d(changed from %d)", newlen, len);
+ } else {
+ g_snprintf(lenstr, strmax, "%d", len);
+ }
+ return newlen;
+}
+
+static guint decode_asn1_sequence(tvbuff_t *tvb, guint offset, guint len, proto_tree *pt, int level);
+static void PDUreset(int count, int counr2);
static void
dissect_asn1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
char tagstr[BUFLS];
char headstr[BUFLL];
char offstr[BUFLS];
- char *name;
+ const char *name, *tname;
volatile guint boffset;
volatile int i = 0; /* PDU counter */
proto_tree * volatile ti = 0, * volatile ti2 = 0, *asn1_tree, *tree2;
offstr[0] = 0;
if ((first_pdu_offset > 0) && !reassembled) {
boffset = first_pdu_offset;
- snprintf(offstr, sizeof(offstr), " at %d", boffset);
+ g_snprintf(offstr, sizeof(offstr), " at %d", boffset);
}
/* open BER decoding */
PDUreset(pcount, 0); /* arguments are just for debugging */
getPDUprops(&props, boffset, cls, tag, con);
name = props.name;
+ tname = props.typename;
+
+ len = checklength(len, def, cls, tag, lenstr, sizeof(lenstr));
if (asn1_debug) {
- if (def) {
- snprintf(lenstr, sizeof(lenstr), "%d", len);
- } else {
- strncpy(lenstr, "indefinite", sizeof(lenstr) );
- }
- snprintf(tagstr, sizeof(tagstr), "%ctag%d", tag_class[cls], tag);
- snprintf(headstr, sizeof(headstr), "first%s: %s %d %s, %s, %s, len=%s, off=%d, size=%d ",
+ g_snprintf(tagstr, sizeof(tagstr), "%ctag%d", tag_class[cls], tag);
+
+ g_snprintf(headstr, sizeof(headstr), "first%s: (%s)%s %d %s, %s, %s, len=%s, off=%d, size=%d ",
offstr,
+ tname,
name,
pcount,
asn1_cls[cls],
);
} else {
if (props.flags & OUT_FLAG_noname) {
- snprintf(tagstr, sizeof(tagstr), "%ctag%d", tag_class[cls], tag);
+ g_snprintf(tagstr, sizeof(tagstr), "%ctag%d", tag_class[cls], tag);
name = ((cls == ASN1_UNI) && (tag < 32)) ? asn1_tag[tag] : tagstr;
}
- snprintf(headstr, sizeof(headstr), "first pdu%s: %s ", offstr, name );
+ g_snprintf(headstr, sizeof(headstr), "first pdu%s: (%s)%s ", offstr, tname, name );
}
-
+
/* Set the info column */
if(check_col(pinfo->cinfo, COL_INFO)){
col_add_str(pinfo->cinfo, COL_INFO, headstr );
tree2 = proto_item_add_subtree(ti, ett_asn1);
+ proto_tree_add_item_hidden(tree2, ((PDUinfo *)PDUtree->data)->value_id, tvb, boffset,
+ def? (int) (offset - boffset + len) : -1, TRUE);
+
offset = boffset; /* the first packet */
while((i < MAXPDU) && (tvb_length_remaining(tvb, offset) > 0)) {
ti2 = 0;
PDUreset(pcount, i+1);
getPDUprops(&props, boffset, cls, tag, con);
name = props.name;
+ tname = props.typename;
if (!def)
len = tvb_length_remaining(tvb, offset);
+ len = checklength(len, def, cls, tag, lenstr, sizeof(lenstr));
+
if (asn1_debug) {
- if (def) {
- snprintf(lenstr, sizeof(lenstr), "%d", len);
- } else {
- strncpy(lenstr, "indefinite", sizeof(lenstr));
- }
- snprintf(tagstr, sizeof(tagstr), "%ctag%d", tag_class[cls], tag);
- snprintf(headstr, sizeof(headstr), "%s, %s, %s, len=%s, off=%d, remaining=%d",
+ g_snprintf(tagstr, sizeof(tagstr), "%ctag%d", tag_class[cls], tag);
+
+ g_snprintf(headstr, sizeof(headstr), "%s, %s, %s, len=%s, off=%d, remaining=%d",
asn1_cls[cls],
asn1_con[con],
((cls == ASN1_UNI) && (tag < 32)) ? asn1_tag[tag] : tagstr,
if (props.value_id == -1)
ti2 = proto_tree_add_text(tree2, tvb, boffset,
def? (int) (offset - boffset + len) : -1,
- "%s: %s %d-%d %s", current_pduname, name,
- pcount, i+1, headstr);
+ "%s: (%s)%s %d-%d %s", current_pduname,
+ tname, name, pcount, i+1, headstr);
else {
ti2 = proto_tree_add_none_format(tree2, props.value_id, tvb, boffset,
def? (int) (offset - boffset + len) : -1,
- "%s: %s %d-%d %s ~", current_pduname, name,
- pcount, i+1, headstr);
+ "%s: (%s)%s %d-%d %s ~", current_pduname,
+ tname, name, pcount, i+1, headstr);
if (props.type_id != -1)
proto_tree_add_item_hidden(tree2, props.type_id, tvb, boffset,
}
} else {
if (props.flags & OUT_FLAG_noname) {
- snprintf(tagstr, sizeof(tagstr), "%ctag%d", tag_class[cls], tag);
+ g_snprintf(tagstr, sizeof(tagstr), "%ctag%d", tag_class[cls], tag);
name = ((cls == ASN1_UNI) && (tag < 32)) ? asn1_tag[tag] : tagstr;
}
if (props.value_id == -1)
ti2 = proto_tree_add_text(tree2, tvb, boffset,
def? (int) (offset - boffset + len) : -1,
- "%s: %s", current_pduname, name);
+ "%s: (%s)%s", current_pduname, tname, name);
else {
ti2 = proto_tree_add_none_format(tree2, props.value_id, tvb, boffset,
def? (int) (offset - boffset + len) : -1,
- "%s: %s ~", current_pduname, name);
+ "%s: (%s)%s ~", current_pduname, tname, name);
if (props.type_id != -1)
proto_tree_add_item_hidden(tree2, props.type_id, tvb, boffset,
def? (int) (offset - boffset + len) : -1, TRUE);
#endif /* NEST */
if (!def) len++; /* make sure we get an exception if we run off the end! */
+
offset = decode_asn1_sequence(tvb, offset, len, asn1_tree, 1);
+
proto_item_set_len(ti2, offset - boffset); /* mark length for hex display */
i++; /* one more full message handled */
}
/* decode an ASN.1 sequence, until we have consumed the specified length */
-guint
+static guint
decode_asn1_sequence(tvbuff_t *tvb, guint offset, guint tlen, proto_tree *pt, int level)
{
ASN1_SCK asn1;
guint ret, cls, con, tag, def, len, boffset, soffset, eos;
guint value;
- char *clsstr, *constr, *tagstr;
+ const char *clsstr, *constr, *tagstr;
char tagbuf[BUFLM];
char lenbuf[BUFLM];
char nnbuf[BUFLS];
static char textfmt_b[] = "off=%d: [%s %s %s] (%s)%s: %s:%s%s"; /* bit field */
static char textfmt_c[] = "off=%d: [%s %s %s] (%s)%s%s%s"; /* constructed */
static char matchind[] = " ~"; /* indication of possible match */
- char *name, *ename, *tname, *oname;
+ const char *name, *ename, *tname;
+ char *oname;
PDUprops props;
ti = 0; /* suppress gcc warning */
if ((cls == ASN1_UNI) && ( tag < 32 )) {
tagstr = asn1_tag[tag];
} else {
- snprintf(tagbuf, sizeof(tagbuf), "%ctag%d", tag_class[cls], tag);
+ g_snprintf(tagbuf, sizeof(tagbuf), "%ctag%d", tag_class[cls], tag);
tagstr = tagbuf;
}
+
+ len = checklength(len, def, cls, tag, lenbuf, sizeof(lenbuf));
+
if (def) {
- snprintf(lenbuf, sizeof(lenbuf), "%d", len);
- snprintf(nnbuf, sizeof(nnbuf), "NN%d", len);
+ g_snprintf(nnbuf, sizeof(nnbuf), "NN%d", len);
} else {
- strncpy(lenbuf, "indefinite", sizeof(lenbuf));
strncpy(nnbuf, "NN-", sizeof(nnbuf));
/* make sure we get an exception if we run off the end! */
len = tvb_length_remaining(tvb, offset) + 1;
/* search throug the ASN.1 description for appropriate names */
/************************************************************************************************/
-guint lev_limit = G_MAXINT;;
+guint lev_limit = G_MAXINT;
int icount = 0; /* item counter */
-guint
+static guint
parse_tt3(tvbuff_t *tvb, guint offset, guint size, guint level, GNode *ptr)
{
ASN1_SCK asn1;
guint eos, ret, cls, con, tag, def, len, value;
guchar *octets, *bits, unused;
subid_t *oid;
- char *clsstr, *constr, *tagstr;
+ const char *clsstr, *constr, *tagstr;
char tagbuf[BUFLM];
char lenbuf[BUFLM];
GNode *cur_node = 0;
while(offset < eos) {
if (ptr) /* build pointer tree to all asn1 enteties */
- cur_node = g_node_append_data(ptr, (void *)offset);
+ cur_node = g_node_append_data(ptr, GUINT_TO_POINTER(offset));
asn1_open(&asn1, tvb, offset);
ret = asn1_header_decode(&asn1, &cls, &con, &tag, &def, &len);
if ((cls == ASN1_UNI) && ( tag < 32 )) {
tagstr = asn1_tag[tag];
} else {
- snprintf(tagbuf, sizeof(tagbuf), "tag%d", tag);
+ g_snprintf(tagbuf, sizeof(tagbuf), "tag%d", tag);
tagstr = tagbuf;
}
if (def) {
- snprintf(lenbuf, sizeof(lenbuf), "%d", len);
+ g_snprintf(lenbuf, sizeof(lenbuf), "%d", len);
} else {
strncpy(lenbuf, "indefinite", sizeof(lenbuf));
- len = tvb_length_remaining(tvb, offset);;
+ len = tvb_length_remaining(tvb, offset);
}
switch(cls) {
case ASN1_CTX: /* fprintf(stderr, "Context\n"); */
tagstr = tagbuf;
- snprintf(tagbuf, sizeof(tagbuf), "TAG%d", tag);
+ g_snprintf(tagbuf, sizeof(tagbuf), "TAG%d", tag);
if (def && !con) {
/* defined length, not constructed, must be a string.... */
asn1_string_value_decode(&asn1, len, &octets); /* read value */
return offset;
}
-void showGNodes(GNode *p, int n);
+static void showGNodes(GNode *p, int n);
-gboolean
+#if 0
+static gboolean
myLeaf(GNode *node, gpointer data)
{
ASN1_SCK asn1;
if ((cls == ASN1_UNI) && ( tag < 32 )) {
tagstr = asn1_tag[tag];
} else {
- snprintf(tagbuf, sizeof(tagbuf), "tag%d", tag);
+ g_snprintf(tagbuf, sizeof(tagbuf), "tag%d", tag);
tagstr = tagbuf;
}
if (def) {
- snprintf(lenbuf, sizeof(lenbuf), "%d", len);
+ g_snprintf(lenbuf, sizeof(lenbuf), "%d", len);
} else {
strncpy(lenbuf, "indefinite", sizeof(lenbuf));
}
return FALSE;
}
-void
-list_modules()
+static void
+list_modules(void)
{
if (asn1_verbose) g_message("build GNode tree:");
showGNodes(g_node_first_child(asn1_nodes), 0);
g_node_traverse(g_node_first_child(asn1_nodes), G_PRE_ORDER, G_TRAVERSE_LEAFS, -1, myLeaf, 0);
}
+#endif
-void
-tt_build_tree() /* build a GNode tree with all offset's to ASN.1 entities */
+static void
+tt_build_tree(void) /* build a GNode tree with all offset's to ASN.1 entities */
{
if (asn1_nodes)
g_node_destroy(asn1_nodes);
/*****************************************************************************************************/
-guint anonCount; /* for naming anonymous types */
+static guint anonCount; /* for naming anonymous types */
typedef struct _TBLModule TBLModule;
typedef struct _TBLTypeDef TBLTypeDef;
typedef struct _TBLNamedNumber TBLNamedNumber;
typedef struct _TBLRange TBLRange;
-typedef enum _tbl_t tbl_t;
enum _tbl_t {
TBLTYPE_Module,
TBLTYPE_TypeDef,
TBLTYPE_Type,
TBLTYPE_TypeRef,
TBLTYPE_NamedNumber,
- TBLTYPE_Range,
+ TBLTYPE_Range
};
+typedef enum _tbl_t tbl_t;
/* text for 'tbl_t' type for debugging */
-char *data_types[] = { "Module",
+static const char *data_types[] = {
+ "Module",
"TypeDef",
"Tag",
"Type",
"Range",
};
-typedef enum _TBLTypeContent_t TBLTypeContent_t;
enum _TBLTypeContent_t {
TBLTYPETYPE_None,
TBLTYPETYPE_Primitive,
TBLTYPETYPE_Elements,
- TBLTYPETYPE_TypeRef,
+ TBLTYPETYPE_TypeRef
};
+typedef enum _TBLTypeContent_t TBLTypeContent_t;
struct _TBLNamedNumber {
tbl_t type;
#define CHECKP(p) {if (p==0){g_warning("pointer==0, line %d **********", __LINE__);return;}}
-guint
+static guint
get_asn1_int(guint want_tag, guint offset)
{
ASN1_SCK asn1;
return 0;
}
-subid_t * /* with prepended length ..... */
+static subid_t * /* with prepended length ..... */
get_asn1_oid(guint want_tag, guint offset)
{
ASN1_SCK asn1;
asn1_oid_value_decode(&asn1, len, &oid, &con);
oid = g_realloc(oid, con + sizeof(guint)); /* prepend the length */
memmove(&oid[1], oid, con*sizeof(guint));
- oid[0] = con;;
+ oid[0] = con;
return oid;
} else
ret = ASN1_ERR_LENGTH_NOT_DEFINITE;
return 0;
}
-guchar * /* 0 terminated string */
+static guchar * /* 0 terminated string */
get_asn1_string(guint want_tag, guint offset)
{
ASN1_SCK asn1;
return 0;
}
-guint
+static guint
get_asn1_uint(guint offset)
{
ASN1_SCK asn1;
return value;
}
-gboolean
+static gboolean
check_tag(guint want_tag, guint offset)
{
ASN1_SCK asn1;
return FALSE;
}
-gboolean
+#if 0
+static gboolean
constructed(guint offset)
{
ASN1_SCK asn1;
return FALSE;
}
+#endif
-void
+static void
define_constraint(GNode *p, GNode *q)
{
TBLRange *range = g_malloc(sizeof(TBLRange));
p = g_node_first_child(p);
- range->from = get_asn1_int(0, (guint)p->data);
+ range->from = get_asn1_int(0, GPOINTER_TO_UINT(p->data));
p = g_node_next_sibling(p);
- range->to = get_asn1_int(1, (guint)p->data);
+ range->to = get_asn1_int(1, GPOINTER_TO_UINT(p->data));
}
-void
+static void
define_namednumber(GNode *p, GNode *q)
{
TBLNamedNumber *num = g_malloc(sizeof(TBLNamedNumber));
p = g_node_first_child(p);
- num->name = get_asn1_string(0, (guint)p->data);
+ num->name = get_asn1_string(0, GPOINTER_TO_UINT(p->data));
p = g_node_next_sibling(p);
- num->value = get_asn1_int(1, (guint)p->data);
+ num->value = get_asn1_int(1, GPOINTER_TO_UINT(p->data));
}
-void
+static void
define_typeref(GNode *p, GNode *q)
{
TBLTypeRef *ref = g_malloc(sizeof(TBLTypeRef));
p = g_node_first_child(p);
- ref->typeDefId = get_asn1_uint((guint)p->data);
+ ref->typeDefId = get_asn1_uint(GPOINTER_TO_UINT(p->data));
p = g_node_next_sibling(p);
- ref->implicit = get_asn1_int(ASN1_BOL, (guint)p->data);
+ ref->implicit = get_asn1_int(ASN1_BOL, GPOINTER_TO_UINT(p->data));
}
-void
+static void
define_tag(GNode *p, GNode *q)
{
TBLTag *type = g_malloc(sizeof(TBLTag));
p = g_node_first_child(p);
- type->tclass = get_asn1_int(ASN1_ENUM, (guint)p->data);
+ type->tclass = get_asn1_int(ASN1_ENUM, GPOINTER_TO_UINT(p->data));
p = g_node_next_sibling(p);
- type->code = get_asn1_int(ASN1_INT, (guint)p->data);
+ type->code = get_asn1_int(ASN1_INT, GPOINTER_TO_UINT(p->data));
}
-void
+static void
define_type(GNode *p, GNode *q)
{
GNode *r;
/* g_message("define_type %p, %p", p, q); */
- type->typeId = get_asn1_int(0, (guint)p->data);
+ type->typeId = get_asn1_int(0, GPOINTER_TO_UINT(p->data));
p = g_node_next_sibling(p);
- type->optional = get_asn1_int(1, (guint)p->data);
+ type->optional = get_asn1_int(1, GPOINTER_TO_UINT(p->data));
p = g_node_next_sibling(p);
- if (check_tag(2, (guint)p->data)) { /* optional, need empty node if not there ?*/
+ if (check_tag(2, GPOINTER_TO_UINT(p->data))) { /* optional, need empty node if not there ?*/
r = g_node_first_child(p);
while (r) {
define_tag(r, t);
p = g_node_next_sibling(p);
}
- if (!check_tag(3, (guint)p->data)) {
+ if (!check_tag(3, GPOINTER_TO_UINT(p->data))) {
g_warning("expect tag 3, ERROR");
}
r = g_node_first_child(p);
/* a choice ... */
type->content = TBLTYPETYPE_None;
- if (check_tag(0, (guint)r->data)) type->content = TBLTYPETYPE_Primitive;
- if (check_tag(1, (guint)r->data)) type->content = TBLTYPETYPE_Elements;
- if (check_tag(2, (guint)r->data)) type->content = TBLTYPETYPE_TypeRef;
+ if (check_tag(0, GPOINTER_TO_UINT(r->data))) type->content = TBLTYPETYPE_Primitive;
+ if (check_tag(1, GPOINTER_TO_UINT(r->data))) type->content = TBLTYPETYPE_Elements;
+ if (check_tag(2, GPOINTER_TO_UINT(r->data))) type->content = TBLTYPETYPE_TypeRef;
switch(type->content) {
case TBLTYPETYPE_Primitive:
break;
type->fieldName = 0;
type->anonymous = FALSE;
- if (p && check_tag(4, (guint)p->data)) {
- type->fieldName = get_asn1_string(4, (guint)p->data);
+ if (p && check_tag(4, GPOINTER_TO_UINT(p->data))) {
+ type->fieldName = get_asn1_string(4, GPOINTER_TO_UINT(p->data));
p = g_node_next_sibling(p);
} else {
type->anonymous = TRUE;
}
type->constraint = FALSE;
- if (p && check_tag(5, (guint)p->data)) {
+ if (p && check_tag(5, GPOINTER_TO_UINT(p->data))) {
type->constraint = TRUE;
define_constraint(p, t);
p = g_node_next_sibling(p);
}
- if (p && check_tag(6, (guint)p->data)) {
+ if (p && check_tag(6, GPOINTER_TO_UINT(p->data))) {
r = g_node_first_child(p);
while(r) {
define_namednumber(r, t);
}
}
-void
+static void
define_typedef(GNode *p, GNode *q)
{
TBLTypeDef *type_def = g_malloc(sizeof(TBLTypeDef));
p = g_node_first_child(p);
- type_def->typeDefId = get_asn1_uint((guint)p->data);
+ type_def->typeDefId = get_asn1_uint(GPOINTER_TO_UINT(p->data));
p = g_node_next_sibling(p);
- type_def->typeName = get_asn1_string(ASN1_PRNSTR, (guint)p->data);
+ type_def->typeName = get_asn1_string(ASN1_PRNSTR, GPOINTER_TO_UINT(p->data));
p = g_node_next_sibling(p);
define_type(g_node_first_child(p), t);
type_def->isPdu = (p != 0); /* true if it exists, value ignored */
}
-void
+static void
define_module(GNode *p, GNode *q)
{
TBLModule *module = g_malloc(sizeof(TBLModule));
p = g_node_first_child(p);
- module->name = get_asn1_string(0, (guint)p->data);
+ module->name = get_asn1_string(0, GPOINTER_TO_UINT(p->data));
p = g_node_next_sibling(p);
module->id = 0;
- if (check_tag(1, (guint)p->data)) { /* optional */
- module->id = get_asn1_oid(1, (guint)p->data);
+ if (check_tag(1, GPOINTER_TO_UINT(p->data))) { /* optional */
+ module->id = get_asn1_oid(1, GPOINTER_TO_UINT(p->data));
p = g_node_next_sibling(p);
}
- module->isUseful = get_asn1_int(2, (guint)p->data);
+ module->isUseful = get_asn1_int(2, GPOINTER_TO_UINT(p->data));
p = g_node_next_sibling(p);
p = g_node_first_child(p);
typedef struct _SearchDef SearchDef;
struct _SearchDef {
- char *key;
+ const char *key;
GNode *here;
};
-gboolean
+static gboolean
is_typedef(GNode *node, gpointer data)
{
TBLTypeDef *d = (TBLTypeDef *)node->data;
#define ALLOC_INCR 4
#define CLASSREF (ASN1_PRV+1)
-gboolean
+static gboolean
is_named(GNode *node, gpointer data)
{
TBLNamedNumber *num = (TBLNamedNumber *)node->data;
return FALSE;
}
-gboolean
+static gboolean
index_typedef(GNode *node, gpointer data)
{
TBLTypeDef *d = (TBLTypeDef *)node->data;
return FALSE;
}
-TypeRef *typeDef_names = 0;
-guint numTypedefs = 0;
+static TypeRef *typeDef_names = 0;
+static guint numTypedefs = 0;
-void
-get_values() /* collect values from ASN.1 tree */
+static gboolean
+free_node_data(GNode *node, gpointer data _U_)
+{
+ g_free(node->data);
+ return FALSE;
+}
+
+static void
+get_values(void) /* collect values from ASN.1 tree */
/* coded according to the tbl.asn1 description of snacc output */
{ /* This routine does not leave references to the tvbuff or */
/* to the asn1_nodes, both can be freed by the caller of this.*/
SearchDef sd;
NameDefs nd;
guint i;
- char X, *t, *s, *E;
+ char X;
+ const char *t, *s, *E;
static char missing[] = " **missing** ";
if (asn1_verbose) g_message("interpreting tree");
typeDef_names = 0; /* just forget allocated any data .... */
- if (data_nodes)
+ if (data_nodes) {
+ g_node_traverse(data_nodes, G_POST_ORDER, G_TRAVERSE_ALL, -1,
+ free_node_data, NULL);
g_node_destroy(data_nodes);
+ }
data_nodes = g_node_new(0);
p = g_node_first_child(asn1_nodes); /* top of the data tree */
p = g_node_first_child(p);
- TT.totalNumModules = get_asn1_uint((guint)p->data);
+ TT.totalNumModules = get_asn1_uint(GPOINTER_TO_UINT(p->data));
p = g_node_next_sibling(p);
- TT.totalNumTypeDefs = get_asn1_uint((guint)p->data);
+ TT.totalNumTypeDefs = get_asn1_uint(GPOINTER_TO_UINT(p->data));
p = g_node_next_sibling(p);
- TT.totalNumTypes = get_asn1_uint((guint)p->data);
+ TT.totalNumTypes = get_asn1_uint(GPOINTER_TO_UINT(p->data));
p = g_node_next_sibling(p);
- TT.totalNumTags = get_asn1_uint((guint)p->data);
+ TT.totalNumTags = get_asn1_uint(GPOINTER_TO_UINT(p->data));
p = g_node_next_sibling(p);
- TT.totalNumStrings = get_asn1_uint((guint)p->data);
+ TT.totalNumStrings = get_asn1_uint(GPOINTER_TO_UINT(p->data));
p = g_node_next_sibling(p);
- TT.totalLenStrings = get_asn1_uint((guint)p->data);
+ TT.totalLenStrings = get_asn1_uint(GPOINTER_TO_UINT(p->data));
p = g_node_next_sibling(p);
p = g_node_first_child(p);
}
-void
+static void
showGNode(GNode *p, int n)
{
if (p == 0) return;
break;
case TBLTYPE_Type: {
TBLType *t = (TBLType *)p->data;
- char *fn, *s = empty;
+ const char *fn, *s = empty;
if (t->fieldName)
s = t->fieldName;
/* typeId is a value from enum TBLTypeId */
break;
case TBLTYPE_Tag: {
TBLTag *t = (TBLTag *)p->data;
- char *s = empty;
+ const char *s = empty;
if ((t->tclass == ASN1_UNI) && (t->code < 32))
s = asn1_tag[t->code];
if (asn1_verbose) g_message("%*stag %c%d[%s]", n, empty,
break;
case TBLTYPE_TypeRef: {
TBLTypeRef *r = (TBLTypeRef *)p->data;
- char *s = empty;
+ const char *s = empty;
if (typeDef_names)
s = typeDef_names[r->typeDefId].name;
if (asn1_verbose) g_message("%*styperef %d[%s]%s", n, empty,
}
}
-void
+static void
showGNodes(GNode *p, int n)
{
if (p == 0) return;
showGNodes(p->next, n);
}
-void showGenv(GNode *p, int n, int m)
+static void showGenv(GNode *p, int n, int m)
{
int i;
}
-void
-debug_dump_TT() /* dump contents of TT struct, for debugging */
+static void
+debug_dump_TT(void) /* dump contents of TT struct, for debugging */
{
if (asn1_verbose)
g_message("modules=%d, defs=%d, types=%d, tags=%d, strings=%d, lenstrings=%d",
TT.totalLenStrings);
}
-void
+static void
my_log_handler(const gchar *log_domain, GLogLevelFlags log_level,
const gchar *message, gpointer user_data)
{
(void) log_domain; (void) log_level; (void) user_data; /* make references */
if (logf == NULL && asn1_logfile) {
- logf = fopen(asn1_logfile, "w");
+ logf = eth_fopen(asn1_logfile, "w");
}
if (logf) {
fputs(message, logf);
fputs(eol, logf);
-}
+ fflush(logf); /* debugging ... */
+ }
}
-void
-read_asn1_type_table(char *filename)
+static void
+read_asn1_type_table(const char *filename)
{
FILE *f;
guint size;
guchar *data;
struct stat stat;
- f = fopen(filename, "rb");
+ if ((filename == 0) || (strlen(filename) == 0))
+ return; /* no filename provided */
+
+ f = eth_fopen(filename, "rb");
if (f == 0) {
- if (strcmp(filename, default_asn1_filename) != 0 ||
- errno != ENOENT)
- g_warning("error opening %s, %s", filename, strerror(errno));
+ /*
+ * Ignore "file not found" errors if it's the old default
+ * ASN.1 file name, as we never shipped such a file.
+ * Also, on Win32, ignore the earlier default, which
+ * had a "/" rather than a "\" as the last pathname
+ * separator.
+ */
+ if ((strcmp(filename, old_default_asn1_filename) != 0
+#ifdef _WIN32
+ && strcmp(filename, bad_separator_old_default_asn1_filename) != 0
+#endif
+ ) || errno != ENOENT)
+ report_open_failure(filename, errno, FALSE);
return;
}
fstat(fileno(f), &stat);
tt_build_tree();
if (asn1_verbose) g_message("read %d items from %s", icount, filename);
- /* list_modules(); */
+#if 0
+ list_modules();
+#endif
get_values();
g_node_destroy(asn1_nodes); asn1_nodes = 0;
-#ifndef WIN32 /* tvb_free not yet exported to plugins... */
+#ifndef _WIN32 /* tvb_free not yet exported to plugins... */
tvb_free(asn1_desc);
#endif
asn1_desc = 0;
debug_dump_TT();
}
-typedef struct _PDUinfo PDUinfo;
-struct _PDUinfo {
- guint type;
- char *name;
- char *typename;
- char *fullname;
- guchar tclass;
- guint tag;
- guint flags;
- GNode *reference;
- gint typenum;
- gint basetype; /* parent type */
- gint mytype; /* original type number, typenum may have gone through a reference */
- gint value_id; /* ethereal field id for the value in this PDU */
- gint type_id; /* ethereal field id for the type of this PDU */
- hf_register_info value_hf; /* ethereal field info for this value */
-};
-
-
-/* bits in the flags collection */
-#define PDU_OPTIONAL 1
-#define PDU_IMPLICIT 2
-#define PDU_NAMEDNUM 4
-#define PDU_REFERENCE 8
-#define PDU_TYPEDEF 0x10
-#define PDU_ANONYMOUS 0x20
-#define PDU_TYPETREE 0x40
-
-#define PDU_CHOICE 0x08000000 /* manipulated by the PDUname routine */
-
-guint PDUinfo_initflags = 0; /* default flags for newly allocated PDUinfo structs */
#define CHECKTYPE(p,x) {if (((TBLTag *)(p)->data)->type != (x)) \
g_warning("**** unexpected type %s, want %s, at line %d", \
data_types[((TBLTag *)p->data)->type], data_types[(x)], __LINE__);}
-void
+static void
save_reference(PDUinfo *p)
{
gint i = p->mytype;
g_ptr_array_add(typeDef_names[i].refs, (gpointer)p);
}
-void
+static void
tbl_type(guint n, GNode *pdu, GNode *list, guint fullindex);
/* evaluate typeref, pointer to current pdu node and typedef */
-void
+static void
tbl_typeref(guint n, GNode *pdu, GNode *tree, guint fullindex)
{
GNode *q;
PDUinfo *p = (PDUinfo *)pdu->data, *p1;
guint nvals;
value_string *v;
+
+ if (n > 40) { /* don't believe this....! ...... stop recursion ...... */
+ g_warning("****tbl_typeref: n>40, return [recursion too deep] ****************");
+ return;
+ }
CHECKTYPE(tree, TBLTYPE_TypeDef);
ss[0] = 0;
if (p->tclass==CLASSREF)
- snprintf(ss, 128, ", CLASSREF %d", p->tag);
+ g_snprintf(ss, 128, ", CLASSREF %d", p->tag);
if (asn1_verbose) g_message("%*sno typeref tag%s", n*2, empty, ss);
if (p->tclass==CLASSREF) {
TypeRef *tr;
+ int i = p->basetype;
/* CLASSREF....., get it defined using type of the reference */
- tr = &typeDef_names[p->tag];
+ /* p->basetype may be -1 .... ? XXX */
+ if (i == -1)
+ i = p->tag;
+ tr = &typeDef_names[i];
if (asn1_verbose)
g_message("%*s*refer2 to type#%d %s, %p", n*2, empty,
p->tag, tr->name, tr->pdu);
}
}
-void
+static void
tbl_type(guint n, GNode *pdu, GNode *list, guint fullindex) /* indent, pdu, source type node list */
{
GNode *q, *pdu1;
value_string *v;
if (n > 40) { /* don't believe this....! ...... stop recursion ...... */
- g_warning("**** n>40, return [recursion too deep] ****************");
+ g_warning("****tbl_type: n>40, return [recursion too deep] ****************");
return;
}
pdu1 = pdu; /* save start location for append */
while (list) { /* handle all entries */
if (asn1_verbose)
- g_message("%*s+handle a %s", n*2, empty,
- data_types[((TBLTag *)list->data)->type]);
+ g_message("%*s+handle a %s, list=%p", n*2, empty,
+ data_types[((TBLTag *)list->data)->type], list);
if (((TBLTag *)list->data)->type == TBLTYPE_Range) { /* ignore this ..... */
list = g_node_next_sibling(list);
break;
}
- if (((TBLTag *)list->data)->type != TBLTYPE_TypeRef) {
+ /******* change to positive comparation, but leave comment for reference
+ * if (((TBLTag *)list->data)->type != TBLTYPE_TypeRef) {
+ * CHECKTYPE(list, TBLTYPE_Type);
+ */
+
+ if (((TBLTag *)list->data)->type == TBLTYPE_Type) {
CHECKTYPE(list, TBLTYPE_Type);
p = g_malloc0(sizeof(PDUinfo));
p->name = ((TBLType *)list->data)->fieldName;
ni = fullindex;
- ni += sprintf(&fieldname[ni], ".%s", p->name);
+ ni += snprintf(&fieldname[ni], sizeof(fieldname) - ni, ".%s", p->name);
p->fullname = g_strdup(fieldname);
/* initialize field info */
case TBL_SETOF:
case TBL_CHOICE:
CHECKTYPE(q, TBLTYPE_Tag);
+ q = g_node_first_child(list);
tbl_type(n+1, pdu, q, ni);
break;
}
}
-void
+static void
PDUtext(char *txt, PDUinfo *info) /* say everything we know about this entry */
{
PDUinfo *rinfo;
- char *tt, *nn, *tn, *fn, *oo, *ii, *an, *tr, *ty;
+ const char *tt, *nn, *tn, *fn, *oo, *ii, *an, *tr, *ty;
if (info) {
tt = TBLTYPE(info->type);
}
-void
+static void
showPDUtree(GNode *p, int n)
{
PDUinfo *info;
return;
}
-gboolean
-build_pdu_tree(char *pduname)
+static gboolean
+build_pdu_tree(const char *pduname)
{
SearchDef sd;
guint pdudef, i, tcount;
if (asn1_verbose) g_message("build msg tree from '%s' for '%s'", current_asn1, pduname);
+ if (!data_nodes) {
+ if (asn1_verbose) g_message("no data nodes");
+ return FALSE;
+ }
sd.key = pduname;
sd.here = 0;
g_node_traverse(data_nodes, G_PRE_ORDER, G_TRAVERSE_ALL, -1, is_typedef, (gpointer)&sd);
return FALSE;
}
+ /* If there's an existing PDU tree, free it */
+ if (PDUtree) {
+ g_node_traverse(PDUtree, G_POST_ORDER, G_TRAVERSE_ALL, -1,
+ free_node_data, NULL);
+ g_node_destroy(PDUtree);
+ }
+
/* initialize the PDU tree, hand craft the root entry */
info = g_malloc0(sizeof(PDUinfo));
N_COLUMNS
};
-FILE *namelist = 0;
+static FILE *namelist = 0;
-void
+static void
build_tree_view(GtkTreeStore *store, GNode *p, GtkTreeIter *iter)
{
GtkTreeIter iter2;
};
#define PATHSTACKMAX 10
-GtkTreePath *pathstack[PATHSTACKMAX];
-gint pathstackp = 0;
+static GtkTreePath *pathstack[PATHSTACKMAX];
+static gint pathstackp = 0;
-void add_path(GtkTreePath *p)
+static void add_path(GtkTreePath *p)
{
if (pathstackp >= PATHSTACKMAX) { /* shift old contents */
gtk_tree_path_free(pathstack[0]); /* we forget about this one */
pathstack[pathstackp++] = p;
}
-GtkTreePath *pop_path() {
+static GtkTreePath *pop_path(void)
+{
if (pathstackp > 0)
return pathstack[--pathstackp];
return 0;
}
-gboolean find_definition(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
+static gboolean
+find_definition(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
{
gint def;
}
-void
+static void
my_signal_handler(GtkTreeView *treeview, GtkTreePath *spath, GtkTreeViewColumn *arg2, gpointer model)
{
GtkTreeIter iter;
}
-void
-create_message_window()
+static void
+create_message_window(void)
{
GtkCellRenderer *renderer;
GtkTreeStore *model;
model = gtk_tree_store_new(N_COLUMNS, G_TYPE_STRING, G_TYPE_INT, G_TYPE_INT,
G_TYPE_STRING, G_TYPE_STRING);
- namelist = fopen("namelist.txt", "w");
+ namelist = eth_fopen("namelist.txt", "w");
build_tree_view(model, PDUtree, NULL);
fclose(namelist);
namelist = 0;
* routines to find names to go with the decoded data stream *
************************************************************************************************/
typedef struct _statestack statestack;
-struct _statestack {
+static struct _statestack {
GNode *node;
guint type;
guint offset;
- char *name;
+ const char *name;
} PDUstate[1024];
-gint PDUstatec = 0;
+static gint PDUstatec = 0;
#define PUSHNODE(x) { PDUstate[PDUstatec++] = (x); }
#define STORENODE(x) { PDUstate[PDUstatec-1] = (x); }
pos.node=0;PUSHNODE(pos);return ret;}}
-void
+static void
showstack(statestack *pos, char *txt, int n)
{
- char buf[1024], *name, *type, *stype;
- char *rep, *chs, *done, *ref, *pop, *chr, *rch, *sch, *con;
+ char buf[1024];
+ const char *name, *type, *stype;
+ const char *rep, *chs, *done, *ref, *pop, *chr, *rch, *sch, *con;
int i, j;
GNode *g;
statestack *p;
g_message(buf);
}
-void
+static void
showrefNode(GNode *node, int n)
{
- char *name = empty, *type = empty, *tname = empty;
+ const char *name = empty, *type = empty, *tname = empty;
int cls = 0, tag = 0;
PDUinfo *info;
GNode *ref = 0;
showrefNode(ref, n+1);
}
-void
+static void
showNode(GNode *node, int n, int m)
{
- char *name = empty, *type = empty;
+ const char *name = empty, *type = empty;
GNode *ref = 0;
if (n > m)
if (node->next) showNode(node->next, n, m);
}
-void
+static void
PDUreset(int count, int count2)
{
statestack pos;
if (PDUtree) {
pos.node = PDUtree; /* root of the tree */
- pos.name = GETNAME;;
+ pos.name = GETNAME;
pos.type = GETTYPE | TBL_REPEAT;
pos.offset = 0;
PUSHNODE(pos);
}
}
-GNode * /* find GNode for a choice element, 0 if none */
+static GNode * /* find GNode for a choice element, 0 if none */
makechoice(GNode *p, guint class, guint tag)
{
GNode *q;
}
/* offset is for debugging only, a reference to output on screen */
-PDUprops *
+static PDUprops *
getPDUprops(PDUprops *out, guint offset, guint class, guint tag, guint cons)
{
statestack pos, pos2, save_pos;
PDUinfo *info;
- char *ret, *tmp;
+ const char *ret, *tmp;
int typeflags = 0, donext = 0, pushed = 0, cons_handled = 0;
static char namestr[64]; /* enough ? */
static char posstr[40];
return out;
}
-char *
+static const char *
getPDUenum(PDUprops *props, guint offset, guint cls, guint tag, guint value)
{
GNode *list;
PDUinfo *info;
- char *ret, *name;
+ const char *ret, *name;
static char unnamed[] = "*unnamed*";
(void) cls; (void) tag; /* make a reference */
proto_register_asn1(void) {
static const enum_val_t type_recursion_opts[] = {
- { "0", 0 },
- { "1", 1 },
- { "2", 2 },
- { "3", 3 },
- { "4", 4 },
- { "5", 5 },
- { "6", 6 },
- { "7", 7 },
- { "8", 8 },
- { "9", 9 },
- { NULL, -1},
+ { "0", "0", 0 },
+ { "1", "1", 1 },
+ { "2", "2", 2 },
+ { "3", "3", 3 },
+ { "4", "4", 4 },
+ { "4", "5", 5 },
+ { "6", "6", 6 },
+ { "7", "7", 7 },
+ { "8", "8", 8 },
+ { "9", "9", 9 },
+ { NULL, NULL, -1},
};
static gint *ett[1+MAX_NEST+MAXPDU];
+ char tmpstr[64];
+
module_t *asn1_module;
int i, j;
asn1_logfile = get_tempfile_path(ASN1LOGFILE);
+ current_asn1 = g_strdup("");
+ asn1_filename = g_strdup(current_asn1);
+
current_pduname = g_strdup("ASN1");
asn1_pduname = g_strdup(current_pduname);
asn1_module = prefs_register_protocol(proto_asn1,
proto_reg_handoff_asn1);
+#ifdef JUST_ONE_PORT
prefs_register_uint_preference(asn1_module, "tcp_port",
"ASN.1 TCP Port",
"The TCP port on which "
- "ASN.1 packets will be read",
+ "ASN.1 messages will be read",
10, &global_tcp_port_asn1);
prefs_register_uint_preference(asn1_module, "udp_port",
"ASN.1 UDP Port",
"The UDP port on which "
- "ASN.1 packets will be read",
+ "ASN.1 messages will be read",
10, &global_udp_port_asn1);
+ prefs_register_uint_preference(asn1_module, "sctp_port",
+ "ASN.1 SCTP Port",
+ "The SCTP port on which "
+ "ASN.1 messages will be read",
+ 10, &global_sctp_port_asn1);
+#else
+ g_snprintf(tmpstr, sizeof(tmpstr), "%u", TCP_PORT_ASN1);
+ range_convert_str(&global_tcp_ports_asn1, tmpstr, 65535);
+
+ g_snprintf(tmpstr, sizeof(tmpstr), "%u", UDP_PORT_ASN1);
+ range_convert_str(&global_udp_ports_asn1, tmpstr, 65535);
+
+ g_snprintf(tmpstr, sizeof(tmpstr), "%u", SCTP_PORT_ASN1);
+ range_convert_str(&global_sctp_ports_asn1, tmpstr, 65535);
+
+ prefs_register_range_preference(asn1_module, "tcp_ports",
+ "ASN.1 TCP Ports",
+ "The TCP ports on which "
+ "ASN.1 messages will be read",
+ &global_tcp_ports_asn1, 65535);
+ prefs_register_range_preference(asn1_module, "udp_ports",
+ "ASN.1 UDP Ports",
+ "The UDP ports on which "
+ "ASN.1 messages will be read",
+ &global_udp_ports_asn1, 65535);
+ prefs_register_range_preference(asn1_module, "sctp_ports",
+ "ASN.1 SCTP Ports",
+ "The SCTP ports on which "
+ "ASN.1 messages will be read",
+ &global_sctp_ports_asn1, 65535);
+#endif /* JUST_ONE_PORT */
+
prefs_register_bool_preference(asn1_module, "desegment_messages",
"Desegment TCP",
"Desegment ASN.1 messages that span TCP segments",
&asn1_desegment);
- default_asn1_filename = get_datafile_path(ASN1FILE);
- asn1_filename = default_asn1_filename;
+ old_default_asn1_filename = get_datafile_path(OLD_DEFAULT_ASN1FILE);
+#ifdef _WIN32
+ bad_separator_old_default_asn1_filename = get_datafile_path(BAD_SEPARATOR_OLD_DEFAULT_ASN1FILE);
+#endif
prefs_register_string_preference(asn1_module, "file",
"ASN.1 type table file",
"ASN.1 debug mode",
"Extra output useful for debuging",
&asn1_debug);
-
+#if 0
prefs_register_bool_preference(asn1_module, "message_win",
"Show ASN.1 tree",
"show full message description",
&asn1_message_win);
+#else
+ prefs_register_obsolete_preference(asn1_module, "message_win");
+#endif
prefs_register_bool_preference(asn1_module, "verbose_log",
"Write very verbose log",
"log to file $TMP/" ASN1LOGFILE,
/* The registration hand-off routing */
+static dissector_handle_t asn1_handle;
+
+static void
+register_tcp_port(guint32 port)
+{
+ dissector_add("tcp.port", port, asn1_handle);
+}
+
+static void
+unregister_tcp_port(guint32 port)
+{
+ dissector_delete("tcp.port", port, asn1_handle);
+}
+
+static void
+register_udp_port(guint32 port)
+{
+ dissector_add("udp.port", port, asn1_handle);
+}
+
+static void
+unregister_udp_port(guint32 port)
+{
+ dissector_delete("udp.port", port, asn1_handle);
+}
+
+static void
+register_sctp_port(guint32 port)
+{
+ dissector_add("sctp.port", port, asn1_handle);
+}
+
+static void
+unregister_sctp_port(guint32 port)
+{
+ dissector_delete("sctp.port", port, asn1_handle);
+}
+
void
proto_reg_handoff_asn1(void) {
static int asn1_initialized = FALSE;
- static dissector_handle_t asn1_handle;
+#ifndef JUST_ONE_PORT
+ char *tcp_ports_asn1_string, *udp_ports_asn1_string, *sctp_ports_asn1_string;
+#endif
pcount = 0;
- if (asn1_verbose) g_message("prefs change: tcpport=%d, udpport=%d, desegnment=%d, asn1file=%s, "
- "pduname=%s, first_offset=%d, debug=%d, msg_win=%d, verbose=%d",
- global_tcp_port_asn1, global_udp_port_asn1, asn1_desegment, asn1_filename,
- asn1_pduname, first_pdu_offset, asn1_debug, asn1_message_win, asn1_verbose);
+#ifdef JUST_ONE_PORT
+ if (asn1_verbose) g_message("prefs change: tcpport=%u, udpport=%u, sctpport=%u, desegnment=%d, "
+ "asn1file=%s, pduname=%s, first_offset=%d, debug=%d, msg_win=%d, verbose=%d",
+ global_tcp_port_asn1, global_udp_port_asn1, global_sctp_port_asn1, asn1_desegment,
+ asn1_filename, asn1_pduname, first_pdu_offset, asn1_debug, asn1_message_win, asn1_verbose);
+#else
+ if (asn1_verbose) {
+ tcp_ports_asn1_string = range_convert_range(global_tcp_ports_asn1);
+ udp_ports_asn1_string = range_convert_range(global_udp_ports_asn1);
+ sctp_ports_asn1_string = range_convert_range(global_sctp_ports_asn1);
+ g_message("prefs change: tcpports=%s, udpports=%s, sctpports=%s, desegnment=%d, "
+ "asn1file=%s, pduname=%s, first_offset=%d, debug=%d, msg_win=%d, verbose=%d",
+ tcp_ports_asn1_string, udp_ports_asn1_string, sctp_ports_asn1_string, asn1_desegment,
+ asn1_filename, asn1_pduname, first_pdu_offset, asn1_debug, asn1_message_win, asn1_verbose);
+ }
+#endif /* JUST_ONE_PORT */
if(!asn1_initialized) {
asn1_handle = create_dissector_handle(dissect_asn1,proto_asn1);
asn1_initialized = TRUE;
- } else {
- dissector_delete("tcp.port", tcp_port_asn1, asn1_handle);
- dissector_delete("udp.port", udp_port_asn1, asn1_handle);
- }
+ } else { /* clean up ports and their lists */
+#ifdef JUST_ONE_PORT
+ unregister_tcp_port(tcp_port_asn1);
+ unregister_udp_port(udp_port_asn1);
+ unregister_sctp_port(sctp_port_asn1);
+#else
+ if (tcp_ports_asn1 != NULL) {
+ range_foreach(tcp_ports_asn1, unregister_tcp_port);
+ g_free(tcp_ports_asn1);
+ }
- tcp_port_asn1 = global_tcp_port_asn1;
- udp_port_asn1 = global_udp_port_asn1;
-
- dissector_add("tcp.port", global_tcp_port_asn1, asn1_handle);
- dissector_add("udp.port", global_udp_port_asn1, asn1_handle);
+ if (udp_ports_asn1 != NULL) {
+ range_foreach(udp_ports_asn1, unregister_udp_port);
+ g_free(udp_ports_asn1);
+ }
+
+ if (sctp_ports_asn1 != NULL) {
+ range_foreach(sctp_ports_asn1, unregister_sctp_port);
+ g_free(sctp_ports_asn1);
+ }
+#endif /* JUST_ONE_PORT */
+ }
- if ( g_strcmp(asn1_filename, current_asn1) != 0) { /* new defintions, parse it */
+ if (strcmp(asn1_filename, current_asn1) != 0) {
+ /* new definitions, parse the file if we have one */
/* !!! should be postponed until we really need it !!! */
#ifdef READSYNTAX
read_asn1_type_table(asn1_filename);
g_free(current_asn1);
current_asn1 = g_strdup(asn1_filename);
}
- if (g_strcmp(asn1_pduname, current_pduname) != 0) { /* new PDU type, build tree for it */
+ if (!PDUtree || /* no tree built yet for PDU type */
+ strcmp(asn1_pduname, current_pduname) != 0) { /* new PDU type, build tree for it */
if (build_pdu_tree(asn1_pduname)) {
g_free(current_pduname);
current_pduname = g_strdup(asn1_pduname);
create_message_window();
}
#endif /* SHOWPDU */
+
+ /* If we now have a PDU tree, register for the port or ports we have */
+ if (PDUtree) {
+#ifdef JUST_ONE_PORT
+ tcp_port_asn1 = global_tcp_port_asn1;
+ udp_port_asn1 = global_udp_port_asn1;
+ sctp_port_asn1 = global_sctp_port_asn1;
+
+ register_tcp_port(tcp_port_asn1);
+ register_udp_port(udp_port_asn1);
+ register_sctp_port(sctp_port_asn1);
+#else
+ tcp_ports_asn1 = range_copy(global_tcp_ports_asn1);
+ udp_ports_asn1 = range_copy(global_udp_ports_asn1);
+ sctp_ports_asn1 = range_copy(global_sctp_ports_asn1);
+
+ range_foreach(tcp_ports_asn1, register_tcp_port);
+ range_foreach(udp_ports_asn1, register_udp_port);
+ range_foreach(sctp_ports_asn1, register_sctp_port);
+ }
+#endif /* JUST_ONE_PORT */
}
/* Start the functions we need for the plugin stuff */
#ifndef ENABLE_STATIC
G_MODULE_EXPORT void
-plugin_reg_handoff(void){
- proto_reg_handoff_asn1();
-}
-
-G_MODULE_EXPORT void
-plugin_init(plugin_address_table_t *pat
-#ifndef PLUGINS_NEED_ADDRESS_TABLE
-_U_
-#endif
-)
+plugin_register(void)
{
- /* initialise the table of pointers needed in Win32 DLLs */
- plugin_address_table_init(pat);
/* register the new protocol, protocol fields, and subtrees */
if (proto_asn1 == -1) { /* execute protocol initialization only once */
proto_register_asn1();
}
}
+G_MODULE_EXPORT void
+plugin_reg_handoff(void){
+ proto_reg_handoff_asn1();
+}
+
#endif
/* End the functions we need for plugin stuff */