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