#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 #include #include #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; }