Use <wiretap/file_util.h> to include "file_util.h"; otherwise, the
[obnox/wireshark/wip.git] / plugins / asn1 / packet-asn1.c
index 9f78479d526fe849a9df9319ac7dc18ea1d08f11..f38f6bbc662ad6b91fec7487ddf5565c779b5a73 100644 (file)
@@ -67,8 +67,6 @@
 #include <sys/stat.h>
 #include <errno.h>
 
-#include "plugins/plugin_api.h"
-
 #include "moduleinfo.h"
 
 #include <stdio.h>
@@ -84,9 +82,8 @@
 #include <epan/filesystem.h>
 #include <epan/report_err.h>
 #include <epan/dissectors/packet-tcp.h>
-#include "asn1.h"
-
-#include "plugins/plugin_api_defs.h"
+#include <epan/asn1.h>
+#include <wiretap/file_util.h>
 
 #ifdef DISSECTOR_WITH_GUI
 #include <gtk/gtk.h>
@@ -139,17 +136,17 @@ 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 range_t *global_tcp_ports_asn1;
+static range_t *global_udp_ports_asn1;
+static range_t *global_sctp_ports_asn1;
 
-static GSList *tcp_ports_asn1 = 0;
-static GSList *udp_ports_asn1 = 0;
-static GSList *sctp_ports_asn1 = 0;
+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 = NULL;
+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
@@ -157,7 +154,7 @@ static char *old_default_asn1_filename = NULL;
 static char *bad_separator_old_default_asn1_filename = NULL;
 #endif
 static char *current_asn1 = NULL;
-static char *asn1_pduname = NULL;
+static const char *asn1_pduname = NULL;
 static char *current_pduname = NULL;
 static gboolean asn1_debug = FALSE;
 static guint first_pdu_offset = 0;
@@ -194,13 +191,13 @@ static guint pabbrev_pdu_len;             /* length initial part of fieldname with 'abbrev.
 #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 */
 
-static char tag_class[] = "UACPX";
+static const char tag_class[] = "UACPX";
 
-static char *asn1_cls[] = { "Universal", "Application", "Context", "Private" };
+static const char *asn1_cls[] = { "Universal", "Application", "Context", "Private" };
 
-static char *asn1_con[] = { "Primitive", "Constructed" };
+static const char *asn1_con[] = { "Primitive", "Constructed" };
 
-static char *asn1_tag[] = {
+static const char *asn1_tag[] = {
        /*  0 */ "EOC",             "Boolean",        "Integer",          "BitString",
        /*  4 */ "OctetString",     "Null",           "ObjectIdentifier", "ObjectDescriptor",
        /*  8 */ "External",        "Real",           "Enumerated",       "tag11",
@@ -270,7 +267,7 @@ static int asn1_uni_type[] = {
 #define TBLTYPE(x) (tbl_types[x&TBL_TYPEmask])
 
 /* text tables for debugging and GUI */
-static char *tbl_types[] = {
+static const char *tbl_types[] = {
                       /*  0 */ "tbl-boolean",
                       /*  1 */ "tbl-integer",
                       /*  2 */ "tbl-bitstring",
@@ -294,7 +291,7 @@ static char *tbl_types[] = {
 
                       /* 19 */ "tbl-invalid",
 };
-static char *tbl_types_asn1[] = {
+static const char *tbl_types_asn1[] = {
                       /*  0 */ "BOOLEAN",
                       /*  1 */ "INTEGER",
                       /*  2 */ "BITSTRING",
@@ -344,7 +341,7 @@ static guint tbl_types_ethereal[] = {
                       /* 19 */ FT_NONE,        /* TBL_INVALID */               
 };
 
-static 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 */
@@ -372,9 +369,9 @@ static char *tbl_types_ethereal_txt[] = {
 typedef struct _PDUinfo PDUinfo;
 struct _PDUinfo {
        guint type;
-       char *name;
-       char *typename;
-       char *fullname;
+       const char *name;
+       const char *typename;
+       const char *fullname;
        guchar tclass;
        guint tag;
        guint flags;
@@ -407,9 +404,9 @@ static guint PDUinfo_initflags = 0; /* default flags for newly allocated PDUinfo
 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;
@@ -424,9 +421,9 @@ struct _PDUprops {
 #define OUT_FLAG_constructed 0x20
 
 static PDUprops *getPDUprops(PDUprops *out, guint offset, guint class, guint tag, guint cons);
-static char *getPDUenum(PDUprops *props, guint offset, guint cls, guint tag, guint value);
+static const char *getPDUenum(PDUprops *props, guint offset, guint cls, guint tag, guint value);
 
-static 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 */
 
 
@@ -487,7 +484,7 @@ get_context(guint level)
 /* Convert a bit string to an ascii representation for printing
  * -- not thread safe ...
  */
-static char *showbits(guchar *val, guint count)
+static const char *showbits(guchar *val, guint count)
 {
        static char str[BUFLM];
        guint i;
@@ -507,7 +504,7 @@ static char *showbits(guchar *val, guint count)
 }
 
 /* get bitnames string for bits set */
-static char *
+static const char *
 showbitnames(guchar *val, guint count, PDUprops *props, guint offset)
 {
        static char str[BUFLL];
@@ -561,7 +558,7 @@ showoctets(guchar *octets, guint len, guint hexlen) /* if len <= hexlen, always
        guint dohex = 0;
        guint i;
        char *str, *p;
-       char *endstr = empty;
+       const char *endstr = empty;
 
        if (len == 0) {
                str = g_malloc(1);
@@ -628,7 +625,7 @@ checklength(int len, int def, int cls, int tag, char *lenstr, int strmax)
        int newlen = len;
 
        if ( ! def) {
-               snprintf(lenstr, strmax, "indefinite");
+               g_snprintf(lenstr, strmax, "indefinite");
                return len;
        }
 
@@ -698,9 +695,9 @@ checklength(int len, int def, int cls, int tag, char *lenstr, int strmax)
 
        if (newlen != len) {
                /* a change was needed.... */
-               snprintf(lenstr, strmax, "%d(changed from %d)", newlen, len);
+               g_snprintf(lenstr, strmax, "%d(changed from %d)", newlen, len);
        } else {
-               snprintf(lenstr, strmax, "%d", len);
+               g_snprintf(lenstr, strmax, "%d", len);
        }
        return newlen;
 }
@@ -717,7 +714,7 @@ dissect_asn1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
   char tagstr[BUFLS];
   char headstr[BUFLL];
   char offstr[BUFLS];
-  char *name, *tname;
+  const char *name, *tname;
   volatile guint boffset;
   volatile int i = 0;          /* PDU counter */
   proto_tree * volatile ti = 0, * volatile ti2 = 0, *asn1_tree, *tree2;
@@ -754,7 +751,7 @@ dissect_asn1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
   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 */
@@ -773,9 +770,9 @@ dissect_asn1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
 
   if (asn1_debug) {
 
-         snprintf(tagstr, sizeof(tagstr), "%ctag%d", tag_class[cls], tag);
+         g_snprintf(tagstr, sizeof(tagstr), "%ctag%d", tag_class[cls], tag);
 
-         snprintf(headstr, sizeof(headstr), "first%s: (%s)%s %d %s, %s, %s, len=%s, off=%d, size=%d ",
+         g_snprintf(headstr, sizeof(headstr), "first%s: (%s)%s %d %s, %s, %s, len=%s, off=%d, size=%d ",
                   offstr,
                   tname,
                   name,   
@@ -789,10 +786,10 @@ dissect_asn1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
                  );
   } 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)%s ", offstr, tname, name );
+         g_snprintf(headstr, sizeof(headstr), "first pdu%s: (%s)%s ", offstr, tname, name );
   }
 
   /* Set the info column */
@@ -841,9 +838,9 @@ dissect_asn1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
 
            if (asn1_debug) {
 
-                   snprintf(tagstr, sizeof(tagstr), "%ctag%d", tag_class[cls], tag);
+                   g_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(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,
@@ -869,7 +866,7 @@ dissect_asn1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
                    }
            } 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)
@@ -942,7 +939,7 @@ decode_asn1_sequence(tvbuff_t *tvb, guint offset, guint tlen, proto_tree *pt, in
   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];
@@ -956,7 +953,8 @@ decode_asn1_sequence(tvbuff_t *tvb, guint offset, guint tlen, proto_tree *pt, in
   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 */
@@ -988,14 +986,14 @@ decode_asn1_sequence(tvbuff_t *tvb, guint offset, guint tlen, proto_tree *pt, in
          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(nnbuf, sizeof(nnbuf), "NN%d", len);
+                 g_snprintf(nnbuf, sizeof(nnbuf), "NN%d", len);
          } else {
                  strncpy(nnbuf, "NN-", sizeof(nnbuf));
                                /* make sure we get an exception if we run off the end! */
@@ -1717,7 +1715,7 @@ parse_tt3(tvbuff_t *tvb, guint offset, guint size, guint level, GNode *ptr)
        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;
@@ -1740,11 +1738,11 @@ parse_tt3(tvbuff_t *tvb, guint offset, guint size, guint level, GNode *ptr)
                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);
@@ -1820,7 +1818,7 @@ parse_tt3(tvbuff_t *tvb, guint offset, guint size, guint level, GNode *ptr)
 
                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 */
@@ -1866,11 +1864,11 @@ myLeaf(GNode *node, gpointer data)
        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));
        }
@@ -1931,7 +1929,7 @@ enum _tbl_t {
 };
 typedef enum _tbl_t tbl_t;
 /* text for 'tbl_t' type for debugging */
-static char *data_types[] = {
+static const char *data_types[] = {
                        "Module",
                        "TypeDef",
                        "Tag",
@@ -2372,7 +2370,7 @@ define_module(GNode *p, GNode *q)
 
 typedef struct _SearchDef SearchDef;
 struct _SearchDef {
-       char *key;
+       const char *key;
        GNode *here;
 };
 
@@ -2510,7 +2508,8 @@ get_values(void)          /* collect values from ASN.1 tree */
        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");
@@ -2629,7 +2628,7 @@ showGNode(GNode *p, int n)
                        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 */
@@ -2640,7 +2639,7 @@ showGNode(GNode *p, int n)
                        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,
@@ -2661,7 +2660,7 @@ showGNode(GNode *p, int n)
                        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,
@@ -2731,7 +2730,7 @@ static char eol[] = "\r\n";
        (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);
@@ -2741,7 +2740,7 @@ static char eol[] = "\r\n";
 }
 
 static void
-read_asn1_type_table(char *filename)
+read_asn1_type_table(const char *filename)
 {
        FILE *f;
        guint size;
@@ -2751,7 +2750,7 @@ read_asn1_type_table(char *filename)
        if ((filename == 0) || (strlen(filename) == 0))
                return;         /* no filename provided */
 
-       f = fopen(filename, "rb");
+       f = eth_fopen(filename, "rb");
        if (f == 0) {
                /*
                 * Ignore "file not found" errors if it's the old default
@@ -2909,7 +2908,7 @@ tbl_typeref(guint n, GNode *pdu, GNode *tree, guint fullindex)
 
                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) {
@@ -3261,7 +3260,7 @@ 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);
@@ -3334,7 +3333,7 @@ showPDUtree(GNode *p, int n)
 }
 
 static gboolean
-build_pdu_tree(char *pduname)
+build_pdu_tree(const char *pduname)
 {
        SearchDef sd;
        guint pdudef, i, tcount;
@@ -3860,7 +3859,7 @@ create_message_window(void)
        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;
@@ -3974,7 +3973,7 @@ static struct _statestack {
        GNode *node;
        guint type;
        guint offset;
-       char *name;
+       const char *name;
 } PDUstate[1024];
 static gint PDUstatec = 0;
 
@@ -4004,8 +4003,9 @@ static gint PDUstatec = 0;
 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;
@@ -4070,7 +4070,7 @@ showstack(statestack *pos, char *txt, int n)
 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;
@@ -4099,7 +4099,7 @@ showrefNode(GNode *node, int n)
 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)
@@ -4198,7 +4198,7 @@ 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];
@@ -4754,12 +4754,12 @@ getPDUprops(PDUprops *out, guint offset, guint class, guint tag, guint cons)
        return out;
 }
 
-static 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 */
@@ -4798,142 +4798,6 @@ 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((guchar)*(_s))) { (_s)++; } }
-
-/* insert error text in front of spec
- * with a delimeter we can recognize on next attempt
- */
-static 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
- */
-static 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((guchar)*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
- */
-static 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) {
 
@@ -5000,30 +4864,30 @@ proto_register_asn1(void) {
                                 "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);
+  g_snprintf(tmpstr, sizeof(tmpstr), "%u", TCP_PORT_ASN1);
+  range_convert_str(&global_tcp_ports_asn1, tmpstr, 65535);
   
-  snprintf(tmpstr, sizeof(tmpstr), "%d", UDP_PORT_ASN1);
-  global_udp_ports_asn1 = strdup(tmpstr);
+  g_snprintf(tmpstr, sizeof(tmpstr), "%u", UDP_PORT_ASN1);
+  range_convert_str(&global_udp_ports_asn1, tmpstr, 65535);
   
-  snprintf(tmpstr, sizeof(tmpstr), "%d", SCTP_PORT_ASN1);
-  global_sctp_ports_asn1 = strdup(tmpstr);
+  g_snprintf(tmpstr, sizeof(tmpstr), "%u", SCTP_PORT_ASN1);
+  range_convert_str(&global_sctp_ports_asn1, tmpstr, 65535);
   
-  prefs_register_string_preference(asn1_module, "tcp_ports",
+  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);
-  prefs_register_string_preference(asn1_module, "udp_ports",
+                                &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);
-  prefs_register_string_preference(asn1_module, "sctp_ports",
+                                &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);
+                                &global_sctp_ports_asn1, 65535);
 #endif /* JUST_ONE_PORT */
 
   prefs_register_bool_preference(asn1_module, "desegment_messages",
@@ -5078,25 +4942,68 @@ proto_register_asn1(void) {
 
 /* 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;
-  GSList *list;
-  gint len;
+#ifndef JUST_ONE_PORT
+  char *tcp_ports_asn1_string, *udp_ports_asn1_string, *sctp_ports_asn1_string;
+#endif
 
   pcount = 0;
 
 #ifdef JUST_ONE_PORT
-  if (asn1_verbose) g_message("prefs change: tcpport=%d, udpport=%d, sctpport=%d, desegnment=%d, "
+  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) g_message("prefs change: tcpports=%s, udpports=%s, sctpports=%s, desegnment=%d, "
+  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",
-         global_tcp_ports_asn1, global_udp_ports_asn1, global_sctp_ports_asn1, asn1_desegment,
+         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) {
@@ -5104,30 +5011,24 @@ proto_reg_handoff_asn1(void) {
     asn1_initialized = TRUE;
   } 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);
+    unregister_tcp_port(tcp_port_asn1);
+    unregister_udp_port(udp_port_asn1);
+    unregister_sctp_port(sctp_port_asn1);
 #else
-    list = tcp_ports_asn1;
-    while (list) {
-           dissector_delete("tcp.port", GPOINTER_TO_INT(list->data), asn1_handle);
-           list = g_slist_next(list);
+    if (tcp_ports_asn1 != NULL) {
+      range_foreach(tcp_ports_asn1, unregister_tcp_port);
+      g_free(tcp_ports_asn1);
     }
-    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);
+    if (udp_ports_asn1 != NULL) {
+      range_foreach(udp_ports_asn1, unregister_udp_port);
+      g_free(udp_ports_asn1);
     }
-    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);
+    if (sctp_ports_asn1 != NULL) {
+      range_foreach(sctp_ports_asn1, unregister_sctp_port);
+      g_free(sctp_ports_asn1);
     }
-    g_slist_free(sctp_ports_asn1);
 #endif /* JUST_ONE_PORT */
   }
 
@@ -5164,49 +5065,17 @@ proto_reg_handoff_asn1(void) {
     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);
+    register_tcp_port(tcp_port_asn1);
+    register_udp_port(udp_port_asn1);
+    register_sctp_port(sctp_port_asn1);
 #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);
+    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);
 
-    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);
-    }
+    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 */
 }
@@ -5216,25 +5085,19 @@ proto_reg_handoff_asn1(void) {
 #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 */