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"
|
||||
)
|
||||
|
||||
// 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,
|
||||
// which includes the domain header.
|
||||
type Header struct {
|
||||
|
@ -86,16 +58,19 @@ const (
|
|||
type RoutingFlag uint16
|
||||
|
||||
const (
|
||||
// Open-Req and RI-Req
|
||||
// Open-Req and RI-Req (SUI flags)
|
||||
RoutingFlagSUINA RoutingFlag = 0x4000
|
||||
RoutingFlagSUINDOrNRC RoutingFlag = 0x2000
|
||||
RoutingFlagSUINDC RoutingFlag = 0x1000
|
||||
RoutingFlagSUIZC RoutingFlag = 0x0800
|
||||
|
||||
// The combination of the above four flags (the SUI flags).
|
||||
RoutingFlagAllSUI RoutingFlag = 0x7800
|
||||
|
||||
// RI-Rsp and GDZL-Rsp
|
||||
RoutingFlagLast RoutingFlag = 0x8000
|
||||
|
||||
// Open-Rsp
|
||||
// Open-Rsp (environment flags)
|
||||
RoutingFlagRemappingActive RoutingFlag = 0x4000
|
||||
RoutingFlagHopCountReduction RoutingFlag = 0x2000
|
||||
RoutingFlagReservedEnv RoutingFlag = 0x1800
|
||||
|
@ -110,20 +85,6 @@ type Packet interface {
|
|||
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
|
||||
// based on the packet type, an AURP-Tr header, an AURP routing header, and
|
||||
// then a particular packet type.
|
||||
|
|
|
@ -13,7 +13,7 @@ type DomainHeader struct {
|
|||
DestinationDI DomainIdentifier
|
||||
SourceDI DomainIdentifier
|
||||
Version uint16 // Should always be 0x0001
|
||||
Reserved uint16
|
||||
Reserved uint16 // Should always be 0x0000
|
||||
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) {
|
||||
p.Sequence = 0
|
||||
p.CommandCode = CmdCodeOpenReq
|
||||
|
||||
a := acc(w)
|
||||
a.writeTo(&p.Header)
|
||||
a.write16(p.Version)
|
||||
|
@ -48,9 +45,6 @@ type OpenRspPacket struct {
|
|||
}
|
||||
|
||||
func (p *OpenRspPacket) WriteTo(w io.Writer) (int64, error) {
|
||||
p.Sequence = 0
|
||||
p.CommandCode = CmdCodeOpenRsp
|
||||
|
||||
a := acc(w)
|
||||
a.writeTo(&p.Header)
|
||||
a.write16(uint16(p.RateOrErrCode))
|
||||
|
|
|
@ -13,8 +13,6 @@ type RDPacket struct {
|
|||
}
|
||||
|
||||
func (p *RDPacket) WriteTo(w io.Writer) (int64, error) {
|
||||
p.CommandCode = CmdCodeRD
|
||||
|
||||
a := acc(w)
|
||||
a.writeTo(&p.Header)
|
||||
a.write16(uint16(p.ErrorCode))
|
||||
|
|
|
@ -10,12 +10,6 @@ type RIReqPacket struct {
|
|||
Header
|
||||
}
|
||||
|
||||
func (p *RIReqPacket) WriteTo(w io.Writer) (int64, error) {
|
||||
p.Sequence = 0
|
||||
p.CommandCode = CmdCodeRIReq
|
||||
return p.Header.WriteTo(w)
|
||||
}
|
||||
|
||||
type RIRspPacket struct {
|
||||
Header
|
||||
|
||||
|
@ -23,8 +17,6 @@ type RIRspPacket struct {
|
|||
}
|
||||
|
||||
func (p *RIRspPacket) WriteTo(w io.Writer) (int64, error) {
|
||||
p.CommandCode = CmdCodeRIRsp
|
||||
|
||||
a := acc(w)
|
||||
a.writeTo(&p.Header)
|
||||
a.writeTo(p.Networks)
|
||||
|
@ -45,11 +37,6 @@ type RIAckPacket struct {
|
|||
Header
|
||||
}
|
||||
|
||||
func (p *RIAckPacket) WriteTo(w io.Writer) (int64, error) {
|
||||
p.CommandCode = CmdCodeRIAck
|
||||
return p.Header.WriteTo(w)
|
||||
}
|
||||
|
||||
type RIUpdPacket struct {
|
||||
Header
|
||||
|
||||
|
@ -57,8 +44,6 @@ type RIUpdPacket struct {
|
|||
}
|
||||
|
||||
func (p *RIUpdPacket) WriteTo(w io.Writer) (int64, error) {
|
||||
p.CommandCode = CmdCodeRIUpd
|
||||
|
||||
a := acc(w)
|
||||
a.writeTo(&p.Header)
|
||||
a.writeTo(p.Events)
|
||||
|
|
|
@ -1,25 +1,9 @@
|
|||
package aurp
|
||||
|
||||
import "io"
|
||||
|
||||
type TicklePacket struct {
|
||||
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 {
|
||||
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) {
|
||||
p.Sequence = 0
|
||||
p.CommandCode = CmdCodeZoneReq
|
||||
p.Flags = 0
|
||||
p.Subcode = SubcodeZoneInfoReq
|
||||
|
||||
a := acc(w)
|
||||
a.writeTo(&p.Header)
|
||||
a.write16(uint16(p.Subcode))
|
||||
|
@ -79,11 +74,6 @@ type ZIRspPacket struct {
|
|||
}
|
||||
|
||||
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.writeTo(&p.Header)
|
||||
a.write16(uint16(p.Subcode))
|
||||
|
@ -109,11 +99,6 @@ type GDZLReqPacket struct {
|
|||
}
|
||||
|
||||
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.writeTo(&p.Header)
|
||||
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.writeTo(&p.Header)
|
||||
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)
|
||||
}
|
||||
|
||||
p.Sequence = 0
|
||||
p.CommandCode = CmdCodeZoneReq
|
||||
p.Flags = 0
|
||||
p.Subcode = SubcodeGetZonesNet
|
||||
|
||||
a := acc(w)
|
||||
a.writeTo(&p.Header)
|
||||
a.write16(uint16(p.Subcode))
|
||||
|
|
Loading…
Reference in a new issue