/*
 *  tcpConnTable MIB architecture support
 *
 * $Id$
 */
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>

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

#include "tcp-mib/tcpConnectionTable/tcpConnectionTable_constants.h"
#include "tcp-mib/data_access/tcpConn_private.h"
#include "mibgroup/util_funcs/get_pid_from_inode.h"
static int
linux_states[12] = { 1, 5, 3, 4, 6, 7, 11, 1, 8, 9, 2, 10 };

static int _load4(netsnmp_container *container, u_int flags);
#if defined (NETSNMP_ENABLE_IPV6)
static int _load6(netsnmp_container *container, u_int flags);
#endif

/*
 * initialize arch specific storage
 *
 * @retval  0: success
 * @retval <0: error
 */
int
netsnmp_arch_tcpconn_entry_init(netsnmp_tcpconn_entry *entry)
{
    /*
     * init
     */
    return 0;
}

/*
 * cleanup arch specific storage
 */
void
netsnmp_arch_tcpconn_entry_cleanup(netsnmp_tcpconn_entry *entry)
{
    /*
     * cleanup
     */
}

/*
 * copy arch specific storage
 */
int
netsnmp_arch_tcpconn_entry_copy(netsnmp_tcpconn_entry *lhs,
                                  netsnmp_tcpconn_entry *rhs)
{
    return 0;
}

/*
 * delete an entry
 */
int
netsnmp_arch_tcpconn_delete(netsnmp_tcpconn_entry *entry)
{
    if (NULL == entry)
        return -1;
    /** xxx-rks:9 tcpConn delete not implemented */
    return -1;
}


/**
 *
 * @retval  0 no errors
 * @retval !0 errors
 */
int
netsnmp_arch_tcpconn_container_load(netsnmp_container *container,
                                    u_int load_flags )
{
    int rc = 0;

    DEBUGMSGTL(("access:tcpconn:container",
                "tcpconn_container_arch_load (flags %x)\n", load_flags));

    if (NULL == container) {
        snmp_log(LOG_ERR, "no container specified/found for access_tcpconn\n");
        return -1;
    }

    rc = _load4(container, load_flags);

#if defined (NETSNMP_ENABLE_IPV6)
    if((0 != rc) || (load_flags & NETSNMP_ACCESS_TCPCONN_LOAD_IPV4_ONLY))
        return rc;

    /*
     * load ipv6. ipv6 module might not be loaded,
     * so ignore -2 err (file not found)
     */
    rc = _load6(container, load_flags);
    if (-2 == rc)
        rc = 0;
#endif

    return rc;
}

/**
 *
 * @retval  0 no errors
 * @retval !0 errors
 */
static int
_load4(netsnmp_container *container, u_int load_flags)
{
    int             rc = 0;
    FILE           *in;
    char            line[160];
    
    netsnmp_assert(NULL != container);

#define PROCFILE "/proc/net/tcp"
    if (!(in = fopen(PROCFILE, "r"))) {
        snmp_log(LOG_ERR,"could not open " PROCFILE "\n");
        return -2;
    }
    
    fgets(line, sizeof(line), in); /* skip header */

    /*
     *   sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode
     *   0: 00000000:8000 00000000:0000 0A 00000000:00000000 00:00000000 00000000    29        0 1028 1 df7b1b80 300 0 0 2 -1
     */
    while (fgets(line, sizeof(line), in)) {
        netsnmp_tcpconn_entry *entry;
        int             state, rc, local_port, remote_port, tmp_state;
        unsigned long long inode;
        size_t          buf_len, offset;
        char            local_addr[10], remote_addr[10];
        u_char         *tmp_ptr;

        if (6 != (rc = sscanf(line, "%*d: %8[0-9A-Z]:%x %8[0-9A-Z]:%x %x %*x:%*x %*x:%*x %*x %*x %*x %llu",
                              local_addr, &local_port,
                              remote_addr, &remote_port, &tmp_state, &inode))) {
            DEBUGMSGT(("access:tcpconn:container",
                       "error parsing line (%d != 6)\n", rc));
            DEBUGMSGT(("access:tcpconn:container"," line '%s'\n", line));
	    snmp_log(LOG_ERR, "tcp:_load4: bad line in " PROCFILE ": %s\n", line);
	    rc = 0;
            continue;
        }
        DEBUGMSGT(("verbose:access:tcpconn:container"," line '%s'\n", line));

        /*
         * check if we care about listen state
         */
        state = (tmp_state & 0xf) < 12 ? linux_states[tmp_state & 0xf] : 2;
        if (load_flags) {
            if (TCPCONNECTIONSTATE_LISTEN == state) {
                if (load_flags & NETSNMP_ACCESS_TCPCONN_LOAD_NOLISTEN) {
                    DEBUGMSGT(("verbose:access:tcpconn:container",
                               " skipping listen\n"));
                    continue;
                }
            }
            else if (load_flags & NETSNMP_ACCESS_TCPCONN_LOAD_ONLYLISTEN) {
                    DEBUGMSGT(("verbose:access:tcpconn:container",
                               " skipping non-listen\n"));
                    continue;
            }
        }

        /*
         */
        entry = netsnmp_access_tcpconn_entry_create();
        if(NULL == entry) {
            rc = -3;
            break;
        }

        /** oddly enough, these appear to already be in network order */
        entry->loc_port = (unsigned short) local_port;
        entry->rmt_port = (unsigned short) remote_port;
        entry->tcpConnState = state;
        entry->pid = netsnmp_get_pid_from_inode(inode);
        
        /** the addr string may need work */
        buf_len = strlen(local_addr);
        if ((8 != buf_len) ||
            (-1 == netsnmp_addrstr_hton(local_addr, 8))) {
            DEBUGMSGT(("verbose:access:tcpconn:container",
                       " error processing local address\n"));
            netsnmp_access_tcpconn_entry_free(entry);
            continue;
        }
        offset = 0;
        tmp_ptr = entry->loc_addr;
        rc = netsnmp_hex_to_binary(&tmp_ptr, &buf_len,
                                   &offset, 0, local_addr, NULL);
        entry->loc_addr_len = offset;
        if ( 4 != entry->loc_addr_len ) {
            DEBUGMSGT(("access:tcpconn:container",
                       "error parsing local addr (%d != 4)\n",
                       entry->loc_addr_len));
            DEBUGMSGT(("access:tcpconn:container"," line '%s'\n", line));
            netsnmp_access_tcpconn_entry_free(entry);
            continue;
        }

        /** the addr string may need work */
        buf_len = strlen((char*)remote_addr);
        if ((8 != buf_len) ||
            (-1 == netsnmp_addrstr_hton(remote_addr, 8))) {
            DEBUGMSGT(("verbose:access:tcpconn:container",
                       " error processing remote address\n"));
            netsnmp_access_tcpconn_entry_free(entry);
            continue;
        }
        offset = 0;
        tmp_ptr = entry->rmt_addr;
        rc = netsnmp_hex_to_binary(&tmp_ptr, &buf_len,
                                   &offset, 0, remote_addr, NULL);
        entry->rmt_addr_len = offset;
        if ( 4 != entry->rmt_addr_len ) {
            DEBUGMSGT(("access:tcpconn:container",
                       "error parsing remote addr (%d != 4)\n",
                       entry->rmt_addr_len));
            DEBUGMSGT(("access:tcpconn:container"," line '%s'\n", line));
            netsnmp_access_tcpconn_entry_free(entry);
            continue;
        }

        /*
         * add entry to container
         */
        entry->arbitrary_index = CONTAINER_SIZE(container) + 1;
        CONTAINER_INSERT(container, entry);
    }

    fclose(in);

    if(rc<0)
        return rc;

    return 0;
}

#if defined (NETSNMP_ENABLE_IPV6)
/**
 *
 * @retval  0 no errors
 * @retval !0 errors
 */
static int
_load6(netsnmp_container *container, u_int load_flags)
{
    int             rc = 0;
    FILE           *in;
    char            line[360];

    netsnmp_assert(NULL != container);

#undef PROCFILE
#define PROCFILE "/proc/net/tcp6"
    if (!(in = fopen(PROCFILE, "r"))) {
        DEBUGMSGTL(("access:tcpconn:container","could not open " PROCFILE "\n"));
        return -2;
    }

    fgets(line, sizeof(line), in); /* skip header */

    /*
     * Note: PPC (big endian)
     *
     *   sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode
     *  0: 00000000000000000000000000000001:1466 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000   500        0 326699 1 efb81580 3000 0 0 2 -1
     */
    while (fgets(line, sizeof(line), in)) {
        netsnmp_tcpconn_entry *entry;
        int             state, local_port, remote_port, tmp_state;
        unsigned long long  inode;
        size_t          buf_len, offset;
        char            local_addr[48], remote_addr[48];
        u_char         *tmp_ptr;

        if (6 != (rc = sscanf(line, "%*d: %47[0-9A-Z]:%x %47[0-9A-Z]:%x %x %*x:%*x %*x:%*x %*x %*x %*x %llu",
                              local_addr, &local_port,
                              remote_addr, &remote_port, &tmp_state, &inode))) {
            DEBUGMSGT(("access:tcpconn:container",
                       "error parsing line (%d != 6)\n", rc));
            DEBUGMSGT(("access:tcpconn:container"," line '%s'\n", line));
	    snmp_log(LOG_ERR, "tcp:_load6: bad line in " PROCFILE ": %s\n", line);
	    rc = 0;
            continue;
        }
        DEBUGMSGT(("verbose:access:tcpconn:container"," line '%s'\n", line));

        /*
         * check if we care about listen state
         */
        state = (tmp_state & 0xf) < 12 ? linux_states[tmp_state & 0xf] : 2;
        if (load_flags) {
            if (TCPCONNECTIONSTATE_LISTEN == state) {
                if (load_flags & NETSNMP_ACCESS_TCPCONN_LOAD_NOLISTEN) {
                    DEBUGMSGT(("verbose:access:tcpconn:container",
                               " skipping listen\n"));
                    continue;
                }
            }
            else if (load_flags & NETSNMP_ACCESS_TCPCONN_LOAD_ONLYLISTEN) {
                    DEBUGMSGT(("verbose:access:tcpconn:container",
                               " skipping non-listen\n"));
                    continue;
            }
        }

        /*
         */
        entry = netsnmp_access_tcpconn_entry_create();
        if(NULL == entry) {
            rc = -3;
            break;
        }

        /** oddly enough, these appear to already be in network order */
        entry->loc_port = (unsigned short) local_port;
        entry->rmt_port = (unsigned short) remote_port;
        entry->tcpConnState = state;
        entry->pid = netsnmp_get_pid_from_inode(inode);

        /** the addr string may need work */
        buf_len = strlen(local_addr);
        if ((32 != buf_len) ||
            (-1 == netsnmp_addrstr_hton(local_addr, 32))) {
            DEBUGMSGT(("verbose:access:tcpconn:container",
                       " error processing local address\n"));
            netsnmp_access_tcpconn_entry_free(entry);
            continue;
        }
        offset = 0;
        tmp_ptr = entry->loc_addr;
        rc = netsnmp_hex_to_binary(&tmp_ptr, &buf_len,
                                   &offset, 0, local_addr, NULL);
        entry->loc_addr_len = offset;
        if (( 16 != entry->loc_addr_len ) && ( 20 != entry->loc_addr_len )) {
            DEBUGMSGT(("access:tcpconn:container",
                       "error parsing local addr (%d != 16|20)\n",
                       entry->loc_addr_len));
            DEBUGMSGT(("access:tcpconn:container"," line '%s'\n", line));
            netsnmp_access_tcpconn_entry_free(entry);
            continue;
        }

        buf_len = strlen((char*)remote_addr);
        if ((32 != buf_len) ||
            (-1 == netsnmp_addrstr_hton(remote_addr, 32))) {
            DEBUGMSGT(("verbose:access:tcpconn:container",
                       " error processing remote address\n"));
            netsnmp_access_tcpconn_entry_free(entry);
            continue;
        }
        offset = 0;
        tmp_ptr = entry->rmt_addr;
        rc = netsnmp_hex_to_binary(&tmp_ptr, &buf_len,
                                   &offset, 0, remote_addr, NULL);
        entry->rmt_addr_len = offset;
        if (( 16 != entry->rmt_addr_len ) && ( 20 != entry->rmt_addr_len )) {
            DEBUGMSGT(("access:tcpconn:container",
                       "error parsing remote addr (%d != 16|20)\n",
                       entry->rmt_addr_len));
            DEBUGMSGT(("access:tcpconn:container"," line '%s'\n", line));
            netsnmp_access_tcpconn_entry_free(entry);
            continue;
        }


        /*
         * add entry to container
         */
        entry->arbitrary_index = CONTAINER_SIZE(container) + 1;
        CONTAINER_INSERT(container, entry);
    }

    fclose(in);

    if(rc<0)
        return rc;

    return 0;
}
#endif /* NETSNMP_ENABLE_IPV6 */
