Official mbed lwIP library (version 1.4.0)

Dependents:   LwIPNetworking NetServicesMin EthernetInterface EthernetInterface_RSF ... more

Legacy Networking Libraries

This is an mbed 2 networking library. For mbed OS 5, lwip has been integrated with built-in networking interfaces. The networking libraries have been revised to better support additional network stacks and thread safety here.

This library is based on the code of lwIP v1.4.0

Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
All rights reserved. 

Redistribution and use in source and binary forms, with or without modification, 
are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice,
   this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
   derived from this software without specific prior written permission. 

THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
OF SUCH DAMAGE.
Committer:
mbed_official
Date:
Mon Mar 14 16:15:36 2016 +0000
Revision:
20:08f08bfc3f3d
Parent:
0:51ac1d130fd4
Synchronized with git revision fec574a5ed6db26aca1b13992ff271bf527d4a0d

Full URL: https://github.com/mbedmicro/mbed/commit/fec574a5ed6db26aca1b13992ff271bf527d4a0d/

Increased allocated netbufs to handle DTLS handshakes

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 */