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 type InterfaceAnnounceMessage struct {
     57 	Header IfAnnounceMsghdr
     58 }
     59 
     60 func (m *InterfaceAnnounceMessage) sockaddr() ([]Sockaddr, error) { return nil, nil }
     61 
     62 // InterfaceMulticastAddrMessage represents a routing message
     63 // containing network interface address entries.
     64 type InterfaceMulticastAddrMessage struct {
     65 	Header IfmaMsghdr
     66 	Data   []byte
     67 }
     68 
     69 func (m *InterfaceMulticastAddrMessage) sockaddr() ([]Sockaddr, error) {
     70 	var sas [RTAX_MAX]Sockaddr
     71 	b := m.Data[:]
     72 	for i := uint(0); i < RTAX_MAX && len(b) >= minRoutingSockaddrLen; i++ {
     73 		if m.Header.Addrs&(1<<i) == 0 {
     74 			continue
     75 		}
     76 		rsa := (*RawSockaddr)(unsafe.Pointer(&b[0]))
     77 		switch rsa.Family {
     78 		case AF_LINK:
     79 			sa, err := parseSockaddrLink(b)
     80 			if err != nil {
     81 				return nil, err
     82 			}
     83 			sas[i] = sa
     84 			b = b[rsaAlignOf(int(rsa.Len)):]
     85 		case AF_INET, AF_INET6:
     86 			sa, err := parseSockaddrInet(b, rsa.Family)
     87 			if err != nil {
     88 				return nil, err
     89 			}
     90 			sas[i] = sa
     91 			b = b[rsaAlignOf(int(rsa.Len)):]
     92 		default:
     93 			sa, l, err := parseLinkLayerAddr(b)
     94 			if err != nil {
     95 				return nil, err
     96 			}
     97 			sas[i] = sa
     98 			b = b[l:]
     99 		}
    100 	}
    101 	return sas[:], nil
    102 }
    103