jrouter/aurp/routing_info.go

229 lines
4.5 KiB
Go
Raw Normal View History

2024-03-17 12:56:56 +11:00
package aurp
import (
"encoding/binary"
"fmt"
"io"
)
type RIReqPacket struct {
2024-03-17 13:31:26 +11:00
Header
2024-03-17 12:56:56 +11:00
}
2024-03-17 18:19:36 +11:00
func (p *RIReqPacket) WriteTo(w io.Writer) (int64, error) {
p.Sequence = 0
p.CommandCode = CmdCodeRIReq
return p.Header.WriteTo(w)
}
2024-03-17 12:56:56 +11:00
type RIRspPacket struct {
2024-03-17 13:31:26 +11:00
Header
2024-03-17 12:56:56 +11:00
Networks NetworkTuples
}
func (p *RIRspPacket) WriteTo(w io.Writer) (int64, error) {
2024-03-17 18:19:36 +11:00
p.CommandCode = CmdCodeRIRsp
2024-03-17 12:56:56 +11:00
a := acc(w)
2024-03-17 13:31:26 +11:00
a.writeTo(&p.Header)
2024-03-17 12:56:56 +11:00
a.writeTo(p.Networks)
return a.ret()
}
func parseRIRsp(p []byte) (*RIRspPacket, error) {
n, err := parseNetworkTuples(p)
if err != nil {
return nil, err
}
return &RIRspPacket{
Networks: n,
}, nil
}
type RIAckPacket struct {
2024-03-17 13:31:26 +11:00
Header
2024-03-17 12:56:56 +11:00
}
2024-03-17 18:19:36 +11:00
func (p *RIAckPacket) WriteTo(w io.Writer) (int64, error) {
p.CommandCode = CmdCodeRIAck
return p.Header.WriteTo(w)
}
2024-03-17 12:56:56 +11:00
type RIUpdPacket struct {
2024-03-17 13:31:26 +11:00
Header
2024-03-17 12:56:56 +11:00
Events EventTuples
}
func (p *RIUpdPacket) WriteTo(w io.Writer) (int64, error) {
2024-03-17 18:19:36 +11:00
p.CommandCode = CmdCodeRIUpd
2024-03-17 12:56:56 +11:00
a := acc(w)
2024-03-17 13:31:26 +11:00
a.writeTo(&p.Header)
2024-03-17 12:56:56 +11:00
a.writeTo(p.Events)
return a.ret()
}
func parseRIUpd(p []byte) (*RIUpdPacket, error) {
e, err := parseEventTuples(p)
if err != nil {
return nil, err
}
return &RIUpdPacket{
Events: e,
}, nil
}
type NetworkTuples []NetworkTuple
func (n NetworkTuples) WriteTo(w io.Writer) (int64, error) {
a := acc(w)
for _, nt := range n {
a.writeTo(&nt)
}
return a.ret()
}
func parseNetworkTuples(p []byte) (NetworkTuples, error) {
// Each network tuple is at least 3 bytes, so we need to store at most
// len(p)/3 of them.
n := make(NetworkTuples, 0, len(p)/3)
for len(p) > 0 {
nt, nextp, err := parseNetworkTuple(p)
if err != nil {
return nil, fmt.Errorf("parsing network tuple %d: %w", len(n), err)
}
n = append(n, nt)
p = nextp
}
return n, nil
}
type NetworkTuple struct {
RangeStart uint16
Distance uint8
RangeEnd uint16
// 0x00 for extended tuples
}
func (nt *NetworkTuple) WriteTo(w io.Writer) (int64, error) {
a := acc(w)
a.write16(nt.RangeStart)
if nt.RangeStart == nt.RangeEnd {
// non-extended tuple
a.write8(nt.Distance)
return a.ret()
}
// extended tuple
a.write8(nt.Distance | 0x80)
a.write16(nt.RangeEnd)
a.write8(0x00)
return a.ret()
}
func parseNetworkTuple(p []byte) (NetworkTuple, []byte, error) {
if len(p) < 3 {
return NetworkTuple{}, p, fmt.Errorf("insufficient input length %d for network tuple", len(p))
}
var nt NetworkTuple
nt.RangeStart = binary.BigEndian.Uint16(p[:2])
nt.RangeEnd = nt.RangeStart
nt.Distance = p[2]
if nt.Distance&0x80 == 0 {
return nt, p[3:], nil
}
if len(p) < 6 {
return NetworkTuple{}, p, fmt.Errorf("insufficient input length %d for extended network tuple", len(p))
}
nt.Distance &^= 0x80
nt.RangeEnd = binary.BigEndian.Uint16(p[3:5])
return nt, p[6:], nil
}
type EventTuples []EventTuple
func (e EventTuples) WriteTo(w io.Writer) (int64, error) {
a := acc(w)
for _, et := range e {
a.writeTo(&et)
}
return a.ret()
}
func parseEventTuples(p []byte) (EventTuples, error) {
// Each event tuple is at least 4 bytes, so we need to store at most
// len(p)/4 of them.
e := make(EventTuples, 0, len(p)/4)
for len(p) > 0 {
et, nextp, err := parseEventTuple(p)
if err != nil {
return nil, fmt.Errorf("parsing event tuple %d: %w", len(e), err)
}
e = append(e, et)
p = nextp
}
return e, nil
}
type EventTuple struct {
EventCode EventCode
RangeStart uint16
Distance uint8
RangeEnd uint16
}
func (et *EventTuple) WriteTo(w io.Writer) (int64, error) {
a := acc(w)
a.write8(uint8(et.EventCode))
a.write16(et.RangeStart)
if et.RangeStart == et.RangeEnd {
// non-extended tuple
a.write8(et.Distance)
return a.ret()
}
// extended tuple
a.write8(et.Distance | 0x80)
a.write16(et.RangeEnd)
return a.ret()
}
func parseEventTuple(p []byte) (EventTuple, []byte, error) {
if len(p) < 4 {
return EventTuple{}, p, fmt.Errorf("insufficient input length %d for network event tuple", len(p))
}
var et EventTuple
et.EventCode = EventCode(p[0])
et.RangeStart = binary.BigEndian.Uint16(p[1:3])
et.RangeEnd = et.RangeStart
et.Distance = p[3]
if et.Distance&0x80 == 0 {
return et, p[4:], nil
}
if len(p) < 6 {
return EventTuple{}, p, fmt.Errorf("insufficient input length %d for extended network event tuple", len(p))
}
et.Distance &^= 0x80
et.RangeEnd = binary.BigEndian.Uint16(p[4:6])
return et, p[6:], nil
}
type EventCode uint8
const (
EventCodeNull EventCode = 0
EventCodeNA EventCode = 1
EventCodeND EventCode = 2
EventCodeNRC EventCode = 3
EventCodeNDC EventCode = 4
EventCodeZC EventCode = 5
)