forked from Arisstath/raknet-dissector
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathFileCapture.go
More file actions
107 lines (95 loc) · 2.63 KB
/
FileCapture.go
File metadata and controls
107 lines (95 loc) · 2.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package main
import (
"context"
"net"
"github.com/Gskartwii/roblox-dissector/peer"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"github.com/google/gopacket/pcap"
"github.com/olebedev/emitter"
)
func SrcAndDestFromGoPacket(packet gopacket.Packet) (*net.UDPAddr, *net.UDPAddr) {
var srcIP, dstIP net.IP
if ipv4, ok := packet.Layer(layers.LayerTypeIPv4).(*layers.IPv4); ok {
srcIP = ipv4.SrcIP
dstIP = ipv4.DstIP
} else if ipv6, ok := packet.Layer(layers.LayerTypeIPv6).(*layers.IPv6); ok {
srcIP = ipv6.SrcIP
dstIP = ipv6.DstIP
}
return &net.UDPAddr{
IP: srcIP,
Port: int(packet.Layer(layers.LayerTypeUDP).(*layers.UDP).SrcPort),
Zone: "udp",
}, &net.UDPAddr{
IP: dstIP,
Port: int(packet.Layer(layers.LayerTypeUDP).(*layers.UDP).DstPort),
Zone: "udp",
}
}
func NewLayers(source *net.UDPAddr, dest *net.UDPAddr, fromClient bool) *peer.PacketLayers {
return &peer.PacketLayers{
Root: peer.RootLayer{
Source: source,
Destination: dest,
FromClient: fromClient,
FromServer: !fromClient,
},
}
}
type PacketProvider interface {
Layers() *emitter.Emitter
Errors() *emitter.Emitter
}
type Conversations interface {
ConversationFor(source *net.UDPAddr, dest *net.UDPAddr, payload []byte) *Conversation
SetProgress(int)
}
func CaptureFromSource(ctx context.Context, convs Conversations, packetSource *gopacket.PacketSource) error {
var progress int
packetChan := packetSource.Packets()
for {
select {
case <-ctx.Done():
print("done")
return nil
case packet, ok := <-packetChan:
if !ok {
return nil
}
progress++
if packet.ApplicationLayer() == nil ||
(packet.Layer(layers.LayerTypeIPv4) == nil && packet.Layer(layers.LayerTypeIPv6) == nil) ||
packet.Layer(layers.LayerTypeUDP) == nil {
continue
}
payload := packet.ApplicationLayer().Payload()
if len(payload) == 0 {
continue
}
src, dest := SrcAndDestFromGoPacket(packet)
conv := convs.ConversationFor(src, dest, payload)
if conv == nil {
continue // Not a RakNet packet
}
fromClient := AddressEq(src, conv.Client)
layers := NewLayers(src, dest, fromClient)
var reader PacketProvider
if fromClient {
reader = conv.ClientReader
} else {
reader = conv.ServerReader
}
reader.(peer.PacketReader).ReadPacket(payload, layers)
convs.SetProgress(progress)
}
}
}
func CaptureFromHandle(ctx context.Context, convs Conversations, handle *pcap.Handle) error {
err := handle.SetBPFFilter("udp")
if err != nil {
return err
}
packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
return CaptureFromSource(ctx, convs, packetSource)
}