英文:
How to bind physical nic to send a ip package with golang?
问题
我在Windows客户端上设置了一个虚拟网络卡(TUN)用于VPN流量的获取。在捕获虚拟网络卡流量时,我执行以下资源判断逻辑:当访问特定资源时,流量(IP数据包)将不会通过VPN通道发送。我想要将流量(IP数据包)直接发送到物理网络适配器。
现在的问题是如何将流量直接发送到物理网卡。
--系统:WINDOWS
--语言:GOLANG
我尝试通过解析IP数据包并绑定网络适配器地址进行TCP/UDP模拟发送,但速度太慢。是否有一种直接绑定物理网卡并发送IP数据包的方法?
英文:
I set up a virtual network card(TUN) on the windows client for the vpn to get traffic. When capturing virtual NIC traffic, I perform the following resource judgment logic: When accessing certain resources, the traffic (IP packets) will not be sent through the VPN channel. I want to send the traffic (IP packets) directly through the physical NIC.
The problem now is how do I get the traffic sent directly through the physical network card.
--SYSTEM:WINDOWS
--LANGUAGE:GOLANG
I tried to simulate TCP/UDP by parsing IP packets and binding network adapter addresses for sending, but this was too slow.
Is there a way to directly bind the physical NIC and send IP packets?
答案1
得分: 0
原始套接字自Windows XP以来已被禁用,因此您需要第三方软件来注入IP数据包。
我使用了WinPcap库来实现这一点。Go语言的绑定存在:https://pkg.go.dev/github.com/google/gopacket/pcap
将以太网帧写入数据链路层的函数是Handle.WritePacketData
具体步骤如下:
- 使用
OpenLive
创建与物理网卡的句柄。 - 将IP数据包封装到数据链路层帧中。
- 使用
Handle.WritePacketData
将帧写入句柄。
第1步中的棘手之处在于接口的名称。在Windows中,没有eth0
这样的名称。所需的名称看起来像\Device\NPF_{BBECCD43-3F2B-4594-B17B-5F38E73787E8}
要获取设备的正确名称,可以查询FindAllDevs
函数。需要以管理员
身份运行!
package main
import (
"fmt"
"github.com/google/gopacket/pcap"
)
func main() {
// 获取设备列表 - 以管理员身份运行!
devices, err := pcap.FindAllDevs()
if err != nil {
panic(err)
}
// 打印设备信息
fmt.Println("设备:")
for _, device := range devices {
fmt.Println("-----------------------")
fmt.Println("名称: ", device.Name)
fmt.Println("描述: ", device.Description)
fmt.Println("地址: ", device.Description)
for _, address := range device.Addresses {
fmt.Println(" IP地址: ", address.IP)
fmt.Println(" 子网掩码: ", address.Netmask)
}
}
}
示例输出(这是我的WiFi适配器):
-----------------------
名称: \Device\NPF_{BBECCD43-3F2B-4594-B17B-5F38E73787E8}
描述: Microsoft
地址: Microsoft
IP地址: fe80::de52:6717:446:57a1
子网掩码: <nil>
IP地址: 172.30.1.95
子网掩码: ffffff00
英文:
Raw sockets are disabled since Windows XP, so you need third party software to inject IP packets.
I used WinPcap library for this. The Go binding exists: https://pkg.go.dev/github.com/google/gopacket/pcap
The function that writes Ethernet frames to the datalink is Handle.WritePacketData
The steps are:
- Create a handle to your physical NIC with
OpenLive
- Wrap IP packed into datalink layer frame
- Write the frame to the handle with
Handle.WritePacketData
The tricky part with the step 1 is the name of the interface. In windows there are no such names as eth0
. The required name looks like \Device\NPF_{BBECCD43-3F2B-4594-B17B-5F38E73787E8}
To get the proper names of the devices you can query FindAllDevs
function. As Administrator
!
package main
import (
"fmt"
"github.com/google/gopacket/pcap"
)
func main() {
// Get device list - run as ADMINISTRATOR!
devices, err := pcap.FindAllDevs()
if err != nil {
panic(err)
}
// Print device information
fmt.Println("Devices:")
for _, device := range devices {
fmt.Println("-----------------------")
fmt.Println("Name: ", device.Name)
fmt.Println("Description: ", device.Description)
fmt.Println("Addresses: ", device.Description)
for _, address := range device.Addresses {
fmt.Println(" IP address: ", address.IP)
fmt.Println(" Netmask: ", address.Netmask)
}
}
}
Sample output (this is my WiFi adapter):
-----------------------
Name: \Device\NPF_{BBECCD43-3F2B-4594-B17B-5F38E73787E8}
Description: Microsoft
Addresses: Microsoft
IP address: fe80::de52:6717:446:57a1
Netmask: <nil>
IP address: 172.30.1.95
Netmask: ffffff00
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论