ソースの整理中ですが、利用はできます。

Dependencies:   EthernetInterface HttpServer TextLCD mbed-rpc mbed-rtos mbed Socket lwip-eth lwip-sys lwip

Committer:
yueee_yt
Date:
Wed Mar 12 04:39:15 2014 +0000
Revision:
2:14b689a85306
Parent:
0:7766f6712673
bug fix

Who changed what in which revision?

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