Nut/OS  4.10.3
API Reference
snmp.c
Go to the documentation of this file.
00001 /*
00002  * Copyright 1998-2007 by egnite Software GmbH
00003  * Copyright 1988, 1989, 1991, 1992 by Carnegie Mellon University
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  *
00009  * 1. Redistributions of source code must retain the above copyright
00010  *    notice, this list of conditions and the following disclaimer.
00011  * 2. Redistributions in binary form must reproduce the above copyright
00012  *    notice, this list of conditions and the following disclaimer in the
00013  *    documentation and/or other materials provided with the distribution.
00014  * 3. Neither the name of the copyright holders nor the names of
00015  *    contributors may be used to endorse or promote products derived
00016  *    from this software without specific prior written permission.
00017  *
00018  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00019  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00020  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00021  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00022  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00023  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00024  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
00025  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
00026  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00027  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
00028  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00029  * SUCH DAMAGE.
00030  *
00031  * For additional information see http://www.ethernut.de/
00032  */
00033 
00034 #include <pro/snmp.h>
00035 #include <pro/snmp_api.h>
00036 
00041 
00065 CONST uint8_t *SnmpVarParse(CONST uint8_t * data, size_t * dlen, OID * name, size_t * nlen, uint8_t * type,
00066                            uint8_t ** value, size_t * vlen)
00067 {
00068     CONST uint8_t *dp;
00069     uint8_t vtype = ASN_SEQUENCE | ASN_CONSTRUCTOR;
00070     size_t len = *dlen;
00071 
00072     /* Get the object's length and check its type. */
00073     if ((dp = AsnSequenceParse(data, &len, vtype)) == NULL) {
00074         return NULL;
00075     }
00076     /* Get type, value and length of the name. */
00077     if ((dp = AsnOidParse(dp, &len, &vtype, name, nlen)) == NULL) {
00078         return NULL;
00079     }
00080     /* Check the name's type. */
00081     if (vtype != (uint8_t) (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OBJECT_ID)) {
00082         return NULL;
00083     }
00084     /* Return a pointer to the value. */
00085     *value = (uint8_t *) dp;
00086     /* Find out what type of object this is. */
00087     if ((dp = AsnHeaderParse(dp, &len, type)) == NULL) {
00088         return NULL;
00089     }
00090     *vlen = len;
00091     dp += *vlen;
00092     *dlen -= dp - data;
00093 
00094     return dp;
00095 }
00096 
00114 uint8_t *SnmpVarBuild(uint8_t * data, size_t * dlen, CONST OID * name, size_t nlen, uint8_t type, CONST uint8_t * value, size_t vlen)
00115 {
00116     size_t headerLen = 4;
00117     uint8_t *dp;
00118 
00119     /* 
00120      * The final length is not known now, thus the header will have to 
00121      * be build later. 
00122      */
00123     if (*dlen < headerLen) {
00124         SnmpStatsInc(SNMP_STAT_OUTTOOBIGS);
00125         return NULL;
00126     }
00127     *dlen -= headerLen;
00128     dp = data + headerLen;
00129 
00130     /* Build the name. */
00131     if ((dp = AsnOidBuild(dp, dlen, ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OBJECT_ID, name, nlen)) == NULL) {
00132         SnmpStatsInc(SNMP_STAT_OUTTOOBIGS);
00133         return NULL;
00134     }
00135     /* Build the value. */
00136     switch (type) {
00137     case ASN_INTEGER:
00138         dp = AsnIntegerBuild(dp, dlen, type, (long *) value);
00139         break;
00140     case ASN_GAUGE:
00141     case ASN_COUNTER:
00142     case ASN_TIMETICKS:
00143     case ASN_UINTEGER:
00144         dp = AsnUnsignedBuild(dp, dlen, type, (uint32_t *) value);
00145         break;
00146     case ASN_COUNTER64:
00147         dp = AsnUnsigned64Build(dp, dlen, type, (UNSIGNED64 *) value);
00148         break;
00149     case ASN_OCTET_STR:
00150     case ASN_IPADDRESS:
00151     case ASN_OPAQUE:
00152     case ASN_NSAP:
00153         dp = AsnOctetStringBuild(dp, dlen, type, value, vlen);
00154         break;
00155     case ASN_OBJECT_ID:
00156         dp = AsnOidBuild(dp, dlen, type, (OID *) value, vlen / sizeof(OID));
00157         break;
00158     case ASN_NULL:
00159         dp = AsnNullBuild(dp, dlen, type);
00160         break;
00161     case ASN_BIT_STR:
00162         dp = AsnBitStringBuild(dp, dlen, type, value, vlen);
00163         break;
00164     case SNMP_NOSUCHOBJECT:
00165     case SNMP_NOSUCHINSTANCE:
00166     case SNMP_ENDOFMIBVIEW:
00167         dp = AsnNullBuild(dp, dlen, type);
00168         break;
00169     default:
00170         SnmpStatsInc(SNMP_STAT_OUTBADVALUES);
00171         return NULL;
00172     }
00173     /* Now build the header. */
00174     if (dp) {
00175         size_t dummyLen = (dp - data) - headerLen;
00176         AsnSequenceBuild(data, &dummyLen, ASN_SEQUENCE | ASN_CONSTRUCTOR, dummyLen);
00177     } else {
00178         SnmpStatsInc(SNMP_STAT_OUTTOOBIGS);
00179     }
00180     return dp;
00181 }
00182