⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 _snmp.c

📁 This directory contains source code for tcpdump, a tool for network monitoring and data acquisition
💻 C
📖 第 1 页 / 共 4 页
字号:
    {
      if (vflag)
        PRINTF ("|%.2x", *p);
      elem->asnlen = (elem->asnlen << ASN_SHIFT8) | *p++;
    }
  }
  if (len < elem->asnlen)
  {
    if (!truncated)
    {
      PRINTF ("[len%d<asnlen%u]", len, elem->asnlen);
      return -1;
    }
    /* maybe should check at least 4? */
    elem->asnlen = len;
  }
  if (form >= DIM(Form))
  {
    ifNotTruncated PRINTF ("[form?%d]", form);

    return -1;
  }
  if (class >= DIM(Class))
  {
    ifNotTruncated PRINTF ("[class?%c/%d]", *Form[form], class);

    return -1;
  }
  if ((int) id >= Class[class].numIDs)
  {
    ifNotTruncated PRINTF ("[id?%c/%s/%d]", *Form[form], Class[class].name, id);

    return -1;
  }

  switch (form)
  {
    case PRIMITIVE:
         switch (class)
         {
           case UNIVERSAL:
                switch (id)
                {
                  case STRING:
                       elem->type = BE_STR;
                       elem->data.str = p;
                       break;

                  case INTEGER:
                       {
                         int32_t data;

                         elem->type = BE_INT;
                         data = 0;

                         if (*p & ASN_BIT8)        /* negative */
                           data = -1;
                         for (i = elem->asnlen; i-- > 0; p++)
                           data = (data << ASN_SHIFT8) | *p;
                         elem->data.integer = data;
                         break;
                       }

                  case OBJECTID:
                       elem->type = BE_OID;
                       elem->data.raw = (caddr_t) p;
                       break;

                  case ASN_NULL:
                       elem->type = BE_NULL;
                       elem->data.raw = (caddr_t)0;
                       break;

                  default:
                       elem->type = BE_OCTET;
                       elem->data.raw = (caddr_t) p;
                       PRINTF ("[P/U/%s]", Class[class].Id[id]);
                       break;
                }
                break;

           case APPLICATION:
                switch (id)
                {
                  case IPADDR:
                       elem->type = BE_INETADDR;
                       elem->data.raw = (caddr_t) p;
                       break;

                  case COUNTER:
                  case GAUGE:
                  case TIMETICKS:
                       {
                         u_int32_t data;

                         elem->type = BE_UNS;
                         data = 0;
                         for (i = elem->asnlen; i-- > 0; p++)
                           data = (data << 8) + *p;
                         elem->data.uns = data;
                         break;
                       }

                  case COUNTER64:
                       {
                         u_int32_t high, low;

                         elem->type = BE_UNS64;
                         high = 0, low = 0;
                         for (i = elem->asnlen; i-- > 0; p++)
                         {
                           high = (high << 8) | ((low & 0xFF000000) >> 24);
                           low = (low << 8) | *p;
                         }
                         elem->data.uns64.high = high;
                         elem->data.uns64.low = low;
                         break;
                       }

                  default:
                       elem->type = BE_OCTET;
                       elem->data.raw = (caddr_t) p;
                       PRINTF ("[P/A/%s]", Class[class].Id[id]);
                       break;
                }
                break;

           case CONTEXT:
                switch (id)
                {
                  case NOSUCHOBJECT:
                       elem->type = BE_NOSUCHOBJECT;
                       elem->data.raw = (caddr_t)0;
                       break;

                  case NOSUCHINSTANCE:
                       elem->type = BE_NOSUCHINST;
                       elem->data.raw = (caddr_t)0;
                       break;

                  case ENDOFMIBVIEW:
                       elem->type = BE_ENDOFMIBVIEW;
                       elem->data.raw = (caddr_t)0;
                       break;
                }
                break;

           default:
                elem->type = BE_OCTET;
                elem->data.raw = (caddr_t) p;
                PRINTF ("[P/%s/%s]", Class[class].name, Class[class].Id[id]);
                break;
         }
         break;

    case CONSTRUCTED:
         switch (class)
         {
           case UNIVERSAL:
                switch (id)
                {
                  case SEQUENCE:
                       elem->type = BE_SEQ;
                       elem->data.raw = (caddr_t) p;
                       break;

                  default:
                       elem->type = BE_OCTET;
                       elem->data.raw = (caddr_t) p;
                       PRINTF ("C/U/%s", Class[class].Id[id]);
                       break;
                }
                break;

           case CONTEXT:
                elem->type = BE_PDU;
                elem->data.raw = (caddr_t) p;
                break;

           default:
                elem->type = BE_OCTET;
                elem->data.raw = (caddr_t) p;
                PRINTF ("C/%s/%s", Class[class].name, Class[class].Id[id]);
                break;
         }
         break;
  }
  p += elem->asnlen;
  len -= elem->asnlen;
  return elem->asnlen + hdr;
}

/*
 * Display the ASN.1 object represented by the BE object.
 * This used to be an integral part of asn1_parse() before the intermediate
 * BE form was added.
 */
static void asn1_print (struct be *elem)
{
  u_char *p = (u_char *) elem->data.raw;
  u_int32_t asnlen = elem->asnlen;
  int i;

  switch (elem->type)
  {

    case BE_OCTET:
         for (i = asnlen; i-- > 0; p++) ;
         PRINTF ("_%.2x", *p);
         break;

    case BE_NULL:
         break;

    case BE_OID:
         {
           int o = 0, first = -1, i = asnlen;

           if (!sflag && !nflag && asnlen > 2)
           {
             struct obj_abrev *a = &obj_abrev_list[0];

             for (; a->node; a++)
             {
               if (!memcmp (a->oid, (char *) p, strlen (a->oid)))
               {
                 objp = a->node->child;
                 i -= strlen (a->oid);
                 p += strlen (a->oid);
                 PUTS (a->prefix);
                 first = 1;
                 break;
               }
             }
           }

           for (; !sflag && i-- > 0; p++)
           {
             o = (o << ASN_SHIFT7) + (*p & ~ASN_BIT8);
             if (*p & ASN_LONGLEN)
               continue;

             /*
              * first subitem encodes two items with 1st*OIDMUX+2nd
              */
             if (first < 0)
             {
               if (!nflag)
                 objp = mibroot;
               first = 0;
               OBJ_PRINT (o / OIDMUX, first);
               o %= OIDMUX;
             }
             OBJ_PRINT (o, first);
             if (--first < 0)
               first = 0;
             o = 0;
           }
           break;
         }

    case BE_INT:
         PRINTF ("%d", elem->data.integer);
         break;

    case BE_UNS:
         PRINTF ("%u", elem->data.uns);
         break;

    case BE_UNS64:
         {                        /* idea borrowed from by Marshall Rose */
           double d;
           int j, carry;
           char *cpf, *cpl, last[6], first[30];

           if (elem->data.uns64.high == 0)
           {
             PRINTF ("%u", elem->data.uns64.low);
             break;
           }
           d = elem->data.uns64.high * 4294967296.0;        /* 2^32 */
           if (elem->data.uns64.high <= 0x1fffff)
           {
             d += elem->data.uns64.low;
#if 0        /* it looks illegal, but what is the intention??? */
             PRINTF ("%.f", d);
#else
             PRINTF ("%f", d);
#endif
             break;
           }
           d += (elem->data.uns64.low & 0xfffff000);
#if 0      /* it looks illegal, but what is the intention??? */
           sprintf (first, "%.f", d);
#else
           sprintf (first, "%f", d);
#endif
           sprintf (last, "%5.5ld", elem->data.uns64.low & 0xfff);
           for (carry = 0, cpf = first + strlen (first) - 1, cpl = last + 4; cpl >= last; cpf--, cpl--)
           {
             j = carry + (*cpf - '0') + (*cpl - '0');
             if (j > 9)
             {
               j -= 10;
               carry = 1;
             }
             else
             {
               carry = 0;
             }
             *cpf = j + '0';
           }
           PUTS (first);
           break;
         }

    case BE_STR:
         {
           int printable = 1, first = 1;
           const u_char *p = elem->data.str;

           for (i = asnlen; printable && i-- > 0; p++)
             printable = isprint (*p) || isspace (*p);
           p = elem->data.str;
           if (printable)
           {
             PUTCHAR ('"');
             fn_print ((char*)p, (char*)(p+asnlen));
             PUTCHAR ('"');
           }
           else
             for (i = asnlen; i-- > 0; p++)
             {
               PRINTF (first ? "%.2x" : "_%.2x", *p);
               first = 0;
             }
           break;
         }

    case BE_SEQ:
         PRINTF ("Seq(%u)", elem->asnlen);
         break;

    case BE_INETADDR:
         if (asnlen != ASNLEN_INETADDR)
            PRINTF ("[inetaddr len!=%d]", ASNLEN_INETADDR);
         for (i = asnlen; i-- > 0; p++)
            PRINTF ((i == asnlen - 1) ? "%u" : ".%u", *p);
         break;

    case BE_NOSUCHOBJECT:
    case BE_NOSUCHINST:
    case BE_ENDOFMIBVIEW:
         PRINTF ("[%s]", Class[EXCEPTIONS].Id[elem->id]);
         break;

    case BE_PDU:
         PRINTF ("%s(%u)", Class[CONTEXT].Id[elem->id], elem->asnlen);
         break;

    case BE_ANY:
         PUTS ("[BE_ANY!?]");
         break;

    default:
         PUTS ("[be!?]");
         break;
  }
}

#ifdef notdef
/*
 * This is a brute force ASN.1 printer: recurses to dump an entire structure.
 * This will work for any ASN.1 stream, not just an SNMP PDU.
 *
 * By adding newlines and spaces at the correct places, this would print in
 * Rose-Normal-Form.
 *
 * This is not currently used.
 */
static void asn1_decode (u_char * p, u_int length)
{
  struct be elem;
  int i = 0;

  while (i >= 0 && length > 0)
  {
    i = asn1_parse (p, length, &elem);
    if (i >= 0)
    {
      PUTCHAR (' ');
      asn1_print (&elem);
      if (elem.type == BE_SEQ || elem.type == BE_PDU)
      {
        PUTS (" {");
        asn1_decode (elem.data.raw, elem.asnlen);
        PUTS (" }");
      }
      length -= i;
      p += i;
    }
  }
}
#endif

#ifdef LIBSMI

struct smi2be {
       SmiBasetype basetype;
       int         be;
     };

struct smi2be smi2betab[] = {
  {SMI_BASETYPE_INTEGER32, BE_INT},
  {SMI_BASETYPE_OCTETSTRING, BE_STR},
  {SMI_BASETYPE_OCTETSTRING, BE_INETADDR},
  {SMI_BASETYPE_OBJECTIDENTIFIER, BE_OID},
  {SMI_BASETYPE_UNSIGNED32, BE_UNS},
  {SMI_BASETYPE_INTEGER64, BE_NONE},
  {SMI_BASETYPE_UNSIGNED64, BE_UNS64},
  {SMI_BASETYPE_FLOAT32, BE_NONE},
  {SMI_BASETYPE_FLOAT64, BE_NONE},
  {SMI_BASETYPE_FLOAT128, BE_NONE},
  {SMI_BASETYPE_ENUM, BE_INT},
  {SMI_BASETYPE_BITS, BE_STR},
  {SMI_BASETYPE_UNKNOWN, BE_NONE}
};

static void smi_decode_oid (struct be *elem, unsigned int *oid, unsigned int *oidlen)
{
  u_char   *p      = (u_char *) elem->data.raw;
  u_int32_t asnlen = elem->asnlen;
  int       o = 0, first = -1, i = asnlen;

  for (*oidlen = 0; sflag && i-- > 0; p++)
  {
    o = (o << ASN_SHIFT7) + (*p & ~ASN_BIT8);
    if (*p & ASN_LONGLEN)
      continue;

    /*
     * first subitem encodes two items with 1st*OIDMUX+2nd
     */
    if (first < 0)
    {
      first = 0;
      oid[(*oidlen)++] = o / OIDMUX;
      o %= OIDMUX;
    }
    oid[(*oidlen)++] = o;
    o = 0;
  }
}

static int smi_check_type (SmiBasetype basetype, int be)
{
  int i;

  for (i = 0; smi2betab[i].basetype != SMI_BASETYPE_UNKNOWN; i++)
  {
    if (smi2betab[i].basetype == basetype && smi2betab[i].be == be)
       return 1;
  }
  return 0;
}

static int smi_check_a_range (SmiType * smiType, SmiRange * smiRange, struct be *elem)
{
  int ok;

  switch (smiType->basetype)
  {
    case SMI_BASETYPE_OBJECTIDENTIFIER:
    case SMI_BASETYPE_OCTETSTRING:
         if (smiRange->minValue.value.unsigned32 == smiRange->maxValue.value.unsigned32)
              ok = (elem->asnlen == smiRange->minValue.value.unsigned32);
         else ok = (elem->asnlen >= smiRange->minValue.value.unsigned32 &&
                    elem->asnlen <= smiRange->maxValue.value.unsigned32);
         break;

    case SMI_BASETYPE_INTEGER32:
         ok = (elem->data.integer >= smiRange->minValue.value.integer32 &&
               elem->data.integer <= smiRange->maxValue.value.integer32);
         break;

    case SMI_BASETYPE_UNSIGNED32:
         ok = (elem->data.uns >= smiRange->minValue.value.unsigned32 &&
               elem->data.uns <= smiRange->maxValue.value.unsigned32);
         break;

    case SMI_BASETYPE_UNSIGNED64:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -