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
0
{
162
0
    u_char          var_op_type;
163
0
    size_t          var_op_len = *listlength;
164
0
    u_char         *var_op_start = data;
165
166
0
    data = asn_parse_sequence(data, &var_op_len, &var_op_type,
167
0
                              (ASN_SEQUENCE | ASN_CONSTRUCTOR), "var_op");
168
0
    if (data == NULL) {
169
        /*
170
         * msg detail is set 
171
         */
172
0
        return NULL;
173
0
    }
174
0
    DEBUGDUMPHEADER("recv", "Name");
175
0
    data =
176
0
        asn_parse_objid(data, &var_op_len, &var_op_type, var_name,
177
0
                        var_name_len);
178
0
    DEBUGINDENTLESS();
179
0
    if (data == NULL) {
180
0
        ERROR_MSG("No OID for variable");
181
0
        return NULL;
182
0
    }
183
0
    if (var_op_type !=
184
0
        (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OBJECT_ID))
185
0
        return NULL;
186
0
    *var_val = data;            /* save pointer to this object */
187
    /*
188
     * find out what type of object this is 
189
     */
190
0
    data = asn_parse_header(data, &var_op_len, var_val_type);
191
0
    if (data == NULL) {
192
0
        ERROR_MSG("No header for value");
193
0
        return NULL;
194
0
    }
195
    /*
196
     * XXX no check for type! 
197
     */
198
0
    *var_val_len = var_op_len;
199
0
    data += var_op_len;
200
0
    *listlength -= (int) (data - var_op_start);
201
0
    return data;
202
0
}
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
0
{
224
0
    const size_t    headerLen = 4;
225
0
    size_t          sequenceLen;
226
0
    u_char   *const dataPtr = data;
227
228
0
    if (*listlength < headerLen)
229
0
        return NULL;
230
0
    data += headerLen;
231
0
    *listlength -= headerLen;
232
233
0
    DEBUGDUMPHEADER("send", "Name");
234
0
    data = asn_build_objid(data, listlength,
235
0
                           (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE |
236
0
                                     ASN_OBJECT_ID), var_name,
237
0
                           *var_name_len);
238
0
    DEBUGINDENTLESS();
239
0
    if (data == NULL) {
240
0
        ERROR_MSG("Can't build OID for variable");
241
0
        return NULL;
242
0
    }
243
0
    DEBUGDUMPHEADER("send", "Value");
244
0
    switch (var_val_type) {
245
0
    case ASN_INTEGER:
246
0
        data = asn_build_int(data, listlength, var_val_type,
247
0
                             var_val, var_val_len);
248
0
        break;
249
0
    case ASN_GAUGE:
250
0
    case ASN_COUNTER:
251
0
    case ASN_TIMETICKS:
252
0
    case ASN_UINTEGER:
253
0
        data = asn_build_unsigned_int(data, listlength, var_val_type,
254
0
                                      var_val, var_val_len);
255
0
        break;
256
0
#ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES
257
0
    case ASN_OPAQUE_COUNTER64:
258
0
    case ASN_OPAQUE_U64:
259
0
#endif
260
0
    case ASN_COUNTER64:
261
0
        data = asn_build_unsigned_int64(data, listlength, var_val_type,
262
0
                                        var_val, var_val_len);
263
0
        break;
264
0
    case ASN_OCTET_STR:
265
0
    case ASN_IPADDRESS:
266
0
    case ASN_OPAQUE:
267
0
    case ASN_NSAP:
268
0
        data = asn_build_string(data, listlength, var_val_type,
269
0
                                var_val, var_val_len);
270
0
        break;
271
0
    case ASN_OBJECT_ID:
272
0
        data = asn_build_objid(data, listlength, var_val_type,
273
0
                               var_val, var_val_len / sizeof(oid));
274
0
        break;
275
0
    case ASN_NULL:
276
0
        data = asn_build_null(data, listlength, var_val_type);
277
0
        break;
278
0
    case ASN_BIT_STR:
279
0
        data = asn_build_bitstring(data, listlength, var_val_type,
280
0
                                   var_val, var_val_len);
281
0
        break;
282
0
    case SNMP_NOSUCHOBJECT:
283
0
    case SNMP_NOSUCHINSTANCE:
284
0
    case SNMP_ENDOFMIBVIEW:
285
0
        data = asn_build_null(data, listlength, var_val_type);
286
0
        break;
287
0
#ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES
288
0
    case ASN_OPAQUE_FLOAT:
289
0
        data = asn_build_float(data, listlength, var_val_type,
290
0
                               var_val, var_val_len);
291
0
        break;
292
0
    case ASN_OPAQUE_DOUBLE:
293
0
        data = asn_build_double(data, listlength, var_val_type,
294
0
                                var_val, var_val_len);
295
0
        break;
296
0
    case ASN_OPAQUE_I64:
297
0
        data = asn_build_signed_int64(data, listlength, var_val_type,
298
0
                                      var_val, var_val_len);
299
0
        break;
300
0
#endif                          /* NETSNMP_WITH_OPAQUE_SPECIAL_TYPES */
301
0
    default:
302
0
  {
303
0
  char error_buf[64];
304
0
  snprintf(error_buf, sizeof(error_buf),
305
0
    "wrong type in snmp_build_var_op: %d", var_val_type);
306
0
        ERROR_MSG(error_buf);
307
0
        data = NULL;
308
0
  }
309
0
    }
310
0
    DEBUGINDENTLESS();
311
0
    if (data == NULL) {
312
0
        return NULL;
313
0
    }
314
315
0
    sequenceLen = (data - dataPtr) - headerLen;
316
0
    asn_build_sequence(dataPtr, &sequenceLen, ASN_SEQUENCE | ASN_CONSTRUCTOR,
317
0
                       headerLen);
318
0
    return data;
319
0
}
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
0
{
329
0
    size_t          start_offset = *offset;
330
0
    int             rc = 0;
331
332
    /*
333
     * Encode the value.  
334
     */
335
0
    DEBUGDUMPHEADER("send", "Value");
336
337
0
    switch (var_val_type) {
338
0
    case ASN_INTEGER:
339
0
        rc = asn_realloc_rbuild_int(pkt, pkt_len, offset, allow_realloc,
340
0
                                    var_val_type, (long *) var_val,
341
0
                                    var_val_len);
342
0
        break;
343
344
0
    case ASN_GAUGE:
345
0
    case ASN_COUNTER:
346
0
    case ASN_TIMETICKS:
347
0
    case ASN_UINTEGER:
348
0
        rc = asn_realloc_rbuild_unsigned_int(pkt, pkt_len, offset,
349
0
                                             allow_realloc, var_val_type,
350
0
                                             (u_long *) var_val,
351
0
                                             var_val_len);
352
0
        break;
353
354
0
#ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES
355
0
    case ASN_OPAQUE_COUNTER64:
356
0
    case ASN_OPAQUE_U64:
357
0
#endif
358
0
    case ASN_COUNTER64:
359
0
        rc = asn_realloc_rbuild_unsigned_int64(pkt, pkt_len, offset,
360
0
                                               allow_realloc, var_val_type,
361
0
                                               (struct counter64 *)
362
0
                                               var_val, var_val_len);
363
0
        break;
364
365
0
    case ASN_OCTET_STR:
366
0
    case ASN_IPADDRESS:
367
0
    case ASN_OPAQUE:
368
0
    case ASN_NSAP:
369
0
        rc = asn_realloc_rbuild_string(pkt, pkt_len, offset, allow_realloc,
370
0
                                       var_val_type, var_val, var_val_len);
371
0
        break;
372
373
0
    case ASN_OBJECT_ID:
374
0
        rc = asn_realloc_rbuild_objid(pkt, pkt_len, offset, allow_realloc,
375
0
                                      var_val_type, (oid *) var_val,
376
0
                                      var_val_len / sizeof(oid));
377
0
        break;
378
379
0
    case ASN_NULL:
380
0
        rc = asn_realloc_rbuild_null(pkt, pkt_len, offset, allow_realloc,
381
0
                                     var_val_type);
382
0
        break;
383
384
0
    case ASN_BIT_STR:
385
0
        rc = asn_realloc_rbuild_bitstring(pkt, pkt_len, offset,
386
0
                                          allow_realloc, var_val_type,
387
0
                                          var_val, var_val_len);
388
0
        break;
389
390
0
    case SNMP_NOSUCHOBJECT:
391
0
    case SNMP_NOSUCHINSTANCE:
392
0
    case SNMP_ENDOFMIBVIEW:
393
0
        rc = asn_realloc_rbuild_null(pkt, pkt_len, offset, allow_realloc,
394
0
                                     var_val_type);
395
0
        break;
396
397
0
#ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES
398
0
    case ASN_OPAQUE_FLOAT:
399
0
        rc = asn_realloc_rbuild_float(pkt, pkt_len, offset, allow_realloc,
400
0
                                      var_val_type, (float *) var_val,
401
0
                                      var_val_len);
402
0
        break;
403
404
0
    case ASN_OPAQUE_DOUBLE:
405
0
        rc = asn_realloc_rbuild_double(pkt, pkt_len, offset, allow_realloc,
406
0
                                       var_val_type, (double *) var_val,
407
0
                                       var_val_len);
408
0
        break;
409
410
0
    case ASN_OPAQUE_I64:
411
0
        rc = asn_realloc_rbuild_signed_int64(pkt, pkt_len, offset,
412
0
                                             allow_realloc, var_val_type,
413
0
                                             (struct counter64 *) var_val,
414
0
                                             var_val_len);
415
0
        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
0
    }
426
0
    DEBUGINDENTLESS();
427
428
0
    if (rc == 0) {
429
0
        return 0;
430
0
    }
431
432
    /*
433
     * Build the OID.  
434
     */
435
436
0
    DEBUGDUMPHEADER("send", "Name");
437
0
    rc = asn_realloc_rbuild_objid(pkt, pkt_len, offset, allow_realloc,
438
0
                                  (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE |
439
0
                                            ASN_OBJECT_ID), var_name,
440
0
                                  *var_name_len);
441
0
    DEBUGINDENTLESS();
442
0
    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
0
    rc = asn_realloc_rbuild_sequence(pkt, pkt_len, offset, allow_realloc,
452
0
                                     (u_char) (ASN_SEQUENCE |
453
0
                                               ASN_CONSTRUCTOR),
454
0
                                     *offset - start_offset);
455
0
    return rc;
456
0
}
457
458
#endif                          /* NETSNMP_USE_REVERSE_ASNENCODING */