1a7398723SShteryana Shopova /*- 2a7398723SShteryana Shopova * Copyright (c) 2005-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 * Helper functions for snmp client tools 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/uio.h> 37a7398723SShteryana Shopova 38a7398723SShteryana Shopova #include <assert.h> 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 <bsnmp/asn1.h> 50a7398723SShteryana Shopova #include <bsnmp/snmp.h> 51a7398723SShteryana Shopova #include <bsnmp/snmpclient.h> 52a7398723SShteryana Shopova #include "bsnmptc.h" 53a7398723SShteryana Shopova #include "bsnmptools.h" 54a7398723SShteryana Shopova 55a7398723SShteryana Shopova /* Internal varibale to turn on library debugging for testing and to 56a7398723SShteryana Shopova * find bugs. It is not exported via the header file. 57a7398723SShteryana Shopova * XXX should we cover it by some #ifdef BSNMPTOOLS_DEBUG? */ 58a7398723SShteryana Shopova int _bsnmptools_debug = 0; 59a7398723SShteryana Shopova 60a7398723SShteryana Shopova /* Default files to import mapping from if none explicitly provided. */ 61a7398723SShteryana Shopova #define bsnmpd_defs "/usr/share/snmp/defs/tree.def" 62a7398723SShteryana Shopova #define mibII_defs "/usr/share/snmp/defs/mibII_tree.def" 63a7398723SShteryana Shopova 64a7398723SShteryana Shopova /* 65a7398723SShteryana Shopova * The .iso.org.dod oid that has to be prepended to every OID when requesting 66a7398723SShteryana Shopova * a value. 67a7398723SShteryana Shopova */ 68a7398723SShteryana Shopova const struct asn_oid IsoOrgDod_OID = { 69a7398723SShteryana Shopova 3, { 1, 3, 6 } 70a7398723SShteryana Shopova }; 71a7398723SShteryana Shopova 72a7398723SShteryana Shopova 73a7398723SShteryana Shopova #define SNMP_ERR_UNKNOWN 0 74a7398723SShteryana Shopova 75a7398723SShteryana Shopova /* 76a7398723SShteryana Shopova * An array of error strings corresponding to error definitions from libbsnmp. 77a7398723SShteryana Shopova */ 78a7398723SShteryana Shopova static const struct { 79a7398723SShteryana Shopova const char *str; 80a7398723SShteryana Shopova int32_t error; 81a7398723SShteryana Shopova } error_strings[] = { 82a7398723SShteryana Shopova { "Unknown", SNMP_ERR_UNKNOWN }, 83a7398723SShteryana Shopova { "Too big ", SNMP_ERR_TOOBIG }, 84a7398723SShteryana Shopova { "No such Name", SNMP_ERR_NOSUCHNAME }, 85a7398723SShteryana Shopova { "Bad Value", SNMP_ERR_BADVALUE }, 86a7398723SShteryana Shopova { "Readonly", SNMP_ERR_READONLY }, 87a7398723SShteryana Shopova { "General error", SNMP_ERR_GENERR }, 88a7398723SShteryana Shopova { "No access", SNMP_ERR_NO_ACCESS }, 89a7398723SShteryana Shopova { "Wrong type", SNMP_ERR_WRONG_TYPE }, 903df5ecacSUlrich Spörlein { "Wrong length", SNMP_ERR_WRONG_LENGTH }, 91a7398723SShteryana Shopova { "Wrong encoding", SNMP_ERR_WRONG_ENCODING }, 92a7398723SShteryana Shopova { "Wrong value", SNMP_ERR_WRONG_VALUE }, 93a7398723SShteryana Shopova { "No creation", SNMP_ERR_NO_CREATION }, 94a7398723SShteryana Shopova { "Inconsistent value", SNMP_ERR_INCONS_VALUE }, 95a7398723SShteryana Shopova { "Resource unavailable", SNMP_ERR_RES_UNAVAIL }, 96a7398723SShteryana Shopova { "Commit failed", SNMP_ERR_COMMIT_FAILED }, 97a7398723SShteryana Shopova { "Undo failed", SNMP_ERR_UNDO_FAILED }, 98a7398723SShteryana Shopova { "Authorization error", SNMP_ERR_AUTH_ERR }, 99a7398723SShteryana Shopova { "Not writable", SNMP_ERR_NOT_WRITEABLE }, 100a7398723SShteryana Shopova { "Inconsistent name", SNMP_ERR_INCONS_NAME }, 101a7398723SShteryana Shopova { NULL, 0 } 102a7398723SShteryana Shopova }; 103a7398723SShteryana Shopova 104a7398723SShteryana Shopova /* This one and any following are exceptions. */ 105a7398723SShteryana Shopova #define SNMP_SYNTAX_UNKNOWN SNMP_SYNTAX_NOSUCHOBJECT 106a7398723SShteryana Shopova 107a7398723SShteryana Shopova static const struct { 108a7398723SShteryana Shopova const char *str; 109a7398723SShteryana Shopova enum snmp_syntax stx; 110a7398723SShteryana Shopova } syntax_strings[] = { 111a7398723SShteryana Shopova { "Null", SNMP_SYNTAX_NULL }, 112a7398723SShteryana Shopova { "Integer", SNMP_SYNTAX_INTEGER }, 113a7398723SShteryana Shopova { "OctetString", SNMP_SYNTAX_OCTETSTRING }, 114a7398723SShteryana Shopova { "OID", SNMP_SYNTAX_OID }, 115a7398723SShteryana Shopova { "IpAddress", SNMP_SYNTAX_IPADDRESS }, 116a7398723SShteryana Shopova { "Counter32", SNMP_SYNTAX_COUNTER }, 117a7398723SShteryana Shopova { "Gauge", SNMP_SYNTAX_GAUGE }, 118a7398723SShteryana Shopova { "TimeTicks", SNMP_SYNTAX_TIMETICKS }, 119a7398723SShteryana Shopova { "Counter64", SNMP_SYNTAX_COUNTER64 }, 120a7398723SShteryana Shopova { "Unknown", SNMP_SYNTAX_UNKNOWN }, 121a7398723SShteryana Shopova }; 122a7398723SShteryana Shopova 123a7398723SShteryana Shopova int 124a7398723SShteryana Shopova snmptool_init(struct snmp_toolinfo *snmptoolctx) 125a7398723SShteryana Shopova { 126a7398723SShteryana Shopova char *str; 127a7398723SShteryana Shopova size_t slen; 128a7398723SShteryana Shopova 129a7398723SShteryana Shopova memset(snmptoolctx, 0, sizeof(struct snmp_toolinfo)); 130a7398723SShteryana Shopova snmptoolctx->objects = 0; 131a7398723SShteryana Shopova snmptoolctx->mappings = NULL; 132a7398723SShteryana Shopova snmptoolctx->flags = SNMP_PDU_GET; /* XXX */ 133a7398723SShteryana Shopova SLIST_INIT(&snmptoolctx->filelist); 134a7398723SShteryana Shopova snmp_client_init(&snmp_client); 135b9288caaSShteryana Shopova SET_MAXREP(snmptoolctx, SNMP_MAX_REPETITIONS); 136a7398723SShteryana Shopova 137a7398723SShteryana Shopova if (add_filename(snmptoolctx, bsnmpd_defs, &IsoOrgDod_OID, 0) < 0) 138a7398723SShteryana Shopova warnx("Error adding file %s to list", bsnmpd_defs); 139a7398723SShteryana Shopova 140a7398723SShteryana Shopova if (add_filename(snmptoolctx, mibII_defs, &IsoOrgDod_OID, 0) < 0) 141a7398723SShteryana Shopova warnx("Error adding file %s to list", mibII_defs); 142a7398723SShteryana Shopova 143a7398723SShteryana Shopova /* Read the environment */ 144a7398723SShteryana Shopova if ((str = getenv("SNMPAUTH")) != NULL) { 145a7398723SShteryana Shopova slen = strlen(str); 146a7398723SShteryana Shopova if (slen == strlen("md5") && strcasecmp(str, "md5") == 0) 147a7398723SShteryana Shopova snmp_client.user.auth_proto = SNMP_AUTH_HMAC_MD5; 148a7398723SShteryana Shopova else if (slen == strlen("sha")&& strcasecmp(str, "sha") == 0) 149a7398723SShteryana Shopova snmp_client.user.auth_proto = SNMP_AUTH_HMAC_SHA; 150a7398723SShteryana Shopova else if (slen != 0) 151a7398723SShteryana Shopova warnx("Bad authentication type - %s in SNMPAUTH", str); 152a7398723SShteryana Shopova } 153a7398723SShteryana Shopova 154a7398723SShteryana Shopova if ((str = getenv("SNMPPRIV")) != NULL) { 155a7398723SShteryana Shopova slen = strlen(str); 156a7398723SShteryana Shopova if (slen == strlen("des") && strcasecmp(str, "des") == 0) 157a7398723SShteryana Shopova snmp_client.user.priv_proto = SNMP_PRIV_DES; 158a7398723SShteryana Shopova else if (slen == strlen("aes")&& strcasecmp(str, "aes") == 0) 159a7398723SShteryana Shopova snmp_client.user.priv_proto = SNMP_PRIV_AES; 160a7398723SShteryana Shopova else if (slen != 0) 161a7398723SShteryana Shopova warnx("Bad privacy type - %s in SNMPPRIV", str); 162a7398723SShteryana Shopova } 163a7398723SShteryana Shopova 164a7398723SShteryana Shopova if ((str = getenv("SNMPUSER")) != NULL) { 165a7398723SShteryana Shopova if ((slen = strlen(str)) > sizeof(snmp_client.user.sec_name)) { 166a7398723SShteryana Shopova warnx("Username too long - %s in SNMPUSER", str); 167a7398723SShteryana Shopova return (-1); 168a7398723SShteryana Shopova } 169a7398723SShteryana Shopova if (slen > 0) { 170a7398723SShteryana Shopova strlcpy(snmp_client.user.sec_name, str, 171a7398723SShteryana Shopova sizeof(snmp_client.user.sec_name)); 172a7398723SShteryana Shopova snmp_client.version = SNMP_V3; 173a7398723SShteryana Shopova } 174a7398723SShteryana Shopova } 175a7398723SShteryana Shopova 176a7398723SShteryana Shopova if ((str = getenv("SNMPPASSWD")) != NULL) { 177a7398723SShteryana Shopova if ((slen = strlen(str)) > MAXSTR) 178a7398723SShteryana Shopova slen = MAXSTR - 1; 179a7398723SShteryana Shopova if ((snmptoolctx->passwd = malloc(slen + 1)) == NULL) { 180a7398723SShteryana Shopova warnx("malloc() failed - %s", strerror(errno)); 181a7398723SShteryana Shopova return (-1); 182a7398723SShteryana Shopova } 183a7398723SShteryana Shopova if (slen > 0) 184a7398723SShteryana Shopova strlcpy(snmptoolctx->passwd, str, slen + 1); 185a7398723SShteryana Shopova } 186a7398723SShteryana Shopova 187a7398723SShteryana Shopova return (0); 188a7398723SShteryana Shopova } 189a7398723SShteryana Shopova 190a7398723SShteryana Shopova #define OBJECT_IDX_LIST(o) o->info->table_idx->index_list 191a7398723SShteryana Shopova 192a7398723SShteryana Shopova /* 193a7398723SShteryana Shopova * Walk through the file list and import string<->oid mappings from each file. 194a7398723SShteryana Shopova */ 195a7398723SShteryana Shopova int32_t 196a7398723SShteryana Shopova snmp_import_all(struct snmp_toolinfo *snmptoolctx) 197a7398723SShteryana Shopova { 198a7398723SShteryana Shopova int32_t fc; 199a7398723SShteryana Shopova struct fname *tmp; 200a7398723SShteryana Shopova 201a7398723SShteryana Shopova if (snmptoolctx == NULL) 202a7398723SShteryana Shopova return (-1); 203a7398723SShteryana Shopova 204a7398723SShteryana Shopova if (ISSET_NUMERIC(snmptoolctx)) 205a7398723SShteryana Shopova return (0); 206a7398723SShteryana Shopova 207a7398723SShteryana Shopova if ((snmptoolctx->mappings = snmp_mapping_init()) == NULL) 208a7398723SShteryana Shopova return (-1); 209a7398723SShteryana Shopova 210a7398723SShteryana Shopova fc = 0; 211a7398723SShteryana Shopova if (SLIST_EMPTY(&snmptoolctx->filelist)) { 212a7398723SShteryana Shopova warnx("No files to read OID <-> string conversions from"); 213a7398723SShteryana Shopova return (-1); 214a7398723SShteryana Shopova } else { 215a7398723SShteryana Shopova SLIST_FOREACH(tmp, &snmptoolctx->filelist, link) { 216a7398723SShteryana Shopova if (tmp->done) 217a7398723SShteryana Shopova continue; 218a7398723SShteryana Shopova if (snmp_import_file(snmptoolctx, tmp) < 0) { 219a7398723SShteryana Shopova fc = -1; 220a7398723SShteryana Shopova break; 221a7398723SShteryana Shopova } 222a7398723SShteryana Shopova fc++; 223a7398723SShteryana Shopova } 224a7398723SShteryana Shopova } 225a7398723SShteryana Shopova 226a7398723SShteryana Shopova snmp_mapping_dump(snmptoolctx); 227a7398723SShteryana Shopova return (fc); 228a7398723SShteryana Shopova } 229a7398723SShteryana Shopova 230a7398723SShteryana Shopova /* 2313df5ecacSUlrich Spörlein * Add a filename to the file list - the initial idea of keeping a list with all 232a7398723SShteryana Shopova * files to read OIDs from was that an application might want to have loaded in 233a7398723SShteryana Shopova * memory the OIDs from a single file only and when done with them read the OIDs 234a7398723SShteryana Shopova * from another file. This is not used yet but might be a good idea at some 235a7398723SShteryana Shopova * point. Size argument is number of bytes in string including trailing '\0', 2363df5ecacSUlrich Spörlein * not string length. 237a7398723SShteryana Shopova */ 238a7398723SShteryana Shopova int32_t 239a7398723SShteryana Shopova add_filename(struct snmp_toolinfo *snmptoolctx, const char *filename, 240a7398723SShteryana Shopova const struct asn_oid *cut, int32_t done) 241a7398723SShteryana Shopova { 242a7398723SShteryana Shopova char *fstring; 243a7398723SShteryana Shopova struct fname *entry; 244a7398723SShteryana Shopova 245a7398723SShteryana Shopova if (snmptoolctx == NULL) 246a7398723SShteryana Shopova return (-1); 247a7398723SShteryana Shopova 248a7398723SShteryana Shopova /* Make sure file was not in list. */ 249a7398723SShteryana Shopova SLIST_FOREACH(entry, &snmptoolctx->filelist, link) { 250a7398723SShteryana Shopova if (strncmp(entry->name, filename, strlen(entry->name)) == 0) 251a7398723SShteryana Shopova return (0); 252a7398723SShteryana Shopova } 253a7398723SShteryana Shopova 254a7398723SShteryana Shopova if ((fstring = malloc(strlen(filename) + 1)) == NULL) { 255a7398723SShteryana Shopova warnx("malloc() failed - %s", strerror(errno)); 256a7398723SShteryana Shopova return (-1); 257a7398723SShteryana Shopova } 258a7398723SShteryana Shopova 259031987d9SEnji Cooper if ((entry = calloc(1, sizeof(struct fname))) == NULL) { 260a7398723SShteryana Shopova warnx("malloc() failed - %s", strerror(errno)); 261a7398723SShteryana Shopova free(fstring); 262a7398723SShteryana Shopova return (-1); 263a7398723SShteryana Shopova } 264a7398723SShteryana Shopova 265a7398723SShteryana Shopova if (cut != NULL) 266a7398723SShteryana Shopova asn_append_oid(&(entry->cut), cut); 26778a780e3SEnji Cooper strlcpy(fstring, filename, sizeof(fstring)); 268a7398723SShteryana Shopova entry->name = fstring; 269a7398723SShteryana Shopova entry->done = done; 270a7398723SShteryana Shopova SLIST_INSERT_HEAD(&snmptoolctx->filelist, entry, link); 271a7398723SShteryana Shopova 272a7398723SShteryana Shopova return (1); 273a7398723SShteryana Shopova } 274a7398723SShteryana Shopova 275a7398723SShteryana Shopova void 276a7398723SShteryana Shopova free_filelist(struct snmp_toolinfo *snmptoolctx) 277a7398723SShteryana Shopova { 278a7398723SShteryana Shopova struct fname *f; 279a7398723SShteryana Shopova 280a7398723SShteryana Shopova if (snmptoolctx == NULL) 281a7398723SShteryana Shopova return; /* XXX error handling */ 282a7398723SShteryana Shopova 283a7398723SShteryana Shopova while ((f = SLIST_FIRST(&snmptoolctx->filelist)) != NULL) { 284a7398723SShteryana Shopova SLIST_REMOVE_HEAD(&snmptoolctx->filelist, link); 285a7398723SShteryana Shopova if (f->name) 286a7398723SShteryana Shopova free(f->name); 287a7398723SShteryana Shopova free(f); 288a7398723SShteryana Shopova } 289a7398723SShteryana Shopova } 290a7398723SShteryana Shopova 291a7398723SShteryana Shopova static char 292a7398723SShteryana Shopova isvalid_fchar(char c, int pos) 293a7398723SShteryana Shopova { 294a7398723SShteryana Shopova if (isalpha(c)|| c == '/'|| c == '_' || c == '.' || c == '~' || 295a7398723SShteryana Shopova (pos != 0 && isdigit(c))){ 296a7398723SShteryana Shopova return (c); 297a7398723SShteryana Shopova } 298a7398723SShteryana Shopova 299a7398723SShteryana Shopova if (c == '\0') 300a7398723SShteryana Shopova return (0); 301a7398723SShteryana Shopova 302a7398723SShteryana Shopova if (!isascii(c) || !isprint(c)) 303a7398723SShteryana Shopova warnx("Unexpected character %#2x", (u_int) c); 304a7398723SShteryana Shopova else 305a7398723SShteryana Shopova warnx("Illegal character '%c'", c); 306a7398723SShteryana Shopova 307a7398723SShteryana Shopova return (-1); 308a7398723SShteryana Shopova } 309a7398723SShteryana Shopova 310a7398723SShteryana Shopova /* 311a7398723SShteryana Shopova * Re-implement getsubopt from scratch, because the second argument is broken 312a7398723SShteryana Shopova * and will not compile with WARNS=5. 313a7398723SShteryana Shopova * Copied from src/contrib/bsnmp/snmpd/main.c. 314a7398723SShteryana Shopova */ 315a7398723SShteryana Shopova static int 316a7398723SShteryana Shopova getsubopt1(char **arg, const char *const *options, char **valp, char **optp) 317a7398723SShteryana Shopova { 318a7398723SShteryana Shopova static const char *const delim = ",\t "; 319a7398723SShteryana Shopova u_int i; 320a7398723SShteryana Shopova char *ptr; 321a7398723SShteryana Shopova 322a7398723SShteryana Shopova *optp = NULL; 323a7398723SShteryana Shopova 324a7398723SShteryana Shopova /* Skip leading junk. */ 325a7398723SShteryana Shopova for (ptr = *arg; *ptr != '\0'; ptr++) 326a7398723SShteryana Shopova if (strchr(delim, *ptr) == NULL) 327a7398723SShteryana Shopova break; 328a7398723SShteryana Shopova if (*ptr == '\0') { 329a7398723SShteryana Shopova *arg = ptr; 330a7398723SShteryana Shopova return (-1); 331a7398723SShteryana Shopova } 332a7398723SShteryana Shopova *optp = ptr; 333a7398723SShteryana Shopova 334a7398723SShteryana Shopova /* Find the end of the option. */ 335a7398723SShteryana Shopova while (*++ptr != '\0') 336a7398723SShteryana Shopova if (strchr(delim, *ptr) != NULL || *ptr == '=') 337a7398723SShteryana Shopova break; 338a7398723SShteryana Shopova 339a7398723SShteryana Shopova if (*ptr != '\0') { 340a7398723SShteryana Shopova if (*ptr == '=') { 341a7398723SShteryana Shopova *ptr++ = '\0'; 342a7398723SShteryana Shopova *valp = ptr; 343a7398723SShteryana Shopova while (*ptr != '\0' && strchr(delim, *ptr) == NULL) 344a7398723SShteryana Shopova ptr++; 345a7398723SShteryana Shopova if (*ptr != '\0') 346a7398723SShteryana Shopova *ptr++ = '\0'; 347a7398723SShteryana Shopova } else 348a7398723SShteryana Shopova *ptr++ = '\0'; 349a7398723SShteryana Shopova } 350a7398723SShteryana Shopova 351a7398723SShteryana Shopova *arg = ptr; 352a7398723SShteryana Shopova 353a7398723SShteryana Shopova for (i = 0; *options != NULL; options++, i++) 354a7398723SShteryana Shopova if (strcmp(*optp, *options) == 0) 355a7398723SShteryana Shopova return (i); 356a7398723SShteryana Shopova return (-1); 357a7398723SShteryana Shopova } 358a7398723SShteryana Shopova 359a7398723SShteryana Shopova static int32_t 360a7398723SShteryana Shopova parse_path(char *value) 361a7398723SShteryana Shopova { 362a7398723SShteryana Shopova int32_t i, len; 363a7398723SShteryana Shopova 364a7398723SShteryana Shopova if (value == NULL) 365a7398723SShteryana Shopova return (-1); 366a7398723SShteryana Shopova 367a7398723SShteryana Shopova for (len = 0; len < MAXPATHLEN; len++) { 368a7398723SShteryana Shopova i = isvalid_fchar(*(value + len), len) ; 369a7398723SShteryana Shopova 370a7398723SShteryana Shopova if (i == 0) 371a7398723SShteryana Shopova break; 372a7398723SShteryana Shopova else if (i < 0) 373a7398723SShteryana Shopova return (-1); 374a7398723SShteryana Shopova } 375a7398723SShteryana Shopova 376a7398723SShteryana Shopova if (len >= MAXPATHLEN || value[len] != '\0') { 377a7398723SShteryana Shopova warnx("Bad pathname - '%s'", value); 378a7398723SShteryana Shopova return (-1); 379a7398723SShteryana Shopova } 380a7398723SShteryana Shopova 381a7398723SShteryana Shopova return (len); 382a7398723SShteryana Shopova } 383a7398723SShteryana Shopova 384a7398723SShteryana Shopova static int32_t 385a7398723SShteryana Shopova parse_flist(struct snmp_toolinfo *snmptoolctx, char *value, char *path, 386a7398723SShteryana Shopova const struct asn_oid *cut) 387a7398723SShteryana Shopova { 388a7398723SShteryana Shopova int32_t namelen; 389a7398723SShteryana Shopova char filename[MAXPATHLEN + 1]; 390a7398723SShteryana Shopova 391a7398723SShteryana Shopova if (value == NULL) 392a7398723SShteryana Shopova return (-1); 393a7398723SShteryana Shopova 394a7398723SShteryana Shopova do { 395a7398723SShteryana Shopova memset(filename, 0, MAXPATHLEN + 1); 396a7398723SShteryana Shopova 397a7398723SShteryana Shopova if (isalpha(*value) && (path == NULL || path[0] == '\0')) { 398a7398723SShteryana Shopova strlcpy(filename, SNMP_DEFS_DIR, MAXPATHLEN + 1); 399a7398723SShteryana Shopova namelen = strlen(SNMP_DEFS_DIR); 400a7398723SShteryana Shopova } else if (path != NULL){ 401a7398723SShteryana Shopova strlcpy(filename, path, MAXPATHLEN + 1); 402a7398723SShteryana Shopova namelen = strlen(path); 403a7398723SShteryana Shopova } else 404a7398723SShteryana Shopova namelen = 0; 405a7398723SShteryana Shopova 406a7398723SShteryana Shopova for ( ; namelen < MAXPATHLEN; value++) { 407a7398723SShteryana Shopova if (isvalid_fchar(*value, namelen) > 0) { 408a7398723SShteryana Shopova filename[namelen++] = *value; 409a7398723SShteryana Shopova continue; 410a7398723SShteryana Shopova } 411a7398723SShteryana Shopova 412a7398723SShteryana Shopova if (*value == ',' ) 413a7398723SShteryana Shopova value++; 414a7398723SShteryana Shopova else if (*value == '\0') 415a7398723SShteryana Shopova ; 416a7398723SShteryana Shopova else { 417a7398723SShteryana Shopova if (!isascii(*value) || !isprint(*value)) 418a7398723SShteryana Shopova warnx("Unexpected character %#2x in" 419a7398723SShteryana Shopova " filename", (u_int) *value); 420a7398723SShteryana Shopova else 421a7398723SShteryana Shopova warnx("Illegal character '%c' in" 422a7398723SShteryana Shopova " filename", *value); 423a7398723SShteryana Shopova return (-1); 424a7398723SShteryana Shopova } 425a7398723SShteryana Shopova 426a7398723SShteryana Shopova filename[namelen]='\0'; 427a7398723SShteryana Shopova break; 428a7398723SShteryana Shopova } 429a7398723SShteryana Shopova 430a7398723SShteryana Shopova if ((namelen == MAXPATHLEN) && (filename[MAXPATHLEN] != '\0')) { 431a7398723SShteryana Shopova warnx("Filename %s too long", filename); 432a7398723SShteryana Shopova return (-1); 433a7398723SShteryana Shopova } 434a7398723SShteryana Shopova 435a7398723SShteryana Shopova if (add_filename(snmptoolctx, filename, cut, 0) < 0) { 436a7398723SShteryana Shopova warnx("Error adding file %s to list", filename); 437a7398723SShteryana Shopova return (-1); 438a7398723SShteryana Shopova } 439a7398723SShteryana Shopova } while (*value != '\0'); 440a7398723SShteryana Shopova 441a7398723SShteryana Shopova return(1); 442a7398723SShteryana Shopova } 443a7398723SShteryana Shopova 444a7398723SShteryana Shopova static int32_t 445a7398723SShteryana Shopova parse_ascii(char *ascii, uint8_t *binstr, size_t binlen) 446a7398723SShteryana Shopova { 447a7398723SShteryana Shopova char dptr[3]; 4484a8c12cdSEnji Cooper size_t count; 4494a8c12cdSEnji Cooper int32_t alen, i, saved_errno; 4509a3ebeefSEnji Cooper uint32_t val; 451a7398723SShteryana Shopova 4523df5ecacSUlrich Spörlein /* Filter 0x at the beginning */ 453a7398723SShteryana Shopova if ((alen = strlen(ascii)) > 2 && ascii[0] == '0' && ascii[1] == 'x') 454a7398723SShteryana Shopova i = 2; 455a7398723SShteryana Shopova else 456a7398723SShteryana Shopova i = 0; 457a7398723SShteryana Shopova 458a7398723SShteryana Shopova saved_errno = errno; 459a7398723SShteryana Shopova errno = 0; 460a7398723SShteryana Shopova for (count = 0; i < alen; i += 2) { 461a7398723SShteryana Shopova /* XXX: consider strlen(ascii) % 2 != 0 */ 462a7398723SShteryana Shopova dptr[0] = ascii[i]; 463a7398723SShteryana Shopova dptr[1] = ascii[i + 1]; 464a7398723SShteryana Shopova dptr[2] = '\0'; 465a7398723SShteryana Shopova if ((val = strtoul(dptr, NULL, 16)) > 0xFF || errno != 0) { 466a7398723SShteryana Shopova errno = saved_errno; 467a7398723SShteryana Shopova return (-1); 468a7398723SShteryana Shopova } 469a7398723SShteryana Shopova binstr[count] = (uint8_t) val; 470a7398723SShteryana Shopova if (++count >= binlen) { 4713df5ecacSUlrich Spörlein warnx("Key %s too long - truncating to %zu octets", 472a7398723SShteryana Shopova ascii, binlen); 473a7398723SShteryana Shopova break; 474a7398723SShteryana Shopova } 475a7398723SShteryana Shopova } 476a7398723SShteryana Shopova 477a7398723SShteryana Shopova return (count); 478a7398723SShteryana Shopova } 479a7398723SShteryana Shopova 480a7398723SShteryana Shopova /* 481a7398723SShteryana Shopova * Functions to parse common input options for client tools and fill in the 482a7398723SShteryana Shopova * snmp_client structure. 483a7398723SShteryana Shopova */ 484a7398723SShteryana Shopova int32_t 485444991f1SEnji Cooper parse_authentication(struct snmp_toolinfo *snmptoolctx __unused, char *opt_arg) 486a7398723SShteryana Shopova { 487a7398723SShteryana Shopova int32_t count, subopt; 488a7398723SShteryana Shopova char *val, *option; 489a7398723SShteryana Shopova const char *const subopts[] = { 490a7398723SShteryana Shopova "proto", 491a7398723SShteryana Shopova "key", 492a7398723SShteryana Shopova NULL 493a7398723SShteryana Shopova }; 494a7398723SShteryana Shopova 495a7398723SShteryana Shopova assert(opt_arg != NULL); 496a7398723SShteryana Shopova count = 1; 497a7398723SShteryana Shopova while ((subopt = getsubopt1(&opt_arg, subopts, &val, &option)) != EOF) { 498a7398723SShteryana Shopova switch (subopt) { 499a7398723SShteryana Shopova case 0: 500a7398723SShteryana Shopova if (val == NULL) { 501a7398723SShteryana Shopova warnx("Suboption 'proto' requires an argument"); 502a7398723SShteryana Shopova return (-1); 503a7398723SShteryana Shopova } 504a7398723SShteryana Shopova if (strlen(val) != 3) { 505a7398723SShteryana Shopova warnx("Unknown auth protocol - %s", val); 506a7398723SShteryana Shopova return (-1); 507a7398723SShteryana Shopova } 508a7398723SShteryana Shopova if (strncasecmp("md5", val, strlen("md5")) == 0) 509a7398723SShteryana Shopova snmp_client.user.auth_proto = 510a7398723SShteryana Shopova SNMP_AUTH_HMAC_MD5; 511a7398723SShteryana Shopova else if (strncasecmp("sha", val, strlen("sha")) == 0) 512a7398723SShteryana Shopova snmp_client.user.auth_proto = 513a7398723SShteryana Shopova SNMP_AUTH_HMAC_SHA; 514a7398723SShteryana Shopova else { 515a7398723SShteryana Shopova warnx("Unknown auth protocol - %s", val); 516a7398723SShteryana Shopova return (-1); 517a7398723SShteryana Shopova } 518a7398723SShteryana Shopova break; 519a7398723SShteryana Shopova case 1: 520a7398723SShteryana Shopova if (val == NULL) { 521a7398723SShteryana Shopova warnx("Suboption 'key' requires an argument"); 522a7398723SShteryana Shopova return (-1); 523a7398723SShteryana Shopova } 524a7398723SShteryana Shopova if (parse_ascii(val, snmp_client.user.auth_key, 525a7398723SShteryana Shopova SNMP_AUTH_KEY_SIZ) < 0) { 526a7398723SShteryana Shopova warnx("Bad authentication key- %s", val); 527a7398723SShteryana Shopova return (-1); 528a7398723SShteryana Shopova } 529a7398723SShteryana Shopova break; 530a7398723SShteryana Shopova default: 531a7398723SShteryana Shopova warnx("Unknown suboption - '%s'", suboptarg); 532a7398723SShteryana Shopova return (-1); 533a7398723SShteryana Shopova } 534a7398723SShteryana Shopova count += 1; 535a7398723SShteryana Shopova } 536a7398723SShteryana Shopova return (2/* count */); 537a7398723SShteryana Shopova } 538a7398723SShteryana Shopova 539a7398723SShteryana Shopova int32_t 540444991f1SEnji Cooper parse_privacy(struct snmp_toolinfo *snmptoolctx __unused, char *opt_arg) 541a7398723SShteryana Shopova { 542a7398723SShteryana Shopova int32_t count, subopt; 543a7398723SShteryana Shopova char *val, *option; 544a7398723SShteryana Shopova const char *const subopts[] = { 545a7398723SShteryana Shopova "proto", 546a7398723SShteryana Shopova "key", 547a7398723SShteryana Shopova NULL 548a7398723SShteryana Shopova }; 549a7398723SShteryana Shopova 550a7398723SShteryana Shopova assert(opt_arg != NULL); 551a7398723SShteryana Shopova count = 1; 552a7398723SShteryana Shopova while ((subopt = getsubopt1(&opt_arg, subopts, &val, &option)) != EOF) { 553a7398723SShteryana Shopova switch (subopt) { 554a7398723SShteryana Shopova case 0: 555a7398723SShteryana Shopova if (val == NULL) { 556a7398723SShteryana Shopova warnx("Suboption 'proto' requires an argument"); 557a7398723SShteryana Shopova return (-1); 558a7398723SShteryana Shopova } 559a7398723SShteryana Shopova if (strlen(val) != 3) { 560a7398723SShteryana Shopova warnx("Unknown privacy protocol - %s", val); 561a7398723SShteryana Shopova return (-1); 562a7398723SShteryana Shopova } 563a7398723SShteryana Shopova if (strncasecmp("aes", val, strlen("aes")) == 0) 564a7398723SShteryana Shopova snmp_client.user.priv_proto = SNMP_PRIV_AES; 565a7398723SShteryana Shopova else if (strncasecmp("des", val, strlen("des")) == 0) 566a7398723SShteryana Shopova snmp_client.user.priv_proto = SNMP_PRIV_DES; 567a7398723SShteryana Shopova else { 568a7398723SShteryana Shopova warnx("Unknown privacy protocol - %s", val); 569a7398723SShteryana Shopova return (-1); 570a7398723SShteryana Shopova } 571a7398723SShteryana Shopova break; 572a7398723SShteryana Shopova case 1: 573a7398723SShteryana Shopova if (val == NULL) { 574a7398723SShteryana Shopova warnx("Suboption 'key' requires an argument"); 575a7398723SShteryana Shopova return (-1); 576a7398723SShteryana Shopova } 577a7398723SShteryana Shopova if (parse_ascii(val, snmp_client.user.priv_key, 578a7398723SShteryana Shopova SNMP_PRIV_KEY_SIZ) < 0) { 579a7398723SShteryana Shopova warnx("Bad privacy key- %s", val); 580a7398723SShteryana Shopova return (-1); 581a7398723SShteryana Shopova } 582a7398723SShteryana Shopova break; 583a7398723SShteryana Shopova default: 584a7398723SShteryana Shopova warnx("Unknown suboption - '%s'", suboptarg); 585a7398723SShteryana Shopova return (-1); 586a7398723SShteryana Shopova } 587a7398723SShteryana Shopova count += 1; 588a7398723SShteryana Shopova } 589a7398723SShteryana Shopova return (2/* count */); 590a7398723SShteryana Shopova } 591a7398723SShteryana Shopova 592a7398723SShteryana Shopova int32_t 593444991f1SEnji Cooper parse_context(struct snmp_toolinfo *snmptoolctx __unused, char *opt_arg) 594a7398723SShteryana Shopova { 595a7398723SShteryana Shopova int32_t count, subopt; 596a7398723SShteryana Shopova char *val, *option; 597a7398723SShteryana Shopova const char *const subopts[] = { 598a7398723SShteryana Shopova "context", 599a7398723SShteryana Shopova "context-engine", 600a7398723SShteryana Shopova NULL 601a7398723SShteryana Shopova }; 602a7398723SShteryana Shopova 603a7398723SShteryana Shopova assert(opt_arg != NULL); 604a7398723SShteryana Shopova count = 1; 605a7398723SShteryana Shopova while ((subopt = getsubopt1(&opt_arg, subopts, &val, &option)) != EOF) { 606a7398723SShteryana Shopova switch (subopt) { 607a7398723SShteryana Shopova case 0: 608a7398723SShteryana Shopova if (val == NULL) { 609a7398723SShteryana Shopova warnx("Suboption 'context' - no argument"); 610a7398723SShteryana Shopova return (-1); 611a7398723SShteryana Shopova } 612a7398723SShteryana Shopova strlcpy(snmp_client.cname, val, SNMP_CONTEXT_NAME_SIZ); 613a7398723SShteryana Shopova break; 614a7398723SShteryana Shopova case 1: 615a7398723SShteryana Shopova if (val == NULL) { 616a7398723SShteryana Shopova warnx("Suboption 'context-engine' - no argument"); 617a7398723SShteryana Shopova return (-1); 618a7398723SShteryana Shopova } 619a7398723SShteryana Shopova if ((snmp_client.clen = parse_ascii(val, 620a7398723SShteryana Shopova snmp_client.cengine, SNMP_ENGINE_ID_SIZ)) < 0) { 621a7398723SShteryana Shopova warnx("Bad EngineID - %s", val); 622a7398723SShteryana Shopova return (-1); 623a7398723SShteryana Shopova } 624a7398723SShteryana Shopova break; 625a7398723SShteryana Shopova default: 626a7398723SShteryana Shopova warnx("Unknown suboption - '%s'", suboptarg); 627a7398723SShteryana Shopova return (-1); 628a7398723SShteryana Shopova } 629a7398723SShteryana Shopova count += 1; 630a7398723SShteryana Shopova } 631a7398723SShteryana Shopova return (2/* count */); 632a7398723SShteryana Shopova } 633a7398723SShteryana Shopova 634a7398723SShteryana Shopova int32_t 635444991f1SEnji Cooper parse_user_security(struct snmp_toolinfo *snmptoolctx __unused, char *opt_arg) 636a7398723SShteryana Shopova { 637a7398723SShteryana Shopova int32_t count, subopt, saved_errno; 638a7398723SShteryana Shopova char *val, *option; 639a7398723SShteryana Shopova const char *const subopts[] = { 640a7398723SShteryana Shopova "engine", 641a7398723SShteryana Shopova "engine-boots", 642a7398723SShteryana Shopova "engine-time", 643a7398723SShteryana Shopova "name", 644a7398723SShteryana Shopova NULL 645a7398723SShteryana Shopova }; 646a7398723SShteryana Shopova 647a7398723SShteryana Shopova assert(opt_arg != NULL); 648a7398723SShteryana Shopova count = 1; 649a7398723SShteryana Shopova while ((subopt = getsubopt1(&opt_arg, subopts, &val, &option)) != EOF) { 650a7398723SShteryana Shopova switch (subopt) { 651a7398723SShteryana Shopova case 0: 652a7398723SShteryana Shopova if (val == NULL) { 653a7398723SShteryana Shopova warnx("Suboption 'engine' - no argument"); 654a7398723SShteryana Shopova return (-1); 655a7398723SShteryana Shopova } 656a7398723SShteryana Shopova snmp_client.engine.engine_len = parse_ascii(val, 657a7398723SShteryana Shopova snmp_client.engine.engine_id, SNMP_ENGINE_ID_SIZ); 658a7398723SShteryana Shopova if (snmp_client.engine.engine_len < 0) { 659a7398723SShteryana Shopova warnx("Bad EngineID - %s", val); 660a7398723SShteryana Shopova return (-1); 661a7398723SShteryana Shopova } 662a7398723SShteryana Shopova break; 663a7398723SShteryana Shopova case 1: 664a7398723SShteryana Shopova if (val == NULL) { 665a7398723SShteryana Shopova warnx("Suboption 'engine-boots' - no argument"); 666a7398723SShteryana Shopova return (-1); 667a7398723SShteryana Shopova } 668a7398723SShteryana Shopova saved_errno = errno; 669a7398723SShteryana Shopova errno = 0; 670a7398723SShteryana Shopova snmp_client.engine.engine_boots = strtoul(val, NULL, 10); 671a7398723SShteryana Shopova if (errno != 0) { 672a7398723SShteryana Shopova warnx("Bad 'engine-boots' value %s - %s", val, 673a7398723SShteryana Shopova strerror(errno)); 674a7398723SShteryana Shopova errno = saved_errno; 675a7398723SShteryana Shopova return (-1); 676a7398723SShteryana Shopova } 677a7398723SShteryana Shopova errno = saved_errno; 678a7398723SShteryana Shopova break; 679a7398723SShteryana Shopova case 2: 680a7398723SShteryana Shopova if (val == NULL) { 681a7398723SShteryana Shopova warnx("Suboption 'engine-time' - no argument"); 682a7398723SShteryana Shopova return (-1); 683a7398723SShteryana Shopova } 684a7398723SShteryana Shopova saved_errno = errno; 685a7398723SShteryana Shopova errno = 0; 686a7398723SShteryana Shopova snmp_client.engine.engine_time = strtoul(val, NULL, 10); 687a7398723SShteryana Shopova if (errno != 0) { 688a7398723SShteryana Shopova warnx("Bad 'engine-time' value %s - %s", val, 689a7398723SShteryana Shopova strerror(errno)); 690a7398723SShteryana Shopova errno = saved_errno; 691a7398723SShteryana Shopova return (-1); 692a7398723SShteryana Shopova } 693a7398723SShteryana Shopova errno = saved_errno; 694a7398723SShteryana Shopova break; 695a7398723SShteryana Shopova case 3: 696a7398723SShteryana Shopova strlcpy(snmp_client.user.sec_name, val, 697a7398723SShteryana Shopova SNMP_ADM_STR32_SIZ); 698a7398723SShteryana Shopova break; 699a7398723SShteryana Shopova default: 700a7398723SShteryana Shopova warnx("Unknown suboption - '%s'", suboptarg); 701a7398723SShteryana Shopova return (-1); 702a7398723SShteryana Shopova } 703a7398723SShteryana Shopova count += 1; 704a7398723SShteryana Shopova } 705a7398723SShteryana Shopova return (2/* count */); 706a7398723SShteryana Shopova } 707a7398723SShteryana Shopova 708a7398723SShteryana Shopova int32_t 709a7398723SShteryana Shopova parse_file(struct snmp_toolinfo *snmptoolctx, char *opt_arg) 710a7398723SShteryana Shopova { 711a7398723SShteryana Shopova assert(opt_arg != NULL); 712a7398723SShteryana Shopova 713a7398723SShteryana Shopova if (parse_flist(snmptoolctx, opt_arg, NULL, &IsoOrgDod_OID) < 0) 714a7398723SShteryana Shopova return (-1); 715a7398723SShteryana Shopova 716a7398723SShteryana Shopova return (2); 717a7398723SShteryana Shopova } 718a7398723SShteryana Shopova 719a7398723SShteryana Shopova int32_t 720a7398723SShteryana Shopova parse_include(struct snmp_toolinfo *snmptoolctx, char *opt_arg) 721a7398723SShteryana Shopova { 722a7398723SShteryana Shopova char path[MAXPATHLEN + 1]; 723a7398723SShteryana Shopova int32_t cut_dflt, len, subopt; 724a7398723SShteryana Shopova struct asn_oid cut; 725a7398723SShteryana Shopova char *val, *option; 726a7398723SShteryana Shopova const char *const subopts[] = { 727a7398723SShteryana Shopova "cut", 728a7398723SShteryana Shopova "path", 729a7398723SShteryana Shopova "file", 730a7398723SShteryana Shopova NULL 731a7398723SShteryana Shopova }; 732a7398723SShteryana Shopova 733a7398723SShteryana Shopova #define INC_CUT 0 734a7398723SShteryana Shopova #define INC_PATH 1 735a7398723SShteryana Shopova #define INC_LIST 2 736a7398723SShteryana Shopova 737a7398723SShteryana Shopova assert(opt_arg != NULL); 738a7398723SShteryana Shopova 739a7398723SShteryana Shopova /* if (opt == 'i') 740a7398723SShteryana Shopova free_filelist(snmptoolctx, ); */ 741a7398723SShteryana Shopova /* 742a7398723SShteryana Shopova * This function should be called only after getopt(3) - otherwise if 743a7398723SShteryana Shopova * no previous validation of opt_arg strlen() may not return what is 744a7398723SShteryana Shopova * expected. 745a7398723SShteryana Shopova */ 746a7398723SShteryana Shopova 747a7398723SShteryana Shopova path[0] = '\0'; 748a7398723SShteryana Shopova memset(&cut, 0, sizeof(struct asn_oid)); 749a7398723SShteryana Shopova cut_dflt = -1; 750a7398723SShteryana Shopova 751a7398723SShteryana Shopova while ((subopt = getsubopt1(&opt_arg, subopts, &val, &option)) != EOF) { 752a7398723SShteryana Shopova switch (subopt) { 753a7398723SShteryana Shopova case INC_CUT: 754a7398723SShteryana Shopova if (val == NULL) { 755a7398723SShteryana Shopova warnx("Suboption 'cut' requires an argument"); 756a7398723SShteryana Shopova return (-1); 757a7398723SShteryana Shopova } else { 758a7398723SShteryana Shopova if (snmp_parse_numoid(val, &cut) < 0) 759a7398723SShteryana Shopova return (-1); 760a7398723SShteryana Shopova } 761a7398723SShteryana Shopova cut_dflt = 1; 762a7398723SShteryana Shopova break; 763a7398723SShteryana Shopova 764a7398723SShteryana Shopova case INC_PATH: 765a7398723SShteryana Shopova if ((len = parse_path(val)) < 0) 766a7398723SShteryana Shopova return (-1); 767a7398723SShteryana Shopova strlcpy(path, val, len + 1); 768a7398723SShteryana Shopova break; 769a7398723SShteryana Shopova 770a7398723SShteryana Shopova case INC_LIST: 771a7398723SShteryana Shopova if (val == NULL) 772a7398723SShteryana Shopova return (-1); 773a7398723SShteryana Shopova if (cut_dflt == -1) 774a7398723SShteryana Shopova len = parse_flist(snmptoolctx, val, path, &IsoOrgDod_OID); 775a7398723SShteryana Shopova else 776a7398723SShteryana Shopova len = parse_flist(snmptoolctx, val, path, &cut); 777a7398723SShteryana Shopova if (len < 0) 778a7398723SShteryana Shopova return (-1); 779a7398723SShteryana Shopova break; 780a7398723SShteryana Shopova 781a7398723SShteryana Shopova default: 782a7398723SShteryana Shopova warnx("Unknown suboption - '%s'", suboptarg); 783a7398723SShteryana Shopova return (-1); 784a7398723SShteryana Shopova } 785a7398723SShteryana Shopova } 786a7398723SShteryana Shopova 787a7398723SShteryana Shopova /* XXX: Fix me - returning two is wrong here */ 788a7398723SShteryana Shopova return (2); 789a7398723SShteryana Shopova } 790a7398723SShteryana Shopova 791a7398723SShteryana Shopova int32_t 792a7398723SShteryana Shopova parse_server(char *opt_arg) 793a7398723SShteryana Shopova { 794a7398723SShteryana Shopova assert(opt_arg != NULL); 795a7398723SShteryana Shopova 796a7398723SShteryana Shopova if (snmp_parse_server(&snmp_client, opt_arg) < 0) 797a7398723SShteryana Shopova return (-1); 798a7398723SShteryana Shopova 799a7398723SShteryana Shopova if (snmp_client.trans > SNMP_TRANS_UDP && snmp_client.chost == NULL) { 8007a7c07efSDon Lewis if ((snmp_client.chost = malloc(strlen(SNMP_DEFAULT_LOCAL) + 1)) 801a7398723SShteryana Shopova == NULL) { 802a7398723SShteryana Shopova syslog(LOG_ERR, "malloc() failed: %s", strerror(errno)); 803a7398723SShteryana Shopova return (-1); 804a7398723SShteryana Shopova } 805a7398723SShteryana Shopova strcpy(snmp_client.chost, SNMP_DEFAULT_LOCAL); 806a7398723SShteryana Shopova } 807a7398723SShteryana Shopova 808a7398723SShteryana Shopova return (2); 809a7398723SShteryana Shopova } 810a7398723SShteryana Shopova 811a7398723SShteryana Shopova int32_t 812a7398723SShteryana Shopova parse_timeout(char *opt_arg) 813a7398723SShteryana Shopova { 814a7398723SShteryana Shopova int32_t v, saved_errno; 815a7398723SShteryana Shopova 816a7398723SShteryana Shopova assert(opt_arg != NULL); 817a7398723SShteryana Shopova 818a7398723SShteryana Shopova saved_errno = errno; 819a7398723SShteryana Shopova errno = 0; 820a7398723SShteryana Shopova 821a7398723SShteryana Shopova v = strtol(opt_arg, NULL, 10); 822a7398723SShteryana Shopova if (errno != 0) { 823a7398723SShteryana Shopova warnx( "Error parsing timeout value - %s", strerror(errno)); 824a7398723SShteryana Shopova errno = saved_errno; 825a7398723SShteryana Shopova return (-1); 826a7398723SShteryana Shopova } 827a7398723SShteryana Shopova 828a7398723SShteryana Shopova snmp_client.timeout.tv_sec = v; 829a7398723SShteryana Shopova errno = saved_errno; 830a7398723SShteryana Shopova return (2); 831a7398723SShteryana Shopova } 832a7398723SShteryana Shopova 833a7398723SShteryana Shopova int32_t 834a7398723SShteryana Shopova parse_retry(char *opt_arg) 835a7398723SShteryana Shopova { 836a7398723SShteryana Shopova uint32_t v; 837a7398723SShteryana Shopova int32_t saved_errno; 838a7398723SShteryana Shopova 839a7398723SShteryana Shopova assert(opt_arg != NULL); 840a7398723SShteryana Shopova 841a7398723SShteryana Shopova saved_errno = errno; 842a7398723SShteryana Shopova errno = 0; 843a7398723SShteryana Shopova 844a7398723SShteryana Shopova v = strtoul(opt_arg, NULL, 10); 845a7398723SShteryana Shopova if (errno != 0) { 846a7398723SShteryana Shopova warnx("Error parsing retries count - %s", strerror(errno)); 847a7398723SShteryana Shopova errno = saved_errno; 848a7398723SShteryana Shopova return (-1); 849a7398723SShteryana Shopova } 850a7398723SShteryana Shopova 851a7398723SShteryana Shopova snmp_client.retries = v; 852a7398723SShteryana Shopova errno = saved_errno; 853a7398723SShteryana Shopova return (2); 854a7398723SShteryana Shopova } 855a7398723SShteryana Shopova 856a7398723SShteryana Shopova int32_t 857a7398723SShteryana Shopova parse_version(char *opt_arg) 858a7398723SShteryana Shopova { 859a7398723SShteryana Shopova uint32_t v; 860a7398723SShteryana Shopova int32_t saved_errno; 861a7398723SShteryana Shopova 862a7398723SShteryana Shopova assert(opt_arg != NULL); 863a7398723SShteryana Shopova 864a7398723SShteryana Shopova saved_errno = errno; 865a7398723SShteryana Shopova errno = 0; 866a7398723SShteryana Shopova 867a7398723SShteryana Shopova v = strtoul(opt_arg, NULL, 10); 868a7398723SShteryana Shopova if (errno != 0) { 869a7398723SShteryana Shopova warnx("Error parsing version - %s", strerror(errno)); 870a7398723SShteryana Shopova errno = saved_errno; 871a7398723SShteryana Shopova return (-1); 872a7398723SShteryana Shopova } 873a7398723SShteryana Shopova 874a7398723SShteryana Shopova switch (v) { 875a7398723SShteryana Shopova case 1: 876a7398723SShteryana Shopova snmp_client.version = SNMP_V1; 877a7398723SShteryana Shopova break; 878a7398723SShteryana Shopova case 2: 879a7398723SShteryana Shopova snmp_client.version = SNMP_V2c; 880a7398723SShteryana Shopova break; 881a7398723SShteryana Shopova case 3: 882a7398723SShteryana Shopova snmp_client.version = SNMP_V3; 883a7398723SShteryana Shopova break; 884a7398723SShteryana Shopova default: 885a7398723SShteryana Shopova warnx("Unsupported SNMP version - %u", v); 886a7398723SShteryana Shopova errno = saved_errno; 887a7398723SShteryana Shopova return (-1); 888a7398723SShteryana Shopova } 889a7398723SShteryana Shopova 890a7398723SShteryana Shopova errno = saved_errno; 891a7398723SShteryana Shopova return (2); 892a7398723SShteryana Shopova } 893a7398723SShteryana Shopova 894a7398723SShteryana Shopova int32_t 895a7398723SShteryana Shopova parse_local_path(char *opt_arg) 896a7398723SShteryana Shopova { 897a7398723SShteryana Shopova assert(opt_arg != NULL); 898a7398723SShteryana Shopova 899a7398723SShteryana Shopova if (sizeof(opt_arg) > sizeof(SNMP_LOCAL_PATH)) { 900a7398723SShteryana Shopova warnx("Filename too long - %s", opt_arg); 901a7398723SShteryana Shopova return (-1); 902a7398723SShteryana Shopova } 903a7398723SShteryana Shopova 904a7398723SShteryana Shopova strlcpy(snmp_client.local_path, opt_arg, sizeof(SNMP_LOCAL_PATH)); 905a7398723SShteryana Shopova return (2); 906a7398723SShteryana Shopova } 907a7398723SShteryana Shopova 908a7398723SShteryana Shopova int32_t 909a7398723SShteryana Shopova parse_buflen(char *opt_arg) 910a7398723SShteryana Shopova { 911a7398723SShteryana Shopova uint32_t size; 912a7398723SShteryana Shopova int32_t saved_errno; 913a7398723SShteryana Shopova 914a7398723SShteryana Shopova assert(opt_arg != NULL); 915a7398723SShteryana Shopova 916a7398723SShteryana Shopova saved_errno = errno; 917a7398723SShteryana Shopova errno = 0; 918a7398723SShteryana Shopova 919a7398723SShteryana Shopova size = strtoul(opt_arg, NULL, 10); 920a7398723SShteryana Shopova if (errno != 0) { 921a7398723SShteryana Shopova warnx("Error parsing buffer size - %s", strerror(errno)); 922a7398723SShteryana Shopova errno = saved_errno; 923a7398723SShteryana Shopova return (-1); 924a7398723SShteryana Shopova } 925a7398723SShteryana Shopova 926a7398723SShteryana Shopova if (size > MAX_BUFF_SIZE) { 927a7398723SShteryana Shopova warnx("Buffer size too big - %d max allowed", MAX_BUFF_SIZE); 928a7398723SShteryana Shopova errno = saved_errno; 929a7398723SShteryana Shopova return (-1); 930a7398723SShteryana Shopova } 931a7398723SShteryana Shopova 932a7398723SShteryana Shopova snmp_client.txbuflen = snmp_client.rxbuflen = size; 933a7398723SShteryana Shopova errno = saved_errno; 934a7398723SShteryana Shopova return (2); 935a7398723SShteryana Shopova } 936a7398723SShteryana Shopova 937a7398723SShteryana Shopova int32_t 938a7398723SShteryana Shopova parse_debug(void) 939a7398723SShteryana Shopova { 940a7398723SShteryana Shopova snmp_client.dump_pdus = 1; 941a7398723SShteryana Shopova return (1); 942a7398723SShteryana Shopova } 943a7398723SShteryana Shopova 944a7398723SShteryana Shopova int32_t 945a7398723SShteryana Shopova parse_discovery(struct snmp_toolinfo *snmptoolctx) 946a7398723SShteryana Shopova { 947a7398723SShteryana Shopova SET_EDISCOVER(snmptoolctx); 948a7398723SShteryana Shopova snmp_client.version = SNMP_V3; 949a7398723SShteryana Shopova return (1); 950a7398723SShteryana Shopova } 951a7398723SShteryana Shopova 952a7398723SShteryana Shopova int32_t 953a7398723SShteryana Shopova parse_local_key(struct snmp_toolinfo *snmptoolctx) 954a7398723SShteryana Shopova { 955a7398723SShteryana Shopova SET_LOCALKEY(snmptoolctx); 956a7398723SShteryana Shopova snmp_client.version = SNMP_V3; 957a7398723SShteryana Shopova return (1); 958a7398723SShteryana Shopova } 959a7398723SShteryana Shopova 960a7398723SShteryana Shopova int32_t 961a7398723SShteryana Shopova parse_num_oids(struct snmp_toolinfo *snmptoolctx) 962a7398723SShteryana Shopova { 963a7398723SShteryana Shopova SET_NUMERIC(snmptoolctx); 964a7398723SShteryana Shopova return (1); 965a7398723SShteryana Shopova } 966a7398723SShteryana Shopova 967a7398723SShteryana Shopova int32_t 968a7398723SShteryana Shopova parse_output(struct snmp_toolinfo *snmptoolctx, char *opt_arg) 969a7398723SShteryana Shopova { 970a7398723SShteryana Shopova assert(opt_arg != NULL); 971a7398723SShteryana Shopova 972a7398723SShteryana Shopova if (strlen(opt_arg) > strlen("verbose")) { 973a7398723SShteryana Shopova warnx( "Invalid output option - %s",opt_arg); 974a7398723SShteryana Shopova return (-1); 975a7398723SShteryana Shopova } 976a7398723SShteryana Shopova 977a7398723SShteryana Shopova if (strncasecmp(opt_arg, "short", strlen(opt_arg)) == 0) 978a7398723SShteryana Shopova SET_OUTPUT(snmptoolctx, OUTPUT_SHORT); 979a7398723SShteryana Shopova else if (strncasecmp(opt_arg, "verbose", strlen(opt_arg)) == 0) 980a7398723SShteryana Shopova SET_OUTPUT(snmptoolctx, OUTPUT_VERBOSE); 981a7398723SShteryana Shopova else if (strncasecmp(opt_arg,"tabular", strlen(opt_arg)) == 0) 982a7398723SShteryana Shopova SET_OUTPUT(snmptoolctx, OUTPUT_TABULAR); 983a7398723SShteryana Shopova else if (strncasecmp(opt_arg, "quiet", strlen(opt_arg)) == 0) 984a7398723SShteryana Shopova SET_OUTPUT(snmptoolctx, OUTPUT_QUIET); 985a7398723SShteryana Shopova else { 986a7398723SShteryana Shopova warnx( "Invalid output option - %s", opt_arg); 987a7398723SShteryana Shopova return (-1); 988a7398723SShteryana Shopova } 989a7398723SShteryana Shopova 990a7398723SShteryana Shopova return (2); 991a7398723SShteryana Shopova } 992a7398723SShteryana Shopova 993a7398723SShteryana Shopova int32_t 994a7398723SShteryana Shopova parse_errors(struct snmp_toolinfo *snmptoolctx) 995a7398723SShteryana Shopova { 996a7398723SShteryana Shopova SET_RETRY(snmptoolctx); 997a7398723SShteryana Shopova return (1); 998a7398723SShteryana Shopova } 999a7398723SShteryana Shopova 1000a7398723SShteryana Shopova int32_t 1001a7398723SShteryana Shopova parse_skip_access(struct snmp_toolinfo *snmptoolctx) 1002a7398723SShteryana Shopova { 1003a7398723SShteryana Shopova SET_ERRIGNORE(snmptoolctx); 1004a7398723SShteryana Shopova return (1); 1005a7398723SShteryana Shopova } 1006a7398723SShteryana Shopova 1007a7398723SShteryana Shopova char * 1008a7398723SShteryana Shopova snmp_parse_suboid(char *str, struct asn_oid *oid) 1009a7398723SShteryana Shopova { 1010a7398723SShteryana Shopova char *endptr; 1011a7398723SShteryana Shopova asn_subid_t suboid; 1012a7398723SShteryana Shopova 1013a7398723SShteryana Shopova if (*str == '.') 1014a7398723SShteryana Shopova str++; 1015a7398723SShteryana Shopova 1016a7398723SShteryana Shopova if (*str < '0' || *str > '9') 1017a7398723SShteryana Shopova return (str); 1018a7398723SShteryana Shopova 1019a7398723SShteryana Shopova do { 1020a7398723SShteryana Shopova suboid = strtoul(str, &endptr, 10); 1021a7398723SShteryana Shopova if ((asn_subid_t) suboid > ASN_MAXID) { 1022a7398723SShteryana Shopova warnx("Suboid %u > ASN_MAXID", suboid); 1023a7398723SShteryana Shopova return (NULL); 1024a7398723SShteryana Shopova } 1025a7398723SShteryana Shopova if (snmp_suboid_append(oid, suboid) < 0) 1026a7398723SShteryana Shopova return (NULL); 1027a7398723SShteryana Shopova str = endptr + 1; 1028a7398723SShteryana Shopova } while (*endptr == '.'); 1029a7398723SShteryana Shopova 1030a7398723SShteryana Shopova return (endptr); 1031a7398723SShteryana Shopova } 1032a7398723SShteryana Shopova 1033a7398723SShteryana Shopova static char * 1034a7398723SShteryana Shopova snmp_int2asn_oid(char *str, struct asn_oid *oid) 1035a7398723SShteryana Shopova { 1036a7398723SShteryana Shopova char *endptr; 1037a7398723SShteryana Shopova int32_t v, saved_errno; 1038a7398723SShteryana Shopova 1039a7398723SShteryana Shopova saved_errno = errno; 1040a7398723SShteryana Shopova errno = 0; 1041a7398723SShteryana Shopova 1042a7398723SShteryana Shopova v = strtol(str, &endptr, 10); 1043a7398723SShteryana Shopova if (errno != 0) { 1044a7398723SShteryana Shopova warnx("Integer value %s not supported - %s", str, 1045a7398723SShteryana Shopova strerror(errno)); 1046a7398723SShteryana Shopova errno = saved_errno; 1047a7398723SShteryana Shopova return (NULL); 1048a7398723SShteryana Shopova } 1049a7398723SShteryana Shopova errno = saved_errno; 1050a7398723SShteryana Shopova 1051a7398723SShteryana Shopova if (snmp_suboid_append(oid, (asn_subid_t) v) < 0) 1052a7398723SShteryana Shopova return (NULL); 1053a7398723SShteryana Shopova 1054a7398723SShteryana Shopova return (endptr); 1055a7398723SShteryana Shopova } 1056a7398723SShteryana Shopova 1057a7398723SShteryana Shopova /* It is a bit weird to have a table indexed by OID but still... */ 1058a7398723SShteryana Shopova static char * 1059a7398723SShteryana Shopova snmp_oid2asn_oid(struct snmp_toolinfo *snmptoolctx, char *str, 1060a7398723SShteryana Shopova struct asn_oid *oid) 1061a7398723SShteryana Shopova { 1062a7398723SShteryana Shopova int32_t i; 106381910adfSEnji Cooper char string[MAXSTR + 1], *endptr; 1064a7398723SShteryana Shopova struct snmp_object obj; 1065a7398723SShteryana Shopova 1066a7398723SShteryana Shopova for (i = 0; i < MAXSTR; i++) 1067a7398723SShteryana Shopova if (isalpha (*(str + i)) == 0) 1068a7398723SShteryana Shopova break; 1069a7398723SShteryana Shopova 1070a7398723SShteryana Shopova endptr = str + i; 1071a7398723SShteryana Shopova memset(&obj, 0, sizeof(struct snmp_object)); 1072a7398723SShteryana Shopova if (i == 0) { 1073a7398723SShteryana Shopova if ((endptr = snmp_parse_suboid(str, &(obj.val.var))) == NULL) 1074a7398723SShteryana Shopova return (NULL); 1075a7398723SShteryana Shopova if (snmp_suboid_append(oid, (asn_subid_t) obj.val.var.len) < 0) 1076a7398723SShteryana Shopova return (NULL); 1077a7398723SShteryana Shopova } else { 1078a7398723SShteryana Shopova strlcpy(string, str, i + 1); 1079a7398723SShteryana Shopova if (snmp_lookup_enumoid(snmptoolctx, &obj, string) < 0) { 1080a7398723SShteryana Shopova warnx("Unknown string - %s", string); 1081a7398723SShteryana Shopova return (NULL); 1082a7398723SShteryana Shopova } 1083a7398723SShteryana Shopova } 1084a7398723SShteryana Shopova 1085a7398723SShteryana Shopova asn_append_oid(oid, &(obj.val.var)); 1086a7398723SShteryana Shopova return (endptr); 1087a7398723SShteryana Shopova } 1088a7398723SShteryana Shopova 1089a7398723SShteryana Shopova static char * 1090a7398723SShteryana Shopova snmp_ip2asn_oid(char *str, struct asn_oid *oid) 1091a7398723SShteryana Shopova { 1092a7398723SShteryana Shopova uint32_t v; 1093a7398723SShteryana Shopova int32_t i; 1094a7398723SShteryana Shopova char *endptr, *ptr; 1095a7398723SShteryana Shopova 1096a7398723SShteryana Shopova ptr = str; 1097a7398723SShteryana Shopova for (i = 0; i < 4; i++) { 1098a7398723SShteryana Shopova v = strtoul(ptr, &endptr, 10); 1099a7398723SShteryana Shopova if (v > 0xff) 1100a7398723SShteryana Shopova return (NULL); 1101a7398723SShteryana Shopova if (*endptr != '.' && strchr("],\0", *endptr) == NULL && i != 3) 1102a7398723SShteryana Shopova return (NULL); 1103a7398723SShteryana Shopova if (snmp_suboid_append(oid, (asn_subid_t) v) < 0) 1104a7398723SShteryana Shopova return (NULL); 1105a7398723SShteryana Shopova ptr = endptr + 1; 1106a7398723SShteryana Shopova } 1107a7398723SShteryana Shopova 1108a7398723SShteryana Shopova return (endptr); 1109a7398723SShteryana Shopova } 1110a7398723SShteryana Shopova 1111a7398723SShteryana Shopova /* 32-bit counter, gauge, timeticks. */ 1112a7398723SShteryana Shopova static char * 1113a7398723SShteryana Shopova snmp_uint2asn_oid(char *str, struct asn_oid *oid) 1114a7398723SShteryana Shopova { 1115a7398723SShteryana Shopova char *endptr; 1116a7398723SShteryana Shopova uint32_t v; 1117a7398723SShteryana Shopova int32_t saved_errno; 1118a7398723SShteryana Shopova 1119a7398723SShteryana Shopova saved_errno = errno; 1120a7398723SShteryana Shopova errno = 0; 1121a7398723SShteryana Shopova 1122a7398723SShteryana Shopova v = strtoul(str, &endptr, 10); 1123a7398723SShteryana Shopova if (errno != 0) { 1124a7398723SShteryana Shopova warnx("Integer value %s not supported - %s\n", str, 1125a7398723SShteryana Shopova strerror(errno)); 1126a7398723SShteryana Shopova errno = saved_errno; 1127a7398723SShteryana Shopova return (NULL); 1128a7398723SShteryana Shopova } 1129a7398723SShteryana Shopova errno = saved_errno; 1130a7398723SShteryana Shopova if (snmp_suboid_append(oid, (asn_subid_t) v) < 0) 1131a7398723SShteryana Shopova return (NULL); 1132a7398723SShteryana Shopova 1133a7398723SShteryana Shopova return (endptr); 1134a7398723SShteryana Shopova } 1135a7398723SShteryana Shopova 1136a7398723SShteryana Shopova static char * 1137a7398723SShteryana Shopova snmp_cnt64_2asn_oid(char *str, struct asn_oid *oid) 1138a7398723SShteryana Shopova { 1139a7398723SShteryana Shopova char *endptr; 1140a7398723SShteryana Shopova uint64_t v; 1141a7398723SShteryana Shopova int32_t saved_errno; 1142a7398723SShteryana Shopova 1143a7398723SShteryana Shopova saved_errno = errno; 1144a7398723SShteryana Shopova errno = 0; 1145a7398723SShteryana Shopova 1146a7398723SShteryana Shopova v = strtoull(str, &endptr, 10); 1147a7398723SShteryana Shopova 1148a7398723SShteryana Shopova if (errno != 0) { 1149a7398723SShteryana Shopova warnx("Integer value %s not supported - %s", str, 1150a7398723SShteryana Shopova strerror(errno)); 1151a7398723SShteryana Shopova errno = saved_errno; 1152a7398723SShteryana Shopova return (NULL); 1153a7398723SShteryana Shopova } 1154a7398723SShteryana Shopova errno = saved_errno; 1155a7398723SShteryana Shopova if (snmp_suboid_append(oid, (asn_subid_t) (v & 0xffffffff)) < 0) 1156a7398723SShteryana Shopova return (NULL); 1157a7398723SShteryana Shopova 1158a7398723SShteryana Shopova if (snmp_suboid_append(oid, (asn_subid_t) (v >> 32)) < 0) 1159a7398723SShteryana Shopova return (NULL); 1160a7398723SShteryana Shopova 1161a7398723SShteryana Shopova return (endptr); 1162a7398723SShteryana Shopova } 1163a7398723SShteryana Shopova 1164a7398723SShteryana Shopova enum snmp_syntax 1165a7398723SShteryana Shopova parse_syntax(char *str) 1166a7398723SShteryana Shopova { 1167a7398723SShteryana Shopova int32_t i; 1168a7398723SShteryana Shopova 1169a7398723SShteryana Shopova for (i = 0; i < SNMP_SYNTAX_UNKNOWN; i++) { 1170a7398723SShteryana Shopova if (strncmp(syntax_strings[i].str, str, 1171a7398723SShteryana Shopova strlen(syntax_strings[i].str)) == 0) 1172a7398723SShteryana Shopova return (syntax_strings[i].stx); 1173a7398723SShteryana Shopova } 1174a7398723SShteryana Shopova 1175a7398723SShteryana Shopova return (SNMP_SYNTAX_NULL); 1176a7398723SShteryana Shopova } 1177a7398723SShteryana Shopova 1178a7398723SShteryana Shopova static char * 1179a7398723SShteryana Shopova snmp_parse_subindex(struct snmp_toolinfo *snmptoolctx, char *str, 1180a7398723SShteryana Shopova struct index *idx, struct snmp_object *object) 1181a7398723SShteryana Shopova { 1182a7398723SShteryana Shopova char *ptr; 1183a7398723SShteryana Shopova int32_t i; 1184a7398723SShteryana Shopova enum snmp_syntax stx; 1185a7398723SShteryana Shopova char syntax[MAX_CMD_SYNTAX_LEN]; 1186a7398723SShteryana Shopova 1187a7398723SShteryana Shopova ptr = str; 1188a7398723SShteryana Shopova if (GET_OUTPUT(snmptoolctx) == OUTPUT_VERBOSE) { 1189a7398723SShteryana Shopova for (i = 0; i < MAX_CMD_SYNTAX_LEN ; i++) { 1190a7398723SShteryana Shopova if (*(ptr + i) == ':') 1191a7398723SShteryana Shopova break; 1192a7398723SShteryana Shopova } 1193a7398723SShteryana Shopova 1194a7398723SShteryana Shopova if (i >= MAX_CMD_SYNTAX_LEN) { 1195a7398723SShteryana Shopova warnx("Unknown syntax in OID - %s", str); 1196a7398723SShteryana Shopova return (NULL); 1197a7398723SShteryana Shopova } 1198a7398723SShteryana Shopova /* Expect a syntax string here. */ 1199a7398723SShteryana Shopova if ((stx = parse_syntax(str)) <= SNMP_SYNTAX_NULL) { 1200a7398723SShteryana Shopova warnx("Invalid syntax - %s",syntax); 1201a7398723SShteryana Shopova return (NULL); 1202a7398723SShteryana Shopova } 1203a7398723SShteryana Shopova 1204a7398723SShteryana Shopova if (stx != idx->syntax && !ISSET_ERRIGNORE(snmptoolctx)) { 1205a7398723SShteryana Shopova warnx("Syntax mismatch - %d expected, %d given", 1206a7398723SShteryana Shopova idx->syntax, stx); 1207a7398723SShteryana Shopova return (NULL); 1208a7398723SShteryana Shopova } 1209a7398723SShteryana Shopova /* 1210a7398723SShteryana Shopova * That is where the suboid started + the syntax length + one 1211a7398723SShteryana Shopova * character for ':'. 1212a7398723SShteryana Shopova */ 1213a7398723SShteryana Shopova ptr = str + i + 1; 1214a7398723SShteryana Shopova } else 1215a7398723SShteryana Shopova stx = idx->syntax; 1216a7398723SShteryana Shopova 1217a7398723SShteryana Shopova switch (stx) { 1218a7398723SShteryana Shopova case SNMP_SYNTAX_INTEGER: 1219a7398723SShteryana Shopova return (snmp_int2asn_oid(ptr, &(object->val.var))); 1220a7398723SShteryana Shopova case SNMP_SYNTAX_OID: 1221a7398723SShteryana Shopova return (snmp_oid2asn_oid(snmptoolctx, ptr, 1222a7398723SShteryana Shopova &(object->val.var))); 1223a7398723SShteryana Shopova case SNMP_SYNTAX_IPADDRESS: 1224a7398723SShteryana Shopova return (snmp_ip2asn_oid(ptr, &(object->val.var))); 1225a7398723SShteryana Shopova case SNMP_SYNTAX_COUNTER: 1226a7398723SShteryana Shopova /* FALLTHROUGH */ 1227a7398723SShteryana Shopova case SNMP_SYNTAX_GAUGE: 1228a7398723SShteryana Shopova /* FALLTHROUGH */ 1229a7398723SShteryana Shopova case SNMP_SYNTAX_TIMETICKS: 1230a7398723SShteryana Shopova return (snmp_uint2asn_oid(ptr, &(object->val.var))); 1231a7398723SShteryana Shopova case SNMP_SYNTAX_COUNTER64: 1232a7398723SShteryana Shopova return (snmp_cnt64_2asn_oid(ptr, &(object->val.var))); 1233a7398723SShteryana Shopova case SNMP_SYNTAX_OCTETSTRING: 1234a7398723SShteryana Shopova return (snmp_tc2oid(idx->tc, ptr, &(object->val.var))); 1235a7398723SShteryana Shopova default: 1236a7398723SShteryana Shopova /* NOTREACHED */ 1237a7398723SShteryana Shopova break; 1238a7398723SShteryana Shopova } 1239a7398723SShteryana Shopova 1240a7398723SShteryana Shopova return (NULL); 1241a7398723SShteryana Shopova } 1242a7398723SShteryana Shopova 1243a7398723SShteryana Shopova char * 1244a7398723SShteryana Shopova snmp_parse_index(struct snmp_toolinfo *snmptoolctx, char *str, 1245a7398723SShteryana Shopova struct snmp_object *object) 1246a7398723SShteryana Shopova { 1247a7398723SShteryana Shopova char *ptr; 1248a7398723SShteryana Shopova struct index *temp; 1249a7398723SShteryana Shopova 1250a7398723SShteryana Shopova if (object->info->table_idx == NULL) 1251a7398723SShteryana Shopova return (NULL); 1252a7398723SShteryana Shopova 1253a7398723SShteryana Shopova ptr = NULL; 1254a7398723SShteryana Shopova STAILQ_FOREACH(temp, &(OBJECT_IDX_LIST(object)), link) { 1255a7398723SShteryana Shopova if ((ptr = snmp_parse_subindex(snmptoolctx, str, temp, object)) 1256a7398723SShteryana Shopova == NULL) 1257a7398723SShteryana Shopova return (NULL); 1258a7398723SShteryana Shopova 1259a7398723SShteryana Shopova if (*ptr != ',' && *ptr != ']') 1260a7398723SShteryana Shopova return (NULL); 1261a7398723SShteryana Shopova str = ptr + 1; 1262a7398723SShteryana Shopova } 1263a7398723SShteryana Shopova 1264a7398723SShteryana Shopova if (ptr == NULL || *ptr != ']') { 1265a7398723SShteryana Shopova warnx("Mismatching index - %s", str); 1266a7398723SShteryana Shopova return (NULL); 1267a7398723SShteryana Shopova } 1268a7398723SShteryana Shopova 1269a7398723SShteryana Shopova return (ptr + 1); 1270a7398723SShteryana Shopova } 1271a7398723SShteryana Shopova 1272a7398723SShteryana Shopova /* 1273a7398723SShteryana Shopova * Fill in the struct asn_oid member of snmp_value with suboids from input. 1274a7398723SShteryana Shopova * If an error occurs - print message on stderr and return (-1). 1275a7398723SShteryana Shopova * If all is ok - return the length of the oid. 1276a7398723SShteryana Shopova */ 1277a7398723SShteryana Shopova int32_t 1278a7398723SShteryana Shopova snmp_parse_numoid(char *argv, struct asn_oid *var) 1279a7398723SShteryana Shopova { 1280a7398723SShteryana Shopova char *endptr, *str; 1281a7398723SShteryana Shopova asn_subid_t suboid; 1282a7398723SShteryana Shopova 1283a7398723SShteryana Shopova str = argv; 1284a7398723SShteryana Shopova 1285a7398723SShteryana Shopova if (*str == '.') 1286a7398723SShteryana Shopova str++; 1287a7398723SShteryana Shopova 1288a7398723SShteryana Shopova do { 1289a7398723SShteryana Shopova if (var->len == ASN_MAXOIDLEN) { 1290a7398723SShteryana Shopova warnx("Oid too long - %u", var->len); 1291a7398723SShteryana Shopova return (-1); 1292a7398723SShteryana Shopova } 1293a7398723SShteryana Shopova 1294a7398723SShteryana Shopova suboid = strtoul(str, &endptr, 10); 1295a7398723SShteryana Shopova if (suboid > ASN_MAXID) { 1296a7398723SShteryana Shopova warnx("Oid too long - %u", var->len); 1297a7398723SShteryana Shopova return (-1); 1298a7398723SShteryana Shopova } 1299a7398723SShteryana Shopova 1300a7398723SShteryana Shopova var->subs[var->len++] = suboid; 1301a7398723SShteryana Shopova str = endptr + 1; 1302a7398723SShteryana Shopova } while ( *endptr == '.'); 1303a7398723SShteryana Shopova 1304a7398723SShteryana Shopova if (*endptr != '\0') { 1305a7398723SShteryana Shopova warnx("Invalid oid string - %s", argv); 1306a7398723SShteryana Shopova return (-1); 1307a7398723SShteryana Shopova } 1308a7398723SShteryana Shopova 1309a7398723SShteryana Shopova return (var->len); 1310a7398723SShteryana Shopova } 1311a7398723SShteryana Shopova 1312a7398723SShteryana Shopova /* Append a length 1 suboid to an asn_oid structure. */ 1313a7398723SShteryana Shopova int32_t 1314a7398723SShteryana Shopova snmp_suboid_append(struct asn_oid *var, asn_subid_t suboid) 1315a7398723SShteryana Shopova { 1316a7398723SShteryana Shopova if (var == NULL) 1317a7398723SShteryana Shopova return (-1); 1318a7398723SShteryana Shopova 1319a7398723SShteryana Shopova if (var->len >= ASN_MAXOIDLEN) { 1320a7398723SShteryana Shopova warnx("Oid too long - %u", var->len); 1321a7398723SShteryana Shopova return (-1); 1322a7398723SShteryana Shopova } 1323a7398723SShteryana Shopova 1324a7398723SShteryana Shopova var->subs[var->len++] = suboid; 1325a7398723SShteryana Shopova 1326a7398723SShteryana Shopova return (1); 1327a7398723SShteryana Shopova } 1328a7398723SShteryana Shopova 1329a7398723SShteryana Shopova /* Pop the last suboid from an asn_oid structure. */ 1330a7398723SShteryana Shopova int32_t 1331a7398723SShteryana Shopova snmp_suboid_pop(struct asn_oid *var) 1332a7398723SShteryana Shopova { 1333a7398723SShteryana Shopova asn_subid_t suboid; 1334a7398723SShteryana Shopova 1335a7398723SShteryana Shopova if (var == NULL) 1336a7398723SShteryana Shopova return (-1); 1337a7398723SShteryana Shopova 1338a7398723SShteryana Shopova if (var->len < 1) 1339a7398723SShteryana Shopova return (-1); 1340a7398723SShteryana Shopova 1341a7398723SShteryana Shopova suboid = var->subs[--(var->len)]; 1342a7398723SShteryana Shopova var->subs[var->len] = 0; 1343a7398723SShteryana Shopova 1344a7398723SShteryana Shopova return (suboid); 1345a7398723SShteryana Shopova } 1346a7398723SShteryana Shopova 1347a7398723SShteryana Shopova /* 1348a7398723SShteryana Shopova * Parse the command-line provided string into an OID - alocate memory for a new 1349a7398723SShteryana Shopova * snmp object, fill in its fields and insert it in the object list. A 1350a7398723SShteryana Shopova * (snmp_verify_inoid_f) function must be provided to validate the input string. 1351a7398723SShteryana Shopova */ 1352a7398723SShteryana Shopova int32_t 1353a7398723SShteryana Shopova snmp_object_add(struct snmp_toolinfo *snmptoolctx, snmp_verify_inoid_f func, 1354a7398723SShteryana Shopova char *string) 1355a7398723SShteryana Shopova { 1356a7398723SShteryana Shopova struct snmp_object *obj; 1357a7398723SShteryana Shopova 1358a7398723SShteryana Shopova if (snmptoolctx == NULL) 1359a7398723SShteryana Shopova return (-1); 1360a7398723SShteryana Shopova 1361a7398723SShteryana Shopova /* XXX-BZ does that chack make sense? */ 1362a7398723SShteryana Shopova if (snmptoolctx->objects >= SNMP_MAX_BINDINGS) { 1363a7398723SShteryana Shopova warnx("Too many bindings in PDU - %u", snmptoolctx->objects + 1); 1364a7398723SShteryana Shopova return (-1); 1365a7398723SShteryana Shopova } 1366a7398723SShteryana Shopova 1367031987d9SEnji Cooper if ((obj = calloc(1, sizeof(struct snmp_object))) == NULL) { 1368a7398723SShteryana Shopova syslog(LOG_ERR, "malloc() failed: %s", strerror(errno)); 1369a7398723SShteryana Shopova return (-1); 1370a7398723SShteryana Shopova } 1371a7398723SShteryana Shopova 1372a7398723SShteryana Shopova if (func(snmptoolctx, obj, string) < 0) { 1373a7398723SShteryana Shopova warnx("Invalid OID - %s", string); 1374a7398723SShteryana Shopova free(obj); 1375a7398723SShteryana Shopova return (-1); 1376a7398723SShteryana Shopova } 1377a7398723SShteryana Shopova 1378a7398723SShteryana Shopova snmptoolctx->objects++; 1379a7398723SShteryana Shopova SLIST_INSERT_HEAD(&snmptoolctx->snmp_objectlist, obj, link); 1380a7398723SShteryana Shopova 1381a7398723SShteryana Shopova return (1); 1382a7398723SShteryana Shopova } 1383a7398723SShteryana Shopova 1384a7398723SShteryana Shopova /* Given an OID, find it in the object list and remove it. */ 1385a7398723SShteryana Shopova int32_t 1386a7398723SShteryana Shopova snmp_object_remove(struct snmp_toolinfo *snmptoolctx, struct asn_oid *oid) 1387a7398723SShteryana Shopova { 1388a7398723SShteryana Shopova struct snmp_object *temp; 1389a7398723SShteryana Shopova 1390a7398723SShteryana Shopova if (SLIST_EMPTY(&snmptoolctx->snmp_objectlist)) { 1391a7398723SShteryana Shopova warnx("Object list already empty"); 1392a7398723SShteryana Shopova return (-1); 1393a7398723SShteryana Shopova } 1394a7398723SShteryana Shopova 1395a7398723SShteryana Shopova 1396a7398723SShteryana Shopova SLIST_FOREACH(temp, &snmptoolctx->snmp_objectlist, link) 1397a7398723SShteryana Shopova if (asn_compare_oid(&(temp->val.var), oid) == 0) 1398a7398723SShteryana Shopova break; 1399a7398723SShteryana Shopova 1400a7398723SShteryana Shopova if (temp == NULL) { 1401a7398723SShteryana Shopova warnx("No such object in list"); 1402a7398723SShteryana Shopova return (-1); 1403a7398723SShteryana Shopova } 1404a7398723SShteryana Shopova 1405a7398723SShteryana Shopova SLIST_REMOVE(&snmptoolctx->snmp_objectlist, temp, snmp_object, link); 1406a7398723SShteryana Shopova if (temp->val.syntax == SNMP_SYNTAX_OCTETSTRING && 1407a7398723SShteryana Shopova temp->val.v.octetstring.octets != NULL) 1408a7398723SShteryana Shopova free(temp->val.v.octetstring.octets); 1409a7398723SShteryana Shopova free(temp); 1410a7398723SShteryana Shopova 1411a7398723SShteryana Shopova return (1); 1412a7398723SShteryana Shopova } 1413a7398723SShteryana Shopova 1414a7398723SShteryana Shopova static void 1415a7398723SShteryana Shopova snmp_object_freeall(struct snmp_toolinfo *snmptoolctx) 1416a7398723SShteryana Shopova { 1417a7398723SShteryana Shopova struct snmp_object *o; 1418a7398723SShteryana Shopova 1419a7398723SShteryana Shopova while ((o = SLIST_FIRST(&snmptoolctx->snmp_objectlist)) != NULL) { 1420a7398723SShteryana Shopova SLIST_REMOVE_HEAD(&snmptoolctx->snmp_objectlist, link); 1421a7398723SShteryana Shopova 1422a7398723SShteryana Shopova if (o->val.syntax == SNMP_SYNTAX_OCTETSTRING && 1423a7398723SShteryana Shopova o->val.v.octetstring.octets != NULL) 1424a7398723SShteryana Shopova free(o->val.v.octetstring.octets); 1425a7398723SShteryana Shopova free(o); 1426a7398723SShteryana Shopova } 1427a7398723SShteryana Shopova } 1428a7398723SShteryana Shopova 1429a7398723SShteryana Shopova /* Do all possible memory release before exit. */ 1430a7398723SShteryana Shopova void 1431a7398723SShteryana Shopova snmp_tool_freeall(struct snmp_toolinfo *snmptoolctx) 1432a7398723SShteryana Shopova { 1433a7398723SShteryana Shopova if (snmp_client.chost != NULL) { 1434a7398723SShteryana Shopova free(snmp_client.chost); 1435a7398723SShteryana Shopova snmp_client.chost = NULL; 1436a7398723SShteryana Shopova } 1437a7398723SShteryana Shopova 1438a7398723SShteryana Shopova if (snmp_client.cport != NULL) { 1439a7398723SShteryana Shopova free(snmp_client.cport); 1440a7398723SShteryana Shopova snmp_client.cport = NULL; 1441a7398723SShteryana Shopova } 1442a7398723SShteryana Shopova 1443a7398723SShteryana Shopova snmp_mapping_free(snmptoolctx); 1444a7398723SShteryana Shopova free_filelist(snmptoolctx); 1445a7398723SShteryana Shopova snmp_object_freeall(snmptoolctx); 1446a7398723SShteryana Shopova 1447a7398723SShteryana Shopova if (snmptoolctx->passwd != NULL) { 1448a7398723SShteryana Shopova free(snmptoolctx->passwd); 1449a7398723SShteryana Shopova snmptoolctx->passwd = NULL; 1450a7398723SShteryana Shopova } 1451a7398723SShteryana Shopova } 1452a7398723SShteryana Shopova 1453a7398723SShteryana Shopova /* 1454a7398723SShteryana Shopova * Fill all variables from the object list into a PDU. (snmp_verify_vbind_f) 1455a7398723SShteryana Shopova * function should check whether the variable is consistent in this PDU 1456a7398723SShteryana Shopova * (e.g do not add non-leaf OIDs to a GET PDU, or OIDs with read access only to 1457a7398723SShteryana Shopova * a SET PDU) - might be NULL though. (snmp_add_vbind_f) function is the 1458a7398723SShteryana Shopova * function actually adds the variable to the PDU and must not be NULL. 1459a7398723SShteryana Shopova */ 1460a7398723SShteryana Shopova int32_t 1461a7398723SShteryana Shopova snmp_pdu_add_bindings(struct snmp_toolinfo *snmptoolctx, 1462a7398723SShteryana Shopova snmp_verify_vbind_f vfunc, snmp_add_vbind_f afunc, 1463a7398723SShteryana Shopova struct snmp_pdu *pdu, int32_t maxcount) 1464a7398723SShteryana Shopova { 1465a7398723SShteryana Shopova int32_t nbindings, abind; 1466a7398723SShteryana Shopova struct snmp_object *obj; 1467a7398723SShteryana Shopova 1468a7398723SShteryana Shopova if (pdu == NULL || afunc == NULL) 1469a7398723SShteryana Shopova return (-1); 1470a7398723SShteryana Shopova 1471a7398723SShteryana Shopova /* Return 0 in case of no more work todo. */ 1472a7398723SShteryana Shopova if (SLIST_EMPTY(&snmptoolctx->snmp_objectlist)) 1473a7398723SShteryana Shopova return (0); 1474a7398723SShteryana Shopova 1475a7398723SShteryana Shopova if (maxcount < 0 || maxcount > SNMP_MAX_BINDINGS) { 1476a7398723SShteryana Shopova warnx("maxcount out of range: <0 || >SNMP_MAX_BINDINGS"); 1477a7398723SShteryana Shopova return (-1); 1478a7398723SShteryana Shopova } 1479a7398723SShteryana Shopova 1480a7398723SShteryana Shopova nbindings = 0; 1481a7398723SShteryana Shopova SLIST_FOREACH(obj, &snmptoolctx->snmp_objectlist, link) { 1482a7398723SShteryana Shopova if ((vfunc != NULL) && (vfunc(snmptoolctx, pdu, obj) < 0)) { 1483a7398723SShteryana Shopova nbindings = -1; 1484a7398723SShteryana Shopova break; 1485a7398723SShteryana Shopova } 1486a7398723SShteryana Shopova if ((abind = afunc(pdu, obj)) < 0) { 1487a7398723SShteryana Shopova nbindings = -1; 1488a7398723SShteryana Shopova break; 1489a7398723SShteryana Shopova } 1490a7398723SShteryana Shopova 1491a7398723SShteryana Shopova if (abind > 0) { 1492a7398723SShteryana Shopova /* Do not put more varbindings than requested. */ 1493a7398723SShteryana Shopova if (++nbindings >= maxcount) 1494a7398723SShteryana Shopova break; 1495a7398723SShteryana Shopova } 1496a7398723SShteryana Shopova } 1497a7398723SShteryana Shopova 1498a7398723SShteryana Shopova return (nbindings); 1499a7398723SShteryana Shopova } 1500a7398723SShteryana Shopova 1501a7398723SShteryana Shopova /* 1502a7398723SShteryana Shopova * Locate an object in the object list and set a corresponding error status. 1503a7398723SShteryana Shopova */ 1504a7398723SShteryana Shopova int32_t 1505a7398723SShteryana Shopova snmp_object_seterror(struct snmp_toolinfo *snmptoolctx, 1506a7398723SShteryana Shopova struct snmp_value *err_value, int32_t error_status) 1507a7398723SShteryana Shopova { 1508a7398723SShteryana Shopova struct snmp_object *obj; 1509a7398723SShteryana Shopova 1510a7398723SShteryana Shopova if (SLIST_EMPTY(&snmptoolctx->snmp_objectlist) || err_value == NULL) 1511a7398723SShteryana Shopova return (-1); 1512a7398723SShteryana Shopova 1513a7398723SShteryana Shopova SLIST_FOREACH(obj, &snmptoolctx->snmp_objectlist, link) 1514a7398723SShteryana Shopova if (asn_compare_oid(&(err_value->var), &(obj->val.var)) == 0) { 1515a7398723SShteryana Shopova obj->error = error_status; 1516a7398723SShteryana Shopova return (1); 1517a7398723SShteryana Shopova } 1518a7398723SShteryana Shopova 1519a7398723SShteryana Shopova return (0); 1520a7398723SShteryana Shopova } 1521a7398723SShteryana Shopova 1522a7398723SShteryana Shopova /* 15233df5ecacSUlrich Spörlein * Check a PDU received in response to a SNMP_PDU_GET/SNMP_PDU_GETBULK request 1524a7398723SShteryana Shopova * but don't compare syntaxes - when sending a request PDU they must be null. 1525a7398723SShteryana Shopova * This is a (almost) complete copy of snmp_pdu_check() - with matching syntaxes 15263df5ecacSUlrich Spörlein * checks and some other checks skipped. 1527a7398723SShteryana Shopova */ 1528a7398723SShteryana Shopova int32_t 1529a7398723SShteryana Shopova snmp_parse_get_resp(struct snmp_pdu *resp, struct snmp_pdu *req) 1530a7398723SShteryana Shopova { 1531a7398723SShteryana Shopova uint32_t i; 1532a7398723SShteryana Shopova 1533a7398723SShteryana Shopova for (i = 0; i < req->nbindings; i++) { 1534a7398723SShteryana Shopova if (asn_compare_oid(&req->bindings[i].var, 1535a7398723SShteryana Shopova &resp->bindings[i].var) != 0) { 1536a7398723SShteryana Shopova warnx("Bad OID in response"); 1537a7398723SShteryana Shopova return (-1); 1538a7398723SShteryana Shopova } 1539a7398723SShteryana Shopova 1540a7398723SShteryana Shopova if (snmp_client.version != SNMP_V1 && (resp->bindings[i].syntax 1541a7398723SShteryana Shopova == SNMP_SYNTAX_NOSUCHOBJECT || resp->bindings[i].syntax == 1542a7398723SShteryana Shopova SNMP_SYNTAX_NOSUCHINSTANCE)) 1543a7398723SShteryana Shopova return (0); 1544a7398723SShteryana Shopova } 1545a7398723SShteryana Shopova 1546a7398723SShteryana Shopova return (1); 1547a7398723SShteryana Shopova } 1548a7398723SShteryana Shopova 1549a7398723SShteryana Shopova int32_t 1550a7398723SShteryana Shopova snmp_parse_getbulk_resp(struct snmp_pdu *resp, struct snmp_pdu *req) 1551a7398723SShteryana Shopova { 1552a7398723SShteryana Shopova int32_t N, R, M, r; 1553a7398723SShteryana Shopova 1554a7398723SShteryana Shopova if (req->error_status > (int32_t) resp->nbindings) { 1555a7398723SShteryana Shopova warnx("Bad number of bindings in response"); 1556a7398723SShteryana Shopova return (-1); 1557a7398723SShteryana Shopova } 1558a7398723SShteryana Shopova 1559a7398723SShteryana Shopova for (N = 0; N < req->error_status; N++) { 1560a7398723SShteryana Shopova if (asn_is_suboid(&req->bindings[N].var, 1561a7398723SShteryana Shopova &resp->bindings[N].var) == 0) 1562a7398723SShteryana Shopova return (0); 1563a7398723SShteryana Shopova if (resp->bindings[N].syntax == SNMP_SYNTAX_ENDOFMIBVIEW) 1564a7398723SShteryana Shopova return (0); 1565a7398723SShteryana Shopova } 1566a7398723SShteryana Shopova 1567a7398723SShteryana Shopova for (R = N , r = N; R < (int32_t) req->nbindings; R++) { 1568a7398723SShteryana Shopova for (M = 0; M < req->error_index && (r + M) < 1569a7398723SShteryana Shopova (int32_t) resp->nbindings; M++) { 1570a7398723SShteryana Shopova if (asn_is_suboid(&req->bindings[R].var, 1571a7398723SShteryana Shopova &resp->bindings[r + M].var) == 0) 1572a7398723SShteryana Shopova return (0); 1573a7398723SShteryana Shopova 1574a7398723SShteryana Shopova if (resp->bindings[r + M].syntax == 1575a7398723SShteryana Shopova SNMP_SYNTAX_ENDOFMIBVIEW) { 1576a7398723SShteryana Shopova M++; 1577a7398723SShteryana Shopova break; 1578a7398723SShteryana Shopova } 1579a7398723SShteryana Shopova } 1580a7398723SShteryana Shopova r += M; 1581a7398723SShteryana Shopova } 1582a7398723SShteryana Shopova 1583a7398723SShteryana Shopova return (0); 1584a7398723SShteryana Shopova } 1585a7398723SShteryana Shopova 1586a7398723SShteryana Shopova int32_t 1587a7398723SShteryana Shopova snmp_parse_getnext_resp(struct snmp_pdu *resp, struct snmp_pdu *req) 1588a7398723SShteryana Shopova { 1589a7398723SShteryana Shopova uint32_t i; 1590a7398723SShteryana Shopova 1591a7398723SShteryana Shopova for (i = 0; i < req->nbindings; i++) { 1592a7398723SShteryana Shopova if (asn_is_suboid(&req->bindings[i].var, &resp->bindings[i].var) 1593a7398723SShteryana Shopova == 0) 1594a7398723SShteryana Shopova return (0); 1595a7398723SShteryana Shopova 1596a7398723SShteryana Shopova if (resp->version != SNMP_V1 && resp->bindings[i].syntax == 1597a7398723SShteryana Shopova SNMP_SYNTAX_ENDOFMIBVIEW) 1598a7398723SShteryana Shopova return (0); 1599a7398723SShteryana Shopova } 1600a7398723SShteryana Shopova 1601a7398723SShteryana Shopova return (1); 1602a7398723SShteryana Shopova } 1603a7398723SShteryana Shopova 1604a7398723SShteryana Shopova /* 16053df5ecacSUlrich Spörlein * Should be called to check a response to get/getnext/getbulk. 1606a7398723SShteryana Shopova */ 1607a7398723SShteryana Shopova int32_t 1608a7398723SShteryana Shopova snmp_parse_resp(struct snmp_pdu *resp, struct snmp_pdu *req) 1609a7398723SShteryana Shopova { 1610a7398723SShteryana Shopova if (resp == NULL || req == NULL) 1611a7398723SShteryana Shopova return (-2); 1612a7398723SShteryana Shopova 1613a7398723SShteryana Shopova if (resp->version != req->version) { 1614a7398723SShteryana Shopova warnx("Response has wrong version"); 1615a7398723SShteryana Shopova return (-1); 1616a7398723SShteryana Shopova } 1617a7398723SShteryana Shopova 1618a7398723SShteryana Shopova if (resp->error_status == SNMP_ERR_NOSUCHNAME) { 1619a7398723SShteryana Shopova warnx("Error - No Such Name"); 1620a7398723SShteryana Shopova return (0); 1621a7398723SShteryana Shopova } 1622a7398723SShteryana Shopova 1623a7398723SShteryana Shopova if (resp->error_status != SNMP_ERR_NOERROR) { 16243df5ecacSUlrich Spörlein warnx("Error %d in response", resp->error_status); 1625a7398723SShteryana Shopova return (-1); 1626a7398723SShteryana Shopova } 1627a7398723SShteryana Shopova 1628a7398723SShteryana Shopova if (resp->nbindings != req->nbindings && req->type != SNMP_PDU_GETBULK){ 1629a7398723SShteryana Shopova warnx("Bad number of bindings in response"); 1630a7398723SShteryana Shopova return (-1); 1631a7398723SShteryana Shopova } 1632a7398723SShteryana Shopova 1633a7398723SShteryana Shopova switch (req->type) { 1634a7398723SShteryana Shopova case SNMP_PDU_GET: 1635a7398723SShteryana Shopova return (snmp_parse_get_resp(resp,req)); 1636a7398723SShteryana Shopova case SNMP_PDU_GETBULK: 1637a7398723SShteryana Shopova return (snmp_parse_getbulk_resp(resp,req)); 1638a7398723SShteryana Shopova case SNMP_PDU_GETNEXT: 1639a7398723SShteryana Shopova return (snmp_parse_getnext_resp(resp,req)); 1640a7398723SShteryana Shopova default: 1641a7398723SShteryana Shopova /* NOTREACHED */ 1642a7398723SShteryana Shopova break; 1643a7398723SShteryana Shopova } 1644a7398723SShteryana Shopova 1645a7398723SShteryana Shopova return (-2); 1646a7398723SShteryana Shopova } 1647a7398723SShteryana Shopova 1648a7398723SShteryana Shopova static void 1649a7398723SShteryana Shopova snmp_output_octetstring(struct snmp_toolinfo *snmptoolctx, enum snmp_tc tc, 1650a7398723SShteryana Shopova uint32_t len, uint8_t *octets) 1651a7398723SShteryana Shopova { 1652a7398723SShteryana Shopova char *buf; 1653a7398723SShteryana Shopova 1654a7398723SShteryana Shopova if (len == 0 || octets == NULL) 1655a7398723SShteryana Shopova return; 1656a7398723SShteryana Shopova 1657a7398723SShteryana Shopova if (GET_OUTPUT(snmptoolctx) == OUTPUT_VERBOSE) 1658a7398723SShteryana Shopova fprintf(stdout, "%s : ", 1659a7398723SShteryana Shopova syntax_strings[SNMP_SYNTAX_OCTETSTRING].str); 1660a7398723SShteryana Shopova 1661a7398723SShteryana Shopova if ((buf = snmp_oct2tc(tc, len, (char *) octets)) != NULL) { 1662a7398723SShteryana Shopova fprintf(stdout, "%s", buf); 1663a7398723SShteryana Shopova free(buf); 1664a7398723SShteryana Shopova } 1665a7398723SShteryana Shopova } 1666a7398723SShteryana Shopova 1667a7398723SShteryana Shopova static void 1668a7398723SShteryana Shopova snmp_output_octetindex(struct snmp_toolinfo *snmptoolctx, enum snmp_tc tc, 1669a7398723SShteryana Shopova struct asn_oid *oid) 1670a7398723SShteryana Shopova { 1671a7398723SShteryana Shopova uint32_t i; 1672a7398723SShteryana Shopova uint8_t *s; 1673a7398723SShteryana Shopova 1674a7398723SShteryana Shopova if ((s = malloc(oid->subs[0] + 1)) == NULL) 1675a7398723SShteryana Shopova syslog(LOG_ERR, "malloc failed - %s", strerror(errno)); 1676a7398723SShteryana Shopova else { 1677a7398723SShteryana Shopova for (i = 0; i < oid->subs[0]; i++) 1678a7398723SShteryana Shopova s[i] = (u_char) (oid->subs[i + 1]); 1679a7398723SShteryana Shopova 1680a7398723SShteryana Shopova snmp_output_octetstring(snmptoolctx, tc, oid->subs[0], s); 1681a7398723SShteryana Shopova free(s); 1682a7398723SShteryana Shopova } 1683a7398723SShteryana Shopova } 1684a7398723SShteryana Shopova 1685a7398723SShteryana Shopova /* 1686a7398723SShteryana Shopova * Check and output syntax type and value. 1687a7398723SShteryana Shopova */ 1688a7398723SShteryana Shopova static void 1689a7398723SShteryana Shopova snmp_output_oid_value(struct snmp_toolinfo *snmptoolctx, struct asn_oid *oid) 1690a7398723SShteryana Shopova { 1691a7398723SShteryana Shopova char oid_string[ASN_OIDSTRLEN]; 1692a7398723SShteryana Shopova struct snmp_object obj; 1693a7398723SShteryana Shopova 1694a7398723SShteryana Shopova if (GET_OUTPUT(snmptoolctx) == OUTPUT_VERBOSE) 1695a7398723SShteryana Shopova fprintf(stdout, "%s : ", syntax_strings[SNMP_SYNTAX_OID].str); 1696a7398723SShteryana Shopova 1697a7398723SShteryana Shopova if(!ISSET_NUMERIC(snmptoolctx)) { 1698a7398723SShteryana Shopova memset(&obj, 0, sizeof(struct snmp_object)); 1699a7398723SShteryana Shopova asn_append_oid(&(obj.val.var), oid); 1700a7398723SShteryana Shopova 1701a7398723SShteryana Shopova if (snmp_lookup_enumstring(snmptoolctx, &obj) > 0) 1702a7398723SShteryana Shopova fprintf(stdout, "%s" , obj.info->string); 1703a7398723SShteryana Shopova else if (snmp_lookup_oidstring(snmptoolctx, &obj) > 0) 1704a7398723SShteryana Shopova fprintf(stdout, "%s" , obj.info->string); 1705a7398723SShteryana Shopova else if (snmp_lookup_nodestring(snmptoolctx, &obj) > 0) 1706a7398723SShteryana Shopova fprintf(stdout, "%s" , obj.info->string); 1707a7398723SShteryana Shopova else { 1708a7398723SShteryana Shopova (void) asn_oid2str_r(oid, oid_string); 1709a7398723SShteryana Shopova fprintf(stdout, "%s", oid_string); 1710a7398723SShteryana Shopova } 1711a7398723SShteryana Shopova } else { 1712a7398723SShteryana Shopova (void) asn_oid2str_r(oid, oid_string); 1713a7398723SShteryana Shopova fprintf(stdout, "%s", oid_string); 1714a7398723SShteryana Shopova } 1715a7398723SShteryana Shopova } 1716a7398723SShteryana Shopova 1717a7398723SShteryana Shopova static void 1718a7398723SShteryana Shopova snmp_output_int(struct snmp_toolinfo *snmptoolctx, struct enum_pairs *enums, 1719a7398723SShteryana Shopova int32_t int_val) 1720a7398723SShteryana Shopova { 1721a7398723SShteryana Shopova char *string; 1722a7398723SShteryana Shopova 1723a7398723SShteryana Shopova if (GET_OUTPUT(snmptoolctx) == OUTPUT_VERBOSE) 1724a7398723SShteryana Shopova fprintf(stdout, "%s : ", 1725a7398723SShteryana Shopova syntax_strings[SNMP_SYNTAX_INTEGER].str); 1726a7398723SShteryana Shopova 1727a7398723SShteryana Shopova if (enums != NULL && (string = enum_string_lookup(enums, int_val)) 1728a7398723SShteryana Shopova != NULL) 1729a7398723SShteryana Shopova fprintf(stdout, "%s", string); 1730a7398723SShteryana Shopova else 1731a7398723SShteryana Shopova fprintf(stdout, "%d", int_val); 1732a7398723SShteryana Shopova } 1733a7398723SShteryana Shopova 1734a7398723SShteryana Shopova static void 1735a7398723SShteryana Shopova snmp_output_ipaddress(struct snmp_toolinfo *snmptoolctx, uint8_t *ip) 1736a7398723SShteryana Shopova { 1737a7398723SShteryana Shopova if (GET_OUTPUT(snmptoolctx) == OUTPUT_VERBOSE) 1738a7398723SShteryana Shopova fprintf(stdout, "%s : ", 1739a7398723SShteryana Shopova syntax_strings[SNMP_SYNTAX_IPADDRESS].str); 1740a7398723SShteryana Shopova 1741a7398723SShteryana Shopova fprintf(stdout, "%u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3]); 1742a7398723SShteryana Shopova } 1743a7398723SShteryana Shopova 1744a7398723SShteryana Shopova static void 1745a7398723SShteryana Shopova snmp_output_counter(struct snmp_toolinfo *snmptoolctx, uint32_t counter) 1746a7398723SShteryana Shopova { 1747a7398723SShteryana Shopova if (GET_OUTPUT(snmptoolctx) == OUTPUT_VERBOSE) 1748a7398723SShteryana Shopova fprintf(stdout, "%s : ", 1749a7398723SShteryana Shopova syntax_strings[SNMP_SYNTAX_COUNTER].str); 1750a7398723SShteryana Shopova 1751a7398723SShteryana Shopova fprintf(stdout, "%u", counter); 1752a7398723SShteryana Shopova } 1753a7398723SShteryana Shopova 1754a7398723SShteryana Shopova static void 1755a7398723SShteryana Shopova snmp_output_gauge(struct snmp_toolinfo *snmptoolctx, uint32_t gauge) 1756a7398723SShteryana Shopova { 1757a7398723SShteryana Shopova if (GET_OUTPUT(snmptoolctx) == OUTPUT_VERBOSE) 1758a7398723SShteryana Shopova fprintf(stdout, "%s : ", syntax_strings[SNMP_SYNTAX_GAUGE].str); 1759a7398723SShteryana Shopova 1760a7398723SShteryana Shopova fprintf(stdout, "%u", gauge); 1761a7398723SShteryana Shopova } 1762a7398723SShteryana Shopova 1763a7398723SShteryana Shopova static void 1764a7398723SShteryana Shopova snmp_output_ticks(struct snmp_toolinfo *snmptoolctx, uint32_t ticks) 1765a7398723SShteryana Shopova { 1766a7398723SShteryana Shopova if (GET_OUTPUT(snmptoolctx) == OUTPUT_VERBOSE) 1767a7398723SShteryana Shopova fprintf(stdout, "%s : ", 1768a7398723SShteryana Shopova syntax_strings[SNMP_SYNTAX_TIMETICKS].str); 1769a7398723SShteryana Shopova 1770a7398723SShteryana Shopova fprintf(stdout, "%u", ticks); 1771a7398723SShteryana Shopova } 1772a7398723SShteryana Shopova 1773a7398723SShteryana Shopova static void 1774a7398723SShteryana Shopova snmp_output_counter64(struct snmp_toolinfo *snmptoolctx, uint64_t counter64) 1775a7398723SShteryana Shopova { 1776a7398723SShteryana Shopova if (GET_OUTPUT(snmptoolctx) == OUTPUT_VERBOSE) 1777a7398723SShteryana Shopova fprintf(stdout, "%s : ", 1778a7398723SShteryana Shopova syntax_strings[SNMP_SYNTAX_COUNTER64].str); 1779a7398723SShteryana Shopova 1780a7398723SShteryana Shopova fprintf(stdout,"%ju", counter64); 1781a7398723SShteryana Shopova } 1782a7398723SShteryana Shopova 1783a7398723SShteryana Shopova int32_t 1784a7398723SShteryana Shopova snmp_output_numval(struct snmp_toolinfo *snmptoolctx, struct snmp_value *val, 1785a7398723SShteryana Shopova struct snmp_oid2str *entry) 1786a7398723SShteryana Shopova { 1787a7398723SShteryana Shopova if (val == NULL) 1788a7398723SShteryana Shopova return (-1); 1789a7398723SShteryana Shopova 1790a7398723SShteryana Shopova if (GET_OUTPUT(snmptoolctx) != OUTPUT_QUIET) 1791a7398723SShteryana Shopova fprintf(stdout, " = "); 1792a7398723SShteryana Shopova 1793a7398723SShteryana Shopova switch (val->syntax) { 1794a7398723SShteryana Shopova case SNMP_SYNTAX_INTEGER: 1795a7398723SShteryana Shopova if (entry != NULL) 1796a7398723SShteryana Shopova snmp_output_int(snmptoolctx, entry->snmp_enum, 1797a7398723SShteryana Shopova val->v.integer); 1798a7398723SShteryana Shopova else 1799a7398723SShteryana Shopova snmp_output_int(snmptoolctx, NULL, val->v.integer); 1800a7398723SShteryana Shopova break; 1801a7398723SShteryana Shopova 1802a7398723SShteryana Shopova case SNMP_SYNTAX_OCTETSTRING: 1803a7398723SShteryana Shopova if (entry != NULL) 1804a7398723SShteryana Shopova snmp_output_octetstring(snmptoolctx, entry->tc, 1805a7398723SShteryana Shopova val->v.octetstring.len, val->v.octetstring.octets); 1806a7398723SShteryana Shopova else 1807a7398723SShteryana Shopova snmp_output_octetstring(snmptoolctx, SNMP_STRING, 1808a7398723SShteryana Shopova val->v.octetstring.len, val->v.octetstring.octets); 1809a7398723SShteryana Shopova break; 1810a7398723SShteryana Shopova 1811a7398723SShteryana Shopova case SNMP_SYNTAX_OID: 1812a7398723SShteryana Shopova snmp_output_oid_value(snmptoolctx, &(val->v.oid)); 1813a7398723SShteryana Shopova break; 1814a7398723SShteryana Shopova 1815a7398723SShteryana Shopova case SNMP_SYNTAX_IPADDRESS: 1816a7398723SShteryana Shopova snmp_output_ipaddress(snmptoolctx, val->v.ipaddress); 1817a7398723SShteryana Shopova break; 1818a7398723SShteryana Shopova 1819a7398723SShteryana Shopova case SNMP_SYNTAX_COUNTER: 1820a7398723SShteryana Shopova snmp_output_counter(snmptoolctx, val->v.uint32); 1821a7398723SShteryana Shopova break; 1822a7398723SShteryana Shopova 1823a7398723SShteryana Shopova case SNMP_SYNTAX_GAUGE: 1824a7398723SShteryana Shopova snmp_output_gauge(snmptoolctx, val->v.uint32); 1825a7398723SShteryana Shopova break; 1826a7398723SShteryana Shopova 1827a7398723SShteryana Shopova case SNMP_SYNTAX_TIMETICKS: 1828a7398723SShteryana Shopova snmp_output_ticks(snmptoolctx, val->v.uint32); 1829a7398723SShteryana Shopova break; 1830a7398723SShteryana Shopova 1831a7398723SShteryana Shopova case SNMP_SYNTAX_COUNTER64: 1832a7398723SShteryana Shopova snmp_output_counter64(snmptoolctx, val->v.counter64); 1833a7398723SShteryana Shopova break; 1834a7398723SShteryana Shopova 1835a7398723SShteryana Shopova case SNMP_SYNTAX_NOSUCHOBJECT: 1836a7398723SShteryana Shopova fprintf(stdout, "No Such Object\n"); 1837a7398723SShteryana Shopova return (val->syntax); 1838a7398723SShteryana Shopova 1839a7398723SShteryana Shopova case SNMP_SYNTAX_NOSUCHINSTANCE: 1840a7398723SShteryana Shopova fprintf(stdout, "No Such Instance\n"); 1841a7398723SShteryana Shopova return (val->syntax); 1842a7398723SShteryana Shopova 1843a7398723SShteryana Shopova case SNMP_SYNTAX_ENDOFMIBVIEW: 1844a7398723SShteryana Shopova fprintf(stdout, "End of Mib View\n"); 1845a7398723SShteryana Shopova return (val->syntax); 1846a7398723SShteryana Shopova 1847a7398723SShteryana Shopova case SNMP_SYNTAX_NULL: 1848a7398723SShteryana Shopova /* NOTREACHED */ 1849a7398723SShteryana Shopova fprintf(stdout, "agent returned NULL Syntax\n"); 1850a7398723SShteryana Shopova return (val->syntax); 1851a7398723SShteryana Shopova 1852a7398723SShteryana Shopova default: 1853a7398723SShteryana Shopova /* NOTREACHED - If here - then all went completely wrong. */ 1854a7398723SShteryana Shopova fprintf(stdout, "agent returned unknown syntax\n"); 1855a7398723SShteryana Shopova return (-1); 1856a7398723SShteryana Shopova } 1857a7398723SShteryana Shopova 1858a7398723SShteryana Shopova fprintf(stdout, "\n"); 1859a7398723SShteryana Shopova 1860a7398723SShteryana Shopova return (0); 1861a7398723SShteryana Shopova } 1862a7398723SShteryana Shopova 1863a7398723SShteryana Shopova static int32_t 1864a7398723SShteryana Shopova snmp_fill_object(struct snmp_toolinfo *snmptoolctx, struct snmp_object *obj, 1865a7398723SShteryana Shopova struct snmp_value *val) 1866a7398723SShteryana Shopova { 1867a7398723SShteryana Shopova int32_t rc; 1868a7398723SShteryana Shopova asn_subid_t suboid; 1869a7398723SShteryana Shopova 1870a7398723SShteryana Shopova if (obj == NULL || val == NULL) 1871a7398723SShteryana Shopova return (-1); 1872a7398723SShteryana Shopova 1873a7398723SShteryana Shopova if ((suboid = snmp_suboid_pop(&(val->var))) > ASN_MAXID) 1874a7398723SShteryana Shopova return (-1); 1875a7398723SShteryana Shopova 1876a7398723SShteryana Shopova memset(obj, 0, sizeof(struct snmp_object)); 1877a7398723SShteryana Shopova asn_append_oid(&(obj->val.var), &(val->var)); 1878a7398723SShteryana Shopova obj->val.syntax = val->syntax; 1879a7398723SShteryana Shopova 1880a7398723SShteryana Shopova if (obj->val.syntax > 0) 1881a7398723SShteryana Shopova rc = snmp_lookup_leafstring(snmptoolctx, obj); 1882a7398723SShteryana Shopova else 1883a7398723SShteryana Shopova rc = snmp_lookup_nonleaf_string(snmptoolctx, obj); 1884a7398723SShteryana Shopova 1885a7398723SShteryana Shopova (void) snmp_suboid_append(&(val->var), suboid); 1886a7398723SShteryana Shopova (void) snmp_suboid_append(&(obj->val.var), suboid); 1887a7398723SShteryana Shopova 1888a7398723SShteryana Shopova return (rc); 1889a7398723SShteryana Shopova } 1890a7398723SShteryana Shopova 1891a7398723SShteryana Shopova static int32_t 1892a7398723SShteryana Shopova snmp_output_index(struct snmp_toolinfo *snmptoolctx, struct index *stx, 1893a7398723SShteryana Shopova struct asn_oid *oid) 1894a7398723SShteryana Shopova { 1895a7398723SShteryana Shopova uint8_t ip[4]; 1896a7398723SShteryana Shopova uint32_t bytes = 1; 1897a7398723SShteryana Shopova uint64_t cnt64; 1898a7398723SShteryana Shopova struct asn_oid temp, out; 1899a7398723SShteryana Shopova 1900a7398723SShteryana Shopova if (oid->len < bytes) 1901a7398723SShteryana Shopova return (-1); 1902a7398723SShteryana Shopova 1903a7398723SShteryana Shopova memset(&temp, 0, sizeof(struct asn_oid)); 1904a7398723SShteryana Shopova asn_append_oid(&temp, oid); 1905a7398723SShteryana Shopova 1906a7398723SShteryana Shopova switch (stx->syntax) { 1907a7398723SShteryana Shopova case SNMP_SYNTAX_INTEGER: 1908a7398723SShteryana Shopova snmp_output_int(snmptoolctx, stx->snmp_enum, temp.subs[0]); 1909a7398723SShteryana Shopova break; 1910a7398723SShteryana Shopova 1911a7398723SShteryana Shopova case SNMP_SYNTAX_OCTETSTRING: 1912a7398723SShteryana Shopova if ((temp.subs[0] > temp.len -1 ) || (temp.subs[0] > 1913a7398723SShteryana Shopova ASN_MAXOCTETSTRING)) 1914a7398723SShteryana Shopova return (-1); 1915a7398723SShteryana Shopova snmp_output_octetindex(snmptoolctx, stx->tc, &temp); 1916a7398723SShteryana Shopova bytes += temp.subs[0]; 1917a7398723SShteryana Shopova break; 1918a7398723SShteryana Shopova 1919a7398723SShteryana Shopova case SNMP_SYNTAX_OID: 1920a7398723SShteryana Shopova if ((temp.subs[0] > temp.len -1) || (temp.subs[0] > 1921a7398723SShteryana Shopova ASN_MAXOIDLEN)) 1922a7398723SShteryana Shopova return (-1); 1923a7398723SShteryana Shopova 1924a7398723SShteryana Shopova bytes += temp.subs[0]; 1925a7398723SShteryana Shopova memset(&out, 0, sizeof(struct asn_oid)); 1926a7398723SShteryana Shopova asn_slice_oid(&out, &temp, 1, bytes); 1927a7398723SShteryana Shopova snmp_output_oid_value(snmptoolctx, &out); 1928a7398723SShteryana Shopova break; 1929a7398723SShteryana Shopova 1930a7398723SShteryana Shopova case SNMP_SYNTAX_IPADDRESS: 1931a7398723SShteryana Shopova if (temp.len < 4) 1932a7398723SShteryana Shopova return (-1); 1933a7398723SShteryana Shopova for (bytes = 0; bytes < 4; bytes++) 1934a7398723SShteryana Shopova ip[bytes] = temp.subs[bytes]; 1935a7398723SShteryana Shopova 1936a7398723SShteryana Shopova snmp_output_ipaddress(snmptoolctx, ip); 1937a7398723SShteryana Shopova bytes = 4; 1938a7398723SShteryana Shopova break; 1939a7398723SShteryana Shopova 1940a7398723SShteryana Shopova case SNMP_SYNTAX_COUNTER: 1941a7398723SShteryana Shopova snmp_output_counter(snmptoolctx, temp.subs[0]); 1942a7398723SShteryana Shopova break; 1943a7398723SShteryana Shopova 1944a7398723SShteryana Shopova case SNMP_SYNTAX_GAUGE: 1945a7398723SShteryana Shopova snmp_output_gauge(snmptoolctx, temp.subs[0]); 1946a7398723SShteryana Shopova break; 1947a7398723SShteryana Shopova 1948a7398723SShteryana Shopova case SNMP_SYNTAX_TIMETICKS: 1949a7398723SShteryana Shopova snmp_output_ticks(snmptoolctx, temp.subs[0]); 1950a7398723SShteryana Shopova break; 1951a7398723SShteryana Shopova 1952a7398723SShteryana Shopova case SNMP_SYNTAX_COUNTER64: 1953a7398723SShteryana Shopova if (oid->len < 2) 1954a7398723SShteryana Shopova return (-1); 1955a7398723SShteryana Shopova bytes = 2; 1956a7398723SShteryana Shopova memcpy(&cnt64, temp.subs, bytes); 1957a7398723SShteryana Shopova snmp_output_counter64(snmptoolctx, cnt64); 1958a7398723SShteryana Shopova break; 1959a7398723SShteryana Shopova 1960a7398723SShteryana Shopova default: 1961a7398723SShteryana Shopova return (-1); 1962a7398723SShteryana Shopova } 1963a7398723SShteryana Shopova 1964a7398723SShteryana Shopova return (bytes); 1965a7398723SShteryana Shopova } 1966a7398723SShteryana Shopova 1967a7398723SShteryana Shopova static int32_t 1968a7398723SShteryana Shopova snmp_output_object(struct snmp_toolinfo *snmptoolctx, struct snmp_object *o) 1969a7398723SShteryana Shopova { 1970a7398723SShteryana Shopova int32_t i, first, len; 1971a7398723SShteryana Shopova struct asn_oid oid; 1972a7398723SShteryana Shopova struct index *temp; 1973a7398723SShteryana Shopova 1974a7398723SShteryana Shopova if (ISSET_NUMERIC(snmptoolctx)) 1975a7398723SShteryana Shopova return (-1); 1976a7398723SShteryana Shopova 1977a7398723SShteryana Shopova if (o->info->table_idx == NULL) { 1978a7398723SShteryana Shopova fprintf(stdout,"%s.%d", o->info->string, 1979a7398723SShteryana Shopova o->val.var.subs[o->val.var.len - 1]); 1980a7398723SShteryana Shopova return (1); 1981a7398723SShteryana Shopova } 1982a7398723SShteryana Shopova 1983a7398723SShteryana Shopova fprintf(stdout,"%s[", o->info->string); 1984a7398723SShteryana Shopova memset(&oid, 0, sizeof(struct asn_oid)); 1985a7398723SShteryana Shopova 1986a7398723SShteryana Shopova len = 1; 1987a7398723SShteryana Shopova asn_slice_oid(&oid, &(o->val.var), (o->info->table_idx->var.len + len), 1988a7398723SShteryana Shopova o->val.var.len); 1989a7398723SShteryana Shopova 1990a7398723SShteryana Shopova first = 1; 1991a7398723SShteryana Shopova STAILQ_FOREACH(temp, &(OBJECT_IDX_LIST(o)), link) { 1992a7398723SShteryana Shopova if(first) 1993a7398723SShteryana Shopova first = 0; 1994a7398723SShteryana Shopova else 1995a7398723SShteryana Shopova fprintf(stdout, ", "); 1996a7398723SShteryana Shopova if ((i = snmp_output_index(snmptoolctx, temp, &oid)) < 0) 1997a7398723SShteryana Shopova break; 1998a7398723SShteryana Shopova len += i; 1999a7398723SShteryana Shopova memset(&oid, 0, sizeof(struct asn_oid)); 2000a7398723SShteryana Shopova asn_slice_oid(&oid, &(o->val.var), 2001a7398723SShteryana Shopova (o->info->table_idx->var.len + len), o->val.var.len + 1); 2002a7398723SShteryana Shopova } 2003a7398723SShteryana Shopova 2004a7398723SShteryana Shopova fprintf(stdout,"]"); 2005a7398723SShteryana Shopova return (1); 2006a7398723SShteryana Shopova } 2007a7398723SShteryana Shopova 2008a7398723SShteryana Shopova void 2009a7398723SShteryana Shopova snmp_output_err_resp(struct snmp_toolinfo *snmptoolctx, struct snmp_pdu *pdu) 2010a7398723SShteryana Shopova { 2011a7398723SShteryana Shopova char buf[ASN_OIDSTRLEN]; 2012a7398723SShteryana Shopova struct snmp_object object; 2013a7398723SShteryana Shopova 2014a7398723SShteryana Shopova if (pdu == NULL || (pdu->error_index > (int32_t) pdu->nbindings)) { 2015a7398723SShteryana Shopova fprintf(stdout,"Invalid error index in PDU\n"); 2016a7398723SShteryana Shopova return; 2017a7398723SShteryana Shopova } 2018a7398723SShteryana Shopova 2019a7398723SShteryana Shopova fprintf(stdout, "Agent %s:%s returned error \n", snmp_client.chost, 2020a7398723SShteryana Shopova snmp_client.cport); 2021a7398723SShteryana Shopova 2022a7398723SShteryana Shopova if (!ISSET_NUMERIC(snmptoolctx) && (snmp_fill_object(snmptoolctx, &object, 2023a7398723SShteryana Shopova &(pdu->bindings[pdu->error_index - 1])) > 0)) 2024a7398723SShteryana Shopova snmp_output_object(snmptoolctx, &object); 2025a7398723SShteryana Shopova else { 2026a7398723SShteryana Shopova asn_oid2str_r(&(pdu->bindings[pdu->error_index - 1].var), buf); 2027a7398723SShteryana Shopova fprintf(stdout,"%s", buf); 2028a7398723SShteryana Shopova } 2029a7398723SShteryana Shopova 2030a7398723SShteryana Shopova fprintf(stdout," caused error - "); 2031a7398723SShteryana Shopova if ((pdu->error_status > 0) && (pdu->error_status <= 2032a7398723SShteryana Shopova SNMP_ERR_INCONS_NAME)) 2033a7398723SShteryana Shopova fprintf(stdout, "%s\n", error_strings[pdu->error_status].str); 2034a7398723SShteryana Shopova else 2035a7398723SShteryana Shopova fprintf(stdout,"%s\n", error_strings[SNMP_ERR_UNKNOWN].str); 2036a7398723SShteryana Shopova } 2037a7398723SShteryana Shopova 2038a7398723SShteryana Shopova int32_t 2039b9288caaSShteryana Shopova snmp_output_resp(struct snmp_toolinfo *snmptoolctx, struct snmp_pdu *pdu, 2040b9288caaSShteryana Shopova struct asn_oid *root) 2041a7398723SShteryana Shopova { 2042a7398723SShteryana Shopova int32_t error; 2043a7398723SShteryana Shopova char p[ASN_OIDSTRLEN]; 2044a7398723SShteryana Shopova uint32_t i; 2045a7398723SShteryana Shopova struct snmp_object object; 2046a7398723SShteryana Shopova 2047b9288caaSShteryana Shopova i = error = 0; 2048b9288caaSShteryana Shopova while (i < pdu->nbindings) { 2049b9288caaSShteryana Shopova if (root != NULL && !(asn_is_suboid(root, 2050b9288caaSShteryana Shopova &(pdu->bindings[i].var)))) 2051b9288caaSShteryana Shopova break; 2052b9288caaSShteryana Shopova 2053a7398723SShteryana Shopova if (GET_OUTPUT(snmptoolctx) != OUTPUT_QUIET) { 2054a7398723SShteryana Shopova if (!ISSET_NUMERIC(snmptoolctx) && 2055a7398723SShteryana Shopova (snmp_fill_object(snmptoolctx, &object, 2056a7398723SShteryana Shopova &(pdu->bindings[i])) > 0)) 2057a7398723SShteryana Shopova snmp_output_object(snmptoolctx, &object); 2058a7398723SShteryana Shopova else { 2059a7398723SShteryana Shopova asn_oid2str_r(&(pdu->bindings[i].var), p); 2060a7398723SShteryana Shopova fprintf(stdout, "%s", p); 2061a7398723SShteryana Shopova } 2062a7398723SShteryana Shopova } 2063a7398723SShteryana Shopova error |= snmp_output_numval(snmptoolctx, &(pdu->bindings[i]), object.info); 2064b9288caaSShteryana Shopova i++; 2065a7398723SShteryana Shopova } 2066a7398723SShteryana Shopova 2067b9288caaSShteryana Shopova if (error) 2068b9288caaSShteryana Shopova return (-1); 2069b9288caaSShteryana Shopova 2070b9288caaSShteryana Shopova return (i); 2071a7398723SShteryana Shopova } 2072a7398723SShteryana Shopova 2073a7398723SShteryana Shopova void 2074a7398723SShteryana Shopova snmp_output_engine(void) 2075a7398723SShteryana Shopova { 2076a7398723SShteryana Shopova uint32_t i; 2077a7398723SShteryana Shopova char *cptr, engine[2 * SNMP_ENGINE_ID_SIZ + 2]; 2078a7398723SShteryana Shopova 2079a7398723SShteryana Shopova cptr = engine; 2080a7398723SShteryana Shopova for (i = 0; i < snmp_client.engine.engine_len; i++) 2081a7398723SShteryana Shopova cptr += sprintf(cptr, "%.2x", snmp_client.engine.engine_id[i]); 2082a7398723SShteryana Shopova *cptr++ = '\0'; 2083a7398723SShteryana Shopova 2084a7398723SShteryana Shopova fprintf(stdout, "Engine ID 0x%s\n", engine); 2085a7398723SShteryana Shopova fprintf(stdout, "Boots : %u\t\tTime : %d\n", 2086a7398723SShteryana Shopova snmp_client.engine.engine_boots, 2087a7398723SShteryana Shopova snmp_client.engine.engine_time); 2088a7398723SShteryana Shopova } 2089a7398723SShteryana Shopova 2090a7398723SShteryana Shopova void 2091a7398723SShteryana Shopova snmp_output_keys(void) 2092a7398723SShteryana Shopova { 2093a7398723SShteryana Shopova uint32_t i, keylen = 0; 2094a7398723SShteryana Shopova char *cptr, extkey[2 * SNMP_AUTH_KEY_SIZ + 2]; 2095a7398723SShteryana Shopova 2096a7398723SShteryana Shopova fprintf(stdout, "Localized keys for %s\n", snmp_client.user.sec_name); 2097a7398723SShteryana Shopova if (snmp_client.user.auth_proto == SNMP_AUTH_HMAC_MD5) { 2098a7398723SShteryana Shopova fprintf(stdout, "MD5 : 0x"); 2099a7398723SShteryana Shopova keylen = SNMP_AUTH_HMACMD5_KEY_SIZ; 2100a7398723SShteryana Shopova } else if (snmp_client.user.auth_proto == SNMP_AUTH_HMAC_SHA) { 2101a7398723SShteryana Shopova fprintf(stdout, "SHA : 0x"); 2102a7398723SShteryana Shopova keylen = SNMP_AUTH_HMACSHA_KEY_SIZ; 2103a7398723SShteryana Shopova } 2104a7398723SShteryana Shopova if (snmp_client.user.auth_proto != SNMP_AUTH_NOAUTH) { 2105a7398723SShteryana Shopova cptr = extkey; 2106a7398723SShteryana Shopova for (i = 0; i < keylen; i++) 2107a7398723SShteryana Shopova cptr += sprintf(cptr, "%.2x", 2108a7398723SShteryana Shopova snmp_client.user.auth_key[i]); 2109a7398723SShteryana Shopova *cptr++ = '\0'; 2110a7398723SShteryana Shopova fprintf(stdout, "%s\n", extkey); 2111a7398723SShteryana Shopova } 2112a7398723SShteryana Shopova 2113a7398723SShteryana Shopova if (snmp_client.user.priv_proto == SNMP_PRIV_DES) { 2114a7398723SShteryana Shopova fprintf(stdout, "DES : 0x"); 2115a7398723SShteryana Shopova keylen = SNMP_PRIV_DES_KEY_SIZ; 2116a7398723SShteryana Shopova } else if (snmp_client.user.priv_proto == SNMP_PRIV_AES) { 2117a7398723SShteryana Shopova fprintf(stdout, "AES : 0x"); 2118a7398723SShteryana Shopova keylen = SNMP_PRIV_AES_KEY_SIZ; 2119a7398723SShteryana Shopova } 2120a7398723SShteryana Shopova if (snmp_client.user.priv_proto != SNMP_PRIV_NOPRIV) { 2121a7398723SShteryana Shopova cptr = extkey; 2122a7398723SShteryana Shopova for (i = 0; i < keylen; i++) 2123a7398723SShteryana Shopova cptr += sprintf(cptr, "%.2x", 2124a7398723SShteryana Shopova snmp_client.user.priv_key[i]); 2125a7398723SShteryana Shopova *cptr++ = '\0'; 2126a7398723SShteryana Shopova fprintf(stdout, "%s\n", extkey); 2127a7398723SShteryana Shopova } 2128a7398723SShteryana Shopova } 2129