~john-koepi/ubuntu/trusty/golang/default

« back to all changes in this revision

Viewing changes to src/pkg/net/interface_windows.go

  • Committer: Bazaar Package Importer
  • Author(s): Ondřej Surý
  • Date: 2011-08-03 17:04:59 UTC
  • mfrom: (14.1.2 sid)
  • Revision ID: james.westby@ubuntu.com-20110803170459-wzd99m3567y80ila
Tags: 1:59-1
* Imported Upstream version 59
* Refresh patches to a new release
* Fix FTBFS on ARM (Closes: #634270)
* Update version.bash to work with Debian packaging and not hg
  repository

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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.
 
4
 
 
5
// Network interface identification for Windows
 
6
 
 
7
package net
 
8
 
 
9
import (
 
10
        "os"
 
11
        "syscall"
 
12
        "unsafe"
 
13
)
 
14
 
 
15
func bytePtrToString(p *uint8) string {
 
16
        a := (*[10000]uint8)(unsafe.Pointer(p))
 
17
        i := 0
 
18
        for a[i] != 0 {
 
19
                i++
 
20
        }
 
21
        return string(a[:i])
 
22
}
 
23
 
 
24
func getAdapterList() (*syscall.IpAdapterInfo, os.Error) {
 
25
        b := make([]byte, 1000)
 
26
        l := uint32(len(b))
 
27
        a := (*syscall.IpAdapterInfo)(unsafe.Pointer(&b[0]))
 
28
        e := syscall.GetAdaptersInfo(a, &l)
 
29
        if e == syscall.ERROR_BUFFER_OVERFLOW {
 
30
                b = make([]byte, l)
 
31
                a = (*syscall.IpAdapterInfo)(unsafe.Pointer(&b[0]))
 
32
                e = syscall.GetAdaptersInfo(a, &l)
 
33
        }
 
34
        if e != 0 {
 
35
                return nil, os.NewSyscallError("GetAdaptersInfo", e)
 
36
        }
 
37
        return a, nil
 
38
}
 
39
 
 
40
func getInterfaceList() ([]syscall.InterfaceInfo, os.Error) {
 
41
        s, e := syscall.Socket(syscall.AF_INET, syscall.SOCK_DGRAM, syscall.IPPROTO_UDP)
 
42
        if e != 0 {
 
43
                return nil, os.NewSyscallError("Socket", e)
 
44
        }
 
45
        defer syscall.Closesocket(s)
 
46
 
 
47
        ii := [20]syscall.InterfaceInfo{}
 
48
        ret := uint32(0)
 
49
        size := uint32(unsafe.Sizeof(ii))
 
50
        e = syscall.WSAIoctl(s, syscall.SIO_GET_INTERFACE_LIST, nil, 0, (*byte)(unsafe.Pointer(&ii[0])), size, &ret, nil, 0)
 
51
        if e != 0 {
 
52
                return nil, os.NewSyscallError("WSAIoctl", e)
 
53
        }
 
54
        c := ret / uint32(unsafe.Sizeof(ii[0]))
 
55
        return ii[:c-1], nil
 
56
}
 
57
 
 
58
 
 
59
// If the ifindex is zero, interfaceTable returns mappings of all
 
60
// network interfaces.  Otheriwse it returns a mapping of a specific
 
61
// interface.
 
62
func interfaceTable(ifindex int) ([]Interface, os.Error) {
 
63
        ai, e := getAdapterList()
 
64
        if e != nil {
 
65
                return nil, e
 
66
        }
 
67
 
 
68
        ii, e := getInterfaceList()
 
69
        if e != nil {
 
70
                return nil, e
 
71
        }
 
72
 
 
73
        var ift []Interface
 
74
        for ; ai != nil; ai = ai.Next {
 
75
                index := ai.Index
 
76
                if ifindex == 0 || ifindex == int(index) {
 
77
                        var flags Flags
 
78
 
 
79
                        row := syscall.MibIfRow{Index: index}
 
80
                        e := syscall.GetIfEntry(&row)
 
81
                        if e != 0 {
 
82
                                return nil, os.NewSyscallError("GetIfEntry", e)
 
83
                        }
 
84
 
 
85
                        for _, ii := range ii {
 
86
                                ip := (*syscall.RawSockaddrInet4)(unsafe.Pointer(&ii.Address)).Addr
 
87
                                ipv4 := IPv4(ip[0], ip[1], ip[2], ip[3])
 
88
                                ipl := &ai.IpAddressList
 
89
                                for ipl != nil {
 
90
                                        ips := bytePtrToString(&ipl.IpAddress.String[0])
 
91
                                        if ipv4.Equal(parseIPv4(ips)) {
 
92
                                                break
 
93
                                        }
 
94
                                        ipl = ipl.Next
 
95
                                }
 
96
                                if ipl == nil {
 
97
                                        continue
 
98
                                }
 
99
                                if ii.Flags&syscall.IFF_UP != 0 {
 
100
                                        flags |= FlagUp
 
101
                                }
 
102
                                if ii.Flags&syscall.IFF_LOOPBACK != 0 {
 
103
                                        flags |= FlagLoopback
 
104
                                }
 
105
                                if ii.Flags&syscall.IFF_BROADCAST != 0 {
 
106
                                        flags |= FlagBroadcast
 
107
                                }
 
108
                                if ii.Flags&syscall.IFF_POINTTOPOINT != 0 {
 
109
                                        flags |= FlagPointToPoint
 
110
                                }
 
111
                                if ii.Flags&syscall.IFF_MULTICAST != 0 {
 
112
                                        flags |= FlagMulticast
 
113
                                }
 
114
                        }
 
115
 
 
116
                        name := bytePtrToString(&ai.AdapterName[0])
 
117
 
 
118
                        ifi := Interface{
 
119
                                Index:        int(index),
 
120
                                MTU:          int(row.Mtu),
 
121
                                Name:         name,
 
122
                                HardwareAddr: HardwareAddr(row.PhysAddr[:row.PhysAddrLen]),
 
123
                                Flags:        flags}
 
124
                        ift = append(ift, ifi)
 
125
                }
 
126
        }
 
127
        return ift, nil
 
128
}
 
129
 
 
130
// If the ifindex is zero, interfaceAddrTable returns addresses
 
131
// for all network interfaces.  Otherwise it returns addresses
 
132
// for a specific interface.
 
133
func interfaceAddrTable(ifindex int) ([]Addr, os.Error) {
 
134
        ai, e := getAdapterList()
 
135
        if e != nil {
 
136
                return nil, e
 
137
        }
 
138
 
 
139
        var ifat []Addr
 
140
        for ; ai != nil; ai = ai.Next {
 
141
                index := ai.Index
 
142
                if ifindex == 0 || ifindex == int(index) {
 
143
                        ipl := &ai.IpAddressList
 
144
                        for ; ipl != nil; ipl = ipl.Next {
 
145
                                ifa := IPAddr{}
 
146
                                ifa.IP = parseIPv4(bytePtrToString(&ipl.IpAddress.String[0]))
 
147
                                ifat = append(ifat, ifa.toAddr())
 
148
                        }
 
149
                }
 
150
        }
 
151
        return ifat, nil
 
152
}