Compare commits

...

3 Commits

3 changed files with 89 additions and 37 deletions

View File

@ -90,7 +90,6 @@ func run(opt options) error {
var s tlv.PacketDecoder
s.Reset(b, src)
for s.Scan() {
var subtlv []byte
switch t := s.TLV().(type) {
case tlv.NextHop:
fmt.Printf("%12s %s\n", t.T(), t.Address)
@ -122,6 +121,7 @@ func run(opt options) error {
fmt.Println("got nil TLV")
}
}
subtlv := s.SubTLV()
for len(subtlv) > 0 {
switch tlv.SubType(subtlv[0]) {
case tlv.SubTypeSourcePrefix:

27
tlv/aetype_string.go Normal file
View File

@ -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]]
}

View File

@ -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 (
@ -35,6 +36,10 @@ type TLV interface {
type SubType uint8
func (s SubType) IsMandatory() bool {
return s >= 128
}
const (
SubTypePad1 = SubType(0)
SubTypePadN = SubType(1)
@ -48,6 +53,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
@ -216,6 +248,12 @@ func (s *PacketDecoder) TLV() TLV {
}
return s.tlv
}
func (s *PacketDecoder) SubTLV() []byte {
if s.err != nil {
return nil
}
return s.subtlv
}
func (s *PacketDecoder) Err() error {
return s.err
}
@ -279,6 +317,7 @@ func assertSubLengthGreater(b []byte, t SubType, l int) error {
return nil
}
// https://datatracker.ietf.org/doc/html/rfc8966#section-4.6.1
type Pad1 struct{}
func (Pad1) T() Type {
@ -294,6 +333,7 @@ func Pad1FromBytes(b []byte) (Pad1, []byte, error) {
return Pad1{}, b[1:], nil
}
// https://datatracker.ietf.org/doc/html/rfc8966#section-4.6.2
type PadN uint8
func (PadN) T() Type {
@ -309,6 +349,7 @@ func PadNFromBytes(b []byte) (PadN, []byte, error) {
return PadN(b[1]), b[1:], nil
}
// https://datatracker.ietf.org/doc/html/rfc8966#section-4.6.3
type AckReq struct {
Opaque [2]byte
Interval uint16
@ -333,6 +374,7 @@ func AckReqFromBytes(b []byte) (AckReq, []byte, error) {
return ar, b[6:], nil
}
// https://datatracker.ietf.org/doc/html/rfc8966#section-4.6.4
type Ack struct {
Opaque uint16
}
@ -340,11 +382,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
@ -353,6 +393,7 @@ func AckFromBytes(b []byte) (Ack, []byte, error) {
return Ack{uint16(b[0])<<8 | uint16(b[1])}, b[4:], nil
}
// https://datatracker.ietf.org/doc/html/rfc8966#section-4.6.5
type Hello struct {
Flags uint16
Seqno uint16
@ -378,6 +419,7 @@ func HelloFromBytes(b []byte) (Hello, []byte, error) {
return h, b[6:], nil
}
// https://datatracker.ietf.org/doc/html/rfc8966#section-4.6.6
type IHU struct {
// AE uint8
// reserved uint8
@ -389,7 +431,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 +455,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:])
@ -421,6 +463,7 @@ func IHUFromBytes(b []byte) (IHU, []byte, error) {
return ihu, b, err
}
// https://datatracker.ietf.org/doc/html/rfc8966#section-4.6.7
type RouterID [8]byte
var (
@ -447,15 +490,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)
@ -468,6 +508,7 @@ func (r RouterID) String() string {
return buf.String()
}
// https://datatracker.ietf.org/doc/html/rfc8966#section-4.6.8
type NextHop struct {
// AE uint8
// reserved uint8
@ -495,11 +536,12 @@ 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
}
// https://datatracker.ietf.org/doc/html/rfc8966#section-4.6.9
type Update struct {
// AE uint8
Flags uint8
@ -516,17 +558,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 +619,14 @@ 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")
}
// https://datatracker.ietf.org/doc/html/rfc8966#section-4.6.10
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 {
@ -626,6 +647,7 @@ func RouteRequestFromBytes(b []byte) (RouteRequest, []byte, error) {
return rr, b, err
}
// https://datatracker.ietf.org/doc/html/rfc8966#section-4.6.11
type SeqnoRequest struct {
// AE uint8
// Plen uint8
@ -659,6 +681,7 @@ func SeqnoRequestFromBytes(b []byte) (SeqnoRequest, []byte, error) {
return sr, b, err
}
// https://datatracker.ietf.org/doc/html/draft-ietf-babel-source-specific-07#section-7.1
type SourcePrefix struct {
netaddr.IPPrefix
}
@ -734,25 +757,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 +784,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)
}