addr: Parse address lifetime information from IFA_CACHEINFO attr

This adds parsing of the preferred and valid lifetime information from the
netlink IFA_CACHEINFO attribute. They are stored as PreferedLft and ValidLft in
the Addr struct if found.

Signed-off-by: Toke Høiland-Jørgensen <toke@toke.dk>
This commit is contained in:
Toke Høiland-Jørgensen 2017-04-12 18:54:00 +02:00 committed by Vish Ishaya
parent 40e43c1d63
commit 69df5c75fb
4 changed files with 69 additions and 5 deletions

12
addr.go
View File

@ -10,11 +10,13 @@ import (
// include a mask, so it stores the address as a net.IPNet.
type Addr struct {
*net.IPNet
Label string
Flags int
Scope int
Peer *net.IPNet
Broadcast net.IP
Label string
Flags int
Scope int
Peer *net.IPNet
Broadcast net.IP
PreferedLft int
ValidLft int
}
// String returns $ip/$netmask $label

View File

@ -199,6 +199,10 @@ func parseAddr(m []byte) (addr Addr, family, index int, err error) {
addr.Label = string(attr.Value[:len(attr.Value)-1])
case IFA_FLAGS:
addr.Flags = int(native.Uint32(attr.Value[0:4]))
case nl.IFA_CACHEINFO:
ci := nl.DeserializeIfaCacheInfo(attr.Value)
addr.PreferedLft = int(ci.IfaPrefered)
addr.ValidLft = int(ci.IfaValid)
}
}

View File

@ -45,3 +45,32 @@ func (msg *IfAddrmsg) Serialize() []byte {
func (msg *IfAddrmsg) Len() int {
return syscall.SizeofIfAddrmsg
}
// struct ifa_cacheinfo {
// __u32 ifa_prefered;
// __u32 ifa_valid;
// __u32 cstamp; /* created timestamp, hundredths of seconds */
// __u32 tstamp; /* updated timestamp, hundredths of seconds */
// };
const IFA_CACHEINFO = 6
const SizeofIfaCacheInfo = 0x10
type IfaCacheInfo struct {
IfaPrefered uint32
IfaValid uint32
Cstamp uint32
Tstamp uint32
}
func (msg *IfaCacheInfo) Len() int {
return SizeofIfaCacheInfo
}
func DeserializeIfaCacheInfo(b []byte) *IfaCacheInfo {
return (*IfaCacheInfo)(unsafe.Pointer(&b[0:SizeofIfaCacheInfo][0]))
}
func (msg *IfaCacheInfo) Serialize() []byte {
return (*(*[SizeofIfaCacheInfo]byte)(unsafe.Pointer(msg)))[:]
}

View File

@ -37,3 +37,32 @@ func TestIfAddrmsgDeserializeSerialize(t *testing.T) {
msg := DeserializeIfAddrmsg(orig)
testDeserializeSerialize(t, orig, safemsg, msg)
}
func (msg *IfaCacheInfo) write(b []byte) {
native := NativeEndian()
native.PutUint32(b[0:4], uint32(msg.IfaPrefered))
native.PutUint32(b[4:8], uint32(msg.IfaValid))
native.PutUint32(b[8:12], uint32(msg.Cstamp))
native.PutUint32(b[12:16], uint32(msg.Tstamp))
}
func (msg *IfaCacheInfo) serializeSafe() []byte {
length := SizeofIfaCacheInfo
b := make([]byte, length)
msg.write(b)
return b
}
func deserializeIfaCacheInfoSafe(b []byte) *IfaCacheInfo {
var msg = IfaCacheInfo{}
binary.Read(bytes.NewReader(b[0:SizeofIfaCacheInfo]), NativeEndian(), &msg)
return &msg
}
func TestIfaCacheInfoDeserializeSerialize(t *testing.T) {
var orig = make([]byte, SizeofIfaCacheInfo)
rand.Read(orig)
safemsg := deserializeIfaCacheInfoSafe(orig)
msg := DeserializeIfaCacheInfo(orig)
testDeserializeSerialize(t, orig, safemsg, msg)
}