?? tapdrvr.c
字號:
#endif (int)l_Adapter->m_Rx, (int)l_Adapter->m_RxErr,#if PACKET_TRUNCATION_CHECK (int)l_Adapter->m_RxTrunc,#endif (int)l_Adapter->m_Extension.m_IrpQueue->size, (int)l_Adapter->m_Extension.m_IrpQueue->max_size, (int)IRP_QUEUE_SIZE, (int)l_Adapter->m_Extension.m_PacketQueue->size, (int)l_Adapter->m_Extension.m_PacketQueue->max_size, (int)PACKET_QUEUE_SIZE ); p_IRP->IoStatus.Information = l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength; break; }#if DBG case TAP_IOCTL_GET_LOG_LINE: { if (GetDebugLine ((LPTSTR)p_IRP->AssociatedIrp.SystemBuffer, l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength)) p_IRP->IoStatus.Status = l_Status = STATUS_SUCCESS; else p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL; p_IRP->IoStatus.Information = l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength; break; }#endif case TAP_IOCTL_CONFIG_TUN: { if (l_IrpSp->Parameters.DeviceIoControl.InputBufferLength >= (sizeof (IPADDR) * 3)) { MACADDR dest; l_Adapter->m_tun = FALSE; GenerateRelatedMAC (dest, l_Adapter->m_MAC, 1); l_Adapter->m_localIP = ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[0]; l_Adapter->m_remoteNetwork = ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[1]; l_Adapter->m_remoteNetmask = ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[2]; // sanity check on network/netmask if ((l_Adapter->m_remoteNetwork & l_Adapter->m_remoteNetmask) != l_Adapter->m_remoteNetwork) { NOTE_ERROR (); p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER; break; } COPY_MAC (l_Adapter->m_TapToUser.src, l_Adapter->m_MAC); COPY_MAC (l_Adapter->m_TapToUser.dest, dest); COPY_MAC (l_Adapter->m_UserToTap.src, dest); COPY_MAC (l_Adapter->m_UserToTap.dest, l_Adapter->m_MAC); l_Adapter->m_TapToUser.proto = l_Adapter->m_UserToTap.proto = htons (ETH_P_IP); l_Adapter->m_tun = TRUE; CheckIfDhcpAndTunMode (l_Adapter); p_IRP->IoStatus.Information = 1; // Simple boolean value } else { NOTE_ERROR (); p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER; } break; } case TAP_IOCTL_CONFIG_POINT_TO_POINT: // Obsoleted by TAP_IOCTL_CONFIG_TUN { if (l_IrpSp->Parameters.DeviceIoControl.InputBufferLength >= (sizeof (IPADDR) * 2)) { MACADDR dest; l_Adapter->m_tun = FALSE; GenerateRelatedMAC (dest, l_Adapter->m_MAC, 1); l_Adapter->m_localIP = ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[0]; l_Adapter->m_remoteNetwork = ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[1]; l_Adapter->m_remoteNetmask = ~0; COPY_MAC (l_Adapter->m_TapToUser.src, l_Adapter->m_MAC); COPY_MAC (l_Adapter->m_TapToUser.dest, dest); COPY_MAC (l_Adapter->m_UserToTap.src, dest); COPY_MAC (l_Adapter->m_UserToTap.dest, l_Adapter->m_MAC); l_Adapter->m_TapToUser.proto = l_Adapter->m_UserToTap.proto = htons (ETH_P_IP); l_Adapter->m_tun = TRUE; CheckIfDhcpAndTunMode (l_Adapter); p_IRP->IoStatus.Information = 1; // Simple boolean value } else { NOTE_ERROR (); p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER; } break; } case TAP_IOCTL_SET_MEDIA_STATUS: { if (l_IrpSp->Parameters.DeviceIoControl.InputBufferLength >= (sizeof (ULONG) * 1)) { ULONG parm = ((PULONG) (p_IRP->AssociatedIrp.SystemBuffer))[0]; SetMediaStatus (l_Adapter, (BOOLEAN) parm); p_IRP->IoStatus.Information = 1; } else { NOTE_ERROR (); p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER; } break; } case TAP_IOCTL_CONFIG_DHCP_MASQ: { if (l_IrpSp->Parameters.DeviceIoControl.InputBufferLength >= (sizeof (IPADDR) * 4)) { l_Adapter->m_dhcp_enabled = FALSE; l_Adapter->m_dhcp_server_arp = FALSE; l_Adapter->m_dhcp_user_supplied_options_buffer_len = 0; // Adapter IP addr / netmask l_Adapter->m_dhcp_addr = ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[0]; l_Adapter->m_dhcp_netmask = ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[1]; // IP addr of DHCP masq server l_Adapter->m_dhcp_server_ip = ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[2]; // Lease time in seconds l_Adapter->m_dhcp_lease_time = ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[3]; GenerateRelatedMAC (l_Adapter->m_dhcp_server_mac, l_Adapter->m_MAC, 2); l_Adapter->m_dhcp_enabled = TRUE; l_Adapter->m_dhcp_server_arp = TRUE; CheckIfDhcpAndTunMode (l_Adapter); p_IRP->IoStatus.Information = 1; // Simple boolean value } else { NOTE_ERROR (); p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER; } break; } case TAP_IOCTL_CONFIG_DHCP_SET_OPT: { if (l_IrpSp->Parameters.DeviceIoControl.InputBufferLength <= DHCP_USER_SUPPLIED_OPTIONS_BUFFER_SIZE && l_Adapter->m_dhcp_enabled) { l_Adapter->m_dhcp_user_supplied_options_buffer_len = 0; NdisMoveMemory (l_Adapter->m_dhcp_user_supplied_options_buffer, p_IRP->AssociatedIrp.SystemBuffer, l_IrpSp->Parameters.DeviceIoControl.InputBufferLength); l_Adapter->m_dhcp_user_supplied_options_buffer_len = l_IrpSp->Parameters.DeviceIoControl.InputBufferLength; p_IRP->IoStatus.Information = 1; // Simple boolean value } else { NOTE_ERROR (); p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER; } break; } default: { NOTE_ERROR (); p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER; break; } } IoCompleteRequest (p_IRP, IO_NO_INCREMENT); break; } //=========================================================== // User mode thread issued a read request on the tap device // If there are packets waiting to be read, then the request // will be satisfied here. If not, then the request will be // queued and satisfied by any packet that is not used to // satisfy requests ahead of it. //=========================================================== case IRP_MJ_READ: { TapPacketPointer l_PacketBuffer; BOOLEAN pending = FALSE; // Save IRP-accessible copy of buffer length p_IRP->IoStatus.Information = l_IrpSp->Parameters.Read.Length; if (p_IRP->MdlAddress == NULL) { DEBUGP (("[%s] MdlAddress is NULL for IRP_MJ_READ\n", NAME (l_Adapter))); NOTE_ERROR (); p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER; p_IRP->IoStatus.Information = 0; IoCompleteRequest (p_IRP, IO_NO_INCREMENT); break; } else if ((p_IRP->AssociatedIrp.SystemBuffer = MmGetSystemAddressForMdlSafe (p_IRP->MdlAddress, NormalPagePriority)) == NULL) { DEBUGP (("[%s] Could not map address in IRP_MJ_READ\n", NAME (l_Adapter))); NOTE_ERROR (); p_IRP->IoStatus.Status = l_Status = STATUS_INSUFFICIENT_RESOURCES; p_IRP->IoStatus.Information = 0; IoCompleteRequest (p_IRP, IO_NO_INCREMENT); break; } else if (!l_Adapter->m_InterfaceIsRunning) { DEBUGP (("[%s] Interface is down in IRP_MJ_READ\n", NAME (l_Adapter))); NOTE_ERROR (); p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL; p_IRP->IoStatus.Information = 0; IoCompleteRequest (p_IRP, IO_NO_INCREMENT); break; } //================================== // Can we provide immediate service? //================================== l_PacketBuffer = NULL; NdisAcquireSpinLock (&l_Adapter->m_Extension.m_QueueLock); if (IS_UP (l_Adapter) && QueueCount (l_Adapter->m_Extension.m_PacketQueue) && QueueCount (l_Adapter->m_Extension.m_IrpQueue) == 0) { l_PacketBuffer = (TapPacketPointer) QueuePop (l_Adapter->m_Extension.m_PacketQueue); } NdisReleaseSpinLock (&l_Adapter->m_Extension.m_QueueLock); if (l_PacketBuffer) { l_Status = CompleteIRP (p_IRP, l_PacketBuffer, IO_NO_INCREMENT); break; } //============================= // Attempt to pend read request //============================= NdisAcquireSpinLock (&l_Adapter->m_Extension.m_QueueLock); if (IS_UP (l_Adapter) && QueuePush (l_Adapter->m_Extension.m_IrpQueue, p_IRP) == (PIRP) p_IRP) { IoSetCancelRoutine (p_IRP, CancelIRPCallback); l_Status = STATUS_PENDING; IoMarkIrpPending (p_IRP); pending = TRUE; } NdisReleaseSpinLock (&l_Adapter->m_Extension.m_QueueLock); if (pending) break; // Can't queue anymore IRP's DEBUGP (("[%s] TAP [%s] read IRP overrun\n", NAME (l_Adapter), l_Adapter->m_Extension.m_TapName)); NOTE_ERROR (); p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL; p_IRP->IoStatus.Information = 0; IoCompleteRequest (p_IRP, IO_NO_INCREMENT); break; } //============================================================== // User mode issued a WriteFile request on the TAP file handle. // The request will always get satisfied here. The call may // fail if there are too many pending packets (queue full). //============================================================== case IRP_MJ_WRITE: { if (p_IRP->MdlAddress == NULL) { DEBUGP (("[%s] MdlAddress is NULL for IRP_MJ_WRITE\n", NAME (l_Adapter))); NOTE_ERROR (); p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER; p_IRP->IoStatus.Information = 0; } else if ((p_IRP->AssociatedIrp.SystemBuffer = MmGetSystemAddressForMdlSafe (p_IRP->MdlAddress, NormalPagePriority)) == NULL) { DEBUGP (("[%s] Could not map address in IRP_MJ_WRITE\n", NAME (l_Adapter))); NOTE_ERROR (); p_IRP->IoStatus.Status = l_Status = STATUS_INSUFFICIENT_RESOURCES; p_IRP->IoStatus.Information = 0; } else if (!l_Adapter->m_InterfaceIsRunning) { DEBUGP (("[%s] Interface is down in IRP_MJ_WRITE\n", NAME (l_Adapter))); NOTE_ERROR (); p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL; p_IRP->IoStatus.Information = 0; } else if (!l_Adapter->m_tun && ((l_IrpSp->Parameters.Write.Length) >= ETHERNET_HEADER_SIZE)) { __try { p_IRP->IoStatus.Information = l_IrpSp->Parameters.Write.Length; DUMP_PACKET ("IRP_MJ_WRITE ETH", (unsigned char *) p_IRP->AssociatedIrp.SystemBuffer, l_IrpSp->Parameters.Write.Length); //===================================================== // If IPv4 packet, check whether or not packet // was truncated. //=====================================================#if PACKET_TRUNCATION_CHECK IPv4PacketSizeVerify ((unsigned char *) p_IRP->AssociatedIrp.SystemBuffer, l_IrpSp->Parameters.Write.Length, FALSE, "RX", &l_Adapter->m_RxTrunc);#endif NdisMEthIndicateReceive (l_Adapter->m_MiniportAdapterHandle, (NDIS_HANDLE) l_Adapter, (unsigned char *) p_IRP->AssociatedIrp.SystemBuffer, ETHERNET_HEADER_SIZE, (unsigned char *) p_IRP->AssociatedIrp.SystemBuffer + ETHERNET_HEADER_SIZE, l_IrpSp->Parameters.Write.Length - ETHERNET_HEADER_SIZE, l_IrpSp->Parameters.Write.Length - ETHERNET_HEADER_SIZE); NdisMEthIndicateReceiveComplete (l_Adapter->m_MiniportAdapterHandle); p_IRP->IoStatus.Status = l_Status = STATUS_SUCCESS; } __except (EXCEPTION_EXECUTE_HANDLER) { DEBUGP (("[%s] NdisMEthIndicateReceive failed in IRP_MJ_WRITE\n", NAME (l_Adapter))); NOTE_ERROR (); p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL; p_IRP->IoStatus.Information = 0; } } else if (l_Adapter->m_tun && ((l_IrpSp->Parameters.Write.Length) >= IP_HEADER_SIZE)) { __try { p_IRP->IoStatus.Information = l_IrpSp->Parameters.Write.Length; DUMP_PACKET2 ("IRP_MJ_WRITE P2P", &l_Adapter->m_UserToTap, (unsigned char *) p_IRP->AssociatedIrp.SystemBuffer, l_IrpSp->Parameters.Write.Length); //===================================================== // If IPv4 packet, check whether or not packet // was truncated. //=====================================================#if PACKET_TRUNCATION_CHECK IPv4PacketSizeVerify ((unsigned char *) p_IRP->AssociatedIrp.SystemBuffer, l_IrpSp->Parameters.Write.Length, TRUE, "RX", &l_Adapter->m_RxTrunc);#endif NdisMEthIndicateReceive (l_Adapter->m_MiniportAdapterHandle, (NDIS_HANDLE) l_Adapter, (unsigned char *) &l_Adapter->m_UserToTap, sizeof (l_Adapter->m_UserToTap), (unsigned char *) p_IRP->AssociatedIrp.SystemBuffer, l_IrpSp->Parameters.Write.Length, l_IrpSp->Parameters.Write.Length); NdisMEthIndicateReceiveComplete (l_Adapter->m_MiniportAdapterHandle); p_IRP->IoStatus.Status = l_Status = STATUS_SUCCESS; } __except (EXCEPTION_EXECUTE_HANDLER) { DEBUGP (("[%s] NdisMEthIndicateReceive failed in IRP_MJ_WRITE (P2P)\n", NAME (l_Adapter))); NOTE_ERROR (); p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL; } } else { DEBUGP (("[%s] Bad buffer size in IRP_MJ_WRITE, len=%d\n", NAME (l_Adapter), l_IrpSp->Parameters.Write.Length)); NOTE_ERROR (); p_IRP->IoStatus.Information = 0; // ETHER
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -