Home › Forums › Discussions › General › Sending a packet to Adapter, can’t see anywhere
- This topic has 4 replies, 3 voices, and was last updated 1 month ago by Vadim Smirnov.
-
AuthorPosts
-
September 15, 2024 at 2:07 am #13891
Hi. My question is about how actually the driver sends packets to the adapter, because I seems like have success on the sending but I can not see the actual result anywhere, in my own driver capturing or in the Wireshark everything is just empty… Can you clarify is it actually normal or I do something wrong?
Here is my C# function to send the packet to the adapter. Maybe I made a mistake or something.
public unsafe void SendPacket(Span<byte> bytes, int adapterIndex)
{
var _driver = NdisApi.Open();
var availableNetworkAdapters = _driver.GetNetworkAdapters().ToList();fixed (byte* dataPinnedPtr = bytes)
{
// Allocate memory
var bufPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(INTERMEDIATE_BUFFER)));var intBuff = new INTERMEDIATE_BUFFER
{
m_Length = (uint)bytes.Length,
m_Flags = 0,
};
for (var i = 0; i < MAX_ETHER_FRAME; i++)
{
intBuff.m_IBuffer[i] = dataPinnedPtr[i];
}Marshal.StructureToPtr(intBuff, bufPtr, false);
var ethRequest = new ETH_REQUEST
{
hAdapterHandle = availableNetworkAdapters[adapterIndex].Handle,
EthPacket = new NDISRD_ETH_Packet
{
Buffer = bufPtr
}
};
var result = _driver.SendPacketToAdapter(ref ethRequest);
Debug.WriteLine($”Result: {result}”);// Free allocated memory
Marshal.FreeHGlobal(bufPtr);
}
_driver.Close();
}September 17, 2024 at 11:06 am #13892The ability to capture a sent packet depends on how the drivers are layered. In some cases, it might not be possible. I recommend trying to capture the packet using Wireshark on the destination machine.
If the adapter handle is configured correctly, you should be able to send any packet on a wired network. However, with WiFi, the situation is more complex since the MAC addresses must be accurate.October 27, 2024 at 7:02 pm #13912I am having a similar issue. I have received using a filter, an incoming TCP SYN packet from an IP address I want to block. I can just drop it, but it will cause the remote sender to resend the packet multiple times before giving up. So I tried sending a RST packet response using the SYN packet as a base, swapping the ethernet address, IP addresses and TCP ports setting the TCP flags to RST and then sending the packet back to the adapter. However, the packet was never received at the destination, confirmed by running wireshark.
October 28, 2024 at 3:46 pm #13914FYI, I also update the TCP and IP checksums before sending to the adapter.
October 28, 2024 at 10:05 pm #13916/** @brief Resets a TCP session by sending a forged RST packet. * This function clones the original packet, swaps the necessary fields to create a RST packet,recalculates the checksums, and re-injects both the modified original and the forged RST packets. * @param packet The original packet to be processed.@return true if the session is successfully reset, false otherwise. */ bool reset_tcp_session( intermediate_buffer& packet) { bool result = true; if (const auto ethernet_header = reinterpret_cast<ether_header_ptr>(packet.m_IBuffer); ntohs( ethernet_header->h_proto) == ETH_P_IP) { if (const auto ip_header = reinterpret_cast<iphdr_ptr>(ethernet_header + 1); ip_header->ip_p == IPPROTO_TCP) { const auto tcp_header = reinterpret_cast<tcphdr_ptr>(ip_header + 1); // 1. Clone the original packet and obtain headers intermediate_buffer cloned_packet = packet; const auto clone_ethernet_header = reinterpret_cast<ether_header_ptr>(cloned_packet.m_IBuffer); const auto clone_ip_header = reinterpret_cast<iphdr_ptr>(clone_ethernet_header + 1); const auto clone_tcp_header = reinterpret_cast<tcphdr_ptr>(reinterpret_cast<PUCHAR>(clone_ip_header) + sizeof(DWORD) * clone_ip_header->ip_hl); // 2. Swap Ethernet addresses for the clone std::swap(clone_ethernet_header->h_dest, clone_ethernet_header->h_source); // 3. Swap IP addresses for the clone std::swap(clone_ip_header->ip_dst, clone_ip_header->ip_src); // 4. Swap TCP ports for the clone std::swap(clone_tcp_header->th_dport, clone_tcp_header->th_sport); // 5. Swap SEQ/ACK for the clone std::swap(clone_tcp_header->th_ack, clone_tcp_header->th_seq); // 6. Update ACK from the original packet with m_data size for the clone if (clone_tcp_header->th_flags & TH_SYN) clone_tcp_header->th_ack = htonl(ntohl(clone_tcp_header->th_ack) + 1); else clone_tcp_header->th_ack = htonl(ntohl(clone_tcp_header->th_ack) + ntohs(clone_ip_header->ip_len) - clone_ip_header->ip_hl * 4 - clone_tcp_header->th_off * 4); // 7. Set new packet buffer length cloned_packet.m_Length = sizeof(ether_header) + clone_ip_header->ip_hl * 4 + sizeof(tcphdr); // 7.1. Adjust tcp m_data offset clone_tcp_header->th_off = 0x5; // 8. Set IP total length clone_ip_header->ip_len = htons(static_cast<short>(cloned_packet.m_Length - sizeof(ether_header))); // 9. Set TTL clone_ip_header->ip_ttl = 128; // 10. Set TCP flags clone_tcp_header->th_flags = TH_RST | TH_ACK; // 11. Recalculate checksums CNdisApi::RecalculateTCPChecksum(&cloned_packet); CNdisApi::RecalculateIPChecksum(&cloned_packet); // 7-11 for original packet only done if it is not a connection establishment phase if (tcp_header->th_flags != TH_SYN) { packet.m_Length = sizeof(ether_header) + ip_header->ip_hl * 4 + tcp_header->th_off * 4; ip_header->ip_len = htons(static_cast<short>(packet.m_Length - sizeof(ether_header))); tcp_header->th_flags = TH_RST | TH_ACK; CNdisApi::RecalculateTCPChecksum(&packet); CNdisApi::RecalculateIPChecksum(&packet); } // 12. Re-inject the modified original and forged RST packets PINTERMEDIATE_BUFFER packets[] = {&packet}; PINTERMEDIATE_BUFFER cloned_packets[] = {&cloned_packet}; // Check if the packet is not a SYN packet for sending to the appropriate filter if (tcp_header->th_flags != TH_SYN) { if (packet.m_dwDeviceFlags == PACKET_FLAG_ON_SEND) { result = result && send_packets_to_adapters(packets, 1); } else { result = result && send_packets_to_mstcp(packets, 1); } } // Send cloned packets to the opposite filter based on the flag if (packet.m_dwDeviceFlags == PACKET_FLAG_ON_SEND) { result = result && send_packets_to_mstcp(cloned_packets, 1); } else { result = result && send_packets_to_adapters(cloned_packets, 1); } } } return result; }
-
AuthorPosts
- You must be logged in to reply to this topic.