From cd9d6616c0e47be812dd5ccc12c26ee21c7a3d36 Mon Sep 17 00:00:00 2001 From: Carlos Hernandez Date: Mon, 10 Feb 2025 19:47:21 +0000 Subject: [PATCH] route: fix RTM_GET netmask parsing on Darwin On Darwin, the AF_FAMILY byte of a sockaddr for a netmask or genmask can be ignored if unreasonable. In such cases, it is the family of the DST address that should instead be used. Additionally, fixing faulty test data. 192.168.86.0 is a Class C network address, that should have a subnet mask of 255.255.255.0. What's more is the data can also be flag as incorrect considering structure padding rules alone. Further more, you can validate that `route get` will never actually return a netmask for a host query, even though it should be 255.255.255.255. You can run the following to check: route -n get -host 127.0.0.1 You will note the reply has no mention of netmask. Depends on CL 646556 - https://go.dev/cl/646556 Fixes golang/go#71578. Change-Id: Id95669b649a416a380d26c5cdba0e3d1c4bc1ffb GitHub-Last-Rev: 20064b27979b0244db23b4d1f38c5e40479df166 GitHub-Pull-Request: golang/net#232 Reviewed-on: https://go-review.googlesource.com/c/net/+/647176 LUCI-TryBot-Result: Go LUCI Reviewed-by: Ian Lance Taylor Auto-Submit: Ian Lance Taylor Commit-Queue: Ian Lance Taylor Reviewed-by: Damien Neil --- route/address.go | 16 ++++++--- route/address_darwin_test.go | 4 +-- route/example_darwin_test.go | 70 ++++++++++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+), 6 deletions(-) create mode 100644 route/example_darwin_test.go diff --git a/route/address.go b/route/address.go index 279505b1..492838a7 100644 --- a/route/address.go +++ b/route/address.go @@ -396,13 +396,19 @@ func marshalAddrs(b []byte, as []Addr) (uint, error) { func parseAddrs(attrs uint, fn func(int, []byte) (int, Addr, error), b []byte) ([]Addr, error) { var as [syscall.RTAX_MAX]Addr af := int(syscall.AF_UNSPEC) + isInet := func(fam int) bool { + return fam == syscall.AF_INET || fam == syscall.AF_INET6 + } + isMask := func(addrType uint) bool { + return addrType == syscall.RTAX_NETMASK || addrType == syscall.RTAX_GENMASK + } for i := uint(0); i < syscall.RTAX_MAX && len(b) >= roundup(0); i++ { if attrs&(1<