|
|
#include "oscfg.h"
#include "ndis.h"
#include "ip6imp.h"
#include "ip6def.h"
#include "ipexport.h"
#include "icmp.h"
#include "neighbor.h"
#include "route.h"
#include <tdiinfo.h>
#include <tdi.h>
#include <tdistat.h>
#include "info.h"
#include "fragment.h"
//* IPv6QueryInfo - IP query information handler.
//
// Called by the upper layer when it wants to query information about us.
// We take in an ID, a buffer and length, and a context value, and return
// whatever information we can.
//
// Input: ID - Pointer to ID structure.
// Buffer - Pointer to buffer chain.
// Size - Pointer to size in bytes of buffer. On return, filled
// in with bytes read.
// Context - Pointer to context value.
//
// Returns: TDI_STATUS of attempt to read information.
//
TDI_STATUS IPv6QueryInfo( TDIObjectID *ID, PNDIS_BUFFER Buffer, uint *Size, void *Context, uint ContextSize) { uint BufferSize = *Size; uint BytesCopied; uint Entity; uint Instance;
Entity = ID->toi_entity.tei_entity; Instance = ID->toi_entity.tei_instance;
*Size = 0; // Set to 0 in case of an error.
// See if it's something we might handle.
if ((Entity != CL_NL_ENTITY) || (Instance != 0)) return TDI_INVALID_REQUEST;
// The request is for us.
if ((ID->toi_class != INFO_CLASS_PROTOCOL) && (ID->toi_type != INFO_TYPE_PROVIDER)) return TDI_INVALID_PARAMETER;
switch (ID->toi_id) { case IP6_MIB_STATS_ID: { uint Offset = 0; int fStatus; IPInternalPerCpuStats SumCpuStats;
if (BufferSize < sizeof(IPSNMPInfo)) return TDI_BUFFER_TOO_SMALL; IPSInfo.ipsi_defaultttl = DefaultCurHopLimit; IPSInfo.ipsi_reasmtimeout = DEFAULT_REASSEMBLY_TIMEOUT; IPSInfo.ipsi_forwarding = (NumForwardingInterfaces > 0)? IP_FORWARDING : IP_NOT_FORWARDING; IPSGetTotalCounts(&SumCpuStats); IPSInfo.ipsi_inreceives = SumCpuStats.ics_inreceives; IPSInfo.ipsi_indelivers = SumCpuStats.ics_indelivers; IPSInfo.ipsi_outrequests = SumCpuStats.ics_outrequests; IPSInfo.ipsi_forwdatagrams = SumCpuStats.ics_forwdatagrams;
fStatus = CopyToNdisSafe(Buffer, NULL, (PVOID)&IPSInfo, sizeof(IPSNMPInfo), &Offset); if (!fStatus) return TDI_NO_RESOURCES;
BytesCopied = sizeof(IPSNMPInfo); } break;
case ICMP6_MIB_STATS_ID: { uint Offset = 0; int fStatus;
if (BufferSize < sizeof(ICMPv6SNMPInfo)) return TDI_BUFFER_TOO_SMALL;
fStatus = CopyToNdisSafe(Buffer, &Buffer, (uchar *) &ICMPv6InStats, sizeof(ICMPv6Stats), &Offset); if (!fStatus) return (TDI_NO_RESOURCES);
fStatus = CopyToNdisSafe(Buffer, NULL, (uchar *) &ICMPv6OutStats, sizeof(ICMPv6Stats), &Offset); if (!fStatus) return (TDI_NO_RESOURCES);
BytesCopied = sizeof(ICMPv6SNMPInfo); } break;
case IP6_GET_BEST_ROUTE_ID: { TDI_ADDRESS_IP6 *In = (TDI_ADDRESS_IP6 *) Context; IP6RouteEntry Ire; uint Offset; IP_STATUS Status; int fStatus;
if (ContextSize < sizeof(TDI_ADDRESS_IP6)) return TDI_INVALID_PARAMETER;
if (BufferSize < sizeof(IP6RouteEntry)) return TDI_BUFFER_OVERFLOW;
Status = GetBestRouteInfo((struct in6_addr *)In->sin6_addr, In->sin6_scope_id, &Ire); if (Status != IP_SUCCESS) return TDI_DEST_HOST_UNREACH;
Offset = 0; fStatus = CopyToNdisSafe(Buffer, &Buffer, (PVOID)&Ire, Ire.ire_Length, &Offset); if (!fStatus) return TDI_NO_RESOURCES;
BytesCopied = sizeof(IP6RouteEntry); } break;
default: return TDI_INVALID_PARAMETER; }
*Size = BytesCopied; return TDI_SUCCESS; }
|