OID.xs
上传用户:wxp200602
上传日期:2007-10-30
资源大小:4028k
文件大小:11k
源码类别:

SNMP编程

开发平台:

Unix_Linux

  1. /* -*- C -*- */
  2. #include "EXTERN.h"
  3. #include "perl.h"
  4. #include "XSUB.h"
  5. #include <net-snmp/net-snmp-config.h>
  6. #include <net-snmp/net-snmp-includes.h>
  7. /* pulled from Dave's, yet-to-be-used, net-snmp library rewrite.
  8.    autocompatibility for the future? */
  9. typedef struct netsnmp_oid_s {
  10.     oid                 *name;
  11.     unsigned int         len;
  12.     oid                  namebuf[ MAX_OID_LEN ];
  13. } netsnmp_oid;
  14. static int
  15. not_here(char *s)
  16. {
  17.     croak("%s not implemented on this architecture", s);
  18.     return -1;
  19. }
  20. static double
  21. constant(char *name, int len, int arg)
  22. {
  23.     errno = EINVAL;
  24.     return 0;
  25. }
  26. netsnmp_oid *
  27. nso_newarrayptr(oid *name, size_t name_len) 
  28. {
  29.     netsnmp_oid *RETVAL;
  30.     RETVAL = SNMP_MALLOC_TYPEDEF(netsnmp_oid);
  31.     RETVAL->name = RETVAL->namebuf;
  32.     RETVAL->len = name_len;
  33.     memcpy(RETVAL->name, name, name_len * sizeof(oid));
  34.     return RETVAL;
  35. }
  36. static int __sprint_num_objid _((char *, oid *, int));
  37. /* stolen from SNMP.xs.  Ug, this needs merging to snmplib */
  38. /* XXX: this is only here because snmplib forces quotes around the
  39.    data and won't return real binary data or a numeric string.  Every
  40.    app must do its own switch() to get around it.  Ug. */
  41. #define USE_BASIC 0
  42. #define USE_ENUMS 1
  43. #define USE_SPRINT_VALUE 2
  44. static int
  45. __snprint_value (buf, buf_len, var, tp, type, flag)
  46. char * buf;
  47. size_t buf_len;
  48. netsnmp_variable_list * var;
  49. struct tree * tp;
  50. int type;
  51. int flag;
  52. {
  53.    int len = 0;
  54.    u_char* ip;
  55.    struct enum_list *ep;
  56.    buf[0] = '';
  57.    if (flag == USE_SPRINT_VALUE) {
  58. snprint_value(buf, buf_len, var->name, var->name_length, var);
  59. len = strlen(buf);
  60.    } else {
  61.      switch (var->type) {
  62.         case ASN_INTEGER:
  63.            if (flag == USE_ENUMS) {
  64.               for(ep = tp->enums; ep; ep = ep->next) {
  65.                  if (ep->value == *var->val.integer) {
  66.                     strcpy(buf, ep->label);
  67.                     len = strlen(buf);
  68.                     break;
  69.                  }
  70.               }
  71.            }
  72.            if (!len) {
  73.               sprintf(buf,"%ld", *var->val.integer);
  74.               len = strlen(buf);
  75.            }
  76.            break;
  77.         case ASN_GAUGE:
  78.         case ASN_COUNTER:
  79.         case ASN_TIMETICKS:
  80.         case ASN_UINTEGER:
  81.            sprintf(buf,"%lu", (unsigned long) *var->val.integer);
  82.            len = strlen(buf);
  83.            break;
  84.         case ASN_OCTET_STR:
  85.         case ASN_OPAQUE:
  86.            memcpy(buf, (char*)var->val.string, var->val_len);
  87.            len = var->val_len;
  88.            break;
  89.         case ASN_IPADDRESS:
  90.           ip = (u_char*)var->val.string;
  91.           sprintf(buf, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
  92.           len = strlen(buf);
  93.           break;
  94.         case ASN_NULL:
  95.            break;
  96.         case ASN_OBJECT_ID:
  97.           __sprint_num_objid(buf, (oid *)(var->val.objid),
  98.                              var->val_len/sizeof(oid));
  99.           len = strlen(buf);
  100.           break;
  101. case SNMP_ENDOFMIBVIEW:
  102.           sprintf(buf,"%s", "ENDOFMIBVIEW");
  103.   break;
  104. case SNMP_NOSUCHOBJECT:
  105.   sprintf(buf,"%s", "NOSUCHOBJECT");
  106.   break;
  107. case SNMP_NOSUCHINSTANCE:
  108.   sprintf(buf,"%s", "NOSUCHINSTANCE");
  109.   break;
  110.         case ASN_COUNTER64:
  111.           printU64(buf,(struct counter64 *)var->val.counter64);
  112.           len = strlen(buf);
  113.           break;
  114.         case ASN_BIT_STR:
  115.             snprint_bitstring(buf, sizeof(buf), var, NULL, NULL, NULL);
  116.             len = strlen(buf);
  117.             break;
  118.         case ASN_NSAP:
  119.         default:
  120.            warn("snprint_value: asn type not handled %dn",var->type);
  121.      }
  122.    }
  123.    return(len);
  124. }
  125. static int
  126. __sprint_num_objid (buf, objid, len)
  127. char *buf;
  128. oid *objid;
  129. int len;
  130. {
  131.    int i;
  132.    buf[0] = '';
  133.    for (i=0; i < len; i++) {
  134. sprintf(buf,".%lu",*objid++);
  135. buf += strlen(buf);
  136.    }
  137.    return SNMPERR_SUCCESS;
  138. }
  139. static int
  140. __tp_sprint_num_objid (buf, tp)
  141. char *buf;
  142. struct tree *tp;
  143. {
  144.    oid newname[MAX_OID_LEN], *op;
  145.    /* code taken from get_node in snmp_client.c */
  146.    for (op = newname + MAX_OID_LEN - 1; op >= newname; op--) {
  147.       *op = tp->subid;
  148.       tp = tp->parent;
  149.       if (tp == NULL) break;
  150.    }
  151.    return __sprint_num_objid(buf, op, newname + MAX_OID_LEN - op);
  152. }
  153. MODULE = NetSNMP::OID PACKAGE = NetSNMP::OID PREFIX=nso_
  154. netsnmp_oid *
  155. nso_newptr(initstring)
  156.     char *initstring
  157.     CODE:
  158.         if (get_tree_head() == NULL)
  159.             init_mib();
  160.         RETVAL = SNMP_MALLOC_TYPEDEF(netsnmp_oid);
  161.         RETVAL->name = RETVAL->namebuf;
  162.         RETVAL->len = sizeof(RETVAL->namebuf)/sizeof(RETVAL->namebuf[0]);
  163.         if (!snmp_parse_oid(initstring, (oid *) RETVAL->name, &RETVAL->len)) {
  164.             snmp_log(LOG_ERR, "Can't parse: %sn", initstring);
  165.             RETVAL->len = 0;
  166.             RETVAL = NULL;
  167.         }
  168.     OUTPUT:
  169.         RETVAL
  170. double
  171. constant(sv,arg)
  172.     PREINIT:
  173. STRLEN len;
  174.     INPUT:
  175. SV * sv
  176. char * s = SvPV(sv, len);
  177. int arg
  178.     CODE:
  179. RETVAL = constant(s,len,arg);
  180.     OUTPUT:
  181. RETVAL
  182. int
  183. _snmp_oid_compare(oid1, oid2)
  184.     netsnmp_oid *oid1;
  185.     netsnmp_oid *oid2;
  186.     CODE:
  187.         RETVAL = snmp_oid_compare((oid *) oid1->name, oid1->len,
  188.                                   (oid *) oid2->name, oid2->len);
  189.     OUTPUT:
  190.         RETVAL
  191. MODULE = NetSNMP::OID  PACKAGE = netsnmp_oidPtr  PREFIX = nsop_
  192. void
  193. nsop_DESTROY(oid1)
  194. netsnmp_oid *oid1
  195.     CODE:
  196. free(oid1);
  197.         
  198. char *
  199. nsop_to_string(oid1)
  200.      netsnmp_oid *oid1
  201.     PREINIT:
  202.         static char mystr[SNMP_MAXBUF];
  203.     CODE:
  204.         {
  205.             if (oid1->len == 0)
  206.                 snprintf(mystr, sizeof(mystr), "Illegal OID");
  207.             else
  208.                 snprint_objid(mystr, sizeof(mystr),
  209.                               (oid *) oid1->name, oid1->len);
  210.             RETVAL = mystr;
  211.         }
  212.                 
  213.     OUTPUT:
  214.         RETVAL
  215. void
  216. nsop_to_array(oid1)
  217.     netsnmp_oid *oid1;
  218.     PREINIT:
  219.         int i;
  220.     PPCODE:
  221.         EXTEND(SP, oid1->len);
  222.         for(i=0; i < (int)oid1->len; i++) {
  223.             PUSHs(sv_2mortal(newSVnv(oid1->name[i])));
  224.         }
  225. SV *
  226. nsop_get_indexes(oid1)
  227.         netsnmp_oid *oid1;
  228.     PREINIT:
  229.         int i, nodecount;
  230.         struct tree    *tp, *tpe, *tpnode, *indexnode;
  231.         struct index_list *index;
  232.         netsnmp_variable_list vbdata;
  233.         u_char         *buf = NULL;
  234.         size_t          buf_len = 256, out_len = 0;
  235.         oid name[MAX_OID_LEN];
  236.         size_t name_len = MAX_OID_LEN;
  237.         oid *oidp;
  238.         size_t oidp_len;
  239.         AV *myret;
  240.     CODE:
  241.         {
  242.             memset(&vbdata, 0, sizeof(vbdata));
  243.             if (NULL == (tp = get_tree(oid1->name, oid1->len,
  244.                                        get_tree_head()))) {
  245.                 RETVAL = NULL;
  246.                 return;
  247.             }
  248.                 
  249.             if ((buf = (u_char *) calloc(buf_len, 1)) == NULL) {
  250.                 RETVAL = NULL;
  251.                 return;
  252.             }
  253.             nodecount = 0;
  254.             for(tpnode = tp; tpnode; tpnode = tpnode->parent) {
  255.                 nodecount++;
  256.                 if (nodecount == 2)
  257.                     tpe = tpnode;
  258.                 if (nodecount == 3 &&
  259.                     (strlen(tpnode->label) < 6 ||
  260.                      strcmp(tpnode->label + strlen(tpnode->label) - 5,
  261.                             "Table"))) {
  262.                     /* we're not within a table.  bad logic, little choice */
  263.                     RETVAL = NULL;
  264.                     return;
  265.                 }
  266.             }
  267.             if (tpe->augments && strlen(tpe->augments) > 0) {
  268.                 /* we're augmenting another table, so use that entry instead */
  269.                 if (!snmp_parse_oid(tpe->augments, name, &name_len) ||
  270.                     (NULL ==
  271.                      (tpe = get_tree(name, name_len,
  272.                                      get_tree_head())))) {
  273.                     RETVAL = NULL;
  274.                     return; /* XXX: better error recovery needed? */
  275.                 }
  276.             }
  277.             
  278.             i = 0;
  279.             for(index = tpe->indexes; index; index = index->next) {
  280.                 i++;
  281.             }
  282.             myret = (AV *) sv_2mortal((SV *) newAV());
  283.             oidp = oid1->name + nodecount;
  284.             oidp_len = oid1->len - nodecount;
  285.             for(index = tpe->indexes; index; index = index->next) {
  286.                 /* XXX: NOT efficient! */
  287.                 name_len = MAX_OID_LEN;
  288.                 if (!snmp_parse_oid(index->ilabel, name, &name_len) ||
  289.                     (NULL ==
  290.                      (indexnode = get_tree(name, name_len,
  291.                                            get_tree_head())))) {
  292.                     RETVAL = NULL;
  293.                     return;             /* xxx mem leak */
  294.                 }
  295.                 vbdata.type = mib_to_asn_type(indexnode->type);
  296.                 
  297.                 if (vbdata.type == (u_char) -1) {
  298.                     RETVAL = NULL;
  299.                     return; /* XXX: not good.  half populated stack? */
  300.                 }
  301.                 if (index->isimplied)
  302.                     vbdata.type |= ASN_PRIVATE;
  303.                 /* possible memory leak: vbdata.data should be freed later */
  304.                 if (parse_one_oid_index(&oidp, &oidp_len, &vbdata, 0)
  305.                     != SNMPERR_SUCCESS) {
  306.                     RETVAL = NULL;
  307.                     return;
  308.                 }
  309.                 out_len = 0;
  310.                 if (index->isimplied)
  311.                     vbdata.type ^= ASN_PRIVATE;
  312.                 out_len =
  313.                     __snprint_value (buf, buf_len, &vbdata, indexnode,
  314.                                      vbdata.type, 0);
  315. /*
  316.                 sprint_realloc_value(&buf, &buf_len, &out_len,
  317.                                      1, name, name_len, &vbdata);
  318. */
  319.                 av_push(myret, newSVpv(buf, out_len));
  320.             }
  321.             RETVAL = newRV((SV *)myret);
  322.         }
  323.     OUTPUT:
  324.         RETVAL
  325. void
  326. nsop_append(oid1, string)
  327.     netsnmp_oid *oid1;
  328.     char *string;
  329.     PREINIT:
  330.     oid name[MAX_OID_LEN];
  331.     size_t name_len = MAX_OID_LEN;
  332.     int i;
  333.     CODE: 
  334.     {
  335.         if (!snmp_parse_oid(string, (oid *) name, &name_len)) {
  336.             /* XXX */
  337.         }
  338.         if (oid1->len + name_len > MAX_OID_LEN) {
  339.             /* XXX: illegal */
  340.         }
  341.         for(i = 0; i < (int)name_len; i++) {
  342.             oid1->name[i+oid1->len] = name[i];
  343.         }
  344.         oid1->len += name_len;
  345.     }
  346. void
  347. nsop_append_oid(oid1, oid2)
  348.     netsnmp_oid *oid1;
  349.     netsnmp_oid *oid2;
  350.     PREINIT:
  351.     int i;
  352.     CODE: 
  353.     {
  354.         if (oid1->len + oid2->len > MAX_OID_LEN) {
  355.             /* XXX: illegal */
  356.         }
  357.         for(i = 0; i < (int)oid2->len; i++) {
  358.             oid1->name[i+oid1->len] = oid2->name[i];
  359.         }
  360.         oid1->len += oid2->len;
  361.     }
  362. int
  363. nsop_length(oid1)
  364.     netsnmp_oid *oid1;
  365.     CODE: 
  366.     {
  367.         RETVAL = oid1->len;
  368.     }
  369.     OUTPUT:
  370.     RETVAL
  371.     
  372. netsnmp_oid *
  373. nsop_clone(oid1)
  374.     netsnmp_oid *oid1;
  375.     PREINIT:
  376.     netsnmp_oid *oid2;
  377.     CODE:
  378.     {
  379.         oid2 = nso_newarrayptr(oid1->name, oid1->len);
  380.         RETVAL = oid2;
  381.     }
  382. OUTPUT:
  383.     RETVAL
  384.