Push up exploritory work

This commit is contained in:
rncwnd 2024-07-01 15:24:30 +01:00
commit 1e48775af2
12 changed files with 1230 additions and 0 deletions

604
Cargo.lock generated Normal file
View file

@ -0,0 +1,604 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "aho-corasick"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
dependencies = [
"memchr",
]
[[package]]
name = "anstream"
version = "0.6.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon",
"colorchoice",
"is_terminal_polyfill",
"utf8parse",
]
[[package]]
name = "anstyle"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b"
[[package]]
name = "anstyle-parse"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391"
dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "anstyle-wincon"
version = "3.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19"
dependencies = [
"anstyle",
"windows-sys 0.52.0",
]
[[package]]
name = "arrayvec"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711"
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitflags"
version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
[[package]]
name = "cc"
version = "1.0.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac367972e516d45567c7eafc73d24e1c193dcf200a8d94e9db7b3d38b349572d"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clap"
version = "4.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5db83dced34638ad474f39f250d7fea9598bdd239eaced1bdf45d597da0f433f"
dependencies = [
"clap_builder",
"clap_derive",
]
[[package]]
name = "clap_builder"
version = "4.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7e204572485eb3fbf28f871612191521df159bc3e15a9f5064c66dba3a8c05f"
dependencies = [
"anstream",
"anstyle",
"clap_lex",
"strsim",
]
[[package]]
name = "clap_derive"
version = "4.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c780290ccf4fb26629baa7a1081e68ced113f1d3ec302fa5948f1c381ebf06c6"
dependencies = [
"heck",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "clap_lex"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70"
[[package]]
name = "colorchoice"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422"
[[package]]
name = "dipper"
version = "0.1.0"
dependencies = [
"bitflags 1.3.2",
"clap",
"etherparse",
"log",
"nom",
"pcap",
"simple-dns",
"tracing",
"tracing-subscriber",
]
[[package]]
name = "errno"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1"
dependencies = [
"errno-dragonfly",
"libc",
"winapi",
]
[[package]]
name = "errno-dragonfly"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
dependencies = [
"cc",
"libc",
]
[[package]]
name = "etherparse"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "827292ea592108849932ad8e30218f8b1f21c0dfd0696698a18b5d0aed62d990"
dependencies = [
"arrayvec",
]
[[package]]
name = "heck"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "is_terminal_polyfill"
version = "1.70.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800"
[[package]]
name = "lazy_static"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]]
name = "libc"
version = "0.2.155"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
[[package]]
name = "libloading"
version = "0.6.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "351a32417a12d5f7e82c368a66781e307834dae04c6ce0cd4456d52989229883"
dependencies = [
"cfg-if",
"winapi",
]
[[package]]
name = "log"
version = "0.4.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
[[package]]
name = "memchr"
version = "2.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
[[package]]
name = "minimal-lexical"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]]
name = "nom"
version = "7.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
dependencies = [
"memchr",
"minimal-lexical",
]
[[package]]
name = "nu-ansi-term"
version = "0.46.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84"
dependencies = [
"overload",
"winapi",
]
[[package]]
name = "once_cell"
version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
[[package]]
name = "overload"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
[[package]]
name = "pcap"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99e935fc73d54a89fff576526c2ccd42bbf8247aae05b358693475b14fd4ff79"
dependencies = [
"bitflags 1.3.2",
"errno",
"libc",
"libloading",
"pkg-config",
"regex",
"windows-sys 0.36.1",
]
[[package]]
name = "pin-project-lite"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02"
[[package]]
name = "pkg-config"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
[[package]]
name = "proc-macro2"
version = "1.0.86"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
dependencies = [
"proc-macro2",
]
[[package]]
name = "regex"
version = "1.10.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata",
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b"
[[package]]
name = "sharded-slab"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6"
dependencies = [
"lazy_static",
]
[[package]]
name = "simple-dns"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3625957337d21eb40a7125c2df5c92db5c0267195d66b297948c816ea9c33157"
dependencies = [
"bitflags 2.6.0",
]
[[package]]
name = "smallvec"
version = "1.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
[[package]]
name = "strsim"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "syn"
version = "2.0.68"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "901fa70d88b9d6c98022e23b4136f9f3e54e4662c3bc1bd1d84a42a9a0f0c1e9"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "thread_local"
version = "1.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c"
dependencies = [
"cfg-if",
"once_cell",
]
[[package]]
name = "tracing"
version = "0.1.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"
dependencies = [
"pin-project-lite",
"tracing-attributes",
"tracing-core",
]
[[package]]
name = "tracing-attributes"
version = "0.1.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "tracing-core"
version = "0.1.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54"
dependencies = [
"once_cell",
"valuable",
]
[[package]]
name = "tracing-log"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3"
dependencies = [
"log",
"once_cell",
"tracing-core",
]
[[package]]
name = "tracing-subscriber"
version = "0.3.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b"
dependencies = [
"nu-ansi-term",
"sharded-slab",
"smallvec",
"thread_local",
"tracing-core",
"tracing-log",
]
[[package]]
name = "unicode-ident"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "utf8parse"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "valuable"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-sys"
version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2"
dependencies = [
"windows_aarch64_msvc 0.36.1",
"windows_i686_gnu 0.36.1",
"windows_i686_msvc 0.36.1",
"windows_x86_64_gnu 0.36.1",
"windows_x86_64_msvc 0.36.1",
]
[[package]]
name = "windows-sys"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc 0.52.5",
"windows_i686_gnu 0.52.5",
"windows_i686_gnullvm",
"windows_i686_msvc 0.52.5",
"windows_x86_64_gnu 0.52.5",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc 0.52.5",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263"
[[package]]
name = "windows_aarch64_msvc"
version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6"
[[package]]
name = "windows_i686_gnu"
version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6"
[[package]]
name = "windows_i686_gnu"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9"
[[package]]
name = "windows_i686_msvc"
version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024"
[[package]]
name = "windows_i686_msvc"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf"
[[package]]
name = "windows_x86_64_gnu"
version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596"
[[package]]
name = "windows_x86_64_msvc"
version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0"

17
Cargo.toml Normal file
View file

@ -0,0 +1,17 @@
[package]
name = "dipper"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
bitflags = "1.3.2"
clap = { version = "4.1.4", features = ["derive"] }
etherparse = "0.13.0"
log = "0.4.17"
nom = "7.1.3"
pcap = "1.0.0"
simple-dns = "0.7.0"
tracing = "0.1.37"
tracing-subscriber = "0.3.16"

117
flake.lock generated Normal file
View file

@ -0,0 +1,117 @@
{
"nodes": {
"crane": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1719249093,
"narHash": "sha256-0q1haa3sw6GbmJ+WhogMnducZGjEaCa/iR6hF2vq80I=",
"owner": "ipetkov",
"repo": "crane",
"rev": "9791c77eb7e98b8d8ac5b0305d47282f994411ca",
"type": "github"
},
"original": {
"owner": "ipetkov",
"repo": "crane",
"type": "github"
}
},
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1710146030,
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1719254875,
"narHash": "sha256-ECni+IkwXjusHsm9Sexdtq8weAq/yUyt1TWIemXt3Ko=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "2893f56de08021cffd9b6b6dfc70fd9ccd51eb60",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1718428119,
"narHash": "sha256-WdWDpNaq6u1IPtxtYHHWpl5BmabtpmLnMAx0RdJ/vo8=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "e6cea36f83499eb4e9cd184c8a8e823296b50ad5",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"crane": "crane",
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs",
"rust-overlay": "rust-overlay"
}
},
"rust-overlay": {
"inputs": {
"nixpkgs": "nixpkgs_2"
},
"locked": {
"lastModified": 1719541143,
"narHash": "sha256-YdHqW6EM5pXMwXHhC+KniBv3aquXuJrFar2XXaV7x+c=",
"owner": "oxalica",
"repo": "rust-overlay",
"rev": "ed12832f267ab223cd085b0bd6ee3432caa69067",
"type": "github"
},
"original": {
"owner": "oxalica",
"repo": "rust-overlay",
"type": "github"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

103
flake.nix Normal file
View file

@ -0,0 +1,103 @@
{
# Note, a lot of this is boilerplate i just lifted from another project of
# mine.
# TODO: Refactor this.
description = "Dipper, a pure rust DPI system";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
rust-overlay.url = "github:oxalica/rust-overlay";
flake-utils.url = "github:numtide/flake-utils";
crane = {
url = "github:ipetkov/crane";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = {
self,
nixpkgs,
rust-overlay,
flake-utils,
crane,
...
}:
flake-utils.lib.eachDefaultSystem (system: let
pkgs = import nixpkgs {
inherit system;
overlays = [rust-overlay.overlays.default];
};
inherit (pkgs) lib;
commonPkgs = [
pkgs.openssl
pkgs.pkg-config
pkgs.protobuf
pkgs.protolint
pkgs.grcov
pkgs.rustc.llvmPackages.llvm
pkgs.llvmPackages.bintools
pkgs.gcc
pkgs.libpcap
pkgs.tcpdump
pkgs.rust-bin.stable.latest.complete
];
# We have protobuf files we want to include. To do this we need to apply a filter
# nix a functional language after all!
protoFilter = path: _type: null != builtins.match ".*proto$" path;
protoOrCargo = path: type: (protoFilter path type) || (craneLib.filterCargoSources path type);
craneLib = crane.lib.${system};
dipperSrc = lib.cleanSourceWith {
src = craneLib.path ./.;
filter = protoOrCargo;
};
dipper = craneLib.buildPackage {
src = dipperSrc;
nativeBuildInputs = [pkgs.protobuf];
buildInputs = [
commonPkgs
];
PROTOC = "${pkgs.protobuf}/bin/protoc";
doCheck = false;
cargoTestCommand = "";
};
shellPkgs = [
pkgs.rust-analyzer-unwrapped
pkgs.gpsd
pkgs.cargo-cross
pkgs.rustup
pkgs.cargo2junit
pkgs.mosquitto
pkgs.poetry
pkgs.nodePackages.npm
pkgs.nodejs
];
# shared ShellHook Elements.
sharedHook = ''
export PROTOBUF_LOCATION=${pkgs.protobuf}
export PROTOC_INCLUDE=$PROTOBUF_LOCATION/include
export PROTOC=$PROTOBUF_LOCATION/bin/protoc
export LLVM_TOOL_PATH=${pkgs.rustc.llvmPackages.llvm}/bin
export LD_LIBRARY_PATH=${pkgs.stdenv.cc.cc.lib}/lib/
export RUST_LOG="info"
export REPORT=true
'';
in
with pkgs; {
packages.default = dipper;
apps.default = flake-utils.lib.mkApp {
drv = dipper;
};
devShells.default = mkShell {
buildInputs = [
commonPkgs
shellPkgs
];
shellHook = sharedHook;
};
});
}

BIN
pcaps/dns.cap Normal file

Binary file not shown.

32
src/README.md Normal file
View file

@ -0,0 +1,32 @@
# Dipper
A highly experimental pure rust DPI engine.
## Rationale
nDPI exists but it's all C and there's a lot of macros, it's hard to use cleanly
from rust.
Commercial DPI systems exist, but are prohibitivley expensive.
Alternative "Kind of DPI" systems like Suricata exist and are great, but are
only part rust.
## Tools used
- Nom is used extensivley in order to parse wire formats.
- Etherparse is used to "chunk" packets into their various components.
## Goals
### Short Term
- Functional offline packet inspection.
- DNS, ICMP, HTTP, maybe SSH parsing and inspection.
- Standardised output format.
### Long Term
- Online analysis
- Plugin system?

73
src/main.rs Normal file
View file

@ -0,0 +1,73 @@
mod protocols;
mod util;
use std::path::PathBuf;
use clap::Parser;
use pcap::*;
use tracing::*;
use crate::protocols::*;
use crate::util::Stats;
#[derive(Parser, Debug)]
#[command(author, version, about)]
struct Opts {
#[arg(short, long)]
pcap_file: Option<PathBuf>,
#[arg(long, default_value_t = false)]
print_analysis: bool,
}
#[tracing::instrument]
fn main() {
tracing_subscriber::fmt()
.pretty()
.with_thread_names(true)
.with_max_level(tracing::Level::TRACE)
.init();
let opt = Opts::parse();
let mut pcap = match opt.pcap_file {
Some(pf) => Capture::from_file(pf).expect("Invalid pcap file provided"),
None => {
warn!("Using example.pcap as no pcap was provided");
Capture::from_file(PathBuf::from("./pcaps/ssh_test.pcap"))
.expect("./pcaps/ssh_test.pcap does not exist")
}
};
info!("Pcap loaded");
let mut stats = Stats::new();
while let Ok(packet) = pcap.next_packet() {
stats.total_packets += 1;
match etherparse::SlicedPacket::from_ethernet(packet.data) {
Err(e) => {
error!(
"Slicing packet {} resulted in error {:?}",
stats.total_packets, e
);
stats.errored_packets += 1;
continue;
}
Ok(sliced) => {
if !sliced.payload.is_empty() {
match match_protocol(sliced.payload.to_vec()) {
Ok(x) => {
stats.known_packets += 1;
trace!("Known packet type found: {:?}", x);
let extracted = extract_info(x, sliced.payload.to_vec());
if opt.print_analysis {
info!("{:?}", extracted);
}
}
Err(_) => stats.unknown_packets += 1,
}
}
}
}
}
println!("pcap processing complete.");
println!("{}", stats);
//info!("There were {} packets in the pcap", pkts);
}

202
src/protocols/dns.rs Normal file
View file

@ -0,0 +1,202 @@
use crate::util::*;
use nom::{
bytes::complete::{tag, take},
combinator::map,
multi::{length_data, many_till},
sequence::tuple,
IResult, Parser,
};
use tracing::*;
#[derive(Debug)]
pub enum DNSType {
Query,
Response,
}
#[derive(Debug, PartialEq, Eq)]
pub struct DNSValue {
pub txid: u16,
pub flags: u16,
pub question_count: u16,
pub answer_rrs: u16,
pub auth_rrs: u16,
pub additional_rrs: u16,
pub questions: Option<Vec<String>>,
pub answers: Option<Vec<String>>,
pub question_type: u16,
pub question_class: u16,
pub remainder: Option<Vec<u8>>,
}
pub fn is_dns(payload: Vec<u8>) -> Result<DNSType, ()> {
if is_dns_query(&payload) {
return Ok(DNSType::Query);
}
if is_dns_response(&payload) {
return Ok(DNSType::Response);
}
Err(())
}
fn is_dns_query(payload: &[u8]) -> bool {
payload[2] == 0x01 && payload[3] == 0x00
}
fn is_dns_response(payload: &[u8]) -> bool {
payload[2] == 0x81 && payload[3] == 0x80
}
fn ld(s: &[u8]) -> IResult<&[u8], &[u8]> {
length_data(nom::number::complete::u8)(s)
}
fn parse_dns_string(payload: &[u8]) -> IResult<&[u8], (Vec<&[u8]>, &[u8])> {
let mut parser = many_till(ld, tag([0x00]));
parser.parse(payload)
}
fn take_two_as_u16(payload: &[u8]) -> IResult<&[u8], u16> {
let mut parser = map(take(2_u8), |s: &[u8]| as_u16(s[0], s[1]));
parser.parse(payload)
}
fn parse_dns_preamble(payload: &[u8]) -> IResult<&[u8], (u16, u16, u16, u16, u16, u16)> {
let mut parser = tuple((
take_two_as_u16,
take_two_as_u16,
take_two_as_u16,
take_two_as_u16,
take_two_as_u16,
take_two_as_u16,
));
parser.parse(payload)
}
fn parse_query_postamble(payload: &[u8]) -> IResult<&[u8], (u16, u16)> {
let mut parser = tuple((take_two_as_u16, take_two_as_u16));
parser.parse(payload)
}
fn parsed_dns_string_to_real_string(data: Vec<Vec<u8>>) -> String {
let mut domain_name = String::from("");
for (i, subpart) in data.into_iter().enumerate() {
let as_str = String::from_utf8_lossy(&subpart);
if i == 0 {
domain_name = as_str.to_string()
} else {
domain_name = format!("{}.{}", domain_name, as_str);
}
}
domain_name
}
pub fn analyse_dns_query(payload: Vec<u8>) -> DNSValue {
let mut parser = tuple((parse_dns_preamble, parse_dns_string, parse_query_postamble));
let result = parser.parse(&payload).unwrap();
let remainder = result.0;
let preamble = result.1 .0;
let string_fragments = result.1 .1 .0;
let postamble = result.1 .2;
trace!("Preamble : {:02X?}", preamble);
trace!("strings {:02X?}", string_fragments);
trace!("postamble {:02X?}", postamble);
let mut string_parts: Vec<Vec<u8>> = Vec::new();
for substring in string_fragments {
string_parts.push(substring.to_vec());
}
let real_query_string = parsed_dns_string_to_real_string(string_parts);
let real_remainder = if remainder.is_empty() {
None
} else {
Some(remainder.to_vec())
};
DNSValue {
txid: preamble.0,
flags: preamble.1,
question_count: preamble.2,
answer_rrs: preamble.3,
auth_rrs: preamble.4,
additional_rrs: preamble.5,
question_type: postamble.0,
question_class: postamble.1,
remainder: real_remainder,
questions: Some(vec![real_query_string]),
answers: None,
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_dns_txt_query_parse() {
let packet_bytes: [u8; 28] = [
0x10, 0x32, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x67,
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x10, 0x00, 0x01,
];
let parsed_query = analyse_dns_query(packet_bytes.to_vec());
let expected = DNSValue {
txid: 0x1032,
flags: 0x0100,
question_count: 1,
answer_rrs: 0,
auth_rrs: 0,
additional_rrs: 0,
questions: Some(vec!["google.com".to_string()]),
answers: None,
question_type: 16,
question_class: 0x0001,
remainder: None,
};
assert!(parsed_query == expected);
}
#[test]
fn test_parse_dns_string() {
let packet_bytes: [u8; 13] = [
0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x01,
];
let (_, result) = parse_dns_string(&packet_bytes).unwrap();
let mut string_parts: Vec<Vec<u8>> = Vec::new();
for substring in result.0 {
string_parts.push(substring.to_vec());
}
let real_string = parsed_dns_string_to_real_string(string_parts);
assert!(real_string == *"google.com")
}
#[test]
fn test_dns_a_record_query_parse() {
let packet_bytes: [u8; 32] = [
0x75, 0xc0, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x77,
0x77, 0x77, 0x06, 0x6e, 0x65, 0x74, 0x62, 0x73, 0x64, 0x03, 0x6f, 0x72, 0x67, 0x00,
0x00, 0x01, 0x00, 0x01,
];
let parsed_query = analyse_dns_query(packet_bytes.to_vec());
let expected = DNSValue {
txid: 0x75c0,
flags: 0x0100,
question_count: 1,
answer_rrs: 0,
auth_rrs: 0,
additional_rrs: 0,
questions: Some(vec!["www.netbsd.org".to_string()]),
answers: None,
question_type: 1,
question_class: 0x0001,
remainder: None,
};
assert!(parsed_query == expected);
}
}

1
src/protocols/icmp.rs Normal file
View file

@ -0,0 +1 @@

32
src/protocols/mod.rs Normal file
View file

@ -0,0 +1,32 @@
use dns::{DNSType, DNSValue};
mod dns;
#[derive(Debug)]
pub enum ProtocolType {
DNS(DNSType),
}
#[derive(Debug)]
pub enum ExtractedInfo {
DNSQuery(DNSValue),
}
pub fn extract_info(ptype: ProtocolType, payload: Vec<u8>) -> Option<ExtractedInfo> {
match ptype {
ProtocolType::DNS(x) => match x {
DNSType::Query => {
return Some(ExtractedInfo::DNSQuery(dns::analyse_dns_query(payload)));
}
DNSType::Response => return None,
},
}
}
pub fn match_protocol(payload: Vec<u8>) -> Result<ProtocolType, ()> {
match dns::is_dns(payload) {
Ok(x) => return Ok(ProtocolType::DNS(x)),
Err(_) => {}
};
return Err(());
}

1
src/protocols/ssh.rs Normal file
View file

@ -0,0 +1 @@

48
src/util.rs Normal file
View file

@ -0,0 +1,48 @@
use std::fmt;
use std::fmt::Display;
pub fn as_u16(a: u8, b: u8) -> u16 {
(a as u16) << 8 | b as u16
}
pub struct Stats {
pub total_packets: usize,
pub known_packets: usize,
pub unknown_packets: usize,
pub errored_packets: usize,
pub empty_payload: usize,
}
impl Stats {
pub fn new() -> Stats {
Stats {
total_packets: 0,
known_packets: 0,
unknown_packets: 0,
errored_packets: 0,
empty_payload: 0,
}
}
fn percent_known(self) -> f64 {
self.total_packets as f64 / self.known_packets as f64
}
fn percent_error(self) -> f64 {
self.total_packets as f64 / self.errored_packets as f64
}
}
impl Display for Stats {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"Total: {}\nKnown: {}\nUnknown: {}\nErrored: {}\nEmpty: {}",
self.total_packets,
self.known_packets,
self.unknown_packets,
self.errored_packets,
self.empty_payload
)
}
}