/* Portions of this file are subject to the following copyright(s).  See
 * the Net-SNMP's COPYING file for more details and other copyrights
 * that may apply:
 */
/*
 * Portions of this file are copyrighted by:
 * Copyright @ 2009 Sun Microsystems, Inc. All rights reserved.
 * Use is subject to license terms specified in the COPYING file
 * distributed with the Net-SNMP package.
 */
#include <net-snmp/net-snmp-config.h>

#include <sys/types.h>
#if HAVE_WINSOCK_H
#include <winsock.h>
#endif
#if HAVE_STRING_H
#include <string.h>
#endif
#ifdef 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 "proxy.h"

static struct simple_proxy *proxies = NULL;

oid             testoid[] = { 1, 3, 6, 1, 4, 1, 2021, 8888, 1 };

/*
 * this must be standardized somewhere, right? 
 */
#define MAX_ARGS 128

char           *context_string;

static void
proxyOptProc(int argc, char *const *argv, int opt)
{
    switch (opt) {
    case 'C':
        while (*optarg) {
            switch (*optarg++) {
            case 'n':
                optind++;
                if (optind < argc) {
                    context_string = argv[optind - 1];
                } else {
                    config_perror("No context name passed to -Cn");
                }
                break;
            case 'c':
                netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID,
                                       NETSNMP_DS_LIB_IGNORE_NO_COMMUNITY, 1);
                break;
            default:
                config_perror("unknown argument passed to -C");
                break;
            }
        }
        break;
    default:
        break;
        /*
         * shouldn't get here 
         */
    }
}

void
proxy_parse_config(const char *token, char *line)
{
    /*
     * proxy args [base-oid] [remap-to-remote-oid] 
     */

    netsnmp_session session, *ss;
    struct simple_proxy *newp, **listpp;
    char            args[MAX_ARGS][SPRINT_MAX_LEN], *argv[MAX_ARGS];
    int             argn, arg;
    char           *cp;
    netsnmp_handler_registration *reg;

    context_string = NULL;

    DEBUGMSGTL(("proxy_config", "entering\n"));

    /*
     * create the argv[] like array 
     */
    strcpy(argv[0] = args[0], "snmpd-proxy");   /* bogus entry for getopt() */
    for (argn = 1, cp = line; cp && argn < MAX_ARGS;) {
	argv[argn] = args[argn];
        cp = copy_nword(cp, argv[argn], SPRINT_MAX_LEN);
	argn++;
    }

    for (arg = 0; arg < argn; arg++) {
        DEBUGMSGTL(("proxy_args", "final args: %d = %s\n", arg,
                    argv[arg]));
    }

    DEBUGMSGTL(("proxy_config", "parsing args: %d\n", argn));
    /* Call special parse_args that allows for no specified community string */
    arg = snmp_parse_args(argn, argv, &session, "C:", proxyOptProc);

    /* reset this in case we modified it */
    netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID,
                           NETSNMP_DS_LIB_IGNORE_NO_COMMUNITY, 0);
    
    if (arg < 0) {
        config_perror("failed to parse proxy args");
        return;
    }
    DEBUGMSGTL(("proxy_config", "done parsing args\n"));

    if (arg >= argn) {
        config_perror("missing base oid");
        return;
    }

    /*
     * usm_set_reportErrorOnUnknownID(0); 
     *
     * hack, stupid v3 ASIs. 
     */
    /*
     * XXX: on a side note, we don't really need to be a reference
     * platform any more so the proper thing to do would be to fix
     * snmplib/snmpusm.c to pass in the pdu type to usm_process_incoming
     * so this isn't needed. 
     */
    ss = snmp_open(&session);
    /*
     * usm_set_reportErrorOnUnknownID(1); 
     */
    if (ss == NULL) {
        /*
         * diagnose snmp_open errors with the input netsnmp_session pointer 
         */
        snmp_sess_perror("snmpget", &session);
        SOCK_CLEANUP;
        return;
    }

    newp = (struct simple_proxy *) calloc(1, sizeof(struct simple_proxy));

    newp->sess = ss;
    DEBUGMSGTL(("proxy_init", "name = %s\n", args[arg]));
    newp->name_len = MAX_OID_LEN;
    if (!snmp_parse_oid(args[arg++], newp->name, &newp->name_len)) {
        snmp_perror("proxy");
        config_perror("illegal proxy oid specified\n");
        return;
    }

    if (arg < argn) {
        DEBUGMSGTL(("proxy_init", "base = %s\n", args[arg]));
        newp->base_len = MAX_OID_LEN;
        if (!snmp_parse_oid(args[arg++], newp->base, &newp->base_len)) {
            snmp_perror("proxy");
            config_perror("illegal variable name specified (base oid)\n");
            return;
        }
    }
    if ( context_string )
        newp->context = strdup(context_string);

    DEBUGMSGTL(("proxy_init", "registering at: "));
    DEBUGMSGOID(("proxy_init", newp->name, newp->name_len));
    DEBUGMSG(("proxy_init", "\n"));

    /*
     * add to our chain 
     */
    /*
     * must be sorted! 
     */
    listpp = &proxies;
    while (*listpp &&
           snmp_oid_compare(newp->name, newp->name_len,
                            (*listpp)->name, (*listpp)->name_len) > 0) {
        listpp = &((*listpp)->next);
    }

    /*
     * listpp should be next in line from us. 
     */
    if (*listpp) {
        /*
         * make our next in the link point to the current link 
         */
        newp->next = *listpp;
    }
    /*
     * replace current link with us 
     */
    *listpp = newp;

    reg = netsnmp_create_handler_registration("proxy",
                                              proxy_handler,
                                              newp->name,
                                              newp->name_len,
                                              HANDLER_CAN_RWRITE);
    reg->handler->myvoid = newp;
    if (context_string)
        reg->contextName = strdup(context_string);

    netsnmp_register_handler(reg);
}

void
proxy_free_config(void)
{
    struct simple_proxy *rm;

    DEBUGMSGTL(("proxy_free_config", "Free config\n"));
    while (proxies) {
        rm = proxies;
        proxies = rm->next;

        DEBUGMSGTL(( "proxy_free_config", "freeing "));
        DEBUGMSGOID(("proxy_free_config", rm->name, rm->name_len));
        DEBUGMSG((   "proxy_free_config", " (%s)\n", rm->context));
        unregister_mib_context(rm->name, rm->name_len,
                               DEFAULT_MIB_PRIORITY, 0, 0,
                               rm->context);
        SNMP_FREE(rm->variables);
        SNMP_FREE(rm->context);
        snmp_close(rm->sess);
        SNMP_FREE(rm);
    }
}

/*
 * Configure special parameters on the session.
 * Currently takes the parameter configured and changes it if something 
 * was configured.  It becomes "-c" if the community string from the pdu
 * is placed on the session.
 */
int
proxy_fill_in_session(netsnmp_mib_handler *handler,
                      netsnmp_agent_request_info *reqinfo,
                      void **configured)
{
    netsnmp_session *session;
    struct simple_proxy *sp;

    sp = (struct simple_proxy *) handler->myvoid;
    if (!sp) {
        return 0;
    }
    session = sp->sess;
    if (!session) {
        return 0;
    }

#if !defined(NETSNMP_DISABLE_SNMPV1) || !defined(NETSNMP_DISABLE_SNMPV2C)
#if defined(NETSNMP_DISABLE_SNMPV1)
    if (session->version == SNMP_VERSION_2c) {
#else
#if defined(NETSNMP_DISABLE_SNMPV2C)
    if (session->version == SNMP_VERSION_1) {
#else
    if (session->version == SNMP_VERSION_1 ||
        session->version == SNMP_VERSION_2c) {
#endif
#endif

        /*
         * Check if session has community string defined for it.
         * If not, need to extract community string from the pdu.
         * Copy to session and set 'configured' to indicate this.
         */
        if (session->community_len == 0) {
            DEBUGMSGTL(("proxy", "session has no community string\n"));
            if (reqinfo->asp == NULL || reqinfo->asp->pdu == NULL ||
                reqinfo->asp->pdu->community_len == 0) {
                return 0;
            }

            *configured = strdup("-c");
            DEBUGMSGTL(("proxy", "pdu has community string\n"));
            session->community_len = reqinfo->asp->pdu->community_len;
            session->community = malloc(session->community_len + 1);
            sprintf((char *)session->community, "%.*s",
                    (int) session->community_len,
                    (const char *)reqinfo->asp->pdu->community);
        }
    }
#endif

    return 1;
}

/*
 * Free any specially configured parameters used on the session.
 */
void
proxy_free_filled_in_session_args(netsnmp_session *session, void **configured)
{

    /* Only do comparisions, etc., if something was configured */
    if (*configured == NULL) {
        return;
    }

    /* If used community string from pdu, release it from session now */
    if (strcmp((const char *)(*configured), "-c") == 0) {
        free(session->community);
        session->community = NULL;
        session->community_len = 0;
    }

    free((u_char *)(*configured));
    *configured = NULL;
}

void
init_proxy(void)
{
    snmpd_register_config_handler("proxy", proxy_parse_config,
                                  proxy_free_config,
                                  "[snmpcmd args] host oid [remoteoid]");
}

void
shutdown_proxy(void)
{
    proxy_free_config();
}

int
proxy_handler(netsnmp_mib_handler *handler,
              netsnmp_handler_registration *reginfo,
              netsnmp_agent_request_info *reqinfo,
              netsnmp_request_info *requests)
{

    netsnmp_pdu    *pdu;
    struct simple_proxy *sp;
    oid            *ourname;
    size_t          ourlength;
    netsnmp_request_info *request = requests;
    u_char         *configured = NULL;

    DEBUGMSGTL(("proxy", "proxy handler starting, mode = %d\n",
                reqinfo->mode));

    switch (reqinfo->mode) {
    case MODE_GET:
    case MODE_GETNEXT:
    case MODE_GETBULK:         /* WWWXXX */
        pdu = snmp_pdu_create(reqinfo->mode);
        break;

    case MODE_SET_ACTION:
        pdu = snmp_pdu_create(SNMP_MSG_SET);
        break;

    case MODE_SET_UNDO:
        /*
         *  If we set successfully (status == NOERROR),
         *     we can't back out again, so need to report the fact.
         *  If we failed to set successfully, then we're fine.
         */
        for (request = requests; request; request=request->next) {
            if (request->status == SNMP_ERR_NOERROR) {
                netsnmp_set_request_error(reqinfo, requests,
                                          SNMP_ERR_UNDOFAILED);
                return SNMP_ERR_UNDOFAILED;
	    }
	}
        return SNMP_ERR_NOERROR;

    case MODE_SET_RESERVE1:
    case MODE_SET_RESERVE2:
    case MODE_SET_FREE:
    case MODE_SET_COMMIT:
        /*
         *  Nothing to do in this pass
         */
        return SNMP_ERR_NOERROR;

    default:
        snmp_log(LOG_WARNING, "unsupported mode for proxy called (%d)\n",
                               reqinfo->mode);
        return SNMP_ERR_NOERROR;
    }

    sp = (struct simple_proxy *) handler->myvoid;

    if (!pdu || !sp) {
        netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_GENERR);
        if (pdu)
            snmp_free_pdu(pdu);
        return SNMP_ERR_NOERROR;
    }

    while (request) {
        ourname = request->requestvb->name;
        ourlength = request->requestvb->name_length;

        if (sp->base_len > 0) {
            if ((ourlength - sp->name_len + sp->base_len) > MAX_OID_LEN) {
                /*
                 * too large 
                 */
                if (pdu)
                    snmp_free_pdu(pdu);
                snmp_log(LOG_ERR,
                         "proxy oid request length is too long\n");
                return SNMP_ERR_NOERROR;
            }
            /*
             * suffix appended? 
             */
            DEBUGMSGTL(("proxy", "length=%d, base_len=%d, name_len=%d\n",
                        ourlength, sp->base_len, sp->name_len));
            if (ourlength > (int) sp->name_len)
                memcpy(&(sp->base[sp->base_len]), &(ourname[sp->name_len]),
                       sizeof(oid) * (ourlength - sp->name_len));
            ourlength = ourlength - sp->name_len + sp->base_len;
            ourname = sp->base;
        }

        snmp_pdu_add_variable(pdu, ourname, ourlength,
                              request->requestvb->type,
                              request->requestvb->val.string,
                              request->requestvb->val_len);
        request->delegated = 1;
        request = request->next;
    }

    /*
     * Customize session parameters based on request information
     */
    if (!proxy_fill_in_session(handler, reqinfo, (void **)&configured)) {
        netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_GENERR);
        if (pdu)
            snmp_free_pdu(pdu);
        return SNMP_ERR_NOERROR;
    }

    /*
     * send the request out 
     */
    DEBUGMSGTL(("proxy", "sending pdu\n"));
    snmp_async_send(sp->sess, pdu, proxy_got_response,
                    netsnmp_create_delegated_cache(handler, reginfo,
                                                   reqinfo, requests,
                                                   (void *) sp));

    /* Free any special parameters generated on the session */
    proxy_free_filled_in_session_args(sp->sess, (void **)&configured);

    return SNMP_ERR_NOERROR;
}

int
proxy_got_response(int operation, netsnmp_session * sess, int reqid,
                   netsnmp_pdu *pdu, void *cb_data)
{
    netsnmp_delegated_cache *cache = (netsnmp_delegated_cache *) cb_data;
    netsnmp_request_info  *requests, *request = NULL;
    netsnmp_variable_list *vars,     *var     = NULL;

    struct simple_proxy *sp;
    oid             myname[MAX_OID_LEN];
    size_t          myname_len = MAX_OID_LEN;

    cache = netsnmp_handler_check_cache(cache);

    if (!cache) {
        DEBUGMSGTL(("proxy", "a proxy request was no longer valid.\n"));
        return SNMP_ERR_NOERROR;
    }

    requests = cache->requests;


    sp = (struct simple_proxy *) cache->localinfo;

    if (!sp) {
        DEBUGMSGTL(("proxy", "a proxy request was no longer valid.\n"));
        return SNMP_ERR_NOERROR;
    }

    switch (operation) {
    case NETSNMP_CALLBACK_OP_TIMED_OUT:
        /*
         * WWWXXX: don't leave requests delayed if operation is
         * something like TIMEOUT 
         */
        DEBUGMSGTL(("proxy", "got timed out... requests = %08p\n", requests));

        netsnmp_handler_mark_requests_as_delegated(requests,
                                                   REQUEST_IS_NOT_DELEGATED);
        if(cache->reqinfo->mode != MODE_GETNEXT) {
            DEBUGMSGTL(("proxy", "  ignoring timeout\n"));
            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:
        vars = pdu->variables;

        if (pdu->errstat != SNMP_ERR_NOERROR) {
            /*
             *  If we receive an error from the proxy agent, pass it on up.
             *  The higher-level processing seems to Do The Right Thing.
             *
             * 2005/06 rks: actually, it doesn't do the right thing for
             * a get-next request that returns NOSUCHNAME. If we do nothing,
             * it passes that error back to the comman initiator. What it should
             * do is ignore the error and move on to the next tree. To
             * accomplish that, all we need to do is clear the delegated flag.
             * Not sure if any other error codes need the same treatment. Left
             * as an exercise to the reader...
             */
            DEBUGMSGTL(("proxy", "got error response (%d)\n", pdu->errstat));
            if((cache->reqinfo->mode == MODE_GETNEXT) &&
               (SNMP_ERR_NOSUCHNAME == pdu->errstat)) {
                DEBUGMSGTL(("proxy", "  ignoring error response\n"));
                netsnmp_handler_mark_requests_as_delegated(requests,
                                                           REQUEST_IS_NOT_DELEGATED);
            }
	    else if (cache->reqinfo->mode == MODE_SET_ACTION) {
		/*
		 * In order for netsnmp_wrap_up_request to consider the
		 * SET request complete,
		 * there must be no delegated requests pending.
		 * https://sourceforge.net/tracker/
		 *	?func=detail&atid=112694&aid=1554261&group_id=12694
		 */
		DEBUGMSGTL(("proxy",
		    "got SET error %s, index %d\n",
		    snmp_errstring(pdu->errstat), pdu->errindex));
		netsnmp_handler_mark_requests_as_delegated(
		    requests, REQUEST_IS_NOT_DELEGATED);
		netsnmp_request_set_error_idx(requests, pdu->errstat,
                                                        pdu->errindex);
	    }
            else {
		netsnmp_handler_mark_requests_as_delegated( requests,
                                             REQUEST_IS_NOT_DELEGATED);
		netsnmp_request_set_error_idx(requests, pdu->errstat,
                                                        pdu->errindex);
            }

        /*
         * update the original request varbinds with the results 
         */
	} else for (var = vars, request = requests;
             request && var;
             request = request->next, var = var->next_variable) {
            /*
             * XXX - should this be done here?
             *       Or wait until we know it's OK?
             */
            snmp_set_var_typed_value(request->requestvb, var->type,
                                     var->val.string, var->val_len);

            DEBUGMSGTL(("proxy", "got response... "));
            DEBUGMSGOID(("proxy", var->name, var->name_length));
            DEBUGMSG(("proxy", "\n"));
            request->delegated = 0;

            /*
             * Check the response oid is legitimate,
             *   and discard the value if not.
             *
             * XXX - what's the difference between these cases?
             */
            if (sp->base_len &&
                (var->name_length < sp->base_len ||
                 snmp_oid_compare(var->name, sp->base_len, sp->base,
                                  sp->base_len) != 0)) {
                DEBUGMSGTL(( "proxy", "out of registered range... "));
                DEBUGMSGOID(("proxy", var->name, sp->base_len));
                DEBUGMSG((   "proxy", " (%d) != ", sp->base_len));
                DEBUGMSGOID(("proxy", sp->base, sp->base_len));
                DEBUGMSG((   "proxy", "\n"));
                snmp_set_var_typed_value(request->requestvb, ASN_NULL, NULL, 0);

                continue;
            } else if (!sp->base_len &&
                       (var->name_length < sp->name_len ||
                        snmp_oid_compare(var->name, sp->name_len, sp->name,
                                         sp->name_len) != 0)) {
                DEBUGMSGTL(( "proxy", "out of registered base range... "));
                DEBUGMSGOID(("proxy", var->name, sp->name_len));
                DEBUGMSG((   "proxy", " (%d) != ", sp->name_len));
                DEBUGMSGOID(("proxy", sp->name, sp->name_len));
                DEBUGMSG((   "proxy", "\n"));
                snmp_set_var_typed_value(request->requestvb, ASN_NULL, NULL, 0);
                continue;
            } else {
                /*
                 * If the returned OID is legitimate, then update
                 *   the original request varbind accordingly.
                 */
                if (sp->base_len) {
                    /*
                     * XXX: oid size maxed? 
                     */
                    memcpy(myname, sp->name, sizeof(oid) * sp->name_len);
                    myname_len =
                        sp->name_len + var->name_length - sp->base_len;
                    if (myname_len > MAX_OID_LEN) {
                        snmp_log(LOG_WARNING,
                                 "proxy OID return length too long.\n");
                        netsnmp_set_request_error(cache->reqinfo, requests,
                                                  SNMP_ERR_GENERR);
                        if (pdu)
                            snmp_free_pdu(pdu);
                        netsnmp_free_delegated_cache(cache);
                        return 1;
                    }

                    if (var->name_length > sp->base_len)
                        memcpy(&myname[sp->name_len],
                               &var->name[sp->base_len],
                               sizeof(oid) * (var->name_length -
                                              sp->base_len));
                    snmp_set_var_objid(request->requestvb, myname,
                                       myname_len);
                } else {
                    snmp_set_var_objid(request->requestvb, var->name,
                                       var->name_length);
                }
            }
        }

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

        /* fix bulk_to_next operations */
        if (cache->reqinfo->mode == MODE_GETBULK)
            netsnmp_bulk_to_next_fix_requests(requests);
        
        /*
         * free the response 
         */
        if (pdu && 0)
            snmp_free_pdu(pdu);
	break;

    default:
        DEBUGMSGTL(("proxy", "no response received: op = %d\n",
                    operation));
	break;
    }

    netsnmp_free_delegated_cache(cache);
    return 1;
}
