ReactOS 0.4.15-dev-5669-g09dde2c
asn1_enc.c
Go to the documentation of this file.
1
8/*
9 * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands.
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without modification,
13 * are permitted provided that the following conditions are met:
14 *
15 * 1. Redistributions of source code must retain the above copyright notice,
16 * this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright notice,
18 * this list of conditions and the following disclaimer in the documentation
19 * and/or other materials provided with the distribution.
20 * 3. The name of the author may not be used to endorse or promote products
21 * derived from this software without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
24 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
26 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
28 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
31 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
32 * OF SUCH DAMAGE.
33 *
34 * Author: Christiaan Simons <christiaan.simons@axon.tv>
35 */
36
37#include "lwip/opt.h"
38
39#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */
40
41#include "lwip/snmp_asn1.h"
42
49void
50snmp_asn1_enc_length_cnt(u16_t length, u8_t *octets_needed)
51{
52 if (length < 0x80U)
53 {
54 *octets_needed = 1;
55 }
56 else if (length < 0x100U)
57 {
58 *octets_needed = 2;
59 }
60 else
61 {
62 *octets_needed = 3;
63 }
64}
65
76void
77snmp_asn1_enc_u32t_cnt(u32_t value, u16_t *octets_needed)
78{
79 if (value < 0x80UL)
80 {
81 *octets_needed = 1;
82 }
83 else if (value < 0x8000UL)
84 {
85 *octets_needed = 2;
86 }
87 else if (value < 0x800000UL)
88 {
89 *octets_needed = 3;
90 }
91 else if (value < 0x80000000UL)
92 {
93 *octets_needed = 4;
94 }
95 else
96 {
97 *octets_needed = 5;
98 }
99}
100
109void
110snmp_asn1_enc_s32t_cnt(s32_t value, u16_t *octets_needed)
111{
112 if (value < 0)
113 {
114 value = ~value;
115 }
116 if (value < 0x80L)
117 {
118 *octets_needed = 1;
119 }
120 else if (value < 0x8000L)
121 {
122 *octets_needed = 2;
123 }
124 else if (value < 0x800000L)
125 {
126 *octets_needed = 3;
127 }
128 else
129 {
130 *octets_needed = 4;
131 }
132}
133
141void
142snmp_asn1_enc_oid_cnt(u8_t ident_len, s32_t *ident, u16_t *octets_needed)
143{
144 s32_t sub_id;
145 u8_t cnt;
146
147 cnt = 0;
148 if (ident_len > 1)
149 {
150 /* compressed prefix in one octet */
151 cnt++;
152 ident_len -= 2;
153 ident += 2;
154 }
155 while(ident_len > 0)
156 {
157 ident_len--;
158 sub_id = *ident;
159
160 sub_id >>= 7;
161 cnt++;
162 while(sub_id > 0)
163 {
164 sub_id >>= 7;
165 cnt++;
166 }
167 ident++;
168 }
169 *octets_needed = cnt;
170}
171
180err_t
181snmp_asn1_enc_type(struct pbuf *p, u16_t ofs, u8_t type)
182{
183 u16_t plen, base;
184 u8_t *msg_ptr;
185
186 plen = 0;
187 while (p != NULL)
188 {
189 base = plen;
190 plen += p->len;
191 if (ofs < plen)
192 {
193 msg_ptr = (u8_t*)p->payload;
194 msg_ptr += ofs - base;
195 *msg_ptr = type;
196 return ERR_OK;
197 }
198 p = p->next;
199 }
200 /* p == NULL, ofs >= plen */
201 return ERR_ARG;
202}
203
212err_t
213snmp_asn1_enc_length(struct pbuf *p, u16_t ofs, u16_t length)
214{
215 u16_t plen, base;
216 u8_t *msg_ptr;
217
218 plen = 0;
219 while (p != NULL)
220 {
221 base = plen;
222 plen += p->len;
223 if (ofs < plen)
224 {
225 msg_ptr = (u8_t*)p->payload;
226 msg_ptr += ofs - base;
227
228 if (length < 0x80)
229 {
230 *msg_ptr = (u8_t)length;
231 return ERR_OK;
232 }
233 else if (length < 0x100)
234 {
235 *msg_ptr = 0x81;
236 ofs += 1;
237 if (ofs >= plen)
238 {
239 /* next octet in next pbuf */
240 p = p->next;
241 if (p == NULL) { return ERR_ARG; }
242 msg_ptr = (u8_t*)p->payload;
243 }
244 else
245 {
246 /* next octet in same pbuf */
247 msg_ptr++;
248 }
249 *msg_ptr = (u8_t)length;
250 return ERR_OK;
251 }
252 else
253 {
254 u8_t i;
255
256 /* length >= 0x100 && length <= 0xFFFF */
257 *msg_ptr = 0x82;
258 i = 2;
259 while (i > 0)
260 {
261 i--;
262 ofs += 1;
263 if (ofs >= plen)
264 {
265 /* next octet in next pbuf */
266 p = p->next;
267 if (p == NULL) { return ERR_ARG; }
268 msg_ptr = (u8_t*)p->payload;
269 plen += p->len;
270 }
271 else
272 {
273 /* next octet in same pbuf */
274 msg_ptr++;
275 }
276 if (i == 0)
277 {
278 /* least significant length octet */
279 *msg_ptr = (u8_t)length;
280 }
281 else
282 {
283 /* most significant length octet */
284 *msg_ptr = (u8_t)(length >> 8);
285 }
286 }
287 return ERR_OK;
288 }
289 }
290 p = p->next;
291 }
292 /* p == NULL, ofs >= plen */
293 return ERR_ARG;
294}
295
307err_t
308snmp_asn1_enc_u32t(struct pbuf *p, u16_t ofs, u16_t octets_needed, u32_t value)
309{
310 u16_t plen, base;
311 u8_t *msg_ptr;
312
313 plen = 0;
314 while (p != NULL)
315 {
316 base = plen;
317 plen += p->len;
318 if (ofs < plen)
319 {
320 msg_ptr = (u8_t*)p->payload;
321 msg_ptr += ofs - base;
322
323 if (octets_needed == 5)
324 {
325 /* not enough bits in 'value' add leading 0x00 */
326 octets_needed--;
327 *msg_ptr = 0x00;
328 ofs += 1;
329 if (ofs >= plen)
330 {
331 /* next octet in next pbuf */
332 p = p->next;
333 if (p == NULL) { return ERR_ARG; }
334 msg_ptr = (u8_t*)p->payload;
335 plen += p->len;
336 }
337 else
338 {
339 /* next octet in same pbuf */
340 msg_ptr++;
341 }
342 }
343 while (octets_needed > 1)
344 {
345 octets_needed--;
346 *msg_ptr = (u8_t)(value >> (octets_needed << 3));
347 ofs += 1;
348 if (ofs >= plen)
349 {
350 /* next octet in next pbuf */
351 p = p->next;
352 if (p == NULL) { return ERR_ARG; }
353 msg_ptr = (u8_t*)p->payload;
354 plen += p->len;
355 }
356 else
357 {
358 /* next octet in same pbuf */
359 msg_ptr++;
360 }
361 }
362 /* (only) one least significant octet */
363 *msg_ptr = (u8_t)value;
364 return ERR_OK;
365 }
366 p = p->next;
367 }
368 /* p == NULL, ofs >= plen */
369 return ERR_ARG;
370}
371
383err_t
384snmp_asn1_enc_s32t(struct pbuf *p, u16_t ofs, u16_t octets_needed, s32_t value)
385{
386 u16_t plen, base;
387 u8_t *msg_ptr;
388
389 plen = 0;
390 while (p != NULL)
391 {
392 base = plen;
393 plen += p->len;
394 if (ofs < plen)
395 {
396 msg_ptr = (u8_t*)p->payload;
397 msg_ptr += ofs - base;
398
399 while (octets_needed > 1)
400 {
401 octets_needed--;
402 *msg_ptr = (u8_t)(value >> (octets_needed << 3));
403 ofs += 1;
404 if (ofs >= plen)
405 {
406 /* next octet in next pbuf */
407 p = p->next;
408 if (p == NULL) { return ERR_ARG; }
409 msg_ptr = (u8_t*)p->payload;
410 plen += p->len;
411 }
412 else
413 {
414 /* next octet in same pbuf */
415 msg_ptr++;
416 }
417 }
418 /* (only) one least significant octet */
419 *msg_ptr = (u8_t)value;
420 return ERR_OK;
421 }
422 p = p->next;
423 }
424 /* p == NULL, ofs >= plen */
425 return ERR_ARG;
426}
427
437err_t
438snmp_asn1_enc_oid(struct pbuf *p, u16_t ofs, u8_t ident_len, s32_t *ident)
439{
440 u16_t plen, base;
441 u8_t *msg_ptr;
442
443 plen = 0;
444 while (p != NULL)
445 {
446 base = plen;
447 plen += p->len;
448 if (ofs < plen)
449 {
450 msg_ptr = (u8_t*)p->payload;
451 msg_ptr += ofs - base;
452
453 if (ident_len > 1)
454 {
455 if ((ident[0] == 1) && (ident[1] == 3))
456 {
457 /* compressed (most common) prefix .iso.org */
458 *msg_ptr = 0x2b;
459 }
460 else
461 {
462 /* calculate prefix */
463 *msg_ptr = (u8_t)((ident[0] * 40) + ident[1]);
464 }
465 ofs += 1;
466 if (ofs >= plen)
467 {
468 /* next octet in next pbuf */
469 p = p->next;
470 if (p == NULL) { return ERR_ARG; }
471 msg_ptr = (u8_t*)p->payload;
472 plen += p->len;
473 }
474 else
475 {
476 /* next octet in same pbuf */
477 msg_ptr++;
478 }
479 ident_len -= 2;
480 ident += 2;
481 }
482 else
483 {
484/* @bug: allow empty varbinds for symmetry (we must decode them for getnext), allow partial compression?? */
485 /* ident_len <= 1, at least we need zeroDotZero (0.0) (ident_len == 2) */
486 return ERR_ARG;
487 }
488 while (ident_len > 0)
489 {
490 s32_t sub_id;
491 u8_t shift, tail;
492
493 ident_len--;
494 sub_id = *ident;
495 tail = 0;
496 shift = 28;
497 while(shift > 0)
498 {
499 u8_t code;
500
501 code = (u8_t)(sub_id >> shift);
502 if ((code != 0) || (tail != 0))
503 {
504 tail = 1;
505 *msg_ptr = code | 0x80;
506 ofs += 1;
507 if (ofs >= plen)
508 {
509 /* next octet in next pbuf */
510 p = p->next;
511 if (p == NULL) { return ERR_ARG; }
512 msg_ptr = (u8_t*)p->payload;
513 plen += p->len;
514 }
515 else
516 {
517 /* next octet in same pbuf */
518 msg_ptr++;
519 }
520 }
521 shift -= 7;
522 }
523 *msg_ptr = (u8_t)sub_id & 0x7F;
524 if (ident_len > 0)
525 {
526 ofs += 1;
527 if (ofs >= plen)
528 {
529 /* next octet in next pbuf */
530 p = p->next;
531 if (p == NULL) { return ERR_ARG; }
532 msg_ptr = (u8_t*)p->payload;
533 plen += p->len;
534 }
535 else
536 {
537 /* next octet in same pbuf */
538 msg_ptr++;
539 }
540 }
541 /* proceed to next sub-identifier */
542 ident++;
543 }
544 return ERR_OK;
545 }
546 p = p->next;
547 }
548 /* p == NULL, ofs >= plen */
549 return ERR_ARG;
550}
551
561err_t
562snmp_asn1_enc_raw(struct pbuf *p, u16_t ofs, u16_t raw_len, u8_t *raw)
563{
564 u16_t plen, base;
565 u8_t *msg_ptr;
566
567 plen = 0;
568 while (p != NULL)
569 {
570 base = plen;
571 plen += p->len;
572 if (ofs < plen)
573 {
574 msg_ptr = (u8_t*)p->payload;
575 msg_ptr += ofs - base;
576
577 while (raw_len > 1)
578 {
579 /* copy raw_len - 1 octets */
580 raw_len--;
581 *msg_ptr = *raw;
582 raw++;
583 ofs += 1;
584 if (ofs >= plen)
585 {
586 /* next octet in next pbuf */
587 p = p->next;
588 if (p == NULL) { return ERR_ARG; }
589 msg_ptr = (u8_t*)p->payload;
590 plen += p->len;
591 }
592 else
593 {
594 /* next octet in same pbuf */
595 msg_ptr++;
596 }
597 }
598 if (raw_len > 0)
599 {
600 /* copy last or single octet */
601 *msg_ptr = *raw;
602 }
603 return ERR_OK;
604 }
605 p = p->next;
606 }
607 /* p == NULL, ofs >= plen */
608 return ERR_ARG;
609}
610
611#endif /* LWIP_SNMP */
struct outqueuenode * tail
Definition: adnsresfilter.c:66
while(CdLookupNextInitialFileDirent(IrpContext, Fcb, FileContext))
#define NULL
Definition: types.h:112
signed long s32_t
Definition: cc.h:30
unsigned long u32_t
Definition: cc.h:25
unsigned char u8_t
Definition: cc.h:23
unsigned short u16_t
Definition: cc.h:24
#define ERR_ARG
Definition: err.h:70
#define ERR_OK
Definition: err.h:52
s8_t err_t
Definition: err.h:47
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLfloat GLfloat p
Definition: glext.h:8902
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
if(dx< 0)
Definition: linetemp.h:194
#define shift
Definition: input.c:1755
static INT ident_len(LPCTSTR p)
Definition: set.c:259
Definition: inflate.c:139
struct define * next
Definition: compiler.c:65
Definition: pbuf.h:79
Definition: pdh_main.c:94
_In_ ULONG _In_ ULONG_PTR ident
Definition: winddi.h:3994