diff --git a/atalk/raw.go b/atalk/raw.go index 01cea20..ab05b44 100644 --- a/atalk/raw.go +++ b/atalk/raw.go @@ -16,26 +16,4 @@ package atalk -import ( - "fmt" - "time" - - "github.com/google/gopacket/pcap" -) - const DDPExtHeaderSize = 13 - -// StartPcap opens an AppleTalk and AARP listening session on a network device. -func StartPcap(device string) (*pcap.Handle, error) { - handle, err := pcap.OpenLive(device, 4096, true, 100*time.Millisecond) - if err != nil { - return nil, fmt.Errorf("opening device %q: %w", device, err) - } - - if err := handle.SetBPFFilter("atalk or aarp"); err != nil { - handle.Close() - return nil, fmt.Errorf("setting BPF filter: %w", err) - } - - return handle, nil -} diff --git a/config.go b/config.go index 1b53bce..d573177 100644 --- a/config.go +++ b/config.go @@ -36,6 +36,7 @@ type config struct { // Required for routing a local EtherTalk network. EtherTalk struct { + EthAddr string `yaml:"ethernet_addr"` Device string `yaml:"device"` ZoneName string `yaml:"zone_name"` NetStart ddp.Network `yaml:"net_start"` diff --git a/main.go b/main.go index 4f5654a..6f8adb5 100644 --- a/main.go +++ b/main.go @@ -20,6 +20,7 @@ import ( "context" "errors" "flag" + "fmt" "io" "log" "math/rand/v2" @@ -30,7 +31,6 @@ import ( "sync" "time" - "gitea.drjosh.dev/josh/jrouter/atalk" "gitea.drjosh.dev/josh/jrouter/aurp" "github.com/google/gopacket/pcap" "github.com/sfiera/multitalk/pkg/ddp" @@ -98,15 +98,29 @@ func main() { ctx, _ := signal.NotifyContext(cctx, os.Interrupt) // Open PCAP session + // First check the interface iface, err := net.InterfaceByName(cfg.EtherTalk.Device) if err != nil { log.Fatalf("Couldn't find interface named %q: %v", cfg.EtherTalk.Device, err) } myHWAddr := ethernet.Addr(iface.HardwareAddr) + if cfg.EtherTalk.EthAddr != "" { + // Override myHWAddr with the configured address + netHWAddr, err := net.ParseMAC(cfg.EtherTalk.EthAddr) + if err != nil { + log.Fatalf("Couldn't parse ethertalk.ethernet_addr value %q: %v", cfg.EtherTalk.EthAddr, err) + } + myHWAddr = ethernet.Addr(netHWAddr) + } - pcapHandle, err := atalk.StartPcap(cfg.EtherTalk.Device) + pcapHandle, err := pcap.OpenLive(cfg.EtherTalk.Device, 4096, true, 100*time.Millisecond) if err != nil { - log.Fatalf("Couldn't open network device for AppleTalk: %v", err) + log.Fatalf("Couldn't open %q for packet capture: %v", cfg.EtherTalk.Device, err) + } + bpfFilter := fmt.Sprintf("(atalk or aarp) and (ether multicast or ether dst %s)", myHWAddr) + if err := pcapHandle.SetBPFFilter(bpfFilter); err != nil { + pcapHandle.Close() + log.Fatalf("Couldn't set BPF filter on packet capture: %v", err) } defer pcapHandle.Close()