2013-02-11 Sebastian Huber <sebastian.huber@embedded-brains.de>
[official-gcc.git] / libgo / go / net / interface_windows.go
blob4368b3306213b54c814cec6079e7373904eb7577
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 // Network interface identification for Windows
7 package net
9 import (
10 "os"
11 "syscall"
12 "unsafe"
15 func bytePtrToString(p *uint8) string {
16 a := (*[10000]uint8)(unsafe.Pointer(p))
17 i := 0
18 for a[i] != 0 {
19 i++
21 return string(a[:i])
24 func getAdapterList() (*syscall.IpAdapterInfo, error) {
25 b := make([]byte, 1000)
26 l := uint32(len(b))
27 a := (*syscall.IpAdapterInfo)(unsafe.Pointer(&b[0]))
28 err := syscall.GetAdaptersInfo(a, &l)
29 if err == syscall.ERROR_BUFFER_OVERFLOW {
30 b = make([]byte, l)
31 a = (*syscall.IpAdapterInfo)(unsafe.Pointer(&b[0]))
32 err = syscall.GetAdaptersInfo(a, &l)
34 if err != nil {
35 return nil, os.NewSyscallError("GetAdaptersInfo", err)
37 return a, nil
40 func getInterfaceList() ([]syscall.InterfaceInfo, error) {
41 s, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_DGRAM, syscall.IPPROTO_UDP)
42 if err != nil {
43 return nil, os.NewSyscallError("Socket", err)
45 defer syscall.Closesocket(s)
47 ii := [20]syscall.InterfaceInfo{}
48 ret := uint32(0)
49 size := uint32(unsafe.Sizeof(ii))
50 err = syscall.WSAIoctl(s, syscall.SIO_GET_INTERFACE_LIST, nil, 0, (*byte)(unsafe.Pointer(&ii[0])), size, &ret, nil, 0)
51 if err != nil {
52 return nil, os.NewSyscallError("WSAIoctl", err)
54 c := ret / uint32(unsafe.Sizeof(ii[0]))
55 return ii[:c-1], nil
58 // If the ifindex is zero, interfaceTable returns mappings of all
59 // network interfaces. Otherwise it returns a mapping of a specific
60 // interface.
61 func interfaceTable(ifindex int) ([]Interface, error) {
62 ai, err := getAdapterList()
63 if err != nil {
64 return nil, err
67 ii, err := getInterfaceList()
68 if err != nil {
69 return nil, err
72 var ift []Interface
73 for ; ai != nil; ai = ai.Next {
74 index := ai.Index
75 if ifindex == 0 || ifindex == int(index) {
76 var flags Flags
78 row := syscall.MibIfRow{Index: index}
79 e := syscall.GetIfEntry(&row)
80 if e != nil {
81 return nil, os.NewSyscallError("GetIfEntry", e)
84 for _, ii := range ii {
85 ip := (*syscall.RawSockaddrInet4)(unsafe.Pointer(&ii.Address)).Addr
86 ipv4 := IPv4(ip[0], ip[1], ip[2], ip[3])
87 ipl := &ai.IpAddressList
88 for ipl != nil {
89 ips := bytePtrToString(&ipl.IpAddress.String[0])
90 if ipv4.Equal(parseIPv4(ips)) {
91 break
93 ipl = ipl.Next
95 if ipl == nil {
96 continue
98 if ii.Flags&syscall.IFF_UP != 0 {
99 flags |= FlagUp
101 if ii.Flags&syscall.IFF_LOOPBACK != 0 {
102 flags |= FlagLoopback
104 if ii.Flags&syscall.IFF_BROADCAST != 0 {
105 flags |= FlagBroadcast
107 if ii.Flags&syscall.IFF_POINTTOPOINT != 0 {
108 flags |= FlagPointToPoint
110 if ii.Flags&syscall.IFF_MULTICAST != 0 {
111 flags |= FlagMulticast
115 name := bytePtrToString(&ai.AdapterName[0])
117 ifi := Interface{
118 Index: int(index),
119 MTU: int(row.Mtu),
120 Name: name,
121 HardwareAddr: HardwareAddr(row.PhysAddr[:row.PhysAddrLen]),
122 Flags: flags}
123 ift = append(ift, ifi)
126 return ift, nil
129 // If the ifindex is zero, interfaceAddrTable returns addresses
130 // for all network interfaces. Otherwise it returns addresses
131 // for a specific interface.
132 func interfaceAddrTable(ifindex int) ([]Addr, error) {
133 ai, err := getAdapterList()
134 if err != nil {
135 return nil, err
138 var ifat []Addr
139 for ; ai != nil; ai = ai.Next {
140 index := ai.Index
141 if ifindex == 0 || ifindex == int(index) {
142 ipl := &ai.IpAddressList
143 for ; ipl != nil; ipl = ipl.Next {
144 ifa := IPAddr{}
145 ifa.IP = parseIPv4(bytePtrToString(&ipl.IpAddress.String[0]))
146 ifat = append(ifat, ifa.toAddr())
150 return ifat, nil
153 // If the ifindex is zero, interfaceMulticastAddrTable returns
154 // addresses for all network interfaces. Otherwise it returns
155 // addresses for a specific interface.
156 func interfaceMulticastAddrTable(ifindex int) ([]Addr, error) {
157 return nil, nil