1
0
Files
2022-09-29 17:59:04 +03:00

710 lines
14 KiB
C++

/*
* Copyright 1990 Silicon Graphics, Inc. All rights reserved.
*
* SNMP
*
* $Revision: 1.7 $
*
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
* the contents of this file may not be disclosed to third parties, copied or
* duplicated in any form, in whole or in part, without the prior written
* permission of Silicon Graphics, Inc.
*
* RESTRICTED RIGHTS LEGEND:
* Use, duplication or disclosure by the Government is subject to restrictions
* as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
* and Computer Software clause at DFARS 252.227-7013, and/or in similar or
* successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
* rights reserved under the Copyright Laws of the United States.
*/
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <libc.h>
#include <string.h>
#include "oid.h"
#include "asn1.h"
#include "snmp.h"
/*
* SNMP network address class
*/
snmpNetworkAddress::snmpNetworkAddress(void)
{
}
snmpNetworkAddress::snmpNetworkAddress(unsigned long a)
{
setValue(a);
}
snmpNetworkAddress::snmpNetworkAddress(const char *s)
{
setValue(s);
}
snmpNetworkAddress::~snmpNetworkAddress(void)
{
}
void
snmpNetworkAddress::setValue(unsigned long a)
{
value = (void *) a;
tag = TAG_IPADDRESS; // XXX - tag = TAG_NETADDR_IP;
}
void
snmpNetworkAddress::setValue(const char *s)
{
value = (void *) inet_addr(s);
tag = TAG_NETADDR_IP;
}
void
snmpNetworkAddress::setValue(asnObject *a)
{
*this = *((snmpNetworkAddress *) a);
}
unsigned long
snmpNetworkAddress::getValue(void)
{
return (unsigned long) value;
}
int
snmpNetworkAddress::encode(void)
{
if (asn == 0 || asnLength < 6)
return 0;
char *p = asn;
*p++ = tag; // Fill in the tag value
int llen = encodeLength(&p, 4);
if (llen == 0)
return 0;
unsigned long temp = (unsigned long) value;
unsigned int ii = (unsigned int) temp;
bcopy(&ii, p, 4);
p += 4;
return llen + 5;
}
int
snmpNetworkAddress::encode(char *a, unsigned int len)
{
setAsn(a, len);
return encode();
}
int
snmpNetworkAddress::decode(void)
{
if (asn == 0 || asnLength < 6)
return 0;
char *p = asn;
tag = *p++;
if (tag != TAG_IPADDRESS) // XXX - TAG_NETADDR_IP?
return 0; // Wrong tag
unsigned int len;
int llen = decodeLength(&p, len);
if (llen == 0 || len != 4)
return 0; // Bad length
unsigned int ii;
bcopy(p, &ii, 4);
unsigned long temp = (unsigned long) ii;
value = (void *) temp;
unsigned long tmp = (unsigned long)p + 4;
return llen + 5;
}
int
snmpNetworkAddress::decode(char *a, unsigned int len)
{
setAsn(a, len);
return decode();
}
asnObject *
snmpNetworkAddress::dup(void)
{
return new snmpNetworkAddress(getValue());
}
char *
snmpNetworkAddress::getString(void)
{
struct in_addr i;
i.s_addr = (unsigned long) value;
char *a = inet_ntoa(i);
char *s = new char[strlen(a) + 1];
strcpy(s, a);
return s;
}
/*
* SNMP IP address class
*/
snmpIPaddress::snmpIPaddress(void)
{
}
snmpIPaddress::snmpIPaddress(unsigned long a)
{
setValue(a);
}
snmpIPaddress::snmpIPaddress(const char *s)
{
setValue(s);
}
snmpIPaddress::~snmpIPaddress(void)
{
}
void
snmpIPaddress::setValue(unsigned long a)
{
value = (void *) a;
tag = TAG_IPADDRESS;
}
void
snmpIPaddress::setValue(const char *s)
{
value = (void *) inet_addr(s);
tag = TAG_IPADDRESS;
}
void
snmpIPaddress::setValue(asnObject *a)
{
*this = *((snmpIPaddress *) a);
}
unsigned long
snmpIPaddress::getValue(void)
{
return (unsigned long) value;
}
int
snmpIPaddress::encode(void)
{
if (asn == 0 || asnLength < 6)
return 0;
char *p = asn;
*p++ = tag; // Fill in the tag value
int llen = encodeLength(&p, 4);
if (llen == 0)
return 0;
unsigned long temp = (unsigned long) value;
unsigned int ii = (unsigned int) temp;
bcopy(&ii, p, 4);
p += 4;
return llen + 5;
}
int
snmpIPaddress::encode(char *a, unsigned int len)
{
setAsn(a, len);
return encode();
}
int
snmpIPaddress::decode(void)
{
if (asn == 0 || asnLength < 6)
return 0;
char *p = asn;
tag = *p++;
if (tag != TAG_IPADDRESS)
return 0; // Wrong tag
unsigned int len;
int llen = decodeLength(&p, len);
if (llen == 0 || len != 4)
return 0; // Bad length
unsigned int ii;
bcopy(p, &ii, 4);
unsigned long temp = (unsigned long) ii;
value = (void *) temp;
return llen + 5;
}
int
snmpIPaddress::decode(char *a, unsigned int len)
{
setAsn(a, len);
return decode();
}
asnObject *
snmpIPaddress::dup(void)
{
return new snmpIPaddress(getValue());
}
char *
snmpIPaddress::getString(void)
{
struct in_addr i;
i.s_addr = (unsigned long) value;
char *a = inet_ntoa(i);
char *s = new char[strlen(a) + 1];
strcpy(s, a);
return s;
}
/*
* SNMP Counter class
*/
snmpCounter::snmpCounter(void)
{
}
snmpCounter::snmpCounter(unsigned int i)
{
setValue(i);
}
snmpCounter::~snmpCounter(void)
{
}
void
snmpCounter::setValue(unsigned int i)
{
unsigned long tmp = i;
value = (void *) tmp;
tag = TAG_COUNTER;
}
void
snmpCounter::setValue(asnObject *a)
{
*this = *((snmpCounter *) a);
}
unsigned int
snmpCounter::getValue(void)
{
unsigned long tmp = (unsigned long) value;
return (unsigned int) tmp;
}
int
snmpCounter::encode(void)
{
if (asn == 0 || asnLength < 2)
return 0;
char *p = asn;
*p++ = tag; // Fill in the tag value
/*
* Send the least number of bytes necessary to hold a signed number
* most significant byte first. Bit 8 of the first byte must
* be zero if the number is positive.
*/
unsigned long tmp = (unsigned long)value;
unsigned int v = (unsigned int) tmp;
unsigned int len = sizeof(int);
unsigned int shift = 8 * (len - 1);
unsigned int mask = 0x1FF << (shift - 1);
while ( ((mask & v) == 0 || (mask & v) == mask) && len > 1) {
v <<= 8;
len--;
}
int llen = encodeLength(&p, len);
if (llen == 0)
return 0; // Bad length
if (len > asnLength - llen)
return 0; // End of ASN string
while (len-- != 0) {
*p++ = v >> shift;
v <<= 8;
}
tmp = (unsigned long)p - (unsigned long)asn;
return (int) tmp;
}
int
snmpCounter::encode(char *a, unsigned int len)
{
setAsn(a, len);
return encode();
}
int
snmpCounter::decode(void)
{
if (asn == 0 || asnLength == 0)
return 0;
char *p = asn;
tag = *p++;
if (tag != TAG_COUNTER)
return 0; // Wrong tag
if (asnLength == 1)
return 0;
unsigned int len;
int llen = decodeLength(&p, len);
if (llen == 0)
return 0; // Bad length
if (len > asnLength - llen)
return 0; // End of ASN string
for (unsigned int size = sizeof(int); len > size; len--) {
if (*p++ != 0)
return 0; // Too big!
}
if (len > 0) {
unsigned int result = (*p & 0x80) ? -1 : 0;
for ( ; len != 0; len--)
result = (result << 8) | *p++;
unsigned long tmp = result;
value = (void *) tmp;
} else
value = 0;
unsigned long tmp = (unsigned long)p - (unsigned long)asn;
return (int) tmp;
}
int
snmpCounter::decode(char *a, unsigned int len)
{
setAsn(a, len);
return decode();
}
asnObject *
snmpCounter::dup(void)
{
return new snmpCounter(getValue());
}
char *
snmpCounter::getString(void)
{
char *s = new char[12];
sprintf(s, "%u", value);
return s;
}
/*
* SNMP Gauge class
*/
snmpGauge::snmpGauge(void)
{
}
snmpGauge::snmpGauge(unsigned int i)
{
setValue(i);
}
snmpGauge::~snmpGauge(void)
{
}
void
snmpGauge::setValue(unsigned int i)
{
unsigned long tmp = i;
value = (void *) tmp;
tag = TAG_GAUGE;
}
void
snmpGauge::setValue(asnObject *a)
{
*this = *((snmpGauge *) a);
}
unsigned int
snmpGauge::getValue(void)
{
unsigned long tmp = (unsigned long) value;
return (unsigned int) tmp;
}
int
snmpGauge::encode(void)
{
if (asn == 0 || asnLength < 2)
return 0;
char *p = asn;
*p++ = tag; // Fill in the tag value
/*
* Send the least number of bytes necessary to hold a signed number
* most significant byte first. Bit 8 of the first byte must
* be zero if the number is positive.
*/
unsigned long tmp = (unsigned long)value;
unsigned int v = (unsigned int) tmp;
unsigned int len = sizeof(int);
unsigned int shift = 8 * (len - 1);
unsigned int mask = 0x1FF << (shift - 1);
while ( ((mask & v) == 0 || (mask & v) == mask) && len > 1) {
v <<= 8;
len--;
}
int llen = encodeLength(&p, len);
if (llen == 0)
return 0; // Bad length
if (len > asnLength - llen)
return 0; // End of ASN string
while (len-- != 0) {
*p++ = v >> shift;
v <<= 8;
}
tmp = (unsigned long)p - (unsigned long)asn;
return (int)tmp;
}
int
snmpGauge::encode(char *a, unsigned int len)
{
setAsn(a, len);
return encode();
}
int
snmpGauge::decode(void)
{
if (asn == 0 || asnLength == 0)
return 0;
char *p = asn;
tag = *p++;
if (tag != TAG_GAUGE)
return 0; // Wrong tag
if (asnLength == 1)
return 0;
unsigned int len;
int llen = decodeLength(&p, len);
if (llen == 0)
return 0; // Bad length
if (len > asnLength - llen)
return 0; // End of ASN string
for (unsigned int size = sizeof(int); len > size; len--) {
if (*p++ != 0)
return 0; // Too big!
}
if (len > 0) {
unsigned int result = (*p & 0x80) ? -1 : 0;
for ( ; len != 0; len--)
result = (result << 8) | *p++;
unsigned long tmp = result;
value = (void *) tmp;
} else
value = 0;
unsigned long tmp = (unsigned long)p - (unsigned long)asn;
return (int) tmp;
}
int
snmpGauge::decode(char *a, unsigned int len)
{
setAsn(a, len);
return decode();
}
asnObject *
snmpGauge::dup(void)
{
return new snmpGauge(getValue());
}
char *
snmpGauge::getString(void)
{
char *s = new char[12];
sprintf(s, "%u", value);
return s;
}
/*
* SNMP Timeticks class
*/
snmpTimeticks::snmpTimeticks(void)
{
}
snmpTimeticks::snmpTimeticks(int i)
{
setValue(i);
}
snmpTimeticks::~snmpTimeticks(void)
{
}
void
snmpTimeticks::setValue(int i)
{
long tmp = i;
value = (void *) tmp;
tag = TAG_TIMETICKS;
}
void
snmpTimeticks::setValue(asnObject *a)
{
*this = *((snmpTimeticks *) a);
}
int
snmpTimeticks::getValue(void)
{
unsigned long tmp = (unsigned long) value;
return (unsigned int) tmp;
}
int
snmpTimeticks::encode(void)
{
if (asn == 0 || asnLength < 2)
return 0;
char *p = asn;
*p++ = tag; // Fill in the tag value
/*
* Send the least number of bytes necessary to hold a signed number
* most significant byte first. Bit 8 of the first byte must
* be zero if the number is positive.
*/
unsigned long tmp = (unsigned long) value;
unsigned int v = (unsigned int) tmp;
unsigned int len = sizeof(int);
unsigned int shift = 8 * (len - 1);
unsigned int mask = 0x1FF << (shift - 1);
while ( ((mask & v) == 0 || (mask & v) == mask) && len > 1) {
v <<= 8;
len--;
}
int llen = encodeLength(&p, len);
if (llen == 0)
return 0; // Bad length
if (len > asnLength - llen)
return 0; // End of ASN string
while (len-- != 0) {
*p++ = v >> shift;
v <<= 8;
}
tmp = (unsigned long)p - (unsigned long)asn;
return (int) tmp;
}
int
snmpTimeticks::encode(char *a, unsigned int len)
{
setAsn(a, len);
return encode();
}
int
snmpTimeticks::decode(void)
{
if (asn == 0 || asnLength == 0)
return 0;
char *p = asn;
tag = *p++;
if (tag != TAG_TIMETICKS)
return 0; // Wrong tag
if (asnLength == 1)
return 0;
unsigned int len;
int llen = decodeLength(&p, len);
if (llen == 0)
return 0; // Bad length
if (len > asnLength - llen)
return 0; // End of ASN string
for (unsigned int size = sizeof(int); len > size; len--) {
if (*p++ != 0)
return 0; // Too big!
}
if (len > 0) {
unsigned int result = (*p & 0x80) ? -1 : 0;
for ( ; len != 0; len--)
result = (result << 8) | *p++;
unsigned long tmp = result;
value = (void *) tmp;
} else
value = 0;
unsigned long tmp = (unsigned long)p -(unsigned long)asn;
return (int) tmp;
}
int
snmpTimeticks::decode(char *a, unsigned int len)
{
setAsn(a, len);
return decode();
}
asnObject *
snmpTimeticks::dup(void)
{
return new snmpTimeticks(getValue());
}
char *
snmpTimeticks::getString(void)
{
char *s = new char[32];
unsigned long tmp = (unsigned long)value;
unsigned int t = (unsigned int) tmp / 100;
unsigned int days = t / (24 * 60 * 60);
unsigned int hours = t % (24 * 60 * 60) / (60 * 60);
unsigned int minutes = t % (60 * 60) / 60;
unsigned int seconds = t % 60;
unsigned int hundreths = (unsigned int) tmp % 100;
if (days > 0)
sprintf(s, "%d day%s, %02d:%02d:%02d.%02d",
days, (days == 1) ? "" : "s", hours, minutes, seconds, hundreths);
else
sprintf(s, "%02d:%02d:%02d.%02d", hours, minutes, seconds, hundreths);
return s;
}