diff options
Diffstat (limited to 'libgo/go/syscall/route_freebsd.go')
-rw-r--r-- | libgo/go/syscall/route_freebsd.go | 70 |
1 files changed, 47 insertions, 23 deletions
diff --git a/libgo/go/syscall/route_freebsd.go b/libgo/go/syscall/route_freebsd.go index 15897b1aca9..0e181038555 100644 --- a/libgo/go/syscall/route_freebsd.go +++ b/libgo/go/syscall/route_freebsd.go @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// Routing sockets and messages for FreeBSD - package syscall import "unsafe" @@ -13,13 +11,31 @@ var freebsdVersion uint32 func init() { freebsdVersion, _ = SysctlUint32("kern.osreldate") + conf, _ := Sysctl("kern.conftxt") + for i, j := 0, 0; j < len(conf); j++ { + if conf[j] != '\n' { + continue + } + s := conf[i:j] + i = j + 1 + if len(s) > len("machine") && s[:len("machine")] == "machine" { + s = s[len("machine"):] + for k := 0; k < len(s); k++ { + if s[k] == ' ' || s[k] == '\t' { + s = s[1:] + } + break + } + freebsdConfArch = s + break + } + } } func (any *anyMessage) toRoutingMessage(b []byte) RoutingMessage { switch any.Type { case RTM_ADD, RTM_DELETE, RTM_CHANGE, RTM_GET, RTM_LOSING, RTM_REDIRECT, RTM_MISS, RTM_LOCK, RTM_RESOLVE: - p := (*RouteMessage)(unsafe.Pointer(any)) - return &RouteMessage{Header: p.Header, Data: b[SizeofRtMsghdr:any.Msglen]} + return any.parseRouteMessage(b) case RTM_IFINFO: return any.parseInterfaceMessage(b) case RTM_IFANNOUNCE: @@ -41,7 +57,7 @@ type InterfaceAnnounceMessage struct { Header IfAnnounceMsghdr } -func (m *InterfaceAnnounceMessage) sockaddr() (sas []Sockaddr) { return nil } +func (m *InterfaceAnnounceMessage) sockaddr() ([]Sockaddr, error) { return nil, nil } // InterfaceMulticastAddrMessage represents a routing message // containing network interface address entries. @@ -50,29 +66,37 @@ type InterfaceMulticastAddrMessage struct { Data []byte } -const rtaIfmaMask = RTA_GATEWAY | RTA_IFP | RTA_IFA - -func (m *InterfaceMulticastAddrMessage) sockaddr() (sas []Sockaddr) { - if m.Header.Addrs&rtaIfmaMask == 0 { - return nil - } +func (m *InterfaceMulticastAddrMessage) sockaddr() ([]Sockaddr, error) { + var sas [RTAX_MAX]Sockaddr b := m.Data[:] - for i := uint(0); i < RTAX_MAX; i++ { - if m.Header.Addrs&rtaIfmaMask&(1<<i) == 0 { + for i := uint(0); i < RTAX_MAX && len(b) >= minRoutingSockaddrLen; i++ { + if m.Header.Addrs&(1<<i) == 0 { continue } rsa := (*RawSockaddr)(unsafe.Pointer(&b[0])) - switch i { - case RTAX_IFA: - sa, e := anyToSockaddr((*RawSockaddrAny)(unsafe.Pointer(rsa))) - if e != nil { - return nil + switch rsa.Family { + case AF_LINK: + sa, err := parseSockaddrLink(b) + if err != nil { + return nil, err + } + sas[i] = sa + b = b[rsaAlignOf(int(rsa.Len)):] + case AF_INET, AF_INET6: + sa, err := parseSockaddrInet(b, rsa.Family) + if err != nil { + return nil, err + } + sas[i] = sa + b = b[rsaAlignOf(int(rsa.Len)):] + default: + sa, l, err := parseLinkLayerAddr(b) + if err != nil { + return nil, err } - sas = append(sas, sa) - case RTAX_GATEWAY, RTAX_IFP: - // nothing to do + sas[i] = sa + b = b[l:] } - b = b[rsaAlignOf(int(rsa.Len)):] } - return sas + return sas[:], nil } |