Skip to content

Commit 04f6565

Browse files
committed
parser: implement DecodeLayerContainer
Changes: * add DecodingLayerContainer to contain/search DecodingLayer values: * add DecodingLayerFunc type as a decoder closure; * add DecodingLayerMap, DecodingLayerSparse, DecodingLayerArray as implementations of DecodingLayerContainer; * add code generation for the reference LayersDecoder method implementation. * refactor DecodingLayerParser: * use DecodingLayerMap by default; * add SetDecodingLayerContainer method to initialize parser. Signed-off-by: Yerden Zhumabekov <[email protected]>
1 parent 72ef6fb commit 04f6565

File tree

3 files changed

+345
-26
lines changed

3 files changed

+345
-26
lines changed

gen.go

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// Copyright 2019 The GoPacket Authors. All rights reserved.
2+
//
3+
// Use of this source code is governed by a BSD-style license
4+
// that can be found in the LICENSE file in the root of the source
5+
// tree.
6+
7+
// +build ignore
8+
9+
// This file generates LayersDecoder function for DecodingLayerContainer
10+
// go run gen.go | gofmt > layers_decoder.go
11+
package main
12+
13+
import (
14+
"fmt"
15+
"os"
16+
"time"
17+
)
18+
19+
const headerFmt = `// Copyright 2019 The GoPacket Authors. All rights reserved.
20+
21+
package gopacket
22+
23+
// Created by gen.go, don't edit manually
24+
// Generated at %s
25+
26+
// LayersDecoder returns DecodingLayerFunc for specified
27+
// DecodingLayerContainer, LayerType value to start decoding with and
28+
// some DecodeFeedback.
29+
func LayersDecoder(dl DecodingLayerContainer, first LayerType, df DecodeFeedback) DecodingLayerFunc {
30+
firstDec, ok := dl.Decoder(first)
31+
if !ok {
32+
return func([]byte, *[]LayerType) (LayerType, error) {
33+
return first, nil
34+
}
35+
}
36+
`
37+
38+
var funcBody = `return func(data []byte, decoded *[]LayerType) (LayerType, error) {
39+
*decoded = (*decoded)[:0] // Truncated decoded layers.
40+
typ := first
41+
decoder := firstDec
42+
for {
43+
if err := decoder.DecodeFromBytes(data, df); err != nil {
44+
return LayerTypeZero, err
45+
}
46+
*decoded = append(*decoded, typ)
47+
typ = decoder.NextLayerType()
48+
if data = decoder.LayerPayload(); len(data) == 0 {
49+
break
50+
}
51+
if decoder, ok = dlc.Decoder(typ); !ok {
52+
return typ, nil
53+
}
54+
}
55+
return LayerTypeZero, nil
56+
}`
57+
58+
func main() {
59+
fmt.Fprintf(os.Stderr, "Writing results to stdout\n")
60+
types := []string{
61+
"DecodingLayerSparse",
62+
"DecodingLayerArray",
63+
"DecodingLayerMap",
64+
}
65+
66+
fmt.Printf(headerFmt, time.Now())
67+
for _, t := range types {
68+
fmt.Printf("if dlc, ok := dl.(%s); ok {", t)
69+
fmt.Println(funcBody)
70+
fmt.Println("}")
71+
}
72+
fmt.Println("dlc := dl")
73+
fmt.Println(funcBody)
74+
fmt.Println("}")
75+
}

layers_decoder.go

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
// Copyright 2019 The GoPacket Authors. All rights reserved.
2+
3+
package gopacket
4+
5+
// Created by gen.go, don't edit manually
6+
// Generated at 2019-06-18 11:37:31.308731293 +0600 +06 m=+0.000842599
7+
8+
// LayersDecoder returns DecodingLayerFunc for specified
9+
// DecodingLayerContainer, LayerType value to start decoding with and
10+
// some DecodeFeedback.
11+
func LayersDecoder(dl DecodingLayerContainer, first LayerType, df DecodeFeedback) DecodingLayerFunc {
12+
firstDec, ok := dl.Decoder(first)
13+
if !ok {
14+
return func([]byte, *[]LayerType) (LayerType, error) {
15+
return first, nil
16+
}
17+
}
18+
if dlc, ok := dl.(DecodingLayerSparse); ok {
19+
return func(data []byte, decoded *[]LayerType) (LayerType, error) {
20+
*decoded = (*decoded)[:0] // Truncated decoded layers.
21+
typ := first
22+
decoder := firstDec
23+
for {
24+
if err := decoder.DecodeFromBytes(data, df); err != nil {
25+
return LayerTypeZero, err
26+
}
27+
*decoded = append(*decoded, typ)
28+
typ = decoder.NextLayerType()
29+
if data = decoder.LayerPayload(); len(data) == 0 {
30+
break
31+
}
32+
if decoder, ok = dlc.Decoder(typ); !ok {
33+
return typ, nil
34+
}
35+
}
36+
return LayerTypeZero, nil
37+
}
38+
}
39+
if dlc, ok := dl.(DecodingLayerArray); ok {
40+
return func(data []byte, decoded *[]LayerType) (LayerType, error) {
41+
*decoded = (*decoded)[:0] // Truncated decoded layers.
42+
typ := first
43+
decoder := firstDec
44+
for {
45+
if err := decoder.DecodeFromBytes(data, df); err != nil {
46+
return LayerTypeZero, err
47+
}
48+
*decoded = append(*decoded, typ)
49+
typ = decoder.NextLayerType()
50+
if data = decoder.LayerPayload(); len(data) == 0 {
51+
break
52+
}
53+
if decoder, ok = dlc.Decoder(typ); !ok {
54+
return typ, nil
55+
}
56+
}
57+
return LayerTypeZero, nil
58+
}
59+
}
60+
if dlc, ok := dl.(DecodingLayerMap); ok {
61+
return func(data []byte, decoded *[]LayerType) (LayerType, error) {
62+
*decoded = (*decoded)[:0] // Truncated decoded layers.
63+
typ := first
64+
decoder := firstDec
65+
for {
66+
if err := decoder.DecodeFromBytes(data, df); err != nil {
67+
return LayerTypeZero, err
68+
}
69+
*decoded = append(*decoded, typ)
70+
typ = decoder.NextLayerType()
71+
if data = decoder.LayerPayload(); len(data) == 0 {
72+
break
73+
}
74+
if decoder, ok = dlc.Decoder(typ); !ok {
75+
return typ, nil
76+
}
77+
}
78+
return LayerTypeZero, nil
79+
}
80+
}
81+
dlc := dl
82+
return func(data []byte, decoded *[]LayerType) (LayerType, error) {
83+
*decoded = (*decoded)[:0] // Truncated decoded layers.
84+
typ := first
85+
decoder := firstDec
86+
for {
87+
if err := decoder.DecodeFromBytes(data, df); err != nil {
88+
return LayerTypeZero, err
89+
}
90+
*decoded = append(*decoded, typ)
91+
typ = decoder.NextLayerType()
92+
if data = decoder.LayerPayload(); len(data) == 0 {
93+
break
94+
}
95+
if decoder, ok = dlc.Decoder(typ); !ok {
96+
return typ, nil
97+
}
98+
}
99+
return LayerTypeZero, nil
100+
}
101+
}

0 commit comments

Comments
 (0)