Update ChangeLog and version files for release
[official-gcc.git] / libgo / go / net / interface_freebsd.go
blobc42d90b7403e8b858673ff01b3971b72d975dc81
1 // Copyright 2011 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 package net
7 import (
8 "os"
9 "syscall"
12 // interfaceMulticastAddrTable returns addresses for a specific
13 // interface.
14 func interfaceMulticastAddrTable(ifi *Interface) ([]Addr, error) {
15 tab, err := syscall.RouteRIB(syscall.NET_RT_IFMALIST, ifi.Index)
16 if err != nil {
17 return nil, os.NewSyscallError("routerib", err)
19 msgs, err := syscall.ParseRoutingMessage(tab)
20 if err != nil {
21 return nil, os.NewSyscallError("parseroutingmessage", err)
23 var ifmat []Addr
24 for _, m := range msgs {
25 switch m := m.(type) {
26 case *syscall.InterfaceMulticastAddrMessage:
27 if ifi.Index == int(m.Header.Index) {
28 ifma, err := newMulticastAddr(ifi, m)
29 if err != nil {
30 return nil, err
32 if ifma != nil {
33 ifmat = append(ifmat, ifma)
38 return ifmat, nil
41 func newMulticastAddr(ifi *Interface, m *syscall.InterfaceMulticastAddrMessage) (*IPAddr, error) {
42 sas, err := syscall.ParseRoutingSockaddr(m)
43 if err != nil {
44 return nil, os.NewSyscallError("parseroutingsockaddr", err)
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
58 return &ifma, nil
59 default:
60 return nil, nil