fork allowing use of the latest official mbed networking library
Fork of Agentbed by
Agentbed.cpp
00001 /* 00002 Agentbed library 00003 Modified for mbed, 2010 Suga. 00004 00005 00006 Agentuino.cpp - An Arduino library for a lightweight SNMP Agent. 00007 Copyright (C) 2010 Eric C. Gionet <lavco_eg@hotmail.com> 00008 All rights reserved. 00009 00010 This library is free software; you can redistribute it and/or 00011 modify it under the terms of the GNU Lesser General Public 00012 License as published by the Free Software Foundation; either 00013 version 2.1 of the License, or (at your option) any later version. 00014 00015 This library is distributed in the hope that it will be useful, 00016 but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00018 Lesser General Public License for more details. 00019 00020 You should have received a copy of the GNU Lesser General Public 00021 License along with this library; if not, write to the Free Software 00022 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00023 */ 00024 00025 // 00026 // sketch_aug23a 00027 // 00028 00029 #include "Agentbed.h" 00030 00031 SNMP_API_STAT_CODES SNMP::init() 00032 { 00033 // set community names 00034 _getCommName = "public"; 00035 _setCommName = "private"; 00036 // 00037 // set community name set/get sizes 00038 _setSize = strlen(_setCommName); 00039 _getSize = strlen(_getCommName); 00040 // 00041 return SNMP_API_STAT_SUCCESS; 00042 } 00043 00044 SNMP_API_STAT_CODES SNMP::init(char *getCommName, char *setCommName) 00045 { 00046 // set community name set/get sizes 00047 _setSize = strlen(setCommName); 00048 _getSize = strlen(getCommName); 00049 // 00050 // validate get/set community name sizes 00051 if ( _setSize > SNMP_MAX_NAME_LEN + 1 || _getSize > SNMP_MAX_NAME_LEN + 1 ) { 00052 return SNMP_API_STAT_NAME_TOO_BIG; 00053 } 00054 // 00055 // set community names 00056 _getCommName = getCommName; 00057 _setCommName = setCommName; 00058 // 00059 00060 return SNMP_API_STAT_SUCCESS; 00061 } 00062 00063 SNMP_API_STAT_CODES SNMP::toPdu(SNMP_PDU *pdu,char *_packet,uint16_t _packetSize) 00064 { 00065 char *community; 00066 // sequence length 00067 byte __attribute__((__unused__)) seqLen; 00068 // version 00069 byte verLen, verEnd; 00070 // community string 00071 byte comLen, comEnd; 00072 // pdu 00073 byte __attribute__((__unused__)) pduTyp, pduLen; 00074 byte ridLen, ridEnd; 00075 byte errLen, errEnd; 00076 byte eriLen, eriEnd; 00077 byte __attribute__((__unused__)) vblTyp, vblLen; 00078 byte __attribute__((__unused__)) vbiTyp, vbiLen; 00079 byte obiLen, obiEnd; 00080 byte __attribute__((__unused__)) valTyp, valLen, valEnd; 00081 byte i; 00082 // 00083 // set packet packet size (skip UDP header) 00084 // _packetSize = Udp.available()-8; 00085 // 00086 // memset(_packet, 0, SNMP_MAX_PACKET_LEN); 00087 // 00088 // get UDP packet 00089 /// _packetSize = udpsock->recvfrom((char*)_packet, SNMP_MAX_PACKET_LEN, &_dst); 00090 // 00091 // validate packet 00092 if ( _packetSize != 0 && _packetSize > SNMP_MAX_PACKET_LEN ) { 00093 // 00094 //SNMP_FREE(_packet); 00095 00096 return SNMP_API_STAT_PACKET_TOO_BIG; 00097 } 00098 // 00099 // allocate byte array based on packet size 00100 //if ( (_packet = (byte *)malloc(sizeof(byte)*_packetSize)) == NULL ) { 00101 // 00102 //SNMP_FREE(_packet); 00103 00104 // return SNMP_API_STAT_MALLOC_ERR; 00105 //} 00106 // 00107 // packet check 1 00108 if ( _packet[0] != 0x30 ) { 00109 // 00110 //SNMP_FREE(_packet); 00111 00112 return SNMP_API_STAT_PACKET_INVALID; 00113 } 00114 // 00115 // sequence length 00116 seqLen = _packet[1]; 00117 // version 00118 verLen = _packet[3]; 00119 verEnd = 3 + verLen; 00120 // community string 00121 comLen = _packet[verEnd + 2]; 00122 comEnd = verEnd + 2 + comLen; 00123 // pdu 00124 pduTyp = _packet[comEnd + 1]; 00125 pduLen = _packet[comEnd + 2]; 00126 ridLen = _packet[comEnd + 4]; 00127 ridEnd = comEnd + 4 + ridLen; 00128 errLen = _packet[ridEnd + 2]; 00129 errEnd = ridEnd + 2 + errLen; 00130 eriLen = _packet[errEnd + 2]; 00131 eriEnd = errEnd + 2 + eriLen; 00132 vblTyp = _packet[eriEnd + 1]; 00133 vblLen = _packet[eriEnd + 2]; 00134 vbiTyp = _packet[eriEnd + 3]; 00135 vbiLen = _packet[eriEnd + 4]; 00136 obiLen = _packet[eriEnd + 6]; 00137 obiEnd = eriEnd + obiLen + 6; 00138 valTyp = _packet[obiEnd + 1]; 00139 valLen = _packet[obiEnd + 2]; 00140 valEnd = obiEnd + 2 + valLen; 00141 // 00142 // extract version 00143 pdu->version = 0; 00144 for ( i = 0; i < verLen; i++ ) { 00145 pdu->version = (pdu->version << 8) | _packet[5 + i]; 00146 } 00147 // 00148 // pdu-type 00149 pdu->type = (SNMP_PDU_TYPES)pduTyp; 00150 _dstType = pdu->type; 00151 // 00152 // validate community size 00153 if ( comLen > SNMP_MAX_NAME_LEN ) { 00154 // set pdu error 00155 pdu->error = SNMP_ERR_TOO_BIG; 00156 // 00157 //SNMP_FREE(_packet); 00158 00159 return SNMP_API_STAT_NAME_TOO_BIG; 00160 } 00161 // 00162 // extract and compare community name 00163 // allocate char array based on community size 00164 if ( (community = (char *)malloc(sizeof(char)*comLen)) == NULL ) { 00165 // 00166 //SNMP_FREE(_packet); 00167 00168 return SNMP_API_STAT_MALLOC_ERR; 00169 } 00170 // 00171 for ( i = 0; i < comLen; i++ ) { 00172 community[i] = _packet[verEnd + 3 + i]; 00173 } 00174 // terminate as a string 00175 community[comLen] = '\0'; 00176 // 00177 // validate community name 00178 if ( pdu->type == SNMP_PDU_SET ) { 00179 if ( strcmp(_setCommName, community) != 0 ) 00180 // set pdu error 00181 pdu->error = SNMP_ERR_NO_SUCH_NAME; 00182 } else { 00183 if ( strcmp(_getCommName, community) != 0 ) 00184 // set pdu error 00185 pdu->error = SNMP_ERR_NO_SUCH_NAME; 00186 } 00187 // 00188 // free community buffer 00189 SNMP_FREE(community); 00190 // 00191 // extract reqiest-id 0x00 0x00 0x00 0x01 (4-byte int aka int32) 00192 pdu->requestId = 0; 00193 for ( i = 0; i < ridLen; i++ ) { 00194 pdu->requestId = (pdu->requestId << 8) | _packet[comEnd + 5 + i]; 00195 } 00196 // 00197 // extract error 00198 pdu->error = SNMP_ERR_NO_ERROR; 00199 int32_t err = 0; 00200 for ( i = 0; i < errLen; i++ ) { 00201 err = (err << 8) | _packet[ridEnd + 3 + i]; 00202 } 00203 pdu->error = (SNMP_ERR_CODES)err; 00204 // 00205 // extract error-index 00206 pdu->errorIndex = 0; 00207 for ( i = 0; i < eriLen; i++ ) { 00208 pdu->errorIndex = (pdu->errorIndex << 8) | _packet[errEnd + 3 + i]; 00209 } 00210 // 00211 // 00212 // validate object-identifier size 00213 if ( obiLen > SNMP_MAX_OID_LEN ) { 00214 // set pdu error 00215 pdu->error = SNMP_ERR_TOO_BIG; 00216 // 00217 //SNMP_FREE(_packet); 00218 00219 return SNMP_API_STAT_OID_TOO_BIG; 00220 } 00221 // 00222 // extract and contruct object-identifier 00223 /* 00224 if ( (pdu->OID.oid = (byte *)malloc(sizeof(byte)*obiLen)) == NULL ) { 00225 // free DPU receive buffer 00226 _socket.readSkip(_socket.available()); 00227 // 00228 SNMP_FREE(_packet); 00229 00230 return SNMP_API_STAT_MALLOC_ERR; 00231 } 00232 */ 00233 memset(pdu->OID.data, 0, SNMP_MAX_OID_LEN); 00234 pdu->OID.size = obiLen; 00235 for ( i = 0; i < obiLen; i++ ) { 00236 pdu->OID.data[i] = _packet[eriEnd + 7 + i]; 00237 } 00238 // 00239 // value-type 00240 pdu->VALUE.syntax = (SNMP_SYNTAXES)valTyp; 00241 // 00242 // validate value size 00243 if ( obiLen > SNMP_MAX_VALUE_LEN ) { 00244 // set pdu error 00245 pdu->error = SNMP_ERR_TOO_BIG; 00246 // 00247 //SNMP_FREE(_packet); 00248 00249 return SNMP_API_STAT_VALUE_TOO_BIG; 00250 } 00251 // 00252 // value-size 00253 pdu->VALUE.size = valLen; 00254 // 00255 // extract value 00256 // allocate char array based on oid size 00257 /* 00258 if( (pdu->VALUE.value = (byte *)malloc(sizeof(byte)*valLen)) == NULL ) { 00259 // free DPU receive buffer 00260 _socket.readSkip(_socket.available()); 00261 // 00262 SNMP_FREE(_packet); 00263 00264 return SNMP_API_STAT_MALLOC_ERR; 00265 } 00266 */ 00267 memset(pdu->VALUE.data, 0, SNMP_MAX_VALUE_LEN); 00268 for ( i = 0; i < valLen; i++ ) { 00269 pdu->VALUE.data[i] = _packet[obiEnd + 3 + i]; 00270 } 00271 // 00272 //SNMP_FREE(_packet); 00273 // 00274 return SNMP_API_STAT_SUCCESS; 00275 } 00276 00277 uint16_t SNMP::fromPdu(SNMP_PDU *pdu,char *_packet) 00278 { 00279 int32_u u; 00280 uint16_t _packetSize; 00281 byte i; 00282 // 00283 // Length of entire SNMP packet 00284 _packetPos = 0; // 23 00285 _packetSize = 25 - 1 + sizeof(pdu->requestId) + sizeof(pdu->error) + sizeof(pdu->errorIndex) + pdu->OID.size + pdu->VALUE.size; 00286 // 00287 memset(_packet, 0, SNMP_MAX_PACKET_LEN); 00288 // 00289 if ( _dstType == SNMP_PDU_SET ) { 00290 _packetSize += _setSize; 00291 } else { 00292 _packetSize += _getSize; 00293 } 00294 // 00295 // allocate byte array based on packet size 00296 //if ( (_packet = (byte *)malloc(sizeof(byte)*_packetSize)) == NULL ) { 00297 // 00298 //SNMP_FREE(_packet); 00299 00300 // return SNMP_API_STAT_MALLOC_ERR; 00301 //} 00302 // 00303 _packet[_packetPos++] = (byte)SNMP_SYNTAX_SEQUENCE; // type 00304 _packet[_packetPos++] = (byte)_packetSize; // length 00305 // 00306 00307 // SNMP version 00308 _packet[_packetPos++] = (byte)SNMP_SYNTAX_INT; // type 00309 _packet[_packetPos++] = 0x01; // length 00310 _packet[_packetPos++] = 0x00; // value 00311 // 00312 // SNMP community string 00313 _packet[_packetPos++] = (byte)SNMP_SYNTAX_OCTETS; // type 00314 if ( _dstType == SNMP_PDU_SET ) { 00315 _packet[_packetPos++] = (byte)_setSize; // length 00316 for ( i = 0; i < _setSize; i++ ) { 00317 _packet[_packetPos++] = (byte)_setCommName[i]; 00318 } 00319 } else { 00320 _packet[_packetPos++] = (byte)_getSize; // length 00321 for ( i = 0; i < _getSize; i++ ) { 00322 _packet[_packetPos++] = (byte)_getCommName[i]; 00323 } 00324 } 00325 // 00326 // SNMP PDU 00327 _packet[_packetPos++] = (byte)pdu->type; 00328 _packet[_packetPos++] = (byte)( sizeof(pdu->requestId) + sizeof((int32_t)pdu->error) + sizeof(pdu->errorIndex) + pdu->OID.size + pdu->VALUE.size + 14 ); 00329 // 00330 // Request ID (size always 4 e.g. 4-byte int) 00331 _packet[_packetPos++] = (byte)SNMP_SYNTAX_INT; // type 00332 _packet[_packetPos++] = (byte)sizeof(pdu->requestId); 00333 u.int32 = pdu->requestId; 00334 _packet[_packetPos++] = u.data[3]; 00335 _packet[_packetPos++] = u.data[2]; 00336 _packet[_packetPos++] = u.data[1]; 00337 _packet[_packetPos++] = u.data[0]; 00338 // 00339 // Error (size always 4 e.g. 4-byte int) 00340 _packet[_packetPos++] = (byte)SNMP_SYNTAX_INT; // type 00341 _packet[_packetPos++] = (byte)sizeof((int32_t)pdu->error); 00342 u.int32 = pdu->error; 00343 _packet[_packetPos++] = u.data[3]; 00344 _packet[_packetPos++] = u.data[2]; 00345 _packet[_packetPos++] = u.data[1]; 00346 _packet[_packetPos++] = u.data[0]; 00347 // 00348 // Error Index (size always 4 e.g. 4-byte int) 00349 _packet[_packetPos++] = (byte)SNMP_SYNTAX_INT; // type 00350 _packet[_packetPos++] = (byte)sizeof(pdu->errorIndex); 00351 u.int32 = pdu->errorIndex; 00352 _packet[_packetPos++] = u.data[3]; 00353 _packet[_packetPos++] = u.data[2]; 00354 _packet[_packetPos++] = u.data[1]; 00355 _packet[_packetPos++] = u.data[0]; 00356 // 00357 // Varbind List 00358 _packet[_packetPos++] = (byte)SNMP_SYNTAX_SEQUENCE; // type 00359 _packet[_packetPos++] = (byte)( pdu->OID.size + pdu->VALUE.size + 6 ); //4 00360 // 00361 // Varbind 00362 _packet[_packetPos++] = (byte)SNMP_SYNTAX_SEQUENCE; // type 00363 _packet[_packetPos++] = (byte)( pdu->OID.size + pdu->VALUE.size + 4 ); //2 00364 // 00365 // ObjectIdentifier 00366 _packet[_packetPos++] = (byte)SNMP_SYNTAX_OID; // type 00367 _packet[_packetPos++] = (byte)(pdu->OID.size); 00368 for ( i = 0; i < pdu->OID.size; i++ ) { 00369 _packet[_packetPos++] = pdu->OID.data[i]; 00370 } 00371 // 00372 // Value 00373 _packet[_packetPos++] = (byte)pdu->VALUE.syntax; // type 00374 _packet[_packetPos++] = (byte)(pdu->VALUE.size); 00375 for ( i = 0; i < pdu->VALUE.size; i++ ) { 00376 _packet[_packetPos++] = pdu->VALUE.data[i]; 00377 } 00378 // 00379 // 00380 //SNMP_FREE(_packet); 00381 // 00382 return _packetSize; 00383 } 00384 00385 00386 00387 00388 void SNMP::freePdu(SNMP_PDU *pdu) 00389 { 00390 //SNMP_FREE(pdu->OID.oid); 00391 //SNMP_FREE(pdu->VALUE.value); 00392 memset(pdu->OID.data, 0, SNMP_MAX_OID_LEN); 00393 memset(pdu->VALUE.data, 0, SNMP_MAX_VALUE_LEN); 00394 //free((char *) pdu); 00395 } 00396 00397 // Create one global object 00398 //SNMP Agentbed;
Generated on Wed Jul 13 2022 06:43:37 by 1.7.2