1

我正在编写一个帧/数据报/数据包处理程序,它将帧从一个源转发到另一个源。我正在使用 Go 图层库来操作帧。

如果我没有设置计算​​校验和的选项,则 SYN 数据包会到达运行此 go 代码的计算机并被转发。但是,我已经更改了数据包 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)

                    }

                }

            }

        }
    }

}
4

0 回答 0