/*
 *  udpEndpointTable 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/library/file_utils.h>
#include <net-snmp/library/text_utils.h>

#include <net-snmp/data_access/ipaddress.h>
#include <net-snmp/data_access/udp_endpoint.h>

#include "udp-mib/udpEndpointTable/udpEndpointTable_constants.h"
#include "mibgroup/util_funcs/get_pid_from_inode.h"
#include "udp_endpoint_private.h"

#include <fcntl.h>

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_udp_endpoint_entry_init(netsnmp_udp_endpoint_entry *entry)
{
    /*
     * init
     */
    return 0;
}

/*
 * cleanup arch specific storage
 */
void
netsnmp_arch_udp_endpoint_entry_cleanup(netsnmp_udp_endpoint_entry *entry)
{
    /*
     * cleanup
     */
}

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

/*
 * delete an entry
 */
int
netsnmp_arch_udp_endpoint_delete(netsnmp_udp_endpoint_entry *entry)
{
    if (NULL == entry)
        return -1;
    /** xxx-rks:9 udp_endpoint delete not implemented */
    return -1;
}


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

    rc = _load4(container, load_flags);
    if(rc < 0) {
        u_int flags = NETSNMP_ACCESS_UDP_ENDPOINT_FREE_KEEP_CONTAINER;
        netsnmp_access_udp_endpoint_container_free(container, flags);
        return rc;
    }

#if defined (NETSNMP_ENABLE_IPV6)
    rc = _load6(container, load_flags);
    if(rc < 0) {
        u_int flags = NETSNMP_ACCESS_UDP_ENDPOINT_FREE_KEEP_CONTAINER;
        netsnmp_access_udp_endpoint_container_free(container, flags);
        return rc;
    }
#endif

    return 0;
}

/**
 * @internal
 * process token value index line
 */
static int
_process_line_udp_ep(netsnmp_line_info *line_info, void *mem,
                     struct netsnmp_line_process_info_s* lpi)
{
    netsnmp_udp_endpoint_entry *ep = (netsnmp_udp_endpoint_entry *)mem;
    char                 *ptr, *sep;
    u_char               *u_ptr;
    size_t                u_ptr_len, offset, len;
    unsigned long long    inode;
    size_t                count = 0;

    /*
     * skip 'sl'
     */
    ptr = skip_not_white(line_info->start);
    if (NULL == ptr) {
        DEBUGMSGTL(("access:udp_endpoint", "no sl '%s'\n",
                       line_info->start));
        return PMLP_RC_MEMORY_UNUSED;
    }
    ptr = skip_white(ptr);
    if (NULL == ptr) {
        DEBUGMSGTL(("text:util:tvi", "no space after sl '%s'\n",
                    line_info->start));
        return PMLP_RC_MEMORY_UNUSED;
    }

    /*
     * get local address. ignore error on hex conversion, since that
     * function doesn't like the ':' between address and port. check the
     * offset to see if it worked. May need to flip string too.
     */
    u_ptr = ep->loc_addr;
    u_ptr_len = sizeof(ep->loc_addr);
    sep = strchr(ptr, ':');
    if (NULL == sep) {
        DEBUGMSGTL(("text:util:tvi", "no ':' '%s'\n",
                    line_info->start));
        return PMLP_RC_MEMORY_UNUSED;
    }
    len = (sep - ptr);
    if (-1 == netsnmp_addrstr_hton(ptr, len)) {
        DEBUGMSGTL(("text:util:tvi", "bad length %d for loc addr '%s'\n",
                    (int)u_ptr_len, line_info->start));
        return PMLP_RC_MEMORY_UNUSED;
    }
    offset = 0;
    netsnmp_hex_to_binary(&u_ptr, &u_ptr_len, &offset, 0, ptr, NULL);
    if ((4 != offset) && (16 != offset)) {
        DEBUGMSGTL(("text:util:tvi", "bad offset %d for loc addr '%s'\n",
                    (int)offset, line_info->start));
        return PMLP_RC_MEMORY_UNUSED;
    }
    ep->loc_addr_len = offset;
    ptr += (offset * 2);
    ++ptr; /* skip ':' */

    /*
     * get local port
     */
    ep->loc_port = strtol(ptr, &ptr, 16);
    ptr = skip_white(ptr);

    /*
     * get remote address. ignore error on hex conversion, since that
     * function doesn't like the ':' between address and port. check the
     * offset to see if it worked. May need to flip string too.
     */
    u_ptr = ep->rmt_addr;
    u_ptr_len = sizeof(ep->rmt_addr);
    sep = strchr(ptr, ':');
    if (NULL == sep) {
        DEBUGMSGTL(("text:util:tvi", "no ':' '%s'\n",
                    line_info->start));
        return PMLP_RC_MEMORY_UNUSED;
    }
    len = (sep - ptr);
    if (-1 == netsnmp_addrstr_hton(ptr, len)) {
        DEBUGMSGTL(("text:util:tvi", "bad length %d for rmt addr '%s'\n",
                    (int)u_ptr_len, line_info->start));
        return PMLP_RC_MEMORY_UNUSED;
    }
    offset = 0;
    netsnmp_hex_to_binary(&u_ptr, &u_ptr_len, &offset, 0, ptr, NULL);
    if ((4 != offset) && (16 != offset)) {
        DEBUGMSGTL(("text:util:tvi", "bad offset %d for rmt addr '%s'\n",
                    (int)offset, line_info->start));
        return PMLP_RC_MEMORY_UNUSED;
    }
    ep->rmt_addr_len = offset;
    ptr += (offset * 2);
    ++ptr; /* skip ':' */

    /*
     * get remote port
     */
    ep->rmt_port = strtol(ptr, &ptr, 16);
    ptr = skip_white(ptr);

    /*
     * get state too
     */
    ep->state = strtol(ptr, &ptr, 16);

    /*
     * Use inode as instance value.
     */
    while (count != 5) {
	ptr = skip_white(ptr);
	ptr = skip_not_white(ptr);
	count++;
    }
    inode = strtoull(ptr, &ptr, 0);
    ep->instance = (u_int)inode;

    /*
     * get the pid also
     */
    ep->pid = netsnmp_get_pid_from_inode(inode);

    ep->index = (uintptr_t)(lpi->user_context);
    lpi->user_context = (void*)((char*)(lpi->user_context) + 1);

    ep->oid_index.oids = &ep->index;
    ep->oid_index.len = 1;

    return PMLP_RC_MEMORY_USED;
}

/**
 *
 * @retval  0 no errors
 * @retval !0 errors
 */
static int
_load4(netsnmp_container *container, u_int load_flags)
{
    netsnmp_file              *fp;
    netsnmp_line_process_info  lpi;

    if (NULL == container)
        return -1;

    /*
     * allocate file resources
     */
    fp = netsnmp_file_fill(NULL, "/proc/net/udp" , O_RDONLY, 0, 0);
    if (NULL == fp) /** msg already logged */
        return -2;
    
    memset(&lpi, 0x0, sizeof(lpi));
    lpi.mem_size = sizeof(netsnmp_udp_endpoint_entry);
    lpi.process = _process_line_udp_ep;
    lpi.user_context = (void*)0;

    container = netsnmp_file_text_parse(fp, container, PM_USER_FUNCTION,
                                        0, &lpi);
    netsnmp_file_release(fp);
    return (NULL == container);
}

#if defined (NETSNMP_ENABLE_IPV6)
/**
 *
 * @retval  0 no errors
 * @retval !0 errors
 */
static int
_load6(netsnmp_container *container, u_int load_flags)
{
    netsnmp_file              *fp;
    netsnmp_line_process_info  lpi;

    if (NULL == container)
        return -1;

    /*
     * allocate file resources
     */
    fp = netsnmp_file_fill(NULL, "/proc/net/udp6" , O_RDONLY, 0, 0);
    if (NULL == fp) /** msg already logged */
        return -2;
    
    memset(&lpi, 0x0, sizeof(lpi));
    lpi.mem_size = sizeof(netsnmp_udp_endpoint_entry);
    lpi.process = _process_line_udp_ep;
    lpi.user_context = (void*)CONTAINER_SIZE(container);

    container = netsnmp_file_text_parse(fp, container, PM_USER_FUNCTION,
                                        0, &lpi);
    netsnmp_file_release(fp);
    return (NULL == container);
}
#endif /* NETSNMP_ENABLE_IPV6 */
