pike.git / lib / modules / Protocols.pmod / SNMP.pmod / protocol.pike

version» Context lines:

pike.git/lib/modules/Protocols.pmod/SNMP.pmod/protocol.pike:10:   //! 1155-7 : v1   //!   //! 1901-4 : v2/community (Bulk ops aren't implemented!)   //!   //! planned:   //! 2742 : agentX   //!   //! 2570 : v3 description   //!    - // $Id: protocol.pike,v 1.13 2004/01/11 00:46:54 nilsson Exp $ + // $Id: protocol.pike,v 1.14 2005/11/26 03:58:55 nilsson Exp $         #include "snmp_globals.h"   #include "snmp_errors.h"      #if 1   // --- ASN.1 hack   class asn1_application_octet_string   {    inherit Standards.ASN1.Types.asn1_octet_string;    constant cls = 1;    constant type_name = "APPLICATION OCTET_STRING";    int tagx;       int get_tag() { return tagx; }       void init(int tagid, string arg) {    ::value = arg;    tagx = tagid;    } -  +    }      class asn1_application_integer   {    inherit Standards.ASN1.Types.asn1_integer;    constant cls = 1;    constant type_name = "APPLICATION INTEGER";    int tagx;       int get_tag() { return tagx; }       void init(int tagid, int arg) {    ::init(arg);    tagx = tagid;    } -  +    }      object|mapping der_decode(object data, mapping types)   {    int raw_tag = data->get_uint(1);    int len;    string contents;       if ( (raw_tag & 0x1f) == 0x1f) -  error("ASN1.Decode: High tag numbers is not supported\n"); +  error("ASN1.Decode: High tag numbers is not supported.\n");       len = data->get_uint(1);    if (len & 0x80)    len = data->get_uint(len & 0x7f);       contents = data->get_fix_string(len);       int tag = raw_tag & 0xdf; // Class and tag bits - //werror(sprintf("DEBx: tag=%O\n",tag)); +        program p = types[tag];       if (raw_tag & 0x20)    { -  /* Constructed encoding */ +  // Constructed encoding       array elements = ({ });    object struct = ADT.struct(contents);       if (!p)    {    while (!struct->is_empty())    elements += ({ der_decode(struct, types) });       return Standards.ASN1.Decode.constructed(tag, contents, elements);
pike.git/lib/modules/Protocols.pmod/SNMP.pmod/protocol.pike:94: Inside #if 1
      object res = p();    // hop: For non-universal classes we provide tag number    if(tag & 0xC0)    res = p(tag & 0x1F, ({}));       res->begin_decode_constructed(contents);       int i;    -  /* Ask object which types it expects for field i, decode it, and -  * record the decoded object */ +  // Ask object which types it expects for field i, decode it, and +  // record the decoded object.    for(i = 0; !struct->is_empty(); i++)    {    res->decode_constructed_element    (i, der_decode(struct,    res->element_types(i, types)));    }    return res->end_decode_constructed(i);    }    else    { -  /* Primitive encoding */ +  // Primitive encoding    return p ? p()->decode_primitive(contents)    : Standards.ASN1.Decode.primitive(tag, contents);    }   }      static mapping snmp_type_proc =    ([ 1 : Standards.ASN1.Types.asn1_boolean,    2 : Standards.ASN1.Types.asn1_integer,    3 : Standards.ASN1.Types.asn1_bit_string,    4 : Standards.ASN1.Types.asn1_octet_string,
pike.git/lib/modules/Protocols.pmod/SNMP.pmod/protocol.pike:206:   //!   //! @param rem_port   //! @param rem_addr   //! remote address and UDP port (optional)   //! @param loc_port   //! @param loc_addr   //! local address and UDP port (optional)   //!   void create(int|void rem_port, string|void rem_addr, int|void loc_port, string|void loc_addr) {    +  werror("%O\n", wait); +     int lport = loc_port;       local_host = (!loc_addr || !sizeof(loc_addr)) ? SNMP_DEFAULT_LOCHOST : loc_addr;    if(stringp(rem_addr) && sizeof(rem_addr)) remote_host = rem_addr;    if(rem_port) remote_port = rem_port;       if (!snmp::bind(lport, local_host)) {    //# error ...    DWRITE("protocol.create: can't bind to the socket.\n");    ok = 0;    if(con_fail)    con_fail(this, @extra_args);    }       if(snmp_errno) -  THROW(({"Failed to bind to SNMP port.\n", backtrace()})); +  ERROR("Failed to bind to SNMP port.\n");    DWRITE("protocol.bind: success!\n");    -  DWRITE(sprintf("protocol.create: local adress:port bound: [%s:%d].\n", local_host, lport)); +  DWRITE("protocol.create: local adress:port bound: [%s:%d].\n", +  local_host, lport);      }         //! return the whole SNMP message in raw format - mapping readmsg() { + mapping readmsg(int|float|void timeout) {    mapping rv;       rv = read();    return rv;   }      //! decode ASN1 data, if garbaged ignore it   mapping decode_asn1_msg(mapping rawd) {       object xdec = snmp_der_decode(rawd->data);    string msgid = (string)xdec->elements[2]->elements[0]->value;    int errno = xdec->elements[2]->elements[1]->value;    mapping msg = ([ "ip":rawd->ip,    "port":rawd->port,    "error-status":errno,    "error-string":snmp_errlist[errno],    "error-index":xdec->elements[2]->elements[2]->value,    "version":xdec->elements[0]->value,    "community":xdec->elements[1]->value,    "op":xdec->elements[2]->get_tag(), -  "attribute":Array.map(xdec->elements[2]->elements[3]->elements, lambda(object duo) { return ([(array(string))(duo->elements[0]->id)*".":duo->elements[1]->value]); } ) +  "attribute":map(xdec->elements[2]->elements[3]->elements, +  lambda(object duo) { +  return ([ +  (array(string))(duo->elements[0]->id)*".":duo->elements[1]->value    ]); -  +  } ) +  ]);       return ([msgid:msg]);   }         //! decode raw pdu message and place in message pool   void to_pool(mapping rawd) {    //: put decoded msg to the pool       msgpool += decode_asn1_msg(rawd);
pike.git/lib/modules/Protocols.pmod/SNMP.pmod/protocol.pike:313:    string rawd;    int msize;       msg = Standards.ASN1.Types.asn1_sequence(({    Standards.ASN1.Types.asn1_integer(snmp_version-1),    Standards.ASN1.Types.asn1_octet_string(snmp_community),    pdu}));       rawd = msg->get_der();    -  DWRITE(sprintf("protocol.writemsg: %O\n", rawd)); +  DWRITE("protocol.writemsg: %O\n", rawd);       msize = send(rem_addr, rem_port, rawd);    return (msize = sizeof(rawd) ? SNMP_SUCCESS : SNMP_SEND_ERROR);   }         private int get_req_id() {    //: returns unicate id       //LOCK
pike.git/lib/modules/Protocols.pmod/SNMP.pmod/protocol.pike:358:   //! request ID   int get_request(array(string) varlist, string|void rem_addr,    int|void rem_port) {    object pdu;    int id = get_req_id(), flg;    array vararr = ({});       foreach(varlist, string varname)    vararr += ({Standards.ASN1.Types.asn1_sequence(    ({Standards.ASN1.Types.asn1_identifier( -  @Array.map(varname/".", lambda(string el){ return (int)el;})), +  @(array(int))(varname/".")),    Standards.ASN1.Types.asn1_integer(1)}) //doesn't sense but req    )});       pdu = Protocols.LDAP.ldap_privates.asn1_context_sequence(0,    ({Standards.ASN1.Types.asn1_integer(id), // request-id    Standards.ASN1.Types.asn1_integer(0), // error-status    Standards.ASN1.Types.asn1_integer(0), // error-index    Standards.ASN1.Types.asn1_sequence(vararr)})    );       // now we have PDU ... -  flg = writemsg(rem_addr||remote_host, rem_port || remote_port || SNMP_DEFAULT_PORT, pdu); +  flg = writemsg(rem_addr||remote_host, +  rem_port || remote_port || SNMP_DEFAULT_PORT, pdu);       return id; -  +    }      object mk_asn1_val(string type, int|string val) {   // returns appropriate ASN.1 value       object rv;       switch(type) {    case "oid": // OID -  rv = Standards.ASN1.Types.asn1_identifier( -  @Array.map(val/".", lambda(string el){ return (int)el;})); +  rv = Standards.ASN1.Types.asn1_identifier( @(array(int))(val/".") );    break;       case "int": // INTEGER    rv = Standards.ASN1.Types.asn1_integer(val);    break;       case "str": // STRING    rv = Standards.ASN1.Types.asn1_octet_string(val);    break;       case "ipaddr": // ipAddress -  rv = asn1_application_octet_string(0,val[..3]); +  rv = asn1_application_octet_string(0, val[..3]);    break;       case "count": // COUNTER -  rv = asn1_application_integer(1,val); +  rv = asn1_application_integer(1, val);    break;       case "gauge": // GAUGE -  rv = asn1_application_integer(2,val); +  rv = asn1_application_integer(2, val);    break;       case "tick": // TICK -  rv = asn1_application_integer(3,val); +  rv = asn1_application_integer(3, val);    break;       case "opaque": // OPAQUE -  rv = asn1_application_octet_string(4,val); +  rv = asn1_application_octet_string(4, val);    break;       case "count64": // COUNTER64 - v2 object -  rv = asn1_application_integer(6,val); +  rv = asn1_application_integer(6, val);    break;       default: // bad type! -  error("Unknown SNMP data type " + type + "."); -  return 0; +  error("Unknown SNMP data type %O.", type);    }       return rv;   }      //!   //! GetResponse-PDU call   //!   //! @param varlist   //! a mapping containing data to return
pike.git/lib/modules/Protocols.pmod/SNMP.pmod/protocol.pike:463:   //! @endarray   //! @endmapping   //! @param origdata   //! original received decoded pdu that this response corresponds to   //! @param errcode   //! error code   //! @param erridx   //! error index   //! @returns   //! request ID - int get_response(mapping varlist, mapping origdata, int|void errcode, int|void erridx) { + int get_response(mapping varlist, mapping origdata, int|void errcode, +  int|void erridx) {    //: GetResponse-PDU low call    object pdu;    int id = indices(origdata)[0], flg;    array vararr = ({});       foreach(indices(varlist), string varname)    if(arrayp(varlist[varname]) || sizeof(varlist[varname]) > 1) {    vararr += ({Standards.ASN1.Types.asn1_sequence(    ({Standards.ASN1.Types.asn1_identifier( -  @Array.map(varname/".", lambda(string el){ return (int)el;})), +  @(array(int))(varname/".")),    mk_asn1_val(varlist[varname][0], varlist[varname][1])})    )});    }       pdu = Protocols.LDAP.ldap_privates.asn1_context_sequence(2,    ({Standards.ASN1.Types.asn1_integer(id), // request-id    Standards.ASN1.Types.asn1_integer(errcode), // error-status    Standards.ASN1.Types.asn1_integer(erridx), // error-index    Standards.ASN1.Types.asn1_sequence(vararr)})    );       // now we have PDU ... -  flg = writemsg(origdata[id]->ip||remote_host, origdata[id]->port || remote_port || SNMP_DEFAULT_PORT, pdu); +  flg = writemsg(origdata[id]->ip||remote_host, +  origdata[id]->port || remote_port || SNMP_DEFAULT_PORT, pdu);       return id; -  +    }         //!   //! GetNextRequest-PDU call   //!   //! @param varlist   //! an array of OIDs to GET   //! @param rem_addr   //! @param rem_port
pike.git/lib/modules/Protocols.pmod/SNMP.pmod/protocol.pike:513:   int get_nextrequest(array(string) varlist, string|void rem_addr,    int|void rem_port) {    //: GetNextRequest-PDU low call    object pdu;    int id = get_req_id(), flg;    array vararr = ({});       foreach(varlist, string varname)    vararr += ({Standards.ASN1.Types.asn1_sequence(    ({Standards.ASN1.Types.asn1_identifier( -  @Array.map(varname/".", lambda(string el){ return (int)el; })), +  @(array(int))(varname/".")),    Standards.ASN1.Types.asn1_integer(1)}) //doesn't sense but req    )});       pdu = Protocols.LDAP.ldap_privates.asn1_context_sequence(1,    ({Standards.ASN1.Types.asn1_integer(id), // request-id    Standards.ASN1.Types.asn1_integer(0), // error-status    Standards.ASN1.Types.asn1_integer(0), // error-index    Standards.ASN1.Types.asn1_sequence(vararr)})    );       // now we have PDU ... -  flg = writemsg(rem_addr||remote_host, rem_port || remote_port || SNMP_DEFAULT_PORT, pdu); +  flg = writemsg(rem_addr||remote_host, +  rem_port || remote_port || SNMP_DEFAULT_PORT, pdu);       return id; -  +    }      //!   //! SetRequest-PDU call   //!   //! @param varlist   //! a mapping of OIDs to SET   //! @mapping   //! @member array oid1   //! @array
pike.git/lib/modules/Protocols.pmod/SNMP.pmod/protocol.pike:582:   int set_request(mapping varlist, string|void rem_addr,    int|void rem_port) {    //: SetRequest-PDU low call    object pdu;    int id = get_req_id(), flg;    array vararr = ({});       foreach(indices(varlist), string varname)    vararr += ({Standards.ASN1.Types.asn1_sequence(    ({Standards.ASN1.Types.asn1_identifier( -  @Array.map(varname/".", lambda(string el){ return (int)el; })), +  @(array(int))(varname/".")),    mk_asn1_val(varlist[varname][0], varlist[varname][1])})    )});       pdu = Protocols.LDAP.ldap_privates.asn1_context_sequence(3,    ({Standards.ASN1.Types.asn1_integer(id), // request-id    Standards.ASN1.Types.asn1_integer(0), // error-status    Standards.ASN1.Types.asn1_integer(0), // error-index    Standards.ASN1.Types.asn1_sequence(vararr)})    );       // now we have PDU ... -  flg = writemsg(rem_addr||remote_host, rem_port || remote_port || SNMP_DEFAULT_PORT, pdu); +  flg = writemsg(rem_addr||remote_host, +  rem_port || remote_port || SNMP_DEFAULT_PORT, pdu);       return id;   }         //! send an SNMP-v1 trap   //!   //! @param varlist   //! a mapping of OIDs to include in trap   //! @mapping
pike.git/lib/modules/Protocols.pmod/SNMP.pmod/protocol.pike:649:   //! @returns   //! request id   int trap(mapping varlist, string oid, int type, int spectype, int ticks,    string|void locip, string|void remaddr, int|void remport) {    //: Trap-PDU low call    object pdu;    int id = get_req_id(), flg;    array vararr = ({});    string lip = "1234";    - // DWRITE(sprintf("protocols.trap: varlist: %O, oid: %O, type: %O, spectype: %O," - // " ticks: %O, locip: %O, remaddr: %O, remport: %O\n", - // varlist, oid, type, spectype, ticks, locip, remaddr, remport)); +     locip = locip || "0.0.0.0";    if (has_value(locip,":")) // FIXME: Can't handle IPv6    locip = "0.0.0.0";    if (sizeof(locip/".") != 4)    locip = "0.0.0.0"; //FIXME: what for hell I want to do with such ugly value? -  //sscanf(locip, "%d.%d.%d.%d", @lip); +     sscanf(locip, "%d.%d.%d.%d", lip[0], lip[1], lip[2], lip[3]);       foreach(indices(varlist), string varname)    vararr += ({Standards.ASN1.Types.asn1_sequence(    ({Standards.ASN1.Types.asn1_identifier( -  @Array.map(varname/".", lambda(string el){ return (int)el; })), +  @(array(int))(varname/".")),    mk_asn1_val(varlist[varname][0], varlist[varname][1])})    )});    pdu = Protocols.LDAP.ldap_privates.asn1_context_sequence(4,    ({ -  mk_asn1_val("oid", oid), // enterprise OID -  mk_asn1_val("ipaddr", lip), // ip address (UGLY!) -  mk_asn1_val("int", type), // type (0 = coldstart, ...) -  mk_asn1_val("int", spectype), // enterprise type -  mk_asn1_val("tick", ticks), // uptime -  Standards.ASN1.Types.asn1_sequence(vararr) // optional vars +  // enterprise OID +  mk_asn1_val("oid", oid), +  +  // ip address (UGLY!) +  mk_asn1_val("ipaddr", lip), +  +  // type (0 = coldstart, ...) +  mk_asn1_val("int", type), +  +  // enterprise type +  mk_asn1_val("int", spectype), +  +  // uptime +  mk_asn1_val("tick", ticks), +  +  // optional vars +  Standards.ASN1.Types.asn1_sequence(vararr)    })       );       // now we have PDU ... -  flg = writemsg(remaddr||remote_host, remport || remote_port || SNMP_DEFAULT_TRAPPORT, pdu); +  flg = writemsg(remaddr||remote_host, +  remport || remote_port || SNMP_DEFAULT_TRAPPORT, pdu);       return id;   }