diff --git a/tlv/aetype_string.go b/tlv/aetype_string.go new file mode 100644 index 0000000..6eab6d9 --- /dev/null +++ b/tlv/aetype_string.go @@ -0,0 +1,27 @@ +// Code generated by "stringer -type=AEType -trimprefix AE"; DO NOT EDIT. + +package tlv + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[AEWildcard-0] + _ = x[AEIPv4-1] + _ = x[AEIPv6-2] + _ = x[AEIPv6LL-3] + _ = x[AEIPv4oIPv6-4] +} + +const _AEType_name = "WildcardIPv4IPv6IPv6LLIPv4oIPv6" + +var _AEType_index = [...]uint8{0, 8, 12, 16, 22, 31} + +func (i AEType) String() string { + if i >= AEType(len(_AEType_index)-1) { + return "AEType(" + strconv.FormatInt(int64(i), 10) + ")" + } + return _AEType_name[_AEType_index[i]:_AEType_index[i+1]] +} diff --git a/tlv/tlv.go b/tlv/tlv.go index 5c19e88..0b0a845 100644 --- a/tlv/tlv.go +++ b/tlv/tlv.go @@ -1,5 +1,6 @@ //go:generate stringer -type=Type -trimprefix Type //go:generate stringer -type=SubType -trimprefix SubType +//go:generate stringer -type=AEType -trimprefix AE package tlv import ( @@ -48,6 +49,33 @@ type SubTLV interface { L() uint8 } +type AEType uint8 + +const ( + AEWildcard = AEType(0) + AEIPv4 = AEType(1) + AEIPv6 = AEType(2) + AEIPv6LL = AEType(3) + AEIPv4oIPv6 = AEType(4) +) + +func AEFromPrefix(p netaddr.IPPrefix) AEType { + return AEFromIP(p.IP()) +} +func AEFromIP(p netaddr.IP) AEType { + switch { + case p.IsZero(): + return AEWildcard + case p.Is4(): + return AEIPv4 + case p.IsLinkLocalUnicast(): + return AEIPv6LL + case p.Is6(): + return AEIPv6 + } + panic("unknown AE") +} + type Scanner struct { buf []byte err error @@ -340,11 +368,9 @@ type Ack struct { func (Ack) T() Type { return TypeAck } - func (Ack) L() uint8 { return 4 } - func AckFromBytes(b []byte) (Ack, []byte, error) { if err := assertLengthGreater(b, TypeAck, 2); err != nil { return Ack{}, b, err @@ -389,7 +415,7 @@ type IHU struct { func (IHU) T() Type { return TypeIHU } -func (i IHU) AE() uint8 { +func (i IHU) AE() AEType { return AEFromIP(i.Address) } func (i IHU) L() uint8 { @@ -413,7 +439,7 @@ func IHUFromBytes(b []byte) (IHU, []byte, error) { var ihu IHU var err error - ae := b[0] + ae := AEType(b[0]) ihu.Rxcost = uint16(b[2])<<8 | uint16(b[3]) ihu.Interval = uint16(b[4])<<8 | uint16(b[5]) ihu.Address, b, err = ipFromBytes(ae, b[6:]) @@ -447,15 +473,12 @@ func RouterIDFromBytes(b []byte) (RouterID, []byte, error) { return rid, b, nil } - func (RouterID) T() Type { return TypeRouterID } - func (RouterID) L() uint8 { return 8 } - func (r RouterID) String() string { var buf bytes.Buffer buf.Grow(8*3 - 1) @@ -495,7 +518,7 @@ func NextHopFromBytes(b []byte) (NextHop, []byte, error) { var nh NextHop var err error - ae := b[0] + ae := AEType(b[0]) nh.Address, b, err = ipFromBytes(ae, b[2:]) return nh, b, err } @@ -516,17 +539,14 @@ type Update struct { func (Update) T() Type { return TypeUpdate } - func (u Update) L() uint8 { return 10 + psizeFromPlen(u.Prefix.Bits()) } - func (u Update) FormatHeader() string { return fmt.Sprintf("Flags 0x%02x Omitted %2d Interval %4d Seqno %5d Metric %5d RouterID %s", u.Flags, u.Omitted, u.Interval, u.Seqno, u.Metric, u.RouterID, ) } - func (s *PacketDecoder) UpdateFromBytes(b []byte) (Update, []byte, error) { if err := assertLengthGreater(b, TypeUpdate, 10); err != nil { return Update{}, b, err @@ -580,32 +600,13 @@ func (s *PacketDecoder) UpdateFromBytes(b []byte) (Update, []byte, error) { return u, b, err } -func AEFromPrefix(p netaddr.IPPrefix) uint8 { - return AEFromIP(p.IP()) -} -func AEFromIP(p netaddr.IP) uint8 { - if p.IsZero() { - return 0 - } - if p.Is4() { - return 1 - } - if p.IsLinkLocalUnicast() { - return 3 - } - if p.Is6() { - return 2 - } - panic("unknown AE") -} - type RouteRequest struct { // AE uint8 // plen uint8 Prefix netaddr.IPPrefix } -func (r RouteRequest) AE() uint8 { +func (r RouteRequest) AE() AEType { return AEFromPrefix(r.Prefix) } func (RouteRequest) T() Type { @@ -734,25 +735,25 @@ func prefixV6LL(b []byte) (netaddr.IPPrefix, []byte, error) { copy(ip6ll[8:], b[:8]) return netaddr.IPPrefixFrom(netaddr.IPv6Raw(ip6ll), 8), b[8:], nil } -func ipFromBytes(ae uint8, b []byte) (netaddr.IP, []byte, error) { +func ipFromBytes(ae AEType, b []byte) (netaddr.IP, []byte, error) { switch ae { - case 0: + case AEWildcard: return netaddr.IP{}, b, nil - case 1: + case AEIPv4: if len(b) < 4 { return netaddr.IP{}, b, fmt.Errorf("Not enough bytes for v4 address: %d", len(b)) } var ip4 [4]byte copy(ip4[:], b[:4]) return netaddr.IPFrom4(ip4), b[4:], nil - case 2: + case AEIPv6: if len(b) < 16 { return netaddr.IP{}, b, fmt.Errorf("Not enough bytes for v6 address: %d", len(b)) } var ip6 [16]byte copy(ip6[:], b[:16]) return netaddr.IPv6Raw(ip6), b[16:], nil - case 3: + case AEIPv6LL: if len(b) < 8 { return netaddr.IP{}, b, fmt.Errorf("Not enough bytes for v6ll address: %d", len(b)) } @@ -761,6 +762,8 @@ func ipFromBytes(ae uint8, b []byte) (netaddr.IP, []byte, error) { ip6ll[1] = 0x80 copy(ip6ll[8:], b[:8]) return netaddr.IPv6Raw(ip6ll), b[8:], nil + case AEIPv4oIPv6: + return netaddr.IP{}, b, fmt.Errorf("Not implemented AE Type %s", ae) default: return netaddr.IP{}, b, fmt.Errorf("Invalid AE %d", ae) }