2 * Common routines for ASN.1
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
34 #include <epan/emem.h>
35 #include <epan/packet.h>
39 void asn1_ctx_init(asn1_ctx_t
*actx
, asn1_enc_e encoding
, gboolean aligned
, packet_info
*pinfo
) {
40 memset(actx
, '\0', sizeof(*actx
));
41 actx
->signature
= ASN1_CTX_SIGNATURE
;
42 actx
->encoding
= encoding
;
43 actx
->aligned
= aligned
;
47 gboolean
asn1_ctx_check_signature(asn1_ctx_t
*actx
) {
48 return actx
&& (actx
->signature
== ASN1_CTX_SIGNATURE
);
51 void asn1_ctx_clean_external(asn1_ctx_t
*actx
) {
52 memset(&actx
->external
, '\0', sizeof(actx
->external
));
53 actx
->external
.hf_index
= -1;
54 actx
->external
.encoding
= -1;
57 void asn1_ctx_clean_epdv(asn1_ctx_t
*actx
) {
58 memset(&actx
->embedded_pdv
, '\0', sizeof(actx
->embedded_pdv
));
59 actx
->embedded_pdv
.hf_index
= -1;
60 actx
->embedded_pdv
.identification
= -1;
64 /*--- stack/parameters ---*/
66 void asn1_stack_frame_push(asn1_ctx_t
*actx
, const gchar
*name
) {
67 asn1_stack_frame_t
*frame
;
69 frame
= ep_new0(asn1_stack_frame_t
);
71 frame
->next
= actx
->stack
;
75 void asn1_stack_frame_pop(asn1_ctx_t
*actx
, const gchar
*name
) {
76 DISSECTOR_ASSERT(actx
->stack
);
77 DISSECTOR_ASSERT(!strcmp(actx
->stack
->name
, name
));
78 actx
->stack
= actx
->stack
->next
;
81 void asn1_stack_frame_check(asn1_ctx_t
*actx
, const gchar
*name
, const asn1_par_def_t
*par_def
) {
82 const asn1_par_def_t
*pd
= par_def
;
85 DISSECTOR_ASSERT(actx
->stack
);
86 DISSECTOR_ASSERT(!strcmp(actx
->stack
->name
, name
));
88 par
= actx
->stack
->par
;
90 DISSECTOR_ASSERT(par
);
91 DISSECTOR_ASSERT((pd
->ptype
== ASN1_PAR_IRR
) || (par
->ptype
== pd
->ptype
));
96 DISSECTOR_ASSERT(!par
);
99 static asn1_par_t
*get_par_by_name(asn1_ctx_t
*actx
, const gchar
*name
) {
100 asn1_par_t
*par
= NULL
;
102 DISSECTOR_ASSERT(actx
->stack
);
103 par
= actx
->stack
->par
;
105 if (!strcmp(par
->name
, name
))
112 static asn1_par_t
*push_new_par(asn1_ctx_t
*actx
) {
113 asn1_par_t
*par
, **pp
;
115 DISSECTOR_ASSERT(actx
->stack
);
117 par
= ep_new0(asn1_par_t
);
119 pp
= &(actx
->stack
->par
);
127 void asn1_param_push_boolean(asn1_ctx_t
*actx
, gboolean value
) {
130 par
= push_new_par(actx
);
131 par
->ptype
= ASN1_PAR_BOOLEAN
;
132 par
->value
.v_boolean
= value
;
135 void asn1_param_push_integer(asn1_ctx_t
*actx
, gint32 value
) {
138 par
= push_new_par(actx
);
139 par
->ptype
= ASN1_PAR_INTEGER
;
140 par
->value
.v_integer
= value
;
143 gboolean
asn1_param_get_boolean(asn1_ctx_t
*actx
, const gchar
*name
) {
144 asn1_par_t
*par
= NULL
;
146 par
= get_par_by_name(actx
, name
);
147 DISSECTOR_ASSERT(par
);
148 return par
->value
.v_boolean
;
151 gint32
asn1_param_get_integer(asn1_ctx_t
*actx
, const gchar
*name
) {
152 asn1_par_t
*par
= NULL
;
154 par
= get_par_by_name(actx
, name
);
155 DISSECTOR_ASSERT(par
);
156 return par
->value
.v_integer
;
162 void rose_ctx_init(rose_ctx_t
*rctx
) {
163 memset(rctx
, '\0', sizeof(*rctx
));
164 rctx
->signature
= ROSE_CTX_SIGNATURE
;
167 gboolean
rose_ctx_check_signature(rose_ctx_t
*rctx
) {
168 return rctx
&& (rctx
->signature
== ROSE_CTX_SIGNATURE
);
171 void rose_ctx_clean_data(rose_ctx_t
*rctx
) {
172 memset(&rctx
->d
, '\0', sizeof(rctx
->d
));
176 asn1_ctx_t
*get_asn1_ctx(void *ptr
) {
177 asn1_ctx_t
*actx
= (asn1_ctx_t
*)ptr
;
179 if (!asn1_ctx_check_signature(actx
))
185 rose_ctx_t
*get_rose_ctx(void *ptr
) {
186 rose_ctx_t
*rctx
= (rose_ctx_t
*)ptr
;
187 asn1_ctx_t
*actx
= (asn1_ctx_t
*)ptr
;
189 if (!asn1_ctx_check_signature(actx
))
193 rctx
= actx
->rose_ctx
;
195 if (!rose_ctx_check_signature(rctx
))
201 double asn1_get_real(const guint8
*real_ptr
, gint real_len
) {
207 if (real_len
< 1) return val
;
211 if (octet
& 0x80) { /* binary encoding */
212 } else if (octet
& 0x40) { /* SpecialRealValue */
213 switch (octet
& 0x3F) {
214 case 0x00: val
= HUGE_VAL
; break;
215 case 0x01: val
= -HUGE_VAL
; break;
217 } else { /* decimal encoding */
218 buf
= ep_strndup(p
, real_len
);