/*
 *   AgentX utility routines
 */

#include <net-snmp/net-snmp-config.h>

#include <stdio.h>
#include <errno.h>
#if HAVE_STDLIB_H
#include <stdlib.h>
#endif
#if HAVE_STRING_H
#include <string.h>
#else
#include <strings.h>
#endif
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <sys/types.h>
#if TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
#else
# if HAVE_SYS_TIME_H
#  include <sys/time.h>
# else
#  include <time.h>
# endif
#endif

#if HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif

#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include <net-snmp/agent/agent_index.h>

#include "agentx/protocol.h"
#include "agentx/client.h"
#include "agentx/subagent.h"

        /*
         * AgentX handling utility routines
         *
         * Mostly wrappers round, or re-writes of
         *   the SNMP equivalents
         */

int
agentx_synch_input(int op,
                   netsnmp_session * session,
                   int reqid, netsnmp_pdu *pdu, void *magic)
{
    struct synch_state *state = (struct synch_state *) magic;

    if (!state || reqid != state->reqid) {
        return handle_agentx_packet(op, session, reqid, pdu, magic);
    }

    DEBUGMSGTL(("agentx/subagent", "synching input, op 0x%02x\n", op));
    state->waiting = 0;
    if (op == NETSNMP_CALLBACK_OP_RECEIVED_MESSAGE) {
        if (pdu->command == AGENTX_MSG_RESPONSE) {
            state->pdu = snmp_clone_pdu(pdu);
            state->status = STAT_SUCCESS;
            session->s_snmp_errno = SNMPERR_SUCCESS;

            /*
             * Synchronise sysUpTime with the master agent
             */
            netsnmp_set_agent_uptime(pdu->time);
        }
    } else if (op == NETSNMP_CALLBACK_OP_TIMED_OUT) {
        state->pdu = NULL;
        state->status = STAT_TIMEOUT;
        session->s_snmp_errno = SNMPERR_TIMEOUT;
    } else if (op == NETSNMP_CALLBACK_OP_DISCONNECT) {
        return handle_agentx_packet(op, session, reqid, pdu, magic);
    }

    return 1;
}



int
agentx_synch_response(netsnmp_session * ss, netsnmp_pdu *pdu,
                      netsnmp_pdu **response)
{
    return snmp_synch_response_cb(ss, pdu, response, agentx_synch_input);
}


        /*
         * AgentX PofE convenience functions
         */

int
agentx_open_session(netsnmp_session * ss)
{
    netsnmp_pdu    *pdu, *response;
    extern oid      version_sysoid[];
    extern int      version_sysoid_len;
    u_long 	    timeout;

    DEBUGMSGTL(("agentx/subagent", "opening session \n"));
    if (ss == NULL || !IS_AGENTX_VERSION(ss->version)) {
        return 0;
    }

    pdu = snmp_pdu_create(AGENTX_MSG_OPEN);
    if (pdu == NULL)
        return 0;
    timeout = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID,
                                   NETSNMP_DS_AGENT_AGENTX_TIMEOUT);
    if (timeout < 0) 
    pdu->time = 0;
    else
	/* for master TIMEOUT is usec, but Agentx Open specifies sec */
    	pdu->time = timeout/ONE_SEC;

    snmp_add_var(pdu, version_sysoid, version_sysoid_len,
		 's', "Net-SNMP AgentX sub-agent");

    if (agentx_synch_response(ss, pdu, &response) != STAT_SUCCESS)
        return 0;

    if (!response)
        return 0;

    if (response->errstat != SNMP_ERR_NOERROR) {
        snmp_free_pdu(response);
        return 0;
    }

    ss->sessid = response->sessid;
    snmp_free_pdu(response);

    DEBUGMSGTL(("agentx/subagent", "open \n"));
    return 1;
}

int
agentx_close_session(netsnmp_session * ss, int why)
{
    netsnmp_pdu    *pdu, *response;
    DEBUGMSGTL(("agentx/subagent", "closing session\n"));

    if (ss == NULL || !IS_AGENTX_VERSION(ss->version)) {
        return 0;
    }

    pdu = snmp_pdu_create(AGENTX_MSG_CLOSE);
    if (pdu == NULL)
        return 0;
    pdu->time = 0;
    pdu->errstat = why;
    pdu->sessid = ss->sessid;

    if (agentx_synch_response(ss, pdu, &response) == STAT_SUCCESS)
        snmp_free_pdu(response);
    DEBUGMSGTL(("agentx/subagent", "closed\n"));

    return 1;
}

int
agentx_register(netsnmp_session * ss, oid start[], size_t startlen,
                int priority, int range_subid, oid range_ubound,
                int timeout, u_char flags, const char *contextName)
{
    netsnmp_pdu    *pdu, *response;

    DEBUGMSGTL(("agentx/subagent", "registering: "));
    DEBUGMSGOIDRANGE(("agentx/subagent", start, startlen, range_subid,
                      range_ubound));
    DEBUGMSG(("agentx/subagent", "\n"));

    if (ss == NULL || !IS_AGENTX_VERSION(ss->version)) {
        return 0;
    }

    pdu = snmp_pdu_create(AGENTX_MSG_REGISTER);
    if (pdu == NULL) {
        return 0;
    }
    pdu->time = timeout;
    pdu->priority = priority;
    pdu->sessid = ss->sessid;
    pdu->range_subid = range_subid;
    if (contextName) {
        pdu->flags |= AGENTX_MSG_FLAG_NON_DEFAULT_CONTEXT;
        pdu->community = (u_char *) strdup(contextName);
        pdu->community_len = strlen(contextName);
    }

    if (flags & FULLY_QUALIFIED_INSTANCE) {
        pdu->flags |= AGENTX_MSG_FLAG_INSTANCE_REGISTER;
    }

    if (range_subid) {
        snmp_pdu_add_variable(pdu, start, startlen, ASN_OBJECT_ID,
                              (u_char *) start, startlen * sizeof(oid));
        pdu->variables->val.objid[range_subid - 1] = range_ubound;
    } else {
        snmp_add_null_var(pdu, start, startlen);
    }

    if (agentx_synch_response(ss, pdu, &response) != STAT_SUCCESS) {
        DEBUGMSGTL(("agentx/subagent", "registering failed!\n"));
        return 0;
    }

    if (response->errstat != SNMP_ERR_NOERROR) {
        snmp_log(LOG_ERR,"registering pdu failed: %ld!\n", response->errstat);
        snmp_free_pdu(response);
        return 0;
    }

    snmp_free_pdu(response);
    DEBUGMSGTL(("agentx/subagent", "registered\n"));
    return 1;
}

int
agentx_unregister(netsnmp_session * ss, oid start[], size_t startlen,
                  int priority, int range_subid, oid range_ubound,
                  const char *contextName)
{
    netsnmp_pdu    *pdu, *response;

    if (ss == NULL || !IS_AGENTX_VERSION(ss->version)) {
        return 0;
    }

    DEBUGMSGTL(("agentx/subagent", "unregistering: "));
    DEBUGMSGOIDRANGE(("agentx/subagent", start, startlen, range_subid,
                      range_ubound));
    DEBUGMSG(("agentx/subagent", "\n"));
    pdu = snmp_pdu_create(AGENTX_MSG_UNREGISTER);
    if (pdu == NULL) {
        return 0;
    }
    pdu->time = 0;
    pdu->priority = priority;
    pdu->sessid = ss->sessid;
    pdu->range_subid = range_subid;
    if (contextName) {
        pdu->flags |= AGENTX_MSG_FLAG_NON_DEFAULT_CONTEXT;
        pdu->community = (u_char *) strdup(contextName);
        pdu->community_len = strlen(contextName);
    }

    if (range_subid) {
        snmp_pdu_add_variable(pdu, start, startlen, ASN_OBJECT_ID,
                              (u_char *) start, startlen * sizeof(oid));
        pdu->variables->val.objid[range_subid - 1] = range_ubound;
    } else {
        snmp_add_null_var(pdu, start, startlen);
    }

    if (agentx_synch_response(ss, pdu, &response) != STAT_SUCCESS)
        return 0;

    if (response->errstat != SNMP_ERR_NOERROR) {
        snmp_free_pdu(response);
        return 0;
    }

    snmp_free_pdu(response);
    DEBUGMSGTL(("agentx/subagent", "unregistered\n"));
    return 1;
}

netsnmp_variable_list *
agentx_register_index(netsnmp_session * ss,
                      netsnmp_variable_list * varbind, int flags)
{
    netsnmp_pdu    *pdu, *response;
    netsnmp_variable_list *varbind2;

    if (ss == NULL || !IS_AGENTX_VERSION(ss->version)) {
        return NULL;
    }

    /*
     * Make a copy of the index request varbind
     *    for the AgentX request PDU
     *    (since the pdu structure will be freed)
     */
    varbind2 =
        (netsnmp_variable_list *) malloc(sizeof(netsnmp_variable_list));
    if (varbind2 == NULL)
        return NULL;
    if (snmp_clone_var(varbind, varbind2)) {
        snmp_free_varbind(varbind2);
        return NULL;
    }
    if (varbind2->val.string == NULL)
        varbind2->val.string = varbind2->buf;   /* ensure it points somewhere */

    pdu = snmp_pdu_create(AGENTX_MSG_INDEX_ALLOCATE);
    if (pdu == NULL) {
        snmp_free_varbind(varbind2);
        return NULL;
    }
    pdu->time = 0;
    pdu->sessid = ss->sessid;
    if (flags == ALLOCATE_ANY_INDEX)
        pdu->flags |= AGENTX_MSG_FLAG_ANY_INSTANCE;
    if (flags == ALLOCATE_NEW_INDEX)
        pdu->flags |= AGENTX_MSG_FLAG_NEW_INSTANCE;

    /*
     *  Just send a single index request varbind.
     *  Although the AgentX protocol supports
     *    multiple index allocations in a single
     *    request, the model used in the net-snmp agent
     *    doesn't currently take advantage of this.
     *  I believe this is our prerogative - just as
     *    long as the master side Index request handler
     *    can cope with multiple index requests.
     */
    pdu->variables = varbind2;

    if (agentx_synch_response(ss, pdu, &response) != STAT_SUCCESS)
        return NULL;

    if (response->errstat != SNMP_ERR_NOERROR) {
        snmp_free_pdu(response);
        return NULL;
    }

    /*
     * Unlink the (single) response varbind to return
     *  to the main driving index request routine.
     *
     * This is a memory leak, as nothing will ever
     *  release this varbind.  If this becomes a problem,
     *  we'll need to keep a list of these here, and
     *  free the memory in the "index release" routine.
     * But the master side never frees these either (by
     *  design, since it still needs them), so expecting
     *  the subagent to is discrimination, pure & simple :-)
     */
    varbind2 = response->variables;
    response->variables = NULL;
    snmp_free_pdu(response);
    return varbind2;
}

int
agentx_unregister_index(netsnmp_session * ss,
                        netsnmp_variable_list * varbind)
{
    netsnmp_pdu    *pdu, *response;
    netsnmp_variable_list *varbind2;

    if (ss == NULL || !IS_AGENTX_VERSION(ss->version)) {
        return -1;
    }

    /*
     * Make a copy of the index request varbind
     *    for the AgentX request PDU
     *    (since the pdu structure will be freed)
     */
    varbind2 =
        (netsnmp_variable_list *) malloc(sizeof(netsnmp_variable_list));
    if (varbind2 == NULL)
        return -1;
    if (snmp_clone_var(varbind, varbind2)) {
        snmp_free_varbind(varbind2);
        return -1;
    }

    pdu = snmp_pdu_create(AGENTX_MSG_INDEX_DEALLOCATE);
    if (pdu == NULL) {
        snmp_free_varbind(varbind2);
        return -1;
    }
    pdu->time = 0;
    pdu->sessid = ss->sessid;

    /*
     *  Just send a single index release varbind.
     *      (as above)
     */
    pdu->variables = varbind2;

    if (agentx_synch_response(ss, pdu, &response) != STAT_SUCCESS)
        return -1;

    if (response->errstat != SNMP_ERR_NOERROR) {
        snmp_free_pdu(response);
        return -1;              /* XXX - say why */
    }

    snmp_free_pdu(response);
    return SNMP_ERR_NOERROR;
}

int
agentx_add_agentcaps(netsnmp_session * ss,
                     const oid * agent_cap, size_t agent_caplen,
                     const char *descr)
{
    netsnmp_pdu    *pdu, *response;

    if (ss == NULL || !IS_AGENTX_VERSION(ss->version)) {
        return 0;
    }

    pdu = snmp_pdu_create(AGENTX_MSG_ADD_AGENT_CAPS);
    if (pdu == NULL)
        return 0;
    pdu->time = 0;
    pdu->sessid = ss->sessid;
    snmp_add_var(pdu, agent_cap, agent_caplen, 's', descr);

    if (agentx_synch_response(ss, pdu, &response) != STAT_SUCCESS)
        return 0;

    if (response->errstat != SNMP_ERR_NOERROR) {
        snmp_free_pdu(response);
        return 0;
    }

    snmp_free_pdu(response);
    return 1;
}

int
agentx_remove_agentcaps(netsnmp_session * ss,
                        const oid * agent_cap, size_t agent_caplen)
{
    netsnmp_pdu    *pdu, *response;

    if (ss == NULL || !IS_AGENTX_VERSION(ss->version)) {
        return 0;
    }

    pdu = snmp_pdu_create(AGENTX_MSG_REMOVE_AGENT_CAPS);
    if (pdu == NULL)
        return 0;
    pdu->time = 0;
    pdu->sessid = ss->sessid;
    snmp_add_null_var(pdu, agent_cap, agent_caplen);

    if (agentx_synch_response(ss, pdu, &response) != STAT_SUCCESS)
        return 0;

    if (response->errstat != SNMP_ERR_NOERROR) {
        snmp_free_pdu(response);
        return 0;
    }

    snmp_free_pdu(response);
    return 1;
}

int
agentx_send_ping(netsnmp_session * ss)
{
    netsnmp_pdu    *pdu, *response;

    if (ss == NULL || !IS_AGENTX_VERSION(ss->version)) {
        return 0;
    }

    pdu = snmp_pdu_create(AGENTX_MSG_PING);
    if (pdu == NULL)
        return 0;
    pdu->time = 0;
    pdu->sessid = ss->sessid;

    if (agentx_synch_response(ss, pdu, &response) != STAT_SUCCESS)
        return 0;

    if (response->errstat != SNMP_ERR_NOERROR) {
        snmp_free_pdu(response);
        return 0;
    }

    snmp_free_pdu(response);
    return 1;
}
