diff --git a/hack/packetgen/templates/decode.tmpl b/hack/packetgen/templates/decode.tmpl
index b06b0f5542c41191ce08d2d8fd59367eb8412a54..2a0b2cd336208abe1164aecb0579ade1702d24b6 100644
--- a/hack/packetgen/templates/decode.tmpl
+++ b/hack/packetgen/templates/decode.tmpl
@@ -1,117 +1,137 @@
 {{$name := index . 0 -}}
-{{$value := index . 1 -}}
+{{$pointer := index . 1 -}}
+{{$value := index . 2 -}}
 
 {{if some $value.Map -}}
-	err = {{$name}}.ReadFrom(decoder)
+	{{$prefixPointer := temp -}}
+
+	var {{$prefixPointer}} {{template "type" (list $name $value.Map.Prefix)}}
+
+	{{template "decode" (list $name $prefixPointer $value.Map.Prefix)}}
+
+	switch {{$prefixPointer}} {
+	{{range $n, $item := $value.Map.Items -}}
+        {{$itemName := printf "%s%s" $name $n -}}
+
+		case {{$item.Type}}:
+			{{$pointer}} = new({{$itemName}})
+	{{end -}}
+	}
+
+	err = {{$pointer}}.ReadFrom(decoder)
 	if err != nil {
 		return
 	}
 {{else if some $value.Remaining -}}
-	{{$name}} = {{$name}}[:0]
+	{{$pointer}} = {{$pointer}}[:0]
 
 	for {
 		if decoder.Position() >= decoder.Length() {
 			break
 		}
 
-		{{$name}} = slices.Resize({{$name}}, len({{$name}})+1)
+		{{$pointer}} = slices.Resize({{$pointer}}, len({{$pointer}})+1)
 
-		{{$targetName := printf "%s[len(%s)-1]" $name $name -}}
+		{{$targetPointer := printf "%s[len(%s)-1]" $pointer $pointer -}}
 
-		{{template "decode" (list $targetName $value.Remaining)}}
+		{{template "decode" (list $name $targetPointer $value.Remaining)}}
 	}
 {{else if some $value.Basic -}}
-	*(*{{$value.Basic}})(&({{$name}})), err = decoder.{{upperCamel $value.Basic}}()
+	*(*{{$value.Basic}})(&({{$pointer}})), err = decoder.{{upperCamel $value.Basic}}()
 	if err != nil {
 		return
 	}
 {{else if some $value.Array -}}
-	{{$indexName := temp -}}
+	{{$indexPointer := temp -}}
 
-	for {{$indexName}} := 0; {{$indexName}} < {{$value.Array.Length}}; {{$indexName}}++ {
-		{{$targetName := printf "%s[%s]" $name $indexName -}}
+	for {{$indexPointer}} := 0; {{$indexPointer}} < {{$value.Array.Length}}; {{$indexPointer}}++ {
+		{{$targetPointer := printf "%s[%s]" $pointer $indexPointer -}}
 
-		{{template "decode" (list $targetName $value.Array)}}
+		{{template "decode" (list $name $targetPointer $value.Array)}}
 	}
 {{else if some $value.Struct -}}
+	{{$structName := printf "%s%s" $name $value.Struct.Name -}}
+
 	{{range $field := $value.Struct.Fields -}}
-        {{$fieldName := printf "%s.%s" $name $field.Name -}}
+        {{$fieldPointer := printf "%s.%s" $pointer $field.Name -}}
 
-		{{template "decode" (list $fieldName $field) -}}
+		{{template "decode" (list $structName $fieldPointer $field) -}}
 	{{end -}}
 {{else if some $value.LengthPrefixedSlice -}}
-	{{$lengthName := temp -}}
+	{{$lengthPointer := temp -}}
 
-	var {{$lengthName}} {{template "type" (list "" $value.LengthPrefixedSlice.Prefix)}}
-	{{template "decode" (list $lengthName $value.LengthPrefixedSlice.Prefix)}}
+	var {{$lengthPointer}} {{template "type" (list $name $value.LengthPrefixedSlice.Prefix)}}
+	{{template "decode" (list $name $lengthPointer $value.LengthPrefixedSlice.Prefix)}}
 
-	{{$name}} = slices.Resize({{$name}}, int({{$lengthName}}))
+	{{$pointer}} = slices.Resize({{$pointer}}, int({{$lengthPointer}}))
 
-	{{$indexName := temp -}}
+	{{$indexPointer := temp -}}
 
-	for {{$indexName}} := 0; {{$indexName}} < int({{$lengthName}}); {{$indexName}}++ {
-		{{$targetName := printf "%s[%s]" $name $indexName -}}
+	for {{$indexPointer}} := 0; {{$indexPointer}} < int({{$lengthPointer}}); {{$indexPointer}}++ {
+		{{$targetPointer := printf "%s[%s]" $pointer $indexPointer -}}
 
-		{{template "decode" (list $targetName $value.LengthPrefixedSlice)}}
+		{{template "decode" (list $name $targetPointer $value.LengthPrefixedSlice)}}
 	}
 
 {{else if some $value.NullableLengthPrefixedSlice -}}
-    {{$lengthName := temp -}}
+    {{$lengthPointer := temp -}}
 
-	var {{$lengthName}} {{template "type" (list "" $value.NullableLengthPrefixedSlice.Prefix)}}
-    {{template "decode" (list $lengthName $value.NullableLengthPrefixedSlice.Prefix)}}
+	var {{$lengthPointer}} {{template "type" (list $name $value.NullableLengthPrefixedSlice.Prefix)}}
+    {{template "decode" (list $name $lengthPointer $value.NullableLengthPrefixedSlice.Prefix)}}
 
-	if {{$lengthName}} == -1 {
-		{{$name}} = nil
+	if {{$lengthPointer}} == -1 {
+		{{$pointer}} = nil
 	} else {
-		{{$name}} = slices.Resize({{$name}}, int({{$lengthName}}))
+		{{$pointer}} = slices.Resize({{$pointer}}, int({{$lengthPointer}}))
 
-		{{$indexName := temp -}}
+		{{$indexPointer := temp -}}
 
-		for {{$indexName}} := 0; {{$indexName}} < int({{$lengthName}}); {{$indexName}}++ {
-			{{$targetName := printf "%s[%s]" $name $indexName -}}
+		for {{$indexPointer}} := 0; {{$indexPointer}} < int({{$lengthPointer}}); {{$indexPointer}}++ {
+			{{$targetPointer := printf "%s[%s]" $pointer $indexPointer -}}
 
-			{{template "decode" (list $targetName $value.NullableLengthPrefixedSlice)}}
+			{{template "decode" (list $name $targetPointer $value.NullableLengthPrefixedSlice)}}
 		}
 	}
 
 {{else if some $value.ZeroByteTerminatedSlice -}}
-	{{$name}} = {{$name}}[:0]
+    {{$structName := printf "%s%s" $name $value.ZeroByteTerminatedSlice.Name -}}
+
+    {{$pointer}} = {{$pointer}}[:0]
 
 	for {
-	    {{$name}} = slices.Resize({{$name}}, len({{$name}})+1)
+	    {{$pointer}} = slices.Resize({{$pointer}}, len({{$pointer}})+1)
 
-		{{$targetName := printf "%s[len(%s)-1]" $name $name -}}
+		{{$targetPointer := printf "%s[len(%s)-1]" $pointer $pointer -}}
 
-		{{$keyName := printf "%s.%s" $targetName $value.ZeroByteTerminatedSlice.KeyName -}}
+		{{$keyPointer := printf "%s.%s" $targetPointer $value.ZeroByteTerminatedSlice.KeyName -}}
 
-		{{$keyName}}, err = decoder.Uint8()
+		{{$keyPointer}}, err = decoder.Uint8()
 		if err != nil {
 			return
 		}
-		if {{$keyName}} == 0 {
-			{{$name}} = {{$name}}[:len({{$name}})-1]
+		if {{$keyPointer}} == 0 {
+			{{$pointer}} = {{$pointer}}[:len({{$pointer}})-1]
 			break
 		}
 
 		{{range $field := $value.ZeroByteTerminatedSlice.Fields -}}
-			{{$fieldName := printf "%s.%s" $targetName $field.Name -}}
+			{{$fieldPointer := printf "%s.%s" $targetPointer $field.Name -}}
 
-			{{template "decode" (list $fieldName $field) -}}
+			{{template "decode" (list $structName $fieldPointer $field) -}}
 		{{end -}}
 	}
 {{else if some $value.ZeroTerminatedSlice -}}
-	{{$name}} = {{$name}}[:0]
+	{{$pointer}} = {{$pointer}}[:0]
 
 	for {
-		{{$name}} = slices.Resize({{$name}}, len({{$name}})+1)
+		{{$pointer}} = slices.Resize({{$pointer}}, len({{$pointer}})+1)
 
-		{{$targetName := printf "%s[len(%s)-1]" $name $name -}}
+		{{$targetPointer := printf "%s[len(%s)-1]" $pointer $pointer -}}
 
-		{{template "decode" (list $targetName $value.ZeroTerminatedSlice)}}
+		{{template "decode" (list $name $targetPointer $value.ZeroTerminatedSlice)}}
 
-		if {{$targetName}} == *new({{template "type" (list "" $value.ZeroTerminatedSlice)}}) {
-    		{{$name}} = {{$name}}[:len({{$name}})-1]
+		if {{$targetPointer}} == *new({{template "type" (list $name $value.ZeroTerminatedSlice)}}) {
+    		{{$pointer}} = {{$pointer}}[:len({{$pointer}})-1]
 			break
 		}
 	}
diff --git a/hack/packetgen/templates/encode.tmpl b/hack/packetgen/templates/encode.tmpl
index 50006c3691d8db4b65e784deaaa28ac26428f08f..e49e2e2facf9519116019b4041c844ad4d0696c7 100644
--- a/hack/packetgen/templates/encode.tmpl
+++ b/hack/packetgen/templates/encode.tmpl
@@ -1,77 +1,88 @@
 {{$name := index . 0 -}}
-{{$value := index . 1 -}}
+{{$pointer := index . 1 -}}
+{{$value := index . 2 -}}
 
 {{if some $value.Map -}}
-	err = {{$name}}.WriteTo(encoder)
+    {{$ifaceName := printf "%s%s" $name $value.Map.Name -}}
+
+    {{$prefixPointer := printf "%s.%s()" $pointer $ifaceName -}}
+
+	{{template "encode" (list $name $prefixPointer $value.Map.Prefix)}}
+
+	err = {{$pointer}}.WriteTo(encoder)
 	if err != nil {
 		return
 	}
 {{else if some $value.Remaining -}}
-	{{$itemName := temp -}}
+	{{$itemPointer := temp -}}
 
-	for _, {{$itemName}} := range {{$name}} {
-		{{template "encode" (list $itemName $value.Remaining)}}
+	for _, {{$itemPointer}} := range {{$pointer}} {
+		{{template "encode" (list $name $itemPointer $value.Remaining)}}
 	}
 {{else if some $value.Basic -}}
-	err = encoder.{{upperCamel $value.Basic}}({{$value.Basic}}({{$name}}))
+	err = encoder.{{upperCamel $value.Basic}}({{$value.Basic}}({{$pointer}}))
 	if err != nil {
 		return
 	}
 {{else if some $value.Array -}}
-	{{$itemName := temp -}}
+	{{$itemPointer := temp -}}
 
-	for _, {{$itemName}} := range {{$name}} {
-		{{template "encode" (list $itemName $value.Array)}}
+	for _, {{$itemPointer}} := range {{$pointer}} {
+		{{template "encode" (list $name $itemPointer $value.Array)}}
 	}
 {{else if some $value.Struct -}}
-	{{range $field := $value.Struct.Fields -}}
-		{{$fieldName := printf "%s.%s" $name $field.Name -}}
+    {{$structName := printf "%s%s" $name $value.Struct.Name -}}
 
-		{{template "encode" (list $fieldName $field)}}
+    {{range $field := $value.Struct.Fields -}}
+		{{$fieldPointer := printf "%s.%s" $pointer $field.Name -}}
+
+		{{template "encode" (list $structName $fieldPointer $field)}}
 	{{end -}}
 {{else if some $value.LengthPrefixedSlice -}}
-	{{$lengthName := temp -}}
+	{{$lengthPointer := temp -}}
 
-	{{$lengthName}} := {{template "type" (list "" $value.LengthPrefixedSlice.Prefix)}}(len({{$name}}))
+	{{$lengthPointer}} := {{template "type" (list $name $value.LengthPrefixedSlice.Prefix)}}(len({{$pointer}}))
 
-	{{template "encode" (list $lengthName $value.LengthPrefixedSlice.Prefix)}}
+	{{template "encode" (list $name $lengthPointer $value.LengthPrefixedSlice.Prefix)}}
 
-	{{$itemName := temp -}}
+	{{$itemPointer := temp -}}
 
-	for _, {{$itemName}} := range {{$name}} {
-		{{template "encode" (list $itemName $value.LengthPrefixedSlice)}}
+	for _, {{$itemPointer}} := range {{$pointer}} {
+		{{template "encode" (list $name $itemPointer $value.LengthPrefixedSlice)}}
 	}
 {{else if some $value.NullableLengthPrefixedSlice -}}
-    {{$lengthName := temp -}}
+    {{$lengthPointer := temp -}}
 
-    {{$lengthName}} := {{template "type" (list "" $value.NullableLengthPrefixedSlice.Prefix)}}(len({{$name}}))
+    {{$lengthPointer}} := {{template "type" (list $name $value.NullableLengthPrefixedSlice.Prefix)}}(len({{$pointer}}))
 
-	if {{$name}} == nil {
-		{{$lengthName}} = -1
+	if {{$pointer}} == nil {
+		{{$lengthPointer}} = -1
 	}
 
-    {{template "encode" (list $lengthName $value.NullableLengthPrefixedSlice.Prefix)}}
+    {{template "encode" (list $name $lengthPointer $value.NullableLengthPrefixedSlice.Prefix)}}
 
-    {{$itemName := temp -}}
+    {{$itemPointer := temp -}}
 
-	for _, {{$itemName}} := range {{$name}} {
-    	{{template "encode" (list $itemName $value.NullableLengthPrefixedSlice)}}
+	for _, {{$itemPointer}} := range {{$pointer}} {
+    	{{template "encode" (list $name $itemPointer $value.NullableLengthPrefixedSlice)}}
 	}
 {{else if some $value.ZeroByteTerminatedSlice -}}
-	{{$itemName := temp -}}
+    {{$structName := printf "%s%s" $name $value.ZeroByteTerminatedSlice.Name -}}
+
+    {{$itemPointer := temp -}}
 
-	for _, {{$itemName}} := range {{$name}} {
-		{{$keyName := printf "%s.%s" $itemName $value.ZeroByteTerminatedSlice.KeyName -}}
+	for _, {{$itemPointer}} := range {{$pointer}} {
+		{{$keyPointer := printf "%s.%s" $itemPointer $value.ZeroByteTerminatedSlice.KeyName -}}
 
-		err = encoder.Uint8({{$keyName}})
+		err = encoder.Uint8({{$keyPointer}})
 		if err != nil {
 			return
 		}
 
 		{{range $field := $value.ZeroByteTerminatedSlice.Fields -}}
-			{{$fieldName := printf "%s.%s" $itemName $field.Name -}}
+			{{$fieldPointer := printf "%s.%s" $itemPointer $field.Name -}}
 
-			{{template "encode" (list $fieldName $field)}}
+			{{template "encode" (list $structName $fieldPointer $field)}}
 		{{end -}}
 	}
 
@@ -80,15 +91,15 @@
 		return
 	}
 {{else if some $value.ZeroTerminatedSlice -}}
-	{{$itemName := temp -}}
+	{{$itemPointer := temp -}}
 
-	for _, {{$itemName}} := range {{$name}} {
-    	{{template "encode" (list $itemName $value.ZeroTerminatedSlice)}}
+	for _, {{$itemPointer}} := range {{$pointer}} {
+    	{{template "encode" (list $name $itemPointer $value.ZeroTerminatedSlice)}}
 	}
 
-	{{$doneName := temp -}}
+	{{$donePointer := temp -}}
 
-	var {{$doneName}} {{template "type" (list "" $value.ZeroTerminatedSlice)}}
+	var {{$donePointer}} {{template "type" (list $name $value.ZeroTerminatedSlice)}}
 
-	{{template "encode" (list $doneName $value.ZeroTerminatedSlice)}}
+	{{template "encode" (list $name $donePointer $value.ZeroTerminatedSlice)}}
 {{end -}}
diff --git a/hack/packetgen/templates/packets.tmpl b/hack/packetgen/templates/packets.tmpl
index 9d46347bda0f1f7357ef5d856637041114119843..78311a7ccf56e1c37620593921efc75d8f863a9a 100644
--- a/hack/packetgen/templates/packets.tmpl
+++ b/hack/packetgen/templates/packets.tmpl
@@ -35,13 +35,13 @@ const (
 			}
 		{{end -}}
 
-		{{template "decode" (list "(*T)" $packet)}}
+		{{template "decode" (list $name "(*T)" $packet)}}
 
 		return
 	}
 
 	func (T *{{$name}}) WriteTo(encoder *fed.Encoder) (err error) {
-		{{template "encode" (list "(*T)" $packet)}}
+		{{template "encode" (list $name "(*T)" $packet)}}
 
 		return
 	}
diff --git a/hack/packetgen/templates/preType.tmpl b/hack/packetgen/templates/preType.tmpl
index a98bff85cbc0bea7f1243a08b93a8be09c61b1e7..2f63581966b62af91b41c9863f6442f7d99e772f 100644
--- a/hack/packetgen/templates/preType.tmpl
+++ b/hack/packetgen/templates/preType.tmpl
@@ -11,16 +11,18 @@
 
 		type {{$itemName}} {{template "type" (list $itemName $item)}}
 
-		func (*{{$itemName}}) {{$ifaceName}}() {}
+		func (*{{$itemName}}) {{$ifaceName}}() {{template "type" (list $name $value.Map.Prefix)}} {
+			return {{$item.Type}}
+		}
 
 		func (T *{{$itemName}}) ReadFrom(decoder *fed.Decoder) (err error) {
-			{{template "decode" (list "(*T)" $item)}}
+			{{template "decode" (list $itemName "(*T)" $item)}}
 
 			return
 		}
 
 		func (T *{{$itemName}}) WriteTo(encoder *fed.Encoder) (err error) {
-			{{template "encode" (list "(*T)" $item)}}
+			{{template "encode" (list $itemName "(*T)" $item)}}
 
 			return
 		}
@@ -28,7 +30,7 @@
 	{{end -}}
 
 	type {{$ifaceName}} interface{
-		{{$ifaceName}}()
+		{{$ifaceName}}() {{template "type" (list $name $value.Map.Prefix)}}
 
 		ReadFrom(decoder *fed.Decoder) error
 		WriteTo(encoder *fed.Encoder) error