duanhongxian6982 2017-03-08 13:26
浏览 148

试图找到一段代码,负责发送带有RST标志的TCP数据包

I'm trying to realize how works a following code made by kdar:

package main

import (
    "github.com/google/gopacket"
    "github.com/google/gopacket/layers"
    "log"
    "net"
    "os"
    "strconv"
    "time"
)

// get the local ip and port based on our destination ip
func localIPPort(dstip net.IP) (net.IP, int) {
    serverAddr, err := net.ResolveUDPAddr("udp", dstip.String()+":12345")
    if err != nil {
        log.Fatal(err)
    }

    // We don't actually connect to anything, but we can determine
    // based on our destination ip what source ip we should use.
    if con, err := net.DialUDP("udp", nil, serverAddr); err == nil {
        if udpaddr, ok := con.LocalAddr().(*net.UDPAddr); ok {
            return udpaddr.IP, udpaddr.Port
        }
    }
    log.Fatal("could not get local ip: " + err.Error())
    return nil, -1
}

func main() {
    if len(os.Args) != 3 {
        log.Printf("Usage: %s <host/ip> <port>
", os.Args[0])
        os.Exit(-1)
    }
    log.Println("starting")

    dstaddrs, err := net.LookupIP(os.Args[1])
    if err != nil {
        log.Fatal(err)
    }

    // parse the destination host and port from the command line os.Args
    dstip := dstaddrs[0].To4()
    var dstport layers.TCPPort
    if d, err := strconv.ParseInt(os.Args[2], 10, 16); err != nil {
        log.Fatal(err)
    } else {
        dstport = layers.TCPPort(d)
    }

    srcip, sport := localIPPort(dstip)
    srcport := layers.TCPPort(sport)
    log.Printf("using srcip: %v", srcip.String())

    // Our IP header... not used, but necessary for TCP checksumming.
    ip := &layers.IPv4{
        SrcIP:    srcip,
        DstIP:    dstip,
        Protocol: layers.IPProtocolTCP,
    }
    // Our TCP header
    tcp := &layers.TCP{
        SrcPort: srcport,
        DstPort: dstport,
        Seq:     1105024978,
        SYN:     true,
        Window:  14600,
    }
    tcp.SetNetworkLayerForChecksum(ip)

    // Serialize.  Note:  we only serialize the TCP layer, because the
    // socket we get with net.ListenPacket wraps our data in IPv4 packets
    // already.  We do still need the IP layer to compute checksums
    // correctly, though.
    buf := gopacket.NewSerializeBuffer()
    opts := gopacket.SerializeOptions{
        ComputeChecksums: true,
        FixLengths:       true,
    }
    if err := gopacket.SerializeLayers(buf, opts, tcp); err != nil {
        log.Fatal(err)
    }

    conn, err := net.ListenPacket("ip4:tcp", "0.0.0.0")
    if err != nil {
        log.Fatal(err)
    }
    log.Println("writing request")
    if _, err := conn.WriteTo(buf.Bytes(), &net.IPAddr{IP: dstip}); err != nil {
        log.Fatal(err)
    }

    // Set deadline so we don't wait forever.
    if err := conn.SetDeadline(time.Now().Add(10 * time.Second)); err != nil {
        log.Fatal(err)
    }

    for {
        b := make([]byte, 4096)
        log.Println("reading from conn")
        n, addr, err := conn.ReadFrom(b)
        if err != nil {
            log.Println("error reading packet: ", err)
            return
        } else if addr.String() == dstip.String() {
            // Decode a packet
            packet := gopacket.NewPacket(b[:n], layers.LayerTypeTCP, gopacket.Default)
            // Get the TCP layer from this packet
            if tcpLayer := packet.Layer(layers.LayerTypeTCP); tcpLayer != nil {
                tcp, _ := tcpLayer.(*layers.TCP)

                if tcp.DstPort == srcport {
                    if tcp.SYN && tcp.ACK {
                        log.Printf("Port %d is OPEN
", dstport)
                    } else {
                        log.Printf("Port %d is CLOSED
", dstport)
                    }
                    return
                }
            }
        } else {
            log.Printf("Got packet not matching addr")
        }
    }
}

If i understand right, that code sends a raw TCP packet with SYN-flag to a server and waits for response. Using wireshark I found out that after receiving a response (SYN-ACK) from a server, the client sends a packet with RST flag. I can't understand, which piece of code is responsible for sending a TCP packet with RST-flag.

  • 写回答

0条回答 默认 最新

    报告相同问题?

    悬赏问题

    • ¥15 stm32开发clion时遇到的编译问题
    • ¥15 lna设计 源简并电感型共源放大器
    • ¥15 如何用Labview在myRIO上做LCD显示?(语言-开发语言)
    • ¥15 Vue3地图和异步函数使用
    • ¥15 C++ yoloV5改写遇到的问题
    • ¥20 win11修改中文用户名路径
    • ¥15 win2012磁盘空间不足,c盘正常,d盘无法写入
    • ¥15 用土力学知识进行土坡稳定性分析与挡土墙设计
    • ¥70 PlayWright在Java上连接CDP关联本地Chrome启动失败,貌似是Windows端口转发问题
    • ¥15 帮我写一个c++工程