/* 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",
                        (int)ourlength, (int)sp->base_len, (int)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 = %8p\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 (%ld)\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 %ld\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) != ", (int)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) != ", (int)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;
}
