/*
 *  AgentX sub-agent
 */
#include <net-snmp/net-snmp-config.h>

#include <sys/types.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#if TIME_WITH_SYS_TIME
# ifdef WIN32
#  include <sys/timeb.h>
# else
#  include <sys/time.h>
# endif
# include <time.h>
#else
# if HAVE_SYS_TIME_H
#  include <sys/time.h>
# else
#  include <time.h>
# endif
#endif
#if HAVE_WINSOCK_H
#include <winsock.h>
#endif
#if HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#if HAVE_STRING_H
#include <string.h>
#else
#include <strings.h>
#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/library/snmp_assert.h>

#include "snmpd.h"
#include "agentx/protocol.h"
#include "agentx/client.h"
#include "agentx/agentx_config.h"
#include <net-snmp/agent/agent_callbacks.h>
#include <net-snmp/agent/agent_trap.h>
#ifdef USING_MIBII_SYSORTABLE_MODULE
#include "mibII/sysORTable.h"
#endif

#include "subagent.h"

#ifdef USING_AGENTX_SUBAGENT_MODULE

static SNMPCallback subagent_register_ping_alarm;
static SNMPAlarmCallback agentx_reopen_session;
void            agentx_register_callbacks(netsnmp_session * s);
void            agentx_unregister_callbacks(netsnmp_session * ss);
int             handle_subagent_response(int op, netsnmp_session * session,
                                         int reqid, netsnmp_pdu *pdu,
                                         void *magic);
int             handle_subagent_set_response(int op,
                                             netsnmp_session * session,
                                             int reqid, netsnmp_pdu *pdu,
                                             void *magic);
void            subagent_startup_callback(unsigned int clientreg,
                                          void *clientarg);
int             subagent_open_master_session(void);

typedef struct _net_snmpsubagent_magic_s {
    int             original_command;
    netsnmp_session *session;
    netsnmp_variable_list *ovars;
} ns_subagent_magic;

struct agent_netsnmp_set_info {
    int             transID;
    int             mode;
    int             errstat;
    time_t          uptime;
    netsnmp_session *sess;
    netsnmp_variable_list *var_list;

    struct agent_netsnmp_set_info *next;
};

static struct agent_netsnmp_set_info *Sets = NULL;

netsnmp_session *agentx_callback_sess = NULL;
extern int      callback_master_num;
extern netsnmp_session *main_session;   /* from snmp_agent.c */

int
subagent_startup(int majorID, int minorID,
                             void *serverarg, void *clientarg)
{
    DEBUGMSGTL(("agentx/subagent", "connecting to master...\n"));
    /*
     * if a valid ping interval has been defined, call agentx_reopen_session
     * to try to connect to master or setup a ping alarm if it couldn't
     * succeed. if no ping interval was set up, just try to connect once.
     */
    if (netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID,
                           NETSNMP_DS_AGENT_AGENTX_PING_INTERVAL) > 0)
        agentx_reopen_session(0, NULL);
    else {
        subagent_open_master_session();
    }
    return 0;
}

static void
subagent_init_callback_session(void)
{
    if (agentx_callback_sess == NULL) {
        agentx_callback_sess = netsnmp_callback_open(callback_master_num,
                                                     handle_subagent_response,
                                                     NULL, NULL);
        DEBUGMSGTL(("agentx/subagent", "subagent_init sess %p\n",
                    agentx_callback_sess));
    }
}

static int subagent_init_init = 0;
/**
 * init subagent callback (local) session and connect to master agent
 *
 * @returns 0 for success, !0 otherwise
 */
int
subagent_init(void)
{
    int rc = 0;

    DEBUGMSGTL(("agentx/subagent", "initializing....\n"));

    if (++subagent_init_init != 1)
        return 0;

    netsnmp_assert(netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
                                          NETSNMP_DS_AGENT_ROLE) == SUB_AGENT);

#ifndef NETSNMP_TRANSPORT_CALLBACK_DOMAIN
    snmp_log(LOG_WARNING,"AgentX subagent has been disabled because "
               "the callback transport is not available.\n");
    return -1;
#endif /* NETSNMP_TRANSPORT_CALLBACK_DOMAIN */

    /*
     * open (local) callback session
     */
    subagent_init_callback_session();
    if (NULL == agentx_callback_sess)
        return -1;

    snmp_register_callback(SNMP_CALLBACK_LIBRARY,
                           SNMP_CALLBACK_POST_READ_CONFIG,
                           subagent_startup, NULL);

    DEBUGMSGTL(("agentx/subagent", "initializing....  DONE\n"));

    return rc;
}

void
netsnmp_enable_subagent(void) {
    netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_ROLE,
                           SUB_AGENT);
}

struct agent_netsnmp_set_info *
save_set_vars(netsnmp_session * ss, netsnmp_pdu *pdu)
{
    struct agent_netsnmp_set_info *ptr;
    struct timeval  now;
    extern struct timeval starttime;

    ptr = (struct agent_netsnmp_set_info *)
        malloc(sizeof(struct agent_netsnmp_set_info));
    if (ptr == NULL)
        return NULL;

    /*
     * Save the important information
     */
    ptr->transID = pdu->transid;
    ptr->sess = ss;
    ptr->mode = SNMP_MSG_INTERNAL_SET_RESERVE1;
    gettimeofday(&now, NULL);
    ptr->uptime = calculate_time_diff(&now, &starttime);

    ptr->var_list = snmp_clone_varbind(pdu->variables);
    if (ptr->var_list == NULL) {
        free(ptr);
        return NULL;
    }

    ptr->next = Sets;
    Sets = ptr;

    return ptr;
}

struct agent_netsnmp_set_info *
restore_set_vars(netsnmp_session * sess, netsnmp_pdu *pdu)
{
    struct agent_netsnmp_set_info *ptr;

    for (ptr = Sets; ptr != NULL; ptr = ptr->next)
        if (ptr->sess == sess && ptr->transID == pdu->transid)
            break;

    if (ptr == NULL || ptr->var_list == NULL)
        return NULL;

    pdu->variables = snmp_clone_varbind(ptr->var_list);
    if (pdu->variables == NULL)
        return NULL;

    return ptr;
}


void
free_set_vars(netsnmp_session * ss, netsnmp_pdu *pdu)
{
    struct agent_netsnmp_set_info *ptr, *prev = NULL;

    for (ptr = Sets; ptr != NULL; ptr = ptr->next) {
        if (ptr->sess == ss && ptr->transID == pdu->transid) {
            if (prev)
                prev->next = ptr->next;
            else
                Sets = ptr->next;
            snmp_free_varbind(ptr->var_list);
            free(ptr);
            return;
        }
        prev = ptr;
    }
}

static void
send_agentx_error(netsnmp_session *session, netsnmp_pdu *pdu, int errstat, int errindex)
{
    pdu = snmp_clone_pdu(pdu);
    pdu->command   = AGENTX_MSG_RESPONSE;
    pdu->version   = session->version;
    pdu->errstat   = errstat;
    pdu->errindex  = errindex;
    snmp_free_varbind(pdu->variables);
    pdu->variables = NULL;

    DEBUGMSGTL(("agentx/subagent", "Sending AgentX response error stat %d idx %d\n",
             errstat, errindex));
    if (!snmp_send(session, pdu)) {
        snmp_free_pdu(pdu);
    }
}

int
handle_agentx_packet(int operation, netsnmp_session * session, int reqid,
                     netsnmp_pdu *pdu, void *magic)
{
    struct agent_netsnmp_set_info *asi = NULL;
    snmp_callback   mycallback;
    netsnmp_pdu    *internal_pdu = NULL;
    void           *retmagic = NULL;
    ns_subagent_magic *smagic = NULL;
    int             result;

    if (operation == NETSNMP_CALLBACK_OP_DISCONNECT) {
        struct synch_state *state = (struct synch_state *) magic;
        int             period =
            netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID,
                               NETSNMP_DS_AGENT_AGENTX_PING_INTERVAL);
        DEBUGMSGTL(("agentx/subagent",
                    "transport disconnect indication\n"));

        /*
         * deal with existing session. This happend if agentx sends
         * a message to the master, but the master goes away before
         * a response is sent. agentx will spin in snmp_synch_response_cb,
         * waiting for a response. At the very least, the waiting
         * flag must be set to break that loop. The rest is copied
         * from disconnect handling in snmp_sync_input.
         */
        if(state) {
            state->waiting = 0;
            state->pdu = NULL;
            state->status = STAT_ERROR;
            session->s_snmp_errno = SNMPERR_ABORT;
            SET_SNMP_ERROR(SNMPERR_ABORT);
        }

        /*
         * Deregister the ping alarm, if any, and invalidate all other
         * references to this session.  
         */
        if (session->securityModel != SNMP_DEFAULT_SECMODEL) {
            snmp_alarm_unregister(session->securityModel);
        }
        snmp_call_callbacks(SNMP_CALLBACK_APPLICATION,
                            SNMPD_CALLBACK_INDEX_STOP, (void *) session);
        agentx_unregister_callbacks(session);
        remove_trap_session(session);
        register_mib_detach();
        main_session = NULL;
        if (period != 0) {
            /*
             * Pings are enabled, so periodically attempt to re-establish contact 
             * with the master agent.  Don't worry about the handle,
             * agentx_reopen_session unregisters itself if it succeeds in talking 
             * to the master agent.  
             */
            snmp_alarm_register(period, SA_REPEAT, agentx_reopen_session, NULL);
            snmp_log(LOG_INFO, "AgentX master disconnected us, reconnecting in %d\n", period);
        } else {
            snmp_log(LOG_INFO, "AgentX master disconnected us, not reconnecting\n");
        }
        return 0;
    } else if (operation != NETSNMP_CALLBACK_OP_RECEIVED_MESSAGE) {
        DEBUGMSGTL(("agentx/subagent", "unexpected callback op %d\n",
                    operation));
        return 1;
    }

    /*
     * ok, we have a pdu from the net. Modify as needed 
     */

    DEBUGMSGTL(("agentx/subagent", "handling agentx request (req=0x%x,trans="
                "0x%x,sess=0x%x)\n", pdu->reqid,pdu->transid, pdu->sessid));
    pdu->version = AGENTX_VERSION_1;
    pdu->flags |= UCD_MSG_FLAG_ALWAYS_IN_VIEW;

    /* Master agent is alive, no need to ping */
    if (session->securityModel != SNMP_DEFAULT_SECMODEL) {
        snmp_alarm_reset(session->securityModel);
    }

    if (pdu->command == AGENTX_MSG_GET
        || pdu->command == AGENTX_MSG_GETNEXT
        || pdu->command == AGENTX_MSG_GETBULK) {
        smagic =
            (ns_subagent_magic *) calloc(1, sizeof(ns_subagent_magic));
        if (smagic == NULL) {
            DEBUGMSGTL(("agentx/subagent", "couldn't malloc() smagic\n"));
            /* would like to send_agentx_error(), but it needs memory too */
            return 1;
        }
        smagic->original_command = pdu->command;
        smagic->session = session;
        smagic->ovars = NULL;
        retmagic = (void *) smagic;
    }

    switch (pdu->command) {
    case AGENTX_MSG_GET:
        DEBUGMSGTL(("agentx/subagent", "  -> get\n"));
        pdu->command = SNMP_MSG_GET;
        mycallback = handle_subagent_response;
        break;

    case AGENTX_MSG_GETNEXT:
        DEBUGMSGTL(("agentx/subagent", "  -> getnext\n"));
        pdu->command = SNMP_MSG_GETNEXT;

        /*
         * We have to save a copy of the original variable list here because
         * if the master agent has requested scoping for some of the varbinds
         * that information is stored there.  
         */

        smagic->ovars = snmp_clone_varbind(pdu->variables);
        DEBUGMSGTL(("agentx/subagent", "saved variables\n"));
        mycallback = handle_subagent_response;
        break;

    case AGENTX_MSG_GETBULK:
        /*
         * WWWXXX 
         */
        DEBUGMSGTL(("agentx/subagent", "  -> getbulk\n"));
        pdu->command = SNMP_MSG_GETBULK;

        /*
         * We have to save a copy of the original variable list here because
         * if the master agent has requested scoping for some of the varbinds
         * that information is stored there.  
         */

        smagic->ovars = snmp_clone_varbind(pdu->variables);
        DEBUGMSGTL(("agentx/subagent", "saved variables at %p\n",
                    smagic->ovars));
        mycallback = handle_subagent_response;
        break;

    case AGENTX_MSG_RESPONSE:
        SNMP_FREE(smagic);
        DEBUGMSGTL(("agentx/subagent", "  -> response\n"));
        return 1;

    case AGENTX_MSG_TESTSET:
        /*
         * XXXWWW we have to map this twice to both RESERVE1 and RESERVE2 
         */
        DEBUGMSGTL(("agentx/subagent", "  -> testset\n"));
        asi = save_set_vars(session, pdu);
        if (asi == NULL) {
            SNMP_FREE(smagic);
            snmp_log(LOG_WARNING, "save_set_vars() failed\n");
            send_agentx_error(session, pdu, AGENTX_ERR_PARSE_FAILED, 0);
            return 1;
        }
        asi->mode = pdu->command = SNMP_MSG_INTERNAL_SET_RESERVE1;
        mycallback = handle_subagent_set_response;
        retmagic = asi;
        break;

    case AGENTX_MSG_COMMITSET:
        DEBUGMSGTL(("agentx/subagent", "  -> commitset\n"));
        asi = restore_set_vars(session, pdu);
        if (asi == NULL) {
            SNMP_FREE(smagic);
            snmp_log(LOG_WARNING, "restore_set_vars() failed\n");
            send_agentx_error(session, pdu, AGENTX_ERR_PROCESSING_ERROR, 0);
            return 1;
        }
        if (asi->mode != SNMP_MSG_INTERNAL_SET_RESERVE2) {
            SNMP_FREE(smagic);
            snmp_log(LOG_WARNING,
                     "dropping bad AgentX request (wrong mode %d)\n",
                     asi->mode);
            send_agentx_error(session, pdu, AGENTX_ERR_PROCESSING_ERROR, 0);
            return 1;
        }
        asi->mode = pdu->command = SNMP_MSG_INTERNAL_SET_ACTION;
        mycallback = handle_subagent_set_response;
        retmagic = asi;
        break;

    case AGENTX_MSG_CLEANUPSET:
        DEBUGMSGTL(("agentx/subagent", "  -> cleanupset\n"));
        asi = restore_set_vars(session, pdu);
        if (asi == NULL) {
            SNMP_FREE(smagic);
            snmp_log(LOG_WARNING, "restore_set_vars() failed\n");
            send_agentx_error(session, pdu, AGENTX_ERR_PROCESSING_ERROR, 0);
            return 1;
        }
        if (asi->mode == SNMP_MSG_INTERNAL_SET_RESERVE1 ||
            asi->mode == SNMP_MSG_INTERNAL_SET_RESERVE2) {
            asi->mode = pdu->command = SNMP_MSG_INTERNAL_SET_FREE;
        } else if (asi->mode == SNMP_MSG_INTERNAL_SET_ACTION) {
            asi->mode = pdu->command = SNMP_MSG_INTERNAL_SET_COMMIT;
        } else {
            snmp_log(LOG_WARNING,
                     "dropping bad AgentX request (wrong mode %d)\n",
                     asi->mode);
            SNMP_FREE(retmagic);
            return 1;
        }
        mycallback = handle_subagent_set_response;
        retmagic = asi;
        break;

    case AGENTX_MSG_UNDOSET:
        DEBUGMSGTL(("agentx/subagent", "  -> undoset\n"));
        asi = restore_set_vars(session, pdu);
        if (asi == NULL) {
            SNMP_FREE(smagic);
            snmp_log(LOG_WARNING, "restore_set_vars() failed\n");
            send_agentx_error(session, pdu, AGENTX_ERR_PROCESSING_ERROR, 0);
            return 1;
        }
        asi->mode = pdu->command = SNMP_MSG_INTERNAL_SET_UNDO;
        mycallback = handle_subagent_set_response;
        retmagic = asi;
        break;

    default:
        SNMP_FREE(smagic);
        DEBUGMSGTL(("agentx/subagent", "  -> unknown command %d (%02x)\n",
                    pdu->command, pdu->command));
        return 0;
    }

    /*
     * submit the pdu to the internal handler 
     */

    /*
     * We have to clone the PDU here, because when we return from this
     * callback, sess_process_packet will free(pdu), but this call also
     * free()s its argument PDU.  
     */

    internal_pdu = snmp_clone_pdu(pdu);
    internal_pdu->contextName = internal_pdu->community;
    internal_pdu->contextNameLen = internal_pdu->community_len;
    internal_pdu->community = NULL;
    internal_pdu->community_len = 0;
    result = snmp_async_send(agentx_callback_sess, internal_pdu, mycallback,
                    retmagic);
    if (result == 0) {
        snmp_free_pdu(internal_pdu);
    }
    return 1;
}

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;
}

int
handle_subagent_response(int op, netsnmp_session * session, int reqid,
                         netsnmp_pdu *pdu, void *magic)
{
    ns_subagent_magic *smagic = (ns_subagent_magic *) magic;
    netsnmp_variable_list *u = NULL, *v = NULL;
    int             rc = 0;

    if (_invalid_op_and_magic(op, magic)) {
        return 1;
    }

    pdu = snmp_clone_pdu(pdu);
    DEBUGMSGTL(("agentx/subagent",
                "handling AgentX response (cmd 0x%02x orig_cmd 0x%02x)\n",
                pdu->command, smagic->original_command));

    if (pdu->command == SNMP_MSG_INTERNAL_SET_FREE ||
        pdu->command == SNMP_MSG_INTERNAL_SET_UNDO ||
        pdu->command == SNMP_MSG_INTERNAL_SET_COMMIT) {
        free_set_vars(smagic->session, pdu);
    }

    if (smagic->original_command == AGENTX_MSG_GETNEXT) {
        DEBUGMSGTL(("agentx/subagent",
                    "do getNext scope processing %p %p\n", smagic->ovars,
                    pdu->variables));
        for (u = smagic->ovars, v = pdu->variables; u != NULL && v != NULL;
             u = u->next_variable, v = v->next_variable) {
            if (snmp_oid_compare
                (u->val.objid, u->val_len / sizeof(oid), nullOid,
                 nullOidLen/sizeof(oid)) != 0) {
                /*
                 * The master agent requested scoping for this variable.  
                 */
                rc = snmp_oid_compare(v->name, v->name_length,
                                      u->val.objid,
                                      u->val_len / sizeof(oid));
                DEBUGMSGTL(("agentx/subagent", "result "));
                DEBUGMSGOID(("agentx/subagent", v->name, v->name_length));
                DEBUGMSG(("agentx/subagent", " scope to "));
                DEBUGMSGOID(("agentx/subagent",
                             u->val.objid, u->val_len / sizeof(oid)));
                DEBUGMSG(("agentx/subagent", " result %d\n", rc));

                if (rc >= 0) {
                    /*
                     * The varbind is out of scope.  From RFC2741, p. 66: "If
                     * the subagent cannot locate an appropriate variable,
                     * v.name is set to the starting OID, and the VarBind is
                     * set to `endOfMibView'".  
                     */
                    snmp_set_var_objid(v, u->name, u->name_length);
                    snmp_set_var_typed_value(v, SNMP_ENDOFMIBVIEW, 0, 0);
                    DEBUGMSGTL(("agentx/subagent",
                                "scope violation -- return endOfMibView\n"));
                }
            } else {
                DEBUGMSGTL(("agentx/subagent", "unscoped var\n"));
            }
        }
    }

    /*
     * XXXJBPN: similar for GETBULK but the varbinds can get re-ordered I
     * think which makes it er more difficult.  
     */

    if (smagic->ovars != NULL) {
        snmp_free_varbind(smagic->ovars);
    }

    pdu->command = AGENTX_MSG_RESPONSE;
    pdu->version = smagic->session->version;

    if (!snmp_send(smagic->session, pdu)) {
        snmp_free_pdu(pdu);
    }
    DEBUGMSGTL(("agentx/subagent", "  FINISHED\n"));
    free(smagic);
    return 1;
}

int
handle_subagent_set_response(int op, netsnmp_session * session, int reqid,
                             netsnmp_pdu *pdu, void *magic)
{
    netsnmp_session *retsess;
    struct agent_netsnmp_set_info *asi;
    int    result;

    if (op != NETSNMP_CALLBACK_OP_RECEIVED_MESSAGE || magic == NULL) {
        return 1;
    }

    DEBUGMSGTL(("agentx/subagent",
                "handling agentx subagent set response (mode=%d,req=0x%x,"
                "trans=0x%x,sess=0x%x)\n",
                pdu->command, pdu->reqid,pdu->transid, pdu->sessid));
    pdu = snmp_clone_pdu(pdu);

    asi = (struct agent_netsnmp_set_info *) magic;
    retsess = asi->sess;
    asi->errstat = pdu->errstat;

    if (asi->mode == SNMP_MSG_INTERNAL_SET_RESERVE1) {
        /*
         * reloop for RESERVE2 mode, an internal only agent mode 
         */
        /*
         * XXX: check exception statuses of reserve1 first 
         */
        if (!pdu->errstat) {
            asi->mode = pdu->command = SNMP_MSG_INTERNAL_SET_RESERVE2;
            result = snmp_async_send(agentx_callback_sess, pdu,
                            handle_subagent_set_response, asi);
            if (result == 0) {
                snmp_free_pdu(pdu);
            }
            DEBUGMSGTL(("agentx/subagent",
                        "  going from RESERVE1 -> RESERVE2\n"));
            return 1;
        }
    } else {
        if (asi->mode == SNMP_MSG_INTERNAL_SET_FREE ||
            asi->mode == SNMP_MSG_INTERNAL_SET_UNDO ||
            asi->mode == SNMP_MSG_INTERNAL_SET_COMMIT) {
            free_set_vars(retsess, pdu);
        }
        snmp_free_varbind(pdu->variables);
        pdu->variables = NULL;  /* the variables were added by us */
    }

    netsnmp_assert(retsess != NULL);
    pdu->command = AGENTX_MSG_RESPONSE;
    pdu->version = retsess->version;

    if (!snmp_send(retsess, pdu)) {
        snmp_free_pdu(pdu);
    }
    DEBUGMSGTL(("agentx/subagent", "  FINISHED\n"));
    return 1;
}



int
agentx_registration_callback(int majorID, int minorID, void *serverarg,
                             void *clientarg)
{
    struct register_parameters *reg_parms =
        (struct register_parameters *) serverarg;
    netsnmp_session *agentx_ss = (netsnmp_session *) clientarg;

    if (minorID == SNMPD_CALLBACK_REGISTER_OID)
        return agentx_register(agentx_ss,
                               reg_parms->name, reg_parms->namelen,
                               reg_parms->priority,
                               reg_parms->range_subid,
                               reg_parms->range_ubound, reg_parms->timeout,
                               reg_parms->flags,
                               reg_parms->contextName);
    else
        return agentx_unregister(agentx_ss,
                                 reg_parms->name, reg_parms->namelen,
                                 reg_parms->priority,
                                 reg_parms->range_subid,
                                 reg_parms->range_ubound,
                                 reg_parms->contextName);
}


#ifdef USING_MIBII_SYSORTABLE_MODULE
int
agentx_sysOR_callback(int majorID, int minorID, void *serverarg,
                      void *clientarg)
{
    struct register_sysOR_parameters *reg_parms =
        (struct register_sysOR_parameters *) serverarg;
    netsnmp_session *agentx_ss = (netsnmp_session *) clientarg;

    if (minorID == SNMPD_CALLBACK_REG_SYSOR)
        return agentx_add_agentcaps(agentx_ss,
                                    reg_parms->name, reg_parms->namelen,
                                    reg_parms->descr);
    else
        return agentx_remove_agentcaps(agentx_ss,
                                       reg_parms->name,
                                       reg_parms->namelen);
}
#endif


static int
subagent_shutdown(int majorID, int minorID, void *serverarg, void *clientarg)
{
    netsnmp_session *thesession = (netsnmp_session *)clientarg;
    DEBUGMSGTL(("agentx/subagent", "shutting down session....\n"));
    if (thesession == NULL) {
	DEBUGMSGTL(("agentx/subagent", "Empty session to shutdown\n"));
	main_session = NULL;
	return 0;
    }
    agentx_close_session(thesession, AGENTX_CLOSE_SHUTDOWN);
    snmp_close(thesession);
    if (main_session != NULL) {
        remove_trap_session(main_session);
        main_session = NULL;
    }
    DEBUGMSGTL(("agentx/subagent", "shut down finished.\n"));

    subagent_init_init = 0;
    return 1;
}



/*
 * Register all the "standard" AgentX callbacks for the given session.  
 */

void
agentx_register_callbacks(netsnmp_session * s)
{
    DEBUGMSGTL(("agentx/subagent",
                "registering callbacks for session %p\n", s));
    snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_SHUTDOWN,
                           subagent_shutdown, s);
    snmp_register_callback(SNMP_CALLBACK_APPLICATION,
                           SNMPD_CALLBACK_REGISTER_OID,
                           agentx_registration_callback, s);
    snmp_register_callback(SNMP_CALLBACK_APPLICATION,
                           SNMPD_CALLBACK_UNREGISTER_OID,
                           agentx_registration_callback, s);
#ifdef USING_MIBII_SYSORTABLE_MODULE
    snmp_register_callback(SNMP_CALLBACK_APPLICATION,
                           SNMPD_CALLBACK_REG_SYSOR,
                           agentx_sysOR_callback, s);
    snmp_register_callback(SNMP_CALLBACK_APPLICATION,
                           SNMPD_CALLBACK_UNREG_SYSOR,
                           agentx_sysOR_callback, s);
#endif
}

/*
 * Unregister all the callbacks associated with this session.  
 */

void
agentx_unregister_callbacks(netsnmp_session * ss)
{
    DEBUGMSGTL(("agentx/subagent",
                "unregistering callbacks for session %p\n", ss));
    snmp_unregister_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_SHUTDOWN,
                             subagent_shutdown, ss, 1);
    snmp_unregister_callback(SNMP_CALLBACK_APPLICATION,
                             SNMPD_CALLBACK_REGISTER_OID,
                             agentx_registration_callback, ss, 1);
    snmp_unregister_callback(SNMP_CALLBACK_APPLICATION,
                             SNMPD_CALLBACK_UNREGISTER_OID,
                             agentx_registration_callback, ss, 1);
#ifdef USING_MIBII_SYSORTABLE_MODULE
    snmp_unregister_callback(SNMP_CALLBACK_APPLICATION,
                             SNMPD_CALLBACK_REG_SYSOR,
                             agentx_sysOR_callback, ss, 1);
    snmp_unregister_callback(SNMP_CALLBACK_APPLICATION,
                             SNMPD_CALLBACK_UNREG_SYSOR,
                             agentx_sysOR_callback, ss, 1);
#endif

}

/*
 * Open a session to the master agent.  
 */
int
subagent_open_master_session(void)
{
    netsnmp_transport *t;
    netsnmp_session sess;
    const char *agentx_socket;

    DEBUGMSGTL(("agentx/subagent", "opening session...\n"));

    if (main_session) {
        snmp_log(LOG_WARNING,
                 "AgentX session to master agent attempted to be re-opened.\n");
        return -1;
    }

    snmp_sess_init(&sess);
    sess.version = AGENTX_VERSION_1;
    sess.retries = SNMP_DEFAULT_RETRIES;
    sess.timeout = SNMP_DEFAULT_TIMEOUT;
    sess.flags |= SNMP_FLAGS_STREAM_SOCKET;
    sess.callback = handle_agentx_packet;
    sess.authenticator = NULL;

    agentx_socket = netsnmp_ds_get_string(NETSNMP_DS_APPLICATION_ID,
                                          NETSNMP_DS_AGENT_X_SOCKET);
    t = netsnmp_transport_open_client("agentx", agentx_socket);
    if (t == NULL) {
        /*
         * Diagnose snmp_open errors with the input
         * netsnmp_session pointer.  
         */
        if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
                                    NETSNMP_DS_AGENT_NO_CONNECTION_WARNINGS)) {
            char buf[1024];
            snprintf(buf, sizeof(buf), "Warning: "
                     "Failed to connect to the agentx master agent (%s)",
                     agentx_socket ? agentx_socket : "[NIL]");
            if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
                                        NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
                netsnmp_sess_log_error(LOG_WARNING, buf, &sess);
            } else {
                snmp_sess_perror(buf, &sess);
            }
        }
        return -1;
    }

    main_session =
        snmp_add_full(&sess, t, NULL, agentx_parse, NULL, NULL,
                      agentx_realloc_build, agentx_check_packet, NULL);

    if (main_session == NULL) {
        if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
                                    NETSNMP_DS_AGENT_NO_CONNECTION_WARNINGS)) {
            char buf[1024];
            snprintf(buf, sizeof(buf), "Error: "
                     "Failed to create the agentx master agent session (%s)",
                     agentx_socket);
            snmp_sess_perror(buf, &sess);
        }
        netsnmp_transport_free(t);
        return -1;
    }

    /*
     * I don't know why 1 is success instead of the usual 0 = noerr, 
     * but that's what the function returns.
     */
    if (1 != agentx_open_session(main_session)) {
        snmp_close(main_session);
        main_session = NULL;
        return -1;
    }

    /*
     * subagent_register_ping_alarm assumes that securityModel will
     *  be set to SNMP_DEFAULT_SECMODEL on new AgentX sessions.
     *  This field is then (ab)used to hold the alarm stash.
     *
     * Why is the securityModel field used for this purpose, I hear you ask.
     * Damn good question!   (See SVN revision 4886)
     */
    main_session->securityModel = SNMP_DEFAULT_SECMODEL;

    if (add_trap_session(main_session, AGENTX_MSG_NOTIFY, 1,
                         AGENTX_VERSION_1)) {
        DEBUGMSGTL(("agentx/subagent", " trap session registered OK\n"));
    } else {
        DEBUGMSGTL(("agentx/subagent",
                    "trap session registration failed\n"));
        snmp_close(main_session);
        main_session = NULL;
        return -1;
    }

    agentx_register_callbacks(main_session);

    snmp_call_callbacks(SNMP_CALLBACK_APPLICATION,
                        SNMPD_CALLBACK_INDEX_START, (void *) main_session);

    snmp_log(LOG_INFO, "NET-SNMP version %s AgentX subagent connected\n",
             netsnmp_get_version());
    DEBUGMSGTL(("agentx/subagent", "opening session...  DONE (%p)\n",
                main_session));

    return 0;
}


/*
 * Alarm callback function to open a session to the master agent.  If a
 * transport disconnection callback occurs, indicating that the master agent
 * has died (or there has been some strange communication problem), this
 * alarm is called repeatedly to try to re-open the connection.  
 */

void
agentx_reopen_session(unsigned int clientreg, void *clientarg)
{
    DEBUGMSGTL(("agentx/subagent", "agentx_reopen_session(%d) called\n",
                clientreg));

    if (subagent_open_master_session() == 0) {
        /*
         * Successful.  Delete the alarm handle if one exists.  
         */
        if (clientreg != 0) {
            snmp_alarm_unregister(clientreg);
        }

        /*
         * Reregister all our nodes.  
         */
        register_mib_reattach();

        /*
         * Register a ping alarm (if need be).  
         */
        subagent_register_ping_alarm(0, 0, 0, main_session);
    } else {
        if (clientreg == 0) {
            /*
             * Register a reattach alarm for later 
             */
            subagent_register_ping_alarm(0, 0, 0, main_session);
        }
    }
}

/*
 * If a valid session is passed in (through clientarg), register a
 * ping handler to ping it frequently, else register an attempt to try
 * and open it again later. 
 */

static int
subagent_register_ping_alarm(int majorID, int minorID,
                             void *serverarg, void *clientarg)
{

    netsnmp_session *ss = (netsnmp_session *) clientarg;
    int             ping_interval =
        netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID,
                           NETSNMP_DS_AGENT_AGENTX_PING_INTERVAL);

    if (!ping_interval)         /* don't do anything if not setup properly */
        return 0;

    /*
     * register a ping alarm, if desired 
     */
    if (ss) {
        if (ss->securityModel != SNMP_DEFAULT_SECMODEL) {
            DEBUGMSGTL(("agentx/subagent",
                        "unregister existing alarm %d\n",
                        ss->securityModel));
            snmp_alarm_unregister(ss->securityModel);
        }

        DEBUGMSGTL(("agentx/subagent",
                    "register ping alarm every %d seconds\n",
                    ping_interval));
        /*
         * we re-use the securityModel parameter for an alarm stash,
         * since agentx doesn't need it 
         */
        ss->securityModel = snmp_alarm_register(ping_interval, SA_REPEAT,
                                                agentx_check_session, ss);
    } else {
        /*
         * attempt to open it later instead 
         */
        DEBUGMSGTL(("agentx/subagent",
                    "subagent not properly attached, postponing registration till later....\n"));
        snmp_alarm_register(ping_interval, SA_REPEAT,
                            agentx_reopen_session, NULL);
    }
    return 0;
}

/*
 * check a session validity for connectivity to the master agent.  If
 * not functioning, close and start attempts to reopen the session 
 */
void
agentx_check_session(unsigned int clientreg, void *clientarg)
{
    netsnmp_session *ss = (netsnmp_session *) clientarg;
    if (!ss) {
        if (clientreg)
            snmp_alarm_unregister(clientreg);
        return;
    }
    DEBUGMSGTL(("agentx/subagent", "checking status of session %p\n", ss));

    if (!agentx_send_ping(ss)) {
        snmp_log(LOG_WARNING,
                 "AgentX master agent failed to respond to ping.  Attempting to re-register.\n");
        /*
         * master agent disappeared?  Try and re-register.
         * close first, just to be sure .
         */
        agentx_unregister_callbacks(ss);
        agentx_close_session(ss, AGENTX_CLOSE_TIMEOUT);
        snmp_alarm_unregister(clientreg);       /* delete ping alarm timer */
        snmp_call_callbacks(SNMP_CALLBACK_APPLICATION,
                            SNMPD_CALLBACK_INDEX_STOP, (void *) ss);
        register_mib_detach();
        if (main_session != NULL) {
            remove_trap_session(ss);
            snmp_close(main_session);
            /*
             * We need to remove the callbacks attached to the callback
             * session because they have a magic callback data structure
             * which includes a pointer to the main session
             *    (which is no longer valid).
             * 
             * Given that the main session is not responsive anyway.
             * it shoudn't matter if we lose some outstanding requests.
             */
            if (agentx_callback_sess != NULL ) {
                snmp_close(agentx_callback_sess);
                agentx_callback_sess = NULL;
    
                subagent_init_callback_session();
            }
            main_session = NULL;
            agentx_reopen_session(0, NULL);
        }
        else {
            snmp_close(main_session);
            main_session = NULL;
        }
    } else {
        DEBUGMSGTL(("agentx/subagent", "session %p responded to ping\n",
                    ss));
    }
}


#endif /* USING_AGENTX_SUBAGENT_MODULE */
