1216295Ssyrinx/*- 2216295Ssyrinx * Copyright (c) 2006 The FreeBSD Project 3216295Ssyrinx * All rights reserved. 4216295Ssyrinx * 5216295Ssyrinx * Author: Shteryana Shopova <syrinx@FreeBSD.org> 6216295Ssyrinx * 7216295Ssyrinx * Redistribution of this software and documentation and use in source and 8216295Ssyrinx * binary forms, with or without modification, are permitted provided that 9216295Ssyrinx * the following conditions are met: 10216295Ssyrinx * 11216295Ssyrinx * 1. Redistributions of source code or documentation must retain the above 12216295Ssyrinx * copyright notice, this list of conditions and the following disclaimer. 13216295Ssyrinx * 2. Redistributions in binary form must reproduce the above copyright 14216295Ssyrinx * notice, this list of conditions and the following disclaimer in the 15216295Ssyrinx * documentation and/or other materials provided with the distribution. 16216295Ssyrinx * 17216295Ssyrinx * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18216295Ssyrinx * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19216295Ssyrinx * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20216295Ssyrinx * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21216295Ssyrinx * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22216295Ssyrinx * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23216295Ssyrinx * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24216295Ssyrinx * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25216295Ssyrinx * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26216295Ssyrinx * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27216295Ssyrinx * SUCH DAMAGE. 28216295Ssyrinx * 29216295Ssyrinx * Textual conventions for OctetStrings 30216295Ssyrinx * 31216295Ssyrinx * $FreeBSD$ 32216295Ssyrinx */ 33216295Ssyrinx 34216295Ssyrinx#include <sys/param.h> 35216295Ssyrinx#include <sys/queue.h> 36216295Ssyrinx#include <sys/socket.h> 37216295Ssyrinx#include <sys/uio.h> 38216295Ssyrinx 39216295Ssyrinx#include <ctype.h> 40216295Ssyrinx#include <err.h> 41216295Ssyrinx#include <errno.h> 42216295Ssyrinx#include <fcntl.h> 43216295Ssyrinx#include <stdio.h> 44216295Ssyrinx#include <stdlib.h> 45216295Ssyrinx#include <string.h> 46216295Ssyrinx#include <syslog.h> 47216295Ssyrinx#include <unistd.h> 48216295Ssyrinx 49216295Ssyrinx#include <arpa/inet.h> 50216295Ssyrinx#include <netinet/in.h> 51216295Ssyrinx 52216295Ssyrinx#include <bsnmp/asn1.h> 53216295Ssyrinx#include <bsnmp/snmp.h> 54216295Ssyrinx#include "bsnmptc.h" 55216295Ssyrinx#include "bsnmptools.h" 56216295Ssyrinx 57216295Ssyrinx/* OctetString, DisplayString */ 58216295Ssyrinxstatic char *snmp_oct2str(uint32_t, char *, char *); 59216295Ssyrinxstatic char *snmp_str2asn_oid(char *, struct asn_oid *); 60216295Ssyrinxstatic int parse_octetstring(struct snmp_value *, char *); 61216295Ssyrinx 62216295Ssyrinx/* DateAndTime */ 63216295Ssyrinxstatic char *snmp_octstr2date(uint32_t, char *, char *); 64216295Ssyrinxstatic char *snmp_date2asn_oid(char * , struct asn_oid *); 65216295Ssyrinxstatic int parse_dateandtime(struct snmp_value *, char *); 66216295Ssyrinx 67216295Ssyrinx/* PhysAddress */ 68216295Ssyrinxstatic char *snmp_oct2physAddr(uint32_t, char *, char *); 69216295Ssyrinxstatic char *snmp_addr2asn_oid(char *, struct asn_oid *); 70216295Ssyrinxstatic int parse_physaddress(struct snmp_value *, char *); 71216295Ssyrinx 72216295Ssyrinx/* NTPTimeStamp */ 73216295Ssyrinxstatic char *snmp_oct2ntp_ts(uint32_t, char *, char *); 74216295Ssyrinxstatic char *snmp_ntp_ts2asn_oid(char *, struct asn_oid *); 75216295Ssyrinxstatic int parse_ntp_ts(struct snmp_value *, char *); 76216295Ssyrinx 77216295Ssyrinx/* BridgeId */ 78216295Ssyrinxstatic char *snmp_oct2bridgeid(uint32_t, char *, char *); 79216295Ssyrinxstatic char *snmp_bridgeid2oct(char *, struct asn_oid *); 80216295Ssyrinxstatic int parse_bridge_id(struct snmp_value *, char *); 81216295Ssyrinx 82216295Ssyrinx/* BridgePortId */ 83216295Ssyrinxstatic char *snmp_oct2bport_id(uint32_t, char *, char *); 84216295Ssyrinxstatic char *snmp_bport_id2oct(char *, struct asn_oid *); 85216295Ssyrinxstatic int parse_bport_id(struct snmp_value *, char *); 86216295Ssyrinx 87216295Ssyrinx/* InetAddress */ 88216295Ssyrinxstatic char *snmp_oct2inetaddr(uint32_t len, char *octets, char *buf); 89216295Ssyrinxstatic char *snmp_inetaddr2oct(char *str, struct asn_oid *oid); 90216295Ssyrinxstatic int32_t parse_inetaddr(struct snmp_value *value, char *string); 91216295Ssyrinx 92216295Ssyrinxstatic char *snmp_oct2bits(uint32_t len, char *octets, char *buf); 93216295Ssyrinxstatic char *snmp_bits2oct(char *str, struct asn_oid *oid); 94216295Ssyrinxstatic int32_t parse_bits(struct snmp_value *value, char *string); 95216295Ssyrinx 96216295Ssyrinxstruct snmp_text_conv { 97216295Ssyrinx enum snmp_tc tc; 98216295Ssyrinx const char *tc_str; 99216295Ssyrinx int32_t len; 100216295Ssyrinx snmp_oct2tc_f oct2tc; 101216295Ssyrinx snmp_tc2oid_f tc2oid; 102216295Ssyrinx snmp_tc2oct_f tc2oct; 103216295Ssyrinx} text_convs[] = { 104216295Ssyrinx { SNMP_STRING, "OctetString", SNMP_VAR_STRSZ, 105216295Ssyrinx snmp_oct2str, snmp_str2asn_oid, parse_octetstring }, 106216295Ssyrinx 107216295Ssyrinx { SNMP_DISPLAYSTRING, "DisplayString" , SNMP_VAR_STRSZ, 108216295Ssyrinx snmp_oct2str, snmp_str2asn_oid, parse_octetstring }, 109216295Ssyrinx 110216295Ssyrinx { SNMP_DATEANDTIME, "DateAndTime", SNMP_DATETIME_STRSZ, 111216295Ssyrinx snmp_octstr2date, snmp_date2asn_oid, parse_dateandtime }, 112216295Ssyrinx 113216295Ssyrinx { SNMP_PHYSADDR, "PhysAddress", SNMP_PHYSADDR_STRSZ, 114216295Ssyrinx snmp_oct2physAddr, snmp_addr2asn_oid, parse_physaddress }, 115216295Ssyrinx 116216295Ssyrinx { SNMP_ATMESI, "AtmESI", SNMP_PHYSADDR_STRSZ, 117216295Ssyrinx snmp_oct2physAddr, snmp_addr2asn_oid, parse_physaddress }, 118216295Ssyrinx 119216295Ssyrinx { SNMP_NTP_TIMESTAMP, "NTPTimeStamp", SNMP_NTP_TS_STRSZ, 120216295Ssyrinx snmp_oct2ntp_ts, snmp_ntp_ts2asn_oid, parse_ntp_ts }, 121216295Ssyrinx 122216295Ssyrinx { SNMP_MACADDRESS, "MacAddress", SNMP_PHYSADDR_STRSZ, 123216295Ssyrinx snmp_oct2physAddr, snmp_addr2asn_oid, parse_physaddress }, 124216295Ssyrinx 125216295Ssyrinx { SNMP_BRIDGE_ID, "BridgeId", SNMP_BRIDGEID_STRSZ, 126216295Ssyrinx snmp_oct2bridgeid, snmp_bridgeid2oct, parse_bridge_id }, 127216295Ssyrinx 128216295Ssyrinx { SNMP_BPORT_ID, "BridgePortId", SNMP_BPORT_STRSZ, 129216295Ssyrinx snmp_oct2bport_id, snmp_bport_id2oct, parse_bport_id }, 130216295Ssyrinx 131216295Ssyrinx { SNMP_INETADDRESS, "InetAddress", SNMP_INADDRS_STRSZ, 132216295Ssyrinx snmp_oct2inetaddr, snmp_inetaddr2oct, parse_inetaddr }, 133216295Ssyrinx 134216295Ssyrinx { SNMP_TC_OWN, "BITS", SNMP_VAR_STRSZ, 135216295Ssyrinx snmp_oct2bits, snmp_bits2oct, parse_bits }, 136216295Ssyrinx 137216295Ssyrinx { SNMP_UNKNOWN, "Unknown", SNMP_VAR_STRSZ, snmp_oct2str, 138216295Ssyrinx snmp_str2asn_oid, parse_octetstring } /* keep last */ 139216295Ssyrinx}; 140216295Ssyrinx 141216295Ssyrinx/* Common API */ 142216295Ssyrinxenum snmp_tc 143216295Ssyrinxsnmp_get_tc(char *str) 144216295Ssyrinx{ 145216295Ssyrinx int i; 146216295Ssyrinx for (i = 0; i < SNMP_UNKNOWN; i++) { 147216295Ssyrinx if (!strncmp(text_convs[i].tc_str, str, 148216295Ssyrinx strlen(text_convs[i].tc_str))) 149216295Ssyrinx return (text_convs[i].tc); 150216295Ssyrinx } 151216295Ssyrinx 152216295Ssyrinx return (SNMP_STRING); 153216295Ssyrinx} 154216295Ssyrinx 155216295Ssyrinxchar * 156216295Ssyrinxsnmp_oct2tc(enum snmp_tc tc, uint32_t len, char *octets) 157216295Ssyrinx{ 158216295Ssyrinx uint32_t tc_len; 159216295Ssyrinx char * buf; 160216295Ssyrinx 161216295Ssyrinx if (tc < 0 || tc > SNMP_UNKNOWN) 162216295Ssyrinx tc = SNMP_UNKNOWN; 163216295Ssyrinx 164216295Ssyrinx if (text_convs[tc].len > 0) 165216295Ssyrinx tc_len = text_convs[tc].len; 166216295Ssyrinx else 167216295Ssyrinx tc_len = 2 * len + 3; 168216295Ssyrinx 169216295Ssyrinx if ((buf = malloc(tc_len)) == NULL ) { 170216295Ssyrinx syslog(LOG_ERR, "malloc failed - %s", strerror(errno)); 171216295Ssyrinx return (NULL); 172216295Ssyrinx } 173216295Ssyrinx 174216295Ssyrinx memset(buf, 0, tc_len); 175216295Ssyrinx if (text_convs[tc].oct2tc(len, octets, buf) == NULL) { 176216295Ssyrinx free(buf); 177216295Ssyrinx return (NULL); 178216295Ssyrinx } 179216295Ssyrinx 180216295Ssyrinx return (buf); 181216295Ssyrinx} 182216295Ssyrinx 183216295Ssyrinxchar * 184216295Ssyrinxsnmp_tc2oid(enum snmp_tc tc, char *str, struct asn_oid *oid) 185216295Ssyrinx{ 186216295Ssyrinx if (tc < 0 || tc > SNMP_UNKNOWN) 187216295Ssyrinx tc = SNMP_UNKNOWN; 188216295Ssyrinx 189216295Ssyrinx return (text_convs[tc].tc2oid(str, oid)); 190216295Ssyrinx} 191216295Ssyrinx 192216295Ssyrinxint32_t 193216295Ssyrinxsnmp_tc2oct(enum snmp_tc tc, struct snmp_value *value, char *string) 194216295Ssyrinx{ 195216295Ssyrinx if (tc < 0 || tc > SNMP_UNKNOWN) 196216295Ssyrinx tc = SNMP_UNKNOWN; 197216295Ssyrinx 198216295Ssyrinx return (text_convs[tc].tc2oct(value, string)); 199216295Ssyrinx} 200216295Ssyrinx 201216295Ssyrinx/***************************************************** 202216295Ssyrinx* Basic OctetString type. 203216295Ssyrinx*/ 204216295Ssyrinxstatic char * 205216295Ssyrinxsnmp_oct2str(uint32_t len, char *octets, char *buf) 206216295Ssyrinx{ 207216295Ssyrinx uint8_t binary = 0; 208216295Ssyrinx uint32_t i; 209216295Ssyrinx char *ptr; 210216295Ssyrinx 211216295Ssyrinx if (len > MAX_OCTSTRING_LEN || octets == NULL || buf == NULL) 212216295Ssyrinx return (NULL); 213216295Ssyrinx 214216295Ssyrinx for (ptr = buf, i = 0; i < len; i++) 215216295Ssyrinx if (!isprint(octets[i])) { 216216295Ssyrinx binary = 1; 217216295Ssyrinx buf += sprintf(buf, "0x"); 218216295Ssyrinx break; 219216295Ssyrinx } 220216295Ssyrinx 221216295Ssyrinx for (ptr = buf, i = 0; i < len; i++) 222216295Ssyrinx if (!binary) 223216295Ssyrinx ptr += sprintf(ptr, "%c", octets[i]); 224216295Ssyrinx else 225216295Ssyrinx ptr += sprintf(ptr, "%2.2x", (u_char)octets[i]); 226216295Ssyrinx 227216295Ssyrinx return (buf); 228216295Ssyrinx} 229216295Ssyrinx 230216295Ssyrinxstatic char * 231216295Ssyrinxsnmp_str2asn_oid(char *str, struct asn_oid *oid) 232216295Ssyrinx{ 233216295Ssyrinx uint32_t i, len = 0; 234216295Ssyrinx 235216295Ssyrinx /* 236216295Ssyrinx * OctetStrings are allowed max length of ASN_MAXOCTETSTRING, 237216295Ssyrinx * but trying to index an entry with such a long OctetString 238216295Ssyrinx * will fail anyway. 239216295Ssyrinx */ 240216295Ssyrinx for (len = 0; len < ASN_MAXOIDLEN; len++) { 241216295Ssyrinx if (strchr(",]", *(str + len)) != NULL) 242216295Ssyrinx break; 243216295Ssyrinx } 244216295Ssyrinx 245216295Ssyrinx if (len >= ASN_MAXOIDLEN) 246216295Ssyrinx return (NULL); 247216295Ssyrinx 248216295Ssyrinx if (snmp_suboid_append(oid, (asn_subid_t) len) < 0) 249216295Ssyrinx return (NULL); 250216295Ssyrinx 251216295Ssyrinx for (i = 0; i < len; i++) 252216295Ssyrinx if (snmp_suboid_append(oid, (asn_subid_t) *(str + i)) < 0) 253216295Ssyrinx return (NULL); 254216295Ssyrinx 255216295Ssyrinx return (str + len); 256216295Ssyrinx} 257216295Ssyrinx 258216295Ssyrinxstatic int32_t 259216295Ssyrinxparse_octetstring(struct snmp_value *value, char *val) 260216295Ssyrinx{ 261216295Ssyrinx size_t len; 262216295Ssyrinx 263216295Ssyrinx if ((len = strlen(val)) >= MAX_OCTSTRING_LEN) { 264216295Ssyrinx warnx("Octetstring too long - %d is max allowed", 265216295Ssyrinx MAX_OCTSTRING_LEN - 1); 266216295Ssyrinx return (-1); 267216295Ssyrinx } 268216295Ssyrinx 269216295Ssyrinx value->v.octetstring.len = len; 270216295Ssyrinx 271216295Ssyrinx if((value->v.octetstring.octets = malloc(len)) == NULL) { 272216295Ssyrinx syslog(LOG_ERR,"malloc failed: %s", strerror(errno)); 273216295Ssyrinx return (-1); 274216295Ssyrinx } 275216295Ssyrinx 276216295Ssyrinx memcpy(value->v.octetstring.octets, val, len); 277216295Ssyrinx value->syntax = SNMP_SYNTAX_OCTETSTRING; 278216295Ssyrinx 279216295Ssyrinx return (0); 280216295Ssyrinx} 281216295Ssyrinx 282216295Ssyrinx/************************************************************* 283216295Ssyrinx * DateAndTime 284216295Ssyrinx ************************************************************* 285216295Ssyrinx * rfc 2579 specification: 286216295Ssyrinx * DateAndTime ::= TEXTUAL-CONVENTION 287216295Ssyrinx * DISPLAY-HINT "2d-1d-1d,1d:1d:1d.1d,1a1d:1d" 288216295Ssyrinx * STATUS current 289216295Ssyrinx * DESCRIPTION 290216295Ssyrinx * "A date-time specification. 291216295Ssyrinx * 292216295Ssyrinx * field octets contents range 293216295Ssyrinx * ----- ------ -------- ----- 294216295Ssyrinx * 1 1-2 year* 0..65536 295216295Ssyrinx * 2 3 month 1..12 296216295Ssyrinx * 3 4 day 1..31 297216295Ssyrinx * 4 5 hour 0..23 298216295Ssyrinx * 5 6 minutes 0..59 299216295Ssyrinx * 6 7 seconds 0..60 300216295Ssyrinx * (use 60 for leap-second) 301216295Ssyrinx * 7 8 deci-seconds 0..9 302216295Ssyrinx * 8 9 direction from UTC '+' / '-' 303216295Ssyrinx * 9 10 hours from UTC* 0..13 304216295Ssyrinx * 10 11 minutes from UTC 0..59 305216295Ssyrinx * 306216295Ssyrinx * * Notes: 307216295Ssyrinx * - the value of year is in network-byte order 308216295Ssyrinx * - daylight saving time in New Zealand is +13 309216295Ssyrinx * 310216295Ssyrinx * For example, Tuesday May 26, 1992 at 1:30:15 PM EDT would be 311216295Ssyrinx * displayed as: 312216295Ssyrinx * 313216295Ssyrinx * 1992-5-26,13:30:15.0,-4:0 314216295Ssyrinx */ 315216295Ssyrinxstatic char * 316216295Ssyrinxsnmp_octstr2date(uint32_t len, char *octets, char *buf) 317216295Ssyrinx{ 318216295Ssyrinx int year; 319216295Ssyrinx char *ptr; 320216295Ssyrinx 321216295Ssyrinx if (len != SNMP_DATETIME_OCTETS || octets == NULL || buf == NULL) 322216295Ssyrinx return (NULL); 323216295Ssyrinx 324216295Ssyrinx buf[0]= '\0'; 325216295Ssyrinx year = (octets[0] << 8); 326216295Ssyrinx year += (octets[1]); 327216295Ssyrinx 328216295Ssyrinx ptr = buf; 329216295Ssyrinx ptr += sprintf(ptr, "%4.4d-%.2d-%.2d, ", year, octets[2],octets[3]); 330216295Ssyrinx ptr += sprintf(ptr, "%2.2d:%2.2d:%2.2d.%.2d, ", octets[4],octets[5], 331216295Ssyrinx octets[6],octets[7]); 332216295Ssyrinx ptr += sprintf(ptr, "%c%.2d:%.2d", octets[8],octets[9],octets[10]); 333216295Ssyrinx 334216295Ssyrinx return (buf); 335216295Ssyrinx} 336216295Ssyrinx 337216295Ssyrinxstatic char * 338216295Ssyrinxsnmp_date2asn_oid(char *str, struct asn_oid *oid) 339216295Ssyrinx{ 340216295Ssyrinx char *endptr, *ptr; 341216295Ssyrinx uint32_t v; 342216295Ssyrinx int32_t saved_errno; 343216295Ssyrinx 344216295Ssyrinx if (snmp_suboid_append(oid, (asn_subid_t) SNMP_DATETIME_OCTETS) < 0) 345216295Ssyrinx return (NULL); 346216295Ssyrinx 347216295Ssyrinx /* Read 'YYYY-' and write it in two subs. */ 348216295Ssyrinx ptr = str; 349216295Ssyrinx saved_errno = errno; 350216295Ssyrinx errno = 0; 351216295Ssyrinx v = strtoul(ptr, &endptr, 10); 352216295Ssyrinx if (v > 0xffff) 353216295Ssyrinx goto error; 354216295Ssyrinx else 355216295Ssyrinx errno = saved_errno; 356216295Ssyrinx if (*endptr != '-') 357216295Ssyrinx goto error1; 358216295Ssyrinx if (snmp_suboid_append(oid, (asn_subid_t) ((v & 0xff00) >> 8)) < 0) 359216295Ssyrinx return (NULL); 360216295Ssyrinx if (snmp_suboid_append(oid, (asn_subid_t) (v & 0xff)) < 0) 361216295Ssyrinx return (NULL); 362216295Ssyrinx 363216295Ssyrinx /* 'MM-' */ 364216295Ssyrinx ptr = endptr + 1; 365216295Ssyrinx saved_errno = errno; 366216295Ssyrinx v = strtoul(ptr, &endptr, 10); 367216295Ssyrinx if (errno != 0) 368216295Ssyrinx goto error; 369216295Ssyrinx else 370216295Ssyrinx errno = saved_errno; 371216295Ssyrinx if (*endptr != '-') 372216295Ssyrinx goto error1; 373216295Ssyrinx if (snmp_suboid_append(oid, (asn_subid_t) v) < 0) 374216295Ssyrinx return (NULL); 375216295Ssyrinx 376216295Ssyrinx /* 'DD,' */ 377216295Ssyrinx ptr = endptr + 1; 378216295Ssyrinx saved_errno = errno; 379216295Ssyrinx v = strtoul(ptr, &endptr, 10); 380216295Ssyrinx if (errno != 0) 381216295Ssyrinx goto error; 382216295Ssyrinx else 383216295Ssyrinx errno = saved_errno; 384216295Ssyrinx if (*endptr != '-') 385216295Ssyrinx goto error1; 386216295Ssyrinx if (snmp_suboid_append(oid, (asn_subid_t) v) < 0) 387216295Ssyrinx return (NULL); 388216295Ssyrinx 389216295Ssyrinx /* 'HH:' */ 390216295Ssyrinx ptr = endptr + 1; 391216295Ssyrinx saved_errno = errno; 392216295Ssyrinx v = strtoul(ptr, &endptr, 10); 393216295Ssyrinx if (errno != 0) 394216295Ssyrinx goto error; 395216295Ssyrinx else 396216295Ssyrinx errno = saved_errno; 397216295Ssyrinx if (*endptr != ':') 398216295Ssyrinx goto error1; 399216295Ssyrinx if (snmp_suboid_append(oid, (asn_subid_t) v) < 0) 400216295Ssyrinx return (NULL); 401216295Ssyrinx 402216295Ssyrinx /* 'MM:' */ 403216295Ssyrinx ptr = endptr + 1; 404216295Ssyrinx saved_errno = errno; 405216295Ssyrinx v = strtoul(ptr, &endptr, 10); 406216295Ssyrinx if (errno != 0) 407216295Ssyrinx goto error; 408216295Ssyrinx else 409216295Ssyrinx errno = saved_errno; 410216295Ssyrinx if (*endptr != ':') 411216295Ssyrinx goto error1; 412216295Ssyrinx if (snmp_suboid_append(oid, (asn_subid_t) v) < 0) 413216295Ssyrinx return (NULL); 414216295Ssyrinx 415216295Ssyrinx /* 'SS.' */ 416216295Ssyrinx ptr = endptr + 1; 417216295Ssyrinx saved_errno = errno; 418216295Ssyrinx v = strtoul(ptr, &endptr, 10); 419216295Ssyrinx if (errno != 0) 420216295Ssyrinx goto error; 421216295Ssyrinx else 422216295Ssyrinx errno = saved_errno; 423216295Ssyrinx if (*endptr != '.') 424216295Ssyrinx goto error1; 425216295Ssyrinx if (snmp_suboid_append(oid, (asn_subid_t) v) < 0) 426216295Ssyrinx return (NULL); 427216295Ssyrinx 428216295Ssyrinx /* 'M(mseconds),' */ 429216295Ssyrinx ptr = endptr + 1; 430216295Ssyrinx saved_errno = errno; 431216295Ssyrinx v = strtoul(ptr, &endptr, 10); 432216295Ssyrinx if (errno != 0) 433216295Ssyrinx goto error; 434216295Ssyrinx else 435216295Ssyrinx errno = saved_errno; 436216295Ssyrinx if (*endptr != ',') 437216295Ssyrinx goto error1; 438216295Ssyrinx if (snmp_suboid_append(oid, (asn_subid_t) v) < 0) 439216295Ssyrinx return (NULL); 440216295Ssyrinx 441216295Ssyrinx /* 'UTC' - optional */ 442216295Ssyrinx ptr = endptr + 1; 443216295Ssyrinx if (*ptr == 'U' && *(ptr + 1) == 'T' && *(ptr + 1) == 'C') 444216295Ssyrinx ptr += 3; 445216295Ssyrinx 446216295Ssyrinx /* '+/-' */ 447216295Ssyrinx if (*ptr == '-' || *ptr == '+') { 448216295Ssyrinx if (snmp_suboid_append(oid, (asn_subid_t) (*ptr)) < 0) 449216295Ssyrinx return (NULL); 450216295Ssyrinx } else 451216295Ssyrinx goto error1; 452216295Ssyrinx 453216295Ssyrinx /* 'HH:' */ 454216295Ssyrinx ptr = endptr + 1; 455216295Ssyrinx saved_errno = errno; 456216295Ssyrinx v = strtoul(ptr, &endptr, 10); 457216295Ssyrinx if (errno != 0) 458216295Ssyrinx goto error; 459216295Ssyrinx else 460216295Ssyrinx errno = saved_errno; 461216295Ssyrinx if (*endptr != ':') 462216295Ssyrinx goto error1; 463216295Ssyrinx if (snmp_suboid_append(oid, (asn_subid_t) v) < 0) 464216295Ssyrinx return (NULL); 465216295Ssyrinx 466216295Ssyrinx /* 'MM' - last one - ignore endptr here. */ 467216295Ssyrinx ptr = endptr + 1; 468216295Ssyrinx saved_errno = errno; 469216295Ssyrinx v = strtoul(ptr, &endptr, 10); 470216295Ssyrinx if (errno != 0) 471216295Ssyrinx goto error; 472216295Ssyrinx else 473216295Ssyrinx errno = saved_errno; 474216295Ssyrinx if (snmp_suboid_append(oid, (asn_subid_t) v) < 0) 475216295Ssyrinx return (NULL); 476216295Ssyrinx 477216295Ssyrinx return (endptr); 478216295Ssyrinx 479216295Ssyrinx error: 480216295Ssyrinx errno = saved_errno; 481216295Ssyrinx error1: 482216295Ssyrinx warnx("Date value %s not supported", str); 483216295Ssyrinx return (NULL); 484216295Ssyrinx} 485216295Ssyrinx 486216295Ssyrinx/* Read a DateAndTime string eg. 1992-5-26,13:30:15.0,-4:0. */ 487216295Ssyrinxstatic int32_t 488216295Ssyrinxparse_dateandtime(struct snmp_value *sv, char *val) 489216295Ssyrinx{ 490216295Ssyrinx char *endptr; 491216295Ssyrinx uint32_t v; 492216295Ssyrinx uint8_t date[SNMP_DATETIME_OCTETS]; 493216295Ssyrinx 494216295Ssyrinx /* 'YYYY-' */ 495216295Ssyrinx v = strtoul(val, &endptr, 10); 496216295Ssyrinx if (v > 0xffff || *endptr != '-') 497216295Ssyrinx goto error; 498216295Ssyrinx date[0] = ((v & 0xff00) >> 8); 499216295Ssyrinx date[1] = (v & 0xff); 500216295Ssyrinx val = endptr + 1; 501216295Ssyrinx 502216295Ssyrinx /* 'MM-' */ 503216295Ssyrinx v = strtoul(val, &endptr, 10); 504216295Ssyrinx if (v == 0 || v > 12 || *endptr != '-') 505216295Ssyrinx goto error; 506216295Ssyrinx date[2] = v; 507216295Ssyrinx val = endptr + 1; 508216295Ssyrinx 509216295Ssyrinx /* 'DD,' */ 510216295Ssyrinx v = strtoul(val, &endptr, 10); 511216295Ssyrinx if (v == 0 || v > 31 || *endptr != ',') 512216295Ssyrinx goto error; 513216295Ssyrinx date[3] = v; 514216295Ssyrinx val = endptr + 1; 515216295Ssyrinx 516216295Ssyrinx /* 'HH:' */ 517216295Ssyrinx v = strtoul(val, &endptr, 10); 518216295Ssyrinx if (v > 23 || *endptr != ':') 519216295Ssyrinx goto error; 520216295Ssyrinx date[4] = v; 521216295Ssyrinx val = endptr + 1; 522216295Ssyrinx 523216295Ssyrinx /* 'MM:' */ 524216295Ssyrinx v = strtoul(val, &endptr, 10); 525216295Ssyrinx if (v > 59 || *endptr != ':') 526216295Ssyrinx goto error; 527216295Ssyrinx date[5] = v; 528216295Ssyrinx val = endptr + 1; 529216295Ssyrinx 530216295Ssyrinx /* 'SS.' */ 531216295Ssyrinx v = strtoul(val, &endptr, 10); 532216295Ssyrinx if (v > 60 || *endptr != '.') 533216295Ssyrinx goto error; 534216295Ssyrinx date[6] = v; 535216295Ssyrinx val = endptr + 1; 536216295Ssyrinx 537216295Ssyrinx /* '(deci-)s,' */ 538216295Ssyrinx v = strtoul(val, &endptr, 10); 539216295Ssyrinx if (v > 9 || *endptr != ',') 540216295Ssyrinx goto error; 541216295Ssyrinx date[7] = v; 542216295Ssyrinx val = endptr + 1; 543216295Ssyrinx 544216295Ssyrinx /* offset - '+/-' */ 545216295Ssyrinx if (*val != '-' && *val != '+') 546216295Ssyrinx goto error; 547216295Ssyrinx date[8] = (uint8_t) *val; 548216295Ssyrinx val = endptr + 1; 549216295Ssyrinx 550216295Ssyrinx /* 'HH:' - offset from UTC */ 551216295Ssyrinx v = strtoul(val, &endptr, 10); 552216295Ssyrinx if (v > 13 || *endptr != ':') 553216295Ssyrinx goto error; 554216295Ssyrinx date[9] = v; 555216295Ssyrinx val = endptr + 1; 556216295Ssyrinx 557216295Ssyrinx /* 'MM'\0'' offset from UTC */ 558216295Ssyrinx v = strtoul(val, &endptr, 10); 559216295Ssyrinx if (v > 59 || *endptr != '\0') 560216295Ssyrinx goto error; 561216295Ssyrinx date[10] = v; 562216295Ssyrinx 563216295Ssyrinx if ((sv->v.octetstring.octets = malloc(SNMP_DATETIME_OCTETS)) == NULL) { 564216295Ssyrinx warnx("malloc() failed - %s", strerror(errno)); 565216295Ssyrinx return (-1); 566216295Ssyrinx } 567216295Ssyrinx 568216295Ssyrinx sv->v.octetstring.len = SNMP_DATETIME_OCTETS; 569216295Ssyrinx memcpy(sv->v.octetstring.octets, date, SNMP_DATETIME_OCTETS); 570216295Ssyrinx sv->syntax = SNMP_SYNTAX_OCTETSTRING; 571216295Ssyrinx return (1); 572216295Ssyrinx 573216295Ssyrinx error: 574216295Ssyrinx warnx("Date value %s not supported", val); 575216295Ssyrinx return (-1); 576216295Ssyrinx} 577216295Ssyrinx 578216295Ssyrinx/************************************************************** 579216295Ssyrinx * PhysAddress 580216295Ssyrinx */ 581216295Ssyrinxstatic char * 582216295Ssyrinxsnmp_oct2physAddr(uint32_t len, char *octets, char *buf) 583216295Ssyrinx{ 584216295Ssyrinx char *ptr; 585216295Ssyrinx uint32_t i; 586216295Ssyrinx 587216295Ssyrinx if (len != SNMP_PHYSADDR_OCTETS || octets == NULL || buf == NULL) 588216295Ssyrinx return (NULL); 589216295Ssyrinx 590216295Ssyrinx buf[0]= '\0'; 591216295Ssyrinx 592216295Ssyrinx ptr = buf; 593216295Ssyrinx ptr += sprintf(ptr, "%2.2x", octets[0]); 594216295Ssyrinx for (i = 1; i < 6; i++) 595216295Ssyrinx ptr += sprintf(ptr, ":%2.2x", octets[i]); 596216295Ssyrinx 597216295Ssyrinx return (buf); 598216295Ssyrinx} 599216295Ssyrinx 600216295Ssyrinxstatic char * 601216295Ssyrinxsnmp_addr2asn_oid(char *str, struct asn_oid *oid) 602216295Ssyrinx{ 603216295Ssyrinx char *endptr, *ptr; 604216295Ssyrinx uint32_t v, i; 605216295Ssyrinx int saved_errno; 606216295Ssyrinx 607216295Ssyrinx if (snmp_suboid_append(oid, (asn_subid_t) SNMP_PHYSADDR_OCTETS) < 0) 608216295Ssyrinx return (NULL); 609216295Ssyrinx 610216295Ssyrinx ptr = str; 611216295Ssyrinx for (i = 0; i < 5; i++) { 612216295Ssyrinx saved_errno = errno; 613216295Ssyrinx v = strtoul(ptr, &endptr, 16); 614216295Ssyrinx errno = saved_errno; 615216295Ssyrinx if (v > 0xff) { 616216295Ssyrinx warnx("Integer value %s not supported", str); 617216295Ssyrinx return (NULL); 618216295Ssyrinx } 619216295Ssyrinx if (*endptr != ':') { 620216295Ssyrinx warnx("Failed adding oid - %s",str); 621216295Ssyrinx return (NULL); 622216295Ssyrinx } 623216295Ssyrinx if (snmp_suboid_append(oid, (asn_subid_t) v) < 0) 624216295Ssyrinx return (NULL); 625216295Ssyrinx ptr = endptr + 1; 626216295Ssyrinx } 627216295Ssyrinx 628216295Ssyrinx /* The last one - don't check the ending char here. */ 629216295Ssyrinx saved_errno = errno; 630216295Ssyrinx v = strtoul(ptr, &endptr, 16); 631216295Ssyrinx errno = saved_errno; 632216295Ssyrinx if (v > 0xff) { 633216295Ssyrinx warnx("Integer value %s not supported", str); 634216295Ssyrinx return (NULL); 635216295Ssyrinx } 636216295Ssyrinx if (snmp_suboid_append(oid, (asn_subid_t) v) < 0) 637216295Ssyrinx return (NULL); 638216295Ssyrinx 639216295Ssyrinx return (endptr); 640216295Ssyrinx} 641216295Ssyrinx 642216295Ssyrinxstatic int32_t 643216295Ssyrinxparse_physaddress(struct snmp_value *sv, char *val) 644216295Ssyrinx{ 645216295Ssyrinx char *endptr; 646216295Ssyrinx int32_t i; 647216295Ssyrinx uint32_t v; 648216295Ssyrinx uint8_t phys_addr[SNMP_PHYSADDR_OCTETS]; 649216295Ssyrinx 650216295Ssyrinx for (i = 0; i < 5; i++) { 651216295Ssyrinx v = strtoul(val, &endptr, 16); 652216295Ssyrinx if (v > 0xff) { 653216295Ssyrinx warnx("Integer value %s not supported", val); 654216295Ssyrinx return (-1); 655216295Ssyrinx } 656216295Ssyrinx if(*endptr != ':') { 657216295Ssyrinx warnx("Failed reading octet - %s", val); 658216295Ssyrinx return (-1); 659216295Ssyrinx } 660216295Ssyrinx phys_addr[i] = v; 661216295Ssyrinx val = endptr + 1; 662216295Ssyrinx } 663216295Ssyrinx 664216295Ssyrinx /* The last one - don't check the ending char here. */ 665216295Ssyrinx v = strtoul(val, &endptr, 16); 666216295Ssyrinx if (v > 0xff) { 667216295Ssyrinx warnx("Integer value %s not supported", val); 668216295Ssyrinx return (-1); 669216295Ssyrinx } 670216295Ssyrinx phys_addr[5] = v; 671216295Ssyrinx 672216295Ssyrinx if ((sv->v.octetstring.octets = malloc(SNMP_PHYSADDR_OCTETS)) == NULL) { 673216295Ssyrinx syslog(LOG_ERR,"malloc failed: %s", strerror(errno)); 674216295Ssyrinx return (-1); 675216295Ssyrinx } 676216295Ssyrinx 677216295Ssyrinx sv->v.octetstring.len = SNMP_PHYSADDR_OCTETS; 678216295Ssyrinx memcpy(sv->v.octetstring.octets, phys_addr, SNMP_PHYSADDR_OCTETS); 679216295Ssyrinx sv->syntax = SNMP_SYNTAX_OCTETSTRING; 680216295Ssyrinx return (1); 681216295Ssyrinx} 682216295Ssyrinx 683216295Ssyrinx/************************************************************** 684216295Ssyrinx * NTPTimeStamp 685216295Ssyrinx ************************************************************** 686216295Ssyrinx * NTP MIB, Revision 0.2, 7/25/97: 687216295Ssyrinx * NTPTimeStamp ::= TEXTUAL-CONVENTION 688216295Ssyrinx * DISPLAY-HINT "4x.4x" 689216295Ssyrinx * STATUS current 690216295Ssyrinx * DESCRIPTION 691216295Ssyrinx * "" 692216295Ssyrinx * SYNTAX OCTET STRING (SIZE(8)) 693216295Ssyrinx */ 694216295Ssyrinxstatic char * 695216295Ssyrinxsnmp_oct2ntp_ts(uint32_t len, char *octets, char *buf) 696216295Ssyrinx{ 697216295Ssyrinx char *ptr; 698216295Ssyrinx uint32_t i; 699216295Ssyrinx 700216295Ssyrinx if (len != SNMP_NTP_TS_OCTETS || octets == NULL || buf == NULL) 701216295Ssyrinx return (NULL); 702216295Ssyrinx 703216295Ssyrinx buf[0]= '\0'; 704216295Ssyrinx 705216295Ssyrinx ptr = buf; 706216295Ssyrinx i = octets[0] * 1000 + octets[1] * 100 + octets[2] * 10 + octets[3]; 707216295Ssyrinx ptr += sprintf(ptr, "%4.4d", i); 708216295Ssyrinx i = octets[4] * 1000 + octets[5] * 100 + octets[6] * 10 + octets[7]; 709216295Ssyrinx ptr += sprintf(ptr, ".%4.4d", i); 710216295Ssyrinx 711216295Ssyrinx return (buf); 712216295Ssyrinx} 713216295Ssyrinx 714216295Ssyrinxstatic char * 715216295Ssyrinxsnmp_ntp_ts2asn_oid(char *str, struct asn_oid *oid) 716216295Ssyrinx{ 717216295Ssyrinx char *endptr, *ptr; 718216295Ssyrinx uint32_t v, i, d; 719216295Ssyrinx struct asn_oid suboid; 720216295Ssyrinx int saved_errno; 721216295Ssyrinx 722216295Ssyrinx if (snmp_suboid_append(oid, (asn_subid_t) SNMP_NTP_TS_OCTETS) < 0) 723216295Ssyrinx return (NULL); 724216295Ssyrinx 725216295Ssyrinx ptr = str; 726216295Ssyrinx saved_errno = errno; 727216295Ssyrinx v = strtoul(ptr, &endptr, 10); 728216295Ssyrinx if (errno != 0 || (v / 1000) > 9) { 729216295Ssyrinx warnx("Integer value %s not supported", str); 730216295Ssyrinx errno = saved_errno; 731216295Ssyrinx return (NULL); 732216295Ssyrinx } else 733216295Ssyrinx errno = saved_errno; 734216295Ssyrinx 735216295Ssyrinx if (*endptr != '.') { 736216295Ssyrinx warnx("Failed adding oid - %s",str); 737216295Ssyrinx return (NULL); 738216295Ssyrinx } 739216295Ssyrinx 740216295Ssyrinx memset(&suboid, 0, sizeof(struct asn_oid)); 741216295Ssyrinx suboid.len = SNMP_NTP_TS_OCTETS; 742216295Ssyrinx 743216295Ssyrinx for (i = 0, d = 1000; i < 4; i++) { 744216295Ssyrinx suboid.subs[i] = v / d; 745216295Ssyrinx v = v % d; 746216295Ssyrinx d = d / 10; 747216295Ssyrinx } 748216295Ssyrinx 749216295Ssyrinx ptr = endptr + 1; 750216295Ssyrinx saved_errno = errno; 751216295Ssyrinx v = strtoul(ptr, &endptr, 10); 752216295Ssyrinx if (errno != 0 || (v / 1000) > 9) { 753216295Ssyrinx warnx("Integer value %s not supported", str); 754216295Ssyrinx errno = saved_errno; 755216295Ssyrinx return (NULL); 756216295Ssyrinx } else 757216295Ssyrinx errno = saved_errno; 758216295Ssyrinx 759216295Ssyrinx for (i = 0, d = 1000; i < 4; i++) { 760216295Ssyrinx suboid.subs[i + 4] = v / d; 761216295Ssyrinx v = v % d; 762216295Ssyrinx d = d / 10; 763216295Ssyrinx } 764216295Ssyrinx 765216295Ssyrinx asn_append_oid(oid, &suboid); 766216295Ssyrinx return (endptr); 767216295Ssyrinx} 768216295Ssyrinx 769216295Ssyrinxstatic int32_t 770216295Ssyrinxparse_ntp_ts(struct snmp_value *sv, char *val) 771216295Ssyrinx{ 772216295Ssyrinx char *endptr; 773216295Ssyrinx int32_t i, d, saved_errno; 774216295Ssyrinx uint32_t v; 775216295Ssyrinx uint8_t ntp_ts[SNMP_NTP_TS_OCTETS]; 776216295Ssyrinx 777216295Ssyrinx saved_errno = errno; 778216295Ssyrinx v = strtoul(val, &endptr, 10); 779216295Ssyrinx if (errno != 0 || (v / 1000) > 9) { 780216295Ssyrinx saved_errno = errno; 781216295Ssyrinx warnx("Integer value %s not supported", val); 782216295Ssyrinx return (-1); 783216295Ssyrinx } else 784216295Ssyrinx saved_errno = errno; 785216295Ssyrinx 786216295Ssyrinx if (*endptr != '.') { 787216295Ssyrinx warnx("Failed reading octet - %s", val); 788216295Ssyrinx return (-1); 789216295Ssyrinx } 790216295Ssyrinx 791216295Ssyrinx for (i = 0, d = 1000; i < 4; i++) { 792216295Ssyrinx ntp_ts[i] = v / d; 793216295Ssyrinx v = v % d; 794216295Ssyrinx d = d / 10; 795216295Ssyrinx } 796216295Ssyrinx val = endptr + 1; 797216295Ssyrinx 798216295Ssyrinx saved_errno = errno; 799216295Ssyrinx v = strtoul(val, &endptr, 10); 800216295Ssyrinx if (errno != 0 || (v / 1000) > 9) { 801216295Ssyrinx saved_errno = errno; 802216295Ssyrinx warnx("Integer value %s not supported", val); 803216295Ssyrinx return (-1); 804216295Ssyrinx } else 805216295Ssyrinx saved_errno = errno; 806216295Ssyrinx 807216295Ssyrinx for (i = 0, d = 1000; i < 4; i++) { 808216295Ssyrinx ntp_ts[i + 4] = v / d; 809216295Ssyrinx v = v % d; 810216295Ssyrinx d = d / 10; 811216295Ssyrinx } 812216295Ssyrinx 813216295Ssyrinx if ((sv->v.octetstring.octets = malloc(SNMP_NTP_TS_OCTETS)) == NULL) { 814216295Ssyrinx syslog(LOG_ERR,"malloc failed: %s", strerror(errno)); 815216295Ssyrinx return (-1); 816216295Ssyrinx } 817216295Ssyrinx 818216295Ssyrinx sv->v.octetstring.len = SNMP_NTP_TS_OCTETS; 819216295Ssyrinx memcpy(sv->v.octetstring.octets, ntp_ts, SNMP_NTP_TS_OCTETS); 820216295Ssyrinx sv->syntax = SNMP_SYNTAX_OCTETSTRING; 821216295Ssyrinx return (1); 822216295Ssyrinx} 823216295Ssyrinx 824216295Ssyrinx/************************************************************** 825216295Ssyrinx * BridgeId 826216295Ssyrinx ************************************************************** 827216295Ssyrinx * BRIDGE-MIB, REVISION "200509190000Z" 828216295Ssyrinx * BridgeId ::= TEXTUAL-CONVENTION 829216295Ssyrinx * STATUS current 830216295Ssyrinx * DESCRIPTION 831216295Ssyrinx * "The Bridge-Identifier, as used in the Spanning Tree 832216295Ssyrinx * Protocol, to uniquely identify a bridge. Its first two 833216295Ssyrinx * octets (in network byte order) contain a priority value, 834216295Ssyrinx * and its last 6 octets contain the MAC address used to 835216295Ssyrinx * refer to a bridge in a unique fashion (typically, the 836216295Ssyrinx * numerically smallest MAC address of all ports on the 837216295Ssyrinx * bridge)." 838216295Ssyrinx * SYNTAX OCTET STRING (SIZE (8)) 839216295Ssyrinx */ 840216295Ssyrinxstatic char * 841216295Ssyrinxsnmp_oct2bridgeid(uint32_t len, char *octets, char *buf) 842216295Ssyrinx{ 843216295Ssyrinx char *ptr; 844216295Ssyrinx uint32_t i, priority; 845216295Ssyrinx 846216295Ssyrinx if (len != SNMP_BRIDGEID_OCTETS || octets == NULL || buf == NULL) 847216295Ssyrinx return (NULL); 848216295Ssyrinx 849216295Ssyrinx buf[0]= '\0'; 850216295Ssyrinx ptr = buf; 851216295Ssyrinx 852216295Ssyrinx priority = octets[0] << 8; 853216295Ssyrinx priority += octets[1]; 854216295Ssyrinx if (priority > SNMP_MAX_BRIDGE_PRIORITY) { 855216295Ssyrinx warnx("Invalid bridge priority %d", priority); 856216295Ssyrinx return (NULL); 857216295Ssyrinx } else 858216295Ssyrinx ptr += sprintf(ptr, "%d.", octets[0]); 859216295Ssyrinx 860216295Ssyrinx ptr += sprintf(ptr, "%2.2x", octets[2]); 861216295Ssyrinx 862216295Ssyrinx for (i = 1; i < 6; i++) 863216295Ssyrinx ptr += sprintf(ptr, ":%2.2x", octets[i + 2]); 864216295Ssyrinx 865216295Ssyrinx return (buf); 866216295Ssyrinx} 867216295Ssyrinx 868216295Ssyrinxstatic char * 869216295Ssyrinxsnmp_bridgeid2oct(char *str, struct asn_oid *oid) 870216295Ssyrinx{ 871216295Ssyrinx char *endptr, *ptr; 872216295Ssyrinx uint32_t v, i; 873216295Ssyrinx int32_t saved_errno; 874216295Ssyrinx 875216295Ssyrinx if (snmp_suboid_append(oid, (asn_subid_t) SNMP_BRIDGEID_OCTETS) < 0) 876216295Ssyrinx return (NULL); 877216295Ssyrinx 878216295Ssyrinx ptr = str; 879216295Ssyrinx /* Read the priority. */ 880216295Ssyrinx saved_errno = errno; 881216295Ssyrinx v = strtoul(ptr, &endptr, 10); 882216295Ssyrinx errno = 0; 883216295Ssyrinx 884216295Ssyrinx if (v > SNMP_MAX_BRIDGE_PRIORITY || errno != 0 || *endptr != '.') { 885216295Ssyrinx errno = saved_errno; 886216295Ssyrinx warnx("Bad bridge priority value %d", v); 887216295Ssyrinx return (NULL); 888216295Ssyrinx } 889216295Ssyrinx 890216295Ssyrinx if (snmp_suboid_append(oid, (asn_subid_t) (v & 0xff00)) < 0) 891216295Ssyrinx return (NULL); 892216295Ssyrinx 893216295Ssyrinx if (snmp_suboid_append(oid, (asn_subid_t) (v & 0xff)) < 0) 894216295Ssyrinx return (NULL); 895216295Ssyrinx 896216295Ssyrinx ptr = endptr + 1; 897216295Ssyrinx for (i = 0; i < 5; i++) { 898216295Ssyrinx saved_errno = errno; 899216295Ssyrinx v = strtoul(ptr, &endptr, 16); 900216295Ssyrinx errno = saved_errno; 901216295Ssyrinx if (v > 0xff) { 902216295Ssyrinx warnx("Integer value %s not supported", str); 903216295Ssyrinx return (NULL); 904216295Ssyrinx } 905216295Ssyrinx if (*endptr != ':') { 906216295Ssyrinx warnx("Failed adding oid - %s",str); 907216295Ssyrinx return (NULL); 908216295Ssyrinx } 909216295Ssyrinx if (snmp_suboid_append(oid, (asn_subid_t) v) < 0) 910216295Ssyrinx return (NULL); 911216295Ssyrinx ptr = endptr + 1; 912216295Ssyrinx } 913216295Ssyrinx 914216295Ssyrinx /* The last one - don't check the ending char here. */ 915216295Ssyrinx saved_errno = errno; 916216295Ssyrinx v = strtoul(ptr, &endptr, 16); 917216295Ssyrinx errno = saved_errno; 918216295Ssyrinx if (v > 0xff) { 919216295Ssyrinx warnx("Integer value %s not supported", str); 920216295Ssyrinx return (NULL); 921216295Ssyrinx } 922216295Ssyrinx if (snmp_suboid_append(oid, (asn_subid_t) v) < 0) 923216295Ssyrinx return (NULL); 924216295Ssyrinx 925216295Ssyrinx return (endptr); 926216295Ssyrinx} 927216295Ssyrinx 928216295Ssyrinxstatic int32_t 929216295Ssyrinxparse_bridge_id(struct snmp_value *sv, char *string) 930216295Ssyrinx{ 931216295Ssyrinx char *ptr, *endptr; 932216295Ssyrinx int32_t i, saved_errno; 933216295Ssyrinx uint32_t v; 934216295Ssyrinx uint8_t bridge_id[SNMP_BRIDGEID_OCTETS]; 935216295Ssyrinx 936216295Ssyrinx ptr = string; 937216295Ssyrinx /* Read the priority. */ 938216295Ssyrinx saved_errno = errno; 939216295Ssyrinx errno = 0; 940216295Ssyrinx v = strtoul(string, &endptr, 10); 941216295Ssyrinx errno = saved_errno; 942216295Ssyrinx 943216295Ssyrinx if (v > SNMP_MAX_BRIDGE_PRIORITY || errno != 0 || *endptr != '.') { 944216295Ssyrinx errno = saved_errno; 945216295Ssyrinx warnx("Bad bridge priority value %d", v); 946216295Ssyrinx return (-1); 947216295Ssyrinx } 948216295Ssyrinx 949216295Ssyrinx bridge_id[0] = (v & 0xff00); 950216295Ssyrinx bridge_id[1] = (v & 0xff); 951216295Ssyrinx 952216295Ssyrinx string = endptr + 1; 953216295Ssyrinx 954216295Ssyrinx for (i = 0; i < 5; i++) { 955216295Ssyrinx v = strtoul(string, &endptr, 16); 956216295Ssyrinx if (v > 0xff) { 957216295Ssyrinx warnx("Integer value %s not supported", string); 958216295Ssyrinx return (-1); 959216295Ssyrinx } 960216295Ssyrinx if(*endptr != ':') { 961216295Ssyrinx warnx("Failed reading octet - %s", string); 962216295Ssyrinx return (-1); 963216295Ssyrinx } 964216295Ssyrinx bridge_id[i + 2] = v; 965216295Ssyrinx string = endptr + 1; 966216295Ssyrinx } 967216295Ssyrinx 968216295Ssyrinx /* The last one - don't check the ending char here. */ 969216295Ssyrinx v = strtoul(string, &endptr, 16); 970216295Ssyrinx if (v > 0xff) { 971216295Ssyrinx warnx("Integer value %s not supported", string); 972216295Ssyrinx return (-1); 973216295Ssyrinx } 974216295Ssyrinx bridge_id[7] = v; 975216295Ssyrinx 976216295Ssyrinx if ((sv->v.octetstring.octets = malloc(SNMP_BRIDGEID_OCTETS)) == NULL) { 977216295Ssyrinx syslog(LOG_ERR,"malloc failed: %s", strerror(errno)); 978216295Ssyrinx return (-1); 979216295Ssyrinx } 980216295Ssyrinx 981216295Ssyrinx sv->v.octetstring.len = SNMP_BRIDGEID_OCTETS; 982216295Ssyrinx memcpy(sv->v.octetstring.octets, bridge_id, SNMP_BRIDGEID_OCTETS); 983216295Ssyrinx sv->syntax = SNMP_SYNTAX_OCTETSTRING; 984216295Ssyrinx return (1); 985216295Ssyrinx} 986216295Ssyrinx 987216295Ssyrinx/************************************************************** 988216295Ssyrinx * BridgePortId 989216295Ssyrinx ************************************************************** 990216295Ssyrinx * BEGEMOT-BRIDGE-MIB, LAST-UPDATED "200608100000Z" 991216295Ssyrinx * BridgePortId ::= TEXTUAL-CONVENTION 992216295Ssyrinx * DISPLAY-HINT "1x.1x" 993216295Ssyrinx * STATUS current 994216295Ssyrinx * DESCRIPTION 995216295Ssyrinx * "A port identifier that contains a bridge port's STP priority 996216295Ssyrinx * in the first octet and the port number in the second octet." 997216295Ssyrinx * SYNTAX OCTET STRING (SIZE(2)) 998216295Ssyrinx */ 999216295Ssyrinxstatic char * 1000216295Ssyrinxsnmp_oct2bport_id(uint32_t len, char *octets, char *buf) 1001216295Ssyrinx{ 1002216295Ssyrinx char *ptr; 1003216295Ssyrinx 1004216295Ssyrinx if (len != SNMP_BPORT_OCTETS || octets == NULL || buf == NULL) 1005216295Ssyrinx return (NULL); 1006216295Ssyrinx 1007216295Ssyrinx buf[0]= '\0'; 1008216295Ssyrinx ptr = buf; 1009216295Ssyrinx 1010216295Ssyrinx ptr += sprintf(ptr, "%d.", octets[0]); 1011216295Ssyrinx ptr += sprintf(ptr, "%d", octets[1]); 1012216295Ssyrinx 1013216295Ssyrinx return (buf); 1014216295Ssyrinx} 1015216295Ssyrinx 1016216295Ssyrinxstatic char * 1017216295Ssyrinxsnmp_bport_id2oct(char *str, struct asn_oid *oid) 1018216295Ssyrinx{ 1019216295Ssyrinx char *endptr, *ptr; 1020216295Ssyrinx uint32_t v; 1021216295Ssyrinx int saved_errno; 1022216295Ssyrinx 1023216295Ssyrinx if (snmp_suboid_append(oid, (asn_subid_t) SNMP_BPORT_OCTETS) < 0) 1024216295Ssyrinx return (NULL); 1025216295Ssyrinx 1026216295Ssyrinx ptr = str; 1027216295Ssyrinx /* Read the priority. */ 1028216295Ssyrinx saved_errno = errno; 1029216295Ssyrinx v = strtoul(ptr, &endptr, 10); 1030216295Ssyrinx errno = 0; 1031216295Ssyrinx 1032216295Ssyrinx if (v > SNMP_MAX_BPORT_PRIORITY || errno != 0 || *endptr != '.') { 1033216295Ssyrinx errno = saved_errno; 1034216295Ssyrinx warnx("Bad bridge port priority value %d", v); 1035216295Ssyrinx return (NULL); 1036216295Ssyrinx } 1037216295Ssyrinx 1038216295Ssyrinx if (snmp_suboid_append(oid, (asn_subid_t) v) < 0) 1039216295Ssyrinx return (NULL); 1040216295Ssyrinx 1041216295Ssyrinx saved_errno = errno; 1042216295Ssyrinx v = strtoul(ptr, &endptr, 16); 1043216295Ssyrinx errno = saved_errno; 1044216295Ssyrinx 1045216295Ssyrinx if (v > 0xff) { 1046216295Ssyrinx warnx("Bad port number - %d", v); 1047216295Ssyrinx return (NULL); 1048216295Ssyrinx } 1049216295Ssyrinx 1050216295Ssyrinx if (snmp_suboid_append(oid, (asn_subid_t) v) < 0) 1051216295Ssyrinx return (NULL); 1052216295Ssyrinx 1053216295Ssyrinx return (endptr); 1054216295Ssyrinx} 1055216295Ssyrinx 1056216295Ssyrinxstatic int32_t 1057216295Ssyrinxparse_bport_id(struct snmp_value *value, char *string) 1058216295Ssyrinx{ 1059216295Ssyrinx char *ptr, *endptr; 1060216295Ssyrinx int saved_errno; 1061216295Ssyrinx uint32_t v; 1062216295Ssyrinx uint8_t bport_id[SNMP_BPORT_OCTETS]; 1063216295Ssyrinx 1064216295Ssyrinx ptr = string; 1065216295Ssyrinx /* Read the priority. */ 1066216295Ssyrinx saved_errno = errno; 1067216295Ssyrinx errno = 0; 1068216295Ssyrinx v = strtoul(string, &endptr, 10); 1069216295Ssyrinx errno = saved_errno; 1070216295Ssyrinx 1071216295Ssyrinx if (v > SNMP_MAX_BPORT_PRIORITY || errno != 0 || *endptr != '.') { 1072216295Ssyrinx errno = saved_errno; 1073216295Ssyrinx warnx("Bad bridge port priority value %d", v); 1074216295Ssyrinx return (-1); 1075216295Ssyrinx } 1076216295Ssyrinx 1077216295Ssyrinx bport_id[0] = v; 1078216295Ssyrinx 1079216295Ssyrinx string = endptr + 1; 1080216295Ssyrinx v = strtoul(string, &endptr, 16); 1081216295Ssyrinx if (v > 0xff) { 1082216295Ssyrinx warnx("Bad port number - %d", v); 1083216295Ssyrinx return (-1); 1084216295Ssyrinx } 1085216295Ssyrinx 1086216295Ssyrinx bport_id[1] = v; 1087216295Ssyrinx 1088216295Ssyrinx if ((value->v.octetstring.octets = malloc(SNMP_BPORT_OCTETS)) == NULL) { 1089216295Ssyrinx syslog(LOG_ERR,"malloc failed: %s", strerror(errno)); 1090216295Ssyrinx return (-1); 1091216295Ssyrinx } 1092216295Ssyrinx 1093216295Ssyrinx value->v.octetstring.len = SNMP_BPORT_OCTETS; 1094216295Ssyrinx memcpy(value->v.octetstring.octets, bport_id, SNMP_BPORT_OCTETS); 1095216295Ssyrinx value->syntax = SNMP_SYNTAX_OCTETSTRING; 1096216295Ssyrinx return (1); 1097216295Ssyrinx} 1098216295Ssyrinx/************************************************************** 1099216295Ssyrinx * InetAddress 1100216295Ssyrinx ************************************************************** 1101216295Ssyrinx * INET-ADDRESS-MIB, REVISION "200502040000Z" 1102216295Ssyrinx * InetAddress ::= TEXTUAL-CONVENTION 1103216295Ssyrinx * STATUS current 1104216295Ssyrinx * DESCRIPTION 1105216295Ssyrinx * "Denotes a generic Internet address. 1106216295Ssyrinx * 1107216295Ssyrinx * An InetAddress value is always interpreted within the context 1108216295Ssyrinx * of an InetAddressType value. Every usage of the InetAddress 1109216295Ssyrinx * textual convention is required to specify the InetAddressType 1110216295Ssyrinx * object that provides the context. It is suggested that the 1111216295Ssyrinx * InetAddressType object be logically registered before the 1112216295Ssyrinx * object(s) that use the InetAddress textual convention, if 1113216295Ssyrinx * they appear in the same logical row. 1114216295Ssyrinx * 1115216295Ssyrinx * The value of an InetAddress object must always be 1116216295Ssyrinx * consistent with the value of the associated InetAddressType 1117216295Ssyrinx * object. Attempts to set an InetAddress object to a value 1118216295Ssyrinx * inconsistent with the associated InetAddressType 1119216295Ssyrinx * must fail with an inconsistentValue error. 1120216295Ssyrinx * 1121216295Ssyrinx * When this textual convention is used as the syntax of an 1122216295Ssyrinx * index object, there may be issues with the limit of 128 1123216295Ssyrinx * sub-identifiers specified in SMIv2, STD 58. In this case, 1124216295Ssyrinx * the object definition MUST include a 'SIZE' clause to 1125216295Ssyrinx * limit the number of potential instance sub-identifiers; 1126216295Ssyrinx * otherwise the applicable constraints MUST be stated in 1127216295Ssyrinx * the appropriate conceptual row DESCRIPTION clauses, or 1128216295Ssyrinx * in the surrounding documentation if there is no single 1129216295Ssyrinx * DESCRIPTION clause that is appropriate." 1130216295Ssyrinx * SYNTAX OCTET STRING (SIZE (0..255)) 1131216295Ssyrinx ************************************************************** 1132216295Ssyrinx * TODO: FIXME!!! syrinx: Since we do not support checking the 1133216295Ssyrinx * consistency of a varbinding based on the value of a previous 1134216295Ssyrinx * one, try to guess the type of address based on the 1135216295Ssyrinx * OctetString SIZE - 4 for IPv4, 16 for IPv6, others currently 1136216295Ssyrinx * not supported. 1137216295Ssyrinx */ 1138216295Ssyrinxstatic char * 1139216295Ssyrinxsnmp_oct2inetaddr(uint32_t len, char *octets, char *buf) 1140216295Ssyrinx{ 1141216295Ssyrinx int af; 1142216295Ssyrinx void *ip; 1143216295Ssyrinx struct in_addr ipv4; 1144216295Ssyrinx struct in6_addr ipv6; 1145216295Ssyrinx 1146216295Ssyrinx if (len > MAX_OCTSTRING_LEN || octets == NULL || buf == NULL) 1147216295Ssyrinx return (NULL); 1148216295Ssyrinx 1149216295Ssyrinx switch (len) { 1150216295Ssyrinx /* XXX: FIXME - IPv4*/ 1151216295Ssyrinx case 4: 1152216295Ssyrinx memcpy(&ipv4.s_addr, octets, sizeof(ipv4.s_addr)); 1153216295Ssyrinx af = AF_INET; 1154216295Ssyrinx ip = &ipv4; 1155216295Ssyrinx break; 1156216295Ssyrinx 1157216295Ssyrinx /* XXX: FIXME - IPv4*/ 1158216295Ssyrinx case 16: 1159216295Ssyrinx memcpy(ipv6.s6_addr, octets, sizeof(ipv6.s6_addr)); 1160216295Ssyrinx af = AF_INET6; 1161216295Ssyrinx ip = &ipv6; 1162216295Ssyrinx break; 1163216295Ssyrinx 1164216295Ssyrinx default: 1165216295Ssyrinx return (NULL); 1166216295Ssyrinx } 1167216295Ssyrinx 1168216295Ssyrinx if (inet_ntop(af, ip, buf, SNMP_INADDRS_STRSZ) == NULL) { 1169216295Ssyrinx warnx("inet_ntop failed - %s", strerror(errno)); 1170216295Ssyrinx return (NULL); 1171216295Ssyrinx } 1172216295Ssyrinx 1173216295Ssyrinx return (buf); 1174216295Ssyrinx} 1175216295Ssyrinx 1176216295Ssyrinxstatic char * 1177216295Ssyrinxsnmp_inetaddr2oct(char *str, struct asn_oid *oid) 1178216295Ssyrinx{ 1179216295Ssyrinx return (NULL); 1180216295Ssyrinx} 1181216295Ssyrinx 1182216295Ssyrinxstatic int32_t 1183216295Ssyrinxparse_inetaddr(struct snmp_value *value, char *string) 1184216295Ssyrinx{ 1185216295Ssyrinx return (-1); 1186216295Ssyrinx} 1187216295Ssyrinx 1188216295Ssyrinx/************************************************************** 1189216295Ssyrinx * SNMP BITS type - XXX: FIXME 1190216295Ssyrinx **************************************************************/ 1191216295Ssyrinxstatic char * 1192216295Ssyrinxsnmp_oct2bits(uint32_t len, char *octets, char *buf) 1193216295Ssyrinx{ 1194216295Ssyrinx int i, bits; 1195216295Ssyrinx uint64_t value; 1196216295Ssyrinx 1197216295Ssyrinx if (len > sizeof(value) || octets == NULL || buf == NULL) 1198216295Ssyrinx return (NULL); 1199216295Ssyrinx 1200216295Ssyrinx for (i = len, value = 0, bits = 0; i > 0; i--, bits += 8) 1201216295Ssyrinx value += octets[i] << bits; 1202216295Ssyrinx 1203216295Ssyrinx buf[0]= '\0'; 1204216295Ssyrinx sprintf(buf, "0x%llx.",(long long unsigned) value); 1205216295Ssyrinx 1206216295Ssyrinx return (buf); 1207216295Ssyrinx} 1208216295Ssyrinx 1209216295Ssyrinxstatic char * 1210216295Ssyrinxsnmp_bits2oct(char *str, struct asn_oid *oid) 1211216295Ssyrinx{ 1212216295Ssyrinx char *endptr; 1213216295Ssyrinx int i, size, bits, saved_errno; 1214216295Ssyrinx uint64_t v, mask = 0xFF00000000000000; 1215216295Ssyrinx 1216216295Ssyrinx saved_errno = errno; 1217216295Ssyrinx errno = 0; 1218216295Ssyrinx 1219216295Ssyrinx v = strtoull(str, &endptr, 16); 1220216295Ssyrinx if (errno != 0) { 1221216295Ssyrinx warnx("Bad BITS value %s - %s", str, strerror(errno)); 1222216295Ssyrinx errno = saved_errno; 1223216295Ssyrinx return (NULL); 1224216295Ssyrinx } 1225216295Ssyrinx 1226216295Ssyrinx bits = 8; 1227216295Ssyrinx /* Determine length - up to 8 octets supported so far. */ 1228216295Ssyrinx for (size = sizeof(v); size > 0; size--) { 1229216295Ssyrinx if ((v & mask) != 0) 1230216295Ssyrinx break; 1231216295Ssyrinx mask = mask >> bits; 1232216295Ssyrinx } 1233216295Ssyrinx 1234216295Ssyrinx if (size == 0) 1235216295Ssyrinx size = 1; 1236216295Ssyrinx 1237216295Ssyrinx if (snmp_suboid_append(oid, (asn_subid_t) size) < 0) 1238216295Ssyrinx return (NULL); 1239216295Ssyrinx 1240216295Ssyrinx for (i = 0, bits = 0; i < size; i++, bits += 8) 1241216295Ssyrinx if (snmp_suboid_append(oid, 1242216295Ssyrinx (asn_subid_t)((v & mask) >> bits)) < 0) 1243216295Ssyrinx return (NULL); 1244216295Ssyrinx 1245216295Ssyrinx return (endptr); 1246216295Ssyrinx} 1247216295Ssyrinx 1248216295Ssyrinxstatic int32_t 1249216295Ssyrinxparse_bits(struct snmp_value *value, char *string) 1250216295Ssyrinx{ 1251216295Ssyrinx char *endptr; 1252216295Ssyrinx int i, size, bits, saved_errno; 1253216295Ssyrinx uint64_t v, mask = 0xFF00000000000000; 1254216295Ssyrinx 1255216295Ssyrinx saved_errno = errno; 1256216295Ssyrinx errno = 0; 1257216295Ssyrinx 1258216295Ssyrinx v = strtoull(string, &endptr, 16); 1259216295Ssyrinx 1260216295Ssyrinx if (errno != 0) { 1261216295Ssyrinx warnx("Bad BITS value %s - %s", string, strerror(errno)); 1262216295Ssyrinx errno = saved_errno; 1263216295Ssyrinx return (-1); 1264216295Ssyrinx } 1265216295Ssyrinx 1266216295Ssyrinx bits = 8; 1267216295Ssyrinx /* Determine length - up to 8 octets supported so far. */ 1268216295Ssyrinx for (size = sizeof(v); size > 0; size--) { 1269216295Ssyrinx if ((v & mask) != 0) 1270216295Ssyrinx break; 1271216295Ssyrinx mask = mask >> bits; 1272216295Ssyrinx } 1273216295Ssyrinx 1274216295Ssyrinx if (size == 0) 1275216295Ssyrinx size = 1; 1276216295Ssyrinx 1277216295Ssyrinx if ((value->v.octetstring.octets = malloc(size)) == NULL) { 1278216295Ssyrinx syslog(LOG_ERR, "malloc failed: %s", strerror(errno)); 1279216295Ssyrinx return (-1); 1280216295Ssyrinx } 1281216295Ssyrinx 1282216295Ssyrinx value->v.octetstring.len = size; 1283216295Ssyrinx for (i = 0, bits = 0; i < size; i++, bits += 8) 1284216295Ssyrinx value->v.octetstring.octets[i] = (v & mask) >> bits; 1285216295Ssyrinx value->syntax = SNMP_SYNTAX_OCTETSTRING; 1286216295Ssyrinx return (1); 1287216295Ssyrinx} 1288