Home | History | Annotate | Download | only in syscall
      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 package syscall
      6 
      7 import "unsafe"
      8 
      9 // See http://www.freebsd.org/doc/en/books/porters-handbook/freebsd-versions.html.
     10 var freebsdVersion uint32
     11 
     12 func init() {
     13 	freebsdVersion, _ = SysctlUint32("kern.osreldate")
     14 	conf, _ := Sysctl("kern.conftxt")
     15 	for i, j := 0, 0; j < len(conf); j++ {
     16 		if conf[j] != '\n' {
     17 			continue
     18 		}
     19 		s := conf[i:j]
     20 		i = j + 1
     21 		if len(s) > len("machine") && s[:len("machine")] == "machine" {
     22 			s = s[len("machine"):]
     23 			for k := 0; k < len(s); k++ {
     24 				if s[k] == ' ' || s[k] == '\t' {
     25 					s = s[1:]
     26 				}
     27 				break
     28 			}
     29 			freebsdConfArch = s
     30 			break
     31 		}
     32 	}
     33 }
     34 
     35 func (any *anyMessage) toRoutingMessage(b []byte) RoutingMessage {
     36 	switch any.Type {
     37 	case RTM_ADD, RTM_DELETE, RTM_CHANGE, RTM_GET, RTM_LOSING, RTM_REDIRECT, RTM_MISS, RTM_LOCK, RTM_RESOLVE:
     38 		return any.parseRouteMessage(b)
     39 	case RTM_IFINFO:
     40 		return any.parseInterfaceMessage(b)
     41 	case RTM_IFANNOUNCE:
     42 		p := (*InterfaceAnnounceMessage)(unsafe.Pointer(any))
     43 		return &InterfaceAnnounceMessage{Header: p.Header}
     44 	case RTM_NEWADDR, RTM_DELADDR:
     45 		p := (*InterfaceAddrMessage)(unsafe.Pointer(any))
     46 		return &InterfaceAddrMessage{Header: p.Header, Data: b[SizeofIfaMsghdr:any.Msglen]}
     47 	case RTM_NEWMADDR, RTM_DELMADDR:
     48 		p := (*InterfaceMulticastAddrMessage)(unsafe.Pointer(any))
     49 		return &InterfaceMulticastAddrMessage{Header: p.Header, Data: b[SizeofIfmaMsghdr:any.Msglen]}
     50 	}
     51 	return nil
     52 }
     53 
     54 // InterfaceAnnounceMessage represents a routing message containing
     55 // network interface arrival and departure information.
     56 //
     57 // Deprecated: Use golang.org/x/net/route instead.
     58 type InterfaceAnnounceMessage struct {
     59 	Header IfAnnounceMsghdr
     60 }
     61 
     62 func (m *InterfaceAnnounceMessage) sockaddr() ([]Sockaddr, error) { return nil, nil }
     63 
     64 // InterfaceMulticastAddrMessage represents a routing message
     65 // containing network interface address entries.
     66 //
     67 // Deprecated: Use golang.org/x/net/route instead.
     68 type InterfaceMulticastAddrMessage struct {
     69 	Header IfmaMsghdr
     70 	Data   []byte
     71 }
     72 
     73 func (m *InterfaceMulticastAddrMessage) sockaddr() ([]Sockaddr, error) {
     74 	var sas [RTAX_MAX]Sockaddr
     75 	b := m.Data[:]
     76 	for i := uint(0); i < RTAX_MAX && len(b) >= minRoutingSockaddrLen; i++ {
     77 		if m.Header.Addrs&(1<<i) == 0 {
     78 			continue
     79 		}
     80 		rsa := (*RawSockaddr)(unsafe.Pointer(&b[0]))
     81 		switch rsa.Family {
     82 		case AF_LINK:
     83 			sa, err := parseSockaddrLink(b)
     84 			if err != nil {
     85 				return nil, err
     86 			}
     87 			sas[i] = sa
     88 			b = b[rsaAlignOf(int(rsa.Len)):]
     89 		case AF_INET, AF_INET6:
     90 			sa, err := parseSockaddrInet(b, rsa.Family)
     91 			if err != nil {
     92 				return nil, err
     93 			}
     94 			sas[i] = sa
     95 			b = b[rsaAlignOf(int(rsa.Len)):]
     96 		default:
     97 			sa, l, err := parseLinkLayerAddr(b)
     98 			if err != nil {
     99 				return nil, err
    100 			}
    101 			sas[i] = sa
    102 			b = b[l:]
    103 		}
    104 	}
    105 	return sas[:], nil
    106 }
    107