bedrocktool/subcommands/capture.go

94 lines
2.1 KiB
Go
Raw Normal View History

2022-09-04 14:53:21 +00:00
package subcommands
2022-04-03 20:12:21 +00:00
import (
"bytes"
"context"
"encoding/binary"
2022-04-03 20:12:21 +00:00
"flag"
"io"
2022-04-03 20:12:21 +00:00
"net"
"os"
2022-10-14 22:42:43 +00:00
"sync"
2022-04-03 20:12:21 +00:00
"time"
"github.com/bedrock-tool/bedrocktool/locale"
2022-09-04 14:53:21 +00:00
"github.com/bedrock-tool/bedrocktool/utils"
2022-09-04 14:26:32 +00:00
"github.com/google/subcommands"
2022-04-03 20:12:21 +00:00
"github.com/sandertv/gophertunnel/minecraft/protocol/packet"
2022-09-03 17:32:30 +00:00
"github.com/sirupsen/logrus"
2022-04-03 20:12:21 +00:00
)
func init() {
2022-09-04 14:26:32 +00:00
utils.RegisterCommand(&CaptureCMD{})
2022-04-03 20:12:21 +00:00
}
2023-01-29 21:20:13 +00:00
var dumpLock sync.Mutex
2022-10-14 22:42:43 +00:00
2023-01-29 21:20:13 +00:00
func dumpPacket(f io.WriteCloser, toServer bool, payload []byte) {
dumpLock.Lock()
defer dumpLock.Unlock()
2022-10-14 22:42:43 +00:00
f.Write([]byte{0xAA, 0xAA, 0xAA, 0xAA})
2023-01-29 21:20:13 +00:00
packetSize := uint32(len(payload))
binary.Write(f, binary.LittleEndian, packetSize)
binary.Write(f, binary.LittleEndian, toServer)
2023-01-29 21:20:13 +00:00
n, err := f.Write(payload)
2022-10-14 22:42:43 +00:00
if err != nil {
logrus.Error(err)
}
2023-01-29 21:20:13 +00:00
if n < int(packetSize) {
f.Write(make([]byte, int(packetSize)-n))
}
2022-10-14 22:42:43 +00:00
f.Write([]byte{0xBB, 0xBB, 0xBB, 0xBB})
2022-04-03 20:12:21 +00:00
}
type CaptureCMD struct {
2023-01-29 21:20:13 +00:00
serverAddress string
}
func (*CaptureCMD) Name() string { return "capture" }
func (*CaptureCMD) Synopsis() string { return locale.Loc("capture_synopsis", nil) }
2023-01-29 21:20:13 +00:00
func (c *CaptureCMD) SetFlags(f *flag.FlagSet) {
f.StringVar(&c.serverAddress, "address", "", "remote server address")
}
2022-09-03 17:32:30 +00:00
func (c *CaptureCMD) Usage() string {
return c.Name() + ": " + c.Synopsis() + "\n" + locale.Loc("server_address_help", nil)
}
2022-04-03 20:12:21 +00:00
func (c *CaptureCMD) Execute(ctx context.Context, f *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus {
2023-01-29 21:20:13 +00:00
address, hostname, err := utils.ServerInput(ctx, c.serverAddress)
2022-04-03 20:12:21 +00:00
if err != nil {
2022-09-07 12:07:33 +00:00
logrus.Fatal(err)
return 1
2022-04-03 20:12:21 +00:00
}
os.Mkdir("captures", 0o775)
fio, err := os.Create("captures/" + hostname + "-" + time.Now().Format("2006-01-02_15-04-05") + ".pcap2")
2022-04-03 20:12:21 +00:00
if err != nil {
2022-09-07 12:07:33 +00:00
logrus.Fatal(err)
return 1
2022-04-03 20:12:21 +00:00
}
defer fio.Close()
2022-04-03 20:12:21 +00:00
proxy := utils.NewProxy()
2022-09-04 14:26:32 +00:00
proxy.PacketFunc = func(header packet.Header, payload []byte, src, dst net.Addr) {
2023-01-29 22:07:42 +00:00
IsfromClient := src.String() == proxy.Client.LocalAddr().String()
buf := bytes.NewBuffer(nil)
header.Write(buf)
buf.Write(payload)
2023-01-29 21:20:13 +00:00
dumpPacket(fio, IsfromClient, buf.Bytes())
2022-09-04 13:24:55 +00:00
}
2022-08-13 14:30:46 +00:00
2022-09-04 13:24:55 +00:00
err = proxy.Run(ctx, address)
2022-10-14 22:42:43 +00:00
time.Sleep(2 * time.Second)
2022-09-03 17:32:30 +00:00
if err != nil {
2022-09-07 12:07:33 +00:00
logrus.Fatal(err)
2022-09-03 17:32:30 +00:00
return 1
2022-04-03 20:12:21 +00:00
}
2022-09-03 17:32:30 +00:00
return 0
2022-04-03 20:12:21 +00:00
}