Skip to content

Commit 09b1530

Browse files
committed
replace pcap with raw socket calls
1 parent b6dec95 commit 09b1530

File tree

3 files changed

+55
-18
lines changed

3 files changed

+55
-18
lines changed

ipmanager/basicConfigurer.go

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import (
77

88
"github.com/google/gopacket"
99
"github.com/google/gopacket/layers"
10-
"github.com/google/gopacket/pcap"
1110
)
1211

1312
// BasicConfigurer can be used to enable vip-management on nodes
@@ -55,14 +54,7 @@ const (
5554
)
5655

5756
// arpSendGratuitous is a function that sends gratuitous ARP requests
58-
func (c *BasicConfigurer) arpSendGratuitous() error {
59-
// Open the network interface for sending
60-
handle, err := pcap.OpenLive(c.Iface.Name, 65536, false, pcap.BlockForever)
61-
if err != nil {
62-
return err
63-
}
64-
defer handle.Close()
65-
57+
func (c *BasicConfigurer) createGratuitousARP() ([]byte, error) {
6658
// Create the Ethernet layer
6759
ethLayer := &layers.Ethernet{
6860
SrcMAC: c.Iface.HardwareAddr,
@@ -89,11 +81,10 @@ func (c *BasicConfigurer) arpSendGratuitous() error {
8981
FixLengths: true,
9082
ComputeChecksums: true,
9183
}
92-
err = gopacket.SerializeLayers(buffer, opts, ethLayer, arpLayer)
93-
if err != nil {
94-
return err
84+
85+
if err := gopacket.SerializeLayers(buffer, opts, ethLayer, arpLayer); err != nil {
86+
return nil, err
9587
}
9688

97-
// Send the packet
98-
return handle.WritePacketData(buffer.Bytes())
89+
return buffer.Bytes(), nil
9990
}

ipmanager/basicConfigurer_linux.go

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,51 @@
11
package ipmanager
22

33
import (
4+
"net"
45
"os/exec"
6+
"syscall"
57
)
68

79
const (
810
arpRequestOp = 1
911
arpReplyOp = 2
1012
)
1113

14+
func htons(i uint16) uint16 {
15+
return (i<<8)&0xff00 | i>>8
16+
}
17+
18+
func sendPacketLinux(iface net.Interface, packetData []byte) error {
19+
fd, err := syscall.Socket(syscall.AF_PACKET, syscall.SOCK_RAW, int(htons(syscall.ETH_P_ALL)))
20+
if err != nil {
21+
return err
22+
}
23+
defer syscall.Close(fd)
24+
25+
var sll syscall.SockaddrLinklayer
26+
sll.Protocol = htons(syscall.ETH_P_ARP)
27+
sll.Ifindex = iface.Index
28+
sll.Hatype = syscall.ARPHRD_ETHER
29+
sll.Pkttype = syscall.PACKET_BROADCAST
30+
31+
if err = syscall.Bind(fd, &sll); err != nil {
32+
return err
33+
}
34+
35+
return syscall.Sendto(fd, packetData, 0, &sll)
36+
}
37+
1238
// configureAddress assigns virtual IP address
1339
func (c *BasicConfigurer) configureAddress() bool {
1440
log.Infof("Configuring address %s on %s", c.getCIDR(), c.Iface.Name)
1541
result := c.runAddressConfiguration("add")
1642
if result {
17-
if err := c.arpSendGratuitous(); err != nil {
18-
log.Error("Failed to send gratuitous ARP: ", err)
43+
if buff, err := c.createGratuitousARP(); err != nil {
44+
log.Warn("Failed to compose gratuitous ARP request: ", err)
45+
} else {
46+
if err := sendPacketLinux(c.Iface, buff); err != nil {
47+
log.Warn("Failed to send gratuitous ARP request: ", err)
48+
}
1949
}
2050
}
2151

ipmanager/basicConfigurer_windows.go

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,18 @@ import (
77
"github.com/cybertec-postgresql/vip-manager/iphlpapi"
88
)
99

10+
func sendPacketWindows(iface net.Interface, packetData []byte) error {
11+
// Open a raw socket using Winsock
12+
conn, err := net.Dial("ip4:ethernet", iface.HardwareAddr.String())
13+
if err != nil {
14+
return err
15+
}
16+
defer conn.Close()
17+
// Send the packet
18+
_, err = conn.Write(packetData)
19+
return err
20+
}
21+
1022
// configureAddress assigns virtual IP address
1123
func (c *BasicConfigurer) configureAddress() bool {
1224
log.Infof("Configuring address %s on %s", c.getCIDR(), c.Iface.Name)
@@ -26,8 +38,12 @@ func (c *BasicConfigurer) configureAddress() bool {
2638
return false
2739
}
2840

29-
if err := c.arpSendGratuitous(); err != nil {
30-
log.Error("Failed to send gratuitous ARP: ", err)
41+
if buff, err := c.createGratuitousARP(); err != nil {
42+
log.Warn("Failed to compose gratuitous ARP request: ", err)
43+
} else {
44+
if err := sendPacketWindows(c.Iface, buff); err != nil {
45+
log.Warn("Failed to send gratuitous ARP request: ", err)
46+
}
3147
}
3248
return true
3349
}

0 commit comments

Comments
 (0)