aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomas Kukosa <tomas.kukosa@siemens.com>2007-05-14 13:39:31 +0000
committerTomas Kukosa <tomas.kukosa@siemens.com>2007-05-14 13:39:31 +0000
commit61ffcf48a924ff176154165118dc0f1516e0e959 (patch)
treee352329679a4ff3602cbebc2ad5b23a3fda09c00
parentfc5ce01ee49e86b2a0628319434885b9ca385412 (diff)
- more variants of dissect_per_open_type_*()
- move asn1_get_real() to asn1.c/.h svn path=/trunk/; revision=21757
-rw-r--r--epan/asn1.c37
-rw-r--r--epan/asn1.h14
-rw-r--r--epan/dissectors/packet-per.c87
-rw-r--r--epan/dissectors/packet-per.h15
4 files changed, 109 insertions, 44 deletions
diff --git a/epan/asn1.c b/epan/asn1.c
index 8d1053304b..667a848780 100644
--- a/epan/asn1.c
+++ b/epan/asn1.c
@@ -27,21 +27,52 @@
# include "config.h"
#endif
+#include <stdlib.h>
+#include <math.h>
+
#include <glib.h>
#include <epan/packet.h>
#include "asn1.h"
void asn1_ctx_init(asn1_ctx_t *actx, asn1_enc_e encoding, gboolean aligned, packet_info *pinfo) {
+ memset(actx, '\0', sizeof(*actx));
+ actx->signature = ASN1_CTX_SIGNATURE;
actx->encoding = encoding;
actx->aligned = aligned;
actx->pinfo = pinfo;
- actx->created_item = NULL;
- actx->value_ptr = NULL;
- actx->private_data = NULL;
+}
+
+gboolean asn1_ctx_check_signature(asn1_ctx_t *actx) {
+ return actx->signature == ASN1_CTX_SIGNATURE;
}
void asn1_ctx_clean_external(asn1_ctx_t *actx) {
memset(&actx->external, '\0', sizeof(actx->external));
actx->external.hf_index = -1;
}
+
+double asn1_get_real(const guint8 *real_ptr, gint real_len) {
+ guint8 octet;
+ const guint8 *p;
+ guint8 *buf;
+ double val = 0;
+
+ if (real_len < 1) return val;
+ octet = real_ptr[0];
+ p = real_ptr + 1;
+ real_len -= 1;
+ if (octet & 0x80) { /* binary encoding */
+ } else if (octet & 0x40) { /* SpecialRealValue */
+ switch (octet & 0x3F) {
+ case 0x00: val = HUGE_VAL; break;
+ case 0x01: val = -HUGE_VAL; break;
+ }
+ } else { /* decimal encoding */
+ buf = ep_alloc0(real_len + 1);
+ memcpy(buf, p, real_len);
+ val = atof(buf);
+ }
+
+ return val;
+}
diff --git a/epan/asn1.h b/epan/asn1.h
index 5dd491f8b1..baad3a91cf 100644
--- a/epan/asn1.h
+++ b/epan/asn1.h
@@ -33,7 +33,10 @@ typedef enum {
ASN1_ENC_XER /* X.693 - XER */
} asn1_enc_e;
+#define ASN1_CTX_SIGNATURE 0x41435458 /* "ACTX" */
+
typedef struct _asn1_ctx_t {
+ guint32 signature;
asn1_enc_e encoding;
gboolean aligned;
packet_info *pinfo;
@@ -67,7 +70,18 @@ typedef struct _asn1_ctx_t {
} asn1_ctx_t;
extern void asn1_ctx_init(asn1_ctx_t *actx, asn1_enc_e encoding, gboolean aligned, packet_info *pinfo);
+extern gboolean asn1_ctx_check_signature(asn1_ctx_t *actx);
extern void asn1_ctx_clean_external(asn1_ctx_t *actx);
+extern double asn1_get_real(const guint8 *real_ptr, gint real_len);
+
+/* flags */
+#define ASN1_EXT_ROOT 0x01
+#define ASN1_EXT_EXT 0x02
+#define ASN1_OPT 0x04
+#define ASN1_DFLT 0x08
+
+#define ASN1_HAS_EXT(f) ((f)&(ASN1_EXT_ROOT|ASN1_EXT_EXT))
+
#endif /* __ASN1_H__ */
diff --git a/epan/dissectors/packet-per.c b/epan/dissectors/packet-per.c
index af96db9494..1d60f6b592 100644
--- a/epan/dissectors/packet-per.c
+++ b/epan/dissectors/packet-per.c
@@ -73,10 +73,16 @@ static int hf_per_single_ASN1_type = -1; /* T_single_ASN1_type */
static int hf_per_octet_aligned = -1; /* T_octet_aligned */
static int hf_per_arbitrary = -1; /* T_arbitrary */
+static gint ett_per_open_type = -1;
static gint ett_per_sequence_of_item = -1;
static gint ett_per_External = -1;
static gint ett_per_External_encoding = -1;
+typedef enum {
+ CB_ASN1_ENC,
+ CB_DISSECTOR,
+ CB_NEW_DISSECTOR,
+} type_cb_variant;
/*
#define DEBUG_ENTRY(x) \
@@ -111,31 +117,6 @@ static const true_false_string tfs_optional_field_bit = {
""
};
-double asn1_get_real(const guint8 *real_ptr, gint real_len) {
- guint8 octet;
- const guint8 *p;
- guint8 *buf;
- double val = 0;
-
- if (real_len < 1) return val;
- octet = real_ptr[0];
- p = real_ptr + 1;
- real_len -= 1;
- if (octet & 0x80) { /* binary encoding */
- } else if (octet & 0x40) { /* SpecialRealValue */
- switch (octet & 0x3F) {
- case 0x00: val = HUGE_VAL; break;
- case 0x01: val = -HUGE_VAL; break;
- }
- } else { /* decimal encoding */
- buf = ep_alloc0(real_len + 1);
- memcpy(buf, p, real_len);
- val = atof(buf);
- }
-
- return val;
-}
-
#define BYTE_ALIGN_OFFSET(offset) if(offset&0x07){offset=(offset&0xfffffff8)+8;}
@@ -167,17 +148,48 @@ static tvbuff_t *new_octet_aligned_subset(tvbuff_t *tvb, guint32 offset, guint32
/* 10 Encoding procedures -------------------------------------------------- */
/* 10.2 Open type fields --------------------------------------------------- */
-guint32
-dissect_per_open_type(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, per_type_fn type_cb)
+static guint32
+dissect_per_open_type_internal(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, void* type_cb, type_cb_variant variant)
{
guint32 type_length, end_offset;
+ tvbuff_t *val_tvb;
+ header_field_info *hfi;
+ proto_tree *subtree = tree;
+
+ hfi = (hf_index == -1) ? NULL : proto_registrar_get_nth(hf_index);
offset = dissect_per_length_determinant(tvb, offset, actx, tree, hf_per_open_type_length, &type_length);
if (actx->aligned) BYTE_ALIGN_OFFSET(offset);
end_offset = offset + type_length * 8;
+ if ((variant==CB_DISSECTOR)||(variant==CB_NEW_DISSECTOR)) {
+ val_tvb = new_octet_aligned_subset(tvb, offset, type_length);
+ if (hfi) {
+ if (IS_FT_UINT(hfi->type)||IS_FT_INT(hfi->type)) {
+ if (IS_FT_UINT(hfi->type))
+ actx->created_item = proto_tree_add_uint(tree, hf_index, val_tvb, 0, type_length, type_length);
+ else
+ actx->created_item = proto_tree_add_int(tree, hf_index, val_tvb, 0, type_length, type_length);
+ proto_item_append_text(actx->created_item, plurality(type_length, " octet", " octets"));
+ } else {
+ actx->created_item = proto_tree_add_item(tree, hf_index, val_tvb, 0, type_length, FALSE);
+ }
+ subtree = proto_item_add_subtree(actx->created_item, ett_per_open_type);
+ }
+ }
+
if (type_cb) {
- type_cb(tvb, offset, actx, tree, hf_index);
+ switch (variant) {
+ case CB_ASN1_ENC:
+ ((per_type_fn)type_cb)(tvb, offset, actx, tree, hf_index);
+ break;
+ case CB_DISSECTOR:
+ ((dissector_t)type_cb)(val_tvb, actx->pinfo, subtree);
+ break;
+ case CB_NEW_DISSECTOR:
+ ((new_dissector_t)type_cb)(val_tvb, actx->pinfo, subtree);
+ break;
+ }
} else {
actx->created_item = proto_tree_add_text(tree, tvb, offset>>3, BLEN(offset, end_offset), "Unknown Open Type");
}
@@ -185,6 +197,24 @@ dissect_per_open_type(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tre
return end_offset;
}
+guint32
+dissect_per_open_type(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, per_type_fn type_cb)
+{
+ return dissect_per_open_type_internal(tvb, offset, actx, tree, hf_index, type_cb, CB_ASN1_ENC);
+}
+
+guint32
+dissect_per_open_type_pdu(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, dissector_t type_cb)
+{
+ return dissect_per_open_type_internal(tvb, offset, actx, tree, hf_index, type_cb, CB_DISSECTOR);
+}
+
+guint32
+dissect_per_open_type_pdu_new(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, new_dissector_t type_cb)
+{
+ return dissect_per_open_type_internal(tvb, offset, actx, tree, hf_index, type_cb, CB_NEW_DISSECTOR);
+}
+
/* 10.9 General rules for encoding a length determinant --------------------
NOTE 1 - (Tutorial) The procedures of this subclause are invoked when an explicit length field is needed
@@ -2009,6 +2039,7 @@ proto_register_per(void)
};
static gint *ett[] =
{
+ &ett_per_open_type,
&ett_per_sequence_of_item,
&ett_per_External,
&ett_per_External_encoding,
diff --git a/epan/dissectors/packet-per.h b/epan/dissectors/packet-per.h
index 9dc47212c4..393bcc56be 100644
--- a/epan/dissectors/packet-per.h
+++ b/epan/dissectors/packet-per.h
@@ -26,19 +26,6 @@
#ifndef __PACKET_PER_H__
#define __PACKET_PER_H__
-extern double asn1_get_real(const guint8 *real_ptr, gint real_len);
-
-/* flags */
-#define ASN1_EXT_ROOT 0x01
-#define ASN1_EXT_EXT 0x02
-#define ASN1_OPT 0x04
-#define ASN1_DFLT 0x08
-
-#define ASN1_HAS_EXT(f) ((f)&(ASN1_EXT_ROOT|ASN1_EXT_EXT))
-
-
-/*----------------------------------*/
-
#define PER_NOT_DECODED_YET(x) \
proto_tree_add_text(tree, tvb, 0, 0, "something unknown here [%s]",x); \
@@ -130,6 +117,8 @@ extern guint32 dissect_per_restricted_character_string(tvbuff_t *tvb, guint32 of
extern guint32 dissect_per_enumerated(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, guint32 root_num, guint32 *value, gboolean has_extension, guint32 ext_num, guint32 *value_map);
extern guint32 dissect_per_open_type(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, per_type_fn type_cb);
+extern guint32 dissect_per_open_type_pdu(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, dissector_t type_cb);
+extern guint32 dissect_per_open_type_pdu_new(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, new_dissector_t type_cb);
extern guint32 dissect_per_external_type(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, per_type_fn type_cb);