/*							-- DO NOT EDIT --
 * This file has been generated by smidump
 * version 0.3.1 for the scli package.
 *
 * Derived from UDP-MIB:
 *   The MIB module for managing UDP implementations.
 *
 * Revision 1994-11-01 00:00:
 *   [Revision added by libsmi due to a LAST-UPDATED clause.]
 *
 * Revision 1991-03-31 00:00:
 *   The initial revision of this MIB module was part of MIB-
 *   II.
 *
 * $Id: udp-mib.c,v 1.19 2002/03/27 13:48:23 schoenw Exp $
 */

#include "udp-mib.h"

static guint16 udpLocalAddress_constraints[] = {4, 4, 0, 0};
static guint32 udpLocalPort_constraints[] = {0L, 65535L, 0, 0};


static guint32 const udp_oid[] = {1, 3, 6, 1, 2, 1, 7};

static GSnmpAttribute udp_attr[] = {
    { 1, G_SNMP_COUNTER32,
      UDP_MIB_UDPINDATAGRAMS, "udpInDatagrams",
       NULL,
      G_STRUCT_OFFSET(udp_mib_udp_t, udpInDatagrams),
      0,
      0 },
    { 2, G_SNMP_COUNTER32,
      UDP_MIB_UDPNOPORTS, "udpNoPorts",
       NULL,
      G_STRUCT_OFFSET(udp_mib_udp_t, udpNoPorts),
      0,
      0 },
    { 3, G_SNMP_COUNTER32,
      UDP_MIB_UDPINERRORS, "udpInErrors",
       NULL,
      G_STRUCT_OFFSET(udp_mib_udp_t, udpInErrors),
      0,
      0 },
    { 4, G_SNMP_COUNTER32,
      UDP_MIB_UDPOUTDATAGRAMS, "udpOutDatagrams",
       NULL,
      G_STRUCT_OFFSET(udp_mib_udp_t, udpOutDatagrams),
      0,
      0 },
    { 0, 0, 0, NULL }
};

static guint32 const udpEntry_oid[] = {1, 3, 6, 1, 2, 1, 7, 5, 1};

static GSnmpAttribute udpEntry_attr[] = {
    { 1, G_SNMP_IPADDRESS,
      UDP_MIB_UDPLOCALADDRESS, "udpLocalAddress",
       udpLocalAddress_constraints,
      -1,
      0,
      0 },
    { 2, G_SNMP_INTEGER32,
      UDP_MIB_UDPLOCALPORT, "udpLocalPort",
       udpLocalPort_constraints,
      -1,
      0,
      0 },
    { 0, 0, 0, NULL }
};


udp_mib_udp_t *
udp_mib_new_udp()
{
    udp_mib_udp_t *udp;

    udp = (udp_mib_udp_t *) g_malloc0(sizeof(udp_mib_udp_t) + sizeof(gpointer));
    return udp;
}

static udp_mib_udp_t *
assign_udp(GSList *vbl)
{
    udp_mib_udp_t *udp;
    char *p;

    udp = udp_mib_new_udp();
    if (! udp) {
        return NULL;
    }

    p = (char *) udp + sizeof(udp_mib_udp_t);
    * (GSList **) p = vbl;

    gsnmp_attr_assign(vbl, udp_oid, sizeof(udp_oid)/sizeof(guint32),
                      udp_attr, udp);

    return udp;
}

void
udp_mib_get_udp(GSnmpSession *s, udp_mib_udp_t **udp, gint mask)
{
    GSList *in = NULL, *out = NULL;
    static guint32 base[] = {1, 3, 6, 1, 2, 1, 7, 0};

    *udp = NULL;

    gsnmp_attr_get(s, &in, base, 8, 7, udp_attr, mask);

    out = g_snmp_session_sync_getnext(s, in);
    g_snmp_vbl_free(in);
    if (out) {
        if (s->error_status != G_SNMP_ERR_NOERROR) {
            g_snmp_vbl_free(out);
            return;
        }
        *udp = assign_udp(out);
    }
}

void
udp_mib_free_udp(udp_mib_udp_t *udp)
{
    GSList *vbl;
    char *p;

    if (udp) {
        p = (char *) udp + sizeof(udp_mib_udp_t);
        vbl = * (GSList **) p;
        g_snmp_vbl_free(vbl);
        g_free(udp);
    }
}

udp_mib_udpEntry_t *
udp_mib_new_udpEntry()
{
    udp_mib_udpEntry_t *udpEntry;

    udpEntry = (udp_mib_udpEntry_t *) g_malloc0(sizeof(udp_mib_udpEntry_t) + sizeof(gpointer));
    return udpEntry;
}

static int
unpack_udpEntry(GSnmpVarBind *vb, udp_mib_udpEntry_t *udpEntry)
{
    guint8 idx = 10;
    guint16 i, len;

    len = 4;
    if (vb->id_len < idx + len) return -1;
    if (len != 4) return -1;
    if (vb->id_len < idx + len) return -1;
    for (i = 0; i < len; i++) {
        udpEntry->udpLocalAddress[i] = vb->id[idx++];
    }
    if (vb->id_len < idx) return -1;
    udpEntry->udpLocalPort = vb->id[idx++];
    if (vb->id_len > idx) return -1;
    return 0;
}

static int
pack_udpEntry(guint32 *base, guchar *udpLocalAddress, gint32 udpLocalPort)
{
    guint8 idx = 10;
    guint16 i, len;

    len = 4;
    if (len != 4) return -1;
    for (i = 0; i < len; i++) {
        base[idx++] = udpLocalAddress[i];
        if (idx >= 128) return -1;
    }
    base[idx++] = udpLocalPort;
    return idx;
}

static udp_mib_udpEntry_t *
assign_udpEntry(GSList *vbl)
{
    udp_mib_udpEntry_t *udpEntry;
    char *p;

    udpEntry = udp_mib_new_udpEntry();
    if (! udpEntry) {
        return NULL;
    }

    p = (char *) udpEntry + sizeof(udp_mib_udpEntry_t);
    * (GSList **) p = vbl;

    if (unpack_udpEntry((GSnmpVarBind *) vbl->data, udpEntry) < 0) {
        g_warning("%s: invalid instance identifier", "udpEntry");
        g_free(udpEntry);
        return NULL;
    }

    gsnmp_attr_assign(vbl, udpEntry_oid, sizeof(udpEntry_oid)/sizeof(guint32),
                      udpEntry_attr, udpEntry);

    return udpEntry;
}

void
udp_mib_get_udpTable(GSnmpSession *s, udp_mib_udpEntry_t ***udpEntry, gint mask)
{
    GSList *in = NULL, *out = NULL;
    GSList *row;
    int i;
    static guint32 base[] = {1, 3, 6, 1, 2, 1, 7, 5, 1, 0};

    *udpEntry = NULL;

    gsnmp_attr_get(s, &in, base, 10, 9, udpEntry_attr, mask);

    out = gsnmp_gettable(s, in);
    /* g_snmp_vbl_free(in); */

    if (out) {
        *udpEntry = (udp_mib_udpEntry_t **) g_malloc0((g_slist_length(out) + 1) * sizeof(udp_mib_udpEntry_t *));
        if (! *udpEntry) {
            s->error_status = G_SNMP_ERR_INTERNAL;
            g_snmp_vbl_free(out);
            return;
        }
        for (row = out, i = 0; row; row = g_slist_next(row), i++) {
            (*udpEntry)[i] = assign_udpEntry(row->data);
        }
    }
}

void
udp_mib_get_udpEntry(GSnmpSession *s, udp_mib_udpEntry_t **udpEntry, guchar *udpLocalAddress, gint32 udpLocalPort, gint mask)
{
    GSList *in = NULL, *out = NULL;
    guint32 base[128];
    gint8 len;

    memset(base, 0, sizeof(base));
    memcpy(base, udpEntry_oid, sizeof(udpEntry_oid));
    len = pack_udpEntry(base, udpLocalAddress, udpLocalPort);
    if (len < 0) {
        g_warning("%s: invalid index values", "udpEntry");
        s->error_status = G_SNMP_ERR_INTERNAL;
        return;
    }

    *udpEntry = NULL;

    gsnmp_attr_get(s, &in, base, len, 9, udpEntry_attr, mask);

    out = g_snmp_session_sync_get(s, in);
    g_snmp_vbl_free(in);
    if (out) {
        if (s->error_status != G_SNMP_ERR_NOERROR) {
            g_snmp_vbl_free(out);
            return;
        }
        *udpEntry = assign_udpEntry(out);
    }
}

void
udp_mib_free_udpEntry(udp_mib_udpEntry_t *udpEntry)
{
    GSList *vbl;
    char *p;

    if (udpEntry) {
        p = (char *) udpEntry + sizeof(udp_mib_udpEntry_t);
        vbl = * (GSList **) p;
        g_snmp_vbl_free(vbl);
        g_free(udpEntry);
    }
}

void
udp_mib_free_udpTable(udp_mib_udpEntry_t **udpEntry)
{
    int i;

    if (udpEntry) {
        for (i = 0; udpEntry[i]; i++) {
            udp_mib_free_udpEntry(udpEntry[i]);
        }
        g_free(udpEntry);
    }
}


