func parseRoutingSockaddrs(m syscall.RoutingMessage) ([]syscall.Sockaddr, error) { switch m := m.(type) { case *syscall.RouteMessage: sas, err := syscall.ParseRoutingSockaddr(m) if err != nil { return nil, fmt.Errorf("%T: %v, %#v", m, err, m.Data) } if err = sockaddrs(sas).match(addrFlags(m.Header.Addrs)); err != nil { return nil, err } return sas, nil case *syscall.InterfaceMessage: sas, err := syscall.ParseRoutingSockaddr(m) if err != nil { return nil, fmt.Errorf("%T: %v, %#v", m, err, m.Data) } if err = sockaddrs(sas).match(addrFlags(m.Header.Addrs)); err != nil { return nil, err } return sas, nil case *syscall.InterfaceAddrMessage: sas, err := syscall.ParseRoutingSockaddr(m) if err != nil { return nil, fmt.Errorf("%T: %v, %#v", m, err, m.Data) } if err = sockaddrs(sas).match(addrFlags(m.Header.Addrs)); err != nil { return nil, err } return sas, nil default: panic(fmt.Sprintf("unknown routing message type: %T", m)) } }
func newMulticastAddr(m *syscall.InterfaceMulticastAddrMessage) ([]Addr, os.Error) { var ifmat []Addr sas, e := syscall.ParseRoutingSockaddr(m) if e != 0 { return nil, os.NewSyscallError("route sockaddr", e) } for _, s := range sas { switch v := s.(type) { case *syscall.SockaddrInet4: ifma := &IPAddr{IP: IPv4(v.Addr[0], v.Addr[1], v.Addr[2], v.Addr[3])} ifmat = append(ifmat, ifma.toAddr()) case *syscall.SockaddrInet6: ifma := &IPAddr{IP: make(IP, IPv6len)} copy(ifma.IP, v.Addr[:]) // NOTE: KAME based IPv6 protcol stack usually embeds // the interface index in the interface-local or link- // local address as the kernel-internal form. if ifma.IP.IsInterfaceLocalMulticast() || ifma.IP.IsLinkLocalMulticast() { // remove embedded scope zone ID ifma.IP[2], ifma.IP[3] = 0, 0 } ifmat = append(ifmat, ifma.toAddr()) } } return ifmat, nil }
func newMulticastAddr(ifi *Interface, m *syscall.InterfaceMulticastAddrMessage) ([]Addr, error) { sas, err := syscall.ParseRoutingSockaddr(m) if err != nil { return nil, os.NewSyscallError("route sockaddr", err) } var ifmat []Addr for _, sa := range sas { switch sa := sa.(type) { case *syscall.SockaddrInet4: ifma := &IPAddr{IP: IPv4(sa.Addr[0], sa.Addr[1], sa.Addr[2], sa.Addr[3])} ifmat = append(ifmat, ifma.toAddr()) case *syscall.SockaddrInet6: ifma := &IPAddr{IP: make(IP, IPv6len)} copy(ifma.IP, sa.Addr[:]) // NOTE: KAME based IPv6 protcol stack usually embeds // the interface index in the interface-local or link- // local address as the kernel-internal form. if ifma.IP.IsInterfaceLocalMulticast() || ifma.IP.IsLinkLocalMulticast() { ifma.IP[2], ifma.IP[3] = 0, 0 } ifmat = append(ifmat, ifma.toAddr()) } } return ifmat, nil }
func newLink(m *syscall.InterfaceMessage) (*Interface, error) { sas, err := syscall.ParseRoutingSockaddr(m) if err != nil { return nil, os.NewSyscallError("route sockaddr", err) } ifi := &Interface{Index: int(m.Header.Index), Flags: linkFlags(m.Header.Flags)} for _, sa := range sas { switch sa := sa.(type) { case *syscall.SockaddrDatalink: // NOTE: SockaddrDatalink.Data is minimum work area, // can be larger. m.Data = m.Data[unsafe.Offsetof(sa.Data):] var name [syscall.IFNAMSIZ]byte for i := 0; i < int(sa.Nlen); i++ { name[i] = byte(m.Data[i]) } ifi.Name = string(name[:sa.Nlen]) ifi.MTU = int(m.Header.Data.Mtu) addr := make([]byte, sa.Alen) for i := 0; i < int(sa.Alen); i++ { addr[i] = byte(m.Data[int(sa.Nlen)+i]) } ifi.HardwareAddr = addr[:sa.Alen] } } return ifi, nil }
func newAddr(ifi *Interface, m *syscall.InterfaceAddrMessage) (*IPNet, error) { sas, err := syscall.ParseRoutingSockaddr(m) if err != nil { return nil, os.NewSyscallError("parseroutingsockaddr", err) } ifa := &IPNet{} switch sa := sas[syscall.RTAX_NETMASK].(type) { case *syscall.SockaddrInet4: ifa.Mask = IPv4Mask(sa.Addr[0], sa.Addr[1], sa.Addr[2], sa.Addr[3]) case *syscall.SockaddrInet6: ifa.Mask = make(IPMask, IPv6len) copy(ifa.Mask, sa.Addr[:]) } switch sa := sas[syscall.RTAX_IFA].(type) { case *syscall.SockaddrInet4: ifa.IP = IPv4(sa.Addr[0], sa.Addr[1], sa.Addr[2], sa.Addr[3]) case *syscall.SockaddrInet6: ifa.IP = make(IP, IPv6len) copy(ifa.IP, sa.Addr[:]) // NOTE: KAME based IPv6 protcol stack usually embeds // the interface index in the interface-local or // link-local address as the kernel-internal form. if ifa.IP.IsLinkLocalUnicast() { ifa.IP[2], ifa.IP[3] = 0, 0 } } if ifa.IP == nil || ifa.Mask == nil { return nil, nil // Sockaddrs contain syscall.SockaddrDatalink on NetBSD } return ifa, nil }
func TestParseInterfaceMessage(t *testing.T) { for i, tt := range parseInterfaceMessageTests { if _, err := syscall.ParseRoutingSockaddr(tt); err != nil { t.Errorf("#%d: %v", i, err) } } }
func newLink(m *syscall.InterfaceMessage) ([]Interface, os.Error) { var ift []Interface sas, e := syscall.ParseRoutingSockaddr(m) if e != 0 { return nil, os.NewSyscallError("route sockaddr", e) } for _, s := range sas { switch v := s.(type) { case *syscall.SockaddrDatalink: // NOTE: SockaddrDatalink.Data is minimum work area, // can be larger. m.Data = m.Data[unsafe.Offsetof(v.Data):] ifi := Interface{Index: int(m.Header.Index), Flags: linkFlags(m.Header.Flags)} var name [syscall.IFNAMSIZ]byte for i := 0; i < int(v.Nlen); i++ { name[i] = byte(m.Data[i]) } ifi.Name = string(name[:v.Nlen]) ifi.MTU = int(m.Header.Data.Mtu) addr := make([]byte, v.Alen) for i := 0; i < int(v.Alen); i++ { addr[i] = byte(m.Data[int(v.Nlen)+i]) } ifi.HardwareAddr = addr[:v.Alen] ift = append(ift, ifi) } } return ift, nil }
func newMulticastAddr(ifi *Interface, m *syscall.InterfaceMulticastAddrMessage) (*IPAddr, error) { sas, err := syscall.ParseRoutingSockaddr(m) if err != nil { return nil, os.NewSyscallError("route sockaddr", err) } switch sa := sas[syscall.RTAX_IFA].(type) { case *syscall.SockaddrInet4: return &IPAddr{IP: IPv4(sa.Addr[0], sa.Addr[1], sa.Addr[2], sa.Addr[3])}, nil case *syscall.SockaddrInet6: ifma := IPAddr{IP: make(IP, IPv6len)} copy(ifma.IP, sa.Addr[:]) // NOTE: KAME based IPv6 protcol stack usually embeds // the interface index in the interface-local or // link-local address as the kernel-internal form. if ifma.IP.IsInterfaceLocalMulticast() || ifma.IP.IsLinkLocalMulticast() { ifma.IP[2], ifma.IP[3] = 0, 0 } return &ifma, nil default: return nil, nil } }
func newAddr(m *syscall.InterfaceAddrMessage) (Addr, error) { ifa := &IPNet{} sas, err := syscall.ParseRoutingSockaddr(m) if err != nil { return nil, os.NewSyscallError("route sockaddr", err) } for i, s := range sas { switch v := s.(type) { case *syscall.SockaddrInet4: switch i { case 0: ifa.Mask = IPv4Mask(v.Addr[0], v.Addr[1], v.Addr[2], v.Addr[3]) case 1: ifa.IP = IPv4(v.Addr[0], v.Addr[1], v.Addr[2], v.Addr[3]) } case *syscall.SockaddrInet6: switch i { case 0: ifa.Mask = make(IPMask, IPv6len) copy(ifa.Mask, v.Addr[:]) case 1: ifa.IP = make(IP, IPv6len) copy(ifa.IP, v.Addr[:]) // NOTE: KAME based IPv6 protcol stack usually embeds // the interface index in the interface-local or link- // local address as the kernel-internal form. if ifa.IP.IsLinkLocalUnicast() { // remove embedded scope zone ID ifa.IP[2], ifa.IP[3] = 0, 0 } } } } return ifa, nil }
func newAddr(m *syscall.InterfaceAddrMessage) (Addr, error) { sas, err := syscall.ParseRoutingSockaddr(m) if err != nil { return nil, os.NewSyscallError("route sockaddr", err) } ifa := &IPNet{} for i, sa := range sas { switch sa := sa.(type) { case *syscall.SockaddrInet4: switch i { case 0: ifa.Mask = IPv4Mask(sa.Addr[0], sa.Addr[1], sa.Addr[2], sa.Addr[3]) case 1: ifa.IP = IPv4(sa.Addr[0], sa.Addr[1], sa.Addr[2], sa.Addr[3]) } case *syscall.SockaddrInet6: switch i { case 0: ifa.Mask = make(IPMask, IPv6len) copy(ifa.Mask, sa.Addr[:]) case 1: ifa.IP = make(IP, IPv6len) copy(ifa.IP, sa.Addr[:]) // NOTE: KAME based IPv6 protcol stack usually embeds // the interface index in the interface-local or link- // local address as the kernel-internal form. if ifa.IP.IsLinkLocalUnicast() { ifa.Zone = zoneToString(int(ifa.IP[2]<<8 | ifa.IP[3])) ifa.IP[2], ifa.IP[3] = 0, 0 } } default: // Sockaddrs contain syscall.SockaddrDatalink on NetBSD return nil, nil } } return ifa, nil }