-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathsegment.go
130 lines (100 loc) · 2.7 KB
/
segment.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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package go_cip
import (
"bytes"
eip "github.com/loki-os/go-ethernet-ip"
"github.com/loki-os/go-ethernet-ip/typedef"
)
type SegmentType typedef.Usint
const (
SegmentTypePort SegmentType = 0 << 5
SegmentTypeLogical SegmentType = 1 << 5
SegmentTypeNetwork SegmentType = 2 << 5
SegmentTypeSymbolic SegmentType = 3 << 5
SegmentTypeData SegmentType = 4 << 5
SegmentTypeDataType1 SegmentType = 5 << 5
SegmentTypeDataType2 SegmentType = 6 << 5
)
func Paths(arg ...[]byte) []byte {
buffer := new(bytes.Buffer)
for i := 0; i < len(arg); i++ {
eip.WriteByte(buffer, arg[i])
}
return buffer.Bytes()
}
type DataTypes typedef.Usint
const (
DataTypeSimple DataTypes = 0x0
DataTypeANSI DataTypes = 0x11
)
type LogicalType typedef.Usint
const (
LogicalTypeClassID LogicalType = 0 << 2
LogicalTypeInstanceID LogicalType = 1 << 2
LogicalTypeMemberID LogicalType = 2 << 2
LogicalTypeConnPoint LogicalType = 3 << 2
LogicalTypeAttributeID LogicalType = 4 << 2
LogicalTypeSpecial LogicalType = 5 << 2
LogicalTypeServiceID LogicalType = 6 << 2
)
func DataBuild(tp DataTypes, data []byte, padded bool) []byte {
buffer := new(bytes.Buffer)
firstByte := uint8(SegmentTypeData) | uint8(tp)
eip.WriteByte(buffer, firstByte)
length := uint8(len(data))
eip.WriteByte(buffer, length)
eip.WriteByte(buffer, data)
if padded && buffer.Len()%2 == 1 {
eip.WriteByte(buffer, uint8(0))
}
return buffer.Bytes()
}
func LogicalBuild(tp LogicalType, address uint32, padded bool) []byte {
format := uint8(0)
if address <= 255 {
format = 0
} else if address > 255 && address <= 65535 {
format = 1
} else {
format = 2
}
buffer := new(bytes.Buffer)
firstByte := uint8(SegmentTypeLogical) | uint8(tp) | format
eip.WriteByte(buffer, firstByte)
if address > 255 && address <= 65535 && padded {
eip.WriteByte(buffer, uint8(0))
}
if address <= 255 {
eip.WriteByte(buffer, uint8(address))
} else if address > 255 && address <= 65535 {
eip.WriteByte(buffer, uint16(address))
} else {
eip.WriteByte(buffer, address)
}
return buffer.Bytes()
}
func PortBuild(link []byte, portID uint16, padded bool) []byte {
extendedLinkTag := len(link) > 1
extendedPortTag := !(portID < 15)
buffer := new(bytes.Buffer)
firstByte := uint8(SegmentTypePort)
if extendedLinkTag {
firstByte = firstByte | 0x10
}
if !extendedPortTag {
firstByte = firstByte | uint8(portID)
} else {
firstByte = firstByte | 0xf
}
eip.WriteByte(buffer, firstByte)
if extendedLinkTag {
eip.WriteByte(buffer, uint8(len(link)))
}
if extendedPortTag {
eip.WriteByte(buffer, portID)
}
eip.WriteByte(buffer, link)
if padded && buffer.Len()%2 == 1 {
eip.WriteByte(buffer, uint8(0))
}
return buffer.Bytes()
}