OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [freertos-6.1.1/] [Demo/] [Common/] [ethernet/] [lwIP/] [core/] [snmp/] [msg_out.c] - Blame information for rev 606

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 606 jeremybenn
/**
2
 * @file
3
 * SNMP output message processing (RFC1157).
4
 *
5
 * Output responses and traps are build in two passes:
6
 *
7
 * Pass 0: iterate over the output message backwards to determine encoding lengths
8
 * Pass 1: the actual forward encoding of internal form into ASN1
9
 *
10
 * The single-pass encoding method described by Comer & Stevens
11
 * requires extra buffer space and copying for reversal of the packet.
12
 * The buffer requirement can be prohibitively large for big payloads
13
 * (>= 484) therefore we use the two encoding passes.
14
 */
15
 
16
/*
17
 * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands.
18
 * All rights reserved.
19
 *
20
 * Redistribution and use in source and binary forms, with or without modification,
21
 * are permitted provided that the following conditions are met:
22
 *
23
 * 1. Redistributions of source code must retain the above copyright notice,
24
 *    this list of conditions and the following disclaimer.
25
 * 2. Redistributions in binary form must reproduce the above copyright notice,
26
 *    this list of conditions and the following disclaimer in the documentation
27
 *    and/or other materials provided with the distribution.
28
 * 3. The name of the author may not be used to endorse or promote products
29
 *    derived from this software without specific prior written permission.
30
 *
31
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
32
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
33
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
34
 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
35
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
36
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
37
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
38
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
39
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
40
 * OF SUCH DAMAGE.
41
 *
42
 * Author: Christiaan Simons <christiaan.simons@axon.tv>
43
 */
44
 
45
#include "lwip/opt.h"
46
 
47
#if LWIP_SNMP
48
#include "arch/cc.h"
49
#include "lwip/udp.h"
50
#include "lwip/netif.h"
51
 
52
#include "lwip/snmp.h"
53
#include "lwip/snmp_asn1.h"
54
#include "lwip/snmp_msg.h"
55
 
56
struct snmp_trap_dst
57
{
58
  /* destination IP address in network order */
59
  struct ip_addr dip;
60
  /* set to 0 when disabled, >0 when enabled */
61
  u8_t enable;
62
};
63
#if (SNMP_TRAP_DESTINATIONS == 0)
64
#error "need at least one trap destination"
65
#endif
66
struct snmp_trap_dst trap_dst[SNMP_TRAP_DESTINATIONS];
67
 
68
/** TRAP message structure */
69
struct snmp_msg_trap trap_msg;
70
 
71
static u16_t snmp_resp_header_sum(struct snmp_msg_pstat *m_stat, u16_t vb_len);
72
static u16_t snmp_trap_header_sum(struct snmp_msg_trap *m_trap, u16_t vb_len);
73
static u16_t snmp_varbind_list_sum(struct snmp_varbind_root *root);
74
 
75
static u16_t snmp_resp_header_enc(struct snmp_msg_pstat *m_stat, struct pbuf *p);
76
static u16_t snmp_trap_header_enc(struct snmp_msg_trap *m_trap, struct pbuf *p);
77
static u16_t snmp_varbind_list_enc(struct snmp_varbind_root *root, struct pbuf *p, u16_t ofs);
78
 
79
/**
80
 * Sets enable switch for this trap destination.
81
 * @param dst_idx index in 0 .. SNMP_TRAP_DESTINATIONS-1
82
 * @param enable switch if 0 destination is disabled >0 enabled.
83
 */
84
void
85
snmp_trap_dst_enable(u8_t dst_idx, u8_t enable)
86
{
87
  if (dst_idx < SNMP_TRAP_DESTINATIONS)
88
  {
89
    trap_dst[dst_idx].enable = enable;
90
  }
91
}
92
 
93
/**
94
 * Sets IPv4 address for this trap destination.
95
 * @param dst_idx index in 0 .. SNMP_TRAP_DESTINATIONS-1
96
 * @param dst IPv4 address in host order.
97
 */
98
void
99
snmp_trap_dst_ip_set(u8_t dst_idx, struct ip_addr *dst)
100
{
101
  if (dst_idx < SNMP_TRAP_DESTINATIONS)
102
  {
103
    trap_dst[dst_idx].dip.addr = htonl(dst->addr);
104
  }
105
}
106
 
107
/**
108
 * Sends a 'getresponse' message to the request originator.
109
 *
110
 * @param m_stat points to the current message request state source
111
 * @return ERR_OK when success, ERR_MEM if we're out of memory
112
 *
113
 * @note the caller is responsible for filling in outvb in the m_stat
114
 * and provide error-status and index (except for tooBig errors) ...
115
 */
116
err_t
117
snmp_send_response(struct snmp_msg_pstat *m_stat)
118
{
119
  struct snmp_varbind_root emptyvb = {NULL, NULL, 0, 0, 0};
120
  struct pbuf *p;
121
  u16_t tot_len;
122
  err_t err;
123
 
124
  /* pass 0, calculate length fields */
125
  tot_len = snmp_varbind_list_sum(&m_stat->outvb);
126
  tot_len = snmp_resp_header_sum(m_stat, tot_len);
127
 
128
  /* try allocating pbuf(s) for complete response */
129
  p = pbuf_alloc(PBUF_TRANSPORT, tot_len, PBUF_POOL);
130
  if (p == NULL)
131
  {
132
    LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_snd_response() tooBig\n"));
133
 
134
    /* can't construct reply, return error-status tooBig */
135
    m_stat->error_status = SNMP_ES_TOOBIG;
136
    m_stat->error_index = 0;
137
    /* pass 0, recalculate lengths, for empty varbind-list */
138
    tot_len = snmp_varbind_list_sum(&emptyvb);
139
    tot_len = snmp_resp_header_sum(m_stat, tot_len);
140
    /* retry allocation once for header and empty varbind-list */
141
    p = pbuf_alloc(PBUF_TRANSPORT, tot_len, PBUF_POOL);
142
  }
143
  if (p != NULL)
144
  {
145
    /* first pbuf alloc try or retry alloc success */
146
    u16_t ofs;
147
 
148
    LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_snd_response() p != NULL\n"));
149
 
150
    /* pass 1, size error, encode packet ino the pbuf(s) */
151
    ofs = snmp_resp_header_enc(m_stat, p);
152
    if (m_stat->error_status == SNMP_ES_TOOBIG)
153
    {
154
      snmp_varbind_list_enc(&emptyvb, p, ofs);
155
    }
156
    else
157
    {
158
      snmp_varbind_list_enc(&m_stat->outvb, p, ofs);
159
    }
160
 
161
    switch (m_stat->error_status)
162
    {
163
      case SNMP_ES_TOOBIG:
164
        snmp_inc_snmpouttoobigs();
165
        break;
166
      case SNMP_ES_NOSUCHNAME:
167
        snmp_inc_snmpoutnosuchnames();
168
        break;
169
      case SNMP_ES_BADVALUE:
170
        snmp_inc_snmpoutbadvalues();
171
        break;
172
      case SNMP_ES_GENERROR:
173
        snmp_inc_snmpoutgenerrs();
174
        break;
175
    }
176
    snmp_inc_snmpoutgetresponses();
177
    snmp_inc_snmpoutpkts();
178
 
179
    /** @todo do we need separate rx and tx pcbs for threaded case? */
180
    /** connect to the originating source */
181
    udp_connect(m_stat->pcb, &m_stat->sip, m_stat->sp);
182
    err = udp_send(m_stat->pcb, p);
183
    if (err == ERR_MEM)
184
    {
185
      /** @todo release some memory, retry and return tooBig? tooMuchHassle? */
186
      err = ERR_MEM;
187
    }
188
    else
189
    {
190
      err = ERR_OK;
191
    }
192
    /** disassociate remote address and port with this pcb */
193
    udp_disconnect(m_stat->pcb);
194
 
195
    pbuf_free(p);
196
    LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_snd_response() done\n"));
197
    return err;
198
  }
199
  else
200
  {
201
    /* first pbuf alloc try or retry alloc failed
202
       very low on memory, couldn't return tooBig */
203
    return ERR_MEM;
204
  }
205
}
206
 
207
 
208
/**
209
 * Sends an generic or enterprise specific trap message.
210
 *
211
 * @param generic_trap is the trap code
212
 * @param eoid points to enterprise object identifier
213
 * @param specific_trap used for enterprise traps when generic_trap == 6
214
 * @return ERR_OK when success, ERR_MEM if we're out of memory
215
 *
216
 * @note the caller is responsible for filling in outvb in the trap_msg
217
 * @note the use of the enterpise identifier field
218
 * is per RFC1215.
219
 * Use .iso.org.dod.internet.mgmt.mib-2.snmp for generic traps
220
 * and .iso.org.dod.internet.private.enterprises.yourenterprise
221
 * (sysObjectID) for specific traps.
222
 */
223
err_t
224
snmp_send_trap(s8_t generic_trap, struct snmp_obj_id *eoid, s32_t specific_trap)
225
{
226
  struct snmp_trap_dst *td;
227
  struct netif *dst_if;
228
  struct ip_addr dst_ip;
229
  struct pbuf *p;
230
  u16_t i,tot_len;
231
 
232
  for (i=0, td = &trap_dst[0]; i<SNMP_TRAP_DESTINATIONS; i++, td++)
233
  {
234
    if ((td->enable != 0) && (td->dip.addr != 0))
235
    {
236
      /* network order trap destination */
237
      trap_msg.dip.addr = td->dip.addr;
238
      /* lookup current source address for this dst */
239
      dst_if = ip_route(&td->dip);
240
      dst_ip.addr = ntohl(dst_if->ip_addr.addr);
241
      trap_msg.sip_raw[0] = dst_ip.addr >> 24;
242
      trap_msg.sip_raw[1] = dst_ip.addr >> 16;
243
      trap_msg.sip_raw[2] = dst_ip.addr >> 8;
244
      trap_msg.sip_raw[3] = dst_ip.addr;
245
      trap_msg.gen_trap = generic_trap;
246
      trap_msg.spc_trap = specific_trap;
247
      if (generic_trap == SNMP_GENTRAP_ENTERPRISESPC)
248
      {
249
        /* enterprise-Specific trap */
250
        trap_msg.enterprise = eoid;
251
      }
252
      else
253
      {
254
        /* generic (MIB-II) trap */
255
        snmp_get_snmpgrpid_ptr(&trap_msg.enterprise);
256
      }
257
      snmp_get_sysuptime(&trap_msg.ts);
258
 
259
      /* pass 0, calculate length fields */
260
      tot_len = snmp_varbind_list_sum(&trap_msg.outvb);
261
      tot_len = snmp_trap_header_sum(&trap_msg, tot_len);
262
 
263
      /* allocate pbuf(s) */
264
      p = pbuf_alloc(PBUF_TRANSPORT, tot_len, PBUF_POOL);
265
      if (p != NULL)
266
      {
267
        u16_t ofs;
268
 
269
        /* pass 1, encode packet ino the pbuf(s) */
270
        ofs = snmp_trap_header_enc(&trap_msg, p);
271
        snmp_varbind_list_enc(&trap_msg.outvb, p, ofs);
272
 
273
        snmp_inc_snmpouttraps();
274
        snmp_inc_snmpoutpkts();
275
 
276
        /** connect to the TRAP destination */
277
        udp_connect(trap_msg.pcb, &trap_msg.dip, SNMP_TRAP_PORT);
278
        udp_send(trap_msg.pcb, p);
279
        /** disassociate remote address and port with this pcb */
280
        udp_disconnect(trap_msg.pcb);
281
 
282
        pbuf_free(p);
283
      }
284
      else
285
      {
286
        return ERR_MEM;
287
      }
288
    }
289
  }
290
  return ERR_OK;
291
}
292
 
293
void
294
snmp_coldstart_trap(void)
295
{
296
  trap_msg.outvb.head = NULL;
297
  trap_msg.outvb.tail = NULL;
298
  trap_msg.outvb.count = 0;
299
  snmp_send_trap(SNMP_GENTRAP_COLDSTART, NULL, 0);
300
}
301
 
302
void
303
snmp_authfail_trap(void)
304
{
305
  u8_t enable;
306
  snmp_get_snmpenableauthentraps(&enable);
307
  if (enable == 1)
308
  {
309
    trap_msg.outvb.head = NULL;
310
    trap_msg.outvb.tail = NULL;
311
    trap_msg.outvb.count = 0;
312
    snmp_send_trap(SNMP_GENTRAP_AUTHFAIL, NULL, 0);
313
  }
314
}
315
 
316
/**
317
 * Sums response header field lengths from tail to head and
318
 * returns resp_header_lengths for second encoding pass.
319
 *
320
 * @param vb_len varbind-list length
321
 * @param rhl points to returned header lengths
322
 * @return the required lenght for encoding the response header
323
 */
324
static u16_t
325
snmp_resp_header_sum(struct snmp_msg_pstat *m_stat, u16_t vb_len)
326
{
327
  u16_t tot_len;
328
  struct snmp_resp_header_lengths *rhl;
329
 
330
  rhl = &m_stat->rhl;
331
  tot_len = vb_len;
332
  snmp_asn1_enc_s32t_cnt(m_stat->error_index, &rhl->erridxlen);
333
  snmp_asn1_enc_length_cnt(rhl->erridxlen, &rhl->erridxlenlen);
334
  tot_len += 1 + rhl->erridxlenlen + rhl->erridxlen;
335
 
336
  snmp_asn1_enc_s32t_cnt(m_stat->error_status, &rhl->errstatlen);
337
  snmp_asn1_enc_length_cnt(rhl->errstatlen, &rhl->errstatlenlen);
338
  tot_len += 1 + rhl->errstatlenlen + rhl->errstatlen;
339
 
340
  snmp_asn1_enc_s32t_cnt(m_stat->rid, &rhl->ridlen);
341
  snmp_asn1_enc_length_cnt(rhl->ridlen, &rhl->ridlenlen);
342
  tot_len += 1 + rhl->ridlenlen + rhl->ridlen;
343
 
344
  rhl->pdulen = tot_len;
345
  snmp_asn1_enc_length_cnt(rhl->pdulen, &rhl->pdulenlen);
346
  tot_len += 1 + rhl->pdulenlen;
347
 
348
  rhl->comlen = m_stat->com_strlen;
349
  snmp_asn1_enc_length_cnt(rhl->comlen, &rhl->comlenlen);
350
  tot_len += 1 + rhl->comlenlen + rhl->comlen;
351
 
352
  snmp_asn1_enc_s32t_cnt(snmp_version, &rhl->verlen);
353
  snmp_asn1_enc_length_cnt(rhl->verlen, &rhl->verlenlen);
354
  tot_len += 1 + rhl->verlen + rhl->verlenlen;
355
 
356
  rhl->seqlen = tot_len;
357
  snmp_asn1_enc_length_cnt(rhl->seqlen, &rhl->seqlenlen);
358
  tot_len += 1 + rhl->seqlenlen;
359
 
360
  return tot_len;
361
}
362
 
363
/**
364
 * Sums trap header field lengths from tail to head and
365
 * returns trap_header_lengths for second encoding pass.
366
 *
367
 * @param vb_len varbind-list length
368
 * @param thl points to returned header lengths
369
 * @return the required lenght for encoding the trap header
370
 */
371
static u16_t
372
snmp_trap_header_sum(struct snmp_msg_trap *m_trap, u16_t vb_len)
373
{
374
  u16_t tot_len;
375
  struct snmp_trap_header_lengths *thl;
376
 
377
  thl = &m_trap->thl;
378
  tot_len = vb_len;
379
 
380
  snmp_asn1_enc_u32t_cnt(m_trap->ts, &thl->tslen);
381
  snmp_asn1_enc_length_cnt(thl->tslen, &thl->tslenlen);
382
  tot_len += 1 + thl->tslen + thl->tslenlen;
383
 
384
  snmp_asn1_enc_s32t_cnt(m_trap->spc_trap, &thl->strplen);
385
  snmp_asn1_enc_length_cnt(thl->strplen, &thl->strplenlen);
386
  tot_len += 1 + thl->strplen + thl->strplenlen;
387
 
388
  snmp_asn1_enc_s32t_cnt(m_trap->gen_trap, &thl->gtrplen);
389
  snmp_asn1_enc_length_cnt(thl->gtrplen, &thl->gtrplenlen);
390
  tot_len += 1 + thl->gtrplen + thl->gtrplenlen;
391
 
392
  thl->aaddrlen = 4;
393
  snmp_asn1_enc_length_cnt(thl->aaddrlen, &thl->aaddrlenlen);
394
  tot_len += 1 + thl->aaddrlen + thl->aaddrlenlen;
395
 
396
  snmp_asn1_enc_oid_cnt(m_trap->enterprise->len, &m_trap->enterprise->id[0], &thl->eidlen);
397
  snmp_asn1_enc_length_cnt(thl->eidlen, &thl->eidlenlen);
398
  tot_len += 1 + thl->eidlen + thl->eidlenlen;
399
 
400
  thl->pdulen = tot_len;
401
  snmp_asn1_enc_length_cnt(thl->pdulen, &thl->pdulenlen);
402
  tot_len += 1 + thl->pdulenlen;
403
 
404
  thl->comlen = sizeof(snmp_publiccommunity) - 1;
405
  snmp_asn1_enc_length_cnt(thl->comlen, &thl->comlenlen);
406
  tot_len += 1 + thl->comlenlen + thl->comlen;
407
 
408
  snmp_asn1_enc_s32t_cnt(snmp_version, &thl->verlen);
409
  snmp_asn1_enc_length_cnt(thl->verlen, &thl->verlenlen);
410
  tot_len += 1 + thl->verlen + thl->verlenlen;
411
 
412
  thl->seqlen = tot_len;
413
  snmp_asn1_enc_length_cnt(thl->seqlen, &thl->seqlenlen);
414
  tot_len += 1 + thl->seqlenlen;
415
 
416
  return tot_len;
417
}
418
 
419
/**
420
 * Sums varbind lengths from tail to head and
421
 * annotates lengths in varbind for second encoding pass.
422
 *
423
 * @param root points to the root of the variable binding list
424
 * @return the required lenght for encoding the variable bindings
425
 */
426
static u16_t
427
snmp_varbind_list_sum(struct snmp_varbind_root *root)
428
{
429
  struct snmp_varbind *vb;
430
  u32_t *uint_ptr;
431
  s32_t *sint_ptr;
432
  u16_t tot_len;
433
 
434
  tot_len = 0;
435
  vb = root->tail;
436
  while ( vb != NULL )
437
  {
438
    /* encoded value lenght depends on type */
439
    switch (vb->value_type)
440
    {
441
      case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG):
442
        sint_ptr = vb->value;
443
        snmp_asn1_enc_s32t_cnt(*sint_ptr, &vb->vlen);
444
        break;
445
      case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER):
446
      case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_GAUGE):
447
      case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_TIMETICKS):
448
        uint_ptr = vb->value;
449
        snmp_asn1_enc_u32t_cnt(*uint_ptr, &vb->vlen);
450
        break;
451
      case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR):
452
      case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_NUL):
453
      case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR):
454
      case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_OPAQUE):
455
        vb->vlen = vb->value_len;
456
        break;
457
      case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID):
458
        sint_ptr = vb->value;
459
        snmp_asn1_enc_oid_cnt(vb->value_len / sizeof(s32_t), sint_ptr, &vb->vlen);
460
        break;
461
      default:
462
        /* unsupported type */
463
        vb->vlen = 0;
464
        break;
465
    };
466
    /* encoding length of value length field */
467
    snmp_asn1_enc_length_cnt(vb->vlen, &vb->vlenlen);
468
    snmp_asn1_enc_oid_cnt(vb->ident_len, vb->ident, &vb->olen);
469
    snmp_asn1_enc_length_cnt(vb->olen, &vb->olenlen);
470
 
471
    vb->seqlen = 1 + vb->vlenlen + vb->vlen;
472
    vb->seqlen += 1 + vb->olenlen + vb->olen;
473
    snmp_asn1_enc_length_cnt(vb->seqlen, &vb->seqlenlen);
474
 
475
    /* varbind seq */
476
    tot_len += 1 + vb->seqlenlen + vb->seqlen;
477
 
478
    vb = vb->prev;
479
  }
480
 
481
  /* varbind-list seq */
482
  root->seqlen = tot_len;
483
  snmp_asn1_enc_length_cnt(root->seqlen, &root->seqlenlen);
484
  tot_len += 1 + root->seqlenlen;
485
 
486
  return tot_len;
487
}
488
 
489
/**
490
 * Encodes response header from head to tail.
491
 */
492
static u16_t
493
snmp_resp_header_enc(struct snmp_msg_pstat *m_stat, struct pbuf *p)
494
{
495
  u16_t ofs;
496
 
497
  ofs = 0;
498
  snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ));
499
  ofs += 1;
500
  snmp_asn1_enc_length(p, ofs, m_stat->rhl.seqlen);
501
  ofs += m_stat->rhl.seqlenlen;
502
 
503
  snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG));
504
  ofs += 1;
505
  snmp_asn1_enc_length(p, ofs, m_stat->rhl.verlen);
506
  ofs += m_stat->rhl.verlenlen;
507
  snmp_asn1_enc_s32t(p, ofs, m_stat->rhl.verlen, snmp_version);
508
  ofs += m_stat->rhl.verlen;
509
 
510
  snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR));
511
  ofs += 1;
512
  snmp_asn1_enc_length(p, ofs, m_stat->rhl.comlen);
513
  ofs += m_stat->rhl.comlenlen;
514
  snmp_asn1_enc_raw(p, ofs, m_stat->rhl.comlen, m_stat->community);
515
  ofs += m_stat->rhl.comlen;
516
 
517
  snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_GET_RESP));
518
  ofs += 1;
519
  snmp_asn1_enc_length(p, ofs, m_stat->rhl.pdulen);
520
  ofs += m_stat->rhl.pdulenlen;
521
 
522
  snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG));
523
  ofs += 1;
524
  snmp_asn1_enc_length(p, ofs, m_stat->rhl.ridlen);
525
  ofs += m_stat->rhl.ridlenlen;
526
  snmp_asn1_enc_s32t(p, ofs, m_stat->rhl.ridlen, m_stat->rid);
527
  ofs += m_stat->rhl.ridlen;
528
 
529
  snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG));
530
  ofs += 1;
531
  snmp_asn1_enc_length(p, ofs, m_stat->rhl.errstatlen);
532
  ofs += m_stat->rhl.errstatlenlen;
533
  snmp_asn1_enc_s32t(p, ofs, m_stat->rhl.errstatlen, m_stat->error_status);
534
  ofs += m_stat->rhl.errstatlen;
535
 
536
  snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG));
537
  ofs += 1;
538
  snmp_asn1_enc_length(p, ofs, m_stat->rhl.erridxlen);
539
  ofs += m_stat->rhl.erridxlenlen;
540
  snmp_asn1_enc_s32t(p, ofs, m_stat->rhl.erridxlen, m_stat->error_index);
541
  ofs += m_stat->rhl.erridxlen;
542
 
543
  return ofs;
544
}
545
 
546
/**
547
 * Encodes trap header from head to tail.
548
 */
549
static u16_t
550
snmp_trap_header_enc(struct snmp_msg_trap *m_trap, struct pbuf *p)
551
{
552
  u16_t ofs;
553
 
554
  ofs = 0;
555
  snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ));
556
  ofs += 1;
557
  snmp_asn1_enc_length(p, ofs, m_trap->thl.seqlen);
558
  ofs += m_trap->thl.seqlenlen;
559
 
560
  snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG));
561
  ofs += 1;
562
  snmp_asn1_enc_length(p, ofs, m_trap->thl.verlen);
563
  ofs += m_trap->thl.verlenlen;
564
  snmp_asn1_enc_s32t(p, ofs, m_trap->thl.verlen, snmp_version);
565
  ofs += m_trap->thl.verlen;
566
 
567
  snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR));
568
  ofs += 1;
569
  snmp_asn1_enc_length(p, ofs, m_trap->thl.comlen);
570
  ofs += m_trap->thl.comlenlen;
571
  snmp_asn1_enc_raw(p, ofs, m_trap->thl.comlen, (u8_t *)&snmp_publiccommunity[0]);
572
  ofs += m_trap->thl.comlen;
573
 
574
  snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_TRAP));
575
  ofs += 1;
576
  snmp_asn1_enc_length(p, ofs, m_trap->thl.pdulen);
577
  ofs += m_trap->thl.pdulenlen;
578
 
579
  snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID));
580
  ofs += 1;
581
  snmp_asn1_enc_length(p, ofs, m_trap->thl.eidlen);
582
  ofs += m_trap->thl.eidlenlen;
583
  snmp_asn1_enc_oid(p, ofs, m_trap->enterprise->len, &m_trap->enterprise->id[0]);
584
  ofs += m_trap->thl.eidlen;
585
 
586
  snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR));
587
  ofs += 1;
588
  snmp_asn1_enc_length(p, ofs, m_trap->thl.aaddrlen);
589
  ofs += m_trap->thl.aaddrlenlen;
590
  snmp_asn1_enc_raw(p, ofs, m_trap->thl.aaddrlen, &m_trap->sip_raw[0]);
591
  ofs += m_trap->thl.aaddrlen;
592
 
593
  snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG));
594
  ofs += 1;
595
  snmp_asn1_enc_length(p, ofs, m_trap->thl.gtrplen);
596
  ofs += m_trap->thl.gtrplenlen;
597
  snmp_asn1_enc_u32t(p, ofs, m_trap->thl.gtrplen, m_trap->gen_trap);
598
  ofs += m_trap->thl.gtrplen;
599
 
600
  snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG));
601
  ofs += 1;
602
  snmp_asn1_enc_length(p, ofs, m_trap->thl.strplen);
603
  ofs += m_trap->thl.strplenlen;
604
  snmp_asn1_enc_u32t(p, ofs, m_trap->thl.strplen, m_trap->spc_trap);
605
  ofs += m_trap->thl.strplen;
606
 
607
  snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_TIMETICKS));
608
  ofs += 1;
609
  snmp_asn1_enc_length(p, ofs, m_trap->thl.tslen);
610
  ofs += m_trap->thl.tslenlen;
611
  snmp_asn1_enc_u32t(p, ofs, m_trap->thl.tslen, m_trap->ts);
612
  ofs += m_trap->thl.tslen;
613
 
614
  return ofs;
615
}
616
 
617
/**
618
 * Encodes varbind list from head to tail.
619
 */
620
static u16_t
621
snmp_varbind_list_enc(struct snmp_varbind_root *root, struct pbuf *p, u16_t ofs)
622
{
623
  struct snmp_varbind *vb;
624
  s32_t *sint_ptr;
625
  u32_t *uint_ptr;
626
  u8_t *raw_ptr;
627
 
628
  snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ));
629
  ofs += 1;
630
  snmp_asn1_enc_length(p, ofs, root->seqlen);
631
  ofs += root->seqlenlen;
632
 
633
  vb = root->head;
634
  while ( vb != NULL )
635
  {
636
    snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ));
637
    ofs += 1;
638
    snmp_asn1_enc_length(p, ofs, vb->seqlen);
639
    ofs += vb->seqlenlen;
640
 
641
    snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID));
642
    ofs += 1;
643
    snmp_asn1_enc_length(p, ofs, vb->olen);
644
    ofs += vb->olenlen;
645
    snmp_asn1_enc_oid(p, ofs, vb->ident_len, &vb->ident[0]);
646
    ofs += vb->olen;
647
 
648
    snmp_asn1_enc_type(p, ofs, vb->value_type);
649
    ofs += 1;
650
    snmp_asn1_enc_length(p, ofs, vb->vlen);
651
    ofs += vb->vlenlen;
652
 
653
    switch (vb->value_type)
654
    {
655
      case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG):
656
        sint_ptr = vb->value;
657
        snmp_asn1_enc_s32t(p, ofs, vb->vlen, *sint_ptr);
658
        break;
659
      case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER):
660
      case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_GAUGE):
661
      case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_TIMETICKS):
662
        uint_ptr = vb->value;
663
        snmp_asn1_enc_u32t(p, ofs, vb->vlen, *uint_ptr);
664
        break;
665
      case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR):
666
      case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR):
667
      case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_OPAQUE):
668
        raw_ptr = vb->value;
669
        snmp_asn1_enc_raw(p, ofs, vb->vlen, raw_ptr);
670
        break;
671
      case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_NUL):
672
        break;
673
      case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID):
674
        sint_ptr = vb->value;
675
        snmp_asn1_enc_oid(p, ofs, vb->value_len / sizeof(s32_t), sint_ptr);
676
        break;
677
      default:
678
        /* unsupported type */
679
        break;
680
    };
681
    ofs += vb->vlen;
682
    vb = vb->next;
683
  }
684
  return ofs;
685
}
686
 
687
#endif /* LWIP_SNMP */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.