Coverage Report

Created: 2024-07-27 06:05

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