/* oids.c
* Object IDentifier Support
*
- * (c) 2007, Luis E. Garcia Ontanon <luis.ontanon@gmail.com>
+ * (c) 2007, Luis E. Garcia Ontanon <luis@ontanon.org>
*
* $Id$
*
static const oid_value_type_t bytes_type = { FT_BYTES, BASE_NONE, BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, 0, -1, OID_KEY_TYPE_BYTES, 0};
static const oid_value_type_t oid_type = { FT_OID, BASE_NONE, BER_CLASS_UNI, BER_UNI_TAG_OID, 1, -1, OID_KEY_TYPE_OID, 0};
static const oid_value_type_t ipv4_type = { FT_IPv4, BASE_NONE, BER_CLASS_APP, 0, 4, 4, OID_KEY_TYPE_IPADDR, 4};
-static const oid_value_type_t counter32_type = { FT_UINT32, BASE_DEC, BER_CLASS_APP, 1, 1, 4, OID_KEY_TYPE_INTEGER, 1};
+static const oid_value_type_t counter32_type = { FT_UINT64, BASE_DEC, BER_CLASS_APP, 1, 1, 5, OID_KEY_TYPE_INTEGER, 1};
static const oid_value_type_t unsigned32_type = { FT_UINT32, BASE_DEC, BER_CLASS_APP, 2, 1, 4, OID_KEY_TYPE_INTEGER, 1};
-static const oid_value_type_t timeticks_type = { FT_UINT32, BASE_DEC, BER_CLASS_APP, 3, 1, 4, OID_KEY_TYPE_INTEGER, 1};
+/*static const oid_value_type_t timeticks_type = { FT_UINT32, BASE_DEC, BER_CLASS_APP, 3, 1, 4, OID_KEY_TYPE_INTEGER, 1};
+ * TimeTicks ::= [APPLICATION 3] IMPLICIT INTEGER (0..4294967295)
+ * If the BER encoding should not have the top bit set as to not become a negative number
+ * the ber encoding may take 5 octets to encode.
+ */
+static const oid_value_type_t timeticks_type = { FT_UINT64, BASE_DEC, BER_CLASS_APP, 3, 1, 5, OID_KEY_TYPE_INTEGER, 1};
static const oid_value_type_t opaque_type = { FT_BYTES, BASE_NONE, BER_CLASS_APP, 4, 1, 4, OID_KEY_TYPE_BYTES, 0};
static const oid_value_type_t nsap_type = { FT_BYTES, BASE_NONE, BER_CLASS_APP, 5, 0, -1, OID_KEY_TYPE_NSAP, 0};
static const oid_value_type_t counter64_type = { FT_UINT64, BASE_DEC, BER_CLASS_APP, 6, 1, 8, OID_KEY_TYPE_INTEGER, 1};
static const oid_value_type_t ipv6_type = { FT_IPv6, BASE_NONE, BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, 16, 16, OID_KEY_TYPE_BYTES, 16};
static const oid_value_type_t float_type = { FT_FLOAT, BASE_DEC, BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, 4, 4, OID_KEY_TYPE_WRONG, 0};
static const oid_value_type_t double_type = { FT_DOUBLE, BASE_DEC, BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, 8, 8, OID_KEY_TYPE_WRONG, 0};
-static const oid_value_type_t ether_type = { FT_ETHER, BASE_NONE, BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, 6, 6, OID_KEY_TYPE_BYTES, 6};
+static const oid_value_type_t ether_type = { FT_ETHER, BASE_NONE, BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, 6, 6, OID_KEY_TYPE_ETHER, 6};
static const oid_value_type_t string_type = { FT_STRING, BASE_NONE, BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, 0, -1, OID_KEY_TYPE_STRING, 0};
static const oid_value_type_t unknown_type = { FT_BYTES, BASE_NONE, BER_CLASS_ANY, BER_TAG_ANY, 0, -1, OID_KEY_TYPE_WRONG, 0};
}
#ifdef HAVE_LIBSMI
+/* de-allocate storage mallocated by libsmi */
+/* */
+/* XXX: libsmi provides access to smiFree as of libsmi v 0.4.8. */
+/* On Windows: Wireshark 1.01 and later is built and distributed */
+/* with libsmi 0.4.8 (or newer). */
+/* On non-Windows systems, free() should be OK for libsmi */
+/* versions older than 0.4.8. */
+
+static void smi_free(void *ptr) {
+
+#if (SMI_VERSION_MAJOR >= 0) && (SMI_VERSION_MINOR >= 4) && (SMI_VERSION_PATCHLEVEL >= 8)
+ smiFree(ptr);
+#else
+ #ifdef _WIN32
+ #error Invalid Windows libsmi version ?? !!
+ #endif
+#define xx_free free /* hack so checkAPIs.pl doesn't complain */
+ xx_free(ptr);
+#endif
+}
+
+
typedef struct smi_module_t {
char* name;
} smi_module_t;
UAT_CSTRING_CB_DEF(smi_mod,name,smi_module_t)
static void smi_error_handler(char *path, int line, int severity, char *msg, char *tag) {
- g_string_sprintfa(smi_errors,"%s:%d %d %s %s\n",
+ g_string_append_printf(smi_errors,"%s:%d %d %s %s\n",
path ? path : "-",
line, severity,
tag ? tag : "-",
static void smi_mod_free_cb(void* p) {
smi_module_t* m = p;
- if (m->name) g_free(m->name);
+ g_free(m->name);
}
return s;
}
-const oid_value_type_t* get_typedata(SmiType* smiType) {
+static const oid_value_type_t* get_typedata(SmiType* smiType) {
/*
* There has to be a better way to know if a given
* OCTETSTRING type is actually human readable text,
{"MacAddress",SMI_BASETYPE_UNKNOWN,ðer_type},
{"TimeTicks",SMI_BASETYPE_UNKNOWN,&timeticks_type},
{"Ipv6Address",SMI_BASETYPE_UNKNOWN,&ipv6_type},
- {"TimeStamp",SMI_BASETYPE_UNKNOWN,&integer_type},
+ {"TimeStamp",SMI_BASETYPE_UNKNOWN,&timeticks_type},
{"DisplayString",SMI_BASETYPE_UNKNOWN,&string_type},
{"SnmpAdminString",SMI_BASETYPE_UNKNOWN,&string_type},
{"DateAndTime",SMI_BASETYPE_UNKNOWN,&string_type},
for (t = types; t->type ; t++ ) {
char* name = smiRenderType(sT, SMI_RENDER_NAME);
if (name && t->name && g_str_equal(name, t->name )) {
-#ifndef WIN32
- free (name);
-#endif
+ smi_free(name);
return t->type;
}
-#ifndef WIN32
if (name) {
- free (name);
+ smi_free (name);
}
-#endif
}
} while(( sT = smiGetParentType(sT) ));
oid1 = smiRenderOID(sN->oidlen, sN->oid, SMI_RENDER_QUALIFIED);
oid2 = smiRenderOID(elNode->oidlen, elNode->oid, SMI_RENDER_NAME);
k->name = g_strdup_printf("%s.%s", oid1, oid2);
-#ifndef WIN32
- free (oid1);
- free (oid2);
-#endif
+ smi_free (oid1);
+ smi_free (oid2);
k->hfid = -2;
k->ft_type = typedata ? typedata->ft_type : FT_BYTES;
kl = k;
}
- if (implied) {
+ if (implied && kl) {
switch (kl->key_type) {
case OID_KEY_TYPE_BYTES: kl->key_type = OID_KEY_TYPE_IMPLIED_BYTES; break;
case OID_KEY_TYPE_STRING: kl->key_type = OID_KEY_TYPE_IMPLIED_STRING; break;
|| (ft == FT_INT8) || (ft == FT_INT16) || (ft == FT_INT24) || (ft == FT_INT32) \
|| (ft == FT_UINT64) || (ft == FT_INT64) )
-void register_mibs(void) {
+static void register_mibs(void) {
SmiModule *smiModule;
SmiNode *smiNode;
guint i;
GArray* hfa = g_array_new(FALSE,TRUE,sizeof(hf_register_info));
GArray* etta = g_array_new(FALSE,TRUE,sizeof(gint*));
static uat_field_t smi_fields[] = {
- UAT_FLD_CSTRING(smi_mod,name,"The module's name"),
+ UAT_FLD_CSTRING(smi_mod,name,"Module name","The module's name"),
UAT_END_FIELDS
};
static uat_field_t smi_paths_fields[] = {
- UAT_FLD_CSTRING(smi_mod,name,"The directory name"),
+ UAT_FLD_PATHNAME(smi_mod,name,"Directory path","The directory name"),
UAT_END_FIELDS
};
char* smi_load_error = NULL;
return;
}
+ smi_errors = g_string_new("");
+ smiSetErrorHandler(smi_error_handler);
+
path_str = oid_get_default_mib_path();
D(1,("SMI Path: '%s'",path_str));
smiSetPath(path_str);
-
-
- smi_errors = g_string_new("");
- smiSetErrorHandler(smi_error_handler);
-
for(i=0;i<num_smi_modules;i++) {
if (!smi_modules[i].name) continue;
-
if (smiIsLoaded(smi_modules[i].name)) {
continue;
} else {
if (smi_errors->len) {
report_failure("The following errors were found while loading the MIBS:\n%s\n\n"
- "The Current Path is: %s\n" , smi_errors->str , path_str);
+ "The Current Path is: %s\n\nYou can avoid this error message "
+ "by removing the missing MIB modules at Edit -> Preferences"
+ " -> Name Resolution -> SMI (MIB and PIB) modules or by "
+ "installing them.\n" , smi_errors->str , path_str);
D(1,("Errors while loading:\n%s\n",smi_errors->str));
}
D(3,("\tModule: %s", smiModule->name));
+ /* TODO: Check libsmi version at compile time and disable this
+ * workaround for libsmi versions where this problem is fixed.
+ * Currently there is no such version. :-(
+ */
+ if (smiModule->conformance == 1)
+ report_failure("Stopped processing module %s due to "
+ "error(s) to prevent potential crash in libsmi.\n"
+ "Module's conformance level: %d.\n"
+ "See details at: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=560325\n",
+ smiModule->name, smiModule->conformance);
+ continue;
+
for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_ANY);
smiNode;
smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_ANY)) {
key,
smiNode->oidlen,
smiNode->oid);
-#ifndef WIN32
- free (oid);
-#endif
+ smi_free (oid);
D(4,("\t\tNode: kind=%d oid=%s name=%s ",
oid_data->kind, oid_subid2string(smiNode->oid, smiNode->oidlen), oid_data->name ));
typedata->display,
NULL,
0,
-#ifndef WIN32
smiRenderOID(smiNode->oidlen, smiNode->oid, SMI_RENDER_ALL),
-#else
- g_strdup (smiRenderOID(smiNode->oidlen, smiNode->oid, SMI_RENDER_ALL)),
-#endif
HFILL }};
+ /* Don't allow duplicate blurb/name */
+ if (strcmp(hf.hfinfo.blurb, hf.hfinfo.name) == 0) {
+ smi_free((void *) hf.hfinfo.blurb);
+ hf.hfinfo.blurb = NULL;
+ }
+
oid_data->value_hfid = -1;
if ( IS_ENUMABLE(hf.hfinfo.type) && (smiEnum = smiGetFirstNamedNumber(smiType))) {
hf.hfinfo.strings = VALS(vals->data);
g_array_free(vals,FALSE);
}
-#if 0 /* packet-snmp does not hanldle bits yet */
+#if 0 /* packet-snmp does not handle bits yet */
} else if (smiType->basetype == SMI_BASETYPE_BITS && ( smiEnum = smiGetFirstNamedNumber(smiType) )) {
guint n = 0;
oid_bits_info_t* bits = g_malloc(sizeof(oid_bits_info_t));
guint mask = 1 << (smiEnum->value.value.integer32 % 8);
char* base = alnumerize(oid_data->name);
char* ext = alnumerize(smiEnum->name);
- hf_register_info hf2 = { &(bits->data[n].hfid), { NULL, NULL, FT_UINT8, BASE_HEX, NULL, mask, "", HFILL }};
+ hf_register_info hf2 = { &(bits->data[n].hfid), { NULL, NULL, FT_UINT8, BASE_HEX, NULL, mask, NULL, HFILL }};
bits->data[n].hfid = -1;
bits->data[n].offset = smiEnum->value.value.integer32 / 8;
key->display,
NULL,
0,
- "",
+ NULL,
HFILL }};
D(5,("\t\t\tIndex: name=%s subids=%d key_type=%d",
return "*** Empty OID ***";
do {
- w += sprintf(w,"%u.",*subids++);
+ w += g_snprintf(w,12,"%u.",*subids++);
} while(--len);
if (w!=s) *(w-1) = '\0'; else *(s) = '\0';
guint n = 0;
D(8,("check_num_oid: '%s'",str));
- if (*r == '.' || *r == '\0') return 0;
+ if (!r || *r == '.' || *r == '\0') return 0;
do {
D(9,("\tcheck_num_oid: '%c' %d",*r,n));
guint bytelen = 0;
guint i;
guint32 subid;
- guint8* bytes;
guint8* b;
if ( !subids || subids_len <= 0) {
subid = subids[i];
} while ( i++ < subids_len );
- *bytes_p = b = bytes = ep_alloc(bytelen);
+ *bytes_p = b = ep_alloc(bytelen);
subid = (subids[0] * 40) + subids[1];
i = 2;
guint i;
path_str = g_string_new("");
-#ifdef WIN32
+#ifdef _WIN32
#define PATH_SEPARATOR ";"
path = get_datafile_path("snmp\\mibs");
- g_string_sprintfa(path_str, "%s;", path);
+ g_string_append_printf(path_str, "%s;", path);
g_free (path);
path = get_persconffile_path("snmp\\mibs", FALSE, FALSE);
- g_string_sprintfa(path_str, "%s", path);
+ g_string_append_printf(path_str, "%s", path);
g_free (path);
#else
#define PATH_SEPARATOR ":"
path = smiGetPath();
- g_string_sprintfa(path_str, "%s", path);
+ g_string_append(path_str, "/usr/share/snmp/mibs");
+ if (strlen(path) > 0 ) {
+ g_string_append(path_str, PATH_SEPARATOR);
+ }
+ g_string_append_printf(path_str, "%s", path);
free (path);
#endif
if (!( smi_paths[i].name && *smi_paths[i].name))
continue;
- g_string_sprintfa(path_str,PATH_SEPARATOR "%s",smi_paths[i].name);
+ g_string_append_printf(path_str,PATH_SEPARATOR "%s",smi_paths[i].name);
}
path_ret = path_str->str;
* Local Variables:
* c-basic-offset: 8
* tab-width: 8
- * indent-tabs-mode: tabs
+ * indent-tabs-mode: t
* End:
*
* ex: set shiftwidth=8 tabstop=8 noexpandtab