PCAP Go使用原始套接字校验和计算

时间:2015-03-13 22:54:34

标签: sockets tcp go ip raw-ethernet

我正在编写一个帧/数据报/数据包操作程序,它将帧从一个源转发到另一个源。我正在使用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)

                    }

                }

            }

        }
    }

}

0 个答案:

没有答案