-
Notifications
You must be signed in to change notification settings - Fork 2
/
pcaprelay.go
78 lines (68 loc) · 1.99 KB
/
pcaprelay.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
package etherconn
import (
"context"
"fmt"
"time"
"github.com/google/gopacket/pcap"
)
type PcapConn struct {
*pcap.Handle
}
// GetIfNameViaDesc returns interface name via its description,
// this could be used on windows to get the interface name
func GetIfNameViaDesc(desc string) (string, error) {
iflist, err := pcap.FindAllDevs()
if err != nil {
return "", fmt.Errorf("failed to get interface list, %w", err)
}
for _, intf := range iflist {
if intf.Description == desc {
return intf.Name, nil
}
}
return "", fmt.Errorf("%v not found", desc)
}
// NewPcapConn creates a new PcapRelay instances for specified ifname.
// Note: on windows, the ifname is the "\Device\NPF_xxxx"
func NewPcapConn(ifname string) (*PcapConn, error) {
var err error
r := &PcapConn{}
r.Handle, err = pcap.OpenLive(ifname,
DefaultMaxEtherFrameSize,
true, time.Millisecond)
if err != nil {
return nil, err
}
return r, nil
}
func (pconn *PcapConn) getRawStats() any {
stats, _ := pconn.Stats()
return stats
}
func (pconn *PcapConn) CloseMe() {
pconn.WritePacketData([]byte{1, 2, 3, 4, 5, 5, 6, 6, 8})
pconn.Close()
}
func (pconn *PcapConn) setBPFFilter(filter string) error {
return pconn.SetBPFFilter(filter)
}
func (pconn *PcapConn) relayType() RelayType {
return RelayTypePCAP
}
func (pconn *PcapConn) isTimeout(err error) bool {
if e, ok := err.(pcap.NextError); !ok {
return false
} else {
return e == pcap.NextErrorTimeoutExpired
}
}
// NewRawSocketRelayPcap creates a new RawSocketRelay instance using libpcap, bound to the interface ifname,
// optionally with RelayOption functions.
// This function will put the interface in promisc mode, which means it requires root privilage.
func NewRawSocketRelayPcap(parentctx context.Context, ifname string, options ...RelayOption) (*RawSocketRelay, error) {
conn, err := NewPcapConn(ifname)
if err != nil {
return nil, fmt.Errorf("failed to create rawsocketrelay,%w", err)
}
return newRawSocketRelayWithRelayConn(parentctx, ifname, conn, options...)
}