SNMP Agent http://mbed.org/users/okini3939/notebook/agentbed-library/

Dependents:   WeatherPlatform_20110408 WeatherPlatform WeatherStation

Committer:
okini3939
Date:
Fri Jan 28 09:17:03 2011 +0000
Revision:
2:9e4369522e03
Parent:
1:b2db0ea96703

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
okini3939 0:bb21da73024a 1 /*
okini3939 0:bb21da73024a 2 Agentbed library
okini3939 0:bb21da73024a 3 Modified for mbed, 2010 Suga.
okini3939 0:bb21da73024a 4
okini3939 0:bb21da73024a 5
okini3939 0:bb21da73024a 6 Agentuino.cpp - An Arduino library for a lightweight SNMP Agent.
okini3939 0:bb21da73024a 7 Copyright (C) 2010 Eric C. Gionet <lavco_eg@hotmail.com>
okini3939 0:bb21da73024a 8 All rights reserved.
okini3939 0:bb21da73024a 9
okini3939 0:bb21da73024a 10 This library is free software; you can redistribute it and/or
okini3939 0:bb21da73024a 11 modify it under the terms of the GNU Lesser General Public
okini3939 0:bb21da73024a 12 License as published by the Free Software Foundation; either
okini3939 0:bb21da73024a 13 version 2.1 of the License, or (at your option) any later version.
okini3939 0:bb21da73024a 14
okini3939 0:bb21da73024a 15 This library is distributed in the hope that it will be useful,
okini3939 0:bb21da73024a 16 but WITHOUT ANY WARRANTY; without even the implied warranty of
okini3939 0:bb21da73024a 17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
okini3939 0:bb21da73024a 18 Lesser General Public License for more details.
okini3939 0:bb21da73024a 19
okini3939 0:bb21da73024a 20 You should have received a copy of the GNU Lesser General Public
okini3939 0:bb21da73024a 21 License along with this library; if not, write to the Free Software
okini3939 0:bb21da73024a 22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
okini3939 0:bb21da73024a 23 */
okini3939 0:bb21da73024a 24
okini3939 0:bb21da73024a 25 #ifndef Agentbed_h
okini3939 0:bb21da73024a 26 #define Agentbed_h
okini3939 0:bb21da73024a 27
okini3939 0:bb21da73024a 28 #define SNMP_DEFAULT_PORT 161
okini3939 0:bb21da73024a 29 #define SNMP_MIN_OID_LEN 2
okini3939 0:bb21da73024a 30 #define SNMP_MAX_OID_LEN 64 // 128
okini3939 0:bb21da73024a 31 #define SNMP_MAX_NAME_LEN 20
okini3939 0:bb21da73024a 32 #define SNMP_MAX_VALUE_LEN 64 // 128 ??? should limit this
okini3939 0:bb21da73024a 33 #define SNMP_MAX_PACKET_LEN SNMP_MAX_VALUE_LEN + SNMP_MAX_OID_LEN + 25 //???
okini3939 0:bb21da73024a 34 #define SNMP_FREE(s) do { if (s) { free((void *)s); s=NULL; } } while(0)
okini3939 0:bb21da73024a 35 //Frees a pointer only if it is !NULL and sets its value to NULL.
okini3939 0:bb21da73024a 36
okini3939 0:bb21da73024a 37 #include "mbed.h"
okini3939 0:bb21da73024a 38 #include "EthernetNetIf.h"
okini3939 0:bb21da73024a 39 #include "UDPSocket.h"
okini3939 0:bb21da73024a 40 #include <stdlib.h>
okini3939 0:bb21da73024a 41
okini3939 0:bb21da73024a 42 extern "C" {
okini3939 0:bb21da73024a 43 // callback function
okini3939 0:bb21da73024a 44 typedef void (*onPduReceiveCallback)(void);
okini3939 0:bb21da73024a 45 }
okini3939 0:bb21da73024a 46
okini3939 0:bb21da73024a 47 //typedef long long int64_t;
okini3939 0:bb21da73024a 48 typedef unsigned long long uint64_t;
okini3939 0:bb21da73024a 49 //typedef long int32_t;
okini3939 0:bb21da73024a 50 //typedef unsigned long uint32_t;
okini3939 0:bb21da73024a 51 //typedef unsigned char uint8_t;
okini3939 0:bb21da73024a 52 //typedef short int16_t;
okini3939 0:bb21da73024a 53 //typedef unsigned short uint16_t;
okini3939 0:bb21da73024a 54 typedef unsigned char byte;
okini3939 0:bb21da73024a 55
okini3939 0:bb21da73024a 56 typedef union uint64_u {
okini3939 0:bb21da73024a 57 uint64_t uint64;
okini3939 0:bb21da73024a 58 byte data[8];
okini3939 0:bb21da73024a 59 } uint64_u;
okini3939 0:bb21da73024a 60
okini3939 0:bb21da73024a 61 typedef union int32_u {
okini3939 0:bb21da73024a 62 int32_t int32;
okini3939 0:bb21da73024a 63 byte data[4];
okini3939 0:bb21da73024a 64 } int32_u;
okini3939 0:bb21da73024a 65
okini3939 0:bb21da73024a 66 typedef union uint32_u{
okini3939 0:bb21da73024a 67 uint32_t uint32;
okini3939 0:bb21da73024a 68 byte data[4];
okini3939 0:bb21da73024a 69 } uint32_u;
okini3939 0:bb21da73024a 70
okini3939 0:bb21da73024a 71 typedef union int16_u {
okini3939 0:bb21da73024a 72 int16_t int16;
okini3939 0:bb21da73024a 73 byte data[2];
okini3939 0:bb21da73024a 74 } int16_u;
okini3939 0:bb21da73024a 75
okini3939 0:bb21da73024a 76 //typedef union uint16_u {
okini3939 0:bb21da73024a 77 // uint16_t uint16;
okini3939 0:bb21da73024a 78 // byte data[2];
okini3939 0:bb21da73024a 79 //};
okini3939 0:bb21da73024a 80
okini3939 1:b2db0ea96703 81 typedef union float_u{
okini3939 1:b2db0ea96703 82 float float_t;
okini3939 1:b2db0ea96703 83 byte data[4];
okini3939 1:b2db0ea96703 84 } float_u;
okini3939 1:b2db0ea96703 85
okini3939 0:bb21da73024a 86 enum ASN_BER_BASE_TYPES {
okini3939 0:bb21da73024a 87 // ASN/BER base types
okini3939 0:bb21da73024a 88 ASN_BER_BASE_UNIVERSAL = 0x0,
okini3939 0:bb21da73024a 89 ASN_BER_BASE_APPLICATION = 0x40,
okini3939 0:bb21da73024a 90 ASN_BER_BASE_CONTEXT = 0x80,
okini3939 0:bb21da73024a 91 ASN_BER_BASE_PUBLIC = 0xC0,
okini3939 0:bb21da73024a 92 ASN_BER_BASE_PRIMITIVE = 0x0,
okini3939 0:bb21da73024a 93 ASN_BER_BASE_CONSTRUCTOR = 0x20
okini3939 0:bb21da73024a 94 };
okini3939 0:bb21da73024a 95
okini3939 0:bb21da73024a 96 enum SNMP_PDU_TYPES {
okini3939 0:bb21da73024a 97 // PDU choices
okini3939 0:bb21da73024a 98 SNMP_PDU_GET = ASN_BER_BASE_CONTEXT | ASN_BER_BASE_CONSTRUCTOR | 0,
okini3939 0:bb21da73024a 99 SNMP_PDU_GET_NEXT = ASN_BER_BASE_CONTEXT | ASN_BER_BASE_CONSTRUCTOR | 1,
okini3939 0:bb21da73024a 100 SNMP_PDU_RESPONSE = ASN_BER_BASE_CONTEXT | ASN_BER_BASE_CONSTRUCTOR | 2,
okini3939 0:bb21da73024a 101 SNMP_PDU_SET = ASN_BER_BASE_CONTEXT | ASN_BER_BASE_CONSTRUCTOR | 3,
okini3939 0:bb21da73024a 102 SNMP_PDU_TRAP = ASN_BER_BASE_CONTEXT | ASN_BER_BASE_CONSTRUCTOR | 4
okini3939 0:bb21da73024a 103 };
okini3939 0:bb21da73024a 104
okini3939 0:bb21da73024a 105 enum SNMP_TRAP_TYPES {
okini3939 0:bb21da73024a 106 // Trap generic types:
okini3939 0:bb21da73024a 107 SNMP_TRAP_COLD_START = 0,
okini3939 0:bb21da73024a 108 SNMP_TRAP_WARM_START = 1,
okini3939 0:bb21da73024a 109 SNMP_TRAP_LINK_DOWN = 2,
okini3939 0:bb21da73024a 110 SNMP_TRAP_LINK_UP = 3,
okini3939 0:bb21da73024a 111 SNMP_TRAP_AUTHENTICATION_FAIL = 4,
okini3939 0:bb21da73024a 112 SNMP_TRAP_EGP_NEIGHBORLOSS = 5,
okini3939 0:bb21da73024a 113 SNMP_TRAP_ENTERPRISE_SPECIFIC = 6
okini3939 0:bb21da73024a 114 };
okini3939 0:bb21da73024a 115
okini3939 0:bb21da73024a 116 enum SNMP_ERR_CODES {
okini3939 0:bb21da73024a 117 SNMP_ERR_NO_ERROR = 0,
okini3939 0:bb21da73024a 118 SNMP_ERR_TOO_BIG = 1,
okini3939 0:bb21da73024a 119 SNMP_ERR_NO_SUCH_NAME = 2,
okini3939 0:bb21da73024a 120 SNMP_ERR_BAD_VALUE = 3,
okini3939 0:bb21da73024a 121 SNMP_ERR_READ_ONLY = 4,
okini3939 0:bb21da73024a 122 SNMP_ERR_GEN_ERROR = 5,
okini3939 0:bb21da73024a 123
okini3939 0:bb21da73024a 124 SNMP_ERR_NO_ACCESS = 6,
okini3939 0:bb21da73024a 125 SNMP_ERR_WRONG_TYPE = 7,
okini3939 0:bb21da73024a 126 SNMP_ERR_WRONG_LENGTH = 8,
okini3939 0:bb21da73024a 127 SNMP_ERR_WRONG_ENCODING = 9,
okini3939 0:bb21da73024a 128 SNMP_ERR_WRONG_VALUE = 10,
okini3939 0:bb21da73024a 129 SNMP_ERR_NO_CREATION = 11,
okini3939 0:bb21da73024a 130 SNMP_ERR_INCONSISTANT_VALUE = 12,
okini3939 0:bb21da73024a 131 SNMP_ERR_RESOURCE_UNAVAILABLE = 13,
okini3939 0:bb21da73024a 132 SNMP_ERR_COMMIT_FAILED = 14,
okini3939 0:bb21da73024a 133 SNMP_ERR_UNDO_FAILED = 15,
okini3939 0:bb21da73024a 134 SNMP_ERR_AUTHORIZATION_ERROR = 16,
okini3939 0:bb21da73024a 135 SNMP_ERR_NOT_WRITABLE = 17,
okini3939 0:bb21da73024a 136 SNMP_ERR_INCONSISTEN_NAME = 18
okini3939 0:bb21da73024a 137 };
okini3939 0:bb21da73024a 138
okini3939 0:bb21da73024a 139 enum SNMP_API_STAT_CODES {
okini3939 0:bb21da73024a 140 SNMP_API_STAT_SUCCESS = 0,
okini3939 0:bb21da73024a 141 SNMP_API_STAT_MALLOC_ERR = 1,
okini3939 0:bb21da73024a 142 SNMP_API_STAT_NAME_TOO_BIG = 2,
okini3939 0:bb21da73024a 143 SNMP_API_STAT_OID_TOO_BIG = 3,
okini3939 0:bb21da73024a 144 SNMP_API_STAT_VALUE_TOO_BIG = 4,
okini3939 0:bb21da73024a 145 SNMP_API_STAT_PACKET_INVALID = 5,
okini3939 0:bb21da73024a 146 SNMP_API_STAT_PACKET_TOO_BIG = 6
okini3939 0:bb21da73024a 147 };
okini3939 0:bb21da73024a 148
okini3939 0:bb21da73024a 149 //
okini3939 0:bb21da73024a 150 // http://oreilly.com/catalog/esnmp/chapter/ch02.html Table 2-1: SMIv1 Datatypes
okini3939 0:bb21da73024a 151
okini3939 0:bb21da73024a 152 enum SNMP_SYNTAXES {
okini3939 0:bb21da73024a 153 // SNMP ObjectSyntax values
okini3939 0:bb21da73024a 154 SNMP_SYNTAX_SEQUENCE = ASN_BER_BASE_UNIVERSAL | ASN_BER_BASE_CONSTRUCTOR | 0x10,
okini3939 0:bb21da73024a 155 // These values are used in the "syntax" member of VALUEs
okini3939 0:bb21da73024a 156 SNMP_SYNTAX_BOOL = ASN_BER_BASE_UNIVERSAL | ASN_BER_BASE_PRIMITIVE | 1,
okini3939 0:bb21da73024a 157 SNMP_SYNTAX_INT = ASN_BER_BASE_UNIVERSAL | ASN_BER_BASE_PRIMITIVE | 2,
okini3939 0:bb21da73024a 158 SNMP_SYNTAX_BITS = ASN_BER_BASE_UNIVERSAL | ASN_BER_BASE_PRIMITIVE | 3,
okini3939 0:bb21da73024a 159 SNMP_SYNTAX_OCTETS = ASN_BER_BASE_UNIVERSAL | ASN_BER_BASE_PRIMITIVE | 4,
okini3939 0:bb21da73024a 160 SNMP_SYNTAX_NULL = ASN_BER_BASE_UNIVERSAL | ASN_BER_BASE_PRIMITIVE | 5,
okini3939 0:bb21da73024a 161 SNMP_SYNTAX_OID = ASN_BER_BASE_UNIVERSAL | ASN_BER_BASE_PRIMITIVE | 6,
okini3939 0:bb21da73024a 162 SNMP_SYNTAX_INT32 = SNMP_SYNTAX_INT,
okini3939 0:bb21da73024a 163 SNMP_SYNTAX_IP_ADDRESS = ASN_BER_BASE_APPLICATION | ASN_BER_BASE_PRIMITIVE | 0,
okini3939 0:bb21da73024a 164 SNMP_SYNTAX_COUNTER = ASN_BER_BASE_APPLICATION | ASN_BER_BASE_PRIMITIVE | 1,
okini3939 0:bb21da73024a 165 SNMP_SYNTAX_GAUGE = ASN_BER_BASE_APPLICATION | ASN_BER_BASE_PRIMITIVE | 2,
okini3939 0:bb21da73024a 166 SNMP_SYNTAX_TIME_TICKS = ASN_BER_BASE_APPLICATION | ASN_BER_BASE_PRIMITIVE | 3,
okini3939 0:bb21da73024a 167 SNMP_SYNTAX_OPAQUE = ASN_BER_BASE_APPLICATION | ASN_BER_BASE_PRIMITIVE | 4,
okini3939 0:bb21da73024a 168 SNMP_SYNTAX_NSAPADDR = ASN_BER_BASE_APPLICATION | ASN_BER_BASE_PRIMITIVE | 5,
okini3939 0:bb21da73024a 169 SNMP_SYNTAX_COUNTER64 = ASN_BER_BASE_APPLICATION | ASN_BER_BASE_PRIMITIVE | 6,
okini3939 0:bb21da73024a 170 SNMP_SYNTAX_UINT32 = ASN_BER_BASE_APPLICATION | ASN_BER_BASE_PRIMITIVE | 7,
okini3939 1:b2db0ea96703 171 SNMP_SYNTAX_OPAQUE_FLOAT = 0x78,
okini3939 0:bb21da73024a 172 };
okini3939 0:bb21da73024a 173
okini3939 0:bb21da73024a 174 typedef struct SNMP_OID {
okini3939 0:bb21da73024a 175 byte data[SNMP_MAX_OID_LEN]; // ushort array insted??
okini3939 0:bb21da73024a 176 size_t size;
okini3939 0:bb21da73024a 177 //
okini3939 0:bb21da73024a 178 void fromString(const char *buffer) {
okini3939 0:bb21da73024a 179 }
okini3939 0:bb21da73024a 180 //
okini3939 0:bb21da73024a 181 void toString(char *buffer) {
okini3939 0:bb21da73024a 182 buffer[0] = '1';
okini3939 0:bb21da73024a 183 buffer[1] = '.';
okini3939 0:bb21da73024a 184 buffer[2] = '3';
okini3939 0:bb21da73024a 185 buffer[3] = '\0';
okini3939 0:bb21da73024a 186 //
okini3939 0:bb21da73024a 187 // tmp buffer - short (Int16)
okini3939 0:bb21da73024a 188 //char *buff = (char *)malloc(sizeof(char)*16); // I ya ya keeps hanging the MCU
okini3939 0:bb21da73024a 189 char buff[16];
okini3939 0:bb21da73024a 190 byte hsize = size - 1;
okini3939 0:bb21da73024a 191 byte hpos = 1;
okini3939 0:bb21da73024a 192 uint16_t subid;
okini3939 0:bb21da73024a 193 //
okini3939 0:bb21da73024a 194 while ( hsize > 0 ) {
okini3939 0:bb21da73024a 195 subid = 0;
okini3939 0:bb21da73024a 196 uint16_t b = 0;
okini3939 0:bb21da73024a 197 do {
okini3939 0:bb21da73024a 198 uint16_t next = data[hpos++];
okini3939 0:bb21da73024a 199 b = next & 0xFF;
okini3939 0:bb21da73024a 200 subid = (subid << 7) + (b & ~0x80);
okini3939 0:bb21da73024a 201 hsize--;
okini3939 0:bb21da73024a 202 } while ( (hsize > 0) && ((b & 0x80) != 0) );
okini3939 0:bb21da73024a 203 //utoa(subid, buff, 10);
okini3939 0:bb21da73024a 204 sprintf(buff, "%d", subid);
okini3939 0:bb21da73024a 205 strcat(buffer, ".");
okini3939 0:bb21da73024a 206 strcat(buffer, buff);
okini3939 0:bb21da73024a 207 }
okini3939 0:bb21da73024a 208 //
okini3939 0:bb21da73024a 209 // free buff
okini3939 0:bb21da73024a 210 //SNMP_FREE(buff);
okini3939 0:bb21da73024a 211 };
okini3939 0:bb21da73024a 212 } SNMP_OID;
okini3939 0:bb21da73024a 213
okini3939 0:bb21da73024a 214 // union for values?
okini3939 0:bb21da73024a 215 //
okini3939 0:bb21da73024a 216 typedef struct SNMP_VALUE {
okini3939 0:bb21da73024a 217 byte data[SNMP_MAX_VALUE_LEN];
okini3939 0:bb21da73024a 218 size_t size;
okini3939 0:bb21da73024a 219 SNMP_SYNTAXES syntax;
okini3939 0:bb21da73024a 220 //
okini3939 0:bb21da73024a 221 byte i; // for encoding/decoding functions
okini3939 0:bb21da73024a 222 //
okini3939 0:bb21da73024a 223 // clear's buffer and sets size to 0
okini3939 0:bb21da73024a 224 void clear(void) {
okini3939 0:bb21da73024a 225 memset(data, 0, SNMP_MAX_VALUE_LEN);
okini3939 0:bb21da73024a 226 size = 0;
okini3939 0:bb21da73024a 227 }
okini3939 0:bb21da73024a 228 //
okini3939 0:bb21da73024a 229 //
okini3939 0:bb21da73024a 230 // ASN.1 decoding functions
okini3939 0:bb21da73024a 231 //
okini3939 0:bb21da73024a 232 // decode's an octet string, object-identifier, opaque syntax to string
okini3939 0:bb21da73024a 233 SNMP_ERR_CODES decode(char *value, size_t max_size) {
okini3939 0:bb21da73024a 234 if ( syntax == SNMP_SYNTAX_OCTETS || syntax == SNMP_SYNTAX_OID
okini3939 0:bb21da73024a 235 || syntax == SNMP_SYNTAX_OPAQUE ) {
okini3939 0:bb21da73024a 236 if ( strlen(value) - 1 < max_size ) {
okini3939 0:bb21da73024a 237 if ( syntax == SNMP_SYNTAX_OID ) {
okini3939 0:bb21da73024a 238 value[0] = '1';
okini3939 0:bb21da73024a 239 value[1] = '.';
okini3939 0:bb21da73024a 240 value[2] = '3';
okini3939 0:bb21da73024a 241 value[3] = '\0';
okini3939 0:bb21da73024a 242 //
okini3939 0:bb21da73024a 243 // tmp buffer - ushort (UInt16)
okini3939 0:bb21da73024a 244 //char *buff = (char *)malloc(sizeof(char)*16); // I ya ya..keep hanging the MCU
okini3939 0:bb21da73024a 245 char buff[16];
okini3939 0:bb21da73024a 246 byte hsize = size - 1;
okini3939 0:bb21da73024a 247 byte hpos = 1;
okini3939 0:bb21da73024a 248 uint16_t subid;
okini3939 0:bb21da73024a 249 //
okini3939 0:bb21da73024a 250 while ( hsize > 0 ) {
okini3939 0:bb21da73024a 251 subid = 0;
okini3939 0:bb21da73024a 252 uint16_t b = 0;
okini3939 0:bb21da73024a 253 do {
okini3939 0:bb21da73024a 254 uint16_t next = data[hpos++];
okini3939 0:bb21da73024a 255 b = next & 0xFF;
okini3939 0:bb21da73024a 256 subid = (subid << 7) + (b & ~0x80);
okini3939 0:bb21da73024a 257 hsize--;
okini3939 0:bb21da73024a 258 } while ( (hsize > 0) && ((b & 0x80) != 0) );
okini3939 0:bb21da73024a 259 //utoa(subid, buff, 10);
okini3939 0:bb21da73024a 260 sprintf(buff, "%d", subid);
okini3939 0:bb21da73024a 261 strcat(value, ".");
okini3939 0:bb21da73024a 262 strcat(value, buff);
okini3939 0:bb21da73024a 263 }
okini3939 0:bb21da73024a 264 //
okini3939 0:bb21da73024a 265 // free buff
okini3939 0:bb21da73024a 266 //SNMP_FREE(buff);
okini3939 0:bb21da73024a 267 } else {
okini3939 0:bb21da73024a 268 for ( i = 0; i < size; i++ ) {
okini3939 0:bb21da73024a 269 value[i] = (char)data[i];
okini3939 0:bb21da73024a 270 }
okini3939 0:bb21da73024a 271 value[size] = '\0';
okini3939 0:bb21da73024a 272 }
okini3939 0:bb21da73024a 273 return SNMP_ERR_NO_ERROR;
okini3939 0:bb21da73024a 274 } else {
okini3939 0:bb21da73024a 275 clear();
okini3939 0:bb21da73024a 276 return SNMP_ERR_TOO_BIG;
okini3939 0:bb21da73024a 277 }
okini3939 0:bb21da73024a 278 } else {
okini3939 0:bb21da73024a 279 clear();
okini3939 0:bb21da73024a 280 return SNMP_ERR_WRONG_TYPE;
okini3939 0:bb21da73024a 281 }
okini3939 0:bb21da73024a 282 }
okini3939 0:bb21da73024a 283 //
okini3939 0:bb21da73024a 284 // decode's an int syntax to int16 ?? is this applicable
okini3939 0:bb21da73024a 285 SNMP_ERR_CODES decode(int16_t *value) {
okini3939 0:bb21da73024a 286 if ( syntax == SNMP_SYNTAX_INT ) {
okini3939 0:bb21da73024a 287 int16_u tmp;
okini3939 0:bb21da73024a 288 tmp.data[1] = data[0];
okini3939 0:bb21da73024a 289 tmp.data[0] = data[1];
okini3939 0:bb21da73024a 290 *value = tmp.int16;
okini3939 0:bb21da73024a 291 return SNMP_ERR_NO_ERROR;
okini3939 0:bb21da73024a 292 } else {
okini3939 0:bb21da73024a 293 clear();
okini3939 0:bb21da73024a 294 return SNMP_ERR_WRONG_TYPE;
okini3939 0:bb21da73024a 295 }
okini3939 0:bb21da73024a 296 }
okini3939 0:bb21da73024a 297 //
okini3939 0:bb21da73024a 298 // decode's an int32 syntax to int32
okini3939 0:bb21da73024a 299 SNMP_ERR_CODES decode(int32_t *value) {
okini3939 0:bb21da73024a 300 if ( syntax == SNMP_SYNTAX_INT32 ) {
okini3939 0:bb21da73024a 301 int32_u tmp;
okini3939 0:bb21da73024a 302 tmp.data[3] = data[0];
okini3939 0:bb21da73024a 303 tmp.data[2] = data[1];
okini3939 0:bb21da73024a 304 tmp.data[1] = data[2];
okini3939 0:bb21da73024a 305 tmp.data[0] = data[3];
okini3939 0:bb21da73024a 306 *value = tmp.int32;
okini3939 0:bb21da73024a 307 return SNMP_ERR_NO_ERROR;
okini3939 0:bb21da73024a 308 } else {
okini3939 0:bb21da73024a 309 clear();
okini3939 0:bb21da73024a 310 return SNMP_ERR_WRONG_TYPE;
okini3939 0:bb21da73024a 311 }
okini3939 0:bb21da73024a 312 }
okini3939 0:bb21da73024a 313 //
okini3939 0:bb21da73024a 314 // decode's an uint32, counter, time-ticks, gauge syntax to uint32
okini3939 0:bb21da73024a 315 SNMP_ERR_CODES decode(uint32_t *value) {
okini3939 0:bb21da73024a 316 if ( syntax == SNMP_SYNTAX_COUNTER || syntax == SNMP_SYNTAX_TIME_TICKS
okini3939 0:bb21da73024a 317 || syntax == SNMP_SYNTAX_GAUGE || syntax == SNMP_SYNTAX_UINT32 ) {
okini3939 0:bb21da73024a 318 uint32_u tmp;
okini3939 0:bb21da73024a 319 tmp.data[3] = data[0];
okini3939 0:bb21da73024a 320 tmp.data[2] = data[1];
okini3939 0:bb21da73024a 321 tmp.data[1] = data[2];
okini3939 0:bb21da73024a 322 tmp.data[0] = data[3];
okini3939 0:bb21da73024a 323 *value = tmp.uint32;
okini3939 0:bb21da73024a 324 return SNMP_ERR_NO_ERROR;
okini3939 0:bb21da73024a 325 } else {
okini3939 0:bb21da73024a 326 clear();
okini3939 0:bb21da73024a 327 return SNMP_ERR_WRONG_TYPE;
okini3939 0:bb21da73024a 328 }
okini3939 0:bb21da73024a 329 }
okini3939 0:bb21da73024a 330 //
okini3939 0:bb21da73024a 331 // decode's an ip-address, NSAP-address syntax to an ip-address byte array
okini3939 0:bb21da73024a 332 SNMP_ERR_CODES decode(byte *value) {
okini3939 0:bb21da73024a 333 memset(data, 0, SNMP_MAX_VALUE_LEN);
okini3939 0:bb21da73024a 334 if ( syntax == SNMP_SYNTAX_IP_ADDRESS || syntax == SNMP_SYNTAX_NSAPADDR ) {
okini3939 0:bb21da73024a 335 if ( sizeof(value) > 4 ) {
okini3939 0:bb21da73024a 336 clear();
okini3939 0:bb21da73024a 337 return SNMP_ERR_TOO_BIG;
okini3939 0:bb21da73024a 338 } else {
okini3939 0:bb21da73024a 339 size = 4;
okini3939 0:bb21da73024a 340 data[0] = value[3];
okini3939 0:bb21da73024a 341 data[1] = value[2];
okini3939 0:bb21da73024a 342 data[2] = value[1];
okini3939 0:bb21da73024a 343 data[3] = value[0];
okini3939 0:bb21da73024a 344 return SNMP_ERR_NO_ERROR;
okini3939 0:bb21da73024a 345 }
okini3939 0:bb21da73024a 346 } else {
okini3939 0:bb21da73024a 347 clear();
okini3939 0:bb21da73024a 348 return SNMP_ERR_WRONG_TYPE;
okini3939 0:bb21da73024a 349 }
okini3939 0:bb21da73024a 350 }
okini3939 0:bb21da73024a 351 //
okini3939 0:bb21da73024a 352 // decode's a boolean syntax to boolean
okini3939 0:bb21da73024a 353 SNMP_ERR_CODES decode(bool *value) {
okini3939 0:bb21da73024a 354 if ( syntax == SNMP_SYNTAX_BOOL ) {
okini3939 0:bb21da73024a 355 *value = (data[0] != 0);
okini3939 0:bb21da73024a 356 return SNMP_ERR_NO_ERROR;
okini3939 0:bb21da73024a 357 } else {
okini3939 0:bb21da73024a 358 clear();
okini3939 0:bb21da73024a 359 return SNMP_ERR_WRONG_TYPE;
okini3939 0:bb21da73024a 360 }
okini3939 0:bb21da73024a 361 }
okini3939 0:bb21da73024a 362 //
okini3939 0:bb21da73024a 363 //
okini3939 0:bb21da73024a 364 // ASN.1 encoding functions
okini3939 0:bb21da73024a 365 //
okini3939 0:bb21da73024a 366 // encode's a octet string to a string, opaque syntax
okini3939 0:bb21da73024a 367 // encode object-identifier here??
okini3939 0:bb21da73024a 368 SNMP_ERR_CODES encode(SNMP_SYNTAXES syn, const char *value) {
okini3939 0:bb21da73024a 369 memset(data, 0, SNMP_MAX_VALUE_LEN);
okini3939 0:bb21da73024a 370 if ( syn == SNMP_SYNTAX_OCTETS || syn == SNMP_SYNTAX_OPAQUE ) {
okini3939 0:bb21da73024a 371 if ( strlen(value) - 1 < SNMP_MAX_VALUE_LEN ) {
okini3939 0:bb21da73024a 372 syntax = syn;
okini3939 0:bb21da73024a 373 size = strlen(value);
okini3939 0:bb21da73024a 374 for ( i = 0; i < size; i++ ) {
okini3939 0:bb21da73024a 375 data[i] = (byte)value[i];
okini3939 0:bb21da73024a 376 }
okini3939 0:bb21da73024a 377 return SNMP_ERR_NO_ERROR;
okini3939 0:bb21da73024a 378 } else {
okini3939 0:bb21da73024a 379 clear();
okini3939 0:bb21da73024a 380 return SNMP_ERR_TOO_BIG;
okini3939 0:bb21da73024a 381 }
okini3939 0:bb21da73024a 382 } else {
okini3939 0:bb21da73024a 383 clear();
okini3939 0:bb21da73024a 384 return SNMP_ERR_WRONG_TYPE;
okini3939 0:bb21da73024a 385 }
okini3939 0:bb21da73024a 386 }
okini3939 0:bb21da73024a 387 //
okini3939 0:bb21da73024a 388 // encode's an int16 to int, opaque syntax
okini3939 0:bb21da73024a 389 SNMP_ERR_CODES encode(SNMP_SYNTAXES syn, const int16_t value) {
okini3939 0:bb21da73024a 390 memset(data, 0, SNMP_MAX_VALUE_LEN);
okini3939 0:bb21da73024a 391 if ( syn == SNMP_SYNTAX_INT || syn == SNMP_SYNTAX_OPAQUE ) {
okini3939 0:bb21da73024a 392 int16_u tmp;
okini3939 0:bb21da73024a 393 size = 2;
okini3939 0:bb21da73024a 394 syntax = syn;
okini3939 0:bb21da73024a 395 tmp.int16 = value;
okini3939 0:bb21da73024a 396 data[0] = tmp.data[1];
okini3939 0:bb21da73024a 397 data[1] = tmp.data[0];
okini3939 0:bb21da73024a 398 return SNMP_ERR_NO_ERROR;
okini3939 0:bb21da73024a 399 } else {
okini3939 0:bb21da73024a 400 clear();
okini3939 0:bb21da73024a 401 return SNMP_ERR_WRONG_TYPE;
okini3939 0:bb21da73024a 402 }
okini3939 0:bb21da73024a 403 }
okini3939 0:bb21da73024a 404 //
okini3939 0:bb21da73024a 405 // encode's an int32 to int32, opaque syntax
okini3939 0:bb21da73024a 406 SNMP_ERR_CODES encode(SNMP_SYNTAXES syn, const int32_t value) {
okini3939 0:bb21da73024a 407 memset(data, 0, SNMP_MAX_VALUE_LEN);
okini3939 0:bb21da73024a 408 if ( syn == SNMP_SYNTAX_INT32 || syn == SNMP_SYNTAX_OPAQUE ) {
okini3939 0:bb21da73024a 409 int32_u tmp;
okini3939 0:bb21da73024a 410 size = 4;
okini3939 0:bb21da73024a 411 syntax = syn;
okini3939 0:bb21da73024a 412 tmp.int32 = value;
okini3939 0:bb21da73024a 413 data[0] = tmp.data[3];
okini3939 0:bb21da73024a 414 data[1] = tmp.data[2];
okini3939 0:bb21da73024a 415 data[2] = tmp.data[1];
okini3939 0:bb21da73024a 416 data[3] = tmp.data[0];
okini3939 0:bb21da73024a 417 return SNMP_ERR_NO_ERROR;
okini3939 0:bb21da73024a 418 } else {
okini3939 0:bb21da73024a 419 clear();
okini3939 0:bb21da73024a 420 return SNMP_ERR_WRONG_TYPE;
okini3939 0:bb21da73024a 421 }
okini3939 0:bb21da73024a 422 }
okini3939 0:bb21da73024a 423 //
okini3939 0:bb21da73024a 424 // encode's an uint32 to uint32, counter, time-ticks, gauge, opaque syntax
okini3939 0:bb21da73024a 425 SNMP_ERR_CODES encode(SNMP_SYNTAXES syn, const uint32_t value) {
okini3939 0:bb21da73024a 426 memset(data, 0, SNMP_MAX_VALUE_LEN);
okini3939 0:bb21da73024a 427 if ( syn == SNMP_SYNTAX_COUNTER || syn == SNMP_SYNTAX_TIME_TICKS
okini3939 0:bb21da73024a 428 || syn == SNMP_SYNTAX_GAUGE || syn == SNMP_SYNTAX_UINT32
okini3939 0:bb21da73024a 429 || syn == SNMP_SYNTAX_OPAQUE ) {
okini3939 0:bb21da73024a 430 uint32_u tmp;
okini3939 0:bb21da73024a 431 size = 4;
okini3939 0:bb21da73024a 432 syntax = syn;
okini3939 0:bb21da73024a 433 tmp.uint32 = value;
okini3939 0:bb21da73024a 434 data[0] = tmp.data[3];
okini3939 0:bb21da73024a 435 data[1] = tmp.data[2];
okini3939 0:bb21da73024a 436 data[2] = tmp.data[1];
okini3939 0:bb21da73024a 437 data[3] = tmp.data[0];
okini3939 0:bb21da73024a 438 return SNMP_ERR_NO_ERROR;
okini3939 0:bb21da73024a 439 } else {
okini3939 0:bb21da73024a 440 clear();
okini3939 0:bb21da73024a 441 return SNMP_ERR_WRONG_TYPE;
okini3939 0:bb21da73024a 442 }
okini3939 0:bb21da73024a 443 }
okini3939 0:bb21da73024a 444 //
okini3939 0:bb21da73024a 445 // encode's an ip-address byte array to ip-address, NSAP-address, opaque syntax
okini3939 0:bb21da73024a 446 SNMP_ERR_CODES encode(SNMP_SYNTAXES syn, const byte *value) {
okini3939 0:bb21da73024a 447 memset(data, 0, SNMP_MAX_VALUE_LEN);
okini3939 0:bb21da73024a 448 if ( syn == SNMP_SYNTAX_IP_ADDRESS || syn == SNMP_SYNTAX_NSAPADDR
okini3939 0:bb21da73024a 449 || syn == SNMP_SYNTAX_OPAQUE ) {
okini3939 0:bb21da73024a 450 if ( sizeof(value) > 4 ) {
okini3939 0:bb21da73024a 451 clear();
okini3939 0:bb21da73024a 452 return SNMP_ERR_TOO_BIG;
okini3939 0:bb21da73024a 453 } else {
okini3939 0:bb21da73024a 454 size = 4;
okini3939 0:bb21da73024a 455 syntax = syn;
okini3939 0:bb21da73024a 456 data[0] = value[3];
okini3939 0:bb21da73024a 457 data[1] = value[2];
okini3939 0:bb21da73024a 458 data[2] = value[1];
okini3939 0:bb21da73024a 459 data[3] = value[0];
okini3939 0:bb21da73024a 460 return SNMP_ERR_NO_ERROR;
okini3939 0:bb21da73024a 461 }
okini3939 0:bb21da73024a 462 } else {
okini3939 0:bb21da73024a 463 clear();
okini3939 0:bb21da73024a 464 return SNMP_ERR_WRONG_TYPE;
okini3939 0:bb21da73024a 465 }
okini3939 0:bb21da73024a 466 }
okini3939 0:bb21da73024a 467 //
okini3939 0:bb21da73024a 468 // encode's a boolean to boolean, opaque syntax
okini3939 0:bb21da73024a 469 SNMP_ERR_CODES encode(SNMP_SYNTAXES syn, const bool value) {
okini3939 0:bb21da73024a 470 memset(data, 0, SNMP_MAX_VALUE_LEN);
okini3939 0:bb21da73024a 471 if ( syn == SNMP_SYNTAX_BOOL || syn == SNMP_SYNTAX_OPAQUE ) {
okini3939 0:bb21da73024a 472 size = 1;
okini3939 0:bb21da73024a 473 syntax = syn;
okini3939 0:bb21da73024a 474 data[0] = value ? 0xff : 0;
okini3939 0:bb21da73024a 475 return SNMP_ERR_NO_ERROR;
okini3939 0:bb21da73024a 476 } else {
okini3939 0:bb21da73024a 477 clear();
okini3939 0:bb21da73024a 478 return SNMP_ERR_WRONG_TYPE;
okini3939 0:bb21da73024a 479 }
okini3939 0:bb21da73024a 480 }
okini3939 0:bb21da73024a 481 //
okini3939 0:bb21da73024a 482 // encode's an uint64 to counter64, opaque syntax
okini3939 0:bb21da73024a 483 SNMP_ERR_CODES encode(SNMP_SYNTAXES syn, const uint64_t value) {
okini3939 0:bb21da73024a 484 memset(data, 0, SNMP_MAX_VALUE_LEN);
okini3939 0:bb21da73024a 485 if ( syn == SNMP_SYNTAX_COUNTER64 || syn == SNMP_SYNTAX_OPAQUE ) {
okini3939 0:bb21da73024a 486 uint64_u tmp;
okini3939 0:bb21da73024a 487 size = 8;
okini3939 0:bb21da73024a 488 syntax = syn;
okini3939 0:bb21da73024a 489 tmp.uint64 = value;
okini3939 0:bb21da73024a 490 data[0] = tmp.data[7];
okini3939 0:bb21da73024a 491 data[1] = tmp.data[6];
okini3939 0:bb21da73024a 492 data[2] = tmp.data[5];
okini3939 0:bb21da73024a 493 data[3] = tmp.data[4];
okini3939 0:bb21da73024a 494 data[4] = tmp.data[3];
okini3939 0:bb21da73024a 495 data[5] = tmp.data[2];
okini3939 0:bb21da73024a 496 data[6] = tmp.data[1];
okini3939 0:bb21da73024a 497 data[7] = tmp.data[0];
okini3939 0:bb21da73024a 498 return SNMP_ERR_NO_ERROR;
okini3939 0:bb21da73024a 499 } else {
okini3939 0:bb21da73024a 500 clear();
okini3939 0:bb21da73024a 501 return SNMP_ERR_WRONG_TYPE;
okini3939 0:bb21da73024a 502 }
okini3939 0:bb21da73024a 503 }
okini3939 0:bb21da73024a 504 //
okini3939 1:b2db0ea96703 505 // encode's an int32 to int32, opaque syntax
okini3939 1:b2db0ea96703 506 SNMP_ERR_CODES encode(SNMP_SYNTAXES syn, const float value) {
okini3939 1:b2db0ea96703 507 memset(data, 0, SNMP_MAX_VALUE_LEN);
okini3939 1:b2db0ea96703 508 if ( syn == SNMP_SYNTAX_OPAQUE_FLOAT ) {
okini3939 1:b2db0ea96703 509 float_u tmp;
okini3939 1:b2db0ea96703 510 size = 4;
okini3939 1:b2db0ea96703 511 syntax = syn;
okini3939 1:b2db0ea96703 512 tmp.float_t = value;
okini3939 1:b2db0ea96703 513 data[0] = tmp.data[3];
okini3939 1:b2db0ea96703 514 data[1] = tmp.data[2];
okini3939 1:b2db0ea96703 515 data[2] = tmp.data[1];
okini3939 1:b2db0ea96703 516 data[3] = tmp.data[0];
okini3939 1:b2db0ea96703 517 return SNMP_ERR_NO_ERROR;
okini3939 1:b2db0ea96703 518 } else {
okini3939 1:b2db0ea96703 519 clear();
okini3939 1:b2db0ea96703 520 return SNMP_ERR_WRONG_TYPE;
okini3939 1:b2db0ea96703 521 }
okini3939 1:b2db0ea96703 522 }
okini3939 1:b2db0ea96703 523 //
okini3939 0:bb21da73024a 524 // encode's a null to null, opaque syntax
okini3939 0:bb21da73024a 525 SNMP_ERR_CODES encode(SNMP_SYNTAXES syn) {
okini3939 0:bb21da73024a 526 clear();
okini3939 0:bb21da73024a 527 if ( syn == SNMP_SYNTAX_NULL || syn == SNMP_SYNTAX_OPAQUE ) {
okini3939 0:bb21da73024a 528 size = 0;
okini3939 0:bb21da73024a 529 syntax = syn;
okini3939 0:bb21da73024a 530 return SNMP_ERR_NO_ERROR;
okini3939 0:bb21da73024a 531 } else {
okini3939 0:bb21da73024a 532 return SNMP_ERR_WRONG_TYPE;
okini3939 0:bb21da73024a 533 }
okini3939 0:bb21da73024a 534 }
okini3939 0:bb21da73024a 535 } SNMP_VALUE;
okini3939 0:bb21da73024a 536
okini3939 0:bb21da73024a 537 typedef struct SNMP_PDU {
okini3939 0:bb21da73024a 538 SNMP_PDU_TYPES type;
okini3939 0:bb21da73024a 539 int32_t version;
okini3939 0:bb21da73024a 540 int32_t requestId;
okini3939 0:bb21da73024a 541 SNMP_ERR_CODES error;
okini3939 0:bb21da73024a 542 int32_t errorIndex;
okini3939 0:bb21da73024a 543 SNMP_OID OID;
okini3939 0:bb21da73024a 544 SNMP_VALUE VALUE;
okini3939 0:bb21da73024a 545 } SNMP_PDU;
okini3939 0:bb21da73024a 546
okini3939 0:bb21da73024a 547 class AgentbedClass {
okini3939 0:bb21da73024a 548 public:
okini3939 0:bb21da73024a 549 // Agent functions
okini3939 0:bb21da73024a 550 SNMP_API_STAT_CODES begin(EthernetNetIf *eth);
okini3939 0:bb21da73024a 551 SNMP_API_STAT_CODES begin(char *getCommName, char *setCommName, uint16_t port, EthernetNetIf *eth);
okini3939 0:bb21da73024a 552 void listen(UDPSocketEvent);
okini3939 0:bb21da73024a 553 SNMP_API_STAT_CODES requestPdu(SNMP_PDU *pdu);
okini3939 0:bb21da73024a 554 SNMP_API_STAT_CODES responsePdu(SNMP_PDU *pdu);
okini3939 0:bb21da73024a 555 void onPduReceive(onPduReceiveCallback pduReceived);
okini3939 0:bb21da73024a 556 void freePdu(SNMP_PDU *pdu);
okini3939 0:bb21da73024a 557
okini3939 0:bb21da73024a 558 // Helper functions
okini3939 0:bb21da73024a 559
okini3939 0:bb21da73024a 560 private:
okini3939 0:bb21da73024a 561 byte _packet[SNMP_MAX_PACKET_LEN];
okini3939 0:bb21da73024a 562 uint16_t _packetSize;
okini3939 0:bb21da73024a 563 uint16_t _packetPos;
okini3939 0:bb21da73024a 564 SNMP_PDU_TYPES _dstType;
okini3939 0:bb21da73024a 565 char *_getCommName;
okini3939 0:bb21da73024a 566 size_t _getSize;
okini3939 0:bb21da73024a 567 char *_setCommName;
okini3939 0:bb21da73024a 568 size_t _setSize;
okini3939 0:bb21da73024a 569 onPduReceiveCallback _callback;
okini3939 0:bb21da73024a 570 UDPSocket *udpsock;
okini3939 0:bb21da73024a 571 Host _dst;
okini3939 0:bb21da73024a 572 };
okini3939 0:bb21da73024a 573
okini3939 0:bb21da73024a 574 //extern AgentbedClass Agentbed;
okini3939 0:bb21da73024a 575
okini3939 0:bb21da73024a 576 #endif