Exemple #1
0
int
asmp_sess_login(netsnmp_session *session,
                const char *user, const char *passwd)
{
    oid val = 0;
    int status;
    netsnmp_pdu *pdu;
    netsnmp_pdu *response;
    netsnmp_transport *transport;
    struct asmp_connection *asmp;

    transport = snmp_sess_transport(snmp_sess_pointer(session));
    if (transport == NULL || transport->data == NULL)
        return -1;

    asmp = transport->data;

    pdu = snmp_pdu_create(ASMP_LOGIN_REQUEST);
    snmp_add_var(pdu, &val, 1, 's', user   == NULL ? "" : user);
    snmp_add_var(pdu, &val, 1, 's', passwd == NULL ? "" : passwd);
    asmp->user = user == NULL ? "" : strdup(user);

    status = asmp_synch_response(session, pdu, &response);

    return status;
}
Exemple #2
0
static int
_hook_build(netsnmp_session * sp,
            netsnmp_pdu *pdu, u_char * pkt, size_t * len)
{
    int i, k;
    int rc = 0;
    size_t offset     = 0;
    size_t sz_payload = 0;
    netsnmp_variable_list *vp;
    netsnmp_transport *transport;
    struct asmp_connection *asmp;

    transport = snmp_sess_transport(snmp_sess_pointer(sp));
    if (transport == NULL || transport->data == NULL)
        return -1;

    asmp = transport->data;

    memset(pkt, 0, 0x100);

    pkt[offset++] = ASMP_SOH;
    switch (asmp->proto) {
        case ASMP_PROTO_AIDP:
            memcpy(pkt+offset, "AIDP", 4);
            break;

        case ASMP_PROTO_ASMP:
        case ASMP_PROTO_ASMPS:
            memcpy(pkt+offset, "ASMP", 4);
            break;

        default:
            return -1;
    }
    offset += 4;

    /* Fix Request ID by locally stored value */
    pdu->msgid = pdu->reqid = ++asmp->seq;
    if (asmp->seq == 0xffff)
        asmp->seq = 0;
    if (pdu->version == SNMP_VERSION_3) {
        pkt[offset++] = (pdu->msgid >> 8) & 0xff;
        pkt[offset++] =  pdu->msgid & 0xff;
    } else {
Exemple #3
0
static int _invalid_op_and_magic (int op, ns_subagent_magic * smagic)
{
    int invalid = 0;

    if (smagic && (snmp_sess_pointer (smagic->session) == NULL || op == NETSNMP_CALLBACK_OP_TIMED_OUT))
    {
        if (smagic->ovars != NULL)
        {
            snmp_free_varbind (smagic->ovars);
        }
        free (smagic);
        invalid = 1;
    }

    if (op != NETSNMP_CALLBACK_OP_RECEIVED_MESSAGE || smagic == NULL)
        invalid = 1;

    return invalid;
}
Exemple #4
0
int
notifyTable_register_notifications(int major, int minor,
                                   void *serverarg, void *clientarg)
{
    struct targetAddrTable_struct *ptr;
    struct targetParamTable_struct *pptr;
    struct snmpNotifyTable_data *nptr;
    int             confirm, i;
    char            buf[SNMP_MAXBUF_SMALL];
    netsnmp_transport *t = NULL;
    struct agent_add_trap_args *args =
        (struct agent_add_trap_args *) serverarg;
    netsnmp_session *ss;

    if (!args || !(args->ss)) {
        return (0);
    }
    confirm = args->confirm;
    ss = args->ss;

    /*
     * XXX: START move target creation to target code 
     */
    for (i = 0; i < MAX_ENTRIES; i++) {
        sprintf(buf, "internal%d", i);
        if (get_addrForName(buf) == NULL && get_paramEntry(buf) == NULL)
            break;
    }
    if (i == MAX_ENTRIES) {
        snmp_log(LOG_ERR,
                 "Can't register new trap destination: max limit reached: %d",
                 MAX_ENTRIES);
        snmp_sess_close(ss);
        return (0);
    }

    /*
     * address 
     */
    ptr = snmpTargetAddrTable_create();
    ptr->name = strdup(buf);
    t = snmp_sess_transport(snmp_sess_pointer(ss));
    memcpy(ptr->tDomain, t->domain, t->domain_length * sizeof(oid));
    ptr->tDomainLen = t->domain_length;
    ptr->tAddressLen = t->remote_length;
    ptr->tAddress = t->remote;

    ptr->timeout = ss->timeout / 1000;
    ptr->retryCount = ss->retries;
    SNMP_FREE(ptr->tagList);
    ptr->tagList = strdup(ptr->name);
    ptr->params = strdup(ptr->name);
    ptr->storageType = ST_READONLY;
    ptr->rowStatus = RS_ACTIVE;
    ptr->sess = ss;
    DEBUGMSGTL(("trapsess", "adding to trap table\n"));
    snmpTargetAddrTable_add(ptr);

    /*
     * param 
     */
    pptr = snmpTargetParamTable_create();
    pptr->paramName = strdup(buf);
    pptr->mpModel = ss->version;
    if (ss->version == SNMP_VERSION_3) {
        pptr->secModel = ss->securityModel;
        pptr->secLevel = ss->securityLevel;
        pptr->secName = (char *) malloc(ss->securityNameLen + 1);
        memcpy((void *) pptr->secName, (void *) ss->securityName,
               ss->securityNameLen);
        pptr->secName[ss->securityNameLen] = 0;
    } else {
        pptr->secModel = ss->version == SNMP_VERSION_1 ?
            SNMP_SEC_MODEL_SNMPv1 : SNMP_SEC_MODEL_SNMPv2c;
        pptr->secLevel = SNMP_SEC_LEVEL_NOAUTH;
        pptr->secName = NULL;
        if (ss->community && (ss->community_len > 0)) {
            pptr->secName = (char *) malloc(ss->community_len + 1);
            memcpy((void *) pptr->secName, (void *) ss->community,
                   ss->community_len);
            pptr->secName[ss->community_len] = 0;
        }
    }
    pptr->storageType = ST_READONLY;
    pptr->rowStatus = RS_ACTIVE;
    snmpTargetParamTable_add(pptr);
    /*
     * XXX: END move target creation to target code 
     */

    /*
     * notify table 
     */
    nptr = SNMP_MALLOC_STRUCT(snmpNotifyTable_data);
    nptr->snmpNotifyName = strdup(buf);
    nptr->snmpNotifyNameLen = strlen(buf);
    nptr->snmpNotifyTag = strdup(buf);
    nptr->snmpNotifyTagLen = strlen(buf);
    nptr->snmpNotifyType = confirm ?
        SNMPNOTIFYTYPE_INFORM : SNMPNOTIFYTYPE_TRAP;
    nptr->snmpNotifyStorageType = ST_READONLY;
    nptr->snmpNotifyRowStatus = RS_ACTIVE;

    snmpNotifyTable_add(nptr);
    return 0;
}
        /*
         * Handle the response from an AgentX subagent,
         *   merging the answers back into the original query
         */
int
agentx_got_response(int operation,
                    netsnmp_session * session,
                    int reqid, netsnmp_pdu *pdu, void *magic)
{
    netsnmp_delegated_cache *cache = (netsnmp_delegated_cache *) magic;
    int             i, ret;
    netsnmp_request_info *requests, *request;
    netsnmp_variable_list *var;
    netsnmp_session *ax_session;

    cache = netsnmp_handler_check_cache(cache);
    if (!cache) {
        DEBUGMSGTL(("agentx/master", "response too late on session %8p\n",
                    session));
        return 0;
    }
    requests = cache->requests;

    switch (operation) {
    case NETSNMP_CALLBACK_OP_TIMED_OUT:{
            void           *s = snmp_sess_pointer(session);
            DEBUGMSGTL(("agentx/master", "timeout on session %8p\n",
                        session));

            netsnmp_handler_mark_requests_as_delegated(requests,
                                       REQUEST_IS_NOT_DELEGATED);
            netsnmp_set_request_error(cache->reqinfo, requests,
                                      /* XXXWWW: should be index=0 */
                                      SNMP_ERR_GENERR);

            /*
             * This is a bit sledgehammer because the other sessions on this
             * transport may be okay (e.g. some thread in the subagent has
             * wedged, but the others are alright).  OTOH the overwhelming
             * probability is that the whole agent has died somehow.  
             */

            if (s != NULL) {
                netsnmp_transport *t = snmp_sess_transport(s);
                close_agentx_session(session, -1);

                if (t != NULL) {
                    DEBUGMSGTL(("agentx/master", "close transport\n"));
                    t->f_close(t);
                } else {
                    DEBUGMSGTL(("agentx/master", "NULL transport??\n"));
                }
            } else {
                DEBUGMSGTL(("agentx/master", "NULL sess_pointer??\n"));
            }
            ax_session = (netsnmp_session *) cache->localinfo;
            netsnmp_free_agent_snmp_session_by_session(ax_session, NULL);
            netsnmp_free_delegated_cache(cache);
            return 0;
        }

    case NETSNMP_CALLBACK_OP_DISCONNECT:
    case NETSNMP_CALLBACK_OP_SEND_FAILED:
        if (operation == NETSNMP_CALLBACK_OP_DISCONNECT) {
            DEBUGMSGTL(("agentx/master", "disconnect on session %8p\n",
                        session));
        } else {
            DEBUGMSGTL(("agentx/master", "send failed on session %8p\n",
                        session));
        }
        close_agentx_session(session, -1);
        netsnmp_handler_mark_requests_as_delegated(requests,
                                                   REQUEST_IS_NOT_DELEGATED);
        netsnmp_set_request_error(cache->reqinfo, requests,     /* XXXWWW: should be index=0 */
                                  SNMP_ERR_GENERR);
        netsnmp_free_delegated_cache(cache);
        return 0;

    case NETSNMP_CALLBACK_OP_RECEIVED_MESSAGE:
        /*
         * This session is alive 
         */
        CLEAR_SNMP_STRIKE_FLAGS(session->flags);
        break;
    default:
        snmp_log(LOG_ERR, "Unknown operation %d in agentx_got_response\n",
                 operation);
        netsnmp_free_delegated_cache(cache);
        return 0;
    }

    DEBUGMSGTL(("agentx/master", "got response errstat=%ld, (req=0x%x,trans="
                "0x%x,sess=0x%x)\n",
                pdu->errstat, (unsigned)pdu->reqid, (unsigned)pdu->transid,
		(unsigned)pdu->sessid));

    if (pdu->errstat != AGENTX_ERR_NOERROR) {
        /* [RFC 2471 - 7.2.5.2.]
         *
         *   1) For any received AgentX response PDU, if res.error is
         *      not `noError', the SNMP response PDU's error code is
         *      set to this value.  If res.error contains an AgentX
         *      specific value (e.g.  `parseError'), the SNMP response
         *      PDU's error code is set to a value of genErr instead.
         *      Also, the SNMP response PDU's error index is set to
         *      the index of the variable binding corresponding to the
         *      failed VarBind in the subagent's AgentX response PDU.
         *
         *      All other AgentX response PDUs received due to
         *      processing this SNMP request are ignored.  Processing
         *      is complete; the SNMP Response PDU is ready to be sent
         *      (see section 7.2.6, "Sending the SNMP Response-PDU").
         */
        int err;

        DEBUGMSGTL(("agentx/master",
                    "agentx_got_response() error branch\n"));

        switch (pdu->errstat) {
        case AGENTX_ERR_PARSE_FAILED:
        case AGENTX_ERR_REQUEST_DENIED:
        case AGENTX_ERR_PROCESSING_ERROR:
            err = SNMP_ERR_GENERR;
            break;
        default:
            err = pdu->errstat;
        }

        ret = 0;
        for (request = requests, i = 1; request;
             request = request->next, i++) {
            if (i == pdu->errindex) {
                /*
                 * Mark this varbind as the one generating the error.
                 * Note that the AgentX errindex may not match the
                 * position in the original SNMP PDU (request->index)
                 */
                netsnmp_set_request_error(cache->reqinfo, request,
                                          err);
                ret = 1;
            }
            request->delegated = REQUEST_IS_NOT_DELEGATED;
        }
        if (!ret) {
            /*
             * ack, unknown, mark the first one
             */
            netsnmp_set_request_error(cache->reqinfo, requests,
                                      SNMP_ERR_GENERR);
        }
        netsnmp_free_delegated_cache(cache);
        DEBUGMSGTL(("agentx/master", "end error branch\n"));
        return 1;
    } else if (cache->reqinfo->mode == MODE_GET ||
               cache->reqinfo->mode == MODE_GETNEXT ||
               cache->reqinfo->mode == MODE_GETBULK) {
        /*
         * Replace varbinds for data request types, but not SETs.  
         */
        DEBUGMSGTL(("agentx/master",
                    "agentx_got_response() beginning...\n"));
        for (var = pdu->variables, request = requests; request && var;
             request = request->next, var = var->next_variable) {
            /*
             * Otherwise, process successful requests
             */
            DEBUGMSGTL(("agentx/master",
                        "  handle_agentx_response: processing: "));
            DEBUGMSGOID(("agentx/master", var->name, var->name_length));
            DEBUGMSG(("agentx/master", "\n"));
            if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_VERBOSE)) {
                DEBUGMSGTL(("snmp_agent", "    >> "));
                DEBUGMSGVAR(("snmp_agent", var));
                DEBUGMSG(("snmp_agent", "\n"));
            }

            /*
             * update the oid in the original request 
             */
            if (var->type != SNMP_ENDOFMIBVIEW) {
                snmp_set_var_typed_value(request->requestvb, var->type,
                                         var->val.string, var->val_len);
                snmp_set_var_objid(request->requestvb, var->name,
                                   var->name_length);
            }
            request->delegated = REQUEST_IS_NOT_DELEGATED;
        }

        if (request || var) {
            /*
             * ack, this is bad.  The # of varbinds don't match and
             * there is no way to fix the problem 
             */
            snmp_log(LOG_ERR,
                     "response to agentx request illegal.  bailing out.\n");
            netsnmp_set_request_error(cache->reqinfo, requests,
                                      SNMP_ERR_GENERR);
        }

        if (cache->reqinfo->mode == MODE_GETBULK)
            netsnmp_bulk_to_next_fix_requests(requests);
    } else {
        /*
         * mark set requests as handled 
         */
        for (request = requests; request; request = request->next) {
            request->delegated = REQUEST_IS_NOT_DELEGATED;
        }
    }
    DEBUGMSGTL(("agentx/master",
                "handle_agentx_response() finishing...\n"));
    netsnmp_free_delegated_cache(cache);
    return 1;
}
Exemple #6
0
static int
_hook_parse(netsnmp_session * sp, netsnmp_pdu * pdu,
            u_char * pkt, size_t len)
{
    int      i;
    int      rc;
    u_char  *p;
    oid      val;
    int      payload_len;
    netsnmp_transport *transport;
    struct asmp_connection *asmp;

    transport = snmp_sess_transport(snmp_sess_pointer(sp));
    if (transport == NULL || transport->data == NULL)
        return -1;

    asmp = transport->data;

    pdu->msgid   = pdu->reqid = (pkt[5] << 8) | pkt[6];
    pdu->command = pkt[7];

    if (pdu->command == 0x90 || pdu->command == 0x91)
        rc = 1;
    else
        rc = SNMP_ERR_NOERROR;

    p = pkt+12;
    payload_len = ntohl(*((uint32_t *)(pkt+8)));
    while (payload_len > 1) {
        uint16_t vlen;

        if (*p == ASMP_FIELD_TERM)
            break;

        val  = *p;
        vlen = ntohs(*((uint16_t *)(p+1)));

        if (asmp->proto != ASMP_PROTO_AIDP) {
            switch (val) {
            case 1:
                if (pdu->command >= 0x90 && pdu->command <= 0x92)
                    pdu->errstat = ntohs(*((uint16_t *)(p+3)));
                break;

            case 2:
                if (pdu->command >= 0x90 && pdu->command <= 0x92)
                    pdu->errindex = ntohs(*((uint16_t *)(p+3)));
                break;

            case 3:
                if (pdu->command >= 0x90 && pdu->command <= 0x92) {
                    int     nlen;
                    oid    *name = NULL;
                    netsnmp_variable_list *var = NULL;

                    p += 3;
                    if (*p != ASN_OBJECT_ID) {
                        fprintf(stderr, "Wrong VarBind data\n");
                        return rc;
                    }
                    while (vlen > 0) {
                        nlen = (*(p+1) << 8 | *(p+2));

                        switch (*p) {
                        case ASN_OBJECT_ID:
                            name = calloc(1, nlen);
                            //fprintf(stderr, "OID: ");
                            for (p += 3, i=0; i<nlen/sizeof(oid); i++, p += 4) {
                                name[i] = *p     << 24 |
                                          *(p+1) << 16 |
                                          *(p+2) << 8  |
                                          *(p+3);
                                //fprintf(stderr, ".%d", name[i]);
                            }
                            //fprintf(stderr, "\n");
                            /* move pointer back */
                            p -= nlen+3;
#if 0
                            if (pkt[16] == 6 && pkt[21] == 1)
                                 snmp_pdu_add_variable(pdu, name, nlen,
                                                       SNMP_ENDOFMIBVIEW,
                                                       NULL, 0);
#endif
                            if (var == NULL) {
                                /* First OID is name OID */
                                var = snmp_add_null_var(pdu, name, nlen/sizeof(oid));
                            } else {
                                /* Second OID is value OID */
                                var->type = *p;
                                snmp_set_var_value(var, (u_char *)name, nlen);
                            }
                            free(name);
                            break;

                        case ASN_COUNTER:
                        case ASN_TIMETICKS:
                        case ASN_GAUGE:
                        case ASN_INTEGER: {
                                int32_t v;
                                v = ntohl(*((int32_t *)(p+3)));
                                var->type = *p;
                                snmp_set_var_value(var, (u_char *)&v, nlen);
                            }
                            break;

                        case ASN_OCTET_STR:
                            var->type = *p;
                            snmp_set_var_value(var, p+3, nlen);
                            break;

                        case ASN_IPADDRESS:
                            var->type = *p;
                            snmp_set_var_value(var, p+3, nlen);
                            break;

                        case ASN_NULL:
                            var->type = *p;
                            snmp_set_var_value(var, NULL, 0);
                            break;

                        default:
                            fprintf(stderr, "AAA: %d\n", *p);
                            break;
                        }
                        p += nlen+3;
                        vlen -= nlen+3;
                        payload_len -= nlen+3;
                    }
                    pdu->command = SNMP_MSG_RESPONSE;
                    rc = SNMP_ERR_NOERROR;
                }
                break;

            default:
                break;
            }
        } else {
            fprintf(stderr, "Flen: %04x\n", vlen);
            snmp_pdu_add_variable(pdu, &val, 1,
                                  ASN_OCTET_STR,
                                  p+3, vlen);
        }

        p += vlen+3;
        payload_len -= vlen+3;
    }

    return rc;
}