我正在编写一个帧/数据报/数据包操作程序,它将帧从一个源转发到另一个源。我正在使用Go图层库来操纵帧。
如果我没有设置计算校验和的选项,则SYN数据包将被运行到运行此代码的计算机并转发。但是,我更改了数据包dstIP,srcIP,而校验和保持不变,接收方永远不会发回SYN ACK,我怀疑这是因为校验和现在由于更改而出错。
但是,图层库包含一个名为CalculateChecksum的选项,如果我将其打开为true,则运行此程序的计算机将获取该帧,但不会将其传输到接收器。
这是我第一次使用RAW套接字,所以我正在研究理论,没有经验,有什么想法吗?
package main
import (
"code.google.com/p/gopacket"
"code.google.com/p/gopacket/layers"
"code.google.com/p/gopacket/pcap"
"fmt"
"net"
)
func main() {
if handle, err := pcap.OpenLive("enp3s0", 1600, true, 100); err != nil {
panic(err)
} else {
packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
for packet := range packetSource.Packets() {
if ethLayer := packet.Layer(layers.LayerTypeEthernet); ethLayer != nil {
eth, _ := ethLayer.(*layers.Ethernet)
//eth.DstMAC, _ = net.ParseMAC("14:10:9f:d1:47:e5")
eth.SrcMAC, _ = net.ParseMAC("98:90:96:a3:93:e0")
if ipLayer := packet.Layer(layers.LayerTypeIPv4); ipLayer != nil {
ip, _ := ipLayer.(*layers.IPv4)
if ip.SrcIP.Equal(net.ParseIP("192.168.1.72")) {
fmt.Println("from cal")
//change the dst IP to something 192.168.1.65
eth.DstMAC, _ = net.ParseMAC("00:90:F5:D6:02:FD")
ip.SrcIP = net.IP{192, 168, 1, 70}
ip.DstIP = net.IP{192, 168, 1, 73}
}
if ip.SrcIP.Equal(net.ParseIP("192.168.1.73")) {
fmt.Println("from me")
//change the dst IP to something 192.168.1.65
eth.DstMAC, _ = net.ParseMAC("AC:16:2D:49:69:4B")
ip.SrcIP = net.IP{192, 168, 1, 70}
ip.DstIP = net.IP{192, 168, 1, 72}
}
if tcpLayer := packet.Layer(layers.LayerTypeTCP); tcpLayer != nil {
tcp, _ := tcpLayer.(*layers.TCP)
buf := gopacket.NewSerializeBuffer()
opts := gopacket.SerializeOptions{}
opts.FixLengths = true
/* I WISH TO RE-COMPUTE CHECKSUMS HOWEVER WHEN THIS OPTION IS TRUE
I NEVER TRANSMIT THE FRAME*/
opts.ComputeChecksums = true
gopacket.SerializeLayers(buf, opts,
eth,
ip,
tcp,
gopacket.Payload([]byte(tcp.LayerPayload())))
packetData := buf.Bytes()
handle.WritePacketData(buf)
}
}
}
}
}
}