diff options
| -rw-r--r-- | common/config-parser.c | 34 | ||||
| -rw-r--r-- | common/config-parser.h | 2 | ||||
| -rw-r--r-- | common/snmp-engine.c | 27 | ||||
| -rw-r--r-- | common/snmp-engine.h | 8 | ||||
| -rw-r--r-- | daemon/config.c | 5 | ||||
| -rw-r--r-- | daemon/poll-engine.c | 10 | ||||
| -rw-r--r-- | daemon/rrdbotd.h | 1 | ||||
| -rw-r--r-- | tools/rrdbot-get.c | 16 | 
8 files changed, 72 insertions, 31 deletions
| diff --git a/common/config-parser.c b/common/config-parser.c index fbb9c70..881838f 100644 --- a/common/config-parser.c +++ b/common/config-parser.c @@ -356,9 +356,24 @@ cfg_parse_dir(const char* dirname, void* data)      return ret;  } +static int +looks_like_port (const char *port) +{ +	if (!port || !*port) +		return 0; + +	while (*port) { +		if (!isdigit(*port)) +			return 0; +		++port; +	} + +	return 1; +} +  const char* -cfg_parse_uri (char *uri, char** scheme, char** host, char** user, -               char** path, char** query) +cfg_parse_uri (char *uri, char** scheme, char** host, char **port, +               char** user, char** path, char** query)  {      char* t; @@ -367,6 +382,7 @@ cfg_parse_uri (char *uri, char** scheme, char** host, char** user,      *user = NULL;      *path = NULL;      *query = NULL; +    *port = NULL;      *scheme = strsep(&uri, ":");      if(uri == NULL || (uri[0] != '/' && uri[1] != '/')) @@ -374,9 +390,10 @@ cfg_parse_uri (char *uri, char** scheme, char** host, char** user,      uri += 2;      *host = strsep(&uri, "/"); + +    /* Parse the community out from the host */      if(*host[0])      { -        /* Parse the community out from the host */          t = strchr(*host, '@');          if(t)          { @@ -386,6 +403,17 @@ cfg_parse_uri (char *uri, char** scheme, char** host, char** user,          }      } +    /* Parse out the port from the uri */ +    if(*host[0]) +    { +        t = strrchr(*host, ':'); +        if(t && looks_like_port(t + 1)) +        { +            *t = 0; +            *port = t + 1; +        } +    } +      if(!*host[0])          return "invalid uri: no host name found"; diff --git a/common/config-parser.h b/common/config-parser.h index c804874..1df5d78 100644 --- a/common/config-parser.h +++ b/common/config-parser.h @@ -51,7 +51,7 @@ int cfg_parse_dir(const char* dirname, void* data);  int cfg_parse_file(const char* filename, void* data, char** memory);  /* A helper for parsing URIs */ -const char* cfg_parse_uri (char *uri, char** scheme, char** host, char** user, char** path, char** query); +const char* cfg_parse_uri (char *uri, char** scheme, char** host, char **port, char** user, char** path, char** query);  /* Parsing snmp, snmp2 snmp2c etc... */  const char* cfg_parse_scheme (const char *input, enum snmp_version *scheme); diff --git a/common/snmp-engine.c b/common/snmp-engine.c index 96fb812..945418e 100644 --- a/common/snmp-engine.c +++ b/common/snmp-engine.c @@ -73,6 +73,7 @@ struct host {  	char key[128];  	char *hostname; +	char *portnum;  	char *community;  	int version; @@ -145,7 +146,7 @@ host_resolve (struct host *host, mstime when)  	log_debug ("resolving host: %s", host->hostname);  	host->last_resolve_try = when;  	host->is_resolving = 0; -	async_resolver_queue (host->hostname, "161", &hints, resolve_cb, host); +	async_resolver_queue (host->hostname, host->portnum, &hints, resolve_cb, host);  }  static int @@ -203,7 +204,8 @@ host_update_interval (struct host *host, mstime interval)  }  static struct host* -host_instance (const char *hostname, const char *community, int version, mstime interval) +host_instance (const char *hostname, const char *portnum, +               const char *community, int version, mstime interval)  {  	struct addrinfo hints, *ai;  	struct host *host; @@ -213,6 +215,9 @@ host_instance (const char *hostname, const char *community, int version, mstime  	ASSERT (hostname);  	initialize = 0; +	if (!portnum) +		portnum = "161"; +  	/*  	 * Build a lookup key. We can only combine requests for the same  	 * host when the version and community match. @@ -230,7 +235,7 @@ host_instance (const char *hostname, const char *community, int version, mstime  		hints.ai_socktype = SOCK_DGRAM;  		hints.ai_flags = AI_NUMERICSERV | AI_NUMERICHOST; -		r = getaddrinfo (hostname, "161", &hints, &ai); +		r = getaddrinfo (hostname, portnum, &hints, &ai);  		/* Ignore error and try to resolve again later */  		if (r == EAI_NONAME || r == EAI_AGAIN || r == EAI_MEMORY) { @@ -281,6 +286,7 @@ host_instance (const char *hostname, const char *community, int version, mstime  		host->version = version;  		host->hostname = strdup (hostname); +		host->portnum = strdup (portnum);  		host->community = strdup (community);  		host->resolve_interval = 0;  		host->last_resolved = 0; @@ -321,8 +327,10 @@ host_cleanup (void)  	for (host = host_list; host; host = next) {  		next = host->next; -	        if (host->hostname) +		if (host->hostname)  			free (host->hostname); +		if (host->portnum) +			free (host->portnum);  		if (host->community)  			free (host->community);  		if (host->prepared) @@ -818,7 +826,8 @@ request_prep_instance (struct host *host, mstime interval, mstime timeout, int r  }  int -snmp_engine_request (const char *hostname, const char *community, int version, +snmp_engine_request (const char *hostname, const char *port, +                     const char *community, int version,                       mstime interval, mstime timeout, int reqtype,                       struct asn_oid *oid, snmp_response func, void *arg)  { @@ -829,7 +838,7 @@ snmp_engine_request (const char *hostname, const char *community, int version,  	ASSERT (func);  	/* Lookup host for request */ -	host = host_instance (hostname, community, version, interval); +	host = host_instance (hostname, port, community, version, interval);  	if (!host)  		return 0; @@ -945,8 +954,8 @@ sync_response (int req, int code, struct snmp_value *value, void *data)  }  int -snmp_engine_sync (const char* host, const char* community, int version, -                  uint64_t interval, uint64_t timeout, int reqtype, +snmp_engine_sync (const char* host, const char *port, const char* community, +                  int version, uint64_t interval, uint64_t timeout, int reqtype,                    struct snmp_value *value)  {  	struct sync_data sync; @@ -958,7 +967,7 @@ snmp_engine_sync (const char* host, const char* community, int version,  	sync.code = 0;  	sync.dest = value; -	sync.id = snmp_engine_request (host, community, version, interval, timeout, +	sync.id = snmp_engine_request (host, port, community, version, interval, timeout,  	                               reqtype, &value->var, sync_response, &sync);  	if (!sync.id) diff --git a/common/snmp-engine.h b/common/snmp-engine.h index 98a45e5..59c733d 100644 --- a/common/snmp-engine.h +++ b/common/snmp-engine.h @@ -8,16 +8,16 @@ typedef void (*snmp_response) (int request, int code, struct snmp_value *value,  void snmp_engine_init (const char *bind_address, int retries); -int  snmp_engine_request (const char* host, const char* community, int version, -                          uint64_t interval, uint64_t timeout, int reqtype, +int  snmp_engine_request (const char* host, const char *port, const char* community, +                          int version, uint64_t interval, uint64_t timeout, int reqtype,                            struct asn_oid *oid, snmp_response func, void *data);  void snmp_engine_cancel (int reqid);  void snmp_engine_flush (void); -int  snmp_engine_sync (const char* host, const char* community, int version, -                       uint64_t interval, uint64_t timeout, int reqtype, +int  snmp_engine_sync (const char* host, const char *port, const char* community, +                       int version, uint64_t interval, uint64_t timeout, int reqtype,                         struct snmp_value *value);  void snmp_engine_stop (void); diff --git a/daemon/config.c b/daemon/config.c index fcc4379..0196c62 100644 --- a/daemon/config.c +++ b/daemon/config.c @@ -242,11 +242,11 @@ parse_item (const char *field, char *uri, config_ctx *ctx)  	enum snmp_version version;  	const char *msg;  	char *copy; -	char *scheme, *host, *user, *path, *query; +	char *scheme, *host, *user, *path, *query, *port;  	/* Parse the SNMP URI */  	copy = strdup (uri); -	msg = cfg_parse_uri (uri, &scheme, &host, &user, &path, &query); +	msg = cfg_parse_uri (uri, &scheme, &host, &port, &user, &path, &query);  	if (msg)  		errx(2, "%s: %s: %s", ctx->confname, msg, copy);  	free (copy); @@ -281,6 +281,7 @@ parse_item (const char *field, char *uri, config_ctx *ctx)  	item->poller = NULL; /* Set later in config_done */  	item->vtype = VALUE_UNSET; +	item->portnum = port ? port : "161";  	/* Parse the hosts, query */  	parse_hosts (item, host, ctx); diff --git a/daemon/poll-engine.c b/daemon/poll-engine.c index e628382..30faf94 100644 --- a/daemon/poll-engine.c +++ b/daemon/poll-engine.c @@ -291,7 +291,7 @@ field_request (rb_item *item)          item->vtype = VALUE_UNSET; -	req = snmp_engine_request (item->hostnames[item->hostindex], item->community, +	req = snmp_engine_request (item->hostnames[item->hostindex], item->portnum, item->community,  	                           item->version, item->poller->interval, item->poller->timeout,  	                           SNMP_PDU_GET, &item->field_oid, field_response, item);  	item->field_request = req; @@ -321,7 +321,7 @@ query_value_request (rb_item *item, asn_subid_t subid)  	log_debug ("query requesting value for table index: %u", subid); -	req = snmp_engine_request (item->hostnames[item->hostindex], item->community, +	req = snmp_engine_request (item->hostnames[item->hostindex], item->portnum, item->community,  	                           item->version, item->poller->interval, item->poller->timeout,  	                           SNMP_PDU_GET, &oid, field_response, item); @@ -434,7 +434,7 @@ query_search_request (rb_item *item)  		log_debug ("query looking for next table index");  	} -	req = snmp_engine_request (item->hostnames[item->hostindex], item->community, +	req = snmp_engine_request (item->hostnames[item->hostindex], item->portnum, item->community,  	                           item->version, item->poller->interval, item->poller->timeout,  	                           SNMP_PDU_GETNEXT, oid, query_next_response, item); @@ -526,7 +526,7 @@ query_pair_request (rb_item *item, asn_subid_t subid)  	oid.subs[oid.len] = subid;  	++oid.len; -	req = snmp_engine_request (item->hostnames[item->hostindex], item->community, +	req = snmp_engine_request (item->hostnames[item->hostindex], item->portnum, item->community,  	                           item->version, item->poller->interval, item->poller->timeout,  	                           SNMP_PDU_GET, &oid, query_match_response, item); @@ -539,7 +539,7 @@ query_pair_request (rb_item *item, asn_subid_t subid)  	oid.subs[oid.len] = subid;  	++oid.len; -	req = snmp_engine_request (item->hostnames[item->hostindex], item->community, +	req = snmp_engine_request (item->hostnames[item->hostindex], item->portnum, item->community,  	                           item->version, item->poller->interval, item->poller->timeout,  	                           SNMP_PDU_GET, &oid, field_response, item); diff --git a/daemon/rrdbotd.h b/daemon/rrdbotd.h index aa19b23..49ec1bb 100644 --- a/daemon/rrdbotd.h +++ b/daemon/rrdbotd.h @@ -76,6 +76,7 @@ typedef struct _rb_item      /* Host names, with alternate hosts */      #define MAX_HOSTNAMES 16      const char* hostnames[MAX_HOSTNAMES]; +    const char* portnum;      int hostindex;      int n_hostnames; diff --git a/tools/rrdbot-get.c b/tools/rrdbot-get.c index a2fd19b..46219d9 100644 --- a/tools/rrdbot-get.c +++ b/tools/rrdbot-get.c @@ -60,7 +60,8 @@ struct context  	struct asn_oid oid_first;           	/* The first OID we've done */  	/* Request data */ -	char host[128];                    	/* The remote host, resolved to an address */ +	char host[128];                    /* The remote host, resolved to an address */ +	char *port;                        /* The remote port to connect to */  	char *community;			/* The community to use */  	int version;				/* protocol version */ @@ -153,12 +154,12 @@ parse_argument (char *uri)  	enum snmp_version version;  	const char* msg;  	char* copy; -	char *user, *host, *scheme, *path, *query; +	char *user, *host, *port, *scheme, *path, *query;  	char *value, *name;  	/* Parse the SNMP URI */  	copy = strdup (uri); -	msg = cfg_parse_uri (uri, &scheme, &host, &user, &path, &query); +	msg = cfg_parse_uri (uri, &scheme, &host, &port, &user, &path, &query);  	if (msg)  		errx (2, "%s: %s", msg, copy);  	free (copy); @@ -168,6 +169,7 @@ parse_argument (char *uri)  	/* Host, community */  	parse_host (host);  	ctx.community = user ? user : "public"; +	ctx.port = port ? port : "161";  	/* Currently we only support SNMP pollers */  	msg = cfg_parse_scheme (scheme, &version); @@ -282,7 +284,7 @@ process_recursive (void)  		memcpy (&value.var, &last, sizeof (value.var)); -		ret = snmp_engine_sync (ctx.host, ctx.community, ctx.version, +		ret = snmp_engine_sync (ctx.host, ctx.port, ctx.community, ctx.version,  		                        0, ctx.timeout, SNMP_PDU_GETNEXT, &value);  		/* Reached the end */ @@ -330,7 +332,7 @@ process_query (void)  	for (;;) {  		/* Do the request */ -		ret = snmp_engine_sync (ctx.host, ctx.community, ctx.version, +		ret = snmp_engine_sync (ctx.host, ctx.port, ctx.community, ctx.version,  		                        0, ctx.timeout, SNMP_PDU_GETNEXT, &value);  		/* Convert these result codes into 'not found' */ @@ -372,7 +374,7 @@ process_query (void)  	value.var.subs[value.var.len] = sub;  	value.var.len++; -	ret = snmp_engine_sync (ctx.host, ctx.community, ctx.version, +	ret = snmp_engine_sync (ctx.host, ctx.port, ctx.community, ctx.version,  	                        0, ctx.timeout, SNMP_PDU_GET, &value);  	if (ret != SNMP_ERR_NOERROR) @@ -390,7 +392,7 @@ process_simple (void)  	memset (&value, 0, sizeof (value));  	memcpy (&value.var, &ctx.request_oid, sizeof (value.var)); -	ret = snmp_engine_sync (ctx.host, ctx.community, ctx.version, +	ret = snmp_engine_sync (ctx.host, ctx.port, ctx.community, ctx.version,  	                        0, ctx.timeout, SNMP_PDU_GET, &value);  	if (ret != SNMP_ERR_NOERROR) | 
