140 lines
4.3 KiB
C
140 lines
4.3 KiB
C
#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;
|
|
}
|