From 1d06320825d2a9e214cc324c2b2e833aba3edf4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?IOhannes=20m=20zm=C3=B6lnig?= Date: Thu, 15 Mar 2007 16:49:24 +0000 Subject: added the snmp-external (this has been lying on my harddisk for ages) svn path=/trunk/externals/iem/snmp/; revision=7492 --- get.c | 240 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 240 insertions(+) create mode 100644 get.c (limited to 'get.c') diff --git a/get.c b/get.c new file mode 100644 index 0000000..ee2c873 --- /dev/null +++ b/get.c @@ -0,0 +1,240 @@ +/****************************************************** + * + * snmp/get - implementation file + * + * copyleft (c) IOhannes m zmölnig + * + * 2006:forum::für::umläute:2006 + * + * institute of electronic music and acoustics (iem) + * + ****************************************************** + * + * license: GNU General Public License v.2 + * + ******************************************************/ + +/* 2402:forum::für::umläute:2006 */ + +#include +#include +#include + +#include "m_pd.h" + +/* ------------------------- snmpget ------------------------------- */ + +static t_class *snmpget_class; + +typedef struct _snmpget +{ + t_object x_obj; + + netsnmp_session*x_session; + + t_outlet*out_data, *out_err; + int x_raw; /* if set, the raw string is output; no interpretation is done */ +} t_snmpget; + +static void snmpget_get(t_snmpget *x, t_symbol *s) +{ + if(NULL!=x->x_session){ + oid name[MAX_OID_LEN]; + size_t name_length=MAX_OID_LEN; + netsnmp_variable_list *vars; + netsnmp_pdu *pdu,*response; + int err=0; + char*symname=s->s_name; + + if(!snmp_parse_oid(symname, name, &name_length)){ + error("snmpget: bad OID %d", name_length); + snmp_perror(symname); + return; + } + pdu = snmp_pdu_create(SNMP_MSG_GET); + snmp_add_null_var(pdu, name, name_length); + err=snmp_synch_response(x->x_session, pdu, &response); + if(STAT_SUCCESS == err){ + if(SNMP_ERR_NOERROR == response->errstat){ + for (vars = response->variables; vars; + vars = vars->next_variable) { + char mybuf[MAXPDSTRING]; + t_binbuf *bbuf = binbuf_new(); + int type=vars->type; + //print_variable(vars->name, vars->name_length, vars); + //print_value(vars->name, vars->name_length, vars); + /* + INTEGER = 2 + Counter32 = 65 + Gauge32 = 66 + + Hex-STRING = 4 + STRING = 4 + + IpAddress = 64 + Network Address: 64 + + OID = 6 + Timeticks = 67 + */ + //post("type: %d", vars->type); + if(0==x->x_raw) { + switch(type) { + case ASN_TIMETICKS: + case ASN_GAUGE: case ASN_COUNTER: + case ASN_INTEGER: + { + long v=(long)(*vars->val.integer); + outlet_float(x->out_data, (t_float)v); + } + break; + /* + case ASN_OCTET_STR: + { + outlet_symbol(x->out_data, gensym(vars->val.string)); + } + break; + */ + default: + snprint_value(mybuf, sizeof(mybuf), vars->name, vars->name_length, vars); + binbuf_text(bbuf, mybuf, strlen(mybuf)); + int ac=binbuf_getnatom(bbuf); + t_atom*av=binbuf_getvec(bbuf); + outlet_list(x->out_data, + gensym("list"), + ac, av); + } + } else { + t_atom atm, *ap; + ap=&atm; + snprint_value(mybuf, sizeof(mybuf), vars->name, vars->name_length, vars); + SETSYMBOL(ap, gensym(mybuf)); + outlet_anything(x->out_data, gensym("raw"), 1, ap); + } + if(bbuf)binbuf_free(bbuf); + } + } + } else { + error("[snmp/get] error while synching"); + } + snmp_free_pdu(response); + } else { + pd_error(x, "[snmp/get] not connected"); + } +} + + + +/* + connect [:] +*/ +static void snmpget_connect(t_snmpget *x, t_symbol *hostport, t_symbol*comm) +{ + if(x->x_session==NULL) { + SOCK_STARTUP; + netsnmp_session session; + + int len=0; + char*cdummy; + + char*peername=0; + int peerport=-1; + + char*community=0; + + if(0!=comm && &s_!=comm) + community=comm->s_name; + + for(cdummy=hostport->s_name; *cdummy!=0 && *cdummy!=':'; cdummy++, len++); + + if(*cdummy==':') { + // there is a port hidden in this string! + peerport=(int)strtol(cdummy+1, (char **)NULL, 10); + } + + peername=(char*)getbytes(sizeof(char)*len+1); + strncpy(peername, hostport->s_name, len); + peername[len]=0; + snmp_sess_init(&session); + + session.version=SNMP_VERSION_1; + session.peername=peername; + + if(peerport>0 && peerport<65536) { + session.remote_port=peerport; + } + + if(0!=community) { + session.community=(unsigned char*)community; + session.community_len=strlen(community); + } + x->x_session = snmp_open(&session); + freebytes(peername, len); + + if(x->x_session==NULL){ + SOCK_CLEANUP; + outlet_float(x->out_err, 0); + return; + } + } else { + pd_error(x, "[snmp/get] already connected"); + } + outlet_float(x->out_err, 1); +} +static void snmpget_dodisconnect(t_snmpget *x) +{ + if(x->x_session){ + snmp_close(x->x_session); + SOCK_CLEANUP; + } + x->x_session=NULL; + outlet_float(x->out_err, 0); +} +static void snmpget_disconnect(t_snmpget *x) { + if(x->x_session) + snmpget_dodisconnect(x); + else + pd_error(x, "[snmp/get] not connected!"); +} + +static void snmpget_raw(t_snmpget *x, t_float f) { + int i=(int)f; + x->x_raw=(i>0); +} + +static void *snmpget_free(t_snmpget *x) +{ + snmpget_disconnect(x); + outlet_free(x->out_err); + outlet_free(x->out_data); +} + +static void *snmpget_new(t_symbol*s, int argc, t_atom*argv) +{ + t_snmpget *x = (t_snmpget *)pd_new(snmpget_class); + + x->out_data=outlet_new(&x->x_obj, 0); + x->out_err=outlet_new(&x->x_obj, &s_float); + + x->x_session=0; + x->x_raw=0; + + return (x); +} + +void snmpget_setup(void) +{ + init_snmp("snmp4pd"); + + snmpget_class = class_new(gensym("snmpget"), (t_newmethod)snmpget_new, + 0, sizeof(t_snmpget), 0, A_GIMME, 0); + class_addmethod(snmpget_class, (t_method)snmpget_get, gensym("get"), A_SYMBOL, 0); + class_addmethod(snmpget_class, (t_method)snmpget_connect, gensym("connect"), A_SYMBOL, A_DEFSYM, 0); + class_addmethod(snmpget_class, (t_method)snmpget_disconnect, gensym("disconnect"), 0); + class_addmethod(snmpget_class, (t_method)snmpget_raw, gensym("raw"), A_FLOAT, 0); +} + +void get_setup(void) +{ + snmpget_setup(); +} -- cgit v1.2.1