You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Go实现类Bash的tcpdump流式传输至Wireshark?

问题描述

需要用Go实现一段与以下Bash命令功能相同的代码:

ssh -p 8022 root@${h} -i \~/.ssh/eve -C 'tcpdump -U -i '${i}' -w -' | /Applications/Wireshark.app/Contents/MacOS/Wireshark -i - -k &

该命令通过SSH在远程主机执行tcpdump(-U参数确保完整数据包输出到stdout),再通过管道将数据流传输到本地Wireshark进行实时分析,运行正常。

自行编写的Go代码如下:

func main() {

    Command := "ssh -i $HOME/.ssh/id_rsa.sbm n@127.0.0.6 -p 21057 -C \"sudo tcpdump -U -i any host 10.1.1.1 -w -\""
    cmd := exec.Command("bash", "-c", Command)
    stdout, _ := cmd.StdoutPipe()

    reader := bufio.NewReader(stdout)
    go func(reader io.Reader) {
        scanner := bufio.NewScanner(reader)
        for scanner.Scan() {
            os.Stdout.Write(scanner.Bytes())
        }
    }(reader)

    if err := cmd.Start(); nil != err {
        log.Fatalf("Error starting program: %s, %s", cmd.Path, err.Error())
    }
    cmd.Wait()
}

编译为stdinoutExample后执行:

./stdinoutExample | /Applications/Wireshark.app/Contents/MacOS/Wireshark -i - -k 2>/dev/null &

Wireshark能接收到数据,但无法解析,显示乱码并提示数据包字段错误。请问如何用Go实现与Bash一致的正确数据传输?

解决方案

问题根源

tcpdump输出的是二进制pcap格式数据流,而非文本行。原代码中使用bufio.Scanner按行读取数据,会将二进制流中的换行符作为分隔符截断数据,破坏pcap的结构化格式,导致Wireshark无法解析。Bash管道是字节级的原样传输,不会对数据流做任何分割处理,这是两者的核心差异。

修复方案

直接通过io.Copy将远程命令的stdout字节流原样复制到本地的os.Stdout,完全模拟Bash管道的行为。修改后的代码如下:

package main

import (
    "io"
    "log"
    "os"
    "os/exec"
)

func main() {
    command := "ssh -i $HOME/.ssh/id_rsa.sbm n@127.0.0.6 -p 21057 -C \"sudo tcpdump -U -i any host 10.1.1.1 -w -\""
    cmd := exec.Command("bash", "-c", command)
    
    stdout, err := cmd.StdoutPipe()
    if err != nil {
        log.Fatalf("获取stdout管道失败: %v", err)
    }
    
    // 字节级原样复制数据流,与Bash管道行为一致
    go func() {
        _, copyErr := io.Copy(os.Stdout, stdout)
        if copyErr != nil && copyErr != io.EOF {
            log.Printf("数据复制出错: %v", copyErr)
        }
    }()
    
    if err := cmd.Start(); err != nil {
        log.Fatalf("启动命令失败: %v", err)
    }
    
    if err := cmd.Wait(); err != nil {
        log.Printf("命令执行退出异常: %v", err)
    }
}

说明

  1. io.Copy会逐字节复制输入流到输出流,完全保留原始二进制数据的结构,不会像bufio.Scanner那样分割数据。
  2. 补充了原代码中忽略的错误检查,避免潜在的隐性问题。
  3. 编译后执行原有的管道命令,Wireshark即可正常解析pcap数据流。

内容的提问来源于stack exchange,提问作者n1k3

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 00:25:19