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