Ethernet test for ECE 4180 and others to find your IP address and do a simple HTTP GET request over port 80.

Dependencies:   mbed Socket lwip-eth lwip-sys lwip

Committer:
mkersh3
Date:
Thu Apr 04 05:26:09 2013 +0000
Revision:
0:e7ca326e76ee
Ethernet Test for ECE4180 and others to find their IP Address and do a simple HTTP GET request over port 80.

Who changed what in which revision?

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