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

#include <stdio.h>
#include <sys/types.h>
#include <ctype.h>
#include <errno.h>

#ifdef WIN32
#include <net-snmp/library/winpipe.h>
#endif
#if HAVE_STRING_H
#include <string.h>
#else
#include <strings.h>
#endif
#if HAVE_STDLIB_H
#include <stdlib.h>
#endif
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#if HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#if HAVE_SYS_UN_H
#include <sys/un.h>
#endif
#if HAVE_IO_H
#include <io.h>
#endif
#if HAVE_FCNTL_H
#include <fcntl.h>
#endif

#if HAVE_DMALLOC_H
#include <dmalloc.h>
#endif

#include <net-snmp/types.h>
#include <net-snmp/output_api.h>
#include <net-snmp/config_api.h>
#include <net-snmp/utilities.h>

#include <net-snmp/library/snmp_transport.h>
#include <net-snmp/library/snmpUnixDomain.h>
#include <net-snmp/library/snmp_api.h>
#include <net-snmp/library/snmp_client.h>
#include <net-snmp/library/snmpCallbackDomain.h>

#ifndef NETSNMP_STREAM_QUEUE_LEN
#define NETSNMP_STREAM_QUEUE_LEN  5
#endif

#ifdef NETSNMP_TRANSPORT_CALLBACK_DOMAIN

static netsnmp_transport_list *trlist = NULL;

static int      callback_count = 0;

typedef struct callback_hack_s {
    void           *orig_transport_data;
    netsnmp_pdu    *pdu;
} callback_hack;

typedef struct callback_queue_s {
    int             callback_num;
    netsnmp_callback_pass *item;
    struct callback_queue_s *next, *prev;
} callback_queue;

callback_queue *thequeue;

static netsnmp_transport *
find_transport_from_callback_num(int num)
{
    static netsnmp_transport_list *ptr;
    for (ptr = trlist; ptr; ptr = ptr->next)
        if (((netsnmp_callback_info *) ptr->transport->data)->
            callback_num == num)
            return ptr->transport;
    return NULL;
}

static void
callback_debug_pdu(const char *ourstring, netsnmp_pdu *pdu)
{
    netsnmp_variable_list *vb;
    int             i = 1;
    DEBUGMSGTL((ourstring,
                "PDU: command = %d, errstat = %d, errindex = %d\n",
                pdu->command, pdu->errstat, pdu->errindex));
    for (vb = pdu->variables; vb; vb = vb->next_variable) {
        DEBUGMSGTL((ourstring, "  var %d:", i++));
        DEBUGMSGVAR((ourstring, vb));
        DEBUGMSG((ourstring, "\n"));
    }
}

void
callback_push_queue(int num, netsnmp_callback_pass *item)
{
    callback_queue *newitem = SNMP_MALLOC_TYPEDEF(callback_queue);
    callback_queue *ptr;

    newitem->callback_num = num;
    newitem->item = item;
    if (thequeue) {
        for (ptr = thequeue; ptr && ptr->next; ptr = ptr->next) {
        }
        ptr->next = newitem;
        newitem->prev = ptr;
    } else {
        thequeue = newitem;
    }
    DEBUGIF("dump_send_callback_transport") {
        callback_debug_pdu("dump_send_callback_transport", item->pdu);
    }
}

netsnmp_callback_pass *
callback_pop_queue(int num)
{
    netsnmp_callback_pass *cp;
    callback_queue *ptr;

    for (ptr = thequeue; ptr; ptr = ptr->next) {
        if (ptr->callback_num == num) {
            if (ptr->prev) {
                ptr->prev->next = ptr->next;
            } else {
                thequeue = ptr->next;
            }
            if (ptr->next) {
                ptr->next->prev = ptr->prev;
            }
            cp = ptr->item;
            SNMP_FREE(ptr);
            DEBUGIF("dump_recv_callback_transport") {
                callback_debug_pdu("dump_recv_callback_transport",
                                   cp->pdu);
            }
            return cp;
        }
    }
    return NULL;
}

/*
 * Return a string representing the address in data, or else the "far end"
 * address if data is NULL.  
 */

char *
netsnmp_callback_fmtaddr(netsnmp_transport *t, void *data, int len)
{
    char buf[SPRINT_MAX_LEN];
    netsnmp_callback_info *mystuff;

    if (!t)
        return strdup("callback: unknown");

    mystuff = (netsnmp_callback_info *) t->data;

    if (!mystuff)
        return strdup("callback: unknown");

    snprintf(buf, SPRINT_MAX_LEN, "callback: %d on fd %d",
             mystuff->callback_num, mystuff->pipefds[0]);
    return strdup(buf);
}



/*
 * You can write something into opaque that will subsequently get passed back 
 * to your send function if you like.  For instance, you might want to
 * remember where a PDU came from, so that you can send a reply there...  
 */

int
netsnmp_callback_recv(netsnmp_transport *t, void *buf, int size,
		      void **opaque, int *olength)
{
    int rc = -1;
    char newbuf[1];
    netsnmp_callback_info *mystuff = (netsnmp_callback_info *) t->data;

    DEBUGMSGTL(("transport_callback", "hook_recv enter\n"));

    while (rc < 0) {
#ifdef WIN32
	rc = recvfrom(mystuff->pipefds[0], newbuf, 1, 0, NULL, 0);
#else
	rc = read(mystuff->pipefds[0], newbuf, 1);
#endif
	if (rc < 0 && errno != EINTR) {
	    break;
	}
    }
    if (rc > 0)
        memset(buf, 0, rc);

    if (mystuff->linkedto) {
        /*
         * we're the client.  We don't need to do anything. 
         */
    } else {
        /*
         * malloc the space here, but it's filled in by
         * snmp_callback_created_pdu() below 
         */
        int            *returnnum = (int *) calloc(1, sizeof(int));
        *opaque = returnnum;
        *olength = sizeof(int);
    }
    DEBUGMSGTL(("transport_callback", "hook_recv exit\n"));
    return rc;
}



int
netsnmp_callback_send(netsnmp_transport *t, void *buf, int size,
		      void **opaque, int *olength)
{
    int from, rc = -1;
    netsnmp_callback_info *mystuff = (netsnmp_callback_info *) t->data;
    netsnmp_callback_pass *cp;

    /*
     * extract the pdu from the hacked buffer 
     */
    netsnmp_transport *other_side;
    callback_hack  *ch = (callback_hack *) * opaque;
    netsnmp_pdu    *pdu = ch->pdu;
    *opaque = ch->orig_transport_data;
    SNMP_FREE(ch);

    DEBUGMSGTL(("transport_callback", "hook_send enter\n"));

    cp = SNMP_MALLOC_TYPEDEF(netsnmp_callback_pass);
    if (!cp)
        return -1;

    cp->pdu = snmp_clone_pdu(pdu);
    if (cp->pdu->transport_data) {
        /*
         * not needed and not properly freed later 
         */
        SNMP_FREE(cp->pdu->transport_data);
    }

    if (cp->pdu->flags & UCD_MSG_FLAG_EXPECT_RESPONSE)
        cp->pdu->flags ^= UCD_MSG_FLAG_EXPECT_RESPONSE;

    /*
     * push the sent pdu onto the stack 
     */
    /*
     * AND send a bogus byte to the remote callback receiver's pipe 
     */
    if (mystuff->linkedto) {
        /*
         * we're the client, send it to the parent 
         */
        cp->return_transport_num = mystuff->callback_num;

        other_side = find_transport_from_callback_num(mystuff->linkedto);
        if (!other_side) {
            snmp_free_pdu(cp->pdu);
            SNMP_FREE(cp);
            return -1;
        }

	while (rc < 0) {
#ifdef WIN32
	    rc = sendto(((netsnmp_callback_info*) other_side->data)->pipefds[1], " ", 1, 0, NULL, 0);
#else
	    rc = write(((netsnmp_callback_info *)other_side->data)->pipefds[1],
		       " ", 1);
#endif
	    if (rc < 0 && errno != EINTR) {
		break;
	    }
	}
        callback_push_queue(mystuff->linkedto, cp);
        /*
         * we don't need the transport data any more 
         */
        if (*opaque) {
            SNMP_FREE(*opaque);
            *opaque = NULL;
        }
    } else {
        /*
         * we're the server, send it to the person that sent us the request 
         */
        from = **((int **) opaque);
        /*
         * we don't need the transport data any more 
         */
        if (*opaque) {
            SNMP_FREE(*opaque);
            *opaque = NULL;
        }
        other_side = find_transport_from_callback_num(from);
        if (!other_side) {
            snmp_free_pdu(cp->pdu);
            SNMP_FREE(cp);
            return -1;
        }
	while (rc < 0) {
#ifdef WIN32
	    rc = sendto(((netsnmp_callback_info*) other_side->data)->pipefds[1], " ", 1, 0, NULL, 0);
#else
	    rc = write(((netsnmp_callback_info *)other_side->data)->pipefds[1],
		       " ", 1);
#endif
	    if (rc < 0 && errno != EINTR) {
		break;
	    }
	}
        callback_push_queue(from, cp);
    }

    DEBUGMSGTL(("transport_callback", "hook_send exit\n"));
    return 0;
}



int
netsnmp_callback_close(netsnmp_transport *t)
{
    int             rc;
    netsnmp_callback_info *mystuff = (netsnmp_callback_info *) t->data;
    DEBUGMSGTL(("transport_callback", "hook_close enter\n"));

#ifdef WIN32
    rc  = closesocket(mystuff->pipefds[0]);
    rc |= closesocket(mystuff->pipefds[1]);
#else
    rc  = close(mystuff->pipefds[0]);
    rc |= close(mystuff->pipefds[1]);
#endif

    rc |= netsnmp_transport_remove_from_list(&trlist, t);

    DEBUGMSGTL(("transport_callback", "hook_close exit\n"));
    return rc;
}



int
netsnmp_callback_accept(netsnmp_transport *t)
{
    DEBUGMSGTL(("transport_callback", "hook_accept enter\n"));
    DEBUGMSGTL(("transport_callback", "hook_accept exit\n"));
    return 0;
}



/*
 * Open a Callback-domain transport for SNMP.  Local is TRUE if addr
 * is the local address to bind to (i.e. this is a server-type
 * session); otherwise addr is the remote address to send things to
 * (and we make up a temporary name for the local end of the
 * connection).  
 */

netsnmp_transport *
netsnmp_callback_transport(int to)
{

    netsnmp_transport *t = NULL;
    netsnmp_callback_info *mydata;
    int             rc;

    /*
     * transport 
     */
    t = SNMP_MALLOC_TYPEDEF(netsnmp_transport);
    if (!t)
        return NULL;

    /*
     * our stuff 
     */
    mydata = SNMP_MALLOC_TYPEDEF(netsnmp_callback_info);
    mydata->linkedto = to;
    mydata->callback_num = ++callback_count;
    mydata->data = NULL;
    t->data = mydata;

#ifdef WIN32
    rc = create_winpipe_transport(mydata->pipefds);
#else
    rc = pipe(mydata->pipefds);
#endif
    t->sock = mydata->pipefds[0];

    if (rc) {
        SNMP_FREE(mydata);
        SNMP_FREE(t);
        return NULL;
    }

    t->f_recv    = netsnmp_callback_recv;
    t->f_send    = netsnmp_callback_send;
    t->f_close   = netsnmp_callback_close;
    t->f_accept  = netsnmp_callback_accept;
    t->f_fmtaddr = netsnmp_callback_fmtaddr;

    netsnmp_transport_add_to_list(&trlist, t);

    if (to)
        DEBUGMSGTL(("transport_callback", "initialized %d linked to %d\n",
                    mydata->callback_num, to));
    else
        DEBUGMSGTL(("transport_callback",
                    "initialized master listening on %d\n",
                    mydata->callback_num));
    return t;
}

int
netsnmp_callback_hook_parse(netsnmp_session * sp,
                            netsnmp_pdu *pdu,
                            u_char * packetptr, size_t len)
{
    if (SNMP_MSG_RESPONSE == pdu->command ||
        SNMP_MSG_REPORT == pdu->command)
        pdu->flags |= UCD_MSG_FLAG_RESPONSE_PDU;
    else
        pdu->flags &= (~UCD_MSG_FLAG_RESPONSE_PDU);

    return SNMP_ERR_NOERROR;
}

int
netsnmp_callback_hook_build(netsnmp_session * sp,
                            netsnmp_pdu *pdu, u_char * ptk, size_t * len)
{
    /*
     * very gross hack, as this is passed later to the transport_send
     * function 
     */
    callback_hack  *ch = SNMP_MALLOC_TYPEDEF(callback_hack);
    DEBUGMSGTL(("transport_callback", "hook_build enter\n"));
    ch->pdu = pdu;
    ch->orig_transport_data = pdu->transport_data;
    pdu->transport_data = ch;
    switch (pdu->command) {
    case SNMP_MSG_GETBULK:
        if (pdu->max_repetitions < 0) {
            sp->s_snmp_errno = SNMPERR_BAD_REPETITIONS;
            return -1;
        }
        if (pdu->non_repeaters < 0) {
            sp->s_snmp_errno = SNMPERR_BAD_REPEATERS;
            return -1;
        }
        break;
    case SNMP_MSG_RESPONSE:
    case SNMP_MSG_TRAP:
    case SNMP_MSG_TRAP2:
        pdu->flags &= (~UCD_MSG_FLAG_EXPECT_RESPONSE);
        /*
         * Fallthrough
         */
    default:
        if (pdu->errstat == SNMP_DEFAULT_ERRSTAT)
            pdu->errstat = 0;
        if (pdu->errindex == SNMP_DEFAULT_ERRINDEX)
            pdu->errindex = 0;
        break;
    }

    /*
     * Copy missing values from session defaults
     */
    switch (pdu->version) {
#ifndef NETSNMP_DISABLE_SNMPV1
    case SNMP_VERSION_1:
#endif
#ifndef NETSNMP_DISABLE_SNMPV2C
    case SNMP_VERSION_2c:
#endif
#if !defined(NETSNMP_DISABLE_SNMPV1) || !defined(NETSNMP_DISABLE_SNMPV2C)
        if (pdu->community_len == 0) {
            if (sp->community_len == 0) {
                sp->s_snmp_errno = SNMPERR_BAD_COMMUNITY;
                return -1;
            }
            pdu->community = (u_char *) malloc(sp->community_len);
            if (pdu->community == NULL) {
                sp->s_snmp_errno = SNMPERR_MALLOC;
                return -1;
            }
            memmove(pdu->community,
                    sp->community, sp->community_len);
            pdu->community_len = sp->community_len;
        }
        break;
#endif
    case SNMP_VERSION_3:
        if (pdu->securityNameLen == 0) {
	  pdu->securityName = (char *)malloc(sp->securityNameLen);
            if (pdu->securityName == NULL) {
                sp->s_snmp_errno = SNMPERR_MALLOC;
                return -1;
            }
            memmove(pdu->securityName,
                     sp->securityName, sp->securityNameLen);
            pdu->securityNameLen = sp->securityNameLen;
        }
        if (pdu->securityModel == -1)
            pdu->securityModel = sp->securityModel;
        if (pdu->securityLevel == 0)
            pdu->securityLevel = sp->securityLevel;
        /* WHAT ELSE ?? */
    }
    ptk[0] = 0;
    *len = 1;
    DEBUGMSGTL(("transport_callback", "hook_build exit\n"));
    return 1;
}

int
netsnmp_callback_check_packet(u_char * pkt, size_t len)
{
    return 1;
}

netsnmp_pdu    *
netsnmp_callback_create_pdu(netsnmp_transport *transport,
                            void *opaque, size_t olength)
{
    netsnmp_pdu    *pdu;
    netsnmp_callback_pass *cp =
        callback_pop_queue(((netsnmp_callback_info *) transport->data)->
                           callback_num);
    if (!cp)
        return NULL;
    pdu = cp->pdu;
    pdu->transport_data = opaque;
    pdu->transport_data_length = olength;
    if (opaque)                 /* if created, we're the server */
        *((int *) opaque) = cp->return_transport_num;
    SNMP_FREE(cp);
    return pdu;
}

netsnmp_session *
netsnmp_callback_open(int attach_to,
                      int (*return_func) (int op,
                                          netsnmp_session * session,
                                          int reqid, netsnmp_pdu *pdu,
                                          void *magic),
                      int (*fpre_parse) (netsnmp_session *,
                                         struct netsnmp_transport_s *,
                                         void *, int),
                      int (*fpost_parse) (netsnmp_session *, netsnmp_pdu *,
                                          int))
{
    netsnmp_session callback_sess, *callback_ss;
    netsnmp_transport *callback_tr;

    callback_tr = netsnmp_callback_transport(attach_to);
    snmp_sess_init(&callback_sess);
    callback_sess.callback = return_func;
    if (attach_to) {
        /*
         * client 
         */
        /*
         * trysess.community = (u_char *) callback_ss; 
         */
    } else {
        callback_sess.isAuthoritative = SNMP_SESS_AUTHORITATIVE;
    }
    callback_sess.remote_port = 0;
    callback_sess.retries = 0;
    callback_sess.timeout = 30000000;
    callback_sess.version = SNMP_DEFAULT_VERSION;       /* (mostly) bogus */
    callback_ss = snmp_add_full(&callback_sess, callback_tr,
                                fpre_parse,
                                netsnmp_callback_hook_parse, fpost_parse,
                                netsnmp_callback_hook_build,
                                NULL,
                                netsnmp_callback_check_packet,
                                netsnmp_callback_create_pdu);
    if (callback_ss)
        callback_ss->local_port =
            ((netsnmp_callback_info *) callback_tr->data)->callback_num;
    return callback_ss;
}



void
netsnmp_clear_callback_list(void)
{

    netsnmp_transport_list *list = trlist, *next = NULL;
    netsnmp_transport *tr = NULL;

    DEBUGMSGTL(("callback_clear", "called netsnmp_callback_clear_list()\n"));
    while (list != NULL) {
	next = list->next;
	tr = list->transport;

	if (tr != NULL) {
	    tr->f_close(tr);
  	    netsnmp_transport_remove_from_list(&trlist, tr);
	    netsnmp_transport_free(tr);
	}
	list = next;
    }
    trlist = NULL;

}

#endif /* NETSNMP_TRANSPORT_CALLBACK_DOMAIN */
