aboutsummaryrefslogtreecommitdiffstats
path: root/plugins
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2004-07-30 07:28:31 +0000
committerGuy Harris <guy@alum.mit.edu>2004-07-30 07:28:31 +0000
commit0ee683e0b898df467b68274bd358f108234d1191 (patch)
tree03375ed90570e52c5959490157c302fed06381c9 /plugins
parent4b9d2228e395aeee1b8c414b278e4c22baada3a5 (diff)
From Matthijs Melchior:
add SCTP support; allow more than one port number to be specified; add recovery from garbled or incomplete ASN.1 messages. svn path=/trunk/; revision=11572
Diffstat (limited to 'plugins')
-rw-r--r--plugins/asn1/packet-asn1.c531
1 files changed, 455 insertions, 76 deletions
diff --git a/plugins/asn1/packet-asn1.c b/plugins/asn1/packet-asn1.c
index 41f01e2c8c..1628e19cec 100644
--- a/plugins/asn1/packet-asn1.c
+++ b/plugins/asn1/packet-asn1.c
@@ -90,7 +90,6 @@
#ifdef DISSECTOR_WITH_GUI
#include <gtk/gtk.h>
-#include "ui_util.h"
#endif
#include <ipproto.h>
@@ -110,6 +109,7 @@ G_MODULE_EXPORT const gchar version[] = VERSION;
#define TCP_PORT_ASN1 801
#define UDP_PORT_ASN1 801
+#define SCTP_PORT_ASN1 801
void proto_reg_handoff_asn1(void);
@@ -131,10 +131,22 @@ static int ett_seq[MAX_NEST];
* 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 char *global_tcp_ports_asn1 = NULL;
+static char *global_udp_ports_asn1 = NULL;
+static char *global_sctp_ports_asn1 = NULL;
+
+static GSList *tcp_ports_asn1 = 0;
+static GSList *udp_ports_asn1 = 0;
+static GSList *sctp_ports_asn1 = 0;
+#endif /* JUST_ONE_PORT */
static gboolean asn1_desegment = TRUE;
static char *asn1_filename = NULL;
@@ -356,6 +368,38 @@ char *tbl_types_ethereal_txt[] = {
/* 19 */ "FT_NONE", /* TBL_INVALID */
};
+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 */
+
/* description of PDU properties as passed from the matching routine
* to the decoder and GUI.
*/
@@ -563,6 +607,100 @@ g_strcmp(gconstpointer a, gconstpointer b)
return strcmp(a, b);
}
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+/* 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 */
+int checklength(int len, int def, int cls, int tag, char *lenstr, int strmax)
+{
+ int newlen = len;
+
+ if ( ! def) {
+ 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.... */
+ snprintf(lenstr, strmax, "%d(changed from %d)", newlen, len);
+ } else {
+ snprintf(lenstr, strmax, "%d", len);
+ }
+ return newlen;
+}
+
guint decode_asn1_sequence(tvbuff_t *tvb, guint offset, guint len, proto_tree *pt, int level);
void PDUreset(int count, int counr2);
@@ -575,7 +713,7 @@ dissect_asn1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
char tagstr[BUFLS];
char headstr[BUFLL];
char offstr[BUFLS];
- char *name;
+ char *name, *tname;
volatile guint boffset;
volatile int i = 0; /* PDU counter */
proto_tree * volatile ti = 0, * volatile ti2 = 0, *asn1_tree, *tree2;
@@ -625,17 +763,17 @@ dissect_asn1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
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 ",
+ 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],
@@ -650,9 +788,9 @@ dissect_asn1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
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 );
+ 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 );
@@ -675,6 +813,9 @@ dissect_asn1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
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;
@@ -687,16 +828,15 @@ dissect_asn1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
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",
@@ -710,13 +850,13 @@ dissect_asn1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
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,
@@ -731,11 +871,11 @@ dissect_asn1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
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);
@@ -749,7 +889,9 @@ dissect_asn1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
#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 */
@@ -845,11 +987,12 @@ decode_asn1_sequence(tvbuff_t *tvb, guint offset, guint tlen, proto_tree *pt, in
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);
} 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;
@@ -1600,7 +1743,7 @@ parse_tt3(tvbuff_t *tvb, guint offset, guint size, guint level, GNode *ptr)
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) {
@@ -1905,7 +2048,7 @@ get_asn1_oid(guint want_tag, guint offset)
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;
@@ -2574,7 +2717,8 @@ static char eol[] = "\r\n";
if (logf) {
fputs(message, logf);
fputs(eol, logf);
-}
+ fflush(logf); /* debugging ... */
+ }
}
void
@@ -2616,7 +2760,7 @@ read_asn1_type_table(char *filename)
data = g_malloc(size);
if (fread(data, size, 1, f) < 1) {
- report_read_failure(filename, errno);
+ g_warning("error reading %s, %s", filename, strerror(errno));
}
fclose(f);
@@ -2658,37 +2802,6 @@ read_asn1_type_table(char *filename)
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", \
@@ -2719,6 +2832,11 @@ tbl_typeref(guint n, GNode *pdu, GNode *tree, guint fullindex)
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);
@@ -2775,9 +2893,13 @@ tbl_typeref(guint n, GNode *pdu, GNode *tree, guint fullindex)
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);
@@ -2882,7 +3004,7 @@ tbl_type(guint n, GNode *pdu, GNode *list, guint fullindex) /* indent, pdu, sour
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;
}
@@ -2892,8 +3014,8 @@ tbl_type(guint n, GNode *pdu, GNode *list, guint fullindex) /* indent, pdu, sour
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);
@@ -2902,7 +3024,11 @@ tbl_type(guint n, GNode *pdu, GNode *list, guint fullindex) /* indent, pdu, sour
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));
@@ -2925,7 +3051,7 @@ tbl_type(guint n, GNode *pdu, GNode *list, guint fullindex) /* indent, pdu, sour
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 */
@@ -3016,6 +3142,7 @@ tbl_type(guint n, GNode *pdu, GNode *list, guint fullindex) /* indent, pdu, sour
case TBL_SETOF:
case TBL_CHOICE:
CHECKTYPE(q, TBLTYPE_Tag);
+ q = g_node_first_child(list);
tbl_type(n+1, pdu, q, ni);
break;
@@ -3687,9 +3814,12 @@ create_message_window()
FALSE, FALSE, 0);
g_free(text);
- sw = scrolled_window_new(NULL, NULL);
+ sw = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw),
- GTK_SHADOW_IN);
+ GTK_SHADOW_ETCHED_IN);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
+ GTK_POLICY_AUTOMATIC,
+ GTK_POLICY_AUTOMATIC);
gtk_box_pack_start (GTK_BOX (vbox), sw, TRUE, TRUE, 0);
model = gtk_tree_store_new(N_COLUMNS, G_TYPE_STRING, G_TYPE_INT, G_TYPE_INT,
@@ -3978,7 +4108,7 @@ PDUreset(int count, int count2)
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);
@@ -4633,6 +4763,142 @@ getPDUenum(PDUprops *props, guint offset, guint cls, guint tag, guint value)
#endif /* READSYNTAX */
+/* * * * * * * * * * * * * * * * * * * * * * * * */
+/* Routines to handle parsing a list of ports */
+/* * * * * * * * * * * * * * * * * * * * * * * * */
+
+#define SKIPWHITE(_s) { while(isspace(*(_s))) { (_s)++; } }
+
+/* insert error text in front of spec
+ * with a delimeter we can recognize on next attempt
+ */
+void insert_error(gchar *s, int len, gchar *err, guint mark)
+{
+ gchar *news;
+ guint slen;
+
+ news = malloc(len);
+ slen = strlen(s);
+
+ mark = (mark < slen) ? mark : slen; /* clamp mark within the string */
+
+ snprintf(news, len, "[%s] %.*s|%s", err, (int)mark, s, s + mark);
+ strncpy(s, news, len);
+ free(news);
+}
+
+/* parse a range of port numbers: a,b-c,d
+ */
+GSList *parse_port_range(gchar *s, int len)
+{
+ GSList *list = NULL;
+ guint n, count, fill, fillstart = 0;
+ gchar *es, *orgs;
+
+ count = fill = 0;
+
+ if (s == 0) return 0;
+
+ orgs = es = s;
+
+ SKIPWHITE(es);
+ if (*es == '[') { /* an old error message */
+ while(*es != ']') { es++; };
+ es++;
+ SKIPWHITE(es);
+ }
+ memmove(orgs, es, strlen(es)+1); /* remove old error message */
+
+ es = orgs;
+
+ while(1) {
+ s = es;
+ SKIPWHITE(s); /* for better position of error indicator */
+ n = strtoul(s, &es, 0);
+ if ( (s == es) || /* no character processed */
+ (n > 0xffff) ) { /* port number out of range */
+ /* syntax error */
+ if (s == es) es++; /* err indicator after error pos */
+ insert_error(orgs, len, "syntax error", es - orgs);
+ g_slist_free (list);
+ return 0;
+ } else { /* OK, have a port number */
+ if (fill) { /* create a range of numbers */
+ fill = 0;
+ while(++fillstart < n) {
+ list = g_slist_append (list, GINT_TO_POINTER (fillstart));
+ count++;
+ if (count > 100) {
+ insert_error(orgs, len, "too many ports", es - orgs);
+ g_slist_free (list);
+ return 0;
+ }
+ }
+ }
+ list = g_slist_append (list, GINT_TO_POINTER (n));
+ count++;
+
+ SKIPWHITE(es);
+
+ if (isdigit(*es))
+ continue; /* a missig comma is OK */
+
+ switch(*es++) {
+ case ',': /* on to the next port number */
+ continue;
+ case '-': /* start a port range */
+ fill = 1;
+ fillstart = n;
+ continue;
+ case '\0': /* OK, finished */
+ break;
+ default: /* some error */
+ insert_error(orgs, len, "invalid character", es - orgs);
+ g_slist_free (list);
+ return 0;
+ }
+ break;
+ }
+ }
+ return list;
+}
+
+/* build text representation of given port list
+ */
+void show_port_range(GSList *list, gchar *buf, int len)
+{
+ gchar delim = 0;
+ int this, last, size;
+
+ last = -2;
+ size = 0;
+ while(list) {
+ this = GPOINTER_TO_INT(list->data);
+ if ((last+1) == this) {
+ delim = '-';
+ last++;
+ } else {
+ if (delim == '-') {
+ size += snprintf(&buf[size], len - size, "%c%d", delim, last);
+ delim = ',';
+ }
+ if (delim)
+ buf[size++] = delim;
+ size += snprintf(&buf[size], len - size, "%d", this);
+ delim = ',';
+ last = this;
+ }
+ list = g_slist_next(list);
+
+ }
+
+ if (delim == '-')
+ size += snprintf(&buf[size], len - size, "%c%d", delim, last);
+}
+
+/* end of port list management routines */
+
+
void
proto_register_asn1(void) {
@@ -4652,6 +4918,8 @@ proto_register_asn1(void) {
static gint *ett[1+MAX_NEST+MAXPDU];
+ char tmpstr[64];
+
module_t *asn1_module;
int i, j;
@@ -4677,16 +4945,49 @@ proto_register_asn1(void) {
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
+ snprintf(tmpstr, sizeof(tmpstr), "%d", TCP_PORT_ASN1);
+ global_tcp_ports_asn1 = strdup(tmpstr);
+
+ snprintf(tmpstr, sizeof(tmpstr), "%d", UDP_PORT_ASN1);
+ global_udp_ports_asn1 = strdup(tmpstr);
+
+ snprintf(tmpstr, sizeof(tmpstr), "%d", SCTP_PORT_ASN1);
+ global_sctp_ports_asn1 = strdup(tmpstr);
+
+ prefs_register_string_preference(asn1_module, "tcp_ports",
+ "ASN.1 TCP Ports",
+ "The TCP ports on which "
+ "ASN.1 messages will be read",
+ &global_tcp_ports_asn1);
+ prefs_register_string_preference(asn1_module, "udp_ports",
+ "ASN.1 UDP Ports",
+ "The UDP ports on which "
+ "ASN.1 messages will be read",
+ &global_udp_ports_asn1);
+ prefs_register_string_preference(asn1_module, "sctp_ports",
+ "ASN.1 SCTP Ports",
+ "The SCTP ports on which "
+ "ASN.1 messages will be read",
+ &global_sctp_ports_asn1);
+#endif /* JUST_ONE_PORT */
+
prefs_register_bool_preference(asn1_module, "desegment_messages",
"Desegment TCP",
"Desegment ASN.1 messages that span TCP segments",
@@ -4723,11 +5024,12 @@ proto_register_asn1(void) {
"ASN.1 debug mode",
"Extra output useful for debuging",
&asn1_debug);
-
+/*
prefs_register_bool_preference(asn1_module, "message_win",
"Show ASN.1 tree",
"show full message description",
&asn1_message_win);
+*/
prefs_register_bool_preference(asn1_module, "verbose_log",
"Write very verbose log",
"log to file $TMP/" ASN1LOGFILE,
@@ -4740,27 +5042,104 @@ void
proto_reg_handoff_asn1(void) {
static int asn1_initialized = FALSE;
static dissector_handle_t asn1_handle;
+ GSList *list;
+ gint len;
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=%d, udpport=%d, sctpport=%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, global_sctp_port_asn1, asn1_desegment,
+ asn1_filename, asn1_pduname, first_pdu_offset, asn1_debug, asn1_message_win, asn1_verbose);
+#else
+ if (asn1_verbose) 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",
+ global_tcp_ports_asn1, global_udp_ports_asn1, global_sctp_ports_asn1, 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 {
+ } else { /* clean up ports and their lists */
+#ifdef JUST_ONE_PORT
dissector_delete("tcp.port", tcp_port_asn1, asn1_handle);
dissector_delete("udp.port", udp_port_asn1, asn1_handle);
+ dissector_delete("sctp.port", sctp_port_asn1, asn1_handle);
+#else
+ list = tcp_ports_asn1;
+ while (list) {
+ dissector_delete("tcp.port", GPOINTER_TO_INT(list->data), asn1_handle);
+ list = g_slist_next(list);
+ }
+ g_slist_free(tcp_ports_asn1);
+
+ list = udp_ports_asn1;
+ while (list) {
+ dissector_delete("udp.port", GPOINTER_TO_INT(list->data), asn1_handle);
+ list = g_slist_next(list);
+ }
+ g_slist_free(udp_ports_asn1);
+
+ list = sctp_ports_asn1;
+ while (list) {
+ dissector_delete("sctp.port", GPOINTER_TO_INT(list->data), asn1_handle);
+ list = g_slist_next(list);
+ }
+ g_slist_free(sctp_ports_asn1);
+#endif /* JUST_ONE_PORT */
}
+#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;
+
dissector_add("tcp.port", global_tcp_port_asn1, asn1_handle);
dissector_add("udp.port", global_udp_port_asn1, asn1_handle);
+ dissector_add("sctp.port", global_sctp_port_asn1, asn1_handle);
+#else
+ len = strlen(global_tcp_ports_asn1) + 32; /* extra for possible error message */
+ global_tcp_ports_asn1 = realloc(global_tcp_ports_asn1, len);
+ tcp_ports_asn1 = parse_port_range(global_tcp_ports_asn1, len);
+ if (tcp_ports_asn1) /* no error, normalize presentation */
+ show_port_range(tcp_ports_asn1, global_tcp_ports_asn1, len);
+ else
+ g_message("tcp_ports: %s\n", global_tcp_ports_asn1);
+
+ len = strlen(global_udp_ports_asn1) + 32; /* extra for possible error message */
+ global_udp_ports_asn1 = realloc(global_udp_ports_asn1, len);
+ udp_ports_asn1 = parse_port_range(global_udp_ports_asn1, len);
+ if (udp_ports_asn1) /* no error, normalize presentation */
+ show_port_range(udp_ports_asn1, global_udp_ports_asn1, len);
+ else
+ g_message("udp_ports: %s\n", global_udp_ports_asn1);
+
+ len = strlen(global_sctp_ports_asn1) + 32; /* extra for possible error message */
+ global_sctp_ports_asn1 = realloc(global_sctp_ports_asn1, len);
+ sctp_ports_asn1 = parse_port_range(global_sctp_ports_asn1, len);
+ if (sctp_ports_asn1) /* no error, normalize presentation */
+ show_port_range(sctp_ports_asn1, global_sctp_ports_asn1, len);
+ else
+ g_message("sctp_ports: %s\n", global_sctp_ports_asn1);
+
+ list = tcp_ports_asn1;
+ while (list) {
+ dissector_add("tcp.port", GPOINTER_TO_INT(list->data), asn1_handle);
+ list = g_slist_next(list);
+ }
+ list = udp_ports_asn1;
+ while (list) {
+ dissector_add("udp.port", GPOINTER_TO_INT(list->data), asn1_handle);
+ list = g_slist_next(list);
+ }
+ list = sctp_ports_asn1;
+ while (list) {
+ dissector_add("sctp.port", GPOINTER_TO_INT(list->data), asn1_handle);
+ list = g_slist_next(list);
+ }
+#endif /* JUST_ONE_PORT */
if ( g_strcmp(asn1_filename, current_asn1) != 0) { /* new defintions, parse it */
/* !!! should be postponed until we really need it !!! */