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