diff options
author | Christian Pointner <equinox@anytun.org> | 2017-09-02 03:24:41 +0200 |
---|---|---|
committer | Christian Pointner <equinox@anytun.org> | 2017-09-02 03:24:41 +0200 |
commit | 10212b0f9e7c5b2e3166d927cadbc4824f494bd3 (patch) | |
tree | 744951c3f1ae6b30b58d5432959c0ac33313f88d /satp/packet.go | |
parent | make interface config more modular (diff) |
addes first simple satp packets
Diffstat (limited to 'satp/packet.go')
-rw-r--r-- | satp/packet.go | 146 |
1 files changed, 146 insertions, 0 deletions
diff --git a/satp/packet.go b/satp/packet.go new file mode 100644 index 0000000..a24b69a --- /dev/null +++ b/satp/packet.go @@ -0,0 +1,146 @@ +// +// Copyright (c) 2017 anygone contributors (see AUTHORS file) +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * Neither the name of anygone nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// + +package satp + +import ( + "bytes" + "encoding/binary" + "errors" +) + +// 0 1 2 3 +// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | sequence number | | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +// | sender ID | MUX | | +// +#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+ | +// | | payload type | | | +// | +-------------------------------+ | | +// | | .... payload ... | | +// | | +-------------------------------+ | +// | | | padding (OPT) | pad count(OPT)| | +// +#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+-+ +// | : authentication tag (RECOMMENDED) : | +// | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +// | | +// +- Encrypted Portion Authenticated Portion ---+ + +type PlainPacket struct { + Type uint16 + Payload []byte +} + +func NewPlainPacket(PayloadType uint16) (pp *PlainPacket) { + pp = &PlainPacket{} + pp.Type = PayloadType + return +} + +func (pp *PlainPacket) MarshalBinary() (data []byte, err error) { + buf := &bytes.Buffer{} + if err = binary.Write(buf, binary.BigEndian, pp.Type); err != nil { + return + } + buf.Write(pp.Payload) // returned error is always nil + return buf.Bytes(), nil +} + +func (pp *PlainPacket) UnmarshalBinary(data []byte) (err error) { + buf := bytes.NewReader(data) + if err = binary.Read(buf, binary.BigEndian, &(pp.Type)); err != nil { + return + } + if buf.Len() > 0 { + pp.Payload = make([]byte, buf.Len()) + buf.Read(pp.Payload) + } + return +} + +type EncryptedPacket struct { + SequenceNumber uint32 + SenderID uint16 + Mux uint16 + Payload []byte + AuthTag []byte +} + +func NewEncryptedPacket(AuthTagLength uint) (ep *EncryptedPacket) { + ep = &EncryptedPacket{} + ep.AuthTag = make([]byte, AuthTagLength) + return +} + +func (ep *EncryptedPacket) MarshalBinary() (data []byte, err error) { + buf := &bytes.Buffer{} + if err = binary.Write(buf, binary.BigEndian, ep.SequenceNumber); err != nil { + return + } + if err = binary.Write(buf, binary.BigEndian, ep.SenderID); err != nil { + return + } + if err = binary.Write(buf, binary.BigEndian, ep.Mux); err != nil { + return + } + if len(ep.Payload) >= 2 { // Payload must at least have a payload type which is a uint16 -> 2 bytes + buf.Write(ep.Payload) // returned error is always nil + } else { + return nil, errors.New("Unable to marshal packet: payload is empty/too short") + } + + if len(ep.AuthTag) > 0 { + buf.Write(ep.AuthTag) // returned error is always nil + } + return buf.Bytes(), nil +} + +func (ep *EncryptedPacket) UnmarshalBinary(data []byte) (err error) { + buf := bytes.NewReader(data) + if err = binary.Read(buf, binary.BigEndian, &(ep.SequenceNumber)); err != nil { + return + } + if err = binary.Read(buf, binary.BigEndian, &(ep.SenderID)); err != nil { + return + } + if err = binary.Read(buf, binary.BigEndian, &(ep.Mux)); err != nil { + return + } + + if (buf.Len() - len(ep.AuthTag)) < 2 { // 2 bytes payload type + length of AuthTag must be left on buffer + return errors.New("Unable to unmarshal packet: too short") + } + + ep.Payload = make([]byte, buf.Len()-len(ep.AuthTag)) + buf.Read(ep.Payload) + buf.Read(ep.AuthTag) + return +} |