V1

Dependents:   EthernetInterface

Fork of lwip by mbed official

Committer:
lemniskata
Date:
Thu Jun 13 20:00:31 2013 +0000
Revision:
11:c9233fe7de67
Parent:
0:51ac1d130fd4
V1

Who changed what in which revision?

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