forked from platinasystems/vnet
-
Notifications
You must be signed in to change notification settings - Fork 0
/
header.go
90 lines (70 loc) · 2.17 KB
/
header.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
// Copyright 2016 Platina Systems, Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package vnet
import (
"github.com/platinasystems/elib/parse"
"fmt"
"unsafe"
)
type Layer interface {
ParseLayer(b []byte, in *parse.Input) uint
FormatLayer(b []byte) []string
}
type PacketHeader interface {
// Number of packet bytes in this header's payload.
Len() uint
// Write this header's packet data to given slice.
Write([]byte)
// Return given slice as packet header type.
Read([]byte) PacketHeader
String() string
}
func Pointer(b []byte) unsafe.Pointer { return unsafe.Pointer(&b[0]) }
func MakePacket(args ...PacketHeader) (b []byte) {
na := len(args)
// Find total length of packet.
l := uint(0)
for _, a := range args {
l += a.Len()
}
// Allocate buffer.
b = make([]byte, l)
// Write packet from innermost header to outermost.
k := uint(0)
for i := 0; i < na; i++ {
a := args[na-1-i]
k += a.Len()
a.Write(b[l-k:])
}
return
}
func ReadPacket(b []byte, args ...PacketHeader) (hs []PacketHeader) {
i := uint(0)
for a := range args {
l := args[a]
hs = append(hs, l.Read(b[i:]))
i += l.Len()
}
return hs
}
// Packet header with incrementing data of given byte count.
type IncrementingPayload struct{ Count uint }
func (i *IncrementingPayload) Len() uint { return i.Count }
func (i *IncrementingPayload) Finalize(l []PacketHeader) {}
func (i *IncrementingPayload) String() string { return fmt.Sprintf("incrementing %d", i.Count) }
func (i *IncrementingPayload) Write(b []byte) {
for j := uint(0); j < i.Count; j++ {
b[j] = byte(j % 256)
}
}
func (i *IncrementingPayload) Read(b []byte) PacketHeader { return i }
// Header for a given fixed payload.
type GivenPayload struct{ Payload []byte }
func (i *GivenPayload) Len() uint { return uint(len(i.Payload)) }
func (i *GivenPayload) Finalize(l []PacketHeader) {}
func (i *GivenPayload) String() string { return fmt.Sprintf("payload %x", i.Payload) }
func (i *GivenPayload) Write(b []byte) {
copy(b[:], i.Payload)
}
func (i *GivenPayload) Read(b []byte) PacketHeader { return i }