-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathpcap.go
78 lines (69 loc) · 1.89 KB
/
pcap.go
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
// pkg/pktgen/af_packet.go
package pktgen
import (
"context"
"fmt"
"net"
"github.com/google/gopacket/pcap"
)
// AFPcapSender implements the Sender
type AFPcapSender struct {
iface string
srcIP net.IP
dstIP net.IP
srcPort uint16
dstPort uint16
payloadSize int
srcMAC, dstMAC net.HardwareAddr
}
// NewAFPcapSender creates a new NewAFPcapSender with specified parameters
func NewAFPcapSender(iface string, srcIP, dstIP net.IP, srcPort, dstPort, payloadSize int, srcMAC, dstMAC net.HardwareAddr) *AFPcapSender {
return &AFPcapSender{
srcMAC: srcMAC,
dstMAC: dstMAC,
iface: iface,
srcIP: srcIP,
dstIP: dstIP,
srcPort: uint16(srcPort),
dstPort: uint16(dstPort),
payloadSize: payloadSize,
}
}
// Send sends packets using PCAP handle
func (s *AFPcapSender) Send(ctx context.Context) error {
// open the device for sending
// we don't need to block, as we're not reading packets
// snaplen is set to 1500, but it doesn't matter as we're not reading packets
handle, err := pcap.OpenLive(s.iface, 1500, false, pcap.BlockForever)
if err != nil {
return fmt.Errorf("could not open device: %w", err)
}
defer handle.Close()
// Construct the packet once outside the loop
// create a packet configuration
config, err := NewPacketConfig(
WithEthernetLayer(s.srcMAC, s.dstMAC),
WithIpLayer(s.srcIP, s.dstIP),
WithUdpLayer(int(s.srcPort), int(s.dstPort)),
WithPayloadSize(s.payloadSize),
)
if err != nil {
return fmt.Errorf("error configuring packet: %v", err)
}
// build the packet
packet, err := BuildPacket(config)
if err != nil {
return fmt.Errorf("failed to build packet: %w", err)
}
for {
select {
case <-ctx.Done():
return nil
default:
// Send the packet
if err := handle.WritePacketData(packet); err != nil {
return fmt.Errorf("failed to send packet: %w", err)
}
}
}
}