Coverage Report

Created: 2026-10-17 06:54

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
    size_t               bufsize = strlen(prefix) + 80;
93
0
#ifndef NETSNMP_DISABLE_DYNAMIC_LOG_LEVEL
94
0
    int      debug_log_level = netsnmp_get_debug_log_level();
95
#else
96
#define debug_log_level LOG_DEBUG
97
#endif /* NETSNMP_DISABLE_DYNAMIC_LOG_LEVEL */
98
99
    /* If the length limit is increased, also increase buffer size. */
100
0
    if (length > 10000) {
101
0
        snmp_log(LOG_NOTICE,
102
0
                 "xdump: count = %" NETSNMP_PRIz "u > 10,000\n", length);
103
0
        return;
104
0
    }
105
106
0
    buffer = malloc(bufsize);
107
0
    if (!buffer) {
108
0
        snmp_log(LOG_NOTICE,
109
0
                 "xdump: malloc failed. packet-dump skipped\n");
110
0
        return;
111
0
    }
112
113
0
    count = 0;
114
0
    while (count < length) {
115
0
        p = buffer + snprintf(buffer, bufsize, "%s%.4d: ", prefix, count);
116
117
0
        for (col = 0; count + col < length && col < 16; col++) {
118
0
            p += snprintf(p, bufsize - (p - buffer), "%02X ", cp[count + col]);
119
0
            if (col % 4 == 3)
120
0
                p += snprintf(p, bufsize - (p - buffer), " ");
121
0
        }
122
0
        for (; col < 16; col++) {       /* pad end of buffer with zeros */
123
0
            p += snprintf(p, bufsize - (p - buffer), "   ");
124
0
            if (col % 4 == 3)
125
0
                p += snprintf(p, bufsize - (p - buffer), " ");
126
0
        }
127
0
        p += snprintf(p, bufsize - (p - buffer), "  ");
128
0
        for (col = 0; count + col < length && col < 16; col++) {
129
0
            unsigned char byte = cp[count + col];
130
131
0
            *p++ = isprint(byte) ? byte : '.';
132
0
        }
133
0
        *p++ = '\n';
134
0
        *p++ = 0;
135
0
        snmp_log(debug_log_level, "%s", buffer);
136
0
        count += col;
137
0
    }
138
0
    snmp_log(debug_log_level, "\n");
139
0
    free(buffer);
140
141
0
}                               /* end xdump() */
142
143
/*
144
 * u_char * snmp_parse_var_op(
145
 * u_char *data              IN - pointer to the start of object
146
 * oid *var_name             OUT - object id of variable 
147
 * int *var_name_len         IN/OUT - length of variable name 
148
 * u_char *var_val_type      OUT - type of variable (int or octet string) (one byte) 
149
 * int *var_val_len          OUT - length of variable 
150
 * u_char **var_val          OUT - pointer to ASN1 encoded value of variable 
151
 * int *listlength          IN/OUT - number of valid bytes left in var_op_list 
152
 */
153
154
u_char         *
155
snmp_parse_var_op(u_char * data,
156
                  oid * var_name,
157
                  size_t * var_name_len,
158
                  u_char * var_val_type,
159
                  size_t * var_val_len,
160
                  u_char ** var_val, size_t * listlength)
161
38.3k
{
162
38.3k
    u_char          var_op_type;
163
38.3k
    size_t          var_op_len = *listlength;
164
38.3k
    u_char         *var_op_start = data;
165
166
38.3k
    data = asn_parse_sequence(data, &var_op_len, &var_op_type,
167
38.3k
                              (ASN_SEQUENCE | ASN_CONSTRUCTOR), "var_op");
168
38.3k
    if (data == NULL) {
169
        /*
170
         * msg detail is set 
171
         */
172
2.20k
        return NULL;
173
2.20k
    }
174
36.1k
    DEBUGDUMPHEADER("recv", "Name");
175
36.1k
    data =
176
36.1k
        asn_parse_objid(data, &var_op_len, &var_op_type, var_name,
177
36.1k
                        var_name_len);
178
36.1k
    DEBUGINDENTLESS();
179
36.1k
    if (data == NULL) {
180
438
        ERROR_MSG("No OID for variable");
181
438
        return NULL;
182
438
    }
183
35.6k
    if (var_op_type !=
184
35.6k
        (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OBJECT_ID))
185
0
        return NULL;
186
35.6k
    *var_val = data;            /* save pointer to this object */
187
    /*
188
     * find out what type of object this is 
189
     */
190
35.6k
    data = asn_parse_header(data, &var_op_len, var_val_type);
191
35.6k
    if (data == NULL) {
192
172
        ERROR_MSG("No header for value");
193
172
        return NULL;
194
172
    }
195
    /*
196
     * XXX no check for type! 
197
     */
198
35.5k
    *var_val_len = var_op_len;
199
35.5k
    data += var_op_len;
200
35.5k
    *listlength -= (int) (data - var_op_start);
201
35.5k
    return data;
202
35.6k
}
203
204
/**
205
 * ASN encode a varbind
206
 *
207
 * @param data[in]           pointer to the beginning of the output buffer
208
 * @param var_name[in]       object id of variable
209
 * @param var_name_len[in]   length of object id
210
 * @param var_val_type[in]   type of variable
211
 * @param var_val_len[in]    length of variable
212
 * @param var_val[in]        value of variable
213
 * @param listlength[in|out] number of valid bytes left in output buffer
214
 */
215
216
u_char         *
217
snmp_build_var_op(u_char * data,
218
                  const oid * var_name,
219
                  size_t * var_name_len,
220
                  u_char var_val_type,
221
                  size_t var_val_len,
222
                  const void * var_val, size_t * listlength)
223
1.84k
{
224
1.84k
    const size_t    headerLen = 4;
225
1.84k
    size_t          sequenceLen;
226
1.84k
    u_char   *const dataPtr = data;
227
228
1.84k
    if (*listlength < headerLen)
229
9
        return NULL;
230
1.83k
    data += headerLen;
231
1.83k
    *listlength -= headerLen;
232
233
1.83k
    DEBUGDUMPHEADER("send", "Name");
234
1.83k
    data = asn_build_objid(data, listlength,
235
1.83k
                           (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE |
236
1.83k
                                     ASN_OBJECT_ID), var_name,
237
1.83k
                           *var_name_len);
238
1.83k
    DEBUGINDENTLESS();
239
1.83k
    if (data == NULL) {
240
91
        ERROR_MSG("Can't build OID for variable");
241
91
        return NULL;
242
91
    }
243
1.74k
    DEBUGDUMPHEADER("send", "Value");
244
1.74k
    switch (var_val_type) {
245
181
    case ASN_INTEGER:
246
181
        data = asn_build_int(data, listlength, var_val_type,
247
181
                             var_val, var_val_len);
248
181
        break;
249
69
    case ASN_GAUGE:
250
135
    case ASN_COUNTER:
251
178
    case ASN_TIMETICKS:
252
279
    case ASN_UINTEGER:
253
279
        data = asn_build_unsigned_int(data, listlength, var_val_type,
254
279
                                      var_val, var_val_len);
255
279
        break;
256
0
#ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES
257
39
    case ASN_OPAQUE_COUNTER64:
258
142
    case ASN_OPAQUE_U64:
259
142
#endif
260
362
    case ASN_COUNTER64:
261
362
        data = asn_build_unsigned_int64(data, listlength, var_val_type,
262
362
                                        var_val, var_val_len);
263
362
        break;
264
83
    case ASN_OCTET_STR:
265
111
    case ASN_IPADDRESS:
266
177
    case ASN_OPAQUE:
267
205
    case ASN_NSAP:
268
205
        data = asn_build_string(data, listlength, var_val_type,
269
205
                                var_val, var_val_len);
270
205
        break;
271
251
    case ASN_OBJECT_ID:
272
251
        data = asn_build_objid(data, listlength, var_val_type,
273
251
                               var_val, var_val_len / sizeof(oid));
274
251
        break;
275
35
    case ASN_NULL:
276
35
        data = asn_build_null(data, listlength, var_val_type);
277
35
        break;
278
46
    case ASN_BIT_STR:
279
46
        data = asn_build_bitstring(data, listlength, var_val_type,
280
46
                                   var_val, var_val_len);
281
46
        break;
282
43
    case SNMP_NOSUCHOBJECT:
283
83
    case SNMP_NOSUCHINSTANCE:
284
117
    case SNMP_ENDOFMIBVIEW:
285
117
        data = asn_build_null(data, listlength, var_val_type);
286
117
        break;
287
0
#ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES
288
54
    case ASN_OPAQUE_FLOAT:
289
54
        data = asn_build_float(data, listlength, var_val_type,
290
54
                               var_val, var_val_len);
291
54
        break;
292
22
    case ASN_OPAQUE_DOUBLE:
293
22
        data = asn_build_double(data, listlength, var_val_type,
294
22
                                var_val, var_val_len);
295
22
        break;
296
189
    case ASN_OPAQUE_I64:
297
189
        data = asn_build_signed_int64(data, listlength, var_val_type,
298
189
                                      var_val, var_val_len);
299
189
        break;
300
0
#endif                          /* NETSNMP_WITH_OPAQUE_SPECIAL_TYPES */
301
7
    default:
302
7
  {
303
7
  char error_buf[64];
304
7
  snprintf(error_buf, sizeof(error_buf),
305
7
    "wrong type in snmp_build_var_op: %d", var_val_type);
306
7
        ERROR_MSG(error_buf);
307
7
        data = NULL;
308
7
  }
309
1.74k
    }
310
1.74k
    DEBUGINDENTLESS();
311
1.74k
    if (data == NULL) {
312
394
        return NULL;
313
394
    }
314
315
1.35k
    sequenceLen = (data - dataPtr) - headerLen;
316
1.35k
    asn_build_sequence(dataPtr, &sequenceLen, ASN_SEQUENCE | ASN_CONSTRUCTOR,
317
1.35k
                       headerLen);
318
1.35k
    return data;
319
1.74k
}
320
321
#ifdef NETSNMP_USE_REVERSE_ASNENCODING
322
int
323
snmp_realloc_rbuild_var_op(u_char ** pkt, size_t * pkt_len,
324
                           size_t * offset, int allow_realloc,
325
                           const oid * var_name, size_t * var_name_len,
326
                           u_char var_val_type,
327
                           u_char * var_val, size_t var_val_len)
328
1.57k
{
329
1.57k
    size_t          start_offset = *offset;
330
1.57k
    int             rc = 0;
331
332
    /*
333
     * Encode the value.  
334
     */
335
1.57k
    DEBUGDUMPHEADER("send", "Value");
336
337
1.57k
    switch (var_val_type) {
338
111
    case ASN_INTEGER:
339
111
        rc = asn_realloc_rbuild_int(pkt, pkt_len, offset, allow_realloc,
340
111
                                    var_val_type, (long *) var_val,
341
111
                                    var_val_len);
342
111
        break;
343
344
90
    case ASN_GAUGE:
345
205
    case ASN_COUNTER:
346
267
    case ASN_TIMETICKS:
347
330
    case ASN_UINTEGER:
348
330
        rc = asn_realloc_rbuild_unsigned_int(pkt, pkt_len, offset,
349
330
                                             allow_realloc, var_val_type,
350
330
                                             (u_long *) var_val,
351
330
                                             var_val_len);
352
330
        break;
353
354
0
#ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES
355
47
    case ASN_OPAQUE_COUNTER64:
356
108
    case ASN_OPAQUE_U64:
357
108
#endif
358
282
    case ASN_COUNTER64:
359
282
        rc = asn_realloc_rbuild_unsigned_int64(pkt, pkt_len, offset,
360
282
                                               allow_realloc, var_val_type,
361
282
                                               (struct counter64 *)
362
282
                                               var_val, var_val_len);
363
282
        break;
364
365
48
    case ASN_OCTET_STR:
366
76
    case ASN_IPADDRESS:
367
169
    case ASN_OPAQUE:
368
204
    case ASN_NSAP:
369
204
        rc = asn_realloc_rbuild_string(pkt, pkt_len, offset, allow_realloc,
370
204
                                       var_val_type, var_val, var_val_len);
371
204
        break;
372
373
104
    case ASN_OBJECT_ID:
374
104
        rc = asn_realloc_rbuild_objid(pkt, pkt_len, offset, allow_realloc,
375
104
                                      var_val_type, (oid *) var_val,
376
104
                                      var_val_len / sizeof(oid));
377
104
        break;
378
379
20
    case ASN_NULL:
380
20
        rc = asn_realloc_rbuild_null(pkt, pkt_len, offset, allow_realloc,
381
20
                                     var_val_type);
382
20
        break;
383
384
73
    case ASN_BIT_STR:
385
73
        rc = asn_realloc_rbuild_bitstring(pkt, pkt_len, offset,
386
73
                                          allow_realloc, var_val_type,
387
73
                                          var_val, var_val_len);
388
73
        break;
389
390
32
    case SNMP_NOSUCHOBJECT:
391
70
    case SNMP_NOSUCHINSTANCE:
392
110
    case SNMP_ENDOFMIBVIEW:
393
110
        rc = asn_realloc_rbuild_null(pkt, pkt_len, offset, allow_realloc,
394
110
                                     var_val_type);
395
110
        break;
396
397
0
#ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES
398
85
    case ASN_OPAQUE_FLOAT:
399
85
        rc = asn_realloc_rbuild_float(pkt, pkt_len, offset, allow_realloc,
400
85
                                      var_val_type, (float *) var_val,
401
85
                                      var_val_len);
402
85
        break;
403
404
43
    case ASN_OPAQUE_DOUBLE:
405
43
        rc = asn_realloc_rbuild_double(pkt, pkt_len, offset, allow_realloc,
406
43
                                       var_val_type, (double *) var_val,
407
43
                                       var_val_len);
408
43
        break;
409
410
208
    case ASN_OPAQUE_I64:
411
208
        rc = asn_realloc_rbuild_signed_int64(pkt, pkt_len, offset,
412
208
                                             allow_realloc, var_val_type,
413
208
                                             (struct counter64 *) var_val,
414
208
                                             var_val_len);
415
208
        break;
416
0
#endif                          /* NETSNMP_WITH_OPAQUE_SPECIAL_TYPES */
417
0
    default:
418
0
  {
419
0
  char error_buf[64];
420
0
  snprintf(error_buf, sizeof(error_buf),
421
0
    "wrong type in snmp_realloc_rbuild_var_op: %d", var_val_type);
422
0
        ERROR_MSG(error_buf);
423
0
        rc = 0;
424
0
  }
425
1.57k
    }
426
1.57k
    DEBUGINDENTLESS();
427
428
1.57k
    if (rc == 0) {
429
0
        return 0;
430
0
    }
431
432
    /*
433
     * Build the OID.  
434
     */
435
436
1.57k
    DEBUGDUMPHEADER("send", "Name");
437
1.57k
    rc = asn_realloc_rbuild_objid(pkt, pkt_len, offset, allow_realloc,
438
1.57k
                                  (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE |
439
1.57k
                                            ASN_OBJECT_ID), var_name,
440
1.57k
                                  *var_name_len);
441
1.57k
    DEBUGINDENTLESS();
442
1.57k
    if (rc == 0) {
443
0
        ERROR_MSG("Can't build OID for variable");
444
0
        return 0;
445
0
    }
446
447
    /*
448
     * Build the sequence header.  
449
     */
450
451
1.57k
    rc = asn_realloc_rbuild_sequence(pkt, pkt_len, offset, allow_realloc,
452
1.57k
                                     (u_char) (ASN_SEQUENCE |
453
1.57k
                                               ASN_CONSTRUCTOR),
454
1.57k
                                     *offset - start_offset);
455
1.57k
    return rc;
456
1.57k
}
457
458
#endif                          /* NETSNMP_USE_REVERSE_ASNENCODING */