// Query takes a URI in RFC 4088 format, does an SNMP query and returns the results. func Query(params *QueryParams) (results *llrb.Tree, err error) { parsed_uri, err := parseURI(params.Uri) if Debug { applog.Debugf("parsed_uri: %s\n\n", parsed_uri) } if err != nil { return nil, err } path := C.GoString((*C.char)(parsed_uri.path)) if Debug { applog.Warningf("number of incoming uris: %d", uriCount(path)) } if err := uriCountMaxed(path, MAX_URI_COUNT); err != nil { return nil, err } vbl, uritype, err := parsePath(params.Uri, parsed_uri) defer uriDelete(parsed_uri) if Debug { applog.Debugf("vbl, uritype: %s, %s", gListOidsString(vbl), uritype) } if err != nil { return nil, err } session, err := newUri(params, parsed_uri) /* causing <undefined symbol: gnet_snmp_taddress_get_short_name> if Debug { applog.Warningf("session: %s\n\n", session) } */ if err != nil { return nil, err } vbl_results, err := querySync(session, vbl, uritype, params.Version) defer vblDelete(vbl_results) if err != nil { return nil, err } return convertResults(params, vbl_results), nil }
// convertResults converts C results to a Go struct. func convertResults(params *QueryParams, out *_Ctype_GList) (results *llrb.Tree) { var out_count int // create or re-use an existing llrb Tree if params.Tree == nil { results = llrb.New(LessOID) } else { results = params.Tree } for { if out == nil { // finished if Debug { applog.Warningf("number of results converted: %d", out_count) } return results } // another result: initialise out_count++ data := (*C.GNetSnmpVarBind)(out.data) oid := gIntArrayOidString(data.oid, data.oid_len) var value Varbinder // convert C values to Go values vbt := VarBindType(data._type) switch vbt { case GNET_SNMP_VARBIND_TYPE_NULL: value = new(VBT_Null) case GNET_SNMP_VARBIND_TYPE_OCTETSTRING: value = VBT_OctetString(union_ui8v_string(data.value, data.value_len)) case GNET_SNMP_VARBIND_TYPE_OBJECTID: guint32_ptr := union_ui32v(data.value) value = VBT_ObjectID("." + gIntArrayOidString(guint32_ptr, data.value_len)) case GNET_SNMP_VARBIND_TYPE_IPADDRESS: value = VBT_IPAddress(union_ui8v_ipaddress(data.value, data.value_len)) case GNET_SNMP_VARBIND_TYPE_INTEGER32: value = VBT_Integer32(union_i32(data.value)) case GNET_SNMP_VARBIND_TYPE_UNSIGNED32: value = VBT_Unsigned32(union_ui32(data.value)) case GNET_SNMP_VARBIND_TYPE_COUNTER32: value = VBT_Counter32(union_ui32(data.value)) case GNET_SNMP_VARBIND_TYPE_TIMETICKS: value = VBT_Timeticks(union_ui32(data.value)) case GNET_SNMP_VARBIND_TYPE_OPAQUE: value = VBT_Opaque(union_ui8v_hexstring(data.value, data.value_len)) case GNET_SNMP_VARBIND_TYPE_COUNTER64: value = VBT_Counter64(union_ui64(data.value)) case GNET_SNMP_VARBIND_TYPE_NOSUCHOBJECT: value = new(VBT_NoSuchObject) case GNET_SNMP_VARBIND_TYPE_NOSUCHINSTANCE: value = new(VBT_NoSuchInstance) case GNET_SNMP_VARBIND_TYPE_ENDOFMIBVIEW: value = new(VBT_EndOfMibView) } result := QueryResult{Oid: oid, Value: value} results.ReplaceOrInsert(result) // move on to next element in list out = out.next } panic(fmt.Sprintf("%s: convertResults(): fell out of for loop", libname())) }