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