Coverage Report

Created: 2026-03-17 06:31

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