From b2b89723a2427bba8290bd6967a1ab39cbb630be Mon Sep 17 00:00:00 2001 From: Maksym Mamontov Date: Sun, 28 Aug 2022 18:02:04 +0300 Subject: [PATCH] Regen SMUX support library with more recent ASN1 compiler. --- libs/smux/ANY.c | 149 ++- libs/smux/ApplicationSyntax.c | 50 +- libs/smux/AtEntry.c | 31 +- libs/smux/BIT_STRING.c | 511 +++++++++- libs/smux/BIT_STRING_oer.c | 174 ++++ libs/smux/BOOLEAN.c | 282 ------ libs/smux/ClosePDU.c | 86 +- libs/smux/Counter.c | 90 +- libs/smux/DisplayString.c | 88 +- libs/smux/EgpNeighEntry.c | 79 +- libs/smux/Gauge.c | 90 +- libs/smux/GetNextRequest-PDU.c | 91 +- libs/smux/GetRequest-PDU.c | 91 +- libs/smux/GetResponse-PDU.c | 91 +- libs/smux/INTEGER.c | 788 ++++++++++----- libs/smux/INTEGER_oer.c | 179 ++++ libs/smux/IfEntry.c | 107 +- libs/smux/IpAddrEntry.c | 49 +- libs/smux/IpAddress.c | 90 +- libs/smux/IpNetToMediaEntry.c | 35 +- libs/smux/IpRouteEntry.c | 71 +- libs/smux/Message.c | 33 +- libs/smux/NULL.c | 223 +++- libs/smux/NativeEnumerated.c | 207 ---- libs/smux/NativeInteger.c | 284 ++++-- libs/smux/NativeInteger_oer.c | 99 ++ libs/smux/NetworkAddress.c | 34 +- libs/smux/OBJECT_IDENTIFIER.c | 933 ++++++++--------- libs/smux/OCTET_STRING.c | 814 +++++++++------ libs/smux/OCTET_STRING_oer.c | 171 ++++ libs/smux/OPEN_TYPE.c | 402 ++++++++ libs/smux/OPEN_TYPE_oer.c | 92 ++ libs/smux/ObjectName.c | 86 +- libs/smux/ObjectSyntax.c | 38 +- libs/smux/Opaque.c | 88 +- libs/smux/OpenPDU.c | 34 +- libs/smux/PDU.c | 39 +- libs/smux/PDUs.c | 50 +- libs/smux/PhysAddress.c | 88 +- libs/smux/RReqPDU.c | 45 +- libs/smux/RRspPDU.c | 86 +- libs/smux/SMUX-PDUs.c | 53 +- libs/smux/SOutPDU.c | 86 +- libs/smux/SetRequest-PDU.c | 91 +- libs/smux/SimpleOpen.c | 39 +- libs/smux/SimpleSyntax.c | 49 +- libs/smux/TcpConnEntry.c | 59 +- libs/smux/TimeTicks.c | 90 +- libs/smux/Trap-PDU.c | 47 +- libs/smux/UdpEntry.c | 37 +- libs/smux/VarBind.c | 31 +- libs/smux/VarBindList.c | 24 +- libs/smux/asn_application.c | 440 ++++++++ libs/smux/asn_bit_data.c | 333 ++++++ libs/smux/asn_codecs_prim.c | 55 +- libs/smux/asn_internal.c | 47 + libs/smux/asn_random_fill.c | 56 + libs/smux/ber_decoder.c | 28 +- libs/smux/ber_tlv_length.c | 30 +- libs/smux/ber_tlv_tag.c | 2 +- libs/smux/constr_CHOICE.c | 520 +++++++--- libs/smux/constr_CHOICE_oer.c | 380 +++++++ libs/smux/constr_SEQUENCE.c | 953 +++++++++++------- libs/smux/constr_SEQUENCE_OF.c | 280 +++-- libs/smux/constr_SEQUENCE_oer.c | 561 +++++++++++ libs/smux/constr_SET_OF.c | 854 +++++++++++----- libs/smux/constr_SET_OF_oer.c | 285 ++++++ libs/smux/constr_TYPE.c | 27 +- libs/smux/constraints.c | 54 +- libs/smux/der_encoder.c | 71 +- libs/smux/include/stg/ANY.h | 14 +- libs/smux/include/stg/ApplicationSyntax.h | 7 +- libs/smux/include/stg/AtEntry.h | 4 +- libs/smux/include/stg/BIT_STRING.h | 17 +- libs/smux/include/stg/BOOLEAN.h | 36 - libs/smux/include/stg/ClosePDU.h | 8 +- libs/smux/include/stg/Counter.h | 10 +- libs/smux/include/stg/DisplayString.h | 8 +- libs/smux/include/stg/EgpNeighEntry.h | 4 +- libs/smux/include/stg/Gauge.h | 10 +- libs/smux/include/stg/GetNextRequest-PDU.h | 8 +- libs/smux/include/stg/GetRequest-PDU.h | 8 +- libs/smux/include/stg/GetResponse-PDU.h | 8 +- libs/smux/include/stg/INTEGER.h | 54 +- libs/smux/include/stg/IfEntry.h | 4 +- libs/smux/include/stg/IpAddrEntry.h | 4 +- libs/smux/include/stg/IpAddress.h | 9 +- libs/smux/include/stg/IpNetToMediaEntry.h | 4 +- libs/smux/include/stg/IpRouteEntry.h | 4 +- libs/smux/include/stg/Message.h | 4 +- libs/smux/include/stg/NULL.h | 15 +- libs/smux/include/stg/NativeEnumerated.h | 32 - libs/smux/include/stg/NativeInteger.h | 9 +- libs/smux/include/stg/NetworkAddress.h | 7 +- libs/smux/include/stg/OBJECT_IDENTIFIER.h | 117 ++- libs/smux/include/stg/OCTET_STRING.h | 50 +- libs/smux/include/stg/OPEN_TYPE.h | 63 ++ libs/smux/include/stg/ObjectName.h | 8 +- libs/smux/include/stg/ObjectSyntax.h | 7 +- libs/smux/include/stg/Opaque.h | 8 +- libs/smux/include/stg/OpenPDU.h | 7 +- libs/smux/include/stg/PDU.h | 6 +- libs/smux/include/stg/PDUs.h | 7 +- libs/smux/include/stg/PhysAddress.h | 8 +- libs/smux/include/stg/RReqPDU.h | 6 +- libs/smux/include/stg/RRspPDU.h | 8 +- libs/smux/include/stg/SMUX-PDUs.h | 4 +- libs/smux/include/stg/SOutPDU.h | 8 +- libs/smux/include/stg/SetRequest-PDU.h | 8 +- libs/smux/include/stg/SimpleOpen.h | 6 +- libs/smux/include/stg/SimpleSyntax.h | 7 +- libs/smux/include/stg/TcpConnEntry.h | 4 +- libs/smux/include/stg/TimeTicks.h | 10 +- libs/smux/include/stg/Trap-PDU.h | 6 +- libs/smux/include/stg/UdpEntry.h | 4 +- libs/smux/include/stg/VarBind.h | 6 +- libs/smux/include/stg/VarBindList.h | 6 +- libs/smux/include/stg/asn_SEQUENCE_OF.h | 2 +- libs/smux/include/stg/asn_SET_OF.h | 28 +- libs/smux/include/stg/asn_application.h | 132 ++- libs/smux/include/stg/asn_bit_data.h | 83 ++ libs/smux/include/stg/asn_codecs.h | 9 +- libs/smux/include/stg/asn_codecs_prim.h | 34 +- libs/smux/include/stg/asn_internal.h | 98 +- libs/smux/include/stg/asn_ioc.h | 50 + libs/smux/include/stg/asn_random_fill.h | 51 + libs/smux/include/stg/asn_system.h | 95 +- libs/smux/include/stg/ber_decoder.h | 46 +- libs/smux/include/stg/ber_tlv_length.h | 4 +- libs/smux/include/stg/ber_tlv_tag.h | 2 +- libs/smux/include/stg/constr_CHOICE.h | 43 +- libs/smux/include/stg/constr_SEQUENCE.h | 26 +- libs/smux/include/stg/constr_SEQUENCE_OF.h | 14 +- libs/smux/include/stg/constr_SET_OF.h | 29 +- libs/smux/include/stg/constr_TYPE.h | 248 +++-- libs/smux/include/stg/constraints.h | 25 +- libs/smux/include/stg/der_encoder.h | 58 +- libs/smux/include/stg/oer_decoder.h | 72 ++ libs/smux/include/stg/oer_encoder.h | 70 ++ libs/smux/include/stg/oer_support.h | 47 + libs/smux/include/stg/per_decoder.h | 47 +- libs/smux/include/stg/per_encoder.h | 39 +- libs/smux/include/stg/per_opentype.h | 18 +- libs/smux/include/stg/per_support.h | 95 +- libs/smux/include/stg/xer_decoder.h | 48 +- libs/smux/include/stg/xer_encoder.h | 56 +- libs/smux/include/stg/xer_support.h | 2 +- libs/smux/oer_decoder.c | 152 +++ libs/smux/oer_encoder.c | 141 +++ libs/smux/oer_support.c | 122 +++ libs/smux/pdu_collection.c | 35 + libs/smux/per_decoder.c | 16 +- libs/smux/per_encoder.c | 138 +-- libs/smux/per_opentype.c | 126 ++- libs/smux/per_support.c | 496 +++------ libs/smux/regen.sh | 8 +- libs/smux/xer_decoder.c | 17 +- libs/smux/xer_encoder.c | 188 +++- .../stargazer/plugins/other/smux/types.cpp | 44 +- projects/stargazer/plugins/other/smux/types.h | 20 +- .../stargazer/plugins/other/smux/utils.cpp | 7 +- 161 files changed, 10736 insertions(+), 5647 deletions(-) create mode 100644 libs/smux/BIT_STRING_oer.c delete mode 100644 libs/smux/BOOLEAN.c create mode 100644 libs/smux/INTEGER_oer.c delete mode 100644 libs/smux/NativeEnumerated.c create mode 100644 libs/smux/NativeInteger_oer.c create mode 100644 libs/smux/OCTET_STRING_oer.c create mode 100644 libs/smux/OPEN_TYPE.c create mode 100644 libs/smux/OPEN_TYPE_oer.c create mode 100644 libs/smux/asn_application.c create mode 100644 libs/smux/asn_bit_data.c create mode 100644 libs/smux/asn_internal.c create mode 100644 libs/smux/asn_random_fill.c create mode 100644 libs/smux/constr_CHOICE_oer.c create mode 100644 libs/smux/constr_SEQUENCE_oer.c create mode 100644 libs/smux/constr_SET_OF_oer.c delete mode 100644 libs/smux/include/stg/BOOLEAN.h delete mode 100644 libs/smux/include/stg/NativeEnumerated.h create mode 100644 libs/smux/include/stg/OPEN_TYPE.h create mode 100644 libs/smux/include/stg/asn_bit_data.h create mode 100644 libs/smux/include/stg/asn_ioc.h create mode 100644 libs/smux/include/stg/asn_random_fill.h create mode 100644 libs/smux/include/stg/oer_decoder.h create mode 100644 libs/smux/include/stg/oer_encoder.h create mode 100644 libs/smux/include/stg/oer_support.h create mode 100644 libs/smux/oer_decoder.c create mode 100644 libs/smux/oer_encoder.c create mode 100644 libs/smux/oer_support.c create mode 100644 libs/smux/pdu_collection.c diff --git a/libs/smux/ANY.c b/libs/smux/ANY.c index 77024bdc..6bd5e67a 100644 --- a/libs/smux/ANY.c +++ b/libs/smux/ANY.c @@ -1,41 +1,64 @@ -/*- - * Copyright (c) 2004 Lev Walkin . All rights reserved. +/* + * Copyright (c) 2004-2017 Lev Walkin . All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ #include #include #include -static asn_OCTET_STRING_specifics_t asn_DEF_ANY_specs = { +asn_OCTET_STRING_specifics_t asn_SPC_ANY_specs = { sizeof(ANY_t), offsetof(ANY_t, _asn_ctx), ASN_OSUBV_ANY }; -asn_TYPE_descriptor_t asn_DEF_ANY = { - "ANY", - "ANY", +asn_TYPE_operation_t asn_OP_ANY = { OCTET_STRING_free, OCTET_STRING_print, - asn_generic_no_constraint, + OCTET_STRING_compare, OCTET_STRING_decode_ber, OCTET_STRING_encode_der, OCTET_STRING_decode_xer_hex, ANY_encode_xer, +#ifdef ASN_DISABLE_OER_SUPPORT + 0, + 0, +#else + 0, + 0, +#endif /* ASN_DISABLE_OER_SUPPORT */ +#ifdef ASN_DISABLE_PER_SUPPORT 0, 0, - 0, /* Use generic outmost tag fetcher */ +#else + ANY_decode_uper, + ANY_encode_uper, +#endif /* ASN_DISABLE_PER_SUPPORT */ + 0, /* Random fill is not defined for ANY type */ + 0 /* Use generic outmost tag fetcher */ +}; +asn_TYPE_descriptor_t asn_DEF_ANY = { + "ANY", + "ANY", + &asn_OP_ANY, 0, 0, 0, 0, - 0, /* No PER visible constraints */ + { 0, 0, asn_generic_no_constraint }, /* No constraints */ 0, 0, /* No members */ - &asn_DEF_ANY_specs, + &asn_SPC_ANY_specs, }; +#undef RETURN +#define RETURN(_code) \ + do { \ + asn_dec_rval_t tmprval; \ + tmprval.code = _code; \ + tmprval.consumed = consumed_myself; \ + return tmprval; \ + } while(0) asn_enc_rval_t -ANY_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, - int ilevel, enum xer_encoder_flags_e flags, - asn_app_consume_bytes_f *cb, void *app_key) { - - if(flags & XER_F_CANONICAL) { +ANY_encode_xer(const asn_TYPE_descriptor_t *td, const void *sptr, int ilevel, + enum xer_encoder_flags_e flags, asn_app_consume_bytes_f *cb, + void *app_key) { + if(flags & XER_F_CANONICAL) { /* * Canonical XER-encoding of ANY type is not supported. */ @@ -156,3 +179,99 @@ static int ANY__consume_bytes(const void *buffer, size_t size, void *key) { return 0; } +#ifndef ASN_DISABLE_PER_SUPPORT + +asn_dec_rval_t +ANY_decode_uper(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, void **sptr, + asn_per_data_t *pd) { + const asn_OCTET_STRING_specifics_t *specs = + td->specifics ? (const asn_OCTET_STRING_specifics_t *)td->specifics + : &asn_SPC_ANY_specs; + size_t consumed_myself = 0; + int repeat; + ANY_t *st = (ANY_t *)*sptr; + + (void)opt_codec_ctx; + (void)constraints; + + /* + * Allocate the structure. + */ + if(!st) { + st = (ANY_t *)(*sptr = CALLOC(1, specs->struct_size)); + if(!st) RETURN(RC_FAIL); + } + + ASN_DEBUG("PER Decoding ANY type"); + + + st->size = 0; + do { + ssize_t raw_len; + ssize_t len_bytes; + ssize_t len_bits; + void *p; + int ret; + + /* Get the PER length */ + raw_len = uper_get_length(pd, -1, 0, &repeat); + if(raw_len < 0) RETURN(RC_WMORE); + if(raw_len == 0 && st->buf) break; + + ASN_DEBUG("Got PER length len %" ASN_PRI_SIZE ", %s (%s)", raw_len, + repeat ? "repeat" : "once", td->name); + len_bytes = raw_len; + len_bits = len_bytes * 8; + + p = REALLOC(st->buf, st->size + len_bytes + 1); + if(!p) RETURN(RC_FAIL); + st->buf = (uint8_t *)p; + + ret = per_get_many_bits(pd, &st->buf[st->size], 0, len_bits); + if(ret < 0) RETURN(RC_WMORE); + consumed_myself += len_bits; + st->size += len_bytes; + } while(repeat); + st->buf[st->size] = 0; /* nul-terminate */ + + RETURN(RC_OK); +} + +asn_enc_rval_t +ANY_encode_uper(const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, const void *sptr, + asn_per_outp_t *po) { + const ANY_t *st = (const ANY_t *)sptr; + asn_enc_rval_t er = {0, 0, 0}; + const uint8_t *buf; + size_t size; + int ret; + + (void)constraints; + + if(!st || (!st->buf && st->size)) ASN__ENCODE_FAILED; + + buf = st->buf; + size = st->size; + do { + int need_eom = 0; + ssize_t may_save = uper_put_length(po, size, &need_eom); + if(may_save < 0) ASN__ENCODE_FAILED; + + ret = per_put_many_bits(po, buf, may_save * 8); + if(ret) ASN__ENCODE_FAILED; + + buf += may_save; + size -= may_save; + assert(!(may_save & 0x07) || !size); + if(need_eom && uper_put_length(po, 0, 0)) + ASN__ENCODE_FAILED; /* End of Message length */ + } while(size); + + ASN__ENCODED_OK(er); +} + +#endif /* ASN_DISABLE_PER_SUPPORT */ + diff --git a/libs/smux/ApplicationSyntax.c b/libs/smux/ApplicationSyntax.c index 163bae33..a9a9637e 100644 --- a/libs/smux/ApplicationSyntax.c +++ b/libs/smux/ApplicationSyntax.c @@ -1,56 +1,64 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1155-SMI" * found in "RFC1155-SMI.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #include "ApplicationSyntax.h" -static asn_TYPE_member_t asn_MBR_ApplicationSyntax_1[] = { +static asn_oer_constraints_t asn_OER_type_ApplicationSyntax_constr_1 CC_NOTUSED = { + { 0, 0 }, + -1}; +asn_per_constraints_t asn_PER_type_ApplicationSyntax_constr_1 CC_NOTUSED = { + { APC_CONSTRAINED, 3, 3, 0, 4 } /* (0..4) */, + { APC_UNCONSTRAINED, -1, -1, 0, 0 }, + 0, 0 /* No PER value map */ +}; +asn_TYPE_member_t asn_MBR_ApplicationSyntax_1[] = { { ATF_NOFLAGS, 0, offsetof(struct ApplicationSyntax, choice.address), -1 /* Ambiguous tag (CHOICE?) */, 0, &asn_DEF_NetworkAddress, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "address" }, { ATF_NOFLAGS, 0, offsetof(struct ApplicationSyntax, choice.counter), (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 0, &asn_DEF_Counter, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "counter" }, { ATF_NOFLAGS, 0, offsetof(struct ApplicationSyntax, choice.gauge), (ASN_TAG_CLASS_APPLICATION | (2 << 2)), 0, &asn_DEF_Gauge, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "gauge" }, { ATF_NOFLAGS, 0, offsetof(struct ApplicationSyntax, choice.ticks), (ASN_TAG_CLASS_APPLICATION | (3 << 2)), 0, &asn_DEF_TimeTicks, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "ticks" }, { ATF_NOFLAGS, 0, offsetof(struct ApplicationSyntax, choice.arbitrary), (ASN_TAG_CLASS_APPLICATION | (4 << 2)), 0, &asn_DEF_Opaque, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "arbitrary" }, }; @@ -61,33 +69,25 @@ static const asn_TYPE_tag2member_t asn_MAP_ApplicationSyntax_tag2el_1[] = { { (ASN_TAG_CLASS_APPLICATION | (3 << 2)), 3, 0, 0 }, /* ticks */ { (ASN_TAG_CLASS_APPLICATION | (4 << 2)), 4, 0, 0 } /* arbitrary */ }; -static asn_CHOICE_specifics_t asn_SPC_ApplicationSyntax_specs_1 = { +asn_CHOICE_specifics_t asn_SPC_ApplicationSyntax_specs_1 = { sizeof(struct ApplicationSyntax), offsetof(struct ApplicationSyntax, _asn_ctx), offsetof(struct ApplicationSyntax, present), sizeof(((struct ApplicationSyntax *)0)->present), asn_MAP_ApplicationSyntax_tag2el_1, 5, /* Count of tags in the map */ - 0, + 0, 0, -1 /* Extensions start */ }; asn_TYPE_descriptor_t asn_DEF_ApplicationSyntax = { "ApplicationSyntax", "ApplicationSyntax", - CHOICE_free, - CHOICE_print, - CHOICE_constraint, - CHOICE_decode_ber, - CHOICE_encode_der, - CHOICE_decode_xer, - CHOICE_encode_xer, - 0, 0, /* No PER support, use "-gen-PER" to enable */ - CHOICE_outmost_tag, + &asn_OP_CHOICE, 0, /* No effective tags (pointer) */ 0, /* No effective tags (count) */ 0, /* No tags (pointer) */ 0, /* No tags (count) */ - 0, /* No PER visible constraints */ + { &asn_OER_type_ApplicationSyntax_constr_1, &asn_PER_type_ApplicationSyntax_constr_1, CHOICE_constraint }, asn_MBR_ApplicationSyntax_1, 5, /* Elements count */ &asn_SPC_ApplicationSyntax_specs_1 /* Additional specs */ diff --git a/libs/smux/AtEntry.c b/libs/smux/AtEntry.c index 035ea40a..0e815d39 100644 --- a/libs/smux/AtEntry.c +++ b/libs/smux/AtEntry.c @@ -1,8 +1,8 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1213-MIB" * found in "RFC1213-MIB.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #include "AtEntry.h" @@ -12,27 +12,27 @@ static asn_TYPE_member_t asn_MBR_AtEntry_1[] = { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, &asn_DEF_INTEGER, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "atIfIndex" }, { ATF_NOFLAGS, 0, offsetof(struct AtEntry, atPhysAddress), (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), 0, &asn_DEF_PhysAddress, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "atPhysAddress" }, { ATF_NOFLAGS, 0, offsetof(struct AtEntry, atNetAddress), -1 /* Ambiguous tag (CHOICE?) */, 0, &asn_DEF_NetworkAddress, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "atNetAddress" }, }; @@ -50,28 +50,19 @@ static asn_SEQUENCE_specifics_t asn_SPC_AtEntry_specs_1 = { asn_MAP_AtEntry_tag2el_1, 3, /* Count of tags in the map */ 0, 0, 0, /* Optional elements (not needed) */ - -1, /* Start extensions */ - -1 /* Stop extensions */ + -1, /* First extension addition */ }; asn_TYPE_descriptor_t asn_DEF_AtEntry = { "AtEntry", "AtEntry", - SEQUENCE_free, - SEQUENCE_print, - SEQUENCE_constraint, - SEQUENCE_decode_ber, - SEQUENCE_encode_der, - SEQUENCE_decode_xer, - SEQUENCE_encode_xer, - 0, 0, /* No PER support, use "-gen-PER" to enable */ - 0, /* Use generic outmost tag fetcher */ + &asn_OP_SEQUENCE, asn_DEF_AtEntry_tags_1, sizeof(asn_DEF_AtEntry_tags_1) /sizeof(asn_DEF_AtEntry_tags_1[0]), /* 1 */ asn_DEF_AtEntry_tags_1, /* Same as above */ sizeof(asn_DEF_AtEntry_tags_1) /sizeof(asn_DEF_AtEntry_tags_1[0]), /* 1 */ - 0, /* No PER visible constraints */ + { 0, 0, SEQUENCE_constraint }, asn_MBR_AtEntry_1, 3, /* Elements count */ &asn_SPC_AtEntry_specs_1 /* Additional specs */ diff --git a/libs/smux/BIT_STRING.c b/libs/smux/BIT_STRING.c index 997ff416..0cff7706 100644 --- a/libs/smux/BIT_STRING.c +++ b/libs/smux/BIT_STRING.c @@ -12,42 +12,58 @@ static const ber_tlv_tag_t asn_DEF_BIT_STRING_tags[] = { (ASN_TAG_CLASS_UNIVERSAL | (3 << 2)) }; -static asn_OCTET_STRING_specifics_t asn_DEF_BIT_STRING_specs = { +asn_OCTET_STRING_specifics_t asn_SPC_BIT_STRING_specs = { sizeof(BIT_STRING_t), offsetof(BIT_STRING_t, _asn_ctx), ASN_OSUBV_BIT }; -asn_TYPE_descriptor_t asn_DEF_BIT_STRING = { - "BIT STRING", - "BIT_STRING", +asn_TYPE_operation_t asn_OP_BIT_STRING = { OCTET_STRING_free, /* Implemented in terms of OCTET STRING */ BIT_STRING_print, - BIT_STRING_constraint, + BIT_STRING_compare, OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */ OCTET_STRING_encode_der, /* Implemented in terms of OCTET STRING */ OCTET_STRING_decode_xer_binary, BIT_STRING_encode_xer, - OCTET_STRING_decode_uper, /* Unaligned PER decoder */ - OCTET_STRING_encode_uper, /* Unaligned PER encoder */ - 0, /* Use generic outmost tag fetcher */ +#ifdef ASN_DISABLE_OER_SUPPORT + 0, + 0, +#else + BIT_STRING_decode_oer, + BIT_STRING_encode_oer, +#endif /* ASN_DISABLE_OER_SUPPORT */ +#ifdef ASN_DISABLE_PER_SUPPORT + 0, + 0, +#else + BIT_STRING_decode_uper, /* Unaligned PER decoder */ + BIT_STRING_encode_uper, /* Unaligned PER encoder */ +#endif /* ASN_DISABLE_PER_SUPPORT */ + BIT_STRING_random_fill, + 0 /* Use generic outmost tag fetcher */ +}; +asn_TYPE_descriptor_t asn_DEF_BIT_STRING = { + "BIT STRING", + "BIT_STRING", + &asn_OP_BIT_STRING, asn_DEF_BIT_STRING_tags, sizeof(asn_DEF_BIT_STRING_tags) / sizeof(asn_DEF_BIT_STRING_tags[0]), asn_DEF_BIT_STRING_tags, /* Same as above */ sizeof(asn_DEF_BIT_STRING_tags) / sizeof(asn_DEF_BIT_STRING_tags[0]), - 0, /* No PER visible constraints */ + { 0, 0, BIT_STRING_constraint }, 0, 0, /* No members */ - &asn_DEF_BIT_STRING_specs + &asn_SPC_BIT_STRING_specs }; /* * BIT STRING generic constraint. */ int -BIT_STRING_constraint(asn_TYPE_descriptor_t *td, const void *sptr, - asn_app_constraint_failed_f *ctfailcb, void *app_key) { - const BIT_STRING_t *st = (const BIT_STRING_t *)sptr; +BIT_STRING_constraint(const asn_TYPE_descriptor_t *td, const void *sptr, + asn_app_constraint_failed_f *ctfailcb, void *app_key) { + const BIT_STRING_t *st = (const BIT_STRING_t *)sptr; if(st && st->buf) { if((st->size == 0 && st->bits_unused) @@ -67,16 +83,16 @@ BIT_STRING_constraint(asn_TYPE_descriptor_t *td, const void *sptr, return 0; } -static char *_bit_pattern[16] = { +static const char *_bit_pattern[16] = { "0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111" }; asn_enc_rval_t -BIT_STRING_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, - int ilevel, enum xer_encoder_flags_e flags, - asn_app_consume_bytes_f *cb, void *app_key) { - asn_enc_rval_t er; +BIT_STRING_encode_xer(const asn_TYPE_descriptor_t *td, const void *sptr, + int ilevel, enum xer_encoder_flags_e flags, + asn_app_consume_bytes_f *cb, void *app_key) { + asn_enc_rval_t er; char scratch[128]; char *p = scratch; char *scend = scratch + (sizeof(scratch) - 10); @@ -100,7 +116,6 @@ BIT_STRING_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, int v = *buf; int nline = xcan?0:(((buf - st->buf) % 8) == 0); if(p >= scend || nline) { - er.encoded += p - scratch; ASN__CALLBACK(scratch, p - scratch); p = scratch; if(nline) ASN__TEXT_INDENT(1, ilevel); @@ -112,7 +127,6 @@ BIT_STRING_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, if(!xcan && ((buf - st->buf) % 8) == 0) ASN__TEXT_INDENT(1, ilevel); - er.encoded += p - scratch; ASN__CALLBACK(scratch, p - scratch); p = scratch; @@ -122,7 +136,6 @@ BIT_STRING_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, int i; for(i = 7; i >= ubits; i--) *p++ = (v & (1 << i)) ? 0x31 : 0x30; - er.encoded += p - scratch; ASN__CALLBACK(scratch, p - scratch); } @@ -138,9 +151,9 @@ cb_failed: * BIT STRING specific contents printer. */ int -BIT_STRING_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel, - asn_app_consume_bytes_f *cb, void *app_key) { - const char * const h2c = "0123456789ABCDEF"; +BIT_STRING_print(const asn_TYPE_descriptor_t *td, const void *sptr, int ilevel, + asn_app_consume_bytes_f *cb, void *app_key) { + const char * const h2c = "0123456789ABCDEF"; char scratch[64]; const BIT_STRING_t *st = (const BIT_STRING_t *)sptr; uint8_t *buf; @@ -184,6 +197,456 @@ BIT_STRING_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel, return -1; } + if(st->bits_unused) { + int ret = snprintf(scratch, sizeof(scratch), " (%d bit%s unused)", + st->bits_unused, st->bits_unused == 1 ? "" : "s"); + assert(ret > 0 && ret < (ssize_t)sizeof(scratch)); + if(ret > 0 && ret < (ssize_t)sizeof(scratch) + && cb(scratch, ret, app_key) < 0) + return -1; + } + return 0; } +/* + * Non-destructively remove the trailing 0-bits from the given bit string. + */ +static const BIT_STRING_t * +BIT_STRING__compactify(const BIT_STRING_t *st, BIT_STRING_t *tmp) { + const uint8_t *b; + union { + const uint8_t *c_buf; + uint8_t *nc_buf; + } unconst; + + if(st->size == 0) { + assert(st->bits_unused == 0); + return st; + } else { + for(b = &st->buf[st->size - 1]; b > st->buf && *b == 0; b--) { + ; + } + /* b points to the last byte which may contain data */ + if(*b) { + int unused = 7; + uint8_t v = *b; + v &= -(int8_t)v; + if(v & 0x0F) unused -= 4; + if(v & 0x33) unused -= 2; + if(v & 0x55) unused -= 1; + tmp->size = b-st->buf + 1; + tmp->bits_unused = unused; + } else { + tmp->size = b-st->buf; + tmp->bits_unused = 0; + } + + assert(b >= st->buf); + } + + unconst.c_buf = st->buf; + tmp->buf = unconst.nc_buf; + return tmp; +} + +/* + * Lexicographically compare the common prefix of both strings, + * and if it is the same return -1 for the smallest string. + */ +int +BIT_STRING_compare(const asn_TYPE_descriptor_t *td, const void *aptr, + const void *bptr) { + /* + * Remove information about trailing bits, since + * X.680 (08/2015) #22.7 "ensure that different semantics are not" + * "associated with [values that differ only in] the trailing 0 bits." + */ + BIT_STRING_t compact_a, compact_b; + const BIT_STRING_t *a = BIT_STRING__compactify(aptr, &compact_a); + const BIT_STRING_t *b = BIT_STRING__compactify(bptr, &compact_b); + const asn_OCTET_STRING_specifics_t *specs = td->specifics; + + assert(specs && specs->subvariant == ASN_OSUBV_BIT); + + if(a && b) { + size_t common_prefix_size = a->size <= b->size ? a->size : b->size; + int ret = memcmp(a->buf, b->buf, common_prefix_size); + if(ret == 0) { + /* Figure out which string with equal prefixes is longer. */ + if(a->size < b->size) { + return -1; + } else if(a->size > b->size) { + return 1; + } else { + /* Figure out how many unused bits */ + if(a->bits_unused > b->bits_unused) { + return -1; + } else if(a->bits_unused < b->bits_unused) { + return 1; + } else { + return 0; + } + } + } else { + return ret; + } + } else if(!a && !b) { + return 0; + } else if(!a) { + return -1; + } else { + return 1; + } +} + +#ifndef ASN_DISABLE_PER_SUPPORT + +#undef RETURN +#define RETURN(_code) \ + do { \ + asn_dec_rval_t tmprval; \ + tmprval.code = _code; \ + tmprval.consumed = consumed_myself; \ + return tmprval; \ + } while(0) + +static asn_per_constraint_t asn_DEF_BIT_STRING_constraint_size = { + APC_SEMI_CONSTRAINED, -1, -1, 0, 0}; + +asn_dec_rval_t +BIT_STRING_decode_uper(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, void **sptr, + asn_per_data_t *pd) { + const asn_OCTET_STRING_specifics_t *specs = td->specifics + ? (const asn_OCTET_STRING_specifics_t *)td->specifics + : &asn_SPC_BIT_STRING_specs; + const asn_per_constraints_t *pc = + constraints ? constraints : td->encoding_constraints.per_constraints; + const asn_per_constraint_t *csiz; + asn_dec_rval_t rval = { RC_OK, 0 }; + BIT_STRING_t *st = (BIT_STRING_t *)*sptr; + ssize_t consumed_myself = 0; + int repeat; + + (void)opt_codec_ctx; + + if(pc) { + csiz = &pc->size; + } else { + csiz = &asn_DEF_BIT_STRING_constraint_size; + } + + if(specs->subvariant != ASN_OSUBV_BIT) { + ASN_DEBUG("Subvariant %d is not BIT OSUBV_BIT", specs->subvariant); + RETURN(RC_FAIL); + } + + /* + * Allocate the string. + */ + if(!st) { + st = (BIT_STRING_t *)(*sptr = CALLOC(1, specs->struct_size)); + if(!st) RETURN(RC_FAIL); + } + + ASN_DEBUG("PER Decoding %s size %ld .. %ld bits %d", + csiz->flags & APC_EXTENSIBLE ? "extensible" : "non-extensible", + csiz->lower_bound, csiz->upper_bound, csiz->effective_bits); + + if(csiz->flags & APC_EXTENSIBLE) { + int inext = per_get_few_bits(pd, 1); + if(inext < 0) RETURN(RC_WMORE); + if(inext) { + csiz = &asn_DEF_BIT_STRING_constraint_size; + } + } + + if(csiz->effective_bits >= 0) { + FREEMEM(st->buf); + st->size = (csiz->upper_bound + 7) >> 3; + st->buf = (uint8_t *)MALLOC(st->size + 1); + if(!st->buf) { st->size = 0; RETURN(RC_FAIL); } + } + + /* X.691, #16.5: zero-length encoding */ + /* X.691, #16.6: short fixed length encoding (up to 2 octets) */ + /* X.691, #16.7: long fixed length encoding (up to 64K octets) */ + if(csiz->effective_bits == 0) { + int ret; + ASN_DEBUG("Encoding BIT STRING size %ld", csiz->upper_bound); + ret = per_get_many_bits(pd, st->buf, 0, csiz->upper_bound); + if(ret < 0) RETURN(RC_WMORE); + consumed_myself += csiz->upper_bound; + st->buf[st->size] = 0; + st->bits_unused = (8 - (csiz->upper_bound & 0x7)) & 0x7; + RETURN(RC_OK); + } + + st->size = 0; + do { + ssize_t raw_len; + ssize_t len_bytes; + ssize_t len_bits; + void *p; + int ret; + + /* Get the PER length */ + raw_len = uper_get_length(pd, csiz->effective_bits, csiz->lower_bound, + &repeat); + if(raw_len < 0) RETURN(RC_WMORE); + if(raw_len == 0 && st->buf) break; + + ASN_DEBUG("Got PER length eb %ld, len %ld, %s (%s)", + (long)csiz->effective_bits, (long)raw_len, + repeat ? "repeat" : "once", td->name); + len_bits = raw_len; + len_bytes = (len_bits + 7) >> 3; + if(len_bits & 0x7) st->bits_unused = 8 - (len_bits & 0x7); + /* len_bits be multiple of 16K if repeat is set */ + p = REALLOC(st->buf, st->size + len_bytes + 1); + if(!p) RETURN(RC_FAIL); + st->buf = (uint8_t *)p; + + ret = per_get_many_bits(pd, &st->buf[st->size], 0, len_bits); + if(ret < 0) RETURN(RC_WMORE); + st->size += len_bytes; + } while(repeat); + st->buf[st->size] = 0; /* nul-terminate */ + + return rval; +} + +asn_enc_rval_t +BIT_STRING_encode_uper(const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, + const void *sptr, asn_per_outp_t *po) { + const asn_OCTET_STRING_specifics_t *specs = + td->specifics ? (const asn_OCTET_STRING_specifics_t *)td->specifics + : &asn_SPC_BIT_STRING_specs; + const asn_per_constraints_t *pc = + constraints ? constraints : td->encoding_constraints.per_constraints; + const asn_per_constraint_t *csiz; + const BIT_STRING_t *st = (const BIT_STRING_t *)sptr; + BIT_STRING_t compact_bstr; /* Do not modify this directly! */ + asn_enc_rval_t er = { 0, 0, 0 }; + int inext = 0; /* Lies not within extension root */ + size_t size_in_bits; + const uint8_t *buf; + int ret; + int ct_extensible; + + if(!st || (!st->buf && st->size)) + ASN__ENCODE_FAILED; + + if(specs->subvariant == ASN_OSUBV_BIT) { + if((st->size == 0 && st->bits_unused) || (st->bits_unused & ~7)) + ASN__ENCODE_FAILED; + } else { + ASN__ENCODE_FAILED; + } + + if(pc) { + csiz = &pc->size; + } else { + csiz = &asn_DEF_BIT_STRING_constraint_size; + } + ct_extensible = csiz->flags & APC_EXTENSIBLE; + + /* Figure out the size without the trailing bits */ + st = BIT_STRING__compactify(st, &compact_bstr); + size_in_bits = 8 * st->size - st->bits_unused; + + ASN_DEBUG( + "Encoding %s into %" ASN_PRI_SIZE " bits" + " (%ld..%ld, effective %d)%s", + td->name, size_in_bits, csiz->lower_bound, csiz->upper_bound, + csiz->effective_bits, ct_extensible ? " EXT" : ""); + + /* Figure out whether size lies within PER visible constraint */ + + if(csiz->effective_bits >= 0) { + if((ssize_t)size_in_bits > csiz->upper_bound) { + if(ct_extensible) { + csiz = &asn_DEF_BIT_STRING_constraint_size; + inext = 1; + } else { + ASN__ENCODE_FAILED; + } + } + } else { + inext = 0; + } + + if(ct_extensible) { + /* Declare whether length is [not] within extension root */ + if(per_put_few_bits(po, inext, 1)) + ASN__ENCODE_FAILED; + } + + if(csiz->effective_bits >= 0 && !inext) { + int add_trailer = (ssize_t)size_in_bits < csiz->lower_bound; + ASN_DEBUG( + "Encoding %" ASN_PRI_SIZE " bytes (%ld), length (in %d bits) trailer %d; actual " + "value %" ASN_PRI_SSIZE "", + st->size, size_in_bits - csiz->lower_bound, csiz->effective_bits, + add_trailer, + add_trailer ? 0 : (ssize_t)size_in_bits - csiz->lower_bound); + ret = per_put_few_bits( + po, add_trailer ? 0 : (ssize_t)size_in_bits - csiz->lower_bound, + csiz->effective_bits); + if(ret) ASN__ENCODE_FAILED; + ret = per_put_many_bits(po, st->buf, size_in_bits); + if(ret) ASN__ENCODE_FAILED; + if(add_trailer) { + static const uint8_t zeros[16]; + size_t trailing_zero_bits = csiz->lower_bound - size_in_bits; + while(trailing_zero_bits > 0) { + if(trailing_zero_bits > 8 * sizeof(zeros)) { + ret = per_put_many_bits(po, zeros, 8 * sizeof(zeros)); + trailing_zero_bits -= 8 * sizeof(zeros); + } else { + ret = per_put_many_bits(po, zeros, trailing_zero_bits); + trailing_zero_bits = 0; + } + if(ret) ASN__ENCODE_FAILED; + } + } + ASN__ENCODED_OK(er); + } + + ASN_DEBUG("Encoding %" ASN_PRI_SIZE " bytes", st->size); + + buf = st->buf; + do { + int need_eom = 0; + ssize_t maySave = uper_put_length(po, size_in_bits, &need_eom); + if(maySave < 0) ASN__ENCODE_FAILED; + + ASN_DEBUG("Encoding %" ASN_PRI_SSIZE " of %" ASN_PRI_SIZE "", maySave, size_in_bits); + + ret = per_put_many_bits(po, buf, maySave); + if(ret) ASN__ENCODE_FAILED; + + buf += maySave >> 3; + size_in_bits -= maySave; + assert(!(maySave & 0x07) || !size_in_bits); + if(need_eom && uper_put_length(po, 0, 0)) + ASN__ENCODE_FAILED; /* End of Message length */ + } while(size_in_bits); + + ASN__ENCODED_OK(er); +} + +#endif /* ASN_DISABLE_PER_SUPPORT */ + +asn_random_fill_result_t +BIT_STRING_random_fill(const asn_TYPE_descriptor_t *td, void **sptr, + const asn_encoding_constraints_t *constraints, + size_t max_length) { + const asn_OCTET_STRING_specifics_t *specs = + td->specifics ? (const asn_OCTET_STRING_specifics_t *)td->specifics + : &asn_SPC_BIT_STRING_specs; + asn_random_fill_result_t result_ok = {ARFILL_OK, 1}; + asn_random_fill_result_t result_failed = {ARFILL_FAILED, 0}; + asn_random_fill_result_t result_skipped = {ARFILL_SKIPPED, 0}; + static unsigned lengths[] = {0, 1, 2, 3, 4, 8, + 126, 127, 128, 16383, 16384, 16385, + 65534, 65535, 65536, 65537}; + uint8_t *buf; + uint8_t *bend; + uint8_t *b; + size_t rnd_bits, rnd_len; + BIT_STRING_t *st; + + if(max_length == 0) return result_skipped; + + switch(specs->subvariant) { + case ASN_OSUBV_ANY: + return result_failed; + case ASN_OSUBV_BIT: + break; + default: + break; + } + + /* Figure out how far we should go */ + rnd_bits = lengths[asn_random_between( + 0, sizeof(lengths) / sizeof(lengths[0]) - 1)]; + if(!constraints || !constraints->per_constraints) + constraints = &td->encoding_constraints; + if(constraints->per_constraints) { + const asn_per_constraint_t *pc = &constraints->per_constraints->size; + if(pc->flags & APC_CONSTRAINED) { + long suggested_upper_bound = pc->upper_bound < (ssize_t)max_length + ? pc->upper_bound + : (ssize_t)max_length; + if(max_length < (size_t)pc->lower_bound) { + return result_skipped; + } + if(pc->flags & APC_EXTENSIBLE) { + switch(asn_random_between(0, 5)) { + case 0: + if(pc->lower_bound > 0) { + rnd_bits = pc->lower_bound - 1; + break; + } + /* Fall through */ + case 1: + rnd_bits = pc->upper_bound + 1; + break; + case 2: + /* Keep rnd_bits from the table */ + if(rnd_bits < max_length) { + break; + } + /* Fall through */ + default: + rnd_bits = asn_random_between(pc->lower_bound, + suggested_upper_bound); + } + } else { + rnd_bits = + asn_random_between(pc->lower_bound, suggested_upper_bound); + } + } else { + rnd_bits = asn_random_between(0, max_length - 1); + } + } else if(rnd_bits >= max_length) { + rnd_bits = asn_random_between(0, max_length - 1); + } + + rnd_len = (rnd_bits + 7) / 8; + buf = CALLOC(1, rnd_len + 1); + if(!buf) return result_failed; + + bend = &buf[rnd_len]; + + for(b = buf; b < bend; b++) { + *(uint8_t *)b = asn_random_between(0, 255); + } + *b = 0; /* Zero-terminate just in case. */ + + if(*sptr) { + st = *sptr; + FREEMEM(st->buf); + } else { + st = (BIT_STRING_t *)(*sptr = CALLOC(1, specs->struct_size)); + if(!st) { + FREEMEM(buf); + return result_failed; + } + } + + st->buf = buf; + st->size = rnd_len; + st->bits_unused = (8 - (rnd_bits & 0x7)) & 0x7; + if(st->bits_unused) { + assert(st->size > 0); + st->buf[st->size-1] &= 0xff << st->bits_unused; + } + + result_ok.length = st->size; + return result_ok; +} diff --git a/libs/smux/BIT_STRING_oer.c b/libs/smux/BIT_STRING_oer.c new file mode 100644 index 00000000..aff5075c --- /dev/null +++ b/libs/smux/BIT_STRING_oer.c @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2017 Lev Walkin . + * All rights reserved. + * Redistribution and modifications are permitted subject to BSD license. + */ +#ifndef ASN_DISABLE_OER_SUPPORT + +#include +#include +#include + +asn_dec_rval_t +BIT_STRING_decode_oer(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *td, + const asn_oer_constraints_t *constraints, void **sptr, + const void *ptr, size_t size) { + BIT_STRING_t *st = (BIT_STRING_t *)*sptr; + const asn_oer_constraints_t *cts = + constraints ? constraints : td->encoding_constraints.oer_constraints; + ssize_t ct_size = cts ? cts->size : -1; + asn_dec_rval_t rval = {RC_OK, 0}; + size_t expected_length = 0; + + (void)opt_codec_ctx; + + if(!st) { + st = (BIT_STRING_t *)(*sptr = CALLOC(1, sizeof(*st))); + if(!st) ASN__DECODE_FAILED; + } + + if(ct_size >= 0) { + expected_length = (ct_size + 7) >> 3; + st->bits_unused = (8 - (ct_size & 7)) & 7; + } else { + /* + * X.696 (08/2015) #13.3.1 + * Encode length determinant as _number of octets_, but only + * if upper bound is not equal to lower bound. + */ + ssize_t len_len = oer_fetch_length(ptr, size, &expected_length); + if(len_len > 0) { + ptr = (const char *)ptr + len_len; + size -= len_len; + } else if(len_len == 0) { + ASN__DECODE_STARVED; + } else if(len_len < 0) { + ASN__DECODE_FAILED; + } + + if(expected_length < 1) { + ASN__DECODE_FAILED; + } else if(expected_length > size) { + ASN__DECODE_STARVED; + } + + st->bits_unused = ((const uint8_t *)ptr)[0]; + if(st->bits_unused & ~7) { + ASN_DEBUG("%s: unused bits outside of 0..7 range", td->name); + ASN__DECODE_FAILED; + } + ptr = (const char *)ptr + 1; + size--; + expected_length--; + rval.consumed = len_len + 1; + } + + if(size < expected_length) { + ASN__DECODE_STARVED; + } else { + uint8_t *buf = MALLOC(expected_length + 1); + if(buf == NULL) { + ASN__DECODE_FAILED; + } else { + memcpy(buf, ptr, expected_length); + buf[expected_length] = '\0'; + } + FREEMEM(st->buf); + st->buf = buf; + st->size = expected_length; + if(expected_length > 0) { + buf[expected_length - 1] &= (0xff << st->bits_unused); + } + + rval.consumed += expected_length; + return rval; + } +} + +/* + * Encode as Canonical OER. + */ +asn_enc_rval_t +BIT_STRING_encode_oer(const asn_TYPE_descriptor_t *td, + const asn_oer_constraints_t *constraints, + const void *sptr, asn_app_consume_bytes_f *cb, + void *app_key) { + const BIT_STRING_t *st = (const BIT_STRING_t *)sptr; + asn_enc_rval_t erval = {0, 0, 0}; + const asn_oer_constraints_t *cts = + constraints ? constraints : td->encoding_constraints.oer_constraints; + ssize_t ct_size = cts ? cts->size : -1; + size_t trailing_zeros = 0; + int fix_last_byte = 0; + + if(!st) ASN__ENCODE_FAILED; + + if(st->bits_unused & ~7) { + ASN_DEBUG("BIT STRING unused bits %d out of 0..7 range", + st->bits_unused); + ASN__ENCODE_FAILED; + } + if(st->bits_unused && !(st->size && st->buf)) { + ASN_DEBUG("BIT STRING %s size 0 can't support unused bits %d", td->name, + st->bits_unused); + ASN__ENCODE_FAILED; + } + + if(ct_size >= 0) { + size_t ct_bytes = (ct_size + 7) >> 3; + if(st->size > ct_bytes) { + ASN_DEBUG("More bits in BIT STRING %s (%" ASN_PRI_SSIZE ") than constrained %" ASN_PRI_SSIZE "", + td->name, 8 * st->size - st->bits_unused, ct_size); + ASN__ENCODE_FAILED; + } + trailing_zeros = ct_bytes - st->size; /* Allow larger constraint */ + } else { + uint8_t ub = st->bits_unused & 7; + ssize_t len_len = oer_serialize_length(1 + st->size, cb, app_key); + if(len_len < 0) ASN__ENCODE_FAILED; + if(cb(&ub, 1, app_key) < 0) { + ASN__ENCODE_FAILED; + } + erval.encoded += len_len + 1; + } + + if(st->bits_unused) { + if(st->buf[st->size - 1] & (0xff << st->bits_unused)) { + fix_last_byte = 1; + } + } + + if(cb(st->buf, st->size - fix_last_byte, app_key) < 0) { + ASN__ENCODE_FAILED; + } + + if(fix_last_byte) { + uint8_t b = st->buf[st->size - 1] & (0xff << st->bits_unused); + if(cb(&b, 1, app_key) < 0) { + ASN__ENCODE_FAILED; + } + } + + erval.encoded += st->size; + + if(trailing_zeros) { + static uint8_t zeros[16]; + while(trailing_zeros > 0) { + int ret; + if(trailing_zeros < sizeof(zeros)) { + ret = cb(zeros, trailing_zeros, app_key); + erval.encoded += trailing_zeros; + } else { + ret = cb(zeros, sizeof(zeros), app_key); + erval.encoded += sizeof(zeros); + } + if(ret < 0) ASN__ENCODE_FAILED; + } + } + + return erval; +} + + +#endif /* ASN_DISABLE_OER_SUPPORT */ diff --git a/libs/smux/BOOLEAN.c b/libs/smux/BOOLEAN.c deleted file mode 100644 index 6e55b3e6..00000000 --- a/libs/smux/BOOLEAN.c +++ /dev/null @@ -1,282 +0,0 @@ -/*- - * Copyright (c) 2003, 2005 Lev Walkin . All rights reserved. - * Redistribution and modifications are permitted subject to BSD license. - */ -#include -#include -#include - -/* - * BOOLEAN basic type description. - */ -static const ber_tlv_tag_t asn_DEF_BOOLEAN_tags[] = { - (ASN_TAG_CLASS_UNIVERSAL | (1 << 2)) -}; -asn_TYPE_descriptor_t asn_DEF_BOOLEAN = { - "BOOLEAN", - "BOOLEAN", - BOOLEAN_free, - BOOLEAN_print, - asn_generic_no_constraint, - BOOLEAN_decode_ber, - BOOLEAN_encode_der, - BOOLEAN_decode_xer, - BOOLEAN_encode_xer, - BOOLEAN_decode_uper, /* Unaligned PER decoder */ - BOOLEAN_encode_uper, /* Unaligned PER encoder */ - 0, /* Use generic outmost tag fetcher */ - asn_DEF_BOOLEAN_tags, - sizeof(asn_DEF_BOOLEAN_tags) / sizeof(asn_DEF_BOOLEAN_tags[0]), - asn_DEF_BOOLEAN_tags, /* Same as above */ - sizeof(asn_DEF_BOOLEAN_tags) / sizeof(asn_DEF_BOOLEAN_tags[0]), - 0, /* No PER visible constraints */ - 0, 0, /* No members */ - 0 /* No specifics */ -}; - -/* - * Decode BOOLEAN type. - */ -asn_dec_rval_t -BOOLEAN_decode_ber(asn_codec_ctx_t *opt_codec_ctx, - asn_TYPE_descriptor_t *td, - void **bool_value, const void *buf_ptr, size_t size, - int tag_mode) { - BOOLEAN_t *st = (BOOLEAN_t *)*bool_value; - asn_dec_rval_t rval; - ber_tlv_len_t length; - ber_tlv_len_t lidx; - - if(st == NULL) { - st = (BOOLEAN_t *)(*bool_value = CALLOC(1, sizeof(*st))); - if(st == NULL) { - rval.code = RC_FAIL; - rval.consumed = 0; - return rval; - } - } - - ASN_DEBUG("Decoding %s as BOOLEAN (tm=%d)", - td->name, tag_mode); - - /* - * Check tags. - */ - rval = ber_check_tags(opt_codec_ctx, td, 0, buf_ptr, size, - tag_mode, 0, &length, 0); - if(rval.code != RC_OK) - return rval; - - ASN_DEBUG("Boolean length is %d bytes", (int)length); - - buf_ptr = ((const char *)buf_ptr) + rval.consumed; - size -= rval.consumed; - if(length > (ber_tlv_len_t)size) { - rval.code = RC_WMORE; - rval.consumed = 0; - return rval; - } - - /* - * Compute boolean value. - */ - for(*st = 0, lidx = 0; - (lidx < length) && *st == 0; lidx++) { - /* - * Very simple approach: read bytes until the end or - * value is already TRUE. - * BOOLEAN is not supposed to contain meaningful data anyway. - */ - *st |= ((const uint8_t *)buf_ptr)[lidx]; - } - - rval.code = RC_OK; - rval.consumed += length; - - ASN_DEBUG("Took %ld/%ld bytes to encode %s, value=%d", - (long)rval.consumed, (long)length, - td->name, *st); - - return rval; -} - -asn_enc_rval_t -BOOLEAN_encode_der(asn_TYPE_descriptor_t *td, void *sptr, - int tag_mode, ber_tlv_tag_t tag, - asn_app_consume_bytes_f *cb, void *app_key) { - asn_enc_rval_t erval; - BOOLEAN_t *st = (BOOLEAN_t *)sptr; - - erval.encoded = der_write_tags(td, 1, tag_mode, 0, tag, cb, app_key); - if(erval.encoded == -1) { - erval.failed_type = td; - erval.structure_ptr = sptr; - return erval; - } - - if(cb) { - uint8_t bool_value; - - bool_value = *st ? 0xff : 0; /* 0xff mandated by DER */ - - if(cb(&bool_value, 1, app_key) < 0) { - erval.encoded = -1; - erval.failed_type = td; - erval.structure_ptr = sptr; - return erval; - } - } - - erval.encoded += 1; - - ASN__ENCODED_OK(erval); -} - - -/* - * Decode the chunk of XML text encoding INTEGER. - */ -static enum xer_pbd_rval -BOOLEAN__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const void *chunk_buf, size_t chunk_size) { - BOOLEAN_t *st = (BOOLEAN_t *)sptr; - const char *p = (const char *)chunk_buf; - - (void)td; - - if(chunk_size && p[0] == 0x3c /* '<' */) { - switch(xer_check_tag(chunk_buf, chunk_size, "false")) { - case XCT_BOTH: - /* "" */ - *st = 0; - break; - case XCT_UNKNOWN_BO: - if(xer_check_tag(chunk_buf, chunk_size, "true") - != XCT_BOTH) - return XPBD_BROKEN_ENCODING; - /* "" */ - *st = 1; /* Or 0xff as in DER?.. */ - break; - default: - return XPBD_BROKEN_ENCODING; - } - return XPBD_BODY_CONSUMED; - } else { - return XPBD_BROKEN_ENCODING; - } -} - - -asn_dec_rval_t -BOOLEAN_decode_xer(asn_codec_ctx_t *opt_codec_ctx, - asn_TYPE_descriptor_t *td, void **sptr, const char *opt_mname, - const void *buf_ptr, size_t size) { - - return xer_decode_primitive(opt_codec_ctx, td, - sptr, sizeof(BOOLEAN_t), opt_mname, buf_ptr, size, - BOOLEAN__xer_body_decode); -} - -asn_enc_rval_t -BOOLEAN_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, - int ilevel, enum xer_encoder_flags_e flags, - asn_app_consume_bytes_f *cb, void *app_key) { - const BOOLEAN_t *st = (const BOOLEAN_t *)sptr; - asn_enc_rval_t er; - - (void)ilevel; - (void)flags; - - if(!st) ASN__ENCODE_FAILED; - - if(*st) { - ASN__CALLBACK("", 7); - er.encoded = 7; - } else { - ASN__CALLBACK("", 8); - er.encoded = 8; - } - - ASN__ENCODED_OK(er); -cb_failed: - ASN__ENCODE_FAILED; -} - -int -BOOLEAN_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel, - asn_app_consume_bytes_f *cb, void *app_key) { - const BOOLEAN_t *st = (const BOOLEAN_t *)sptr; - const char *buf; - size_t buflen; - - (void)td; /* Unused argument */ - (void)ilevel; /* Unused argument */ - - if(st) { - if(*st) { - buf = "TRUE"; - buflen = 4; - } else { - buf = "FALSE"; - buflen = 5; - } - } else { - buf = ""; - buflen = 8; - } - - return (cb(buf, buflen, app_key) < 0) ? -1 : 0; -} - -void -BOOLEAN_free(asn_TYPE_descriptor_t *td, void *ptr, int contents_only) { - if(td && ptr && !contents_only) { - FREEMEM(ptr); - } -} - -asn_dec_rval_t -BOOLEAN_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, - asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { - asn_dec_rval_t rv; - BOOLEAN_t *st = (BOOLEAN_t *)*sptr; - - (void)opt_codec_ctx; - (void)constraints; - - if(!st) { - st = (BOOLEAN_t *)(*sptr = MALLOC(sizeof(*st))); - if(!st) ASN__DECODE_FAILED; - } - - /* - * Extract a single bit - */ - switch(per_get_few_bits(pd, 1)) { - case 1: *st = 1; break; - case 0: *st = 0; break; - case -1: default: ASN__DECODE_STARVED; - } - - ASN_DEBUG("%s decoded as %s", td->name, *st ? "TRUE" : "FALSE"); - - rv.code = RC_OK; - rv.consumed = 1; - return rv; -} - - -asn_enc_rval_t -BOOLEAN_encode_uper(asn_TYPE_descriptor_t *td, - asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { - const BOOLEAN_t *st = (const BOOLEAN_t *)sptr; - asn_enc_rval_t er = { 0, 0, 0 }; - - (void)constraints; - - if(!st) ASN__ENCODE_FAILED; - - if(per_put_few_bits(po, *st ? 1 : 0, 1)) - ASN__ENCODE_FAILED; - - ASN__ENCODED_OK(er); -} diff --git a/libs/smux/ClosePDU.c b/libs/smux/ClosePDU.c index ce9745d7..b58b0253 100644 --- a/libs/smux/ClosePDU.c +++ b/libs/smux/ClosePDU.c @@ -1,86 +1,16 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "SMUX" * found in "SMUX.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #include "ClosePDU.h" -int -ClosePDU_constraint(asn_TYPE_descriptor_t *td, const void *sptr, - asn_app_constraint_failed_f *ctfailcb, void *app_key) { - /* Replace with underlying type checker */ - td->check_constraints = asn_DEF_INTEGER.check_constraints; - return td->check_constraints(td, sptr, ctfailcb, app_key); -} - /* * This type is implemented using INTEGER, * so here we adjust the DEF accordingly. */ -static void -ClosePDU_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) { - td->free_struct = asn_DEF_INTEGER.free_struct; - td->print_struct = asn_DEF_INTEGER.print_struct; - td->check_constraints = asn_DEF_INTEGER.check_constraints; - td->ber_decoder = asn_DEF_INTEGER.ber_decoder; - td->der_encoder = asn_DEF_INTEGER.der_encoder; - td->xer_decoder = asn_DEF_INTEGER.xer_decoder; - td->xer_encoder = asn_DEF_INTEGER.xer_encoder; - td->uper_decoder = asn_DEF_INTEGER.uper_decoder; - td->uper_encoder = asn_DEF_INTEGER.uper_encoder; - if(!td->per_constraints) - td->per_constraints = asn_DEF_INTEGER.per_constraints; - td->elements = asn_DEF_INTEGER.elements; - td->elements_count = asn_DEF_INTEGER.elements_count; - td->specifics = asn_DEF_INTEGER.specifics; -} - -void -ClosePDU_free(asn_TYPE_descriptor_t *td, - void *struct_ptr, int contents_only) { - ClosePDU_1_inherit_TYPE_descriptor(td); - td->free_struct(td, struct_ptr, contents_only); -} - -int -ClosePDU_print(asn_TYPE_descriptor_t *td, const void *struct_ptr, - int ilevel, asn_app_consume_bytes_f *cb, void *app_key) { - ClosePDU_1_inherit_TYPE_descriptor(td); - return td->print_struct(td, struct_ptr, ilevel, cb, app_key); -} - -asn_dec_rval_t -ClosePDU_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, - void **structure, const void *bufptr, size_t size, int tag_mode) { - ClosePDU_1_inherit_TYPE_descriptor(td); - return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode); -} - -asn_enc_rval_t -ClosePDU_encode_der(asn_TYPE_descriptor_t *td, - void *structure, int tag_mode, ber_tlv_tag_t tag, - asn_app_consume_bytes_f *cb, void *app_key) { - ClosePDU_1_inherit_TYPE_descriptor(td); - return td->der_encoder(td, structure, tag_mode, tag, cb, app_key); -} - -asn_dec_rval_t -ClosePDU_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, - void **structure, const char *opt_mname, const void *bufptr, size_t size) { - ClosePDU_1_inherit_TYPE_descriptor(td); - return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size); -} - -asn_enc_rval_t -ClosePDU_encode_xer(asn_TYPE_descriptor_t *td, void *structure, - int ilevel, enum xer_encoder_flags_e flags, - asn_app_consume_bytes_f *cb, void *app_key) { - ClosePDU_1_inherit_TYPE_descriptor(td); - return td->xer_encoder(td, structure, ilevel, flags, cb, app_key); -} - static const ber_tlv_tag_t asn_DEF_ClosePDU_tags_1[] = { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)) @@ -88,22 +18,14 @@ static const ber_tlv_tag_t asn_DEF_ClosePDU_tags_1[] = { asn_TYPE_descriptor_t asn_DEF_ClosePDU = { "ClosePDU", "ClosePDU", - ClosePDU_free, - ClosePDU_print, - ClosePDU_constraint, - ClosePDU_decode_ber, - ClosePDU_encode_der, - ClosePDU_decode_xer, - ClosePDU_encode_xer, - 0, 0, /* No PER support, use "-gen-PER" to enable */ - 0, /* Use generic outmost tag fetcher */ + &asn_OP_INTEGER, asn_DEF_ClosePDU_tags_1, sizeof(asn_DEF_ClosePDU_tags_1) /sizeof(asn_DEF_ClosePDU_tags_1[0]) - 1, /* 1 */ asn_DEF_ClosePDU_tags_1, /* Same as above */ sizeof(asn_DEF_ClosePDU_tags_1) /sizeof(asn_DEF_ClosePDU_tags_1[0]), /* 2 */ - 0, /* No PER visible constraints */ + { 0, 0, INTEGER_constraint }, 0, 0, /* Defined elsewhere */ 0 /* No specifics */ }; diff --git a/libs/smux/Counter.c b/libs/smux/Counter.c index a083ee8f..e858b205 100644 --- a/libs/smux/Counter.c +++ b/libs/smux/Counter.c @@ -1,14 +1,14 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1155-SMI" * found in "RFC1155-SMI.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #include "Counter.h" int -Counter_constraint(asn_TYPE_descriptor_t *td, const void *sptr, +Counter_constraint(const asn_TYPE_descriptor_t *td, const void *sptr, asn_app_constraint_failed_f *ctfailcb, void *app_key) { if(!sptr) { @@ -27,69 +27,15 @@ Counter_constraint(asn_TYPE_descriptor_t *td, const void *sptr, * This type is implemented using NativeInteger, * so here we adjust the DEF accordingly. */ -static void -Counter_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) { - td->free_struct = asn_DEF_NativeInteger.free_struct; - td->print_struct = asn_DEF_NativeInteger.print_struct; - td->check_constraints = asn_DEF_NativeInteger.check_constraints; - td->ber_decoder = asn_DEF_NativeInteger.ber_decoder; - td->der_encoder = asn_DEF_NativeInteger.der_encoder; - td->xer_decoder = asn_DEF_NativeInteger.xer_decoder; - td->xer_encoder = asn_DEF_NativeInteger.xer_encoder; - td->uper_decoder = asn_DEF_NativeInteger.uper_decoder; - td->uper_encoder = asn_DEF_NativeInteger.uper_encoder; - if(!td->per_constraints) - td->per_constraints = asn_DEF_NativeInteger.per_constraints; - td->elements = asn_DEF_NativeInteger.elements; - td->elements_count = asn_DEF_NativeInteger.elements_count; - /* td->specifics = asn_DEF_NativeInteger.specifics; // Defined explicitly */ -} - -void -Counter_free(asn_TYPE_descriptor_t *td, - void *struct_ptr, int contents_only) { - Counter_1_inherit_TYPE_descriptor(td); - td->free_struct(td, struct_ptr, contents_only); -} - -int -Counter_print(asn_TYPE_descriptor_t *td, const void *struct_ptr, - int ilevel, asn_app_consume_bytes_f *cb, void *app_key) { - Counter_1_inherit_TYPE_descriptor(td); - return td->print_struct(td, struct_ptr, ilevel, cb, app_key); -} - -asn_dec_rval_t -Counter_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, - void **structure, const void *bufptr, size_t size, int tag_mode) { - Counter_1_inherit_TYPE_descriptor(td); - return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode); -} - -asn_enc_rval_t -Counter_encode_der(asn_TYPE_descriptor_t *td, - void *structure, int tag_mode, ber_tlv_tag_t tag, - asn_app_consume_bytes_f *cb, void *app_key) { - Counter_1_inherit_TYPE_descriptor(td); - return td->der_encoder(td, structure, tag_mode, tag, cb, app_key); -} - -asn_dec_rval_t -Counter_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, - void **structure, const char *opt_mname, const void *bufptr, size_t size) { - Counter_1_inherit_TYPE_descriptor(td); - return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size); -} - -asn_enc_rval_t -Counter_encode_xer(asn_TYPE_descriptor_t *td, void *structure, - int ilevel, enum xer_encoder_flags_e flags, - asn_app_consume_bytes_f *cb, void *app_key) { - Counter_1_inherit_TYPE_descriptor(td); - return td->xer_encoder(td, structure, ilevel, flags, cb, app_key); -} - -static const asn_INTEGER_specifics_t asn_SPC_Counter_specs_1 = { +static asn_oer_constraints_t asn_OER_type_Counter_constr_1 CC_NOTUSED = { + { 4, 1 } /* (0..4294967295) */, + -1}; +asn_per_constraints_t asn_PER_type_Counter_constr_1 CC_NOTUSED = { + { APC_CONSTRAINED, 32, -1, 0, 4294967295 } /* (0..4294967295) */, + { APC_UNCONSTRAINED, -1, -1, 0, 0 }, + 0, 0 /* No PER value map */ +}; +const asn_INTEGER_specifics_t asn_SPC_Counter_specs_1 = { 0, 0, 0, 0, 0, 0, /* Native long size */ 1 /* Unsigned representation */ @@ -101,22 +47,14 @@ static const ber_tlv_tag_t asn_DEF_Counter_tags_1[] = { asn_TYPE_descriptor_t asn_DEF_Counter = { "Counter", "Counter", - Counter_free, - Counter_print, - Counter_constraint, - Counter_decode_ber, - Counter_encode_der, - Counter_decode_xer, - Counter_encode_xer, - 0, 0, /* No PER support, use "-gen-PER" to enable */ - 0, /* Use generic outmost tag fetcher */ + &asn_OP_NativeInteger, asn_DEF_Counter_tags_1, sizeof(asn_DEF_Counter_tags_1) /sizeof(asn_DEF_Counter_tags_1[0]) - 1, /* 1 */ asn_DEF_Counter_tags_1, /* Same as above */ sizeof(asn_DEF_Counter_tags_1) /sizeof(asn_DEF_Counter_tags_1[0]), /* 2 */ - 0, /* No PER visible constraints */ + { &asn_OER_type_Counter_constr_1, &asn_PER_type_Counter_constr_1, Counter_constraint }, 0, 0, /* No members */ &asn_SPC_Counter_specs_1 /* Additional specs */ }; diff --git a/libs/smux/DisplayString.c b/libs/smux/DisplayString.c index a567799f..a868a672 100644 --- a/libs/smux/DisplayString.c +++ b/libs/smux/DisplayString.c @@ -1,109 +1,31 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1213-MIB" * found in "RFC1213-MIB.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #include "DisplayString.h" -int -DisplayString_constraint(asn_TYPE_descriptor_t *td, const void *sptr, - asn_app_constraint_failed_f *ctfailcb, void *app_key) { - /* Replace with underlying type checker */ - td->check_constraints = asn_DEF_OCTET_STRING.check_constraints; - return td->check_constraints(td, sptr, ctfailcb, app_key); -} - /* * This type is implemented using OCTET_STRING, * so here we adjust the DEF accordingly. */ -static void -DisplayString_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) { - td->free_struct = asn_DEF_OCTET_STRING.free_struct; - td->print_struct = asn_DEF_OCTET_STRING.print_struct; - td->check_constraints = asn_DEF_OCTET_STRING.check_constraints; - td->ber_decoder = asn_DEF_OCTET_STRING.ber_decoder; - td->der_encoder = asn_DEF_OCTET_STRING.der_encoder; - td->xer_decoder = asn_DEF_OCTET_STRING.xer_decoder; - td->xer_encoder = asn_DEF_OCTET_STRING.xer_encoder; - td->uper_decoder = asn_DEF_OCTET_STRING.uper_decoder; - td->uper_encoder = asn_DEF_OCTET_STRING.uper_encoder; - if(!td->per_constraints) - td->per_constraints = asn_DEF_OCTET_STRING.per_constraints; - td->elements = asn_DEF_OCTET_STRING.elements; - td->elements_count = asn_DEF_OCTET_STRING.elements_count; - td->specifics = asn_DEF_OCTET_STRING.specifics; -} - -void -DisplayString_free(asn_TYPE_descriptor_t *td, - void *struct_ptr, int contents_only) { - DisplayString_1_inherit_TYPE_descriptor(td); - td->free_struct(td, struct_ptr, contents_only); -} - -int -DisplayString_print(asn_TYPE_descriptor_t *td, const void *struct_ptr, - int ilevel, asn_app_consume_bytes_f *cb, void *app_key) { - DisplayString_1_inherit_TYPE_descriptor(td); - return td->print_struct(td, struct_ptr, ilevel, cb, app_key); -} - -asn_dec_rval_t -DisplayString_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, - void **structure, const void *bufptr, size_t size, int tag_mode) { - DisplayString_1_inherit_TYPE_descriptor(td); - return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode); -} - -asn_enc_rval_t -DisplayString_encode_der(asn_TYPE_descriptor_t *td, - void *structure, int tag_mode, ber_tlv_tag_t tag, - asn_app_consume_bytes_f *cb, void *app_key) { - DisplayString_1_inherit_TYPE_descriptor(td); - return td->der_encoder(td, structure, tag_mode, tag, cb, app_key); -} - -asn_dec_rval_t -DisplayString_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, - void **structure, const char *opt_mname, const void *bufptr, size_t size) { - DisplayString_1_inherit_TYPE_descriptor(td); - return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size); -} - -asn_enc_rval_t -DisplayString_encode_xer(asn_TYPE_descriptor_t *td, void *structure, - int ilevel, enum xer_encoder_flags_e flags, - asn_app_consume_bytes_f *cb, void *app_key) { - DisplayString_1_inherit_TYPE_descriptor(td); - return td->xer_encoder(td, structure, ilevel, flags, cb, app_key); -} - static const ber_tlv_tag_t asn_DEF_DisplayString_tags_1[] = { (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)) }; asn_TYPE_descriptor_t asn_DEF_DisplayString = { "DisplayString", "DisplayString", - DisplayString_free, - DisplayString_print, - DisplayString_constraint, - DisplayString_decode_ber, - DisplayString_encode_der, - DisplayString_decode_xer, - DisplayString_encode_xer, - 0, 0, /* No PER support, use "-gen-PER" to enable */ - 0, /* Use generic outmost tag fetcher */ + &asn_OP_OCTET_STRING, asn_DEF_DisplayString_tags_1, sizeof(asn_DEF_DisplayString_tags_1) /sizeof(asn_DEF_DisplayString_tags_1[0]), /* 1 */ asn_DEF_DisplayString_tags_1, /* Same as above */ sizeof(asn_DEF_DisplayString_tags_1) /sizeof(asn_DEF_DisplayString_tags_1[0]), /* 1 */ - 0, /* No PER visible constraints */ + { 0, 0, OCTET_STRING_constraint }, 0, 0, /* No members */ - 0 /* No specifics */ + &asn_SPC_OCTET_STRING_specs /* Additional specs */ }; diff --git a/libs/smux/EgpNeighEntry.c b/libs/smux/EgpNeighEntry.c index b12c489f..2c2268a0 100644 --- a/libs/smux/EgpNeighEntry.c +++ b/libs/smux/EgpNeighEntry.c @@ -1,8 +1,8 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1213-MIB" * found in "RFC1213-MIB.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #include "EgpNeighEntry.h" @@ -12,135 +12,135 @@ static asn_TYPE_member_t asn_MBR_EgpNeighEntry_1[] = { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, &asn_DEF_INTEGER, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "egpNeighState" }, { ATF_NOFLAGS, 0, offsetof(struct EgpNeighEntry, egpNeighAddr), (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 0, &asn_DEF_IpAddress, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "egpNeighAddr" }, { ATF_NOFLAGS, 0, offsetof(struct EgpNeighEntry, egpNeighAs), (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, &asn_DEF_INTEGER, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "egpNeighAs" }, { ATF_NOFLAGS, 0, offsetof(struct EgpNeighEntry, egpNeighInMsgs), (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 0, &asn_DEF_Counter, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "egpNeighInMsgs" }, { ATF_NOFLAGS, 0, offsetof(struct EgpNeighEntry, egpNeighInErrs), (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 0, &asn_DEF_Counter, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "egpNeighInErrs" }, { ATF_NOFLAGS, 0, offsetof(struct EgpNeighEntry, egpNeighOutMsgs), (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 0, &asn_DEF_Counter, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "egpNeighOutMsgs" }, { ATF_NOFLAGS, 0, offsetof(struct EgpNeighEntry, egpNeighOutErrs), (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 0, &asn_DEF_Counter, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "egpNeighOutErrs" }, { ATF_NOFLAGS, 0, offsetof(struct EgpNeighEntry, egpNeighInErrMsgs), (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 0, &asn_DEF_Counter, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "egpNeighInErrMsgs" }, { ATF_NOFLAGS, 0, offsetof(struct EgpNeighEntry, egpNeighOutErrMsgs), (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 0, &asn_DEF_Counter, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "egpNeighOutErrMsgs" }, { ATF_NOFLAGS, 0, offsetof(struct EgpNeighEntry, egpNeighStateUps), (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 0, &asn_DEF_Counter, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "egpNeighStateUps" }, { ATF_NOFLAGS, 0, offsetof(struct EgpNeighEntry, egpNeighStateDowns), (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 0, &asn_DEF_Counter, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "egpNeighStateDowns" }, { ATF_NOFLAGS, 0, offsetof(struct EgpNeighEntry, egpNeighIntervalHello), (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, &asn_DEF_INTEGER, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "egpNeighIntervalHello" }, { ATF_NOFLAGS, 0, offsetof(struct EgpNeighEntry, egpNeighIntervalPoll), (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, &asn_DEF_INTEGER, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "egpNeighIntervalPoll" }, { ATF_NOFLAGS, 0, offsetof(struct EgpNeighEntry, egpNeighMode), (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, &asn_DEF_INTEGER, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "egpNeighMode" }, { ATF_NOFLAGS, 0, offsetof(struct EgpNeighEntry, egpNeighEventTrigger), (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, &asn_DEF_INTEGER, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "egpNeighEventTrigger" }, }; @@ -170,28 +170,19 @@ static asn_SEQUENCE_specifics_t asn_SPC_EgpNeighEntry_specs_1 = { asn_MAP_EgpNeighEntry_tag2el_1, 15, /* Count of tags in the map */ 0, 0, 0, /* Optional elements (not needed) */ - -1, /* Start extensions */ - -1 /* Stop extensions */ + -1, /* First extension addition */ }; asn_TYPE_descriptor_t asn_DEF_EgpNeighEntry = { "EgpNeighEntry", "EgpNeighEntry", - SEQUENCE_free, - SEQUENCE_print, - SEQUENCE_constraint, - SEQUENCE_decode_ber, - SEQUENCE_encode_der, - SEQUENCE_decode_xer, - SEQUENCE_encode_xer, - 0, 0, /* No PER support, use "-gen-PER" to enable */ - 0, /* Use generic outmost tag fetcher */ + &asn_OP_SEQUENCE, asn_DEF_EgpNeighEntry_tags_1, sizeof(asn_DEF_EgpNeighEntry_tags_1) /sizeof(asn_DEF_EgpNeighEntry_tags_1[0]), /* 1 */ asn_DEF_EgpNeighEntry_tags_1, /* Same as above */ sizeof(asn_DEF_EgpNeighEntry_tags_1) /sizeof(asn_DEF_EgpNeighEntry_tags_1[0]), /* 1 */ - 0, /* No PER visible constraints */ + { 0, 0, SEQUENCE_constraint }, asn_MBR_EgpNeighEntry_1, 15, /* Elements count */ &asn_SPC_EgpNeighEntry_specs_1 /* Additional specs */ diff --git a/libs/smux/Gauge.c b/libs/smux/Gauge.c index 2007be44..52b737f8 100644 --- a/libs/smux/Gauge.c +++ b/libs/smux/Gauge.c @@ -1,14 +1,14 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1155-SMI" * found in "RFC1155-SMI.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #include "Gauge.h" int -Gauge_constraint(asn_TYPE_descriptor_t *td, const void *sptr, +Gauge_constraint(const asn_TYPE_descriptor_t *td, const void *sptr, asn_app_constraint_failed_f *ctfailcb, void *app_key) { if(!sptr) { @@ -27,69 +27,15 @@ Gauge_constraint(asn_TYPE_descriptor_t *td, const void *sptr, * This type is implemented using NativeInteger, * so here we adjust the DEF accordingly. */ -static void -Gauge_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) { - td->free_struct = asn_DEF_NativeInteger.free_struct; - td->print_struct = asn_DEF_NativeInteger.print_struct; - td->check_constraints = asn_DEF_NativeInteger.check_constraints; - td->ber_decoder = asn_DEF_NativeInteger.ber_decoder; - td->der_encoder = asn_DEF_NativeInteger.der_encoder; - td->xer_decoder = asn_DEF_NativeInteger.xer_decoder; - td->xer_encoder = asn_DEF_NativeInteger.xer_encoder; - td->uper_decoder = asn_DEF_NativeInteger.uper_decoder; - td->uper_encoder = asn_DEF_NativeInteger.uper_encoder; - if(!td->per_constraints) - td->per_constraints = asn_DEF_NativeInteger.per_constraints; - td->elements = asn_DEF_NativeInteger.elements; - td->elements_count = asn_DEF_NativeInteger.elements_count; - /* td->specifics = asn_DEF_NativeInteger.specifics; // Defined explicitly */ -} - -void -Gauge_free(asn_TYPE_descriptor_t *td, - void *struct_ptr, int contents_only) { - Gauge_1_inherit_TYPE_descriptor(td); - td->free_struct(td, struct_ptr, contents_only); -} - -int -Gauge_print(asn_TYPE_descriptor_t *td, const void *struct_ptr, - int ilevel, asn_app_consume_bytes_f *cb, void *app_key) { - Gauge_1_inherit_TYPE_descriptor(td); - return td->print_struct(td, struct_ptr, ilevel, cb, app_key); -} - -asn_dec_rval_t -Gauge_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, - void **structure, const void *bufptr, size_t size, int tag_mode) { - Gauge_1_inherit_TYPE_descriptor(td); - return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode); -} - -asn_enc_rval_t -Gauge_encode_der(asn_TYPE_descriptor_t *td, - void *structure, int tag_mode, ber_tlv_tag_t tag, - asn_app_consume_bytes_f *cb, void *app_key) { - Gauge_1_inherit_TYPE_descriptor(td); - return td->der_encoder(td, structure, tag_mode, tag, cb, app_key); -} - -asn_dec_rval_t -Gauge_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, - void **structure, const char *opt_mname, const void *bufptr, size_t size) { - Gauge_1_inherit_TYPE_descriptor(td); - return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size); -} - -asn_enc_rval_t -Gauge_encode_xer(asn_TYPE_descriptor_t *td, void *structure, - int ilevel, enum xer_encoder_flags_e flags, - asn_app_consume_bytes_f *cb, void *app_key) { - Gauge_1_inherit_TYPE_descriptor(td); - return td->xer_encoder(td, structure, ilevel, flags, cb, app_key); -} - -static const asn_INTEGER_specifics_t asn_SPC_Gauge_specs_1 = { +static asn_oer_constraints_t asn_OER_type_Gauge_constr_1 CC_NOTUSED = { + { 4, 1 } /* (0..4294967295) */, + -1}; +asn_per_constraints_t asn_PER_type_Gauge_constr_1 CC_NOTUSED = { + { APC_CONSTRAINED, 32, -1, 0, 4294967295 } /* (0..4294967295) */, + { APC_UNCONSTRAINED, -1, -1, 0, 0 }, + 0, 0 /* No PER value map */ +}; +const asn_INTEGER_specifics_t asn_SPC_Gauge_specs_1 = { 0, 0, 0, 0, 0, 0, /* Native long size */ 1 /* Unsigned representation */ @@ -101,22 +47,14 @@ static const ber_tlv_tag_t asn_DEF_Gauge_tags_1[] = { asn_TYPE_descriptor_t asn_DEF_Gauge = { "Gauge", "Gauge", - Gauge_free, - Gauge_print, - Gauge_constraint, - Gauge_decode_ber, - Gauge_encode_der, - Gauge_decode_xer, - Gauge_encode_xer, - 0, 0, /* No PER support, use "-gen-PER" to enable */ - 0, /* Use generic outmost tag fetcher */ + &asn_OP_NativeInteger, asn_DEF_Gauge_tags_1, sizeof(asn_DEF_Gauge_tags_1) /sizeof(asn_DEF_Gauge_tags_1[0]) - 1, /* 1 */ asn_DEF_Gauge_tags_1, /* Same as above */ sizeof(asn_DEF_Gauge_tags_1) /sizeof(asn_DEF_Gauge_tags_1[0]), /* 2 */ - 0, /* No PER visible constraints */ + { &asn_OER_type_Gauge_constr_1, &asn_PER_type_Gauge_constr_1, Gauge_constraint }, 0, 0, /* No members */ &asn_SPC_Gauge_specs_1 /* Additional specs */ }; diff --git a/libs/smux/GetNextRequest-PDU.c b/libs/smux/GetNextRequest-PDU.c index ef88e805..323ba4eb 100644 --- a/libs/smux/GetNextRequest-PDU.c +++ b/libs/smux/GetNextRequest-PDU.c @@ -1,86 +1,16 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1157-SNMP" * found in "RFC1157-SNMP.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #include "GetNextRequest-PDU.h" -int -GetNextRequest_PDU_constraint(asn_TYPE_descriptor_t *td, const void *sptr, - asn_app_constraint_failed_f *ctfailcb, void *app_key) { - /* Replace with underlying type checker */ - td->check_constraints = asn_DEF_PDU.check_constraints; - return td->check_constraints(td, sptr, ctfailcb, app_key); -} - /* * This type is implemented using PDU, * so here we adjust the DEF accordingly. */ -static void -GetNextRequest_PDU_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) { - td->free_struct = asn_DEF_PDU.free_struct; - td->print_struct = asn_DEF_PDU.print_struct; - td->check_constraints = asn_DEF_PDU.check_constraints; - td->ber_decoder = asn_DEF_PDU.ber_decoder; - td->der_encoder = asn_DEF_PDU.der_encoder; - td->xer_decoder = asn_DEF_PDU.xer_decoder; - td->xer_encoder = asn_DEF_PDU.xer_encoder; - td->uper_decoder = asn_DEF_PDU.uper_decoder; - td->uper_encoder = asn_DEF_PDU.uper_encoder; - if(!td->per_constraints) - td->per_constraints = asn_DEF_PDU.per_constraints; - td->elements = asn_DEF_PDU.elements; - td->elements_count = asn_DEF_PDU.elements_count; - td->specifics = asn_DEF_PDU.specifics; -} - -void -GetNextRequest_PDU_free(asn_TYPE_descriptor_t *td, - void *struct_ptr, int contents_only) { - GetNextRequest_PDU_1_inherit_TYPE_descriptor(td); - td->free_struct(td, struct_ptr, contents_only); -} - -int -GetNextRequest_PDU_print(asn_TYPE_descriptor_t *td, const void *struct_ptr, - int ilevel, asn_app_consume_bytes_f *cb, void *app_key) { - GetNextRequest_PDU_1_inherit_TYPE_descriptor(td); - return td->print_struct(td, struct_ptr, ilevel, cb, app_key); -} - -asn_dec_rval_t -GetNextRequest_PDU_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, - void **structure, const void *bufptr, size_t size, int tag_mode) { - GetNextRequest_PDU_1_inherit_TYPE_descriptor(td); - return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode); -} - -asn_enc_rval_t -GetNextRequest_PDU_encode_der(asn_TYPE_descriptor_t *td, - void *structure, int tag_mode, ber_tlv_tag_t tag, - asn_app_consume_bytes_f *cb, void *app_key) { - GetNextRequest_PDU_1_inherit_TYPE_descriptor(td); - return td->der_encoder(td, structure, tag_mode, tag, cb, app_key); -} - -asn_dec_rval_t -GetNextRequest_PDU_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, - void **structure, const char *opt_mname, const void *bufptr, size_t size) { - GetNextRequest_PDU_1_inherit_TYPE_descriptor(td); - return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size); -} - -asn_enc_rval_t -GetNextRequest_PDU_encode_xer(asn_TYPE_descriptor_t *td, void *structure, - int ilevel, enum xer_encoder_flags_e flags, - asn_app_consume_bytes_f *cb, void *app_key) { - GetNextRequest_PDU_1_inherit_TYPE_descriptor(td); - return td->xer_encoder(td, structure, ilevel, flags, cb, app_key); -} - static const ber_tlv_tag_t asn_DEF_GetNextRequest_PDU_tags_1[] = { (ASN_TAG_CLASS_CONTEXT | (1 << 2)), (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)) @@ -88,23 +18,16 @@ static const ber_tlv_tag_t asn_DEF_GetNextRequest_PDU_tags_1[] = { asn_TYPE_descriptor_t asn_DEF_GetNextRequest_PDU = { "GetNextRequest-PDU", "GetNextRequest-PDU", - GetNextRequest_PDU_free, - GetNextRequest_PDU_print, - GetNextRequest_PDU_constraint, - GetNextRequest_PDU_decode_ber, - GetNextRequest_PDU_encode_der, - GetNextRequest_PDU_decode_xer, - GetNextRequest_PDU_encode_xer, - 0, 0, /* No PER support, use "-gen-PER" to enable */ - 0, /* Use generic outmost tag fetcher */ + &asn_OP_SEQUENCE, asn_DEF_GetNextRequest_PDU_tags_1, sizeof(asn_DEF_GetNextRequest_PDU_tags_1) /sizeof(asn_DEF_GetNextRequest_PDU_tags_1[0]) - 1, /* 1 */ asn_DEF_GetNextRequest_PDU_tags_1, /* Same as above */ sizeof(asn_DEF_GetNextRequest_PDU_tags_1) /sizeof(asn_DEF_GetNextRequest_PDU_tags_1[0]), /* 2 */ - 0, /* No PER visible constraints */ - 0, 0, /* Defined elsewhere */ - 0 /* No specifics */ + { 0, 0, SEQUENCE_constraint }, + asn_MBR_PDU_1, + 4, /* Elements count */ + &asn_SPC_PDU_specs_1 /* Additional specs */ }; diff --git a/libs/smux/GetRequest-PDU.c b/libs/smux/GetRequest-PDU.c index 953999ce..bed361c5 100644 --- a/libs/smux/GetRequest-PDU.c +++ b/libs/smux/GetRequest-PDU.c @@ -1,86 +1,16 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1157-SNMP" * found in "RFC1157-SNMP.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #include "GetRequest-PDU.h" -int -GetRequest_PDU_constraint(asn_TYPE_descriptor_t *td, const void *sptr, - asn_app_constraint_failed_f *ctfailcb, void *app_key) { - /* Replace with underlying type checker */ - td->check_constraints = asn_DEF_PDU.check_constraints; - return td->check_constraints(td, sptr, ctfailcb, app_key); -} - /* * This type is implemented using PDU, * so here we adjust the DEF accordingly. */ -static void -GetRequest_PDU_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) { - td->free_struct = asn_DEF_PDU.free_struct; - td->print_struct = asn_DEF_PDU.print_struct; - td->check_constraints = asn_DEF_PDU.check_constraints; - td->ber_decoder = asn_DEF_PDU.ber_decoder; - td->der_encoder = asn_DEF_PDU.der_encoder; - td->xer_decoder = asn_DEF_PDU.xer_decoder; - td->xer_encoder = asn_DEF_PDU.xer_encoder; - td->uper_decoder = asn_DEF_PDU.uper_decoder; - td->uper_encoder = asn_DEF_PDU.uper_encoder; - if(!td->per_constraints) - td->per_constraints = asn_DEF_PDU.per_constraints; - td->elements = asn_DEF_PDU.elements; - td->elements_count = asn_DEF_PDU.elements_count; - td->specifics = asn_DEF_PDU.specifics; -} - -void -GetRequest_PDU_free(asn_TYPE_descriptor_t *td, - void *struct_ptr, int contents_only) { - GetRequest_PDU_1_inherit_TYPE_descriptor(td); - td->free_struct(td, struct_ptr, contents_only); -} - -int -GetRequest_PDU_print(asn_TYPE_descriptor_t *td, const void *struct_ptr, - int ilevel, asn_app_consume_bytes_f *cb, void *app_key) { - GetRequest_PDU_1_inherit_TYPE_descriptor(td); - return td->print_struct(td, struct_ptr, ilevel, cb, app_key); -} - -asn_dec_rval_t -GetRequest_PDU_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, - void **structure, const void *bufptr, size_t size, int tag_mode) { - GetRequest_PDU_1_inherit_TYPE_descriptor(td); - return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode); -} - -asn_enc_rval_t -GetRequest_PDU_encode_der(asn_TYPE_descriptor_t *td, - void *structure, int tag_mode, ber_tlv_tag_t tag, - asn_app_consume_bytes_f *cb, void *app_key) { - GetRequest_PDU_1_inherit_TYPE_descriptor(td); - return td->der_encoder(td, structure, tag_mode, tag, cb, app_key); -} - -asn_dec_rval_t -GetRequest_PDU_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, - void **structure, const char *opt_mname, const void *bufptr, size_t size) { - GetRequest_PDU_1_inherit_TYPE_descriptor(td); - return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size); -} - -asn_enc_rval_t -GetRequest_PDU_encode_xer(asn_TYPE_descriptor_t *td, void *structure, - int ilevel, enum xer_encoder_flags_e flags, - asn_app_consume_bytes_f *cb, void *app_key) { - GetRequest_PDU_1_inherit_TYPE_descriptor(td); - return td->xer_encoder(td, structure, ilevel, flags, cb, app_key); -} - static const ber_tlv_tag_t asn_DEF_GetRequest_PDU_tags_1[] = { (ASN_TAG_CLASS_CONTEXT | (0 << 2)), (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)) @@ -88,23 +18,16 @@ static const ber_tlv_tag_t asn_DEF_GetRequest_PDU_tags_1[] = { asn_TYPE_descriptor_t asn_DEF_GetRequest_PDU = { "GetRequest-PDU", "GetRequest-PDU", - GetRequest_PDU_free, - GetRequest_PDU_print, - GetRequest_PDU_constraint, - GetRequest_PDU_decode_ber, - GetRequest_PDU_encode_der, - GetRequest_PDU_decode_xer, - GetRequest_PDU_encode_xer, - 0, 0, /* No PER support, use "-gen-PER" to enable */ - 0, /* Use generic outmost tag fetcher */ + &asn_OP_SEQUENCE, asn_DEF_GetRequest_PDU_tags_1, sizeof(asn_DEF_GetRequest_PDU_tags_1) /sizeof(asn_DEF_GetRequest_PDU_tags_1[0]) - 1, /* 1 */ asn_DEF_GetRequest_PDU_tags_1, /* Same as above */ sizeof(asn_DEF_GetRequest_PDU_tags_1) /sizeof(asn_DEF_GetRequest_PDU_tags_1[0]), /* 2 */ - 0, /* No PER visible constraints */ - 0, 0, /* Defined elsewhere */ - 0 /* No specifics */ + { 0, 0, SEQUENCE_constraint }, + asn_MBR_PDU_1, + 4, /* Elements count */ + &asn_SPC_PDU_specs_1 /* Additional specs */ }; diff --git a/libs/smux/GetResponse-PDU.c b/libs/smux/GetResponse-PDU.c index 37019105..529beeeb 100644 --- a/libs/smux/GetResponse-PDU.c +++ b/libs/smux/GetResponse-PDU.c @@ -1,86 +1,16 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1157-SNMP" * found in "RFC1157-SNMP.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #include "GetResponse-PDU.h" -int -GetResponse_PDU_constraint(asn_TYPE_descriptor_t *td, const void *sptr, - asn_app_constraint_failed_f *ctfailcb, void *app_key) { - /* Replace with underlying type checker */ - td->check_constraints = asn_DEF_PDU.check_constraints; - return td->check_constraints(td, sptr, ctfailcb, app_key); -} - /* * This type is implemented using PDU, * so here we adjust the DEF accordingly. */ -static void -GetResponse_PDU_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) { - td->free_struct = asn_DEF_PDU.free_struct; - td->print_struct = asn_DEF_PDU.print_struct; - td->check_constraints = asn_DEF_PDU.check_constraints; - td->ber_decoder = asn_DEF_PDU.ber_decoder; - td->der_encoder = asn_DEF_PDU.der_encoder; - td->xer_decoder = asn_DEF_PDU.xer_decoder; - td->xer_encoder = asn_DEF_PDU.xer_encoder; - td->uper_decoder = asn_DEF_PDU.uper_decoder; - td->uper_encoder = asn_DEF_PDU.uper_encoder; - if(!td->per_constraints) - td->per_constraints = asn_DEF_PDU.per_constraints; - td->elements = asn_DEF_PDU.elements; - td->elements_count = asn_DEF_PDU.elements_count; - td->specifics = asn_DEF_PDU.specifics; -} - -void -GetResponse_PDU_free(asn_TYPE_descriptor_t *td, - void *struct_ptr, int contents_only) { - GetResponse_PDU_1_inherit_TYPE_descriptor(td); - td->free_struct(td, struct_ptr, contents_only); -} - -int -GetResponse_PDU_print(asn_TYPE_descriptor_t *td, const void *struct_ptr, - int ilevel, asn_app_consume_bytes_f *cb, void *app_key) { - GetResponse_PDU_1_inherit_TYPE_descriptor(td); - return td->print_struct(td, struct_ptr, ilevel, cb, app_key); -} - -asn_dec_rval_t -GetResponse_PDU_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, - void **structure, const void *bufptr, size_t size, int tag_mode) { - GetResponse_PDU_1_inherit_TYPE_descriptor(td); - return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode); -} - -asn_enc_rval_t -GetResponse_PDU_encode_der(asn_TYPE_descriptor_t *td, - void *structure, int tag_mode, ber_tlv_tag_t tag, - asn_app_consume_bytes_f *cb, void *app_key) { - GetResponse_PDU_1_inherit_TYPE_descriptor(td); - return td->der_encoder(td, structure, tag_mode, tag, cb, app_key); -} - -asn_dec_rval_t -GetResponse_PDU_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, - void **structure, const char *opt_mname, const void *bufptr, size_t size) { - GetResponse_PDU_1_inherit_TYPE_descriptor(td); - return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size); -} - -asn_enc_rval_t -GetResponse_PDU_encode_xer(asn_TYPE_descriptor_t *td, void *structure, - int ilevel, enum xer_encoder_flags_e flags, - asn_app_consume_bytes_f *cb, void *app_key) { - GetResponse_PDU_1_inherit_TYPE_descriptor(td); - return td->xer_encoder(td, structure, ilevel, flags, cb, app_key); -} - static const ber_tlv_tag_t asn_DEF_GetResponse_PDU_tags_1[] = { (ASN_TAG_CLASS_CONTEXT | (2 << 2)), (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)) @@ -88,23 +18,16 @@ static const ber_tlv_tag_t asn_DEF_GetResponse_PDU_tags_1[] = { asn_TYPE_descriptor_t asn_DEF_GetResponse_PDU = { "GetResponse-PDU", "GetResponse-PDU", - GetResponse_PDU_free, - GetResponse_PDU_print, - GetResponse_PDU_constraint, - GetResponse_PDU_decode_ber, - GetResponse_PDU_encode_der, - GetResponse_PDU_decode_xer, - GetResponse_PDU_encode_xer, - 0, 0, /* No PER support, use "-gen-PER" to enable */ - 0, /* Use generic outmost tag fetcher */ + &asn_OP_SEQUENCE, asn_DEF_GetResponse_PDU_tags_1, sizeof(asn_DEF_GetResponse_PDU_tags_1) /sizeof(asn_DEF_GetResponse_PDU_tags_1[0]) - 1, /* 1 */ asn_DEF_GetResponse_PDU_tags_1, /* Same as above */ sizeof(asn_DEF_GetResponse_PDU_tags_1) /sizeof(asn_DEF_GetResponse_PDU_tags_1[0]), /* 2 */ - 0, /* No PER visible constraints */ - 0, 0, /* Defined elsewhere */ - 0 /* No specifics */ + { 0, 0, SEQUENCE_constraint }, + asn_MBR_PDU_1, + 4, /* Elements count */ + &asn_SPC_PDU_specs_1 /* Additional specs */ }; diff --git a/libs/smux/INTEGER.c b/libs/smux/INTEGER.c index eed82176..2b43cdf7 100644 --- a/libs/smux/INTEGER.c +++ b/libs/smux/INTEGER.c @@ -1,5 +1,5 @@ -/*- - * Copyright (c) 2003-2014 Lev Walkin . +/* + * Copyright (c) 2003-2019 Lev Walkin . * All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ @@ -14,16 +14,21 @@ static const ber_tlv_tag_t asn_DEF_INTEGER_tags[] = { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)) }; -asn_TYPE_descriptor_t asn_DEF_INTEGER = { - "INTEGER", - "INTEGER", - ASN__PRIMITIVE_TYPE_free, +asn_TYPE_operation_t asn_OP_INTEGER = { + INTEGER_free, INTEGER_print, - asn_generic_no_constraint, + INTEGER_compare, ber_decode_primitive, INTEGER_encode_der, INTEGER_decode_xer, INTEGER_encode_xer, +#ifdef ASN_DISABLE_OER_SUPPORT + 0, + 0, +#else + INTEGER_decode_oer, /* OER decoder */ + INTEGER_encode_oer, /* Canonical OER encoder */ +#endif /* ASN_DISABLE_OER_SUPPORT */ #ifdef ASN_DISABLE_PER_SUPPORT 0, 0, @@ -31,12 +36,18 @@ asn_TYPE_descriptor_t asn_DEF_INTEGER = { INTEGER_decode_uper, /* Unaligned PER decoder */ INTEGER_encode_uper, /* Unaligned PER encoder */ #endif /* ASN_DISABLE_PER_SUPPORT */ - 0, /* Use generic outmost tag fetcher */ + INTEGER_random_fill, + 0 /* Use generic outmost tag fetcher */ +}; +asn_TYPE_descriptor_t asn_DEF_INTEGER = { + "INTEGER", + "INTEGER", + &asn_OP_INTEGER, asn_DEF_INTEGER_tags, sizeof(asn_DEF_INTEGER_tags) / sizeof(asn_DEF_INTEGER_tags[0]), asn_DEF_INTEGER_tags, /* Same as above */ sizeof(asn_DEF_INTEGER_tags) / sizeof(asn_DEF_INTEGER_tags[0]), - 0, /* No PER visible constraints */ + { 0, 0, asn_generic_no_constraint }, 0, 0, /* No members */ 0 /* No specifics */ }; @@ -45,10 +56,12 @@ asn_TYPE_descriptor_t asn_DEF_INTEGER = { * Encode INTEGER type using DER. */ asn_enc_rval_t -INTEGER_encode_der(asn_TYPE_descriptor_t *td, void *sptr, - int tag_mode, ber_tlv_tag_t tag, - asn_app_consume_bytes_f *cb, void *app_key) { - INTEGER_t *st = (INTEGER_t *)sptr; +INTEGER_encode_der(const asn_TYPE_descriptor_t *td, const void *sptr, + int tag_mode, ber_tlv_tag_t tag, asn_app_consume_bytes_f *cb, + void *app_key) { + const INTEGER_t *st = (const INTEGER_t *)sptr; + asn_enc_rval_t rval; + INTEGER_t effective_integer; ASN_DEBUG("%s %s as INTEGER (tm=%d)", cb?"Encoding":"Estimating", td->name, tag_mode); @@ -85,58 +98,60 @@ INTEGER_encode_der(asn_TYPE_descriptor_t *td, void *sptr, /* Remove leading superfluous bytes from the integer */ shift = buf - st->buf; if(shift) { - uint8_t *nb = st->buf; - uint8_t *end; - - st->size -= shift; /* New size, minus bad bytes */ - end = nb + st->size; - - for(; nb < end; nb++, buf++) - *nb = *buf; - } - - } /* if(1) */ + union { + const uint8_t *c_buf; + uint8_t *nc_buf; + } unconst; + unconst.c_buf = st->buf; + effective_integer.buf = unconst.nc_buf + shift; + effective_integer.size = st->size - shift; + + st = &effective_integer; + } + } - return der_encode_primitive(td, sptr, tag_mode, tag, cb, app_key); + rval = der_encode_primitive(td, st, tag_mode, tag, cb, app_key); + if(rval.structure_ptr == &effective_integer) { + rval.structure_ptr = sptr; + } + return rval; } -static const asn_INTEGER_enum_map_t *INTEGER_map_enum2value(asn_INTEGER_specifics_t *specs, const char *lstart, const char *lstop); +static const asn_INTEGER_enum_map_t *INTEGER_map_enum2value( + const asn_INTEGER_specifics_t *specs, const char *lstart, + const char *lstop); /* * INTEGER specific human-readable output. */ static ssize_t INTEGER__dump(const asn_TYPE_descriptor_t *td, const INTEGER_t *st, asn_app_consume_bytes_f *cb, void *app_key, int plainOrXER) { - asn_INTEGER_specifics_t *specs=(asn_INTEGER_specifics_t *)td->specifics; - char scratch[32]; /* Enough for 64-bit integer */ + const asn_INTEGER_specifics_t *specs = + (const asn_INTEGER_specifics_t *)td->specifics; + char scratch[32]; uint8_t *buf = st->buf; uint8_t *buf_end = st->buf + st->size; - signed long value; + intmax_t value; ssize_t wrote = 0; char *p; int ret; if(specs && specs->field_unsigned) - ret = asn_INTEGER2ulong(st, (unsigned long *)&value); + ret = asn_INTEGER2umax(st, (uintmax_t *)&value); else - ret = asn_INTEGER2long(st, &value); + ret = asn_INTEGER2imax(st, &value); /* Simple case: the integer size is small */ if(ret == 0) { const asn_INTEGER_enum_map_t *el; - size_t scrsize; - char *scr; - el = (value >= 0 || !specs || !specs->field_unsigned) ? INTEGER_map_value2enum(specs, value) : 0; if(el) { - scrsize = el->enum_len + 32; - scr = (char *)alloca(scrsize); if(plainOrXER == 0) - ret = snprintf(scr, scrsize, - "%ld (%s)", value, el->enum_name); + return asn__format_to_callback(cb, app_key, + "%" ASN_PRIdMAX " (%s)", value, el->enum_name); else - ret = snprintf(scr, scrsize, + return asn__format_to_callback(cb, app_key, "<%s/>", el->enum_name); } else if(plainOrXER && specs && specs->strict_enumeration) { ASN_DEBUG("ASN.1 forbids dealing with " @@ -144,14 +159,12 @@ INTEGER__dump(const asn_TYPE_descriptor_t *td, const INTEGER_t *st, asn_app_cons errno = EPERM; return -1; } else { - scrsize = sizeof(scratch); - scr = scratch; - ret = snprintf(scr, scrsize, - (specs && specs->field_unsigned) - ?"%lu":"%ld", value); - } - assert(ret > 0 && (size_t)ret < scrsize); - return (cb(scr, ret, app_key) < 0) ? -1 : ret; + return asn__format_to_callback(cb, app_key, + (specs && specs->field_unsigned) + ? "%" ASN_PRIuMAX + : "%" ASN_PRIdMAX, + value); + } } else if(plainOrXER && specs && specs->strict_enumeration) { /* * Here and earlier, we cannot encode the ENUMERATED values @@ -189,12 +202,11 @@ INTEGER__dump(const asn_TYPE_descriptor_t *td, const INTEGER_t *st, asn_app_cons * INTEGER specific human-readable output. */ int -INTEGER_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel, - asn_app_consume_bytes_f *cb, void *app_key) { - const INTEGER_t *st = (const INTEGER_t *)sptr; +INTEGER_print(const asn_TYPE_descriptor_t *td, const void *sptr, int ilevel, + asn_app_consume_bytes_f *cb, void *app_key) { + const INTEGER_t *st = (const INTEGER_t *)sptr; ssize_t ret; - (void)td; (void)ilevel; if(!st || !st->buf) @@ -223,7 +235,7 @@ INTEGER__compar_enum2value(const void *kp, const void *am) { /* Compare strings */ for(ptr = key->start, end = key->stop, name = el->enum_name; ptr < end; ptr++, name++) { - if(*ptr != *name) + if(*ptr != *name || !*name) return *(const unsigned char *)ptr - *(const unsigned char *)name; } @@ -231,8 +243,9 @@ INTEGER__compar_enum2value(const void *kp, const void *am) { } static const asn_INTEGER_enum_map_t * -INTEGER_map_enum2value(asn_INTEGER_specifics_t *specs, const char *lstart, const char *lstop) { - const asn_INTEGER_enum_map_t *el_found; +INTEGER_map_enum2value(const asn_INTEGER_specifics_t *specs, const char *lstart, + const char *lstop) { + const asn_INTEGER_enum_map_t *el_found; int count = specs ? specs->map_count : 0; struct e2v_key key; const char *lp; @@ -279,7 +292,7 @@ INTEGER__compar_value2enum(const void *kp, const void *am) { } const asn_INTEGER_enum_map_t * -INTEGER_map_value2enum(asn_INTEGER_specifics_t *specs, long value) { +INTEGER_map_value2enum(const asn_INTEGER_specifics_t *specs, long value) { int count = specs ? specs->map_count : 0; if(!count) return 0; return (asn_INTEGER_enum_map_t *)bsearch(&value, specs->value2enum, @@ -305,10 +318,11 @@ INTEGER_st_prealloc(INTEGER_t *st, int min_size) { * Decode the chunk of XML text encoding INTEGER. */ static enum xer_pbd_rval -INTEGER__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const void *chunk_buf, size_t chunk_size) { - INTEGER_t *st = (INTEGER_t *)sptr; - long dec_value; - long hex_value = 0; +INTEGER__xer_body_decode(const asn_TYPE_descriptor_t *td, void *sptr, + const void *chunk_buf, size_t chunk_size) { + INTEGER_t *st = (INTEGER_t *)sptr; + intmax_t dec_value; + intmax_t hex_value = 0; const char *lp; const char *lstart = (const char *)chunk_buf; const char *lstop = lstart + chunk_size; @@ -407,7 +421,7 @@ INTEGER__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const void *chun if(state == ST_LEADSPACE) { const asn_INTEGER_enum_map_t *el; el = INTEGER_map_enum2value( - (asn_INTEGER_specifics_t *) + (const asn_INTEGER_specifics_t *) td->specifics, lstart, lstop); if(el) { ASN_DEBUG("Found \"%s\" => %ld", @@ -485,14 +499,24 @@ INTEGER__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const void *chun /* FALL THROUGH */ case ST_DIGITS_TRAILSPACE: /* The last symbol encountered was a digit. */ - switch(asn_strtol_lim(dec_value_start, &dec_value_end, &dec_value)) { - case ASN_STRTOL_OK: - break; - case ASN_STRTOL_ERROR_RANGE: - return XPBD_DECODER_LIMIT; - case ASN_STRTOL_ERROR_INVAL: - case ASN_STRTOL_EXPECT_MORE: - case ASN_STRTOL_EXTRA_DATA: + switch(asn_strtoimax_lim(dec_value_start, &dec_value_end, &dec_value)) { + case ASN_STRTOX_OK: + if(dec_value >= LONG_MIN && dec_value <= LONG_MAX) { + break; + } else { + /* + * We model INTEGER on long for XER, + * to avoid rewriting all the tests at once. + */ + ASN_DEBUG("INTEGER exceeds long range"); + } + /* Fall through */ + case ASN_STRTOX_ERROR_RANGE: + ASN_DEBUG("INTEGER decode %s hit range limit", td->name); + return XPBD_DECODER_LIMIT; + case ASN_STRTOX_ERROR_INVAL: + case ASN_STRTOX_EXPECT_MORE: + case ASN_STRTOX_EXTRA_DATA: return XPBD_BROKEN_ENCODING; } break; @@ -517,27 +541,28 @@ INTEGER__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const void *chun * Convert the result of parsing of enumeration or a straight * decimal value into a BER representation. */ - if(asn_long2INTEGER(st, dec_value)) + if(asn_imax2INTEGER(st, dec_value)) { + ASN_DEBUG("INTEGER decode %s conversion failed", td->name); return XPBD_SYSTEM_FAILURE; + } return XPBD_BODY_CONSUMED; } asn_dec_rval_t -INTEGER_decode_xer(asn_codec_ctx_t *opt_codec_ctx, - asn_TYPE_descriptor_t *td, void **sptr, const char *opt_mname, - const void *buf_ptr, size_t size) { - - return xer_decode_primitive(opt_codec_ctx, td, +INTEGER_decode_xer(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *td, void **sptr, + const char *opt_mname, const void *buf_ptr, size_t size) { + return xer_decode_primitive(opt_codec_ctx, td, sptr, sizeof(INTEGER_t), opt_mname, buf_ptr, size, INTEGER__xer_body_decode); } asn_enc_rval_t -INTEGER_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, - int ilevel, enum xer_encoder_flags_e flags, - asn_app_consume_bytes_f *cb, void *app_key) { - const INTEGER_t *st = (const INTEGER_t *)sptr; +INTEGER_encode_xer(const asn_TYPE_descriptor_t *td, const void *sptr, + int ilevel, enum xer_encoder_flags_e flags, + asn_app_consume_bytes_f *cb, void *app_key) { + const INTEGER_t *st = (const INTEGER_t *)sptr; asn_enc_rval_t er; (void)ilevel; @@ -555,12 +580,15 @@ INTEGER_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, #ifndef ASN_DISABLE_PER_SUPPORT asn_dec_rval_t -INTEGER_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, - asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { - asn_INTEGER_specifics_t *specs=(asn_INTEGER_specifics_t *)td->specifics; - asn_dec_rval_t rval = { RC_OK, 0 }; +INTEGER_decode_uper(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, void **sptr, + asn_per_data_t *pd) { + const asn_INTEGER_specifics_t *specs = + (const asn_INTEGER_specifics_t *)td->specifics; + asn_dec_rval_t rval = { RC_OK, 0 }; INTEGER_t *st = (INTEGER_t *)*sptr; - asn_per_constraint_t *ct; + const asn_per_constraint_t *ct; int repeat; (void)opt_codec_ctx; @@ -570,7 +598,7 @@ INTEGER_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, if(!st) ASN__DECODE_FAILED; } - if(!constraints) constraints = td->per_constraints; + if(!constraints) constraints = td->encoding_constraints.per_constraints; ct = constraints ? &constraints->value : 0; if(ct && ct->flags & APC_EXTENSIBLE) { @@ -604,7 +632,7 @@ INTEGER_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, ASN__DECODE_FAILED; if(specs && specs->field_unsigned) { - unsigned long uvalue; + unsigned long uvalue = 0; if(uper_get_constrained_whole_number(pd, &uvalue, ct->range_bits)) ASN__DECODE_STARVED; @@ -614,15 +642,18 @@ INTEGER_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, if(asn_ulong2INTEGER(st, uvalue)) ASN__DECODE_FAILED; } else { - unsigned long svalue; + unsigned long uvalue = 0; + long svalue; if(uper_get_constrained_whole_number(pd, - &svalue, ct->range_bits)) + &uvalue, ct->range_bits)) ASN__DECODE_STARVED; - ASN_DEBUG("Got value %ld + low %ld", - svalue, ct->lower_bound); - svalue += ct->lower_bound; - if(asn_long2INTEGER(st, svalue)) - ASN__DECODE_FAILED; + ASN_DEBUG("Got value %lu + low %ld", + uvalue, ct->lower_bound); + if(per_long_range_unrebase(uvalue, ct->lower_bound, + ct->upper_bound, &svalue) + || asn_long2INTEGER(st, svalue)) { + ASN__DECODE_FAILED; + } } return rval; } @@ -632,12 +663,12 @@ INTEGER_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, /* X.691, #12.2.3, #12.2.4 */ do { - ssize_t len; - void *p; - int ret; + ssize_t len = 0; + void *p = NULL; + int ret = 0; /* Get the PER length */ - len = uper_get_length(pd, -1, &repeat); + len = uper_get_length(pd, -1, 0, &repeat); if(len < 0) ASN__DECODE_STARVED; p = REALLOC(st->buf, st->size + len + 1); @@ -655,10 +686,10 @@ INTEGER_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, /* * TODO: replace by in-place arithmetics. */ - long value; + long value = 0; if(asn_INTEGER2long(st, &value)) ASN__DECODE_FAILED; - if(asn_long2INTEGER(st, value + ct->lower_bound)) + if(asn_imax2INTEGER(st, value + ct->lower_bound)) ASN__DECODE_FAILED; } @@ -666,20 +697,21 @@ INTEGER_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, } asn_enc_rval_t -INTEGER_encode_uper(asn_TYPE_descriptor_t *td, - asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { - asn_INTEGER_specifics_t *specs=(asn_INTEGER_specifics_t *)td->specifics; - asn_enc_rval_t er; - INTEGER_t *st = (INTEGER_t *)sptr; +INTEGER_encode_uper(const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, const void *sptr, + asn_per_outp_t *po) { + const asn_INTEGER_specifics_t *specs = + (const asn_INTEGER_specifics_t *)td->specifics; + asn_enc_rval_t er; + const INTEGER_t *st = (const INTEGER_t *)sptr; const uint8_t *buf; const uint8_t *end; - asn_per_constraint_t *ct; + const asn_per_constraint_t *ct; long value = 0; - unsigned long v = 0; if(!st || st->size == 0) ASN__ENCODE_FAILED; - if(!constraints) constraints = td->per_constraints; + if(!constraints) constraints = td->encoding_constraints.per_constraints; ct = constraints ? &constraints->value : 0; er.encoded = 0; @@ -699,7 +731,7 @@ INTEGER_encode_uper(asn_TYPE_descriptor_t *td, || uval > (unsigned long)ct->upper_bound) inext = 1; } - ASN_DEBUG("Value %lu (%02x/%d) lb %lu ub %lu %s", + ASN_DEBUG("Value %lu (%02x/%" ASN_PRI_SIZE ") lb %lu ub %lu %s", uval, st->buf[0], st->size, ct->lower_bound, ct->upper_bound, inext ? "ext" : "fix"); @@ -716,7 +748,7 @@ INTEGER_encode_uper(asn_TYPE_descriptor_t *td, || value > ct->upper_bound) inext = 1; } - ASN_DEBUG("Value %ld (%02x/%d) lb %ld ub %ld %s", + ASN_DEBUG("Value %ld (%02x/%" ASN_PRI_SIZE ") lb %ld ub %ld %s", value, st->buf[0], st->size, ct->lower_bound, ct->upper_bound, inext ? "ext" : "fix"); @@ -733,12 +765,15 @@ INTEGER_encode_uper(asn_TYPE_descriptor_t *td, /* X.691-11/2008, #13.2.2, test if constrained whole number */ if(ct && ct->range_bits >= 0) { + unsigned long v; /* #11.5.6 -> #11.3 */ ASN_DEBUG("Encoding integer %ld (%lu) with range %d bits", value, value - ct->lower_bound, ct->range_bits); - v = value - ct->lower_bound; - if(uper_put_constrained_whole_number_u(po, v, ct->range_bits)) - ASN__ENCODE_FAILED; + if(per_long_range_rebase(value, ct->lower_bound, ct->upper_bound, &v)) { + ASN__ENCODE_FAILED; + } + if(uper_put_constrained_whole_number_u(po, v, ct->range_bits)) + ASN__ENCODE_FAILED; ASN__ENCODED_OK(er); } @@ -749,24 +784,45 @@ INTEGER_encode_uper(asn_TYPE_descriptor_t *td, } for(buf = st->buf, end = st->buf + st->size; buf < end;) { - ssize_t mayEncode = uper_put_length(po, end - buf); - if(mayEncode < 0) + int need_eom = 0; + ssize_t mayEncode = uper_put_length(po, end - buf, &need_eom); + if(mayEncode < 0) ASN__ENCODE_FAILED; if(per_put_many_bits(po, buf, 8 * mayEncode)) ASN__ENCODE_FAILED; buf += mayEncode; - } + if(need_eom && uper_put_length(po, 0, 0)) ASN__ENCODE_FAILED; + } ASN__ENCODED_OK(er); } #endif /* ASN_DISABLE_PER_SUPPORT */ +static intmax_t +asn__integer_convert(const uint8_t *b, const uint8_t *end) { + uintmax_t value; + + /* Perform the sign initialization */ + /* Actually value = -(*b >> 7); gains nothing, yet unreadable! */ + if((*b >> 7)) { + value = (uintmax_t)(-1); + } else { + value = 0; + } + + /* Conversion engine */ + for(; b < end; b++) { + value = (value << 8) | *b; + } + + return value; +} + int -asn_INTEGER2long(const INTEGER_t *iptr, long *lptr) { +asn_INTEGER2imax(const INTEGER_t *iptr, intmax_t *lptr) { uint8_t *b, *end; size_t size; - long l; /* Sanity checking */ if(!iptr || !iptr->buf || !lptr) { @@ -779,26 +835,26 @@ asn_INTEGER2long(const INTEGER_t *iptr, long *lptr) { size = iptr->size; end = b + size; /* Where to stop */ - if(size > sizeof(long)) { + if(size > sizeof(intmax_t)) { uint8_t *end1 = end - 1; /* * Slightly more advanced processing, - * able to >sizeof(long) bytes, - * when the actual value is small - * (0x0000000000abcdef would yield a fine 0x00abcdef) + * able to process INTEGERs with >sizeof(intmax_t) bytes + * when the actual value is small, e.g. for intmax_t == int32_t + * (0x0000000000abcdef INTEGER would yield a fine 0x00abcdef int32_t) */ /* Skip out the insignificant leading bytes */ for(; b < end1; b++) { switch(*b) { - case 0x00: if((b[1] & 0x80) == 0) continue; break; - case 0xff: if((b[1] & 0x80) != 0) continue; break; + case 0x00: if((b[1] & 0x80) == 0) continue; break; + case 0xff: if((b[1] & 0x80) != 0) continue; break; } break; } size = end - b; - if(size > sizeof(long)) { - /* Still cannot fit the long */ + if(size > sizeof(intmax_t)) { + /* Still cannot fit the sizeof(intmax_t) */ errno = ERANGE; return -1; } @@ -810,22 +866,15 @@ asn_INTEGER2long(const INTEGER_t *iptr, long *lptr) { return 0; } - /* Perform the sign initialization */ - /* Actually l = -(*b >> 7); gains nothing, yet unreadable! */ - if((*b >> 7)) l = -1; else l = 0; - - /* Conversion engine */ - for(; b < end; b++) - l = (l << 8) | *b; - - *lptr = l; + *lptr = asn__integer_convert(b, end); return 0; } +/* FIXME: negative INTEGER values are silently interpreted as large unsigned ones. */ int -asn_INTEGER2ulong(const INTEGER_t *iptr, unsigned long *lptr) { +asn_INTEGER2umax(const INTEGER_t *iptr, uintmax_t *lptr) { uint8_t *b, *end; - unsigned long l; + uintmax_t value; size_t size; if(!iptr || !iptr->buf || !lptr) { @@ -838,49 +887,50 @@ asn_INTEGER2ulong(const INTEGER_t *iptr, unsigned long *lptr) { end = b + size; /* If all extra leading bytes are zeroes, ignore them */ - for(; size > sizeof(unsigned long); b++, size--) { + for(; size > sizeof(value); b++, size--) { if(*b) { - /* Value won't fit unsigned long */ + /* Value won't fit into uintmax_t */ errno = ERANGE; return -1; } } /* Conversion engine */ - for(l = 0; b < end; b++) - l = (l << 8) | *b; + for(value = 0; b < end; b++) + value = (value << 8) | *b; - *lptr = l; + *lptr = value; return 0; } int -asn_ulong2INTEGER(INTEGER_t *st, unsigned long value) { - uint8_t *buf; - uint8_t *end; - uint8_t *b; - int shr; - - if(value <= LONG_MAX) - return asn_long2INTEGER(st, value); +asn_umax2INTEGER(INTEGER_t *st, uintmax_t value) { + uint8_t *buf; + uint8_t *end; + uint8_t *b; + int shr; + + if(value <= ((~(uintmax_t)0) >> 1)) { + return asn_imax2INTEGER(st, value); + } - buf = (uint8_t *)MALLOC(1 + sizeof(value)); - if(!buf) return -1; + buf = (uint8_t *)MALLOC(1 + sizeof(value)); + if(!buf) return -1; - end = buf + (sizeof(value) + 1); - buf[0] = 0; - for(b = buf + 1, shr = (sizeof(long)-1)*8; b < end; shr -= 8, b++) - *b = (uint8_t)(value >> shr); + end = buf + (sizeof(value) + 1); + buf[0] = 0; /* INTEGERs are signed. 0-byte indicates positive. */ + for(b = buf + 1, shr = (sizeof(value) - 1) * 8; b < end; shr -= 8, b++) + *b = (uint8_t)(value >> shr); - if(st->buf) FREEMEM(st->buf); - st->buf = buf; - st->size = 1 + sizeof(value); + if(st->buf) FREEMEM(st->buf); + st->buf = buf; + st->size = 1 + sizeof(value); return 0; } int -asn_long2INTEGER(INTEGER_t *st, long value) { +asn_imax2INTEGER(INTEGER_t *st, intmax_t value) { uint8_t *buf, *bp; uint8_t *p; uint8_t *pstart; @@ -893,7 +943,7 @@ asn_long2INTEGER(INTEGER_t *st, long value) { return -1; } - buf = (uint8_t *)MALLOC(sizeof(value)); + buf = (uint8_t *)(long *)MALLOC(sizeof(value)); if(!buf) return -1; if(*(char *)&littleEndian) { @@ -924,7 +974,7 @@ asn_long2INTEGER(INTEGER_t *st, long value) { break; } /* Copy the integer body */ - for(pstart = p, bp = buf, pend1 += add; p != pend1; p += add) + for(bp = buf, pend1 += add; p != pend1; p += add) *bp++ = *p; if(st->buf) FREEMEM(st->buf); @@ -934,92 +984,370 @@ asn_long2INTEGER(INTEGER_t *st, long value) { return 0; } +int +asn_INTEGER2long(const INTEGER_t *iptr, long *l) { + intmax_t v; + if(asn_INTEGER2imax(iptr, &v) == 0) { + if(v < LONG_MIN || v > LONG_MAX) { + errno = ERANGE; + return -1; + } + *l = v; + return 0; + } else { + return -1; + } +} + +int +asn_INTEGER2ulong(const INTEGER_t *iptr, unsigned long *l) { + uintmax_t v; + if(asn_INTEGER2umax(iptr, &v) == 0) { + if(v > ULONG_MAX) { + errno = ERANGE; + return -1; + } + *l = v; + return 0; + } else { + return -1; + } +} + +int +asn_long2INTEGER(INTEGER_t *st, long value) { + return asn_imax2INTEGER(st, value); +} + +int +asn_ulong2INTEGER(INTEGER_t *st, unsigned long value) { + return asn_imax2INTEGER(st, value); +} + /* - * This function is going to be DEPRECATED soon. + * Parse the number in the given string until the given *end position, + * returning the position after the last parsed character back using the + * same (*end) pointer. + * WARNING: This behavior is different from the standard strtol/strtoimax(3). */ -enum asn_strtol_result_e -asn_strtol(const char *str, const char *end, long *lp) { - const char *endp = end; - - switch(asn_strtol_lim(str, &endp, lp)) { - case ASN_STRTOL_ERROR_RANGE: - return ASN_STRTOL_ERROR_RANGE; - case ASN_STRTOL_ERROR_INVAL: - return ASN_STRTOL_ERROR_INVAL; - case ASN_STRTOL_EXPECT_MORE: - return ASN_STRTOL_ERROR_INVAL; /* Retain old behavior */ - case ASN_STRTOL_OK: - return ASN_STRTOL_OK; - case ASN_STRTOL_EXTRA_DATA: - return ASN_STRTOL_ERROR_INVAL; /* Retain old behavior */ +enum asn_strtox_result_e +asn_strtoimax_lim(const char *str, const char **end, intmax_t *intp) { + int sign = 1; + intmax_t value; + + const intmax_t asn1_intmax_max = ((~(uintmax_t)0) >> 1); + const intmax_t upper_boundary = asn1_intmax_max / 10; + intmax_t last_digit_max = asn1_intmax_max % 10; + + if(str >= *end) return ASN_STRTOX_ERROR_INVAL; + + switch(*str) { + case '-': + last_digit_max++; + sign = -1; + /* FALL THROUGH */ + case '+': + str++; + if(str >= *end) { + *end = str; + return ASN_STRTOX_EXPECT_MORE; + } + } + + for(value = 0; str < (*end); str++) { + if(*str >= 0x30 && *str <= 0x39) { + int d = *str - '0'; + if(value < upper_boundary) { + value = value * 10 + d; + } else if(value == upper_boundary) { + if(d <= last_digit_max) { + if(sign > 0) { + value = value * 10 + d; + } else { + sign = 1; + value = -value * 10 - d; + } + str += 1; + if(str < *end) { + // If digits continue, we're guaranteed out of range. + *end = str; + if(*str >= 0x30 && *str <= 0x39) { + return ASN_STRTOX_ERROR_RANGE; + } else { + *intp = sign * value; + return ASN_STRTOX_EXTRA_DATA; + } + } + break; + } else { + *end = str; + return ASN_STRTOX_ERROR_RANGE; + } + } else { + *end = str; + return ASN_STRTOX_ERROR_RANGE; + } + } else { + *end = str; + *intp = sign * value; + return ASN_STRTOX_EXTRA_DATA; + } } - return ASN_STRTOL_ERROR_INVAL; /* Retain old behavior */ + *end = str; + *intp = sign * value; + return ASN_STRTOX_OK; } /* * Parse the number in the given string until the given *end position, * returning the position after the last parsed character back using the * same (*end) pointer. - * WARNING: This behavior is different from the standard strtol(3). + * WARNING: This behavior is different from the standard strtoul/strtoumax(3). */ -enum asn_strtol_result_e +enum asn_strtox_result_e +asn_strtoumax_lim(const char *str, const char **end, uintmax_t *uintp) { + uintmax_t value; + + const uintmax_t asn1_uintmax_max = ((~(uintmax_t)0)); + const uintmax_t upper_boundary = asn1_uintmax_max / 10; + uintmax_t last_digit_max = asn1_uintmax_max % 10; + + if(str >= *end) return ASN_STRTOX_ERROR_INVAL; + + switch(*str) { + case '-': + return ASN_STRTOX_ERROR_INVAL; + case '+': + str++; + if(str >= *end) { + *end = str; + return ASN_STRTOX_EXPECT_MORE; + } + } + + for(value = 0; str < (*end); str++) { + if(*str >= 0x30 && *str <= 0x39) { + unsigned int d = *str - '0'; + if(value < upper_boundary) { + value = value * 10 + d; + } else if(value == upper_boundary) { + if(d <= last_digit_max) { + value = value * 10 + d; + str += 1; + if(str < *end) { + // If digits continue, we're guaranteed out of range. + *end = str; + if(*str >= 0x30 && *str <= 0x39) { + return ASN_STRTOX_ERROR_RANGE; + } else { + *uintp = value; + return ASN_STRTOX_EXTRA_DATA; + } + } + break; + } else { + *end = str; + return ASN_STRTOX_ERROR_RANGE; + } + } else { + *end = str; + return ASN_STRTOX_ERROR_RANGE; + } + } else { + *end = str; + *uintp = value; + return ASN_STRTOX_EXTRA_DATA; + } + } + + *end = str; + *uintp = value; + return ASN_STRTOX_OK; +} + +enum asn_strtox_result_e asn_strtol_lim(const char *str, const char **end, long *lp) { - int sign = 1; - long l; + intmax_t value; + switch(asn_strtoimax_lim(str, end, &value)) { + case ASN_STRTOX_ERROR_RANGE: + return ASN_STRTOX_ERROR_RANGE; + case ASN_STRTOX_ERROR_INVAL: + return ASN_STRTOX_ERROR_INVAL; + case ASN_STRTOX_EXPECT_MORE: + return ASN_STRTOX_EXPECT_MORE; + case ASN_STRTOX_OK: + if(value >= LONG_MIN && value <= LONG_MAX) { + *lp = value; + return ASN_STRTOX_OK; + } else { + return ASN_STRTOX_ERROR_RANGE; + } + case ASN_STRTOX_EXTRA_DATA: + if(value >= LONG_MIN && value <= LONG_MAX) { + *lp = value; + return ASN_STRTOX_EXTRA_DATA; + } else { + return ASN_STRTOX_ERROR_RANGE; + } + } - const long upper_boundary = LONG_MAX / 10; - long last_digit_max = LONG_MAX % 10; + assert(!"Unreachable"); + return ASN_STRTOX_ERROR_INVAL; +} - if(str >= *end) return ASN_STRTOL_ERROR_INVAL; +enum asn_strtox_result_e +asn_strtoul_lim(const char *str, const char **end, unsigned long *ulp) { + uintmax_t value; + switch(asn_strtoumax_lim(str, end, &value)) { + case ASN_STRTOX_ERROR_RANGE: + return ASN_STRTOX_ERROR_RANGE; + case ASN_STRTOX_ERROR_INVAL: + return ASN_STRTOX_ERROR_INVAL; + case ASN_STRTOX_EXPECT_MORE: + return ASN_STRTOX_EXPECT_MORE; + case ASN_STRTOX_OK: + if(value <= ULONG_MAX) { + *ulp = value; + return ASN_STRTOX_OK; + } else { + return ASN_STRTOX_ERROR_RANGE; + } + case ASN_STRTOX_EXTRA_DATA: + if(value <= ULONG_MAX) { + *ulp = value; + return ASN_STRTOX_EXTRA_DATA; + } else { + return ASN_STRTOX_ERROR_RANGE; + } + } - switch(*str) { - case '-': - last_digit_max++; - sign = -1; - /* FALL THROUGH */ - case '+': - str++; - if(str >= *end) { - *end = str; - return ASN_STRTOL_EXPECT_MORE; - } - } + assert(!"Unreachable"); + return ASN_STRTOX_ERROR_INVAL; +} - for(l = 0; str < (*end); str++) { - switch(*str) { - case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: - case 0x35: case 0x36: case 0x37: case 0x38: case 0x39: { - int d = *str - '0'; - if(l < upper_boundary) { - l = l * 10 + d; - } else if(l == upper_boundary) { - if(d <= last_digit_max) { - if(sign > 0) { - l = l * 10 + d; - } else { - sign = 1; - l = -l * 10 - d; - } - } else { - *end = str; - return ASN_STRTOL_ERROR_RANGE; - } - } else { - *end = str; - return ASN_STRTOL_ERROR_RANGE; - } - } - continue; - default: - *end = str; - *lp = sign * l; - return ASN_STRTOL_EXTRA_DATA; - } - } +int +INTEGER_compare(const asn_TYPE_descriptor_t *td, const void *aptr, + const void *bptr) { + const INTEGER_t *a = aptr; + const INTEGER_t *b = bptr; + + (void)td; + + if(a && b) { + if(a->size && b->size) { + int sign_a = (a->buf[0] & 0x80) ? -1 : 1; + int sign_b = (b->buf[0] & 0x80) ? -1 : 1; + + if(sign_a < sign_b) return -1; + if(sign_a > sign_b) return 1; + + /* The shortest integer wins, unless comparing negatives */ + if(a->size < b->size) { + return -1 * sign_a; + } else if(a->size > b->size) { + return 1 * sign_b; + } + + return sign_a * memcmp(a->buf, b->buf, a->size); + } else if(a->size) { + int sign = (a->buf[0] & 0x80) ? -1 : 1; + return (1) * sign; + } else if(b->size) { + int sign = (a->buf[0] & 0x80) ? -1 : 1; + return (-1) * sign; + } else { + return 0; + } + } else if(!a && !b) { + return 0; + } else if(!a) { + return -1; + } else { + return 1; + } - *end = str; - *lp = sign * l; - return ASN_STRTOL_OK; } +asn_random_fill_result_t +INTEGER_random_fill(const asn_TYPE_descriptor_t *td, void **sptr, + const asn_encoding_constraints_t *constraints, + size_t max_length) { + const asn_INTEGER_specifics_t *specs = + (const asn_INTEGER_specifics_t *)td->specifics; + asn_random_fill_result_t result_ok = {ARFILL_OK, 1}; + asn_random_fill_result_t result_failed = {ARFILL_FAILED, 0}; + asn_random_fill_result_t result_skipped = {ARFILL_SKIPPED, 0}; + INTEGER_t *st = *sptr; + const asn_INTEGER_enum_map_t *emap; + size_t emap_len; + intmax_t value; + int find_inside_map; + + if(max_length == 0) return result_skipped; + + if(st == NULL) { + st = (INTEGER_t *)CALLOC(1, sizeof(*st)); + if(st == NULL) { + return result_failed; + } + } + + if(specs) { + emap = specs->value2enum; + emap_len = specs->map_count; + if(specs->strict_enumeration) { + find_inside_map = emap_len > 0; + } else { + find_inside_map = emap_len ? asn_random_between(0, 1) : 0; + } + } else { + emap = 0; + emap_len = 0; + find_inside_map = 0; + } + + if(find_inside_map) { + assert(emap_len > 0); + value = emap[asn_random_between(0, emap_len - 1)].nat_value; + } else { + const asn_per_constraints_t *ct; + + static const long variants[] = { + -65536, -65535, -65534, -32769, -32768, -32767, -16385, -16384, + -16383, -257, -256, -255, -254, -129, -128, -127, + -126, -1, 0, 1, 126, 127, 128, 129, + 254, 255, 256, 257, 16383, 16384, 16385, 32767, + 32768, 32769, 65534, 65535, 65536, 65537}; + if(specs && specs->field_unsigned) { + assert(variants[18] == 0); + value = variants[asn_random_between( + 18, sizeof(variants) / sizeof(variants[0]) - 1)]; + } else { + value = variants[asn_random_between( + 0, sizeof(variants) / sizeof(variants[0]) - 1)]; + } + + if(!constraints) constraints = &td->encoding_constraints; + ct = constraints ? constraints->per_constraints : 0; + if(ct && (ct->value.flags & APC_CONSTRAINED)) { + if(value < ct->value.lower_bound || value > ct->value.upper_bound) { + value = asn_random_between(ct->value.lower_bound, + ct->value.upper_bound); + } + } + } + + if(asn_imax2INTEGER(st, value)) { + if(st == *sptr) { + ASN_STRUCT_RESET(*td, st); + } else { + ASN_STRUCT_FREE(*td, st); + } + return result_failed; + } else { + *sptr = st; + result_ok.length = st->size; + return result_ok; + } +} diff --git a/libs/smux/INTEGER_oer.c b/libs/smux/INTEGER_oer.c new file mode 100644 index 00000000..5c98d3e7 --- /dev/null +++ b/libs/smux/INTEGER_oer.c @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2017 Lev Walkin . + * All rights reserved. + * Redistribution and modifications are permitted subject to BSD license. + */ +#ifndef ASN_DISABLE_OER_SUPPORT + +#include +#include +#include + +asn_dec_rval_t +INTEGER_decode_oer(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *td, + const asn_oer_constraints_t *constraints, void **sptr, + const void *ptr, size_t size) { + const asn_INTEGER_specifics_t *specs = + (const asn_INTEGER_specifics_t *)td->specifics; + asn_dec_rval_t rval = {RC_OK, 0}; + INTEGER_t *st = (INTEGER_t *)*sptr; + struct asn_oer_constraint_number_s ct = {0, 0}; + size_t req_bytes; + + (void)opt_codec_ctx; + (void)specs; + + if(!st) { + st = (INTEGER_t *)(*sptr = CALLOC(1, sizeof(*st))); + if(!st) ASN__DECODE_FAILED; + } + + FREEMEM(st->buf); + st->buf = 0; + st->size = 0; + + if(!constraints) constraints = td->encoding_constraints.oer_constraints; + if(constraints) ct = constraints->value; + + if(ct.width) { + req_bytes = ct.width; + } else { + /* No lower bound and no upper bound, effectively */ + + ssize_t consumed = oer_fetch_length(ptr, size, &req_bytes); + if(consumed == 0) { + ASN__DECODE_STARVED; + } else if(consumed == -1) { + ASN__DECODE_FAILED; + } + rval.consumed += consumed; + ptr = (const char *)ptr + consumed; + size -= consumed; + } + + if(req_bytes > size) { + ASN__DECODE_STARVED; + } + + if(ct.positive) { + /* X.969 08/2015 10.2(a) */ + unsigned msb; /* Most significant bit */ + size_t useful_size; + + /* Check most significant bit */ + msb = *(const uint8_t *)ptr >> 7; /* yields 0 or 1 */ + useful_size = msb + req_bytes; + st->buf = (uint8_t *)MALLOC(useful_size + 1); + if(!st->buf) { + ASN__DECODE_FAILED; + } + + /* + * Record a large unsigned in a way not to confuse it + * with signed value. + */ + st->buf[0] = '\0'; + memcpy(st->buf + msb, ptr, req_bytes); + st->buf[useful_size] = '\0'; /* Just in case, 0-terminate */ + st->size = useful_size; + + rval.consumed += req_bytes; + return rval; + } else { + /* X.969 08/2015 10.2(b) */ + st->buf = (uint8_t *)MALLOC(req_bytes + 1); + if(!st->buf) { + ASN__DECODE_FAILED; + } + + memcpy(st->buf, ptr, req_bytes); + st->buf[req_bytes] = '\0'; /* Just in case, 0-terminate */ + st->size = req_bytes; + + rval.consumed += req_bytes; + return rval; + } +} + +/* + * Encode as Canonical OER. + */ +asn_enc_rval_t +INTEGER_encode_oer(const asn_TYPE_descriptor_t *td, + const asn_oer_constraints_t *constraints, const void *sptr, + asn_app_consume_bytes_f *cb, void *app_key) { + const INTEGER_t *st = sptr; + asn_enc_rval_t er; + struct asn_oer_constraint_number_s ct = {0, 0}; + const uint8_t *buf; + const uint8_t *end; + size_t useful_bytes; + size_t req_bytes = 0; + int sign = 0; + + if(!st || st->size == 0) ASN__ENCODE_FAILED; + + if(!constraints) constraints = td->encoding_constraints.oer_constraints; + if(constraints) ct = constraints->value; + + er.encoded = 0; + + buf = st->buf; + end = buf + st->size; + + sign = (buf && buf < end) ? buf[0] & 0x80 : 0; + + /* Ignore 9 leading zeroes or ones */ + if(ct.positive) { + if(sign) { + /* The value given is a signed value. Can't proceed. */ + ASN__ENCODE_FAILED; + } + /* Remove leading zeros. */ + for(; buf + 1 < end; buf++) { + if(buf[0] != 0x0) break; + } + } else { + for(; buf + 1 < end; buf++) { + if(buf[0] == 0x0 && (buf[1] & 0x80) == 0) { + continue; + } else if(buf[0] == 0xff && (buf[1] & 0x80) != 0) { + continue; + } + break; + } + } + + useful_bytes = end - buf; + if(ct.width) { + req_bytes = ct.width; + } else { + ssize_t r = oer_serialize_length(useful_bytes, cb, app_key); + if(r < 0) { + ASN__ENCODE_FAILED; + } + er.encoded += r; + req_bytes = useful_bytes; + } + + if(req_bytes < useful_bytes) { + ASN__ENCODE_FAILED; + } + + er.encoded += req_bytes; + + for(; req_bytes > useful_bytes; req_bytes--) { + if(cb(sign?"\xff":"\0", 1, app_key) < 0) { + ASN__ENCODE_FAILED; + } + } + + if(cb(buf, useful_bytes, app_key) < 0) { + ASN__ENCODE_FAILED; + } + + ASN__ENCODED_OK(er); +} + +#endif /* ASN_DISABLE_OER_SUPPORT */ diff --git a/libs/smux/IfEntry.c b/libs/smux/IfEntry.c index ad2e29d9..85806373 100644 --- a/libs/smux/IfEntry.c +++ b/libs/smux/IfEntry.c @@ -1,8 +1,8 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1213-MIB" * found in "RFC1213-MIB.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #include "IfEntry.h" @@ -12,198 +12,198 @@ static asn_TYPE_member_t asn_MBR_IfEntry_1[] = { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, &asn_DEF_INTEGER, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "ifIndex" }, { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifDescr), (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), 0, &asn_DEF_DisplayString, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "ifDescr" }, { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifType), (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, &asn_DEF_INTEGER, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "ifType" }, { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifMtu), (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, &asn_DEF_INTEGER, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "ifMtu" }, { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifSpeed), (ASN_TAG_CLASS_APPLICATION | (2 << 2)), 0, &asn_DEF_Gauge, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "ifSpeed" }, { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifPhysAddress), (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), 0, &asn_DEF_PhysAddress, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "ifPhysAddress" }, { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifAdminStatus), (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, &asn_DEF_INTEGER, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "ifAdminStatus" }, { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifOperStatus), (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, &asn_DEF_INTEGER, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "ifOperStatus" }, { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifLastChange), (ASN_TAG_CLASS_APPLICATION | (3 << 2)), 0, &asn_DEF_TimeTicks, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "ifLastChange" }, { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifInOctets), (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 0, &asn_DEF_Counter, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "ifInOctets" }, { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifInUcastPkts), (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 0, &asn_DEF_Counter, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "ifInUcastPkts" }, { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifInNUcastPkts), (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 0, &asn_DEF_Counter, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "ifInNUcastPkts" }, { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifInDiscards), (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 0, &asn_DEF_Counter, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "ifInDiscards" }, { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifInErrors), (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 0, &asn_DEF_Counter, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "ifInErrors" }, { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifInUnknownProtos), (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 0, &asn_DEF_Counter, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "ifInUnknownProtos" }, { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifOutOctets), (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 0, &asn_DEF_Counter, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "ifOutOctets" }, { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifOutUcastPkts), (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 0, &asn_DEF_Counter, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "ifOutUcastPkts" }, { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifOutNUcastPkts), (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 0, &asn_DEF_Counter, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "ifOutNUcastPkts" }, { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifOutDiscards), (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 0, &asn_DEF_Counter, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "ifOutDiscards" }, { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifOutErrors), (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 0, &asn_DEF_Counter, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "ifOutErrors" }, { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifOutQLen), (ASN_TAG_CLASS_APPLICATION | (2 << 2)), 0, &asn_DEF_Gauge, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "ifOutQLen" }, { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifSpecific), (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)), 0, &asn_DEF_OBJECT_IDENTIFIER, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "ifSpecific" }, }; @@ -240,28 +240,19 @@ static asn_SEQUENCE_specifics_t asn_SPC_IfEntry_specs_1 = { asn_MAP_IfEntry_tag2el_1, 22, /* Count of tags in the map */ 0, 0, 0, /* Optional elements (not needed) */ - -1, /* Start extensions */ - -1 /* Stop extensions */ + -1, /* First extension addition */ }; asn_TYPE_descriptor_t asn_DEF_IfEntry = { "IfEntry", "IfEntry", - SEQUENCE_free, - SEQUENCE_print, - SEQUENCE_constraint, - SEQUENCE_decode_ber, - SEQUENCE_encode_der, - SEQUENCE_decode_xer, - SEQUENCE_encode_xer, - 0, 0, /* No PER support, use "-gen-PER" to enable */ - 0, /* Use generic outmost tag fetcher */ + &asn_OP_SEQUENCE, asn_DEF_IfEntry_tags_1, sizeof(asn_DEF_IfEntry_tags_1) /sizeof(asn_DEF_IfEntry_tags_1[0]), /* 1 */ asn_DEF_IfEntry_tags_1, /* Same as above */ sizeof(asn_DEF_IfEntry_tags_1) /sizeof(asn_DEF_IfEntry_tags_1[0]), /* 1 */ - 0, /* No PER visible constraints */ + { 0, 0, SEQUENCE_constraint }, asn_MBR_IfEntry_1, 22, /* Elements count */ &asn_SPC_IfEntry_specs_1 /* Additional specs */ diff --git a/libs/smux/IpAddrEntry.c b/libs/smux/IpAddrEntry.c index bccd1550..22f8b8d5 100644 --- a/libs/smux/IpAddrEntry.c +++ b/libs/smux/IpAddrEntry.c @@ -1,14 +1,14 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1213-MIB" * found in "RFC1213-MIB.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #include "IpAddrEntry.h" static int -memb_ipAdEntReasmMaxSize_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr, +memb_ipAdEntReasmMaxSize_constraint_1(const asn_TYPE_descriptor_t *td, const void *sptr, asn_app_constraint_failed_f *ctfailcb, void *app_key) { long value; @@ -32,50 +32,58 @@ memb_ipAdEntReasmMaxSize_constraint_1(asn_TYPE_descriptor_t *td, const void *spt } } +static asn_oer_constraints_t asn_OER_memb_ipAdEntReasmMaxSize_constr_6 CC_NOTUSED = { + { 2, 1 } /* (0..65535) */, + -1}; +static asn_per_constraints_t asn_PER_memb_ipAdEntReasmMaxSize_constr_6 CC_NOTUSED = { + { APC_CONSTRAINED, 16, 16, 0, 65535 } /* (0..65535) */, + { APC_UNCONSTRAINED, -1, -1, 0, 0 }, + 0, 0 /* No PER value map */ +}; static asn_TYPE_member_t asn_MBR_IpAddrEntry_1[] = { { ATF_NOFLAGS, 0, offsetof(struct IpAddrEntry, ipAdEntAddr), (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 0, &asn_DEF_IpAddress, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "ipAdEntAddr" }, { ATF_NOFLAGS, 0, offsetof(struct IpAddrEntry, ipAdEntIfIndex), (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, &asn_DEF_INTEGER, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "ipAdEntIfIndex" }, { ATF_NOFLAGS, 0, offsetof(struct IpAddrEntry, ipAdEntNetMask), (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 0, &asn_DEF_IpAddress, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "ipAdEntNetMask" }, { ATF_NOFLAGS, 0, offsetof(struct IpAddrEntry, ipAdEntBcastAddr), (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, &asn_DEF_INTEGER, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "ipAdEntBcastAddr" }, { ATF_NOFLAGS, 0, offsetof(struct IpAddrEntry, ipAdEntReasmMaxSize), (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, &asn_DEF_NativeInteger, - memb_ipAdEntReasmMaxSize_constraint_1, - 0, /* PER is not compiled, use -gen-PER */ 0, + { &asn_OER_memb_ipAdEntReasmMaxSize_constr_6, &asn_PER_memb_ipAdEntReasmMaxSize_constr_6, memb_ipAdEntReasmMaxSize_constraint_1 }, + 0, 0, /* No default value */ "ipAdEntReasmMaxSize" }, }; @@ -95,28 +103,19 @@ static asn_SEQUENCE_specifics_t asn_SPC_IpAddrEntry_specs_1 = { asn_MAP_IpAddrEntry_tag2el_1, 5, /* Count of tags in the map */ 0, 0, 0, /* Optional elements (not needed) */ - -1, /* Start extensions */ - -1 /* Stop extensions */ + -1, /* First extension addition */ }; asn_TYPE_descriptor_t asn_DEF_IpAddrEntry = { "IpAddrEntry", "IpAddrEntry", - SEQUENCE_free, - SEQUENCE_print, - SEQUENCE_constraint, - SEQUENCE_decode_ber, - SEQUENCE_encode_der, - SEQUENCE_decode_xer, - SEQUENCE_encode_xer, - 0, 0, /* No PER support, use "-gen-PER" to enable */ - 0, /* Use generic outmost tag fetcher */ + &asn_OP_SEQUENCE, asn_DEF_IpAddrEntry_tags_1, sizeof(asn_DEF_IpAddrEntry_tags_1) /sizeof(asn_DEF_IpAddrEntry_tags_1[0]), /* 1 */ asn_DEF_IpAddrEntry_tags_1, /* Same as above */ sizeof(asn_DEF_IpAddrEntry_tags_1) /sizeof(asn_DEF_IpAddrEntry_tags_1[0]), /* 1 */ - 0, /* No PER visible constraints */ + { 0, 0, SEQUENCE_constraint }, asn_MBR_IpAddrEntry_1, 5, /* Elements count */ &asn_SPC_IpAddrEntry_specs_1 /* Additional specs */ diff --git a/libs/smux/IpAddress.c b/libs/smux/IpAddress.c index 2eaebf9b..7eec1b5c 100644 --- a/libs/smux/IpAddress.c +++ b/libs/smux/IpAddress.c @@ -1,14 +1,14 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1155-SMI" * found in "RFC1155-SMI.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #include "IpAddress.h" int -IpAddress_constraint(asn_TYPE_descriptor_t *td, const void *sptr, +IpAddress_constraint(const asn_TYPE_descriptor_t *td, const void *sptr, asn_app_constraint_failed_f *ctfailcb, void *app_key) { const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr; size_t size; @@ -37,68 +37,14 @@ IpAddress_constraint(asn_TYPE_descriptor_t *td, const void *sptr, * This type is implemented using OCTET_STRING, * so here we adjust the DEF accordingly. */ -static void -IpAddress_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) { - td->free_struct = asn_DEF_OCTET_STRING.free_struct; - td->print_struct = asn_DEF_OCTET_STRING.print_struct; - td->check_constraints = asn_DEF_OCTET_STRING.check_constraints; - td->ber_decoder = asn_DEF_OCTET_STRING.ber_decoder; - td->der_encoder = asn_DEF_OCTET_STRING.der_encoder; - td->xer_decoder = asn_DEF_OCTET_STRING.xer_decoder; - td->xer_encoder = asn_DEF_OCTET_STRING.xer_encoder; - td->uper_decoder = asn_DEF_OCTET_STRING.uper_decoder; - td->uper_encoder = asn_DEF_OCTET_STRING.uper_encoder; - if(!td->per_constraints) - td->per_constraints = asn_DEF_OCTET_STRING.per_constraints; - td->elements = asn_DEF_OCTET_STRING.elements; - td->elements_count = asn_DEF_OCTET_STRING.elements_count; - td->specifics = asn_DEF_OCTET_STRING.specifics; -} - -void -IpAddress_free(asn_TYPE_descriptor_t *td, - void *struct_ptr, int contents_only) { - IpAddress_1_inherit_TYPE_descriptor(td); - td->free_struct(td, struct_ptr, contents_only); -} - -int -IpAddress_print(asn_TYPE_descriptor_t *td, const void *struct_ptr, - int ilevel, asn_app_consume_bytes_f *cb, void *app_key) { - IpAddress_1_inherit_TYPE_descriptor(td); - return td->print_struct(td, struct_ptr, ilevel, cb, app_key); -} - -asn_dec_rval_t -IpAddress_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, - void **structure, const void *bufptr, size_t size, int tag_mode) { - IpAddress_1_inherit_TYPE_descriptor(td); - return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode); -} - -asn_enc_rval_t -IpAddress_encode_der(asn_TYPE_descriptor_t *td, - void *structure, int tag_mode, ber_tlv_tag_t tag, - asn_app_consume_bytes_f *cb, void *app_key) { - IpAddress_1_inherit_TYPE_descriptor(td); - return td->der_encoder(td, structure, tag_mode, tag, cb, app_key); -} - -asn_dec_rval_t -IpAddress_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, - void **structure, const char *opt_mname, const void *bufptr, size_t size) { - IpAddress_1_inherit_TYPE_descriptor(td); - return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size); -} - -asn_enc_rval_t -IpAddress_encode_xer(asn_TYPE_descriptor_t *td, void *structure, - int ilevel, enum xer_encoder_flags_e flags, - asn_app_consume_bytes_f *cb, void *app_key) { - IpAddress_1_inherit_TYPE_descriptor(td); - return td->xer_encoder(td, structure, ilevel, flags, cb, app_key); -} - +static asn_oer_constraints_t asn_OER_type_IpAddress_constr_1 CC_NOTUSED = { + { 0, 0 }, + 4 /* (SIZE(4..4)) */}; +asn_per_constraints_t asn_PER_type_IpAddress_constr_1 CC_NOTUSED = { + { APC_UNCONSTRAINED, -1, -1, 0, 0 }, + { APC_CONSTRAINED, 0, 0, 4, 4 } /* (SIZE(4..4)) */, + 0, 0 /* No PER value map */ +}; static const ber_tlv_tag_t asn_DEF_IpAddress_tags_1[] = { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)) @@ -106,23 +52,15 @@ static const ber_tlv_tag_t asn_DEF_IpAddress_tags_1[] = { asn_TYPE_descriptor_t asn_DEF_IpAddress = { "IpAddress", "IpAddress", - IpAddress_free, - IpAddress_print, - IpAddress_constraint, - IpAddress_decode_ber, - IpAddress_encode_der, - IpAddress_decode_xer, - IpAddress_encode_xer, - 0, 0, /* No PER support, use "-gen-PER" to enable */ - 0, /* Use generic outmost tag fetcher */ + &asn_OP_OCTET_STRING, asn_DEF_IpAddress_tags_1, sizeof(asn_DEF_IpAddress_tags_1) /sizeof(asn_DEF_IpAddress_tags_1[0]) - 1, /* 1 */ asn_DEF_IpAddress_tags_1, /* Same as above */ sizeof(asn_DEF_IpAddress_tags_1) /sizeof(asn_DEF_IpAddress_tags_1[0]), /* 2 */ - 0, /* No PER visible constraints */ + { &asn_OER_type_IpAddress_constr_1, &asn_PER_type_IpAddress_constr_1, IpAddress_constraint }, 0, 0, /* No members */ - 0 /* No specifics */ + &asn_SPC_OCTET_STRING_specs /* Additional specs */ }; diff --git a/libs/smux/IpNetToMediaEntry.c b/libs/smux/IpNetToMediaEntry.c index ce6aa6d2..6c19cde6 100644 --- a/libs/smux/IpNetToMediaEntry.c +++ b/libs/smux/IpNetToMediaEntry.c @@ -1,8 +1,8 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1213-MIB" * found in "RFC1213-MIB.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #include "IpNetToMediaEntry.h" @@ -12,36 +12,36 @@ static asn_TYPE_member_t asn_MBR_IpNetToMediaEntry_1[] = { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, &asn_DEF_INTEGER, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "ipNetToMediaIfIndex" }, { ATF_NOFLAGS, 0, offsetof(struct IpNetToMediaEntry, ipNetToMediaPhysAddress), (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), 0, &asn_DEF_PhysAddress, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "ipNetToMediaPhysAddress" }, { ATF_NOFLAGS, 0, offsetof(struct IpNetToMediaEntry, ipNetToMediaNetAddress), (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 0, &asn_DEF_IpAddress, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "ipNetToMediaNetAddress" }, { ATF_NOFLAGS, 0, offsetof(struct IpNetToMediaEntry, ipNetToMediaType), (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, &asn_DEF_INTEGER, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "ipNetToMediaType" }, }; @@ -60,28 +60,19 @@ static asn_SEQUENCE_specifics_t asn_SPC_IpNetToMediaEntry_specs_1 = { asn_MAP_IpNetToMediaEntry_tag2el_1, 4, /* Count of tags in the map */ 0, 0, 0, /* Optional elements (not needed) */ - -1, /* Start extensions */ - -1 /* Stop extensions */ + -1, /* First extension addition */ }; asn_TYPE_descriptor_t asn_DEF_IpNetToMediaEntry = { "IpNetToMediaEntry", "IpNetToMediaEntry", - SEQUENCE_free, - SEQUENCE_print, - SEQUENCE_constraint, - SEQUENCE_decode_ber, - SEQUENCE_encode_der, - SEQUENCE_decode_xer, - SEQUENCE_encode_xer, - 0, 0, /* No PER support, use "-gen-PER" to enable */ - 0, /* Use generic outmost tag fetcher */ + &asn_OP_SEQUENCE, asn_DEF_IpNetToMediaEntry_tags_1, sizeof(asn_DEF_IpNetToMediaEntry_tags_1) /sizeof(asn_DEF_IpNetToMediaEntry_tags_1[0]), /* 1 */ asn_DEF_IpNetToMediaEntry_tags_1, /* Same as above */ sizeof(asn_DEF_IpNetToMediaEntry_tags_1) /sizeof(asn_DEF_IpNetToMediaEntry_tags_1[0]), /* 1 */ - 0, /* No PER visible constraints */ + { 0, 0, SEQUENCE_constraint }, asn_MBR_IpNetToMediaEntry_1, 4, /* Elements count */ &asn_SPC_IpNetToMediaEntry_specs_1 /* Additional specs */ diff --git a/libs/smux/IpRouteEntry.c b/libs/smux/IpRouteEntry.c index 5ee104ea..c0b54fe8 100644 --- a/libs/smux/IpRouteEntry.c +++ b/libs/smux/IpRouteEntry.c @@ -1,8 +1,8 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1213-MIB" * found in "RFC1213-MIB.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #include "IpRouteEntry.h" @@ -12,117 +12,117 @@ static asn_TYPE_member_t asn_MBR_IpRouteEntry_1[] = { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 0, &asn_DEF_IpAddress, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "ipRouteDest" }, { ATF_NOFLAGS, 0, offsetof(struct IpRouteEntry, ipRouteIfIndex), (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, &asn_DEF_INTEGER, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "ipRouteIfIndex" }, { ATF_NOFLAGS, 0, offsetof(struct IpRouteEntry, ipRouteMetric1), (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, &asn_DEF_INTEGER, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "ipRouteMetric1" }, { ATF_NOFLAGS, 0, offsetof(struct IpRouteEntry, ipRouteMetric2), (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, &asn_DEF_INTEGER, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "ipRouteMetric2" }, { ATF_NOFLAGS, 0, offsetof(struct IpRouteEntry, ipRouteMetric3), (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, &asn_DEF_INTEGER, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "ipRouteMetric3" }, { ATF_NOFLAGS, 0, offsetof(struct IpRouteEntry, ipRouteMetric4), (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, &asn_DEF_INTEGER, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "ipRouteMetric4" }, { ATF_NOFLAGS, 0, offsetof(struct IpRouteEntry, ipRouteNextHop), (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 0, &asn_DEF_IpAddress, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "ipRouteNextHop" }, { ATF_NOFLAGS, 0, offsetof(struct IpRouteEntry, ipRouteType), (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, &asn_DEF_INTEGER, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "ipRouteType" }, { ATF_NOFLAGS, 0, offsetof(struct IpRouteEntry, ipRouteProto), (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, &asn_DEF_INTEGER, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "ipRouteProto" }, { ATF_NOFLAGS, 0, offsetof(struct IpRouteEntry, ipRouteAge), (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, &asn_DEF_INTEGER, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "ipRouteAge" }, { ATF_NOFLAGS, 0, offsetof(struct IpRouteEntry, ipRouteMask), (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 0, &asn_DEF_IpAddress, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "ipRouteMask" }, { ATF_NOFLAGS, 0, offsetof(struct IpRouteEntry, ipRouteMetric5), (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, &asn_DEF_INTEGER, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "ipRouteMetric5" }, { ATF_NOFLAGS, 0, offsetof(struct IpRouteEntry, ipRouteInfo), (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)), 0, &asn_DEF_OBJECT_IDENTIFIER, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "ipRouteInfo" }, }; @@ -150,28 +150,19 @@ static asn_SEQUENCE_specifics_t asn_SPC_IpRouteEntry_specs_1 = { asn_MAP_IpRouteEntry_tag2el_1, 13, /* Count of tags in the map */ 0, 0, 0, /* Optional elements (not needed) */ - -1, /* Start extensions */ - -1 /* Stop extensions */ + -1, /* First extension addition */ }; asn_TYPE_descriptor_t asn_DEF_IpRouteEntry = { "IpRouteEntry", "IpRouteEntry", - SEQUENCE_free, - SEQUENCE_print, - SEQUENCE_constraint, - SEQUENCE_decode_ber, - SEQUENCE_encode_der, - SEQUENCE_decode_xer, - SEQUENCE_encode_xer, - 0, 0, /* No PER support, use "-gen-PER" to enable */ - 0, /* Use generic outmost tag fetcher */ + &asn_OP_SEQUENCE, asn_DEF_IpRouteEntry_tags_1, sizeof(asn_DEF_IpRouteEntry_tags_1) /sizeof(asn_DEF_IpRouteEntry_tags_1[0]), /* 1 */ asn_DEF_IpRouteEntry_tags_1, /* Same as above */ sizeof(asn_DEF_IpRouteEntry_tags_1) /sizeof(asn_DEF_IpRouteEntry_tags_1[0]), /* 1 */ - 0, /* No PER visible constraints */ + { 0, 0, SEQUENCE_constraint }, asn_MBR_IpRouteEntry_1, 13, /* Elements count */ &asn_SPC_IpRouteEntry_specs_1 /* Additional specs */ diff --git a/libs/smux/Message.c b/libs/smux/Message.c index 27ed3a2a..126eb1d9 100644 --- a/libs/smux/Message.c +++ b/libs/smux/Message.c @@ -1,8 +1,8 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1157-SNMP" * found in "RFC1157-SNMP.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #include "Message.h" @@ -12,27 +12,27 @@ static asn_TYPE_member_t asn_MBR_Message_1[] = { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, &asn_DEF_INTEGER, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "version" }, { ATF_NOFLAGS, 0, offsetof(struct Message, community), (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), 0, &asn_DEF_OCTET_STRING, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "community" }, - { ATF_OPEN_TYPE | ATF_NOFLAGS, 0, offsetof(struct Message, data), + { ATF_ANY_TYPE | ATF_NOFLAGS, 0, offsetof(struct Message, data), -1 /* Ambiguous tag (ANY?) */, 0, &asn_DEF_ANY, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "data" }, }; @@ -49,28 +49,19 @@ static asn_SEQUENCE_specifics_t asn_SPC_Message_specs_1 = { asn_MAP_Message_tag2el_1, 2, /* Count of tags in the map */ 0, 0, 0, /* Optional elements (not needed) */ - -1, /* Start extensions */ - -1 /* Stop extensions */ + -1, /* First extension addition */ }; asn_TYPE_descriptor_t asn_DEF_Message = { "Message", "Message", - SEQUENCE_free, - SEQUENCE_print, - SEQUENCE_constraint, - SEQUENCE_decode_ber, - SEQUENCE_encode_der, - SEQUENCE_decode_xer, - SEQUENCE_encode_xer, - 0, 0, /* No PER support, use "-gen-PER" to enable */ - 0, /* Use generic outmost tag fetcher */ + &asn_OP_SEQUENCE, asn_DEF_Message_tags_1, sizeof(asn_DEF_Message_tags_1) /sizeof(asn_DEF_Message_tags_1[0]), /* 1 */ asn_DEF_Message_tags_1, /* Same as above */ sizeof(asn_DEF_Message_tags_1) /sizeof(asn_DEF_Message_tags_1[0]), /* 1 */ - 0, /* No PER visible constraints */ + { 0, 0, SEQUENCE_constraint }, asn_MBR_Message_1, 3, /* Elements count */ &asn_SPC_Message_specs_1 /* Additional specs */ diff --git a/libs/smux/NULL.c b/libs/smux/NULL.c index 62bc91e0..076898e0 100644 --- a/libs/smux/NULL.c +++ b/libs/smux/NULL.c @@ -5,7 +5,6 @@ #include #include #include -#include /* Implemented in terms of BOOLEAN type */ /* * NULL basic type description. @@ -13,33 +12,107 @@ static const ber_tlv_tag_t asn_DEF_NULL_tags[] = { (ASN_TAG_CLASS_UNIVERSAL | (5 << 2)) }; -asn_TYPE_descriptor_t asn_DEF_NULL = { - "NULL", - "NULL", - BOOLEAN_free, +asn_TYPE_operation_t asn_OP_NULL = { + NULL_free, NULL_print, - asn_generic_no_constraint, - BOOLEAN_decode_ber, /* Implemented in terms of BOOLEAN */ + NULL_compare, + NULL_decode_ber, NULL_encode_der, /* Special handling of DER encoding */ NULL_decode_xer, NULL_encode_xer, +#ifdef ASN_DISABLE_OER_SUPPORT + 0, + 0, +#else + NULL_decode_oer, + NULL_encode_oer, +#endif /* ASN_DISABLE_OER_SUPPORT */ +#ifdef ASN_DISABLE_PER_SUPPORT + 0, + 0, +#else NULL_decode_uper, /* Unaligned PER decoder */ NULL_encode_uper, /* Unaligned PER encoder */ - 0, /* Use generic outmost tag fetcher */ +#endif /* ASN_DISABLE_PER_SUPPORT */ + NULL_random_fill, + 0 /* Use generic outmost tag fetcher */ +}; +asn_TYPE_descriptor_t asn_DEF_NULL = { + "NULL", + "NULL", + &asn_OP_NULL, asn_DEF_NULL_tags, sizeof(asn_DEF_NULL_tags) / sizeof(asn_DEF_NULL_tags[0]), asn_DEF_NULL_tags, /* Same as above */ sizeof(asn_DEF_NULL_tags) / sizeof(asn_DEF_NULL_tags[0]), - 0, /* No PER visible constraints */ + { 0, 0, asn_generic_no_constraint }, 0, 0, /* No members */ 0 /* No specifics */ }; +void +NULL_free(const asn_TYPE_descriptor_t *td, void *ptr, + enum asn_struct_free_method method) { + if(td && ptr) { + switch(method) { + case ASFM_FREE_EVERYTHING: + FREEMEM(ptr); + break; + case ASFM_FREE_UNDERLYING: + break; + case ASFM_FREE_UNDERLYING_AND_RESET: + memset(ptr, 0, sizeof(NULL_t)); + break; + } + } +} + +/* + * Decode NULL type. + */ +asn_dec_rval_t +NULL_decode_ber(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *td, void **bool_value, + const void *buf_ptr, size_t size, int tag_mode) { + NULL_t *st = (NULL_t *)*bool_value; + asn_dec_rval_t rval; + ber_tlv_len_t length; + + if(st == NULL) { + st = (NULL_t *)(*bool_value = CALLOC(1, sizeof(*st))); + if(st == NULL) { + rval.code = RC_FAIL; + rval.consumed = 0; + return rval; + } + } + + ASN_DEBUG("Decoding %s as NULL (tm=%d)", td->name, tag_mode); + + /* + * Check tags. + */ + rval = ber_check_tags(opt_codec_ctx, td, 0, buf_ptr, size, tag_mode, 0, + &length, 0); + if(rval.code != RC_OK) { + return rval; + } + + // X.690-201508, #8.8.2, length shall be zero. + if(length != 0) { + ASN_DEBUG("Decoding %s as NULL failed: too much data", td->name); + rval.code = RC_FAIL; + rval.consumed = 0; + return rval; + } + + return rval; +} + asn_enc_rval_t -NULL_encode_der(asn_TYPE_descriptor_t *td, void *ptr, - int tag_mode, ber_tlv_tag_t tag, - asn_app_consume_bytes_f *cb, void *app_key) { - asn_enc_rval_t erval; +NULL_encode_der(const asn_TYPE_descriptor_t *td, const void *ptr, int tag_mode, + ber_tlv_tag_t tag, asn_app_consume_bytes_f *cb, void *app_key) { + asn_enc_rval_t erval; erval.encoded = der_write_tags(td, 0, tag_mode, 0, tag, cb, app_key); if(erval.encoded == -1) { @@ -51,10 +124,10 @@ NULL_encode_der(asn_TYPE_descriptor_t *td, void *ptr, } asn_enc_rval_t -NULL_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, - int ilevel, enum xer_encoder_flags_e flags, - asn_app_consume_bytes_f *cb, void *app_key) { - asn_enc_rval_t er; +NULL_encode_xer(const asn_TYPE_descriptor_t *td, const void *sptr, int ilevel, + enum xer_encoder_flags_e flags, asn_app_consume_bytes_f *cb, + void *app_key) { + asn_enc_rval_t er; (void)td; (void)sptr; @@ -70,8 +143,9 @@ NULL_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, static enum xer_pbd_rval -NULL__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const void *chunk_buf, size_t chunk_size) { - (void)td; +NULL__xer_body_decode(const asn_TYPE_descriptor_t *td, void *sptr, + const void *chunk_buf, size_t chunk_size) { + (void)td; (void)sptr; (void)chunk_buf; /* Going to be empty according to the rules below. */ @@ -85,20 +159,26 @@ NULL__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const void *chunk_b } asn_dec_rval_t -NULL_decode_xer(asn_codec_ctx_t *opt_codec_ctx, - asn_TYPE_descriptor_t *td, void **sptr, const char *opt_mname, - const void *buf_ptr, size_t size) { - - return xer_decode_primitive(opt_codec_ctx, td, +NULL_decode_xer(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *td, void **sptr, + const char *opt_mname, const void *buf_ptr, size_t size) { + return xer_decode_primitive(opt_codec_ctx, td, sptr, sizeof(NULL_t), opt_mname, buf_ptr, size, NULL__xer_body_decode); } int -NULL_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel, - asn_app_consume_bytes_f *cb, void *app_key) { +NULL_compare(const asn_TYPE_descriptor_t *td, const void *a, const void *b) { + (void)td; + (void)a; + (void)b; + return 0; +} - (void)td; /* Unused argument */ +int +NULL_print(const asn_TYPE_descriptor_t *td, const void *sptr, int ilevel, + asn_app_consume_bytes_f *cb, void *app_key) { + (void)td; /* Unused argument */ (void)ilevel; /* Unused argument */ if(sptr) { @@ -108,10 +188,59 @@ NULL_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel, } } +#ifndef ASN_DISABLE_OER_SUPPORT + +asn_dec_rval_t +NULL_decode_oer(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *td, + const asn_oer_constraints_t *constraints, void **sptr, + const void *ptr, size_t size) { + asn_dec_rval_t rv = {RC_OK, 0}; + (void)opt_codec_ctx; + (void)td; + (void)constraints; + (void)ptr; + (void)size; + + if(!*sptr) { + *sptr = MALLOC(sizeof(NULL_t)); + if(*sptr) { + *(NULL_t *)*sptr = 0; + } else { + ASN__DECODE_FAILED; + } + } + + return rv; +} + +asn_enc_rval_t +NULL_encode_oer(const asn_TYPE_descriptor_t *td, + const asn_oer_constraints_t *constraints, const void *sptr, + asn_app_consume_bytes_f *cb, void *app_key) { + asn_enc_rval_t er; + + (void)td; + (void)sptr; + (void)constraints; + (void)cb; + (void)app_key; + + er.encoded = 0; /* Encoding in 0 bytes. */ + + ASN__ENCODED_OK(er); +} + +#endif /* ASN_DISABLE_OER_SUPPORT */ + +#ifndef ASN_DISABLE_PER_SUPPORT + asn_dec_rval_t -NULL_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, - asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { - asn_dec_rval_t rv; +NULL_decode_uper(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, void **sptr, + asn_per_data_t *pd) { + asn_dec_rval_t rv; (void)opt_codec_ctx; (void)td; @@ -137,9 +266,10 @@ NULL_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, } asn_enc_rval_t -NULL_encode_uper(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, - void *sptr, asn_per_outp_t *po) { - asn_enc_rval_t er; +NULL_encode_uper(const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, const void *sptr, + asn_per_outp_t *po) { + asn_enc_rval_t er; (void)td; (void)constraints; @@ -149,3 +279,30 @@ NULL_encode_uper(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, er.encoded = 0; ASN__ENCODED_OK(er); } + +#endif /* ASN_DISABLE_PER_SUPPORT */ + +asn_random_fill_result_t +NULL_random_fill(const asn_TYPE_descriptor_t *td, void **sptr, + const asn_encoding_constraints_t *constr, + size_t max_length) { + asn_random_fill_result_t result_ok = {ARFILL_OK, 1}; + asn_random_fill_result_t result_failed = {ARFILL_FAILED, 0}; + asn_random_fill_result_t result_skipped = {ARFILL_SKIPPED, 0}; + NULL_t *st = *sptr; + + (void)td; + (void)constr; + + if(max_length == 0) return result_skipped; + + if(st == NULL) { + st = (NULL_t *)(*sptr = CALLOC(1, sizeof(*st))); + if(st == NULL) { + return result_failed; + } + } + + return result_ok; +} + diff --git a/libs/smux/NativeEnumerated.c b/libs/smux/NativeEnumerated.c deleted file mode 100644 index 78366af3..00000000 --- a/libs/smux/NativeEnumerated.c +++ /dev/null @@ -1,207 +0,0 @@ -/*- - * Copyright (c) 2004, 2007 Lev Walkin . All rights reserved. - * Redistribution and modifications are permitted subject to BSD license. - */ -/* - * Read the NativeInteger.h for the explanation wrt. differences between - * INTEGER and NativeInteger. - * Basically, both are decoders and encoders of ASN.1 INTEGER type, but this - * implementation deals with the standard (machine-specific) representation - * of them instead of using the platform-independent buffer. - */ -#include -#include - -/* - * NativeEnumerated basic type description. - */ -static const ber_tlv_tag_t asn_DEF_NativeEnumerated_tags[] = { - (ASN_TAG_CLASS_UNIVERSAL | (10 << 2)) -}; -asn_TYPE_descriptor_t asn_DEF_NativeEnumerated = { - "ENUMERATED", /* The ASN.1 type is still ENUMERATED */ - "ENUMERATED", - NativeInteger_free, - NativeInteger_print, - asn_generic_no_constraint, - NativeInteger_decode_ber, - NativeInteger_encode_der, - NativeInteger_decode_xer, - NativeEnumerated_encode_xer, - NativeEnumerated_decode_uper, - NativeEnumerated_encode_uper, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_NativeEnumerated_tags, - sizeof(asn_DEF_NativeEnumerated_tags) / sizeof(asn_DEF_NativeEnumerated_tags[0]), - asn_DEF_NativeEnumerated_tags, /* Same as above */ - sizeof(asn_DEF_NativeEnumerated_tags) / sizeof(asn_DEF_NativeEnumerated_tags[0]), - 0, /* No PER visible constraints */ - 0, 0, /* No members */ - 0 /* No specifics */ -}; - -asn_enc_rval_t -NativeEnumerated_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, - int ilevel, enum xer_encoder_flags_e flags, - asn_app_consume_bytes_f *cb, void *app_key) { - asn_INTEGER_specifics_t *specs=(asn_INTEGER_specifics_t *)td->specifics; - asn_enc_rval_t er; - const long *native = (const long *)sptr; - const asn_INTEGER_enum_map_t *el; - - (void)ilevel; - (void)flags; - - if(!native) ASN__ENCODE_FAILED; - - el = INTEGER_map_value2enum(specs, *native); - if(el) { - size_t srcsize = el->enum_len + 5; - char *src = (char *)alloca(srcsize); - - er.encoded = snprintf(src, srcsize, "<%s/>", el->enum_name); - assert(er.encoded > 0 && (size_t)er.encoded < srcsize); - if(cb(src, er.encoded, app_key) < 0) ASN__ENCODE_FAILED; - ASN__ENCODED_OK(er); - } else { - ASN_DEBUG("ASN.1 forbids dealing with " - "unknown value of ENUMERATED type"); - ASN__ENCODE_FAILED; - } -} - -asn_dec_rval_t -NativeEnumerated_decode_uper(asn_codec_ctx_t *opt_codec_ctx, - asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, - void **sptr, asn_per_data_t *pd) { - asn_INTEGER_specifics_t *specs = (asn_INTEGER_specifics_t *)td->specifics; - asn_dec_rval_t rval = { RC_OK, 0 }; - long *native = (long *)*sptr; - asn_per_constraint_t *ct; - long value; - - (void)opt_codec_ctx; - - if(constraints) ct = &constraints->value; - else if(td->per_constraints) ct = &td->per_constraints->value; - else ASN__DECODE_FAILED; /* Mandatory! */ - if(!specs) ASN__DECODE_FAILED; - - if(!native) { - native = (long *)(*sptr = CALLOC(1, sizeof(*native))); - if(!native) ASN__DECODE_FAILED; - } - - ASN_DEBUG("Decoding %s as NativeEnumerated", td->name); - - if(ct->flags & APC_EXTENSIBLE) { - int inext = per_get_few_bits(pd, 1); - if(inext < 0) ASN__DECODE_STARVED; - if(inext) ct = 0; - } - - if(ct && ct->range_bits >= 0) { - value = per_get_few_bits(pd, ct->range_bits); - if(value < 0) ASN__DECODE_STARVED; - if(value >= (specs->extension - ? specs->extension - 1 : specs->map_count)) - ASN__DECODE_FAILED; - } else { - if(!specs->extension) - ASN__DECODE_FAILED; - /* - * X.691, #10.6: normally small non-negative whole number; - */ - value = uper_get_nsnnwn(pd); - if(value < 0) ASN__DECODE_STARVED; - value += specs->extension - 1; - if(value >= specs->map_count) - ASN__DECODE_FAILED; - } - - *native = specs->value2enum[value].nat_value; - ASN_DEBUG("Decoded %s = %ld", td->name, *native); - - return rval; -} - -static int -NativeEnumerated__compar_value2enum(const void *ap, const void *bp) { - const asn_INTEGER_enum_map_t *a = ap; - const asn_INTEGER_enum_map_t *b = bp; - if(a->nat_value == b->nat_value) - return 0; - if(a->nat_value < b->nat_value) - return -1; - return 1; -} - -asn_enc_rval_t -NativeEnumerated_encode_uper(asn_TYPE_descriptor_t *td, - asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { - asn_INTEGER_specifics_t *specs = (asn_INTEGER_specifics_t *)td->specifics; - asn_enc_rval_t er; - long native, value; - asn_per_constraint_t *ct; - int inext = 0; - asn_INTEGER_enum_map_t key; - const asn_INTEGER_enum_map_t *kf; - - if(!sptr) ASN__ENCODE_FAILED; - if(!specs) ASN__ENCODE_FAILED; - - if(constraints) ct = &constraints->value; - else if(td->per_constraints) ct = &td->per_constraints->value; - else ASN__ENCODE_FAILED; /* Mandatory! */ - - ASN_DEBUG("Encoding %s as NativeEnumerated", td->name); - - er.encoded = 0; - - native = *(long *)sptr; - if(native < 0) ASN__ENCODE_FAILED; - - key.nat_value = native; - kf = bsearch(&key, specs->value2enum, specs->map_count, - sizeof(key), NativeEnumerated__compar_value2enum); - if(!kf) { - ASN_DEBUG("No element corresponds to %ld", native); - ASN__ENCODE_FAILED; - } - value = kf - specs->value2enum; - - if(ct->range_bits >= 0) { - int cmpWith = specs->extension - ? specs->extension - 1 : specs->map_count; - if(value >= cmpWith) - inext = 1; - } - if(ct->flags & APC_EXTENSIBLE) { - if(per_put_few_bits(po, inext, 1)) - ASN__ENCODE_FAILED; - if(inext) ct = 0; - } else if(inext) { - ASN__ENCODE_FAILED; - } - - if(ct && ct->range_bits >= 0) { - if(per_put_few_bits(po, value, ct->range_bits)) - ASN__ENCODE_FAILED; - ASN__ENCODED_OK(er); - } - - if(!specs->extension) - ASN__ENCODE_FAILED; - - /* - * X.691, #10.6: normally small non-negative whole number; - */ - ASN_DEBUG("value = %ld, ext = %d, inext = %d, res = %ld", - value, specs->extension, inext, - value - (inext ? (specs->extension - 1) : 0)); - if(uper_put_nsnnwn(po, value - (inext ? (specs->extension - 1) : 0))) - ASN__ENCODE_FAILED; - - ASN__ENCODED_OK(er); -} - diff --git a/libs/smux/NativeInteger.c b/libs/smux/NativeInteger.c index e8ce6d2c..d6b73940 100644 --- a/libs/smux/NativeInteger.c +++ b/libs/smux/NativeInteger.c @@ -19,24 +19,40 @@ static const ber_tlv_tag_t asn_DEF_NativeInteger_tags[] = { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)) }; -asn_TYPE_descriptor_t asn_DEF_NativeInteger = { - "INTEGER", /* The ASN.1 type is still INTEGER */ - "INTEGER", +asn_TYPE_operation_t asn_OP_NativeInteger = { NativeInteger_free, NativeInteger_print, - asn_generic_no_constraint, + NativeInteger_compare, NativeInteger_decode_ber, NativeInteger_encode_der, NativeInteger_decode_xer, NativeInteger_encode_xer, +#ifdef ASN_DISABLE_OER_SUPPORT + 0, + 0, +#else + NativeInteger_decode_oer, /* OER decoder */ + NativeInteger_encode_oer, /* Canonical OER encoder */ +#endif /* ASN_DISABLE_OER_SUPPORT */ +#ifdef ASN_DISABLE_PER_SUPPORT + 0, + 0, +#else NativeInteger_decode_uper, /* Unaligned PER decoder */ NativeInteger_encode_uper, /* Unaligned PER encoder */ - 0, /* Use generic outmost tag fetcher */ +#endif /* ASN_DISABLE_PER_SUPPORT */ + NativeInteger_random_fill, + 0 /* Use generic outmost tag fetcher */ +}; +asn_TYPE_descriptor_t asn_DEF_NativeInteger = { + "INTEGER", /* The ASN.1 type is still INTEGER */ + "INTEGER", + &asn_OP_NativeInteger, asn_DEF_NativeInteger_tags, sizeof(asn_DEF_NativeInteger_tags) / sizeof(asn_DEF_NativeInteger_tags[0]), asn_DEF_NativeInteger_tags, /* Same as above */ sizeof(asn_DEF_NativeInteger_tags) / sizeof(asn_DEF_NativeInteger_tags[0]), - 0, /* No PER visible constraints */ + { 0, 0, asn_generic_no_constraint }, 0, 0, /* No members */ 0 /* No specifics */ }; @@ -45,11 +61,12 @@ asn_TYPE_descriptor_t asn_DEF_NativeInteger = { * Decode INTEGER type. */ asn_dec_rval_t -NativeInteger_decode_ber(asn_codec_ctx_t *opt_codec_ctx, - asn_TYPE_descriptor_t *td, - void **nint_ptr, const void *buf_ptr, size_t size, int tag_mode) { - asn_INTEGER_specifics_t *specs=(asn_INTEGER_specifics_t *)td->specifics; - long *native = (long *)*nint_ptr; +NativeInteger_decode_ber(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *td, void **nint_ptr, + const void *buf_ptr, size_t size, int tag_mode) { + const asn_INTEGER_specifics_t *specs = + (const asn_INTEGER_specifics_t *)td->specifics; + long *native = (long *)*nint_ptr; asn_dec_rval_t rval; ber_tlv_len_t length; @@ -92,7 +109,7 @@ NativeInteger_decode_ber(asn_codec_ctx_t *opt_codec_ctx, /* * ASN.1 encoded INTEGER: buf_ptr, length * Fill the native, at the same time checking for overflow. - * If overflow occured, return with RC_FAIL. + * If overflow occurred, return with RC_FAIL. */ { INTEGER_t tmp; @@ -130,11 +147,11 @@ NativeInteger_decode_ber(asn_codec_ctx_t *opt_codec_ctx, * Encode the NativeInteger using the standard INTEGER type DER encoder. */ asn_enc_rval_t -NativeInteger_encode_der(asn_TYPE_descriptor_t *sd, void *ptr, - int tag_mode, ber_tlv_tag_t tag, - asn_app_consume_bytes_f *cb, void *app_key) { - unsigned long native = *(unsigned long *)ptr; /* Disable sign ext. */ - asn_enc_rval_t erval; +NativeInteger_encode_der(const asn_TYPE_descriptor_t *sd, const void *ptr, + int tag_mode, ber_tlv_tag_t tag, + asn_app_consume_bytes_f *cb, void *app_key) { + unsigned long native = *(const unsigned long *)ptr; /* Disable sign ext. */ + asn_enc_rval_t erval; INTEGER_t tmp; #ifdef WORDS_BIGENDIAN /* Opportunistic optimization */ @@ -156,10 +173,9 @@ NativeInteger_encode_der(asn_TYPE_descriptor_t *sd, void *ptr, /* Encode fake INTEGER */ erval = INTEGER_encode_der(sd, &tmp, tag_mode, tag, cb, app_key); - if(erval.encoded == -1) { - assert(erval.structure_ptr == &tmp); - erval.structure_ptr = ptr; - } + if(erval.structure_ptr == &tmp) { + erval.structure_ptr = ptr; + } return erval; } @@ -167,11 +183,13 @@ NativeInteger_encode_der(asn_TYPE_descriptor_t *sd, void *ptr, * Decode the chunk of XML text encoding INTEGER. */ asn_dec_rval_t -NativeInteger_decode_xer(asn_codec_ctx_t *opt_codec_ctx, - asn_TYPE_descriptor_t *td, void **sptr, const char *opt_mname, - const void *buf_ptr, size_t size) { - asn_INTEGER_specifics_t *specs=(asn_INTEGER_specifics_t *)td->specifics; - asn_dec_rval_t rval; +NativeInteger_decode_xer(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *td, void **sptr, + const char *opt_mname, const void *buf_ptr, + size_t size) { + const asn_INTEGER_specifics_t *specs = + (const asn_INTEGER_specifics_t *)td->specifics; + asn_dec_rval_t rval; INTEGER_t st; void *st_ptr = (void *)&st; long *native = (long *)*sptr; @@ -208,11 +226,12 @@ NativeInteger_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_enc_rval_t -NativeInteger_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, - int ilevel, enum xer_encoder_flags_e flags, - asn_app_consume_bytes_f *cb, void *app_key) { - asn_INTEGER_specifics_t *specs=(asn_INTEGER_specifics_t *)td->specifics; - char scratch[32]; /* Enough for 64-bit int */ +NativeInteger_encode_xer(const asn_TYPE_descriptor_t *td, const void *sptr, + int ilevel, enum xer_encoder_flags_e flags, + asn_app_consume_bytes_f *cb, void *app_key) { + const asn_INTEGER_specifics_t *specs = + (const asn_INTEGER_specifics_t *)td->specifics; + char scratch[32]; /* Enough for 64-bit int */ asn_enc_rval_t er; const long *native = (const long *)sptr; @@ -231,13 +250,16 @@ NativeInteger_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, ASN__ENCODED_OK(er); } -asn_dec_rval_t -NativeInteger_decode_uper(asn_codec_ctx_t *opt_codec_ctx, - asn_TYPE_descriptor_t *td, - asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { +#ifndef ASN_DISABLE_PER_SUPPORT - asn_INTEGER_specifics_t *specs=(asn_INTEGER_specifics_t *)td->specifics; - asn_dec_rval_t rval; +asn_dec_rval_t +NativeInteger_decode_uper(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, void **sptr, + asn_per_data_t *pd) { + const asn_INTEGER_specifics_t *specs = + (const asn_INTEGER_specifics_t *)td->specifics; + asn_dec_rval_t rval; long *native = (long *)*sptr; INTEGER_t tmpint; void *tmpintptr = &tmpint; @@ -268,18 +290,20 @@ NativeInteger_decode_uper(asn_codec_ctx_t *opt_codec_ctx, } asn_enc_rval_t -NativeInteger_encode_uper(asn_TYPE_descriptor_t *td, - asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { - asn_INTEGER_specifics_t *specs=(asn_INTEGER_specifics_t *)td->specifics; - asn_enc_rval_t er; +NativeInteger_encode_uper(const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, + const void *sptr, asn_per_outp_t *po) { + const asn_INTEGER_specifics_t *specs = + (const asn_INTEGER_specifics_t *)td->specifics; + asn_enc_rval_t er; long native; INTEGER_t tmpint; if(!sptr) ASN__ENCODE_FAILED; - native = *(long *)sptr; + native = *(const long *)sptr; - ASN_DEBUG("Encoding NativeInteger %s %ld (UPER)", td->name, native); + ASN_DEBUG("Encoding NativeInteger %s %ld (UPER)", td->name, native); memset(&tmpint, 0, sizeof(tmpint)); if((specs&&specs->field_unsigned) @@ -291,42 +315,170 @@ NativeInteger_encode_uper(asn_TYPE_descriptor_t *td, return er; } +#endif /* ASN_DISABLE_PER_SUPPORT */ + /* * INTEGER specific human-readable output. */ int -NativeInteger_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel, - asn_app_consume_bytes_f *cb, void *app_key) { - asn_INTEGER_specifics_t *specs=(asn_INTEGER_specifics_t *)td->specifics; - const long *native = (const long *)sptr; - char scratch[32]; /* Enough for 64-bit int */ - int ret; - - (void)td; /* Unused argument */ - (void)ilevel; /* Unused argument */ - - if(native) { - ret = snprintf(scratch, sizeof(scratch), - (specs && specs->field_unsigned) - ? "%lu" : "%ld", *native); - assert(ret > 0 && (size_t)ret < sizeof(scratch)); - return (cb(scratch, ret, app_key) < 0) ? -1 : 0; +NativeInteger_print(const asn_TYPE_descriptor_t *td, const void *sptr, + int ilevel, asn_app_consume_bytes_f *cb, void *app_key) { + const asn_INTEGER_specifics_t *specs = + (const asn_INTEGER_specifics_t *)td->specifics; + const long *native = (const long *)sptr; + char scratch[32]; /* Enough for 64-bit int */ + int ret; + + (void)td; /* Unused argument */ + (void)ilevel; /* Unused argument */ + + if(native) { + long value = *native; + ret = snprintf(scratch, sizeof(scratch), + (specs && specs->field_unsigned) ? "%lu" : "%ld", value); + assert(ret > 0 && (size_t)ret < sizeof(scratch)); + if(cb(scratch, ret, app_key) < 0) return -1; + if(specs && (value >= 0 || !specs->field_unsigned)) { + const asn_INTEGER_enum_map_t *el = + INTEGER_map_value2enum(specs, value); + if(el) { + if(cb(" (", 2, app_key) < 0) return -1; + if(cb(el->enum_name, el->enum_len, app_key) < 0) return -1; + if(cb(")", 1, app_key) < 0) return -1; + } + } + return 0; } else { return (cb("", 8, app_key) < 0) ? -1 : 0; } } void -NativeInteger_free(asn_TYPE_descriptor_t *td, void *ptr, int contents_only) { - - if(!td || !ptr) +NativeInteger_free(const asn_TYPE_descriptor_t *td, void *ptr, + enum asn_struct_free_method method) { + if(!td || !ptr) return; ASN_DEBUG("Freeing %s as INTEGER (%d, %p, Native)", - td->name, contents_only, ptr); + td->name, method, ptr); + + switch(method) { + case ASFM_FREE_EVERYTHING: + FREEMEM(ptr); + break; + case ASFM_FREE_UNDERLYING: + break; + case ASFM_FREE_UNDERLYING_AND_RESET: + memset(ptr, 0, sizeof(long)); + break; + } +} - if(!contents_only) { - FREEMEM(ptr); - } +int +NativeInteger_compare(const asn_TYPE_descriptor_t *td, const void *aptr, const void *bptr) { + (void)td; + + if(aptr && bptr) { + const asn_INTEGER_specifics_t *specs = + (const asn_INTEGER_specifics_t *)td->specifics; + if(specs && specs->field_unsigned) { + const unsigned long *a = aptr; + const unsigned long *b = bptr; + if(*a < *b) { + return -1; + } else if(*a > *b) { + return 1; + } else { + return 0; + } + } else { + const long *a = aptr; + const long *b = bptr; + if(*a < *b) { + return -1; + } else if(*a > *b) { + return 1; + } else { + return 0; + } + } + } else if(!aptr) { + return -1; + } else { + return 1; + } } +asn_random_fill_result_t +NativeInteger_random_fill(const asn_TYPE_descriptor_t *td, void **sptr, + const asn_encoding_constraints_t *constraints, + size_t max_length) { + const asn_INTEGER_specifics_t *specs = + (const asn_INTEGER_specifics_t *)td->specifics; + asn_random_fill_result_t result_ok = {ARFILL_OK, 1}; + asn_random_fill_result_t result_failed = {ARFILL_FAILED, 0}; + asn_random_fill_result_t result_skipped = {ARFILL_SKIPPED, 0}; + long *st = *sptr; + const asn_INTEGER_enum_map_t *emap; + size_t emap_len; + intmax_t value; + int find_inside_map; + + if(max_length == 0) return result_skipped; + + if(st == NULL) { + st = (long *)CALLOC(1, sizeof(*st)); + if(st == NULL) { + return result_failed; + } + } + + if(specs) { + emap = specs->value2enum; + emap_len = specs->map_count; + if(specs->strict_enumeration) { + find_inside_map = emap_len > 0; + } else { + find_inside_map = emap_len ? asn_random_between(0, 1) : 0; + } + } else { + emap = 0; + emap_len = 0; + find_inside_map = 0; + } + + if(find_inside_map) { + assert(emap_len > 0); + value = emap[asn_random_between(0, emap_len - 1)].nat_value; + } else { + const asn_per_constraints_t *ct; + + static const long variants[] = { + -65536, -65535, -65534, -32769, -32768, -32767, -16385, -16384, + -16383, -257, -256, -255, -254, -129, -128, -127, + -126, -1, 0, 1, 126, 127, 128, 129, + 254, 255, 256, 257, 16383, 16384, 16385, 32767, + 32768, 32769, 65534, 65535, 65536, 65537}; + if(specs && specs->field_unsigned) { + assert(variants[18] == 0); + value = variants[asn_random_between( + 18, sizeof(variants) / sizeof(variants[0]) - 1)]; + } else { + value = variants[asn_random_between( + 0, sizeof(variants) / sizeof(variants[0]) - 1)]; + } + + if(!constraints) constraints = &td->encoding_constraints; + ct = constraints ? constraints->per_constraints : 0; + if(ct && (ct->value.flags & APC_CONSTRAINED)) { + if(value < ct->value.lower_bound || value > ct->value.upper_bound) { + value = asn_random_between(ct->value.lower_bound, + ct->value.upper_bound); + } + } + } + + *sptr = st; + *st = value; + return result_ok; +} diff --git a/libs/smux/NativeInteger_oer.c b/libs/smux/NativeInteger_oer.c new file mode 100644 index 00000000..411413a2 --- /dev/null +++ b/libs/smux/NativeInteger_oer.c @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2017 Lev Walkin . + * All rights reserved. + * Redistribution and modifications are permitted subject to BSD license. + */ +#ifndef ASN_DISABLE_OER_SUPPORT + +#include +#include +#include + +asn_dec_rval_t +NativeInteger_decode_oer(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *td, + const asn_oer_constraints_t *constraints, + void **nint_ptr, const void *ptr, size_t size) { + const asn_INTEGER_specifics_t *specs = + (const asn_INTEGER_specifics_t *)td->specifics; + asn_dec_rval_t rval = {RC_OK, 0}; + long *native = (long *)*nint_ptr; + INTEGER_t tmpint; + INTEGER_t *tmpintptr = &tmpint; + + memset(&tmpint, 0, sizeof(tmpint)); + + if(!native) { + native = (long *)(*nint_ptr = CALLOC(1, sizeof(*native))); + if(!native) ASN__DECODE_FAILED; + } + + /* + * OPTIMIZATION: Encode directly rather than passing through INTEGER. + * Saves a memory allocation. + */ + rval = INTEGER_decode_oer(opt_codec_ctx, td, constraints, + (void **)&tmpintptr, ptr, size); + if(rval.code != RC_OK) { + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_INTEGER, &tmpint); + return rval; + } + + if(specs && specs->field_unsigned) { + unsigned long ul; + int ok = asn_INTEGER2ulong(&tmpint, &ul) == 0; + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_INTEGER, &tmpint); + if(ok) { + *native = ul; + } else { + rval.code = RC_FAIL; + return rval; + } + } else { + long l; + int ok = asn_INTEGER2long(&tmpint, &l) == 0; + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_INTEGER, &tmpint); + if(ok) { + *native = l; + } else { + rval.code = RC_FAIL; + return rval; + } + } + + return rval; +} + +/* + * Encode as Canonical OER. + */ +asn_enc_rval_t +NativeInteger_encode_oer(const asn_TYPE_descriptor_t *td, + const asn_oer_constraints_t *constraints, + const void *sptr, asn_app_consume_bytes_f *cb, + void *app_key) { + const asn_INTEGER_specifics_t *specs = + (const asn_INTEGER_specifics_t *)td->specifics; + INTEGER_t tmpint; + long native; + + if(!sptr) ASN__ENCODE_FAILED; + + native = *(const long *)sptr; + memset(&tmpint, 0, sizeof(tmpint)); + + ASN_DEBUG("Encoding %s %ld as NativeInteger", td ? td->name : "", native); + + if((specs && specs->field_unsigned) ? asn_ulong2INTEGER(&tmpint, native) + : asn_long2INTEGER(&tmpint, native)) { + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_INTEGER, &tmpint); + ASN__ENCODE_FAILED; + } else { + asn_enc_rval_t er = + INTEGER_encode_oer(td, constraints, &tmpint, cb, app_key); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_INTEGER, &tmpint); + return er; + } +} + +#endif /* ASN_DISABLE_OER_SUPPORT */ diff --git a/libs/smux/NetworkAddress.c b/libs/smux/NetworkAddress.c index 3a65001d..e56c9465 100644 --- a/libs/smux/NetworkAddress.c +++ b/libs/smux/NetworkAddress.c @@ -1,53 +1,53 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1155-SMI" * found in "RFC1155-SMI.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #include "NetworkAddress.h" -static asn_TYPE_member_t asn_MBR_NetworkAddress_1[] = { +static asn_oer_constraints_t asn_OER_type_NetworkAddress_constr_1 CC_NOTUSED = { + { 0, 0 }, + -1}; +asn_per_constraints_t asn_PER_type_NetworkAddress_constr_1 CC_NOTUSED = { + { APC_CONSTRAINED, 0, 0, 0, 0 } /* (0..0) */, + { APC_UNCONSTRAINED, -1, -1, 0, 0 }, + 0, 0 /* No PER value map */ +}; +asn_TYPE_member_t asn_MBR_NetworkAddress_1[] = { { ATF_NOFLAGS, 0, offsetof(struct NetworkAddress, choice.internet), (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 0, &asn_DEF_IpAddress, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "internet" }, }; static const asn_TYPE_tag2member_t asn_MAP_NetworkAddress_tag2el_1[] = { { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 0, 0, 0 } /* internet */ }; -static asn_CHOICE_specifics_t asn_SPC_NetworkAddress_specs_1 = { +asn_CHOICE_specifics_t asn_SPC_NetworkAddress_specs_1 = { sizeof(struct NetworkAddress), offsetof(struct NetworkAddress, _asn_ctx), offsetof(struct NetworkAddress, present), sizeof(((struct NetworkAddress *)0)->present), asn_MAP_NetworkAddress_tag2el_1, 1, /* Count of tags in the map */ - 0, + 0, 0, -1 /* Extensions start */ }; asn_TYPE_descriptor_t asn_DEF_NetworkAddress = { "NetworkAddress", "NetworkAddress", - CHOICE_free, - CHOICE_print, - CHOICE_constraint, - CHOICE_decode_ber, - CHOICE_encode_der, - CHOICE_decode_xer, - CHOICE_encode_xer, - 0, 0, /* No PER support, use "-gen-PER" to enable */ - CHOICE_outmost_tag, + &asn_OP_CHOICE, 0, /* No effective tags (pointer) */ 0, /* No effective tags (count) */ 0, /* No tags (pointer) */ 0, /* No tags (count) */ - 0, /* No PER visible constraints */ + { &asn_OER_type_NetworkAddress_constr_1, &asn_PER_type_NetworkAddress_constr_1, CHOICE_constraint }, asn_MBR_NetworkAddress_1, 1, /* Elements count */ &asn_SPC_NetworkAddress_specs_1 /* Additional specs */ diff --git a/libs/smux/OBJECT_IDENTIFIER.c b/libs/smux/OBJECT_IDENTIFIER.c index d0f8b311..290545d1 100644 --- a/libs/smux/OBJECT_IDENTIFIER.c +++ b/libs/smux/OBJECT_IDENTIFIER.c @@ -15,35 +15,51 @@ static const ber_tlv_tag_t asn_DEF_OBJECT_IDENTIFIER_tags[] = { (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)) }; -asn_TYPE_descriptor_t asn_DEF_OBJECT_IDENTIFIER = { - "OBJECT IDENTIFIER", - "OBJECT_IDENTIFIER", +asn_TYPE_operation_t asn_OP_OBJECT_IDENTIFIER = { ASN__PRIMITIVE_TYPE_free, OBJECT_IDENTIFIER_print, - OBJECT_IDENTIFIER_constraint, + OCTET_STRING_compare, /* Implemented in terms of a string comparison */ ber_decode_primitive, der_encode_primitive, OBJECT_IDENTIFIER_decode_xer, OBJECT_IDENTIFIER_encode_xer, +#ifdef ASN_DISABLE_OER_SUPPORT + 0, + 0, +#else + OBJECT_IDENTIFIER_decode_oer, + OBJECT_IDENTIFIER_encode_oer, +#endif /* ASN_DISABLE_OER_SUPPORT */ +#ifdef ASN_DISABLE_PER_SUPPORT + 0, + 0, +#else OCTET_STRING_decode_uper, OCTET_STRING_encode_uper, - 0, /* Use generic outmost tag fetcher */ +#endif /* ASN_DISABLE_PER_SUPPORT */ + OBJECT_IDENTIFIER_random_fill, + 0 /* Use generic outmost tag fetcher */ +}; +asn_TYPE_descriptor_t asn_DEF_OBJECT_IDENTIFIER = { + "OBJECT IDENTIFIER", + "OBJECT_IDENTIFIER", + &asn_OP_OBJECT_IDENTIFIER, asn_DEF_OBJECT_IDENTIFIER_tags, sizeof(asn_DEF_OBJECT_IDENTIFIER_tags) / sizeof(asn_DEF_OBJECT_IDENTIFIER_tags[0]), asn_DEF_OBJECT_IDENTIFIER_tags, /* Same as above */ sizeof(asn_DEF_OBJECT_IDENTIFIER_tags) / sizeof(asn_DEF_OBJECT_IDENTIFIER_tags[0]), - 0, /* No PER visible constraints */ + { 0, 0, OBJECT_IDENTIFIER_constraint }, 0, 0, /* No members */ 0 /* No specifics */ }; - int -OBJECT_IDENTIFIER_constraint(asn_TYPE_descriptor_t *td, const void *sptr, - asn_app_constraint_failed_f *ctfailcb, void *app_key) { - const OBJECT_IDENTIFIER_t *st = (const OBJECT_IDENTIFIER_t *)sptr; +OBJECT_IDENTIFIER_constraint(const asn_TYPE_descriptor_t *td, const void *sptr, + asn_app_constraint_failed_f *ctfailcb, + void *app_key) { + const OBJECT_IDENTIFIER_t *st = (const OBJECT_IDENTIFIER_t *)sptr; if(st && st->buf) { if(st->size < 1) { @@ -63,285 +79,186 @@ OBJECT_IDENTIFIER_constraint(asn_TYPE_descriptor_t *td, const void *sptr, return 0; } - -int -OBJECT_IDENTIFIER_get_single_arc(const uint8_t *arcbuf, unsigned int arclen, signed int add, void *rvbufp, unsigned int rvsize) { - unsigned LE GCC_NOTUSED = 1; /* Little endian (x86) */ - const uint8_t *arcend = arcbuf + arclen; /* End of arc */ - unsigned int cache = 0; /* No more than 14 significant bits */ - unsigned char *rvbuf = (unsigned char *)rvbufp; - unsigned char *rvstart = rvbuf; /* Original start of the value buffer */ - int inc; /* Return value growth direction */ - - rvsize *= CHAR_BIT; /* bytes to bits */ - arclen *= 7; /* bytes to bits */ - - /* - * The arc has the number of bits - * cannot be represented using supplied return value type. - */ - if(arclen > rvsize) { - if(arclen > (rvsize + CHAR_BIT)) { - errno = ERANGE; /* Overflow */ - return -1; - } else { - /* - * Even if the number of bits in the arc representation - * is higher than the width of supplied * return value - * type, there is still possible to fit it when there - * are few unused high bits in the arc value - * representaion. - * - * Moreover, there is a possibility that the - * number could actually fit the arc space, given - * that add is negative, but we don't handle - * such "temporary lack of precision" situation here. - * May be considered as a bug. - */ - uint8_t mask = (0xff << (7-(arclen - rvsize))) & 0x7f; - if((*arcbuf & mask)) { - errno = ERANGE; /* Overflow */ - return -1; - } - /* Fool the routine computing unused bits */ - arclen -= 7; - cache = *arcbuf & 0x7f; - arcbuf++; - } - } - - /* Faster path for common size */ - if(rvsize == (CHAR_BIT * sizeof(unsigned long))) { - unsigned long accum; - /* Gather all bits into the accumulator */ - for(accum = cache; arcbuf < arcend; arcbuf++) - accum = (accum << 7) | (*arcbuf & ~0x80); - if(accum < (unsigned)-add) { - errno = ERANGE; /* Overflow */ - return -1; - } - *(unsigned long *)(void *)rvbuf = accum + add; /* alignment OK! */ - return 0; - } - -#ifndef WORDS_BIGENDIAN - if(*(unsigned char *)&LE) { /* Little endian (x86) */ - /* "Convert" to big endian */ - rvbuf += rvsize / CHAR_BIT - 1; - rvstart--; - inc = -1; /* Descending */ - } else -#endif /* !WORDS_BIGENDIAN */ - inc = +1; /* Big endian is known [at compile time] */ - - { - int bits; /* typically no more than 3-4 bits */ - - /* Clear the high unused bits */ - for(bits = rvsize - arclen; - bits > CHAR_BIT; - rvbuf += inc, bits -= CHAR_BIT) - *rvbuf = 0; - - /* Fill the body of a value */ - for(; arcbuf < arcend; arcbuf++) { - cache = (cache << 7) | (*arcbuf & 0x7f); - bits += 7; - if(bits >= CHAR_BIT) { - bits -= CHAR_BIT; - *rvbuf = (cache >> bits); - rvbuf += inc; - } - } - if(bits) { - *rvbuf = cache; - rvbuf += inc; - } - } - - if(add) { - for(rvbuf -= inc; rvbuf != rvstart; rvbuf -= inc) { - int v = add + *rvbuf; - if(v & ((unsigned)~0 << CHAR_BIT)) { - *rvbuf = (unsigned char)(v + (1 << CHAR_BIT)); - add = -1; - } else { - *rvbuf = v; - break; - } - } - if(rvbuf == rvstart) { - /* No space to carry over */ - errno = ERANGE; /* Overflow */ - return -1; - } - } - - return 0; +static ssize_t +OBJECT_IDENTIFIER_get_first_arcs(const uint8_t *arcbuf, size_t arcbuf_len, + asn_oid_arc_t *arc0, asn_oid_arc_t *arc1) { + asn_oid_arc_t value; + + ssize_t rd = OBJECT_IDENTIFIER_get_single_arc(arcbuf, arcbuf_len, &value); + if(rd <= 0) return rd; + + if(value >= 80) { + *arc0 = 2; + *arc1 = value - 80; + } else if(value >= 40) { + *arc0 = 1; + *arc1 = value - 40; + } else { + *arc0 = 0; + *arc1 = value; + } + + return rd; } ssize_t -OBJECT_IDENTIFIER__dump_arc(const uint8_t *arcbuf, int arclen, int add, - asn_app_consume_bytes_f *cb, void *app_key) { - char scratch[64]; /* Conservative estimate */ - unsigned long accum; /* Bits accumulator */ - char *p; /* Position in the scratch buffer */ - - if(OBJECT_IDENTIFIER_get_single_arc(arcbuf, arclen, add, - &accum, sizeof(accum))) - return -1; +OBJECT_IDENTIFIER_get_single_arc(const uint8_t *arcbuf, size_t arcbuf_len, + asn_oid_arc_t *ret_value) { + const uint8_t *b = arcbuf; + const uint8_t *arcend = arcbuf + arcbuf_len; /* End of arc */ + + if(arcbuf == arcend) { + return 0; + } else { + asn_oid_arc_t accum; + /* Gather all bits into the accumulator */ + for(accum = 0; b < arcend; b++) { + accum = (accum << 7) | (*b & ~0x80); + if((*b & 0x80) == 0) { + if(accum <= ASN_OID_ARC_MAX) { + *ret_value = accum; + return 1 + (b - arcbuf); + } else { + errno = ERANGE; /* Overflow */ + return -1; + } + } + } + errno = EINVAL; + return -1; + } - if(accum) { - ssize_t len; - - /* Fill the scratch buffer in reverse. */ - p = scratch + sizeof(scratch); - for(; accum; accum /= 10) - *(--p) = (char)(accum % 10) + 0x30; /* Put a digit */ - - len = sizeof(scratch) - (p - scratch); - if(cb(p, len, app_key) < 0) - return -1; - return len; - } else { - *scratch = 0x30; - if(cb(scratch, 1, app_key) < 0) - return -1; - return 1; - } -} - -int -OBJECT_IDENTIFIER_print_arc(const uint8_t *arcbuf, int arclen, int add, - asn_app_consume_bytes_f *cb, void *app_key) { - - if(OBJECT_IDENTIFIER__dump_arc(arcbuf, arclen, add, cb, app_key) < 0) - return -1; - - return 0; } static ssize_t -OBJECT_IDENTIFIER__dump_body(const OBJECT_IDENTIFIER_t *st, asn_app_consume_bytes_f *cb, void *app_key) { - ssize_t wrote_len = 0; - int startn; - int add = 0; - int i; - - for(i = 0, startn = 0; i < st->size; i++) { - uint8_t b = st->buf[i]; - if((b & 0x80)) /* Continuation expected */ - continue; - - if(startn == 0) { - /* - * First two arcs are encoded through the backdoor. - */ - if(i) { - add = -80; - if(cb("2", 1, app_key) < 0) return -1; - } else if(b <= 39) { - add = 0; - if(cb("0", 1, app_key) < 0) return -1; - } else if(b < 79) { - add = -40; - if(cb("1", 1, app_key) < 0) return -1; - } else { - add = -80; - if(cb("2", 1, app_key) < 0) return -1; - } - wrote_len += 1; - } - - if(cb(".", 1, app_key) < 0) /* Separate arcs */ - return -1; - - add = OBJECT_IDENTIFIER__dump_arc(&st->buf[startn], - i - startn + 1, add, cb, app_key); - if(add < 0) return -1; - wrote_len += 1 + add; - startn = i + 1; - add = 0; - } - - return wrote_len; +OBJECT_IDENTIFIER__dump_body(const OBJECT_IDENTIFIER_t *st, + asn_app_consume_bytes_f *cb, void *app_key) { + char scratch[32]; + asn_oid_arc_t arc0, arc1; + size_t produced = 0; + size_t off = 0; + ssize_t rd; + int ret; + + rd = OBJECT_IDENTIFIER_get_first_arcs(st->buf, st->size, &arc0, &arc1); + if(rd <= 0) { + return -1; + } + + ret = snprintf(scratch, sizeof(scratch), "%"PRIu32".%"PRIu32, arc0, arc1); + if(ret >= (ssize_t)sizeof(scratch)) { + return -1; + } + produced += ret; + if(cb(scratch, ret, app_key) < 0) + return -1; + + for(off = rd; ; ) { + asn_oid_arc_t arc; + rd = OBJECT_IDENTIFIER_get_single_arc(st->buf + off, st->size - off, + &arc); + if(rd < 0) { + return -1; + } else if(rd == 0) { + /* No more arcs. */ + break; + } else { + off += rd; + assert(off <= st->size); + ret = snprintf(scratch, sizeof(scratch), ".%" PRIu32, arc); + if(ret >= (ssize_t)sizeof(scratch)) { + return -1; + } + produced += ret; + if(cb(scratch, ret, app_key) < 0) return -1; + } + } + + if(off != st->size) { + ASN_DEBUG("Could not scan to the end of Object Identifier"); + return -1; + } + + return produced; } static enum xer_pbd_rval -OBJECT_IDENTIFIER__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const void *chunk_buf, size_t chunk_size) { - OBJECT_IDENTIFIER_t *st = (OBJECT_IDENTIFIER_t *)sptr; +OBJECT_IDENTIFIER__xer_body_decode(const asn_TYPE_descriptor_t *td, void *sptr, + const void *chunk_buf, size_t chunk_size) { + OBJECT_IDENTIFIER_t *st = (OBJECT_IDENTIFIER_t *)sptr; const char *chunk_end = (const char *)chunk_buf + chunk_size; const char *endptr; - long s_arcs[10]; - long *arcs = s_arcs; - int arcs_count; - int ret; + asn_oid_arc_t s_arcs[10]; + asn_oid_arc_t *arcs = s_arcs; + ssize_t num_arcs; + ssize_t ret; (void)td; - arcs_count = OBJECT_IDENTIFIER_parse_arcs( - (const char *)chunk_buf, chunk_size, arcs, - sizeof(s_arcs)/sizeof(s_arcs[0]), &endptr); - if(arcs_count < 0) { + num_arcs = OBJECT_IDENTIFIER_parse_arcs( + (const char *)chunk_buf, chunk_size, arcs, + sizeof(s_arcs) / sizeof(s_arcs[0]), &endptr); + if(num_arcs < 0) { /* Expecting more than zero arcs */ return XPBD_BROKEN_ENCODING; - } else if(arcs_count == 0) { + } else if(num_arcs == 0) { return XPBD_NOT_BODY_IGNORE; } assert(endptr == chunk_end); - if((size_t)arcs_count > sizeof(s_arcs)/sizeof(s_arcs[0])) { - arcs = (long *)MALLOC(arcs_count * sizeof(long)); + if((size_t)num_arcs > sizeof(s_arcs)/sizeof(s_arcs[0])) { + arcs = (asn_oid_arc_t *)MALLOC(num_arcs * sizeof(asn_oid_arc_t)); if(!arcs) return XPBD_SYSTEM_FAILURE; - ret = OBJECT_IDENTIFIER_parse_arcs( - (const char *)chunk_buf, chunk_size, - arcs, arcs_count, &endptr); - if(ret != arcs_count) + ret = OBJECT_IDENTIFIER_parse_arcs((const char *)chunk_buf, chunk_size, + arcs, num_arcs, &endptr); + if(ret != num_arcs) return XPBD_SYSTEM_FAILURE; /* assert?.. */ } /* * Convert arcs into BER representation. */ - ret = OBJECT_IDENTIFIER_set_arcs(st, arcs, sizeof(*arcs), arcs_count); + ret = OBJECT_IDENTIFIER_set_arcs(st, arcs, num_arcs); if(arcs != s_arcs) FREEMEM(arcs); return ret ? XPBD_SYSTEM_FAILURE : XPBD_BODY_CONSUMED; } asn_dec_rval_t -OBJECT_IDENTIFIER_decode_xer(asn_codec_ctx_t *opt_codec_ctx, - asn_TYPE_descriptor_t *td, void **sptr, const char *opt_mname, - const void *buf_ptr, size_t size) { - - return xer_decode_primitive(opt_codec_ctx, td, +OBJECT_IDENTIFIER_decode_xer(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *td, void **sptr, + const char *opt_mname, const void *buf_ptr, + size_t size) { + return xer_decode_primitive(opt_codec_ctx, td, sptr, sizeof(OBJECT_IDENTIFIER_t), opt_mname, buf_ptr, size, OBJECT_IDENTIFIER__xer_body_decode); } asn_enc_rval_t -OBJECT_IDENTIFIER_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, - int ilevel, enum xer_encoder_flags_e flags, - asn_app_consume_bytes_f *cb, void *app_key) { - const OBJECT_IDENTIFIER_t *st = (const OBJECT_IDENTIFIER_t *)sptr; +OBJECT_IDENTIFIER_encode_xer(const asn_TYPE_descriptor_t *td, const void *sptr, + int ilevel, enum xer_encoder_flags_e flags, + asn_app_consume_bytes_f *cb, void *app_key) { + const OBJECT_IDENTIFIER_t *st = (const OBJECT_IDENTIFIER_t *)sptr; asn_enc_rval_t er; - (void)ilevel; - (void)flags; + (void)ilevel; + (void)flags; - if(!st || !st->buf) - ASN__ENCODE_FAILED; + if(!st || !st->buf) { + ASN__ENCODE_FAILED; + } - er.encoded = OBJECT_IDENTIFIER__dump_body(st, cb, app_key); - if(er.encoded < 0) ASN__ENCODE_FAILED; + er.encoded = OBJECT_IDENTIFIER__dump_body(st, cb, app_key); + if(er.encoded < 0) ASN__ENCODE_FAILED; - ASN__ENCODED_OK(er); + ASN__ENCODED_OK(er); } int -OBJECT_IDENTIFIER_print(asn_TYPE_descriptor_t *td, const void *sptr, - int ilevel, asn_app_consume_bytes_f *cb, void *app_key) { - const OBJECT_IDENTIFIER_t *st = (const OBJECT_IDENTIFIER_t *)sptr; +OBJECT_IDENTIFIER_print(const asn_TYPE_descriptor_t *td, const void *sptr, + int ilevel, asn_app_consume_bytes_f *cb, + void *app_key) { + const OBJECT_IDENTIFIER_t *st = (const OBJECT_IDENTIFIER_t *)sptr; (void)td; /* Unused argument */ (void)ilevel; /* Unused argument */ @@ -353,301 +270,198 @@ OBJECT_IDENTIFIER_print(asn_TYPE_descriptor_t *td, const void *sptr, if(cb("{ ", 2, app_key) < 0) return -1; - if(OBJECT_IDENTIFIER__dump_body(st, cb, app_key) < 0) - return -1; + if(OBJECT_IDENTIFIER__dump_body(st, cb, app_key) < 0) { + return -1; + } - return (cb(" }", 2, app_key) < 0) ? -1 : 0; + return (cb(" }", 2, app_key) < 0) ? -1 : 0; } -int -OBJECT_IDENTIFIER_get_arcs(const OBJECT_IDENTIFIER_t *oid, void *arcs, - unsigned int arc_type_size, unsigned int arc_slots) { - void *arcs_end = (char *)arcs + (arc_type_size * arc_slots); - int num_arcs = 0; - int startn = 0; - int add = 0; - int i; - - if(!oid || !oid->buf || (arc_slots && arc_type_size <= 1)) { - errno = EINVAL; - return -1; - } - - for(i = 0; i < oid->size; i++) { - uint8_t b = oid->buf[i]; - if((b & 0x80)) /* Continuation expected */ - continue; - - if(num_arcs == 0) { - /* - * First two arcs are encoded through the backdoor. - */ - unsigned LE = 1; /* Little endian */ - int first_arc; - num_arcs++; - if(!arc_slots) { num_arcs++; continue; } - - if(i) first_arc = 2; - else if(b <= 39) first_arc = 0; - else if(b < 79) first_arc = 1; - else first_arc = 2; - - add = -40 * first_arc; - memset(arcs, 0, arc_type_size); - *(unsigned char *)((char *)arcs - + ((*(char *)&LE)?0:(arc_type_size - 1))) - = first_arc; - arcs = ((char *)arcs) + arc_type_size; - } - - /* Decode, if has space */ - if(arcs < arcs_end) { - if(OBJECT_IDENTIFIER_get_single_arc(&oid->buf[startn], - i - startn + 1, add, - arcs, arc_type_size)) - return -1; - startn = i + 1; - arcs = ((char *)arcs) + arc_type_size; - add = 0; - } - num_arcs++; - } - - return num_arcs; +ssize_t +OBJECT_IDENTIFIER_get_arcs(const OBJECT_IDENTIFIER_t *st, asn_oid_arc_t *arcs, + size_t arc_slots) { + asn_oid_arc_t arc0, arc1; + size_t num_arcs = 0; + size_t off; + ssize_t rd; + + if(!st || !st->buf) { + errno = EINVAL; + return -1; + } + + rd = OBJECT_IDENTIFIER_get_first_arcs(st->buf, st->size, &arc0, &arc1); + if(rd <= 0) { + return -1; + } + num_arcs = 2; + switch(arc_slots) { + default: + case 2: + arcs[1] = arc1; + /* Fall through */ + case 1: + arcs[0] = arc0; + /* Fall through */ + case 0: + break; + } + + for(off = rd; ; ) { + asn_oid_arc_t arc; + rd = OBJECT_IDENTIFIER_get_single_arc(st->buf + off, st->size - off, + &arc); + if(rd < 0) { + return -1; + } else if(rd == 0) { + /* No more arcs. */ + break; + } else { + off += rd; + if(num_arcs < arc_slots) { + arcs[num_arcs] = arc; + } + num_arcs++; + } + } + + if(off != st->size) { + return -1; + } + + return num_arcs; } /* * Save the single value as an object identifier arc. */ -int -OBJECT_IDENTIFIER_set_single_arc(uint8_t *arcbuf, const void *arcval, unsigned int arcval_size, int prepared_order) { - /* +ssize_t +OBJECT_IDENTIFIER_set_single_arc(uint8_t *arcbuf, size_t arcbuf_len, + asn_oid_arc_t value) { + /* * The following conditions must hold: - * assert(arcval); - * assert(arcval_size > 0); - * assert(arcval_size <= 16); * assert(arcbuf); */ -#ifdef WORDS_BIGENDIAN - const unsigned isLittleEndian = 0; -#else - unsigned LE = 1; - unsigned isLittleEndian = *(char *)&LE; -#endif - const uint8_t *tend, *tp; - unsigned int cache; - uint8_t *bp = arcbuf; - int bits; - uint8_t buffer[16]; - - if(isLittleEndian && !prepared_order) { - const uint8_t *a = (const unsigned char *)arcval + arcval_size - 1; - const uint8_t *aend = (const uint8_t *)arcval; - uint8_t *msb = buffer + arcval_size - 1; - uint8_t *tb; - for(tb = buffer; a >= aend; tb++, a--) - if((*tb = *a) && (tb < msb)) - msb = tb; - tend = &buffer[arcval_size]; - tp = msb; /* Most significant non-zero byte */ - } else { - /* Look for most significant non-zero byte */ - tend = (const unsigned char *)arcval + arcval_size; - for(tp = (const uint8_t *)arcval; tp < tend - 1; tp++) - if(*tp) break; - } + uint8_t scratch[((sizeof(value) * CHAR_BIT + 6) / 7)]; + uint8_t *scratch_end = &scratch[sizeof(scratch)-1]; + uint8_t *b; + size_t result_len; + uint8_t mask; - /* - * Split the value in 7-bits chunks. - */ - bits = ((tend - tp) * CHAR_BIT) % 7; - if(bits) { - cache = *tp >> (CHAR_BIT - bits); - if(cache) { - *bp++ = cache | 0x80; - cache = *tp++; - bits = CHAR_BIT - bits; - } else { - bits = -bits; - } - } else { - cache = 0; - } - for(; tp < tend; tp++) { - cache = (cache << CHAR_BIT) + *tp; - bits += CHAR_BIT; - while(bits >= 7) { - bits -= 7; - *bp++ = 0x80 | (cache >> bits); - } - } - if(bits) *bp++ = cache; - bp[-1] &= 0x7f; /* Clear the last bit */ + for(b = scratch_end, mask = 0; ; mask = 0x80, b--) { + *b = mask | (value & 0x7f); + value >>= 7; + if(!value) { + break; + } + } + + result_len = (scratch_end - b) + 1; - return bp - arcbuf; + if(result_len > arcbuf_len) { + return -1; + } + + memcpy(arcbuf, b, result_len); + + return result_len; } int -OBJECT_IDENTIFIER_set_arcs(OBJECT_IDENTIFIER_t *oid, const void *arcs, unsigned int arc_type_size, unsigned int arc_slots) { - uint8_t *buf; - uint8_t *bp; - unsigned LE = 1; /* Little endian (x86) */ - unsigned isLittleEndian = *((char *)&LE); - unsigned int arc0; - unsigned int arc1; - unsigned size; - unsigned i; - - if(!oid || !arcs || arc_type_size < 1 - || arc_type_size > 16 - || arc_slots < 2) { - errno = EINVAL; +OBJECT_IDENTIFIER_set_arcs(OBJECT_IDENTIFIER_t *st, const asn_oid_arc_t *arcs, + size_t arc_slots) { + uint8_t *buf; + uint8_t *bp; + ssize_t wrote; + asn_oid_arc_t arc0; + asn_oid_arc_t arc1; + size_t size; + size_t i; + + if(!st || !arcs || arc_slots < 2) { + errno = EINVAL; return -1; } - switch(arc_type_size) { - case sizeof(char): - arc0 = ((const unsigned char *)arcs)[0]; - arc1 = ((const unsigned char *)arcs)[1]; - break; - case sizeof(short): - arc0 = ((const unsigned short *)arcs)[0]; - arc1 = ((const unsigned short *)arcs)[1]; - break; - case sizeof(int): - arc0 = ((const unsigned int *)arcs)[0]; - arc1 = ((const unsigned int *)arcs)[1]; - break; - default: - arc1 = arc0 = 0; - if(isLittleEndian) { /* Little endian (x86) */ - const unsigned char *ps, *pe; - /* If more significant bytes are present, - * make them > 255 quick */ - for(ps = (const unsigned char *)arcs + 1, pe = ps+arc_type_size; - ps < pe; ps++) - arc0 |= *ps, arc1 |= *(ps + arc_type_size); - arc0 <<= CHAR_BIT, arc1 <<= CHAR_BIT; - arc0 = *((const unsigned char *)arcs + 0); - arc1 = *((const unsigned char *)arcs + arc_type_size); - } else { - const unsigned char *ps, *pe; - /* If more significant bytes are present, - * make them > 255 quick */ - for(ps = (const unsigned char *)arcs, pe = ps+arc_type_size - 1; ps < pe; ps++) - arc0 |= *ps, arc1 |= *(ps + arc_type_size); - arc0 = *((const unsigned char *)arcs + arc_type_size - 1); - arc1 = *((const unsigned char *)arcs +(arc_type_size<< 1)-1); - } - } + arc0 = arcs[0]; + arc1 = arcs[1]; - /* - * The previous chapter left us with the first and the second arcs. - * The values are not precise (that is, they are valid only if - * they're less than 255), but OK for the purposes of making - * the sanity test below. - */ if(arc0 <= 1) { - if(arc1 >= 39) { + if(arc1 >= 40) { /* 8.19.4: At most 39 subsequent values (including 0) */ errno = ERANGE; return -1; } - } else if(arc0 > 2) { - /* 8.19.4: Only three values are allocated from the root node */ - errno = ERANGE; - return -1; - } - /* + } else if(arc0 == 2) { + if(arc1 > ASN_OID_ARC_MAX - 80) { + errno = ERANGE; + return -1; + } + } else if(arc0 > 2) { + /* 8.19.4: Only three values are allocated from the root node */ + errno = ERANGE; + return -1; + } + + /* * After above tests it is known that the value of arc0 is completely * trustworthy (0..2). However, the arc1's value is still meaningless. */ - /* - * Roughly estimate the maximum size necessary to encode these arcs. - * This estimation implicitly takes in account the following facts, - * that cancel each other: - * * the first two arcs are encoded in a single value. - * * the first value may require more space (+1 byte) - * * the value of the first arc which is in range (0..2) - */ - size = ((arc_type_size * CHAR_BIT + 6) / 7) * arc_slots; - bp = buf = (uint8_t *)MALLOC(size + 1); - if(!buf) { - /* ENOMEM */ - return -1; - } - - /* - * Encode the first two arcs. - * These require special treatment. - */ - { - uint8_t *tp; - uint8_t first_value[1 + 16]; /* of two arcs */ - uint8_t *fv = first_value; - - /* - * Simulate first_value = arc0 * 40 + arc1; - */ - /* Copy the second (1'st) arcs[1] into the first_value */ - *fv++ = 0; - arcs = ((const char *)arcs) + arc_type_size; - if(isLittleEndian) { - const uint8_t *aend = (const unsigned char *)arcs - 1; - const uint8_t *a1 = (const unsigned char *)arcs + arc_type_size - 1; - for(; a1 > aend; fv++, a1--) *fv = *a1; - } else { - const uint8_t *a1 = (const uint8_t *)arcs; - const uint8_t *aend = a1 + arc_type_size; - for(; a1 < aend; fv++, a1++) *fv = *a1; - } - /* Increase the first_value by arc0 */ - arc0 *= 40; /* (0..80) */ - for(tp = first_value + arc_type_size; tp >= first_value; tp--) { - unsigned int v = *tp; - v += arc0; - *tp = v; - if(v >= (1 << CHAR_BIT)) arc0 = v >> CHAR_BIT; - else break; - } - - assert(tp >= first_value); - - bp += OBJECT_IDENTIFIER_set_single_arc(bp, first_value, - fv - first_value, 1); - } - - /* - * Save the rest of arcs. - */ - for(arcs = ((const char *)arcs) + arc_type_size, i = 2; - i < arc_slots; - i++, arcs = ((const char *)arcs) + arc_type_size) { - bp += OBJECT_IDENTIFIER_set_single_arc(bp, - arcs, arc_type_size, 0); - } - - assert((unsigned)(bp - buf) <= size); - - /* + /* + * Roughly estimate the maximum size necessary to encode these arcs. + * This estimation implicitly takes in account the following facts, + * that cancel each other: + * * the first two arcs are encoded in a single value. + * * the first value may require more space (+1 byte) + * * the value of the first arc which is in range (0..2) + */ + size = ((sizeof(asn_oid_arc_t) * CHAR_BIT + 6) / 7) * arc_slots; + bp = buf = (uint8_t *)MALLOC(size + 1); + if(!buf) { + /* ENOMEM */ + return -1; + } + + wrote = OBJECT_IDENTIFIER_set_single_arc(bp, size, arc0 * 40 + arc1); + if(wrote <= 0) { + FREEMEM(buf); + return -1; + } + assert((size_t)wrote <= size); + bp += wrote; + size -= wrote; + + for(i = 2; i < arc_slots; i++) { + wrote = OBJECT_IDENTIFIER_set_single_arc(bp, size, arcs[i]); + if(wrote <= 0) { + FREEMEM(buf); + return -1; + } + assert((size_t)wrote <= size); + bp += wrote; + size -= wrote; + } + + /* * Replace buffer. */ - oid->size = bp - buf; - bp = oid->buf; - oid->buf = buf; + st->size = bp - buf; + bp = st->buf; + st->buf = buf; + st->buf[st->size] = '\0'; if(bp) FREEMEM(bp); return 0; } - -int +ssize_t OBJECT_IDENTIFIER_parse_arcs(const char *oid_text, ssize_t oid_txt_length, - long *arcs, unsigned int arcs_slots, const char **opt_oid_text_end) { - unsigned int arcs_count = 0; - const char *oid_end; + asn_oid_arc_t *arcs, size_t arcs_count, + const char **opt_oid_text_end) { + size_t num_arcs = 0; + const char *oid_end; enum { ST_LEADSPACE, ST_TAILSPACE, @@ -655,7 +469,7 @@ OBJECT_IDENTIFIER_parse_arcs(const char *oid_text, ssize_t oid_txt_length, ST_WAITDIGITS /* Next character is expected to be a digit */ } state = ST_LEADSPACE; - if(!oid_text || oid_txt_length < -1 || (arcs_slots && !arcs)) { + if(!oid_text || oid_txt_length < -1 || (arcs_count && !arcs)) { if(opt_oid_text_end) *opt_oid_text_end = oid_text; errno = EINVAL; return -1; @@ -664,32 +478,33 @@ OBJECT_IDENTIFIER_parse_arcs(const char *oid_text, ssize_t oid_txt_length, if(oid_txt_length == -1) oid_txt_length = strlen(oid_text); -#define _OID_CAPTURE_ARC(oid_text, oid_end) do { \ - const char *endp = oid_end; \ - long value; \ - switch(asn_strtol_lim(oid_text, &endp, &value)) { \ - case ASN_STRTOL_EXTRA_DATA: \ - case ASN_STRTOL_OK: \ - if(arcs_count < arcs_slots) \ - arcs[arcs_count] = value; \ - arcs_count++; \ - oid_text = endp - 1; \ - break; \ - case ASN_STRTOL_ERROR_RANGE: \ - if(opt_oid_text_end) \ - *opt_oid_text_end = oid_text; \ - errno = ERANGE; \ - return -1; \ - case ASN_STRTOL_ERROR_INVAL: \ - case ASN_STRTOL_EXPECT_MORE: \ - if(opt_oid_text_end) \ - *opt_oid_text_end = oid_text; \ - errno = EINVAL; \ - return -1; \ - } \ - } while(0) - - for(oid_end = oid_text + oid_txt_length; oid_textsize; + return result_ok; +} diff --git a/libs/smux/OCTET_STRING.c b/libs/smux/OCTET_STRING.c index 5420dede..a6928516 100644 --- a/libs/smux/OCTET_STRING.c +++ b/libs/smux/OCTET_STRING.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2003, 2004, 2005, 2006 Lev Walkin . + * Copyright (c) 2003-2017 Lev Walkin . * All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ @@ -14,38 +14,50 @@ static const ber_tlv_tag_t asn_DEF_OCTET_STRING_tags[] = { (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)) }; -static const asn_OCTET_STRING_specifics_t asn_DEF_OCTET_STRING_specs = { +asn_OCTET_STRING_specifics_t asn_SPC_OCTET_STRING_specs = { sizeof(OCTET_STRING_t), offsetof(OCTET_STRING_t, _asn_ctx), ASN_OSUBV_STR }; -static const asn_per_constraints_t asn_DEF_OCTET_STRING_constraints = { - { APC_CONSTRAINED, 8, 8, 0, 255 }, - { APC_SEMI_CONSTRAINED, -1, -1, 0, 0 }, - 0, 0 -}; -asn_TYPE_descriptor_t asn_DEF_OCTET_STRING = { - "OCTET STRING", /* Canonical name */ - "OCTET_STRING", /* XML tag name */ + +asn_TYPE_operation_t asn_OP_OCTET_STRING = { OCTET_STRING_free, - OCTET_STRING_print, /* non-ascii stuff, generally */ - asn_generic_no_constraint, + OCTET_STRING_print, /* OCTET STRING generally means a non-ascii sequence */ + OCTET_STRING_compare, OCTET_STRING_decode_ber, OCTET_STRING_encode_der, OCTET_STRING_decode_xer_hex, OCTET_STRING_encode_xer, +#ifdef ASN_DISABLE_OER_SUPPORT + 0, + 0, +#else + OCTET_STRING_decode_oer, + OCTET_STRING_encode_oer, +#endif /* ASN_DISABLE_OER_SUPPORT */ +#ifdef ASN_DISABLE_PER_SUPPORT + 0, + 0, +#else OCTET_STRING_decode_uper, /* Unaligned PER decoder */ OCTET_STRING_encode_uper, /* Unaligned PER encoder */ - 0, /* Use generic outmost tag fetcher */ +#endif /* ASN_DISABLE_PER_SUPPORT */ + OCTET_STRING_random_fill, + 0 /* Use generic outmost tag fetcher */ +}; +asn_TYPE_descriptor_t asn_DEF_OCTET_STRING = { + "OCTET STRING", /* Canonical name */ + "OCTET_STRING", /* XML tag name */ + &asn_OP_OCTET_STRING, asn_DEF_OCTET_STRING_tags, sizeof(asn_DEF_OCTET_STRING_tags) / sizeof(asn_DEF_OCTET_STRING_tags[0]), asn_DEF_OCTET_STRING_tags, /* Same as above */ sizeof(asn_DEF_OCTET_STRING_tags) / sizeof(asn_DEF_OCTET_STRING_tags[0]), - 0, /* No PER visible constraints */ + { 0, 0, asn_generic_no_constraint }, 0, 0, /* No members */ - &asn_DEF_OCTET_STRING_specs + &asn_SPC_OCTET_STRING_specs }; #undef _CH_PHASE @@ -111,14 +123,14 @@ asn_TYPE_descriptor_t asn_DEF_OCTET_STRING = { * No, I am not going to explain what the following stuff is. */ struct _stack_el { - ber_tlv_len_t left; /* What's left to read (or -1) */ - ber_tlv_len_t got; /* What was actually processed */ - int cont_level; /* Depth of subcontainment */ - int want_nulls; /* Want null "end of content" octets? */ - int bits_chopped; /* Flag in BIT STRING mode */ - ber_tlv_tag_t tag; /* For debugging purposes */ - struct _stack_el *prev; - struct _stack_el *next; + ber_tlv_len_t left; /* What's left to read (or -1) */ + ber_tlv_len_t got; /* What was actually processed */ + unsigned cont_level; /* Depth of subcontainment */ + int want_nulls; /* Want null "end of content" octets? */ + int bits_chopped; /* Flag in BIT STRING mode */ + ber_tlv_tag_t tag; /* For debugging purposes */ + struct _stack_el *prev; + struct _stack_el *next; }; struct _stack { struct _stack_el *tail; @@ -157,7 +169,7 @@ OS__add_stack_el(struct _stack *st) { } static struct _stack * -_new_stack() { +_new_stack(void) { return (struct _stack *)CALLOC(1, sizeof(struct _stack)); } @@ -165,12 +177,12 @@ _new_stack() { * Decode OCTET STRING type. */ asn_dec_rval_t -OCTET_STRING_decode_ber(asn_codec_ctx_t *opt_codec_ctx, - asn_TYPE_descriptor_t *td, - void **sptr, const void *buf_ptr, size_t size, int tag_mode) { - asn_OCTET_STRING_specifics_t *specs = td->specifics - ? (asn_OCTET_STRING_specifics_t *)td->specifics - : &asn_DEF_OCTET_STRING_specs; +OCTET_STRING_decode_ber(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *td, void **sptr, + const void *buf_ptr, size_t size, int tag_mode) { + const asn_OCTET_STRING_specifics_t *specs = td->specifics + ? (const asn_OCTET_STRING_specifics_t *)td->specifics + : &asn_SPC_OCTET_STRING_specs; BIT_STRING_t *st = (BIT_STRING_t *)*sptr; asn_dec_rval_t rval; asn_struct_ctx_t *ctx; @@ -213,9 +225,7 @@ OCTET_STRING_decode_ber(asn_codec_ctx_t *opt_codec_ctx, * Complex operation, requires stack of expectations. */ ctx->ptr = _new_stack(); - if(ctx->ptr) { - stck = (struct _stack *)ctx->ptr; - } else { + if(!ctx->ptr) { RETURN(RC_FAIL); } } else { @@ -244,11 +254,11 @@ OCTET_STRING_decode_ber(asn_codec_ctx_t *opt_codec_ctx, ber_tlv_tag_t expected_tag; ssize_t tl, ll, tlvl; /* This one works even if (sel->left == -1) */ - ssize_t Left = ((!sel||(size_t)sel->left >= size) - ?(ssize_t)size:sel->left); + size_t Left = ((!sel||(size_t)sel->left >= size) + ?size:(size_t)sel->left); - ASN_DEBUG("%p, s->l=%ld, s->wn=%ld, s->g=%ld\n", sel, + ASN_DEBUG("%p, s->l=%ld, s->wn=%ld, s->g=%ld\n", (void *)sel, (long)(sel?sel->left:0), (long)(sel?sel->want_nulls:0), (long)(sel?sel->got:0) @@ -333,7 +343,7 @@ OCTET_STRING_decode_ber(asn_codec_ctx_t *opt_codec_ctx, case ASN_OSUBV_STR: default: if(sel) { - int level = sel->cont_level; + unsigned level = sel->cont_level; if(level < td->all_tags_count) { expected_tag = td->all_tags[level]; break; @@ -396,7 +406,7 @@ OCTET_STRING_decode_ber(asn_codec_ctx_t *opt_codec_ctx, sel->got += tlvl; ADVANCE(tlvl); - ASN_DEBUG("+EXPECT2 got=%ld left=%ld, wn=%d, clvl=%d", + ASN_DEBUG("+EXPECT2 got=%ld left=%ld, wn=%d, clvl=%u", (long)sel->got, (long)sel->left, sel->want_nulls, sel->cont_level); @@ -485,7 +495,7 @@ OCTET_STRING_decode_ber(asn_codec_ctx_t *opt_codec_ctx, if(sel) { ASN_DEBUG("3sel p=%p, wn=%d, l=%ld, g=%ld, size=%ld", - sel->prev, sel->want_nulls, + (void *)sel->prev, sel->want_nulls, (long)sel->left, (long)sel->got, (long)size); if(sel->prev || sel->want_nulls > 1 || sel->left > 0) { RETURN(RC_WMORE); @@ -495,9 +505,18 @@ OCTET_STRING_decode_ber(asn_codec_ctx_t *opt_codec_ctx, /* * BIT STRING-specific processing. */ - if(type_variant == ASN_OSUBV_BIT && st->size) { - /* Finalize BIT STRING: zero out unused bits. */ - st->buf[st->size-1] &= 0xff << st->bits_unused; + if(type_variant == ASN_OSUBV_BIT) { + if(st->size) { + if(st->bits_unused < 0 || st->bits_unused > 7) { + RETURN(RC_FAIL); + } + /* Finalize BIT STRING: zero out unused bits. */ + st->buf[st->size-1] &= 0xff << st->bits_unused; + } else { + if(st->bits_unused) { + RETURN(RC_FAIL); + } + } } ASN_DEBUG("Took %ld bytes to encode %s: [%s]:%ld", @@ -513,14 +532,14 @@ OCTET_STRING_decode_ber(asn_codec_ctx_t *opt_codec_ctx, * Encode OCTET STRING type using DER. */ asn_enc_rval_t -OCTET_STRING_encode_der(asn_TYPE_descriptor_t *td, void *sptr, - int tag_mode, ber_tlv_tag_t tag, - asn_app_consume_bytes_f *cb, void *app_key) { - asn_enc_rval_t er; - asn_OCTET_STRING_specifics_t *specs = td->specifics - ? (asn_OCTET_STRING_specifics_t *)td->specifics - : &asn_DEF_OCTET_STRING_specs; - BIT_STRING_t *st = (BIT_STRING_t *)sptr; +OCTET_STRING_encode_der(const asn_TYPE_descriptor_t *td, const void *sptr, + int tag_mode, ber_tlv_tag_t tag, + asn_app_consume_bytes_f *cb, void *app_key) { + asn_enc_rval_t er; + const asn_OCTET_STRING_specifics_t *specs = td->specifics + ? (const asn_OCTET_STRING_specifics_t *)td->specifics + : &asn_SPC_OCTET_STRING_specs; + const BIT_STRING_t *st = (const BIT_STRING_t *)sptr; enum asn_OS_Subvariant type_variant = specs->subvariant; int fix_last_byte = 0; @@ -558,7 +577,6 @@ OCTET_STRING_encode_der(asn_TYPE_descriptor_t *td, void *sptr, uint8_t b = st->bits_unused & 0x07; if(b && st->size) fix_last_byte = 1; ASN__CALLBACK(&b, 1); - er.encoded++; } /* Invoke callback for the main part of the buffer */ @@ -570,17 +588,16 @@ OCTET_STRING_encode_der(asn_TYPE_descriptor_t *td, void *sptr, ASN__CALLBACK(&b, 1); } - er.encoded += st->size; ASN__ENCODED_OK(er); cb_failed: ASN__ENCODE_FAILED; } asn_enc_rval_t -OCTET_STRING_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, - int ilevel, enum xer_encoder_flags_e flags, - asn_app_consume_bytes_f *cb, void *app_key) { - const char * const h2c = "0123456789ABCDEF"; +OCTET_STRING_encode_xer(const asn_TYPE_descriptor_t *td, const void *sptr, + int ilevel, enum xer_encoder_flags_e flags, + asn_app_consume_bytes_f *cb, void *app_key) { + const char * const h2c = "0123456789ABCDEF"; const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr; asn_enc_rval_t er; char scratch[16 * 3 + 4]; @@ -604,7 +621,6 @@ OCTET_STRING_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, for(; buf < end; buf++) { if(p >= scend) { ASN__CALLBACK(scratch, p - scratch); - er.encoded += p - scratch; p = scratch; } *p++ = h2c[(*buf >> 4) & 0x0F]; @@ -612,12 +628,10 @@ OCTET_STRING_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, } ASN__CALLBACK(scratch, p-scratch); /* Dump the rest */ - er.encoded += p - scratch; } else { for(i = 0; buf < end; buf++, i++) { if(!(i % 16) && (i || st->size > 16)) { ASN__CALLBACK(scratch, p-scratch); - er.encoded += (p-scratch); p = scratch; ASN__TEXT_INDENT(1, ilevel); } @@ -628,7 +642,6 @@ OCTET_STRING_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, if(p - scratch) { p--; /* Remove the tail space */ ASN__CALLBACK(scratch, p-scratch); /* Dump the rest */ - er.encoded += p - scratch; if(st->size > 16) ASN__TEXT_INDENT(1, ilevel-1); } @@ -733,10 +746,10 @@ OCTET_STRING__handle_control_chars(void *struct_ptr, const void *chunk_buf, size } asn_enc_rval_t -OCTET_STRING_encode_xer_utf8(asn_TYPE_descriptor_t *td, void *sptr, - int ilevel, enum xer_encoder_flags_e flags, - asn_app_consume_bytes_f *cb, void *app_key) { - const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr; +OCTET_STRING_encode_xer_utf8(const asn_TYPE_descriptor_t *td, const void *sptr, + int ilevel, enum xer_encoder_flags_e flags, + asn_app_consume_bytes_f *cb, void *app_key) { + const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr; asn_enc_rval_t er; uint8_t *buf, *end; uint8_t *ss; /* Sequence start */ @@ -790,8 +803,8 @@ static ssize_t OCTET_STRING__convert_hexadecimal(void *sptr, const void *chunk_b uint8_t *buf; /* Reallocate buffer according to high cap estimation */ - ssize_t _ns = st->size + (chunk_size + 1) / 2; - void *nptr = REALLOC(st->buf, _ns + 1); + size_t new_size = st->size + (chunk_size + 1) / 2; + void *nptr = REALLOC(st->buf, new_size + 1); if(!nptr) return -1; st->buf = (uint8_t *)nptr; buf = st->buf + st->size; @@ -848,7 +861,7 @@ static ssize_t OCTET_STRING__convert_hexadecimal(void *sptr, const void *chunk_b } st->size = buf - st->buf; /* Adjust the buffer size */ - assert(st->size <= _ns); + assert(st->size <= new_size); st->buf[st->size] = 0; /* Courtesy termination */ return (chunk_stop - (const char *)chunk_buf); /* Converted size */ @@ -865,8 +878,8 @@ static ssize_t OCTET_STRING__convert_binary(void *sptr, const void *chunk_buf, s uint8_t *buf; /* Reallocate buffer according to high cap estimation */ - ssize_t _ns = st->size + (chunk_size + 7) / 8; - void *nptr = REALLOC(st->buf, _ns + 1); + size_t new_size = st->size + (chunk_size + 7) / 8; + void *nptr = REALLOC(st->buf, new_size + 1); if(!nptr) return -1; st->buf = (uint8_t *)nptr; buf = st->buf + st->size; @@ -910,7 +923,7 @@ static ssize_t OCTET_STRING__convert_binary(void *sptr, const void *chunk_buf, s st->bits_unused = bits_unused; } - assert(st->size <= _ns); + assert(st->size <= new_size); st->buf[st->size] = 0; /* Courtesy termination */ return chunk_size; /* Converted in full */ @@ -921,16 +934,13 @@ static ssize_t OCTET_STRING__convert_binary(void *sptr, const void *chunk_buf, s */ static int OS__strtoent(int base, const char *buf, const char *end, int32_t *ret_value) { + const int32_t last_unicode_codepoint = 0x10ffff; int32_t val = 0; const char *p; for(p = buf; p < end; p++) { int ch = *p; - /* Strange huge value */ - if((val * base + base) < 0) - return -1; - switch(ch) { case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: /*01234*/ case 0x35: case 0x36: case 0x37: case 0x38: case 0x39: /*56789*/ @@ -950,6 +960,11 @@ OS__strtoent(int base, const char *buf, const char *end, int32_t *ret_value) { default: return -1; /* Character set error */ } + + /* Value exceeds the Unicode range. */ + if(val > last_unicode_codepoint) { + return -1; + } } *ret_value = -1; @@ -959,15 +974,17 @@ OS__strtoent(int base, const char *buf, const char *end, int32_t *ret_value) { /* * Convert from the plain UTF-8 format, expanding entity references: "2 < 3" */ -static ssize_t OCTET_STRING__convert_entrefs(void *sptr, const void *chunk_buf, size_t chunk_size, int have_more) { - OCTET_STRING_t *st = (OCTET_STRING_t *)sptr; +static ssize_t +OCTET_STRING__convert_entrefs(void *sptr, const void *chunk_buf, + size_t chunk_size, int have_more) { + OCTET_STRING_t *st = (OCTET_STRING_t *)sptr; const char *p = (const char *)chunk_buf; const char *pend = p + chunk_size; uint8_t *buf; /* Reallocate buffer */ - ssize_t _ns = st->size + chunk_size; - void *nptr = REALLOC(st->buf, _ns + 1); + size_t new_size = st->size + chunk_size; + void *nptr = REALLOC(st->buf, new_size + 1); if(!nptr) return -1; st->buf = (uint8_t *)nptr; buf = st->buf + st->size; @@ -1090,7 +1107,7 @@ static ssize_t OCTET_STRING__convert_entrefs(void *sptr, const void *chunk_buf, } st->size = buf - st->buf; - assert(st->size <= _ns); + assert(st->size <= new_size); st->buf[st->size] = 0; /* Courtesy termination */ return chunk_size; /* Converted in full */ @@ -1100,19 +1117,17 @@ static ssize_t OCTET_STRING__convert_entrefs(void *sptr, const void *chunk_buf, * Decode OCTET STRING from the XML element's body. */ static asn_dec_rval_t -OCTET_STRING__decode_xer(asn_codec_ctx_t *opt_codec_ctx, - asn_TYPE_descriptor_t *td, void **sptr, - const char *opt_mname, const void *buf_ptr, size_t size, - int (*opt_unexpected_tag_decoder) - (void *struct_ptr, const void *chunk_buf, size_t chunk_size), - ssize_t (*body_receiver) - (void *struct_ptr, const void *chunk_buf, size_t chunk_size, - int have_more) -) { - OCTET_STRING_t *st = (OCTET_STRING_t *)*sptr; - asn_OCTET_STRING_specifics_t *specs = td->specifics - ? (asn_OCTET_STRING_specifics_t *)td->specifics - : &asn_DEF_OCTET_STRING_specs; +OCTET_STRING__decode_xer( + const asn_codec_ctx_t *opt_codec_ctx, const asn_TYPE_descriptor_t *td, + void **sptr, const char *opt_mname, const void *buf_ptr, size_t size, + int (*opt_unexpected_tag_decoder)(void *struct_ptr, const void *chunk_buf, + size_t chunk_size), + ssize_t (*body_receiver)(void *struct_ptr, const void *chunk_buf, + size_t chunk_size, int have_more)) { + OCTET_STRING_t *st = (OCTET_STRING_t *)*sptr; + const asn_OCTET_STRING_specifics_t *specs = td->specifics + ? (const asn_OCTET_STRING_specifics_t *)td->specifics + : &asn_SPC_OCTET_STRING_specs; const char *xml_tag = opt_mname ? opt_mname : td->xml_tag; asn_struct_ctx_t *ctx; /* Per-structure parser context */ asn_dec_rval_t rval; /* Return value from the decoder */ @@ -1160,10 +1175,11 @@ sta_failed: * Decode OCTET STRING from the hexadecimal data. */ asn_dec_rval_t -OCTET_STRING_decode_xer_hex(asn_codec_ctx_t *opt_codec_ctx, - asn_TYPE_descriptor_t *td, void **sptr, - const char *opt_mname, const void *buf_ptr, size_t size) { - return OCTET_STRING__decode_xer(opt_codec_ctx, td, sptr, opt_mname, +OCTET_STRING_decode_xer_hex(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *td, void **sptr, + const char *opt_mname, const void *buf_ptr, + size_t size) { + return OCTET_STRING__decode_xer(opt_codec_ctx, td, sptr, opt_mname, buf_ptr, size, 0, OCTET_STRING__convert_hexadecimal); } @@ -1171,10 +1187,11 @@ OCTET_STRING_decode_xer_hex(asn_codec_ctx_t *opt_codec_ctx, * Decode OCTET STRING from the binary (0/1) data. */ asn_dec_rval_t -OCTET_STRING_decode_xer_binary(asn_codec_ctx_t *opt_codec_ctx, - asn_TYPE_descriptor_t *td, void **sptr, - const char *opt_mname, const void *buf_ptr, size_t size) { - return OCTET_STRING__decode_xer(opt_codec_ctx, td, sptr, opt_mname, +OCTET_STRING_decode_xer_binary(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *td, void **sptr, + const char *opt_mname, const void *buf_ptr, + size_t size) { + return OCTET_STRING__decode_xer(opt_codec_ctx, td, sptr, opt_mname, buf_ptr, size, 0, OCTET_STRING__convert_binary); } @@ -1182,19 +1199,22 @@ OCTET_STRING_decode_xer_binary(asn_codec_ctx_t *opt_codec_ctx, * Decode OCTET STRING from the string (ASCII/UTF-8) data. */ asn_dec_rval_t -OCTET_STRING_decode_xer_utf8(asn_codec_ctx_t *opt_codec_ctx, - asn_TYPE_descriptor_t *td, void **sptr, - const char *opt_mname, const void *buf_ptr, size_t size) { - return OCTET_STRING__decode_xer(opt_codec_ctx, td, sptr, opt_mname, +OCTET_STRING_decode_xer_utf8(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *td, void **sptr, + const char *opt_mname, const void *buf_ptr, + size_t size) { + return OCTET_STRING__decode_xer(opt_codec_ctx, td, sptr, opt_mname, buf_ptr, size, OCTET_STRING__handle_control_chars, OCTET_STRING__convert_entrefs); } +#ifndef ASN_DISABLE_PER_SUPPORT + static int OCTET_STRING_per_get_characters(asn_per_data_t *po, uint8_t *buf, size_t units, unsigned int bpc, unsigned int unit_bits, - long lb, long ub, asn_per_constraints_t *pc) { + long lb, long ub, const asn_per_constraints_t *pc) { uint8_t *end = buf + units * bpc; ASN_DEBUG("Expanding %d characters into (%ld..%ld):%d", @@ -1236,8 +1256,8 @@ OCTET_STRING_per_get_characters(asn_per_data_t *po, uint8_t *buf, } for(; buf < end; buf += bpc) { - int code = per_get_few_bits(po, unit_bits); - int ch = code + lb; + int32_t code = per_get_few_bits(po, unit_bits); + int32_t ch = code + lb; if(code < 0) return -1; /* WMORE */ if(ch > ub) { ASN_DEBUG("Code %d is out of range (%ld..%ld)", @@ -1258,7 +1278,7 @@ OCTET_STRING_per_get_characters(asn_per_data_t *po, uint8_t *buf, static int OCTET_STRING_per_put_characters(asn_per_outp_t *po, const uint8_t *buf, size_t units, unsigned int bpc, unsigned int unit_bits, - long lb, long ub, asn_per_constraints_t *pc) { + long lb, long ub, const asn_per_constraints_t *pc) { const uint8_t *end = buf + units * bpc; ASN_DEBUG("Squeezing %d characters into (%ld..%ld):%d (%d bpc)", @@ -1296,48 +1316,57 @@ OCTET_STRING_per_put_characters(asn_per_outp_t *po, const uint8_t *buf, return per_put_many_bits(po, buf, unit_bits * units); } - for(ub -= lb; buf < end; buf += bpc) { - int ch; - uint32_t value; - switch(bpc) { - case 1: value = *(const uint8_t *)buf; break; - case 2: value = (buf[0] << 8) | buf[1]; break; - case 4: value = (buf[0] << 24) | (buf[1] << 16) - | (buf[2] << 8) | buf[3]; break; - default: return -1; - } - ch = value - lb; - if(ch < 0 || ch > ub) { - ASN_DEBUG("Character %d (0x%02x)" - " is out of range (%ld..%ld)", - *buf, *buf, lb, ub + lb); - return -1; - } - if(per_put_few_bits(po, ch, unit_bits)) - return -1; - } - - return 0; + for(ub -= lb; buf < end; buf += bpc) { + int ch; + uint32_t value; + switch(bpc) { + case 1: + value = *(const uint8_t *)buf; + break; + case 2: + value = (buf[0] << 8) | buf[1]; + break; + case 4: + value = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; + break; + default: + return -1; + } + ch = value - lb; + if(ch < 0 || ch > ub) { + ASN_DEBUG("Character %d (0x%02x) is out of range (%ld..%ld)", *buf, + value, lb, ub + lb); + return -1; + } + if(per_put_few_bits(po, ch, unit_bits)) return -1; + } + + return 0; } +static asn_per_constraints_t asn_DEF_OCTET_STRING_constraints = { + { APC_CONSTRAINED, 8, 8, 0, 255 }, + { APC_SEMI_CONSTRAINED, -1, -1, 0, 0 }, + 0, 0 +}; + asn_dec_rval_t -OCTET_STRING_decode_uper(asn_codec_ctx_t *opt_codec_ctx, - asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, - void **sptr, asn_per_data_t *pd) { - - asn_OCTET_STRING_specifics_t *specs = td->specifics - ? (asn_OCTET_STRING_specifics_t *)td->specifics - : &asn_DEF_OCTET_STRING_specs; - asn_per_constraints_t *pc = constraints ? constraints - : td->per_constraints; - asn_per_constraint_t *cval; - asn_per_constraint_t *csiz; +OCTET_STRING_decode_uper(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, void **sptr, + asn_per_data_t *pd) { + const asn_OCTET_STRING_specifics_t *specs = td->specifics + ? (const asn_OCTET_STRING_specifics_t *)td->specifics + : &asn_SPC_OCTET_STRING_specs; + const asn_per_constraints_t *pc = + constraints ? constraints : td->encoding_constraints.per_constraints; + const asn_per_constraint_t *cval; + const asn_per_constraint_t *csiz; asn_dec_rval_t rval = { RC_OK, 0 }; - BIT_STRING_t *st = (BIT_STRING_t *)*sptr; + OCTET_STRING_t *st = (OCTET_STRING_t *)*sptr; ssize_t consumed_myself = 0; int repeat; enum { - OS__BPC_BIT = 0, OS__BPC_CHAR = 1, OS__BPC_U16 = 2, OS__BPC_U32 = 4 @@ -1358,11 +1387,9 @@ OCTET_STRING_decode_uper(asn_codec_ctx_t *opt_codec_ctx, switch(specs->subvariant) { default: case ASN_OSUBV_ANY: + case ASN_OSUBV_BIT: ASN_DEBUG("Unrecognized subvariant %d", specs->subvariant); RETURN(RC_FAIL); - case ASN_OSUBV_BIT: - canonical_unit_bits = unit_bits = 1; - bpc = OS__BPC_BIT; break; case ASN_OSUBV_STR: canonical_unit_bits = unit_bits = 8; @@ -1388,7 +1415,7 @@ OCTET_STRING_decode_uper(asn_codec_ctx_t *opt_codec_ctx, * Allocate the string. */ if(!st) { - st = (BIT_STRING_t *)(*sptr = CALLOC(1, specs->struct_size)); + st = (OCTET_STRING_t *)(*sptr = CALLOC(1, specs->struct_size)); if(!st) RETURN(RC_FAIL); } @@ -1401,7 +1428,6 @@ OCTET_STRING_decode_uper(asn_codec_ctx_t *opt_codec_ctx, if(inext < 0) RETURN(RC_WMORE); if(inext) { csiz = &asn_DEF_OCTET_STRING_constraints.size; - cval = &asn_DEF_OCTET_STRING_constraints.value; unit_bits = canonical_unit_bits; } } @@ -1438,10 +1464,6 @@ OCTET_STRING_decode_uper(asn_codec_ctx_t *opt_codec_ctx, if(ret < 0) RETURN(RC_WMORE); consumed_myself += unit_bits * csiz->upper_bound; st->buf[st->size] = 0; - if(bpc == 0) { - int ubs = (csiz->upper_bound & 0x7); - st->bits_unused = ubs ? 8 - ubs : 0; - } RETURN(RC_OK); } @@ -1449,41 +1471,27 @@ OCTET_STRING_decode_uper(asn_codec_ctx_t *opt_codec_ctx, do { ssize_t raw_len; ssize_t len_bytes; - ssize_t len_bits; void *p; int ret; /* Get the PER length */ - raw_len = uper_get_length(pd, csiz->effective_bits, &repeat); + raw_len = uper_get_length(pd, csiz->effective_bits, csiz->lower_bound, + &repeat); if(raw_len < 0) RETURN(RC_WMORE); - raw_len += csiz->lower_bound; + if(raw_len == 0 && st->buf) break; ASN_DEBUG("Got PER length eb %ld, len %ld, %s (%s)", (long)csiz->effective_bits, (long)raw_len, repeat ? "repeat" : "once", td->name); - if(bpc) { - len_bytes = raw_len * bpc; - len_bits = len_bytes * unit_bits; - } else { - len_bits = raw_len; - len_bytes = (len_bits + 7) >> 3; - if(len_bits & 0x7) - st->bits_unused = 8 - (len_bits & 0x7); - /* len_bits be multiple of 16K if repeat is set */ - } + len_bytes = raw_len * bpc; p = REALLOC(st->buf, st->size + len_bytes + 1); if(!p) RETURN(RC_FAIL); st->buf = (uint8_t *)p; - if(bpc) { - ret = OCTET_STRING_per_get_characters(pd, - &st->buf[st->size], raw_len, bpc, unit_bits, - cval->lower_bound, cval->upper_bound, pc); - if(ret > 0) RETURN(RC_FAIL); - } else { - ret = per_get_many_bits(pd, &st->buf[st->size], - 0, len_bits); - } + ret = OCTET_STRING_per_get_characters(pd, &st->buf[st->size], raw_len, + bpc, unit_bits, cval->lower_bound, + cval->upper_bound, pc); + if(ret > 0) RETURN(RC_FAIL); if(ret < 0) RETURN(RC_WMORE); st->size += len_bytes; } while(repeat); @@ -1493,26 +1501,25 @@ OCTET_STRING_decode_uper(asn_codec_ctx_t *opt_codec_ctx, } asn_enc_rval_t -OCTET_STRING_encode_uper(asn_TYPE_descriptor_t *td, - asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { - - asn_OCTET_STRING_specifics_t *specs = td->specifics - ? (asn_OCTET_STRING_specifics_t *)td->specifics - : &asn_DEF_OCTET_STRING_specs; - asn_per_constraints_t *pc = constraints ? constraints - : td->per_constraints; - asn_per_constraint_t *cval; - asn_per_constraint_t *csiz; - const BIT_STRING_t *st = (const BIT_STRING_t *)sptr; +OCTET_STRING_encode_uper(const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, + const void *sptr, asn_per_outp_t *po) { + const asn_OCTET_STRING_specifics_t *specs = td->specifics + ? (const asn_OCTET_STRING_specifics_t *)td->specifics + : &asn_SPC_OCTET_STRING_specs; + const asn_per_constraints_t *pc = constraints ? constraints + : td->encoding_constraints.per_constraints; + const asn_per_constraint_t *cval; + const asn_per_constraint_t *csiz; + const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr; asn_enc_rval_t er = { 0, 0, 0 }; int inext = 0; /* Lies not within extension root */ unsigned int unit_bits; unsigned int canonical_unit_bits; - unsigned int sizeinunits; + size_t size_in_units; const uint8_t *buf; int ret; enum { - OS__BPC_BIT = 0, OS__BPC_CHAR = 1, OS__BPC_U16 = 2, OS__BPC_U32 = 4 @@ -1534,128 +1541,114 @@ OCTET_STRING_encode_uper(asn_TYPE_descriptor_t *td, switch(specs->subvariant) { default: case ASN_OSUBV_ANY: - ASN__ENCODE_FAILED; case ASN_OSUBV_BIT: - canonical_unit_bits = unit_bits = 1; - bpc = OS__BPC_BIT; - sizeinunits = st->size * 8 - (st->bits_unused & 0x07); - ASN_DEBUG("BIT STRING of %d bytes, %d bits unused", - sizeinunits, st->bits_unused); - break; + ASN__ENCODE_FAILED; case ASN_OSUBV_STR: canonical_unit_bits = unit_bits = 8; if(cval->flags & APC_CONSTRAINED) unit_bits = cval->range_bits; bpc = OS__BPC_CHAR; - sizeinunits = st->size; + size_in_units = st->size; break; case ASN_OSUBV_U16: canonical_unit_bits = unit_bits = 16; if(cval->flags & APC_CONSTRAINED) unit_bits = cval->range_bits; bpc = OS__BPC_U16; - sizeinunits = st->size / 2; + size_in_units = st->size >> 1; + if(st->size & 1) { + ASN_DEBUG("%s string size is not modulo 2", td->name); + ASN__ENCODE_FAILED; + } break; case ASN_OSUBV_U32: canonical_unit_bits = unit_bits = 32; if(cval->flags & APC_CONSTRAINED) unit_bits = cval->range_bits; bpc = OS__BPC_U32; - sizeinunits = st->size / 4; + size_in_units = st->size >> 2; + if(st->size & 3) { + ASN_DEBUG("%s string size is not modulo 4", td->name); + ASN__ENCODE_FAILED; + } break; } - ASN_DEBUG("Encoding %s into %d units of %d bits" + ASN_DEBUG("Encoding %s into %" ASN_PRI_SIZE " units of %d bits" " (%ld..%ld, effective %d)%s", - td->name, sizeinunits, unit_bits, + td->name, size_in_units, unit_bits, csiz->lower_bound, csiz->upper_bound, csiz->effective_bits, ct_extensible ? " EXT" : ""); /* Figure out whether size lies within PER visible constraint */ - if(csiz->effective_bits >= 0) { - if((int)sizeinunits < csiz->lower_bound - || (int)sizeinunits > csiz->upper_bound) { - if(ct_extensible) { - cval = &asn_DEF_OCTET_STRING_constraints.value; - csiz = &asn_DEF_OCTET_STRING_constraints.size; - unit_bits = canonical_unit_bits; - inext = 1; - } else - ASN__ENCODE_FAILED; - } - } else { - inext = 0; - } - - if(ct_extensible) { + if(csiz->effective_bits >= 0) { + if((ssize_t)size_in_units < csiz->lower_bound + || (ssize_t)size_in_units > csiz->upper_bound) { + if(ct_extensible) { + csiz = &asn_DEF_OCTET_STRING_constraints.size; + unit_bits = canonical_unit_bits; + inext = 1; + } else { + ASN__ENCODE_FAILED; + } + } + } else { + inext = 0; + } + + if(ct_extensible) { /* Declare whether length is [not] within extension root */ if(per_put_few_bits(po, inext, 1)) ASN__ENCODE_FAILED; } - /* X.691, #16.5: zero-length encoding */ - /* X.691, #16.6: short fixed length encoding (up to 2 octets) */ - /* X.691, #16.7: long fixed length encoding (up to 64K octets) */ - if(csiz->effective_bits >= 0) { - ASN_DEBUG("Encoding %d bytes (%ld), length in %d bits", - st->size, sizeinunits - csiz->lower_bound, - csiz->effective_bits); - ret = per_put_few_bits(po, sizeinunits - csiz->lower_bound, - csiz->effective_bits); - if(ret) ASN__ENCODE_FAILED; - if(bpc) { - ret = OCTET_STRING_per_put_characters(po, st->buf, - sizeinunits, bpc, unit_bits, - cval->lower_bound, cval->upper_bound, pc); - } else { - ret = per_put_many_bits(po, st->buf, - sizeinunits * unit_bits); - } - if(ret) ASN__ENCODE_FAILED; - ASN__ENCODED_OK(er); - } - - ASN_DEBUG("Encoding %d bytes", st->size); - - if(sizeinunits == 0) { - if(uper_put_length(po, 0)) - ASN__ENCODE_FAILED; - ASN__ENCODED_OK(er); - } - - buf = st->buf; - while(sizeinunits) { - ssize_t maySave = uper_put_length(po, sizeinunits); - if(maySave < 0) ASN__ENCODE_FAILED; - - ASN_DEBUG("Encoding %ld of %ld", - (long)maySave, (long)sizeinunits); - - if(bpc) { - ret = OCTET_STRING_per_put_characters(po, buf, - maySave, bpc, unit_bits, - cval->lower_bound, cval->upper_bound, pc); - } else { - ret = per_put_many_bits(po, buf, maySave * unit_bits); - } - if(ret) ASN__ENCODE_FAILED; - - if(bpc) - buf += maySave * bpc; - else - buf += maySave >> 3; - sizeinunits -= maySave; - assert(!(maySave & 0x07) || !sizeinunits); - } - - ASN__ENCODED_OK(er); + if(csiz->effective_bits >= 0 && !inext) { + ASN_DEBUG("Encoding %" ASN_PRI_SIZE " bytes (%ld), length in %d bits", st->size, + size_in_units - csiz->lower_bound, csiz->effective_bits); + ret = per_put_few_bits(po, size_in_units - csiz->lower_bound, + csiz->effective_bits); + if(ret) ASN__ENCODE_FAILED; + ret = OCTET_STRING_per_put_characters(po, st->buf, size_in_units, bpc, + unit_bits, cval->lower_bound, + cval->upper_bound, pc); + if(ret) ASN__ENCODE_FAILED; + ASN__ENCODED_OK(er); + } + + ASN_DEBUG("Encoding %" ASN_PRI_SIZE " bytes", st->size); + + buf = st->buf; + ASN_DEBUG("Encoding %" ASN_PRI_SIZE " in units", size_in_units); + do { + int need_eom = 0; + ssize_t may_save = uper_put_length(po, size_in_units, &need_eom); + if(may_save < 0) ASN__ENCODE_FAILED; + + ASN_DEBUG("Encoding %" ASN_PRI_SSIZE " of %" ASN_PRI_SIZE "%s", may_save, size_in_units, + need_eom ? ",+EOM" : ""); + + ret = OCTET_STRING_per_put_characters(po, buf, may_save, bpc, unit_bits, + cval->lower_bound, + cval->upper_bound, pc); + if(ret) ASN__ENCODE_FAILED; + + buf += may_save * bpc; + size_in_units -= may_save; + assert(!(may_save & 0x07) || !size_in_units); + if(need_eom && uper_put_length(po, 0, 0)) + ASN__ENCODE_FAILED; /* End of Message length */ + } while(size_in_units); + + ASN__ENCODED_OK(er); } +#endif /* ASN_DISABLE_PER_SUPPORT */ + int -OCTET_STRING_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel, - asn_app_consume_bytes_f *cb, void *app_key) { - const char * const h2c = "0123456789ABCDEF"; +OCTET_STRING_print(const asn_TYPE_descriptor_t *td, const void *sptr, + int ilevel, asn_app_consume_bytes_f *cb, void *app_key) { + const char * const h2c = "0123456789ABCDEF"; const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr; char scratch[16 * 3 + 4]; char *p = scratch; @@ -1695,9 +1688,10 @@ OCTET_STRING_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel, } int -OCTET_STRING_print_utf8(asn_TYPE_descriptor_t *td, const void *sptr, - int ilevel, asn_app_consume_bytes_f *cb, void *app_key) { - const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr; +OCTET_STRING_print_utf8(const asn_TYPE_descriptor_t *td, const void *sptr, + int ilevel, asn_app_consume_bytes_f *cb, + void *app_key) { + const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr; (void)td; /* Unused argument */ (void)ilevel; /* Unused argument */ @@ -1710,9 +1704,10 @@ OCTET_STRING_print_utf8(asn_TYPE_descriptor_t *td, const void *sptr, } void -OCTET_STRING_free(asn_TYPE_descriptor_t *td, void *sptr, int contents_only) { +OCTET_STRING_free(const asn_TYPE_descriptor_t *td, void *sptr, + enum asn_struct_free_method method) { OCTET_STRING_t *st = (OCTET_STRING_t *)sptr; - asn_OCTET_STRING_specifics_t *specs; + const asn_OCTET_STRING_specifics_t *specs; asn_struct_ctx_t *ctx; struct _stack *stck; @@ -1720,8 +1715,8 @@ OCTET_STRING_free(asn_TYPE_descriptor_t *td, void *sptr, int contents_only) { return; specs = td->specifics - ? (asn_OCTET_STRING_specifics_t *)td->specifics - : &asn_DEF_OCTET_STRING_specs; + ? (const asn_OCTET_STRING_specifics_t *)td->specifics + : &asn_SPC_OCTET_STRING_specs; ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset); ASN_DEBUG("Freeing %s as OCTET STRING", td->name); @@ -1744,9 +1739,20 @@ OCTET_STRING_free(asn_TYPE_descriptor_t *td, void *sptr, int contents_only) { FREEMEM(stck); } - if(!contents_only) { - FREEMEM(st); - } + switch(method) { + case ASFM_FREE_EVERYTHING: + FREEMEM(sptr); + break; + case ASFM_FREE_UNDERLYING: + break; + case ASFM_FREE_UNDERLYING_AND_RESET: + memset(sptr, 0, + td->specifics + ? ((const asn_OCTET_STRING_specifics_t *)(td->specifics)) + ->struct_size + : sizeof(OCTET_STRING_t)); + break; + } } /* @@ -1790,11 +1796,12 @@ OCTET_STRING_fromBuf(OCTET_STRING_t *st, const char *str, int len) { } OCTET_STRING_t * -OCTET_STRING_new_fromBuf(asn_TYPE_descriptor_t *td, const char *str, int len) { - asn_OCTET_STRING_specifics_t *specs = td->specifics - ? (asn_OCTET_STRING_specifics_t *)td->specifics - : &asn_DEF_OCTET_STRING_specs; - OCTET_STRING_t *st; +OCTET_STRING_new_fromBuf(const asn_TYPE_descriptor_t *td, const char *str, + int len) { + const asn_OCTET_STRING_specifics_t *specs = + td->specifics ? (const asn_OCTET_STRING_specifics_t *)td->specifics + : &asn_SPC_OCTET_STRING_specs; + OCTET_STRING_t *st; st = (OCTET_STRING_t *)CALLOC(1, specs->struct_size); if(st && str && OCTET_STRING_fromBuf(st, str, len)) { @@ -1805,3 +1812,232 @@ OCTET_STRING_new_fromBuf(asn_TYPE_descriptor_t *td, const char *str, int len) { return st; } +/* + * Lexicographically compare the common prefix of both strings, + * and if it is the same return -1 for the smallest string. + */ +int +OCTET_STRING_compare(const asn_TYPE_descriptor_t *td, const void *aptr, + const void *bptr) { + const asn_OCTET_STRING_specifics_t *specs = td->specifics; + const OCTET_STRING_t *a = aptr; + const OCTET_STRING_t *b = bptr; + + assert(!specs || specs->subvariant != ASN_OSUBV_BIT); + + if(a && b) { + size_t common_prefix_size = a->size <= b->size ? a->size : b->size; + int ret = memcmp(a->buf, b->buf, common_prefix_size); + if(ret == 0) { + /* Figure out which string with equal prefixes is longer. */ + if(a->size < b->size) { + return -1; + } else if(a->size > b->size) { + return 1; + } else { + return 0; + } + } else { + return ret < 0 ? -1 : 1; + } + } else if(!a && !b) { + return 0; + } else if(!a) { + return -1; + } else { + return 1; + } + +} + +/* + * Biased function for randomizing character values around their limits. + */ +static uint32_t +OCTET_STRING__random_char(unsigned long lb, unsigned long ub) { + assert(lb <= ub); + switch(asn_random_between(0, 16)) { + case 0: + if(lb < ub) return lb + 1; + /* Fall through */ + case 1: + return lb; + case 2: + if(lb < ub) return ub - 1; + /* Fall through */ + case 3: + return ub; + default: + return asn_random_between(lb, ub); + } +} + + +size_t +OCTET_STRING_random_length_constrained( + const asn_TYPE_descriptor_t *td, + const asn_encoding_constraints_t *constraints, size_t max_length) { + const unsigned lengths[] = {0, 1, 2, 3, 4, 8, + 126, 127, 128, 16383, 16384, 16385, + 65534, 65535, 65536, 65537}; + size_t rnd_len; + + /* Figure out how far we should go */ + rnd_len = lengths[asn_random_between( + 0, sizeof(lengths) / sizeof(lengths[0]) - 1)]; + + if(!constraints || !constraints->per_constraints) + constraints = &td->encoding_constraints; + if(constraints->per_constraints) { + const asn_per_constraint_t *pc = &constraints->per_constraints->size; + if(pc->flags & APC_CONSTRAINED) { + long suggested_upper_bound = pc->upper_bound < (ssize_t)max_length + ? pc->upper_bound + : (ssize_t)max_length; + if(max_length <= (size_t)pc->lower_bound) { + return pc->lower_bound; + } + if(pc->flags & APC_EXTENSIBLE) { + switch(asn_random_between(0, 5)) { + case 0: + if(pc->lower_bound > 0) { + rnd_len = pc->lower_bound - 1; + break; + } + /* Fall through */ + case 1: + rnd_len = pc->upper_bound + 1; + break; + case 2: + /* Keep rnd_len from the table */ + if(rnd_len <= max_length) { + break; + } + /* Fall through */ + default: + rnd_len = asn_random_between(pc->lower_bound, + suggested_upper_bound); + } + } else { + rnd_len = + asn_random_between(pc->lower_bound, suggested_upper_bound); + } + } else { + rnd_len = asn_random_between(0, max_length); + } + } else if(rnd_len > max_length) { + rnd_len = asn_random_between(0, max_length); + } + + return rnd_len; +} + +asn_random_fill_result_t +OCTET_STRING_random_fill(const asn_TYPE_descriptor_t *td, void **sptr, + const asn_encoding_constraints_t *constraints, + size_t max_length) { + const asn_OCTET_STRING_specifics_t *specs = td->specifics + ? (const asn_OCTET_STRING_specifics_t *)td->specifics + : &asn_SPC_OCTET_STRING_specs; + asn_random_fill_result_t result_ok = {ARFILL_OK, 1}; + asn_random_fill_result_t result_failed = {ARFILL_FAILED, 0}; + asn_random_fill_result_t result_skipped = {ARFILL_SKIPPED, 0}; + unsigned int unit_bytes = 1; + unsigned long clb = 0; /* Lower bound on char */ + unsigned long cub = 255; /* Higher bound on char value */ + uint8_t *buf; + uint8_t *bend; + uint8_t *b; + size_t rnd_len; + OCTET_STRING_t *st; + + if(max_length == 0 && !*sptr) return result_skipped; + + switch(specs->subvariant) { + default: + case ASN_OSUBV_ANY: + return result_failed; + case ASN_OSUBV_BIT: + /* Handled by BIT_STRING itself. */ + return result_failed; + case ASN_OSUBV_STR: + unit_bytes = 1; + clb = 0; + cub = 255; + break; + case ASN_OSUBV_U16: + unit_bytes = 2; + clb = 0; + cub = 65535; + break; + case ASN_OSUBV_U32: + unit_bytes = 4; + clb = 0; + cub = 0x10FFFF; + break; + } + + if(!constraints || !constraints->per_constraints) + constraints = &td->encoding_constraints; + if(constraints->per_constraints) { + const asn_per_constraint_t *pc = &constraints->per_constraints->value; + if(pc->flags & APC_SEMI_CONSTRAINED) { + clb = pc->lower_bound; + } else if(pc->flags & APC_CONSTRAINED) { + clb = pc->lower_bound; + cub = pc->upper_bound; + } + } + + rnd_len = + OCTET_STRING_random_length_constrained(td, constraints, max_length); + + buf = CALLOC(unit_bytes, rnd_len + 1); + if(!buf) return result_failed; + + bend = &buf[unit_bytes * rnd_len]; + + switch(unit_bytes) { + case 1: + for(b = buf; b < bend; b += unit_bytes) { + *(uint8_t *)b = OCTET_STRING__random_char(clb, cub); + } + *(uint8_t *)b = 0; + break; + case 2: + for(b = buf; b < bend; b += unit_bytes) { + uint32_t code = OCTET_STRING__random_char(clb, cub); + b[0] = code >> 8; + b[1] = code; + } + *(uint16_t *)b = 0; + break; + case 4: + for(b = buf; b < bend; b += unit_bytes) { + uint32_t code = OCTET_STRING__random_char(clb, cub); + b[0] = code >> 24; + b[1] = code >> 16; + b[2] = code >> 8; + b[3] = code; + } + *(uint32_t *)b = 0; + break; + } + + if(*sptr) { + st = *sptr; + FREEMEM(st->buf); + } else { + st = (OCTET_STRING_t *)(*sptr = CALLOC(1, specs->struct_size)); + if(!st) { + FREEMEM(buf); + return result_failed; + } + } + + st->buf = buf; + st->size = unit_bytes * rnd_len; + + result_ok.length = st->size; + return result_ok; +} diff --git a/libs/smux/OCTET_STRING_oer.c b/libs/smux/OCTET_STRING_oer.c new file mode 100644 index 00000000..c16faeaf --- /dev/null +++ b/libs/smux/OCTET_STRING_oer.c @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2017 Lev Walkin . + * All rights reserved. + * Redistribution and modifications are permitted subject to BSD license. + */ +#ifndef ASN_DISABLE_OER_SUPPORT + +#include +#include +#include + +asn_dec_rval_t +OCTET_STRING_decode_oer(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *td, + const asn_oer_constraints_t *constraints, void **sptr, + const void *ptr, size_t size) { + const asn_OCTET_STRING_specifics_t *specs = + td->specifics ? (const asn_OCTET_STRING_specifics_t *)td->specifics + : &asn_SPC_OCTET_STRING_specs; + OCTET_STRING_t *st = (OCTET_STRING_t *)*sptr; + const asn_oer_constraints_t *cts = + constraints ? constraints : td->encoding_constraints.oer_constraints; + ssize_t ct_size = cts ? cts->size : -1; + asn_dec_rval_t rval = {RC_OK, 0}; + size_t expected_length = 0; + + size_t unit_bytes; + switch(specs->subvariant) { + default: + case ASN_OSUBV_BIT: + ASN_DEBUG("Invalid use of OCTET STRING to decode BIT STRING"); + ASN__DECODE_FAILED; + case ASN_OSUBV_ANY: + /* Fall through */ + case ASN_OSUBV_STR: + unit_bytes = 1; + break; + case ASN_OSUBV_U16: + unit_bytes = 2; + break; + case ASN_OSUBV_U32: + unit_bytes = 4; + break; + } + + (void)opt_codec_ctx; + + if(!st) { + st = (OCTET_STRING_t *)(*sptr = CALLOC(1, specs->struct_size)); + if(!st) ASN__DECODE_FAILED; + } + + if(ct_size >= 0) { + expected_length = unit_bytes * ct_size; + } else { + /* + * X.696 (08/2015) #27.2 + * Encode length determinant as _number of octets_, but only + * if upper bound is not equal to lower bound. + */ + ssize_t len_len = oer_fetch_length(ptr, size, &expected_length); + if(len_len > 0) { + rval.consumed = len_len; + ptr = (const char *)ptr + len_len; + size -= len_len; + } else if(len_len == 0) { + ASN__DECODE_STARVED; + } else if(len_len < 0) { + ASN__DECODE_FAILED; + } + + if(expected_length % unit_bytes != 0) { + ASN_DEBUG( + "Data size %" ASN_PRI_SIZE " bytes is not consistent with multiplier %" ASN_PRI_SIZE "", + expected_length, unit_bytes); + ASN__DECODE_FAILED; + } + } + + if(size < expected_length) { + ASN__DECODE_STARVED; + } else { + uint8_t *buf = MALLOC(expected_length + 1); + if(buf == NULL) { + ASN__DECODE_FAILED; + } else { + memcpy(buf, ptr, expected_length); + buf[expected_length] = '\0'; + } + FREEMEM(st->buf); + st->buf = buf; + st->size = expected_length; + + rval.consumed += expected_length; + return rval; + } +} + +/* + * Encode as Canonical OER. + */ +asn_enc_rval_t +OCTET_STRING_encode_oer(const asn_TYPE_descriptor_t *td, + const asn_oer_constraints_t *constraints, + const void *sptr, asn_app_consume_bytes_f *cb, + void *app_key) { + const asn_OCTET_STRING_specifics_t *specs = + td->specifics ? (const asn_OCTET_STRING_specifics_t *)td->specifics + : &asn_SPC_OCTET_STRING_specs; + const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr; + const asn_oer_constraints_t *cts = + constraints ? constraints : td->encoding_constraints.oer_constraints; + ssize_t ct_size = cts ? cts->size : -1; + asn_enc_rval_t er = {0, 0, 0}; + + if(!st) ASN__ENCODE_FAILED; + + ASN_DEBUG("Encoding %s %" ASN_PRI_SIZE " as OCTET STRING", td ? td->name : "", st->size); + + if(ct_size >= 0) { + /* + * Check that available data matches the constraint + */ + size_t unit_bytes; + switch(specs->subvariant) { + default: + case ASN_OSUBV_BIT: + ASN_DEBUG("Invalid use of OCTET STRING to encode BIT STRING"); + ASN__ENCODE_FAILED; + case ASN_OSUBV_ANY: + /* Fall through */ + case ASN_OSUBV_STR: + unit_bytes = 1; + break; + case ASN_OSUBV_U16: + unit_bytes = 2; + break; + case ASN_OSUBV_U32: + unit_bytes = 4; + break; + } + + if(st->size != unit_bytes * (size_t)ct_size) { + ASN_DEBUG( + "Trying to encode %s (%" ASN_PRI_SIZE " bytes) which doesn't fit SIZE " + "constraint (%" ASN_PRI_SIZE ")", + td->name, st->size, ct_size); + ASN__ENCODE_FAILED; + } + } else { + /* + * X.696 (08/2015) #27.2 + * Encode length determinant as _number of octets_, but only + * if upper bound is not equal to lower bound. + */ + ssize_t ret = oer_serialize_length(st->size, cb, app_key); + if(ret < 0) { + ASN__ENCODE_FAILED; + } + er.encoded += ret; + } + + er.encoded += st->size; + if(cb(st->buf, st->size, app_key) < 0) { + ASN__ENCODE_FAILED; + } else { + ASN__ENCODED_OK(er); + } +} + +#endif /* ASN_DISABLE_OER_SUPPORT */ diff --git a/libs/smux/OPEN_TYPE.c b/libs/smux/OPEN_TYPE.c new file mode 100644 index 00000000..c672992c --- /dev/null +++ b/libs/smux/OPEN_TYPE.c @@ -0,0 +1,402 @@ +/* + * Copyright (c) 2017 Lev Walkin . All rights reserved. + * Redistribution and modifications are permitted subject to BSD license. + */ +#include +#include +#include +#include +#include + +asn_TYPE_operation_t asn_OP_OPEN_TYPE = { + OPEN_TYPE_free, + OPEN_TYPE_print, + OPEN_TYPE_compare, + OPEN_TYPE_decode_ber, + OPEN_TYPE_encode_der, + OPEN_TYPE_decode_xer, + OPEN_TYPE_encode_xer, + 0, 0, /* No OER support, use "-gen-OER" to enable */ +#ifdef ASN_DISABLE_PER_SUPPORT + 0, 0, +#else + OPEN_TYPE_decode_uper, + OPEN_TYPE_encode_uper, +#endif + 0, /* Random fill is not supported for open type */ + 0, /* Use generic outmost tag fetcher */ +}; + +#undef ADVANCE +#define ADVANCE(num_bytes) \ + do { \ + size_t num = num_bytes; \ + ptr = ((const char *)ptr) + num; \ + size -= num; \ + consumed_myself += num; \ + } while(0) + +asn_dec_rval_t +OPEN_TYPE_ber_get(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *td, void *sptr, + const asn_TYPE_member_t *elm, const void *ptr, size_t size) { + size_t consumed_myself = 0; + asn_type_selector_result_t selected; + void *memb_ptr; /* Pointer to the member */ + void **memb_ptr2; /* Pointer to that pointer */ + void *inner_value; + asn_dec_rval_t rv; + + if(!(elm->flags & ATF_OPEN_TYPE)) { + ASN__DECODE_FAILED; + } + + if(!elm->type_selector) { + ASN_DEBUG("Type selector is not defined for Open Type %s->%s->%s", + td->name, elm->name, elm->type->name); + ASN__DECODE_FAILED; + } + + selected = elm->type_selector(td, sptr); + if(!selected.presence_index) { + ASN__DECODE_FAILED; + } + + /* Fetch the pointer to this member */ + if(elm->flags & ATF_POINTER) { + memb_ptr2 = (void **)((char *)sptr + elm->memb_offset); + } else { + memb_ptr = (char *)sptr + elm->memb_offset; + memb_ptr2 = &memb_ptr; + } + if(*memb_ptr2 != NULL) { + /* Make sure we reset the structure first before encoding */ + if(CHOICE_variant_set_presence(elm->type, *memb_ptr2, 0) != 0) { + ASN__DECODE_FAILED; + } + } + + inner_value = + (char *)*memb_ptr2 + + elm->type->elements[selected.presence_index - 1].memb_offset; + + ASN_DEBUG("presence %d\n", selected.presence_index); + + rv = selected.type_descriptor->op->ber_decoder( + opt_codec_ctx, selected.type_descriptor, &inner_value, ptr, size, + elm->tag_mode); + ADVANCE(rv.consumed); + rv.consumed = 0; + switch(rv.code) { + case RC_OK: + if(CHOICE_variant_set_presence(elm->type, *memb_ptr2, + selected.presence_index) + == 0) { + rv.code = RC_OK; + rv.consumed = consumed_myself; + return rv; + } else { + /* Oh, now a full-blown failure failure */ + } + /* Fall through */ + case RC_FAIL: + rv.consumed = consumed_myself; + /* Fall through */ + case RC_WMORE: + break; + } + + if(*memb_ptr2) { + const asn_CHOICE_specifics_t *specs = + selected.type_descriptor->specifics; + if(elm->flags & ATF_POINTER) { + ASN_STRUCT_FREE(*selected.type_descriptor, inner_value); + *memb_ptr2 = NULL; + } else { + ASN_STRUCT_FREE_CONTENTS_ONLY(*selected.type_descriptor, + inner_value); + memset(*memb_ptr2, 0, specs->struct_size); + } + } + return rv; +} + +asn_dec_rval_t +OPEN_TYPE_xer_get(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *td, void *sptr, + const asn_TYPE_member_t *elm, const void *ptr, size_t size) { + size_t consumed_myself = 0; + asn_type_selector_result_t selected; + void *memb_ptr; /* Pointer to the member */ + void **memb_ptr2; /* Pointer to that pointer */ + void *inner_value; + asn_dec_rval_t rv; + + int xer_context = 0; + ssize_t ch_size; + pxer_chunk_type_e ch_type; + + if(!(elm->flags & ATF_OPEN_TYPE)) { + ASN__DECODE_FAILED; + } + + if(!elm->type_selector) { + ASN_DEBUG("Type selector is not defined for Open Type %s->%s->%s", + td->name, elm->name, elm->type->name); + ASN__DECODE_FAILED; + } + + selected = elm->type_selector(td, sptr); + if(!selected.presence_index) { + ASN__DECODE_FAILED; + } + + /* Fetch the pointer to this member */ + assert(elm->flags == ATF_OPEN_TYPE); + if(elm->flags & ATF_POINTER) { + memb_ptr2 = (void **)((char *)sptr + elm->memb_offset); + } else { + memb_ptr = (char *)sptr + elm->memb_offset; + memb_ptr2 = &memb_ptr; + } + if(*memb_ptr2 != NULL) { + /* Make sure we reset the structure first before encoding */ + if(CHOICE_variant_set_presence(elm->type, *memb_ptr2, 0) + != 0) { + ASN__DECODE_FAILED; + } + } + + /* + * Confirm wrapper. + */ + for(;;) { + ch_size = xer_next_token(&xer_context, ptr, size, &ch_type); + if(ch_size < 0) { + ASN__DECODE_FAILED; + } else { + switch(ch_type) { + case PXER_WMORE: + ASN__DECODE_STARVED; + case PXER_COMMENT: + case PXER_TEXT: + ADVANCE(ch_size); + continue; + case PXER_TAG: + break; + } + break; + } + } + + /* + * Wrapper value confirmed. + */ + switch(xer_check_tag(ptr, ch_size, elm->name)) { + case XCT_OPENING: + ADVANCE(ch_size); + break; + case XCT_BROKEN: + default: + ASN__DECODE_FAILED; + } + + inner_value = + (char *)*memb_ptr2 + + elm->type->elements[selected.presence_index - 1].memb_offset; + + rv = selected.type_descriptor->op->xer_decoder( + opt_codec_ctx, selected.type_descriptor, &inner_value, NULL, ptr, size); + ADVANCE(rv.consumed); + rv.consumed = 0; + switch(rv.code) { + case RC_OK: + if(CHOICE_variant_set_presence(elm->type, *memb_ptr2, + selected.presence_index) + == 0) { + break; + } else { + rv.code = RC_FAIL; + } + /* Fall through */ + case RC_FAIL: + /* Point to a best position where failure occurred */ + rv.consumed = consumed_myself; + /* Fall through */ + case RC_WMORE: + /* Wrt. rv.consumed==0: + * In case a genuine RC_WMORE, the whole Open Type decoding + * will have to be restarted. + */ + if(*memb_ptr2) { + const asn_CHOICE_specifics_t *specs = + selected.type_descriptor->specifics; + if(elm->flags & ATF_POINTER) { + ASN_STRUCT_FREE(*selected.type_descriptor, inner_value); + *memb_ptr2 = NULL; + } else { + ASN_STRUCT_FREE_CONTENTS_ONLY(*selected.type_descriptor, + inner_value); + memset(*memb_ptr2, 0, specs->struct_size); + } + } + return rv; + } + + /* + * Finalize wrapper. + */ + for(;;) { + ch_size = xer_next_token(&xer_context, ptr, size, &ch_type); + if(ch_size < 0) { + ASN__DECODE_FAILED; + } else { + switch(ch_type) { + case PXER_WMORE: + ASN__DECODE_STARVED; + case PXER_COMMENT: + case PXER_TEXT: + ADVANCE(ch_size); + continue; + case PXER_TAG: + break; + } + break; + } + } + + /* + * Wrapper value confirmed. + */ + switch(xer_check_tag(ptr, ch_size, elm->name)) { + case XCT_CLOSING: + ADVANCE(ch_size); + break; + case XCT_BROKEN: + default: + ASN__DECODE_FAILED; + } + + rv.consumed += consumed_myself; + + return rv; +} + + +#ifndef ASN_DISABLE_PER_SUPPORT + +asn_dec_rval_t +OPEN_TYPE_uper_get(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *td, void *sptr, + const asn_TYPE_member_t *elm, asn_per_data_t *pd) { + asn_type_selector_result_t selected; + void *memb_ptr; /* Pointer to the member */ + void **memb_ptr2; /* Pointer to that pointer */ + void *inner_value; + asn_dec_rval_t rv; + + if(!(elm->flags & ATF_OPEN_TYPE)) { + ASN__DECODE_FAILED; + } + + if(!elm->type_selector) { + ASN_DEBUG("Type selector is not defined for Open Type %s->%s->%s", + td->name, elm->name, elm->type->name); + ASN__DECODE_FAILED; + } + + selected = elm->type_selector(td, sptr); + if(!selected.presence_index) { + ASN__DECODE_FAILED; + } + + /* Fetch the pointer to this member */ + assert(elm->flags == ATF_OPEN_TYPE); + if(elm->flags & ATF_POINTER) { + memb_ptr2 = (void **)((char *)sptr + elm->memb_offset); + } else { + memb_ptr = (char *)sptr + elm->memb_offset; + memb_ptr2 = &memb_ptr; + } + if(*memb_ptr2 != NULL) { + /* Make sure we reset the structure first before encoding */ + if(CHOICE_variant_set_presence(elm->type, *memb_ptr2, 0) + != 0) { + ASN__DECODE_FAILED; + } + } + + inner_value = + (char *)*memb_ptr2 + + elm->type->elements[selected.presence_index - 1].memb_offset; + + rv = uper_open_type_get(opt_codec_ctx, selected.type_descriptor, NULL, + &inner_value, pd); + switch(rv.code) { + case RC_OK: + if(CHOICE_variant_set_presence(elm->type, *memb_ptr2, + selected.presence_index) + == 0) { + break; + } else { + rv.code = RC_FAIL; + } + /* Fall through */ + case RC_WMORE: + case RC_FAIL: + if(*memb_ptr2) { + const asn_CHOICE_specifics_t *specs = + selected.type_descriptor->specifics; + if(elm->flags & ATF_POINTER) { + ASN_STRUCT_FREE(*selected.type_descriptor, inner_value); + *memb_ptr2 = NULL; + } else { + ASN_STRUCT_FREE_CONTENTS_ONLY(*selected.type_descriptor, + inner_value); + memset(*memb_ptr2, 0, specs->struct_size); + } + } + } + return rv; +} + +asn_enc_rval_t +OPEN_TYPE_encode_uper(const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, + const void *sptr, asn_per_outp_t *po) { + const void *memb_ptr; /* Pointer to the member */ + asn_TYPE_member_t *elm; /* CHOICE's element */ + asn_enc_rval_t er; + unsigned present; + + (void)constraints; + + present = CHOICE_variant_get_presence(td, sptr); + if(present == 0 || present > td->elements_count) { + ASN__ENCODE_FAILED; + } else { + present--; + } + + ASN_DEBUG("Encoding %s OPEN TYPE element %d", td->name, present); + + elm = &td->elements[present]; + if(elm->flags & ATF_POINTER) { + /* Member is a pointer to another structure */ + memb_ptr = + *(const void *const *)((const char *)sptr + elm->memb_offset); + if(!memb_ptr) ASN__ENCODE_FAILED; + } else { + memb_ptr = (const char *)sptr + elm->memb_offset; + } + + if(uper_open_type_put(elm->type, NULL, memb_ptr, po) < 0) { + ASN__ENCODE_FAILED; + } + + er.encoded = 0; + ASN__ENCODED_OK(er); +} + + +#endif /* ASN_DISABLE_PER_SUPPORT */ diff --git a/libs/smux/OPEN_TYPE_oer.c b/libs/smux/OPEN_TYPE_oer.c new file mode 100644 index 00000000..dd2f5c64 --- /dev/null +++ b/libs/smux/OPEN_TYPE_oer.c @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2017 Lev Walkin . All rights reserved. + * Redistribution and modifications are permitted subject to BSD license. + */ +#include +#include +#include +#include + +asn_dec_rval_t +OPEN_TYPE_oer_get(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *td, void *sptr, + asn_TYPE_member_t *elm, const void *ptr, size_t size) { + asn_type_selector_result_t selected; + void *memb_ptr; /* Pointer to the member */ + void **memb_ptr2; /* Pointer to that pointer */ + void *inner_value; + asn_dec_rval_t rv; + size_t ot_ret; + + + if(!(elm->flags & ATF_OPEN_TYPE)) { + ASN__DECODE_FAILED; + } + + if(!elm->type_selector) { + ASN_DEBUG("Type selector is not defined for Open Type %s->%s->%s", + td->name, elm->name, elm->type->name); + ASN__DECODE_FAILED; + } + + selected = elm->type_selector(td, sptr); + if(!selected.presence_index) { + ASN__DECODE_FAILED; + } + + /* Fetch the pointer to this member */ + if(elm->flags & ATF_POINTER) { + memb_ptr2 = (void **)((char *)sptr + elm->memb_offset); + } else { + memb_ptr = (char *)sptr + elm->memb_offset; + memb_ptr2 = &memb_ptr; + } + if(*memb_ptr2 != NULL) { + /* Make sure we reset the structure first before encoding */ + if(CHOICE_variant_set_presence(elm->type, *memb_ptr2, 0) != 0) { + ASN__DECODE_FAILED; + } + } + + inner_value = + (char *)*memb_ptr2 + + elm->type->elements[selected.presence_index - 1].memb_offset; + + ot_ret = oer_open_type_get(opt_codec_ctx, selected.type_descriptor, NULL, + &inner_value, ptr, size); + switch(ot_ret) { + default: + if(CHOICE_variant_set_presence(elm->type, *memb_ptr2, + selected.presence_index) + == 0) { + rv.code = RC_OK; + rv.consumed = ot_ret; + return rv; + } else { + /* Oh, now a full-blown failure failure */ + } + /* Fall through */ + case -1: + rv.code = RC_FAIL; + rv.consumed = ot_ret; + break; + case 0: + rv.code = RC_WMORE; + rv.consumed = 0; + break; + } + + if(*memb_ptr2) { + const asn_CHOICE_specifics_t *specs = + selected.type_descriptor->specifics; + if(elm->flags & ATF_POINTER) { + ASN_STRUCT_FREE(*selected.type_descriptor, inner_value); + *memb_ptr2 = NULL; + } else { + ASN_STRUCT_FREE_CONTENTS_ONLY(*selected.type_descriptor, + inner_value); + memset(*memb_ptr2, 0, specs->struct_size); + } + } + return rv; +} diff --git a/libs/smux/ObjectName.c b/libs/smux/ObjectName.c index 5b059007..96917a87 100644 --- a/libs/smux/ObjectName.c +++ b/libs/smux/ObjectName.c @@ -1,108 +1,30 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1155-SMI" * found in "RFC1155-SMI.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #include "ObjectName.h" -int -ObjectName_constraint(asn_TYPE_descriptor_t *td, const void *sptr, - asn_app_constraint_failed_f *ctfailcb, void *app_key) { - /* Replace with underlying type checker */ - td->check_constraints = asn_DEF_OBJECT_IDENTIFIER.check_constraints; - return td->check_constraints(td, sptr, ctfailcb, app_key); -} - /* * This type is implemented using OBJECT_IDENTIFIER, * so here we adjust the DEF accordingly. */ -static void -ObjectName_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) { - td->free_struct = asn_DEF_OBJECT_IDENTIFIER.free_struct; - td->print_struct = asn_DEF_OBJECT_IDENTIFIER.print_struct; - td->check_constraints = asn_DEF_OBJECT_IDENTIFIER.check_constraints; - td->ber_decoder = asn_DEF_OBJECT_IDENTIFIER.ber_decoder; - td->der_encoder = asn_DEF_OBJECT_IDENTIFIER.der_encoder; - td->xer_decoder = asn_DEF_OBJECT_IDENTIFIER.xer_decoder; - td->xer_encoder = asn_DEF_OBJECT_IDENTIFIER.xer_encoder; - td->uper_decoder = asn_DEF_OBJECT_IDENTIFIER.uper_decoder; - td->uper_encoder = asn_DEF_OBJECT_IDENTIFIER.uper_encoder; - if(!td->per_constraints) - td->per_constraints = asn_DEF_OBJECT_IDENTIFIER.per_constraints; - td->elements = asn_DEF_OBJECT_IDENTIFIER.elements; - td->elements_count = asn_DEF_OBJECT_IDENTIFIER.elements_count; - td->specifics = asn_DEF_OBJECT_IDENTIFIER.specifics; -} - -void -ObjectName_free(asn_TYPE_descriptor_t *td, - void *struct_ptr, int contents_only) { - ObjectName_1_inherit_TYPE_descriptor(td); - td->free_struct(td, struct_ptr, contents_only); -} - -int -ObjectName_print(asn_TYPE_descriptor_t *td, const void *struct_ptr, - int ilevel, asn_app_consume_bytes_f *cb, void *app_key) { - ObjectName_1_inherit_TYPE_descriptor(td); - return td->print_struct(td, struct_ptr, ilevel, cb, app_key); -} - -asn_dec_rval_t -ObjectName_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, - void **structure, const void *bufptr, size_t size, int tag_mode) { - ObjectName_1_inherit_TYPE_descriptor(td); - return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode); -} - -asn_enc_rval_t -ObjectName_encode_der(asn_TYPE_descriptor_t *td, - void *structure, int tag_mode, ber_tlv_tag_t tag, - asn_app_consume_bytes_f *cb, void *app_key) { - ObjectName_1_inherit_TYPE_descriptor(td); - return td->der_encoder(td, structure, tag_mode, tag, cb, app_key); -} - -asn_dec_rval_t -ObjectName_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, - void **structure, const char *opt_mname, const void *bufptr, size_t size) { - ObjectName_1_inherit_TYPE_descriptor(td); - return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size); -} - -asn_enc_rval_t -ObjectName_encode_xer(asn_TYPE_descriptor_t *td, void *structure, - int ilevel, enum xer_encoder_flags_e flags, - asn_app_consume_bytes_f *cb, void *app_key) { - ObjectName_1_inherit_TYPE_descriptor(td); - return td->xer_encoder(td, structure, ilevel, flags, cb, app_key); -} - static const ber_tlv_tag_t asn_DEF_ObjectName_tags_1[] = { (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)) }; asn_TYPE_descriptor_t asn_DEF_ObjectName = { "ObjectName", "ObjectName", - ObjectName_free, - ObjectName_print, - ObjectName_constraint, - ObjectName_decode_ber, - ObjectName_encode_der, - ObjectName_decode_xer, - ObjectName_encode_xer, - 0, 0, /* No PER support, use "-gen-PER" to enable */ - 0, /* Use generic outmost tag fetcher */ + &asn_OP_OBJECT_IDENTIFIER, asn_DEF_ObjectName_tags_1, sizeof(asn_DEF_ObjectName_tags_1) /sizeof(asn_DEF_ObjectName_tags_1[0]), /* 1 */ asn_DEF_ObjectName_tags_1, /* Same as above */ sizeof(asn_DEF_ObjectName_tags_1) /sizeof(asn_DEF_ObjectName_tags_1[0]), /* 1 */ - 0, /* No PER visible constraints */ + { 0, 0, OBJECT_IDENTIFIER_constraint }, 0, 0, /* No members */ 0 /* No specifics */ }; diff --git a/libs/smux/ObjectSyntax.c b/libs/smux/ObjectSyntax.c index 1e5c6350..6b0cd24f 100644 --- a/libs/smux/ObjectSyntax.c +++ b/libs/smux/ObjectSyntax.c @@ -1,29 +1,37 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1155-SMI" * found in "RFC1155-SMI.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #include "ObjectSyntax.h" -static asn_TYPE_member_t asn_MBR_ObjectSyntax_1[] = { +static asn_oer_constraints_t asn_OER_type_ObjectSyntax_constr_1 CC_NOTUSED = { + { 0, 0 }, + -1}; +asn_per_constraints_t asn_PER_type_ObjectSyntax_constr_1 CC_NOTUSED = { + { APC_CONSTRAINED, 1, 1, 0, 1 } /* (0..1) */, + { APC_UNCONSTRAINED, -1, -1, 0, 0 }, + 0, 0 /* No PER value map */ +}; +asn_TYPE_member_t asn_MBR_ObjectSyntax_1[] = { { ATF_NOFLAGS, 0, offsetof(struct ObjectSyntax, choice.simple), -1 /* Ambiguous tag (CHOICE?) */, 0, &asn_DEF_SimpleSyntax, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "simple" }, { ATF_NOFLAGS, 0, offsetof(struct ObjectSyntax, choice.application_wide), -1 /* Ambiguous tag (CHOICE?) */, 0, &asn_DEF_ApplicationSyntax, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "application-wide" }, }; @@ -38,33 +46,25 @@ static const asn_TYPE_tag2member_t asn_MAP_ObjectSyntax_tag2el_1[] = { { (ASN_TAG_CLASS_APPLICATION | (3 << 2)), 1, 0, 0 }, /* ticks */ { (ASN_TAG_CLASS_APPLICATION | (4 << 2)), 1, 0, 0 } /* arbitrary */ }; -static asn_CHOICE_specifics_t asn_SPC_ObjectSyntax_specs_1 = { +asn_CHOICE_specifics_t asn_SPC_ObjectSyntax_specs_1 = { sizeof(struct ObjectSyntax), offsetof(struct ObjectSyntax, _asn_ctx), offsetof(struct ObjectSyntax, present), sizeof(((struct ObjectSyntax *)0)->present), asn_MAP_ObjectSyntax_tag2el_1, 9, /* Count of tags in the map */ - 0, + 0, 0, -1 /* Extensions start */ }; asn_TYPE_descriptor_t asn_DEF_ObjectSyntax = { "ObjectSyntax", "ObjectSyntax", - CHOICE_free, - CHOICE_print, - CHOICE_constraint, - CHOICE_decode_ber, - CHOICE_encode_der, - CHOICE_decode_xer, - CHOICE_encode_xer, - 0, 0, /* No PER support, use "-gen-PER" to enable */ - CHOICE_outmost_tag, + &asn_OP_CHOICE, 0, /* No effective tags (pointer) */ 0, /* No effective tags (count) */ 0, /* No tags (pointer) */ 0, /* No tags (count) */ - 0, /* No PER visible constraints */ + { &asn_OER_type_ObjectSyntax_constr_1, &asn_PER_type_ObjectSyntax_constr_1, CHOICE_constraint }, asn_MBR_ObjectSyntax_1, 2, /* Elements count */ &asn_SPC_ObjectSyntax_specs_1 /* Additional specs */ diff --git a/libs/smux/Opaque.c b/libs/smux/Opaque.c index f9e6823c..07c608e8 100644 --- a/libs/smux/Opaque.c +++ b/libs/smux/Opaque.c @@ -1,86 +1,16 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1155-SMI" * found in "RFC1155-SMI.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #include "Opaque.h" -int -Opaque_constraint(asn_TYPE_descriptor_t *td, const void *sptr, - asn_app_constraint_failed_f *ctfailcb, void *app_key) { - /* Replace with underlying type checker */ - td->check_constraints = asn_DEF_OCTET_STRING.check_constraints; - return td->check_constraints(td, sptr, ctfailcb, app_key); -} - /* * This type is implemented using OCTET_STRING, * so here we adjust the DEF accordingly. */ -static void -Opaque_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) { - td->free_struct = asn_DEF_OCTET_STRING.free_struct; - td->print_struct = asn_DEF_OCTET_STRING.print_struct; - td->check_constraints = asn_DEF_OCTET_STRING.check_constraints; - td->ber_decoder = asn_DEF_OCTET_STRING.ber_decoder; - td->der_encoder = asn_DEF_OCTET_STRING.der_encoder; - td->xer_decoder = asn_DEF_OCTET_STRING.xer_decoder; - td->xer_encoder = asn_DEF_OCTET_STRING.xer_encoder; - td->uper_decoder = asn_DEF_OCTET_STRING.uper_decoder; - td->uper_encoder = asn_DEF_OCTET_STRING.uper_encoder; - if(!td->per_constraints) - td->per_constraints = asn_DEF_OCTET_STRING.per_constraints; - td->elements = asn_DEF_OCTET_STRING.elements; - td->elements_count = asn_DEF_OCTET_STRING.elements_count; - td->specifics = asn_DEF_OCTET_STRING.specifics; -} - -void -Opaque_free(asn_TYPE_descriptor_t *td, - void *struct_ptr, int contents_only) { - Opaque_1_inherit_TYPE_descriptor(td); - td->free_struct(td, struct_ptr, contents_only); -} - -int -Opaque_print(asn_TYPE_descriptor_t *td, const void *struct_ptr, - int ilevel, asn_app_consume_bytes_f *cb, void *app_key) { - Opaque_1_inherit_TYPE_descriptor(td); - return td->print_struct(td, struct_ptr, ilevel, cb, app_key); -} - -asn_dec_rval_t -Opaque_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, - void **structure, const void *bufptr, size_t size, int tag_mode) { - Opaque_1_inherit_TYPE_descriptor(td); - return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode); -} - -asn_enc_rval_t -Opaque_encode_der(asn_TYPE_descriptor_t *td, - void *structure, int tag_mode, ber_tlv_tag_t tag, - asn_app_consume_bytes_f *cb, void *app_key) { - Opaque_1_inherit_TYPE_descriptor(td); - return td->der_encoder(td, structure, tag_mode, tag, cb, app_key); -} - -asn_dec_rval_t -Opaque_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, - void **structure, const char *opt_mname, const void *bufptr, size_t size) { - Opaque_1_inherit_TYPE_descriptor(td); - return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size); -} - -asn_enc_rval_t -Opaque_encode_xer(asn_TYPE_descriptor_t *td, void *structure, - int ilevel, enum xer_encoder_flags_e flags, - asn_app_consume_bytes_f *cb, void *app_key) { - Opaque_1_inherit_TYPE_descriptor(td); - return td->xer_encoder(td, structure, ilevel, flags, cb, app_key); -} - static const ber_tlv_tag_t asn_DEF_Opaque_tags_1[] = { (ASN_TAG_CLASS_APPLICATION | (4 << 2)), (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)) @@ -88,23 +18,15 @@ static const ber_tlv_tag_t asn_DEF_Opaque_tags_1[] = { asn_TYPE_descriptor_t asn_DEF_Opaque = { "Opaque", "Opaque", - Opaque_free, - Opaque_print, - Opaque_constraint, - Opaque_decode_ber, - Opaque_encode_der, - Opaque_decode_xer, - Opaque_encode_xer, - 0, 0, /* No PER support, use "-gen-PER" to enable */ - 0, /* Use generic outmost tag fetcher */ + &asn_OP_OCTET_STRING, asn_DEF_Opaque_tags_1, sizeof(asn_DEF_Opaque_tags_1) /sizeof(asn_DEF_Opaque_tags_1[0]) - 1, /* 1 */ asn_DEF_Opaque_tags_1, /* Same as above */ sizeof(asn_DEF_Opaque_tags_1) /sizeof(asn_DEF_Opaque_tags_1[0]), /* 2 */ - 0, /* No PER visible constraints */ + { 0, 0, OCTET_STRING_constraint }, 0, 0, /* No members */ - 0 /* No specifics */ + &asn_SPC_OCTET_STRING_specs /* Additional specs */ }; diff --git a/libs/smux/OpenPDU.c b/libs/smux/OpenPDU.c index 337275e4..d4036f85 100644 --- a/libs/smux/OpenPDU.c +++ b/libs/smux/OpenPDU.c @@ -1,53 +1,53 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "SMUX" * found in "SMUX.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #include "OpenPDU.h" -static asn_TYPE_member_t asn_MBR_OpenPDU_1[] = { +static asn_oer_constraints_t asn_OER_type_OpenPDU_constr_1 CC_NOTUSED = { + { 0, 0 }, + -1}; +asn_per_constraints_t asn_PER_type_OpenPDU_constr_1 CC_NOTUSED = { + { APC_CONSTRAINED, 0, 0, 0, 0 } /* (0..0) */, + { APC_UNCONSTRAINED, -1, -1, 0, 0 }, + 0, 0 /* No PER value map */ +}; +asn_TYPE_member_t asn_MBR_OpenPDU_1[] = { { ATF_NOFLAGS, 0, offsetof(struct OpenPDU, choice.simple), (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 0, &asn_DEF_SimpleOpen, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "simple" }, }; static const asn_TYPE_tag2member_t asn_MAP_OpenPDU_tag2el_1[] = { { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 0, 0, 0 } /* simple */ }; -static asn_CHOICE_specifics_t asn_SPC_OpenPDU_specs_1 = { +asn_CHOICE_specifics_t asn_SPC_OpenPDU_specs_1 = { sizeof(struct OpenPDU), offsetof(struct OpenPDU, _asn_ctx), offsetof(struct OpenPDU, present), sizeof(((struct OpenPDU *)0)->present), asn_MAP_OpenPDU_tag2el_1, 1, /* Count of tags in the map */ - 0, + 0, 0, -1 /* Extensions start */ }; asn_TYPE_descriptor_t asn_DEF_OpenPDU = { "OpenPDU", "OpenPDU", - CHOICE_free, - CHOICE_print, - CHOICE_constraint, - CHOICE_decode_ber, - CHOICE_encode_der, - CHOICE_decode_xer, - CHOICE_encode_xer, - 0, 0, /* No PER support, use "-gen-PER" to enable */ - CHOICE_outmost_tag, + &asn_OP_CHOICE, 0, /* No effective tags (pointer) */ 0, /* No effective tags (count) */ 0, /* No tags (pointer) */ 0, /* No tags (count) */ - 0, /* No PER visible constraints */ + { &asn_OER_type_OpenPDU_constr_1, &asn_PER_type_OpenPDU_constr_1, CHOICE_constraint }, asn_MBR_OpenPDU_1, 1, /* Elements count */ &asn_SPC_OpenPDU_specs_1 /* Additional specs */ diff --git a/libs/smux/PDU.c b/libs/smux/PDU.c index af8528d5..73c0534e 100644 --- a/libs/smux/PDU.c +++ b/libs/smux/PDU.c @@ -1,47 +1,47 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1157-SNMP" * found in "RFC1157-SNMP.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #include "PDU.h" -static asn_TYPE_member_t asn_MBR_PDU_1[] = { +asn_TYPE_member_t asn_MBR_PDU_1[] = { { ATF_NOFLAGS, 0, offsetof(struct PDU, request_id), (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, &asn_DEF_INTEGER, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "request-id" }, { ATF_NOFLAGS, 0, offsetof(struct PDU, error_status), (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, &asn_DEF_INTEGER, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "error-status" }, { ATF_NOFLAGS, 0, offsetof(struct PDU, error_index), (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, &asn_DEF_INTEGER, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "error-index" }, { ATF_NOFLAGS, 0, offsetof(struct PDU, variable_bindings), (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)), 0, &asn_DEF_VarBindList, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "variable-bindings" }, }; @@ -54,34 +54,25 @@ static const asn_TYPE_tag2member_t asn_MAP_PDU_tag2el_1[] = { { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 2, -2, 0 }, /* error-index */ { (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)), 3, 0, 0 } /* variable-bindings */ }; -static asn_SEQUENCE_specifics_t asn_SPC_PDU_specs_1 = { +asn_SEQUENCE_specifics_t asn_SPC_PDU_specs_1 = { sizeof(struct PDU), offsetof(struct PDU, _asn_ctx), asn_MAP_PDU_tag2el_1, 4, /* Count of tags in the map */ 0, 0, 0, /* Optional elements (not needed) */ - -1, /* Start extensions */ - -1 /* Stop extensions */ + -1, /* First extension addition */ }; asn_TYPE_descriptor_t asn_DEF_PDU = { "PDU", "PDU", - SEQUENCE_free, - SEQUENCE_print, - SEQUENCE_constraint, - SEQUENCE_decode_ber, - SEQUENCE_encode_der, - SEQUENCE_decode_xer, - SEQUENCE_encode_xer, - 0, 0, /* No PER support, use "-gen-PER" to enable */ - 0, /* Use generic outmost tag fetcher */ + &asn_OP_SEQUENCE, asn_DEF_PDU_tags_1, sizeof(asn_DEF_PDU_tags_1) /sizeof(asn_DEF_PDU_tags_1[0]), /* 1 */ asn_DEF_PDU_tags_1, /* Same as above */ sizeof(asn_DEF_PDU_tags_1) /sizeof(asn_DEF_PDU_tags_1[0]), /* 1 */ - 0, /* No PER visible constraints */ + { 0, 0, SEQUENCE_constraint }, asn_MBR_PDU_1, 4, /* Elements count */ &asn_SPC_PDU_specs_1 /* Additional specs */ diff --git a/libs/smux/PDUs.c b/libs/smux/PDUs.c index 177d23d9..a956ab4e 100644 --- a/libs/smux/PDUs.c +++ b/libs/smux/PDUs.c @@ -1,56 +1,64 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1157-SNMP" * found in "RFC1157-SNMP.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #include "PDUs.h" -static asn_TYPE_member_t asn_MBR_PDUs_1[] = { +static asn_oer_constraints_t asn_OER_type_PDUs_constr_1 CC_NOTUSED = { + { 0, 0 }, + -1}; +asn_per_constraints_t asn_PER_type_PDUs_constr_1 CC_NOTUSED = { + { APC_CONSTRAINED, 3, 3, 0, 4 } /* (0..4) */, + { APC_UNCONSTRAINED, -1, -1, 0, 0 }, + 0, 0 /* No PER value map */ +}; +asn_TYPE_member_t asn_MBR_PDUs_1[] = { { ATF_NOFLAGS, 0, offsetof(struct PDUs, choice.get_request), (ASN_TAG_CLASS_CONTEXT | (0 << 2)), 0, &asn_DEF_GetRequest_PDU, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "get-request" }, { ATF_NOFLAGS, 0, offsetof(struct PDUs, choice.get_next_request), (ASN_TAG_CLASS_CONTEXT | (1 << 2)), 0, &asn_DEF_GetNextRequest_PDU, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "get-next-request" }, { ATF_NOFLAGS, 0, offsetof(struct PDUs, choice.get_response), (ASN_TAG_CLASS_CONTEXT | (2 << 2)), 0, &asn_DEF_GetResponse_PDU, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "get-response" }, { ATF_NOFLAGS, 0, offsetof(struct PDUs, choice.set_request), (ASN_TAG_CLASS_CONTEXT | (3 << 2)), 0, &asn_DEF_SetRequest_PDU, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "set-request" }, { ATF_NOFLAGS, 0, offsetof(struct PDUs, choice.trap), (ASN_TAG_CLASS_CONTEXT | (4 << 2)), 0, &asn_DEF_Trap_PDU, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "trap" }, }; @@ -61,33 +69,25 @@ static const asn_TYPE_tag2member_t asn_MAP_PDUs_tag2el_1[] = { { (ASN_TAG_CLASS_CONTEXT | (3 << 2)), 3, 0, 0 }, /* set-request */ { (ASN_TAG_CLASS_CONTEXT | (4 << 2)), 4, 0, 0 } /* trap */ }; -static asn_CHOICE_specifics_t asn_SPC_PDUs_specs_1 = { +asn_CHOICE_specifics_t asn_SPC_PDUs_specs_1 = { sizeof(struct PDUs), offsetof(struct PDUs, _asn_ctx), offsetof(struct PDUs, present), sizeof(((struct PDUs *)0)->present), asn_MAP_PDUs_tag2el_1, 5, /* Count of tags in the map */ - 0, + 0, 0, -1 /* Extensions start */ }; asn_TYPE_descriptor_t asn_DEF_PDUs = { "PDUs", "PDUs", - CHOICE_free, - CHOICE_print, - CHOICE_constraint, - CHOICE_decode_ber, - CHOICE_encode_der, - CHOICE_decode_xer, - CHOICE_encode_xer, - 0, 0, /* No PER support, use "-gen-PER" to enable */ - CHOICE_outmost_tag, + &asn_OP_CHOICE, 0, /* No effective tags (pointer) */ 0, /* No effective tags (count) */ 0, /* No tags (pointer) */ 0, /* No tags (count) */ - 0, /* No PER visible constraints */ + { &asn_OER_type_PDUs_constr_1, &asn_PER_type_PDUs_constr_1, CHOICE_constraint }, asn_MBR_PDUs_1, 5, /* Elements count */ &asn_SPC_PDUs_specs_1 /* Additional specs */ diff --git a/libs/smux/PhysAddress.c b/libs/smux/PhysAddress.c index 2ffd2c3d..e751f555 100644 --- a/libs/smux/PhysAddress.c +++ b/libs/smux/PhysAddress.c @@ -1,109 +1,31 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1213-MIB" * found in "RFC1213-MIB.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #include "PhysAddress.h" -int -PhysAddress_constraint(asn_TYPE_descriptor_t *td, const void *sptr, - asn_app_constraint_failed_f *ctfailcb, void *app_key) { - /* Replace with underlying type checker */ - td->check_constraints = asn_DEF_OCTET_STRING.check_constraints; - return td->check_constraints(td, sptr, ctfailcb, app_key); -} - /* * This type is implemented using OCTET_STRING, * so here we adjust the DEF accordingly. */ -static void -PhysAddress_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) { - td->free_struct = asn_DEF_OCTET_STRING.free_struct; - td->print_struct = asn_DEF_OCTET_STRING.print_struct; - td->check_constraints = asn_DEF_OCTET_STRING.check_constraints; - td->ber_decoder = asn_DEF_OCTET_STRING.ber_decoder; - td->der_encoder = asn_DEF_OCTET_STRING.der_encoder; - td->xer_decoder = asn_DEF_OCTET_STRING.xer_decoder; - td->xer_encoder = asn_DEF_OCTET_STRING.xer_encoder; - td->uper_decoder = asn_DEF_OCTET_STRING.uper_decoder; - td->uper_encoder = asn_DEF_OCTET_STRING.uper_encoder; - if(!td->per_constraints) - td->per_constraints = asn_DEF_OCTET_STRING.per_constraints; - td->elements = asn_DEF_OCTET_STRING.elements; - td->elements_count = asn_DEF_OCTET_STRING.elements_count; - td->specifics = asn_DEF_OCTET_STRING.specifics; -} - -void -PhysAddress_free(asn_TYPE_descriptor_t *td, - void *struct_ptr, int contents_only) { - PhysAddress_1_inherit_TYPE_descriptor(td); - td->free_struct(td, struct_ptr, contents_only); -} - -int -PhysAddress_print(asn_TYPE_descriptor_t *td, const void *struct_ptr, - int ilevel, asn_app_consume_bytes_f *cb, void *app_key) { - PhysAddress_1_inherit_TYPE_descriptor(td); - return td->print_struct(td, struct_ptr, ilevel, cb, app_key); -} - -asn_dec_rval_t -PhysAddress_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, - void **structure, const void *bufptr, size_t size, int tag_mode) { - PhysAddress_1_inherit_TYPE_descriptor(td); - return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode); -} - -asn_enc_rval_t -PhysAddress_encode_der(asn_TYPE_descriptor_t *td, - void *structure, int tag_mode, ber_tlv_tag_t tag, - asn_app_consume_bytes_f *cb, void *app_key) { - PhysAddress_1_inherit_TYPE_descriptor(td); - return td->der_encoder(td, structure, tag_mode, tag, cb, app_key); -} - -asn_dec_rval_t -PhysAddress_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, - void **structure, const char *opt_mname, const void *bufptr, size_t size) { - PhysAddress_1_inherit_TYPE_descriptor(td); - return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size); -} - -asn_enc_rval_t -PhysAddress_encode_xer(asn_TYPE_descriptor_t *td, void *structure, - int ilevel, enum xer_encoder_flags_e flags, - asn_app_consume_bytes_f *cb, void *app_key) { - PhysAddress_1_inherit_TYPE_descriptor(td); - return td->xer_encoder(td, structure, ilevel, flags, cb, app_key); -} - static const ber_tlv_tag_t asn_DEF_PhysAddress_tags_1[] = { (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)) }; asn_TYPE_descriptor_t asn_DEF_PhysAddress = { "PhysAddress", "PhysAddress", - PhysAddress_free, - PhysAddress_print, - PhysAddress_constraint, - PhysAddress_decode_ber, - PhysAddress_encode_der, - PhysAddress_decode_xer, - PhysAddress_encode_xer, - 0, 0, /* No PER support, use "-gen-PER" to enable */ - 0, /* Use generic outmost tag fetcher */ + &asn_OP_OCTET_STRING, asn_DEF_PhysAddress_tags_1, sizeof(asn_DEF_PhysAddress_tags_1) /sizeof(asn_DEF_PhysAddress_tags_1[0]), /* 1 */ asn_DEF_PhysAddress_tags_1, /* Same as above */ sizeof(asn_DEF_PhysAddress_tags_1) /sizeof(asn_DEF_PhysAddress_tags_1[0]), /* 1 */ - 0, /* No PER visible constraints */ + { 0, 0, OCTET_STRING_constraint }, 0, 0, /* No members */ - 0 /* No specifics */ + &asn_SPC_OCTET_STRING_specs /* Additional specs */ }; diff --git a/libs/smux/RReqPDU.c b/libs/smux/RReqPDU.c index ee4040dc..43e78ae5 100644 --- a/libs/smux/RReqPDU.c +++ b/libs/smux/RReqPDU.c @@ -1,14 +1,14 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "SMUX" * found in "SMUX.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #include "RReqPDU.h" static int -memb_priority_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr, +memb_priority_constraint_1(const asn_TYPE_descriptor_t *td, const void *sptr, asn_app_constraint_failed_f *ctfailcb, void *app_key) { long value; @@ -32,32 +32,40 @@ memb_priority_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr, } } -static asn_TYPE_member_t asn_MBR_RReqPDU_1[] = { +static asn_oer_constraints_t asn_OER_memb_priority_constr_3 CC_NOTUSED = { + { 4, 0 } /* (-1..2147483647) */, + -1}; +static asn_per_constraints_t asn_PER_memb_priority_constr_3 CC_NOTUSED = { + { APC_CONSTRAINED, 32, -1, -1, 2147483647 } /* (-1..2147483647) */, + { APC_UNCONSTRAINED, -1, -1, 0, 0 }, + 0, 0 /* No PER value map */ +}; +asn_TYPE_member_t asn_MBR_RReqPDU_1[] = { { ATF_NOFLAGS, 0, offsetof(struct RReqPDU, subtree), (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)), 0, &asn_DEF_ObjectName, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "subtree" }, { ATF_NOFLAGS, 0, offsetof(struct RReqPDU, priority), (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, &asn_DEF_NativeInteger, - memb_priority_constraint_1, - 0, /* PER is not compiled, use -gen-PER */ 0, + { &asn_OER_memb_priority_constr_3, &asn_PER_memb_priority_constr_3, memb_priority_constraint_1 }, + 0, 0, /* No default value */ "priority" }, { ATF_NOFLAGS, 0, offsetof(struct RReqPDU, operation), (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, &asn_DEF_INTEGER, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "operation" }, }; @@ -70,34 +78,25 @@ static const asn_TYPE_tag2member_t asn_MAP_RReqPDU_tag2el_1[] = { { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 2, -1, 0 }, /* operation */ { (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)), 0, 0, 0 } /* subtree */ }; -static asn_SEQUENCE_specifics_t asn_SPC_RReqPDU_specs_1 = { +asn_SEQUENCE_specifics_t asn_SPC_RReqPDU_specs_1 = { sizeof(struct RReqPDU), offsetof(struct RReqPDU, _asn_ctx), asn_MAP_RReqPDU_tag2el_1, 3, /* Count of tags in the map */ 0, 0, 0, /* Optional elements (not needed) */ - -1, /* Start extensions */ - -1 /* Stop extensions */ + -1, /* First extension addition */ }; asn_TYPE_descriptor_t asn_DEF_RReqPDU = { "RReqPDU", "RReqPDU", - SEQUENCE_free, - SEQUENCE_print, - SEQUENCE_constraint, - SEQUENCE_decode_ber, - SEQUENCE_encode_der, - SEQUENCE_decode_xer, - SEQUENCE_encode_xer, - 0, 0, /* No PER support, use "-gen-PER" to enable */ - 0, /* Use generic outmost tag fetcher */ + &asn_OP_SEQUENCE, asn_DEF_RReqPDU_tags_1, sizeof(asn_DEF_RReqPDU_tags_1) /sizeof(asn_DEF_RReqPDU_tags_1[0]) - 1, /* 1 */ asn_DEF_RReqPDU_tags_1, /* Same as above */ sizeof(asn_DEF_RReqPDU_tags_1) /sizeof(asn_DEF_RReqPDU_tags_1[0]), /* 2 */ - 0, /* No PER visible constraints */ + { 0, 0, SEQUENCE_constraint }, asn_MBR_RReqPDU_1, 3, /* Elements count */ &asn_SPC_RReqPDU_specs_1 /* Additional specs */ diff --git a/libs/smux/RRspPDU.c b/libs/smux/RRspPDU.c index b4d026f3..c29401b4 100644 --- a/libs/smux/RRspPDU.c +++ b/libs/smux/RRspPDU.c @@ -1,86 +1,16 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "SMUX" * found in "SMUX.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #include "RRspPDU.h" -int -RRspPDU_constraint(asn_TYPE_descriptor_t *td, const void *sptr, - asn_app_constraint_failed_f *ctfailcb, void *app_key) { - /* Replace with underlying type checker */ - td->check_constraints = asn_DEF_INTEGER.check_constraints; - return td->check_constraints(td, sptr, ctfailcb, app_key); -} - /* * This type is implemented using INTEGER, * so here we adjust the DEF accordingly. */ -static void -RRspPDU_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) { - td->free_struct = asn_DEF_INTEGER.free_struct; - td->print_struct = asn_DEF_INTEGER.print_struct; - td->check_constraints = asn_DEF_INTEGER.check_constraints; - td->ber_decoder = asn_DEF_INTEGER.ber_decoder; - td->der_encoder = asn_DEF_INTEGER.der_encoder; - td->xer_decoder = asn_DEF_INTEGER.xer_decoder; - td->xer_encoder = asn_DEF_INTEGER.xer_encoder; - td->uper_decoder = asn_DEF_INTEGER.uper_decoder; - td->uper_encoder = asn_DEF_INTEGER.uper_encoder; - if(!td->per_constraints) - td->per_constraints = asn_DEF_INTEGER.per_constraints; - td->elements = asn_DEF_INTEGER.elements; - td->elements_count = asn_DEF_INTEGER.elements_count; - td->specifics = asn_DEF_INTEGER.specifics; -} - -void -RRspPDU_free(asn_TYPE_descriptor_t *td, - void *struct_ptr, int contents_only) { - RRspPDU_1_inherit_TYPE_descriptor(td); - td->free_struct(td, struct_ptr, contents_only); -} - -int -RRspPDU_print(asn_TYPE_descriptor_t *td, const void *struct_ptr, - int ilevel, asn_app_consume_bytes_f *cb, void *app_key) { - RRspPDU_1_inherit_TYPE_descriptor(td); - return td->print_struct(td, struct_ptr, ilevel, cb, app_key); -} - -asn_dec_rval_t -RRspPDU_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, - void **structure, const void *bufptr, size_t size, int tag_mode) { - RRspPDU_1_inherit_TYPE_descriptor(td); - return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode); -} - -asn_enc_rval_t -RRspPDU_encode_der(asn_TYPE_descriptor_t *td, - void *structure, int tag_mode, ber_tlv_tag_t tag, - asn_app_consume_bytes_f *cb, void *app_key) { - RRspPDU_1_inherit_TYPE_descriptor(td); - return td->der_encoder(td, structure, tag_mode, tag, cb, app_key); -} - -asn_dec_rval_t -RRspPDU_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, - void **structure, const char *opt_mname, const void *bufptr, size_t size) { - RRspPDU_1_inherit_TYPE_descriptor(td); - return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size); -} - -asn_enc_rval_t -RRspPDU_encode_xer(asn_TYPE_descriptor_t *td, void *structure, - int ilevel, enum xer_encoder_flags_e flags, - asn_app_consume_bytes_f *cb, void *app_key) { - RRspPDU_1_inherit_TYPE_descriptor(td); - return td->xer_encoder(td, structure, ilevel, flags, cb, app_key); -} - static const ber_tlv_tag_t asn_DEF_RRspPDU_tags_1[] = { (ASN_TAG_CLASS_APPLICATION | (3 << 2)), (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)) @@ -88,22 +18,14 @@ static const ber_tlv_tag_t asn_DEF_RRspPDU_tags_1[] = { asn_TYPE_descriptor_t asn_DEF_RRspPDU = { "RRspPDU", "RRspPDU", - RRspPDU_free, - RRspPDU_print, - RRspPDU_constraint, - RRspPDU_decode_ber, - RRspPDU_encode_der, - RRspPDU_decode_xer, - RRspPDU_encode_xer, - 0, 0, /* No PER support, use "-gen-PER" to enable */ - 0, /* Use generic outmost tag fetcher */ + &asn_OP_INTEGER, asn_DEF_RRspPDU_tags_1, sizeof(asn_DEF_RRspPDU_tags_1) /sizeof(asn_DEF_RRspPDU_tags_1[0]) - 1, /* 1 */ asn_DEF_RRspPDU_tags_1, /* Same as above */ sizeof(asn_DEF_RRspPDU_tags_1) /sizeof(asn_DEF_RRspPDU_tags_1[0]), /* 2 */ - 0, /* No PER visible constraints */ + { 0, 0, INTEGER_constraint }, 0, 0, /* Defined elsewhere */ 0 /* No specifics */ }; diff --git a/libs/smux/SMUX-PDUs.c b/libs/smux/SMUX-PDUs.c index adfdccde..12516acd 100644 --- a/libs/smux/SMUX-PDUs.c +++ b/libs/smux/SMUX-PDUs.c @@ -1,68 +1,78 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "SMUX" * found in "SMUX.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #include "SMUX-PDUs.h" +static asn_oer_constraints_t asn_OER_type_SMUX_PDUs_constr_1 CC_NOTUSED = { + { 0, 0 }, + -1}; +static asn_per_constraints_t asn_PER_type_SMUX_PDUs_constr_1 CC_NOTUSED = { + { APC_CONSTRAINED, 3, 3, 0, 5 } /* (0..5) */, + { APC_UNCONSTRAINED, -1, -1, 0, 0 }, + 0, 0 /* No PER value map */ +}; static asn_TYPE_member_t asn_MBR_SMUX_PDUs_1[] = { { ATF_NOFLAGS, 0, offsetof(struct SMUX_PDUs, choice.open), -1 /* Ambiguous tag (CHOICE?) */, 0, &asn_DEF_OpenPDU, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "open" }, { ATF_NOFLAGS, 0, offsetof(struct SMUX_PDUs, choice.close), (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 0, &asn_DEF_ClosePDU, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "close" }, { ATF_NOFLAGS, 0, offsetof(struct SMUX_PDUs, choice.registerRequest), (ASN_TAG_CLASS_APPLICATION | (2 << 2)), 0, &asn_DEF_RReqPDU, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "registerRequest" }, { ATF_NOFLAGS, 0, offsetof(struct SMUX_PDUs, choice.registerResponse), (ASN_TAG_CLASS_APPLICATION | (3 << 2)), 0, &asn_DEF_RRspPDU, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "registerResponse" }, { ATF_NOFLAGS, 0, offsetof(struct SMUX_PDUs, choice.pdus), -1 /* Ambiguous tag (CHOICE?) */, 0, &asn_DEF_PDUs, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "pdus" }, { ATF_NOFLAGS, 0, offsetof(struct SMUX_PDUs, choice.commitOrRollback), (ASN_TAG_CLASS_APPLICATION | (4 << 2)), 0, &asn_DEF_SOutPDU, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "commitOrRollback" }, }; +static const unsigned asn_MAP_SMUX_PDUs_to_canonical_1[] = { 0, 1, 2, 3, 5, 4 }; +static const unsigned asn_MAP_SMUX_PDUs_from_canonical_1[] = { 0, 1, 2, 3, 5, 4 }; static const asn_TYPE_tag2member_t asn_MAP_SMUX_PDUs_tag2el_1[] = { { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 0, 0, 0 }, /* simple */ { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 1, 0, 0 }, /* close */ @@ -82,26 +92,19 @@ static asn_CHOICE_specifics_t asn_SPC_SMUX_PDUs_specs_1 = { sizeof(((struct SMUX_PDUs *)0)->present), asn_MAP_SMUX_PDUs_tag2el_1, 10, /* Count of tags in the map */ - 0, + asn_MAP_SMUX_PDUs_to_canonical_1, + asn_MAP_SMUX_PDUs_from_canonical_1, -1 /* Extensions start */ }; asn_TYPE_descriptor_t asn_DEF_SMUX_PDUs = { "SMUX-PDUs", "SMUX-PDUs", - CHOICE_free, - CHOICE_print, - CHOICE_constraint, - CHOICE_decode_ber, - CHOICE_encode_der, - CHOICE_decode_xer, - CHOICE_encode_xer, - 0, 0, /* No PER support, use "-gen-PER" to enable */ - CHOICE_outmost_tag, + &asn_OP_CHOICE, 0, /* No effective tags (pointer) */ 0, /* No effective tags (count) */ 0, /* No tags (pointer) */ 0, /* No tags (count) */ - 0, /* No PER visible constraints */ + { &asn_OER_type_SMUX_PDUs_constr_1, &asn_PER_type_SMUX_PDUs_constr_1, CHOICE_constraint }, asn_MBR_SMUX_PDUs_1, 6, /* Elements count */ &asn_SPC_SMUX_PDUs_specs_1 /* Additional specs */ diff --git a/libs/smux/SOutPDU.c b/libs/smux/SOutPDU.c index 29d47786..ef1547e6 100644 --- a/libs/smux/SOutPDU.c +++ b/libs/smux/SOutPDU.c @@ -1,86 +1,16 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "SMUX" * found in "SMUX.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #include "SOutPDU.h" -int -SOutPDU_constraint(asn_TYPE_descriptor_t *td, const void *sptr, - asn_app_constraint_failed_f *ctfailcb, void *app_key) { - /* Replace with underlying type checker */ - td->check_constraints = asn_DEF_INTEGER.check_constraints; - return td->check_constraints(td, sptr, ctfailcb, app_key); -} - /* * This type is implemented using INTEGER, * so here we adjust the DEF accordingly. */ -static void -SOutPDU_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) { - td->free_struct = asn_DEF_INTEGER.free_struct; - td->print_struct = asn_DEF_INTEGER.print_struct; - td->check_constraints = asn_DEF_INTEGER.check_constraints; - td->ber_decoder = asn_DEF_INTEGER.ber_decoder; - td->der_encoder = asn_DEF_INTEGER.der_encoder; - td->xer_decoder = asn_DEF_INTEGER.xer_decoder; - td->xer_encoder = asn_DEF_INTEGER.xer_encoder; - td->uper_decoder = asn_DEF_INTEGER.uper_decoder; - td->uper_encoder = asn_DEF_INTEGER.uper_encoder; - if(!td->per_constraints) - td->per_constraints = asn_DEF_INTEGER.per_constraints; - td->elements = asn_DEF_INTEGER.elements; - td->elements_count = asn_DEF_INTEGER.elements_count; - td->specifics = asn_DEF_INTEGER.specifics; -} - -void -SOutPDU_free(asn_TYPE_descriptor_t *td, - void *struct_ptr, int contents_only) { - SOutPDU_1_inherit_TYPE_descriptor(td); - td->free_struct(td, struct_ptr, contents_only); -} - -int -SOutPDU_print(asn_TYPE_descriptor_t *td, const void *struct_ptr, - int ilevel, asn_app_consume_bytes_f *cb, void *app_key) { - SOutPDU_1_inherit_TYPE_descriptor(td); - return td->print_struct(td, struct_ptr, ilevel, cb, app_key); -} - -asn_dec_rval_t -SOutPDU_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, - void **structure, const void *bufptr, size_t size, int tag_mode) { - SOutPDU_1_inherit_TYPE_descriptor(td); - return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode); -} - -asn_enc_rval_t -SOutPDU_encode_der(asn_TYPE_descriptor_t *td, - void *structure, int tag_mode, ber_tlv_tag_t tag, - asn_app_consume_bytes_f *cb, void *app_key) { - SOutPDU_1_inherit_TYPE_descriptor(td); - return td->der_encoder(td, structure, tag_mode, tag, cb, app_key); -} - -asn_dec_rval_t -SOutPDU_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, - void **structure, const char *opt_mname, const void *bufptr, size_t size) { - SOutPDU_1_inherit_TYPE_descriptor(td); - return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size); -} - -asn_enc_rval_t -SOutPDU_encode_xer(asn_TYPE_descriptor_t *td, void *structure, - int ilevel, enum xer_encoder_flags_e flags, - asn_app_consume_bytes_f *cb, void *app_key) { - SOutPDU_1_inherit_TYPE_descriptor(td); - return td->xer_encoder(td, structure, ilevel, flags, cb, app_key); -} - static const ber_tlv_tag_t asn_DEF_SOutPDU_tags_1[] = { (ASN_TAG_CLASS_APPLICATION | (4 << 2)), (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)) @@ -88,22 +18,14 @@ static const ber_tlv_tag_t asn_DEF_SOutPDU_tags_1[] = { asn_TYPE_descriptor_t asn_DEF_SOutPDU = { "SOutPDU", "SOutPDU", - SOutPDU_free, - SOutPDU_print, - SOutPDU_constraint, - SOutPDU_decode_ber, - SOutPDU_encode_der, - SOutPDU_decode_xer, - SOutPDU_encode_xer, - 0, 0, /* No PER support, use "-gen-PER" to enable */ - 0, /* Use generic outmost tag fetcher */ + &asn_OP_INTEGER, asn_DEF_SOutPDU_tags_1, sizeof(asn_DEF_SOutPDU_tags_1) /sizeof(asn_DEF_SOutPDU_tags_1[0]) - 1, /* 1 */ asn_DEF_SOutPDU_tags_1, /* Same as above */ sizeof(asn_DEF_SOutPDU_tags_1) /sizeof(asn_DEF_SOutPDU_tags_1[0]), /* 2 */ - 0, /* No PER visible constraints */ + { 0, 0, INTEGER_constraint }, 0, 0, /* Defined elsewhere */ 0 /* No specifics */ }; diff --git a/libs/smux/SetRequest-PDU.c b/libs/smux/SetRequest-PDU.c index 1bc9495d..7c339d03 100644 --- a/libs/smux/SetRequest-PDU.c +++ b/libs/smux/SetRequest-PDU.c @@ -1,86 +1,16 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1157-SNMP" * found in "RFC1157-SNMP.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #include "SetRequest-PDU.h" -int -SetRequest_PDU_constraint(asn_TYPE_descriptor_t *td, const void *sptr, - asn_app_constraint_failed_f *ctfailcb, void *app_key) { - /* Replace with underlying type checker */ - td->check_constraints = asn_DEF_PDU.check_constraints; - return td->check_constraints(td, sptr, ctfailcb, app_key); -} - /* * This type is implemented using PDU, * so here we adjust the DEF accordingly. */ -static void -SetRequest_PDU_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) { - td->free_struct = asn_DEF_PDU.free_struct; - td->print_struct = asn_DEF_PDU.print_struct; - td->check_constraints = asn_DEF_PDU.check_constraints; - td->ber_decoder = asn_DEF_PDU.ber_decoder; - td->der_encoder = asn_DEF_PDU.der_encoder; - td->xer_decoder = asn_DEF_PDU.xer_decoder; - td->xer_encoder = asn_DEF_PDU.xer_encoder; - td->uper_decoder = asn_DEF_PDU.uper_decoder; - td->uper_encoder = asn_DEF_PDU.uper_encoder; - if(!td->per_constraints) - td->per_constraints = asn_DEF_PDU.per_constraints; - td->elements = asn_DEF_PDU.elements; - td->elements_count = asn_DEF_PDU.elements_count; - td->specifics = asn_DEF_PDU.specifics; -} - -void -SetRequest_PDU_free(asn_TYPE_descriptor_t *td, - void *struct_ptr, int contents_only) { - SetRequest_PDU_1_inherit_TYPE_descriptor(td); - td->free_struct(td, struct_ptr, contents_only); -} - -int -SetRequest_PDU_print(asn_TYPE_descriptor_t *td, const void *struct_ptr, - int ilevel, asn_app_consume_bytes_f *cb, void *app_key) { - SetRequest_PDU_1_inherit_TYPE_descriptor(td); - return td->print_struct(td, struct_ptr, ilevel, cb, app_key); -} - -asn_dec_rval_t -SetRequest_PDU_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, - void **structure, const void *bufptr, size_t size, int tag_mode) { - SetRequest_PDU_1_inherit_TYPE_descriptor(td); - return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode); -} - -asn_enc_rval_t -SetRequest_PDU_encode_der(asn_TYPE_descriptor_t *td, - void *structure, int tag_mode, ber_tlv_tag_t tag, - asn_app_consume_bytes_f *cb, void *app_key) { - SetRequest_PDU_1_inherit_TYPE_descriptor(td); - return td->der_encoder(td, structure, tag_mode, tag, cb, app_key); -} - -asn_dec_rval_t -SetRequest_PDU_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, - void **structure, const char *opt_mname, const void *bufptr, size_t size) { - SetRequest_PDU_1_inherit_TYPE_descriptor(td); - return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size); -} - -asn_enc_rval_t -SetRequest_PDU_encode_xer(asn_TYPE_descriptor_t *td, void *structure, - int ilevel, enum xer_encoder_flags_e flags, - asn_app_consume_bytes_f *cb, void *app_key) { - SetRequest_PDU_1_inherit_TYPE_descriptor(td); - return td->xer_encoder(td, structure, ilevel, flags, cb, app_key); -} - static const ber_tlv_tag_t asn_DEF_SetRequest_PDU_tags_1[] = { (ASN_TAG_CLASS_CONTEXT | (3 << 2)), (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)) @@ -88,23 +18,16 @@ static const ber_tlv_tag_t asn_DEF_SetRequest_PDU_tags_1[] = { asn_TYPE_descriptor_t asn_DEF_SetRequest_PDU = { "SetRequest-PDU", "SetRequest-PDU", - SetRequest_PDU_free, - SetRequest_PDU_print, - SetRequest_PDU_constraint, - SetRequest_PDU_decode_ber, - SetRequest_PDU_encode_der, - SetRequest_PDU_decode_xer, - SetRequest_PDU_encode_xer, - 0, 0, /* No PER support, use "-gen-PER" to enable */ - 0, /* Use generic outmost tag fetcher */ + &asn_OP_SEQUENCE, asn_DEF_SetRequest_PDU_tags_1, sizeof(asn_DEF_SetRequest_PDU_tags_1) /sizeof(asn_DEF_SetRequest_PDU_tags_1[0]) - 1, /* 1 */ asn_DEF_SetRequest_PDU_tags_1, /* Same as above */ sizeof(asn_DEF_SetRequest_PDU_tags_1) /sizeof(asn_DEF_SetRequest_PDU_tags_1[0]), /* 2 */ - 0, /* No PER visible constraints */ - 0, 0, /* Defined elsewhere */ - 0 /* No specifics */ + { 0, 0, SEQUENCE_constraint }, + asn_MBR_PDU_1, + 4, /* Elements count */ + &asn_SPC_PDU_specs_1 /* Additional specs */ }; diff --git a/libs/smux/SimpleOpen.c b/libs/smux/SimpleOpen.c index 479430bf..ff64f59d 100644 --- a/libs/smux/SimpleOpen.c +++ b/libs/smux/SimpleOpen.c @@ -1,47 +1,47 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "SMUX" * found in "SMUX.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #include "SimpleOpen.h" -static asn_TYPE_member_t asn_MBR_SimpleOpen_1[] = { +asn_TYPE_member_t asn_MBR_SimpleOpen_1[] = { { ATF_NOFLAGS, 0, offsetof(struct SimpleOpen, version), (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, &asn_DEF_INTEGER, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "version" }, { ATF_NOFLAGS, 0, offsetof(struct SimpleOpen, identity), (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)), 0, &asn_DEF_OBJECT_IDENTIFIER, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "identity" }, { ATF_NOFLAGS, 0, offsetof(struct SimpleOpen, description), (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), 0, &asn_DEF_DisplayString, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "description" }, { ATF_NOFLAGS, 0, offsetof(struct SimpleOpen, password), (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), 0, &asn_DEF_OCTET_STRING, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "password" }, }; @@ -55,34 +55,25 @@ static const asn_TYPE_tag2member_t asn_MAP_SimpleOpen_tag2el_1[] = { { (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), 3, -1, 0 }, /* password */ { (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)), 1, 0, 0 } /* identity */ }; -static asn_SEQUENCE_specifics_t asn_SPC_SimpleOpen_specs_1 = { +asn_SEQUENCE_specifics_t asn_SPC_SimpleOpen_specs_1 = { sizeof(struct SimpleOpen), offsetof(struct SimpleOpen, _asn_ctx), asn_MAP_SimpleOpen_tag2el_1, 4, /* Count of tags in the map */ 0, 0, 0, /* Optional elements (not needed) */ - -1, /* Start extensions */ - -1 /* Stop extensions */ + -1, /* First extension addition */ }; asn_TYPE_descriptor_t asn_DEF_SimpleOpen = { "SimpleOpen", "SimpleOpen", - SEQUENCE_free, - SEQUENCE_print, - SEQUENCE_constraint, - SEQUENCE_decode_ber, - SEQUENCE_encode_der, - SEQUENCE_decode_xer, - SEQUENCE_encode_xer, - 0, 0, /* No PER support, use "-gen-PER" to enable */ - 0, /* Use generic outmost tag fetcher */ + &asn_OP_SEQUENCE, asn_DEF_SimpleOpen_tags_1, sizeof(asn_DEF_SimpleOpen_tags_1) /sizeof(asn_DEF_SimpleOpen_tags_1[0]) - 1, /* 1 */ asn_DEF_SimpleOpen_tags_1, /* Same as above */ sizeof(asn_DEF_SimpleOpen_tags_1) /sizeof(asn_DEF_SimpleOpen_tags_1[0]), /* 2 */ - 0, /* No PER visible constraints */ + { 0, 0, SEQUENCE_constraint }, asn_MBR_SimpleOpen_1, 4, /* Elements count */ &asn_SPC_SimpleOpen_specs_1 /* Additional specs */ diff --git a/libs/smux/SimpleSyntax.c b/libs/smux/SimpleSyntax.c index b2a385b4..6a3fc678 100644 --- a/libs/smux/SimpleSyntax.c +++ b/libs/smux/SimpleSyntax.c @@ -1,83 +1,86 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1155-SMI" * found in "RFC1155-SMI.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #include "SimpleSyntax.h" -static asn_TYPE_member_t asn_MBR_SimpleSyntax_1[] = { +static asn_oer_constraints_t asn_OER_type_SimpleSyntax_constr_1 CC_NOTUSED = { + { 0, 0 }, + -1}; +asn_per_constraints_t asn_PER_type_SimpleSyntax_constr_1 CC_NOTUSED = { + { APC_CONSTRAINED, 2, 2, 0, 3 } /* (0..3) */, + { APC_UNCONSTRAINED, -1, -1, 0, 0 }, + 0, 0 /* No PER value map */ +}; +asn_TYPE_member_t asn_MBR_SimpleSyntax_1[] = { { ATF_NOFLAGS, 0, offsetof(struct SimpleSyntax, choice.number), (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, &asn_DEF_INTEGER, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "number" }, { ATF_NOFLAGS, 0, offsetof(struct SimpleSyntax, choice.string), (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), 0, &asn_DEF_OCTET_STRING, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "string" }, { ATF_NOFLAGS, 0, offsetof(struct SimpleSyntax, choice.object), (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)), 0, &asn_DEF_OBJECT_IDENTIFIER, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "object" }, { ATF_NOFLAGS, 0, offsetof(struct SimpleSyntax, choice.empty), (ASN_TAG_CLASS_UNIVERSAL | (5 << 2)), 0, &asn_DEF_NULL, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "empty" }, }; +static const unsigned asn_MAP_SimpleSyntax_to_canonical_1[] = { 0, 1, 3, 2 }; +static const unsigned asn_MAP_SimpleSyntax_from_canonical_1[] = { 0, 1, 3, 2 }; static const asn_TYPE_tag2member_t asn_MAP_SimpleSyntax_tag2el_1[] = { { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 0 }, /* number */ { (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), 1, 0, 0 }, /* string */ { (ASN_TAG_CLASS_UNIVERSAL | (5 << 2)), 3, 0, 0 }, /* empty */ { (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)), 2, 0, 0 } /* object */ }; -static asn_CHOICE_specifics_t asn_SPC_SimpleSyntax_specs_1 = { +asn_CHOICE_specifics_t asn_SPC_SimpleSyntax_specs_1 = { sizeof(struct SimpleSyntax), offsetof(struct SimpleSyntax, _asn_ctx), offsetof(struct SimpleSyntax, present), sizeof(((struct SimpleSyntax *)0)->present), asn_MAP_SimpleSyntax_tag2el_1, 4, /* Count of tags in the map */ - 0, + asn_MAP_SimpleSyntax_to_canonical_1, + asn_MAP_SimpleSyntax_from_canonical_1, -1 /* Extensions start */ }; asn_TYPE_descriptor_t asn_DEF_SimpleSyntax = { "SimpleSyntax", "SimpleSyntax", - CHOICE_free, - CHOICE_print, - CHOICE_constraint, - CHOICE_decode_ber, - CHOICE_encode_der, - CHOICE_decode_xer, - CHOICE_encode_xer, - 0, 0, /* No PER support, use "-gen-PER" to enable */ - CHOICE_outmost_tag, + &asn_OP_CHOICE, 0, /* No effective tags (pointer) */ 0, /* No effective tags (count) */ 0, /* No tags (pointer) */ 0, /* No tags (count) */ - 0, /* No PER visible constraints */ + { &asn_OER_type_SimpleSyntax_constr_1, &asn_PER_type_SimpleSyntax_constr_1, CHOICE_constraint }, asn_MBR_SimpleSyntax_1, 4, /* Elements count */ &asn_SPC_SimpleSyntax_specs_1 /* Additional specs */ diff --git a/libs/smux/TcpConnEntry.c b/libs/smux/TcpConnEntry.c index 994baa29..1f6e0d61 100644 --- a/libs/smux/TcpConnEntry.c +++ b/libs/smux/TcpConnEntry.c @@ -1,14 +1,14 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1213-MIB" * found in "RFC1213-MIB.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #include "TcpConnEntry.h" static int -memb_tcpConnLocalPort_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr, +memb_tcpConnLocalPort_constraint_1(const asn_TYPE_descriptor_t *td, const void *sptr, asn_app_constraint_failed_f *ctfailcb, void *app_key) { long value; @@ -33,7 +33,7 @@ memb_tcpConnLocalPort_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr, } static int -memb_tcpConnRemPort_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr, +memb_tcpConnRemPort_constraint_1(const asn_TYPE_descriptor_t *td, const void *sptr, asn_app_constraint_failed_f *ctfailcb, void *app_key) { long value; @@ -57,50 +57,66 @@ memb_tcpConnRemPort_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr, } } +static asn_oer_constraints_t asn_OER_memb_tcpConnLocalPort_constr_4 CC_NOTUSED = { + { 2, 1 } /* (0..65535) */, + -1}; +static asn_per_constraints_t asn_PER_memb_tcpConnLocalPort_constr_4 CC_NOTUSED = { + { APC_CONSTRAINED, 16, 16, 0, 65535 } /* (0..65535) */, + { APC_UNCONSTRAINED, -1, -1, 0, 0 }, + 0, 0 /* No PER value map */ +}; +static asn_oer_constraints_t asn_OER_memb_tcpConnRemPort_constr_6 CC_NOTUSED = { + { 2, 1 } /* (0..65535) */, + -1}; +static asn_per_constraints_t asn_PER_memb_tcpConnRemPort_constr_6 CC_NOTUSED = { + { APC_CONSTRAINED, 16, 16, 0, 65535 } /* (0..65535) */, + { APC_UNCONSTRAINED, -1, -1, 0, 0 }, + 0, 0 /* No PER value map */ +}; static asn_TYPE_member_t asn_MBR_TcpConnEntry_1[] = { { ATF_NOFLAGS, 0, offsetof(struct TcpConnEntry, tcpConnState), (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, &asn_DEF_INTEGER, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "tcpConnState" }, { ATF_NOFLAGS, 0, offsetof(struct TcpConnEntry, tcpConnLocalAddress), (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 0, &asn_DEF_IpAddress, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "tcpConnLocalAddress" }, { ATF_NOFLAGS, 0, offsetof(struct TcpConnEntry, tcpConnLocalPort), (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, &asn_DEF_NativeInteger, - memb_tcpConnLocalPort_constraint_1, - 0, /* PER is not compiled, use -gen-PER */ 0, + { &asn_OER_memb_tcpConnLocalPort_constr_4, &asn_PER_memb_tcpConnLocalPort_constr_4, memb_tcpConnLocalPort_constraint_1 }, + 0, 0, /* No default value */ "tcpConnLocalPort" }, { ATF_NOFLAGS, 0, offsetof(struct TcpConnEntry, tcpConnRemAddress), (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 0, &asn_DEF_IpAddress, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "tcpConnRemAddress" }, { ATF_NOFLAGS, 0, offsetof(struct TcpConnEntry, tcpConnRemPort), (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, &asn_DEF_NativeInteger, - memb_tcpConnRemPort_constraint_1, - 0, /* PER is not compiled, use -gen-PER */ 0, + { &asn_OER_memb_tcpConnRemPort_constr_6, &asn_PER_memb_tcpConnRemPort_constr_6, memb_tcpConnRemPort_constraint_1 }, + 0, 0, /* No default value */ "tcpConnRemPort" }, }; @@ -120,28 +136,19 @@ static asn_SEQUENCE_specifics_t asn_SPC_TcpConnEntry_specs_1 = { asn_MAP_TcpConnEntry_tag2el_1, 5, /* Count of tags in the map */ 0, 0, 0, /* Optional elements (not needed) */ - -1, /* Start extensions */ - -1 /* Stop extensions */ + -1, /* First extension addition */ }; asn_TYPE_descriptor_t asn_DEF_TcpConnEntry = { "TcpConnEntry", "TcpConnEntry", - SEQUENCE_free, - SEQUENCE_print, - SEQUENCE_constraint, - SEQUENCE_decode_ber, - SEQUENCE_encode_der, - SEQUENCE_decode_xer, - SEQUENCE_encode_xer, - 0, 0, /* No PER support, use "-gen-PER" to enable */ - 0, /* Use generic outmost tag fetcher */ + &asn_OP_SEQUENCE, asn_DEF_TcpConnEntry_tags_1, sizeof(asn_DEF_TcpConnEntry_tags_1) /sizeof(asn_DEF_TcpConnEntry_tags_1[0]), /* 1 */ asn_DEF_TcpConnEntry_tags_1, /* Same as above */ sizeof(asn_DEF_TcpConnEntry_tags_1) /sizeof(asn_DEF_TcpConnEntry_tags_1[0]), /* 1 */ - 0, /* No PER visible constraints */ + { 0, 0, SEQUENCE_constraint }, asn_MBR_TcpConnEntry_1, 5, /* Elements count */ &asn_SPC_TcpConnEntry_specs_1 /* Additional specs */ diff --git a/libs/smux/TimeTicks.c b/libs/smux/TimeTicks.c index b1aa1130..74cac1ee 100644 --- a/libs/smux/TimeTicks.c +++ b/libs/smux/TimeTicks.c @@ -1,14 +1,14 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1155-SMI" * found in "RFC1155-SMI.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #include "TimeTicks.h" int -TimeTicks_constraint(asn_TYPE_descriptor_t *td, const void *sptr, +TimeTicks_constraint(const asn_TYPE_descriptor_t *td, const void *sptr, asn_app_constraint_failed_f *ctfailcb, void *app_key) { if(!sptr) { @@ -27,69 +27,15 @@ TimeTicks_constraint(asn_TYPE_descriptor_t *td, const void *sptr, * This type is implemented using NativeInteger, * so here we adjust the DEF accordingly. */ -static void -TimeTicks_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) { - td->free_struct = asn_DEF_NativeInteger.free_struct; - td->print_struct = asn_DEF_NativeInteger.print_struct; - td->check_constraints = asn_DEF_NativeInteger.check_constraints; - td->ber_decoder = asn_DEF_NativeInteger.ber_decoder; - td->der_encoder = asn_DEF_NativeInteger.der_encoder; - td->xer_decoder = asn_DEF_NativeInteger.xer_decoder; - td->xer_encoder = asn_DEF_NativeInteger.xer_encoder; - td->uper_decoder = asn_DEF_NativeInteger.uper_decoder; - td->uper_encoder = asn_DEF_NativeInteger.uper_encoder; - if(!td->per_constraints) - td->per_constraints = asn_DEF_NativeInteger.per_constraints; - td->elements = asn_DEF_NativeInteger.elements; - td->elements_count = asn_DEF_NativeInteger.elements_count; - /* td->specifics = asn_DEF_NativeInteger.specifics; // Defined explicitly */ -} - -void -TimeTicks_free(asn_TYPE_descriptor_t *td, - void *struct_ptr, int contents_only) { - TimeTicks_1_inherit_TYPE_descriptor(td); - td->free_struct(td, struct_ptr, contents_only); -} - -int -TimeTicks_print(asn_TYPE_descriptor_t *td, const void *struct_ptr, - int ilevel, asn_app_consume_bytes_f *cb, void *app_key) { - TimeTicks_1_inherit_TYPE_descriptor(td); - return td->print_struct(td, struct_ptr, ilevel, cb, app_key); -} - -asn_dec_rval_t -TimeTicks_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, - void **structure, const void *bufptr, size_t size, int tag_mode) { - TimeTicks_1_inherit_TYPE_descriptor(td); - return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode); -} - -asn_enc_rval_t -TimeTicks_encode_der(asn_TYPE_descriptor_t *td, - void *structure, int tag_mode, ber_tlv_tag_t tag, - asn_app_consume_bytes_f *cb, void *app_key) { - TimeTicks_1_inherit_TYPE_descriptor(td); - return td->der_encoder(td, structure, tag_mode, tag, cb, app_key); -} - -asn_dec_rval_t -TimeTicks_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, - void **structure, const char *opt_mname, const void *bufptr, size_t size) { - TimeTicks_1_inherit_TYPE_descriptor(td); - return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size); -} - -asn_enc_rval_t -TimeTicks_encode_xer(asn_TYPE_descriptor_t *td, void *structure, - int ilevel, enum xer_encoder_flags_e flags, - asn_app_consume_bytes_f *cb, void *app_key) { - TimeTicks_1_inherit_TYPE_descriptor(td); - return td->xer_encoder(td, structure, ilevel, flags, cb, app_key); -} - -static const asn_INTEGER_specifics_t asn_SPC_TimeTicks_specs_1 = { +static asn_oer_constraints_t asn_OER_type_TimeTicks_constr_1 CC_NOTUSED = { + { 4, 1 } /* (0..4294967295) */, + -1}; +asn_per_constraints_t asn_PER_type_TimeTicks_constr_1 CC_NOTUSED = { + { APC_CONSTRAINED, 32, -1, 0, 4294967295 } /* (0..4294967295) */, + { APC_UNCONSTRAINED, -1, -1, 0, 0 }, + 0, 0 /* No PER value map */ +}; +const asn_INTEGER_specifics_t asn_SPC_TimeTicks_specs_1 = { 0, 0, 0, 0, 0, 0, /* Native long size */ 1 /* Unsigned representation */ @@ -101,22 +47,14 @@ static const ber_tlv_tag_t asn_DEF_TimeTicks_tags_1[] = { asn_TYPE_descriptor_t asn_DEF_TimeTicks = { "TimeTicks", "TimeTicks", - TimeTicks_free, - TimeTicks_print, - TimeTicks_constraint, - TimeTicks_decode_ber, - TimeTicks_encode_der, - TimeTicks_decode_xer, - TimeTicks_encode_xer, - 0, 0, /* No PER support, use "-gen-PER" to enable */ - 0, /* Use generic outmost tag fetcher */ + &asn_OP_NativeInteger, asn_DEF_TimeTicks_tags_1, sizeof(asn_DEF_TimeTicks_tags_1) /sizeof(asn_DEF_TimeTicks_tags_1[0]) - 1, /* 1 */ asn_DEF_TimeTicks_tags_1, /* Same as above */ sizeof(asn_DEF_TimeTicks_tags_1) /sizeof(asn_DEF_TimeTicks_tags_1[0]), /* 2 */ - 0, /* No PER visible constraints */ + { &asn_OER_type_TimeTicks_constr_1, &asn_PER_type_TimeTicks_constr_1, TimeTicks_constraint }, 0, 0, /* No members */ &asn_SPC_TimeTicks_specs_1 /* Additional specs */ }; diff --git a/libs/smux/Trap-PDU.c b/libs/smux/Trap-PDU.c index 4c1b44dc..5ea27c19 100644 --- a/libs/smux/Trap-PDU.c +++ b/libs/smux/Trap-PDU.c @@ -1,65 +1,65 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1157-SNMP" * found in "RFC1157-SNMP.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #include "Trap-PDU.h" -static asn_TYPE_member_t asn_MBR_Trap_PDU_1[] = { +asn_TYPE_member_t asn_MBR_Trap_PDU_1[] = { { ATF_NOFLAGS, 0, offsetof(struct Trap_PDU, enterprise), (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)), 0, &asn_DEF_OBJECT_IDENTIFIER, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "enterprise" }, { ATF_NOFLAGS, 0, offsetof(struct Trap_PDU, agent_addr), -1 /* Ambiguous tag (CHOICE?) */, 0, &asn_DEF_NetworkAddress, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "agent-addr" }, { ATF_NOFLAGS, 0, offsetof(struct Trap_PDU, generic_trap), (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, &asn_DEF_INTEGER, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "generic-trap" }, { ATF_NOFLAGS, 0, offsetof(struct Trap_PDU, specific_trap), (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, &asn_DEF_INTEGER, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "specific-trap" }, { ATF_NOFLAGS, 0, offsetof(struct Trap_PDU, time_stamp), (ASN_TAG_CLASS_APPLICATION | (3 << 2)), 0, &asn_DEF_TimeTicks, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "time-stamp" }, { ATF_NOFLAGS, 0, offsetof(struct Trap_PDU, variable_bindings), (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)), 0, &asn_DEF_VarBindList, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "variable-bindings" }, }; @@ -75,34 +75,25 @@ static const asn_TYPE_tag2member_t asn_MAP_Trap_PDU_tag2el_1[] = { { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 1, 0, 0 }, /* internet */ { (ASN_TAG_CLASS_APPLICATION | (3 << 2)), 4, 0, 0 } /* time-stamp */ }; -static asn_SEQUENCE_specifics_t asn_SPC_Trap_PDU_specs_1 = { +asn_SEQUENCE_specifics_t asn_SPC_Trap_PDU_specs_1 = { sizeof(struct Trap_PDU), offsetof(struct Trap_PDU, _asn_ctx), asn_MAP_Trap_PDU_tag2el_1, 6, /* Count of tags in the map */ 0, 0, 0, /* Optional elements (not needed) */ - -1, /* Start extensions */ - -1 /* Stop extensions */ + -1, /* First extension addition */ }; asn_TYPE_descriptor_t asn_DEF_Trap_PDU = { "Trap-PDU", "Trap-PDU", - SEQUENCE_free, - SEQUENCE_print, - SEQUENCE_constraint, - SEQUENCE_decode_ber, - SEQUENCE_encode_der, - SEQUENCE_decode_xer, - SEQUENCE_encode_xer, - 0, 0, /* No PER support, use "-gen-PER" to enable */ - 0, /* Use generic outmost tag fetcher */ + &asn_OP_SEQUENCE, asn_DEF_Trap_PDU_tags_1, sizeof(asn_DEF_Trap_PDU_tags_1) /sizeof(asn_DEF_Trap_PDU_tags_1[0]) - 1, /* 1 */ asn_DEF_Trap_PDU_tags_1, /* Same as above */ sizeof(asn_DEF_Trap_PDU_tags_1) /sizeof(asn_DEF_Trap_PDU_tags_1[0]), /* 2 */ - 0, /* No PER visible constraints */ + { 0, 0, SEQUENCE_constraint }, asn_MBR_Trap_PDU_1, 6, /* Elements count */ &asn_SPC_Trap_PDU_specs_1 /* Additional specs */ diff --git a/libs/smux/UdpEntry.c b/libs/smux/UdpEntry.c index d4c85a38..ce2c10a7 100644 --- a/libs/smux/UdpEntry.c +++ b/libs/smux/UdpEntry.c @@ -1,14 +1,14 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1213-MIB" * found in "RFC1213-MIB.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #include "UdpEntry.h" static int -memb_udpLocalPort_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr, +memb_udpLocalPort_constraint_1(const asn_TYPE_descriptor_t *td, const void *sptr, asn_app_constraint_failed_f *ctfailcb, void *app_key) { long value; @@ -32,23 +32,31 @@ memb_udpLocalPort_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr, } } +static asn_oer_constraints_t asn_OER_memb_udpLocalPort_constr_3 CC_NOTUSED = { + { 2, 1 } /* (0..65535) */, + -1}; +static asn_per_constraints_t asn_PER_memb_udpLocalPort_constr_3 CC_NOTUSED = { + { APC_CONSTRAINED, 16, 16, 0, 65535 } /* (0..65535) */, + { APC_UNCONSTRAINED, -1, -1, 0, 0 }, + 0, 0 /* No PER value map */ +}; static asn_TYPE_member_t asn_MBR_UdpEntry_1[] = { { ATF_NOFLAGS, 0, offsetof(struct UdpEntry, udpLocalAddress), (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 0, &asn_DEF_IpAddress, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "udpLocalAddress" }, { ATF_NOFLAGS, 0, offsetof(struct UdpEntry, udpLocalPort), (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, &asn_DEF_NativeInteger, - memb_udpLocalPort_constraint_1, - 0, /* PER is not compiled, use -gen-PER */ 0, + { &asn_OER_memb_udpLocalPort_constr_3, &asn_PER_memb_udpLocalPort_constr_3, memb_udpLocalPort_constraint_1 }, + 0, 0, /* No default value */ "udpLocalPort" }, }; @@ -65,28 +73,19 @@ static asn_SEQUENCE_specifics_t asn_SPC_UdpEntry_specs_1 = { asn_MAP_UdpEntry_tag2el_1, 2, /* Count of tags in the map */ 0, 0, 0, /* Optional elements (not needed) */ - -1, /* Start extensions */ - -1 /* Stop extensions */ + -1, /* First extension addition */ }; asn_TYPE_descriptor_t asn_DEF_UdpEntry = { "UdpEntry", "UdpEntry", - SEQUENCE_free, - SEQUENCE_print, - SEQUENCE_constraint, - SEQUENCE_decode_ber, - SEQUENCE_encode_der, - SEQUENCE_decode_xer, - SEQUENCE_encode_xer, - 0, 0, /* No PER support, use "-gen-PER" to enable */ - 0, /* Use generic outmost tag fetcher */ + &asn_OP_SEQUENCE, asn_DEF_UdpEntry_tags_1, sizeof(asn_DEF_UdpEntry_tags_1) /sizeof(asn_DEF_UdpEntry_tags_1[0]), /* 1 */ asn_DEF_UdpEntry_tags_1, /* Same as above */ sizeof(asn_DEF_UdpEntry_tags_1) /sizeof(asn_DEF_UdpEntry_tags_1[0]), /* 1 */ - 0, /* No PER visible constraints */ + { 0, 0, SEQUENCE_constraint }, asn_MBR_UdpEntry_1, 2, /* Elements count */ &asn_SPC_UdpEntry_specs_1 /* Additional specs */ diff --git a/libs/smux/VarBind.c b/libs/smux/VarBind.c index 047337f3..49d3cfc5 100644 --- a/libs/smux/VarBind.c +++ b/libs/smux/VarBind.c @@ -1,29 +1,29 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1157-SNMP" * found in "RFC1157-SNMP.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #include "VarBind.h" -static asn_TYPE_member_t asn_MBR_VarBind_1[] = { +asn_TYPE_member_t asn_MBR_VarBind_1[] = { { ATF_NOFLAGS, 0, offsetof(struct VarBind, name), (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)), 0, &asn_DEF_ObjectName, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "name" }, { ATF_NOFLAGS, 0, offsetof(struct VarBind, value), -1 /* Ambiguous tag (CHOICE?) */, 0, &asn_DEF_ObjectSyntax, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "value" }, }; @@ -42,34 +42,25 @@ static const asn_TYPE_tag2member_t asn_MAP_VarBind_tag2el_1[] = { { (ASN_TAG_CLASS_APPLICATION | (3 << 2)), 1, 0, 0 }, /* ticks */ { (ASN_TAG_CLASS_APPLICATION | (4 << 2)), 1, 0, 0 } /* arbitrary */ }; -static asn_SEQUENCE_specifics_t asn_SPC_VarBind_specs_1 = { +asn_SEQUENCE_specifics_t asn_SPC_VarBind_specs_1 = { sizeof(struct VarBind), offsetof(struct VarBind, _asn_ctx), asn_MAP_VarBind_tag2el_1, 10, /* Count of tags in the map */ 0, 0, 0, /* Optional elements (not needed) */ - -1, /* Start extensions */ - -1 /* Stop extensions */ + -1, /* First extension addition */ }; asn_TYPE_descriptor_t asn_DEF_VarBind = { "VarBind", "VarBind", - SEQUENCE_free, - SEQUENCE_print, - SEQUENCE_constraint, - SEQUENCE_decode_ber, - SEQUENCE_encode_der, - SEQUENCE_decode_xer, - SEQUENCE_encode_xer, - 0, 0, /* No PER support, use "-gen-PER" to enable */ - 0, /* Use generic outmost tag fetcher */ + &asn_OP_SEQUENCE, asn_DEF_VarBind_tags_1, sizeof(asn_DEF_VarBind_tags_1) /sizeof(asn_DEF_VarBind_tags_1[0]), /* 1 */ asn_DEF_VarBind_tags_1, /* Same as above */ sizeof(asn_DEF_VarBind_tags_1) /sizeof(asn_DEF_VarBind_tags_1[0]), /* 1 */ - 0, /* No PER visible constraints */ + { 0, 0, SEQUENCE_constraint }, asn_MBR_VarBind_1, 2, /* Elements count */ &asn_SPC_VarBind_specs_1 /* Additional specs */ diff --git a/libs/smux/VarBindList.c b/libs/smux/VarBindList.c index d84026e1..2f970016 100644 --- a/libs/smux/VarBindList.c +++ b/libs/smux/VarBindList.c @@ -1,27 +1,27 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1157-SNMP" * found in "RFC1157-SNMP.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #include "VarBindList.h" -static asn_TYPE_member_t asn_MBR_VarBindList_1[] = { +asn_TYPE_member_t asn_MBR_VarBindList_1[] = { { ATF_POINTER, 0, 0, (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)), 0, &asn_DEF_VarBind, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ "" }, }; static const ber_tlv_tag_t asn_DEF_VarBindList_tags_1[] = { (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)) }; -static asn_SET_OF_specifics_t asn_SPC_VarBindList_specs_1 = { +asn_SET_OF_specifics_t asn_SPC_VarBindList_specs_1 = { sizeof(struct VarBindList), offsetof(struct VarBindList, _asn_ctx), 0, /* XER encoding is XMLDelimitedItemList */ @@ -29,22 +29,14 @@ static asn_SET_OF_specifics_t asn_SPC_VarBindList_specs_1 = { asn_TYPE_descriptor_t asn_DEF_VarBindList = { "VarBindList", "VarBindList", - SEQUENCE_OF_free, - SEQUENCE_OF_print, - SEQUENCE_OF_constraint, - SEQUENCE_OF_decode_ber, - SEQUENCE_OF_encode_der, - SEQUENCE_OF_decode_xer, - SEQUENCE_OF_encode_xer, - 0, 0, /* No PER support, use "-gen-PER" to enable */ - 0, /* Use generic outmost tag fetcher */ + &asn_OP_SEQUENCE_OF, asn_DEF_VarBindList_tags_1, sizeof(asn_DEF_VarBindList_tags_1) /sizeof(asn_DEF_VarBindList_tags_1[0]), /* 1 */ asn_DEF_VarBindList_tags_1, /* Same as above */ sizeof(asn_DEF_VarBindList_tags_1) /sizeof(asn_DEF_VarBindList_tags_1[0]), /* 1 */ - 0, /* No PER visible constraints */ + { 0, 0, SEQUENCE_OF_constraint }, asn_MBR_VarBindList_1, 1, /* Single element */ &asn_SPC_VarBindList_specs_1 /* Additional specs */ diff --git a/libs/smux/asn_application.c b/libs/smux/asn_application.c new file mode 100644 index 00000000..8ce0261b --- /dev/null +++ b/libs/smux/asn_application.c @@ -0,0 +1,440 @@ +/* + * Copyright (c) 2017 Lev Walkin . All rights reserved. + * Redistribution and modifications are permitted subject to BSD license. + */ +#include +#include +#include + +static asn_enc_rval_t asn_encode_internal(const asn_codec_ctx_t *opt_codec_ctx, + enum asn_transfer_syntax syntax, + const asn_TYPE_descriptor_t *td, + const void *sptr, + asn_app_consume_bytes_f *callback, + void *callback_key); + + +struct callback_count_bytes_key { + asn_app_consume_bytes_f *callback; + void *callback_key; + size_t computed_size; +}; + +/* + * Encoder which just counts bytes that come through it. + */ +static int +callback_count_bytes_cb(const void *data, size_t size, void *keyp) { + struct callback_count_bytes_key *key = keyp; + int ret; + + ret = key->callback(data, size, key->callback_key); + if(ret >= 0) { + key->computed_size += size; + } + + return ret; +} + +struct overrun_encoder_key { + void *buffer; + size_t buffer_size; + size_t computed_size; +}; + +struct dynamic_encoder_key { + void *buffer; + size_t buffer_size; + size_t computed_size; +}; + +struct callback_failure_catch_key { + asn_app_consume_bytes_f *callback; + void *callback_key; + int callback_failed; +}; + +/* + * Encoder which doesn't stop counting bytes + * even if it reaches the end of the buffer. + */ +static int +overrun_encoder_cb(const void *data, size_t size, void *keyp) { + struct overrun_encoder_key *key = keyp; + + if(key->computed_size + size > key->buffer_size) { + /* + * Avoid accident on the next call: + * stop adding bytes to the buffer. + */ + key->buffer_size = 0; + } else { + memcpy((char *)key->buffer + key->computed_size, data, size); + } + key->computed_size += size; + + return 0; +} + +/* + * Encoder which dynamically allocates output, and continues + * to count even if allocation failed. + */ +static int +dynamic_encoder_cb(const void *data, size_t size, void *keyp) { + struct dynamic_encoder_key *key = keyp; + + if(key->buffer) { + if(key->computed_size + size >= key->buffer_size) { + void *p; + size_t new_size = key->buffer_size; + + do { + new_size *= 2; + } while(new_size <= key->computed_size + size); + + p = REALLOC(key->buffer, new_size); + if(p) { + key->buffer = p; + key->buffer_size = new_size; + } else { + FREEMEM(key->buffer); + key->buffer = 0; + key->buffer_size = 0; + key->computed_size += size; + return 0; + } + } + memcpy((char *)key->buffer + key->computed_size, data, size); + } + + key->computed_size += size; + + return 0; +} + +/* + * Encoder which help convert the application level encoder failure into EIO. + */ +static int +callback_failure_catch_cb(const void *data, size_t size, void *keyp) { + struct callback_failure_catch_key *key = keyp; + int ret; + + ret = key->callback(data, size, key->callback_key); + if(ret < 0) { + key->callback_failed = 1; + } + + return ret; +} + +asn_enc_rval_t +asn_encode(const asn_codec_ctx_t *opt_codec_ctx, + enum asn_transfer_syntax syntax, const asn_TYPE_descriptor_t *td, + const void *sptr, asn_app_consume_bytes_f *callback, void *callback_key) { + struct callback_failure_catch_key cb_key; + asn_enc_rval_t er; + + if(!callback) { + errno = EINVAL; + ASN__ENCODE_FAILED; + } + + cb_key.callback = callback; + cb_key.callback_key = callback_key; + cb_key.callback_failed = 0; + + er = asn_encode_internal(opt_codec_ctx, syntax, td, sptr, + callback_failure_catch_cb, &cb_key); + if(cb_key.callback_failed) { + assert(er.encoded == -1); + assert(errno == EBADF); + errno = EIO; + } + + return er; +} + +asn_enc_rval_t +asn_encode_to_buffer(const asn_codec_ctx_t *opt_codec_ctx, + enum asn_transfer_syntax syntax, + const asn_TYPE_descriptor_t *td, const void *sptr, + void *buffer, size_t buffer_size) { + struct overrun_encoder_key buf_key; + asn_enc_rval_t er; + + if(buffer_size > 0 && !buffer) { + errno = EINVAL; + ASN__ENCODE_FAILED; + } + + buf_key.buffer = buffer; + buf_key.buffer_size = buffer_size; + buf_key.computed_size = 0; + + er = asn_encode_internal(opt_codec_ctx, syntax, td, sptr, + overrun_encoder_cb, &buf_key); + + if(er.encoded >= 0 && (size_t)er.encoded != buf_key.computed_size) { + ASN_DEBUG("asn_encode() returned %" ASN_PRI_SSIZE + " yet produced %" ASN_PRI_SIZE " bytes", + er.encoded, buf_key.computed_size); + assert(er.encoded < 0 || (size_t)er.encoded == buf_key.computed_size); + } + + return er; +} + +asn_encode_to_new_buffer_result_t +asn_encode_to_new_buffer(const asn_codec_ctx_t *opt_codec_ctx, + enum asn_transfer_syntax syntax, + const asn_TYPE_descriptor_t *td, const void *sptr) { + struct dynamic_encoder_key buf_key; + asn_encode_to_new_buffer_result_t res; + + buf_key.buffer_size = 16; + buf_key.buffer = MALLOC(buf_key.buffer_size); + buf_key.computed_size = 0; + + res.result = asn_encode_internal(opt_codec_ctx, syntax, td, sptr, + dynamic_encoder_cb, &buf_key); + + if(res.result.encoded >= 0 + && (size_t)res.result.encoded != buf_key.computed_size) { + ASN_DEBUG("asn_encode() returned %" ASN_PRI_SSIZE + " yet produced %" ASN_PRI_SIZE " bytes", + res.result.encoded, buf_key.computed_size); + assert(res.result.encoded < 0 + || (size_t)res.result.encoded == buf_key.computed_size); + } + + res.buffer = buf_key.buffer; + + /* 0-terminate just in case. */ + if(res.buffer) { + assert(buf_key.computed_size < buf_key.buffer_size); + ((char *)res.buffer)[buf_key.computed_size] = '\0'; + } + + return res; +} + +static asn_enc_rval_t +asn_encode_internal(const asn_codec_ctx_t *opt_codec_ctx, + enum asn_transfer_syntax syntax, + const asn_TYPE_descriptor_t *td, const void *sptr, + asn_app_consume_bytes_f *callback, void *callback_key) { + asn_enc_rval_t er; + enum xer_encoder_flags_e xer_flags = XER_F_CANONICAL; + + (void)opt_codec_ctx; /* Parameters are not checked on encode yet. */ + + if(!td || !sptr) { + errno = EINVAL; + ASN__ENCODE_FAILED; + } + + switch(syntax) { + case ATS_NONSTANDARD_PLAINTEXT: + if(td->op->print_struct) { + struct callback_count_bytes_key cb_key; + cb_key.callback = callback; + cb_key.callback_key = callback_key; + cb_key.computed_size = 0; + if(td->op->print_struct(td, sptr, 1, callback_count_bytes_cb, + &cb_key) + < 0 + || callback_count_bytes_cb("\n", 1, &cb_key) < 0) { + errno = EBADF; /* Structure has incorrect form. */ + er.encoded = -1; + er.failed_type = td; + er.structure_ptr = sptr; + } else { + er.encoded = cb_key.computed_size; + er.failed_type = 0; + er.structure_ptr = 0; + } + } else { + errno = ENOENT; /* Transfer syntax is not defined for this type. */ + ASN__ENCODE_FAILED; + } + break; + + case ATS_RANDOM: + errno = ENOENT; /* Randomization doesn't make sense on output. */ + ASN__ENCODE_FAILED; + + case ATS_BER: + /* BER is a superset of DER. */ + /* Fall through. */ + case ATS_DER: + if(td->op->der_encoder) { + er = der_encode(td, sptr, callback, callback_key); + if(er.encoded == -1) { + if(er.failed_type && er.failed_type->op->der_encoder) { + errno = EBADF; /* Structure has incorrect form. */ + } else { + errno = ENOENT; /* DER is not defined for this type. */ + } + } + } else { + errno = ENOENT; /* Transfer syntax is not defined for this type. */ + ASN__ENCODE_FAILED; + } + break; + case ATS_CER: + errno = ENOENT; /* Transfer syntax is not defined for any type. */ + ASN__ENCODE_FAILED; + +#ifdef ASN_DISABLE_OER_SUPPORT + case ATS_BASIC_OER: + case ATS_CANONICAL_OER: + errno = ENOENT; /* PER is not defined. */ + ASN__ENCODE_FAILED; + break; +#else /* ASN_DISABLE_OER_SUPPORT */ + case ATS_BASIC_OER: + /* CANONICAL-OER is a superset of BASIC-OER. */ + /* Fall through. */ + case ATS_CANONICAL_OER: + if(td->op->oer_encoder) { + er = oer_encode(td, sptr, callback, callback_key); + if(er.encoded == -1) { + if(er.failed_type && er.failed_type->op->oer_encoder) { + errno = EBADF; /* Structure has incorrect form. */ + } else { + errno = ENOENT; /* OER is not defined for this type. */ + } + } + } else { + errno = ENOENT; /* Transfer syntax is not defined for this type. */ + ASN__ENCODE_FAILED; + } + break; +#endif /* ASN_DISABLE_OER_SUPPORT */ + +#ifdef ASN_DISABLE_PER_SUPPORT + case ATS_UNALIGNED_BASIC_PER: + case ATS_UNALIGNED_CANONICAL_PER: + errno = ENOENT; /* PER is not defined. */ + ASN__ENCODE_FAILED; + break; +#else /* ASN_DISABLE_PER_SUPPORT */ + case ATS_UNALIGNED_BASIC_PER: + /* CANONICAL-UPER is a superset of BASIC-UPER. */ + /* Fall through. */ + case ATS_UNALIGNED_CANONICAL_PER: + if(td->op->uper_encoder) { + er = uper_encode(td, 0, sptr, callback, callback_key); + if(er.encoded == -1) { + if(er.failed_type && er.failed_type->op->uper_encoder) { + errno = EBADF; /* Structure has incorrect form. */ + } else { + errno = ENOENT; /* UPER is not defined for this type. */ + } + } else { + ASN_DEBUG("Complete encoded in %ld bits", (long)er.encoded); + if(er.encoded == 0) { + /* Enforce "Complete Encoding" of X.691 #11.1 */ + if(callback("\0", 1, callback_key) < 0) { + errno = EBADF; + ASN__ENCODE_FAILED; + } + er.encoded = 8; /* Exactly 8 zero bits is added. */ + } + /* Convert bits into bytes */ + er.encoded = (er.encoded + 7) >> 3; + } + } else { + errno = ENOENT; /* Transfer syntax is not defined for this type. */ + ASN__ENCODE_FAILED; + } + break; +#endif /* ASN_DISABLE_PER_SUPPORT */ + + case ATS_BASIC_XER: + /* CANONICAL-XER is a superset of BASIC-XER. */ + xer_flags &= ~XER_F_CANONICAL; + xer_flags |= XER_F_BASIC; + /* Fall through. */ + case ATS_CANONICAL_XER: + if(td->op->xer_encoder) { + er = xer_encode(td, sptr, xer_flags, callback, callback_key); + if(er.encoded == -1) { + if(er.failed_type && er.failed_type->op->xer_encoder) { + errno = EBADF; /* Structure has incorrect form. */ + } else { + errno = ENOENT; /* XER is not defined for this type. */ + } + } + } else { + errno = ENOENT; /* Transfer syntax is not defined for this type. */ + ASN__ENCODE_FAILED; + } + break; + + default: + errno = ENOENT; + ASN__ENCODE_FAILED; + } + + return er; +} + +asn_dec_rval_t +asn_decode(const asn_codec_ctx_t *opt_codec_ctx, + enum asn_transfer_syntax syntax, const asn_TYPE_descriptor_t *td, + void **sptr, const void *buffer, size_t size) { + if(!td || !td->op || !sptr || (size && !buffer)) { + ASN__DECODE_FAILED; + } + + switch(syntax) { + case ATS_CER: + case ATS_NONSTANDARD_PLAINTEXT: + default: + errno = ENOENT; + ASN__DECODE_FAILED; + + case ATS_RANDOM: + if(!td->op->random_fill) { + ASN__DECODE_FAILED; + } else { + if(asn_random_fill(td, sptr, 16000) == 0) { + asn_dec_rval_t ret = {RC_OK, 0}; + return ret; + } else { + ASN__DECODE_FAILED; + } + } + break; + + case ATS_DER: + case ATS_BER: + return ber_decode(opt_codec_ctx, td, sptr, buffer, size); + + case ATS_BASIC_OER: + case ATS_CANONICAL_OER: +#ifdef ASN_DISABLE_OER_SUPPORT + errno = ENOENT; + ASN__DECODE_FAILED; +#else + return oer_decode(opt_codec_ctx, td, sptr, buffer, size); +#endif + + case ATS_UNALIGNED_BASIC_PER: + case ATS_UNALIGNED_CANONICAL_PER: +#ifdef ASN_DISABLE_PER_SUPPORT + errno = ENOENT; + ASN__DECODE_FAILED; +#else + return uper_decode_complete(opt_codec_ctx, td, sptr, buffer, size); +#endif + + case ATS_BASIC_XER: + case ATS_CANONICAL_XER: + return xer_decode(opt_codec_ctx, td, sptr, buffer, size); + } +} + diff --git a/libs/smux/asn_bit_data.c b/libs/smux/asn_bit_data.c new file mode 100644 index 00000000..fe4b89ba --- /dev/null +++ b/libs/smux/asn_bit_data.c @@ -0,0 +1,333 @@ +/* + * Copyright (c) 2005-2017 Lev Walkin . + * All rights reserved. + * Redistribution and modifications are permitted subject to BSD license. + */ +#include +#include +#include + +/* + * Create a contiguous non-refillable bit data structure. + * Can be freed by FREEMEM(). + */ +asn_bit_data_t * +asn_bit_data_new_contiguous(const void *data, size_t size_bits) { + size_t size_bytes = (size_bits + 7) / 8; + asn_bit_data_t *pd; + uint8_t *bytes; + + /* Get the extensions map */ + pd = CALLOC(1, sizeof(*pd) + size_bytes + 1); + if(!pd) { + return NULL; + } + bytes = (void *)(((char *)pd) + sizeof(*pd)); + memcpy(bytes, data, size_bytes); + bytes[size_bytes] = 0; + pd->buffer = bytes; + pd->nboff = 0; + pd->nbits = size_bits; + + return pd; +} + + +char * +asn_bit_data_string(asn_bit_data_t *pd) { + static char buf[2][32]; + static int n; + n = (n+1) % 2; + snprintf(buf[n], sizeof(buf[n]), + "{m=%" ASN_PRI_SIZE " span %" ASN_PRI_SIZE "[%" ASN_PRI_SIZE + "..%" ASN_PRI_SIZE "] (%" ASN_PRI_SIZE ")}", + pd->moved, ((uintptr_t)(pd->buffer) & 0xf), pd->nboff, pd->nbits, + pd->nbits - pd->nboff); + return buf[n]; +} + +void +asn_get_undo(asn_bit_data_t *pd, int nbits) { + if((ssize_t)pd->nboff < nbits) { + assert((ssize_t)pd->nboff < nbits); + } else { + pd->nboff -= nbits; + pd->moved -= nbits; + } +} + +/* + * Extract a small number of bits (<= 31) from the specified PER data pointer. + */ +int32_t +asn_get_few_bits(asn_bit_data_t *pd, int nbits) { + size_t off; /* Next after last bit offset */ + ssize_t nleft; /* Number of bits left in this stream */ + uint32_t accum; + const uint8_t *buf; + + if(nbits < 0) + return -1; + + nleft = pd->nbits - pd->nboff; + if(nbits > nleft) { + int32_t tailv, vhead; + if(!pd->refill || nbits > 31) return -1; + /* Accumulate unused bytes before refill */ + ASN_DEBUG("Obtain the rest %d bits (want %d)", + (int)nleft, (int)nbits); + tailv = asn_get_few_bits(pd, nleft); + if(tailv < 0) return -1; + /* Refill (replace pd contents with new data) */ + if(pd->refill(pd)) + return -1; + nbits -= nleft; + vhead = asn_get_few_bits(pd, nbits); + /* Combine the rest of previous pd with the head of new one */ + tailv = (tailv << nbits) | vhead; /* Could == -1 */ + return tailv; + } + + /* + * Normalize position indicator. + */ + if(pd->nboff >= 8) { + pd->buffer += (pd->nboff >> 3); + pd->nbits -= (pd->nboff & ~0x07); + pd->nboff &= 0x07; + } + pd->moved += nbits; + pd->nboff += nbits; + off = pd->nboff; + buf = pd->buffer; + + /* + * Extract specified number of bits. + */ + if(off <= 8) + accum = nbits ? (buf[0]) >> (8 - off) : 0; + else if(off <= 16) + accum = ((buf[0] << 8) + buf[1]) >> (16 - off); + else if(off <= 24) + accum = ((buf[0] << 16) + (buf[1] << 8) + buf[2]) >> (24 - off); + else if(off <= 31) + accum = (((uint32_t)buf[0] << 24) + (buf[1] << 16) + + (buf[2] << 8) + (buf[3])) >> (32 - off); + else if(nbits <= 31) { + asn_bit_data_t tpd = *pd; + /* Here are we with our 31-bits limit plus 1..7 bits offset. */ + asn_get_undo(&tpd, nbits); + /* The number of available bits in the stream allow + * for the following operations to take place without + * invoking the ->refill() function */ + accum = asn_get_few_bits(&tpd, nbits - 24) << 24; + accum |= asn_get_few_bits(&tpd, 24); + } else { + asn_get_undo(pd, nbits); + return -1; + } + + accum &= (((uint32_t)1 << nbits) - 1); + + ASN_DEBUG(" [PER got %2d<=%2d bits => span %d %+ld[%d..%d]:%02x (%d) => 0x%x]", + (int)nbits, (int)nleft, + (int)pd->moved, + (((long)pd->buffer) & 0xf), + (int)pd->nboff, (int)pd->nbits, + ((pd->buffer != NULL)?pd->buffer[0]:0), + (int)(pd->nbits - pd->nboff), + (int)accum); + + return accum; +} + +/* + * Extract a large number of bits from the specified PER data pointer. + */ +int +asn_get_many_bits(asn_bit_data_t *pd, uint8_t *dst, int alright, int nbits) { + int32_t value; + + if(alright && (nbits & 7)) { + /* Perform right alignment of a first few bits */ + value = asn_get_few_bits(pd, nbits & 0x07); + if(value < 0) return -1; + *dst++ = value; /* value is already right-aligned */ + nbits &= ~7; + } + + while(nbits) { + if(nbits >= 24) { + value = asn_get_few_bits(pd, 24); + if(value < 0) return -1; + *(dst++) = value >> 16; + *(dst++) = value >> 8; + *(dst++) = value; + nbits -= 24; + } else { + value = asn_get_few_bits(pd, nbits); + if(value < 0) return -1; + if(nbits & 7) { /* implies left alignment */ + value <<= 8 - (nbits & 7), + nbits += 8 - (nbits & 7); + if(nbits > 24) + *dst++ = value >> 24; + } + if(nbits > 16) + *dst++ = value >> 16; + if(nbits > 8) + *dst++ = value >> 8; + *dst++ = value; + break; + } + } + + return 0; +} + +/* + * Put a small number of bits (<= 31). + */ +int +asn_put_few_bits(asn_bit_outp_t *po, uint32_t bits, int obits) { + size_t off; /* Next after last bit offset */ + size_t omsk; /* Existing last byte meaningful bits mask */ + uint8_t *buf; + + if(obits <= 0 || obits >= 32) return obits ? -1 : 0; + + ASN_DEBUG("[PER put %d bits %x to %p+%d bits]", + obits, (int)bits, (void *)po->buffer, (int)po->nboff); + + /* + * Normalize position indicator. + */ + if(po->nboff >= 8) { + po->buffer += (po->nboff >> 3); + po->nbits -= (po->nboff & ~0x07); + po->nboff &= 0x07; + } + + /* + * Flush whole-bytes output, if necessary. + */ + if(po->nboff + obits > po->nbits) { + size_t complete_bytes; + if(!po->buffer) po->buffer = po->tmpspace; + complete_bytes = (po->buffer - po->tmpspace); + ASN_DEBUG("[PER output %ld complete + %ld]", + (long)complete_bytes, (long)po->flushed_bytes); + if(po->output(po->tmpspace, complete_bytes, po->op_key) < 0) + return -1; + if(po->nboff) + po->tmpspace[0] = po->buffer[0]; + po->buffer = po->tmpspace; + po->nbits = 8 * sizeof(po->tmpspace); + po->flushed_bytes += complete_bytes; + } + + /* + * Now, due to sizeof(tmpspace), we are guaranteed large enough space. + */ + buf = po->buffer; + omsk = ~((1 << (8 - po->nboff)) - 1); + off = (po->nboff + obits); + + /* Clear data of debris before meaningful bits */ + bits &= (((uint32_t)1 << obits) - 1); + + ASN_DEBUG("[PER out %d %u/%x (t=%d,o=%d) %x&%x=%x]", obits, + (int)bits, (int)bits, + (int)po->nboff, (int)off, + buf[0], (int)(omsk&0xff), + (int)(buf[0] & omsk)); + + if(off <= 8) /* Completely within 1 byte */ + po->nboff = off, + bits <<= (8 - off), + buf[0] = (buf[0] & omsk) | bits; + else if(off <= 16) + po->nboff = off, + bits <<= (16 - off), + buf[0] = (buf[0] & omsk) | (bits >> 8), + buf[1] = bits; + else if(off <= 24) + po->nboff = off, + bits <<= (24 - off), + buf[0] = (buf[0] & omsk) | (bits >> 16), + buf[1] = bits >> 8, + buf[2] = bits; + else if(off <= 31) + po->nboff = off, + bits <<= (32 - off), + buf[0] = (buf[0] & omsk) | (bits >> 24), + buf[1] = bits >> 16, + buf[2] = bits >> 8, + buf[3] = bits; + else { + if(asn_put_few_bits(po, bits >> (obits - 24), 24)) return -1; + if(asn_put_few_bits(po, bits, obits - 24)) return -1; + } + + ASN_DEBUG("[PER out %u/%x => %02x buf+%ld]", + (int)bits, (int)bits, buf[0], + (long)(po->buffer - po->tmpspace)); + + return 0; +} + + +/* + * Output a large number of bits. + */ +int +asn_put_many_bits(asn_bit_outp_t *po, const uint8_t *src, int nbits) { + + while(nbits) { + uint32_t value; + + if(nbits >= 24) { + value = (src[0] << 16) | (src[1] << 8) | src[2]; + src += 3; + nbits -= 24; + if(asn_put_few_bits(po, value, 24)) + return -1; + } else { + value = src[0]; + if(nbits > 8) + value = (value << 8) | src[1]; + if(nbits > 16) + value = (value << 8) | src[2]; + if(nbits & 0x07) + value >>= (8 - (nbits & 0x07)); + if(asn_put_few_bits(po, value, nbits)) + return -1; + break; + } + } + + return 0; +} + + +int +asn_put_aligned_flush(asn_bit_outp_t *po) { + uint32_t unused_bits = (0x7 & (8 - (po->nboff & 0x07))); + size_t complete_bytes = + (po->buffer ? po->buffer - po->tmpspace : 0) + ((po->nboff + 7) >> 3); + + if(unused_bits) { + po->buffer[po->nboff >> 3] &= ~0u << unused_bits; + } + + if(po->output(po->tmpspace, complete_bytes, po->op_key) < 0) { + return -1; + } else { + po->buffer = po->tmpspace; + po->nboff = 0; + po->nbits = 8 * sizeof(po->tmpspace); + po->flushed_bytes += complete_bytes; + return 0; + } +} + diff --git a/libs/smux/asn_codecs_prim.c b/libs/smux/asn_codecs_prim.c index 426339c9..78448a8e 100644 --- a/libs/smux/asn_codecs_prim.c +++ b/libs/smux/asn_codecs_prim.c @@ -10,10 +10,10 @@ * Decode an always-primitive type. */ asn_dec_rval_t -ber_decode_primitive(asn_codec_ctx_t *opt_codec_ctx, - asn_TYPE_descriptor_t *td, - void **sptr, const void *buf_ptr, size_t size, int tag_mode) { - ASN__PRIMITIVE_TYPE_t *st = (ASN__PRIMITIVE_TYPE_t *)*sptr; +ber_decode_primitive(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *td, void **sptr, + const void *buf_ptr, size_t size, int tag_mode) { + ASN__PRIMITIVE_TYPE_t *st = (ASN__PRIMITIVE_TYPE_t *)*sptr; asn_dec_rval_t rval; ber_tlv_len_t length = 0; /* =0 to avoid [incorrect] warning. */ @@ -81,11 +81,11 @@ ber_decode_primitive(asn_codec_ctx_t *opt_codec_ctx, * Encode an always-primitive type using DER. */ asn_enc_rval_t -der_encode_primitive(asn_TYPE_descriptor_t *td, void *sptr, - int tag_mode, ber_tlv_tag_t tag, - asn_app_consume_bytes_f *cb, void *app_key) { - asn_enc_rval_t erval; - ASN__PRIMITIVE_TYPE_t *st = (ASN__PRIMITIVE_TYPE_t *)sptr; +der_encode_primitive(const asn_TYPE_descriptor_t *td, const void *sptr, + int tag_mode, ber_tlv_tag_t tag, + asn_app_consume_bytes_f *cb, void *app_key) { + asn_enc_rval_t erval; + const ASN__PRIMITIVE_TYPE_t *st = (const ASN__PRIMITIVE_TYPE_t *)sptr; ASN_DEBUG("%s %s as a primitive type (tm=%d)", cb?"Encoding":"Estimating", td->name, tag_mode); @@ -115,9 +115,9 @@ der_encode_primitive(asn_TYPE_descriptor_t *td, void *sptr, } void -ASN__PRIMITIVE_TYPE_free(asn_TYPE_descriptor_t *td, void *sptr, - int contents_only) { - ASN__PRIMITIVE_TYPE_t *st = (ASN__PRIMITIVE_TYPE_t *)sptr; +ASN__PRIMITIVE_TYPE_free(const asn_TYPE_descriptor_t *td, void *sptr, + enum asn_struct_free_method method) { + ASN__PRIMITIVE_TYPE_t *st = (ASN__PRIMITIVE_TYPE_t *)sptr; if(!td || !sptr) return; @@ -127,8 +127,16 @@ ASN__PRIMITIVE_TYPE_free(asn_TYPE_descriptor_t *td, void *sptr, if(st->buf) FREEMEM(st->buf); - if(!contents_only) - FREEMEM(st); + switch(method) { + case ASFM_FREE_EVERYTHING: + FREEMEM(sptr); + break; + case ASFM_FREE_UNDERLYING: + break; + case ASFM_FREE_UNDERLYING_AND_RESET: + memset(sptr, 0, sizeof(ASN__PRIMITIVE_TYPE_t)); + break; + } } @@ -136,8 +144,8 @@ ASN__PRIMITIVE_TYPE_free(asn_TYPE_descriptor_t *td, void *sptr, * Local internal type passed around as an argument. */ struct xdp_arg_s { - asn_TYPE_descriptor_t *type_descriptor; - void *struct_key; + const asn_TYPE_descriptor_t *type_descriptor; + void *struct_key; xer_primitive_body_decoder_f *prim_body_decoder; int decoded_something; int want_more; @@ -240,15 +248,12 @@ xer_decode__primitive_body(void *key, const void *chunk_buf, size_t chunk_size, asn_dec_rval_t -xer_decode_primitive(asn_codec_ctx_t *opt_codec_ctx, - asn_TYPE_descriptor_t *td, - void **sptr, - size_t struct_size, - const char *opt_mname, - const void *buf_ptr, size_t size, - xer_primitive_body_decoder_f *prim_body_decoder -) { - const char *xml_tag = opt_mname ? opt_mname : td->xml_tag; +xer_decode_primitive(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *td, void **sptr, + size_t struct_size, const char *opt_mname, + const void *buf_ptr, size_t size, + xer_primitive_body_decoder_f *prim_body_decoder) { + const char *xml_tag = opt_mname ? opt_mname : td->xml_tag; asn_struct_ctx_t s_ctx; struct xdp_arg_s s_arg; asn_dec_rval_t rc; diff --git a/libs/smux/asn_internal.c b/libs/smux/asn_internal.c new file mode 100644 index 00000000..91e537c4 --- /dev/null +++ b/libs/smux/asn_internal.c @@ -0,0 +1,47 @@ +#include + +ssize_t +asn__format_to_callback(int (*cb)(const void *, size_t, void *key), void *key, + const char *fmt, ...) { + char scratch[64]; + char *buf = scratch; + size_t buf_size = sizeof(scratch); + int wrote; + int cb_ret; + + do { + va_list args; + va_start(args, fmt); + + wrote = vsnprintf(buf, buf_size, fmt, args); + if(wrote < (ssize_t)buf_size) { + if(wrote < 0) { + if(buf != scratch) FREEMEM(buf); + return -1; + } + break; + } + + buf_size <<= 1; + if(buf == scratch) { + buf = MALLOC(buf_size); + if(!buf) return -1; + } else { + void *p = REALLOC(buf, buf_size); + if(!p) { + FREEMEM(buf); + return -1; + } + buf = p; + } + } while(1); + + cb_ret = cb(buf, wrote, key); + if(buf != scratch) FREEMEM(buf); + if(cb_ret < 0) { + return -1; + } + + return wrote; +} + diff --git a/libs/smux/asn_random_fill.c b/libs/smux/asn_random_fill.c new file mode 100644 index 00000000..819cf700 --- /dev/null +++ b/libs/smux/asn_random_fill.c @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2017 Lev Walkin . + * All rights reserved. + * Redistribution and modifications are permitted subject to BSD license. + */ +#include +#include +#include + +int +asn_random_fill(const struct asn_TYPE_descriptor_s *td, void **struct_ptr, + size_t length) { + + if(td && td->op->random_fill) { + asn_random_fill_result_t res = + td->op->random_fill(td, struct_ptr, 0, length); + return (res.code == ARFILL_OK) ? 0 : -1; + } else { + return -1; + } +} + +static uintmax_t +asn__intmax_range(intmax_t lb, intmax_t ub) { + assert(lb <= ub); + if((ub < 0) == (lb < 0)) { + return ub - lb; + } else if(lb < 0) { + return 1 + ((uintmax_t)ub + (uintmax_t)-(lb + 1)); + } else { + assert(!"Unreachable"); + return 0; + } +} + +intmax_t +asn_random_between(intmax_t lb, intmax_t rb) { + if(lb == rb) { + return lb; + } else { + const uintmax_t intmax_max = ((~(uintmax_t)0) >> 1); + uintmax_t range = asn__intmax_range(lb, rb); + uintmax_t value = 0; + uintmax_t got_entropy = 0; + + assert(RAND_MAX > 0xffffff); /* Seen 7ffffffd! */ + assert(range < intmax_max); + + for(; got_entropy < range;) { + got_entropy = (got_entropy << 24) | 0xffffff; + value = (value << 24) | (random() % 0xffffff); + } + + return lb + (intmax_t)(value % (range + 1)); + } +} diff --git a/libs/smux/ber_decoder.c b/libs/smux/ber_decoder.c index b3a6329e..75d60169 100644 --- a/libs/smux/ber_decoder.c +++ b/libs/smux/ber_decoder.c @@ -27,10 +27,10 @@ * The BER decoder of any type. */ asn_dec_rval_t -ber_decode(asn_codec_ctx_t *opt_codec_ctx, - asn_TYPE_descriptor_t *type_descriptor, - void **struct_ptr, const void *ptr, size_t size) { - asn_codec_ctx_t s_codec_ctx; +ber_decode(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *type_descriptor, void **struct_ptr, + const void *ptr, size_t size) { + asn_codec_ctx_t s_codec_ctx; /* * Stack checker requires that the codec context @@ -51,7 +51,7 @@ ber_decode(asn_codec_ctx_t *opt_codec_ctx, /* * Invoke type-specific decoder. */ - return type_descriptor->ber_decoder(opt_codec_ctx, type_descriptor, + return type_descriptor->op->ber_decoder(opt_codec_ctx, type_descriptor, struct_ptr, /* Pointer to the destination structure */ ptr, size, /* Buffer and its size */ 0 /* Default tag mode is 0 */ @@ -62,11 +62,11 @@ ber_decode(asn_codec_ctx_t *opt_codec_ctx, * Check the set of >> tags matches the definition. */ asn_dec_rval_t -ber_check_tags(asn_codec_ctx_t *opt_codec_ctx, - asn_TYPE_descriptor_t *td, asn_struct_ctx_t *opt_ctx, - const void *ptr, size_t size, int tag_mode, int last_tag_form, - ber_tlv_len_t *last_length, int *opt_tlv_form) { - ssize_t consumed_myself = 0; +ber_check_tags(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *td, asn_struct_ctx_t *opt_ctx, + const void *ptr, size_t size, int tag_mode, int last_tag_form, + ber_tlv_len_t *last_length, int *opt_tlv_form) { + ssize_t consumed_myself = 0; ssize_t tag_len; ssize_t len_len; ber_tlv_tag_t tlv_tag; @@ -112,7 +112,7 @@ ber_check_tags(asn_codec_ctx_t *opt_codec_ctx, td->name, (long)size, tag_mode, step, tagno); /* assert(td->tags_count >= 1) May not be the case for CHOICE or ANY */ - if(tag_mode == 0 && tagno == td->tags_count) { + if(tag_mode == 0 && tagno == (int)td->tags_count) { /* * This must be the _untagged_ ANY type, * which outermost tag isn't known in advance. @@ -134,9 +134,9 @@ ber_check_tags(asn_codec_ctx_t *opt_codec_ctx, (long)(tag_len + len_len)); ADVANCE(tag_len + len_len); } else { - assert(tagno < td->tags_count); /* At least one loop */ + assert(tagno < (int)td->tags_count); /* At least one loop */ } - for((void)tagno; tagno < td->tags_count; tagno++, step++) { + for((void)tagno; tagno < (int)td->tags_count; tagno++, step++) { /* * Fetch and process T from TLV. @@ -186,7 +186,7 @@ ber_check_tags(asn_codec_ctx_t *opt_codec_ctx, * If this one is the last one, check that the tag form * matches the one given in descriptor. */ - if(tagno < (td->tags_count - 1)) { + if(tagno < ((int)td->tags_count - 1)) { if(tlv_constr == 0) { ASN_DEBUG("tlv_constr = %d, expfail", tlv_constr); diff --git a/libs/smux/ber_tlv_length.c b/libs/smux/ber_tlv_length.c index 4c2f1e5f..cfd46723 100644 --- a/libs/smux/ber_tlv_length.c +++ b/libs/smux/ber_tlv_length.c @@ -40,28 +40,18 @@ ber_fetch_length(int _is_constructed, const void *bufptr, size_t size, for(len = 0, buf++, skipped = 1; oct && (++skipped <= size); buf++, oct--) { - len = (len << 8) | *buf; - if(len < 0 - || (len >> ((8 * sizeof(len)) - 8) && oct > 1)) { - /* - * Too large length value. - */ + /* Verify that we won't overflow. */ + if(!(len >> ((8 * sizeof(len)) - (8+1)))) { + len = (len << 8) | *buf; + } else { + /* Too large length value. */ return -1; } } if(oct == 0) { - ber_tlv_len_t lenplusepsilon = (size_t)len + 1024; - /* - * Here length may be very close or equal to 2G. - * However, the arithmetics used in some decoders - * may add some (small) quantities to the length, - * to check the resulting value against some limits. - * This may result in integer wrap-around, which - * we try to avoid by checking it earlier here. - */ - if(lenplusepsilon < 0) { - /* Too large length value */ + if(len < 0 || len > RSSIZE_MAX) { + /* Length value out of sane range. */ return -1; } @@ -75,7 +65,7 @@ ber_fetch_length(int _is_constructed, const void *bufptr, size_t size, } ssize_t -ber_skip_length(asn_codec_ctx_t *opt_codec_ctx, +ber_skip_length(const asn_codec_ctx_t *opt_codec_ctx, int _is_constructed, const void *ptr, size_t size) { ber_tlv_len_t vlen; /* Length of V in TLV */ ssize_t tl; /* Length of L in TLV */ @@ -143,7 +133,7 @@ der_tlv_length_serialize(ber_tlv_len_t len, void *bufp, size_t size) { size_t required_size; /* Size of len encoding */ uint8_t *buf = (uint8_t *)bufp; uint8_t *end; - size_t i; + int i; if(len <= 127) { /* Encoded in 1 octet */ @@ -154,7 +144,7 @@ der_tlv_length_serialize(ber_tlv_len_t len, void *bufp, size_t size) { /* * Compute the size of the subsequent bytes. */ - for(required_size = 1, i = 8; i < 8 * sizeof(len); i += 8) { + for(required_size = 1, i = 8; i < 8 * (int)sizeof(len); i += 8) { if(len >> i) required_size++; else diff --git a/libs/smux/ber_tlv_tag.c b/libs/smux/ber_tlv_tag.c index 42708760..4a7d732f 100644 --- a/libs/smux/ber_tlv_tag.c +++ b/libs/smux/ber_tlv_tag.c @@ -74,7 +74,7 @@ ber_tlv_tag_fwrite(ber_tlv_tag_t tag, FILE *f) { ssize_t ber_tlv_tag_snprint(ber_tlv_tag_t tag, char *buf, size_t size) { - char *type = 0; + const char *type = 0; int ret; switch(tag & 0x3) { diff --git a/libs/smux/constr_CHOICE.c b/libs/smux/constr_CHOICE.c index 6116e6a6..628979ec 100644 --- a/libs/smux/constr_CHOICE.c +++ b/libs/smux/constr_CHOICE.c @@ -1,6 +1,5 @@ /* - * Copyright (c) 2003, 2004, 2005, 2006, 2007 Lev Walkin . - * All rights reserved. + * Copyright (c) 2003-2017 Lev Walkin . All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ #include @@ -63,8 +62,13 @@ /* * See the definitions. */ -static int _fetch_present_idx(const void *struct_ptr, int off, int size); -static void _set_present_idx(void *sptr, int offset, int size, int pres); +static unsigned _fetch_present_idx(const void *struct_ptr, unsigned off, + unsigned size); +static void _set_present_idx(void *sptr, unsigned offset, unsigned size, + unsigned pres); +static const void *_get_member_ptr(const asn_TYPE_descriptor_t *, + const void *sptr, asn_TYPE_member_t **elm, + unsigned *present); /* * Tags are canonically sorted in the tag to member table. @@ -98,12 +102,14 @@ _search4tag(const void *ap, const void *bp) { * The decoder of the CHOICE type. */ asn_dec_rval_t -CHOICE_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, - void **struct_ptr, const void *ptr, size_t size, int tag_mode) { - /* +CHOICE_decode_ber(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *td, void **struct_ptr, + const void *ptr, size_t size, int tag_mode) { + /* * Bring closer parts of structure description. */ - asn_CHOICE_specifics_t *specs = (asn_CHOICE_specifics_t *)td->specifics; + const asn_CHOICE_specifics_t *specs = + (const asn_CHOICE_specifics_t *)td->specifics; asn_TYPE_member_t *elements = td->elements; /* @@ -259,7 +265,7 @@ CHOICE_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, /* * Invoke the member fetch routine according to member's type */ - rval = elm->type->ber_decoder(opt_codec_ctx, elm->type, + rval = elm->type->op->ber_decoder(opt_codec_ctx, elm->type, memb_ptr2, ptr, LEFT, elm->tag_mode); switch(rval.code) { case RC_OK: @@ -354,15 +360,15 @@ CHOICE_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, } asn_enc_rval_t -CHOICE_encode_der(asn_TYPE_descriptor_t *td, void *sptr, - int tag_mode, ber_tlv_tag_t tag, - asn_app_consume_bytes_f *cb, void *app_key) { - asn_CHOICE_specifics_t *specs = (asn_CHOICE_specifics_t *)td->specifics; +CHOICE_encode_der(const asn_TYPE_descriptor_t *td, const void *sptr, + int tag_mode, ber_tlv_tag_t tag, asn_app_consume_bytes_f *cb, + void *app_key) { + const asn_CHOICE_specifics_t *specs = (const asn_CHOICE_specifics_t *)td->specifics; asn_TYPE_member_t *elm; /* CHOICE element */ asn_enc_rval_t erval; - void *memb_ptr; + const void *memb_ptr; size_t computed_size = 0; - int present; + unsigned present; if(!sptr) ASN__ENCODE_FAILED; @@ -376,7 +382,7 @@ CHOICE_encode_der(asn_TYPE_descriptor_t *td, void *sptr, * If the structure was not initialized, it cannot be encoded: * can't deduce what to encode in the choice type. */ - if(present <= 0 || present > td->elements_count) { + if(present == 0 || present > td->elements_count) { if(present == 0 && td->elements_count == 0) { /* The CHOICE is empty?! */ erval.encoded = 0; @@ -390,8 +396,9 @@ CHOICE_encode_der(asn_TYPE_descriptor_t *td, void *sptr, */ elm = &td->elements[present-1]; if(elm->flags & ATF_POINTER) { - memb_ptr = *(void **)((char *)sptr + elm->memb_offset); - if(memb_ptr == 0) { + memb_ptr = + *(const void *const *)((const char *)sptr + elm->memb_offset); + if(memb_ptr == 0) { if(elm->optional) { erval.encoded = 0; ASN__ENCODED_OK(erval); @@ -400,8 +407,8 @@ CHOICE_encode_der(asn_TYPE_descriptor_t *td, void *sptr, ASN__ENCODE_FAILED; } } else { - memb_ptr = (void *)((char *)sptr + elm->memb_offset); - } + memb_ptr = (const void *)((const char *)sptr + elm->memb_offset); + } /* * If the CHOICE itself is tagged EXPLICIT: @@ -415,7 +422,7 @@ CHOICE_encode_der(asn_TYPE_descriptor_t *td, void *sptr, ssize_t ret; /* Encode member with its tag */ - erval = elm->type->der_encoder(elm->type, memb_ptr, + erval = elm->type->op->der_encoder(elm->type, memb_ptr, elm->tag_mode, elm->tag, 0, 0); if(erval.encoded == -1) return erval; @@ -431,7 +438,7 @@ CHOICE_encode_der(asn_TYPE_descriptor_t *td, void *sptr, /* * Encode the single underlying member. */ - erval = elm->type->der_encoder(elm->type, memb_ptr, + erval = elm->type->op->der_encoder(elm->type, memb_ptr, elm->tag_mode, elm->tag, cb, app_key); if(erval.encoded == -1) return erval; @@ -446,8 +453,8 @@ CHOICE_encode_der(asn_TYPE_descriptor_t *td, void *sptr, ber_tlv_tag_t CHOICE_outmost_tag(const asn_TYPE_descriptor_t *td, const void *ptr, int tag_mode, ber_tlv_tag_t tag) { - asn_CHOICE_specifics_t *specs = (asn_CHOICE_specifics_t *)td->specifics; - int present; + const asn_CHOICE_specifics_t *specs = (const asn_CHOICE_specifics_t *)td->specifics; + unsigned present; assert(tag_mode == 0); (void)tag_mode; assert(tag == 0); (void)tag; @@ -457,7 +464,7 @@ CHOICE_outmost_tag(const asn_TYPE_descriptor_t *td, const void *ptr, int tag_mod */ present = _fetch_present_idx(ptr, specs->pres_offset, specs->pres_size); - if(present > 0 || present <= td->elements_count) { + if(present > 0 && present <= td->elements_count) { const asn_TYPE_member_t *elm = &td->elements[present-1]; const void *memb_ptr; @@ -477,10 +484,11 @@ CHOICE_outmost_tag(const asn_TYPE_descriptor_t *td, const void *ptr, int tag_mod } int -CHOICE_constraint(asn_TYPE_descriptor_t *td, const void *sptr, - asn_app_constraint_failed_f *ctfailcb, void *app_key) { - asn_CHOICE_specifics_t *specs = (asn_CHOICE_specifics_t *)td->specifics; - int present; +CHOICE_constraint(const asn_TYPE_descriptor_t *td, const void *sptr, + asn_app_constraint_failed_f *ctfailcb, void *app_key) { + const asn_CHOICE_specifics_t *specs = + (const asn_CHOICE_specifics_t *)td->specifics; + unsigned present; if(!sptr) { ASN__CTFAIL(app_key, td, sptr, @@ -511,18 +519,12 @@ CHOICE_constraint(asn_TYPE_descriptor_t *td, const void *sptr, memb_ptr = (const void *)((const char *)sptr + elm->memb_offset); } - if(elm->memb_constraints) { - return elm->memb_constraints(elm->type, memb_ptr, + if(elm->encoding_constraints.general_constraints) { + return elm->encoding_constraints.general_constraints(elm->type, memb_ptr, ctfailcb, app_key); } else { - int ret = elm->type->check_constraints(elm->type, + return elm->type->encoding_constraints.general_constraints(elm->type, memb_ptr, ctfailcb, app_key); - /* - * Cannot inherit it eralier: - * need to make sure we get the updated version. - */ - elm->memb_constraints = elm->type->check_constraints; - return ret; } } else { ASN__CTFAIL(app_key, td, sptr, @@ -544,13 +546,13 @@ CHOICE_constraint(asn_TYPE_descriptor_t *td, const void *sptr, * Decode the XER (XML) data. */ asn_dec_rval_t -CHOICE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, - void **struct_ptr, const char *opt_mname, - const void *buf_ptr, size_t size) { - /* +CHOICE_decode_xer(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *td, void **struct_ptr, + const char *opt_mname, const void *buf_ptr, size_t size) { + /* * Bring closer parts of structure description. */ - asn_CHOICE_specifics_t *specs = (asn_CHOICE_specifics_t *)td->specifics; + const asn_CHOICE_specifics_t *specs = (const asn_CHOICE_specifics_t *)td->specifics; const char *xml_tag = opt_mname ? opt_mname : td->xml_tag; /* @@ -561,7 +563,7 @@ CHOICE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, asn_dec_rval_t rval; /* Return value of a decoder */ ssize_t consumed_myself = 0; /* Consumed bytes from ptr */ - int edx; /* Element index */ + size_t edx; /* Element index */ /* * Create the target structure if it is not present already. @@ -600,6 +602,7 @@ CHOICE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, asn_dec_rval_t tmprval; void *memb_ptr; /* Pointer to the member */ void **memb_ptr2; /* Pointer to that pointer */ + unsigned old_present; elm = &td->elements[edx]; @@ -613,19 +616,20 @@ CHOICE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, } /* Start/Continue decoding the inner member */ - tmprval = elm->type->xer_decoder(opt_codec_ctx, + tmprval = elm->type->op->xer_decoder(opt_codec_ctx, elm->type, memb_ptr2, elm->name, buf_ptr, size); XER_ADVANCE(tmprval.consumed); ASN_DEBUG("XER/CHOICE: itdf: [%s] code=%d", elm->type->name, tmprval.code); - if(tmprval.code != RC_OK) - RETURN(tmprval.code); - assert(_fetch_present_idx(st, - specs->pres_offset, specs->pres_size) == 0); + old_present = _fetch_present_idx(st, + specs->pres_offset, specs->pres_size); + assert(old_present == 0 || old_present == edx + 1); /* Record what we've got */ _set_present_idx(st, specs->pres_offset, specs->pres_size, edx + 1); + if(tmprval.code != RC_OK) + RETURN(tmprval.code); ctx->phase = 3; /* Fall through */ } @@ -671,7 +675,6 @@ CHOICE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, case -1: ctx->phase = 5; RETURN(RC_FAIL); - continue; case 1: ctx->phase = 3; /* Fall through */ @@ -773,12 +776,13 @@ CHOICE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, asn_enc_rval_t -CHOICE_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, - int ilevel, enum xer_encoder_flags_e flags, - asn_app_consume_bytes_f *cb, void *app_key) { - asn_CHOICE_specifics_t *specs=(asn_CHOICE_specifics_t *)td->specifics; - asn_enc_rval_t er; - int present; +CHOICE_encode_xer(const asn_TYPE_descriptor_t *td, const void *sptr, int ilevel, + enum xer_encoder_flags_e flags, asn_app_consume_bytes_f *cb, + void *app_key) { + const asn_CHOICE_specifics_t *specs = + (const asn_CHOICE_specifics_t *)td->specifics; + asn_enc_rval_t er; + unsigned present; if(!sptr) ASN__ENCODE_FAILED; @@ -788,34 +792,34 @@ CHOICE_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, */ present = _fetch_present_idx(sptr, specs->pres_offset,specs->pres_size); - if(present <= 0 || present > td->elements_count) { + if(present == 0 || present > td->elements_count) { ASN__ENCODE_FAILED; } else { asn_enc_rval_t tmper; asn_TYPE_member_t *elm = &td->elements[present-1]; - void *memb_ptr; + const void *memb_ptr; const char *mname = elm->name; unsigned int mlen = strlen(mname); if(elm->flags & ATF_POINTER) { - memb_ptr = *(void **)((char *)sptr + elm->memb_offset); - if(!memb_ptr) ASN__ENCODE_FAILED; + memb_ptr = + *(const void *const *)((const char *)sptr + elm->memb_offset); + if(!memb_ptr) ASN__ENCODE_FAILED; } else { - memb_ptr = (void *)((char *)sptr + elm->memb_offset); - } + memb_ptr = (const void *)((const char *)sptr + elm->memb_offset); + } - er.encoded = 0; + er.encoded = 0; - if(!(flags & XER_F_CANONICAL)) ASN__TEXT_INDENT(1, ilevel); + if(!(flags & XER_F_CANONICAL)) ASN__TEXT_INDENT(1, ilevel); ASN__CALLBACK3("<", 1, mname, mlen, ">", 1); - tmper = elm->type->xer_encoder(elm->type, memb_ptr, + tmper = elm->type->op->xer_encoder(elm->type, memb_ptr, ilevel + 1, flags, cb, app_key); if(tmper.encoded == -1) return tmper; + er.encoded += tmper.encoded; ASN__CALLBACK3("", 1); - - er.encoded += 5 + (2 * mlen) + tmper.encoded; } if(!(flags & XER_F_CANONICAL)) ASN__TEXT_INDENT(1, ilevel - 1); @@ -826,11 +830,14 @@ cb_failed: } asn_dec_rval_t -CHOICE_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, - asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { - asn_CHOICE_specifics_t *specs = (asn_CHOICE_specifics_t *)td->specifics; - asn_dec_rval_t rv; - asn_per_constraint_t *ct; +CHOICE_decode_uper(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, void **sptr, + asn_per_data_t *pd) { + const asn_CHOICE_specifics_t *specs = + (const asn_CHOICE_specifics_t *)td->specifics; + asn_dec_rval_t rv; + const asn_per_constraint_t *ct; asn_TYPE_member_t *elm; /* CHOICE's element */ void *memb_ptr; void **memb_ptr2; @@ -849,7 +856,7 @@ CHOICE_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, } if(constraints) ct = &constraints->value; - else if(td->per_constraints) ct = &td->per_constraints->value; + else if(td->encoding_constraints.per_constraints) ct = &td->encoding_constraints.per_constraints->value; else ct = 0; if(ct && ct->flags & APC_EXTENSIBLE) { @@ -871,13 +878,16 @@ CHOICE_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, value = uper_get_nsnnwn(pd); if(value < 0) ASN__DECODE_STARVED; value += specs->ext_start; - if(value >= td->elements_count) + if((unsigned)value >= td->elements_count) ASN__DECODE_FAILED; } /* Adjust if canonical order is different from natural order */ - if(specs->canonical_order) - value = specs->canonical_order[value]; + if(specs->from_canonical_order) { + ASN_DEBUG("CHOICE presence from wire %d", value); + value = specs->from_canonical_order[value]; + ASN_DEBUG("CHOICE presence index effective %d", value); + } /* Set presence to be able to free it later */ _set_present_idx(st, specs->pres_offset, specs->pres_size, value + 1); @@ -893,11 +903,11 @@ CHOICE_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, ASN_DEBUG("Discovered CHOICE %s encodes %s", td->name, elm->name); if(ct && ct->range_bits >= 0) { - rv = elm->type->uper_decoder(opt_codec_ctx, elm->type, - elm->per_constraints, memb_ptr2, pd); + rv = elm->type->op->uper_decoder(opt_codec_ctx, elm->type, + elm->encoding_constraints.per_constraints, memb_ptr2, pd); } else { rv = uper_open_type_get(opt_codec_ctx, elm->type, - elm->per_constraints, memb_ptr2, pd); + elm->encoding_constraints.per_constraints, memb_ptr2, pd); } if(rv.code != RC_OK) @@ -905,15 +915,16 @@ CHOICE_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, elm->name, td->name, rv.code); return rv; } - + asn_enc_rval_t -CHOICE_encode_uper(asn_TYPE_descriptor_t *td, - asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { - asn_CHOICE_specifics_t *specs = (asn_CHOICE_specifics_t *)td->specifics; +CHOICE_encode_uper(const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, const void *sptr, + asn_per_outp_t *po) { + const asn_CHOICE_specifics_t *specs = (const asn_CHOICE_specifics_t *)td->specifics; asn_TYPE_member_t *elm; /* CHOICE's element */ - asn_per_constraint_t *ct; - void *memb_ptr; - int present; + const asn_per_constraint_t *ct; + const void *memb_ptr; + unsigned present; int present_enc; if(!sptr) ASN__ENCODE_FAILED; @@ -921,34 +932,37 @@ CHOICE_encode_uper(asn_TYPE_descriptor_t *td, ASN_DEBUG("Encoding %s as CHOICE", td->name); if(constraints) ct = &constraints->value; - else if(td->per_constraints) ct = &td->per_constraints->value; + else if(td->encoding_constraints.per_constraints) + ct = &td->encoding_constraints.per_constraints->value; else ct = 0; - present = _fetch_present_idx(sptr, - specs->pres_offset, specs->pres_size); + present = _fetch_present_idx(sptr, specs->pres_offset, specs->pres_size); /* * If the structure was not initialized properly, it cannot be encoded: * can't deduce what to encode in the choice type. */ - if(present <= 0 || present > td->elements_count) + if(present == 0 || present > td->elements_count) ASN__ENCODE_FAILED; else present--; ASN_DEBUG("Encoding %s CHOICE element %d", td->name, present); - /* Adjust if canonical order is different from natural order */ - if(specs->canonical_order) - present_enc = specs->canonical_order[present]; - else - present_enc = present; + /* Adjust if canonical order is different from natural order */ + if(specs->to_canonical_order) + present_enc = specs->to_canonical_order[present]; + else + present_enc = present; - if(ct && ct->range_bits >= 0) { + if(ct && ct->range_bits >= 0) { if(present_enc < ct->lower_bound || present_enc > ct->upper_bound) { if(ct->flags & APC_EXTENSIBLE) { - if(per_put_few_bits(po, 1, 1)) + ASN_DEBUG( + "CHOICE member %d (enc %d) is an extension (%ld..%ld)", + present, present_enc, ct->lower_bound, ct->upper_bound); + if(per_put_few_bits(po, 1, 1)) ASN__ENCODE_FAILED; } else { ASN__ENCODE_FAILED; @@ -956,45 +970,52 @@ CHOICE_encode_uper(asn_TYPE_descriptor_t *td, ct = 0; } } - if(ct && ct->flags & APC_EXTENSIBLE) - if(per_put_few_bits(po, 0, 1)) + if(ct && ct->flags & APC_EXTENSIBLE) { + ASN_DEBUG("CHOICE member %d (enc %d) is not an extension (%ld..%ld)", + present, present_enc, ct->lower_bound, ct->upper_bound); + if(per_put_few_bits(po, 0, 1)) ASN__ENCODE_FAILED; + } + elm = &td->elements[present]; - if(elm->flags & ATF_POINTER) { + ASN_DEBUG("CHOICE member \"%s\" %d (as %d)", elm->name, present, + present_enc); + if(elm->flags & ATF_POINTER) { /* Member is a pointer to another structure */ - memb_ptr = *(void **)((char *)sptr + elm->memb_offset); - if(!memb_ptr) ASN__ENCODE_FAILED; - } else { - memb_ptr = (char *)sptr + elm->memb_offset; - } - - if(ct && ct->range_bits >= 0) { - if(per_put_few_bits(po, present_enc, ct->range_bits)) - ASN__ENCODE_FAILED; - - return elm->type->uper_encoder(elm->type, elm->per_constraints, - memb_ptr, po); + memb_ptr = + *(const void *const *)((const char *)sptr + elm->memb_offset); + if(!memb_ptr) ASN__ENCODE_FAILED; } else { - asn_enc_rval_t rval; - if(specs->ext_start == -1) - ASN__ENCODE_FAILED; - if(uper_put_nsnnwn(po, present_enc - specs->ext_start)) - ASN__ENCODE_FAILED; - if(uper_open_type_put(elm->type, elm->per_constraints, - memb_ptr, po)) - ASN__ENCODE_FAILED; - rval.encoded = 0; - ASN__ENCODED_OK(rval); - } + memb_ptr = (const char *)sptr + elm->memb_offset; + } + + if(ct && ct->range_bits >= 0) { + if(per_put_few_bits(po, present_enc, ct->range_bits)) + ASN__ENCODE_FAILED; + + return elm->type->op->uper_encoder( + elm->type, elm->encoding_constraints.per_constraints, memb_ptr, po); + } else { + asn_enc_rval_t rval; + if(specs->ext_start == -1) ASN__ENCODE_FAILED; + if(uper_put_nsnnwn(po, present_enc - specs->ext_start)) + ASN__ENCODE_FAILED; + if(uper_open_type_put(elm->type, + elm->encoding_constraints.per_constraints, + memb_ptr, po)) + ASN__ENCODE_FAILED; + rval.encoded = 0; + ASN__ENCODED_OK(rval); + } } - + int -CHOICE_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel, - asn_app_consume_bytes_f *cb, void *app_key) { - asn_CHOICE_specifics_t *specs = (asn_CHOICE_specifics_t *)td->specifics; - int present; +CHOICE_print(const asn_TYPE_descriptor_t *td, const void *sptr, int ilevel, + asn_app_consume_bytes_f *cb, void *app_key) { + const asn_CHOICE_specifics_t *specs = (const asn_CHOICE_specifics_t *)td->specifics; + unsigned present; if(!sptr) return (cb("", 8, app_key) < 0) ? -1 : 0; @@ -1024,7 +1045,7 @@ CHOICE_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel, return -1; } - return elm->type->print_struct(elm->type, memb_ptr, ilevel, + return elm->type->op->print_struct(elm->type, memb_ptr, ilevel, cb, app_key); } else { return (cb("", 8, app_key) < 0) ? -1 : 0; @@ -1032,9 +1053,11 @@ CHOICE_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel, } void -CHOICE_free(asn_TYPE_descriptor_t *td, void *ptr, int contents_only) { - asn_CHOICE_specifics_t *specs = (asn_CHOICE_specifics_t *)td->specifics; - int present; +CHOICE_free(const asn_TYPE_descriptor_t *td, void *ptr, + enum asn_struct_free_method method) { + const asn_CHOICE_specifics_t *specs = + (const asn_CHOICE_specifics_t *)td->specifics; + unsigned present; if(!td || !ptr) return; @@ -1063,9 +1086,16 @@ CHOICE_free(asn_TYPE_descriptor_t *td, void *ptr, int contents_only) { } } - if(!contents_only) { - FREEMEM(ptr); - } + switch(method) { + case ASFM_FREE_EVERYTHING: + FREEMEM(ptr); + break; + case ASFM_FREE_UNDERLYING: + break; + case ASFM_FREE_UNDERLYING_AND_RESET: + memset(ptr, 0, specs->struct_size); + break; + } } @@ -1078,17 +1108,18 @@ CHOICE_free(asn_TYPE_descriptor_t *td, void *ptr, int contents_only) { * is guaranteed to be aligned properly. ASN.1 compiler itself does not * produce packed code. */ -static int -_fetch_present_idx(const void *struct_ptr, int pres_offset, int pres_size) { - const void *present_ptr; - int present; +static unsigned +_fetch_present_idx(const void *struct_ptr, unsigned pres_offset, + unsigned pres_size) { + const void *present_ptr; + unsigned present; present_ptr = ((const char *)struct_ptr) + pres_offset; switch(pres_size) { - case sizeof(int): present = *(const int *)present_ptr; break; - case sizeof(short): present = *(const short *)present_ptr; break; - case sizeof(char): present = *(const char *)present_ptr; break; + case sizeof(int): present = *(const unsigned int *)present_ptr; break; + case sizeof(short): present = *(const unsigned short *)present_ptr; break; + case sizeof(char): present = *(const unsigned char *)present_ptr; break; default: /* ANSI C mandates enum to be equivalent to integer */ assert(pres_size != sizeof(int)); @@ -1099,16 +1130,211 @@ _fetch_present_idx(const void *struct_ptr, int pres_offset, int pres_size) { } static void -_set_present_idx(void *struct_ptr, int pres_offset, int pres_size, int present) { - void *present_ptr; +_set_present_idx(void *struct_ptr, unsigned pres_offset, unsigned pres_size, + unsigned present) { + void *present_ptr; present_ptr = ((char *)struct_ptr) + pres_offset; switch(pres_size) { - case sizeof(int): *(int *)present_ptr = present; break; - case sizeof(short): *(short *)present_ptr = present; break; - case sizeof(char): *(char *)present_ptr = present; break; + case sizeof(int): *(unsigned int *)present_ptr = present; break; + case sizeof(short): *(unsigned short *)present_ptr = present; break; + case sizeof(char): *(unsigned char *)present_ptr = present; break; default: /* ANSI C mandates enum to be equivalent to integer */ assert(pres_size != sizeof(int)); } } + +static const void * +_get_member_ptr(const asn_TYPE_descriptor_t *td, const void *sptr, + asn_TYPE_member_t **elm_ptr, unsigned *present_out) { + const asn_CHOICE_specifics_t *specs = + (const asn_CHOICE_specifics_t *)td->specifics; + unsigned present; + + if(!sptr) { + *elm_ptr = NULL; + *present_out = 0; + return NULL; + } + + /* + * Figure out which CHOICE element is encoded. + */ + present = _fetch_present_idx(sptr, specs->pres_offset, specs->pres_size); + *present_out = present; + + /* + * The presence index is intentionally 1-based to avoid + * treating zeroed structure as a valid one. + */ + if(present > 0 && present <= td->elements_count) { + asn_TYPE_member_t *const elm = &td->elements[present - 1]; + const void *memb_ptr; + + if(elm->flags & ATF_POINTER) { + memb_ptr = + *(const void *const *)((const char *)sptr + elm->memb_offset); + } else { + memb_ptr = (const void *)((const char *)sptr + elm->memb_offset); + } + *elm_ptr = elm; + return memb_ptr; + } else { + *elm_ptr = NULL; + return NULL; + } + +} + +int +CHOICE_compare(const asn_TYPE_descriptor_t *td, const void *aptr, const void *bptr) { + asn_TYPE_member_t *aelm; + asn_TYPE_member_t *belm; + unsigned apresent = 0; + unsigned bpresent = 0; + const void *amember = _get_member_ptr(td, aptr, &aelm, &apresent); + const void *bmember = _get_member_ptr(td, bptr, &belm, &bpresent); + + if(amember && bmember) { + if(apresent == bpresent) { + assert(aelm == belm); + return aelm->type->op->compare_struct(aelm->type, amember, bmember); + } else if(apresent < bpresent) { + return -1; + } else { + return 1; + } + } else if(!amember) { + return -1; + } else { + return 1; + } +} + +/* + * Return the 1-based choice variant presence index. + * Returns 0 in case of error. + */ +unsigned +CHOICE_variant_get_presence(const asn_TYPE_descriptor_t *td, const void *sptr) { + const asn_CHOICE_specifics_t *specs = + (const asn_CHOICE_specifics_t *)td->specifics; + return _fetch_present_idx(sptr, specs->pres_offset, specs->pres_size); +} + +/* + * Sets or resets the 1-based choice variant presence index. + * In case a previous index is not zero, the currently selected structure + * member is freed and zeroed-out first. + * Returns 0 on success and -1 on error. + */ +int +CHOICE_variant_set_presence(const asn_TYPE_descriptor_t *td, void *sptr, + unsigned present) { + const asn_CHOICE_specifics_t *specs = + (const asn_CHOICE_specifics_t *)td->specifics; + unsigned old_present; + + if(!sptr) { + return -1; + } + + if(present > td->elements_count) + return -1; + + old_present = + _fetch_present_idx(sptr, specs->pres_offset, specs->pres_size); + if(present == old_present) + return 0; + + if(old_present != 0) { + assert(old_present <= td->elements_count); + ASN_STRUCT_RESET(*td, sptr); + } + + _set_present_idx(sptr, specs->pres_offset, specs->pres_size, present); + + return 0; +} + + +asn_random_fill_result_t +CHOICE_random_fill(const asn_TYPE_descriptor_t *td, void **sptr, + const asn_encoding_constraints_t *constr, + size_t max_length) { + const asn_CHOICE_specifics_t *specs = + (const asn_CHOICE_specifics_t *)td->specifics; + asn_random_fill_result_t res; + asn_random_fill_result_t result_failed = {ARFILL_FAILED, 0}; + asn_random_fill_result_t result_skipped = {ARFILL_SKIPPED, 0}; + const asn_TYPE_member_t *elm; + unsigned present; + void *memb_ptr; /* Pointer to the member */ + void **memb_ptr2; /* Pointer to that pointer */ + void *st = *sptr; + + if(max_length == 0) return result_skipped; + + (void)constr; + + if(st == NULL) { + st = CALLOC(1, specs->struct_size); + if(st == NULL) { + return result_failed; + } + } + + present = asn_random_between(1, td->elements_count); + elm = &td->elements[present - 1]; + + if(elm->flags & ATF_POINTER) { + /* Member is a pointer to another structure */ + memb_ptr2 = (void **)((char *)st + elm->memb_offset); + } else { + memb_ptr = (char *)st + elm->memb_offset; + memb_ptr2 = &memb_ptr; + } + + res = elm->type->op->random_fill(elm->type, memb_ptr2, + &elm->encoding_constraints, max_length); + _set_present_idx(st, specs->pres_offset, specs->pres_size, present); + if(res.code == ARFILL_OK) { + *sptr = st; + } else { + if(st == *sptr) { + ASN_STRUCT_RESET(*td, st); + } else { + ASN_STRUCT_FREE(*td, st); + } + } + + return res; +} + + +asn_TYPE_operation_t asn_OP_CHOICE = { + CHOICE_free, + CHOICE_print, + CHOICE_compare, + CHOICE_decode_ber, + CHOICE_encode_der, + CHOICE_decode_xer, + CHOICE_encode_xer, +#ifdef ASN_DISABLE_OER_SUPPORT + 0, + 0, +#else + CHOICE_decode_oer, + CHOICE_encode_oer, +#endif /* ASN_DISABLE_OER_SUPPORT */ +#ifdef ASN_DISABLE_PER_SUPPORT + 0, + 0, +#else + CHOICE_decode_uper, + CHOICE_encode_uper, +#endif /* ASN_DISABLE_PER_SUPPORT */ + CHOICE_random_fill, + CHOICE_outmost_tag +}; diff --git a/libs/smux/constr_CHOICE_oer.c b/libs/smux/constr_CHOICE_oer.c new file mode 100644 index 00000000..6480a961 --- /dev/null +++ b/libs/smux/constr_CHOICE_oer.c @@ -0,0 +1,380 @@ +/* + * Copyright (c) 2017 Lev Walkin . + * All rights reserved. + * Redistribution and modifications are permitted subject to BSD license. + */ +#ifndef ASN_DISABLE_OER_SUPPORT + +#include +#include +#include + +/* + * Return a standardized complex structure. + */ +#undef RETURN +#define RETURN(_code) \ + do { \ + asn_dec_rval_t rval; \ + rval.code = _code; \ + rval.consumed = consumed_myself; \ + return rval; \ + } while(0) + +#undef ADVANCE +#define ADVANCE(num_bytes) \ + do { \ + size_t num = num_bytes; \ + ptr = ((const char *)ptr) + num; \ + size -= num; \ + consumed_myself += num; \ + } while(0) + +/* + * Switch to the next phase of parsing. + */ +#undef NEXT_PHASE +#define NEXT_PHASE(ctx) \ + do { \ + ctx->phase++; \ + ctx->step = 0; \ + } while(0) +#undef SET_PHASE +#define SET_PHASE(ctx, value) \ + do { \ + ctx->phase = value; \ + ctx->step = 0; \ + } while(0) + +/* + * Tags are canonically sorted in the tag to member table. + */ +static int +_search4tag(const void *ap, const void *bp) { + const asn_TYPE_tag2member_t *a = (const asn_TYPE_tag2member_t *)ap; + const asn_TYPE_tag2member_t *b = (const asn_TYPE_tag2member_t *)bp; + + int a_class = BER_TAG_CLASS(a->el_tag); + int b_class = BER_TAG_CLASS(b->el_tag); + + if(a_class == b_class) { + ber_tlv_tag_t a_value = BER_TAG_VALUE(a->el_tag); + ber_tlv_tag_t b_value = BER_TAG_VALUE(b->el_tag); + + if(a_value == b_value) + return 0; + else if(a_value < b_value) + return -1; + else + return 1; + } else if(a_class < b_class) { + return -1; + } else { + return 1; + } +} + +/* + * X.696 (08/2015) #8.7 Encoding of tags + */ +static ssize_t +oer_fetch_tag(const void *ptr, size_t size, ber_tlv_tag_t *tag_r) { + ber_tlv_tag_t val; + ber_tlv_tag_t tclass; + size_t skipped; + + if(size == 0) + return 0; + + val = *(const uint8_t *)ptr; + tclass = (val >> 6); + if((val & 0x3F) != 0x3F) { + /* #8.7.1 */ + *tag_r = ((val & 0x3F) << 2) | tclass; + return 1; + } + + /* + * Each octet contains 7 bits of useful information. + * The MSB is 0 if it is the last octet of the tag. + */ + for(val = 0, ptr = ((const char *)ptr) + 1, skipped = 2; skipped <= size; + ptr = ((const char *)ptr) + 1, skipped++) { + unsigned int oct = *(const uint8_t *)ptr; + if(oct & 0x80) { + val = (val << 7) | (oct & 0x7F); + /* + * Make sure there are at least 9 bits spare + * at the MS side of a value. + */ + if(val >> ((8 * sizeof(val)) - 9)) { + /* + * We would not be able to accomodate + * any more tag bits. + */ + return -1; + } + } else { + val = (val << 7) | oct; + *tag_r = (val << 2) | tclass; + return skipped; + } + } + + return 0; /* Want more */ +} + +asn_dec_rval_t +CHOICE_decode_oer(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *td, + const asn_oer_constraints_t *constraints, void **struct_ptr, + const void *ptr, size_t size) { + /* + * Bring closer parts of structure description. + */ + const asn_CHOICE_specifics_t *specs = + (const asn_CHOICE_specifics_t *)td->specifics; + asn_TYPE_member_t *elements = td->elements; + + /* + * Parts of the structure being constructed. + */ + void *st = *struct_ptr; /* Target structure. */ + asn_struct_ctx_t *ctx; /* Decoder context */ + + ssize_t consumed_myself = 0; /* Consumed bytes from ptr */ + + (void)constraints; + + ASN_DEBUG("Decoding %s as CHOICE", td->name); + + /* + * Create the target structure if it is not present already. + */ + if(st == 0) { + st = *struct_ptr = CALLOC(1, specs->struct_size); + if(st == 0) { + RETURN(RC_FAIL); + } + } + + /* + * Restore parsing context. + */ + ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset); + switch(ctx->phase) { + case 0: { + /* + * Discover the tag. + */ + ber_tlv_tag_t tlv_tag; /* T from TLV */ + ssize_t tag_len; /* Length of TLV's T */ + + tag_len = oer_fetch_tag(ptr, size, &tlv_tag); + switch(tag_len) { + case 0: + ASN__DECODE_STARVED; + case -1: + ASN__DECODE_FAILED; + } + + do { + const asn_TYPE_tag2member_t *t2m; + asn_TYPE_tag2member_t key = {0, 0, 0, 0}; + key.el_tag = tlv_tag; + + t2m = (const asn_TYPE_tag2member_t *)bsearch( + &key, specs->tag2el, specs->tag2el_count, + sizeof(specs->tag2el[0]), _search4tag); + if(t2m) { + /* + * Found the element corresponding to the tag. + */ + NEXT_PHASE(ctx); + ctx->step = t2m->el_no; + break; + } else if(specs->ext_start == -1) { + ASN_DEBUG( + "Unexpected tag %s " + "in non-extensible CHOICE %s", + ber_tlv_tag_string(tlv_tag), td->name); + RETURN(RC_FAIL); + } else { + /* Skip open type extension */ + ASN_DEBUG( + "Not implemented skipping open type extension for tag %s", + ber_tlv_tag_string(tlv_tag)); + RETURN(RC_FAIL); + } + } while(0); + + + ADVANCE(tag_len); + } + /* Fall through */ + case 1: { + asn_TYPE_member_t *elm = &elements[ctx->step]; /* CHOICE's element */ + void *memb_ptr; /* Pointer to the member */ + void **memb_ptr2; /* Pointer to that pointer */ + asn_dec_rval_t rval; + + /* + * Compute the position of the member inside a structure, + * and also a type of containment (it may be contained + * as pointer or using inline inclusion). + */ + if(elm->flags & ATF_POINTER) { + /* Member is a pointer to another structure */ + memb_ptr2 = (void **)((char *)st + elm->memb_offset); + } else { + /* + * A pointer to a pointer + * holding the start of the structure + */ + memb_ptr = (char *)st + elm->memb_offset; + memb_ptr2 = &memb_ptr; + } + + /* Set presence to be able to free it properly at any time */ + (void)CHOICE_variant_set_presence(td, st, ctx->step + 1); + + if(specs->ext_start >= 0 && specs->ext_start <= ctx->step) { + ssize_t got = + oer_open_type_get(opt_codec_ctx, elm->type, + elm->encoding_constraints.oer_constraints, + memb_ptr2, ptr, size); + if(got < 0) ASN__DECODE_FAILED; + if(got == 0) ASN__DECODE_STARVED; + rval.code = RC_OK; + rval.consumed = got; + } else { + rval = elm->type->op->oer_decoder( + opt_codec_ctx, elm->type, + elm->encoding_constraints.oer_constraints, memb_ptr2, ptr, + size); + } + rval.consumed += consumed_myself; + switch(rval.code) { + case RC_OK: + NEXT_PHASE(ctx); + case RC_WMORE: + break; + case RC_FAIL: + SET_PHASE(ctx, 3); /* => 3 */ + } + return rval; + } + case 2: + /* Already decoded everything */ + RETURN(RC_OK); + case 3: + /* Failed to decode, after all */ + RETURN(RC_FAIL); + } + + RETURN(RC_FAIL); +} + +/* + * X.696 (08/2015) #8.7 Encoding of tags + */ +static ssize_t +oer_put_tag(ber_tlv_tag_t tag, asn_app_consume_bytes_f *cb, void *app_key) { + uint8_t tclass = BER_TAG_CLASS(tag); + ber_tlv_tag_t tval = BER_TAG_VALUE(tag); + + if(tval < 0x3F) { + uint8_t b = (uint8_t)((tclass << 6) | tval); + if(cb(&b, 1, app_key) < 0) { + return -1; + } + return 1; + } else { + uint8_t buf[1 + 2 * sizeof(tval)]; + uint8_t *b = &buf[sizeof(buf)-1]; /* Last addressable */ + size_t encoded; + for(; ; tval >>= 7) { + if(tval >> 7) { + *b-- = 0x80 | (tval & 0x7f); + } else { + *b-- = tval & 0x7f; + break; + } + } + *b = (uint8_t)((tclass << 6) | 0x3F); + encoded = sizeof(buf) - (b - buf); + if(cb(b, encoded, app_key) < 0) { + return -1; + } + return encoded; + } + +} + +/* + * Encode as Canonical OER. + */ +asn_enc_rval_t +CHOICE_encode_oer(const asn_TYPE_descriptor_t *td, + const asn_oer_constraints_t *constraints, const void *sptr, + asn_app_consume_bytes_f *cb, void *app_key) { + const asn_CHOICE_specifics_t *specs = + (const asn_CHOICE_specifics_t *)td->specifics; + asn_TYPE_member_t *elm; /* CHOICE element */ + unsigned present; + const void *memb_ptr; + ber_tlv_tag_t tag; + ssize_t tag_len; + asn_enc_rval_t er = {0, 0, 0}; + + (void)constraints; + + if(!sptr) ASN__ENCODE_FAILED; + + ASN_DEBUG("OER %s encoding as CHOICE", td->name); + + present = CHOICE_variant_get_presence(td, sptr); + if(present == 0 || present > td->elements_count) { + ASN_DEBUG("CHOICE %s member is not selected", td->name); + ASN__ENCODE_FAILED; + } + + elm = &td->elements[present-1]; + if(elm->flags & ATF_POINTER) { + memb_ptr = + *(const void *const *)((const char *)sptr + elm->memb_offset); + if(memb_ptr == 0) { + /* Mandatory element absent */ + ASN__ENCODE_FAILED; + } + } else { + memb_ptr = (const void *)((const char *)sptr + elm->memb_offset); + } + + tag = asn_TYPE_outmost_tag(elm->type, memb_ptr, elm->tag_mode, elm->tag); + if(tag == 0) { + ASN__ENCODE_FAILED; + } + + tag_len = oer_put_tag(tag, cb, app_key); + if(tag_len < 0) { + ASN__ENCODE_FAILED; + } + + if(specs->ext_start >= 0 && (unsigned)specs->ext_start <= (present-1)) { + ssize_t encoded = oer_open_type_put(elm->type, + elm->encoding_constraints.oer_constraints, + memb_ptr, cb, app_key); + if(encoded < 0) ASN__ENCODE_FAILED; + er.encoded = tag_len + encoded; + } else { + er = elm->type->op->oer_encoder( + elm->type, elm->encoding_constraints.oer_constraints, memb_ptr, cb, + app_key); + if(er.encoded >= 0) er.encoded += tag_len; + } + + return er; +} + +#endif /* ASN_DISABLE_OER_SUPPORT */ diff --git a/libs/smux/constr_SEQUENCE.c b/libs/smux/constr_SEQUENCE.c index 5923023d..2fbf97b6 100644 --- a/libs/smux/constr_SEQUENCE.c +++ b/libs/smux/constr_SEQUENCE.c @@ -1,10 +1,11 @@ -/*- - * Copyright (c) 2003, 2004, 2005, 2006, 2007 Lev Walkin . +/* + * Copyright (c) 2003-2017 Lev Walkin . * All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ #include #include +#include #include /* @@ -65,10 +66,9 @@ /* * Check whether we are inside the extensions group. */ -#define IN_EXTENSION_GROUP(specs, memb_idx) \ - ( ((memb_idx) > (specs)->ext_after) \ - &&((memb_idx) < (specs)->ext_before)) - +#define IN_EXTENSION_GROUP(specs, memb_idx) \ + ((specs)->first_extension >= 0 \ + && (unsigned)(specs)->first_extension <= (memb_idx)) /* * Tags are canonically sorted in the tag2element map. @@ -109,15 +109,16 @@ _t2e_cmp(const void *ap, const void *bp) { * The decoder of the SEQUENCE type. */ asn_dec_rval_t -SEQUENCE_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, - void **struct_ptr, const void *ptr, size_t size, int tag_mode) { - /* +SEQUENCE_decode_ber(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *td, void **struct_ptr, + const void *ptr, size_t size, int tag_mode) { + /* * Bring closer parts of structure description. */ - asn_SEQUENCE_specifics_t *specs = (asn_SEQUENCE_specifics_t *)td->specifics; - asn_TYPE_member_t *elements = td->elements; + const asn_SEQUENCE_specifics_t *specs = (const asn_SEQUENCE_specifics_t *)td->specifics; + const asn_TYPE_member_t *elements = td->elements; - /* + /* * Parts of the structure being constructed. */ void *st = *struct_ptr; /* Target structure. */ @@ -127,7 +128,7 @@ SEQUENCE_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, asn_dec_rval_t rval; /* Return code from subparsers */ ssize_t consumed_myself = 0; /* Consumed bytes from ptr */ - int edx; /* SEQUENCE element's index */ + size_t edx; /* SEQUENCE element's index */ ASN_DEBUG("Decoding %s as SEQUENCE", td->name); @@ -186,14 +187,14 @@ SEQUENCE_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, * that member: * step = ( * 2 + ). */ - for(edx = (ctx->step >> 1); edx < td->elements_count; + for(edx = ((size_t)ctx->step >> 1); edx < td->elements_count; edx++, ctx->step = (ctx->step & ~1) + 2) { void *memb_ptr; /* Pointer to the member */ void **memb_ptr2; /* Pointer to that pointer */ ssize_t tag_len; /* Length of TLV's T */ - int opt_edx_end; /* Next non-optional element */ + size_t opt_edx_end; /* Next non-optional element */ + size_t n; int use_bsearch; - int n; if(ctx->step & 1) goto microphase2; @@ -201,36 +202,31 @@ SEQUENCE_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, /* * MICROPHASE 1: Synchronize decoding. */ - ASN_DEBUG("In %s SEQUENCE left %d, edx=%d flags=%d" + ASN_DEBUG("In %s SEQUENCE left %d, edx=%" ASN_PRI_SIZE " flags=%d" " opt=%d ec=%d", td->name, (int)ctx->left, edx, elements[edx].flags, elements[edx].optional, td->elements_count); - if(ctx->left == 0 /* No more stuff is expected */ - && ( - /* Explicit OPTIONAL specification reaches the end */ - (edx + elements[edx].optional - == td->elements_count) - || - /* All extensions are optional */ - (IN_EXTENSION_GROUP(specs, edx) - && specs->ext_before > td->elements_count) - ) - ) { - ASN_DEBUG("End of SEQUENCE %s", td->name); - /* - * Found the legitimate end of the structure. - */ - PHASE_OUT(ctx); - RETURN(RC_OK); - } + if(ctx->left == 0 /* No more stuff is expected */ + && ( + /* Explicit OPTIONAL specification reaches the end */ + (edx + elements[edx].optional == td->elements_count) || + /* All extensions are optional */ + IN_EXTENSION_GROUP(specs, edx))) { + ASN_DEBUG("End of SEQUENCE %s", td->name); + /* + * Found the legitimate end of the structure. + */ + PHASE_OUT(ctx); + RETURN(RC_OK); + } /* * Fetch the T from TLV. */ tag_len = ber_fetch_tag(ptr, LEFT, &tlv_tag); - ASN_DEBUG("Current tag in %s SEQUENCE for element %d " + ASN_DEBUG("Current tag in %s SEQUENCE for element %" ASN_PRI_SIZE " " "(%s) is %s encoded in %d bytes, of frame %ld", td->name, edx, elements[edx].name, ber_tlv_tag_string(tlv_tag), (int)tag_len, (long)LEFT); @@ -240,34 +236,31 @@ SEQUENCE_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, case -1: RETURN(RC_FAIL); } - if(ctx->left < 0 && ((const uint8_t *)ptr)[0] == 0) { - if(LEFT < 2) { - if(SIZE_VIOLATION) - RETURN(RC_FAIL); - else - RETURN(RC_WMORE); - } else if(((const uint8_t *)ptr)[1] == 0) { - ASN_DEBUG("edx = %d, opt = %d, ec=%d", - edx, elements[edx].optional, - td->elements_count); - if((edx + elements[edx].optional - == td->elements_count) - || (IN_EXTENSION_GROUP(specs, edx) - && specs->ext_before - > td->elements_count)) { - /* - * Yeah, baby! Found the terminator - * of the indefinite length structure. - */ - /* - * Proceed to the canonical - * finalization function. - * No advancing is necessary. - */ - goto phase3; - } - } - } + if(ctx->left < 0 && ((const uint8_t *)ptr)[0] == 0) { + if(LEFT < 2) { + if(SIZE_VIOLATION) { + RETURN(RC_FAIL); + } else { + RETURN(RC_WMORE); + } + } else if(((const uint8_t *)ptr)[1] == 0) { + ASN_DEBUG("edx = %" ASN_PRI_SIZE ", opt = %d, ec=%d", edx, + elements[edx].optional, td->elements_count); + if((edx + elements[edx].optional == td->elements_count) + || IN_EXTENSION_GROUP(specs, edx)) { + /* + * Yeah, baby! Found the terminator + * of the indefinite length structure. + */ + /* + * Proceed to the canonical + * finalization function. + * No advancing is necessary. + */ + goto phase3; + } + } + } /* * Find the next available type with this tag. @@ -292,7 +285,7 @@ SEQUENCE_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, edx = n; ctx->step = 1 + 2 * edx; /* Remember! */ goto microphase2; - } else if(elements[n].flags & ATF_OPEN_TYPE) { + } else if(elements[n].flags & ATF_ANY_TYPE) { /* * This is the ANY type, which may bear * any flag whatsoever. @@ -311,7 +304,7 @@ SEQUENCE_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, * sorted array of tags. */ const asn_TYPE_tag2member_t *t2m; - asn_TYPE_tag2member_t key; + asn_TYPE_tag2member_t key = {0, 0, 0, 0}; key.el_tag = tlv_tag; key.el_no = edx; t2m = (const asn_TYPE_tag2member_t *)bsearch(&key, @@ -320,7 +313,7 @@ SEQUENCE_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, if(t2m) { const asn_TYPE_tag2member_t *best = 0; const asn_TYPE_tag2member_t *t2m_f, *t2m_l; - int edx_max = edx + elements[edx].optional; + size_t edx_max = edx + elements[edx].optional; /* * Rewind to the first element with that tag, * `cause bsearch() does not guarantee order. @@ -349,7 +342,7 @@ SEQUENCE_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, */ if(!IN_EXTENSION_GROUP(specs, edx + elements[edx].optional)) { - ASN_DEBUG("Unexpected tag %s (at %d)", + ASN_DEBUG("Unexpected tag %s (at %" ASN_PRI_SIZE ")", ber_tlv_tag_string(tlv_tag), edx); ASN_DEBUG("Expected tag %s (%s)%s", ber_tlv_tag_string(elements[edx].tag), @@ -362,7 +355,7 @@ SEQUENCE_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, ssize_t skip; edx += elements[edx].optional; - ASN_DEBUG("Skipping unexpected %s (at %d)", + ASN_DEBUG("Skipping unexpected %s (at %" ASN_PRI_SIZE ")", ber_tlv_tag_string(tlv_tag), edx); skip = ber_skip_length(opt_codec_ctx, BER_TLV_CONSTRUCTED(ptr), @@ -409,11 +402,15 @@ SEQUENCE_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, /* * Invoke the member fetch routine according to member's type */ - rval = elements[edx].type->ber_decoder(opt_codec_ctx, - elements[edx].type, - memb_ptr2, ptr, LEFT, - elements[edx].tag_mode); - ASN_DEBUG("In %s SEQUENCE decoded %d %s of %d " + if(elements[edx].flags & ATF_OPEN_TYPE) { + rval = OPEN_TYPE_ber_get(opt_codec_ctx, td, st, &elements[edx], ptr, LEFT); + } else { + rval = elements[edx].type->op->ber_decoder(opt_codec_ctx, + elements[edx].type, + memb_ptr2, ptr, LEFT, + elements[edx].tag_mode); + } + ASN_DEBUG("In %s SEQUENCE decoded %" ASN_PRI_SIZE " %s of %d " "in %d bytes rval.code %d, size=%d", td->name, edx, elements[edx].type->name, (int)LEFT, (int)rval.consumed, rval.code, (int)size); @@ -437,6 +434,7 @@ SEQUENCE_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, phase3: ctx->phase = 3; + /* Fall through */ case 3: /* 00 and other tags expected */ case 4: /* only 00's expected */ @@ -510,13 +508,13 @@ SEQUENCE_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, * The DER encoder of the SEQUENCE type. */ asn_enc_rval_t -SEQUENCE_encode_der(asn_TYPE_descriptor_t *td, - void *sptr, int tag_mode, ber_tlv_tag_t tag, - asn_app_consume_bytes_f *cb, void *app_key) { - size_t computed_size = 0; +SEQUENCE_encode_der(const asn_TYPE_descriptor_t *td, const void *sptr, + int tag_mode, ber_tlv_tag_t tag, + asn_app_consume_bytes_f *cb, void *app_key) { + size_t computed_size = 0; asn_enc_rval_t erval; ssize_t ret; - int edx; + size_t edx; ASN_DEBUG("%s %s as SEQUENCE", cb?"Encoding":"Estimating", td->name); @@ -526,24 +524,37 @@ SEQUENCE_encode_der(asn_TYPE_descriptor_t *td, */ for(edx = 0; edx < td->elements_count; edx++) { asn_TYPE_member_t *elm = &td->elements[edx]; - void *memb_ptr; - if(elm->flags & ATF_POINTER) { - memb_ptr = *(void **)((char *)sptr + elm->memb_offset); - if(!memb_ptr) { - if(elm->optional) continue; + + const void *memb_ptr; /* Pointer to the member */ + const void *const *memb_ptr2; /* Pointer to that pointer */ + + if(elm->flags & ATF_POINTER) { + memb_ptr2 = + (const void *const *)((const char *)sptr + elm->memb_offset); + if(!*memb_ptr2) { + ASN_DEBUG("Element %s %" ASN_PRI_SIZE " not present", + elm->name, edx); + if(elm->optional) + continue; /* Mandatory element is missing */ ASN__ENCODE_FAILED; } } else { - memb_ptr = (void *)((char *)sptr + elm->memb_offset); + memb_ptr = (const void *)((const char *)sptr + elm->memb_offset); + memb_ptr2 = &memb_ptr; } - erval = elm->type->der_encoder(elm->type, memb_ptr, + + /* Eliminate default values */ + if(elm->default_value_cmp && elm->default_value_cmp(*memb_ptr2) == 0) + continue; + + erval = elm->type->op->der_encoder(elm->type, *memb_ptr2, elm->tag_mode, elm->tag, 0, 0); if(erval.encoded == -1) return erval; computed_size += erval.encoded; - ASN_DEBUG("Member %d %s estimated %ld bytes", + ASN_DEBUG("Member %" ASN_PRI_SIZE " %s estimated %ld bytes", edx, elm->name, (long)erval.encoded); } @@ -564,21 +575,28 @@ SEQUENCE_encode_der(asn_TYPE_descriptor_t *td, for(edx = 0; edx < td->elements_count; edx++) { asn_TYPE_member_t *elm = &td->elements[edx]; asn_enc_rval_t tmperval; - void *memb_ptr; + const void *memb_ptr; /* Pointer to the member */ + const void *const *memb_ptr2; /* Pointer to that pointer */ - if(elm->flags & ATF_POINTER) { - memb_ptr = *(void **)((char *)sptr + elm->memb_offset); - if(!memb_ptr) continue; + if(elm->flags & ATF_POINTER) { + memb_ptr2 = + (const void *const *)((const char *)sptr + elm->memb_offset); + if(!*memb_ptr2) continue; } else { - memb_ptr = (void *)((char *)sptr + elm->memb_offset); + memb_ptr = (const void *)((const char *)sptr + elm->memb_offset); + memb_ptr2 = &memb_ptr; } - tmperval = elm->type->der_encoder(elm->type, memb_ptr, - elm->tag_mode, elm->tag, - cb, app_key); + + /* Eliminate default values */ + if(elm->default_value_cmp && elm->default_value_cmp(*memb_ptr2) == 0) + continue; + + tmperval = elm->type->op->der_encoder(elm->type, *memb_ptr2, + elm->tag_mode, elm->tag, cb, app_key); if(tmperval.encoded == -1) return tmperval; computed_size -= tmperval.encoded; - ASN_DEBUG("Member %d %s of SEQUENCE %s encoded in %ld bytes", + ASN_DEBUG("Member %" ASN_PRI_SIZE " %s of SEQUENCE %s encoded in %ld bytes", edx, elm->name, td->name, (long)tmperval.encoded); } @@ -593,25 +611,26 @@ SEQUENCE_encode_der(asn_TYPE_descriptor_t *td, #undef XER_ADVANCE -#define XER_ADVANCE(num_bytes) do { \ - size_t num = num_bytes; \ - buf_ptr = ((const char *)buf_ptr) + num;\ - size -= num; \ - consumed_myself += num; \ - } while(0) +#define XER_ADVANCE(num_bytes) \ + do { \ + size_t num = (num_bytes); \ + ptr = ((const char *)ptr) + num; \ + size -= num; \ + consumed_myself += num; \ + } while(0) /* * Decode the XER (XML) data. */ asn_dec_rval_t -SEQUENCE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, - void **struct_ptr, const char *opt_mname, - const void *buf_ptr, size_t size) { - /* +SEQUENCE_decode_xer(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *td, void **struct_ptr, + const char *opt_mname, const void *ptr, size_t size) { + /* * Bring closer parts of structure description. */ - asn_SEQUENCE_specifics_t *specs - = (asn_SEQUENCE_specifics_t *)td->specifics; + const asn_SEQUENCE_specifics_t *specs + = (const asn_SEQUENCE_specifics_t *)td->specifics; asn_TYPE_member_t *elements = td->elements; const char *xml_tag = opt_mname ? opt_mname : td->xml_tag; @@ -623,8 +642,7 @@ SEQUENCE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, asn_dec_rval_t rval; /* Return value from a decoder */ ssize_t consumed_myself = 0; /* Consumed bytes from ptr */ - int edx; /* Element index */ - int edx_end; + size_t edx; /* Element index */ /* * Create the target structure if it is not present already. @@ -653,14 +671,13 @@ SEQUENCE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, ssize_t ch_size; /* Chunk size */ xer_check_tag_e tcv; /* Tag check value */ asn_TYPE_member_t *elm; - int n; /* * Go inside the inner member of a sequence. */ if(ctx->phase == 2) { asn_dec_rval_t tmprval; - void *memb_ptr; /* Pointer to the member */ + void *memb_ptr_dontuse; /* Pointer to the member */ void **memb_ptr2; /* Pointer to that pointer */ elm = &td->elements[edx]; @@ -669,14 +686,18 @@ SEQUENCE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, /* Member is a pointer to another structure */ memb_ptr2 = (void **)((char *)st + elm->memb_offset); } else { - memb_ptr = (char *)st + elm->memb_offset; - memb_ptr2 = &memb_ptr; + memb_ptr_dontuse = (char *)st + elm->memb_offset; + memb_ptr2 = &memb_ptr_dontuse; /* Only use of memb_ptr_dontuse */ } - /* Invoke the inner type decoder, m.b. multiple times */ - tmprval = elm->type->xer_decoder(opt_codec_ctx, - elm->type, memb_ptr2, elm->name, - buf_ptr, size); + if(elm->flags & ATF_OPEN_TYPE) { + tmprval = OPEN_TYPE_xer_get(opt_codec_ctx, td, st, elm, ptr, size); + } else { + /* Invoke the inner type decoder, m.b. multiple times */ + tmprval = elm->type->op->xer_decoder(opt_codec_ctx, + elm->type, memb_ptr2, elm->name, + ptr, size); + } XER_ADVANCE(tmprval.consumed); if(tmprval.code != RC_OK) RETURN(tmprval.code); @@ -690,14 +711,14 @@ SEQUENCE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, /* * Get the next part of the XML stream. */ - ch_size = xer_next_token(&ctx->context, buf_ptr, size, + ch_size = xer_next_token(&ctx->context, ptr, size, &ch_type); if(ch_size == -1) { RETURN(RC_FAIL); - } else { + } else { switch(ch_type) { - case PXER_WMORE: - RETURN(RC_WMORE); + case PXER_WMORE: + RETURN(RC_WMORE); case PXER_COMMENT: /* Got XML comment */ case PXER_TEXT: /* Ignore free-standing text */ XER_ADVANCE(ch_size); /* Skip silently */ @@ -707,7 +728,7 @@ SEQUENCE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, } } - tcv = xer_check_tag(buf_ptr, ch_size, xml_tag); + tcv = xer_check_tag(ptr, ch_size, xml_tag); ASN_DEBUG("XER/SEQUENCE: tcv = %d, ph=%d [%s]", tcv, ctx->phase, xml_tag); @@ -736,19 +757,13 @@ SEQUENCE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, ctx->phase = 0; /* Fall through */ case XCT_BOTH: - if(ctx->phase == 0) { - if(edx >= td->elements_count - || - /* Explicit OPTIONAL specs reaches the end */ - (edx + elements[edx].optional - == td->elements_count) - || - /* All extensions are optional */ - (IN_EXTENSION_GROUP(specs, edx) - && specs->ext_before - > td->elements_count) - ) { - XER_ADVANCE(ch_size); + if(ctx->phase == 0) { + if(edx >= td->elements_count || + /* Explicit OPTIONAL specs reaches the end */ + (edx + elements[edx].optional == td->elements_count) || + /* All extensions are optional */ + IN_EXTENSION_GROUP(specs, edx)) { + XER_ADVANCE(ch_size); ctx->phase = 4; /* Phase out */ RETURN(RC_OK); } else { @@ -767,7 +782,7 @@ SEQUENCE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, case XCT_UNKNOWN_OP: case XCT_UNKNOWN_BO: - ASN_DEBUG("XER/SEQUENCE: tcv=%d, ph=%d, edx=%d", + ASN_DEBUG("XER/SEQUENCE: tcv=%d, ph=%d, edx=%" ASN_PRI_SIZE "", tcv, ctx->phase, edx); if(ctx->phase != 1) { break; /* Really unexpected */ @@ -777,13 +792,13 @@ SEQUENCE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, /* * Search which member corresponds to this tag. */ - edx_end = edx + elements[edx].optional + 1; + size_t n; + size_t edx_end = edx + elements[edx].optional + 1; if(edx_end > td->elements_count) edx_end = td->elements_count; for(n = edx; n < edx_end; n++) { elm = &td->elements[n]; - tcv = xer_check_tag(buf_ptr, - ch_size, elm->name); + tcv = xer_check_tag(ptr, ch_size, elm->name); switch(tcv) { case XCT_BOTH: case XCT_OPENING: @@ -805,7 +820,7 @@ SEQUENCE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, if(n != edx_end) continue; } else { - ASN_DEBUG("Out of defined members: %d/%d", + ASN_DEBUG("Out of defined members: %" ASN_PRI_SIZE "/%u", edx, td->elements_count); } @@ -813,7 +828,7 @@ SEQUENCE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, if(IN_EXTENSION_GROUP(specs, edx + (edx < td->elements_count ? elements[edx].optional : 0))) { - ASN_DEBUG("Got anticipated extension at %d", + ASN_DEBUG("Got anticipated extension at %" ASN_PRI_SIZE "", edx); /* * Check for (XCT_BOTH or XCT_UNKNOWN_BO) @@ -836,12 +851,12 @@ SEQUENCE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, } ASN_DEBUG("Unexpected XML tag in SEQUENCE [%c%c%c%c%c%c]", - size>0?((const char *)buf_ptr)[0]:'.', - size>1?((const char *)buf_ptr)[1]:'.', - size>2?((const char *)buf_ptr)[2]:'.', - size>3?((const char *)buf_ptr)[3]:'.', - size>4?((const char *)buf_ptr)[4]:'.', - size>5?((const char *)buf_ptr)[5]:'.'); + size>0?((const char *)ptr)[0]:'.', + size>1?((const char *)ptr)[1]:'.', + size>2?((const char *)ptr)[2]:'.', + size>3?((const char *)ptr)[3]:'.', + size>4?((const char *)ptr)[4]:'.', + size>5?((const char *)ptr)[5]:'.'); break; } @@ -850,60 +865,77 @@ SEQUENCE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, } asn_enc_rval_t -SEQUENCE_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, - int ilevel, enum xer_encoder_flags_e flags, - asn_app_consume_bytes_f *cb, void *app_key) { - asn_enc_rval_t er; - int xcan = (flags & XER_F_CANONICAL); - int edx; - - if(!sptr) - ASN__ENCODE_FAILED; - - er.encoded = 0; - - for(edx = 0; edx < td->elements_count; edx++) { - asn_enc_rval_t tmper; - asn_TYPE_member_t *elm = &td->elements[edx]; - void *memb_ptr; - const char *mname = elm->name; - unsigned int mlen = strlen(mname); - - if(elm->flags & ATF_POINTER) { - memb_ptr = *(void **)((char *)sptr + elm->memb_offset); - if(!memb_ptr) { - if(elm->optional) - continue; - /* Mandatory element is missing */ - ASN__ENCODE_FAILED; - } - } else { - memb_ptr = (void *)((char *)sptr + elm->memb_offset); - } +SEQUENCE_encode_xer(const asn_TYPE_descriptor_t *td, const void *sptr, + int ilevel, enum xer_encoder_flags_e flags, + asn_app_consume_bytes_f *cb, void *app_key) { + asn_enc_rval_t er; + int xcan = (flags & XER_F_CANONICAL); + asn_TYPE_descriptor_t *tmp_def_val_td = 0; + void *tmp_def_val = 0; + size_t edx; + + if(!sptr) ASN__ENCODE_FAILED; + + er.encoded = 0; + + for(edx = 0; edx < td->elements_count; edx++) { + asn_enc_rval_t tmper; + asn_TYPE_member_t *elm = &td->elements[edx]; + const void *memb_ptr; + const char *mname = elm->name; + unsigned int mlen = strlen(mname); + + if(elm->flags & ATF_POINTER) { + memb_ptr = + *(const void *const *)((const char *)sptr + elm->memb_offset); + if(!memb_ptr) { + assert(tmp_def_val == 0); + if(elm->default_value_set) { + if(elm->default_value_set(&tmp_def_val)) { + ASN__ENCODE_FAILED; + } else { + memb_ptr = tmp_def_val; + tmp_def_val_td = elm->type; + } + } else if(elm->optional) { + continue; + } else { + /* Mandatory element is missing */ + ASN__ENCODE_FAILED; + } + } + } else { + memb_ptr = (const void *)((const char *)sptr + elm->memb_offset); + } - if(!xcan) ASN__TEXT_INDENT(1, ilevel); - ASN__CALLBACK3("<", 1, mname, mlen, ">", 1); + if(!xcan) ASN__TEXT_INDENT(1, ilevel); + ASN__CALLBACK3("<", 1, mname, mlen, ">", 1); - /* Print the member itself */ - tmper = elm->type->xer_encoder(elm->type, memb_ptr, - ilevel + 1, flags, cb, app_key); - if(tmper.encoded == -1) return tmper; + /* Print the member itself */ + tmper = elm->type->op->xer_encoder(elm->type, memb_ptr, ilevel + 1, + flags, cb, app_key); + if(tmp_def_val) { + ASN_STRUCT_FREE(*tmp_def_val_td, tmp_def_val); + tmp_def_val = 0; + } + if(tmper.encoded == -1) return tmper; + er.encoded += tmper.encoded; - ASN__CALLBACK3("", 1); - er.encoded += 5 + (2 * mlen) + tmper.encoded; - } + ASN__CALLBACK3("", 1); + } - if(!xcan) ASN__TEXT_INDENT(1, ilevel - 1); + if(!xcan) ASN__TEXT_INDENT(1, ilevel - 1); - ASN__ENCODED_OK(er); + ASN__ENCODED_OK(er); cb_failed: - ASN__ENCODE_FAILED; + if(tmp_def_val) ASN_STRUCT_FREE(*tmp_def_val_td, tmp_def_val); + ASN__ENCODE_FAILED; } int -SEQUENCE_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel, - asn_app_consume_bytes_f *cb, void *app_key) { - int edx; +SEQUENCE_print(const asn_TYPE_descriptor_t *td, const void *sptr, int ilevel, + asn_app_consume_bytes_f *cb, void *app_key) { + size_t edx; int ret; if(!sptr) return (cb("", 8, app_key) < 0) ? -1 : 0; @@ -937,7 +969,7 @@ SEQUENCE_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel, return -1; /* Print the member itself */ - ret = elm->type->print_struct(elm->type, memb_ptr, ilevel + 1, + ret = elm->type->op->print_struct(elm->type, memb_ptr, ilevel + 1, cb, app_key); if(ret) return ret; } @@ -949,8 +981,12 @@ SEQUENCE_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel, } void -SEQUENCE_free(asn_TYPE_descriptor_t *td, void *sptr, int contents_only) { - int edx; +SEQUENCE_free(const asn_TYPE_descriptor_t *td, void *sptr, + enum asn_struct_free_method method) { + size_t edx; + const asn_SEQUENCE_specifics_t *specs = + (const asn_SEQUENCE_specifics_t *)td->specifics; + asn_struct_ctx_t *ctx; /* Decoder context */ if(!td || !sptr) return; @@ -970,15 +1006,28 @@ SEQUENCE_free(asn_TYPE_descriptor_t *td, void *sptr, int contents_only) { } } - if(!contents_only) { - FREEMEM(sptr); - } + /* Clean parsing context */ + ctx = (asn_struct_ctx_t *)((char *)sptr + specs->ctx_offset); + FREEMEM(ctx->ptr); + + switch(method) { + case ASFM_FREE_EVERYTHING: + FREEMEM(sptr); + break; + case ASFM_FREE_UNDERLYING: + break; + case ASFM_FREE_UNDERLYING_AND_RESET: + memset( + sptr, 0, + ((const asn_SEQUENCE_specifics_t *)(td->specifics))->struct_size); + break; + } } int -SEQUENCE_constraint(asn_TYPE_descriptor_t *td, const void *sptr, - asn_app_constraint_failed_f *ctfailcb, void *app_key) { - int edx; +SEQUENCE_constraint(const asn_TYPE_descriptor_t *td, const void *sptr, + asn_app_constraint_failed_f *ctfailcb, void *app_key) { + size_t edx; if(!sptr) { ASN__CTFAIL(app_key, td, sptr, @@ -1008,35 +1057,33 @@ SEQUENCE_constraint(asn_TYPE_descriptor_t *td, const void *sptr, memb_ptr = (const void *)((const char *)sptr + elm->memb_offset); } - if(elm->memb_constraints) { - int ret = elm->memb_constraints(elm->type, memb_ptr, + if(elm->encoding_constraints.general_constraints) { + int ret = elm->encoding_constraints.general_constraints(elm->type, memb_ptr, ctfailcb, app_key); if(ret) return ret; } else { - int ret = elm->type->check_constraints(elm->type, + return elm->type->encoding_constraints.general_constraints(elm->type, memb_ptr, ctfailcb, app_key); - if(ret) return ret; - /* - * Cannot inherit it earlier: - * need to make sure we get the updated version. - */ - elm->memb_constraints = elm->type->check_constraints; } } return 0; } +#ifndef ASN_DISABLE_PER_SUPPORT + asn_dec_rval_t -SEQUENCE_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, - asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { - asn_SEQUENCE_specifics_t *specs = (asn_SEQUENCE_specifics_t *)td->specifics; +SEQUENCE_decode_uper(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, void **sptr, + asn_per_data_t *pd) { + const asn_SEQUENCE_specifics_t *specs = (const asn_SEQUENCE_specifics_t *)td->specifics; void *st = *sptr; /* Target structure. */ int extpresent; /* Extension additions are present */ uint8_t *opres; /* Presence of optional root members */ asn_per_data_t opmd; asn_dec_rval_t rv; - int edx; + size_t edx; (void)constraints; @@ -1051,11 +1098,11 @@ SEQUENCE_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, ASN_DEBUG("Decoding %s as SEQUENCE (UPER)", td->name); /* Handle extensions */ - if(specs->ext_before >= 0) { + if(specs->first_extension < 0) { + extpresent = 0; + } else { extpresent = per_get_few_bits(pd, 1); if(extpresent < 0) ASN__DECODE_STARVED; - } else { - extpresent = 0; } /* Prepare a place and read-in the presence bitmap */ @@ -1079,13 +1126,15 @@ SEQUENCE_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, /* * Get the sequence ROOT elements. */ - for(edx = 0; edx < td->elements_count; edx++) { - asn_TYPE_member_t *elm = &td->elements[edx]; + for(edx = 0; + edx < (specs->first_extension < 0 ? td->elements_count + : (size_t)specs->first_extension); + edx++) { + asn_TYPE_member_t *elm = &td->elements[edx]; void *memb_ptr; /* Pointer to the member */ void **memb_ptr2; /* Pointer to that pointer */ - if(IN_EXTENSION_GROUP(specs, edx)) - continue; + assert(!IN_EXTENSION_GROUP(specs, edx)); /* Fetch the pointer to this member */ if(elm->flags & ATF_POINTER) { @@ -1103,9 +1152,9 @@ SEQUENCE_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, (int)opmd.nboff, (int)opmd.nbits); if(present == 0) { /* This element is not present */ - if(elm->default_value) { + if(elm->default_value_set) { /* Fill-in DEFAULT */ - if(elm->default_value(1, memb_ptr2)) { + if(elm->default_value_set(memb_ptr2)) { FREEMEM(opres); ASN__DECODE_FAILED; } @@ -1118,9 +1167,14 @@ SEQUENCE_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, } /* Fetch the member from the stream */ - ASN_DEBUG("Decoding member %s in %s", elm->name, td->name); - rv = elm->type->uper_decoder(opt_codec_ctx, elm->type, - elm->per_constraints, memb_ptr2, pd); + ASN_DEBUG("Decoding member \"%s\" in %s", elm->name, td->name); + + if(elm->flags & ATF_OPEN_TYPE) { + rv = OPEN_TYPE_uper_get(opt_codec_ctx, td, st, elm, pd); + } else { + rv = elm->type->op->uper_decoder(opt_codec_ctx, elm->type, + elm->encoding_constraints.per_constraints, memb_ptr2, pd); + } if(rv.code != RC_OK) { ASN_DEBUG("Failed decode %s in %s", elm->name, td->name); @@ -1143,7 +1197,7 @@ SEQUENCE_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, bmlength = uper_get_nslength(pd); if(bmlength < 0) ASN__DECODE_STARVED; - ASN_DEBUG("Extensions %ld present in %s", (long)bmlength, td->name); + ASN_DEBUG("Extensions %" ASN_PRI_SSIZE " present in %s", bmlength, td->name); epres = (uint8_t *)MALLOC((bmlength + 15) >> 3); if(!epres) ASN__DECODE_STARVED; @@ -1161,38 +1215,35 @@ SEQUENCE_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, td->name, (long)bmlength, *epres); /* Go over extensions and read them in */ - for(edx = specs->ext_after + 1; edx < td->elements_count; edx++) { - asn_TYPE_member_t *elm = &td->elements[edx]; - void *memb_ptr; /* Pointer to the member */ - void **memb_ptr2; /* Pointer to that pointer */ - int present; - - if(!IN_EXTENSION_GROUP(specs, edx)) { - ASN_DEBUG("%d is not extension", edx); - continue; - } - - /* Fetch the pointer to this member */ - if(elm->flags & ATF_POINTER) { - memb_ptr2 = (void **)((char *)st + elm->memb_offset); - } else { - memb_ptr = (void *)((char *)st + elm->memb_offset); - memb_ptr2 = &memb_ptr; - } - - present = per_get_few_bits(&epmd, 1); - if(present <= 0) { - if(present < 0) break; /* No more extensions */ - continue; - } - - ASN_DEBUG("Decoding member %s in %s %p", elm->name, td->name, *memb_ptr2); - rv = uper_open_type_get(opt_codec_ctx, elm->type, - elm->per_constraints, memb_ptr2, pd); - if(rv.code != RC_OK) { - FREEMEM(epres); - return rv; - } + for(edx = specs->first_extension; edx < td->elements_count; edx++) { + asn_TYPE_member_t *elm = &td->elements[edx]; + void *memb_ptr; /* Pointer to the member */ + void **memb_ptr2; /* Pointer to that pointer */ + int present; + + /* Fetch the pointer to this member */ + if(elm->flags & ATF_POINTER) { + memb_ptr2 = (void **)((char *)st + elm->memb_offset); + } else { + memb_ptr = (void *)((char *)st + elm->memb_offset); + memb_ptr2 = &memb_ptr; + } + + present = per_get_few_bits(&epmd, 1); + if(present <= 0) { + if(present < 0) break; /* No more extensions */ + continue; + } + + ASN_DEBUG("Decoding member %s in %s %p", elm->name, td->name, + *memb_ptr2); + rv = uper_open_type_get(opt_codec_ctx, elm->type, + elm->encoding_constraints.per_constraints, + memb_ptr2, pd); + if(rv.code != RC_OK) { + FREEMEM(epres); + return rv; + } } /* Skip over overflow extensions which aren't present @@ -1207,6 +1258,8 @@ SEQUENCE_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, FREEMEM(epres); ASN__DECODE_STARVED; } + ASN_DEBUG("Skipped overflow extension"); + continue; } break; } @@ -1214,28 +1267,33 @@ SEQUENCE_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, FREEMEM(epres); } - /* Fill DEFAULT members in extensions */ - for(edx = specs->roms_count; edx < specs->roms_count - + specs->aoms_count; edx++) { - asn_TYPE_member_t *elm = &td->elements[edx]; - void **memb_ptr2; /* Pointer to member pointer */ - - if(!elm->default_value) continue; - - /* Fetch the pointer to this member */ - if(elm->flags & ATF_POINTER) { - memb_ptr2 = (void **)((char *)st - + elm->memb_offset); - if(*memb_ptr2) continue; - } else { - continue; /* Extensions are all optionals */ - } - - /* Set default value */ - if(elm->default_value(1, memb_ptr2)) { - ASN__DECODE_FAILED; - } - } + if(specs->first_extension >= 0) { + unsigned i; + /* Fill DEFAULT members in extensions */ + for(i = specs->roms_count; i < specs->roms_count + specs->aoms_count; + i++) { + asn_TYPE_member_t *elm; + void **memb_ptr2; /* Pointer to member pointer */ + + edx = specs->oms[i]; + elm = &td->elements[edx]; + + if(!elm->default_value_set) continue; + + /* Fetch the pointer to this member */ + if(elm->flags & ATF_POINTER) { + memb_ptr2 = (void **)((char *)st + elm->memb_offset); + if(*memb_ptr2) continue; + } else { + continue; /* Extensions are all optionals */ + } + + /* Set default value */ + if(elm->default_value_set(memb_ptr2)) { + ASN__DECODE_FAILED; + } + } + } rv.consumed = 0; rv.code = RC_OK; @@ -1243,66 +1301,66 @@ SEQUENCE_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, } static int -SEQUENCE_handle_extensions(asn_TYPE_descriptor_t *td, void *sptr, - asn_per_outp_t *po1, asn_per_outp_t *po2) { - asn_SEQUENCE_specifics_t *specs - = (asn_SEQUENCE_specifics_t *)td->specifics; - int exts_present = 0; - int exts_count = 0; - int edx; - - if(specs->ext_before < 0) - return 0; - - /* Find out which extensions are present */ - for(edx = specs->ext_after + 1; edx < td->elements_count; edx++) { - asn_TYPE_member_t *elm = &td->elements[edx]; - void *memb_ptr; /* Pointer to the member */ - void **memb_ptr2; /* Pointer to that pointer */ - int present; - - if(!IN_EXTENSION_GROUP(specs, edx)) { - ASN_DEBUG("%s (@%d) is not extension", elm->type->name, edx); - continue; - } - - /* Fetch the pointer to this member */ - if(elm->flags & ATF_POINTER) { - memb_ptr2 = (void **)((char *)sptr + elm->memb_offset); - present = (*memb_ptr2 != 0); - } else { - memb_ptr = (void *)((char *)sptr + elm->memb_offset); - memb_ptr2 = &memb_ptr; +SEQUENCE__handle_extensions(const asn_TYPE_descriptor_t *td, const void *sptr, + asn_per_outp_t *po1, asn_per_outp_t *po2) { + const asn_SEQUENCE_specifics_t *specs = + (const asn_SEQUENCE_specifics_t *)td->specifics; + int exts_present = 0; + int exts_count = 0; + size_t edx; + + if(specs->first_extension < 0) { + return 0; + } + + /* Find out which extensions are present */ + for(edx = specs->first_extension; edx < td->elements_count; edx++) { + asn_TYPE_member_t *elm = &td->elements[edx]; + const void *memb_ptr; /* Pointer to the member */ + const void *const *memb_ptr2; /* Pointer to that pointer */ + int present; + + /* Fetch the pointer to this member */ + if(elm->flags & ATF_POINTER) { + memb_ptr2 = + (const void *const *)((const char *)sptr + elm->memb_offset); + present = (*memb_ptr2 != 0); + } else { + memb_ptr = (const void *)((const char *)sptr + elm->memb_offset); + memb_ptr2 = &memb_ptr; present = 1; } - ASN_DEBUG("checking %s (@%d) present => %d", - elm->type->name, edx, present); - exts_count++; - exts_present += present; - - /* Encode as presence marker */ - if(po1 && per_put_few_bits(po1, present, 1)) - return -1; - /* Encode as open type field */ - if(po2 && present && uper_open_type_put(elm->type, - elm->per_constraints, *memb_ptr2, po2)) - return -1; - - } - - return exts_present ? exts_count : 0; + ASN_DEBUG("checking %s:%s (@%" ASN_PRI_SIZE ") present => %d", elm->name, + elm->type->name, edx, present); + exts_count++; + exts_present += present; + + /* Encode as presence marker */ + if(po1 && per_put_few_bits(po1, present, 1)) { + return -1; + } + /* Encode as open type field */ + if(po2 && present + && uper_open_type_put(elm->type, + elm->encoding_constraints.per_constraints, + *memb_ptr2, po2)) + return -1; + } + + return exts_present ? exts_count : 0; } asn_enc_rval_t -SEQUENCE_encode_uper(asn_TYPE_descriptor_t *td, - asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { - asn_SEQUENCE_specifics_t *specs - = (asn_SEQUENCE_specifics_t *)td->specifics; +SEQUENCE_encode_uper(const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, const void *sptr, + asn_per_outp_t *po) { + const asn_SEQUENCE_specifics_t *specs + = (const asn_SEQUENCE_specifics_t *)td->specifics; asn_enc_rval_t er; int n_extensions; - int edx; - int i; + size_t edx; + size_t i; (void)constraints; @@ -1313,46 +1371,49 @@ SEQUENCE_encode_uper(asn_TYPE_descriptor_t *td, ASN_DEBUG("Encoding %s as SEQUENCE (UPER)", td->name); - /* * X.691#18.1 Whether structure is extensible * and whether to encode extensions */ - if(specs->ext_before >= 0) { - n_extensions = SEQUENCE_handle_extensions(td, sptr, 0, 0); - per_put_few_bits(po, n_extensions ? 1 : 0, 1); - } else { - n_extensions = 0; /* There are no extensions to encode */ - } + if(specs->first_extension < 0) { + n_extensions = 0; /* There are no extensions to encode */ + } else { + n_extensions = SEQUENCE__handle_extensions(td, sptr, 0, 0); + if(n_extensions < 0) ASN__ENCODE_FAILED; + if(per_put_few_bits(po, n_extensions ? 1 : 0, 1)) { + ASN__ENCODE_FAILED; + } + } /* Encode a presence bitmap */ for(i = 0; i < specs->roms_count; i++) { asn_TYPE_member_t *elm; - void *memb_ptr; /* Pointer to the member */ - void **memb_ptr2; /* Pointer to that pointer */ - int present; + const void *memb_ptr; /* Pointer to the member */ + const void *const *memb_ptr2; /* Pointer to that pointer */ + int present; edx = specs->oms[i]; elm = &td->elements[edx]; /* Fetch the pointer to this member */ if(elm->flags & ATF_POINTER) { - memb_ptr2 = (void **)((char *)sptr + elm->memb_offset); - present = (*memb_ptr2 != 0); + memb_ptr2 = + (const void *const *)((const char *)sptr + elm->memb_offset); + present = (*memb_ptr2 != 0); } else { - memb_ptr = (void *)((char *)sptr + elm->memb_offset); - memb_ptr2 = &memb_ptr; + memb_ptr = (const void *)((const char *)sptr + elm->memb_offset); + memb_ptr2 = &memb_ptr; present = 1; } /* Eliminate default values */ - if(present && elm->default_value - && elm->default_value(0, memb_ptr2) == 1) - present = 0; + if(present && elm->default_value_cmp + && elm->default_value_cmp(*memb_ptr2) == 0) + present = 0; ASN_DEBUG("Element %s %s %s->%s is %s", elm->flags & ATF_POINTER ? "ptr" : "inline", - elm->default_value ? "def" : "wtv", + elm->default_value_cmp ? "def" : "wtv", td->name, elm->name, present ? "present" : "absent"); if(per_put_few_bits(po, present, 1)) ASN__ENCODE_FAILED; @@ -1361,24 +1422,24 @@ SEQUENCE_encode_uper(asn_TYPE_descriptor_t *td, /* * Encode the sequence ROOT elements. */ - ASN_DEBUG("ext_after = %d, ec = %d, eb = %d", specs->ext_after, td->elements_count, specs->ext_before); - for(edx = 0; edx < ((specs->ext_after < 0) - ? td->elements_count : specs->ext_before - 1); edx++) { - + ASN_DEBUG("first_extension = %d, elements = %d", specs->first_extension, + td->elements_count); + for(edx = 0; + edx < ((specs->first_extension < 0) ? td->elements_count + : (size_t)specs->first_extension); + edx++) { asn_TYPE_member_t *elm = &td->elements[edx]; - void *memb_ptr; /* Pointer to the member */ - void **memb_ptr2; /* Pointer to that pointer */ - - if(IN_EXTENSION_GROUP(specs, edx)) - continue; + const void *memb_ptr; /* Pointer to the member */ + const void *const *memb_ptr2; /* Pointer to that pointer */ ASN_DEBUG("About to encode %s", elm->type->name); /* Fetch the pointer to this member */ if(elm->flags & ATF_POINTER) { - memb_ptr2 = (void **)((char *)sptr + elm->memb_offset); - if(!*memb_ptr2) { - ASN_DEBUG("Element %s %d not present", + memb_ptr2 = + (const void *const *)((const char *)sptr + elm->memb_offset); + if(!*memb_ptr2) { + ASN_DEBUG("Element %s %" ASN_PRI_SIZE " not present", elm->name, edx); if(elm->optional) continue; @@ -1386,25 +1447,25 @@ SEQUENCE_encode_uper(asn_TYPE_descriptor_t *td, ASN__ENCODE_FAILED; } } else { - memb_ptr = (void *)((char *)sptr + elm->memb_offset); - memb_ptr2 = &memb_ptr; + memb_ptr = (const void *)((const char *)sptr + elm->memb_offset); + memb_ptr2 = &memb_ptr; } /* Eliminate default values */ - if(elm->default_value && elm->default_value(0, memb_ptr2) == 1) + if(elm->default_value_cmp && elm->default_value_cmp(*memb_ptr2) == 0) continue; - ASN_DEBUG("Encoding %s->%s", td->name, elm->name); - er = elm->type->uper_encoder(elm->type, elm->per_constraints, - *memb_ptr2, po); - if(er.encoded == -1) - return er; - } + ASN_DEBUG("Encoding %s->%s:%s", td->name, elm->name, elm->type->name); + er = elm->type->op->uper_encoder( + elm->type, elm->encoding_constraints.per_constraints, *memb_ptr2, + po); + if(er.encoded == -1) return er; + } /* No extensions to encode */ if(!n_extensions) ASN__ENCODED_OK(er); - ASN_DEBUG("Length of %d bit-map", n_extensions); + ASN_DEBUG("Length of extensions %d bit-map", n_extensions); /* #18.8. Write down the presence bit-map length. */ if(uper_put_nslength(po, n_extensions)) ASN__ENCODE_FAILED; @@ -1412,14 +1473,154 @@ SEQUENCE_encode_uper(asn_TYPE_descriptor_t *td, ASN_DEBUG("Bit-map of %d elements", n_extensions); /* #18.7. Encoding the extensions presence bit-map. */ /* TODO: act upon NOTE in #18.7 for canonical PER */ - if(SEQUENCE_handle_extensions(td, sptr, po, 0) != n_extensions) + if(SEQUENCE__handle_extensions(td, sptr, po, 0) != n_extensions) ASN__ENCODE_FAILED; ASN_DEBUG("Writing %d extensions", n_extensions); /* #18.9. Encode extensions as open type fields. */ - if(SEQUENCE_handle_extensions(td, sptr, 0, po) != n_extensions) + if(SEQUENCE__handle_extensions(td, sptr, 0, po) != n_extensions) ASN__ENCODE_FAILED; ASN__ENCODED_OK(er); } +#endif /* ASN_DISABLE_PER_SUPPORT */ + +int +SEQUENCE_compare(const asn_TYPE_descriptor_t *td, const void *aptr, + const void *bptr) { + size_t edx; + + for(edx = 0; edx < td->elements_count; edx++) { + asn_TYPE_member_t *elm = &td->elements[edx]; + const void *amemb; + const void *bmemb; + int ret; + + if(elm->flags & ATF_POINTER) { + amemb = + *(const void *const *)((const char *)aptr + elm->memb_offset); + bmemb = + *(const void *const *)((const char *)bptr + elm->memb_offset); + if(!amemb) { + if(!bmemb) continue; + if(elm->default_value_cmp + && elm->default_value_cmp(bmemb) == 0) { + /* A is absent, but B is present and equal to DEFAULT */ + continue; + } + return -1; + } else if(!bmemb) { + if(elm->default_value_cmp + && elm->default_value_cmp(amemb) == 0) { + /* B is absent, but A is present and equal to DEFAULT */ + continue; + } + return 1; + } + } else { + amemb = (const void *)((const char *)aptr + elm->memb_offset); + bmemb = (const void *)((const char *)bptr + elm->memb_offset); + } + + ret = elm->type->op->compare_struct(elm->type, amemb, bmemb); + if(ret != 0) return ret; + } + + return 0; +} + +asn_TYPE_operation_t asn_OP_SEQUENCE = { + SEQUENCE_free, + SEQUENCE_print, + SEQUENCE_compare, + SEQUENCE_decode_ber, + SEQUENCE_encode_der, + SEQUENCE_decode_xer, + SEQUENCE_encode_xer, +#ifdef ASN_DISABLE_OER_SUPPORT + 0, + 0, +#else + SEQUENCE_decode_oer, + SEQUENCE_encode_oer, +#endif /* ASN_DISABLE_OER_SUPPORT */ +#ifdef ASN_DISABLE_PER_SUPPORT + 0, + 0, +#else + SEQUENCE_decode_uper, + SEQUENCE_encode_uper, +#endif /* ASN_DISABLE_PER_SUPPORT */ + SEQUENCE_random_fill, + 0 /* Use generic outmost tag fetcher */ +}; + + +asn_random_fill_result_t +SEQUENCE_random_fill(const asn_TYPE_descriptor_t *td, void **sptr, + const asn_encoding_constraints_t *constr, + size_t max_length) { + const asn_SEQUENCE_specifics_t *specs = + (const asn_SEQUENCE_specifics_t *)td->specifics; + asn_random_fill_result_t result_ok = {ARFILL_OK, 0}; + asn_random_fill_result_t result_failed = {ARFILL_FAILED, 0}; + asn_random_fill_result_t result_skipped = {ARFILL_SKIPPED, 0}; + void *st = *sptr; + size_t edx; + + if(max_length == 0) return result_skipped; + + (void)constr; + + if(st == NULL) { + st = CALLOC(1, specs->struct_size); + if(st == NULL) { + return result_failed; + } + } + + for(edx = 0; edx < td->elements_count; edx++) { + const asn_TYPE_member_t *elm = &td->elements[edx]; + void *memb_ptr; /* Pointer to the member */ + void **memb_ptr2; /* Pointer to that pointer */ + asn_random_fill_result_t tmpres; + + if(elm->optional && asn_random_between(0, 4) == 2) { + /* Sometimes decide not to fill the optional value */ + continue; + } + + if(elm->flags & ATF_POINTER) { + /* Member is a pointer to another structure */ + memb_ptr2 = (void **)((char *)st + elm->memb_offset); + } else { + memb_ptr = (char *)st + elm->memb_offset; + memb_ptr2 = &memb_ptr; + } + + tmpres = elm->type->op->random_fill( + elm->type, memb_ptr2, &elm->encoding_constraints, + max_length > result_ok.length ? max_length - result_ok.length : 0); + switch(tmpres.code) { + case ARFILL_OK: + result_ok.length += tmpres.length; + continue; + case ARFILL_SKIPPED: + assert(!(elm->flags & ATF_POINTER) || *memb_ptr2 == NULL); + continue; + case ARFILL_FAILED: + if(st == *sptr) { + ASN_STRUCT_RESET(*td, st); + } else { + ASN_STRUCT_FREE(*td, st); + } + return tmpres; + } + } + + *sptr = st; + + return result_ok; +} + diff --git a/libs/smux/constr_SEQUENCE_OF.c b/libs/smux/constr_SEQUENCE_OF.c index 8a08ee8a..2fdc38f2 100644 --- a/libs/smux/constr_SEQUENCE_OF.c +++ b/libs/smux/constr_SEQUENCE_OF.c @@ -11,11 +11,11 @@ * The DER encoder of the SEQUENCE OF type. */ asn_enc_rval_t -SEQUENCE_OF_encode_der(asn_TYPE_descriptor_t *td, void *ptr, - int tag_mode, ber_tlv_tag_t tag, - asn_app_consume_bytes_f *cb, void *app_key) { - asn_TYPE_member_t *elm = td->elements; - asn_anonymous_sequence_ *list = _A_SEQUENCE_FROM_VOID(ptr); +SEQUENCE_OF_encode_der(const asn_TYPE_descriptor_t *td, const void *ptr, + int tag_mode, ber_tlv_tag_t tag, + asn_app_consume_bytes_f *cb, void *app_key) { + asn_TYPE_member_t *elm = td->elements; + const asn_anonymous_sequence_ *list = _A_CSEQUENCE_FROM_VOID(ptr); size_t computed_size = 0; ssize_t encoding_size = 0; asn_enc_rval_t erval; @@ -29,7 +29,7 @@ SEQUENCE_OF_encode_der(asn_TYPE_descriptor_t *td, void *ptr, for(edx = 0; edx < list->count; edx++) { void *memb_ptr = list->array[edx]; if(!memb_ptr) continue; - erval = elm->type->der_encoder(elm->type, memb_ptr, + erval = elm->type->op->der_encoder(elm->type, memb_ptr, 0, elm->tag, 0, 0); if(erval.encoded == -1) @@ -63,7 +63,7 @@ SEQUENCE_OF_encode_der(asn_TYPE_descriptor_t *td, void *ptr, for(edx = 0; edx < list->count; edx++) { void *memb_ptr = list->array[edx]; if(!memb_ptr) continue; - erval = elm->type->der_encoder(elm->type, memb_ptr, + erval = elm->type->op->der_encoder(elm->type, memb_ptr, 0, elm->tag, cb, app_key); if(erval.encoded == -1) @@ -88,121 +88,197 @@ SEQUENCE_OF_encode_der(asn_TYPE_descriptor_t *td, void *ptr, } asn_enc_rval_t -SEQUENCE_OF_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, - int ilevel, enum xer_encoder_flags_e flags, - asn_app_consume_bytes_f *cb, void *app_key) { - asn_enc_rval_t er; - asn_SET_OF_specifics_t *specs = (asn_SET_OF_specifics_t *)td->specifics; - asn_TYPE_member_t *elm = td->elements; - asn_anonymous_sequence_ *list = _A_SEQUENCE_FROM_VOID(sptr); - const char *mname = specs->as_XMLValueList - ? 0 : ((*elm->name) ? elm->name : elm->type->xml_tag); - unsigned int mlen = mname ? strlen(mname) : 0; - int xcan = (flags & XER_F_CANONICAL); - int i; +SEQUENCE_OF_encode_xer(const asn_TYPE_descriptor_t *td, const void *sptr, + int ilevel, enum xer_encoder_flags_e flags, + asn_app_consume_bytes_f *cb, void *app_key) { + asn_enc_rval_t er; + const asn_SET_OF_specifics_t *specs = (const asn_SET_OF_specifics_t *)td->specifics; + const asn_TYPE_member_t *elm = td->elements; + const asn_anonymous_sequence_ *list = _A_CSEQUENCE_FROM_VOID(sptr); + const char *mname = specs->as_XMLValueList + ? 0 + : ((*elm->name) ? elm->name : elm->type->xml_tag); + size_t mlen = mname ? strlen(mname) : 0; + int xcan = (flags & XER_F_CANONICAL); + int i; - if(!sptr) ASN__ENCODE_FAILED; + if(!sptr) ASN__ENCODE_FAILED; - er.encoded = 0; + er.encoded = 0; - for(i = 0; i < list->count; i++) { - asn_enc_rval_t tmper; - void *memb_ptr = list->array[i]; - if(!memb_ptr) continue; + for(i = 0; i < list->count; i++) { + asn_enc_rval_t tmper; + void *memb_ptr = list->array[i]; + if(!memb_ptr) continue; - if(mname) { - if(!xcan) ASN__TEXT_INDENT(1, ilevel); - ASN__CALLBACK3("<", 1, mname, mlen, ">", 1); - } - - tmper = elm->type->xer_encoder(elm->type, memb_ptr, - ilevel + 1, flags, cb, app_key); - if(tmper.encoded == -1) return tmper; - if(tmper.encoded == 0 && specs->as_XMLValueList) { - const char *name = elm->type->xml_tag; - size_t len = strlen(name); - if(!xcan) ASN__TEXT_INDENT(1, ilevel + 1); - ASN__CALLBACK3("<", 1, name, len, "/>", 2); - } - - if(mname) { - ASN__CALLBACK3("", 1); - er.encoded += 5; - } - - er.encoded += (2 * mlen) + tmper.encoded; - } + if(mname) { + if(!xcan) ASN__TEXT_INDENT(1, ilevel); + ASN__CALLBACK3("<", 1, mname, mlen, ">", 1); + } - if(!xcan) ASN__TEXT_INDENT(1, ilevel - 1); + tmper = elm->type->op->xer_encoder(elm->type, memb_ptr, ilevel + 1, + flags, cb, app_key); + if(tmper.encoded == -1) return tmper; + er.encoded += tmper.encoded; + if(tmper.encoded == 0 && specs->as_XMLValueList) { + const char *name = elm->type->xml_tag; + size_t len = strlen(name); + if(!xcan) ASN__TEXT_INDENT(1, ilevel + 1); + ASN__CALLBACK3("<", 1, name, len, "/>", 2); + } - ASN__ENCODED_OK(er); + if(mname) { + ASN__CALLBACK3("", 1); + } + } + + if(!xcan) ASN__TEXT_INDENT(1, ilevel - 1); + + ASN__ENCODED_OK(er); cb_failed: - ASN__ENCODE_FAILED; + ASN__ENCODE_FAILED; } +#ifndef ASN_DISABLE_PER_SUPPORT + asn_enc_rval_t -SEQUENCE_OF_encode_uper(asn_TYPE_descriptor_t *td, - asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { - asn_anonymous_sequence_ *list; - asn_per_constraint_t *ct; +SEQUENCE_OF_encode_uper(const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, + const void *sptr, asn_per_outp_t *po) { + const asn_anonymous_sequence_ *list; + const asn_per_constraint_t *ct; asn_enc_rval_t er; - asn_TYPE_member_t *elm = td->elements; - int seq; + const asn_TYPE_member_t *elm = td->elements; + size_t encoded_edx; if(!sptr) ASN__ENCODE_FAILED; - list = _A_SEQUENCE_FROM_VOID(sptr); + list = _A_CSEQUENCE_FROM_VOID(sptr); - er.encoded = 0; + er.encoded = 0; ASN_DEBUG("Encoding %s as SEQUENCE OF (%d)", td->name, list->count); - if(constraints) ct = &constraints->size; - else if(td->per_constraints) ct = &td->per_constraints->size; - else ct = 0; - - /* If extensible constraint, check if size is in root */ - if(ct) { - int not_in_root = (list->count < ct->lower_bound - || list->count > ct->upper_bound); - ASN_DEBUG("lb %ld ub %ld %s", - ct->lower_bound, ct->upper_bound, - ct->flags & APC_EXTENSIBLE ? "ext" : "fix"); - if(ct->flags & APC_EXTENSIBLE) { - /* Declare whether size is in extension root */ - if(per_put_few_bits(po, not_in_root, 1)) - ASN__ENCODE_FAILED; - if(not_in_root) ct = 0; - } else if(not_in_root && ct->effective_bits >= 0) - ASN__ENCODE_FAILED; - } + if(constraints) ct = &constraints->size; + else if(td->encoding_constraints.per_constraints) + ct = &td->encoding_constraints.per_constraints->size; + else ct = 0; - if(ct && ct->effective_bits >= 0) { - /* X.691, #19.5: No length determinant */ - if(per_put_few_bits(po, list->count - ct->lower_bound, - ct->effective_bits)) - ASN__ENCODE_FAILED; - } + /* If extensible constraint, check if size is in root */ + if(ct) { + int not_in_root = + (list->count < ct->lower_bound || list->count > ct->upper_bound); + ASN_DEBUG("lb %ld ub %ld %s", ct->lower_bound, ct->upper_bound, + ct->flags & APC_EXTENSIBLE ? "ext" : "fix"); + if(ct->flags & APC_EXTENSIBLE) { + /* Declare whether size is in extension root */ + if(per_put_few_bits(po, not_in_root, 1)) ASN__ENCODE_FAILED; + if(not_in_root) ct = 0; + } else if(not_in_root && ct->effective_bits >= 0) { + ASN__ENCODE_FAILED; + } - for(seq = -1; seq < list->count;) { - ssize_t mayEncode; - if(seq < 0) seq = 0; - if(ct && ct->effective_bits >= 0) { - mayEncode = list->count; - } else { - mayEncode = uper_put_length(po, list->count - seq); - if(mayEncode < 0) ASN__ENCODE_FAILED; - } - - while(mayEncode--) { - void *memb_ptr = list->array[seq++]; - if(!memb_ptr) ASN__ENCODE_FAILED; - er = elm->type->uper_encoder(elm->type, - elm->per_constraints, memb_ptr, po); - if(er.encoded == -1) - ASN__ENCODE_FAILED; - } - } + } + + if(ct && ct->effective_bits >= 0) { + /* X.691, #19.5: No length determinant */ + if(per_put_few_bits(po, list->count - ct->lower_bound, + ct->effective_bits)) + ASN__ENCODE_FAILED; + } else if(list->count == 0) { + /* When the list is empty add only the length determinant + * X.691, #20.6 and #11.9.4.1 + */ + if (uper_put_length(po, 0, 0)) { + ASN__ENCODE_FAILED; + } + ASN__ENCODED_OK(er); + } + + for(encoded_edx = 0; (ssize_t)encoded_edx < list->count;) { + ssize_t may_encode; + size_t edx; + int need_eom = 0; + + if(ct && ct->effective_bits >= 0) { + may_encode = list->count; + } else { + may_encode = + uper_put_length(po, list->count - encoded_edx, &need_eom); + if(may_encode < 0) ASN__ENCODE_FAILED; + } + + for(edx = encoded_edx; edx < encoded_edx + may_encode; edx++) { + void *memb_ptr = list->array[edx]; + if(!memb_ptr) ASN__ENCODE_FAILED; + er = elm->type->op->uper_encoder( + elm->type, elm->encoding_constraints.per_constraints, memb_ptr, + po); + if(er.encoded == -1) ASN__ENCODE_FAILED; + } + + if(need_eom && uper_put_length(po, 0, 0)) + ASN__ENCODE_FAILED; /* End of Message length */ + + encoded_edx += may_encode; + } ASN__ENCODED_OK(er); } +#endif /* ASN_DISABLE_PER_SUPPORT */ + +int +SEQUENCE_OF_compare(const asn_TYPE_descriptor_t *td, const void *aptr, + const void *bptr) { + const asn_anonymous_sequence_ *a = _A_CSEQUENCE_FROM_VOID(aptr); + const asn_anonymous_sequence_ *b = _A_CSEQUENCE_FROM_VOID(bptr); + ssize_t idx; + + if(a && b) { + ssize_t common_length = (a->count < b->count ? a->count : b->count); + for(idx = 0; idx < common_length; idx++) { + int ret = td->elements->type->op->compare_struct( + td->elements->type, a->array[idx], b->array[idx]); + if(ret) return ret; + } + + if(idx < b->count) /* more elements in b */ + return -1; /* a is shorter, so put it first */ + if(idx < a->count) return 1; + + } else if(!a) { + return -1; + } else if(!b) { + return 1; + } + + return 0; +} + + +asn_TYPE_operation_t asn_OP_SEQUENCE_OF = { + SEQUENCE_OF_free, + SEQUENCE_OF_print, + SEQUENCE_OF_compare, + SEQUENCE_OF_decode_ber, + SEQUENCE_OF_encode_der, + SEQUENCE_OF_decode_xer, + SEQUENCE_OF_encode_xer, +#ifdef ASN_DISABLE_OER_SUPPORT + 0, + 0, +#else + SEQUENCE_OF_decode_oer, /* Same as SET OF decoder. */ + SEQUENCE_OF_encode_oer, /* Same as SET OF encoder */ +#endif /* ASN_DISABLE_OER_SUPPORT */ +#ifdef ASN_DISABLE_PER_SUPPORT + 0, + 0, +#else + SEQUENCE_OF_decode_uper, /* Same as SET OF decoder */ + SEQUENCE_OF_encode_uper, +#endif /* ASN_DISABLE_PER_SUPPORT */ + SEQUENCE_OF_random_fill, + 0 /* Use generic outmost tag fetcher */ +}; + diff --git a/libs/smux/constr_SEQUENCE_oer.c b/libs/smux/constr_SEQUENCE_oer.c new file mode 100644 index 00000000..4f290a12 --- /dev/null +++ b/libs/smux/constr_SEQUENCE_oer.c @@ -0,0 +1,561 @@ +/* + * Copyright (c) 2017 Lev Walkin . + * All rights reserved. + * Redistribution and modifications are permitted subject to BSD license. + */ +#ifndef ASN_DISABLE_OER_SUPPORT + +#include +#include +#include +#include + +/* + * This macro "eats" the part of the buffer which is definitely "consumed", + * i.e. was correctly converted into local representation or rightfully skipped. + */ +#undef ADVANCE +#define ADVANCE(num_bytes) \ + do { \ + size_t num = num_bytes; \ + ptr = ((const char *)ptr) + num; \ + size -= num; \ + consumed_myself += num; \ + } while(0) + +/* + * Switch to the next phase of parsing. + */ +#undef NEXT_PHASE +#undef PHASE_OUT +#define NEXT_PHASE(ctx) \ + do { \ + ctx->phase++; \ + ctx->step = 0; \ + } while(0) + +/* + * Check whether we are inside the extensions group. + */ +#define IN_EXTENSION_GROUP(specs, memb_idx) \ + ((specs)->first_extension >= 0 \ + && (unsigned)(specs)->first_extension <= (memb_idx)) + +#define IN_ROOT_GROUP_PRED(edx) \ + edx < (specs->first_extension < 0 ? td->elements_count \ + : (size_t)specs->first_extension) + +#define FOR_IN_ROOT_GROUP(edx) for(edx = 0; IN_ROOT_GROUP_PRED(edx); edx++) + +/* + * Return a standardized complex structure. + */ +#undef RETURN +#define RETURN(_code) do { \ + rval.code = _code; \ + rval.consumed = consumed_myself;\ + return rval; \ + } while(0) + +/* + * Return pointer to a member. + */ +static void ** +element_ptrptr(void *struct_ptr, asn_TYPE_member_t *elm, void **tmp_save_ptr) { + if(elm->flags & ATF_POINTER) { + /* Member is a pointer to another structure */ + return (void **)((char *)struct_ptr + elm->memb_offset); + } else { + assert(tmp_save_ptr); + *tmp_save_ptr = (void *)((char *)struct_ptr + elm->memb_offset); + return tmp_save_ptr; + } +} + +static const void * +element_ptr(const void *struct_ptr, const asn_TYPE_member_t *elm) { + if(elm->flags & ATF_POINTER) { + /* Member is a pointer to another structure */ + return *(const void *const *)((const char *)struct_ptr + + elm->memb_offset); + } else { + return (const void *)((const char *)struct_ptr + elm->memb_offset); + } +} + +asn_dec_rval_t +SEQUENCE_decode_oer(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *td, + const asn_oer_constraints_t *constraints, void **struct_ptr, + const void *ptr, size_t size) { + const asn_SEQUENCE_specifics_t *specs = + (const asn_SEQUENCE_specifics_t *)td->specifics; + asn_dec_rval_t rval = {RC_OK, 0}; + void *st = *struct_ptr; /* Target structure */ + asn_struct_ctx_t *ctx; /* Decoder context */ + size_t consumed_myself = 0; /* Consumed bytes from ptr. */ + + (void)constraints; + + if(ASN__STACK_OVERFLOW_CHECK(opt_codec_ctx)) + ASN__DECODE_FAILED; + + /* + * Create the target structure if it is not present already. + */ + if(st == 0) { + st = *struct_ptr = CALLOC(1, specs->struct_size); + if(st == 0) { + RETURN(RC_FAIL); + } + } + + /* + * Restore parsing context. + */ + ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset); + + /* + * Start to parse where left previously. + */ + switch(ctx->phase) { + case 0: { + /* + * Fetch preamble. + */ + asn_bit_data_t *preamble; + int has_extensions_bit = (specs->first_extension >= 0); + size_t preamble_bits = (has_extensions_bit + specs->roms_count); + size_t preamble_bytes = ((7 + preamble_bits) >> 3); + + ASN_DEBUG("OER SEQUENCE %s Decoding PHASE 0", td->name); + + ASN_DEBUG( + "Expecting preamble bits %" ASN_PRI_SIZE " for %s (including %d extension bits)", + preamble_bits, td->name, has_extensions_bit); + + if(preamble_bytes > size) { + ASN__DECODE_STARVED; + } + + preamble = asn_bit_data_new_contiguous(ptr, preamble_bits); + if(!preamble) { + RETURN(RC_FAIL); + } + preamble->nboff = has_extensions_bit; + ctx->ptr = preamble; + ADVANCE(preamble_bytes); + } + NEXT_PHASE(ctx); + /* FALL THROUGH */ + case 1: { + /* Decode components of the extension root */ + asn_bit_data_t *preamble = ctx->ptr; + size_t edx; + + ASN_DEBUG("OER SEQUENCE %s Decoding PHASE 1 (Root)", td->name); + + assert(preamble); + + for(edx = (ctx->step >> 1); IN_ROOT_GROUP_PRED(edx); + edx++, ctx->step = (ctx->step & ~1) + 2) { + asn_TYPE_member_t *elm = &td->elements[edx]; + + ASN_DEBUG("Decoding %s->%s", td->name, elm->name); + + assert(!IN_EXTENSION_GROUP(specs, edx)); + + if(ctx->step & 1) { + goto microphase2_decode_continues; + } + + + if(elm->optional) { + int32_t present = asn_get_few_bits(preamble, 1); + if(present < 0) { + ASN_DEBUG("Presence map ended prematurely: %d", present); + RETURN(RC_FAIL); + } else if(present == 0) { + if(elm->default_value_set) { + /* Fill-in DEFAULT */ + void *tmp; + if(elm->default_value_set( + element_ptrptr(st, elm, &tmp))) { + RETURN(RC_FAIL); + } + } + /* The member is not present. */ + continue; + } + /* Present OPTIONAL or DEFAULT component. */ + } + + /* + * MICROPHASE 2: Invoke the member-specific decoder. + */ + ctx->step |= 1; /* Confirm entering next microphase */ + microphase2_decode_continues: + if(elm->flags & ATF_OPEN_TYPE) { + rval = OPEN_TYPE_oer_get(opt_codec_ctx, td, st, elm, ptr, size); + } else { + void *save_memb_ptr; /* Temporary reference. */ + void **memb_ptr2; /* Pointer to a pointer to a memmber */ + + memb_ptr2 = element_ptrptr(st, elm, &save_memb_ptr); + + rval = elm->type->op->oer_decoder( + opt_codec_ctx, elm->type, + elm->encoding_constraints.oer_constraints, memb_ptr2, ptr, + size); + } + switch(rval.code) { + case RC_OK: + ADVANCE(rval.consumed); + break; + case RC_WMORE: + ASN_DEBUG("More bytes needed at element %s \"%s\"", td->name, + elm->name); + ADVANCE(rval.consumed); + RETURN(RC_WMORE); + case RC_FAIL: + ASN_DEBUG("Decoding failed at element %s \"%s\"", td->name, + elm->name); + RETURN(RC_FAIL); + } + } /* for(all root members) */ + + } + NEXT_PHASE(ctx); + /* FALL THROUGH */ + case 2: + assert(ctx->ptr); + { + /* Cleanup preamble. */ + asn_bit_data_t *preamble = ctx->ptr; + asn_bit_data_t *extadds; + int has_extensions_bit = (specs->first_extension >= 0); + int extensions_present = + has_extensions_bit + && (preamble->buffer == NULL + || (((const uint8_t *)preamble->buffer)[0] & 0x80)); + uint8_t unused_bits; + size_t len = 0; + ssize_t len_len; + + ASN_DEBUG("OER SEQUENCE %s Decoding PHASE 2", td->name); + + preamble->buffer = 0; /* Will do extensions_present==1 next time. */ + + if(!extensions_present) { + ctx->phase = 10; + RETURN(RC_OK); + } + + /* + * X.696 (08/2015) #16.1 (c), #16.4 + * Read in the extension addition presence bitmap. + */ + + len_len = oer_fetch_length(ptr, size, &len); + if(len_len > 0) { + ADVANCE(len_len); + } else if(len_len < 0) { + RETURN(RC_FAIL); + } else { + RETURN(RC_WMORE); + } + + if(len == 0) { + /* 16.4.1-2 */ + RETURN(RC_FAIL); + } else if(len > size) { + RETURN(RC_WMORE); + } + + /* Account for unused bits */ + unused_bits = 0x7 & *(const uint8_t *)ptr; + ADVANCE(1); + len--; + if(unused_bits && len == 0) { + RETURN(RC_FAIL); + } + + /* Get the extensions map */ + extadds = asn_bit_data_new_contiguous(ptr, len * 8 - unused_bits); + if(!extadds) { + RETURN(RC_FAIL); + } + FREEMEM(preamble); + ctx->ptr = extadds; + ADVANCE(len); + } + NEXT_PHASE(ctx); + ctx->step = + (specs->first_extension < 0 ? td->elements_count + : (size_t)specs->first_extension); + /* Fall through */ + case 3: + ASN_DEBUG("OER SEQUENCE %s Decoding PHASE 3 (Extensions)", td->name); + for(; ctx->step < (signed)td->elements_count; ctx->step++) { + asn_bit_data_t *extadds = ctx->ptr; + size_t edx = ctx->step; + asn_TYPE_member_t *elm = &td->elements[edx]; + void *tmp_memb_ptr; + void **memb_ptr2 = element_ptrptr(st, elm, &tmp_memb_ptr); + + switch(asn_get_few_bits(extadds, 1)) { + case -1: + /* + * Not every one of our extensions is known to the remote side. + * Continue filling in their defaults though. + */ + /* Fall through */ + case 0: + /* Fill-in DEFAULT */ + if(elm->default_value_set + && elm->default_value_set(memb_ptr2)) { + RETURN(RC_FAIL); + } + continue; + case 1: { + /* Read OER open type */ + ssize_t ot_size = + oer_open_type_get(opt_codec_ctx, elm->type, + elm->encoding_constraints.oer_constraints, + memb_ptr2, ptr, size); + assert(ot_size <= (ssize_t)size); + if(ot_size > 0) { + ADVANCE(ot_size); + } else if(ot_size < 0) { + RETURN(RC_FAIL); + } else { + /* Roll back open type parsing */ + asn_get_undo(extadds, 1); + RETURN(RC_WMORE); + } + break; + } + default: + RETURN(RC_FAIL); + } + } + + NEXT_PHASE(ctx); + /* Fall through */ + case 4: + ASN_DEBUG("OER SEQUENCE %s Decoding PHASE 4", td->name); + /* Read in the rest of Open Types while ignoring them */ + for(;;) { + asn_bit_data_t *extadds = ctx->ptr; + switch(asn_get_few_bits(extadds, 1)) { + case 0: + continue; + case 1: { + ssize_t skipped = oer_open_type_skip(ptr, size); + if(skipped > 0) { + ADVANCE(skipped); + } else if(skipped < 0) { + RETURN(RC_FAIL); + } else { + asn_get_undo(extadds, 1); + RETURN(RC_WMORE); + } + continue; + } + case -1: + /* No more Open Type encoded components */ + break; + default: + RETURN(RC_FAIL); + } + break; + } + } + + RETURN(RC_OK); +} + +/* + * Encode as Canonical OER. + */ +asn_enc_rval_t +SEQUENCE_encode_oer(const asn_TYPE_descriptor_t *td, + const asn_oer_constraints_t *constraints, const void *sptr, + asn_app_consume_bytes_f *cb, void *app_key) { + const asn_SEQUENCE_specifics_t *specs = (const asn_SEQUENCE_specifics_t *)td->specifics; + size_t computed_size = 0; + int has_extensions_bit = (specs->first_extension >= 0); + size_t preamble_bits = (has_extensions_bit + specs->roms_count); + uint32_t has_extensions = 0; + size_t edx; + int ret; + + (void)constraints; + + if(preamble_bits) { + asn_bit_outp_t preamble; + + memset(&preamble, 0, sizeof(preamble)); + preamble.output = cb; + preamble.op_key = app_key; + + if(has_extensions_bit) { + for(edx = specs->first_extension; edx < td->elements_count; edx++) { + asn_TYPE_member_t *elm = &td->elements[edx]; + const void *memb_ptr = element_ptr(sptr, elm); + if(memb_ptr) { + if(elm->default_value_cmp + && elm->default_value_cmp(memb_ptr) == 0) { + /* Do not encode default values in extensions */ + } else { + has_extensions = 1; + break; + } + } + } + ret = asn_put_few_bits(&preamble, has_extensions, 1); + assert(ret == 0); + if(ret < 0) { + ASN__ENCODE_FAILED; + } + } + + /* + * Encode optional components bitmap. + */ + if(specs->roms_count) { + FOR_IN_ROOT_GROUP(edx) { + asn_TYPE_member_t *elm = &td->elements[edx]; + + if(IN_EXTENSION_GROUP(specs, edx)) break; + + if(elm->optional) { + const void *memb_ptr = element_ptr(sptr, elm); + uint32_t has_component = memb_ptr != NULL; + if(has_component && elm->default_value_cmp + && elm->default_value_cmp(memb_ptr) == 0) { + has_component = 0; + } + ret = asn_put_few_bits(&preamble, has_component, 1); + if(ret < 0) { + ASN__ENCODE_FAILED; + } + } + } + } + + asn_put_aligned_flush(&preamble); + computed_size += preamble.flushed_bytes; + } /* if(preamble_bits) */ + + /* + * Put root components and extensions root. + */ + for(edx = 0; edx < td->elements_count; edx++) { + asn_TYPE_member_t *elm = &td->elements[edx]; + asn_enc_rval_t er; + const void *memb_ptr; + + if(IN_EXTENSION_GROUP(specs, edx)) break; + + memb_ptr = element_ptr(sptr, elm); + if(memb_ptr) { + if(elm->default_value_cmp + && elm->default_value_cmp(memb_ptr) == 0) { + /* Skip default values in encoding */ + continue; + } + } else { + if(elm->optional) continue; + /* Mandatory element is missing */ + ASN__ENCODE_FAILED; + } + if(!elm->type->op->oer_encoder) { + ASN_DEBUG("OER encoder is not defined for type %s", elm->type->name); + ASN__ENCODE_FAILED; + } + er = elm->type->op->oer_encoder( + elm->type, elm->encoding_constraints.oer_constraints, memb_ptr, cb, + app_key); + if(er.encoded == -1) { + ASN_DEBUG("... while encoding %s member \"%s\"\n", td->name, + elm->name); + return er; + } + computed_size += er.encoded; + } + + /* + * Before encode extensions, encode extensions additions presense bitmap + # X.696 (08/2015) #16.4. + */ + if(has_extensions) { + asn_bit_outp_t extadds; + + /* Special case allowing us to use exactly one byte for #8.6 */ + size_t aoms_length_bits = specs->aoms_count; + size_t aoms_length_bytes = (7 + aoms_length_bits) >> 3; + uint8_t unused_bits = 0x07 & (8 - (aoms_length_bits & 0x07)); + + assert(1 + aoms_length_bytes <= 127); + + memset(&extadds, 0, sizeof(extadds)); + extadds.output = cb; + extadds.op_key = app_key; + + /* #8.6 length determinant */ + ret = asn_put_few_bits(&extadds, (1 + aoms_length_bytes), 8); + if(ret < 0) ASN__ENCODE_FAILED; + + /* Number of unused bytes, #16.4.2 */ + ret = asn_put_few_bits(&extadds, unused_bits, 8); + if(ret < 0) ASN__ENCODE_FAILED; + + /* Encode presence bitmap #16.4.3 */ + for(edx = specs->first_extension; edx < td->elements_count; edx++) { + asn_TYPE_member_t *elm = &td->elements[edx]; + const void *memb_ptr = element_ptr(sptr, elm); + if(memb_ptr && elm->default_value_cmp + && elm->default_value_cmp(memb_ptr) == 0) { + memb_ptr = 0; /* Do not encode default value. */ + } + ret |= asn_put_few_bits(&extadds, memb_ptr ? 1 : 0, 1); + } + if(ret < 0) ASN__ENCODE_FAILED; + + asn_put_aligned_flush(&extadds); + computed_size += extadds.flushed_bytes; + + /* Now, encode extensions */ + for(edx = specs->first_extension; edx < td->elements_count; edx++) { + asn_TYPE_member_t *elm = &td->elements[edx]; + const void *memb_ptr = element_ptr(sptr, elm); + + if(memb_ptr) { + if(elm->default_value_cmp + && elm->default_value_cmp(memb_ptr) == 0) { + /* Do not encode default value. */ + } else { + ssize_t wrote = oer_open_type_put( + elm->type, elm->encoding_constraints.oer_constraints, + memb_ptr, cb, app_key); + if(wrote == -1) { + ASN__ENCODE_FAILED; + } + computed_size += wrote; + } + } else if(!elm->optional) { + ASN__ENCODE_FAILED; + } + } + } /* if(has_extensions) */ + + + { + asn_enc_rval_t er = {0, 0, 0}; + er.encoded = computed_size; + ASN__ENCODED_OK(er); + } +} + +#endif /* ASN_DISABLE_OER_SUPPORT */ diff --git a/libs/smux/constr_SET_OF.c b/libs/smux/constr_SET_OF.c index 2dbc6e51..02fc5156 100644 --- a/libs/smux/constr_SET_OF.c +++ b/libs/smux/constr_SET_OF.c @@ -1,5 +1,5 @@ -/*- - * Copyright (c) 2003, 2004, 2005 Lev Walkin . +/* + * Copyright (c) 2003-2017 Lev Walkin . * All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ @@ -66,15 +66,16 @@ * The decoder of the SET OF type. */ asn_dec_rval_t -SET_OF_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, - void **struct_ptr, const void *ptr, size_t size, int tag_mode) { - /* +SET_OF_decode_ber(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *td, void **struct_ptr, + const void *ptr, size_t size, int tag_mode) { + /* * Bring closer parts of structure description. */ - asn_SET_OF_specifics_t *specs = (asn_SET_OF_specifics_t *)td->specifics; - asn_TYPE_member_t *elm = td->elements; /* Single one */ + const asn_SET_OF_specifics_t *specs = (const asn_SET_OF_specifics_t *)td->specifics; + const asn_TYPE_member_t *elm = td->elements; /* Single one */ - /* + /* * Parts of the structure being constructed. */ void *st = *struct_ptr; /* Target structure. */ @@ -205,7 +206,7 @@ SET_OF_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, /* * Invoke the member fetch routine according to member's type */ - rval = elm->type->ber_decoder(opt_codec_ctx, + rval = elm->type->op->ber_decoder(opt_codec_ctx, elm->type, &ctx->ptr, ptr, LEFT, 0); ASN_DEBUG("In %s SET OF %s code %d consumed %d", td->name, elm->type->name, @@ -270,188 +271,230 @@ SET_OF_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, struct _el_buffer { uint8_t *buf; size_t length; - size_t size; + size_t allocated_size; + unsigned bits_unused; }; /* Append bytes to the above structure */ static int _el_addbytes(const void *buffer, size_t size, void *el_buf_ptr) { - struct _el_buffer *el_buf = (struct _el_buffer *)el_buf_ptr; + struct _el_buffer *el_buf = (struct _el_buffer *)el_buf_ptr; - if(el_buf->length + size > el_buf->size) - return -1; + if(el_buf->length + size > el_buf->allocated_size) { + size_t new_size = el_buf->allocated_size ? el_buf->allocated_size : 8; + void *p; - memcpy(el_buf->buf + el_buf->length, buffer, size); + do { + new_size <<= 2; + } while(el_buf->length + size > new_size); - el_buf->length += size; - return 0; + p = REALLOC(el_buf->buf, new_size); + if(p) { + el_buf->buf = p; + el_buf->allocated_size = new_size; + } else { + return -1; + } + } + + memcpy(el_buf->buf + el_buf->length, buffer, size); + + el_buf->length += size; + return 0; } -static int _el_buf_cmp(const void *ap, const void *bp) { - const struct _el_buffer *a = (const struct _el_buffer *)ap; - const struct _el_buffer *b = (const struct _el_buffer *)bp; - int ret; - size_t common_len; - - if(a->length < b->length) - common_len = a->length; - else - common_len = b->length; - - ret = memcmp(a->buf, b->buf, common_len); - if(ret == 0) { - if(a->length < b->length) - ret = -1; - else if(a->length > b->length) - ret = 1; - } - return ret; +static void assert_unused_bits(const struct _el_buffer* p) { + if(p->length) { + assert((p->buf[p->length-1] & ~(0xff << p->bits_unused)) == 0); + } else { + assert(p->bits_unused == 0); + } } -/* - * The DER encoder of the SET OF type. - */ -asn_enc_rval_t -SET_OF_encode_der(asn_TYPE_descriptor_t *td, void *ptr, - int tag_mode, ber_tlv_tag_t tag, - asn_app_consume_bytes_f *cb, void *app_key) { - asn_TYPE_member_t *elm = td->elements; - asn_TYPE_descriptor_t *elm_type = elm->type; - der_type_encoder_f *der_encoder = elm_type->der_encoder; - asn_anonymous_set_ *list = _A_SET_FROM_VOID(ptr); - size_t computed_size = 0; - ssize_t encoding_size = 0; - struct _el_buffer *encoded_els; - ssize_t eels_count = 0; - size_t max_encoded_len = 1; - asn_enc_rval_t erval; - int ret; - int edx; +static int _el_buf_cmp(const void *ap, const void *bp) { + const struct _el_buffer *a = (const struct _el_buffer *)ap; + const struct _el_buffer *b = (const struct _el_buffer *)bp; + size_t common_len; + int ret = 0; + + if(a->length < b->length) + common_len = a->length; + else + common_len = b->length; + + if (a->buf && b->buf) { + ret = memcmp(a->buf, b->buf, common_len); + } + if(ret == 0) { + if(a->length < b->length) + ret = -1; + else if(a->length > b->length) + ret = 1; + /* Ignore unused bits. */ + assert_unused_bits(a); + assert_unused_bits(b); + } + + return ret; +} - ASN_DEBUG("Estimating size for SET OF %s", td->name); +static void +SET_OF__encode_sorted_free(struct _el_buffer *el_buf, size_t count) { + size_t i; - /* - * Gather the length of the underlying members sequence. - */ - for(edx = 0; edx < list->count; edx++) { - void *memb_ptr = list->array[edx]; - if(!memb_ptr) continue; - erval = der_encoder(elm_type, memb_ptr, 0, elm->tag, 0, 0); - if(erval.encoded == -1) - return erval; - computed_size += erval.encoded; - - /* Compute maximum encoding's size */ - if(max_encoded_len < (size_t)erval.encoded) - max_encoded_len = erval.encoded; - } + for(i = 0; i < count; i++) { + FREEMEM(el_buf[i].buf); + } - /* - * Encode the TLV for the sequence itself. - */ - encoding_size = der_write_tags(td, computed_size, tag_mode, 1, tag, - cb, app_key); - if(encoding_size == -1) { - erval.encoded = -1; - erval.failed_type = td; - erval.structure_ptr = ptr; - return erval; - } - computed_size += encoding_size; + FREEMEM(el_buf); +} - if(!cb || list->count == 0) { - erval.encoded = computed_size; - ASN__ENCODED_OK(erval); - } +enum SET_OF__encode_method { + SOES_DER, /* Distinguished Encoding Rules */ + SOES_CUPER /* Canonical Unaligned Packed Encoding Rules */ +}; - /* - * DER mandates dynamic sorting of the SET OF elements - * according to their encodings. Build an array of the - * encoded elements. - */ - encoded_els = (struct _el_buffer *)MALLOC( - list->count * sizeof(encoded_els[0])); - if(encoded_els == NULL) { - erval.encoded = -1; - erval.failed_type = td; - erval.structure_ptr = ptr; - return erval; - } +static struct _el_buffer * +SET_OF__encode_sorted(const asn_TYPE_member_t *elm, + const asn_anonymous_set_ *list, + enum SET_OF__encode_method method) { + struct _el_buffer *encoded_els; + int edx; - ASN_DEBUG("Encoding members of %s SET OF", td->name); + encoded_els = + (struct _el_buffer *)CALLOC(list->count, sizeof(encoded_els[0])); + if(encoded_els == NULL) { + return NULL; + } /* * Encode all members. */ - for(edx = 0; edx < list->count; edx++) { - void *memb_ptr = list->array[edx]; - struct _el_buffer *encoded_el = &encoded_els[eels_count]; - - if(!memb_ptr) continue; + for(edx = 0; edx < list->count; edx++) { + const void *memb_ptr = list->array[edx]; + struct _el_buffer *encoding_el = &encoded_els[edx]; + asn_enc_rval_t erval; - /* - * Prepare space for encoding. - */ - encoded_el->buf = (uint8_t *)MALLOC(max_encoded_len); - if(encoded_el->buf) { - encoded_el->length = 0; - encoded_el->size = max_encoded_len; - } else { - for(edx--; edx >= 0; edx--) - FREEMEM(encoded_els[edx].buf); - FREEMEM(encoded_els); - erval.encoded = -1; - erval.failed_type = td; - erval.structure_ptr = ptr; - return erval; - } + if(!memb_ptr) break; - /* + /* * Encode the member into the prepared space. */ - erval = der_encoder(elm_type, memb_ptr, 0, elm->tag, - _el_addbytes, encoded_el); - if(erval.encoded == -1) { - for(; edx >= 0; edx--) - FREEMEM(encoded_els[edx].buf); - FREEMEM(encoded_els); - return erval; - } - encoding_size += erval.encoded; - eels_count++; + switch(method) { + case SOES_DER: + erval = elm->type->op->der_encoder(elm->type, memb_ptr, 0, elm->tag, + _el_addbytes, encoding_el); + break; + case SOES_CUPER: + erval = uper_encode(elm->type, + elm->encoding_constraints.per_constraints, + memb_ptr, _el_addbytes, encoding_el); + if(erval.encoded != -1) { + size_t extra_bits = erval.encoded % 8; + assert(encoding_el->length == (size_t)(erval.encoded + 7) / 8); + encoding_el->bits_unused = (8 - extra_bits) & 0x7; + } + break; + default: + assert(!"Unreachable"); + break; + } + if(erval.encoded < 0) break; } - /* - * Sort the encoded elements according to their encoding. - */ - qsort(encoded_els, eels_count, sizeof(encoded_els[0]), _el_buf_cmp); + if(edx == list->count) { + /* + * Sort the encoded elements according to their encoding. + */ + qsort(encoded_els, list->count, sizeof(encoded_els[0]), _el_buf_cmp); + + return encoded_els; + } else { + SET_OF__encode_sorted_free(encoded_els, edx); + return NULL; + } +} - /* - * Report encoded elements to the application. - * Dispose of temporary sorted members table. - */ - ret = 0; - for(edx = 0; edx < eels_count; edx++) { - struct _el_buffer *encoded_el = &encoded_els[edx]; - /* Report encoded chunks to the application */ - if(ret == 0 - && cb(encoded_el->buf, encoded_el->length, app_key) < 0) - ret = -1; - FREEMEM(encoded_el->buf); - } - FREEMEM(encoded_els); - if(ret || computed_size != (size_t)encoding_size) { - /* - * Standard callback failed, or - * encoded size is not equal to the computed size. - */ - erval.encoded = -1; - erval.failed_type = td; - erval.structure_ptr = ptr; - } else { - erval.encoded = computed_size; +/* + * The DER encoder of the SET OF type. + */ +asn_enc_rval_t +SET_OF_encode_der(const asn_TYPE_descriptor_t *td, const void *sptr, + int tag_mode, ber_tlv_tag_t tag, asn_app_consume_bytes_f *cb, + void *app_key) { + const asn_TYPE_member_t *elm = td->elements; + const asn_anonymous_set_ *list = _A_CSET_FROM_VOID(sptr); + size_t computed_size = 0; + ssize_t encoding_size = 0; + struct _el_buffer *encoded_els; + int edx; + + ASN_DEBUG("Estimating size for SET OF %s", td->name); + + /* + * Gather the length of the underlying members sequence. + */ + for(edx = 0; edx < list->count; edx++) { + void *memb_ptr = list->array[edx]; + asn_enc_rval_t erval; + + if(!memb_ptr) ASN__ENCODE_FAILED; + + erval = + elm->type->op->der_encoder(elm->type, memb_ptr, 0, elm->tag, 0, 0); + if(erval.encoded == -1) return erval; + computed_size += erval.encoded; } - ASN__ENCODED_OK(erval); + + /* + * Encode the TLV for the sequence itself. + */ + encoding_size = + der_write_tags(td, computed_size, tag_mode, 1, tag, cb, app_key); + if(encoding_size < 0) { + ASN__ENCODE_FAILED; + } + computed_size += encoding_size; + + if(!cb || list->count == 0) { + asn_enc_rval_t erval; + erval.encoded = computed_size; + ASN__ENCODED_OK(erval); + } + + ASN_DEBUG("Encoding members of %s SET OF", td->name); + + /* + * DER mandates dynamic sorting of the SET OF elements + * according to their encodings. Build an array of the + * encoded elements. + */ + encoded_els = SET_OF__encode_sorted(elm, list, SOES_DER); + + /* + * Report encoded elements to the application. + * Dispose of temporary sorted members table. + */ + for(edx = 0; edx < list->count; edx++) { + struct _el_buffer *encoded_el = &encoded_els[edx]; + /* Report encoded chunks to the application */ + if(cb(encoded_el->buf, encoded_el->length, app_key) < 0) { + break; + } else { + encoding_size += encoded_el->length; + } + } + + SET_OF__encode_sorted_free(encoded_els, list->count); + + if(edx == list->count) { + asn_enc_rval_t erval; + assert(computed_size == (size_t)encoding_size); + erval.encoded = computed_size; + ASN__ENCODED_OK(erval); + } else { + ASN__ENCODE_FAILED; + } } #undef XER_ADVANCE @@ -466,14 +509,14 @@ SET_OF_encode_der(asn_TYPE_descriptor_t *td, void *ptr, * Decode the XER (XML) data. */ asn_dec_rval_t -SET_OF_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, - void **struct_ptr, const char *opt_mname, - const void *buf_ptr, size_t size) { - /* +SET_OF_decode_xer(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *td, void **struct_ptr, + const char *opt_mname, const void *buf_ptr, size_t size) { + /* * Bring closer parts of structure description. */ - asn_SET_OF_specifics_t *specs = (asn_SET_OF_specifics_t *)td->specifics; - asn_TYPE_member_t *element = td->elements; + const asn_SET_OF_specifics_t *specs = (const asn_SET_OF_specifics_t *)td->specifics; + const asn_TYPE_member_t *element = td->elements; const char *elm_tag; const char *xml_tag = opt_mname ? opt_mname : td->xml_tag; @@ -526,7 +569,7 @@ SET_OF_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, /* Invoke the inner type decoder, m.b. multiple times */ ASN_DEBUG("XER/SET OF element [%s]", elm_tag); - tmprval = element->type->xer_decoder(opt_codec_ctx, + tmprval = element->type->op->xer_decoder(opt_codec_ctx, element->type, &ctx->ptr, elm_tag, buf_ptr, size); if(tmprval.code == RC_OK) { @@ -651,14 +694,14 @@ SET_OF_xer_order(const void *aptr, const void *bptr) { asn_enc_rval_t -SET_OF_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, - int ilevel, enum xer_encoder_flags_e flags, - asn_app_consume_bytes_f *cb, void *app_key) { - asn_enc_rval_t er; - asn_SET_OF_specifics_t *specs = (asn_SET_OF_specifics_t *)td->specifics; - asn_TYPE_member_t *elm = td->elements; - asn_anonymous_set_ *list = _A_SET_FROM_VOID(sptr); - const char *mname = specs->as_XMLValueList +SET_OF_encode_xer(const asn_TYPE_descriptor_t *td, const void *sptr, int ilevel, + enum xer_encoder_flags_e flags, asn_app_consume_bytes_f *cb, + void *app_key) { + asn_enc_rval_t er; + const asn_SET_OF_specifics_t *specs = (const asn_SET_OF_specifics_t *)td->specifics; + const asn_TYPE_member_t *elm = td->elements; + const asn_anonymous_set_ *list = _A_CSET_FROM_VOID(sptr); + const char *mname = specs->as_XMLValueList ? 0 : ((*elm->name) ? elm->name : elm->type->xml_tag); size_t mlen = mname ? strlen(mname) : 0; int xcan = (flags & XER_F_CANONICAL); @@ -697,14 +740,11 @@ SET_OF_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, if(!xcan && specs->as_XMLValueList == 1) ASN__TEXT_INDENT(1, ilevel + 1); - tmper = elm->type->xer_encoder(elm->type, memb_ptr, + tmper = elm->type->op->xer_encoder(elm->type, memb_ptr, ilevel + (specs->as_XMLValueList != 2), flags, cb, app_key); - if(tmper.encoded == -1) { - td = tmper.failed_type; - sptr = tmper.structure_ptr; - goto cb_failed; - } + if(tmper.encoded == -1) return tmper; + er.encoded += tmper.encoded; if(tmper.encoded == 0 && specs->as_XMLValueList) { const char *name = elm->type->xml_tag; size_t len = strlen(name); @@ -713,10 +753,8 @@ SET_OF_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, if(mname) { ASN__CALLBACK3("", 1); - er.encoded += 5; } - er.encoded += (2 * mlen) + tmper.encoded; } if(!xcan) ASN__TEXT_INDENT(1, ilevel - 1); @@ -726,6 +764,7 @@ SET_OF_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, xer_tmp_enc_t *end = encs + encs_count; ssize_t control_size = 0; + er.encoded = 0; cb = original_cb; app_key = original_app_key; qsort(encs, encs_count, sizeof(encs[0]), SET_OF_xer_order); @@ -741,14 +780,12 @@ SET_OF_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, goto cleanup; cb_failed: - er.encoded = -1; - er.failed_type = td; - er.structure_ptr = sptr; + ASN__ENCODE_FAILED; cleanup: if(encs) { - while(encs_count-- > 0) { - if(encs[encs_count].buffer) - FREEMEM(encs[encs_count].buffer); + size_t n; + for(n = 0; n < encs_count; n++) { + FREEMEM(encs[n].buffer); } FREEMEM(encs); } @@ -756,9 +793,9 @@ cleanup: } int -SET_OF_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel, - asn_app_consume_bytes_f *cb, void *app_key) { - asn_TYPE_member_t *elm = td->elements; +SET_OF_print(const asn_TYPE_descriptor_t *td, const void *sptr, int ilevel, + asn_app_consume_bytes_f *cb, void *app_key) { + asn_TYPE_member_t *elm = td->elements; const asn_anonymous_set_ *list = _A_CSET_FROM_VOID(sptr); int ret; int i; @@ -776,7 +813,7 @@ SET_OF_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel, _i_INDENT(1); - ret = elm->type->print_struct(elm->type, memb_ptr, + ret = elm->type->op->print_struct(elm->type, memb_ptr, ilevel + 1, cb, app_key); if(ret) return ret; } @@ -788,9 +825,10 @@ SET_OF_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel, } void -SET_OF_free(asn_TYPE_descriptor_t *td, void *ptr, int contents_only) { - if(td && ptr) { - asn_SET_OF_specifics_t *specs; +SET_OF_free(const asn_TYPE_descriptor_t *td, void *ptr, + enum asn_struct_free_method method) { + if(td && ptr) { + const asn_SET_OF_specifics_t *specs; asn_TYPE_member_t *elm = td->elements; asn_anonymous_set_ *list = _A_SET_FROM_VOID(ptr); asn_struct_ctx_t *ctx; /* Decoder context */ @@ -809,23 +847,30 @@ SET_OF_free(asn_TYPE_descriptor_t *td, void *ptr, int contents_only) { asn_set_empty(list); /* Remove (list->array) */ - specs = (asn_SET_OF_specifics_t *)td->specifics; + specs = (const asn_SET_OF_specifics_t *)td->specifics; ctx = (asn_struct_ctx_t *)((char *)ptr + specs->ctx_offset); if(ctx->ptr) { ASN_STRUCT_FREE(*elm->type, ctx->ptr); ctx->ptr = 0; } - if(!contents_only) { - FREEMEM(ptr); - } - } + switch(method) { + case ASFM_FREE_EVERYTHING: + FREEMEM(ptr); + break; + case ASFM_FREE_UNDERLYING: + break; + case ASFM_FREE_UNDERLYING_AND_RESET: + memset(ptr, 0, specs->struct_size); + break; + } + } } int -SET_OF_constraint(asn_TYPE_descriptor_t *td, const void *sptr, - asn_app_constraint_failed_f *ctfailcb, void *app_key) { - asn_TYPE_member_t *elm = td->elements; +SET_OF_constraint(const asn_TYPE_descriptor_t *td, const void *sptr, + asn_app_constraint_failed_f *ctfailcb, void *app_key) { + const asn_TYPE_member_t *elm = td->elements; asn_constr_check_f *constr; const asn_anonymous_set_ *list = _A_CSET_FROM_VOID(sptr); int i; @@ -837,8 +882,8 @@ SET_OF_constraint(asn_TYPE_descriptor_t *td, const void *sptr, return -1; } - constr = elm->memb_constraints; - if(!constr) constr = elm->type->check_constraints; + constr = elm->encoding_constraints.general_constraints; + if(!constr) constr = elm->type->encoding_constraints.general_constraints; /* * Iterate over the members of an array. @@ -854,25 +899,22 @@ SET_OF_constraint(asn_TYPE_descriptor_t *td, const void *sptr, if(ret) return ret; } - /* - * Cannot inherit it eralier: - * need to make sure we get the updated version. - */ - if(!elm->memb_constraints) - elm->memb_constraints = elm->type->check_constraints; - return 0; } +#ifndef ASN_DISABLE_PER_SUPPORT + asn_dec_rval_t -SET_OF_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, - asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { - asn_dec_rval_t rv; - asn_SET_OF_specifics_t *specs = (asn_SET_OF_specifics_t *)td->specifics; - asn_TYPE_member_t *elm = td->elements; /* Single one */ - void *st = *sptr; +SET_OF_decode_uper(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, void **sptr, + asn_per_data_t *pd) { + asn_dec_rval_t rv; + const asn_SET_OF_specifics_t *specs = (const asn_SET_OF_specifics_t *)td->specifics; + const asn_TYPE_member_t *elm = td->elements; /* Single one */ + void *st = *sptr; asn_anonymous_set_ *list; - asn_per_constraint_t *ct; + const asn_per_constraint_t *ct; int repeat = 0; ssize_t nelems; @@ -890,7 +932,8 @@ SET_OF_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, /* Figure out which constraints to use */ if(constraints) ct = &constraints->size; - else if(td->per_constraints) ct = &td->per_constraints->size; + else if(td->encoding_constraints.per_constraints) + ct = &td->encoding_constraints.per_constraints->size; else ct = 0; if(ct && ct->flags & APC_EXTENSIBLE) { @@ -913,23 +956,27 @@ SET_OF_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, do { int i; if(nelems < 0) { - nelems = uper_get_length(pd, - ct ? ct->effective_bits : -1, &repeat); - ASN_DEBUG("Got to decode %d elements (eff %d)", - (int)nelems, (int)(ct ? ct->effective_bits : -1)); - if(nelems < 0) ASN__DECODE_STARVED; + nelems = uper_get_length(pd, -1, 0, &repeat); + ASN_DEBUG("Got to decode %" ASN_PRI_SSIZE " elements (eff %d)", + nelems, (int)(ct ? ct->effective_bits : -1)); + if(nelems < 0) ASN__DECODE_STARVED; } for(i = 0; i < nelems; i++) { void *ptr = 0; ASN_DEBUG("SET OF %s decoding", elm->type->name); - rv = elm->type->uper_decoder(opt_codec_ctx, elm->type, - elm->per_constraints, &ptr, pd); + rv = elm->type->op->uper_decoder(opt_codec_ctx, elm->type, + elm->encoding_constraints.per_constraints, &ptr, pd); ASN_DEBUG("%s SET OF %s decoded %d, %p", td->name, elm->type->name, rv.code, ptr); if(rv.code == RC_OK) { - if(ASN_SET_ADD(list, ptr) == 0) + if(ASN_SET_ADD(list, ptr) == 0) { + if(rv.consumed == 0 && nelems > 200) { + /* Protect from SET OF NULL compression bombs. */ + ASN__DECODE_FAILED; + } continue; + } ASN_DEBUG("Failed to add element into %s", td->name); /* Fall through */ @@ -952,3 +999,350 @@ SET_OF_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, return rv; } +asn_enc_rval_t +SET_OF_encode_uper(const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, const void *sptr, + asn_per_outp_t *po) { + const asn_anonymous_set_ *list; + const asn_per_constraint_t *ct; + const asn_TYPE_member_t *elm = td->elements; + struct _el_buffer *encoded_els; + asn_enc_rval_t er; + size_t encoded_edx; + + if(!sptr) ASN__ENCODE_FAILED; + + list = _A_CSET_FROM_VOID(sptr); + + er.encoded = 0; + + ASN_DEBUG("Encoding %s as SEQUENCE OF (%d)", td->name, list->count); + + if(constraints) ct = &constraints->size; + else if(td->encoding_constraints.per_constraints) + ct = &td->encoding_constraints.per_constraints->size; + else ct = 0; + + /* If extensible constraint, check if size is in root */ + if(ct) { + int not_in_root = + (list->count < ct->lower_bound || list->count > ct->upper_bound); + ASN_DEBUG("lb %ld ub %ld %s", ct->lower_bound, ct->upper_bound, + ct->flags & APC_EXTENSIBLE ? "ext" : "fix"); + if(ct->flags & APC_EXTENSIBLE) { + /* Declare whether size is in extension root */ + if(per_put_few_bits(po, not_in_root, 1)) ASN__ENCODE_FAILED; + if(not_in_root) ct = 0; + } else if(not_in_root && ct->effective_bits >= 0) { + ASN__ENCODE_FAILED; + } + + } + + if(ct && ct->effective_bits >= 0) { + /* X.691, #19.5: No length determinant */ + if(per_put_few_bits(po, list->count - ct->lower_bound, + ct->effective_bits)) + ASN__ENCODE_FAILED; + } else if(list->count == 0) { + /* When the list is empty add only the length determinant + * X.691, #20.6 and #11.9.4.1 + */ + if (uper_put_length(po, 0, 0)) { + ASN__ENCODE_FAILED; + } + ASN__ENCODED_OK(er); + } + + + /* + * Canonical UPER #22.1 mandates dynamic sorting of the SET OF elements + * according to their encodings. Build an array of the encoded elements. + */ + encoded_els = SET_OF__encode_sorted(elm, list, SOES_CUPER); + + for(encoded_edx = 0; (ssize_t)encoded_edx < list->count;) { + ssize_t may_encode; + size_t edx; + int need_eom = 0; + + if(ct && ct->effective_bits >= 0) { + may_encode = list->count; + } else { + may_encode = + uper_put_length(po, list->count - encoded_edx, &need_eom); + if(may_encode < 0) ASN__ENCODE_FAILED; + } + + for(edx = encoded_edx; edx < encoded_edx + may_encode; edx++) { + const struct _el_buffer *el = &encoded_els[edx]; + if(asn_put_many_bits(po, el->buf, + (8 * el->length) - el->bits_unused) < 0) { + break; + } + } + + if(need_eom && uper_put_length(po, 0, 0)) + ASN__ENCODE_FAILED; /* End of Message length */ + + encoded_edx += may_encode; + } + + SET_OF__encode_sorted_free(encoded_els, list->count); + + if((ssize_t)encoded_edx == list->count) { + ASN__ENCODED_OK(er); + } else { + ASN__ENCODE_FAILED; + } +} + + +#endif /* ASN_DISABLE_PER_SUPPORT */ + +struct comparable_ptr { + const asn_TYPE_descriptor_t *td; + const void *sptr; +}; + +static int +SET_OF__compare_cb(const void *aptr, const void *bptr) { + const struct comparable_ptr *a = aptr; + const struct comparable_ptr *b = bptr; + assert(a->td == b->td); + return a->td->op->compare_struct(a->td, a->sptr, b->sptr); +} + +int +SET_OF_compare(const asn_TYPE_descriptor_t *td, const void *aptr, + const void *bptr) { + const asn_anonymous_set_ *a = _A_CSET_FROM_VOID(aptr); + const asn_anonymous_set_ *b = _A_CSET_FROM_VOID(bptr); + + if(a && b) { + struct comparable_ptr *asorted; + struct comparable_ptr *bsorted; + ssize_t common_length; + ssize_t idx; + + if(a->count == 0) { + if(b->count) return -1; + return 0; + } else if(b->count == 0) { + return 1; + } + + asorted = MALLOC(a->count * sizeof(asorted[0])); + bsorted = MALLOC(b->count * sizeof(bsorted[0])); + if(!asorted || !bsorted) { + FREEMEM(asorted); + FREEMEM(bsorted); + return -1; + } + + for(idx = 0; idx < a->count; idx++) { + asorted[idx].td = td->elements->type; + asorted[idx].sptr = a->array[idx]; + } + + for(idx = 0; idx < b->count; idx++) { + bsorted[idx].td = td->elements->type; + bsorted[idx].sptr = b->array[idx]; + } + + qsort(asorted, a->count, sizeof(asorted[0]), SET_OF__compare_cb); + qsort(bsorted, b->count, sizeof(bsorted[0]), SET_OF__compare_cb); + + common_length = (a->count < b->count ? a->count : b->count); + for(idx = 0; idx < common_length; idx++) { + int ret = td->elements->type->op->compare_struct( + td->elements->type, asorted[idx].sptr, bsorted[idx].sptr); + if(ret) { + FREEMEM(asorted); + FREEMEM(bsorted); + return ret; + } + } + + FREEMEM(asorted); + FREEMEM(bsorted); + + if(idx < b->count) /* more elements in b */ + return -1; /* a is shorter, so put it first */ + if(idx < a->count) return 1; + } else if(!a) { + return -1; + } else if(!b) { + return 1; + } + + return 0; +} + + +asn_TYPE_operation_t asn_OP_SET_OF = { + SET_OF_free, + SET_OF_print, + SET_OF_compare, + SET_OF_decode_ber, + SET_OF_encode_der, + SET_OF_decode_xer, + SET_OF_encode_xer, +#ifdef ASN_DISABLE_OER_SUPPORT + 0, + 0, +#else + SET_OF_decode_oer, + SET_OF_encode_oer, +#endif +#ifdef ASN_DISABLE_PER_SUPPORT + 0, + 0, +#else + SET_OF_decode_uper, + SET_OF_encode_uper, +#endif /* ASN_DISABLE_PER_SUPPORT */ + SET_OF_random_fill, + 0 /* Use generic outmost tag fetcher */ +}; + + +asn_random_fill_result_t +SET_OF_random_fill(const asn_TYPE_descriptor_t *td, void **sptr, + const asn_encoding_constraints_t *constraints, + size_t max_length) { + const asn_SET_OF_specifics_t *specs = + (const asn_SET_OF_specifics_t *)td->specifics; + asn_random_fill_result_t res_ok = {ARFILL_OK, 0}; + asn_random_fill_result_t result_failed = {ARFILL_FAILED, 0}; + asn_random_fill_result_t result_skipped = {ARFILL_SKIPPED, 0}; + const asn_TYPE_member_t *elm = td->elements; + void *st = *sptr; + long max_elements = 5; + long slb = 0; /* Lower size bound */ + long sub = 0; /* Upper size bound */ + size_t rnd_len; + + if(max_length == 0) return result_skipped; + + if(st == NULL) { + st = (*sptr = CALLOC(1, specs->struct_size)); + if(st == NULL) { + return result_failed; + } + } + + switch(asn_random_between(0, 6)) { + case 0: max_elements = 0; break; + case 1: max_elements = 1; break; + case 2: max_elements = 5; break; + case 3: max_elements = max_length; break; + case 4: max_elements = max_length / 2; break; + case 5: max_elements = max_length / 4; break; + default: break; + } + sub = slb + max_elements; + + if(!constraints || !constraints->per_constraints) + constraints = &td->encoding_constraints; + if(constraints->per_constraints) { + const asn_per_constraint_t *pc = &constraints->per_constraints->size; + if(pc->flags & APC_SEMI_CONSTRAINED) { + slb = pc->lower_bound; + sub = pc->lower_bound + max_elements; + } else if(pc->flags & APC_CONSTRAINED) { + slb = pc->lower_bound; + sub = pc->upper_bound; + if(sub - slb > max_elements) sub = slb + max_elements; + } + } + + /* Bias towards edges of allowed space */ + switch(asn_random_between(-1, 4)) { + default: + case -1: + /* Prepare lengths somewhat outside of constrained range. */ + if(constraints->per_constraints + && (constraints->per_constraints->size.flags & APC_EXTENSIBLE)) { + switch(asn_random_between(0, 5)) { + default: + case 0: + rnd_len = 0; + break; + case 1: + if(slb > 0) { + rnd_len = slb - 1; + } else { + rnd_len = 0; + } + break; + case 2: + rnd_len = asn_random_between(0, slb); + break; + case 3: + if(sub < (ssize_t)max_length) { + rnd_len = sub + 1; + } else { + rnd_len = max_length; + } + break; + case 4: + if(sub < (ssize_t)max_length) { + rnd_len = asn_random_between(sub + 1, max_length); + } else { + rnd_len = max_length; + } + break; + case 5: + rnd_len = max_length; + break; + } + break; + } + /* Fall through */ + case 0: + rnd_len = asn_random_between(slb, sub); + break; + case 1: + if(slb < sub) { + rnd_len = asn_random_between(slb + 1, sub); + break; + } + /* Fall through */ + case 2: + rnd_len = asn_random_between(slb, slb); + break; + case 3: + if(slb < sub) { + rnd_len = asn_random_between(slb, sub - 1); + break; + } + /* Fall through */ + case 4: + rnd_len = asn_random_between(sub, sub); + break; + } + + for(; rnd_len > 0; rnd_len--) { + asn_anonymous_set_ *list = _A_SET_FROM_VOID(st); + void *ptr = 0; + asn_random_fill_result_t tmpres = elm->type->op->random_fill( + elm->type, &ptr, &elm->encoding_constraints, + (max_length > res_ok.length ? max_length - res_ok.length : 0) + / rnd_len); + switch(tmpres.code) { + case ARFILL_OK: + ASN_SET_ADD(list, ptr); + res_ok.length += tmpres.length; + break; + case ARFILL_SKIPPED: + break; + case ARFILL_FAILED: + assert(ptr == 0); + return tmpres; + } + } + + return res_ok; +} + diff --git a/libs/smux/constr_SET_OF_oer.c b/libs/smux/constr_SET_OF_oer.c new file mode 100644 index 00000000..88d7a2a1 --- /dev/null +++ b/libs/smux/constr_SET_OF_oer.c @@ -0,0 +1,285 @@ +/* + * Copyright (c) 2017 Lev Walkin . + * All rights reserved. + * Redistribution and modifications are permitted subject to BSD license. + */ +#ifndef ASN_DISABLE_OER_SUPPORT + +#include +#include +#include +#include + +/* + * This macro "eats" the part of the buffer which is definitely "consumed", + * i.e. was correctly converted into local representation or rightfully skipped. + */ +#undef ADVANCE +#define ADVANCE(num_bytes) \ + do { \ + size_t num = num_bytes; \ + ptr = ((const char *)ptr) + num; \ + size -= num; \ + consumed_myself += num; \ + } while(0) + +/* + * Switch to the next phase of parsing. + */ +#undef NEXT_PHASE +#define NEXT_PHASE(ctx) \ + do { \ + ctx->phase++; \ + ctx->step = 0; \ + } while(0) +#undef SET_PHASE +#define SET_PHASE(ctx, value) \ + do { \ + ctx->phase = value; \ + ctx->step = 0; \ + } while(0) + +/* + * Return a standardized complex structure. + */ +#undef RETURN +#define RETURN(_code) \ + do { \ + asn_dec_rval_t rval; \ + rval.code = _code; \ + rval.consumed = consumed_myself; \ + return rval; \ + } while(0) + +/* + * The SEQUENCE OF and SET OF values utilize a "quantity field". + * It is is a pointless combination of #8.6 (length determinant, capable + * of encoding tiny and huge numbers in the shortest possible number of octets) + * and the variable sized integer. What could have been encoded by #8.6 alone + * is required to be encoded by #8.6 followed by that number of unsigned octets. + * This doesn't make too much sense. It seems that the original version of OER + * standard have been using the unconstrained unsigned integer as a quantity + * field, and this legacy have gone through ISO/ITU-T standardization process. + */ +static ssize_t +oer_fetch_quantity(const void *ptr, size_t size, size_t *qty_r) { + const uint8_t *b; + const uint8_t *bend; + size_t len = 0; + size_t qty; + + ssize_t len_len = oer_fetch_length(ptr, size, &len); + if(len_len <= 0) { + *qty_r = 0; + return len_len; + } + + if((len_len + len) > size) { + *qty_r = 0; + return 0; + } + + b = (const uint8_t *)ptr + len_len; + bend = b + len; + + /* Skip the leading 0-bytes */ + for(; b < bend && *b == 0; b++) { + } + + if((bend - b) > (ssize_t)sizeof(size_t)) { + /* Length is not representable by the native size_t type */ + *qty_r = 0; + return -1; + } + + for(qty = 0; b < bend; b++) { + qty = (qty << 8) + *b; + } + + if(qty > RSIZE_MAX) { /* A bit of C11 validation */ + *qty_r = 0; + return -1; + } + + *qty_r = qty; + assert((size_t)len_len + len == (size_t)(bend - (const uint8_t *)ptr)); + return len_len + len; +} + +asn_dec_rval_t +SET_OF_decode_oer(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *td, + const asn_oer_constraints_t *constraints, void **struct_ptr, + const void *ptr, size_t size) { + const asn_SET_OF_specifics_t *specs = (const asn_SET_OF_specifics_t *)td->specifics; + asn_dec_rval_t rval = {RC_OK, 0}; + void *st = *struct_ptr; /* Target structure */ + asn_struct_ctx_t *ctx; /* Decoder context */ + size_t consumed_myself = 0; /* Consumed bytes from ptr. */ + + (void)constraints; + + if(ASN__STACK_OVERFLOW_CHECK(opt_codec_ctx)) + ASN__DECODE_FAILED; + + /* + * Create the target structure if it is not present already. + */ + if(st == 0) { + st = *struct_ptr = CALLOC(1, specs->struct_size); + if(st == 0) { + RETURN(RC_FAIL); + } + } + + /* + * Restore parsing context. + */ + ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset); + + /* + * Start to parse where left previously. + */ + switch(ctx->phase) { + case 0: { + /* + * Fetch number of elements to decode. + */ + size_t length = 0; + size_t len_size = oer_fetch_quantity(ptr, size, &length); + switch(len_size) { + case 0: + RETURN(RC_WMORE); + case -1: + RETURN(RC_FAIL); + default: + ADVANCE(len_size); + ctx->left = length; + } + } + NEXT_PHASE(ctx); + /* FALL THROUGH */ + case 1: { + /* Decode components of the extension root */ + asn_TYPE_member_t *elm = td->elements; + asn_anonymous_set_ *list = _A_SET_FROM_VOID(st); + const void *base_ptr = ptr; + ber_tlv_len_t base_ctx_left = ctx->left; + + assert(td->elements_count == 1); + + ASN_DEBUG("OER SET OF %s Decoding PHASE 1", td->name); + + for(; ctx->left > 0; ctx->left--) { + asn_dec_rval_t rv = elm->type->op->oer_decoder( + opt_codec_ctx, elm->type, + elm->encoding_constraints.oer_constraints, &ctx->ptr, ptr, + size); + ADVANCE(rv.consumed); + switch(rv.code) { + case RC_OK: + if(ASN_SET_ADD(list, ctx->ptr) != 0) { + RETURN(RC_FAIL); + } else { + ctx->ptr = 0; + /* + * This check is to avoid compression bomb with + * specs like SEQUENCE/SET OF NULL which don't + * consume data at all. + */ + if(rv.consumed == 0 && base_ptr == ptr + && (base_ctx_left - ctx->left) > 200) { + ASN__DECODE_FAILED; + } + break; + } + case RC_WMORE: + RETURN(RC_WMORE); + case RC_FAIL: + ASN_STRUCT_FREE(*elm->type, ctx->ptr); + ctx->ptr = 0; + SET_PHASE(ctx, 3); + RETURN(RC_FAIL); + } + } + /* Decoded decently. */ + NEXT_PHASE(ctx); + } + /* Fall through */ + case 2: + /* Ignore fully decoded */ + assert(ctx->left == 0); + RETURN(RC_OK); + case 3: + /* Failed to decode. */ + RETURN(RC_FAIL); + } + + return rval; +} + +static ssize_t +oer_put_quantity(size_t qty, asn_app_consume_bytes_f *cb, void *app_key) { + uint8_t buf[1 + sizeof(size_t)]; + uint8_t *b = &buf[sizeof(size_t)]; /* Last addressable */ + size_t encoded; + + do { + *b-- = qty; + qty >>= 8; + } while(qty); + + *b = sizeof(buf) - (b-buf) - 1; + encoded = sizeof(buf) - (b-buf); + if(cb(b, encoded, app_key) < 0) + return -1; + return encoded; +} + +/* + * Encode as Canonical OER. + */ +asn_enc_rval_t +SET_OF_encode_oer(const asn_TYPE_descriptor_t *td, + const asn_oer_constraints_t *constraints, const void *sptr, + asn_app_consume_bytes_f *cb, void *app_key) { + const asn_TYPE_member_t *elm; + const asn_anonymous_set_ *list; + size_t computed_size = 0; + ssize_t qty_len; + int n; + + (void)constraints; + + if(!sptr) ASN__ENCODE_FAILED; + + elm = td->elements; + list = _A_CSET_FROM_VOID(sptr); + + qty_len = oer_put_quantity(list->count, cb, app_key); + if(qty_len < 0) { + ASN__ENCODE_FAILED; + } + computed_size += qty_len; + + for(n = 0; n < list->count; n++) { + void *memb_ptr = list->array[n]; + asn_enc_rval_t er; + er = elm->type->op->oer_encoder( + elm->type, elm->encoding_constraints.oer_constraints, memb_ptr, cb, + app_key); + if(er.encoded < 0) { + return er; + } else { + computed_size += er.encoded; + } + } + + { + asn_enc_rval_t erval; + erval.encoded = computed_size; + ASN__ENCODED_OK(erval); + } +} + +#endif /* ASN_DISABLE_OER_SUPPORT */ diff --git a/libs/smux/constr_TYPE.c b/libs/smux/constr_TYPE.c index 322f68c8..aefaefdb 100644 --- a/libs/smux/constr_TYPE.c +++ b/libs/smux/constr_TYPE.c @@ -26,29 +26,32 @@ asn_TYPE_outmost_tag(const asn_TYPE_descriptor_t *type_descriptor, if(type_descriptor->tags_count) return type_descriptor->tags[0]; - return type_descriptor->outmost_tag(type_descriptor, struct_ptr, 0, 0); + return type_descriptor->op->outmost_tag(type_descriptor, struct_ptr, 0, 0); } /* * Print the target language's structure in human readable form. */ int -asn_fprint(FILE *stream, asn_TYPE_descriptor_t *td, const void *struct_ptr) { - if(!stream) stream = stdout; - if(!td || !struct_ptr) { - errno = EINVAL; - return -1; +asn_fprint(FILE *stream, const asn_TYPE_descriptor_t *td, + const void *struct_ptr) { + if(!stream) stream = stdout; + if(!td || !struct_ptr) { + errno = EINVAL; + return -1; } /* Invoke type-specific printer */ - if(td->print_struct(td, struct_ptr, 1, _print2fp, stream)) - return -1; + if(td->op->print_struct(td, struct_ptr, 1, _print2fp, stream)) { + return -1; + } - /* Terminate the output */ - if(_print2fp("\n", 1, stream)) - return -1; + /* Terminate the output */ + if(_print2fp("\n", 1, stream)) { + return -1; + } - return fflush(stream); + return fflush(stream); } /* Dump the data into the specified stdio stream */ diff --git a/libs/smux/constraints.c b/libs/smux/constraints.c index 1bdda73e..df3c6c19 100644 --- a/libs/smux/constraints.c +++ b/libs/smux/constraints.c @@ -1,11 +1,11 @@ -#include "asn_internal.h" -#include "constraints.h" +#include +#include int -asn_generic_no_constraint(asn_TYPE_descriptor_t *type_descriptor, - const void *struct_ptr, asn_app_constraint_failed_f *cb, void *key) { - - (void)type_descriptor; /* Unused argument */ +asn_generic_no_constraint(const asn_TYPE_descriptor_t *type_descriptor, + const void *struct_ptr, + asn_app_constraint_failed_f *cb, void *key) { + (void)type_descriptor; /* Unused argument */ (void)struct_ptr; /* Unused argument */ (void)cb; /* Unused argument */ (void)key; /* Unused argument */ @@ -15,10 +15,10 @@ asn_generic_no_constraint(asn_TYPE_descriptor_t *type_descriptor, } int -asn_generic_unknown_constraint(asn_TYPE_descriptor_t *type_descriptor, - const void *struct_ptr, asn_app_constraint_failed_f *cb, void *key) { - - (void)type_descriptor; /* Unused argument */ +asn_generic_unknown_constraint(const asn_TYPE_descriptor_t *type_descriptor, + const void *struct_ptr, + asn_app_constraint_failed_f *cb, void *key) { + (void)type_descriptor; /* Unused argument */ (void)struct_ptr; /* Unused argument */ (void)cb; /* Unused argument */ (void)key; /* Unused argument */ @@ -28,15 +28,16 @@ asn_generic_unknown_constraint(asn_TYPE_descriptor_t *type_descriptor, } struct errbufDesc { - asn_TYPE_descriptor_t *failed_type; - const void *failed_struct_ptr; + const asn_TYPE_descriptor_t *failed_type; + const void *failed_struct_ptr; char *errbuf; size_t errlen; }; static void -_asn_i_ctfailcb(void *key, asn_TYPE_descriptor_t *td, const void *sptr, const char *fmt, ...) { - struct errbufDesc *arg = key; +_asn_i_ctfailcb(void *key, const asn_TYPE_descriptor_t *td, const void *sptr, + const char *fmt, ...) { + struct errbufDesc *arg = key; va_list ap; ssize_t vlen; ssize_t maxlen; @@ -73,21 +74,20 @@ _asn_i_ctfailcb(void *key, asn_TYPE_descriptor_t *td, const void *sptr, const ch } int -asn_check_constraints(asn_TYPE_descriptor_t *type_descriptor, - const void *struct_ptr, char *errbuf, size_t *errlen) { - struct errbufDesc arg; - int ret; +asn_check_constraints(const asn_TYPE_descriptor_t *type_descriptor, + const void *struct_ptr, char *errbuf, size_t *errlen) { + struct errbufDesc arg; + int ret; - arg.failed_type = 0; - arg.failed_struct_ptr = 0; - arg.errbuf = errbuf; - arg.errlen = errlen ? *errlen : 0; + arg.failed_type = 0; + arg.failed_struct_ptr = 0; + arg.errbuf = errbuf; + arg.errlen = errlen ? *errlen : 0; - ret = type_descriptor->check_constraints(type_descriptor, - struct_ptr, _asn_i_ctfailcb, &arg); - if(ret == -1 && errlen) - *errlen = arg.errlen; + ret = type_descriptor->encoding_constraints.general_constraints( + type_descriptor, struct_ptr, _asn_i_ctfailcb, &arg); + if(ret == -1 && errlen) *errlen = arg.errlen; - return ret; + return ret; } diff --git a/libs/smux/der_encoder.c b/libs/smux/der_encoder.c index 1c014802..2c6a6f76 100644 --- a/libs/smux/der_encoder.c +++ b/libs/smux/der_encoder.c @@ -12,19 +12,17 @@ static ssize_t der_write_TL(ber_tlv_tag_t tag, ber_tlv_len_t len, * The DER encoder of any type. */ asn_enc_rval_t -der_encode(asn_TYPE_descriptor_t *type_descriptor, void *struct_ptr, - asn_app_consume_bytes_f *consume_bytes, void *app_key) { - - ASN_DEBUG("DER encoder invoked for %s", +der_encode(const asn_TYPE_descriptor_t *type_descriptor, const void *struct_ptr, + asn_app_consume_bytes_f *consume_bytes, void *app_key) { + ASN_DEBUG("DER encoder invoked for %s", type_descriptor->name); /* * Invoke type-specific encoder. */ - return type_descriptor->der_encoder(type_descriptor, - struct_ptr, /* Pointer to the destination structure */ - 0, 0, - consume_bytes, app_key); + return type_descriptor->op->der_encoder( + type_descriptor, struct_ptr, /* Pointer to the destination structure */ + 0, 0, consume_bytes, app_key); } /* @@ -51,15 +49,15 @@ static int encode_to_buffer_cb(const void *buffer, size_t size, void *key) { * A variant of the der_encode() which encodes the data into the provided buffer */ asn_enc_rval_t -der_encode_to_buffer(asn_TYPE_descriptor_t *type_descriptor, void *struct_ptr, - void *buffer, size_t buffer_size) { - enc_to_buf_arg arg; +der_encode_to_buffer(const asn_TYPE_descriptor_t *type_descriptor, + const void *struct_ptr, void *buffer, size_t buffer_size) { + enc_to_buf_arg arg; asn_enc_rval_t ec; arg.buffer = buffer; arg.left = buffer_size; - ec = type_descriptor->der_encoder(type_descriptor, + ec = type_descriptor->op->der_encoder(type_descriptor, struct_ptr, /* Pointer to the destination structure */ 0, 0, encode_to_buffer_cb, &arg); if(ec.encoded != -1) { @@ -74,19 +72,20 @@ der_encode_to_buffer(asn_TYPE_descriptor_t *type_descriptor, void *struct_ptr, * Write out leading TL[v] sequence according to the type definition. */ ssize_t -der_write_tags(asn_TYPE_descriptor_t *sd, - size_t struct_length, - int tag_mode, int last_tag_form, - ber_tlv_tag_t tag, /* EXPLICIT or IMPLICIT tag */ - asn_app_consume_bytes_f *cb, - void *app_key) { - const ber_tlv_tag_t *tags; /* Copy of tags stream */ - int tags_count; /* Number of tags */ - size_t overall_length; - ssize_t *lens; - int i; - - ASN_DEBUG("Writing tags (%s, tm=%d, tc=%d, tag=%s, mtc=%d)", +der_write_tags(const asn_TYPE_descriptor_t *sd, size_t struct_length, + int tag_mode, int last_tag_form, + ber_tlv_tag_t tag, /* EXPLICIT or IMPLICIT tag */ + asn_app_consume_bytes_f *cb, void *app_key) { +#define ASN1_DER_MAX_TAGS_COUNT 4 + ber_tlv_tag_t + tags_buf_scratch[ASN1_DER_MAX_TAGS_COUNT * sizeof(ber_tlv_tag_t)]; + ssize_t lens[ASN1_DER_MAX_TAGS_COUNT * sizeof(ssize_t)]; + const ber_tlv_tag_t *tags; /* Copy of tags stream */ + int tags_count; /* Number of tags */ + size_t overall_length; + int i; + + ASN_DEBUG("Writing tags (%s, tm=%d, tc=%d, tag=%s, mtc=%d)", sd->name, tag_mode, sd->tags_count, ber_tlv_tag_string(tag), tag_mode @@ -95,6 +94,11 @@ der_write_tags(asn_TYPE_descriptor_t *sd, :sd->tags_count ); + if(sd->tags_count + 1 > ASN1_DER_MAX_TAGS_COUNT) { + ASN_DEBUG("System limit %d on tags count", ASN1_DER_MAX_TAGS_COUNT); + return -1; + } + if(tag_mode) { /* * Instead of doing shaman dance like we do in ber_check_tags(), @@ -102,12 +106,7 @@ der_write_tags(asn_TYPE_descriptor_t *sd, * and initialize it appropriately. */ int stag_offset; - ber_tlv_tag_t *tags_buf; - tags_buf = (ber_tlv_tag_t *)alloca((sd->tags_count + 1) * sizeof(ber_tlv_tag_t)); - if(!tags_buf) { /* Can fail on !x86 */ - errno = ENOMEM; - return -1; - } + ber_tlv_tag_t *tags_buf = tags_buf_scratch; tags_count = sd->tags_count + 1 /* EXPLICIT or IMPLICIT tag is given */ - ((tag_mode == -1) && sd->tags_count); @@ -126,12 +125,6 @@ der_write_tags(asn_TYPE_descriptor_t *sd, if(tags_count == 0) return 0; - lens = (ssize_t *)alloca(tags_count * sizeof(lens[0])); - if(!lens) { - errno = ENOMEM; - return -1; - } - /* * Array of tags is initialized. * Now, compute the size of the TLV pairs, from right to left. @@ -146,8 +139,8 @@ der_write_tags(asn_TYPE_descriptor_t *sd, if(!cb) return overall_length - struct_length; - ASN_DEBUG("%s %s TL sequence (%d elements)", - cb?"Encoding":"Estimating", sd->name, tags_count); + ASN_DEBUG("Encoding %s TL sequence (%d elements)", sd->name, + tags_count); /* * Encode the TL sequence for real. diff --git a/libs/smux/include/stg/ANY.h b/libs/smux/include/stg/ANY.h index b7d92fa9..70d42a9e 100644 --- a/libs/smux/include/stg/ANY.h +++ b/libs/smux/include/stg/ANY.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2004 Lev Walkin . All rights reserved. + * Copyright (c) 2004-2017 Lev Walkin . All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ #ifndef ASN_TYPE_ANY_H @@ -19,12 +19,24 @@ typedef struct ANY { } ANY_t; extern asn_TYPE_descriptor_t asn_DEF_ANY; +extern asn_TYPE_operation_t asn_OP_ANY; +extern asn_OCTET_STRING_specifics_t asn_SPC_ANY_specs; asn_struct_free_f ANY_free; asn_struct_print_f ANY_print; ber_type_decoder_f ANY_decode_ber; der_type_encoder_f ANY_encode_der; xer_type_encoder_f ANY_encode_xer; +per_type_decoder_f ANY_decode_uper; +per_type_encoder_f ANY_encode_uper; + +#define ANY_free OCTET_STRING_free +#define ANY_print OCTET_STRING_print +#define ANY_compare OCTET_STRING_compare +#define ANY_constraint asn_generic_no_constraint +#define ANY_decode_ber OCTET_STRING_decode_ber +#define ANY_encode_der OCTET_STRING_encode_der +#define ANY_decode_xer OCTET_STRING_decode_xer_hex /****************************** * Handy conversion routines. * diff --git a/libs/smux/include/stg/ApplicationSyntax.h b/libs/smux/include/stg/ApplicationSyntax.h index a0f37545..c1f36cab 100644 --- a/libs/smux/include/stg/ApplicationSyntax.h +++ b/libs/smux/include/stg/ApplicationSyntax.h @@ -1,8 +1,8 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1155-SMI" * found in "RFC1155-SMI.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #ifndef _ApplicationSyntax_H_ @@ -50,6 +50,9 @@ typedef struct ApplicationSyntax { /* Implementation */ extern asn_TYPE_descriptor_t asn_DEF_ApplicationSyntax; +extern asn_CHOICE_specifics_t asn_SPC_ApplicationSyntax_specs_1; +extern asn_TYPE_member_t asn_MBR_ApplicationSyntax_1[5]; +extern asn_per_constraints_t asn_PER_type_ApplicationSyntax_constr_1; #ifdef __cplusplus } diff --git a/libs/smux/include/stg/AtEntry.h b/libs/smux/include/stg/AtEntry.h index d07e8e94..d45b915c 100644 --- a/libs/smux/include/stg/AtEntry.h +++ b/libs/smux/include/stg/AtEntry.h @@ -1,8 +1,8 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1213-MIB" * found in "RFC1213-MIB.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #ifndef _AtEntry_H_ diff --git a/libs/smux/include/stg/BIT_STRING.h b/libs/smux/include/stg/BIT_STRING.h index 732e878b..bd2d23db 100644 --- a/libs/smux/include/stg/BIT_STRING.h +++ b/libs/smux/include/stg/BIT_STRING.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2003 Lev Walkin . All rights reserved. + * Copyright (c) 2003-2017 Lev Walkin . All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ #ifndef _BIT_STRING_H_ @@ -13,7 +13,7 @@ extern "C" { typedef struct BIT_STRING_s { uint8_t *buf; /* BIT STRING body */ - int size; /* Size of the above buffer */ + size_t size; /* Size of the above buffer */ int bits_unused;/* Unused trailing bits in the last octet (0..7) */ @@ -21,10 +21,23 @@ typedef struct BIT_STRING_s { } BIT_STRING_t; extern asn_TYPE_descriptor_t asn_DEF_BIT_STRING; +extern asn_TYPE_operation_t asn_OP_BIT_STRING; +extern asn_OCTET_STRING_specifics_t asn_SPC_BIT_STRING_specs; asn_struct_print_f BIT_STRING_print; /* Human-readable output */ +asn_struct_compare_f BIT_STRING_compare; asn_constr_check_f BIT_STRING_constraint; xer_type_encoder_f BIT_STRING_encode_xer; +oer_type_decoder_f BIT_STRING_decode_oer; +oer_type_encoder_f BIT_STRING_encode_oer; +per_type_decoder_f BIT_STRING_decode_uper; +per_type_encoder_f BIT_STRING_encode_uper; +asn_random_fill_f BIT_STRING_random_fill; + +#define BIT_STRING_free OCTET_STRING_free +#define BIT_STRING_decode_ber OCTET_STRING_decode_ber +#define BIT_STRING_encode_der OCTET_STRING_encode_der +#define BIT_STRING_decode_xer OCTET_STRING_decode_xer_binary #ifdef __cplusplus } diff --git a/libs/smux/include/stg/BOOLEAN.h b/libs/smux/include/stg/BOOLEAN.h deleted file mode 100644 index 217d0f16..00000000 --- a/libs/smux/include/stg/BOOLEAN.h +++ /dev/null @@ -1,36 +0,0 @@ -/*- - * Copyright (c) 2003 Lev Walkin . All rights reserved. - * Redistribution and modifications are permitted subject to BSD license. - */ -#ifndef _BOOLEAN_H_ -#define _BOOLEAN_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * The underlying integer may contain various values, but everything - * non-zero is capped to 0xff by the DER encoder. The BER decoder may - * yield non-zero values different from 1, beware. - */ -typedef int BOOLEAN_t; - -extern asn_TYPE_descriptor_t asn_DEF_BOOLEAN; - -asn_struct_free_f BOOLEAN_free; -asn_struct_print_f BOOLEAN_print; -ber_type_decoder_f BOOLEAN_decode_ber; -der_type_encoder_f BOOLEAN_encode_der; -xer_type_decoder_f BOOLEAN_decode_xer; -xer_type_encoder_f BOOLEAN_encode_xer; -per_type_decoder_f BOOLEAN_decode_uper; -per_type_encoder_f BOOLEAN_encode_uper; - -#ifdef __cplusplus -} -#endif - -#endif /* _BOOLEAN_H_ */ diff --git a/libs/smux/include/stg/ClosePDU.h b/libs/smux/include/stg/ClosePDU.h index 0e90b6c4..e5d209c6 100644 --- a/libs/smux/include/stg/ClosePDU.h +++ b/libs/smux/include/stg/ClosePDU.h @@ -1,8 +1,8 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "SMUX" * found in "SMUX.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #ifndef _ClosePDU_H_ @@ -40,6 +40,10 @@ ber_type_decoder_f ClosePDU_decode_ber; der_type_encoder_f ClosePDU_encode_der; xer_type_decoder_f ClosePDU_decode_xer; xer_type_encoder_f ClosePDU_encode_xer; +oer_type_decoder_f ClosePDU_decode_oer; +oer_type_encoder_f ClosePDU_encode_oer; +per_type_decoder_f ClosePDU_decode_uper; +per_type_encoder_f ClosePDU_encode_uper; #ifdef __cplusplus } diff --git a/libs/smux/include/stg/Counter.h b/libs/smux/include/stg/Counter.h index 3b7b7699..cecde4a2 100644 --- a/libs/smux/include/stg/Counter.h +++ b/libs/smux/include/stg/Counter.h @@ -1,8 +1,8 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1155-SMI" * found in "RFC1155-SMI.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #ifndef _Counter_H_ @@ -22,7 +22,9 @@ extern "C" { typedef unsigned long Counter_t; /* Implementation */ +extern asn_per_constraints_t asn_PER_type_Counter_constr_1; extern asn_TYPE_descriptor_t asn_DEF_Counter; +extern const asn_INTEGER_specifics_t asn_SPC_Counter_specs_1; asn_struct_free_f Counter_free; asn_struct_print_f Counter_print; asn_constr_check_f Counter_constraint; @@ -30,6 +32,10 @@ ber_type_decoder_f Counter_decode_ber; der_type_encoder_f Counter_encode_der; xer_type_decoder_f Counter_decode_xer; xer_type_encoder_f Counter_encode_xer; +oer_type_decoder_f Counter_decode_oer; +oer_type_encoder_f Counter_encode_oer; +per_type_decoder_f Counter_decode_uper; +per_type_encoder_f Counter_encode_uper; #ifdef __cplusplus } diff --git a/libs/smux/include/stg/DisplayString.h b/libs/smux/include/stg/DisplayString.h index 0be1c6cb..c676dacc 100644 --- a/libs/smux/include/stg/DisplayString.h +++ b/libs/smux/include/stg/DisplayString.h @@ -1,8 +1,8 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1213-MIB" * found in "RFC1213-MIB.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #ifndef _DisplayString_H_ @@ -30,6 +30,10 @@ ber_type_decoder_f DisplayString_decode_ber; der_type_encoder_f DisplayString_encode_der; xer_type_decoder_f DisplayString_decode_xer; xer_type_encoder_f DisplayString_encode_xer; +oer_type_decoder_f DisplayString_decode_oer; +oer_type_encoder_f DisplayString_encode_oer; +per_type_decoder_f DisplayString_decode_uper; +per_type_encoder_f DisplayString_encode_uper; #ifdef __cplusplus } diff --git a/libs/smux/include/stg/EgpNeighEntry.h b/libs/smux/include/stg/EgpNeighEntry.h index 422ce2df..afbb1dae 100644 --- a/libs/smux/include/stg/EgpNeighEntry.h +++ b/libs/smux/include/stg/EgpNeighEntry.h @@ -1,8 +1,8 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1213-MIB" * found in "RFC1213-MIB.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #ifndef _EgpNeighEntry_H_ diff --git a/libs/smux/include/stg/Gauge.h b/libs/smux/include/stg/Gauge.h index 1fba79e9..c5c6d21e 100644 --- a/libs/smux/include/stg/Gauge.h +++ b/libs/smux/include/stg/Gauge.h @@ -1,8 +1,8 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1155-SMI" * found in "RFC1155-SMI.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #ifndef _Gauge_H_ @@ -22,7 +22,9 @@ extern "C" { typedef unsigned long Gauge_t; /* Implementation */ +extern asn_per_constraints_t asn_PER_type_Gauge_constr_1; extern asn_TYPE_descriptor_t asn_DEF_Gauge; +extern const asn_INTEGER_specifics_t asn_SPC_Gauge_specs_1; asn_struct_free_f Gauge_free; asn_struct_print_f Gauge_print; asn_constr_check_f Gauge_constraint; @@ -30,6 +32,10 @@ ber_type_decoder_f Gauge_decode_ber; der_type_encoder_f Gauge_encode_der; xer_type_decoder_f Gauge_decode_xer; xer_type_encoder_f Gauge_encode_xer; +oer_type_decoder_f Gauge_decode_oer; +oer_type_encoder_f Gauge_encode_oer; +per_type_decoder_f Gauge_decode_uper; +per_type_encoder_f Gauge_encode_uper; #ifdef __cplusplus } diff --git a/libs/smux/include/stg/GetNextRequest-PDU.h b/libs/smux/include/stg/GetNextRequest-PDU.h index cecfd5ae..7eed8d0e 100644 --- a/libs/smux/include/stg/GetNextRequest-PDU.h +++ b/libs/smux/include/stg/GetNextRequest-PDU.h @@ -1,8 +1,8 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1157-SNMP" * found in "RFC1157-SNMP.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #ifndef _GetNextRequest_PDU_H_ @@ -30,6 +30,10 @@ ber_type_decoder_f GetNextRequest_PDU_decode_ber; der_type_encoder_f GetNextRequest_PDU_encode_der; xer_type_decoder_f GetNextRequest_PDU_decode_xer; xer_type_encoder_f GetNextRequest_PDU_encode_xer; +oer_type_decoder_f GetNextRequest_PDU_decode_oer; +oer_type_encoder_f GetNextRequest_PDU_encode_oer; +per_type_decoder_f GetNextRequest_PDU_decode_uper; +per_type_encoder_f GetNextRequest_PDU_encode_uper; #ifdef __cplusplus } diff --git a/libs/smux/include/stg/GetRequest-PDU.h b/libs/smux/include/stg/GetRequest-PDU.h index 872c5a2e..ff4d88c7 100644 --- a/libs/smux/include/stg/GetRequest-PDU.h +++ b/libs/smux/include/stg/GetRequest-PDU.h @@ -1,8 +1,8 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1157-SNMP" * found in "RFC1157-SNMP.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #ifndef _GetRequest_PDU_H_ @@ -30,6 +30,10 @@ ber_type_decoder_f GetRequest_PDU_decode_ber; der_type_encoder_f GetRequest_PDU_encode_der; xer_type_decoder_f GetRequest_PDU_decode_xer; xer_type_encoder_f GetRequest_PDU_encode_xer; +oer_type_decoder_f GetRequest_PDU_decode_oer; +oer_type_encoder_f GetRequest_PDU_encode_oer; +per_type_decoder_f GetRequest_PDU_decode_uper; +per_type_encoder_f GetRequest_PDU_encode_uper; #ifdef __cplusplus } diff --git a/libs/smux/include/stg/GetResponse-PDU.h b/libs/smux/include/stg/GetResponse-PDU.h index b154ea3d..00997bbc 100644 --- a/libs/smux/include/stg/GetResponse-PDU.h +++ b/libs/smux/include/stg/GetResponse-PDU.h @@ -1,8 +1,8 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1157-SNMP" * found in "RFC1157-SNMP.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #ifndef _GetResponse_PDU_H_ @@ -30,6 +30,10 @@ ber_type_decoder_f GetResponse_PDU_decode_ber; der_type_encoder_f GetResponse_PDU_encode_der; xer_type_decoder_f GetResponse_PDU_decode_xer; xer_type_encoder_f GetResponse_PDU_encode_xer; +oer_type_decoder_f GetResponse_PDU_decode_oer; +oer_type_encoder_f GetResponse_PDU_encode_oer; +per_type_decoder_f GetResponse_PDU_decode_uper; +per_type_encoder_f GetResponse_PDU_encode_uper; #ifdef __cplusplus } diff --git a/libs/smux/include/stg/INTEGER.h b/libs/smux/include/stg/INTEGER.h index 9a880970..cc760ffa 100644 --- a/libs/smux/include/stg/INTEGER.h +++ b/libs/smux/include/stg/INTEGER.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2003, 2005 Lev Walkin . All rights reserved. + * Copyright (c) 2003-2017 Lev Walkin . All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ #ifndef _INTEGER_H_ @@ -15,6 +15,7 @@ extern "C" { typedef ASN__PRIMITIVE_TYPE_t INTEGER_t; extern asn_TYPE_descriptor_t asn_DEF_INTEGER; +extern asn_TYPE_operation_t asn_OP_INTEGER; /* Map with to integer value association */ typedef struct asn_INTEGER_enum_map_s { @@ -24,7 +25,7 @@ typedef struct asn_INTEGER_enum_map_s { } asn_INTEGER_enum_map_t; /* This type describes an enumeration for INTEGER and ENUMERATED types */ -typedef const struct asn_INTEGER_specifics_s { +typedef struct asn_INTEGER_specifics_s { const asn_INTEGER_enum_map_t *value2enum; /* N -> "tag"; sorted by N */ const unsigned int *enum2value; /* "tag" => N; sorted by tag */ int map_count; /* Elements in either map */ @@ -34,46 +35,67 @@ typedef const struct asn_INTEGER_specifics_s { int field_unsigned; /* Signed=0, unsigned=1 */ } asn_INTEGER_specifics_t; +#define INTEGER_free ASN__PRIMITIVE_TYPE_free +#define INTEGER_decode_ber ber_decode_primitive +#define INTEGER_constraint asn_generic_no_constraint asn_struct_print_f INTEGER_print; -ber_type_decoder_f INTEGER_decode_ber; +asn_struct_compare_f INTEGER_compare; der_type_encoder_f INTEGER_encode_der; xer_type_decoder_f INTEGER_decode_xer; xer_type_encoder_f INTEGER_encode_xer; +oer_type_decoder_f INTEGER_decode_oer; +oer_type_encoder_f INTEGER_encode_oer; per_type_decoder_f INTEGER_decode_uper; per_type_encoder_f INTEGER_encode_uper; +asn_random_fill_f INTEGER_random_fill; /*********************************** * Some handy conversion routines. * ***********************************/ /* + * Natiwe size-independent conversion of native integers to/from INTEGER. + * (l_size) is in bytes. * Returns 0 if it was possible to convert, -1 otherwise. * -1/EINVAL: Mandatory argument missing * -1/ERANGE: Value encoded is out of range for long representation - * -1/ENOMEM: Memory allocation failed (in asn_long2INTEGER()). + * -1/ENOMEM: Memory allocation failed (in asn_*2INTEGER()). + */ +int asn_INTEGER2imax(const INTEGER_t *i, intmax_t *l); +int asn_INTEGER2umax(const INTEGER_t *i, uintmax_t *l); +int asn_imax2INTEGER(INTEGER_t *i, intmax_t l); +int asn_umax2INTEGER(INTEGER_t *i, uintmax_t l); + +/* + * Size-specific conversion helpers. */ int asn_INTEGER2long(const INTEGER_t *i, long *l); int asn_INTEGER2ulong(const INTEGER_t *i, unsigned long *l); int asn_long2INTEGER(INTEGER_t *i, long l); int asn_ulong2INTEGER(INTEGER_t *i, unsigned long l); -/* A a reified version of strtol(3) with nicer error reporting. */ -enum asn_strtol_result_e { - ASN_STRTOL_ERROR_RANGE = -3, /* Input outside of numeric range for long type */ - ASN_STRTOL_ERROR_INVAL = -2, /* Invalid data encountered (e.g., "+-") */ - ASN_STRTOL_EXPECT_MORE = -1, /* More data expected (e.g. "+") */ - ASN_STRTOL_OK = 0, /* Conversion succeded, number ends at (*end) */ - ASN_STRTOL_EXTRA_DATA = 1 /* Conversion succeded, but the string has extra stuff */ +/* A version of strtol/strtoimax(3) with nicer error reporting. */ +enum asn_strtox_result_e { + ASN_STRTOX_ERROR_RANGE = -3, /* Input outside of supported numeric range */ + ASN_STRTOX_ERROR_INVAL = -2, /* Invalid data encountered (e.g., "+-") */ + ASN_STRTOX_EXPECT_MORE = -1, /* More data expected (e.g. "+") */ + ASN_STRTOX_OK = 0, /* Conversion succeded, number ends at (*end) */ + ASN_STRTOX_EXTRA_DATA = 1 /* Conversion succeded, but the string has extra stuff */ }; -enum asn_strtol_result_e asn_strtol_lim(const char *str, const char **end, long *l); - -/* The asn_strtol is going to be DEPRECATED soon */ -enum asn_strtol_result_e asn_strtol(const char *str, const char *end, long *l); +enum asn_strtox_result_e asn_strtol_lim(const char *str, const char **end, + long *l); +enum asn_strtox_result_e asn_strtoul_lim(const char *str, const char **end, + unsigned long *l); +enum asn_strtox_result_e asn_strtoimax_lim(const char *str, const char **end, + intmax_t *l); +enum asn_strtox_result_e asn_strtoumax_lim(const char *str, const char **end, + uintmax_t *l); /* * Convert the integer value into the corresponding enumeration map entry. */ -const asn_INTEGER_enum_map_t *INTEGER_map_value2enum(asn_INTEGER_specifics_t *specs, long value); +const asn_INTEGER_enum_map_t *INTEGER_map_value2enum( + const asn_INTEGER_specifics_t *specs, long value); #ifdef __cplusplus } diff --git a/libs/smux/include/stg/IfEntry.h b/libs/smux/include/stg/IfEntry.h index 9fdd9477..dba42368 100644 --- a/libs/smux/include/stg/IfEntry.h +++ b/libs/smux/include/stg/IfEntry.h @@ -1,8 +1,8 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1213-MIB" * found in "RFC1213-MIB.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #ifndef _IfEntry_H_ diff --git a/libs/smux/include/stg/IpAddrEntry.h b/libs/smux/include/stg/IpAddrEntry.h index 0a44b3cb..31088925 100644 --- a/libs/smux/include/stg/IpAddrEntry.h +++ b/libs/smux/include/stg/IpAddrEntry.h @@ -1,8 +1,8 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1213-MIB" * found in "RFC1213-MIB.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #ifndef _IpAddrEntry_H_ diff --git a/libs/smux/include/stg/IpAddress.h b/libs/smux/include/stg/IpAddress.h index 544cb40c..99521e01 100644 --- a/libs/smux/include/stg/IpAddress.h +++ b/libs/smux/include/stg/IpAddress.h @@ -1,8 +1,8 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1155-SMI" * found in "RFC1155-SMI.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #ifndef _IpAddress_H_ @@ -22,6 +22,7 @@ extern "C" { typedef OCTET_STRING_t IpAddress_t; /* Implementation */ +extern asn_per_constraints_t asn_PER_type_IpAddress_constr_1; extern asn_TYPE_descriptor_t asn_DEF_IpAddress; asn_struct_free_f IpAddress_free; asn_struct_print_f IpAddress_print; @@ -30,6 +31,10 @@ ber_type_decoder_f IpAddress_decode_ber; der_type_encoder_f IpAddress_encode_der; xer_type_decoder_f IpAddress_decode_xer; xer_type_encoder_f IpAddress_encode_xer; +oer_type_decoder_f IpAddress_decode_oer; +oer_type_encoder_f IpAddress_encode_oer; +per_type_decoder_f IpAddress_decode_uper; +per_type_encoder_f IpAddress_encode_uper; #ifdef __cplusplus } diff --git a/libs/smux/include/stg/IpNetToMediaEntry.h b/libs/smux/include/stg/IpNetToMediaEntry.h index ca72bff6..f795d7fb 100644 --- a/libs/smux/include/stg/IpNetToMediaEntry.h +++ b/libs/smux/include/stg/IpNetToMediaEntry.h @@ -1,8 +1,8 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1213-MIB" * found in "RFC1213-MIB.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #ifndef _IpNetToMediaEntry_H_ diff --git a/libs/smux/include/stg/IpRouteEntry.h b/libs/smux/include/stg/IpRouteEntry.h index 28030dcb..999e3421 100644 --- a/libs/smux/include/stg/IpRouteEntry.h +++ b/libs/smux/include/stg/IpRouteEntry.h @@ -1,8 +1,8 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1213-MIB" * found in "RFC1213-MIB.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #ifndef _IpRouteEntry_H_ diff --git a/libs/smux/include/stg/Message.h b/libs/smux/include/stg/Message.h index 3049e477..51aba789 100644 --- a/libs/smux/include/stg/Message.h +++ b/libs/smux/include/stg/Message.h @@ -1,8 +1,8 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1157-SNMP" * found in "RFC1157-SNMP.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #ifndef _Message_H_ diff --git a/libs/smux/include/stg/NULL.h b/libs/smux/include/stg/NULL.h index 131e7759..c8e05d23 100644 --- a/libs/smux/include/stg/NULL.h +++ b/libs/smux/include/stg/NULL.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2003 Lev Walkin . All rights reserved. + * Copyright (c) 2003-2017 Lev Walkin . All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ #ifndef ASN_TYPE_NULL_H @@ -12,19 +12,28 @@ extern "C" { #endif /* - * The value of the NULL type is meaningless: see BOOLEAN if you want to - * carry true/false semantics. + * The value of the NULL type is meaningless. + * Use the BOOLEAN type if you need to carry true/false semantics. */ typedef int NULL_t; extern asn_TYPE_descriptor_t asn_DEF_NULL; +extern asn_TYPE_operation_t asn_OP_NULL; +asn_struct_free_f NULL_free; asn_struct_print_f NULL_print; +asn_struct_compare_f NULL_compare; +ber_type_decoder_f NULL_decode_ber; der_type_encoder_f NULL_encode_der; xer_type_decoder_f NULL_decode_xer; xer_type_encoder_f NULL_encode_xer; +oer_type_decoder_f NULL_decode_oer; +oer_type_encoder_f NULL_encode_oer; per_type_decoder_f NULL_decode_uper; per_type_encoder_f NULL_encode_uper; +asn_random_fill_f NULL_random_fill; + +#define NULL_constraint asn_generic_no_constraint #ifdef __cplusplus } diff --git a/libs/smux/include/stg/NativeEnumerated.h b/libs/smux/include/stg/NativeEnumerated.h deleted file mode 100644 index c59bb1ba..00000000 --- a/libs/smux/include/stg/NativeEnumerated.h +++ /dev/null @@ -1,32 +0,0 @@ -/*- - * Copyright (c) 2004, 2005, 2006 Lev Walkin . - * All rights reserved. - * Redistribution and modifications are permitted subject to BSD license. - */ -/* - * This type differs from the standard ENUMERATED in that it is modelled using - * the fixed machine type (long, int, short), so it can hold only values of - * limited length. There is no type (i.e., NativeEnumerated_t, any integer type - * will do). - * This type may be used when integer range is limited by subtype constraints. - */ -#ifndef _NativeEnumerated_H_ -#define _NativeEnumerated_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -extern asn_TYPE_descriptor_t asn_DEF_NativeEnumerated; - -xer_type_encoder_f NativeEnumerated_encode_xer; -per_type_decoder_f NativeEnumerated_decode_uper; -per_type_encoder_f NativeEnumerated_encode_uper; - -#ifdef __cplusplus -} -#endif - -#endif /* _NativeEnumerated_H_ */ diff --git a/libs/smux/include/stg/NativeInteger.h b/libs/smux/include/stg/NativeInteger.h index 4e63a835..e2741c20 100644 --- a/libs/smux/include/stg/NativeInteger.h +++ b/libs/smux/include/stg/NativeInteger.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2004 Lev Walkin . All rights reserved. + * Copyright (c) 2004-2017 Lev Walkin . All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ /* @@ -20,15 +20,22 @@ extern "C" { #endif extern asn_TYPE_descriptor_t asn_DEF_NativeInteger; +extern asn_TYPE_operation_t asn_OP_NativeInteger; asn_struct_free_f NativeInteger_free; asn_struct_print_f NativeInteger_print; +asn_struct_compare_f NativeInteger_compare; ber_type_decoder_f NativeInteger_decode_ber; der_type_encoder_f NativeInteger_encode_der; xer_type_decoder_f NativeInteger_decode_xer; xer_type_encoder_f NativeInteger_encode_xer; +oer_type_decoder_f NativeInteger_decode_oer; +oer_type_encoder_f NativeInteger_encode_oer; per_type_decoder_f NativeInteger_decode_uper; per_type_encoder_f NativeInteger_encode_uper; +asn_random_fill_f NativeInteger_random_fill; + +#define NativeInteger_constraint asn_generic_no_constraint #ifdef __cplusplus } diff --git a/libs/smux/include/stg/NetworkAddress.h b/libs/smux/include/stg/NetworkAddress.h index 8bcba17d..f3ba6a69 100644 --- a/libs/smux/include/stg/NetworkAddress.h +++ b/libs/smux/include/stg/NetworkAddress.h @@ -1,8 +1,8 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1155-SMI" * found in "RFC1155-SMI.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #ifndef _NetworkAddress_H_ @@ -38,6 +38,9 @@ typedef struct NetworkAddress { /* Implementation */ extern asn_TYPE_descriptor_t asn_DEF_NetworkAddress; +extern asn_CHOICE_specifics_t asn_SPC_NetworkAddress_specs_1; +extern asn_TYPE_member_t asn_MBR_NetworkAddress_1[1]; +extern asn_per_constraints_t asn_PER_type_NetworkAddress_constr_1; #ifdef __cplusplus } diff --git a/libs/smux/include/stg/OBJECT_IDENTIFIER.h b/libs/smux/include/stg/OBJECT_IDENTIFIER.h index c2c6373e..aa0d5c70 100644 --- a/libs/smux/include/stg/OBJECT_IDENTIFIER.h +++ b/libs/smux/include/stg/OBJECT_IDENTIFIER.h @@ -1,6 +1,5 @@ -/*- - * Copyright (c) 2003, 2004, 2005 Lev Walkin . - * All rights reserved. +/* + * Copyright (c) 2003-2017 Lev Walkin . All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ #ifndef _OBJECT_IDENTIFIER_H_ @@ -8,70 +7,80 @@ #include #include +#include #ifdef __cplusplus extern "C" { #endif +typedef uint32_t asn_oid_arc_t; +#define ASN_OID_ARC_MAX (~((asn_oid_arc_t)0)) + typedef ASN__PRIMITIVE_TYPE_t OBJECT_IDENTIFIER_t; extern asn_TYPE_descriptor_t asn_DEF_OBJECT_IDENTIFIER; +extern asn_TYPE_operation_t asn_OP_OBJECT_IDENTIFIER; asn_struct_print_f OBJECT_IDENTIFIER_print; asn_constr_check_f OBJECT_IDENTIFIER_constraint; der_type_encoder_f OBJECT_IDENTIFIER_encode_der; xer_type_decoder_f OBJECT_IDENTIFIER_decode_xer; xer_type_encoder_f OBJECT_IDENTIFIER_encode_xer; +asn_random_fill_f OBJECT_IDENTIFIER_random_fill; + +#define OBJECT_IDENTIFIER_free ASN__PRIMITIVE_TYPE_free +#define OBJECT_IDENTIFIER_compare OCTET_STRING_compare +#define OBJECT_IDENTIFIER_decode_ber ber_decode_primitive +#define OBJECT_IDENTIFIER_encode_der der_encode_primitive +#define OBJECT_IDENTIFIER_decode_oer oer_decode_primitive +#define OBJECT_IDENTIFIER_encode_oer oer_encode_primitive +#define OBJECT_IDENTIFIER_decode_uper OCTET_STRING_decode_uper +#define OBJECT_IDENTIFIER_encode_uper OCTET_STRING_encode_uper /********************************** * Some handy conversion routines * **********************************/ /* - * This function fills an (_arcs) array with OBJECT IDENTIFIER arcs - * up to specified (_arc_slots) elements. - * + * This function fills an (arcs) array with OBJECT IDENTIFIER arcs + * up to specified (arc_slots) elements. + * * EXAMPLE: * void print_arcs(OBJECT_IDENTIFIER_t *oid) { - * unsigned long fixed_arcs[10]; // Try with fixed space first - * unsigned long *arcs = fixed_arcs; - * int arc_type_size = sizeof(fixed_arcs[0]); // sizeof(long) - * int arc_slots = sizeof(fixed_arcs)/sizeof(fixed_arcs[0]); // 10 - * int count; // Real number of arcs. + * asn_oid_arc_t fixed_arcs[10]; // Try with fixed space first + * asn_oid_arc_t *arcs = fixed_arcs; + * size_t arc_slots = sizeof(fixed_arcs)/sizeof(fixed_arcs[0]); // 10 + * ssize_t count; // Real number of arcs. * int i; - * - * count = OBJECT_IDENTIFIER_get_arcs(oid, arcs, - * arc_type_size, arc_slots); + * + * count = OBJECT_IDENTIFIER_get_arcs(oid, arcs, arc_slots); * // If necessary, reallocate arcs array and try again. * if(count > arc_slots) { * arc_slots = count; - * arcs = malloc(arc_type_size * arc_slots); + * arcs = malloc(sizeof(asn_oid_arc_t) * arc_slots); * if(!arcs) return; - * count = OBJECT_IDENTIFIER_get_arcs(oid, arcs, - * arc_type_size, arc_slots); + * count = OBJECT_IDENTIFIER_get_arcs(oid, arcs, arc_slots); * assert(count == arc_slots); * } - * + * * // Print the contents of the arcs array. * for(i = 0; i < count; i++) - * printf("%d\n", arcs[i]); - * + * printf("%"PRIu32"\n", arcs[i]); + * * // Avoid memory leak. * if(arcs != fixed_arcs) free(arcs); * } - * + * * RETURN VALUES: * -1/EINVAL: Invalid arguments (oid is missing) * -1/ERANGE: One or more arcs have value out of array cell type range. * >=0: Number of arcs contained in the OBJECT IDENTIFIER - * - * WARNING: The function always returns the real number of arcs, - * even if there is no sufficient (_arc_slots) provided. + * + * WARNING: The function always returns the actual number of arcs, + * even if there is no sufficient (arc_slots) provided. */ -int OBJECT_IDENTIFIER_get_arcs(const OBJECT_IDENTIFIER_t *_oid, - void *_arcs, /* e.g., unsigned int arcs[N] */ - unsigned int _arc_type_size, /* e.g., sizeof(arcs[0]) */ - unsigned int _arc_slots /* e.g., N */); +ssize_t OBJECT_IDENTIFIER_get_arcs(const OBJECT_IDENTIFIER_t *oid, + asn_oid_arc_t *arcs, size_t arc_slots); /* * This functions initializes the OBJECT IDENTIFIER object with @@ -83,25 +92,13 @@ int OBJECT_IDENTIFIER_get_arcs(const OBJECT_IDENTIFIER_t *_oid, * -1/ENOMEM: Memory allocation failed * 0: The object was initialized with new arcs. */ -int OBJECT_IDENTIFIER_set_arcs(OBJECT_IDENTIFIER_t *_oid, - const void *_arcs, /* e.g., unsigned int arcs[N] */ - unsigned int _arc_type_size, /* e.g., sizeof(arcs[0]) */ - unsigned int _arc_slots /* e.g., N */); +int OBJECT_IDENTIFIER_set_arcs(OBJECT_IDENTIFIER_t *oid, + const asn_oid_arc_t *arcs, size_t arcs_count); -/* - * Print the specified OBJECT IDENTIFIER arc. - */ -int OBJECT_IDENTIFIER_print_arc(const uint8_t *arcbuf, int arclen, - int add, /* Arbitrary offset, required to process the first two arcs */ - asn_app_consume_bytes_f *cb, void *app_key); - -/* Same as above, but returns the number of written digits, instead of 0 */ -ssize_t OBJECT_IDENTIFIER__dump_arc(const uint8_t *arcbuf, int arclen, int add, - asn_app_consume_bytes_f *cb, void *app_key); /* * Parse the OBJECT IDENTIFIER textual representation ("1.3.6.1.4.1.9363"). - * No arc can exceed the (0..signed_long_max) range (typically, 0..2G if L32). + * No arc can exceed the (0..ASN_OID_ARC_MAX, which is the same as UINT32_MAX). * This function is not specific to OBJECT IDENTIFIER, it may be used to parse * the RELATIVE-OID data, or any other data consisting of dot-separated * series of numeric values. @@ -117,20 +114,38 @@ ssize_t OBJECT_IDENTIFIER__dump_arc(const uint8_t *arcbuf, int arclen, int add, * >= 0: Number of arcs contained in the OBJECT IDENTIFIER. * * WARNING: The function always returns the real number of arcs, - * even if there is no sufficient (_arc_slots) provided. - * This is useful for (_arc_slots) value estimation. + * even if there is no sufficient (arc_slots) provided. + * This is useful for (arc_slots) value estimation. */ -int OBJECT_IDENTIFIER_parse_arcs(const char *oid_text, ssize_t oid_txt_length, - long arcs[], unsigned int arcs_slots, const char **opt_oid_text_end); +ssize_t OBJECT_IDENTIFIER_parse_arcs(const char *oid_text, + ssize_t oid_txt_length, + asn_oid_arc_t *arcs, size_t arcs_count, + const char **opt_oid_text_end); /* * Internal functions. * Used by RELATIVE-OID implementation in particular. */ -int OBJECT_IDENTIFIER_get_single_arc(const uint8_t *arcbuf, unsigned int arclen, - signed int add, void *value, unsigned int value_size); -int OBJECT_IDENTIFIER_set_single_arc(uint8_t *arcbuf, - const void *arcval, unsigned int arcval_size, int _prepared_order); + +/* + * Retrieve a single arc of size from the (arcbuf) buffer. + * RETURN VALUES: + * -1: Failed to retrieve the value from the (arcbuf). + * >0: Number of bytes consumed from the (arcbuf), <= (arcbuf_len). + */ +ssize_t OBJECT_IDENTIFIER_get_single_arc(const uint8_t *arcbuf, + size_t arcbuf_len, + asn_oid_arc_t *ret_value); + +/* + * Write the unterminated arc value into the (arcbuf) which has the size at + * least (arcbuf_len). + * RETURN VALUES: + * -1: (arcbuf_len) size is not sufficient to write the value. + * : Number of bytes appended to the arcbuf (<= arcbuf_len). + */ +ssize_t OBJECT_IDENTIFIER_set_single_arc(uint8_t *arcbuf, size_t arcbuf_len, + asn_oid_arc_t arc_value); #ifdef __cplusplus } diff --git a/libs/smux/include/stg/OCTET_STRING.h b/libs/smux/include/stg/OCTET_STRING.h index 013c7b13..bb06dc62 100644 --- a/libs/smux/include/stg/OCTET_STRING.h +++ b/libs/smux/include/stg/OCTET_STRING.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2003 Lev Walkin . All rights reserved. + * Copyright (c) 2003-2017 Lev Walkin . All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ #ifndef _OCTET_STRING_H_ @@ -13,16 +13,18 @@ extern "C" { typedef struct OCTET_STRING { uint8_t *buf; /* Buffer with consecutive OCTET_STRING bits */ - int size; /* Size of the buffer */ + size_t size; /* Size of the buffer */ asn_struct_ctx_t _asn_ctx; /* Parsing across buffer boundaries */ } OCTET_STRING_t; extern asn_TYPE_descriptor_t asn_DEF_OCTET_STRING; +extern asn_TYPE_operation_t asn_OP_OCTET_STRING; asn_struct_free_f OCTET_STRING_free; asn_struct_print_f OCTET_STRING_print; asn_struct_print_f OCTET_STRING_print_utf8; +asn_struct_compare_f OCTET_STRING_compare; ber_type_decoder_f OCTET_STRING_decode_ber; der_type_encoder_f OCTET_STRING_encode_der; xer_type_decoder_f OCTET_STRING_decode_xer_hex; /* Hexadecimal */ @@ -30,8 +32,14 @@ xer_type_decoder_f OCTET_STRING_decode_xer_binary; /* 01010111010 */ xer_type_decoder_f OCTET_STRING_decode_xer_utf8; /* ASCII/UTF-8 */ xer_type_encoder_f OCTET_STRING_encode_xer; xer_type_encoder_f OCTET_STRING_encode_xer_utf8; +oer_type_decoder_f OCTET_STRING_decode_oer; +oer_type_encoder_f OCTET_STRING_encode_oer; per_type_decoder_f OCTET_STRING_decode_uper; per_type_encoder_f OCTET_STRING_encode_uper; +asn_random_fill_f OCTET_STRING_random_fill; + +#define OCTET_STRING_constraint asn_generic_no_constraint +#define OCTET_STRING_decode_xer OCTET_STRING_decode_xer_hex /****************************** * Handy conversion routines. * @@ -56,29 +64,35 @@ int OCTET_STRING_fromBuf(OCTET_STRING_t *s, const char *str, int size); * allocated object. NULL is permitted in str: the function will just allocate * empty OCTET STRING. */ -OCTET_STRING_t *OCTET_STRING_new_fromBuf(asn_TYPE_descriptor_t *td, - const char *str, int size); +OCTET_STRING_t *OCTET_STRING_new_fromBuf(const asn_TYPE_descriptor_t *td, + const char *str, int size); /**************************** * Internally useful stuff. * ****************************/ -typedef const struct asn_OCTET_STRING_specifics_s { - /* - * Target structure description. - */ - int struct_size; /* Size of the structure */ - int ctx_offset; /* Offset of the asn_struct_ctx_t member */ - - enum asn_OS_Subvariant { - ASN_OSUBV_ANY, /* The open type (ANY) */ - ASN_OSUBV_BIT, /* BIT STRING */ - ASN_OSUBV_STR, /* String types, not {BMP,Universal}String */ - ASN_OSUBV_U16, /* 16-bit character (BMPString) */ - ASN_OSUBV_U32 /* 32-bit character (UniversalString) */ - } subvariant; +typedef struct asn_OCTET_STRING_specifics_s { + /* + * Target structure description. + */ + unsigned struct_size; /* Size of the structure */ + unsigned ctx_offset; /* Offset of the asn_struct_ctx_t member */ + + enum asn_OS_Subvariant { + ASN_OSUBV_ANY, /* The open type (ANY) */ + ASN_OSUBV_BIT, /* BIT STRING */ + ASN_OSUBV_STR, /* String types, not {BMP,Universal}String */ + ASN_OSUBV_U16, /* 16-bit character (BMPString) */ + ASN_OSUBV_U32 /* 32-bit character (UniversalString) */ + } subvariant; } asn_OCTET_STRING_specifics_t; +extern asn_OCTET_STRING_specifics_t asn_SPC_OCTET_STRING_specs; + +size_t OCTET_STRING_random_length_constrained( + const asn_TYPE_descriptor_t *, const asn_encoding_constraints_t *, + size_t max_length); + #ifdef __cplusplus } #endif diff --git a/libs/smux/include/stg/OPEN_TYPE.h b/libs/smux/include/stg/OPEN_TYPE.h new file mode 100644 index 00000000..d0f02fd7 --- /dev/null +++ b/libs/smux/include/stg/OPEN_TYPE.h @@ -0,0 +1,63 @@ +/*- + * Copyright (c) 2017-2017 Lev Walkin . All rights reserved. + * Redistribution and modifications are permitted subject to BSD license. + */ +#ifndef ASN_OPEN_TYPE_H +#define ASN_OPEN_TYPE_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define OPEN_TYPE_free CHOICE_free +#define OPEN_TYPE_print CHOICE_print +#define OPEN_TYPE_compare CHOICE_compare +#define OPEN_TYPE_constraint CHOICE_constraint +#define OPEN_TYPE_decode_ber NULL +#define OPEN_TYPE_encode_der CHOICE_encode_der +#define OPEN_TYPE_decode_xer NULL +#define OPEN_TYPE_encode_xer CHOICE_encode_xer +#define OPEN_TYPE_decode_uper NULL + +extern asn_TYPE_operation_t asn_OP_OPEN_TYPE; + +/* + * Decode an Open Type which is potentially constraiend + * by the other members of the parent structure. + */ +asn_dec_rval_t OPEN_TYPE_ber_get(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *parent_type, + void *parent_structure, + const asn_TYPE_member_t *element, + const void *ptr, size_t size); + +asn_dec_rval_t OPEN_TYPE_xer_get(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *parent_type, + void *parent_structure, + const asn_TYPE_member_t *element, + const void *ptr, size_t size); + +asn_dec_rval_t OPEN_TYPE_oer_get(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *parent_type, + void *parent_structure, + asn_TYPE_member_t *element, const void *ptr, + size_t size); + +asn_dec_rval_t OPEN_TYPE_uper_get(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *parent_type, + void *parent_structure, + const asn_TYPE_member_t *element, + asn_per_data_t *pd); + +asn_enc_rval_t OPEN_TYPE_encode_uper( + const asn_TYPE_descriptor_t *type_descriptor, + const asn_per_constraints_t *constraints, const void *struct_ptr, + asn_per_outp_t *per_output); + +#ifdef __cplusplus +} +#endif + +#endif /* ASN_OPEN_TYPE_H */ diff --git a/libs/smux/include/stg/ObjectName.h b/libs/smux/include/stg/ObjectName.h index 4187cd0c..2e8c238d 100644 --- a/libs/smux/include/stg/ObjectName.h +++ b/libs/smux/include/stg/ObjectName.h @@ -1,8 +1,8 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1155-SMI" * found in "RFC1155-SMI.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #ifndef _ObjectName_H_ @@ -30,6 +30,10 @@ ber_type_decoder_f ObjectName_decode_ber; der_type_encoder_f ObjectName_encode_der; xer_type_decoder_f ObjectName_decode_xer; xer_type_encoder_f ObjectName_encode_xer; +oer_type_decoder_f ObjectName_decode_oer; +oer_type_encoder_f ObjectName_encode_oer; +per_type_decoder_f ObjectName_decode_uper; +per_type_encoder_f ObjectName_encode_uper; #ifdef __cplusplus } diff --git a/libs/smux/include/stg/ObjectSyntax.h b/libs/smux/include/stg/ObjectSyntax.h index ad56e7e0..eb83dbf2 100644 --- a/libs/smux/include/stg/ObjectSyntax.h +++ b/libs/smux/include/stg/ObjectSyntax.h @@ -1,8 +1,8 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1155-SMI" * found in "RFC1155-SMI.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #ifndef _ObjectSyntax_H_ @@ -41,6 +41,9 @@ typedef struct ObjectSyntax { /* Implementation */ extern asn_TYPE_descriptor_t asn_DEF_ObjectSyntax; +extern asn_CHOICE_specifics_t asn_SPC_ObjectSyntax_specs_1; +extern asn_TYPE_member_t asn_MBR_ObjectSyntax_1[2]; +extern asn_per_constraints_t asn_PER_type_ObjectSyntax_constr_1; #ifdef __cplusplus } diff --git a/libs/smux/include/stg/Opaque.h b/libs/smux/include/stg/Opaque.h index ff94eff6..7dfd338b 100644 --- a/libs/smux/include/stg/Opaque.h +++ b/libs/smux/include/stg/Opaque.h @@ -1,8 +1,8 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1155-SMI" * found in "RFC1155-SMI.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #ifndef _Opaque_H_ @@ -30,6 +30,10 @@ ber_type_decoder_f Opaque_decode_ber; der_type_encoder_f Opaque_encode_der; xer_type_decoder_f Opaque_decode_xer; xer_type_encoder_f Opaque_encode_xer; +oer_type_decoder_f Opaque_decode_oer; +oer_type_encoder_f Opaque_encode_oer; +per_type_decoder_f Opaque_decode_uper; +per_type_encoder_f Opaque_encode_uper; #ifdef __cplusplus } diff --git a/libs/smux/include/stg/OpenPDU.h b/libs/smux/include/stg/OpenPDU.h index 1b77d558..cab800ca 100644 --- a/libs/smux/include/stg/OpenPDU.h +++ b/libs/smux/include/stg/OpenPDU.h @@ -1,8 +1,8 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "SMUX" * found in "SMUX.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #ifndef _OpenPDU_H_ @@ -38,6 +38,9 @@ typedef struct OpenPDU { /* Implementation */ extern asn_TYPE_descriptor_t asn_DEF_OpenPDU; +extern asn_CHOICE_specifics_t asn_SPC_OpenPDU_specs_1; +extern asn_TYPE_member_t asn_MBR_OpenPDU_1[1]; +extern asn_per_constraints_t asn_PER_type_OpenPDU_constr_1; #ifdef __cplusplus } diff --git a/libs/smux/include/stg/PDU.h b/libs/smux/include/stg/PDU.h index 10e30f17..5d9f69b6 100644 --- a/libs/smux/include/stg/PDU.h +++ b/libs/smux/include/stg/PDU.h @@ -1,8 +1,8 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1157-SNMP" * found in "RFC1157-SNMP.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #ifndef _PDU_H_ @@ -43,6 +43,8 @@ typedef struct PDU { /* Implementation */ extern asn_TYPE_descriptor_t asn_DEF_PDU; +extern asn_SEQUENCE_specifics_t asn_SPC_PDU_specs_1; +extern asn_TYPE_member_t asn_MBR_PDU_1[4]; #ifdef __cplusplus } diff --git a/libs/smux/include/stg/PDUs.h b/libs/smux/include/stg/PDUs.h index db197d31..6baf7ce5 100644 --- a/libs/smux/include/stg/PDUs.h +++ b/libs/smux/include/stg/PDUs.h @@ -1,8 +1,8 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1157-SNMP" * found in "RFC1157-SNMP.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #ifndef _PDUs_H_ @@ -50,6 +50,9 @@ typedef struct PDUs { /* Implementation */ extern asn_TYPE_descriptor_t asn_DEF_PDUs; +extern asn_CHOICE_specifics_t asn_SPC_PDUs_specs_1; +extern asn_TYPE_member_t asn_MBR_PDUs_1[5]; +extern asn_per_constraints_t asn_PER_type_PDUs_constr_1; #ifdef __cplusplus } diff --git a/libs/smux/include/stg/PhysAddress.h b/libs/smux/include/stg/PhysAddress.h index 08e43e91..738e970b 100644 --- a/libs/smux/include/stg/PhysAddress.h +++ b/libs/smux/include/stg/PhysAddress.h @@ -1,8 +1,8 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1213-MIB" * found in "RFC1213-MIB.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #ifndef _PhysAddress_H_ @@ -30,6 +30,10 @@ ber_type_decoder_f PhysAddress_decode_ber; der_type_encoder_f PhysAddress_encode_der; xer_type_decoder_f PhysAddress_decode_xer; xer_type_encoder_f PhysAddress_encode_xer; +oer_type_decoder_f PhysAddress_decode_oer; +oer_type_encoder_f PhysAddress_encode_oer; +per_type_decoder_f PhysAddress_decode_uper; +per_type_encoder_f PhysAddress_encode_uper; #ifdef __cplusplus } diff --git a/libs/smux/include/stg/RReqPDU.h b/libs/smux/include/stg/RReqPDU.h index 570c1964..c7a48242 100644 --- a/libs/smux/include/stg/RReqPDU.h +++ b/libs/smux/include/stg/RReqPDU.h @@ -1,8 +1,8 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "SMUX" * found in "SMUX.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #ifndef _RReqPDU_H_ @@ -40,6 +40,8 @@ typedef struct RReqPDU { /* Implementation */ extern asn_TYPE_descriptor_t asn_DEF_RReqPDU; +extern asn_SEQUENCE_specifics_t asn_SPC_RReqPDU_specs_1; +extern asn_TYPE_member_t asn_MBR_RReqPDU_1[3]; #ifdef __cplusplus } diff --git a/libs/smux/include/stg/RRspPDU.h b/libs/smux/include/stg/RRspPDU.h index f9b43874..158e1353 100644 --- a/libs/smux/include/stg/RRspPDU.h +++ b/libs/smux/include/stg/RRspPDU.h @@ -1,8 +1,8 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "SMUX" * found in "SMUX.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #ifndef _RRspPDU_H_ @@ -35,6 +35,10 @@ ber_type_decoder_f RRspPDU_decode_ber; der_type_encoder_f RRspPDU_encode_der; xer_type_decoder_f RRspPDU_decode_xer; xer_type_encoder_f RRspPDU_encode_xer; +oer_type_decoder_f RRspPDU_decode_oer; +oer_type_encoder_f RRspPDU_encode_oer; +per_type_decoder_f RRspPDU_decode_uper; +per_type_encoder_f RRspPDU_encode_uper; #ifdef __cplusplus } diff --git a/libs/smux/include/stg/SMUX-PDUs.h b/libs/smux/include/stg/SMUX-PDUs.h index 03387542..9bac69c0 100644 --- a/libs/smux/include/stg/SMUX-PDUs.h +++ b/libs/smux/include/stg/SMUX-PDUs.h @@ -1,8 +1,8 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "SMUX" * found in "SMUX.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #ifndef _SMUX_PDUs_H_ diff --git a/libs/smux/include/stg/SOutPDU.h b/libs/smux/include/stg/SOutPDU.h index d0259f9a..08fa3db8 100644 --- a/libs/smux/include/stg/SOutPDU.h +++ b/libs/smux/include/stg/SOutPDU.h @@ -1,8 +1,8 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "SMUX" * found in "SMUX.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #ifndef _SOutPDU_H_ @@ -36,6 +36,10 @@ ber_type_decoder_f SOutPDU_decode_ber; der_type_encoder_f SOutPDU_encode_der; xer_type_decoder_f SOutPDU_decode_xer; xer_type_encoder_f SOutPDU_encode_xer; +oer_type_decoder_f SOutPDU_decode_oer; +oer_type_encoder_f SOutPDU_encode_oer; +per_type_decoder_f SOutPDU_decode_uper; +per_type_encoder_f SOutPDU_encode_uper; #ifdef __cplusplus } diff --git a/libs/smux/include/stg/SetRequest-PDU.h b/libs/smux/include/stg/SetRequest-PDU.h index 1a5636fb..4c5a5a69 100644 --- a/libs/smux/include/stg/SetRequest-PDU.h +++ b/libs/smux/include/stg/SetRequest-PDU.h @@ -1,8 +1,8 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1157-SNMP" * found in "RFC1157-SNMP.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #ifndef _SetRequest_PDU_H_ @@ -30,6 +30,10 @@ ber_type_decoder_f SetRequest_PDU_decode_ber; der_type_encoder_f SetRequest_PDU_encode_der; xer_type_decoder_f SetRequest_PDU_decode_xer; xer_type_encoder_f SetRequest_PDU_encode_xer; +oer_type_decoder_f SetRequest_PDU_decode_oer; +oer_type_encoder_f SetRequest_PDU_encode_oer; +per_type_decoder_f SetRequest_PDU_decode_uper; +per_type_encoder_f SetRequest_PDU_encode_uper; #ifdef __cplusplus } diff --git a/libs/smux/include/stg/SimpleOpen.h b/libs/smux/include/stg/SimpleOpen.h index 4f838ade..f6e94d7d 100644 --- a/libs/smux/include/stg/SimpleOpen.h +++ b/libs/smux/include/stg/SimpleOpen.h @@ -1,8 +1,8 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "SMUX" * found in "SMUX.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #ifndef _SimpleOpen_H_ @@ -40,6 +40,8 @@ typedef struct SimpleOpen { /* Implementation */ extern asn_TYPE_descriptor_t asn_DEF_SimpleOpen; +extern asn_SEQUENCE_specifics_t asn_SPC_SimpleOpen_specs_1; +extern asn_TYPE_member_t asn_MBR_SimpleOpen_1[4]; #ifdef __cplusplus } diff --git a/libs/smux/include/stg/SimpleSyntax.h b/libs/smux/include/stg/SimpleSyntax.h index dcf32c95..0b7c13b8 100644 --- a/libs/smux/include/stg/SimpleSyntax.h +++ b/libs/smux/include/stg/SimpleSyntax.h @@ -1,8 +1,8 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1155-SMI" * found in "RFC1155-SMI.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #ifndef _SimpleSyntax_H_ @@ -47,6 +47,9 @@ typedef struct SimpleSyntax { /* Implementation */ extern asn_TYPE_descriptor_t asn_DEF_SimpleSyntax; +extern asn_CHOICE_specifics_t asn_SPC_SimpleSyntax_specs_1; +extern asn_TYPE_member_t asn_MBR_SimpleSyntax_1[4]; +extern asn_per_constraints_t asn_PER_type_SimpleSyntax_constr_1; #ifdef __cplusplus } diff --git a/libs/smux/include/stg/TcpConnEntry.h b/libs/smux/include/stg/TcpConnEntry.h index fb3d33ca..5ebd315b 100644 --- a/libs/smux/include/stg/TcpConnEntry.h +++ b/libs/smux/include/stg/TcpConnEntry.h @@ -1,8 +1,8 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1213-MIB" * found in "RFC1213-MIB.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #ifndef _TcpConnEntry_H_ diff --git a/libs/smux/include/stg/TimeTicks.h b/libs/smux/include/stg/TimeTicks.h index fe7ea1db..52210c03 100644 --- a/libs/smux/include/stg/TimeTicks.h +++ b/libs/smux/include/stg/TimeTicks.h @@ -1,8 +1,8 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1155-SMI" * found in "RFC1155-SMI.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #ifndef _TimeTicks_H_ @@ -22,7 +22,9 @@ extern "C" { typedef unsigned long TimeTicks_t; /* Implementation */ +extern asn_per_constraints_t asn_PER_type_TimeTicks_constr_1; extern asn_TYPE_descriptor_t asn_DEF_TimeTicks; +extern const asn_INTEGER_specifics_t asn_SPC_TimeTicks_specs_1; asn_struct_free_f TimeTicks_free; asn_struct_print_f TimeTicks_print; asn_constr_check_f TimeTicks_constraint; @@ -30,6 +32,10 @@ ber_type_decoder_f TimeTicks_decode_ber; der_type_encoder_f TimeTicks_encode_der; xer_type_decoder_f TimeTicks_decode_xer; xer_type_encoder_f TimeTicks_encode_xer; +oer_type_decoder_f TimeTicks_decode_oer; +oer_type_encoder_f TimeTicks_encode_oer; +per_type_decoder_f TimeTicks_decode_uper; +per_type_encoder_f TimeTicks_encode_uper; #ifdef __cplusplus } diff --git a/libs/smux/include/stg/Trap-PDU.h b/libs/smux/include/stg/Trap-PDU.h index f4169aeb..9dbde794 100644 --- a/libs/smux/include/stg/Trap-PDU.h +++ b/libs/smux/include/stg/Trap-PDU.h @@ -1,8 +1,8 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1157-SNMP" * found in "RFC1157-SNMP.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #ifndef _Trap_PDU_H_ @@ -49,6 +49,8 @@ typedef struct Trap_PDU { /* Implementation */ extern asn_TYPE_descriptor_t asn_DEF_Trap_PDU; +extern asn_SEQUENCE_specifics_t asn_SPC_Trap_PDU_specs_1; +extern asn_TYPE_member_t asn_MBR_Trap_PDU_1[6]; #ifdef __cplusplus } diff --git a/libs/smux/include/stg/UdpEntry.h b/libs/smux/include/stg/UdpEntry.h index af9772d5..94581071 100644 --- a/libs/smux/include/stg/UdpEntry.h +++ b/libs/smux/include/stg/UdpEntry.h @@ -1,8 +1,8 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1213-MIB" * found in "RFC1213-MIB.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #ifndef _UdpEntry_H_ diff --git a/libs/smux/include/stg/VarBind.h b/libs/smux/include/stg/VarBind.h index 6291d640..988eebe3 100644 --- a/libs/smux/include/stg/VarBind.h +++ b/libs/smux/include/stg/VarBind.h @@ -1,8 +1,8 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1157-SNMP" * found in "RFC1157-SNMP.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #ifndef _VarBind_H_ @@ -31,6 +31,8 @@ typedef struct VarBind { /* Implementation */ extern asn_TYPE_descriptor_t asn_DEF_VarBind; +extern asn_SEQUENCE_specifics_t asn_SPC_VarBind_specs_1; +extern asn_TYPE_member_t asn_MBR_VarBind_1[2]; #ifdef __cplusplus } diff --git a/libs/smux/include/stg/VarBindList.h b/libs/smux/include/stg/VarBindList.h index b9061796..508354b3 100644 --- a/libs/smux/include/stg/VarBindList.h +++ b/libs/smux/include/stg/VarBindList.h @@ -1,8 +1,8 @@ /* - * Generated by asn1c-0.9.28 (http://lionet.info/asn1c) + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) * From ASN.1 module "RFC1157-SNMP" * found in "RFC1157-SNMP.asn1" - * `asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types` + * `asn1c -S /home/faust/software/asn1c/skeletons/ -fcompound-names -fwide-types` */ #ifndef _VarBindList_H_ @@ -32,6 +32,8 @@ typedef struct VarBindList { /* Implementation */ extern asn_TYPE_descriptor_t asn_DEF_VarBindList; +extern asn_SET_OF_specifics_t asn_SPC_VarBindList_specs_1; +extern asn_TYPE_member_t asn_MBR_VarBindList_1[1]; #ifdef __cplusplus } diff --git a/libs/smux/include/stg/asn_SEQUENCE_OF.h b/libs/smux/include/stg/asn_SEQUENCE_OF.h index e678f034..e35bc447 100644 --- a/libs/smux/include/stg/asn_SEQUENCE_OF.h +++ b/libs/smux/include/stg/asn_SEQUENCE_OF.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2003, 2004 Lev Walkin . All rights reserved. + * Copyright (c) 2003-2017 Lev Walkin . All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ #ifndef ASN_SEQUENCE_OF_H diff --git a/libs/smux/include/stg/asn_SET_OF.h b/libs/smux/include/stg/asn_SET_OF.h index 7edf14b5..882e1a47 100644 --- a/libs/smux/include/stg/asn_SET_OF.h +++ b/libs/smux/include/stg/asn_SET_OF.h @@ -1,21 +1,31 @@ /*- - * Copyright (c) 2003, 2004 Lev Walkin . All rights reserved. + * Copyright (c) 2003-2017 Lev Walkin . All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ #ifndef ASN_SET_OF_H #define ASN_SET_OF_H #ifdef __cplusplus -extern "C" { +#define A_SET_OF(type) \ + struct { \ + type **array; \ + int count; /* Meaningful size */ \ + int size; /* Allocated size */ \ + void (*free)(decltype(*array)); \ + } +#else /* C */ +#define A_SET_OF(type) \ + struct { \ + type **array; \ + int count; /* Meaningful size */ \ + int size; /* Allocated size */ \ + void (*free)(type *); \ + } #endif -#define A_SET_OF(type) \ - struct { \ - type **array; \ - int count; /* Meaningful size */ \ - int size; /* Allocated size */ \ - void (*free)(type *); \ - } +#ifdef __cplusplus +extern "C" { +#endif #define ASN_SET_ADD(headptr, ptr) \ asn_set_add((headptr), (ptr)) diff --git a/libs/smux/include/stg/asn_application.h b/libs/smux/include/stg/asn_application.h index 71e9ba61..3ca9f138 100644 --- a/libs/smux/include/stg/asn_application.h +++ b/libs/smux/include/stg/asn_application.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2004, 2006 Lev Walkin . All rights reserved. + * Copyright (c) 2004-2017 Lev Walkin . All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ /* @@ -15,6 +15,95 @@ extern "C" { #endif +/* + * A selection of ASN.1 Transfer Syntaxes to use with generalized + * encoders and decoders declared further in this .h file. + */ +enum asn_transfer_syntax { + /* Avoid appearance of a default transfer syntax. */ + ATS_INVALID = 0, + /* Plaintext output (not conforming to any standard), for debugging. */ + ATS_NONSTANDARD_PLAINTEXT, + /* Returns a randomly generatede structure. */ + ATS_RANDOM, + /* + * X.690: + * BER: Basic Encoding Rules. + * DER: Distinguished Encoding Rules. + * CER: Canonical Encoding Rules. + * DER and CER are more strict variants of BER. + */ + ATS_BER, + ATS_DER, + ATS_CER, /* Only decoding is supported */ + /* + * X.696: + * OER: Octet Encoding Rules. + * CANONICAL-OER is a more strict variant of BASIC-OER. + */ + ATS_BASIC_OER, + ATS_CANONICAL_OER, + /* + * X.691: + * PER: Packed Encoding Rules. + * CANONICAL-PER is a more strict variant of BASIC-PER. + * NOTE: Produces or consumes a complete encoding (X.691 (08/2015) #11.1). + */ + ATS_UNALIGNED_BASIC_PER, + ATS_UNALIGNED_CANONICAL_PER, + /* + * X.693: + * XER: XML Encoding Rules. + * CANONICAL-XER is a more strict variant of BASIC-XER. + */ + ATS_BASIC_XER, + ATS_CANONICAL_XER +}; + +/* + * A generic encoder for any supported transfer syntax. + * RETURN VALUES: + * The (.encoded) field of the return value is REDEFINED to mean the following: + * >=0: The computed size of the encoded data. Can exceed the (buffer_size). + * -1: Error encoding the structure. See the error code in (errno): + * EINVAL: Incorrect parameters to the function, such as NULLs. + * ENOENT: Encoding transfer syntax is not defined (for this type). + * EBADF: The structure has invalid form or content constraint failed. + * The (.failed_type) and (.structure_ptr) MIGHT be set to the appropriate + * values at the place of failure, if at all possible. + * WARNING: The (.encoded) field of the return value can exceed the buffer_size. + * This is similar to snprintf(3) contract which might return values + * greater than the buffer size. + */ +asn_enc_rval_t asn_encode_to_buffer( + const asn_codec_ctx_t *opt_codec_parameters, /* See asn_codecs.h */ + enum asn_transfer_syntax, + const struct asn_TYPE_descriptor_s *type_to_encode, + const void *structure_to_encode, void *buffer, size_t buffer_size); + +/* + * A variant of asn_encode_to_buffer() with automatically allocated buffer. + * RETURN VALUES: + * On success, returns a newly allocated (.buffer) containing the whole message. + * The message size is returned in (.result.encoded). + * On failure: + * (.buffer) is NULL, + * (.result.encoded) as in asn_encode_to_buffer(), + * The errno codes as in asn_encode_to_buffer(), plus the following: + * ENOMEM: Memory allocation failed due to system or internal limits. + * The user is responsible for freeing the (.buffer). + */ +typedef struct asn_encode_to_new_buffer_result_s { + void *buffer; /* NULL if failed to encode. */ + asn_enc_rval_t result; +} asn_encode_to_new_buffer_result_t; +asn_encode_to_new_buffer_result_t asn_encode_to_new_buffer( + const asn_codec_ctx_t *opt_codec_parameters, /* See asn_codecs.h */ + enum asn_transfer_syntax, + const struct asn_TYPE_descriptor_s *type_to_encode, + const void *structure_to_encode); + + /* * Generic type of an application-defined callback to return various * types of data to the application. @@ -22,8 +111,40 @@ extern "C" { * -1: Failed to consume bytes. Abort the mission. * Non-negative return values indicate success, and ignored. */ -typedef int (asn_app_consume_bytes_f)(const void *buffer, size_t size, - void *application_specific_key); +typedef int(asn_app_consume_bytes_f)(const void *buffer, size_t size, + void *application_specific_key); + + +/* + * A generic encoder for any supported transfer syntax. + * Returns the comprehensive encoding result descriptor (see asn_codecs.h). + * RETURN VALUES: + * The negative (.encoded) field of the return values is accompanied with the + * following error codes (errno): + * EINVAL: Incorrect parameters to the function, such as NULLs. + * ENOENT: Encoding transfer syntax is not defined (for this type). + * EBADF: The structure has invalid form or content constraint failed. + * EIO: The (callback) has returned negative value during encoding. + */ +asn_enc_rval_t asn_encode( + const asn_codec_ctx_t *opt_codec_parameters, /* See asn_codecs.h */ + enum asn_transfer_syntax, + const struct asn_TYPE_descriptor_s *type_to_encode, + const void *structure_to_encode, + asn_app_consume_bytes_f *callback, void *callback_key); + + +/* + * A generic decoder for any supported transfer syntax. + */ +asn_dec_rval_t asn_decode( + const asn_codec_ctx_t *opt_codec_parameters, enum asn_transfer_syntax, + const struct asn_TYPE_descriptor_s *type_to_decode, + void **structure_ptr, /* Pointer to a target structure's pointer */ + const void *buffer, /* Data to be decoded */ + size_t size /* Size of that buffer */ +); + /* * A callback of this type is called whenever constraint validation fails @@ -34,9 +155,10 @@ typedef int (asn_app_consume_bytes_f)(const void *buffer, size_t size, * particular constraint has failed. */ typedef void (asn_app_constraint_failed_f)(void *application_specific_key, - struct asn_TYPE_descriptor_s *type_descriptor_which_failed, + const struct asn_TYPE_descriptor_s *type_descriptor_which_failed, const void *structure_which_failed_ptr, - const char *error_message_format, ...) GCC_PRINTFLIKE(4, 5); + const char *error_message_format, ...) CC_PRINTFLIKE(4, 5); + #ifdef __cplusplus } diff --git a/libs/smux/include/stg/asn_bit_data.h b/libs/smux/include/stg/asn_bit_data.h new file mode 100644 index 00000000..59de7af5 --- /dev/null +++ b/libs/smux/include/stg/asn_bit_data.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2005-2017 Lev Walkin . All rights reserved. + * Redistribution and modifications are permitted subject to BSD license. + */ +#ifndef ASN_BIT_DATA +#define ASN_BIT_DATA + +#include /* Platform-specific types */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * This structure describes a position inside an incoming PER bit stream. + */ +typedef struct asn_bit_data_s { + const uint8_t *buffer; /* Pointer to the octet stream */ + size_t nboff; /* Bit offset to the meaningful bit */ + size_t nbits; /* Number of bits in the stream */ + size_t moved; /* Number of bits moved through this bit stream */ + int (*refill)(struct asn_bit_data_s *); + void *refill_key; +} asn_bit_data_t; + +/* + * Create a contiguous non-refillable bit data structure. + * Can be freed by FREEMEM(). + */ +asn_bit_data_t *asn_bit_data_new_contiguous(const void *data, size_t size_bits); + +/* + * Extract a small number of bits (<= 31) from the specified PER data pointer. + * This function returns -1 if the specified number of bits could not be + * extracted due to EOD or other conditions. + */ +int32_t asn_get_few_bits(asn_bit_data_t *, int get_nbits); + +/* Undo the immediately preceeding "get_few_bits" operation */ +void asn_get_undo(asn_bit_data_t *, int get_nbits); + +/* + * Extract a large number of bits from the specified PER data pointer. + * This function returns -1 if the specified number of bits could not be + * extracted due to EOD or other conditions. + */ +int asn_get_many_bits(asn_bit_data_t *, uint8_t *dst, int right_align, + int get_nbits); + +/* Non-thread-safe debugging function, don't use it */ +char *asn_bit_data_string(asn_bit_data_t *); + +/* + * This structure supports forming bit output. + */ +typedef struct asn_bit_outp_s { + uint8_t *buffer; /* Pointer into the (tmpspace) */ + size_t nboff; /* Bit offset to the meaningful bit */ + size_t nbits; /* Number of bits left in (tmpspace) */ + uint8_t tmpspace[32]; /* Preliminary storage to hold data */ + int (*output)(const void *data, size_t size, void *op_key); + void *op_key; /* Key for (output) data callback */ + size_t flushed_bytes; /* Bytes already flushed through (output) */ +} asn_bit_outp_t; + +/* Output a small number of bits (<= 31) */ +int asn_put_few_bits(asn_bit_outp_t *, uint32_t bits, int obits); + +/* Output a large number of bits */ +int asn_put_many_bits(asn_bit_outp_t *, const uint8_t *src, int put_nbits); + +/* + * Flush whole bytes (0 or more) through (outper) member. + * The least significant bits which are not used are guaranteed to be set to 0. + * Returns -1 if callback returns -1. Otherwise, 0. + */ +int asn_put_aligned_flush(asn_bit_outp_t *); + +#ifdef __cplusplus +} +#endif + +#endif /* ASN_BIT_DATA */ diff --git a/libs/smux/include/stg/asn_codecs.h b/libs/smux/include/stg/asn_codecs.h index 4b2a2942..e75c2709 100644 --- a/libs/smux/include/stg/asn_codecs.h +++ b/libs/smux/include/stg/asn_codecs.h @@ -1,6 +1,5 @@ -/*- - * Copyright (c) 2003, 2004, 2005 Lev Walkin . - * All rights reserved. +/* + * Copyright (c) 2003-2017 Lev Walkin . All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ #ifndef ASN_CODECS_H @@ -52,10 +51,10 @@ typedef struct asn_enc_rval_s { */ /* Type which cannot be encoded */ - struct asn_TYPE_descriptor_s *failed_type; + const struct asn_TYPE_descriptor_s *failed_type; /* Pointer to the structure of that type */ - void *structure_ptr; + const void *structure_ptr; } asn_enc_rval_t; #define ASN__ENCODE_FAILED do { \ asn_enc_rval_t tmp_error; \ diff --git a/libs/smux/include/stg/asn_codecs_prim.h b/libs/smux/include/stg/asn_codecs_prim.h index 0f683fdd..fbc55764 100644 --- a/libs/smux/include/stg/asn_codecs_prim.h +++ b/libs/smux/include/stg/asn_codecs_prim.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2004 Lev Walkin . All rights reserved. + * Copyright (c) 2004-2017 Lev Walkin . All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ #ifndef ASN_CODECS_PRIM_H @@ -12,8 +12,8 @@ extern "C" { #endif typedef struct ASN__PRIMITIVE_TYPE_s { - uint8_t *buf; /* Buffer with consecutive primitive encoding bytes */ - int size; /* Size of the buffer */ + uint8_t *buf; /* Buffer with consecutive primitive encoding bytes */ + size_t size; /* Size of the buffer */ } ASN__PRIMITIVE_TYPE_t; /* Do not use this type directly! */ asn_struct_free_f ASN__PRIMITIVE_TYPE_free; @@ -24,27 +24,25 @@ der_type_encoder_f der_encode_primitive; * A callback specification for the xer_decode_primitive() function below. */ enum xer_pbd_rval { - XPBD_SYSTEM_FAILURE, /* System failure (memory shortage, etc) */ - XPBD_DECODER_LIMIT, /* Hit some decoder limitation or deficiency */ - XPBD_BROKEN_ENCODING, /* Encoding of a primitive body is broken */ - XPBD_NOT_BODY_IGNORE, /* Not a body format, but safe to ignore */ - XPBD_BODY_CONSUMED /* Body is recognized and consumed */ + XPBD_SYSTEM_FAILURE, /* System failure (memory shortage, etc) */ + XPBD_DECODER_LIMIT, /* Hit some decoder limitation or deficiency */ + XPBD_BROKEN_ENCODING, /* Encoding of a primitive body is broken */ + XPBD_NOT_BODY_IGNORE, /* Not a body format, but safe to ignore */ + XPBD_BODY_CONSUMED /* Body is recognized and consumed */ }; -typedef enum xer_pbd_rval (xer_primitive_body_decoder_f) - (asn_TYPE_descriptor_t *td, void *struct_ptr, - const void *chunk_buf, size_t chunk_size); +typedef enum xer_pbd_rval(xer_primitive_body_decoder_f)( + const asn_TYPE_descriptor_t *td, void *struct_ptr, const void *chunk_buf, + size_t chunk_size); /* * Specific function to decode simple primitive types. * Also see xer_decode_general() in xer_decoder.h */ -asn_dec_rval_t xer_decode_primitive(asn_codec_ctx_t *opt_codec_ctx, - asn_TYPE_descriptor_t *type_descriptor, - void **struct_ptr, size_t struct_size, - const char *opt_mname, - const void *buf_ptr, size_t size, - xer_primitive_body_decoder_f *prim_body_decoder -); +asn_dec_rval_t xer_decode_primitive( + const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *type_descriptor, void **struct_ptr, + size_t struct_size, const char *opt_mname, const void *buf_ptr, size_t size, + xer_primitive_body_decoder_f *prim_body_decoder); #ifdef __cplusplus } diff --git a/libs/smux/include/stg/asn_internal.h b/libs/smux/include/stg/asn_internal.h index 9c94ca6c..4e72d62f 100644 --- a/libs/smux/include/stg/asn_internal.h +++ b/libs/smux/include/stg/asn_internal.h @@ -1,6 +1,5 @@ -/*- - * Copyright (c) 2003, 2004, 2005, 2007 Lev Walkin . - * All rights reserved. +/* + * Copyright (c) 2003-2017 Lev Walkin . All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ /* @@ -8,7 +7,9 @@ */ #ifndef ASN_INTERNAL_H #define ASN_INTERNAL_H - +#ifndef __EXTENSIONS__ +#define __EXTENSIONS__ /* for Sun */ +#endif #include "asn_application.h" /* Application-visible API */ #ifndef __NO_ASSERT_H__ /* Include assert.h only for internal use. */ @@ -31,13 +32,18 @@ int get_asn1c_environment_version(void); /* Run-time version */ #define asn_debug_indent 0 #define ASN_DEBUG_INDENT_ADD(i) do{}while(0) +#ifdef EMIT_ASN_DEBUG +#warning "Use ASN_EMIT_DEBUG instead of EMIT_ASN_DEBUG" +#define ASN_EMIT_DEBUG EMIT_ASN_DEBUG +#endif + /* * A macro for debugging the ASN.1 internals. * You may enable or override it. */ #ifndef ASN_DEBUG /* If debugging code is not defined elsewhere... */ -#if EMIT_ASN_DEBUG == 1 /* And it was asked to emit this code... */ -#ifdef __GNUC__ +#if ASN_EMIT_DEBUG == 1 /* And it was asked to emit this code... */ +#if __STDC_VERSION__ >= 199901L #ifdef ASN_THREAD_SAFE /* Thread safety requires sacrifice in output indentation: * Retain empty definition of ASN_DEBUG_INDENT_ADD. */ @@ -54,40 +60,58 @@ int asn_debug_indent; fprintf(stderr, " (%s:%d)\n", \ __FILE__, __LINE__); \ } while(0) -#else /* !__GNUC__ */ -void ASN_DEBUG_f(const char *fmt, ...); +#else /* !C99 */ +void CC_PRINTFLIKE(1, 2) ASN_DEBUG_f(const char *fmt, ...); #define ASN_DEBUG ASN_DEBUG_f -#endif /* __GNUC__ */ -#else /* EMIT_ASN_DEBUG != 1 */ -static void ASN_DEBUG(const char *fmt, ...) { (void)fmt; } -#endif /* EMIT_ASN_DEBUG */ +#endif /* C99 */ +#else /* ASN_EMIT_DEBUG != 1 */ +#if __STDC_VERSION__ >= 199901L +#define ASN_DEBUG(...) do{}while(0) +#else /* not C99 */ +static void CC_PRINTFLIKE(1, 2) ASN_DEBUG(const char *fmt, ...) { (void)fmt; } +#endif /* C99 or better */ +#endif /* ASN_EMIT_DEBUG */ #endif /* ASN_DEBUG */ +/* + * Print to a callback. + * The callback is expected to return negative values on error. + * 0 and positive values are treated as success. + * RETURN VALUES: + * -1: Failed to format or invoke the callback. + * >0: Size of the data that got delivered to the callback. + */ +ssize_t CC_PRINTFLIKE(3, 4) +asn__format_to_callback( + int (*callback)(const void *, size_t, void *key), void *key, + const char *fmt, ...); + /* * Invoke the application-supplied callback and fail, if something is wrong. */ -#define ASN__E_cbc(buf, size) (cb((buf), (size), app_key) < 0) -#define ASN__E_CALLBACK(foo) do { \ - if(foo) goto cb_failed; \ - } while(0) -#define ASN__CALLBACK(buf, size) \ - ASN__E_CALLBACK(ASN__E_cbc(buf, size)) -#define ASN__CALLBACK2(buf1, size1, buf2, size2) \ - ASN__E_CALLBACK(ASN__E_cbc(buf1, size1) || ASN__E_cbc(buf2, size2)) -#define ASN__CALLBACK3(buf1, size1, buf2, size2, buf3, size3) \ - ASN__E_CALLBACK(ASN__E_cbc(buf1, size1) \ - || ASN__E_cbc(buf2, size2) \ - || ASN__E_cbc(buf3, size3)) - -#define ASN__TEXT_INDENT(nl, level) do { \ - int tmp_level = (level); \ - int tmp_nl = ((nl) != 0); \ - int tmp_i; \ - if(tmp_nl) ASN__CALLBACK("\n", 1); \ - if(tmp_level < 0) tmp_level = 0; \ - for(tmp_i = 0; tmp_i < tmp_level; tmp_i++) \ - ASN__CALLBACK(" ", 4); \ - er.encoded += tmp_nl + 4 * tmp_level; \ +#define ASN__E_cbc(buf, size) (cb((buf), (size), app_key) < 0) +#define ASN__E_CALLBACK(size, foo) \ + do { \ + if(foo) goto cb_failed; \ + er.encoded += (size); \ + } while(0) +#define ASN__CALLBACK(buf, size) ASN__E_CALLBACK(size, ASN__E_cbc(buf, size)) +#define ASN__CALLBACK2(buf1, size1, buf2, size2) \ + ASN__E_CALLBACK((size1) + (size2), \ + ASN__E_cbc(buf1, size1) || ASN__E_cbc(buf2, size2)) +#define ASN__CALLBACK3(buf1, size1, buf2, size2, buf3, size3) \ + ASN__E_CALLBACK((size1) + (size2) + (size3), \ + ASN__E_cbc(buf1, size1) || ASN__E_cbc(buf2, size2) \ + || ASN__E_cbc(buf3, size3)) + +#define ASN__TEXT_INDENT(nl, level) \ + do { \ + int tmp_level = (level); \ + int tmp_nl = ((nl) != 0); \ + int tmp_i; \ + if(tmp_nl) ASN__CALLBACK("\n", 1); \ + if(tmp_level < 0) tmp_level = 0; \ + for(tmp_i = 0; tmp_i < tmp_level; tmp_i++) ASN__CALLBACK(" ", 4); \ } while(0) #define _i_INDENT(nl) do { \ @@ -103,12 +127,12 @@ static void ASN_DEBUG(const char *fmt, ...) { (void)fmt; } * Check stack against overflow, if limit is set. */ #define ASN__DEFAULT_STACK_MAX (30000) -static int __attribute__((unused)) -ASN__STACK_OVERFLOW_CHECK(asn_codec_ctx_t *ctx) { +static int CC_NOTUSED +ASN__STACK_OVERFLOW_CHECK(const asn_codec_ctx_t *ctx) { if(ctx && ctx->max_stack_size) { /* ctx MUST be allocated on the stack */ - ptrdiff_t usedstack = ((char *)ctx - (char *)&ctx); + ptrdiff_t usedstack = ((const char *)ctx - (const char *)&ctx); if(usedstack > 0) usedstack = -usedstack; /* grows up! */ /* double negative required to avoid int wrap-around */ diff --git a/libs/smux/include/stg/asn_ioc.h b/libs/smux/include/stg/asn_ioc.h new file mode 100644 index 00000000..d2fe3659 --- /dev/null +++ b/libs/smux/include/stg/asn_ioc.h @@ -0,0 +1,50 @@ +/* + * Run-time support for Information Object Classes. + * Copyright (c) 2017 Lev Walkin . All rights reserved. + * Redistribution and modifications are permitted subject to BSD license. + */ +#ifndef ASN_IOC_H +#define ASN_IOC_H + +#include /* Platform-specific types */ + +#ifdef __cplusplus +extern "C" { +#endif + +struct asn_TYPE_descriptor_s; +struct asn_ioc_cell_s; + +/* + * X.681, #13 + */ +typedef struct asn_ioc_set_s { + size_t rows_count; + size_t columns_count; + const struct asn_ioc_cell_s *rows; +} asn_ioc_set_t; + + +typedef struct asn_ioc_cell_s { + const char *field_name; /* Is equal to corresponding column_name */ + enum { + aioc__value, + aioc__type, + aioc__open_type, + } cell_kind; + struct asn_TYPE_descriptor_s *type_descriptor; + const void *value_sptr; + struct { + size_t types_count; + struct { + unsigned choice_position; + } *types; + } open_type; +} asn_ioc_cell_t; + + +#ifdef __cplusplus +} +#endif + +#endif /* ASN_IOC_H */ diff --git a/libs/smux/include/stg/asn_random_fill.h b/libs/smux/include/stg/asn_random_fill.h new file mode 100644 index 00000000..47f9b8af --- /dev/null +++ b/libs/smux/include/stg/asn_random_fill.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2017 Lev Walkin . All rights reserved. + * Redistribution and modifications are permitted subject to BSD license. + */ +#ifndef ASN_RANDOM_FILL +#define ASN_RANDOM_FILL + +/* Forward declarations */ +struct asn_TYPE_descriptor_s; +struct asn_encoding_constraints_s; + +/* + * Initialize a structure with random data according to the type specification + * and optional member constraints. + * ARGUMENTS: + * (max_length) - See (approx_max_length_limit). + * (memb_constraints) - Member constraints, if exist. + * The type can be constrained differently according + * to PER and OER specifications, so we find a value + * at the intersection of these constraints. + * In case the return differs from ARFILL_OK, the (struct_ptr) contents + * and (current_length) value remain in their original state. + */ +typedef struct asn_random_fill_result_s { + enum { + ARFILL_FAILED = -1, /* System error (memory?) */ + ARFILL_OK = 0, /* Initialization succeeded */ + ARFILL_SKIPPED = 1 /* Not done due to (length?) constraint */ + } code; + size_t length; /* Approximate number of bytes created. */ +} asn_random_fill_result_t; +typedef asn_random_fill_result_t(asn_random_fill_f)( + const struct asn_TYPE_descriptor_s *td, void **struct_ptr, + const struct asn_encoding_constraints_s *memb_constraints, + size_t max_length); + +/* + * Returns 0 if the structure was properly initialized, -1 otherwise. + * The (approx_max_length_limit) specifies the approximate limit of the + * resulting structure in units closely resembling bytes. The actual result + * might be several times larger or smaller than the length limit. + */ +int asn_random_fill(const struct asn_TYPE_descriptor_s *td, void **struct_ptr, + size_t approx_max_length_limit); + +/* + * Returns a random number between min and max. + */ +intmax_t asn_random_between(intmax_t min, intmax_t max); + +#endif /* ASN_RANDOM_FILL */ diff --git a/libs/smux/include/stg/asn_system.h b/libs/smux/include/stg/asn_system.h index d19837ed..fa8cf116 100644 --- a/libs/smux/include/stg/asn_system.h +++ b/libs/smux/include/stg/asn_system.h @@ -1,6 +1,5 @@ -/*- - * Copyright (c) 2003, 2004, 2007 Lev Walkin . - * All rights reserved. +/* + * Copyright (c) 2003-2017 Lev Walkin . All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ /* @@ -13,6 +12,10 @@ #include "config.h" #endif +#ifndef _DEFAULT_SOURCE +#define _DEFAULT_SOURCE 1 +#endif + #ifndef _BSD_SOURCE #define _BSD_SOURCE /* for snprintf() on some linux systems */ #endif @@ -25,10 +28,6 @@ #include /* For va_start */ #include /* for offsetof and ptrdiff_t */ -#ifdef HAVE_ALLOCA_H -#include /* For alloca(3) */ -#endif - #ifdef _WIN32 #include @@ -47,12 +46,16 @@ #endif #ifndef ASSUMESTDTYPES /* Standard types have been defined elsewhere */ #define ssize_t SSIZE_T +#if _MSC_VER < 1600 typedef char int8_t; typedef short int16_t; typedef int int32_t; typedef unsigned char uint8_t; typedef unsigned short uint16_t; typedef unsigned int uint32_t; +#else /* _MSC_VER >= 1600 */ +#include +#endif /* _MSC_VER < 1600 */ #endif /* ASSUMESTDTYPES */ #define WIN32_LEAN_AND_MEAN #include @@ -72,48 +75,21 @@ typedef unsigned int uint32_t; #else /* !defined(__vxworks) */ #include /* C99 specifies this file */ -/* - * 1. Earlier FreeBSD version didn't have , - * but was present. - * 2. Sun Solaris requires for alloca(3), - * but does not have . - */ -#if (!defined(__FreeBSD__) || !defined(_SYS_INTTYPES_H_)) -#if defined(sun) -#include /* For alloca(3) */ -#include /* for finite(3) */ -#elif defined(__hpux) -#ifdef __GNUC__ -#include /* For alloca(3) */ -#else /* !__GNUC__ */ -#define inline -#endif /* __GNUC__ */ -#else -#include /* SUSv2+ and C99 specify this file, for uintXX_t */ -#endif /* defined(sun) */ -#endif - #include /* for ntohl() */ #define sys_ntohl(foo) ntohl(foo) - #endif /* defined(__vxworks) */ #endif /* _WIN32 */ -#if __GNUC__ >= 3 -#ifndef GCC_PRINTFLIKE -#define GCC_PRINTFLIKE(fmt,var) __attribute__((format(printf,fmt,var))) -#endif -#ifndef GCC_NOTUSED -#define GCC_NOTUSED __attribute__((unused)) -#endif +#if __GNUC__ >= 3 || defined(__clang__) +#define CC_ATTRIBUTE(attr) __attribute__((attr)) #else -#ifndef GCC_PRINTFLIKE -#define GCC_PRINTFLIKE(fmt,var) /* nothing */ -#endif -#ifndef GCC_NOTUSED -#define GCC_NOTUSED +#define CC_ATTRIBUTE(attr) #endif +#define CC_PRINTFLIKE(fmt, var) CC_ATTRIBUTE(format(printf, fmt, var)) +#define CC_NOTUSED CC_ATTRIBUTE(unused) +#ifndef CC_ATTR_NO_SANITIZE +#define CC_ATTR_NO_SANITIZE(what) CC_ATTRIBUTE(no_sanitize(what)) #endif /* Figure out if thread safety is requested */ @@ -134,4 +110,41 @@ typedef unsigned int uint32_t; #endif /* __GNUC__ */ #endif /* MIN */ +#if __STDC_VERSION__ >= 199901L +#ifndef SIZE_MAX +#define SIZE_MAX ((~((size_t)0)) >> 1) +#endif + +#ifndef RSIZE_MAX /* C11, Annex K */ +#define RSIZE_MAX (SIZE_MAX >> 1) +#endif +#ifndef RSSIZE_MAX /* Halve signed size even further than unsigned */ +#define RSSIZE_MAX ((ssize_t)(RSIZE_MAX >> 1)) +#endif +#else /* Old compiler */ +#undef SIZE_MAX +#undef RSIZE_MAX +#undef RSSIZE_MAX +#define SIZE_MAX ((~((size_t)0)) >> 1) +#define RSIZE_MAX (SIZE_MAX >> 1) +#define RSSIZE_MAX ((ssize_t)(RSIZE_MAX >> 1)) +#endif + +#if __STDC_VERSION__ >= 199901L +#define ASN_PRI_SIZE "zu" +#define ASN_PRI_SSIZE "zd" +#define ASN_PRIuMAX PRIuMAX +#define ASN_PRIdMAX PRIdMAX +#else +#define ASN_PRI_SIZE "lu" +#define ASN_PRI_SSIZE "ld" +#if LLONG_MAX > LONG_MAX +#define ASN_PRIuMAX "llu" +#define ASN_PRIdMAX "lld" +#else +#define ASN_PRIuMAX "lu" +#define ASN_PRIdMAX "ld" +#endif +#endif + #endif /* ASN_SYSTEM_H */ diff --git a/libs/smux/include/stg/ber_decoder.h b/libs/smux/include/stg/ber_decoder.h index 9fe2e895..1ac2a5ef 100644 --- a/libs/smux/include/stg/ber_decoder.h +++ b/libs/smux/include/stg/ber_decoder.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2003, 2004 Lev Walkin . All rights reserved. + * Copyright (c) 2003-2017 Lev Walkin . All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ #ifndef _BER_DECODER_H_ @@ -17,23 +17,26 @@ struct asn_codec_ctx_s; /* Forward declaration */ /* * The BER decoder of any type. * This function may be invoked directly from the application. - * The der_encode() function (der_encoder.h) is an opposite to ber_decode(). + * Decodes BER, DER and CER data (DER and CER are different subsets of BER). + * + * NOTE: Use the der_encode() function (der_encoder.h) to produce encoding + * which is compliant with ber_decode(). */ -asn_dec_rval_t ber_decode(struct asn_codec_ctx_s *opt_codec_ctx, - struct asn_TYPE_descriptor_s *type_descriptor, - void **struct_ptr, /* Pointer to a target structure's pointer */ - const void *buffer, /* Data to be decoded */ - size_t size /* Size of that buffer */ - ); +asn_dec_rval_t ber_decode( + const struct asn_codec_ctx_s *opt_codec_ctx, + const struct asn_TYPE_descriptor_s *type_descriptor, + void **struct_ptr, /* Pointer to a target structure's pointer */ + const void *buffer, /* Data to be decoded */ + size_t size /* Size of that buffer */ +); /* * Type of generic function which decodes the byte stream into the structure. */ -typedef asn_dec_rval_t (ber_type_decoder_f)( - struct asn_codec_ctx_s *opt_codec_ctx, - struct asn_TYPE_descriptor_s *type_descriptor, - void **struct_ptr, const void *buf_ptr, size_t size, - int tag_mode); +typedef asn_dec_rval_t(ber_type_decoder_f)( + const struct asn_codec_ctx_s *opt_codec_ctx, + const struct asn_TYPE_descriptor_s *type_descriptor, void **struct_ptr, + const void *buf_ptr, size_t size, int tag_mode); /******************************* * INTERNALLY USEFUL FUNCTIONS * @@ -47,15 +50,14 @@ typedef asn_dec_rval_t (ber_type_decoder_f)( * head->last_tag_form is non-zero. */ asn_dec_rval_t ber_check_tags( - struct asn_codec_ctx_s *opt_codec_ctx, /* codec options */ - struct asn_TYPE_descriptor_s *type_descriptor, - asn_struct_ctx_t *opt_ctx, /* saved decoding context */ - const void *ptr, size_t size, - int tag_mode, /* {-1,0,1}: IMPLICIT, no, EXPLICIT */ - int last_tag_form, /* {-1,0:1}: any, primitive, constr */ - ber_tlv_len_t *last_length, - int *opt_tlv_form /* optional tag form */ - ); + const struct asn_codec_ctx_s *opt_codec_ctx, /* codec options */ + const struct asn_TYPE_descriptor_s *type_descriptor, + asn_struct_ctx_t *opt_ctx, /* saved decoding context */ + const void *ptr, size_t size, + int tag_mode, /* {-1,0,1}: IMPLICIT, no, EXPLICIT */ + int last_tag_form, /* {-1,0:1}: any, primitive, constr */ + ber_tlv_len_t *last_length, int *opt_tlv_form /* optional tag form */ +); #ifdef __cplusplus } diff --git a/libs/smux/include/stg/ber_tlv_length.h b/libs/smux/include/stg/ber_tlv_length.h index 34968022..d1e4d48d 100644 --- a/libs/smux/include/stg/ber_tlv_length.h +++ b/libs/smux/include/stg/ber_tlv_length.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2003 Lev Walkin . All rights reserved. + * Copyright (c) 2003-2017 Lev Walkin . All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ #ifndef _BER_TLV_LENGTH_H_ @@ -32,7 +32,7 @@ ssize_t ber_fetch_length(int _is_constructed, const void *bufptr, size_t size, * Standard {-1,0,>0} convention. */ ssize_t ber_skip_length( - struct asn_codec_ctx_s *opt_codec_ctx, /* optional context */ + const struct asn_codec_ctx_s *opt_codec_ctx, /* optional context */ int _is_constructed, const void *bufptr, size_t size); /* diff --git a/libs/smux/include/stg/ber_tlv_tag.h b/libs/smux/include/stg/ber_tlv_tag.h index 60e86686..ce227add 100644 --- a/libs/smux/include/stg/ber_tlv_tag.h +++ b/libs/smux/include/stg/ber_tlv_tag.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2003, 2004 Lev Walkin . All rights reserved. + * Copyright (c) 2003-2017 Lev Walkin . All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ #ifndef _BER_TLV_TAG_H_ diff --git a/libs/smux/include/stg/constr_CHOICE.h b/libs/smux/include/stg/constr_CHOICE.h index e824a220..76494809 100644 --- a/libs/smux/include/stg/constr_CHOICE.h +++ b/libs/smux/include/stg/constr_CHOICE.h @@ -1,6 +1,5 @@ -/*- - * Copyright (c) 2003, 2004, 2005 Lev Walkin . - * All rights reserved. +/* + * Copyright (c) 2003-2017 Lev Walkin . All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ #ifndef _CONSTR_CHOICE_H_ @@ -12,28 +11,29 @@ extern "C" { #endif -typedef const struct asn_CHOICE_specifics_s { +typedef struct asn_CHOICE_specifics_s { /* * Target structure description. */ - int struct_size; /* Size of the target structure. */ - int ctx_offset; /* Offset of the asn_codec_ctx_t member */ - int pres_offset; /* Identifier of the present member */ - int pres_size; /* Size of the identifier (enum) */ + unsigned struct_size; /* Size of the target structure. */ + unsigned ctx_offset; /* Offset of the asn_codec_ctx_t member */ + unsigned pres_offset; /* Identifier of the present member */ + unsigned pres_size; /* Size of the identifier (enum) */ /* * Tags to members mapping table. */ const asn_TYPE_tag2member_t *tag2el; - int tag2el_count; + unsigned tag2el_count; /* Canonical ordering of CHOICE elements, for PER */ - int *canonical_order; + const unsigned *to_canonical_order; + const unsigned *from_canonical_order; /* * Extensions-related stuff. */ - int ext_start; /* First member of extensions, or -1 */ + signed ext_start; /* First member of extensions, or -1 */ } asn_CHOICE_specifics_t; /* @@ -41,14 +41,35 @@ typedef const struct asn_CHOICE_specifics_s { */ asn_struct_free_f CHOICE_free; asn_struct_print_f CHOICE_print; +asn_struct_compare_f CHOICE_compare; asn_constr_check_f CHOICE_constraint; ber_type_decoder_f CHOICE_decode_ber; der_type_encoder_f CHOICE_encode_der; xer_type_decoder_f CHOICE_decode_xer; xer_type_encoder_f CHOICE_encode_xer; +oer_type_decoder_f CHOICE_decode_oer; +oer_type_encoder_f CHOICE_encode_oer; per_type_decoder_f CHOICE_decode_uper; per_type_encoder_f CHOICE_encode_uper; asn_outmost_tag_f CHOICE_outmost_tag; +asn_random_fill_f CHOICE_random_fill; +extern asn_TYPE_operation_t asn_OP_CHOICE; + +/* + * Return the 1-based choice variant presence index. + * Returns 0 in case of error. + */ +unsigned CHOICE_variant_get_presence(const asn_TYPE_descriptor_t *td, + const void *structure_ptr); + +/* + * Sets or resets the 1-based choice variant presence index. + * In case a previous index is not zero, the currently selected structure + * member is freed and zeroed-out first. + * Returns 0 on success and -1 on error. + */ +int CHOICE_variant_set_presence(const asn_TYPE_descriptor_t *td, + void *structure_ptr, unsigned present); #ifdef __cplusplus } diff --git a/libs/smux/include/stg/constr_SEQUENCE.h b/libs/smux/include/stg/constr_SEQUENCE.h index c2aeb667..f9dd4e5e 100644 --- a/libs/smux/include/stg/constr_SEQUENCE.h +++ b/libs/smux/include/stg/constr_SEQUENCE.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2003, 2004 Lev Walkin . All rights reserved. + * Copyright (c) 2003-2017 Lev Walkin . All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ #ifndef _CONSTR_SEQUENCE_H_ @@ -11,32 +11,33 @@ extern "C" { #endif -typedef const struct asn_SEQUENCE_specifics_s { +typedef struct asn_SEQUENCE_specifics_s { /* * Target structure description. */ - int struct_size; /* Size of the target structure. */ - int ctx_offset; /* Offset of the asn_struct_ctx_t member */ + unsigned struct_size; /* Size of the target structure. */ + unsigned ctx_offset; /* Offset of the asn_struct_ctx_t member */ /* * Tags to members mapping table (sorted). */ const asn_TYPE_tag2member_t *tag2el; - int tag2el_count; + unsigned tag2el_count; /* * Optional members of the extensions root (roms) or additions (aoms). * Meaningful for PER. */ - const int *oms; /* Optional MemberS */ - int roms_count; /* Root optional members count */ - int aoms_count; /* Additions optional members count */ + const int *oms; /* Optional MemberS */ + unsigned roms_count; /* Root optional members count */ + unsigned aoms_count; /* Additions optional members count */ /* * Description of an extensions group. + * Root components are clustered at the beginning of the structure, + * whereas extensions are clustered at the end. -1 means not extensible. */ - int ext_after; /* Extensions start after this member */ - int ext_before; /* Extensions stop before this member */ + signed first_extension; /* First extension addition */ } asn_SEQUENCE_specifics_t; @@ -45,13 +46,18 @@ typedef const struct asn_SEQUENCE_specifics_s { */ asn_struct_free_f SEQUENCE_free; asn_struct_print_f SEQUENCE_print; +asn_struct_compare_f SEQUENCE_compare; asn_constr_check_f SEQUENCE_constraint; ber_type_decoder_f SEQUENCE_decode_ber; der_type_encoder_f SEQUENCE_encode_der; xer_type_decoder_f SEQUENCE_decode_xer; xer_type_encoder_f SEQUENCE_encode_xer; +oer_type_decoder_f SEQUENCE_decode_oer; +oer_type_encoder_f SEQUENCE_encode_oer; per_type_decoder_f SEQUENCE_decode_uper; per_type_encoder_f SEQUENCE_encode_uper; +asn_random_fill_f SEQUENCE_random_fill; +extern asn_TYPE_operation_t asn_OP_SEQUENCE; #ifdef __cplusplus } diff --git a/libs/smux/include/stg/constr_SEQUENCE_OF.h b/libs/smux/include/stg/constr_SEQUENCE_OF.h index e2272f32..f21b91e1 100644 --- a/libs/smux/include/stg/constr_SEQUENCE_OF.h +++ b/libs/smux/include/stg/constr_SEQUENCE_OF.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2003, 2005 Lev Walkin . All rights reserved. + * Copyright (c) 2003-2017 Lev Walkin . All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ #ifndef _CONSTR_SEQUENCE_OF_H_ @@ -16,15 +16,21 @@ extern "C" { * A set specialized functions dealing with the SEQUENCE OF type. * Generally implemented using SET OF. */ +asn_struct_compare_f SEQUENCE_OF_compare; +der_type_encoder_f SEQUENCE_OF_encode_der; +xer_type_encoder_f SEQUENCE_OF_encode_xer; +per_type_encoder_f SEQUENCE_OF_encode_uper; +extern asn_TYPE_operation_t asn_OP_SEQUENCE_OF; + #define SEQUENCE_OF_free SET_OF_free #define SEQUENCE_OF_print SET_OF_print #define SEQUENCE_OF_constraint SET_OF_constraint #define SEQUENCE_OF_decode_ber SET_OF_decode_ber #define SEQUENCE_OF_decode_xer SET_OF_decode_xer #define SEQUENCE_OF_decode_uper SET_OF_decode_uper -der_type_encoder_f SEQUENCE_OF_encode_der; -xer_type_encoder_f SEQUENCE_OF_encode_xer; -per_type_encoder_f SEQUENCE_OF_encode_uper; +#define SEQUENCE_OF_decode_oer SET_OF_decode_oer +#define SEQUENCE_OF_encode_oer SET_OF_encode_oer +#define SEQUENCE_OF_random_fill SET_OF_random_fill #ifdef __cplusplus } diff --git a/libs/smux/include/stg/constr_SET_OF.h b/libs/smux/include/stg/constr_SET_OF.h index 75e18cfa..f32e607b 100644 --- a/libs/smux/include/stg/constr_SET_OF.h +++ b/libs/smux/include/stg/constr_SET_OF.h @@ -1,9 +1,9 @@ /*- - * Copyright (c) 2003 Lev Walkin . All rights reserved. + * Copyright (c) 2003-2017 Lev Walkin . All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ -#ifndef _CONSTR_SET_OF_H_ -#define _CONSTR_SET_OF_H_ +#ifndef CONSTR_SET_OF_H +#define CONSTR_SET_OF_H #include @@ -11,15 +11,15 @@ extern "C" { #endif -typedef const struct asn_SET_OF_specifics_s { - /* - * Target structure description. - */ - int struct_size; /* Size of the target structure. */ - int ctx_offset; /* Offset of the asn_struct_ctx_t member */ +typedef struct asn_SET_OF_specifics_s { + /* + * Target structure description. + */ + unsigned struct_size; /* Size of the target structure. */ + unsigned ctx_offset; /* Offset of the asn_struct_ctx_t member */ - /* XER-specific stuff */ - int as_XMLValueList; /* The member type must be encoded like this */ + /* XER-specific stuff */ + int as_XMLValueList; /* The member type must be encoded like this */ } asn_SET_OF_specifics_t; /* @@ -27,16 +27,21 @@ typedef const struct asn_SET_OF_specifics_s { */ asn_struct_free_f SET_OF_free; asn_struct_print_f SET_OF_print; +asn_struct_compare_f SET_OF_compare; asn_constr_check_f SET_OF_constraint; ber_type_decoder_f SET_OF_decode_ber; der_type_encoder_f SET_OF_encode_der; xer_type_decoder_f SET_OF_decode_xer; xer_type_encoder_f SET_OF_encode_xer; +oer_type_decoder_f SET_OF_decode_oer; +oer_type_encoder_f SET_OF_encode_oer; per_type_decoder_f SET_OF_decode_uper; per_type_encoder_f SET_OF_encode_uper; +asn_random_fill_f SET_OF_random_fill; +extern asn_TYPE_operation_t asn_OP_SET_OF; #ifdef __cplusplus } #endif -#endif /* _CONSTR_SET_OF_H_ */ +#endif /* CONSTR_SET_OF_H */ diff --git a/libs/smux/include/stg/constr_TYPE.h b/libs/smux/include/stg/constr_TYPE.h index a9cd86dc..10bb0f36 100644 --- a/libs/smux/include/stg/constr_TYPE.h +++ b/libs/smux/include/stg/constr_TYPE.h @@ -1,6 +1,5 @@ -/*- - * Copyright (c) 2003, 2004, 2005, 2006 Lev Walkin . - * All rights reserved. +/* + * Copyright (c) 2003-2017 Lev Walkin . All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ /* @@ -42,29 +41,77 @@ typedef struct asn_struct_ctx_s { #include /* Packet Encoding Rules decoder */ #include /* Packet Encoding Rules encoder */ #include /* Subtype constraints support */ +#include /* Random structures support */ + +#ifdef ASN_DISABLE_OER_SUPPORT +typedef void (oer_type_decoder_f)(void); +typedef void (oer_type_encoder_f)(void); +typedef void asn_oer_constraints_t; +#else +#include /* Octet Encoding Rules encoder */ +#include /* Octet Encoding Rules encoder */ +#endif /* * Free the structure according to its specification. - * If (free_contents_only) is set, the wrapper structure itself (struct_ptr) - * will not be freed. (It may be useful in case the structure is allocated - * statically or arranged on the stack, yet its elements are allocated - * dynamically.) + * Use one of ASN_STRUCT_{FREE,RESET,CONTENTS_ONLY} macros instead. + * Do not use directly. */ +enum asn_struct_free_method { + ASFM_FREE_EVERYTHING, /* free(struct_ptr) and underlying members */ + ASFM_FREE_UNDERLYING, /* free underlying members */ + ASFM_FREE_UNDERLYING_AND_RESET /* FREE_UNDERLYING + memset(0) */ +}; typedef void (asn_struct_free_f)( - struct asn_TYPE_descriptor_s *type_descriptor, - void *struct_ptr, int free_contents_only); -#define ASN_STRUCT_FREE(asn_DEF, ptr) (asn_DEF).free_struct(&(asn_DEF),ptr,0) -#define ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF, ptr) \ - (asn_DEF).free_struct(&(asn_DEF),ptr,1) + const struct asn_TYPE_descriptor_s *type_descriptor, + void *struct_ptr, enum asn_struct_free_method); + +/* + * Free the structure including freeing the memory pointed to by ptr itself. + */ +#define ASN_STRUCT_FREE(asn_DEF, ptr) \ + (asn_DEF).op->free_struct(&(asn_DEF), (ptr), ASFM_FREE_EVERYTHING) + +/* + * Free the memory used by the members of the structure without freeing the + * the structure pointer itself. + * ZERO-OUT the structure to the safe clean state. + * (Retaining the pointer may be useful in case the structure is allocated + * statically or arranged on the stack, yet its elements are dynamic.) + */ +#define ASN_STRUCT_RESET(asn_DEF, ptr) \ + (asn_DEF).op->free_struct(&(asn_DEF), (ptr), ASFM_FREE_UNDERLYING_AND_RESET) + +/* + * Free memory used by the members of the structure without freeing + * the structure pointer itself. + * (Retaining the pointer may be useful in case the structure is allocated + * statically or arranged on the stack, yet its elements are dynamic.) + * AVOID using it in the application code; + * Use a safer ASN_STRUCT_RESET() instead. + */ +#define ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF, ptr) \ + (asn_DEF).op->free_struct(&(asn_DEF), (ptr), ASFM_FREE_UNDERLYING) /* * Print the structure according to its specification. */ -typedef int (asn_struct_print_f)( - struct asn_TYPE_descriptor_s *type_descriptor, - const void *struct_ptr, - int level, /* Indentation level */ - asn_app_consume_bytes_f *callback, void *app_key); +typedef int(asn_struct_print_f)( + const struct asn_TYPE_descriptor_s *type_descriptor, + const void *struct_ptr, + int level, /* Indentation level */ + asn_app_consume_bytes_f *callback, void *app_key); + +/* + * Compare two structs between each other. + * Returns <0 if struct_A is "smaller" than struct_B, >0 if "greater", + * and =0 if "equal to", for some type-specific, stable definition of + * "smaller", "greater" and "equal to". + */ +typedef int (asn_struct_compare_f)( + const struct asn_TYPE_descriptor_s *type_descriptor, + const void *struct_A, + const void *struct_B); /* * Return the outmost tag of the type. @@ -78,54 +125,86 @@ typedef ber_tlv_tag_t (asn_outmost_tag_f)( /* The instance of the above function type; used internally. */ asn_outmost_tag_f asn_TYPE_outmost_tag; - +/* + * Fetch the desired type of the Open Type based on the + * Information Object Set driven constraints. + */ +typedef struct asn_type_selector_result_s { + const struct asn_TYPE_descriptor_s *type_descriptor; /* Type encoded. */ + unsigned presence_index; /* Associated choice variant. */ +} asn_type_selector_result_t; +typedef asn_type_selector_result_t(asn_type_selector_f)( + const struct asn_TYPE_descriptor_s *parent_type_descriptor, + const void *parent_structure_ptr); + +/* + * Generalized functions for dealing with the speciic type. + * May be directly invoked by applications. + */ +typedef struct asn_TYPE_operation_s { + asn_struct_free_f *free_struct; /* Free the structure */ + asn_struct_print_f *print_struct; /* Human readable output */ + asn_struct_compare_f *compare_struct; /* Compare two structures */ + ber_type_decoder_f *ber_decoder; /* Generic BER decoder */ + der_type_encoder_f *der_encoder; /* Canonical DER encoder */ + xer_type_decoder_f *xer_decoder; /* Generic XER decoder */ + xer_type_encoder_f *xer_encoder; /* [Canonical] XER encoder */ + oer_type_decoder_f *oer_decoder; /* Generic OER decoder */ + oer_type_encoder_f *oer_encoder; /* Canonical OER encoder */ + per_type_decoder_f *uper_decoder; /* Unaligned PER decoder */ + per_type_encoder_f *uper_encoder; /* Unaligned PER encoder */ + asn_random_fill_f *random_fill; /* Initialize with a random value */ + asn_outmost_tag_f *outmost_tag; /* */ +} asn_TYPE_operation_t; + +/* + * A constraints tuple specifying both the OER and PER constraints. + */ +typedef struct asn_encoding_constraints_s { + const struct asn_oer_constraints_s *oer_constraints; + const struct asn_per_constraints_s *per_constraints; + asn_constr_check_f *general_constraints; +} asn_encoding_constraints_t; + /* * The definitive description of the destination language's structure. */ typedef struct asn_TYPE_descriptor_s { - const char *name; /* A name of the ASN.1 type. "" in some cases. */ - const char *xml_tag; /* Name used in XML tag */ - - /* - * Generalized functions for dealing with the specific type. - * May be directly invoked by applications. - */ - asn_struct_free_f *free_struct; /* Free the structure */ - asn_struct_print_f *print_struct; /* Human readable output */ - asn_constr_check_f *check_constraints; /* Constraints validator */ - ber_type_decoder_f *ber_decoder; /* Generic BER decoder */ - der_type_encoder_f *der_encoder; /* Canonical DER encoder */ - xer_type_decoder_f *xer_decoder; /* Generic XER decoder */ - xer_type_encoder_f *xer_encoder; /* [Canonical] XER encoder */ - per_type_decoder_f *uper_decoder; /* Unaligned PER decoder */ - per_type_encoder_f *uper_encoder; /* Unaligned PER encoder */ - - /*********************************************************************** - * Internally useful members. Not to be used by applications directly. * - **********************************************************************/ - - /* - * Tags that are expected to occur. - */ - asn_outmost_tag_f *outmost_tag; /* */ - const ber_tlv_tag_t *tags; /* Effective tags sequence for this type */ - int tags_count; /* Number of tags which are expected */ - const ber_tlv_tag_t *all_tags; /* Every tag for BER/containment */ - int all_tags_count; /* Number of tags */ - - asn_per_constraints_t *per_constraints; /* PER compiled constraints */ - - /* - * An ASN.1 production type members (members of SEQUENCE, SET, CHOICE). - */ - struct asn_TYPE_member_s *elements; - int elements_count; - - /* - * Additional information describing the type, used by appropriate - * functions above. - */ - const void *specifics; + const char *name; /* A name of the ASN.1 type. "" in some cases. */ + const char *xml_tag; /* Name used in XML tag */ + + /* + * Generalized functions for dealing with the specific type. + * May be directly invoked by applications. + */ + asn_TYPE_operation_t *op; + + /*********************************************************************** + * Internally useful members. Not to be used by applications directly. * + **********************************************************************/ + + /* + * Tags that are expected to occur. + */ + const ber_tlv_tag_t *tags; /* Effective tags sequence for this type */ + unsigned tags_count; /* Number of tags which are expected */ + const ber_tlv_tag_t *all_tags; /* Every tag for BER/containment */ + unsigned all_tags_count; /* Number of tags */ + + /* OER, PER, and general constraints */ + asn_encoding_constraints_t encoding_constraints; + + /* + * An ASN.1 production type members (members of SEQUENCE, SET, CHOICE). + */ + struct asn_TYPE_member_s *elements; + unsigned elements_count; + + /* + * Additional information describing the type, used by appropriate + * functions above. + */ + const void *specifics; } asn_TYPE_descriptor_t; /* @@ -133,45 +212,46 @@ typedef struct asn_TYPE_descriptor_s { * i.e. SEQUENCE, SET, CHOICE, etc. */ enum asn_TYPE_flags_e { - ATF_NOFLAGS, - ATF_POINTER = 0x01, /* Represented by the pointer */ - ATF_OPEN_TYPE = 0x02 /* ANY type, without meaningful tag */ + ATF_NOFLAGS, + ATF_POINTER = 0x01, /* Represented by the pointer */ + ATF_OPEN_TYPE = 0x02, /* Open Type */ + ATF_ANY_TYPE = 0x04 /* ANY type (deprecated!) */ }; typedef struct asn_TYPE_member_s { - enum asn_TYPE_flags_e flags; /* Element's presentation flags */ - int optional; /* Following optional members, including current */ - int memb_offset; /* Offset of the element */ - ber_tlv_tag_t tag; /* Outmost (most immediate) tag */ - int tag_mode; /* IMPLICIT/no/EXPLICIT tag at current level */ - asn_TYPE_descriptor_t *type; /* Member type descriptor */ - asn_constr_check_f *memb_constraints; /* Constraints validator */ - asn_per_constraints_t *per_constraints; /* PER compiled constraints */ - int (*default_value)(int setval, void **sptr); /* DEFAULT */ - const char *name; /* ASN.1 identifier of the element */ + enum asn_TYPE_flags_e flags; /* Element's presentation flags */ + unsigned optional; /* Following optional members, including current */ + unsigned memb_offset; /* Offset of the element */ + ber_tlv_tag_t tag; /* Outmost (most immediate) tag */ + int tag_mode; /* IMPLICIT/no/EXPLICIT tag at current level */ + asn_TYPE_descriptor_t *type; /* Member type descriptor */ + asn_type_selector_f *type_selector; /* IoS runtime type selector */ + asn_encoding_constraints_t encoding_constraints; + int (*default_value_cmp)(const void *sptr); /* Compare DEFAULT */ + int (*default_value_set)(void **sptr); /* Set DEFAULT */ + const char *name; /* ASN.1 identifier of the element */ } asn_TYPE_member_t; /* * BER tag to element number mapping. */ typedef struct asn_TYPE_tag2member_s { - ber_tlv_tag_t el_tag; /* Outmost tag of the member */ - int el_no; /* Index of the associated member, base 0 */ - int toff_first; /* First occurence of the el_tag, relative */ - int toff_last; /* Last occurence of the el_tag, relatvie */ + ber_tlv_tag_t el_tag; /* Outmost tag of the member */ + unsigned el_no; /* Index of the associated member, base 0 */ + int toff_first; /* First occurence of the el_tag, relative */ + int toff_last; /* Last occurence of the el_tag, relative */ } asn_TYPE_tag2member_t; /* - * This function is a wrapper around (td)->print_struct, which prints out - * the contents of the target language's structure (struct_ptr) into the - * file pointer (stream) in human readable form. + * This function prints out the contents of the target language's structure + * (struct_ptr) into the file pointer (stream) in human readable form. * RETURN VALUES: * 0: The structure is printed. * -1: Problem dumping the structure. * (See also xer_fprint() in xer_encoder.h) */ -int asn_fprint(FILE *stream, /* Destination stream descriptor */ - asn_TYPE_descriptor_t *td, /* ASN.1 type descriptor */ - const void *struct_ptr); /* Structure to be printed */ +int asn_fprint(FILE *stream, /* Destination stream descriptor */ + const asn_TYPE_descriptor_t *td, /* ASN.1 type descriptor */ + const void *struct_ptr); /* Structure to be printed */ #ifdef __cplusplus } diff --git a/libs/smux/include/stg/constraints.h b/libs/smux/include/stg/constraints.h index 48d49e24..0bd86a96 100644 --- a/libs/smux/include/stg/constraints.h +++ b/libs/smux/include/stg/constraints.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2004, 2006 Lev Walkin . All rights reserved. + * Copyright (c) 2004-2017 Lev Walkin . All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ #ifndef ASN1_CONSTRAINTS_VALIDATOR_H @@ -25,24 +25,23 @@ struct asn_TYPE_descriptor_s; /* Forward declaration */ * This function returns 0 in case all ASN.1 constraints are met * and -1 if one or more constraints were failed. */ -int -asn_check_constraints(struct asn_TYPE_descriptor_s *type_descriptor, - const void *struct_ptr, /* Target language's structure */ - char *errbuf, /* Returned error description */ - size_t *errlen /* Length of the error description */ - ); +int asn_check_constraints( + const struct asn_TYPE_descriptor_s *type_descriptor, + const void *struct_ptr, /* Target language's structure */ + char *errbuf, /* Returned error description */ + size_t *errlen /* Length of the error description */ +); /* * Generic type for constraint checking callback, * associated with every type descriptor. */ -typedef int (asn_constr_check_f)( - struct asn_TYPE_descriptor_s *type_descriptor, - const void *struct_ptr, - asn_app_constraint_failed_f *optional_callback, /* Log the error */ - void *optional_app_key /* Opaque key passed to a callback */ - ); +typedef int(asn_constr_check_f)( + const struct asn_TYPE_descriptor_s *type_descriptor, const void *struct_ptr, + asn_app_constraint_failed_f *optional_callback, /* Log the error */ + void *optional_app_key /* Opaque key passed to a callback */ +); /******************************* * INTERNALLY USEFUL FUNCTIONS * diff --git a/libs/smux/include/stg/der_encoder.h b/libs/smux/include/stg/der_encoder.h index 61431c6d..e93944ed 100644 --- a/libs/smux/include/stg/der_encoder.h +++ b/libs/smux/include/stg/der_encoder.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2003, 2004 Lev Walkin . All rights reserved. + * Copyright (c) 2003-2017 Lev Walkin . All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ #ifndef _DER_ENCODER_H_ @@ -15,33 +15,35 @@ struct asn_TYPE_descriptor_s; /* Forward declaration */ /* * The DER encoder of any type. May be invoked by the application. - * The ber_decode() function (ber_decoder.h) is an opposite of der_encode(). + * Produces DER- and BER-compliant encoding. (DER is a subset of BER). + * + * NOTE: Use the ber_decode() function (ber_decoder.h) to decode data + * produced by der_encode(). */ -asn_enc_rval_t der_encode(struct asn_TYPE_descriptor_s *type_descriptor, - void *struct_ptr, /* Structure to be encoded */ - asn_app_consume_bytes_f *consume_bytes_cb, - void *app_key /* Arbitrary callback argument */ - ); +asn_enc_rval_t der_encode(const struct asn_TYPE_descriptor_s *type_descriptor, + const void *struct_ptr, /* Structure to be encoded */ + asn_app_consume_bytes_f *consume_bytes_cb, + void *app_key /* Arbitrary callback argument */ +); /* A variant of der_encode() which encodes data into the pre-allocated buffer */ asn_enc_rval_t der_encode_to_buffer( - struct asn_TYPE_descriptor_s *type_descriptor, - void *struct_ptr, /* Structure to be encoded */ - void *buffer, /* Pre-allocated buffer */ - size_t buffer_size /* Initial buffer size (maximum) */ - ); + const struct asn_TYPE_descriptor_s *type_descriptor, + const void *struct_ptr, /* Structure to be encoded */ + void *buffer, /* Pre-allocated buffer */ + size_t buffer_size /* Initial buffer size (maximum) */ +); /* * Type of the generic DER encoder. */ -typedef asn_enc_rval_t (der_type_encoder_f)( - struct asn_TYPE_descriptor_s *type_descriptor, - void *struct_ptr, /* Structure to be encoded */ - int tag_mode, /* {-1,0,1}: IMPLICIT, no, EXPLICIT */ - ber_tlv_tag_t tag, - asn_app_consume_bytes_f *consume_bytes_cb, /* Callback */ - void *app_key /* Arbitrary callback argument */ - ); +typedef asn_enc_rval_t(der_type_encoder_f)( + const struct asn_TYPE_descriptor_s *type_descriptor, + const void *struct_ptr, /* Structure to be encoded */ + int tag_mode, /* {-1,0,1}: IMPLICIT, no, EXPLICIT */ + ber_tlv_tag_t tag, asn_app_consume_bytes_f *consume_bytes_cb, /* Callback */ + void *app_key /* Arbitrary callback argument */ +); /******************************* @@ -51,15 +53,13 @@ typedef asn_enc_rval_t (der_type_encoder_f)( /* * Write out leading TL[v] sequence according to the type definition. */ -ssize_t der_write_tags( - struct asn_TYPE_descriptor_s *type_descriptor, - size_t struct_length, - int tag_mode, /* {-1,0,1}: IMPLICIT, no, EXPLICIT */ - int last_tag_form, /* {0,!0}: prim, constructed */ - ber_tlv_tag_t tag, - asn_app_consume_bytes_f *consume_bytes_cb, - void *app_key - ); +ssize_t der_write_tags(const struct asn_TYPE_descriptor_s *type_descriptor, + size_t struct_length, + int tag_mode, /* {-1,0,1}: IMPLICIT, no, EXPLICIT */ + int last_tag_form, /* {0,!0}: prim, constructed */ + ber_tlv_tag_t tag, + asn_app_consume_bytes_f *consume_bytes_cb, + void *app_key); #ifdef __cplusplus } diff --git a/libs/smux/include/stg/oer_decoder.h b/libs/smux/include/stg/oer_decoder.h new file mode 100644 index 00000000..40992e94 --- /dev/null +++ b/libs/smux/include/stg/oer_decoder.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2017 Lev Walkin . All rights reserved. + * Redistribution and modifications are permitted subject to BSD license. + */ +#ifndef OER_DECODER_H +#define OER_DECODER_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct asn_TYPE_descriptor_s; /* Forward declaration */ +struct asn_codec_ctx_s; /* Forward declaration */ + +/* + * The Octet Encoding Rules (OER, X.696 08/2015) decoder for any given type. + * This function may be invoked directly by the application. + * Parses CANONICAL-OER and BASIC-OER. + */ +asn_dec_rval_t oer_decode(const struct asn_codec_ctx_s *opt_codec_ctx, + const struct asn_TYPE_descriptor_s *type_descriptor, + void **struct_ptr, /* Pointer to a target structure's pointer */ + const void *buffer, /* Data to be decoded */ + size_t size /* Size of that buffer */ + ); + +/* + * Type of generic function which decodes the byte stream into the structure. + */ +typedef asn_dec_rval_t(oer_type_decoder_f)( + const struct asn_codec_ctx_s *opt_codec_ctx, + const struct asn_TYPE_descriptor_s *type_descriptor, + const asn_oer_constraints_t *constraints, + void **struct_ptr, + const void *buf_ptr, + size_t size); + +/* + * Swallow the Open Type (X.696 (08/2015), #30) into /dev/null. + * RETURN VALUES: + * -1: Fatal error deciphering length. + * 0: More data expected than bufptr contains. + * >0: Number of bytes used from bufptr. + */ +ssize_t oer_open_type_skip(const void *bufptr, size_t size); + +/* + * Read the Open Type (X.696 (08/2015), #30). + * RETURN VALUES: + * 0: More data expected than bufptr contains. + * -1: Fatal error deciphering length. + * >0: Number of bytes used from bufptr. + */ +ssize_t oer_open_type_get(const asn_codec_ctx_t *opt_codec_ctx, + const struct asn_TYPE_descriptor_s *td, + const asn_oer_constraints_t *constraints, + void **struct_ptr, const void *bufptr, size_t size); + +/* + * Length-prefixed buffer decoding for primitive types. + */ +oer_type_decoder_f oer_decode_primitive; + + +#ifdef __cplusplus +} +#endif + +#endif /* OER_DECODER_H */ diff --git a/libs/smux/include/stg/oer_encoder.h b/libs/smux/include/stg/oer_encoder.h new file mode 100644 index 00000000..6a7b6812 --- /dev/null +++ b/libs/smux/include/stg/oer_encoder.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2017 Lev Walkin . All rights reserved. + * Redistribution and modifications are permitted subject to BSD license. + */ +#ifndef OER_ENCODER_H +#define OER_ENCODER_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct asn_TYPE_descriptor_s; /* Forward declaration */ + +/* + * The Octet Encoding Rules (OER, X.696 08/2015) encoder for any type. + * This function may be invoked directly by the application. + * Produces CANONICAL-OER output compatible with CANONICAL-OER + * and BASIC-OER decoders. + */ +asn_enc_rval_t oer_encode(const struct asn_TYPE_descriptor_s *type_descriptor, + const void *struct_ptr, /* Structure to be encoded */ + asn_app_consume_bytes_f *consume_bytes_cb, + void *app_key /* Arbitrary callback argument */ +); + +/* A variant of oer_encode() which encodes data into the pre-allocated buffer */ +asn_enc_rval_t oer_encode_to_buffer( + const struct asn_TYPE_descriptor_s *type_descriptor, + const asn_oer_constraints_t *constraints, + const void *struct_ptr, /* Structure to be encoded */ + void *buffer, /* Pre-allocated buffer */ + size_t buffer_size /* Initial buffer size (maximum) */ +); + +/* + * Type of the generic OER encoder. + */ +typedef asn_enc_rval_t(oer_type_encoder_f)( + const struct asn_TYPE_descriptor_s *type_descriptor, + const asn_oer_constraints_t *constraints, + const void *struct_ptr, /* Structure to be encoded */ + asn_app_consume_bytes_f *consume_bytes_cb, /* Callback */ + void *app_key /* Arbitrary callback argument */ +); + +/* + * Write out the Open Type (X.696 (08/2015), #30). + * RETURN VALUES: + * -1: Fatal error encoding the type. + * >0: Number of bytes serialized. + */ +ssize_t oer_open_type_put(const struct asn_TYPE_descriptor_s *td, + const asn_oer_constraints_t *constraints, + const void *struct_ptr, + asn_app_consume_bytes_f *consume_bytes_cb, + void *app_key); + + +/* + * Length-prefixed buffer encoding for primitive types. + */ +oer_type_encoder_f oer_encode_primitive; + +#ifdef __cplusplus +} +#endif + +#endif /* OER_ENCODER_H */ diff --git a/libs/smux/include/stg/oer_support.h b/libs/smux/include/stg/oer_support.h new file mode 100644 index 00000000..dbc9b5fc --- /dev/null +++ b/libs/smux/include/stg/oer_support.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2017 Lev Walkin . All rights reserved. + * Redistribution and modifications are permitted subject to BSD license. + */ +#ifndef OER_SUPPORT_H +#define OER_SUPPORT_H + +#include /* Platform-specific types */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Pre-computed OER constraints. + */ +typedef struct asn_oer_constraint_number_s { + unsigned width; /* ±8,4,2,1 fixed bytes */ + unsigned positive; /* 1 for unsigned number, 0 for signed */ +} asn_oer_constraint_number_t; +typedef struct asn_oer_constraints_s { + asn_oer_constraint_number_t value; + ssize_t size; /* -1 (no constraint) or >= 0 */ +} asn_oer_constraints_t; + + +/* + * Fetch the length determinant (X.696 (08/2015), #8.6) into *len_r. + * RETURN VALUES: + * 0: More data expected than bufptr contains. + * -1: Fatal error deciphering length. + * >0: Number of bytes used from bufptr. + */ +ssize_t oer_fetch_length(const void *bufptr, size_t size, size_t *len_r); + +/* + * Serialize OER length. Returns the number of bytes serialized + * or -1 if a given callback returned with negative result. + */ +ssize_t oer_serialize_length(size_t length, asn_app_consume_bytes_f *cb, void *app_key); + + +#ifdef __cplusplus +} +#endif + +#endif /* OER_SUPPORT_H */ diff --git a/libs/smux/include/stg/per_decoder.h b/libs/smux/include/stg/per_decoder.h index 8397a545..710f4ee0 100644 --- a/libs/smux/include/stg/per_decoder.h +++ b/libs/smux/include/stg/per_decoder.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2005, 2007 Lev Walkin . All rights reserved. + * Copyright (c) 2005-2017 Lev Walkin . All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ #ifndef _PER_DECODER_H_ @@ -15,39 +15,40 @@ extern "C" { struct asn_TYPE_descriptor_s; /* Forward declaration */ /* - * Unaligned PER decoder of a "complete encoding" as per X.691#10.1. - * On success, this call always returns (.consumed >= 1), as per X.691#10.1.3. + * Unaligned PER decoder of a "complete encoding" as per X.691 (08/2015) #11.1. + * On success, this call always returns (.consumed >= 1), as per #11.1.3. */ -asn_dec_rval_t uper_decode_complete(struct asn_codec_ctx_s *opt_codec_ctx, - struct asn_TYPE_descriptor_s *type_descriptor, /* Type to decode */ - void **struct_ptr, /* Pointer to a target structure's pointer */ - const void *buffer, /* Data to be decoded */ - size_t size /* Size of data buffer */ - ); +asn_dec_rval_t uper_decode_complete( + const struct asn_codec_ctx_s *opt_codec_ctx, + const struct asn_TYPE_descriptor_s *type_descriptor, /* Type to decode */ + void **struct_ptr, /* Pointer to a target structure's pointer */ + const void *buffer, /* Data to be decoded */ + size_t size /* Size of data buffer */ +); /* * Unaligned PER decoder of any ASN.1 type. May be invoked by the application. * WARNING: This call returns the number of BITS read from the stream. Beware. */ -asn_dec_rval_t uper_decode(struct asn_codec_ctx_s *opt_codec_ctx, - struct asn_TYPE_descriptor_s *type_descriptor, /* Type to decode */ - void **struct_ptr, /* Pointer to a target structure's pointer */ - const void *buffer, /* Data to be decoded */ - size_t size, /* Size of data buffer */ - int skip_bits, /* Number of unused leading bits, 0..7 */ - int unused_bits /* Number of unused tailing bits, 0..7 */ - ); +asn_dec_rval_t uper_decode( + const struct asn_codec_ctx_s *opt_codec_ctx, + const struct asn_TYPE_descriptor_s *type_descriptor, /* Type to decode */ + void **struct_ptr, /* Pointer to a target structure's pointer */ + const void *buffer, /* Data to be decoded */ + size_t size, /* Size of the input data buffer, in bytes */ + int skip_bits, /* Number of unused leading bits, 0..7 */ + int unused_bits /* Number of unused tailing bits, 0..7 */ +); /* * Type of the type-specific PER decoder function. */ -typedef asn_dec_rval_t (per_type_decoder_f)(asn_codec_ctx_t *opt_codec_ctx, - struct asn_TYPE_descriptor_s *type_descriptor, - asn_per_constraints_t *constraints, - void **struct_ptr, - asn_per_data_t *per_data - ); +typedef asn_dec_rval_t(per_type_decoder_f)( + const asn_codec_ctx_t *opt_codec_ctx, + const struct asn_TYPE_descriptor_s *type_descriptor, + const asn_per_constraints_t *constraints, void **struct_ptr, + asn_per_data_t *per_data); #ifdef __cplusplus } diff --git a/libs/smux/include/stg/per_encoder.h b/libs/smux/include/stg/per_encoder.h index 95a6506e..44d8e8ac 100644 --- a/libs/smux/include/stg/per_encoder.h +++ b/libs/smux/include/stg/per_encoder.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2006, 2007 Lev Walkin . All rights reserved. + * Copyright (c) 2006-2017 Lev Walkin . All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ #ifndef _PER_ENCODER_H_ @@ -20,10 +20,12 @@ struct asn_TYPE_descriptor_s; /* Forward declaration */ * field of the return value. Use the following formula to convert to bytes: * bytes = ((.encoded + 7) / 8) */ -asn_enc_rval_t uper_encode(struct asn_TYPE_descriptor_s *type_descriptor, - void *struct_ptr, /* Structure to be encoded */ - asn_app_consume_bytes_f *consume_bytes_cb, /* Data collector */ - void *app_key /* Arbitrary callback argument */ +asn_enc_rval_t uper_encode( + const struct asn_TYPE_descriptor_s *type_descriptor, + const asn_per_constraints_t *constraints, + const void *struct_ptr, /* Structure to be encoded */ + asn_app_consume_bytes_f *consume_bytes_cb, /* Data collector */ + void *app_key /* Arbitrary callback argument */ ); /* @@ -32,10 +34,11 @@ asn_enc_rval_t uper_encode(struct asn_TYPE_descriptor_s *type_descriptor, * field of the return value. */ asn_enc_rval_t uper_encode_to_buffer( - struct asn_TYPE_descriptor_s *type_descriptor, - void *struct_ptr, /* Structure to be encoded */ - void *buffer, /* Pre-allocated buffer */ - size_t buffer_size /* Initial buffer size (max) */ + const struct asn_TYPE_descriptor_s *type_descriptor, + const asn_per_constraints_t *constraints, + const void *struct_ptr, /* Structure to be encoded */ + void *buffer, /* Pre-allocated buffer */ + size_t buffer_size /* Initial buffer size (max) */ ); /* @@ -46,21 +49,19 @@ asn_enc_rval_t uper_encode_to_buffer( * encoding of uper_encode() and uper_encode_to_buffer(). */ ssize_t uper_encode_to_new_buffer( - struct asn_TYPE_descriptor_s *type_descriptor, - asn_per_constraints_t *constraints, - void *struct_ptr, /* Structure to be encoded */ - void **buffer_r /* Buffer allocated and returned */ + const struct asn_TYPE_descriptor_s *type_descriptor, + const asn_per_constraints_t *constraints, + const void *struct_ptr, /* Structure to be encoded */ + void **buffer_r /* Buffer allocated and returned */ ); /* * Type of the generic PER encoder function. */ -typedef asn_enc_rval_t (per_type_encoder_f)( - struct asn_TYPE_descriptor_s *type_descriptor, - asn_per_constraints_t *constraints, - void *struct_ptr, - asn_per_outp_t *per_output -); +typedef asn_enc_rval_t(per_type_encoder_f)( + const struct asn_TYPE_descriptor_s *type_descriptor, + const asn_per_constraints_t *constraints, const void *struct_ptr, + asn_per_outp_t *per_output); #ifdef __cplusplus } diff --git a/libs/smux/include/stg/per_opentype.h b/libs/smux/include/stg/per_opentype.h index facfaa63..7e7dc610 100644 --- a/libs/smux/include/stg/per_opentype.h +++ b/libs/smux/include/stg/per_opentype.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 Lev Walkin . All rights reserved. + * Copyright (c) 2007-2017 Lev Walkin . All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ #ifndef _PER_OPENTYPE_H_ @@ -9,11 +9,21 @@ extern "C" { #endif -asn_dec_rval_t uper_open_type_get(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd); +asn_dec_rval_t uper_open_type_get(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, + void **sptr, asn_per_data_t *pd); -int uper_open_type_skip(asn_codec_ctx_t *opt_codec_ctx, asn_per_data_t *pd); +int uper_open_type_skip(const asn_codec_ctx_t *opt_codec_ctx, + asn_per_data_t *pd); -int uper_open_type_put(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po); +/* + * X.691 (2015/08), #11.2 + * Returns -1 if error is encountered. 0 if all OK. + */ +int uper_open_type_put(const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, + const void *sptr, asn_per_outp_t *po); #ifdef __cplusplus } diff --git a/libs/smux/include/stg/per_support.h b/libs/smux/include/stg/per_support.h index a75ac94f..3e905a8b 100644 --- a/libs/smux/include/stg/per_support.h +++ b/libs/smux/include/stg/per_support.h @@ -1,12 +1,12 @@ /* - * Copyright (c) 2005-2014 Lev Walkin . - * All rights reserved. + * Copyright (c) 2005-2017 Lev Walkin . All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ #ifndef _PER_SUPPORT_H_ #define _PER_SUPPORT_H_ #include /* Platform-specific types */ +#include #ifdef __cplusplus extern "C" { @@ -15,7 +15,7 @@ extern "C" { /* * Pre-computed PER constraints. */ -typedef const struct asn_per_constraint_s { +typedef struct asn_per_constraint_s { enum asn_per_constraint_flags { APC_UNCONSTRAINED = 0x0, /* No PER visible constraints */ APC_SEMI_CONSTRAINED = 0x1, /* Constrained at "lb" */ @@ -27,49 +27,26 @@ typedef const struct asn_per_constraint_s { long lower_bound; /* "lb" value */ long upper_bound; /* "ub" value */ } asn_per_constraint_t; -typedef const struct asn_per_constraints_s { - struct asn_per_constraint_s value; - struct asn_per_constraint_s size; +typedef struct asn_per_constraints_s { + asn_per_constraint_t value; + asn_per_constraint_t size; int (*value2code)(unsigned int value); int (*code2value)(unsigned int code); } asn_per_constraints_t; -/* - * This structure describes a position inside an incoming PER bit stream. - */ -typedef struct asn_per_data_s { - const uint8_t *buffer; /* Pointer to the octet stream */ - size_t nboff; /* Bit offset to the meaningful bit */ - size_t nbits; /* Number of bits in the stream */ - size_t moved; /* Number of bits moved through this bit stream */ - int (*refill)(struct asn_per_data_s *); - void *refill_key; -} asn_per_data_t; - -/* - * Extract a small number of bits (<= 31) from the specified PER data pointer. - * This function returns -1 if the specified number of bits could not be - * extracted due to EOD or other conditions. - */ -int32_t per_get_few_bits(asn_per_data_t *per_data, int get_nbits); - -/* Undo the immediately preceeding "get_few_bits" operation */ -void per_get_undo(asn_per_data_t *per_data, int get_nbits); - -/* - * Extract a large number of bits from the specified PER data pointer. - * This function returns -1 if the specified number of bits could not be - * extracted due to EOD or other conditions. - */ -int per_get_many_bits(asn_per_data_t *pd, uint8_t *dst, int right_align, - int get_nbits); +/* Temporary compatibility layer. Will get removed. */ +typedef struct asn_bit_data_s asn_per_data_t; +#define per_get_few_bits(data, bits) asn_get_few_bits(data, bits) +#define per_get_undo(data, bits) asn_get_undo(data, bits) +#define per_get_many_bits(data, dst, align, bits) \ + asn_get_many_bits(data, dst, align, bits) /* + * X.691 (08/2015) #11.9 "General rules for encoding a length determinant" * Get the length "n" from the Unaligned PER stream. */ -ssize_t uper_get_length(asn_per_data_t *pd, - int effective_bound_bits, - int *repeat); +ssize_t uper_get_length(asn_per_data_t *pd, int effective_bound_bits, + size_t lower_bound, int *repeat); /* * Get the normally small length "n". @@ -84,38 +61,38 @@ ssize_t uper_get_nsnnwn(asn_per_data_t *pd); /* X.691-2008/11, #11.5.6 */ int uper_get_constrained_whole_number(asn_per_data_t *pd, unsigned long *v, int nbits); -/* Non-thread-safe debugging function, don't use it */ -char *per_data_string(asn_per_data_t *pd); + +/* Temporary compatibility layer. Will get removed. */ +typedef struct asn_bit_outp_s asn_per_outp_t; +#define per_put_few_bits(out, bits, obits) asn_put_few_bits(out, bits, obits) +#define per_put_many_bits(out, src, nbits) asn_put_many_bits(out, src, nbits) +#define per_put_aligned_flush(out) asn_put_aligned_flush(out) + /* - * This structure supports forming PER output. + * Rebase the given value as an offset into the range specified by the + * lower bound (lb) and upper bound (ub). + * RETURN VALUES: + * -1: Conversion failed due to range problems. + * 0: Conversion was successful. */ -typedef struct asn_per_outp_s { - uint8_t *buffer; /* Pointer into the (tmpspace) */ - size_t nboff; /* Bit offset to the meaningful bit */ - size_t nbits; /* Number of bits left in (tmpspace) */ - uint8_t tmpspace[32]; /* Preliminary storage to hold data */ - int (*outper)(const void *data, size_t size, void *op_key); - void *op_key; /* Key for (outper) data callback */ - size_t flushed_bytes; /* Bytes already flushed through (outper) */ -} asn_per_outp_t; - -/* Output a small number of bits (<= 31) */ -int per_put_few_bits(asn_per_outp_t *per_data, uint32_t bits, int obits); - -/* Output a large number of bits */ -int per_put_many_bits(asn_per_outp_t *po, const uint8_t *src, int put_nbits); +int per_long_range_rebase(long v, long lb, long ub, unsigned long *output); +/* The inverse operation: restores the value by the offset and its bounds. */ +int per_long_range_unrebase(unsigned long inp, long lb, long ub, long *outp); /* X.691-2008/11, #11.5 */ -int uper_put_constrained_whole_number_s(asn_per_outp_t *po, long v, int nbits); int uper_put_constrained_whole_number_u(asn_per_outp_t *po, unsigned long v, int nbits); /* - * Put the length "n" to the Unaligned PER stream. + * X.691 (08/2015) #11.9 "General rules for encoding a length determinant" + * Put the length "whole_length" to the Unaligned PER stream. + * If (opt_need_eom) is given, it will be set to 1 if final 0-length is needed. + * In that case, invoke uper_put_length(po, 0, 0) after encoding the last block. * This function returns the number of units which may be flushed * in the next units saving iteration. */ -ssize_t uper_put_length(asn_per_outp_t *po, size_t whole_length); +ssize_t uper_put_length(asn_per_outp_t *po, size_t whole_length, + int *opt_need_eom); /* * Put the normally small length "n" to the Unaligned PER stream. diff --git a/libs/smux/include/stg/xer_decoder.h b/libs/smux/include/stg/xer_decoder.h index 301b613c..b951c41d 100644 --- a/libs/smux/include/stg/xer_decoder.h +++ b/libs/smux/include/stg/xer_decoder.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2004 Lev Walkin . All rights reserved. + * Copyright (c) 2004-2017 Lev Walkin . All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ #ifndef _XER_DECODER_H_ @@ -15,23 +15,24 @@ struct asn_TYPE_descriptor_s; /* Forward declaration */ /* * The XER decoder of any ASN.1 type. May be invoked by the application. + * Decodes CANONICAL-XER and BASIC-XER. */ -asn_dec_rval_t xer_decode(struct asn_codec_ctx_s *opt_codec_ctx, - struct asn_TYPE_descriptor_s *type_descriptor, - void **struct_ptr, /* Pointer to a target structure's pointer */ - const void *buffer, /* Data to be decoded */ - size_t size /* Size of data buffer */ - ); +asn_dec_rval_t xer_decode( + const struct asn_codec_ctx_s *opt_codec_ctx, + const struct asn_TYPE_descriptor_s *type_descriptor, + void **struct_ptr, /* Pointer to a target structure's pointer */ + const void *buffer, /* Data to be decoded */ + size_t size /* Size of data buffer */ +); /* * Type of the type-specific XER decoder function. */ -typedef asn_dec_rval_t (xer_type_decoder_f)(asn_codec_ctx_t *opt_codec_ctx, - struct asn_TYPE_descriptor_s *type_descriptor, - void **struct_ptr, - const char *opt_mname, /* Member name */ - const void *buf_ptr, size_t size - ); +typedef asn_dec_rval_t(xer_type_decoder_f)( + const asn_codec_ctx_t *opt_codec_ctx, + const struct asn_TYPE_descriptor_s *type_descriptor, void **struct_ptr, + const char *opt_mname, /* Member name */ + const void *buf_ptr, size_t size); /******************************* * INTERNALLY USEFUL FUNCTIONS * @@ -43,17 +44,16 @@ typedef asn_dec_rval_t (xer_type_decoder_f)(asn_codec_ctx_t *opt_codec_ctx, * and others. This function should not be used by applications, as its API * is subject to changes. */ -asn_dec_rval_t xer_decode_general(asn_codec_ctx_t *opt_codec_ctx, - asn_struct_ctx_t *ctx, /* Type decoder context */ - void *struct_key, /* Treated as opaque pointer */ - const char *xml_tag, /* Expected XML tag name */ - const void *buf_ptr, size_t size, - int (*opt_unexpected_tag_decoder) - (void *struct_key, const void *chunk_buf, size_t chunk_size), - ssize_t (*body_receiver) - (void *struct_key, const void *chunk_buf, size_t chunk_size, - int have_more) - ); +asn_dec_rval_t xer_decode_general( + const asn_codec_ctx_t *opt_codec_ctx, + asn_struct_ctx_t *ctx, /* Type decoder context */ + void *struct_key, /* Treated as opaque pointer */ + const char *xml_tag, /* Expected XML tag name */ + const void *buf_ptr, size_t size, + int (*opt_unexpected_tag_decoder)(void *struct_key, const void *chunk_buf, + size_t chunk_size), + ssize_t (*body_receiver)(void *struct_key, const void *chunk_buf, + size_t chunk_size, int have_more)); /* diff --git a/libs/smux/include/stg/xer_encoder.h b/libs/smux/include/stg/xer_encoder.h index 055e73c0..9d75922c 100644 --- a/libs/smux/include/stg/xer_encoder.h +++ b/libs/smux/include/stg/xer_encoder.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2004 Lev Walkin . All rights reserved. + * Copyright (c) 2004-2017 Lev Walkin . All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ #ifndef _XER_ENCODER_H_ @@ -22,13 +22,14 @@ enum xer_encoder_flags_e { /* * The XER encoder of any type. May be invoked by the application. + * Produces CANONICAL-XER and BASIC-XER depending on the (xer_flags). */ -asn_enc_rval_t xer_encode(struct asn_TYPE_descriptor_s *type_descriptor, - void *struct_ptr, /* Structure to be encoded */ - enum xer_encoder_flags_e xer_flags, - asn_app_consume_bytes_f *consume_bytes_cb, - void *app_key /* Arbitrary callback argument */ - ); +asn_enc_rval_t xer_encode(const struct asn_TYPE_descriptor_s *type_descriptor, + const void *struct_ptr, /* Structure to be encoded */ + enum xer_encoder_flags_e xer_flags, + asn_app_consume_bytes_f *consume_bytes_cb, + void *app_key /* Arbitrary callback argument */ +); /* * The variant of the above function which dumps the BASIC-XER (XER_F_BASIC) @@ -38,19 +39,42 @@ asn_enc_rval_t xer_encode(struct asn_TYPE_descriptor_s *type_descriptor, * -1: Problem printing the structure. * WARNING: No sensible errno value is returned. */ -int xer_fprint(FILE *stream, struct asn_TYPE_descriptor_s *td, void *sptr); +int xer_fprint(FILE *stream, const struct asn_TYPE_descriptor_s *td, + const void *struct_ptr); + +/* + * A helper function that uses XER encoding/decoding to verify that: + * - Both structures encode into the same BASIC XER. + * - Both resulting XER byte streams can be decoded back. + * - Both decoded structures encode into the same BASIC XER (round-trip). + * All of this verifies equivalence between structures and a round-trip. + * ARGUMENTS: + * (opt_debug_stream) - If specified, prints ongoing details. + */ +enum xer_equivalence_e { + XEQ_SUCCESS, /* The only completely positive return value */ + XEQ_FAILURE, /* General failure */ + XEQ_ENCODE1_FAILED, /* First sructure XER encoding failed */ + XEQ_ENCODE2_FAILED, /* Second structure XER encoding failed */ + XEQ_DIFFERENT, /* Structures encoded into different XER */ + XEQ_DECODE_FAILED, /* Decode of the XER data failed */ + XEQ_ROUND_TRIP_FAILED /* Bad round-trip */ +}; +enum xer_equivalence_e xer_equivalent( + const struct asn_TYPE_descriptor_s *type_descriptor, const void *struct1, + const void *struct2, FILE *opt_debug_stream); /* * Type of the generic XER encoder. */ -typedef asn_enc_rval_t (xer_type_encoder_f)( - struct asn_TYPE_descriptor_s *type_descriptor, - void *struct_ptr, /* Structure to be encoded */ - int ilevel, /* Level of indentation */ - enum xer_encoder_flags_e xer_flags, - asn_app_consume_bytes_f *consume_bytes_cb, /* Callback */ - void *app_key /* Arbitrary callback argument */ - ); +typedef asn_enc_rval_t(xer_type_encoder_f)( + const struct asn_TYPE_descriptor_s *type_descriptor, + const void *struct_ptr, /* Structure to be encoded */ + int ilevel, /* Level of indentation */ + enum xer_encoder_flags_e xer_flags, + asn_app_consume_bytes_f *consume_bytes_cb, /* Callback */ + void *app_key /* Arbitrary callback argument */ +); #ifdef __cplusplus } diff --git a/libs/smux/include/stg/xer_support.h b/libs/smux/include/stg/xer_support.h index 8b01944a..c3a36e72 100644 --- a/libs/smux/include/stg/xer_support.h +++ b/libs/smux/include/stg/xer_support.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2003, 2004 X/IO Labs, xiolabs.com. - * Copyright (c) 2003, 2004 Lev Walkin . All rights reserved. + * Copyright (c) 2003-2017 Lev Walkin . All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ #ifndef _XER_SUPPORT_H_ diff --git a/libs/smux/oer_decoder.c b/libs/smux/oer_decoder.c new file mode 100644 index 00000000..07017382 --- /dev/null +++ b/libs/smux/oer_decoder.c @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2017 Lev Walkin . All rights reserved. + * Redistribution and modifications are permitted subject to BSD license. + */ +#include +#include + +/* + * The OER decoder of any type. + */ +asn_dec_rval_t +oer_decode(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *type_descriptor, void **struct_ptr, + const void *ptr, size_t size) { + asn_codec_ctx_t s_codec_ctx; + + /* + * Stack checker requires that the codec context + * must be allocated on the stack. + */ + if(opt_codec_ctx) { + if(opt_codec_ctx->max_stack_size) { + s_codec_ctx = *opt_codec_ctx; + opt_codec_ctx = &s_codec_ctx; + } + } else { + /* If context is not given, be security-conscious anyway */ + memset(&s_codec_ctx, 0, sizeof(s_codec_ctx)); + s_codec_ctx.max_stack_size = ASN__DEFAULT_STACK_MAX; + opt_codec_ctx = &s_codec_ctx; + } + + /* + * Invoke type-specific decoder. + */ + return type_descriptor->op->oer_decoder(opt_codec_ctx, type_descriptor, 0, + struct_ptr, /* Pointer to the destination structure */ + ptr, size /* Buffer and its size */ + ); +} + +/* + * Open Type is encoded as a length (#8.6) followed by that number of bytes. + * Since we're just skipping, reading the length would be enough. + */ +ssize_t +oer_open_type_skip(const void *bufptr, size_t size) { + size_t len = 0; + return oer_fetch_length(bufptr, size, &len); +} + +/* + * Read the Open Type (X.696 (08/2015), #30). + * RETURN VALUES: + * 0: More data expected than bufptr contains. + * -1: Fatal error deciphering length. + * >0: Number of bytes used from bufptr. + */ +ssize_t +oer_open_type_get(const asn_codec_ctx_t *opt_codec_ctx, + const struct asn_TYPE_descriptor_s *td, + const asn_oer_constraints_t *constraints, void **struct_ptr, + const void *bufptr, size_t size) { + asn_dec_rval_t dr; + size_t container_len = 0; + ssize_t len_len; + enum asn_struct_free_method dispose_method = + (*struct_ptr) ? ASFM_FREE_UNDERLYING_AND_RESET : ASFM_FREE_EVERYTHING; + + /* Get the size of a length determinant */ + len_len = oer_fetch_length(bufptr, size, &container_len); + if(len_len <= 0) { + return len_len; /* Error or more data expected */ + } + + /* + * len_len can't be bigger than size, but size without len_len + * should be bigger or equal to container length + */ + if(size - len_len < container_len) { + /* More data is expected */ + return 0; + } + + dr = td->op->oer_decoder(opt_codec_ctx, td, constraints, struct_ptr, + (const uint8_t *)bufptr + len_len, container_len); + if(dr.code == RC_OK) { + return len_len + container_len; + } else { + /* Even if RC_WMORE, we can't get more data into a closed container. */ + td->op->free_struct(td, *struct_ptr, dispose_method); + *struct_ptr = NULL; + return -1; + } +} + + +asn_dec_rval_t +oer_decode_primitive(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *td, + const asn_oer_constraints_t *constraints, void **sptr, + const void *ptr, size_t size) { + ASN__PRIMITIVE_TYPE_t *st = (ASN__PRIMITIVE_TYPE_t *)*sptr; + asn_dec_rval_t rval = {RC_OK, 0}; + size_t expected_length = 0; + ssize_t len_len; + + (void)td; + (void)opt_codec_ctx; + (void)constraints; + + if(!st) { + st = (ASN__PRIMITIVE_TYPE_t *)(*sptr = CALLOC( + 1, sizeof(ASN__PRIMITIVE_TYPE_t))); + if(!st) ASN__DECODE_FAILED; + } + + + /* + * X.696 (08/2015) #27.2 + * Encode length determinant as _number of octets_, but only + * if upper bound is not equal to lower bound. + */ + len_len = oer_fetch_length(ptr, size, &expected_length); + if(len_len > 0) { + rval.consumed = len_len; + ptr = (const char *)ptr + len_len; + size -= len_len; + } else if(len_len == 0) { + ASN__DECODE_STARVED; + } else if(len_len < 0) { + ASN__DECODE_FAILED; + } + + if(size < expected_length) { + ASN__DECODE_STARVED; + } else { + uint8_t *buf = MALLOC(expected_length + 1); + if(buf == NULL) { + ASN__DECODE_FAILED; + } else { + memcpy(buf, ptr, expected_length); + buf[expected_length] = '\0'; + } + FREEMEM(st->buf); + st->buf = buf; + st->size = expected_length; + + rval.consumed += expected_length; + return rval; + } +} diff --git a/libs/smux/oer_encoder.c b/libs/smux/oer_encoder.c new file mode 100644 index 00000000..895aed4e --- /dev/null +++ b/libs/smux/oer_encoder.c @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2017 Lev Walkin . All rights reserved. + * Redistribution and modifications are permitted subject to BSD license. + */ +#include +#include + +/* + * The OER encoder of any type. + */ +asn_enc_rval_t +oer_encode(const asn_TYPE_descriptor_t *type_descriptor, const void *struct_ptr, + asn_app_consume_bytes_f *consume_bytes, void *app_key) { + ASN_DEBUG("OER encoder invoked for %s", type_descriptor->name); + + /* + * Invoke type-specific encoder. + */ + return type_descriptor->op->oer_encoder( + type_descriptor, 0, + struct_ptr, /* Pointer to the destination structure */ + consume_bytes, app_key); +} + +/* + * Argument type and callback necessary for oer_encode_to_buffer(). + */ +typedef struct enc_to_buf_arg { + void *buffer; + size_t left; +} enc_to_buf_arg; +static int +encode_to_buffer_cb(const void *buffer, size_t size, void *key) { + enc_to_buf_arg *arg = (enc_to_buf_arg *)key; + + if(arg->left < size) return -1; /* Data exceeds the available buffer size */ + + memcpy(arg->buffer, buffer, size); + arg->buffer = ((char *)arg->buffer) + size; + arg->left -= size; + + return 0; +} + +/* + * A variant of the oer_encode() which encodes the data into the provided buffer + */ +asn_enc_rval_t +oer_encode_to_buffer(const asn_TYPE_descriptor_t *type_descriptor, + const asn_oer_constraints_t *constraints, + const void *struct_ptr, /* Structure to be encoded */ + void *buffer, /* Pre-allocated buffer */ + size_t buffer_size /* Initial buffer size (maximum) */ +) { + enc_to_buf_arg arg; + asn_enc_rval_t ec; + + arg.buffer = buffer; + arg.left = buffer_size; + + if(type_descriptor->op->oer_encoder == NULL) { + ec.encoded = -1; + ec.failed_type = type_descriptor; + ec.structure_ptr = struct_ptr; + ASN_DEBUG("OER encoder is not defined for %s", + type_descriptor->name); + } else { + ec = type_descriptor->op->oer_encoder( + type_descriptor, constraints, + struct_ptr, /* Pointer to the destination structure */ + encode_to_buffer_cb, &arg); + if(ec.encoded != -1) { + assert(ec.encoded == (ssize_t)(buffer_size - arg.left)); + /* Return the encoded contents size */ + } + } + return ec; +} + +asn_enc_rval_t +oer_encode_primitive(const asn_TYPE_descriptor_t *td, + const asn_oer_constraints_t *constraints, const void *sptr, + asn_app_consume_bytes_f *cb, void *app_key) { + const ASN__PRIMITIVE_TYPE_t *st = (const ASN__PRIMITIVE_TYPE_t *)sptr; + asn_enc_rval_t er = {0, 0, 0}; + ssize_t ret; + + (void)constraints; + + if(!st) ASN__ENCODE_FAILED; + + ASN_DEBUG("Encoding %s (%" ASN_PRI_SIZE " bytes)", td ? td->name : "", st->size); + + /* + * X.696 (08/2015) #27.2 + */ + ret = oer_serialize_length(st->size, cb, app_key); + if(ret < 0) { + ASN__ENCODE_FAILED; + } + er.encoded += ret; + + er.encoded += st->size; + if(cb(st->buf, st->size, app_key) < 0) { + ASN__ENCODE_FAILED; + } else { + ASN__ENCODED_OK(er); + } +} + +static int +oer__count_bytes(const void *buffer, size_t size, void *bytes_ptr) { + size_t *bytes = bytes_ptr; + (void)buffer; + *bytes += size; + return 0; +} + +ssize_t +oer_open_type_put(const asn_TYPE_descriptor_t *td, + const asn_oer_constraints_t *constraints, const void *sptr, + asn_app_consume_bytes_f *cb, void *app_key) { + size_t serialized_byte_count = 0; + asn_enc_rval_t er; + ssize_t len_len; + + er = td->op->oer_encoder(td, constraints, sptr, oer__count_bytes, + &serialized_byte_count); + if(er.encoded < 0) return -1; + assert(serialized_byte_count == (size_t)er.encoded); + + len_len = oer_serialize_length(serialized_byte_count, cb, app_key); + if(len_len == -1) return -1; + + er = td->op->oer_encoder(td, constraints, sptr, cb, app_key); + if(er.encoded < 0) return -1; + assert(serialized_byte_count == (size_t)er.encoded); + + return len_len + er.encoded; +} + diff --git a/libs/smux/oer_support.c b/libs/smux/oer_support.c new file mode 100644 index 00000000..b15a3bc9 --- /dev/null +++ b/libs/smux/oer_support.c @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2017 Lev Walkin . + * All rights reserved. + * Redistribution and modifications are permitted subject to BSD license. + */ +#include +#include + +#include + +/* + * Fetch the length determinant (X.696 08/2015, #8.6) into *len_r. + * RETURN VALUES: + * 0: More data expected than bufptr contains. + * -1: Fatal error deciphering length. + * >0: Number of bytes used from bufptr. + */ +ssize_t +oer_fetch_length(const void *bufptr, size_t size, size_t *len_r) { + uint8_t first_byte; + size_t len_len; /* Length of the length determinant */ + const uint8_t *b; + const uint8_t *bend; + size_t len; + + if(size == 0) { + *len_r = 0; + return 0; + } + + first_byte = *(const uint8_t *)bufptr; + if((first_byte & 0x80) == 0) { /* Short form */ + *len_r = first_byte; /* 0..127 */ + return 1; + } + + len_len = (first_byte & 0x7f); + if((1 + len_len) > size) { + *len_r = 0; + return 0; + } + + b = (const uint8_t *)bufptr + 1; + bend = b + len_len; + + for(; b < bend && *b == 0; b++) { + /* Skip the leading 0-bytes */ + } + + if((bend - b) > (ssize_t)sizeof(size_t)) { + /* Length is not representable by the native size_t type */ + *len_r = 0; + return -1; + } + + for(len = 0; b < bend; b++) { + len = (len << 8) + *b; + } + + if(len > RSIZE_MAX) { /* A bit of C11 validation */ + *len_r = 0; + return -1; + } + + *len_r = len; + assert(len_len + 1 == (size_t)(bend - (const uint8_t *)bufptr)); + return len_len + 1; +} + + +/* + * Serialize OER length. Returns the number of bytes serialized + * or -1 if a given callback returned with negative result. + */ +ssize_t +oer_serialize_length(size_t length, asn_app_consume_bytes_f *cb, + void *app_key) { + uint8_t scratch[1 + sizeof(length)]; + uint8_t *sp = scratch; + int littleEndian = 1; /* Run-time detection */ + const uint8_t *pstart; + const uint8_t *pend; + const uint8_t *p; + int add; + + if(length <= 127) { + uint8_t b = length; + if(cb(&b, 1, app_key) < 0) { + return -1; + } + return 1; + } + + if(*(char *)&littleEndian) { + pstart = (const uint8_t *)&length + sizeof(length) - 1; + pend = (const uint8_t *)&length; + add = -1; + } else { + pstart = (const uint8_t *)&length; + pend = pstart + sizeof(length); + add = 1; + } + + for(p = pstart; p != pend; p += add) { + /* Skip leading zeros. */ + if(*p) break; + } + + for(sp = scratch + 1; ; p += add) { + *sp++ = *p; + if(p == pend) break; + } + assert((sp - scratch) - 1 <= 0x7f); + scratch[0] = 0x80 + ((sp - scratch) - 1); + + if(cb(scratch, sp - scratch, app_key) < 0) { + return -1; + } + + return sp - scratch; +} + diff --git a/libs/smux/pdu_collection.c b/libs/smux/pdu_collection.c new file mode 100644 index 00000000..b34c67f1 --- /dev/null +++ b/libs/smux/pdu_collection.c @@ -0,0 +1,35 @@ +/* + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) + */ + +struct asn_TYPE_descriptor_s; /* Forward declaration */ + +extern struct asn_TYPE_descriptor_s asn_DEF_IfEntry; +extern struct asn_TYPE_descriptor_s asn_DEF_AtEntry; +extern struct asn_TYPE_descriptor_s asn_DEF_IpAddrEntry; +extern struct asn_TYPE_descriptor_s asn_DEF_IpRouteEntry; +extern struct asn_TYPE_descriptor_s asn_DEF_IpNetToMediaEntry; +extern struct asn_TYPE_descriptor_s asn_DEF_TcpConnEntry; +extern struct asn_TYPE_descriptor_s asn_DEF_UdpEntry; +extern struct asn_TYPE_descriptor_s asn_DEF_EgpNeighEntry; +extern struct asn_TYPE_descriptor_s asn_DEF_Message; +extern struct asn_TYPE_descriptor_s asn_DEF_SMUX_PDUs; + + +struct asn_TYPE_descriptor_s *asn_pdu_collection[] = { + /* From module RFC1213-MIB in RFC1213-MIB.asn1 */ + &asn_DEF_IfEntry, + &asn_DEF_AtEntry, + &asn_DEF_IpAddrEntry, + &asn_DEF_IpRouteEntry, + &asn_DEF_IpNetToMediaEntry, + &asn_DEF_TcpConnEntry, + &asn_DEF_UdpEntry, + &asn_DEF_EgpNeighEntry, + /* From module RFC1157-SNMP in RFC1157-SNMP.asn1 */ + &asn_DEF_Message, + /* From module SMUX in SMUX.asn1 */ + &asn_DEF_SMUX_PDUs, + 0 +}; + diff --git a/libs/smux/per_decoder.c b/libs/smux/per_decoder.c index 461b7262..a9051fb7 100644 --- a/libs/smux/per_decoder.c +++ b/libs/smux/per_decoder.c @@ -8,8 +8,10 @@ * multiple of 8 bytes. */ asn_dec_rval_t -uper_decode_complete(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, void **sptr, const void *buffer, size_t size) { - asn_dec_rval_t rval; +uper_decode_complete(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *td, void **sptr, + const void *buffer, size_t size) { + asn_dec_rval_t rval; rval = uper_decode(opt_codec_ctx, td, sptr, buffer, size, 0, 0); if(rval.consumed) { @@ -37,8 +39,10 @@ uper_decode_complete(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, } asn_dec_rval_t -uper_decode(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, void **sptr, const void *buffer, size_t size, int skip_bits, int unused_bits) { - asn_codec_ctx_t s_codec_ctx; +uper_decode(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *td, void **sptr, const void *buffer, + size_t size, int skip_bits, int unused_bits) { + asn_codec_ctx_t s_codec_ctx; asn_dec_rval_t rval; asn_per_data_t pd; @@ -74,9 +78,9 @@ uper_decode(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, void **sp /* * Invoke type-specific decoder. */ - if(!td->uper_decoder) + if(!td->op->uper_decoder) ASN__DECODE_FAILED; /* PER is not compiled in */ - rval = td->uper_decoder(opt_codec_ctx, td, 0, sptr, &pd); + rval = td->op->uper_decoder(opt_codec_ctx, td, 0, sptr, &pd); if(rval.code == RC_OK) { /* Return the number of consumed bits */ rval.consumed = ((pd.buffer - (const uint8_t *)buffer) << 3) diff --git a/libs/smux/per_encoder.c b/libs/smux/per_encoder.c index 47f3c916..86aec4ea 100644 --- a/libs/smux/per_encoder.c +++ b/libs/smux/per_encoder.c @@ -2,11 +2,49 @@ #include #include -static asn_enc_rval_t uper_encode_internal(asn_TYPE_descriptor_t *td, asn_per_constraints_t *, void *sptr, asn_app_consume_bytes_f *cb, void *app_key); +static int _uper_encode_flush_outp(asn_per_outp_t *po); + +static int +ignore_output(const void *data, size_t size, void *app_key) { + (void)data; + (void)size; + (void)app_key; + return 0; +} asn_enc_rval_t -uper_encode(asn_TYPE_descriptor_t *td, void *sptr, asn_app_consume_bytes_f *cb, void *app_key) { - return uper_encode_internal(td, 0, sptr, cb, app_key); +uper_encode(const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, const void *sptr, + asn_app_consume_bytes_f *cb, void *app_key) { + asn_per_outp_t po; + asn_enc_rval_t er; + + /* + * Invoke type-specific encoder. + */ + if(!td || !td->op->uper_encoder) + ASN__ENCODE_FAILED; /* PER is not compiled in */ + + po.buffer = po.tmpspace; + po.nboff = 0; + po.nbits = 8 * sizeof(po.tmpspace); + po.output = cb ? cb : ignore_output; + po.op_key = app_key; + po.flushed_bytes = 0; + + er = td->op->uper_encoder(td, constraints, sptr, &po); + if(er.encoded != -1) { + size_t bits_to_flush; + + bits_to_flush = ((po.buffer - po.tmpspace) << 3) + po.nboff; + + /* Set number of bits encoded to a firm value */ + er.encoded = (po.flushed_bytes << 3) + bits_to_flush; + + if(_uper_encode_flush_outp(&po)) ASN__ENCODE_FAILED; + } + + return er; } /* @@ -30,15 +68,17 @@ static int encode_to_buffer_cb(const void *buffer, size_t size, void *key) { } asn_enc_rval_t -uper_encode_to_buffer(asn_TYPE_descriptor_t *td, void *sptr, void *buffer, size_t buffer_size) { - enc_to_buf_arg key; +uper_encode_to_buffer(const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, + const void *sptr, void *buffer, size_t buffer_size) { + enc_to_buf_arg key; - key.buffer = buffer; - key.left = buffer_size; + key.buffer = buffer; + key.left = buffer_size; - if(td) ASN_DEBUG("Encoding \"%s\" using UNALIGNED PER", td->name); + if(td) ASN_DEBUG("Encoding \"%s\" using UNALIGNED PER", td->name); - return uper_encode_internal(td, 0, sptr, encode_to_buffer_cb, &key); + return uper_encode(td, constraints, sptr, encode_to_buffer_cb, &key); } typedef struct enc_dyn_arg { @@ -48,30 +88,38 @@ typedef struct enc_dyn_arg { } enc_dyn_arg; static int encode_dyn_cb(const void *buffer, size_t size, void *key) { - enc_dyn_arg *arg = key; - if(arg->length + size >= arg->allocated) { - void *p; - arg->allocated = arg->allocated ? (arg->allocated << 2) : size; - p = REALLOC(arg->buffer, arg->allocated); - if(!p) { - FREEMEM(arg->buffer); - memset(arg, 0, sizeof(*arg)); - return -1; - } - arg->buffer = p; - } - memcpy(((char *)arg->buffer) + arg->length, buffer, size); - arg->length += size; - return 0; + enc_dyn_arg *arg = key; + if(arg->length + size >= arg->allocated) { + size_t new_size = arg->allocated ? arg->allocated : 8; + void *p; + + do { + new_size <<= 2; + } while(arg->length + size >= new_size); + + p = REALLOC(arg->buffer, new_size); + if(!p) { + FREEMEM(arg->buffer); + memset(arg, 0, sizeof(*arg)); + return -1; + } + arg->buffer = p; + arg->allocated = new_size; + } + memcpy(((char *)arg->buffer) + arg->length, buffer, size); + arg->length += size; + return 0; } ssize_t -uper_encode_to_new_buffer(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void *sptr, void **buffer_r) { - asn_enc_rval_t er; +uper_encode_to_new_buffer(const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, + const void *sptr, void **buffer_r) { + asn_enc_rval_t er; enc_dyn_arg key; memset(&key, 0, sizeof(key)); - er = uper_encode_internal(td, constraints, sptr, encode_dyn_cb, &key); + er = uper_encode(td, constraints, sptr, encode_dyn_cb, &key); switch(er.encoded) { case -1: FREEMEM(key.buffer); @@ -112,40 +160,6 @@ _uper_encode_flush_outp(asn_per_outp_t *po) { buf++; } - return po->outper(po->tmpspace, buf - po->tmpspace, po->op_key); -} - -static asn_enc_rval_t -uper_encode_internal(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void *sptr, asn_app_consume_bytes_f *cb, void *app_key) { - asn_per_outp_t po; - asn_enc_rval_t er; - - /* - * Invoke type-specific encoder. - */ - if(!td || !td->uper_encoder) - ASN__ENCODE_FAILED; /* PER is not compiled in */ - - po.buffer = po.tmpspace; - po.nboff = 0; - po.nbits = 8 * sizeof(po.tmpspace); - po.outper = cb; - po.op_key = app_key; - po.flushed_bytes = 0; - - er = td->uper_encoder(td, constraints, sptr, &po); - if(er.encoded != -1) { - size_t bits_to_flush; - - bits_to_flush = ((po.buffer - po.tmpspace) << 3) + po.nboff; - - /* Set number of bits encoded to a firm value */ - er.encoded = (po.flushed_bytes << 3) + bits_to_flush; - - if(_uper_encode_flush_outp(&po)) - ASN__ENCODE_FAILED; - } - - return er; + return po->output(po->tmpspace, buf - po->tmpspace, po->op_key); } diff --git a/libs/smux/per_opentype.c b/libs/smux/per_opentype.c index 404aa726..f86dad70 100644 --- a/libs/smux/per_opentype.c +++ b/libs/smux/per_opentype.c @@ -16,47 +16,60 @@ typedef struct uper_ugot_key { static int uper_ugot_refill(asn_per_data_t *pd); static int per_skip_bits(asn_per_data_t *pd, int skip_nbits); -static asn_dec_rval_t uper_sot_suck(asn_codec_ctx_t *, asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd); +static asn_dec_rval_t uper_sot_suck(const asn_codec_ctx_t *, + const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, + void **sptr, asn_per_data_t *pd); /* * Encode an "open type field". * #10.1, #10.2 */ int -uper_open_type_put(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { - void *buf; - void *bptr; - ssize_t size; - size_t toGo; - - ASN_DEBUG("Open type put %s ...", td->name); - - size = uper_encode_to_new_buffer(td, constraints, sptr, &buf); - if(size <= 0) return -1; - - for(bptr = buf, toGo = size; toGo;) { - ssize_t maySave = uper_put_length(po, toGo); - ASN_DEBUG("Prepending length %d to %s and allowing to save %d", - (int)size, td->name, (int)maySave); - if(maySave < 0) break; - if(per_put_many_bits(po, bptr, maySave * 8)) break; - bptr = (char *)bptr + maySave; - toGo -= maySave; - } - - FREEMEM(buf); - if(toGo) return -1; - - ASN_DEBUG("Open type put %s of length %ld + overhead (1byte?)", - td->name, (long)size); - - return 0; +uper_open_type_put(const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, const void *sptr, + asn_per_outp_t *po) { + void *buf; + void *bptr; + ssize_t size; + + ASN_DEBUG("Open type put %s ...", td->name); + + size = uper_encode_to_new_buffer(td, constraints, sptr, &buf); + if(size <= 0) return -1; + + ASN_DEBUG("Open type put %s of length %" ASN_PRI_SSIZE " + overhead (1byte?)", td->name, + size); + + bptr = buf; + do { + int need_eom = 0; + ssize_t may_save = uper_put_length(po, size, &need_eom); + ASN_DEBUG("Prepending length %" ASN_PRI_SSIZE + " to %s and allowing to save %" ASN_PRI_SSIZE, + size, td->name, may_save); + if(may_save < 0) break; + if(per_put_many_bits(po, bptr, may_save * 8)) break; + bptr = (char *)bptr + may_save; + size -= may_save; + if(need_eom && uper_put_length(po, 0, 0)) { + FREEMEM(buf); + return -1; + } + } while(size); + + FREEMEM(buf); + if(size) return -1; + + return 0; } static asn_dec_rval_t -uper_open_type_get_simple(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td, - asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { - asn_dec_rval_t rv; +uper_open_type_get_simple(const asn_codec_ctx_t *ctx, + const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, void **sptr, + asn_per_data_t *pd) { + asn_dec_rval_t rv; ssize_t chunk_bytes; int repeat; uint8_t *buf = 0; @@ -70,7 +83,7 @@ uper_open_type_get_simple(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td, ASN_DEBUG("Getting open type %s...", td->name); do { - chunk_bytes = uper_get_length(pd, -1, &repeat); + chunk_bytes = uper_get_length(pd, -1, 0, &repeat); if(chunk_bytes < 0) { FREEMEM(buf); ASN__DECODE_STARVED; @@ -100,7 +113,7 @@ uper_open_type_get_simple(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td, spd.nbits = bufLen << 3; ASN_DEBUG_INDENT_ADD(+4); - rv = td->uper_decoder(ctx, td, constraints, sptr, &spd); + rv = td->op->uper_decoder(ctx, td, constraints, sptr, &spd); ASN_DEBUG_INDENT_ADD(-4); if(rv.code == RC_OK) { @@ -131,17 +144,19 @@ uper_open_type_get_simple(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td, return rv; } -static asn_dec_rval_t GCC_NOTUSED -uper_open_type_get_complex(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td, - asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { - uper_ugot_key arg; +static asn_dec_rval_t CC_NOTUSED +uper_open_type_get_complex(const asn_codec_ctx_t *ctx, + const asn_TYPE_descriptor_t *td, + asn_per_constraints_t *constraints, void **sptr, + asn_per_data_t *pd) { + uper_ugot_key arg; asn_dec_rval_t rv; ssize_t padding; ASN__STACK_OVERFLOW_CHECK(ctx); ASN_DEBUG("Getting open type %s from %s", td->name, - per_data_string(pd)); + asn_bit_data_string(pd)); arg.oldpd = *pd; arg.unclaimed = 0; arg.ot_moved = 0; @@ -152,7 +167,7 @@ uper_open_type_get_complex(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td, pd->moved = 0; /* This now counts the open type size in bits */ ASN_DEBUG_INDENT_ADD(+4); - rv = td->uper_decoder(ctx, td, constraints, sptr, pd); + rv = td->op->uper_decoder(ctx, td, constraints, sptr, pd); ASN_DEBUG_INDENT_ADD(-4); #define UPDRESTOREPD do { \ @@ -169,8 +184,8 @@ uper_open_type_get_complex(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td, } ASN_DEBUG("OpenType %s pd%s old%s unclaimed=%d, repeat=%d", td->name, - per_data_string(pd), - per_data_string(&arg.oldpd), + asn_bit_data_string(pd), + asn_bit_data_string(&arg.oldpd), (int)arg.unclaimed, (int)arg.repeat); padding = pd->moved % 8; @@ -201,7 +216,7 @@ uper_open_type_get_complex(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td, } if(pd->nboff != pd->nbits) { ASN_DEBUG("Open type %s overhead pd%s old%s", td->name, - per_data_string(pd), per_data_string(&arg.oldpd)); + asn_bit_data_string(pd), asn_bit_data_string(&arg.oldpd)); if(1) { UPDRESTOREPD; ASN__DECODE_FAILED; @@ -242,19 +257,21 @@ uper_open_type_get_complex(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td, asn_dec_rval_t -uper_open_type_get(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td, - asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { - - return uper_open_type_get_simple(ctx, td, constraints, sptr, pd); +uper_open_type_get(const asn_codec_ctx_t *ctx, const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, void **sptr, + asn_per_data_t *pd) { + return uper_open_type_get_simple(ctx, td, constraints, sptr, pd); } int -uper_open_type_skip(asn_codec_ctx_t *ctx, asn_per_data_t *pd) { +uper_open_type_skip(const asn_codec_ctx_t *ctx, asn_per_data_t *pd) { asn_TYPE_descriptor_t s_td; + asn_TYPE_operation_t s_op; asn_dec_rval_t rv; s_td.name = ""; - s_td.uper_decoder = uper_sot_suck; + s_td.op = &s_op; + s_op.uper_decoder = uper_sot_suck; rv = uper_open_type_get(ctx, &s_td, 0, 0, pd); if(rv.code != RC_OK) @@ -268,9 +285,10 @@ uper_open_type_skip(asn_codec_ctx_t *ctx, asn_per_data_t *pd) { */ static asn_dec_rval_t -uper_sot_suck(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td, - asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { - asn_dec_rval_t rv; +uper_sot_suck(const asn_codec_ctx_t *ctx, const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, void **sptr, + asn_per_data_t *pd) { + asn_dec_rval_t rv; (void)ctx; (void)td; @@ -324,7 +342,7 @@ uper_ugot_refill(asn_per_data_t *pd) { return -1; } - next_chunk_bytes = uper_get_length(oldpd, -1, &arg->repeat); + next_chunk_bytes = uper_get_length(oldpd, -1, 0, &arg->repeat); ASN_DEBUG("Open type LENGTH %ld bytes at off %ld, repeat %ld", (long)next_chunk_bytes, (long)oldpd->moved, (long)arg->repeat); if(next_chunk_bytes < 0) return -1; @@ -351,7 +369,7 @@ uper_ugot_refill(asn_per_data_t *pd) { pd->buffer = oldpd->buffer; pd->nboff = oldpd->nboff; ASN_DEBUG("Refilled pd%s old%s", - per_data_string(pd), per_data_string(oldpd)); + asn_bit_data_string(pd), asn_bit_data_string(oldpd)); return 0; } diff --git a/libs/smux/per_support.c b/libs/smux/per_support.c index 14b4c4c7..8f4d4604 100644 --- a/libs/smux/per_support.c +++ b/libs/smux/per_support.c @@ -1,190 +1,46 @@ /* - * Copyright (c) 2005-2014 Lev Walkin . - * All rights reserved. + * Copyright (c) 2005-2017 Lev Walkin . All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ #include #include #include -char * -per_data_string(asn_per_data_t *pd) { - static char buf[2][32]; - static int n; - n = (n+1) % 2; - snprintf(buf[n], sizeof(buf[n]), - "{m=%ld span %+ld[%d..%d] (%d)}", - (long)pd->moved, - (((long)pd->buffer) & 0xf), - (int)pd->nboff, (int)pd->nbits, - (int)(pd->nbits - pd->nboff)); - return buf[n]; -} - -void -per_get_undo(asn_per_data_t *pd, int nbits) { - if((ssize_t)pd->nboff < nbits) { - assert((ssize_t)pd->nboff < nbits); - } else { - pd->nboff -= nbits; - pd->moved -= nbits; - } -} - -/* - * Extract a small number of bits (<= 31) from the specified PER data pointer. - */ -int32_t -per_get_few_bits(asn_per_data_t *pd, int nbits) { - size_t off; /* Next after last bit offset */ - ssize_t nleft; /* Number of bits left in this stream */ - uint32_t accum; - const uint8_t *buf; - - if(nbits < 0) - return -1; - - nleft = pd->nbits - pd->nboff; - if(nbits > nleft) { - int32_t tailv, vhead; - if(!pd->refill || nbits > 31) return -1; - /* Accumulate unused bytes before refill */ - ASN_DEBUG("Obtain the rest %d bits (want %d)", - (int)nleft, (int)nbits); - tailv = per_get_few_bits(pd, nleft); - if(tailv < 0) return -1; - /* Refill (replace pd contents with new data) */ - if(pd->refill(pd)) - return -1; - nbits -= nleft; - vhead = per_get_few_bits(pd, nbits); - /* Combine the rest of previous pd with the head of new one */ - tailv = (tailv << nbits) | vhead; /* Could == -1 */ - return tailv; - } - - /* - * Normalize position indicator. - */ - if(pd->nboff >= 8) { - pd->buffer += (pd->nboff >> 3); - pd->nbits -= (pd->nboff & ~0x07); - pd->nboff &= 0x07; - } - pd->moved += nbits; - pd->nboff += nbits; - off = pd->nboff; - buf = pd->buffer; - - /* - * Extract specified number of bits. - */ - if(off <= 8) - accum = nbits ? (buf[0]) >> (8 - off) : 0; - else if(off <= 16) - accum = ((buf[0] << 8) + buf[1]) >> (16 - off); - else if(off <= 24) - accum = ((buf[0] << 16) + (buf[1] << 8) + buf[2]) >> (24 - off); - else if(off <= 31) - accum = ((buf[0] << 24) + (buf[1] << 16) - + (buf[2] << 8) + (buf[3])) >> (32 - off); - else if(nbits <= 31) { - asn_per_data_t tpd = *pd; - /* Here are we with our 31-bits limit plus 1..7 bits offset. */ - per_get_undo(&tpd, nbits); - /* The number of available bits in the stream allow - * for the following operations to take place without - * invoking the ->refill() function */ - accum = per_get_few_bits(&tpd, nbits - 24) << 24; - accum |= per_get_few_bits(&tpd, 24); - } else { - per_get_undo(pd, nbits); - return -1; - } - - accum &= (((uint32_t)1 << nbits) - 1); - - ASN_DEBUG(" [PER got %2d<=%2d bits => span %d %+ld[%d..%d]:%02x (%d) => 0x%x]", - (int)nbits, (int)nleft, - (int)pd->moved, - (((long)pd->buffer) & 0xf), - (int)pd->nboff, (int)pd->nbits, - ((pd->buffer != NULL)?pd->buffer[0]:0), - (int)(pd->nbits - pd->nboff), - (int)accum); - - return accum; -} - /* - * Extract a large number of bits from the specified PER data pointer. - */ -int -per_get_many_bits(asn_per_data_t *pd, uint8_t *dst, int alright, int nbits) { - int32_t value; - - if(alright && (nbits & 7)) { - /* Perform right alignment of a first few bits */ - value = per_get_few_bits(pd, nbits & 0x07); - if(value < 0) return -1; - *dst++ = value; /* value is already right-aligned */ - nbits &= ~7; - } - - while(nbits) { - if(nbits >= 24) { - value = per_get_few_bits(pd, 24); - if(value < 0) return -1; - *(dst++) = value >> 16; - *(dst++) = value >> 8; - *(dst++) = value; - nbits -= 24; - } else { - value = per_get_few_bits(pd, nbits); - if(value < 0) return -1; - if(nbits & 7) { /* implies left alignment */ - value <<= 8 - (nbits & 7), - nbits += 8 - (nbits & 7); - if(nbits > 24) - *dst++ = value >> 24; - } - if(nbits > 16) - *dst++ = value >> 16; - if(nbits > 8) - *dst++ = value >> 8; - *dst++ = value; - break; - } - } - - return 0; -} - -/* - * Get the length "n" from the stream. + * X.691-201508 #10.9 General rules for encoding a length determinant. + * Get the optionally constrained length "n" from the stream. */ ssize_t -uper_get_length(asn_per_data_t *pd, int ebits, int *repeat) { - ssize_t value; +uper_get_length(asn_per_data_t *pd, int ebits, size_t lower_bound, + int *repeat) { + ssize_t value; - *repeat = 0; + *repeat = 0; - if(ebits >= 0) return per_get_few_bits(pd, ebits); + /* #11.9.4.1 Encoding if constrained (according to effective bits) */ + if(ebits >= 0 && ebits <= 16) { + value = per_get_few_bits(pd, ebits); + if(value >= 0) value += lower_bound; + return value; + } value = per_get_few_bits(pd, 8); - if(value < 0) return -1; - if((value & 128) == 0) /* #10.9.3.6 */ - return (value & 0x7F); - if((value & 64) == 0) { /* #10.9.3.7 */ - value = ((value & 63) << 8) | per_get_few_bits(pd, 8); - if(value < 0) return -1; - return value; - } - value &= 63; /* this is "m" from X.691, #10.9.3.8 */ - if(value < 1 || value > 4) - return -1; - *repeat = 1; - return (16384 * value); + if((value & 0x80) == 0) { /* #11.9.3.6 */ + return (value & 0x7F); + } else if((value & 0x40) == 0) { /* #11.9.3.7 */ + /* bit 8 ... set to 1 and bit 7 ... set to zero */ + value = ((value & 0x3f) << 8) | per_get_few_bits(pd, 8); + return value; /* potential -1 from per_get_few_bits passes through. */ + } else if(value < 0) { + ASN_DEBUG("END of stream reached for PER"); + return -1; + } + value &= 0x3f; /* this is "m" from X.691, #11.9.3.8 */ + if(value < 1 || value > 4) { + return -1; /* Prohibited by #11.9.3.8 */ + } + *repeat = 1; + return (16384 * value); } /* @@ -205,7 +61,7 @@ uper_get_nslength(asn_per_data_t *pd) { return length; } else { int repeat; - length = uper_get_length(pd, -1, &repeat); + length = uper_get_length(pd, -1, 0, &repeat); if(length >= 0 && !repeat) return length; return -1; /* Error, or do not support >16K extensions */ } @@ -291,171 +147,48 @@ int uper_get_constrained_whole_number(asn_per_data_t *pd, unsigned long *out_val /* X.691-2008/11, #11.5.6 -> #11.3 */ -int uper_put_constrained_whole_number_s(asn_per_outp_t *po, long v, int nbits) { - /* - * Assume signed number can be safely coerced into - * unsigned of the same range. - * The following testing code will likely be optimized out - * by compiler if it is true. - */ - unsigned long uvalue1 = ULONG_MAX; - long svalue = uvalue1; - unsigned long uvalue2 = svalue; - assert(uvalue1 == uvalue2); - return uper_put_constrained_whole_number_u(po, v, nbits); -} - -int uper_put_constrained_whole_number_u(asn_per_outp_t *po, unsigned long v, int nbits) { - if(nbits <= 31) { - return per_put_few_bits(po, v, nbits); - } else { - /* Put higher portion first, followed by lower 31-bit */ - if(uper_put_constrained_whole_number_u(po, v >> 31, nbits - 31)) - return -1; - return per_put_few_bits(po, v, 31); - } -} - -/* - * Put a small number of bits (<= 31). - */ int -per_put_few_bits(asn_per_outp_t *po, uint32_t bits, int obits) { - size_t off; /* Next after last bit offset */ - size_t omsk; /* Existing last byte meaningful bits mask */ - uint8_t *buf; - - if(obits <= 0 || obits >= 32) return obits ? -1 : 0; - - ASN_DEBUG("[PER put %d bits %x to %p+%d bits]", - obits, (int)bits, po->buffer, (int)po->nboff); - - /* - * Normalize position indicator. - */ - if(po->nboff >= 8) { - po->buffer += (po->nboff >> 3); - po->nbits -= (po->nboff & ~0x07); - po->nboff &= 0x07; - } - - /* - * Flush whole-bytes output, if necessary. - */ - if(po->nboff + obits > po->nbits) { - int complete_bytes = (po->buffer - po->tmpspace); - ASN_DEBUG("[PER output %ld complete + %ld]", - (long)complete_bytes, (long)po->flushed_bytes); - if(po->outper(po->tmpspace, complete_bytes, po->op_key) < 0) - return -1; - if(po->nboff) - po->tmpspace[0] = po->buffer[0]; - po->buffer = po->tmpspace; - po->nbits = 8 * sizeof(po->tmpspace); - po->flushed_bytes += complete_bytes; - } - - /* - * Now, due to sizeof(tmpspace), we are guaranteed large enough space. - */ - buf = po->buffer; - omsk = ~((1 << (8 - po->nboff)) - 1); - off = (po->nboff + obits); - - /* Clear data of debris before meaningful bits */ - bits &= (((uint32_t)1 << obits) - 1); - - ASN_DEBUG("[PER out %d %u/%x (t=%d,o=%d) %x&%x=%x]", obits, - (int)bits, (int)bits, - (int)po->nboff, (int)off, - buf[0], (int)(omsk&0xff), - (int)(buf[0] & omsk)); - - if(off <= 8) /* Completely within 1 byte */ - po->nboff = off, - bits <<= (8 - off), - buf[0] = (buf[0] & omsk) | bits; - else if(off <= 16) - po->nboff = off, - bits <<= (16 - off), - buf[0] = (buf[0] & omsk) | (bits >> 8), - buf[1] = bits; - else if(off <= 24) - po->nboff = off, - bits <<= (24 - off), - buf[0] = (buf[0] & omsk) | (bits >> 16), - buf[1] = bits >> 8, - buf[2] = bits; - else if(off <= 31) - po->nboff = off, - bits <<= (32 - off), - buf[0] = (buf[0] & omsk) | (bits >> 24), - buf[1] = bits >> 16, - buf[2] = bits >> 8, - buf[3] = bits; - else { - per_put_few_bits(po, bits >> (obits - 24), 24); - per_put_few_bits(po, bits, obits - 24); - } - - ASN_DEBUG("[PER out %u/%x => %02x buf+%ld]", - (int)bits, (int)bits, buf[0], - (long)(po->buffer - po->tmpspace)); - - return 0; -} - - -/* - * Output a large number of bits. - */ -int -per_put_many_bits(asn_per_outp_t *po, const uint8_t *src, int nbits) { - - while(nbits) { - uint32_t value; - - if(nbits >= 24) { - value = (src[0] << 16) | (src[1] << 8) | src[2]; - src += 3; - nbits -= 24; - if(per_put_few_bits(po, value, 24)) - return -1; - } else { - value = src[0]; - if(nbits > 8) - value = (value << 8) | src[1]; - if(nbits > 16) - value = (value << 8) | src[2]; - if(nbits & 0x07) - value >>= (8 - (nbits & 0x07)); - if(per_put_few_bits(po, value, nbits)) - return -1; - break; - } - } - - return 0; +uper_put_constrained_whole_number_u(asn_per_outp_t *po, unsigned long v, + int nbits) { + if(nbits <= 31) { + return per_put_few_bits(po, v, nbits); + } else { + /* Put higher portion first, followed by lower 31-bit */ + if(uper_put_constrained_whole_number_u(po, v >> 31, nbits - 31)) + return -1; + return per_put_few_bits(po, v, 31); + } } /* + * X.691 (08/2015) #11.9 "General rules for encoding a length determinant" * Put the length "n" (or part of it) into the stream. */ ssize_t -uper_put_length(asn_per_outp_t *po, size_t length) { - - if(length <= 127) /* #10.9.3.6 */ - return per_put_few_bits(po, length, 8) - ? -1 : (ssize_t)length; - else if(length < 16384) /* #10.9.3.7 */ - return per_put_few_bits(po, length|0x8000, 16) - ? -1 : (ssize_t)length; - - length >>= 14; - if(length > 4) length = 4; +uper_put_length(asn_per_outp_t *po, size_t length, int *need_eom) { + int dummy = 0; + if(!need_eom) need_eom = &dummy; + + if(length <= 127) { /* #11.9.3.6 */ + *need_eom = 0; + return per_put_few_bits(po, length, 8) + ? -1 : (ssize_t)length; + } else if(length < 16384) { /* #10.9.3.7 */ + *need_eom = 0; + return per_put_few_bits(po, length|0x8000, 16) + ? -1 : (ssize_t)length; + } + + *need_eom = 0 == (length & 16383); + length >>= 14; + if(length > 4) { + *need_eom = 0; + length = 4; + } + + return per_put_few_bits(po, 0xC0 | length, 8) + ? -1 : (ssize_t)(length << 14); - return per_put_few_bits(po, 0xC0 | length, 8) - ? -1 : (ssize_t)(length << 14); } @@ -466,18 +199,97 @@ uper_put_length(asn_per_outp_t *po, size_t length) { */ int uper_put_nslength(asn_per_outp_t *po, size_t length) { + if(length <= 64) { + /* #11.9.3.4 */ + if(length == 0) return -1; + return per_put_few_bits(po, length - 1, 7) ? -1 : 0; + } else { + int need_eom = 0; + if(uper_put_length(po, length, &need_eom) != (ssize_t)length + || need_eom) { + /* This might happen in case of >16K extensions */ + return -1; + } + } + + return 0; +} - if(length <= 64) { - /* #10.9.3.4 */ - if(length == 0) return -1; - return per_put_few_bits(po, length-1, 7) ? -1 : 0; - } else { - if(uper_put_length(po, length) != (ssize_t)length) { - /* This might happen in case of >16K extensions */ - return -1; - } - } +static int +per__long_range(long lb, long ub, unsigned long *range_r) { + unsigned long bounds_range; + if((ub < 0) == (lb < 0)) { + bounds_range = ub - lb; + } else if(lb < 0) { + assert(ub >= 0); + bounds_range = 1 + ((unsigned long)ub + (unsigned long)-(lb + 1)); + } else { + assert(!"Unreachable"); + return -1; + } + *range_r = bounds_range; + return 0; +} - return 0; +int +per_long_range_rebase(long v, long lb, long ub, unsigned long *output) { + unsigned long range; + + assert(lb <= ub); + + if(v < lb || v > ub || per__long_range(lb, ub, &range) < 0) { + /* Range error. */ + return -1; + } + + /* + * Fundamentally what we're doing is returning (v-lb). + * However, this triggers undefined behavior when the word width + * of signed (v) is the same as the size of unsigned (*output). + * In practice, it triggers the UndefinedSanitizer. Therefore we shall + * compute the ranges accurately to avoid C's undefined behavior. + */ + if((v < 0) == (lb < 0)) { + *output = v-lb; + return 0; + } else if(v < 0) { + unsigned long rebased = 1 + (unsigned long)-(v+1) + (unsigned long)lb; + assert(rebased <= range); /* By construction */ + *output = rebased; + return 0; + } else if(lb < 0) { + unsigned long rebased = 1 + (unsigned long)-(lb+1) + (unsigned long)v; + assert(rebased <= range); /* By construction */ + *output = rebased; + return 0; + } else { + assert(!"Unreachable"); + return -1; + } } +int +per_long_range_unrebase(unsigned long inp, long lb, long ub, long *outp) { + unsigned long range; + + if(per__long_range(lb, ub, &range) != 0) { + return -1; + } + + if(inp > range) { + /* + * We can encode something in the given number of bits that technically + * exceeds the range. This is an avenue for security errors, + * so we don't allow that. + */ + return -1; + } + + if(inp <= LONG_MAX) { + *outp = (long)inp + lb; + } else { + *outp = (lb + LONG_MAX + 1) + (long)((inp - LONG_MAX) - 1); + } + + return 0; +} diff --git a/libs/smux/regen.sh b/libs/smux/regen.sh index 2624ffd1..926ed30d 100755 --- a/libs/smux/regen.sh +++ b/libs/smux/regen.sh @@ -8,5 +8,9 @@ ASN1C_FLAGS="${ASN1C_FLAGS:-""} -fcompound-names -fwide-types" ${ASN1C} ${ASN1C_FLAGS} RFC1213-MIB.asn1 RFC1155-SMI.asn1 RFC1157-SNMP.asn1 SMUX.asn1 mv *.h include/stg/ -rm Makefile.am.sample -rm converter-sample.c +rm -f Makefile.am.sample +rm -f converter-sample.c +rm -f Makefile.am.asn1convert +rm -f Makefile.am.libasncodec +rm -f converter-example.mk +rm -f converter-example.c diff --git a/libs/smux/xer_decoder.c b/libs/smux/xer_decoder.c index 299a7c1e..5b87703a 100644 --- a/libs/smux/xer_decoder.c +++ b/libs/smux/xer_decoder.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2005 Lev Walkin . All rights reserved. + * Copyright (c) 2004-2017 Lev Walkin . All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ #include @@ -11,9 +11,10 @@ * Decode the XER encoding of a given type. */ asn_dec_rval_t -xer_decode(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, - void **struct_ptr, const void *buffer, size_t size) { - asn_codec_ctx_t s_codec_ctx; +xer_decode(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *td, void **struct_ptr, + const void *buffer, size_t size) { + asn_codec_ctx_t s_codec_ctx; /* * Stack checker requires that the codec context @@ -34,7 +35,7 @@ xer_decode(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, /* * Invoke type-specific decoder. */ - return td->xer_decoder(opt_codec_ctx, td, struct_ptr, 0, buffer, size); + return td->op->xer_decoder(opt_codec_ctx, td, struct_ptr, 0, buffer, size); } @@ -85,8 +86,8 @@ xer_next_token(int *stateContext, const void *buffer, size_t size, pxer_chunk_ty *ch_type = PXER_TEXT; break; case PXML_TAG: - *ch_type = PXER_WMORE; - return 0; /* Want more */ + *ch_type = PXER_WMORE; + return 0; /* Want more */ case PXML_TAG_END: *ch_type = PXER_TAG; break; @@ -201,7 +202,7 @@ xer_check_tag(const void *buf_ptr, int size, const char *need_tag) { * Generalized function for decoding the primitive values. */ asn_dec_rval_t -xer_decode_general(asn_codec_ctx_t *opt_codec_ctx, +xer_decode_general(const asn_codec_ctx_t *opt_codec_ctx, asn_struct_ctx_t *ctx, /* Type decoder context */ void *struct_key, const char *xml_tag, /* Expected XML tag */ diff --git a/libs/smux/xer_encoder.c b/libs/smux/xer_encoder.c index 46065758..dff3c44e 100644 --- a/libs/smux/xer_encoder.c +++ b/libs/smux/xer_encoder.c @@ -10,10 +10,11 @@ * The XER encoder of any type. May be invoked by the application. */ asn_enc_rval_t -xer_encode(asn_TYPE_descriptor_t *td, void *sptr, - enum xer_encoder_flags_e xer_flags, - asn_app_consume_bytes_f *cb, void *app_key) { - asn_enc_rval_t er, tmper; +xer_encode(const asn_TYPE_descriptor_t *td, const void *sptr, + enum xer_encoder_flags_e xer_flags, asn_app_consume_bytes_f *cb, + void *app_key) { + asn_enc_rval_t er = {0, 0, 0}; + asn_enc_rval_t tmper; const char *mname; size_t mlen; int xcan = (xer_flags & XER_F_CANONICAL) ? 1 : 2; @@ -25,13 +26,12 @@ xer_encode(asn_TYPE_descriptor_t *td, void *sptr, ASN__CALLBACK3("<", 1, mname, mlen, ">", 1); - tmper = td->xer_encoder(td, sptr, 1, xer_flags, cb, app_key); + tmper = td->op->xer_encoder(td, sptr, 1, xer_flags, cb, app_key); if(tmper.encoded == -1) return tmper; + er.encoded += tmper.encoded; ASN__CALLBACK3("\n", xcan); - er.encoded = 4 + xcan + (2 * mlen) + tmper.encoded; - ASN__ENCODED_OK(er); cb_failed: ASN__ENCODE_FAILED; @@ -52,8 +52,8 @@ xer__print2fp(const void *buffer, size_t size, void *app_key) { } int -xer_fprint(FILE *stream, asn_TYPE_descriptor_t *td, void *sptr) { - asn_enc_rval_t er; +xer_fprint(FILE *stream, const asn_TYPE_descriptor_t *td, const void *sptr) { + asn_enc_rval_t er; if(!stream) stream = stdout; if(!td || !sptr) @@ -65,3 +65,173 @@ xer_fprint(FILE *stream, asn_TYPE_descriptor_t *td, void *sptr) { return fflush(stream); } + +struct xer_buffer { + char *buffer; + size_t buffer_size; + size_t allocated_size; +}; + +static int +xer__buffer_append(const void *buffer, size_t size, void *app_key) { + struct xer_buffer *xb = app_key; + + while(xb->buffer_size + size + 1 > xb->allocated_size) { + size_t new_size = 2 * (xb->allocated_size ? xb->allocated_size : 64); + char *new_buf = MALLOC(new_size); + if(!new_buf) return -1; + if (xb->buffer) { + memcpy(new_buf, xb->buffer, xb->buffer_size); + } + FREEMEM(xb->buffer); + xb->buffer = new_buf; + xb->allocated_size = new_size; + } + + memcpy(xb->buffer + xb->buffer_size, buffer, size); + xb->buffer_size += size; + xb->buffer[xb->buffer_size] = '\0'; + return 0; +} + +enum xer_equivalence_e +xer_equivalent(const struct asn_TYPE_descriptor_s *td, const void *struct1, + const void *struct2, FILE *opt_debug_stream) { + struct xer_buffer xb1 = {0, 0, 0}; + struct xer_buffer xb2 = {0, 0, 0}; + asn_enc_rval_t e1, e2; + asn_dec_rval_t rval; + void *sptr = NULL; + + if(!td || !struct1 || !struct2) { + if(opt_debug_stream) { + if(!td) fprintf(opt_debug_stream, "Type descriptor missing\n"); + if(!struct1) fprintf(opt_debug_stream, "Structure 1 missing\n"); + if(!struct2) fprintf(opt_debug_stream, "Structure 2 missing\n"); + } + return XEQ_FAILURE; + } + + e1 = xer_encode(td, struct1, XER_F_BASIC, xer__buffer_append, &xb1); + if(e1.encoded == -1) { + if(opt_debug_stream) { + fprintf(stderr, "XER Encoding of %s failed\n", td->name); + } + FREEMEM(xb1.buffer); + return XEQ_ENCODE1_FAILED; + } + + e2 = xer_encode(td, struct2, XER_F_BASIC, xer__buffer_append, &xb2); + if(e2.encoded == -1) { + if(opt_debug_stream) { + fprintf(stderr, "XER Encoding of %s failed\n", td->name); + } + FREEMEM(xb1.buffer); + FREEMEM(xb2.buffer); + return XEQ_ENCODE1_FAILED; + } + + if(xb1.buffer_size != xb2.buffer_size + || memcmp(xb1.buffer, xb2.buffer, xb1.buffer_size) != 0) { + if(opt_debug_stream) { + fprintf(opt_debug_stream, + "Structures XER-encoded into different byte streams:\n=== " + "Structure 1 ===\n%s\n=== Structure 2 ===\n%s\n", + xb1.buffer, xb2.buffer); + } + FREEMEM(xb1.buffer); + FREEMEM(xb2.buffer); + return XEQ_DIFFERENT; + } else { + if(opt_debug_stream) { + fprintf(opt_debug_stream, + "Both structures encoded into the same XER byte stream " + "of size %" ASN_PRI_SIZE ":\n%s", + xb1.buffer_size, xb1.buffer); + } + } + + rval = xer_decode(NULL, td, (void **)&sptr, xb1.buffer, + xb1.buffer_size); + switch(rval.code) { + case RC_OK: + break; + case RC_WMORE: + if(opt_debug_stream) { + fprintf(opt_debug_stream, + "Structure %s XER decode unexpectedly requires " + "more data:\n%s\n", + td->name, xb1.buffer); + } + /* Fall through */ + case RC_FAIL: + default: + if(opt_debug_stream) { + fprintf(opt_debug_stream, + "Structure %s XER decoding resulted in failure.\n", + td->name); + } + ASN_STRUCT_FREE(*td, sptr); + FREEMEM(xb1.buffer); + FREEMEM(xb2.buffer); + return XEQ_DECODE_FAILED; + } + + if(rval.consumed != xb1.buffer_size + && ((rval.consumed > xb1.buffer_size) + || xer_whitespace_span(xb1.buffer + rval.consumed, + xb1.buffer_size - rval.consumed) + != (xb1.buffer_size - rval.consumed))) { + if(opt_debug_stream) { + fprintf(opt_debug_stream, + "Round-trip decode of %s required less bytes (%" ASN_PRI_SIZE ") than " + "encoded (%" ASN_PRI_SIZE ")\n", + td->name, rval.consumed, xb1.buffer_size); + } + ASN_STRUCT_FREE(*td, sptr); + FREEMEM(xb1.buffer); + FREEMEM(xb2.buffer); + return XEQ_ROUND_TRIP_FAILED; + } + + /* + * Reuse xb2 to encode newly decoded structure. + */ + FREEMEM(xb2.buffer); + memset(&xb2, 0, sizeof(xb2)); + + e2 = xer_encode(td, sptr, XER_F_BASIC, xer__buffer_append, &xb2); + if(e2.encoded == -1) { + if(opt_debug_stream) { + fprintf(stderr, "XER Encoding of round-trip decode of %s failed\n", + td->name); + } + ASN_STRUCT_FREE(*td, sptr); + FREEMEM(xb1.buffer); + FREEMEM(xb2.buffer); + return XEQ_ROUND_TRIP_FAILED; + } + + ASN_STRUCT_FREE(*td, sptr); + sptr = 0; + + if(xb1.buffer_size != xb2.buffer_size + || memcmp(xb1.buffer, xb2.buffer, xb1.buffer_size) != 0) { + if(opt_debug_stream) { + fprintf(opt_debug_stream, + "XER Encoding of round-trip decode of %s resulted in " + "different byte stream:\n" + "=== Original ===\n%s\n" + "=== Round-tripped ===\n%s\n", + xb1.buffer, xb2.buffer, td->name); + } + FREEMEM(xb1.buffer); + FREEMEM(xb2.buffer); + return XEQ_ROUND_TRIP_FAILED; + } + + FREEMEM(xb1.buffer); + FREEMEM(xb2.buffer); + return XEQ_SUCCESS; +} + diff --git a/projects/stargazer/plugins/other/smux/types.cpp b/projects/stargazer/plugins/other/smux/types.cpp index 8132bca0..5dc19b6f 100644 --- a/projects/stargazer/plugins/other/smux/types.cpp +++ b/projects/stargazer/plugins/other/smux/types.cpp @@ -8,11 +8,11 @@ namespace { -bool ParseArcs(const char * str, ptrdiff_t length, unsigned * a, size_t * pos); -bool StringToArcs(const char * str, size_t length, std::vector & arcs); -bool AppendToArcs(const char * str, size_t length, std::vector & arcs); +bool ParseArcs(const char * str, ptrdiff_t length, uint32_t * a, size_t * pos); +bool StringToArcs(const char * str, size_t length, std::vector & arcs); +bool AppendToArcs(const char * str, size_t length, std::vector & arcs); -bool ParseArcs(const char * str, ptrdiff_t length, unsigned * a, size_t * pos) +bool ParseArcs(const char * str, ptrdiff_t length, uint32_t * a, size_t * pos) { if (length == 0) return false; @@ -23,7 +23,7 @@ size_t arcPos = 0; while ((left - str) < length) { char * p = NULL; - unsigned arc = static_cast(strtoul(left, &p, 10)); + uint32_t arc = static_cast(strtoul(left, &p, 10)); if (p == left) return false; a[arcPos++] = arc; @@ -35,9 +35,9 @@ while ((left - str) < length) return true; } -bool StringToArcs(const char * str, size_t length, std::vector & arcs) +bool StringToArcs(const char * str, size_t length, std::vector & arcs) { -unsigned a[1024]; +uint32_t a[1024]; size_t pos = 0; if (!ParseArcs(str, length, a, &pos)) @@ -47,9 +47,9 @@ arcs.assign(a, a + pos); return true; } -bool AppendToArcs(const char * str, size_t length, std::vector & arcs) +bool AppendToArcs(const char * str, size_t length, std::vector & arcs) { -unsigned a[1024]; +uint32_t a[1024]; size_t pos = 0; if (!ParseArcs(str, length, a, &pos)) @@ -75,28 +75,28 @@ if (!StringToArcs(str, length, arcs)) throw std::runtime_error("Invalid oid"); } -OID::OID(const std::vector & a) +OID::OID(const std::vector & a) : arcs(a) { } -OID::OID(const unsigned * a, size_t length) +OID::OID(const uint32_t * a, size_t length) : arcs() { -std::vector newArcs(a, a + length); +std::vector newArcs(a, a + length); arcs.swap(newArcs); } OID::OID(OBJECT_IDENTIFIER_t * oid) : arcs() { -unsigned a[1024]; -int count = OBJECT_IDENTIFIER_get_arcs(oid, a, sizeof(a[0]), 1024); +uint32_t a[1024]; +int count = OBJECT_IDENTIFIER_get_arcs(oid, a, 1024); if (count > 1024) throw std::runtime_error("OID is too long"); -std::vector newArcs(a, a + count); +std::vector newArcs(a, a + count); arcs.swap(newArcs); } @@ -123,19 +123,19 @@ if (!AppendToArcs(suffix.c_str(), suffix.length(), arcs)) return true; } -bool OID::addSuffix(const unsigned * suffix, size_t length) +bool OID::addSuffix(const uint32_t * suffix, size_t length) { std::copy(suffix, suffix + length, std::back_inserter(arcs)); return true; } -bool OID::addSuffix(const std::vector & suffix) +bool OID::addSuffix(const std::vector & suffix) { std::copy(suffix.begin(), suffix.end(), std::back_inserter(arcs)); return true; } -bool OID::addSuffix(unsigned a, unsigned b) +bool OID::addSuffix(uint32_t a, uint32_t b) { arcs.push_back(a); arcs.push_back(b); @@ -158,7 +158,7 @@ if (!oid.addSuffix(suffix)) return oid; } -OID OID::copyWithSuffix(const unsigned * suffix, size_t length) const +OID OID::copyWithSuffix(const uint32_t * suffix, size_t length) const { OID oid(*this); if (!oid.addSuffix(suffix, length)) @@ -166,7 +166,7 @@ if (!oid.addSuffix(suffix, length)) return oid; } -OID OID::copyWithSuffix(const std::vector & suffix) const +OID OID::copyWithSuffix(const std::vector & suffix) const { OID oid(*this); if (!oid.addSuffix(suffix)) @@ -174,7 +174,7 @@ if (!oid.addSuffix(suffix)) return oid; } -OID OID::copyWithSuffix(unsigned a, unsigned b) const +OID OID::copyWithSuffix(uint32_t a, uint32_t b) const { OID oid(*this); oid.addSuffix(a, b); @@ -191,7 +191,7 @@ return stream.str(); void OID::ToOID(OBJECT_IDENTIFIER_t * oid) const { -OBJECT_IDENTIFIER_set_arcs(oid, &arcs.front(), sizeof(unsigned), static_cast(arcs.size())); +OBJECT_IDENTIFIER_set_arcs(oid, &arcs.front(), static_cast(arcs.size())); } OID & OID::operator=(const OID & rvalue) diff --git a/projects/stargazer/plugins/other/smux/types.h b/projects/stargazer/plugins/other/smux/types.h index f6b145f7..e7fcbeef 100644 --- a/projects/stargazer/plugins/other/smux/types.h +++ b/projects/stargazer/plugins/other/smux/types.h @@ -14,26 +14,26 @@ class OID public: explicit OID(const std::string & str); OID(const char * str, size_t length); - explicit OID(const std::vector & arcs); - OID(const unsigned * arcs, size_t length); + explicit OID(const std::vector & arcs); + OID(const uint32_t * arcs, size_t length); explicit OID(OBJECT_IDENTIFIER_t * oid); OID(const OID & rvalue); ~OID(); bool addSuffix(const char * suffix, size_t length); bool addSuffix(const std::string & suffix); - bool addSuffix(const unsigned * suffix, size_t length); - bool addSuffix(const std::vector & suffix); - bool addSuffix(unsigned a, unsigned b); + bool addSuffix(const uint32_t * suffix, size_t length); + bool addSuffix(const std::vector & suffix); + bool addSuffix(uint32_t a, uint32_t b); OID copyWithSuffix(const char * suffix, size_t length) const; OID copyWithSuffix(const std::string & suffix) const; - OID copyWithSuffix(const unsigned * suffix, size_t length) const; - OID copyWithSuffix(const std::vector & suffix) const; - OID copyWithSuffix(unsigned a, unsigned b) const; + OID copyWithSuffix(const uint32_t * suffix, size_t length) const; + OID copyWithSuffix(const std::vector & suffix) const; + OID copyWithSuffix(uint32_t a, uint32_t b) const; std::string ToString() const; - const std::vector & ToVector() const { return arcs; } + const std::vector & ToVector() const { return arcs; } void ToOID(OBJECT_IDENTIFIER_t * oid) const; OID & operator=(const OID & rvalue); @@ -48,7 +48,7 @@ class OID friend std::ostream & operator<<(std::ostream & stream, const OID & oid); private: - std::vector arcs; + std::vector arcs; }; inline diff --git a/projects/stargazer/plugins/other/smux/utils.cpp b/projects/stargazer/plugins/other/smux/utils.cpp index a2c1a47f..d1a0c281 100644 --- a/projects/stargazer/plugins/other/smux/utils.cpp +++ b/projects/stargazer/plugins/other/smux/utils.cpp @@ -20,7 +20,7 @@ bool String2OI(const std::string & str, OBJECT_IDENTIFIER_t * oi) { size_t left = 0, pos = 0, arcPos = 0; -int arcs[1024]; +uint32_t arcs[1024]; pos = str.find_first_of('.', left); if (pos == 0) { @@ -47,7 +47,7 @@ if (left < str.length()) } arcs[arcPos++] = arc; } -OBJECT_IDENTIFIER_set_arcs(oi, arcs, sizeof(arcs[0]), static_cast(arcPos)); +OBJECT_IDENTIFIER_set_arcs(oi, arcs, static_cast(arcPos)); return true; } @@ -125,7 +125,7 @@ return true; bool SendRReqPDU(int fd) { -int oid[] = {1, 3, 6, 1, 4, 1, 38313, 1}; +uint32_t oid[] = {1, 3, 6, 1, 4, 1, 38313, 1}; asn_enc_rval_t error; RReqPDU_t msg; @@ -135,7 +135,6 @@ msg.priority = 0; asn_long2INTEGER(&msg.operation, RReqPDU__operation_readOnly); OBJECT_IDENTIFIER_set_arcs(&msg.subtree, oid, - sizeof(oid[0]), 8); char buffer[1024]; -- 2.43.2