summaryrefslogtreecommitdiffstats
path: root/vendor/golang.org/x/net/route/address.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/golang.org/x/net/route/address.go')
-rw-r--r--vendor/golang.org/x/net/route/address.go152
1 files changed, 148 insertions, 4 deletions
diff --git a/vendor/golang.org/x/net/route/address.go b/vendor/golang.org/x/net/route/address.go
index a56909c10..e6bfa39e9 100644
--- a/vendor/golang.org/x/net/route/address.go
+++ b/vendor/golang.org/x/net/route/address.go
@@ -24,6 +24,39 @@ type LinkAddr struct {
// Family implements the Family method of Addr interface.
func (a *LinkAddr) Family() int { return sysAF_LINK }
+func (a *LinkAddr) lenAndSpace() (int, int) {
+ l := 8 + len(a.Name) + len(a.Addr)
+ return l, roundup(l)
+}
+
+func (a *LinkAddr) marshal(b []byte) (int, error) {
+ l, ll := a.lenAndSpace()
+ if len(b) < ll {
+ return 0, errShortBuffer
+ }
+ nlen, alen := len(a.Name), len(a.Addr)
+ if nlen > 255 || alen > 255 {
+ return 0, errInvalidAddr
+ }
+ b[0] = byte(l)
+ b[1] = sysAF_LINK
+ if a.Index > 0 {
+ nativeEndian.PutUint16(b[2:4], uint16(a.Index))
+ }
+ data := b[8:]
+ if nlen > 0 {
+ b[5] = byte(nlen)
+ copy(data[:nlen], a.Addr)
+ data = data[nlen:]
+ }
+ if alen > 0 {
+ b[6] = byte(alen)
+ copy(data[:alen], a.Name)
+ data = data[alen:]
+ }
+ return ll, nil
+}
+
func parseLinkAddr(b []byte) (Addr, error) {
if len(b) < 8 {
return nil, errInvalidAddr
@@ -90,6 +123,21 @@ type Inet4Addr struct {
// Family implements the Family method of Addr interface.
func (a *Inet4Addr) Family() int { return sysAF_INET }
+func (a *Inet4Addr) lenAndSpace() (int, int) {
+ return sizeofSockaddrInet, roundup(sizeofSockaddrInet)
+}
+
+func (a *Inet4Addr) marshal(b []byte) (int, error) {
+ l, ll := a.lenAndSpace()
+ if len(b) < ll {
+ return 0, errShortBuffer
+ }
+ b[0] = byte(l)
+ b[1] = sysAF_INET
+ copy(b[4:8], a.IP[:])
+ return ll, nil
+}
+
// An Inet6Addr represents an internet address for IPv6.
type Inet6Addr struct {
IP [16]byte // IP address
@@ -99,18 +147,36 @@ type Inet6Addr struct {
// Family implements the Family method of Addr interface.
func (a *Inet6Addr) Family() int { return sysAF_INET6 }
+func (a *Inet6Addr) lenAndSpace() (int, int) {
+ return sizeofSockaddrInet6, roundup(sizeofSockaddrInet6)
+}
+
+func (a *Inet6Addr) marshal(b []byte) (int, error) {
+ l, ll := a.lenAndSpace()
+ if len(b) < ll {
+ return 0, errShortBuffer
+ }
+ b[0] = byte(l)
+ b[1] = sysAF_INET6
+ copy(b[8:24], a.IP[:])
+ if a.ZoneID > 0 {
+ nativeEndian.PutUint32(b[24:28], uint32(a.ZoneID))
+ }
+ return ll, nil
+}
+
// parseInetAddr parses b as an internet address for IPv4 or IPv6.
func parseInetAddr(af int, b []byte) (Addr, error) {
switch af {
case sysAF_INET:
- if len(b) < 16 {
+ if len(b) < sizeofSockaddrInet {
return nil, errInvalidAddr
}
a := &Inet4Addr{}
copy(a.IP[:], b[4:8])
return a, nil
case sysAF_INET6:
- if len(b) < 28 {
+ if len(b) < sizeofSockaddrInet6 {
return nil, errInvalidAddr
}
a := &Inet6Addr{ZoneID: int(nativeEndian.Uint32(b[24:28]))}
@@ -174,7 +240,7 @@ func parseKernelInetAddr(af int, b []byte) (int, Addr, error) {
off6 = 8 // offset of in6_addr
)
switch {
- case b[0] == 28: // size of sockaddr_in6
+ case b[0] == sizeofSockaddrInet6:
a := &Inet6Addr{}
copy(a.IP[:], b[off6:off6+16])
return int(b[0]), a, nil
@@ -186,7 +252,7 @@ func parseKernelInetAddr(af int, b []byte) (int, Addr, error) {
copy(a.IP[:], b[l-off6:l])
}
return int(b[0]), a, nil
- case b[0] == 16: // size of sockaddr_in
+ case b[0] == sizeofSockaddrInet:
a := &Inet4Addr{}
copy(a.IP[:], b[off4:off4+4])
return int(b[0]), a, nil
@@ -211,6 +277,24 @@ type DefaultAddr struct {
// Family implements the Family method of Addr interface.
func (a *DefaultAddr) Family() int { return a.af }
+func (a *DefaultAddr) lenAndSpace() (int, int) {
+ l := len(a.Raw)
+ return l, roundup(l)
+}
+
+func (a *DefaultAddr) marshal(b []byte) (int, error) {
+ l, ll := a.lenAndSpace()
+ if len(b) < ll {
+ return 0, errShortBuffer
+ }
+ if l > 255 {
+ return 0, errInvalidAddr
+ }
+ b[1] = byte(l)
+ copy(b[:l], a.Raw)
+ return ll, nil
+}
+
func parseDefaultAddr(b []byte) (Addr, error) {
if len(b) < 2 || len(b) < int(b[0]) {
return nil, errInvalidAddr
@@ -219,6 +303,66 @@ func parseDefaultAddr(b []byte) (Addr, error) {
return a, nil
}
+func addrsSpace(as []Addr) int {
+ var l int
+ for _, a := range as {
+ switch a := a.(type) {
+ case *LinkAddr:
+ _, ll := a.lenAndSpace()
+ l += ll
+ case *Inet4Addr:
+ _, ll := a.lenAndSpace()
+ l += ll
+ case *Inet6Addr:
+ _, ll := a.lenAndSpace()
+ l += ll
+ case *DefaultAddr:
+ _, ll := a.lenAndSpace()
+ l += ll
+ }
+ }
+ return l
+}
+
+// marshalAddrs marshals as and returns a bitmap indicating which
+// address is stored in b.
+func marshalAddrs(b []byte, as []Addr) (uint, error) {
+ var attrs uint
+ for i, a := range as {
+ switch a := a.(type) {
+ case *LinkAddr:
+ l, err := a.marshal(b)
+ if err != nil {
+ return 0, err
+ }
+ b = b[l:]
+ attrs |= 1 << uint(i)
+ case *Inet4Addr:
+ l, err := a.marshal(b)
+ if err != nil {
+ return 0, err
+ }
+ b = b[l:]
+ attrs |= 1 << uint(i)
+ case *Inet6Addr:
+ l, err := a.marshal(b)
+ if err != nil {
+ return 0, err
+ }
+ b = b[l:]
+ attrs |= 1 << uint(i)
+ case *DefaultAddr:
+ l, err := a.marshal(b)
+ if err != nil {
+ return 0, err
+ }
+ b = b[l:]
+ attrs |= 1 << uint(i)
+ }
+ }
+ return attrs, nil
+}
+
func parseAddrs(attrs uint, fn func(int, []byte) (int, Addr, error), b []byte) ([]Addr, error) {
var as [sysRTAX_MAX]Addr
af := int(sysAF_UNSPEC)