/*							-- DO NOT EDIT --
 * This file has been generated by smidump
 * version 0.3.1 for the scli package.
 *
 * Derived from IP-MIB:
 *   The MIB module for managing IP and ICMP implementations,
 *   but excluding their management of IP routes.
 *
 * 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: ip-mib.c,v 1.20 2002/03/27 13:48:21 schoenw Exp $
 */

#include "ip-mib.h"

GSnmpEnum const ip_mib_enums_ipForwarding[] = {
    { IP_MIB_IPFORWARDING_FORWARDING,    "forwarding" },
    { IP_MIB_IPFORWARDING_NOTFORWARDING, "notForwarding" },
    { 0, NULL }
};

GSnmpEnum const ip_mib_enums_ipNetToMediaType[] = {
    { IP_MIB_IPNETTOMEDIATYPE_OTHER,   "other" },
    { IP_MIB_IPNETTOMEDIATYPE_INVALID, "invalid" },
    { IP_MIB_IPNETTOMEDIATYPE_DYNAMIC, "dynamic" },
    { IP_MIB_IPNETTOMEDIATYPE_STATIC,  "static" },
    { 0, NULL }
};


static guint32 ipDefaultTTL_constraints[] = {1L, 255L, 0, 0};
static guint32 ipAdEntIfIndex_constraints[] = {1L, 2147483647L, 0, 0};
static guint16 ipAdEntNetMask_constraints[] = {4, 4, 0, 0};
static guint32 ipAdEntBcastAddr_constraints[] = {0L, 1L, 0, 0};
static guint32 ipAdEntReasmMaxSize_constraints[] = {0L, 65535L, 0, 0};


static guint32 const ip_oid[] = {1, 3, 6, 1, 2, 1, 4};

static GSnmpAttribute ip_attr[] = {
    { 1, G_SNMP_INTEGER32,
      IP_MIB_IPFORWARDING, "ipForwarding",
       NULL,
      G_STRUCT_OFFSET(ip_mib_ip_t, ipForwarding),
      0,
      GSNMP_ATTR_FLAG_WRITABLE },
    { 2, G_SNMP_INTEGER32,
      IP_MIB_IPDEFAULTTTL, "ipDefaultTTL",
       ipDefaultTTL_constraints,
      G_STRUCT_OFFSET(ip_mib_ip_t, ipDefaultTTL),
      0,
      GSNMP_ATTR_FLAG_WRITABLE },
    { 3, G_SNMP_COUNTER32,
      IP_MIB_IPINRECEIVES, "ipInReceives",
       NULL,
      G_STRUCT_OFFSET(ip_mib_ip_t, ipInReceives),
      0,
      0 },
    { 4, G_SNMP_COUNTER32,
      IP_MIB_IPINHDRERRORS, "ipInHdrErrors",
       NULL,
      G_STRUCT_OFFSET(ip_mib_ip_t, ipInHdrErrors),
      0,
      0 },
    { 5, G_SNMP_COUNTER32,
      IP_MIB_IPINADDRERRORS, "ipInAddrErrors",
       NULL,
      G_STRUCT_OFFSET(ip_mib_ip_t, ipInAddrErrors),
      0,
      0 },
    { 6, G_SNMP_COUNTER32,
      IP_MIB_IPFORWDATAGRAMS, "ipForwDatagrams",
       NULL,
      G_STRUCT_OFFSET(ip_mib_ip_t, ipForwDatagrams),
      0,
      0 },
    { 7, G_SNMP_COUNTER32,
      IP_MIB_IPINUNKNOWNPROTOS, "ipInUnknownProtos",
       NULL,
      G_STRUCT_OFFSET(ip_mib_ip_t, ipInUnknownProtos),
      0,
      0 },
    { 8, G_SNMP_COUNTER32,
      IP_MIB_IPINDISCARDS, "ipInDiscards",
       NULL,
      G_STRUCT_OFFSET(ip_mib_ip_t, ipInDiscards),
      0,
      0 },
    { 9, G_SNMP_COUNTER32,
      IP_MIB_IPINDELIVERS, "ipInDelivers",
       NULL,
      G_STRUCT_OFFSET(ip_mib_ip_t, ipInDelivers),
      0,
      0 },
    { 10, G_SNMP_COUNTER32,
      IP_MIB_IPOUTREQUESTS, "ipOutRequests",
       NULL,
      G_STRUCT_OFFSET(ip_mib_ip_t, ipOutRequests),
      0,
      0 },
    { 11, G_SNMP_COUNTER32,
      IP_MIB_IPOUTDISCARDS, "ipOutDiscards",
       NULL,
      G_STRUCT_OFFSET(ip_mib_ip_t, ipOutDiscards),
      0,
      0 },
    { 12, G_SNMP_COUNTER32,
      IP_MIB_IPOUTNOROUTES, "ipOutNoRoutes",
       NULL,
      G_STRUCT_OFFSET(ip_mib_ip_t, ipOutNoRoutes),
      0,
      0 },
    { 13, G_SNMP_INTEGER32,
      IP_MIB_IPREASMTIMEOUT, "ipReasmTimeout",
       NULL,
      G_STRUCT_OFFSET(ip_mib_ip_t, ipReasmTimeout),
      0,
      0 },
    { 14, G_SNMP_COUNTER32,
      IP_MIB_IPREASMREQDS, "ipReasmReqds",
       NULL,
      G_STRUCT_OFFSET(ip_mib_ip_t, ipReasmReqds),
      0,
      0 },
    { 15, G_SNMP_COUNTER32,
      IP_MIB_IPREASMOKS, "ipReasmOKs",
       NULL,
      G_STRUCT_OFFSET(ip_mib_ip_t, ipReasmOKs),
      0,
      0 },
    { 16, G_SNMP_COUNTER32,
      IP_MIB_IPREASMFAILS, "ipReasmFails",
       NULL,
      G_STRUCT_OFFSET(ip_mib_ip_t, ipReasmFails),
      0,
      0 },
    { 17, G_SNMP_COUNTER32,
      IP_MIB_IPFRAGOKS, "ipFragOKs",
       NULL,
      G_STRUCT_OFFSET(ip_mib_ip_t, ipFragOKs),
      0,
      0 },
    { 18, G_SNMP_COUNTER32,
      IP_MIB_IPFRAGFAILS, "ipFragFails",
       NULL,
      G_STRUCT_OFFSET(ip_mib_ip_t, ipFragFails),
      0,
      0 },
    { 19, G_SNMP_COUNTER32,
      IP_MIB_IPFRAGCREATES, "ipFragCreates",
       NULL,
      G_STRUCT_OFFSET(ip_mib_ip_t, ipFragCreates),
      0,
      0 },
    { 23, G_SNMP_COUNTER32,
      IP_MIB_IPROUTINGDISCARDS, "ipRoutingDiscards",
       NULL,
      G_STRUCT_OFFSET(ip_mib_ip_t, ipRoutingDiscards),
      0,
      0 },
    { 0, 0, 0, NULL }
};

static guint32 const ipAddrEntry_oid[] = {1, 3, 6, 1, 2, 1, 4, 20, 1};

static GSnmpAttribute ipAddrEntry_attr[] = {
    { 2, G_SNMP_INTEGER32,
      IP_MIB_IPADENTIFINDEX, "ipAdEntIfIndex",
       ipAdEntIfIndex_constraints,
      G_STRUCT_OFFSET(ip_mib_ipAddrEntry_t, ipAdEntIfIndex),
      0,
      0 },
    { 3, G_SNMP_IPADDRESS,
      IP_MIB_IPADENTNETMASK, "ipAdEntNetMask",
       ipAdEntNetMask_constraints,
      G_STRUCT_OFFSET(ip_mib_ipAddrEntry_t, ipAdEntNetMask),
      0,
      0 },
    { 4, G_SNMP_INTEGER32,
      IP_MIB_IPADENTBCASTADDR, "ipAdEntBcastAddr",
       ipAdEntBcastAddr_constraints,
      G_STRUCT_OFFSET(ip_mib_ipAddrEntry_t, ipAdEntBcastAddr),
      0,
      0 },
    { 5, G_SNMP_INTEGER32,
      IP_MIB_IPADENTREASMMAXSIZE, "ipAdEntReasmMaxSize",
       ipAdEntReasmMaxSize_constraints,
      G_STRUCT_OFFSET(ip_mib_ipAddrEntry_t, ipAdEntReasmMaxSize),
      0,
      0 },
    { 0, 0, 0, NULL }
};

static guint32 const ipNetToMediaEntry_oid[] = {1, 3, 6, 1, 2, 1, 4, 22, 1};

static GSnmpAttribute ipNetToMediaEntry_attr[] = {
    { 2, G_SNMP_OCTETSTRING,
      IP_MIB_IPNETTOMEDIAPHYSADDRESS, "ipNetToMediaPhysAddress",
       NULL,
      G_STRUCT_OFFSET(ip_mib_ipNetToMediaEntry_t, ipNetToMediaPhysAddress),
      G_STRUCT_OFFSET(ip_mib_ipNetToMediaEntry_t, _ipNetToMediaPhysAddressLength),
      GSNMP_ATTR_FLAG_WRITABLE },
    { 4, G_SNMP_INTEGER32,
      IP_MIB_IPNETTOMEDIATYPE, "ipNetToMediaType",
       NULL,
      G_STRUCT_OFFSET(ip_mib_ipNetToMediaEntry_t, ipNetToMediaType),
      0,
      GSNMP_ATTR_FLAG_WRITABLE },
    { 0, 0, 0, NULL }
};

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

static GSnmpAttribute icmp_attr[] = {
    { 1, G_SNMP_COUNTER32,
      IP_MIB_ICMPINMSGS, "icmpInMsgs",
       NULL,
      G_STRUCT_OFFSET(ip_mib_icmp_t, icmpInMsgs),
      0,
      0 },
    { 2, G_SNMP_COUNTER32,
      IP_MIB_ICMPINERRORS, "icmpInErrors",
       NULL,
      G_STRUCT_OFFSET(ip_mib_icmp_t, icmpInErrors),
      0,
      0 },
    { 3, G_SNMP_COUNTER32,
      IP_MIB_ICMPINDESTUNREACHS, "icmpInDestUnreachs",
       NULL,
      G_STRUCT_OFFSET(ip_mib_icmp_t, icmpInDestUnreachs),
      0,
      0 },
    { 4, G_SNMP_COUNTER32,
      IP_MIB_ICMPINTIMEEXCDS, "icmpInTimeExcds",
       NULL,
      G_STRUCT_OFFSET(ip_mib_icmp_t, icmpInTimeExcds),
      0,
      0 },
    { 5, G_SNMP_COUNTER32,
      IP_MIB_ICMPINPARMPROBS, "icmpInParmProbs",
       NULL,
      G_STRUCT_OFFSET(ip_mib_icmp_t, icmpInParmProbs),
      0,
      0 },
    { 6, G_SNMP_COUNTER32,
      IP_MIB_ICMPINSRCQUENCHS, "icmpInSrcQuenchs",
       NULL,
      G_STRUCT_OFFSET(ip_mib_icmp_t, icmpInSrcQuenchs),
      0,
      0 },
    { 7, G_SNMP_COUNTER32,
      IP_MIB_ICMPINREDIRECTS, "icmpInRedirects",
       NULL,
      G_STRUCT_OFFSET(ip_mib_icmp_t, icmpInRedirects),
      0,
      0 },
    { 8, G_SNMP_COUNTER32,
      IP_MIB_ICMPINECHOS, "icmpInEchos",
       NULL,
      G_STRUCT_OFFSET(ip_mib_icmp_t, icmpInEchos),
      0,
      0 },
    { 9, G_SNMP_COUNTER32,
      IP_MIB_ICMPINECHOREPS, "icmpInEchoReps",
       NULL,
      G_STRUCT_OFFSET(ip_mib_icmp_t, icmpInEchoReps),
      0,
      0 },
    { 10, G_SNMP_COUNTER32,
      IP_MIB_ICMPINTIMESTAMPS, "icmpInTimestamps",
       NULL,
      G_STRUCT_OFFSET(ip_mib_icmp_t, icmpInTimestamps),
      0,
      0 },
    { 11, G_SNMP_COUNTER32,
      IP_MIB_ICMPINTIMESTAMPREPS, "icmpInTimestampReps",
       NULL,
      G_STRUCT_OFFSET(ip_mib_icmp_t, icmpInTimestampReps),
      0,
      0 },
    { 12, G_SNMP_COUNTER32,
      IP_MIB_ICMPINADDRMASKS, "icmpInAddrMasks",
       NULL,
      G_STRUCT_OFFSET(ip_mib_icmp_t, icmpInAddrMasks),
      0,
      0 },
    { 13, G_SNMP_COUNTER32,
      IP_MIB_ICMPINADDRMASKREPS, "icmpInAddrMaskReps",
       NULL,
      G_STRUCT_OFFSET(ip_mib_icmp_t, icmpInAddrMaskReps),
      0,
      0 },
    { 14, G_SNMP_COUNTER32,
      IP_MIB_ICMPOUTMSGS, "icmpOutMsgs",
       NULL,
      G_STRUCT_OFFSET(ip_mib_icmp_t, icmpOutMsgs),
      0,
      0 },
    { 15, G_SNMP_COUNTER32,
      IP_MIB_ICMPOUTERRORS, "icmpOutErrors",
       NULL,
      G_STRUCT_OFFSET(ip_mib_icmp_t, icmpOutErrors),
      0,
      0 },
    { 16, G_SNMP_COUNTER32,
      IP_MIB_ICMPOUTDESTUNREACHS, "icmpOutDestUnreachs",
       NULL,
      G_STRUCT_OFFSET(ip_mib_icmp_t, icmpOutDestUnreachs),
      0,
      0 },
    { 17, G_SNMP_COUNTER32,
      IP_MIB_ICMPOUTTIMEEXCDS, "icmpOutTimeExcds",
       NULL,
      G_STRUCT_OFFSET(ip_mib_icmp_t, icmpOutTimeExcds),
      0,
      0 },
    { 18, G_SNMP_COUNTER32,
      IP_MIB_ICMPOUTPARMPROBS, "icmpOutParmProbs",
       NULL,
      G_STRUCT_OFFSET(ip_mib_icmp_t, icmpOutParmProbs),
      0,
      0 },
    { 19, G_SNMP_COUNTER32,
      IP_MIB_ICMPOUTSRCQUENCHS, "icmpOutSrcQuenchs",
       NULL,
      G_STRUCT_OFFSET(ip_mib_icmp_t, icmpOutSrcQuenchs),
      0,
      0 },
    { 20, G_SNMP_COUNTER32,
      IP_MIB_ICMPOUTREDIRECTS, "icmpOutRedirects",
       NULL,
      G_STRUCT_OFFSET(ip_mib_icmp_t, icmpOutRedirects),
      0,
      0 },
    { 21, G_SNMP_COUNTER32,
      IP_MIB_ICMPOUTECHOS, "icmpOutEchos",
       NULL,
      G_STRUCT_OFFSET(ip_mib_icmp_t, icmpOutEchos),
      0,
      0 },
    { 22, G_SNMP_COUNTER32,
      IP_MIB_ICMPOUTECHOREPS, "icmpOutEchoReps",
       NULL,
      G_STRUCT_OFFSET(ip_mib_icmp_t, icmpOutEchoReps),
      0,
      0 },
    { 23, G_SNMP_COUNTER32,
      IP_MIB_ICMPOUTTIMESTAMPS, "icmpOutTimestamps",
       NULL,
      G_STRUCT_OFFSET(ip_mib_icmp_t, icmpOutTimestamps),
      0,
      0 },
    { 24, G_SNMP_COUNTER32,
      IP_MIB_ICMPOUTTIMESTAMPREPS, "icmpOutTimestampReps",
       NULL,
      G_STRUCT_OFFSET(ip_mib_icmp_t, icmpOutTimestampReps),
      0,
      0 },
    { 25, G_SNMP_COUNTER32,
      IP_MIB_ICMPOUTADDRMASKS, "icmpOutAddrMasks",
       NULL,
      G_STRUCT_OFFSET(ip_mib_icmp_t, icmpOutAddrMasks),
      0,
      0 },
    { 26, G_SNMP_COUNTER32,
      IP_MIB_ICMPOUTADDRMASKREPS, "icmpOutAddrMaskReps",
       NULL,
      G_STRUCT_OFFSET(ip_mib_icmp_t, icmpOutAddrMaskReps),
      0,
      0 },
    { 0, 0, 0, NULL }
};


ip_mib_ip_t *
ip_mib_new_ip()
{
    ip_mib_ip_t *ip;

    ip = (ip_mib_ip_t *) g_malloc0(sizeof(ip_mib_ip_t) + sizeof(gpointer));
    return ip;
}

static ip_mib_ip_t *
assign_ip(GSList *vbl)
{
    ip_mib_ip_t *ip;
    char *p;

    ip = ip_mib_new_ip();
    if (! ip) {
        return NULL;
    }

    p = (char *) ip + sizeof(ip_mib_ip_t);
    * (GSList **) p = vbl;

    gsnmp_attr_assign(vbl, ip_oid, sizeof(ip_oid)/sizeof(guint32),
                      ip_attr, ip);

    return ip;
}

void
ip_mib_get_ip(GSnmpSession *s, ip_mib_ip_t **ip, gint mask)
{
    GSList *in = NULL, *out = NULL;
    static guint32 base[] = {1, 3, 6, 1, 2, 1, 4, 0};

    *ip = NULL;

    gsnmp_attr_get(s, &in, base, 8, 7, ip_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;
        }
        *ip = assign_ip(out);
    }
}

void
ip_mib_set_ip(GSnmpSession *s, ip_mib_ip_t *ip, gint mask)
{
    GSList *in = NULL, *out = NULL;
    static guint32 base[] = {1, 3, 6, 1, 2, 1, 4, 0, 0};

    gsnmp_attr_set(s, &in, base, 9, 7, ip_attr, mask, ip);

    out = g_snmp_session_sync_set(s, in);
    g_snmp_vbl_free(in);
    if (out) {
        g_snmp_vbl_free(out);
    }
}

void
ip_mib_free_ip(ip_mib_ip_t *ip)
{
    GSList *vbl;
    char *p;

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

ip_mib_ipAddrEntry_t *
ip_mib_new_ipAddrEntry()
{
    ip_mib_ipAddrEntry_t *ipAddrEntry;

    ipAddrEntry = (ip_mib_ipAddrEntry_t *) g_malloc0(sizeof(ip_mib_ipAddrEntry_t) + sizeof(gpointer));
    return ipAddrEntry;
}

static int
unpack_ipAddrEntry(GSnmpVarBind *vb, ip_mib_ipAddrEntry_t *ipAddrEntry)
{
    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++) {
        ipAddrEntry->ipAdEntAddr[i] = vb->id[idx++];
    }
    if (vb->id_len > idx) return -1;
    return 0;
}

static int
pack_ipAddrEntry(guint32 *base, guchar *ipAdEntAddr)
{
    guint8 idx = 10;
    guint16 i, len;

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

static ip_mib_ipAddrEntry_t *
assign_ipAddrEntry(GSList *vbl)
{
    ip_mib_ipAddrEntry_t *ipAddrEntry;
    char *p;

    ipAddrEntry = ip_mib_new_ipAddrEntry();
    if (! ipAddrEntry) {
        return NULL;
    }

    p = (char *) ipAddrEntry + sizeof(ip_mib_ipAddrEntry_t);
    * (GSList **) p = vbl;

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

    gsnmp_attr_assign(vbl, ipAddrEntry_oid, sizeof(ipAddrEntry_oid)/sizeof(guint32),
                      ipAddrEntry_attr, ipAddrEntry);

    return ipAddrEntry;
}

void
ip_mib_get_ipAddrTable(GSnmpSession *s, ip_mib_ipAddrEntry_t ***ipAddrEntry, gint mask)
{
    GSList *in = NULL, *out = NULL;
    GSList *row;
    int i;
    static guint32 base[] = {1, 3, 6, 1, 2, 1, 4, 20, 1, 0};

    *ipAddrEntry = NULL;

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

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

    if (out) {
        *ipAddrEntry = (ip_mib_ipAddrEntry_t **) g_malloc0((g_slist_length(out) + 1) * sizeof(ip_mib_ipAddrEntry_t *));
        if (! *ipAddrEntry) {
            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++) {
            (*ipAddrEntry)[i] = assign_ipAddrEntry(row->data);
        }
    }
}

void
ip_mib_get_ipAddrEntry(GSnmpSession *s, ip_mib_ipAddrEntry_t **ipAddrEntry, guchar *ipAdEntAddr, gint mask)
{
    GSList *in = NULL, *out = NULL;
    guint32 base[128];
    gint8 len;

    memset(base, 0, sizeof(base));
    memcpy(base, ipAddrEntry_oid, sizeof(ipAddrEntry_oid));
    len = pack_ipAddrEntry(base, ipAdEntAddr);
    if (len < 0) {
        g_warning("%s: invalid index values", "ipAddrEntry");
        s->error_status = G_SNMP_ERR_INTERNAL;
        return;
    }

    *ipAddrEntry = NULL;

    gsnmp_attr_get(s, &in, base, len, 9, ipAddrEntry_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;
        }
        *ipAddrEntry = assign_ipAddrEntry(out);
    }
}

void
ip_mib_free_ipAddrEntry(ip_mib_ipAddrEntry_t *ipAddrEntry)
{
    GSList *vbl;
    char *p;

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

void
ip_mib_free_ipAddrTable(ip_mib_ipAddrEntry_t **ipAddrEntry)
{
    int i;

    if (ipAddrEntry) {
        for (i = 0; ipAddrEntry[i]; i++) {
            ip_mib_free_ipAddrEntry(ipAddrEntry[i]);
        }
        g_free(ipAddrEntry);
    }
}

ip_mib_ipNetToMediaEntry_t *
ip_mib_new_ipNetToMediaEntry()
{
    ip_mib_ipNetToMediaEntry_t *ipNetToMediaEntry;

    ipNetToMediaEntry = (ip_mib_ipNetToMediaEntry_t *) g_malloc0(sizeof(ip_mib_ipNetToMediaEntry_t) + sizeof(gpointer));
    return ipNetToMediaEntry;
}

static int
unpack_ipNetToMediaEntry(GSnmpVarBind *vb, ip_mib_ipNetToMediaEntry_t *ipNetToMediaEntry)
{
    guint8 idx = 10;
    guint16 i, len;

    if (vb->id_len < idx) return -1;
    ipNetToMediaEntry->ipNetToMediaIfIndex = vb->id[idx++];
    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++) {
        ipNetToMediaEntry->ipNetToMediaNetAddress[i] = vb->id[idx++];
    }
    if (vb->id_len > idx) return -1;
    return 0;
}

static int
pack_ipNetToMediaEntry(guint32 *base, gint32 ipNetToMediaIfIndex, guchar *ipNetToMediaNetAddress)
{
    guint8 idx = 10;
    guint16 i, len;

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

static ip_mib_ipNetToMediaEntry_t *
assign_ipNetToMediaEntry(GSList *vbl)
{
    ip_mib_ipNetToMediaEntry_t *ipNetToMediaEntry;
    char *p;

    ipNetToMediaEntry = ip_mib_new_ipNetToMediaEntry();
    if (! ipNetToMediaEntry) {
        return NULL;
    }

    p = (char *) ipNetToMediaEntry + sizeof(ip_mib_ipNetToMediaEntry_t);
    * (GSList **) p = vbl;

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

    gsnmp_attr_assign(vbl, ipNetToMediaEntry_oid, sizeof(ipNetToMediaEntry_oid)/sizeof(guint32),
                      ipNetToMediaEntry_attr, ipNetToMediaEntry);

    return ipNetToMediaEntry;
}

void
ip_mib_get_ipNetToMediaTable(GSnmpSession *s, ip_mib_ipNetToMediaEntry_t ***ipNetToMediaEntry, gint mask)
{
    GSList *in = NULL, *out = NULL;
    GSList *row;
    int i;
    static guint32 base[] = {1, 3, 6, 1, 2, 1, 4, 22, 1, 0};

    *ipNetToMediaEntry = NULL;

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

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

    if (out) {
        *ipNetToMediaEntry = (ip_mib_ipNetToMediaEntry_t **) g_malloc0((g_slist_length(out) + 1) * sizeof(ip_mib_ipNetToMediaEntry_t *));
        if (! *ipNetToMediaEntry) {
            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++) {
            (*ipNetToMediaEntry)[i] = assign_ipNetToMediaEntry(row->data);
        }
    }
}

void
ip_mib_get_ipNetToMediaEntry(GSnmpSession *s, ip_mib_ipNetToMediaEntry_t **ipNetToMediaEntry, gint32 ipNetToMediaIfIndex, guchar *ipNetToMediaNetAddress, gint mask)
{
    GSList *in = NULL, *out = NULL;
    guint32 base[128];
    gint8 len;

    memset(base, 0, sizeof(base));
    memcpy(base, ipNetToMediaEntry_oid, sizeof(ipNetToMediaEntry_oid));
    len = pack_ipNetToMediaEntry(base, ipNetToMediaIfIndex, ipNetToMediaNetAddress);
    if (len < 0) {
        g_warning("%s: invalid index values", "ipNetToMediaEntry");
        s->error_status = G_SNMP_ERR_INTERNAL;
        return;
    }

    *ipNetToMediaEntry = NULL;

    gsnmp_attr_get(s, &in, base, len, 9, ipNetToMediaEntry_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;
        }
        *ipNetToMediaEntry = assign_ipNetToMediaEntry(out);
    }
}

void
ip_mib_set_ipNetToMediaEntry(GSnmpSession *s, ip_mib_ipNetToMediaEntry_t *ipNetToMediaEntry, gint mask)
{
    GSList *in = NULL, *out = NULL;
    guint32 base[128];
    gint8 len;

    memset(base, 0, sizeof(base));
    memcpy(base, ipNetToMediaEntry_oid, sizeof(ipNetToMediaEntry_oid));
    len = pack_ipNetToMediaEntry(base, ipNetToMediaEntry->ipNetToMediaIfIndex, ipNetToMediaEntry->ipNetToMediaNetAddress);
    if (len < 0) {
        g_warning("%s: invalid index values", "ipNetToMediaEntry");
        s->error_status = G_SNMP_ERR_INTERNAL;
        return;
    }

    gsnmp_attr_set(s, &in, base, len, 9, ipNetToMediaEntry_attr, mask, ipNetToMediaEntry);

    out = g_snmp_session_sync_set(s, in);
    g_snmp_vbl_free(in);
    if (out) {
        g_snmp_vbl_free(out);
    }
}

void
ip_mib_free_ipNetToMediaEntry(ip_mib_ipNetToMediaEntry_t *ipNetToMediaEntry)
{
    GSList *vbl;
    char *p;

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

void
ip_mib_free_ipNetToMediaTable(ip_mib_ipNetToMediaEntry_t **ipNetToMediaEntry)
{
    int i;

    if (ipNetToMediaEntry) {
        for (i = 0; ipNetToMediaEntry[i]; i++) {
            ip_mib_free_ipNetToMediaEntry(ipNetToMediaEntry[i]);
        }
        g_free(ipNetToMediaEntry);
    }
}

ip_mib_icmp_t *
ip_mib_new_icmp()
{
    ip_mib_icmp_t *icmp;

    icmp = (ip_mib_icmp_t *) g_malloc0(sizeof(ip_mib_icmp_t) + sizeof(gpointer));
    return icmp;
}

static ip_mib_icmp_t *
assign_icmp(GSList *vbl)
{
    ip_mib_icmp_t *icmp;
    char *p;

    icmp = ip_mib_new_icmp();
    if (! icmp) {
        return NULL;
    }

    p = (char *) icmp + sizeof(ip_mib_icmp_t);
    * (GSList **) p = vbl;

    gsnmp_attr_assign(vbl, icmp_oid, sizeof(icmp_oid)/sizeof(guint32),
                      icmp_attr, icmp);

    return icmp;
}

void
ip_mib_get_icmp(GSnmpSession *s, ip_mib_icmp_t **icmp, gint mask)
{
    GSList *in = NULL, *out = NULL;
    static guint32 base[] = {1, 3, 6, 1, 2, 1, 5, 0};

    *icmp = NULL;

    gsnmp_attr_get(s, &in, base, 8, 7, icmp_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;
        }
        *icmp = assign_icmp(out);
    }
}

void
ip_mib_free_icmp(ip_mib_icmp_t *icmp)
{
    GSList *vbl;
    char *p;

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


