Ethernetwebsoc

Dependencies:   C12832_lcd LM75B WebSocketClient mbed-rtos mbed Socket lwip-eth lwip-sys lwip

Committer:
GordonSin
Date:
Fri May 31 04:09:54 2013 +0000
Revision:
0:0ed2a7c7190c
31/5/2013;

Who changed what in which revision?

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