How to use Golang to compose raw TCP packet (using gopacket) and send it via raw socket

前端 未结 1 831
攒了一身酷
攒了一身酷 2021-02-04 16:18

I would like to craft custome TCP packets using gopacket and then send them using raw sockets.

Here is a short and readable example go program that demonstrates what I\'

1条回答
  •  遥遥无期
    2021-02-04 17:16

    You question says "craft custome[sic] TCP packets" but your code makes it clear you also want to craft custom IP layer 3 headers and there is a difference between the two. Also, you don't mention IPv4 vs IPv6, but again your code seems IPv4 specific.

    Given your example code I'll assume you want to be set the full IPv4 header.

    As of Go 1.3.3 and the soon to be released Go 1.4 you can't do what you want using the Core Go packages. To accomplish what you desire you need to do two things:

    1. You need to create a raw socket in Go. Contrary to other incorrect answers on this website you can create a raw socket in Go using one of net.ListenPacket, net.DialIP, or net.ListenIP.

    For example:

    conn, err := net.ListenIP("ip4:tcp", netaddr)
    if err != nil {
        log.Fatalf("ListenIP: %s\n", err)
    }
    

    creates a raw socket.

    1. If you want to set your own IPv4 layer 3 header you will need to set a socket option to enable functionality.

    Your question don't state what OS and architecture you are using. On my laptop running Mac OS X:

    % man ip
    . . .
    Outgoing packets automatically have an IP header prepended to them
    (based on the destination address and the protocol number the socket is created with),
    unless the IP_HDRINCL option has been set.
    

    IP_HDRINCL is also available on Linux. Unfortunately, Core Go does not have a way to set the IP_HDRINCL socket option nor does it have a way to set other IP socket options such as IP_TTL. I have a set of private patches that enable this functionality with Core Go but that won't help you.

    I believe the following package has all the functionality you desire ipv4. Please note it's a large package and I haven't used it myself. I did grep and it supports IP_HDRINCL on multiple platforms. You want to call NewRawConn to create a raw connection and this function creates a raw socket and sets the IP_HDRINCL socket option.

    See also here: raw-sockets-in-go and the code he wrote here latency to get a feel for a much simpler approach that might suit your needs if you just want to set TCP headers. However, please note this code doesn't let you set the IP addresses in the IPv4 IP header which I suspect you want to do.

    0 讨论(0)
提交回复
热议问题