1 // Copyright 2016 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 // +build darwin dragonfly freebsd netbsd openbsd
16 func (m *RouteMessage) String() string {
17 return fmt.Sprintf("%s", addrAttrs(nativeEndian.Uint32(m.raw[12:16])))
20 func (m *InterfaceMessage) String() string {
22 if runtime.GOOS == "openbsd" {
23 attrs = addrAttrs(nativeEndian.Uint32(m.raw[12:16]))
25 attrs = addrAttrs(nativeEndian.Uint32(m.raw[4:8]))
27 return fmt.Sprintf("%s", attrs)
30 func (m *InterfaceAddrMessage) String() string {
32 if runtime.GOOS == "openbsd" {
33 attrs = addrAttrs(nativeEndian.Uint32(m.raw[12:16]))
35 attrs = addrAttrs(nativeEndian.Uint32(m.raw[4:8]))
37 return fmt.Sprintf("%s", attrs)
40 func (m *InterfaceMulticastAddrMessage) String() string {
41 return fmt.Sprintf("%s", addrAttrs(nativeEndian.Uint32(m.raw[4:8])))
44 func (m *InterfaceAnnounceMessage) String() string {
52 return fmt.Sprintf("(%d %s %s)", m.Index, m.Name, what)
55 func (m *InterfaceMetrics) String() string {
56 return fmt.Sprintf("(type=%d mtu=%d)", m.Type, m.MTU)
59 func (m *RouteMetrics) String() string {
60 return fmt.Sprintf("(pmtu=%d)", m.PathMTU)
65 var addrAttrNames = [...]string{
74 "df:mpls1-n:tag-o:src", // mpls1 for dragonfly, tag for netbsd, src for openbsd
75 "df:mpls2-o:srcmask", // mpls2 for dragonfly, srcmask for openbsd
76 "df:mpls3-o:label", // mpls3 for dragonfly, label for openbsd
77 "o:bfd", // bfd for openbsd
78 "o:dns", // dns for openbsd
79 "o:static", // static for openbsd
80 "o:search", // search for openbsd
83 func (attrs addrAttrs) String() string {
85 for i, name := range addrAttrNames {
86 if attrs&(1<<uint(i)) != 0 {
101 func (ms msgs) validate() ([]string, error) {
103 for _, m := range ms {
104 switch m := m.(type) {
106 if err := addrs(m.Addrs).match(addrAttrs(nativeEndian.Uint32(m.raw[12:16]))); err != nil {
111 return nil, fmt.Errorf("no sys for %s", m.String())
113 ss = append(ss, m.String()+" "+syss(sys).String()+" "+addrs(m.Addrs).String())
114 case *InterfaceMessage:
116 if runtime.GOOS == "openbsd" {
117 attrs = addrAttrs(nativeEndian.Uint32(m.raw[12:16]))
119 attrs = addrAttrs(nativeEndian.Uint32(m.raw[4:8]))
121 if err := addrs(m.Addrs).match(attrs); err != nil {
126 return nil, fmt.Errorf("no sys for %s", m.String())
128 ss = append(ss, m.String()+" "+syss(sys).String()+" "+addrs(m.Addrs).String())
129 case *InterfaceAddrMessage:
131 if runtime.GOOS == "openbsd" {
132 attrs = addrAttrs(nativeEndian.Uint32(m.raw[12:16]))
134 attrs = addrAttrs(nativeEndian.Uint32(m.raw[4:8]))
136 if err := addrs(m.Addrs).match(attrs); err != nil {
139 ss = append(ss, m.String()+" "+addrs(m.Addrs).String())
140 case *InterfaceMulticastAddrMessage:
141 if err := addrs(m.Addrs).match(addrAttrs(nativeEndian.Uint32(m.raw[4:8]))); err != nil {
144 ss = append(ss, m.String()+" "+addrs(m.Addrs).String())
145 case *InterfaceAnnounceMessage:
146 ss = append(ss, m.String())
148 ss = append(ss, fmt.Sprintf("%+v", m))
156 func (sys syss) String() string {
158 for _, sy := range sys {
159 switch sy := sy.(type) {
160 case *InterfaceMetrics:
177 func (af addrFamily) String() string {
188 return fmt.Sprintf("%d", af)
192 const hexDigit = "0123456789abcdef"
196 func (a llAddr) String() string {
200 buf := make([]byte, 0, len(a)*3-1)
201 for i, b := range a {
203 buf = append(buf, ':')
205 buf = append(buf, hexDigit[b>>4])
206 buf = append(buf, hexDigit[b&0xF])
213 func (a ipAddr) String() string {
218 return fmt.Sprintf("%d.%d.%d.%d", a[0], a[1], a[2], a[3])
221 return fmt.Sprintf("%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x", a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15])
223 s := make([]byte, len(a)*2)
224 for i, tn := range a {
225 s[i*2], s[i*2+1] = hexDigit[tn>>4], hexDigit[tn&0xf]
230 func (a *LinkAddr) String() string {
235 lla := llAddr(a.Addr).String()
239 return fmt.Sprintf("(%v %d %s %s)", addrFamily(a.Family()), a.Index, name, lla)
242 func (a *Inet4Addr) String() string {
243 return fmt.Sprintf("(%v %v)", addrFamily(a.Family()), ipAddr(a.IP[:]))
246 func (a *Inet6Addr) String() string {
247 return fmt.Sprintf("(%v %v %d)", addrFamily(a.Family()), ipAddr(a.IP[:]), a.ZoneID)
250 func (a *DefaultAddr) String() string {
251 return fmt.Sprintf("(%v %s)", addrFamily(a.Family()), ipAddr(a.Raw[2:]).String())
256 func (as addrs) String() string {
258 for _, a := range as {
265 switch a := a.(type) {
282 func (as addrs) match(attrs addrAttrs) error {
289 switch as[i].(type) {
291 if af == sysAF_UNSPEC {
294 if af != sysAF_INET {
295 return fmt.Errorf("got %v; want %v", addrs(as), addrFamily(af))
298 if af == sysAF_UNSPEC {
301 if af != sysAF_INET6 {
302 return fmt.Errorf("got %v; want %v", addrs(as), addrFamily(af))
306 if ts != attrs && ts > attrs {
307 return fmt.Errorf("%v not included in %v", ts, attrs)
312 func fetchAndParseRIB(af int, typ RIBType) ([]Message, error) {
315 for i := 0; i < 3; i++ {
316 if b, err = FetchRIB(af, typ, 0); err != nil {
317 time.Sleep(10 * time.Millisecond)
323 return nil, fmt.Errorf("%v %d %v", addrFamily(af), typ, err)
325 ms, err := ParseRIB(typ, b)
327 return nil, fmt.Errorf("%v %d %v", addrFamily(af), typ, err)
332 // propVirtual is a proprietary virtual network interface.
333 type propVirtual struct {
336 setupCmds []*exec.Cmd
337 teardownCmds []*exec.Cmd
340 func (pv *propVirtual) setup() error {
341 for _, cmd := range pv.setupCmds {
342 if err := cmd.Run(); err != nil {
350 func (pv *propVirtual) teardown() error {
351 for _, cmd := range pv.teardownCmds {
352 if err := cmd.Run(); err != nil {
359 func (pv *propVirtual) configure(suffix int) error {
360 if runtime.GOOS == "openbsd" {
361 pv.name = fmt.Sprintf("vether%d", suffix)
363 pv.name = fmt.Sprintf("vlan%d", suffix)
365 xname, err := exec.LookPath("ifconfig")
369 pv.setupCmds = append(pv.setupCmds, &exec.Cmd{
371 Args: []string{"ifconfig", pv.name, "create"},
373 if runtime.GOOS == "netbsd" {
374 // NetBSD requires an underlying dot1Q-capable network
376 pv.setupCmds = append(pv.setupCmds, &exec.Cmd{
378 Args: []string{"ifconfig", pv.name, "vlan", fmt.Sprintf("%d", suffix&0xfff), "vlanif", "wm0"},
381 pv.setupCmds = append(pv.setupCmds, &exec.Cmd{
383 Args: []string{"ifconfig", pv.name, "inet", pv.addr, "netmask", pv.mask},
385 pv.teardownCmds = append(pv.teardownCmds, &exec.Cmd{
387 Args: []string{"ifconfig", pv.name, "destroy"},