|
|
@@ -222,12 +222,20 @@ func (spec *compiledSpec) apply(interceptedPacket gopacket.Packet) ([][]byte, er
|
|
|
transformedTCP := *interceptedTCP
|
|
|
var payload gopacket.Payload
|
|
|
setCalculatedField := false
|
|
|
+ fixLengths := true
|
|
|
+ computeChecksums := true
|
|
|
|
|
|
for _, transform := range packetTransformations {
|
|
|
transform.apply(&transformedTCP, &payload)
|
|
|
if transform.setsCalculatedField() {
|
|
|
setCalculatedField = true
|
|
|
}
|
|
|
+ if transform.isDataOffset() {
|
|
|
+ fixLengths = false
|
|
|
+ }
|
|
|
+ if transform.isChecksum() {
|
|
|
+ computeChecksums = false
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
err := transformedTCP.SetNetworkLayerForChecksum(networkLayer)
|
|
|
@@ -238,6 +246,10 @@ func (spec *compiledSpec) apply(interceptedPacket gopacket.Packet) ([][]byte, er
|
|
|
buffer := gopacket.NewSerializeBuffer()
|
|
|
options := gopacket.SerializeOptions{FixLengths: true, ComputeChecksums: true}
|
|
|
|
|
|
+ //warning: first SerializeLayers call may modify transformedTCP, we must copy the TCP DataOffset and Checksum
|
|
|
+ tmpDataOffset := transformedTCP.DataOffset
|
|
|
+ tmpChecksum := transformedTCP.Checksum
|
|
|
+
|
|
|
gopacket.SerializeLayers(
|
|
|
buffer,
|
|
|
options,
|
|
|
@@ -255,10 +267,12 @@ func (spec *compiledSpec) apply(interceptedPacket gopacket.Packet) ([][]byte, er
|
|
|
// from the first round.
|
|
|
|
|
|
if setCalculatedField {
|
|
|
+ transformedTCP.DataOffset = tmpDataOffset
|
|
|
+ transformedTCP.Checksum = tmpChecksum
|
|
|
buffer.Clear()
|
|
|
gopacket.SerializeLayers(
|
|
|
buffer,
|
|
|
- gopacket.SerializeOptions{},
|
|
|
+ gopacket.SerializeOptions{FixLengths: fixLengths, ComputeChecksums: computeChecksums},
|
|
|
serializableNetworkLayer,
|
|
|
&transformedTCP,
|
|
|
payload)
|
|
|
@@ -266,13 +280,14 @@ func (spec *compiledSpec) apply(interceptedPacket gopacket.Packet) ([][]byte, er
|
|
|
|
|
|
packets[i] = buffer.Bytes()
|
|
|
}
|
|
|
-
|
|
|
return packets, nil
|
|
|
}
|
|
|
|
|
|
type transformation interface {
|
|
|
apply(tcp *layers.TCP, payload *gopacket.Payload)
|
|
|
setsCalculatedField() bool
|
|
|
+ isDataOffset() bool
|
|
|
+ isChecksum() bool
|
|
|
}
|
|
|
|
|
|
const (
|
|
|
@@ -392,6 +407,14 @@ func (t *transformationTCPFlags) setsCalculatedField() bool {
|
|
|
return false
|
|
|
}
|
|
|
|
|
|
+func (t *transformationTCPFlags) isDataOffset() bool {
|
|
|
+ return false
|
|
|
+}
|
|
|
+
|
|
|
+func (t *transformationTCPFlags) isChecksum() bool {
|
|
|
+ return false
|
|
|
+}
|
|
|
+
|
|
|
type transformationTCPField struct {
|
|
|
fieldName string
|
|
|
transformationType int
|
|
|
@@ -496,6 +519,14 @@ func (t *transformationTCPField) setsCalculatedField() bool {
|
|
|
return t.fieldName == tcpFieldDataOffset || t.fieldName == tcpFieldChecksum
|
|
|
}
|
|
|
|
|
|
+func (t *transformationTCPField) isDataOffset() bool {
|
|
|
+ return t.fieldName == tcpFieldDataOffset
|
|
|
+}
|
|
|
+
|
|
|
+func (t *transformationTCPField) isChecksum() bool {
|
|
|
+ return t.fieldName == tcpFieldChecksum
|
|
|
+}
|
|
|
+
|
|
|
type transformationTCPOption struct {
|
|
|
optionName string
|
|
|
transformationType int
|
|
|
@@ -710,6 +741,14 @@ func (t *transformationTCPOption) setsCalculatedField() bool {
|
|
|
return false
|
|
|
}
|
|
|
|
|
|
+func (t *transformationTCPOption) isDataOffset() bool {
|
|
|
+ return false
|
|
|
+}
|
|
|
+
|
|
|
+func (t *transformationTCPOption) isChecksum() bool {
|
|
|
+ return false
|
|
|
+}
|
|
|
+
|
|
|
type transformationTCPPayload struct {
|
|
|
transformationType int
|
|
|
value []byte
|
|
|
@@ -767,6 +806,14 @@ func (t *transformationTCPPayload) setsCalculatedField() bool {
|
|
|
return false
|
|
|
}
|
|
|
|
|
|
+func (t *transformationTCPPayload) isDataOffset() bool {
|
|
|
+ return false
|
|
|
+}
|
|
|
+
|
|
|
+func (t *transformationTCPPayload) isChecksum() bool {
|
|
|
+ return false
|
|
|
+}
|
|
|
+
|
|
|
func stripEOLOption(packet gopacket.Packet) {
|
|
|
|
|
|
// gopacket.NewPacket appears to decode padding (0s) as an explicit EOL
|