Skip to content

Commit

Permalink
[IMP]upgrade wireshark4.2.6,delete func print_*_frame,add func GetSev…
Browse files Browse the repository at this point in the history
…eralFrameProtoTreeInJson
  • Loading branch information
randolphcyg committed Jul 15, 2024
1 parent 61dd4e9 commit 4e6dc1d
Show file tree
Hide file tree
Showing 45 changed files with 1,460 additions and 9,812 deletions.
38 changes: 19 additions & 19 deletions README-zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,7 @@ go get "github.com/randolphcyg/gowireshark"
如何测试:

```shell
cd tests/
go test -v -run TestDissectPrintFirstFrame
go test -v -run TestDissectPrintAllFrame
```

如何解析 pcap 数据包文件的某一帧:
Expand Down Expand Up @@ -91,7 +90,7 @@ func main() {
fmt.Println("【layer frame】:", frame)
}
```
其他示例可以参考[测试文件](https://github.com/randolphcyg/gowireshark/blob/main/tests/gowireshark_test.go)
其他示例可以参考[测试文件](https://github.com/randolphcyg/gowireshark/blob/main/gowireshark_test.go)

## 2. 详细说明

Expand Down Expand Up @@ -122,19 +121,18 @@ gowireshark
│   ├── libpcap.so.1
│   ├── libwireshark.so
│   ├── libwireshark.so.17
│   ├── libwireshark.so.17.0.5
│   ├── libwireshark.so.17.0.6
│   ├── libwiretap.so
│   ├── libwiretap.so.14
│   ├── libwiretap.so.14.1.5
│   ├── libwiretap.so.14.1.6
│   ├── libwsutil.so
│   ├── libwsutil.so.15
│   └── libwsutil.so.15.0.0
├── offline.c
├── online.c
├── pcaps/
│   └── mysql.pcapng
└── tests/
└── gowireshark_test.go
└── gowireshark_test.go
```
项目目录结构的详细说明:

Expand All @@ -145,7 +143,7 @@ gowireshark
| `frame_tvbuff.c``include/frame_tvbuff.h` | wireshark的源码文件、拷贝出来的、必须放在此处 |
| `libs/` | wireshark、libpcap最新动态链接库文件 |
| `pcaps/` | 用于测试的 pcap 数据包文件 |
| `tests/` | 测试文件夹 |
| `gowireshark_test.go` | 测试文件 |
| `uthash.h` | 第三方 [uthash](https://github.com/troydhanson/uthash)|
| `cJSON.c、cJSON.h` | 第三方[cJSON](https://github.com/DaveGamble/cJSON)|
| `lib.c、offline.c、online.c` | 用C封装和加强libpcap和wireshark功能的代码 |
Expand Down Expand Up @@ -179,7 +177,7 @@ graph LR

```shell
# 确定最新发行版本并设置环境变量
export WIRESHARKV=4.2.5
export WIRESHARKV=4.2.6
# 到/opt目录下操作
cd /opt/
# 下载源码
Expand Down Expand Up @@ -812,7 +810,7 @@ apt install bison
1. 可以在 `lib.c、offline.c、online.c` 中或在根目录中创建一个新的C文件并添加自定义功能的接口;
2. 接口完成后需要在`include/`目录下同名H头文件增加声明,若`gowireshark.go`中也用到该接口,则需要在此文件的cgo序文中增加相同的声明;
3.`gowireshark.go`中封装该接口;
4.`tests/`目录下增加测试案例;
4.`gowireshark_test.go`文件中增加测试案例;
5. 使用 clang 格式工具格式化自定义的 C 代码和头文件:
例如:`clang-format -i lib.c`,参数`-i`表示此命令直接格式化指定的文件,删除`-i`进行预览。
修改根目录中的所有 .c 文件和 `include/` 目录中的所有 .h 头文件(注意用grep去掉第三方库文件例如cJSON)
Expand All @@ -822,21 +820,23 @@ apt install bison
find . -maxdepth 1 -name '*.c' | grep -v 'cJSON.c' | grep -v 'frame_tvbuff.c' | xargs clang-format -i
find ./include -maxdepth 1 -name '*.h' | grep -v 'cJSON.h' | grep -v 'frame_tvbuff.h' | grep -v 'uthash.h' | xargs clang-format -i
```
6. 如何测试(cd tests/):
6. 测试:

可以在`tests/`目录下编写测试函数,直接测试:
可以在`gowireshark_test.go`文件中编写测试函数,直接测试:
```shell
# Parse and output the first frame
go test -v -run TestDissectPrintFirstFrame
# Parse and output a frame in JSON format
# 解析并输出一个流量包文件所有帧
go test -v -run TestDissectPrintAllFrame
# 解析并输出一个流量包文件特定帧,并以json格式呈现
go test -v -run TestGetSpecificFrameProtoTreeInJson
# Parse and output all frame in JSON format
# 解析并输出一个流量包文件多个选定帧,并以json格式呈现
go test -v -run TestGetSeveralFrameProtoTreeInJson
# 解析并输出一个流量包文件所有帧,并以json格式呈现
go test -v -run TestGetAllFrameProtoTreeInJson
# Parses and outputs a frame of HEX data
# 解析并输出一个流量包文件特定帧的16进制数据,并以json格式呈现
go test -v -run TestGetSpecificFrameHexData
# Parse packets in real time
# 实时抓包解析
go test -v -run TestDissectPktLive
# Real-time packet capture Read a certain number and parse it
# 实时抓取一定数目包并解析
go test -v -run TestDissectPktLiveSpecificNum
```
或者通过调用此库的方式测试。
Expand Down
28 changes: 14 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,7 @@ go get "github.com/randolphcyg/gowireshark"
how to test:

```shell
cd tests/
go test -v -run TestDissectPrintFirstFrame
go test -v -run TestDissectPrintAllFrame
```

how to dissect specific frame of a pcap file:
Expand Down Expand Up @@ -92,7 +91,7 @@ func main() {
}
```

Other examples can refer to the [test file](https://github.com/randolphcyg/gowireshark/blob/main/tests/gowireshark_test.go).
Other examples can refer to the [test file](https://github.com/randolphcyg/gowireshark/blob/main/gowireshark_test.go).

## 2. Detailed description

Expand Down Expand Up @@ -123,19 +122,18 @@ gowireshark
│   ├── libpcap.so.1
│   ├── libwireshark.so
│   ├── libwireshark.so.17
│   ├── libwireshark.so.17.0.5
│   ├── libwireshark.so.17.0.6
│   ├── libwiretap.so
│   ├── libwiretap.so.14
│   ├── libwiretap.so.14.1.5
│   ├── libwiretap.so.14.1.6
│   ├── libwsutil.so
│   ├── libwsutil.so.15
│   └── libwsutil.so.15.0.0
├── offline.c
├── online.c
├── pcaps/
│   └── mysql.pcapng
└── tests/
└── gowireshark_test.go
└── gowireshark_test.go
```
Detailed description of the project directory structure:

Expand All @@ -146,7 +144,7 @@ Detailed description of the project directory structure:
| `frame_tvbuff.c``include/frame_tvbuff.h` | The wireshark source files, copied out, must be placed here |
| `libs/` | wireshark、libpcap latest dll files |
| `pcaps/` | Pcap packet files used for testing |
| `tests/` | Test files |
| `gowireshark_test.go` | Test files |
| `uthash.h` | Third-party [uthash](https://github.com/troydhanson/uthash) library |
| `cJSON.c、cJSON.h` | Third-party [cJSON](https://github.com/DaveGamble/cJSON) library |
| `lib.c、offline.c、online.c` | Code that encapsulates and enhances libpcap and wireshark functionality in C |
Expand Down Expand Up @@ -185,7 +183,7 @@ Note that some interfaces in this project may not be valid if the wireshark vers

```shell
# Determine the latest release version and set environment variables
export WIRESHARKV=4.2.5
export WIRESHARKV=4.2.6
# Operate in the /opt directory
cd /opt/
# Download the source code
Expand Down Expand Up @@ -819,22 +817,24 @@ apt install bison
1. You can create a new C file in `lib.c, offline.c, online.c`'` or in the root directory and add interfaces for custom functions;
2. After the interface is completed, you need to add a declaration in the H header file with the same name in the `include/` directory, and if the interface is also used in `gowireshark.go`, you need to add the same declaration in the cgo preamble of this file;
3. encapsulate the interface in `gowireshark.go`;
4. Add test cases under `tests/` directory;
4. Add test cases in file `gowireshark_test.go`;
5. Use the clang-format tool to format custom C code and header files:
E.g:`clang-format -i lib.c`,With the parameter '-i' indicates that this command directly formats the specified file, remove '-i' to preview.
Modify all .c files in the root directory and all .h header files in the `include/` directory (note that third-party library files such as cJSON are removed with grep)
(Only the current directory is level 1, do not traverse down the lookup, i.e. do not format the source files under `include/wireshark/` and `include/libpcap/`):

```shell
find . -maxdepth 1 -name '*.c' | grep -v 'cJSON.c' | grep -v 'frame_tvbuff.c' | xargs clang-format -i
find ./include -maxdepth 1 -name '*.h' | grep -v 'cJSON.h' | grep -v 'frame_tvbuff.h' | xargs clang-format -i
find ./include -maxdepth 1 -name '*.h' | grep -v 'cJSON.h' | grep -v 'frame_tvbuff.h' | grep -v 'uthash.h' | xargs clang-format -i
```
6. how to test(cd tests/):
6. how to test:
```shell
# Parse and output the first frame
go test -v -run TestDissectPrintFirstFrame
# Parse and output all the frame of a pcap file
go test -v -run TestDissectPrintAllFrame
# Parse and output a frame in JSON format
go test -v -run TestGetSpecificFrameProtoTreeInJson
# Parse and output several frame in JSON format
go test -v -run TestGetSeveralFrameProtoTreeInJson
# Parse and output all frame in JSON format
go test -v -run TestGetAllFrameProtoTreeInJson
# Parses and outputs a frame of HEX data
Expand Down
134 changes: 65 additions & 69 deletions gowireshark.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"encoding/json"
"log/slog"
"os"
"slices"
"strconv"
"sync"
"time"
Expand Down Expand Up @@ -92,21 +93,6 @@ func initCapFile(inputFilepath string) (err error) {
return
}

// DissectPrintFirstFrame Dissect and print the first frame
func DissectPrintFirstFrame(inputFilepath string) (err error) {
EpanMutex.Lock()
defer EpanMutex.Unlock()

err = initCapFile(inputFilepath)
if err != nil {
return
}

C.print_first_frame()

return
}

// DissectPrintAllFrame Dissect and print all frames
func DissectPrintAllFrame(inputFilepath string) (err error) {
EpanMutex.Lock()
Expand All @@ -122,59 +108,6 @@ func DissectPrintAllFrame(inputFilepath string) (err error) {
return
}

// DissectPrintFirstSeveralFrame
//
// @Description: Dissect and print the first several frames
// @param inputFilepath: Pcap src file path
// @param count: The index of the first several frame you want to dissect
func DissectPrintFirstSeveralFrame(inputFilepath string, count int) (err error) {
EpanMutex.Lock()
defer EpanMutex.Unlock()

err = initCapFile(inputFilepath)
if err != nil {
return
}

if count < 1 {
err = errors.Wrap(ErrIllegalPara, strconv.Itoa(count))
return
}

C.print_first_several_frame(C.int(count))

return
}

// DissectPrintSpecificFrame
//
// @Description: Dissect and print the Specific frame
// @param inputFilepath: Pcap src file path
// @param num: The index value of the specific frame you want to dissect
func DissectPrintSpecificFrame(inputFilepath string, num int) (err error) {
EpanMutex.Lock()
defer EpanMutex.Unlock()

err = initCapFile(inputFilepath)
if err != nil {
return
}

if num < 1 {
err = errors.Wrap(ErrIllegalPara, "Frame num "+strconv.Itoa(num))
return
}

// errNo is 2 if num is out of bounds
errNo := C.print_specific_frame(C.int(num))
if errNo == 2 {
err = errors.Wrap(WarnFrameIndexOutOfBounds, strconv.Itoa(int(errNo)))
return
}

return
}

// HexData hex data
type HexData struct {
Offset []string `json:"offset"`
Expand Down Expand Up @@ -754,6 +687,69 @@ func GetSpecificFrameProtoTreeInJson(inputFilepath string, num int, isDescriptiv
}
}

func removeNegativeAndZero(nums []int) []int {
var result []int
for _, num := range nums {
if num > 0 {
result = append(result, num)
}
}
return result
}

// GetSeveralFrameProtoTreeInJson
//
// @Description: Transfer specific frame proto tree to json format
// @param inputFilepath: Pcap src file path
// @param nums: The frame number that needs to be output
// @param isDescriptive: Whether the JSON result has descriptive fields
// @param isDebug: Whether to print JSON result in C logic
// @return res: Contains specific frame's JSON dissect result
func GetSeveralFrameProtoTreeInJson(inputFilepath string, nums []int, isDescriptive, isDebug bool) (res []FrameDissectRes, err error) {
EpanMutex.Lock()
defer EpanMutex.Unlock()

err = initCapFile(inputFilepath)
if err != nil {
return
}

descriptive := 0
if isDescriptive {
descriptive = 1
}

debug := 0
if isDebug {
debug = 1
}

nums = removeNegativeAndZero(nums)
// Must sort from smallest to largest
slices.Sort(nums)

for _, num := range nums {
// get proto dissect result in json format by c
srcFrame := C.proto_tree_in_json(C.int(num), C.int(descriptive), C.int(debug))
if srcFrame != nil {
if C.strlen(srcFrame) == 0 {
continue
}
}

// unmarshal dissect result
singleFrame, err := UnmarshalDissectResult(CChar2GoStr(srcFrame))
if err != nil {
err = errors.Wrap(ErrUnmarshalObj, "Num "+strconv.Itoa(num))
slog.Warn(err.Error())
}

res = append(res, singleFrame)
}

return
}

// GetAllFrameProtoTreeInJson
//
// @Description: Transfer proto tree to json format
Expand Down Expand Up @@ -785,7 +781,7 @@ func GetAllFrameProtoTreeInJson(inputFilepath string, isDescriptive bool, isDebu
// get proto dissect result in json format by c
srcFrame := C.proto_tree_in_json(C.int(counter), C.int(descriptive), C.int(debug))
if srcFrame != nil {
if C.strlen(srcFrame) == 0 { // loop ends
if C.strlen(srcFrame) == 0 {
break
}
}
Expand Down
Loading

0 comments on commit 4e6dc1d

Please sign in to comment.