Some quick code to use UDP-only (no TCP) with mBed. Echos received packets and sends packets when a button is pressed

Dependencies:   mbed

Committer:
pehrhovey
Date:
Sun Mar 14 00:54:12 2010 +0000
Revision:
0:a548a085de55

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
pehrhovey 0:a548a085de55 1 /**
pehrhovey 0:a548a085de55 2 * @file
pehrhovey 0:a548a085de55 3 * Abstract Syntax Notation One (ISO 8824, 8825) decoding
pehrhovey 0:a548a085de55 4 *
pehrhovey 0:a548a085de55 5 * @todo not optimised (yet), favor correctness over speed, favor speed over size
pehrhovey 0:a548a085de55 6 */
pehrhovey 0:a548a085de55 7
pehrhovey 0:a548a085de55 8 /*
pehrhovey 0:a548a085de55 9 * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands.
pehrhovey 0:a548a085de55 10 * All rights reserved.
pehrhovey 0:a548a085de55 11 *
pehrhovey 0:a548a085de55 12 * Redistribution and use in source and binary forms, with or without modification,
pehrhovey 0:a548a085de55 13 * are permitted provided that the following conditions are met:
pehrhovey 0:a548a085de55 14 *
pehrhovey 0:a548a085de55 15 * 1. Redistributions of source code must retain the above copyright notice,
pehrhovey 0:a548a085de55 16 * this list of conditions and the following disclaimer.
pehrhovey 0:a548a085de55 17 * 2. Redistributions in binary form must reproduce the above copyright notice,
pehrhovey 0:a548a085de55 18 * this list of conditions and the following disclaimer in the documentation
pehrhovey 0:a548a085de55 19 * and/or other materials provided with the distribution.
pehrhovey 0:a548a085de55 20 * 3. The name of the author may not be used to endorse or promote products
pehrhovey 0:a548a085de55 21 * derived from this software without specific prior written permission.
pehrhovey 0:a548a085de55 22 *
pehrhovey 0:a548a085de55 23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
pehrhovey 0:a548a085de55 24 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
pehrhovey 0:a548a085de55 25 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
pehrhovey 0:a548a085de55 26 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
pehrhovey 0:a548a085de55 27 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
pehrhovey 0:a548a085de55 28 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
pehrhovey 0:a548a085de55 29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
pehrhovey 0:a548a085de55 30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
pehrhovey 0:a548a085de55 31 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
pehrhovey 0:a548a085de55 32 * OF SUCH DAMAGE.
pehrhovey 0:a548a085de55 33 *
pehrhovey 0:a548a085de55 34 * Author: Christiaan Simons <christiaan.simons@axon.tv>
pehrhovey 0:a548a085de55 35 */
pehrhovey 0:a548a085de55 36
pehrhovey 0:a548a085de55 37 #include "lwip/opt.h"
pehrhovey 0:a548a085de55 38
pehrhovey 0:a548a085de55 39 #if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */
pehrhovey 0:a548a085de55 40
pehrhovey 0:a548a085de55 41 #include "lwip/snmp_asn1.h"
pehrhovey 0:a548a085de55 42
pehrhovey 0:a548a085de55 43 /**
pehrhovey 0:a548a085de55 44 * Retrieves type field from incoming pbuf chain.
pehrhovey 0:a548a085de55 45 *
pehrhovey 0:a548a085de55 46 * @param p points to a pbuf holding an ASN1 coded type field
pehrhovey 0:a548a085de55 47 * @param ofs points to the offset within the pbuf chain of the ASN1 coded type field
pehrhovey 0:a548a085de55 48 * @param type return ASN1 type
pehrhovey 0:a548a085de55 49 * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) decode
pehrhovey 0:a548a085de55 50 */
pehrhovey 0:a548a085de55 51 err_t
pehrhovey 0:a548a085de55 52 snmp_asn1_dec_type(struct pbuf *p, u16_t ofs, u8_t *type)
pehrhovey 0:a548a085de55 53 {
pehrhovey 0:a548a085de55 54 u16_t plen, base;
pehrhovey 0:a548a085de55 55 u8_t *msg_ptr;
pehrhovey 0:a548a085de55 56
pehrhovey 0:a548a085de55 57 plen = 0;
pehrhovey 0:a548a085de55 58 while (p != NULL)
pehrhovey 0:a548a085de55 59 {
pehrhovey 0:a548a085de55 60 base = plen;
pehrhovey 0:a548a085de55 61 plen += p->len;
pehrhovey 0:a548a085de55 62 if (ofs < plen)
pehrhovey 0:a548a085de55 63 {
pehrhovey 0:a548a085de55 64 msg_ptr = p->payload;
pehrhovey 0:a548a085de55 65 msg_ptr += ofs - base;
pehrhovey 0:a548a085de55 66 *type = *msg_ptr;
pehrhovey 0:a548a085de55 67 return ERR_OK;
pehrhovey 0:a548a085de55 68 }
pehrhovey 0:a548a085de55 69 p = p->next;
pehrhovey 0:a548a085de55 70 }
pehrhovey 0:a548a085de55 71 /* p == NULL, ofs >= plen */
pehrhovey 0:a548a085de55 72 return ERR_ARG;
pehrhovey 0:a548a085de55 73 }
pehrhovey 0:a548a085de55 74
pehrhovey 0:a548a085de55 75 /**
pehrhovey 0:a548a085de55 76 * Decodes length field from incoming pbuf chain into host length.
pehrhovey 0:a548a085de55 77 *
pehrhovey 0:a548a085de55 78 * @param p points to a pbuf holding an ASN1 coded length
pehrhovey 0:a548a085de55 79 * @param ofs points to the offset within the pbuf chain of the ASN1 coded length
pehrhovey 0:a548a085de55 80 * @param octets_used returns number of octets used by the length code
pehrhovey 0:a548a085de55 81 * @param length return host order length, upto 64k
pehrhovey 0:a548a085de55 82 * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) decode
pehrhovey 0:a548a085de55 83 */
pehrhovey 0:a548a085de55 84 err_t
pehrhovey 0:a548a085de55 85 snmp_asn1_dec_length(struct pbuf *p, u16_t ofs, u8_t *octets_used, u16_t *length)
pehrhovey 0:a548a085de55 86 {
pehrhovey 0:a548a085de55 87 u16_t plen, base;
pehrhovey 0:a548a085de55 88 u8_t *msg_ptr;
pehrhovey 0:a548a085de55 89
pehrhovey 0:a548a085de55 90 plen = 0;
pehrhovey 0:a548a085de55 91 while (p != NULL)
pehrhovey 0:a548a085de55 92 {
pehrhovey 0:a548a085de55 93 base = plen;
pehrhovey 0:a548a085de55 94 plen += p->len;
pehrhovey 0:a548a085de55 95 if (ofs < plen)
pehrhovey 0:a548a085de55 96 {
pehrhovey 0:a548a085de55 97 msg_ptr = p->payload;
pehrhovey 0:a548a085de55 98 msg_ptr += ofs - base;
pehrhovey 0:a548a085de55 99
pehrhovey 0:a548a085de55 100 if (*msg_ptr < 0x80)
pehrhovey 0:a548a085de55 101 {
pehrhovey 0:a548a085de55 102 /* primitive definite length format */
pehrhovey 0:a548a085de55 103 *octets_used = 1;
pehrhovey 0:a548a085de55 104 *length = *msg_ptr;
pehrhovey 0:a548a085de55 105 return ERR_OK;
pehrhovey 0:a548a085de55 106 }
pehrhovey 0:a548a085de55 107 else if (*msg_ptr == 0x80)
pehrhovey 0:a548a085de55 108 {
pehrhovey 0:a548a085de55 109 /* constructed indefinite length format, termination with two zero octets */
pehrhovey 0:a548a085de55 110 u8_t zeros;
pehrhovey 0:a548a085de55 111 u8_t i;
pehrhovey 0:a548a085de55 112
pehrhovey 0:a548a085de55 113 *length = 0;
pehrhovey 0:a548a085de55 114 zeros = 0;
pehrhovey 0:a548a085de55 115 while (zeros != 2)
pehrhovey 0:a548a085de55 116 {
pehrhovey 0:a548a085de55 117 i = 2;
pehrhovey 0:a548a085de55 118 while (i > 0)
pehrhovey 0:a548a085de55 119 {
pehrhovey 0:a548a085de55 120 i--;
pehrhovey 0:a548a085de55 121 (*length) += 1;
pehrhovey 0:a548a085de55 122 ofs += 1;
pehrhovey 0:a548a085de55 123 if (ofs >= plen)
pehrhovey 0:a548a085de55 124 {
pehrhovey 0:a548a085de55 125 /* next octet in next pbuf */
pehrhovey 0:a548a085de55 126 p = p->next;
pehrhovey 0:a548a085de55 127 if (p == NULL) { return ERR_ARG; }
pehrhovey 0:a548a085de55 128 msg_ptr = p->payload;
pehrhovey 0:a548a085de55 129 plen += p->len;
pehrhovey 0:a548a085de55 130 }
pehrhovey 0:a548a085de55 131 else
pehrhovey 0:a548a085de55 132 {
pehrhovey 0:a548a085de55 133 /* next octet in same pbuf */
pehrhovey 0:a548a085de55 134 msg_ptr++;
pehrhovey 0:a548a085de55 135 }
pehrhovey 0:a548a085de55 136 if (*msg_ptr == 0)
pehrhovey 0:a548a085de55 137 {
pehrhovey 0:a548a085de55 138 zeros++;
pehrhovey 0:a548a085de55 139 if (zeros == 2)
pehrhovey 0:a548a085de55 140 {
pehrhovey 0:a548a085de55 141 /* stop while (i > 0) */
pehrhovey 0:a548a085de55 142 i = 0;
pehrhovey 0:a548a085de55 143 }
pehrhovey 0:a548a085de55 144 }
pehrhovey 0:a548a085de55 145 else
pehrhovey 0:a548a085de55 146 {
pehrhovey 0:a548a085de55 147 zeros = 0;
pehrhovey 0:a548a085de55 148 }
pehrhovey 0:a548a085de55 149 }
pehrhovey 0:a548a085de55 150 }
pehrhovey 0:a548a085de55 151 *octets_used = 1;
pehrhovey 0:a548a085de55 152 return ERR_OK;
pehrhovey 0:a548a085de55 153 }
pehrhovey 0:a548a085de55 154 else if (*msg_ptr == 0x81)
pehrhovey 0:a548a085de55 155 {
pehrhovey 0:a548a085de55 156 /* constructed definite length format, one octet */
pehrhovey 0:a548a085de55 157 ofs += 1;
pehrhovey 0:a548a085de55 158 if (ofs >= plen)
pehrhovey 0:a548a085de55 159 {
pehrhovey 0:a548a085de55 160 /* next octet in next pbuf */
pehrhovey 0:a548a085de55 161 p = p->next;
pehrhovey 0:a548a085de55 162 if (p == NULL) { return ERR_ARG; }
pehrhovey 0:a548a085de55 163 msg_ptr = p->payload;
pehrhovey 0:a548a085de55 164 }
pehrhovey 0:a548a085de55 165 else
pehrhovey 0:a548a085de55 166 {
pehrhovey 0:a548a085de55 167 /* next octet in same pbuf */
pehrhovey 0:a548a085de55 168 msg_ptr++;
pehrhovey 0:a548a085de55 169 }
pehrhovey 0:a548a085de55 170 *length = *msg_ptr;
pehrhovey 0:a548a085de55 171 *octets_used = 2;
pehrhovey 0:a548a085de55 172 return ERR_OK;
pehrhovey 0:a548a085de55 173 }
pehrhovey 0:a548a085de55 174 else if (*msg_ptr == 0x82)
pehrhovey 0:a548a085de55 175 {
pehrhovey 0:a548a085de55 176 u8_t i;
pehrhovey 0:a548a085de55 177
pehrhovey 0:a548a085de55 178 /* constructed definite length format, two octets */
pehrhovey 0:a548a085de55 179 i = 2;
pehrhovey 0:a548a085de55 180 while (i > 0)
pehrhovey 0:a548a085de55 181 {
pehrhovey 0:a548a085de55 182 i--;
pehrhovey 0:a548a085de55 183 ofs += 1;
pehrhovey 0:a548a085de55 184 if (ofs >= plen)
pehrhovey 0:a548a085de55 185 {
pehrhovey 0:a548a085de55 186 /* next octet in next pbuf */
pehrhovey 0:a548a085de55 187 p = p->next;
pehrhovey 0:a548a085de55 188 if (p == NULL) { return ERR_ARG; }
pehrhovey 0:a548a085de55 189 msg_ptr = p->payload;
pehrhovey 0:a548a085de55 190 plen += p->len;
pehrhovey 0:a548a085de55 191 }
pehrhovey 0:a548a085de55 192 else
pehrhovey 0:a548a085de55 193 {
pehrhovey 0:a548a085de55 194 /* next octet in same pbuf */
pehrhovey 0:a548a085de55 195 msg_ptr++;
pehrhovey 0:a548a085de55 196 }
pehrhovey 0:a548a085de55 197 if (i == 0)
pehrhovey 0:a548a085de55 198 {
pehrhovey 0:a548a085de55 199 /* least significant length octet */
pehrhovey 0:a548a085de55 200 *length |= *msg_ptr;
pehrhovey 0:a548a085de55 201 }
pehrhovey 0:a548a085de55 202 else
pehrhovey 0:a548a085de55 203 {
pehrhovey 0:a548a085de55 204 /* most significant length octet */
pehrhovey 0:a548a085de55 205 *length = (*msg_ptr) << 8;
pehrhovey 0:a548a085de55 206 }
pehrhovey 0:a548a085de55 207 }
pehrhovey 0:a548a085de55 208 *octets_used = 3;
pehrhovey 0:a548a085de55 209 return ERR_OK;
pehrhovey 0:a548a085de55 210 }
pehrhovey 0:a548a085de55 211 else
pehrhovey 0:a548a085de55 212 {
pehrhovey 0:a548a085de55 213 /* constructed definite length format 3..127 octets, this is too big (>64k) */
pehrhovey 0:a548a085de55 214 /** @todo: do we need to accept inefficient codings with many leading zero's? */
pehrhovey 0:a548a085de55 215 *octets_used = 1 + ((*msg_ptr) & 0x7f);
pehrhovey 0:a548a085de55 216 return ERR_ARG;
pehrhovey 0:a548a085de55 217 }
pehrhovey 0:a548a085de55 218 }
pehrhovey 0:a548a085de55 219 p = p->next;
pehrhovey 0:a548a085de55 220 }
pehrhovey 0:a548a085de55 221
pehrhovey 0:a548a085de55 222 /* p == NULL, ofs >= plen */
pehrhovey 0:a548a085de55 223 return ERR_ARG;
pehrhovey 0:a548a085de55 224 }
pehrhovey 0:a548a085de55 225
pehrhovey 0:a548a085de55 226 /**
pehrhovey 0:a548a085de55 227 * Decodes positive integer (counter, gauge, timeticks) into u32_t.
pehrhovey 0:a548a085de55 228 *
pehrhovey 0:a548a085de55 229 * @param p points to a pbuf holding an ASN1 coded integer
pehrhovey 0:a548a085de55 230 * @param ofs points to the offset within the pbuf chain of the ASN1 coded integer
pehrhovey 0:a548a085de55 231 * @param len length of the coded integer field
pehrhovey 0:a548a085de55 232 * @param value return host order integer
pehrhovey 0:a548a085de55 233 * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) decode
pehrhovey 0:a548a085de55 234 *
pehrhovey 0:a548a085de55 235 * @note ASN coded integers are _always_ signed. E.g. +0xFFFF is coded
pehrhovey 0:a548a085de55 236 * as 0x00,0xFF,0xFF. Note the leading sign octet. A positive value
pehrhovey 0:a548a085de55 237 * of 0xFFFFFFFF is preceded with 0x00 and the length is 5 octets!!
pehrhovey 0:a548a085de55 238 */
pehrhovey 0:a548a085de55 239 err_t
pehrhovey 0:a548a085de55 240 snmp_asn1_dec_u32t(struct pbuf *p, u16_t ofs, u16_t len, u32_t *value)
pehrhovey 0:a548a085de55 241 {
pehrhovey 0:a548a085de55 242 u16_t plen, base;
pehrhovey 0:a548a085de55 243 u8_t *msg_ptr;
pehrhovey 0:a548a085de55 244
pehrhovey 0:a548a085de55 245 plen = 0;
pehrhovey 0:a548a085de55 246 while (p != NULL)
pehrhovey 0:a548a085de55 247 {
pehrhovey 0:a548a085de55 248 base = plen;
pehrhovey 0:a548a085de55 249 plen += p->len;
pehrhovey 0:a548a085de55 250 if (ofs < plen)
pehrhovey 0:a548a085de55 251 {
pehrhovey 0:a548a085de55 252 msg_ptr = p->payload;
pehrhovey 0:a548a085de55 253 msg_ptr += ofs - base;
pehrhovey 0:a548a085de55 254 if ((len > 0) && (len < 6))
pehrhovey 0:a548a085de55 255 {
pehrhovey 0:a548a085de55 256 /* start from zero */
pehrhovey 0:a548a085de55 257 *value = 0;
pehrhovey 0:a548a085de55 258 if (*msg_ptr & 0x80)
pehrhovey 0:a548a085de55 259 {
pehrhovey 0:a548a085de55 260 /* negative, expecting zero sign bit! */
pehrhovey 0:a548a085de55 261 return ERR_ARG;
pehrhovey 0:a548a085de55 262 }
pehrhovey 0:a548a085de55 263 else
pehrhovey 0:a548a085de55 264 {
pehrhovey 0:a548a085de55 265 /* positive */
pehrhovey 0:a548a085de55 266 if ((len > 1) && (*msg_ptr == 0))
pehrhovey 0:a548a085de55 267 {
pehrhovey 0:a548a085de55 268 /* skip leading "sign byte" octet 0x00 */
pehrhovey 0:a548a085de55 269 len--;
pehrhovey 0:a548a085de55 270 ofs += 1;
pehrhovey 0:a548a085de55 271 if (ofs >= plen)
pehrhovey 0:a548a085de55 272 {
pehrhovey 0:a548a085de55 273 /* next octet in next pbuf */
pehrhovey 0:a548a085de55 274 p = p->next;
pehrhovey 0:a548a085de55 275 if (p == NULL) { return ERR_ARG; }
pehrhovey 0:a548a085de55 276 msg_ptr = p->payload;
pehrhovey 0:a548a085de55 277 plen += p->len;
pehrhovey 0:a548a085de55 278 }
pehrhovey 0:a548a085de55 279 else
pehrhovey 0:a548a085de55 280 {
pehrhovey 0:a548a085de55 281 /* next octet in same pbuf */
pehrhovey 0:a548a085de55 282 msg_ptr++;
pehrhovey 0:a548a085de55 283 }
pehrhovey 0:a548a085de55 284 }
pehrhovey 0:a548a085de55 285 }
pehrhovey 0:a548a085de55 286 /* OR octets with value */
pehrhovey 0:a548a085de55 287 while (len > 1)
pehrhovey 0:a548a085de55 288 {
pehrhovey 0:a548a085de55 289 len--;
pehrhovey 0:a548a085de55 290 *value |= *msg_ptr;
pehrhovey 0:a548a085de55 291 *value <<= 8;
pehrhovey 0:a548a085de55 292 ofs += 1;
pehrhovey 0:a548a085de55 293 if (ofs >= plen)
pehrhovey 0:a548a085de55 294 {
pehrhovey 0:a548a085de55 295 /* next octet in next pbuf */
pehrhovey 0:a548a085de55 296 p = p->next;
pehrhovey 0:a548a085de55 297 if (p == NULL) { return ERR_ARG; }
pehrhovey 0:a548a085de55 298 msg_ptr = p->payload;
pehrhovey 0:a548a085de55 299 plen += p->len;
pehrhovey 0:a548a085de55 300 }
pehrhovey 0:a548a085de55 301 else
pehrhovey 0:a548a085de55 302 {
pehrhovey 0:a548a085de55 303 /* next octet in same pbuf */
pehrhovey 0:a548a085de55 304 msg_ptr++;
pehrhovey 0:a548a085de55 305 }
pehrhovey 0:a548a085de55 306 }
pehrhovey 0:a548a085de55 307 *value |= *msg_ptr;
pehrhovey 0:a548a085de55 308 return ERR_OK;
pehrhovey 0:a548a085de55 309 }
pehrhovey 0:a548a085de55 310 else
pehrhovey 0:a548a085de55 311 {
pehrhovey 0:a548a085de55 312 return ERR_ARG;
pehrhovey 0:a548a085de55 313 }
pehrhovey 0:a548a085de55 314 }
pehrhovey 0:a548a085de55 315 p = p->next;
pehrhovey 0:a548a085de55 316 }
pehrhovey 0:a548a085de55 317 /* p == NULL, ofs >= plen */
pehrhovey 0:a548a085de55 318 return ERR_ARG;
pehrhovey 0:a548a085de55 319 }
pehrhovey 0:a548a085de55 320
pehrhovey 0:a548a085de55 321 /**
pehrhovey 0:a548a085de55 322 * Decodes integer into s32_t.
pehrhovey 0:a548a085de55 323 *
pehrhovey 0:a548a085de55 324 * @param p points to a pbuf holding an ASN1 coded integer
pehrhovey 0:a548a085de55 325 * @param ofs points to the offset within the pbuf chain of the ASN1 coded integer
pehrhovey 0:a548a085de55 326 * @param len length of the coded integer field
pehrhovey 0:a548a085de55 327 * @param value return host order integer
pehrhovey 0:a548a085de55 328 * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) decode
pehrhovey 0:a548a085de55 329 *
pehrhovey 0:a548a085de55 330 * @note ASN coded integers are _always_ signed!
pehrhovey 0:a548a085de55 331 */
pehrhovey 0:a548a085de55 332 err_t
pehrhovey 0:a548a085de55 333 snmp_asn1_dec_s32t(struct pbuf *p, u16_t ofs, u16_t len, s32_t *value)
pehrhovey 0:a548a085de55 334 {
pehrhovey 0:a548a085de55 335 u16_t plen, base;
pehrhovey 0:a548a085de55 336 u8_t *msg_ptr;
pehrhovey 0:a548a085de55 337 #if BYTE_ORDER == LITTLE_ENDIAN
pehrhovey 0:a548a085de55 338 u8_t *lsb_ptr = (u8_t*)value;
pehrhovey 0:a548a085de55 339 #endif
pehrhovey 0:a548a085de55 340 #if BYTE_ORDER == BIG_ENDIAN
pehrhovey 0:a548a085de55 341 u8_t *lsb_ptr = (u8_t*)value + sizeof(s32_t) - 1;
pehrhovey 0:a548a085de55 342 #endif
pehrhovey 0:a548a085de55 343 u8_t sign;
pehrhovey 0:a548a085de55 344
pehrhovey 0:a548a085de55 345 plen = 0;
pehrhovey 0:a548a085de55 346 while (p != NULL)
pehrhovey 0:a548a085de55 347 {
pehrhovey 0:a548a085de55 348 base = plen;
pehrhovey 0:a548a085de55 349 plen += p->len;
pehrhovey 0:a548a085de55 350 if (ofs < plen)
pehrhovey 0:a548a085de55 351 {
pehrhovey 0:a548a085de55 352 msg_ptr = p->payload;
pehrhovey 0:a548a085de55 353 msg_ptr += ofs - base;
pehrhovey 0:a548a085de55 354 if ((len > 0) && (len < 5))
pehrhovey 0:a548a085de55 355 {
pehrhovey 0:a548a085de55 356 if (*msg_ptr & 0x80)
pehrhovey 0:a548a085de55 357 {
pehrhovey 0:a548a085de55 358 /* negative, start from -1 */
pehrhovey 0:a548a085de55 359 *value = -1;
pehrhovey 0:a548a085de55 360 sign = 1;
pehrhovey 0:a548a085de55 361 }
pehrhovey 0:a548a085de55 362 else
pehrhovey 0:a548a085de55 363 {
pehrhovey 0:a548a085de55 364 /* positive, start from 0 */
pehrhovey 0:a548a085de55 365 *value = 0;
pehrhovey 0:a548a085de55 366 sign = 0;
pehrhovey 0:a548a085de55 367 }
pehrhovey 0:a548a085de55 368 /* OR/AND octets with value */
pehrhovey 0:a548a085de55 369 while (len > 1)
pehrhovey 0:a548a085de55 370 {
pehrhovey 0:a548a085de55 371 len--;
pehrhovey 0:a548a085de55 372 if (sign)
pehrhovey 0:a548a085de55 373 {
pehrhovey 0:a548a085de55 374 *lsb_ptr &= *msg_ptr;
pehrhovey 0:a548a085de55 375 *value <<= 8;
pehrhovey 0:a548a085de55 376 *lsb_ptr |= 255;
pehrhovey 0:a548a085de55 377 }
pehrhovey 0:a548a085de55 378 else
pehrhovey 0:a548a085de55 379 {
pehrhovey 0:a548a085de55 380 *lsb_ptr |= *msg_ptr;
pehrhovey 0:a548a085de55 381 *value <<= 8;
pehrhovey 0:a548a085de55 382 }
pehrhovey 0:a548a085de55 383 ofs += 1;
pehrhovey 0:a548a085de55 384 if (ofs >= plen)
pehrhovey 0:a548a085de55 385 {
pehrhovey 0:a548a085de55 386 /* next octet in next pbuf */
pehrhovey 0:a548a085de55 387 p = p->next;
pehrhovey 0:a548a085de55 388 if (p == NULL) { return ERR_ARG; }
pehrhovey 0:a548a085de55 389 msg_ptr = p->payload;
pehrhovey 0:a548a085de55 390 plen += p->len;
pehrhovey 0:a548a085de55 391 }
pehrhovey 0:a548a085de55 392 else
pehrhovey 0:a548a085de55 393 {
pehrhovey 0:a548a085de55 394 /* next octet in same pbuf */
pehrhovey 0:a548a085de55 395 msg_ptr++;
pehrhovey 0:a548a085de55 396 }
pehrhovey 0:a548a085de55 397 }
pehrhovey 0:a548a085de55 398 if (sign)
pehrhovey 0:a548a085de55 399 {
pehrhovey 0:a548a085de55 400 *lsb_ptr &= *msg_ptr;
pehrhovey 0:a548a085de55 401 }
pehrhovey 0:a548a085de55 402 else
pehrhovey 0:a548a085de55 403 {
pehrhovey 0:a548a085de55 404 *lsb_ptr |= *msg_ptr;
pehrhovey 0:a548a085de55 405 }
pehrhovey 0:a548a085de55 406 return ERR_OK;
pehrhovey 0:a548a085de55 407 }
pehrhovey 0:a548a085de55 408 else
pehrhovey 0:a548a085de55 409 {
pehrhovey 0:a548a085de55 410 return ERR_ARG;
pehrhovey 0:a548a085de55 411 }
pehrhovey 0:a548a085de55 412 }
pehrhovey 0:a548a085de55 413 p = p->next;
pehrhovey 0:a548a085de55 414 }
pehrhovey 0:a548a085de55 415 /* p == NULL, ofs >= plen */
pehrhovey 0:a548a085de55 416 return ERR_ARG;
pehrhovey 0:a548a085de55 417 }
pehrhovey 0:a548a085de55 418
pehrhovey 0:a548a085de55 419 /**
pehrhovey 0:a548a085de55 420 * Decodes object identifier from incoming message into array of s32_t.
pehrhovey 0:a548a085de55 421 *
pehrhovey 0:a548a085de55 422 * @param p points to a pbuf holding an ASN1 coded object identifier
pehrhovey 0:a548a085de55 423 * @param ofs points to the offset within the pbuf chain of the ASN1 coded object identifier
pehrhovey 0:a548a085de55 424 * @param len length of the coded object identifier
pehrhovey 0:a548a085de55 425 * @param oid return object identifier struct
pehrhovey 0:a548a085de55 426 * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) decode
pehrhovey 0:a548a085de55 427 */
pehrhovey 0:a548a085de55 428 err_t
pehrhovey 0:a548a085de55 429 snmp_asn1_dec_oid(struct pbuf *p, u16_t ofs, u16_t len, struct snmp_obj_id *oid)
pehrhovey 0:a548a085de55 430 {
pehrhovey 0:a548a085de55 431 u16_t plen, base;
pehrhovey 0:a548a085de55 432 u8_t *msg_ptr;
pehrhovey 0:a548a085de55 433 s32_t *oid_ptr;
pehrhovey 0:a548a085de55 434
pehrhovey 0:a548a085de55 435 plen = 0;
pehrhovey 0:a548a085de55 436 while (p != NULL)
pehrhovey 0:a548a085de55 437 {
pehrhovey 0:a548a085de55 438 base = plen;
pehrhovey 0:a548a085de55 439 plen += p->len;
pehrhovey 0:a548a085de55 440 if (ofs < plen)
pehrhovey 0:a548a085de55 441 {
pehrhovey 0:a548a085de55 442 msg_ptr = p->payload;
pehrhovey 0:a548a085de55 443 msg_ptr += ofs - base;
pehrhovey 0:a548a085de55 444
pehrhovey 0:a548a085de55 445 oid->len = 0;
pehrhovey 0:a548a085de55 446 oid_ptr = &oid->id[0];
pehrhovey 0:a548a085de55 447 if (len > 0)
pehrhovey 0:a548a085de55 448 {
pehrhovey 0:a548a085de55 449 /* first compressed octet */
pehrhovey 0:a548a085de55 450 if (*msg_ptr == 0x2B)
pehrhovey 0:a548a085de55 451 {
pehrhovey 0:a548a085de55 452 /* (most) common case 1.3 (iso.org) */
pehrhovey 0:a548a085de55 453 *oid_ptr = 1;
pehrhovey 0:a548a085de55 454 oid_ptr++;
pehrhovey 0:a548a085de55 455 *oid_ptr = 3;
pehrhovey 0:a548a085de55 456 oid_ptr++;
pehrhovey 0:a548a085de55 457 }
pehrhovey 0:a548a085de55 458 else if (*msg_ptr < 40)
pehrhovey 0:a548a085de55 459 {
pehrhovey 0:a548a085de55 460 *oid_ptr = 0;
pehrhovey 0:a548a085de55 461 oid_ptr++;
pehrhovey 0:a548a085de55 462 *oid_ptr = *msg_ptr;
pehrhovey 0:a548a085de55 463 oid_ptr++;
pehrhovey 0:a548a085de55 464 }
pehrhovey 0:a548a085de55 465 else if (*msg_ptr < 80)
pehrhovey 0:a548a085de55 466 {
pehrhovey 0:a548a085de55 467 *oid_ptr = 1;
pehrhovey 0:a548a085de55 468 oid_ptr++;
pehrhovey 0:a548a085de55 469 *oid_ptr = (*msg_ptr) - 40;
pehrhovey 0:a548a085de55 470 oid_ptr++;
pehrhovey 0:a548a085de55 471 }
pehrhovey 0:a548a085de55 472 else
pehrhovey 0:a548a085de55 473 {
pehrhovey 0:a548a085de55 474 *oid_ptr = 2;
pehrhovey 0:a548a085de55 475 oid_ptr++;
pehrhovey 0:a548a085de55 476 *oid_ptr = (*msg_ptr) - 80;
pehrhovey 0:a548a085de55 477 oid_ptr++;
pehrhovey 0:a548a085de55 478 }
pehrhovey 0:a548a085de55 479 oid->len = 2;
pehrhovey 0:a548a085de55 480 }
pehrhovey 0:a548a085de55 481 else
pehrhovey 0:a548a085de55 482 {
pehrhovey 0:a548a085de55 483 /* accepting zero length identifiers e.g. for
pehrhovey 0:a548a085de55 484 getnext operation. uncommon but valid */
pehrhovey 0:a548a085de55 485 return ERR_OK;
pehrhovey 0:a548a085de55 486 }
pehrhovey 0:a548a085de55 487 len--;
pehrhovey 0:a548a085de55 488 if (len > 0)
pehrhovey 0:a548a085de55 489 {
pehrhovey 0:a548a085de55 490 ofs += 1;
pehrhovey 0:a548a085de55 491 if (ofs >= plen)
pehrhovey 0:a548a085de55 492 {
pehrhovey 0:a548a085de55 493 /* next octet in next pbuf */
pehrhovey 0:a548a085de55 494 p = p->next;
pehrhovey 0:a548a085de55 495 if (p == NULL) { return ERR_ARG; }
pehrhovey 0:a548a085de55 496 msg_ptr = p->payload;
pehrhovey 0:a548a085de55 497 plen += p->len;
pehrhovey 0:a548a085de55 498 }
pehrhovey 0:a548a085de55 499 else
pehrhovey 0:a548a085de55 500 {
pehrhovey 0:a548a085de55 501 /* next octet in same pbuf */
pehrhovey 0:a548a085de55 502 msg_ptr++;
pehrhovey 0:a548a085de55 503 }
pehrhovey 0:a548a085de55 504 }
pehrhovey 0:a548a085de55 505 while ((len > 0) && (oid->len < LWIP_SNMP_OBJ_ID_LEN))
pehrhovey 0:a548a085de55 506 {
pehrhovey 0:a548a085de55 507 /* sub-identifier uses multiple octets */
pehrhovey 0:a548a085de55 508 if (*msg_ptr & 0x80)
pehrhovey 0:a548a085de55 509 {
pehrhovey 0:a548a085de55 510 s32_t sub_id = 0;
pehrhovey 0:a548a085de55 511
pehrhovey 0:a548a085de55 512 while ((*msg_ptr & 0x80) && (len > 1))
pehrhovey 0:a548a085de55 513 {
pehrhovey 0:a548a085de55 514 len--;
pehrhovey 0:a548a085de55 515 sub_id = (sub_id << 7) + (*msg_ptr & ~0x80);
pehrhovey 0:a548a085de55 516 ofs += 1;
pehrhovey 0:a548a085de55 517 if (ofs >= plen)
pehrhovey 0:a548a085de55 518 {
pehrhovey 0:a548a085de55 519 /* next octet in next pbuf */
pehrhovey 0:a548a085de55 520 p = p->next;
pehrhovey 0:a548a085de55 521 if (p == NULL) { return ERR_ARG; }
pehrhovey 0:a548a085de55 522 msg_ptr = p->payload;
pehrhovey 0:a548a085de55 523 plen += p->len;
pehrhovey 0:a548a085de55 524 }
pehrhovey 0:a548a085de55 525 else
pehrhovey 0:a548a085de55 526 {
pehrhovey 0:a548a085de55 527 /* next octet in same pbuf */
pehrhovey 0:a548a085de55 528 msg_ptr++;
pehrhovey 0:a548a085de55 529 }
pehrhovey 0:a548a085de55 530 }
pehrhovey 0:a548a085de55 531 if (!(*msg_ptr & 0x80) && (len > 0))
pehrhovey 0:a548a085de55 532 {
pehrhovey 0:a548a085de55 533 /* last octet sub-identifier */
pehrhovey 0:a548a085de55 534 len--;
pehrhovey 0:a548a085de55 535 sub_id = (sub_id << 7) + *msg_ptr;
pehrhovey 0:a548a085de55 536 *oid_ptr = sub_id;
pehrhovey 0:a548a085de55 537 }
pehrhovey 0:a548a085de55 538 }
pehrhovey 0:a548a085de55 539 else
pehrhovey 0:a548a085de55 540 {
pehrhovey 0:a548a085de55 541 /* !(*msg_ptr & 0x80) sub-identifier uses single octet */
pehrhovey 0:a548a085de55 542 len--;
pehrhovey 0:a548a085de55 543 *oid_ptr = *msg_ptr;
pehrhovey 0:a548a085de55 544 }
pehrhovey 0:a548a085de55 545 if (len > 0)
pehrhovey 0:a548a085de55 546 {
pehrhovey 0:a548a085de55 547 /* remaining oid bytes available ... */
pehrhovey 0:a548a085de55 548 ofs += 1;
pehrhovey 0:a548a085de55 549 if (ofs >= plen)
pehrhovey 0:a548a085de55 550 {
pehrhovey 0:a548a085de55 551 /* next octet in next pbuf */
pehrhovey 0:a548a085de55 552 p = p->next;
pehrhovey 0:a548a085de55 553 if (p == NULL) { return ERR_ARG; }
pehrhovey 0:a548a085de55 554 msg_ptr = p->payload;
pehrhovey 0:a548a085de55 555 plen += p->len;
pehrhovey 0:a548a085de55 556 }
pehrhovey 0:a548a085de55 557 else
pehrhovey 0:a548a085de55 558 {
pehrhovey 0:a548a085de55 559 /* next octet in same pbuf */
pehrhovey 0:a548a085de55 560 msg_ptr++;
pehrhovey 0:a548a085de55 561 }
pehrhovey 0:a548a085de55 562 }
pehrhovey 0:a548a085de55 563 oid_ptr++;
pehrhovey 0:a548a085de55 564 oid->len++;
pehrhovey 0:a548a085de55 565 }
pehrhovey 0:a548a085de55 566 if (len == 0)
pehrhovey 0:a548a085de55 567 {
pehrhovey 0:a548a085de55 568 /* len == 0, end of oid */
pehrhovey 0:a548a085de55 569 return ERR_OK;
pehrhovey 0:a548a085de55 570 }
pehrhovey 0:a548a085de55 571 else
pehrhovey 0:a548a085de55 572 {
pehrhovey 0:a548a085de55 573 /* len > 0, oid->len == LWIP_SNMP_OBJ_ID_LEN or malformed encoding */
pehrhovey 0:a548a085de55 574 return ERR_ARG;
pehrhovey 0:a548a085de55 575 }
pehrhovey 0:a548a085de55 576
pehrhovey 0:a548a085de55 577 }
pehrhovey 0:a548a085de55 578 p = p->next;
pehrhovey 0:a548a085de55 579 }
pehrhovey 0:a548a085de55 580 /* p == NULL, ofs >= plen */
pehrhovey 0:a548a085de55 581 return ERR_ARG;
pehrhovey 0:a548a085de55 582 }
pehrhovey 0:a548a085de55 583
pehrhovey 0:a548a085de55 584 /**
pehrhovey 0:a548a085de55 585 * Decodes (copies) raw data (ip-addresses, octet strings, opaque encoding)
pehrhovey 0:a548a085de55 586 * from incoming message into array.
pehrhovey 0:a548a085de55 587 *
pehrhovey 0:a548a085de55 588 * @param p points to a pbuf holding an ASN1 coded raw data
pehrhovey 0:a548a085de55 589 * @param ofs points to the offset within the pbuf chain of the ASN1 coded raw data
pehrhovey 0:a548a085de55 590 * @param len length of the coded raw data (zero is valid, e.g. empty string!)
pehrhovey 0:a548a085de55 591 * @param raw_len length of the raw return value
pehrhovey 0:a548a085de55 592 * @param raw return raw bytes
pehrhovey 0:a548a085de55 593 * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) decode
pehrhovey 0:a548a085de55 594 */
pehrhovey 0:a548a085de55 595 err_t
pehrhovey 0:a548a085de55 596 snmp_asn1_dec_raw(struct pbuf *p, u16_t ofs, u16_t len, u16_t raw_len, u8_t *raw)
pehrhovey 0:a548a085de55 597 {
pehrhovey 0:a548a085de55 598 u16_t plen, base;
pehrhovey 0:a548a085de55 599 u8_t *msg_ptr;
pehrhovey 0:a548a085de55 600
pehrhovey 0:a548a085de55 601 if (len > 0)
pehrhovey 0:a548a085de55 602 {
pehrhovey 0:a548a085de55 603 plen = 0;
pehrhovey 0:a548a085de55 604 while (p != NULL)
pehrhovey 0:a548a085de55 605 {
pehrhovey 0:a548a085de55 606 base = plen;
pehrhovey 0:a548a085de55 607 plen += p->len;
pehrhovey 0:a548a085de55 608 if (ofs < plen)
pehrhovey 0:a548a085de55 609 {
pehrhovey 0:a548a085de55 610 msg_ptr = p->payload;
pehrhovey 0:a548a085de55 611 msg_ptr += ofs - base;
pehrhovey 0:a548a085de55 612 if (raw_len >= len)
pehrhovey 0:a548a085de55 613 {
pehrhovey 0:a548a085de55 614 while (len > 1)
pehrhovey 0:a548a085de55 615 {
pehrhovey 0:a548a085de55 616 /* copy len - 1 octets */
pehrhovey 0:a548a085de55 617 len--;
pehrhovey 0:a548a085de55 618 *raw = *msg_ptr;
pehrhovey 0:a548a085de55 619 raw++;
pehrhovey 0:a548a085de55 620 ofs += 1;
pehrhovey 0:a548a085de55 621 if (ofs >= plen)
pehrhovey 0:a548a085de55 622 {
pehrhovey 0:a548a085de55 623 /* next octet in next pbuf */
pehrhovey 0:a548a085de55 624 p = p->next;
pehrhovey 0:a548a085de55 625 if (p == NULL) { return ERR_ARG; }
pehrhovey 0:a548a085de55 626 msg_ptr = p->payload;
pehrhovey 0:a548a085de55 627 plen += p->len;
pehrhovey 0:a548a085de55 628 }
pehrhovey 0:a548a085de55 629 else
pehrhovey 0:a548a085de55 630 {
pehrhovey 0:a548a085de55 631 /* next octet in same pbuf */
pehrhovey 0:a548a085de55 632 msg_ptr++;
pehrhovey 0:a548a085de55 633 }
pehrhovey 0:a548a085de55 634 }
pehrhovey 0:a548a085de55 635 /* copy last octet */
pehrhovey 0:a548a085de55 636 *raw = *msg_ptr;
pehrhovey 0:a548a085de55 637 return ERR_OK;
pehrhovey 0:a548a085de55 638 }
pehrhovey 0:a548a085de55 639 else
pehrhovey 0:a548a085de55 640 {
pehrhovey 0:a548a085de55 641 /* raw_len < len, not enough dst space */
pehrhovey 0:a548a085de55 642 return ERR_ARG;
pehrhovey 0:a548a085de55 643 }
pehrhovey 0:a548a085de55 644 }
pehrhovey 0:a548a085de55 645 p = p->next;
pehrhovey 0:a548a085de55 646 }
pehrhovey 0:a548a085de55 647 /* p == NULL, ofs >= plen */
pehrhovey 0:a548a085de55 648 return ERR_ARG;
pehrhovey 0:a548a085de55 649 }
pehrhovey 0:a548a085de55 650 else
pehrhovey 0:a548a085de55 651 {
pehrhovey 0:a548a085de55 652 /* len == 0, empty string */
pehrhovey 0:a548a085de55 653 return ERR_OK;
pehrhovey 0:a548a085de55 654 }
pehrhovey 0:a548a085de55 655 }
pehrhovey 0:a548a085de55 656
pehrhovey 0:a548a085de55 657 #endif /* LWIP_SNMP */