Skip to content

Commit 61899df

Browse files
committed
Update Go module dependencies, add support for packet sending on macOS and Windows, and enhance CI workflow for cross-platform builds
1 parent aff0a14 commit 61899df

File tree

6 files changed

+150
-17
lines changed

6 files changed

+150
-17
lines changed

.github/workflows/release.yml

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,25 +10,42 @@ permissions:
1010

1111
jobs:
1212
build-and-release:
13-
runs-on: ubuntu-latest
1413
strategy:
1514
fail-fast: false
1615
matrix:
1716
include:
1817
# Linux
19-
- goos: linux
18+
- runner: ubuntu-latest
19+
goos: linux
2020
goarch: amd64
21-
- goos: linux
21+
cgo_enabled: "0"
22+
- runner: ubuntu-latest
23+
goos: linux
2224
goarch: arm64
23-
- goos: linux
25+
cgo_enabled: "0"
26+
- runner: ubuntu-latest
27+
goos: linux
2428
goarch: arm
2529
goarm: "7"
30+
cgo_enabled: "0"
2631

27-
# macOS
28-
# - goos: darwin
29-
# goarch: amd64
30-
# - goos: darwin
31-
# goarch: arm64
32+
# Windows (pcap sender path requires cgo)
33+
- runner: windows-latest
34+
goos: windows
35+
goarch: amd64
36+
cgo_enabled: "1"
37+
38+
# macOS (pcap sender path requires cgo)
39+
- runner: macos-latest
40+
goos: darwin
41+
goarch: amd64
42+
cgo_enabled: "1"
43+
- runner: macos-latest
44+
goos: darwin
45+
goarch: arm64
46+
cgo_enabled: "1"
47+
48+
runs-on: ${{ matrix.runner }}
3249

3350
steps:
3451
- name: Checkout
@@ -58,7 +75,7 @@ jobs:
5875
GOOS: ${{ matrix.goos }}
5976
GOARCH: ${{ matrix.goarch }}
6077
GOARM: ${{ matrix.goarm }}
61-
CGO_ENABLED: "0"
78+
CGO_ENABLED: ${{ matrix.cgo_enabled }}
6279
run: |
6380
set -euo pipefail
6481
mkdir -p dist
@@ -69,10 +86,10 @@ jobs:
6986
7087
# ldflags version injection
7188
LDFLAGS="-s -w \
72-
-X github.com/yanjiulab/packetforge/internal/version.Version=${VERSION} \
73-
-X github.com/yanjiulab/packetforge/internal/version.Commit=${COMMIT} \
74-
-X github.com/yanjiulab/packetforge/internal/version.Date=${DATE} \
75-
-X github.com/yanjiulab/packetforge/internal/version.BuiltBy=github-actions"
89+
-X main.Version=${VERSION} \
90+
-X main.Commit=${COMMIT} \
91+
-X main.Date=${DATE} \
92+
-X main.BuiltBy=github-actions"
7693
7794
EXT=""
7895
if [[ "${GOOS}" == "windows" ]]; then

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ go 1.23.0
55
toolchain go1.23.5
66

77
require (
8+
github.com/google/gopacket v1.1.19
89
github.com/spf13/cobra v1.10.2
910
github.com/spf13/viper v1.21.0
1011
)

go.sum

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9L
99
github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
1010
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
1111
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
12+
github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8=
13+
github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo=
1214
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
1315
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
1416
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
@@ -43,10 +45,23 @@ github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8
4345
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
4446
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
4547
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
48+
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
49+
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
50+
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
51+
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
52+
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
53+
golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI=
54+
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
55+
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
56+
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
57+
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
4658
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
4759
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
60+
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
4861
golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
4962
golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
63+
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
64+
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
5065
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
5166
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
5267
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

pkg/packet/send_darwin.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
//go:build darwin
2+
3+
package packet
4+
5+
import (
6+
"fmt"
7+
"time"
8+
9+
"github.com/google/gopacket/pcap"
10+
)
11+
12+
// Sender sends raw ethernet frames via libpcap on macOS.
13+
// Root privileges are typically required.
14+
type Sender struct {
15+
ifaceName string
16+
handle *pcap.Handle
17+
}
18+
19+
// NewSender creates a packet sender for the specified interface on macOS.
20+
func NewSender(ifaceName string) (*Sender, error) {
21+
// snaplen 65535, non-promiscuous, small timeout for write path.
22+
handle, err := pcap.OpenLive(ifaceName, 65535, false, 100*time.Millisecond)
23+
if err != nil {
24+
return nil, fmt.Errorf("open pcap on interface %s: %w", ifaceName, err)
25+
}
26+
return &Sender{
27+
ifaceName: ifaceName,
28+
handle: handle,
29+
}, nil
30+
}
31+
32+
// Send sends full ethernet frame bytes.
33+
func (s *Sender) Send(data []byte) error {
34+
if s.handle == nil {
35+
return fmt.Errorf("pcap handle is closed")
36+
}
37+
if err := s.handle.WritePacketData(data); err != nil {
38+
return fmt.Errorf("send packet on %s: %w", s.ifaceName, err)
39+
}
40+
return nil
41+
}
42+
43+
// Close closes sender resources.
44+
func (s *Sender) Close() error {
45+
if s.handle != nil {
46+
s.handle.Close()
47+
s.handle = nil
48+
}
49+
return nil
50+
}

pkg/packet/send_stub.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//go:build !linux
1+
//go:build !linux && !darwin && !windows
22

33
package packet
44

@@ -8,11 +8,11 @@ import "fmt"
88
type Sender struct{}
99

1010
func NewSender(ifaceName string) (*Sender, error) {
11-
return nil, fmt.Errorf("raw socket sending is only supported on Linux, please use -dry-run to only build packets")
11+
return nil, fmt.Errorf("packet sending is only supported on Linux, macOS and Windows, please use -dry-run to only build packets")
1212
}
1313

1414
func (s *Sender) Send(data []byte) error {
15-
return fmt.Errorf("only supports sending on Linux")
15+
return fmt.Errorf("only supports sending on Linux, macOS and Windows")
1616
}
1717

1818
func (s *Sender) Close() error { return nil }

pkg/packet/send_windows.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
//go:build windows
2+
3+
package packet
4+
5+
import (
6+
"fmt"
7+
"time"
8+
9+
"github.com/google/gopacket/pcap"
10+
)
11+
12+
// Sender sends raw ethernet frames via libpcap-compatible backend on Windows.
13+
// Requires Npcap/WinPcap installed and sufficient privileges.
14+
type Sender struct {
15+
ifaceName string
16+
handle *pcap.Handle
17+
}
18+
19+
// NewSender creates a packet sender for the specified interface on Windows.
20+
func NewSender(ifaceName string) (*Sender, error) {
21+
// snaplen 65535, non-promiscuous mode, small timeout for write path.
22+
handle, err := pcap.OpenLive(ifaceName, 65535, false, 100*time.Millisecond)
23+
if err != nil {
24+
return nil, fmt.Errorf("open pcap on interface %s: %w", ifaceName, err)
25+
}
26+
return &Sender{
27+
ifaceName: ifaceName,
28+
handle: handle,
29+
}, nil
30+
}
31+
32+
// Send sends full ethernet frame bytes.
33+
func (s *Sender) Send(data []byte) error {
34+
if s.handle == nil {
35+
return fmt.Errorf("pcap handle is closed")
36+
}
37+
if err := s.handle.WritePacketData(data); err != nil {
38+
return fmt.Errorf("send packet on %s: %w", s.ifaceName, err)
39+
}
40+
return nil
41+
}
42+
43+
// Close closes sender resources.
44+
func (s *Sender) Close() error {
45+
if s.handle != nil {
46+
s.handle.Close()
47+
s.handle = nil
48+
}
49+
return nil
50+
}

0 commit comments

Comments
 (0)