OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [net/] [interface_linux.go] - Blame information for rev 747

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 747 jeremybenn
// 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 Linux
6
 
7
package net
8
 
9
import (
10
        "fmt"
11
        "os"
12
        "syscall"
13
        "unsafe"
14
)
15
 
16
// If the ifindex is zero, interfaceTable returns mappings of all
17
// network interfaces.  Otheriwse it returns a mapping of a specific
18
// interface.
19
func interfaceTable(ifindex int) ([]Interface, error) {
20
        tab, err := syscall.NetlinkRIB(syscall.RTM_GETLINK, syscall.AF_UNSPEC)
21
        if err != nil {
22
                return nil, os.NewSyscallError("netlink rib", err)
23
        }
24
 
25
        msgs, err := syscall.ParseNetlinkMessage(tab)
26
        if err != nil {
27
                return nil, os.NewSyscallError("netlink message", err)
28
        }
29
 
30
        var ift []Interface
31
        for _, m := range msgs {
32
                switch m.Header.Type {
33
                case syscall.NLMSG_DONE:
34
                        goto done
35
                case syscall.RTM_NEWLINK:
36
                        ifim := (*syscall.IfInfomsg)(unsafe.Pointer(&m.Data[0]))
37
                        if ifindex == 0 || ifindex == int(ifim.Index) {
38
                                attrs, err := syscall.ParseNetlinkRouteAttr(&m)
39
                                if err != nil {
40
                                        return nil, os.NewSyscallError("netlink routeattr", err)
41
                                }
42
                                ifi := newLink(ifim, attrs)
43
                                ift = append(ift, ifi)
44
                        }
45
                }
46
        }
47
done:
48
        return ift, nil
49
}
50
 
51
func newLink(ifim *syscall.IfInfomsg, attrs []syscall.NetlinkRouteAttr) Interface {
52
        ifi := Interface{Index: int(ifim.Index), Flags: linkFlags(ifim.Flags)}
53
        for _, a := range attrs {
54
                switch a.Attr.Type {
55
                case syscall.IFLA_ADDRESS:
56
                        var nonzero bool
57
                        for _, b := range a.Value {
58
                                if b != 0 {
59
                                        nonzero = true
60
                                }
61
                        }
62
                        if nonzero {
63
                                ifi.HardwareAddr = a.Value[:]
64
                        }
65
                case syscall.IFLA_IFNAME:
66
                        ifi.Name = string(a.Value[:len(a.Value)-1])
67
                case syscall.IFLA_MTU:
68
                        ifi.MTU = int(uint32(a.Value[3])<<24 | uint32(a.Value[2])<<16 | uint32(a.Value[1])<<8 | uint32(a.Value[0]))
69
                }
70
        }
71
        return ifi
72
}
73
 
74
func linkFlags(rawFlags uint32) Flags {
75
        var f Flags
76
        if rawFlags&syscall.IFF_UP != 0 {
77
                f |= FlagUp
78
        }
79
        if rawFlags&syscall.IFF_BROADCAST != 0 {
80
                f |= FlagBroadcast
81
        }
82
        if rawFlags&syscall.IFF_LOOPBACK != 0 {
83
                f |= FlagLoopback
84
        }
85
        if rawFlags&syscall.IFF_POINTOPOINT != 0 {
86
                f |= FlagPointToPoint
87
        }
88
        if rawFlags&syscall.IFF_MULTICAST != 0 {
89
                f |= FlagMulticast
90
        }
91
        return f
92
}
93
 
94
// If the ifindex is zero, interfaceAddrTable returns addresses
95
// for all network interfaces.  Otherwise it returns addresses
96
// for a specific interface.
97
func interfaceAddrTable(ifindex int) ([]Addr, error) {
98
        tab, err := syscall.NetlinkRIB(syscall.RTM_GETADDR, syscall.AF_UNSPEC)
99
        if err != nil {
100
                return nil, os.NewSyscallError("netlink rib", err)
101
        }
102
 
103
        msgs, err := syscall.ParseNetlinkMessage(tab)
104
        if err != nil {
105
                return nil, os.NewSyscallError("netlink message", err)
106
        }
107
 
108
        ifat, err := addrTable(msgs, ifindex)
109
        if err != nil {
110
                return nil, err
111
        }
112
        return ifat, nil
113
}
114
 
115
func addrTable(msgs []syscall.NetlinkMessage, ifindex int) ([]Addr, error) {
116
        var ifat []Addr
117
        for _, m := range msgs {
118
                switch m.Header.Type {
119
                case syscall.NLMSG_DONE:
120
                        goto done
121
                case syscall.RTM_NEWADDR:
122
                        ifam := (*syscall.IfAddrmsg)(unsafe.Pointer(&m.Data[0]))
123
                        if ifindex == 0 || ifindex == int(ifam.Index) {
124
                                attrs, err := syscall.ParseNetlinkRouteAttr(&m)
125
                                if err != nil {
126
                                        return nil, os.NewSyscallError("netlink routeattr", err)
127
                                }
128
                                ifat = append(ifat, newAddr(attrs, int(ifam.Family), int(ifam.Prefixlen)))
129
                        }
130
                }
131
        }
132
done:
133
        return ifat, nil
134
}
135
 
136
func newAddr(attrs []syscall.NetlinkRouteAttr, family, pfxlen int) Addr {
137
        ifa := &IPNet{}
138
        for _, a := range attrs {
139
                switch a.Attr.Type {
140
                case syscall.IFA_ADDRESS:
141
                        switch family {
142
                        case syscall.AF_INET:
143
                                ifa.IP = IPv4(a.Value[0], a.Value[1], a.Value[2], a.Value[3])
144
                                ifa.Mask = CIDRMask(pfxlen, 8*IPv4len)
145
                        case syscall.AF_INET6:
146
                                ifa.IP = make(IP, IPv6len)
147
                                copy(ifa.IP, a.Value[:])
148
                                ifa.Mask = CIDRMask(pfxlen, 8*IPv6len)
149
                        }
150
                }
151
        }
152
        return ifa
153
}
154
 
155
// If the ifindex is zero, interfaceMulticastAddrTable returns
156
// addresses for all network interfaces.  Otherwise it returns
157
// addresses for a specific interface.
158
func interfaceMulticastAddrTable(ifindex int) ([]Addr, error) {
159
        var (
160
                err error
161
                ifi *Interface
162
        )
163
        if ifindex > 0 {
164
                ifi, err = InterfaceByIndex(ifindex)
165
                if err != nil {
166
                        return nil, err
167
                }
168
        }
169
        ifmat4 := parseProcNetIGMP(ifi)
170
        ifmat6 := parseProcNetIGMP6(ifi)
171
        return append(ifmat4, ifmat6...), nil
172
}
173
 
174
func parseProcNetIGMP(ifi *Interface) []Addr {
175
        fd, err := open("/proc/net/igmp")
176
        if err != nil {
177
                return nil
178
        }
179
        defer fd.close()
180
 
181
        var (
182
                ifmat []Addr
183
                name  string
184
        )
185
        fd.readLine() // skip first line
186
        b := make([]byte, IPv4len)
187
        for l, ok := fd.readLine(); ok; l, ok = fd.readLine() {
188
                f := getFields(l)
189
                switch len(f) {
190
                case 4:
191
                        if ifi == nil || name == ifi.Name {
192
                                fmt.Sscanf(f[0], "%08x", &b)
193
                                ifma := IPAddr{IP: IPv4(b[3], b[2], b[1], b[0])}
194
                                ifmat = append(ifmat, ifma.toAddr())
195
                        }
196
                case 5:
197
                        name = f[1]
198
                }
199
        }
200
        return ifmat
201
}
202
 
203
func parseProcNetIGMP6(ifi *Interface) []Addr {
204
        fd, err := open("/proc/net/igmp6")
205
        if err != nil {
206
                return nil
207
        }
208
        defer fd.close()
209
 
210
        var ifmat []Addr
211
        b := make([]byte, IPv6len)
212
        for l, ok := fd.readLine(); ok; l, ok = fd.readLine() {
213
                f := getFields(l)
214
                if ifi == nil || f[1] == ifi.Name {
215
                        fmt.Sscanf(f[2], "%32x", &b)
216
                        ifma := IPAddr{IP: IP{b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7], b[8], b[9], b[10], b[11], b[12], b[13], b[14], b[15]}}
217
                        ifmat = append(ifmat, ifma.toAddr())
218
 
219
                }
220
        }
221
        return ifmat
222
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.