2 * Copyright (c) 2006 The FreeBSD Project
5 * Author: Shteryana Shopova <syrinx@FreeBSD.org>
7 * Redistribution of this software and documentation and use in source and
8 * binary forms, with or without modification, are permitted provided that
9 * the following conditions are met:
11 * 1. Redistributions of source code or documentation must retain the above
12 * copyright notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * Textual conventions for OctetStrings
34 #include <sys/param.h>
35 #include <sys/queue.h>
36 #include <sys/socket.h>
49 #include <arpa/inet.h>
50 #include <netinet/in.h>
52 #include <bsnmp/asn1.h>
53 #include <bsnmp/snmp.h>
55 #include "bsnmptools.h"
57 /* OctetString, DisplayString */
58 static char *snmp_oct2str(uint32_t, char *, char *);
59 static char *snmp_str2asn_oid(char *, struct asn_oid *);
60 static int parse_octetstring(struct snmp_value *, char *);
63 static char *snmp_octstr2date(uint32_t, char *, char *);
64 static char *snmp_date2asn_oid(char * , struct asn_oid *);
65 static int parse_dateandtime(struct snmp_value *, char *);
68 static char *snmp_oct2physAddr(uint32_t, char *, char *);
69 static char *snmp_addr2asn_oid(char *, struct asn_oid *);
70 static int parse_physaddress(struct snmp_value *, char *);
73 static char *snmp_oct2ntp_ts(uint32_t, char *, char *);
74 static char *snmp_ntp_ts2asn_oid(char *, struct asn_oid *);
75 static int parse_ntp_ts(struct snmp_value *, char *);
78 static char *snmp_oct2bridgeid(uint32_t, char *, char *);
79 static char *snmp_bridgeid2oct(char *, struct asn_oid *);
80 static int parse_bridge_id(struct snmp_value *, char *);
83 static char *snmp_oct2bport_id(uint32_t, char *, char *);
84 static char *snmp_bport_id2oct(char *, struct asn_oid *);
85 static int parse_bport_id(struct snmp_value *, char *);
88 static char *snmp_oct2inetaddr(uint32_t len, char *octets, char *buf);
89 static char *snmp_inetaddr2oct(char *str, struct asn_oid *oid);
90 static int32_t parse_inetaddr(struct snmp_value *value, char *string);
92 static char *snmp_oct2bits(uint32_t len, char *octets, char *buf);
93 static char *snmp_bits2oct(char *str, struct asn_oid *oid);
94 static int32_t parse_bits(struct snmp_value *value, char *string);
96 struct snmp_text_conv {
100 snmp_oct2tc_f oct2tc;
101 snmp_tc2oid_f tc2oid;
102 snmp_tc2oct_f tc2oct;
104 { SNMP_STRING, "OctetString", SNMP_VAR_STRSZ,
105 snmp_oct2str, snmp_str2asn_oid, parse_octetstring },
107 { SNMP_DISPLAYSTRING, "DisplayString" , SNMP_VAR_STRSZ,
108 snmp_oct2str, snmp_str2asn_oid, parse_octetstring },
110 { SNMP_DATEANDTIME, "DateAndTime", SNMP_DATETIME_STRSZ,
111 snmp_octstr2date, snmp_date2asn_oid, parse_dateandtime },
113 { SNMP_PHYSADDR, "PhysAddress", SNMP_PHYSADDR_STRSZ,
114 snmp_oct2physAddr, snmp_addr2asn_oid, parse_physaddress },
116 { SNMP_ATMESI, "AtmESI", SNMP_PHYSADDR_STRSZ,
117 snmp_oct2physAddr, snmp_addr2asn_oid, parse_physaddress },
119 { SNMP_NTP_TIMESTAMP, "NTPTimeStamp", SNMP_NTP_TS_STRSZ,
120 snmp_oct2ntp_ts, snmp_ntp_ts2asn_oid, parse_ntp_ts },
122 { SNMP_MACADDRESS, "MacAddress", SNMP_PHYSADDR_STRSZ,
123 snmp_oct2physAddr, snmp_addr2asn_oid, parse_physaddress },
125 { SNMP_BRIDGE_ID, "BridgeId", SNMP_BRIDGEID_STRSZ,
126 snmp_oct2bridgeid, snmp_bridgeid2oct, parse_bridge_id },
128 { SNMP_BPORT_ID, "BridgePortId", SNMP_BPORT_STRSZ,
129 snmp_oct2bport_id, snmp_bport_id2oct, parse_bport_id },
131 { SNMP_INETADDRESS, "InetAddress", SNMP_INADDRS_STRSZ,
132 snmp_oct2inetaddr, snmp_inetaddr2oct, parse_inetaddr },
134 { SNMP_TC_OWN, "BITS", SNMP_VAR_STRSZ,
135 snmp_oct2bits, snmp_bits2oct, parse_bits },
137 { SNMP_UNKNOWN, "Unknown", SNMP_VAR_STRSZ, snmp_oct2str,
138 snmp_str2asn_oid, parse_octetstring } /* keep last */
143 snmp_get_tc(char *str)
146 for (i = 0; i < SNMP_UNKNOWN; i++) {
147 if (!strncmp(text_convs[i].tc_str, str,
148 strlen(text_convs[i].tc_str)))
149 return (text_convs[i].tc);
152 return (SNMP_STRING);
156 snmp_oct2tc(enum snmp_tc tc, uint32_t len, char *octets)
161 if (tc < 0 || tc > SNMP_UNKNOWN)
164 if (text_convs[tc].len > 0)
165 tc_len = text_convs[tc].len;
167 tc_len = 2 * len + 3;
169 if ((buf = malloc(tc_len)) == NULL ) {
170 syslog(LOG_ERR, "malloc failed - %s", strerror(errno));
174 memset(buf, 0, tc_len);
175 if (text_convs[tc].oct2tc(len, octets, buf) == NULL) {
184 snmp_tc2oid(enum snmp_tc tc, char *str, struct asn_oid *oid)
186 if (tc < 0 || tc > SNMP_UNKNOWN)
189 return (text_convs[tc].tc2oid(str, oid));
193 snmp_tc2oct(enum snmp_tc tc, struct snmp_value *value, char *string)
195 if (tc < 0 || tc > SNMP_UNKNOWN)
198 return (text_convs[tc].tc2oct(value, string));
201 /*****************************************************
202 * Basic OctetString type.
205 snmp_oct2str(uint32_t len, char *octets, char *buf)
211 if (len > MAX_OCTSTRING_LEN || octets == NULL || buf == NULL)
214 for (ptr = buf, i = 0; i < len; i++)
215 if (!isprint(octets[i])) {
217 buf += sprintf(buf, "0x");
221 for (ptr = buf, i = 0; i < len; i++)
223 ptr += sprintf(ptr, "%c", octets[i]);
225 ptr += sprintf(ptr, "%2.2x", (u_char)octets[i]);
231 snmp_str2asn_oid(char *str, struct asn_oid *oid)
236 * OctetStrings are allowed max length of ASN_MAXOCTETSTRING,
237 * but trying to index an entry with such a long OctetString
240 for (len = 0; len < ASN_MAXOIDLEN; len++) {
241 if (strchr(",]", *(str + len)) != NULL)
245 if (len >= ASN_MAXOIDLEN)
248 if (snmp_suboid_append(oid, (asn_subid_t) len) < 0)
251 for (i = 0; i < len; i++)
252 if (snmp_suboid_append(oid, (asn_subid_t) *(str + i)) < 0)
259 parse_octetstring(struct snmp_value *value, char *val)
263 if ((len = strlen(val)) >= MAX_OCTSTRING_LEN) {
264 warnx("Octetstring too long - %d is max allowed",
265 MAX_OCTSTRING_LEN - 1);
269 value->v.octetstring.len = len;
271 if((value->v.octetstring.octets = malloc(len)) == NULL) {
272 syslog(LOG_ERR,"malloc failed: %s", strerror(errno));
276 memcpy(value->v.octetstring.octets, val, len);
277 value->syntax = SNMP_SYNTAX_OCTETSTRING;
282 /*************************************************************
284 *************************************************************
285 * rfc 2579 specification:
286 * DateAndTime ::= TEXTUAL-CONVENTION
287 * DISPLAY-HINT "2d-1d-1d,1d:1d:1d.1d,1a1d:1d"
290 * "A date-time specification.
292 * field octets contents range
293 * ----- ------ -------- -----
294 * 1 1-2 year* 0..65536
300 * (use 60 for leap-second)
301 * 7 8 deci-seconds 0..9
302 * 8 9 direction from UTC '+' / '-'
303 * 9 10 hours from UTC* 0..13
304 * 10 11 minutes from UTC 0..59
307 * - the value of year is in network-byte order
308 * - daylight saving time in New Zealand is +13
310 * For example, Tuesday May 26, 1992 at 1:30:15 PM EDT would be
313 * 1992-5-26,13:30:15.0,-4:0
316 snmp_octstr2date(uint32_t len, char *octets, char *buf)
321 if (len != SNMP_DATETIME_OCTETS || octets == NULL || buf == NULL)
325 year = (octets[0] << 8);
329 ptr += sprintf(ptr, "%4.4d-%.2d-%.2d, ", year, octets[2],octets[3]);
330 ptr += sprintf(ptr, "%2.2d:%2.2d:%2.2d.%.2d, ", octets[4],octets[5],
331 octets[6],octets[7]);
332 ptr += sprintf(ptr, "%c%.2d:%.2d", octets[8],octets[9],octets[10]);
338 snmp_date2asn_oid(char *str, struct asn_oid *oid)
344 if (snmp_suboid_append(oid, (asn_subid_t) SNMP_DATETIME_OCTETS) < 0)
347 /* Read 'YYYY-' and write it in two subs. */
351 v = strtoul(ptr, &endptr, 10);
358 if (snmp_suboid_append(oid, (asn_subid_t) ((v & 0xff00) >> 8)) < 0)
360 if (snmp_suboid_append(oid, (asn_subid_t) (v & 0xff)) < 0)
366 v = strtoul(ptr, &endptr, 10);
373 if (snmp_suboid_append(oid, (asn_subid_t) v) < 0)
379 v = strtoul(ptr, &endptr, 10);
386 if (snmp_suboid_append(oid, (asn_subid_t) v) < 0)
392 v = strtoul(ptr, &endptr, 10);
399 if (snmp_suboid_append(oid, (asn_subid_t) v) < 0)
405 v = strtoul(ptr, &endptr, 10);
412 if (snmp_suboid_append(oid, (asn_subid_t) v) < 0)
418 v = strtoul(ptr, &endptr, 10);
425 if (snmp_suboid_append(oid, (asn_subid_t) v) < 0)
431 v = strtoul(ptr, &endptr, 10);
438 if (snmp_suboid_append(oid, (asn_subid_t) v) < 0)
441 /* 'UTC' - optional */
443 if (*ptr == 'U' && *(ptr + 1) == 'T' && *(ptr + 1) == 'C')
447 if (*ptr == '-' || *ptr == '+') {
448 if (snmp_suboid_append(oid, (asn_subid_t) (*ptr)) < 0)
456 v = strtoul(ptr, &endptr, 10);
463 if (snmp_suboid_append(oid, (asn_subid_t) v) < 0)
466 /* 'MM' - last one - ignore endptr here. */
469 v = strtoul(ptr, &endptr, 10);
474 if (snmp_suboid_append(oid, (asn_subid_t) v) < 0)
482 warnx("Date value %s not supported", str);
486 /* Read a DateAndTime string eg. 1992-5-26,13:30:15.0,-4:0. */
488 parse_dateandtime(struct snmp_value *sv, char *val)
492 uint8_t date[SNMP_DATETIME_OCTETS];
495 v = strtoul(val, &endptr, 10);
496 if (v > 0xffff || *endptr != '-')
498 date[0] = ((v & 0xff00) >> 8);
499 date[1] = (v & 0xff);
503 v = strtoul(val, &endptr, 10);
504 if (v == 0 || v > 12 || *endptr != '-')
510 v = strtoul(val, &endptr, 10);
511 if (v == 0 || v > 31 || *endptr != ',')
517 v = strtoul(val, &endptr, 10);
518 if (v > 23 || *endptr != ':')
524 v = strtoul(val, &endptr, 10);
525 if (v > 59 || *endptr != ':')
531 v = strtoul(val, &endptr, 10);
532 if (v > 60 || *endptr != '.')
538 v = strtoul(val, &endptr, 10);
539 if (v > 9 || *endptr != ',')
545 if (*val != '-' && *val != '+')
547 date[8] = (uint8_t) *val;
550 /* 'HH:' - offset from UTC */
551 v = strtoul(val, &endptr, 10);
552 if (v > 13 || *endptr != ':')
557 /* 'MM'\0'' offset from UTC */
558 v = strtoul(val, &endptr, 10);
559 if (v > 59 || *endptr != '\0')
563 if ((sv->v.octetstring.octets = malloc(SNMP_DATETIME_OCTETS)) == NULL) {
564 warnx("malloc() failed - %s", strerror(errno));
568 sv->v.octetstring.len = SNMP_DATETIME_OCTETS;
569 memcpy(sv->v.octetstring.octets, date, SNMP_DATETIME_OCTETS);
570 sv->syntax = SNMP_SYNTAX_OCTETSTRING;
574 warnx("Date value %s not supported", val);
578 /**************************************************************
582 snmp_oct2physAddr(uint32_t len, char *octets, char *buf)
587 if (len != SNMP_PHYSADDR_OCTETS || octets == NULL || buf == NULL)
593 ptr += sprintf(ptr, "%2.2x", octets[0]);
594 for (i = 1; i < 6; i++)
595 ptr += sprintf(ptr, ":%2.2x", octets[i]);
601 snmp_addr2asn_oid(char *str, struct asn_oid *oid)
607 if (snmp_suboid_append(oid, (asn_subid_t) SNMP_PHYSADDR_OCTETS) < 0)
611 for (i = 0; i < 5; i++) {
613 v = strtoul(ptr, &endptr, 16);
616 warnx("Integer value %s not supported", str);
619 if (*endptr != ':') {
620 warnx("Failed adding oid - %s",str);
623 if (snmp_suboid_append(oid, (asn_subid_t) v) < 0)
628 /* The last one - don't check the ending char here. */
630 v = strtoul(ptr, &endptr, 16);
633 warnx("Integer value %s not supported", str);
636 if (snmp_suboid_append(oid, (asn_subid_t) v) < 0)
643 parse_physaddress(struct snmp_value *sv, char *val)
648 uint8_t phys_addr[SNMP_PHYSADDR_OCTETS];
650 for (i = 0; i < 5; i++) {
651 v = strtoul(val, &endptr, 16);
653 warnx("Integer value %s not supported", val);
657 warnx("Failed reading octet - %s", val);
664 /* The last one - don't check the ending char here. */
665 v = strtoul(val, &endptr, 16);
667 warnx("Integer value %s not supported", val);
672 if ((sv->v.octetstring.octets = malloc(SNMP_PHYSADDR_OCTETS)) == NULL) {
673 syslog(LOG_ERR,"malloc failed: %s", strerror(errno));
677 sv->v.octetstring.len = SNMP_PHYSADDR_OCTETS;
678 memcpy(sv->v.octetstring.octets, phys_addr, SNMP_PHYSADDR_OCTETS);
679 sv->syntax = SNMP_SYNTAX_OCTETSTRING;
683 /**************************************************************
685 **************************************************************
686 * NTP MIB, Revision 0.2, 7/25/97:
687 * NTPTimeStamp ::= TEXTUAL-CONVENTION
688 * DISPLAY-HINT "4x.4x"
692 * SYNTAX OCTET STRING (SIZE(8))
695 snmp_oct2ntp_ts(uint32_t len, char *octets, char *buf)
700 if (len != SNMP_NTP_TS_OCTETS || octets == NULL || buf == NULL)
706 i = octets[0] * 1000 + octets[1] * 100 + octets[2] * 10 + octets[3];
707 ptr += sprintf(ptr, "%4.4d", i);
708 i = octets[4] * 1000 + octets[5] * 100 + octets[6] * 10 + octets[7];
709 ptr += sprintf(ptr, ".%4.4d", i);
715 snmp_ntp_ts2asn_oid(char *str, struct asn_oid *oid)
719 struct asn_oid suboid;
722 if (snmp_suboid_append(oid, (asn_subid_t) SNMP_NTP_TS_OCTETS) < 0)
727 v = strtoul(ptr, &endptr, 10);
728 if (errno != 0 || (v / 1000) > 9) {
729 warnx("Integer value %s not supported", str);
735 if (*endptr != '.') {
736 warnx("Failed adding oid - %s",str);
740 memset(&suboid, 0, sizeof(struct asn_oid));
741 suboid.len = SNMP_NTP_TS_OCTETS;
743 for (i = 0, d = 1000; i < 4; i++) {
744 suboid.subs[i] = v / d;
751 v = strtoul(ptr, &endptr, 10);
752 if (errno != 0 || (v / 1000) > 9) {
753 warnx("Integer value %s not supported", str);
759 for (i = 0, d = 1000; i < 4; i++) {
760 suboid.subs[i + 4] = v / d;
765 asn_append_oid(oid, &suboid);
770 parse_ntp_ts(struct snmp_value *sv, char *val)
773 int32_t i, d, saved_errno;
775 uint8_t ntp_ts[SNMP_NTP_TS_OCTETS];
778 v = strtoul(val, &endptr, 10);
779 if (errno != 0 || (v / 1000) > 9) {
781 warnx("Integer value %s not supported", val);
786 if (*endptr != '.') {
787 warnx("Failed reading octet - %s", val);
791 for (i = 0, d = 1000; i < 4; i++) {
799 v = strtoul(val, &endptr, 10);
800 if (errno != 0 || (v / 1000) > 9) {
802 warnx("Integer value %s not supported", val);
807 for (i = 0, d = 1000; i < 4; i++) {
808 ntp_ts[i + 4] = v / d;
813 if ((sv->v.octetstring.octets = malloc(SNMP_NTP_TS_OCTETS)) == NULL) {
814 syslog(LOG_ERR,"malloc failed: %s", strerror(errno));
818 sv->v.octetstring.len = SNMP_NTP_TS_OCTETS;
819 memcpy(sv->v.octetstring.octets, ntp_ts, SNMP_NTP_TS_OCTETS);
820 sv->syntax = SNMP_SYNTAX_OCTETSTRING;
824 /**************************************************************
826 **************************************************************
827 * BRIDGE-MIB, REVISION "200509190000Z"
828 * BridgeId ::= TEXTUAL-CONVENTION
831 * "The Bridge-Identifier, as used in the Spanning Tree
832 * Protocol, to uniquely identify a bridge. Its first two
833 * octets (in network byte order) contain a priority value,
834 * and its last 6 octets contain the MAC address used to
835 * refer to a bridge in a unique fashion (typically, the
836 * numerically smallest MAC address of all ports on the
838 * SYNTAX OCTET STRING (SIZE (8))
841 snmp_oct2bridgeid(uint32_t len, char *octets, char *buf)
844 uint32_t i, priority;
846 if (len != SNMP_BRIDGEID_OCTETS || octets == NULL || buf == NULL)
852 priority = octets[0] << 8;
853 priority += octets[1];
854 if (priority > SNMP_MAX_BRIDGE_PRIORITY) {
855 warnx("Invalid bridge priority %d", priority);
858 ptr += sprintf(ptr, "%d.", octets[0]);
860 ptr += sprintf(ptr, "%2.2x", octets[2]);
862 for (i = 1; i < 6; i++)
863 ptr += sprintf(ptr, ":%2.2x", octets[i + 2]);
869 snmp_bridgeid2oct(char *str, struct asn_oid *oid)
875 if (snmp_suboid_append(oid, (asn_subid_t) SNMP_BRIDGEID_OCTETS) < 0)
879 /* Read the priority. */
881 v = strtoul(ptr, &endptr, 10);
884 if (v > SNMP_MAX_BRIDGE_PRIORITY || errno != 0 || *endptr != '.') {
886 warnx("Bad bridge priority value %d", v);
890 if (snmp_suboid_append(oid, (asn_subid_t) (v & 0xff00)) < 0)
893 if (snmp_suboid_append(oid, (asn_subid_t) (v & 0xff)) < 0)
897 for (i = 0; i < 5; i++) {
899 v = strtoul(ptr, &endptr, 16);
902 warnx("Integer value %s not supported", str);
905 if (*endptr != ':') {
906 warnx("Failed adding oid - %s",str);
909 if (snmp_suboid_append(oid, (asn_subid_t) v) < 0)
914 /* The last one - don't check the ending char here. */
916 v = strtoul(ptr, &endptr, 16);
919 warnx("Integer value %s not supported", str);
922 if (snmp_suboid_append(oid, (asn_subid_t) v) < 0)
929 parse_bridge_id(struct snmp_value *sv, char *string)
932 int32_t i, saved_errno;
934 uint8_t bridge_id[SNMP_BRIDGEID_OCTETS];
937 /* Read the priority. */
940 v = strtoul(string, &endptr, 10);
943 if (v > SNMP_MAX_BRIDGE_PRIORITY || errno != 0 || *endptr != '.') {
945 warnx("Bad bridge priority value %d", v);
949 bridge_id[0] = (v & 0xff00);
950 bridge_id[1] = (v & 0xff);
954 for (i = 0; i < 5; i++) {
955 v = strtoul(string, &endptr, 16);
957 warnx("Integer value %s not supported", string);
961 warnx("Failed reading octet - %s", string);
964 bridge_id[i + 2] = v;
968 /* The last one - don't check the ending char here. */
969 v = strtoul(string, &endptr, 16);
971 warnx("Integer value %s not supported", string);
976 if ((sv->v.octetstring.octets = malloc(SNMP_BRIDGEID_OCTETS)) == NULL) {
977 syslog(LOG_ERR,"malloc failed: %s", strerror(errno));
981 sv->v.octetstring.len = SNMP_BRIDGEID_OCTETS;
982 memcpy(sv->v.octetstring.octets, bridge_id, SNMP_BRIDGEID_OCTETS);
983 sv->syntax = SNMP_SYNTAX_OCTETSTRING;
987 /**************************************************************
989 **************************************************************
990 * BEGEMOT-BRIDGE-MIB, LAST-UPDATED "200608100000Z"
991 * BridgePortId ::= TEXTUAL-CONVENTION
992 * DISPLAY-HINT "1x.1x"
995 * "A port identifier that contains a bridge port's STP priority
996 * in the first octet and the port number in the second octet."
997 * SYNTAX OCTET STRING (SIZE(2))
1000 snmp_oct2bport_id(uint32_t len, char *octets, char *buf)
1004 if (len != SNMP_BPORT_OCTETS || octets == NULL || buf == NULL)
1010 ptr += sprintf(ptr, "%d.", octets[0]);
1011 ptr += sprintf(ptr, "%d", octets[1]);
1017 snmp_bport_id2oct(char *str, struct asn_oid *oid)
1023 if (snmp_suboid_append(oid, (asn_subid_t) SNMP_BPORT_OCTETS) < 0)
1027 /* Read the priority. */
1028 saved_errno = errno;
1029 v = strtoul(ptr, &endptr, 10);
1032 if (v > SNMP_MAX_BPORT_PRIORITY || errno != 0 || *endptr != '.') {
1033 errno = saved_errno;
1034 warnx("Bad bridge port priority value %d", v);
1038 if (snmp_suboid_append(oid, (asn_subid_t) v) < 0)
1041 saved_errno = errno;
1042 v = strtoul(ptr, &endptr, 16);
1043 errno = saved_errno;
1046 warnx("Bad port number - %d", v);
1050 if (snmp_suboid_append(oid, (asn_subid_t) v) < 0)
1057 parse_bport_id(struct snmp_value *value, char *string)
1062 uint8_t bport_id[SNMP_BPORT_OCTETS];
1065 /* Read the priority. */
1066 saved_errno = errno;
1068 v = strtoul(string, &endptr, 10);
1069 errno = saved_errno;
1071 if (v > SNMP_MAX_BPORT_PRIORITY || errno != 0 || *endptr != '.') {
1072 errno = saved_errno;
1073 warnx("Bad bridge port priority value %d", v);
1079 string = endptr + 1;
1080 v = strtoul(string, &endptr, 16);
1082 warnx("Bad port number - %d", v);
1088 if ((value->v.octetstring.octets = malloc(SNMP_BPORT_OCTETS)) == NULL) {
1089 syslog(LOG_ERR,"malloc failed: %s", strerror(errno));
1093 value->v.octetstring.len = SNMP_BPORT_OCTETS;
1094 memcpy(value->v.octetstring.octets, bport_id, SNMP_BPORT_OCTETS);
1095 value->syntax = SNMP_SYNTAX_OCTETSTRING;
1098 /**************************************************************
1100 **************************************************************
1101 * INET-ADDRESS-MIB, REVISION "200502040000Z"
1102 * InetAddress ::= TEXTUAL-CONVENTION
1105 * "Denotes a generic Internet address.
1107 * An InetAddress value is always interpreted within the context
1108 * of an InetAddressType value. Every usage of the InetAddress
1109 * textual convention is required to specify the InetAddressType
1110 * object that provides the context. It is suggested that the
1111 * InetAddressType object be logically registered before the
1112 * object(s) that use the InetAddress textual convention, if
1113 * they appear in the same logical row.
1115 * The value of an InetAddress object must always be
1116 * consistent with the value of the associated InetAddressType
1117 * object. Attempts to set an InetAddress object to a value
1118 * inconsistent with the associated InetAddressType
1119 * must fail with an inconsistentValue error.
1121 * When this textual convention is used as the syntax of an
1122 * index object, there may be issues with the limit of 128
1123 * sub-identifiers specified in SMIv2, STD 58. In this case,
1124 * the object definition MUST include a 'SIZE' clause to
1125 * limit the number of potential instance sub-identifiers;
1126 * otherwise the applicable constraints MUST be stated in
1127 * the appropriate conceptual row DESCRIPTION clauses, or
1128 * in the surrounding documentation if there is no single
1129 * DESCRIPTION clause that is appropriate."
1130 * SYNTAX OCTET STRING (SIZE (0..255))
1131 **************************************************************
1132 * TODO: FIXME!!! syrinx: Since we do not support checking the
1133 * consistency of a varbinding based on the value of a previous
1134 * one, try to guess the type of address based on the
1135 * OctetString SIZE - 4 for IPv4, 16 for IPv6, others currently
1139 snmp_oct2inetaddr(uint32_t len, char *octets, char *buf)
1143 struct in_addr ipv4;
1144 struct in6_addr ipv6;
1146 if (len > MAX_OCTSTRING_LEN || octets == NULL || buf == NULL)
1150 /* XXX: FIXME - IPv4*/
1152 memcpy(&ipv4.s_addr, octets, sizeof(ipv4.s_addr));
1157 /* XXX: FIXME - IPv4*/
1159 memcpy(ipv6.s6_addr, octets, sizeof(ipv6.s6_addr));
1168 if (inet_ntop(af, ip, buf, SNMP_INADDRS_STRSZ) == NULL) {
1169 warnx("inet_ntop failed - %s", strerror(errno));
1177 snmp_inetaddr2oct(char *str, struct asn_oid *oid)
1183 parse_inetaddr(struct snmp_value *value, char *string)
1188 /**************************************************************
1189 * SNMP BITS type - XXX: FIXME
1190 **************************************************************/
1192 snmp_oct2bits(uint32_t len, char *octets, char *buf)
1197 if (len > sizeof(value) || octets == NULL || buf == NULL)
1200 for (i = len, value = 0, bits = 0; i > 0; i--, bits += 8)
1201 value += octets[i] << bits;
1204 sprintf(buf, "0x%llx.",(long long unsigned) value);
1210 snmp_bits2oct(char *str, struct asn_oid *oid)
1213 int i, size, bits, saved_errno;
1214 uint64_t v, mask = 0xFF00000000000000;
1216 saved_errno = errno;
1219 v = strtoull(str, &endptr, 16);
1221 warnx("Bad BITS value %s - %s", str, strerror(errno));
1222 errno = saved_errno;
1227 /* Determine length - up to 8 octets supported so far. */
1228 for (size = sizeof(v); size > 0; size--) {
1229 if ((v & mask) != 0)
1231 mask = mask >> bits;
1237 if (snmp_suboid_append(oid, (asn_subid_t) size) < 0)
1240 for (i = 0, bits = 0; i < size; i++, bits += 8)
1241 if (snmp_suboid_append(oid,
1242 (asn_subid_t)((v & mask) >> bits)) < 0)
1249 parse_bits(struct snmp_value *value, char *string)
1252 int i, size, bits, saved_errno;
1253 uint64_t v, mask = 0xFF00000000000000;
1255 saved_errno = errno;
1258 v = strtoull(string, &endptr, 16);
1261 warnx("Bad BITS value %s - %s", string, strerror(errno));
1262 errno = saved_errno;
1267 /* Determine length - up to 8 octets supported so far. */
1268 for (size = sizeof(v); size > 0; size--) {
1269 if ((v & mask) != 0)
1271 mask = mask >> bits;
1277 if ((value->v.octetstring.octets = malloc(size)) == NULL) {
1278 syslog(LOG_ERR, "malloc failed: %s", strerror(errno));
1282 value->v.octetstring.len = size;
1283 for (i = 0, bits = 0; i < size; i++, bits += 8)
1284 value->v.octetstring.octets[i] = (v & mask) >> bits;
1285 value->syntax = SNMP_SYNTAX_OCTETSTRING;