Compare commits
No commits in common. "4b5fce5c1f321ea371455da3fb73473cb92bbb7d" and "7283f52d413d9b8cd0694ebfb0204adae3a198ea" have entirely different histories.
4b5fce5c1f
...
7283f52d41
2
main.go
2
main.go
|
@ -90,6 +90,7 @@ 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)
|
||||
|
@ -121,7 +122,6 @@ 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:
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
// 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]]
|
||||
}
|
97
tlv/tlv.go
97
tlv/tlv.go
|
@ -1,6 +1,5 @@
|
|||
//go:generate stringer -type=Type -trimprefix Type
|
||||
//go:generate stringer -type=SubType -trimprefix SubType
|
||||
//go:generate stringer -type=AEType -trimprefix AE
|
||||
package tlv
|
||||
|
||||
import (
|
||||
|
@ -36,10 +35,6 @@ type TLV interface {
|
|||
|
||||
type SubType uint8
|
||||
|
||||
func (s SubType) IsMandatory() bool {
|
||||
return s >= 128
|
||||
}
|
||||
|
||||
const (
|
||||
SubTypePad1 = SubType(0)
|
||||
SubTypePadN = SubType(1)
|
||||
|
@ -53,33 +48,6 @@ 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
|
||||
|
@ -248,12 +216,6 @@ 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
|
||||
}
|
||||
|
@ -317,7 +279,6 @@ 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 {
|
||||
|
@ -333,7 +294,6 @@ 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 {
|
||||
|
@ -349,7 +309,6 @@ 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
|
||||
|
@ -374,7 +333,6 @@ 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
|
||||
}
|
||||
|
@ -382,9 +340,11 @@ 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
|
||||
|
@ -393,7 +353,6 @@ 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
|
||||
|
@ -419,7 +378,6 @@ 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
|
||||
|
@ -431,7 +389,7 @@ type IHU struct {
|
|||
func (IHU) T() Type {
|
||||
return TypeIHU
|
||||
}
|
||||
func (i IHU) AE() AEType {
|
||||
func (i IHU) AE() uint8 {
|
||||
return AEFromIP(i.Address)
|
||||
}
|
||||
func (i IHU) L() uint8 {
|
||||
|
@ -455,7 +413,7 @@ func IHUFromBytes(b []byte) (IHU, []byte, error) {
|
|||
var ihu IHU
|
||||
var err error
|
||||
|
||||
ae := AEType(b[0])
|
||||
ae := 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:])
|
||||
|
@ -463,7 +421,6 @@ 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 (
|
||||
|
@ -490,12 +447,15 @@ 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)
|
||||
|
@ -508,7 +468,6 @@ 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
|
||||
|
@ -536,12 +495,11 @@ func NextHopFromBytes(b []byte) (NextHop, []byte, error) {
|
|||
|
||||
var nh NextHop
|
||||
var err error
|
||||
ae := AEType(b[0])
|
||||
ae := 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
|
||||
|
@ -558,14 +516,17 @@ 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
|
||||
|
@ -619,14 +580,32 @@ func (s *PacketDecoder) UpdateFromBytes(b []byte) (Update, []byte, error) {
|
|||
return u, b, err
|
||||
}
|
||||
|
||||
// https://datatracker.ietf.org/doc/html/rfc8966#section-4.6.10
|
||||
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() AEType {
|
||||
func (r RouteRequest) AE() uint8 {
|
||||
return AEFromPrefix(r.Prefix)
|
||||
}
|
||||
func (RouteRequest) T() Type {
|
||||
|
@ -647,7 +626,6 @@ 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
|
||||
|
@ -681,7 +659,6 @@ 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
|
||||
}
|
||||
|
@ -757,25 +734,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 AEType, b []byte) (netaddr.IP, []byte, error) {
|
||||
func ipFromBytes(ae uint8, b []byte) (netaddr.IP, []byte, error) {
|
||||
switch ae {
|
||||
case AEWildcard:
|
||||
case 0:
|
||||
return netaddr.IP{}, b, nil
|
||||
case AEIPv4:
|
||||
case 1:
|
||||
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 AEIPv6:
|
||||
case 2:
|
||||
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 AEIPv6LL:
|
||||
case 3:
|
||||
if len(b) < 8 {
|
||||
return netaddr.IP{}, b, fmt.Errorf("Not enough bytes for v6ll address: %d", len(b))
|
||||
}
|
||||
|
@ -784,8 +761,6 @@ func ipFromBytes(ae AEType, 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)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue