WIP
This commit is contained in:
parent
b9660caa3d
commit
b43fabc5b6
9 changed files with 123 additions and 110 deletions
17
aurp/atalk.go
Normal file
17
aurp/atalk.go
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
package aurp
|
||||||
|
|
||||||
|
import "io"
|
||||||
|
|
||||||
|
// AppleTalkPacket is for encapsulated AppleTalk traffic.
|
||||||
|
type AppleTalkPacket struct {
|
||||||
|
DomainHeader // where PacketTypeAppleTalk
|
||||||
|
|
||||||
|
Data []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *AppleTalkPacket) WriteTo(w io.Writer) (int64, error) {
|
||||||
|
a := acc(w)
|
||||||
|
a.writeTo(&p.DomainHeader)
|
||||||
|
a.write(p.Data)
|
||||||
|
return a.ret()
|
||||||
|
}
|
49
aurp/aurp.go
49
aurp/aurp.go
|
@ -8,34 +8,6 @@ import (
|
||||||
"io"
|
"io"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TrHeader represent an AURP-Tr packet header. It includes the domain header.
|
|
||||||
type TrHeader struct {
|
|
||||||
DomainHeader
|
|
||||||
|
|
||||||
ConnectionID uint16
|
|
||||||
Sequence uint16 // Note: 65535 is succeeded by 1, not 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// WriteTo writes the encoded form of the header to w, including the domain
|
|
||||||
// header.
|
|
||||||
func (h *TrHeader) WriteTo(w io.Writer) (int64, error) {
|
|
||||||
a := acc(w)
|
|
||||||
a.writeTo(&h.DomainHeader)
|
|
||||||
a.write16(h.ConnectionID)
|
|
||||||
a.write16(h.Sequence)
|
|
||||||
return a.ret()
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseTrHeader(p []byte) (TrHeader, []byte, error) {
|
|
||||||
if len(p) < 4 {
|
|
||||||
return TrHeader{}, p, fmt.Errorf("insufficient input length %d for tr header", len(p))
|
|
||||||
}
|
|
||||||
return TrHeader{
|
|
||||||
ConnectionID: binary.BigEndian.Uint16(p[:2]),
|
|
||||||
Sequence: binary.BigEndian.Uint16(p[2:4]),
|
|
||||||
}, p[4:], nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Header represents an AURP packet header. It includes the AURP-Tr header,
|
// Header represents an AURP packet header. It includes the AURP-Tr header,
|
||||||
// which includes the domain header.
|
// which includes the domain header.
|
||||||
type Header struct {
|
type Header struct {
|
||||||
|
@ -86,16 +58,19 @@ const (
|
||||||
type RoutingFlag uint16
|
type RoutingFlag uint16
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// Open-Req and RI-Req
|
// Open-Req and RI-Req (SUI flags)
|
||||||
RoutingFlagSUINA RoutingFlag = 0x4000
|
RoutingFlagSUINA RoutingFlag = 0x4000
|
||||||
RoutingFlagSUINDOrNRC RoutingFlag = 0x2000
|
RoutingFlagSUINDOrNRC RoutingFlag = 0x2000
|
||||||
RoutingFlagSUINDC RoutingFlag = 0x1000
|
RoutingFlagSUINDC RoutingFlag = 0x1000
|
||||||
RoutingFlagSUIZC RoutingFlag = 0x0800
|
RoutingFlagSUIZC RoutingFlag = 0x0800
|
||||||
|
|
||||||
|
// The combination of the above four flags (the SUI flags).
|
||||||
|
RoutingFlagAllSUI RoutingFlag = 0x7800
|
||||||
|
|
||||||
// RI-Rsp and GDZL-Rsp
|
// RI-Rsp and GDZL-Rsp
|
||||||
RoutingFlagLast RoutingFlag = 0x8000
|
RoutingFlagLast RoutingFlag = 0x8000
|
||||||
|
|
||||||
// Open-Rsp
|
// Open-Rsp (environment flags)
|
||||||
RoutingFlagRemappingActive RoutingFlag = 0x4000
|
RoutingFlagRemappingActive RoutingFlag = 0x4000
|
||||||
RoutingFlagHopCountReduction RoutingFlag = 0x2000
|
RoutingFlagHopCountReduction RoutingFlag = 0x2000
|
||||||
RoutingFlagReservedEnv RoutingFlag = 0x1800
|
RoutingFlagReservedEnv RoutingFlag = 0x1800
|
||||||
|
@ -110,20 +85,6 @@ type Packet interface {
|
||||||
io.WriterTo
|
io.WriterTo
|
||||||
}
|
}
|
||||||
|
|
||||||
// AppleTalkPacket is for encapsulated AppleTalk traffic.
|
|
||||||
type AppleTalkPacket struct {
|
|
||||||
DomainHeader // where PacketTypeAppleTalk
|
|
||||||
|
|
||||||
Data []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *AppleTalkPacket) WriteTo(w io.Writer) (int64, error) {
|
|
||||||
a := acc(w)
|
|
||||||
a.writeTo(&p.DomainHeader)
|
|
||||||
a.write(p.Data)
|
|
||||||
return a.ret()
|
|
||||||
}
|
|
||||||
|
|
||||||
// ParsePacket parses the body of a UDP packet for a domain header, and then
|
// ParsePacket parses the body of a UDP packet for a domain header, and then
|
||||||
// based on the packet type, an AURP-Tr header, an AURP routing header, and
|
// based on the packet type, an AURP-Tr header, an AURP routing header, and
|
||||||
// then a particular packet type.
|
// then a particular packet type.
|
||||||
|
|
|
@ -13,7 +13,7 @@ type DomainHeader struct {
|
||||||
DestinationDI DomainIdentifier
|
DestinationDI DomainIdentifier
|
||||||
SourceDI DomainIdentifier
|
SourceDI DomainIdentifier
|
||||||
Version uint16 // Should always be 0x0001
|
Version uint16 // Should always be 0x0001
|
||||||
Reserved uint16
|
Reserved uint16 // Should always be 0x0000
|
||||||
PacketType PacketType // 2 = AppleTalk data packet, 3 = AURP packet
|
PacketType PacketType // 2 = AppleTalk data packet, 3 = AURP packet
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,9 +15,6 @@ type OpenReqPacket struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *OpenReqPacket) WriteTo(w io.Writer) (int64, error) {
|
func (p *OpenReqPacket) WriteTo(w io.Writer) (int64, error) {
|
||||||
p.Sequence = 0
|
|
||||||
p.CommandCode = CmdCodeOpenReq
|
|
||||||
|
|
||||||
a := acc(w)
|
a := acc(w)
|
||||||
a.writeTo(&p.Header)
|
a.writeTo(&p.Header)
|
||||||
a.write16(p.Version)
|
a.write16(p.Version)
|
||||||
|
@ -48,9 +45,6 @@ type OpenRspPacket struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *OpenRspPacket) WriteTo(w io.Writer) (int64, error) {
|
func (p *OpenRspPacket) WriteTo(w io.Writer) (int64, error) {
|
||||||
p.Sequence = 0
|
|
||||||
p.CommandCode = CmdCodeOpenRsp
|
|
||||||
|
|
||||||
a := acc(w)
|
a := acc(w)
|
||||||
a.writeTo(&p.Header)
|
a.writeTo(&p.Header)
|
||||||
a.write16(uint16(p.RateOrErrCode))
|
a.write16(uint16(p.RateOrErrCode))
|
||||||
|
|
|
@ -13,8 +13,6 @@ type RDPacket struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *RDPacket) WriteTo(w io.Writer) (int64, error) {
|
func (p *RDPacket) WriteTo(w io.Writer) (int64, error) {
|
||||||
p.CommandCode = CmdCodeRD
|
|
||||||
|
|
||||||
a := acc(w)
|
a := acc(w)
|
||||||
a.writeTo(&p.Header)
|
a.writeTo(&p.Header)
|
||||||
a.write16(uint16(p.ErrorCode))
|
a.write16(uint16(p.ErrorCode))
|
||||||
|
|
|
@ -10,12 +10,6 @@ type RIReqPacket struct {
|
||||||
Header
|
Header
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *RIReqPacket) WriteTo(w io.Writer) (int64, error) {
|
|
||||||
p.Sequence = 0
|
|
||||||
p.CommandCode = CmdCodeRIReq
|
|
||||||
return p.Header.WriteTo(w)
|
|
||||||
}
|
|
||||||
|
|
||||||
type RIRspPacket struct {
|
type RIRspPacket struct {
|
||||||
Header
|
Header
|
||||||
|
|
||||||
|
@ -23,8 +17,6 @@ type RIRspPacket struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *RIRspPacket) WriteTo(w io.Writer) (int64, error) {
|
func (p *RIRspPacket) WriteTo(w io.Writer) (int64, error) {
|
||||||
p.CommandCode = CmdCodeRIRsp
|
|
||||||
|
|
||||||
a := acc(w)
|
a := acc(w)
|
||||||
a.writeTo(&p.Header)
|
a.writeTo(&p.Header)
|
||||||
a.writeTo(p.Networks)
|
a.writeTo(p.Networks)
|
||||||
|
@ -45,11 +37,6 @@ type RIAckPacket struct {
|
||||||
Header
|
Header
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *RIAckPacket) WriteTo(w io.Writer) (int64, error) {
|
|
||||||
p.CommandCode = CmdCodeRIAck
|
|
||||||
return p.Header.WriteTo(w)
|
|
||||||
}
|
|
||||||
|
|
||||||
type RIUpdPacket struct {
|
type RIUpdPacket struct {
|
||||||
Header
|
Header
|
||||||
|
|
||||||
|
@ -57,8 +44,6 @@ type RIUpdPacket struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *RIUpdPacket) WriteTo(w io.Writer) (int64, error) {
|
func (p *RIUpdPacket) WriteTo(w io.Writer) (int64, error) {
|
||||||
p.CommandCode = CmdCodeRIUpd
|
|
||||||
|
|
||||||
a := acc(w)
|
a := acc(w)
|
||||||
a.writeTo(&p.Header)
|
a.writeTo(&p.Header)
|
||||||
a.writeTo(p.Events)
|
a.writeTo(p.Events)
|
||||||
|
|
|
@ -1,25 +1,9 @@
|
||||||
package aurp
|
package aurp
|
||||||
|
|
||||||
import "io"
|
|
||||||
|
|
||||||
type TicklePacket struct {
|
type TicklePacket struct {
|
||||||
Header
|
Header
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *TicklePacket) WriteTo(w io.Writer) (int64, error) {
|
|
||||||
p.Sequence = 0
|
|
||||||
p.CommandCode = CmdCodeTickle
|
|
||||||
p.Flags = 0
|
|
||||||
return p.Header.WriteTo(w)
|
|
||||||
}
|
|
||||||
|
|
||||||
type TickleAckPacket struct {
|
type TickleAckPacket struct {
|
||||||
Header
|
Header
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *TickleAckPacket) WriteTo(w io.Writer) (int64, error) {
|
|
||||||
p.Sequence = 0
|
|
||||||
p.CommandCode = CmdCodeTickleAck
|
|
||||||
p.Flags = 0
|
|
||||||
return p.Header.WriteTo(w)
|
|
||||||
}
|
|
||||||
|
|
99
aurp/transport.go
Normal file
99
aurp/transport.go
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
package aurp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TrHeader represent an AURP-Tr packet header. It includes the domain header.
|
||||||
|
type TrHeader struct {
|
||||||
|
DomainHeader
|
||||||
|
|
||||||
|
ConnectionID uint16
|
||||||
|
Sequence uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteTo writes the encoded form of the header to w, including the domain
|
||||||
|
// header.
|
||||||
|
func (h *TrHeader) WriteTo(w io.Writer) (int64, error) {
|
||||||
|
a := acc(w)
|
||||||
|
a.writeTo(&h.DomainHeader)
|
||||||
|
a.write16(h.ConnectionID)
|
||||||
|
a.write16(h.Sequence)
|
||||||
|
return a.ret()
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseTrHeader(p []byte) (TrHeader, []byte, error) {
|
||||||
|
if len(p) < 4 {
|
||||||
|
return TrHeader{}, p, fmt.Errorf("insufficient input length %d for tr header", len(p))
|
||||||
|
}
|
||||||
|
return TrHeader{
|
||||||
|
ConnectionID: binary.BigEndian.Uint16(p[:2]),
|
||||||
|
Sequence: binary.BigEndian.Uint16(p[2:4]),
|
||||||
|
}, p[4:], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// incSequence increments the sequence number.
|
||||||
|
// Note that 0 is special and 65535+1 = 1, according to AURP.
|
||||||
|
func (tr *TrHeader) incSequence() {
|
||||||
|
tr.Sequence++
|
||||||
|
if tr.Sequence == 0 {
|
||||||
|
tr.Sequence = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// transaction returns a new TrHeader based on this one, usable for transaction
|
||||||
|
// requests or responses.
|
||||||
|
func (tr *TrHeader) transaction() TrHeader {
|
||||||
|
return TrHeader{
|
||||||
|
DomainHeader: DomainHeader{
|
||||||
|
DestinationDI: tr.DestinationDI,
|
||||||
|
SourceDI: tr.SourceDI,
|
||||||
|
Version: 1,
|
||||||
|
Reserved: 0,
|
||||||
|
PacketType: PacketTypeRouting,
|
||||||
|
},
|
||||||
|
ConnectionID: tr.ConnectionID,
|
||||||
|
Sequence: 0, // Transaction packets all use sequence number 0.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DataSender is used to track sender state in a one-way AURP connection.
|
||||||
|
// Note that both data senders and data recievers can send packets.
|
||||||
|
type DataSender struct {
|
||||||
|
TrHeader
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewOpenRspPacket returns a new Open-Rsp packet structure.
|
||||||
|
func (ds *DataSender) NewOpenRspPacket(envFlags RoutingFlag, rateOrErr int16, opts Options) *OpenRspPacket {
|
||||||
|
return &OpenRspPacket{
|
||||||
|
Header: Header{
|
||||||
|
TrHeader: ds.transaction(),
|
||||||
|
CommandCode: CmdCodeOpenRsp,
|
||||||
|
Flags: envFlags,
|
||||||
|
},
|
||||||
|
RateOrErrCode: rateOrErr,
|
||||||
|
Options: opts,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DataReceiver is used to track reciever state in a one-way AURP connection.
|
||||||
|
// Note that both data senders and data recievers can send packets.
|
||||||
|
type DataReceiver struct {
|
||||||
|
TrHeader
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewOpenReqPacket returns a new Open-Req packet structure. By default it sets
|
||||||
|
// all SUI flags and uses version 1.
|
||||||
|
func (dr *DataReceiver) NewOpenReqPacket(opts Options) *OpenReqPacket {
|
||||||
|
return &OpenReqPacket{
|
||||||
|
Header: Header{
|
||||||
|
TrHeader: dr.transaction(),
|
||||||
|
CommandCode: CmdCodeOpenReq,
|
||||||
|
Flags: RoutingFlagAllSUI,
|
||||||
|
},
|
||||||
|
Version: 1,
|
||||||
|
Options: opts,
|
||||||
|
}
|
||||||
|
}
|
|
@ -32,11 +32,6 @@ type ZIReqPacket struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *ZIReqPacket) WriteTo(w io.Writer) (int64, error) {
|
func (p *ZIReqPacket) WriteTo(w io.Writer) (int64, error) {
|
||||||
p.Sequence = 0
|
|
||||||
p.CommandCode = CmdCodeZoneReq
|
|
||||||
p.Flags = 0
|
|
||||||
p.Subcode = SubcodeZoneInfoReq
|
|
||||||
|
|
||||||
a := acc(w)
|
a := acc(w)
|
||||||
a.writeTo(&p.Header)
|
a.writeTo(&p.Header)
|
||||||
a.write16(uint16(p.Subcode))
|
a.write16(uint16(p.Subcode))
|
||||||
|
@ -79,11 +74,6 @@ type ZIRspPacket struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *ZIRspPacket) WriteTo(w io.Writer) (int64, error) {
|
func (p *ZIRspPacket) WriteTo(w io.Writer) (int64, error) {
|
||||||
p.Sequence = 0
|
|
||||||
p.CommandCode = CmdCodeZoneRsp
|
|
||||||
p.Flags = 0
|
|
||||||
// Subcode can vary for this packet type: it's either 1 or 2
|
|
||||||
|
|
||||||
a := acc(w)
|
a := acc(w)
|
||||||
a.writeTo(&p.Header)
|
a.writeTo(&p.Header)
|
||||||
a.write16(uint16(p.Subcode))
|
a.write16(uint16(p.Subcode))
|
||||||
|
@ -109,11 +99,6 @@ type GDZLReqPacket struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *GDZLReqPacket) WriteTo(w io.Writer) (int64, error) {
|
func (p *GDZLReqPacket) WriteTo(w io.Writer) (int64, error) {
|
||||||
p.Sequence = 0
|
|
||||||
p.CommandCode = CmdCodeZoneReq
|
|
||||||
p.Flags = 0
|
|
||||||
p.Subcode = SubcodeGetDomainZoneList
|
|
||||||
|
|
||||||
a := acc(w)
|
a := acc(w)
|
||||||
a.writeTo(&p.Header)
|
a.writeTo(&p.Header)
|
||||||
a.write16(uint16(p.Subcode))
|
a.write16(uint16(p.Subcode))
|
||||||
|
@ -145,11 +130,6 @@ func (p *GDZLRspPacket) WriteTo(w io.Writer) (int64, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
p.Sequence = 0
|
|
||||||
p.CommandCode = CmdCodeZoneRsp
|
|
||||||
// Flags is used to distinguish the final response packet, so leave alone
|
|
||||||
p.Subcode = SubcodeGetDomainZoneList
|
|
||||||
|
|
||||||
a := acc(w)
|
a := acc(w)
|
||||||
a.writeTo(&p.Header)
|
a.writeTo(&p.Header)
|
||||||
a.write16(uint16(p.Subcode))
|
a.write16(uint16(p.Subcode))
|
||||||
|
@ -207,11 +187,6 @@ func (p *GZNReqPacket) WriteTo(w io.Writer) (int64, error) {
|
||||||
return 0, fmt.Errorf("zone name %q too long", p.ZoneName)
|
return 0, fmt.Errorf("zone name %q too long", p.ZoneName)
|
||||||
}
|
}
|
||||||
|
|
||||||
p.Sequence = 0
|
|
||||||
p.CommandCode = CmdCodeZoneReq
|
|
||||||
p.Flags = 0
|
|
||||||
p.Subcode = SubcodeGetZonesNet
|
|
||||||
|
|
||||||
a := acc(w)
|
a := acc(w)
|
||||||
a.writeTo(&p.Header)
|
a.writeTo(&p.Header)
|
||||||
a.write16(uint16(p.Subcode))
|
a.write16(uint16(p.Subcode))
|
||||||
|
|
Loading…
Reference in a new issue