snmp.c

00001 /*
00002  * Simple Network Management Protocol (RFC 1067).
00003  *
00004  */
00005 /**********************************************************************
00006         Copyright 1988, 1989, 1991, 1992 by Carnegie Mellon University
00007 
00008                       All Rights Reserved
00009 
00010 Permission to use, copy, modify, and distribute this software and its 
00011 documentation for any purpose and without fee is hereby granted, 
00012 provided that the above copyright notice appear in all copies and that
00013 both that copyright notice and this permission notice appear in 
00014 supporting documentation, and that the name of CMU not be
00015 used in advertising or publicity pertaining to distribution of the
00016 software without specific, written prior permission.  
00017 
00018 CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
00019 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
00020 CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
00021 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
00022 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
00023 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
00024 SOFTWARE.
00025 ******************************************************************/
00026 
00027 #include <net-snmp/net-snmp-config.h>
00028 #include <ctype.h>
00029 
00030 #ifdef KINETICS
00031 #include "gw.h"
00032 #include "ab.h"
00033 #include "inet.h"
00034 #include "fp4/cmdmacro.h"
00035 #include "fp4/pbuf.h"
00036 #include "glob.h"
00037 #endif
00038 
00039 #include <stdio.h>
00040 #include <stdlib.h>
00041 
00042 #include <sys/types.h>
00043 #ifdef HAVE_STRING_H
00044 #include <string.h>
00045 #else
00046 #include <strings.h>
00047 #endif
00048 #if HAVE_NETINET_IN_H
00049 #include <netinet/in.h>
00050 #endif
00051 #ifdef HAVE_SYS_SELECT_H
00052 #include <sys/select.h>
00053 #endif
00054 #if HAVE_WINSOCK_H
00055 #include <winsock.h>
00056 #endif
00057 #ifndef NULL
00058 #define NULL 0
00059 #endif
00060 
00061 #if HAVE_DMALLOC_H
00062 #include <dmalloc.h>
00063 #endif
00064 
00065 #ifdef vms
00066 #include <in.h>
00067 #endif
00068 
00069 #include <net-snmp/types.h>
00070 #include <net-snmp/output_api.h>
00071 
00072 #include <net-snmp/library/asn1.h>
00073 #include <net-snmp/library/snmp.h>      /* for "internal" definitions */
00074 #include <net-snmp/library/snmp_api.h>
00075 #include <net-snmp/library/mib.h>
00076 
00092 void
00093 xdump(const u_char * cp, size_t length, const char *prefix)
00094 {
00095     int             col, count;
00096     char           *buffer;
00097 
00098     buffer = (char *) malloc(strlen(prefix) + 80);
00099     if (!buffer) {
00100         snmp_log(LOG_NOTICE,
00101                  "xdump: malloc failed. packet-dump skipped\n");
00102         return;
00103     }
00104 
00105     count = 0;
00106     while (count < (int) length) {
00107         strcpy(buffer, prefix);
00108         sprintf(buffer + strlen(buffer), "%.4d: ", count);
00109 
00110         for (col = 0; ((count + col) < (int) length) && col < 16; col++) {
00111             sprintf(buffer + strlen(buffer), "%02X ", cp[count + col]);
00112             if (col % 4 == 3)
00113                 strcat(buffer, " ");
00114         }
00115         for (; col < 16; col++) {       /* pad end of buffer with zeros */
00116             strcat(buffer, "   ");
00117             if (col % 4 == 3)
00118                 strcat(buffer, " ");
00119         }
00120         strcat(buffer, "  ");
00121         for (col = 0; ((count + col) < (int) length) && col < 16; col++) {
00122             buffer[col + 60] =
00123                 isprint(cp[count + col]) ? cp[count + col] : '.';
00124         }
00125         buffer[col + 60] = '\n';
00126         buffer[col + 60 + 1] = 0;
00127         snmp_log(LOG_DEBUG, "%s", buffer);
00128         count += col;
00129     }
00130     snmp_log(LOG_DEBUG, "\n");
00131     free(buffer);
00132 
00133 }                               /* end xdump() */
00134 
00135 /*
00136  * u_char * snmp_parse_var_op(
00137  * u_char *data              IN - pointer to the start of object
00138  * oid *var_name             OUT - object id of variable 
00139  * int *var_name_len         IN/OUT - length of variable name 
00140  * u_char *var_val_type      OUT - type of variable (int or octet string) (one byte) 
00141  * int *var_val_len          OUT - length of variable 
00142  * u_char **var_val          OUT - pointer to ASN1 encoded value of variable 
00143  * int *listlength          IN/OUT - number of valid bytes left in var_op_list 
00144  */
00145 
00146 u_char         *
00147 snmp_parse_var_op(u_char * data,
00148                   oid * var_name,
00149                   size_t * var_name_len,
00150                   u_char * var_val_type,
00151                   size_t * var_val_len,
00152                   u_char ** var_val, size_t * listlength)
00153 {
00154     u_char          var_op_type;
00155     size_t          var_op_len = *listlength;
00156     u_char         *var_op_start = data;
00157 
00158     data = asn_parse_sequence(data, &var_op_len, &var_op_type,
00159                               (ASN_SEQUENCE | ASN_CONSTRUCTOR), "var_op");
00160     if (data == NULL) {
00161         /*
00162          * msg detail is set 
00163          */
00164         return NULL;
00165     }
00166     DEBUGDUMPHEADER("recv", "Name");
00167     data =
00168         asn_parse_objid(data, &var_op_len, &var_op_type, var_name,
00169                         var_name_len);
00170     DEBUGINDENTLESS();
00171     if (data == NULL) {
00172         ERROR_MSG("No OID for variable");
00173         return NULL;
00174     }
00175     if (var_op_type !=
00176         (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OBJECT_ID))
00177         return NULL;
00178     *var_val = data;            /* save pointer to this object */
00179     /*
00180      * find out what type of object this is 
00181      */
00182     data = asn_parse_header(data, &var_op_len, var_val_type);
00183     if (data == NULL) {
00184         ERROR_MSG("No header for value");
00185         return NULL;
00186     }
00187     /*
00188      * XXX no check for type! 
00189      */
00190     *var_val_len = var_op_len;
00191     data += var_op_len;
00192     *listlength -= (int) (data - var_op_start);
00193     return data;
00194 }
00195 
00196 /*
00197  * u_char * snmp_build_var_op(
00198  * u_char *data      IN - pointer to the beginning of the output buffer
00199  * oid *var_name        IN - object id of variable 
00200  * int *var_name_len    IN - length of object id 
00201  * u_char var_val_type  IN - type of variable 
00202  * int    var_val_len   IN - length of variable 
00203  * u_char *var_val      IN - value of variable 
00204  * int *listlength      IN/OUT - number of valid bytes left in
00205  * output buffer 
00206  */
00207 
00208 u_char         *
00209 snmp_build_var_op(u_char * data,
00210                   oid * var_name,
00211                   size_t * var_name_len,
00212                   u_char var_val_type,
00213                   size_t var_val_len,
00214                   u_char * var_val, size_t * listlength)
00215 {
00216     size_t          dummyLen, headerLen;
00217     u_char         *dataPtr;
00218 
00219     dummyLen = *listlength;
00220     dataPtr = data;
00221 #if 0
00222     data = asn_build_sequence(data, &dummyLen,
00223                               (u_char) (ASN_SEQUENCE | ASN_CONSTRUCTOR),
00224                               0);
00225     if (data == NULL) {
00226         return NULL;
00227     }
00228 #endif
00229     if (dummyLen < 4)
00230         return NULL;
00231     data += 4;
00232     dummyLen -= 4;
00233 
00234     headerLen = data - dataPtr;
00235     *listlength -= headerLen;
00236     DEBUGDUMPHEADER("send", "Name");
00237     data = asn_build_objid(data, listlength,
00238                            (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE |
00239                                      ASN_OBJECT_ID), var_name,
00240                            *var_name_len);
00241     DEBUGINDENTLESS();
00242     if (data == NULL) {
00243         ERROR_MSG("Can't build OID for variable");
00244         return NULL;
00245     }
00246     DEBUGDUMPHEADER("send", "Value");
00247     switch (var_val_type) {
00248     case ASN_INTEGER:
00249         data = asn_build_int(data, listlength, var_val_type,
00250                              (long *) var_val, var_val_len);
00251         break;
00252     case ASN_GAUGE:
00253     case ASN_COUNTER:
00254     case ASN_TIMETICKS:
00255     case ASN_UINTEGER:
00256         data = asn_build_unsigned_int(data, listlength, var_val_type,
00257                                       (u_long *) var_val, var_val_len);
00258         break;
00259 #ifdef OPAQUE_SPECIAL_TYPES
00260     case ASN_OPAQUE_COUNTER64:
00261     case ASN_OPAQUE_U64:
00262 #endif
00263     case ASN_COUNTER64:
00264         data = asn_build_unsigned_int64(data, listlength, var_val_type,
00265                                         (struct counter64 *) var_val,
00266                                         var_val_len);
00267         break;
00268     case ASN_OCTET_STR:
00269     case ASN_IPADDRESS:
00270     case ASN_OPAQUE:
00271     case ASN_NSAP:
00272         data = asn_build_string(data, listlength, var_val_type,
00273                                 var_val, var_val_len);
00274         break;
00275     case ASN_OBJECT_ID:
00276         data = asn_build_objid(data, listlength, var_val_type,
00277                                (oid *) var_val, var_val_len / sizeof(oid));
00278         break;
00279     case ASN_NULL:
00280         data = asn_build_null(data, listlength, var_val_type);
00281         break;
00282     case ASN_BIT_STR:
00283         data = asn_build_bitstring(data, listlength, var_val_type,
00284                                    var_val, var_val_len);
00285         break;
00286     case SNMP_NOSUCHOBJECT:
00287     case SNMP_NOSUCHINSTANCE:
00288     case SNMP_ENDOFMIBVIEW:
00289         data = asn_build_null(data, listlength, var_val_type);
00290         break;
00291 #ifdef OPAQUE_SPECIAL_TYPES
00292     case ASN_OPAQUE_FLOAT:
00293         data = asn_build_float(data, listlength, var_val_type,
00294                                (float *) var_val, var_val_len);
00295         break;
00296     case ASN_OPAQUE_DOUBLE:
00297         data = asn_build_double(data, listlength, var_val_type,
00298                                 (double *) var_val, var_val_len);
00299         break;
00300     case ASN_OPAQUE_I64:
00301         data = asn_build_signed_int64(data, listlength, var_val_type,
00302                                       (struct counter64 *) var_val,
00303                                       var_val_len);
00304         break;
00305 #endif                          /* OPAQUE_SPECIAL_TYPES */
00306     default:
00307         {
00308         char error_buf[64];
00309         snprintf(error_buf, sizeof(error_buf),
00310                 "wrong type in snmp_build_var_op: %d", var_val_type);
00311         ERROR_MSG(error_buf);
00312         data = NULL;
00313         }
00314     }
00315     DEBUGINDENTLESS();
00316     if (data == NULL) {
00317         return NULL;
00318     }
00319     dummyLen = (data - dataPtr) - headerLen;
00320 
00321     asn_build_sequence(dataPtr, &dummyLen,
00322                        (u_char) (ASN_SEQUENCE | ASN_CONSTRUCTOR),
00323                        dummyLen);
00324     return data;
00325 }
00326 
00327 #ifdef USE_REVERSE_ASNENCODING
00328 int
00329 snmp_realloc_rbuild_var_op(u_char ** pkt, size_t * pkt_len,
00330                            size_t * offset, int allow_realloc,
00331                            const oid * var_name, size_t * var_name_len,
00332                            u_char var_val_type,
00333                            u_char * var_val, size_t var_val_len)
00334 {
00335     size_t          start_offset = *offset;
00336     int             rc = 0;
00337 
00338     /*
00339      * Encode the value.  
00340      */
00341     DEBUGDUMPHEADER("send", "Value");
00342 
00343     switch (var_val_type) {
00344     case ASN_INTEGER:
00345         rc = asn_realloc_rbuild_int(pkt, pkt_len, offset, allow_realloc,
00346                                     var_val_type, (long *) var_val,
00347                                     var_val_len);
00348         break;
00349 
00350     case ASN_GAUGE:
00351     case ASN_COUNTER:
00352     case ASN_TIMETICKS:
00353     case ASN_UINTEGER:
00354         rc = asn_realloc_rbuild_unsigned_int(pkt, pkt_len, offset,
00355                                              allow_realloc, var_val_type,
00356                                              (u_long *) var_val,
00357                                              var_val_len);
00358         break;
00359 
00360 #ifdef OPAQUE_SPECIAL_TYPES
00361     case ASN_OPAQUE_COUNTER64:
00362     case ASN_OPAQUE_U64:
00363 #endif
00364     case ASN_COUNTER64:
00365         rc = asn_realloc_rbuild_unsigned_int64(pkt, pkt_len, offset,
00366                                                allow_realloc, var_val_type,
00367                                                (struct counter64 *)
00368                                                var_val, var_val_len);
00369         break;
00370 
00371     case ASN_OCTET_STR:
00372     case ASN_IPADDRESS:
00373     case ASN_OPAQUE:
00374     case ASN_NSAP:
00375         rc = asn_realloc_rbuild_string(pkt, pkt_len, offset, allow_realloc,
00376                                        var_val_type, var_val, var_val_len);
00377         break;
00378 
00379     case ASN_OBJECT_ID:
00380         rc = asn_realloc_rbuild_objid(pkt, pkt_len, offset, allow_realloc,
00381                                       var_val_type, (oid *) var_val,
00382                                       var_val_len / sizeof(oid));
00383         break;
00384 
00385     case ASN_NULL:
00386         rc = asn_realloc_rbuild_null(pkt, pkt_len, offset, allow_realloc,
00387                                      var_val_type);
00388         break;
00389 
00390     case ASN_BIT_STR:
00391         rc = asn_realloc_rbuild_bitstring(pkt, pkt_len, offset,
00392                                           allow_realloc, var_val_type,
00393                                           var_val, var_val_len);
00394         break;
00395 
00396     case SNMP_NOSUCHOBJECT:
00397     case SNMP_NOSUCHINSTANCE:
00398     case SNMP_ENDOFMIBVIEW:
00399         rc = asn_realloc_rbuild_null(pkt, pkt_len, offset, allow_realloc,
00400                                      var_val_type);
00401         break;
00402 
00403 #ifdef OPAQUE_SPECIAL_TYPES
00404     case ASN_OPAQUE_FLOAT:
00405         rc = asn_realloc_rbuild_float(pkt, pkt_len, offset, allow_realloc,
00406                                       var_val_type, (float *) var_val,
00407                                       var_val_len);
00408         break;
00409 
00410     case ASN_OPAQUE_DOUBLE:
00411         rc = asn_realloc_rbuild_double(pkt, pkt_len, offset, allow_realloc,
00412                                        var_val_type, (double *) var_val,
00413                                        var_val_len);
00414         break;
00415 
00416     case ASN_OPAQUE_I64:
00417         rc = asn_realloc_rbuild_signed_int64(pkt, pkt_len, offset,
00418                                              allow_realloc, var_val_type,
00419                                              (struct counter64 *) var_val,
00420                                              var_val_len);
00421         break;
00422 #endif                          /* OPAQUE_SPECIAL_TYPES */
00423     default:
00424         {
00425         char error_buf[64];
00426         snprintf(error_buf, sizeof(error_buf),
00427                 "wrong type in snmp_realloc_rbuild_var_op: %d", var_val_type);
00428         ERROR_MSG(error_buf);
00429         rc = 0;
00430         }
00431     }
00432     DEBUGINDENTLESS();
00433 
00434     if (rc == 0) {
00435         return 0;
00436     }
00437 
00438     /*
00439      * Build the OID.  
00440      */
00441 
00442     DEBUGDUMPHEADER("send", "Name");
00443     rc = asn_realloc_rbuild_objid(pkt, pkt_len, offset, allow_realloc,
00444                                   (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE |
00445                                             ASN_OBJECT_ID), var_name,
00446                                   *var_name_len);
00447     DEBUGINDENTLESS();
00448     if (rc == 0) {
00449         ERROR_MSG("Can't build OID for variable");
00450         return 0;
00451     }
00452 
00453     /*
00454      * Build the sequence header.  
00455      */
00456 
00457     rc = asn_realloc_rbuild_sequence(pkt, pkt_len, offset, allow_realloc,
00458                                      (u_char) (ASN_SEQUENCE |
00459                                                ASN_CONSTRUCTOR),
00460                                      *offset - start_offset);
00461     return rc;
00462 }
00463 
00464 #endif                          /* USE_REVERSE_ASNENCODING */

net-snmpに対してSat Sep 5 13:14:23 2009に生成されました。  doxygen 1.4.7