Skip to content

Commit 69275ee

Browse files
committed
net, syscall: more accurate parsers for routing messages on BSD variants
This changes fixes two issues with regard to handling routing messages as follows: - Misparsing on platforms (such as FreeBSD) supporting multiple architectures in the same kernel (kern.supported_archs="amd64 i386") - Misparsing with unimplemented messages such as route, interface address state notifications To fix those issues, this change implements all the required socket address parsers, adds a processor architecture identifying function to FreeBSD and tests. Fixes #9707. Fixes #8203. Change-Id: I7ed7b4a0b6f10f54b29edc681a2f35603f2d8d45 Reviewed-on: https://go-review.googlesource.com/4330 Reviewed-by: Ian Lance Taylor <[email protected]>
1 parent 668762c commit 69275ee

14 files changed

+740
-250
lines changed

src/net/interface_bsd.go

Lines changed: 37 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -54,24 +54,22 @@ func newLink(m *syscall.InterfaceMessage) (*Interface, error) {
5454
return nil, os.NewSyscallError("route sockaddr", err)
5555
}
5656
ifi := &Interface{Index: int(m.Header.Index), Flags: linkFlags(m.Header.Flags)}
57-
for _, sa := range sas {
58-
switch sa := sa.(type) {
59-
case *syscall.SockaddrDatalink:
60-
// NOTE: SockaddrDatalink.Data is minimum work area,
61-
// can be larger.
62-
m.Data = m.Data[unsafe.Offsetof(sa.Data):]
63-
var name [syscall.IFNAMSIZ]byte
64-
for i := 0; i < int(sa.Nlen); i++ {
65-
name[i] = byte(m.Data[i])
66-
}
67-
ifi.Name = string(name[:sa.Nlen])
68-
ifi.MTU = int(m.Header.Data.Mtu)
69-
addr := make([]byte, sa.Alen)
70-
for i := 0; i < int(sa.Alen); i++ {
71-
addr[i] = byte(m.Data[int(sa.Nlen)+i])
72-
}
73-
ifi.HardwareAddr = addr[:sa.Alen]
57+
sa, _ := sas[syscall.RTAX_IFP].(*syscall.SockaddrDatalink)
58+
if sa != nil {
59+
// NOTE: SockaddrDatalink.Data is minimum work area,
60+
// can be larger.
61+
m.Data = m.Data[unsafe.Offsetof(sa.Data):]
62+
var name [syscall.IFNAMSIZ]byte
63+
for i := 0; i < int(sa.Nlen); i++ {
64+
name[i] = byte(m.Data[i])
7465
}
66+
ifi.Name = string(name[:sa.Nlen])
67+
ifi.MTU = int(m.Header.Data.Mtu)
68+
addr := make([]byte, sa.Alen)
69+
for i := 0; i < int(sa.Alen); i++ {
70+
addr[i] = byte(m.Data[int(sa.Nlen)+i])
71+
}
72+
ifi.HardwareAddr = addr[:sa.Alen]
7573
}
7674
return ifi, nil
7775
}
@@ -144,39 +142,34 @@ func interfaceAddrTable(ifi *Interface) ([]Addr, error) {
144142
return ifat, nil
145143
}
146144

147-
func newAddr(ifi *Interface, m *syscall.InterfaceAddrMessage) (Addr, error) {
145+
func newAddr(ifi *Interface, m *syscall.InterfaceAddrMessage) (*IPNet, error) {
148146
sas, err := syscall.ParseRoutingSockaddr(m)
149147
if err != nil {
150148
return nil, os.NewSyscallError("route sockaddr", err)
151149
}
152150
ifa := &IPNet{}
153-
for i, sa := range sas {
154-
switch sa := sa.(type) {
155-
case *syscall.SockaddrInet4:
156-
switch i {
157-
case 0:
158-
ifa.Mask = IPv4Mask(sa.Addr[0], sa.Addr[1], sa.Addr[2], sa.Addr[3])
159-
case 1:
160-
ifa.IP = IPv4(sa.Addr[0], sa.Addr[1], sa.Addr[2], sa.Addr[3])
161-
}
162-
case *syscall.SockaddrInet6:
163-
switch i {
164-
case 0:
165-
ifa.Mask = make(IPMask, IPv6len)
166-
copy(ifa.Mask, sa.Addr[:])
167-
case 1:
168-
ifa.IP = make(IP, IPv6len)
169-
copy(ifa.IP, sa.Addr[:])
170-
// NOTE: KAME based IPv6 protcol stack usually embeds
171-
// the interface index in the interface-local or link-
172-
// local address as the kernel-internal form.
173-
if ifa.IP.IsLinkLocalUnicast() {
174-
ifa.IP[2], ifa.IP[3] = 0, 0
175-
}
176-
}
177-
default: // Sockaddrs contain syscall.SockaddrDatalink on NetBSD
178-
return nil, nil
151+
switch sa := sas[syscall.RTAX_NETMASK].(type) {
152+
case *syscall.SockaddrInet4:
153+
ifa.Mask = IPv4Mask(sa.Addr[0], sa.Addr[1], sa.Addr[2], sa.Addr[3])
154+
case *syscall.SockaddrInet6:
155+
ifa.Mask = make(IPMask, IPv6len)
156+
copy(ifa.Mask, sa.Addr[:])
157+
}
158+
switch sa := sas[syscall.RTAX_IFA].(type) {
159+
case *syscall.SockaddrInet4:
160+
ifa.IP = IPv4(sa.Addr[0], sa.Addr[1], sa.Addr[2], sa.Addr[3])
161+
case *syscall.SockaddrInet6:
162+
ifa.IP = make(IP, IPv6len)
163+
copy(ifa.IP, sa.Addr[:])
164+
// NOTE: KAME based IPv6 protcol stack usually embeds
165+
// the interface index in the interface-local or
166+
// link-local address as the kernel-internal form.
167+
if ifa.IP.IsLinkLocalUnicast() {
168+
ifa.IP[2], ifa.IP[3] = 0, 0
179169
}
180170
}
171+
if ifa.IP == nil || ifa.Mask == nil {
172+
return nil, nil // Sockaddrs contain syscall.SockaddrDatalink on NetBSD
173+
}
181174
return ifa, nil
182175
}

src/net/interface_darwin.go

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -29,35 +29,34 @@ func interfaceMulticastAddrTable(ifi *Interface) ([]Addr, error) {
2929
if err != nil {
3030
return nil, err
3131
}
32-
ifmat = append(ifmat, ifma...)
32+
if ifma != nil {
33+
ifmat = append(ifmat, ifma)
34+
}
3335
}
3436
}
3537
}
3638
return ifmat, nil
3739
}
3840

39-
func newMulticastAddr(ifi *Interface, m *syscall.InterfaceMulticastAddrMessage) ([]Addr, error) {
41+
func newMulticastAddr(ifi *Interface, m *syscall.InterfaceMulticastAddrMessage) (*IPAddr, error) {
4042
sas, err := syscall.ParseRoutingSockaddr(m)
4143
if err != nil {
4244
return nil, os.NewSyscallError("route sockaddr", err)
4345
}
44-
var ifmat []Addr
45-
for _, sa := range sas {
46-
switch sa := sa.(type) {
47-
case *syscall.SockaddrInet4:
48-
ifma := &IPAddr{IP: IPv4(sa.Addr[0], sa.Addr[1], sa.Addr[2], sa.Addr[3])}
49-
ifmat = append(ifmat, ifma.toAddr())
50-
case *syscall.SockaddrInet6:
51-
ifma := &IPAddr{IP: make(IP, IPv6len)}
52-
copy(ifma.IP, sa.Addr[:])
53-
// NOTE: KAME based IPv6 protocol stack usually embeds
54-
// the interface index in the interface-local or link-
55-
// local address as the kernel-internal form.
56-
if ifma.IP.IsInterfaceLocalMulticast() || ifma.IP.IsLinkLocalMulticast() {
57-
ifma.IP[2], ifma.IP[3] = 0, 0
58-
}
59-
ifmat = append(ifmat, ifma.toAddr())
46+
switch sa := sas[syscall.RTAX_IFA].(type) {
47+
case *syscall.SockaddrInet4:
48+
return &IPAddr{IP: IPv4(sa.Addr[0], sa.Addr[1], sa.Addr[2], sa.Addr[3])}, nil
49+
case *syscall.SockaddrInet6:
50+
ifma := IPAddr{IP: make(IP, IPv6len)}
51+
copy(ifma.IP, sa.Addr[:])
52+
// NOTE: KAME based IPv6 protcol stack usually embeds
53+
// the interface index in the interface-local or
54+
// link-local address as the kernel-internal form.
55+
if ifma.IP.IsInterfaceLocalMulticast() || ifma.IP.IsLinkLocalMulticast() {
56+
ifma.IP[2], ifma.IP[3] = 0, 0
6057
}
58+
return &ifma, nil
59+
default:
60+
return nil, nil
6161
}
62-
return ifmat, nil
6362
}

src/net/interface_freebsd.go

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -29,35 +29,34 @@ func interfaceMulticastAddrTable(ifi *Interface) ([]Addr, error) {
2929
if err != nil {
3030
return nil, err
3131
}
32-
ifmat = append(ifmat, ifma...)
32+
if ifma != nil {
33+
ifmat = append(ifmat, ifma)
34+
}
3335
}
3436
}
3537
}
3638
return ifmat, nil
3739
}
3840

39-
func newMulticastAddr(ifi *Interface, m *syscall.InterfaceMulticastAddrMessage) ([]Addr, error) {
41+
func newMulticastAddr(ifi *Interface, m *syscall.InterfaceMulticastAddrMessage) (*IPAddr, error) {
4042
sas, err := syscall.ParseRoutingSockaddr(m)
4143
if err != nil {
4244
return nil, os.NewSyscallError("route sockaddr", err)
4345
}
44-
var ifmat []Addr
45-
for _, sa := range sas {
46-
switch sa := sa.(type) {
47-
case *syscall.SockaddrInet4:
48-
ifma := &IPAddr{IP: IPv4(sa.Addr[0], sa.Addr[1], sa.Addr[2], sa.Addr[3])}
49-
ifmat = append(ifmat, ifma.toAddr())
50-
case *syscall.SockaddrInet6:
51-
ifma := &IPAddr{IP: make(IP, IPv6len)}
52-
copy(ifma.IP, sa.Addr[:])
53-
// NOTE: KAME based IPv6 protocol stack usually embeds
54-
// the interface index in the interface-local or link-
55-
// local address as the kernel-internal form.
56-
if ifma.IP.IsInterfaceLocalMulticast() || ifma.IP.IsLinkLocalMulticast() {
57-
ifma.IP[2], ifma.IP[3] = 0, 0
58-
}
59-
ifmat = append(ifmat, ifma.toAddr())
46+
switch sa := sas[syscall.RTAX_IFA].(type) {
47+
case *syscall.SockaddrInet4:
48+
return &IPAddr{IP: IPv4(sa.Addr[0], sa.Addr[1], sa.Addr[2], sa.Addr[3])}, nil
49+
case *syscall.SockaddrInet6:
50+
ifma := IPAddr{IP: make(IP, IPv6len)}
51+
copy(ifma.IP, sa.Addr[:])
52+
// NOTE: KAME based IPv6 protcol stack usually embeds
53+
// the interface index in the interface-local or
54+
// link-local address as the kernel-internal form.
55+
if ifma.IP.IsInterfaceLocalMulticast() || ifma.IP.IsLinkLocalMulticast() {
56+
ifma.IP[2], ifma.IP[3] = 0, 0
6057
}
58+
return &ifma, nil
59+
default:
60+
return nil, nil
6161
}
62-
return ifmat, nil
6362
}

0 commit comments

Comments
 (0)