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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [syscall/] [route_bsd.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
// +build darwin freebsd netbsd openbsd
6
 
7
// Routing sockets and messages
8
 
9
package syscall
10
 
11
import (
12
        "unsafe"
13
)
14
 
15
// Round the length of a raw sockaddr up to align it properly.
16
func rsaAlignOf(salen int) int {
17
        salign := sizeofPtr
18
        // NOTE: It seems like 64-bit Darwin kernel still requires 32-bit
19
        // aligned access to BSD subsystem.
20
        if darwinAMD64 {
21
                salign = 4
22
        }
23
        if salen == 0 {
24
                return salign
25
        }
26
        return (salen + salign - 1) & ^(salign - 1)
27
}
28
 
29
// RouteRIB returns routing information base, as known as RIB,
30
// which consists of network facility information, states and
31
// parameters.
32
func RouteRIB(facility, param int) ([]byte, error) {
33
        mib := []_C_int{CTL_NET, AF_ROUTE, 0, 0, _C_int(facility), _C_int(param)}
34
 
35
        // Find size.
36
        n := uintptr(0)
37
        if err := sysctl(mib, nil, &n, nil, 0); err != nil {
38
                return nil, err
39
        }
40
        if n == 0 {
41
                return nil, nil
42
        }
43
 
44
        tab := make([]byte, n)
45
        if err := sysctl(mib, &tab[0], &n, nil, 0); err != nil {
46
                return nil, err
47
        }
48
 
49
        return tab[:n], nil
50
}
51
 
52
// RoutingMessage represents a routing message.
53
type RoutingMessage interface {
54
        sockaddr() []Sockaddr
55
}
56
 
57
const anyMessageLen = int(unsafe.Sizeof(anyMessage{}))
58
 
59
type anyMessage struct {
60
        Msglen  uint16
61
        Version uint8
62
        Type    uint8
63
}
64
 
65
// RouteMessage represents a routing message containing routing
66
// entries.
67
type RouteMessage struct {
68
        Header RtMsghdr
69
        Data   []byte
70
}
71
 
72
const rtaRtMask = RTA_DST | RTA_GATEWAY | RTA_NETMASK | RTA_GENMASK
73
 
74
func (m *RouteMessage) sockaddr() []Sockaddr {
75
        var (
76
                af  int
77
                sas [4]Sockaddr
78
        )
79
 
80
        buf := m.Data[:]
81
        for i := uint(0); i < RTAX_MAX; i++ {
82
                if m.Header.Addrs&rtaRtMask&(1<
83
                        continue
84
                }
85
                rsa := (*RawSockaddr)(unsafe.Pointer(&buf[0]))
86
                switch i {
87
                case RTAX_DST, RTAX_GATEWAY:
88
                        sa, err := anyToSockaddr((*RawSockaddrAny)(unsafe.Pointer(rsa)))
89
                        if err != nil {
90
                                return nil
91
                        }
92
                        if i == RTAX_DST {
93
                                af = int(rsa.Family)
94
                        }
95
                        sas[i] = sa
96
                case RTAX_NETMASK, RTAX_GENMASK:
97
                        switch af {
98
                        case AF_INET:
99
                                rsa4 := (*RawSockaddrInet4)(unsafe.Pointer(&buf[0]))
100
                                sa := new(SockaddrInet4)
101
                                for j := 0; rsa4.Len > 0 && j < int(rsa4.Len)-int(unsafe.Offsetof(rsa4.Addr)); j++ {
102
                                        sa.Addr[j] = rsa4.Addr[j]
103
                                }
104
                                sas[i] = sa
105
                        case AF_INET6:
106
                                rsa6 := (*RawSockaddrInet6)(unsafe.Pointer(&buf[0]))
107
                                sa := new(SockaddrInet6)
108
                                for j := 0; rsa6.Len > 0 && j < int(rsa6.Len)-int(unsafe.Offsetof(rsa6.Addr)); j++ {
109
                                        sa.Addr[j] = rsa6.Addr[j]
110
                                }
111
                                sas[i] = sa
112
                        }
113
                }
114
                buf = buf[rsaAlignOf(int(rsa.Len)):]
115
        }
116
 
117
        return sas[:]
118
}
119
 
120
// InterfaceMessage represents a routing message containing
121
// network interface entries.
122
type InterfaceMessage struct {
123
        Header IfMsghdr
124
        Data   []byte
125
}
126
 
127
func (m *InterfaceMessage) sockaddr() (sas []Sockaddr) {
128
        if m.Header.Addrs&RTA_IFP == 0 {
129
                return nil
130
        }
131
        sa, err := anyToSockaddr((*RawSockaddrAny)(unsafe.Pointer(&m.Data[0])))
132
        if err != nil {
133
                return nil
134
        }
135
        return append(sas, sa)
136
}
137
 
138
// InterfaceAddrMessage represents a routing message containing
139
// network interface address entries.
140
type InterfaceAddrMessage struct {
141
        Header IfaMsghdr
142
        Data   []byte
143
}
144
 
145
const rtaIfaMask = RTA_IFA | RTA_NETMASK | RTA_BRD
146
 
147
func (m *InterfaceAddrMessage) sockaddr() (sas []Sockaddr) {
148
        if m.Header.Addrs&rtaIfaMask == 0 {
149
                return nil
150
        }
151
 
152
        buf := m.Data[:]
153
        for i := uint(0); i < RTAX_MAX; i++ {
154
                if m.Header.Addrs&rtaIfaMask&(1<
155
                        continue
156
                }
157
                rsa := (*RawSockaddr)(unsafe.Pointer(&buf[0]))
158
                switch i {
159
                case RTAX_IFA:
160
                        sa, err := anyToSockaddr((*RawSockaddrAny)(unsafe.Pointer(rsa)))
161
                        if err != nil {
162
                                return nil
163
                        }
164
                        sas = append(sas, sa)
165
                case RTAX_NETMASK:
166
                        if rsa.Family == AF_UNSPEC {
167
                                rsa.Family = AF_INET // an old fasion, AF_UNSPEC means AF_INET
168
                        }
169
                        sa, err := anyToSockaddr((*RawSockaddrAny)(unsafe.Pointer(rsa)))
170
                        if err != nil {
171
                                return nil
172
                        }
173
                        sas = append(sas, sa)
174
                case RTAX_BRD:
175
                        // nothing to do
176
                }
177
                buf = buf[rsaAlignOf(int(rsa.Len)):]
178
        }
179
 
180
        return sas
181
}
182
 
183
// ParseRoutingMessage parses buf as routing messages and returns
184
// the slice containing the RoutingMessage interfaces.
185
func ParseRoutingMessage(buf []byte) (msgs []RoutingMessage, err error) {
186
        for len(buf) >= anyMessageLen {
187
                any := (*anyMessage)(unsafe.Pointer(&buf[0]))
188
                if any.Version != RTM_VERSION {
189
                        return nil, EINVAL
190
                }
191
                msgs = append(msgs, any.toRoutingMessage(buf))
192
                buf = buf[any.Msglen:]
193
        }
194
        return msgs, nil
195
}
196
 
197
// ParseRoutingMessage parses msg's payload as raw sockaddrs and
198
// returns the slice containing the Sockaddr interfaces.
199
func ParseRoutingSockaddr(msg RoutingMessage) (sas []Sockaddr, err error) {
200
        return append(sas, msg.sockaddr()...), nil
201
}

powered by: WebSVN 2.1.0

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