123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029 |
- /*
- * TAP-Windows -- A kernel driver to provide virtual tap
- * device functionality on Windows.
- *
- * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson.
- *
- * This source code is Copyright (C) 2002-2014 OpenVPN Technologies, Inc.,
- * and is released under the GPL version 2 (see below).
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * This program 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program (see the file COPYING included with this
- * distribution); if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
- //
- // Include files.
- //
- #include "tap.h"
- #ifndef DBG
- #define DBG_PRINT_OID_NAME
- #else
- VOID
- DBG_PRINT_OID_NAME(
- __in NDIS_OID Oid
- )
- {
- PCHAR oidName = NULL;
- switch (Oid){
- #undef MAKECASE
- #define MAKECASE(oidx) case oidx: oidName = #oidx "\n"; break;
- /* Operational OIDs */
- MAKECASE(OID_GEN_SUPPORTED_LIST)
- MAKECASE(OID_GEN_HARDWARE_STATUS)
- MAKECASE(OID_GEN_MEDIA_SUPPORTED)
- MAKECASE(OID_GEN_MEDIA_IN_USE)
- MAKECASE(OID_GEN_MAXIMUM_LOOKAHEAD)
- MAKECASE(OID_GEN_MAXIMUM_FRAME_SIZE)
- MAKECASE(OID_GEN_LINK_SPEED)
- MAKECASE(OID_GEN_TRANSMIT_BUFFER_SPACE)
- MAKECASE(OID_GEN_RECEIVE_BUFFER_SPACE)
- MAKECASE(OID_GEN_TRANSMIT_BLOCK_SIZE)
- MAKECASE(OID_GEN_RECEIVE_BLOCK_SIZE)
- MAKECASE(OID_GEN_VENDOR_ID)
- MAKECASE(OID_GEN_VENDOR_DESCRIPTION)
- MAKECASE(OID_GEN_VENDOR_DRIVER_VERSION)
- MAKECASE(OID_GEN_CURRENT_PACKET_FILTER)
- MAKECASE(OID_GEN_CURRENT_LOOKAHEAD)
- MAKECASE(OID_GEN_DRIVER_VERSION)
- MAKECASE(OID_GEN_MAXIMUM_TOTAL_SIZE)
- MAKECASE(OID_GEN_PROTOCOL_OPTIONS)
- MAKECASE(OID_GEN_MAC_OPTIONS)
- MAKECASE(OID_GEN_MEDIA_CONNECT_STATUS)
- MAKECASE(OID_GEN_MAXIMUM_SEND_PACKETS)
- MAKECASE(OID_GEN_SUPPORTED_GUIDS)
- MAKECASE(OID_GEN_NETWORK_LAYER_ADDRESSES)
- MAKECASE(OID_GEN_TRANSPORT_HEADER_OFFSET)
- MAKECASE(OID_GEN_MEDIA_CAPABILITIES)
- MAKECASE(OID_GEN_PHYSICAL_MEDIUM)
- MAKECASE(OID_GEN_MACHINE_NAME)
- MAKECASE(OID_GEN_VLAN_ID)
- MAKECASE(OID_GEN_RNDIS_CONFIG_PARAMETER)
- /* Operational OIDs for NDIS 6.0 */
- MAKECASE(OID_GEN_MAX_LINK_SPEED)
- MAKECASE(OID_GEN_LINK_STATE)
- MAKECASE(OID_GEN_LINK_PARAMETERS)
- MAKECASE(OID_GEN_MINIPORT_RESTART_ATTRIBUTES)
- MAKECASE(OID_GEN_ENUMERATE_PORTS)
- MAKECASE(OID_GEN_PORT_STATE)
- MAKECASE(OID_GEN_PORT_AUTHENTICATION_PARAMETERS)
- MAKECASE(OID_GEN_INTERRUPT_MODERATION)
- MAKECASE(OID_GEN_PHYSICAL_MEDIUM_EX)
- /* Statistical OIDs */
- MAKECASE(OID_GEN_XMIT_OK)
- MAKECASE(OID_GEN_RCV_OK)
- MAKECASE(OID_GEN_XMIT_ERROR)
- MAKECASE(OID_GEN_RCV_ERROR)
- MAKECASE(OID_GEN_RCV_NO_BUFFER)
- MAKECASE(OID_GEN_DIRECTED_BYTES_XMIT)
- MAKECASE(OID_GEN_DIRECTED_FRAMES_XMIT)
- MAKECASE(OID_GEN_MULTICAST_BYTES_XMIT)
- MAKECASE(OID_GEN_MULTICAST_FRAMES_XMIT)
- MAKECASE(OID_GEN_BROADCAST_BYTES_XMIT)
- MAKECASE(OID_GEN_BROADCAST_FRAMES_XMIT)
- MAKECASE(OID_GEN_DIRECTED_BYTES_RCV)
- MAKECASE(OID_GEN_DIRECTED_FRAMES_RCV)
- MAKECASE(OID_GEN_MULTICAST_BYTES_RCV)
- MAKECASE(OID_GEN_MULTICAST_FRAMES_RCV)
- MAKECASE(OID_GEN_BROADCAST_BYTES_RCV)
- MAKECASE(OID_GEN_BROADCAST_FRAMES_RCV)
- MAKECASE(OID_GEN_RCV_CRC_ERROR)
- MAKECASE(OID_GEN_TRANSMIT_QUEUE_LENGTH)
- /* Statistical OIDs for NDIS 6.0 */
- MAKECASE(OID_GEN_STATISTICS)
- MAKECASE(OID_GEN_BYTES_RCV)
- MAKECASE(OID_GEN_BYTES_XMIT)
- MAKECASE(OID_GEN_RCV_DISCARDS)
- MAKECASE(OID_GEN_XMIT_DISCARDS)
- /* Misc OIDs */
- MAKECASE(OID_GEN_GET_TIME_CAPS)
- MAKECASE(OID_GEN_GET_NETCARD_TIME)
- MAKECASE(OID_GEN_NETCARD_LOAD)
- MAKECASE(OID_GEN_DEVICE_PROFILE)
- MAKECASE(OID_GEN_INIT_TIME_MS)
- MAKECASE(OID_GEN_RESET_COUNTS)
- MAKECASE(OID_GEN_MEDIA_SENSE_COUNTS)
- /* PnP power management operational OIDs */
- MAKECASE(OID_PNP_CAPABILITIES)
- MAKECASE(OID_PNP_SET_POWER)
- MAKECASE(OID_PNP_QUERY_POWER)
- MAKECASE(OID_PNP_ADD_WAKE_UP_PATTERN)
- MAKECASE(OID_PNP_REMOVE_WAKE_UP_PATTERN)
- MAKECASE(OID_PNP_ENABLE_WAKE_UP)
- MAKECASE(OID_PNP_WAKE_UP_PATTERN_LIST)
- /* PnP power management statistical OIDs */
- MAKECASE(OID_PNP_WAKE_UP_ERROR)
- MAKECASE(OID_PNP_WAKE_UP_OK)
- /* Ethernet operational OIDs */
- MAKECASE(OID_802_3_PERMANENT_ADDRESS)
- MAKECASE(OID_802_3_CURRENT_ADDRESS)
- MAKECASE(OID_802_3_MULTICAST_LIST)
- MAKECASE(OID_802_3_MAXIMUM_LIST_SIZE)
- MAKECASE(OID_802_3_MAC_OPTIONS)
- /* Ethernet operational OIDs for NDIS 6.0 */
- MAKECASE(OID_802_3_ADD_MULTICAST_ADDRESS)
- MAKECASE(OID_802_3_DELETE_MULTICAST_ADDRESS)
- /* Ethernet statistical OIDs */
- MAKECASE(OID_802_3_RCV_ERROR_ALIGNMENT)
- MAKECASE(OID_802_3_XMIT_ONE_COLLISION)
- MAKECASE(OID_802_3_XMIT_MORE_COLLISIONS)
- MAKECASE(OID_802_3_XMIT_DEFERRED)
- MAKECASE(OID_802_3_XMIT_MAX_COLLISIONS)
- MAKECASE(OID_802_3_RCV_OVERRUN)
- MAKECASE(OID_802_3_XMIT_UNDERRUN)
- MAKECASE(OID_802_3_XMIT_HEARTBEAT_FAILURE)
- MAKECASE(OID_802_3_XMIT_TIMES_CRS_LOST)
- MAKECASE(OID_802_3_XMIT_LATE_COLLISIONS)
- /* TCP/IP OIDs */
- MAKECASE(OID_TCP_TASK_OFFLOAD)
- MAKECASE(OID_TCP_TASK_IPSEC_ADD_SA)
- MAKECASE(OID_TCP_TASK_IPSEC_DELETE_SA)
- MAKECASE(OID_TCP_SAN_SUPPORT)
- MAKECASE(OID_TCP_TASK_IPSEC_ADD_UDPESP_SA)
- MAKECASE(OID_TCP_TASK_IPSEC_DELETE_UDPESP_SA)
- MAKECASE(OID_TCP4_OFFLOAD_STATS)
- MAKECASE(OID_TCP6_OFFLOAD_STATS)
- MAKECASE(OID_IP4_OFFLOAD_STATS)
- MAKECASE(OID_IP6_OFFLOAD_STATS)
- /* TCP offload OIDs for NDIS 6 */
- MAKECASE(OID_TCP_OFFLOAD_CURRENT_CONFIG)
- MAKECASE(OID_TCP_OFFLOAD_PARAMETERS)
- MAKECASE(OID_TCP_OFFLOAD_HARDWARE_CAPABILITIES)
- MAKECASE(OID_TCP_CONNECTION_OFFLOAD_CURRENT_CONFIG)
- MAKECASE(OID_TCP_CONNECTION_OFFLOAD_HARDWARE_CAPABILITIES)
- MAKECASE(OID_OFFLOAD_ENCAPSULATION)
- #if (NDIS_SUPPORT_NDIS620)
- /* VMQ OIDs for NDIS 6.20 */
- MAKECASE(OID_RECEIVE_FILTER_FREE_QUEUE)
- MAKECASE(OID_RECEIVE_FILTER_CLEAR_FILTER)
- MAKECASE(OID_RECEIVE_FILTER_ALLOCATE_QUEUE)
- MAKECASE(OID_RECEIVE_FILTER_QUEUE_ALLOCATION_COMPLETE)
- MAKECASE(OID_RECEIVE_FILTER_SET_FILTER)
- #endif
- #if (NDIS_SUPPORT_NDIS630)
- /* NDIS QoS OIDs for NDIS 6.30 */
- MAKECASE(OID_QOS_PARAMETERS)
- #endif
- }
- if (oidName)
- {
- DEBUGP(("OID: %s", oidName));
- }
- else
- {
- DEBUGP(("<** Unknown OID 0x%08x **>\n", Oid));
- }
- }
- #endif // DBG
- //======================================================================
- // TAP NDIS 6 OID Request Callbacks
- //======================================================================
- NDIS_STATUS
- tapSetMulticastList(
- __in PTAP_ADAPTER_CONTEXT Adapter,
- __in PNDIS_OID_REQUEST OidRequest
- )
- {
- NDIS_STATUS status = NDIS_STATUS_SUCCESS;
- //
- // Initialize.
- //
- OidRequest->DATA.SET_INFORMATION.BytesNeeded = MACADDR_SIZE;
- OidRequest->DATA.SET_INFORMATION.BytesRead
- = OidRequest->DATA.SET_INFORMATION.InformationBufferLength;
- do
- {
- if (OidRequest->DATA.SET_INFORMATION.InformationBufferLength % MACADDR_SIZE)
- {
- status = NDIS_STATUS_INVALID_LENGTH;
- break;
- }
- if (OidRequest->DATA.SET_INFORMATION.InformationBufferLength > (TAP_MAX_MCAST_LIST * MACADDR_SIZE))
- {
- status = NDIS_STATUS_MULTICAST_FULL;
- OidRequest->DATA.SET_INFORMATION.BytesNeeded = TAP_MAX_MCAST_LIST * MACADDR_SIZE;
- break;
- }
- // BUGBUG!!! Is lock needed??? If so, use NDIS_RW_LOCK. Also apply to packet filter.
- NdisZeroMemory(Adapter->MCList,
- TAP_MAX_MCAST_LIST * MACADDR_SIZE);
- NdisMoveMemory(Adapter->MCList,
- OidRequest->DATA.SET_INFORMATION.InformationBuffer,
- OidRequest->DATA.SET_INFORMATION.InformationBufferLength);
- Adapter->ulMCListSize = OidRequest->DATA.SET_INFORMATION.InformationBufferLength / MACADDR_SIZE;
- } while(FALSE);
- return status;
- }
- NDIS_STATUS
- tapSetPacketFilter(
- __in PTAP_ADAPTER_CONTEXT Adapter,
- __in ULONG PacketFilter
- )
- {
- NDIS_STATUS status = NDIS_STATUS_SUCCESS;
- // any bits not supported?
- if (PacketFilter & ~(TAP_SUPPORTED_FILTERS))
- {
- DEBUGP (("[TAP] Unsupported packet filter: 0x%08x\n", PacketFilter));
- status = NDIS_STATUS_NOT_SUPPORTED;
- }
- else
- {
- // Any actual filtering changes?
- if (PacketFilter != Adapter->PacketFilter)
- {
- //
- // Change the filtering modes on hardware
- //
- // Save the new packet filter value
- Adapter->PacketFilter = PacketFilter;
- }
- }
- return status;
- }
- NDIS_STATUS
- AdapterSetPowerD0(
- __in PTAP_ADAPTER_CONTEXT Adapter
- )
- /*++
- Routine Description:
- NIC power has been restored to the working power state (D0).
- Prepare the NIC for normal operation:
- - Restore hardware context (packet filters, multicast addresses, MAC address, etc.)
- - Enable interrupts and the NIC's DMA engine.
- Arguments:
- Adapter - Pointer to adapter block
- Return Value:
- NDIS_STATUS
- --*/
- {
- NDIS_STATUS status = NDIS_STATUS_SUCCESS;
- DEBUGP (("[TAP] PowerState: Fully powered\n"));
- // Start data path...
- return status;
- }
- NDIS_STATUS
- AdapterSetPowerLow(
- __in PTAP_ADAPTER_CONTEXT Adapter,
- __in NDIS_DEVICE_POWER_STATE PowerState
- )
- /*++
- Routine Description:
- The NIC is about to be transitioned to a low power state.
- Prepare the NIC for the sleeping state:
- - Disable interrupts and the NIC's DMA engine, cancel timers.
- - Save any hardware context that the NIC cannot preserve in
- a sleeping state (packet filters, multicast addresses,
- the current MAC address, etc.)
- A miniport driver cannot access the NIC hardware after
- the NIC has been set to the D3 state by the bus driver.
- Miniport drivers NDIS v6.30 and above
- Do NOT wait for NDIS to return the ownership of all
- NBLs from outstanding receive indications
- Retain ownership of all the receive descriptors and
- packet buffers previously owned by the hardware.
- Arguments:
- Adapter - Pointer to adapter block
- PowerState - New power state
- Return Value:
- NDIS_STATUS
- --*/
- {
- NDIS_STATUS status = NDIS_STATUS_SUCCESS;
- DEBUGP (("[TAP] PowerState: Low-power\n"));
- //
- // Miniport drivers NDIS v6.20 and below are
- // paused prior the low power transition
- //
- // Check for paused state...
- // Verify data path stopped...
- return status;
- }
- NDIS_STATUS
- tapSetInformation(
- __in PTAP_ADAPTER_CONTEXT Adapter,
- __in PNDIS_OID_REQUEST OidRequest
- )
- /*++
- Routine Description:
- Helper function to perform a set OID request
- Arguments:
- Adapter -
- NdisSetRequest - The OID to set
- Return Value:
- NDIS_STATUS
- --*/
- {
- NDIS_STATUS status = NDIS_STATUS_SUCCESS;
- DBG_PRINT_OID_NAME(OidRequest->DATA.SET_INFORMATION.Oid);
- switch(OidRequest->DATA.SET_INFORMATION.Oid)
- {
- case OID_802_3_MULTICAST_LIST:
- //
- // Set the multicast address list on the NIC for packet reception.
- // The NIC driver can set a limit on the number of multicast
- // addresses bound protocol drivers can enable simultaneously.
- // NDIS returns NDIS_STATUS_MULTICAST_FULL if a protocol driver
- // exceeds this limit or if it specifies an invalid multicast
- // address.
- //
- status = tapSetMulticastList(Adapter,OidRequest);
- break;
- case OID_GEN_CURRENT_LOOKAHEAD:
- //
- // A protocol driver can set a suggested value for the number
- // of bytes to be used in its binding; however, the underlying
- // NIC driver is never required to limit its indications to
- // the value set.
- //
- if (OidRequest->DATA.SET_INFORMATION.InformationBufferLength != sizeof(ULONG))
- {
- OidRequest->DATA.SET_INFORMATION.BytesNeeded = sizeof(ULONG);
- status = NDIS_STATUS_INVALID_LENGTH;
- break;
- }
- Adapter->ulLookahead = *(PULONG)OidRequest->DATA.SET_INFORMATION.InformationBuffer;
- OidRequest->DATA.SET_INFORMATION.BytesRead = sizeof(ULONG);
- status = NDIS_STATUS_SUCCESS;
- break;
- case OID_GEN_CURRENT_PACKET_FILTER:
- //
- // Program the hardware to indicate the packets
- // of certain filter types.
- //
- if(OidRequest->DATA.SET_INFORMATION.InformationBufferLength != sizeof(ULONG))
- {
- OidRequest->DATA.SET_INFORMATION.BytesNeeded = sizeof(ULONG);
- status = NDIS_STATUS_INVALID_LENGTH;
- break;
- }
- OidRequest->DATA.SET_INFORMATION.BytesRead
- = OidRequest->DATA.SET_INFORMATION.InformationBufferLength;
- status = tapSetPacketFilter(
- Adapter,
- *((PULONG)OidRequest->DATA.SET_INFORMATION.InformationBuffer)
- );
- break;
- case OID_PNP_SET_POWER:
- {
- // Sanity check.
- if (OidRequest->DATA.SET_INFORMATION.InformationBufferLength
- < sizeof(NDIS_DEVICE_POWER_STATE)
- )
- {
- status = NDIS_STATUS_INVALID_LENGTH;
- }
- else
- {
- NDIS_DEVICE_POWER_STATE PowerState;
- PowerState = *(PNDIS_DEVICE_POWER_STATE UNALIGNED)OidRequest->DATA.SET_INFORMATION.InformationBuffer;
- OidRequest->DATA.SET_INFORMATION.BytesRead = sizeof(NDIS_DEVICE_POWER_STATE);
- if(PowerState < NdisDeviceStateD0 ||
- PowerState > NdisDeviceStateD3)
- {
- status = NDIS_STATUS_INVALID_DATA;
- }
- else
- {
- Adapter->CurrentPowerState = PowerState;
- if (PowerState == NdisDeviceStateD0)
- {
- status = AdapterSetPowerD0(Adapter);
- }
- else
- {
- status = AdapterSetPowerLow(Adapter, PowerState);
- }
- }
- }
- }
- break;
- #if (NDIS_SUPPORT_NDIS61)
- case OID_PNP_ADD_WAKE_UP_PATTERN:
- case OID_PNP_REMOVE_WAKE_UP_PATTERN:
- case OID_PNP_ENABLE_WAKE_UP:
- #endif
- ASSERT(!"NIC does not support wake on LAN OIDs");
- default:
- //
- // The entry point may by used by other requests
- //
- status = NDIS_STATUS_NOT_SUPPORTED;
- break;
- }
- return status;
- }
- NDIS_STATUS
- tapQueryInformation(
- __in PTAP_ADAPTER_CONTEXT Adapter,
- __in PNDIS_OID_REQUEST OidRequest
- )
- /*++
- Routine Description:
- Helper function to perform a query OID request
- Arguments:
- Adapter -
- OidRequest - The OID request that is being queried
- Return Value:
- NDIS_STATUS
- --*/
- {
- NDIS_STATUS status = NDIS_STATUS_SUCCESS;
- NDIS_MEDIUM Medium = TAP_MEDIUM_TYPE;
- NDIS_HARDWARE_STATUS HardwareStatus = NdisHardwareStatusReady;
- UCHAR VendorDesc[] = TAP_VENDOR_DESC;
- ULONG ulInfo;
- USHORT usInfo;
- ULONG64 ulInfo64;
- // Default to returning the ULONG value
- PVOID pInfo=NULL;
- ULONG ulInfoLen = sizeof(ulInfo);
- // ATTENTION!!! Ignore OIDs to noisy to print...
- if((OidRequest->DATA.QUERY_INFORMATION.Oid != OID_GEN_STATISTICS)
- && (OidRequest->DATA.QUERY_INFORMATION.Oid != OID_IP4_OFFLOAD_STATS)
- && (OidRequest->DATA.QUERY_INFORMATION.Oid != OID_IP6_OFFLOAD_STATS)
- )
- {
- DBG_PRINT_OID_NAME(OidRequest->DATA.QUERY_INFORMATION.Oid);
- }
- // Dispatch based on object identifier (OID).
- switch(OidRequest->DATA.QUERY_INFORMATION.Oid)
- {
- case OID_GEN_HARDWARE_STATUS:
- //
- // Specify the current hardware status of the underlying NIC as
- // one of the following NDIS_HARDWARE_STATUS-type values.
- //
- pInfo = (PVOID) &HardwareStatus;
- ulInfoLen = sizeof(NDIS_HARDWARE_STATUS);
- break;
- case OID_802_3_PERMANENT_ADDRESS:
- //
- // Return the MAC address of the NIC burnt in the hardware.
- //
- pInfo = Adapter->PermanentAddress;
- ulInfoLen = MACADDR_SIZE;
- break;
- case OID_802_3_CURRENT_ADDRESS:
- //
- // Return the MAC address the NIC is currently programmed to
- // use. Note that this address could be different from the
- // permananent address as the user can override using
- // registry. Read NdisReadNetworkAddress doc for more info.
- //
- pInfo = Adapter->CurrentAddress;
- ulInfoLen = MACADDR_SIZE;
- break;
- case OID_GEN_MEDIA_SUPPORTED:
- //
- // Return an array of media that are supported by the miniport.
- // This miniport only supports one medium (Ethernet), so the OID
- // returns identical results to OID_GEN_MEDIA_IN_USE.
- //
- __fallthrough;
- case OID_GEN_MEDIA_IN_USE:
- //
- // Return an array of media that are currently in use by the
- // miniport. This array should be a subset of the array returned
- // by OID_GEN_MEDIA_SUPPORTED.
- //
- pInfo = &Medium;
- ulInfoLen = sizeof(Medium);
- break;
- case OID_GEN_MAXIMUM_TOTAL_SIZE:
- //
- // Specify the maximum total packet length, in bytes, the NIC
- // supports including the header. A protocol driver might use
- // this returned length as a gauge to determine the maximum
- // size packet that a NIC driver could forward to the
- // protocol driver. The miniport driver must never indicate
- // up to the bound protocol driver packets received over the
- // network that are longer than the packet size specified by
- // OID_GEN_MAXIMUM_TOTAL_SIZE.
- //
- __fallthrough;
- case OID_GEN_TRANSMIT_BLOCK_SIZE:
- //
- // The OID_GEN_TRANSMIT_BLOCK_SIZE OID specifies the minimum
- // number of bytes that a single net packet occupies in the
- // transmit buffer space of the NIC. In our case, the transmit
- // block size is identical to its maximum packet size.
- __fallthrough;
- case OID_GEN_RECEIVE_BLOCK_SIZE:
- //
- // The OID_GEN_RECEIVE_BLOCK_SIZE OID specifies the amount of
- // storage, in bytes, that a single packet occupies in the receive
- // buffer space of the NIC.
- //
- ulInfo = (ULONG) TAP_MAX_FRAME_SIZE;
- pInfo = &ulInfo;
- break;
- case OID_GEN_INTERRUPT_MODERATION:
- {
- PNDIS_INTERRUPT_MODERATION_PARAMETERS moderationParams
- = (PNDIS_INTERRUPT_MODERATION_PARAMETERS)OidRequest->DATA.QUERY_INFORMATION.InformationBuffer;
- moderationParams->Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
- moderationParams->Header.Revision = NDIS_INTERRUPT_MODERATION_PARAMETERS_REVISION_1;
- moderationParams->Header.Size = NDIS_SIZEOF_INTERRUPT_MODERATION_PARAMETERS_REVISION_1;
- moderationParams->Flags = 0;
- moderationParams->InterruptModeration = NdisInterruptModerationNotSupported;
- ulInfoLen = NDIS_SIZEOF_INTERRUPT_MODERATION_PARAMETERS_REVISION_1;
- }
- break;
- case OID_PNP_QUERY_POWER:
- // Simply succeed this.
- break;
- case OID_GEN_VENDOR_ID:
- //
- // Specify a three-byte IEEE-registered vendor code, followed
- // by a single byte that the vendor assigns to identify a
- // particular NIC. The IEEE code uniquely identifies the vendor
- // and is the same as the three bytes appearing at the beginning
- // of the NIC hardware address. Vendors without an IEEE-registered
- // code should use the value 0xFFFFFF.
- //
- ulInfo = TAP_VENDOR_ID;
- pInfo = &ulInfo;
- break;
- case OID_GEN_VENDOR_DESCRIPTION:
- //
- // Specify a zero-terminated string describing the NIC vendor.
- //
- pInfo = VendorDesc;
- ulInfoLen = sizeof(VendorDesc);
- break;
- case OID_GEN_VENDOR_DRIVER_VERSION:
- //
- // Specify the vendor-assigned version number of the NIC driver.
- // The low-order half of the return value specifies the minor
- // version; the high-order half specifies the major version.
- //
- ulInfo = TAP_DRIVER_VENDOR_VERSION;
- pInfo = &ulInfo;
- break;
- case OID_GEN_DRIVER_VERSION:
- //
- // Specify the NDIS version in use by the NIC driver. The high
- // byte is the major version number; the low byte is the minor
- // version number.
- //
- usInfo = (USHORT) (TAP_NDIS_MAJOR_VERSION<<8) + TAP_NDIS_MINOR_VERSION;
- pInfo = (PVOID) &usInfo;
- ulInfoLen = sizeof(USHORT);
- break;
- case OID_802_3_MAXIMUM_LIST_SIZE:
- //
- // The maximum number of multicast addresses the NIC driver
- // can manage. This list is global for all protocols bound
- // to (or above) the NIC. Consequently, a protocol can receive
- // NDIS_STATUS_MULTICAST_FULL from the NIC driver when
- // attempting to set the multicast address list, even if
- // the number of elements in the given list is less than
- // the number originally returned for this query.
- //
- ulInfo = TAP_MAX_MCAST_LIST;
- pInfo = &ulInfo;
- break;
- case OID_GEN_XMIT_ERROR:
- ulInfo = (ULONG)
- (Adapter->TxAbortExcessCollisions +
- Adapter->TxDmaUnderrun +
- Adapter->TxLostCRS +
- Adapter->TxLateCollisions+
- Adapter->TransmitFailuresOther);
- pInfo = &ulInfo;
- break;
- case OID_GEN_RCV_ERROR:
- ulInfo = (ULONG)
- (Adapter->RxCrcErrors +
- Adapter->RxAlignmentErrors +
- Adapter->RxDmaOverrunErrors +
- Adapter->RxRuntErrors);
- pInfo = &ulInfo;
- break;
- case OID_GEN_RCV_DISCARDS:
- ulInfo = (ULONG)Adapter->RxResourceErrors;
- pInfo = &ulInfo;
- break;
- case OID_GEN_RCV_NO_BUFFER:
- ulInfo = (ULONG)Adapter->RxResourceErrors;
- pInfo = &ulInfo;
- break;
- case OID_GEN_XMIT_OK:
- ulInfo64 = Adapter->FramesTxBroadcast
- + Adapter->FramesTxMulticast
- + Adapter->FramesTxDirected;
- pInfo = &ulInfo64;
- if (OidRequest->DATA.QUERY_INFORMATION.InformationBufferLength >= sizeof(ULONG64) ||
- OidRequest->DATA.QUERY_INFORMATION.InformationBufferLength == 0)
- {
- ulInfoLen = sizeof(ULONG64);
- }
- else
- {
- ulInfoLen = sizeof(ULONG);
- }
- // We should always report that only 8 bytes are required to keep ndistest happy
- OidRequest->DATA.QUERY_INFORMATION.BytesNeeded = sizeof(ULONG64);
- break;
- case OID_GEN_RCV_OK:
- ulInfo64 = Adapter->FramesRxBroadcast
- + Adapter->FramesRxMulticast
- + Adapter->FramesRxDirected;
- pInfo = &ulInfo64;
- if (OidRequest->DATA.QUERY_INFORMATION.InformationBufferLength >= sizeof(ULONG64) ||
- OidRequest->DATA.QUERY_INFORMATION.InformationBufferLength == 0)
- {
- ulInfoLen = sizeof(ULONG64);
- }
- else
- {
- ulInfoLen = sizeof(ULONG);
- }
- // We should always report that only 8 bytes are required to keep ndistest happy
- OidRequest->DATA.QUERY_INFORMATION.BytesNeeded = sizeof(ULONG64);
- break;
- case OID_802_3_RCV_ERROR_ALIGNMENT:
- ulInfo = Adapter->RxAlignmentErrors;
- pInfo = &ulInfo;
- break;
- case OID_802_3_XMIT_ONE_COLLISION:
- ulInfo = Adapter->OneRetry;
- pInfo = &ulInfo;
- break;
- case OID_802_3_XMIT_MORE_COLLISIONS:
- ulInfo = Adapter->MoreThanOneRetry;
- pInfo = &ulInfo;
- break;
- case OID_802_3_XMIT_DEFERRED:
- ulInfo = Adapter->TxOKButDeferred;
- pInfo = &ulInfo;
- break;
- case OID_802_3_XMIT_MAX_COLLISIONS:
- ulInfo = Adapter->TxAbortExcessCollisions;
- pInfo = &ulInfo;
- break;
- case OID_802_3_RCV_OVERRUN:
- ulInfo = Adapter->RxDmaOverrunErrors;
- pInfo = &ulInfo;
- break;
- case OID_802_3_XMIT_UNDERRUN:
- ulInfo = Adapter->TxDmaUnderrun;
- pInfo = &ulInfo;
- break;
- case OID_GEN_STATISTICS:
- if (OidRequest->DATA.QUERY_INFORMATION.InformationBufferLength < sizeof(NDIS_STATISTICS_INFO))
- {
- status = NDIS_STATUS_INVALID_LENGTH;
- OidRequest->DATA.QUERY_INFORMATION.BytesNeeded = sizeof(NDIS_STATISTICS_INFO);
- break;
- }
- else
- {
- PNDIS_STATISTICS_INFO Statistics
- = (PNDIS_STATISTICS_INFO)OidRequest->DATA.QUERY_INFORMATION.InformationBuffer;
- {C_ASSERT(sizeof(NDIS_STATISTICS_INFO) >= NDIS_SIZEOF_STATISTICS_INFO_REVISION_1);}
- Statistics->Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
- Statistics->Header.Size = NDIS_SIZEOF_STATISTICS_INFO_REVISION_1;
- Statistics->Header.Revision = NDIS_STATISTICS_INFO_REVISION_1;
- Statistics->SupportedStatistics = TAP_SUPPORTED_STATISTICS;
- /* Bytes in */
- Statistics->ifHCInOctets =
- Adapter->BytesRxDirected +
- Adapter->BytesRxMulticast +
- Adapter->BytesRxBroadcast;
- Statistics->ifHCInUcastOctets =
- Adapter->BytesRxDirected;
- Statistics->ifHCInMulticastOctets =
- Adapter->BytesRxMulticast;
- Statistics->ifHCInBroadcastOctets =
- Adapter->BytesRxBroadcast;
- /* Packets in */
- Statistics->ifHCInUcastPkts =
- Adapter->FramesRxDirected;
- Statistics->ifHCInMulticastPkts =
- Adapter->FramesRxMulticast;
- Statistics->ifHCInBroadcastPkts =
- Adapter->FramesRxBroadcast;
- /* Errors in */
- Statistics->ifInErrors =
- Adapter->RxCrcErrors +
- Adapter->RxAlignmentErrors +
- Adapter->RxDmaOverrunErrors +
- Adapter->RxRuntErrors;
- Statistics->ifInDiscards =
- Adapter->RxResourceErrors;
- /* Bytes out */
- Statistics->ifHCOutOctets =
- Adapter->BytesTxDirected +
- Adapter->BytesTxMulticast +
- Adapter->BytesTxBroadcast;
- Statistics->ifHCOutUcastOctets =
- Adapter->BytesTxDirected;
- Statistics->ifHCOutMulticastOctets =
- Adapter->BytesTxMulticast;
- Statistics->ifHCOutBroadcastOctets =
- Adapter->BytesTxBroadcast;
- /* Packets out */
- Statistics->ifHCOutUcastPkts =
- Adapter->FramesTxDirected;
- Statistics->ifHCOutMulticastPkts =
- Adapter->FramesTxMulticast;
- Statistics->ifHCOutBroadcastPkts =
- Adapter->FramesTxBroadcast;
- /* Errors out */
- Statistics->ifOutErrors =
- Adapter->TxAbortExcessCollisions +
- Adapter->TxDmaUnderrun +
- Adapter->TxLostCRS +
- Adapter->TxLateCollisions+
- Adapter->TransmitFailuresOther;
- Statistics->ifOutDiscards = 0ULL;
- ulInfoLen = NDIS_SIZEOF_STATISTICS_INFO_REVISION_1;
- }
- break;
- // TODO: Inplement these query information requests.
- case OID_GEN_RECEIVE_BUFFER_SPACE:
- case OID_GEN_MAXIMUM_SEND_PACKETS:
- case OID_GEN_TRANSMIT_QUEUE_LENGTH:
- case OID_802_3_XMIT_HEARTBEAT_FAILURE:
- case OID_802_3_XMIT_TIMES_CRS_LOST:
- case OID_802_3_XMIT_LATE_COLLISIONS:
- default:
- //
- // The entry point may by used by other requests
- //
- status = NDIS_STATUS_NOT_SUPPORTED;
- break;
- }
- if (status == NDIS_STATUS_SUCCESS)
- {
- ASSERT(ulInfoLen > 0);
- if (ulInfoLen <= OidRequest->DATA.QUERY_INFORMATION.InformationBufferLength)
- {
- if(pInfo)
- {
- // Copy result into InformationBuffer
- NdisMoveMemory(
- OidRequest->DATA.QUERY_INFORMATION.InformationBuffer,
- pInfo,
- ulInfoLen
- );
- }
- OidRequest->DATA.QUERY_INFORMATION.BytesWritten = ulInfoLen;
- }
- else
- {
- // too short
- OidRequest->DATA.QUERY_INFORMATION.BytesNeeded = ulInfoLen;
- status = NDIS_STATUS_BUFFER_TOO_SHORT;
- }
- }
- return status;
- }
- NDIS_STATUS
- AdapterOidRequest(
- __in NDIS_HANDLE MiniportAdapterContext,
- __in PNDIS_OID_REQUEST OidRequest
- )
- /*++
- Routine Description:
- Entry point called by NDIS to get or set the value of a specified OID.
- Arguments:
- MiniportAdapterContext - Our adapter handle
- NdisRequest - The OID request to handle
- Return Value:
- Return code from the NdisRequest below.
- --*/
- {
- PTAP_ADAPTER_CONTEXT adapter = (PTAP_ADAPTER_CONTEXT )MiniportAdapterContext;
- NDIS_STATUS status;
- // Dispatch based on request type.
- switch (OidRequest->RequestType)
- {
- case NdisRequestSetInformation:
- status = tapSetInformation(adapter,OidRequest);
- break;
- case NdisRequestQueryInformation:
- case NdisRequestQueryStatistics:
- status = tapQueryInformation(adapter,OidRequest);
- break;
- case NdisRequestMethod: // TAP doesn't need to respond to this request type.
- default:
- //
- // The entry point may by used by other requests
- //
- status = NDIS_STATUS_NOT_SUPPORTED;
- break;
- }
- return status;
- }
- VOID
- AdapterCancelOidRequest(
- __in NDIS_HANDLE MiniportAdapterContext,
- __in PVOID RequestId
- )
- {
- PTAP_ADAPTER_CONTEXT adapter = (PTAP_ADAPTER_CONTEXT )MiniportAdapterContext;
- UNREFERENCED_PARAMETER(RequestId);
- //
- // This miniport sample does not pend any OID requests, so we don't have
- // to worry about cancelling them.
- //
- }
|