/*
 * Copyright 2008 Juan Lang
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include "config.h"
#include <assert.h>
#include <stdarg.h>
#include <stdlib.h>
#include <limits.h>
#include "windef.h"
#include "winbase.h"
#include "snmp.h"
#include "iphlpapi.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(inetmib1);

/**
 * Utility functions
 */
static DWORD copyInt(AsnAny *value, void *src)
{
    value->asnType = ASN_INTEGER;
    value->asnValue.number = *(DWORD *)src;
    return SNMP_ERRORSTATUS_NOERROR;
}

static void setStringValue(AsnAny *value, BYTE type, DWORD len, BYTE *str)
{
    AsnAny strValue;

    strValue.asnType = type;
    strValue.asnValue.string.stream = str;
    strValue.asnValue.string.length = len;
    strValue.asnValue.string.dynamic = FALSE;
    SnmpUtilAsnAnyCpy(value, &strValue);
}

typedef DWORD (*copyValueFunc)(AsnAny *value, void *src);

struct structToAsnValue
{
    size_t        offset;
    copyValueFunc copy;
};

static AsnInteger32 mapStructEntryToValue(struct structToAsnValue *map,
    UINT mapLen, void *record, UINT id, BYTE bPduType, SnmpVarBind *pVarBind)
{
    /* OIDs are 1-based */
    if (!id)
        return SNMP_ERRORSTATUS_NOSUCHNAME;
    --id;
    if (id >= mapLen)
        return SNMP_ERRORSTATUS_NOSUCHNAME;
    if (!map[id].copy)
        return SNMP_ERRORSTATUS_NOSUCHNAME;
    return map[id].copy(&pVarBind->value, (BYTE *)record + map[id].offset);
}

static DWORD copyIpAddr(AsnAny *value, void *src)
{
    setStringValue(value, ASN_IPADDRESS, sizeof(DWORD), src);
    return SNMP_ERRORSTATUS_NOERROR;
}

static UINT mib2[] = { 1,3,6,1,2,1 };
static UINT mib2System[] = { 1,3,6,1,2,1,1 };

typedef BOOL (*varqueryfunc)(BYTE bPduType, SnmpVarBind *pVarBind,
    AsnInteger32 *pErrorStatus);

struct mibImplementation
{
    AsnObjectIdentifier name;
    void              (*init)(void);
    varqueryfunc        query;
    void              (*cleanup)(void);
};

static UINT mib2IfNumber[] = { 1,3,6,1,2,1,2,1 };
static PMIB_IFTABLE ifTable;

static void mib2IfNumberInit(void)
{
    DWORD size = 0, ret = GetIfTable(NULL, &size, FALSE);

    if (ret == ERROR_INSUFFICIENT_BUFFER)
    {
        MIB_IFTABLE *table = HeapAlloc(GetProcessHeap(), 0, size);
        if (table)
        {
            if (!GetIfTable(table, &size, FALSE)) ifTable = table;
            else HeapFree(GetProcessHeap(), 0, table );
        }
    }
}

static void mib2IfNumberCleanup(void)
{
    HeapFree(GetProcessHeap(), 0, ifTable);
}

static BOOL mib2IfNumberQuery(BYTE bPduType, SnmpVarBind *pVarBind,
    AsnInteger32 *pErrorStatus)
{
    AsnObjectIdentifier numberOid = DEFINE_OID(mib2IfNumber);
    BOOL ret = TRUE;

    TRACE("(0x%02x, %s, %p)\n", bPduType, SnmpUtilOidToA(&pVarBind->name),
        pErrorStatus);

    switch (bPduType)
    {
    case SNMP_PDU_GET:
    case SNMP_PDU_GETNEXT:
        if ((bPduType == SNMP_PDU_GET &&
            !SnmpUtilOidNCmp(&pVarBind->name, &numberOid, numberOid.idLength))
            || SnmpUtilOidNCmp(&pVarBind->name, &numberOid, numberOid.idLength)
            < 0)
        {
            DWORD numIfs = ifTable ? ifTable->dwNumEntries : 0;

            copyInt(&pVarBind->value, &numIfs);
            if (bPduType == SNMP_PDU_GETNEXT)
            {
                SnmpUtilOidFree(&pVarBind->name);
                SnmpUtilOidCpy(&pVarBind->name, &numberOid);
            }
            *pErrorStatus = SNMP_ERRORSTATUS_NOERROR;
        }
        else
        {
            *pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME;
            /* Caller deals with OID if bPduType == SNMP_PDU_GETNEXT, so don't
             * need to set it here.
             */
        }
        break;
    case SNMP_PDU_SET:
        *pErrorStatus = SNMP_ERRORSTATUS_READONLY;
        ret = FALSE;
        break;
    default:
        FIXME("0x%02x: unsupported PDU type\n", bPduType);
        *pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME;
    }
    return ret;
}

static DWORD copyOperStatus(AsnAny *value, void *src)
{
    value->asnType = ASN_INTEGER;
    /* The IPHlpApi definition of operational status differs from the MIB2 one,
     * so map it to the MIB2 value.
     */
    switch (*(DWORD *)src)
    {
    case MIB_IF_OPER_STATUS_OPERATIONAL:
        value->asnValue.number = MIB_IF_ADMIN_STATUS_UP;
        break;
    case MIB_IF_OPER_STATUS_CONNECTING:
    case MIB_IF_OPER_STATUS_CONNECTED:
        value->asnValue.number = MIB_IF_ADMIN_STATUS_TESTING;
        break;
    default:
        value->asnValue.number = MIB_IF_ADMIN_STATUS_DOWN;
    };
    return SNMP_ERRORSTATUS_NOERROR;
}

/* Given an OID and a base OID that it must begin with, finds the item and
 * integer instance from the OID.  E.g., given an OID foo.1.2 and a base OID
 * foo, returns item 1 and instance 2.
 * If bPduType is not SNMP_PDU_GETNEXT and either the item or instance is
 * missing, returns SNMP_ERRORSTATUS_NOSUCHNAME.
 * If bPduType is SNMP_PDU_GETNEXT, returns the successor to the item and
 * instance, or item 1, instance 1 if either is missing.
 */
static AsnInteger32 getItemAndIntegerInstanceFromOid(AsnObjectIdentifier *oid,
    AsnObjectIdentifier *base, BYTE bPduType, UINT *item, UINT *instance)
{
    AsnInteger32 ret = SNMP_ERRORSTATUS_NOERROR;

    switch (bPduType)
    {
    case SNMP_PDU_GETNEXT:
        if (SnmpUtilOidNCmp(oid, base, base->idLength) < 0)
        {
            *item = 1;
            *instance = 1;
        }
        else if (!SnmpUtilOidNCmp(oid, base, base->idLength))
        {
            if (oid->idLength == base->idLength ||
                oid->idLength == base->idLength + 1)
            {
                /* Either the table or an item within the table is specified,
                 * but the instance is not.  Get the first instance.
                 */
                *instance = 1;
                if (oid->idLength == base->idLength + 1)
                    *item = oid->ids[base->idLength];
                else
                    *item = 1;
            }
            else
            {
                *item = oid->ids[base->idLength];
                *instance = oid->ids[base->idLength + 1] + 1;
            }
        }
        else
            ret = SNMP_ERRORSTATUS_NOSUCHNAME;
        break;
    default:
        if (!SnmpUtilOidNCmp(oid, base, base->idLength))
        {
            if (oid->idLength == base->idLength ||
                oid->idLength == base->idLength + 1)
            {
                /* Either the table or an item within the table is specified,
                 * but the instance is not.
                 */
                ret = SNMP_ERRORSTATUS_NOSUCHNAME;
            }
            else
            {
                *item = oid->ids[base->idLength];
                *instance = oid->ids[base->idLength + 1];
            }
        }
        else
            ret = SNMP_ERRORSTATUS_NOSUCHNAME;
    }
    return ret;
}

/* Given an OID and a base OID that it must begin with, finds the item from the
 * OID.  E.g., given an OID foo.1 and a base OID foo, returns item 1.
 * If bPduType is not SNMP_PDU_GETNEXT and the item is missing, returns
 * SNMP_ERRORSTATUS_NOSUCHNAME.
 * If bPduType is SNMP_PDU_GETNEXT, returns the successor to the item, or item
 * 1 if the item is missing.
 */
static AsnInteger32 getItemFromOid(AsnObjectIdentifier *oid,
    AsnObjectIdentifier *base, BYTE bPduType, UINT *item)
{
    AsnInteger32 ret = SNMP_ERRORSTATUS_NOERROR;

    switch (bPduType)
    {
    case SNMP_PDU_GETNEXT:
        if (SnmpUtilOidNCmp(oid, base, base->idLength) < 0)
            *item = 1;
        else if (!SnmpUtilOidNCmp(oid, base, base->idLength))
        {
            if (oid->idLength == base->idLength)
            {
                /* The item is missing, assume the first item */
                *item = 1;
            }
            else
                *item = oid->ids[base->idLength] + 1;
        }
        else
            ret = SNMP_ERRORSTATUS_NOSUCHNAME;
        break;
    default:
        if (!SnmpUtilOidNCmp(oid, base, base->idLength))
        {
            if (oid->idLength == base->idLength)
            {
                /* The item is missing */
                ret = SNMP_ERRORSTATUS_NOSUCHNAME;
            }
            else
            {
                *item = oid->ids[base->idLength];
                if (!*item)
                    ret = SNMP_ERRORSTATUS_NOSUCHNAME;
            }
        }
        else
            ret = SNMP_ERRORSTATUS_NOSUCHNAME;
    }
    return ret;
}

struct GenericTable
{
    DWORD numEntries;
    BYTE  entries[1];
};

static DWORD oidToIpAddr(AsnObjectIdentifier *oid)
{
    assert(oid && oid->idLength >= 4);
    /* Map the IDs to an IP address in little-endian order */
    return (BYTE)oid->ids[3] << 24 | (BYTE)oid->ids[2] << 16 |
        (BYTE)oid->ids[1] << 8 | (BYTE)oid->ids[0];
}

typedef void (*oidToKeyFunc)(AsnObjectIdentifier *oid, void *dst);
typedef int (*compareFunc)(const void *key, const void *value);

/* Finds the first value in the table that matches key.  Returns its 1-based
 * index if found, or 0 if not found.
 */
static UINT findValueInTable(const void *key,
    struct GenericTable *table, size_t tableEntrySize, compareFunc compare)
{
    UINT index = 0;
    void *value;

    value = bsearch(key, table->entries, table->numEntries, tableEntrySize,
        compare);
    if (value)
        index = ((BYTE *)value - (BYTE *)table->entries) / tableEntrySize + 1;
    return index;
}

/* Finds the first value in the table that matches oid, using makeKey to
 * convert the oid to a key for comparison.  Returns the value's 1-based
 * index if found, or 0 if not found.
 */
static UINT findOidInTable(AsnObjectIdentifier *oid,
    struct GenericTable *table, size_t tableEntrySize, oidToKeyFunc makeKey,
    compareFunc compare)
{
    UINT index = 0;
    void *key = HeapAlloc(GetProcessHeap(), 0, tableEntrySize);

    if (key)
    {
        makeKey(oid, key);
        index = findValueInTable(key, table, tableEntrySize, compare);
        HeapFree(GetProcessHeap(), 0, key);
    }
    return index;
}

/* Finds the first successor to the value in the table that does matches oid,
 * using makeKey to convert the oid to a key for comparison.  A successor is
 * a value that does not match oid, so if multiple entries match an oid, only
 * the first will ever be returned using this method.
 * Returns the successor's 1-based index if found, or 0 if not found.
 */
static UINT findNextOidInTable(AsnObjectIdentifier *oid,
    struct GenericTable *table, size_t tableEntrySize, oidToKeyFunc makeKey,
    compareFunc compare)
{
    UINT index = 0;
    void *key = HeapAlloc(GetProcessHeap(), 0, tableEntrySize);

    if (key)
    {
        makeKey(oid, key);
        index = findValueInTable(key, table, tableEntrySize, compare);
        if (index == 0)
        {
            /* Not found in table.  If it's less than the first entry, return
             * the first index.  Otherwise just return 0 and let the caller
             * handle finding the successor.
             */
            if (compare(key, table->entries) < 0)
                index = 1;
        }
        else
        {
            /* Skip any entries that match the same key.  This enumeration will
             * be incomplete, but it's what Windows appears to do if there are
             * multiple entries with the same index in a table, and it avoids
             * an infinite loop.
             */
            for (++index; index <= table->numEntries && compare(key,
                &table->entries[tableEntrySize * (index - 1)]) == 0; ++index)
                ;
        }
        HeapFree(GetProcessHeap(), 0, key);
    }
    return index;
}

/* Given an OID and a base OID that it must begin with, finds the item and
 * element of the table whose value matches the instance from the OID.
 * The OID is converted to a key with the function makeKey, and compared
 * against entries in the table with the function compare.
 * If bPduType is not SNMP_PDU_GETNEXT and either the item or instance is
 * missing, returns SNMP_ERRORSTATUS_NOSUCHNAME.
 * If bPduType is SNMP_PDU_GETNEXT, returns the successor to the item and
 * instance, or item 1, instance 1 if either is missing.
 */
static AsnInteger32 getItemAndInstanceFromTable(AsnObjectIdentifier *oid,
    AsnObjectIdentifier *base, UINT instanceLen, BYTE bPduType,
    struct GenericTable *table, size_t tableEntrySize, oidToKeyFunc makeKey,
    compareFunc compare, UINT *item, UINT *instance)
{
    AsnInteger32 ret = SNMP_ERRORSTATUS_NOERROR;

    if (!table)
        return SNMP_ERRORSTATUS_NOSUCHNAME;

    switch (bPduType)
    {
    case SNMP_PDU_GETNEXT:
        if (SnmpUtilOidNCmp(oid, base, base->idLength) < 0)
        {
            /* Return the first item and instance from the table */
            *item = 1;
            *instance = 1;
        }
        else if (!SnmpUtilOidNCmp(oid, base, base->idLength) &&
            oid->idLength < base->idLength + instanceLen + 1)
        {
            /* Either the table or an item is specified, but the instance is
             * not.
             */
            *instance = 1;
            if (oid->idLength >= base->idLength + 1)
            {
                *item = oid->ids[base->idLength];
                if (!*item)
                    *item = 1;
            }
            else
                *item = 1;
        }
        else if (!SnmpUtilOidNCmp(oid, base, base->idLength) &&
            oid->idLength == base->idLength + instanceLen + 1)
        {
            *item = oid->ids[base->idLength];
            if (!*item)
            {
                *instance = 1;
                *item = 1;
            }
            else
            {
                AsnObjectIdentifier instanceOid = { instanceLen,
                    oid->ids + base->idLength + 1 };

                *instance = findNextOidInTable(&instanceOid, table,
                    tableEntrySize, makeKey, compare);
                if (!*instance || *instance > table->numEntries)
                    ret = SNMP_ERRORSTATUS_NOSUCHNAME;
            }
        }
        else
            ret = SNMP_ERRORSTATUS_NOSUCHNAME;
        break;
    default:
        if (!SnmpUtilOidNCmp(oid, base, base->idLength) &&
            oid->idLength == base->idLength + instanceLen + 1)
        {
            *item = oid->ids[base->idLength];
            if (!*item)
                ret = SNMP_ERRORSTATUS_NOSUCHNAME;
            else
            {
                AsnObjectIdentifier instanceOid = { instanceLen,
                    oid->ids + base->idLength + 1 };

                *instance = findOidInTable(&instanceOid, table, tableEntrySize,
                    makeKey, compare);
                if (!*instance)
                    ret = SNMP_ERRORSTATUS_NOSUCHNAME;
            }
        }
        else
            ret = SNMP_ERRORSTATUS_NOSUCHNAME;
    }
    return ret;
}

static INT setOidWithItem(AsnObjectIdentifier *dst, AsnObjectIdentifier *base,
    UINT item)
{
    UINT id;
    AsnObjectIdentifier oid;
    INT ret;

    SnmpUtilOidFree(dst);
    ret = SnmpUtilOidCpy(dst, base);
    if (ret)
    {
        oid.idLength = 1;
        oid.ids = &id;
        id = item;
        ret = SnmpUtilOidAppend(dst, &oid);
    }
    return ret;
}

static INT setOidWithItemAndIpAddr(AsnObjectIdentifier *dst,
    AsnObjectIdentifier *base, UINT item, DWORD addr)
{
    UINT id;
    BYTE *ptr;
    AsnObjectIdentifier oid;
    INT ret;

    ret = setOidWithItem(dst, base, item);
    if (ret)
    {
        oid.idLength = 1;
        oid.ids = &id;
        for (ptr = (BYTE *)&addr; ret && ptr < (BYTE *)&addr + sizeof(DWORD);
         ptr++)
        {
            id = *ptr;
            ret = SnmpUtilOidAppend(dst, &oid);
        }
    }
    return ret;
}

static INT setOidWithItemAndInteger(AsnObjectIdentifier *dst,
    AsnObjectIdentifier *base, UINT item, UINT instance)
{
    AsnObjectIdentifier oid;
    INT ret;

    ret = setOidWithItem(dst, base, item);
    if (ret)
    {
        oid.idLength = 1;
        oid.ids = &instance;
        ret = SnmpUtilOidAppend(dst, &oid);
    }
    return ret;
}

static DWORD copyIfRowDescr(AsnAny *value, void *src)
{
    PMIB_IFROW row = (PMIB_IFROW)((BYTE *)src -
                                  FIELD_OFFSET(MIB_IFROW, dwDescrLen));
    DWORD ret;

    if (row->dwDescrLen)
    {
        setStringValue(value, ASN_OCTETSTRING, row->dwDescrLen, row->bDescr);
        ret = SNMP_ERRORSTATUS_NOERROR;
    }
    else
        ret = SNMP_ERRORSTATUS_NOSUCHNAME;
    return ret;
}

static DWORD copyIfRowPhysAddr(AsnAny *value, void *src)
{
    PMIB_IFROW row = (PMIB_IFROW)((BYTE *)src -
                                  FIELD_OFFSET(MIB_IFROW, dwPhysAddrLen));
    DWORD ret;

    if (row->dwPhysAddrLen)
    {
        setStringValue(value, ASN_OCTETSTRING, row->dwPhysAddrLen,
                       row->bPhysAddr);
        ret = SNMP_ERRORSTATUS_NOERROR;
    }
    else
        ret = SNMP_ERRORSTATUS_NOSUCHNAME;
    return ret;
}

static struct structToAsnValue mib2IfEntryMap[] = {
    { FIELD_OFFSET(MIB_IFROW, dwIndex), copyInt },
    { FIELD_OFFSET(MIB_IFROW, dwDescrLen), copyIfRowDescr },
    { FIELD_OFFSET(MIB_IFROW, dwType), copyInt },
    { FIELD_OFFSET(MIB_IFROW, dwMtu), copyInt },
    { FIELD_OFFSET(MIB_IFROW, dwSpeed), copyInt },
    { FIELD_OFFSET(MIB_IFROW, dwPhysAddrLen), copyIfRowPhysAddr },
    { FIELD_OFFSET(MIB_IFROW, dwAdminStatus), copyInt },
    { FIELD_OFFSET(MIB_IFROW, dwOperStatus), copyOperStatus },
    { FIELD_OFFSET(MIB_IFROW, dwLastChange), copyInt },
    { FIELD_OFFSET(MIB_IFROW, dwInOctets), copyInt },
    { FIELD_OFFSET(MIB_IFROW, dwInUcastPkts), copyInt },
    { FIELD_OFFSET(MIB_IFROW, dwInNUcastPkts), copyInt },
    { FIELD_OFFSET(MIB_IFROW, dwInDiscards), copyInt },
    { FIELD_OFFSET(MIB_IFROW, dwInErrors), copyInt },
    { FIELD_OFFSET(MIB_IFROW, dwInUnknownProtos), copyInt },
    { FIELD_OFFSET(MIB_IFROW, dwOutOctets), copyInt },
    { FIELD_OFFSET(MIB_IFROW, dwOutUcastPkts), copyInt },
    { FIELD_OFFSET(MIB_IFROW, dwOutNUcastPkts), copyInt },
    { FIELD_OFFSET(MIB_IFROW, dwOutDiscards), copyInt },
    { FIELD_OFFSET(MIB_IFROW, dwOutErrors), copyInt },
    { FIELD_OFFSET(MIB_IFROW, dwOutQLen), copyInt },
};

static UINT mib2IfEntry[] = { 1,3,6,1,2,1,2,2,1 };

static BOOL mib2IfEntryQuery(BYTE bPduType, SnmpVarBind *pVarBind,
    AsnInteger32 *pErrorStatus)
{
    AsnObjectIdentifier entryOid = DEFINE_OID(mib2IfEntry);
    BOOL ret = TRUE;

    TRACE("(0x%02x, %s, %p)\n", bPduType, SnmpUtilOidToA(&pVarBind->name),
        pErrorStatus);

    switch (bPduType)
    {
    case SNMP_PDU_GET:
    case SNMP_PDU_GETNEXT:
        if (!ifTable)
        {
            /* There is no interface present, so let the caller deal
             * with finding the successor.
             */
            *pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME;
        }
        else
        {
            UINT tableIndex = 0, item = 0;

            *pErrorStatus = getItemAndIntegerInstanceFromOid(&pVarBind->name,
                &entryOid, bPduType, &item, &tableIndex);
            if (!*pErrorStatus)
            {
                assert(tableIndex);
                assert(item);
                if (tableIndex > ifTable->dwNumEntries)
                    *pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME;
                else
                {
                    *pErrorStatus = mapStructEntryToValue(mib2IfEntryMap,
                        DEFINE_SIZEOF(mib2IfEntryMap),
                        &ifTable->table[tableIndex - 1], item, bPduType,
                        pVarBind);
                    if (bPduType == SNMP_PDU_GETNEXT)
                        ret = setOidWithItemAndInteger(&pVarBind->name,
                            &entryOid, item, tableIndex);
                }
            }
        }
        break;
    case SNMP_PDU_SET:
        *pErrorStatus = SNMP_ERRORSTATUS_READONLY;
        ret = FALSE;
        break;
    default:
        FIXME("0x%02x: unsupported PDU type\n", bPduType);
        *pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME;
    }
    return ret;
}

static UINT mib2Ip[] = { 1,3,6,1,2,1,4 };
static MIB_IPSTATS ipStats;

static void mib2IpStatsInit(void)
{
    GetIpStatistics(&ipStats);
}

static struct structToAsnValue mib2IpMap[] = {
    { FIELD_OFFSET(MIB_IPSTATS, dwForwarding), copyInt }, /* 1 */
    { FIELD_OFFSET(MIB_IPSTATS, dwDefaultTTL), copyInt }, /* 2 */
    { FIELD_OFFSET(MIB_IPSTATS, dwInReceives), copyInt }, /* 3 */
    { FIELD_OFFSET(MIB_IPSTATS, dwInHdrErrors), copyInt }, /* 4 */
    { FIELD_OFFSET(MIB_IPSTATS, dwInAddrErrors), copyInt }, /* 5 */
    { FIELD_OFFSET(MIB_IPSTATS, dwForwDatagrams), copyInt }, /* 6 */
    { FIELD_OFFSET(MIB_IPSTATS, dwInUnknownProtos), copyInt }, /* 7 */
    { FIELD_OFFSET(MIB_IPSTATS, dwInDiscards), copyInt }, /* 8 */
    { FIELD_OFFSET(MIB_IPSTATS, dwInDelivers), copyInt }, /* 9 */
    { FIELD_OFFSET(MIB_IPSTATS, dwOutRequests), copyInt }, /* 10 */
    { FIELD_OFFSET(MIB_IPSTATS, dwOutDiscards), copyInt }, /* 11 */
    { FIELD_OFFSET(MIB_IPSTATS, dwOutNoRoutes), copyInt }, /* 12 */
    { FIELD_OFFSET(MIB_IPSTATS, dwReasmTimeout), copyInt }, /* 13 */
    { FIELD_OFFSET(MIB_IPSTATS, dwReasmReqds), copyInt }, /* 14 */
    { FIELD_OFFSET(MIB_IPSTATS, dwReasmOks), copyInt }, /* 15 */
    { FIELD_OFFSET(MIB_IPSTATS, dwReasmFails), copyInt }, /* 16 */
    { FIELD_OFFSET(MIB_IPSTATS, dwFragOks), copyInt }, /* 17 */
    { FIELD_OFFSET(MIB_IPSTATS, dwFragFails), copyInt }, /* 18 */
    { FIELD_OFFSET(MIB_IPSTATS, dwFragCreates), copyInt }, /* 19 */
    { 0, NULL }, /* 20: not used, IP addr table */
    { 0, NULL }, /* 21: not used, route table */
    { 0, NULL }, /* 22: not used, net to media (ARP) table */
    { FIELD_OFFSET(MIB_IPSTATS, dwRoutingDiscards), copyInt }, /* 23 */
};

static BOOL mib2IpStatsQuery(BYTE bPduType, SnmpVarBind *pVarBind,
    AsnInteger32 *pErrorStatus)
{
    AsnObjectIdentifier myOid = DEFINE_OID(mib2Ip);
    UINT item = 0;
    BOOL ret = TRUE;

    TRACE("(0x%02x, %s, %p)\n", bPduType, SnmpUtilOidToA(&pVarBind->name),
        pErrorStatus);

    switch (bPduType)
    {
    case SNMP_PDU_GET:
    case SNMP_PDU_GETNEXT:
        *pErrorStatus = getItemFromOid(&pVarBind->name, &myOid, bPduType,
            &item);
        if (!*pErrorStatus)
        {
            *pErrorStatus = mapStructEntryToValue(mib2IpMap,
                DEFINE_SIZEOF(mib2IpMap), &ipStats, item, bPduType, pVarBind);
            if (!*pErrorStatus && bPduType == SNMP_PDU_GETNEXT)
                ret = setOidWithItem(&pVarBind->name, &myOid, item);
        }
        break;
    case SNMP_PDU_SET:
        *pErrorStatus = SNMP_ERRORSTATUS_READONLY;
        ret = FALSE;
        break;
    default:
        FIXME("0x%02x: unsupported PDU type\n", bPduType);
        *pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME;
    }
    return ret;
}

static UINT mib2IpAddr[] = { 1,3,6,1,2,1,4,20,1 };
static PMIB_IPADDRTABLE ipAddrTable;

static struct structToAsnValue mib2IpAddrMap[] = {
    { FIELD_OFFSET(MIB_IPADDRROW, dwAddr), copyIpAddr },
    { FIELD_OFFSET(MIB_IPADDRROW, dwIndex), copyInt },
    { FIELD_OFFSET(MIB_IPADDRROW, dwMask), copyIpAddr },
    { FIELD_OFFSET(MIB_IPADDRROW, dwBCastAddr), copyInt },
    { FIELD_OFFSET(MIB_IPADDRROW, dwReasmSize), copyInt },
};

static void mib2IpAddrInit(void)
{
    DWORD size = 0, ret = GetIpAddrTable(NULL, &size, TRUE);

    if (ret == ERROR_INSUFFICIENT_BUFFER)
    {
        MIB_IPADDRTABLE *table = HeapAlloc(GetProcessHeap(), 0, size);
        if (table)
        {
            if (!GetIpAddrTable(table, &size, TRUE)) ipAddrTable = table;
            else HeapFree(GetProcessHeap(), 0, table );
        }
    }
}

static void mib2IpAddrCleanup(void)
{
    HeapFree(GetProcessHeap(), 0, ipAddrTable);
}

static void oidToIpAddrRow(AsnObjectIdentifier *oid, void *dst)
{
    MIB_IPADDRROW *row = dst;

    row->dwAddr = oidToIpAddr(oid);
}

static int compareIpAddrRow(const void *a, const void *b)
{
    const MIB_IPADDRROW *key = a, *value = b;

    return key->dwAddr - value->dwAddr;
}

static BOOL mib2IpAddrQuery(BYTE bPduType, SnmpVarBind *pVarBind,
    AsnInteger32 *pErrorStatus)
{
    AsnObjectIdentifier myOid = DEFINE_OID(mib2IpAddr);
    UINT tableIndex = 0, item = 0;
    BOOL ret = TRUE;

    TRACE("(0x%02x, %s, %p)\n", bPduType, SnmpUtilOidToA(&pVarBind->name),
        pErrorStatus);

    switch (bPduType)
    {
    case SNMP_PDU_GET:
    case SNMP_PDU_GETNEXT:
        *pErrorStatus = getItemAndInstanceFromTable(&pVarBind->name,
            &myOid, 4, bPduType, (struct GenericTable *)ipAddrTable,
            sizeof(MIB_IPADDRROW), oidToIpAddrRow, compareIpAddrRow, &item,
            &tableIndex);
        if (!*pErrorStatus)
        {
            assert(tableIndex);
            assert(item);
            *pErrorStatus = mapStructEntryToValue(mib2IpAddrMap,
                DEFINE_SIZEOF(mib2IpAddrMap),
                &ipAddrTable->table[tableIndex - 1], item, bPduType, pVarBind);
            if (!*pErrorStatus && bPduType == SNMP_PDU_GETNEXT)
                ret = setOidWithItemAndIpAddr(&pVarBind->name, &myOid, item,
                    ipAddrTable->table[tableIndex - 1].dwAddr);
        }
        break;
    case SNMP_PDU_SET:
        *pErrorStatus = SNMP_ERRORSTATUS_READONLY;
        ret = FALSE;
        break;
    default:
        FIXME("0x%02x: unsupported PDU type\n", bPduType);
        *pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME;
    }
    return ret;
}

static UINT mib2IpRoute[] = { 1,3,6,1,2,1,4,21,1 };
static PMIB_IPFORWARDTABLE ipRouteTable;

static struct structToAsnValue mib2IpRouteMap[] = {
    { FIELD_OFFSET(MIB_IPFORWARDROW, dwForwardDest), copyIpAddr },
    { FIELD_OFFSET(MIB_IPFORWARDROW, dwForwardIfIndex), copyInt },
    { FIELD_OFFSET(MIB_IPFORWARDROW, dwForwardMetric1), copyInt },
    { FIELD_OFFSET(MIB_IPFORWARDROW, dwForwardMetric2), copyInt },
    { FIELD_OFFSET(MIB_IPFORWARDROW, dwForwardMetric3), copyInt },
    { FIELD_OFFSET(MIB_IPFORWARDROW, dwForwardMetric4), copyInt },
    { FIELD_OFFSET(MIB_IPFORWARDROW, dwForwardNextHop), copyIpAddr },
    { FIELD_OFFSET(MIB_IPFORWARDROW, dwForwardType), copyInt },
    { FIELD_OFFSET(MIB_IPFORWARDROW, dwForwardProto), copyInt },
    { FIELD_OFFSET(MIB_IPFORWARDROW, dwForwardAge), copyInt },
    { FIELD_OFFSET(MIB_IPFORWARDROW, dwForwardMask), copyIpAddr },
    { FIELD_OFFSET(MIB_IPFORWARDROW, dwForwardMetric5), copyInt },
};

static void mib2IpRouteInit(void)
{
    DWORD size = 0, ret = GetIpForwardTable(NULL, &size, TRUE);

    if (ret == ERROR_INSUFFICIENT_BUFFER)
    {
        MIB_IPFORWARDTABLE *table = HeapAlloc(GetProcessHeap(), 0, size);
        if (table)
        {
            if (!GetIpForwardTable(table, &size, TRUE)) ipRouteTable = table;
            else HeapFree(GetProcessHeap(), 0, table );
        }
    }
}

static void mib2IpRouteCleanup(void)
{
    HeapFree(GetProcessHeap(), 0, ipRouteTable);
}

static void oidToIpForwardRow(AsnObjectIdentifier *oid, void *dst)
{
    MIB_IPFORWARDROW *row = dst;

    row->dwForwardDest = oidToIpAddr(oid);
}

static int compareIpForwardRow(const void *a, const void *b)
{
    const MIB_IPFORWARDROW *key = a, *value = b;

    return key->dwForwardDest - value->dwForwardDest;
}

static BOOL mib2IpRouteQuery(BYTE bPduType, SnmpVarBind *pVarBind,
    AsnInteger32 *pErrorStatus)
{
    AsnObjectIdentifier myOid = DEFINE_OID(mib2IpRoute);
    UINT tableIndex = 0, item = 0;
    BOOL ret = TRUE;

    TRACE("(0x%02x, %s, %p)\n", bPduType, SnmpUtilOidToA(&pVarBind->name),
        pErrorStatus);

    switch (bPduType)
    {
    case SNMP_PDU_GET:
    case SNMP_PDU_GETNEXT:
        *pErrorStatus = getItemAndInstanceFromTable(&pVarBind->name,
            &myOid, 4, bPduType, (struct GenericTable *)ipRouteTable,
            sizeof(MIB_IPFORWARDROW), oidToIpForwardRow, compareIpForwardRow,
            &item, &tableIndex);
        if (!*pErrorStatus)
        {
            assert(tableIndex);
            assert(item);
            *pErrorStatus = mapStructEntryToValue(mib2IpRouteMap,
                DEFINE_SIZEOF(mib2IpRouteMap),
                &ipRouteTable->table[tableIndex - 1], item, bPduType, pVarBind);
            if (!*pErrorStatus && bPduType == SNMP_PDU_GETNEXT)
                ret = setOidWithItemAndIpAddr(&pVarBind->name, &myOid, item,
                    ipRouteTable->table[tableIndex - 1].dwForwardDest);
        }
        break;
    case SNMP_PDU_SET:
        *pErrorStatus = SNMP_ERRORSTATUS_READONLY;
        ret = FALSE;
        break;
    default:
        FIXME("0x%02x: unsupported PDU type\n", bPduType);
        *pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME;
    }
    return ret;
}

static UINT mib2IpNet[] = { 1,3,6,1,2,1,4,22,1 };
static PMIB_IPNETTABLE ipNetTable;

static DWORD copyIpNetPhysAddr(AsnAny *value, void *src)
{
    PMIB_IPNETROW row = (PMIB_IPNETROW)((BYTE *)src - FIELD_OFFSET(MIB_IPNETROW,
                                        dwPhysAddrLen));

    setStringValue(value, ASN_OCTETSTRING, row->dwPhysAddrLen, row->bPhysAddr);
    return SNMP_ERRORSTATUS_NOERROR;
}

static struct structToAsnValue mib2IpNetMap[] = {
    { FIELD_OFFSET(MIB_IPNETROW, dwIndex), copyInt },
    { FIELD_OFFSET(MIB_IPNETROW, dwPhysAddrLen), copyIpNetPhysAddr },
    { FIELD_OFFSET(MIB_IPNETROW, dwAddr), copyIpAddr },
    { FIELD_OFFSET(MIB_IPNETROW, dwType), copyInt },
};

static void mib2IpNetInit(void)
{
    DWORD size = 0, ret = GetIpNetTable(NULL, &size, FALSE);

    if (ret == ERROR_INSUFFICIENT_BUFFER)
    {
        MIB_IPNETTABLE *table = HeapAlloc(GetProcessHeap(), 0, size);
        if (table)
        {
            if (!GetIpNetTable(table, &size, FALSE)) ipNetTable = table;
            else HeapFree(GetProcessHeap(), 0, table );
        }
    }
}

static void mib2IpNetCleanup(void)
{
    HeapFree(GetProcessHeap(), 0, ipNetTable);
}

static BOOL mib2IpNetQuery(BYTE bPduType, SnmpVarBind *pVarBind,
    AsnInteger32 *pErrorStatus)
{
    AsnObjectIdentifier myOid = DEFINE_OID(mib2IpNet);
    BOOL ret = TRUE;

    TRACE("(0x%02x, %s, %p)\n", bPduType, SnmpUtilOidToA(&pVarBind->name),
        pErrorStatus);

    switch (bPduType)
    {
    case SNMP_PDU_GET:
    case SNMP_PDU_GETNEXT:
        if (!ipNetTable)
            *pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME;
        else
        {
            UINT tableIndex = 0, item = 0;

            *pErrorStatus = getItemAndIntegerInstanceFromOid(&pVarBind->name,
                &myOid, bPduType, &item, &tableIndex);
            if (!*pErrorStatus)
            {
                assert(tableIndex);
                assert(item);
                if (tableIndex > ipNetTable->dwNumEntries)
                    *pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME;
                else
                {
                    *pErrorStatus = mapStructEntryToValue(mib2IpNetMap,
                        DEFINE_SIZEOF(mib2IpNetMap),
                        &ipNetTable[tableIndex - 1], item, bPduType, pVarBind);
                    if (!*pErrorStatus && bPduType == SNMP_PDU_GETNEXT)
                        ret = setOidWithItemAndInteger(&pVarBind->name, &myOid,
                            item, tableIndex);
                }
            }
        }
        break;
    case SNMP_PDU_SET:
        *pErrorStatus = SNMP_ERRORSTATUS_READONLY;
        ret = FALSE;
        break;
    default:
        FIXME("0x%02x: unsupported PDU type\n", bPduType);
        *pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME;
    }
    return ret;
}

static UINT mib2Icmp[] = { 1,3,6,1,2,1,5 };
static MIB_ICMP icmpStats;

static void mib2IcmpInit(void)
{
    GetIcmpStatistics(&icmpStats);
}

static struct structToAsnValue mib2IcmpMap[] = {
    { FIELD_OFFSET(MIBICMPINFO, icmpInStats.dwMsgs), copyInt },
    { FIELD_OFFSET(MIBICMPINFO, icmpInStats.dwErrors), copyInt },
    { FIELD_OFFSET(MIBICMPINFO, icmpInStats.dwDestUnreachs), copyInt },
    { FIELD_OFFSET(MIBICMPINFO, icmpInStats.dwTimeExcds), copyInt },
    { FIELD_OFFSET(MIBICMPINFO, icmpInStats.dwParmProbs), copyInt },
    { FIELD_OFFSET(MIBICMPINFO, icmpInStats.dwSrcQuenchs), copyInt },
    { FIELD_OFFSET(MIBICMPINFO, icmpInStats.dwRedirects), copyInt },
    { FIELD_OFFSET(MIBICMPINFO, icmpInStats.dwEchos), copyInt },
    { FIELD_OFFSET(MIBICMPINFO, icmpInStats.dwEchoReps), copyInt },
    { FIELD_OFFSET(MIBICMPINFO, icmpInStats.dwTimestamps), copyInt },
    { FIELD_OFFSET(MIBICMPINFO, icmpInStats.dwTimestampReps), copyInt },
    { FIELD_OFFSET(MIBICMPINFO, icmpInStats.dwAddrMasks), copyInt },
    { FIELD_OFFSET(MIBICMPINFO, icmpInStats.dwAddrMaskReps), copyInt },
    { FIELD_OFFSET(MIBICMPINFO, icmpOutStats.dwMsgs), copyInt },
    { FIELD_OFFSET(MIBICMPINFO, icmpOutStats.dwErrors), copyInt },
    { FIELD_OFFSET(MIBICMPINFO, icmpOutStats.dwDestUnreachs), copyInt },
    { FIELD_OFFSET(MIBICMPINFO, icmpOutStats.dwTimeExcds), copyInt },
    { FIELD_OFFSET(MIBICMPINFO, icmpOutStats.dwParmProbs), copyInt },
    { FIELD_OFFSET(MIBICMPINFO, icmpOutStats.dwSrcQuenchs), copyInt },
    { FIELD_OFFSET(MIBICMPINFO, icmpOutStats.dwRedirects), copyInt },
    { FIELD_OFFSET(MIBICMPINFO, icmpOutStats.dwEchos), copyInt },
    { FIELD_OFFSET(MIBICMPINFO, icmpOutStats.dwEchoReps), copyInt },
    { FIELD_OFFSET(MIBICMPINFO, icmpOutStats.dwTimestamps), copyInt },
    { FIELD_OFFSET(MIBICMPINFO, icmpOutStats.dwTimestampReps), copyInt },
    { FIELD_OFFSET(MIBICMPINFO, icmpOutStats.dwAddrMasks), copyInt },
    { FIELD_OFFSET(MIBICMPINFO, icmpOutStats.dwAddrMaskReps), copyInt },
};

static BOOL mib2IcmpQuery(BYTE bPduType, SnmpVarBind *pVarBind,
    AsnInteger32 *pErrorStatus)
{
    AsnObjectIdentifier myOid = DEFINE_OID(mib2Icmp);
    UINT item = 0;
    BOOL ret = TRUE;

    TRACE("(0x%02x, %s, %p)\n", bPduType, SnmpUtilOidToA(&pVarBind->name),
        pErrorStatus);

    switch (bPduType)
    {
    case SNMP_PDU_GET:
    case SNMP_PDU_GETNEXT:
        *pErrorStatus = getItemFromOid(&pVarBind->name, &myOid, bPduType,
            &item);
        if (!*pErrorStatus)
        {
            *pErrorStatus = mapStructEntryToValue(mib2IcmpMap,
                DEFINE_SIZEOF(mib2IcmpMap), &icmpStats, item, bPduType,
                pVarBind);
            if (!*pErrorStatus && bPduType == SNMP_PDU_GETNEXT)
                ret = setOidWithItem(&pVarBind->name, &myOid, item);
        }
        break;
    case SNMP_PDU_SET:
        *pErrorStatus = SNMP_ERRORSTATUS_READONLY;
        ret = FALSE;
        break;
    default:
        FIXME("0x%02x: unsupported PDU type\n", bPduType);
        *pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME;
    }
    return ret;
}

static UINT mib2Tcp[] = { 1,3,6,1,2,1,6 };
static MIB_TCPSTATS tcpStats;

static void mib2TcpInit(void)
{
    GetTcpStatistics(&tcpStats);
}

static struct structToAsnValue mib2TcpMap[] = {
    { FIELD_OFFSET(MIB_TCPSTATS, dwRtoAlgorithm), copyInt },
    { FIELD_OFFSET(MIB_TCPSTATS, dwRtoMin), copyInt },
    { FIELD_OFFSET(MIB_TCPSTATS, dwRtoMax), copyInt },
    { FIELD_OFFSET(MIB_TCPSTATS, dwMaxConn), copyInt },
    { FIELD_OFFSET(MIB_TCPSTATS, dwActiveOpens), copyInt },
    { FIELD_OFFSET(MIB_TCPSTATS, dwPassiveOpens), copyInt },
    { FIELD_OFFSET(MIB_TCPSTATS, dwAttemptFails), copyInt },
    { FIELD_OFFSET(MIB_TCPSTATS, dwEstabResets), copyInt },
    { FIELD_OFFSET(MIB_TCPSTATS, dwCurrEstab), copyInt },
    { FIELD_OFFSET(MIB_TCPSTATS, dwInSegs), copyInt },
    { FIELD_OFFSET(MIB_TCPSTATS, dwOutSegs), copyInt },
    { FIELD_OFFSET(MIB_TCPSTATS, dwRetransSegs), copyInt },
    { FIELD_OFFSET(MIB_TCPSTATS, dwInErrs), copyInt },
    { FIELD_OFFSET(MIB_TCPSTATS, dwOutRsts), copyInt },
    { FIELD_OFFSET(MIB_TCPSTATS, dwNumConns), copyInt },
};

static BOOL mib2TcpQuery(BYTE bPduType, SnmpVarBind *pVarBind,
    AsnInteger32 *pErrorStatus)
{
    AsnObjectIdentifier myOid = DEFINE_OID(mib2Tcp);
    UINT item = 0;
    BOOL ret = TRUE;

    TRACE("(0x%02x, %s, %p)\n", bPduType, SnmpUtilOidToA(&pVarBind->name),
        pErrorStatus);

    switch (bPduType)
    {
    case SNMP_PDU_GET:
    case SNMP_PDU_GETNEXT:
        *pErrorStatus = getItemFromOid(&pVarBind->name, &myOid, bPduType,
            &item);
        if (!*pErrorStatus)
        {
            *pErrorStatus = mapStructEntryToValue(mib2TcpMap,
                DEFINE_SIZEOF(mib2TcpMap), &tcpStats, item, bPduType, pVarBind);
            if (!*pErrorStatus && bPduType == SNMP_PDU_GETNEXT)
                ret = setOidWithItem(&pVarBind->name, &myOid, item);
        }
        break;
    case SNMP_PDU_SET:
        *pErrorStatus = SNMP_ERRORSTATUS_READONLY;
        ret = FALSE;
        break;
    default:
        FIXME("0x%02x: unsupported PDU type\n", bPduType);
        *pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME;
    }
    return ret;
}

static UINT mib2Udp[] = { 1,3,6,1,2,1,7 };
static MIB_UDPSTATS udpStats;

static void mib2UdpInit(void)
{
    GetUdpStatistics(&udpStats);
}

static struct structToAsnValue mib2UdpMap[] = {
    { FIELD_OFFSET(MIB_UDPSTATS, dwInDatagrams), copyInt },
    { FIELD_OFFSET(MIB_UDPSTATS, dwNoPorts), copyInt },
    { FIELD_OFFSET(MIB_UDPSTATS, dwInErrors), copyInt },
    { FIELD_OFFSET(MIB_UDPSTATS, dwOutDatagrams), copyInt },
};

static BOOL mib2UdpQuery(BYTE bPduType, SnmpVarBind *pVarBind,
    AsnInteger32 *pErrorStatus)
{
    AsnObjectIdentifier myOid = DEFINE_OID(mib2Udp);
    UINT item;
    BOOL ret = TRUE;

    TRACE("(0x%02x, %s, %p)\n", bPduType, SnmpUtilOidToA(&pVarBind->name),
        pErrorStatus);

    switch (bPduType)
    {
    case SNMP_PDU_GET:
    case SNMP_PDU_GETNEXT:
        *pErrorStatus = getItemFromOid(&pVarBind->name, &myOid, bPduType,
            &item);
        if (!*pErrorStatus)
        {
            *pErrorStatus = mapStructEntryToValue(mib2UdpMap,
                DEFINE_SIZEOF(mib2UdpMap), &udpStats, item, bPduType, pVarBind);
            if (!*pErrorStatus && bPduType == SNMP_PDU_GETNEXT)
                ret = setOidWithItem(&pVarBind->name, &myOid, item);
        }
        break;
    case SNMP_PDU_SET:
        *pErrorStatus = SNMP_ERRORSTATUS_READONLY;
        ret = FALSE;
        break;
    default:
        FIXME("0x%02x: unsupported PDU type\n", bPduType);
        *pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME;
    }
    return ret;
}

static UINT mib2UdpEntry[] = { 1,3,6,1,2,1,7,5,1 };
static PMIB_UDPTABLE udpTable;

static void mib2UdpEntryInit(void)
{
    DWORD size = 0, ret = GetUdpTable(NULL, &size, TRUE);

    if (ret == ERROR_INSUFFICIENT_BUFFER)
    {
        MIB_UDPTABLE *table = HeapAlloc(GetProcessHeap(), 0, size);
        if (table)
        {
            if (!GetUdpTable(table, &size, TRUE)) udpTable = table;
            else HeapFree(GetProcessHeap(), 0, table);
        }
    }
}

static void mib2UdpEntryCleanup(void)
{
    HeapFree(GetProcessHeap(), 0, udpTable);
}

static struct structToAsnValue mib2UdpEntryMap[] = {
    { FIELD_OFFSET(MIB_UDPROW, dwLocalAddr), copyIpAddr },
    { FIELD_OFFSET(MIB_UDPROW, dwLocalPort), copyInt },
};

static void oidToUdpRow(AsnObjectIdentifier *oid, void *dst)
{
    MIB_UDPROW *row = dst;

    assert(oid && oid->idLength >= 5);
    row->dwLocalAddr = oidToIpAddr(oid);
    row->dwLocalPort = oid->ids[4];
}

static int compareUdpRow(const void *a, const void *b)
{
    const MIB_UDPROW *key = a, *value = b;
    int ret;

    ret = key->dwLocalAddr - value->dwLocalAddr;
    if (ret == 0)
        ret = key->dwLocalPort - value->dwLocalPort;
    return ret;
}

static BOOL mib2UdpEntryQuery(BYTE bPduType, SnmpVarBind *pVarBind,
    AsnInteger32 *pErrorStatus)
{
    AsnObjectIdentifier myOid = DEFINE_OID(mib2UdpEntry);
    BOOL ret = TRUE;

    TRACE("(0x%02x, %s, %p)\n", bPduType, SnmpUtilOidToA(&pVarBind->name),
        pErrorStatus);

    switch (bPduType)
    {
    case SNMP_PDU_GET:
    case SNMP_PDU_GETNEXT:
        if (!udpTable)
            *pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME;
        else
        {
            UINT tableIndex = 0, item = 0;

            *pErrorStatus = getItemAndInstanceFromTable(&pVarBind->name, &myOid,
                5, bPduType, (struct GenericTable *)udpTable,
                sizeof(MIB_UDPROW), oidToUdpRow, compareUdpRow, &item,
                &tableIndex);
            if (!*pErrorStatus)
            {
                assert(tableIndex);
                assert(item);
                *pErrorStatus = mapStructEntryToValue(mib2UdpEntryMap,
                    DEFINE_SIZEOF(mib2UdpEntryMap),
                    &udpTable->table[tableIndex - 1], item, bPduType, pVarBind);
                if (!*pErrorStatus && bPduType == SNMP_PDU_GETNEXT)
                {
                    AsnObjectIdentifier oid;

                    ret = setOidWithItemAndIpAddr(&pVarBind->name, &myOid, item,
                        udpTable->table[tableIndex - 1].dwLocalAddr);
                    if (ret)
                    {
                        oid.idLength = 1;
                        oid.ids = &udpTable->table[tableIndex - 1].dwLocalPort;
                        ret = SnmpUtilOidAppend(&pVarBind->name, &oid);
                    }
                }
            }
        }
        break;
    case SNMP_PDU_SET:
        *pErrorStatus = SNMP_ERRORSTATUS_READONLY;
        ret = FALSE;
        break;
    default:
        FIXME("0x%02x: unsupported PDU type\n", bPduType);
        *pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME;
    }
    return ret;
}

/* This list MUST BE lexicographically sorted */
static struct mibImplementation supportedIDs[] = {
    { DEFINE_OID(mib2IfNumber), mib2IfNumberInit, mib2IfNumberQuery,
      mib2IfNumberCleanup },
    { DEFINE_OID(mib2IfEntry), NULL, mib2IfEntryQuery, NULL },
    { DEFINE_OID(mib2Ip), mib2IpStatsInit, mib2IpStatsQuery, NULL },
    { DEFINE_OID(mib2IpAddr), mib2IpAddrInit, mib2IpAddrQuery,
      mib2IpAddrCleanup },
    { DEFINE_OID(mib2IpRoute), mib2IpRouteInit, mib2IpRouteQuery,
      mib2IpRouteCleanup },
    { DEFINE_OID(mib2IpNet), mib2IpNetInit, mib2IpNetQuery, mib2IpNetCleanup },
    { DEFINE_OID(mib2Icmp), mib2IcmpInit, mib2IcmpQuery, NULL },
    { DEFINE_OID(mib2Tcp), mib2TcpInit, mib2TcpQuery, NULL },
    { DEFINE_OID(mib2Udp), mib2UdpInit, mib2UdpQuery, NULL },
    { DEFINE_OID(mib2UdpEntry), mib2UdpEntryInit, mib2UdpEntryQuery,
      mib2UdpEntryCleanup },
};
static UINT minSupportedIDLength;

/*****************************************************************************
 * SnmpExtensionInit [INETMIB1.@]
 */
BOOL WINAPI SnmpExtensionInit(DWORD dwUptimeReference,
    HANDLE *phSubagentTrapEvent, AsnObjectIdentifier *pFirstSupportedRegion)
{
    AsnObjectIdentifier myOid = DEFINE_OID(mib2System);
    UINT i;

    TRACE("(%d, %p, %p)\n", dwUptimeReference, phSubagentTrapEvent,
        pFirstSupportedRegion);

    minSupportedIDLength = UINT_MAX;
    for (i = 0; i < sizeof(supportedIDs) / sizeof(supportedIDs[0]); i++)
    {
        if (supportedIDs[i].init)
            supportedIDs[i].init();
        if (supportedIDs[i].name.idLength < minSupportedIDLength)
            minSupportedIDLength = supportedIDs[i].name.idLength;
    }
    *phSubagentTrapEvent = NULL;
    SnmpUtilOidCpy(pFirstSupportedRegion, &myOid);
    return TRUE;
}

static void cleanup(void)
{
    UINT i;

    for (i = 0; i < sizeof(supportedIDs) / sizeof(supportedIDs[0]); i++)
        if (supportedIDs[i].cleanup)
            supportedIDs[i].cleanup();
}

static struct mibImplementation *findSupportedQuery(UINT *ids, UINT idLength,
    UINT *matchingIndex)
{
    int indexHigh = DEFINE_SIZEOF(supportedIDs) - 1, indexLow = 0, i;
    struct mibImplementation *impl = NULL;
    AsnObjectIdentifier oid1 = { idLength, ids};

    if (!idLength)
        return NULL;
    for (i = (indexLow + indexHigh) / 2; !impl && indexLow <= indexHigh;
         i = (indexLow + indexHigh) / 2)
    {
        INT cmp;

        cmp = SnmpUtilOidNCmp(&oid1, &supportedIDs[i].name, idLength);
        if (!cmp)
        {
            impl = &supportedIDs[i];
            *matchingIndex = i;
        }
        else if (cmp > 0)
            indexLow = i + 1;
        else
            indexHigh = i - 1;
    }
    return impl;
}

/*****************************************************************************
 * SnmpExtensionQuery [INETMIB1.@]
 */
BOOL WINAPI SnmpExtensionQuery(BYTE bPduType, SnmpVarBindList *pVarBindList,
    AsnInteger32 *pErrorStatus, AsnInteger32 *pErrorIndex)
{
    AsnObjectIdentifier mib2oid = DEFINE_OID(mib2);
    AsnInteger32 error = SNMP_ERRORSTATUS_NOERROR, errorIndex = 0;
    UINT i;
    BOOL ret = TRUE;

    TRACE("(0x%02x, %p, %p, %p)\n", bPduType, pVarBindList,
        pErrorStatus, pErrorIndex);

    for (i = 0; !error && i < pVarBindList->len; i++)
    {
        /* Ignore any OIDs not in MIB2 */
        if (!SnmpUtilOidNCmp(&pVarBindList->list[i].name, &mib2oid,
            mib2oid.idLength))
        {
            struct mibImplementation *impl = NULL;
            UINT len, matchingIndex = 0;

            TRACE("%s\n", SnmpUtilOidToA(&pVarBindList->list[i].name));
            /* Search for an implementation matching as many octets as possible
             */
            for (len = pVarBindList->list[i].name.idLength;
                len >= minSupportedIDLength && !impl; len--)
                impl = findSupportedQuery(pVarBindList->list[i].name.ids, len,
                    &matchingIndex);
            if (impl && impl->query)
                ret = impl->query(bPduType, &pVarBindList->list[i], &error);
            else
                error = SNMP_ERRORSTATUS_NOSUCHNAME;
            if (error == SNMP_ERRORSTATUS_NOSUCHNAME &&
                bPduType == SNMP_PDU_GETNEXT)
            {
                /* GetNext is special: it finds the successor to the given OID,
                 * so we have to continue until an implementation handles the
                 * query or we exhaust the table of supported OIDs.
                 */
                for (matchingIndex++; error == SNMP_ERRORSTATUS_NOSUCHNAME &&
                    matchingIndex < DEFINE_SIZEOF(supportedIDs);
                    matchingIndex++)
                {
                    error = SNMP_ERRORSTATUS_NOERROR;
                    impl = &supportedIDs[matchingIndex];
                    if (impl->query)
                        ret = impl->query(bPduType, &pVarBindList->list[i],
                            &error);
                    else
                        error = SNMP_ERRORSTATUS_NOSUCHNAME;
                }
                /* If the query still isn't resolved, set the OID to the
                 * successor to the last entry in the table.
                 */
                if (error == SNMP_ERRORSTATUS_NOSUCHNAME)
                {
                    SnmpUtilOidFree(&pVarBindList->list[i].name);
                    ret = SnmpUtilOidCpy(&pVarBindList->list[i].name,
                        &supportedIDs[matchingIndex - 1].name);
                    pVarBindList->list[i].name.ids[
                        pVarBindList->list[i].name.idLength - 1] += 1;
                }
            }
            if (error)
                errorIndex = i + 1;
        }
    }
    *pErrorStatus = error;
    *pErrorIndex = errorIndex;
    return ret;
}

/*****************************************************************************
 * DllMain [INETMIB1.@]
 */
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
    TRACE("(0x%p, %d, %p)\n", hinstDLL, fdwReason, lpvReserved);

    switch (fdwReason)
    {
        case DLL_PROCESS_ATTACH:
            DisableThreadLibraryCalls(hinstDLL);
            break;
        case DLL_PROCESS_DETACH:
            cleanup();
            break;
        default:
            break;
    }

    return TRUE;
}
