├── .gitignore
├── LICENSE
├── Makefile
├── README.md
├── docs
├── .gitignore
├── Makefile
├── Pipfile
├── Pipfile.lock
├── README.md
├── mkdocs.yml
└── src
│ ├── arch.md
│ ├── config.md
│ ├── expcap.md
│ ├── img
│ ├── .DS_Store
│ ├── exact-capture-arch.png
│ ├── exact-capture-eg-topo.png
│ ├── exact-capture-expcap-footer.png
│ ├── exact-capture-expcap-padding.png
│ ├── exact-capture-expcap.png
│ └── exact-capture-toolchain.png
│ ├── index.md
│ ├── install.md
│ ├── quick.md
│ ├── server.md
│ ├── tools
│ ├── analyze.md
│ ├── extract.md
│ ├── match.md
│ ├── modify.md
│ ├── overview.md
│ └── parse.md
│ ├── tuning.md
│ └── versions.md
├── libs
├── chaste
└── libchaste
│ ├── 60740670f7763b10d1b022c6d1709434b39c2a5d
│ ├── LICENSE
│ ├── README
│ ├── include
│ ├── asm
│ │ └── asm.h
│ ├── chaste.h
│ ├── data_structs
│ │ ├── array
│ │ │ ├── array.h
│ │ │ ├── array_std.h
│ │ │ ├── array_typed_declare_template.h
│ │ │ └── array_typed_define_template.h
│ │ ├── circular_queue
│ │ │ └── circular_queue.h
│ │ ├── function_hash_map
│ │ │ └── function_hash_map.h
│ │ ├── hash_map
│ │ │ └── hash_map.h
│ │ ├── linked_list
│ │ │ ├── linked_list.h
│ │ │ ├── linked_list_std.h
│ │ │ ├── linked_list_typed_declare_template.h
│ │ │ └── linked_list_typed_define_template.h
│ │ └── vector
│ │ │ ├── vector.h
│ │ │ ├── vector_std.h
│ │ │ ├── vector_typed_declare_template.h
│ │ │ └── vector_typed_define_template.h
│ ├── hash_functions
│ │ └── spooky
│ │ │ └── spooky_hash.h
│ ├── log
│ │ ├── log.h
│ │ └── log_levels.h
│ ├── makeinclude.sh
│ ├── options
│ │ ├── options.h
│ │ └── options_vectors.h
│ ├── parsing
│ │ ├── bool_parser.h
│ │ ├── numeric_parser.h
│ │ └── utils.h
│ ├── perf
│ │ ├── perf.h
│ │ └── perf_mon.h
│ ├── scripts
│ │ └── camio_prepare_boot.sh
│ ├── string
│ │ └── string.h
│ ├── sys
│ │ ├── sys.h
│ │ ├── sys_apple.h
│ │ └── sys_linux.h
│ ├── term_color
│ │ └── term_color.h
│ ├── timing
│ │ └── timestamp.h
│ ├── types
│ │ └── types.h
│ └── utils
│ │ ├── debug.h
│ │ └── util.h
│ └── libchaste.a
├── src
├── data_structs
│ ├── eiostream_vec.c
│ ├── eiostream_vec.h
│ ├── expcap.h
│ ├── pcap-structures.h
│ ├── pthread_vec.c
│ ├── pthread_vec.h
│ └── timespecps.h
├── exact-capture-listener.c
├── exact-capture-listener.h
├── exact-capture-writer.c
├── exact-capture-writer.h
├── exact-capture.c
├── exact-capture.h
├── exactio
│ ├── exactio.c
│ ├── exactio.h
│ ├── exactio_bring.c
│ ├── exactio_bring.h
│ ├── exactio_dummy.c
│ ├── exactio_dummy.h
│ ├── exactio_exanic.c
│ ├── exactio_exanic.h
│ ├── exactio_file.c
│ ├── exactio_file.h
│ ├── exactio_stream.h
│ ├── exactio_timing.c
│ └── exactio_timing.h
├── utils.c
└── utils.h
└── tools
├── checksum.h
├── data_structs
├── buff.c
├── buff.h
├── fusion_hpt.h
├── pcap_buff.c
├── pcap_buff.h
├── pseudo_ip_header.h
├── timespecps.h
└── vlan_ethhdr.h
├── exact-pcap-analyze.c
├── exact-pcap-extract.c
├── exact-pcap-match.c
├── exact-pcap-modify.c
├── exact-pcap-parse.c
├── utils.c
└── utils.h
/.gitignore:
--------------------------------------------------------------------------------
1 | bin/*
2 |
3 | # Prerequisites
4 | *.d
5 |
6 | # Object files
7 | *.o
8 | *.ko
9 | *.obj
10 | *.elf
11 |
12 | # Linker output
13 | *.ilk
14 | *.map
15 | *.exp
16 |
17 | # Precompiled Headers
18 | *.gch
19 | *.pch
20 |
21 | # Libraries
22 | *.lib
23 | *.la
24 | *.lo
25 |
26 | # Shared objects (inc. Windows DLLs)
27 | *.dll
28 | *.so
29 | *.so.*
30 | *.dylib
31 |
32 | # Executables
33 | *.exe
34 | *.out
35 | *.app
36 | *.i*86
37 | *.x86_64
38 | *.hex
39 |
40 | # Debug files
41 | *.dSYM/
42 | *.su
43 | *.idb
44 | *.pdb
45 |
46 | # Kernel Module Compile Results
47 | *.mod*
48 | *.cmd
49 | .tmp_versions/
50 | modules.order
51 | Module.symvers
52 | Mkfile.old
53 | dkms.conf
54 |
55 | #Build outputs
56 | bin/*
57 |
58 | #Eclipse settings files
59 | .settings/*
60 | .project
61 | .cproject
62 |
63 | # Emacs temp files
64 | *~
65 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | PREFIX=/usr/local
2 | CC=cc
3 | INCLUDES=-Ilibs -Isrc -I.
4 | LDFLAGS=libs/libchaste/libchaste.a
5 | GLOBAL_CFLAGS=-g -std=c99 -D_GNU_SOURCE -D_DEFAULT_SOURCE -D_XOPEN_SOURCE=700 -fPIC -Wno-missing-field-initializers -Wno-missing-braces
6 | RELEASE_CFLAGS=$(INCLUDES) $(GLOBAL_CFLAGS) -O3 -Wall -DNDEBUG -DNOIFASSERT
7 | ASSERT_CFLAGS=$(INCLUDES) $(GLOBAL_CFLAGS) -O3 -Wall -DNDEBUG
8 | DEBUG_CFLAGS=$(INCLUDES) $(GLOBAL_CFLAGS) -Werror -Wall -Wextra -pedantic
9 | BIN=bin/exact-capture
10 | TOOLS=bin/exact-pcap-extract bin/exact-pcap-parse bin/exact-pcap-match bin/exact-pcap-modify bin/exact-pcap-analyze
11 |
12 | EXACTCAP_SRCS=$(wildcard src/*.c) $(wildcard src/**/*.c)
13 | EXACTCAP_HDRS=$(wildcard src/*.h) $(wildcard src/**/*.h)
14 | LIBCHASTE_HDRS=$(wildcard libs/chaste/*.h) $(wildcard libs/chaste/**/*.h)
15 | BUFF_SRC=tools/data_structs/buff.c tools/data_structs/pcap_buff.c
16 | BUFF_HDRS=tools/data_structs/buff.h tools/data_structs/pcap_buff.h
17 |
18 | all: CFLAGS = $(RELEASE_CFLAGS)
19 | all: $(BIN) $(TOOLS)
20 |
21 | assert: CFLAGS = $(ASSERT_CFLAGS)
22 | assert: $(BIN) $(TOOLS)
23 |
24 | debug: CFLAGS = $(DEBUG_CFLAGS)
25 | debug: $(BIN) $(TOOLS)
26 |
27 | tools: CFLAGS= $(RELEASE_CFLAGS)
28 | tools: $(TOOLS)
29 |
30 | bin/exact-capture: $(EXACTCAP_SRCS) $(EXACTCAP_HDRS) $(LIBCASHTE_HDRS)
31 | mkdir -p bin
32 | $(CC) $(CFLAGS) $(EXACTCAP_SRCS) $(LDFLAGS) -lm -lexanic -lpthread -lrt -o $@
33 |
34 | bin/exact-pcap-parse: $(BUFF_SRC) $(BUFF_HDRS) tools/exact-pcap-parse.c $(EXACTCAP_HDRS) $(LIBCAHSTE_HDRS)
35 | mkdir -p bin
36 | $(CC) $(CFLAGS) $(BUFF_SRC) $(BUFF_HDRS) tools/exact-pcap-parse.c $(LDFLAGS) -o $@
37 |
38 | bin/exact-pcap-match: $(BUFF_SRC) $(BUFF_HDRS) tools/exact-pcap-match.c $(EXACTCAP_HDRS) $(LIBCAHSTE_HDRS)
39 | $(CC) $(CFLAGS) $(BUFF_SRC) $(BUFF_HDRS) tools/exact-pcap-match.c $(LDFLAGS) -o $@
40 |
41 | bin/exact-pcap-extract: $(BUFF_SRC) $(BUFF_HDRS) tools/exact-pcap-extract.c $(EXACTCAP_HDRS) $(LIBCAHSTE_HDRS)
42 | $(CC) $(CFLAGS) $(BUFF_SRC) $(BUFF_HDRS) tools/exact-pcap-extract.c $(LDFLAGS) -o $@
43 |
44 | bin/exact-pcap-analyze: $(BUFF_SRC) $(BUFF_HDRS) tools/exact-pcap-analyze.c tools/utils.c $(EXACTCAP_HDRS) $(LIBCAHSTE_HDRS)
45 | $(CC) $(CFLAGS) $(BUFF_SRC) $(BUFF_HDRS) tools/exact-pcap-analyze.c tools/utils.c $(LDFLAGS) -o $@
46 |
47 | bin/exact-pcap-modify: tools/exact-pcap-modify.c $(EXACTCAP_HDRS) $(LIBCAHSTE_HDRS)
48 | $(CC) $(CFLAGS) tools/exact-pcap-modify.c $(LDFLAGS) -o $@
49 |
50 | install: all install_tools
51 | install -d $(PREFIX)/bin
52 | install -m 0755 -D $(BIN) $(PREFIX)/bin
53 |
54 | install_tools: tools
55 | install -d $(PREFIX)/bin
56 | install -m 0755 -D $(TOOLS) $(PREFIX)/bin
57 |
58 | uninstall: uninstall_tools
59 | rm -f $(foreach file,$(BIN),$(PREFIX)/bin/$(file))
60 |
61 | uninstall_tools:
62 | rm -f $(foreach file,$(TOOLS),$(PREFIX)/bin/$(file))
63 |
64 | .PHONY: docs
65 | docs:
66 | $(MAKE) -C docs/
67 |
68 | clean:
69 | rm -rf bin/*
70 | $(MAKE) -C docs/ clean
71 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Exact Capture
2 | ## Lossless Packet Capture for ExaNICs
3 |
4 | Exact Capture is a high-rate, lossless packet capture solution for ExaNIC network adapters.
5 | The system is fully open source and designed for performance as well as ease of configuration.
6 | It can be used with any ExaNIC network card, and is optimised for use with ExaDisk high speed flash drives.
7 | The system can be deployed on any suitably powerful server system.
8 |
9 | Full online documentation is available [here](https://www.cisco.com/c/en/us/td/docs/dcn/nexus3550/exact-capture/sw/user-guide/exact-capture-user-guide/install.html)
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/docs/.gitignore:
--------------------------------------------------------------------------------
1 | #ignore the generated site
2 | site
3 |
4 |
--------------------------------------------------------------------------------
/docs/Makefile:
--------------------------------------------------------------------------------
1 | env = pipenv run
2 |
3 |
4 | all: docs
5 | .PHONY all:
6 |
7 |
8 | test:
9 | $(env) mkdocs serve
10 |
11 | publish:
12 | $(env) mkdocs gh-deploy
13 |
14 | docs:
15 | $(env) mkdocs build --clean
16 |
17 | clean:
18 | rm -rf site
19 |
20 |
--------------------------------------------------------------------------------
/docs/Pipfile:
--------------------------------------------------------------------------------
1 | [[source]]
2 | name = "pypi"
3 | url = "https://pypi.org/simple"
4 | verify_ssl = true
5 |
6 | [dev-packages]
7 |
8 | [packages]
9 | mkdocs = "*"
10 |
11 | [requires]
12 | python_version = "3"
13 |
--------------------------------------------------------------------------------
/docs/Pipfile.lock:
--------------------------------------------------------------------------------
1 | {
2 | "_meta": {
3 | "hash": {
4 | "sha256": "53f0dad17ad7f48f8daa50a9063cd498a5c01c1f1c808fec48ae82c2d031bd0b"
5 | },
6 | "pipfile-spec": 6,
7 | "requires": {
8 | "python_version": "3.6"
9 | },
10 | "sources": [
11 | {
12 | "name": "pypi",
13 | "url": "https://pypi.org/simple",
14 | "verify_ssl": true
15 | }
16 | ]
17 | },
18 | "default": {
19 | "click": {
20 | "hashes": [
21 | "sha256:2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13",
22 | "sha256:5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7"
23 | ],
24 | "version": "==7.0"
25 | },
26 | "jinja2": {
27 | "hashes": [
28 | "sha256:065c4f02ebe7f7cf559e49ee5a95fb800a9e4528727aec6f24402a5374c65013",
29 | "sha256:14dd6caf1527abb21f08f86c784eac40853ba93edb79552aa1e4b8aef1b61c7b"
30 | ],
31 | "version": "==2.10.1"
32 | },
33 | "livereload": {
34 | "hashes": [
35 | "sha256:78d55f2c268a8823ba499305dcac64e28ddeb9a92571e12d543cd304faf5817b",
36 | "sha256:89254f78d7529d7ea0a3417d224c34287ebfe266b05e67e51facaf82c27f0f66"
37 | ],
38 | "version": "==2.6.1"
39 | },
40 | "markdown": {
41 | "hashes": [
42 | "sha256:2e50876bcdd74517e7b71f3e7a76102050edec255b3983403f1a63e7c8a41e7a",
43 | "sha256:56a46ac655704b91e5b7e6326ce43d5ef72411376588afa1dd90e881b83c7e8c"
44 | ],
45 | "version": "==3.1.1"
46 | },
47 | "markupsafe": {
48 | "hashes": [
49 | "sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473",
50 | "sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161",
51 | "sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235",
52 | "sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5",
53 | "sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff",
54 | "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b",
55 | "sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1",
56 | "sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e",
57 | "sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183",
58 | "sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66",
59 | "sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1",
60 | "sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1",
61 | "sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e",
62 | "sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b",
63 | "sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905",
64 | "sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735",
65 | "sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d",
66 | "sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e",
67 | "sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d",
68 | "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c",
69 | "sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21",
70 | "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2",
71 | "sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5",
72 | "sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b",
73 | "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6",
74 | "sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f",
75 | "sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f",
76 | "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7"
77 | ],
78 | "version": "==1.1.1"
79 | },
80 | "mkdocs": {
81 | "hashes": [
82 | "sha256:17d34329aad75d5de604b9ed4e31df3a4d235afefdc46ce7b1964fddb2e1e939",
83 | "sha256:8cc8b38325456b9e942c981a209eaeb1e9f3f77b493ad755bfef889b9c8d356a"
84 | ],
85 | "index": "pypi",
86 | "version": "==1.0.4"
87 | },
88 | "pyyaml": {
89 | "hashes": [
90 | "sha256:0113bc0ec2ad727182326b61326afa3d1d8280ae1122493553fd6f4397f33df9",
91 | "sha256:01adf0b6c6f61bd11af6e10ca52b7d4057dd0be0343eb9283c878cf3af56aee4",
92 | "sha256:5124373960b0b3f4aa7df1707e63e9f109b5263eca5976c66e08b1c552d4eaf8",
93 | "sha256:5ca4f10adbddae56d824b2c09668e91219bb178a1eee1faa56af6f99f11bf696",
94 | "sha256:7907be34ffa3c5a32b60b95f4d95ea25361c951383a894fec31be7252b2b6f34",
95 | "sha256:7ec9b2a4ed5cad025c2278a1e6a19c011c80a3caaac804fd2d329e9cc2c287c9",
96 | "sha256:87ae4c829bb25b9fe99cf71fbb2140c448f534e24c998cc60f39ae4f94396a73",
97 | "sha256:9de9919becc9cc2ff03637872a440195ac4241c80536632fffeb6a1e25a74299",
98 | "sha256:a5a85b10e450c66b49f98846937e8cfca1db3127a9d5d1e31ca45c3d0bef4c5b",
99 | "sha256:b0997827b4f6a7c286c01c5f60384d218dca4ed7d9efa945c3e1aa623d5709ae",
100 | "sha256:b631ef96d3222e62861443cc89d6563ba3eeb816eeb96b2629345ab795e53681",
101 | "sha256:bf47c0607522fdbca6c9e817a6e81b08491de50f3766a7a0e6a5be7905961b41",
102 | "sha256:f81025eddd0327c7d4cfe9b62cf33190e1e736cc6e97502b3ec425f574b3e7a8"
103 | ],
104 | "version": "==5.1.2"
105 | },
106 | "six": {
107 | "hashes": [
108 | "sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c",
109 | "sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73"
110 | ],
111 | "version": "==1.12.0"
112 | },
113 | "tornado": {
114 | "hashes": [
115 | "sha256:349884248c36801afa19e342a77cc4458caca694b0eda633f5878e458a44cb2c",
116 | "sha256:398e0d35e086ba38a0427c3b37f4337327231942e731edaa6e9fd1865bbd6f60",
117 | "sha256:4e73ef678b1a859f0cb29e1d895526a20ea64b5ffd510a2307b5998c7df24281",
118 | "sha256:559bce3d31484b665259f50cd94c5c28b961b09315ccd838f284687245f416e5",
119 | "sha256:abbe53a39734ef4aba061fca54e30c6b4639d3e1f59653f0da37a0003de148c7",
120 | "sha256:c845db36ba616912074c5b1ee897f8e0124df269468f25e4fe21fe72f6edd7a9",
121 | "sha256:c9399267c926a4e7c418baa5cbe91c7d1cf362d505a1ef898fde44a07c9dd8a5"
122 | ],
123 | "version": "==6.0.3"
124 | }
125 | },
126 | "develop": {}
127 | }
128 |
--------------------------------------------------------------------------------
/docs/README.md:
--------------------------------------------------------------------------------
1 | # Exact Capture Documentation
2 | -----------------------------
3 |
4 | ## mkdocs
5 | Exact capture documentation is written using (mkdocs)[https://www.mkdocs.org/].
6 | All of the documentation pages can be found in markdown format in the `src` directory.
7 | Configuration for mkdocs is found in `mkdocs.yml`.
8 |
9 | ## Requirements
10 | - python3
11 | - pipenv
12 | - mkdocs
13 |
14 | Python2 is now deprecated, with end of support as of 2019.
15 | Python3 has been around for over 10 years, so it's time to move on to Python3.
16 |
17 | To ensure a consistent output, the build process uses `pipenv`.
18 | Settings for pipenv can be found in the `Pipfile` and `Pipfile.lock`
19 |
20 | To install `python3`, run (on Fedora/RedHat/Centos systems)
21 | ```
22 | $ sudo yum install python3
23 | ```
24 |
25 | or (on Debian/Ubuntu systems)
26 |
27 | ```
28 | $ sudo apt install python3
29 | ```
30 |
31 |
32 | To install `pip`, run
33 | ```
34 | $ curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
35 | $ sudo python get-pip.py
36 | ```
37 |
38 | To install `pipenv` run
39 | ```
40 | $ sudo pip install pipenv
41 | ```
42 | **Note**
43 | -----------------
44 | The following error is common on Ubuntu based systems:
45 |
46 | ```
47 | import distutils.spawn
48 | ModuleNotFoundError: No module named 'distutils.spawn'
49 |
50 | Failed to create virtual environment.
51 | ```
52 |
53 | To resolve you need to install `python3-distuilts`.
54 | You can do this as follows:
55 | ```
56 | $ sudp apt-get install python3-distutils
57 | ```
58 | -----------------
59 |
60 |
61 | To install `mkdocs` run (inside the exact-capture documentation directory)
62 | ```
63 | ~/exact-capture/docs $ sudo pipenv install mkdocs
64 | ```
65 |
66 |
67 | ## Building
68 | Pipenv is called directly from the makefile. To build simply run:
69 |
70 | ```
71 | $ make
72 | pipenv run mkdocs build --clean
73 | INFO - Cleaning site directory
74 | INFO - Building documentation to directory: /home/exact-cap/exact-capture/docs/site
75 | ```
76 |
77 | ## Testing
78 | mkdocs ships with a built in server for local testing and viewing of the rendered output.
79 | To test, run:
80 |
81 | ```
82 | $ make test
83 | pipenv run mkdocs serve
84 | INFO - Building documentation...
85 | INFO - Cleaning site directory
86 | [I 191002 17:56:22 server:296] Serving on http://127.0.0.1:8000
87 | [I 191002 17:56:22 handlers:62] Start watching changes
88 | [I 191002 17:56:22 handlers:64] Start detecting changes
89 | ```
90 |
91 | Connecting your browser to `127.0.0.1:8000` should show the fully rendered page.
92 |
--------------------------------------------------------------------------------
/docs/mkdocs.yml:
--------------------------------------------------------------------------------
1 | site_name: Exact Capture Documentation
2 | site_url: http://exact-capture.io
3 | theme:
4 | name: readthedocs
5 | highlightjs: true
6 |
7 | docs_dir: src
8 |
9 | nav:
10 | - Exact Capture:
11 | - Introduction: index.md
12 | - Installation: install.md
13 | - Quick Start: quick.md
14 | - Server Requirements: server.md
15 | - Configuration Guide: config.md
16 | - Performance Tuning: tuning.md
17 | - Output Format (expcap): expcap.md
18 | - Internal Architecture: arch.md
19 | - Tools:
20 | - Overview: tools/overview.md
21 | - Exact PCAP Extract: tools/extract.md
22 | - Exact PCAP Modify: tools/modify.md
23 | - Exact PCAP Match: tools/match.md
24 | - Exact PCAP Parse: tools/parse.md
25 | - Exact PCAP Analyze: tools/analyze.md
26 | - Version History: versions.md
27 |
28 | markdown_extensions:
29 | - markdown.extensions.admonition
30 | - markdown.extensions.fenced_code
31 |
32 | plugins:
33 | - search
34 |
--------------------------------------------------------------------------------
/docs/src/arch.md:
--------------------------------------------------------------------------------
1 | The Exact Capture software system comprises 4 major internal components:
2 |
3 | 1. One or more “hot” threads - to read packets from the ExaNIC(s) into memory
4 | 2. One or more “cold” threads - to write packets from memory to disk(s)
5 | 3. One or more shared memory queues - to connect the hot and cold threads to each other
6 | 4. One management thread - responsible for control and statistics collection / reporting
7 |
8 | These basic architectural components are illustrated below, with the addition of the ExaNIC and ExaDisk resources.
9 | The head of each column highlights the performance limiting resource for that component:
10 |
11 | 
12 |
13 |
--------------------------------------------------------------------------------
/docs/src/expcap.md:
--------------------------------------------------------------------------------
1 | Exact Capture outputs packet captures to a modified `pcap` format called `expcap`.
2 | The `expcap` format is a backwards compatible extension to standard `pcap` format.
3 | A number of [tools and utilities](tools/overview.md) are included for operating on these files, including converting them into standard `pcap` format if necessary.
4 |
5 | For reference, standard `pcap` files are formatted as follows (more details can be found on the [Wireshark](https://wiki.wireshark.org/Development/LibpcapFileFormat) website):
6 |
7 | 
8 |
9 |
10 | ## Padding Packets
11 | As a performance optimisation, Exact Capture occasionally needs to insert padding packets (e.g. to align to a 4k boundary) into the output file.
12 | These packets are easily recognizable because `pcap` header wire length field (as above) is set to 0B, with the on disk length field (again as above) is set to the size of the padding.
13 |
14 | Although setting these header fields precisely captures the semantics of the padding packets (i.e bytes written to disk that were never found on the wire), this is technically a `pcap` file specification violation.
15 | Presumably the writers never envisaged this kind of use case.
16 | Nevertheless, standard tools like `Wireshark` operate correctly and ignore these packets as they should.
17 |
18 | The following figure depicts a padding packet directly after the file header.
19 | This will be found in all Exact Capture output files.
20 |
21 | 
22 |
23 |
24 | ## Packet Footers
25 | Each captured packet is extended with a packet footer.
26 | This footer contains a variety of extra fields, not available in the standard pcap format. When the footer is added, the standard pcap disk bytes field is updated to reflect the extra length on disk. Once again, this means that the byes on disk value may exceed the bytes on the wire value (though not always. e.g. when a snaplength is set). The addition of a footer adds bytes to the disk that were never found on the wire is again, technically a PCAP specification violation. However, once again, standard pcap processing tools like Wireshark operate correctly and ignore these extra bytes as they should. The above figure shows a representation of expcap packet footers added to the first packet.
27 |
28 | 
29 |
30 | The additional expcap footer fields are described in detail in the table below. They borrow the spirit of some of the fields found in the ERF format.
31 |
32 |
33 |
34 |
35 |
36 | Field |
37 | Width (bits) |
38 | Description |
39 |
40 |
41 | Time (seconds) |
42 | 32 |
43 |
44 | Time in seconds since the epoch
45 | |
46 |
47 |
48 | Time (picoseconds) |
49 | 40 |
50 |
51 | Time in picoseconds since the last second boundary
52 | |
53 |
54 |
55 | Flags |
56 | 8 |
57 |
58 | The following flags bits are currently supported:
59 |
60 |
61 | - New CRC Calculated (The CRC field contains a new new value including the footer)
62 | - Frame aborted - this frame was aborted on the wire by the sender.
63 | - Frame corrupt - the hardware CRC checker detected an error with this frame.
64 | - Frame truncated - this packet was longer than the snap length and has been truncated.
65 |
66 | |
67 |
68 |
69 | Device ID Number |
70 | 8 |
71 |
72 | The ID of the device that captured these packets.
73 | For example, when capturing on the exanic3:7 interface, the device number would be 3.
74 | |
75 |
76 |
77 | Port ID Number |
78 | 8 |
79 |
80 | The port on the device that was used to capture the packet.
81 | For example, capturing on exanic3:7 interface, the port number would be 7.
82 | |
83 |
84 |
85 | CRC top |
86 | 16 |
87 |
88 | If the new CRC flag is not set, contains the number of packets dropped between this packet and the previous packet.
89 | Otherwise this is the top 16 bits of the new CRC.
90 | |
91 |
92 |
93 | CRC bottom |
94 | 16 |
95 |
96 | If the new CRC flag is set, contains the bottom 16 bits of the new CRC. Otherwise, unused.
97 | |
98 |
99 |
100 |
--------------------------------------------------------------------------------
/docs/src/img/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cisco/exact-capture/2a7b74e66cbbafcec7c39947dea63bec03972685/docs/src/img/.DS_Store
--------------------------------------------------------------------------------
/docs/src/img/exact-capture-arch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cisco/exact-capture/2a7b74e66cbbafcec7c39947dea63bec03972685/docs/src/img/exact-capture-arch.png
--------------------------------------------------------------------------------
/docs/src/img/exact-capture-eg-topo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cisco/exact-capture/2a7b74e66cbbafcec7c39947dea63bec03972685/docs/src/img/exact-capture-eg-topo.png
--------------------------------------------------------------------------------
/docs/src/img/exact-capture-expcap-footer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cisco/exact-capture/2a7b74e66cbbafcec7c39947dea63bec03972685/docs/src/img/exact-capture-expcap-footer.png
--------------------------------------------------------------------------------
/docs/src/img/exact-capture-expcap-padding.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cisco/exact-capture/2a7b74e66cbbafcec7c39947dea63bec03972685/docs/src/img/exact-capture-expcap-padding.png
--------------------------------------------------------------------------------
/docs/src/img/exact-capture-expcap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cisco/exact-capture/2a7b74e66cbbafcec7c39947dea63bec03972685/docs/src/img/exact-capture-expcap.png
--------------------------------------------------------------------------------
/docs/src/img/exact-capture-toolchain.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cisco/exact-capture/2a7b74e66cbbafcec7c39947dea63bec03972685/docs/src/img/exact-capture-toolchain.png
--------------------------------------------------------------------------------
/docs/src/index.md:
--------------------------------------------------------------------------------
1 | Exact Capture is a high-rate, lossless packet capture solution for ExaNIC network adapters.
2 | The system is fully open source and designed for performance as well as ease of configuration.
3 | It can be used with any ExaNIC network adapter, and is optimised for use with ExaDISK high speed NVMe SSDs.
4 | The system can be deployed on any suitably powerful server system.
5 |
6 | This manual covers full details on configuring and operating Exact Capture including:
7 |
8 | * [Quick start guide](quick.md)
9 | * [Installing and building](install)
10 | * [Hardware requirements](server.md)
11 | * [Configuration options](config.md)
12 | * [Version history](versions.md)
13 |
--------------------------------------------------------------------------------
/docs/src/install.md:
--------------------------------------------------------------------------------
1 | ## Source Code and Licensing
2 | Exact Capture is available from [github.com](https://github.com/exablaze-oss/exact-capture) as an open source project.
3 | If you would like to discuss alternative licensing schemes, please contact the Exablaze sales team.
4 |
5 | ## Hardware Requirements
6 | Exact Capture requires a high performance server to operate optimally.
7 | Please read the [Server Requirements](server.md) for more details.
8 |
9 | ## Software Requirements
10 | To build the software, you will need a recent C compiler supporting C99 or higher, and to have installed the ExaNIC software libraries (also available from github.com).
11 |
12 | ##Building
13 | There are 3 build options for Exact Capture:
14 |
15 | 1. Performance build
16 | 2. Error assertions build
17 | 3. Debug build
18 |
19 | By default, Exact Capture is built in performance mode.
20 | In performance mode, unnecessary internal error checking is disabled.
21 | For example, bounds checks on memory access.
22 | To build Exact Capture in performance mode, simply run `make` in the top level.
23 |
24 | To build a version with stricter internal error checking assertions, run `make assert`.
25 | This version is still capable of operating at 10Gb/s on many systems, though will suffer marginal performance degradation, especially on slower CPUs.
26 |
27 | To build a debug version, run `make debug`.
28 | The debug build applies stricter warning checking requirements at build time, and enables detailed debug tracing throughout the application.
29 | This version is unlikely to keep up at high-rate.
30 |
31 | ## (un)Installation
32 | To install Exact Capture, run `make install` as the root user. To uninstall, run `make uninstall` as the root user.
33 |
--------------------------------------------------------------------------------
/docs/src/quick.md:
--------------------------------------------------------------------------------
1 | To run Exact Capture on a single 10GbE interface, writing to a single disk slice, the following command line is sufficient:
2 |
3 | ```bash
4 | $ exact-capture --input=exanic0:0 --output=/data0/ --cpus=0:1:2
5 | ```
6 |
7 | !!! note
8 | Canonical Linux interface names such as “eth1” or “enp0s1” can be freely used in place of Exablaze ExaNIC device names (e.g. “exanic0:0”).
9 | The interface must however be an ExaNIC.
10 |
11 | !!! note
12 | The CPU specification is a colon (“:”) separated list containing the management CPU, the ExaNIC listener thread CPU(s), and the ExaDisk writer thread CPU(s).
13 | It is assumed that CPU cores have been isolated according to the System Configuration instructions above.
14 | For more details see [configuration options](config.md#cpus)
15 |
16 | To run exact capture on a pair of 10GbE interfaces, writing to a two disk slices, using 5 cpu cores (management core = 0, NIC listener cores = 1,2, disk writer cores = 3,4):
17 |
18 | ```bash
19 | $ exact-capture --input=exanic0:0 --input=exanic0:1 --output=/data0/ --output=/data1/ --cpus=0:1,2:3,4
20 | ```
21 |
--------------------------------------------------------------------------------
/docs/src/server.md:
--------------------------------------------------------------------------------
1 | You are free to run Exact Capture on any system hardware.
2 | The following table describes our recommendations for the minimum system hardware requirements.
3 | For general guidance, we have successfully run the system on suitably configured Dell R230 and R730 machines.
4 | Any of the Dell R*30 and R*40 machines are likely to be excellent candidates.
5 |
6 | ## CPUs
7 | Core Count
8 | The number of CPU cores required depends on:
9 |
10 | 1. The number of interfaces that you wish to capture on
11 | 2. The type and speed of the disk drives
12 | 3. The maximum capture rate you need to sustain
13 |
14 | Assuming that **ExaDisks** are the target drives, each drive slice is capable of writing at a sustained rate of 10Gb/s.
15 |
16 | As an example, a minimal 10Gb/s Exact Capture installation will require 3 CPU cores.
17 | One core for a (hot) listener thread, one core for a (cold) disk writer thread and one management core.
18 | The management core is low priority and can be safely shared with other general purpose system cores.
19 | The listener thread should not be shared with any other process (i.e. be sure to make use of the isolcpus kernel parameter).
20 |
21 | In general, for n line-rate 10G ports, the system requires 2n + 1 CPU cores. e.g a 4x10G capture system will require 9 cores in total.
22 |
23 | !!! warning
24 | CPU core counts are based on actual cores, rather than hyperthreads.
25 | In general, we recommend disabling hyperthreads on CPUs that support them.
26 |
27 | !!! tip
28 | We have had good results with Intel Xeon E5-26xx range CPUs with a 3Ghz+ clock speed. For example the Intel Xeon E5-2643.
29 |
30 |
31 | Speed
32 | The minimum required CPU speed depends on the maximum capture rate required.
33 | For the purposes of this document, we assume that 10G line rate, at minimum sized (64B) frames is the capture rate requirement (i.e. approx. 14 million packets per second ).
34 |
35 | !!! tip
36 | We have found that 3Ghz+ CPUs are sufficient.
37 |
38 |
39 | ##RAM
40 | RAM usage will vary based on the number of NICs and disks that you are using.
41 | By default, each memory queue is organised into 256x 2MB slots for a total memory usage of approximately 512MB per queue.
42 | The total number of memory queues the product of the number of hot (ExaNIC) and cold (ExaDisk) threads.
43 | For a minimal 10Gb/s capture solution, with a single ExaNIC and ExaDisk, only 1 memory queue is required for a total of approximately 512MB of memory.
44 | For 4x10Gbs system, with 4 disks, 4x4 = 16 queues will be required, for a minimum memory usage of ~8GB.
45 |
46 | !!! tip
47 | We recommend at least 16GB of DDR IV RAM in your machine.
48 |
49 |
50 | ##PCIe
51 | For sustained, minimum sized packet capture, each 10Gb/s ExaNIC interface requires approximately 4x PCIe Gen 3 lanes.
52 | The hot threads must run on the CPU socket directly connected to these PCIe lanes.
53 |
54 | For sustained high performance writing, each ExaDisk interface requires 2x PCIe Gen 3 lanes.
55 | The cold threads must run on the CPU socket directly connected to these PCIe lanes.
56 |
57 | !!! tip
58 | For optimal performance, w recommend running PCIe Gen3x8 for all cards connected.
59 |
60 |
61 | ##ExaNIC
62 | All ExaNIC network cards will work with Exact Capture.
63 | Following is a summary of the features, requirements and limitations of each card:
64 |
65 | - **ExaNIC X10 / GM (2x 10GbE)** - these cards can be used without restriction on suitable PCIe Gen 3x8 slots.
66 | Timestamp resolution is 6.2ns.
67 | - **ExaNIC HPT (2x 10GbE)** - these cards can be used without restriction on suitable PCIe Gen 3x8 slots.
68 | Timestamp resolution is 0.25ns (250ps)
69 | - **ExaNIC X40 / VXP (8x 10GbE)** - Only 2 ports can be used at line rate for all packet sizes. Up to 4 ports can be used at larger (average) packet sizes (e.g. 512B+).
70 | Timestamp resolution is 6.2ns.
71 | - **ExaNIC X40 (2x 40GbE)** - Speeds up to 20Gb/s are likely to work out of the box on any single interface (though this is untested).
72 | Load balancing/packet spraying across multiple receive rings is also likely to assist line rate capture, though this is feature is not (yet) implemented.
73 |
74 | !!! tip
75 | ExaNIC X10 and ExaNIC HPT devices are currently optimal.
76 |
77 |
78 |
79 | ##Disk Drives
80 | Exact Capture is tested and optimized to run on *ExaDisk FX1* NVMe SSD drives.
81 | Each ExaDisk is capable of running 40Gb/s sustained write speed to disk in a PCIe Gen 3x 8 slot.
82 | The drives are currently available in 4TB and 8TB capacities.
83 |
84 | The system will (in principle) operate with any disks.
85 | High speed flash drives, especially NVMe disks are highly recommended to keep the number of threads and memory usage down.
86 | For slower disks (e.g. SATA based flash disks) sharing CPU cores for writer threads is likely to reduce the CPU core count requirements without affecting overall performance.
87 | This is untested.
88 |
89 | !!! tip
90 | ExaDISK FX1 (8TB) is the recommended disk drive
91 |
--------------------------------------------------------------------------------
/docs/src/tools/analyze.md:
--------------------------------------------------------------------------------
1 | # Exact PCAP Analyze
2 |
3 | Exact PCAP analyze (`exact-pcap-analyze`) is a tool used to analyze `.pcap` files and derive a number of statistics concerning a given capture.
4 | It will determine the total length of the capture (in nanoseconds, microseconds and seconds), the average packet rate (in pps, packets per second), the minimum/maximum inter-frame gaps (IFGs) and the throughput rate (in gigabits per second).
5 |
6 | The following table lists all commands available:
7 |
8 |
9 |
10 | Short |
11 | Long |
12 | Default |
13 | Description |
14 |
15 |
16 | i |
17 | input |
18 | (required) |
19 |
20 | The input .pcap file to analyze.
21 | |
22 |
23 |
24 | f |
25 | format |
26 | (required) |
27 |
28 | The input file format. Valid values are pcap or expcap .
29 | |
30 |
31 |
32 | r |
33 | line-rate |
34 | (required) |
35 |
36 | The line rate of traffic in the input capture. This value is in Gbps, e.g. 10 = 10Gb/s.
37 | |
38 |
39 |
40 | o |
41 | offset |
42 | 0 |
43 |
44 | Start analyzing packets from this packet offset into the input file.
45 | |
46 |
47 |
48 | m |
49 | max |
50 | -1 (no limit) |
51 |
52 | Limit the number of packets to analyze.
53 | |
54 |
55 |
56 | w |
57 | window |
58 | 100 |
59 |
60 | Analyze packets within this window. Analysis occurs each time this window is exceeded in the input capture.
61 | |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/docs/src/tools/extract.md:
--------------------------------------------------------------------------------
1 | # Exact Extract
2 |
3 | Exact Extract is a utility that extracts packets from one or more expcap files and writes them out into a user-specified format. It outputs capture files that are
4 | ordered by the expcap timestamps present in the original capture.
5 |
6 | ```bash
7 | $ exact-pcap-extract -i cap0-0.expcap -w extracted -a -f expcap
8 | ```
9 |
10 | !!! Note
11 | Exact Extract can take multiple expcap files as its input. It will search for the earliest timestamp in all of the input capture files.
12 | This means that the first packet written out will be the packet with the earliest timestamp across all of the input files.
13 |
14 | The following table lists all commands available:
15 |
16 |
17 |
18 | Short |
19 | Long |
20 | Default |
21 | Description |
22 |
23 |
24 | i |
25 | input |
26 | (required) |
27 |
28 | The expcap files to extract packets from.
29 | |
30 |
31 |
32 | w |
33 | write |
34 | (required) |
35 |
36 | The filename used for extracted packets. Exact Extract will automatically append .pcap to the filename.
37 | |
38 |
39 |
40 | W |
41 | write-dir |
42 | (none) |
43 |
44 | The directory used to write extracted packets. If used in conjunction with '--write', packets are extracted to {write-dir}/{write}.pcap.
45 | It must be specified if steering options (--steer) are in use.
46 | |
47 |
48 |
49 | p |
50 | port |
51 | -1 |
52 |
53 | Only extract packets that were captured on the specified port number. If this is not specified and '--device' is not set, the user must use '--all' to
54 | extract packets that were captured on all ports.
55 | |
56 |
57 |
58 | d |
59 | device |
60 | -1 |
61 |
62 | Only extract packets that were captured on the specified device number (i.e., 0 corresponds to exanic0). If this is not specified and '--port' is not
63 | set, the user must use '--all' to extract packets that were captured on all ports.
64 | |
65 |
66 |
67 | a |
68 | all |
69 | (flag) |
70 |
71 | Extract packets that were captured on all ports and all devices. This flag must be set if neither '--port' or '--device' are specified.
72 | |
73 |
74 |
75 | f |
76 | format |
77 | expcap |
78 |
79 | The file format to use when writing out packets. Valid options are 'pcap' and 'expcap'.
80 | |
81 |
82 |
83 | c |
84 | count |
85 | 0 (no limit) |
86 |
87 | The maximum number of files to write out in total.
88 | |
89 |
90 |
91 | M |
92 | maxfile |
93 | 0 (128MB) |
94 |
95 | The maximum file size for output files, in MB. Output files will never exceed 128MB, regardless of the value specified with this option.
96 | If the output must be spread over multiple files, Exact Extract will append _n to the filename, where n is the current segment being written out
97 | (starting from 1).
98 | |
99 |
100 |
101 | u |
102 | usepcap |
103 | (flag) |
104 |
105 | If set, Exact Extract will write pcap timestamps in the microsecond format.
106 | |
107 |
108 |
109 | S |
110 | snaplen |
111 | 1518 |
112 |
113 | The limit in bytes for each individual packet in the output file.
114 | |
115 |
116 |
117 | r |
118 | skip-runts |
119 | (flag) |
120 |
121 | If this flag is set, runt frames will not be written to the output
122 | |
123 |
124 |
125 | D |
126 | allow-duplicates |
127 | (flag) |
128 |
129 | By default, Exact Extract will write over files which have the same name as specified by '--write'. If this flag is set, it will instead create a file
130 | with a duplicate name, and append __n to the duplicate file, where n is the current number of files with the same name.
131 | |
132 |
133 |
134 | t |
135 | hpt-trailer |
136 | (flag) |
137 |
138 | If this flag is set, Exact Extract will assume that each packet terminates in a Fusion HPT timestamp trailer. It will extract the timestamp from this
139 | trailer and write it to the pcap header (in microsecon/nanosecond format) and to the expcap trailer (in picosecond format) for all output files.
140 |
Note: this option assumes all packets in the input captures have Fusion HPT trailers. If this is not
141 | true, the pcap/expcap timestamp fields will contain invalid values in the output file(s).
142 | |
143 |
144 |
145 | s |
146 | steer |
147 | (null) |
148 |
149 | --steer accepts one of the following values as valid options: hpt, vlan, expcap.
150 | A directory must be specified when using this option (via '--write-dir')
151 | If this option is set, Exact Extract will steer packets to separate files depending upon their content.
152 |
153 | Specifying '--steer vlan' will cause packets to be steered to separate files depending upon their VLAN ID. For example, packets with VLAN ID 100 will
154 | be steered to the file {write-dir}/{write}_vlan_100.pcap. Packets which do not have an 8021.Q tag will be written to the file named
155 | {write-dir}/{write}.pcap.
156 |
157 | Specifying '--steer hpt' will cause packets to be steered to separate files depending upon their Fusion HPT trailer, using the device ID and port
158 | number. For example, files with device ID 0 and port number 10 will be steered to the file {write-dir}/{write}_device_0_port_10.pcap.
159 | Note: use of this option assumes that all packets in the input file(s) have a Fusion HPT trailer.
160 |
161 | Specifying '--steer expcap' will cause packets to be steered to separate files depending upon their expcap footer, using the device ID and port
162 | number. For example, files with device ID 0 and port number 10 will be steered to the file {write-dir}/{write}_device_0_port_10.pcap.
163 | Note: use of this option assumes that all packets in the input file(s) have an expcap footer.
164 | |
165 |
166 |
167 |
168 | !!! Note
169 | Depending upon the options specified by, Exact Extract may attempt to keep more files open simultaneously than is allowed the OS.
170 | If it is unable to override this limit, it will need to close and open outputs each time a packet is written in order to ensure that it does not exceed this limit.
171 | This can degrade the performance of Exact Extract, due to the additional overhead of repeatedly opening and closing output files.
172 |
173 | On Linux, it is possible to override the number of open file descriptors limit by giving Exact Extract the "CAP_SYS_RESOURCE" capability to the binary.
174 | This can be accomplished by running:
175 |
176 | ```
177 | $ sudo setcap cap_sys_resouce+ep exact-pcap-extract
178 | ```
179 |
180 | The full list of permissions granted by CAP_SYS_RESOURCE is available on the [capabilities(7)](https://man7.org/linux/man-pages/man7/capabilities.7.html)
181 | man page. Granting Exact Extract this permission should improve its performance, however it is not a requirement. Users will receive the warning "Could not
182 | raise the limit on concurrently open files" if they are exceeding the open file limit.
--------------------------------------------------------------------------------
/docs/src/tools/match.md:
--------------------------------------------------------------------------------
1 | # Exact PCAP Match
2 |
3 | Exact PCAP Match (`exact-pcap-match`) is a tool used to match packets in two separate files.
4 | It outputs timestamps, timestamp deltas (latency) and the packet data of matched packets in a `.csv` file.
5 |
6 | Where timestamp deltas are shown, they are produced from `reference_file.timestamp minus input_file.timestamp`.
7 |
8 | The following table lists all commands available:
9 |
10 |
11 |
12 | Short |
13 | Long |
14 | Default |
15 | Description |
16 |
17 |
18 | r |
19 | reference |
20 | (required) |
21 |
22 | The reference file to use for matching.
23 | |
24 |
25 |
26 | i |
27 | input |
28 | (required) |
29 |
30 | The file to compare against the reference file.
31 | |
32 |
33 |
34 | c |
35 | csv |
36 | (required) |
37 |
38 | The .csv file to write matching packet statistics to.
39 | |
40 |
41 |
42 | R |
43 | ref-miss |
44 | (optional) |
45 |
46 | The .csv file to store reference packet misses.
47 | These are packets which were present in the reference file but were not found in the input file.
48 | |
49 |
50 |
51 | I |
52 | inp-miss |
53 | (optional) |
54 |
55 | The .csv file to store input packet misses.
56 | These are packets which were present in the input file but were not found in the reference file.
57 | |
58 |
59 |
60 | f |
61 | format |
62 | (required) |
63 |
64 | The input file format. Valid values are pcap or expcap .
65 | |
66 |
67 |
68 | O |
69 | offset-ref |
70 | 0 |
71 |
72 | Start matching packets in the reference file from this packet offset onwards.
73 | |
74 |
75 |
76 | o |
77 | offset-inp |
78 | 0 |
79 |
80 | Start matching packets in the input file from this packet offset onwards.
81 | |
82 |
83 |
84 | M |
85 | max-ref |
86 | -1 (no limit) |
87 |
88 | Limit the amount of packets in the reference file to match.
89 | |
90 |
91 |
92 | n |
93 | num-chars |
94 | 64 |
95 |
96 | The number of bytes from matched packets to output in the packet data field of the .csv file.
97 | |
98 |
99 |
100 | v |
101 | verbose |
102 | (flag) |
103 |
104 | Enables verbose output printing.
105 | |
106 |
107 |
108 |
--------------------------------------------------------------------------------
/docs/src/tools/modify.md:
--------------------------------------------------------------------------------
1 | # Exact PCAP Modify
2 |
3 | Exact PCAP Modify (`exact-pcap-modify`) is a tool which can be used to filter and modify Ethernet packets.
4 | Where modifications occur which would invalidate a checksum, Exact PCAP Modify will recalculate a correct checksum in the output file.
5 |
6 | It can perform modify/filter operations on the following fields:
7 |
8 | * Ethernet header:
9 | * Destination MAC address (DST MAC)
10 | * Souce MAC address (SRC MAC)
11 | * 8021.Q tag:
12 | * VLAN ID
13 | * IPv4 header:
14 | * Source address (SRC IP)
15 | * Destination address (DST IP)
16 | * Time-to-live (IP TTL)
17 | * UDP/TCP headers:
18 | * Source port (SRC PORT)
19 | * Destination port (DST PORT)
20 |
21 | ```
22 | $ exact-pcap-modify -i capture.pcap -f expcap -w modified -a 1.1.1.1,2.2.2.2
23 | ```
24 |
25 | # Configuration
26 |
27 | Options which operate on the fields of a header are to be supplied in the form filter,modify
.
28 | For example, if Exact PCAP Modify should filter a capture such that only packets with the SRC IP of 1.1.1.1 are present written to the output, it should be invoked with the `--src-ip 1.1.1.1` option.
29 |
30 | If the user wishes to modify all packets which have the SRC IP 1.1.1.1 to produce an output where the SRC IP becomes 2.2.2.2, it should be invoked with the `--src-ip 1.1.1.1,2.2.2.2` option.
31 |
32 | When multiple filters are used, packets will need to match **all** of the specified filters to be present in the output capture.
33 |
34 | The following table lists all commands available:
35 |
36 |
37 |
38 | Short |
39 | Long |
40 | Default |
41 | Description |
42 |
43 |
44 | i |
45 | input |
46 | (required) |
47 |
48 | The .pcap /.expcap file to filter/modify.
49 | |
50 |
51 |
52 | w |
53 | write |
54 | (required) |
55 |
56 | The destination file where packets which match the specified filter will be written to.
57 | |
58 |
59 |
60 | W |
61 | write-filtered |
62 | (optional) |
63 |
64 | The destination file where all packets which do not match all specified filters will be written to.
65 | |
66 |
67 |
68 | v |
69 | verbose |
70 | (flag) |
71 |
72 | Enables verbose output printing.
73 | |
74 |
75 |
76 | f |
77 | format |
78 | expcap |
79 |
80 | The file format to use when writing out packets. Valid options are .pcap and .expcap .
81 | |
82 |
83 |
84 | o |
85 | offset |
86 | 0 |
87 |
88 | Jump to the specified packet offset and start processing filter/modify operations from there.
89 | |
90 |
91 |
92 | t |
93 | time |
94 | 0 (Epoch time in ns) |
95 |
96 | Skip all packets that are older than this time.
97 | |
98 |
99 |
100 | m |
101 | max |
102 | 0 (no limit) |
103 |
104 | The maximum number of packets to write out in total.
105 | |
106 |
107 |
108 | n |
109 | num-chars |
110 | 64 |
111 |
112 | For use with --verbose . Limit the amount of characters written when dumping packets.
113 | |
114 |
115 |
116 | e |
117 | --dst-mac |
118 | (null) |
119 |
120 | Filter/modify based on the DST MAC.
121 | Accepts arguments in the form 0x001122334455 for filtering and 0x001122334455,0xAABBCCDDEEFF for filtering and modifying.
122 | |
123 |
124 |
125 | E |
126 | --src-mac |
127 | (null) |
128 |
129 | Fitler/modify based on the SRC MAC.
130 | Accepts arguments in the form 0x001122334455 for filtering and 0x001122334455,0xAABBCCDDEEFF for filtering and modifying.
131 | |
132 |
133 |
134 | l |
135 | vlan |
136 | (null) |
137 |
138 | Filter/modify based on the VLAN ID.
139 | Accepts arguments in the form 100 for filtering and 100,200 for filtering and modifying.
140 |
141 | The --vlan option also allows users to strip and add 8021.Q tags in addition to filtering and modifying based on these tags.
142 | For example if --vlan 0,100 is specified, that will cause Exact PCAP Modify to add an 8021.Q header with a VLAN ID of 100 to all non-8021.Q frames.
143 |
144 | The inverse usage, --vlan 100,0 will cause Exact PCAP Modify to strip all 8021.Q frames which have VLAN ID 100 and set the Ethertype to IPv4.
145 | |
146 |
147 |
148 | a |
149 | src-ip |
150 | (null) |
151 |
152 | Fitler/modify based on the SRC IP.
153 | Accepts arguments in the form 1.1.1.1 for filtering and 1.1.1.1,2.2.2.2 for filtering and modifying.
154 | |
155 |
156 |
157 | A |
158 | dst-ip |
159 | (null) |
160 |
161 | Fitler/modify based on the DST IP.
162 | Accepts arguments in the form 1.1.1.1 for filtering and 1.1.1.1,2.2.2.2 for filtering and modifying.
163 | |
164 |
165 |
166 | T |
167 | ip-ttl |
168 | (null) |
169 |
170 | Fitler/modify based on the IP TTL.
171 | Accepts arguments in the form 10 for filtering and 10,64 for filtering and modifying.
172 | |
173 |
174 |
175 | p |
176 | src-port |
177 | (null) |
178 |
179 | Fitler/modify based on the SRC PORT of the TCP/UDP header.
180 | Accepts arguments in the form 1000 for filtering and 1000,2000 for filtering and modifying.
181 | |
182 |
183 |
184 | P |
185 | dst-port |
186 | (null) |
187 |
188 | Fitler/modify based on the DST PORT of the TCP/UDP header.
189 | Accepts arguments in the form 1000 for filtering and 1000,2000 for filtering and modifying.
190 | |
191 |
192 |
193 | d |
194 | device-type |
195 | nexus3548 |
196 |
197 | When modifying frames, emulate the behaviour of the specified device.
198 | Valid values are: nexus3548 , fusion , triton , arista7150 .
199 | |
200 |
201 |
202 |
--------------------------------------------------------------------------------
/docs/src/tools/parse.md:
--------------------------------------------------------------------------------
1 | # Exact PCAP Parse
2 |
3 | Exact PCAP Parse (`exact-pcap-parse`) is a tool used to create ASCII dumps from `.pcap` and `.expcap` files. It outputs timestamps and packet data in `.csv` files.
4 |
5 | The following table lists all commands available:
6 |
7 |
8 |
9 | Short |
10 | Long |
11 | Default |
12 | Description |
13 |
14 |
15 | i |
16 | input |
17 | (required) |
18 |
19 | The input `.pcap` file to parse and dump.
20 | |
21 |
22 |
23 | c |
24 | csv |
25 | (required) |
26 |
27 | The `.csv` file to write out the dumped timestamps and packet data.
28 | |
29 |
30 |
31 | v |
32 | verbose |
33 | (flag) |
34 |
35 | Enables verbose output printing.
36 | |
37 |
38 |
39 | f |
40 | format |
41 | (required) |
42 |
43 | The input file format. Valid values are pcap or expcap .
44 | |
45 |
46 |
47 | o |
48 | offset |
49 | 0 |
50 |
51 | Start parsing packets from this packet offset into the input file.
52 | |
53 |
54 |
55 | m |
56 | max |
57 | -1 (no limit) |
58 |
59 | Limit the number of packets to parse.
60 | |
61 |
62 |
63 | n |
64 | num-chars |
65 | 64 |
66 |
67 | The number of bytes parse and output in the packet data field of the .csv file.
68 | |
69 |
70 |
71 |
--------------------------------------------------------------------------------
/docs/src/versions.md:
--------------------------------------------------------------------------------
1 | ## Version 1.2.1
2 | **Release date:** 8 March 2021
3 | **Commit ID:** [5025a3682a26179808574e1261be94da93341db3](https://github.com/exablaze-oss/exact-capture/commit/5025a3682a26179808574e1261be94da93341db3)
4 | **Source:** [https://github.com/exablaze-oss/exact-capture/releases/tag/v1.2.1](https://github.com/exablaze-oss/exact-capture/releases/tag/v1.2.1)
5 |
6 | **Release Notes:**
7 |
8 | * Fix non-fatal compiler warning: enumeration value ‘PKT_OVER_SNAPLEN’ not handled in switch
9 |
10 | ---------------------------------------
11 |
12 | ## Version 1.2
13 | **Release date:** 5 March 2021
14 | **Commit ID:** [fdf4d555e768d839eb8d98d66aac70ec4f34d4ad](https://github.com/exablaze-oss/exact-capture/commit/fdf4d555e768d839eb8d98d66aac70ec4f34d4ad)
15 | **Source:** [https://github.com/exablaze-oss/exact-capture/releases/tag/v1.2](https://github.com/exablaze-oss/exact-capture/releases/tag/v1.2)
16 |
17 | **Release Notes:**
18 |
19 | * Moved all utilities into /tools directory
20 | * Moved all utilities to a use common code-base for PCAP read/write operations
21 | * Add exact-pcap-analyze utility for PCAP statistics generation (useful for performance debugging)
22 | * Add exact-pcap-modify utility for easy PCAP search/modify operations (useful for switch benchmarking)
23 | * Improve exact-pcap-extract to understand N3550-F HPT trailer format
24 | * Improve exact-pcap-extract to filter based on H3550-F HPT trailer format or VLAN tag header
25 | * Add performance optimisation and tuning guide
26 | * Add utility and workflow overview documentation
27 | * Add exact-pcap-extract detailed documentation
28 | * Add exact-pcap-match detailed documentation
29 | * Add exact-pacp-analyze detailed documentation
30 | * Add exact-pcap-parse detailed documentation
31 | * Add exact-pcap-modify detailed documentation
32 |
33 | ---------------------------------------
34 |
35 | ## Version 1.1
36 | **Release date:** 30 September 2019
37 | **Commit ID:** [5d337a645987af00fc0d1afa6769ee7ccf62caea](https://github.com/exablaze-oss/exact-capture/commit/5d337a645987af00fc0d1afa6769ee7ccf62caea)
38 | **Source:** [https://github.com/exablaze-oss/exact-capture/tree/v1.1](https://github.com/exablaze-oss/exact-capture/tree/v1.1)
39 |
40 | **Release Notes:**
41 |
42 | * Moved documentation online use [mkdocs](https://www.mkdocs.org/) and [github pages](https://pages.github.com/)
43 | * Removed PDF documentation
44 | * Updated readme
45 |
46 | ---------------------------------------
47 |
48 | ## Version 1.0
49 | **Release date:** 7 March 2018
50 | **Commit ID:** [624a3f97bbaddd3cf827387e2352d5f5c662a7e5](https://github.com/exablaze-oss/exact-capture/commit/624a3f97bbaddd3cf827387e2352d5f5c662a7e5)
51 | **Source:** [https://github.com/exablaze-oss/exact-capture/tree/v1.0](https://github.com/exablaze-oss/exact-capture/tree/v1.0)
52 |
53 | **Release Notes:**
54 |
55 | * Initial release of Exact Capture
56 | * PDF documentation included in repo
57 |
58 | ---------------------------------------
59 |
--------------------------------------------------------------------------------
/libs/chaste:
--------------------------------------------------------------------------------
1 | libchaste/include/
--------------------------------------------------------------------------------
/libs/libchaste/60740670f7763b10d1b022c6d1709434b39c2a5d:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cisco/exact-capture/2a7b74e66cbbafcec7c39947dea63bec03972685/libs/libchaste/60740670f7763b10d1b022c6d1709434b39c2a5d
--------------------------------------------------------------------------------
/libs/libchaste/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2013, Matthew P. Grosvenor
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without
5 | modification, are permitted provided that the following conditions are met:
6 | * Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | * Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | * Neither the name of the Matthew P. Grosvenor nor the
12 | names of its contributors may be used to endorse or promote products
13 | derived from this software without specific prior written permission.
14 |
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 | DISCLAIMED. IN NO EVENT SHALL MATTHEW P. GROSVENOR BE LIABLE FOR ANY
19 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 |
--------------------------------------------------------------------------------
/libs/libchaste/README:
--------------------------------------------------------------------------------
1 | -------------------------------------------------------------------------------
2 | Pure, virtuous, unadulterated programming bliss - hastily assembled C programs.
3 | -------------------------------------------------------------------------------
4 |
5 | The C-Haste Library (libchaste)
6 | ===============================
7 |
8 | License:
9 | --------
10 | See LICENSE file included. TL;DR - BSD 3 Clause.
11 |
12 |
13 | Main features:
14 | --------------
15 | Data structures: generic, type safe array, vector and linked list (hash map partially implemented)
16 |
17 | Type safe command line options parser with super simple syntax, usage text etc.
18 |
19 | Powerful logging with runtime and compile time log level tuning, coloured output.
20 |
21 |
22 | Todo/In progress
23 | -----------------
24 | Architecture agnositc performance monitoring and measuring tools around RDTSC/PMC/PDU
25 |
26 | Yet another string library to efficiently do useful string manipulations using nice macros to make
27 |
28 |
29 | Currently builds on:
30 | ---------------------
31 | - x86 Linux (Ubtuntu 12.10/13.04) (clang 3.2 and gcc 4.6-4.8)
32 | - x86 Darwin (Mac OSX 10.10/10.11) (clang 7.0)
33 |
34 | Targeted to build on:
35 | - Linux/BSD/Darwin (OS X)
36 | - 32bit/64bit (64bit optimized)
37 | - ARM / x86
38 |
39 |
40 | Obtaining the source:
41 | ----------------------
42 |
43 | The C-Haste library is available at https://github.com/mgrosvenor/libchaste
44 |
45 | - The master branch is a "stable" "release" candidate -- the bleeding edge - guaranteed compile and pass unit tests -- API may vary wildly.
46 | - Release branches are stable, tagged with the release ID. Incremental fixes to a release will be tags added to the release branch. Bug fixes only. No new features. No new APIs.
47 |
48 |
49 | Building
50 | ---------
51 |
52 | Libchaste builds on both gcc 4.6 and clang 3.2 against the c11 standard with pedantic warnings and errors using the Posix 2008 system API.
53 |
54 | It includes a set of unit tests and infrastructure for making them all running and passing valgrind tests.
55 |
56 | - run build.sh to build a debug libcahste.a binary in the bin/ directory.
57 | - run build_release.sh to build a release binary libcahste.tar.bz
58 |
59 | Requirements
60 | -------------
61 | Cake build system - https://github.com/Zomojo/Cake
62 | Clang 3.2+ / GCC 4.6+
63 |
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/libs/libchaste/include/asm/asm.h:
--------------------------------------------------------------------------------
1 | // CamIO 2: asm.h
2 | // Copyright (C) 2013: Matthew P. Grosvenor (matthew.grosvenor@cl.cam.ac.uk)
3 | // Licensed under BSD 3 Clause, please see LICENSE for more details.
4 |
5 | #ifndef ASM_H_
6 | #define ASM_H_
7 |
8 |
9 |
10 | #endif /* ASM_H_ */
11 |
--------------------------------------------------------------------------------
/libs/libchaste/include/chaste.h:
--------------------------------------------------------------------------------
1 | /*
2 | * libm6.h
3 | *
4 | * Created on: Jun 29, 2013
5 | * Author: mgrosvenor
6 | */
7 |
8 | #ifndef LIBM6_H_
9 | #define LIBM6_H_
10 |
11 | #include "types/types.h"
12 | #include "utils/util.h"
13 | #include "string/string.h"
14 |
15 | #include "options/options.h"
16 | //#include "perf/perf.h"
17 | #include "log/log.h"
18 | //#include "perf/perf_mon.h"
19 |
20 | #include "data_structs/array/array_std.h"
21 | #include "data_structs/vector/vector_std.h"
22 | #include "data_structs/linked_list/linked_list_std.h"
23 | #include "data_structs/hash_map/hash_map.h"
24 | #include "data_structs/function_hash_map/function_hash_map.h"
25 |
26 | #endif /* LIBM6_H_ */
27 |
--------------------------------------------------------------------------------
/libs/libchaste/include/data_structs/array/array.h:
--------------------------------------------------------------------------------
1 | // CamIO 2: array.h
2 | // Copyright (C) 2013: Matthew P. Grosvenor (matthew.grosvenor@cl.cam.ac.uk)
3 | // Licensed under BSD 3 Clause, please see LICENSE for more details.
4 |
5 | #ifndef ARRAY_H_
6 | #define ARRAY_H_
7 |
8 | #include "../../types/types.h"
9 |
10 | struct ch_array;
11 | typedef struct ch_array ch_array_t;
12 |
13 |
14 | struct ch_array{
15 | ch_word size; //Return the max number number of elements in the array list
16 |
17 | void* first; //Pointer to the fist valid entry list. Not valid if first == end
18 | void* last; //Pointer to the last valid element in the array. Not valid if last == end
19 | void* end; //Pointer to the one element beyond the end of the valid elements in array. Do not dereference!
20 |
21 | // Members prefixed with "_" are nominally "private" Don't touch my privates!
22 | int (*_cmp)(const void *, const void *); // Comparator function for find and sort operations
23 | void* _array_backing; //Actual array storage
24 | ch_word _array_backing_size; //Number of elements allocated in the given array
25 | ch_word _element_size;
26 |
27 | };
28 |
29 |
30 | //Resize the array
31 | void array_resize(ch_array_t* this, ch_word new_size);
32 |
33 | //Check for equality
34 | ch_word array_eq(ch_array_t* this, ch_array_t* that);
35 |
36 | //Return the element at a given offset, with bounds checking
37 | void* array_off(ch_array_t* this, ch_word idx);
38 |
39 | //Step forwards by one entry
40 | void* array_next(ch_array_t* this, void* ptr);
41 |
42 | //Step backwards by one entry
43 | void* array_prev(ch_array_t* this, void* ptr);
44 |
45 | //Step forwards by amount
46 | void* array_forward(ch_array_t* this, void* ptr, ch_word amount);
47 |
48 | //Step backwards by amount
49 | void* array_back(ch_array_t* this, void* ptr, ch_word amount);
50 |
51 | //find the given value using the comparitor function
52 | void* array_find(ch_array_t* this, void* begin, void* end, void* value);
53 |
54 | //return the offset/index of the given item
55 | int array_get_idx(ch_array_t* this, void* value);
56 |
57 | //sort into order given the comparitor function
58 | void array_sort(ch_array_t* this);
59 |
60 | //sort into reverse order given the comparitor function
61 | void array_sort_reverse(ch_array_t* this);
62 |
63 | //Free the resources associated with this array, assumes that individual items have been freed
64 | void array_delete(ch_array_t* this);
65 |
66 | //Set at most count elements to the value in carray starting at offset in this array
67 | void* array_from_carray(ch_array_t* this, void* carray, ch_word count);
68 |
69 |
70 | ch_array_t* ch_array_new(ch_word size, ch_word element_size, int(*cmp)(const void* lhs, const void* rhs));
71 |
72 | #endif //ARRAY_H_
73 |
--------------------------------------------------------------------------------
/libs/libchaste/include/data_structs/array/array_std.h:
--------------------------------------------------------------------------------
1 | /*
2 | * array_std.h
3 | *
4 | * Created on: Sep 12, 2013
5 | * Author: mgrosvenor
6 | */
7 |
8 | #ifndef ARRAY_STD_H_
9 | #define ARRAY_STD_H_
10 |
11 | #include "array_typed_declare_template.h"
12 |
13 | declare_array(u8, u8)
14 | declare_array(u16, u16)
15 | declare_array(u32, u32)
16 | declare_array(u64, u64)
17 |
18 | declare_array(u8p, u8*)
19 | declare_array(u16p, u16*)
20 | declare_array(u32p, u32*)
21 | declare_array(u64p, u64*)
22 |
23 | declare_array(i8, i8)
24 | declare_array(i16, i16)
25 | declare_array(i32, i32)
26 | declare_array(i64, i64)
27 |
28 | declare_array(i8p, i8*)
29 | declare_array(i16p, i16*)
30 | declare_array(i32p, i32*)
31 | declare_array(i64p, i64*)
32 |
33 | declare_array(machine, ch_machine)
34 | declare_array(word, ch_word)
35 | declare_array(char, ch_char)
36 | declare_array(ch_bool, ch_bool)
37 | declare_array(float, ch_float)
38 | declare_array(string, ch_str)
39 |
40 |
41 | declare_array(machinep, ch_machine*)
42 | declare_array(wordp, ch_word*)
43 | declare_array(charp, ch_char*)
44 | declare_array(boolp, ch_bool*)
45 | declare_array(floatp, ch_float*)
46 | declare_array(stringp, ch_str*)
47 |
48 | declare_array(voidp, void*)
49 |
50 | declare_ch_array_cmp(u8, u8)
51 | declare_ch_array_cmp(u16, u16)
52 | declare_ch_array_cmp(u32, u32)
53 | declare_ch_array_cmp(u64, u64)
54 |
55 | declare_ch_array_cmp(u8p, u8*)
56 | declare_ch_array_cmp(u16p, u16*)
57 | declare_ch_array_cmp(u32p, u32*)
58 | declare_ch_array_cmp(u64p, u64*)
59 |
60 | declare_ch_array_cmp(i8, i8)
61 | declare_ch_array_cmp(i16, i16)
62 | declare_ch_array_cmp(i32, i32)
63 | declare_ch_array_cmp(i64, i64)
64 |
65 | declare_ch_array_cmp(i8p, i8*)
66 | declare_ch_array_cmp(i16p, i16*)
67 | declare_ch_array_cmp(i32p, i32*)
68 | declare_ch_array_cmp(i64p, i64*)
69 |
70 | declare_ch_array_cmp(machine, ch_machine)
71 | declare_ch_array_cmp(word, ch_word)
72 | declare_ch_array_cmp(char, ch_char)
73 | declare_ch_array_cmp(ch_bool, ch_bool)
74 | declare_ch_array_cmp(float, ch_float)
75 | declare_ch_array_cmp(string, ch_str)
76 | declare_ch_array_cmp(cstr, ch_cstr)
77 |
78 | declare_ch_array_cmp(machinep, ch_machine*)
79 | declare_ch_array_cmp(wordp, ch_word*)
80 | declare_ch_array_cmp(charp, ch_char*)
81 | declare_ch_array_cmp(boolp, ch_bool*)
82 | declare_ch_array_cmp(floatp, ch_float*)
83 | declare_ch_array_cmp(stringp, ch_str*)
84 | declare_ch_array_cmp(cstrp, ch_cstr*)
85 |
86 | declare_ch_array_cmp(voidp, void*)
87 |
88 | #endif /* ARRAY_STD_H_ */
89 |
--------------------------------------------------------------------------------
/libs/libchaste/include/data_structs/array/array_typed_declare_template.h:
--------------------------------------------------------------------------------
1 | /*
2 | * array_typed.h
3 | *
4 | * Created on: Sep 12, 2013
5 | * Author: mgrosvenor
6 | */
7 |
8 | #ifndef ARRAY_TYPED_TEMPLATE_DECLARE_H_
9 | #define ARRAY_TYPED_TEMPLATE_DECLARE_H_
10 |
11 |
12 | #include "../../types/types.h"
13 | #include "array.h"
14 |
15 | #define declare_array(NAME,TYPE)\
16 | \
17 | struct ch_array_##NAME;\
18 | typedef struct ch_array_##NAME ch_array_##NAME##_t;\
19 | \
20 | struct ch_array_##NAME{\
21 | ch_word size; /*Return the max number number of elements in the array list*/\
22 | TYPE* first; /*Pointer to the fist valid entry list. Not valid if first == end*/\
23 | TYPE* last; /*Pointer to the last valid element in the array. Not valid if last == end*/\
24 | TYPE* end; /*Pointer to the one element beyond the end of the valid elements in array. Do not dereference! */\
25 | \
26 | void (*resize)(ch_array_##NAME##_t* this, ch_word new_size); /*Resize the array*/\
27 | ch_word (*eq)(ch_array_##NAME##_t* this, ch_array_##NAME##_t* that); /*Check for equality*/\
28 | \
29 | TYPE* (*off)(ch_array_##NAME##_t* this, ch_word idx); /*Return the element at a given offset, with bounds checking*/\
30 | TYPE* (*next)(ch_array_##NAME##_t* this, TYPE* ptr); /*Step forwards by one entry*/\
31 | TYPE* (*prev)(ch_array_##NAME##_t* this, TYPE* ptr); /*Step backwards by one entry*/\
32 | TYPE* (*forward)(ch_array_##NAME##_t* this, TYPE* ptr, ch_word amount); /*Step forwards by amount*/\
33 | TYPE* (*back)(ch_array_##NAME##_t* this, TYPE* ptr, ch_word amount); /*Step backwards by amount*/\
34 | \
35 | TYPE* (*find)(ch_array_##NAME##_t* this, TYPE* begin, TYPE* end, TYPE value); /*find the given value using the comparator function*/\
36 | void (*sort)(ch_array_##NAME##_t* this); /*sort into order given the comparator function*/\
37 | \
38 | void (*delete)(ch_array_##NAME##_t* this); /*Free the resources associated with this array, assumes that individual items have been freed*/\
39 | \
40 | TYPE* (*from_carray)(ch_array_##NAME##_t* this, TYPE* carray, ch_word count); /*Set at most count elements to the value in carray starting at offset in this array*/\
41 | \
42 | ch_array_t* _array;\
43 | };\
44 | \
45 | ch_array_##NAME##_t* ch_array_##NAME##_new(ch_word size, ch_word (*cmp)(TYPE* lhs, TYPE* rhs) );\
46 |
47 |
48 | #define declare_ch_array_cmp(NAME, TYPE) ch_word ch_array_cmp_##NAME(TYPE* lhs, TYPE* rhs);
49 |
50 |
51 | #define CH_ARRAY(NAME) ch_array_##NAME##_t
52 | #define CH_ARRAY_CMP(NAME) ch_array_cmp_##NAME
53 | #define CH_ARRAY_NEW(NAME, size, cmp) ch_array_##NAME##_new(size, cmp )
54 |
55 | #endif //ARRAY_TYPED_TEMPLATE_DECLARE_H_
56 |
--------------------------------------------------------------------------------
/libs/libchaste/include/data_structs/array/array_typed_define_template.h:
--------------------------------------------------------------------------------
1 | /*
2 | * array_typed.c
3 | *
4 | * Created on: Sep 12, 2013
5 | * Author: mgrosvenor
6 | */
7 |
8 | #ifndef ARRAY_TYPED_TEMPLATE_DEFINE_H_
9 | #define ARRAY_TYPED_TEMPLATE_DEFINE_H_
10 |
11 |
12 | #include "array.h"
13 |
14 | #include
15 | #include
16 |
17 | #define define_array(NAME,TYPE)\
18 | \
19 | static void _update_##NAME(ch_array_##NAME##_t* this)\
20 | {\
21 | this->size = this->_array->size;\
22 | this->first = this->_array->first;\
23 | this->last = this->_array->last;\
24 | this->end = this->_array->end;\
25 | }\
26 | \
27 | static void _resize_##NAME(ch_array_##NAME##_t* this, ch_word new_size) { array_resize(this->_array, new_size); _update_##NAME(this); }\
28 | static ch_word _eq_##NAME(ch_array_##NAME##_t* this, ch_array_##NAME##_t* that) { ch_word result = array_eq(this->_array, that->_array); _update_##NAME(this); return result;}\
29 | static TYPE* _off_##NAME(ch_array_##NAME##_t* this, ch_word idx) { TYPE* result = (TYPE*)array_off(this->_array, idx); _update_##NAME(this); return result; }\
30 | static TYPE* _forward_##NAME(ch_array_##NAME##_t* this, TYPE* ptr, ch_word amount) { TYPE* result = (TYPE*)array_forward(this->_array, (void*)ptr, amount); _update_##NAME(this); return result; }\
31 | static TYPE* _back_##NAME(ch_array_##NAME##_t* this, TYPE* ptr, ch_word amount) { TYPE* result = (TYPE*)array_back(this->_array, (void*)ptr, amount); _update_##NAME(this); return result; }\
32 | static TYPE* _next_##NAME(ch_array_##NAME##_t* this, TYPE* ptr) { TYPE* result = (TYPE*)_forward_##NAME(this, ptr, 1); _update_##NAME(this); return result; }\
33 | static TYPE* _prev_##NAME(ch_array_##NAME##_t* this, TYPE* ptr) { TYPE* result = (TYPE*)_back_##NAME(this, ptr, 1); _update_##NAME(this); return result; }\
34 | static TYPE* _find_##NAME(ch_array_##NAME##_t* this, TYPE* begin, TYPE* end, TYPE value) { TYPE* result = (TYPE*) array_find(this->_array, (void*)begin, (void*)end, &value); _update_##NAME(this); return result; }\
35 | static void _sort_##NAME(ch_array_##NAME##_t* this) { array_sort(this->_array); _update_##NAME(this); }\
36 | static TYPE* _from_carray_##NAME(ch_array_##NAME##_t* this, TYPE* carray, ch_word count) { TYPE* result = array_from_carray(this->_array, (void*)carray, count); _update_##NAME(this); return result; }\
37 | \
38 | static void _delete_##NAME(ch_array_##NAME##_t* this)\
39 | {\
40 | if(this->_array){\
41 | array_delete(this->_array);\
42 | }\
43 | \
44 | free(this);\
45 | }\
46 | \
47 | \
48 | ch_array_##NAME##_t* ch_array_##NAME##_new(ch_word size, ch_word (*cmp)(TYPE* lhs, TYPE* rhs) )\
49 | {\
50 | \
51 | ch_array_##NAME##_t* result = (ch_array_##NAME##_t*)calloc(1,sizeof(ch_array_##NAME##_t));\
52 | if(!result){\
53 | printf("Could not allocate memory for new array structure. Giving upn");\
54 | return ((void *)0);\
55 | }\
56 | \
57 | result->_array = ch_array_new(size, sizeof(TYPE), (cmp_void_f)cmp );\
58 | \
59 | \
60 | /*We have memory to play with, now do all the other assignments*/\
61 | result->resize = _resize_##NAME;\
62 | result->off = _off_##NAME;\
63 | result->next = _next_##NAME;\
64 | result->prev = _prev_##NAME;\
65 | result->forward = _forward_##NAME;\
66 | result->back = _back_##NAME;\
67 | result->from_carray = _from_carray_##NAME;\
68 | result->delete = _delete_##NAME;\
69 | \
70 | /*Fail hard and early if the compare function is NULL*/\
71 | if(cmp){\
72 | result->eq = _eq_##NAME;\
73 | result->find = _find_##NAME;\
74 | result->sort = _sort_##NAME;\
75 | }\
76 | \
77 | _update_##NAME(result);\
78 | \
79 | return result;\
80 | }
81 |
82 | //Regular comparison function
83 | #define define_ch_array_cmp(NAME, TYPE) \
84 | ch_word ch_array_cmp_##NAME(TYPE* lhs, TYPE* rhs)\
85 | { \
86 | return ( *lhs == *rhs ? 0 : *lhs < *rhs ? -1 : 1); \
87 | }
88 |
89 | //Pointer comparison function
90 | #define define_ch_array_cmpp(NAME, TYPE) ch_word ch_array_cmp_##NAME##p(TYPE* lhs, TYPE* rhs)\
91 | { \
92 | return ch_array_cmp_##NAME(*lhs, *rhs);\
93 | }
94 |
95 | #define define_ch_array_compare(NAME, TYPE) ch_word ch_array_cmp_##NAME(TYPE* lhs, TYPE* rhs)
96 |
97 |
98 | #endif //ARRAY_TYPED_TEMPLATE_DEFINE_H_
99 |
--------------------------------------------------------------------------------
/libs/libchaste/include/data_structs/circular_queue/circular_queue.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This is the implementation of a circular buffer based queue data structure. The data structure provides a fixed sized
3 | * queue with constant time push and pop operations (much like a linked listed) but with out runtime memory allocation
4 | * costs. The structure provides the ability to push items on to the queue, to "use" items from that queue and to release
5 | * items from the queue. All operations are O(c) time with the size of the queue. The structure also provides the ability to
6 | * push an array of times on to the queue which is O(n) with the size of the array.
7 | *
8 | * cbq.c
9 | *
10 | * Created on: July 22, 2015
11 | * Author: mgrosvenor
12 | */
13 |
14 |
15 | #ifndef CBQ_H_
16 | #define CBQ_H_
17 |
18 | #include "../../types/types.h"
19 | #include "../array/array.h"
20 |
21 | struct ch_cbq;
22 | typedef struct ch_cbq ch_cbq_t;
23 |
24 | struct ch_cbq{
25 | ch_word size; //Return the max number number of elements in the cbq list
26 | ch_word count; //Return the actual number of elements in the cbq
27 | ch_word in_use; //Return the number of elements that are currently in use. in_use <= count <= size.
28 |
29 | // Members prefixed with "_" are nominally "private" Don't touch my privates!
30 | ch_word _add_next_index;
31 | ch_word _release_index;
32 | ch_word _use_next_index;
33 |
34 | ch_array_t* _array; //Actual CBQ storage back end
35 | };
36 |
37 | //Get access to an element at the front of the list. Return a pointer to the element.
38 | void* cbq_peek_front(ch_cbq_t* this);
39 |
40 | //Pull an element from the front of the cbq. Return 0 on success, -1 on failure.
41 | int cbq_pop_front(ch_cbq_t* this);
42 |
43 | //Mark an item as "used" an item from the front of the queue. This marks the item as "in use" and returns a pointer to it.
44 | //This is useful to use the queue for in-place storage while working on producing a result.
45 | void* cbq_use_front(ch_cbq_t* this);
46 |
47 | //Unmark the last item as used. This is useful if an operation failed on an item marked as used.
48 | void cbq_unuse_front(ch_cbq_t* this);
49 |
50 | // Put an element at the back of the circular buffer queue
51 | void* cbq_push_back(ch_cbq_t* this, void* value);
52 |
53 | //Push back count elements the C cbq to the back cbq-list
54 | void* cbq_push_back_carray(ch_cbq_t* this, void* ccbq, ch_word* count);
55 |
56 | //Free the resources associated with this cbq, assumes that individual items have been freed
57 | void cbq_delete(ch_cbq_t* this);
58 |
59 | //Create a new circualr buffer queue structure with size queue slots in it, each with element_size storage.
60 | ch_cbq_t* ch_cbq_new(ch_word size, ch_word element_size);
61 |
62 | #endif // CBQ_H_
63 |
--------------------------------------------------------------------------------
/libs/libchaste/include/data_structs/function_hash_map/function_hash_map.h:
--------------------------------------------------------------------------------
1 | /*
2 | * function_hash_map.h
3 | *
4 | * Created on: Sep 23, 2013
5 | * Author: mgrosvenor
6 | */
7 |
8 | #ifndef FUNCTION_HASH_MAP_H_
9 | #define FUNCTION_HASH_MAP_H_
10 |
11 | #include "../../types/types.h"
12 | #include "../linked_list/linked_list.h"
13 | #include "../array/array.h"
14 |
15 |
16 | struct ch_function_hash_map_t;
17 | typedef struct ch_function_hash_map_t ch_function_hash_map;
18 |
19 | typedef struct {
20 | ch_llist_t* list;
21 | ch_word offset;
22 | ch_word key_size;
23 | ch_word key_int; //For keys less than or equal to 8bytes, just assign them
24 | void* key_ptr; //For keys that are longer, and not static, alloc memory and copy them here
25 | void* key_ptr_unsafe; //For keys that are in mapped memory for the life of the program, just keep the pointer here
26 | ch_word value;
27 | ch_word index;
28 | } ch_function_hash_map_node;
29 |
30 | typedef struct {
31 | //These state variables are private
32 | ch_function_hash_map_node* _node;
33 | ch_llist_it item;
34 |
35 | //This is public
36 | void* key;
37 | ch_word key_size;
38 | ch_word value;
39 | } ch_function_hash_map_it;
40 |
41 |
42 | struct ch_function_hash_map_t{
43 | ch_word count; //Return the actual number of elements in the function_hash_map
44 |
45 | // Members prefixed with "_" are nominally "private" Don't touch my privates!
46 | ch_word (*_cmp)(void* lhs, void* rhs); // Comparator function for find and sort operations
47 | ch_array_t* _backing_array;
48 | ch_word _element_size;
49 | ch_word (*_func)(ch_word value, void* key, ch_word key_size, void* data, ch_word index);
50 | };
51 |
52 |
53 |
54 | //Return the element at a given offset, with bounds checking
55 | ch_function_hash_map_it function_hash_map_off(ch_function_hash_map* this, ch_word idx);
56 |
57 | //Get the first entry
58 | ch_function_hash_map_it function_hash_map_first(ch_function_hash_map* this);
59 | //Get the last entry
60 | ch_function_hash_map_it function_hash_map_last(ch_function_hash_map* this);
61 | //Get the end
62 | ch_function_hash_map_it function_hash_map_end(ch_function_hash_map* this);
63 |
64 | //Step forwards by one entry
65 | void function_hash_map_next (ch_function_hash_map* this, ch_function_hash_map_it* it);
66 | //Step backwards by one entry
67 | void function_hash_map_prev(ch_function_hash_map* this, ch_function_hash_map_it*);
68 | //Step forwards by amount
69 | void function_hash_map_forward(ch_function_hash_map* this, ch_function_hash_map_it* it, ch_word amount);
70 | //Step backwards by amount
71 | void function_hash_map_back(ch_function_hash_map* this, ch_function_hash_map_it* it, ch_word amount);
72 |
73 | // Put an element into the table,
74 | ch_function_hash_map_it function_hash_map_push_unsafe_ptr(ch_function_hash_map* this, void* key, ch_word key_size, void* value);
75 | ch_function_hash_map_it function_hash_map_push(ch_function_hash_map* this, void* key, ch_word key_size, void* value);
76 | //Remove the given ptr
77 | ch_function_hash_map_it function_hash_map_remove(ch_function_hash_map* this, ch_function_hash_map_it* itr);
78 |
79 | //Free the resources associated with this function_hash_map, assumes that individual items have been freed
80 | void function_hash_map_delete(ch_function_hash_map* this);
81 |
82 | //Push back count elements the C function_hash_map to the back function_hash_map-list
83 | ch_function_hash_map_it function_hash_map_push_back_carray(ch_function_hash_map* this, const void* keys, ch_word* key_sizes, const void* carray, ch_word count);
84 |
85 | //Check for equality
86 | ch_word function_hash_map_eq(ch_function_hash_map* this, ch_function_hash_map* that);
87 |
88 | //Return the value associated with key using the comparator function
89 | ch_function_hash_map_it function_hash_map_get_first(ch_function_hash_map* this, void* key, ch_word key_size);
90 |
91 | //Get the next value with the given key
92 | ch_function_hash_map_it function_hash_map_get_next(ch_function_hash_map_it it);
93 |
94 | //Find the key of the given value
95 | ch_function_hash_map_it function_hash_map_find(ch_function_hash_map* this, ch_function_hash_map_it* begin, ch_function_hash_map_it* end, void* value);
96 |
97 | ch_function_hash_map* ch_function_hash_map_new( ch_word size, ch_word (*func)(ch_word value, void* key, ch_word key_size, void* data, ch_word index) );
98 |
99 | #endif // FUNCTION_HASH_MAP_H_
100 |
101 |
--------------------------------------------------------------------------------
/libs/libchaste/include/data_structs/hash_map/hash_map.h:
--------------------------------------------------------------------------------
1 | /*
2 | * hash_map.h
3 | *
4 | * Created on: Sep 23, 2013
5 | * Author: mgrosvenor
6 | */
7 |
8 | #ifndef HASH_MAP_H_
9 | #define HASH_MAP_H_
10 |
11 | #include "../../types/types.h"
12 | #include "../linked_list/linked_list.h"
13 | #include "../array/array.h"
14 |
15 |
16 | struct ch_hash_map_t;
17 | typedef struct ch_hash_map_t ch_hash_map;
18 |
19 | typedef struct {
20 | ch_llist_t* list;
21 | ch_word offset;
22 | ch_word key_size;
23 | ch_word key_int; //For keys less than or equal to 8bytes, just assign them
24 | void* key_ptr; //For keys that are longer, and not static, alloc memory and copy them here
25 | void* key_ptr_unsafe; //For keys that are in mapped memory for the life of the program, just keep the pointer here
26 | } ch_hash_map_node;
27 |
28 | typedef struct {
29 | //These state variables are private
30 | ch_hash_map_node* _node;
31 | ch_llist_it item;
32 |
33 | //This is public
34 | void* key;
35 | ch_word key_size;
36 | void* value;
37 | } ch_hash_map_it;
38 |
39 |
40 | struct ch_hash_map_t{
41 | ch_word count; //Return the actual number of elements in the hash_map
42 |
43 | // Members prefixed with "_" are nominally "private" Don't touch my privates!
44 | cmp_void_f _cmp; // Comparator function for find and sort operations
45 | ch_array_t* _backing_array;
46 | ch_word _element_size;
47 | };
48 |
49 |
50 |
51 | //Return the element at a given offset, with bounds checking
52 | ch_hash_map_it hash_map_off(ch_hash_map* this, ch_word idx);
53 |
54 | //Get the first entry
55 | ch_hash_map_it hash_map_first(ch_hash_map* this);
56 | //Get the last entry
57 | ch_hash_map_it hash_map_last(ch_hash_map* this);
58 | //Get the end
59 | ch_hash_map_it hash_map_end(ch_hash_map* this);
60 |
61 | //Step forwards by one entry
62 | void hash_map_next (ch_hash_map* this, ch_hash_map_it* it);
63 | //Step backwards by one entry
64 | void hash_map_prev(ch_hash_map* this, ch_hash_map_it*);
65 | //Step forwards by amount
66 | void hash_map_forward(ch_hash_map* this, ch_hash_map_it* it, ch_word amount);
67 | //Step backwards by amount
68 | void hash_map_back(ch_hash_map* this, ch_hash_map_it* it, ch_word amount);
69 |
70 | // Put an element into the table,
71 | ch_hash_map_it hash_map_push_unsafe_ptr(ch_hash_map* this, void* key, ch_word key_size, void* value);
72 | ch_hash_map_it hash_map_push(ch_hash_map* this, void* key, ch_word key_size, void* value);
73 | //Remove the given ptr
74 | ch_hash_map_it hash_map_remove(ch_hash_map* this, ch_hash_map_it* itr);
75 |
76 | //Free the resources associated with this hash_map, assumes that individual items have been freed
77 | void hash_map_delete(ch_hash_map* this);
78 |
79 | //Push back count elements the C hash_map to the back hash_map-list
80 | ch_hash_map_it hash_map_push_back_carray(ch_hash_map* this, const void* keys, ch_word* key_sizes, const void* carray, ch_word count);
81 |
82 | //Check for equality
83 | ch_word hash_map_eq(ch_hash_map* this, ch_hash_map* that);
84 |
85 | //Return the value associated with key using the comparator function
86 | ch_hash_map_it hash_map_get_first(ch_hash_map* this, void* key, ch_word key_size);
87 |
88 | //Get the next value with the given key
89 | ch_hash_map_it hash_map_get_next(ch_hash_map_it it);
90 |
91 | //Find the key of the given value
92 | ch_hash_map_it hash_map_find(ch_hash_map* this, ch_hash_map_it* begin, ch_hash_map_it* end, void* value);
93 |
94 | ch_hash_map* ch_hash_map_new( ch_word size, ch_word element_size, cmp_void_f cmp );
95 |
96 | #endif // HASH_MAP_H_
97 |
98 |
--------------------------------------------------------------------------------
/libs/libchaste/include/data_structs/linked_list/linked_list.h:
--------------------------------------------------------------------------------
1 | /*
2 | * llist.h
3 | *
4 | * Created on: Sep 12, 2013
5 | * Author: mgrosvenor
6 | */
7 |
8 | #ifndef LINKEDLIST_H_
9 | #define LINKEDLIST_H_
10 |
11 | #include "../../types/types.h"
12 |
13 | struct ch_llist_node;
14 | typedef struct ch_llist_node ch_llist_node_t;
15 |
16 | struct ch_llist_node {
17 | ch_llist_node_t* next;
18 | ch_llist_node_t* prev;
19 | };
20 |
21 | struct ch_llist;
22 | typedef struct ch_llist ch_llist_t;
23 |
24 | struct ch_llist{
25 | ch_word count; //Return the actual number of elements in the llist
26 |
27 | // Members prefixed with "_" are nominally "private" Don't touch my privates!
28 | cmp_void_f _cmp; // Comparator function for find and sort operations
29 | ch_llist_node_t* _first;
30 | ch_llist_node_t* _last;
31 | ch_word _element_size;
32 | };
33 |
34 | typedef struct {
35 | //These state variables are private
36 | ch_llist_node_t* _node;
37 |
38 | //This is public
39 | void* value;
40 | } ch_llist_it;
41 |
42 |
43 | //Return the element at a given offset, with bounds checking [WARN: This is slow in general]
44 | ch_llist_it llist_off(ch_llist_t* this, ch_word idx);
45 |
46 | //Get the first entry
47 | ch_llist_it llist_first(ch_llist_t* this);
48 | //Get the last entry
49 | ch_llist_it llist_last(ch_llist_t* this);
50 | //Get the end
51 | ch_llist_it llist_end(ch_llist_t* this);
52 |
53 | //Step forwards by one entry
54 | void llist_next (ch_llist_t* this, ch_llist_it* it);
55 | //Step backwards by one entry
56 | void llist_prev(ch_llist_t* this, ch_llist_it*);
57 | //Step forwards by amount
58 | void llist_forward(ch_llist_t* this, ch_llist_it* it, ch_word amount);
59 | //Step backwards by amount
60 | void llist_back(ch_llist_t* this, ch_llist_it* it, ch_word amount);
61 |
62 | // Put an element at the front of the llist list values,
63 | ch_llist_it llist_push_front(ch_llist_t* this, const void* value);
64 | // Push an element off the front of the llist list values,
65 | ch_llist_it llist_pop_front(ch_llist_t* this);
66 | // Put an element at the back of the llist values
67 | ch_llist_it llist_push_back(ch_llist_t* this, const void* value);
68 | // Push an element at the back of the llist values
69 | ch_llist_it llist_pop_back(ch_llist_t* this);
70 |
71 | // Insert an element after the element given by ptr
72 | ch_llist_it* llist_insert_after(ch_llist_t* this, ch_llist_it* itr, const void* value);
73 | // Insert an element before the element giver by ptr
74 | ch_llist_it* llist_insert_before(ch_llist_t* this, ch_llist_it* it, const void* value);
75 | //Remove the given iterator
76 | ch_llist_it llist_remove_it(ch_llist_t* this, ch_llist_it* itr);
77 | //Remove all items with the given value
78 | ch_llist_it llist_remove_all(ch_llist_t* this, void* value);
79 |
80 | //Remove all elememts from the list
81 | void llist_pop_all(ch_llist_t* this);
82 |
83 | //Free the resources associated with this llist, assumes that individual items have been freed
84 | void llist_delete(ch_llist_t* this);
85 |
86 | //Push back count elements the C llist to the back llist-list
87 | ch_llist_it llist_push_back_carray(ch_llist_t* this, const void* carray, ch_word count);
88 |
89 | //Check for equality
90 | ch_word llist_eq(ch_llist_t* this, ch_llist_t* that);
91 | //find the given value using the comparator function
92 | ch_llist_it llist_find(ch_llist_t* this, ch_llist_it* begin, ch_llist_it* end, void* value);
93 | ch_llist_it llist_find_first(ch_llist_t* this, void* value);
94 | ch_llist_it llist_find_next(ch_llist_t* this, ch_llist_it* begin, void* value);
95 | ch_llist_it llist_insert_inorder(ch_llist_t* this, void* value);
96 | ch_llist_it llist_insert_carray_ordered(ch_llist_t* this, void* carray, ch_word count);
97 | //sort into order given the comparator function
98 | void llist_sort(ch_llist_t* this);
99 |
100 | ch_llist_t* ch_llist_new( ch_word element_size, cmp_void_f cmp );
101 | ch_llist_t* ch_llist_init( ch_llist_t* this, ch_word element_size, cmp_void_f cmp );
102 |
103 | #endif // LINKEDLIST_H_
104 |
--------------------------------------------------------------------------------
/libs/libchaste/include/data_structs/linked_list/linked_list_std.h:
--------------------------------------------------------------------------------
1 | /*
2 | * linked_list_std.h
3 | *
4 | * Created on: Sep 23, 2013
5 | * Author: mgrosvenor
6 | */
7 |
8 | #ifndef LINKED_LIST_STD_H_
9 | #define LINKED_LIST_STD_H_
10 |
11 | #include "linked_list_typed_declare_template.h"
12 |
13 | declare_ch_llist(u8, u8)
14 | declare_ch_llist(u16, u16)
15 | declare_ch_llist(u32, u32)
16 | declare_ch_llist(u64, u64)
17 |
18 | declare_ch_llist(u8p, u8*)
19 | declare_ch_llist(u16p, u16*)
20 | declare_ch_llist(u32p, u32*)
21 | declare_ch_llist(u64p, u64*)
22 |
23 | declare_ch_llist(i8, i8)
24 | declare_ch_llist(i16, i16)
25 | declare_ch_llist(i32, i32)
26 | declare_ch_llist(i64, i64)
27 |
28 | declare_ch_llist(i8p, i8*)
29 | declare_ch_llist(i16p, i16*)
30 | declare_ch_llist(i32p, i32*)
31 | declare_ch_llist(i64p, i64*)
32 |
33 | declare_ch_llist(machine, ch_machine)
34 | declare_ch_llist(word, ch_word)
35 | declare_ch_llist(char, ch_char)
36 | declare_ch_llist(ch_bool, ch_bool)
37 | declare_ch_llist(float, ch_float)
38 | declare_ch_llist(string, ch_str)
39 | declare_ch_llist(cstr, ch_cstr)
40 |
41 | declare_ch_llist(machinep, ch_machine*)
42 | declare_ch_llist(wordp, ch_word*)
43 | declare_ch_llist(charp, ch_char*)
44 | declare_ch_llist(boolp, ch_bool*)
45 | declare_ch_llist(floatp, ch_float*)
46 | declare_ch_llist(stringp, ch_str*)
47 | declare_ch_llist(cstrp, ch_cstr*)
48 |
49 | declare_ch_llist(voidp, void*)
50 |
51 | declare_ch_llist_cmp(u8, u8);
52 | declare_ch_llist_cmp(u16, u16);
53 | declare_ch_llist_cmp(u32, u32);
54 | declare_ch_llist_cmp(u64, u64);
55 |
56 | declare_ch_llist_cmp(u8p, u8*);
57 | declare_ch_llist_cmp(u16p, u16*);
58 | declare_ch_llist_cmp(u32p, u32*);
59 | declare_ch_llist_cmp(u64p, u64*);
60 |
61 | declare_ch_llist_cmp(i8, i8);
62 | declare_ch_llist_cmp(i16, i16);
63 | declare_ch_llist_cmp(i32, i32);
64 | declare_ch_llist_cmp(i64, i64);
65 |
66 | declare_ch_llist_cmp(i8p, i8*);
67 | declare_ch_llist_cmp(i16p, i16*);
68 | declare_ch_llist_cmp(i32p, i32*);
69 | declare_ch_llist_cmp(i64p, i64*);
70 |
71 | declare_ch_llist_cmp(machine, ch_machine);
72 | declare_ch_llist_cmp(word, ch_word);
73 | declare_ch_llist_cmp(char, ch_char);
74 | declare_ch_llist_cmp(ch_bool, ch_bool);
75 | declare_ch_llist_cmp(float, ch_float);
76 | declare_ch_llist_cmp(string, ch_str);
77 | declare_ch_llist_cmp(cstr, ch_cstr);
78 |
79 | declare_ch_llist_cmp(machinep, ch_machine*);
80 | declare_ch_llist_cmp(wordp, ch_word*);
81 | declare_ch_llist_cmp(charp, ch_char*);
82 | declare_ch_llist_cmp(boolp, ch_bool*);
83 | declare_ch_llist_cmp(floatp, ch_float*);
84 | declare_ch_llist_cmp(stringp, ch_str*);
85 | declare_ch_llist_cmp(cstrp, ch_cstr*);
86 |
87 | declare_ch_llist_cmp(voidp, void*);
88 |
89 |
90 | declare_ch_llist(UINT64, u64)
91 | declare_ch_llist_cmp(UINT64, u64);
92 |
93 | #endif /* LINKED_LIST_STD_H_ */
94 |
--------------------------------------------------------------------------------
/libs/libchaste/include/data_structs/linked_list/linked_list_typed_declare_template.h:
--------------------------------------------------------------------------------
1 | #ifndef LINKED_LIST_TYPED_TEMPLATE_DECLARE_H_
2 | #define LINKED_LIST_TYPED_TEMPLATE_DECLARE_H_
3 |
4 |
5 | #include "../../types/types.h"
6 | #include "linked_list.h"
7 |
8 | #define declare_ch_llist(NAME,TYPE) \
9 | \
10 | struct ch_llist_##NAME;\
11 | struct ch_llist_##NAME##_it_t;\
12 | typedef struct ch_llist_##NAME ch_llist_##NAME##_t;\
13 | typedef struct ch_llist_##NAME##_it_t ch_llist_##NAME##_it;\
14 | \
15 | struct ch_llist_##NAME##_it_t{ \
16 | ch_llist_node_t* _node; \
17 | TYPE* value;\
18 | };\
19 | \
20 | \
21 | struct ch_llist_##NAME{\
22 | ch_word count; /*Return the actual number of elements in the llist*/ \
23 | \
24 | ch_llist_##NAME##_it (*off)(ch_llist_##NAME##_t* this, ch_word idx); /* Return the element at a given offset, with bounds checking [WARN: This is slow in general] */\
25 | \
26 | ch_llist_##NAME##_it (*first)(ch_llist_##NAME##_t* this); /*Get the first entry*/\
27 | ch_llist_##NAME##_it (*last)(ch_llist_##NAME##_t* this); /*Get the last entry*/\
28 | ch_llist_##NAME##_it (*end)(ch_llist_##NAME##_t* this); /*Get the end*/\
29 | \
30 | void (*next)(ch_llist_##NAME##_t* this, ch_llist_##NAME##_it* it); /*Step forwards by one entry*/\
31 | void (*prev)(ch_llist_##NAME##_t* this, ch_llist_##NAME##_it*); /*Step backwards by one entry*/\
32 | void (*forward)(ch_llist_##NAME##_t* this, ch_llist_##NAME##_it* it, ch_word amount); /*Step forwards by amount*/\
33 | void (*back)(ch_llist_##NAME##_t* this, ch_llist_##NAME##_it* it, ch_word amount); /*Step backwards by amount*/\
34 | \
35 | ch_llist_##NAME##_it (*push_front)(ch_llist_##NAME##_t* this, TYPE value); /* Put an element at the front of the linked list values,*/\
36 | ch_llist_##NAME##_it (*pop_front)(ch_llist_##NAME##_t* this);/* Push an element off the front of the linked list values,*/\
37 | ch_llist_##NAME##_it (*push_back)(ch_llist_##NAME##_t* this, TYPE value); /* Put an element at the back of the linked list values*/\
38 | ch_llist_##NAME##_it (*pop_back)(ch_llist_##NAME##_t* this); /* Push an element at the back of the linked list values*/\
39 | \
40 | ch_llist_##NAME##_it* (*insert_after)(ch_llist_##NAME##_t* this, ch_llist_##NAME##_it* itr, TYPE value); /* Insert an element after the element given by ptr*/\
41 | ch_llist_##NAME##_it* (*insert_before)(ch_llist_##NAME##_t* this, ch_llist_##NAME##_it* it, TYPE value); /* Insert an element before the element giver by ptr*/\
42 | ch_llist_##NAME##_it (*remove_it)(ch_llist_##NAME##_t* this, ch_llist_##NAME##_it* itr); /*Remove the given ptr*/\
43 | ch_llist_##NAME##_it (*remove_all)(ch_llist_##NAME##_t* this, TYPE value); /*Remove the given ptr*/\
44 | \
45 | void (*delete)(ch_llist_##NAME##_t* this); /*Free the resources associated with this llist, assumes that individual items have been freed*/\
46 | \
47 | ch_llist_##NAME##_it (*push_back_carray)(ch_llist_##NAME##_t* this, const TYPE* carray, ch_word count); /*Push back count elements the C llist to the back llist-list*/\
48 | \
49 | ch_word (*eq)(ch_llist_##NAME##_t* this, ch_llist_##NAME##_t* that); /*Check for equality*/\
50 | ch_llist_##NAME##_it (*find)(ch_llist_##NAME##_t* this, ch_llist_##NAME##_it* begin, ch_llist_##NAME##_it* end, TYPE value); /*find the given value using the comparator function*/\
51 | ch_llist_##NAME##_it (*find_first)(ch_llist_##NAME##_t* this, TYPE value); /*find the given value using the comparator function*/\
52 | ch_llist_##NAME##_it (*find_next)(ch_llist_##NAME##_t* this, ch_llist_##NAME##_it* begin, TYPE value); /*find the given value using the comparator function*/\
53 | ch_llist_##NAME##_it (*insert_inorder)(ch_llist_##NAME##_t* this, TYPE value); /* Insert an element before the element giver by ptr*/\
54 | ch_llist_##NAME##_it (*insert_carray_ordered)(ch_llist_##NAME##_t* this, const TYPE* carray, ch_word count); /*Insert count element in order*/\
55 | void (*sort)(ch_llist_##NAME##_t* this); /*sort into order given the comparator function*/\
56 | \
57 | /* Members prefixed with "_" are nominally "private" Don't touch my privates!*/\
58 | ch_llist_t* _llist; /*Actual llist storage*/\
59 | \
60 | };\
61 | \
62 | \
63 | ch_llist_##NAME##_t* ch_llist_##NAME##_new(ch_word(*cmp)(TYPE* lhs, TYPE* rhs) );
64 |
65 |
66 | #define declare_ch_llist_cmp(NAME, TYPE) ch_word ch_llist_cmp_##NAME(TYPE* lhs, TYPE* rhs)
67 |
68 |
69 | //**********************************************************************************************************************
70 | //Shortcuts to make things more accessible
71 | #define CH_LIST(NAME) ch_llist_##NAME##_t
72 | #define CH_LIST_IT(NAME) ch_llist_##NAME##_it
73 | #define CH_LIST_NEW(NAME, cmp) ch_llist_##NAME##_new(cmp )
74 | #define CH_LIST_CMP(NAME) ch_llist_cmp_##NAME
75 | #define CH_LIST_FOREACH(TYPE_NAME, LIST_NAME,IT_NAME) \
76 | for(CH_LIST_IT(TYPE_NAME) IT_NAME = LIST_NAME->first(LIST_NAME); IT_NAME.value; LIST_NAME->next(LIST_NAME,&IT_NAME))
77 |
78 | #endif /*LINKED_LIST_TYPED_TEMPLATE_DECLARE_H_*/
79 |
80 |
--------------------------------------------------------------------------------
/libs/libchaste/include/data_structs/vector/vector.h:
--------------------------------------------------------------------------------
1 | /*
2 | * vector.h
3 | *
4 | * Created on: Sep 12, 2013
5 | * Author: mgrosvenor
6 | */
7 |
8 | #ifndef VECTOR_H_
9 | #define VECTOR_H_
10 |
11 | #include "../../types/types.h"
12 | #include "../array/array.h"
13 |
14 | struct ch_vector;
15 | typedef struct ch_vector ch_vector_t;
16 |
17 |
18 | struct ch_vector{
19 | ch_word size; //Return the max number number of elements in the vector list
20 | ch_word count; //Return the actual number of elements in the vector
21 |
22 | void* first; //Pointer to the fist valid entry list. Not valid if first == end
23 | void* last; //Pointer to the last valid element in the list. Not valid if last == end
24 | void* end; //Pointer to the one element beyond the end of the valid elements in list. Do not dereference!
25 |
26 | // Members prefixed with "_" are nominally "private" Don't touch my privates!
27 | cmp_void_f _cmp; // Comparator function for find and sort operations
28 | ch_array_t* _array; //Actual vector storage
29 | ch_word _array_count; //NUmber of elements currently in the vector
30 | };
31 |
32 |
33 | //Resize the vector
34 | void vector_resize(ch_vector_t* this, ch_word new_size);
35 |
36 | //Return the element at a given offset, with bounds checking
37 | void* vector_off(ch_vector_t* this, ch_word idx);
38 |
39 | //Step forwards by one entry
40 | void* vector_next (ch_vector_t* this, void* ptr);
41 | //Step backwards by one entry
42 | void* vector_prev(ch_vector_t* this, void* ptr);
43 | //Step forwards by amount
44 | void* vector_forward(ch_vector_t* this, void* ptr, ch_word amount);
45 | //Step backwards by amount
46 | void* vector_back(ch_vector_t* this, void* ptr, ch_word amount);
47 |
48 | // Put an element at the front of the vector list values, [WARN: In general this is very expensive for an vector]
49 | void* vector_push_front(ch_vector_t* this, void* value);
50 | // Push an element off the front of the vector list values, [WARN: In general this is very expensive for an vector]
51 | void vector_pop_front(ch_vector_t* this);
52 | // Put an element at the back of the vector values
53 | void* vector_push_back(ch_vector_t* this, void* value);
54 | // Push an element at the back of the vector values
55 | void vector_pop_back(ch_vector_t* this);
56 |
57 | // Insert an element after the element given by ptr
58 | void* vector_insert_after(ch_vector_t* this, void* ptr, void* value);
59 | // Insert an element before the element giver by ptr [WARN: In general this is very expensive for an vector]
60 | void* vector_insert_before(ch_vector_t* this, void* ptr, void* value);
61 | //Remove the given ptr [WARN: In general this is very expensive]
62 | void* vector_remove(ch_vector_t* this, void* ptr);
63 | //Pop everything out of the vector
64 | void vector_clear(ch_vector_t* this);
65 |
66 | //Free the resources associated with this vector, assumes that individual items have been freed
67 | void vector_delete(ch_vector_t* this);
68 |
69 | //Push back count elements the C vector to the back vector-list
70 | void* vector_push_back_carray(ch_vector_t* this, void* cvector, ch_word count);
71 |
72 | //Check for equality
73 | ch_word vector_eq(ch_vector_t* this, ch_vector_t* that);
74 | //find the given value using the comparator function
75 | void* vector_find(ch_vector_t* this, void* begin, void* end, void* value);
76 | //return the index of the value
77 | int vector_get_idx(ch_vector_t* this, void* value);
78 | //sort into order given the comparator function
79 | void vector_sort(ch_vector_t* this);
80 |
81 | ch_vector_t* ch_vector_new(ch_word size, ch_word element_size, cmp_void_f cmp );
82 |
83 | #endif // VECTOR_H_
84 |
--------------------------------------------------------------------------------
/libs/libchaste/include/data_structs/vector/vector_std.h:
--------------------------------------------------------------------------------
1 | // CamIO 2: vector_std_int.h
2 | // Copyright (C) 2013: Matthew P. Grosvenor (matthew.grosvenor@cl.cam.ac.uk)
3 | // Licensed under BSD 3 Clause, please see LICENSE for more details.
4 |
5 | #ifndef VECTOR_STD_INT_H_
6 | #define VECTOR_STD_INT_H_
7 |
8 | #include
9 |
10 | #include "../../types/types.h"
11 | #include "vector_typed_declare_template.h"
12 |
13 | declare_ch_vector(u8, u8)
14 | declare_ch_vector(u16, u16)
15 | declare_ch_vector(u32, u32)
16 | declare_ch_vector(u64, u64)
17 |
18 | declare_ch_vector(u8p, u8*)
19 | declare_ch_vector(u16p, u16*)
20 | declare_ch_vector(u32p, u32*)
21 | declare_ch_vector(u64p, u64*)
22 |
23 | declare_ch_vector(i8, i8)
24 | declare_ch_vector(i16, i16)
25 | declare_ch_vector(i32, i32)
26 | declare_ch_vector(i64, i64)
27 |
28 | declare_ch_vector(i8p, i8*)
29 | declare_ch_vector(i16p, i16*)
30 | declare_ch_vector(i32p, i32*)
31 | declare_ch_vector(i64p, i64*)
32 |
33 | declare_ch_vector(machine, ch_machine)
34 | declare_ch_vector(word, ch_word)
35 | declare_ch_vector(char, ch_char)
36 | declare_ch_vector(ch_bool, ch_bool)
37 | declare_ch_vector(float, ch_float)
38 | declare_ch_vector(string, ch_str)
39 | declare_ch_vector(cstr, ch_cstr)
40 |
41 | declare_ch_vector(machinep, ch_machine*)
42 | declare_ch_vector(wordp, ch_word*)
43 | declare_ch_vector(charp, ch_char*)
44 | declare_ch_vector(boolp, ch_bool*)
45 | declare_ch_vector(floatp, ch_float*)
46 | declare_ch_vector(stringp, ch_str*)
47 | declare_ch_vector(cstrp, ch_cstr*)
48 |
49 | declare_ch_vector(voidp, void*)
50 |
51 | declare_ch_vector_cmp(u8, u8)
52 | declare_ch_vector_cmp(u16, u16)
53 | declare_ch_vector_cmp(u32, u32)
54 | declare_ch_vector_cmp(u64, u64)
55 |
56 | declare_ch_vector_cmp(u8p, u8*)
57 | declare_ch_vector_cmp(u16p, u16*)
58 | declare_ch_vector_cmp(u32p, u32*)
59 | declare_ch_vector_cmp(u64p, u64*)
60 |
61 | declare_ch_vector_cmp(i8, i8)
62 | declare_ch_vector_cmp(i16, i16)
63 | declare_ch_vector_cmp(i32, i32)
64 | declare_ch_vector_cmp(i64, i64)
65 |
66 | declare_ch_vector_cmp(i8p, i8*)
67 | declare_ch_vector_cmp(i16p, i16*)
68 | declare_ch_vector_cmp(i32p, i32*)
69 | declare_ch_vector_cmp(i64p, i64*)
70 |
71 | declare_ch_vector_cmp(machine, ch_machine)
72 | declare_ch_vector_cmp(word, ch_word)
73 | declare_ch_vector_cmp(char, ch_char)
74 | declare_ch_vector_cmp(ch_bool, ch_bool)
75 | declare_ch_vector_cmp(float, ch_float)
76 | declare_ch_vector_cmp(string, ch_str)
77 | declare_ch_vector_cmp(cstr, ch_cstr)
78 |
79 | declare_ch_vector_cmp(machinep, ch_machine*)
80 | declare_ch_vector_cmp(wordp, ch_word*)
81 | declare_ch_vector_cmp(charp, ch_char*)
82 | declare_ch_vector_cmp(boolp, ch_bool*)
83 | declare_ch_vector_cmp(floatp, ch_float*)
84 | declare_ch_vector_cmp(stringp, ch_str*)
85 | declare_ch_vector_cmp(cstrp, ch_cstr*)
86 |
87 | declare_ch_vector_cmp(voidp, void*)
88 |
89 |
90 |
91 |
92 | #endif /* ARRAY_STD_INT_H_ */
93 |
--------------------------------------------------------------------------------
/libs/libchaste/include/data_structs/vector/vector_typed_declare_template.h:
--------------------------------------------------------------------------------
1 | #ifndef VECTOR_TYPED_TEMPLATE_DECLARE_H_
2 | #define VECTOR_TYPED_TEMPLATE_DECLARE_H_
3 |
4 |
5 | #include "../../types/types.h"
6 | #include "vector.h"
7 |
8 |
9 | #define declare_ch_vector(NAME,TYPE) \
10 | \
11 | struct ch_vector_##NAME;\
12 | typedef struct ch_vector_##NAME ch_vector_##NAME##_t;\
13 | \
14 | \
15 | struct ch_vector_##NAME{\
16 | ch_word size; /*Return the max number number of elements in the vector list*/\
17 | ch_word count; /*Return the actual number of elements in the vector*/\
18 | TYPE* first; /*Pointer to the fist valid entry list. Not valid if first == end*/\
19 | TYPE* last; /*Pointer to the last valid element in the list. Not valid if last == end*/\
20 | TYPE* end; /*Pointer to the one element beyond the end of the valid elements in list. Do not dereference! */\
21 | \
22 | \
23 | void (*resize)(ch_vector_##NAME##_t* this, ch_word new_size); /*Resize the vector*/\
24 | TYPE* (*off)(ch_vector_##NAME##_t* this, ch_word idx); /*Return the element at a given offset, with bounds checking*/\
25 | \
26 | TYPE* (*next)(ch_vector_##NAME##_t* this, TYPE* ptr); /*Step forwards by one entry*/\
27 | TYPE* (*prev)(ch_vector_##NAME##_t* this, TYPE* ptr); /*Step backwards by one entry*/\
28 | TYPE* (*forward)(ch_vector_##NAME##_t* this, TYPE* ptr, ch_word amount); /*Step forwards by amount*/\
29 | TYPE* (*back)(ch_vector_##NAME##_t* this, TYPE* ptr, ch_word amount); /*Step backwards by amount*/\
30 | \
31 | TYPE* (*push_front)(ch_vector_##NAME##_t* this, TYPE value); /* Put an element at the front of the vector list values, [WARN: In general this is very expensive for a vector] */\
32 | void (*pop_front)(ch_vector_##NAME##_t* this); /* Push an element off the front of the vector list values, [WARN: In general this is very expensive for a vector] */\
33 | TYPE* (*push_back)(ch_vector_##NAME##_t* this, TYPE value); /* Put an element at the back of the vector values*/\
34 | void (*pop_back)(ch_vector_##NAME##_t* this); /* Push an element at the back of the vector values*/\
35 | void (*clear)(ch_vector_##NAME##_t* this); /*Pop everything out of the vector*/\
36 | \
37 | TYPE* (*insert_after)(ch_vector_##NAME##_t* this, TYPE* ptr, TYPE value); /* Insert an element after the element given by ptr*/\
38 | TYPE* (*insert_before)(ch_vector_##NAME##_t* this, TYPE* ptr, TYPE value); /* Insert an element before the element giver by ptr [WARN: In general this is very expensive for a vector] */\
39 | TYPE* (*remove)(ch_vector_##NAME##_t* this, TYPE* ptr); /*Remove the given ptr [WARN: In general this is very expensive] */\
40 | void (*delete)(ch_vector_##NAME##_t* this); /*Free the resources associated with this vector, assumes that individual items have been freed*/\
41 | \
42 | TYPE* (*find)(ch_vector_##NAME##_t* this, TYPE* begin, TYPE* end, TYPE value); /*find the given value using the comparator function*/\
43 | int (*get_idx)(ch_vector_##NAME##_t* this, TYPE* value); /*Convert the iterator into an index for use with off() above*/\
44 | void (*sort)(ch_vector_##NAME##_t* this); /*sort into order given the comparator function*/\
45 | ch_word (*eq)(ch_vector_##NAME##_t* this, ch_vector_##NAME##_t* that); /*Check for equality*/\
46 | \
47 | TYPE* (*push_back_carray)(ch_vector_##NAME##_t* this, TYPE* carray, ch_word count); /*Push back count elements the C vector to the back vector-list*/\
48 | \
49 | /* Members prefixed with "_" are "private" Don't touch my privates!*/\
50 | ch_vector_t* _vector; /*Actual vector storage*/\
51 | \
52 | };\
53 | \
54 | \
55 | ch_vector_##NAME##_t* ch_vector_##NAME##_new(ch_word size, ch_word(*cmp)(TYPE* lhs, TYPE* rhs) );
56 |
57 | #define declare_ch_vector_cmp(NAME, TYPE) ch_word ch_vector_cmp_##NAME(TYPE* lhs, TYPE* rhs);
58 |
59 | #define CH_VECTOR(NAME) ch_vector_##NAME##_t
60 | #define CH_VECTOR_NEW(NAME, size, cmp) ch_vector_##NAME##_new(size, cmp )
61 | #define CH_VECTOR_CMP(NAME) ch_vector_cmp_##NAME
62 |
63 | #endif //VECTOR_TYPED_TEMPLATE_DECLARE_H_
64 |
65 |
--------------------------------------------------------------------------------
/libs/libchaste/include/data_structs/vector/vector_typed_define_template.h:
--------------------------------------------------------------------------------
1 | #ifndef VECTOR_TYPED_TEMPLATE_DEFINE_H_
2 | #define VECTOR_TYPED_TEMPLATE_DEFINE_H_
3 |
4 | #include "vector.h"
5 | #include "vector_std.h"
6 |
7 | #include "../../utils/util.h"
8 | #include "../../types/types.h"
9 |
10 | #include
11 | #include
12 | #include
13 |
14 | #define define_ch_vector(NAME,TYPE)\
15 | \
16 | static void _update_##NAME(ch_vector_##NAME##_t* this)\
17 | {\
18 | this->size = this->_vector->size;\
19 | this->first = this->_vector->first;\
20 | this->last = this->_vector->last;\
21 | this->end = this->_vector->end;\
22 | this->count = this->_vector->count;\
23 | }\
24 | \
25 | static void _resize_##NAME(ch_vector_##NAME##_t* this, ch_word new_size) { vector_resize(this->_vector, new_size); _update_##NAME(this); }\
26 | static ch_word _eq_##NAME(ch_vector_##NAME##_t* this, ch_vector_##NAME##_t* that) { ch_word result = vector_eq(this->_vector, that->_vector); _update_##NAME(this); return result;}\
27 | static TYPE* _off_##NAME(ch_vector_##NAME##_t* this, ch_word idx) { TYPE* result = (TYPE*)vector_off(this->_vector, idx); _update_##NAME(this); return result; }\
28 | static TYPE* _forward_##NAME(ch_vector_##NAME##_t* this, TYPE* ptr, ch_word amount) { TYPE* result = (TYPE*)vector_forward(this->_vector, (void*)ptr, amount); _update_##NAME(this); return result; }\
29 | static TYPE* _back_##NAME(ch_vector_##NAME##_t* this, TYPE* ptr, ch_word amount) { TYPE* result = (TYPE*)vector_back(this->_vector, (void*)ptr, amount); _update_##NAME(this); return result; }\
30 | static TYPE* _next_##NAME(ch_vector_##NAME##_t* this, TYPE* ptr) { TYPE* result = (TYPE*)_forward_##NAME(this, ptr, 1); _update_##NAME(this); return result; }\
31 | static TYPE* _prev_##NAME(ch_vector_##NAME##_t* this, TYPE* ptr) { TYPE* result = (TYPE*)_back_##NAME(this, ptr, 1); _update_##NAME(this); return result; }\
32 | static TYPE* _find_##NAME(ch_vector_##NAME##_t* this, TYPE* begin, TYPE* end, TYPE value) { TYPE* result = (TYPE*) vector_find(this->_vector, (void*)begin, (void*)end, &value); _update_##NAME(this); return result; }\
33 | static int _get_idx_##NAME(ch_vector_##NAME##_t* this, TYPE* value) { return vector_get_idx(this->_vector, value); }\
34 | static void _sort_##NAME(ch_vector_##NAME##_t* this) { vector_sort(this->_vector); _update_##NAME(this); }\
35 | static TYPE* _push_front_##NAME(ch_vector_##NAME##_t* this, TYPE value) { TYPE* result = (TYPE*) vector_push_front(this->_vector, &value); _update_##NAME(this); return result; }\
36 | static TYPE* _push_back_##NAME(ch_vector_##NAME##_t* this, TYPE value) { TYPE* result = (TYPE*) vector_push_back(this->_vector, &value); _update_##NAME(this); return result; }\
37 | static TYPE* _insert_after_##NAME(ch_vector_##NAME##_t* this, TYPE* ptr, TYPE value) { TYPE* result = (TYPE*) vector_insert_after(this->_vector, ptr, &value); _update_##NAME(this); return result; }\
38 | static TYPE* _insert_before_##NAME(ch_vector_##NAME##_t* this, TYPE* ptr, TYPE value) { TYPE* result = (TYPE*) vector_insert_before(this->_vector, ptr, &value); _update_##NAME(this); return result; }\
39 | static TYPE* _remove_##NAME(ch_vector_##NAME##_t* this, TYPE* ptr) { TYPE* result = (TYPE*) vector_remove(this->_vector, ptr); _update_##NAME(this); return result; }\
40 | static void _pop_front_##NAME(ch_vector_##NAME##_t* this) { vector_pop_front(this->_vector); _update_##NAME(this); }\
41 | static void _pop_back_##NAME(ch_vector_##NAME##_t* this) { vector_pop_back(this->_vector); _update_##NAME(this); }\
42 | static void _clear_##NAME(ch_vector_##NAME##_t* this) { vector_clear(this->_vector); _update_##NAME(this); }\
43 | static TYPE* _push_back_carray_##NAME(ch_vector_##NAME##_t* this, TYPE* carray, ch_word count) { TYPE* result = vector_push_back_carray(this->_vector, (void*)carray, count); _update_##NAME(this); return result; }\
44 | \
45 | static void _delete_##NAME(ch_vector_##NAME##_t* this)\
46 | {\
47 | if(this->_vector){\
48 | vector_delete(this->_vector);\
49 | }\
50 | \
51 | free(this);\
52 | }\
53 | \
54 | \
55 | ch_vector_##NAME##_t* ch_vector_##NAME##_new(ch_word size, ch_word (*cmp)(TYPE* lhs, TYPE* rhs) )\
56 | {\
57 | \
58 | ch_vector_##NAME##_t* result = (ch_vector_##NAME##_t*)calloc(1,sizeof(ch_vector_##NAME##_t));\
59 | if(!result){\
60 | printf("Could not allocate memory for new vector structure. Giving upn");\
61 | return ((void *)0);\
62 | }\
63 | \
64 | result->_vector = ch_vector_new(size, sizeof(TYPE), (cmp_void_f)cmp );\
65 | \
66 | \
67 | /*We have memory to play with, now do all the other assignments*/\
68 | result->resize = _resize_##NAME;\
69 | result->eq = _eq_##NAME;\
70 | result->off = _off_##NAME;\
71 | result->get_idx = _get_idx_##NAME;\
72 | result->next = _next_##NAME;\
73 | result->prev = _prev_##NAME;\
74 | result->forward = _forward_##NAME;\
75 | result->back = _back_##NAME;\
76 | result->find = _find_##NAME;\
77 | result->sort = _sort_##NAME;\
78 | result->push_front = _push_front_##NAME;\
79 | result->pop_front = _pop_front_##NAME;\
80 | result->push_back = _push_back_##NAME;\
81 | result->pop_back = _pop_back_##NAME;\
82 | result->insert_after = _insert_after_##NAME;\
83 | result->insert_before = _insert_before_##NAME;\
84 | result->remove = _remove_##NAME;\
85 | result->push_back_carray = _push_back_carray_##NAME;\
86 | result->clear = _clear_##NAME;\
87 | result->delete = _delete_##NAME;\
88 | \
89 | \
90 | \
91 | /*Fail hard and early if the compare function is NULL*/\
92 | if(cmp){\
93 | result->eq = _eq_##NAME;\
94 | result->find = _find_##NAME;\
95 | result->sort = _sort_##NAME;\
96 | }\
97 | \
98 | _update_##NAME(result);\
99 | \
100 | return result;\
101 | }
102 |
103 | //Regular comparison function
104 | #define define_ch_vector_cmp(NAME, TYPE) \
105 | ch_word ch_vector_cmp_##NAME(TYPE* lhs, TYPE* rhs)\
106 | { \
107 | return ( *lhs == *rhs ? 0 : *lhs < *rhs ? -1 : 1); \
108 | }
109 |
110 | //Pointer comparison function
111 | #define define_ch_vector_cmpp(NAME, TYPE) ch_word ch_vector_cmp_##NAME##p(TYPE* lhs, TYPE* rhs)\
112 | { \
113 | return ch_vector_cmp_##NAME(*lhs, *rhs);\
114 | }
115 |
116 | #define define_ch_vector_compare(NAME, TYPE) ch_word ch_vector_cmp_##NAME(TYPE* lhs, TYPE* rhs)
117 |
118 | #endif //VECTOR_TYPED_TEMPLATE_DEFINE_H_
119 |
--------------------------------------------------------------------------------
/libs/libchaste/include/hash_functions/spooky/spooky_hash.h:
--------------------------------------------------------------------------------
1 | /*
2 | * spooky_hash.h
3 | *
4 | * Created on: Sep 23, 2013
5 | * Author: mgrosvenor
6 | */
7 |
8 | #ifndef SPOOKY_HASH_H_
9 | #define SPOOKY_HASH_H_
10 |
11 | /*
12 | * This is a port of Bob Jenkins Spooky Hash from C++ to C. Port by M. P. Grosvenor.
13 | * http://burtleburtle.net/bob/hash/spooky.html
14 | */
15 |
16 | // SpookyHash: a 128-bit noncryptographic hash function
17 | // By Bob Jenkins, public domain
18 | // Oct 31 2010: alpha, framework + SpookyHash::Mix appears right
19 | // Oct 31 2011: alpha again, Mix only good to 2^^69 but rest appears right
20 | // Dec 31 2011: beta, improved Mix, tested it for 2-bit deltas
21 | // Feb 2 2012: production, same bits as beta
22 | // Feb 5 2012: adjusted definitions of uint* to be more portable
23 | // Mar 30 2012: 3 bytes/cycle, not 4. Alpha was 4 but wasn't thorough enough.
24 | // August 5 2012: SpookyV2 (different results)
25 | //
26 | // Up to 3 bytes/cycle for long messages. Reasonably fast for short messages.
27 | // All 1 or 2 bit deltas achieve avalanche within 1% bias per output bit.
28 | //
29 | // This was developed for and tested on 64-bit x86-compatible processors.
30 | // It assumes the processor is little-endian. There is a macro
31 | // controlling whether unaligned reads are allowed (by default they are).
32 | // This should be an equally good hash on big-endian machines, but it will
33 | // compute different results on them than on little-endian machines.
34 | //
35 | // Google's CityHash has similar specs to SpookyHash, and CityHash is faster
36 | // on new Intel boxes. MD4 and MD5 also have similar specs, but they are orders
37 | // of magnitude slower. CRCs are two or more times slower, but unlike
38 | // SpookyHash, they have nice math for combining the CRCs of pieces to form
39 | // the CRCs of wholes. There are also cryptographic hashes, but those are even
40 | // slower than MD5.
41 | //
42 |
43 | #include
44 | #include
45 |
46 | #define INLINE inline
47 | typedef uint64_t uint64;
48 | typedef uint32_t uint32;
49 | typedef uint16_t uint16;
50 | typedef uint8_t uint8;
51 |
52 |
53 | #define sc_numVars 12
54 | #define sc_blockSize (sc_numVars * 8)
55 | #define sc_bufSize (sc_blockSize * 2)
56 | #define sc_const ( 0xdeadb0efdeadbeefLL )
57 | #define SPOOKY_HASH_INIT_STATE = { .sc_numVars = sc_numVars, .sc_blockSize = sc_blockSize, .sc_bufSize = sc_bufSize, .sc_const = sc_const, 0 }
58 |
59 |
60 | typedef struct {
61 | uint64 m_data[2*sc_numVars]; // unhashed data, for partial messages
62 | uint64 m_state[sc_numVars]; // internal state of the hash
63 | size_t m_length; // total length of the input so far
64 | uint8 m_remainder; // length of unhashed data stashed in m_data
65 | } spooky_hash_state;
66 |
67 |
68 |
69 | //
70 | // SpookyHash: hash a single message in one call, produce 128-bit output
71 | //
72 | // message to hash
73 | // length of message in bytes
74 | // in/out: in seed 1, out hash value 1
75 | // in/out: in seed 2, out hash value 2
76 | void spooky_Hash128( const void *message, size_t length, uint64 *hash1, uint64 *hash2);
77 | uint64 spooky_Hash64( const void *message, size_t length, uint64 seed);
78 | uint32 spooky_Hash32( const void *message, size_t length, uint32 seed);
79 |
80 | //
81 | // Init: initialize the context of a SpookyHash
82 | //
83 | // any 64-bit value will do, including 0
84 | // different seeds produce independent hashes
85 | void spooky_Init(spooky_hash_state* s, uint64 seed1, uint64 seed2);
86 |
87 | //
88 | // Update: add a piece of a message to a SpookyHash state
89 | //
90 | // message fragment
91 | // length of message fragment in bytes
92 | void spooky_Update(spooky_hash_state* s, const void *message, size_t length);
93 |
94 |
95 | //
96 | // Final: compute the hash for the current SpookyHash state
97 | //
98 | // This does not modify the state; you can keep updating it afterward
99 | //
100 | // The result is the same as if SpookyHash() had been called with
101 | // all the pieces concatenated into one message.
102 | //
103 | // out only: first 64 bits of hash value.
104 | // out only: second 64 bits of hash value.
105 | void spooky_Final(spooky_hash_state* s, uint64 *hash1, uint64 *hash2);
106 |
107 |
108 |
109 |
110 | #endif /* SPOOKY_HASH_H_ */
111 |
--------------------------------------------------------------------------------
/libs/libchaste/include/log/log_levels.h:
--------------------------------------------------------------------------------
1 | /*
2 | * log_levels.h
3 | *
4 | * Created on: Jul 2, 2013
5 | * Author: mgrosvenor
6 | */
7 |
8 |
9 | //Logging levels - The higher the number, the more this is on the critical path
10 | #define CH_LOG_LVL_FATAL 0 //0: Fatal errors that cause the program to terminate
11 | #define CH_LOG_LVL_ERROR 1 //1: Errors that a user can detect and recover from with substantial effort
12 | #define CH_LOG_LVL_WARN 2 //2: Warnings that do not hinder operation, but may lead to unexpected results
13 | #define CH_LOG_LVL_INFO 3 //3: Generally useful output information
14 | #define CH_LOG_LVL_DEBUG1 4 //4: Shallow depth debug logs
15 | #define CH_LOG_LVL_DEBUG2 5 //5: Medium depth debug logs
16 | #define CH_LOG_LVL_DEBUG3 6 //6: Very deep debug logs
17 | #define CH_LOG_LVL_COUNT 7
18 |
19 |
20 | //Options for output
21 | #define CH_LOG_OUT_STDOUT 0
22 | #define CH_LOG_OUT_STDERR 1
23 | #define CH_LOG_OUT_FILE 2
24 | #define CH_LOG_OUT_SYSLOG 3
25 |
--------------------------------------------------------------------------------
/libs/libchaste/include/makeinclude.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 |
3 | tmp=$1
4 |
5 | rm -rf $tmp/include
6 | find . -type d | grep -v "\.$" | grep -v ".\/include" | grep -v "\/bin" | grep -v "/\.git" | grep -v ".\/dag" | grep -v ".\/netmap" | grep -v "build" > $tmp/.tmp.dirs
7 | find . | grep ".*.h$" | grep -v ".\/include" | grep -v "\/bin" | grep -v "/\.git" | grep -v ".\/dag" | grep -v ".\/netmap" | grep -v "build" > $tmp/.tmp.headers
8 |
9 | python makeinclude.py $tmp
10 |
11 | rm $tmp/.tmp.headers
12 | rm $tmp/.tmp.dirs
13 |
14 |
--------------------------------------------------------------------------------
/libs/libchaste/include/options/options.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) Matthew P. Grosvenor, 2012, All Rights Reserved
3 | *
4 | * Tools to parse and print command line options
5 | */
6 |
7 | #ifndef CH_OPTIONS_H_
8 | #define CH_OPTIONS_H_
9 |
10 | #include "../types/types.h"
11 | #include "../log/log.h" //Include this here, so users don't have to
12 | #include "options_vectors.h"
13 | #include "../data_structs/vector/vector_std.h"
14 |
15 |
16 | typedef struct {
17 | char* short_description;
18 | char* long_description;
19 | CH_VECTOR(opts)* opt_defs;
20 | uint64_t count;
21 | ch_bool help;
22 | int unlimted_set;
23 | ch_bool done_init;
24 | } ch_options_t;
25 |
26 |
27 | //Declare all the options parsers for non vector types, with initializers
28 | #define ch_opt_add_declare_i(ch_type_name, c_type_name, short_name, long_name)\
29 | int ch_opt_add##short_name##i(ch_options_mode_e mode, char short_str, char* long_str, char* descr, c_type_name* result_out, c_type_name default_val)
30 | ch_opt_add_declare_i(CH_BOOL, ch_bool, b, "Boolean");
31 | ch_opt_add_declare_i(CH_UINT64, u64, u, "Unsigned");
32 | ch_opt_add_declare_i(CH_INT64, ch_word, i, "Integer");
33 | ch_opt_add_declare_i(CH_STRING, ch_cstr, s, "String");
34 | ch_opt_add_declare_i(CH_DOUBLE, ch_float, f, "Float");
35 | ch_opt_add_declare_i(CH_HEX, u64, x, "Unsigned");
36 |
37 | //Declare all the options parsers for non vector types, untantalized
38 | #define ch_opt_add_declare_u(ch_type_name, c_type_name, short_name, long_name)\
39 | int ch_opt_add##short_name##u(ch_options_mode_e mode, char short_str, char* long_str, char* descr, c_type_name* result_out)
40 | ch_opt_add_declare_u(CH_BOOL, ch_bool, b, "boolean");
41 | ch_opt_add_declare_u(CH_UINT64, u64, u, "unsigned");
42 | ch_opt_add_declare_u(CH_INT64, ch_word, i, "integer");
43 | ch_opt_add_declare_u(CH_STRING, ch_cstr, s, "string");
44 | ch_opt_add_declare_u(CH_DOUBLE, ch_float, f, "float");
45 | ch_opt_add_declare_u(CH_HEX, u64, x, "Unsigned");
46 |
47 | //Declare all the options parsers for vector types, with initializers
48 | #define ch_opt_add_declare_VI(ch_type_name, vector_name, c_type_name_default, short_name, long_name)\
49 | int ch_opt_add##short_name##I(ch_options_mode_e mode, char short_str, char* long_str, char* descr, CH_VECTOR(vector_name)** result_out, c_type_name_default default_val)
50 | ch_opt_add_declare_VI(CH_BOOLS, ch_bool, ch_bool, B, "Boolean List");
51 | ch_opt_add_declare_VI(CH_UINT64S, u64, u64, U, "Unsigned List");
52 | ch_opt_add_declare_VI(CH_INT64S, word, ch_word, I, "Integer List");
53 | ch_opt_add_declare_VI(CH_STRINGS, cstr, ch_cstr, S, "String List");
54 | ch_opt_add_declare_VI(CH_DOUBLES, float, ch_float, F, "Float List");
55 | ch_opt_add_declare_VI(CH_HEXS, u64, u64, X, "Unsigned List");
56 |
57 | //Declare all the options parsers for vector types, with uninitialized
58 | #define ch_opt_add_declare_VU(ch_type_name, vector_name, short_name, long_name)\
59 | int ch_opt_add##short_name##U(ch_options_mode_e mode, char short_str, char* long_str, char* descr, CH_VECTOR(vector_name)** result_out)
60 | ch_opt_add_declare_VU(CH_BOOLS, ch_bool, B, "Boolean List");
61 | ch_opt_add_declare_VU(CH_UINT64S, u64, U, "Unsigned List");
62 | ch_opt_add_declare_VU(CH_INT64S, word, I, "Integer List");
63 | ch_opt_add_declare_VU(CH_STRINGS, cstr, S, "String List");
64 | ch_opt_add_declare_VU(CH_DOUBLES, float, F, "Float List");
65 | ch_opt_add_declare_VU(CH_HEXS, u64, X, "Unsigned List");
66 |
67 | #define Vector_geti(type,vector,i) ((type*)vector.mem)[i]
68 |
69 |
70 | #define USE_CH_OPTIONS \
71 | ch_options_t opts = { 0 }
72 |
73 | int ch_opt_name(char* description);
74 | int ch_opt_tail(char* description);
75 | int ch_opt_short_description(char* description);
76 | int ch_opt_long_description(char* description);
77 | int ch_opt_parse(int argc, char** argv);
78 |
79 |
80 | #endif /* CH_OPTIONS_H_ */
81 |
--------------------------------------------------------------------------------
/libs/libchaste/include/options/options_vectors.h:
--------------------------------------------------------------------------------
1 | /*
2 | * options_vectors.h
3 | *
4 | * Created on: 16 Sep 2013
5 | * Author: mpg39
6 | */
7 |
8 | #ifndef OPTIONS_VECTORS_H_
9 | #define OPTIONS_VECTORS_H_
10 |
11 | #include "../data_structs/vector/vector_typed_declare_template.h"
12 |
13 | typedef enum {
14 | CH_OPTION_REQUIRED, //This option is required for the program to run
15 | CH_OPTION_OPTIONAL, //This option is not required but has a default value
16 | CH_OPTION_UNLIMTED, //This option produces a list of outputs
17 | CH_OPTION_FLAG, //This option is optional, and has no arguments
18 | } ch_options_mode_e;
19 |
20 |
21 | typedef struct ch_options_opt{
22 | ch_options_mode_e mode;
23 | ch_types_e type;
24 | void* var;
25 | char short_str;
26 | char* long_str;
27 | char* descr;
28 | int found;
29 | } ch_options_opt_t;
30 |
31 |
32 | declare_ch_vector(opts, ch_options_opt_t)
33 |
34 |
35 |
36 | #endif /* OPTIONS_VECTORS_H_ */
37 |
--------------------------------------------------------------------------------
/libs/libchaste/include/parsing/bool_parser.h:
--------------------------------------------------------------------------------
1 | /*
2 | * bool_parser.h
3 | *
4 | * Created on: Dec 20, 2012
5 | * Author: mgrosvenor
6 | */
7 |
8 | #ifndef BOOL_PARSER_H_
9 | #define BOOL_PARSER_H_
10 | #include
11 |
12 | #include "numeric_parser.h"
13 |
14 | num_result_t parse_bool(const char* c, size_t n, size_t i);
15 |
16 |
17 | #endif /* BOOL_PARSER_H_ */
18 |
--------------------------------------------------------------------------------
/libs/libchaste/include/parsing/numeric_parser.h:
--------------------------------------------------------------------------------
1 | /*
2 | * numeric_parser.h
3 | *
4 | * Created on: Dec 20, 2012
5 | * Author: mgrosvenor
6 | */
7 |
8 | #ifndef NUMERIC_PARSER_H_
9 | #define NUMERIC_PARSER_H_
10 |
11 | #include
12 | #include
13 |
14 | #include "../types/types.h"
15 |
16 | typedef struct{
17 | ch_types_e type;
18 | union{
19 | uint64_t val_uint;
20 | int64_t val_int;
21 | double val_dble;
22 | };
23 | ch_word index; //If the type returned is a valid number, return the index of the first char directly after the number
24 | } num_result_t;
25 |
26 |
27 | num_result_t parse_number(const char* c, size_t i);
28 | num_result_t parse_nnumber(const char* c, size_t i, size_t n);
29 |
30 |
31 | #endif /* NUMERIC_PARSER_H_ */
32 |
--------------------------------------------------------------------------------
/libs/libchaste/include/parsing/utils.h:
--------------------------------------------------------------------------------
1 | /*
2 | * utils.h
3 | *
4 | * Created on: Dec 20, 2012
5 | * Author: mgrosvenor
6 | */
7 |
8 | #ifndef UTILS_H_
9 | #define UTILS_H_
10 |
11 |
12 | /*
13 | * utils.c
14 | *
15 | * Created on: Dec 20, 2012
16 | * Author: mgrosvenor
17 | */
18 |
19 | #include "utils.h"
20 |
21 | int isodigit(char c);
22 | int isbdigit(char c);
23 | uint8_t getxdigit(char c);
24 | int iswhite(char c);
25 | int isnwhite(char c);
26 |
27 |
28 | #endif /* UTILS_H_ */
29 |
--------------------------------------------------------------------------------
/libs/libchaste/include/perf/perf.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) Matthew P. Grosvenor, 2012, All Rights Reserved
3 | *
4 | * Input stream definition
5 | *
6 | */
7 |
8 | #ifndef CH_PERF_H_
9 | #define CH_PERF_H_
10 |
11 | #include
12 | #include
13 | #include
14 |
15 | #include "../log/log.h" //Include this here, so users don't have to
16 | #include "../utils/util.h"
17 |
18 | //#warning "This is all broken and arch specifc. Need to make the logic and impl separate"
19 | #define uint64_t unsigned long long
20 |
21 | typedef struct {
22 | uint64_t ts; //Time the event was logged
23 | uint32_t event_id; //ID of the event, used to tie start and stop operations together
24 | uint32_t cond_id; //ID of the event, used to differentiate different start/stop conditions for the same ID.
25 | uint64_t data;
26 | } ch_perf_event_t;
27 |
28 |
29 | typedef struct {
30 | //Perf logging control
31 | u64 event_count;
32 | u64 event_index;
33 | u64 max_events;
34 | ch_perf_event_t* events;
35 |
36 | //Output control
37 | int fd;
38 |
39 | //Stop watch temps
40 | u64 timer_start;
41 | u64 timer_stop;
42 |
43 | //Get tsc
44 | u64 tsc;
45 |
46 |
47 | } ch_perf_t;
48 |
49 |
50 | #define USE_CH_PERF(events_max) \
51 | ch_perf_event_t ch_perf_events[events_max]; \
52 | ch_perf_t ch_perf = { \
53 | .event_count = 0, \
54 | .event_index = 0, \
55 | .max_events = events_max, \
56 | .events = ch_perf_events, \
57 | .fd = -1, \
58 | .timer_start = ~0, \
59 | .timer_stop = ~0, \
60 | .tsc = ~0 \
61 | }
62 |
63 | extern ch_perf_t ch_perf;
64 |
65 | //Borrowed from linux/arch/x86/include/asm/msr.h
66 | #define EAX_EDX_VAL(low, high) ((low) | ((uint64_t)(high) << 32))
67 | #define EAX_EDX_RET(low, high) "=a" (low), "=d" (high)
68 | #define DECLARE_ARGS(low, high) uint32_t low, high
69 |
70 | //Notes:
71 | //- This function is written as a macro to ensure that it is inlined
72 | //- Generally calls to rdtsc are prepended by a call to cpuid. This is done so that the
73 | // pipeline is flushed and that there is determinism about the moment when rdtsc is called.
74 | // Flushing the pipeline is an expensive call and not something that we want to do too much
75 | // on the critical path. For this reason I've decided to trade a little accuracy for
76 | // better overall performance.
77 | #ifndef NDEBUG
78 | #define ch_perf_event_start(ch_word_event_id, ch_word_cond_id, ch_word_data) \
79 | if(likely(ch_perf.event_index < ch_perf.max_events)){ \
80 | ch_perf.events[ch_perf.event_index].event_id = (ch_word_event_id); \
81 | ch_perf.events[ch_perf.event_index].cond_id = (ch_word_cond_id); \
82 | ch_perf.events[ch_perf.event_index].data = (ch_word_data); \
83 | DECLARE_ARGS(lo, hi); \
84 | __asm__ __volatile__("rdtsc" : EAX_EDX_RET(lo, hi)); \
85 | ch_perf.events[ch_perf.event_index].ts = EAX_EDX_VAL(lo, hi); \
86 | ch_perf.event_index++; \
87 | } \
88 | ch_perf.event_count++;
89 | #else
90 | #define ch_perf_event_start(ch_word_event_id, ch_word_cond_id, ch_word_data)
91 | #endif
92 |
93 |
94 |
95 | //Notes:
96 | //- This function is written as a macro to ensure that it is inlined
97 | //- Generally calls to rdtsc are prepended by a call to cpuid. This is done so that the
98 | // pipeline is flushed and that there is determinism about the moment when rdtsc is called.
99 | // Flushing the pipeline is an expensive call and not something that we want to do too much
100 | // on the critical path. For this reason I've decided to trade a little accuracy for
101 | // better overall performance.
102 | #ifndef NDEBUG
103 | #define ch_perf_event_stop(ch_word_event_id, ch_word_cond_id, ch_word_data) \
104 | if(likely(ch_perf.event_index < ch_perf.max_events)){ \
105 | DECLARE_ARGS(lo, hi); \
106 | __asm__ __volatile__("rdtsc" : EAX_EDX_RET(lo, hi)); \
107 | ch_perf.events[ch_perf.event_index].ts = EAX_EDX_VAL(lo, hi); \
108 | ch_perf.events[ch_perf.event_index].event_id = (ch_word_event_id) | (1<<31); \
109 | ch_perf.events[ch_perf.event_index].cond_id = (ch_word_cond_id); \
110 | ch_perf.events[ch_perf.event_index].data = (ch_word_data); \
111 | ch_perf.event_index++; \
112 | } \
113 | ch_perf.event_count++;
114 | #else
115 | #define ch_perf_event_stop(ch_word_event_id, ch_word_cond_id, ch_word_data)
116 | #endif
117 |
118 | typedef enum {
119 | ch_perf_output_tostdout,
120 | ch_perf_output_tostderr,
121 | ch_perf_output_tofile,
122 | //ch_perf_http, -- Not yet implemented
123 | } ch_perf_output_e;
124 |
125 |
126 | typedef enum {
127 | ch_perf_format_csv, //Output CSV -- Easy to read text format.
128 | ch_perf_format_ssv, //Output SSV -- Easy to read inside GNU plot, useless for everything else
129 | ch_perf_format_binary, //Output in binary format -- Nice and compact, easy to store, anaylse later.
130 | //ch_perf_format_http, -- Not yet implemented
131 | } ch_perf_format_e;
132 |
133 |
134 | void ch_perf_finish_(ch_perf_output_e output, ch_perf_format_e format, const char* filename);
135 |
136 | #ifndef NDEBU
137 | #define ch_perf_finish(ch_perf_output, ch_perf_format, filename)\
138 | ch_perf_finish_(ch_perf_output, ch_perf_format, filename);
139 | #else
140 | #define ch_perf_finish(ch_perf_output, ch_perf_format, filename)
141 | #endif
142 |
143 |
144 | #define ch_perf_timer_start { \
145 | DECLARE_ARGS(lo, hi); \
146 | __asm__ __volatile__("rdtsc" : EAX_EDX_RET(lo, hi)); \
147 | ch_perf.timer_start = EAX_EDX_VAL(lo, hi); \
148 | }
149 |
150 |
151 | #define ch_perf_timer_stop { \
152 | DECLARE_ARGS(lo, hi); \
153 | __asm__ __volatile__("rdtsc" : EAX_EDX_RET(lo, hi)); \
154 | ch_perf.timer_stop = EAX_EDX_VAL(lo, hi); \
155 | }
156 |
157 | #define ch_perf_timer_reset { \
158 | ch_perf.timer_start = ~0; \
159 | ch_perf.timer_stop = ~0; \
160 | }
161 |
162 |
163 | #define ch_perf_sample_tsc { \
164 | DECLARE_ARGS(lo, hi); \
165 | __asm__ __volatile__("rdtsc" : EAX_EDX_RET(lo, hi)); \
166 | ch_perf.tsc = EAX_EDX_VAL(lo, hi); \
167 | }
168 |
169 | #define ch_perf_cycles_now(result) { \
170 | DECLARE_ARGS(lo, hi); \
171 | __asm__ __volatile__("rdtsc" : EAX_EDX_RET(lo, hi)); \
172 | result = EAX_EDX_VAL(lo, hi); \
173 | }
174 |
175 |
176 | u64 ch_perf_get_watch_ticks();
177 | u64 ch_perf_get_tsc_sample();
178 |
179 |
180 | #endif /* CH_PERF_H_ */
181 |
--------------------------------------------------------------------------------
/libs/libchaste/include/perf/perf_mon.h:
--------------------------------------------------------------------------------
1 | // CamIO 2: perf_mon.h
2 | // Copyright (C) 2013: Matthew P. Grosvenor (matthew.grosvenor@cl.cam.ac.uk)
3 | // Licensed under BSD 3 Clause, please see LICENSE for more details.
4 |
5 | #ifndef PERF_MON_H_
6 | #define PERF_MON_H_
7 |
8 | #include "../types/types.h"
9 | #include
10 |
11 | /**
12 | * The TSC counter structure is used for both time and cycle based profiling/performance monitoring.
13 | * The intention is that 1 or more of these structures will be used in an array. Multiple instances
14 | * are used to monitor multiple stop conditions. i.e. If there are multiple paths to exit a function,
15 | * then an idea for which paths are taken most often and how much they cost can be gathered in real-
16 | * time or compiled out. The strong intention is that performance monitoring should be light weight
17 | * enough that it can be run in production without affecting performance (too much). At a minimum,
18 | * counter based performance monitoring is offered which only adds an additional increment operator
19 | * as it's cost but provides useful insight into code performance
20 | */
21 |
22 | typedef struct {
23 | //Sample using just incrementing a counter
24 | u64 start_count; //Number of times start counter was called. Only used for counter 0
25 | u64 end_count; //Number of times end counter was called
26 |
27 | //Sampling using timestamp counter
28 | u64 nanos_tmp; //Only used for counter 0
29 | u64 nanos_total;
30 | u64 nanos_max;
31 | u64 nanos_min;
32 | double nanos_avg;
33 |
34 | //Sampling using cycle counter
35 | u64 cycles_tmp; //Only used for counter 0
36 | u64 cycles_total;
37 | u64 cycles_max;
38 | u64 cycles_min;
39 | double cycles_avg;
40 | } TSC;
41 |
42 |
43 | /**
44 | * Per module performance monitoring. Use only once per file scope. Never in headers.
45 | */
46 |
47 | struct perf_mod_generic;
48 | typedef struct perf_mod_generic perf_mod_generic_t;
49 |
50 | struct perf_mod_generic{
51 | ch_word id;
52 | ch_cstr descr;
53 | ch_word descr_len;
54 | };
55 |
56 |
57 | #define make_perf_module(PERFS) \
58 | static struct perf_mod_t { \
59 | ch_word id; \
60 | ch_cstr descr; \
61 | ch_word descr_len; \
62 | PERFS \
63 | } perf_mod = { .id = 0, .descr = #PERFS, . descr_len = strlen(#PERFS) }
64 |
65 |
66 | #define get_perf_mod_ref (perf_mod_generic_t*)&perf_mod
67 |
68 | #define perf_mod_start( NAME ) \
69 | perf_mod.NAME[0].start_count += 1; \
70 | perf_mod.NAME[0].nanos_tmp = get_nanos_now();
71 |
72 |
73 | #define perf_mod_end( NAME, ID ) \
74 | perf_mod.NAME[ID].end_count += 1; \
75 | perf_mod.NAME[0].nanos_tmp = (get_nanos_now() - perf_mod.NAME[0].nanos_tmp); \
76 | perf_mod.NAME[ID].nanos_total += perf_mod.NAME[0].nanos_tmp; \
77 | perf_mod.NAME[ID].nanos_min = perf_mod.NAME[ID].nanos_min == 0 ? perf_mod.NAME[0].nanos_tmp : perf_mod.NAME[0].nanos_tmp < perf_mod.NAME[ID].nanos_min ? perf_mod.NAME[0].nanos_tmp : perf_mod.NAME[ID].nanos_min ; \
78 | perf_mod.NAME[ID].nanos_max = perf_mod.NAME[0].nanos_tmp > perf_mod.NAME[ID].nanos_max ? perf_mod.NAME[0].nanos_tmp : perf_mod.NAME[ID].nanos_max ;
79 |
80 |
81 | void print_perf_stats(perf_mod_generic_t* perf_mod);
82 | u64 get_nanos_now();
83 |
84 | #endif /* PERF_MON_H_ */
85 |
--------------------------------------------------------------------------------
/libs/libchaste/include/scripts/camio_prepare_boot.sh:
--------------------------------------------------------------------------------
1 | #! /bin/sh
2 |
3 | #This scrpit kicks off the install process, it checks that a sufficiently new
4 | #version of python is available assuming that it is, starts the installer script
5 |
6 |
7 | #Try to find python or accept the first command line arg as the ptyhon path
8 | python_dir=$(which python)
9 |
10 | if [ $# -gt 0 ]
11 | then
12 | python_dir="$1"
13 | fi
14 |
15 | if [ ! -f "$python_dir" ]
16 | then
17 | echo "Could not find python in \"$python_dir\", Python is not installed."
18 | echo "Please install it before continuing,"
19 | fi
20 |
21 | cd scripts
22 | python camio_prepare_boot.py
23 |
24 |
25 |
--------------------------------------------------------------------------------
/libs/libchaste/include/string/string.h:
--------------------------------------------------------------------------------
1 | /*
2 | * string_utils.h
3 | *
4 | * Created on: Jul 6, 2013
5 | * Author: mgrosvenor
6 | */
7 |
8 | #ifndef STRING_UTILS_H_
9 | #define STRING_UTILS_H_
10 |
11 | #include "../types/types.h"
12 | #include
13 |
14 |
15 | void ch_str_free(ch_str* s); //Safe free function
16 | i64 ch_str_resize(ch_str* rhs,i64 newsize); //
17 | ch_str ch_str_new(const char* s,i64 size, ch_bool is_char); //Try not to use this, use the macro functions below which are better optimised for useful situations
18 | ch_str ch_str_cat(ch_str* lhs, ch_str rhs);
19 | ch_str ch_str_cat_cstr(ch_str* lhs, const char* cstr);
20 | ch_str ch_str_cat_char(ch_str* lhs, const char ch);
21 | ch_str ch_str_trunc(ch_str* lhs, ch_word count);
22 | ch_word ch_str_eq(ch_str lhs, ch_str rhs);
23 |
24 |
25 |
26 | #define CH_STR_CONST_NEW(name, s) ch_str name = CH_STR_CONST_LIT(s)
27 | #define CH_STR_CONST_LIT(s) { .cstr = (char*)s, .is_const = 1, .slen = strlen(s), .mlen = strlen(s) }
28 | #define CH_STR_CONST_LIT_NSTRL(s) { .cstr = (char*)s, .is_const = 1, .slen = -1, .mlen = -1 }
29 | #define CH_STR_FUNC(s) { .cstr = (char*)s, .is_const = -1, .slen = -1, .mlen = -1 }
30 | #define CH_STR_NULL { .cstr = NULL, .is_const = 1, .slen = 0, .mlen = 0 }
31 | #define CH_STR(s,sz) ch_str_new(s, sz, 0)
32 |
33 | #define CH_STR_CAT(lhs,rhs) ch_str_cat(lhs, rhs)
34 | #define CH_STR_CAT_CSTR(lhs,rhs) ch_str_cat_cstr(lhs, rhs)
35 | #define CH_STR_CAT_CHAR(lhs,rhs) ch_str_cat_char(lhs, rhs)
36 |
37 | #define CH_STR_CSTR(ch_str) ( (ch_str).cstr)
38 | #define CH_STR_CSTR_END(ch_str) ( (ch_str).cstr + (ch_str).slen )
39 | #define CH_STR_AVAIL(ch_str) ( (ch_str).mlen -1 - (ch_str).slen )
40 | #define CH_STR_LEN(ch_str) ( (ch_str).slen)
41 |
42 |
43 | #endif /* STRING_UTILS_H_ */
44 |
45 |
46 |
--------------------------------------------------------------------------------
/libs/libchaste/include/sys/sys.h:
--------------------------------------------------------------------------------
1 | /*
2 | * sys.h
3 | *
4 | * Created on: Apr 23, 2015
5 | * Author: mgrosvenor
6 | */
7 |
8 | #ifndef SYS_H_
9 | #define SYS_H_
10 |
11 | #ifdef __APPLE__
12 | # include "sys_apple.h"
13 | #else
14 | # include "sys_linux.h"
15 | #endif
16 | //#else
17 | //# warning "LibChaste Needs to be ported to this system"
18 | //#endif
19 |
20 |
21 | #endif /* SYS_H_ */
22 |
--------------------------------------------------------------------------------
/libs/libchaste/include/sys/sys_apple.h:
--------------------------------------------------------------------------------
1 | /*
2 | * sys_apple.h
3 | *
4 | * Created on: Apr 23, 2015
5 | * Author: mgrosvenor
6 | */
7 |
8 | #ifndef SYS_APPLE_H_
9 | #define SYS_APPLE_H_
10 |
11 | #include
12 | #include
13 |
14 | #ifdef __APPLE__ //These definitions are only required for apple/darwin
15 |
16 | #define CLOCK_REALTIME 0
17 | void clock_gettime(int ignored, struct timespec *ts);
18 |
19 | #endif
20 |
21 | #endif /* SYS_APPLE_H_ */
22 |
--------------------------------------------------------------------------------
/libs/libchaste/include/sys/sys_linux.h:
--------------------------------------------------------------------------------
1 | /*
2 | * sys_linux.h
3 | *
4 | * Created on: Apr 23, 2015
5 | * Author: mgrosvenor
6 | */
7 |
8 | #ifndef SYS_LINUX_H_
9 | #define SYS_LINUX_H_
10 |
11 |
12 | #endif /* SYS_LINUX_H_ */
13 |
--------------------------------------------------------------------------------
/libs/libchaste/include/term_color/term_color.h:
--------------------------------------------------------------------------------
1 | /*
2 | * ch_term_colors.h
3 | *
4 | * Created on: Jul 2, 2013
5 | * Author: mgrosvenor
6 | */
7 | #include
8 |
9 | #include "../types/types.h"
10 | #include "../string/string.h"
11 |
12 |
13 | #ifndef CH_TERM_COLORS_H_
14 | #define CH_TERM_COLORS_H_
15 |
16 | //Private definitions, don't use directly
17 | #define CH_TERM_ATTR_RAW_RESET "0"
18 | #define CH_TERM_ATTR_RAW_BRIGHT "1"
19 | #define CH_TERM_ATTR_RAW_DIM "2"
20 | #define CH_TERM_ATTR_RAW_UNDERLINE "3"
21 | #define CH_TERM_ATTR_RAW_BLINK "4"
22 | #define CH_TERM_ATTR_RAW_REVERSE "7"
23 | #define CH_TERM_ATTR_RAW_HIDDEN "8"
24 |
25 | //Private definitions, don't use directly
26 | #define CH_TERM_COL_RAW_BLACK "0"
27 | #define CH_TERM_COL_RAW_RED "1"
28 | #define CH_TERM_COL_RAW_GREEN "2"
29 | #define CH_TERM_COL_RAW_YELLOW "3"
30 | #define CH_TERM_COL_RAW_BLUE "4"
31 | #define CH_TERM_COL_RAW_MAGENTA "5"
32 | #define CH_TERM_COL_RAW_CYAN "6"
33 | #define CH_TERM_COL_RAW_WHITE "7"
34 |
35 | //Private definitions, don't use directly
36 | #define CH_TERM_COLOR(col) CH_STR_CONST_LIT_NSTRL("\x1B[3"col"m")
37 | #define CH_TERM_COLOR_ATTR(col,attr) CH_STR_CONST_LIT_NSTRL("\x1B["attr";3"col"m")
38 | #define CH_TERM_ATTR(attr) CH_STR_CONST_LIT_NSTRL("\x1B["attr"m")
39 |
40 | //Colors to be used by users - Please use directly!
41 | #define CH_TERM_COL_NONE CH_TERM_ATTR(CH_TERM_ATTR_RAW_RESET)
42 | #define CH_TERM_COL_BLACK CH_TERM_COLOR(CH_TERM_COL_RAW_BLACK)
43 | #define CH_TERM_COL_BLUE CH_TERM_COLOR(CH_TERM_COL_RAW_BLUE)
44 | #define CH_TERM_COL_CYAN CH_TERM_COLOR(CH_TERM_COL_RAW_CYAN)
45 | #define CH_TERM_COL_GREEN CH_TERM_COLOR(CH_TERM_COL_RAW_GREEN)
46 | #define CH_TERM_COL_MAGENTA CH_TERM_COLOR(CH_TERM_COL_RAW_MAGENTA)
47 | #define CH_TERM_COL_RED CH_TERM_COLOR(CH_TERM_COL_RAW_RED)
48 | #define CH_TERM_COL_WHITE CH_TERM_COLOR(CH_TERM_COL_RAW_WHITE)
49 | #define CH_TERM_COL_YELLOW CH_TERM_COLOR(CH_TERM_COL_RAW_YELLOW)
50 |
51 | #define CH_TERM_COL_BRIGHT_BLACK CH_TERM_COLOR_ATTR(CH_TERM_COL_RAW_BLACK, CH_TERM_ATTR_RAW_BRIGHT)
52 | #define CH_TERM_COL_BRIGHT_BLUE CH_TERM_COLOR_ATTR(CH_TERM_COL_RAW_BLUE, CH_TERM_ATTR_RAW_BRIGHT)
53 | #define CH_TERM_COL_BRIGHT_CYAN CH_TERM_COLOR_ATTR(CH_TERM_COL_RAW_CYAN, CH_TERM_ATTR_RAW_BRIGHT)
54 | #define CH_TERM_COL_BRIGHT_GREEN CH_TERM_COLOR_ATTR(CH_TERM_COL_RAW_GREEN, CH_TERM_ATTR_RAW_BRIGHT)
55 | #define CH_TERM_COL_BRIGHT_MAGENTA CH_TERM_COLOR_ATTR(CH_TERM_COL_RAW_MAGENTA, CH_TERM_ATTR_RAW_BRIGHT)
56 | #define CH_TERM_COL_BRIGHT_RED CH_TERM_COLOR_ATTR(CH_TERM_COL_RAW_RED, CH_TERM_ATTR_RAW_BRIGHT)
57 | #define CH_TERM_COL_BRIGHT_WHITE CH_TERM_COLOR_ATTR(CH_TERM_COL_RAW_WHITE, CH_TERM_ATTR_RAW_BRIGHT)
58 | #define CH_TERM_COL_BRIGHT_YELLOW CH_TERM_COLOR_ATTR(CH_TERM_COL_RAW_YELLOW, CH_TERM_ATTR_RAW_BRIGHT)
59 |
60 | #define CH_TERM_COL_DIM_BLACK CH_TERM_COLOR_ATTR(CH_TERM_COL_RAW_BLACK, CH_TERM_ATTR_RAW_DIM)
61 | #define CH_TERM_COL_DIM_BLUE CH_TERM_COLOR_ATTR(CH_TERM_COL_RAW_BLUE, CH_TERM_ATTR_RAW_DIM)
62 | #define CH_TERM_COL_DIM_CYAN CH_TERM_COLOR_ATTR(CH_TERM_COL_RAW_CYAN, CH_TERM_ATTR_RAW_DIM)
63 | #define CH_TERM_COL_DIM_GREEN CH_TERM_COLOR_ATTR(CH_TERM_COL_RAW_GREEN, CH_TERM_ATTR_RAW_DIM)
64 | #define CH_TERM_COL_DIM_MAGENTA CH_TERM_COLOR_ATTR(CH_TERM_COL_RAW_MAGENTA, CH_TERM_ATTR_RAW_DIM)
65 | #define CH_TERM_COL_DIM_WHITE CH_TERM_COLOR_ATTR(CH_TERM_COL_RAW_WHITE, CH_TERM_ATTR_RAW_DIM)
66 | #define CH_TERM_COL_DIM_RED CH_TERM_COLOR_ATTR(CH_TERM_COL_RAW_RED, CH_TERM_ATTR_RAW_DIM)
67 | #define CH_TERM_COL_DIM_YELLOW CH_TERM_COLOR_ATTR(CH_TERM_COL_RAW_YELLOW, CH_TERM_ATTR_RAW_DIM)
68 |
69 | #define CH_TERM_COL_EMPH_BLACK CH_TERM_COLOR_ATTR(CH_TERM_COL_RAW_BLACK, CH_TERM_ATTR_RAW_UNDERLINE)
70 | #define CH_TERM_COL_EMPH_BLUE CH_TERM_COLOR_ATTR(CH_TERM_COL_RAW_BLUE, CH_TERM_ATTR_RAW_UNDERLINE)
71 | #define CH_TERM_COL_EMPH_CYAN CH_TERM_COLOR_ATTR(CH_TERM_COL_RAW_CYAN, CH_TERM_ATTR_RAW_UNDERLINE)
72 | #define CH_TERM_COL_EMPH_GREEN CH_TERM_COLOR_ATTR(CH_TERM_COL_RAW_GREEN, CH_TERM_ATTR_RAW_UNDERLINE)
73 | #define CH_TERM_COL_EMPH_MAGENTA CH_TERM_COLOR_ATTR(CH_TERM_COL_RAW_MAGENTA, CH_TERM_ATTR_RAW_UNDERLINE)
74 | #define CH_TERM_COL_EMPH_WHITE CH_TERM_COLOR_ATTR(CH_TERM_COL_RAW_WHITE, CH_TERM_ATTR_RAW_UNDERLINE)
75 | #define CH_TERM_COL_EMPH_RED CH_TERM_COLOR_ATTR(CH_TERM_COL_RAW_RED, CH_TERM_ATTR_RAW_UNDERLINE)
76 | #define CH_TERM_COL_EMPH_YELLOW CH_TERM_COLOR_ATTR(CH_TERM_COL_RAW_YELLOW, CH_TERM_ATTR_RAW_UNDERLINE)
77 |
78 |
79 | typedef ch_str ch_colour_t;
80 |
81 | int dprintf_color_va(int fd, ch_colour_t color, ch_str format, va_list va);
82 | int dprintf_color(int fd, ch_colour_t color, ch_str format, ...);
83 | int printf_color_va( ch_colour_t color, ch_str format, va_list va);
84 | int printf_color( ch_colour_t color, ch_str format, ...);
85 |
86 |
87 |
88 | #endif /* CH_TERM_COLORS_H_ */
89 |
--------------------------------------------------------------------------------
/libs/libchaste/include/timing/timestamp.h:
--------------------------------------------------------------------------------
1 | /*
2 | * timestamp.h
3 | *
4 | * Created on: Jul 3, 2013
5 | * Author: mgrosvenor
6 | */
7 |
8 | #ifndef TIMESTAMP_H_
9 | #define TIMESTAMP_H_
10 |
11 | #include "../types/types.h"
12 |
13 | ch_str generate_iso_timestamp(ch_bool use_gmt, ch_word subseconds, ch_bool incl_tz_offset);
14 |
15 | #endif /* TIMESTAMP_H_ */
16 |
--------------------------------------------------------------------------------
/libs/libchaste/include/types/types.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) Matthew P. Grosvenor, 2012, All Rights Reserved
3 | */
4 |
5 |
6 | #ifndef CH_TYPES_H_
7 | #define CH_TYPES_H_
8 |
9 | #include
10 | #include
11 | #include
12 |
13 | //#include "../deps/libcgen/vector.h"
14 |
15 | //Unsigned types, use these sparingly
16 | typedef uint8_t u8;
17 | typedef uint16_t u16;
18 | typedef uint32_t u32;
19 | //typedef uint64_t u64; //Try to avoid this unless absolutely necessary. Too many bugs are caused by int/uint mixups
20 | typedef unsigned long long u64; //Try to avoid this unless absolutely necessary. Too many bugs are caused by int/uint mixups
21 |
22 | //Signed types, use these sparingly
23 | typedef int8_t i8;
24 | typedef int16_t i16;
25 | typedef int32_t i32;
26 | typedef long long i64; //Try to avoid this, use ch_word.
27 |
28 |
29 | //CH Library Preferred Types
30 | typedef size_t ch_machine; //Use this sparingly, only when it really matters that the int size is the same as the word size
31 | typedef i8 ch_char;
32 | typedef u8 ch_byte;
33 | typedef long long int ch_word; //Singed int chosen specifically to avoid underrun and signed/unsigned comparisons
34 | typedef bool ch_bool; //Give the compiler tons of freedom to decide what to do here
35 | typedef double ch_float; //Again we preference 64bit machines explicitly
36 |
37 | //Please avoid using char*. CH strings are a thin wrapper, that support easy concatenation and other functions
38 | typedef struct {
39 | char* cstr; //Can be NULL or point to a const or non-const memory area
40 | int is_const; //Can be -1 (unknown), 0 (can call free) or 1 (cannot call free)
41 | i64 slen; //A valid string len is always -1 (unknown), or < mlen
42 | i64 mlen; //A valid memory len is always -1 (unknown), or > slen
43 | } ch_str;
44 |
45 | typedef char* ch_cstr; //Use this sparingly, only when it really matters that you are backwards compatible with c-strings
46 | typedef const char* ch_ccstr; //Use this sparingly as well
47 |
48 | //#define cstr(bstr) ((char*)(bstr->data))
49 |
50 | typedef enum {
51 | CH_NO_TYPE = 0,
52 | CH_BOOL,
53 | CH_UINT64,
54 | CH_HEX,
55 | CH_INT64,
56 | CH_STRING,
57 | CH_DOUBLE,
58 | CH_BOOLS, //Vector types
59 | CH_UINT64S,
60 | CH_INT64S,
61 | CH_HEXS,
62 | CH_STRINGS,
63 | CH_DOUBLES,
64 | } ch_types_e;
65 |
66 | ch_word is_vector(ch_word type);
67 |
68 | typedef int (*cmp_void_f)(const void*, const void*);
69 |
70 |
71 |
72 | #endif /* CH_TYPES_H_ */
73 |
--------------------------------------------------------------------------------
/libs/libchaste/include/utils/debug.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2015, All rights reserved.
3 | * See LICENSE.txt for full details.
4 | *
5 | * Created: Jul 30, 2015
6 | * File name: debug.h
7 | * Description:
8 | *
9 | */
10 | #ifndef DEBUG_H_
11 | #define DEBUG_H_
12 |
13 | #include "../types/types.h"
14 |
15 | typedef enum {
16 | DBG,
17 | ERR,
18 | WARN
19 | } ch_dbg_mode_e;
20 |
21 |
22 | ch_word ch_debug_out_(
23 | ch_bool info,
24 | ch_dbg_mode_e mode,
25 | ch_word line_num,
26 | const char* filename,
27 | const char* function,
28 | const char* format, ... );
29 | #define ERR( /*format, args*/...) camio_err_helper(__VA_ARGS__, "")
30 | #define camio_err_helper(format, ...) ch_debug_out_(true, ERR, __LINE__, __FILE__, __FUNCTION__, format, __VA_ARGS__ )
31 | #define ERR2( /*format, args*/...) camio_err_helper(__VA_ARGS__, "")
32 | #define camio_err_helper2(format, ...) ch_debug_out_(false, ERR, __LINE__, __FILE__, __FUNCTION__, format, __VA_ARGS__ )
33 |
34 |
35 |
36 | #ifndef NDEBUG
37 | //ch_word ch_debug_out_(ch_bool info, ch_word line_num, const char* filename, const char* function, const char* format, ... );
38 | #define DBG( /*format, args*/...) ch_debug_helper(__VA_ARGS__, "")
39 | #define ch_debug_helper(format, ...) ch_debug_out_(true,DBG,__LINE__, __FILE__, __FUNCTION__, format, __VA_ARGS__ )
40 | #define DBG2( /*format, args*/...) ch_debug_helper2(__VA_ARGS__, "")
41 | #define ch_debug_helper2(format, ...) ch_debug_out_(false,DBG,__LINE__, __FILE__, __FUNCTION__, format, __VA_ARGS__ )
42 | #define WARN( /*format, args*/...) ch_debug_helper3(__VA_ARGS__, "")
43 | #define ch_debug_helper3(format, ...) ch_debug_out_(true,WARN,__LINE__, __FILE__, __FUNCTION__, format, __VA_ARGS__ )
44 | #else
45 | #define DBG( /*format, args*/...)
46 | #define DBG2( /*format, args*/...)
47 | #define WARN( /*format, args*/...)
48 | #endif
49 |
50 | void hexdump(const void *data, int size);
51 |
52 |
53 | #endif /* DEBUG_H_ */
54 |
--------------------------------------------------------------------------------
/libs/libchaste/include/utils/util.h:
--------------------------------------------------------------------------------
1 | /*
2 | * util.h
3 | *
4 | * Created on: Nov 18, 2012
5 | * Author: mgrosvenor
6 | */
7 |
8 | #ifndef CH_UTIL_H_
9 | #define CH_UTIL_H_
10 |
11 | #define iflikely(x) if(__builtin_expect((long long)(x),1))
12 | #define ifunlikely(x) if(__builtin_expect((long long)(x),0))
13 | #define ifeqlikely(x) if((x))
14 |
15 | #define MIN(x,y) ( (x) < (y) ? (x) : (y))
16 | #define MIN3(x,y,z) (MIN(MIN(x,y),z))
17 | #define MAX(x,y) ( (x) > (y) ? (x) : (y))
18 |
19 | #include "../types/types.h"
20 | #include "debug.h"
21 | ///**
22 | // * (from Linux kernel source)
23 | // * container_of - cast a member of a structure out to the containing structure
24 | // * @ptr: the pointer to the member.
25 | // * @type: the type of the container struct this is embedded in.
26 | // * @member: the name of the member within the struct.
27 | // *
28 | // */
29 | #define container_of(ptr, type, member) ({ \
30 | const typeof( ((type *)0)->member ) *__mptr = (ptr); \
31 | (type *)( (char *)__mptr - offsetof(type,member) );})
32 |
33 |
34 | /*
35 | * The below version is borrowed from http://stackoverflow.com/questions/10269685/kernels-container-of-any-way-to-make-it-iso-conforming
36 | * The new one is better because it is iso compatible (apparently)
37 | */
38 |
39 | #ifdef __GNUC__
40 | #define member_type(type, member) __typeof__ (((type *)0)->member)
41 | #else
42 | #define member_type(type, member) const void
43 | #endif
44 |
45 |
46 | //#ifndef __clang__
47 | // #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
48 | //#endif
49 |
50 | ch_word next_pow2(ch_word v);
51 |
52 | #define CH_ASSERT(p) do { if(!(p)) { fprintf(stdout, "Error in %s: failed assertion \""#p"\" on line %u\n", __FUNCTION__, __LINE__); result = 0; } } while(0)
53 |
54 | //Uses integer division to round up
55 | #define round_up( value, nearest) ((( value + nearest -1) / nearest ) * nearest )
56 |
57 | #endif /* UTIL_H_ */
58 |
--------------------------------------------------------------------------------
/libs/libchaste/libchaste.a:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cisco/exact-capture/2a7b74e66cbbafcec7c39947dea63bec03972685/libs/libchaste/libchaste.a
--------------------------------------------------------------------------------
/src/data_structs/eiostream_vec.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017,2018 All rights reserved.
3 | * See LICENSE.txt for full details.
4 | *
5 | * Created: 7 Jul 2017
6 | * Author: Matthew P. Grosvenor
7 | * Description:
8 | * Implementation of a libchaste vector, containing exactio
9 | * streams
10 | */
11 |
12 |
13 | #include
14 | #include "eiostream_vec.h"
15 |
16 | define_ch_vector(eiostreamp,eio_stream_t*)
17 |
--------------------------------------------------------------------------------
/src/data_structs/eiostream_vec.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017,2018 All rights reserved.
3 | * See LICENSE.txt for full details.
4 | *
5 | * Created: 7 Jul 2017
6 | * Author: Matthew P. Grosvenor
7 | * Description:
8 | * Declaration of a libchaste vector, containing exactio
9 | * streams
10 | */
11 |
12 |
13 | #ifndef SRC_DATA_STRUCTS_EIOSTREAM_VEC_H_
14 | #define SRC_DATA_STRUCTS_EIOSTREAM_VEC_H_
15 |
16 | #include
17 |
18 | #include "../exactio/exactio.h"
19 |
20 | declare_ch_vector(eiostreamp,eio_stream_t*)
21 |
22 |
23 | #endif /* SRC_DATA_STRUCTS_PTHREAD_VEC_H_ */
24 |
--------------------------------------------------------------------------------
/src/data_structs/expcap.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017,2018 All rights reserved.
3 | * See LICENSE.txt for full details.
4 | *
5 | * Created: 5 Mar 2018
6 | * Author: Matthew P. Grosvenor
7 | * Description:
8 | * Declaration of a the expcap footer structure. This structure
9 | * makes it possible to include picosecond timestamps (for high resolution
10 | * capture), port and device IDs (for traceability) and dropped counters and
11 | * flags (for debugging). It is appended to each packet.
12 | */
13 |
14 |
15 | #ifndef SRC_DATA_STRUCTS_EXPCAP_H_
16 | #define SRC_DATA_STRUCTS_EXPCAP_H_
17 |
18 | #include
19 |
20 | enum {
21 | EXPCAP_FLAG_NONE = 0x00, //No flags
22 | EXPCAP_FLAG_HASCRC = 0x01, //New CRC included
23 | EXPCAP_FLAG_ABRT = 0x02, //Frame aborted
24 | EXPCAP_FLAG_CRPT = 0x04, //Frame corrupt
25 | EXPCAP_FLAG_TRNC = 0x08, //Frame truncated
26 | EXPCAP_FLAG_SWOVFL = 0x10, //A software overflow happened
27 | EXPCAP_FLAG_HWOVFL = 0x20, //A hardware overflow happened
28 | };
29 |
30 |
31 | typedef struct expcap_pktftr {
32 | uint64_t ts_secs : 32; /* 32bit seconds = max 136 years */
33 | uint64_t ts_psecs :40; /* 40bit picos = max 1.09 seconds */
34 | uint8_t flags;
35 | uint8_t dev_id;
36 | uint8_t port_id;
37 | union {
38 | struct{
39 | uint16_t dropped;
40 | uint16_t _reserved;
41 | } extra;
42 | uint32_t new_fcs;
43 | } foot;
44 | } __attribute__((packed)) expcap_pktftr_t;
45 |
46 |
47 | #endif /* SRC_DATA_STRUCTS_EXPCAP_H_ */
48 |
--------------------------------------------------------------------------------
/src/data_structs/pcap-structures.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017,2018 All rights reserved.
3 | * See LICENSE.txt for full details.
4 | *
5 | * Created: 10 July 2017
6 | * Author: Matthew P. Grosvenor
7 | * Description:
8 | * A local declaration of the the PCAP file format headers, to avoid pulling in
9 | * all of libpcap
10 | */
11 |
12 |
13 | #ifndef SRC_DATA_STRUCTS_PCAP_STRUCTURES_H_
14 | #define SRC_DATA_STRUCTS_PCAP_STRUCTURES_H_
15 |
16 | #include
17 | #include
18 | #include "../data_structs/timespecps.h"
19 |
20 | #define TCPDUMP_MAGIC 0xa1b2c3d4
21 | #define NSEC_TCPDUMP_MAGIC 0xa1b23c4d
22 | #define PCAP_VERSION_MAJOR 2
23 | #define PCAP_VERSION_MINOR 4
24 | #define DLT_EN10MB 1
25 |
26 | typedef struct __attribute__ ((packed)) pcap_file_header {
27 | uint32_t magic;
28 | uint16_t version_major;
29 | uint16_t version_minor;
30 | uint32_t thiszone; /* gmt to local correction */
31 | uint32_t sigfigs; /* accuracy of timestamps */
32 | uint32_t snaplen; /* max length saved portion of each pkt */
33 | uint32_t linktype; /* data link type (LINKTYPE_*) */
34 | } __attribute__ ((packed)) pcap_file_header_t;
35 |
36 | typedef struct __attribute__ ((packed)) pcap_pkthdr {
37 | union {
38 | struct{
39 | uint32_t ts_sec; /* time stamp */
40 | uint32_t ts_usec;
41 | } us;
42 | struct{
43 | uint32_t ts_sec; /* time stamp */
44 | uint32_t ts_nsec;
45 | } ns;
46 | int64_t raw;
47 | } ts;
48 |
49 | uint32_t caplen; /* length of portion present */
50 | uint32_t len; /* length this packet (off wire) */
51 | } __attribute__ ((packed)) pcap_pkthdr_t;
52 |
53 | #endif /* SRC_DATA_STRUCTS_PCAP_STRUCTURES_H_ */
54 |
--------------------------------------------------------------------------------
/src/data_structs/pthread_vec.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017,2018 All rights reserved.
3 | * See LICENSE.txt for full details.
4 | *
5 | * Created: 7 July 2017
6 | * Author: Matthew P. Grosvenor
7 | * Description:
8 | * Implementaton of a libchaste vector containing pthread structures.
9 | */
10 | #include
11 | #include "pthread_vec.h"
12 |
13 | define_ch_vector(pthread,pthread_t)
14 |
15 | define_ch_vector_cmp(pthread,pthread_t)
16 |
--------------------------------------------------------------------------------
/src/data_structs/pthread_vec.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017,2018 All rights reserved.
3 | * See LICENSE.txt for full details.
4 | *
5 | * Created: 7 July 2017
6 | * Author: Matthew P. Grosvenor
7 | * Description:
8 | * Declaration of a libchaste vector containing pthread structures.
9 | */
10 |
11 | #ifndef SRC_DATA_STRUCTS_PTHREAD_VEC_H_
12 | #define SRC_DATA_STRUCTS_PTHREAD_VEC_H_
13 |
14 | #include
15 | #include
16 |
17 | declare_ch_vector(pthread,pthread_t)
18 |
19 |
20 | #endif /* SRC_DATA_STRUCTS_PTHREAD_VEC_H_ */
21 |
--------------------------------------------------------------------------------
/src/data_structs/timespecps.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017,2018 All rights reserved.
3 | * See LICENSE.txt for full details.
4 | *
5 | * Created: 13 July 2017
6 | * Author: Matthew P. Grosvenor
7 | * Description:
8 | * A local definition of a timespec like structure for containing picosecond
9 | * values
10 | */
11 |
12 | #ifndef SRC_DATA_STRUCTS_TIMESPECPS_H_
13 | #define SRC_DATA_STRUCTS_TIMESPECPS_H_
14 |
15 | #include
16 |
17 | typedef struct timespecps {
18 | uint64_t tv_sec;
19 | uint64_t tv_psec;
20 | } __attribute__((packed)) timespecps_t;
21 |
22 |
23 | #endif /* SRC_DATA_STRUCTS_TIMESPECPS_H_ */
24 |
--------------------------------------------------------------------------------
/src/exact-capture-listener.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017,2018 All rights reserved.
3 | * See LICENSE.txt for full details.
4 | *
5 | * Created: 4 Aug 2017
6 | * Author: Matthew P. Grosvenor
7 | * Description: Definition of listener threads
8 | */
9 |
10 |
11 | #ifndef SRC_EXACT_CAPTURE_LISTENER_C_
12 | #define SRC_EXACT_CAPTURE_LISTENER_C_
13 |
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 | #include
20 | #include
21 | #include
22 | #include
23 |
24 | #include
25 | #include
26 | #include
27 | #include
28 | #include
29 |
30 | #include "data_structs/pthread_vec.h"
31 | #include "data_structs/eiostream_vec.h"
32 | #include "data_structs/pcap-structures.h"
33 |
34 | #include "exactio/exactio.h"
35 | #include "exactio/exactio_exanic.h"
36 | #include "exactio/exactio_timing.h"
37 |
38 | #include "exact-capture.h"
39 |
40 | typedef struct
41 | {
42 | char* interface;
43 | CH_VECTOR(cstr)* dests;
44 | volatile bool* stop;
45 | bool dummy_istream;
46 | bool dummy_ostream;
47 | int64_t ltid; /* Listener thread id */
48 |
49 | exanic_t* nic;
50 | int exanic_port;
51 | int exanic_dev_num;
52 | char exanic_dev[16];
53 |
54 | bool kernel_bypass;
55 | bool promisc;
56 |
57 | } listener_params_t;
58 |
59 | void* listener_thread (void* params);
60 |
61 | #endif /* SRC_EXACT_CAPTURE_LISTENER_C_ */
62 |
--------------------------------------------------------------------------------
/src/exact-capture-writer.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017,2018 All rights reserved.
3 | * See LICENSE.txt for full details.
4 | *
5 | * Created: 4 Aug 2017
6 | * Author: Matthew P. Grosvenor
7 | * Description: Definition of writer threads
8 | */
9 |
10 |
11 | #ifndef SRC_EXACT_CAPTURE_WRITER_C_
12 | #define SRC_EXACT_CAPTURE_WRITER_C_
13 |
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 | #include
20 | #include
21 | #include
22 | #include
23 |
24 | #include
25 | #include
26 | #include
27 | #include
28 | #include
29 |
30 | #include "data_structs/pthread_vec.h"
31 | #include "data_structs/eiostream_vec.h"
32 | #include "data_structs/pcap-structures.h"
33 |
34 | #include "exactio/exactio.h"
35 | #include "exactio/exactio_exanic.h"
36 | #include "exactio/exactio_timing.h"
37 |
38 | #include "exact-capture.h"
39 | #include "utils.h"
40 |
41 | typedef struct
42 | {
43 | char* destination;
44 | CH_VECTOR(cstr)* interfaces;
45 | int* exanic_port_id;
46 | int* exanic_dev_id;
47 | volatile bool* stop;
48 | bool dummy_istream;
49 | bool dummy_ostream;
50 | int64_t wtid; /* Writer thread id */
51 | } writer_params_t;
52 |
53 | typedef struct
54 | {
55 | eio_stream_t* istream;
56 | eio_stream_t* exa_istream;
57 | ch_word dev_id;
58 | ch_word port_num;
59 | } istream_state_t;
60 |
61 | void* writer_thread (void* params);
62 |
63 |
64 | #endif /* SRC_EXACT_CAPTURE_WRITER_C_ */
65 |
--------------------------------------------------------------------------------
/src/exact-capture.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017,2018 All rights reserved.
3 | * See LICENSE.txt for full details.
4 | *
5 | * Created: 4 Aug 2017
6 | * Author: Matthew P. Grosvenor
7 | * Description: Useful global definitions for the application, especially stats
8 | */
9 |
10 |
11 | #ifndef SRC_EXACT_CAPTURE_H_
12 | #define SRC_EXACT_CAPTURE_H_
13 |
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 |
20 |
21 | #define MIN_ETH_PKT (64)
22 |
23 | /*
24 | * High efficiency disk writing uses O_DIRECT, but writing must be aligned and
25 | * sized as a multiple of the disk block size
26 | */
27 | #define DISK_BLOCK (4096)
28 |
29 | /*
30 | * BRINGs are used join listener and writer threads to each other. They are
31 | * named shared memory rings that reside in /dev/shm.
32 | */
33 | #define BRING_NAME_LEN (512)
34 | /*Must be a multiple of disk block size. 512 * 4096 = 2MB */
35 | #define BRING_SLOT_SIZE (512 * DISK_BLOCK)
36 | #define BRING_SLOT_COUNT (128)
37 |
38 | /*Maximum number of input and output threads/cores*/
39 | #define MAX_OTHREADS (64)
40 | #define MAX_ITHREADS (64)
41 |
42 | typedef struct
43 | {
44 | int64_t swofl;
45 | int64_t hwofl;
46 | int64_t dropped;
47 | int64_t errors;
48 | int64_t spins1_rx;
49 | int64_t spinsP_rx;
50 | int64_t bytes_rx;
51 | int64_t packets_rx;
52 |
53 | } lstats_t __attribute__( ( aligned ( 8 ) ) );
54 |
55 |
56 |
57 | typedef struct
58 | {
59 | int64_t pcbytes; /* capture packet bytes */
60 | int64_t plbytes; /* wire length packet bytes */
61 | int64_t dbytes; /* to disk bytes */
62 | int64_t packets;
63 | int64_t spins;
64 |
65 | } wstats_t __attribute__( ( aligned ( 8 ) ) );
66 |
67 |
68 |
69 | #endif /* SRC_EXACT_CAPTURE_H_ */
70 |
--------------------------------------------------------------------------------
/src/exactio/exactio.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017,2018 All rights reserved.
3 | * See LICENSE.txt for full details.
4 | *
5 | * Created: 21 Jun 2017
6 | * Author: Matthew P. Grosvenor
7 | * Description:
8 | * A "factory" function for creating and destroying exactio streams.
9 | */
10 |
11 |
12 |
13 | #include "exactio.h"
14 | #include "exactio_file.h"
15 | #include "exactio_dummy.h"
16 | #include "exactio_exanic.h"
17 | #include "exactio_bring.h"
18 |
19 | int eio_new(eio_args_t* args, eio_stream_t** result)
20 | {
21 |
22 | switch(args->type){
23 | case EIO_FILE: return NEW_IOSTREAM(file,result,&args->args.file);
24 | case EIO_DUMMY: return NEW_IOSTREAM(dummy,result,&args->args.dummy);
25 | case EIO_EXA: return NEW_IOSTREAM(exa,result,&args->args.exa);
26 | case EIO_BRING:return NEW_IOSTREAM(bring,result,&args->args.bring);
27 | }
28 |
29 | return -1;
30 | }
31 |
32 | void eio_des(eio_stream_t* this)
33 | {
34 | this->vtable.destroy(this);
35 | }
36 |
37 |
38 |
--------------------------------------------------------------------------------
/src/exactio/exactio.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017,2018 All rights reserved.
3 | * See LICENSE.txt for full details.
4 | *
5 | * Created: 19 Jun 2017
6 | * Author: Matthew P. Grosvenor
7 | * Description:
8 | * An abstract IO interface to make it possible to perf test Exact Capture.
9 | * These generic functions make it easier to call exactio functions without
10 | * having to put "this" pointers everywhere.
11 | */
12 |
13 |
14 | #ifndef EXACTIO_IO_H_
15 | #define EXACTIO_IO_H_
16 |
17 | #include "exactio_bring.h"
18 | #include "exactio_file.h"
19 | #include "exactio_stream.h"
20 | #include "exactio_dummy.h"
21 | #include "exactio_exanic.h"
22 |
23 | #include "../data_structs/timespecps.h"
24 |
25 | typedef enum {
26 | EIO_DUMMY,
27 | EIO_FILE,
28 | EIO_EXA,
29 | EIO_BRING,
30 | } exactio_stream_type_t;
31 |
32 |
33 | typedef struct {
34 | exactio_stream_type_t type;
35 | union {
36 | exa_args_t exa;
37 | dummy_args_t dummy;
38 | file_args_t file;
39 | bring_args_t bring;
40 | } args;
41 | } eio_args_t;
42 |
43 |
44 | int eio_new(eio_args_t* args, eio_stream_t** result);
45 | void eio_des(eio_stream_t* this);
46 |
47 | /* Keep these implementations in the header file so that they can (ideally) be
48 | * compiled inline */
49 |
50 | //Read operations
51 | static inline eio_error_t eio_rd_acq(eio_stream_t* this, char** buffer, int64_t* len, int64_t* ts )
52 | {
53 | return this->vtable.read_acquire(this, buffer, len, ts);
54 | }
55 |
56 | static inline eio_error_t eio_rd_rel(eio_stream_t* this, int64_t* ts)
57 | {
58 | return this->vtable.read_release(this, ts);
59 | }
60 |
61 | //Write operations
62 | static inline eio_error_t eio_wr_acq(eio_stream_t* this, char** buffer, int64_t* len, int64_t* ts)
63 | {
64 | return this->vtable.write_acquire(this, buffer, len, ts);
65 | }
66 |
67 |
68 | static inline eio_error_t eio_wr_rel(eio_stream_t* this, int64_t len, int64_t* ts)
69 | {
70 | return this->vtable.write_release(this,len, ts);
71 | }
72 |
73 |
74 | #endif /* EXACTIO_IO_H_ */
75 |
--------------------------------------------------------------------------------
/src/exactio/exactio_bring.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017, 2018 All rights reserved.
3 | * See LICENSE.txt for full details.
4 | *
5 | * Created: 19 Jun 2017
6 | * Author: Matthew P. Grosvenor
7 | * Description:
8 | * Definition of a memory mapped "blocking ring" or circular queue to join
9 | * listener and writer threads using the exactio abstract IO interface.
10 | */
11 |
12 | #ifndef EXACTIO_BRING_H_
13 | #define EXACTIO_BRING_H_
14 |
15 | #include "exactio_stream.h"
16 |
17 | typedef struct {
18 | char* filename;
19 | uint64_t isserver;
20 |
21 | //These params only required if server
22 | uint64_t slot_size;
23 | uint64_t slot_count;
24 | uint64_t dontexpand;
25 | } bring_args_t;
26 |
27 | NEW_IOSTREAM_DECLARE(bring,bring_args_t);
28 |
29 | #endif /* EXACTIO_BRING_H_ */
30 |
--------------------------------------------------------------------------------
/src/exactio/exactio_dummy.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017, 2018 All rights reserved.
3 | * See LICENSE.txt for full details.
4 | *
5 | * Created: 19 Jun 2017
6 | * Author: Matthew P. Grosvenor
7 | * Description:
8 | * Definition of a dummy stream using the exactio abstract IO interface. The
9 | * dummy simply returns a static memory region rather than performing I/O
10 | * operations.
11 | */
12 |
13 |
14 |
15 | #ifndef EXACTIO_DUMMY_H_
16 | #define EXACTIO_DUMMY_H_
17 |
18 | #include "exactio_stream.h"
19 |
20 |
21 | typedef enum
22 | {
23 | DUMMY_MODE_NONE, /* Reads as if there is one big empty buffer */
24 | DUMMY_MODE_EXPCAP, /* The buffer full of minimum sized expcap records */
25 | DUMMY_MODE_EXANIC, /* The buffer is full of minimum sized ExaNIC chunks */
26 | } dummy_read_mode;
27 |
28 | typedef struct {
29 | uint64_t read_buff_size;
30 | uint64_t write_buff_size;
31 | dummy_read_mode rd_mode;
32 | uint64_t expcap_bytes;
33 | uint64_t exanic_pkt_bytes;
34 | } dummy_args_t;
35 |
36 |
37 | NEW_IOSTREAM_DECLARE(dummy, dummy_args_t);
38 |
39 | #endif /* EXACTIO_DUMMY_H_ */
40 |
--------------------------------------------------------------------------------
/src/exactio/exactio_exanic.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017, 2018 All rights reserved.
3 | * See LICENSE.txt for full details.
4 | *
5 | * Created: 19 Jun 2017
6 | * Author: Matthew P. Grosvenor
7 | * Description:
8 | * Definition of an ExaNIC reader/writer stream using the exactio abstract
9 | * I/O interface. Some of the speed critical function a pulled into the header
10 | * file to (hopefully) aid compilation optimizations.
11 | */
12 |
13 |
14 | #ifndef EXACTIO_EXA_H_
15 | #define EXACTIO_EXA_H_
16 |
17 | #include "exactio_stream.h"
18 |
19 | #include
20 | #include
21 | #include
22 | #include
23 | #include
24 |
25 | #include "exactio_timing.h"
26 |
27 |
28 | typedef struct {
29 | char* interface_rx;
30 | char* interface_tx;
31 | bool promisc;
32 | bool kernel_bypass;
33 | } exa_args_t;
34 |
35 | NEW_IOSTREAM_DECLARE(exa,exa_args_t);
36 |
37 | /******************************************************************************/
38 | /* Bring the below code up in to the header to make it easier for the compiler
39 | * to inline the functions properly.
40 | */
41 |
42 |
43 | typedef struct exa_priv {
44 | int rx_port;
45 | int rx_dev_id;
46 | int tx_port;
47 | int tx_dev_id;
48 | char rx_dev[16];
49 | char tx_dev[16];
50 |
51 | exanic_t* tx_nic;
52 | exanic_t* rx_nic;
53 | exanic_tx_t *tx;
54 | exanic_rx_t *rx;
55 |
56 | char* rx_buffer;
57 | int64_t rx_len;
58 | uint32_t chunk_id;
59 | int more_rx_chunks;
60 |
61 | size_t max_tx_mtu;
62 | char* tx_buffer;
63 | int64_t tx_buffer_len;
64 |
65 |
66 | bool closed;
67 | } exa_priv_t;
68 |
69 |
70 | //eio_error_t exa_read_acquire(eio_stream_t* this, char** buffer, int64_t* len, int64_t* ts );
71 | //eio_error_t exa_read_release(eio_stream_t* this, int64_t* ts);
72 |
73 | //Read operations
74 | static inline eio_error_t exa_read_acquire(eio_stream_t* this, char** buffer, int64_t* len, int64_t* ts )
75 | {
76 | exa_priv_t* priv = IOSTREAM_GET_PRIVATE(this);
77 | ifassert(priv->closed){
78 | return EIO_ECLOSED;
79 | }
80 |
81 | ifassert((ssize_t)priv->rx_buffer){
82 | return EIO_ERELEASE;
83 | }
84 |
85 | struct rx_chunk_info info = {.frame_status =0};
86 | priv->rx_len = exanic_receive_chunk_inplace_ex(
87 | priv->rx,&priv->rx_buffer,&priv->chunk_id,&priv->more_rx_chunks,
88 | &info);
89 |
90 | ssize_t frame_error = -(info.frame_status & EXANIC_RX_FRAME_ERROR_MASK);
91 | ifunlikely(priv->rx_len < 0){
92 | frame_error = -EXANIC_RX_FRAME_SWOVFL;
93 | }
94 |
95 | ifunlikely(frame_error){
96 | switch(frame_error){
97 | //These are unrecoverable errors, so exit now.
98 | //Translate between ExaNIC error codes and EIO codes
99 | case -EXANIC_RX_FRAME_SWOVFL: return EIO_ESWOVFL;
100 | case -EXANIC_RX_FRAME_HWOVFL: return EIO_EHWOVFL;
101 | }
102 | }
103 |
104 | //This is a very likely path, but we want to optimise the data path
105 | ifunlikely(priv->rx_len == 0){
106 | return EIO_ETRYAGAIN;
107 | }
108 |
109 | //The user doesn't want this chunk, and therefore the whole frame, skip it
110 | ifunlikely(buffer == NULL || len == NULL){
111 | iflikely(priv->more_rx_chunks){
112 | int err = exanic_receive_abort(priv->rx);
113 | ifunlikely( err == -EXANIC_RX_FRAME_SWOVFL){
114 | return EIO_ESWOVFL;
115 | }
116 | }
117 | return EIO_ENONE;
118 | }
119 |
120 |
121 | iflikely((ssize_t)ts){
122 | const exanic_cycles32_t ts32 = exanic_receive_chunk_timestamp(priv->rx, priv->chunk_id);
123 | const exanic_cycles_t ts64 = exanic_expand_timestamp(priv->rx_nic,ts32);
124 | // struct exanic_timespecps tsps;
125 | // exanic_cycles_to_timespecps(priv->rx_nic, ts64, &tsps);
126 | //These two timespecps structures look the same but come from different
127 | //names-spaces. Making the copy explicit here just to be safe
128 | //ts->tv_sec = tsps.tv_sec;
129 | *ts = ts64; //tsps.tv_psec;
130 | }
131 |
132 | //All good! Successful "read"!
133 | *buffer = priv->rx_buffer;
134 | *len = priv->rx_len;
135 |
136 | switch(frame_error){
137 | case -EXANIC_RX_FRAME_CORRUPT: return EIO_EFRAG_CPT;
138 | case -EXANIC_RX_FRAME_ABORTED: return EIO_EFRAG_ABT;
139 | default:
140 | iflikely(priv->more_rx_chunks) return EIO_EFRAG_MOR;
141 | return EIO_ENONE;
142 | }
143 | }
144 |
145 | //Convert an exanic timestamp into cycles
146 | static inline eio_error_t exa_rxcycles_to_timespec(eio_stream_t* this, exanic_cycles_t cycles, struct timespec* ts )
147 | {
148 | exa_priv_t* priv = IOSTREAM_GET_PRIVATE(this);
149 |
150 | iflikely(ts){
151 | exanic_cycles_to_timespec(priv->rx_nic, cycles, ts);
152 | }
153 |
154 | return EIO_ENONE;
155 | }
156 |
157 | static inline eio_error_t exa_rxcycles_to_timespecps(eio_stream_t* this, exanic_cycles_t cycles, struct exanic_timespecps* ts )
158 | {
159 | exa_priv_t* priv = IOSTREAM_GET_PRIVATE(this);
160 |
161 | iflikely(ts){
162 | exanic_cycles_to_timespecps(priv->rx_nic, cycles, ts);
163 | }
164 |
165 | return EIO_ENONE;
166 | }
167 |
168 |
169 |
170 |
171 | static inline eio_error_t exa_read_release(eio_stream_t* this, int64_t* ts)
172 | {
173 | eio_error_t result = EIO_ENONE;
174 | exa_priv_t* priv = IOSTREAM_GET_PRIVATE(this);
175 |
176 |
177 | ifassert(!priv->rx_buffer){
178 | return EIO_ERELEASE;
179 | }
180 |
181 | ifunlikely(exanic_receive_chunk_recheck(priv->rx, priv->chunk_id) == 0){
182 | result = EIO_ESWOVFL;
183 | }
184 |
185 | priv->rx_buffer = NULL;
186 | (void)ts;
187 | //eio_nowns(ts);
188 |
189 | //Nothing to do here;
190 | return result;
191 | }
192 |
193 |
194 | #endif /* EXACTIO_EXA_H_ */
195 |
--------------------------------------------------------------------------------
/src/exactio/exactio_file.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017, 2018 All rights reserved.
3 | * See LICENSE.txt for full details.
4 | *
5 | * Created: 19 Jun 2017
6 | * Author: Matthew P. Grosvenor
7 | * Description:
8 | * Definition of the file read/write interface using the exactio abstract I/O
9 | * interface.
10 | */
11 |
12 | #ifndef EXACTIO_FILE_H_
13 | #define EXACTIO_FILE_H_
14 |
15 | #include "exactio_stream.h"
16 |
17 | typedef struct {
18 | char* filename;
19 | uint64_t read_buff_size;
20 | uint64_t write_buff_size;
21 | uint64_t on_mod;
22 | } file_args_t;
23 |
24 | NEW_IOSTREAM_DECLARE(file, file_args_t);
25 |
26 | #endif /* EXACTIO_FILE_H_ */
27 |
--------------------------------------------------------------------------------
/src/exactio/exactio_stream.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017, 2018 All rights reserved.
3 | * See LICENSE.txt for full details.
4 | *
5 | * Created: 17 Jul 2017
6 | * Author: Matthew P. Grosvenor
7 | * Description:
8 | * Definition of the exactio abstract straeming I/O interface. This is loosely
9 | * based on code from CAMIO (https://github.com/mgrosvenor/camio2). It provides
10 | * a fast way to interface to a number of underlying transports using a common
11 | * API. A C++ style interface is implemented directly in C, similar to Linux
12 | * kernel abstract interfaces.
13 | */
14 |
15 |
16 | #ifndef SRC_EXACTIO_EXACTIO_STREAM_H_
17 | #define SRC_EXACTIO_EXACTIO_STREAM_H_
18 |
19 | #include
20 | #include
21 | #include
22 | #include
23 |
24 | #include
25 | #include "../data_structs/timespecps.h"
26 |
27 | //This compile out checks that aren't strictly necessary
28 | #ifdef NOIFASSERT
29 | #define ifassert(x) if(0 && (x))
30 | #else
31 | #define ifassert(x) ifunlikely((ssize_t)(x))
32 | #endif
33 |
34 |
35 |
36 | typedef struct exactio_stream_s eio_stream_t;
37 |
38 | typedef enum {
39 | EIO_ENONE = 0,
40 | EIO_EUNSPEC, //Unspecified error
41 | EIO_ETRYAGAIN, //No data available, try again
42 | EIO_ECLOSED, //The underlying data source has closed
43 | EIO_EEOF, //End of file has been reached
44 | EIO_ENOTIMPL, //This function is not implemented
45 | EIO_ETOOBIG, //Returned buffer len is too long
46 | EIO_ERELEASE, //Release the buffer first before trying acquire again
47 | EIO_EACQUIRE, //Acquire the buffer first before trying release again
48 | EIO_ENOMEM, //No memory to back this
49 |
50 | //These error codes only apply to fragment based transports.
51 | EIO_EFRAG_MOR, //More fragments to come
52 | EIO_EFRAG_EOF, //End of fragment sequence
53 | EIO_EFRAG_ABT, //Fragment aborted by sender
54 | EIO_EFRAG_CPT, //Fragment corrupt (e.g. csum failure)
55 |
56 | EIO_EHWOVFL, //Hardware overflow (e.g. insufficient PCIe bandwidth)
57 | EIO_ESWOVFL, //Software overflow (e.g. software not keeping up)
58 |
59 | EIO_EINVALID, //Something was done wrong
60 |
61 | } eio_error_t;
62 |
63 | /**
64 | * Nice simple generic read/write I/O abstraction
65 | */
66 | typedef struct exactio_stream_interface_s{
67 |
68 | void (*destroy)(eio_stream_t* this);
69 |
70 | //Read operations
71 | //----------------
72 | eio_error_t (*read_acquire)(eio_stream_t* this, char** buffer, int64_t* len, int64_t* ts );
73 | eio_error_t (*read_release)(eio_stream_t* this,int64_t* ts);
74 |
75 | //Write operations
76 | //----------------
77 | //for write_acquire len can be supplied as a hint. If len is 0, the MTU will be used
78 | //for write_release len is zero, the frame the data is not committed
79 | eio_error_t (*write_acquire)(eio_stream_t* this, char** buffer, int64_t* len, int64_t* ts );
80 | eio_error_t (*write_release)(eio_stream_t* this, int64_t len, int64_t* ts );
81 |
82 |
83 | } exactio_stream_interface_t;
84 |
85 | /**
86 | * All streams must implement this. Streams will use the macros provided to overload
87 | * this structure with and include a private data structure.
88 | */
89 | struct exactio_stream_s {
90 |
91 | /**
92 | * vtable that holds the function pointers, usually this would be a pointer to a constant, but saving 6x8bytes seems a
93 | * little silly when it will cost a pointer dereference on the critical
94 | * path.
95 | */
96 | exactio_stream_interface_t vtable;
97 |
98 | int fd;
99 |
100 | };
101 |
102 |
103 | #define IOSTREAM_GET_PRIVATE(THIS) ( (void*)(THIS + 1))
104 |
105 | #define NEW_IOSTREAM(name, out, args)\
106 | new_##name##_stream(out, args)
107 |
108 | #define NEW_IOSTREAM_DECLARE(NAME, ARGT)\
109 | int new_##NAME##_stream(eio_stream_t** out, ARGT* args)
110 |
111 | #define NEW_IOSTREAM_DEFINE(NAME, ARGT, PRIVATE_TYPE) \
112 | static const exactio_stream_interface_t NAME##_stream_interface = {\
113 | .read_acquire = NAME##_read_acquire,\
114 | .read_release = NAME##_read_release,\
115 | .write_acquire = NAME##_write_acquire,\
116 | .write_release = NAME##_write_release,\
117 | .destroy = NAME##_destroy,\
118 | };\
119 | \
120 | NEW_IOSTREAM_DECLARE(NAME, ARGT)\
121 | {\
122 | eio_stream_t* result = (eio_stream_t*)calloc(1,sizeof(eio_stream_t) + sizeof(PRIVATE_TYPE));\
123 | if(!result) return EIO_ENOMEM;\
124 | result->vtable = NAME##_stream_interface;\
125 | result->fd = -1;\
126 | *out = result;\
127 | int err = NAME##_construct(result, args);\
128 | if(err){ free(result); *out = NULL;}\
129 | return err;\
130 | }
131 |
132 |
133 | #endif /* SRC_EXACTIO_EXACTIO_STREAM_H_ */
134 |
--------------------------------------------------------------------------------
/src/exactio/exactio_timing.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017, 2018 All rights reserved.
3 | * See LICENSE.txt for full details.
4 | *
5 | * Created: 17 Jul 2017
6 | * Author: Matthew P. Grosvenor
7 | * Description:
8 | * Implementation of utilities for operating with time (quickly)
9 | */
10 |
11 |
12 |
13 |
14 | #include
15 | #include
16 |
17 | #include "exactio_timing.h"
18 | #include "exactio.h"
19 |
20 |
21 | //static inline uint64_t rdtscp( uint32_t *aux )
22 | //{
23 | // uint64_t rax,rdx;
24 | // __asm__ __volatile__( "rdtscp\n" : "=a" (rax), "=d" (rdx), "=c" (aux) : : );
25 | // return (rdx << 32) + rax;
26 | //}
27 |
28 | void eio_nowns(int64_t* ts)
29 | {
30 |
31 |
32 | iflikely(!ts){
33 | return;
34 | }
35 |
36 | struct timespec now;
37 | clock_gettime(CLOCK_REALTIME, &now );
38 | *ts = now.tv_sec * 1000 * 1000 * 1000 + now.tv_nsec;
39 |
40 | // uint32_t aux;
41 | // ts->tv_sec = 0;
42 | // ts->tv_psec = rdtscp(&aux); // * 1000 / 3.5;
43 | }
44 |
45 |
46 | double eio_tspstonsf(timespecps_t* ts)
47 | {
48 | if(!ts){
49 | return NAN;
50 | }
51 |
52 |
53 | const double secs = ts->tv_sec;
54 | const double psec = ts->tv_psec;
55 |
56 | return secs * 1000.0 * 1000.0 * 1000.0 + psec / 1000.0;
57 | }
58 |
59 | int64_t eio_tspstonsll(timespecps_t* ts)
60 | {
61 |
62 | if(!ts){
63 | return ~0;
64 | }
65 |
66 | const int64_t secs = ts->tv_sec;
67 | const int64_t psec = ts->tv_psec;
68 | //return (double)psec/3.5;
69 |
70 | return secs * 1000 * 1000 * 1000 + psec / 1000;
71 | }
72 |
73 |
--------------------------------------------------------------------------------
/src/exactio/exactio_timing.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017, 2018 All rights reserved.
3 | * See LICENSE.txt for full details.
4 | *
5 | * Created: 17 Jul 2017
6 | * Author: Matthew P. Grosvenor
7 | * Description:
8 | * Definition of utilities for operating with time (quickly)
9 | */
10 |
11 | #ifndef SRC_EXACTIO_EXACTIO_TIMING_H_
12 | #define SRC_EXACTIO_EXACTIO_TIMING_H_
13 |
14 | #include "../data_structs/timespecps.h"
15 |
16 |
17 | //Some handy time related utils
18 | //Get the current time in timespecps format
19 | void eio_nowns(int64_t* ts);
20 |
21 | //Convert a timespec ps to int64 nanoseconds
22 | //int64_t eio_tspstonsll(timespecps_t* ts);
23 |
24 | //Convert a timespec ps to double double
25 | //double eio_tspstonsf(timespecps_t* ts);
26 |
27 | #endif /* SRC_EXACTIO_EXACTIO_TIMING_H_ */
28 |
--------------------------------------------------------------------------------
/src/utils.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2018 All rights reserved.
3 | * See LICENSE.txt for full details.
4 | *
5 | * Created: 6 Apr. 2018
6 | * Author: Matthew P. Grosvenor
7 | * Description: Application wide useful utility functions
8 | */
9 |
10 |
11 |
12 | #include
13 | #include
14 | #include
15 | #include
16 |
17 | #include
18 | #include
19 |
20 | #include "data_structs/expcap.h"
21 |
22 | #include "utils.h"
23 |
24 |
25 |
26 |
27 | int64_t time_now_ns()
28 | {
29 | struct timespec now = {0};
30 | clock_gettime(CLOCK_REALTIME, &now);
31 | return now.tv_sec * 1000ULL * 1000 * 1000 + now.tv_nsec;
32 | }
33 |
34 |
35 | void init_dummy_data(char* dummy_data, int len)
36 | {
37 | const char* dummy_text = "EXABLAZEEXACTCAPPADDING PACKET ";
38 | const int64_t dummy_text_len = strlen (dummy_text);
39 | memset (dummy_data, 0xFF, 16);
40 | for (int i = 16; i < len; i++)
41 | {
42 | dummy_data[i] = dummy_text[(i - 16) % dummy_text_len];
43 | }
44 |
45 | }
46 |
47 |
48 | void print_flags(uint8_t flags)
49 | {
50 | if(flags & EXPCAP_FLAG_ABRT) printf("ABRT ");
51 | if(flags & EXPCAP_FLAG_CRPT) printf("CRPT ");
52 | if(flags & EXPCAP_FLAG_HASCRC) printf("HCRC ");
53 | if(flags & EXPCAP_FLAG_HWOVFL) printf("HWOVF ");
54 | if(flags & EXPCAP_FLAG_SWOVFL) printf("SWOVF ");
55 | if(flags & EXPCAP_FLAG_TRNC) printf("TRNC ");
56 | }
57 |
58 |
59 | int parse_device_id(const char *str, int* dev_number)
60 | {
61 | char* p;
62 |
63 | p = strchr(str, ':');
64 | if (p == NULL){
65 | return -1;
66 | }
67 |
68 | if ((p - str) >= 16){
69 | return -1;
70 | }
71 |
72 | *dev_number = strtol(p - 1, NULL, 10);
73 |
74 | return 0;
75 | }
76 |
77 |
78 |
79 | //Parses a string of the format ":"
80 | int parse_device_port(const char *str, char *device, int *port_number)
81 | {
82 | char *p, *q;
83 |
84 | p = strchr(str, ':');
85 | if (p == NULL){
86 | return -1;
87 | }
88 |
89 | if ((p - str) >= 16){
90 | return -1;
91 | }
92 |
93 | strncpy(device, str, p - str);
94 | device[p - str] = '\0';
95 | *port_number = strtol(p + 1, &q, 10);
96 | if (*(p + 1) == '\0' || *q != '\0'){
97 | // strtol failed
98 | return -1;
99 | }
100 |
101 | return 0;
102 | }
103 |
104 |
105 | int parse_device (const char* interface,
106 | char device[16], int* dev_number, int *port_number)
107 | {
108 | if(!exanic_find_port_by_interface_name (interface, device, 16, port_number))
109 | {
110 | parse_device_id(device, dev_number);
111 | return 0;
112 | }
113 |
114 | if(!parse_device_port (interface, device, port_number))
115 | {
116 | parse_device_id(device, dev_number);
117 | return 0;
118 |
119 | }
120 |
121 | return 1;
122 |
123 |
124 | }
125 |
126 |
127 |
128 | /* This is a dumb way to do this, but who cares? */
129 | static int get_digitsll (int64_t num)
130 | {
131 | int i = 1;
132 | for (; num > 0; i++)
133 | {
134 | num = num / 10;
135 | }
136 |
137 | return i;
138 | }
139 |
140 | int max_digitsll (int64_t a, int64_t b, int64_t c, int64_t d, int64_t e,
141 | int64_t f, int64_t g, int64_t h, int64_t i, int64_t j)
142 | {
143 | int result = 0;
144 | result = MAX (result, get_digitsll (a));
145 | result = MAX (result, get_digitsll (b));
146 | result = MAX (result, get_digitsll (c));
147 | result = MAX (result, get_digitsll (d));
148 | result = MAX (result, get_digitsll (e));
149 | result = MAX (result, get_digitsll (f));
150 | result = MAX (result, get_digitsll (g));
151 | result = MAX (result, get_digitsll (h));
152 | result = MAX (result, get_digitsll (i));
153 | result = MAX (result, get_digitsll (j));
154 |
155 | return result;
156 | }
157 |
158 | /* This is a dumb way to do this, but who cares? */
159 |
160 | static int get_digitsf (double num)
161 | {
162 | int i = 1;
163 | for (; num > 1; i++)
164 | {
165 | num = num / 10;
166 | }
167 |
168 | return i;
169 | }
170 |
171 | int max_digitsf (double a, double b, double c, double d, double e, double f,
172 | double g, double h, double i, double j)
173 | {
174 | int result = 0;
175 | result = MAX (result, get_digitsf (a));
176 | result = MAX (result, get_digitsf (b));
177 | result = MAX (result, get_digitsf (c));
178 | result = MAX (result, get_digitsf (d));
179 | result = MAX (result, get_digitsf (e));
180 | result = MAX (result, get_digitsf (f));
181 | result = MAX (result, get_digitsf (g));
182 | result = MAX (result, get_digitsf (h));
183 | result = MAX (result, get_digitsf (i));
184 | result = MAX (result, get_digitsf (j));
185 | return result;
186 | }
187 |
188 |
--------------------------------------------------------------------------------
/src/utils.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2018 All rights reserved.
3 | * See LICENSE.txt for full details.
4 | *
5 | * Created: 6 Apr. 2018
6 | * Author: Matthew P. Grosvenor
7 | * Description: Application wide useful utility functions and macros
8 | */
9 |
10 |
11 | #ifndef SRC_UTILS_H_
12 | #define SRC_UTILS_H_
13 |
14 | #include
15 | #include
16 |
17 | #if __BYTE_ORDER == __LITTLE_ENDIAN
18 | # define htonll(x) __bswap_64(x)
19 | # define ntohll(x) __bswap_64(x)
20 | #elif __BYTE_ORDER == __BIG_ENDIAN
21 | # define htonll(x) (x)
22 | # define ntohll(x) (x)
23 | #else
24 | # error Unknown byte order
25 | #endif
26 |
27 |
28 | #define PKT(hdr) ((char*)(hdr+1))
29 | #define PKT_OFF(hdr, off) (PKT(hdr) + off)
30 |
31 | int64_t time_now_ns();
32 |
33 | void init_dummy_data(char* dummy_data, int len);
34 |
35 | void print_flags(uint8_t flags);
36 |
37 | int parse_device (const char* interface,
38 | char device[16], int* dev_number, int *port_number);
39 |
40 |
41 | int max_digitsf (double a, double b, double c, double d, double e, double f,
42 | double g, double h, double i, double j);
43 | int max_digitsll (int64_t a, int64_t b, int64_t c, int64_t d, int64_t e,
44 | int64_t f, int64_t g, int64_t h, int64_t i, int64_t j);
45 |
46 | #endif /* SRC_UTILS_H_ */
47 |
--------------------------------------------------------------------------------
/tools/checksum.h:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include "data_structs/pseudo_ip_header.h"
4 |
5 | const uint32_t crc32_tab[] = {
6 | 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
7 | 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
8 | 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
9 | 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
10 | 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
11 | 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
12 | 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
13 | 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
14 | 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
15 | 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
16 | 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
17 | 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
18 | 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
19 | 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
20 | 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
21 | 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
22 | 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
23 | 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
24 | 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
25 | 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
26 | 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
27 | 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
28 | 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
29 | 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
30 | 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
31 | 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
32 | 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
33 | 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
34 | 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
35 | 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
36 | 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
37 | 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
38 | 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
39 | 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
40 | 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
41 | 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
42 | 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
43 | 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
44 | 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
45 | 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
46 | 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
47 | 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
48 | 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
49 | };
50 |
51 | uint32_t crc32(const void* buf, size_t size)
52 | {
53 | const uint8_t* p = buf;
54 | uint32_t crc;
55 |
56 | crc = ~0U;
57 | while (size--)
58 | crc = crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8);
59 | return crc ^ ~0U;
60 | }
61 |
62 | uint16_t csum(uint8_t* buf, size_t len, uint16_t initial)
63 | {
64 | uint32_t sum = (uint32_t)(initial);
65 | const uint16_t *u16 = (const uint16_t*)buf;
66 |
67 | while (len >= (sizeof(*u16) * 4)) {
68 | sum += u16[0];
69 | sum += u16[1];
70 | sum += u16[2];
71 | sum += u16[3];
72 | len -= sizeof(*u16) * 4;
73 | u16 += 4;
74 | }
75 | while (len >= sizeof(*u16)) {
76 | sum += *u16;
77 | len -= sizeof(*u16);
78 | u16 += 1;
79 | }
80 |
81 | /* if length is in odd bytes */
82 | if (len == 1)
83 | sum += *((const uint8_t*)u16);
84 |
85 | while(sum>>16)
86 | sum = (sum & 0xFFFF) + (sum>>16);
87 | return (uint16_t)~sum;
88 | }
89 |
90 | /* Format a pseudo IP header, used for UDP/TCP checksum calculation */
91 | static inline void get_pseudo_iphdr(struct iphdr* ip_hdr, uint16_t hdr_len, struct pseudo_iphdr* hdro)
92 | {
93 | hdro->saddr = ip_hdr->saddr;
94 | hdro->daddr = ip_hdr->daddr;
95 | hdro->zero = 0;
96 | hdro->protocol = ip_hdr->protocol;
97 | hdro->len = hdr_len;
98 | }
99 |
100 | uint16_t calc_l4_csum(uint8_t* buf, struct iphdr* ip_hdr, uint16_t len)
101 | {
102 | struct pseudo_iphdr p_hdr;
103 | uint16_t len_be = htobe16(len);
104 | get_pseudo_iphdr(ip_hdr, len_be, &p_hdr);
105 | uint16_t pseudo_csum = csum((uint8_t*)&p_hdr, sizeof(struct pseudo_iphdr), 0);
106 | return csum(buf, len, ~pseudo_csum);
107 | }
108 |
--------------------------------------------------------------------------------
/tools/data_structs/buff.h:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #include
4 | #include
5 | #include "data_structs/pcap-structures.h"
6 |
7 | #define BUFF_SIZE (128 * 1024 * 1024) /* 128MB */
8 | #define MAX_FILENAME 2048
9 |
10 | #define BUFF_TRY(x) \
11 | do { \
12 | buff_error_t err = (x); \
13 | if (err != BUFF_ENONE) { \
14 | ch_log_warn("%s failed at %s:%d\n", #x, __FILE__, __LINE__); \
15 | ch_log_fatal("Reason: %s\n", buff_strerror(err)); \
16 | } \
17 | } while(0) \
18 |
19 | typedef struct {
20 | char* filename;
21 | char* file_header;
22 | size_t header_size;
23 | char* data;
24 | int eof;
25 | int fd;
26 | bool conserve_fds;
27 | uint64_t filesize;
28 | int64_t max_filesize;
29 | uint64_t offset;
30 | uint64_t pkt_idx;
31 | int file_seg;
32 | int file_dup;
33 | uint64_t file_bytes_written;
34 | bool read_only;
35 | bool allow_duplicates;
36 | } buff_t;
37 |
38 | typedef enum {
39 | BUFF_ENONE = 0,
40 | BUFF_EALLOC, // Failed to allocate memory for a buff_t
41 | BUFF_EOPEN, // Failed to open a file for read/write
42 | BUFF_EWRITE, // Failed to write out buff_t data
43 | BUFF_EMMAP, // Failed to map a buff_t from a file
44 | BUFF_ESTAT, // Failed to stat a file
45 | BUFF_ECOPY, // Failed to copy bytes to a buff_t
46 | BUFF_EOVERFLOW, // Buffer offset is greater than the allocated buffer size.
47 | BUFF_EREADONLY, // Attempting to write to a read-only buffer.
48 | BUFF_EBADHEADER, // Failed to open file as buff_t, due to a badly formed file header.
49 | BUFF_ECLOSE // Failed to close buff_t.
50 | } buff_error_t;
51 |
52 | /* Allocate and initialize a buff_t. */
53 | buff_error_t buff_init(char* filename, int64_t max_filesize, bool conserve_fds, bool allow_duplicates, buff_t** buffo);
54 |
55 | /* Read a file into a buff_t */
56 | buff_error_t buff_init_from_file(buff_t** buff, char* filename, size_t header_size);
57 |
58 | /* Create a new pcap file header within a buff_t */
59 | buff_error_t buff_new_file(buff_t* buff);
60 |
61 | /* Copy bytes to buff, flushing to disk if required */
62 | buff_error_t buff_copy_bytes(buff_t* buff, void* bytes, uint64_t len);
63 |
64 | /* Write out the contents of a buff_t to disk */
65 | buff_error_t buff_flush_to_disk(buff_t* wr_buff);
66 |
67 | /* Get the amount of bytes left available in the buffer */
68 | buff_error_t buff_remaining(buff_t* buff, int64_t* remaining);
69 |
70 | /* Get the amount of bytes left in the current segment */
71 | int64_t buff_seg_remaining(buff_t* buff);
72 |
73 | /* Get full buff filename */
74 | void buff_get_full_filename(buff_t* buff, char* full_filename, size_t len);
75 |
76 | /* Write file header */
77 | buff_error_t buff_write_file_header(buff_t *buff);
78 |
79 | /* Close and resources associated with this buff_t */
80 | buff_error_t buff_close(buff_t* buff);
81 |
82 | /* Translate an error value to a string */
83 | const char* buff_strerror(buff_error_t err);
84 |
--------------------------------------------------------------------------------
/tools/data_structs/fusion_hpt.h:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #define be40toh(x) (be64toh(x) >> 24)
4 |
5 | typedef struct fusion_hpt_trailer {
6 | uint8_t device_id;
7 | uint8_t port;
8 | uint64_t seconds_since_epoch : 32;
9 | uint64_t frac_seconds : 40;
10 | uint8_t __reserved;
11 | uint32_t new_fcs;
12 | } __attribute__((packed)) fusion_hpt_trailer_t;
13 |
--------------------------------------------------------------------------------
/tools/data_structs/pcap_buff.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 |
7 | #include
8 | #include
9 | #include "pcap_buff.h"
10 |
11 | buff_error_t pcap_buff_init(char* filename, int64_t snaplen, int64_t max_filesize, bool usec,
12 | bool conserve_fds, bool allow_duplicates, pcap_buff_t* pcap_buffo)
13 | {
14 | buff_t* buff = NULL;
15 | BUFF_TRY(buff_init(filename, max_filesize, conserve_fds, allow_duplicates, &buff));
16 |
17 | pcap_buffo->_buff = buff;
18 | pcap_buffo->snaplen = snaplen;
19 | pcap_buffo->usec = usec;
20 |
21 | /* Generate the output file header */
22 | pcap_file_header_t* hdr = (pcap_file_header_t*)malloc(sizeof(pcap_file_header_t));
23 | if(!hdr){
24 | ch_log_fatal("Failed to allocate memory for file header!\n");
25 | }
26 |
27 | buff->file_header = (char*)hdr;
28 | buff->header_size = sizeof(pcap_file_header_t);
29 |
30 | hdr->magic = usec ? TCPDUMP_MAGIC: NSEC_TCPDUMP_MAGIC;
31 | hdr->version_major = PCAP_VERSION_MAJOR;
32 | hdr->version_minor = PCAP_VERSION_MINOR;
33 | hdr->thiszone = 0;
34 | hdr->sigfigs = 0; /* 9? libpcap always writes 0 */
35 | hdr->snaplen = snaplen + (int)sizeof(expcap_pktftr_t);
36 | hdr->linktype = DLT_EN10MB;
37 |
38 | BUFF_TRY(buff_new_file(buff));
39 |
40 | return BUFF_ENONE;
41 | }
42 |
43 | buff_error_t pcap_buff_from_file(pcap_buff_t* pcap_buff, char* filename, bool is_expcap)
44 | {
45 | pcap_buff->expcap = is_expcap;
46 | BUFF_TRY(buff_init_from_file(&pcap_buff->_buff, filename, sizeof(pcap_file_header_t)));
47 | return BUFF_ENONE;
48 | }
49 |
50 | pkt_info_t pcap_buff_get_info(pcap_buff_t* pcap_buff)
51 | {
52 | if(pcap_buff->hdr == NULL){
53 | pcap_buff->hdr = (pcap_pkthdr_t*)(pcap_buff->_buff->data + sizeof(pcap_file_header_t));
54 | pcap_buff->idx = 0;
55 | }
56 |
57 | pcap_buff->pkt = (char*)(pcap_buff->hdr + 1);
58 |
59 | /* Check if we've overflowed */
60 | buff_t* buff = pcap_buff->_buff;
61 | int64_t offset = (char*)pcap_buff->hdr - buff->data;
62 | buff->eof = offset >= buff->filesize;
63 | if(buff->eof){
64 | return PKT_EOF;
65 | }
66 |
67 | if(pcap_buff->hdr->len == 0){
68 | return PKT_PADDING;
69 | }
70 |
71 | if(pcap_buff->hdr->caplen < 64){
72 | return PKT_RUNT;
73 | }
74 |
75 | pcap_file_header_t* hdr = (pcap_file_header_t*)buff->file_header;
76 | if(pcap_buff->hdr->len > hdr->snaplen){
77 | return PKT_OVER_SNAPLEN;
78 | }
79 |
80 | if(pcap_buff->hdr->len > pcap_buff->hdr->caplen){
81 | return PKT_SNAPPED;
82 | }
83 |
84 | if(pcap_buff->expcap){
85 | pcap_buff->ftr = (expcap_pktftr_t*)(pcap_buff->pkt + pcap_buff->hdr->caplen - sizeof(expcap_pktftr_t));
86 |
87 | if(pcap_buff->ftr->foot.extra.dropped > 0){
88 | ch_log_warn("%li packets were droped before this one\n",
89 | pcap_buff->ftr->foot.extra.dropped);
90 | }
91 |
92 | if( (pcap_buff->ftr->flags & EXPCAP_FLAG_ABRT) ||
93 | (pcap_buff->ftr->flags & EXPCAP_FLAG_CRPT) ||
94 | (pcap_buff->ftr->flags & EXPCAP_FLAG_SWOVFL)){
95 |
96 | return PKT_ERROR;
97 | }
98 | } else {
99 | pcap_buff->ftr = NULL;
100 | }
101 |
102 | return PKT_OK;
103 | }
104 |
105 | pkt_info_t pcap_buff_next_packet(pcap_buff_t* pcap_buff)
106 | {
107 | pcap_pkthdr_t* curr_hdr = pcap_buff->hdr;
108 |
109 | if(curr_hdr == NULL){
110 | pcap_buff->hdr = (pcap_pkthdr_t*)(pcap_buff->_buff->data + sizeof(pcap_file_header_t));
111 | pcap_buff->idx = 0;
112 | } else {
113 | const int64_t curr_cap_len = curr_hdr->caplen;
114 | pcap_pkthdr_t* next_hdr = (pcap_pkthdr_t*)((char*)(curr_hdr+1) + curr_cap_len);
115 | pcap_buff->hdr = next_hdr;
116 | pcap_buff->idx++;
117 | }
118 |
119 | return pcap_buff_get_info(pcap_buff);
120 | }
121 |
122 | bool pcap_buff_eof(pcap_buff_t* pcap_buff)
123 | {
124 | buff_t* buff = pcap_buff->_buff;
125 | return buff->eof;
126 | }
127 |
128 | char* pcap_buff_get_filename(pcap_buff_t* pcap_buff)
129 | {
130 | return pcap_buff->_buff->filename;
131 | }
132 |
133 | buff_error_t pcap_buff_flush_to_disk(pcap_buff_t* pcap_buff){
134 | return buff_flush_to_disk(pcap_buff->_buff);
135 | }
136 |
137 | buff_error_t pcap_buff_write(pcap_buff_t* pcap_buff, pcap_pkthdr_t* hdr, char* data, size_t data_len, expcap_pktftr_t* ftr)
138 | {
139 | buff_t* buff = pcap_buff->_buff;
140 | const int64_t pcap_record_bytes = sizeof(pcap_pkthdr_t) + data_len + (ftr ? sizeof(expcap_pktftr_t) : 0);
141 |
142 | // there isn't enough space in the buff_t. must flush to disk.
143 | int64_t bytes_remaining;
144 | BUFF_TRY(buff_remaining(buff, &bytes_remaining));
145 | const bool buff_full = bytes_remaining < pcap_record_bytes;
146 |
147 | if(buff_full){
148 | BUFF_TRY(buff_flush_to_disk(buff));
149 | }
150 |
151 | if(buff->max_filesize > 0){
152 | /* tcpdump allows one packet to be written past the filesize limit. */
153 | if(buff_seg_remaining(buff) < 0){
154 | BUFF_TRY(buff_flush_to_disk(buff));
155 | buff->file_seg++;
156 | buff_new_file(buff);
157 | }
158 | }
159 |
160 | /* Flush the buffer if we need to */
161 | if(ftr){
162 | hdr->caplen += sizeof(expcap_pktftr_t);
163 | }
164 |
165 | ch_log_debug1("header bytes=%li\n", sizeof(pcap_pkthdr_t));
166 | ch_log_debug1("footer bytes=%li\n", sizeof(expcap_pktftr_t));
167 | ch_log_debug1("max pcap_record_bytes=%li\n", pcap_record_bytes);
168 |
169 | BUFF_TRY(buff_copy_bytes(buff, hdr, sizeof(pcap_pkthdr_t)));
170 | BUFF_TRY(buff_copy_bytes(buff, data, data_len));
171 |
172 | if(ftr){
173 | BUFF_TRY(buff_copy_bytes(buff, ftr, sizeof(expcap_pktftr_t)));
174 | }
175 |
176 | return BUFF_ENONE;
177 | }
178 |
179 | buff_error_t pcap_buff_close(pcap_buff_t* pcap_buff){
180 | return buff_close(pcap_buff->_buff);
181 | }
182 |
183 | static const char* pkt_infolist[] = {
184 | "Packet OK.", // PKT_OK
185 | "Packet is expcap padding.", // PKT_PADDING
186 | "Packet is a runt (len < 64B).", // PKT_RUNT
187 | "Packet contains an error.", // PKT_ERROR
188 | "No more packets left in this buffer. ", // PKT_EOF
189 | "Packet length exceeds the pcap file's snaplen.", // PKT_OVER_SNAPLEN
190 | "Packet data length is less than the length on disk.", // PKT_BAD_LEN
191 | "Packet has been snapped to less than it's length on the wire." // PKT_SNAPPED
192 | };
193 |
194 | const char* pcap_buff_strinfo(pkt_info_t info){
195 | return pkt_infolist[info];
196 | }
197 |
--------------------------------------------------------------------------------
/tools/data_structs/pcap_buff.h:
--------------------------------------------------------------------------------
1 | #include
2 | #include "../../src/data_structs/expcap.h"
3 | #include "../../src/data_structs/pcap-structures.h"
4 | #include "buff.h"
5 |
6 | typedef struct {
7 | pcap_pkthdr_t* hdr; // header
8 | char* pkt; // packet data
9 | expcap_pktftr_t* ftr; // footer
10 | uint64_t idx; // index
11 | int64_t snaplen;
12 | int64_t max_filesize;
13 | bool usec;
14 | bool expcap;
15 | buff_t* _buff; // _private buff_t.
16 | } pcap_buff_t;
17 |
18 | typedef enum {
19 | PKT_OK = 0,
20 | PKT_PADDING,
21 | PKT_RUNT,
22 | PKT_ERROR,
23 | PKT_EOF,
24 | PKT_OVER_SNAPLEN,
25 | PKT_SNAPPED
26 | } pkt_info_t;
27 |
28 | /* Initialize a packet buffer for writing. */
29 | buff_error_t pcap_buff_init(char* filename, int64_t snaplen, int64_t max_filesize, bool usec,
30 | bool conserve_fds, bool allow_duplicates, pcap_buff_t* pcap_buffo);
31 |
32 | /* Read in a pcap from disk. */
33 | /* The underlying buff is read only */
34 | buff_error_t pcap_buff_from_file(pcap_buff_t* pcap_buff, char* filename, bool is_expcap);
35 |
36 | /* Return information about the current packet */
37 | pkt_info_t pcap_buff_get_info(pcap_buff_t* pcap_buff);
38 |
39 | /* Adjust hdr, data, idx, ftr to point to the next packet and return packet information */
40 | pkt_info_t pcap_buff_next_packet(pcap_buff_t* pcap_buff);
41 |
42 | /* Get the filename used by the buff_t. */
43 | char* pcap_buff_get_filename(pcap_buff_t* pcap_buff);
44 |
45 | /* Write a full packet (headers + data + footer). Footer can be NULL if not used. */
46 | /* Header caplen will be adjusted to account for the presence of a footer.. */
47 | buff_error_t pcap_buff_write(pcap_buff_t* pcap_buff, pcap_pkthdr_t* hdr, char* data, size_t data_len, expcap_pktftr_t* ftr);
48 |
49 | /* Flushes _buff to disk. */
50 | buff_error_t pcap_buff_flush_to_disk(pcap_buff_t* pcap_buff);
51 |
52 | /* Check if _buff is at eof. */
53 | bool pcap_buff_eof(pcap_buff_t* pcap_buff);
54 |
55 | /* Close and release resources associated with this pcap_buff */
56 | buff_error_t pcap_buff_close(pcap_buff_t* pcap_buff);
57 |
58 | /* Translate an info value to a string */
59 | const char* pcap_buff_strinfo(pkt_info_t info);
60 |
--------------------------------------------------------------------------------
/tools/data_structs/pseudo_ip_header.h:
--------------------------------------------------------------------------------
1 | /* Pseudo IP header, used in calculating UDP/TCP checksums */
2 | struct pseudo_iphdr {
3 | uint32_t saddr;
4 | uint32_t daddr;
5 | uint8_t zero;
6 | uint8_t protocol;
7 | uint16_t len;
8 | } __attribute__((packed));
9 |
--------------------------------------------------------------------------------
/tools/data_structs/timespecps.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017,2018 All rights reserved.
3 | * See LICENSE.txt for full details.
4 | *
5 | * Created: 13 July 2017
6 | * Author: Matthew P. Grosvenor
7 | * Description:
8 | * A local definition of a timespec like structure for containing picosecond
9 | * values
10 | */
11 |
12 | #ifndef SRC_DATA_STRUCTS_TIMESPECPS_H_
13 | #define SRC_DATA_STRUCTS_TIMESPECPS_H_
14 |
15 | #include
16 |
17 | typedef struct timespecps {
18 | int64_t tv_sec;
19 | int64_t tv_psec;
20 | } __attribute__((packed)) timespecps_t;
21 |
22 |
23 | #endif /* SRC_DATA_STRUCTS_TIMESPECPS_H_ */
24 |
--------------------------------------------------------------------------------
/tools/data_structs/vlan_ethhdr.h:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | typedef struct vlan_ethhdr {
4 | uint64_t h_dest : 48;
5 | uint64_t h_source : 48;
6 | uint16_t h_vlan_proto;
7 | uint16_t h_vlan_TCI;
8 | uint16_t h_vlan_encapsulated_proto;
9 | }__attribute__((packed)) vlan_ethhdr_t;
10 |
--------------------------------------------------------------------------------
/tools/exact-pcap-parse.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017, 2018 All rights reserved.
3 | * See LICENSE.txt for full details.
4 | *
5 | * Created: 28 Jul 2017
6 | * Author: Matthew P. Grosvenor
7 | * Description: A tool for parsing pcaps and expcaps and outputting in ASCII
8 | * for debugging and inspection.
9 | *
10 | */
11 |
12 |
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 | #include
20 |
21 | #include
22 | #include
23 | #include
24 | #include
25 |
26 | #include "data_structs/pcap_buff.h"
27 | #include "data_structs/expcap.h"
28 |
29 |
30 | USE_CH_LOGGER_DEFAULT;
31 | USE_CH_OPTIONS;
32 |
33 |
34 | struct {
35 | char* input;
36 | char* csv;
37 | bool verbose;
38 | char* format;
39 | ch_word offset;
40 | ch_word max;
41 | ch_word num;
42 | bool write_header;
43 | } options;
44 |
45 |
46 | static volatile bool stop = false;
47 | void signal_handler(int signum)
48 | {
49 | ch_log_warn("Caught signal %li, shutting down\n", signum);
50 | if(stop == 1){
51 | ch_log_fatal("Hard exit\n");
52 | }
53 | stop = 1;
54 | }
55 |
56 |
57 | void dprint_packet(int fd, bool expcap, pcap_pkthdr_t* pkt_hdr, char* packet,
58 | bool nl, bool content, int total_out, int64_t timedelta_ns)
59 | {
60 | char fmtd[4096] = {0};
61 |
62 | if(content && options.num != 0){
63 | int n = 0;
64 |
65 | if(options.num < 0){
66 | options.num = INT64_MAX;
67 | }
68 |
69 | for(int64_t i = 0; i < MIN((int64_t)pkt_hdr->caplen,options.num); i++){
70 | n += snprintf(fmtd + n, 4096 -n, "%02x", *((uint8_t*)packet +i));
71 | }
72 | }
73 | dprintf(fd, "%04i,%lins,%i.%09i,%i,%i,",
74 | total_out, timedelta_ns,
75 | pkt_hdr->ts.ns.ts_sec, pkt_hdr->ts.ns.ts_nsec,
76 | pkt_hdr->caplen, pkt_hdr->len);
77 |
78 |
79 | if(expcap && packet){
80 | expcap_pktftr_t* pkt_ftr = (expcap_pktftr_t*)((char*)(packet)
81 | + pkt_hdr->caplen - sizeof(expcap_pktftr_t));
82 |
83 | dprintf(fd, "%i,%i,%li.%012li,",
84 | pkt_ftr->dev_id,
85 | pkt_ftr->port_id,
86 | (int64_t)pkt_ftr->ts_secs, (int64_t)pkt_ftr->ts_psecs);
87 | }
88 |
89 | dprintf(fd, "%s",fmtd);
90 |
91 | if(nl){
92 | dprintf(fd, "\n");
93 | }
94 | }
95 |
96 | int main(int argc, char** argv)
97 | {
98 | signal(SIGHUP, signal_handler);
99 | signal(SIGINT, signal_handler);
100 | signal(SIGPIPE, signal_handler);
101 | signal(SIGALRM, signal_handler);
102 | signal(SIGTERM, signal_handler);
103 |
104 | ch_opt_addsu(CH_OPTION_REQUIRED,'i',"input","PCAP file to read", &options.input);
105 | ch_opt_addsi(CH_OPTION_OPTIONAL,'c',"csv","CSV output file to write to ", &options.csv, NULL);
106 | ch_opt_addbi(CH_OPTION_FLAG,'v',"verbose","Printout verbose output", &options.verbose, false);
107 | ch_opt_addsu(CH_OPTION_REQUIRED,'f',"format","Input format [pcap | expcap]", &options.format);
108 | ch_opt_addii(CH_OPTION_OPTIONAL,'o',"offset","Offset into the file to start ", &options.offset, 0);
109 | ch_opt_addii(CH_OPTION_OPTIONAL,'m',"max","Max packets to output (<0 means all)", &options.max, -1);
110 | ch_opt_addii(CH_OPTION_OPTIONAL,'n',"num-chars","Number of characters to output (<=0 means all)", &options.num, 64);
111 | ch_opt_addbi(CH_OPTION_FLAG,'w',"write-header","Write out a header row", &options.write_header, false);
112 |
113 | ch_opt_parse(argc,argv);
114 |
115 | if(!options.verbose && !options.csv){
116 | ch_log_fatal("Must choose an output type. Use either --verbose or --csv\n");
117 | }
118 |
119 | bool expcap = false;
120 | if(strncmp(options.format, "pcap", strlen("pcap")) == 0){
121 | expcap = false;
122 | }
123 | else if(strncmp(options.format, "expcap", strlen("expcap")) == 0){
124 | expcap = true;
125 | }
126 | else{
127 | ch_log_fatal("Unknown format type =\"%s\". Must be \"pcap\" or \"expcap\"\n", options.format);
128 | }
129 |
130 | if(options.max < 0){
131 | options.max = INT64_MAX;
132 | }
133 |
134 | ch_log_info("Starting PCAP parser...\n");
135 | pcap_buff_t buff = {0};
136 | if(pcap_buff_from_file(&buff, options.input, expcap) != BUFF_ENONE){
137 | ch_log_fatal("Failed to create a new pcap buff from file: %s\n", options.input);
138 | }
139 |
140 | int csv_fd = -1;
141 | if(options.csv){
142 | csv_fd = open(options.csv,O_WRONLY | O_CREAT | O_TRUNC, 0666);
143 | if(csv_fd < 0){
144 | ch_log_fatal("Could not open in missed file %s (%s)\n", options.csv, strerror(errno));
145 | }
146 |
147 | if(options.write_header){
148 | dprintf(csv_fd,"packet_num,delta_ns,seconds.nanos,capture_length,packet_length");
149 | if(expcap){
150 | dprintf(csv_fd,",device_id,port_id,seconds.picos");
151 | }
152 |
153 | dprintf(csv_fd,"\n");
154 | }
155 | }
156 |
157 | int64_t timenowns = 0;
158 | int64_t timeprevns = 0;
159 | int64_t total_out = 0;
160 | pkt_info_t info;
161 | for(int pkt_num = 0; !stop && pkt_num < options.offset + options.max; pkt_num++,
162 | timeprevns = timenowns ){
163 | if(pkt_num && pkt_num % (1000 * 1000) == 0){
164 | ch_log_info("Loaded %li,000,000 packets\n", pkt_num/1000/1000);
165 | }
166 |
167 | info = pcap_buff_next_packet(&buff);
168 | if(info == PKT_EOF){
169 | break;
170 | }
171 |
172 | pcap_pkthdr_t hdr = *buff.hdr;
173 | timenowns = hdr.ts.ns.ts_sec * 1000ULL * 1000 * 1000 + hdr.ts.ns.ts_nsec;
174 |
175 | if(timeprevns == 0){
176 | timeprevns = timenowns;
177 | }
178 |
179 | const int64_t time_delta = timenowns - timeprevns;
180 |
181 | if(pkt_num < options.offset){
182 | continue;
183 | }
184 |
185 | if(options.verbose){
186 | dprint_packet(STDOUT_FILENO, expcap, &hdr, buff.pkt, true, true, total_out, time_delta);
187 | }
188 |
189 | if(csv_fd > 0){
190 | dprint_packet(csv_fd, expcap, &hdr, buff.pkt, true, true, total_out, time_delta);
191 | }
192 |
193 | total_out++;
194 | }
195 |
196 |
197 | if(csv_fd){
198 | close(csv_fd);
199 | }
200 |
201 | ch_log_info("Output %li packets\n", total_out);
202 | ch_log_info("PCAP parser, finished\n");
203 | return 0;
204 |
205 | }
206 |
--------------------------------------------------------------------------------
/tools/utils.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2018 All rights reserved.
3 | * See LICENSE.txt for full details.
4 | *
5 | * Created: 6 Apr. 2018
6 | * Author: Matthew P. Grosvenor
7 | * Description: Application wide useful utility functions
8 | */
9 |
10 |
11 |
12 | #include
13 | #include
14 | #include
15 | #include
16 |
17 | #include "utils.h"
18 |
19 | int64_t time_now_ns()
20 | {
21 | struct timespec now = {0};
22 | clock_gettime(CLOCK_REALTIME, &now);
23 | return now.tv_sec * 1000ULL * 1000 * 1000 + now.tv_nsec;
24 | }
25 |
26 | timespecps_t sub_tsps_tsps(const timespecps_t* lhs, const timespecps_t* rhs)
27 | {
28 | timespecps_t result = {0};
29 | result.tv_psec = lhs->tv_psec - rhs->tv_psec;
30 | result.tv_sec = lhs->tv_sec - rhs->tv_sec;
31 |
32 | if(result.tv_psec < 0){
33 | result.tv_psec = PS_IN_SECS + result.tv_psec;
34 | result.tv_sec -= 1;
35 | }
36 |
37 | return result;
38 | }
39 |
40 | timespecps_t add_tsps_tsps(const timespecps_t* lhs, const timespecps_t* rhs)
41 | {
42 | timespecps_t result = {0};
43 | int64_t carry_secs = 0;
44 | result.tv_psec = lhs->tv_psec + rhs->tv_psec;
45 |
46 | if(result.tv_psec > PS_IN_SECS){
47 | carry_secs++;
48 | result.tv_psec -= PS_IN_SECS;
49 | }
50 |
51 | result.tv_sec = lhs->tv_sec + rhs->tv_sec + carry_secs;
52 |
53 | return result;
54 | }
55 |
56 | timespecps_t sub_tsps_ps(const timespecps_t* lhs, const int64_t ps)
57 | {
58 | timespecps_t rhs = {.tv_sec = 0, .tv_psec = ps};
59 | return sub_tsps_tsps(lhs, &rhs);
60 | }
61 |
62 |
63 | timespecps_t add_tsps_ps(const timespecps_t* lhs, const int64_t ps)
64 | {
65 | timespecps_t rhs = {.tv_sec = 0, .tv_psec = ps};
66 | return add_tsps_tsps(lhs, &rhs);
67 | }
68 |
69 |
70 | double tsps_to_double_ns(const timespecps_t* lhs)
71 | {
72 | return (double)(lhs->tv_psec/1000.0) + (double)lhs->tv_sec*PS_IN_SECS/1000.0;
73 | }
74 |
--------------------------------------------------------------------------------
/tools/utils.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2018 All rights reserved.
3 | * See LICENSE.txt for full details.
4 | *
5 | * Created: 6 Apr. 2018
6 | * Author: Matthew P. Grosvenor
7 | * Description: Application wide useful utility functions and macros
8 | */
9 |
10 |
11 | #ifndef SRC_UTILS_H_
12 | #define SRC_UTILS_H_
13 |
14 | #include
15 | #include
16 | #include "data_structs/timespecps.h"
17 |
18 | int64_t time_now_ns();
19 |
20 | #define NS_IN_SECS (1000LL*1000*1000)
21 | #define PS_IN_SECS (1000LL*1000*1000*1000)
22 | timespecps_t sub_tsps_tsps(const timespecps_t* lhs, const timespecps_t* rhs);
23 | timespecps_t add_tsps_tsps(const timespecps_t* lhs, const timespecps_t* rhs);
24 | timespecps_t sub_tsps_ps(const timespecps_t* lhs, const int64_t ps);
25 | timespecps_t add_tsps_ps(const timespecps_t* lhs, const int64_t ps);
26 | double tsps_to_double_ns(const timespecps_t* lhs);
27 |
28 | #endif /* SRC_UTILS_H_ */
29 |
--------------------------------------------------------------------------------