Code Search for Developers
 
 
  

asn1_8c-source.html from net-snmp at Krugle


Show asn1_8c-source.html syntax highlighted

<!--#set var="section" value="development" -->
<!--#include virtual="/page-top.html" -->
<!-- CONTENT START -->
  <!-- Generated by Doxygen 1.3.9.1 -->

  <div class="qindex">
    <a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class=
    "qindex" href="annotated.html">Data&nbsp;Structures</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class=
    "qindex" href="functions.html">Data&nbsp;Fields</a> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a> | <a class=
    "qindex" href="examples.html">Examples</a>
  </div>

  <div class="nav">
    <a class="el" href="dir_000005.html">snmplib</a>
  </div>

  <h1>asn1.c</h1>

  <div class="fragment">
    <pre class="fragment">
00001 <span class="comment">/*</span>
00002 <span class="comment"> * Abstract Syntax Notation One, ASN.1</span>
00003 <span class="comment"> * As defined in ISO/IS 8824 and ISO/IS 8825</span>
00004 <span class="comment"> * This implements a subset of the above International Standards that</span>
00005 <span class="comment"> * is sufficient to implement SNMP.</span>
00006 <span class="comment"> *</span>
00007 <span class="comment"> * Encodes abstract data types into a machine independent stream of bytes.</span>
00008 <span class="comment"> *</span>
00009 <span class="comment"> */</span>
00010 <span class="comment">/**********************************************************************</span>
00011 <span class="comment">        Copyright 1988, 1989, 1991, 1992 by Carnegie Mellon University</span>
00012 
00013 <span class="comment">                      All Rights Reserved</span>
00014 
00015 <span class="comment">Permission to use, copy, modify, and distribute this software and its </span>
00016 <span class="comment">documentation for any purpose and without fee is hereby granted, </span>
00017 <span class="comment">provided that the above copyright notice appear in all copies and that</span>
00018 <span class="comment">both that copyright notice and this permission notice appear in </span>
00019 <span class="comment">supporting documentation, and that the name of CMU not be</span>
00020 <span class="comment">used in advertising or publicity pertaining to distribution of the</span>
00021 <span class="comment">software without specific, written prior permission.  </span>
00022 
00023 <span class="comment">CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING</span>
00024 <span class="comment">ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL</span>
00025 <span class="comment">CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR</span>
00026 <span class="comment">ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,</span>
00027 <span class="comment">WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,</span>
00028 <span class="comment">ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS</span>
00029 <span class="comment">SOFTWARE.</span>
00030 <span class="comment">******************************************************************/</span>
00156 <span class="preprocessor">#include &lt;net-snmp/net-snmp-config.h&gt;</span>
00157 
00158 <span class="preprocessor">#ifdef KINETICS</span>
00159 <span class="preprocessor">#include "gw.h"</span>
00160 <span class="preprocessor">#endif</span>
00161 
00162 <span class="preprocessor">#if HAVE_STRING_H</span>
00163 <span class="preprocessor">#include &lt;string.h&gt;</span>
00164 <span class="preprocessor">#else</span>
00165 <span class="preprocessor">#include &lt;strings.h&gt;</span>
00166 <span class="preprocessor">#endif</span>
00167 
00168 <span class="preprocessor">#include &lt;sys/types.h&gt;</span>
00169 <span class="preprocessor">#include &lt;stdio.h&gt;</span>
00170 <span class="preprocessor">#ifdef HAVE_STDLIB_H</span>
00171 <span class="preprocessor">#include &lt;stdlib.h&gt;</span>
00172 <span class="preprocessor">#endif</span>
00173 <span class="preprocessor">#if HAVE_WINSOCK_H</span>
00174 <span class="preprocessor">#include &lt;winsock.h&gt;</span>
00175 <span class="preprocessor">#endif</span>
00176 <span class="preprocessor">#if HAVE_NETINET_IN_H</span>
00177 <span class="preprocessor">#include &lt;netinet/in.h&gt;</span>
00178 <span class="preprocessor">#endif</span>
00179 
00180 <span class="preprocessor">#ifdef vms</span>
00181 <span class="preprocessor">#include &lt;in.h&gt;</span>
00182 <span class="preprocessor">#endif</span>
00183 
00184 <span class="preprocessor">#if HAVE_DMALLOC_H</span>
00185 <span class="preprocessor">#include &lt;dmalloc.h&gt;</span>
00186 <span class="preprocessor">#endif</span>
00187 
00188 <span class="preprocessor">#include &lt;net-snmp/output_api.h&gt;</span>
00189 <span class="preprocessor">#include &lt;net-snmp/utilities.h&gt;</span>
00190 
00191 <span class="preprocessor">#include &lt;net-snmp/library/asn1.h&gt;</span>
00192 <span class="preprocessor">#include &lt;net-snmp/library/int64.h&gt;</span>
00193 <span class="preprocessor">#include &lt;net-snmp/library/mib.h&gt;</span>
00194 
00195 <span class="preprocessor">#ifndef NULL</span>
00196 <span class="preprocessor">#define NULL    0</span>
00197 <span class="preprocessor">#endif</span>
00198 
00199 <span class="preprocessor">#include &lt;net-snmp/library/snmp_api.h&gt;</span>
00200 
00201 <span class="preprocessor">#ifndef INT32_MAX</span>
00202 <span class="preprocessor">#   define INT32_MAX 2147483647</span>
00203 <span class="preprocessor">#endif</span>
00204 
00205 <span class="preprocessor">#ifndef INT32_MIN</span>
00206 <span class="preprocessor">#   define INT32_MIN (0 - INT32_MAX - 1)</span>
00207 <span class="preprocessor">#endif</span>
00208 
00209 
00210 <span class="preprocessor">#if SIZEOF_LONG == 4</span>
00211 <span class="preprocessor">#  define CHECK_OVERFLOW_S(x,y)</span>
00212 <span class="preprocessor">#  define CHECK_OVERFLOW_U(x,y)</span>
00213 <span class="preprocessor">#else</span>
00214 <span class="preprocessor">#  define CHECK_OVERFLOW_S(x,y) do { int trunc = 0;                     \</span>
00215 <span class="preprocessor">        if (x &gt; INT32_MAX) {                                            \</span>
00216 <span class="preprocessor">            trunc = 1;                                                  \</span>
00217 <span class="preprocessor">            x &amp;= 0xffffffff;                                            \</span>
00218 <span class="preprocessor">        } else if (x &lt; INT32_MIN) {                                     \</span>
00219 <span class="preprocessor">            trunc = 1;                                                  \</span>
00220 <span class="preprocessor">            x = 0 - (x &amp; 0xffffffff);                                   \</span>
00221 <span class="preprocessor">        }                                                               \</span>
00222 <span class="preprocessor">        if (trunc)                                                      \</span>
00223 <span class="preprocessor">            snmp_log(LOG_ERR,"truncating signed value to 32 bits (%d)\n",y); \</span>
00224 <span class="preprocessor">    } while(0)</span>
00225 
00226 <span class="preprocessor">#  define CHECK_OVERFLOW_U(x,y) do {                                    \</span>
00227 <span class="preprocessor">        if (x &gt; UINT32_MAX) {                                           \</span>
00228 <span class="preprocessor">            x &amp;= 0xffffffff;                                            \</span>
00229 <span class="preprocessor">            snmp_log(LOG_ERR,"truncating unsigned value to 32 bits (%d)\n",y); \</span>
00230 <span class="preprocessor">        }                                                               \</span>
00231 <span class="preprocessor">    } while(0)</span>
00232 <span class="preprocessor">#endif</span>
00233 
00242 <span class="keyword">static</span>
00243     <span class="keywordtype">void</span>
00244 _asn_size_err(<span class="keyword">const</span> <span class=
"keywordtype">char</span> *str, size_t wrongsize, size_t rightsize)
00245 {
00246     <span class="keywordtype">char</span>            ebuf[128];
00247 
00248     snprintf(ebuf, <span class="keyword">sizeof</span>(ebuf),
00249             <span class="stringliteral">"%s size %lu: s/b %lu"</span>, str,
00250             (<span class="keywordtype">unsigned</span> <span class="keywordtype">long</span>)wrongsize, (<span class=
"keywordtype">unsigned</span> <span class="keywordtype">long</span>)rightsize);
00251     ebuf[ <span class="keyword">sizeof</span>(ebuf)-1 ] = 0;
00252     ERROR_MSG(ebuf);
00253 }
00254 
00263 <span class="keyword">static</span>
00264     <span class="keywordtype">void</span>
00265 _asn_length_err(<span class="keyword">const</span> <span class=
"keywordtype">char</span> *str, size_t wrongsize, size_t rightsize)
00266 {
00267     <span class="keywordtype">char</span>            ebuf[128];
00268 
00269     snprintf(ebuf, <span class="keyword">sizeof</span>(ebuf),
00270             <span class="stringliteral">"%s length %lu too large: exceeds %lu"</span>, str,
00271             (<span class="keywordtype">unsigned</span> <span class="keywordtype">long</span>)wrongsize, (<span class=
"keywordtype">unsigned</span> <span class="keywordtype">long</span>)rightsize);
00272     ebuf[ <span class="keyword">sizeof</span>(ebuf)-1 ] = 0;
00273     ERROR_MSG(ebuf);
00274 }
00275 
00288 <span class="keyword">static</span>
00289     <span class="keywordtype">int</span>
00290 _asn_parse_length_check(<span class="keyword">const</span> <span class="keywordtype">char</span> *str,
00291                         <span class="keyword">const</span> u_char * bufp, <span class="keyword">const</span> u_char * data,
00292                         u_long plen, size_t dlen)
00293 {
00294     <span class="keywordtype">char</span>            ebuf[128];
00295     size_t          header_len;
00296 
00297     <span class="keywordflow">if</span> (bufp == NULL) {
00298         <span class="comment">/*</span>
00299 <span class="comment">         * error message is set </span>
00300 <span class="comment">         */</span>
00301         <span class="keywordflow">return</span> 1;
00302     }
00303     header_len = bufp - data;
00304     <span class="keywordflow">if</span> (plen &gt; 0x7fffffff || header_len &gt; 0x7fffffff ||
00305         ((size_t) plen + header_len) &gt; dlen) {
00306         snprintf(ebuf, <span class="keyword">sizeof</span>(ebuf),
00307                 <span class="stringliteral">"%s: message overflow: %d len + %d delta &gt; %d len"</span>,
00308                 str, (<span class="keywordtype">int</span>) plen, (<span class=
"keywordtype">int</span>) header_len, (<span class="keywordtype">int</span>) dlen);
00309         ebuf[ <span class="keyword">sizeof</span>(ebuf)-1 ] = 0;
00310         ERROR_MSG(ebuf);
00311         <span class="keywordflow">return</span> 1;
00312     }
00313     <span class="keywordflow">return</span> 0;
00314 }
00315 
00316 
00328 <span class="keyword">static</span>
00329     <span class="keywordtype">int</span>
00330 _asn_build_header_check(<span class="keyword">const</span> <span class="keywordtype">char</span> *str, <span class=
"keyword">const</span> u_char * data,
00331                         size_t datalen, size_t typedlen)
00332 {
00333     <span class="keywordtype">char</span>            ebuf[128];
00334 
00335     <span class="keywordflow">if</span> (data == NULL) {
00336         <span class="comment">/*</span>
00337 <span class="comment">         * error message is set </span>
00338 <span class="comment">         */</span>
00339         <span class="keywordflow">return</span> 1;
00340     }
00341     <span class="keywordflow">if</span> (datalen &lt; typedlen) {
00342         snprintf(ebuf, <span class="keyword">sizeof</span>(ebuf),
00343                 <span class="stringliteral">"%s: bad header, length too short: %lu &lt; %lu"</span>, str,
00344                 (<span class="keywordtype">unsigned</span> <span class="keywordtype">long</span>)datalen, (<span class=
"keywordtype">unsigned</span> <span class="keywordtype">long</span>)typedlen);
00345         ebuf[ <span class="keyword">sizeof</span>(ebuf)-1 ] = 0;
00346         ERROR_MSG(ebuf);
00347         <span class="keywordflow">return</span> 1;
00348     }
00349     <span class="keywordflow">return</span> 0;
00350 }
00351 
00363 <span class="keyword">static</span>
00364     <span class="keywordtype">int</span>
00365 _asn_realloc_build_header_check(<span class="keyword">const</span> <span class="keywordtype">char</span> *str,
00366                                 u_char ** pkt,
00367                                 <span class="keyword">const</span> size_t * pkt_len, size_t typedlen)
00368 {
00369     <span class="keywordtype">char</span>            ebuf[128];
00370 
00371     <span class="keywordflow">if</span> (pkt == NULL || *pkt == NULL) {
00372         <span class="comment">/*</span>
00373 <span class="comment">         * Error message is set.  </span>
00374 <span class="comment">         */</span>
00375         <span class="keywordflow">return</span> 1;
00376     }
00377 
00378     <span class="keywordflow">if</span> (*pkt_len &lt; typedlen) {
00379         snprintf(ebuf, <span class="keyword">sizeof</span>(ebuf),
00380                 <span class="stringliteral">"%s: bad header, length too short: %lu &lt; %lu"</span>, str,
00381                 (<span class="keywordtype">unsigned</span> <span class="keywordtype">long</span>)*pkt_len, (<span class=
"keywordtype">unsigned</span> <span class="keywordtype">long</span>)typedlen);
00382         ebuf[ <span class="keyword">sizeof</span>(ebuf)-1 ] = 0;
00383         ERROR_MSG(ebuf);
00384         <span class="keywordflow">return</span> 1;
00385     }
00386     <span class="keywordflow">return</span> 0;
00387 }
00388 
00398 <span class="keywordtype">int</span>
00399 asn_check_packet(u_char * pkt, size_t len)
00400 {
00401     u_long          asn_length;
00402 
00403     <span class="keywordflow">if</span> (len &lt; 2)
00404         <span class="keywordflow">return</span> 0;               <span class="comment">/* always too short */</span>
00405 
00406     <span class="keywordflow">if</span> (*pkt != (u_char) (ASN_SEQUENCE | ASN_CONSTRUCTOR))
00407         <span class="keywordflow">return</span> -1;              <span class="comment">/* wrong type */</span>
00408 
00409     <span class="keywordflow">if</span> (*(pkt + 1) &amp; 0x80) {
00410         <span class="comment">/*</span>
00411 <span class="comment">         * long length </span>
00412 <span class="comment">         */</span>
00413         <span class="keywordflow">if</span> ((int) len &lt; (int) (*(pkt + 1) &amp; ~0x80) + 2)
00414             <span class="keywordflow">return</span> 0;           <span class=
"comment">/* still to short, incomplete length */</span>
00415         asn_parse_length(pkt + 1, &amp;asn_length);
00416         <span class="keywordflow">return</span> (asn_length + 2 + (*(pkt + 1) &amp; ~0x80));
00417     } <span class="keywordflow">else</span> {
00418         <span class="comment">/*</span>
00419 <span class="comment">         * short length </span>
00420 <span class="comment">         */</span>
00421         <span class="keywordflow">return</span> (*(pkt + 1) + 2);
00422     }
00423 }
00424 
00425 <span class="keyword">static</span>
00426     <span class="keywordtype">int</span>
00427 _asn_bitstring_check(<span class="keyword">const</span> <span class=
"keywordtype">char</span> *str, size_t asn_length, u_char datum)
00428 {
00429     <span class="keywordtype">char</span>            ebuf[128];
00430 
00431     <span class="keywordflow">if</span> (asn_length &lt; 1) {
00432         snprintf(ebuf, <span class="keyword">sizeof</span>(ebuf),
00433                 <span class="stringliteral">"%s: length %d too small"</span>, str, (<span class=
"keywordtype">int</span>) asn_length);
00434         ebuf[ <span class="keyword">sizeof</span>(ebuf)-1 ] = 0;
00435         ERROR_MSG(ebuf);
00436         <span class="keywordflow">return</span> 1;
00437     }
00438     <span class="comment">/*</span>
00439 <span class="comment">     * if (datum &gt; 7){</span>
00440 <span class="comment">     * sprintf(ebuf,"%s: datum %d &gt;7: too large", str, (int)(datum));</span>
00441 <span class="comment">     * ERROR_MSG(ebuf);</span>
00442 <span class="comment">     * return 1;</span>
00443 <span class="comment">     * }</span>
00444 <span class="comment">     */</span>
00445     <span class="keywordflow">return</span> 0;
00446 }
00447 
00469 u_char         *
00470 asn_parse_int(u_char * data,
00471               size_t * datalength,
00472               u_char * type, <span class="keywordtype">long</span> *intp, size_t intsize)
00473 {
00474     <span class="comment">/*</span>
00475 <span class="comment">     * ASN.1 integer ::= 0x02 asnlength byte {byte}*</span>
00476 <span class="comment">     */</span>
00477     <span class="keyword">static</span> <span class="keyword">const</span> <span class=
"keywordtype">char</span> *errpre = <span class="stringliteral">"parse int"</span>;
00478     <span class="keyword">register</span> u_char *bufp = data;
00479     u_long          asn_length;
00480     <span class="keyword">register</span> <span class="keywordtype">long</span>   value = 0;
00481 
00482     <span class="keywordflow">if</span> (intsize != <span class="keyword">sizeof</span>(long)) {
00483         _asn_size_err(errpre, intsize, <span class="keyword">sizeof</span>(<span class="keywordtype">long</span>));
00484         <span class="keywordflow">return</span> NULL;
00485     }
00486     *type = *bufp++;
00487     bufp = asn_parse_length(bufp, &amp;asn_length);
00488     <span class="keywordflow">if</span> (_asn_parse_length_check
00489         (errpre, bufp, data, asn_length, *datalength))
00490         <span class="keywordflow">return</span> NULL;
00491 
00492     <span class="keywordflow">if</span> ((size_t) asn_length &gt; intsize) {
00493         _asn_length_err(errpre, (size_t) asn_length, intsize);
00494         <span class="keywordflow">return</span> NULL;
00495     }
00496 
00497     *datalength -= (int) asn_length + (bufp - data);
00498     <span class="keywordflow">if</span> (*bufp &amp; 0x80)
00499         value = -1;             <span class="comment">/* integer is negative */</span>
00500 
00501     DEBUGDUMPSETUP(<span class="stringliteral">"recv"</span>, data, bufp - data + asn_length);
00502 
00503     <span class="keywordflow">while</span> (asn_length--)
00504         value = (value &lt;&lt; 8) | *bufp++;
00505 
00506     CHECK_OVERFLOW_S(value,1);
00507 
00508     DEBUGMSG((<span class="stringliteral">"dumpv_recv"</span>, <span class=
"stringliteral">"  Integer:\t%ld (0x%.2X)\n"</span>, value, value));
00509 
00510     *intp = value;
00511     <span class="keywordflow">return</span> bufp;
00512 }
00513 
00514 
00536 u_char         *
00537 asn_parse_unsigned_int(u_char * data,
00538                        size_t * datalength,
00539                        u_char * type, u_long * intp, size_t intsize)
00540 {
00541     <span class="comment">/*</span>
00542 <span class="comment">     * ASN.1 integer ::= 0x02 asnlength byte {byte}*</span>
00543 <span class="comment">     */</span>
00544     <span class="keyword">static</span> <span class="keyword">const</span> <span class=
"keywordtype">char</span> *errpre = <span class="stringliteral">"parse uint"</span>;
00545     <span class="keyword">register</span> u_char *bufp = data;
00546     u_long          asn_length;
00547     <span class="keyword">register</span> u_long value = 0;
00548 
00549     <span class="keywordflow">if</span> (intsize != <span class="keyword">sizeof</span>(long)) {
00550         _asn_size_err(errpre, intsize, <span class="keyword">sizeof</span>(<span class="keywordtype">long</span>));
00551         <span class="keywordflow">return</span> NULL;
00552     }
00553     *type = *bufp++;
00554     bufp = asn_parse_length(bufp, &amp;asn_length);
00555     <span class="keywordflow">if</span> (_asn_parse_length_check
00556         (errpre, bufp, data, asn_length, *datalength))
00557         <span class="keywordflow">return</span> NULL;
00558 
00559     <span class="keywordflow">if</span> (((int) asn_length &gt; (intsize + 1)) ||
00560         (((int) asn_length == intsize + 1) &amp;&amp; *bufp != 0x00)) {
00561         _asn_length_err(errpre, (size_t) asn_length, intsize);
00562         <span class="keywordflow">return</span> NULL;
00563     }
00564     *datalength -= (int) asn_length + (bufp - data);
00565     <span class="keywordflow">if</span> (*bufp &amp; 0x80)
00566         value = ~value;         <span class="comment">/* integer is negative */</span>
00567 
00568     DEBUGDUMPSETUP(<span class="stringliteral">"recv"</span>, data, bufp - data + asn_length);
00569 
00570     <span class="keywordflow">while</span> (asn_length--)
00571         value = (value &lt;&lt; 8) | *bufp++;
00572 
00573     CHECK_OVERFLOW_U(value,2);
00574 
00575     DEBUGMSG((<span class="stringliteral">"dumpv_recv"</span>, <span class=
"stringliteral">"  UInteger:\t%ld (0x%.2X)\n"</span>, value, value));
00576 
00577     *intp = value;
00578     <span class="keywordflow">return</span> bufp;
00579 }
00580 
00581 
00605 u_char         *
00606 asn_build_int(u_char * data,
00607            size_t * datalength, u_char type, <span class="keyword">const</span> <span class=
"keywordtype">long</span> *intp, size_t intsize)
00608 {
00609     <span class="comment">/*</span>
00610 <span class="comment">     * ASN.1 integer ::= 0x02 asnlength byte {byte}*</span>
00611 <span class="comment">     */</span>
00612     <span class="keyword">static</span> <span class="keyword">const</span> <span class=
"keywordtype">char</span> *errpre = <span class="stringliteral">"build int"</span>;
00613     <span class="keyword">register</span> <span class="keywordtype">long</span>   integer;
00614     <span class="keyword">register</span> u_long mask;
00615 <span class="preprocessor">#ifndef SNMP_NO_DEBUGGING</span>
00616     u_char         *initdatap = data;
00617 <span class="preprocessor">#endif</span>
00618 
00619     <span class="keywordflow">if</span> (intsize != <span class="keyword">sizeof</span>(long)) {
00620         _asn_size_err(errpre, intsize, <span class="keyword">sizeof</span>(<span class="keywordtype">long</span>));
00621         <span class="keywordflow">return</span> NULL;
00622     }
00623     integer = *intp;
00624     CHECK_OVERFLOW_S(integer,3);
00625     <span class="comment">/*</span>
00626 <span class="comment">     * Truncate "unnecessary" bytes off of the most significant end of this</span>
00627 <span class="comment">     * 2's complement integer.  There should be no sequence of 9</span>
00628 <span class="comment">     * consecutive 1's or 0's at the most significant end of the</span>
00629 <span class="comment">     * integer.</span>
00630 <span class="comment">     */</span>
00631     mask = ((u_long) 0x1FF) &lt;&lt; ((8 * (<span class="keyword">sizeof</span>(long) - 1)) - 1);
00632     <span class="comment">/*</span>
00633 <span class="comment">     * mask is 0xFF800000 on a big-endian machine </span>
00634 <span class="comment">     */</span>
00635     <span class="keywordflow">while</span> ((((integer &amp; mask) == 0) || ((integer &amp; mask) == mask))
00636            &amp;&amp; intsize &gt; 1) {
00637         intsize--;
00638         integer &lt;&lt;= 8;
00639     }
00640     data = asn_build_header(data, datalength, type, intsize);
00641     <span class="keywordflow">if</span> (_asn_build_header_check(errpre, data, *datalength, intsize))
00642         <span class="keywordflow">return</span> NULL;
00643 
00644     *datalength -= intsize;
00645     mask = ((u_long) 0xFF) &lt;&lt; (8 * (<span class="keyword">sizeof</span>(long) - 1));
00646     <span class="comment">/*</span>
00647 <span class="comment">     * mask is 0xFF000000 on a big-endian machine </span>
00648 <span class="comment">     */</span>
00649     <span class="keywordflow">while</span> (intsize--) {
00650         *data++ = (u_char) ((integer &amp; mask) &gt;&gt; (8 * (<span class="keyword">sizeof</span>(long) - 1)));
00651         integer &lt;&lt;= 8;
00652     }
00653     DEBUGDUMPSETUP(<span class="stringliteral">"send"</span>, initdatap, data - initdatap);
00654     DEBUGMSG((<span class="stringliteral">"dumpv_send"</span>, <span class=
"stringliteral">"  Integer:\t%ld (0x%.2X)\n"</span>, *intp, *intp));
00655     <span class="keywordflow">return</span> data;
00656 }
00657 
00658 
00659 
00683 u_char         *
00684 asn_build_unsigned_int(u_char * data,
00685                        size_t * datalength,
00686                        u_char type, <span class="keyword">const</span> u_long * intp, size_t intsize)
00687 {
00688     <span class="comment">/*</span>
00689 <span class="comment">     * ASN.1 integer ::= 0x02 asnlength byte {byte}*</span>
00690 <span class="comment">     */</span>
00691     <span class="keyword">static</span> <span class="keyword">const</span> <span class=
"keywordtype">char</span> *errpre = <span class="stringliteral">"build uint"</span>;
00692     <span class="keyword">register</span> u_long integer;
00693     <span class="keyword">register</span> u_long mask;
00694     <span class="keywordtype">int</span>             add_null_byte = 0;
00695 <span class="preprocessor">#ifndef SNMP_NO_DEBUGGING</span>
00696     u_char         *initdatap = data;
00697 <span class="preprocessor">#endif</span>
00698 
00699     <span class="keywordflow">if</span> (intsize != <span class="keyword">sizeof</span>(long)) {
00700         _asn_size_err(errpre, intsize, <span class="keyword">sizeof</span>(<span class="keywordtype">long</span>));
00701         <span class="keywordflow">return</span> NULL;
00702     }
00703     integer = *intp;
00704     CHECK_OVERFLOW_U(integer,4);
00705 
00706     mask = ((u_long) 0xFF) &lt;&lt; (8 * (<span class="keyword">sizeof</span>(long) - 1));
00707     <span class="comment">/*</span>
00708 <span class="comment">     * mask is 0xFF000000 on a big-endian machine </span>
00709 <span class="comment">     */</span>
00710     <span class="keywordflow">if</span> ((u_char) ((integer &amp; mask) &gt;&gt; (8 * (<span class=
"keyword">sizeof</span>(long) - 1))) &amp; 0x80) {
00711         <span class="comment">/*</span>
00712 <span class="comment">         * if MSB is set </span>
00713 <span class="comment">         */</span>
00714         add_null_byte = 1;
00715         intsize++;
00716     } <span class="keywordflow">else</span> {
00717         <span class="comment">/*</span>
00718 <span class=
"comment">         * Truncate "unnecessary" bytes off of the most significant end of this 2's complement integer.</span>
00719 <span class=
"comment">         * There should be no sequence of 9 consecutive 1's or 0's at the most significant end of the</span>
00720 <span class="comment">         * integer.</span>
00721 <span class="comment">         */</span>
00722         mask = ((u_long) 0x1FF) &lt;&lt; ((8 * (<span class="keyword">sizeof</span>(long) - 1)) - 1);
00723         <span class="comment">/*</span>
00724 <span class="comment">         * mask is 0xFF800000 on a big-endian machine </span>
00725 <span class="comment">         */</span>
00726         <span class="keywordflow">while</span> ((((integer &amp; mask) == 0) || ((integer &amp; mask) == mask))
00727                &amp;&amp; intsize &gt; 1) {
00728             intsize--;
00729             integer &lt;&lt;= 8;
00730         }
00731     }
00732     data = asn_build_header(data, datalength, type, intsize);
00733     <span class="keywordflow">if</span> (_asn_build_header_check(errpre, data, *datalength, intsize))
00734         <span class="keywordflow">return</span> NULL;
00735 
00736     *datalength -= intsize;
00737     <span class="keywordflow">if</span> (add_null_byte == 1) {
00738         *data++ = <span class="charliteral">'\0'</span>;
00739         intsize--;
00740     }
00741     mask = ((u_long) 0xFF) &lt;&lt; (8 * (<span class="keyword">sizeof</span>(long) - 1));
00742     <span class="comment">/*</span>
00743 <span class="comment">     * mask is 0xFF000000 on a big-endian machine </span>
00744 <span class="comment">     */</span>
00745     <span class="keywordflow">while</span> (intsize--) {
00746         *data++ = (u_char) ((integer &amp; mask) &gt;&gt; (8 * (<span class="keyword">sizeof</span>(long) - 1)));
00747         integer &lt;&lt;= 8;
00748     }
00749     DEBUGDUMPSETUP(<span class="stringliteral">"send"</span>, initdatap, data - initdatap);
00750     DEBUGMSG((<span class="stringliteral">"dumpv_send"</span>, <span class=
"stringliteral">"  UInteger:\t%ld (0x%.2X)\n"</span>, *intp, *intp));
00751     <span class="keywordflow">return</span> data;
00752 }
00753 
00754 
00783 u_char         *
00784 asn_parse_string(u_char * data,
00785                  size_t * datalength,
00786                  u_char * type, u_char * str, size_t * strlength)
00787 {
00788     <span class="keyword">static</span> <span class="keyword">const</span> <span class=
"keywordtype">char</span> *errpre = <span class="stringliteral">"parse string"</span>;
00789     u_char         *bufp = data;
00790     u_long          asn_length;
00791 
00792     *type = *bufp++;
00793     bufp = asn_parse_length(bufp, &amp;asn_length);
00794     <span class="keywordflow">if</span> (_asn_parse_length_check
00795         (errpre, bufp, data, asn_length, *datalength)) {
00796         <span class="keywordflow">return</span> NULL;
00797     }
00798 
00799     <span class="keywordflow">if</span> ((int) asn_length &gt; *strlength) {
00800         _asn_length_err(errpre, (size_t) asn_length, *strlength);
00801         <span class="keywordflow">return</span> NULL;
00802     }
00803 
00804     DEBUGDUMPSETUP(<span class="stringliteral">"recv"</span>, data, bufp - data + asn_length);
00805 
00806     memmove(str, bufp, asn_length);
00807     <span class="keywordflow">if</span> (*strlength &gt; (int) asn_length)
00808         str[asn_length] = 0;
00809     *strlength = (int) asn_length;
00810     *datalength -= (int) asn_length + (bufp - data);
00811 
00812     DEBUGIF(<span class="stringliteral">"dumpv_recv"</span>) {
00813         u_char         *buf = (u_char *) malloc(1 + asn_length);
00814         size_t          l = (buf != NULL) ? (1 + asn_length) : 0, ol = 0;
00815 
00816         <span class="keywordflow">if</span> (<a class="code" href=
"group__mib__utilities.html#ga28">sprint_realloc_asciistring</a>
00817             (&amp;buf, &amp;l, &amp;ol, 1, str, asn_length)) {
00818             DEBUGMSG((<span class="stringliteral">"dumpv_recv"</span>, <span class=
"stringliteral">"  String:\t%s\n"</span>, buf));
00819         } <span class="keywordflow">else</span> {
00820             <span class="keywordflow">if</span> (buf == NULL) {
00821                 DEBUGMSG((<span class="stringliteral">"dumpv_recv"</span>, <span class=
"stringliteral">"  String:\t[TRUNCATED]\n"</span>));
00822             } <span class="keywordflow">else</span> {
00823                 DEBUGMSG((<span class="stringliteral">"dumpv_recv"</span>, <span class=
"stringliteral">"  String:\t%s [TRUNCATED]\n"</span>,
00824                           buf));
00825             }
00826         }
00827         <span class="keywordflow">if</span> (buf != NULL) {
00828             free(buf);
00829         }
00830     }
00831 
00832     <span class="keywordflow">return</span> bufp + asn_length;
00833 }
00834 
00835 
00858 u_char         *
00859 asn_build_string(u_char * data,
00860                  size_t * datalength,
00861                  u_char type, <span class="keyword">const</span> u_char * str, size_t strlength)
00862 {
00863     <span class="comment">/*</span>
00864 <span class="comment">     * ASN.1 octet string ::= primstring | cmpdstring</span>
00865 <span class="comment">     * primstring ::= 0x04 asnlength byte {byte}*</span>
00866 <span class="comment">     * cmpdstring ::= 0x24 asnlength string {string}*</span>
00867 <span class="comment">     * This code will never send a compound string.</span>
00868 <span class="comment">     */</span>
00869 <span class="preprocessor">#ifndef SNMP_NO_DEBUGGING</span>
00870     u_char         *initdatap = data;
00871 <span class="preprocessor">#endif</span>
00872     data = asn_build_header(data, datalength, type, strlength);
00873     <span class="keywordflow">if</span> (_asn_build_header_check
00874         (<span class="stringliteral">"build string"</span>, data, *datalength, strlength))
00875         <span class="keywordflow">return</span> NULL;
00876 
00877     <span class="keywordflow">if</span> (strlength) {
00878         <span class="keywordflow">if</span> (str == NULL) {
00879             memset(data, 0, strlength);
00880         } <span class="keywordflow">else</span> {
00881             memmove(data, str, strlength);
00882         }
00883     }
00884     *datalength -= strlength;
00885     DEBUGDUMPSETUP(<span class="stringliteral">"send"</span>, initdatap, data - initdatap + strlength);
00886     DEBUGIF(<span class="stringliteral">"dumpv_send"</span>) {
00887         u_char         *buf = (u_char *) malloc(1 + strlength);
00888         size_t          l = (buf != NULL) ? (1 + strlength) : 0, ol = 0;
00889 
00890         <span class="keywordflow">if</span> (<a class="code" href=
"group__mib__utilities.html#ga28">sprint_realloc_asciistring</a>
00891             (&amp;buf, &amp;l, &amp;ol, 1, str, strlength)) {
00892             DEBUGMSG((<span class="stringliteral">"dumpv_send"</span>, <span class=
"stringliteral">"  String:\t%s\n"</span>, buf));
00893         } <span class="keywordflow">else</span> {
00894             <span class="keywordflow">if</span> (buf == NULL) {
00895                 DEBUGMSG((<span class="stringliteral">"dumpv_send"</span>, <span class=
"stringliteral">"  String:\t[TRUNCATED]\n"</span>));
00896             } <span class="keywordflow">else</span> {
00897                 DEBUGMSG((<span class="stringliteral">"dumpv_send"</span>, <span class=
"stringliteral">"  String:\t%s [TRUNCATED]\n"</span>,
00898                           buf));
00899             }
00900         }
00901         <span class="keywordflow">if</span> (buf != NULL) {
00902             free(buf);
00903         }
00904     }
00905     <span class="keywordflow">return</span> data + strlength;
00906 }
00907 
00908 
00909 
00929 u_char         *
00930 asn_parse_header(u_char * data, size_t * datalength, u_char * type)
00931 {
00932     <span class="keyword">register</span> u_char *bufp;
00933     u_long          asn_length;
00934 
00935     <span class="keywordflow">if</span> (!data || !datalength || !type) {
00936         ERROR_MSG(<span class="stringliteral">"parse header: NULL pointer"</span>);
00937         <span class="keywordflow">return</span> NULL;
00938     }
00939     bufp = data;
00940     <span class="comment">/*</span>
00941 <span class="comment">     * this only works on data types &lt; 30, i.e. no extension octets </span>
00942 <span class="comment">     */</span>
00943     <span class="keywordflow">if</span> (IS_EXTENSION_ID(*bufp)) {
00944         ERROR_MSG(<span class="stringliteral">"can't process ID &gt;= 30"</span>);
00945         <span class="keywordflow">return</span> NULL;
00946     }
00947     *type = *bufp;
00948     bufp = asn_parse_length(bufp + 1, &amp;asn_length);
00949 
00950     <span class="keywordflow">if</span> (_asn_parse_length_check
00951         (<span class="stringliteral">"parse header"</span>, bufp, data, asn_length, *datalength))
00952         <span class="keywordflow">return</span> NULL;
00953 
00954 <span class="preprocessor">#ifdef DUMP_PRINT_HEADERS</span>
00955     DEBUGDUMPSETUP(<span class="stringliteral">"recv"</span>, data, (bufp - data));
00956     DEBUGMSG((<span class="stringliteral">"dumpv_recv"</span>, <span class=
"stringliteral">"  Header: 0x%.2X, len = %d (0x%X)\n"</span>, *data,
00957               asn_length, asn_length));
00958 <span class="preprocessor">#else</span>
00959     <span class="comment">/*</span>
00960 <span class="comment">     * DEBUGMSGHEXTLI(("recv",data,(bufp-data)));</span>
00961 <span class="comment">     * DEBUGMSG(("dumpH_recv","\n"));</span>
00962 <span class="comment">     */</span>
00963 <span class="preprocessor">#endif</span>
00964 
00965 <span class="preprocessor">#ifdef OPAQUE_SPECIAL_TYPES</span>
00966 
00967     <span class="keywordflow">if</span> ((*type == ASN_OPAQUE) &amp;&amp; (*bufp == ASN_OPAQUE_TAG1)) {
00968 
00969         <span class="comment">/*</span>
00970 <span class="comment">         * check if 64-but counter </span>
00971 <span class="comment">         */</span>
00972         <span class="keywordflow">switch</span> (*(bufp + 1)) {
00973         <span class="keywordflow">case</span> ASN_OPAQUE_COUNTER64:
00974         <span class="keywordflow">case</span> ASN_OPAQUE_U64:
00975         <span class="keywordflow">case</span> ASN_OPAQUE_FLOAT:
00976         <span class="keywordflow">case</span> ASN_OPAQUE_DOUBLE:
00977         <span class="keywordflow">case</span> ASN_OPAQUE_I64:
00978             *type = *(bufp + 1);
00979             <span class="keywordflow">break</span>;
00980 
00981         <span class="keywordflow">default</span>:
00982             <span class="comment">/*</span>
00983 <span class="comment">             * just an Opaque </span>
00984 <span class="comment">             */</span>
00985             *datalength = (int) asn_length;
00986             <span class="keywordflow">return</span> bufp;
00987         }
00988         <span class="comment">/*</span>
00989 <span class="comment">         * value is encoded as special format </span>
00990 <span class="comment">         */</span>
00991         bufp = asn_parse_length(bufp + 2, &amp;asn_length);
00992         <span class="keywordflow">if</span> (_asn_parse_length_check(<span class=
"stringliteral">"parse opaque header"</span>, bufp, data,
00993                                     asn_length, *datalength))
00994             <span class="keywordflow">return</span> NULL;
00995     }
00996 <span class="preprocessor">#endif                          </span><span class="comment">/* OPAQUE_SPECIAL_TYPES */</span>
00997 
00998     *datalength = (int) asn_length;
00999 
01000     <span class="keywordflow">return</span> bufp;
01001 }
01002 
01017 u_char         *
01018 asn_parse_sequence(u_char * data, size_t * datalength, u_char * type, u_char expected_type,     <span class=
"comment">/* must be this type */</span>
01019                    <span class="keyword">const</span> <span class="keywordtype">char</span> *estr)
01020 {                               <span class="comment">/* error message prefix */</span>
01021     data = asn_parse_header(data, datalength, type);
01022     <span class="keywordflow">if</span> (data &amp;&amp; (*type != expected_type)) {
01023         <span class="keywordtype">char</span>            ebuf[128];
01024         snprintf(ebuf, <span class="keyword">sizeof</span>(ebuf),
01025                  <span class="stringliteral">"%s header type %02X: s/b %02X"</span>, estr,
01026                 (u_char) * type, (u_char) expected_type);
01027         ebuf[ <span class="keyword">sizeof</span>(ebuf)-1 ] = 0;
01028         ERROR_MSG(ebuf);
01029         <span class="keywordflow">return</span> NULL;
01030     }
01031     <span class="keywordflow">return</span> data;
01032 }
01033 
01034 
01035 
01058 u_char         *
01059 asn_build_header(u_char * data,
01060                  size_t * datalength, u_char type, size_t length)
01061 {
01062     <span class="keywordtype">char</span>            ebuf[128];
01063 
01064     <span class="keywordflow">if</span> (*datalength &lt; 1) {
01065         snprintf(ebuf, <span class="keyword">sizeof</span>(ebuf),
01066                 <span class="stringliteral">"bad header length &lt; 1 :%lu, %lu"</span>,
01067                 (<span class="keywordtype">unsigned</span> <span class="keywordtype">long</span>)*datalength, (<span class=
"keywordtype">unsigned</span> <span class="keywordtype">long</span>)length);
01068         ebuf[ <span class="keyword">sizeof</span>(ebuf)-1 ] = 0;
01069         ERROR_MSG(ebuf);
01070         <span class="keywordflow">return</span> NULL;
01071     }
01072     *data++ = type;
01073     (*datalength)--;
01074     <span class="keywordflow">return</span> asn_build_length(data, datalength, length);
01075 }
01076 
01100 u_char         *
01101 asn_build_sequence(u_char * data,
01102                    size_t * datalength, u_char type, size_t length)
01103 {
01104     <span class="keyword">static</span> <span class="keyword">const</span> <span class=
"keywordtype">char</span> *errpre = <span class="stringliteral">"build seq"</span>;
01105     <span class="keywordtype">char</span>            ebuf[128];
01106 
01107     <span class="keywordflow">if</span> (*datalength &lt; 4) {
01108         snprintf(ebuf, <span class="keyword">sizeof</span>(ebuf),
01109                 <span class="stringliteral">"%s: length %d &lt; 4: PUNT"</span>, errpre,
01110                 (<span class="keywordtype">int</span>) *datalength);
01111         ebuf[ <span class="keyword">sizeof</span>(ebuf)-1 ] = 0;
01112         ERROR_MSG(ebuf);
01113         <span class="keywordflow">return</span> NULL;
01114     }
01115     *datalength -= 4;
01116     *data++ = type;
01117     *data++ = (u_char) (0x02 | ASN_LONG_LEN);
01118     *data++ = (u_char) ((length &gt;&gt; 8) &amp; 0xFF);
01119     *data++ = (u_char) (length &amp; 0xFF);
01120     <span class="keywordflow">return</span> data;
01121 }
01122 
01140 u_char         *
01141 asn_parse_length(u_char * data, u_long * length)
01142 {
01143     <span class="keyword">static</span> <span class="keyword">const</span> <span class=
"keywordtype">char</span> *errpre = <span class="stringliteral">"parse length"</span>;
01144     <span class="keywordtype">char</span>            ebuf[128];
01145     <span class="keyword">register</span> u_char lengthbyte;
01146 
01147     <span class="keywordflow">if</span> (!data || !length) {
01148         ERROR_MSG(<span class="stringliteral">"parse length: NULL pointer"</span>);
01149         <span class="keywordflow">return</span> NULL;
01150     }
01151     lengthbyte = *data;
01152 
01153     <span class="keywordflow">if</span> (lengthbyte &amp; ASN_LONG_LEN) {
01154         lengthbyte &amp;= ~ASN_LONG_LEN;    <span class="comment">/* turn MSb off */</span>
01155         <span class="keywordflow">if</span> (lengthbyte == 0) {
01156             snprintf(ebuf, <span class="keyword">sizeof</span>(ebuf),
01157                      <span class="stringliteral">"%s: indefinite length not supported"</span>, errpre);
01158             ebuf[ <span class="keyword">sizeof</span>(ebuf)-1 ] = 0;
01159             ERROR_MSG(ebuf);
01160             <span class="keywordflow">return</span> NULL;
01161         }
01162         <span class="keywordflow">if</span> (lengthbyte &gt; <span class="keyword">sizeof</span>(long)) {
01163             snprintf(ebuf, <span class="keyword">sizeof</span>(ebuf),
01164                     <span class="stringliteral">"%s: data length %d &gt; %lu not supported"</span>, errpre,
01165                     lengthbyte, (<span class="keywordtype">unsigned</span> <span class=
"keywordtype">long</span>)<span class="keyword">sizeof</span>(<span class="keywordtype">long</span>));
01166             ebuf[ <span class="keyword">sizeof</span>(ebuf)-1 ] = 0;
01167             ERROR_MSG(ebuf);
01168             <span class="keywordflow">return</span> NULL;
01169         }
01170         data++;
01171         *length = 0;            <span class="comment">/* protect against short lengths */</span>
01172         <span class="keywordflow">while</span> (lengthbyte--) {
01173             *length &lt;&lt;= 8;
01174             *length |= *data++;
01175         }
01176         <span class="keywordflow">if</span> ((long) *length &lt; 0) {
01177             snprintf(ebuf, <span class="keyword">sizeof</span>(ebuf),
01178                      <span class="stringliteral">"%s: negative data length %ld\n"</span>, errpre,
01179                      (<span class="keywordtype">long</span>) *length);
01180             ebuf[ <span class="keyword">sizeof</span>(ebuf)-1 ] = 0;
01181             ERROR_MSG(ebuf);
01182             <span class="keywordflow">return</span> NULL;
01183         }
01184         <span class="keywordflow">return</span> data;
01185     } <span class="keywordflow">else</span> {                    <span class="comment">/* short asnlength */</span>
01186         *length = (long) lengthbyte;
01187         <span class="keywordflow">return</span> data + 1;
01188     }
01189 }
01190 
01211 u_char         *
01212 asn_build_length(u_char * data, size_t * datalength, size_t length)
01213 {
01214     <span class="keyword">static</span> <span class="keyword">const</span> <span class=
"keywordtype">char</span> *errpre = <span class="stringliteral">"build length"</span>;
01215     <span class="keywordtype">char</span>            ebuf[128];
01216 
01217     u_char         *start_data = data;
01218 
01219     <span class="comment">/*</span>
01220 <span class="comment">     * no indefinite lengths sent </span>
01221 <span class="comment">     */</span>
01222     <span class="keywordflow">if</span> (length &lt; 0x80) {
01223         <span class="keywordflow">if</span> (*datalength &lt; 1) {
01224             snprintf(ebuf, <span class="keyword">sizeof</span>(ebuf),
01225                     <span class="stringliteral">"%s: bad length &lt; 1 :%lu, %lu"</span>, errpre,
01226                     (<span class="keywordtype">unsigned</span> <span class=
"keywordtype">long</span>)*datalength, (<span class="keywordtype">unsigned</span> <span class="keywordtype">long</span>)length);
01227             ebuf[ <span class="keyword">sizeof</span>(ebuf)-1 ] = 0;
01228             ERROR_MSG(ebuf);
01229             <span class="keywordflow">return</span> NULL;
01230         }
01231         *data++ = (u_char) length;
01232     } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (length &lt;= 0xFF) {
01233         <span class="keywordflow">if</span> (*datalength &lt; 2) {
01234             snprintf(ebuf, <span class="keyword">sizeof</span>(ebuf),
01235                     <span class="stringliteral">"%s: bad length &lt; 2 :%lu, %lu"</span>, errpre,
01236                     (<span class="keywordtype">unsigned</span> <span class=
"keywordtype">long</span>)*datalength, (<span class="keywordtype">unsigned</span> <span class="keywordtype">long</span>)length);
01237             ebuf[ <span class="keyword">sizeof</span>(ebuf)-1 ] = 0;
01238             ERROR_MSG(ebuf);
01239             <span class="keywordflow">return</span> NULL;
01240         }
01241         *data++ = (u_char) (0x01 | ASN_LONG_LEN);
01242         *data++ = (u_char) length;
01243     } <span class="keywordflow">else</span> {                    <span class=
"comment">/* 0xFF &lt; length &lt;= 0xFFFF */</span>
01244         <span class="keywordflow">if</span> (*datalength &lt; 3) {
01245             snprintf(ebuf, <span class="keyword">sizeof</span>(ebuf),
01246                     <span class="stringliteral">"%s: bad length &lt; 3 :%lu, %lu"</span>, errpre,
01247                     (<span class="keywordtype">unsigned</span> <span class=
"keywordtype">long</span>)*datalength, (<span class="keywordtype">unsigned</span> <span class="keywordtype">long</span>)length);
01248             ebuf[ <span class="keyword">sizeof</span>(ebuf)-1 ] = 0;
01249             ERROR_MSG(ebuf);
01250             <span class="keywordflow">return</span> NULL;
01251         }
01252         *data++ = (u_char) (0x02 | ASN_LONG_LEN);
01253         *data++ = (u_char) ((length &gt;&gt; 8) &amp; 0xFF);
01254         *data++ = (u_char) (length &amp; 0xFF);
01255     }
01256     *datalength -= (data - start_data);
01257     <span class="keywordflow">return</span> data;
01258 
01259 }
01260 
01286 u_char         *
01287 asn_parse_objid(u_char * data,
01288                 size_t * datalength,
01289                 u_char * type, oid * objid, size_t * objidlength)
01290 {
01291     <span class="comment">/*</span>
01292 <span class="comment">     * ASN.1 objid ::= 0x06 asnlength subidentifier {subidentifier}*</span>
01293 <span class="comment">     * subidentifier ::= {leadingbyte}* lastbyte</span>
01294 <span class="comment">     * leadingbyte ::= 1 7bitvalue</span>
01295 <span class="comment">     * lastbyte ::= 0 7bitvalue</span>
01296 <span class="comment">     */</span>
01297     <span class="keyword">register</span> u_char *bufp = data;
01298     <span class="keyword">register</span> oid   *oidp = objid + 1;
01299     <span class="keyword">register</span> u_long subidentifier;
01300     <span class="keyword">register</span> <span class="keywordtype">long</span>   length;
01301     u_long          asn_length;
01302 
01303     *type = *bufp++;
01304     bufp = asn_parse_length(bufp, &amp;asn_length);
01305     <span class="keywordflow">if</span> (_asn_parse_length_check(<span class=
"stringliteral">"parse objid"</span>, bufp, data,
01306                                 asn_length, *datalength))
01307         <span class="keywordflow">return</span> NULL;
01308 
01309     *datalength -= (int) asn_length + (bufp - data);
01310 
01311     DEBUGDUMPSETUP(<span class="stringliteral">"recv"</span>, data, bufp - data + asn_length);
01312 
01313     <span class="comment">/*</span>
01314 <span class="comment">     * Handle invalid object identifier encodings of the form 06 00 robustly </span>
01315 <span class="comment">     */</span>
01316     <span class="keywordflow">if</span> (asn_length == 0)
01317         objid[0] = objid[1] = 0;
01318 
01319     length = asn_length;
01320     (*objidlength)--;           <span class="comment">/* account for expansion of first byte */</span>
01321 
01322     <span class="keywordflow">while</span> (length &gt; 0 &amp;&amp; (*objidlength)-- &gt; 0) {
01323         subidentifier = 0;
01324         <span class="keywordflow">do</span> {                    <span class=
"comment">/* shift and add in low order 7 bits */</span>
01325             subidentifier =
01326                 (subidentifier &lt;&lt; 7) + (*(u_char *) bufp &amp; ~ASN_BIT8);
01327             length--;
01328         } <span class="keywordflow">while</span> (*(u_char *) bufp++ &amp; ASN_BIT8);        <span class=
"comment">/* last byte has high bit clear */</span>
01329 
01330 <span class="preprocessor">#if defined(EIGHTBIT_SUBIDS) || (SIZEOF_LONG != 4)</span>
01331         <span class="keywordflow">if</span> (subidentifier &gt; (u_long) MAX_SUBID) {
01332             ERROR_MSG(<span class="stringliteral">"subidentifier too large"</span>);
01333             <span class="keywordflow">return</span> NULL;
01334         }
01335 <span class="preprocessor">#endif</span>
01336         *oidp++ = (oid) subidentifier;
01337     }
01338 
01339     <span class="keywordflow">if</span> (0 != length) {
01340         ERROR_MSG(<span class="stringliteral">"OID length exceeds buffer size"</span>);
01341         <span class="keywordflow">return</span> NULL;
01342     }
01343 
01344     <span class="comment">/*</span>
01345 <span class="comment">     * The first two subidentifiers are encoded into the first component</span>
01346 <span class="comment">     * with the value (X * 40) + Y, where:</span>
01347 <span class="comment">     *  X is the value of the first subidentifier.</span>
01348 <span class="comment">     *  Y is the value of the second subidentifier.</span>
01349 <span class="comment">     */</span>
01350     subidentifier = (u_long) objid[1];
01351     <span class="keywordflow">if</span> (subidentifier == 0x2B) {
01352         objid[0] = 1;
01353         objid[1] = 3;
01354     } <span class="keywordflow">else</span> {
01355         <span class="keywordflow">if</span> (subidentifier &lt; 40) {
01356             objid[0] = 0;
01357             objid[1] = subidentifier;
01358         } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (subidentifier &lt; 80) {
01359             objid[0] = 1;
01360             objid[1] = subidentifier - 40;
01361         } <span class="keywordflow">else</span> {
01362             objid[0] = 2;
01363             objid[1] = subidentifier - 80;
01364         }
01365     }
01366 
01367     *objidlength = (int) (oidp - objid);
01368 
01369     DEBUGMSG((<span class="stringliteral">"dumpv_recv"</span>, <span class="stringliteral">"  ObjID: "</span>));
01370     DEBUGMSGOID((<span class="stringliteral">"dumpv_recv"</span>, objid, *objidlength));
01371     DEBUGMSG((<span class="stringliteral">"dumpv_recv"</span>, <span class="stringliteral">"\n"</span>));
01372     <span class="keywordflow">return</span> bufp;
01373 }
01374 
01398 u_char         *
01399 asn_build_objid(u_char * data,
01400                 size_t * datalength,
01401                 u_char type, oid * objid, size_t objidlength)
01402 {
01403     <span class="comment">/*</span>
01404 <span class="comment">     * ASN.1 objid ::= 0x06 asnlength subidentifier {subidentifier}*</span>
01405 <span class="comment">     * subidentifier ::= {leadingbyte}* lastbyte</span>
01406 <span class="comment">     * leadingbyte ::= 1 7bitvalue</span>
01407 <span class="comment">     * lastbyte ::= 0 7bitvalue</span>
01408 <span class="comment">     */</span>
01409     size_t          asnlength;
01410     <span class="keyword">register</span> oid   *op = objid;
01411     u_char          objid_size[MAX_OID_LEN];
01412     <span class="keyword">register</span> u_long objid_val;
01413     u_long          first_objid_val;
01414     <span class="keyword">register</span> <span class="keywordtype">int</span>    i;
01415 <span class="preprocessor">#ifndef SNMP_NO_DEBUGGING</span>
01416     u_char         *initdatap = data;
01417 <span class="preprocessor">#endif</span>
01418 
01419     <span class="comment">/*</span>
01420 <span class="comment">     * check if there are at least 2 sub-identifiers </span>
01421 <span class="comment">     */</span>
01422     <span class="keywordflow">if</span> (objidlength == 0) {
01423         <span class="comment">/*</span>
01424 <span class="comment">         * there are not, so make OID have two with value of zero </span>
01425 <span class="comment">         */</span>
01426         objid_val = 0;
01427         objidlength = 2;
01428     } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (objid[0] &gt; 2) {
01429         ERROR_MSG(<span class="stringliteral">"build objid: bad first subidentifier"</span>);
01430         <span class="keywordflow">return</span> NULL;
01431     } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (objidlength == 1) {
01432         <span class="comment">/*</span>
01433 <span class="comment">         * encode the first value </span>
01434 <span class="comment">         */</span>
01435         objid_val = (op[0] * 40);
01436         objidlength = 2;
01437         op++;
01438     } <span class="keywordflow">else</span> {
01439         <span class="comment">/*</span>
01440 <span class="comment">         * combine the first two values </span>
01441 <span class="comment">         */</span>
01442         <span class="keywordflow">if</span> ((op[1] &gt; 40) &amp;&amp;
01443             (op[0] &lt; 2)) {
01444             ERROR_MSG(<span class="stringliteral">"build objid: bad second subidentifier"</span>);
01445             <span class="keywordflow">return</span> NULL;
01446         }
01447         objid_val = (op[0] * 40) + op[1];
01448         op += 2;
01449     }
01450     first_objid_val = objid_val;
01451 
01452     <span class="comment">/*</span>
01453 <span class="comment">     * ditch illegal calls now </span>
01454 <span class="comment">     */</span>
01455     <span class="keywordflow">if</span> (objidlength &gt; MAX_OID_LEN)
01456         <span class="keywordflow">return</span> NULL;
01457 
01458     <span class="comment">/*</span>
01459 <span class="comment">     * calculate the number of bytes needed to store the encoded value </span>
01460 <span class="comment">     */</span>
01461     <span class="keywordflow">for</span> (i = 1, asnlength = 0;;) {
01462 
01463         CHECK_OVERFLOW_U(objid_val,5);
01464         <span class="keywordflow">if</span> (objid_val &lt; (unsigned) 0x80) {
01465             objid_size[i] = 1;
01466             asnlength += 1;
01467         } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (objid_val &lt; (unsigned) 0x4000) {
01468             objid_size[i] = 2;
01469             asnlength += 2;
01470         } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (objid_val &lt; (unsigned) 0x200000) {
01471             objid_size[i] = 3;
01472             asnlength += 3;
01473         } <span class="keywordflow">else</span> <span class=
"keywordflow">if</span> (objid_val &lt; (unsigned) 0x10000000) {
01474             objid_size[i] = 4;
01475             asnlength += 4;
01476         } <span class="keywordflow">else</span> {
01477             objid_size[i] = 5;
01478             asnlength += 5;
01479         }
01480         i++;
01481         <span class="keywordflow">if</span> (i &gt;= (int) objidlength)
01482             <span class="keywordflow">break</span>;
01483         objid_val = *op++;      <span class="comment">/* XXX - doesn't handle 2.X (X &gt; 40) */</span>
01484     }
01485 
01486     <span class="comment">/*</span>
01487 <span class="comment">     * store the ASN.1 tag and length </span>
01488 <span class="comment">     */</span>
01489     data = asn_build_header(data, datalength, type, asnlength);
01490     <span class="keywordflow">if</span> (_asn_build_header_check
01491         (<span class="stringliteral">"build objid"</span>, data, *datalength, asnlength))
01492         <span class="keywordflow">return</span> NULL;
01493 
01494     <span class="comment">/*</span>
01495 <span class="comment">     * store the encoded OID value </span>
01496 <span class="comment">     */</span>
01497     <span class="keywordflow">for</span> (i = 1, objid_val = first_objid_val, op = objid + 2;
01498          i &lt; (int) objidlength; i++) {
01499         <span class="keywordflow">if</span> (i != 1) {
01500             objid_val = *op++;
01501 <span class="preprocessor">#if SIZEOF_LONG != 4</span>
01502             <span class="keywordflow">if</span> (objid_val &gt; 0xffffffff) <span class=
"comment">/* already logged warning above */</span>
01503                 objid_val &amp;= 0xffffffff;
01504 <span class="preprocessor">#endif</span>
01505         }
01506         <span class="keywordflow">switch</span> (objid_size[i]) {
01507         <span class="keywordflow">case</span> 1:
01508             *data++ = (u_char) objid_val;
01509             <span class="keywordflow">break</span>;
01510 
01511         <span class="keywordflow">case</span> 2:
01512             *data++ = (u_char) ((objid_val &gt;&gt; 7) | 0x80);
01513             *data++ = (u_char) (objid_val &amp; 0x07f);
01514             <span class="keywordflow">break</span>;
01515 
01516         <span class="keywordflow">case</span> 3:
01517             *data++ = (u_char) ((objid_val &gt;&gt; 14) | 0x80);
01518             *data++ = (u_char) ((objid_val &gt;&gt; 7 &amp; 0x7f) | 0x80);
01519             *data++ = (u_char) (objid_val &amp; 0x07f);
01520             <span class="keywordflow">break</span>;
01521 
01522         <span class="keywordflow">case</span> 4:
01523             *data++ = (u_char) ((objid_val &gt;&gt; 21) | 0x80);
01524             *data++ = (u_char) ((objid_val &gt;&gt; 14 &amp; 0x7f) | 0x80);
01525             *data++ = (u_char) ((objid_val &gt;&gt; 7 &amp; 0x7f) | 0x80);
01526             *data++ = (u_char) (objid_val &amp; 0x07f);
01527             <span class="keywordflow">break</span>;
01528 
01529         <span class="keywordflow">case</span> 5:
01530             *data++ = (u_char) ((objid_val &gt;&gt; 28) | 0x80);
01531             *data++ = (u_char) ((objid_val &gt;&gt; 21 &amp; 0x7f) | 0x80);
01532             *data++ = (u_char) ((objid_val &gt;&gt; 14 &amp; 0x7f) | 0x80);
01533             *data++ = (u_char) ((objid_val &gt;&gt; 7 &amp; 0x7f) | 0x80);
01534             *data++ = (u_char) (objid_val &amp; 0x07f);
01535             <span class="keywordflow">break</span>;
01536         }
01537     }
01538 
01539     <span class="comment">/*</span>
01540 <span class="comment">     * return the length and data ptr </span>
01541 <span class="comment">     */</span>
01542     *datalength -= asnlength;
01543     DEBUGDUMPSETUP(<span class="stringliteral">"send"</span>, initdatap, data - initdatap);
01544     DEBUGMSG((<span class="stringliteral">"dumpv_send"</span>, <span class="stringliteral">"  ObjID: "</span>));
01545     DEBUGMSGOID((<span class="stringliteral">"dumpv_send"</span>, objid, objidlength));
01546     DEBUGMSG((<span class="stringliteral">"dumpv_send"</span>, <span class="stringliteral">"\n"</span>));
01547     <span class="keywordflow">return</span> data;
01548 }
01549 
01569 u_char         *
01570 asn_parse_null(u_char * data, size_t * datalength, u_char * type)
01571 {
01572     <span class="comment">/*</span>
01573 <span class="comment">     * ASN.1 null ::= 0x05 0x00</span>
01574 <span class="comment">     */</span>
01575     <span class="keyword">register</span> u_char *bufp = data;
01576     u_long          asn_length;
01577 
01578     *type = *bufp++;
01579     bufp = asn_parse_length(bufp, &amp;asn_length);
01580     <span class="keywordflow">if</span> (bufp == NULL) {
01581         ERROR_MSG(<span class="stringliteral">"parse null: bad length"</span>);
01582         <span class="keywordflow">return</span> NULL;
01583     }
01584     <span class="keywordflow">if</span> (asn_length != 0) {
01585         ERROR_MSG(<span class="stringliteral">"parse null: malformed ASN.1 null"</span>);
01586         <span class="keywordflow">return</span> NULL;
01587     }
01588 
01589     *datalength -= (bufp - data);
01590 
01591     DEBUGDUMPSETUP(<span class="stringliteral">"recv"</span>, data, bufp - data);
01592     DEBUGMSG((<span class="stringliteral">"dumpv_recv"</span>, <span class="stringliteral">"  NULL\n"</span>));
01593 
01594     <span class="keywordflow">return</span> bufp + asn_length;
01595 }
01596 
01597 
01618 u_char         *
01619 asn_build_null(u_char * data, size_t * datalength, u_char type)
01620 {
01621     <span class="comment">/*</span>
01622 <span class="comment">     * ASN.1 null ::= 0x05 0x00</span>
01623 <span class="comment">     */</span>
01624 <span class="preprocessor">#ifndef SNMP_NO_DEBUGGING</span>
01625     u_char         *initdatap = data;
01626 <span class="preprocessor">#endif</span>
01627     data = asn_build_header(data, datalength, type, 0);
01628     DEBUGDUMPSETUP(<span class="stringliteral">"send"</span>, initdatap, data - initdatap);
01629     DEBUGMSG((<span class="stringliteral">"dumpv_send"</span>, <span class="stringliteral">"  NULL\n"</span>));
01630     <span class="keywordflow">return</span> data;
01631 }
01632 
01656 u_char         *
01657 asn_parse_bitstring(u_char * data,
01658                     size_t * datalength,
01659                     u_char * type, u_char * str, size_t * strlength)
01660 {
01661     <span class="comment">/*</span>
01662 <span class="comment">     * bitstring ::= 0x03 asnlength unused {byte}*</span>
01663 <span class="comment">     */</span>
01664     <span class="keyword">static</span> <span class="keyword">const</span> <span class=
"keywordtype">char</span> *errpre = <span class="stringliteral">"parse bitstring"</span>;
01665     <span class="keyword">register</span> u_char *bufp = data;
01666     u_long          asn_length;
01667 
01668     *type = *bufp++;
01669     bufp = asn_parse_length(bufp, &amp;asn_length);
01670     <span class="keywordflow">if</span> (_asn_parse_length_check(errpre, bufp, data,
01671                                 asn_length, *datalength))
01672         <span class="keywordflow">return</span> NULL;
01673 
01674     <span class="keywordflow">if</span> ((size_t) asn_length &gt; *strlength) {
01675         _asn_length_err(errpre, (size_t) asn_length, *strlength);
01676         <span class="keywordflow">return</span> NULL;
01677     }
01678     <span class="keywordflow">if</span> (_asn_bitstring_check(errpre, asn_length, *bufp))
01679         <span class="keywordflow">return</span> NULL;
01680 
01681     DEBUGDUMPSETUP(<span class="stringliteral">"recv"</span>, data, bufp - data);
01682     DEBUGMSG((<span class="stringliteral">"dumpv_recv"</span>, <span class="stringliteral">"  Bitstring: "</span>));
01683     DEBUGMSGHEX((<span class="stringliteral">"dumpv_recv"</span>, data, asn_length));
01684     DEBUGMSG((<span class="stringliteral">"dumpv_recv"</span>, <span class="stringliteral">"\n"</span>));
01685 
01686     memmove(str, bufp, asn_length);
01687     *strlength = (int) asn_length;
01688     *datalength -= (int) asn_length + (bufp - data);
01689     <span class="keywordflow">return</span> bufp + asn_length;
01690 }
01691 
01692 
01715 u_char         *
01716 asn_build_bitstring(u_char * data,
01717                     size_t * datalength,
01718                     u_char type, <span class="keyword">const</span> u_char * str, size_t strlength)
01719 {
01720     <span class="comment">/*</span>
01721 <span class="comment">     * ASN.1 bit string ::= 0x03 asnlength unused {byte}*</span>
01722 <span class="comment">     */</span>
01723     <span class="keyword">static</span> <span class="keyword">const</span> <span class=
"keywordtype">char</span> *errpre = <span class="stringliteral">"build bitstring"</span>;
01724     <span class="keywordflow">if</span> (_asn_bitstring_check
01725         (errpre, strlength, (u_char)((str) ? *str :  0)))
01726         <span class="keywordflow">return</span> NULL;
01727 
01728     data = asn_build_header(data, datalength, type, strlength);
01729     <span class="keywordflow">if</span> (_asn_build_header_check(errpre, data, *datalength, strlength))
01730         <span class="keywordflow">return</span> NULL;
01731 
01732     <span class="keywordflow">if</span> (strlength &gt; 0 &amp;&amp; str)
01733         memmove(data, str, strlength);
01734     <span class="keywordflow">else</span> <span class="keywordflow">if</span> (strlength &gt; 0 &amp;&amp; !str) {
01735         ERROR_MSG(<span class="stringliteral">"no string passed into asn_build_bitstring\n"</span>);
01736         <span class="keywordflow">return</span> NULL;
01737     }
01738 
01739     *datalength -= strlength;
01740     DEBUGDUMPSETUP(<span class="stringliteral">"send"</span>, data, strlength);
01741     DEBUGMSG((<span class="stringliteral">"dumpv_send"</span>, <span class="stringliteral">"  Bitstring: "</span>));
01742     DEBUGMSGHEX((<span class="stringliteral">"dumpv_send"</span>, data, strlength));
01743     DEBUGMSG((<span class="stringliteral">"dumpv_send"</span>, <span class="stringliteral">"\n"</span>));
01744     <span class="keywordflow">return</span> data + strlength;
01745 }
01746 
01769 u_char         *
01770 asn_parse_unsigned_int64(u_char * data,
01771                          size_t * datalength,
01772                          u_char * type,
01773                          <span class="keyword">struct</span> counter64 * cp, size_t countersize)
01774 {
01775     <span class="comment">/*</span>
01776 <span class="comment">     * ASN.1 integer ::= 0x02 asnlength byte {byte}*</span>
01777 <span class="comment">     */</span>
01778     <span class="keyword">static</span> <span class="keyword">const</span> <span class=
"keywordtype">char</span> *errpre = <span class="stringliteral">"parse uint64"</span>;
01779     <span class="keyword">const</span> <span class="keywordtype">int</span>       uint64sizelimit = (4 * 2) + 1;
01780     <span class="keyword">register</span> u_char *bufp = data;
01781     u_long          asn_length;
01782     <span class="keyword">register</span> u_long low = 0, high = 0;
01783 
01784     <span class="keywordflow">if</span> (countersize != <span class="keyword">sizeof</span>(<span class=
"keyword">struct </span>counter64)) {
01785         _asn_size_err(errpre, countersize, <span class="keyword">sizeof</span>(<span class=
"keyword">struct</span> counter64));
01786         <span class="keywordflow">return</span> NULL;
01787     }
01788     *type = *bufp++;
01789     bufp = asn_parse_length(bufp, &amp;asn_length);
01790     <span class="keywordflow">if</span> (_asn_parse_length_check
01791         (errpre, bufp, data, asn_length, *datalength))
01792         <span class="keywordflow">return</span> NULL;
01793 
01794     DEBUGDUMPSETUP(<span class="stringliteral">"recv"</span>, data, bufp - data);
01795 <span class="preprocessor">#ifdef OPAQUE_SPECIAL_TYPES</span>
01796     <span class="comment">/*</span>
01797 <span class="comment">     * 64 bit counters as opaque </span>
01798 <span class="comment">     */</span>
01799     <span class="keywordflow">if</span> ((*type == ASN_OPAQUE) &amp;&amp;
01800         (asn_length &lt;= ASN_OPAQUE_COUNTER64_MX_BER_LEN) &amp;&amp;
01801         (*bufp == ASN_OPAQUE_TAG1) &amp;&amp;
01802         ((*(bufp + 1) == ASN_OPAQUE_COUNTER64) ||
01803          (*(bufp + 1) == ASN_OPAQUE_U64))) {
01804         <span class="comment">/*</span>
01805 <span class="comment">         * change type to Counter64 or U64 </span>
01806 <span class="comment">         */</span>
01807         *type = *(bufp + 1);
01808         <span class="comment">/*</span>
01809 <span class="comment">         * value is encoded as special format </span>
01810 <span class="comment">         */</span>
01811         bufp = asn_parse_length(bufp + 2, &amp;asn_length);
01812         <span class="keywordflow">if</span> (_asn_parse_length_check(<span class=
"stringliteral">"parse opaque uint64"</span>, bufp, data,
01813                                     asn_length, *datalength))
01814             <span class="keywordflow">return</span> NULL;
01815     }
01816 <span class="preprocessor">#endif                          </span><span class="comment">/* OPAQUE_SPECIAL_TYPES */</span>
01817     <span class="keywordflow">if</span> (((int) asn_length &gt; uint64sizelimit) ||
01818         (((int) asn_length == uint64sizelimit) &amp;&amp; *bufp != 0x00)) {
01819         _asn_length_err(errpre, (size_t) asn_length, uint64sizelimit);
01820         <span class="keywordflow">return</span> NULL;
01821     }
01822     *datalength -= (int) asn_length + (bufp - data);
01823     <span class="keywordflow">if</span> (*bufp &amp; 0x80) {
01824         low = 0xFFFFFF;     <span class="comment">/* first byte bit 1 means start the data with 1s */</span>
01825         high = 0xFFFFFF;
01826     }
01827 
01828     <span class="keywordflow">while</span> (asn_length--) {
01829         high = ((0x00FFFFFF &amp; high) &lt;&lt; 8) | ((low &amp; 0xFF000000) &gt;&gt; 24);
01830         low = ((low &amp; 0x00FFFFFF) &lt;&lt; 8) | *bufp++;
01831     }
01832 
01833     CHECK_OVERFLOW_U(high,6);
01834     CHECK_OVERFLOW_U(low,6);
01835 
01836     cp-&gt;low = low;
01837     cp-&gt;high = high;
01838 
01839     DEBUGIF(<span class="stringliteral">"dumpv_recv"</span>) {
01840         <span class="keywordtype">char</span>            i64buf[I64CHARSZ + 1];
01841         printU64(i64buf, cp);
01842         DEBUGMSG((<span class="stringliteral">"dumpv_recv"</span>, <span class=
"stringliteral">"Counter64: %s"</span>, i64buf));
01843     }
01844 
01845     <span class="keywordflow">return</span> bufp;
01846 }
01847 
01848 
01870 u_char         *
01871 asn_build_unsigned_int64(u_char * data,
01872                          size_t * datalength,
01873                          u_char type,
01874                          <span class="keyword">const</span> <span class=
"keyword">struct</span> counter64 * cp, size_t countersize)
01875 {
01876     <span class="comment">/*</span>
01877 <span class="comment">     * ASN.1 integer ::= 0x02 asnlength byte {byte}*</span>
01878 <span class="comment">     */</span>
01879 
01880     <span class="keyword">register</span> u_long low, high;
01881     <span class="keyword">register</span> u_long mask, mask2;
01882     <span class="keywordtype">int</span>             add_null_byte = 0;
01883     size_t          intsize;
01884 <span class="preprocessor">#ifndef SNMP_NO_DEBUGGING</span>
01885     u_char         *initdatap = data;
01886 <span class="preprocessor">#endif</span>
01887 
01888     <span class="keywordflow">if</span> (countersize != <span class="keyword">sizeof</span>(<span class=
"keyword">struct </span>counter64)) {
01889         _asn_size_err(<span class="stringliteral">"build uint64"</span>, countersize,
01890                       <span class="keyword">sizeof</span>(<span class="keyword">struct</span> counter64));
01891         <span class="keywordflow">return</span> NULL;
01892     }
01893     intsize = 8;
01894     low = cp-&gt;low;
01895     high = cp-&gt;high;
01896 
01897     CHECK_OVERFLOW_U(high,7);
01898     CHECK_OVERFLOW_U(low,7);
01899 
01900     mask = ((u_long) 0xFF) &lt;&lt; (8 * (<span class="keyword">sizeof</span>(long) - 1));
01901     <span class="comment">/*</span>
01902 <span class="comment">     * mask is 0xFF000000 on a big-endian machine </span>
01903 <span class="comment">     */</span>
01904     <span class="keywordflow">if</span> ((u_char) ((high &amp; mask) &gt;&gt; (8 * (<span class=
"keyword">sizeof</span>(long) - 1))) &amp; 0x80) {
01905         <span class="comment">/*</span>
01906 <span class="comment">         * if MSB is set </span>
01907 <span class="comment">         */</span>
01908         add_null_byte = 1;
01909         intsize++;
01910     } <span class="keywordflow">else</span> {
01911         <span class="comment">/*</span>
01912 <span class="comment">         * Truncate "unnecessary" bytes off of the most significant end of this 2's</span>
01913 <span class="comment">         * complement integer.</span>
01914 <span class="comment">         * There should be no sequence of 9 consecutive 1's or 0's at the most</span>
01915 <span class="comment">         * significant end of the integer.</span>
01916 <span class="comment">         */</span>
01917         mask2 = ((u_long) 0x1FF) &lt;&lt; ((8 * (<span class="keyword">sizeof</span>(long) - 1)) - 1);
01918         <span class="comment">/*</span>
01919 <span class="comment">         * mask2 is 0xFF800000 on a big-endian machine </span>
01920 <span class="comment">         */</span>
01921         <span class="keywordflow">while</span> ((((high &amp; mask2) == 0) || ((high &amp; mask2) == mask2))
01922                &amp;&amp; intsize &gt; 1) {
01923             intsize--;
01924             high = (high &lt;&lt; 8)
01925                 | ((low &amp; mask) &gt;&gt; (8 * (<span class="keyword">sizeof</span>(long) - 1)));
01926             low &lt;&lt;= 8;
01927         }
01928     }
01929 <span class="preprocessor">#ifdef OPAQUE_SPECIAL_TYPES</span>
01930     <span class="comment">/*</span>
01931 <span class="comment">     * encode a Counter64 as an opaque (it also works in SNMPv1) </span>
01932 <span class="comment">     */</span>
01933     <span class="comment">/*</span>
01934 <span class="comment">     * turn into Opaque holding special tagged value </span>
01935 <span class="comment">     */</span>
01936     <span class="keywordflow">if</span> (type == ASN_OPAQUE_COUNTER64) {
01937         <span class="comment">/*</span>
01938 <span class="comment">         * put the tag and length for the Opaque wrapper </span>
01939 <span class="comment">         */</span>
01940         data = asn_build_header(data, datalength, ASN_OPAQUE, intsize + 3);
01941         <span class="keywordflow">if</span> (_asn_build_header_check
01942             (<span class="stringliteral">"build counter u64"</span>, data, *datalength, intsize + 3))
01943             <span class="keywordflow">return</span> NULL;
01944 
01945         <span class="comment">/*</span>
01946 <span class="comment">         * put the special tag and length </span>
01947 <span class="comment">         */</span>
01948         *data++ = ASN_OPAQUE_TAG1;
01949         *data++ = ASN_OPAQUE_COUNTER64;
01950         *data++ = (u_char) intsize;
01951         *datalength = *datalength - 3;
01952     } <span class="keywordflow">else</span>
01953         <span class="comment">/*</span>
01954 <span class="comment">         * Encode the Unsigned int64 in an opaque </span>
01955 <span class="comment">         */</span>
01956         <span class="comment">/*</span>
01957 <span class="comment">         * turn into Opaque holding special tagged value </span>
01958 <span class="comment">         */</span>
01959     <span class="keywordflow">if</span> (type == ASN_OPAQUE_U64) {
01960         <span class="comment">/*</span>
01961 <span class="comment">         * put the tag and length for the Opaque wrapper </span>
01962 <span class="comment">         */</span>
01963         data = asn_build_header(data, datalength, ASN_OPAQUE, intsize + 3);
01964         <span class="keywordflow">if</span> (_asn_build_header_check
01965             (<span class="stringliteral">"build opaque u64"</span>, data, *datalength, intsize + 3))
01966             <span class="keywordflow">return</span> NULL;
01967 
01968         <span class="comment">/*</span>
01969 <span class="comment">         * put the special tag and length </span>
01970 <span class="comment">         */</span>
01971         *data++ = ASN_OPAQUE_TAG1;
01972         *data++ = ASN_OPAQUE_U64;
01973         *data++ = (u_char) intsize;
01974         *datalength = *datalength - 3;
01975     } <span class="keywordflow">else</span> {
01976 <span class="preprocessor">#endif                          </span><span class="comment">/* OPAQUE_SPECIAL_TYPES */</span>
01977         data = asn_build_header(data, datalength, type, intsize);
01978         <span class="keywordflow">if</span> (_asn_build_header_check
01979             (<span class="stringliteral">"build uint64"</span>, data, *datalength, intsize))
01980             <span class="keywordflow">return</span> NULL;
01981 
01982 <span class="preprocessor">#ifdef OPAQUE_SPECIAL_TYPES</span>
01983     }
01984 <span class="preprocessor">#endif                          </span><span class="comment">/* OPAQUE_SPECIAL_TYPES */</span>
01985     *datalength -= intsize;
01986     <span class="keywordflow">if</span> (add_null_byte == 1) {
01987         *data++ = <span class="charliteral">'\0'</span>;
01988         intsize--;
01989     }
01990     <span class="keywordflow">while</span> (intsize--) {
01991         *data++ = (u_char) ((high &amp; mask) &gt;&gt; (8 * (<span class="keyword">sizeof</span>(long) - 1)));
01992         high = (high &lt;&lt; 8)
01993             | ((low &amp; mask) &gt;&gt; (8 * (<span class="keyword">sizeof</span>(long) - 1)));
01994         low &lt;&lt;= 8;
01995 
01996     }
01997     DEBUGDUMPSETUP(<span class="stringliteral">"send"</span>, initdatap, data - initdatap);
01998     DEBUGIF(<span class="stringliteral">"dumpv_send"</span>) {
01999         <span class="keywordtype">char</span>            i64buf[I64CHARSZ + 1];
02000         printU64(i64buf, cp);
02001         DEBUGMSG((<span class="stringliteral">"dumpv_send"</span>, i64buf));
02002     }
02003     <span class="keywordflow">return</span> data;
02004 }
02005 
02006 <span class="preprocessor">#ifdef OPAQUE_SPECIAL_TYPES</span>
02007 
02008 
02032 u_char         *
02033 asn_parse_signed_int64(u_char * data,
02034                        size_t * datalength,
02035                        u_char * type,
02036                        <span class="keyword">struct</span> counter64 * cp, size_t countersize)
02037 {
02038     <span class="keyword">static</span> <span class="keyword">const</span> <span class=
"keywordtype">char</span> *errpre = <span class="stringliteral">"parse int64"</span>;
02039     <span class="keyword">const</span> <span class="keywordtype">int</span>       int64sizelimit = (4 * 2) + 1;
02040     <span class="keywordtype">char</span>            ebuf[128];
02041     <span class="keyword">register</span> u_char *bufp = data;
02042     u_long          asn_length;
02043     <span class="keyword">register</span> u_int  low = 0, high = 0;
02044 
02045     <span class="keywordflow">if</span> (countersize != <span class="keyword">sizeof</span>(<span class=
"keyword">struct </span>counter64)) {
02046         _asn_size_err(errpre, countersize, <span class="keyword">sizeof</span>(<span class=
"keyword">struct</span> counter64));
02047         <span class="keywordflow">return</span> NULL;
02048     }
02049     *type = *bufp++;
02050     bufp = asn_parse_length(bufp, &amp;asn_length);
02051     <span class="keywordflow">if</span> (_asn_parse_length_check
02052         (errpre, bufp, data, asn_length, *datalength))
02053         <span class="keywordflow">return</span> NULL;
02054 
02055     DEBUGDUMPSETUP(<span class="stringliteral">"recv"</span>, data, bufp - data);
02056     <span class="keywordflow">if</span> ((*type == ASN_OPAQUE) &amp;&amp;
02057         (asn_length &lt;= ASN_OPAQUE_COUNTER64_MX_BER_LEN) &amp;&amp;
02058         (*bufp == ASN_OPAQUE_TAG1) &amp;&amp; (*(bufp + 1) == ASN_OPAQUE_I64)) {
02059         <span class="comment">/*</span>
02060 <span class="comment">         * change type to Int64 </span>
02061 <span class="comment">         */</span>
02062         *type = *(bufp + 1);
02063         <span class="comment">/*</span>
02064 <span class="comment">         * value is encoded as special format </span>
02065 <span class="comment">         */</span>
02066         bufp = asn_parse_length(bufp + 2, &amp;asn_length);
02067         <span class="keywordflow">if</span> (_asn_parse_length_check(<span class=
"stringliteral">"parse opaque int64"</span>, bufp, data,
02068                                     asn_length, *datalength))
02069             <span class="keywordflow">return</span> NULL;
02070     }
02071     <span class="comment">/*</span>
02072 <span class="comment">     * this should always have been true until snmp gets int64 PDU types </span>
02073 <span class="comment">     */</span>
02074     <span class="keywordflow">else</span> {
02075         snprintf(ebuf, <span class="keyword">sizeof</span>(ebuf),
02076                 <span class="stringliteral">"%s: wrong type: %d, len %d, buf bytes (%02X,%02X)"</span>,
02077                 errpre, *type, (<span class="keywordtype">int</span>) asn_length, *bufp, *(bufp + 1));
02078         ebuf[ <span class="keyword">sizeof</span>(ebuf)-1 ] = 0;
02079         ERROR_MSG(ebuf);
02080         <span class="keywordflow">return</span> NULL;
02081     }
02082     <span class="keywordflow">if</span> (((int) asn_length &gt; int64sizelimit) ||
02083         (((int) asn_length == int64sizelimit) &amp;&amp; *bufp != 0x00)) {
02084         _asn_length_err(errpre, (size_t) asn_length, int64sizelimit);
02085         <span class="keywordflow">return</span> NULL;
02086     }
02087     *datalength -= (int) asn_length + (bufp - data);
02088     <span class="keywordflow">if</span> (*bufp &amp; 0x80) {
02089         low = 0xFFFFFF;     <span class="comment">/* first byte bit 1 means start the data with 1s */</span>
02090         high = 0xFFFFFF;
02091     }
02092 
02093     <span class="keywordflow">while</span> (asn_length--) {
02094         high = ((0x00FFFFFF &amp; high) &lt;&lt; 8) | ((low &amp; 0xFF000000) &gt;&gt; 24);
02095         low = ((low &amp; 0x00FFFFFF) &lt;&lt; 8) | *bufp++;
02096     }
02097 
02098     CHECK_OVERFLOW_U(high,8);
02099     CHECK_OVERFLOW_U(low,8);
02100 
02101     cp-&gt;low = low;
02102     cp-&gt;high = high;
02103 
02104     DEBUGIF(<span class="stringliteral">"dumpv_recv"</span>) {
02105         <span class="keywordtype">char</span>            i64buf[I64CHARSZ + 1];
02106         printI64(i64buf, cp);
02107         DEBUGMSG((<span class="stringliteral">"dumpv_recv"</span>, <span class=
"stringliteral">"Integer64: %s"</span>, i64buf));
02108     }
02109 
02110     <span class="keywordflow">return</span> bufp;
02111 }
02112 
02113 
02114 
02136 u_char         *
02137 asn_build_signed_int64(u_char * data,
02138                        size_t * datalength,
02139                        u_char type,
02140                        <span class="keyword">const</span> <span class=
"keyword">struct</span> counter64 * cp, size_t countersize)
02141 {
02142     <span class="comment">/*</span>
02143 <span class="comment">     * ASN.1 integer ::= 0x02 asnlength byte {byte}*</span>
02144 <span class="comment">     */</span>
02145 
02146     <span class="keyword">struct </span>counter64 c64;
02147     <span class="keyword">register</span> u_int  mask, mask2;
02148     u_long          low, high;
02149     size_t          intsize;
02150 <span class="preprocessor">#ifndef SNMP_NO_DEBUGGING</span>
02151     u_char         *initdatap = data;
02152 <span class="preprocessor">#endif</span>
02153 
02154     <span class="keywordflow">if</span> (countersize != <span class="keyword">sizeof</span>(<span class=
"keyword">struct </span>counter64)) {
02155         _asn_size_err(<span class="stringliteral">"build int64"</span>, countersize,
02156                       <span class="keyword">sizeof</span>(<span class="keyword">struct</span> counter64));
02157         <span class="keywordflow">return</span> NULL;
02158     }
02159     intsize = 8;
02160     memcpy(&amp;c64, cp, <span class="keyword">sizeof</span>(<span class="keyword">struct</span> counter64)); <span class=
"comment">/* we're may modify it */</span>
02161     low = c64.low;
02162     high = c64.high;
02163 
02164     CHECK_OVERFLOW_S(high,9);
02165     CHECK_OVERFLOW_U(low,9);
02166 
02167     <span class="comment">/*</span>
02168 <span class="comment">     * Truncate "unnecessary" bytes off of the most significant end of this</span>
02169 <span class="comment">     * 2's complement integer.  There should be no sequence of 9</span>
02170 <span class="comment">     * consecutive 1's or 0's at the most significant end of the</span>
02171 <span class="comment">     * integer.</span>
02172 <span class="comment">     */</span>
02173     mask = ((u_int) 0xFF) &lt;&lt; (8 * (<span class="keyword">sizeof</span>(u_int) - 1));
02174     mask2 = ((u_int) 0x1FF) &lt;&lt; ((8 * (<span class="keyword">sizeof</span>(u_int) - 1)) - 1);
02175     <span class="comment">/*</span>
02176 <span class="comment">     * mask is 0xFF800000 on a big-endian machine </span>
02177 <span class="comment">     */</span>
02178     <span class="keywordflow">while</span> ((((high &amp; mask2) == 0) || ((high &amp; mask2) == mask2))
02179            &amp;&amp; intsize &gt; 1) {
02180         intsize--;
02181         high = (high &lt;&lt; 8)
02182             | ((low &amp; mask) &gt;&gt; (8 * (<span class="keyword">sizeof</span>(u_int) - 1)));
02183         low &lt;&lt;= 8;
02184     }
02185     <span class="comment">/*</span>
02186 <span class="comment">     * until a real int64 gets incorperated into SNMP, we are going to</span>
02187 <span class="comment">     * encode it as an opaque instead.  First, we build the opaque</span>
02188 <span class="comment">     * header and then the int64 tag type we use to mark it as an</span>
02189 <span class="comment">     * int64 in the opaque string. </span>
02190 <span class="comment">     */</span>
02191     data = asn_build_header(data, datalength, ASN_OPAQUE, intsize + 3);
02192     <span class="keywordflow">if</span> (_asn_build_header_check
02193         (<span class="stringliteral">"build int64"</span>, data, *datalength, intsize + 3))
02194         <span class="keywordflow">return</span> NULL;
02195 
02196     *data++ = ASN_OPAQUE_TAG1;
02197     *data++ = ASN_OPAQUE_I64;
02198     *data++ = (u_char) intsize;
02199     *datalength -= (3 + intsize);
02200 
02201     <span class="keywordflow">while</span> (intsize--) {
02202         *data++ = (u_char) ((high &amp; mask) &gt;&gt; (8 * (<span class="keyword">sizeof</span>(u_int) - 1)));
02203         high = (high &lt;&lt; 8)
02204             | ((low &amp; mask) &gt;&gt; (8 * (<span class="keyword">sizeof</span>(u_int) - 1)));
02205         low &lt;&lt;= 8;
02206     }
02207     DEBUGDUMPSETUP(<span class="stringliteral">"send"</span>, initdatap, data - initdatap);
02208     DEBUGIF(<span class="stringliteral">"dumpv_send"</span>) {
02209         <span class="keywordtype">char</span>            i64buf[I64CHARSZ + 1];
02210         printU64(i64buf, cp);
02211         DEBUGMSG((<span class="stringliteral">"dumpv_send"</span>, i64buf));
02212     }
02213     <span class="keywordflow">return</span> data;
02214 }
02215 
02216 
02238 u_char         *
02239 asn_parse_float(u_char * data,
02240                 size_t * datalength,
02241                 u_char * type, <span class="keywordtype">float</span> *floatp, size_t floatsize)
02242 {
02243     <span class="keyword">register</span> u_char *bufp = data;
02244     u_long          asn_length;
02245     <span class="keyword">union </span>{
02246         <span class="keywordtype">float</span>           floatVal;
02247         <span class="keywordtype">long</span>            longVal;
02248         u_char          c[<span class="keyword">sizeof</span>(float)];
02249     } fu;
02250 
02251     <span class="keywordflow">if</span> (floatsize != <span class="keyword">sizeof</span>(float)) {
02252         _asn_size_err(<span class="stringliteral">"parse float"</span>, floatsize, <span class=
"keyword">sizeof</span>(<span class="keywordtype">float</span>));
02253         <span class="keywordflow">return</span> NULL;
02254     }
02255     *type = *bufp++;
02256     bufp = asn_parse_length(bufp, &amp;asn_length);
02257     <span class="keywordflow">if</span> (_asn_parse_length_check(<span class=
"stringliteral">"parse float"</span>, bufp, data,
02258                                 asn_length, *datalength))
02259         <span class="keywordflow">return</span> NULL;
02260 
02261     DEBUGDUMPSETUP(<span class="stringliteral">"recv"</span>, data, bufp - data + asn_length);
02262     <span class="comment">/*</span>
02263 <span class="comment">     * the float is encoded as an opaque </span>
02264 <span class="comment">     */</span>
02265     <span class="keywordflow">if</span> ((*type == ASN_OPAQUE) &amp;&amp;
02266         (asn_length == ASN_OPAQUE_FLOAT_BER_LEN) &amp;&amp;
02267         (*bufp == ASN_OPAQUE_TAG1) &amp;&amp; (*(bufp + 1) == ASN_OPAQUE_FLOAT)) {
02268 
02269         <span class="comment">/*</span>
02270 <span class="comment">         * value is encoded as special format </span>
02271 <span class="comment">         */</span>
02272         bufp = asn_parse_length(bufp + 2, &amp;asn_length);
02273         <span class="keywordflow">if</span> (_asn_parse_length_check(<span class=
"stringliteral">"parse opaque float"</span>, bufp, data,
02274                                     asn_length, *datalength))
02275             <span class="keywordflow">return</span> NULL;
02276 
02277         <span class="comment">/*</span>
02278 <span class="comment">         * change type to Float </span>
02279 <span class="comment">         */</span>
02280         *type = ASN_OPAQUE_FLOAT;
02281     }
02282 
02283     <span class="keywordflow">if</span> (asn_length != <span class="keyword">sizeof</span>(float)) {
02284         _asn_size_err(<span class="stringliteral">"parse seq float"</span>, asn_length, <span class=
"keyword">sizeof</span>(<span class="keywordtype">float</span>));
02285         <span class="keywordflow">return</span> NULL;
02286     }
02287 
02288     *datalength -= (int) asn_length + (bufp - data);
02289     memcpy(&amp;fu.c[0], bufp, asn_length);
02290 
02291     <span class="comment">/*</span>
02292 <span class="comment">     * correct for endian differences </span>
02293 <span class="comment">     */</span>
02294     fu.longVal = ntohl(fu.longVal);
02295 
02296     *floatp = fu.floatVal;
02297 
02298     DEBUGMSG((<span class="stringliteral">"dumpv_recv"</span>, <span class=
"stringliteral">"Opaque float: %f\n"</span>, *floatp));
02299     <span class="keywordflow">return</span> bufp;
02300 }
02301 
02325 u_char         *
02326 asn_build_float(u_char * data,
02327                 size_t * datalength,
02328                 u_char type, <span class="keyword">const</span> <span class=
"keywordtype">float</span> *floatp, size_t floatsize)
02329 {
02330     <span class="keyword">union </span>{
02331         <span class="keywordtype">float</span>           floatVal;
02332         <span class="keywordtype">int</span>             intVal;
02333         u_char          c[<span class="keyword">sizeof</span>(float)];
02334     } fu;
02335 <span class="preprocessor">#ifndef SNMP_NO_DEBUGGING</span>
02336     u_char         *initdatap = data;
02337 <span class="preprocessor">#endif</span>
02338 
02339     <span class="keywordflow">if</span> (floatsize != <span class="keyword">sizeof</span>(float)) {
02340         _asn_size_err(<span class="stringliteral">"build float"</span>, floatsize, <span class=
"keyword">sizeof</span>(<span class="keywordtype">float</span>));
02341         <span class="keywordflow">return</span> NULL;
02342     }
02343     <span class="comment">/*</span>
02344 <span class="comment">     * encode the float as an opaque </span>
02345 <span class="comment">     */</span>
02346     <span class="comment">/*</span>
02347 <span class="comment">     * turn into Opaque holding special tagged value </span>
02348 <span class="comment">     */</span>
02349 
02350     <span class="comment">/*</span>
02351 <span class="comment">     * put the tag and length for the Opaque wrapper </span>
02352 <span class="comment">     */</span>
02353     data = asn_build_header(data, datalength, ASN_OPAQUE, floatsize + 3);
02354     <span class="keywordflow">if</span> (_asn_build_header_check
02355         (<span class="stringliteral">"build float"</span>, data, *datalength, (floatsize + 3)))
02356         <span class="keywordflow">return</span> NULL;
02357 
02358     <span class="comment">/*</span>
02359 <span class="comment">     * put the special tag and length </span>
02360 <span class="comment">     */</span>
02361     *data++ = ASN_OPAQUE_TAG1;
02362     *data++ = ASN_OPAQUE_FLOAT;
02363     *data++ = (u_char) floatsize;
02364     *datalength = *datalength - 3;
02365 
02366     fu.floatVal = *floatp;
02367     <span class="comment">/*</span>
02368 <span class="comment">     * correct for endian differences </span>
02369 <span class="comment">     */</span>
02370     fu.intVal = htonl(fu.intVal);
02371 
02372     *datalength -= floatsize;
02373     memcpy(data, &amp;fu.c[0], floatsize);
02374 
02375     DEBUGDUMPSETUP(<span class="stringliteral">"send"</span>, initdatap, data - initdatap);
02376     DEBUGMSG((<span class="stringliteral">"dumpv_send"</span>, <span class=
"stringliteral">"Opaque float: %f\n"</span>, *floatp));
02377     data += floatsize;
02378     <span class="keywordflow">return</span> data;
02379 }
02380 
02381 
02403 u_char         *
02404 asn_parse_double(u_char * data,
02405                  size_t * datalength,
02406                  u_char * type, <span class="keywordtype">double</span> *doublep, size_t doublesize)
02407 {
02408     <span class="keyword">register</span> u_char *bufp = data;
02409     u_long          asn_length;
02410     <span class="keywordtype">long</span>            tmp;
02411     <span class="keyword">union </span>{
02412         <span class="keywordtype">double</span>          doubleVal;
02413         <span class="keywordtype">int</span>             intVal[2];
02414         u_char          c[<span class="keyword">sizeof</span>(double)];
02415     } fu;
02416 
02417 
02418     <span class="keywordflow">if</span> (doublesize != <span class="keyword">sizeof</span>(double)) {
02419         _asn_size_err(<span class="stringliteral">"parse double"</span>, doublesize, <span class=
"keyword">sizeof</span>(<span class="keywordtype">double</span>));
02420         <span class="keywordflow">return</span> NULL;
02421     }
02422     *type = *bufp++;
02423     bufp = asn_parse_length(bufp, &amp;asn_length);
02424     <span class="keywordflow">if</span> (_asn_parse_length_check(<span class=
"stringliteral">"parse double"</span>, bufp, data,
02425                                 asn_length, *datalength))
02426         <span class="keywordflow">return</span> NULL;
02427 
02428     DEBUGDUMPSETUP(<span class="stringliteral">"recv"</span>, data, bufp - data + asn_length);
02429     <span class="comment">/*</span>
02430 <span class="comment">     * the double is encoded as an opaque </span>
02431 <span class="comment">     */</span>
02432     <span class="keywordflow">if</span> ((*type == ASN_OPAQUE) &amp;&amp;
02433         (asn_length == ASN_OPAQUE_DOUBLE_BER_LEN) &amp;&amp;
02434         (*bufp == ASN_OPAQUE_TAG1) &amp;&amp; (*(bufp + 1) == ASN_OPAQUE_DOUBLE)) {
02435 
02436         <span class="comment">/*</span>
02437 <span class="comment">         * value is encoded as special format </span>
02438 <span class="comment">         */</span>
02439         bufp = asn_parse_length(bufp + 2, &amp;asn_length);
02440         <span class="keywordflow">if</span> (_asn_parse_length_check(<span class=
"stringliteral">"parse opaque double"</span>, bufp, dat