/*****************************************************************************/ /* Copyright (C) 1992-1996 Open Systems Solutions, Inc. All rights reserved.*/ /*****************************************************************************/ /* THIS FILE IS PROPRIETARY MATERIAL OF OPEN SYSTEMS SOLUTIONS, INC. AND * MAY BE USED ONLY BY DIRECT LICENSEES OF OPEN SYSTEMS SOLUTIONS, INC. * THIS FILE MAY NOT BE DISTRIBUTED. */ /*****************************************************************************/ /* FILE: @(#)osstrace.h 4.7 96/05/01 */ /* */ /* When tracing is in effect in the OSS ASN.1 Tools encoder/decoder the */ /* user user-replaceable trace routine, osstrace(), is called to trace */ /* the value that is being encoded/decoded. This header file describes */ /* the parameters passed to osstrace(). */ /* */ /* Detailed descriptions appear after the declarations. */ /*****************************************************************************/ #include "ossdll.h" #if defined(_MSC_VER) && (defined(_WIN32) || defined(WIN32)) #pragma pack(push, ossPacking, 4) #elif defined(_MSC_VER) && (defined(_WINDOWS) || defined(_MSDOS)) #pragma pack(1) #elif defined(__BORLANDC__) && defined(__MSDOS__) #pragma option -a1 #elif defined(__BORLANDC__) && defined(__WIN32__) #pragma option -a4 #elif defined(__IBMC__) #pragma pack(4) #endif /* _MSC_VER && _WIN32 */ /* traceKind: describes the type of TraceRecord */ enum traceKind { endOfContentsTrace = 0, /* end-of-contents octets */ valueTrace, /* traceRecord contains a traced value */ skippedFieldTrace, /* a value whose type is not recognized * is being skipped */ messageTrace /* error message is in the field "value" */ }; /* fieldKind: describes the contents of "fieldNumber". "fieldKind" is * meaningful only if "fieldNumber" is not 0 */ enum fieldKind { setOrSequenceField = 0, /* "fieldNumber" is the position of the * component within a SET or SEQUENCE */ pduNumber, /* "fieldNumber" is a PDU number */ setOrSequenceOfElement, /* "fieldNumber" is the position of the * component within a SET OF or SEQUENCE OF * components */ stringElement /* "fieldNumber" is the position of the * substring within a constructed STRING */ }; enum prtType { seqsetType = 0, /* SEQUENCE and SET uses [fieldcount = n] */ seqofType, /* SEQUENCE OF and SET OF use [length = n] */ choiceType, /* CHOICE type uses format [index = n] */ pseudoType, /* No length info is printed or [not encoded] */ primeType, /* All other types use the format */ /* [length = [(not encoded)] nbytes.nbits] */ /* fragmentation is printed for OCTET */ /* STRING and BIT STRING. */ closeType /* Trace message at the end of encoding. */ }; /* tag_length: specifies the tag and length of a value. */ struct tag_length { unsigned long int length; /* length of type, if definite */ unsigned short int tag; /* 16 bits of the form CCTTTTTTTTTTTTTT, * with "CC" the class number, and "T...T" * the tag. (If tag is 0, then "length", * "primitive" and "definite" are * not significant). */ unsigned int definite: 1; /* 1: definite-length encoding */ }; /* traceRecord: OSS ASN.1 Tools trace record */ struct traceRecord { enum traceKind kind; /* kind of trace record */ void *p; /* reserved for OSS */ char *identifier, /* SET/SEQUENCE/CHOICE component name*/ *typeReference,/* defined type name */ *builtinTypeName; /* ASN.1 builtin type defined in * * ISO 8824 or "Character String"*/ void *valueName; /* reserved for future use */ unsigned taggingCount; /* number of entries in the tag&length * or content-end-octet array */ union /* tag&length or end-of-contents-octets array. */ { struct tag_length *tag_length; int *depth; } tagging; enum prtType prtType; /* Refer to prtType above for details */ char lenEncoded; /* Indicate whether length is encoded */ long length; /* Length in bits for all prime types */ /* fieldcount for SET and SEQUENCE */ /* length of components for SET OF */ /* choice index for type CHOICE */ int fragment; /* Fragment for OCTET STRING and BIT */ /* STRING, PER fragment when too long */ enum fieldKind fieldKind; /* kind of value in "fieldNumber" */ unsigned int fieldNumber; /* component number, 0 if not * applicable */ unsigned int depth; /* the depth of this value, from 0 on up */ unsigned int primitive: 1; /* indicates structure of encoding */ char value[1]; /* the formatted value for simple * type and ANY. If the first byte * is 0, no value is present. */ }; extern void DLL_ENTRY osstrace(struct ossGlobal *g, struct traceRecord *p, size_t traceRecordLen); /* osstrace(): User-replaceable trace routine. * * Parameters: * g - Reserved. This is always set to NULL for now. * p - traceRecord, described below. * traceRecordLen - True length of traceRecord, including first \0 in "value" * * osstrace() is called: * * - once for each builtin ASN.1 type, regardless of tagging, with the * field "kind" set to valueTrace. So given a PDU of value "fooBar": * * Sample DEFINITIONS EXPLICIT TAGS ::= BEGIN * fooBar Foo ::= {age 6, living TRUE} * Foo ::= SET {age INTEGER, living [1] [2] Alive} * Alive ::= BOOLEAN * END * * it is called called three times with "kind" set to valueTrace - once * for the SET, once for the INTEGER, and once for the BOOLEAN. * * When the traceRecord "kind" field is set to valueTrace ... * * The field "identifier" contains the component identifier of * the type if one is present in the ASN.1 definition. So in * the above example, "identifier" will be empty on the call for * the SET, while on the call for the INTEGER it will contain "age", * and "living" on the call for the BOOLEAN. * * The field "typeReference" contains the name of the associated ASN.1 * typereference, if any. So in the above example, "typeReference" * will contain "Foo" on the call for the SET, "Alive" on the call * for the BOOLEAN, and will be empty on the call for the INTEGER. * * The field "builtinTypeName" contains the name of the ASN.1 builtin * type. So in the above example, "builtinTypeName" will contain * "SET", "INTEGER", and "BOOLEAN" on the calls as appropriate. * Note that for all character string types "builtinTypeName" is * set to "Character String". This will be changed in the near future * to reflect the true character string type. * * The field "taggingCount" contains the number of entries in the array * of tag_length structs pointed to by tagging.tag_length, and reflects * the number of tags present in the encoding. Note that an entry * exists in the tag_length array for each ANY and CHOICE value as * though they had tags defined for them in the ASN.1 Standard. So in * the above example, "taggingCount" is 1 on the calls for the SET and * INTEGER, and on the call for the BOOLEAN "taggingCount" is 3 since * EXPLICIT TAGS is in effect. * * The field "tagging.tag_length" points to an array of tag_length * structs. * * The field "tagging.tag_length->tag" is the BER tag represented * in the form CCTTTTTTTTTTTTTT with "CC" the class number, and * "TTTTTTTTTTTTTT" the tag number. Since the ANY and CHOICE * types do not have tags of their own, the last entry in the * tag_length array for these types always has 0 as the value of * the "tag" field. So in the above example, "tag" is 0x11 on the * call for the the SET. * * The field "tagging.tag_length->length" is the length of the * encoded value if the length is of definite form (i.e., * "definite" is 1). * * The field "tagging.tag_length->definite" indicates when the * length is definite or indefinite. This field is significant * only if "tag" is non-zero. * * The field "fieldKind" indicates whether the number in "field" is: * -- the position of a component within a SET or SEQUENCE, or * -- the PDU number assigned by the ASN.1 compiler, or * -- the position of a component within a SET OF or SEQUENCE OF, or * -- the position of a substring within a constructed string. * "fieldKind" is significant only if "field" is non-zero. So in * the example above, "fieldKind" has a value of pduNumber on the * call for the SET, and a value of setOrSequenceField on the calls for * the INTEGER and BOOLEAN. * * The field "fieldNumber" is a ordinal number indicating the position * of a component within a SET, SEQUENCE, SET OF, SEQUENCE OF, or * constructed string, or the PDU number assigned by the ASN.1 compiler. * So in the above example, "fieldNumber" is 1 (the PDU number) on the * call for the SET, 1 (the position of the component "age") on the * call for the INTEGER, and 2 (the position of the component "living" * on the call for the BOOLEAN. * * The field "depth" is the level of nesting of the value relative to * the outermost type, which has a "depth" value of 0. So in the above * example, "depth" is 0 on the call for the SET, and 1 on the calls * for the INTEGER and BOOLEAN. * * The field "primitive" is set to 1 if the builtin ASN.1 type is * simple (i.e., the primitive/constructed bit in the identifier * octet is set to 0), so it is 0 for SET, SEQUENCE, SET OF, SEQUENCE * OF, and CHOICE because they are structured. It is also set to 0 if * the type is an ANY. It is 1 for all other builtin types. * * The field "value" contains formatted data if the builtin type * is simple or ANY, regardless of tagging. Hence, in the above * example the call for SET will not contain any data in "value" * (because the builtin type is a constructed type), while for the * INTEGER and BOOLEAN types "value" will contain formatted data. * The maximum number of bytes of formatted data placed into "value" * is controlled by the external variable "asn1chop". If "asn1chop" * is set to 0 the maximum length of the traced value is determined * by the maximum internal buffer size variable, "ossblock". * * - once for each end-of-contents octets pair that is generated/ * encountered while encoding/decoding a constructed value whose * length is of the indefinite-length form. A call with a "valueTrace" * record is always made to osstrace() before one is made with an * "endOfContentsTrace" record. * * A single "endOfContentsTrace" call is made to osstrace() for each * builtin type that is processed if the indefinite-length form of * encoding is used. If the builtin type is a structured type (CHOICE, * SET, SEQUENCE, SET OF, SEQUENCE OF) then there may be multiple * "valueTrace" and possible "endOfContentsTrace" calls made to * osstrace() before the matching "endOfContentsTrace" call is made. * * When the traceRecord "kind" field is set to endOfContentsTrace ... * * The field "taggingCount" contains the number of entries in the array * of "depth" indicators pointed to by tagging.depth, and reflects * the nesting of each pair of end-of-contents-octets associated with * the builtin type being encoded/decoded. So in the above example, * if indefinite-length encoding is being used, "taggingCount" will * be 1 on the call for the SET (since it has a single constructed * tag), and 2 on the call for the BOOLEAN (since it has two explicit * tags, for which the "constructed" bit in the encoding must be set). * * The field "tagging.depth" points to an array of "depth" indicators * that reflect the nesting of each pair of end-of-contents-octets * associated with a builtin type. So in the above example, if * indefinite-length encoding is being used, "tagging.depth" will point * to a single 0 on the call for the SET since it has a single tag for * which the constructed bit is set; while on the call for the BOOLEAN * "tagging.depth" will point to an array whose two entries are 1 and 2 * since there are two explicit tags on the BOOLEAN. * * All other fields in the traceRecord are insignificant for an * endOfContentsTrace record. * * - once for each value that is skipped while decoding, with a "kind" * value of skippedFieldTrace. The skippedFieldTrace "kind" is just * means of indicating that an unexpected value was encountered in the * message and is being skipped. This is not an error if the type is * extensible. * * When the traceRecord "kind" field is set to skippedFieldTrace ... * * The field of the traceRecord are the same as when "kind" is set to * valueTrace, except that: * -- the skipped value is always reported as having one tag, hence * -- there is only one entry in the tag_length array. * -- the content of the field "value" is always "", and * -- "typeReference" is always NULL. * * - once for each error message issued, in which case the "kind" field * is set to messageTrace. * * When the traceRecord "kind" field is set to messageTrace the "value" * field contains the error message, and other fields are * insignificant. */ /* tag_length: describes the tag and length of a value. * * "tag" is 0 if the value is an ANY or CHOICE value, in which * case "definite" is not significant since ANY and CHOICE do * not have a tag of their own. * * If "tag" is not 0, "definite" indicates whether the value * is encoded using definite- or indefinite-length form. * * If "definite" is 1, "length" is the length of the value, else * it is not significant (indefinite-length encoding was used). */ /* tagging: tag&length or end-of-contents-octets array. * * The tag and length array, tag_length, is present if this * is a valueTrace or skippedFieldTrace record. There is one array * entry for each tag present in the encoding of a given value, so * "[1] EXPLICIT [2] EXPLICIT INTEGER" gets three tag_length * array entries, where each entry describes the tag and length * information that precedes the value. * * The depth array, "depth", is present only if this is a * endOfContentsTrace record. There is one array entry for each * indefinite length present in the encoding of a value, so * "[1] EXPLICIT [2] EXPLICIT INTEGER" gets two "depth" entries * corresponding to the two explicit tags, where the value of each * tag indicates the depth of the tagged value relative to outmost type * that contains the INTEGER (e.g., relative to the containing SET). */ /* Odds and ends: * * - When the value of a field is not significant the field is set to 0. */ /* Augmenting for Packed Encoding Rule (PER) tracing. * * PER does not encode tag for any ASN.1 type. For some types, length * may or may not be encoded. PER does not always use octet aligned * encoding, therefore, the length should be in unit of bit. * * We classified ASN.1 types in to the following: * * (1). For all primitive types (including ANY), the prtType in traceRecord * is set to primeType, length is the total length of the content * in bits. The file osstrace.c prints length in the format * length = nbytes.nbits, and the total length should be 8*nbytes+nbits. * If the length is not encoded, "(not encoded)" will be added to the * output string. For BIT STRING with length longer than 64K (bits), and * for OCTET STRING longer that 16K (bytes), fragmentation is needed * and this is indicated by the string "fragment = n" after the length. * The fragmentation index is field fragment in traceRecord. * (2). For SEQUENCE and SET, prtType is seqsetType. In this case, the length * in traceRecord is the fieldcount of the SEQUENCE or SET. * (3). For SEQUENCE OF and SET OF, prtType is seqofType, and the length * in traceRecord is the count of components in the SEQUENCE OF (SET OF). * (4). For CHOICE, prtType is choiceType, and the length field in * traceRecord indicates the choice index. * (5). Total number of bits for the entire encoding is reported at the end * of encoding and decoding. The prtType for this trace is closeType. */ #if defined(_MSC_VER) && (defined(_WIN32) || defined(WIN32)) #pragma pack(pop, ossPacking) #elif defined(_MSC_VER) && (defined(_WINDOWS) || defined(_MSDOS)) #pragma pack() #elif defined(__BORLANDC__) && (defined(__WIN32__) || defined(__MSDOS__)) #pragma option -a. #elif defined(__IBMC__) #pragma pack() #endif /* _MSC_VER && _WIN32 */