I have a problem getting this to work. Server only recieves half of the data being sent. Whats wrong

Dependencies:   mbed

Committer:
tax
Date:
Tue Mar 29 13:20:15 2011 +0000
Revision:
0:66300c77c6e9

        

Who changed what in which revision?

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