1a7398723SShteryana Shopova /*- 2a7398723SShteryana Shopova * Copyright (c) 2006 The FreeBSD Project 3a7398723SShteryana Shopova * All rights reserved. 4a7398723SShteryana Shopova * 5a7398723SShteryana Shopova * Author: Shteryana Shopova <syrinx@FreeBSD.org> 6a7398723SShteryana Shopova * 7a7398723SShteryana Shopova * Redistribution of this software and documentation and use in source and 8a7398723SShteryana Shopova * binary forms, with or without modification, are permitted provided that 9a7398723SShteryana Shopova * the following conditions are met: 10a7398723SShteryana Shopova * 11a7398723SShteryana Shopova * 1. Redistributions of source code or documentation must retain the above 12a7398723SShteryana Shopova * copyright notice, this list of conditions and the following disclaimer. 13a7398723SShteryana Shopova * 2. Redistributions in binary form must reproduce the above copyright 14a7398723SShteryana Shopova * notice, this list of conditions and the following disclaimer in the 15a7398723SShteryana Shopova * documentation and/or other materials provided with the distribution. 16a7398723SShteryana Shopova * 17a7398723SShteryana Shopova * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18a7398723SShteryana Shopova * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19a7398723SShteryana Shopova * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20a7398723SShteryana Shopova * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21a7398723SShteryana Shopova * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22a7398723SShteryana Shopova * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23a7398723SShteryana Shopova * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24a7398723SShteryana Shopova * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25a7398723SShteryana Shopova * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26a7398723SShteryana Shopova * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27a7398723SShteryana Shopova * SUCH DAMAGE. 28a7398723SShteryana Shopova * 29a7398723SShteryana Shopova * Textual conventions for OctetStrings 30a7398723SShteryana Shopova * 31a7398723SShteryana Shopova * $FreeBSD$ 32a7398723SShteryana Shopova */ 33a7398723SShteryana Shopova 34a7398723SShteryana Shopova #include <sys/param.h> 35a7398723SShteryana Shopova #include <sys/queue.h> 36a7398723SShteryana Shopova #include <sys/socket.h> 37a7398723SShteryana Shopova #include <sys/uio.h> 38a7398723SShteryana Shopova 39a7398723SShteryana Shopova #include <ctype.h> 40a7398723SShteryana Shopova #include <err.h> 41a7398723SShteryana Shopova #include <errno.h> 42a7398723SShteryana Shopova #include <fcntl.h> 43a7398723SShteryana Shopova #include <stdio.h> 44a7398723SShteryana Shopova #include <stdlib.h> 45a7398723SShteryana Shopova #include <string.h> 46a7398723SShteryana Shopova #include <syslog.h> 47a7398723SShteryana Shopova #include <unistd.h> 48a7398723SShteryana Shopova 49a7398723SShteryana Shopova #include <arpa/inet.h> 50a7398723SShteryana Shopova #include <netinet/in.h> 51a7398723SShteryana Shopova 52a7398723SShteryana Shopova #include <bsnmp/asn1.h> 53a7398723SShteryana Shopova #include <bsnmp/snmp.h> 54a7398723SShteryana Shopova #include "bsnmptc.h" 55a7398723SShteryana Shopova #include "bsnmptools.h" 56a7398723SShteryana Shopova 57a7398723SShteryana Shopova /* OctetString, DisplayString */ 58a7398723SShteryana Shopova static char *snmp_oct2str(uint32_t, char *, char *); 59a7398723SShteryana Shopova static char *snmp_str2asn_oid(char *, struct asn_oid *); 60a7398723SShteryana Shopova static int parse_octetstring(struct snmp_value *, char *); 61a7398723SShteryana Shopova 62a7398723SShteryana Shopova /* DateAndTime */ 63a7398723SShteryana Shopova static char *snmp_octstr2date(uint32_t, char *, char *); 64a7398723SShteryana Shopova static char *snmp_date2asn_oid(char * , struct asn_oid *); 65a7398723SShteryana Shopova static int parse_dateandtime(struct snmp_value *, char *); 66a7398723SShteryana Shopova 67a7398723SShteryana Shopova /* PhysAddress */ 68a7398723SShteryana Shopova static char *snmp_oct2physAddr(uint32_t, char *, char *); 69a7398723SShteryana Shopova static char *snmp_addr2asn_oid(char *, struct asn_oid *); 70a7398723SShteryana Shopova static int parse_physaddress(struct snmp_value *, char *); 71a7398723SShteryana Shopova 72a7398723SShteryana Shopova /* NTPTimeStamp */ 73a7398723SShteryana Shopova static char *snmp_oct2ntp_ts(uint32_t, char *, char *); 74a7398723SShteryana Shopova static char *snmp_ntp_ts2asn_oid(char *, struct asn_oid *); 75a7398723SShteryana Shopova static int parse_ntp_ts(struct snmp_value *, char *); 76a7398723SShteryana Shopova 77a7398723SShteryana Shopova /* BridgeId */ 78a7398723SShteryana Shopova static char *snmp_oct2bridgeid(uint32_t, char *, char *); 79a7398723SShteryana Shopova static char *snmp_bridgeid2oct(char *, struct asn_oid *); 80a7398723SShteryana Shopova static int parse_bridge_id(struct snmp_value *, char *); 81a7398723SShteryana Shopova 82a7398723SShteryana Shopova /* BridgePortId */ 83a7398723SShteryana Shopova static char *snmp_oct2bport_id(uint32_t, char *, char *); 84a7398723SShteryana Shopova static char *snmp_bport_id2oct(char *, struct asn_oid *); 85a7398723SShteryana Shopova static int parse_bport_id(struct snmp_value *, char *); 86a7398723SShteryana Shopova 87a7398723SShteryana Shopova /* InetAddress */ 88a7398723SShteryana Shopova static char *snmp_oct2inetaddr(uint32_t len, char *octets, char *buf); 89a7398723SShteryana Shopova static char *snmp_inetaddr2oct(char *str, struct asn_oid *oid); 90a7398723SShteryana Shopova static int32_t parse_inetaddr(struct snmp_value *value, char *string); 91a7398723SShteryana Shopova 92a7398723SShteryana Shopova static char *snmp_oct2bits(uint32_t len, char *octets, char *buf); 93a7398723SShteryana Shopova static char *snmp_bits2oct(char *str, struct asn_oid *oid); 94a7398723SShteryana Shopova static int32_t parse_bits(struct snmp_value *value, char *string); 95a7398723SShteryana Shopova 960150b85aSEnji Cooper static struct snmp_text_conv { 97a7398723SShteryana Shopova enum snmp_tc tc; 98a7398723SShteryana Shopova const char *tc_str; 99a7398723SShteryana Shopova int32_t len; 100a7398723SShteryana Shopova snmp_oct2tc_f oct2tc; 101a7398723SShteryana Shopova snmp_tc2oid_f tc2oid; 102a7398723SShteryana Shopova snmp_tc2oct_f tc2oct; 103a7398723SShteryana Shopova } text_convs[] = { 104a7398723SShteryana Shopova { SNMP_STRING, "OctetString", SNMP_VAR_STRSZ, 105a7398723SShteryana Shopova snmp_oct2str, snmp_str2asn_oid, parse_octetstring }, 106a7398723SShteryana Shopova 107a7398723SShteryana Shopova { SNMP_DISPLAYSTRING, "DisplayString" , SNMP_VAR_STRSZ, 108a7398723SShteryana Shopova snmp_oct2str, snmp_str2asn_oid, parse_octetstring }, 109a7398723SShteryana Shopova 110a7398723SShteryana Shopova { SNMP_DATEANDTIME, "DateAndTime", SNMP_DATETIME_STRSZ, 111a7398723SShteryana Shopova snmp_octstr2date, snmp_date2asn_oid, parse_dateandtime }, 112a7398723SShteryana Shopova 113a7398723SShteryana Shopova { SNMP_PHYSADDR, "PhysAddress", SNMP_PHYSADDR_STRSZ, 114a7398723SShteryana Shopova snmp_oct2physAddr, snmp_addr2asn_oid, parse_physaddress }, 115a7398723SShteryana Shopova 116a7398723SShteryana Shopova { SNMP_ATMESI, "AtmESI", SNMP_PHYSADDR_STRSZ, 117a7398723SShteryana Shopova snmp_oct2physAddr, snmp_addr2asn_oid, parse_physaddress }, 118a7398723SShteryana Shopova 119a7398723SShteryana Shopova { SNMP_NTP_TIMESTAMP, "NTPTimeStamp", SNMP_NTP_TS_STRSZ, 120a7398723SShteryana Shopova snmp_oct2ntp_ts, snmp_ntp_ts2asn_oid, parse_ntp_ts }, 121a7398723SShteryana Shopova 122a7398723SShteryana Shopova { SNMP_MACADDRESS, "MacAddress", SNMP_PHYSADDR_STRSZ, 123a7398723SShteryana Shopova snmp_oct2physAddr, snmp_addr2asn_oid, parse_physaddress }, 124a7398723SShteryana Shopova 125a7398723SShteryana Shopova { SNMP_BRIDGE_ID, "BridgeId", SNMP_BRIDGEID_STRSZ, 126a7398723SShteryana Shopova snmp_oct2bridgeid, snmp_bridgeid2oct, parse_bridge_id }, 127a7398723SShteryana Shopova 128a7398723SShteryana Shopova { SNMP_BPORT_ID, "BridgePortId", SNMP_BPORT_STRSZ, 129a7398723SShteryana Shopova snmp_oct2bport_id, snmp_bport_id2oct, parse_bport_id }, 130a7398723SShteryana Shopova 131a7398723SShteryana Shopova { SNMP_INETADDRESS, "InetAddress", SNMP_INADDRS_STRSZ, 132a7398723SShteryana Shopova snmp_oct2inetaddr, snmp_inetaddr2oct, parse_inetaddr }, 133a7398723SShteryana Shopova 134a7398723SShteryana Shopova { SNMP_TC_OWN, "BITS", SNMP_VAR_STRSZ, 135a7398723SShteryana Shopova snmp_oct2bits, snmp_bits2oct, parse_bits }, 136a7398723SShteryana Shopova 137a7398723SShteryana Shopova { SNMP_UNKNOWN, "Unknown", SNMP_VAR_STRSZ, snmp_oct2str, 138a7398723SShteryana Shopova snmp_str2asn_oid, parse_octetstring } /* keep last */ 139a7398723SShteryana Shopova }; 140a7398723SShteryana Shopova 141a7398723SShteryana Shopova /* Common API */ 142a7398723SShteryana Shopova enum snmp_tc 143a7398723SShteryana Shopova snmp_get_tc(char *str) 144a7398723SShteryana Shopova { 145a7398723SShteryana Shopova int i; 146a7398723SShteryana Shopova for (i = 0; i < SNMP_UNKNOWN; i++) { 147a7398723SShteryana Shopova if (!strncmp(text_convs[i].tc_str, str, 148a7398723SShteryana Shopova strlen(text_convs[i].tc_str))) 149a7398723SShteryana Shopova return (text_convs[i].tc); 150a7398723SShteryana Shopova } 151a7398723SShteryana Shopova 152a7398723SShteryana Shopova return (SNMP_STRING); 153a7398723SShteryana Shopova } 154a7398723SShteryana Shopova 155a7398723SShteryana Shopova char * 156a7398723SShteryana Shopova snmp_oct2tc(enum snmp_tc tc, uint32_t len, char *octets) 157a7398723SShteryana Shopova { 158a7398723SShteryana Shopova uint32_t tc_len; 159a7398723SShteryana Shopova char * buf; 160a7398723SShteryana Shopova 1610150b85aSEnji Cooper if (tc > SNMP_UNKNOWN) 162a7398723SShteryana Shopova tc = SNMP_UNKNOWN; 163a7398723SShteryana Shopova 164a7398723SShteryana Shopova if (text_convs[tc].len > 0) 165a7398723SShteryana Shopova tc_len = text_convs[tc].len; 166a7398723SShteryana Shopova else 167a7398723SShteryana Shopova tc_len = 2 * len + 3; 168a7398723SShteryana Shopova 169a7398723SShteryana Shopova if ((buf = malloc(tc_len)) == NULL ) { 170a7398723SShteryana Shopova syslog(LOG_ERR, "malloc failed - %s", strerror(errno)); 171a7398723SShteryana Shopova return (NULL); 172a7398723SShteryana Shopova } 173a7398723SShteryana Shopova 174a7398723SShteryana Shopova memset(buf, 0, tc_len); 175a7398723SShteryana Shopova if (text_convs[tc].oct2tc(len, octets, buf) == NULL) { 176a7398723SShteryana Shopova free(buf); 177a7398723SShteryana Shopova return (NULL); 178a7398723SShteryana Shopova } 179a7398723SShteryana Shopova 180a7398723SShteryana Shopova return (buf); 181a7398723SShteryana Shopova } 182a7398723SShteryana Shopova 183a7398723SShteryana Shopova char * 184a7398723SShteryana Shopova snmp_tc2oid(enum snmp_tc tc, char *str, struct asn_oid *oid) 185a7398723SShteryana Shopova { 1860150b85aSEnji Cooper if (tc > SNMP_UNKNOWN) 187a7398723SShteryana Shopova tc = SNMP_UNKNOWN; 188a7398723SShteryana Shopova 189a7398723SShteryana Shopova return (text_convs[tc].tc2oid(str, oid)); 190a7398723SShteryana Shopova } 191a7398723SShteryana Shopova 192a7398723SShteryana Shopova int32_t 193a7398723SShteryana Shopova snmp_tc2oct(enum snmp_tc tc, struct snmp_value *value, char *string) 194a7398723SShteryana Shopova { 1950150b85aSEnji Cooper if (tc > SNMP_UNKNOWN) 196a7398723SShteryana Shopova tc = SNMP_UNKNOWN; 197a7398723SShteryana Shopova 198a7398723SShteryana Shopova return (text_convs[tc].tc2oct(value, string)); 199a7398723SShteryana Shopova } 200a7398723SShteryana Shopova 201a7398723SShteryana Shopova /***************************************************** 202a7398723SShteryana Shopova * Basic OctetString type. 203a7398723SShteryana Shopova */ 204a7398723SShteryana Shopova static char * 205a7398723SShteryana Shopova snmp_oct2str(uint32_t len, char *octets, char *buf) 206a7398723SShteryana Shopova { 207a7398723SShteryana Shopova uint8_t binary = 0; 208a7398723SShteryana Shopova uint32_t i; 209a7398723SShteryana Shopova char *ptr; 210a7398723SShteryana Shopova 211a7398723SShteryana Shopova if (len > MAX_OCTSTRING_LEN || octets == NULL || buf == NULL) 212a7398723SShteryana Shopova return (NULL); 213a7398723SShteryana Shopova 214a7398723SShteryana Shopova for (ptr = buf, i = 0; i < len; i++) 215a7398723SShteryana Shopova if (!isprint(octets[i])) { 216a7398723SShteryana Shopova binary = 1; 217a7398723SShteryana Shopova buf += sprintf(buf, "0x"); 218a7398723SShteryana Shopova break; 219a7398723SShteryana Shopova } 220a7398723SShteryana Shopova 221a7398723SShteryana Shopova for (ptr = buf, i = 0; i < len; i++) 222a7398723SShteryana Shopova if (!binary) 223a7398723SShteryana Shopova ptr += sprintf(ptr, "%c", octets[i]); 224a7398723SShteryana Shopova else 225a7398723SShteryana Shopova ptr += sprintf(ptr, "%2.2x", (u_char)octets[i]); 226a7398723SShteryana Shopova 227a7398723SShteryana Shopova return (buf); 228a7398723SShteryana Shopova } 229a7398723SShteryana Shopova 230a7398723SShteryana Shopova static char * 231a7398723SShteryana Shopova snmp_str2asn_oid(char *str, struct asn_oid *oid) 232a7398723SShteryana Shopova { 233a7398723SShteryana Shopova uint32_t i, len = 0; 234a7398723SShteryana Shopova 235a7398723SShteryana Shopova /* 236a7398723SShteryana Shopova * OctetStrings are allowed max length of ASN_MAXOCTETSTRING, 237a7398723SShteryana Shopova * but trying to index an entry with such a long OctetString 238a7398723SShteryana Shopova * will fail anyway. 239a7398723SShteryana Shopova */ 240a7398723SShteryana Shopova for (len = 0; len < ASN_MAXOIDLEN; len++) { 241a7398723SShteryana Shopova if (strchr(",]", *(str + len)) != NULL) 242a7398723SShteryana Shopova break; 243a7398723SShteryana Shopova } 244a7398723SShteryana Shopova 245a7398723SShteryana Shopova if (len >= ASN_MAXOIDLEN) 246a7398723SShteryana Shopova return (NULL); 247a7398723SShteryana Shopova 248a7398723SShteryana Shopova if (snmp_suboid_append(oid, (asn_subid_t) len) < 0) 249a7398723SShteryana Shopova return (NULL); 250a7398723SShteryana Shopova 251a7398723SShteryana Shopova for (i = 0; i < len; i++) 252a7398723SShteryana Shopova if (snmp_suboid_append(oid, (asn_subid_t) *(str + i)) < 0) 253a7398723SShteryana Shopova return (NULL); 254a7398723SShteryana Shopova 255a7398723SShteryana Shopova return (str + len); 256a7398723SShteryana Shopova } 257a7398723SShteryana Shopova 258a7398723SShteryana Shopova static int32_t 259a7398723SShteryana Shopova parse_octetstring(struct snmp_value *value, char *val) 260a7398723SShteryana Shopova { 261a7398723SShteryana Shopova size_t len; 262a7398723SShteryana Shopova 263a7398723SShteryana Shopova if ((len = strlen(val)) >= MAX_OCTSTRING_LEN) { 264a7398723SShteryana Shopova warnx("Octetstring too long - %d is max allowed", 265a7398723SShteryana Shopova MAX_OCTSTRING_LEN - 1); 266a7398723SShteryana Shopova return (-1); 267a7398723SShteryana Shopova } 268a7398723SShteryana Shopova 269a7398723SShteryana Shopova value->v.octetstring.len = len; 270a7398723SShteryana Shopova 271a7398723SShteryana Shopova if((value->v.octetstring.octets = malloc(len)) == NULL) { 272a7398723SShteryana Shopova syslog(LOG_ERR,"malloc failed: %s", strerror(errno)); 273a7398723SShteryana Shopova return (-1); 274a7398723SShteryana Shopova } 275a7398723SShteryana Shopova 276a7398723SShteryana Shopova memcpy(value->v.octetstring.octets, val, len); 277a7398723SShteryana Shopova value->syntax = SNMP_SYNTAX_OCTETSTRING; 278a7398723SShteryana Shopova 279a7398723SShteryana Shopova return (0); 280a7398723SShteryana Shopova } 281a7398723SShteryana Shopova 282a7398723SShteryana Shopova /************************************************************* 283a7398723SShteryana Shopova * DateAndTime 284a7398723SShteryana Shopova ************************************************************* 285a7398723SShteryana Shopova * rfc 2579 specification: 286a7398723SShteryana Shopova * DateAndTime ::= TEXTUAL-CONVENTION 287a7398723SShteryana Shopova * DISPLAY-HINT "2d-1d-1d,1d:1d:1d.1d,1a1d:1d" 288a7398723SShteryana Shopova * STATUS current 289a7398723SShteryana Shopova * DESCRIPTION 290a7398723SShteryana Shopova * "A date-time specification. 291a7398723SShteryana Shopova * 292a7398723SShteryana Shopova * field octets contents range 293a7398723SShteryana Shopova * ----- ------ -------- ----- 294a7398723SShteryana Shopova * 1 1-2 year* 0..65536 295a7398723SShteryana Shopova * 2 3 month 1..12 296a7398723SShteryana Shopova * 3 4 day 1..31 297a7398723SShteryana Shopova * 4 5 hour 0..23 298a7398723SShteryana Shopova * 5 6 minutes 0..59 299a7398723SShteryana Shopova * 6 7 seconds 0..60 300a7398723SShteryana Shopova * (use 60 for leap-second) 301a7398723SShteryana Shopova * 7 8 deci-seconds 0..9 302a7398723SShteryana Shopova * 8 9 direction from UTC '+' / '-' 303a7398723SShteryana Shopova * 9 10 hours from UTC* 0..13 304a7398723SShteryana Shopova * 10 11 minutes from UTC 0..59 305a7398723SShteryana Shopova * 306a7398723SShteryana Shopova * * Notes: 307a7398723SShteryana Shopova * - the value of year is in network-byte order 308a7398723SShteryana Shopova * - daylight saving time in New Zealand is +13 309a7398723SShteryana Shopova * 310a7398723SShteryana Shopova * For example, Tuesday May 26, 1992 at 1:30:15 PM EDT would be 311a7398723SShteryana Shopova * displayed as: 312a7398723SShteryana Shopova * 313a7398723SShteryana Shopova * 1992-5-26,13:30:15.0,-4:0 314a7398723SShteryana Shopova */ 315a7398723SShteryana Shopova static char * 316a7398723SShteryana Shopova snmp_octstr2date(uint32_t len, char *octets, char *buf) 317a7398723SShteryana Shopova { 318a7398723SShteryana Shopova int year; 319a7398723SShteryana Shopova char *ptr; 320a7398723SShteryana Shopova 321a7398723SShteryana Shopova if (len != SNMP_DATETIME_OCTETS || octets == NULL || buf == NULL) 322a7398723SShteryana Shopova return (NULL); 323a7398723SShteryana Shopova 324a7398723SShteryana Shopova buf[0]= '\0'; 325a7398723SShteryana Shopova year = (octets[0] << 8); 326a7398723SShteryana Shopova year += (octets[1]); 327a7398723SShteryana Shopova 328a7398723SShteryana Shopova ptr = buf; 329a7398723SShteryana Shopova ptr += sprintf(ptr, "%4.4d-%.2d-%.2d, ", year, octets[2],octets[3]); 330a7398723SShteryana Shopova ptr += sprintf(ptr, "%2.2d:%2.2d:%2.2d.%.2d, ", octets[4],octets[5], 331a7398723SShteryana Shopova octets[6],octets[7]); 332a7398723SShteryana Shopova ptr += sprintf(ptr, "%c%.2d:%.2d", octets[8],octets[9],octets[10]); 333a7398723SShteryana Shopova 334a7398723SShteryana Shopova return (buf); 335a7398723SShteryana Shopova } 336a7398723SShteryana Shopova 337a7398723SShteryana Shopova static char * 338a7398723SShteryana Shopova snmp_date2asn_oid(char *str, struct asn_oid *oid) 339a7398723SShteryana Shopova { 340a7398723SShteryana Shopova char *endptr, *ptr; 341a08b636aSEnji Cooper static const char UTC[3] = "UTC"; 342a7398723SShteryana Shopova int32_t saved_errno; 343a08b636aSEnji Cooper uint32_t v; 344a7398723SShteryana Shopova 345a7398723SShteryana Shopova if (snmp_suboid_append(oid, (asn_subid_t) SNMP_DATETIME_OCTETS) < 0) 346a7398723SShteryana Shopova return (NULL); 347a7398723SShteryana Shopova 348a7398723SShteryana Shopova /* Read 'YYYY-' and write it in two subs. */ 349a7398723SShteryana Shopova ptr = str; 350a7398723SShteryana Shopova saved_errno = errno; 351a7398723SShteryana Shopova errno = 0; 352a7398723SShteryana Shopova v = strtoul(ptr, &endptr, 10); 353a7398723SShteryana Shopova if (v > 0xffff) 354a7398723SShteryana Shopova goto error; 355a7398723SShteryana Shopova else 356a7398723SShteryana Shopova errno = saved_errno; 357a7398723SShteryana Shopova if (*endptr != '-') 358a7398723SShteryana Shopova goto error1; 359a7398723SShteryana Shopova if (snmp_suboid_append(oid, (asn_subid_t) ((v & 0xff00) >> 8)) < 0) 360a7398723SShteryana Shopova return (NULL); 361a7398723SShteryana Shopova if (snmp_suboid_append(oid, (asn_subid_t) (v & 0xff)) < 0) 362a7398723SShteryana Shopova return (NULL); 363a7398723SShteryana Shopova 364a7398723SShteryana Shopova /* 'MM-' */ 365a7398723SShteryana Shopova ptr = endptr + 1; 366a7398723SShteryana Shopova saved_errno = errno; 367a7398723SShteryana Shopova v = strtoul(ptr, &endptr, 10); 368a7398723SShteryana Shopova if (errno != 0) 369a7398723SShteryana Shopova goto error; 370a7398723SShteryana Shopova else 371a7398723SShteryana Shopova errno = saved_errno; 372a7398723SShteryana Shopova if (*endptr != '-') 373a7398723SShteryana Shopova goto error1; 374a7398723SShteryana Shopova if (snmp_suboid_append(oid, (asn_subid_t) v) < 0) 375a7398723SShteryana Shopova return (NULL); 376a7398723SShteryana Shopova 377a7398723SShteryana Shopova /* 'DD,' */ 378a7398723SShteryana Shopova ptr = endptr + 1; 379a7398723SShteryana Shopova saved_errno = errno; 380a7398723SShteryana Shopova v = strtoul(ptr, &endptr, 10); 381a7398723SShteryana Shopova if (errno != 0) 382a7398723SShteryana Shopova goto error; 383a7398723SShteryana Shopova else 384a7398723SShteryana Shopova errno = saved_errno; 385a7398723SShteryana Shopova if (*endptr != '-') 386a7398723SShteryana Shopova goto error1; 387a7398723SShteryana Shopova if (snmp_suboid_append(oid, (asn_subid_t) v) < 0) 388a7398723SShteryana Shopova return (NULL); 389a7398723SShteryana Shopova 390a7398723SShteryana Shopova /* 'HH:' */ 391a7398723SShteryana Shopova ptr = endptr + 1; 392a7398723SShteryana Shopova saved_errno = errno; 393a7398723SShteryana Shopova v = strtoul(ptr, &endptr, 10); 394a7398723SShteryana Shopova if (errno != 0) 395a7398723SShteryana Shopova goto error; 396a7398723SShteryana Shopova else 397a7398723SShteryana Shopova errno = saved_errno; 398a7398723SShteryana Shopova if (*endptr != ':') 399a7398723SShteryana Shopova goto error1; 400a7398723SShteryana Shopova if (snmp_suboid_append(oid, (asn_subid_t) v) < 0) 401a7398723SShteryana Shopova return (NULL); 402a7398723SShteryana Shopova 403a7398723SShteryana Shopova /* 'MM:' */ 404a7398723SShteryana Shopova ptr = endptr + 1; 405a7398723SShteryana Shopova saved_errno = errno; 406a7398723SShteryana Shopova v = strtoul(ptr, &endptr, 10); 407a7398723SShteryana Shopova if (errno != 0) 408a7398723SShteryana Shopova goto error; 409a7398723SShteryana Shopova else 410a7398723SShteryana Shopova errno = saved_errno; 411a7398723SShteryana Shopova if (*endptr != ':') 412a7398723SShteryana Shopova goto error1; 413a7398723SShteryana Shopova if (snmp_suboid_append(oid, (asn_subid_t) v) < 0) 414a7398723SShteryana Shopova return (NULL); 415a7398723SShteryana Shopova 416a7398723SShteryana Shopova /* 'SS.' */ 417a7398723SShteryana Shopova ptr = endptr + 1; 418a7398723SShteryana Shopova saved_errno = errno; 419a7398723SShteryana Shopova v = strtoul(ptr, &endptr, 10); 420a7398723SShteryana Shopova if (errno != 0) 421a7398723SShteryana Shopova goto error; 422a7398723SShteryana Shopova else 423a7398723SShteryana Shopova errno = saved_errno; 424a7398723SShteryana Shopova if (*endptr != '.') 425a7398723SShteryana Shopova goto error1; 426a7398723SShteryana Shopova if (snmp_suboid_append(oid, (asn_subid_t) v) < 0) 427a7398723SShteryana Shopova return (NULL); 428a7398723SShteryana Shopova 429a7398723SShteryana Shopova /* 'M(mseconds),' */ 430a7398723SShteryana Shopova ptr = endptr + 1; 431a7398723SShteryana Shopova saved_errno = errno; 432a7398723SShteryana Shopova v = strtoul(ptr, &endptr, 10); 433a7398723SShteryana Shopova if (errno != 0) 434a7398723SShteryana Shopova goto error; 435a7398723SShteryana Shopova else 436a7398723SShteryana Shopova errno = saved_errno; 437a7398723SShteryana Shopova if (*endptr != ',') 438a7398723SShteryana Shopova goto error1; 439a7398723SShteryana Shopova if (snmp_suboid_append(oid, (asn_subid_t) v) < 0) 440a7398723SShteryana Shopova return (NULL); 441a7398723SShteryana Shopova 442a7398723SShteryana Shopova /* 'UTC' - optional */ 443a7398723SShteryana Shopova ptr = endptr + 1; 444a08b636aSEnji Cooper if (strncmp(ptr, UTC, sizeof(UTC)) == 0) 445a08b636aSEnji Cooper ptr += sizeof(UTC); 446a7398723SShteryana Shopova 447a7398723SShteryana Shopova /* '+/-' */ 448a7398723SShteryana Shopova if (*ptr == '-' || *ptr == '+') { 449a7398723SShteryana Shopova if (snmp_suboid_append(oid, (asn_subid_t) (*ptr)) < 0) 450a7398723SShteryana Shopova return (NULL); 451a7398723SShteryana Shopova } else 452a7398723SShteryana Shopova goto error1; 453a7398723SShteryana Shopova 454a7398723SShteryana Shopova /* 'HH:' */ 455a7398723SShteryana Shopova ptr = endptr + 1; 456a7398723SShteryana Shopova saved_errno = errno; 457a7398723SShteryana Shopova v = strtoul(ptr, &endptr, 10); 458a7398723SShteryana Shopova if (errno != 0) 459a7398723SShteryana Shopova goto error; 460a7398723SShteryana Shopova else 461a7398723SShteryana Shopova errno = saved_errno; 462a7398723SShteryana Shopova if (*endptr != ':') 463a7398723SShteryana Shopova goto error1; 464a7398723SShteryana Shopova if (snmp_suboid_append(oid, (asn_subid_t) v) < 0) 465a7398723SShteryana Shopova return (NULL); 466a7398723SShteryana Shopova 467a7398723SShteryana Shopova /* 'MM' - last one - ignore endptr here. */ 468a7398723SShteryana Shopova ptr = endptr + 1; 469a7398723SShteryana Shopova saved_errno = errno; 470a7398723SShteryana Shopova v = strtoul(ptr, &endptr, 10); 471a7398723SShteryana Shopova if (errno != 0) 472a7398723SShteryana Shopova goto error; 473a7398723SShteryana Shopova else 474a7398723SShteryana Shopova errno = saved_errno; 475a7398723SShteryana Shopova if (snmp_suboid_append(oid, (asn_subid_t) v) < 0) 476a7398723SShteryana Shopova return (NULL); 477a7398723SShteryana Shopova 478a7398723SShteryana Shopova return (endptr); 479a7398723SShteryana Shopova 480a7398723SShteryana Shopova error: 481a7398723SShteryana Shopova errno = saved_errno; 482a7398723SShteryana Shopova error1: 483a7398723SShteryana Shopova warnx("Date value %s not supported", str); 484a7398723SShteryana Shopova return (NULL); 485a7398723SShteryana Shopova } 486a7398723SShteryana Shopova 487a7398723SShteryana Shopova /* Read a DateAndTime string eg. 1992-5-26,13:30:15.0,-4:0. */ 488a7398723SShteryana Shopova static int32_t 489a7398723SShteryana Shopova parse_dateandtime(struct snmp_value *sv, char *val) 490a7398723SShteryana Shopova { 491a7398723SShteryana Shopova char *endptr; 492a7398723SShteryana Shopova uint32_t v; 493a7398723SShteryana Shopova uint8_t date[SNMP_DATETIME_OCTETS]; 494a7398723SShteryana Shopova 495a7398723SShteryana Shopova /* 'YYYY-' */ 496a7398723SShteryana Shopova v = strtoul(val, &endptr, 10); 497a7398723SShteryana Shopova if (v > 0xffff || *endptr != '-') 498a7398723SShteryana Shopova goto error; 499a7398723SShteryana Shopova date[0] = ((v & 0xff00) >> 8); 500a7398723SShteryana Shopova date[1] = (v & 0xff); 501a7398723SShteryana Shopova val = endptr + 1; 502a7398723SShteryana Shopova 503a7398723SShteryana Shopova /* 'MM-' */ 504a7398723SShteryana Shopova v = strtoul(val, &endptr, 10); 505a7398723SShteryana Shopova if (v == 0 || v > 12 || *endptr != '-') 506a7398723SShteryana Shopova goto error; 507a7398723SShteryana Shopova date[2] = v; 508a7398723SShteryana Shopova val = endptr + 1; 509a7398723SShteryana Shopova 510a7398723SShteryana Shopova /* 'DD,' */ 511a7398723SShteryana Shopova v = strtoul(val, &endptr, 10); 512a7398723SShteryana Shopova if (v == 0 || v > 31 || *endptr != ',') 513a7398723SShteryana Shopova goto error; 514a7398723SShteryana Shopova date[3] = v; 515a7398723SShteryana Shopova val = endptr + 1; 516a7398723SShteryana Shopova 517a7398723SShteryana Shopova /* 'HH:' */ 518a7398723SShteryana Shopova v = strtoul(val, &endptr, 10); 519a7398723SShteryana Shopova if (v > 23 || *endptr != ':') 520a7398723SShteryana Shopova goto error; 521a7398723SShteryana Shopova date[4] = v; 522a7398723SShteryana Shopova val = endptr + 1; 523a7398723SShteryana Shopova 524a7398723SShteryana Shopova /* 'MM:' */ 525a7398723SShteryana Shopova v = strtoul(val, &endptr, 10); 526a7398723SShteryana Shopova if (v > 59 || *endptr != ':') 527a7398723SShteryana Shopova goto error; 528a7398723SShteryana Shopova date[5] = v; 529a7398723SShteryana Shopova val = endptr + 1; 530a7398723SShteryana Shopova 531a7398723SShteryana Shopova /* 'SS.' */ 532a7398723SShteryana Shopova v = strtoul(val, &endptr, 10); 533a7398723SShteryana Shopova if (v > 60 || *endptr != '.') 534a7398723SShteryana Shopova goto error; 535a7398723SShteryana Shopova date[6] = v; 536a7398723SShteryana Shopova val = endptr + 1; 537a7398723SShteryana Shopova 538a7398723SShteryana Shopova /* '(deci-)s,' */ 539a7398723SShteryana Shopova v = strtoul(val, &endptr, 10); 540a7398723SShteryana Shopova if (v > 9 || *endptr != ',') 541a7398723SShteryana Shopova goto error; 542a7398723SShteryana Shopova date[7] = v; 543a7398723SShteryana Shopova val = endptr + 1; 544a7398723SShteryana Shopova 545a7398723SShteryana Shopova /* offset - '+/-' */ 546a7398723SShteryana Shopova if (*val != '-' && *val != '+') 547a7398723SShteryana Shopova goto error; 548a7398723SShteryana Shopova date[8] = (uint8_t) *val; 549a7398723SShteryana Shopova val = endptr + 1; 550a7398723SShteryana Shopova 551a7398723SShteryana Shopova /* 'HH:' - offset from UTC */ 552a7398723SShteryana Shopova v = strtoul(val, &endptr, 10); 553a7398723SShteryana Shopova if (v > 13 || *endptr != ':') 554a7398723SShteryana Shopova goto error; 555a7398723SShteryana Shopova date[9] = v; 556a7398723SShteryana Shopova val = endptr + 1; 557a7398723SShteryana Shopova 558a7398723SShteryana Shopova /* 'MM'\0'' offset from UTC */ 559a7398723SShteryana Shopova v = strtoul(val, &endptr, 10); 560a7398723SShteryana Shopova if (v > 59 || *endptr != '\0') 561a7398723SShteryana Shopova goto error; 562a7398723SShteryana Shopova date[10] = v; 563a7398723SShteryana Shopova 564a7398723SShteryana Shopova if ((sv->v.octetstring.octets = malloc(SNMP_DATETIME_OCTETS)) == NULL) { 565a7398723SShteryana Shopova warnx("malloc() failed - %s", strerror(errno)); 566a7398723SShteryana Shopova return (-1); 567a7398723SShteryana Shopova } 568a7398723SShteryana Shopova 569a7398723SShteryana Shopova sv->v.octetstring.len = SNMP_DATETIME_OCTETS; 570a7398723SShteryana Shopova memcpy(sv->v.octetstring.octets, date, SNMP_DATETIME_OCTETS); 571a7398723SShteryana Shopova sv->syntax = SNMP_SYNTAX_OCTETSTRING; 572a7398723SShteryana Shopova return (1); 573a7398723SShteryana Shopova 574a7398723SShteryana Shopova error: 575a7398723SShteryana Shopova warnx("Date value %s not supported", val); 576a7398723SShteryana Shopova return (-1); 577a7398723SShteryana Shopova } 578a7398723SShteryana Shopova 579a7398723SShteryana Shopova /************************************************************** 580a7398723SShteryana Shopova * PhysAddress 581a7398723SShteryana Shopova */ 582a7398723SShteryana Shopova static char * 583a7398723SShteryana Shopova snmp_oct2physAddr(uint32_t len, char *octets, char *buf) 584a7398723SShteryana Shopova { 585a7398723SShteryana Shopova char *ptr; 586a7398723SShteryana Shopova uint32_t i; 587a7398723SShteryana Shopova 588a7398723SShteryana Shopova if (len != SNMP_PHYSADDR_OCTETS || octets == NULL || buf == NULL) 589a7398723SShteryana Shopova return (NULL); 590a7398723SShteryana Shopova 591a7398723SShteryana Shopova buf[0]= '\0'; 592a7398723SShteryana Shopova 593a7398723SShteryana Shopova ptr = buf; 594a7398723SShteryana Shopova ptr += sprintf(ptr, "%2.2x", octets[0]); 595a7398723SShteryana Shopova for (i = 1; i < 6; i++) 596a7398723SShteryana Shopova ptr += sprintf(ptr, ":%2.2x", octets[i]); 597a7398723SShteryana Shopova 598a7398723SShteryana Shopova return (buf); 599a7398723SShteryana Shopova } 600a7398723SShteryana Shopova 601a7398723SShteryana Shopova static char * 602a7398723SShteryana Shopova snmp_addr2asn_oid(char *str, struct asn_oid *oid) 603a7398723SShteryana Shopova { 604a7398723SShteryana Shopova char *endptr, *ptr; 605a7398723SShteryana Shopova uint32_t v, i; 606a7398723SShteryana Shopova int saved_errno; 607a7398723SShteryana Shopova 608a7398723SShteryana Shopova if (snmp_suboid_append(oid, (asn_subid_t) SNMP_PHYSADDR_OCTETS) < 0) 609a7398723SShteryana Shopova return (NULL); 610a7398723SShteryana Shopova 611a7398723SShteryana Shopova ptr = str; 612a7398723SShteryana Shopova for (i = 0; i < 5; i++) { 613a7398723SShteryana Shopova saved_errno = errno; 614a7398723SShteryana Shopova v = strtoul(ptr, &endptr, 16); 615a7398723SShteryana Shopova errno = saved_errno; 616a7398723SShteryana Shopova if (v > 0xff) { 617a7398723SShteryana Shopova warnx("Integer value %s not supported", str); 618a7398723SShteryana Shopova return (NULL); 619a7398723SShteryana Shopova } 620a7398723SShteryana Shopova if (*endptr != ':') { 621a7398723SShteryana Shopova warnx("Failed adding oid - %s",str); 622a7398723SShteryana Shopova return (NULL); 623a7398723SShteryana Shopova } 624a7398723SShteryana Shopova if (snmp_suboid_append(oid, (asn_subid_t) v) < 0) 625a7398723SShteryana Shopova return (NULL); 626a7398723SShteryana Shopova ptr = endptr + 1; 627a7398723SShteryana Shopova } 628a7398723SShteryana Shopova 629a7398723SShteryana Shopova /* The last one - don't check the ending char here. */ 630a7398723SShteryana Shopova saved_errno = errno; 631a7398723SShteryana Shopova v = strtoul(ptr, &endptr, 16); 632a7398723SShteryana Shopova errno = saved_errno; 633a7398723SShteryana Shopova if (v > 0xff) { 634a7398723SShteryana Shopova warnx("Integer value %s not supported", str); 635a7398723SShteryana Shopova return (NULL); 636a7398723SShteryana Shopova } 637a7398723SShteryana Shopova if (snmp_suboid_append(oid, (asn_subid_t) v) < 0) 638a7398723SShteryana Shopova return (NULL); 639a7398723SShteryana Shopova 640a7398723SShteryana Shopova return (endptr); 641a7398723SShteryana Shopova } 642a7398723SShteryana Shopova 643a7398723SShteryana Shopova static int32_t 644a7398723SShteryana Shopova parse_physaddress(struct snmp_value *sv, char *val) 645a7398723SShteryana Shopova { 646a7398723SShteryana Shopova char *endptr; 647a7398723SShteryana Shopova int32_t i; 648a7398723SShteryana Shopova uint32_t v; 649a7398723SShteryana Shopova uint8_t phys_addr[SNMP_PHYSADDR_OCTETS]; 650a7398723SShteryana Shopova 651a7398723SShteryana Shopova for (i = 0; i < 5; i++) { 652a7398723SShteryana Shopova v = strtoul(val, &endptr, 16); 653a7398723SShteryana Shopova if (v > 0xff) { 654a7398723SShteryana Shopova warnx("Integer value %s not supported", val); 655a7398723SShteryana Shopova return (-1); 656a7398723SShteryana Shopova } 657a7398723SShteryana Shopova if(*endptr != ':') { 658a7398723SShteryana Shopova warnx("Failed reading octet - %s", val); 659a7398723SShteryana Shopova return (-1); 660a7398723SShteryana Shopova } 661a7398723SShteryana Shopova phys_addr[i] = v; 662a7398723SShteryana Shopova val = endptr + 1; 663a7398723SShteryana Shopova } 664a7398723SShteryana Shopova 665a7398723SShteryana Shopova /* The last one - don't check the ending char here. */ 666a7398723SShteryana Shopova v = strtoul(val, &endptr, 16); 667a7398723SShteryana Shopova if (v > 0xff) { 668a7398723SShteryana Shopova warnx("Integer value %s not supported", val); 669a7398723SShteryana Shopova return (-1); 670a7398723SShteryana Shopova } 671a7398723SShteryana Shopova phys_addr[5] = v; 672a7398723SShteryana Shopova 673a7398723SShteryana Shopova if ((sv->v.octetstring.octets = malloc(SNMP_PHYSADDR_OCTETS)) == NULL) { 674a7398723SShteryana Shopova syslog(LOG_ERR,"malloc failed: %s", strerror(errno)); 675a7398723SShteryana Shopova return (-1); 676a7398723SShteryana Shopova } 677a7398723SShteryana Shopova 678a7398723SShteryana Shopova sv->v.octetstring.len = SNMP_PHYSADDR_OCTETS; 679a7398723SShteryana Shopova memcpy(sv->v.octetstring.octets, phys_addr, SNMP_PHYSADDR_OCTETS); 680a7398723SShteryana Shopova sv->syntax = SNMP_SYNTAX_OCTETSTRING; 681a7398723SShteryana Shopova return (1); 682a7398723SShteryana Shopova } 683a7398723SShteryana Shopova 684a7398723SShteryana Shopova /************************************************************** 685a7398723SShteryana Shopova * NTPTimeStamp 686a7398723SShteryana Shopova ************************************************************** 687a7398723SShteryana Shopova * NTP MIB, Revision 0.2, 7/25/97: 688a7398723SShteryana Shopova * NTPTimeStamp ::= TEXTUAL-CONVENTION 689a7398723SShteryana Shopova * DISPLAY-HINT "4x.4x" 690a7398723SShteryana Shopova * STATUS current 691a7398723SShteryana Shopova * DESCRIPTION 692a7398723SShteryana Shopova * "" 693a7398723SShteryana Shopova * SYNTAX OCTET STRING (SIZE(8)) 694a7398723SShteryana Shopova */ 695a7398723SShteryana Shopova static char * 696a7398723SShteryana Shopova snmp_oct2ntp_ts(uint32_t len, char *octets, char *buf) 697a7398723SShteryana Shopova { 698a7398723SShteryana Shopova char *ptr; 699a7398723SShteryana Shopova uint32_t i; 700a7398723SShteryana Shopova 701a7398723SShteryana Shopova if (len != SNMP_NTP_TS_OCTETS || octets == NULL || buf == NULL) 702a7398723SShteryana Shopova return (NULL); 703a7398723SShteryana Shopova 704a7398723SShteryana Shopova buf[0]= '\0'; 705a7398723SShteryana Shopova 706a7398723SShteryana Shopova ptr = buf; 707a7398723SShteryana Shopova i = octets[0] * 1000 + octets[1] * 100 + octets[2] * 10 + octets[3]; 708a7398723SShteryana Shopova ptr += sprintf(ptr, "%4.4d", i); 709a7398723SShteryana Shopova i = octets[4] * 1000 + octets[5] * 100 + octets[6] * 10 + octets[7]; 710a7398723SShteryana Shopova ptr += sprintf(ptr, ".%4.4d", i); 711a7398723SShteryana Shopova 712a7398723SShteryana Shopova return (buf); 713a7398723SShteryana Shopova } 714a7398723SShteryana Shopova 715a7398723SShteryana Shopova static char * 716a7398723SShteryana Shopova snmp_ntp_ts2asn_oid(char *str, struct asn_oid *oid) 717a7398723SShteryana Shopova { 718a7398723SShteryana Shopova char *endptr, *ptr; 719a7398723SShteryana Shopova uint32_t v, i, d; 720a7398723SShteryana Shopova struct asn_oid suboid; 721a7398723SShteryana Shopova int saved_errno; 722a7398723SShteryana Shopova 723a7398723SShteryana Shopova if (snmp_suboid_append(oid, (asn_subid_t) SNMP_NTP_TS_OCTETS) < 0) 724a7398723SShteryana Shopova return (NULL); 725a7398723SShteryana Shopova 726a7398723SShteryana Shopova ptr = str; 727a7398723SShteryana Shopova saved_errno = errno; 728a7398723SShteryana Shopova v = strtoul(ptr, &endptr, 10); 729a7398723SShteryana Shopova if (errno != 0 || (v / 1000) > 9) { 730a7398723SShteryana Shopova warnx("Integer value %s not supported", str); 731a7398723SShteryana Shopova errno = saved_errno; 732a7398723SShteryana Shopova return (NULL); 733a7398723SShteryana Shopova } else 734a7398723SShteryana Shopova errno = saved_errno; 735a7398723SShteryana Shopova 736a7398723SShteryana Shopova if (*endptr != '.') { 737a7398723SShteryana Shopova warnx("Failed adding oid - %s",str); 738a7398723SShteryana Shopova return (NULL); 739a7398723SShteryana Shopova } 740a7398723SShteryana Shopova 741a7398723SShteryana Shopova memset(&suboid, 0, sizeof(struct asn_oid)); 742a7398723SShteryana Shopova suboid.len = SNMP_NTP_TS_OCTETS; 743a7398723SShteryana Shopova 744a7398723SShteryana Shopova for (i = 0, d = 1000; i < 4; i++) { 745a7398723SShteryana Shopova suboid.subs[i] = v / d; 746a7398723SShteryana Shopova v = v % d; 747a7398723SShteryana Shopova d = d / 10; 748a7398723SShteryana Shopova } 749a7398723SShteryana Shopova 750a7398723SShteryana Shopova ptr = endptr + 1; 751a7398723SShteryana Shopova saved_errno = errno; 752a7398723SShteryana Shopova v = strtoul(ptr, &endptr, 10); 753a7398723SShteryana Shopova if (errno != 0 || (v / 1000) > 9) { 754a7398723SShteryana Shopova warnx("Integer value %s not supported", str); 755a7398723SShteryana Shopova errno = saved_errno; 756a7398723SShteryana Shopova return (NULL); 757a7398723SShteryana Shopova } else 758a7398723SShteryana Shopova errno = saved_errno; 759a7398723SShteryana Shopova 760a7398723SShteryana Shopova for (i = 0, d = 1000; i < 4; i++) { 761a7398723SShteryana Shopova suboid.subs[i + 4] = v / d; 762a7398723SShteryana Shopova v = v % d; 763a7398723SShteryana Shopova d = d / 10; 764a7398723SShteryana Shopova } 765a7398723SShteryana Shopova 766a7398723SShteryana Shopova asn_append_oid(oid, &suboid); 767a7398723SShteryana Shopova return (endptr); 768a7398723SShteryana Shopova } 769a7398723SShteryana Shopova 770a7398723SShteryana Shopova static int32_t 771a7398723SShteryana Shopova parse_ntp_ts(struct snmp_value *sv, char *val) 772a7398723SShteryana Shopova { 773a7398723SShteryana Shopova char *endptr; 774a7398723SShteryana Shopova int32_t i, d, saved_errno; 775a7398723SShteryana Shopova uint32_t v; 776a7398723SShteryana Shopova uint8_t ntp_ts[SNMP_NTP_TS_OCTETS]; 777a7398723SShteryana Shopova 778a7398723SShteryana Shopova saved_errno = errno; 779a7398723SShteryana Shopova v = strtoul(val, &endptr, 10); 780a7398723SShteryana Shopova if (errno != 0 || (v / 1000) > 9) { 781a7398723SShteryana Shopova saved_errno = errno; 782a7398723SShteryana Shopova warnx("Integer value %s not supported", val); 783a7398723SShteryana Shopova return (-1); 784a7398723SShteryana Shopova } else 785a7398723SShteryana Shopova saved_errno = errno; 786a7398723SShteryana Shopova 787a7398723SShteryana Shopova if (*endptr != '.') { 788a7398723SShteryana Shopova warnx("Failed reading octet - %s", val); 789a7398723SShteryana Shopova return (-1); 790a7398723SShteryana Shopova } 791a7398723SShteryana Shopova 792a7398723SShteryana Shopova for (i = 0, d = 1000; i < 4; i++) { 793a7398723SShteryana Shopova ntp_ts[i] = v / d; 794a7398723SShteryana Shopova v = v % d; 795a7398723SShteryana Shopova d = d / 10; 796a7398723SShteryana Shopova } 797a7398723SShteryana Shopova val = endptr + 1; 798a7398723SShteryana Shopova 799a7398723SShteryana Shopova saved_errno = errno; 800a7398723SShteryana Shopova v = strtoul(val, &endptr, 10); 801a7398723SShteryana Shopova if (errno != 0 || (v / 1000) > 9) { 802a7398723SShteryana Shopova saved_errno = errno; 803a7398723SShteryana Shopova warnx("Integer value %s not supported", val); 804a7398723SShteryana Shopova return (-1); 805a7398723SShteryana Shopova } else 806a7398723SShteryana Shopova saved_errno = errno; 807a7398723SShteryana Shopova 808a7398723SShteryana Shopova for (i = 0, d = 1000; i < 4; i++) { 809a7398723SShteryana Shopova ntp_ts[i + 4] = v / d; 810a7398723SShteryana Shopova v = v % d; 811a7398723SShteryana Shopova d = d / 10; 812a7398723SShteryana Shopova } 813a7398723SShteryana Shopova 814a7398723SShteryana Shopova if ((sv->v.octetstring.octets = malloc(SNMP_NTP_TS_OCTETS)) == NULL) { 815a7398723SShteryana Shopova syslog(LOG_ERR,"malloc failed: %s", strerror(errno)); 816a7398723SShteryana Shopova return (-1); 817a7398723SShteryana Shopova } 818a7398723SShteryana Shopova 819a7398723SShteryana Shopova sv->v.octetstring.len = SNMP_NTP_TS_OCTETS; 820a7398723SShteryana Shopova memcpy(sv->v.octetstring.octets, ntp_ts, SNMP_NTP_TS_OCTETS); 821a7398723SShteryana Shopova sv->syntax = SNMP_SYNTAX_OCTETSTRING; 822a7398723SShteryana Shopova return (1); 823a7398723SShteryana Shopova } 824a7398723SShteryana Shopova 825a7398723SShteryana Shopova /************************************************************** 826a7398723SShteryana Shopova * BridgeId 827a7398723SShteryana Shopova ************************************************************** 828a7398723SShteryana Shopova * BRIDGE-MIB, REVISION "200509190000Z" 829a7398723SShteryana Shopova * BridgeId ::= TEXTUAL-CONVENTION 830a7398723SShteryana Shopova * STATUS current 831a7398723SShteryana Shopova * DESCRIPTION 832a7398723SShteryana Shopova * "The Bridge-Identifier, as used in the Spanning Tree 833a7398723SShteryana Shopova * Protocol, to uniquely identify a bridge. Its first two 834a7398723SShteryana Shopova * octets (in network byte order) contain a priority value, 835a7398723SShteryana Shopova * and its last 6 octets contain the MAC address used to 836a7398723SShteryana Shopova * refer to a bridge in a unique fashion (typically, the 837a7398723SShteryana Shopova * numerically smallest MAC address of all ports on the 838a7398723SShteryana Shopova * bridge)." 839a7398723SShteryana Shopova * SYNTAX OCTET STRING (SIZE (8)) 840a7398723SShteryana Shopova */ 841a7398723SShteryana Shopova static char * 842a7398723SShteryana Shopova snmp_oct2bridgeid(uint32_t len, char *octets, char *buf) 843a7398723SShteryana Shopova { 844a7398723SShteryana Shopova char *ptr; 845a7398723SShteryana Shopova uint32_t i, priority; 846a7398723SShteryana Shopova 847a7398723SShteryana Shopova if (len != SNMP_BRIDGEID_OCTETS || octets == NULL || buf == NULL) 848a7398723SShteryana Shopova return (NULL); 849a7398723SShteryana Shopova 850a7398723SShteryana Shopova buf[0]= '\0'; 851a7398723SShteryana Shopova ptr = buf; 852a7398723SShteryana Shopova 853a7398723SShteryana Shopova priority = octets[0] << 8; 854a7398723SShteryana Shopova priority += octets[1]; 855a7398723SShteryana Shopova if (priority > SNMP_MAX_BRIDGE_PRIORITY) { 856a7398723SShteryana Shopova warnx("Invalid bridge priority %d", priority); 857a7398723SShteryana Shopova return (NULL); 858a7398723SShteryana Shopova } else 859a7398723SShteryana Shopova ptr += sprintf(ptr, "%d.", octets[0]); 860a7398723SShteryana Shopova 861a7398723SShteryana Shopova ptr += sprintf(ptr, "%2.2x", octets[2]); 862a7398723SShteryana Shopova 863a7398723SShteryana Shopova for (i = 1; i < 6; i++) 864a7398723SShteryana Shopova ptr += sprintf(ptr, ":%2.2x", octets[i + 2]); 865a7398723SShteryana Shopova 866a7398723SShteryana Shopova return (buf); 867a7398723SShteryana Shopova } 868a7398723SShteryana Shopova 869a7398723SShteryana Shopova static char * 870a7398723SShteryana Shopova snmp_bridgeid2oct(char *str, struct asn_oid *oid) 871a7398723SShteryana Shopova { 872a7398723SShteryana Shopova char *endptr, *ptr; 873a7398723SShteryana Shopova uint32_t v, i; 874a7398723SShteryana Shopova int32_t saved_errno; 875a7398723SShteryana Shopova 876a7398723SShteryana Shopova if (snmp_suboid_append(oid, (asn_subid_t) SNMP_BRIDGEID_OCTETS) < 0) 877a7398723SShteryana Shopova return (NULL); 878a7398723SShteryana Shopova 879a7398723SShteryana Shopova ptr = str; 880a7398723SShteryana Shopova /* Read the priority. */ 881a7398723SShteryana Shopova saved_errno = errno; 882a7398723SShteryana Shopova v = strtoul(ptr, &endptr, 10); 883a7398723SShteryana Shopova errno = 0; 884a7398723SShteryana Shopova 885a7398723SShteryana Shopova if (v > SNMP_MAX_BRIDGE_PRIORITY || errno != 0 || *endptr != '.') { 886a7398723SShteryana Shopova errno = saved_errno; 887a7398723SShteryana Shopova warnx("Bad bridge priority value %d", v); 888a7398723SShteryana Shopova return (NULL); 889a7398723SShteryana Shopova } 890a7398723SShteryana Shopova 891a7398723SShteryana Shopova if (snmp_suboid_append(oid, (asn_subid_t) (v & 0xff00)) < 0) 892a7398723SShteryana Shopova return (NULL); 893a7398723SShteryana Shopova 894a7398723SShteryana Shopova if (snmp_suboid_append(oid, (asn_subid_t) (v & 0xff)) < 0) 895a7398723SShteryana Shopova return (NULL); 896a7398723SShteryana Shopova 897a7398723SShteryana Shopova ptr = endptr + 1; 898a7398723SShteryana Shopova for (i = 0; i < 5; i++) { 899a7398723SShteryana Shopova saved_errno = errno; 900a7398723SShteryana Shopova v = strtoul(ptr, &endptr, 16); 901a7398723SShteryana Shopova errno = saved_errno; 902a7398723SShteryana Shopova if (v > 0xff) { 903a7398723SShteryana Shopova warnx("Integer value %s not supported", str); 904a7398723SShteryana Shopova return (NULL); 905a7398723SShteryana Shopova } 906a7398723SShteryana Shopova if (*endptr != ':') { 907a7398723SShteryana Shopova warnx("Failed adding oid - %s",str); 908a7398723SShteryana Shopova return (NULL); 909a7398723SShteryana Shopova } 910a7398723SShteryana Shopova if (snmp_suboid_append(oid, (asn_subid_t) v) < 0) 911a7398723SShteryana Shopova return (NULL); 912a7398723SShteryana Shopova ptr = endptr + 1; 913a7398723SShteryana Shopova } 914a7398723SShteryana Shopova 915a7398723SShteryana Shopova /* The last one - don't check the ending char here. */ 916a7398723SShteryana Shopova saved_errno = errno; 917a7398723SShteryana Shopova v = strtoul(ptr, &endptr, 16); 918a7398723SShteryana Shopova errno = saved_errno; 919a7398723SShteryana Shopova if (v > 0xff) { 920a7398723SShteryana Shopova warnx("Integer value %s not supported", str); 921a7398723SShteryana Shopova return (NULL); 922a7398723SShteryana Shopova } 923a7398723SShteryana Shopova if (snmp_suboid_append(oid, (asn_subid_t) v) < 0) 924a7398723SShteryana Shopova return (NULL); 925a7398723SShteryana Shopova 926a7398723SShteryana Shopova return (endptr); 927a7398723SShteryana Shopova } 928a7398723SShteryana Shopova 929a7398723SShteryana Shopova static int32_t 930a7398723SShteryana Shopova parse_bridge_id(struct snmp_value *sv, char *string) 931a7398723SShteryana Shopova { 9320150b85aSEnji Cooper char *endptr; 933a7398723SShteryana Shopova int32_t i, saved_errno; 934a7398723SShteryana Shopova uint32_t v; 935a7398723SShteryana Shopova uint8_t bridge_id[SNMP_BRIDGEID_OCTETS]; 936a7398723SShteryana Shopova 937a7398723SShteryana Shopova /* Read the priority. */ 938a7398723SShteryana Shopova saved_errno = errno; 939a7398723SShteryana Shopova errno = 0; 940a7398723SShteryana Shopova v = strtoul(string, &endptr, 10); 941a7398723SShteryana Shopova errno = saved_errno; 942a7398723SShteryana Shopova 943a7398723SShteryana Shopova if (v > SNMP_MAX_BRIDGE_PRIORITY || errno != 0 || *endptr != '.') { 944a7398723SShteryana Shopova errno = saved_errno; 945a7398723SShteryana Shopova warnx("Bad bridge priority value %d", v); 946a7398723SShteryana Shopova return (-1); 947a7398723SShteryana Shopova } 948a7398723SShteryana Shopova 949a7398723SShteryana Shopova bridge_id[0] = (v & 0xff00); 950a7398723SShteryana Shopova bridge_id[1] = (v & 0xff); 951a7398723SShteryana Shopova 952a7398723SShteryana Shopova string = endptr + 1; 953a7398723SShteryana Shopova 954a7398723SShteryana Shopova for (i = 0; i < 5; i++) { 955a7398723SShteryana Shopova v = strtoul(string, &endptr, 16); 956a7398723SShteryana Shopova if (v > 0xff) { 957a7398723SShteryana Shopova warnx("Integer value %s not supported", string); 958a7398723SShteryana Shopova return (-1); 959a7398723SShteryana Shopova } 960a7398723SShteryana Shopova if(*endptr != ':') { 961a7398723SShteryana Shopova warnx("Failed reading octet - %s", string); 962a7398723SShteryana Shopova return (-1); 963a7398723SShteryana Shopova } 964a7398723SShteryana Shopova bridge_id[i + 2] = v; 965a7398723SShteryana Shopova string = endptr + 1; 966a7398723SShteryana Shopova } 967a7398723SShteryana Shopova 968a7398723SShteryana Shopova /* The last one - don't check the ending char here. */ 969a7398723SShteryana Shopova v = strtoul(string, &endptr, 16); 970a7398723SShteryana Shopova if (v > 0xff) { 971a7398723SShteryana Shopova warnx("Integer value %s not supported", string); 972a7398723SShteryana Shopova return (-1); 973a7398723SShteryana Shopova } 974a7398723SShteryana Shopova bridge_id[7] = v; 975a7398723SShteryana Shopova 976a7398723SShteryana Shopova if ((sv->v.octetstring.octets = malloc(SNMP_BRIDGEID_OCTETS)) == NULL) { 977a7398723SShteryana Shopova syslog(LOG_ERR,"malloc failed: %s", strerror(errno)); 978a7398723SShteryana Shopova return (-1); 979a7398723SShteryana Shopova } 980a7398723SShteryana Shopova 981a7398723SShteryana Shopova sv->v.octetstring.len = SNMP_BRIDGEID_OCTETS; 982a7398723SShteryana Shopova memcpy(sv->v.octetstring.octets, bridge_id, SNMP_BRIDGEID_OCTETS); 983a7398723SShteryana Shopova sv->syntax = SNMP_SYNTAX_OCTETSTRING; 984a7398723SShteryana Shopova return (1); 985a7398723SShteryana Shopova } 986a7398723SShteryana Shopova 987a7398723SShteryana Shopova /************************************************************** 988a7398723SShteryana Shopova * BridgePortId 989a7398723SShteryana Shopova ************************************************************** 990a7398723SShteryana Shopova * BEGEMOT-BRIDGE-MIB, LAST-UPDATED "200608100000Z" 991a7398723SShteryana Shopova * BridgePortId ::= TEXTUAL-CONVENTION 992a7398723SShteryana Shopova * DISPLAY-HINT "1x.1x" 993a7398723SShteryana Shopova * STATUS current 994a7398723SShteryana Shopova * DESCRIPTION 995a7398723SShteryana Shopova * "A port identifier that contains a bridge port's STP priority 996a7398723SShteryana Shopova * in the first octet and the port number in the second octet." 997a7398723SShteryana Shopova * SYNTAX OCTET STRING (SIZE(2)) 998a7398723SShteryana Shopova */ 999a7398723SShteryana Shopova static char * 1000a7398723SShteryana Shopova snmp_oct2bport_id(uint32_t len, char *octets, char *buf) 1001a7398723SShteryana Shopova { 1002a7398723SShteryana Shopova char *ptr; 1003a7398723SShteryana Shopova 1004a7398723SShteryana Shopova if (len != SNMP_BPORT_OCTETS || octets == NULL || buf == NULL) 1005a7398723SShteryana Shopova return (NULL); 1006a7398723SShteryana Shopova 1007a7398723SShteryana Shopova buf[0]= '\0'; 1008a7398723SShteryana Shopova ptr = buf; 1009a7398723SShteryana Shopova 1010a7398723SShteryana Shopova ptr += sprintf(ptr, "%d.", octets[0]); 1011a7398723SShteryana Shopova ptr += sprintf(ptr, "%d", octets[1]); 1012a7398723SShteryana Shopova 1013a7398723SShteryana Shopova return (buf); 1014a7398723SShteryana Shopova } 1015a7398723SShteryana Shopova 1016a7398723SShteryana Shopova static char * 1017a7398723SShteryana Shopova snmp_bport_id2oct(char *str, struct asn_oid *oid) 1018a7398723SShteryana Shopova { 1019a7398723SShteryana Shopova char *endptr, *ptr; 1020a7398723SShteryana Shopova uint32_t v; 1021a7398723SShteryana Shopova int saved_errno; 1022a7398723SShteryana Shopova 1023a7398723SShteryana Shopova if (snmp_suboid_append(oid, (asn_subid_t) SNMP_BPORT_OCTETS) < 0) 1024a7398723SShteryana Shopova return (NULL); 1025a7398723SShteryana Shopova 1026a7398723SShteryana Shopova ptr = str; 1027a7398723SShteryana Shopova /* Read the priority. */ 1028a7398723SShteryana Shopova saved_errno = errno; 1029a7398723SShteryana Shopova v = strtoul(ptr, &endptr, 10); 1030a7398723SShteryana Shopova errno = 0; 1031a7398723SShteryana Shopova 1032a7398723SShteryana Shopova if (v > SNMP_MAX_BPORT_PRIORITY || errno != 0 || *endptr != '.') { 1033a7398723SShteryana Shopova errno = saved_errno; 1034a7398723SShteryana Shopova warnx("Bad bridge port priority value %d", v); 1035a7398723SShteryana Shopova return (NULL); 1036a7398723SShteryana Shopova } 1037a7398723SShteryana Shopova 1038a7398723SShteryana Shopova if (snmp_suboid_append(oid, (asn_subid_t) v) < 0) 1039a7398723SShteryana Shopova return (NULL); 1040a7398723SShteryana Shopova 1041a7398723SShteryana Shopova saved_errno = errno; 1042a7398723SShteryana Shopova v = strtoul(ptr, &endptr, 16); 1043a7398723SShteryana Shopova errno = saved_errno; 1044a7398723SShteryana Shopova 1045a7398723SShteryana Shopova if (v > 0xff) { 1046a7398723SShteryana Shopova warnx("Bad port number - %d", v); 1047a7398723SShteryana Shopova return (NULL); 1048a7398723SShteryana Shopova } 1049a7398723SShteryana Shopova 1050a7398723SShteryana Shopova if (snmp_suboid_append(oid, (asn_subid_t) v) < 0) 1051a7398723SShteryana Shopova return (NULL); 1052a7398723SShteryana Shopova 1053a7398723SShteryana Shopova return (endptr); 1054a7398723SShteryana Shopova } 1055a7398723SShteryana Shopova 1056a7398723SShteryana Shopova static int32_t 1057a7398723SShteryana Shopova parse_bport_id(struct snmp_value *value, char *string) 1058a7398723SShteryana Shopova { 10590150b85aSEnji Cooper char *endptr; 1060a7398723SShteryana Shopova int saved_errno; 1061a7398723SShteryana Shopova uint32_t v; 1062a7398723SShteryana Shopova uint8_t bport_id[SNMP_BPORT_OCTETS]; 1063a7398723SShteryana Shopova 1064a7398723SShteryana Shopova /* Read the priority. */ 1065a7398723SShteryana Shopova saved_errno = errno; 1066a7398723SShteryana Shopova errno = 0; 1067a7398723SShteryana Shopova v = strtoul(string, &endptr, 10); 1068a7398723SShteryana Shopova errno = saved_errno; 1069a7398723SShteryana Shopova 1070a7398723SShteryana Shopova if (v > SNMP_MAX_BPORT_PRIORITY || errno != 0 || *endptr != '.') { 1071a7398723SShteryana Shopova errno = saved_errno; 1072a7398723SShteryana Shopova warnx("Bad bridge port priority value %d", v); 1073a7398723SShteryana Shopova return (-1); 1074a7398723SShteryana Shopova } 1075a7398723SShteryana Shopova 1076a7398723SShteryana Shopova bport_id[0] = v; 1077a7398723SShteryana Shopova 1078a7398723SShteryana Shopova string = endptr + 1; 1079a7398723SShteryana Shopova v = strtoul(string, &endptr, 16); 1080a7398723SShteryana Shopova if (v > 0xff) { 1081a7398723SShteryana Shopova warnx("Bad port number - %d", v); 1082a7398723SShteryana Shopova return (-1); 1083a7398723SShteryana Shopova } 1084a7398723SShteryana Shopova 1085a7398723SShteryana Shopova bport_id[1] = v; 1086a7398723SShteryana Shopova 1087a7398723SShteryana Shopova if ((value->v.octetstring.octets = malloc(SNMP_BPORT_OCTETS)) == NULL) { 1088a7398723SShteryana Shopova syslog(LOG_ERR,"malloc failed: %s", strerror(errno)); 1089a7398723SShteryana Shopova return (-1); 1090a7398723SShteryana Shopova } 1091a7398723SShteryana Shopova 1092a7398723SShteryana Shopova value->v.octetstring.len = SNMP_BPORT_OCTETS; 1093a7398723SShteryana Shopova memcpy(value->v.octetstring.octets, bport_id, SNMP_BPORT_OCTETS); 1094a7398723SShteryana Shopova value->syntax = SNMP_SYNTAX_OCTETSTRING; 1095a7398723SShteryana Shopova return (1); 1096a7398723SShteryana Shopova } 1097a7398723SShteryana Shopova /************************************************************** 1098a7398723SShteryana Shopova * InetAddress 1099a7398723SShteryana Shopova ************************************************************** 1100a7398723SShteryana Shopova * INET-ADDRESS-MIB, REVISION "200502040000Z" 1101a7398723SShteryana Shopova * InetAddress ::= TEXTUAL-CONVENTION 1102a7398723SShteryana Shopova * STATUS current 1103a7398723SShteryana Shopova * DESCRIPTION 1104a7398723SShteryana Shopova * "Denotes a generic Internet address. 1105a7398723SShteryana Shopova * 1106a7398723SShteryana Shopova * An InetAddress value is always interpreted within the context 1107a7398723SShteryana Shopova * of an InetAddressType value. Every usage of the InetAddress 1108a7398723SShteryana Shopova * textual convention is required to specify the InetAddressType 1109a7398723SShteryana Shopova * object that provides the context. It is suggested that the 1110a7398723SShteryana Shopova * InetAddressType object be logically registered before the 1111a7398723SShteryana Shopova * object(s) that use the InetAddress textual convention, if 1112a7398723SShteryana Shopova * they appear in the same logical row. 1113a7398723SShteryana Shopova * 1114a7398723SShteryana Shopova * The value of an InetAddress object must always be 1115a7398723SShteryana Shopova * consistent with the value of the associated InetAddressType 1116a7398723SShteryana Shopova * object. Attempts to set an InetAddress object to a value 1117a7398723SShteryana Shopova * inconsistent with the associated InetAddressType 1118a7398723SShteryana Shopova * must fail with an inconsistentValue error. 1119a7398723SShteryana Shopova * 1120a7398723SShteryana Shopova * When this textual convention is used as the syntax of an 1121a7398723SShteryana Shopova * index object, there may be issues with the limit of 128 1122a7398723SShteryana Shopova * sub-identifiers specified in SMIv2, STD 58. In this case, 1123a7398723SShteryana Shopova * the object definition MUST include a 'SIZE' clause to 1124a7398723SShteryana Shopova * limit the number of potential instance sub-identifiers; 1125a7398723SShteryana Shopova * otherwise the applicable constraints MUST be stated in 1126a7398723SShteryana Shopova * the appropriate conceptual row DESCRIPTION clauses, or 1127a7398723SShteryana Shopova * in the surrounding documentation if there is no single 1128a7398723SShteryana Shopova * DESCRIPTION clause that is appropriate." 1129a7398723SShteryana Shopova * SYNTAX OCTET STRING (SIZE (0..255)) 1130a7398723SShteryana Shopova ************************************************************** 1131a7398723SShteryana Shopova * TODO: FIXME!!! syrinx: Since we do not support checking the 1132a7398723SShteryana Shopova * consistency of a varbinding based on the value of a previous 1133a7398723SShteryana Shopova * one, try to guess the type of address based on the 1134a7398723SShteryana Shopova * OctetString SIZE - 4 for IPv4, 16 for IPv6, others currently 1135a7398723SShteryana Shopova * not supported. 1136a7398723SShteryana Shopova */ 1137a7398723SShteryana Shopova static char * 1138a7398723SShteryana Shopova snmp_oct2inetaddr(uint32_t len, char *octets, char *buf) 1139a7398723SShteryana Shopova { 1140a7398723SShteryana Shopova int af; 1141a7398723SShteryana Shopova void *ip; 1142a7398723SShteryana Shopova struct in_addr ipv4; 1143a7398723SShteryana Shopova struct in6_addr ipv6; 1144a7398723SShteryana Shopova 1145a7398723SShteryana Shopova if (len > MAX_OCTSTRING_LEN || octets == NULL || buf == NULL) 1146a7398723SShteryana Shopova return (NULL); 1147a7398723SShteryana Shopova 1148a7398723SShteryana Shopova switch (len) { 1149a7398723SShteryana Shopova /* XXX: FIXME - IPv4*/ 1150a7398723SShteryana Shopova case 4: 1151a7398723SShteryana Shopova memcpy(&ipv4.s_addr, octets, sizeof(ipv4.s_addr)); 1152a7398723SShteryana Shopova af = AF_INET; 1153a7398723SShteryana Shopova ip = &ipv4; 1154a7398723SShteryana Shopova break; 1155a7398723SShteryana Shopova 1156a7398723SShteryana Shopova /* XXX: FIXME - IPv4*/ 1157a7398723SShteryana Shopova case 16: 1158a7398723SShteryana Shopova memcpy(ipv6.s6_addr, octets, sizeof(ipv6.s6_addr)); 1159a7398723SShteryana Shopova af = AF_INET6; 1160a7398723SShteryana Shopova ip = &ipv6; 1161a7398723SShteryana Shopova break; 1162a7398723SShteryana Shopova 1163a7398723SShteryana Shopova default: 1164a7398723SShteryana Shopova return (NULL); 1165a7398723SShteryana Shopova } 1166a7398723SShteryana Shopova 1167a7398723SShteryana Shopova if (inet_ntop(af, ip, buf, SNMP_INADDRS_STRSZ) == NULL) { 1168a7398723SShteryana Shopova warnx("inet_ntop failed - %s", strerror(errno)); 1169a7398723SShteryana Shopova return (NULL); 1170a7398723SShteryana Shopova } 1171a7398723SShteryana Shopova 1172a7398723SShteryana Shopova return (buf); 1173a7398723SShteryana Shopova } 1174a7398723SShteryana Shopova 1175a7398723SShteryana Shopova static char * 11760150b85aSEnji Cooper snmp_inetaddr2oct(char *str __unused, struct asn_oid *oid __unused) 1177a7398723SShteryana Shopova { 1178a7398723SShteryana Shopova return (NULL); 1179a7398723SShteryana Shopova } 1180a7398723SShteryana Shopova 1181a7398723SShteryana Shopova static int32_t 11820150b85aSEnji Cooper parse_inetaddr(struct snmp_value *value __unused, char *string __unused) 1183a7398723SShteryana Shopova { 1184a7398723SShteryana Shopova return (-1); 1185a7398723SShteryana Shopova } 1186a7398723SShteryana Shopova 1187a7398723SShteryana Shopova /************************************************************** 1188a7398723SShteryana Shopova * SNMP BITS type - XXX: FIXME 1189a7398723SShteryana Shopova **************************************************************/ 1190a7398723SShteryana Shopova static char * 1191a7398723SShteryana Shopova snmp_oct2bits(uint32_t len, char *octets, char *buf) 1192a7398723SShteryana Shopova { 1193a7398723SShteryana Shopova int i, bits; 1194a7398723SShteryana Shopova uint64_t value; 1195a7398723SShteryana Shopova 1196a7398723SShteryana Shopova if (len > sizeof(value) || octets == NULL || buf == NULL) 1197a7398723SShteryana Shopova return (NULL); 1198a7398723SShteryana Shopova 1199a7398723SShteryana Shopova for (i = len, value = 0, bits = 0; i > 0; i--, bits += 8) 1200a7398723SShteryana Shopova value += octets[i] << bits; 1201a7398723SShteryana Shopova 1202a7398723SShteryana Shopova buf[0]= '\0'; 1203a7398723SShteryana Shopova sprintf(buf, "0x%llx.",(long long unsigned) value); 1204a7398723SShteryana Shopova 1205a7398723SShteryana Shopova return (buf); 1206a7398723SShteryana Shopova } 1207a7398723SShteryana Shopova 1208a7398723SShteryana Shopova static char * 1209a7398723SShteryana Shopova snmp_bits2oct(char *str, struct asn_oid *oid) 1210a7398723SShteryana Shopova { 1211a7398723SShteryana Shopova char *endptr; 1212a7398723SShteryana Shopova int i, size, bits, saved_errno; 1213a7398723SShteryana Shopova uint64_t v, mask = 0xFF00000000000000; 1214a7398723SShteryana Shopova 1215a7398723SShteryana Shopova saved_errno = errno; 1216a7398723SShteryana Shopova errno = 0; 1217a7398723SShteryana Shopova 1218a7398723SShteryana Shopova v = strtoull(str, &endptr, 16); 1219a7398723SShteryana Shopova if (errno != 0) { 1220a7398723SShteryana Shopova warnx("Bad BITS value %s - %s", str, strerror(errno)); 1221a7398723SShteryana Shopova errno = saved_errno; 1222a7398723SShteryana Shopova return (NULL); 1223a7398723SShteryana Shopova } 1224a7398723SShteryana Shopova 1225a7398723SShteryana Shopova bits = 8; 1226a7398723SShteryana Shopova /* Determine length - up to 8 octets supported so far. */ 1227a7398723SShteryana Shopova for (size = sizeof(v); size > 0; size--) { 1228a7398723SShteryana Shopova if ((v & mask) != 0) 1229a7398723SShteryana Shopova break; 1230a7398723SShteryana Shopova mask = mask >> bits; 1231a7398723SShteryana Shopova } 1232a7398723SShteryana Shopova 1233a7398723SShteryana Shopova if (size == 0) 1234a7398723SShteryana Shopova size = 1; 1235a7398723SShteryana Shopova 1236a7398723SShteryana Shopova if (snmp_suboid_append(oid, (asn_subid_t) size) < 0) 1237a7398723SShteryana Shopova return (NULL); 1238a7398723SShteryana Shopova 1239a7398723SShteryana Shopova for (i = 0, bits = 0; i < size; i++, bits += 8) 1240a7398723SShteryana Shopova if (snmp_suboid_append(oid, 1241a7398723SShteryana Shopova (asn_subid_t)((v & mask) >> bits)) < 0) 1242a7398723SShteryana Shopova return (NULL); 1243a7398723SShteryana Shopova 1244a7398723SShteryana Shopova return (endptr); 1245a7398723SShteryana Shopova } 1246a7398723SShteryana Shopova 1247a7398723SShteryana Shopova static int32_t 1248a7398723SShteryana Shopova parse_bits(struct snmp_value *value, char *string) 1249a7398723SShteryana Shopova { 1250a7398723SShteryana Shopova char *endptr; 1251a7398723SShteryana Shopova int i, size, bits, saved_errno; 1252a7398723SShteryana Shopova uint64_t v, mask = 0xFF00000000000000; 1253a7398723SShteryana Shopova 1254a7398723SShteryana Shopova saved_errno = errno; 1255a7398723SShteryana Shopova errno = 0; 1256a7398723SShteryana Shopova 1257a7398723SShteryana Shopova v = strtoull(string, &endptr, 16); 1258a7398723SShteryana Shopova 1259a7398723SShteryana Shopova if (errno != 0) { 1260a7398723SShteryana Shopova warnx("Bad BITS value %s - %s", string, strerror(errno)); 1261a7398723SShteryana Shopova errno = saved_errno; 1262a7398723SShteryana Shopova return (-1); 1263a7398723SShteryana Shopova } 1264a7398723SShteryana Shopova 1265a7398723SShteryana Shopova bits = 8; 1266a7398723SShteryana Shopova /* Determine length - up to 8 octets supported so far. */ 1267a7398723SShteryana Shopova for (size = sizeof(v); size > 0; size--) { 1268a7398723SShteryana Shopova if ((v & mask) != 0) 1269a7398723SShteryana Shopova break; 1270a7398723SShteryana Shopova mask = mask >> bits; 1271a7398723SShteryana Shopova } 1272a7398723SShteryana Shopova 1273a7398723SShteryana Shopova if (size == 0) 1274a7398723SShteryana Shopova size = 1; 1275a7398723SShteryana Shopova 1276a7398723SShteryana Shopova if ((value->v.octetstring.octets = malloc(size)) == NULL) { 1277a7398723SShteryana Shopova syslog(LOG_ERR, "malloc failed: %s", strerror(errno)); 1278a7398723SShteryana Shopova return (-1); 1279a7398723SShteryana Shopova } 1280a7398723SShteryana Shopova 1281a7398723SShteryana Shopova value->v.octetstring.len = size; 1282a7398723SShteryana Shopova for (i = 0, bits = 0; i < size; i++, bits += 8) 1283a7398723SShteryana Shopova value->v.octetstring.octets[i] = (v & mask) >> bits; 1284a7398723SShteryana Shopova value->syntax = SNMP_SYNTAX_OCTETSTRING; 1285a7398723SShteryana Shopova return (1); 1286a7398723SShteryana Shopova } 1287