0

I want to do some experiments with TCP packets. Therefore I am using the gopacket (v1.1.19) to craft packets and send them onto an interface. I have this code for creating a SYN packet and putting it on loopback and sending to 127.0.0.1:8888 where I have a ncat server listening (ncat -v -l 127.0.0.1 8888).

I can see my packet on wireshark as expected but there is no SYN/ACK packet send by the server. Calling localhost:8888 from the browser works perfectly fine. And I have build my packet to resemble the one send by the browser (checksum, timestamp, and port are of cause different).

Has someone an Idea what my problem is or what I could be looking into?

package main

import (
    "encoding/binary"
    "github.com/google/gopacket"
    "github.com/google/gopacket/layers"
    "github.com/google/gopacket/pcap"
    "log"
    "math/rand"
    "net"
    "time"
)

var (
    device      string = "lo"
    snapshotLen int32  = 1024
    promiscuous bool   = false
    err          error
    timeout      time.Duration = 30 * time.Second
    handle       *pcap.Handle
    buffer       gopacket.SerializeBuffer
    options      gopacket.SerializeOptions= gopacket.SerializeOptions{FixLengths: true, ComputeChecksums: true}
    ethernetLayer layers.Ethernet = layers.Ethernet{
        SrcMAC: net.HardwareAddr{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
        DstMAC: net.HardwareAddr{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
        EthernetType: layers.EthernetTypeIPv4,
    }
    ipLayer layers.IPv4 = layers.IPv4{
        Version: 4,
        SrcIP: net.IP{127, 0, 0, 1},
        DstIP: net.IP{127,0,0,1},
        Protocol: layers.IPProtocolTCP,
        TTL: 64,
        FragOffset: 0,
        Flags: layers.IPv4DontFragment,
    }
)

func syn() []byte {
    rand.Seed(time.Now().UnixMilli())
    buffer = gopacket.NewSerializeBuffer()

    option1 := layers.TCPOption{layers.TCPOptionKindWindowScale, 3,[]byte{7} }
    bs := make([]byte, 2)
    binary.BigEndian.PutUint16(bs,56495)
    option2 := layers.TCPOption{layers.TCPOptionKindMSS, 0, bs }
    bsTsval := make([]byte,4)
    bsTsecr := make([]byte,4)
    binary.BigEndian.PutUint32(bsTsval,uint32(time.Now().UnixMilli()))
    bsTime := append(bsTsval, bsTsecr...)
    option3 := layers.TCPOption{layers.TCPOptionKindTimestamps,0, bsTime}

    tcpLayerSYN := &layers.TCP{
        SrcPort: layers.TCPPort(rand.Intn(0xffff-1)+1 ),
        DstPort: layers.TCPPort(8888),
        SYN: true,
        Seq: rand.Uint32(),
        Window: 65495,
        Options: []layers.TCPOption{option1, option2, option3},
    }
    tcpLayerSYN.SetNetworkLayerForChecksum(&ipLayer)
    // And create the packet with the layers
    buffer = gopacket.NewSerializeBuffer()
    gopacket.SerializeLayers(buffer, options,
        &ethernetLayer,
        &ipLayer,
        tcpLayerSYN,
    )
    outgoingPacket := buffer.Bytes()
    return outgoingPacket
}


func main() {

    // Open device
    handle, err = pcap.OpenLive(device, snapshotLen, promiscuous, timeout)
    if err != nil {log.Fatal(err) }
    defer handle.Close()

    err = handle.WritePacketData(syn())


}
  • The immediate problem I could see is that the loopback device is not an Ethernet device. Anyway, I'm not sure this question is really on topic on this site [about managing information technology systems in a business environment](https://serverfault.com/help/on-topic). Also no need to involve netcat in the title of the problem. It's a wrong packet problem, not a netcat problem. – A.B Nov 02 '21 at 19:47
  • If I do the browser request the packet is also visible on loopback in wireshark. Why should it be a problem that the loopback is not a Ethernet device? Which platform do you think would be better suited for my question ? – jonathan-dev Nov 02 '21 at 20:09

0 Answers0