Coverage Report

Created: 2026-07-16 06:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/net-snmp/snmplib/snmp.c
Line
Count
Source
1
/*
2
 * Simple Network Management Protocol (RFC 1067).
3
 *
4
 */
5
/**********************************************************************
6
  Copyright 1988, 1989, 1991, 1992 by Carnegie Mellon University
7
8
                      All Rights Reserved
9
10
Permission to use, copy, modify, and distribute this software and its 
11
documentation for any purpose and without fee is hereby granted, 
12
provided that the above copyright notice appear in all copies and that
13
both that copyright notice and this permission notice appear in 
14
supporting documentation, and that the name of CMU not be
15
used in advertising or publicity pertaining to distribution of the
16
software without specific, written prior permission.  
17
18
CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
19
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
20
CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
21
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
22
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
23
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
24
SOFTWARE.
25
******************************************************************/
26
27
#include <net-snmp/net-snmp-config.h>
28
#include <ctype.h>
29
30
#ifdef KINETICS
31
#include "gw.h"
32
#include "ab.h"
33
#include "inet.h"
34
#include "fp4/cmdmacro.h"
35
#include "fp4/pbuf.h"
36
#include "glob.h"
37
#endif
38
39
#include <stdio.h>
40
#include <stdlib.h>
41
42
#include <sys/types.h>
43
#ifdef HAVE_STRING_H
44
#include <string.h>
45
#else
46
#include <strings.h>
47
#endif
48
#ifdef HAVE_NETINET_IN_H
49
#include <netinet/in.h>
50
#endif
51
#ifdef HAVE_SYS_SELECT_H
52
#include <sys/select.h>
53
#endif
54
#ifndef NULL
55
#define NULL 0
56
#endif
57
58
#ifdef vms
59
#include <in.h>
60
#endif
61
62
#include <net-snmp/types.h>
63
#include <net-snmp/output_api.h>
64
65
#include <net-snmp/library/asn1.h>
66
#include <net-snmp/library/snmp.h>      /* for "internal" definitions */
67
#include <net-snmp/library/snmp_api.h>
68
#include <net-snmp/library/snmp_impl.h>
69
#include <net-snmp/library/mib.h>
70
71
/** @mainpage Net-SNMP Coding Documentation
72
 * @section Introduction
73
  
74
   This is the Net-SNMP coding and API reference documentation.  It is
75
   incomplete, but when combined with the manual page set and
76
   tutorials forms a pretty comprehensive starting point.
77
78
   @section Starting_out Starting out
79
80
   The best places to start learning are the @e Net-SNMP @e tutorial
81
   (http://www.Net-SNMP.org/tutorial-5/) and the @e Modules and @e
82
   Examples sections of this document.
83
84
*/
85
86
void
87
xdump(const void * data, size_t length, const char *prefix)
88
0
{
89
0
    const u_char * const cp = data;
90
0
    unsigned int         col, count;
91
0
    char                *buffer, *p;
92
0
#ifndef NETSNMP_DISABLE_DYNAMIC_LOG_LEVEL
93
0
    int      debug_log_level = netsnmp_get_debug_log_level();
94
#else
95
#define debug_log_level LOG_DEBUG
96
#endif /* NETSNMP_DISABLE_DYNAMIC_LOG_LEVEL */
97
98
    /* If the length limit is increased, also increase buffer size. */
99
0
    if (length > 10000) {
100
0
        snmp_log(LOG_NOTICE,
101
0
                 "xdump: count = %" NETSNMP_PRIz "u > 10,000\n", length);
102
0
        return;
103
0
    }
104
105
0
    buffer = malloc(strlen(prefix) + 80);
106
0
    if (!buffer) {
107
0
        snmp_log(LOG_NOTICE,
108
0
                 "xdump: malloc failed. packet-dump skipped\n");
109
0
        return;
110
0
    }
111
112
0
    count = 0;
113
0
    while (count < length) {
114
0
        p = buffer + sprintf(buffer, "%s%.4d: ", prefix, count);
115
116
0
        for (col = 0; count + col < length && col < 16; col++) {
117
0
            p += sprintf(p, "%02X ", cp[count + col]);
118
0
            if (col % 4 == 3)
119
0
                p += sprintf(p, " ");
120
0
        }
121
0
        for (; col < 16; col++) {       /* pad end of buffer with zeros */
122
0
            p += sprintf(p, "   ");
123
0
            if (col % 4 == 3)
124
0
                p += sprintf(p, " ");
125
0
        }
126
0
        p += sprintf(p, "  ");
127
0
        for (col = 0; count + col < length && col < 16; col++) {
128
0
            unsigned char byte = cp[count + col];
129
130
0
            *p++ = isprint(byte) ? byte : '.';
131
0
        }
132
0
        *p++ = '\n';
133
0
        *p++ = 0;
134
0
        snmp_log(debug_log_level, "%s", buffer);
135
0
        count += col;
136
0
    }
137
0
    snmp_log(debug_log_level, "\n");
138
0
    free(buffer);
139
140
0
}                               /* end xdump() */
141
142
/*
143
 * u_char * snmp_parse_var_op(
144
 * u_char *data              IN - pointer to the start of object
145
 * oid *var_name             OUT - object id of variable 
146
 * int *var_name_len         IN/OUT - length of variable name 
147
 * u_char *var_val_type      OUT - type of variable (int or octet string) (one byte) 
148
 * int *var_val_len          OUT - length of variable 
149
 * u_char **var_val          OUT - pointer to ASN1 encoded value of variable 
150
 * int *listlength          IN/OUT - number of valid bytes left in var_op_list 
151
 */
152
153
u_char         *
154
snmp_parse_var_op(u_char * data,
155
                  oid * var_name,
156
                  size_t * var_name_len,
157
                  u_char * var_val_type,
158
                  size_t * var_val_len,
159
                  u_char ** var_val, size_t * listlength)
160
0
{
161
0
    u_char          var_op_type;
162
0
    size_t          var_op_len = *listlength;
163
0
    u_char         *var_op_start = data;
164
165
0
    data = asn_parse_sequence(data, &var_op_len, &var_op_type,
166
0
                              (ASN_SEQUENCE | ASN_CONSTRUCTOR), "var_op");
167
0
    if (data == NULL) {
168
        /*
169
         * msg detail is set 
170
         */
171
0
        return NULL;
172
0
    }
173
0
    DEBUGDUMPHEADER("recv", "Name");
174
0
    data =
175
0
        asn_parse_objid(data, &var_op_len, &var_op_type, var_name,
176
0
                        var_name_len);
177
0
    DEBUGINDENTLESS();
178
0
    if (data == NULL) {
179
0
        ERROR_MSG("No OID for variable");
180
0
        return NULL;
181
0
    }
182
0
    if (var_op_type !=
183
0
        (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OBJECT_ID))
184
0
        return NULL;
185
0
    *var_val = data;            /* save pointer to this object */
186
    /*
187
     * find out what type of object this is 
188
     */
189
0
    data = asn_parse_header(data, &var_op_len, var_val_type);
190
0
    if (data == NULL) {
191
0
        ERROR_MSG("No header for value");
192
0
        return NULL;
193
0
    }
194
    /*
195
     * XXX no check for type! 
196
     */
197
0
    *var_val_len = var_op_len;
198
0
    data += var_op_len;
199
0
    *listlength -= (int) (data - var_op_start);
200
0
    return data;
201
0
}
202
203
/**
204
 * ASN encode a varbind
205
 *
206
 * @param data[in]           pointer to the beginning of the output buffer
207
 * @param var_name[in]       object id of variable
208
 * @param var_name_len[in]   length of object id
209
 * @param var_val_type[in]   type of variable
210
 * @param var_val_len[in]    length of variable
211
 * @param var_val[in]        value of variable
212
 * @param listlength[in|out] number of valid bytes left in output buffer
213
 */
214
215
u_char         *
216
snmp_build_var_op(u_char * data,
217
                  const oid * var_name,
218
                  size_t * var_name_len,
219
                  u_char var_val_type,
220
                  size_t var_val_len,
221
                  const void * var_val, size_t * listlength)
222
0
{
223
0
    const size_t    headerLen = 4;
224
0
    size_t          sequenceLen;
225
0
    u_char   *const dataPtr = data;
226
227
0
    if (*listlength < headerLen)
228
0
        return NULL;
229
0
    data += headerLen;
230
0
    *listlength -= headerLen;
231
232
0
    DEBUGDUMPHEADER("send", "Name");
233
0
    data = asn_build_objid(data, listlength,
234
0
                           (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE |
235
0
                                     ASN_OBJECT_ID), var_name,
236
0
                           *var_name_len);
237
0
    DEBUGINDENTLESS();
238
0
    if (data == NULL) {
239
0
        ERROR_MSG("Can't build OID for variable");
240
0
        return NULL;
241
0
    }
242
0
    DEBUGDUMPHEADER("send", "Value");
243
0
    switch (var_val_type) {
244
0
    case ASN_INTEGER:
245
0
        data = asn_build_int(data, listlength, var_val_type,
246
0
                             var_val, var_val_len);
247
0
        break;
248
0
    case ASN_GAUGE:
249
0
    case ASN_COUNTER:
250
0
    case ASN_TIMETICKS:
251
0
    case ASN_UINTEGER:
252
0
        data = asn_build_unsigned_int(data, listlength, var_val_type,
253
0
                                      var_val, var_val_len);
254
0
        break;
255
0
#ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES
256
0
    case ASN_OPAQUE_COUNTER64:
257
0
    case ASN_OPAQUE_U64:
258
0
#endif
259
0
    case ASN_COUNTER64:
260
0
        data = asn_build_unsigned_int64(data, listlength, var_val_type,
261
0
                                        var_val, var_val_len);
262
0
        break;
263
0
    case ASN_OCTET_STR:
264
0
    case ASN_IPADDRESS:
265
0
    case ASN_OPAQUE:
266
0
    case ASN_NSAP:
267
0
        data = asn_build_string(data, listlength, var_val_type,
268
0
                                var_val, var_val_len);
269
0
        break;
270
0
    case ASN_OBJECT_ID:
271
0
        data = asn_build_objid(data, listlength, var_val_type,
272
0
                               var_val, var_val_len / sizeof(oid));
273
0
        break;
274
0
    case ASN_NULL:
275
0
        data = asn_build_null(data, listlength, var_val_type);
276
0
        break;
277
0
    case ASN_BIT_STR:
278
0
        data = asn_build_bitstring(data, listlength, var_val_type,
279
0
                                   var_val, var_val_len);
280
0
        break;
281
0
    case SNMP_NOSUCHOBJECT:
282
0
    case SNMP_NOSUCHINSTANCE:
283
0
    case SNMP_ENDOFMIBVIEW:
284
0
        data = asn_build_null(data, listlength, var_val_type);
285
0
        break;
286
0
#ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES
287
0
    case ASN_OPAQUE_FLOAT:
288
0
        data = asn_build_float(data, listlength, var_val_type,
289
0
                               var_val, var_val_len);
290
0
        break;
291
0
    case ASN_OPAQUE_DOUBLE:
292
0
        data = asn_build_double(data, listlength, var_val_type,
293
0
                                var_val, var_val_len);
294
0
        break;
295
0
    case ASN_OPAQUE_I64:
296
0
        data = asn_build_signed_int64(data, listlength, var_val_type,
297
0
                                      var_val, var_val_len);
298
0
        break;
299
0
#endif                          /* NETSNMP_WITH_OPAQUE_SPECIAL_TYPES */
300
0
    default:
301
0
  {
302
0
  char error_buf[64];
303
0
  snprintf(error_buf, sizeof(error_buf),
304
0
    "wrong type in snmp_build_var_op: %d", var_val_type);
305
0
        ERROR_MSG(error_buf);
306
0
        data = NULL;
307
0
  }
308
0
    }
309
0
    DEBUGINDENTLESS();
310
0
    if (data == NULL) {
311
0
        return NULL;
312
0
    }
313
314
0
    sequenceLen = (data - dataPtr) - headerLen;
315
0
    asn_build_sequence(dataPtr, &sequenceLen, ASN_SEQUENCE | ASN_CONSTRUCTOR,
316
0
                       headerLen);
317
0
    return data;
318
0
}
319
320
#ifdef NETSNMP_USE_REVERSE_ASNENCODING
321
int
322
snmp_realloc_rbuild_var_op(u_char ** pkt, size_t * pkt_len,
323
                           size_t * offset, int allow_realloc,
324
                           const oid * var_name, size_t * var_name_len,
325
                           u_char var_val_type,
326
                           u_char * var_val, size_t var_val_len)
327
0
{
328
0
    size_t          start_offset = *offset;
329
0
    int             rc = 0;
330
331
    /*
332
     * Encode the value.  
333
     */
334
0
    DEBUGDUMPHEADER("send", "Value");
335
336
0
    switch (var_val_type) {
337
0
    case ASN_INTEGER:
338
0
        rc = asn_realloc_rbuild_int(pkt, pkt_len, offset, allow_realloc,
339
0
                                    var_val_type, (long *) var_val,
340
0
                                    var_val_len);
341
0
        break;
342
343
0
    case ASN_GAUGE:
344
0
    case ASN_COUNTER:
345
0
    case ASN_TIMETICKS:
346
0
    case ASN_UINTEGER:
347
0
        rc = asn_realloc_rbuild_unsigned_int(pkt, pkt_len, offset,
348
0
                                             allow_realloc, var_val_type,
349
0
                                             (u_long *) var_val,
350
0
                                             var_val_len);
351
0
        break;
352
353
0
#ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES
354
0
    case ASN_OPAQUE_COUNTER64:
355
0
    case ASN_OPAQUE_U64:
356
0
#endif
357
0
    case ASN_COUNTER64:
358
0
        rc = asn_realloc_rbuild_unsigned_int64(pkt, pkt_len, offset,
359
0
                                               allow_realloc, var_val_type,
360
0
                                               (struct counter64 *)
361
0
                                               var_val, var_val_len);
362
0
        break;
363
364
0
    case ASN_OCTET_STR:
365
0
    case ASN_IPADDRESS:
366
0
    case ASN_OPAQUE:
367
0
    case ASN_NSAP:
368
0
        rc = asn_realloc_rbuild_string(pkt, pkt_len, offset, allow_realloc,
369
0
                                       var_val_type, var_val, var_val_len);
370
0
        break;
371
372
0
    case ASN_OBJECT_ID:
373
0
        rc = asn_realloc_rbuild_objid(pkt, pkt_len, offset, allow_realloc,
374
0
                                      var_val_type, (oid *) var_val,
375
0
                                      var_val_len / sizeof(oid));
376
0
        break;
377
378
0
    case ASN_NULL:
379
0
        rc = asn_realloc_rbuild_null(pkt, pkt_len, offset, allow_realloc,
380
0
                                     var_val_type);
381
0
        break;
382
383
0
    case ASN_BIT_STR:
384
0
        rc = asn_realloc_rbuild_bitstring(pkt, pkt_len, offset,
385
0
                                          allow_realloc, var_val_type,
386
0
                                          var_val, var_val_len);
387
0
        break;
388
389
0
    case SNMP_NOSUCHOBJECT:
390
0
    case SNMP_NOSUCHINSTANCE:
391
0
    case SNMP_ENDOFMIBVIEW:
392
0
        rc = asn_realloc_rbuild_null(pkt, pkt_len, offset, allow_realloc,
393
0
                                     var_val_type);
394
0
        break;
395
396
0
#ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES
397
0
    case ASN_OPAQUE_FLOAT:
398
0
        rc = asn_realloc_rbuild_float(pkt, pkt_len, offset, allow_realloc,
399
0
                                      var_val_type, (float *) var_val,
400
0
                                      var_val_len);
401
0
        break;
402
403
0
    case ASN_OPAQUE_DOUBLE:
404
0
        rc = asn_realloc_rbuild_double(pkt, pkt_len, offset, allow_realloc,
405
0
                                       var_val_type, (double *) var_val,
406
0
                                       var_val_len);
407
0
        break;
408
409
0
    case ASN_OPAQUE_I64:
410
0
        rc = asn_realloc_rbuild_signed_int64(pkt, pkt_len, offset,
411
0
                                             allow_realloc, var_val_type,
412
0
                                             (struct counter64 *) var_val,
413
0
                                             var_val_len);
414
0
        break;
415
0
#endif                          /* NETSNMP_WITH_OPAQUE_SPECIAL_TYPES */
416
0
    default:
417
0
  {
418
0
  char error_buf[64];
419
0
  snprintf(error_buf, sizeof(error_buf),
420
0
    "wrong type in snmp_realloc_rbuild_var_op: %d", var_val_type);
421
0
        ERROR_MSG(error_buf);
422
0
        rc = 0;
423
0
  }
424
0
    }
425
0
    DEBUGINDENTLESS();
426
427
0
    if (rc == 0) {
428
0
        return 0;
429
0
    }
430
431
    /*
432
     * Build the OID.  
433
     */
434
435
0
    DEBUGDUMPHEADER("send", "Name");
436
0
    rc = asn_realloc_rbuild_objid(pkt, pkt_len, offset, allow_realloc,
437
0
                                  (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE |
438
0
                                            ASN_OBJECT_ID), var_name,
439
0
                                  *var_name_len);
440
0
    DEBUGINDENTLESS();
441
0
    if (rc == 0) {
442
0
        ERROR_MSG("Can't build OID for variable");
443
0
        return 0;
444
0
    }
445
446
    /*
447
     * Build the sequence header.  
448
     */
449
450
0
    rc = asn_realloc_rbuild_sequence(pkt, pkt_len, offset, allow_realloc,
451
0
                                     (u_char) (ASN_SEQUENCE |
452
0
                                               ASN_CONSTRUCTOR),
453
0
                                     *offset - start_offset);
454
0
    return rc;
455
0
}
456
457
#endif                          /* NETSNMP_USE_REVERSE_ASNENCODING */