-
Notifications
You must be signed in to change notification settings - Fork 39
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Extraction tables from spec. .docx file * Initial encode/decode code generator * Add encode code * Add decode code * Move generator files * Refine type treatment in generator * Commit generated codes * Add generated marker * Add error check codes * generate some codes in nas.go * Refactor generator * Add encode/decode test for IEs whose length is maximum one * IEs length check, phase 1 * IEs length check, phase 2 * Special length check for PDU address IE * Fix IEI value of Mapped EPS bearer contexts * Add IE types * Add comments and refactor * fix golangci-lint error * Add encode/decode test for IEs whose length is minimum one * Change R/W codes * Fuzzing code and data * Fix crash by empty message * Expand fuzzing test * fix golangci-lint error * Disable fuzzing in older golang
- Loading branch information
1 parent
4831f29
commit 67b0067
Showing
325 changed files
with
10,141 additions
and
1,703 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,3 +14,7 @@ cscope.* | |
.DS_Store | ||
|
||
support | ||
|
||
# NAS spec | ||
24501-*.zip | ||
spec.csv |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
//go:build go1.18 | ||
// +build go1.18 | ||
|
||
package nas_test | ||
|
||
import ( | ||
"bytes" | ||
"fmt" | ||
"testing" | ||
|
||
"github.com/free5gc/nas" | ||
) | ||
|
||
func FuzzNAS(f *testing.F) { | ||
f.Fuzz(func(t *testing.T, d []byte) { | ||
msg := new(nas.Message) | ||
err := msg.PlainNasDecode(&d) | ||
if err == nil { | ||
buf, err := msg.PlainNasEncode() | ||
if err != nil { | ||
panic(fmt.Sprintf("Re-encoding failed: %s", err.Error())) | ||
} | ||
msg2 := new(nas.Message) | ||
err = msg2.PlainNasDecode(&buf) | ||
if err != nil { | ||
panic(fmt.Sprintf("Re-decoding failed: %s", err.Error())) | ||
} | ||
} | ||
}) | ||
} | ||
|
||
func FuzzGmmMessageDecode(f *testing.F) { | ||
f.Fuzz(func(t *testing.T, d []byte) { | ||
msg := new(nas.Message) | ||
err := msg.GmmMessageDecode(&d) | ||
if err == nil { | ||
buf := new(bytes.Buffer) | ||
err := msg.GmmMessageEncode(buf) | ||
if err != nil { | ||
panic(fmt.Sprintf("Re-encoding failed: %s", err.Error())) | ||
} | ||
msg2 := new(nas.Message) | ||
buf2 := buf.Bytes() | ||
err = msg2.GmmMessageDecode(&buf2) | ||
if err != nil { | ||
panic(fmt.Sprintf("Re-decoding failed: %s", err.Error())) | ||
} | ||
} | ||
}) | ||
} | ||
|
||
func FuzzGsmMessageDecode(f *testing.F) { | ||
f.Fuzz(func(t *testing.T, d []byte) { | ||
msg := new(nas.Message) | ||
err := msg.GsmMessageDecode(&d) | ||
if err == nil { | ||
buf := new(bytes.Buffer) | ||
err := msg.GsmMessageEncode(buf) | ||
if err != nil { | ||
panic(fmt.Sprintf("Re-encoding failed: %s", err.Error())) | ||
} | ||
msg2 := new(nas.Message) | ||
buf2 := buf.Bytes() | ||
err = msg2.GsmMessageDecode(&buf2) | ||
if err != nil { | ||
panic(fmt.Sprintf("Re-decoding failed: %s", err.Error())) | ||
} | ||
} | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
#!/bin/sh | ||
|
||
SPEC=24501-f70 | ||
|
||
cd `dirname $0` | ||
|
||
if [ ! -f spec.csv ] ; then | ||
if [ ! -f ${SPEC}.zip ] ; then | ||
wget https://www.3gpp.org/ftp/Specs/archive/24_series/24.501/${SPEC}.zip | ||
fi | ||
if [ ! -f ${SPEC}.zip ] ; then | ||
echo "Download failed." | ||
exit 1 | ||
fi | ||
python3 internal/tools/extract.py | ||
fi | ||
|
||
rm -rf testdata/GmmMessage testdata/GsmMessage | ||
mkdir -p testdata/GmmMessage testdata/GsmMessage | ||
rm -f testdata/fuzz/FuzzGmmMessageDecode/msg* testdata/fuzz/FuzzGsmMessageDecode/msg* | ||
ls nasMessage/*go | grep -v "_test" | grep -v "NAS_EPD" | grep -v "NAS_CommInfoIE" | xargs rm -f | ||
go run internal/tools/generator_sub.go | ||
go run internal/tools/generator/cmd/cmd.go |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
#!/usr/bin/python3 | ||
|
||
import zipfile | ||
import docx | ||
import csv | ||
from docx.oxml import CT_P | ||
from docx.text.paragraph import Paragraph | ||
from docx.oxml.table import CT_Tbl | ||
from docx.table import _Cell, Table | ||
|
||
with zipfile.ZipFile('24501-f70.zip') as zf: | ||
with zf.open('24501-f70.docx') as inf: | ||
with open('spec.csv', 'w', encoding='utf8', newline='') as outf: | ||
csvw = csv.writer(outf) | ||
doc = docx.Document(inf) | ||
parent = doc._body._body | ||
prev = None | ||
for c in parent.iterchildren(): | ||
if isinstance(c, CT_P): | ||
prev = Paragraph(c, parent) | ||
elif isinstance(c, CT_Tbl): | ||
tab = Table(c, parent) | ||
if isinstance(prev, Paragraph): | ||
csvw.writerow([prev.text]) | ||
for row in tab.rows: | ||
crow = [] | ||
for cell in row.cells: | ||
crow.append(cell.text) | ||
csvw.writerow(crow) | ||
prev = tab |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package main | ||
|
||
import "github.com/free5gc/nas/internal/tools/generator" | ||
|
||
func main() { | ||
generator.ParseSpecs() | ||
|
||
generator.GenerateNasMessage() | ||
|
||
generator.GenerateNasEncDec() | ||
|
||
generator.GenerateTestLarge() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
package generator | ||
|
||
import ( | ||
"fmt" | ||
"strings" | ||
) | ||
|
||
// Generate nas_generated.go | ||
func GenerateNasEncDec() { | ||
fOut := NewOutputFile("nas_generated.go", "nas", []string{ | ||
"\"bytes\"", | ||
"\"encoding/binary\"", | ||
"\"fmt\"", | ||
"", | ||
"\"github.com/free5gc/nas/nasMessage\"", | ||
}) | ||
|
||
for _, isGMM := range []bool{true, false} { | ||
gmmGsm := "" | ||
if isGMM { | ||
gmmGsm = "Gmm" | ||
} else { | ||
gmmGsm = "Gsm" | ||
} | ||
|
||
// Generate (Gmm|Gsm)Message struct | ||
fmt.Fprintf(fOut, "type %sMessage struct {\n", gmmGsm) | ||
fmt.Fprintf(fOut, "%sHeader\n", gmmGsm) | ||
for _, msgDef := range msgOrder { | ||
if msgDef != nil && msgDef.isGMM == isGMM { | ||
fmt.Fprintf(fOut, "*nasMessage.%s // %s\n", msgDef.structName, msgDef.section) | ||
} | ||
} | ||
fmt.Fprintln(fOut, "}") | ||
fmt.Fprintln(fOut, "") | ||
|
||
// Generate constant for message ID | ||
fmt.Fprintln(fOut, "const (") | ||
for msgType, msgDef := range type2Msg { | ||
if msgDef != nil && msgDef.isGMM == isGMM { | ||
fmt.Fprintf(fOut, "MsgType%s uint8 = %d\n", msgDef.structName, msgType) | ||
} | ||
} | ||
fmt.Fprintln(fOut, ")") | ||
fmt.Fprintln(fOut, "") | ||
|
||
// Generate (Gmm|Gsm)MessageDecode functions | ||
fmt.Fprintf(fOut, "func (a *Message) %sMessageDecode(byteArray *[]byte) error {\n", gmmGsm) | ||
fmt.Fprintf(fOut, "buffer := bytes.NewBuffer(*byteArray)\n") | ||
fmt.Fprintf(fOut, "a.%sMessage = New%sMessage()\n", gmmGsm, gmmGsm) | ||
fmt.Fprintf(fOut, "if err := binary.Read(buffer, binary.BigEndian, &a.%sMessage.%sHeader); err != nil {\n", | ||
gmmGsm, gmmGsm) | ||
fmt.Fprintf(fOut, "return fmt.Errorf(\"%s NAS decode Fail: read fail - %%+v\", err)\n", strings.ToUpper(gmmGsm)) | ||
fmt.Fprintf(fOut, "}\n") | ||
fmt.Fprintf(fOut, "switch a.%sMessage.%sHeader.GetMessageType() {\n", gmmGsm, gmmGsm) | ||
for _, msgDef := range type2Msg { | ||
if msgDef != nil && msgDef.isGMM == isGMM { | ||
fmt.Fprintf(fOut, "case MsgType%s:\n", msgDef.structName) | ||
fmt.Fprintf(fOut, "a.%sMessage.%s = nasMessage.New%s(MsgType%s)\n", | ||
gmmGsm, msgDef.structName, msgDef.structName, msgDef.structName) | ||
fmt.Fprintf(fOut, "return a.%sMessage.Decode%s(byteArray)\n", gmmGsm, msgDef.structName) | ||
} | ||
} | ||
fmt.Fprintf(fOut, "default:\n") | ||
fmt.Fprintf(fOut, "return fmt.Errorf(\"NAS decode Fail: MsgType[%%d] doesn't exist in %s Message\",\n", | ||
strings.ToUpper(gmmGsm)) | ||
fmt.Fprintf(fOut, "a.%sMessage.%sHeader.GetMessageType())\n", gmmGsm, gmmGsm) | ||
fmt.Fprintln(fOut, "}") | ||
fmt.Fprintln(fOut, "}") | ||
fmt.Fprintln(fOut, "") | ||
|
||
// Generate (Gmm|Gsm)MessageEncode functions | ||
fmt.Fprintf(fOut, "func (a *Message) %sMessageEncode(buffer *bytes.Buffer) error {\n", gmmGsm) | ||
fmt.Fprintf(fOut, "switch a.%sMessage.%sHeader.GetMessageType() {\n", gmmGsm, gmmGsm) | ||
for _, msgDef := range type2Msg { | ||
if msgDef != nil && msgDef.isGMM == isGMM { | ||
fmt.Fprintf(fOut, "case MsgType%s:\n", msgDef.structName) | ||
fmt.Fprintf(fOut, "return a.%sMessage.Encode%s(buffer)\n", gmmGsm, msgDef.structName) | ||
} | ||
} | ||
fmt.Fprintf(fOut, "default:\n") | ||
fmt.Fprintf(fOut, "return fmt.Errorf(\"NAS Encode Fail: MsgType[%%d] doesn't exist in %s Message\",\n", | ||
strings.ToUpper(gmmGsm)) | ||
fmt.Fprintf(fOut, "a.%sMessage.%sHeader.GetMessageType())\n", gmmGsm, gmmGsm) | ||
fmt.Fprintln(fOut, "}") | ||
fmt.Fprintln(fOut, "}") | ||
fmt.Fprintln(fOut, "") | ||
} | ||
|
||
if err := fOut.Close(); err != nil { | ||
panic(err) | ||
} | ||
} |
Oops, something went wrong.